PageSourceSearch

https://cdn.bkmkitap.com/srv/compressed/load/v5/js/tr/2/0.js?v=179…&isTablet=0&isMobile=1&userType=Ziyaretci

js bkmkitap.com collected 2026-09-24 09:35:07 UTC 41,376 bytes, 1,008 lines download raw bytes

1
2var BLOCK_FN = {};
3var PAGE_LINK = {"CART":"sepet","LOGIN":"uye-girisi-sayfasi","REGISTER":"uye-kayit","CONTACT":"iletisim","CUSTOMER_ORDER_LIST":"uye-siparisleri","MEMBER_SHOPPING_LIST":"uye-alisveris-listesi","ORDER":"order"};
4BLOCK_FN["296"] = function(BLOCK, SETTING) {
5/* Header */
6window.headerMemberLoginFn = (result, options) => {
7    popoverAlert.show(
8        document.getElementById(`${options.prefix}${options.type || 'email'}`), 
9        result.message, 
10        2400, 
11        `btn ${(result.status === true) ? 'btn-success' : 'btn-danger'} text-left`,
12        false
13    );
14
15    if(result.status === true) {
16        setTimeout(() => {
17            window.location.reload();
18        }, 1500);
19    }
20}
21
22const menuAllCategories = T(`#menu-all-categories-${BLOCK.ID}`);
23if (menuAllCategories.length > 0) {
24    const categoriesApp = {
25        data() {
26            return {
27                CATEGORIES: [],
28                LOAD : true,
29            }
30        },
31        methods: {
32            get(id = '', parentId = '') {
33                const self = this;
34                axios.get(getEndpoint('CATEGORY', id)).then(response => {
35                    if (parentId != '') {
36                        const findCat = Array.from(self.CATEGORIES).find(c => c.ID == parentId);
37                        const findCat2 = Array.from(findCat.CHILDREN).find(c => c.ID == id);
38                        findCat2['CHILDREN'] = response.data;
39                    } else if (id != '') {
40                        const findCat = Array.from(self.CATEGORIES).find(c => c.ID == id);
41                        findCat['CHILDREN'] = response.data;
42                    } else {
43                        self.CATEGORIES = response.data;
44                    }
45                    self.LOAD = false;
46                }).catch(error => console.warn(`Categories not loaded => ${error}`));
47            },
48        }
49    };
50    Vue.createApp(categoriesApp).mount(`#menu-all-categories-${BLOCK.ID}`);
51};
52
53window[`headercart-cb-${BLOCK.ID}`] = () => {
54    loadSubFolder({
55        pageId: 1,
56        blockParentId: 1001,
57        subFolder: 'cart',
58        success:  function(loadRes){
59            let popupContent = T(`#header-cart-panel-${BLOCK.ID} .drawer-body`);
60            popupContent.html(loadRes);
61            evalScripts(popupContent[0].innerHTML);
62        }
63    });
64}
65
66if(CART_DROPDOWN_LIST === true) {
67    const cartDropdownBtn = T('.header-cart-dropdown'),
68          dropdownContent = T(`.header-cart-dropdown-list`),
69          cartBtnParent = cartDropdownBtn.length ? T(cartDropdownBtn[0].parentNode) : null;
70
71    let status = 1;
72    callbacks.cart.add.push(() => { status = 1; });
73
74    if(cartDropdownBtn.length && dropdownContent.length) {
75        cartDropdownBtn.on('mouseenter', () => {
76            if(matchMedia("screen and (max-width:768px)").matches === true) return;
77
78            if (status == 1) {
79                dropdownContent.html('');
80                dropdownContent.addClass('is-loading');
81            }
82
83            loadSubFolder({
84                pageId: 1,
85                blockParentId: 1001,
86                subFolder: 'cart',
87                success: function(loadRes){
88                    dropdownContent.html(loadRes);
89                    evalScripts(dropdownContent[0].innerHTML);
90                    dropdownContent.removeClass('is-loading');
91                    status = '';
92                }
93            });
94            cartDropdownBtn.addClass('cart-viewed');
95            dropdownContent.removeClass('d-none');
96        });
97        cartBtnParent.on('mouseleave', () => {
98            if(matchMedia("screen and (max-width:768px)").matches === true) return;
99            setTimeout(() => {
100                cartDropdownBtn.removeClass('cart-viewed');
101                dropdownContent.addClass('d-none');
102            }, 150);
103        });
104    }
105}
106
107window.onscroll = () => {
108    if (document.body.scrollTop > T('header').height() || document.documentElement.scrollTop > T('header').height()) {
109    T(`#scroll-to-up-${BLOCK.ID}`).show();
110    } else { T(`#scroll-to-up-${BLOCK.ID}`).hide(); }
111};
112T(`#scroll-to-up-${BLOCK.ID}`).on('click', () => {
113    scroll({ top: 0, behavior: "smooth" });
114});
115
116const liveSearch = T('[data-search="live-search"]');
117if (liveSearch.length > 0) {
118    const liveSearchApp = {
119        data() {
120            return {
121                data : '',
122                searchVal : '',
123                valueLimit: 3,
124                licence: liveSearch[0].dataset.licence || 0,
125                timer: null,
126            }
127        },
128        methods: {
129            search() {
130                const self = this;
131                self.timer = setTimeout(() => {
132                    const formData = new FormData();
133                    formData.append('searchWord', self.searchVal);
134                    
135                    axios.post(getEndpoint('SEARCH'), formData).then(response => {
136                        self.data = response.data;
137                    });
138                }, 250);
139            },
140            searchAll() {
141                const self = this;
142                self.timer = setTimeout(() => {
143                    axios.get(getEndpoint('SEARCH_ALL', self.searchVal)).then(response => {
144                        self.data = response.data;
145                    });
146                }, 250);
147            }
148        },
149        watch: {
150            'searchVal'(value) {
151                const self = this;
152                clearTimeout(self.timer);
153                if (value.length >= self.valueLimit) {
154                    self.licence == 1 ? self.searchAll() : self.search();
155                } else {
156                    self.data = '';
157                }
158            }
159        },
160        mounted() {
161            const self = this;
162            document.addEventListener('click', e => {
163                var Dom = e.target.nodeName == 'I' ? e.target.parentElement : e.target;
164                const parentDom = Dom.closest('#search');
165                if (parentDom == null) {
166                    self.searchVal = '';
167                    self.data = '';
168                }
169            });
170        },
171    }
172    Vue.createApp(liveSearchApp).mount(`#search`);
173}
174
175T(`#toggleVisiblePassword${BLOCK.ID}`).on('click', e => {
176    const icon = e.target;
177    if (icon == null && T(icon).length < 1) return;
178
179    const type = T(icon).hasClass('ti-eye-off') ? 'text' : 'password';
180    T(icon.closest('.input-group').querySelector('input')).attr('type', type);
181    T(icon).toggleClass('ti-eye-off text-gray ti-eye text-primary');
182});
183
184let nav = T(`.menu-${BLOCK.ID}`);
185let navTime;
186T(nav).on('mouseenter', () => {
187    navTime = setTimeout(() => {
188        if (!T(nav).hasClass('active')) T(nav).addClass("active");
189    }, 250);
190});
191T(nav).on('mouseleave', () => {
192    T(nav).removeClass('active');
193    clearTimeout(navTime);
194});
195
196const app = T(`#mobile-app-${BLOCK.ID}`);
197if (app.length > 0 && T.isMobile()) {
198    const MobileAppRedirect = T(`#mobile-app-redirect-${BLOCK.ID}`)[0].value,
199          AppMarketLink = T(`#app-market-link-${BLOCK.ID}`)[0].value,
200          OpenAppLink = T(`#open-app-link-${BLOCK.ID}`)[0].value;
201
202    if (T.getCookie('mobileApp') == 1) {
203        app[0].remove();
204    } else {
205        app.show();
206        app.removeClass('d-none');
207    }
208
209    let storeUrl, timeout;
210    if (MobileAppRedirect == 'ios') {
211        storeUrl = `https://itunes.apple.com/app/id${AppMarketLink}`;
212    } else if (MobileAppRedirect == 'android') {
213        storeUrl = `market://details?id=${AppMarketLink}`;
214    }
215
216    const meta = document.createElement('meta');
217          meta.name = 'apple-itunes-app';
218          meta.content = `app-id=${AppMarketLink}, affiliate-data=myAffiliateData, app-argument=${OpenAppLink}://`;
219    T('head')[0].append(meta);
220
221    T(`#mobile-app-close-${BLOCK.ID}`).on('click', () => {
222        app[0].remove();
223        T.setCookie('mobileApp', 1);
224    });
225
226    T(`#mobile-app-download-${BLOCK.ID}`).on('click', () => {
227        timeout = setTimeout(() => {
228            document.location.href = storeUrl;
229        }, 2000);
230        document.location.href = `${OpenAppLink}://`;
231    });
232}
233
234}
235 try{ BLOCK_FN["296"]({"ID":296,"PARENT_ID":1001,"PAGE_ID":2,"NAME":"\u00dcst K\u0131s\u0131m","ASSETS":"\/theme\/v5-bkm\/assets\/"}, {"MENU_SELECTED":true,"DISPLAY_TITLE":0,"IS_STICKY":"1","GOOGLE_RECAPTCHA":{"CLIENT_KEY":"","ACTIVE":false}});   }catch(ex){ console.error('HATA VAR : Üst Kısım/2'); console.error(ex); }
236
237
238BLOCK_FN["297"] = function(BLOCK, SETTING) {
239/* Breadcrumb */
240
241
242}
243 try{ BLOCK_FN["297"]({"ID":297,"PARENT_ID":1005,"PAGE_ID":2,"NAME":"Navigasyon","ASSETS":"\/theme\/v5-bkm\/assets\/"}, {"DISPLAY_TITLE":1,"GOOGLE_RECAPTCHA":{"CLIENT_KEY":"","ACTIVE":false}});   }catch(ex){ console.error('HATA VAR : Navigasyon/2'); console.error(ex); }
244
245
246BLOCK_FN["298"] = function(BLOCK, SETTING) {
247/* ProductsTopBottomInfo */
248
249
250}
251 try{ BLOCK_FN["298"]({"ID":298,"PARENT_ID":1049,"PAGE_ID":2,"NAME":"\u00dcr\u00fcnler \u00dcst - Alt Vitrin","ASSETS":"\/theme\/v5-bkm\/assets\/"}, {"POSITION":"top","DISPLAY_TITLE":1,"GOOGLE_RECAPTCHA":{"CLIENT_KEY":"","ACTIVE":false}});   }catch(ex){ console.error('HATA VAR : Ürünler Üst - Alt Vitrin/2'); console.error(ex); }
252
253
254BLOCK_FN["299"] = function(BLOCK, SETTING) {
255/* Filter */
256const FilterBlock = {
257    data() {
258        return {
259            LOADING: true,
260            PARAMS: {
261                'stock': window.location.href.indexOf('stock=') > 0,
262                'discounted': window.location.href.indexOf('discounted=') > 0,
263                'new': window.location.href.indexOf('new=') > 0
264            },
265            FILTERS: {},
266            IS_MOBILE: T.isMobile() === true,
267            BLOCK: BLOCK,
268            SETTING: SETTING
269        }
270    },
271    methods: {
272        select(type, index) {
273            const self = this;
274
275            var tmp = type.split('.');
276            if (tmp.length === 1 && typeof self[type] !== 'undefined') {
277                self[tmp[0]][index]['SELECTED'] = self[tmp[0]][index]['SELECTED'] === 0 ? 1 : 0;
278            } else if (tmp.length === 2) {
279                self[tmp[0]][tmp[1]][index]['SELECTED'] = self[tmp[0]][tmp[1]][index]['SELECTED'] === 0 ? 1 : 0;
280            } else if (tmp.length === 3) {
281                self[tmp[0]][tmp[1]][tmp[2]][index]['SELECTED'] = self[tmp[0]][tmp[1]][tmp[2]][index]['SELECTED'] === 0 ? 1 : 0;
282            }
283
284            if (!self.SETTING.FILTER_BUTTON) self.run();
285        },
286        getSelected(arr, noJoin) {
287            var el = arr.map(function (e) {
288                if (e.SELECTED === 1) {
289                    return e.ID;
290                }
291            });
292
293            el = el.filter(n => n);
294            el = !noJoin ? el.join('-') : el;
295            return el;
296        },
297        getSelectedFilters() {
298            const self = this;
299            const result = {
300                multi: [],
301                single: [],
302                decimal: [],
303            }
304
305            for (let i = 0; i < self.FILTERS.FILTERS.length; i++) {
306                const obj = self.FILTERS.FILTERS[i];
307                switch (obj.TYPE) {
308                    case '0': // multi
309                    case '1': // single
310                        const k = self.getSelected(obj.VALUES, true);
311                        const r = k.map(function (e) {
312                            return obj.ID + '-' + e;
313                        });
314                        if (obj.TYPE === '0') {
315                            result.multi = result.multi.concat(r);
316                        } else {
317                            result.single = result.single.concat(r);
318                        }
319                        break;
320                    case '2': // decimal
321                        if (obj.MIN_SELECTED != obj.MIN || obj.MAX_SELECTED != obj.MAX) {
322                            const n = obj.ID + '-' + obj.MIN_SELECTED + '-' + obj.MAX_SELECTED;
323                            result.decimal = result.decimal.concat(n);
324                        }
325                        break;
326                }
327            }
328
329            result.multi = result.multi.join('+');
330            result.single = result.single.join('+');
331            return result;
332
333        },
334        filter(index, subIndex) {
335            const self = this;
336            let filters = self.FILTERS.FILTERS;
337            if (filters[index] && filters[index].TYPE != 2 && filters[index].VALUES[subIndex] !== 'undefined') {
338                filters[index].VALUES[subIndex]['SELECTED'] = filters[index].VALUES[subIndex]['SELECTED'] === 0 ? 1 : 0;
339            }
340            if (!self.SETTING.FILTER_BUTTON) self.run();
341        },
342        run() {
343            let link = window.location.href;
344
345            if (this.FILTERS?.FILTERS) {
346                const filters = this.getSelectedFilters();
347
348                link = T.getLink('multi', filters.multi, link);
349                link = T.getLink('single', filters.single, link);
350                if (this.SETTING.FILTER_BUTTON) link = T.getLink('decimal', filters.decimal.join('+'), link);
351            }
352
353            if (this.FILTERS?.BRANDS) link = T.getLink('brand', this.getSelected(this.FILTERS.BRANDS), link);
354            if (this.FILTERS?.SUPPLIERS) link = T.getLink('supplier', this.getSelected(this.FILTERS.SUPPLIERS), link);
355            if (this.FILTERS?.MODELS) link = T.getLink('model', this.getSelected(this.FILTERS.MODELS), link);
356            if (this.FILTERS?.VARIANTS?.TYPE1_LIST) link = T.getLink('type1', this.getSelected(this.FILTERS.VARIANTS.TYPE1_LIST), link);
357            if (this.FILTERS?.VARIANTS?.TYPE2_LIST) link = T.getLink('type2', this.getSelected(this.FILTERS.VARIANTS.TYPE2_LIST), link);
358
359            if (this.SETTING.FILTER_BUTTON && this.FILTERS?.PRICE && this.FILTERS.PRICE.SELECTED == 1) link = T.getLink('price', this.FILTERS.PRICE.MIN_SELECTED + '-' + this.FILTERS.PRICE.MAX_SELECTED, link);
360
361            link = T.getLink('stock', this.PARAMS.stock ? '1' : '', link);
362            link = T.getLink('discounted', this.PARAMS.discounted ? '1' : '', link);
363            link = T.getLink('new', this.PARAMS.new ? '1' : '', link);
364
365            window.location.href = link;
366        },
367        search(input, wrapper) {
368            if (document.querySelector('[data-filter-search="' + wrapper + '"]') == null) return;
369
370            const searchString = String(input.target.value).toLowerCase();
371            const items = document.querySelectorAll('[data-filter-search="' + wrapper + '"] > .filter-list-item');
372
373            if (searchString != '') {
374                items.forEach((input) => {
375                    if (String(input.dataset.title).toLowerCase().indexOf(searchString) > -1) {
376                        input.classList.remove('d-none');
377                    } else {
378                        input.classList.add('d-none');
379                    }
380                });
381            } else {
382                items.forEach((input) => {
383                    input.classList.remove('d-none');
384                });
385            }
386        },
387        clearFilter(selected) {
388            let url = '';
389            if (selected == 'all') {
390                const selectedAll = this.FILTERS.SELECTED;
391                if (selectedAll) {
392                    url = document.location;
393                    let type = '';
394                    for (let i = 0; i < selectedAll.length; i++) {
395                        if (type != selectedAll[i].XTYPE) {
396                            url = deleteUrlParam(selectedAll[i].XTYPE, url);
397                            type = selectedAll[i].XTYPE;
398                        }
399                    }
400                }
401            } else {
402                let newParams = '';
403                let split = selected.XTYPE == 'multi' || selected.XTYPE == 'decimal' ? ' ' : '-';
404                if (selected.XTYPE != 'price') {
405                    const get = getUrlParam(selected.XTYPE).split(split);
406                    const paramFilter = (val) => {
407                        return val != selected.VALUE;
408                    }
409                    newParams = get.filter(paramFilter).join(split);
410                }
411                url = newParams == '' ? deleteUrlParam(selected.XTYPE) : setUrlParam(selected.XTYPE, newParams);
412            }
413            url = url.toString();
414            window.location.href = url;
415        },
416        close(id) {
417            T(`[data-rel="${id}"]`).trigger('click');
418        },
419    },
420    watch: {
421        'PARAMS.stock'() {
422            if (!this.SETTING.FILTER_BUTTON) this.run();
423        },
424        'PARAMS.discounted'() {
425            if (!this.SETTING.FILTER_BUTTON) this.run();
426        },
427        'PARAMS.new'() {
428            if (!this.SETTING.FILTER_BUTTON) this.run();
429        },
430    },
431    mounted() {
432        const self = this,
433            linkParam = window.location.href.replace(location.origin + '/', '').replace('?', '&');
434
435        if (self.IS_MOBILE) T('#product-filter').addClass('drawer
435-wrapper');
436
437        axios.get(getEndpoint('FILTER', `${SETTING.PARAMS.join('-').toLowerCase()}?link=${linkParam}`)).then(response => {
438            self.FILTERS = response.data;
439            self.LOADING = false;
440            setTimeout(() => { initComponents(); }, 150);
441        }).catch(err => {
442            console.log(`%c Filter Error => ${err}`, 'background:#222; color:#bada55');
443        });
444    }
445};
446
447Vue.createApp(FilterBlock).component('slider-range', {
448    props: ['id', 'min', 'max', 'start', 'currency', 'decimal', 'params'],
449    data() {
450        return {
451            STEP_LENGTH: this.max > 500 ? 10 : 1,
452            SETTING: SETTING,
453            MIN_PRICE: '',
454            MAX_PRICE: '',
455            FILTERS: this.$parent.FILTERS,
456        }
457    },
458    template: `
459        <div class="w-100">
460            <div class="d-flex align-items-center gap-1 mb-2 noui-slider-input" v-if="SETTING.FILTER_BUTTON">
461                <div class="w-50"><input type="text" class="form-control" :id="id + '-min-price'" @change="set($event, 'min')" :value="MIN_PRICE"></div>
462                <div class="w-50"><input type="text" class="form-control" :id="id + '-max-price'" @change="set($event, 'max')" :value="MAX_PRICE"></div>
463            </div>
464            <div class="d-flex align-items-center gap-1 mb-1 noui-slider-text" v-else>
465                <div class="w-50 text-left" :id="id + '-min-price'">{{ MIN_PRICE }}</div>
466                <div class="w-50 text-right" :id="id + '-max-price'">{{ MAX_PRICE }}</div>
467            </div>
468            <div :id="id" :data-id="params" class="w-100 mb-2" :class="{'decimal-slide' : decimal}"></div>
469        </div>`,
470    methods: {
471        set(event, status) {
472            const self = this;
473            let val = event.target.value;
474            let valReplace = val.replace(/[^0-9]/g, "");
475
476            document.getElementById(self.id).noUiSlider.set(status == 'min' ? [parseFloat(valReplace), null] : [null, parseFloat(valReplace)]);
477            event.target.value = status == 'min' ? self.MIN_PRICE : self.MAX_PRICE;
478        }
479    },
480    mounted() {
481        const self = this;
482        let handlesSlider = document.getElementById(self.id);
483
484        noUiSlider.create(handlesSlider, {
485            start: [self.start[0], self.start[1]],
486            direction: LANGUAGE == 'ar' ? 'rtl' : 'ltr',
487            step: self.STEP_LENGTH,
488            connect: true,
489            range: {
490                min: self.min,
491                max: self.max <= self.min ? self.min + 1 : self.max
492            }
493        });
494
495        handlesSlider.noUiSlider.on('update', function (values, handle) {
496            self.MIN_PRICE = self.decimal ? Math.round(values[0]) : T.format(values[0]) + ' ' + self.currency;
497            self.MAX_PRICE = self.decimal ? Math.round(values[1]) : T.format(values[1]) + ' ' + self.currency;
498        });
499
500        if (self.SETTING.FILTER_BUTTON) {
501            handlesSlider.noUiSlider.on('set', function (values, handle) {
502                const filter = self.decimal ? Array.from(self.FILTERS.FILTERS).find(x => x.ID == self.params) : self.FILTERS.PRICE;
503                filter['SELECTED'] = 1;
504                filter.MIN_SELECTED = parseFloat(values[0]).toFixed(0);
505                filter.MAX_SELECTED = parseFloat(values[1]).toFixed(0);
506            });
507        } else {
508            handlesSlider.noUiSlider.on('set', function (values) {
509                if (self.decimal) {
510                    let decimal = [];
511                    if (getUrlParam('decimal')) {
512                        const paramFilter = (val) => {
513                            return val.split('-')[0] != self.params;
514                        }
515                        decimal = getUrlParam('decimal').split(' ');
516                        decimal = decimal.filter(paramFilter);
517                    }
518                    decimal.push(self.params + '-' + parseFloat(values[0]).toFixed(0) + '-' + parseFloat(values[1]).toFixed(0));
519                    window.location.href = T.getLink('decimal', decimal.join('+'));
520                } else {
521                    window.location.href = T.getLink('price', parseFloat(values[0]).toFixed(0) + '-' + parseFloat(values[1]).toFixed(0));
522                }
523            });
524        }
525    }
526}).mount('#product-filter');
527
528}
529 try{ BLOCK_FN["299"]({"ID":299,"PARENT_ID":1069,"PAGE_ID":2,"NAME":"Filtrele","ASSETS":"\/theme\/v5-bkm\/assets\/"}, {"PARAMS":["FILTERS","VARIANTS","CATEGORIES","BRANDS","PRICE","MODELS"],"DISPLAY_TITLE":1,"FILTER_BUTTON":1,"FILTER_STICKY":0,"GOOGLE_RECAPTCHA":{"CLIENT_KEY":"","ACTIVE":false}});   }catch(ex){ console.error('HATA VAR : Filtrele/2'); console.error(ex); }
530
531
532const productLoaderCallback = [];
533const productLoader = async (opt = {}) => {
534    const defaults = {
535        blockId: null,
536        container: '#catalog',
537        product: '.product-item',
538    };
539
540    const options = { ...defaults, ...opt };
541    if (options.blockId === null || typeof options.blockId !== "number") {
542        console.error(`options.blockId misidentification`);
543        return;
544    }
545
546    options.container += options.blockId;
547
548    const productLoaderObj = {
549        container: null,
550        currentPage: Number(getUrlParam('ps') || 1),
551        firstPage: Number(getUrlParam('ps') || 1),
552        options: {
553            target: options.container,
554            product: options.product,
555            relationId: options.blockId,
556            scrollUp: false
557        },
558        state: {
559            loading: false,
560            prefetching: false,
561            canScrollDown: true,
562            canScrollUp: true,
563            lastScrollTop: 0,
564            abortController: null,
565        },
566        prefetchCache: new Map(),
567        loader: function(show = false) {
568            if (show) {
569                document.body.classList.add('is-loading');
570            } else {
571                document.body.classList.remove('is-loading');
572            }
573        },
574        canPrefetch: function() {
575            const conn = navigator.connection;
576            if (!conn) return true;
577            return !conn.saveData && !['slow-2g', '2g'].includes(conn.effectiveType);
578        },
579        buildEndpoint: function(page) {
580            let params = T.getLink('link', window.location.pathname.replaceAll(/^\//ig, ''));
581            params = T.getLink('ps', '', params);
582            params = T.getLink('pg', page, params);
583            params = params.split('?')[1] || '';
584            return getEndpoint('PRODUCT_LOADER', `${this.options.relationId}?${params}`);
585        },
586        prefetchPage: function(page, prepend = false) {
587            if (page < 1 || this.prefetchCache.has(page) || !this.canPrefetch() || this.state.loading) return;
588        
589            const already = this.container.querySelectorAll(`${this.options.product}[data-page="${page}"]`);
590            if (already.length) return;
591    
592            this.state.prefetching = true;
593        
594            const controller = new AbortController();
595            const promise = axios.get(this.buildEndpoint(page), { signal: controller.signal })
596                .catch((err) => {
597                    if (err?.name !== 'AbortError') {
598                        this.restoreScroll(prepend);
599                    }
600                    return null;
601                })
602                .finally(() => {
603                    this.state.prefetching = false;
604                });
605        
606            this.prefetchCache.set(page, { promise, controller });
607        },
608        paginationPushState: function(key, title, url) {
609            window.pushstateloaded = true;
610            window.history?.pushState && window.history.replaceState(key, title, url);
611        },
612        addClassProduct: function(products) {
613            const arr = Array.from(products);
614            if (!arr.length) return;
615    
616            arr[0].dataset.page = this.currentPage;
617            arr[arr.length - 1].dataset.page = this.currentPage;
618    
619            arr.forEach((product, index) => {
620                product.dataset.index = `${this.currentPage}-${index}`;
621                product.addEventListener('click', () => {
622                    T.setCookie('productIndex', JSON.stringify({
623                        category: window.location.pathname,
624                        product: product.dataset.index,
625                        page: product.dataset.index?.split('-')[0] ?? getUrlParam('ps') ?? 1
626                    }));
627                });
628            });
629        },
630        appendProduct: async function(html, prepend = false) {
631            const parsed = new DOMParser().parseFromString(html, 'text/html');
632            const products = parsed.documentElement.querySelectorAll(this.options.product);
633            if (!products.length) return;
634    
635            const fragment = document.createDocumentFragment();
636            const arr = Array.from(products);
637    
638            if (prepend) {
639                arr.reverse().forEach(p => fragment.prepend(p));
640            } else {
641                arr.forEach(p => fragment.append(p));
642            }
643
644            for (let i = 0; i < productLoaderCallback.length; i++) {
645                productLoaderCallback[i]?.(products);
646            }
647    
648            await new Promise(resolve => setTimeout(resolve, 200));
649            if (prepend) {
650                const anchor = this.container.firstElementChild;
651                this.container.prepend(fragment);
652                requestAnimationFrame(() => {
653                    if (anchor) {
654                        window.scrollTo(0, anchor.offsetTop);
655                    }
656                });
657            } else {
658                this.container.append(fragment);
659            }
660    
661            await initComponents();
662            await favouriteProducts.set();
663            if (T.isMobile()) await lazyControl(this.container);
664
665            this._runDynamicLoaderCallbacks(html);
666            this.addClassProduct(products);
667            setTimeout(() => {
668                if (prepend) {
669                    this.state.canScrollUp = true;
670                } else {
671                    this.state.canScrollDown = true;
672                }
673            }, 300);
674        },
675        _runDynamicLoaderCallbacks: function(html) {
676            const regex = /PRODUCT_DATA\.push\(JSON\.parse\('([^']+)'\)\);/g;
677            const matches = [];
678    
679            for (const match of html.matchAll(regex)) {
680                try {
681                    const jsonStr = eval("'" + match[1] + "'");
682                    matches.push(JSON.parse(jsonStr));
683                    PRODUCT_DATA.push(JSON.parse(jsonStr));
684                } catch (err) {
685                    console.warn('productLoader: PRODUCT_DATA parse hatası', err);
686                }
687            }
688    
689            if (!callbacks?.product?.dynamicLoader?.length) {
690                callbacks.product.dynamicLoader.forEach(cb => {
691                    if (typeof cb === 'function') {
692                        try { cb(matches); }
693                        catch (err) { console.warn('productLoader: dynamicLoader callback hatası', err); }
694                    }
695                });
696            }
697        },
698        getProduct: async function(page, prepend = false) {
699            const nextPage = prepend ? Number(page) - 1 : Number(page) + 1;
700            if (nextPage < 1) return;
701        
702            const already = this.container.querySelectorAll(`${this.options.product}[data-page="${nextPage}"]`);
703            if (already.length) return;
704        
705            if (this.state.loading) return;
706            this.state.loading = true;
707        
708            this.state.abortController?.abort();
709        
710            this.prefetchCache.forEach((entry, cachedPage) => {
711                if (cachedPage !== nextPage) {
712                    entry?.controller?.abort();
713                    this.prefetchCache.delete(cachedPage);
714                }
715            });
716        
717            this.state.abortController = new AbortController();
718            const { signal } = this.state.abortController;
719        
720            if (SETTINGS.DYNAMIC_LOADING_SHOW_BUTTON != 1) {
721                if (prepend) {
722                    this.state.canScrollUp = false;
723                } else {
724                    this.state.canScrollDown = false;
725                }
726            }
727        
728            this.loader(true);
729        
730            try {
731                const cached = this.prefetchCache.get(nextPage);
732                this.prefetchCache.delete(nextPage);
733        
734                let response;
735                if (cached) {
736                    response = await (cached.promise ?? cached);
737                } else {
738                    response = await axios.get(this.buildEndpoint(nextPage), { signal: signal });
739                }
740        
741                if (signal.aborted) return;
742                if (response.data) {
743                    this.currentPage = nextPage;
744                    await this.appendProduct(response.data, prepend);
745                } else {
746                    this.restoreScroll(prepend);
747                }
748            } catch (err) {
749                if (err?.name === 'AbortError') return;
750                this.restoreScroll(prepend);
751            } finally {
752                this.loader();
753                this.state.loading = false;
754            }
755        },
756        restoreScroll: function(prepend) {
757            if (prepend) {
758                this.state.canScrollUp = false;
759            } else {
760                this.state.canScrollDown = false;
761            }
762        },
763        runScroll: function() {
764            const _self = productLoaderObj;
765            const { clientHeight } = document.documentElement;
766            const pageProducts = _self.container.querySelectorAll(`${_self.options.product}[data-page]`);
767            if (!pageProducts.length) return;
768    
769            pageProducts.forEach(product => {
770                const rect = product.getBoundingClientRect();
771                const center = rect.top + rect.height / 2;
772                if (center >= 0 && center <= window.innerHeight
773                    && getUrlParam('ps') != product.dataset.page) {
774                    const url = product.dataset.page == 1
775                        ? T.getLink('ps', '')
776                        : T.getLink('ps', product.dataset.page);
777                    _self.paginationPushState('pagination', `Page ${product.dataset.page}`, url);
778                }
779            });
780    
781            const currentPage = getUrlParam('ps') || 1;
782            const products = _self.container.querySelectorAll(`${_self.options.product}[data-page="${currentPage}"]`);
783            if (!products.length) return;
784    
785            const firstRect = products[0].getBoundingClientRect();
786            const lastRect  = (products[1] ?? products[0]).getBoundingClientRect();
787            const currentST = window.scrollY || document.documentElement.scrollTop;
788    
789            if (currentST > _self.state.lastScrollTop) {                
790                if ((lastRect.bottom - (lastRect.height * 2)) < clientHeight) {
791                    _self.prefetchPage(Number(currentPage) + 1, false);
792                }
793                if (lastRect.bottom < clientHeight && _self.state.canScrollDown) {
794                    _self.getProduct(currentPage);
795                }
796            } else if (currentST < _self.state.lastScrollTop && currentPage > 1) {
797                if (SETTINGS.DYNAMIC_LOADING_SHOW_BUTTON == 1) {
798                    if ((firstRect.top + (firstRect.height * 2)) > 0 && _self.options.scrollUp) {
799                        _self.prefetchPage(Number(currentPage) - 1, true);
800                    }
801                    if (firstRect.bottom > 0 && _self.options.scrollUp && _self.state.canScrollUp) {
802                        _self.getProduct(currentPage, true);
803                    }
804                }
805            }
806    
807            _self.state.lastScrollTop = currentST;
808        },
809        throttle: function(fn, wait) {
810            let last = 0;
811            return (...args) => {
812                const now = Date.now();
813                if (now - last >= wait) {
814                    last = now;
815                    fn(...args);
816                }
817            };
818        },
819        loadMoreBtn: function() {
820            if (SETTINGS.DYNAMIC_LOADING_SHOW_BUTTON != 1) return;
821            const _self = productLoaderObj;
822    
823            const psValue = Number(getUrlParam('ps') || 1);
824            if (Number(psValue) > 1) {
825                const loadBtnUp = document.createElement('div');
826                loadBtnUp.className = 'w-100 mb-2 product-loader-btn';
827                loadBtnUp.innerHTML = `
828                    <button
829                        class="w-100 btn border-gray"
830                        data-direction="up"
831                        data-qa="load-more-button"
832                    >${TLANG?.show_more_products}</button>
833                `;
834                _self.container.before(loadBtnUp);
835        
836                loadBtnUp.querySelector('button').addEventListener('click', () => {
837                    const psValueUp = Number(getUrlParam('ps') || 1);
838                    document.documentElement.style.scrollBehavior = 'revert';
839                    loadBtnUp.remove();
840                    _self.options.scrollUp = true;
841                    _self.getProduct(psValueUp, true);
842                });
843            }
844        },
845        cookieSetScroll: async function() {
846            if (SETTINGS.DYNAMIC_LOADING_SHOW_BUTTON != 1) return;
847            const _self = productLoaderObj;
848            const psValue = Number(getUrlParam('ps') || 1);
849            const cookieRaw = T.getCookie('productIndex');
850            T.setCookie('productIndex', '');
851    
852            if ('scrollRestoration' in history && psValue > 1 && _self.firstPage != psValue) {
853                history.scrollRestoration = 'manual';
854            }
855    
856            const scrollToTop = () => {
857                if (_self.firstPage != psValue) {
858                    window.scrollTo(0, 0);
859                }
860            }
861            const navType = performance.getEntriesByType?.('navigation')?.[0]?.type;
862            if (navType === 'reload' || navType === 'navigate') {
863                scrollToTop();
864            }
865    
866            window.addEventListener('pageshow', async (event) => {
867                const nav = performance.getEntriesByType?.('navigation')?.[0];
868                const isHistoryNavigation = nav?.type === 'back_forward' || event.persisted;
869            
870                document.documentElement.style.scrollBehavior = 'revert';
871                if (isHistoryNavigation && cookieRaw) {
872                    try {
873                        const saved = JSON.parse(cookieRaw) || {};
874                        if (saved?.category === window.location.pathname && saved?.product) {
875                            document.body.style.overflow = 'hidden';
876    
877                            const targetPage = saved.page || psValue;
878                            if (targetPage && targetPage !== psValue) {
879                                const direction = saved.page > psValue ? true : false;
880                                await _self.getProduct(targetPage, direction);
881                            }
882                            document.body.style.overflow = 'auto';
883        
884                            const target = _self.container.querySelector(`${_self.options.product}[data-index="${saved.product}"]`);
885                            const fallback = _self.container.querySelector(`${_self.options.product}`);
886                            const scrollY  = target ? target.offsetTop - 100 : (fallback ? fallback.offsetTop - 100 : 0);
887                            window.scrollTo(0, scrollY);
888                        } else {
889                            scrollToTop();
890                        }
891                    } catch {
892                        scrollToTop();
893                    }
894                }
895            });
896            document.documentElement.style.scrollBehavior = 'smooth';
897        },
898        init: function() {
899            const _self = productLoaderObj;
900    
901            if (!_self.options.target) return;
902            if (!_self.options.product) return;
903            if (!_self.options.relationId) return;
904
905            _self.container = document.querySelector(_self.options.target);
906            if (!_self.container) return;
907    
908            const throttledScroll = _self.throttle(_self.runScroll, 16);
909            _self.cookieSetScroll();
910            _self.loadMoreBtn();
911        
912            const initialProducts = _self.container.querySelectorAll(`${_self.options.product}`);
913            if (initialProducts.length) _self.addClassProduct(initialProducts);
914        
915            window.addEventListener('scroll', throttledScroll, { passive: true });
916            document.body.addEventListener('touchend', throttledScroll, { passive: true });
917    
918            return {
919                destroy() {
920                    window.removeEventListener('scroll', throttledScroll);
921                    document.body.removeEventListener('touchend', throttledScroll);
922    
923                    _self.prefetchCache.forEach(entry => {
924                        entry?.controller?.abort();
925                    });
926                    _self.prefetchCache.clear();
927    
928                    _self.state.abortController?.abort();
929                    _self.state.abortController = null;
930                },
931            };
932        }
933    }
934
935    productLoaderObj.init();
936};
937
938BLOCK_FN["300"] = function(BLOCK, SETTING) {
939/* ProductList */
940const dynamicallyLoad = T(`#is-auto-load-active-${BLOCK.ID}${BLOCK.PARENT_ID}`);
941if (dynamicallyLoad.length == 1) {
942    productLoader({
943        blockId: BLOCK.ID,
944    });
945}
946
947}
948 try{ BLOCK_FN["300"]({"ID":300,"PARENT_ID":1003,"PAGE_ID":2,"NAME":"\u00dcr\u00fcn Listesi","ASSETS":"\/theme\/v5-bkm\/assets\/"}, {"IS_FILTER_PANEL_ACTIVE":"1","DISPLAY_CART_BUTTON":"1","DISPLAY_FAVOURITE_BUTTON":1,"IS_QUICK_VIEW_ACTIVE":0,"PERVIEW":{"ALL":2,"SM":2,"MD":2,"LG":4,"XL":4,"XXL":4},"SORT":["3","4","5","6","7","8","0"],"IMAGE_RATIO":1.3,"PRODUCT_COUNT_PER_PAGE":"12","DISPLAY_TITLE":"1","GOOGLE_RECAPTCHA":{"CLIENT_KEY":"","ACTIVE":false}});   }catch(ex){ console.error('HATA VAR : Ürün Listesi/2'); console.error(ex); }
949
950
951BLOCK_FN["301"] = function(BLOCK, SETTING) {
952/* ProductsTopBottomInfo */
953
954
955}
956 try{ BLOCK_FN["301"]({"ID":301,"PARENT_ID":1049,"PAGE_ID":2,"NAME":"\u00dcr\u00fcnler Alt Vitrin","ASSETS":"\/theme\/v5-bkm\/assets\/"}, {"POSITION":"bottom","DISPLAY_TITLE":"1","GOOGLE_RECAPTCHA":{"CLIENT_KEY":"","ACTIVE":false}});   }catch(ex){ console.error('HATA VAR : Ürünler Alt Vitrin/2'); console.error(ex); }
957
958
959BLOCK_FN["302"] = function(BLOCK, SETTING) {
960/* Footer */
961T(`#newsletter-form-${BLOCK.ID}`).on('submit', e => {
962    e.stopPropagation();
963    e.preventDefault();
964    const formEl = e.target;
965    popoverAlert.hideAll();
966    if(!T.checkValidity(formEl))
967        return;
968    var data = new FormData(formEl);
969    axios.post('/srv/service/guest/subscribeNewsletter', data).then(response => {
970        const result = response.data;
971        const element = T(`#news_${result.key}-${BLOCK.ID}`)[0] || formEl.querySelector('[name="email"]');
972        if(result.status == 1) {
973
974            for(let i=0; i < callbacks.customer.subscribe.length; i++){
975                if(typeof callbacks.customer.subscribe[i] === 'function'){
976                    try {
977                        result.email = formEl.querySelector('[name="email"]').value;
978                        callbacks.customer.subscribe[i]?.(result);
979                    } catch (error) { console.log(`Customer Subscribe Callback Error => ${error}`); }
980                }
981            }
982
983            T.notify({
984                text: result.message,
985                className: 'success',
986                stopOnFocus : true,
987                duration: 3200,
988            });
989            formEl.reset();
990            return;
991        }
992        if (element) {
993            popoverAlert.show(
994                element.type == 'checkbox' ? element.nextElementSibling : element, 
995                result.message || result.statusText,
996                3000, 
997                `btn btn-danger no-radius text-left`,
998                false,
999                `${element.type == 'checkbox' ? '' : 'inline'}`
1000            );
1001        }
1002    });
1003});
1004
1005
1006}
1007 try{ BLOCK_FN["302"]({"ID":302,"PARENT_ID":1002,"PAGE_ID":2,"NAME":"Alt K\u0131s\u0131m","ASSETS":"\/theme\/v5-bkm\/assets\/"}, {"DISPLAY_TITLE":0,"GOOGLE_RECAPTCHA":{"CLIENT_KEY":"","ACTIVE":false}});   }catch(ex){ console.error('HATA VAR : Alt Kısım/2'); console.error(ex); }
1008

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.