1// Cookie notice 2function getCookie(name) { 3 let matches = document.cookie.match( 4 new RegExp( 5 "(?:^|; )" + 6 name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, "\\$1") + 7 "=([^;]*)", 8 ), 9 ); 10 return matches ? decodeURIComponent(matches[1]) : undefined; 11} 12let cookiecook = getCookie("cookiecook"), 13 cookiewin = document.getElementsByClassName("cookie_notice")[0]; 14if (cookiecook != "no" && cookiewin) { 15 cookiewin.style.display = "block"; 16 document 17 .getElementById("cookie_close") 18 .addEventListener("click", function () { 19 cookiewin.style.display = "none"; 20 let date = new Date(); 21 date.setDate(date.getDate() + 180); 22 document.cookie = "cookiecook=no; path=/; expires=" + date.toUTCString(); 23 }); 24} 25 26// UTM tracking â save params from URL to sessionStorage 27(function() { 28 var params = new URLSearchParams(window.location.search); 29 ["utm_source", "utm_campaign", "utm_medium", "utm_content", "utm_term"].forEach(function(p) { 30 if (params.get(p)) sessionStorage.setItem(p, params.get(p)); 31 }); 32})(); 33 34/* Snap-scroll nav helper â finds next/prev child snap point */ 35function snapNavScroll(el,dir){ 36 var items=el.children;var cur=el.scrollLeft;var best=cur; 37 for(var i=0;i<items.length;i++){ 38 var off=items[i].offsetLeft-el.offsetLeft; 39 if(dir>0&&off>cur+2){best=off;break;} 40 if(dir<0&&off<cur-2){best=off;} 41 } 42 el.scrollTo({left:best,behavior:'smooth'}); 43} 44 45/* ============================================================ 46 ADDITIONAL.JS â per-project site interactions, one bundle. 47 The kit ships empty. Build interactions from scratch per project: 48 append each block as a self-contained IIFE that guards on element presence, 49 so loading this file on every page stays safe regardless of which blocks render. 50 51 Template: 52 (function(){ 53 'use strict'; 54 var nodes = document.querySelectorAll('[data-myblock]'); 55 if(!nodes.length) return; // guard: do nothing if block absent 56 // ... block behaviour ... 57 })(); 58 ============================================================ */ 59 60/* ââââ MOTION · reveal (shared) ââââ */ 61(function(){ 62 'use strict'; 63 var els = document.querySelectorAll('[data-reveal]'); 64 if(!els.length) return; 65 var reduce = matchMedia('(prefers-reduced-motion: reduce)').matches; 66 if(reduce || !('IntersectionObserver' in window)){ 67 els.forEach(function(e){ e.classList.add('is-in'); }); 68 return; 69 } 70 var io = new IntersectionObserver(function(ents){ 71 ents.forEach(function(en){ if(en.isIntersecting){ en.target.classList.add('is-in'); io.unobserve(en.target); } }); 72 }, {threshold:0.12, rootMargin:'0px 0px -8% 0px'});
73 els.forEach(function(e){ io.observe(e); }); 74 // safety: in throttled/unpainted/hidden iframes IO never fires AND CSS transitions 75 // are frozen â above-fold reveals fire near-instantly when painting, so if NONE have 76 // after a budget, hard-finalize visuals (no transition) + finalize counters. 77 setTimeout(function(){ 78 if(document.querySelectorAll('[data-reveal].is-in').length === 0){ 79 els.forEach(function(e){ e.style.transition='none'; e.classList.add('is-in'); e.style.opacity='1'; e.style.transform='none'; }); 80 document.querySelectorAll('[data-count]').forEach(function(n){ n.textContent = parseFloat(n.getAttribute('data-count')).toLocaleString('ru-RU'); }); 81 } 82 }, 1400); 83})(); 84 85/* ââââ _header · sticky shadow + search + drawer ââââ */ 86(function(){ 87 'use strict'; 88 var hdr = document.querySelector('.hdr'); 89 if(hdr){ 90 var sy = function(){ return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; }; 91 // fixed header â reserve its height so content isn't hidden underneath 92 var setPad = function(){ var h = hdr.offsetHeight; document.body.style.paddingTop = h + 'px'; document.documentElement.style.setProperty('--hdr-h', h + 'px'); }; 93 setPad(); 94 window.addEventListener('resize', setPad); 95 if(window.requestAnimationFrame) requestAnimationFrame(setPad); 96 var lastY = sy(), ticking = false; 97 var onScrollDir = function(){ 98 var y = sy(); 99 if(Math.abs(y - lastY) > 6){ // ignore jitter 100 if(y > lastY && y > 140){ hdr.classList.add('hdr--up'); } // scrolling down 101 else { hdr.classList.remove('hdr--up'); } // scrolling up 102 lastY = y; 103 } 104 ticking = false; 105 }; 106 window.addEventListener('scroll', function(){ 107 if(!ticking){ requestAnimationFrame(onScrollDir); ticking = true; } 108 }, {passive:true}); 109 } 110 var ovl = document.querySelector('[data-search]'); 111 document.querySelectorAll('[data-search-open]').forEach(function(b){ 112 b.addEventListener('click', function(){ if(ovl){ ovl.classList.add('is-open'); var f=ovl.querySelector('input'); if(f) setTimeout(function(){f.focus();},120); } }); 113 }); 114 document.querySelectorAll('[data-search-close]').forEach(function(b){ 115 b.addEventListener('click', function(){ if(ovl) ovl.classList.remove('is-open'); }); 116 }); 117 var drw = document.querySelector('[data-drawer]'); 118 var scrim = document.querySelector('[data-mega-scrim]'); 119 var toggles = document.querySelectorAll('[data-drawer-toggle]'); 120 var setMega = function(open){ 121 if(drw) drw.classList.toggle('is-open', open); 122 if(scrim) scrim.classList.toggle('is-open', open); 123 toggles.forEach(function(b){ b.classList.toggle('is-x', open); }); 124 }; 125 toggles.forEach(function(b){ 126 b.addEventListener('click', function(){ setMega(!(drw && drw.classList.contains('is-open'))); }); 127 }); 128 if(scrim) scrim.addEventListener('click', function(){ setMega(false); }); 129 // offers page filter (бÑенд, multi-select toggle; напÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑÐ°Ð·Ð²ÐµÐ´ÐµÐ½Ñ Ð¿Ð¾ гÑÑппам) 130 (function(){ 131 var root = document.querySelector('[data-offers-filter]'); 132 if(!root) return; 133 var activeBrands = new Set(); 134 var activeDirs = new Set(); 135 var cards = root.querySelectorAll('.ocard'); 136 var empty = root.querySelector('.offers-empty'); 137 var groups = root.querySelectorAll('[data-of-group]'); 138 function apply(){ 139 var shown = 0; 140 cards.forEach(function(c){ 141 var b = c.getAttribute('data-brand'), d = c.getAttribute('data-dir'); 142 var brandOk = activeBrands.size === 0 || activeBrands.has(b); 143 var dirOk = activeDirs.size === 0 || activeDirs.has(d); 144 var ok = brandOk && dirOk; 145 if(ok){ 146 shown++; 147 if(c.classList.contains('is-gone')){ 148 c.classList.remove('is-gone'); 149 requestAnimationFrame(function(){ requestAnimationFrame(function(){ c.classList.remove('is-fade'); }); }); 150 } else { 151 c.classList.remove('is-fade'); 152 } 153 } else { 154 if(!c.classList.contains('is-gone')){ 155 c.classList.add('is-fade'); 156 setTimeout(function(){ if(c.classList.contains('is-fade')) c.classList.add('is-gone'); }, 350); 157 } 158 } 159 }); 160 // гÑÑппа Ñеликом ÑÑ Ð¾Ð´Ð¸Ñ, еÑли в ней не оÑÑалоÑÑ Ð²Ð¸Ð´Ð¸Ð¼ÑÑ ÐºÐ°ÑÑоÑек 161 groups.forEach(function(g){ 162 var vis = 0; 163 g.querySelectorAll('.ocard').forEach(function(c){ 164 var b = c.getAttribute('data-brand'); 165 if(activeBrands.size === 0 || activeBrands.has(b)) vis++; 166 }); 167 g.classList.toggle('is-gone', vis === 0); 168 var cnt = g.querySelector('.ofgroup__count'); 169 if(cnt) cnt.textContent = vis; 170 }); 171 if(empty) empty.classList.toggle('is-on', shown===0); 172 } 173 root.querySelectorAll('[data-of-brand]').forEach(function(b){ 174 b.addEventListener('click', function(){ 175 var val = b.getAttribute('data-of-brand'); 176 if(activeBrands.has(val)){ activeBrands.delete(val); b.classList.remove('is-on'); } 177 else { activeBrands.add(val); b.classList.add('is-on'); } 178 apply(); 179 }); 180 }); 181 root.querySelectorAll('[data-of-dir]').forEach(function(b){ 182 b.addEventListener('click', function(){ 183 var val = b.getAttribute('data-of-dir'); 184 if(activeDirs.has(val)){ activeDirs.delete(val); b.classList.remove('is-on'); } 185 else { activeDirs.add(val); b.classList.add('is-on'); } 186 apply(); 187 }); 188 }); 189 apply(); 190 })(); 191 // contact dealer-center switch (data-driven) 192 (function(){ 193 var tabs = document.querySelector('[data-dc-tabs]'); 194 if(!tabs) return; 195 var DC = { 196 kgm: {title:'ÐилеÑÑкий ÑенÑÑ Â«ÐвÑобаÑ» · KGM', addr:'г. ÐладимиÑ, Ñл. Ðакина, 4 Ð', tel:'+74922474670', phone:'+7 (4922) 47-46-70', email:'[email protected]', hours:'ÐнâÐÑ: 09:00â20:00', badge:'Ñл. Ðакина, 4 Ð', px:'50%', py:'50%', gx:'0px', gy:'0px'}, 197 bestune:{title:'ÐилеÑÑкий ÑенÑÑ Â«ÐвÑобаÑ» · BESTUNE', addr:'г. ÐладимиÑ, СÑздалÑÑкий пÑ-Ñ, 16', tel:'+74922112233', phone:'+7 (4922) 11-22-33', email:'[email protected]', hours:'ÐнâÐÑ: 09:00â19:00 · СбâÐ
197Ñ: 10:00â17:00', badge:'СÑздалÑÑкий пÑ-Ñ, 16', px:'32%', py:'62%', gx:'-46px', gy:'-23px'}, 198 swm: {title:'ÐилеÑÑкий ÑенÑÑ Â«ÐвÑобаÑ» · SWM', addr:'г. ÐладимиÑ, Ñл. Ðакина, 4 Ð', tel:'+74922474670', phone:'+7 (4922) 47-46-70', email:'[email protected]', hours:'ÐнâÐÑ: 09:00â20:00', badge:'Ñл. Ðакина, 4 Ð', px:'58%', py:'44%', gx:'23px', gy:'0px'}, 199 vgv: {title:'ÐилеÑÑкий ÑенÑÑ Â«ÐвÑобаÑ» · VGV', addr:'г. ÐладимиÑ, Ñл. Ðакина, 4 Ð', tel:'+74922474670', phone:'+7 (4922) 47-46-70', email:'[email protected]', hours:'ÐнâÐÑ: 09:00â20:00', badge:'Ñл. Ðакина, 4 Ð', px:'46%', py:'56%', gx:'0px', gy:'-23px'}, 200 vw: {title:'СеÑÐ²Ð¸Ñ Volkswagen · ÐвÑобаÑ', addr:'г. ÐладимиÑ, Ñл. Ðакина, 4 Ð', tel:'+74922474670', phone:'+7 (4922) 47-46-70', email:'[email protected]', hours:'ÐнâСб: 08:00â20:00', badge:'СеÑÐ²Ð¸Ñ VW · Ñл. Ðакина, 4 Ð', px:'52%', py:'48%', gx:'0px', gy:'0px'} 201 }; 202 var elTitle=document.querySelector('[data-c-title]'), 203 elAddr=document.querySelector('[data-c-addr]'), 204 elPhone=document.querySelector('[data-c-phone]'), 205 elEmail=document.querySelector('[data-c-email]'), 206 elHours=document.querySelector('[data-c-hours]'), 207 elBadge=document.querySelector('[data-c-badge]'), 208 pin=document.querySelector('.cmap__pin'), 209 grid=document.querySelector('.cmap__grid'); 210 function apply(k){ 211 var d=DC[k]; if(!d) return; 212 var card=document.querySelector('[data-c-card]'); 213 var fade=[card,elBadge]; 214 fade.forEach(function(el){ if(el) el.classList.add('dc-fade'); }); 215 setTimeout(function(){ 216 if(elTitle) elTitle.textContent=d.title; 217 if(elAddr) elAddr.textContent=d.addr; 218 if(elPhone){ elPhone.textContent=d.phone; elPhone.setAttribute('href','tel:'+d.tel); } 219 if(elEmail){ elEmail.textContent=d.email; elEmail.setAttribute('href','mailto:'+d.email); } 220 if(elHours) elHours.textContent=d.hours; 221 if(elBadge){ elBadge.textContent=d.badge; elBadge.style.left=d.px; elBadge.style.top=d.py; } 222 if(pin){ pin.style.left=d.px; pin.style.top=d.py; } 223 if(grid){ grid.style.backgroundPosition=d.gx+' '+d.gy; } 224 fade.forEach(function(el){ if(el) el.classList.remove('dc-fade'); }); 225 }, 280); 226 } 227 tabs.addEventListener('click', function(e){ 228 var chip=e.target.closest('.cpill'); if(!chip) return; 229 tabs.querySelectorAll('.cpill').forEach(function(c){ c.classList.toggle('is-on', c===chip); }); 230 apply(chip.getAttribute('data-dc')); 231 }); 232 })(); 233 // brand filter tabs (ÐÑе / ÐовÑе / С пÑобегом) 234 document.querySelectorAll('[data-brandfilter]').forEach(function(sec){ 235 var tabs = sec.querySelector('[data-tabs]'); 236 var cards = sec.querySelectorAll('.brandcard'); 237 var used = sec.querySelector('[data-used]'); 238 if(!tabs) return; 239 tabs.addEventListener('click', function(e){ 240 var b = e.target.closest('.ptab'); if(!b) return; 241 var f = b.getAttribute('data-filter'); 242 cards.forEach(function(c){ c.style.display = (f === 'used') ? 'none' : ''; }); 243 if(used) used.style.display = (f === 'new') ? 'none' : ''; 244 }); 245 }); 246 // mobile sheet: collapsible sections (accordion) 247 document.querySelectorAll('.mega__col > h4').forEach(function(h){ 248 h.addEventListener('click', function(){ h.parentElement.classList.toggle('is-exp'); }); 249 }); 250 if(drw) drw.querySelectorAll('a,[data-drawer-close]').forEach(function(a){ 251 a.addEventListener('click', function(){ setMega(false); }); 252 }); 253 document.addEventListener('keydown', function(e){ 254 if(e.key==='Escape'){ if(ovl) ovl.classList.remove('is-open'); setMega(false); } 255 }); 256})(); 257 258/* ââââ block_faq · accordion ââââ */ 259(function(){ 260 'use strict'; 261 var items = document.querySelectorAll('.faq__item'); 262 if(!items.length) return; 263 items.forEach(function(item){ 264 var q = item.querySelector('.faq__q'); 265 var a = item.querySelector('.faq__a'); 266 if(!q || !a) return; 267 q.addEventListener('click', function(){ 268 var open = item.classList.contains('is-open'); 269 var scope = item.closest('.faq') || document; 270 scope.querySelectorAll('.faq__item.is-open').forEach(function(o){ 271 if(o!==item){ o.classList.remove('is-open'); var oa=o.querySelector('.faq__a'); if(oa) oa.style.height='0px'; } 272 }); 273 if(open){ item.classList.remove('is-open'); a.style.height='0px'; } 274 else { item.classList.add('is-open'); a.style.height = a.firstElementChild.offsetHeight + 'px'; } 275 }); 276 }); 277})(); 278 279/* ââââ block_stats · counters ââââ */ 280(function(){ 281 'use strict'; 282 var nums = document.querySelectorAll('[data-count]'); 283 if(!nums.length) return; 284 function run(el){ 285 var to = parseFloat(el.getAttribute('data-count')), dur = 1500, t0 = null; 286 function step(ts){ 287 if(!t0) t0 = ts; 288 var p = Math.min((ts - t0)/dur, 1), e = 1 - Math.pow(1-p,3);
289 el.textContent = Math.round(to*e).toLocaleString('ru-RU'); 290 if(p<1) requestAnimationFrame(step); 291 } 292 requestAnimationFrame(step); 293 } 294 if(!('IntersectionObserver' in window)){ nums.forEach(function(n){ n.textContent = parseFloat(n.getAttribute('data-count')).toLocaleString('ru-RU'); }); return; } 295 var io = new IntersectionObserver(function(ents){ 296 ents.forEach(function(en){ if(en.isIntersecting){ run(en.target); io.unobserve(en.target); } }); 297 }, {threshold:0.5}); 298 nums.forEach(function(n){ io.observe(n); }); 299 // safety: if values never animated (rAF/IO frozen in hidden iframe), finalize 300 setTimeout(function(){ 301 var first = document.querySelector('[data-count]'); 302 if(first && first.textContent === '0'){ 303 nums.forEach(function(n){ n.textContent = parseFloat(n.getAttribute('data-count')).toLocaleString('ru-RU'); }); 304 } 305 }, 2600); 306})(); 307 308/* ââââ block_hero · subtle media parallax ââââ */ 309(function(){ 310 'use strict'; 311 var els = document.querySelectorAll('[data-parallax]'); 312 if(!els.length || matchMedia('(prefers-reduced-motion: reduce)').matches) return; 313 window.addEventListener('scroll', function(){ 314 var y = window.scrollY; 315 els.forEach(function(el){ var s = parseFloat(el.getAttribute('data-parallax'))||0.06; el.style.transform = 'translate3d(0,'+(y*s)+'px,0)'; }); 316 }, {passive:true}); 317})(); 318 319/* ââââ pill tabs (visual toggle) ââââ */ 320(function(){ 321 'use strict'; 322 var groups = document.querySelectorAll('[data-tabs]'); 323 if(!groups.length) return; 324 groups.forEach(function(g){ 325 g.addEventListener('click', function(e){ 326 var t = e.target.closest('.ptab'); 327 if(!t || !g.contains(t)) return; 328 g.querySelectorAll('.ptab').forEach(function(b){ b.classList.toggle('is-on', b===t); }); 329 }); 330 }); 331})(); 332 333/* ââââ type carousel ââââ */ 334(function(){ 335 'use strict'; 336 var scrollers = document.querySelectorAll('[data-tscroll]'); 337 if(!scrollers.length) return; 338 scrollers.forEach(function(track){ 339 var wrap = track.closest('[data-tscroll-wrap]') || track.parentElement; 340 var step = function(){ var c = track.querySelector('*'); return c ? c.getBoundingClientRect().width + 16 : 240; }; 341 var prev = wrap.querySelector('[data-tscroll-prev]'); 342 var next = wrap.querySelector('[data-tscroll-next]'); 343 function snapNav(dir){ 344 var items = track.children; 345 var tRect = track.getBoundingClientRect(); 346 var cur = track.scrollLeft; 347 var best = cur; 348 for(var i=0;i<items.length;i++){ 349 var off = items[i].offsetLeft - track.offsetLeft; 350 if(dir>0 && off > cur+2){ best=off; break; } 351 if(dir<0 && off < cur-2){ best=off; } 352 } 353 track.scrollTo({left:best, behavior:'smooth'}); 354 } 355 if(prev) prev.addEventListener('click', function(){ snapNav(-1); }); 356 if(next) next.addEventListener('click', function(){ snapNav(1); }); 357 // Mouse drag to scroll 358 var down=false,sx=0,sl=0,dragged=false; 359 track.addEventListener("mousedown",function(e){down=true;dragged=false;sx=e.pageX;sl=track.scrollLeft;track.style.cursor="grabbing";}); 360 track.addEventListener("mousemove",function(e){if(!down)return;e.preventDefault();var dx=e.pageX-sx;if(Math.abs(dx)>5)dragged=true;track.scrollLeft=sl-dx;}); 361 track.addEventListener("mouseup",function(){down=false;track.style.cursor="";}); 362 track.addEventListener("mouseleave",function(){down=false;track.style.cursor="";}); 363 track.addEventListener("click",function(e){if(dragged){e.preventDefault();e.stopPropagation();dragged=false;}},true); 364 365 }); 366})(); 367 368/* ââââ hero variant switcher (preview) ââââ */ 369(function(){ 370 'use strict'; 371 var sw = document.querySelector('[data-vswitch]'); 372 if(!sw) return; 373 var heroes = document.querySelectorAll('[data-hero-variant]'); 374 function show(n){ 375 heroes.forEach(function(h){ h.hidden = (h.getAttribute('data-hero-variant') !== String(n)); }); 376 sw.querySelectorAll('button').forEach(function(b){ b.classList.toggle('is-on', b.getAttribute('data-hero')===String(n)); }); 377 var active = document.querySelector('[data-hero-variant="'+n+'"]'); 378 if(active) active.querySelectorAll('[data-reveal]').forEach(function(e){ e.style.transition='none'; e.classList.add('is-in'); e.style.opacity='1'; e.style.transform='none'; }); 379 try{ localStorage.setItem('autobat_hero', n); }catch(e){} 380 } 381 sw.addEventListener('click', function(e){ 382 var b = e.target.closest('button[data-hero]'); if(!b) return; 383 show(b.getAttribute('data-hero')); 384 window.scrollTo({top:0,behavior:'smooth'}); 385 }); 386 var saved = '1'; try{ saved = localStorage.getItem('autobat_hero') || '1'; }catch(e){} 387 show(saved); 388})(); 389 390/* ââââ banner slider (V1/V2) â supports multiple ââââ */ 391(function(){ 392 'use strict';
393 var roots = document.querySelectorAll('[data-slider]'); 394 if(!roots.length) return; 395 roots.forEach(function(root){ 396 var track = root.querySelector('.slides'); 397 var slides = root.querySelectorAll('.slide'); 398 var dotsBox = root.querySelector('[data-dots]'); 399 var i = 0, timer = null, n = slides.length; 400 if(dotsBox){ 401 for(var d=0; d<n; d++){ 402 var dot = document.createElement('button'); 403 dot.className = 'sl-dot' + (d===0?' is-on':''); 404 dot.setAttribute('aria-label','Слайд '+(d+1)); 405 (function(idx){ dot.addEventListener('click', function(){ go(idx); reset(); }); })(d); 406 dotsBox.appendChild(dot); 407 } 408 } 409 var dots = dotsBox ? dotsBox.querySelectorAll('.sl-dot') : []; 410 function go(idx){ i = (idx+n)%n; track.style.transform = 'translateX(-'+(i*100)+'%)'; dots.forEach(function(x,k){ x.classList.toggle('is-on',k===i); }); } 411 function next(){ go(i+1); } function prev(){ go(i-1); } 412 function play(){ clearInterval(timer); timer = setInterval(next, 7500); } 413 function reset(){ play(); } 414 var nb = root.querySelector('[data-next]'), pb = root.querySelector('[data-prev]'); 415 if(nb) nb.addEventListener('click', function(){ next(); reset(); }); 416 if(pb) pb.addEventListener('click', function(){ prev(); reset(); }); 417 root.addEventListener('mouseenter', function(){ clearInterval(timer); }); 418 root.addEventListener('mouseleave', play); 419 document.addEventListener('visibilitychange', function(){ if(document.hidden){ clearInterval(timer); } else { play(); } }); 420 var touchX0 = null; 421 track.addEventListener('touchstart', function(e){ touchX0 = e.touches[0].clientX; }, {passive:true}); 422 track.addEventListener('touchend', function(e){ 423 if(touchX0 === null) return; 424 var dx = e.changedTouches[0].clientX - touchX0; 425 touchX0 = null; 426 if(Math.abs(dx) < 40) return; 427 if(dx < 0) next(); else prev(); 428 reset(); 429 }); 430 play(); 431 }); 432})(); 433 434/* ââââ credit calculator (hero CTA) ââââ */ 435(function(){ 436 'use strict'; 437 var box = document.querySelector('[data-calc]'); 438 if(!box) return; 439 var range = box.querySelector('.crange'); 440 var payEl = box.querySelector('[data-calc-pay]'); 441 var bubble = box.querySelector('[data-calc-years]'); 442 var amount = parseFloat(box.getAttribute('data-amount')) || 2000000; 443 var rate = (parseFloat(box.getAttribute('data-rate')) || 12) / 100 / 12; 444 function plural(y){ var m=y%10,d=y%100; if(m===1&&d!==11) return 'год'; if(m>=2&&m<=4&&(d<10||d>=20)) return 'года'; return 'леÑ'; } 445 function fmt(v){ return Math.round(v).toLocaleString('ru-RU'); } 446 function update(){ 447 var years = parseInt(range.value,10); 448 var nM = years*12; 449 var pay = amount * (rate*Math.pow(1+rate,nM)) / (Math.pow(1+rate,nM)-1); 450 if(payEl) payEl.textContent = 'ÐÑ ' + fmt(pay) + ' â½/меÑ'; 451 if(bubble) bubble.textContent = years + ' ' + plural(years); 452 var pct = (years - range.min) / (range.max - range.min) * 100; 453 range.style.background = 'linear-gradient(90deg, var(--color-accent) '+pct+'%, hsla(0,0%,100%,.2) '+pct+'%)'; 454 } 455 range.addEventListener('input', update); 456 update(); 457})(); 458 459;(function () { 460 if (!('ontouchstart' in window)) return; 461 var sx = 0, sy = 0, st = 0, moved = false, tracking = false, pending = null, timer = null; 462 function clear() { if (timer) { clearTimeout(timer); timer = null; } pending = null; } 463 function onStart(e) { 464 if (e.touches && e.touches.length > 1) { tracking = false; return; } 465 var t = e.changedTouches[0]; 466 sx = t.clientX; sy = t.clientY; st = e.timeStamp; moved = false; tracking = true; 467 } 468 function onMove(e) { 469 if (!tracking) return; 470 var t = e.changedTouches[0]; 471 if (Math.abs(t.clientX - sx) > 8 || Math.abs(t.clientY - sy) > 8) moved = true; 472 } 473 function onEnd(e) { 474 if (!tracking) return; 475 tracking = false; 476 if (moved || e.timeStamp - st > 700) return; 477 if (!e.target || !e.target.closest) return; 478 var link = e.target.closest('a.carousel__item, .carousel__item a[href]'); 479 if (!link || !link.closest('.js-carousel')) return; 480 var href = link.getAttribute('href'); 481 if (!href || href.charAt(0) === '#') return; 482 clear(); 483 pending = { href: href, blank: link.getAttribute('target') === '_blank' }; 484 timer = setTimeout(function () { 485 var p = pending; clear(); 486 if (!p) return; 487 if (p.blank) window.open(p.href, '_blank'); else window.location.href = p.href; 488 }, 120); 489 } 490 function onClick() { clear(); } 491 document.addEventListener('touchstart', onStart, { passive: true }); 492 document.addEventListener('touchmove', onMove, { passive: true }); 493 document.addEventListener('touchend', onEnd, { passive: true }); 494 document.addEventListener('click', onClick, true); 495})(); 496 497// Ðлок «Ðидео 9:16»: пÑевÑÑ ÐºÑÑÑиÑÑÑ Ð±ÐµÐ· звÑка, когда каÑÑоÑка в зоне видимоÑÑи;
498// клик оÑкÑÑÐ²Ð°ÐµÑ Ð¾Ð±ÑÑÑ Ð¼Ð¾Ð´Ð°Ð»ÐºÑ #modal-video (ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ ModalVideo из main.js). 499(function () { 500 var cards = document.querySelectorAll('.vvid__card .vvid__media'); 501 if (!cards.length) return; 502 var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches; 503 // пÑевÑÑ ÐºÑÑÑим ÑолÑко на деÑкÑопе: на мобилÑнÑÑ ÑÑо лиÑний ÑÑаÑик, Ñам пеÑвÑй ÐºÐ°Ð´Ñ + кнопка play 504 var conn = navigator.connection || {}; 505 var canPreview = window.matchMedia('(hover: hover) and (pointer: fine)').matches && !conn.saveData; 506 507 if (!reduce && canPreview && 'IntersectionObserver' in window) { 508 var io = new IntersectionObserver(function (entries) { 509 entries.forEach(function (e) { 510 var v = e.target; 511 if (e.isIntersecting) { var p = v.play(); if (p && p.catch) p.catch(function () {}); } 512 else v.pause(); 513 }); 514 }, { threshold: 0.4 }); 515 cards.forEach(function (v) { io.observe(v); }); 516 } 517 518 // в модалке видео ÑÑаÑÑÑÐµÑ Ñамо â оÑкÑÑÑие Ñже бÑло жеÑÑом полÑзоваÑÐµÐ»Ñ 519 var modal = document.getElementById('modal-video'); 520 if (modal) { 521 var media = modal.querySelector('.js-modal-video__media'); 522 if (media) { 523 media.addEventListener('loadedmetadata', function () { 524 var p = media.play(); 525 if (p && p.catch) p.catch(function () {}); 526 }); 527 modal.addEventListener('modalIsClose', function () { media.pause(); }); 528 } 529 } 530})();
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.