baron 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/VERSION +1 -1
  2. data/baron.gemspec +32 -23
  3. data/lib/baron.rb +15 -13
  4. data/spec/baron_article_spec.rb +1 -1
  5. data/spec/baron_blog_engine_spec.rb +22 -20
  6. data/spec/baron_spec.rb +10 -22
  7. data/spec/sample_data/.gitignore +5 -0
  8. data/spec/sample_data/Gemfile +1 -1
  9. data/spec/sample_data/README.md +243 -0
  10. data/spec/sample_data/Rakefile +1 -1
  11. data/spec/sample_data/articles/favorites/1916-01-01-the-road-not-taken.txt +26 -0
  12. data/spec/sample_data/articles/north of boston/1914-01-01-the-pasture.txt +10 -0
  13. data/spec/sample_data/articles/north of boston/1914-01-02-mending-wall.txt +48 -0
  14. data/spec/sample_data/articles/north of boston/1914-01-03-the-death-of-the-hired-man.txt +211 -0
  15. data/spec/sample_data/articles/north of boston/1914-01-04-the-mountain.txt +121 -0
  16. data/spec/sample_data/articles/north of boston/1914-01-05-A-Hundred-callers.txt +196 -0
  17. data/spec/sample_data/articles/poems/1909-01-02-If.txt b/data/spec/sample_data/articles/other → authors/1909-01-02-If.txt +0 -0
  18. data/spec/sample_data/config.ru +63 -29
  19. data/spec/sample_data/images/robert-frost-small.png +0 -0
  20. data/spec/sample_data/images/robert-frost.png +0 -0
  21. data/spec/sample_data/pages/about.rhtml +9 -14
  22. data/spec/sample_data/resources/redirects.txt +1 -29
  23. data/spec/sample_data/resources/robots.txt +4 -1
  24. data/spec/sample_data/themes/typography/css/app.css +58 -0
  25. data/spec/sample_data/themes/{test → typography}/css/bootstrap-responsive.css +0 -0
  26. data/spec/sample_data/themes/{test → typography}/css/bootstrap-responsive.min.css +0 -0
  27. data/spec/sample_data/themes/{test → typography}/css/bootstrap.css +0 -0
  28. data/spec/sample_data/themes/{test → typography}/css/bootstrap.min.css +0 -0
  29. data/spec/sample_data/themes/typography/img/github.png +0 -0
  30. data/spec/sample_data/themes/{test → typography}/img/glyphicons-halflings-white.png +0 -0
  31. data/spec/sample_data/themes/{test → typography}/img/glyphicons-halflings.png +0 -0
  32. data/spec/sample_data/{images → themes/typography/img}/instagram.png +0 -0
  33. data/spec/sample_data/themes/typography/js/bootstrap.js +2159 -0
  34. data/spec/sample_data/themes/typography/js/bootstrap.min.js +6 -0
  35. data/spec/sample_data/themes/typography/js/image_alt.js +12 -0
  36. data/spec/sample_data/themes/typography/js/read_later.js +14 -0
  37. data/spec/sample_data/themes/typography/templates/archives.rhtml +18 -0
  38. data/spec/sample_data/themes/typography/templates/article.rhtml +14 -0
  39. data/spec/sample_data/themes/typography/templates/category.rhtml +17 -0
  40. data/spec/sample_data/themes/typography/templates/error.rhtml +3 -0
  41. data/spec/sample_data/themes/typography/templates/home.rhtml +28 -0
  42. data/spec/sample_data/themes/typography/templates/layout.rhtml +141 -0
  43. data/spec/spec_helper.rb +1 -1
  44. metadata +32 -23
  45. data/spec/sample_data/articles/2012-11-09-sample-post.txt +0 -11
  46. data/spec/sample_data/articles/poems/1916-01-01-the-road-not-taken.txt +0 -26
  47. data/spec/sample_data/images/import-csv-file-1.png +0 -0
  48. data/spec/sample_data/images/import-csv-file-2.png +0 -0
  49. data/spec/sample_data/images/import-csv-file-3.png +0 -0
  50. data/spec/sample_data/themes/test/css/app.css +0 -27
  51. data/spec/sample_data/themes/test/img/instagram.png +0 -0
  52. data/spec/sample_data/themes/test/templates/archives.rhtml +0 -14
  53. data/spec/sample_data/themes/test/templates/article.rhtml +0 -14
  54. data/spec/sample_data/themes/test/templates/category.rhtml +0 -15
  55. data/spec/sample_data/themes/test/templates/error.rhtml +0 -11
  56. data/spec/sample_data/themes/test/templates/home.rhtml +0 -26
  57. data/spec/sample_data/themes/test/templates/layout.rhtml +0 -90
@@ -1,39 +1,75 @@
1
- #
1
+ ###
2
2
  # Baron configuration
3
3
 
4
4
  require 'baron'
5
5
 
6
6
  baron = Baron::Server.new do
7
- #
8
- # Add your settings here
9
- # set [:setting], [value]
10
- #
11
- # set :author, ENV['USER'] # blog author
12
- # set :title, Dir.pwd.split('/').last # site title
13
- # set :root, "index" # page to load on /
14
- # set :date, lambda {|now| now.strftime("%d/%m/%Y") } # date format for articles
15
- # set :markdown, :smart # use markdown + smart-mode
16
- # set :disqus, false # disqus id, or false
17
- # set :summary, :max => 150, :delim => /~/ # length of article summary and delimiter
18
- # set :ext, 'txt' # file extension for articles
19
- # set :cache, 28800 # cache duration, in seconds
20
- # set :custom_pages "about, contact-us" # custom pages, should match filename
21
- # set :permalink_prefix, "" # common path prefix for article permalinks
22
- # set :permalink_date_format, :no_date, # :year_date, :year_month_date, :year_month_day_date, :no_date
23
-
7
+
8
+ # Turns on blog comments using disqus. true or false
24
9
  set :disqus, true
25
- set :title, 'test blog'
26
- set :date, lambda {|now| now.strftime("%B #{now.day.ordinal} %Y") }
27
- set :permalink_prefix, 'posts'
28
- set :theme, 'test'
29
- set :permalink_date_format, :no_date
30
- set :article_max, 2
31
- end
32
10
 
33
- #
11
+ # Specify the title of your blog
12
+ set :title, 'Robert Frost'
13
+
14
+ # Specify a description for your blog
15
+ set :description, 'The fake blog of Robert Frost'
16
+
17
+ # Path to the image used in the site header
18
+ set :header_image, 'robert-frost.png'
19
+ set :header_image_small, 'robert-frost-small.png'
20
+
21
+ # Specify the name you want your articles to appear written by
22
+ set :author, 'Rob'
23
+
24
+ # Provide a ruby block function used to render the date
25
+ # http://ruby-doc.org/core-2.0/Time.html#method-i-strftime
26
+ set :date, lambda {|now| now.strftime("#{now.day} %b %Y") }
27
+
28
+ # Prefix your permalink URL. This is useful for maintaining compatibility
29
+ # with the permalink format of your current blog, or so your permalink URLs
30
+ # don't collide with your custom pages
31
+ set :permalink_prefix, ''
32
+
33
+ # Specify which theme you would like to use. You can see the list of themes
34
+ # in the themes/ folder.
35
+ # TODO: link to article for hacking your own theme
36
+ set :theme, 'typography'
37
+
38
+ # Specify how and if you would like the article date to be included in your
39
+ # permalink URL.
40
+ # Options: :year_date, :year_month_date, :year_month_day_date, :no_date
41
+ set :permalink_date_format, :year_month_day_date
42
+
43
+ # Specifies the maximum number of articles that will be show on the home page
44
+ set :article_max, 3
45
+
46
+ # Specify the URL of your blog for creating permalinks (good in case people
47
+ # steal your content, then the links will still point to your articles.)
48
+ # for example: http://nathanbuggia.com
49
+ set :url, 'http://localhost:3000/'
50
+
51
+ # specify your google analytics ID
52
+ # format of "UA-XXXXXX-X"
53
+ set :google_analytics, ''
54
+
55
+ # specify your google webmaster key
56
+ # format: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
57
+ set :google_webmaster, ''
58
+
59
+ # You can add any value here like this:
60
+ # => set :foo_bar, 'foobar'
61
+ # and then access it from any of the rhtml templates like this:
62
+ # => <%= @config[:foo_bar] %>
63
+
64
+ end
65
+
66
+ ###
34
67
  # Rack configuration
35
68
 
69
+ # Rack will allow public access to these folders (and sub folders), though it
70
+ # will not support directory browsing. Add your own folders.
36
71
  use Rack::Static, :urls => ['/themes', '/downloads', '/images']
72
+
37
73
  use Rack::CommonLogger
38
74
 
39
75
  if ENV['RACK_ENV'] == 'development'
@@ -41,6 +77,4 @@ if ENV['RACK_ENV'] == 'development'
41
77
  end
42
78
 
43
79
  # RUN!
