1(function (window, document) { 2 'use strict'; 3 4 var ENDPOINT = window.IF_JIVO_CONTACT_INTAKE_URL || 'https://hooks.globalconf.ru/jivo/contact-intake'; 5 var TOKEN_KEY = 'if_jivo_contact_token_v1'; 6 var lastCompletedKey = ''; 7 var inFlightKey = ''; 8 var memoryToken = ''; 9 10 function randomId(prefix) { 11 if (!window.crypto || typeof window.crypto.getRandomValues !== 'function' || typeof window.btoa !== 'function') return ''; 12 var bytes = new window.Uint8Array(16); 13 window.crypto.getRandomValues(bytes); 14 var raw = Array.prototype.map.call(bytes, function (byte) { return String.fromCharCode(byte); }).join(''); 15 return prefix + window.btoa(raw).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); 16 } 17 18 function getOrCreateToken() { 19 var token = memoryToken; 20 try { token = window.sessionStorage.getItem(TOKEN_KEY) || token; } catch (_) {} 21 if (!/^ifj1_[A-Za-z0-9_-]{22}$/.test(token)) token = randomId('ifj1_'); 22 if (!token) return ''; 23 memoryToken = token; 24 try { window.sessionStorage.setItem(TOKEN_KEY, token); } catch (_) {} 25 return token; 26 } 27 28 function contactKey(info) { 29 return JSON.stringify([ 30 String(info.client_name || '').trim(), 31 String(info.phone || '').trim(), 32 String(info.email || '').trim().toLowerCase(), 33 String(window.location && window.location.href || ''), 34 ]); 35 } 36 37 function sendWithRetry(payload, key) { 38 var delays = [0, 500, 1500]; 39 inFlightKey = key; 40 41 function attempt(index) { 42 window.fetch(ENDPOINT, { 43 method: 'POST', 44 mode: 'cors', 45 credentials: 'omit', 46 keepalive: true, 47 headers: { 'Content-Type': 'application/json' }, 48 body: JSON.stringify(payload), 49 }).then(function (response) { 50 if (!response || !response.ok) throw new Error('contact intake unavailable'); 51 lastCompletedKey = key; 52 if (inFlightKey === key) inFlightKey = ''; 53 }).catch(function () { 54 if (index + 1 < delays.length) { 55 window.setTimeout(function () { attempt(index + 1); }, delays[index + 1]); 56 } else if (inFlightKey === key) { 57 inFlightKey = ''; 58 } 59 }); 60 } 61 62 attempt(0); 63 } 64 65 function configureAndCapture() { 66 var api = window.jivo_api; 67 if (!api || typeof api.setUserToken !== 'function' || typeof api.getContactInfo !== 'function') return false; 68 var token = getOrCreateToken(); 69 if (!token) return false; 70 try { api.setUserToken(token); } catch (_) { return false; } 71 72 var info; 73 try { info = api.getContactInfo() || {}; } catch (_) { return true; } 74 var phone = String(info.phone || '').trim(); 75 var email = String(info.email || '').trim(); 76 if (!phone && !email) return true; 77 var key = contactKey(info); 78 if (key === lastCompletedKey || key === inFlightKey) return true; 79 var eventId = randomId('ifje_'); 80 if (!eventId) return true; 81 sendWithRetry({ 82 version: 1, 83 token: token, 84 event_id: eventId, 85 name: String(info.client_name || '').trim(), 86 phone: phone, 87 email: email, 88 page: String(window.location && window.location.href || ''), 89 }, key); 90 return true; 91 } 92 93 function composeCallback(name) { 94 var previous = window[name]; 95 window[name] = function () { 96 var result; 97 try { 98 if (typeof previous === 'function') result = previous.apply(this, arguments); 99 } finally { 100 configureAndCapture(); 101 } 102 return result; 103 }; 104 } 105 106 composeCallback('jivo_onLoadCallback'); 107 composeCallback('jivo_onIntroduction'); 108 composeCallback('jivo_onCallStart'); 109 [0, 500, 1500, 4000].forEach(function (delay) { 110 window.setTimeout(configureAndCapture, delay); 111 }); 112})(window, document);
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.