hell 0.0.1

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