{"version":3,"file":"siteMetadata.B93lPyVE.mjs","names":[],"sources":["https:/framerusercontent.com/modules/18ru7IZQg4UoI0wqxfTH/uCheSK2AgqAbTY7DnF3l/siteMetadata.js"],"sourcesContent":["// Generated by Framer (397058d)\nexport default function metadata(params,activeLocale){return{customHTMLBodyEnd:\"<!-- Google Tag Manager (noscript) -->\\n<noscript><iframe src=\\\"https://www.googletagmanager.com/ns.html?id=GTM-P4WCW8M\\\" height=\\\"0\\\" width=\\\"0\\\" style=\\\"display:none;visibility:hidden\\\"></iframe></noscript>\\n<!-- End Google Tag Manager (noscript) -->\\n\\n\\n<div id=\\\"global-call-button\\\" style=\\\"position:fixed;bottom:24px;right:24px;z-index:9999;animation:slideUp 0.4s cubic-bezier(0.25,0.46,0.45,0.94);transition:transform 0.3s ease, opacity 0.3s ease;\\\">\\n  <a href=\\\"tel:7202599962\\\" style=\\\"display:flex;align-items:center;justify-content:center;background:#1a536e;color:#fff;text-decoration:none;padding:16px 32px;border-radius:8px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Inter',sans-serif;font-weight:500;font-size:15px;letter-spacing:-0.01em;box-shadow:0 4px 12px rgba(26,83,110,0.15);transition:all 0.2s cubic-bezier(0.25,0.46,0.45,0.94);border:none;cursor:pointer;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);\\\" onmouseover=\\\"this.style.background='# f18d86';this.style.transform='translateY(-2px)';this.style.boxShadow='0 8px 20px rgba(26,83,110,0.25)'\\\" onmouseout=\\\"this.style.background='#1a536e';this.style.transform='translateY(0)';this.style.boxShadow='0 4px 12px rgba(26,83,110,0.15)'\\\">\\n    <svg width=\\\"16\\\" height=\\\"16\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" style=\\\"margin-right:10px;\\\">\\n      <path d=\\\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\\\" fill=\\\"white\\\"></path>\\n    </svg>\\n    <span class=\\\"btn-text\\\">Call Now</span>\\n  </a>\\n</div>\\n\\n<style>\\n@keyframes slideUp {\\n  from { opacity: 0; transform: translateY(60px); }\\n  to   { opacity: 1; transform: translateY(0); }\\n}\\n\\n#global-call-button a {\\n  min-width: 140px;\\n  padding: 16px 32px;\\n  border-radius: 8px;\\n  justify-content: center;\\n}\\n\\n@media (min-width: 1200px) {\\n  #global-call-button {\\n    bottom: 32px;\\n    right: 32px;\\n  }\\n  #global-call-button a {\\n    padding: 18px 36px;\\n    font-size: 16px;\\n  }\\n}\\n\\n@media (prefers-reduced-motion: reduce) {\\n  #global-call-button {\\n    animation: none;\\n  }\\n  #global-call-button a {\\n    transition: none;\\n  }\\n}\\n\\n#global-call-button a:focus {\\n  outline: 2px solid #1A536E;\\n  outline-offset: 2px;\\n}\\n</style>\\n\\n<script>\\ndocument.addEventListener('DOMContentLoaded', function () {\\n  const callButton = document.getElementById('global-call-button');\\n  callButton.style.opacity = '0';\\n  setTimeout(() => {\\n    callButton.style.opacity = '1';\\n  }, 300);\\n});\\n\\ndocument.getElementById('global-call-button').addEventListener('click', function (e) {\\n  if ('vibrate' in navigator) {\\n    navigator.vibrate(50);\\n  }\\n});\\n\\nif (window.innerWidth > 768) {\\n  let lastScrollTop = 0;\\n  let scrollTimeout;\\n  const callButton = document.getElementById('global-call-button');\\n\\n  window.addEventListener('scroll', function () {\\n    clearTimeout(scrollTimeout);\\n    scrollTimeout = setTimeout(() => {\\n      let scrollTop = window.pageYOffset || document.documentElement.scrollTop;\\n      if (scrollTop > lastScrollTop && scrollTop > 200) {\\n        callButton.style.transform = 'scale(0.85)';\\n        callButton.style.opacity = '0.8';\\n      } else {\\n        callButton.style.transform = 'scale(1)';\\n        callButton.style.opacity = '1';\\n      }\\n      lastScrollTop = scrollTop;\\n    }, 10);\\n  }, { passive: true });\\n}\\n</script>\\n\",customHTMLHeadEnd:\"<script nowprocket=\\\"\\\" nitro-exclude=\\\"\\\" type=\\\"text/javascript\\\" id=\\\"sa-dynamic-optimization\\\" data-uuid=\\\"761589b3-c98a-43c7-aff5-1efc17c71370\\\" src=\\\"data:text/javascript;base64,dmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNjcmlwdCIpO3NjcmlwdC5zZXRBdHRyaWJ1dGUoIm5vd3Byb2NrZXQiLCAiIik7c2NyaXB0LnNldEF0dHJpYnV0ZSgibml0cm8tZXhjbHVkZSIsICIiKTtzY3JpcHQuc3JjID0gImh0dHBzOi8vZGFzaGJvYXJkLnNlYXJjaGF0bGFzLmNvbS9zY3JpcHRzL2R5bmFtaWNfb3B0aW1pemF0aW9uLmpzIjtzY3JpcHQuZGF0YXNldC51dWlkID0gIjc2MTU4OWIzLWM5OGEtNDNjNy1hZmY1LTFlZmMxN2M3MTM3MCI7c2NyaXB0LmlkID0gInNhLWR5bmFtaWMtb3B0aW1pemF0aW9uLWxvYWRlciI7ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpOw==\\\"></script>\\n\\n\\n<script>\\n  // Queue dataLayer early\\n  window.dataLayer = window.dataLayer || [];\\n  function gtag(){dataLayer.push(arguments);}\\n  gtag('js', new Date());\\n\\n  // Load GTM after first interaction or when the browser is idle\\n  (function(){\\n    var loaded = false;\\n    function loadGTM(){\\n      if (loaded) return; loaded = true;\\n      var s = document.createElement('script');\\n      s.async = true; s.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-P4WCW8M';\\n      document.head.appendChild(s);\\n    }\\n    // Idle or timeout fallback\\n    if ('requestIdleCallback' in window) requestIdleCallback(loadGTM, {timeout: 3000});\\n    else setTimeout(loadGTM, 3000);\\n\\n    // Any user engagement -> load immediately\\n    ['click','scroll','keydown','pointerdown','touchstart'].forEach(evt =>\\n      window.addEventListener(evt, loadGTM, {once:true, passive:true})\\n    );\\n  })();\\n</script>\\n\\n\\n<!-- Place this in the <head> section -->\\n<script>\\n// Visitor Tracking Script\\nclass VisitorTracker {\\n    constructor() {\\n        this.startTime = this.getOrSetStartTime();\\n        this.pageVisits = this.getOrSetPageVisits();\\n        this.isReturning = this.checkReturningVisitor();\\n        this.setupTracking();\\n    }\\n\\n    // Get or set the initial start time from sessionStorage\\n    getOrSetStartTime() {\\n        let startTime = sessionStorage.getItem('visitorStartTime');\\n        if (!startTime) {\\n            startTime = Date.now();\\n            sessionStorage.setItem('visitorStartTime', startTime);\\n        }\\n        return parseInt(startTime);\\n    }\\n\\n    // Get or set the page visits from sessionStorage\\n    getOrSetPageVisits() {\\n        let visits = new Set();\\n        try {\\n            const storedVisits = JSON.parse(sessionStorage.getItem('pageVisits') || '[]');\\n            visits = new Set(storedVisits);\\n        } catch (e) {\\n            console.error('Error parsing stored page visits:', e);\\n        }\\n        return visits;\\n    }\\n\\n    // Check if this is a returning visitor using localStorage\\n    checkReturningVisitor() {\\n        const lastVisit = localStorage.getItem('lastVisit');\\n        const isReturning = !!lastVisit;\\n        localStorage.setItem('lastVisit', Date.now());\\n        return isReturning;\\n    }\\n\\n    // Calculate time spent on site\\n    getTimeOnSite() {\\n        const timeSpent = Math.floor((Date.now() - this.startTime) / 1000); // in seconds\\n        return timeSpent;\\n    }\\n\\n    // Track page visits\\n    trackPageVisit() {\\n        // Get full URL information\\n        const currentPath = window.location.pathname + window.location.search;\\n        const timestamp = new Date().toISOString();\\n        \\n        // Add new visit with timestamp\\n        this.pageVisits.add(JSON.stringify({\\n            path: currentPath,\\n            timestamp: timestamp,\\n            fullUrl: window.location.href\\n        }));\\n\\n        // Store updated visits in sessionStorage\\n        sessionStorage.setItem('pageVisits', JSON.stringify(Array.from(this.pageVisits)));\\n        \\n        // Log for debugging\\n        console.log('Page visit tracked:', currentPath);\\n        \\n        return Array.from(this.pageVisits).map(visit => JSON.parse(visit));\\n    }\\n\\n    // Get user's browser information\\n    getUserBrowserInfo() {\\n        return {\\n            userAgent: navigator.userAgent,\\n            language: navigator.language,\\n            platform: navigator.platform,\\n            screenWidth: window.screen.width,\\n            screenHeight: window.screen.height,\\n            timezone: Intl.DateTimeFormat().resolvedOptions().timeZone\\n        };\\n    }\\n\\n    // Get all tracking data as an object\\n    getTrackingData() {\\n        const visits = Array.from(this.pageVisits).map(visit => {\\n            try {\\n                return JSON.parse(visit);\\n            } catch (e) {\\n                return visit;\\n            }\\n        });\\n\\n        return {\\n            currentURL: window.location.href,\\n            referrer: document.referrer,\\n            timeOnSite: this.getTimeOnSite(),\\n            pagesVisited: visits,\\n            totalPagesVisited: visits.length,\\n            isReturning: this.isReturning,\\n            browserInfo: this.getUserBrowserInfo(),\\n            lastUpdated: new Date().toISOString(),\\n            sessionStartTime: new Date(this.startTime).toISOString()\\n        };\\n    }\\n\\n    // Update the user_data hidden field\\n    updateFormField() {\\n        const userDataField = document.querySelector('input[name=\\\"user_data\\\"]');\\n        if (userDataField) {\\n            const trackingData = this.getTrackingData();\\n            userDataField.value = JSON.stringify(trackingData);\\n            console.log('Updated user_data field:', trackingData);\\n        } else {\\n            console.error('Could not find hidden field with name \\\"user_data\\\"');\\n        }\\n    }\\n\\n    // Setup tracking events\\n    setupTracking() {\\n        // Track initial page load\\n        this.trackPageVisit();\\n\\n        // Update form field every 2 seconds and check for URL changes\\n        let lastUrl = location.href;\\n        setInterval(() => {\\n            // Check if URL has changed\\n            if (location.href !== lastUrl) {\\n                lastUrl = location.href;\\n                this.trackPageVisit();\\n            }\\n            this.updateFormField();\\n        }, 2000);\\n\\n        // Track page visibility changes\\n        document.addEventListener('visibilitychange', () => {\\n            if (document.visibilityState === 'hidden') {\\n                this.trackPageVisit();\\n                this.updateFormField();\\n            }\\n        });\\n\\n        // Track pushState and replaceState\\n        const originalPushState = history.pushState;\\n        const originalReplaceState = history.replaceState;\\n        \\n        history.pushState = function() {\\n            originalPushState.apply(this, arguments);\\n            window.visitorTracker.trackPageVisit();\\n            window.visitorTracker.updateFormField();\\n        };\\n        \\n        history.replaceState = function() {\\n            originalReplaceState.apply(this, arguments);\\n            window.visitorTracker.trackPageVisit();\\n            window.visitorTracker.updateFormField();\\n        };\\n\\n        // Listen for popstate events\\n        window.addEventListener('popstate', () => {\\n            this.trackPageVisit();\\n            this.updateFormField();\\n        });\\n\\n        // Track all click events that might be navigation\\n        document.addEventListener('click', (e) => {\\n            // Give a small delay to allow for navigation to complete\\n            setTimeout(() => {\\n                this.trackPageVisit();\\n                this.updateFormField();\\n            }, 100);\\n        });\\n    }\\n}\\n\\n// Ensure the hidden field exists\\nfunction ensureHiddenField() {\\n    let userDataField = document.querySelector('input[name=\\\"user_data\\\"]');\\n    \\n    if (!userDataField) {\\n        userDataField = document.createElement('input');\\n        userDataField.type = 'hidden';\\n        userDataField.name = 'user_data';\\n        \\n        // Find any form on the page\\n        const form = document.querySelector('form');\\n        if (form) {\\n            form.appendChild(userDataField);\\n            console.log('Created and attached user_data hidden field to form');\\n        } else {\\n            console.error('No form found on page to attach user_data field');\\n        }\\n    }\\n}\\n\\n// Initialize tracking when DOM is fully loaded\\ndocument.addEventListener('DOMContentLoaded', () => {\\n    ensureHiddenField();\\n    window.visitorTracker = new VisitorTracker();\\n});\\n</script>\\n\\n\\n\\n\\n\\n\\n<script>\\n/**\\n * Lightweight spam guard for Framer forms.\\n * - Honeypot input (bots tend to fill it)\\n * - Min time on page (prevents instant submits)\\n * - Gibberish detector for text inputs / textareas\\n *\\n * Works with most Framer forms without changing your design.\\n */\\n\\n(function () {\\n  // --- CONFIG ---\\n  const MIN_SECONDS_BEFORE_SUBMIT = 6; // user must spend at least this long before submitting\\n  const GIBBERISH_CHECK_FIELDS = [\\n    /first\\\\s*name/i,\\n    /message/i,\\n    /notes?/i\\n  ];\\n\\n  // --- UTILITIES ---\\n  const pageStart = Date.now();\\n\\n  function addHoneypot(form) {\\n    // Randomize honeypot name to prevent autofill and pattern recognition\\n    const hpName = 'middle_' + Math.random().toString(36).slice(2, 8);\\n    if (form.querySelector(`input[name=\\\"${hpName}\\\"]`)) return;\\n\\n    const hp = document.createElement('input');\\n    hp.type = 'text';\\n    hp.name = hpName;\\n    hp.autocomplete = 'off';\\n    hp.inputMode = 'none';\\n    hp.tabIndex = -1;\\n    hp.readOnly = true; // prevent autofill changes\\n    hp.style.position = 'absolute';\\n    hp.style.left = '-9999px';\\n    hp.style.height = '0';\\n    hp.setAttribute('aria-hidden', 'true');\\n    hp.setAttribute('autocapitalize', 'off');\\n    hp.setAttribute('autocorrect', 'off');\\n    hp.setAttribute('spellcheck', 'false');\\n    hp.setAttribute('data-anti-spam-hp', '1');\\n\\n    // Allow legit users to unlock it (e.g. bots won't do this)\\n    form.addEventListener('pointerdown', () => { hp.readOnly = false; }, { once: true });\\n\\n    // Append inside a hidden wrapper (extra autofill safety)\\n    const wrap = document.createElement('fieldset');\\n    wrap.style.display = 'none';\\n    wrap.appendChild(hp);\\n    form.appendChild(wrap);\\n  }\\n\\n  function showError(form, msg) {\\n    let box = form.querySelector('.anti-spam-error');\\n    if (!box) {\\n      box = document.createElement('div');\\n      box.className = 'anti-spam-error';\\n      box.style.cssText = [\\n        'margin:12px 0',\\n        'padding:10px 12px',\\n        'border-radius:8px',\\n        'background:#fff4f4',\\n        'border:1px solid #ffd6d6',\\n        'color:#8a1f1f',\\n        'font-size:14px'\\n      ].join(';');\\n      form.appendChild(box);\\n    }\\n    box.textContent = msg;\\n  }\\n\\n  function getAllTextInputs(form) {\\n    return Array.from(form.querySelectorAll('input[type=\\\"text\\\"], input[type=\\\"search\\\"], input:not([type]) , textarea'))\\n      .filter(el => !/email|phone|tel|url|number|hidden/i.test(el.type || '') && !el.hasAttribute('data-anti-spam-hp'));\\n  }\\n\\n  function getLikelyFieldLabel(el) {\\n    const parts = [el.name, el.getAttribute('aria-label'), el.getAttribute('placeholder')].filter(Boolean).join(' ');\\n    if (parts) return parts;\\n    if (el.id) {\\n      const lbl = el.ownerDocument.querySelector(`label[for=\\\"${el.id}\\\"]`);\\n      if (lbl) return lbl.textContent || '';\\n    }\\n    let p = el.parentElement;\\n    while (p) {\\n      if (p.tagName === 'LABEL') return p.textContent || '';\\n      p = p.parentElement;\\n    }\\n    return '';\\n  }\\n\\n  // --- GIBBERISH DETECTOR ---\\n  function looksLikeGibberish(value, labelText) {\\n    if (!value) return false;\\n    const s = (value || '').trim();\\n\\n    if (/\\\\s/.test(s) && s.length >= 15) return false;\\n\\n    const lettersOnly = /^[A-Za-z]+$/.test(s);\\n    const noSpaces = !/\\\\s/.test(s);\\n    const vowels = (s.match(/[aeiou]/gi) || []).length;\\n    const vowelRatio = vowels / Math.max(1, s.length);\\n    const isWeirdCase =\\n      /[A-Z]/.test(s) && /[a-z]/.test(s) &&\\n      !(s[0] === s[0].toUpperCase() && s.slice(1) === s.slice(1).toLowerCase());\\n    const hasLongConsonantRun = /[bcdfghjklmnpqrstvwxyz]{4,}/i.test(s);\\n    const looksTokeny = lettersOnly && noSpaces && s.length >= 10;\\n\\n    const label = (labelText || '').toLowerCase();\\n    const isNameLike = /first\\\\s*name|name/.test(label);\\n    const isMessageLike = /message|notes?/.test(label);\\n\\n    if (isNameLike) {\\n      if (looksTokeny && (vowelRatio < 0.25 || hasLongConsonantRun || isWeirdCase)) return true;\\n      if (lettersOnly && noSpaces && s.length >= 16) return true;\\n    }\\n\\n    if (isMessageLike) {\\n      if (looksTokeny && s.length <= 40) return true;\\n    }\\n\\n    if (looksTokeny && (vowelRatio < 0.22 || hasLongConsonantRun || isWeirdCase)) return true;\\n\\n    return false;\\n  }\\n\\n  function validateForm(form) {\\n    const hp = form.querySelector('[data-anti-spam-hp]');\\n    if (hp && hp.value && hp.value.trim() !== '') {\\n      console.info('[anti-spam] blocked: honeypot filled');\\n      showError(form, 'Submission blocked.');\\n      return false;\\n    }\\n\\n    const secondsHere = (Date.now() - pageStart) / 1000;\\n    if (secondsHere < MIN_SECONDS_BEFORE_SUBMIT) {\\n      console.info('[anti-spam] blocked: time-on-page', { secondsHere });\\n      showError(form, 'Please take a moment to complete the form before submitting.');\\n      return false;\\n    }\\n\\n    const textInputs = getAllTextInputs(form);\\n    for (const el of textInputs) {\\n      const label = getLikelyFieldLabel(el);\\n      const val = (el.value || '').trim();\\n      if (val.length <= 2) continue;\\n\\n      if (looksLikeGibberish(val, label)) {\\n        console.info('[anti-spam] blocked: gibberish', { label, val });\\n        if (typeof el.setCustomValidity === 'function') {\\n          el.setCustomValidity('Please enter a real value (no random strings).');\\n          el.reportValidity?.();\\n          setTimeout(() => el.setCustomValidity(''), 2000);\\n        }\\n        showError(form, 'Please check your entries and try again.');\\n        return false;\\n      }\\n    }\\n\\n    return true;\\n  }\\n\\n  function hookForm(form) {\\n    addHoneypot(form);\\n    form.addEventListener('submit', function (e) {\\n      try {\\n        if (!validateForm(form)) {\\n          e.preventDefault();\\n          e.stopPropagation();\\n          return false;\\n        }\\n      } catch (err) {\\n        console.warn('Spam guard error:', err);\\n      }\\n    }, true);\\n  }\\n\\n  function init() {\\n    const forms = Array.from(document.querySelectorAll('form'));\\n    forms.forEach(hookForm);\\n\\n    const obs = new MutationObserver(muts => {\\n      muts.forEach(m => {\\n        m.addedNodes && m.addedNodes.forEach(node => {\\n          if (node.nodeType === 1) {\\n            if (node.tagName === 'FORM') hookForm(node);\\n            node.querySelectorAll && node.querySelectorAll('form').forEach(hookForm);\\n          }\\n        });\\n      });\\n    });\\n    obs.observe(document.documentElement, { childList: true, subtree: true });\\n  }\\n\\n  if (document.readyState === 'loading') {\\n    document.addEventListener('DOMContentLoaded', init);\\n  } else {\\n    init();\\n  }\\n})();\\n</script>\\n\",description:\"Struggling with tinnitus or sound sensitivity? Discover Sound Relief’s proven TRT-based approach, personalized care plans, and expert audiologists. Relief starts here.\",favicon:\"https://framerusercontent.com/assets/vsYLPI1FgIpMyCmA0rheTxWi1Mc.png\",robots:\"max-image-preview:large\",socialImage:\"https://framerusercontent.com/assets/r0N45TmMYOqmTOLw0IxO6xOKQ.png\",title:\"Tinnitus & Hearing Treatment Experts | Sound Relief Hearing Center\"};}export const metadataVersion=1;\nexport const __FramerMetadata__ = {\"exports\":{\"metadataVersion\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"default\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}"],"mappings":"2DACA,SAAwB,EAAS,EAAO,EAAa,CAAC,MAAM,CAAC,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAqgH,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA4wd,YAAY,0KAA0K,QAAQ,uEAAuE,OAAO,0BAA0B,YAAY,qEAAqE,MAAM,qEAAqE"}