finery 3.0.0 → 3.0.2

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/assets/javascripts/blazer/application.js +2 -61
  4. data/app/assets/javascripts/blazer/controllers/application.js.erb +2 -0
  5. data/app/assets/javascripts/blazer/controllers/autosubmit_controller.js +11 -0
  6. data/app/assets/javascripts/blazer/controllers/code_controller.js +7 -0
  7. data/app/assets/javascripts/blazer/controllers/datepicker_controller.js +31 -0
  8. data/app/assets/javascripts/blazer/controllers/daterangepicker_controller.js +49 -0
  9. data/app/assets/javascripts/blazer/controllers/index.js +12 -0
  10. data/app/assets/javascripts/blazer/controllers/navbar_padding_controller.js +7 -0
  11. data/app/assets/javascripts/blazer/controllers/selectize_controller.js +8 -0
  12. data/app/assets/javascripts/blazer/controllers/unsaved_controller.js +24 -0
  13. data/app/assets/javascripts/blazer/module.js +1 -0
  14. data/app/assets/stylesheets/blazer/application.css +17 -60
  15. data/app/controllers/blazer/base_controller.rb +6 -5
  16. data/app/controllers/blazer/queries_controller.rb +3 -1
  17. data/app/views/blazer/_navbar.html.erb +38 -0
  18. data/app/views/blazer/_variables.html.erb +9 -87
  19. data/app/views/blazer/checks/_form.html.erb +6 -6
  20. data/app/views/blazer/checks/index.html.erb +0 -19
  21. data/app/views/blazer/dashboards/_form.html.erb +7 -5
  22. data/app/views/blazer/dashboards/show.html.erb +7 -18
  23. data/app/views/blazer/queries/_form.html.erb +20 -14
  24. data/app/views/blazer/queries/home.html.erb +17 -30
  25. data/app/views/blazer/queries/run.html.erb +1 -1
  26. data/app/views/blazer/queries/show.html.erb +24 -35
  27. data/app/views/blazer/uploads/_form.html.erb +3 -3
  28. data/app/views/blazer/uploads/index.html.erb +0 -18
  29. data/app/views/layouts/blazer/application.html.erb +10 -10
  30. data/lib/blazer/engine.rb +1 -5
  31. data/lib/blazer/version.rb +1 -1
  32. data/lib/blazer.rb +12 -8
  33. metadata +27 -14
  34. data/app/assets/fonts/blazer/glyphicons-halflings-regular.eot +0 -0
  35. data/app/assets/fonts/blazer/glyphicons-halflings-regular.svg +0 -288
  36. data/app/assets/fonts/blazer/glyphicons-halflings-regular.ttf +0 -0
  37. data/app/assets/fonts/blazer/glyphicons-halflings-regular.woff +0 -0
  38. data/app/assets/fonts/blazer/glyphicons-halflings-regular.woff2 +0 -0
  39. data/app/assets/javascripts/blazer/bootstrap.js +0 -2580
  40. data/app/assets/javascripts/blazer/selectize.js +0 -3891
  41. data/app/assets/stylesheets/blazer/bootstrap-propshaft.css +0 -10
  42. data/app/assets/stylesheets/blazer/bootstrap-sprockets.css.erb +0 -10
  43. data/app/assets/stylesheets/blazer/bootstrap.css +0 -6828
  44. data/app/assets/stylesheets/blazer/selectize.css +0 -403
  45. data/app/views/blazer/_nav.html.erb +0 -18
