https://www.lovisa.co.uk/cdn/shop/t/811/assets/xgen-product-recomm…?v=159720048528996529371789977862
1if(typeof window.CustomProductRecommendations>"u"){let addToCart2=function(form){const variantId=form.querySelector('input[name="id"]').value,product_id=form.querySelector('input[name="id"]').dataset.productId;let properties={};const collectionsInput=form.querySelector('input[name="properties[_collections]"]');collectionsInput&&collectionsInput.value&&(properties._collections=collectionsInput.value);const items=[{id:variantId,quantity:1}];Object.keys(properties).length>0&&(items[0].properties=properties),fetch(`${window.Shopify.routes.root}cart/add.js`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({items})}).then(data=>data.json()).then(json=>{if(json.items&&json.items[0]){const addedItem=json.items[0];window._learnq=window._learnq||[];const rawSrc=addedItem.image||"",imageSrc=rawSrc?"https:"+rawSrc.replace(/(\.[^.]*)$/,"_grande$1"):"",klaviyoItem={Name:addedItem.title||addedItem.product_title||"",ProductID:addedItem.product_id?addedItem.product_id:"",Categories:addedItem.collections||[],ImageURL:imageSrc,URL:`${window.theme.shopSecureUrl||window.location.origin}${addedItem.url?addedItem.url.split("?")[0]:""}`,Brand:addedItem.vendor||"",Price:slate.Currency.formatMoney(addedItem.price),$value:parseFloat(slate.Currency.formatMoney(addedItem.price,"{{amount}}")),CompareAtPrice:addedItem.compare_price?slate.Currency.formatMoney(addedItem.compare_price):""};window._learnq.push(["track","Added to Cart",klaviyoItem])}if(!json.status)if(window.location.pathname==="/cart")theme.cartPage.updateCartItemsEvent(),window.theme.cartPage.refreshCart(),setTimeout(()=>{window.scrollTo({top:0,behavior:"smooth"})},500);else if(theme.sideCart.updateCartItemsEvent(),window.theme.sideCart.refreshCart(),window.theme.settings.enable_bopis){let size;if(json.items[0].options_with_values&&json.items[0].options_with_values.length){let sizeOption=json.items[0].options_with_values.find(option=>option.name.toLowerCase()==="size");sizeOption&&(size=sizeOption.value)}updateCartPopup({title:json.items[0].product_title,image:json.items[0].image,quantity:1,size,id:product_id,vId:variantId})}else theme.sideCart.openDrawer()}).catch(err=>{console.error(err),window.location.href=window.Shopify.routes.root+"cart"})};var addToCart=addToCart2;window.CustomProductRecommendations=class extends HTMLElement{constructor(){super(),this.waitOnReady()}waitOnReady(){if(this.shadowRoot&&window.xgenCss){const link=document.createElement("link");link.rel="stylesheet",link.href=window.xgenCss,this.shadowRoot.appendChild(link)}this.shadowRoot&&this.shadowRoot.querySelector('form[action*="cart/add"] input[name="id"]')?setTimeout(()=>{this.onReady()},0):setTimeout(()=>{this.waitOnReady()},1e3)}formatMoney(price){const formatted=slate.Currency.formatMoney(price,window.theme.moneyFormat).replace(/<\/?[^>]+(>|$)/g,""),symbol=window.theme.currentCurrencySymbol;return formatted.includes(symbol)?formatted.replace(symbol,`<em class="currency-symbol">${symbol}</em>`):`<em class="currency-symbol">${symbol}</em>${slate.Currency.removeCurrencySymbol(formatted)}`}updateProductPrice(productCard,currentVariant){const pricingWrap=productCard.querySelector(".xgen-product-card__price-container");if(pricingWrap&¤tVariant.price){let pricingHTML=`<p class="xgen-product-card__price xgen-text-[length:var(--price-size)] apply-font-body xgen-apply-font-body xgen-not-italic xgen-font-bold xgen-text-[var(--price-color)]"> 2 ${this.formatMoney(currentVariant.price)} 3 </p>`;currentVariant.compareAtPrice>currentVariant.price&&(pricingHTML=`<p class="xgen-product-card__compare-price xgen-text-[length:var(--compare-size)] apply-font-body xgen-apply-font-body xgen-not-italic xgen-font-normal xgen-line-through xgen-text-[var(--compare-color)]"> 4 ${this.formatMoney(currentVariant.compareAtPrice)} 5 </p>`+pricingHTML,pricingHTML+=`<span class="product-per-off show-per-off-mobile show-per-off-desktop">(-${Math.round((currentVariant.compareAtPrice-currentVariant.price)*100/currentVariant.compareAtPrice)}%)</span>`),pricingWrap.innerHTML=pricingHTML}pricingWrap.classList.add("visible")}handleProductCard(productCard,filteredProducts,repeated=!1){const _this=this,variantIdOriginalInput=productCard.querySelector('input[name="id"].xgen-product-variant-id');if(variantIdOriginalInput&&filteredProducts.length){const variantId=variantIdOriginalInput.value,form=productCard.querySelector('form[action*="cart/add"]'),product=filteredProducts.find(product2=>product2.variants.find(variant=>variant.id===variantId));variantIdOriginalInput.name="variant_id";const variantIdInput=document.createElement("input");if(variantIdInput.name="id",variantIdInput.type="hidden",variantIdInput.value=variantId,product&&(variantIdInput.dataset.productId=product.id,product.collections&&product.collections.length)){let collectionsInput=form.querySelector('input[name="properties[_collections]"]');collectionsInput||(collectionsInput=document.createElement("input"),collectionsInput.name="properties[_collections]",collectionsInput.type="hidden",form.appendChild(collectionsInput)),collectionsInput.value=[...product.collections].sort().join(",")}if(form.appendChild(variantIdInput),!product)return;product.tags&&product.tags.some(tag=>typeof tag=="string"&&tag.trim().toLowerCase()==="in-store")&&form&&(form.style.display="none");let currentVariant=product.variants?product.variants.find(variant=>variant.id===variantId):null;const xGenOptions=productCard.querySelectorAll(".xgen-product-card__options-selector button.xgen-block-option");xGenOptions.length&&xGenOptions.forEach(function(xGenOption){const xGenOptionName=xGenOption.innerText.trim();if(product){const option=product.variants.find(variant=>variant.title===xGenOptionName);option&&option.available?(xGenOption.dataset.variantId=option.id,option.id===variantId&&xGenOption.classList.add("active"),xGenOption.addEventListener("click",function(e){e.preventDefault(),variantIdInput.value=option.id,xGenOptions.forEach(function(xGenOptionInner){xGenOptionInner.classList.remove("active")}),xGenOption.classList.add("active"),currentVariant=option,_this.updateProductPrice(productCard,currentVariant)})):(xGenOption.disabled=!0,xGenOption.classList.add("disabled"))}}),_this.updateProductPrice(productCard,currentVariant),form.addEventListener("submit",function(e){return e.preventDefault(),addToCart2(form),!1}),form.querySelector("button.xgen-product-card__add-to-cart").addEventListener("click",function(e){return e.preventDefault(),addToCart2(form),!1})}else repeated||setTimeout(()=>{_this.handleProductCard(productCard,filteredProducts,!0)},100)}async onReady(){const _this=this,productCards=Array.from(this.shadowRoot.querySelectorAll(".xgen-product-card")),variantIds=[];
5Array.from(productCards).forEach(productCard=>{productCard.querySelector('input[name="id"].xgen-product-variant-id')&&variantIds.push(productCard.querySelector('input[name="id"].xgen-product-variant-id').value)});const PRODUCTS_STORAGE_KEY="graphql_all_products_"+Shopify.country,allProducts=JSON.parse(sessionStorage.getItem(PRODUCTS_STORAGE_KEY)||"[]");let filteredProducts=allProducts.length?allProducts.filter(product=>product.variants&&product.variants.find(variant=>variant.id===variantIds.find(id=>id===variant.id))):[];const hasMissingProducts=filteredProducts.length!==variantIds.length,hasMissingData=filteredProducts.some(p=>!Array.isArray(p.tags)||!Array.isArray(p.collections));if(hasMissingProducts||hasMissingData){const variantIdsToFetch=hasMissingData?variantIds:variantIds.filter(id=>!filteredProducts.find(product=>product.variants.find(variant=>variant.id===id)));hasMissingData&&(filteredProducts=filteredProducts.filter(p=>Array.isArray(p.tags)&&Array.isArray(p.collections)));const resData=await(await fetch(`https://${window.Shopify.shop}/api/2025-10/graphql.json`,{method:"POST",headers:{"Content-Type":"application/graphql","X-Shopify-Storefront-Access-Token":window.theme.storefrontAPIToken},body:` 6 query getProducts @inContext(country: ${Shopify.country}) { 7 ${variantIdsToFetch.map(id=>id?`p_${id}: node(id: "gid://shopify/ProductVariant/${id}") { 8 id 9 ... on ProductVariant { 10 id 11 product { 12 id 13 tags 14 collections(first: 250) { 15 edges { 16 node { 17 handle 18 } 19 } 20 } 21 variants(first: 250) { 22 edges { 23 node { 24 id 25 title 26 availableForSale 27 price { 28 amount 29 } 30 compareAtPrice { 31 amount 32 } 33 } 34 } 35 } 36 } 37 } 38 }`:"").join(` 39`)} 40 41 } 42 `})).json(),resNodes=resData&&resData.data||{};let stillMissingVariantIds=[];Object.keys(resNodes).forEach(key=>{const product=resNodes[key]?.product;product?filteredProducts.push({id:product.id.split("/").pop(),tags:product.tags||[],collections:product.collections&&product.collections.edges?product.collections.edges.map(c=>c.node.handle):[],variants:product.variants.edges.map(variant=>({id:variant.node.id.split("/").pop(),title:variant.node.title,available:variant.node.availableForSale,price:variant.node.price?variant.node.price.amount*100:null,compareAtPrice:variant.node.compareAtPrice?variant.node.compareAtPrice.amount*100:null}))||[]}):stillMissingVariantIds.push(key.split("_")[1])}),stillMissingVariantIds.forEach(id=>{productCards.find(productCard=>productCard?.href?.indexOf(id)!==-1)?.classList.add("xgen-product-card--api-error")}),productCards.forEach(productCard=>{_this.handleProductCard(productCard,filteredProducts,!1)})}else productCards.forEach(productCard=>{_this.handleProductCard(productCard,filteredProducts,!1)})}},customElements.define("x-product-recommendations",window.CustomProductRecommendations)} 43//# sourceMappingURL=/cdn/shop/t/811/assets/xgen-product-recommendations.js.map?v=159720048528996529371789977862
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.