44
- run baron
45
-
46
-
80
+ run baron
@@ -1,14 +1,9 @@
1
- <section id="posts">
2
- <h1>About</h1>
3
- <div>
4
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mauris justo, lobortis et posuere eget, condimentum a sem. In hac habitasse platea dictumst. Vestibulum congue commodo blandit. Quisque lacinia tempus elit quis pulvinar. Pellentesque sit amet pellentesque arcu. Nulla facilisi. Nam aliquet metus sit amet mi pulvinar ornare. Integer et mi non nunc scelerisque tristique. Etiam mattis malesuada rutrum. Fusce eu erat quis neque lacinia mattis sit amet at leo.
5
-
6
- Maecenas sit amet consequat lorem. Praesent id risus quis eros molestie interdum nec nec lacus. Cras ultrices arcu sit amet urna mollis in sagittis nibh auctor. Ut non sem at ipsum commodo gravida in eu est. Suspendisse pellentesque euismod mauris, vitae aliquet lectus condimentum at. Praesent nec augue vitae turpis sollicitudin gravida. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus volutpat malesuada lectus, vel faucibus velit accumsan at. Cras rhoncus vulputate sem, et pharetra ipsum rutrum sed. Fusce nibh elit, dapibus et posuere eget, tempus sagittis orci. Nunc in nisi id orci facilisis imperdiet sit amet fringilla orci. Ut scelerisque est ut libero posuere nec accumsan lectus sollicitudin.
7
-
8
- Morbi euismod, metus nec rhoncus pulvinar, felis mi ultricies turpis, vitae cursus mi eros eu metus. Morbi condimentum pretium sem, non congue sem ultricies eget. Sed nisi libero, tempor a viverra id, iaculis suscipit ante. Suspendisse potenti. Morbi faucibus fringilla fringilla. Fusce eget orci turpis. Phasellus eleifend lectus sit amet elit eleifend eget venenatis felis fermentum.
9
-
10
- Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce eu sodales est. Donec lobortis tristique luctus. Integer pharetra congue nisi vel iaculis. Sed convallis convallis tristique. Aliquam erat volutpat. Maecenas sed volutpat felis. Duis sollicitudin lorem vel felis molestie placerat. Nulla nec lacus lorem, eu sollicitudin lectus. Suspendisse quis ipsum vitae erat rutrum suscipit sit amet non justo. Praesent dignissim pulvinar facilisis. Vivamus vel risus id magna lacinia euismod. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi ultricies nisi sit amet turpis suscipit rhoncus aliquam eros luctus.
11
-
12
- Nunc sit amet leo lectus, a eleifend lectus. Nam pulvinar, purus sed dapibus vestibulum, ligula ligula volutpat purus, at blandit enim elit ut risus. Ut rhoncus ultrices magna, id dignissim ligula pharetra vulputate. Ut rutrum pulvinar urna, quis egestas erat facilisis ac. Integer volutpat euismod accumsan. Donec cursus arcu eget sem bibendum ullamcorper. Quisque enim justo, pharetra vel porta vitae, hendrerit id justo. Sed semper congue dapibus. Fusce suscipit iaculis sapien, vel facilisis justo viverra a. Pellentesque augue turpis, imperdiet ut volutpat eu, viverra quis orci.
13
- </div>
14
- </section>
1
+ <header>
2
+ <h1>About Robert Frost</h1>
3
+ </header>
4
+
5
+ <article>
6
+ <p>
7
+ TODO: add a nice description for Mr. Robert Frost
8
+ </p>
9
+ </article>
@@ -4,41 +4,13 @@
4
4
  # Use this file to list all of the redirections you'd like the blog to process
5
5
  # using the same file-format as Apache.
6
6
  #
7
- # File Format:
8
- #
9
- # Each line is a separate redirect. Below is a description of each field:
10
- #
11
- # Field #1 - Redirect. Doesn't really do anything but make the file easier to read
12
- # Field #2 - Status Code. 301 status codes are for permanent redirections. Google
13
- # transfer full PageRank for these to the destination page (unless it
14
- # is on another domain, that gets a little more complex). 302 status
15
- # codes are for temperary redirects, those are anything less than a
16
- # couple of days. 302 redirects are not really used that often in a blog.
17
- # http://support.google.com/webmasters/bin/answer.py?hl=en&answer=40132
18
- # Field #3 - Source Path. This is the path (e.g. no protocol or domain name) that
19
- # you would like to redirect somewhere else.
20
- # Field #4 - Desitnation Path. This is the location you would like to redirect the
21
- # user to. It does not have to be on your domain
22
- #
23
- # Sample redirects:
24
- #
25
- # Redirect 301 /posts/my-first-article /2013/01/01/my-first-article
26
- # Redirect 302 / /temp-custom-home-page
27
- # Redirect 301 /pub/download/file?name=myarchive.zip /downloads/myarchive.zip
28
- # Redirect 301 /my-project https://github/my-project-home
7
+ # http://support.google.com/webmasters/bin/answer.py?hl=en&answer=40132
29
8
 
30
9
  ###
31
10
  # Handles de-duping of pagination with root (keep this!)
32
11
  Redirect 301 /page/1 /
33
12
  Redirect 301 /page/1/ /
34
13
 
35
- ###
36
- # Test redirects (don't forget to delete this before publishing)
37
- Redirect 301 /foobar-test-1 /
38
- Redirect 301 /foobar-test-2 /archives
39
- Redirect 302 /foobar-test-3 /posts/poems/the-road-not-taken/
40
-
41
14
  ###
42
15
  # Add your redirects here
43
16
 
