PageSourceSearch

https://sigma-service.ru/site/templates/scripts/cars.js?v=2011

js sigma-service.ru collected 2026-10-08 08:03:09 UTC 26,256 bytes, 657 lines download raw bytes

1document.addEventListener("DOMContentLoaded", function () {
2
3  const form = document.querySelector(".js-adv-filter__form");
4  if(form){
5    const container = document.querySelector("#adv-filter-gallery");
6    const phoneNum = container ? container.getAttribute('data-phone') : '';
7    const spinner = document.getElementById("loading-spinner");
8    const sortRadios = form.querySelectorAll('input[name="sort"]');
9    const countFilter = document.querySelector(".js-adv-filter__results-count");
10    const filterPanel = document.querySelector("#filter-panel");
11
12    let currentPage = 1;
13    let loading = false;
14    let allLoaded = false;
15    let abortController = null;
16    let currentRequestId = 0;
17
18    const priceMinInput = form.querySelector('input[name="price-min-value"]');
19    const priceMaxInput = form.querySelector('input[name="price-max-value"]');
20    const yearMinInput = form.querySelector('input[name="year-min-value"]');
21    const yearMaxInput = form.querySelector('input[name="year-max-value"]');
22
23    const manualInputFlags = {
24      priceMin: false,
25      priceMax: false,
26      yearMin: false,
27      yearMax: false,
28    };
29
30    const urlParams = new URLSearchParams(window.location.search);
31    const paramMap = {
32      'price-min-value': { input: priceMinInput, flag: 'priceMin' },
33      'price-max-value': { input: priceMaxInput, flag: 'priceMax' },
34      'year-min-value': { input: yearMinInput, flag: 'yearMin' },
35      'year-max-value': { input: yearMaxInput, flag: 'yearMax' },
36    };
37    for (const [param, cfg] of Object.entries(paramMap)) {
38      const val = urlParams.get(param);
39      if (val && cfg.input) {
40        cfg.input.value = val;
41        manualInputFlags[cfg.flag] = true;
42      }
43    }
44
45    const inputs = [
46      { el: priceMinInput, key: 'priceMin' },
47      { el: priceMaxInput, key: 'priceMax' },
48      { el: yearMinInput, key: 'yearMin' },
49      { el: yearMaxInput, key: 'yearMax' },
50    ];
51
52    for (const { el, key } of inputs) {
53      el.addEventListener('input', () => {
54        manualInputFlags[key] = true;
55      });
56    }
57
58    var applyBtn = document.querySelector('[data-filter-apply]');
59    var resetBtnEl = document.querySelector('[data-filter-reset]');
60    function setBtnLoading(btn, on) {
61      if (!btn) return;
62      if (on) btn.classList.add('btn--loading');
63      else btn.classList.remove('btn--loading');
64    }
65
66    function animateCount(el, target) {
67      target = parseInt(target) || 0;
68      var start = parseInt(el.textContent) || 0;
69      if (start === target) { el.textContent = target; return; }
70      var dur = 400, t0 = null;
71      function step(ts) {
72        if (!t0) t0 = ts;
73        var p = Math.min((ts - t0) / dur, 1);
74        var ease = 1 - Math.pow(1 - p, 3);
75        el.textContent = Math.round(start + (target - start) * ease);
76        if (p < 1) requestAnimationFrame(step);
77      }
78      requestAnimationFrame(step);
79    }
80
81    const skelHtml = '<article class="vcard-skel"><div class="vcard-skel__media"></div><div class="vcard-skel__body"><div class="vcard-skel__line"></div><div class="vcard-skel__line vcard-skel__line--short"></div><div class="vcard-skel__specs"><div class="vcard-skel__spec"></div><div class="vcard-skel__spec"></div><div class="vcard-skel__spec"></div><div class="vcard-skel__spec"></div></div><div class="vcard-skel__line vcard-skel__line--xs"></div><div class="vcard-skel__btn"></div></div></article>';
82    function showSkeletons(){ container.innerHTML = skelHtml.repeat(6); }
83    function clearSkeletons(){ var skels = container.querySelectorAll('.vcard-skel'); skels.forEach(function(s){ s.remove(); }); }
84    const showSpinner = () => { if(!container.children.length) showSkeletons(); };
85    const hideSpinner = () => { clearSkeletons(); };
86
87    function buildFilterUrl() {
88      const slugFields = { drive: {}, transmission: {}, make: {}, state: {} };
89
90      document.querySelectorAll('input[name="make[]"]').forEach(input => {
91        slugFields.make[input.value] = input.dataset.slug;
92      });
93      document.querySelectorAll('input[name="drive[]"]').forEach(input => {
94        slugFields.drive[input.value] = input.dataset.slug;
95      });
96      document.querySelectorAll('input[name="transmission[]"]').forEach(input => {
97        slugFields.transmission[input.value] = input.dataset.slug;
98      });
99      document.querySelectorAll('input[name="state[]"]').forEach(input => {
100        slugFields.state[input.value] = input.dataset.slug;
101      });
102
103      const params = new URLSearchParams();
104      const slugs = [];
105      const formData = new FormData(form);
106      const selectedSort = form.querySelector('input[name="sort"]:checked');
107      if (selectedSort?.value) params.set("sort", selectedSort.value);
108
109      if (manualInputFlags.priceMin && priceMinInput?.value) {
110        params.set("price-min-value", priceMinInput.value);
111      }
112      if (manualInputFlags.priceMax && priceMaxInput?.value) {
113        params.set("price-max-value", priceMaxInput.value);
114      }
115      if (manualInputFlags.yearMin && yearMinInput?.value) {
116        params.set("year-min-value", yearMinInput.value);
117      }
118      if (manualInputFlags.yearMax && yearMaxInput?.value) {
119        params.set("year-max-value", yearMaxInput.value);
120      }
121
122      const selectedValues = { make: [], drive: [], transmission: [], state: [] };
123
124      for (const [key, value] of formData.entries()) {
125        if (!value) continue;
126
127        if (
128          (key === 'price-min-value' && manualInputFlags.priceMin) ||
129          (key === 'price-max-value' && manualInputFlags.priceMax) ||
130          (key === 'year-min-value' && manualInputFlags.yearMin) ||
131          (key === 'year-max-value' && manualInputFlags.yearMax)
132        ) {
133          continue;
134        }
135
136        if (key.endsWith('[]')) {
137          const field = key.replace('[]', '');
138          if (selectedValues.hasOwnProperty(field)) {
139            selectedValues[field].push(value);
140          } else {
141            params.append(key, value);
142          }
143        } else {
144          params.append(key, value);
145        }
146      }
147
148      for (const field of ["make", "transmission", "drive", "state"]) {
149        if (selectedValues[field].length === 1) {
150          slugs.push(slugFields[field][selectedValues[field][0]]);
151        } else if (selectedValues[field].length > 1) {
152          selectedValues[field].forEach(value => params.append(`${field}[]`, value));
153        }
154      }
155
156      let url = "/stock/";
157      if (slugs.length) url += slugs.join("/") + "/";
158      const queryString = params.toString();
159      if (queryString) url += "?" + queryString;
160
161      return url;
162    }
163
164    function updateUrl() {
165      const newUrl = buildFilterUrl();
166      window.history.pushState(null, "", newUrl);
167    }
168
169    let apiData = null;
170
171    async function loadProducts(page = 1) {
172      if (loading || allLoaded) return;
173
174      if (abortController) abortController.abort();
175      abortController = new AbortController();
176
177      currentRequestId++;
178      const requestId = currentRequestId;
179
180      loading = true;
181      showSpinner();
182
183      try {
184        const url = `/site-api/get-autos/?${getParams(page, apiData)}`;
185        const response = await fetch(url, { signal: abortController.signal });
186
187        if (!response.ok) throw new Error('Network response was not ok');
188        const res = await response.json();
189        if (requestId !== currentRequestId) return;
190
191        if (!res.success) throw new Error('API response was not successful');
192
193        if (res.ranges) {
194          apiData = res.ranges;
195
196          if (priceMinInput && !manualInputFlags.priceMin) priceMinInput.value = apiData.minPrice || '';
197          if (priceMaxInput && !manualInputFlags.priceMax) priceMaxInput.value = apiData.maxPrice || '';
198          if (yearMinInput && !manualInputFlags.yearMin) yearMinInput.value = apiData.minYear || '';
199          if (yearMaxInput && !manualInputFlags.yearMax) yearMaxInput.value = apiData.maxYear || '';
200
201          priceMinInput?.dispatchEvent(new Event('input'));
202          priceMaxInput?.dispatchEvent(new Event('input'));
203          yearMinInput?.dispatchEvent(new Event('input'));
204          yearMaxInput?.dispatchEvent(new Event('input'));
205
206          updateUrl();
207        }
208
209        if (page === 1) {
210
211          var oldCards = container.querySelectorAll('.vcard');
212          oldCards.forEach(function(c){ c.style.opacity='0'; c.style.transform='translateY(10px)'; });
213          await new Promise(function(r){ setTimeout(r, oldCards.length ? 250 : 0); });
214          container.innerHTML = "";
215          allLoaded = false;
216        }
217
218        if (res.products.length === 0) {
219          allLoaded = true;
220          if (page === 1) {
221            animateCount(countFilter, 0);
222            container.innerHTML = "<p>Нет товаров по выбранным фильтрам.</p>";
223          }
224          return;
225        }
226
227        const fragment = document.createDocumentFragment();
228        res.products.forEach(product => {
229          const el = document.createElement('article');
230          el.className = "vcard vcard--entering";
231          const totalDiscount = (product.CreditDiscount || 0) + (product.InsuranceDiscount || 0) + (product.TradeinDiscount || 0);
232          const rawPrice = Number(String(product.Price).replace(/\s/g, ''));
233          const priceFmt = rawPrice.toLocaleString('ru');
234          const finalPrice = totalDiscount ? (rawPrice - totalDiscount).toLocaleString('ru') : priceFmt;
235          const mileageNum = Number(product.Mileage) || 0;
236          const powerMatch = (product.Modification || '').match(/\((\d+)\s*л\.?\s*с\.?\)/);
237          const powerText = powerMatch ? powerMatch[1] + ' л.с.' : '';
238          var _volN = (product.EngineValue && Number(product.EngineValue) > 0) ? product.EngineValue : '';
239          if (!_volN) {
240            var _ms = String(product.Modification || '');
241
242            var _vm = _ms.match(/^\s*(\d(?:[.,]\d)?)\b/) || _ms.match(/\b(\d[.,]\d)\b/);
243            if (_vm) _volN = _vm[1].replace(',', '.');
244          }
245          const volText = _volN ? (_volN + ' л') : (product.Engine || '');
246          const engineText = volText + (powerText ? ' (' + powerText + ')' : '');
247
248          const CREDIT_DOWN = 0.5, CREDIT_TERM = 96, CREDIT_RATE = 0.03;
249          const _cr = CREDIT_RATE / 12, _fin = rawPrice * (1 - CREDIT_DOWN);
250          const monthly = _cr > 0 ? Math.round(_fin * _cr / (1 - Math.pow(1 + _cr, -CREDIT_TERM))) : Math.round(_fin / CREDIT_TERM);
251          const trim = [product.Complectation, product.Modification].filter(
251Boolean).join(' ');
252          const trimLine = trim + (product.Year ? ((trim ? ', ' : '') + product.Year + ' год') : '');
253          const company = product.Company || 'AAA MOTORS, Ростов-на-Дону';
254
255          const specRows = [
256            ['Пробег', mileageNum > 0 ? mileageNum.toLocaleString('ru') + ' км' : ''],
257            ['Двигатель', engineText],
258            ['Коробка', product.Transmission || ''],
259            ['Привод', product.Drive || '']
260          ];
261          const specsHtml = specRows
262            .filter(function(r){ return r[1]; })
263            .map(function(r){ return '<li><span>' + r[0] + '</span><b>' + r[1] + '</b></li>'; })
264            .join('');
265          el.innerHTML = `
266            <div class="vcard__media">
267              ${product.image}
268              ${totalDiscount ? '<span class="vcard__save">Выгода ' + totalDiscount.toLocaleString('ru') + ' ₽</span>' : ''}
269              <span class="vcard__state">${product.State}</span>
270            </div>
271            <div class="vcard__body">
272              <span class="vcard__accent" aria-hidden="true"></span>
273              <h3 class="vcard__name">${product.Make} ${product.Model}</h3>
274              <p class="vcard__trim">${trimLine}</p>
275              <ul class="vspecs vspecs--list">${specsHtml}</ul>
276              <div class="vcard__pricebox">
277                <div class="vcard__price">${finalPrice} ₽</div>
278                ${totalDiscount ? '<div class="vcard__old">' + priceFmt + ' ₽</div>' : ''}
279              </div>
280              <div class="vcard__foot">
281                <a class="btn btn--primary width-100%" href="${product.URL}"><span>Подробнее</span></a>
282                <button type="button" class="vcard__call" aria-controls="form-callback-opener" aria-label="Заказать звонок"><svg width="20" height="20"><use href="#i-phone"></use></svg></button>
283              </div>
284              <a class="vcard__link" href="${product.URL}" aria-label="${product.Model}"></a>
285            </div>
286          `;
287          fragment.appendChild(el);
288        });
289
290        container.appendChild(fragment);
291
292        var newCards = container.querySelectorAll('.vcard--entering');
293        newCards.forEach(function(c, i){
294          setTimeout(function(){ c.classList.remove('vcard--entering'); }, i * 40);
295        });
296
297        animateCount(countFilter, res.total);
298      } catch (err) {
299        if (err.name !== 'AbortError') {
300          console.error("Fetch error:", err);
301          if (page === 1) {
302            container.innerHTML = "<p>Ошибка загрузки товаров.</p>";
303          }
304          allLoaded = true;
305        }
306      } finally {
307        hideSpinner();
308        loading = false;
309        abortController = null;
310      }
311    }
312
313    function getParams(page = 1, apiData = null) {
314      const params = new URLSearchParams();
315
316      if (priceMinInput) {
317        if (manualInputFlags.priceMin) {
318          params.set('price-min-value', priceMinInput.value);
319        } else if (apiData?.minPrice != null) {
320          params.set('price-min-value', apiData.minPrice);
321        }
322      }
323
324      if (priceMaxInput) {
325        if (manualInputFlags.priceMax) {
326          params.set('price-max-value', priceMaxInput.value);
327        } else if (apiData?.maxPrice != null) {
328          params.set('price-max-value', apiData.maxPrice);
329        }
330      }
331
332      if (yearMinInput) {
333        if (manualInputFlags.yearMin) {
334          params.set('year-min-value', yearMinInput.value);
335        } else if (apiData?.minYear != null) {
336          params.set('year-min-value', apiData.minYear);
337        }
338      }
339
340      if (yearMaxInput) {
341        if (manualInputFlags.yearMax) {
342          params.set('year-max-value', yearMaxInput.value);
343        } else if (apiData?.maxYear != null) {
344          params.set('year-max-value', apiData.maxYear);
345        }
346      }
347
348      const formData = new FormData(form);
349      for (const [key, value] of formData.entries()) {
350        if (!value) continue;
351        if (key.endsWith('[]')) {
352          params.append(key, value);
353        } else {
354          params.set(key, value);
355        }
356      }
357
358      params.set('page', page);
359      return params.toString();
360    }
361
362    async function fetchAndApplyRanges() {
363      const baseFormData = new FormData(form);
364      baseFormData.delete('price-min-value');
365      baseFormData.delete('price-max-value');
366      baseFormData.delete('year-min-value');
367      baseFormData.delete('year-max-value');
368
369      const baseParams = new URLSearchParams(baseFormData);
370      baseParams.set('page', 1);
371
372      try {
373        const resRanges = await fetch(`/site-api/get-autos/?${baseParams.toString()}`);
374        const rangesData = await resRanges.json();
375        if (rangesData.success && rangesData.ranges) {
376          apiData = rangesData.ranges;
377
378          if (priceMinInput && !manualInputFlags.priceMin) priceMinInput.value = apiData.minPrice || '';
379          if (priceMaxInput && !manualInputFlags.priceMax) priceMaxInput.value = apiData.maxPrice || '';
380          if (yearMinInput && !manualInputFlags.yearMin) yearMinInput.value = apiData.minYear || '';
381          if (yearMaxInput && !manualInputFlags.yearMax) yearMaxInput.value = apiData.maxYear || '';
382
383          priceMinInput.dispatchEvent(new Event('input'));
384          priceMaxInput.dispatchEvent(new Event('input'));
385          yearMinInput.dispatchEvent(new Event('input'));
386          yearMaxInput.dispatchEvent(new Event('input'));
387        }
388      } catch (err) {
389        console.error("Ошибка при получении диапазонов:", err);
390      }
391    }
392
393    form.addEventListener("submit", async (e) => {
394      e.preventDefault();
395      currentPage = 1;
396      allLoaded = false;
397      apiData = null;
398
399      setBtnLoading(applyBtn, true);
400      filterPanel.classList.remove("sidebar--is-visible");
401
402      await fetchAndApplyRanges();
403      await loadProducts(currentPage);
404      setBtnLoading(applyBtn, false);
405
406      const filters = {};
407
408      ["make", "transmission", "drive", "state"].forEach((key) => {
409        const checked = document.querySelectorAll(`input[name="${key}[]"]:checked`);
410        if (checked.length === 1) {
411          const input = checked[0];
412          filters[key] = {
413            slug: input.dataset.slug,
414            title: input.dataset.title,
415          };
416        } else {
417          filters[key] = null;
418        }
419      });
420    });
421
422    form.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
423      checkbox.addEventListener('change', async () => {
424        currentPage = 1;
425        allLoaded = false;
426        apiData = null;
427
428        manualInputFlags.priceMin = false;
429        manualInputFlags.priceMax = false;
430        manualInputFlags.yearMin = false;
431        manualInputFlags.yearMax = false;
432
433      });
434    });
435
436    let scrollTicking = false;
437    window.addEventListener("scroll", () => {
438      if (scrollTicking) return;
439      scrollTicking = true;
440      requestAnimationFrame(() => {
441        const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
442        const preloadMargin = Math.max(clientHeight * 4, scrollHeight * 0.5);
443        if (scrollTop + clientHeight >= scrollHeight - preloadMargin && !loading && !allLoaded) {
444          currentPage++;
445          loadProducts(currentPage);
446        }
447        scrollTicking = false;
448      });
449    }, { passive: true });
450
451    window.addEventListener("popstate", () => {
452      currentPage = 1;
453      allLoaded = false;
454      loadProducts(currentPage);
455    });
456
457    var STOCK_SNAP_KEY = "sigmaStockSnap";
458    function stockUrlKey(){ return location.pathname + location.search; }
459    function saveStockSnap(){
460      try {
461        sessionStorage.setItem(STOCK_SNAP_KEY, JSON.stringify({
462          url: stockUrlKey(),
463          html: container.innerHTML,
464          docH: document.documentElement.scrollHeight,
465          scrollY: window.scrollY || document.documentElement.scrollTop || 0,
466          pages: currentPage,
467          allLoaded: allLoaded,
468          count: countFilter ? countFilter.textContent : "",
469          sliders: {
470            priceMin: priceMinInput ? priceMinInput.value : null,
471            priceMax: priceMaxInput ? priceMaxInput.value : null,
472            yearMin: yearMinInput ? yearMinInput.value : null,
473            yearMax: yearMaxInput ? yearMaxInput.value : null
474          },
475          flags: {
476            priceMin: manualInputFlags.priceMin, priceMax: manualInputFlags.priceMax,
477            yearMin: manualInputFlags.yearMin, yearMax: manualInputFlags.yearMax
478          },
479          ts: Date.now()
480        }));
481      } catch(e){ try { sessionStorage.removeItem(STOCK_SNAP_KEY); } catch(_){} }
482    }
483    function readStockSnap(){
484      try {
485        var raw = sessionStorage.getItem(STOCK_SNAP_KEY);
486        if(!raw) return null;
487        var sn = JSON.parse(raw);
488        if(!sn || sn.url !== stockUrlKey() || !sn.html) return null;
489        if(Date.now() - (sn.ts || 0) > 1800000) return null;
490        return sn;
491      } catch(e){ return null; }
492    }
493
494    if (container) {
495      container.addEventListener("click", function(e){
496        var a = e.target.closest(".vcard a[href]");
497        if(a){ var h = a.getAttribute("href"); if(h && h.charAt(0) === "/") saveStockSnap(); }
498      });
499    }
500    window.addEventListener("pagehide", function(){ saveStockSnap(); });
501
502    if ("scrollRestoration" in history) history.scrollRestoration = "manual";
503
504    var _snap = readStockSnap();
505    if (_snap) {
506      try { sessionStorage.removeItem(STOCK_SNAP_KEY); } catch(e){}
507      container.innerHTML = _snap.html;
508
509      if (_snap.docH) document.body.style.minHeight = _snap.docH + "px";
510      currentPage = _snap.pages || 1;
511      allLoaded = !!_snap.allLoaded;
512      if (countFilter && _snap.count) countFilter.textContent = _snap.count;
513      if (_snap.sliders) {
514        if (priceMinInput && _snap.sliders.priceMin != null) priceMinInput.value = _snap.sliders.priceMin;
515        if (priceMaxInput && _snap.sliders.priceMax != null) priceMaxInput.value = _snap.sliders.priceMax;
516        if (yearMinInput && _snap.sliders.yearMin != null) yearMinInput.value = _snap.sliders.yearMin;
517        if (yearMaxInput && _snap.sliders.yearMax != null) yearMaxInput.value = _snap.sliders.yearMax;
518        [priceMinInput, priceMaxInput, yearMinInput, yearMaxInput].forEach(function(el){ if(el) el.dispatchEvent(new Event("input")); });
519      }
520      if (_snap.flags) {
521        manualInputFlags.priceMin = _snap.flags.priceMin; manualInputFlags.priceMax = _snap.flags.priceMax;
522        manualInputFlags.yearMin = _snap.flags.yearMin; manualInputFlags.yearMax = _snap.flags.yearMax;
523      }
524
525      var _ty = _snap.scrollY || 0, _deadline = Date.now() + 1500;
526      function _jump(y){
527        try { window.scrollTo({ top: y, left: 0, behavior: "instant" }); } catch(e){ window.scrollTo(0, y); }
528        document.documentElement.scrollTop = y;
529      }
530      (function stick(){
531        _jump(_ty);
532        if (Math.abs((window.scrollY || 0) - _ty) > 2 && Date.now() < _deadline) {
533          requestAnimationFrame(stick);
534        } else {
535          setTimeout(function(){ document.body.style.minHeight = ""; }, 300);
536        }
537      })();
538    } else {
539      loadProducts(currentPage);
540    }
541
542    var resetBtn = document.querySelector('[data-filter-reset]');
543    if (resetBtn) {
544      resetBtn.addEventListener('click', async function() {
545        setBtnLoading(resetBtnEl, true);
546
547        form.querySelectorAll('input[type="checkbox"]:checked').forEach(function(cb){ cb.checked = false; cb.dispatchEvent(new Event('change', {bubbles:true})); });
548        form.querySelectorAll('input[type="radio"]:checked').forEach(function(rb){ rb.checked = false; rb.dispatchEvent(new Event('change', {bubbles:true})); });
549
550        form.querySelectorAll('.js-accordion__item, .js-adv-filter__item').forEach(function(item){
551          var sel = item.querySelector('.js-adv-filter__selection');
552          if(sel){ var def = item.getAttribute('data-default-text'); if(def) sel.textContent = def; }
553        });
554
555        manualInputFlags.priceMin = false;
556        manualInputFlags.priceMax = false;
557        manualInputFlags.yearMin = false;
558        manualInputFlags.yearMax = false;
559
560        if (priceMinInput) priceMinInput.value = priceMinInput.min;
561        if (priceMaxInput) priceMaxInput.value = priceMaxInput.max;
562        if (yearMinInput) yearMinInput.value = yearMinInput.min;
563        if (yearMaxInput) yearMaxInput.value = yearMaxInput.max;
564
565        [priceMinInput, priceMaxInput, yearMinInput, yearMaxInput].forEach(function(el){ if(el) el.dispatchEvent(new Event('input')); });
566        apiData = null;
567        currentPage = 1;
568        allLoaded = false;
569
570        if (filterPanel) filterPanel.classList.remove('sidebar--is-visible');
571        window.history.pushState(null, '', '/stock/');
572
573        await fetchAndApplyRanges();
574        await loadProducts(currentPage);
575        setBtnLoading(resetBtnEl, false);
576      });
577    }
578
579      const filters = {};
580
581      ["make", "transmission", "drive", "state"].forEach((key) => {
582        const checked = document.querySelectorAll(`input[name="${key}[]"]:checked`);
583        if (checked.length === 1) {
584          const input = checked[0];
585          filters[key] = {
586            slug: input.dataset.slug,
587            title: input.dataset.title,
588          };
589        } else {
590          filters[key] = null;
591        }
592      });
593
594      const accordionItems = document.querySelectorAll('.js-accordion__item');
595
596      accordionItems.forEach(item => {
597
598        const checkboxes = item.querySelectorAll('input[type="checkbox"]');
599
600        const hasChecked = Array.from(checkboxes).some(checkbox => checkbox.checked);
601
602        const rangeInputs = item.querySelectorAll('input[type="range"]');
603        const hasUrlRange = Array.from(rangeInputs).some(function(input) {
604          return urlParams.has(input.name);
605        });
606
607        if (hasChecked || hasUrlRange) {
608          item.classList.add('accordion__item--is-open');
609
610          const button = item.querySelector('.js-accordion__trigger');
611          const panel = item.querySelector('.js-accordion__panel');
612          if (button) button.setAttribute('aria-expanded', 'true');
613          if (panel) panel.removeAttribute('hidden');
614        }
615      });
616    }
617
618    function checkCheckboxesAndShowDiv() {
619
620    const checkboxes = document.querySelectorAll('input.makeall');
621    let selectedCheckbox = 0;
622    checkboxes.forEach((cb, index) => {
623        if(cb.checked){
624            selectedCheckbox++;
625           document.getElementById('make-div-' + cb.dataset.minititle + '').style.display = 'block';
626        }else{
627          document.getElementById('make-div-' + cb.dataset.minititle + '').style.display = 'none';
628          const allCheckboxesModels = document.querySelectorAll('.for-make-div-' + cb.dataset.minititle + '');
629          allCheckboxesModels.forEach((cbmodel, index) => {
630            cbmodel.checked = false;
631          });
632        }
633    });
634    if(selectedCheckbox === 0){
635      document.getElementById('hidden-filter-badge').style.display = 'block';
636    }else{
637      document.getElementById('hidden-filter-badge').style.display = 'none';
638    }
639  }
640
641  document.querySelectorAll('input.makeall').forEach(cb => {
642    cb.addEventListener('change', checkCheckboxesAndShowDiv);
643  });
644
645  (function(){
646    var back = document.querySelector('.car__back');
647    if(!back) return;
648    try {
649      var raw = sessionStorage.getItem("sigmaStockSnap");
650      if(!raw) return;
651      var sn = JSON.parse(raw);
652      if(!sn || !sn.url) return;
653      if(Date.now() - (sn.ts || 0) > 1800000) return;
654      back.setAttribute('href', sn.url);
655    } catch(e){}
656  })();
657});

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.