@@ -1,2580 +0,0 @@
1
- /*!
2
- * Bootstrap v3.4.1 (https://getbootstrap.com/)
3
- * Copyright 2011-2019 Twitter, Inc.
4
- * Licensed under the MIT license
5
- */
6
-
7
- if (typeof jQuery === 'undefined') {
8
- throw new Error('Bootstrap\'s JavaScript requires jQuery')
9
- }
10
-
11
- +function ($) {
12
- 'use strict';
13
- var version = $.fn.jquery.split(' ')[0].split('.')
14
- if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {
15
- throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
16
- }
17
- }(jQuery);
18
-
19
- /* ========================================================================
20
- * Bootstrap: transition.js v3.4.1
21
- * https://getbootstrap.com/docs/3.4/javascript/#transitions
22
- * ========================================================================
23
- * Copyright 2011-2019 Twitter, Inc.
24
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
25
- * ======================================================================== */
26
-
27
-
28
- +function ($) {
29
- 'use strict';
30
-
31
- // CSS TRANSITION SUPPORT (Shoutout: https://modernizr.com/)
32
- // ============================================================
33
-
34
- function transitionEnd() {
35
- var el = document.createElement('bootstrap')
36
-
37
- var transEndEventNames = {
38
- WebkitTransition : 'webkitTransitionEnd',
39
- MozTransition : 'transitionend',
40
- OTransition : 'oTransitionEnd otransitionend',
41
- transition : 'transitionend'
42
- }
43
-
44
- for (var name in transEndEventNames) {
45
- if (el.style[name] !== undefined) {
46
- return { end: transEndEventNames[name] }
47
- }
48
- }
49
-
50
- return false // explicit for ie8 ( ._.)
51
- }
52
-
53
- // https://blog.alexmaccaw.com/css-transitions
54
- $.fn.emulateTransitionEnd = function (duration) {
55
- var called = false
56
- var $el = this
57
- $(this).one('bsTransitionEnd', function () { called = true })
58
- var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
59
- setTimeout(callback, duration)
60
- return this
61
- }
62
-
63
- $(function () {
64
- $.support.transition = transitionEnd()
65
-
66
- if (!$.support.transition) return
67
-
68
- $.event.special.bsTransitionEnd = {
69
- bindType: $.support.transition.end,
70
- delegateType: $.support.transition.end,
71
- handle: function (e) {
72
- if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
73
- }
74
- }
75
- })
76
-
77
- }(jQuery);
78
-
79
- /* ========================================================================
80
- * Bootstrap: alert.js v3.4.1
81
- * https://getbootstrap.com/docs/3.4/javascript/#alerts
82
- * ========================================================================
83
- * Copyright 2011-2019 Twitter, Inc.
84
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
85
- * ======================================================================== */
86
-
87
-
88
- +function ($) {
89
- 'use strict';
90
-
91
- // ALERT CLASS DEFINITION
92
- // ======================
93
-
94
- var dismiss = '[data-dismiss="alert"]'
95
- var Alert = function (el) {
96
- $(el).on('click', dismiss, this.close)
97
- }
98
-
99
- Alert.VERSION = '3.4.1'
100
-
101
- Alert.TRANSITION_DURATION = 150
102
-
103
- Alert.prototype.close = function (e) {
104
- var $this = $(this)
105
- var selector = $this.attr('data-target')
106
-
107
- if (!selector) {
108
- selector = $this.attr('href')
109
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
110
- }
111
-
112
- selector = selector === '#' ? [] : selector
113
- var $parent = $(document).find(selector)
114
-
115
- if (e) e.preventDefault()
116
-
117
- if (!$parent.length) {
118
- $parent = $this.closest('.alert')
119
- }
120
-
121
- $parent.trigger(e = $.Event('close.bs.alert'))
122
-
123
- if (e.isDefaultPrevented()) return
124
-
125
- $parent.removeClass('in')
126
-
127
- function removeElement() {
128
- // detach from parent, fire event then clean up data
129
- $parent.detach().trigger('closed.bs.alert').remove()
130
- }
131
-
132
- $.support.transition && $parent.hasClass('fade') ?
133
- $parent
134
- .one('bsTransitionEnd', removeElement)
135
- .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
136
- removeElement()
137
- }
138
-
139
-
140
- // ALERT PLUGIN DEFINITION
141
- // =======================
142
-
143
- function Plugin(option) {
144
- return this.each(function () {
145
- var $this = $(this)
146
- var data = $this.data('bs.alert')
147
-
148
- if (!data) $this.data('bs.alert', (data = new Alert(this)))
149
- if (typeof option == 'string') data[option].call($this)
150
- })
151
- }
152
-
153
- var old = $.fn.alert
154
-
155
- $.fn.alert = Plugin
156
- $.fn.alert.Constructor = Alert
157
-
158
-
159
- // ALERT NO CONFLICT
160
- // =================
161
-
162
- $.fn.alert.noConflict = function () {
163
- $.fn.alert = old
164
- return this
165
- }
166
-
167
-
168
- // ALERT DATA-API
169
- // ==============
170
-
171
- $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
172
-
173
- }(jQuery);
174
-
175
- /* ========================================================================
176
- * Bootstrap: button.js v3.4.1
177
- * https://getbootstrap.com/docs/3.4/javascript/#buttons
178
- * ========================================================================
179
- * Copyright 2011-2019 Twitter, Inc.
180
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
181
- * ======================================================================== */
182
-
183
-
184
- +function ($) {
185
- 'use strict';
186
-
187
- // BUTTON PUBLIC CLASS DEFINITION
188
- // ==============================
189
-
190
- var Button = function (element, options) {
191
- this.$element = $(element)
192
- this.options = $.extend({}, Button.DEFAULTS, options)
193
- this.isLoading = false
194
- }
195
-
196
- Button.VERSION = '3.4.1'
197
-
198
- Button.DEFAULTS = {
199
- loadingText: 'loading...'
200
- }
201
-
202
- Button.prototype.setState = function (state) {
203
- var d = 'disabled'
204
- var $el = this.$element
205
- var val = $el.is('input') ? 'val' : 'html'
206
- var data = $el.data()
207
-
208
- state += 'Text'
209
-
210
- if (data.resetText == null) $el.data('resetText', $el[val]())
211
-
212
- // push to event loop to allow forms to submit
213
- setTimeout($.proxy(function () {
214
- $el[val](data[state] == null ? this.options[state] : data[state])
215
-
216
- if (state == 'loadingText') {
217
- this.isLoading = true
218
- $el.addClass(d).attr(d, d).prop(d, true)
219
- } else if (this.isLoading) {
220
- this.isLoading = false
221
- $el.removeClass(d).removeAttr(d).prop(d, false)
222
- }
223
- }, this), 0)
224
- }
225
-
226
- Button.prototype.toggle = function () {
227
- var changed = true
228
- var $parent = this.$element.closest('[data-toggle="buttons"]')
229
-
230
- if ($parent.length) {
231
- var $input = this.$element.find('input')
232
- if ($input.prop('type') == 'radio') {
233
- if ($input.prop('checked')) changed = false
234
- $parent.find('.active').removeClass('active')
235
- this.$element.addClass('active')
236
- } else if ($input.prop('type') == 'checkbox') {
237
- if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
238
- this.$element.toggleClass('active')
239
- }
240
- $input.prop('checked', this.$element.hasClass('active'))
241
- if (changed) $input.trigger('change')
242
- } else {
243
- this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
244
- this.$element.toggleClass('active')
245
- }
246
- }
247
-
248
-
249
- // BUTTON PLUGIN DEFINITION
250
- // ========================
251
-
252
- function Plugin(option) {
253
- return this.each(function () {
254
- var $this = $(this)
255
- var data = $this.data('bs.button')
256
- var options = typeof option == 'object' && option
257
-
258
- if (!data) $this.data('bs.button', (data = new Button(this, options)))
259
-
260
- if (option == 'toggle') data.toggle()
261
- else if (option) data.setState(option)
262
- })
263
- }
264
-
265
- var old = $.fn.button
266
-
267
- $.fn.button = Plugin
268
- $.fn.button.Constructor = Button
269
-
270
-
271
- // BUTTON NO CONFLICT
272
- // ==================
273
-
274
- $.fn.button.noConflict = function () {
275
- $.fn.button = old
276
- return this
277
- }
278
-
279
-
280
- // BUTTON DATA-API
281
- // ===============
282
-
283
- $(document)
284
- .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
285
- var $btn = $(e.target).closest('.btn')
286
- Plugin.call($btn, 'toggle')
287
- if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
288
- // Prevent double click on radios, and the double selections (so cancellation) on checkboxes
289
- e.preventDefault()
290
- // The target component still receive the focus
291
- if ($btn.is('input,button')) $btn.trigger('focus')
292
- else $btn.find('input:visible,button:visible').first().trigger('focus')
293
- }
294
- })
295
- .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
296
- $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
297
- })
298
-
299
- }(jQuery);
300
-
301
- /* ========================================================================
302
- * Bootstrap: carousel.js v3.4.1
303
- * https://getbootstrap.com/docs/3.4/javascript/#carousel
304
- * ========================================================================
305
- * Copyright 2011-2019 Twitter, Inc.
306
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
307
- * ======================================================================== */
308
-
309
-
310
- +function ($) {
311
- 'use strict';
312
-
313
- // CAROUSEL CLASS DEFINITION
314
- // =========================
315
-
316
- var Carousel = function (element, options) {
317
- this.$element = $(element)
318
- this.$indicators = this.$element.find('.carousel-indicators')
319
- this.options = options
320
- this.paused = null
321
- this.sliding = null
322
- this.interval = null
323
- this.$active = null
324
- this.$items = null
325
-
326
- this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
327
-
328
- this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
329
- .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
330
- .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
331
- }
332
-
333
- Carousel.VERSION = '3.4.1'
334
-
335
- Carousel.TRANSITION_DURATION = 600
336
-
337
- Carousel.DEFAULTS = {
338
- interval: 5000,
339
- pause: 'hover',
340
- wrap: true,
341
- keyboard: true
342
- }
343
-
344
- Carousel.prototype.keydown = function (e) {
345
- if (/input|textarea/i.test(e.target.tagName)) return
346
- switch (e.which) {
347
- case 37: this.prev(); break
348
- case 39: this.next(); break
349
- default: return
350
- }
351
-
352
- e.preventDefault()
353
- }
354
-
355
- Carousel.prototype.cycle = function (e) {
356
- e || (this.paused = false)
357
-
358
- this.interval && clearInterval(this.interval)
359
-
360
- this.options.interval
361
- && !this.paused
362
- && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
363
-
364
- return this
365
- }
366
-
367
- Carousel.prototype.getItemIndex = function (item) {
368
- this.$items = item.parent().children('.item')
369
- return this.$items.index(item || this.$active)
370
- }
371
-
372
- Carousel.prototype.getItemForDirection = function (direction, active) {
373
- var activeIndex = this.getItemIndex(active)
374
- var willWrap = (direction == 'prev' && activeIndex === 0)
375
- || (direction == 'next' && activeIndex == (this.$items.length - 1))
376
- if (willWrap && !this.options.wrap) return active
377
- var delta = direction == 'prev' ? -1 : 1
378
- var itemIndex = (activeIndex + delta) % this.$items.length
379
- return this.$items.eq(itemIndex)
380
- }
381
-
382
- Carousel.prototype.to = function (pos) {
383
- var that = this
384
- var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
385
-
386
- if (pos > (this.$items.length - 1) || pos < 0) return
387
-
388
- if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
389
- if (activeIndex == pos) return this.pause().cycle()
390
-
391
- return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
392
- }
393
-
394
- Carousel.prototype.pause = function (e) {
395
- e || (this.paused = true)
396
-
397
- if (this.$element.find('.next, .prev').length && $.support.transition) {
398
- this.$element.trigger($.support.transition.end)
399
- this.cycle(true)
400
- }
401
-
402
- this.interval = clearInterval(this.interval)
403
-
404
- return this
405
- }
406
-
407
- Carousel.prototype.next = function () {
408
- if (this.sliding) return
409
- return this.slide('next')
410
- }
411
-
412
- Carousel.prototype.prev = function () {
413
- if (this.sliding) return
414
- return this.slide('prev')
415
- }
416
-
417
- Carousel.prototype.slide = function (type, next) {
418
- var $active = this.$element.find('.item.active')
419
- var $next = next || this.getItemForDirection(type, $active)
420
- var isCycling = this.interval
421
- var direction = type == 'next' ? 'left' : 'right'
422
- var that = this
423
-
424
- if ($next.hasClass('active')) return (this.sliding = false)
425
-
426
- var relatedTarget = $next[0]
427
- var slideEvent = $.Event('slide.bs.carousel', {
428
- relatedTarget: relatedTarget,
429
- direction: direction
430
- })
431
- this.$element.trigger(slideEvent)
432
- if (slideEvent.isDefaultPrevented()) return
433
-
434
- this.sliding = true
435
-
436
- isCycling && this.pause()
437
-
438
- if (this.$indicators.length) {
439
- this.$indicators.find('.active').removeClass('active')
440
- var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
441
- $nextIndicator && $nextIndicator.addClass('active')
442
- }
443
-
444
- var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
445
- if ($.support.transition && this.$element.hasClass('slide')) {
446
- $next.addClass(type)
447
- if (typeof $next === 'object' && $next.length) {
448
- $next[0].offsetWidth // force reflow
449
- }
450
- $active.addClass(direction)
451
- $next.addClass(direction)
452
- $active
453
- .one('bsTransitionEnd', function () {
454
- $next.removeClass([type, direction].join(' ')).addClass('active')
455
- $active.removeClass(['active', direction].join(' '))
456
- that.sliding = false
457
- setTimeout(function () {
458
- that.$element.trigger(slidEvent)
459
- }, 0)
460
- })
461
- .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
462
- } else {
463
- $active.removeClass('active')
464
- $next.addClass('active')
465
- this.sliding = false
466
- this.$element.trigger(slidEvent)
467
- }
468
-
469
- isCycling && this.cycle()
470
-
471
- return this
472
- }
473
-
474
-
475
- // CAROUSEL PLUGIN DEFINITION
476
- // ==========================
477
-
478
- function Plugin(option) {
479
- return this.each(function () {
480
- var $this = $(this)
481
- var data = $this.data('bs.carousel')
482
- var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
483
- var action = typeof option == 'string' ? option : options.slide
484
-
485
- if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
486
- if (typeof option == 'number') data.to(option)
487
- else if (action) data[action]()
488
- else if (options.interval) data.pause().cycle()
489
- })
490
- }
491
-
492
- var old = $.fn.carousel
493
-
494
- $.fn.carousel = Plugin
495
- $.fn.carousel.Constructor = Carousel
496
-
497
-
498
- // CAROUSEL NO CONFLICT
499
- // ====================
500
-
501
- $.fn.carousel.noConflict = function () {
502
- $.fn.carousel = old
503
- return this
504
- }
505
-
506
-
507
- // CAROUSEL DATA-API
508
- // =================
509
-
510
- var clickHandler = function (e) {
511
- var $this = $(this)
512
- var href = $this.attr('href')
513
- if (href) {
514
- href = href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
515
- }
516
-
517
- var target = $this.attr('data-target') || href
518
- var $target = $(document).find(target)
519
-
520
- if (!$target.hasClass('carousel')) return
521
-
522
- var options = $.extend({}, $target.data(), $this.data())
523
- var slideIndex = $this.attr('data-slide-to')
524
- if (slideIndex) options.interval = false
525
-
526
- Plugin.call($target, options)
527
-
528
- if (slideIndex) {
529
- $target.data('bs.carousel').to(slideIndex)
530
- }
531
-
532
- e.preventDefault()
533
- }
534
-
535
- $(document)
536
- .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
537
- .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
538
-
539
- $(window).on('load', function () {
540
- $('[data-ride="carousel"]').each(function () {
541
- var $carousel = $(this)
542
- Plugin.call($carousel, $carousel.data())
543
- })
544
- })
545
-
546
- }(jQuery);
547
-
548
- /* ========================================================================
549
- * Bootstrap: collapse.js v3.4.1
550
- * https://getbootstrap.com/docs/3.4/javascript/#collapse
551
- * ========================================================================
552
- * Copyright 2011-2019 Twitter, Inc.
553
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
554
- * ======================================================================== */
555
-
556
- /* jshint latedef: false */
557
-
558
- +function ($) {
559
- 'use strict';
560
-
561
- // COLLAPSE PUBLIC CLASS DEFINITION
562
- // ================================
563
-
564
- var Collapse = function (element, options) {
565
- this.$element = $(element)
566
- this.options = $.extend({}, Collapse.DEFAULTS, options)
567
- this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
568
- '[data-toggle="collapse"][data-target="#' + element.id + '"]')
569
- this.transitioning = null
570
-
571
- if (this.options.parent) {
572
- this.$parent = this.getParent()
573
- } else {
574
- this.addAriaAndCollapsedClass(this.$element, this.$trigger)
575
- }
576
-
577
- if (this.options.toggle) this.toggle()
578
- }
579
-
580
- Collapse.VERSION = '3.4.1'
581
-
582
- Collapse.TRANSITION_DURATION = 350
583
-
584
- Collapse.DEFAULTS = {
585
- toggle: true
586
- }
587
-
588
- Collapse.prototype.dimension = function () {
589
- var hasWidth = this.$element.hasClass('width')
590
- return hasWidth ? 'width' : 'height'
591
- }
592
-
593
- Collapse.prototype.show = function () {
594
- if (this.transitioning || this.$element.hasClass('in')) return
595
-
596
- var activesData
597
- var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
598
-
599
- if (actives && actives.length) {
600
- activesData = actives.data('bs.collapse')
601
- if (activesData && activesData.transitioning) return
602
- }
603
-
604
- var startEvent = $.Event('show.bs.collapse')
605
- this.$element.trigger(startEvent)
606
- if (startEvent.isDefaultPrevented()) return
607
-
608
- if (actives && actives.length) {
609
- Plugin.call(actives, 'hide')
610
- activesData || actives.data('bs.collapse', null)
611
- }
612
-
613
- var dimension = this.dimension()
614
-
615
- this.$element
616
- .removeClass('collapse')
617
- .addClass('collapsing')[dimension](0)
618
- .attr('aria-expanded', true)
619
-
620
- this.$trigger
621
- .removeClass('collapsed')
622
- .attr('aria-expanded', true)
623
-
624
- this.transitioning = 1
625
-
626
- var complete = function () {
627
- this.$element
628
- .removeClass('collapsing')
629
- .addClass('collapse in')[dimension]('')
630
- this.transitioning = 0
631
- this.$element
632
- .trigger('shown.bs.collapse')
633
- }
634
-
635
- if (!$.support.transition) return complete.call(this)
636
-
637
- var scrollSize = $.camelCase(['scroll', dimension].join('-'))
638
-
639
- this.$element
640
- .one('bsTransitionEnd', $.proxy(complete, this))
641
- .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
642
- }
643
-
644
- Collapse.prototype.hide = function () {
645
- if (this.transitioning || !this.$element.hasClass('in')) return
646
-
647
- var startEvent = $.Event('hide.bs.collapse')
648
- this.$element.trigger(startEvent)
649
- if (startEvent.isDefaultPrevented()) return
650
-
651
- var dimension = this.dimension()
652
-
653
- this.$element[dimension](this.$element[dimension]())[0].offsetHeight
654
-
655
- this.$element
656
- .addClass('collapsing')
657
- .removeClass('collapse in')
658
- .attr('aria-expanded', false)
659
-
660
- this.$trigger
661
- .addClass('collapsed')
662
- .attr('aria-expanded', false)
663
-
664
- this.transitioning = 1
665
-
666
- var complete = function () {
667
- this.transitioning = 0
668
- this.$element
669
- .removeClass('collapsing')
670
- .addClass('collapse')
671
- .trigger('hidden.bs.collapse')
672
- }
673
-
674
- if (!$.support.transition) return complete.call(this)
675
-
676
- this.$element
677
- [dimension](0)
678
- .one('bsTransitionEnd', $.proxy(complete, this))
679
- .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
680
- }
681
-
682
- Collapse.prototype.toggle = function () {
683
- this[this.$element.hasClass('in') ? 'hide' : 'show']()
684
- }
685
-
686
- Collapse.prototype.getParent = function () {
687
- return $(document).find(this.options.parent)
688
- .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
689
- .each($.proxy(function (i, element) {
690
- var $element = $(element)
691
- this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
692
- }, this))
693
- .end()
694
- }
695
-
696
- Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
697
- var isOpen = $element.hasClass('in')
698
-
699
- $element.attr('aria-expanded', isOpen)
700
- $trigger
701
- .toggleClass('collapsed', !isOpen)
702
- .attr('aria-expanded', isOpen)
703
- }
704
-
705
- function getTargetFromTrigger($trigger) {
706
- var href
707
- var target = $trigger.attr('data-target')
708
- || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
709
-
710
- return $(document).find(target)
711
- }
712
-
713
-
714
- // COLLAPSE PLUGIN DEFINITION
715
- // ==========================
716
-
717
- function Plugin(option) {
718
- return this.each(function () {
719
- var $this = $(this)
720
- var data = $this.data('bs.collapse')
721
- var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
722
-
723
- if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
724
- if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
725
- if (typeof option == 'string') data[option]()
726
- })
727
- }
728
-
729
- var old = $.fn.collapse
730
-
731
- $.fn.collapse = Plugin
732
- $.fn.collapse.Constructor = Collapse
733
-
734
-
735
- // COLLAPSE NO CONFLICT
736
- // ====================
737
-
738
- $.fn.collapse.noConflict = function () {
739
- $.fn.collapse = old
740
- return this
741
- }
742
-
743
-
744
- // COLLAPSE DATA-API
745
- // =================
746
-
747
- $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
748
- var $this = $(this)
749
-
750
- if (!$this.attr('data-target')) e.preventDefault()
751
-
752
- var $target = getTargetFromTrigger($this)
753
- var data = $target.data('bs.collapse')
754
- var option = data ? 'toggle' : $this.data()
755
-
756
- Plugin.call($target, option)
757
- })
758
-
759
- }(jQuery);
760
-
761
- /* ========================================================================
762
- * Bootstrap: dropdown.js v3.4.1
763
- * https://getbootstrap.com/docs/3.4/javascript/#dropdowns
764
- * ========================================================================
765
- * Copyright 2011-2019 Twitter, Inc.
766
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
767
- * ======================================================================== */
768
-
769
-
770
- +function ($) {
771
- 'use strict';
772
-
773
- // DROPDOWN CLASS DEFINITION
774
- // =========================
775
-
776
- var backdrop = '.dropdown-backdrop'
777
- var toggle = '[data-toggle="dropdown"]'
778
- var Dropdown = function (element) {
779
- $(element).on('click.bs.dropdown', this.toggle)
780
- }
781
-
782
- Dropdown.VERSION = '3.4.1'
783
-
784
- function getParent($this) {
785
- var selector = $this.attr('data-target')
786
-
787
- if (!selector) {
788
- selector = $this.attr('href')
789
- selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
790
- }
791
-
792
- var $parent = selector !== '#' ? $(document).find(selector) : null
793
-
794
- return $parent && $parent.length ? $parent : $this.parent()
795
- }
796
-
797
- function clearMenus(e) {
798
- if (e && e.which === 3) return
799
- $(backdrop).remove()
800
- $(toggle).each(function () {
801
- var $this = $(this)
802
- var $parent = getParent($this)
803
- var relatedTarget = { relatedTarget: this }
804
-
805
- if (!$parent.hasClass('open')) return
806
-
807
- if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
808
-
809
- $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
810
-
811
- if (e.isDefaultPrevented()) return
812
-
813
- $this.attr('aria-expanded', 'false')
814
- $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
815
- })
816
- }
817
-
818
- Dropdown.prototype.toggle = function (e) {
819
- var $this = $(this)
820
-
821
- if ($this.is('.disabled, :disabled')) return
822
-
823
- var $parent = getParent($this)
824
- var isActive = $parent.hasClass('open')
825
-
826
- clearMenus()
827
-
828
- if (!isActive) {
829
- if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
830
- // if mobile we use a backdrop because click events don't delegate
831
- $(document.createElement('div'))
832
- .addClass('dropdown-backdrop')
833
- .insertAfter($(this))
834
- .on('click', clearMenus)
835
- }
836
-
837
- var relatedTarget = { relatedTarget: this }
838
- $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
839
-
840
- if (e.isDefaultPrevented()) return
841
-
842
- $this
843
- .trigger('focus')
844
- .attr('aria-expanded', 'true')
845
-
846
- $parent
847
- .toggleClass('open')
848
- .trigger($.Event('shown.bs.dropdown', relatedTarget))
849
- }
850
-
851
- return false
852
- }
853
-
854
- Dropdown.prototype.keydown = function (e) {
855
- if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
856
-
857
- var $this = $(this)
858
-
859
- e.preventDefault()
860
- e.stopPropagation()
861
-
862
- if ($this.is('.disabled, :disabled')) return
863
-
864
- var $parent = getParent($this)
865
- var isActive = $parent.hasClass('open')
866
-
867
- if (!isActive && e.which != 27 || isActive && e.which == 27) {
868
- if (e.which == 27) $parent.find(toggle).trigger('focus')
869
- return $this.trigger('click')
870
- }
871
-
872
- var desc = ' li:not(.disabled):visible a'
873
- var $items = $parent.find('.dropdown-menu' + desc)
874
-
875
- if (!$items.length) return
876
-
877
- var index = $items.index(e.target)
878
-
879
- if (e.which == 38 && index > 0) index-- // up
880
- if (e.which == 40 && index < $items.length - 1) index++ // down
881
- if (!~index) index = 0
882
-
883
- $items.eq(index).trigger('focus')
884
- }
885
-
886
-
887
- // DROPDOWN PLUGIN DEFINITION
888
- // ==========================
889
-
890
- function Plugin(option) {
891
- return this.each(function () {
892
- var $this = $(this)
893
- var data = $this.data('bs.dropdown')
894
-
895
- if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
896
- if (typeof option == 'string') data[option].call($this)
897
- })
898
- }
899
-
900
- var old = $.fn.dropdown
901
-
902
- $.fn.dropdown = Plugin
903
- $.fn.dropdown.Constructor = Dropdown
904
-
905
-
906
- // DROPDOWN NO CONFLICT
907
- // ====================
908
-
909
- $.fn.dropdown.noConflict = function () {
910
- $.fn.dropdown = old
911
- return this
912
- }
913
-
914
-
915
- // APPLY TO STANDARD DROPDOWN ELEMENTS
916
- // ===================================
917
-
918
- $(document)
919
- .on('click.bs.dropdown.data-api', clearMenus)
920
- .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
921
- .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
922
- .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
923
- .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
924
-
925
- }(jQuery);
926
-
927
- /* ========================================================================
928
- * Bootstrap: modal.js v3.4.1
929
- * https://getbootstrap.com/docs/3.4/javascript/#modals
930
- * ========================================================================
931
- * Copyright 2011-2019 Twitter, Inc.
932
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
933
- * ======================================================================== */
934
-
935
-
936
- +function ($) {
937
- 'use strict';
938
-
939
- // MODAL CLASS DEFINITION
940
- // ======================
941
-
942
- var Modal = function (element, options) {
943
- this.options = options
944
- this.$body = $(document.body)
945
- this.$element = $(element)
946
- this.$dialog = this.$element.find('.modal-dialog')
947
- this.$backdrop = null
948
- this.isShown = null
949
- this.originalBodyPad = null
950
- this.scrollbarWidth = 0
951
- this.ignoreBackdropClick = false
952
- this.fixedContent = '.navbar-fixed-top, .navbar-fixed-bottom'
953
-
954
- if (this.options.remote) {
955
- this.$element
956
- .find('.modal-content')
957
- .load(this.options.remote, $.proxy(function () {
958
- this.$element.trigger('loaded.bs.modal')
959
- }, this))
960
- }
961
- }
962
-
963
- Modal.VERSION = '3.4.1'
964
-
965
- Modal.TRANSITION_DURATION = 300
966
- Modal.BACKDROP_TRANSITION_DURATION = 150
967
-
968
- Modal.DEFAULTS = {
969
- backdrop: true,
970
- keyboard: true,
971
- show: true
972
- }
973
-
974
- Modal.prototype.toggle = function (_relatedTarget) {
975
- return this.isShown ? this.hide() : this.show(_relatedTarget)
976
- }
977
-
978
- Modal.prototype.show = function (_relatedTarget) {
979
- var that = this
980
- var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
981
-
982
- this.$element.trigger(e)
983
-
984
- if (this.isShown || e.isDefaultPrevented()) return
985
-
986
- this.isShown = true
987
-
988
- this.checkScrollbar()
989
- this.setScrollbar()
990
- this.$body.addClass('modal-open')
991
-
992
- this.escape()
993
- this.resize()
994
-
995
- this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
996
-
997
- this.$dialog.on('mousedown.dismiss.bs.modal', function () {
998
- that.$element.one('mouseup.dismiss.bs.modal', function (e) {
999
- if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
1000
- })
1001
- })
1002
-
1003
- this.backdrop(function () {
1004
- var transition = $.support.transition && that.$element.hasClass('fade')
1005
-
1006
- if (!that.$element.parent().length) {
1007
- that.$element.appendTo(that.$body) // don't move modals dom position
1008
- }
1009
-
1010
- that.$element
1011
- .show()
1012
- .scrollTop(0)
1013
-
1014
- that.adjustDialog()
1015
-
1016
- if (transition) {
1017
- that.$element[0].offsetWidth // force reflow
1018
- }
1019
-
1020
- that.$element.addClass('in')
1021
-
1022
- that.enforceFocus()
1023
-
1024
- var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
1025
-
1026
- transition ?
1027
- that.$dialog // wait for modal to slide in
1028
- .one('bsTransitionEnd', function () {
1029
- that.$element.trigger('focus').trigger(e)
1030
- })
1031
- .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
1032
- that.$element.trigger('focus').trigger(e)
1033
- })
1034
- }
1035
-
1036
- Modal.prototype.hide = function (e) {
1037
- if (e) e.preventDefault()
1038
-
1039
- e = $.Event('hide.bs.modal')
1040
-
1041
- this.$element.trigger(e)
1042
-
1043
- if (!this.isShown || e.isDefaultPrevented()) return
1044
-
1045
- this.isShown = false
1046
-
1047
- this.escape()
1048
- this.resize()
1049
-
1050
- $(document).off('focusin.bs.modal')
1051
-
1052
- this.$element
1053
- .removeClass('in')
1054
- .off('click.dismiss.bs.modal')
1055
- .off('mouseup.dismiss.bs.modal')
1056
-
1057
- this.$dialog.off('mousedown.dismiss.bs.modal')
1058
-
1059
- $.support.transition && this.$element.hasClass('fade') ?
1060
- this.$element
1061
- .one('bsTransitionEnd', $.proxy(this.hideModal, this))
1062
- .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
1063
- this.hideModal()
1064
- }
1065
-
1066
- Modal.prototype.enforceFocus = function () {
1067
- $(document)
1068
- .off('focusin.bs.modal') // guard against infinite focus loop
1069
- .on('focusin.bs.modal', $.proxy(function (e) {
1070
- if (document !== e.target &&
1071
- this.$element[0] !== e.target &&
1072
- !this.$element.has(e.target).length) {
1073
- this.$element.trigger('focus')
1074
- }
1075
- }, this))
1076
- }
1077
-
1078
- Modal.prototype.escape = function () {
1079
- if (this.isShown && this.options.keyboard) {
1080
- this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
1081
- e.which == 27 && this.hide()
1082
- }, this))
1083
- } else if (!this.isShown) {
1084
- this.$element.off('keydown.dismiss.bs.modal')
1085
- }
1086
- }
1087
-
1088
- Modal.prototype.resize = function () {
1089
- if (this.isShown) {
1090
- $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
1091
- } else {
1092
- $(window).off('resize.bs.modal')
1093
- }
1094
- }
1095
-
1096
- Modal.prototype.hideModal = function () {
1097
- var that = this
1098
- this.$element.hide()
1099
- this.backdrop(function () {
1100
- that.$body.removeClass('modal-open')
1101
- that.resetAdjustments()
1102
- that.resetScrollbar()
1103
- that.$element.trigger('hidden.bs.modal')
1104
- })
1105
- }
1106
-
1107
- Modal.prototype.removeBackdrop = function () {
1108
- this.$backdrop && this.$backdrop.remove()
1109
- this.$backdrop = null
1110
- }
1111
-
1112
- Modal.prototype.backdrop = function (callback) {
1113
- var that = this
1114
- var animate = this.$element.hasClass('fade') ? 'fade' : ''
1115
-
1116
- if (this.isShown && this.options.backdrop) {
1117
- var doAnimate = $.support.transition && animate
1118
-
1119
- this.$backdrop = $(document.createElement('div'))
1120
- .addClass('modal-backdrop ' + animate)
1121
- .appendTo(this.$body)
1122
-
1123
- this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
1124
- if (this.ignoreBackdropClick) {
1125
- this.ignoreBackdropClick = false
1126
- return
1127
- }
1128
- if (e.target !== e.currentTarget) return
1129
- this.options.backdrop == 'static'
1130
- ? this.$element[0].focus()
1131
- : this.hide()
1132
- }, this))
1133
-
1134
- if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
1135
-
1136
- this.$backdrop.addClass('in')
1137
-
1138
- if (!callback) return
1139
-
1140
- doAnimate ?
1141
- this.$backdrop
1142
- .one('bsTransitionEnd', callback)
1143
- .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
1144
- callback()
1145
-
1146
- } else if (!this.isShown && this.$backdrop) {
1147
- this.$backdrop.removeClass('in')
1148
-
1149
- var callbackRemove = function () {
1150
- that.removeBackdrop()
1151
- callback && callback()
1152
- }
1153
- $.support.transition && this.$element.hasClass('fade') ?
1154
- this.$backdrop
1155
- .one('bsTransitionEnd', callbackRemove)
1156
- .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
1157
- callbackRemove()
1158
-
1159
- } else if (callback) {
1160
- callback()
1161
- }
1162
- }
1163
-
1164
- // these following methods are used to handle overflowing modals
1165
-
1166
- Modal.prototype.handleUpdate = function () {
1167
- this.adjustDialog()
1168
- }
1169
-
1170
- Modal.prototype.adjustDialog = function () {
1171
- var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
1172
-
1173
- this.$element.css({
1174
- paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
1175
- paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
1176
- })
1177
- }
1178
-
1179
- Modal.prototype.resetAdjustments = function () {
1180
- this.$element.css({
1181
- paddingLeft: '',
1182
- paddingRight: ''
1183
- })
1184
- }
1185
-
1186
- Modal.prototype.checkScrollbar = function () {
1187
- var fullWindowWidth = window.innerWidth
1188
- if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
1189
- var documentElementRect = document.documentElement.getBoundingClientRect()
1190
- fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
1191
- }
1192
- this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
1193
- this.scrollbarWidth = this.measureScrollbar()
1194
- }
1195
-
1196
- Modal.prototype.setScrollbar = function () {
1197
- var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
1198
- this.originalBodyPad = document.body.style.paddingRight || ''
1199
- var scrollbarWidth = this.scrollbarWidth
1200
- if (this.bodyIsOverflowing) {
1201
- this.$body.css('padding-right', bodyPad + scrollbarWidth)
1202
- $(this.fixedContent).each(function (index, element) {
1203
- var actualPadding = element.style.paddingRight
1204
- var calculatedPadding = $(element).css('padding-right')
1205
- $(element)
1206
- .data('padding-right', actualPadding)
1207
- .css('padding-right', parseFloat(calculatedPadding) + scrollbarWidth + 'px')
1208
- })
1209
- }
1210
- }
1211
-
1212
- Modal.prototype.resetScrollbar = function () {
1213
- this.$body.css('padding-right', this.originalBodyPad)
1214
- $(this.fixedContent).each(function (index, element) {
1215
- var padding = $(element).data('padding-right')
1216
- $(element).removeData('padding-right')
1217
- element.style.paddingRight = padding ? padding : ''
1218
- })
1219
- }
1220
-
1221
- Modal.prototype.measureScrollbar = function () { // thx walsh
1222
- var scrollDiv = document.createElement('div')
1223
- scrollDiv.className = 'modal-scrollbar-measure'
1224
- this.$body.append(scrollDiv)
1225
- var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
1226
- this.$body[0].removeChild(scrollDiv)
1227
- return scrollbarWidth
1228
- }
1229
-
1230
-
1231
- // MODAL PLUGIN DEFINITION
1232
- // =======================
1233
-
1234
- function Plugin(option, _relatedTarget) {
1235
- return this.each(function () {
1236
- var $this = $(this)
1237
- var data = $this.data('bs.modal')
1238
- var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
1239
-
1240
- if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
1241
- if (typeof option == 'string') data[option](_relatedTarget)
1242
- else if (options.show) data.show(_relatedTarget)
1243
- })
1244
- }
1245
-
1246
- var old = $.fn.modal
1247
-
1248
- $.fn.modal = Plugin
1249
- $.fn.modal.Constructor = Modal
1250
-
1251
-
1252
- // MODAL NO CONFLICT
1253
- // =================
1254
-
1255
- $.fn.modal.noConflict = function () {
1256
- $.fn.modal = old
1257
- return this
1258
- }
1259
-
1260
-
1261
- // MODAL DATA-API
1262
- // ==============
1263
-
1264
- $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
1265
- var $this = $(this)
1266
- var href = $this.attr('href')
1267
- var target = $this.attr('data-target') ||
1268
- (href && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
1269
-
1270
- var $target = $(document).find(target)
1271
- var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
1272
-
1273
- if ($this.is('a')) e.preventDefault()
1274
-
1275
- $target.one('show.bs.modal', function (showEvent) {
1276
- if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
1277
- $target.one('hidden.bs.modal', function () {
1278
- $this.is(':visible') && $this.trigger('focus')
1279
- })
1280
- })
1281
- Plugin.call($target, option, this)
1282
- })
1283
-
1284
- }(jQuery);
1285
-
1286
- /* ========================================================================
1287
- * Bootstrap: tooltip.js v3.4.1
1288
- * https://getbootstrap.com/docs/3.4/javascript/#tooltip
1289
- * Inspired by the original jQuery.tipsy by Jason Frame
1290
- * ========================================================================
1291
- * Copyright 2011-2019 Twitter, Inc.
1292
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1293
- * ======================================================================== */
1294
-
1295
- +function ($) {
1296
- 'use strict';
1297
-
1298
- var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']
1299
-
1300
- var uriAttrs = [
1301
- 'background',
1302
- 'cite',
1303
- 'href',
1304
- 'itemtype',
1305
- 'longdesc',
1306
- 'poster',
1307
- 'src',
1308
- 'xlink:href'
1309
- ]
1310
-
1311
- var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
1312
-
1313
- var DefaultWhitelist = {
1314
- // Global attributes allowed on any supplied element below.
1315
- '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
1316
- a: ['target', 'href', 'title', 'rel'],
1317
- area: [],
1318
- b: [],
1319
- br: [],
1320
- col: [],
1321
- code: [],
1322
- div: [],
1323
- em: [],
1324
- hr: [],
1325
- h1: [],
1326
- h2: [],
1327
- h3: [],
1328
- h4: [],
1329
- h5: [],
1330
- h6: [],
1331
- i: [],
1332
- img: ['src', 'alt', 'title', 'width', 'height'],
1333
- li: [],
1334
- ol: [],
1335
- p: [],
1336
- pre: [],
1337
- s: [],
1338
- small: [],
1339
- span: [],
1340
- sub: [],
1341
- sup: [],
1342
- strong: [],
1343
- u: [],
1344
- ul: []
1345
- }
1346
-
1347
- /**
1348
- * A pattern that recognizes a commonly useful subset of URLs that are safe.
1349
- *
1350
- * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
1351
- */
1352
- var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi
1353
-
1354
- /**
1355
- * A pattern that matches safe data URLs. Only matches image, video and audio types.
1356
- *
1357
- * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
1358
- */
1359
- var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i
1360
-
1361
- function allowedAttribute(attr, allowedAttributeList) {
1362
- var attrName = attr.nodeName.toLowerCase()
1363
-
1364
- if ($.inArray(attrName, allowedAttributeList) !== -1) {
1365
- if ($.inArray(attrName, uriAttrs) !== -1) {
1366
- return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))
1367
- }
1368
-
1369
- return true
1370
- }
1371
-
1372
- var regExp = $(allowedAttributeList).filter(function (index, value) {
1373
- return value instanceof RegExp
1374
- })
1375
-
1376
- // Check if a regular expression validates the attribute.
1377
- for (var i = 0, l = regExp.length; i < l; i++) {
1378
- if (attrName.match(regExp[i])) {
1379
- return true
1380
- }
1381
- }
1382
-
1383
- return false
1384
- }
1385
-
1386
- function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
1387
- if (unsafeHtml.length === 0) {
1388
- return unsafeHtml
1389
- }
1390
-
1391
- if (sanitizeFn && typeof sanitizeFn === 'function') {
1392
- return sanitizeFn(unsafeHtml)
1393
- }
1394
-
1395
- // IE 8 and below don't support createHTMLDocument
1396
- if (!document.implementation || !document.implementation.createHTMLDocument) {
1397
- return unsafeHtml
1398
- }
1399
-
1400
- var createdDocument = document.implementation.createHTMLDocument('sanitization')
1401
- createdDocument.body.innerHTML = unsafeHtml
1402
-
1403
- var whitelistKeys = $.map(whiteList, function (el, i) { return i })
1404
- var elements = $(createdDocument.body).find('*')
1405
-
1406
- for (var i = 0, len = elements.length; i < len; i++) {
1407
- var el = elements[i]
1408
- var elName = el.nodeName.toLowerCase()
1409
-
1410
- if ($.inArray(elName, whitelistKeys) === -1) {
1411
- el.parentNode.removeChild(el)
1412
-
1413
- continue
1414
- }
1415
-
1416
- var attributeList = $.map(el.attributes, function (el) { return el })
1417
- var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])
1418
-
1419
- for (var j = 0, len2 = attributeList.length; j < len2; j++) {
1420
- if (!allowedAttribute(attributeList[j], whitelistedAttributes)) {
1421
- el.removeAttribute(attributeList[j].nodeName)
1422
- }
1423
- }
1424
- }
1425
-
1426
- return createdDocument.body.innerHTML
1427
- }
1428
-
1429
- // TOOLTIP PUBLIC CLASS DEFINITION
1430
- // ===============================
1431
-
1432
- var Tooltip = function (element, options) {
1433
- this.type = null
1434
- this.options = null
1435
- this.enabled = null
1436
- this.timeout = null
1437
- this.hoverState = null
1438
- this.$element = null
1439
- this.inState = null
1440
-
1441
- this.init('tooltip', element, options)
1442
- }
1443
-
1444
- Tooltip.VERSION = '3.4.1'
1445
-
1446
- Tooltip.TRANSITION_DURATION = 150
1447
-
1448
- Tooltip.DEFAULTS = {
1449
- animation: true,
1450
- placement: 'top',
1451
- selector: false,
1452
- template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
1453
- trigger: 'hover focus',
1454
- title: '',
1455
- delay: 0,
1456
- html: false,
1457
- container: false,
1458
- viewport: {
1459
- selector: 'body',
1460
- padding: 0
1461
- },
1462
- sanitize : true,
1463
- sanitizeFn : null,
1464
- whiteList : DefaultWhitelist
1465
- }
1466
-
1467
- Tooltip.prototype.init = function (type, element, options) {
1468
- this.enabled = true
1469
- this.type = type
1470
- this.$element = $(element)
1471
- this.options = this.getOptions(options)
1472
- this.$viewport = this.options.viewport && $(document).find($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
1473
- this.inState = { click: false, hover: false, focus: false }
1474
-
1475
- if (this.$element[0] instanceof document.constructor && !this.options.selector) {
1476
- throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
1477
- }
1478
-
1479
- var triggers = this.options.trigger.split(' ')
1480
-
1481
- for (var i = triggers.length; i--;) {
1482
- var trigger = triggers[i]
1483
-
1484
- if (trigger == 'click') {
1485
- this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
1486
- } else if (trigger != 'manual') {
1487
- var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
1488
- var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
1489
-
1490
- this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
1491
- this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
1492
- }
1493
- }
1494
-
1495
- this.options.selector ?
1496
- (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
1497
- this.fixTitle()
1498
- }
1499
-
1500
- Tooltip.prototype.getDefaults = function () {
1501
- return Tooltip.DEFAULTS
1502
- }
1503
-
1504
- Tooltip.prototype.getOptions = function (options) {
1505
- var dataAttributes = this.$element.data()
1506
-
1507
- for (var dataAttr in dataAttributes) {
1508
- if (dataAttributes.hasOwnProperty(dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) {
1509
- delete dataAttributes[dataAttr]
1510
- }
1511
- }
1512
-
1513
- options = $.extend({}, this.getDefaults(), dataAttributes, options)
1514
-
1515
- if (options.delay && typeof options.delay == 'number') {
1516
- options.delay = {
1517
- show: options.delay,
1518
- hide: options.delay
1519
- }
1520
- }
1521
-
1522
- if (options.sanitize) {
1523
- options.template = sanitizeHtml(options.template, options.whiteList, options.sanitizeFn)
1524
- }
1525
-
1526
- return options
1527
- }
1528
-
1529
- Tooltip.prototype.getDelegateOptions = function () {
1530
- var options = {}
1531
- var defaults = this.getDefaults()
1532
-
1533
- this._options && $.each(this._options, function (key, value) {
1534
- if (defaults[key] != value) options[key] = value
1535
- })
1536
-
1537
- return options
1538
- }
1539
-
1540
- Tooltip.prototype.enter = function (obj) {
1541
- var self = obj instanceof this.constructor ?
1542
- obj : $(obj.currentTarget).data('bs.' + this.type)
1543
-
1544
- if (!self) {
1545
- self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
1546
- $(obj.currentTarget).data('bs.' + this.type, self)
1547
- }
1548
-
1549
- if (obj instanceof $.Event) {
1550
- self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
1551
- }
1552
-
1553
- if (self.tip().hasClass('in') || self.hoverState == 'in') {
1554
- self.hoverState = 'in'
1555
- return
1556
- }
1557
-
1558
- clearTimeout(self.timeout)
1559
-
1560
- self.hoverState = 'in'
1561
-
1562
- if (!self.options.delay || !self.options.delay.show) return self.show()
1563
-
1564
- self.timeout = setTimeout(function () {
1565
- if (self.hoverState == 'in') self.show()
1566
- }, self.options.delay.show)
1567
- }
1568
-
1569
- Tooltip.prototype.isInStateTrue = function () {
1570
- for (var key in this.inState) {
1571
- if (this.inState[key]) return true
1572
- }
1573
-
1574
- return false
1575
- }
1576
-
1577
- Tooltip.prototype.leave = function (obj) {
1578
- var self = obj instanceof this.constructor ?
1579
- obj : $(obj.currentTarget).data('bs.' + this.type)
1580
-
1581
- if (!self) {
1582
- self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
1583
- $(obj.currentTarget).data('bs.' + this.type, self)
1584
- }
1585
-
1586
- if (obj instanceof $.Event) {
1587
- self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
1588
- }
1589
-
1590
- if (self.isInStateTrue()) return
1591
-
1592
- clearTimeout(self.timeout)
1593
-
1594
- self.hoverState = 'out'
1595
-
1596
- if (!self.options.delay || !self.options.delay.hide) return self.hide()
1597
-
1598
- self.timeout = setTimeout(function () {
1599
- if (self.hoverState == 'out') self.hide()
1600
- }, self.options.delay.hide)
1601
- }
1602
-
1603
- Tooltip.prototype.show = function () {
1604
- var e = $.Event('show.bs.' + this.type)
1605
-
1606
- if (this.hasContent() && this.enabled) {
1607
- this.$element.trigger(e)
1608
-
1609
- var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
1610
- if (e.isDefaultPrevented() || !inDom) return
1611
- var that = this
1612
-
1613
- var $tip = this.tip()
1614
-
1615
- var tipId = this.getUID(this.type)
1616
-
1617
- this.setContent()
1618
- $tip.attr('id', tipId)
1619
- this.$element.attr('aria-describedby', tipId)
1620
-
1621
- if (this.options.animation) $tip.addClass('fade')
1622
-
1623
- var placement = typeof this.options.placement == 'function' ?
1624
- this.options.placement.call(this, $tip[0], this.$element[0]) :
1625
- this.options.placement
1626
-
1627
- var autoToken = /\s?auto?\s?/i
1628
- var autoPlace = autoToken.test(placement)
1629
- if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
1630
-
1631
- $tip
1632
- .detach()
1633
- .css({ top: 0, left: 0, display: 'block' })
1634
- .addClass(placement)
1635
- .data('bs.' + this.type, this)
1636
-
1637
- this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element)
1638
- this.$element.trigger('inserted.bs.' + this.type)
1639
-
1640
- var pos = this.getPosition()
1641
- var actualWidth = $tip[0].offsetWidth
1642
- var actualHeight = $tip[0].offsetHeight
1643
-
1644
- if (autoPlace) {
1645
- var orgPlacement = placement
1646
- var viewportDim = this.getPosition(this.$viewport)
1647
-
1648
- placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
1649
- placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
1650
- placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
1651
- placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
1652
- placement
1653
-
1654
- $tip
1655
- .removeClass(orgPlacement)
1656
- .addClass(placement)
1657
- }
1658
-
1659
- var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
1660
-
1661
- this.applyPlacement(calculatedOffset, placement)
1662
-
1663
- var complete = function () {
1664
- var prevHoverState = that.hoverState
1665
- that.$element.trigger('shown.bs.' + that.type)
1666
- that.hoverState = null
1667
-
1668
- if (prevHoverState == 'out') that.leave(that)
1669
- }
1670
-
1671
- $.support.transition && this.$tip.hasClass('fade') ?
1672
- $tip
1673
- .one('bsTransitionEnd', complete)
1674
- .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
1675
- complete()
1676
- }
1677
- }
1678
-
1679
- Tooltip.prototype.applyPlacement = function (offset, placement) {
1680
- var $tip = this.tip()
1681
- var width = $tip[0].offsetWidth
1682
- var height = $tip[0].offsetHeight
1683
-
1684
- // manually read margins because getBoundingClientRect includes difference
1685
- var marginTop = parseInt($tip.css('margin-top'), 10)
1686
- var marginLeft = parseInt($tip.css('margin-left'), 10)
1687
-
1688
- // we must check for NaN for ie 8/9
1689
- if (isNaN(marginTop)) marginTop = 0
1690
- if (isNaN(marginLeft)) marginLeft = 0
1691
-
1692
- offset.top += marginTop
1693
- offset.left += marginLeft
1694
-
1695
- // $.fn.offset doesn't round pixel values
1696
- // so we use setOffset directly with our own function B-0
1697
- $.offset.setOffset($tip[0], $.extend({
1698
- using: function (props) {
1699
- $tip.css({
1700
- top: Math.round(props.top),
1701
- left: Math.round(props.left)
1702
- })
1703
- }
1704
- }, offset), 0)
1705
-
1706
- $tip.addClass('in')
1707
-
1708
- // check to see if placing tip in new offset caused the tip to resize itself
1709
- var actualWidth = $tip[0].offsetWidth
1710
- var actualHeight = $tip[0].offsetHeight
1711
-
1712
- if (placement == 'top' && actualHeight != height) {
1713
- offset.top = offset.top + height - actualHeight
1714
- }
1715
-
1716
- var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
1717
-
1718
- if (delta.left) offset.left += delta.left
1719
- else offset.top += delta.top
1720
-
1721
- var isVertical = /top|bottom/.test(placement)
1722
- var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
1723
- var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
1724
-
1725
- $tip.offset(offset)
1726
- this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
1727
- }
1728
-
1729
- Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
1730
- this.arrow()
1731
- .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
1732
- .css(isVertical ? 'top' : 'left', '')
1733
- }
1734
-
1735
- Tooltip.prototype.setContent = function () {
1736
- var $tip = this.tip()
1737
- var title = this.getTitle()
1738
-
1739
- if (this.options.html) {
1740
- if (this.options.sanitize) {
1741
- title = sanitizeHtml(title, this.options.whiteList, this.options.sanitizeFn)
1742
- }
1743
-
1744
- $tip.find('.tooltip-inner').html(title)
1745
- } else {
1746
- $tip.find('.tooltip-inner').text(title)
1747
- }
1748
-
1749
- $tip.removeClass('fade in top bottom left right')
1750
- }
1751
-
1752
- Tooltip.prototype.hide = function (callback) {
1753
- var that = this
1754
- var $tip = $(this.$tip)
1755
- var e = $.Event('hide.bs.' + this.type)
1756
-
1757
- function complete() {
1758
- if (that.hoverState != 'in') $tip.detach()
1759
- if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
1760
- that.$element
1761
- .removeAttr('aria-describedby')
1762
- .trigger('hidden.bs.' + that.type)
1763
- }
1764
- callback && callback()
1765
- }
1766
-
1767
- this.$element.trigger(e)
1768
-
1769
- if (e.isDefaultPrevented()) return
1770
-
1771
- $tip.removeClass('in')
1772
-
1773
- $.support.transition && $tip.hasClass('fade') ?
1774
- $tip
1775
- .one('bsTransitionEnd', complete)
1776
- .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
1777
- complete()
1778
-
1779
- this.hoverState = null
1780
-
1781
- return this
1782
- }
1783
-
1784
- Tooltip.prototype.fixTitle = function () {
1785
- var $e = this.$element
1786
- if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
1787
- $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
1788
- }
1789
- }
1790
-
1791
- Tooltip.prototype.hasContent = function () {
1792
- return this.getTitle()
1793
- }
1794
-
1795
- Tooltip.prototype.getPosition = function ($element) {
1796
- $element = $element || this.$element
1797
-
1798
- var el = $element[0]
1799
- var isBody = el.tagName == 'BODY'
1800
-
1801
- var elRect = el.getBoundingClientRect()
1802
- if (elRect.width == null) {
1803
- // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
1804
- elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
1805
- }
1806
- var isSvg = window.SVGElement && el instanceof window.SVGElement
1807
- // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
1808
- // See https://github.com/twbs/bootstrap/issues/20280
1809
- var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
1810
- var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
1811
- var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
1812
-
1813
- return $.extend({}, elRect, scroll, outerDims, elOffset)
1814
- }
1815
-
1816
- Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
1817
- return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
1818
- placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
1819
- placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
1820
- /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
1821
-
1822
- }
1823
-
1824
- Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
1825
- var delta = { top: 0, left: 0 }
1826
- if (!this.$viewport) return delta
1827
-
1828
- var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
1829
- var viewportDimensions = this.getPosition(this.$viewport)
1830
-
1831
- if (/right|left/.test(placement)) {
1832
- var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
1833
- var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
1834
- if (topEdgeOffset < viewportDimensions.top) { // top overflow
1835
- delta.top = viewportDimensions.top - topEdgeOffset
1836
- } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
1837
- delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
1838
- }
1839
- } else {
1840
- var leftEdgeOffset = pos.left - viewportPadding
1841
- var rightEdgeOffset = pos.left + viewportPadding + actualWidth
1842
- if (leftEdgeOffset < viewportDimensions.left) { // left overflow
1843
- delta.left = viewportDimensions.left - leftEdgeOffset
1844
- } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
1845
- delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
1846
- }
1847
- }
1848
-
1849
- return delta
1850
- }
1851
-
1852
- Tooltip.prototype.getTitle = function () {
1853
- var title
1854
- var $e = this.$element
1855
- var o = this.options
1856
-
1857
- title = $e.attr('data-original-title')
1858
- || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
1859
-
1860
- return title
1861
- }
1862
-
1863
- Tooltip.prototype.getUID = function (prefix) {
1864
- do prefix += ~~(Math.random() * 1000000)
1865
- while (document.getElementById(prefix))
1866
- return prefix
1867
- }
1868
-
1869
- Tooltip.prototype.tip = function () {
1870
- if (!this.$tip) {
1871
- this.$tip = $(this.options.template)
1872
- if (this.$tip.length != 1) {
1873
- throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
1874
- }
1875
- }
1876
- return this.$tip
1877
- }
1878
-
1879
- Tooltip.prototype.arrow = function () {
1880
- return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
1881
- }
1882
-
1883
- Tooltip.prototype.enable = function () {
1884
- this.enabled = true
1885
- }
1886
-
1887
- Tooltip.prototype.disable = function () {
1888
- this.enabled = false
1889
- }
1890
-
1891
- Tooltip.prototype.toggleEnabled = function () {
1892
- this.enabled = !this.enabled
1893
- }
1894
-
1895
- Tooltip.prototype.toggle = function (e) {
1896
- var self = this
1897
- if (e) {
1898
- self = $(e.currentTarget).data('bs.' + this.type)
1899
- if (!self) {
1900
- self = new this.constructor(e.currentTarget, this.getDelegateOptions())
1901
- $(e.currentTarget).data('bs.' + this.type, self)
1902
- }
1903
- }
1904
-
1905
- if (e) {
1906
- self.inState.click = !self.inState.click
1907
- if (self.isInStateTrue()) self.enter(self)
1908
- else self.leave(self)
1909
- } else {
1910
- self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
1911
- }
1912
- }
1913
-
1914
- Tooltip.prototype.destroy = function () {
1915
- var that = this
1916
- clearTimeout(this.timeout)
1917
- this.hide(function () {
1918
- that.$element.off('.' + that.type).removeData('bs.' + that.type)
1919
- if (that.$tip) {
1920
- that.$tip.detach()
1921
- }
1922
- that.$tip = null
1923
- that.$arrow = null
1924
- that.$viewport = null
1925
- that.$element = null
1926
- })
1927
- }
1928
-
1929
- Tooltip.prototype.sanitizeHtml = function (unsafeHtml) {
1930
- return sanitizeHtml(unsafeHtml, this.options.whiteList, this.options.sanitizeFn)
1931
- }
1932
-
1933
- // TOOLTIP PLUGIN DEFINITION
1934
- // =========================
1935
-
1936
- function Plugin(option) {
1937
- return this.each(function () {
1938
- var $this = $(this)
1939
- var data = $this.data('bs.tooltip')
1940
- var options = typeof option == 'object' && option
1941
-
1942
- if (!data && /destroy|hide/.test(option)) return
1943
- if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
1944
- if (typeof option == 'string') data[option]()
1945
- })
1946
- }
1947
-
1948
- var old = $.fn.tooltip
1949
-
1950
- $.fn.tooltip = Plugin
1951
- $.fn.tooltip.Constructor = Tooltip
1952
-
1953
-
1954
- // TOOLTIP NO CONFLICT
1955
- // ===================
1956
-
1957
- $.fn.tooltip.noConflict = function () {
1958
- $.fn.tooltip = old
1959
- return this
1960
- }
1961
-
1962
- }(jQuery);
1963
-
1964
- /* ========================================================================
1965
- * Bootstrap: popover.js v3.4.1
1966
- * https://getbootstrap.com/docs/3.4/javascript/#popovers
1967
- * ========================================================================
1968
- * Copyright 2011-2019 Twitter, Inc.
1969
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1970
- * ======================================================================== */
1971
-
1972
-
1973
- +function ($) {
1974
- 'use strict';
1975
-
1976
- // POPOVER PUBLIC CLASS DEFINITION
1977
- // ===============================
1978
-
1979
- var Popover = function (element, options) {
1980
- this.init('popover', element, options)
1981
- }
1982
-
1983
- if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
1984
-
1985
- Popover.VERSION = '3.4.1'
1986
-
1987
- Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
1988
- placement: 'right',
1989
- trigger: 'click',
1990
- content: '',
1991
- template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1992
- })
1993
-
1994
-
1995
- // NOTE: POPOVER EXTENDS tooltip.js
1996
- // ================================
1997
-
1998
- Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
1999
-
2000
- Popover.prototype.constructor = Popover
2001
-
2002
- Popover.prototype.getDefaults = function () {
2003
- return Popover.DEFAULTS
2004
- }
2005
-
2006
- Popover.prototype.setContent = function () {
2007
- var $tip = this.tip()
2008
- var title = this.getTitle()
2009
- var content = this.getContent()
2010
-
2011
- if (this.options.html) {
2012
- var typeContent = typeof content
2013
-
2014
- if (this.options.sanitize) {
2015
- title = this.sanitizeHtml(title)
2016
-
2017
- if (typeContent === 'string') {
2018
- content = this.sanitizeHtml(content)
2019
- }
2020
- }
2021
-
2022
- $tip.find('.popover-title').html(title)
2023
- $tip.find('.popover-content').children().detach().end()[
2024
- typeContent === 'string' ? 'html' : 'append'
2025
- ](content)
2026
- } else {
2027
- $tip.find('.popover-title').text(title)
2028
- $tip.find('.popover-content').children().detach().end().text(content)
2029
- }
2030
-
2031
- $tip.removeClass('fade top bottom left right in')
2032
-
2033
- // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
2034
- // this manually by checking the contents.
2035
- if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
2036
- }
2037
-
2038
- Popover.prototype.hasContent = function () {
2039
- return this.getTitle() || this.getContent()
2040
- }
2041
-
2042
- Popover.prototype.getContent = function () {
2043
- var $e = this.$element
2044
- var o = this.options
2045
-
2046
- return $e.attr('data-content')
2047
- || (typeof o.content == 'function' ?
2048
- o.content.call($e[0]) :
2049
- o.content)
2050
- }
2051
-
2052
- Popover.prototype.arrow = function () {
2053
- return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
2054
- }
2055
-
2056
-
2057
- // POPOVER PLUGIN DEFINITION
2058
- // =========================
2059
-
2060
- function Plugin(option) {
2061
- return this.each(function () {
2062
- var $this = $(this)
2063
- var data = $this.data('bs.popover')
2064
- var options = typeof option == 'object' && option
2065
-
2066
- if (!data && /destroy|hide/.test(option)) return
2067
- if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
2068
- if (typeof option == 'string') data[option]()
2069
- })
2070
- }
2071
-
2072
- var old = $.fn.popover
2073
-
2074
- $.fn.popover = Plugin
2075
- $.fn.popover.Constructor = Popover
2076
-
2077
-
2078
- // POPOVER NO CONFLICT
2079
- // ===================
2080
-
2081
- $.fn.popover.noConflict = function () {
2082
- $.fn.popover = old
2083
- return this
2084
- }
2085
-
2086
- }(jQuery);
2087
-
2088
- /* ========================================================================
2089
- * Bootstrap: scrollspy.js v3.4.1
2090
- * https://getbootstrap.com/docs/3.4/javascript/#scrollspy
2091
- * ========================================================================
2092
- * Copyright 2011-2019 Twitter, Inc.
2093
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2094
- * ======================================================================== */
2095
-
2096
-
2097
- +function ($) {
2098
- 'use strict';
2099
-
2100
- // SCROLLSPY CLASS DEFINITION
2101
- // ==========================
2102
-
2103
- function ScrollSpy(element, options) {
2104
- this.$body = $(document.body)
2105
- this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
2106
- this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
2107
- this.selector = (this.options.target || '') + ' .nav li > a'
2108
- this.offsets = []
2109
- this.targets = []
2110
- this.activeTarget = null
2111
- this.scrollHeight = 0
2112
-
2113
- this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
2114
- this.refresh()
2115
- this.process()
2116
- }
2117
-
2118
- ScrollSpy.VERSION = '3.4.1'
2119
-
2120
- ScrollSpy.DEFAULTS = {
2121
- offset: 10
2122
- }
2123
-
2124
- ScrollSpy.prototype.getScrollHeight = function () {
2125
- return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
2126
- }
2127
-
2128
- ScrollSpy.prototype.refresh = function () {
2129
- var that = this
2130
- var offsetMethod = 'offset'
2131
- var offsetBase = 0
2132
-
2133
- this.offsets = []
2134
- this.targets = []
2135
- this.scrollHeight = this.getScrollHeight()
2136
-
2137
- if (!$.isWindow(this.$scrollElement[0])) {
2138
- offsetMethod = 'position'
2139
- offsetBase = this.$scrollElement.scrollTop()
2140
- }
2141
-
2142
- this.$body
2143
- .find(this.selector)
2144
- .map(function () {
2145
- var $el = $(this)
2146
- var href = $el.data('target') || $el.attr('href')
2147
- var $href = /^#./.test(href) && $(href)
2148
-
2149
- return ($href
2150
- && $href.length
2151
- && $href.is(':visible')
2152
- && [[$href[offsetMethod]().top + offsetBase, href]]) || null
2153
- })
2154
- .sort(function (a, b) { return a[0] - b[0] })
2155
- .each(function () {
2156
- that.offsets.push(this[0])
2157
- that.targets.push(this[1])
2158
- })
2159
- }
2160
-
2161
- ScrollSpy.prototype.process = function () {
2162
- var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
2163
- var scrollHeight = this.getScrollHeight()
2164
- var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
2165
- var offsets = this.offsets
2166
- var targets = this.targets
2167
- var activeTarget = this.activeTarget
2168
- var i
2169
-
2170
- if (this.scrollHeight != scrollHeight) {
2171
- this.refresh()
2172
- }
2173
-
2174
- if (scrollTop >= maxScroll) {
2175
- return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
2176
- }
2177
-
2178
- if (activeTarget && scrollTop < offsets[0]) {
2179
- this.activeTarget = null
2180
- return this.clear()
2181
- }
2182
-
2183
- for (i = offsets.length; i--;) {
2184
- activeTarget != targets[i]
2185
- && scrollTop >= offsets[i]
2186
- && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
2187
- && this.activate(targets[i])
2188
- }
2189
- }
2190
-
2191
- ScrollSpy.prototype.activate = function (target) {
2192
- this.activeTarget = target
2193
-
2194
- this.clear()
2195
-
2196
- var selector = this.selector +
2197
- '[data-target="' + target + '"],' +
2198
- this.selector + '[href="' + target + '"]'
2199
-
2200
- var active = $(selector)
2201
- .parents('li')
2202
- .addClass('active')
2203
-
2204
- if (active.parent('.dropdown-menu').length) {
2205
- active = active
2206
- .closest('li.dropdown')
2207
- .addClass('active')
2208
- }
2209
-
2210
- active.trigger('activate.bs.scrollspy')
2211
- }
2212
-
2213
- ScrollSpy.prototype.clear = function () {
2214
- $(this.selector)
2215
- .parentsUntil(this.options.target, '.active')
2216
- .removeClass('active')
2217
- }
2218
-
2219
-
2220
- // SCROLLSPY PLUGIN DEFINITION
2221
- // ===========================
2222
-
2223
- function Plugin(option) {
2224
- return this.each(function () {
2225
- var $this = $(this)
2226
- var data = $this.data('bs.scrollspy')
2227
- var options = typeof option == 'object' && option
2228
-
2229
- if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
2230
- if (typeof option == 'string') data[option]()
2231
- })
2232
- }
2233
-
2234
- var old = $.fn.scrollspy
2235
-
2236
- $.fn.scrollspy = Plugin
2237
- $.fn.scrollspy.Constructor = ScrollSpy
2238
-
2239
-
2240
- // SCROLLSPY NO CONFLICT
2241
- // =====================
2242
-
2243
- $.fn.scrollspy.noConflict = function () {
2244
- $.fn.scrollspy = old
2245
- return this
2246
- }
2247
-
2248
-
2249
- // SCROLLSPY DATA-API
2250
- // ==================
2251
-
2252
- $(window).on('load.bs.scrollspy.data-api', function () {
2253
- $('[data-spy="scroll"]').each(function () {
2254
- var $spy = $(this)
2255
- Plugin.call($spy, $spy.data())
2256
- })
2257
- })
2258
-
2259
- }(jQuery);
2260
-
2261
- /* ========================================================================
2262
- * Bootstrap: tab.js v3.4.1
2263
- * https://getbootstrap.com/docs/3.4/javascript/#tabs
2264
- * ========================================================================
2265
- * Copyright 2011-2019 Twitter, Inc.
2266
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2267
- * ======================================================================== */
2268
-
2269
-
2270
- +function ($) {
2271
- 'use strict';
2272
-
2273
- // TAB CLASS DEFINITION
2274
- // ====================
2275
-
2276
- var Tab = function (element) {
2277
- // jscs:disable requireDollarBeforejQueryAssignment
2278
- this.element = $(element)
2279
- // jscs:enable requireDollarBeforejQueryAssignment
2280
- }
2281
-
2282
- Tab.VERSION = '3.4.1'
2283
-
2284
- Tab.TRANSITION_DURATION = 150
2285
-
2286
- Tab.prototype.show = function () {
2287
- var $this = this.element
2288
- var $ul = $this.closest('ul:not(.dropdown-menu)')
2289
- var selector = $this.data('target')
2290
-
2291
- if (!selector) {
2292
- selector = $this.attr('href')
2293
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
2294
- }
2295
-
2296
- if ($this.parent('li').hasClass('active')) return
2297
-
2298
- var $previous = $ul.find('.active:last a')
2299
- var hideEvent = $.Event('hide.bs.tab', {
2300
- relatedTarget: $this[0]
2301
- })
2302
- var showEvent = $.Event('show.bs.tab', {
2303
- relatedTarget: $previous[0]
2304
- })
2305
-
2306
- $previous.trigger(hideEvent)
2307
- $this.trigger(showEvent)
2308
-
2309
- if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
2310
-
2311
- var $target = $(document).find(selector)
2312
-
2313
- this.activate($this.closest('li'), $ul)
2314
- this.activate($target, $target.parent(), function () {
2315
- $previous.trigger({
2316
- type: 'hidden.bs.tab',
2317
- relatedTarget: $this[0]
2318
- })
2319
- $this.trigger({
2320
- type: 'shown.bs.tab',
2321
- relatedTarget: $previous[0]
2322
- })
2323
- })
2324
- }
2325
-
2326
- Tab.prototype.activate = function (element, container, callback) {
2327
- var $active = container.find('> .active')
2328
- var transition = callback
2329
- && $.support.transition
2330
- && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
2331
-
2332
- function next() {
2333
- $active
2334
- .removeClass('active')
2335
- .find('> .dropdown-menu > .active')
2336
- .removeClass('active')
2337
- .end()
2338
- .find('[data-toggle="tab"]')
2339
- .attr('aria-expanded', false)
2340
-
2341
- element
2342
- .addClass('active')
2343
- .find('[data-toggle="tab"]')
2344
- .attr('aria-expanded', true)
2345
-
2346
- if (transition) {
2347
- element[0].offsetWidth // reflow for transition
2348
- element.addClass('in')
2349
- } else {
2350
- element.removeClass('fade')
2351
- }
2352
-
2353
- if (element.parent('.dropdown-menu').length) {
2354
- element
2355
- .closest('li.dropdown')
2356
- .addClass('active')
2357
- .end()
2358
- .find('[data-toggle="tab"]')
2359
- .attr('aria-expanded', true)
2360
- }
2361
-
2362
- callback && callback()
2363
- }
2364
-
2365
- $active.length && transition ?
2366
- $active
2367
- .one('bsTransitionEnd', next)
2368
- .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
2369
- next()
2370
-
2371
- $active.removeClass('in')
2372
- }
2373
-
2374
-
2375
- // TAB PLUGIN DEFINITION
2376
- // =====================
2377
-
2378
- function Plugin(option) {
2379
- return this.each(function () {
2380
- var $this = $(this)
2381
- var data = $this.data('bs.tab')
2382
-
2383
- if (!data) $this.data('bs.tab', (data = new Tab(this)))
2384
- if (typeof option == 'string') data[option]()
2385
- })
2386
- }
2387
-
2388
- var old = $.fn.tab
2389
-
2390
- $.fn.tab = Plugin
2391
- $.fn.tab.Constructor = Tab
2392
-
2393
-
2394
- // TAB NO CONFLICT
2395
- // ===============
2396
-
2397
- $.fn.tab.noConflict = function () {
2398
- $.fn.tab = old
2399
- return this
2400
- }
2401
-
2402
-
2403
- // TAB DATA-API
2404
- // ============
2405
-
2406
- var clickHandler = function (e) {
2407
- e.preventDefault()
2408
- Plugin.call($(this), 'show')
2409
- }
2410
-
2411
- $(document)
2412
- .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
2413
- .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
2414
-
2415
- }(jQuery);
2416
-
2417
- /* ========================================================================
2418
- * Bootstrap: affix.js v3.4.1
2419
- * https://getbootstrap.com/docs/3.4/javascript/#affix
2420
- * ========================================================================
2421
- * Copyright 2011-2019 Twitter, Inc.
2422
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
2423
- * ======================================================================== */
2424
-
2425
-
2426
- +function ($) {
2427
- 'use strict';
2428
-
2429
- // AFFIX CLASS DEFINITION
2430
- // ======================
2431
-
2432
- var Affix = function (element, options) {
2433
- this.options = $.extend({}, Affix.DEFAULTS, options)
2434
-
2435
- var target = this.options.target === Affix.DEFAULTS.target ? $(this.options.target) : $(document).find(this.options.target)
2436
-
2437
- this.$target = target
2438
- .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
2439
- .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
2440
-
2441
- this.$element = $(element)
2442
- this.affixed = null
2443
- this.unpin = null
2444
- this.pinnedOffset = null
2445
-
2446
- this.checkPosition()
2447
- }
2448
-
2449
- Affix.VERSION = '3.4.1'
2450
-
2451
- Affix.RESET = 'affix affix-top affix-bottom'
2452
-
2453
- Affix.DEFAULTS = {
2454
- offset: 0,
2455
- target: window
2456
- }
2457
-
2458
- Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
2459
- var scrollTop = this.$target.scrollTop()
2460
- var position = this.$element.offset()
2461
- var targetHeight = this.$target.height()
2462
-
2463
- if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
2464
-
2465
- if (this.affixed == 'bottom') {
2466
- if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
2467
- return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
2468
- }
2469
-
2470
- var initializing = this.affixed == null
2471
- var colliderTop = initializing ? scrollTop : position.top
2472
- var colliderHeight = initializing ? targetHeight : height
2473
-
2474
- if (offsetTop != null && scrollTop <= offsetTop) return 'top'
2475
- if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
2476
-
2477
- return false
2478
- }
2479
-
2480
- Affix.prototype.getPinnedOffset = function () {
2481
- if (this.pinnedOffset) return this.pinnedOffset
2482
- this.$element.removeClass(Affix.RESET).addClass('affix')
2483
- var scrollTop = this.$target.scrollTop()
2484
- var position = this.$element.offset()
2485
- return (this.pinnedOffset = position.top - scrollTop)
2486
- }
2487
-
2488
- Affix.prototype.checkPositionWithEventLoop = function () {
2489
- setTimeout($.proxy(this.checkPosition, this), 1)
2490
- }
2491
-
2492
- Affix.prototype.checkPosition = function () {
2493
- if (!this.$element.is(':visible')) return
2494
-
2495
- var height = this.$element.height()
2496
- var offset = this.options.offset
2497
- var offsetTop = offset.top
2498
- var offsetBottom = offset.bottom
2499
- var scrollHeight = Math.max($(document).height(), $(document.body).height())
2500
-
2501
- if (typeof offset != 'object') offsetBottom = offsetTop = offset
2502
- if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
2503
- if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
2504
-
2505
- var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
2506
-
2507
- if (this.affixed != affix) {
2508
- if (this.unpin != null) this.$element.css('top', '')
2509
-
2510
- var affixType = 'affix' + (affix ? '-' + affix : '')
2511
- var e = $.Event(affixType + '.bs.affix')
2512
-
2513
- this.$element.trigger(e)
2514
-
2515
- if (e.isDefaultPrevented()) return
2516
-
2517
- this.affixed = affix
2518
- this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
2519
-
2520
- this.$element
2521
- .removeClass(Affix.RESET)
2522
- .addClass(affixType)
2523
- .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
2524
- }
2525
-
2526
- if (affix == 'bottom') {
2527
- this.$element.offset({
2528
- top: scrollHeight - height - offsetBottom
2529
- })
2530
- }
2531
- }
2532
-
2533
-
2534
- // AFFIX PLUGIN DEFINITION
2535
- // =======================
2536
-
2537
- function Plugin(option) {
2538
- return this.each(function () {
2539
- var $this = $(this)
2540
- var data = $this.data('bs.affix')
2541
- var options = typeof option == 'object' && option
2542
-
2543
- if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
2544
- if (typeof option == 'string') data[option]()
2545
- })
2546
- }
2547
-
2548
- var old = $.fn.affix
2549
-
2550
- $.fn.affix = Plugin
2551
- $.fn.affix.Constructor = Affix
2552
-
2553
-
2554
- // AFFIX NO CONFLICT
2555
- // =================
2556
-
2557
- $.fn.affix.noConflict = function () {
2558
- $.fn.affix = old
2559
- return this
2560
- }
2561
-
2562
-
2563
- // AFFIX DATA-API
2564
- // ==============
2565
-
2566
- $(window).on('load', function () {
2567
- $('[data-spy="affix"]').each(function () {
2568
- var $spy = $(this)
2569
- var data = $spy.data()
2570
-
2571
- data.offset = data.offset || {}
2572
-
2573
- if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
2574
- if (data.offsetTop != null) data.offset.top = data.offsetTop
2575
-
2576
- Plugin.call($spy, data)
2577
- })
2578
- })
2579
-
2580
- }(jQuery);