1/* leadflow.js v1.9 (ÐºÐ¾Ð¿Ð¸Ñ lead.js ÑÑалона; адÑÐµÑ /leadflow.php задаÑÑÑÑ data-endpoint Ñ ÑкÑипÑа) */ 2(function () { 3 var D = (document.currentScript && document.currentScript.dataset) || {}; 4 var EP = D.endpoint || '/lead.php', PREFIX = (D.prefix || '').toUpperCase().charAt(0), YM = parseInt(D.ym, 10) || 0; 5 var ALPHABET = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ', cid = '', cidReady = false, token = '', tokenAt = 0; 6 var TOKEN_AGE = 3200; 7 var TOKEN_REFRESH = 3600e3, refreshing = false, inited = false; 8 9 function cookie(n) { var m = document.cookie.match('(?:^|; )' + n + '=([^;]*)'); return m ? decodeURIComponent(m[1]) : ''; } 10 function getCid(cb) { 11 if (cidReady) return cb(cid); 12 var tries = 25, done = false; 13 var finish = function (v) { if (done) return; done = true; cid = v || cookie('_ym_uid'); cidReady = true; cb(cid); }; 14 (function go() { 15 if (window.ym && YM) { 16 ym(YM, 'getClientID', finish); 17 setTimeout(function () { finish(''); }, 3000); 18 } 19 else if (tries-- > 0) { setTimeout(go, 200); } 20 else { finish(''); } 21 })(); 22 } 23 function getToken(cb, force) { 24 if (token && !force) return cb(token); 25 fetch(EP + '?action=token', { credentials: 'same-origin' }).then(function (r) { return r.json(); }) 26 .then(function (j) { 27 if (j.token) { token = j.token; tokenAt = Date.now(); } 28 if (!YM && j.ym) YM = parseInt(j.ym, 10) || 0; 29 if (!PREFIX && j.prefix) PREFIX = String(j.prefix).toUpperCase().charAt(0); 30 mail(j); 31 cb(token); 32 }).catch(function () { cb(token); }); 33 } 34 35 36 var MAIL = { def: '', cur: '', seen: {}, touched: 0, live: false }; 37 function mail(j) { 38 if (!j || !j.default) return; 39 MAIL.def = String(j.default).toLowerCase(); 40 MAIL.seen[MAIL.def] = 1; 41 MAIL.cur = String(j.email || j.default).toLowerCase(); 42 MAIL.touched = Date.now(); 43 MAIL.live = !!(j.tracked || j.busy); 44 if (MAIL.cur !== MAIL.def || document.querySelector('[data-email]')) swapMail(document); 45 } 46 function swapMail(root) { 47 if (!MAIL.cur) return; 48 var known = function (a) { return !!MAIL.seen[String(a || '').toLowerCase()]; }; 49 Array.prototype.forEach.call(root.querySelectorAll('a[href^="mailto:"]'), function (a) { 50 var m = a.getAttribute('href').match(/^mailto:([^?]*)(.*)$/i); 51 if (!m || !known(decodeURIComponent(m[1]))) return; 52 a.setAttribute('href', 'mailto:' + MAIL.cur + m[2]); 53 if (known(a.textContent.trim())) a.textContent = MAIL.cur; 54 }); 55 Array.prototype.forEach.call(root.querySelectorAll('[data-email]'), function (el) { 56 el.textContent = MAIL.cur; 57 if (el.tagName === 'A') el.setAttribute('href', 'mailto:' + MAIL.cur); 58 }); 59 Array.prototype.forEach.call(root.querySelectorAll('[data-messenger="email"]'), function (a) { 60 if (!a.dataset.to || known(a.dataset.to)) a.dataset.to = MAIL.cur; 61 }); 62 MAIL.seen[MAIL.cur] = 1; 63 } 64 function touchMail() { 65 if (!MAIL.live || Date.now() - MAIL.touched < 300e3) return; 66 MAIL.touched = Date.now(); 67 fetch(EP + '?action=email&ym_client_id=' + encodeURIComponent(cid), { credentials: 'same-origin' }) 68 .then(function (r) { return r.json(); }).then(mail).catch(function () {}); 69 } 70 function refreshToken() { 71 touchMail(); 72 if (!inited || refreshing || (token && Date.now() - tokenAt < TOKEN_REFRESH)) return; 73 refreshing = true; 74 getToken(function () { refreshing = false; prepareAll(); }, true); 75 } 76 function hidden(f, name, value) { 77 var el = f.querySelector('input[name="' + name + '"]'); 78 if (!el) { el = document.createElement('input'); el.type = 'hidden'; el.name = name; f.appendChild(el); } 79 el.value = value || ''; 80 } 81 function prepare(f) { 82 hidden(f, 'ym_client_id', cid); 83 hidden(f, 'token', token); 84 if (!f.querySelector('input[name="website"]')) { 85 var h = document.createElement('input'); h.name = 'website'; h.tabIndex = -1; h.autocomplete = 'off'; 86 h.style.cssText = 'position:absolute;left:-9999px;opacity:0;height:0'; f.appendChild(h); 87 } 88 } 89 function prepareAll() { Array.prototype.forEach.call(document.querySelectorAll('form'), prepare); } 90 function goals(next) { 91 next = next || function () {}; 92 var m = document.cookie.match('(?:^|; )lead_goal=([^;]*)'), raw = m ? decodeURIComponent(m[1].replace(/\+/g, ' ')) : '', list = []; 93 if (!raw) return next(); 94 document.cookie = 'lead_goal=; path=/; max-age=0; samesite=Lax'; 95 try { list = JSON.parse(raw) || []; } catch (e) {} 96 if (!list.length || !YM || !window.ym) return next(); 97 var once = false, go = function () { if (!once) { once = true; next(); } }; 98 list.forEach(function (x, i) { ym(YM, 'reachGoal', x.g, x.p || {}, i === list.length - 1 ? go : undefined); }); 99 setTimeout(go, 500); 100 } 101 function finish(f, j) { 102 if (j.ok) { if (f.dataset.redirect) location.href = f.dataset.redirect; else f.reset(); } 103 else alert(j.message || 'ÐÑовеÑÑÑе Ð¿Ð¾Ð»Ñ ÑоÑмÑ'); 104 } 105 106 107 function submit(f) { 108 if (!f || !f.dataset || !f.dataset.lead) return; 109 var btn = f.querySelector('[type=submit]'); if (btn) btn.disabled = true; 110 getToken(function () { 111 prepare(f); 112 var fd = new FormData(f); fd.set('action', 'lead'); fd.set('channel', f.dataset.lead); 113 var wait = Math.max(0, TOKEN_AGE - (Date.now() - tokenAt)); 114 new Promise(function (res) { setTimeout(res, wait); }) 115 .then(function () { return fetch(EP, { method: 'POST', body: fd, credentials: 'same-origin' }); }) 116 .then(function (r) { return r.json(); }) 117 .then(function (j) { 118 f.dispatchEvent(new CustomEvent('lead:done', { detail: j, bubbles: true })); 119 goals(function () { finish(f, j); }); 120 }) 121 .catch(function () { alert('Ðе ÑдалоÑÑ Ð¾ÑпÑавиÑÑ, попÑобÑйÑе еÑÑ Ñаз'); }) 122 .then(function () { if (btn) btn.disabled = false; }); 123 }); 124 } 125 126 function leadSend(data) { 127 data = data || {}; 128 return new Promise(function (resolve) { 129 getToken(function () { 130 var fd = new FormData(); 131 ['channel', 'phone', 'name', 'email', 'comment', 'portal_id', 'embed'].forEach(function (k) { if (data[k] != null) fd.set(k, String(data[k])); }); 132 fd.set('action', 'lead'); fd.set('token', token);
132 fd.set('ym_client_id', cid); fd.set('website', ''); fd.set('page', location.href.slice(0, 255)); 133 setTimeout(function () { 134 fetch(EP, { method: 'POST', body: fd, credentials: 'same-origin' }).then(function (r) { return r.json(); }) 135 .then(function (j) { 136 document.dispatchEvent(new CustomEvent('lead:done', { detail: Object.assign({ embed: data.embed || '', channel: data.channel || '' }, j) })); 137 goals(function () { resolve(j); }); 138 }) 139 .catch(function () { resolve({ ok: false, field: '', message: 'Ðе ÑдалоÑÑ Ð¾ÑпÑавиÑÑ, попÑобÑйÑе еÑÑ Ñаз' }); }); 140 }, Math.max(0, TOKEN_AGE - (Date.now() - tokenAt))); 141 }); 142 }); 143 } 144 145 document.addEventListener('submit', function (e) { 146 var f = e.target; 147 if (!f || !f.dataset || !f.dataset.lead) return; 148 e.preventDefault(); 149 if (f.dataset.leadManual === undefined) submit(f); 150 }, true); 151 152 153 function code() { 154 var c = PREFIX || 'A', r = new Uint32Array(4); 155 if (window.crypto && crypto.getRandomValues) crypto.getRandomValues(r); else for (var j = 0; j < 4; j++) r[j] = Math.floor(Math.random() * 1e9); 156 for (var i = 0; i < 4; i++) c += ALPHABET.charAt(r[i] % ALPHABET.length); 157 return c; 158 } 159 function link(kind, to, c) { 160 var text = encodeURIComponent('ÐдÑавÑÑвÑйÑе, мой пÑомокод ' + c); 161 if (kind === 'whatsapp') return 'https://wa.me/' + to.replace(/\D/g, '') + '?text=' + text; 162 if (kind === 'telegram-bot') return 'https://t.me/' + to.replace(/^@/, '') + '?start=' + c; 163 if (kind === 'telegram') return 'https://t.me/' + to.replace(/^@/, '') + '?text=' + text; 164 if (kind === 'max-bot') return 'https://max.ru/' + to.replace(/^@/, '') + '?start=' + c; 165 if (kind === 'email') return 'mailto:' + to + '?subject=' + encodeURIComponent('ÐаÑвка Ñ ÑайÑа · пÑомокод ' + c) + '&body=' + text; 166 return '#'; 167 } 168 function channelOf(kind) { return kind === 'max-bot' ? 'max' : kind.replace('-bot', ''); } 169 function send(body) { 170 var fd = new FormData(); Object.keys(body).forEach(function (k) { fd.append(k, body[k]); }); 171 var ok = false; 172 try { ok = navigator.sendBeacon && navigator.sendBeacon(EP, fd); } catch (e) {} 173 if (!ok) fetch(EP, { method: 'POST', body: fd, keepalive: true, credentials: 'same-origin' }).catch(function () { queue(body); }); 174 } 175 function queue(body) { try { var q = JSON.parse(localStorage.getItem('visitq') || '[]'); q.push(body); localStorage.setItem('visitq', JSON.stringify(q.slice(-20))); } catch (e) {} } 176 function flush() { 177 try { 178 var q = JSON.parse(localStorage.getItem('visitq') || '[]'); localStorage.removeItem('visitq'); 179 q.filter(function (b) { return Date.now() - b.t < 864e5; }).forEach(send); 180 } catch (e) {} 181 } 182 document.addEventListener('click', function (e) { 183 var m = e.target.closest && e.target.closest('a[href^="mailto:"]'); 184 if (m && m.parentNode) swapMail(m.parentNode); 185 }, true); 186 document.addEventListener('click', function (e) { 187 var a = e.target.closest && e.target.closest('[data-messenger]'); 188 if (!a) return; 189 e.preventDefault(); 190 if (a.dataset.messenger === 'email' && MAIL.cur && (!a.dataset.to || MAIL.seen[a.dataset.to.toLowerCase()])) a.dataset.to = MAIL.cur; 191 var c = code(), kind = a.dataset.messenger, url = link(kind, a.dataset.to || '', c); 192 var hint = a.dataset.hint && document.querySelector(a.dataset.hint); if (hint) hint.textContent = c; 193 if (kind === 'email') { location.href = url; } else { var w = window.open(url, '_blank'); if (!w) location.href = url; } 194 send({ action: 'visit', code: c, channel: channelOf(kind), landing: location.pathname, ym_client_id: cid, t: Date.now() }); 195 }); 196 197 function init() { getCid(function () { getToken(function () { inited = true; prepareAll(); }); }); flush(); goals(); } 198 setInterval(function () { if (document.cookie.indexOf('lead_goal=') > -1) goals(); }, 1500); 199 ['scroll', 'click', 'keydown', 'touchstart'].forEach(function (ev) { document.addEventListener(ev, refreshToken, { passive: true, capture: true }); }); 200 document.addEventListener('visibilitychange', function () { if (!document.hidden) refreshToken(); }); 201 window.addEventListener('pageshow', function (e) { if (e.persisted) refreshToken(); }); 202 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init(); 203 window.leadVisitCode = code; 204 window.leadSubmit = submit; 205 window.leadSend = leadSend; 206})();
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.