{try{
var C={)
=0?'track':'trackCustom',nm,{},{eventID:eid})}catch(e){}}
function beacon(body){var s=JSON.stringify(body);try{if(navigator.sendBeacon){navigator.sendBeacon('/t/collect',new Blob([s],{type:'application/json'}));return}}catch(e){}try{fetch('/t/collect',{method:'POST',headers:{'Content-Type':'application/json'},body:s,keepalive:true})}catch(e){}}
function send(type,data){var eid='e'+Date.now().toString(36)+Math.random().toString(36).slice(2,8);firePixel(type,data,eid);beacon({company:C.company,funnelId:C.funnelId,pageId:C.pageId,vid:vid,sid:sid,type:type,data:data||{},source:SRC(),utm:utm(),ref:document.referrer||'',url:location.href,eventId:eid,fbp:cookie('_fbp'),fbc:cookie('_fbc')});return eid}
window.__emfTrack=send;
// expose the funnel's navigation targets so the builder's structured form can advance on the live page
window.__emfNext=C.next||'';window.__emfRoutes=C.routes||{};
function emfPrefill(u,lead){try{var url=new URL(u,location.href);lead=lead||{};if(lead.name&&!url.searchParams.get('name'))url.searchParams.set('name',lead.name);if(lead.email&&!url.searchParams.get('email'))url.searchParams.set('email',lead.email);var cur=new URLSearchParams(location.search);['utm_source','utm_medium','utm_campaign','utm_id','utm_content','utm_term','s'].forEach(function(k){if(cur.get(k)&&!url.searchParams.get(k))url.searchParams.set(k,cur.get(k))});return url.toString()}catch(e){return u}}
// open a booking link as an on-page popup instead of navigating away: Calendly gets its native overlay
// widget (loads their script once); any other scheduler opens in a centered iframe modal.
window.__emfOpenBooking=function(url){try{
if(/calendly\.com/i.test(url)){
var go=function(){try{window.Calendly.initPopupWidget({url:url})}catch(e){location.href=url}};
if(window.Calendly){go();return}
if(!document.querySelector('link[data-emf-cal]')){var l=document.createElement('link');l.rel='stylesheet';l.href='https://assets.calendly.com/assets/external/widget.css';l.setAttribute('data-emf-cal','1');document.head.appendChild(l)}
var s=document.createElement('script');s.src='https://assets.calendly.com/assets/external/widget.js';s.async=true;s.onload=go;s.onerror=function(){location.href=url};document.head.appendChild(s);return;
}
var ov=document.createElement('div');ov.setAttribute('role','dialog');ov.style.cssText='position:fixed;inset:0;background:rgba(0,0,0,.65);z-index:2147483647;display:flex;align-items:center;justify-content:center;padding:18px;box-sizing:border-box';
var fr=document.createElement('iframe');fr.src=url;fr.setAttribute('allow','payment; fullscreen');fr.style.cssText='width:100%;max-width:920px;height:92%;border:0;border-radius:14px;background:#fff;box-shadow:0 20px 60px rgba(0,0,0,.4)';
var x=document.createElement('button');x.setAttribute('aria-label','Close');x.innerHTML='×';x.style.cssText='position:absolute;top:12px;right:18px;font-size:34px;line-height:1;color:#fff;background:none;border:0;cursor:pointer;padding:4px';
var done=function(){try{ov.remove()}catch(e){}};x.onclick=done;ov.addEventListener('click',function(e){if(e.target===ov)done()});
document.addEventListener('keydown',function esc(e){if(e.key==='Escape'){done();document.removeEventListener('keydown',esc)}});
ov.appendChild(fr);ov.appendChild(x);document.body.appendChild(ov);
}catch(e){location.href=url}};
// Opt-in choke point. A multi-page form calls this once per page; we MERGE each step into one lead held in
// sessionStorage and only actually send it (→ submission row, Zapier, Pixel Lead) when the form is FINISHED —
// i.e. this step doesn't continue to another form page. That turns "3 partial leads" into one complete lead
// with everything (name/email/phone + all answers + first-touch attribution).
window.__emfOptin=function(lead){lead=lead||{};try{
var K='emf_lead_'+C.funnelId,acc={};try{acc=JSON.parse(sessionStorage.getItem(K)||'{}')||{}}catch(e){acc={}}
acc.answers=acc.answers||{};
if(lead.answers)for(var k in lead.answers){var av=lead.answers[k];if(av!==''&&av!=null)acc.answers[k]=av}
if(lead.name)acc.name=lead.name;if(lead.email)acc.email=lead.email;if(lead.phone)acc.phone=lead.phone;
if(lead.route!=null&&lead.route!=='')acc.route=lead.route;
if(lead.honeypot)acc.honeypot=lead.honeypot;
if(lead.fillMs!=null)acc.fillMs=lead.fillMs;
// does this step continue to ANOTHER form page? a branch target (lead.route) wins, else the in-order next.
var destId=(lead.route&&C.routeForms&&C.routeForms.hasOwnProperty(lead.route))?lead.route:(C.nextId||'');
var goesToForm=!!(destId&&C.routeForms&&C.routeForms[destId]);
var complete=(C.next&&C.nextExt)||!goesToForm; // external booking next, or no further form → finished
if(complete){try{sessionStorage.removeItem(K)}catch(e){}}
else{try{sessionStorage.setItem(K,JSON.stringify(acc))}catch(e){};return} // partial step — hold it, send nothing yet
var payload={name:acc.name||'',email:acc.email||'',phone:acc.phone||'',answers:acc.answers||{},route:acc.route||'',honeypot:acc.honeypot||'',fillMs:acc.fillMs};
var eid='e'+Date.now().toString(36)+Math.random().toString(36).slice(2,8);firePixel('optin',{},eid);
beacon({company:C.company,funnelId:C.funnelId,pageId:C.pageId,vid:vid,sid:sid,type:'optin',lead:payload,source:SRC(),utm:utm(),ref:document.referrer||'',url:location.href,eventId:eid,fbp:cookie('_fbp'),fbc:cookie('_fbc')});
// external booking destination (Calendly etc.): open it as an on-page popup, or navigate there, with
// name+email prefilled. __emfBooking flags that a booking action took over so page-nav paths stand down.
if(C.next&&C.nextExt&&!window.__emfBooking){window.__emfBooking=1;var bu=emfPrefill(C.next,payload);if(C.nextBookingPopup&&window.__emfOpenBooking){window.__emfOpenBooking(bu)}else{setTimeout(function(){location.href=bu},120)}}
}catch(e){}};
send('view',{newSession:newSession});
// time on page (only while visible)
setInterval(function(){if(document.visibilityState==='visible')send('time',{s:1})},1000);
// scroll depth + full scroll
var maxPct=0,fullSent=false;
addEventListener('scroll',function(){var h=document.documentElement;var pct=Math.min(100,Math.round((h.scrollTop+innerHeight)/h.scrollHeight*100));if(pct>maxPct)maxPct=pct;if(pct>=85&&!fullSent){fullSent=true;send('scroll',{pct:pct,full:true})}},{passive:true});
// clicks on buttons / links
addEventListener('click',function(e){var t=e.target.closest&&e.target.closest('button,a,.vsl,[data-cta]');if(t)send('click',{label:(t.textContent||t.getAttribute('aria-label')||'').trim().slice(0,40)})},true);
// video 50% / 100%
function wireVideo(v){var h50=false,h100=false;v.addEventListener('timeupdate',function(){if(!v.duration)return;var p=v.currentTime/v.duration;if(p>=0.5&&!h50){h50=true;send('vsl',{pct:50})}if(p>=0.99&&!h100){h100=true;send('vsl',{pct:100})}})}
document.querySelectorAll('video').forEach(wireVideo);
new MutationObserver(function(m){m.forEach(function(x){(x.addedNodes||[]).forEach(function(n){if(n.tagName==='VIDEO')wireVideo(n);else if(n.querySelectorAll)n.querySelectorAll('video').forEach(wireVideo)})})}).observe(document.documentElement,{childList:true,subtree:true});
// Read a lead out of ANY form/section, whatever its markup or styling — so a pasted/imported/screenshot
// page's form still captures. Maps fields to name/email/phone by input type + name/placeholder/label.
// a field is a honeypot if it's type=hidden, named like one, or actually hidden from view (CSS/offscreen).
// (We can't use a bare "hon" match — it falsely hits "p-hon-e". Hidden-ness is the reliable bot signal.)
function emfHidden(el){try{var s=getComputedStyle(el);if(s.display==='none'||s.visibility==='hidden'||parseFloat(s.opacity)===0)return true;var r=el.getBoundingClientRect();if((r.left+r.width)<0||(r.top+r.height)<0)return true;return false}catch(e){return false}}
function emfLead(scope){var lead={answers:{}},hp='';
(scope.querySelectorAll('input,select,textarea')||[]).forEach(function(el){
var t=(el.type||'').toLowerCase();if(t==='submit'||t==='button'||t==='reset'||t==='file')return;
var nm=((el.name||'')+' '+(el.id||'')).toLowerCase();
var hint=(nm+' '+(el.placeholder||'')+' '+((el.getAttribute&&el.getAttribute('aria-label'))||'')).toLowerCase();
var val=(el.value||'');
if(t==='hidden'||/honeypot|honey.?pot|do.?not.?fill|leave.?(this|blank)|\bhp\b/.test(nm)||emfHidden(el)){if(val)hp=val;return}
if(t==='checkbox'||t==='radio'){if(el.checked&&el.name)lead.answers[el.name]=el.value||'on';return}
if(!lead.email&&(t==='email'||/e-?mail/.test(hint)))lead.email=val;
else if(!lead.phone&&(t==='tel'||/phone|mobile|\btel\b|whatsapp/.test(hint)))lead.phone=val;
else if(!lead.name&&/name/.test(hint))lead.name=val;
var key=(el.name||el.id||el.placeholder||'').toString().trim();if(key)lead.answers[key]=val;
});
lead.honeypot=hp;return lead;}
function emfHasLead(l){return !!(l&&((l.email&&/.+@.+\..+/.test(l.email))||(l.phone&&l.phone.replace(/\D/g,'').length>=6)))}
function emfAdvance(form){var action=(form&&form.getAttribute&&(form.getAttribute('action')||'').trim())||'';
if(action&&action!=='#'&&!/^javascript:/i.test(action))return false; // let the page's own action run
if(window.__emfBooking)return true; // a booking redirect (with prefill) already took over
if(C.next){setTimeout(function(){location.href=C.nextExt?emfPrefill(C.next,{}):C.next},140);return true}
try{var b=form&&(form.querySelector('[type=submit]')||form.querySelector('button'));if(b){b.disabled=true;b.textContent='\u2713 You\u2019re in \u2014 check your email'}}catch(e){}
return true;}
// 1) builder forms (data-emf-form) and 2) ANY other