PageSourceSearch

https://ariareserveluxuryresidences.com/wire-botguard.js

js ariareserveluxuryresidences.com collected 2026-09-29 07:11:38 UTC 4,749 bytes, 115 lines download raw bytes

1/*
2 * WIRE Miami Bot Form Guard (wire-botguard.js)
3 * Stage 1 anti spam for the lead capture forms. Self contained.
4 * Add AFTER the kit scripts, before the closing body tag.
5 * It does NOT modify the kit. It intercepts the form submit in the capture
6 * phase, so it covers both the legacy client path and the Option B handler
7 * path without editing wire-tracking.js, wire-lead-capture.js, or
8 * wire-contact-form.js.
9 *
10 * Three independent checks. A submission is blocked if ANY fires:
11 *   1. Honeypot: a hidden field humans never see. If filled, it is a bot.
12 *   2. Timing: a submit under MIN_SECONDS from first interaction is a bot.
13 *      No interaction at all does NOT block by itself (autofill safety).
14 *   3. Gibberish name: triggers ONLY on an absurdly long name token
15 *      (over MAX_TOKEN_LEN chars) plus one corroborating signal. Conservative
16 *      by design. Every block is logged so false positives surface.
17 *
18 * A blocked submission is stopped before the kit handler runs, so it reaches
19 * neither FUB, nor the CRM, nor the Google Ads conversion, and unlocks nothing.
20 * Blocks are counted on window.__wireBotBlocks and logged to console for audit.
21 */
22(function(){
23  'use strict';
24  var MIN_SECONDS = 3;
25  var MAX_TOKEN_LEN = 18;
26  var FORM_SELECTOR = '#inquiry-form, #wire-gate-form';
27  var HP_NAME = 'wire_url';
28  var HP_CLASS = 'wire-hp';
29  window.__wireBotBlocks = window.__wireBotBlocks || 0;
30  function ensureHoneypot(form){
31    if(!form || form.querySelector('.' + HP_CLASS)) return;
32    var hp = document.createElement('input');
33    hp.type = 'text';
34    hp.name = HP_NAME;
35    hp.className = HP_CLASS;
36    hp.tabIndex = -1;
37    hp.setAttribute('autocomplete', 'off');
38    hp.setAttribute('aria-hidden', 'true');
39    hp.style.cssText = 'position:absolute;left:-9999px;top:-9999px;width:1px;height:1px;opacity:0;pointer-events:none;';
40    form.appendChild(hp);
41  }
42  function onInteract(e){
43    var el = e.target;
44    var form = el && el.closest ? el.closest(FORM_SELECTOR) : null;
45    if(!form) return;
46    ensureHoneypot(form);
47    if(!form.dataset.wireFi) form.dataset.wireFi = String(Date.now());
48  }
49  function getName(form){
50    var single = form.querySelector('#wire-g-name, [name="name"]');
51    if(single && single.value) return single.value;
52    var fn = form.querySelector('#first-name, [name="firstName"]');
53    var ln = form.querySelector('#last-name, [name="lastName"]');
54    return (((fn && fn.value) || '') + ' ' + ((ln && ln.value) || '')).trim();
55  }
56  function isGibberish(name){
57    if(!name) return false;
58    var clean = name.trim();
59    if(clean.length < 6) return false;
60    var tokens = clean.split(/\s+/);
61    var hasLongToken = tokens.some(function(t){ return t.length > MAX_TOKEN_LEN; });
62    if(!hasLongToken) return false;
63    var corroborating = 0;
64    if(/[bcdfghjklmnpqrstvwxz]{5,}/i.test(clean)) corroborating++;
65    var nonInitialUpper = 0;
66    tokens.forEach(function(t){
67      for(var i = 1; i < t.length; i++){
68        var c = t.charAt(i);
69        if(c >= 'A' && c <= 'Z') nonInitialUpper++;
70      }
71    });
72    if(nonInitialUpper >= 3) corroborating++;
73    var letters = clean.replace(/[^a-z]/gi, '');
74    if(letters.length){
75      var vowels = (letters.match(/[aeiou]/gi) || []).length;
76      if(vowels / letters.length < 0.20) corroborating++;
77    }
78    return corroborating >= 1;
79  }
80  function blockReason(form){
81    var hp = form.querySelector('.' + HP_CLASS);
82    if(hp && hp.value.trim() !== '') return 'honeypot';
83    var fi = form.dataset.wireFi ? Number(form.dataset.wireFi) : null;
84    if(fi !== null && (Date.now() - fi) < (MIN_SECONDS * 1000)) return 'too_fast';
85    if(isGibberish(getName(form))) return 'gibberish_name';
86    return null;
87  }
88  document.addEventListener('focusin', onInteract, true);
89  document.addEventListener('input', onInteract, true);
90  document.addEventListener('submit', function(e){
91    var form = e.target;
92    if(!form || !form.matches || !form.matches(FORM_SELECTOR)) return;
93    var reason = blockReason(form);
94    if(!reason) return;
95    e.preventDefault();
96    e.stopImmediatePropagation();
97    window.__wireBotBlocks++;
98    try{
99      var em = form.querySelector('#email, #wire-g-email, [name="email"]');
100      console.warn('[WIRE botguard] blocked submission', {
101        reason: reason,
102        form: form.id || '(unnamed)',
103        name: getName(form),
104        email: em ? em.value : '',
105        blocks: window.__wireBotBlocks
106      });
107    }catch(err){}
108  }, true);
109  function init(){
110    var forms = document.querySelectorAll(FORM_SELECTOR);
111    for(var i = 0; i < forms.length; i++) ensureHoneypot(forms[i]);
112  }
113  if(document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
114  else init();
115})();

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.