https://capraaudio.com/cdn/shop/t/4/assets/headphone-model-finder.js?v=36230834451338875481787681474
1class HeadphoneModelFinder extends HTMLElement{constructor(){super(),this.input=this.querySelector("[data-model-finder-input]"),this.results=this.querySelector("[data-model-finder-results]"),this.status=this.querySelector("[data-model-finder-status]"),this.searchLink=this.querySelector("[data-model-finder-search-link]"),this.debounceTimer=null,this.productIndex=null,this.productIndexPromise=null}connectedCallback(){!this.input||!this.results||!this.status||(this.input.addEventListener("input",()=>{window.clearTimeout(this.debounceTimer),this.debounceTimer=window.setTimeout(()=>this.search(),250)}),this.input.addEventListener("keydown",event=>this.onKeydown(event)))}async search(){const term=this.input.value.trim();if(this.updateSearchLink(term),term.length<2){this.clearResults();return}this.setLoading(!0);try{const index=await this.loadProductIndex(),query=this.normalize(term),compactQuery=this.compact(term);if(compactQuery.length<2){this.clearResults();return}const products=index.map(product=>{let score=0;return product.compactTitle.includes(compactQuery)&&(score+=30),product.compactHandle.includes(compactQuery)&&(score+=25),product.compactDescription.includes(compactQuery)&&(score+=20),product.normalizedDescription.includes(query)&&(score+=5),{...product,score}}).filter(product=>product.score>0).sort((a,b)=>b.score-a.score||a.title.localeCompare(b.title)).slice(0,8);this.renderResults(products,term)}catch{this.renderError()}finally{this.setLoading(!1)}}async loadProductIndex(){return this.productIndex?this.productIndex:this.productIndexPromise?this.productIndexPromise:(this.productIndexPromise=fetch(this.dataset.productsUrl).then(response=>{if(!response.ok)throw new Error(`Product index request failed: ${response.status}`);return response.json()}).then(({products})=>(this.productIndex=products.map(product=>{const description=new DOMParser().parseFromString(product.body_html||"","text/html").body.textContent.replace(/\s+/g," ").trim(),image=product.images?.[0];return{title:product.title,url:`/products/${product.handle}`,imageUrl:image?.src||"",imageAlt:image?.alt||product.title,normalizedDescription:this.normalize(description),compactDescription:this.compact(description),compactTitle:this.compact(product.title),compactHandle:this.compact(product.handle)}}),this.productIndex)).catch(error=>{throw this.productIndexPromise=null,error}),this.productIndexPromise)}normalize(value){return value.toLowerCase().normalize("NFKD").replace(/[\u0300-\u036f]/g,"").replace(/[^a-z0-9]+/g," ").trim()}compact(value){return this.normalize(value).replace(/\s+/g,"")}renderResults(products,term){if(this.results.replaceChildren(),!products.length){this.status.textContent=this.dataset.noResults.replace("[term]",term),this.results.hidden=!1,this.searchLink.hidden=!1,this.input.setAttribute("aria-expanded","true");return}const list=document.createElement("ul");list.className="model-finder__list list-unstyled",list.setAttribute("role","listbox"),products.forEach((product,index)=>{const item=document.createElement("li");item.setAttribute("role","option");const link=document.createElement("a");if(link.className="model-finder__result link link--text",link.href=product.url,link.dataset.modelFinderOption="",index===0&&(link.dataset.firstOption=""),product.imageUrl){const image=document.createElement("img");image.className="model-finder__image",image.src=product.imageUrl,image.alt=product.imageAlt,image.width=72,image.height=72,image.loading="lazy",link.append(image)}else{const placeholder=document.createElement("span");placeholder.className="model-finder__image model-finder__image--placeholder",placeholder.setAttribute("aria-hidden","true"),link.append(placeholder)}const copy=document.createElement("span");copy.className="model-finder__result-copy";const eyebrow=document.createElement("span");eyebrow.className="caption-with-letter-spacing",eyebrow.textContent=product.compactTitle.includes(this.compact(term))?this.dataset.nameMatchLabel:this.dataset.compatibilityMatchLabel;const title=document.createElement("span");title.className="model-finder__result-title h5",title.textContent=product.title,copy.append(eyebrow,title),link.append(copy),item.append(link),list.append(item)}),this.results.append(list),this.status.textContent=this.dataset.resultCount.replace("[count]",products.length).replace("[term]",term),this.results.hidden=!1,this.searchLink.hidden=!1,this.input.setAttribute("aria-expanded","true")}renderError(){this.results.replaceChildren(),this.results.hidden=!1,this.searchLink.hidden=!1,this.status.textContent=this.dataset.errorMessage,this.input.setAttribute("aria-expanded","true")}onKeydown(event){if(event.key==="Escape")this.clearResults(),this.input.focus();else if(event.key==="ArrowDown"){const firstOption=this.querySelector("[data-first-option]");firstOption&&(event.preventDefault(),firstOption.focus())}}updateSearchLink(term){if(!this.searchLink)return;const url=new URL(this.searchLink.dataset.baseUrl,window.location.origin);url.searchParams.set("q",term),url.searchParams.set("type","product"),this.searchLink.href=`${url.pathname}${url.search}`}setLoading(isLoading){this.toggleAttribute("loading",isLoading),this.input.setAttribute("aria-busy",String(isLoading)),isLoading&&(this.status.textContent=this.dataset.loadingMessage)}clearResults(){this.results.replaceChildren(),this.results.hidden=!0,this.searchLink.hidden=!0,this.status.textContent="",this.input.setAttribute("aria-expanded","fal
1se")}}customElements.get("headphone-model-finder")||customElements.define("headphone-model-finder",HeadphoneModelFinder); 2//# sourceMappingURL=/cdn/shop/t/4/assets/headphone-model-finder.js.map?v=36230834451338875481787681474
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.