44
-
@@ -1 +1,4 @@
1
- # Robots.txt
1
+ # Robots.txt
2
+
3
+
4
+ Sitemap: <%= @params[:rss_feed] %>
@@ -0,0 +1,58 @@
1
+ body {font-family:"source-sans-pro", sans-serif; font-size:18px; line-height:1.6em; color: #444; border-top:3px solid #069;}
2
+ h1, h2, h3 {font-family:"museo-sans", sans-serif; padding-top:0; margin-top:0;}
3
+ h1 {font-size:2.6em; line-height:1.3em; color:#444; text-align:center; }
4
+ h2 {color: #444; font-size: 1.4em;}
5
+ h3 {text-transform: uppercase; font-size:0.9em;}
6
+ h4 {text-transform: uppercase; font-size:0.76em;}
7
+
8
+ .small {font-size:0.8em;}
9
+ .center {text-align: center;}
10
+
11
+
12
+ a:link, a:hover, a:visited, a:active {color:#069;}
13
+ a:link.subtle, a:hover.subtle, a:visited.subtle, a:active.subtle {color:#444;}
14
+
15
+ /* Site Layout Template */
16
+
17
+ a:hover.logo {border:20px solid #eee; border-top-style:none; border-bottom-style:none; padding:0 2em 0 2em; border-radius:1em;}
18
+
19
+ div.content-strip {max-width: 38em; margin: 0 auto;}
20
+
21
+ #header {padding-top:2em;}
22
+ #header-image {display:block; text-align:center;}
23
+ #blog-title {text-align:center; font-size:1.8em; line-height:1.8em; padding-top:1em;}
24
+ .blog-title {font-size:1.2em;}
25
+
26
+ #content {padding-top:2em; padding-bottom:5em;}
27
+
28
+ #navigation {padding-top:1em;}
29
+ #navigation a:link, #navigation a:hover, #navigation a:visited, #navigation a:active {color:#08c;}
30
+ .navigation-wrapper {background-color:#eee;}
31
+ #navigation ul {list-style-type:none; margin-left:0;}
32
+ #navigation li {padding-top:0.3em; padding-bottom: 0.3em;}
33
+
34
+
35
+ #footer {text-align:center; font-size:0.8em; line-height:0.8em; padding-top:1em; padding-bottom:1em;}
36
+ #footer p {margin:1em 0 1em 0}
37
+ .footer-wrapper {background-color:#eee;}
38
+
39
+ /* Index Template */
40
+
41
+ #articles {font-size: 1.3em;}
42
+ #articles ol {list-style-type:none; margin-left:0;}
43
+ #articles li {width:100%; line-height:1.3em; padding-top:0.5em; padding-bottom: 0.5em; border-bottom:solid 1px #cecece;}
44
+ #articles .article-title {float: left;}
45
+ #articles time {float:right; color:#999; text-transform:uppercase; font-size:0.8em; vertical-align:baseline;}
46
+ #articles span {color:#ccc; font-size:0.5em; text-transform:uppercase;}
47
+ /*#articles a {overflow:hidden; text-overflow:ellipsis; white-space:nowrap; width:22em;}*/
48
+
49
+ #pagination {padding-top:1em;}
50
+
51
+
52
+ /* Article Template */
53
+
54
+ .post-details {font-size:0.8em; color:#888; padding-top:0.7em; padding-bottom:1.3em; text-align:center;}
55
+
56
+ article li {line-height:1.3em; padding-top:0.3em; padding-bottom:0.3em;}
57
+ article p {padding:0.5em 0 0.5em 0;}
58
+ article table, article th, article td {border: 1px solid #444;}
@@ -0,0 +1,2159 @@
1
+ /* ===================================================
2
+ * bootstrap-transition.js v2.2.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
+ * bootstrap-alert.js v2.2.2
62
+ * http://twitter.github.com/bootstrap/javascript.html#alerts
63
+ * ==========================================================
64
+ * Copyright 2012 Twitter, Inc.
65
+ *
66
+ * Licensed under the Apache License, Version 2.0 (the "License");
67
+ * you may not use this file except in compliance with the License.
68
+ * You may obtain a copy of the License at
69
+ *
70
+ * http://www.apache.org/licenses/LICENSE-2.0
71
+ *
72
+ * Unless required by applicable law or agreed to in writing, software
73
+ * distributed under the License is distributed on an "AS IS" BASIS,
74
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
75
+ * See the License for the specific language governing permissions and
76
+ * limitations under the License.
77
+ * ========================================================== */
78
+
79
+
80
+ !function ($) {
81
+
82
+ "use strict"; // jshint ;_;
83
+
84
+
85
+ /* ALERT CLASS DEFINITION
86
+ * ====================== */
87
+
88
+ var dismiss = '[data-dismiss="alert"]'
89
+ , Alert = function (el) {
90
+ $(el).on('click', dismiss, this.close)
91
+ }
92
+
93
+ Alert.prototype.close = function (e) {
94
+ var $this = $(this)
95
+ , selector = $this.attr('data-target')
96
+ , $parent
97
+
98
+ if (!selector) {
99
+ selector = $this.attr('href')
100
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
101
+ }
102
+
103
+ $parent = $(selector)
104
+
105
+ e && e.preventDefault()
106
+
107
+ $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
108
+
109
+ $parent.trigger(e = $.Event('close'))
110
+
111
+ if (e.isDefaultPrevented()) return
112
+
113
+ $parent.removeClass('in')
114
+
115
+ function removeElement() {
116
+ $parent
117
+ .trigger('closed')
118
+ .remove()
119
+ }
120
+
121
+ $.support.transition && $parent.hasClass('fade') ?
122
+ $parent.on($.support.transition.end, removeElement) :
123
+ removeElement()
124
+ }
125
+
126
+
127
+ /* ALERT PLUGIN DEFINITION
128
+ * ======================= */
129
+
130
+ var old = $.fn.alert
131
+
132
+ $.fn.alert = function (option) {
133
+ return this.each(function () {
134
+ var $this = $(this)
135
+ , data = $this.data('alert')
136
+ if (!data) $this.data('alert', (data = new Alert(this)))
137
+ if (typeof option == 'string') data[option].call($this)
138
+ })
139
+ }
140
+
141
+ $.fn.alert.Constructor = Alert
142
+
143
+
144
+ /* ALERT NO CONFLICT
145
+ * ================= */
146
+
147
+ $.fn.alert.noConflict = function () {
148
+ $.fn.alert = old
149
+ return this
150
+ }
151
+
152
+
153
+ /* ALERT DATA-API
154
+ * ============== */
155
+
156
+ $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
157
+
158
+ }(window.jQuery);/* ============================================================
159
+ * bootstrap-button.js v2.2.2
160
+ * http://twitter.github.com/bootstrap/javascript.html#buttons
161
+ * ============================================================
162
+ * Copyright 2012 Twitter, Inc.
163
+ *
164
+ * Licensed under the Apache License, Version 2.0 (the "License");
165
+ * you may not use this file except in compliance with the License.
166
+ * You may obtain a copy of the License at
167
+ *
168
+ * http://www.apache.org/licenses/LICENSE-2.0
169
+ *
170
+ * Unless required by applicable law or agreed to in writing, software
171
+ * distributed under the License is distributed on an "AS IS" BASIS,
172
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
173
+ * See the License for the specific language governing permissions and
174
+ * limitations under the License.
175
+ * ============================================================ */
176
+
177
+
178
+ !function ($) {
179
+
180
+ "use strict"; // jshint ;_;
181
+
182
+
183
+ /* BUTTON PUBLIC CLASS DEFINITION
184
+ * ============================== */
185
+
186
+ var Button = function (element, options) {
187
+ this.$element = $(element)
188
+ this.options = $.extend({}, $.fn.button.defaults, options)
189
+ }
190
+
191
+ Button.prototype.setState = function (state) {
192
+ var d = 'disabled'
193
+ , $el = this.$element
194
+ , data = $el.data()
195
+ , val = $el.is('input') ? 'val' : 'html'
196
+
197
+ state = state + 'Text'
198
+ data.resetText || $el.data('resetText', $el[val]())
199
+
200
+ $el[val](data[state] || this.options[state])
201
+
202
+ // push to event loop to allow forms to submit
203
+ setTimeout(function () {
204
+ state == 'loadingText' ?
205
+ $el.addClass(d).attr(d, d) :
206
+ $el.removeClass(d).removeAttr(d)
207
+ }, 0)
208
+ }
209
+
210
+ Button.prototype.toggle = function () {
211
+ var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
212
+
213
+ $parent && $parent
214
+ .find('.active')
215
+ .removeClass('active')
216
+
217
+ this.$element.toggleClass('active')
218
+ }
219
+
220
+
221
+ /* BUTTON PLUGIN DEFINITION
222
+ * ======================== */
223
+
224
+ var old = $.fn.button
225
+
226
+ $.fn.button = function (option) {
227
+ return this.each(function () {
228
+ var $this = $(this)
229
+ , data = $this.data('button')
230
+ , options = typeof option == 'object' && option
231
+ if (!data) $this.data('button', (data = new Button(this, options)))
232
+ if (option == 'toggle') data.toggle()
233
+ else if (option) data.setState(option)
234
+ })
235
+ }
236
+
237
+ $.fn.button.defaults = {
238
+ loadingText: 'loading...'
239
+ }
240
+
241
+ $.fn.button.Constructor = Button
242
+
243
+
244
+ /* BUTTON NO CONFLICT
245
+ * ================== */
246
+
247
+ $.fn.button.noConflict = function () {
248
+ $.fn.button = old
249
+ return this
250
+ }
251
+
252
+
253
+ /* BUTTON DATA-API
254
+ * =============== */
255
+
256
+ $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
257
+ var $btn = $(e.target)
258
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
259
+ $btn.button('toggle')
260
+ })
261
+
262
+ }(window.jQuery);/* ==========================================================
263
+ * bootstrap-carousel.js v2.2.2
264
+ * http://twitter.github.com/bootstrap/javascript.html#carousel
265
+ * ==========================================================
266
+ * Copyright 2012 Twitter, Inc.
267
+ *
268
+ * Licensed under the Apache License, Version 2.0 (the "License");
269
+ * you may not use this file except in compliance with the License.
270
+ * You may obtain a copy of the License at
271
+ *
272
+ * http://www.apache.org/licenses/LICENSE-2.0
273
+ *
274
+ * Unless required by applicable law or agreed to in writing, software
275
+ * distributed under the License is distributed on an "AS IS" BASIS,
276
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
277
+ * See the License for the specific language governing permissions and
278
+ * limitations under the License.
279
+ * ========================================================== */
280
+
281
+
282
+ !function ($) {
283
+
284
+ "use strict"; // jshint ;_;
285
+
286
+
287
+ /* CAROUSEL CLASS DEFINITION
288
+ * ========================= */
289
+
290
+ var Carousel = function (element, options) {
291
+ this.$element = $(element)
292
+ this.options = options
293
+ this.options.pause == 'hover' && this.$element
294
+ .on('mouseenter', $.proxy(this.pause, this))
295
+ .on('mouseleave', $.proxy(this.cycle, this))
296
+ }
297
+
298
+ Carousel.prototype = {
299
+
300
+ cycle: function (e) {
301
+ if (!e) this.paused = false
302
+ this.options.interval
303
+ && !this.paused
304
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
305
+ return this
306
+ }
307
+
308
+ , to: function (pos) {
309
+ var $active = this.$element.find('.item.active')
310
+ , children = $active.parent().children()
311
+ , activePos = children.index($active)
312
+ , that = this
313
+
314
+ if (pos > (children.length - 1) || pos < 0) return
315
+
316
+ if (this.sliding) {
317
+ return this.$element.one('slid', function () {
318
+ that.to(pos)
319
+ })
320
+ }
321
+
322
+ if (activePos == pos) {
323
+ return this.pause().cycle()
324
+ }
325
+
326
+ return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
327
+ }
328
+
329
+ , pause: function (e) {
330
+ if (!e) this.paused = true
331
+ if (this.$element.find('.next, .prev').length && $.support.transition.end) {
332
+ this.$element.trigger($.support.transition.end)
333
+ this.cycle()
334
+ }
335
+ clearInterval(this.interval)
336
+ this.interval = null
337
+ return this
338
+ }
339
+
340
+ , next: function () {
341
+ if (this.sliding) return
342
+ return this.slide('next')
343
+ }
344
+
345
+ , prev: function () {
346
+ if (this.sliding) return
347
+ return this.slide('prev')
348
+ }
349
+
350
+ , slide: function (type, next) {
351
+ var $active = this.$element.find('.item.active')
352
+ , $next = next || $active[type]()
353
+ , isCycling = this.interval
354
+ , direction = type == 'next' ? 'left' : 'right'
355
+ , fallback = type == 'next' ? 'first' : 'last'
356
+ , that = this
357
+ , e
358
+
359
+ this.sliding = true
360
+
361
+ isCycling && this.pause()
362
+
363
+ $next = $next.length ? $next : this.$element.find('.item')[fallback]()
364
+
365
+ e = $.Event('slide', {
366
+ relatedTarget: $next[0]
367
+ })
368
+
369
+ if ($next.hasClass('active')) return
370
+
371
+ if ($.support.transition && this.$element.hasClass('slide')) {
372
+ this.$element.trigger(e)
373
+ if (e.isDefaultPrevented()) return
374
+ $next.addClass(type)
375
+ $next[0].offsetWidth // force reflow
376
+ $active.addClass(direction)
377
+ $next.addClass(direction)
378
+ this.$element.one($.support.transition.end, function () {
379
+ $next.removeClass([type, direction].join(' ')).addClass('active')
380
+ $active.removeClass(['active', direction].join(' '))
381
+ that.sliding = false
382
+ setTimeout(function () { that.$element.trigger('slid') }, 0)
383
+ })
384
+ } else {
385
+ this.$element.trigger(e)
386
+ if (e.isDefaultPrevented()) return
387
+ $active.removeClass('active')
388
+ $next.addClass('active')
389
+ this.sliding = false
390
+ this.$element.trigger('slid')
391
+ }
392
+
393
+ isCycling && this.cycle()
394
+
395
+ return this
396
+ }
397
+
398
+ }
399
+
400
+
401
+ /* CAROUSEL PLUGIN DEFINITION
402
+ * ========================== */
403
+
404
+ var old = $.fn.carousel
405
+
406
+ $.fn.carousel = function (option) {
407
+ return this.each(function () {
408
+ var $this = $(this)
409
+ , data = $this.data('carousel')
410
+ , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
411
+ , action = typeof option == 'string' ? option : options.slide
412
+ if (!data) $this.data('carousel', (data = new Carousel(this, options)))
413
+ if (typeof option == 'number') data.to(option)
414
+ else if (action) data[action]()
415
+ else if (options.interval) data.cycle()
416
+ })
417
+ }
418
+
419
+ $.fn.carousel.defaults = {
420
+ interval: 5000
421
+ , pause: 'hover'
422
+ }
423
+
424
+ $.fn.carousel.Constructor = Carousel
425
+
426
+
427
+ /* CAROUSEL NO CONFLICT
428
+ * ==================== */
429
+
430
+ $.fn.carousel.noConflict = function () {
431
+ $.fn.carousel = old
432
+ return this
433
+ }
434
+
435
+ /* CAROUSEL DATA-API
436
+ * ================= */
437
+
438
+ $(document).on('click.carousel.data-api', '[data-slide]', function (e) {
439
+ var $this = $(this), href
440
+ , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
441
+ , options = $.extend({}, $target.data(), $this.data())
442
+ $target.carousel(options)
443
+ e.preventDefault()
444
+ })
445
+
446
+ }(window.jQuery);/* =============================================================
447
+ * bootstrap-collapse.js v2.2.2
448
+ * http://twitter.github.com/bootstrap/javascript.html#collapse
449
+ * =============================================================
450
+ * Copyright 2012 Twitter, Inc.
451
+ *
452
+ * Licensed under the Apache License, Version 2.0 (the "License");
453
+ * you may not use this file except in compliance with the License.
454
+ * You may obtain a copy of the License at
455
+ *
456
+ * http://www.apache.org/licenses/LICENSE-2.0
457
+ *
458
+ * Unless required by applicable law or agreed to in writing, software
459
+ * distributed under the License is distributed on an "AS IS" BASIS,
460
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
461
+ * See the License for the specific language governing permissions and
462
+ * limitations under the License.
463
+ * ============================================================ */
464
+
465
+
466
+ !function ($) {
467
+
468
+ "use strict"; // jshint ;_;
469
+
470
+
471
+ /* COLLAPSE PUBLIC CLASS DEFINITION
472
+ * ================================ */
473
+
474
+ var Collapse = function (element, options) {
475
+ this.$element = $(element)
476
+ this.options = $.extend({}, $.fn.collapse.defaults, options)
477
+
478
+ if (this.options.parent) {
479
+ this.$parent = $(this.options.parent)
480
+ }
481
+
482
+ this.options.toggle && this.toggle()
483
+ }
484
+
485
+ Collapse.prototype = {
486
+
487
+ constructor: Collapse
488
+
489
+ , dimension: function () {
490
+ var hasWidth = this.$element.hasClass('width')
491
+ return hasWidth ? 'width' : 'height'
492
+ }
493
+
494
+ , show: function () {
495
+ var dimension
496
+ , scroll
497
+ , actives
498
+ , hasData
499
+
500
+ if (this.transitioning) return
501
+
502
+ dimension = this.dimension()
503
+ scroll = $.camelCase(['scroll', dimension].join('-'))
504
+ actives = this.$parent && this.$parent.find('> .accordion-group > .in')
505
+
506
+ if (actives && actives.length) {
507
+ hasData = actives.data('collapse')
508
+ if (hasData && hasData.transitioning) return
509
+ actives.collapse('hide')
510
+ hasData || actives.data('collapse', null)
511
+ }
512
+
513
+ this.$element[dimension](0)
514
+ this.transition('addClass', $.Event('show'), 'shown')
515
+ $.support.transition && this.$element[dimension](this.$element[0][scroll])
516
+ }
517
+
518
+ , hide: function () {
519
+ var dimension
520
+ if (this.transitioning) return
521
+ dimension = this.dimension()
522
+ this.reset(this.$element[dimension]())
523
+ this.transition('removeClass', $.Event('hide'), 'hidden')
524
+ this.$element[dimension](0)
525
+ }
526
+
527
+ , reset: function (size) {
528
+ var dimension = this.dimension()
529
+
530
+ this.$element
531
+ .removeClass('collapse')
532
+ [dimension](size || 'auto')
533
+ [0].offsetWidth
534
+
535
+ this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
536
+
537
+ return this
538
+ }
539
+
540
+ , transition: function (method, startEvent, completeEvent) {
541
+ var that = this
542
+ , complete = function () {
543
+ if (startEvent.type == 'show') that.reset()
544
+ that.transitioning = 0
545
+ that.$element.trigger(completeEvent)
546
+ }
547
+
548
+ this.$element.trigger(startEvent)
549
+
550
+ if (startEvent.isDefaultPrevented()) return
551
+
552
+ this.transitioning = 1
553
+
554
+ this.$element[method]('in')
555
+
556
+ $.support.transition && this.$element.hasClass('collapse') ?
557
+ this.$element.one($.support.transition.end, complete) :
558
+ complete()
559
+ }
560
+
561
+ , toggle: function () {
562
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
563
+ }
564
+
565
+ }
566
+
567
+
568
+ /* COLLAPSE PLUGIN DEFINITION
569
+ * ========================== */
570
+
571
+ var old = $.fn.collapse
572
+
573
+ $.fn.collapse = function (option) {
574
+ return this.each(function () {
575
+ var $this = $(this)
576
+ , data = $this.data('collapse')
577
+ , options = typeof option == 'object' && option
578
+ if (!data) $this.data('collapse', (data = new Collapse(this, options)))
579
+ if (typeof option == 'string') data[option]()
580
+ })
581
+ }
582
+
583
+ $.fn.collapse.defaults = {
584
+ toggle: true
585
+ }
586
+
587
+ $.fn.collapse.Constructor = Collapse
588
+
589
+
590
+ /* COLLAPSE NO CONFLICT
591
+ * ==================== */
592
+
593
+ $.fn.collapse.noConflict = function () {
594
+ $.fn.collapse = old
595
+ return this
596
+ }
597
+
598
+
599
+ /* COLLAPSE DATA-API
600
+ * ================= */
601
+
602
+ $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
603
+ var $this = $(this), href
604
+ , target = $this.attr('data-target')
605
+ || e.preventDefault()
606
+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
607
+ , option = $(target).data('collapse') ? 'toggle' : $this.data()
608
+ $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
609
+ $(target).collapse(option)
610
+ })
611
+
612
+ }(window.jQuery);/* ============================================================
613
+ * bootstrap-dropdown.js v2.2.2
614
+ * http://twitter.github.com/bootstrap/javascript.html#dropdowns
615
+ * ============================================================
616
+ * Copyright 2012 Twitter, Inc.
617
+ *
618
+ * Licensed under the Apache License, Version 2.0 (the "License");
619
+ * you may not use this file except in compliance with the License.
620
+ * You may obtain a copy of the License at
621
+ *
622
+ * http://www.apache.org/licenses/LICENSE-2.0
623
+ *
624
+ * Unless required by applicable law or agreed to in writing, software
625
+ * distributed under the License is distributed on an "AS IS" BASIS,
626
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
627
+ * See the License for the specific language governing permissions and
628
+ * limitations under the License.
629
+ * ============================================================ */
630
+
631
+
632
+ !function ($) {
633
+
634
+ "use strict"; // jshint ;_;
635
+
636
+
637
+ /* DROPDOWN CLASS DEFINITION
638
+ * ========================= */
639
+
640
+ var toggle = '[data-toggle=dropdown]'
641
+ , Dropdown = function (element) {
642
+ var $el = $(element).on('click.dropdown.data-api', this.toggle)
643
+ $('html').on('click.dropdown.data-api', function () {
644
+ $el.parent().removeClass('open')
645
+ })
646
+ }
647
+
648
+ Dropdown.prototype = {
649
+
650
+ constructor: Dropdown
651
+
652
+ , toggle: function (e) {
653
+ var $this = $(this)
654
+ , $parent
655
+ , isActive
656
+
657
+ if ($this.is('.disabled, :disabled')) return
658
+
659
+ $parent = getParent($this)
660
+
661
+ isActive = $parent.hasClass('open')
662
+
663
+ clearMenus()
664
+
665
+ if (!isActive) {
666
+ $parent.toggleClass('open')
667
+ }
668
+
669
+ $this.focus()
670
+
671
+ return false
672
+ }
673
+
674
+ , keydown: function (e) {
675
+ var $this
676
+ , $items
677
+ , $active
678
+ , $parent
679
+ , isActive
680
+ , index
681
+
682
+ if (!/(38|40|27)/.test(e.keyCode)) return
683
+
684
+ $this = $(this)
685
+
686
+ e.preventDefault()
687
+ e.stopPropagation()
688
+
689
+ if ($this.is('.disabled, :disabled')) return
690
+
691
+ $parent = getParent($this)
692
+
693
+ isActive = $parent.hasClass('open')
694
+
695
+ if (!isActive || (isActive && e.keyCode == 27)) return $this.click()
696
+
697
+ $items = $('[role=menu] li:not(.divider):visible a', $parent)
698
+
699
+ if (!$items.length) return
700
+
701
+ index = $items.index($items.filter(':focus'))
702
+
703
+ if (e.keyCode == 38 && index > 0) index-- // up
704
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
705
+ if (!~index) index = 0
706
+
707
+ $items
708
+ .eq(index)
709
+ .focus()
710
+ }
711
+
712
+ }
713
+
714
+ function clearMenus() {
715
+ $(toggle).each(function () {
716
+ getParent($(this)).removeClass('open')
717
+ })
718
+ }
719
+
720
+ function getParent($this) {
721
+ var selector = $this.attr('data-target')
722
+ , $parent
723
+
724
+ if (!selector) {
725
+ selector = $this.attr('href')
726
+ selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
727
+ }
728
+
729
+ $parent = $(selector)
730
+ $parent.length || ($parent = $this.parent())
731
+
732
+ return $parent
733
+ }
734
+
735
+
736
+ /* DROPDOWN PLUGIN DEFINITION
737
+ * ========================== */
738
+
739
+ var old = $.fn.dropdown
740
+
741
+ $.fn.dropdown = function (option) {
742
+ return this.each(function () {
743
+ var $this = $(this)
744
+ , data = $this.data('dropdown')
745
+ if (!data) $this.data('dropdown', (data = new Dropdown(this)))
746
+ if (typeof option == 'string') data[option].call($this)
747
+ })
748
+ }
749
+
750
+ $.fn.dropdown.Constructor = Dropdown
751
+
752
+
753
+ /* DROPDOWN NO CONFLICT
754
+ * ==================== */
755
+
756
+ $.fn.dropdown.noConflict = function () {
757
+ $.fn.dropdown = old
758
+ return this
759
+ }
760
+
761
+
762
+ /* APPLY TO STANDARD DROPDOWN ELEMENTS
763
+ * =================================== */
764
+
765
+ $(document)
766
+ .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus)
767
+ .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
768
+ .on('touchstart.dropdown.data-api', '.dropdown-menu', function (e) { e.stopPropagation() })
769
+ .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
770
+ .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
771
+
772
+ }(window.jQuery);/* =========================================================
773
+ * bootstrap-modal.js v2.2.2
774
+ * http://twitter.github.com/bootstrap/javascript.html#modals
775
+ * =========================================================
776
+ * Copyright 2012 Twitter, Inc.
777
+ *
778
+ * Licensed under the Apache License, Version 2.0 (the "License");
779
+ * you may not use this file except in compliance with the License.
780
+ * You may obtain a copy of the License at
781
+ *
782
+ * http://www.apache.org/licenses/LICENSE-2.0
783
+ *
784
+ * Unless required by applicable law or agreed to in writing, software
785
+ * distributed under the License is distributed on an "AS IS" BASIS,
786
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
787
+ * See the License for the specific language governing permissions and
788
+ * limitations under the License.
789
+ * ========================================================= */
790
+
791
+
792
+ !function ($) {
793
+
794
+ "use strict"; // jshint ;_;
795
+
796
+
797
+ /* MODAL CLASS DEFINITION
798
+ * ====================== */
799
+
800
+ var Modal = function (element, options) {
801
+ this.options = options
802
+ this.$element = $(element)
803
+ .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
804
+ this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
805
+ }
806
+
807
+ Modal.prototype = {
808
+
809
+ constructor: Modal
810
+
811
+ , toggle: function () {
812
+ return this[!this.isShown ? 'show' : 'hide']()
813
+ }
814
+
815
+ , show: function () {
816
+ var that = this
817
+ , e = $.Event('show')
818
+
819
+ this.$element.trigger(e)
820
+
821
+ if (this.isShown || e.isDefaultPrevented()) return
822
+
823
+ this.isShown = true
824
+
825
+ this.escape()
826
+
827
+ this.backdrop(function () {
828
+ var transition = $.support.transition && that.$element.hasClass('fade')
829
+
830
+ if (!that.$element.parent().length) {
831
+ that.$element.appendTo(document.body) //don't move modals dom position
832
+ }
833
+
834
+ that.$element
835
+ .show()
836
+
837
+ if (transition) {
838
+ that.$element[0].offsetWidth // force reflow
839
+ }
840
+
841
+ that.$element
842
+ .addClass('in')
843
+ .attr('aria-hidden', false)
844
+
845
+ that.enforceFocus()
846
+
847
+ transition ?
848
+ that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
849
+ that.$element.focus().trigger('shown')
850
+
851
+ })
852
+ }
853
+
854
+ , hide: function (e) {
855
+ e && e.preventDefault()
856
+
857
+ var that = this
858
+
859
+ e = $.Event('hide')
860
+
861
+ this.$element.trigger(e)
862
+
863
+ if (!this.isShown || e.isDefaultPrevented()) return
864
+
865
+ this.isShown = false
866
+
867
+ this.escape()
868
+
869
+ $(document).off('focusin.modal')
870
+
871
+ this.$element
872
+ .removeClass('in')
873
+ .attr('aria-hidden', true)
874
+
875
+ $.support.transition && this.$element.hasClass('fade') ?
876
+ this.hideWithTransition() :
877
+ this.hideModal()
878
+ }
879
+
880
+ , enforceFocus: function () {
881
+ var that = this
882
+ $(document).on('focusin.modal', function (e) {
883
+ if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
884
+ that.$element.focus()
885
+ }
886
+ })
887
+ }
888
+
889
+ , escape: function () {
890
+ var that = this
891
+ if (this.isShown && this.options.keyboard) {
892
+ this.$element.on('keyup.dismiss.modal', function ( e ) {
893
+ e.which == 27 && that.hide()
894
+ })
895
+ } else if (!this.isShown) {
896
+ this.$element.off('keyup.dismiss.modal')
897
+ }
898
+ }
899
+
900
+ , hideWithTransition: function () {
901
+ var that = this
902
+ , timeout = setTimeout(function () {
903
+ that.$element.off($.support.transition.end)
904
+ that.hideModal()
905
+ }, 500)
906
+
907
+ this.$element.one($.support.transition.end, function () {
908
+ clearTimeout(timeout)
909
+ that.hideModal()
910
+ })
911
+ }
912
+
913
+ , hideModal: function (that) {
914
+ this.$element
915
+ .hide()
916
+ .trigger('hidden')
917
+
918
+ this.backdrop()
919
+ }
920
+
921
+ , removeBackdrop: function () {
922
+ this.$backdrop.remove()
923
+ this.$backdrop = null
924
+ }
925
+
926
+ , backdrop: function (callback) {
927
+ var that = this
928
+ , animate = this.$element.hasClass('fade') ? 'fade' : ''
929
+
930
+ if (this.isShown && this.options.backdrop) {
931
+ var doAnimate = $.support.transition && animate
932
+
933
+ this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
934
+ .appendTo(document.body)
935
+
936
+ this.$backdrop.click(
937
+ this.options.backdrop == 'static' ?
938
+ $.proxy(this.$element[0].focus, this.$element[0])
939
+ : $.proxy(this.hide, this)
940
+ )
941
+
942
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
943
+
944
+ this.$backdrop.addClass('in')
945
+
946
+ doAnimate ?
947
+ this.$backdrop.one($.support.transition.end, callback) :
948
+ callback()
949
+
950
+ } else if (!this.isShown && this.$backdrop) {
951
+ this.$backdrop.removeClass('in')
952
+
953
+ $.support.transition && this.$element.hasClass('fade')?
954
+ this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) :
955
+ this.removeBackdrop()
956
+
957
+ } else if (callback) {
958
+ callback()
959
+ }
960
+ }
961
+ }
962
+
963
+
964
+ /* MODAL PLUGIN DEFINITION
965
+ * ======================= */
966
+
967
+ var old = $.fn.modal
968
+
969
+ $.fn.modal = function (option) {
970
+ return this.each(function () {
971
+ var $this = $(this)
972
+ , data = $this.data('modal')
973
+ , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
974
+ if (!data) $this.data('modal', (data = new Modal(this, options)))
975
+ if (typeof option == 'string') data[option]()
976
+ else if (options.show) data.show()
977
+ })
978
+ }
979
+
980
+ $.fn.modal.defaults = {
981
+ backdrop: true
982
+ , keyboard: true
983
+ , show: true
984
+ }
985
+
986
+ $.fn.modal.Constructor = Modal
987
+
988
+
989
+ /* MODAL NO CONFLICT
990
+ * ================= */
991
+
992
+ $.fn.modal.noConflict = function () {
993
+ $.fn.modal = old
994
+ return this
995
+ }
996
+
997
+
998
+ /* MODAL DATA-API
999
+ * ============== */
1000
+
1001
+ $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
1002
+ var $this = $(this)
1003
+ , href = $this.attr('href')
1004
+ , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
1005
+ , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
1006
+
1007
+ e.preventDefault()
1008
+
1009
+ $target
1010
+ .modal(option)
1011
+ .one('hide', function () {
1012
+ $this.focus()
1013
+ })
1014
+ })
1015
+
1016
+ }(window.jQuery);
1017
+ /* ===========================================================
1018
+ * bootstrap-tooltip.js v2.2.2
1019
+ * http://twitter.github.com/bootstrap/javascript.html#tooltips
1020
+ * Inspired by the original jQuery.tipsy by Jason Frame
1021
+ * ===========================================================
1022
+ * Copyright 2012 Twitter, Inc.
1023
+ *
1024
+ * Licensed under the Apache License, Version 2.0 (the "License");
1025
+ * you may not use this file except in compliance with the License.
1026
+ * You may obtain a copy of the License at
1027
+ *
1028
+ * http://www.apache.org/licenses/LICENSE-2.0
1029
+ *
1030
+ * Unless required by applicable law or agreed to in writing, software
1031
+ * distributed under the License is distributed on an "AS IS" BASIS,
1032
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1033
+ * See the License for the specific language governing permissions and
1034
+ * limitations under the License.
1035
+ * ========================================================== */
1036
+
1037
+
1038
+ !function ($) {
1039
+
1040
+ "use strict"; // jshint ;_;
1041
+
1042
+
1043
+ /* TOOLTIP PUBLIC CLASS DEFINITION
1044
+ * =============================== */
1045
+
1046
+ var Tooltip = function (element, options) {
1047
+ this.init('tooltip', element, options)
1048
+ }
1049
+
1050
+ Tooltip.prototype = {
1051
+
1052
+ constructor: Tooltip
1053
+
1054
+ , init: function (type, element, options) {
1055
+ var eventIn
1056
+ , eventOut
1057
+
1058
+ this.type = type
1059
+ this.$element = $(element)
1060
+ this.options = this.getOptions(options)
1061
+ this.enabled = true
1062
+
1063
+ if (this.options.trigger == 'click') {
1064
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
1065
+ } else if (this.options.trigger != 'manual') {
1066
+ eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
1067
+ eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
1068
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
1069
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
1070
+ }
1071
+
1072
+ this.options.selector ?
1073
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
1074
+ this.fixTitle()
1075
+ }
1076
+
1077
+ , getOptions: function (options) {
1078
+ options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
1079
+
1080
+ if (options.delay && typeof options.delay == 'number') {
1081
+ options.delay = {
1082
+ show: options.delay
1083
+ , hide: options.delay
1084
+ }
1085
+ }
1086
+
1087
+ return options
1088
+ }
1089
+
1090
+ , enter: function (e) {
1091
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
1092
+
1093
+ if (!self.options.delay || !self.options.delay.show) return self.show()
1094
+
1095
+ clearTimeout(this.timeout)
1096
+ self.hoverState = 'in'
1097
+ this.timeout = setTimeout(function() {
1098
+ if (self.hoverState == 'in') self.show()
1099
+ }, self.options.delay.show)
1100
+ }
1101
+
1102
+ , leave: function (e) {
1103
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
1104
+
1105
+ if (this.timeout) clearTimeout(this.timeout)
1106
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
1107
+
1108
+ self.hoverState = 'out'
1109
+ this.timeout = setTimeout(function() {
1110
+ if (self.hoverState == 'out') self.hide()
1111
+ }, self.options.delay.hide)
1112
+ }
1113
+
1114
+ , show: function () {
1115
+ var $tip
1116
+ , inside
1117
+ , pos
1118
+ , actualWidth
1119
+ , actualHeight
1120
+ , placement
1121
+ , tp
1122
+
1123
+ if (this.hasContent() && this.enabled) {
1124
+ $tip = this.tip()
1125
+ this.setContent()
1126
+
1127
+ if (this.options.animation) {
1128
+ $tip.addClass('fade')
1129
+ }
1130
+
1131
+ placement = typeof this.options.placement == 'function' ?
1132
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
1133
+ this.options.placement
1134
+
1135
+ inside = /in/.test(placement)
1136
+
1137
+ $tip
1138
+ .detach()
1139
+ .css({ top: 0, left: 0, display: 'block' })
1140
+ .insertAfter(this.$element)
1141
+
1142
+ pos = this.getPosition(inside)
1143
+
1144
+ actualWidth = $tip[0].offsetWidth
1145
+ actualHeight = $tip[0].offsetHeight
1146
+
1147
+ switch (inside ? placement.split(' ')[1] : placement) {
1148
+ case 'bottom':
1149
+ tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
1150
+ break
1151
+ case 'top':
1152
+ tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
1153
+ break
1154
+ case 'left':
1155
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
1156
+ break
1157
+ case 'right':
1158
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
1159
+ break
1160
+ }
1161
+
1162
+ $tip
1163
+ .offset(tp)
1164
+ .addClass(placement)
1165
+ .addClass('in')
1166
+ }
1167
+ }
1168
+
1169
+ , setContent: function () {
1170
+ var $tip = this.tip()
1171
+ , title = this.getTitle()
1172
+
1173
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
1174
+ $tip.removeClass('fade in top bottom left right')
1175
+ }
1176
+
1177
+ , hide: function () {
1178
+ var that = this
1179
+ , $tip = this.tip()
1180
+
1181
+ $tip.removeClass('in')
1182
+
1183
+ function removeWithAnimation() {
1184
+ var timeout = setTimeout(function () {
1185
+ $tip.off($.support.transition.end).detach()
1186
+ }, 500)
1187
+
1188
+ $tip.one($.support.transition.end, function () {
1189
+ clearTimeout(timeout)
1190
+ $tip.detach()
1191
+ })
1192
+ }
1193
+
1194
+ $.support.transition && this.$tip.hasClass('fade') ?
1195
+ removeWithAnimation() :
1196
+ $tip.detach()
1197
+
1198
+ return this
1199
+ }
1200
+
1201
+ , fixTitle: function () {
1202
+ var $e = this.$element
1203
+ if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
1204
+ $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
1205
+ }
1206
+ }
1207
+
1208
+ , hasContent: function () {
1209
+ return this.getTitle()
1210
+ }
1211
+
1212
+ , getPosition: function (inside) {
1213
+ return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
1214
+ width: this.$element[0].offsetWidth
1215
+ , height: this.$element[0].offsetHeight
1216
+ })
1217
+ }
1218
+
1219
+ , getTitle: function () {
1220
+ var title
1221
+ , $e = this.$element
1222
+ , o = this.options
1223
+
1224
+ title = $e.attr('data-original-title')
1225
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
1226
+
1227
+ return title
1228
+ }
1229
+
1230
+ , tip: function () {
1231
+ return this.$tip = this.$tip || $(this.options.template)
1232
+ }
1233
+
1234
+ , validate: function () {
1235
+ if (!this.$element[0].parentNode) {
1236
+ this.hide()
1237
+ this.$element = null
1238
+ this.options = null
1239
+ }
1240
+ }
1241
+
1242
+ , enable: function () {
1243
+ this.enabled = true
1244
+ }
1245
+
1246
+ , disable: function () {
1247
+ this.enabled = false
1248
+ }
1249
+
1250
+ , toggleEnabled: function () {
1251
+ this.enabled = !this.enabled
1252
+ }
1253
+
1254
+ , toggle: function (e) {
1255
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
1256
+ self[self.tip().hasClass('in') ? 'hide' : 'show']()
1257
+ }
1258
+
1259
+ , destroy: function () {
1260
+ this.hide().$element.off('.' + this.type).removeData(this.type)
1261
+ }
1262
+
1263
+ }
1264
+
1265
+
1266
+ /* TOOLTIP PLUGIN DEFINITION
1267
+ * ========================= */
1268
+
1269
+ var old = $.fn.tooltip
1270
+
1271
+ $.fn.tooltip = function ( option ) {
1272
+ return this.each(function () {
1273
+ var $this = $(this)
1274
+ , data = $this.data('tooltip')
1275
+ , options = typeof option == 'object' && option
1276
+ if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
1277
+ if (typeof option == 'string') data[option]()
1278
+ })
1279
+ }
1280
+
1281
+ $.fn.tooltip.Constructor = Tooltip
1282
+
1283
+ $.fn.tooltip.defaults = {
1284
+ animation: true
1285
+ , placement: 'top'
1286
+ , selector: false
1287
+ , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
1288
+ , trigger: 'hover'
1289
+ , title: ''
1290
+ , delay: 0
1291
+ , html: false
1292
+ }
1293
+
1294
+
1295
+ /* TOOLTIP NO CONFLICT
1296
+ * =================== */
1297
+
1298
+ $.fn.tooltip.noConflict = function () {
1299
+ $.fn.tooltip = old
1300
+ return this
1301
+ }
1302
+
1303
+ }(window.jQuery);/* ===========================================================
1304
+ * bootstrap-popover.js v2.2.2
1305
+ * http://twitter.github.com/bootstrap/javascript.html#popovers
1306
+ * ===========================================================
1307
+ * Copyright 2012 Twitter, Inc.
1308
+ *
1309
+ * Licensed under the Apache License, Version 2.0 (the "License");
1310
+ * you may not use this file except in compliance with the License.
1311
+ * You may obtain a copy of the License at
1312
+ *
1313
+ * http://www.apache.org/licenses/LICENSE-2.0
1314
+ *
1315
+ * Unless required by applicable law or agreed to in writing, software
1316
+ * distributed under the License is distributed on an "AS IS" BASIS,
1317
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1318
+ * See the License for the specific language governing permissions and
1319
+ * limitations under the License.
1320
+ * =========================================================== */
1321
+
1322
+
1323
+ !function ($) {
1324
+
1325
+ "use strict"; // jshint ;_;
1326
+
1327
+
1328
+ /* POPOVER PUBLIC CLASS DEFINITION
1329
+ * =============================== */
1330
+
1331
+ var Popover = function (element, options) {
1332
+ this.init('popover', element, options)
1333
+ }
1334
+
1335
+
1336
+ /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
1337
+ ========================================== */
1338
+
1339
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
1340
+
1341
+ constructor: Popover
1342
+
1343
+ , setContent: function () {
1344
+ var $tip = this.tip()
1345
+ , title = this.getTitle()
1346
+ , content = this.getContent()
1347
+
1348
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1349
+ $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
1350
+
1351
+ $tip.removeClass('fade top bottom left right in')
1352
+ }
1353
+
1354
+ , hasContent: function () {
1355
+ return this.getTitle() || this.getContent()
1356
+ }
1357
+
1358
+ , getContent: function () {
1359
+ var content
1360
+ , $e = this.$element
1361
+ , o = this.options
1362
+
1363
+ content = $e.attr('data-content')
1364
+ || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
1365
+
1366
+ return content
1367
+ }
1368
+
1369
+ , tip: function () {
1370
+ if (!this.$tip) {
1371
+ this.$tip = $(this.options.template)
1372
+ }
1373
+ return this.$tip
1374
+ }
1375
+
1376
+ , destroy: function () {
1377
+ this.hide().$element.off('.' + this.type).removeData(this.type)
1378
+ }
1379
+
1380
+ })
1381
+
1382
+
1383
+ /* POPOVER PLUGIN DEFINITION
1384
+ * ======================= */
1385
+
1386
+ var old = $.fn.popover
1387
+
1388
+ $.fn.popover = function (option) {
1389
+ return this.each(function () {
1390
+ var $this = $(this)
1391
+ , data = $this.data('popover')
1392
+ , options = typeof option == 'object' && option
1393
+ if (!data) $this.data('popover', (data = new Popover(this, options)))
1394
+ if (typeof option == 'string') data[option]()
1395
+ })
1396
+ }
1397
+
1398
+ $.fn.popover.Constructor = Popover
1399
+
1400
+ $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
1401
+ placement: 'right'
1402
+ , trigger: 'click'
1403
+ , content: ''
1404
+ , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"></div></div></div>'
1405
+ })
1406
+
1407
+
1408
+ /* POPOVER NO CONFLICT
1409
+ * =================== */
1410
+
1411
+ $.fn.popover.noConflict = function () {
1412
+ $.fn.popover = old
1413
+ return this
1414
+ }
1415
+
1416
+ }(window.jQuery);/* =============================================================
1417
+ * bootstrap-scrollspy.js v2.2.2
1418
+ * http://twitter.github.com/bootstrap/javascript.html#scrollspy
1419
+ * =============================================================
1420
+ * Copyright 2012 Twitter, Inc.
1421
+ *
1422
+ * Licensed under the Apache License, Version 2.0 (the "License");
1423
+ * you may not use this file except in compliance with the License.
1424
+ * You may obtain a copy of the License at
1425
+ *
1426
+ * http://www.apache.org/licenses/LICENSE-2.0
1427
+ *
1428
+ * Unless required by applicable law or agreed to in writing, software
1429
+ * distributed under the License is distributed on an "AS IS" BASIS,
1430
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1431
+ * See the License for the specific language governing permissions and
1432
+ * limitations under the License.
1433
+ * ============================================================== */
1434
+
1435
+
1436
+ !function ($) {
1437
+
1438
+ "use strict"; // jshint ;_;
1439
+
1440
+
1441
+ /* SCROLLSPY CLASS DEFINITION
1442
+ * ========================== */
1443
+
1444
+ function ScrollSpy(element, options) {
1445
+ var process = $.proxy(this.process, this)
1446
+ , $element = $(element).is('body') ? $(window) : $(element)
1447
+ , href
1448
+ this.options = $.extend({}, $.fn.scrollspy.defaults, options)
1449
+ this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
1450
+ this.selector = (this.options.target
1451
+ || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1452
+ || '') + ' .nav li > a'
1453
+ this.$body = $('body')
1454
+ this.refresh()
1455
+ this.process()
1456
+ }
1457
+
1458
+ ScrollSpy.prototype = {
1459
+
1460
+ constructor: ScrollSpy
1461
+
1462
+ , refresh: function () {
1463
+ var self = this
1464
+ , $targets
1465
+
1466
+ this.offsets = $([])
1467
+ this.targets = $([])
1468
+
1469
+ $targets = this.$body
1470
+ .find(this.selector)
1471
+ .map(function () {
1472
+ var $el = $(this)
1473
+ , href = $el.data('target') || $el.attr('href')
1474
+ , $href = /^#\w/.test(href) && $(href)
1475
+ return ( $href
1476
+ && $href.length
1477
+ && [[ $href.position().top + self.$scrollElement.scrollTop(), href ]] ) || null
1478
+ })
1479
+ .sort(function (a, b) { return a[0] - b[0] })
1480
+ .each(function () {
1481
+ self.offsets.push(this[0])
1482
+ self.targets.push(this[1])
1483
+ })
1484
+ }
1485
+
1486
+ , process: function () {
1487
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
1488
+ , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
1489
+ , maxScroll = scrollHeight - this.$scrollElement.height()
1490
+ , offsets = this.offsets
1491
+ , targets = this.targets
1492
+ , activeTarget = this.activeTarget
1493
+ , i
1494
+
1495
+ if (scrollTop >= maxScroll) {
1496
+ return activeTarget != (i = targets.last()[0])
1497
+ && this.activate ( i )
1498
+ }
1499
+
1500
+ for (i = offsets.length; i--;) {
1501
+ activeTarget != targets[i]
1502
+ && scrollTop >= offsets[i]
1503
+ && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
1504
+ && this.activate( targets[i] )
1505
+ }
1506
+ }
1507
+
1508
+ , activate: function (target) {
1509
+ var active
1510
+ , selector
1511
+
1512
+ this.activeTarget = target
1513
+
1514
+ $(this.selector)
1515
+ .parent('.active')
1516
+ .removeClass('active')
1517
+
1518
+ selector = this.selector
1519
+ + '[data-target="' + target + '"],'
1520
+ + this.selector + '[href="' + target + '"]'
1521
+
1522
+ active = $(selector)
1523
+ .parent('li')
1524
+ .addClass('active')
1525
+
1526
+ if (active.parent('.dropdown-menu').length) {
1527
+ active = active.closest('li.dropdown').addClass('active')
1528
+ }
1529
+
1530
+ active.trigger('activate')
1531
+ }
1532
+
1533
+ }
1534
+
1535
+
1536
+ /* SCROLLSPY PLUGIN DEFINITION
1537
+ * =========================== */
1538
+
1539
+ var old = $.fn.scrollspy
1540
+
1541
+ $.fn.scrollspy = function (option) {
1542
+ return this.each(function () {
1543
+ var $this = $(this)
1544
+ , data = $this.data('scrollspy')
1545
+ , options = typeof option == 'object' && option
1546
+ if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
1547
+ if (typeof option == 'string') data[option]()
1548
+ })
1549
+ }
1550
+
1551
+ $.fn.scrollspy.Constructor = ScrollSpy
1552
+
1553
+ $.fn.scrollspy.defaults = {
1554
+ offset: 10
1555
+ }
1556
+
1557
+
1558
+ /* SCROLLSPY NO CONFLICT
1559
+ * ===================== */
1560
+
1561
+ $.fn.scrollspy.noConflict = function () {
1562
+ $.fn.scrollspy = old
1563
+ return this
1564
+ }
1565
+
1566
+
1567
+ /* SCROLLSPY DATA-API
1568
+ * ================== */
1569
+
1570
+ $(window).on('load', function () {
1571
+ $('[data-spy="scroll"]').each(function () {
1572
+ var $spy = $(this)
1573
+ $spy.scrollspy($spy.data())
1574
+ })
1575
+ })
1576
+
1577
+ }(window.jQuery);/* ========================================================
1578
+ * bootstrap-tab.js v2.2.2
1579
+ * http://twitter.github.com/bootstrap/javascript.html#tabs
1580
+ * ========================================================
1581
+ * Copyright 2012 Twitter, Inc.
1582
+ *
1583
+ * Licensed under the Apache License, Version 2.0 (the "License");
1584
+ * you may not use this file except in compliance with the License.
1585
+ * You may obtain a copy of the License at
1586
+ *
1587
+ * http://www.apache.org/licenses/LICENSE-2.0
1588
+ *
1589
+ * Unless required by applicable law or agreed to in writing, software
1590
+ * distributed under the License is distributed on an "AS IS" BASIS,
1591
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1592
+ * See the License for the specific language governing permissions and
1593
+ * limitations under the License.
1594
+ * ======================================================== */
1595
+
1596
+
1597
+ !function ($) {
1598
+
1599
+ "use strict"; // jshint ;_;
1600
+
1601
+
1602
+ /* TAB CLASS DEFINITION
1603
+ * ==================== */
1604
+
1605
+ var Tab = function (element) {
1606
+ this.element = $(element)
1607
+ }
1608
+
1609
+ Tab.prototype = {
1610
+
1611
+ constructor: Tab
1612
+
1613
+ , show: function () {
1614
+ var $this = this.element
1615
+ , $ul = $this.closest('ul:not(.dropdown-menu)')
1616
+ , selector = $this.attr('data-target')
1617
+ , previous
1618
+ , $target
1619
+ , e
1620
+
1621
+ if (!selector) {
1622
+ selector = $this.attr('href')
1623
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
1624
+ }
1625
+
1626
+ if ( $this.parent('li').hasClass('active') ) return
1627
+
1628
+ previous = $ul.find('.active:last a')[0]
1629
+
1630
+ e = $.Event('show', {
1631
+ relatedTarget: previous
1632
+ })
1633
+
1634
+ $this.trigger(e)
1635
+
1636
+ if (e.isDefaultPrevented()) return
1637
+
1638
+ $target = $(selector)
1639
+
1640
+ this.activate($this.parent('li'), $ul)
1641
+ this.activate($target, $target.parent(), function () {
1642
+ $this.trigger({
1643
+ type: 'shown'
1644
+ , relatedTarget: previous
1645
+ })
1646
+ })
1647
+ }
1648
+
1649
+ , activate: function ( element, container, callback) {
1650
+ var $active = container.find('> .active')
1651
+ , transition = callback
1652
+ && $.support.transition
1653
+ && $active.hasClass('fade')
1654
+
1655
+ function next() {
1656
+ $active
1657
+ .removeClass('active')
1658
+ .find('> .dropdown-menu > .active')
1659
+ .removeClass('active')
1660
+
1661
+ element.addClass('active')
1662
+
1663
+ if (transition) {
1664
+ element[0].offsetWidth // reflow for transition
1665
+ element.addClass('in')
1666
+ } else {
1667
+ element.removeClass('fade')
1668
+ }
1669
+
1670
+ if ( element.parent('.dropdown-menu') ) {
1671
+ element.closest('li.dropdown').addClass('active')
1672
+ }
1673
+
1674
+ callback && callback()
1675
+ }
1676
+
1677
+ transition ?
1678
+ $active.one($.support.transition.end, next) :
1679
+ next()
1680
+
1681
+ $active.removeClass('in')
1682
+ }
1683
+ }
1684
+
1685
+
1686
+ /* TAB PLUGIN DEFINITION
1687
+ * ===================== */
1688
+
1689
+ var old = $.fn.tab
1690
+
1691
+ $.fn.tab = function ( option ) {
1692
+ return this.each(function () {
1693
+ var $this = $(this)
1694
+ , data = $this.data('tab')
1695
+ if (!data) $this.data('tab', (data = new Tab(this)))
1696
+ if (typeof option == 'string') data[option]()
1697
+ })
1698
+ }
1699
+
1700
+ $.fn.tab.Constructor = Tab
1701
+
1702
+
1703
+ /* TAB NO CONFLICT
1704
+ * =============== */
1705
+
1706
+ $.fn.tab.noConflict = function () {
1707
+ $.fn.tab = old
1708
+ return this
1709
+ }
1710
+
1711
+
1712
+ /* TAB DATA-API
1713
+ * ============ */
1714
+
1715
+ $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
1716
+ e.preventDefault()
1717
+ $(this).tab('show')
1718
+ })
1719
+
1720
+ }(window.jQuery);/* =============================================================
1721
+ * bootstrap-typeahead.js v2.2.2
1722
+ * http://twitter.github.com/bootstrap/javascript.html#typeahead
1723
+ * =============================================================
1724
+ * Copyright 2012 Twitter, Inc.
1725
+ *
1726
+ * Licensed under the Apache License, Version 2.0 (the "License");
1727
+ * you may not use this file except in compliance with the License.
1728
+ * You may obtain a copy of the License at
1729
+ *
1730
+ * http://www.apache.org/licenses/LICENSE-2.0
1731
+ *
1732
+ * Unless required by applicable law or agreed to in writing, software
1733
+ * distributed under the License is distributed on an "AS IS" BASIS,
1734
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1735
+ * See the License for the specific language governing permissions and
1736
+ * limitations under the License.
1737
+ * ============================================================ */
1738
+
1739
+
1740
+ !function($){
1741
+
1742
+ "use strict"; // jshint ;_;
1743
+
1744
+
1745
+ /* TYPEAHEAD PUBLIC CLASS DEFINITION
1746
+ * ================================= */
1747
+
1748
+ var Typeahead = function (element, options) {
1749
+ this.$element = $(element)
1750
+ this.options = $.extend({}, $.fn.typeahead.defaults, options)
1751
+ this.matcher = this.options.matcher || this.matcher
1752
+ this.sorter = this.options.sorter || this.sorter
1753
+ this.highlighter = this.options.highlighter || this.highlighter
1754
+ this.updater = this.options.updater || this.updater
1755
+ this.source = this.options.source
1756
+ this.$menu = $(this.options.menu)
1757
+ this.shown = false
1758
+ this.listen()
1759
+ }
1760
+
1761
+ Typeahead.prototype = {
1762
+
1763
+ constructor: Typeahead
1764
+
1765
+ , select: function () {
1766
+ var val = this.$menu.find('.active').attr('data-value')
1767
+ this.$element
1768
+ .val(this.updater(val))
1769
+ .change()
1770
+ return this.hide()
1771
+ }
1772
+
1773
+ , updater: function (item) {
1774
+ return item
1775
+ }
1776
+
1777
+ , show: function () {
1778
+ var pos = $.extend({}, this.$element.position(), {
1779
+ height: this.$element[0].offsetHeight
1780
+ })
1781
+
1782
+ this.$menu
1783
+ .insertAfter(this.$element)
1784
+ .css({
1785
+ top: pos.top + pos.height
1786
+ , left: pos.left
1787
+ })
1788
+ .show()
1789
+
1790
+ this.shown = true
1791
+ return this
1792
+ }
1793
+
1794
+ , hide: function () {
1795
+ this.$menu.hide()
1796
+ this.shown = false
1797
+ return this
1798
+ }
1799
+
1800
+ , lookup: function (event) {
1801
+ var items
1802
+
1803
+ this.query = this.$element.val()
1804
+
1805
+ if (!this.query || this.query.length < this.options.minLength) {
1806
+ return this.shown ? this.hide() : this
1807
+ }
1808
+
1809
+ items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
1810
+
1811
+ return items ? this.process(items) : this
1812
+ }
1813
+
1814
+ , process: function (items) {
1815
+ var that = this
1816
+
1817
+ items = $.grep(items, function (item) {
1818
+ return that.matcher(item)
1819
+ })
1820
+
1821
+ items = this.sorter(items)
1822
+
1823
+ if (!items.length) {
1824
+ return this.shown ? this.hide() : this
1825
+ }
1826
+
1827
+ return this.render(items.slice(0, this.options.items)).show()
1828
+ }
1829
+
1830
+ , matcher: function (item) {
1831
+ return ~item.toLowerCase().indexOf(this.query.toLowerCase())
1832
+ }
1833
+
1834
+ , sorter: function (items) {
1835
+ var beginswith = []
1836
+ , caseSensitive = []
1837
+ , caseInsensitive = []
1838
+ , item
1839
+
1840
+ while (item = items.shift()) {
1841
+ if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
1842
+ else if (~item.indexOf(this.query)) caseSensitive.push(item)
1843
+ else caseInsensitive.push(item)
1844
+ }
1845
+
1846
+ return beginswith.concat(caseSensitive, caseInsensitive)
1847
+ }
1848
+
1849
+ , highlighter: function (item) {
1850
+ var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
1851
+ return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
1852
+ return '<strong>' + match + '</strong>'
1853
+ })
1854
+ }
1855
+
1856
+ , render: function (items) {
1857
+ var that = this
1858
+
1859
+ items = $(items).map(function (i, item) {
1860
+ i = $(that.options.item).attr('data-value', item)
1861
+ i.find('a').html(that.highlighter(item))
1862
+ return i[0]
1863
+ })
1864
+
1865
+ items.first().addClass('active')
1866
+ this.$menu.html(items)
1867
+ return this
1868
+ }
1869
+
1870
+ , next: function (event) {
1871
+ var active = this.$menu.find('.active').removeClass('active')
1872
+ , next = active.next()
1873
+
1874
+ if (!next.length) {
1875
+ next = $(this.$menu.find('li')[0])
1876
+ }
1877
+
1878
+ next.addClass('active')
1879
+ }
1880
+
1881
+ , prev: function (event) {
1882
+ var active = this.$menu.find('.active').removeClass('active')
1883
+ , prev = active.prev()
1884
+
1885
+ if (!prev.length) {
1886
+ prev = this.$menu.find('li').last()
1887
+ }
1888
+
1889
+ prev.addClass('active')
1890
+ }
1891
+
1892
+ , listen: function () {
1893
+ this.$element
1894
+ .on('blur', $.proxy(this.blur, this))
1895
+ .on('keypress', $.proxy(this.keypress, this))
1896
+ .on('keyup', $.proxy(this.keyup, this))
1897
+
1898
+ if (this.eventSupported('keydown')) {
1899
+ this.$element.on('keydown', $.proxy(this.keydown, this))
1900
+ }
1901
+
1902
+ this.$menu
1903
+ .on('click', $.proxy(this.click, this))
1904
+ .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
1905
+ }
1906
+
1907
+ , eventSupported: function(eventName) {
1908
+ var isSupported = eventName in this.$element
1909
+ if (!isSupported) {
1910
+ this.$element.setAttribute(eventName, 'return;')
1911
+ isSupported = typeof this.$element[eventName] === 'function'
1912
+ }
1913
+ return isSupported
1914
+ }
1915
+
1916
+ , move: function (e) {
1917
+ if (!this.shown) return
1918
+
1919
+ switch(e.keyCode) {
1920
+ case 9: // tab
1921
+ case 13: // enter
1922
+ case 27: // escape
1923
+ e.preventDefault()
1924
+ break
1925
+
1926
+ case 38: // up arrow
1927
+ e.preventDefault()
1928
+ this.prev()
1929
+ break
1930
+
1931
+ case 40: // down arrow
1932
+ e.preventDefault()
1933
+ this.next()
1934
+ break
1935
+ }
1936
+
1937
+ e.stopPropagation()
1938
+ }
1939
+
1940
+ , keydown: function (e) {
1941
+ this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
1942
+ this.move(e)
1943
+ }
1944
+
1945
+ , keypress: function (e) {
1946
+ if (this.suppressKeyPressRepeat) return
1947
+ this.move(e)
1948
+ }
1949
+
1950
+ , keyup: function (e) {
1951
+ switch(e.keyCode) {
1952
+ case 40: // down arrow
1953
+ case 38: // up arrow
1954
+ case 16: // shift
1955
+ case 17: // ctrl
1956
+ case 18: // alt
1957
+ break
1958
+
1959
+ case 9: // tab
1960
+ case 13: // enter
1961
+ if (!this.shown) return
1962
+ this.select()
1963
+ break
1964
+
1965
+ case 27: // escape
1966
+ if (!this.shown) return
1967
+ this.hide()
1968
+ break
1969
+
1970
+ default:
1971
+ this.lookup()
1972
+ }
1973
+
1974
+ e.stopPropagation()
1975
+ e.preventDefault()
1976
+ }
1977
+
1978
+ , blur: function (e) {
1979
+ var that = this
1980
+ setTimeout(function () { that.hide() }, 150)
1981
+ }
1982
+
1983
+ , click: function (e) {
1984
+ e.stopPropagation()
1985
+ e.preventDefault()
1986
+ this.select()
1987
+ }
1988
+
1989
+ , mouseenter: function (e) {
1990
+ this.$menu.find('.active').removeClass('active')
1991
+ $(e.currentTarget).addClass('active')
1992
+ }
1993
+
1994
+ }
1995
+
1996
+
1997
+ /* TYPEAHEAD PLUGIN DEFINITION
1998
+ * =========================== */
1999
+
2000
+ var old = $.fn.typeahead
2001
+
2002
+ $.fn.typeahead = function (option) {
2003
+ return this.each(function () {
2004
+ var $this = $(this)
2005
+ , data = $this.data('typeahead')
2006
+ , options = typeof option == 'object' && option
2007
+ if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
2008
+ if (typeof option == 'string') data[option]()
2009
+ })
2010
+ }
2011
+
2012
+ $.fn.typeahead.defaults = {
2013
+ source: []
2014
+ , items: 8
2015
+ , menu: '<ul class="typeahead dropdown-menu"></ul>'
2016
+ , item: '<li><a href="#"></a></li>'
2017
+ , minLength: 1
2018
+ }
2019
+
2020
+ $.fn.typeahead.Constructor = Typeahead
2021
+
2022
+
2023
+ /* TYPEAHEAD NO CONFLICT
2024
+ * =================== */
2025
+
2026
+ $.fn.typeahead.noConflict = function () {
2027
+ $.fn.typeahead = old
2028
+ return this
2029
+ }
2030
+
2031
+
2032
+ /* TYPEAHEAD DATA-API
2033
+ * ================== */
2034
+
2035
+ $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
2036
+ var $this = $(this)
2037
+ if ($this.data('typeahead')) return
2038
+ e.preventDefault()
2039
+ $this.typeahead($this.data())
2040
+ })
2041
+
2042
+ }(window.jQuery);
2043
+ /* ==========================================================
2044
+ * bootstrap-affix.js v2.2.2
2045
+ * http://twitter.github.com/bootstrap/javascript.html#affix
2046
+ * ==========================================================
2047
+ * Copyright 2012 Twitter, Inc.
2048
+ *
2049
+ * Licensed under the Apache License, Version 2.0 (the "License");
2050
+ * you may not use this file except in compliance with the License.
2051
+ * You may obtain a copy of the License at
2052
+ *
2053
+ * http://www.apache.org/licenses/LICENSE-2.0
2054
+ *
2055
+ * Unless required by applicable law or agreed to in writing, software
2056
+ * distributed under the License is distributed on an "AS IS" BASIS,
2057
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2058
+ * See the License for the specific language governing permissions and
2059
+ * limitations under the License.
2060
+ * ========================================================== */
2061
+
2062
+
2063
+ !function ($) {
2064
+
2065
+ "use strict"; // jshint ;_;
2066
+
2067
+
2068
+ /* AFFIX CLASS DEFINITION
2069
+ * ====================== */
2070
+
2071
+ var Affix = function (element, options) {
2072
+ this.options = $.extend({}, $.fn.affix.defaults, options)
2073
+ this.$window = $(window)
2074
+ .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
2075
+ .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
2076
+ this.$element = $(element)
2077
+ this.checkPosition()
2078
+ }
2079
+
2080
+ Affix.prototype.checkPosition = function () {
2081
+ if (!this.$element.is(':visible')) return
2082
+
2083
+ var scrollHeight = $(document).height()
2084
+ , scrollTop = this.$window.scrollTop()
2085
+ , position = this.$element.offset()
2086
+ , offset = this.options.offset
2087
+ , offsetBottom = offset.bottom
2088
+ , offsetTop = offset.top
2089
+ , reset = 'affix affix-top affix-bottom'
2090
+ , affix
2091
+
2092
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
2093
+ if (typeof offsetTop == 'function') offsetTop = offset.top()
2094
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
2095
+
2096
+ affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
2097
+ false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
2098
+ 'bottom' : offsetTop != null && scrollTop <= offsetTop ?
2099
+ 'top' : false
2100
+
2101
+ if (this.affixed === affix) return
2102
+
2103
+ this.affixed = affix
2104
+ this.unpin = affix == 'bottom' ? position.top - scrollTop : null
2105
+
2106
+ this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
2107
+ }
2108
+
2109
+
2110
+ /* AFFIX PLUGIN DEFINITION
2111
+ * ======================= */
2112
+
2113
+ var old = $.fn.affix
2114
+
2115
+ $.fn.affix = function (option) {
2116
+ return this.each(function () {
2117
+ var $this = $(this)
2118
+ , data = $this.data('affix')
2119
+ , options = typeof option == 'object' && option
2120
+ if (!data) $this.data('affix', (data = new Affix(this, options)))
2121
+ if (typeof option == 'string') data[option]()
2122
+ })
2123
+ }
2124
+
2125
+ $.fn.affix.Constructor = Affix
2126
+
2127
+ $.fn.affix.defaults = {
2128
+ offset: 0
2129
+ }
2130
+
2131
+
2132
+ /* AFFIX NO CONFLICT
2133
+ * ================= */
2134
+
2135
+ $.fn.affix.noConflict = function () {
2136
+ $.fn.affix = old
2137
+ return this
2138
+ }
2139
+
2140
+
2141
+ /* AFFIX DATA-API
2142
+ * ============== */
2143
+
2144
+ $(window).on('load', function () {
2145
+ $('[data-spy="affix"]').each(function () {
2146
+ var $spy = $(this)
2147
+ , data = $spy.data()
2148
+
2149
+ data.offset = data.offset || {}
2150
+
2151
+ data.offsetBottom && (data.offset.bottom = data.offsetBottom)
2152
+ data.offsetTop && (data.offset.top = data.offsetTop)
2153
+
2154
+ $spy.affix(data)
2155
+ })
2156
+ })
2157
+
2158
+
2159
+ }(window.jQuery);