PageSourceSearch

https://sneakerzone.dk/cdn/shop/t/425/assets/m-predictive-search.js?v=134034919666764809821786544806

js sneakerzone.dk collected 2026-09-26 07:27:41 UTC 26,469 bytes, 103 lines download raw bytes

1const mPredictiveSearchNormalizeMoney=value=>String(value).replace(/(?:\s|&nbsp;)*kr\.(?=<|$)/gi,"kr").replace(/(?:\s|&nbsp;)+kr(?=<|$)/gi,"kr"),mPredictiveSearchFormatMoney=amount=>{const moneyFormat=window.theme?.moneyFormat,numericAmount=Number(amount)||0;if(!moneyFormat)return mPredictiveSearchNormalizeMoney(`${numericAmount}${String(window.currencySymbol||"").replace(/\.$/,"")}`);const formatWithDelimiters=(value,precision=2,thousands=",",decimal=".")=>{const fixedValue=value.toFixed(precision),[dollars,remainder]=fixedValue.split(".");return dollars.replace(/\B(?=(\d{3})+(?!\d))/g,thousands)+(precision>0&&remainder?decimal+remainder:"")},placeholderValues={amount:formatWithDelimiters(numericAmount,2),amount_no_decimals:formatWithDelimiters(Math.round(numericAmount),0),amount_with_comma_separator:formatWithDelimiters(numericAmount,2,".",","),amount_no_decimals_with_comma_separator:formatWithDelimiters(Math.round(numericAmount),0,".",","),amount_with_apostrophe_separator:formatWithDelimiters(numericAmount,2,"'",".")};return mPredictiveSearchNormalizeMoney(moneyFormat.replace(/\{\{\s*(amount(?:_[a-z_]+)?)\s*\}\}/g,(_,placeholder)=>placeholderValues[placeholder]??placeholderValues.amount))};class HelloRetail{constructor(){this.baseUrl="https://core.helloretail.com/serve",this.blockKey="594054bf-aa35-4eec-817a-e8aab3fa013a",this.trackingCookieName="hello_retail_id"}async getTrackingUserId(){const savedTrackingUserId=this.normalizeTrackingUserId(document.cookie.split("; ").find(row=>row.startsWith(`${this.trackingCookieName}=`))?.split("=")[1]);return savedTrackingUserId||(window.hrq=window.hrq||[],new Promise(resolve=>{let isResolved=!1;const resolveTrackingUserId=trackingUserId=>{if(isResolved)return;isResolved=!0;const normalizedTrackingUserId=this.normalizeTrackingUserId(trackingUserId)||this.createTrackingUserId();this.saveTrackingUserId(normalizedTrackingUserId),resolve(normalizedTrackingUserId)};window.hrq.push(["getTrackingUserId",resolveTrackingUserId]),setTimeout(resolveTrackingUserId,800)}))}normalizeTrackingUserId(value){const trackingUserId=String(value||"").trim();return/^[a-f0-9]{24}$/i.test(trackingUserId)?trackingUserId:""}createTrackingUserId(){const bytes=new Uint8Array(12);if(window.crypto?.getRandomValues)window.crypto.getRandomValues(bytes);else for(let index=0;index<bytes.length;index+=1)bytes[index]=Math.floor(Math.random()*256);return Array.from(bytes,byte=>byte.toString(16).padStart(2,"0")).join("")}saveTrackingUserId(trackingUserId){const secureAttribute=window.location.protocol==="https:"?";Secure":"";document.cookie=`${this.trackingCookieName}=${trackingUserId};path=/;max-age=31536000;SameSite=Lax${secureAttribute}`}async getSearchResults(searchTerm,options={}){const trackingUserId=await this.getTrackingUserId(),{start=0,count=50,categoriesCount=3}=options,response=await fetch(`${this.baseUrl}/search`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({trackingUserId,query:String(searchTerm??""),key:this.blockKey,products:{start,count,fields:["title","price","priceFormatted","oldPrice","oldPriceFormatted","url","imgUrl","variantProductNumbers","hierarchies","extraData.smallestPriceAndPreviousPriceIfOnSale","extraData.smallestPriceAndPreviousPriceIfOnSaleReplacement","extraDataList"],returnInitialContent:!0},categories:{start:0,count:categoriesCount,fields:["title","url"]}})});if(!response.ok)throw new Error("Hello Retail request failed");const data=await response.json(),product=data?.products?.results?.[0]||data?.initialContent?.products?.results?.[0]||data?.products?.initialContent?.[0]?.products?.[0];return console.log("[Hello Retail product]",product),data}}class PredictiveHelloRetail extends HTMLElement{constructor(){super(),this.helloRetail=new HelloRetail,this.openTrigger=this.querySelector("[data-predictive-search-open]"),this.closeTrigger=this.querySelector("[data-predictive-search-close]"),this.form=this.querySelector("[data-predictive-search-form]"),this.popup=this.querySelector(".m-predictive-search__wrapper"),this.input=this.querySelector('input[type="search"]'),this.content=this.querySelector(".m-predictive-search__content"),this.trendingProducts=[],this.searchQuery="",this.productsLoaded=0,this.totalCount=0,this.isLoading=!1,this.hasMore=!0,this.searchController=null,this.inputTimer=null,this.placeholderTimer=null,this.placeholderText="",this.placeholderIndex=0,this.isDeletingPlaceholder=!1,this.productJsonCache=new Map,this.openMenu=this.openMenu.bind(this),this.closeMenu=this.closeMenu.bind(this),this.onSubmit=this.onSubmit.bind(this),this.onInput=this.onInput.bind(this),this.onScroll=this.onScroll.bind(this),this.onDocumentClick=this.onDocumentClick.bind(this),this.onDocumentKeydown=this.onDocumentKeydown.bind(this),this.animatePlaceholder=this.animatePlaceholder.bind(this)}connectedCallback(){this.openTrigger.addEventListener("click",this.openMenu),this.closeTrigger?.addEventListener("click",this.closeMenu),this.form?.addEventListener("submit",this.onSubmit),this.input?.addEventListener("input",this.onInput),this.content?.addEventListener("scroll",this.onScroll),document.addEventListener("click",this.onDocumentClick),document.addEventListener("keydown",this.onDocumentKeydown),this.startPlaceholderAnimation(),this.loadTrendingProducts()}disconnectedCallback(){this.openTrigger.removeEventListener("click",this.openMenu),this.closeTrigger?.removeEventListener("click",this.closeMenu),this.form?.removeEventListener("submit",this.onSubmit),this.input?.removeEventListener("input",this.onInput),this.content?.removeEventListener("scroll",this.onScroll),document.removeEventListener("click",this.onDocumentClick),document.removeEventListener("keydown",this.onDocumentKeydown),clearTimeout(this.inputTimer),clearTimeout(this.placeholderTimer),this.searchController?.abort()}startPlaceholderAnimation(){this.input&&(this.placeholderText=this.input.dataset.placeholderText||this.input.getAttribute("placeholder")||"",this.placeholderText&&(this.placeholderIndex=0,this.isDeletingPlaceholder=!1,this.input.setAttribute("placeholder",""),this.animatePlaceholder()))}animatePlaceholder(){if(!this.input||!this.placeholderText)return;const nextPlaceholder=this.placeholderText.slice(0,this.placeholderIndex);this.input.setAttribute("placeholder",nextPlaceholder);let delay=this.isDeletingPlaceholder?45:90;!this.isDeletingPlaceholder&&this.placeholderIndex===this.placeholderText.length?(this.isDeletingPlaceholder=!0,delay=1200):this.isDeletingPlaceholder&&this.placeholderIndex===0?(this.isDeletingPlaceholder=!1,delay=350):this.isDeletingPlaceholder?this.placeholderIndex-=1:this.placeholderIndex+=1,this.placeholderTimer=setTimeout(this.animatePlaceholder,delay)}openMenu(){document.body.classList.add("mega-menu-open"),this.popup.classList.add("is-open"),this.closeTrigger.classList.add("is-open"),this.openTrigger.setAttribute("aria-expanded","true"),this.input?.focus()}closeMenu(){document.body.classList.remove("mega-menu-open"),this.popup.classList.remove("is-open"),this.closeTrigger.classList.remove("is-open"),this.openTrigger.setAttribute("aria-expanded","fal
1se"),this.input&&(this.input.value="",this.input.blur()),this.searchQuery="",this.productsLoaded=0,this.totalCount=0,this.hasMore=!0,this.renderTrendingProducts()}onSubmit(event){event.preventDefault(),event.stopPropagation(),this.input?.focus()}onDocumentClick(event){if(!this.popup.classList.contains("is-open"))return;const target=event.target;target instanceof Node&&(this.popup.contains(target)||this.openTrigger.contains(target)||this.closeTrigger?.contains(target)||this.closeMenu())}onDocumentKeydown(event){event.key==="Escape"&&this.popup.classList.contains("is-open")&&this.closeMenu()}async loadTrendingProducts(){try{const data=await this.helloRetail.getSearchResults("*",{start:0,count:16}),products=data?.initialContent?.products?.results||data?.products?.results||[];this.trendingProducts=products.slice(0,16),this.renderTrendingProducts()}catch(error){console.error("Trending load error:",error)}}onInput(event){const value=event.target.value.trim();clearTimeout(this.inputTimer),this.inputTimer=setTimeout(()=>{if(!value){this.searchQuery="",this.renderTrendingProducts();return}this.searchProducts(value)},250)}async searchProducts(query){try{this.searchQuery=query,this.productsLoaded=0,this.hasMore=!0,this.isLoading=!0;const data=await this.helloRetail.getSearchResults(query,{start:0,count:50});if(this.searchQuery!==query)return;const products=data?.products?.results||[],categories=data?.categories?.results||data?.categories||[];this.totalCount=data?.products?.totalCount||data?.products?.totalResults||products.length,this.productsLoaded=products.length,this.hasMore=products.length===50,this.renderSearchProducts(products,!0,categories)}catch(error){console.error("Search error:",error)}finally{this.isLoading=!1}}async loadMoreProducts(){if(!(!this.hasMore||this.isLoading||!this.searchQuery)){this.isLoading=!0;try{const products=(await this.helloRetail.getSearchResults(this.searchQuery,{start:this.productsLoaded,count:50}))?.products?.results||[];this.productsLoaded+=products.length,this.hasMore=products.length===50,this.appendProducts(products)}catch(error){console.error("Load more error:",error)}finally{this.isLoading=!1}}}onScroll(){if(!this.content)return;this.content.scrollHeight-(this.content.scrollTop+this.content.clientHeight)<300&&this.loadMoreProducts()}renderTrendingProducts(){if(!this.content)return;const html=this.trendingProducts.map(product=>this.renderCard(product)).join("");this.content.innerHTML=`
2      <div class="m-predictive-search__content-header">
3        <h2 class="typo-h3">Popul\xE6re produkter</h2>
4        <p class="typo-body-m">16 af vores mest trending produkter lige nu</p>
5      </div>
6
7      <div class="m-predictive-search__content-trending">
8        ${html}
9      </div>
10    `,this.hydrateProductCardPrices(this.content)}renderSearchProducts(products,replace=!1,categories=[]){if(!this.content)return;const html=products.map(product=>this.renderCard(product)).join(""),categoriesHtml=this.renderCategories(categories);if(replace){this.content.innerHTML=`
11        <div class="m-predictive-search__content-header">
12          <h2 class="typo-h3">Kollektioner</h2>
13          ${categoriesHtml}
14        </div>
15
16        <div class="m-predictive-search__content-total-count">
17          <p class="typo-body-m typo-body-600 typo-body-uppercase">${this.totalCount} resultater</p>
18        </div>
19
20        <div class="m-predictive-search__content-trending" data-results>
21          ${html}
22        </div>
23      `,this.hydrateProductCardPrices(this.content);return}this.appendProducts(products)}appendProducts(products){const container=this.querySelector("[data-results]");if(!container)return;const html=products.map(product=>this.renderCard(product)).join("");container.insertAdjacentHTML("beforeend",html),this.hydrateProductCardPrices(container)}renderCard(product){const title=this.escapeHtml(product.title||""),url=this.escapeHtml(product.url||"#"),img=this.escapeHtml(product.imgUrl||""),price=Number(product.price)||0,isSingle=(Array.isArray(product.variantProductNumbers)?product.variantProductNumbers:[]).length<=1,salePricing=this.getSalePricing(product,price),formattedPrice=mPredictiveSearchFormatMoney(salePricing?.price??price),compareAtPrice=salePricing?mPredictiveSearchFormatMoney(salePricing.compareAtPrice):"",pricePrefix=!salePricing&&!isSingle?`${window.priceFrom||""} `:"",badgesHtml=this.renderBadges(product,salePricing),variantsHtml=this.renderVariants(product,url),wishlistHtml=this.renderWishlistButton(product,t
23itle,url);return`
24      <div class="m-product-card__wrraper" data-predictive-product-card data-product-url="${url}">
25        <div class="m-product-card__wrraper-top">
26          <a href="${url}" class="m-product-card__image" aria-label="View ${title}">
27            <div class="m-product-card__image-desk">
28              <img src="${img}" alt="${title}" loading="lazy">
29            </div>
30            <div class="m-product-card__image-overlay"></div>
31          </a>
32
33          ${badgesHtml}
34          ${wishlistHtml}
35          ${variantsHtml}
36        </div>
37
38        <div class="m-product-card__wrraper-bottom">
39          <a href="${url}">
40            <h3 class="typo-h6 typo-body-600 m-product-card__title">
41              ${title}
42            </h3>
43          </a>
44
45          <div class="m-product-card__price" data-predictive-product-price>
46            <span class="typo-body-m typo-body-600" style="color: var(${salePricing?"--m-text-red":"--m-text-blue"});" data-predictive-product-current-price>
47              ${pricePrefix}${formattedPrice}
48            </span>
49            ${salePricing?`
50              <del class="typo-body-s typo-body-600" style="color: var(--m-text-grey);" data-predictive-product-compare-price>
51                <s>${compareAtPrice}</s>
52              </del>
53            `:""}
54          </div>
55        </div>
56      </div>
57    `}hydrateProductCardPrices(scope){Array.from(scope.querySelectorAll("[data-predictive-product-card]:not([data-shopify-price-hydrated])")).forEach(card=>{card.dataset.shopifyPriceHydrated="pending",this.hydrateProductCardPrice(card)})}async hydrateProductCardPrice(card){try{const shopifyProduct=await this.fetchShopifyProductJson(card.dataset.productUrl);if(!shopifyProduct||!card.isConnected)return;const pricing=this.getShopifyProductPricing(shopifyProduct);if(!pricing)return;this.updateProductCardPrice(card,pricing),this.updateProductCardSaleBadge(card,pricing),card.dataset.shopifyPriceHydrated="true"}catch(error){card.dataset.shopifyPriceHydrated="failed",console.error("Predictive search price hydration error:",error)}}async fetchShopifyProductJson(productUrl){const jsonUrl=this.getShopifyProductJsonUrl(productUrl);return jsonUrl?(this.productJsonCache.has(jsonUrl)||this.productJsonCache.set(jsonUrl,fetch(jsonUrl,{credentials:"same-origin",headers:{Accept:"application/json"}}).then(response=>{if(!response.ok)throw new Error(`Product JSON request failed: ${response.status}`);return response.json()}).catch(error=>{throw this.productJsonCache.delete(jsonUrl),error})),this.productJsonCache.get(jsonUrl)):null}getShopifyProductJsonUrl(productUrl){if(!productUrl)return"";try{const pathname=new URL(productUrl,window.location.origin).pathname.replace(/\/$/,"");return pathname.includes("/products/")?`${pathname}.js`:""}catch{return""}}getShopifyProductPricing(product){const variants=Array.isArray(product.variants)?product.variants:[];if(!variants.length)return null;const saleVariant=variants.find(variant=>
57{const price=this.parseShopifyPrice(variant.price),compareAtPrice=this.parseShopifyPrice(variant.compare_at_price);return price!==null&&compareAtPrice!==null&&compareAtPrice>price});if(saleVariant)return{price:this.parseShopifyPrice(saleVariant.price),compareAtPrice:this.parseShopifyPrice(saleVariant.compare_at_price),isSale:!0,showFrom:!1};const prices=variants.map(variant=>this.parseShopifyPrice(variant.price)).filter(price=>price!==null);if(!prices.length)return null;const minPrice=Math.min(...prices),maxPrice=Math.max(...prices);return{price:minPrice,compareAtPrice:null,isSale:!1,showFrom:minPrice!==maxPrice}}updateProductCardPrice(card,pricing){const priceContainer=card.querySelector("[data-predictive-product-price]"),currentPrice=card.querySelector("[data-predictive-product-current-price]");if(!priceContainer||!currentPrice)return;const pricePrefix=pricing.showFrom?`${window.priceFrom||""} `:"";currentPrice.textContent=`${pricePrefix}${mPredictiveSearchFormatMoney(pricing.price)}`,currentPrice.style.color=`var(${pricing.isSale?"--m-text-red":"--m-text-blue"})`,priceContainer.querySelector("[data-predictive-product-compare-price]")?.remove(),!(!pricing.isSale||pricing.compareAtPrice===null)&&priceContainer.insertAdjacentHTML("beforeend",`
58        <del class="typo-body-s typo-body-600" style="color: var(--m-text-grey);" data-predictive-product-compare-price>
59          <s>${mPredictiveSearchFormatMoney(pricing.compareAtPrice)}</s>
60        </del>
61      `)}updateProductCardSaleBadge(card,pricing){const badges=this.ensureProductCardBadges(card);if(!badges||(badges.querySelector('[data-predictive-badge="sale"]')?.remove(),!pricing.isSale||pricing.compareAtPrice===null))return;const savings=mPredictiveSearchFormatMoney(pricing.compareAtPrice-pricing.price);badges.insertAdjacentHTML("beforeend",this.renderBadge(window.productCardBadges?.sale,"",savings,"sale"))}ensureProductCardBadges(card){const existingBadges=card.querySelector("[data-predictive-product-badges]");if(existingBadges)return existingBadges;const wrapperTop=card.querySelector(".m-product-card__wrraper-top"),wishlist=card.querySelector(".m-product-card__wishlist");if(!wrapperTop)return null;const badges=document.createElement("div");return badges.className="m-product-card__badges",badges.dataset.predictiveProductBadges="",wrapperTop.insertBefore(badges,wishlist||null),badges}
61parseShopifyPrice(value){if(value==null||value==="")return null;const price=Number(value);return Number.isFinite(price)?price/100:null}getSalePricing(product,fallbackPrice){const price=this.parsePrice(product.price)??fallbackPrice,oldPrice=this.parsePrice(product.oldPrice);if(oldPrice&&price&&oldPrice>price)return{price,compareAtPrice:oldPrice};const pricePair=this.parsePricePair(product.extraData?.smallestPriceAndPreviousPriceIfOnSale)||this.parsePricePair(product.extraData?.smallestPriceAndPreviousPriceIfOnSaleReplacement);if(pricePair){const[salePrice,compareAtPrice]=pricePair;if(salePrice&&compareAtPrice&&compareAtPrice>salePrice)return{price:salePrice,compareAtPrice}}return null}renderBadges(product,salePricing){const labels=window.productCardBadges||{},badges=[];if(this.isNewIn(product)&&badges.push(this.renderBadge(labels.newIn)),this.isFastDelivery(product)&&badges.push(this.renderBadge(labels.fastDelivery,this.renderFastDeliveryIcon())),salePricing){const savings=mPredictiveSearchFormatMoney(salePricing.compareAtPrice-salePricing.price);badges.push(this.renderBadge(labels.sale,"",savings,"sale"))}return`<div class="m-product-card__badges" data-predictive-product-badges>${badges.filter(Boolean).join("")}</div>`}renderWishlistButton(product,title,productUrl){const productId=this.escapeHtml(product.productNumber||product.extraData?.id||product.extraData?.itemNumber||product.variantProductNumbers?.[0]||"");if(!productId)return"";const cleanProductUrl=this.escapeHtml(product.originalUrl||String(productUrl||"").split("#")[0]);return`
62      <button
63        type="button"
64        aria-label="Add ${title} to wishlist"
65        data-product-id="${productId}"
66        id="gowishRoundedButton${productId}"
67        data-region="denmark"
68        data-producturl="${cleanProductUrl}"
69        class="m-product-card__wishlist"
70      >
71        ${this.renderWishlistIcon()}
72      </button>
73    `}renderWishlistIcon(){return`
74      <svg width="24" height="16" viewBox="0 0 24 16" fill="none" xmlns="http://www.w3.org/2000/svg">
75        <path d="M15.2345 4.43455L14.6011 4.73269L14.8819 5.3291L15.4941 5.08462L15.2345 4.43455ZM19.3435 7.30816L18.6506 7.20914L18.5526 7.89474L19.2371 8.00002L19.3435 7.30816ZM5.79276 8.00816H6.49276L6.49276 6.60816L5.79276 6.60816V7.30816V8.00816ZM5.78999 7.30816L6.48504 7.22506C6.16034 4.50938 7.56369 2.36855 9.27961 1.65908C10.127 1.30871 11.0642 1.29591 11.9697 1.72984C12.8832 2.16757 13.829 3.0925 14.6011 4.73269L15.2345 4.43455L15.8678 4.1364C14.9973 2.28718 13.8518 1.07924 12.5747 0.467302C11.2897 -0.148439 9.93709 -0.127712 8.74468 0.365305C6.38099 1.34261 4.70477 4.128 5.09494 7.39126L5.78999 7.30816ZM15.2345 4.43455L15.4941 5.08462C16.3798 4.73091 17.2795 4.76358 17.871 5.09607C18.3978 5.3922 18.8225 6.00619 18.6506 7.20914L19.3435 7.30816L20.0365 7.40718C20.2752 5.73652 19.6734 4.50319 18.557 3.87565C17.5052 3.28448 16.145 3.31715 14.9749 3.78447L15.2345 4.43455ZM19.3435 7.30816L19.2371 8.00002C21.5661 8.35823 22.4436 9.90337 22.371 11.2737C22.2967 12.6769 21.2413 13.9975 19.3435 13.9975V14.6975V15.3975C22.0448 15.3975 23.6586 13.4339 23.769 11.3477C23.8812 9.22863 22.4592 7.07912 19.45 6.6163L19.3435 7.30816ZM19.3435 14.6975V13.9975H5.38214V14.6975V15.3975H19.3435V14.6975ZM5.38214 14.6975V13.9975C3.01161 13.9975 1.54068 12.3868 1.39988 10.9352C1.33134 10.2286 1.56718 9.53387 2.20091 8.99673C2.85082 8.44588 3.98555 8.00816 5.79276 8.00816V7.30816V6.60816C3.78009 6.60816 2.28042 7.09411 1.29569 7.92874C0.294791 8.7771 -0.104234 9.92966 0.00641602 11.0704C0.223991 13.3135 2.36763 15.3975 5.38214 15.3975V14.6975Z" fill="black"/>
76      </svg>
77    `}renderBadge(config={},icon="",replacement="",type=""){const label=String(config.label||"").trim();if(!label)return"";const text=this.escapeHtml(replacement?label.replace("[[money]]",replacement):label),background=this.escapeHtml(config.background||"#EEFFC8"),color=this.escapeHtml(config.color||"#000000"),badgeTypeAttribute=type?` data-predictive-badge="${this.escapeHtml(type)}"`:"";return`
78      <div class="m-product-card__badges-item" style="background: ${background};color: ${color};"${badgeTypeAttribute}>
79        ${icon}
80        <span class="typo-badges typo-body-600">${text}</span>
81      </div>
82    `}renderFastDeliveryIcon(){return`
83      <svg aria-hidden="true" width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
84        <path d="M8.62066 0.902344L2.625 8.3125H6.125L5.2634 13.0493C5.26176 13.0586 5.26218 13.0681 5.26463 13.0772C5.26707 13.0863 5.27149 13.0948 5.27756 13.102C5.28364 13.1092 5.29122 13.115 5.29978 13.119C5.30834 13.123 5.31767 13.125 5.32711 13.125C5.33715 13.125 5.34705 13.1226 5.35602 13.1181C5.36499 13.1136 5.37279 13.1071 5.37879 13.099L11.375 5.6875H7.875L8.7407 0.950196C8.74187 0.940758 8.74101 0.93118 8.73819 0.922099C8.73536 0.913019 8.73064 0.904643 8.72433 0.89753C8.71801 0.890417 8.71026 0.884729 8.70158 0.880844C8.6929 0.87696 8.68349 0.874968 8.67398 0.875C8.66357 0.875042 8.65332 0.87754 8.64405 0.882291C8.63479 0.887042 8.62677 0.893913 8.62066 0.902344Z" stroke="currentColor" stroke-width="0.7" stroke-linecap="round" stroke-linejoin="round"/>
85      </svg>
86    `}renderVariants(product,productUrl){const sizes=Array.isArray(product.extraDataList?.size)?product.extraDataList.size:[],variantIds=Array.isArray(product.extraDataList?.variantID)?product.extraDataList.variantID:[];if(sizes.length<=1)return"";const links=sizes.slice(0,9).map((size,index)=>{const variantId=this.escapeHtml(variantIds[index]||""),href=variantId?this.addVariantToUrl(productUrl,variantId):productUrl,label=this.escapeHtml(size);return`
87        <a href="${href}" role="listitem" aria-label="${label}" class="m-product-card__variants-link typo-badges">
88          <span>${label}</span>
89        </a>
90      `});return sizes.length>9&&links.push(`
91        <a href="${productUrl}" aria-label="View all variants of ${this.escapeHtml(product.title||"")}" class="m-product-card__variants-link typo-badges">
92          <span>+${sizes.length-9}</span>
93        </a>
94      `),`<div class="m-product-card__variants" role="list">${links.join("")}</div>`}addVariantToUrl(url,variantId){const[urlWithoutHash,hash=""]=String(url||"#").split("#"),separator=urlWithoutHash.includes("?")?"&":"?",variantUrl=`${urlWithoutHash}${separator}variant=${variantId}`;return hash?`${variantUrl}#${hash}`:variantUrl}isNewIn(product){return this.hasProductValue(product,["new in","nyhed","nyheder","new arrivals"])}isFastDelivery(product){return String(product.extraData?.fastDelivery||"").trim().toLowerCase()==="ja"?!0:this.hasProductValue(product,["dag-til-dag levering","48t levering","hurtig levering"])}parsePricePair(value){if(typeof value!="string"||!value.includes(":"))return null;const[price,compareAtPrice]=value.split(":").map(part=>this.parsePrice(part));return price===null||compareAtPrice===null?null:[price,compareAtPrice]}parsePrice(value){if(typeof value=="number")return Number.isFinite(value)?value:null;if(typeof value!="string")return null;let normalizedValue=value.replace(/(?:\s|&nbsp;)/g,"").replace(/[^\d,.-]/g,"");if(!normalizedValue)return null;const lastComma=normalizedValue.lastIndexOf(","),lastDot=normalizedValue.lastIndexOf(".");if(lastComma!==-1&&lastDot!==-1)lastComma>lastDot?normalizedValue=normalizedValue.replace(/\./g,"").replace(",","."):normalizedValue=normalizedValue.replace(/,/g,"");else if(lastComma!==-1){const decimalPart=normalizedValue.slice(lastComma+1);normalizedValue=decimalPart.length>0&&decimalPart.length<=2?normalizedValue.replace(",","."):normalizedValue.replace(/,/g,"")}else if(lastDot!==-1){const parts=normalizedValue.split("."),decimalPart=parts[parts.length-1];(parts.length>2||decimalPart.length===3)&&(normalizedValue=normalizedValue.replace(/\./g,""))}const numberValue=Number(normalizedValue);return Number.isFinite(numberValue)?numberValue:null}hasSaleMarker(product){const saleMarkers=["compare at price greater than 0","nedsat priser","eksklusivt udsalg","onsale"],values=[],addValue=value=>{if(Array.isArray(value)){value.forEach(addValue);return}value!=null&&values.push(String(value).toLowerCase())};return addValue(product.hierarchies),addValue(product.extraDataList?.tags),values.some(value=>saleMarkers.includes(value))}hasProductValue(product,markers){const markerSet=markers.map(marker=>marker.toLowerCase()),values=[],addValue=value=>{if(Array.isArray(value)){value.forEach(addValue);return}value!=null&&values.push(String(value).toLowerCase())};return addValue(product.hierarchies),addValue(product.extraDataList?.tags),addValue(product.extraData?.productType),values.some(value=>markerSet.includes(value))}renderCategories(categories=[]){return categories.length?`
95      <div class="m-predictive-search__collections">
96        ${categories.map(cat=>{const title=this.escapeHtml(cat.title||"");return`
97              <a href="${this.escapeHtml(cat.url||"#")}" class="m-predictive-search__collections-link">
98                <span class="typo-body-m typo-body-uppercase">${title}</span>
99              </a>
100            `}).join("")}
101      </div>
102    `:""}escapeHtml(value){return String(value).replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#039;")}}customElements.get("predictive-hello-retail")||customElements.define("predictive-hello-retail",PredictiveHelloRetail);
103//# sourceMappingURL=/cdn/shop/t/425/assets/m-predictive-search.js.map?v=134034919666764809821786544806

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.