1import{selectedFacets}from"xgen-state";import{refreshFacetResults}from"xgen-api";const SELECTORS={CONTAINER:"#xgen-filters",FILTER_GROUP:".xgen-filter-group",FILTER_HEADER:".xgen-filters-header",FILTER_BODY:".xgen-filters-body",BODY_WRAPPER:".xgen-filters--body-wrapper",CHECKBOX_ITEM:".xgen-filters-checkbox-item",MORE_BTN:".xgen-filters-more-button",PRICE_GO_BTN:"#xgen-price-submit-btn",PRICE_INPUT_FROM:"#xgen-price-range-from",PRICE_INPUT_TO:"#xgen-price-range-to",PRICE_CONTAINER:".price-range-container",HIDDEN_OPTION:".hidden-option"},CLASSES={EXPANDED:"xgen-filters-body--expanded",SELECTED:"selected"};export function buildFilterContext(selected){const context={},arrayKeys=new Set(["colors","availability","brand","model"]);for(const[key,val]of Object.entries(selected))if(val){if(key==="price"&&!Array.isArray(val)){val.min&&(context.min=parseFloat(val.min)),val.max&&(context.max=parseFloat(val.max));continue}Array.isArray(val)&&val.length>0&&(context[key]=arrayKeys.has(key)?val:val.join(" "))}return context}export function displayFacets(res){const facetsArray=Array.isArray(res)?res:res?.facets;if(!facetsArray)return;const hasKey=["brand","model","type","price","availability"],keysToSkip=["rating_count","rating_value","colors"],valuesToSkip=["-"],formattedFacets=facetsArray.reduce((acc,item)=>(item.facets&&Object.entries(item.facets).forEach(([categoryName,facetValues])=>{const isAllowed=hasKey.includes(categoryName),isBlacklisted=keysToSkip.includes(categoryName);!isAllowed||isBlacklisted||(acc[categoryName]||(acc[categoryName]={}),Object.entries(facetValues).forEach(([valKey,rawCount])=>{if(valuesToSkip.includes(valKey))return;const count=parseInt(rawCount,10);!isNaN(count)&&count>0&&(acc[categoryName][valKey]=count)}),Object.keys(acc[categoryName]).length===0&&delete acc[categoryName])}),acc),{});renderFacets(formattedFacets)}function renderFacets(facets){const container=document.querySelector(SELECTORS.CONTAINER);if(!container)return;attachGlobalFacetListeners(container);const fragment=document.createDocumentFragment(),customOrder=["brand","model","type","price","availability"];Object.entries(facets).sort(([keyA],[keyB])=>{let indexA=customOrder.indexOf(keyA.toLowerCase()),indexB=customOrder.indexOf(keyB.toLowerCase());return indexA===-1&&(indexA=99),indexB===-1&&(indexB=99),indexA-indexB}).forEach(([facetName,options])=>{const isPrice=facetName.toLowerCase()==="price",section=document.createElement("div");section.className="xgen-filter-group",section.id=`xgen-filters-${facetName}`;const header=document.createElement("div");header.className="xgen-filters-header",header.setAttribute("role","button");const isInitiallyExpanded=!0;header.setAttribute("aria-expanded",String(isInitiallyExpanded)),header.innerHTML=` 2 <label class="heading heading--5 margin-0">${formatFacetTitle(facetName)}</label> 3 <svg class="icon icon--chevron-down" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" height="24" width="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"><path d="m6 9 6 6 6-6"></path></svg> 4 `;const body=document.createElement("div");body.id=`xgen-filters-${facetName}-body`,body.className=`xgen-filters-body${isInitiallyExpanded?" "+CLASSES.EXPANDED:""}`;const bodyWrapper=document.createElement("div");bodyWrapper.className="xgen-filters--body-wrapper",bodyWrapper.dataset.filterName=facetName;let entries;if(isPrice?entries=getPriceRangeEntries(options):entries=Object.entries(options),entries.forEach(([optionLabel,count,priceMin,priceMax],index)=>{const optionDiv=document.createElement("div");if(optionDiv.className="xgen-filters-checkbox-item",optionDiv.dataset.name=facetName,optionDiv.dataset.type=isPrice?"range":"text",optionDiv.setAttribute("tabindex","0"),optionDiv.setAttribute("role","checkbox"),optionDiv.setAttribute("aria-checked","false"),isPrice){const min=priceMin??0,max=priceMax??"";optionDiv.id=`xgen-filter-${min}-${max||"max"}`,optionDiv.dataset.minPrice=min,optionDiv.dataset.maxPrice=max}else optionDiv.id=`xgen-filter-${optionLabel.replace(/\s+/g,"-")}`,optionDiv.setAttribute("value",optionLabel);!isPrice&&index>=5&&(optionDiv.style.display="none",optionDiv.classList.add("hidden-option")),optionDiv.innerHTML=` 5 <label class="xgen-filters-checkbox-item-value"><span>${optionLabel}</span></label>
6 <span class="xgen-filters-checkbox-item-count paragraph-2">(${count})</span> 7 `,bodyWrapper.appendChild(optionDiv)}),isPrice&&selectedFacets.price){const{min,max}=selectedFacets.price,filterId=`xgen-filter-${min}-${max||"max"}`;if(!bodyWrapper.querySelector(`#${filterId}`)){const customDiv=document.createElement("div");customDiv.className=`${CLASSES.SELECTED} xgen-filters-checkbox-item`,customDiv.dataset.name="price",customDiv.dataset.type="range",customDiv.dataset.minPrice=min,customDiv.dataset.maxPrice=max||"",customDiv.id=filterId,customDiv.setAttribute("aria-checked","true");const label=max?`$${parseFloat(min)} - $${parseFloat(max)}`:`$${parseFloat(min)} & up`;customDiv.innerHTML=`<label class="xgen-filters-checkbox-item-value"><span>${label}</span></label> 8 <span class="xgen-filters-checkbox-item-count paragraph-2 custom-price-count"></span>`;const priceContainer=bodyWrapper.querySelector(SELECTORS.PRICE_CONTAINER);bodyWrapper.insertBefore(customDiv,priceContainer)}}if(!isPrice&&entries.length>5){const toggleBtn=document.createElement("button");toggleBtn.className="xgen-filters-more-button small-text",toggleBtn.textContent="+ More",bodyWrapper.appendChild(toggleBtn)}isPrice&&renderPriceInputs(bodyWrapper,options),body.appendChild(bodyWrapper),section.appendChild(header),section.appendChild(body),fragment.appendChild(section)}),container.innerHTML="",container.appendChild(fragment)}function getPriceRangeEntries(priceData){const ranges=[{label:"under $100",min:0,max:100,count:0},{label:"$100 - $200",min:100,max:200,count:0},{label:"$200 - $300",min:200,max:300,count:0},{label:"$300 - $400",min:300,max:400,count:0},{label:"$400 - $500",min:400,max:500,count:0},{label:"$500 - $1,000",min:500,max:1e3,count:0},{label:"$1,000 & up",min:1e3,max:1/0,count:0}];for(const[priceStr,qty]of Object.entries(priceData)){const price=parseFloat(priceStr);if(!isNaN(price)){for(const r of ranges)if(price>=r.min&&price<r.max){r.count+=qty;break}}}return ranges.filter(r=>r.count>0).map(r=>[r.label,r.count,r.min,r.max===1/0?null:r.max])}function renderPriceInputs(container,priceOptions){const prices=Object.keys(priceOptions).map(parseFloat).filter(n=>!isNaN(n)),minPrice=prices.length?Math.min(...prices):0,maxPrice=prices.length?Math.max(...prices):0,priceInputHtml=` 9 <div class="price-range-container"> 10 <div class="price-range-content"> 11 <div class="xgen-price-range-input-container text-box"> 12 <label><span>$</span><input min="${minPrice}" max="${maxPrice}" type="number" class="price-range-input" id="${SELECTORS.PRICE_INPUT_FROM.substring(1)}"></label> 13 </div> 14 <span>-</span> 15 <div class="xgen-price-range-input-container text-box"> 16 <label>$<input min="${minPrice}" max="${maxPrice}" type="number" class="price-range-input" id="${SELECTORS.PRICE_INPUT_TO.substring(1)}"></label> 17 </div> 18 <button id="${SELECTORS.PRICE_GO_BTN.substring(1)}" class="button-text">Go</button> 19 </div> 20 </div> 21 `;container.insertAdjacentHTML("beforeend",priceInputHtml)}function attachGlobalFacetListeners(container){container.dataset.eventsAttached!=="true"&&(container.dataset.eventsAttached="true",container.addEventListener("click",e=>{const target=e.target,checkboxItem=target.closest(SELECTORS.CHECKBOX_ITEM);if(checkboxItem){handleFacetItemClick(checkboxItem);return}const header=target.closest(SELECTORS.FILTER_HEADER);if(header){toggleGroupExpand(header);return}const moreBtn=target.closest(SELECTORS.MORE_BTN);if(moreBtn){toggleShowMore(moreBtn);return}const goBtn=target.closest(SELECTORS.PRICE_GO_BTN);if(goBtn){handleCustomPriceSubmit(goBtn);return}}),container.addEventListener("keypress",e=>{const checkboxItem=e.target.closest(SELECTORS.CHECKBOX_ITEM);checkboxItem&&(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),handleFacetItemClick(checkboxItem))}))}async function handleFacetItemClick(item){const{type:facetType,name:facetName,minPrice,maxPrice}=item.dataset,value=item.getAttribute("value"),newState=!(item.getAttribute("aria-checked")==="true");item.setAttribute("aria-checked",String(newState)),item.classList.toggle(CLASSES.SELECTED,newState),facetType==="range"&&facetName==="price"?newState?(document.querySelectorAll(`${SELECTORS.CHECKBOX_ITEM}[data-name="price"]`).forEach(el=>
21{el!==item&&(el.setAttribute("aria-checked","false"),el.classList.remove(CLASSES.SELECTED))}),selectedFacets[facetName]={min:minPrice,max:maxPrice}):delete selectedFacets[facetName]:(selectedFacets[facetName]||(selectedFacets[facetName]=[]),newState?selectedFacets[facetName].includes(value)||selectedFacets[facetName].push(value):(selectedFacets[facetName]=selectedFacets[facetName].filter(v=>v!==value),selectedFacets[facetName].length===0&&delete selectedFacets[facetName])),await updateUrlAndRefresh(selectedFacets)}function toggleGroupExpand(header){const body=header.nextElementSibling,isExpanded=header.getAttribute("aria-expanded")==="true";header.setAttribute("aria-expanded",String(!isExpanded)),body.classList.toggle(CLASSES.EXPANDED,!isExpanded)}function toggleShowMore(btn){const hiddenOptions=btn.closest(SELECTORS.BODY_WRAPPER).querySelectorAll(SELECTORS.HIDDEN_OPTION),isExpanded=btn.textContent.includes("- Less");hiddenOptions.forEach(opt=>{opt.style.display=isExpanded?"none":"flex"}),btn.textContent=isExpanded?"+ More":"- Less"}function handleCustomPriceSubmit(btn){const wrapper=btn.closest(SELECTORS.BODY_WRAPPER),fromInput=wrapper.querySelector(SELECTORS.PRICE_INPUT_FROM),toInput=wrapper.querySelector(SELECTORS.PRICE_INPUT_TO),min=fromInput.value!==""?parseFloat(fromInput.value):0,max=toInput.value!==""?parseFloat(toInput.value):null;if(fromInput.value===""&&toInput.value===""||max!==null&&min>max)return;const filterId=`xgen-filter-${min}-${max??"max"}`;let targetOption=wrapper.querySelector(`#${filterId}`);if(!targetOption){const optionLabel=max!==null?`$${min} - $${max}`:`$${min} & up`;targetOption=document.createElement("div"),targetOption.className="xgen-filters-checkbox-item",targetOption.dataset.name="price",targetOption.dataset.type="range",targetOption.dataset.minPrice=min,targetOption.dataset.maxPrice=max||"",targetOption.setAttribute("tabIndex",0),targetOption.setAttribute("role","checkbox"),targetOption.setAttribute("aria-checked","false"),targetOption.id=filterId,targetOption.innerHTML=`<label class="xgen-filters-checkbox-item-value"><span>${optionLabel}</span></label><span class="xgen-filters-checkbox-item-count paragraph-2 custom-price-count"></span>`;const priceContainer=wrapper.querySelector(SELECTORS.PRICE_CONTAINER);wrapper.insertBefore(targetOption,priceContainer)}typeof handleFacetItemClick=="function"&&handleFacetItemClick(targetOption),fromInput.value="",toInput.value=""}async function updateUrlAndRefresh(selected){const url=new URL(window.location.href),params=url.searchParams;for(const key of[...params.keys()])key.startsWith("filter_")&&key!=="filter_sort"&¶ms.delete(key),["min_price","max_price","page"].includes(key)&¶ms.delete(key);Object.entries(selected).forEach(([facet,values])=>{values&&(facet==="price"&&!Array.isArray(values)?(values.min&¶ms.set("min_price",values.min),values.max&¶ms.set("max_price",values.max)):Array.isArray(values)&&values.length>0&¶ms.append(`filter_${facet}`,values.map(v=>encodeURIComponent(v)).join(",")))}),window.history.replaceState({},"",url.toString()),await refreshFacetResults(params,selected)}export function restoreSelectedFacets(selected){const facets=selected||window.selectedFacets;facets&&Object.entries(facets).forEach(([facetName,values])=>{if(values)if(facetName==="price"&&!Array.isArray(values)){const minStr=values.min||"0",maxStr=values.max||"";markOptionSelected(`.xgen-filters-checkbox-item[data-name="price"][data-min-price="${minStr}"][data-max-price="${maxStr}"]`)}else Array.isArray(values)&&values.forEach(value=>{markOptionSelected(`.xgen-filters-checkbox-item[data-name="${facetName}"][value="${CSS.escape(value)}"]`)})})}export function restoreFacetSelections(){const params=new URLSearchParams(window.location.search);for(const[key,value]of params.entries())if(key.startsWith("filter_")&&key!=="filter_sort"){const facetName=key.replace("filter_","");decodeURIComponent(value).split(",").forEach(v=>{markOptionSelected(`.xgen-filters-checkbox-item[data-name="${facetName}"][value="${CSS.escape(decodeURIComponent(v))}"]`)})}const minStr=params.get("min_price"),maxStr=params.get("max_price");(minStr!==null||maxStr!==null)&&markOptionSelected(`.xgen-filters-checkbox-item[data-name="price"][data-min-price="${minStr||"0"}"][data-max-price="${maxStr||""}"]`)}function markOptionSelected(selector){const el=document.querySelector(selector);el&&(el.setAttribute("aria-checked","true"),el.classList.add(CLASSES.SELECTED))}function formatFacetTitle(name){return name.replace(/_/g," ").replace(/\b\w/g,c=>c.toUpperCase())} 22//# sourceMappingURL=/cdn/shop/t/600/assets/xgen-facets.js.map?v=107044843789649096361788243522
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.