1// Cookie consent center (152-ФРamendments in force since 2025-09-01: 2// marketing widgets need explicit, per-category consent; analytics was 3// exempted by the owner decision of 2026-09-19 and runs unconditionally). 4// First visit gets a bottom-right card with the widgets switch: 5// necessary â always on, runs the site (session, basket, city); 6// widgets â Jivo chat (wlnBSkDprV) and the Marquiz quiz. 7// The Yandex.Metrika counter 96864379 loads from here for every visitor 8// (moved out of the yandex.metrika module option 'counters' cleared on 9// production; see ops/bitrix/pdn-consent-gate.php). The widgets decision 10// is stored in the jaba_cookie_consent cookie for 12 months ('widgets' or 11// 'none'; legacy 'analytics,â¦' values are still parsed â the analytics 12// token is ignored). Other scripts gate on 13// window.JabaCookieConsent.allows('widgets') or listen for the 14// jaba-cookie-consent document event ({ detail: { analytics, widgets } }). 15(function () { 16 'use strict'; 17 18 var COOKIE_NAME = 'jaba_cookie_consent'; 19 var COOKIE_MAX_AGE = 31536000; // 12 months, in seconds 20 var POLICY_URL = '/info/requisites/#privacy'; 21 22 // admin pages and kernel endpoints (/bitrix/admin, /bitrix/tools, ...) 23 // are not user-facing and must not carry the banner 24 if (window.location.pathname.indexOf('/bitrix/') === 0) { 25 return; 26 } 27 28 // ---- consent state ------------------------------------------------- 29 30 function readCookie(name) { 31 var parts = document.cookie ? document.cookie.split(';') : []; 32 for (var i = 0; i < parts.length; i++) { 33 var pair = parts[i].trim(); 34 if (pair.indexOf(name + '=') === 0) { 35 return pair.substring(name.length + 1); 36 } 37 } 38 return ''; 39 } 40 41 // v1 values: 'accepted' granted analytics and widgets, 'rejected' 42 // turned optional widgets off â keep that state. v2 comma lists may 43 // still carry an 'analytics' token; it is ignored since the counter 44 // no longer depends on consent. 45 function parseStatus() { 46 var raw = readCookie(COOKIE_NAME); 47 if (raw === 'accepted') { 48 return { decided: true, widgets: true }; 49 } 50 if (raw === 'rejected') { 51 return { decided: true, widgets: false }; 52 } 53 var granted = raw ? raw.split(',') : []; 54 return { 55 decided: raw !== '', 56 widgets: granted.indexOf('widgets') >= 0, 57 }; 58 } 59 60 function persistStatus(status) { 61 var cookie = COOKIE_NAME + '=' + (status.widgets ? 'widgets' : 'none') 62 + '; max-age=' + COOKIE_MAX_AGE + '; path=/; SameSite=Lax'; 63 if (window.location.protocol === 'https:') { 64 cookie += '; Secure'; 65 } 66 document.cookie = cookie; 67 } 68 69 // ---- vendors -------------------------------------------------------- 70 71 var METRIKA_COUNTER = 96864379; 72 var JIVO_WIDGET_ID = 'wlnBSkDprV'; 73 var MARQUIZ_QUIZ_ID = '66daf91be3e0e2002674a23d'; 74 75 var loaded = {}; 76 77 // Same init params the yandex.metrika module used (module option 78 // 'counters' cleared on production; see ops/bitrix/pdn-consent-gate.php). 79 function loadAnalytics() { 80 if (loaded.analytics || window.ym) { 81 return; 82 } 83 loaded.analytics = true; 84 window.dataLayer = window.dataLayer || []; 85 (function (m, e, t, r, i, k, a) { 86 m[i] = m[i] || function () { (m[i].a = m[i].a || []).push(arguments); }; 87 m[i].l = 1 * new Date(); 88 k = e.createElement(t); 89 a = e.getElementsByTagName(t)[0]; 90 k.async = 1; 91 k.src = r; 92 a.parentNode.insertBefore(k, a); 93 })(window, document, 'script', 'https://mc.yandex.ru/metrika/tag.js', 'ym'); 94 window.ym(METRIKA_COUNTER, 'init', { 95 clickmap: true, 96 trackLinks: true, 97 accurateTrackBounce: true, 98 webvisor: true, 99 ecommerce: 'dataLayer', 100 }); 101 // aspro metrika.goals reads this to address the counter 102 window.counters = [String(METRIKA_COUNTER)]; 103 } 104 105 // Jivo: the standard module snippet (option 'widget_id' cleared on 106 // production) only inserts the widget script. 107 function loadJivo() { 108 var s = document.createElement('script'); 109 s.async = true; 110 s.src = '//code.jivosite.com/script/widget/' + JIVO_WIDGET_ID; 111 var first = document.getElementsByTagName('script')[0]; 112 first.parentNode.insertBefore(s, first); 113 } 114 115 // Marquiz: loader + init from the aspro header.php block and the Pop 116 // side-button config from footer.php, both removed on production. 117 function loadMarquiz() { 118 window.addEventListener('marquizLoaded', function () { 119 try { 120 window.Marquiz.add(['Pop', { 121 id: MARQUIZ_QUIZ_ID, 122 title: 'ÐÑойÑи ÑеÑÑ', 123 text: 'ÐаÑеÑÑвеннÑе ÑÑÑоймаÑеÑÐ¸Ð°Ð»Ñ Ð² диÑкаÑнÑеÑе "Ðаба"', 124 delay: 0, 125 textColor: '#ffffff', 126 bgColor: '#59b130', 127 svgColor: '#ffffff', 128 closeColor: '#ffffff', 129 bonusCount: 2, 130 bonusText: 'Ðам доÑÑÑÐ¿Ð½Ñ Ð±Ð¾Ð½ÑÑÑ', 131 type: 'side', 132 position: 'position_bottom-left', 133 rounded: true, 134 shadow: 'rgba(89, 177, 48, 0)', 135 blicked: true, 136 }]); 137 } catch (e) { 138 // the quiz button is optional and must never break the page 139 } 140 }); 141 (function (w, d, s, o) { 142 var j = d.createElement(s); 143 j.async = true; 144 j.src = '//script.marquiz.ru/v2.js'; 145 j.onload = function () { 146 if (document.readyState !== 'loading') { 147 w.Marquiz.init(o); 148 } else { 149 d.addEventListener('DOMContentLoaded', function () { 150 w.Marquiz.init(o); 151 }); 152 } 153 }; 154 d.head.insertBefore(j, d.head.firstElementChild); 155 })(window, document, 'script', { 156 host: '//quiz.marquiz.ru', 157 region: 'eu', 158 id: MARQUIZ_QUIZ_ID, 159 autoOpen: 10, 160 autoOpenFreq: 'once', 161 openOnExit: true, 162 disableOnMobile: false, 163 }); 164 } 165 166 function loadWidgets() { 167 if (loaded.widgets) { 168 return; 169 } 170 loaded.widgets = true; 171 loadJivo(); 172 loadMarquiz(); 173 } 174 175 // The Metrika counter runs for every visitor (owner decision 176 // 2026-09-19); only the widgets stay behind the consent decision. 177 loadAnalytics(); 178 179 function applyStatus(status) { 180 if (status.widgets) { 181 loadWidgets(); 182 } 183 } 184 185 function decide(banner, widgets) { 186 var status = { decided: true, widgets: widgets }; 187 persistStatus(status); 188 banner.remove(); 189 applyStatus(status); 190 try { 191 document.dispatchEvent(new CustomEvent('jaba-cookie-consent', { 192 detail: { analytics: true, widgets: widgets }, 193 })); 194 } catch (e) { 195 // browsers without CustomEvent keep the cookie flow intact 196 } 197 } 198 199 // ---- banner --------------------------------------------------------- 200 201 function makeGroup(className, checked, locked, labelHtml) { 202 var label = document.createElement('label'); 203 label.className = className; 204 var input = document.createElement('input'); 205 input.type = 'checkbox'; 206 input.checked = checked; 207 input.disabled = locked; 208 var span = document.createElement('span'); 209 span.innerHTML = labelHtml; 210 label.appendChild(input); 211 label.appendChild(span); 212 return { label: label, input: input }; 213 } 214 215 function render() { 216 var banner = document.createElement('div'); 217 banner.className = 'jaba-cookie-consent'; 218 banner.setAttribute('role', 'region'); 219 banner.setAttribute('aria-label', 'ÐÑполÑзование cookie-Ñайлов'); 220 221 var text = document.createElement('p'); 222 text.className = 'jaba-cookie-consent__text'; 223 text.innerHTML = 'Ð¡Ð°Ð¹Ñ Â«ÐÐÐл иÑполÑзÑÐµÑ cookie-ÑайлÑ: Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ñе â '
224 + 'Ð´Ð»Ñ ÑабоÑÑ ÑайÑа, коÑÐ·Ð¸Ð½Ñ Ð¸ вÑбÑанного гоÑода, виджеÑÑ ' 225 + 'онлайн-ÑаÑа и подбоÑа ÑоваÑа â ÑолÑко Ñ Ð²Ð°Ñего ÑазÑеÑениÑ. ' 226 + 'ÐодÑобнее â ' 227 + '<a href="' + POLICY_URL + '" target="_blank" rel="noopener">ÐеÑÑоналÑнÑе даннÑе и cookie</a>.'; 228 229 var groups = document.createElement('div'); 230 groups.className = 'jaba-cookie-consent__groups'; 231 groups.appendChild(makeGroup( 232 'jaba-cookie-consent__group jaba-cookie-consent__group--locked', 233 true, 234 true, 235 'ÐÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ñе â ÑабоÑа ÑайÑа, коÑзина, вÑбÑаннÑй гоÑод (вÑегда вклÑÑенÑ)' 236 ).label); 237 var widgets = makeGroup( 238 'jaba-cookie-consent__group', 239 false, 240 false, 241 'ÐиджеÑÑ â онлайн-ÑÐ°Ñ Ð¸ Ð¿Ð¾Ð´Ð±Ð¾Ñ ÑоваÑа (Jivo, Marquiz)' 242 ); 243 groups.appendChild(widgets.label); 244 245 var actions = document.createElement('div'); 246 actions.className = 'jaba-cookie-consent__actions'; 247 248 var accept = document.createElement('button'); 249 accept.type = 'button'; 250 accept.className = 'jaba-cookie-consent__accept'; 251 accept.textContent = 'ÐÑинÑÑÑ Ð²ÑбÑаннÑе'; 252 accept.addEventListener('click', function () { 253 decide(banner, widgets.input.checked); 254 }); 255 256 var reject = document.createElement('button'); 257 reject.type = 'button'; 258 reject.className = 'jaba-cookie-consent__reject'; 259 reject.textContent = 'ТолÑко Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ñе'; 260 reject.addEventListener('click', function () { 261 decide(banner, false); 262 }); 263 264 actions.appendChild(accept); 265 actions.appendChild(reject); 266 banner.appendChild(text); 267 banner.appendChild(groups); 268 banner.appendChild(actions); 269 document.body.appendChild(banner); 270 } 271 272 function mount() { 273 if (document.body) { 274 render(); 275 return true; 276 } 277 return false; 278 } 279 280 // ---- public API ------------------------------------------------------ 281 282 window.JabaCookieConsent = { 283 cookieName: COOKIE_NAME, 284 status: function () { 285 return parseStatus(); 286 }, 287 allows: function (category) { 288 if (category === 'analytics') { 289 // Metrika runs for every visitor (owner decision 290 // 2026-09-19) â kept true for the goal scripts 291 return true; 292 } 293 if (category === 'widgets') { 294 return parseStatus().widgets; 295 } 296 return false; 297 }, 298 // legacy alias: the v1 banner gated analytics only 299 isAccepted: function () { 300 return true; 301 }, 302 }; 303 304 var initial = parseStatus(); 305 if (initial.decided) { 306 applyStatus(initial); 307 return; 308 } 309 310 if (mount()) { 311 return; 312 } 313 document.addEventListener('DOMContentLoaded', function () { 314 mount(); 315 }); 316}());
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.