1(()=>{const e=document.currentScript?document.currentScript.src:"";const t=e.replace(/\/assets\/js\/.*$/,"");function appendHeaderMenuItem(){var e,t;const n=document.getElementById("header-menu");const s=null===(e=window.voyager_widget_setting)||void 0===e?void 0:e.search_setting;const a=null===(t=window.voyager_widget_setting)||void 0===t?void 0:t.header_position;if(!n||!s||"none"===s||"menu"!==a||n.querySelector(".voyager-header__menu-item-custom"))return;n.insertAdjacentHTML("beforeend",`<li class="voyager-header__menu-item voyager-header__menu-item-level-0 voyager-header__menu-item-custom">\n <div class="voyager-header__menu-item-container">\n <div class="voyager-search voyager-search--${s}"></div>\n </div>\n </li>`)}class VoyagerSearch{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.options=Object.assign({containerSelector:".voyager-search",apiEndpoint:"/wp-json/custom/v1/search",debounceDelay:100,minChars:2,maxResults:10,shortcutKey:"k"},e);this.containers=document.querySelectorAll(this.options.containerSelector);if(!this.containers.length)return;this.activeDropdownIndex=-1;this.abortController=null;this.debounceTimer=null;this.init()}init(){this.containers.forEach(e=>{const t=this.getVariation(e);switch(t){case"dropdown":this.initDropdown(e);break;case"popup":this.initPopup(e);break;case"minimal":this.initPopup(e,true);break}});this.bindGlobalShortcut()}getVariation(e){if(e.classList.contains("voyager-search--dropdown"))return"dropdown";if(e.classList.contains("voyager-search--minimal"))return"minimal";if(e.classList.contains("voyager-search--popup"))return"popup";return"dropdown"}icon(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:false;const s=n?" voyager-search__icon--light":"";return`<img src="${t}/assets/img/icons/${e}.svg" class="voyager-search__icon${s}" alt="" aria-hidden="true" width="18" height="18">`}initDropdown(e){const t=this.generateId("dropdown");const n=this.getShortcutLabel();e.innerHTML=`\n <div class="voyager-search__input-wrapper" role="combobox" aria-expanded="false" aria-haspopup="listbox" aria-owns="${t}-listbox">\n <label for="${t}-input" class="screen-reader-text">Search</label>\n <input\n type="search"\n id="${t}-input"\n class="voyager-search__input js-voyager-search__input"\n placeholder="Searchâ¦"\n autocomplete="off"\n aria-autocomplete="list"\n aria-controls="${t}-listbox"\n aria-activedescendant=""\n />\n <span class="voyager-search__shortcut-hint" aria-hidden="true">\n <kbd class="voyager-search__kbd">${n}</kbd>\n <kbd class="voyager-search__kbd">K</kbd>\n </span>\n <button\n type="button"\n class="voyager-search__button voyager-search__button--clear js-voyager-search__clear"\n aria-label="Clear search"\n hidden\n >\n <span class="voyager-search__button-icon">${this.icon("close")}</span>\n </button>\n </div>\n <div\n id="${t}-listbox" \n class="voyager-search__dropdown js-voyager-search__dropdown" \n role="listbox" \n aria-label="Search results" \n data-floating="bottom-start" \n data-lenis-prevent\n ></div>\n <div class="screen-reader-text js-voyager-search__live-region" role="status" aria-live="polite" aria-atomic="true"></div>\n `;const s=e.querySelector(".js-voyager-search__input");const a=e.querySelector(".js-voyager-search__dropdown");const r=e.querySelector(".js-voyager-search__clear");const o=e.querySelector("[role='combobox']");const i=e.querySelector(".js-voyager-search__live-region");this.setupFloatingDropdown(a,e.querySelector(".voyager-search__input-wrapper"));const c=e.dataset.postType||"";s.addEventListener("input",()=>{this.handleDropdownInput(s,a,r,o,i,c);const t=e.querySelector(".voyager-search__shortcut-hint");if(t)t.style.display=s.value.length?"none":""});s.addEventListener("keydown",e=>{this.handleDropdownKeydown(e,s,a,o)});r.addEventListener("click",()=>{s.value="";r.hidden=true;this.hideDropdown(a,o);s.focus();i.textContent="";const t=e.querySelector(".voyager-search__shortcut-hint");if(t)t.style.display=""});document.addEventListener("click",t=>{if(!e.contains(t.target))this.hideDropdown(a,o)});e._searchInput=s}setupFloatingDropdown(e,t){if("undefined"!==typeof FloatingUI)FloatingUI.setupFloatingExter
1nal(e,{floating:"bottom-start",floatingRef:null});if(t){const n=new ResizeObserver(()=>{e.style.width=`${t.offsetWidth}px`});n.observe(t)}}handleDropdownInput(e,t,n,s,a){let r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"";const o=e.value.trim();n.hidden=0===o.length;if(o.length<this.options.minChars){this.hideDropdown(t,s);this.activeDropdownIndex=-1;a.textContent="";return}this.showDropdown(t,s);t.innerHTML=`<div class="voyager-search__status" role="status"><span class="voyager-search__spinner" aria-hidden="true"></span> Searchingâ¦</div>`;this.debouncedSearch(o,e=>{this.renderDropdownResults(e,t,o,a)},r)}handleDropdownKeydown(e,t,n,s){const a=n.querySelectorAll(".voyager-search__result-link");if(!a.length&&"Escape"!==e.key)return;switch(e.key){case"ArrowDown":e.preventDefault();this.activeDropdownIndex=Math.min(this.activeDropdownIndex+1,a.length-1);this.updateActiveDescendant(a,t,s);break;case"ArrowUp":e.preventDefault();this.activeDropdownIndex=Math.max(this.activeDropdownIndex-1,-1);this.updateActiveDescendant(a,t,s);if(-1===this.activeDropdownIndex)t.focus();break;case"Enter":if(this.activeDropdownIndex>=0&&a[this.activeDropdownIndex]){e.preventDefault();a[this.activeDropdownIndex].click()}break;case"Escape":this.hideDropdown(n,s);this.activeDropdownIndex=-1;t.focus();break}}updateActiveDescendant(e,t,n){e.forEach((e,n)=>{const s=n===this.activeDropdownIndex;e.setAttribute("aria-selected",s);if(s){t.setAttribute("aria-activedescendant",e.id);e.scrollIntoView({block:"nearest"})}});if(-1===this.activeDropdownIndex)t.setAttribute("aria-activedescendant","")}renderDropdownResults(e,t,n,s){this.activeDropdownIndex=-1;if(!e||!e.length){t.innerHTML=`<div class="voyager-search__status">No results found for "<strong>${this.escapeHtml(n)}</strong>"</div>`;s.textContent="No results found.";return}const a=t.id;const r=`\n <ul class="voyager-search__results-list" role="listbox" id="${a}">\n ${e.map((e,t)=>`\n <li class="voyager-search__result-item" role="option" id="${a}-option-${t}">\n <a href="${this.escapeHtml(e.url||e.link||"#")}"\n class="voyager-search__result-link"\n aria-selected="false"\n id="${a}-link-${t}"\n tabindex="-1">\n <span class="voyager-search__result-title">${this.highlightMatch(e.title,n)}</span>\n ${e.excerpt?`<span class="voyager-search__result-excerpt">${this.escapeHtml(e.excerpt)}</span>`:""}\n </a>\n </li>\n `).join("")}\n </ul>\n `;t.innerHTML=r;s.textContent=`${e.length} result${1!==e.length?"s":""} found.`}showDropdown(e,t){e.classList.add("is-visible");if(t)t.setAttribute("aria-expanded","true")}hideDropdown(e,t){e.classList.remove("is-visible");if(t)t.setAttribute("aria-expanded","false")}initPopup(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:false;const n=this.generateId("popup");const s=t?"voyager-search__button voyager-search__button--minimal":"voyager-search__button";e.innerHTML=`\n <button\n type="button"\n class="${s} js-voyager-search__popup-trigger"\n aria-label="Open search"\n aria-haspopup="dialog"\n >\n <span class="voyager-search__button-icon">${this.icon("search",true)}</span>\n ${!t?" Search":""}\n </button>\n `;const a=document.createElement("div");a.className="voyager-search__overlay js-voyager-search__overlay";a.id=`${n}-overlay`;a.setAttribute("role","dialog");a.setAttribute("aria-modal","true");a.setAttribute("aria-label","Search");a.innerHTML=`\n <div class="voyager-search__popup">\n <div class="voyager-search__popup-header">\n <div class="voyager-search__input-wrapper" style="flex: 1;">\n <label for="${n}-input" class="screen-reader-text">Search</label>\n <input\n type="search"\n id="${n}-input"\n class="voyager-search__input js-voyager-search__popup-input"\n placeholder="Searchâ¦"\n autocomplete="off"\n aria-label="Search"\n />\n <button\n type="button"\n class="voyager-search__button voyager-search__button--clear js-voyager-search__popup-clear"\n aria-label="Clear search"\n hidden\n >
1\n <span class="voyager-search__button-icon">${this.icon("close")}</span>\n </button>\n </div>\n <button\n type="button"\n class="voyager-search__popup-close js-voyager-search__popup-close"\n aria-label="Close search"\n >\n <span class="voyager-search__button-icon">${this.icon("close")}</span>\n </button>\n </div>\n <div class="voyager-search__popup-body js-voyager-search__popup-body">\n <div class="voyager-search__status">Type to searchâ¦</div>\n </div>\n </div>\n <div class="screen-reader-text js-voyager-search__live-region" role="status" aria-live="polite" aria-atomic="true"></div>\n `;document.body.appendChild(a);const r=e.querySelector(".js-voyager-search__popup-trigger");const o=a.querySelector(".js-voyager-search__popup-close");const i=a.querySelector(".js-voyager-search__popup-input");const c=a.querySelector(".js-voyager-search__popup-body");const l=a.querySelector(".js-voyager-search__popup-clear");const d=a.querySelector(".js-voyager-search__live-region");e._searchOverlay=a;e._searchInput=i;r.addEventListener("click",()=>{this.openPopup(a,i,r)});o.addEventListener("click",()=>{this.closePopup(a,r)});a.addEventListener("click",e=>{if(e.target===a)this.closePopup(a,r)});a.addEventListener("keydown",e=>{if("Escape"===e.key)this.closePopup(a,r);this.trapFocus(e,a)});const p=e.dataset.postType||"";i.addEventListener("input",()=>{this.handlePopupInput(i,c,l,d,p)});l.addEventListener("click",()=>{i.value="";l.hidden=true;c.innerHTML=`<div class="voyager-search__status">Type to searchâ¦</div>`;i.focus();d.textContent=""})}openPopup(e,t,n){e.classList.add("is-visible");document.body.style.overflow="hidden";this._lastFocusedElement=n;requestAnimationFrame(()=>{t.focus()})}closePopup(e,t){e.classList.remove("is-visible");document.body.style.overflow="";if(this._lastFocusedElement)this._lastFocusedElement.focus()}trapFocus(e,t){if("Tab"!==e.key)return;const n=t.querySelectorAll('input, button, [tabindex]:not([tabindex="-1"]), a[href]');if(!n.length)return;const s=n[0];const a=n[n.length-1];if(e.shiftKey&&document.activeElement===s){e.preventDefault();a.focus()}else if(!e.shiftKey&&document.activeElement===a){e.preventDefault();s.focus()}}handlePopupInput(e,t,n,s){let a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"";const r=e.value.trim();n.hidden=0===r.length;if(r.length<this.options.minChars){t.innerHTML=`<div class="voyager-search__status">Type to searchâ¦</div>`;s.textContent="";return}t.innerHTML=`<div class="voyager-search__status" role="status"><span class="voyager-search__spinner" aria-hidden="true"></span> Searchingâ¦</div>`;this.debouncedSearch(r,e=>{this.renderPopupResults(e,t,r,s)},a)}renderPopupResults(e,t,n,s){if(!e||!e.length){t.innerHTML=`<div class="voyager-search__status">No results found for "<strong>${this.escapeHtml(n)}</strong>"</div>`;s.textContent="No results found.";return}const a=`\n <ul class="voyager-search__popup-results">\n ${e.map(e=>`\n <li class="voyager-search__popup-result-item">\n <a href="${this.escapeHtml(e.url||e.link||"#")}"\n class="voyager-search__popup-result-link">\n ${e.featured_image?`\n <span class="voyager-search__popup-result-thumb" aria-hidden="true">\n <img src="${this.escapeHtml(e.featured_image)}" class="voyager-search__thumb-img" alt="" loading="lazy">\n </span>\n `:""}\n <span class="voyager-search__popup-result-content">\n <span class="voyager-search__popup-result-title">${this.highlightMatch(e.title,n)}</span>\n ${e.excerpt?`<span class="voyager-search__popup-result-excerpt">${this.escapeHtml(e.excerpt)}</span>`:""}\n </span>\n </a>\n </li>\n `).join("")}\n </ul>\n `;t.innerHTML=a;s.textContent=`${e.length} result${1!==e.length?"s":""} found.`}bindGlobalShortcut(){document.addEventListener("keydown",e=>{const t=this._isMac();const n=t?e.metaKey:e.ctrlKey;if(n&&e.key.toLowerCase()===this.options.shortcutKey){e.preventDefault();this.activateSearch()}})}activateSearch(){const e=document.querySelector(".voyager-search--popup, .voyager-search--minimal");if(e){const t=e._searchOverlay;const n=e._searchInput;const s=e.querySelector(".js-voyager-search__popup-trigger");if(t&&!t.classList.contains("is-visible"))this.openPopup(t,n,s);else if(n){n.focus();n.select()}return}const t=document.querySelector(".voyager-search--dropdown");
1if(t&&t._searchInput){t._searchInput.focus();t._searchInput.select()}}debouncedSearch(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";clearTimeout(this.debounceTimer);if(this.abortController)this.abortController.abort();this.debounceTimer=setTimeout(()=>{this.fetchResults(e,t,n)},this.options.debounceDelay)}async fetchResults(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";this.abortController=new AbortController;try{let s=`${this.options.apiEndpoint}?keyword=${encodeURIComponent(e)}`;if(n)s+=`&post_type=${encodeURIComponent(n)}`;const a=await fetch(s,{signal:this.abortController.signal,headers:{Accept:"application/json"}});if(!a.ok){t([]);return}const r=await a.json();const o=Array.isArray(r)?r:r.results||r.data||[];t(o.slice(0,this.options.maxResults))}catch(e){if("AbortError"!==e.name){console.error("VoyagerSearch: Fetch error",e);t([])}}}highlightMatch(e,t){if(!e)return"";const n=this.escapeHtml(e);const s=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");const a=new RegExp(`(${s})`,"gi");return n.replace(a,"<mark>$1</mark>")}escapeHtml(e){if(!e)return"";const t=document.createElement("div");t.appendChild(document.createTextNode(e));return t.innerHTML}_isMac(){var e;if(null!==(e=navigator.userAgentData)&&void 0!==e&&e.platform)return"macOS"===navigator.userAgentData.platform;return/Mac/i.test(navigator.userAgent)}generateId(e){return`voyager-search-${e}-${Math.random().toString(36).slice(2,9)}`}getShortcutLabel(){const e=this._isMac();return e?"â":"Ctrl"}}window.addEventListener("DOMContentLoaded",()=>{appendHeaderMenuItem();new VoyagerSearch})})();
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.