diff options
Diffstat (limited to 'src/js')
-rw-r--r-- | src/js/bootstrap.js (renamed from src/js/bootstrap-3.3.7.js) | 397 | ||||
-rw-r--r-- | src/js/entropy.js | 345 | ||||
-rw-r--r-- | src/js/index.js | 16 |
3 files changed, 472 insertions, 286 deletions
diff --git a/src/js/bootstrap-3.3.7.js b/src/js/bootstrap.js index 8a2e99a..170bd60 100644 --- a/src/js/bootstrap-3.3.7.js +++ b/src/js/bootstrap.js | |||
@@ -1,6 +1,6 @@ | |||
1 | /*! | 1 | /*! |
2 | * Bootstrap v3.3.7 (http://getbootstrap.com) | 2 | * Bootstrap v3.4.1 (https://getbootstrap.com/) |
3 | * Copyright 2011-2016 Twitter, Inc. | 3 | * Copyright 2011-2019 Twitter, Inc. |
4 | * Licensed under the MIT license | 4 | * Licensed under the MIT license |
5 | */ | 5 | */ |
6 | 6 | ||
@@ -17,10 +17,10 @@ if (typeof jQuery === 'undefined') { | |||
17 | }(jQuery); | 17 | }(jQuery); |
18 | 18 | ||
19 | /* ======================================================================== | 19 | /* ======================================================================== |
20 | * Bootstrap: transition.js v3.3.7 | 20 | * Bootstrap: transition.js v3.4.1 |
21 | * http://getbootstrap.com/javascript/#transitions | 21 | * https://getbootstrap.com/docs/3.4/javascript/#transitions |
22 | * ======================================================================== | 22 | * ======================================================================== |
23 | * Copyright 2011-2016 Twitter, Inc. | 23 | * Copyright 2011-2019 Twitter, Inc. |
24 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 24 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
25 | * ======================================================================== */ | 25 | * ======================================================================== */ |
26 | 26 | ||
@@ -28,7 +28,7 @@ if (typeof jQuery === 'undefined') { | |||
28 | +function ($) { | 28 | +function ($) { |
29 | 'use strict'; | 29 | 'use strict'; |
30 | 30 | ||
31 | // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) | 31 | // CSS TRANSITION SUPPORT (Shoutout: https://modernizr.com/) |
32 | // ============================================================ | 32 | // ============================================================ |
33 | 33 | ||
34 | function transitionEnd() { | 34 | function transitionEnd() { |
@@ -50,7 +50,7 @@ if (typeof jQuery === 'undefined') { | |||
50 | return false // explicit for ie8 ( ._.) | 50 | return false // explicit for ie8 ( ._.) |
51 | } | 51 | } |
52 | 52 | ||
53 | // http://blog.alexmaccaw.com/css-transitions | 53 | // https://blog.alexmaccaw.com/css-transitions |
54 | $.fn.emulateTransitionEnd = function (duration) { | 54 | $.fn.emulateTransitionEnd = function (duration) { |
55 | var called = false | 55 | var called = false |
56 | var $el = this | 56 | var $el = this |
@@ -77,10 +77,10 @@ if (typeof jQuery === 'undefined') { | |||
77 | }(jQuery); | 77 | }(jQuery); |
78 | 78 | ||
79 | /* ======================================================================== | 79 | /* ======================================================================== |
80 | * Bootstrap: alert.js v3.3.7 | 80 | * Bootstrap: alert.js v3.4.1 |
81 | * http://getbootstrap.com/javascript/#alerts | 81 | * https://getbootstrap.com/docs/3.4/javascript/#alerts |
82 | * ======================================================================== | 82 | * ======================================================================== |
83 | * Copyright 2011-2016 Twitter, Inc. | 83 | * Copyright 2011-2019 Twitter, Inc. |
84 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 84 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
85 | * ======================================================================== */ | 85 | * ======================================================================== */ |
86 | 86 | ||
@@ -96,7 +96,7 @@ if (typeof jQuery === 'undefined') { | |||
96 | $(el).on('click', dismiss, this.close) | 96 | $(el).on('click', dismiss, this.close) |
97 | } | 97 | } |
98 | 98 | ||
99 | Alert.VERSION = '3.3.7' | 99 | Alert.VERSION = '3.4.1' |
100 | 100 | ||
101 | Alert.TRANSITION_DURATION = 150 | 101 | Alert.TRANSITION_DURATION = 150 |
102 | 102 | ||
@@ -109,7 +109,8 @@ if (typeof jQuery === 'undefined') { | |||
109 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 | 109 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 |
110 | } | 110 | } |
111 | 111 | ||
112 | var $parent = $(selector === '#' ? [] : selector) | 112 | selector = selector === '#' ? [] : selector |
113 | var $parent = $(document).find(selector) | ||
113 | 114 | ||
114 | if (e) e.preventDefault() | 115 | if (e) e.preventDefault() |
115 | 116 | ||
@@ -172,10 +173,10 @@ if (typeof jQuery === 'undefined') { | |||
172 | }(jQuery); | 173 | }(jQuery); |
173 | 174 | ||
174 | /* ======================================================================== | 175 | /* ======================================================================== |
175 | * Bootstrap: button.js v3.3.7 | 176 | * Bootstrap: button.js v3.4.1 |
176 | * http://getbootstrap.com/javascript/#buttons | 177 | * https://getbootstrap.com/docs/3.4/javascript/#buttons |
177 | * ======================================================================== | 178 | * ======================================================================== |
178 | * Copyright 2011-2016 Twitter, Inc. | 179 | * Copyright 2011-2019 Twitter, Inc. |
179 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 180 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
180 | * ======================================================================== */ | 181 | * ======================================================================== */ |
181 | 182 | ||
@@ -192,7 +193,7 @@ if (typeof jQuery === 'undefined') { | |||
192 | this.isLoading = false | 193 | this.isLoading = false |
193 | } | 194 | } |
194 | 195 | ||
195 | Button.VERSION = '3.3.7' | 196 | Button.VERSION = '3.4.1' |
196 | 197 | ||
197 | Button.DEFAULTS = { | 198 | Button.DEFAULTS = { |
198 | loadingText: 'loading...' | 199 | loadingText: 'loading...' |
@@ -298,10 +299,10 @@ if (typeof jQuery === 'undefined') { | |||
298 | }(jQuery); | 299 | }(jQuery); |
299 | 300 | ||
300 | /* ======================================================================== | 301 | /* ======================================================================== |
301 | * Bootstrap: carousel.js v3.3.7 | 302 | * Bootstrap: carousel.js v3.4.1 |
302 | * http://getbootstrap.com/javascript/#carousel | 303 | * https://getbootstrap.com/docs/3.4/javascript/#carousel |
303 | * ======================================================================== | 304 | * ======================================================================== |
304 | * Copyright 2011-2016 Twitter, Inc. | 305 | * Copyright 2011-2019 Twitter, Inc. |
305 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 306 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
306 | * ======================================================================== */ | 307 | * ======================================================================== */ |
307 | 308 | ||
@@ -329,7 +330,7 @@ if (typeof jQuery === 'undefined') { | |||
329 | .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) | 330 | .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) |
330 | } | 331 | } |
331 | 332 | ||
332 | Carousel.VERSION = '3.3.7' | 333 | Carousel.VERSION = '3.4.1' |
333 | 334 | ||
334 | Carousel.TRANSITION_DURATION = 600 | 335 | Carousel.TRANSITION_DURATION = 600 |
335 | 336 | ||
@@ -443,7 +444,9 @@ if (typeof jQuery === 'undefined') { | |||
443 | var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" | 444 | var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" |
444 | if ($.support.transition && this.$element.hasClass('slide')) { | 445 | if ($.support.transition && this.$element.hasClass('slide')) { |
445 | $next.addClass(type) | 446 | $next.addClass(type) |
446 | $next[0].offsetWidth // force reflow | 447 | if (typeof $next === 'object' && $next.length) { |
448 | $next[0].offsetWidth // force reflow | ||
449 | } | ||
447 | $active.addClass(direction) | 450 | $active.addClass(direction) |
448 | $next.addClass(direction) | 451 | $next.addClass(direction) |
449 | $active | 452 | $active |
@@ -505,10 +508,17 @@ if (typeof jQuery === 'undefined') { | |||
505 | // ================= | 508 | // ================= |
506 | 509 | ||
507 | var clickHandler = function (e) { | 510 | var clickHandler = function (e) { |
508 | var href | ||
509 | var $this = $(this) | 511 | var $this = $(this) |
510 | var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 | 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 | |||
511 | if (!$target.hasClass('carousel')) return | 520 | if (!$target.hasClass('carousel')) return |
521 | |||
512 | var options = $.extend({}, $target.data(), $this.data()) | 522 | var options = $.extend({}, $target.data(), $this.data()) |
513 | var slideIndex = $this.attr('data-slide-to') | 523 | var slideIndex = $this.attr('data-slide-to') |
514 | if (slideIndex) options.interval = false | 524 | if (slideIndex) options.interval = false |
@@ -536,10 +546,10 @@ if (typeof jQuery === 'undefined') { | |||
536 | }(jQuery); | 546 | }(jQuery); |
537 | 547 | ||
538 | /* ======================================================================== | 548 | /* ======================================================================== |
539 | * Bootstrap: collapse.js v3.3.7 | 549 | * Bootstrap: collapse.js v3.4.1 |
540 | * http://getbootstrap.com/javascript/#collapse | 550 | * https://getbootstrap.com/docs/3.4/javascript/#collapse |
541 | * ======================================================================== | 551 | * ======================================================================== |
542 | * Copyright 2011-2016 Twitter, Inc. | 552 | * Copyright 2011-2019 Twitter, Inc. |
543 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 553 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
544 | * ======================================================================== */ | 554 | * ======================================================================== */ |
545 | 555 | ||
@@ -567,7 +577,7 @@ if (typeof jQuery === 'undefined') { | |||
567 | if (this.options.toggle) this.toggle() | 577 | if (this.options.toggle) this.toggle() |
568 | } | 578 | } |
569 | 579 | ||
570 | Collapse.VERSION = '3.3.7' | 580 | Collapse.VERSION = '3.4.1' |
571 | 581 | ||
572 | Collapse.TRANSITION_DURATION = 350 | 582 | Collapse.TRANSITION_DURATION = 350 |
573 | 583 | ||
@@ -674,7 +684,7 @@ if (typeof jQuery === 'undefined') { | |||
674 | } | 684 | } |
675 | 685 | ||
676 | Collapse.prototype.getParent = function () { | 686 | Collapse.prototype.getParent = function () { |
677 | return $(this.options.parent) | 687 | return $(document).find(this.options.parent) |
678 | .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') | 688 | .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') |
679 | .each($.proxy(function (i, element) { | 689 | .each($.proxy(function (i, element) { |
680 | var $element = $(element) | 690 | var $element = $(element) |
@@ -697,7 +707,7 @@ if (typeof jQuery === 'undefined') { | |||
697 | var target = $trigger.attr('data-target') | 707 | var target = $trigger.attr('data-target') |
698 | || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 | 708 | || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 |
699 | 709 | ||
700 | return $(target) | 710 | return $(document).find(target) |
701 | } | 711 | } |
702 | 712 | ||
703 | 713 | ||
@@ -749,10 +759,10 @@ if (typeof jQuery === 'undefined') { | |||
749 | }(jQuery); | 759 | }(jQuery); |
750 | 760 | ||
751 | /* ======================================================================== | 761 | /* ======================================================================== |
752 | * Bootstrap: dropdown.js v3.3.7 | 762 | * Bootstrap: dropdown.js v3.4.1 |
753 | * http://getbootstrap.com/javascript/#dropdowns | 763 | * https://getbootstrap.com/docs/3.4/javascript/#dropdowns |
754 | * ======================================================================== | 764 | * ======================================================================== |
755 | * Copyright 2011-2016 Twitter, Inc. | 765 | * Copyright 2011-2019 Twitter, Inc. |
756 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 766 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
757 | * ======================================================================== */ | 767 | * ======================================================================== */ |
758 | 768 | ||
@@ -769,7 +779,7 @@ if (typeof jQuery === 'undefined') { | |||
769 | $(element).on('click.bs.dropdown', this.toggle) | 779 | $(element).on('click.bs.dropdown', this.toggle) |
770 | } | 780 | } |
771 | 781 | ||
772 | Dropdown.VERSION = '3.3.7' | 782 | Dropdown.VERSION = '3.4.1' |
773 | 783 | ||
774 | function getParent($this) { | 784 | function getParent($this) { |
775 | var selector = $this.attr('data-target') | 785 | var selector = $this.attr('data-target') |
@@ -779,7 +789,7 @@ if (typeof jQuery === 'undefined') { | |||
779 | selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 | 789 | selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 |
780 | } | 790 | } |
781 | 791 | ||
782 | var $parent = selector && $(selector) | 792 | var $parent = selector !== '#' ? $(document).find(selector) : null |
783 | 793 | ||
784 | return $parent && $parent.length ? $parent : $this.parent() | 794 | return $parent && $parent.length ? $parent : $this.parent() |
785 | } | 795 | } |
@@ -915,10 +925,10 @@ if (typeof jQuery === 'undefined') { | |||
915 | }(jQuery); | 925 | }(jQuery); |
916 | 926 | ||
917 | /* ======================================================================== | 927 | /* ======================================================================== |
918 | * Bootstrap: modal.js v3.3.7 | 928 | * Bootstrap: modal.js v3.4.1 |
919 | * http://getbootstrap.com/javascript/#modals | 929 | * https://getbootstrap.com/docs/3.4/javascript/#modals |
920 | * ======================================================================== | 930 | * ======================================================================== |
921 | * Copyright 2011-2016 Twitter, Inc. | 931 | * Copyright 2011-2019 Twitter, Inc. |
922 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 932 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
923 | * ======================================================================== */ | 933 | * ======================================================================== */ |
924 | 934 | ||
@@ -930,15 +940,16 @@ if (typeof jQuery === 'undefined') { | |||
930 | // ====================== | 940 | // ====================== |
931 | 941 | ||
932 | var Modal = function (element, options) { | 942 | var Modal = function (element, options) { |
933 | this.options = options | 943 | this.options = options |
934 | this.$body = $(document.body) | 944 | this.$body = $(document.body) |
935 | this.$element = $(element) | 945 | this.$element = $(element) |
936 | this.$dialog = this.$element.find('.modal-dialog') | 946 | this.$dialog = this.$element.find('.modal-dialog') |
937 | this.$backdrop = null | 947 | this.$backdrop = null |
938 | this.isShown = null | 948 | this.isShown = null |
939 | this.originalBodyPad = null | 949 | this.originalBodyPad = null |
940 | this.scrollbarWidth = 0 | 950 | this.scrollbarWidth = 0 |
941 | this.ignoreBackdropClick = false | 951 | this.ignoreBackdropClick = false |
952 | this.fixedContent = '.navbar-fixed-top, .navbar-fixed-bottom' | ||
942 | 953 | ||
943 | if (this.options.remote) { | 954 | if (this.options.remote) { |
944 | this.$element | 955 | this.$element |
@@ -949,7 +960,7 @@ if (typeof jQuery === 'undefined') { | |||
949 | } | 960 | } |
950 | } | 961 | } |
951 | 962 | ||
952 | Modal.VERSION = '3.3.7' | 963 | Modal.VERSION = '3.4.1' |
953 | 964 | ||
954 | Modal.TRANSITION_DURATION = 300 | 965 | Modal.TRANSITION_DURATION = 300 |
955 | Modal.BACKDROP_TRANSITION_DURATION = 150 | 966 | Modal.BACKDROP_TRANSITION_DURATION = 150 |
@@ -966,7 +977,7 @@ if (typeof jQuery === 'undefined') { | |||
966 | 977 | ||
967 | Modal.prototype.show = function (_relatedTarget) { | 978 | Modal.prototype.show = function (_relatedTarget) { |
968 | var that = this | 979 | var that = this |
969 | var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) | 980 | var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) |
970 | 981 | ||
971 | this.$element.trigger(e) | 982 | this.$element.trigger(e) |
972 | 983 | ||
@@ -1057,8 +1068,8 @@ if (typeof jQuery === 'undefined') { | |||
1057 | .off('focusin.bs.modal') // guard against infinite focus loop | 1068 | .off('focusin.bs.modal') // guard against infinite focus loop |
1058 | .on('focusin.bs.modal', $.proxy(function (e) { | 1069 | .on('focusin.bs.modal', $.proxy(function (e) { |
1059 | if (document !== e.target && | 1070 | if (document !== e.target && |
1060 | this.$element[0] !== e.target && | 1071 | this.$element[0] !== e.target && |
1061 | !this.$element.has(e.target).length) { | 1072 | !this.$element.has(e.target).length) { |
1062 | this.$element.trigger('focus') | 1073 | this.$element.trigger('focus') |
1063 | } | 1074 | } |
1064 | }, this)) | 1075 | }, this)) |
@@ -1160,7 +1171,7 @@ if (typeof jQuery === 'undefined') { | |||
1160 | var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight | 1171 | var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight |
1161 | 1172 | ||
1162 | this.$element.css({ | 1173 | this.$element.css({ |
1163 | paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', | 1174 | paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', |
1164 | paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' | 1175 | paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' |
1165 | }) | 1176 | }) |
1166 | } | 1177 | } |
@@ -1185,11 +1196,26 @@ if (typeof jQuery === 'undefined') { | |||
1185 | Modal.prototype.setScrollbar = function () { | 1196 | Modal.prototype.setScrollbar = function () { |
1186 | var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) | 1197 | var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) |
1187 | this.originalBodyPad = document.body.style.paddingRight || '' | 1198 | this.originalBodyPad = document.body.style.paddingRight || '' |
1188 | if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) | 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 | } | ||
1189 | } | 1210 | } |
1190 | 1211 | ||
1191 | Modal.prototype.resetScrollbar = function () { | 1212 | Modal.prototype.resetScrollbar = function () { |
1192 | this.$body.css('padding-right', this.originalBodyPad) | 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 | }) | ||
1193 | } | 1219 | } |
1194 | 1220 | ||
1195 | Modal.prototype.measureScrollbar = function () { // thx walsh | 1221 | Modal.prototype.measureScrollbar = function () { // thx walsh |
@@ -1207,8 +1233,8 @@ if (typeof jQuery === 'undefined') { | |||
1207 | 1233 | ||
1208 | function Plugin(option, _relatedTarget) { | 1234 | function Plugin(option, _relatedTarget) { |
1209 | return this.each(function () { | 1235 | return this.each(function () { |
1210 | var $this = $(this) | 1236 | var $this = $(this) |
1211 | var data = $this.data('bs.modal') | 1237 | var data = $this.data('bs.modal') |
1212 | var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) | 1238 | var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) |
1213 | 1239 | ||
1214 | if (!data) $this.data('bs.modal', (data = new Modal(this, options))) | 1240 | if (!data) $this.data('bs.modal', (data = new Modal(this, options))) |
@@ -1219,7 +1245,7 @@ if (typeof jQuery === 'undefined') { | |||
1219 | 1245 | ||
1220 | var old = $.fn.modal | 1246 | var old = $.fn.modal |
1221 | 1247 | ||
1222 | $.fn.modal = Plugin | 1248 | $.fn.modal = Plugin |
1223 | $.fn.modal.Constructor = Modal | 1249 | $.fn.modal.Constructor = Modal |
1224 | 1250 | ||
1225 | 1251 | ||
@@ -1236,10 +1262,13 @@ if (typeof jQuery === 'undefined') { | |||
1236 | // ============== | 1262 | // ============== |
1237 | 1263 | ||
1238 | $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { | 1264 | $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { |
1239 | var $this = $(this) | 1265 | var $this = $(this) |
1240 | var href = $this.attr('href') | 1266 | var href = $this.attr('href') |
1241 | var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 | 1267 | var target = $this.attr('data-target') || |
1242 | var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) | 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()) | ||
1243 | 1272 | ||
1244 | if ($this.is('a')) e.preventDefault() | 1273 | if ($this.is('a')) e.preventDefault() |
1245 | 1274 | ||
@@ -1255,18 +1284,148 @@ if (typeof jQuery === 'undefined') { | |||
1255 | }(jQuery); | 1284 | }(jQuery); |
1256 | 1285 | ||
1257 | /* ======================================================================== | 1286 | /* ======================================================================== |
1258 | * Bootstrap: tooltip.js v3.3.7 | 1287 | * Bootstrap: tooltip.js v3.4.1 |
1259 | * http://getbootstrap.com/javascript/#tooltip | 1288 | * https://getbootstrap.com/docs/3.4/javascript/#tooltip |
1260 | * Inspired by the original jQuery.tipsy by Jason Frame | 1289 | * Inspired by the original jQuery.tipsy by Jason Frame |
1261 | * ======================================================================== | 1290 | * ======================================================================== |
1262 | * Copyright 2011-2016 Twitter, Inc. | 1291 | * Copyright 2011-2019 Twitter, Inc. |
1263 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 1292 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
1264 | * ======================================================================== */ | 1293 | * ======================================================================== */ |
1265 | 1294 | ||
1266 | |||
1267 | +function ($) { | 1295 | +function ($) { |
1268 | 'use strict'; | 1296 | 'use strict'; |
1269 | 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 | |||
1270 | // TOOLTIP PUBLIC CLASS DEFINITION | 1429 | // TOOLTIP PUBLIC CLASS DEFINITION |
1271 | // =============================== | 1430 | // =============================== |
1272 | 1431 | ||
@@ -1282,7 +1441,7 @@ if (typeof jQuery === 'undefined') { | |||
1282 | this.init('tooltip', element, options) | 1441 | this.init('tooltip', element, options) |
1283 | } | 1442 | } |
1284 | 1443 | ||
1285 | Tooltip.VERSION = '3.3.7' | 1444 | Tooltip.VERSION = '3.4.1' |
1286 | 1445 | ||
1287 | Tooltip.TRANSITION_DURATION = 150 | 1446 | Tooltip.TRANSITION_DURATION = 150 |
1288 | 1447 | ||
@@ -1299,7 +1458,10 @@ if (typeof jQuery === 'undefined') { | |||
1299 | viewport: { | 1458 | viewport: { |
1300 | selector: 'body', | 1459 | selector: 'body', |
1301 | padding: 0 | 1460 | padding: 0 |
1302 | } | 1461 | }, |
1462 | sanitize : true, | ||
1463 | sanitizeFn : null, | ||
1464 | whiteList : DefaultWhitelist | ||
1303 | } | 1465 | } |
1304 | 1466 | ||
1305 | Tooltip.prototype.init = function (type, element, options) { | 1467 | Tooltip.prototype.init = function (type, element, options) { |
@@ -1307,7 +1469,7 @@ if (typeof jQuery === 'undefined') { | |||
1307 | this.type = type | 1469 | this.type = type |
1308 | this.$element = $(element) | 1470 | this.$element = $(element) |
1309 | this.options = this.getOptions(options) | 1471 | this.options = this.getOptions(options) |
1310 | this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) | 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)) |
1311 | this.inState = { click: false, hover: false, focus: false } | 1473 | this.inState = { click: false, hover: false, focus: false } |
1312 | 1474 | ||
1313 | if (this.$element[0] instanceof document.constructor && !this.options.selector) { | 1475 | if (this.$element[0] instanceof document.constructor && !this.options.selector) { |
@@ -1340,7 +1502,15 @@ if (typeof jQuery === 'undefined') { | |||
1340 | } | 1502 | } |
1341 | 1503 | ||
1342 | Tooltip.prototype.getOptions = function (options) { | 1504 | Tooltip.prototype.getOptions = function (options) { |
1343 | options = $.extend({}, this.getDefaults(), this.$element.data(), 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) | ||
1344 | 1514 | ||
1345 | if (options.delay && typeof options.delay == 'number') { | 1515 | if (options.delay && typeof options.delay == 'number') { |
1346 | options.delay = { | 1516 | options.delay = { |
@@ -1349,6 +1519,10 @@ if (typeof jQuery === 'undefined') { | |||
1349 | } | 1519 | } |
1350 | } | 1520 | } |
1351 | 1521 | ||
1522 | if (options.sanitize) { | ||
1523 | options.template = sanitizeHtml(options.template, options.whiteList, options.sanitizeFn) | ||
1524 | } | ||
1525 | |||
1352 | return options | 1526 | return options |
1353 | } | 1527 | } |
1354 | 1528 | ||
@@ -1460,7 +1634,7 @@ if (typeof jQuery === 'undefined') { | |||
1460 | .addClass(placement) | 1634 | .addClass(placement) |
1461 | .data('bs.' + this.type, this) | 1635 | .data('bs.' + this.type, this) |
1462 | 1636 | ||
1463 | this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) | 1637 | this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) |
1464 | this.$element.trigger('inserted.bs.' + this.type) | 1638 | this.$element.trigger('inserted.bs.' + this.type) |
1465 | 1639 | ||
1466 | var pos = this.getPosition() | 1640 | var pos = this.getPosition() |
@@ -1562,7 +1736,16 @@ if (typeof jQuery === 'undefined') { | |||
1562 | var $tip = this.tip() | 1736 | var $tip = this.tip() |
1563 | var title = this.getTitle() | 1737 | var title = this.getTitle() |
1564 | 1738 | ||
1565 | $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) | 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 | |||
1566 | $tip.removeClass('fade in top bottom left right') | 1749 | $tip.removeClass('fade in top bottom left right') |
1567 | } | 1750 | } |
1568 | 1751 | ||
@@ -1743,6 +1926,9 @@ if (typeof jQuery === 'undefined') { | |||
1743 | }) | 1926 | }) |
1744 | } | 1927 | } |
1745 | 1928 | ||
1929 | Tooltip.prototype.sanitizeHtml = function (unsafeHtml) { | ||
1930 | return sanitizeHtml(unsafeHtml, this.options.whiteList, this.options.sanitizeFn) | ||
1931 | } | ||
1746 | 1932 | ||
1747 | // TOOLTIP PLUGIN DEFINITION | 1933 | // TOOLTIP PLUGIN DEFINITION |
1748 | // ========================= | 1934 | // ========================= |
@@ -1776,10 +1962,10 @@ if (typeof jQuery === 'undefined') { | |||
1776 | }(jQuery); | 1962 | }(jQuery); |
1777 | 1963 | ||
1778 | /* ======================================================================== | 1964 | /* ======================================================================== |
1779 | * Bootstrap: popover.js v3.3.7 | 1965 | * Bootstrap: popover.js v3.4.1 |
1780 | * http://getbootstrap.com/javascript/#popovers | 1966 | * https://getbootstrap.com/docs/3.4/javascript/#popovers |
1781 | * ======================================================================== | 1967 | * ======================================================================== |
1782 | * Copyright 2011-2016 Twitter, Inc. | 1968 | * Copyright 2011-2019 Twitter, Inc. |
1783 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 1969 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
1784 | * ======================================================================== */ | 1970 | * ======================================================================== */ |
1785 | 1971 | ||
@@ -1796,7 +1982,7 @@ if (typeof jQuery === 'undefined') { | |||
1796 | 1982 | ||
1797 | if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') | 1983 | if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') |
1798 | 1984 | ||
1799 | Popover.VERSION = '3.3.7' | 1985 | Popover.VERSION = '3.4.1' |
1800 | 1986 | ||
1801 | Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { | 1987 | Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { |
1802 | placement: 'right', | 1988 | placement: 'right', |
@@ -1822,10 +2008,25 @@ if (typeof jQuery === 'undefined') { | |||
1822 | var title = this.getTitle() | 2008 | var title = this.getTitle() |
1823 | var content = this.getContent() | 2009 | var content = this.getContent() |
1824 | 2010 | ||
1825 | $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) | 2011 | if (this.options.html) { |
1826 | $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events | 2012 | var typeContent = typeof content |
1827 | this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' | 2013 | |
1828 | ](content) | 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 | } | ||
1829 | 2030 | ||
1830 | $tip.removeClass('fade top bottom left right in') | 2031 | $tip.removeClass('fade top bottom left right in') |
1831 | 2032 | ||
@@ -1844,8 +2045,8 @@ if (typeof jQuery === 'undefined') { | |||
1844 | 2045 | ||
1845 | return $e.attr('data-content') | 2046 | return $e.attr('data-content') |
1846 | || (typeof o.content == 'function' ? | 2047 | || (typeof o.content == 'function' ? |
1847 | o.content.call($e[0]) : | 2048 | o.content.call($e[0]) : |
1848 | o.content) | 2049 | o.content) |
1849 | } | 2050 | } |
1850 | 2051 | ||
1851 | Popover.prototype.arrow = function () { | 2052 | Popover.prototype.arrow = function () { |
@@ -1885,10 +2086,10 @@ if (typeof jQuery === 'undefined') { | |||
1885 | }(jQuery); | 2086 | }(jQuery); |
1886 | 2087 | ||
1887 | /* ======================================================================== | 2088 | /* ======================================================================== |
1888 | * Bootstrap: scrollspy.js v3.3.7 | 2089 | * Bootstrap: scrollspy.js v3.4.1 |
1889 | * http://getbootstrap.com/javascript/#scrollspy | 2090 | * https://getbootstrap.com/docs/3.4/javascript/#scrollspy |
1890 | * ======================================================================== | 2091 | * ======================================================================== |
1891 | * Copyright 2011-2016 Twitter, Inc. | 2092 | * Copyright 2011-2019 Twitter, Inc. |
1892 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 2093 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
1893 | * ======================================================================== */ | 2094 | * ======================================================================== */ |
1894 | 2095 | ||
@@ -1914,7 +2115,7 @@ if (typeof jQuery === 'undefined') { | |||
1914 | this.process() | 2115 | this.process() |
1915 | } | 2116 | } |
1916 | 2117 | ||
1917 | ScrollSpy.VERSION = '3.3.7' | 2118 | ScrollSpy.VERSION = '3.4.1' |
1918 | 2119 | ||
1919 | ScrollSpy.DEFAULTS = { | 2120 | ScrollSpy.DEFAULTS = { |
1920 | offset: 10 | 2121 | offset: 10 |
@@ -2058,10 +2259,10 @@ if (typeof jQuery === 'undefined') { | |||
2058 | }(jQuery); | 2259 | }(jQuery); |
2059 | 2260 | ||
2060 | /* ======================================================================== | 2261 | /* ======================================================================== |
2061 | * Bootstrap: tab.js v3.3.7 | 2262 | * Bootstrap: tab.js v3.4.1 |
2062 | * http://getbootstrap.com/javascript/#tabs | 2263 | * https://getbootstrap.com/docs/3.4/javascript/#tabs |
2063 | * ======================================================================== | 2264 | * ======================================================================== |
2064 | * Copyright 2011-2016 Twitter, Inc. | 2265 | * Copyright 2011-2019 Twitter, Inc. |
2065 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 2266 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
2066 | * ======================================================================== */ | 2267 | * ======================================================================== */ |
2067 | 2268 | ||
@@ -2078,7 +2279,7 @@ if (typeof jQuery === 'undefined') { | |||
2078 | // jscs:enable requireDollarBeforejQueryAssignment | 2279 | // jscs:enable requireDollarBeforejQueryAssignment |
2079 | } | 2280 | } |
2080 | 2281 | ||
2081 | Tab.VERSION = '3.3.7' | 2282 | Tab.VERSION = '3.4.1' |
2082 | 2283 | ||
2083 | Tab.TRANSITION_DURATION = 150 | 2284 | Tab.TRANSITION_DURATION = 150 |
2084 | 2285 | ||
@@ -2107,7 +2308,7 @@ if (typeof jQuery === 'undefined') { | |||
2107 | 2308 | ||
2108 | if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return | 2309 | if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return |
2109 | 2310 | ||
2110 | var $target = $(selector) | 2311 | var $target = $(document).find(selector) |
2111 | 2312 | ||
2112 | this.activate($this.closest('li'), $ul) | 2313 | this.activate($this.closest('li'), $ul) |
2113 | this.activate($target, $target.parent(), function () { | 2314 | this.activate($target, $target.parent(), function () { |
@@ -2132,15 +2333,15 @@ if (typeof jQuery === 'undefined') { | |||
2132 | $active | 2333 | $active |
2133 | .removeClass('active') | 2334 | .removeClass('active') |
2134 | .find('> .dropdown-menu > .active') | 2335 | .find('> .dropdown-menu > .active') |
2135 | .removeClass('active') | 2336 | .removeClass('active') |
2136 | .end() | 2337 | .end() |
2137 | .find('[data-toggle="tab"]') | 2338 | .find('[data-toggle="tab"]') |
2138 | .attr('aria-expanded', false) | 2339 | .attr('aria-expanded', false) |
2139 | 2340 | ||
2140 | element | 2341 | element |
2141 | .addClass('active') | 2342 | .addClass('active') |
2142 | .find('[data-toggle="tab"]') | 2343 | .find('[data-toggle="tab"]') |
2143 | .attr('aria-expanded', true) | 2344 | .attr('aria-expanded', true) |
2144 | 2345 | ||
2145 | if (transition) { | 2346 | if (transition) { |
2146 | element[0].offsetWidth // reflow for transition | 2347 | element[0].offsetWidth // reflow for transition |
@@ -2152,10 +2353,10 @@ if (typeof jQuery === 'undefined') { | |||
2152 | if (element.parent('.dropdown-menu').length) { | 2353 | if (element.parent('.dropdown-menu').length) { |
2153 | element | 2354 | element |
2154 | .closest('li.dropdown') | 2355 | .closest('li.dropdown') |
2155 | .addClass('active') | 2356 | .addClass('active') |
2156 | .end() | 2357 | .end() |
2157 | .find('[data-toggle="tab"]') | 2358 | .find('[data-toggle="tab"]') |
2158 | .attr('aria-expanded', true) | 2359 | .attr('aria-expanded', true) |
2159 | } | 2360 | } |
2160 | 2361 | ||
2161 | callback && callback() | 2362 | callback && callback() |
@@ -2214,10 +2415,10 @@ if (typeof jQuery === 'undefined') { | |||
2214 | }(jQuery); | 2415 | }(jQuery); |
2215 | 2416 | ||
2216 | /* ======================================================================== | 2417 | /* ======================================================================== |
2217 | * Bootstrap: affix.js v3.3.7 | 2418 | * Bootstrap: affix.js v3.4.1 |
2218 | * http://getbootstrap.com/javascript/#affix | 2419 | * https://getbootstrap.com/docs/3.4/javascript/#affix |
2219 | * ======================================================================== | 2420 | * ======================================================================== |
2220 | * Copyright 2011-2016 Twitter, Inc. | 2421 | * Copyright 2011-2019 Twitter, Inc. |
2221 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | 2422 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
2222 | * ======================================================================== */ | 2423 | * ======================================================================== */ |
2223 | 2424 | ||
@@ -2231,7 +2432,9 @@ if (typeof jQuery === 'undefined') { | |||
2231 | var Affix = function (element, options) { | 2432 | var Affix = function (element, options) { |
2232 | this.options = $.extend({}, Affix.DEFAULTS, options) | 2433 | this.options = $.extend({}, Affix.DEFAULTS, options) |
2233 | 2434 | ||
2234 | this.$target = $(this.options.target) | 2435 | var target = this.options.target === Affix.DEFAULTS.target ? $(this.options.target) : $(document).find(this.options.target) |
2436 | |||
2437 | this.$target = target | ||
2235 | .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) | 2438 | .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) |
2236 | .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) | 2439 | .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) |
2237 | 2440 | ||
@@ -2243,7 +2446,7 @@ if (typeof jQuery === 'undefined') { | |||
2243 | this.checkPosition() | 2446 | this.checkPosition() |
2244 | } | 2447 | } |
2245 | 2448 | ||
2246 | Affix.VERSION = '3.3.7' | 2449 | Affix.VERSION = '3.4.1' |
2247 | 2450 | ||
2248 | Affix.RESET = 'affix affix-top affix-bottom' | 2451 | Affix.RESET = 'affix affix-top affix-bottom' |
2249 | 2452 | ||
diff --git a/src/js/entropy.js b/src/js/entropy.js index 62b2711..3b62e10 100644 --- a/src/js/entropy.js +++ b/src/js/entropy.js | |||
@@ -16,7 +16,136 @@ | |||
16 | 16 | ||
17 | window.Entropy = new (function() { | 17 | window.Entropy = new (function() { |
18 | 18 | ||
19 | var TWO = new libs.BigInteger.BigInteger(2); | 19 | let eventBits = { |
20 | |||
21 | "binary": { | ||
22 | "0": "0", | ||
23 | "1": "1", | ||
24 | }, | ||
25 | |||
26 | // log2(6) = 2.58496 bits per roll, with bias | ||
27 | // 4 rolls give 2 bits each | ||
28 | // 2 rolls give 1 bit each | ||
29 | // Average (4*2 + 2*1) / 6 = 1.66 bits per roll without bias | ||
30 | "base 6": { | ||
31 | "0": "00", | ||
32 | "1": "01", | ||
33 | "2": "10", | ||
34 | "3": "11", | ||
35 | "4": "0", | ||
36 | "5": "1", | ||
37 | }, | ||
38 | |||
39 | // log2(6) = 2.58496 bits per roll, with bias | ||
40 | // 4 rolls give 2 bits each | ||
41 | // 2 rolls give 1 bit each | ||
42 | // Average (4*2 + 2*1) / 6 = 1.66 bits per roll without bias | ||
43 | "base 6 (dice)": { | ||
44 | "0": "00", // equivalent to 0 in base 6 | ||
45 | "1": "01", | ||
46 | "2": "10", | ||
47 | "3": "11", | ||
48 | "4": "0", | ||
49 | "5": "1", | ||
50 | }, | ||
51 | |||
52 | // log2(10) = 3.321928 bits per digit, with bias | ||
53 | // 8 digits give 3 bits each | ||
54 | // 2 digits give 1 bit each | ||
55 | // Average (8*3 + 2*1) / 10 = 2.6 bits per digit without bias | ||
56 | "base 10": { | ||
57 | "0": "000", | ||
58 | "1": "001", | ||
59 | "2": "010", | ||
60 | "3": "011", | ||
61 | "4": "100", | ||
62 | "5": "101", | ||
63 | "6": "110", | ||
64 | "7": "111", | ||
65 | "8": "0", | ||
66 | "9": "1", | ||
67 | }, | ||
68 | |||
69 | "hexadecimal": { | ||
70 | "0": "0000", | ||
71 | "1": "0001", | ||
72 | "2": "0010", | ||
73 | "3": "0011", | ||
74 | "4": "0100", | ||
75 | "5": "0101", | ||
76 | "6": "0110", | ||
77 | "7": "0111", | ||
78 | "8": "1000", | ||
79 | "9": "1001", | ||
80 | "a": "1010", | ||
81 | "b": "1011", | ||
82 | "c": "1100", | ||
83 | "d": "1101", | ||
84 | "e": "1110", | ||
85 | "f": "1111", | ||
86 | }, | ||
87 | |||
88 | // log2(52) = 5.7004 bits per card, with bias | ||
89 | // 32 cards give 5 bits each | ||
90 | // 16 cards give 4 bits each | ||
91 | // 4 cards give 2 bits each | ||
92 | // Average (32*5 + 16*4 + 4*2) / 52 = 4.46 bits per card without bias | ||
93 | "card": { | ||
94 | "ac": "00000", | ||
95 | "2c": "00001", | ||
96 | "3c": "00010", | ||
97 | "4c": "00011", | ||
98 | "5c": "00100", | ||
99 | "6c": "00101", | ||
100 | "7c": "00110", | ||
101 | "8c": "00111", | ||
102 | "9c": "01000", | ||
103 | "tc": "01001", | ||
104 | "jc": "01010", | ||
105 | "qc": "01011", | ||
106 | "kc": "01100", | ||
107 | "ad": "01101", | ||
108 | "2d": "01110", | ||
109 | "3d": "01111", | ||
110 | "4d": "10000", | ||
111 | "5d": "10001", | ||
112 | "6d": "10010", | ||
113 | "7d": "10011", | ||
114 | "8d": "10100", | ||
115 | "9d": "10101", | ||
116 | "td": "10110", | ||
117 | "jd": "10111", | ||
118 | "qd": "11000", | ||
119 | "kd": "11001", | ||
120 | "ah": "11010", | ||
121 | "2h": "11011", | ||
122 | "3h": "11100", | ||
123 | "4h": "11101", | ||
124 | "5h": "11110", | ||
125 | "6h": "11111", | ||
126 | "7h": "0000", | ||
127 | "8h": "0001", | ||
128 | "9h": "0010", | ||
129 | "th": "0011", | ||
130 | "jh": "0100", | ||
131 | "qh": "0101", | ||
132 | "kh": "0110", | ||
133 | "as": "0111", | ||
134 | "2s": "1000", | ||
135 | "3s": "1001", | ||
136 | "4s": "1010", | ||
137 | "5s": "1011", | ||
138 | "6s": "1100", | ||
139 | "7s": "1101", | ||
140 | "8s": "1110", | ||
141 | "9s": "1111", | ||
142 | "ts": "00", | ||
143 | "js": "01", | ||
144 | "qs": "10", | ||
145 | "ks": "11", | ||
146 | }, | ||
147 | |||
148 | } | ||
20 | 149 | ||
21 | // matchers returns an array of the matched events for each type of entropy. | 150 | // matchers returns an array of the matched events for each type of entropy. |
22 | // eg | 151 | // eg |
@@ -51,48 +180,28 @@ window.Entropy = new (function() { | |||
51 | } | 180 | } |
52 | } | 181 | } |
53 | 182 | ||
54 | // Convert array of cards from ["ac", "4d", "ks"] | ||
55 | // to numbers between 0 and 51 [0, 16, 51] | ||
56 | function convertCardsToInts(cards) { | ||
57 | var ints = []; | ||
58 | var values = "a23456789tjqk"; | ||
59 | var suits = "cdhs"; | ||
60 | for (var i=0; i<cards.length; i++) { | ||
61 | var card = cards[i].toLowerCase(); | ||
62 | var value = card[0]; | ||
63 | var suit = card[1]; | ||
64 | var asInt = 13 * suits.indexOf(suit) + values.indexOf(value); | ||
65 | ints.push(asInt); | ||
66 | } | ||
67 | return ints; | ||
68 | } | ||
69 | |||
70 | this.fromString = function(rawEntropyStr, baseStr) { | 183 | this.fromString = function(rawEntropyStr, baseStr) { |
71 | // Find type of entropy being used (binary, hex, dice etc) | 184 | // Find type of entropy being used (binary, hex, dice etc) |
72 | var base = getBase(rawEntropyStr, baseStr); | 185 | var base = getBase(rawEntropyStr, baseStr); |
73 | // Convert dice to base6 entropy (ie 1-6 to 0-5) | 186 | // Convert dice to base6 entropy (ie 1-6 to 0-5) |
74 | // This is done by changing all 6s to 0s | 187 | // This is done by changing all 6s to 0s |
75 | if (base.str == "dice") { | 188 | if (base.str == "dice") { |
76 | var newParts = []; | 189 | var newEvents = []; |
77 | var newInts = []; | 190 | for (var i=0; i<base.events.length; i++) { |
78 | for (var i=0; i<base.parts.length; i++) { | 191 | var c = base.events[i]; |
79 | var c = base.parts[i]; | ||
80 | if ("12345".indexOf(c) > -1) { | 192 | if ("12345".indexOf(c) > -1) { |
81 | newParts[i] = base.parts[i]; | 193 | newEvents[i] = base.events[i]; |
82 | newInts[i] = base.ints[i]; | ||
83 | } | 194 | } |
84 | else { | 195 | else { |
85 | newParts[i] = "0"; | 196 | newEvents[i] = "0"; |
86 | newInts[i] = 0; | ||
87 | } | 197 | } |
88 | } | 198 | } |
89 | base.str = "base 6 (dice)"; | 199 | base.str = "base 6 (dice)"; |
90 | base.ints = newInts; | 200 | base.events = newEvents; |
91 | base.parts = newParts; | ||
92 | base.matcher = matchers.base6; | 201 | base.matcher = matchers.base6; |
93 | } | 202 | } |
94 | // Detect empty entropy | 203 | // Detect empty entropy |
95 | if (base.parts.length == 0) { | 204 | if (base.events.length == 0) { |
96 | return { | 205 | return { |
97 | binaryStr: "", | 206 | binaryStr: "", |
98 | cleanStr: "", | 207 | cleanStr: "", |
@@ -100,44 +209,23 @@ window.Entropy = new (function() { | |||
100 | base: base, | 209 | base: base, |
101 | }; | 210 | }; |
102 | } | 211 | } |
103 | // Convert base.ints to BigInteger. | 212 | // Convert entropy events to binary |
104 | // Due to using unusual bases, eg cards of base52, this is not as simple as | 213 | var entropyBin = base.events.map(function(e) { |
105 | // using BigInteger.parse() | 214 | return eventBits[base.str][e.toLowerCase()]; |
106 | var entropyInt = libs.BigInteger.BigInteger.ZERO; | 215 | }).join(""); |
107 | for (var i=base.ints.length-1; i>=0; i--) { | 216 | // Get average bits per event |
108 | var thisInt = libs.BigInteger.BigInteger.parse(base.ints[i]); | 217 | // which may be adjusted for bias if log2(base) is fractional |
109 | var power = (base.ints.length - 1) - i; | 218 | var bitsPerEvent = base.bitsPerEvent; |
110 | var additionalEntropy = libs.BigInteger.BigInteger.parse(base.asInt).pow(power).multiply(thisInt); | ||
111 | entropyInt = entropyInt.add(additionalEntropy); | ||
112 | } | ||
113 | // Convert entropy to binary | ||
114 | var entropyBin = entropyInt.toString(2); | ||
115 | // If the first integer is small, it must be padded with zeros. | ||
116 | // Otherwise the chance of the first bit being 1 is 100%, which is | ||
117 | // obviously incorrect. | ||
118 | // This is not perfect for non-2^n bases. | ||
119 | var expectedBits = Math.floor(base.parts.length * Math.log2(base.asInt)); | ||
120 | while (entropyBin.length < expectedBits) { | ||
121 | entropyBin = "0" + entropyBin; | ||
122 | } | ||
123 | // Calculate the number of bits per event | ||
124 | var bitsPerEvent = Math.log2(base.asInt); | ||
125 | // Cards binary must be handled differently, since they're not replaced | ||
126 | if (base.asInt == 52) { | ||
127 | var cardEntropy = processCardEntropy(base.parts); | ||
128 | entropyBin = cardEntropy.binaryStr; | ||
129 | bitsPerEvent = cardEntropy.bitsPerEvent; | ||
130 | } | ||
131 | // Supply a 'filtered' entropy string for display purposes | 219 | // Supply a 'filtered' entropy string for display purposes |
132 | var entropyClean = base.parts.join(""); | 220 | var entropyClean = base.events.join(""); |
133 | var entropyHtml = base.parts.join(""); | 221 | var entropyHtml = base.events.join(""); |
134 | if (base.asInt == 52) { | 222 | if (base.asInt == 52) { |
135 | entropyClean = base.parts.join(" ").toUpperCase(); | 223 | entropyClean = base.events.join(" ").toUpperCase(); |
136 | entropyClean = entropyClean.replace(/C/g, "\u2663"); | 224 | entropyClean = entropyClean.replace(/C/g, "\u2663"); |
137 | entropyClean = entropyClean.replace(/D/g, "\u2666"); | 225 | entropyClean = entropyClean.replace(/D/g, "\u2666"); |
138 | entropyClean = entropyClean.replace(/H/g, "\u2665"); | 226 | entropyClean = entropyClean.replace(/H/g, "\u2665"); |
139 | entropyClean = entropyClean.replace(/S/g, "\u2660"); | 227 | entropyClean = entropyClean.replace(/S/g, "\u2660"); |
140 | entropyHtml = base.parts.join(" ").toUpperCase(); | 228 | entropyHtml = base.events.join(" ").toUpperCase(); |
141 | entropyHtml = entropyHtml.replace(/C/g, "<span class='card-suit club'>\u2663</span>"); | 229 | entropyHtml = entropyHtml.replace(/C/g, "<span class='card-suit club'>\u2663</span>"); |
142 | entropyHtml = entropyHtml.replace(/D/g, "<span class='card-suit diamond'>\u2666</span>"); | 230 | entropyHtml = entropyHtml.replace(/D/g, "<span class='card-suit diamond'>\u2666</span>"); |
143 | entropyHtml = entropyHtml.replace(/H/g, "<span class='card-suit heart'>\u2665</span>"); | 231 | entropyHtml = entropyHtml.replace(/H/g, "<span class='card-suit heart'>\u2665</span>"); |
@@ -154,18 +242,6 @@ window.Entropy = new (function() { | |||
154 | return e; | 242 | return e; |
155 | } | 243 | } |
156 | 244 | ||
157 | function getSortedDeck() { | ||
158 | var s = []; | ||
159 | var suits = "CDHS"; | ||
160 | var values = "A23456789TJQK"; | ||
161 | for (var i=0; i<suits.length; i++) { | ||
162 | for (var j=0; j<values.length; j++) { | ||
163 | s.push(values[j]+suits[i]); | ||
164 | } | ||
165 | } | ||
166 | return s; | ||
167 | } | ||
168 | |||
169 | function getBase(str, baseStr) { | 245 | function getBase(str, baseStr) { |
170 | // Need to get the lowest base for the supplied entropy. | 246 | // Need to get the lowest base for the supplied entropy. |
171 | // This prevents interpreting, say, dice rolls as hexadecimal. | 247 | // This prevents interpreting, say, dice rolls as hexadecimal. |
@@ -177,20 +253,21 @@ window.Entropy = new (function() { | |||
177 | var ints = binaryMatches.map(function(i) { return parseInt(i, 2) }); | 253 | var ints = binaryMatches.map(function(i) { return parseInt(i, 2) }); |
178 | return { | 254 | return { |
179 | ints: ints, | 255 | ints: ints, |
180 | parts: binaryMatches, | 256 | events: binaryMatches, |
181 | matcher: matchers.binary, | 257 | matcher: matchers.binary, |
182 | asInt: 2, | 258 | asInt: 2, |
259 | bitsPerEvent: 1, | ||
183 | str: "binary", | 260 | str: "binary", |
184 | } | 261 | } |
185 | } | 262 | } |
186 | var cardMatches = matchers.card(str); | 263 | var cardMatches = matchers.card(str); |
187 | if ((cardMatches.length >= hexMatches.length / 2 && autodetect) || baseStr === "card") { | 264 | if ((cardMatches.length >= hexMatches.length / 2 && autodetect) || baseStr === "card") { |
188 | var ints = convertCardsToInts(cardMatches); | ||
189 | return { | 265 | return { |
190 | ints: ints, | 266 | ints: ints, |
191 | parts: cardMatches, | 267 | events: cardMatches, |
192 | matcher: matchers.card, | 268 | matcher: matchers.card, |
193 | asInt: 52, | 269 | asInt: 52, |
270 | bitsPerEvent: (32*5 + 16*4 + 4*2) / 52, // see cardBits | ||
194 | str: "card", | 271 | str: "card", |
195 | } | 272 | } |
196 | } | 273 | } |
@@ -199,9 +276,10 @@ window.Entropy = new (function() { | |||
199 | var ints = diceMatches.map(function(i) { return parseInt(i) }); | 276 | var ints = diceMatches.map(function(i) { return parseInt(i) }); |
200 | return { | 277 | return { |
201 | ints: ints, | 278 | ints: ints, |
202 | parts: diceMatches, | 279 | events: diceMatches, |
203 | matcher: matchers.dice, | 280 | matcher: matchers.dice, |
204 | asInt: 6, | 281 | asInt: 6, |
282 | bitsPerEvent: (4*2 + 2*1) / 6, // see diceBits | ||
205 | str: "dice", | 283 | str: "dice", |
206 | } | 284 | } |
207 | } | 285 | } |
@@ -210,9 +288,10 @@ window.Entropy = new (function() { | |||
210 | var ints = base6Matches.map(function(i) { return parseInt(i) }); | 288 | var ints = base6Matches.map(function(i) { return parseInt(i) }); |
211 | return { | 289 | return { |
212 | ints: ints, | 290 | ints: ints, |
213 | parts: base6Matches, | 291 | events: base6Matches, |
214 | matcher: matchers.base6, | 292 | matcher: matchers.base6, |
215 | asInt: 6, | 293 | asInt: 6, |
294 | bitsPerEvent: (4*2 + 2*1) / 6, // see diceBits | ||
216 | str: "base 6", | 295 | str: "base 6", |
217 | } | 296 | } |
218 | } | 297 | } |
@@ -221,126 +300,22 @@ window.Entropy = new (function() { | |||
221 | var ints = base10Matches.map(function(i) { return parseInt(i) }); | 300 | var ints = base10Matches.map(function(i) { return parseInt(i) }); |
222 | return { | 301 | return { |
223 | ints: ints, | 302 | ints: ints, |
224 | parts: base10Matches, | 303 | events: base10Matches, |
225 | matcher: matchers.base10, | 304 | matcher: matchers.base10, |
226 | asInt: 10, | 305 | asInt: 10, |
306 | bitsPerEvent: (8*3 + 2*1) / 10, // see b10Bits | ||
227 | str: "base 10", | 307 | str: "base 10", |
228 | } | 308 | } |
229 | } | 309 | } |
230 | var ints = hexMatches.map(function(i) { return parseInt(i, 16) }); | 310 | var ints = hexMatches.map(function(i) { return parseInt(i, 16) }); |
231 | return { | 311 | return { |
232 | ints: ints, | 312 | ints: ints, |
233 | parts: hexMatches, | 313 | events: hexMatches, |
234 | matcher: matchers.hex, | 314 | matcher: matchers.hex, |
235 | asInt: 16, | 315 | asInt: 16, |
316 | bitsPerEvent: 4, | ||
236 | str: "hexadecimal", | 317 | str: "hexadecimal", |
237 | } | 318 | } |
238 | } | 319 | } |
239 | 320 | ||
240 | // Assume cards are NOT replaced. | ||
241 | // Additional entropy decreases as more cards are used. This means | ||
242 | // total possible entropy is measured using n!, not base^n. | ||
243 | // eg the second last card can be only one of two, not one of fifty two | ||
244 | // so the added entropy for that card is only one bit at most | ||
245 | function processCardEntropy(cards) { | ||
246 | // Track how many instances of each card have been used, and thus | ||
247 | // how many decks are in use. | ||
248 | var cardCounts = {}; | ||
249 | var numberOfDecks = 0; | ||
250 | // Work out number of decks by max(duplicates) | ||
251 | for (var i=0; i<cards.length; i++) { | ||
252 | // Get the card that was drawn | ||
253 | var cardLower = cards[i]; | ||
254 | var card = cardLower.toUpperCase(); | ||
255 | // Initialize the count for this card if needed | ||
256 | if (!(card in cardCounts)) { | ||
257 | cardCounts[card] = 0; | ||
258 | } | ||
259 | cardCounts[card] += 1; | ||
260 | // See if this is max(duplicates) | ||
261 | if (cardCounts[card] > numberOfDecks) { | ||
262 | numberOfDecks = cardCounts[card]; | ||
263 | } | ||
264 | } | ||
265 | // Work out the total number of bits for this many decks | ||
266 | // See http://crypto.stackexchange.com/q/41886 | ||
267 | var gainedBits = 0; | ||
268 | // Equivalent of Math.log2(factorial(52*numberOfDecks)) | ||
269 | // which becomes infinity for numberOfDecks > 4 | ||
270 | for (var i=1; i<=52*numberOfDecks; i++) { | ||
271 | gainedBits = gainedBits + Math.log2(i); | ||
272 | } | ||
273 | var lostBits = 52 * Math.log2(factorial(numberOfDecks)); | ||
274 | var maxBits = gainedBits - lostBits; | ||
275 | // Convert the drawn cards to a binary representation. | ||
276 | // The exact technique for doing this is unclear. | ||
277 | // See | ||
278 | // http://crypto.stackexchange.com/a/41896 | ||
279 | // "I even doubt that this is well defined (only the average entropy | ||
280 | // is, I believe)." | ||
281 | // See | ||
282 | // https://github.com/iancoleman/bip39/issues/33#issuecomment-263021856 | ||
283 | // "The binary representation can be the first log(permutations,2) bits | ||
284 | // of the sha-2 hash of the normalized deck string." | ||
285 | // | ||
286 | // In this specific implementation, the first N bits of the hash of the | ||
287 | // normalized cards string is being used. Uppercase, no spaces; eg | ||
288 | // sha256("AH8DQSTC2H") | ||
289 | var totalCards = numberOfDecks * 52; | ||
290 | var percentUsed = cards.length / totalCards; | ||
291 | // Calculate the average number of bits of entropy for the number of | ||
292 | // cards drawn. | ||
293 | var numberOfBits = Math.floor(maxBits * percentUsed); | ||
294 | // Create a normalized string of the selected cards | ||
295 | var normalizedCards = cards.join("").toUpperCase(); | ||
296 | // Convert to binary using the SHA256 hash of the normalized cards. | ||
297 | // If the number of bits is more than 256, multiple hashes | ||
298 | // are used until the required number of bits is reached. | ||
299 | var entropyBin = ""; | ||
300 | var iterations = 0; | ||
301 | while (entropyBin.length < numberOfBits) { | ||
302 | var hashedCards = sjcl.hash.sha256.hash(normalizedCards + ":" + iterations); | ||
303 | var hashHex = sjcl.codec.hex.fromBits(hashedCards); | ||
304 | for (var i=0; i<hashHex.length; i++) { | ||
305 | var decimal = parseInt(hashHex[i], 16); | ||
306 | var binary = decimal.toString(2); | ||
307 | while (binary.length < 4) { | ||
308 | binary = "0" + binary; | ||
309 | } | ||
310 | entropyBin = entropyBin + binary; | ||
311 | } | ||
312 | iterations = iterations + 1; | ||
313 | } | ||
314 | // Truncate to the appropriate number of bits. | ||
315 | entropyBin = entropyBin.substring(0, numberOfBits); | ||
316 | // Get the number of bits per event | ||
317 | bitsPerEvent = maxBits / totalCards; | ||
318 | return { | ||
319 | binaryStr: entropyBin, | ||
320 | bitsPerEvent: bitsPerEvent, | ||
321 | } | ||
322 | } | ||
323 | |||
324 | // Polyfill for Math.log2 | ||
325 | // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2#Polyfill | ||
326 | Math.log2 = Math.log2 || function(x) { | ||
327 | // The polyfill isn't good enough because of the poor accuracy of | ||
328 | // Math.LOG2E | ||
329 | // log2(8) gave 2.9999999999999996 which when floored causes issues. | ||
330 | // So instead use the BigInteger library to get it right. | ||
331 | return libs.BigInteger.BigInteger.log(x) / libs.BigInteger.BigInteger.log(2); | ||
332 | }; | ||
333 | |||
334 | // Depends on BigInteger | ||
335 | function factorial(n) { | ||
336 | if (n == 0) { | ||
337 | return 1; | ||
338 | } | ||
339 | f = libs.BigInteger.BigInteger.ONE; | ||
340 | for (var i=1; i<=n; i++) { | ||
341 | f = f.multiply(new libs.BigInteger.BigInteger(i)); | ||
342 | } | ||
343 | return f; | ||
344 | } | ||
345 | |||
346 | })(); | 321 | })(); |
diff --git a/src/js/index.js b/src/js/index.js index e959c58..114f74a 100644 --- a/src/js/index.js +++ b/src/js/index.js | |||
@@ -1737,7 +1737,7 @@ | |||
1737 | var numberOfBits = entropy.binaryStr.length; | 1737 | var numberOfBits = entropy.binaryStr.length; |
1738 | var timeToCrack = "unknown"; | 1738 | var timeToCrack = "unknown"; |
1739 | try { | 1739 | try { |
1740 | var z = libs.zxcvbn(entropy.base.parts.join("")); | 1740 | var z = libs.zxcvbn(entropy.base.events.join("")); |
1741 | timeToCrack = z.crack_times_display.offline_fast_hashing_1e10_per_second; | 1741 | timeToCrack = z.crack_times_display.offline_fast_hashing_1e10_per_second; |
1742 | if (z.feedback.warning != "") { | 1742 | if (z.feedback.warning != "") { |
1743 | timeToCrack = timeToCrack + " - " + z.feedback.warning; | 1743 | timeToCrack = timeToCrack + " - " + z.feedback.warning; |
@@ -1756,7 +1756,7 @@ | |||
1756 | DOM.entropyFiltered.html(entropy.cleanHtml); | 1756 | DOM.entropyFiltered.html(entropy.cleanHtml); |
1757 | DOM.entropyType.text(entropyTypeStr); | 1757 | DOM.entropyType.text(entropyTypeStr); |
1758 | DOM.entropyCrackTime.text(timeToCrack); | 1758 | DOM.entropyCrackTime.text(timeToCrack); |
1759 | DOM.entropyEventCount.text(entropy.base.ints.length); | 1759 | DOM.entropyEventCount.text(entropy.base.events.length); |
1760 | DOM.entropyBits.text(numberOfBits); | 1760 | DOM.entropyBits.text(numberOfBits); |
1761 | DOM.entropyWordCount.text(wordCount); | 1761 | DOM.entropyWordCount.text(wordCount); |
1762 | DOM.entropyBinary.text(spacedBinaryStr); | 1762 | DOM.entropyBinary.text(spacedBinaryStr); |
@@ -1781,8 +1781,8 @@ | |||
1781 | // Detect duplicates | 1781 | // Detect duplicates |
1782 | var dupes = []; | 1782 | var dupes = []; |
1783 | var dupeTracker = {}; | 1783 | var dupeTracker = {}; |
1784 | for (var i=0; i<entropy.base.parts.length; i++) { | 1784 | for (var i=0; i<entropy.base.events.length; i++) { |
1785 | var card = entropy.base.parts[i]; | 1785 | var card = entropy.base.events[i]; |
1786 | var cardUpper = card.toUpperCase(); | 1786 | var cardUpper = card.toUpperCase(); |
1787 | if (cardUpper in dupeTracker) { | 1787 | if (cardUpper in dupeTracker) { |
1788 | dupes.push(card); | 1788 | dupes.push(card); |
@@ -1898,6 +1898,7 @@ | |||
1898 | || (name == "ESN - Ethersocial Network") | 1898 | || (name == "ESN - Ethersocial Network") |
1899 | || (name == "VET - VeChain") | 1899 | || (name == "VET - VeChain") |
1900 | || (name == "ERE - EtherCore") | 1900 | || (name == "ERE - EtherCore") |
1901 | || (name == "BSC - Binance Smart Chain") | ||
1901 | } | 1902 | } |
1902 | 1903 | ||
1903 | function networkIsRsk() { | 1904 | function networkIsRsk() { |
@@ -2244,6 +2245,13 @@ | |||
2244 | }, | 2245 | }, |
2245 | }, | 2246 | }, |
2246 | { | 2247 | { |
2248 | name: "BSC - Binance Smart Chain", | ||
2249 | onSelect: function() { | ||
2250 | network = libs.bitcoin.networks.bitcoin; | ||
2251 | setHdCoin(60); | ||
2252 | }, | ||
2253 | }, | ||
2254 | { | ||
2247 | name: "BSV - BitcoinSV", | 2255 | name: "BSV - BitcoinSV", |
2248 | onSelect: function() { | 2256 | onSelect: function() { |
2249 | network = libs.bitcoin.networks.bitcoinsv; | 2257 | network = libs.bitcoin.networks.bitcoinsv; |