1 2/** 3 * Required JavaScript for challenge/response spam protection 4 */ 5document.addEventListener('DOMContentLoaded', () => 6{ 7 [...document.querySelectorAll('[id$="-cr-field"]')].forEach(element => 8 { 9 let [expiration,challenge,delay] = atob(element.value).split('|'); 10 11 if (delay === undefined) { 12 // The CR field has already been submitted by the client, but server side validation may have failed 13 return; 14 } 15 16 setTimeout(() => 17 { 18 element.value = btoa(expiration + '|' + challenge.replace(/[a-z]/gi, char => 19 { 20 return String.fromCharCode( char.charCodeAt(0) + ( char.toUpperCase() <= 'M' ? 13 : -13 ) )/* https://stackoverflow.com/a/14553231 */ 21 })) 22 }, 1e3 * delay) 23 }) 24}); 25/* appear.min.js 1.0.3 */ 26appear=function(){"use strict";function e(){var e=window.scrollY||window.pageYOffset;null!=n&&(o.velocity=e-n,o.delta=o.velocity>=0?o.velocity:-1*o.velocity),n=e,i&&clearTimeout(i),i=setTimeout(function(){n=null},30)}function t(e,t){var n=e.getBoundingClientRect();return n.top+n.height>=0&&n.left+n.width>=0&&n.bottom-n.height<=(window.innerHeight||document.documentElement.clientHeight)+t&&n.right-n.width<=(window.innerWidth||document.documentElement.clientWidth)+t}var n=null,i=0,o={};return addEventListener("scroll",e,!1),function(e){return function(e){function n(e,t){return function(){var n=this,i=arguments;clearTimeout(l),l=setTimeout(function(){e.apply(n,i)},t)}}function i(){o.delta<y.delta.speed&&(s||(s=!0,d(),setTimeout(function(){s=!1},y.delta.timeout))),n(function(){d()},y.debounce)()}function r(){d(),addEventListener("scroll",i,!1),addEventListener("resize",i,!1)}function a(){v=[],l&&clearTimeout(l),u()}function u(){removeEventListener("scroll",i,!1),removeEventListener("resize",i,!1)}function d(){f||(v.forEach(function(e,n){e&&t(e,y.bounds)?h[n]&&(h[n]=!1,g++,y.appear&&y.appear(e),y.disappear||y.reappear||(v[n]=null)):(h[n]===!1&&(y.disappear&&y.disappear(e),w++,y.reappear||(v[n]=null)),h[n]=!0)}),y.reappear||y.appear&&(!y.appear||g!==p)||y.disappear&&(!y.disappear||w!==p)||(f=!0,u(),y.done&&y.done()))}function c(){if(!m){m=!0,y.init&&y.init();var e;if(e="function"==typeof y.elements?y.elements():y.elements){p=e.length;for(var t=0;p>t;t+=1)v.push(e[t]),h.push(!0);r()}}}var p,l,s,f,m=!1,v=[],h=[],g=0,w=0,y={};return function(e){e=e||{},y={init:e.init,elements:e.elements,appear:e.appear,disappear:e.disappear,done:e.done,reappear:e.reappear,bounds:e.bounds||0,debounce:e.debounce||50,delta:{speed:e.deltaSpeed||50,timeout:e.deltaTimeout||500}},addEventListener("DOMContentLoaded",c,!1);var t=!1;Function("/*@cc_on return document.documentMode===10@*/")()&&(t=!0);var n="complete"===document.readyState||"loaded"===document.readyState;return t?n&&c():(n||"interactive"===document.readyState)&&c(),{trigger:function(){d()},pause:function(){u()},resume:function(){r()},destroy:function(){a()}}}}()(e)}}(); 27// load namespace 28SV = window.SV || {}; 29 30SV.HoverIntent = (function() { 31 32 // constructor 33 return function(elements, userConfig) { 34 35 // private members 36 37 const defaultOptions = { 38 exitDelay: 400, 39 interval: 100, 40 sensitivity: 7, 41 }; 42 let config = {}; 43 44 let currX, currY, prevX, prevY; 45 let allElems, pollTimer, exitTimer; 46 47 // private methods 48 49 // override default options with user config 50 const extend = function(defaults, userArgs) { 51 for (let i in userArgs) { 52 defaults[i] = userArgs[i]; 53 } 54 55 return defaults; 56 }; 57 58 // update mouse position 59 const mouseTrack = function(ev) { 60 currX = ev.pageX; 61 currY = ev.pageY; 62 }; 63 64 // check if mouse movement has slowed enough to trigger active state 65 const mouseCompare = function(targetElem) { 66 const distX = prevX - currX, distY = prevY - currY; 67 const distance = Math.sqrt(distX*distX + distY*distY); 68 69 if (distance < config.sensitivity) { 70 // if we re-entered an element, cancel delayed exit and clear any active elements immediately 71 clearTimeout(exitTimer); 72 for (let elem of allElems) { 73 if (elem.isActive) { 74 config.onExit(elem); 75 elem.isActive = false; 76 } 77 } 78 79 // trigger hover 80 config.onEnter(targetElem); 81 targetElem.isActive = true; 82 } else {
83 // update previous coordinates and try again later 84 prevX = currX; 85 prevY = currY; 86 pollTimer = setTimeout(function() { 87 mouseCompare(targetElem); 88 }, config.interval); 89 } 90 }; 91 92 const init = function(elements, userConfig) { 93 if (!userConfig || !userConfig.onEnter || !userConfig.onExit) { 94 throw 'onEnter and onExit callbacks must be provided'; 95 } 96 config = extend(defaultOptions, userConfig); 97 allElems = elements; 98 99 for (let elem of allElems) { 100 // holds current element state 101 elem.isActive = false; 102 // keeps track of mouse position 103 elem.addEventListener('mousemove', mouseTrack); 104 105 elem.addEventListener('mouseenter', function(ev) { 106 // set initial entry position 107 prevX = ev.pageX; 108 prevY = ev.pageY; 109 // if this element is already active, cancel exit 110 if (elem.isActive) { 111 clearTimeout(exitTimer); 112 return; 113 } 114 115 // while mouse is over this element, check distance every 100ms 116 pollTimer = setTimeout(function() { 117 mouseCompare(elem); 118 }, config.interval); 119 }); 120 elem.addEventListener('mouseleave', function(ev) { 121 clearTimeout(pollTimer); 122 if (!elem.isActive) 123 return; 124 125 exitTimer = setTimeout(function() { 126 config.onExit(elem); 127 elem.isActive = false; 128 }, config.exitDelay); 129 }); 130 } 131 }; 132 133 init(elements, userConfig); 134 }; 135 136})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.