1(function () { 2 var UNLOCK_MAX_AGE = 600; // 10 minutes, in seconds 3 var LOADER_MIN_MS = 400; // avoid a loader flash when media is already cached 4 var LOADER_MAX_WAIT_MS = 1500; // iframes/images typically started loading (hidden) at page load, 5 // so 'load' usually already fired before we could listen for it â 6 // keep this short so the fallback isn't a long false wait 7 8 function fnv1a(str) { 9 var hash = 0x811c9dc5; 10 for (var i = 0; i < str.length; i++) { 11 hash ^= str.charCodeAt(i); 12 hash = Math.imul(hash, 0x01000193) >>> 0; 13 } 14 return hash.toString(16); 15 } 16 17 function setCookie(name, value, maxAgeSeconds) { 18 document.cookie = name + '=' + value + '; max-age=' + maxAgeSeconds + '; path=/; SameSite=Lax'; 19 } 20 21 function getCookie(name) { 22 var match = document.cookie.match('(?:^|; )' + name + '=([^;]*)'); 23 return match ? match[1] : null; 24 } 25 26 function waitForMedia(content) { 27 var media = content.querySelectorAll('img, iframe, video'); 28 if (!media.length) { 29 return Promise.resolve(); 30 } 31 32 return Promise.all( 33 Array.prototype.map.call(media, function (el) { 34 if (el.tagName === 'IMG' && el.complete) { 35 return Promise.resolve(); 36 } 37 return new Promise(function (resolve) { 38 el.addEventListener('load', resolve, { once: true }); 39 el.addEventListener('error', resolve, { once: true }); 40 }); 41 }) 42 ); 43 } 44 45 function revealContent(el) { 46 var loader = el.querySelector('.pex-pp__loader'); 47 var content = el.querySelector('.pex-pp__content'); 48 49 loader.hidden = false; 50 51 var mediaReady = Promise.race([ 52 waitForMedia(content), 53 new Promise(function (resolve) { 54 setTimeout(resolve, LOADER_MAX_WAIT_MS); 55 }) 56 ]); 57 var minDelay = new Promise(function (resolve) { 58 setTimeout(resolve, LOADER_MIN_MS); 59 }); 60 61 Promise.all([mediaReady, minDelay]).then(function () { 62 loader.hidden = true; 63 content.hidden = false; 64 }); 65 } 66 67 var hiddenModules = []; 68 69 function restoreModules() { 70 hiddenModules.forEach(function (mod) { 71 mod.style.display = ''; 72 }); 73 hiddenModules = []; 74 } 75 76 function unlock(el, rememberCookie) { 77 el.querySelector('.pex-pp__gate').hidden = true; 78 revealContent(el); 79 restoreModules(); 80 if (rememberCookie) { 81 setCookie('pex-pp-unlocked-' + el.id, '1', UNLOCK_MAX_AGE); 82 } 83 } 84 85 function hideOtherModules(gates) { 86 var keep = [];
87 gates.forEach(function (el) { 88 var mod = el.closest('.module'); 89 if (mod) { 90 keep.push(mod); 91 } 92 }); 93 if (!keep.length) { 94 return; 95 } 96 document.querySelectorAll('.module').forEach(function (mod) { 97 if (keep.indexOf(mod) === -1) { 98 mod.style.display = 'none'; 99 hiddenModules.push(mod); 100 } 101 }); 102 } 103 104 document.addEventListener('DOMContentLoaded', function () { 105 var gates = document.querySelectorAll('.pex-password-protected'); 106 107 hideOtherModules(gates); 108 109 gates.forEach(function (el) { 110 if (getCookie('pex-pp-unlocked-' + el.id) === '1') { 111 unlock(el, false); 112 return; 113 } 114 115 var form = el.querySelector('.pex-pp__form'); 116 var input = el.querySelector('.pex-pp__input'); 117 var error = el.querySelector('.pex-pp__error'); 118 119 form.addEventListener('submit', function (evt) { 120 evt.preventDefault(); 121 122 if (fnv1a(input.value) === el.dataset.hash) { 123 error.hidden = true; 124 unlock(el, true); 125 } else { 126 error.hidden = false; 127 input.value = ''; 128 input.focus(); 129 } 130 }); 131 }); 132 }); 133})();
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.