1(function () { 2 function waitForMkto(cb) { 3 if (window.MktoForms2) { 4 cb(); 5 } else { 6 setTimeout(() => waitForMkto(cb), 200); 7 } 8 } 9 10 waitForMkto(function () { 11 MktoForms2.whenReady(function (form) { 12 const formEl = form.getFormElem()[0]; 13 14 /* ------------------------------- Check for existing captcha field -------------------------------- */ 15 const captchaInput = formEl.querySelector('input[name="userMathAnswer"]'); 16 17 if (!captchaInput) { 18 console.log('No captcha field found in form - skipping captcha implementation'); 19 return; 20 } 21 22 console.log('Captcha field found - implementing validation'); 23 24 /* ------------------------------- State -------------------------------- */ 25 const loadTime = Date.now(); 26 let interacted = false; 27 28 ["mousemove", "keydown", "touchstart", "scroll"].forEach(evt => { 29 document.addEventListener(evt, () => (interacted = true), { once: true }); 30 }); 31 32 /* ------------------------------- Honeypot -------------------------------- */ 33 const honeypot = document.createElement("input"); 34 honeypot.type = "text"; 35 honeypot.name = "Company_Website"; 36 honeypot.style.display = "none"; 37 formEl.appendChild(honeypot); 38 39 /* ------------------------------- CAPTCHA values -------------------------------- */ 40 const a = Math.floor(Math.random() * 10) + 1; 41 const b = Math.floor(Math.random() * 10) + 1; 42 const answer = a + b; 43 44 /* ------------------------------- Update existing captcha field -------------------------------- */ 45 // Find the label for the captcha field 46 const captchaLabel = formEl.querySelector('label[for="userMathAnswer"]') || 47 captchaInput.closest('.mktoFormRow').querySelector('.mktoLabel'); 48 49 if (captchaLabel) { 50 // Clear existing content 51 captchaLabel.innerHTML = ''; 52 53 // Create asterix element 54 const asterix = document.createElement("div"); 55 asterix.className = "mktoAsterix"; 56 asterix.style.display = "block"; 57 asterix.textContent = "*"; 58 59 // Create strong element 60 const strong = document.createElement("strong"); 61 62 // Create span element 63 const span = document.createElement("span"); 64 span.textContent = `Please verify that you are human. Solve ${a}+${b}`; 65 66 // Build the structure 67 strong.appendChild(span); 68 captchaLabel.appendChild(asterix); 69 captchaLabel.appendChild(strong); 70 } 71 72 // Add error message after the captcha input 73 const errorMsg = document.createElement("div"); 74 errorMsg.className = "captcha-error"; 75 errorMsg.textContent = "Invalid Answer"; 76 errorMsg.style.display = "none"; 77 78 // Insert error message after the captcha input's wrapper 79 const captchaWrapper = captchaInput.closest('.mktoFieldWrap') || captchaInput.parentNode; 80 captchaWrapper.appendChild(errorMsg); 81 82 // Add input restriction - max 3 digits only 83 captchaInput.addEventListener('input', function(e) { 84 // Remove non-digit characters 85 this.value = this.value.replace(/\D/g, ''); 86 // Limit to 3 digits 87 if (this.value.length > 3) { 88 this.value = this.value.slice(0, 3); 89 } 90 }); 91 92 /* ------------------------------- Helpers -------------------------------- */ 93 function showError() { 94 captchaInput.classList.add("mktoInvalid"); 95 errorMsg.style.display = "block"; 96 } 97 98 function hideError() { 99 captchaInput.classList.remove("mktoInvalid"); 100 errorMsg.style.display = "none"; 101 } 102 103 /* ------------------------------- Validation -------------------------------- */ 104 form.onValidate(function () { 105 106 if (honeypot.value.trim() !== "") { 107 form.submittable(false); 108 return; 109 } 110 111 if ((Date.now() - loadTime) / 1000 < 3) { 112 form.submittable(false); 113 return; 114 } 115 116 if (!interacted) { 117 form.submittable(false); 118 return; 119 } 120 121 if (parseInt(captchaInput.value, 10) !== answer) { 122 showError(); 123 form.submittable(false); 124 return; 125 } else { 126 hideError(); 127 } 128 129 form.submittable(true); 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.