PageSourceSearch

https://town-country-market.com/wp-content/themes/svt/js/init.js?ver=1791092785

js town-country-market.com collected 2026-10-04 05:47:40 UTC 129,248 bytes, 2,721 lines download raw bytes

1var myItems = {};
2var products = [];
3var allProducts = [];
4var productsArr = {};
5var bestDealsIDs = [];
6var allCoupons = '';
7
8// Simplified URL parameter function
9const getUrlParameter = (param) => new URLSearchParams(window.location.search).get(param);
10
11// Open or create the IndexedDB
12function openDB() {
13    return new Promise((resolve, reject) => {
14        const request = indexedDB.open("productsDB", 2);
15
16        request.onerror = (event) => {
17            console.log("Error opening database", event);
18            reject(event);
19        };
20
21        request.onsuccess = (event) => {
22            const db = event.target.result;
23            resolve(db);
24        };
25
26        request.onupgradeneeded = (event) => {
27            const db = event.target.result;
28            if (!db.objectStoreNames.contains("jsonStore")) {
29                db.createObjectStore("jsonStore", { autoIncrement: true });
30            }
31        };
32    });
33}
34
35// Get data from IndexedDB by ID
36async function getDataFromIndexedDB(id) {
37    const db = await openDB(); // Open the database
38
39    return new Promise((resolve, reject) => {
40        const transaction = db.transaction(["jsonStore"], "readonly"); // Open a readonly transaction
41        const objectStore = transaction.objectStore("jsonStore"); // Access the object store
42        const request = objectStore.get(id); // Get data by id
43
44        request.onsuccess = (event) => {
45            const data = event.target.result;
46            resolve(data); // Resolve with the retrieved data
47        };
48
49        request.onerror = (event) => {
50            console.error("Error retrieving data from IndexedDB", event);
51            reject(event); // Reject with the error
52        };
53    });
54}
55
56// Add or update data in IndexedDB with a timestamp
57function addDataToIndexedDB(key, data) {
58    return openDB().then(db => {
59        return new Promise((resolve, reject) => {
60            const transaction = db.transaction(["jsonStore"], "readwrite");
61            const objectStore = transaction.objectStore("jsonStore");
62
63            // Add a timestamp to the data
64            const record = {
65                products: data.products,
66                timestamp: Date.now() // Store the current time
67            };
68
69            const request = objectStore.put(record, key);
70
71            request.onsuccess = () => resolve();
72            request.onerror = (event) => {
73                console.error("Error adding data to IndexedDB", event);
74                reject(event);
75            };
76        });
77    });
78}
79
80function deleteDataFromIndexedDB(id) {
81    return openDB().then(db => {
82        return new Promise((resolve, reject) => {
83            const transaction = db.transaction(["jsonStore"], "readwrite");
84            const objectStore = transaction.objectStore("jsonStore");
85
86            const request = objectStore.delete(id);
87
88            request.onsuccess = () => {
89                console.log(`Record with id ${id} deleted successfully`);
90                resolve();
91            };
92
93            request.onerror = (event) => {
94                console.error(`Error deleting record with id ${id} from IndexedDB`, event);
95                reject(event);
96            };
97        });
98    });
99}
100
101// Delete all records from IndexedDB
102function deleteAllDataFromIndexedDB() {
103    return openDB().then(db => {
104        return new Promise((resolve, reject) => {
105            const transaction = db.transaction(["jsonStore"], "readwrite");
106            const objectStore = transaction.objectStore("jsonStore");
107
108            const request = objectStore.clear(); // Clear all records
109
110            request.onsuccess = () => {
111                console.log("All records deleted successfully");
112                resolve();
113            };
114
115            request.onerror = (event) => {
116                console.error("Error deleting all records from IndexedDB", event);
117                reject(event);
118            };
119        });
120    });
121}
122
123async function clearAllIndexedDBData() {
124    const db = await openDB();
125    const transaction = db.transaction(["jsonStore"], "readwrite");
126    const objectStore = transaction.objectStore("jsonStore");
127
128    return new Promise((resolve, reject) => {
129        const clearRequest = objectStore.clear();
130
131        clearRequest.onsuccess = () => {
132            console.log("All records cleared from IndexedDB");
133            resolve();
134        };
135
136        clearRequest.onerror = (event) => {
137            console.error("Error clearing IndexedDB records", event);
138            reject(event);
139        };
140    });
141}
142
143// Fetch data from the server
144function fetchDataFromServer( params ) {
145    return jQuery.ajax({
146        type: 'GET',
147        url: sitedata.svt_ajax_url,
148        data: params,
149        dataType: 'json',
150        cache: true,
151    });
152}
153
154// Check if the data is expired (older than 15 minutes)
155function isDataExpired(timestamp) {
156    if(typeof timestamp == "undefined") {
157        return true;
158    }
159    const currentTime = Date.now();
160    const timeDiff = (currentTime - timestamp) / (1000 * 60); // Time difference in minutes
161    return timeDiff > 15; // Return true if more than 15 minutes have passed
162}
163
164// Check data from IndexedDB and fetch from server if expired or not found
165async function checkAndFetchData(id) {
166    try {
167        const dataRecord = await getDataFromIndexedDB(id);
168        const currentTimestamp = Date.now(); // Use current time for comparison
169        
170        // Prepare the parameters for server fetch
171        const params = {
172            action: 'list_products_json'
173        };
174
175        if (id === 'cateringProducts') {
176            params.priceListID = getCookie('cateringPriceListID');
177        } else if (id === 'myItems') {
178            params.action = 'get_my_items';
179        }
180
181        if (dataRecord) {
182            const { products, timestamp } = dataRecord;
183
184            // Check if the data has expired (15 minutes)
185            /*if (isDataExpired(timestamp, currentTimestamp)) {
186                return await updateData(id, params);
187            }*/
188
189            // Data is valid
190            if (products) {
191                return products;
192            } else {
193                console.log(`${id} is null. Fetching from server...`);
194                return await updateData(id, params);
195            }
196        } else {
197            console.log(`${id} data not found in IndexedDB. Fetching from server...`);
198            return await updateData(id, params);
199        }
200    } catch (error) {
201        console.error("Error:", error);
202    }
203}
204
205// Helper function to update data
206async function updateData(id, params) {
207    const serverData = await fetchDataFromServer(params);
208    if (serverData.products) {
209        if (typeof serverData.products === "string") {
210            serverData.products = JSON.parse(serverData.products);
211        }
212        await addDataToIndexedDB(id, serverData);
213    }
214    return serverData.products; // Return the fetched data
215}
216
217
218function formatPrice(priceStr, unit, avgWeight) {
219    // Remove $ sign
220    let clean = priceStr.replace('$', '').trim();
221
222    if(avgWeight) {
223        clean = (parseFloat(clean) * avgWeight);
224        clean = (clean.toFixed(2)).toString();
225    }
226
227    // Split into dollars + cents
228    let [dollars, cents] = clean.split('.');
229
230    // Default cents if missing
231    cents = cents || "00";
232
233    // If price is less than $1 → show only cents (e.g., 0.69 → 69¢)
234    if (Number(dollars) === 0) {
235        return `
236        <div class="svt-product-org-price under-1">
237            <span class="price-dollar">${cents}</span>
238            <span class="price-currency">¢${(unit) ? '/'+unit : ''}</span>
239        </div>
240        `;
241    }
242
243    // Normal price format
244    return `
245    <div class="svt-product-org-price">
246        <span class="price-currency">$</span>
247        <span class="price-dollar">${dollars}</span>
248        <span class="price-cents">${cents}${(unit) ? '/'+unit : ''}</span>
249    </div>
250    `;
251}
252
253function isFreePromo(promo) {
254    return promo
255        && typeof promo === 'object'
256        && promo.tag
257        && promo.tag.toLowerCase() === 'free';
258}
259
260function isTprPromo(promo) {
261    return promo
262        && typeof promo === 'object'
263        && !isFreePromo(promo)
264        && typeof promo.salePrice === 'number'
265        && promo.salePrice > 0;
266}
267
268function isComplexPromo(promo) {
269    return promo
270        && typeof promo === 'object'
271        && !isFreePromo(promo)
272        && !isTprPromo(promo);
273}
274
275function getGridPromotionsForProduct(promotions, productName) {
276    const promoList =
277        promotions?.items?.[productName]?.primary || [];
278
279    if (!Array.isArray(promoList) || promoList.length === 0) {
280        return { free: null, tpr: null, complex: null };
281    }
282
283    // free promo will always be first (as per BE contract)
284    const freePromo = isFreePromo(promoList[0])
285        ? promoList[0]
286        : null;
287
288    const firstTpr = promoList.find(p => isTprPromo(p)) || null;
289    const firstComplex = promoList.find(p => isComplexPromo(p)) || null;
290
291    return {
292        free: freePromo,
293        tpr: firstTpr,
294        complex: firstComplex
295    };
296}
297
298function getSalePrice(product, promos) {
299    const { complex, tpr, free } = promos;
300
301    if(free) {
302        return 'FREE';
303    }
304
305    // 1. Try complex sale price first
306    if (complex?.salePrice) {
307        return complex.salePrice;
308    }
309
310    // 2.If complex exists but has NO sale price, fallback to TPR price
311    if (complex && tpr?.salePrice) {
312        return tpr.salePrice;
313    }
314
315    // 3.Otherwise just use TPR (no complex at all)
316    if (tpr?.salePrice) {
317        return tpr.salePrice;
318    }
319
320    // 4.fallback to regular price
321    return product.regularPrice;
322}
323
324
325function buildStyledPromoHTML(styledTagLb, promoID) {
326    const promoHTML = styledTagLb.map(tagGroup => {
327        let prevText = "";
328
329        const inner = tagGroup.map(tagData => {
330            const tag = tagData[0];
331            const currentText = tag.text;
332
333            let addMargin = false;
334            const prevEnds = prevText.slice(-1);
335            const currStarts = currentText[0];
336
337            addMargin =
338                prevText &&
339                /[A-Za-z0-9]$/.test(prevEnds) &&
340                /[A-Za-z0-9]/.test(currStarts) &&
341                prevEnds !== "/" &&
342                currStarts !== "$";
343
344            prevText = currentText;
345
346            return `
347                <span class="promo-${tag.weight} promo-${tag.size}"
348                    style="${addMargin ? 'margin-left:4px;' : ''}">
349                    ${currentText}
350                </span>
351            `;
352        }).join("");
353
354        return `<span class="svt-promo-label">${inner}</span>`;
355    }).join("");
356
357    return `
358        <div class="svt-product-new-promo-wrap">
359            <div class="svt-product-new-promo svt-promotion-link" data-id="${promoID}">
360                ${promoHTML}
361            </div>
362        </div>
363    `;
364}
365
366function filterUsableCoupons(coupons) {
367  if (!Array.isArray(coupons)) return [];
368
369  return coupons.filter(coupon =>
370    coupon?.isclippable || coupon?.isclipped
371  );
372}
373
374function couponAppliesToUpc(coupon, upc, productMap) {
375  if (!coupon || !Array.isArray(coupon.upcs)) return false;
376  if (!upc) return false;
377
378  const regex = /^02\d{5}0{5}\d$/;
379
380  // Normalize the incoming UPC the same way
381  function normalize(upcID) {
382    let id = regex.test(upcID) ? upcID.slice(1, 7) : upcID;
383
384    if (id.length > 6) {
385      id = id.replace(/^0+/, '').slice(0, -1);
386    }
387
388    return id;
389  }
390
391  const target = normalize(upc);
392
393  return coupon.upcs.some(upcID => {
394    const normalized = normalize(upcID);
395
396    // If you're matching against productMap like your snippet
397    if (productMap) {
398      const product = productMap.get(normalized);
399      return product && normalized === target;
400    }
401
402    // fallback: compare normalized UPC values directly
403    return normalized === target;
404  });
405}
406
407function couponAppliesToMerchandiseDepartmentCode(coupon, code) {
408  if (!coupon || !Array.isArray(coupon.merchandiseDepartmentCodes)) return false;
409  if (!code) return false;
410
411  return coupon.merchandiseDepartmentCodes.includes(code);
412}
413
414function couponAppliesToProduct(coupon, product) {
415  if (!coupon || !product) return false;
416
417  return (
418    couponAppliesToUpc(coupon, product.upc) ||
419    couponAppliesToMerchandiseDepartmentCode(
420      coupon,
421      product.merchandiseDepartmentCode
422    )
423  );
424}
425
426function filterApplicableCouponsForProduct(product, coupons) {
427  if (
428    !product ||
429    (!product.upc && !product.merchandiseDepartmentCode) ||
430    !Array.isArray(coupons) ||
431    coupons.length === 0
432  ) {
433    return [];
434  }
435
436  return coupons.filter(coupon =>
437    couponAppliesToProduct(coupon, product)
438  );
439}
440
441function getGridCouponForProduct(product, coupons) {
442  if (!product || !Array.isArray(coupons) || coupons.length === 0) {
443    return null;
444  }
445
446  const applicable = filterApplicableCouponsForProduct(product, coupons);
447  const usable = filterUsableCoupons(applicable);
448
449  return usable.length > 0 ? usable[0] : null;
450}
451
452function getGridCouponHTML( product, coupon ) {
453    if(!coupon) return '';
454    const user = JSON.parse(localStorage.getItem('user'));
455    var pointsRequired = coupon.pointrequirement; 
456    let couponHTML = '';
457    var points = 0;
458    if(user != null) {
459        points = user.loyaltyAccount.pointbalance;
460    }
461    if(pointsRequired == null) {
462        pointsRequired = 0;
463    }
464    let confirmationPopup = '';
465    if(pointsRequired) {
466        confirmationPopup = `
467            <div class="svt-list-point-confirmation-popup">
468                <div class="svt-list-point-confirmation-popup-text">
469                    Clipping this coupon will use ${pointsRequired} reward points. Do you want to continue?
470                </div>
471                <div class="svt-list-point-confirmation-popup-actions">
472                    <a href="javascript:void(0);" class="cancel-list-coupon">Cancel</a>
473                    <a href="javascript:void(0);" class="confirm-list-coupon">Confirm</a>
474                </div>
475            </div>
476        `;
477    }
478    const checked = coupon.isclipped ? 'checked="checked"' : '';
479    if(pointsRequired <= points) {
480        couponHTML = `
481            <div class="svt-list-item-coupon">
482                <div class="svt-custom-checkbox">
483                    <input type="checkbox" id="coupon_${product.name}_${coupon.couponid}" name="coupon_${coupon.couponid}" value="${coupon.couponid}" ${checked}>
484                    <span class="checkmark"></span>
485                    <label class="svt-custom-checkbox-lable" for="coupon_${product.name}_${coupon.couponid}">
486                        ${coupon.title}
487                    </label>
488                </div>
489                ${confirmationPopup}
490            </div>
491        `;
492    }
493    return couponHTML;
494}
495
496
497function loadProductCoupons() {
498  const coupons = JSON.parse(sessionStorage.getItem('buyAgainCoupons')) || [];
499  const user = JSON.parse(localStorage.getItem('user'));
500
501  let productsData = allProducts.products || [];
502  let productMap = new Map();
503
504  productsData.forEach(product => {
505    let productUpc = product.upc;
506
507    if (productUpc && productUpc.length > 6) {
508      productUpc = productUpc.replace(/^0+/, '').slice(0, -1);
509    }
510
511    productMap.set(productUpc, product);
512  });
513
514  // Loop all products instead of coupons
515  productMap.forEach((product) => {
516    const coupon = getGridCouponForProduct(product, coupons);
517
518    if (!coupon) return;
519
520    const productID = product.name;
521    const $box = jQuery('.svt-product-box[data-id="' + productID + '"]');
522
523    if ($box.length === 0) return;
524
525    let pointsRequired = coupon.pointrequirement || 0;
526    let points = user?.loyaltyAccount?.pointbalance || 0;
527
528    let confirmationPopup = "";
529
530    if (pointsRequired) {
531      confirmationPopup = `
532        <div class="svt-list-point-confirmation-popup">
533          <div class="svt-list-point-confirmation-popup-text">
534            Clipping this coupon will use ${pointsRequired} reward points. Do you want to continue?
535          </div>
536          <div class="svt-list-point-confirmation-popup-actions">
537            <a href="javascript:void(0);" class="cancel-list-coupon">Cancel</a>
538            <a href="javascript:void(0);" class="confirm-list-coupon">Confirm</a>
539          </div>
540        </div>
541      `;
542    }
543
544    const checked = coupon.isclipped ? 'checked="checked"' : '';
545
546    let couponHTML = "";
547
548    if (pointsRequired <= points) {
549      couponHTML = `
550        <div class="svt-list-item-coupon">
551          <div class="svt-custom-checkbox">
552            <input type="checkbox"
553              id="coupon_${product.name}_${coupon.couponid}"
554              name="coupon_${product.name}_${coupon.couponid}"
555              value="${coupon.couponid}"
556              ${checked}>
557
558            <span class="checkmark"></span>
559
560            <label class="svt-custom-checkbox-lable"
561              for="coupon_${product.name}_${coupon.couponid}">
562              ${coupon.title}
563            </label>
564          </div>
565
566          ${confirmationPopup}
567        </div>
568      `;
569    }
570
571    $box.find(".svt-product-coupon-wrap").html(couponHTML);
572  });
573}
574
575function getWeightUnit() {
576    const location = JSON.parse(localStorage.getItem('ls.location'));
577    return location.weightUnit || 'lb';
578}
579
580function isFloat(n) {
581    return typeof n === 'number' && !Number.isInteger(n);
582}
583
584function getStyledPriceRangeFromZeroPriceTag(tag) {
585    if (tag == '') return null;
586
587    var match = tag.match(/^\s*\$?\s*([\d,]+(?:\.\d{1,2})?)\s*-\s*\$?\s*([\d,]+(?:\.\d{1,2})?)\s*$/);
588    if (!match) return null;
589
590    var min = parseFloat(match[1].replace(/,/g, ''));
591    var max = parseFloat(match[2].replace(/,/g, ''));
592
593    if (min < 0 || max < 0) return null;
594
595    return {
596        min: formatPrice(min.toString()),
597        max: formatPrice(max.toString()),
598    };
599}
600
601function renderProductCard( product, promotions, pricelist, pListName, screenName = 'Home' ) {
602    var html = '';
603    var productID = product.name;
604    let productTitle = product.displayName;
605    var promoText = '';
606    var promoSalePrice = '';
607    var promoID = '';
608    var showEligibleItems = true;
609    var imgName = product.mainImage;
610    if(typeof imgName == "undefined" || imgName == null) {
611        imgName = productID;
612    }
613    var productImg = 'https://s3-us-west-2.amazonaws.com/www.gethomesome.com/productimages_tn/'+imgName+'.jpg';
614    let productPromoHTML = '';
615    // console.log(promotions);
616    let promo = null;
617    
618    const gridPromos = getGridPromotionsForProduct(promotions, productID);
619
620    const activePromo =
621        gridPromos.complex ||
622        gridPromos.tpr ||
623        gridPromos.free ||
624        null;
625
626    // FREE or TPR → no eligible items
627    if (gridPromos.free || gridPromos.tpr) {
628        showEligibleItems = false;
629    }
630
631    // COMPLEX → show eligible items
632    if (gridPromos.complex) {
633        showEligibleItems = true;
634    }
635
636    if (activePromo) {
637        promoID = activePromo.id;
638        promoText = activePromo.tag;
639        promoSalePrice = getSalePrice(product, gridPromos)|| '';
640    }
641
642    if (activePromo && promoID) {
643        const promoObj = promotions?.promotions?.[promoID];
644
645        if (Array.isArray(promoObj?.styledTagLb)) {
646            productPromoHTML = buildStyledPromoHTML(promoObj.styledTagLb, promoID);
647        }
648    }
649    
650    var activeQty = '';
651    var activeMinus = '';
652    var qtyVal = 1;
653    var unitQty = product.unitQuantity;
654
655    let price = product.price;
656
657    if(typeof unitQty == "undefined" || unitQty == null) {
658        unitQty = 1;
659    }
660
661    let weightUnit = getWeightUnit();
662    
663    let weightInPrice = weightUnit;
664
665    let unitIncrement = 1;
666
667    if(product.unit == weightUnit) {
668        unitIncrement = product?.unitIncrement || 0.5;
669        unitQty = unitIncrement;
670        if(promoText != '') {
671            promoText += ' /'+weightUnit;
672        }
673    }
674
675    let avgWeight = '';
676
677    let eaEstimate = '';
678    
679    if(product.unit == weightUnit && product.sellByQty == true && promoSalePrice !== 'FREE') {
680        avgWeight = product.avgWeight;
681        weightInPrice = '';
682        eaEstimate = ' ea (est.)';
683        unitQty = 1;
684        unitIncrement = 1;
685        productTitle += ` (${unitQty} Count)`;
686    }    
687    
688    if(product.unit != weightUnit) {
689        weightInPrice = '';
690    }   
691    
692
693    var redirectPDP = (product.hasModifiers) == false ? '#' : sitedata.pdpurl+'?product='+product.name;
694    // redirectPDP = sitedata.pdpurl+'?product='+product.name;
695    qtyVal = unitQty;
696
697    if(product.minQuantity > 0) {
698        qtyVal = product.minQuantity;
699    }
700
701    let escapedData = JSON.stringify(product).replace(/'/g, "&#39;");
702    
703    var isFav = '';
704
705    var basket = localStorage.getItem('basket');
706    if(typeof pricelist != "undefined" && pricelist != null) {
707        basket = localStorage.getItem('basket_'+pricelist);
708    }
709
710    if(basket != null) {
711        basket = JSON.parse(basket);
712        let items = [];
713        if(typeof basket.items != "undefined") {
714            items = basket.items;
715        }
716        else if(typeof basket.basketItems != "undefined") {
717            items = basket.basketItems;
718        }
719        var productInBasket = items.filter(obj => obj.name == productID);
720        if(productInBasket.length) {
721            qtyVal = productInBasket[0].quantity;
722            activeQty = 'active-qty';
723            if(qtyVal > 1) {
724                if(product.minQuantity > 0) {
725                    if(qtyVal > product.minQuantity) {
726                        activeMinus = ' active-minus';
727                    }
728                }
729                else {
730                    activeMinus = ' active-minus';
731                }
732            }
733        }
734        else {
735            activeQty = '';
736        }
737    }
738
739    if(Object.keys(myItems).length) {
740        var productIDS = Object.keys(myItems);
741        if(productIDS.includes(productID)) {
742            isFav = 'in-fav';
743        }
744    }
745
746    var cat = sanitizeTitle(product.type);
747
748    if(typeof pricelist == "undefined" || pricelist == null) {
749        pricelist = '';
750    }
751    
752    if(typeof pListName == "undefined" || pListName == null) {
753        pListName = '';
754    }
755
756    var pdpLink = embeddata.product+'?product='+productID;
757
758    if(pListName) {
759        pdpLink += '&pListName='+pListName;
760    }
761
762    let ebtEnabled = false;
763
764    const location = JSON.parse(sessionStorage.getItem('ls.location'));
765
766    if(location != null) {
767        if(typeof location.ebtConfig != "undefined") {
768            if(location.ebtConfig.enabled == true && product.ebtSnapEligible == true) {
769                ebtEnabled = true;
770            }
771        }
772    }
773
774    let isZeroPrice = false;
775
776    var zeroPriceObj = {};
777
778    if(price == 0 && product.zeroPriceTag != '' && product.zeroPriceInfo != '') {
779        isZeroPrice = true;
780        zeroPriceObj = getStyledPriceRangeFromZeroPriceTag(product.zeroPriceTag);
781    }
782
783    let isInStock = product.isInStock;
784
785    let priceFormatted = price;
786
787    if(priceFormatted != 'Free') {
788        priceFormatted = formatPrice(parseFloat(priceFormatted).toFixed(2), weightInPrice, avgWeight);
789    }
790
791    if(promoText == 'free') {
792        promoSalePrice = 'FREE';
793    }
794
795    let couponHTML = '';
796    const loggedIn = isUserLoggedIn();
797    if(loggedIn) {
798        const coupons = JSON.parse(sessionStorage.getItem('buyAgainCoupons'));
799        const couponData = getGridCouponForProduct(product, coupons);    
800        couponHTML = getGridCouponHTML( product, couponData );
801    }
802
803    html += '<div class="svt-product-box '+cat+' '+isFav+'" data-id="'+productID+'">'+
804        '<div class="svt-product-img-wrap">'+
805            '<a href="javascript:void(0);" class="open-pdp" data-id="'+productID+'" data-pricelist="'+pricelist+'" aria-hidden="true" aria-label="'+productTitle+'">'+
806                '<img src="'+productImg+'" onerror="this.onerror=null; this.className=\'placeholder-img\'; this.src=\''+embeddata.theme_url+'/images/nophoto-v2.svg\'" alt="'+productTitle+'" />'+
807            '</a>'+
808            '<a href="javascript:void(0);" class="svt-product-favourite" data-id="'+productID+'" aria-hidden="true" aria-label="Add to My Items">'+
809                '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 21L12 16L5 21V5C5 4.46957 5.21071 3.96086 5.58579 3.58579C5.96086 3.21071 6.46957 3 7 3H17C17.5304 3 18.0391 3.21071 18.4142 3.58579C18.7893 3.96086 19 4.46957 19 5V21Z" stroke="#767676" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg>'+
810            '</a>'+
811            '<a href="javascript:void(0);" class="svt-product-list-remove" data-id="'+productID+'" aria-hidden="true" aria-label="Remove from My Items">'+
812                '<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M19 21L12 16L5 21V5C5 4.46957 5.21071 3.96086 5.58579 3.58579C5.9
8126086 3.21071 6.46957 3 7 3H17C17.5304 3 18.0391 3.21071 18.4142 3.58579C18.7893 3.96086 19 4.46957 19 5V21Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /></svg>'+
813                //'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10 10.25C10.4142 10.25 10.75 10.5858 10.75 11V17C10.75 17.4142 10.4142 17.75 10 17.75C9.58579 17.75 9.25 17.4142 9.25 17V11C9.25 10.5858 9.58579 10.25 10 10.25Z" fill="#767676" /><path d="M14.75 11C14.75 10.5858 14.4142 10.25 14 10.25C13.5858 10.25 13.25 10.5858 13.25 11V17C13.25 17.4142 13.5858 17.75 14 17.75C14.4142 17.75 14.75 17.4142 14.75 17V11Z" fill="#767676" /><path fill-rule="evenodd" clip-rule="evenodd" d="M7.25 5.25V4C7.25 3.27065 7.53973 2.57118 8.05546 2.05546C8.57118 1.53973 9.27065 1.25 10 1.25H14C14.7293 1.25 15.4288 1.53973 15.9445 2.05546C16.4603 2.57118 16.75 3.27065 16.75 4V5.25H21C21.4142 5.25 21.75 5.58579 21.75 6C21.75 6.41421 21.4142 6.75 21 6.75H19.75V20C19.75 20.7293 19.4603 21.4288 18.9445 21.9445C18.4288 22.4603 17.7293 22.75 17 22.75H7C6.27065 22.75 5.57118 22.4603 5.05546 21.9445C4.53973 21.4288 4.25 20.7293 4.25 20V6.75H3C2.58579 6.75 2.25 6.41421 2.25 6C2.25 5.58579 2.58579 5.25 3 5.25H7.25ZM9.11612 3.11612C9.35054 2.8817 9.66848 2.75 10 2.75H14C14.3315 2.75 14.6495 2.8817 14.8839 3.11612C15.1183 3.35054 15.25 3.66848 15.25 4V5.25H8.75V4C8.75 3.66848 8.8817 3.35054 9.11612 3.11612ZM5.75 6.75H18.25V20C18.25 20.3315 18.1183 20.6495 17.8839 20.8839C17.6495 21.1183 17.3315 21.25 17 21.25H7C6.66848 21.25 6.35054 21.1183 6.11612 20.8839C5.8817 20.6495 5.75 20.3315 5.75 20V6.75Z" fill="#767676" /></svg>'+
814            '</a>';
815            if(ebtEnabled) {
816                html += '<div class="ebt-badge-container">'+
817                    '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">'+
818                        '<path d="M10.4685 10.3573H12.1049C12.3163 10.3573 12.5191 10.435 12.6686 10.5732C12.8181 10.7113 12.9021 10.8988 12.9021 11.0942C12.9021 11.2896 12.8181 11.477 12.6686 11.6152C12.5191 11.7534 12.3163 11.831 12.1049 11.831H10.4685V10.3573Z" fill="#767676"></path>'+
819                        '<path d="M12.7343 14.6427H10.4685V13.1302H12.7343C12.838 13.1276 12.9411 13.1442 13.0378 13.1791C13.1344 13.214 13.2224 13.2665 13.2968 13.3334C13.3711 13.4002 13.4301 13.4802 13.4704 13.5685C13.5108 13.6569 13.5315 13.7518 13.5315 13.8476C13.5402 13.9492 13.526 14.0513 13.4898 14.1475C13.4537 14.2437 13.3964 14.332 13.3214 14.4067C13.2465 14.4814 13.1557 14.5409 13.0546 14.5816C12.9535 14.6222 12.8445 14.643 12.7343 14.6427Z" fill="#767676"></path>'+
820                        '<path fill-rule="evenodd" clip-rule="evenodd" d="M2 4C0.895431 4 0 4.89543 0 6V18C0 19.1046 0.89543 20 2 20H22C23.1046 20 24 19.1046 24 18V6C24 4.89543 23.1046 4 22 4H2ZM6.82843 10.1586C6.71858 10.2858 6.56958 10.3573 6.41423 10.3573H4.13807V11.831H5.25941C5.40645 11.8304 5.54831 11.8939 5.65683 12.0088C5.76535 12.1238 5.83259 12.2818 5.84519 12.4515C5.84519 12.6315 5.78347 12.8041 5.67362 12.9314C5.56377 13.0587 5.41477 13.1302 5.25941 13.1302H4.13807V14.6427H6.41423C6.56958 14.6427 6.71858 14.7142 6.82843 14.8414C6.93828 14.9687 7 15.1413 7 15.3213C7 15.5013 6.93828 15.6739 6.82843 15.8012C6.71858 15.9285 6.56958 16 6.41423 16H3.58577C3.43536 15.9975 3.29153 15.9281 3.1841 15.8061C3.07015 15.6788 3.00402 15.5047 3 15.3213V9.67867C3 9.49868 3.06172 9.32605 3.17157 9.19878C3.28142 9.0715 3.43042 9 3.58577 9H6.41423C6.56958 9 6.71858 9.0715 6.82843 9.19878C6.93828 9.32605 7 9.49868 7 9.67867C7 9.85867 6.93828 10.0313 6.82843 10.1586ZM13.972 12.1994C14.2049 11.9047 14.3431 11.5552 14.3706 11.1911C14.3848 10.9081 14.3367 10.6253 14.2292 10.3599C14.1217 10.0945 13.9571 9.85209 13.7453 9.64724C13.5334 9.4424 13.2788 9.27941 12.9969 9.16816C12.7149 9.0569 12.4115 8.9997 12.1049 9H9.73427C9.53953 9 9.35276 9.0715 9.21506 9.19878C9.07736 9.32606 9 9.49868 9 9.67867V15.3213C9 15.5013 9.07736 15.6739 9.21506 15.8012C9.35276 15.9285 9.53953 16 9.73427 16H12.7343C13.3352 16 13.9115 15.7794 14.3364 15.3866C14.7613 14.9939 15 14.4612 15 13.9058C14.9898 13.5659 14.891 13.2334 14.712 12.9363C14.5331 12.6392 14.2792 12.3865 13.972 12.1994ZM16.1878 9.19878C16.308 9.0715 16.471 9 16.641 9H20.359C20.529 9 20.692 9.0715 20.8122 9.19878C20.9325 9.32605 21 9.49868 21 9.67867C21 9.85867 20.9325 10.0313 20.8122 10.1586C20.692 10.2858 20.529 10.3573 20.359 10.3573H19.1319V15.3213C19.1319 15.5013 19.0643 15.6739 18.9441 15.8012C18.8239 15.9285 18.6609 16 18.4908 16C18.3208 16 18.1578 15.9285 18.0376 15.8012C17.9174 15.6739 17.8498 15.5013 17.8498 15.3213V10.3573H16.641C16.471 10.3573 16.308 10.2858 16.1878 10.1586C16.0675 10.0313 16 9.85867 16 9.67867C16 9.49868 16.
8200675 9.32605 16.1878 9.19878Z" fill="#767676"></path>'+
821                    '</svg>'+
822                    '<span style="display:none;">EBT Eligible</span>'+
823                '</div>';
824            }
825            if(isInStock) {
826                html += 
827                '<div class="svt-product-add-cart '+activeQty+'" data-minQty="'+product.minQuantity+'" data-maxQty="'+product.maxQuantity+'" data-unit="'+unitQty+'" data-pricelist="'+pricelist+'" data-screen="'+screenName+'">'+
828                    '<input type="hidden" name="productObj" value=\''+escapedData+'\'>'+
829                    '<a href="javascript:void(0);" class="initial-add add-to-cart-action '+(redirectPDP !== '#' ? "redirectpdp open-pdp" : "")+'" aria-hidden="true" aria-label="Add to Cart" data-id="'+productID+'" data-pricelist="'+pricelist+'">'+
830                        '<svg width="11" height="11" viewBox="0 0 11 11" fill="currentColor" xmlns="http://www.w3.org/2000/svg" class="ng-scope"><g id="Group 347"><path id="Vector" d="M5.66699 1V10.3333" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"></path><path id="Vector_2" d="M1 5.66699H10.3333" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>'+
831                        '<span>Add</span>'+
832                    '</a>'+
833                    '<div class="svt-product-qty '+activeMinus+'">'+
834                        '<button class="svt-product-delete" aria-hidden="true" aria-label="Delete from Cart">'+
835                            '<svg width="20" height="22" viewBox="0 0 20 22" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="Group 338"><path id="Vector" d="M1 5H3H19" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path id="Vector_2" d="M17 5V19C17 19.5304 16.7893 20.0391 16.4142 20.4142C16.0391 20.7893 15.5304 21 15 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V5M6 5V3C6 2.46957 6.21071 1.96086 6.58579 1.58579C6.96086 1.21071 7.46957 1 8 1H12C12.5304 1 13.0391 1.21071 13.4142 1.58579C13.7893 1.96086 14 2.46957 14 3V5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path id="Vector_3" d="M8 10V16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path id="Vector_4" d="M12 10V16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>'+
836                        '</button>'+
837                        '<button class="svt-minus-qty" aria-hidden="true" aria-label="Decrease Quantity">'+
838                            '<svg width="11" height="2" viewBox="0 0 11 2" fill="currentColor" xmlns="http://www.w3.org/2000/svg" class="ng-scope"><g id="Group 347"><path id="Vector" d="M1 0.666992H10.3333" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>'+
839                        '</button>'+
840                        '<div class="qty-value">'+qtyVal+'</div>'+
841                        '<button class="svt-qty-plus" aria-hidden="true" aria-label="Increase Quantity">'+
842                            '<svg width="11" height="11" viewBox="0 0 11 11" fill="currentColor" xmlns="http://www.w3.org/2000/svg" class="ng-scope"><g id="Group 347"><path id="Vector" d="M5.66699 1V10.3333" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"></path><path id="Vector_2" d="M1 5.66699H10.3333" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>'+
843                        '</button>'+
844                        '<div class="bouncing-loader small-loader">'+
845                            '<div></div>'+
846                            '<div></div>'+
847                            '<div></div>'+
848                        '</div>'+
849                    '</div>'+
850                '</div>';
851            }
852            else {
853                html += '<div class="svt-out-of-stock-badge">Sold Out!</div>';
854            }
855            html +=
856        '</div>';
857        html += '<div class="svt-product-info-wrap">';
858            if(isZeroPrice == false) {
859                if((promoSalePrice != '' && promoSalePrice > 0) || promoSalePrice == 'FREE') {
860                    let promoPriceFormatted = `<span class="price-dollar">${promoSalePrice}</span>`;
861                    if(promoSalePrice != 'FREE') {
862                        promoPriceFormatted = formatPrice(parseFloat(promoSalePrice).toFixed(2), weightInPrice, avgWeight);
863                    }
864                    var avgPrice = price;
865                    if(product.sellByQty == true) {
866                        avgPrice = price * avgWeight;
867                    }
868                    html += '<div class="svt-product-price">';
869                        html += '<div class="svt-product-sale-price">';
870                            html += promoPriceFormatted;
871                        html += '</div>';
872                        html += "<div class='svt-product-old-price'>$"+parseFloat(avgPrice).toFixed(2)+"</div>";
873                        html += '<div class="svt-product-each-estimate">'+eaEstimate+'</div>';
874                    html += '</div>';    
875                }
876                else {
877                    html += '<div class="svt-product-price">';
878                    html += priceFormatted;
879                    html += '<div class="svt-product-each-estimate">'+eaEstimate+'</div>';
880                    html += '</div>';
881                }
882            }
883            else {
884                html += '<div class="svt-product-zero-price">'+
885                '<div class="svt-product-price-info" data-tippy-content="'+product.zeroPriceInfo+'" data-tippy-arrow="true" data-placement="bottom"><svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 22 22" fill="none" class="ng-scope"><path d="M11 21C16.5228 21 21 16.5228 21 11C21 5.47715 16.5228 1 11 1C5.47715 1 1 5.47715 1 11C1 16.5228 5.47715 21 11 21Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M11 15V11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M11 7H11.01" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path> </svg></div>';
886                if(zeroPriceObj == null) {
887                    html += '<span>'+product.zeroPriceTag+'</span>';
888                }
889                else {
890                    html+= '<span class="svt-product-price">'+zeroPriceObj.min +'-'+zeroPriceObj.max +'</span>';
891                }
892                html += '</div>';
893            }
894            html += '<h6><a href="'+pdpLink+'">'+productTitle+'</a></h6>';
895            if(product.sellByQty == true) {
896                var avgOriginalPrice = price;
897                if(promoSalePrice != '' && promoSalePrice != 'FREE') {
898                    avgOriginalPrice = promoSalePrice;
899                }
900                html += '<div class="svt-avg-weight-org-price">$'+parseFloat(avgOriginalPrice).toFixed(2)+'/'+weightUnit+'</div>';
901            }
902        if(productPromoHTML != '' && showEligibleItems) {
903            html += '<div class="svt-product-promo-wrap">';
904            html += productPromoHTML;
905            html += '<div class="svt-product-coupon-wrap">'+couponHTML+'</div>';
906            if(promoID != '') {
907                html += '<a href="javascript:void(0);" data-id="'+promoID+'" class="svt-promotion-link" aria-hidden="true" aria-label="Eligible items">Eligible items</a>';
908            }
909            html += '</div>';
910        }
911        else {
912            html += '<div class="svt-product-coupon-wrap">'+couponHTML+'</div>';
913        }
914    html += '</div>'+
915    '</div>';
916    return html;
917}
918
919function initPriceInfoTip() {
920    tippy('.svt-product-price-info', {
921        placement: 'bottom',
922    });
923}
924
925function renderCouponCard( coupon, productsData ) {
926    var timestamp = coupon.expirationtimestamp;
927    timestamp = timestamp.replace(' ', 'T');
928    var date = new Date(timestamp);
929    var day = date.getDate();
930    var month = date.getMonth() + 1;
931    var year = date.getFullYear();
932    var expiryDate = month+'/'+day+'/'+year;
933    var pointsRequired = coupon.pointrequirement; 
934    var clippable = coupon.isClippable;
935    var clipped = coupon.isclipped; 
936    var upcs = coupon.upcs;
937    // console.log(coupon.tags);
938    var type = '';
939    if(typeof coupon.type !== "undefined") {
940        type = coupon.type;
941        if(typeof type != "undefined") {
942            type = sanitizeTitle(type);
943        }
944        else {
945            type = '';
946        }
947    }
948    let user = localStorage.getItem('user');
949    var rewardPointsElement = 0;
950    if(user != null) {
951        user = JSON.parse(user);
952        rewardPointsElement = user.loyaltyAccount.pointbalance;
953        // console.log('Points from user session', rewardPointsElement);
954    }
955    var points = rewardPointsElement != null ? parseFloat(rewardPointsElement) : 0;
956    points = isNaN(points) ? 0 : points;
957    var clipCouponText = 'Clip Coupon';
958    if(pointsRequired > points) {
959        clipCouponText = 'Need '+pointsRequired+' Pts';
960    }
961    var imgClass = '';
962    if(upcs != null) {
963        imgClass = 'eligible-items-coupon';
964    }
965
966    let eligibleItems = false;
967    
968    let productMap = new Map();
969    const regex = /^02\d{5}0{5}\d$/;
970
971    if (typeof productsData !== "undefined") {
972        productsData.products.forEach(product => {
973            let productUpc = product.upc.length > 6
974                ? product.upc.replace(/^0+/, '').slice(0, -1)
975                : product.upc;
976            productMap.set(productUpc, product);
977        });
978    }
979
980    if (typeof productsData !== "undefined" && coupon.upcs != null) {
981        eligibleItems = coupon.upcs.some(upcID => {
982            let cleanedUpcID = regex.test(upcID) ? upcID.slice(1, 7) : upcID;
983            if (cleanedUpcID.length > 6) {
984                cleanedUpcID = cleanedUpcID.replace(/^0+/, '').slice(0, -1);
985            }
986            return productMap.has(cleanedUpcID);
987        });
988    } else {
989        eligibleItems = true;
990    }
991
992    let couponDetailURL = sitedata.home_url+'/coupon/?id='+coupon.couponid;
993
994    if(eligibleItems == false) {
995        imgClass = '';
996        couponDetailURL = 'javascript:void(0);';
997    }
998
999    let escapedData = JSON.stringify(coupon).replace(/'/g, "&#39;");
1000
1001    var html = `
1002        <div class="svt-coupon-box ${type}" data-id="${coupon.couponid}" data-description="${coupon.description}">
1003            <div class="svt-coupon-img-wrap ${imgClass}" data-obj='${escapedData}' data-id="${coupon.couponid}" data-title="${coupon.title}">
1004                <img src="${coupon.detailmediapath}" onerror="this.onerror=null; this.className='placeholder-img'; this.src='${embeddata.theme_url}/images/nophoto-v2.svg'" alt="${coupon.title}">
1005            </div>
1006            <div class="svt-coupon-actions ${(clipped == true || clippable == false) ? 'clipped' : ''} ${(clippable == false) ? 'noclip' : ''}">
1007                <div class="svt-coupon-clip ${(pointsRequired !== null) ? 'points-required' : ''} ${(pointsRequired > points) ? 'nopoints': ''}">
1008                    <a href="javascript:void(0);" class="clip-action btn-with-loader ${(pointsRequired !== null) ? 'points-required-a' : ''}" data-id="${coupon.couponid}" aria-hidden="true" aria-label="Clip Coupon">
1009                        <div class="btn-txt-wrap">
1010                            <span class="btn-loader"></span>
1011                            <span class="point-needed btn-txt-pre">${(pointsRequired !== null && pointsRequired < points) ? pointsRequired+' Pts' : ''}</span>`;
1012                            if(pointsRequired > points) {
1013                                html += `<svg xmlns="http://www.w3.org/2000/svg" width="25" height="24" viewBox="0 0 25 24" fill="none">
1014                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M9.51035 3.75001C10.665 1.75 13.5527 1.75 14.7074 3.75001L22.061
10145 16.4982C23.2148 18.4981 21.7713 20.997 19.4639 20.997H4.75387C2.4459 20.997 1.00164 18.4984 2.15622 16.4982V16.4982L9.51035 3.75001ZM10.8094 4.49999L3.45553 17.2478C2.87834 18.2475 3.59993 19.497 4.75387 19.497H19.4639C20.6165 19.497 21.3389 18.2478 20.7622 17.2477L13.4083 4.49999C12.831 3.5 11.3867 3.5 10.8094 4.49999ZM12.1089 8.997C12.5231 8.997 12.8589 9.33279 12.8589 9.747V13.497C12.8589 13.9112 12.5231 14.247 12.1089 14.247C11.6947 14.247 11.3589 13.9112 11.3589 13.497V9.747C11.3589 9.33279 11.6947 8.997 12.1089 8.997ZM11.3589 16.497C11.3589 16.0828 11.6947 15.747 12.1089 15.747H12.1159C12.5301 15.747 12.8659 16.0828 12.8659 16.497V16.505C12.8659 16.9192 12.5301 17.255 12.1159 17.255H12.1089C11.6947 17.255 11.3589 16.9192 11.3589 16.505V16.497Z" fill="#222222"/>
1015                                </svg>`;
1016                            }
1017                            else {
1018                                html += `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
1019                                    <path fill-rule="evenodd" clip-rule="evenodd"
1020                                        d="M9.06507 8.07439C9.46634 7.48276 9.70078 6.76878 9.70078 6.00005C9.70078 3.9566 8.04424 2.30005 6.00078 2.30005C3.95733 2.30005 2.30078 3.9566 2.30078 6.00005C2.30078 8.0435 3.95733 9.70005 6.00078 9.70005C6.76951 9.70005 7.48349 9.46561 8.07512 9.06433L11.0108 12L8.07511 14.9358C7.48349 14.5345 6.76951 14.3 6.00078 14.3C3.95733 14.3 2.30078 15.9566 2.30078 18C2.30078 20.0435 3.95733 21.7 6.00078 21.7C8.04424 21.7 9.70078 20.0435 9.70078 18C9.70078 17.2313 9.46634 16.5173 9.06507 15.9257L20.4958 4.49502C20.7691 4.22166 20.7691 3.77844 20.4958 3.50507C20.2224 3.23171 19.7792 3.23171 19.5058 3.50507L12.0008 11.0101L9.06507 8.07439ZM6.00078 3.70005C4.73053 3.70005 3.70078 4.72979 3.70078 6.00005C3.70078 7.2703 4.73053 8.30005 6.00078 8.30005C6.61966 8.30005 7.18146 8.05561 7.59488 7.65802C7.60477 7.64679 7.61507 7.6358 7.6258 7.62507C7.63653 7.61434 7.64752 7.60403 7.65875 7.59415C8.05635 7.18072 8.30078 6.61893 8.30078 6.00005C8.30078 4.72979 7.27104 3.70005 6.00078 3.70005ZM6.00078 15.7C4.73053 15.7 3.70078 16.7298 3.70078 18C3.70078 19.2703 4.73053 20.3 6.00078 20.3C7.27104 20.3 8.30078 19.2703 8.30078 18C8.30078 17.3812 8.05633 16.8193 7.65872 16.4059C7.6475 16.396 7.63652 16.3857 7.6258 16.375C7.61508 16.3643 7.60478 16.3533 7.5949 16.3421C7.18148 15.9445 6.61968 15.7 6.00078 15.7Z"
1021                                        fill="currentColor" />
1022                                    <path
1023                                        d="M13.9754 13.9855C14.2485 13.7119 14.6917 13.7115 14.9653 13.9846L20.4953 19.5046C20.7689 19.7777 20.7693 20.2209 20.4962 20.4946C20.2231 20.7682 19.7799 20.7686 19.5063 20.4955L13.9763 14.9755C13.7026 14.7023 13.7022 14.2591 13.9754 13.9855Z"
1024                                        fill="currentColor" />
1025                                </svg>`;
1026                            }
1027                            html += `
1028                            <span class="btn-txt">${clipCouponText}</span>
1029                        </div>
1030                        <div class="bouncing-loader small-loader">
1031                            <div></div>
1032                            <div></div>
1033                            <div></div>
1034                        </div>
1035                    </a>
1036                </div>
1037                <div class="svt-coupon-clipped">
1038                    <a href="javascript:void(0);" class="unclip-action btn-with-loader" data-id="${coupon.couponid}" aria-hidden="true" aria-label="Unclip Coupon">
1039                        <div class="btn-txt-wrap">
1040                            <span class="btn-loader"></span>
1041                            <span class="btn-txt">
1041Clipped</span>
1042                            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
1043                                <path
1044                                    d="M9 15L3 9M3 9L9 3M3 9H15C16.5913 9 18.1174 9.63214 19.2426 10.7574C20.3679 11.8826 21 13.4087 21 15C21 16.5913 20.3679 18.1174 19.2426 19.2426C18.1174 20.3679 16.5913 21 15 21H12"
1045                                    stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
1046                            </svg>
1047                        </div>
1048                        <div class="bouncing-loader small-loader">
1049                            <div></div>
1050                            <div></div>
1051                            <div></div>
1052                        </div>
1053                    </a>
1054                </div>
1055            </div>
1056            <div class="svt-coupon-info-wrap">
1057                <h5>
1058                `;
1059                if(upcs != null && eligibleItems === true) {
1060                    html += `<a href="${couponDetailURL}">`;
1061                }
1062                html += `${coupon.title}`;
1063                if(upcs != null && eligibleItems === true) {
1064                    html += `</a>`;
1065                }
1066                html += `</h5>
1067                <div class="coupon-expiry">
1068                    Expires ${expiryDate}
1069                </div>
1070                `;
1071                if(upcs != null && eligibleItems === true) {
1072                    html += `<div class="coupon-actions">
1073                        <a href="javascript:void(0);" data-obj='${escapedData}' data-title="${coupon.title}" data-id="${coupon.couponid}" class="eligible-items-coupon">Eligible items</a>
1074                    </div>`;
1075                }
1076                html +=`
1077            </div>
1078        </div>
1079    `;
1080    return html;
1081}
1082
1083function sanitizeTitle(title) {
1084    if(typeof title != "undefined") {
1085    return title
1086        .trim() // Remove whitespace from both sides
1087        .toLowerCase() // Convert to lowercase
1088        .replace(/[^a-z0-9\s-]/g, '') // Remove special characters (keep letters, numbers, spaces, and dashes)
1089        .replace(/\s+/g, '-') // Replace spaces with dashes
1090        .replace(/-+/g, '-'); // Ensure there are no consecutive dashes
1091    }
1092    return '';
1093}
1094
1095function setBasket( basket ) {
1096    const basketObj = {
1097        'items': basket.basketItems,
1098        'itemsTotal': basket.basketItems.length,
1099        'cartSubTotal': parseFloat(basket.basketSubTotal).toFixed(2),
1100        'cartTotal': parseFloat(basket.basketTotal).toFixed(2),
1101        'tax': parseFloat(basket.tax).toFixed(2),
1102        'isPickupOnly': basket.isPickupOnly
1103    }
1104    localStorage.setItem('basket',JSON.stringify(basketObj));
1105}
1106
1107function updateCartCount() {
1108    let user = localStorage.getItem('user');
1109    user = JSON.parse(user);
1110    const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
1111    const email = user.email;
1112
1113    let headers = {
1114        'emailid': email,
1115        'authToken': user.authToken,
1116        'location': getCookie('selectedLocation'),
1117        'pricelist': getCookie('selectedPriceList'),
1118        'Content-Type': 'application/json'
1119    };
1120
1121    api.getData('/user/basket?lite=true', headers)
1122        .then(response => {
1123            if (response.basketItems) {
1124                setBasket(response);
1125                var cartCount = (response.basketItems).length;
1126                if(cartCount > 0) {
1127                    jQuery('.hs-cart-count').html(cartCount);
1128                    jQuery('.hs-cart-count').addClass('active');
1129                }
1130                if(jQuery('.hs-coupon-detail-wrap').length) {
1131                    loadCouponDetailPage();
1132                }
1133            }
1134        })
1135        .catch(error => console.error('Error fetching basket data:', error));
1136}
1137
1138function loadBestDeals( productsData ) {
1139    jQuery('.hs-best-deals-products .shimmer-product-boxes').show();
1140    jQuery('.hs-best-deals-products .svt-product-box:not(.shimmer-product-boxes)').remove();
1141
1142    let dealsproducts = productsData.products;
1143    let promotions = productsData.promotions;
1144    dealsproducts = dealsproducts.filter((product) => product.virtualCategory == 'weekly deals');
1145
1146    if(typeof promotions !== "undefined") {
1147        let productArr = [];
1148        let productArr2 = [];
1149        for (const product of Object.values(dealsproducts)) {
1150            const productID = product.name;
1151            const promoItem = promotions.items[productID];
1152
1153            if (promoItem && promoItem.primary) {
1154                const promoID = promoItem.primary[0].id;
1155                const promoDetails = promotions.promotions[promoID];
1156                if (promoDetails) {
1157                    productArr.push(product);
1158                }
1159                else {
1160                    productArr2.push(product);
1161                }
1162            }
1163        }
1164        const dealsproductsGroup = [...productArr, ...productArr2].slice(0,12);
1165        const html = dealsproductsGroup.map((product) => {
1166            bestDealsIDs.push(product.name);
1167            return renderProductCard(product, promotions);
1168        }).join('');
1169        jQuery('.hs-best-deals-products .shimmer-product-boxes').hide();
1170        jQuery('.hs-best-deals-products').append(html);
1171        initPriceInfoTip();
1172    }
1173}
1174
1175function loadBestSellingProducts( productsData ) {
1176    let bsProducts = productsData.products;
1177    let promotions = productsData.promotions;
1178    // let productArr = [];
1179
1180    // console.log(bestDealsIDs);
1181
1182    bsProducts = bsProducts.filter((product) => !bestDealsIDs.includes(product.name)).slice(0,20);
1183
1184    const html = bsProducts.map(product => renderProductCard(product, promotions)).join('');
1185    jQuery('.hs-best-selling-products').html(html).addClass('svt-product-carousel');
1186    jQuery('.hs-best-selling-products').removeClass('slick-initialized slick-slider');
1187    initPriceInfoTip();
1188
1189    // Initialize slick carousel after a short delay
1190    setTimeout(() => {
1191        if(!jQuery('.hs-best-selling-products').hasClass('slick-initialized slick-slider')) {
1192            jQuery('.hs-best-selling-products').slick({
1193                slidesToShow: 6,
1194                slidesToScroll: 1,
1195                dots: false,
1196                arrows: true,
1197                prevArrow: '<button type="button" aria-hidden="true" aria-label="Previous" class="slick-prev"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.5303 5.46967C15.2374 5.17678 14.7626 5.17678 14.4697 5.46967L8.46967 11.4697C8.17678 11.7626 8.17678 12.2374 8.46967 12.5303L14.4697 18.5303C14.7626 18.8232 15.2374 18.8232 15.5303 18.5303C15.8232 18.2374 15.8232 17.7626 15.5303 17.4697L10.0607 12L15.5303 6.53033C15.8232 6.23744 15.8232 5.76256 15.5303 5.46967Z" fill="currentColor"></path></svg></button>',
1198                nextArrow: '<button type="button" aria-hidden="true" aria-label="Next" class="slick-next"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.46967 5.46967C8.76256 5.17678 9.23744 5.17678 9.53033 5.46967L15.5303 11.4697C15.8232 11.7626 15.8232 12.2374 15.5303 12.5303L9.53033 18.5303C9.23744 18.8232 8.76256 18.8232 8.46967 18.5303C8.17678 18.2374 8.17678 17.7626 8.46967 17.4697L13.9393 12L8.46967 6.53033C8.17678 6.23744 8.17678 5.76256 8.46967 5.46967Z" fill="currentColor"></path></svg></button>',
1199                responsive: [
1200                    {
1201                        breakpoint: 0,
1202                        settings: {
1203                            slidesToShow: 2,
1204                        }
1205                    },
1206                    {
1207                        breakpoint: 767,
1208                        settings: {
1209                            slidesToShow: 2,
1210                        }
1211                    },
1212                    {
1213                        breakpoint: 1024,
1214                        settings: {
1215                            slidesToShow: 4,
1216                        }
1217                    }
1218                ]
1219            });
1220        }
1221    }, 100);
1222}
1223
1224function loadHomeFeaturedProducts( productsData ) {
1225    let bsProducts = productsData.products;
1226    let promotions = productsData.promotions;
1227    // let productArr = [];
1228
1229    // console.log(bestDealsIDs);
1230
1231    let bsProductsArr = bsProducts.filter((product) => !bestDealsIDs.includes(product.name)).slice(20,40);
1232
1233    if(bsProductsArr == false)  {
1234        bsProductsArr = bsProducts.filter((product) => !bestDealsIDs.includes(product.name)).slice(0,20);
1235    }
1236
1237    const html = bsProductsArr.map(product => renderProductCard(product, promotions)).join('');
1238    jQuery('.hs-home-featured-products').html(html).addClass('svt-product-carou
1238sel');
1239    jQuery('.hs-home-featured-products').removeClass('slick-initialized slick-slider');
1240    initPriceInfoTip();
1241
1242    // Initialize slick carousel after a short delay
1243    setTimeout(() => {
1244        if(!jQuery('.hs-home-featured-products').hasClass('slick-initialized slick-slider')) {
1245            jQuery('.hs-home-featured-products').slick({
1246                slidesToShow: 6,
1247                slidesToScroll: 1,
1248                dots: false,
1249                arrows: true,
1250                prevArrow: '<button type="button" aria-hidden="true" aria-label="Previous" class="slick-prev"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.5303 5.46967C15.2374 5.17678 14.7626 5.17678 14.4697 5.46967L8.46967 11.4697C8.17678 11.7626 8.17678 12.2374 8.46967 12.5303L14.4697 18.5303C14.7626 18.8232 15.2374 18.8232 15.5303 18.5303C15.8232 18.2374 15.8232 17.7626 15.5303 17.4697L10.0607 12L15.5303 6.53033C15.8232 6.23744 15.8232 5.76256 15.5303 5.46967Z" fill="currentColor"></path></svg></button>',
1251                nextArrow: '<button type="button" aria-hidden="true" aria-label="Next" class="slick-next"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.46967 5.46967C8.76256 5.17678 9.23744 5.17678 9.53033 5.46967L15.5303 11.4697C15.8232 11.7626 15.8232 12.2374 15.5303 12.5303L9.53033 18.5303C9.23744 18.8232 8.76256 18.8232 8.46967 18.5303C8.17678 18.2374 8.17678 17.7626 8.46967 17.4697L13.9393 12L8.46967 6.53033C8.17678 6.23744 8.17678 5.76256 8.46967 5.46967Z" fill="currentColor"></path></svg></button>',
1252                responsive: [
1253                    {
1254                        breakpoint: 0,
1255                        settings: {
1256                            slidesToShow: 2,
1257                        }
1258                    },
1259                    {
1260                        breakpoint: 767,
1261                        settings: {
1262                            slidesToShow: 2,
1263                        }
1264                    },
1265                    {
1266                        breakpoint: 1024,
1267                        settings: {
1268                            slidesToShow: 4,
1269                        }
1270                    }
1271                ]
1272            });
1273        }
1274    }, 100);
1275}
1276
1277function loadBuyAgainProducts( buyAgainProducts, productsData ) {
1278    // buyAgainProducts = [];
1279    if(buyAgainProducts.length) {
1280        let bsProducts = buyAgainProducts;
1281        let promotions = productsData.promotions;
1282
1283        const html = bsProducts.map(product => renderProductCard(product, promotions)).join('');
1284
1285        const $productContainer = jQuery('.hs-buy-again-products');
1286        $productContainer.html(html).addClass('svt-product-carousel');
1287
1288        $productContainer.removeClass('slick-initialized slick-slider');
1289
1290        initPriceInfoTip();
1291
1292        setTimeout(function()  {
1293            if (!$productContainer.hasClass('slick-initialized slick-slider')) {
1294                $productContainer.slick({
1295                    slidesToShow: 6,
1296                    slidesToScroll: 1,
1297                    dots: false,
1298                    arrows: true,
1299                    prevArrow: '<button type="button" aria-hidden="true" aria-label="Previous" class="slick-prev"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.5303 5.46967C15.2374 5.17678 14.7626 5.17678 14.4697 5.46967L8.46967 11.4697C8.17678 11.7626 8.17678 12.2374 8.46967 12.5303L14.4697 18.5303C14.7626 18.8232 15.2374 18.8232 15.5303 18.5303C15.8232 18.2374 15.8232 17.7626 15.5303 17.4697L10.0607 12L15.5303 6.53033C15.8232 6.23744 15.8232 5.76256 15.5303 5.46967Z" fill="currentColor"></path></svg></button>',
1300                    nextArrow: '<button type="button" aria-hidden="true" aria-label="Next" class="slick-next"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.46967 5.46967C8.76256 5.17678 9.23744 5.17678 9.53033 5.46967L15.5303 11.4697C15.8232 11.7626 15.8232 12.2374 15.5303 12.5303L9.53033 18.5303C9.23744 18.8232 8.76256 18.8232 8.46967 18.5303C8.17678 18.2374 8.17678 17.7626 8.46967 17.4697L13.9393 12L8.46967 6.53033C8.17678 6.23744 8.17678 5.76256 8.46967 5.46967Z" fill="currentColor"></path></svg></button>',
1301                    responsive: [
1302                        {
1303                            breakpoint: 0,
1304                            settings: {
1305                                slidesToShow: 2,
1306                            }
1307                        },
1308                        {
1309                            breakpoint: 767,
1310                            settings: {
1311                                slidesToShow: 2,
1312                            }
1313                        },
1314                        {
1315                            breakpoint: 1024,
1316                            settings: {
1317                                slidesToShow: 4,
1318                            }
1319                        }
1320                    ]
1321                });
1322            }
1323            jQuery('.hs-buy-again-products-wrapper').addClass('active');
1324        },100);
1325    }
1326}
1327
1328function loadBuyAgainProductsData( productsData ) {
1329    let api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
1330
1331    var user = localStorage.getItem('user');
1332    
1333    let headers = {
1334        'apikey': hsdata.hs_api_key,
1335        'location': getCookie('selectedLocation'),
1336        'pricelist': getCookie('selectedPriceList')
1337    };
1338
1339    if(user != null) {
1340        user = JSON.parse(user);
1341        jQuery('.user-name').html(user.firstName);
1342        headers.emailid = user.email;
1343        headers.authToken = user.authToken;
1344        api.getData('/user/items',headers).then(response => {
1345            if(response.orderedItems) {
1346                loadBuyAgainProducts(response.orderedItems, productsData);
1347            }
1348        });
1349    }
1350}
1351
1352// Function to get a specific cookie value by name
1353function getCookie(name) {
1354    const value = `; ${document.cookie}`;
1355    const parts = value.split(`; ${name}=`);
1356    if (parts.length === 2) return parts.pop().split(';').shift();
1357    return null; // If cookie doesn't exist
1358}
1359
1360// Function to check if both cookie and localStorage are valid
1361function checkStorageAndCookie() {
1362    const selectedLocationCookie = getCookie('selectedLocation');
1363    const cateringPriceListID = getCookie('cateringPriceListID');
1364    const localStorageLocation = sessionStorage.getItem('ls.location');
1365    const localStoragePL = sessionStorage.getItem('ls.selectedPriceList');
1366
1367    // Check if either cookie or localStorage entry is missing
1368    if (!selectedLocationCookie || !localStorageLocation || !localStoragePL) {
1369        console.log('Cookie or localStorage missing. Resending request...');
1370        initLocation(); // Re-trigger the request if the cookie or localStorage is missing
1371    } else {
1372        var storeName = localStorage.getItem("storeName");
1373        if(storeName != null) {
1374            // document.getElementById('navbar-store-location').innerHTML = storeName;
1375            // document.getElementById('navbar-store-location-tab').innerHTML = storeName;
1376        }
1377        // console.log('Cookie and localStorage are valid.');
1378    }
1379    window.dispatchEvent(new Event('locationSet'));
1380}
1381
1382window.addEventListener('locationSet', function () {
1383    console.log('locationSet event triggered');
1384});
1385
1386function setLocationData(location, priceListData, cateringPricelist, deliPricelist, allLocationData) {
1387
1388    // console.log('Setting location data from initLocation');
1389
1390    sessionStorage.setItem('ls.allLocations', JSON.stringify(allLocationData));
1391    sessionStorage.setItem('ls.location', JSON.stringify(location));
1392    localStorage.setItem('ls.location', JSON.stringify(location));
1393    localStorage.setItem('ls.selectedPriceList', JSON.stringify(priceListData));
1394    sessionStorage.setItem('ls.selectedPriceList', JSON.stringify(priceListData));
1395    // console.log(priceListData);
1396    localStorage.setItem('ls.cateringPriceListID', JSON.stringify(cateringPricelist));
1397    localStorage.setItem('ls.deliPriceList', JSON.stringify(deliPricelist));
1398
1399    document.cookie = `selectedLocation=${location.uniqueName}; path=/`;
1400    document.cookie = `selectedLocName=${location.locName}; path=/`;
1401    document.cookie = `selectedPriceList=${priceListData.uniqueName}; path=/`;
1402    document.cookie = `selectedPListName=${priceListData.pListName}; path=/`;
1403    document.cookie = `cateringPriceListID=${cateringPricelist.uniqueName}; path=/`;
1404    document.cookie = `deliPriceListID=${deliPricelist.uniqueName}; path=/`;
1405
1406    localStorage.setItem("storeName", location.name);
1407
1408    window.dispatchEvent(new Event('locationSet'));
1409    document.getElementById('navbar-store-location').innerHTML = location.name;
1410    document.getElementById('navbar-store-location-tab').innerHTML = location.name;
1411    const headerTabs = cateringPricelist.headerTabs;
1412    if(typeof headerTabs != "undefined" && headerTabs != null && headerTabs != '') {
1413        if(headerTabs.showCatering == true) {
1414            document.cookie = 'showCatering=1; path=/';
1415            jQuery('body').addClass('show-catering');
1416        }
1417        else {
1418            document.cookie = 'showCatering=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1419            jQuery('body').removeClass('show-catering');
1420        }
1421        if(headerTabs.showFloral == true) {
1422            document.cookie = 'showFloral=1; path=/';
1423            jQuery('body').addClass('show-floral');
1424        }
1425        else {
1426            document.cookie = 'showFloral=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1427            jQuery('body').removeClass('show-floral');
1428        }
1429        // if(headerTabs.showCakes == true) {
1430        //     document.cookie = 'showCakes=1; path=/';
1431        //     jQuery('body').addClass('show-cakes');
1432        // }
1433        // else {
1434            document.cookie = 'showCakes=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1435            jQuery('body').removeClass('show-cakes');
1436        // }
1437    }
1438    // if(cateringPricelist.isDisabled == true) {
1439    //     jQuery('body').addClass('hide-catering-menus');
1440    //     document.cookie = 'hideCateringMenus=1; path=/';
1441    // }
1442    // else {
1443    //     jQuery('body').removeClass('hide-catering-menus');
1444    //     document.cookie = 'hideCateringMenus=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1445    // }
1446}
1447
1448function clearLocationData() {
1449    document.cookie = 'selectedLocation=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1450    document.cookie = 'selectedLocName=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1451    document.cookie = 'selectedPriceList=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1452    document.cookie = 'selectedPListName=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1453    document.cookie = 'deliPriceListID=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1454    document.cookie = 'cateringPriceListID=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1455
1456    sessionStorage.removeItem('ls.allLocations');
1457    sessionStorage.removeItem('ls.location');
1458    localStorage.removeItem('ls.selectedPriceList');
1459    sessionStorage.removeItem('ls.selectedPriceList');
1460    localStorage.removeItem('ls.cateringPriceListID');
1461    localStorage.removeItem('ls.deliPriceList');
1462}
1463
1464function updateCurrentLocation() {
1465    const lsLocation = JSON.parse(localStorage.getItem('ls.location'));
1466    const locName = getUrlParameter('locName');
1467    if(lsLocation != null) {
1468        // localStorage.removeItemItem('ls.location');
1469        const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
1470        let headers = {
1471            'apikey': hsdata.hs_api_key
1472        };
1473
1474        const loggedIn = isUserLoggedIn();
1475
1476        if(loggedIn) {
1477            const user = JSON.parse(localStorage.getItem('user'));
1478            if(user) {
1479                headers.emailid = user.email;
1480                headers.authToken = user.authToken;
1481            }
1482        }
1483        api.getData('/locations', headers)
1484            .then(response => {
1485                if (response.length) {
1486                    let locations = response;
1487                    console.log('last location: ',lsLocation.name);
1488                    let location = locations.filter(item => lsLocation.uniqueName == item.uniqueName);
1489                    if(locName != null) {
1490                        location = locations.filter(item => locName == item.locName);
1491                    }
1492                    if(location.length) {
1493                        location = location[0];
1494                        console.log('new location: ',location.name);
1495                        const priceListData = location.priceLists.find(p => p.default);
1496                        const cateringPricelist = location.priceLists.find(p => p.pListName === "catering");
1497                        const deliPricelist = location.priceLists.find(p => p.pListName === "deli");
1498                        // console.log('From Update Location');
1499                        setLocationData(location, priceListData, cateringPricelist, deliPricelist, response);
1500                    }
1501                }
1502            })
1503            .catch(console.error);
1504    }
1505}
1506
1507// Function to reinitialize location data and set cookies/localStorage
1508function initLocation() {
1509    const selectedLocation = getCookie('selectedLocation');
1510    const cateringPriceListID = getCookie('cateringPriceListID');
1511    const deliPriceListID = getCookie('deliPriceListID');
1512    // updateCurrentLocation();
1513    const lsLocation = JSON.parse(localStorage.getItem('ls.location'));
1514
1515    const locName = getUrlParameter('locName');
1516
1517    if(locName != null) {
1518        updateCurrentLocation();
1519    }
1520    else {
1521        if (!lsLocation && (!selectedLocation || !cateringPriceListID || !deliPriceListID)) {
1522            const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
1523            let headers = {
1524                'apikey': hsdata.hs_api_key
1525            };
1526
1527            const loggedIn = isUserLoggedIn();
1528
1529            if(loggedIn) {
1530                const user = JSON.parse(localStorage.getItem('user'));
1531                if(user) {
1532                    headers.emailid = user.email;
1533                    headers.authToken = user.authToken;
1534                }
1535            }
1536            api.getData('/locations', headers)
1537                .then(response => {
1538                    if (response.length) {
1539                        const location = response[0];
1540                        const priceListData = location.priceLists.find(p => p.default);
1541                        const cateringPricelist = location.priceLists.find(p => p.pListName === "catering");
1542                        const deliPricelist = location.priceLists.find(p => p.pListName === "deli");
1543                        // console.log('From API Location data');
1544                        setLocationData(location, priceListData, cateringPricelist, deliPricelist, response);
1545                    }
1546                })
1547                .catch(console.error);
1548        } else {
1549            const location = JSON.parse(sessionStorage.getItem('ls.location'));;
1550            if(location == null) {
1551                // console.log('Updating location info');
1552                updateCurrentLocation();
1553            }
1554            else {
1555                const priceListData = location.priceLists.find(p => p.default);
1556                const cateringPricelist = location.priceLists.find(p => p.pListName === "catering");
1557                const deliPricelist = location.priceLists.find(p => p.pListName === "deli");
1558                // console.log('When ls found');
1559                setLocationData(location, priceListData, cateringPricelist, deliPricelist, JSON.parse(sessionStorage.getItem('ls.allLocations')));
1560            }
1561        }
1562    }
1563}
1564
1565// Initial load function to check both localStorage and cookies
1566function checkAndInitOnLoad() {
1567    checkStorageAndCookie(); // Check localStorage and cookie presence on initial load
1568}
1569
1570// Set an interval to continuously check for both cookie and localStorage presence
1571// setInterval(checkStorageAndCookie, 5000); // Check every 5 seconds
1572
1573async function fetchCateringPriceList(selectedLocation) {
1574    try {
1575        // Construct the URL with query parameters
1576        const url = `${sitedata.svt_ajax_url}?action=init_catering_pricelist&locationID=${selectedLocation}`;
1577
1578        const response = await fetch(url, {
1579            method: 'GET',
1580            headers: {
1581                'Content-Type': 'application/json'
1582            }
1583        });
1584
1585        if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
1586
1587        // Parse the JSON response
1588        const data = await response.json();
1589
1590        // Store the cateringPriceListID in the cookie
1591        cateringPriceListID = data.cateringPriceListID;
1592        document.cookie = `cateringPriceListID=${data.cateringPriceListID}; path=/`;
1593
1594        console.log('Catering Price List ID fetched and stored:', data.cateringPriceListID);
1595        
1596    } catch (error) {
1597        console.error('Fetch Error:', error);
1598    }
1599}
1600
1601function showToastMsg( msg, type ) {
1602    jQuery.toast({
1603        text: msg,
1604        icon: type,
1605        loader: false,
1606        position: 'bottom-center',
1607        bgColor: '#1E1E1E',
1608        hideAfter: 2000,
1609        textColor: '#fff',
1610        allowToastClose: false
1611    });
1612}
1613
1614function loadUserPoints() {
1615    const loggedIn = isUserLoggedIn();
1616    if(loggedIn) {
1617        var user = localStorage.getItem('user');
1618        if(user != null) {
1619            user = JSON.parse(user);
1620            jQuery('.reward-points-main').html(user.loyaltyAccount.pointbalance).removeClass('skeleton skeleton-text large');
1621            jQuery('.total-reward-points strong').html(user.loyaltyAccount.pointbalance);
1622            jQuery('.total-reward-points').removeClass('skeleton skeleton-text large');
1623            const lastName = user.lastName;
1624            const name = user.firstName+' '+lastName.substring(0,1)+'.';
1625            jQuery('.short-name').html(name);
1626        }        
1627    }
1628}
1629
1630function clearPointHistorySession() {
1631    sessionStorage.removeItem('pointHistory');
1632}
1633
1634function loadPointsHistory() {
1635    const loggedIn = isUserLoggedIn();
1636    if (loggedIn == false) return; // Early return to avoid unnecessary code execution
1637
1638    // Retrieve the point history from sessionStorage
1639    const pointHistory = sessionStorage.getItem('pointHistory');
1640    
1641    // Function to update the expiring points in the DOM
1642    const updateExpiringPoints = (expiringClub) => {
1643        const eventTS = expiringClub.eventTS;
1644        const rw = Math.abs(expiringClub.value);
1645        const pointExpiryDate = `Points expiring on ${new Date(eventTS).toLocaleDateString('en-US', { day: 'numeric', month: 'short', year: 'numeric' })}`;
1646        
1647        // Update the DOM elements for expiring points in a single loop
1648        document.querySelectorAll('.point-expiring-date').forEach(el => el.innerHTML = pointExpiryDate);
1649        document.querySelectorAll('.expiring-points').forEach(el => el.innerHTML = rw);
1650        // document.querySelector('.mobile-account-points-wrap .total-reward-points strong').innerHTML = rw;
1651
1652        // Remove skeleton classes in bulk
1653        const skeletonClasses = ['skeleton', 'skeleton-text', 'large'];
1654        document.querySelectorAll('.expiring-points, .point-expiring-date').forEach(el => {
1655            skeletonClasses.forEach(cls => el.classList.remove(cls));
1656        });
1657        // document.querySelector('.mobile-account-points-wrap .total-reward-points').classList.remove(...skeletonClasses);
1658    };
1659
1660    // If point history is not in sessionStorage, fetch it from the API
1661    if (!pointHistory) {
1662        const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
1663        let user = localStorage.getItem('user');
1664        
1665        if (user) {
1666            user = JSON.parse(user);
1667            const headers = {
1668                'emailid': user.email,
1669                'authToken': user.authToken,
1670                'location': getCookie('selectedLocation'),
1671                'pricelist': getCookie('selectedPriceList')
1672            };
1673
1674            api.getData('/birdzi/clubs/details?clubPromotionId=0', headers)
1675                .then(response => {
1676                    if (response.clubDetailsList) {
1677                        const clubDetailsList = response.clubDetailsList;
1678                        sessionStorage.setItem('pointHistory', JSON.stringify(clubDetailsList));
1679
1680                        // Filter expiring clubs
1681                        const clubDetailsListExpire = clubDetailsList.filter(club => club.eventTypeName === 'Expiring');
1682                        if (clubDetailsListExpire.length) {
1683                            updateExpiringPoints(clubDetailsListExpire[0]);
1684                        }
1685
1686                        // Filter non-expiring clubs and render them
1687                        const nonExpiringClubs = clubDetailsList.filter(club => club.eventTypeName !== 'Expiring');
1688                        sessionStorage.setItem('clubDetailsList', JSON.stringify(nonExpiringClubs));
1689                        const html = nonExpiringClubs.map(club => generatePointHistoryHtml(club)).join('');
1690                        document.querySelector('.svt-profile-points-popup-content ul').innerHTML = html;
1691                    }
1692                })
1693                .catch(error => {
1694                    console.error('Error fetching point history:', error);
1695                });
1696        }
1697    } else {
1698        // Parse the point history from sessionStorage
1699        const parsedPointHistory = JSON.parse(pointHistory);
1700
1701        // Filter expiring clubs
1702        const clubDetailsListExpire = parsedPointHistory.filter(club => club.eventTypeName === 'Expiring');
1703        if (clubDetailsListExpire.length) {
1704            updateExpiringPoints(clubDetailsListExpire[0]);
1705        }
1706        else {
1707            const skeletonClasses = ['skeleton', 'skeleton-text', 'large'];
1708            document.querySelectorAll('.expiring-points, .point-expiring-date').forEach(el => {
1709                skeletonClasses.forEach(cls => el.classList.remove(cls));
1710            });
1711        }
1712
1713        // Filter non-expiring clubs and render them
1714        const nonExpiringClubs = parsedPointHistory.filter(club => club.eventTypeName !== 'Expiring');
1715        sessionStorage.setItem('clubDetailsList', JSON.stringify(nonExpiringClubs));
1716        const html = nonExpiringClubs.map(club => generatePointHistoryHtml(club)).join('');
1717        document.querySelector('.svt-profile-points-popup-content ul').innerHTML = html;
1718    }
1719}
1720
1721function clearLifetimeSavings() {
1722    sessionStorage.removeItem('lifetimeSaving');
1723}
1724
1725function loadLifetimeSaving() {
1726    const loggedIn = isUserLoggedIn();
1727    if(loggedIn) {
1728        const lifetimeSaving = sessionStorage.getItem('lifetimeSaving');
1729        if(lifetimeSaving == null) {
1730            const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
1731
1732            var user = localStorage.getItem('user');
1733            if(user != null) {
1734                user = JSON.parse(user);
1735                
1736                let headers = {
1737                    'emailid': user.email,
1738                    'authToken': user.authToken,
1739                    'location': getCookie('selectedLocation'),
1740                    'pricelist': getCookie('selectedPriceList')
1741                };
1742
1743                if(user != null) {
1744                    headers.authToken = user.authToken
1745                }
1746
1747                api.getData('/birdzi/clubs/list',headers).then(response => {
1748                    if(response.success) {
1749                        const clubs = response.clubs;
1750                        const saving = clubs.filter((club) => club.clubPromotionID == 0);
1751                        if(saving.length) {
1752                            let rewardBalance = '$'+saving[0].rewardBalance;
1753                            if(typeof saving[0].rewardBalance == "undefined") {
1754                                rewardBalance = '$0';
1755                            }
1756                            sessionStorage.setItem('lifetimeSaving',rewardBalance);
1757                            document.querySelectorAll('.lifetime-savings').forEach(el => el.innerHTML = rewardBalance);
1758                            document.querySelectorAll('.lifetime-savings').forEach(el => el.classList.remove('skeleton', 'skeleton-text', 'large'));
1759                        }
1760                    }
1761                })
1762                .catch(error => {
1763                    console.error('Error posting data on point history 921:', error);
1764                });
1765            }
1766        }
1767        else {
1768            document.querySelectorAll('.lifetime-savings').forEach(el => el.innerHTML = lifetimeSaving);
1769            document.querySelectorAll('.lifetime-savings').forEach(el => el.classList.remove('skeleton', 'skeleton-text', 'large'));
1770        }
1771    }
1772}
1773
1774function generatePointHistoryHtml( club ) {
1775    var date = new Date(club.eventTS).toLocaleString('en-US', { day: '2-digit', month: 'short', year: 'numeric', hour: 'numeric', minute: '2-digit', hour12: true });
1776    var value = club.value;
1777    var info = club.info;
1778    if(value > 0) {
1779        value = '+'+value;
1780    }
1781    if(club.eventTypeName == "Expired") {
1782        if(info == '') {
1783            info = 'Points Expired';
1784        }
1785    }
1786    if(info != '') {
1787        info = info.charAt(0).toUpperCase() + info.slice(1);
1788    }
1789    return `<li>
1790            <div class="points-info-left">
1791                <span>${date}</span>
1792                <h6>${info}</h6>
1793            </div>
1794            <div class="points-info-right">
1795                ${value} Pts
1796            </div>
1797        </li>`;
1798}
1799
1800function loadCategories( data ) {
1801
1802    const categoriesData = data.products.reduce((acc, { type, subType }) => {
1803        if (!acc[type]) acc[type] = [];
1804        if (!acc[type].includes(subType)) {
1805            acc[type].push(subType);
1806        }
1807        return acc;
1808    }, {});
1809
1810    // Sort subcategories within each category
1811    Object.keys(categoriesData).forEach(type => {
1812        categoriesData[type].sort((a, b) => a.localeCompare(b));
1813    });
1814
1815    // Sort main categories and reassign to a new sorted object
1816    const sortedCategoriesData = Object.keys(categoriesData)
1817        .sort((a, b) => a.localeCompare(b))
1818        .reduce((sortedAcc, key) => {
1819            sortedAcc[key] = categoriesData[key];
1820            return sortedAcc;
1821    }, {});
1822    
1823    // Base URL for categories
1824    const baseUrl = `${sitedata.home_url}/category/?cat=`;
1825    
1826    // Build HTML structure
1827    let html = `
1828        <div class="svt-catgory-mm">
1829            <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
1830                <path d="M0.75 2C0.75 1.30964 1.30964 0.75 2 0.75H6C6.69036 0.75 7.25 1.30964 7.25 2V6C7.25 6.69036 6.69036 7.25 6 7.25H2C1.30964 7.25 0.75 6.69036 0.75 6V2Z" stroke="white" stroke-width="1.5" />
1831                <path d="M0.75 12C0.75 11.3096 1.30964 10.75 2 10.75H6C6.69036 10.75 7.25 11.3096 7.25 12V16C7.25 16.6904 6.69036 17.25 6 17.25H2C1.30964 17.25 0.75 16.6904 0.75 16V12Z" stroke="white" stroke-width="1.5" />
1832                <path d="M10.75 2C10.75 1.30964 11.3096 0.75 12 0.75H16C16.6904 0.75 17.25 1.30964 17.25 2V6C17.25 6.69036 16.6904 7.25 16 7.25H12C11.3096 7.25 10.75 6.69036 10.75 6V2Z" stroke="white" stroke-width="1.5" />
1833                <path d="M10.75 12C10.75 11.3096 11.3096 10.75 12 10.75H16C16.6904 10.75 17.25 11.3096 17.25 12V16C17.25 16.6904 16.6904 17.25 16 17.25H12C11.3096 17.25 10.75 16.6904 10.75 16V12Z" stroke="white" stroke-width="1.5" />
1834            </svg>
1835            <span>Categories</span>
1836        </div>
1837        <div class="svt-catgory-mm-popup">
1838            <div class="svt-catgory-mm-popup-content">
1839                <div class="svt-catgory-mm-popup-content-wrap">
1840                    <ul>
1841    `;
1842    
1843    let mobileHtml = `
1844        <div class="svt-mobile-categories-mm-toggle">
1845            <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
1846                <path d="M0.75 2C0.75 1.30964 1.30964 0.75 2 0.75H6C6.69036 0.75 7.25 1.30964 7.25 2V6C7.25 6.69036 6.69036 7.25 6 7.25H2C1.30964 7.25 0.75 6.69036 0.75 6V2Z" stroke="currentColor" stroke-width="1.5" />
1847                <path d="M0.75 12C0.75 11.3096 1.30964 10.75 2 10.75H6C6.69036 10.75 7.25 11.3096 7.25 12V16C7.25 16.6904 6.69036 17.25 6 17.25H2C1.30964 17.25 0.75 16.6904 0.75 16V12Z" stroke="currentColor" stroke-width="1.5" />
1848                <path d="M10.75 2C10.75 1.30964 11.3096 0.75 12 0.75H16C16.6904 0.75 17.25 1.30964 17.25 2V6C17.25 6.69036 16.6904 7.25 16 7.25H12C11.3096 7.25 10.75 6.69036 10.75 6V2Z" stroke="currentColor" stroke-width="1.5" />
1849                <path d="M10.75 12C10.75 11.3096 11.3096 10.75 12 10.75H16C16.6904 10.75 17.25 11.3096 17.25 12V16C17.25 16.6904 16.6904 17.25 16 17.25H12C11.3096 17.25 10.75 16.6904 10.75 16V12Z" stroke="currentColor" stroke-width="1.5" />
1850            </svg>
1851            <span>Categories</span>
1852        </div>
1853        <div class="svt-mobile-catgory-mm-sub">
1854            <div class="mobile-cat-back">
1855                <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
1856                    <path fill-rule="evenodd" clip-rule="evenodd" d="M15.5303 5.46967C15.2374 5.17678 14.7626 5.17678 14.4697 5.46967L8.46967 11.4697C8.17678 11.7626 8.17678 12.2374 8.46967 12.5303L14.4697 18.5303C14.7626 18.8232 15.2374 18.8232 15.5303 18.5303C15.8232 18.2374 15.8232 17.7626 15.5303 17.4697L10.0607 12L15.5303 6.53033C15.8232 6.23744 15.8232 5.76256 15.5303 5.46967Z" fill="black" />
1857                </svg>
1858                Back to menu
1859            </div>
1860            <ul>
1861    `;
1862    
1863    Object.entries(sortedCategoriesData).forEach(([cat, subCategories]) => {
1864        const encodedCat = encodeURIComponent(cat);
1865        html += `<li>
1866                    <a href="${baseUrl}${encodedCat}">${cat}</a>
1867                    <ul class="sub-cat">`;
1868        mobileHtml += `<li>
1869                        <a href="javascript:void(0);" class="mobile-cat-toggle">${cat}</a>
1870                        <ul class="sub-cat">
1871                            <li><a href="${baseUrl}${encodedCat}">All</a></li>`;
1872        
1873        subCategories.forEach(subCat => {
1874            const encodedSubCat = encodeURIComponent(subCat);
1875            html += `<li><a href="${baseUrl}${encodedCat}&subcategory=${encodedSubCat}">${subCat}</a></li>`;
1876            mobileHtml += `<li><a href="${baseUrl}${encodedCat}&subcategory=${encodedSubCat}">${subCat}</a></li>`;
1877        });
1878    
1879        html += `</ul></li>`;
1880        mobileHtml += `</ul></li>`;
1881    });
1882    
1883    // Finalize and update DOM
1884    html += `</ul></div></div></div>`;
1885    mobileHtml += `</ul></div>`;
1886    jQuery('.svt-category-loader').hide();
1887    jQuery('.svt-catgory-mm-wrap').html(html);
1888    jQuery('.svt-mobile-category-loader').hide();
1889    jQuery('.svt-mobile-categories-mm').html(mobileHtml);    
1890}
1891
1892async function fetchData() {
1893    try {
1894        const results = await Promise.all([
1895            // checkAndFetchData('myItems'),
1896            // checkAndFetchData('products'),
1897            checkAndFetchData('cateringProducts'),
1898        ]);
1899
1900        const [myItemsData, productsData, cateringProductsData] = results;
1901
1902        if (myItemsData) {
1903            console.log("Retrieved my items data:", myItemsData);
1904            // loadMyItems(myItemsData);
1905        } else {
1906            console.log("No my items data found.");
1907        }
1908
1909        if (productsData) {
1910            // console.log("Retrieved products data:", productsData);
1911            // products = productsData;
1912            // loadBestSellingProducts(productsData);
1913        } else {
1914            console.log("No products data found.");
1915        }
1916
1917        if (cateringProductsData) {
1918            console.log("Retrieved catering products data:", cateringProductsData);
1919        } else {
1920            console.log("No catering products data found.");
1921        }
1922        
1923    } catch (error) {
1924        console.error("Error fetching data:", error);
1925    }
1926}
1927
1928let isRefreshed = false;
1929
1930// Detect if the session is new (for tab/window close detection)
1931document.addEventListener('DOMContentLoaded', () => {
1932    // console.log(sessionStorage.getItem('isRefreshed'));
1933    if (!sessionStorage.getItem('isRefreshed')) {
1934        isRefreshed = true;
1935        sessionStorage.setItem('isRefreshed', 'true');
1936        if(typeof navigator.serviceWorker != "undefined") {
1937            if (navigator.serviceWorker.controller) {
1938                console.log('service worker cache cleared');
1939                navigator.serviceWorker.controller.postMessage({ action: 'clear-cache' });
1940            }
1941        }
1942    }
1943});
1944
1945
1946
1947function loadProductList( priceList ) {
1948    const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
1949
1950    var user = localStorage.getItem('user');
1951    user = JSON.parse(user);
1952
1953    const loggedIn = isUserLoggedIn();
1954
1955    if(typeof priceList == "undefined") {
1956        priceList = getCookie('selectedPriceList');
1957    }
1958    
1959    let headers = {
1960        'apikey': hsdata.hs_api_key,
1961        'location': getCookie('selectedLocation'),
1962        'pricelist': priceList
1963    };
1964
1965    if(user != null && loggedIn) {
1966        headers.emailid = user.email;
1967        headers.authToken = user.authToken
1968    }
1969
1970    api.getData('/product/list?listType=ui',headers).then(response => {
1971        allProducts = response;
1972        productsArr[priceList] = response;
1973        loadBestDeals( allProducts );
1974        loadBestSellingProducts(allProducts);
1975        loadHomeFeaturedProducts(allProducts);
1976        loadCategories( allProducts );
1977        if(typeof navigator.serviceWorker != "undefined") {
1978            if (navigator.serviceWorker.controller) {
1979                console.log('Service Worker is active and controlling the page');
1980            } else {
1981                const priceListType = priceList;
1982                const data = response;
1983                const customEvent = new CustomEvent('CACHE_DATA_READY', { 
1984                    detail: { priceListType, data } 
1985                });
1986                window.dispatchEvent(customEvent);
1987            }
1988        }
1989        else {
1990            const priceListType = priceList;
1991            const data = response;
1992            const customEvent = new CustomEvent('CACHE_DATA_READY', { 
1993                detail: { priceListType, data } 
1994            });
1995            window.dispatchEvent(customEvent);
1996        }
1997        // window.dispatchEvent(new Event('CACHE_DATA_READY'));
1998        // sessionStorage.setItem('products', JSON.stringify(response));
1999    })
2000    .catch(error => {
2001        console.error('Error posting data:', error);
2002    });
2003}
2004
2005function loadProductListbyPL( priceList ) {
2006    const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
2007
2008    var user = localStorage.getItem('user');
2009    user = JSON.parse(user);
2010
2011    const loggedIn = isUserLoggedIn();
2012
2013    if(typeof priceList == "undefined") {
2014        priceList = getCookie('selectedPriceList');
2015    }
2016    
2017    let headers = {
2018        'apikey': hsdata.hs_api_key,
2019        'location': getCookie('selectedLocation'),
2020        'pricelist': priceList
2021    };
2022
2023    if(user != null && loggedIn) {
2024        headers.emailid = user.email;
2025        headers.authToken = user.authToken
2026    }
2027
2028    api.getData('/product/list?listType=ui',headers).then(response => {
2029        productsArr[priceList] = response;
2030        if(typeof navigator.serviceWorker != "undefined") {
2031            if (navigator.serviceWorker.controller) {
2032                console.log('Service Worker is active and controlling the page');
2033            } else {
2034                const priceListType = priceList;
2035                const data = response;
2036                const customEvent = new CustomEvent('CACHE_DATA_READY', { 
2037                    detail: { priceListType, data } 
2038                });
2039                window.dispatchEvent(customEvent);
2040            }
2041        }
2042        else {
2043            const priceListType = priceList;
2044            const data = response;
2045            const customEvent = new CustomEvent('CACHE_DATA_READY', { 
2046                detail: { priceListType, data } 
2047            });
2048            window.dispatchEvent(customEvent);
2049        }
2050    })
2051    .catch(error => {
2052        console.error('Error posting data:', error);
2053    });
2054}
2055
2056function loadMyItems( allProductsData ) {
2057    const loggedIn = isUserLoggedIn();
2058    if(loggedIn) {
2059        const myItemsListWrap = jQuery('.svt-my-items-listing-wrap');
2060        const noItems = jQuery('.svt-no-items-wrapper');
2061        const myItemsListContainer = jQuery('.svt-my-items-listing-container');
2062        const myItemsList = jQuery('.svt-my-items-listing-wrap .svt-order-products-list');
2063        const myItemsListSkeletonBoxes = jQuery('.svt-my-items-listing-wrap .svt-order-products-list .shimmer-product-boxes');
2064        const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
2065
2066        var user = localStorage.getItem('user');
2067
2068        if(user != null) {
2069            user = JSON.parse(user);
2070
2071            if(typeof priceList == "undefined") {
2072                priceList = getCookie('selectedPriceList');
2073            }
2074            
2075            let headers = {
2076                'apikey': hsdata.hs_api_key,
2077                'location': getCookie('selectedLocation'),
2078                'pricelist': priceList
2079            };
2080
2081            if(user != null) {
2082                headers.emailid = user.email;
2083                headers.authToken = user.authToken;
2084            }
2085
2086            api.getData('/v2/user/shoppinglists',headers).then(response => {
2087                if(response.lists) {
2088                    sessionStorage.setItem('shoppingLists', JSON.stringify(response));
2089                }
2090                const fav = response.lists.filter((list) => list.displayName == "Favorites" );
2091                if(fav.length) {
2092                    const favID = fav[0].name;
2093                    sessionStorage.setItem('favListID',favID);
2094                    const productIDs = fav[0].contents;
2095                    if(productIDs) {
2096                        var productsData = allProductsData.products;
2097                        var promotions = allProductsData.promotions;
2098                        const ids = Object.keys(productIDs);
2099                        const myItems = productsData.filter(product => ids.includes(product.name));
2100                        if(myItems.length) {
2101                            let types = [...new Set(myItems.flatMap(product => product.type))].sort();
2102                        
2103                            // Build category filter HTML based on unique types
2104                            if (types.length) {
2105                                let catHtml = `
2106                                    <div class="svt-profile-search-filter-wrapper">
2107                                        <div class="svt-profile-category-filter-wrapper swiper-container swiper-my-items">
2108                                            <div class="svt-profile-category-filter-carousel-el swiper-wrapper">
2109                                                <div class="svt-profile-category-filter-box active swiper-slide">
2110                                                    <div class="svt-profile-category-filter-img">
2111                                                        <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26" fill="none">
2112                                                            <path d="M7.69809 6.63627C7.11234 6.63627 6.63749 7.11112 6.63749 7.69687C6.63749 8.28263 7.
211211234 8.75748 7.69809 8.75748H7.7087C8.29446 8.75748 8.76931 8.28263 8.76931 7.69687C8.76931 7.11112 8.29446 6.63627 7.7087 6.63627H7.69809Z" fill="#CB333B"/>
2113                                                            <path fill-rule="evenodd" clip-rule="evenodd" d="M2.39506 1.59839C1.95575 1.59839 1.59961 1.95453 1.59961 2.39384V12.9999C1.59961 13.211 1.68354 13.4135 1.83292 13.5627L10.9429 22.6621C11.2137 22.9331 11.5356 23.1484 11.8895 23.2952C12.2436 23.4419 12.6231 23.5175 13.0064 23.5175C13.3897 23.5175 13.7693 23.4419 14.1233 23.2952C14.4774 23.1484 14.7991 22.9332 15.07 22.6621L22.6742 15.0578L22.6759 15.0562C23.2191 14.5097 23.524 13.7704 23.524 12.9999C23.524 12.2294 23.2191 11.4901 22.6759 10.9437L13.5636 1.83137C13.4144 1.6822 13.2121 1.59839 13.0011 1.59839H2.39506ZM3.19052 12.6701V3.1893H12.6716L21.5476 12.0652C21.7941 12.3136 21.9331 12.6499 21.9331 12.9999C21.9331 13.3499 21.7947 13.6856 21.5482 13.9339L13.9447 21.5374C13.8216 21.6607 13.6751 21.7588 13.5141 21.8255C13.3532 21.8922 13.1807 21.9266 13.0064 21.9266C12.8322 21.9266 12.6597 21.8922 12.4987 21.8255C12.3378 21.7588 12.1916 21.661 12.0685 21.5377L3.19052 12.6701Z" fill="#CB333B"/>
2114                                                        </svg>
2115                                                    </div>
2116                                                    <h6>All</h6>
2117                                                </div>`;
2118                        
2119                                // Convert Set to array, sanitize, and build the filter items
2120                                types.forEach(cat => {
2121                                    let catSlug = sanitizeTitle(cat);
2122                                    $categoryImgs = JSON.parse(sitedata.categoryImgs);
2123                                    let catImg = $categoryImgs[catSlug] || '';
2124                                    catHtml += `
2125                                        <div class="svt-profile-category-filter-box swiper-slide" data-name="${catSlug}">
2126                                            <div class="svt-profile-category-filter-img">
2127                                                <img src="${catImg}" alt="${cat}">
2128                                            </div>
2129                                            <h6>${cat}</h6>
2130                                        </div>`;
2131                                });
2132                        
2133                                catHtml += `</div>
2134                                    </div>
2135                                    <!-- Add Pagination -->
2136                                    <div class="swiper-pagination"></div>
2137
2138                                    <!-- Add Navigation -->
2139                                    <div class="swiper-button-next"></div>
2140                                    <div class="swiper-button-prev"></div>
2141                                </div>`;
2142                                jQuery(catHtml).insertBefore(myItemsListContainer);
2143
2144                                // console.log(catHtml);
2145                        
2146                                // Initialize slick carousel
2147                                if(myItemsListWrap.find('.svt-profile-category-filter-carousel-el').length) {
2148                                    var swiperMyItems = new Swiper('.swiper-my-items', {
2149                                        direction: 'horizontal',
2150                                        slidesPerView: 7,
2151                                        spaceBetween: 10,
2152                                        loop: false,
2153                                        navigation: {
2154                                            nextEl: '.swiper-button-next',
2155                                            prevEl: '.swiper-button-prev',
2156                                        },
2157                                        breakpoints: {
2158                                            1100: {
2159                                                slidesPerView: 7,
2160                                            },
2161                                            1024: {
2162                                                slidesPerView: 5.5,
2163                                            },
2164                                            768: {
2165                                                slidesPerView: 5.5,
2166                                            },
2167                                            640: {
2168                                            slidesPerView: 4.5,
2169                                            navigation: {
2170                                                enabled: false, // Disable navigation on mobile
2171                                            },
2172                                            },
2173                                            0: {
2174                                            slidesPerView: 4.5,
2175                                            navigation: {
2176                                                enabled: false, // Disable navigation on mobile
2177                                            },
2178                                            },
2179                                        },
2180                                    });
2181
2182                                    function checkArrowsVisibilityMyItems() {
2183                                        const totalSlidesMyItems = swiperMyItems.slides.length; // Total number of slides
2184                                        const slidesToShowMyItems = swiperMyItems.params.slidesPerView; // Slides per view
2185                                    
2186                                        // Determine if arrows should be shown
2187                                        const showArrowsItems = totalSlidesMyItems > slidesToShowMyItems;
2188                                    
2189                                        // Add or remove class on the Swiper container based on arrow visibility
2190                                        const swiperContainerMyItems = document.querySelector('.swiper-my-items');
2191                                        if (!showArrowsItems) {
2192                                            swiperContainerMyItems.classList.add('no-arrows');
2193                                        } else {
2194                                            swiperContainerMyItems.classList.remove('no-arrows');
2195                                        }
2196                                    }
2197                                    
2198                                    // Call this function on initialization and on window resize
2199                                    checkArrowsVisibilityMyItems();
2200                                    window.addEventListener('resize', checkArrowsVisibilityMyItems);
2201                                }
2202                            }
2203                            var html = myItems.map(product => renderProductCard(product, promotions)).join('');
2204                            myItemsListSkeletonBoxes.hide();
2205                            myItemsList.append(html);
2206                            initPriceInfoTip();
2207                            ids.forEach((productID) => {
2208                                if(jQuery('.svt-product-box[data-id="'+productID+'"]').length) {
2209                                    jQuery('.svt-product-box[data-id="'+productID+'"]').addClass('in-fav');
2210                                }
2211                            });
2212                        }
2213                        else {
2214                            myItemsListWrap.hide();
2215                            noItems.show();
2216                        }
2217                    }
2218                    else {
2219                        myItemsListWrap.hide();
2220                        noItems.show();
2221                    }
2222                }
2223                else {
2224                    myItemsListWrap.hide();
2225                    noItems.show();
2226                }
2227                // window.dispatchEvent(new Event('CACHE_DATA_READY'));
2228                // sessionStorage.setItem('products', JSON.stringify(response));
2229            })
2230            .catch(error => {
2231                console.error('Error posting data:', error);
2232            });
2233        }
2234    }
2235}
2236
2237function openPDPPopup(productID, pricelist) {
2238    jQuery('body').addClass('svt-popup-active');
2239    jQuery('.svt-pdp-popup').fadeIn();
2240    jQuery('.svt-pdp-popup').find('.bouncing-loader').show();
2241
2242    // Retrieve the base source URL and append the productID
2243    let src = jQuery('.svt-pdp-popup').find('.svt-popup-embed').attr('data-src');
2244    src = src + productID;
2245
2246    // Add location if available
2247    let selectedLocation = sessionStorage.getItem('ls.location');
2248    if (selectedLocation !== null) {
2249        selectedLocation = JSON.parse(selectedLocation);
2250        // src += src.includes('?') ? '&locName=' + selectedLocation.locName : '?locName=' + selectedLocation.locName;
2251    }
2252
2253    // Add selected price list if available
2254    let selectedPricelist = sessionStorage.getItem('ls.selectedPriceList');
2255    if (selectedPricelist !== null) {
2256        selectedPricelist = JSON.parse(selectedPricelist);
2257        if(typeof pricelist !== "undefined" && pricelist !== null && pricelist !== '') {
2258            selectedPricelist = selectedLocation.priceLists.find(p => p.uniqueName === pricelist);
2259        }
2260        let plist = getUrlParameter('plist');
2261        // console.log(plist);
2262        if(plist !== null) {
2263            plist = plist.toLowerCase();
2264            if(plist == 'catering') {
2265                const cateringPricelist = localStorage.getItem('ls.cateringPriceListID');
2266                selectedPricelist = JSON.parse(cateringPricelist);
2267            }
2268            if(plist == 'deli') {
2269                const deliPriceList = localStorage.getItem('ls.deliPriceList');
2270                selectedPricelist = JSON.parse(deliPriceList);
2271            }
2272        }
2273        // src += src.includes('?') ? '&pListName=' + selectedPricelist.pListName : '?pListName=' + selectedPricelist.pListName;
2274    }
2275
2276    // Set the updated src to the embed element
2277    jQuery('.svt-pdp-popup').find('.svt-popup-embed').attr('data-pricelist', JSON.stringify(selectedPricelist));
2278    jQuery('.svt-pdp-popup').find('.svt-popup-embed').attr('src', src);
2279}
2280
2281function setUserCookie() {
2282    const date = new Date();
2283    date.setFullYear(date.getFullYear() + 10); // Set expiration to 10 years in the future
2284    document.cookie = `userLoggedIn=1; path=/; expires=${date.toUTCString()};`;
2285}
2286
2287function removeUserCookie() {
2288    document.cookie = 'userLoggedIn=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
2289}
2290
2291function logoutUser() {
2292    jQuery('body').removeClass('hs-logged-in');
2293    removeUserCookie();
2294    localStorage.removeItem('user');
2295    localStorage.removeItem('basket');
2296    jQuery('.hs-cart-count').removeClass('active');
2297}
2298
2299function isUserLoggedIn() {
2300    const loggedIn = getCookie('userLoggedIn');
2301    const user = JSON.parse(localStorage.getItem('user'));
2302    if(loggedIn != null || user != null) {
2303        if(user != null && loggedIn == null) {
2304            setUserCookie();
2305        }
2306        else if(user == null) {
2307            logoutUser();
2308        }
2309        return true;
2310    }
2311    return false;
2312}
2313
2314function getUserData() {
2315    let user = JSON.parse(localStorage.getItem('user'));
2316    if(user != null) {
2317        return user;
2318    }
2319    return null;
2320}
2321
2322document.addEventListener('DOMContentLoaded', () => {
2323    const happyFormInputs = document.querySelectorAll('.happyforms-input input');
2324    
2325    if (happyFormInputs.length > 0) {
2326        happyFormInputs.forEach((input) => {
2327            const placeholderText = input.getAttribute('placeholder');
2328            if (placeholderText) {
2329                input.setAttribute('aria-label', placeholderText);
2330            } else {
2331                input.setAttribute('aria-label', 'Input field');
2332            }
2333        });
2334        // console.log('ARIA labels have been added to Happy Form inputs.');
2335    } else {
2336        // console.log('No Happy Form inputs found on the page.');
2337    }
2338    
2339    const happyFormTextarea = document.querySelectorAll('.happyforms-part__el textarea');
2340    
2341    if (happyFormTextarea.length > 0) {
2342        happyFormTextarea.forEach((input) => {
2343            const placeholderText = input.getAttribute('placeholder');
2344            if (placeholderText) {
2345                input.setAttribute('aria-label', placeholderText);
2346            } else {
2347                input.setAttribute('aria-label', 'Input field');
2348            }
2349        });
2350        // console.log('ARIA labels have been added to Happy Form inputs.');
2351    } else {
2352        // console.log('No Happy Form inputs found on the page.');
2353    }
2354
2355    const hiddenFields = document.querySelectorAll('input[type="text"][tabindex="-1"]');
2356
2357    if (hiddenFields.length > 0) {
2358        hiddenFields.forEach((input) => {
2359            input.setAttribute('aria-label', 'Hidden Field');
2360        });
2361        // console.log('ARIA labels have been added to Happy Form inputs.');
2362    }
2363
2364    var skipLink = document.querySelector('.skip-link');
2365    if (skipLink) {
2366        skipLink.remove();
2367    }
2368});
2369
2370function refreshLocationData() {
2371    const lsLocation = JSON.parse(sessionStorage.getItem('ls.location'));
2372    if (lsLocation) {
2373        const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
2374        let headers = {
2375            'apikey': hsdata.hs_api_key
2376        };
2377
2378        const loggedIn = isUserLoggedIn();
2379
2380        if(loggedIn) {
2381            const user = JSON.parse(localStorage.getItem('user'));
2382            if(user) {
2383                headers.emailid = user.email;
2384                headers.authToken = user.authToken;
2385            }
2386        }
2387        api.getData('/locations', headers)
2388        .then(response => {
2389            let locations = response;
2390            locations = locations.filter(item => item.isDisabled == false);
2391            let location = locations.filter(item => lsLocation.uniqueName == item.uniqueName);
2392            let locationData = location[0];
2393            sessionStorage.setItem('ls.location',JSON.stringify(locationData));
2394            sessionStorage.setItem('ls.allLocations',JSON.stringify(locations));
2395            localStorage.setItem('ls.location',JSON.stringify(locationData));
2396        })
2397        .catch(console.error);
2398    }
2399}
2400
2401window.addEventListener("load", function () {
2402    let navigationType;
2403  
2404    if (performance.getEntriesByType("navigation").length > 0) {
2405        // Modern browsers
2406        navigationType = performance.getEntriesByType("navigation")[0].type;
2407    } else {
2408        // Fallback for older browsers
2409        navigationType = performance.navigation.type === 1 ? 'reload' : 'navigate';
2410    }
2411  
2412    if (navigationType === "reload") {
2413        console.log("Page was refreshed");
2414        setTimeout(function() {
2415            refreshLocationData();
2416        },1000);
2417    }
2418});
2419
2420(function($) {
2421    $(window).on('CACHE_DATA_READY',function(event) {
2422        if(allProducts.length) {
2423            loadMyItems(allProducts);
2424            loadBuyAgainProductsData(allProducts);
2425        }
2426        else {
2427            loadMyItems(event.detail.data);
2428            loadBuyAgainProductsData(event.detail.data);
2429        }
2430    });
2431    window.addEventListener('locationSet',function() {
2432        setTimeout(function() {
2433            const links = document.querySelectorAll('a');
2434            if(links) {
2435                const matchingLinks = Array.from(links).filter(link => link.href === sitedata.home_url+'/cakes/');
2436                let location = sessionStorage.getItem('ls.location');
2437                location = JSON.parse(location);
2438                let locationName = location.name;
2439                locationName = sanitizeTitle(locationName);
2440                let cakesLinks = sitedata.cakesLinks;
2441                cakesLinks = JSON.parse(cakesLinks);
2442                const url = cakesLinks[locationName]?.toString();
2443                if(typeof url != "undefined") {
2444                    matchingLinks.forEach(link => {
2445                        link.href = url;
2446                        link.target = '_blank';
2447                    });
2448                }
2449            }
2450            // loadUserPoints();
2451            loadProductList();
2452            if(jQuery('.svt-wa-digital-link').length) {
2453                let location = sessionStorage.getItem('ls.location');
2454                location = JSON.parse(location);
2455                let locationName = location.name;
2456                // console.log(locationName);
2457                locationName = sanitizeTitle(locationName);
2458                let waDigital = sitedata.waDigital;
2459                waDigital = JSON.parse(waDigital);
2460                const url = waDigital[locationName]?.toString();
2461                if(typeof url != "undefined") {
2462                    const html = `Explore our new digital ad <a href="${url}" target="_blank">
2463                        <span>Switch to Digital View</span>
2464                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
2465                            <path fill-rule="evenodd" clip-rule="evenodd" d="M8.46967 5.46967C8.76256 5.17678 9.23744 5.17678 9.53033 5.46967L15.5303 11.4697C15.8232 11.7626 15.8232 12.2374 15.5303 12.5303L9.53033 18.5303C9.23744 18.8232 8.76256 18.8232 8.46967 18.5303C8.17678 18.2374 8.17678 17.7626 8.46967 17.4697L13.9393 12L8.46967 6.53033C8.17678 6.23744 8.17678 5.76256 8.46967 5.46967Z" fill="#CB333B"></path>
2466                        </svg>
2467                    </a>`;
2468                    jQuery('.svt-wa-digital-link').html(html);
2469                }
2470            }
2471
2472            if($('.svt-contact-store-info').length) {
2473                let location = sessionStorage.getItem('ls.location');
2474                let html = '';
2475                if(location != null) {
2476                    location = JSON.parse(location);
2477                    let location_data;
2478                    if ("locationImgUrl" in location) {
2479                        location_data = location.locationImgUrl;
2480                    } else {
2481                        location_data = "/wp-content/uploads/no-store-image-large.jpg";
2482                    }
2483                    let address = '';
2484                    if(location.address.aptUnit != '') {
2485                        address += location.address.aptUnit+' ';
2486                    }
2487                    if(location.address.street != '') {
2488                        address += location.address.street;
2489                    }
2490                    if(location.address.city != '') {
2491                        address += '<br>'+location.address.city+', ';
2492                    }
2493                    if(location.address.state != '') {
2494                        address += location.address.state+' ';
2495                    }
2496                    if(location.address.zip != '') {
2497                        address += location.address.zip;
2498                    }
2499                    let hours = location.operatingHours;
2500                    // console.log(hours);
2501                    html += `<div class="svt-contact-store-info-top">
2502                                <div class="svt-contact-store-info-left">
2503                                    <div class="svt-contact-store-address">${address}</div>
2504                                    <div class="svt-contact-change-store">
2505                                        <a href="/select-the-location/?ref=contact-us">
2506                                            Change Store
2507                                            <svg xmlns="http://www.w3.org/2000/svg" width="6" height="11" viewB
2507ox="0 0 6 11" fill="none">
2508                                                <path d="M1 9.5L5 5.5L1 1.5" stroke="#232323" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
2509                                            </svg>
2510                                        </a>
2511                                    </div>
2512                                    <div class="svt-store-phone">
2513                                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
2514                                            <path d="M14.2327 22C13.6889 22 13.1507 21.7996 12.7241 21.4141C10.3942 19.3092 8.46556 16.6775 7.14902 13.8057C5.81387 10.8955 5.09098 7.78668 5.00097 4.56845C4.97471 3.64768 5.48383 2.80322 6.2986 2.41584L8.82536 1.21548C9.37104 0.957849 9.98236 0.930174 10.5459 1.13819C11.1103 1.34715 11.5613 1.76794 11.8154 2.32233L13.084 5.0894C13.3381 5.64376 13.3653 6.26589 13.1599 6.84031C12.9546 7.41473 12.5411 7.87368 11.9964 8.13227L10.424 8.87843C10.5196 9.90321 10.7896 10.9156 11.2256 11.8678C11.6597 12.8143 12.2457 13.6731 12.9677 14.4192L14.5335 13.6654C15.6567 13.132 16.9993 13.6272 17.5245 14.7722L18.7931 17.5393C19.0603 18.1213 19.0687 18.7654 18.8184 19.3503C18.5699 19.9285 18.0945 20.398 17.442 20.7081L15.1758 21.7844C14.8739 21.9275 14.5513 21.9972 14.2307 21.9972L14.2327 22ZM9.7764 2.53013C9.66951 2.53013 9.56262 2.55303 9.46043 2.60169L6.93366 3.80205C6.66176 3.93086 6.49206 4.21616 6.50049 4.52626C6.58487 7.53564 7.26089 10.4402 8.50884 13.1616C9.73991 15.8466 11.5421 18.3057 13.7201 20.274C13.9498 20.481 14.2723 20.5326 14.5433 20.4047L16.8095 19.3284C17.1217 19.1805 17.3477 18.9725 17.4452 18.7435C17.522 18.5632 17.5192 18.3714 17.4358 18.1882L16.1672 15.4211C16.0828 15.236 15.9328 15.0967 15.7443 15.0261C15.5559 14.9555 15.3524 14.965 15.1705 15.0518L13.5991 15.798C13.0234 16.0709 12.3418 15.9488 11.9011 15.4927C11.0591 14.6215 10.3756 13.6206 9.86932 12.5155C9.36114 11.4049 9.04517 10.2246 8.93173 9.00712C8.8736 8.37642 9.21863 7.77051 9.79244 7.49761L11.3648 6.75049C11.7399 6.57302 11.903 6.11691 11.7267 5.73622L10.4581 2.96915C10.3316 2.69245 10.0596 2.52832 9.77744 2.52832L9.7764 2.53013Z" fill="#767676"/>
2515                                        </svg>
2516                                        Phone: ${location.phone}
2517                                    </div>
2518                                </div>
2519                                <div class="svt-contact-store-info-right">
2520                                    <div class="svt-store-img-wrap">
2521                                        <img fetchpriority="high" decoding="async" onerror="this.onerror=null; this.removeAttribute('srcset'); this.src='${embeddata.theme_url}/images/location-placeholder.svg'" src="${location_data}" alt="${location.name}" srcset="${location_data} 448w, ${location_data} 448w" />
2522                                    </div>
2523                                </div>
2524                            </div>
2525                            <div class="svt-contact-store-info-bottom">
2526                                <div class="svt-store-time">
2527                                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
2528                                        <path d="M12.75 6C12.75 5.58579 12.4142 5.25 12 5.25C11.5858 5.25 11.25 5.58579 11.25 6V12C11.25 12.2841 11.4105 12.5438 11.6646 12.6708L15.6646 14.6708C16.0351 14.8561 16.4856 14.7059 16.6708 14.3354C16.8561 13.9649 16.7059 13.5144 16.3354 13.3292L12.75 11.5365V6Z" fill="#767676"/>
2529                                        <path fill-rule="evenodd" clip-rule="evenodd" d="M12 1.25C6.06294 1.25 1.25 6.06294 1.25 12C1.25 17.9371 6.06294 22.75 12 22.75C17.9371 22.75 22.75 17.9371 22.75 12C22.75 6.06294 17.9371 1.25 12 1.25ZM2.75 12C2.75 6.89137 6.89137 2.75 12 2.75C17.1086 2.75 21.25 6.89137 21.25 12C21.25 17.1086 17.1086 21.25 12 21.25C6.89137 21.25 2.75 17.1086 2.75 12Z" fill="#767676"/>
2530                                    </svg>
2531                                    Timings
2532                                </div>
2533                                <div class="svt-store-time-table">
2534                                    <table id="dynamic-table" class="has-text-color has-link-color has-border-color has-theme-palette-9-border-color">
2535                                        <tbody>
2536                                            ${(() => {
2537                                                let rows = '';
2538                                                hours.forEach((hour) => {
2539                                                    rows += `
2540                                                        <tr>
2541                                                            <td>${hour.day}</td>
2542                                                            <td class="has-text-align-right" data-align="right">${hour.hours}</td>
2543                                                        </tr>   
2544                                                    `;
2545                                                });
2546                                                return rows; // Return the constructed rows
2547                                            })()}
2548                                        </tbody>
2549                                    </table>
2550                                </div>
2551                            </div>
2552                            <div class="svt-contact-direction">
2553                                <a href="https://www.google.com/maps?q=${location.latitude},${location.longitude}" target="_blank">
2554                                    <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none">
2555                                        <path d="M12.5303 0.46967C12.2374 0.176777 11.7626 0.176777 11.4697 0.46967C11.1768 0.762563 11.1768 1.23744 11.4697 1.53033L15.1893 5.25H5C3.74022 5.25 2.53204 5.75044 1.64124 6.64124C0.750445 7.53204 0.25 8.74022 0.25 10V17C0.25 17.4142 0.585786 17.75 1 17.75C1.41421 17.75 1.75 17.4142 1.75 17V10C1.75 9.13805 2.09241 8.3114 2.7019 7.7019C3.3114 7.09241 4.13805 6.75 5 6.75H15.1893L11.4697 10.4697C11.1768 10.7626 11.1768 11.2374 11.4697 11.5303C11.7626 11.8232 12.2374 11.8232 12.5303 11.5303L17.5303 6.53033C17.8232 6.23744 17.8232 5.76256 17.5303 5.46967L12.5303 0.46967Z" fill="#CB333B"/>
2556                                    </svg>
2557                                    Get Directions
2558                                </a>
2559                            </div>`; 
2560                    $('.svt-contact-store-info').html(html);
2561                }
2562            }
2563            const updateCartCountFn = (items) => {
2564                const loggedIn = isUserLoggedIn();
2565                const cartCount = items.length;
2566                if(cartCount > 0 && loggedIn) {
2567                    $('.hs-cart-count').html(cartCount).addClass('active');
2568                }
2569                else {
2570                    $('.hs-cart-count').html('').removeClass('active');
2571                }
2572            };
2573            
2574            const fetchBasketData = (user) => {
2575                const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
2576                const email = user.email;
2577            
2578                let headers = {
2579                    'emailid': email,
2580                    'authToken': user.authToken,
2581                    'location': getCookie('selectedLocation'),
2582                    'pricelist': getCookie('selectedPriceList'),
2583                    'Content-Type': 'application/json'
2584                };
2585            
2586                return api.getData('/user/basket?lite=true', headers)
2587                    .then(response => {
2588                        if (response.basketItems) {
2589                            setBasket(response);
2590                            updateCartCountFn(response.basketItems);
2591                        }
2592                    })
2593                    .catch(error => console.error('Error fetching basket data:', error));
2594            };
2595            
2596            const loadUserSession = async () => {
2597                const user = JSON.parse(localStorage.getItem('user'));
2598                if(user != null) {
2599                    try {
2600                        const api = new HomesomeAPI(hsdata.base_url, hsdata.hs_api_key);
2601                        const email = user.email;
2602                
2603                        let headers = {
2604                            'emailid': email,
2605                            'authToken': user.authToken,
2606                            'location': getCookie('selectedLocation'),
2607                            'Content-Type': 'application/json'
2608                        };
2609                
2610                        return await api.getData('/user', headers)
2611                            .then(response => {
2612                                if(!response.error) {
2613                                    const user = JSON.stringify(response);
2614                                    localStorage.setItem('user', user);
2615                                    setUserCookie();
2616                                    return response;
2617                                }
2618                                return null;
2619                            })
2620                            .catch(error => {
2621                                console.error('Error fetching user data:', error);
2622                                return null; // Return null if there's an error
2623                            });
2624                    } catch (error) {
2625                        console.error('Error fetching user session:', error);
2626                        return null; // Return null if there's an exception
2627                    }
2628                }
2629            };
2630            
2631            const initializeBasket = () => {
2632                let user = localStorage.getItem('user');
2633                if (user) {
2634                    user = JSON.parse(user);
2635                    let basket = localStorage.getItem('basket');
2636                    if (!basket) {
2637                        return fetchBasketData(user);
2638                    } else {
2639                        basket = JSON.parse(basket);
2640                        if(typeof basket.items != "undefined") {
2641                            updateCartCountFn(basket.items);
2642                        }
2643                        else {
2644                            return fetchBasketData(user);
2645                        }
2646                    }
2647                }
2648            };
2649
2650            const loggedIn = isUserLoggedIn();
2651            
2652            console.log('Logged in: ',loggedIn);
2653            if (loggedIn == false) {
2654                const user = localStorage.getItem('user');
2655                // console.log(user);
2656                if (isRefreshed) {
2657                    isRefreshed = false;
2658                    loadUserSession().then(user => {
2659                        // console.log('After load session: ',user);
2660                        if (user) {
2661                            // console.log('user session set');
2662                            initializeBasket();
2663                            // loadPointsHistory();
2664                            // loadLifetimeSaving();
2665                        }
2666                    });
2667                } else {
2668                    initializeBasket();
2669                }
2670            }
2671            else {
2672                jQuery('body').addClass('hs-logged-in');
2673                const user = localStorage.getItem('user');
2674                if (isRefreshed) {
2675                    isRefreshed = false;
2676                    loadUserSession().then(user => {
2677                        // console.log('After load session: ',user);
2678                        if (user) {
2679                            // console.log('user session set');
2680                            initializeBasket();
2681                            // loadPointsHistory();
2682                            // loadLifetimeSaving();
2683                        }
2684                    });
2685                } else {
2686                    initializeBasket();
2687                }
2688            }
2689        },100);
2690    });
2691    $(document).ready(function() {
2692        initLocation();                        
2693        $(document).on('click','.mobile-app-popup-close',function() {
2694            document.cookie = `mobileAppClosed=1; path=/`;
2695            $('.svt-mobile-app-popup').fadeOut();
2696        });
2697        let lastScrollY = $(window).scrollTop();
2698        $(window).on('scroll', function () {
2699            const currentScrollY = $(window).scrollTop();
2700            if (currentScrollY < lastScrollY) {
2701                // Scrolling up
2702                $('body').addClass('scrolling-up').removeClass('scrolling-down');
2703            } else {
2704                // Scrolling down
2705                $('body').addClass('scrolling-down').removeClass('scrolling-up');
2706                if(currentScrollY < 190) {
2707                    $('body').removeClass('scrolling-down');
2708                }
2709            }
2710            lastScrollY = currentScrollY <= 0 ? 0 : currentScrollY; // Prevent negative values
2711        });
2712    });
2713    $(window).load(function() {
2714        if($(window).width() < 768) {
2715            const mobileAppClosed = getCookie('mobileAppClosed');
2716            if(mobileAppClosed == null) {
2717                $('.svt-mobile-app-popup').fadeIn();
2718            }
2719        }
2720    });
2721})(jQuery);

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.