1/* ========================================================= 2 xyner.ai â Floating WhatsApp button + regional contact popup 3 Self-contained widget. Include with a <script> tag on every 4 page. Path resolves automatically (root, /folder/, etc.). 5 ========================================================= */ 6(function () { 7 if (window.__xynerWhatsAppLoaded) return; 8 window.__xynerWhatsAppLoaded = true; 9 10 // Resolve image path relative to whichever copy of this script loaded 11 function resolveAssetPath() { 12 var scripts = document.getElementsByTagName('script'); 13 for (var i = scripts.length - 1; i >= 0; i--) { 14 var src = scripts[i].getAttribute('src') || ''; 15 if (src.indexOf('whatsapp-widget.js') !== -1) { 16 return src.replace(/[?#].*$/, '').replace(/assets\/js\/whatsapp-widget\.js$/, 'assets/img/whatsapp.png'); 17 } 18 } 19 return '/assets/img/whatsapp.png'; 20 } 21 var WA_ICON = resolveAssetPath(); 22 23 // wa.me requires digits only 24 var OFFICES = [ 25 { iso: 'US', name: 'USA · Global HQ', phone: '+1 (774) 542 1363', wa: '17745421363' }, 26 { iso: 'IN', name: 'India', phone: '+91 96008 52044', wa: '919600852044' }, 27 { iso: 'AE', name: 'UAE', phone: '+971 58 557 6809', wa: '971585576809' }, 28 { iso: 'SA', name: 'Saudi Arabia', phone: '+966 55 108 1650', wa: '966551081650' }, 29 { iso: 'SG', name: 'Singapore', phone: '+65 6866 3337', wa: '6568663337' }, 30 { iso: 'BH', name: 'Bahrain', phone: '+973 3373 3381', wa: '97333733381' } 31 ]; 32 33 // Inject required styles once 34 var css = 35 '.xy-wa-fab{position:fixed;left:20px;bottom:20px;background:transparent;border:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;box-shadow:none;z-index:9998;transition:transform .18s ease;padding:0;outline-offset:4px;overflow:visible}' + 36 '.xy-wa-fab:hover{transform:translateY(-2px) scale(1.06)}' + 37 '.xy-wa-fab img{display:block;width:64px;height:auto}' + 38 '.xy-wa-pop-bg{position:fixed;inset:0;background:rgba(6,7,13,0.55);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);z-index:9999;display:none;align-items:flex-end;justify-content:flex-start;padding:0 20px 96px}' + 39 '.xy-wa-pop-bg.is-open{display:flex}' + 40 '.xy-wa-pop{width:100%;max-width:380px;background:#fff;color:#1a1f2e;border-radius:18px;box-shadow:0 24px 60px -12px rgba(0,0,0,0.45),0 0 0 1px rgba(0,0,0,0.05);overflow:hidden;display:flex;flex-direction:column;max-height:75vh}' + 41 '.xy-wa-pop header{padding:22px 24px 16px;border-bottom:1px solid rgba(0,0,0,0.07);position:relative}' + 42 '.xy-wa-pop h3{margin:0 0 4px;font-size:18px;font-weight:700;color:#1a1f2e}' + 43 '.xy-wa-pop p{margin:0;font-size:13.5px;color:#5b6273}' + 44 '.xy-wa-close{position:absolute;top:14px;right:14px;width:28px;height:28px;border:0;background:rgba(0,0,0,0.05);color:#5b6273;border-radius:7px;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:18px;line-height:1;padding:0}' + 45 '.xy-wa-close:hover{background:rgba(0,0,0,0.1);color:#1a1f2e}' + 46 '.xy-wa-list{list-style:none;margin:0;padding:6px 10px 14px;overflow-y:auto}' + 47 '.xy-wa-row{display:flex;align-items:center;gap:14px;padding:12px 14px;border-radius:12px;text-decoration:none;color:inherit;transition:background .15s;border:1px solid transparent}' + 48 '.xy-wa-row:hover{background:rgba(37,211,102,0.08);border-color:rgba(37,211,102,0.20)}' + 49 '.xy-wa-iso{flex-shrink:0;width:38px;font-size:13px;font-weight:700;color:#5b6273;letter-spacing:0.02em}' + 50 '.xy-wa-info{display:flex;flex-direction:column;min-width:0}' + 51 '.xy-wa-name{font-size:15px;font-weight:700;color:#1a1f2e;line-height:1.2}' + 52 '.xy-wa-num{font-size:13px;color:#5b6273;font-family:"JetBrains Mono","SF Mono",Menlo,Consolas,monospace;margin-top:2px;letter-spacing:0.02em}' + 53 '@media (max-width:640px){.xy-wa-pop-bg{padding:0 12px 92px}.xy-wa-fab{left:14px;bottom:14px}.xy-wa-fab img{width:56px}}'; 54 var styleTag = document.createElement('style'); 55 styleTag.setAttribute('data-xy', 'whatsapp'); 56 styleTag.textContent = css; 57 document.head.appendChild(styleTag); 58 59 // Build popup HTML 60 var rows = ''; 61 for (var i = 0; i < OFFICES.length; i++) { 62 var o = OFFICES[i]; 63 rows += '<li><a class="xy-wa-row" href="https://wa.me/' + o.wa + 64 '?text=' + encodeURIComponent('Hi xyner.ai team, I would like to chat.') + 65 '" target="_blank" rel="noopener noreferrer">' + 66 '<span class="xy-wa-iso">' + o.iso + '</span>' + 67 '<span class="xy-wa-info"><span class="xy-wa-name">' + o.name + '</span>' + 68 '<span class="xy-wa-num">' + o.phone + '</span></span></a></li>'; 69 } 70 71 var html = 72 '<button type="button" class="xy-wa-fab" aria-label="Chat on WhatsApp">' + 73 '<img src="' + WA_ICON + '" alt="WhatsApp" loading="eager"/>' + 74 '</button>' + 75 '<div class="xy-wa-pop-bg" id="xyWaPopBg">' + 76 '<div class="xy-wa-pop" id="xyWaPop" role="dialog" aria-modal="true">' + 77 '<header>' + 78 '<button type="button" class="xy-wa-close" aria-label="Close">×</button>' + 79 '<h3>Chat with our regional team</h3>' + 80 '<p>Pick the office closest to you.</p>' + 81 '</header>' + 82 '<ul class="xy-wa-list">' + rows + '</ul>' + 83 '</div>' + 84 '</div>'; 85 86 function mount() { 87 try { 88 if (document.querySelector('.xy-wa-fab')) return; 89 if (!document.body) { setTimeout(mount, 50); return; } 90 var holder = document.createElement('div'); 91 holder.innerHTML = html; 92 while (holder.firstChild) document.body.appendChild(holder.firstChild); 93 94 var fab = document.querySelector('.xy-wa-fab'); 95 var bg = document.getElementById('xyWaPopBg'); 96 var pop = document.getElementById('xyWaPop'); 97 if (!fab || !bg || !pop) return; 98 var closeBtn = pop.querySelector('.xy-wa-close'); 99 100 function openPopup() { bg.classList.add('is-open'); } 101 function closePopup() { bg.classList.remove('is-open'); } 102 103 fab.addEventListener('click', openPopup); 104 closeBtn.addEventListener('click', closePopup); 105 bg.addEventListener('click', function (e) { if (e.target === bg) closePopup(); }); 106 document.addEventListener('keydown', function (e) { 107 if (e.key === 'Escape' && bg.classList.contains('is-open')) closePopup(); 108 }); 109 110 window.openXynerWhatsApp = openPopup; 111 window.closeXynerWhatsApp = closePopup; 112 } catch (err) { 113 if (window.console && console.error) console.error('[xyner WhatsApp]', err); 114 } 115 } 116 117 if (document.readyState === 'loading') { 118 document.addEventListener('DOMContentLoaded', mount); 119 } else { 120 mount(); 121 } 122})();
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.