@smilodon/core 1.3.12 → 1.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.min.js CHANGED
@@ -1,2 +1,2 @@
1
- const createRendererHelpers=e=>({onSelect:e,getIndex:e=>{const t=e?.closest?.("[data-selectable]");if(!t)return null;const n=Number(t.dataset.index);return Number.isFinite(n)?n:null},keyboardFocus:e=>{const t=document.querySelector(`[data-selectable][data-index="${e}"]`);t?.focus?.()}});function renderTemplate(e,t,n){const s=document.createDocumentFragment();for(let e=0;e<t.length;e++){const i=t[e],o=document.createElement("div");o.innerHTML=n(i,e);let r=o.firstElementChild;if(!r){const t=document.createElement("div");for(t.setAttribute("data-selectable",""),t.setAttribute("data-index",String(e));o.firstChild;)t.appendChild(o.firstChild);s.appendChild(t);continue}r.hasAttribute("data-smilodon-handled")||(r.setAttribute("data-selectable",""),r.setAttribute("data-index",String(e))),s.appendChild(r)}e.replaceChildren(s)}class FenwickTree{constructor(e){this.size=e,this.tree=new Float64Array(e+1)}add(e,t){let n=e+1;for(;n<=this.size;)this.tree[n]+=t,n+=n&-n}sum(e){if(e<0)return 0;let t=e+1,n=0;for(;t>0;)n+=this.tree[t],t-=t&-t;return n}rangeSum(e,t){return e>t?0:this.sum(t)-(e>0?this.sum(e-1):0)}update(e,t,n){this.add(e,n-t)}lowerBound(e){if(e<=0)return 0;let t=0,n=0,s=1<<Math.floor(Math.log2(this.size));for(;s>0;){if(t+s<=this.size){const i=n+this.tree[t+s];i<e&&(t+=s,n=i)}s>>=1}return t}reset(){this.tree.fill(0)}resize(e){if(e===this.size)return;const t=this.tree,n=this.size;this.size=e,this.tree=new Float64Array(e+1);const s=Math.min(n,e);for(let e=1;e<=s;e++)this.tree[e]=t[e]}getSize(){return this.size}exportState(){return{size:this.size,tree:Array.from(this.tree)}}static fromState(e){const t=new FenwickTree(e.size);return t.tree=new Float64Array(e.tree),t}}class DOMPool{constructor(e){this.pool=[],this.hits=0,this.misses=0,this.evictions=0,this.factory=e.factory,this.reset=e.reset||this.defaultReset.bind(this),this.maxSize=e.maxSize||64,this.telemetry=e.telemetry||!1}acquire(){const e=performance.now();for(let t=0;t<this.pool.length;t++){const n=this.pool[t];if(!n.inUse)return n.inUse=!0,n.lastUsed=e,this.reset(n.node),this.telemetry&&this.hits++,n.node}const t=this.factory();return this.pool.push({node:t,lastUsed:e,inUse:!0}),this.telemetry&&this.misses++,this.pool.length>this.maxSize&&this.evictLRU(),t}release(e){const t=this.pool.find(t=>t.node===e);t&&(t.inUse=!1,t.lastUsed=performance.now(),this.reset(t.node))}evictLRU(){let e=-1,t=1/0;for(let n=0;n<this.pool.length;n++){const s=this.pool[n];!s.inUse&&s.lastUsed<t&&(e=n,t=s.lastUsed)}if(e>=0){const t=this.pool.splice(e,1)[0];this.deepCleanup(t.node),this.telemetry&&this.evictions++}}defaultReset(e){e.textContent="",e.removeAttribute("style");const t=Array.from(e.attributes);for(const n of t)n.name.startsWith("data-")&&"data-index"!==n.name&&"data-selectable"!==n.name&&e.removeAttribute(n.name);["aria-selected","aria-checked","aria-disabled"].forEach(t=>e.removeAttribute(t))}deepCleanup(e){const t=e.cloneNode(!0);e.parentNode?.replaceChild(t,e),e.textContent=""}clear(){for(const e of this.pool)this.deepCleanup(e.node);this.pool=[],this.resetTelemetry()}setMaxSize(e){for(this.maxSize=e;this.pool.length>this.maxSize;)this.evictLRU()}getStats(){const e=this.pool.filter(e=>!e.inUse).length,t=this.hits+this.misses>0?this.hits/(this.hits+this.misses):0;return{total:this.pool.length,available:e,inUse:this.pool.length-e,maxSize:this.maxSize,hits:this.hits,misses:this.misses,evictions:this.evictions,hitRate:t}}resetTelemetry(){this.hits=0,this.misses=0,this.evictions=0}}class Virtualizer{constructor(e,t,n,s){this.measuredHeights=new Map,this.activeNodes=new Map,this.container=e,this.itemsLength=t,this.itemGetter=n,this.options=s,this.averageHeight=s.estimatedItemHeight;const i=Math.ceil(1.5*(2*s.buffer+10))+(s.maxPoolExtra??32);if(this.pool=new DOMPool({maxSize:i,factory:()=>{const e=document.createElement("div");return e.setAttribute("data-selectable",""),e},reset:e=>{e.textContent="",e.removeAttribute("style"),e.removeAttribute("aria-selected"),e.removeAttribute("aria-checked")},telemetry:s.enableTelemetry||!1}),t>5e3){this.fenwick=new FenwickTree(t);for(let e=0;e<t;e++)this.fenwick.add(e,s.estimatedItemHeight)}this.container.style.willChange="transform"}computeWindow(e,t){const{buffer:n}=this.options,s=Math.max(Math.floor(e/this.averageHeight)-n,0),i=Math.min(Math.ceil((e+t)/this.averageHeight)+n,this.itemsLength-1),o=Math.max(0,i-s+1),r=o+(this.options.maxPoolExtra??32);return this.pool.setMaxSize(r),{startIndex:s,endIndex:i,windowSize:o}}cumulativeOffset(e){if(e<=0)return 0;if(this.fenwick)return this.fenwick.sum(e-1);let t=0;for(let n=0;n<e;n++)t+=this.measuredHeights.get(n)??this.averageHeight;return t}acquireNode(e){const t=this.activeNodes.get(e);if(t)return t;const n=this.pool.acquire();return n.setAttribute("data-index",String(e)),this.activeNodes.set(e,n),n}releaseNode(e){const t=this.activeNodes.get(e);t&&(this.pool.release(t),this.activeNodes.delete(e))}releaseExcess(e){for(const[t,n]of this.activeNodes)e.has(t)||(this.pool.release(n),this.activeNodes.delete(t))}render(e,t,n){const s=document.createDocumentFragment(),i=new Set;for(let o=e;o<=t;o++){const e=this.acquireNode(o);n(e,this.itemGetter(o),o),s.appendChild(e),i.add(o),queueMicrotask(()=>this.measureOnAppear(e,o))}const o=this.cumulativeOffset(e);this.container.style.transform=`translate3d(0, ${Math.round(100*o)/100}px, 0)`,this.container.replaceChildren(s),requestAnimationFrame(()=>this.releaseExcess(i))}measureOnAppear(e,t){const n=e.offsetHeight,s=this.measuredHeights.get(t),i=this.options.measurementThreshold??5;if(void 0===s||Math.abs(s-n)>i){const e=s??this.averageHeight;this.measuredHeights.set(t,n),this.fenwick&&this.fenwick.update(t,e,n);const i=this.measuredHeights.size,o=Array.from(this.measuredHeights.values()).reduce((e,t)=>e+t,0);this.averageHeight=Math.round(o/i*100)/100}}getPoolStats(){return this.pool.getStats()}setItemsLength(e){if(this.itemsLength=e,this.fenwick)this.fenwick.resize(e);else if(e>5e3&&!this.fenwick){this.fenwick=new FenwickTree(e);for(const[e,t]of this.measuredHeights)this.fenwick.update(e,this.averageHeight,t)}}destroy(){this.pool.clear(),this.activeNodes.clear(),this.measuredHeights.clear(),this.fenwick&&this.fenwick.reset()}}class CustomOptionPool{constructor(e=50){this._pool=new Map,this._activeComponents=new Map,this._maxPoolSize=e}acquire(e,t,n,s,i){const o=this._getFactoryKey(e),r=this._findAvailableComponent(o);let a;if(r)a=r.instance,r.inUse=!0,r.lastUsedIndex=n;else try{a=e(t,n);const s=this._pool.get(o)||[];s.length<this._maxPoolSize&&(s.push({instance:a,inUse:!0,lastUsedIndex:n}),this._pool.set(o,s))}catch(e){throw console.error("[CustomOptionPool] Failed to create component:",e),e}try{a.mountOption(i,s),this._activeComponents.set(n,a)}catch(e){throw console.error(`[CustomOptionPool] Failed to mount component at index ${n}:`,e),e}return a}release(e){const t=this._activeComponents.get(e);if(t){try{t.unmountOption()}catch(t){console.error(`[CustomOptionPool] Failed to unmount component at index ${e}:`,t)}this._activeComponents.delete(e);for(const e of this._pool.values()){const n=e.find(e=>e.instance===t);if(n){n.inUse=!1;break}}}}releaseAll(){Array.from(this._activeComponents.keys()).forEach(e=>this.release(e))}updateSelection(e,t){const n=this._activeComponents.get(e);n&&n.updateSelected(t)}updateFocused(e,t){const n=this._activeComponents.get(e);n&&n.updateFocused&&n.updateFocused(t)}getComponent(e){return this._activeComponents.get(e)}clear(){this.releaseAll(),this._pool.clear()}getStats(){let e=0,t=0;for(const n of this._pool.values())e+=n.length,t+=n.filter(e=>!e.inUse).length;return{totalPooled:e,activeComponents:this._activeComponents.size,availableComponents:t}}_findAvailableComponent(e){const t=this._pool.get(e);if(t)return t.find(e=>!e.inUse)}_getFactoryKey(e){return e.name||`factory_${e.toString().slice(0,50)}`}}class OptionRenderer{constructor(e){this._mountedElements=new Map,this._config=e,this._pool=new CustomOptionPool(e.maxPoolSize)}render(e,t,n,s,i){const o=e,r=this._config.getValue(e),a=this._config.getLabel(e),l=!!this._config.getDisabled&&this._config.getDisabled(e);return o.optionComponent&&"function"==typeof o.optionComponent?this._renderCustomComponent(e,t,r,a,n,s,l,i,o.optionComponent):this._renderLightweightOption(e,t,r,a,n,s,l,i)}updateSelection(e,t){const n=this._mountedElements.get(e);if(!n)return;const s=this._pool.getComponent(e);s?s.updateSelected(t):t?(n.classList.add("selected"),n.setAttribute("aria-selected","true")):(n.classList.remove("selected"),n.setAttribute("aria-selected","false"))}updateFocused(e,t){const n=this._mountedElements.get(e);if(!n)return;const s=this._pool.getComponent(e);s?(s.updateFocused&&s.updateFocused(t),n.classList.toggle("focused",t)):n.classList.toggle("focused",t)}unmount(e){this._pool.release(e),this._mountedElements.delete(e)}unmountAll(){this._pool.releaseAll(),this._mountedElements.clear()}getStats(){return this._pool.getStats()}_renderLightweightOption(e,t,n,s,i,o,r,a){const l=document.createElement("div");return l.className="option",i&&l.classList.add("selected"),o&&l.classList.add("focused"),r&&l.classList.add("disabled"),l.id=`${a}-option-${t}`,l.textContent=s,l.dataset.value=String(n),l.dataset.index=String(t),l.dataset.mode="lightweight",l.setAttribute("role","option"),l.setAttribute("aria-selected",String(i)),r&&l.setAttribute("aria-disabled","true"),r||l.addEventListener("click",()=>{this._config.onSelect(t)}),this._mountedElements.set(t,l),l}_renderCustomComponent(e,t,n,s,i,o,r,a,l){const c=document.createElement("div");c.className="option option-custom",i&&c.classList.add("selected"),o&&c.classList.add("focused"),r&&c.classList.add("disabled"),c.id=`${a}-option-${t}`,c.dataset.value=String(n),c.dataset.index=String(t),c.dataset.mode="component",c.setAttribute("role","option"),c.setAttribute("aria-selected",String(i)),c.setAttribute("aria-label",s),r&&c.setAttribute("aria-disabled","true");const d={item:e,index:t,value:n,label:s,isSelected:i,isFocused:o,isDisabled:r,onSelect:e=>{r||this._config.onSelect(e)},onCustomEvent:(e,n)=>{this._config.onCustomEvent&&this._config.onCustomEvent(t,e,n)}};try{this._pool.acquire(l,e,t,d,c).getElement();r||c.addEventListener("click",e=>{c.contains(e.target)&&this._config.onSelect(t)})}catch(e){console.error(`[OptionRenderer] Failed to render custom component at index ${t}:`,e),c.innerHTML="",c.textContent=s,c.classList.add("component-error"),this._config.onError&&this._config.onError(t,e)}return this._mountedElements.set(t,c),c}}class NativeSelectElement extends HTMLElement{static get observedAttributes(){return["placement","strategy","portal"]}constructor(){super(),this._options={},this._items=[],this._selectedSet=new Set,this._selectedItems=new Map,this._activeIndex=-1,this._multi=!1,this._typeBuffer="",this._shadow=this.attachShadow({mode:"open"}),this._listRoot=document.createElement("div"),this._listRoot.setAttribute("role","listbox"),this._listRoot.setAttribute("tabindex","0"),this._shadow.appendChild(this._listRoot),this._liveRegion=document.createElement("div"),this._liveRegion.setAttribute("role","status"),this._liveRegion.setAttribute("aria-live","polite"),this._liveRegion.style.cssText="position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;",this._shadow.appendChild(this._liveRegion),this._helpers=createRendererHelpers((e,t)=>this._onSelect(e,t)),this._listRoot.addEventListener("click",e=>{const t=e.target.closest("[data-selectable]");if(!t)return;const n=Number(t.dataset.index),s=this._items[n];this._onSelect(s,n)}),this._listRoot.addEventListener("keydown",e=>this._onKeydown(e))}connectedCallback(){this._listRoot.setAttribute("role","listbox"),this._listRoot.setAttribute("aria-label","Options list"),this._multi&&this._listRoot.setAttribute("aria-multiselectable","true"),this._initializeOptionRenderer(),this._emit("open",{})}disconnectedCallback(){this._emit("close",{}),this._unifiedRenderer&&this._unifiedRenderer.unmountAll(),this._typeTimeout&&window.clearTimeout(this._typeTimeout)}_initializeOptionRenderer(){const e={enableRecycling:!0,maxPoolSize:100,getValue:e=>e?.value??e,getLabel:e=>e?.label??String(e),getDisabled:e=>e?.disabled??!1,onSelect:e=>{const t=this._items[e];this._onSelect(t,e)},onCustomEvent:(e,t,n)=>{this.dispatchEvent(new CustomEvent("option:custom-event",{detail:{index:e,eventName:t,data:n},bubbles:!0,composed:!0}))},onError:(e,t)=>{console.error(`[NativeSelect] Error in option ${e}:`,t),this.dispatchEvent(new CustomEvent("option:mount-error",{detail:{index:e,error:t},bubbles:!0,composed:!0}))}};this._unifiedRenderer=new OptionRenderer(e)}attributeChangedCallback(e,t,n){switch(e){case"placement":this._options.placement=n??void 0;break;case"strategy":this._options.strategy=n??void 0;break;case"portal":this._options.portal="true"===n||"false"!==n&&void 0}}set items(e){this._items=e??[],this._virtualizer=new Virtualizer(this._listRoot,this._items.length,e=>this._items[e],{estimatedItemHeight:48,buffer:5}),this.render()}get items(){return this._items}set multi(e){this._multi=e,e?this._listRoot.setAttribute("aria-multiselectable","true"):this._listRoot.removeAttribute("aria-multiselectable")}get multi(){return this._multi}get selectedIndices(){return Array.from(this._selectedSet)}get selectedItems(){return Array.from(this._selectedItems.values())}set optionTemplate(e){this._options.optionTemplate=e,this.render()}set optionRenderer(e){this._options.optionRenderer=e,this.render()}setItems(e){this.items=e??[]}setValue(e){if(null==e||""===e)return this._selectedSet.clear(),this._selectedItems.clear(),this._activeIndex=-1,void this.render();const t=this._items.findIndex(t=>"object"==typeof t&&null!==t&&"value"in t?t.value===e:t===e);if(t>=0){const e=this._items[t];this._multi||(this._selectedSet.clear(),this._selectedItems.clear()),this._selectedSet.add(t),this._selectedItems.set(t,e),this._activeIndex=t,this.render()}}getValue(){const e=Array.from(this._selectedItems.values()).map(e=>"object"==typeof e&&null!==e&&"value"in e?e.value:e);return this._multi?e:e[0]??null}render(){const{optionTemplate:e,optionRenderer:t}=this._options,n=this.getBoundingClientRect().height||300,s=this.scrollTop||0;this._activeIndex>=0?this._listRoot.setAttribute("aria-activedescendant",`option-${this._activeIndex}`):this._listRoot.removeAttribute("aria-activedescendant");if(this._items.some(e=>"object"==typeof e&&null!==e&&Object.prototype.hasOwnProperty.call(e,"optionComponent")&&"function"==typeof e.optionComponent)&&this._unifiedRenderer){this._listRoot.replaceChildren();const e=document.createDocumentFragment();for(let t=0;t<this._items.length;t++){const n=this._items[t],s=this._selectedSet.has(t),i=this._activeIndex===t,o=this._unifiedRenderer.render(n,t,s,i,`native-${this.getAttribute("id")||"default"}`);e.appendChild(o)}return void this._listRoot.appendChild(e)}if(this._virtualizer){const{startIndex:i,endIndex:o}=this._virtualizer.computeWindow(s,n);return void this._virtualizer.render(i,o,(n,s,i)=>{if(this._applyOptionAttrs(n,i),t){const e=t(s,i,this._helpers);n.replaceChildren(e)}else if(e){const t=document.createElement("div");t.innerHTML=e(s,i);const o=t.firstElementChild;n.replaceChildren(o??document.createTextNode(String(s)))}else{const e=String("object"==typeof s&&null!==s&&"label"in s?s.label:s);n.textContent=e}})}const i=document.createDocumentFragment();for(let n=0;n<this._items.length;n++){const s=this._items[n];if(t){const e=t(s,n,this._helpers);e.hasAttribute("data-selectable")||(e.setAttribute("data-selectable",""),e.setAttribute("data-index",String(n))),this._applyOptionAttrs(e,n),i.appendChild(e)}else{if(e)return renderTemplate(this._listRoot,this._items,e),void this._applyAriaToAll();{const e=document.createElement("div"),t=String("object"==typeof s&&null!==s&&"label"in s?s.label:s);e.textContent=t,e.setAttribute("data-selectable",""),e.setAttribute("data-index",String(n)),this._applyOptionAttrs(e,n),i.appendChild(e)}}}this._listRoot.replaceChildren(i)}_applyOptionAttrs(e,t){e.setAttribute("role","option"),e.id=`option-${t}`,this._selectedSet.has(t)?e.setAttribute("aria-selected","true"):e.setAttribute("aria-selected","false")}_applyAriaToAll(){const e=Array.from(this._listRoot.children);for(const t of e){const e=Number(t.dataset.index);Number.isFinite(e)&&this._applyOptionAttrs(t,e)}}_emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0}))}_onSelect(e,t){this._multi?this._selectedSet.has(t)?(this._selectedSet.delete(t),this._selectedItems.delete(t)):(this._selectedSet.add(t),this._selectedItems.set(t,e)):(this._selectedSet.clear(),this._selectedItems.clear(),this._selectedSet.add(t),this._selectedItems.set(t,e)),this._activeIndex=t,this.render();const n=this._selectedSet.has(t),s=e?.value??e,i=e?.label??String(e);this._emit("select",{item:e,index:t,value:s,label:i,selected:n,multi:this._multi}),this._emit("change",{selectedItems:Array.from(this._selectedItems.values()),selectedValues:Array.from(this._selectedItems.values()).map(e=>e?.value??e),selectedIndices:Array.from(this._selectedSet)}),this._announce(`Selected ${i}`)}_onKeydown(e){switch(e.key){case"ArrowDown":e.preventDefault(),this._moveActive(1);break;case"ArrowUp":e.preventDefault(),this._moveActive(-1);break;case"Home":e.preventDefault(),this._setActive(0);break;case"End":e.preventDefault(),this._setActive(this._items.length-1);break;case"PageDown":e.preventDefault(),this._moveActive(10);break;case"PageUp":e.preventDefault(),this._moveActive(-10);break;case"Enter":case" ":if(e.preventDefault(),this._activeIndex>=0){const e=this._items[this._activeIndex];this._onSelect(e,this._activeIndex)}break;case"Escape":e.preventDefault(),this._emit("close",{});break;default:1!==e.key.length||e.ctrlKey||e.altKey||e.metaKey||this._onType(e.key)}}_moveActive(e){const t=Math.max(0,Math.min(this._items.length-1,this._activeIndex+e));this._setActive(t)}_setActive(e){this._activeIndex=e,this.render(),this._scrollToActive(),this._announce(`Navigated to ${String(this._items[e])}`)}_scrollToActive(){const e=this._shadow.getElementById(`option-${this._activeIndex}`);e?.scrollIntoView({block:"nearest",inline:"nearest"})}_onType(e){this._typeTimeout&&window.clearTimeout(this._typeTimeout),this._typeBuffer+=e.toLowerCase(),this._typeTimeout=window.setTimeout(()=>{this._typeBuffer=""},400);const t=this._items.findIndex(e=>String(e).toLowerCase().startsWith(this._typeBuffer));t>=0&&this._setActive(t)}_announce(e){this._liveRegion&&(this._liveRegion.textContent=e,setTimeout(()=>{this._liveRegion&&(this._liveRegion.textContent="")},1e3))}focus(){this._listRoot.focus()}}customElements.define("smilodon-select",NativeSelectElement);const defaultConfig={selection:{mode:"single",allowDeselect:!1,maxSelections:0,showRemoveButton:!0,closeOnSelect:!0},scrollToSelected:{enabled:!0,multiSelectTarget:"first",behavior:"smooth",block:"nearest"},loadMore:{enabled:!1,itemsPerLoad:3,threshold:100,showLoader:!0},busyBucket:{enabled:!0,showSpinner:!0,message:"Loading...",minDisplayTime:200},styles:{classNames:{}},serverSide:{enabled:!1,getValueFromItem:e=>e?.value??e,getLabelFromItem:e=>e?.label??String(e)},infiniteScroll:{enabled:!1,pageSize:20,initialPage:1,cachePages:!0,maxCachedPages:10,preloadAdjacent:!0,scrollRestoration:"auto"},expandable:{enabled:!1,collapsedHeight:"300px",expandedHeight:"500px",expandLabel:"Show more",collapseLabel:"Show less"},callbacks:{},enabled:!0,searchable:!1,placeholder:"Select an option...",virtualize:!0,estimatedItemHeight:48};class SelectConfigManager{constructor(){this.config=this.deepClone(defaultConfig)}getConfig(){return this.config}updateConfig(e){this.config=this.deepMerge(this.config,e)}resetConfig(){this.config=this.deepClone(defaultConfig)}mergeWithComponentConfig(e){return this.deepMerge(this.deepClone(this.config),e)}deepClone(e){return JSON.parse(JSON.stringify(e))}deepMerge(e,t){const n={...e};for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)){const s=t[e],i=n[e];s&&"object"==typeof s&&!Array.isArray(s)?n[e]=this.deepMerge(i&&"object"==typeof i?i:{},s):n[e]=s}return n}}const selectConfig=new SelectConfigManager;function configureSelect(e){selectConfig.updateConfig(e)}function resetSelectConfig(){selectConfig.resetConfig()}class SelectOption extends HTMLElement{constructor(e){super(),this._config=e,this._shadow=this.attachShadow({mode:"open"}),this._container=document.createElement("div"),this._container.className="option-container",this._initializeStyles(),this._render(),this._attachEventListeners(),this._shadow.appendChild(this._container)}_initializeStyles(){const e=document.createElement("style");e.textContent="\n :host {\n display: block;\n position: relative;\n }\n \n .option-container {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n cursor: pointer;\n user-select: none;\n transition: background-color 0.2s ease;\n }\n \n .option-container:hover {\n background-color: var(--select-option-hover-bg, #f0f0f0);\n }\n \n .option-container.selected {\n background-color: var(--select-option-selected-bg, #e3f2fd);\n color: var(--select-option-selected-color, #1976d2);\n }\n \n .option-container.active {\n outline: 2px solid var(--select-option-active-outline, #1976d2);\n outline-offset: -2px;\n }\n \n .option-container.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n \n .option-content {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n \n .remove-button {\n margin-left: 8px;\n padding: 2px 6px;\n border: none;\n background-color: var(--select-remove-btn-bg, transparent);\n color: var(--select-remove-btn-color, #666);\n cursor: pointer;\n border-radius: 3px;\n font-size: 16px;\n line-height: 1;\n transition: all 0.2s ease;\n }\n \n .remove-button:hover {\n background-color: var(--select-remove-btn-hover-bg, #ffebee);\n color: var(--select-remove-btn-hover-color, #c62828);\n }\n \n .remove-button:focus {\n outline: 2px solid var(--select-remove-btn-focus-outline, #1976d2);\n outline-offset: 2px;\n }\n ",this._shadow.appendChild(e)}_render(){const{item:e,index:t,selected:n,disabled:s,active:i,render:o,showRemoveButton:r}=this._config;this._container.innerHTML="",this._container.classList.toggle("selected",n),this._container.classList.toggle("disabled",s||!1),this._container.classList.toggle("active",i||!1),this._config.className&&(this._container.className+=" "+this._config.className),this._config.style&&Object.assign(this._container.style,this._config.style);const a=document.createElement("div");if(a.className="option-content",o){const n=o(e,t);"string"==typeof n?a.innerHTML=n:a.appendChild(n)}else{const e=this._getLabel();a.textContent=e}this._container.appendChild(a),r&&n&&(this._removeButton=document.createElement("button"),this._removeButton.className="remove-button",this._removeButton.innerHTML="×",this._removeButton.setAttribute("aria-label","Remove option"),this._removeButton.setAttribute("type","button"),this._container.appendChild(this._removeButton)),this.setAttribute("role","option"),this.setAttribute("aria-selected",String(n)),s&&this.setAttribute("aria-disabled","true"),this.id=this._config.id||`select-option-${t}`}_attachEventListeners(){this._container.addEventListener("click",e=>{e.target!==this._removeButton&&(this._config.disabled||this._handleSelect())}),this._removeButton&&this._removeButton.addEventListener("click",e=>{e.stopPropagation(),this._handleRemove()}),this.addEventListener("keydown",e=>{this._config.disabled||("Enter"===e.key||" "===e.key?(e.preventDefault(),this._handleSelect()):"Delete"!==e.key&&"Backspace"!==e.key||this._config.selected&&this._config.showRemoveButton&&(e.preventDefault(),this._handleRemove()))})}_handleSelect(){const e={item:this._config.item,index:this._config.index,value:this._getValue(),label:this._getLabel(),selected:!this._config.selected};this.dispatchEvent(new CustomEvent("optionSelect",{detail:e,bubbles:!0,composed:!0}))}_handleRemove(){const e={item:this._config.item,index:this._config.index,value:this._getValue(),label:this._getLabel(),selected:!1};this.dispatchEvent(new CustomEvent("optionRemove",{detail:e,bubbles:!0,composed:!0}))}_getValue(){return this._config.getValue?this._config.getValue(this._config.item):this._config.item?.value??this._config.item}_getLabel(){return this._config.getLabel?this._config.getLabel(this._config.item):this._config.item?.label??String(this._config.item)}updateConfig(e){this._config={...this._config,...e},this._render(),this._attachEventListeners()}getConfig(){return this._config}getValue(){return this._getValue()}getLabel(){return this._getLabel()}setSelected(e){this._config.selected=e,this._render()}setActive(e){this._config.active=e,this._render()}setDisabled(e){this._config.disabled=e,this._render()}}customElements.get("select-option")||customElements.define("select-option",SelectOption);class EnhancedSelect extends HTMLElement{constructor(){super(),this._pageCache={},this._typeBuffer="",this._hasError=!1,this._errorMessage="",this._boundArrowClick=null,this._pendingFirstRenderMark=!1,this._pendingSearchRenderMark=!1,this._rangeAnchorIndex=null,this._shadow=this.attachShadow({mode:"open"}),this._uniqueId=`enhanced-select-${Math.random().toString(36).substr(2,9)}`,this._rendererHelpers=this._buildRendererHelpers(),this._config=selectConfig.getConfig(),this._state={isOpen:!1,isBusy:!1,isSearching:!1,currentPage:this._config.infiniteScroll.initialPage||1,totalPages:1,selectedIndices:new Set,selectedItems:new Map,activeIndex:-1,searchQuery:"",loadedItems:[],groupedItems:[],preserveScrollPosition:!1,lastScrollPosition:0,lastNotifiedQuery:null,lastNotifiedResultCount:0,isExpanded:!1},this._container=this._createContainer(),this._inputContainer=this._createInputContainer(),this._input=this._createInput(),this._arrowContainer=this._createArrowContainer(),this._dropdown=this._createDropdown(),this._optionsContainer=this._createOptionsContainer(),this._liveRegion=this._createLiveRegion(),this._initializeStyles(),this._assembleDOM(),this._attachEventListeners(),this._initializeObservers()}connectedCallback(){this.style.display="block",this.style.width="100%",this._config.serverSide.enabled&&this._config.serverSide.initialSelectedValues&&this._loadInitialSelectedItems(),this._config.callbacks.onOpen&&this._config.callbacks.onOpen()}disconnectedCallback(){this._resizeObserver?.disconnect(),this._intersectionObserver?.disconnect(),this._busyTimeout&&clearTimeout(this._busyTimeout),this._typeTimeout&&clearTimeout(this._typeTimeout),this._searchTimeout&&clearTimeout(this._searchTimeout),this._boundArrowClick&&this._arrowContainer&&this._arrowContainer.removeEventListener("click",this._boundArrowClick)}_createContainer(){const e=document.createElement("div");return e.className="select-container",this._config.styles.classNames?.container&&(e.className+=" "+this._config.styles.classNames.container),this._config.styles.container&&Object.assign(e.style,this._config.styles.container),e}_createInputContainer(){const e=document.createElement("div");return e.className="input-container",e}_createInput(){const e=document.createElement("input");return e.type="text",e.className="select-input",e.id=`${this._uniqueId}-input`,e.placeholder=this._config.placeholder||"Select an option...",e.disabled=!this._config.enabled,e.readOnly=!this._config.searchable,e.addEventListener("focus",()=>{this._config.searchable&&(e.readOnly=!1)}),this._config.styles.classNames?.input&&(e.className+=" "+this._config.styles.classNames.input),this._config.styles.input&&Object.assign(e.style,this._config.styles.input),e.setAttribute("role","combobox"),e.setAttribute("aria-expanded","false"),e.setAttribute("aria-haspopup","listbox"),e.setAttribute("aria-autocomplete",this._config.searchable?"list":"none"),e}_createDropdown(){const e=document.createElement("div");return e.className="select-dropdown",e.style.display="none",this._config.styles.classNames?.dropdown&&(e.className+=" "+this._config.styles.classNames.dropdown),this._config.styles.dropdown&&Object.assign(e.style,this._config.styles.dropdown),e.setAttribute("role","listbox"),e.setAttribute("aria-labelledby",`${this._uniqueId}-input`),"multi"===this._config.selection.mode&&e.setAttribute("aria-multiselectable","true"),e}_createOptionsContainer(){const e=document.createElement("div");return e.className="options-container",e}_createLiveRegion(){const e=document.createElement("div");return e.setAttribute("role","status"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),e.style.cssText="position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;",e}_createArrowContainer(){const e=document.createElement("div");return e.className="dropdown-arrow-container",e.innerHTML='\n <svg class="dropdown-arrow" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ',e}_assembleDOM(){this._inputContainer.appendChild(this._input),this._arrowContainer&&this._inputContainer.appendChild(this._arrowContainer),this._container.appendChild(this._inputContainer),this._dropdown.appendChild(this._optionsContainer),this._container.appendChild(this._dropdown),this._shadow.appendChild(this._container),this._liveRegion&&this._shadow.appendChild(this._liveRegion);const e=`${this._uniqueId}-listbox`;this._dropdown.id=e,this._input.setAttribute("aria-controls",e),this._input.setAttribute("aria-owns",e)}_initializeStyles(){const e=document.createElement("style");e.textContent='\n :host {\n display: block;\n position: relative;\n width: 100%;\n }\n \n .select-container {\n position: relative;\n width: 100%;\n }\n \n .input-container {\n position: relative;\n width: 100%;\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--select-input-gap, 6px);\n padding: var(--select-input-padding, 6px 52px 6px 8px);\n min-height: var(--select-input-min-height, 44px);\n max-height: var(--select-input-max-height, 160px);\n overflow-y: var(--select-input-overflow-y, auto);\n align-content: flex-start;\n background: var(--select-input-bg, white);\n border: var(--select-input-border, 1px solid #d1d5db);\n border-radius: var(--select-input-border-radius, 6px);\n box-sizing: border-box;\n transition: all 0.2s ease;\n }\n \n .input-container:focus-within {\n border-color: var(--select-input-focus-border, #667eea);\n box-shadow: var(--select-input-focus-shadow, 0 0 0 3px rgba(102, 126, 234, 0.1));\n }\n \n /* Gradient separator before arrow */\n .input-container::after {\n content: \'\';\n position: absolute;\n top: 50%;\n right: var(--select-separator-position, 40px);\n transform: translateY(-50%);\n width: var(--select-separator-width, 1px);\n height: var(--select-separator-height, 60%);\n background: var(--select-separator-bg, var(--select-separator-gradient, linear-gradient(\n to bottom,\n transparent 0%,\n rgba(0, 0, 0, 0.1) 20%,\n rgba(0, 0, 0, 0.1) 80%,\n transparent 100%\n )));\n pointer-events: none;\n z-index: 1;\n }\n \n .dropdown-arrow-container {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: var(--select-arrow-width, 40px);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: background-color 0.2s ease;\n border-radius: var(--select-arrow-border-radius, 0 4px 4px 0);\n z-index: 2;\n }\n \n .dropdown-arrow-container:hover {\n background-color: var(--select-arrow-hover-bg, rgba(102, 126, 234, 0.08));\n }\n \n .dropdown-arrow {\n width: var(--select-arrow-size, 16px);\n height: var(--select-arrow-size, 16px);\n color: var(--select-arrow-color, #667eea);\n transition: transform 0.2s ease, color 0.2s ease;\n transform: translateY(0);\n }\n \n .dropdown-arrow path {\n stroke-width: var(--select-arrow-stroke-width, 2);\n }\n \n .dropdown-arrow-container:hover .dropdown-arrow {\n color: var(--select-arrow-hover-color, #667eea);\n }\n \n .dropdown-arrow.open {\n transform: rotate(180deg);\n }\n \n .select-input {\n flex: 1;\n min-width: var(--select-input-min-width, 120px);\n padding: var(--select-input-field-padding, 4px);\n border: none;\n font-size: var(--select-input-font-size, 14px);\n line-height: var(--select-input-line-height, 1.5);\n color: var(--select-input-color, #1f2937);\n background: transparent;\n box-sizing: border-box;\n outline: none;\n font-family: var(--select-font-family, inherit);\n }\n \n .select-input::placeholder {\n color: var(--select-input-placeholder-color, #9ca3af);\n }\n \n .selection-badge {\n display: inline-flex;\n align-items: center;\n gap: var(--select-badge-gap, 4px);\n padding: var(--select-badge-padding, 4px 8px);\n margin: var(--select-badge-margin, 2px);\n background: var(--select-badge-bg, #667eea);\n color: var(--select-badge-color, white);\n border-radius: var(--select-badge-border-radius, 4px);\n font-size: var(--select-badge-font-size, 13px);\n line-height: 1;\n max-width: var(--select-badge-max-width, 100%);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n \n .badge-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--select-badge-remove-size, 16px);\n height: var(--select-badge-remove-size, 16px);\n padding: 0;\n margin-left: 4px;\n background: var(--select-badge-remove-bg, rgba(255, 255, 255, 0.3));\n border: none;\n border-radius: 50%;\n color: var(--select-badge-remove-color, white);\n font-size: var(--select-badge-remove-font-size, 16px);\n line-height: 1;\n cursor: pointer;\n transition: background 0.2s;\n }\n \n .badge-remove:hover {\n background: var(--select-badge-remove-hover-bg, rgba(255, 255, 255, 0.5));\n }\n\n .badge-remove:focus-visible {\n outline: 2px solid var(--select-badge-remove-focus-outline, rgba(255, 255, 255, 0.8));\n outline-offset: 2px;\n }\n \n .select-input:disabled {\n background-color: var(--select-disabled-bg, #f5f5f5);\n cursor: not-allowed;\n }\n \n .select-dropdown {\n position: absolute;\n scroll-behavior: smooth;\n top: 100%;\n left: 0;\n right: 0;\n margin-top: var(--select-dropdown-margin-top, 4px);\n max-height: var(--select-dropdown-max-height, 300px);\n overflow: hidden;\n background: var(--select-dropdown-bg, white);\n border: var(--select-dropdown-border, 1px solid #ccc);\n border-radius: var(--select-dropdown-border-radius, 4px);\n box-shadow: var(--select-dropdown-shadow, 0 4px 6px rgba(0,0,0,0.1));\n z-index: var(--select-dropdown-z-index, 1000);\n }\n \n .options-container {\n position: relative;\n max-height: var(--select-options-max-height, 300px);\n overflow: auto;\n transition: opacity 0.2s ease-in-out;\n background: var(--select-options-bg, white);\n }\n\n .option {\n padding: var(--select-option-padding, 8px 12px);\n cursor: pointer;\n color: var(--select-option-color, #1f2937);\n background: var(--select-option-bg, white);\n transition: var(--select-option-transition, background-color 0.15s ease);\n user-select: none;\n font-size: var(--select-option-font-size, 14px);\n line-height: var(--select-option-line-height, 1.5);\n border: var(--select-option-border, none);\n border-bottom: var(--select-option-border-bottom, none);\n }\n\n .option:hover {\n background-color: var(--select-option-hover-bg, #f3f4f6);\n color: var(--select-option-hover-color, #1f2937);\n }\n\n .option.selected {\n background-color: var(--select-option-selected-bg, #e0e7ff);\n color: var(--select-option-selected-color, #4338ca);\n font-weight: var(--select-option-selected-weight, 500);\n }\n\n .option.active {\n background-color: var(--select-option-active-bg, #f3f4f6);\n color: var(--select-option-active-color, #1f2937);\n outline: var(--select-option-active-outline, 2px solid rgba(99, 102, 241, 0.45));\n outline-offset: -2px;\n }\n\n .option:active {\n background-color: var(--select-option-pressed-bg, #e5e7eb);\n }\n \n .load-more-container {\n padding: var(--select-load-more-padding, 12px);\n text-align: center;\n border-top: var(--select-divider-border, 1px solid #e0e0e0);\n background: var(--select-load-more-bg, white);\n }\n \n .load-more-button {\n padding: var(--select-button-padding, 8px 16px);\n border: var(--select-button-border, 1px solid #1976d2);\n background: var(--select-button-bg, white);\n color: var(--select-button-color, #1976d2);\n border-radius: var(--select-button-border-radius, 4px);\n cursor: pointer;\n font-size: var(--select-button-font-size, 14px);\n font-family: var(--select-font-family, inherit);\n transition: all 0.2s ease;\n }\n \n .load-more-button:hover {\n background: var(--select-button-hover-bg, #1976d2);\n color: var(--select-button-hover-color, white);\n }\n \n .load-more-button:disabled {\n opacity: var(--select-button-disabled-opacity, 0.5);\n cursor: not-allowed;\n }\n \n .busy-bucket {\n padding: var(--select-busy-padding, 16px);\n text-align: center;\n color: var(--select-busy-color, #666);\n background: var(--select-busy-bg, white);\n font-size: var(--select-busy-font-size, 14px);\n }\n \n .spinner {\n display: inline-block;\n width: var(--select-spinner-size, 20px);\n height: var(--select-spinner-size, 20px);\n border: var(--select-spinner-border, 2px solid #ccc);\n border-top-color: var(--select-spinner-active-color, #1976d2);\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n }\n \n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n \n .empty-state {\n padding: var(--select-empty-padding, 24px);\n text-align: center;\n color: var(--select-empty-color, #6b7280);\n font-size: var(--select-empty-font-size, 14px);\n background: var(--select-empty-bg, white);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 6px;\n min-height: var(--select-empty-min-height, 72px);\n }\n \n .searching-state {\n padding: var(--select-searching-padding, 24px);\n text-align: center;\n color: var(--select-searching-color, #667eea);\n font-size: var(--select-searching-font-size, 14px);\n font-style: italic;\n background: var(--select-searching-bg, white);\n animation: pulse 1.5s ease-in-out infinite;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 6px;\n min-height: var(--select-searching-min-height, 72px);\n }\n \n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n \n /* Error states */\n .select-input[aria-invalid="true"] {\n border-color: var(--select-error-border, #dc2626);\n }\n \n .select-input[aria-invalid="true"]:focus {\n border-color: var(--select-error-border, #dc2626);\n box-shadow: 0 0 0 2px var(--select-error-shadow, rgba(220, 38, 38, 0.1));\n outline-color: var(--select-error-border, #dc2626);\n }\n \n /* Accessibility: Reduced motion */\n @media (prefers-reduced-motion: reduce) {\n * {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n }\n \n /* Dark mode - Opt-in via class or data attribute */\n :host(.dark-mode),\n :host([data-theme="dark"]) {\n .input-container {\n background: var(--select-dark-bg, #1f2937);\n border-color: var(--select-dark-border, #4b5563);\n }\n \n .select-input {\n color: var(--select-dark-text, #f9fafb);\n }\n \n .select-input::placeholder {\n color: var(--select-dark-placeholder, #6b7280);\n }\n \n .select-dropdown {\n background: var(--select-dark-dropdown-bg, #1f2937);\n border-color: var(--select-dark-dropdown-border, #4b5563);\n }\n \n .options-container {\n background: var(--select-dark-options-bg, #1f2937);\n }\n \n .option {\n color: var(--select-dark-option-color, #f9fafb);\n background: var(--select-dark-option-bg, #1f2937);\n }\n \n .option:hover {\n background-color: var(--select-dark-option-hover-bg, #374151);\n color: var(--select-dark-option-hover-color, #f9fafb);\n }\n \n .option.selected {\n background-color: var(--select-dark-option-selected-bg, #3730a3);\n color: var(--select-dark-option-selected-text, #e0e7ff);\n }\n \n .option.active {\n background-color: var(--select-dark-option-active-bg, #374151);\n color: var(--select-dark-option-active-color, #f9fafb);\n outline: var(--select-dark-option-active-outline, 2px solid rgba(129, 140, 248, 0.55));\n }\n\n .selection-badge {\n background: var(--select-dark-badge-bg, #4f46e5);\n color: var(--select-dark-badge-color, #eef2ff);\n }\n\n .badge-remove {\n background: var(--select-dark-badge-remove-bg, rgba(255, 255, 255, 0.15));\n color: var(--select-dark-badge-remove-color, #e5e7eb);\n }\n\n .badge-remove:hover {\n background: var(--select-dark-badge-remove-hover-bg, rgba(255, 255, 255, 0.3));\n }\n \n .busy-bucket,\n .empty-state {\n color: var(--select-dark-busy-color, #9ca3af);\n background: var(--select-dark-empty-bg, #111827);\n }\n\n .searching-state {\n background: var(--select-dark-searching-bg, #111827);\n }\n \n .input-container::after {\n background: linear-gradient(\n to bottom,\n transparent 0%,\n rgba(255, 255, 255, 0.1) 20%,\n rgba(255, 255, 255, 0.1) 80%,\n transparent 100%\n );\n }\n }\n \n /* Accessibility: High contrast mode */\n @media (prefers-contrast: high) {\n .select-input:focus {\n outline-width: 3px;\n outline-color: Highlight;\n }\n \n .select-input {\n border-width: 2px;\n }\n }\n \n /* Touch targets (WCAG 2.5.5) */\n .load-more-button,\n select-option {\n min-height: 44px;\n }\n ',this._shadow.firstChild?this._shadow.insertBefore(e,this._shadow.firstChild):this._shadow.appendChild(e)}_attachEventListeners(){this._arrowContainer&&(this._boundArrowClick=e=>{e.stopPropagation(),e.preventDefault();const t=this._state.isOpen;this._state.isOpen=!this._state.isOpen,this._updateDropdownVisibility(),this._updateArrowRotation(),this._state.isOpen&&this._config.callbacks.onOpen?this._config.callbacks.onOpen():!this._state.isOpen&&this._config.callbacks.onClose&&this._config.callbacks.onClose(),!t&&this._state.isOpen&&this._state.selectedIndices.size>0&&setTimeout(()=>this._scrollToSelected(),50)},this._arrowContainer.addEventListener("click",this._boundArrowClick)),this._inputContainer.addEventListener("pointerdown",e=>{const t=e.target;this._config.enabled&&(t&&t.closest(".dropdown-arrow-container")||(this._state.isOpen||this._handleOpen(),this._input.focus()))}),this._container.addEventListener("click",e=>{e.stopPropagation()}),this._input.addEventListener("focus",()=>this._handleOpen()),this._input.addEventListener("blur",e=>{const t=e.relatedTarget;t&&(this._shadow.contains(t)||this._container.contains(t))||setTimeout(()=>{const e=document.activeElement;e&&(this._shadow.contains(e)||this._container.contains(e))||this._handleClose()},0)}),this._input.addEventListener("input",e=>{if(!this._config.searchable)return;const t=e.target.value;this._handleSearch(t)}),this._input.addEventListener("keydown",e=>this._handleKeydown(e)),document.addEventListener("pointerdown",e=>{const t=e.composedPath&&e.composedPath()||[];t.includes(this)||t.includes(this._container)||this._shadow.contains(e.target)||this._handleClose()})}_initializeObservers(){this._intersectionObserver&&(this._intersectionObserver.disconnect(),this._intersectionObserver=void 0),this._config.infiniteScroll.enabled&&(this._intersectionObserver=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting&&(this._state.isBusy||this._loadMoreItems())})},{threshold:.1}))}async _loadInitialSelectedItems(){if(this._config.serverSide.fetchSelectedItems&&this._config.serverSide.initialSelectedValues){this._setBusy(!0);try{(await this._config.serverSide.fetchSelectedItems(this._config.serverSide.initialSelectedValues)).forEach((e,t)=>{this._state.selectedItems.set(t,e),this._state.selectedIndices.add(t)}),this._updateInputDisplay()}catch(e){this._handleError(e)}finally{this._setBusy(!1)}}}_handleOpen(){this._config.enabled&&!this._state.isOpen&&(this._markOpenStart(),this._state.isOpen=!0,this._dropdown.style.display="block",this._input.setAttribute("aria-expanded","true"),this._updateArrowRotation(),this._config.searchable&&(this._state.searchQuery=""),this._renderOptions(),this._setInitialActiveOption(),this._emit("open",{}),this._config.callbacks.onOpen?.(),this._announce("Options expanded"),this._config.scrollToSelected.enabled&&requestAnimationFrame(()=>{requestAnimationFrame(()=>{this._scrollToSelected()})}))}_handleClose(){this._state.isOpen&&(this._state.isOpen=!1,this._dropdown.style.display="none",this._input.setAttribute("aria-expanded","false"),this._input.removeAttribute("aria-activedescendant"),this._updateArrowRotation(),this._emit("close",{}),this._config.callbacks.onClose?.(),this._announce("Options collapsed"))}_updateDropdownVisibility(){this._state.isOpen?(this._dropdown.style.display="block",this._input.setAttribute("aria-expanded","true")):(this._dropdown.style.display="none",this._input.setAttribute("aria-expanded","false"))}_updateArrowRotation(){if(this._arrowContainer){const e=this._arrowContainer.querySelector(".dropdown-arrow");e&&(this._state.isOpen?e.classList.add("open"):e.classList.remove("open"))}}_isPerfEnabled(){return"undefined"!=typeof globalThis&&!0===globalThis.__SMILODON_DEV__&&"undefined"!=typeof performance&&"function"==typeof performance.mark&&"function"==typeof performance.measure}_perfMark(e){this._isPerfEnabled()&&performance.mark(e)}_perfMeasure(e,t,n){this._isPerfEnabled()&&performance.measure(e,t,n)}_markOpenStart(){this._isPerfEnabled()&&(this._pendingFirstRenderMark=!0,this._perfMark("smilodon-dropdown-open-start"))}_finalizePerfMarks(){if(!this._isPerfEnabled())return this._pendingFirstRenderMark=!1,void(this._pendingSearchRenderMark=!1);this._pendingFirstRenderMark&&(this._pendingFirstRenderMark=!1,this._perfMark("smilodon-first-render-complete"),this._perfMeasure("smilodon-dropdown-to-first-render","smilodon-dropdown-open-start","smilodon-first-render-complete")),this._pendingSearchRenderMark&&(this._pendingSearchRenderMark=!1,this._perfMark("smilodon-search-render-complete"),this._perfMeasure("smilodon-search-to-render","smilodon-search-input-last","smilodon-search-render-complete"))}_handleSearch(e){this._state.searchQuery=e,e.length>0?(this._perfMark("smilodon-search-input-last"),this._pendingSearchRenderMark=!0):this._pendingSearchRenderMark=!1,this._searchTimeout&&clearTimeout(this._searchTimeout),this._state.isSearching=!1,this._state.isOpen?this._renderOptions():this._handleOpen();const t=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e)),n=e.toLowerCase(),s=n?this._state.loadedItems.filter(e=>{try{return String(t(e)).toLowerCase().includes(n)}catch(e){return!1}}):this._state.loadedItems,i=s.length;n&&this._announce(`${i} result${1!==i?"s":""} found for "${e}"`),e===this._state.lastNotifiedQuery&&i===this._state.lastNotifiedResultCount||(this._state.lastNotifiedQuery=e,this._state.lastNotifiedResultCount=i,setTimeout(()=>{this._emit("search",{query:e,results:s,count:i}),this._config.callbacks.onSearch?.(e)},0))}_handleKeydown(e){switch(e.key){case"ArrowDown":e.preventDefault(),this._state.isOpen?this._moveActive(1,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey}):this._handleOpen();break;case"ArrowUp":e.preventDefault(),this._state.isOpen?this._moveActive(-1,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey}):this._handleOpen();break;case"Home":e.preventDefault(),this._state.isOpen&&(this._setActive(0),"multi"===this._config.selection.mode&&e.shiftKey&&this._selectRange(this._rangeAnchorIndex??0,0,{clear:!(e.ctrlKey||e.metaKey)}));break;case"End":if(e.preventDefault(),this._state.isOpen){const t=Array.from(this._optionsContainer.children),n=Math.max(0,t.length-1);this._setActive(n),"multi"===this._config.selection.mode&&e.shiftKey&&this._selectRange(this._rangeAnchorIndex??n,n,{clear:!(e.ctrlKey||e.metaKey)})}break;case"PageDown":e.preventDefault(),this._state.isOpen&&this._moveActive(10,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey});break;case"PageUp":e.preventDefault(),this._state.isOpen&&this._moveActive(-10,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey});break;case"Enter":e.preventDefault(),this._state.activeIndex>=0&&this._selectOption(this._state.activeIndex,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey});break;case"Escape":e.preventDefault(),this._handleClose();break;case"Tab":this._state.isOpen&&this._handleClose();break;case"a":case"A":(e.ctrlKey||e.metaKey)&&"multi"===this._config.selection.mode&&(e.preventDefault(),this._selectAll());break;default:1!==e.key.length||e.ctrlKey||e.altKey||e.metaKey||this._handleTypeAhead(e.key)}}_moveActive(e,t){const n=Array.from(this._optionsContainer.children),s=Math.max(0,Math.min(n.length-1,this._state.activeIndex+e));if(this._setActive(s),"multi"===this._config.selection.mode&&t?.shiftKey){const e=this._rangeAnchorIndex??this._state.activeIndex,n=e>=0?e:s;null===this._rangeAnchorIndex&&(this._rangeAnchorIndex=n),this._selectRange(n,s,{clear:!t?.toggleKey})}}_setActive(e){const t=Array.from(this._optionsContainer.children);if(this._state.activeIndex>=0&&t[this._state.activeIndex]){const e=t[this._state.activeIndex];"setActive"in e&&"function"==typeof e.setActive?e.setActive(!1):(e.classList.remove("smilodon-option--active"),e.setAttribute("aria-selected","false"))}if(this._state.activeIndex=e,t[e]){const n=t[e];"setActive"in n&&"function"==typeof n.setActive?n.setActive(!0):(n.classList.add("smilodon-option--active"),n.setAttribute("aria-selected","true")),n.scrollIntoView({block:"nearest",behavior:"smooth"});const s=t.length;this._announce(`Item ${e+1} of ${s}`);const i=n.id||`${this._uniqueId}-option-${e}`;this._input.setAttribute("aria-activedescendant",i)}}_getOptionElementByIndex(e){return this._optionsContainer.querySelector(`[data-index="${e}"]`)}_buildRendererHelpers(){return{onSelect:(e,t)=>this._selectOption(t),getIndex:e=>{const t=e?.closest?.("[data-selectable]");if(!t)return null;const n=Number(t.dataset.index);return Number.isFinite(n)?n:null},keyboardFocus:e=>{this._setActive(e);const t=this._getOptionElementByIndex(e);t?.focus?.()}}}_handleTypeAhead(e){this._typeTimeout&&clearTimeout(this._typeTimeout),this._typeBuffer+=e.toLowerCase(),this._typeTimeout=window.setTimeout(()=>{this._typeBuffer=""},500);const t=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e)),n=this._state.loadedItems.findIndex(e=>t(e).toLowerCase().startsWith(this._typeBuffer));n>=0&&this._setActive(n)}_selectAll(){if("multi"!==this._config.selection.mode)return;const e=Array.from(this._optionsContainer.children),t=this._config.selection.maxSelections||0;e.forEach((e,n)=>{if(!(t>0&&this._state.selectedIndices.size>=t||this._state.selectedIndices.has(n)))if("getConfig"in e&&"function"==typeof e.getConfig){const t=e.getConfig();this._state.selectedIndices.add(n),this._state.selectedItems.set(n,t.item),e.setSelected(!0)}else{const t=this._state.loadedItems[n];t&&(this._state.selectedIndices.add(n),this._state.selectedItems.set(n,t),e.classList.add("smilodon-option--selected"),e.setAttribute("aria-selected","true"))}}),this._updateInputDisplay(),this._emitChange(),this._announce(`Selected all ${e.length} items`)}_selectRange(e,t,n){if("multi"!==this._config.selection.mode)return;const s=this._config.selection.maxSelections||0,[i,o]=e<t?[e,t]:[t,e];n?.clear&&(this._state.selectedIndices.clear(),this._state.selectedItems.clear());for(let e=i;e<=o&&!(s>0&&this._state.selectedIndices.size>=s);e+=1){const t=this._state.loadedItems[e];t&&(this._state.selectedIndices.add(e),this._state.selectedItems.set(e,t))}this._renderOptions(),this._updateInputDisplay(),this._emitChange(),this._announce(`${this._state.selectedIndices.size} items selected`)}_setInitialActiveOption(){const e=Array.from(this._optionsContainer.children);if(0===e.length)return;const t=Array.from(this._state.selectedIndices).sort((e,t)=>e-t);if("multi"===this._config.selection.mode&&0===t.length)return this._state.activeIndex=-1,void this._input.removeAttribute("aria-activedescendant");const n=t.length>0?t[0]:0;this._setActive(Math.min(n,e.length-1))}_announce(e){this._liveRegion&&(this._liveRegion.textContent=e,setTimeout(()=>{this._liveRegion&&(this._liveRegion.textContent="")},1e3))}_selectOption(e,t){const n=this._state.loadedItems[e];if(!n)return;const s=this._state.selectedIndices.has(e);if("single"===this._config.selection.mode){const t=this._state.selectedIndices.has(e);this._state.selectedIndices.clear(),this._state.selectedItems.clear(),t||(this._state.selectedIndices.add(e),this._state.selectedItems.set(e,n)),this._renderOptions(),this._config.selection.closeOnSelect&&this._handleClose()}else{const i=Boolean(t?.toggleKey);if(Boolean(t?.shiftKey)){const t=this._rangeAnchorIndex??e;return this._selectRange(t,e,{clear:!i}),void(this._rangeAnchorIndex=t)}const o=this._config.selection.maxSelections||0;if(s)this._state.selectedIndices.delete(e),this._state.selectedItems.delete(e);else{if(o>0&&this._state.selectedIndices.size>=o)return void this._announce(`Maximum ${o} selections allowed`);this._state.selectedIndices.add(e),this._state.selectedItems.set(e,n)}this._renderOptions()}this._rangeAnchorIndex=e,this._updateInputDisplay(),this._emitChange();const i=this._config.serverSide.getValueFromItem||(e=>e?.value??e),o=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e)),r=o(n);if("single"===this._config.selection.mode)this._announce(`Selected ${r}`);else{const e=this._state.selectedIndices.size,t=s?"Deselected":"Selected";this._announce(`${t} ${r}. ${e} selected`)}this._config.callbacks.onSelect?.({item:n,index:e,value:i(n),label:o(n),selected:this._state.selectedIndices.has(e)})}_handleOptionRemove(e){const t=this._getOptionElementByIndex(e);if(!t)return;this._state.selectedIndices.delete(e),this._state.selectedItems.delete(e),t.setSelected(!1),this._updateInputDisplay(),this._emitChange();const n=t.getConfig();this._emit("remove",{item:n.item,index:e})}_updateInputDisplay(){const e=Array.from(this._state.selectedItems.values()),t=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e));if(0===e.length){this._input.value="",this._input.placeholder=this._config.placeholder||"Select an option...";this._inputContainer.querySelectorAll(".selection-badge").forEach(e=>e.remove())}else if("single"===this._config.selection.mode)this._input.value=t(e[0]);else{this._input.value="",this._input.placeholder="";this._inputContainer.querySelectorAll(".selection-badge").forEach(e=>e.remove());Array.from(this._state.selectedItems.entries()).forEach(([e,n])=>{const s=document.createElement("span");s.className="selection-badge",s.textContent=t(n);const i=document.createElement("button");i.className="badge-remove",i.innerHTML="×",i.setAttribute("aria-label",`Remove ${t(n)}`),i.addEventListener("click",t=>{t.stopPropagation(),this._state.selectedIndices.delete(e),this._state.selectedItems.delete(e),this._updateInputDisplay(),this._renderOptions(),this._emitChange()}),s.appendChild(i),this._inputContainer.insertBefore(s,this._input)})}}_renderOptionsWithAnimation(){this._optionsContainer.style.opacity="0",this._optionsContainer.style.transition="opacity 0.15s ease-out",setTimeout(()=>{this._renderOptions(),this._optionsContainer.style.opacity="1",this._optionsContainer.style.transition="opacity 0.2s ease-in"},150)}_scrollToSelected(){if(0===this._state.selectedIndices.size)return;const e=this._config.scrollToSelected.multiSelectTarget,t=Array.from(this._state.selectedIndices).sort((e,t)=>e-t);let n;if("multi"===this._config.selection.mode&&t.length>1){const e=this._dropdown.getBoundingClientRect(),s=this._dropdown.scrollTop+e.height/2;let i=t[0],o=1/0;for(const e of t){const t=this._getOptionElementByIndex(e);if(t){const n=t.offsetTop,r=Math.abs(n-s);r<o&&(o=r,i=e)}}n=i}else n="first"===e?t[0]:t[t.length-1];const s=this._getOptionElementByIndex(n);s&&(s.scrollIntoView({block:this._config.scrollToSelected.block||"center",behavior:"smooth"}),this._setActive(n))}async _loadMoreItems(){if(!this._state.isBusy){this._setBusy(!0),this._dropdown&&(this._state.lastScrollPosition=this._dropdown.scrollTop,this._state.preserveScrollPosition=!0,this._renderOptions(),this._dropdown.scrollTop=this._state.lastScrollPosition);try{this._state.currentPage++,this._emit("loadMore",{page:this._state.currentPage,items:[]}),this._config.callbacks.onLoadMore?.(this._state.currentPage)}catch(e){this._handleError(e),this._setBusy(!1)}}}_setBusy(e){this._state.isBusy=e,e?this._dropdown.setAttribute("aria-busy","true"):this._dropdown.removeAttribute("aria-busy"),this._renderOptions()}_handleError(e){this._emit("error",{message:e.message,cause:e}),this._config.callbacks.onError?.(e)}_emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}_emitChange(){const e=Array.from(this._state.selectedItems.values()),t=this._config.serverSide.getValueFromItem||(e=>e?.value??e),n=e.map(t),s=Array.from(this._state.selectedIndices);this._emit("change",{selectedItems:e,selectedValues:n,selectedIndices:s}),this._config.callbacks.onChange?.(e,n)}get optionRenderer(){return this._optionRenderer}set optionRenderer(e){this._optionRenderer=e,this._renderOptions()}setItems(e){const t=this._state.loadedItems.length;this._state.loadedItems=e,this._state.groupedItems.length>0&&(this._state.loadedItems=this._state.groupedItems.flatMap(e=>e.options));const n=this._state.loadedItems.length;if(this._state.preserveScrollPosition&&this._dropdown){const e=this._state.lastScrollPosition;n>t&&(this._state.isBusy=!1),this._renderOptions(),this._dropdown.scrollTop=e,requestAnimationFrame(()=>{this._dropdown&&(this._dropdown.scrollTop=e)}),n>t&&(this._state.preserveScrollPosition=!1)}else this._state.isBusy=!1,this._renderOptions()}setGroupedItems(e){this._state.groupedItems=e,this._state.loadedItems=e.flatMap(e=>e.options),this._renderOptions()}getSelectedItems(){return Array.from(this._state.selectedItems.values())}get loadedItems(){return this._state.loadedItems}getSelectedValues(){const e=this._config.serverSide.getValueFromItem||(e=>e?.value??e);return this.getSelectedItems().map(e)}async setSelectedValues(e){if(this._config.serverSide.enabled&&this._config.serverSide.fetchSelectedItems)await this._loadSelectedItemsByValues(e);else{const t=this._config.serverSide.getValueFromItem||(e=>e?.value??e);this._state.selectedIndices.clear(),this._state.selectedItems.clear(),this._state.loadedItems.forEach((n,s)=>{e.includes(t(n))&&(this._state.selectedIndices.add(s),this._state.selectedItems.set(s,n))}),this._renderOptions(),this._updateInputDisplay(),this._emitChange()}}async _loadSelectedItemsByValues(e){if(this._config.serverSide.fetchSelectedItems){this._setBusy(!0);try{const t=await this._config.serverSide.fetchSelectedItems(e);this._state.selectedIndices.clear(),this._state.selectedItems.clear(),t.forEach((e,t)=>{this._state.selectedIndices.add(t),this._state.selectedItems.set(t,e)}),this._renderOptions(),this._updateInputDisplay(),this._emitChange(),this._config.scrollToSelected.enabled&&this._scrollToSelected()}catch(e){this._handleError(e)}finally{this._setBusy(!1)}}}clear(){this._state.selectedIndices.clear(),this._state.selectedItems.clear(),this._renderOptions(),this._updateInputDisplay(),this._emitChange()}open(){this._handleOpen()}close(){this._handleClose()}updateConfig(e){this._config=selectConfig.mergeWithComponentConfig(e),this._input&&(this._input.readOnly=!this._config.searchable,this._input.setAttribute("aria-autocomplete",this._config.searchable?"list":"none"),0===this._state.selectedIndices.size&&(this._input.placeholder=this._config.placeholder||"Select an option...")),this._dropdown&&("multi"===this._config.selection.mode?this._dropdown.setAttribute("aria-multiselectable","true"):this._dropdown.removeAttribute("aria-multiselectable")),this._initializeObservers(),this._renderOptions()}setError(e){this._hasError=!0,this._errorMessage=e,this._input.setAttribute("aria-invalid","true"),this._announce(`Error: ${e}`)}clearError(){this._hasError=!1,this._errorMessage="",this._input.removeAttribute("aria-invalid")}setRequired(e){e?(this._input.setAttribute("aria-required","true"),this._input.setAttribute("required","")):(this._input.removeAttribute("aria-required"),this._input.removeAttribute("required"))}validate(){return this._input.hasAttribute("required")&&0===this._state.selectedIndices.size?(this.setError("Selection is required"),!1):(this.clearError(),!0)}_renderOptions(){if(this._loadMoreTrigger&&this._intersectionObserver&&this._intersectionObserver.unobserve(this._loadMoreTrigger),this._optionsContainer.innerHTML="",Array.from(this._dropdown.children).forEach(e=>{e!==this._optionsContainer&&this._dropdown.removeChild(e)}),this._state.isOpen&&"none"===this._dropdown.style.display&&(this._dropdown.style.display="block"),this._state.isSearching){const e=document.createElement("div");return e.className="searching-state",e.textContent="Searching...",void this._optionsContainer.appendChild(e)}const e=this._config.serverSide.getValueFromItem||(e=>e?.value??e),t=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e)),n=this._state.searchQuery.toLowerCase();if(this._state.groupedItems.length>0&&!n)this._state.groupedItems.forEach(n=>{const s=document.createElement("div");s.className="group-header",s.textContent=n.label,Object.assign(s.style,{padding:"8px 12px",fontWeight:"600",color:"#6b7280",backgroundColor:"#f3f4f6",fontSize:"12px",textTransform:"uppercase",letterSpacing:"0.05em",position:"sticky",top:"0",zIndex:"1",borderBottom:"1px solid #e5e7eb"}),this._optionsContainer.appendChild(s),n.options.forEach(n=>{const s=this._state.loadedItems.indexOf(n);-1!==s&&this._renderSingleOption(n,s,e,t)})});else{let s=!1;if(this._state.loadedItems.forEach((i,o)=>{if(n)try{if(!String(t(i)).toLowerCase().includes(n))return}catch(e){return}s=!0,this._renderSingleOption(i,o,e,t)}),!s&&!this._state.isBusy){const e=document.createElement("div");e.className="empty-state",e.textContent=n?`No results found for "${this._state.searchQuery}"`:"No options available",this._optionsContainer.appendChild(e)}}if(this._state.isBusy&&this._config.busyBucket.enabled){const e=document.createElement("div");if(e.className="busy-bucket",this._config.busyBucket.showSpinner){const t=document.createElement("div");t.className="spinner",e.appendChild(t)}if(this._config.busyBucket.message){const t=document.createElement("div");t.textContent=this._config.busyBucket.message,e.appendChild(t)}this._optionsContainer.appendChild(e)}else(this._config.loadMore.enabled||this._config.infiniteScroll.enabled)&&this._state.loadedItems.length>0&&this._addLoadMoreTrigger();this._finalizePerfMarks()}_renderSingleOption(e,t,n,s){const i=this._state.selectedIndices.has(t),o=Boolean(e?.disabled),r=`${this._uniqueId}-option-${t}`;if(this._optionRenderer){const a=this._optionRenderer(e,t,this._rendererHelpers),l=this._normalizeCustomOptionElement(a,{index:t,value:n(e),label:s(e),selected:i,active:this._state.activeIndex===t,disabled:o,id:r});return void this._optionsContainer.appendChild(l)}const a=new SelectOption({item:e,index:t,id:r,selected:i,disabled:o,active:this._state.activeIndex===t,getValue:n,getLabel:s,showRemoveButton:"multi"===this._config.selection.mode&&this._config.selection.showRemoveButton});a.dataset.index=String(t),a.dataset.value=String(n(e)),a.id=a.id||r,a.addEventListener("click",e=>{const n=e;this._selectOption(t,{shiftKey:n.shiftKey,toggleKey:n.ctrlKey||n.metaKey})}),a.addEventListener("optionRemove",e=>{const n=e.detail,s=n?.index??t;this._handleOptionRemove(s)}),this._optionsContainer.appendChild(a)}_normalizeCustomOptionElement(e,t){const n=e instanceof HTMLElement?e:document.createElement("div");return n.classList.add("smilodon-option"),n.classList.toggle("smilodon-option--selected",t.selected),n.classList.toggle("smilodon-option--active",t.active),n.classList.toggle("smilodon-option--disabled",t.disabled),n.hasAttribute("data-selectable")||n.setAttribute("data-selectable",""),n.dataset.index=String(t.index),n.dataset.value=String(t.value),n.id=n.id||t.id,n.getAttribute("role")||n.setAttribute("role","option"),n.getAttribute("aria-label")||n.setAttribute("aria-label",t.label),n.setAttribute("aria-selected",String(t.selected)),t.disabled?n.setAttribute("aria-disabled","true"):n.removeAttribute("aria-disabled"),n.hasAttribute("tabindex")||(n.tabIndex=-1),t.disabled||(n.addEventListener("click",e=>{const n=e;this._selectOption(t.index,{shiftKey:n.shiftKey,toggleKey:n.ctrlKey||n.metaKey})}),n.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this._selectOption(t.index,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey}))})),n}_addLoadMoreTrigger(){const e=document.createElement("div");if(e.className="load-more-container",this._config.infiniteScroll.enabled){const t=document.createElement("div");t.className="infinite-scroll-sentinel",t.style.height="10px",t.style.width="100%",t.style.opacity="0",this._loadMoreTrigger=t,e.appendChild(t)}else{const t=document.createElement("button");t.className="load-more-button",t.textContent=`Load ${this._config.loadMore.itemsPerLoad} more`,t.addEventListener("click",()=>this._loadMoreItems()),this._loadMoreTrigger=t,e.appendChild(t)}this._optionsContainer.appendChild(e),this._intersectionObserver&&this._loadMoreTrigger&&this._intersectionObserver.observe(this._loadMoreTrigger)}}customElements.get("enhanced-select")||customElements.define("enhanced-select",EnhancedSelect);class WorkerManager{constructor(){this.worker=null,this.pending=new Map,this.supportsWorkers=!1,this.supportsSharedArrayBuffer=!1,this.nextId=0,this.detectFeatures(),this.initWorker()}detectFeatures(){this.supportsWorkers="undefined"!=typeof Worker,this.supportsSharedArrayBuffer="undefined"!=typeof SharedArrayBuffer}initWorker(){if(this.supportsWorkers)try{const e=this.generateWorkerCode(),t=new Blob([e],{type:"application/javascript"}),n=URL.createObjectURL(t);this.worker=new Worker(n),this.worker.onmessage=this.handleMessage.bind(this),this.worker.onerror=this.handleError.bind(this),URL.revokeObjectURL(n)}catch(e){console.warn("Worker initialization failed, falling back to main thread",e),this.worker=null}}generateWorkerCode(){return"\n // Worker code\n self.onmessage = function(e) {\n const start = performance.now();\n const { id, type, payload } = e.data;\n \n try {\n let result;\n \n switch (type) {\n case 'transform':\n result = handleTransform(payload);\n break;\n case 'search':\n result = handleSearch(payload);\n break;\n case 'filter':\n result = handleFilter(payload);\n break;\n case 'sort':\n result = handleSort(payload);\n break;\n default:\n throw new Error('Unknown operation: ' + type);\n }\n \n const duration = performance.now() - start;\n self.postMessage({\n id,\n success: true,\n data: result,\n duration,\n });\n } catch (error) {\n self.postMessage({\n id,\n success: false,\n error: error.message,\n });\n }\n };\n \n function handleTransform({ items, transformer }) {\n const fn = new Function('item', 'index', 'return (' + transformer + ')(item, index)');\n return items.map((item, i) => fn(item, i));\n }\n \n function handleSearch({ items, query, fuzzy, maxResults }) {\n const lowerQuery = query.toLowerCase();\n const results = [];\n \n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const text = String(item).toLowerCase();\n \n if (fuzzy) {\n if (fuzzyMatch(text, lowerQuery)) {\n results.push({ item, index: i, score: fuzzyScore(text, lowerQuery) });\n }\n } else {\n if (text.includes(lowerQuery)) {\n results.push({ item, index: i });\n }\n }\n \n if (maxResults && results.length >= maxResults) break;\n }\n \n if (fuzzy) {\n results.sort((a, b) => b.score - a.score);\n }\n \n return results;\n }\n \n function handleFilter({ items, predicate }) {\n const fn = new Function('item', 'index', 'return (' + predicate + ')(item, index)');\n return items.filter((item, i) => fn(item, i));\n }\n \n function handleSort({ items, comparator }) {\n const fn = new Function('a', 'b', 'return (' + comparator + ')(a, b)');\n return [...items].sort(fn);\n }\n \n // Simple fuzzy matching (Levenshtein-inspired)\n function fuzzyMatch(text, query) {\n let qi = 0;\n for (let ti = 0; ti < text.length && qi < query.length; ti++) {\n if (text[ti] === query[qi]) qi++;\n }\n return qi === query.length;\n }\n \n function fuzzyScore(text, query) {\n let score = 0;\n let qi = 0;\n for (let ti = 0; ti < text.length && qi < query.length; ti++) {\n if (text[ti] === query[qi]) {\n score += 100 - ti; // Earlier matches score higher\n qi++;\n }\n }\n return score;\n }\n "}handleMessage(e){const{id:t,success:n,data:s,error:i}=e.data,o=this.pending.get(t);o&&(clearTimeout(o.timeout),this.pending.delete(t),n?o.resolve(s):o.reject(new Error(i||"Worker error")))}handleError(e){console.error("Worker error:",e);for(const[e,t]of this.pending)clearTimeout(t.timeout),t.reject(new Error("Worker crashed"));this.pending.clear()}async execute(e,t,n=5e3){if(!this.worker)return this.executeFallback(e,t);const s="req_"+this.nextId++;return new Promise((i,o)=>{const r=setTimeout(()=>{this.pending.delete(s),o(new Error("Worker timeout"))},n);this.pending.set(s,{resolve:i,reject:o,timeout:r}),this.worker.postMessage({id:s,type:e,payload:t})})}async executeFallback(e,t){switch(e){case"transform":{const{items:e,transformer:n}=t,s=new Function("item","index",`return (${n})(item, index)`);return e.map((e,t)=>s(e,t))}case"search":{const{items:e,query:n,fuzzy:s}=t,i=n.toLowerCase(),o=[];return e.forEach((e,t)=>{const n=String(e).toLowerCase();if(s){let s=0;for(let e=0;e<n.length&&s<i.length;e++)n[e]===i[s]&&s++;s===i.length&&o.push({item:e,index:t})}else n.includes(i)&&o.push({item:e,index:t})}),o}case"filter":{const{items:e,predicate:n}=t,s=new Function("item","index",`return (${n})(item, index)`);return e.filter((e,t)=>s(e,t))}case"sort":{const{items:e,comparator:n}=t,s=new Function("a","b",`return (${n})(a, b)`);return[...e].sort(s)}default:throw new Error(`Unknown operation: ${e}`)}}async transform(e,t){return this.execute("transform",{items:e,transformer:t.toString()})}async search(e,t,n=!1){return this.execute("search",{items:e,query:t,fuzzy:n})}async filter(e,t){return this.execute("filter",{items:e,predicate:t.toString()})}async sort(e,t){return this.execute("sort",{items:e,comparator:t.toString()})}get hasWorkerSupport(){return this.supportsWorkers&&null!==this.worker}get hasSharedArrayBuffer(){return this.supportsSharedArrayBuffer}destroy(){if(this.worker){for(const[e,t]of this.pending)clearTimeout(t.timeout),t.reject(new Error("Worker terminated"));this.pending.clear(),this.worker.terminate(),this.worker=null}}}let workerManager=null;function getWorkerManager(){return workerManager||(workerManager=new WorkerManager),workerManager}class PerformanceTelemetry{constructor(){this.frameTimes=[],this.longTasks=0,this.lastFrameTime=0,this.rafId=0,this.measuring=!1,this.observer=null,this.workTimes=[],this.measureFrame=()=>{if(!this.measuring)return;const e=performance.now(),t=e-this.lastFrameTime;this.frameTimes.push(t),this.frameTimes.length>60&&this.frameTimes.shift(),this.lastFrameTime=e,this.rafId=requestAnimationFrame(this.measureFrame)},this.setupObserver()}setupObserver(){if("undefined"!=typeof PerformanceObserver)try{this.observer=new PerformanceObserver(e=>{for(const t of e.getEntries())"longtask"===t.entryType&&t.duration>50&&this.longTasks++,"measure"===t.entryType&&this.workTimes.push(t.duration)});try{this.observer.observe({entryTypes:["longtask","measure"]})}catch{this.observer.observe({entryTypes:["measure"]})}}catch(e){console.warn("PerformanceObserver not available",e)}}start(){this.measuring||(this.measuring=!0,this.frameTimes=[],this.workTimes=[],this.longTasks=0,this.lastFrameTime=performance.now(),this.measureFrame())}stop(){this.measuring=!1,this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=0)}markStart(e){performance.mark(`${e}-start`)}markEnd(e){performance.mark(`${e}-end`),performance.measure(e,`${e}-start`,`${e}-end`);const t=performance.getEntriesByName(e,"measure")[0];return t?t.duration:0}getMetrics(){const e=this.frameTimes.length>0?this.frameTimes.reduce((e,t)=>e+t,0)/this.frameTimes.length:0,t={frames:{frameTime:e,fps:e>0?1e3/e:0,longTasks:this.frameTimes.filter(e=>e>16.67).length,droppedFrames:this.frameTimes.filter(e=>e>33.33).length},mainThreadWork:this.workTimes.length>0?this.workTimes.reduce((e,t)=>e+t,0)/this.workTimes.length:0,longTaskCount:this.longTasks};if("memory"in performance&&performance.memory){const e=performance.memory;t.memory={usedJSHeapSize:e.usedJSHeapSize,totalJSHeapSize:e.totalJSHeapSize,jsHeapSizeLimit:e.jsHeapSizeLimit}}return t}isPerformanceGood(){const e=this.getMetrics();return e.frames.fps>=55&&e.mainThreadWork<8&&e.frames.longTasks<3}getReport(){const e=this.getMetrics();let t="=== Performance Report ===\n";if(t+=`FPS: ${e.frames.fps.toFixed(2)}\n`,t+=`Avg Frame Time: ${e.frames.frameTime.toFixed(2)}ms\n`,t+=`Long Frames (>16.67ms): ${e.frames.longTasks}\n`,t+=`Dropped Frames (>33ms): ${e.frames.droppedFrames}\n`,t+=`Avg Main Thread Work: ${e.mainThreadWork.toFixed(2)}ms\n`,t+=`Long Tasks (>50ms): ${e.longTaskCount}\n`,e.memory){t+=`Memory: ${(e.memory.usedJSHeapSize/1024/1024).toFixed(2)}MB / ${(e.memory.jsHeapSizeLimit/1024/1024).toFixed(2)}MB\n`}return t+=`Status: ${this.isPerformanceGood()?"✓ GOOD":"✗ POOR"}\n`,t}reset(){this.frameTimes=[],this.workTimes=[],this.longTasks=0}destroy(){this.stop(),this.observer&&(this.observer.disconnect(),this.observer=null)}}let telemetry=null;function getTelemetry(){return telemetry||(telemetry=new PerformanceTelemetry),telemetry}async function measureAsync(e,t){const n=performance.now();return{result:await t(),duration:performance.now()-n}}function measureSync(e,t){const n=performance.now();return{result:t(),duration:performance.now()-n}}class NoOpSanitizer{sanitize(e){return e}}let globalSanitizer=new NoOpSanitizer;function setHTMLSanitizer(e){globalSanitizer=e}function getHTMLSanitizer(){return globalSanitizer}function sanitizeHTML(e){return globalSanitizer.sanitize(e)}function createTextNode(e){return document.createTextNode(e)}function setTextContent(e,t){e.textContent=t}function createElement(e,t,n){const s=document.createElement(e);if(t)for(const[e,n]of Object.entries(t))e.startsWith("on")||"style"===e?console.warn(`[NativeSelect Security] Blocked attribute: ${e}`):s.setAttribute(e,n);return void 0!==n&&(s.textContent=n),s}function setCSSProperties(e,t){for(const[n,s]of Object.entries(t))n.startsWith("--")?e.style.setProperty(n,s):console.warn(`[NativeSelect Security] CSS property must start with --: ${n}`)}const CSPFeatures={hasInlineScripts(){try{return new Function("return true"),!0}catch{return!1}},hasEval(){try{return eval("true"),!0}catch{return!1}},hasSharedArrayBuffer:()=>"undefined"!=typeof SharedArrayBuffer,hasWorkers(){try{return"undefined"!=typeof Worker}catch{return!1}},isSandboxed(){try{return window!==window.parent&&!window.parent}catch{return!0}},getCSPDirectives(){const e=document.querySelectorAll('meta[http-equiv="Content-Security-Policy"]'),t=[];return e.forEach(e=>{const n=e.getAttribute("content");n&&t.push(n)}),t}};function detectEnvironment(){return{canUseWorkers:CSPFeatures.hasWorkers(),canUseSharedArrayBuffer:CSPFeatures.hasSharedArrayBuffer(),canUseInlineScripts:CSPFeatures.hasInlineScripts(),canUseEval:CSPFeatures.hasEval(),isSandboxed:CSPFeatures.isSandboxed(),cspDirectives:CSPFeatures.getCSPDirectives()}}function validateTemplate(e,t){return globalSanitizer instanceof NoOpSanitizer&&console.warn(`[NativeSelect Security] Template from "${t}" contains HTML but no sanitizer is configured. This may be unsafe if the content is untrusted. Call setHTMLSanitizer() with a sanitizer like DOMPurify.`),sanitizeHTML(e)}function containsSuspiciousPatterns(e){return[/<script/i,/javascript:/i,/on\w+\s*=/i,/eval\s*\(/i,/Function\s*\(/i,/setTimeout\s*\(/i,/setInterval\s*\(/i].some(t=>t.test(e))}function escapeHTML(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function escapeAttribute(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function applyClasses(e,t){e.className=t.filter(Boolean).join(" ")}function toggleClass(e,t,n){e.classList.toggle(t,n)}function setCustomProperties(e,t){for(const[n,s]of Object.entries(t))n.startsWith("--")?e.style.setProperty(n,s):"production"!==process.env.NODE_ENV&&console.warn(`[NativeSelect CSP] Custom property must start with --: "${n}". Skipping.`)}function getCustomProperty(e,t){return getComputedStyle(e).getPropertyValue(t).trim()}function removeCustomProperty(e,t){e.style.removeProperty(t)}const defaultTheme={"--ns-item-height":"40px","--ns-item-padding":"8px 12px","--ns-item-bg":"transparent","--ns-item-hover-bg":"rgba(0, 0, 0, 0.05)","--ns-item-selected-bg":"rgba(0, 102, 204, 0.1)","--ns-item-active-bg":"rgba(0, 102, 204, 0.2)","--ns-item-color":"inherit","--ns-item-selected-color":"#0066cc","--ns-border-color":"#ccc","--ns-border-radius":"4px","--ns-focus-outline":"2px solid #0066cc","--ns-font-size":"14px","--ns-font-family":"system-ui, -apple-system, sans-serif"};function applyDefaultTheme(e){setCustomProperties(e,defaultTheme)}const shadowDOMStyles='\n:host {\n display: block;\n box-sizing: border-box;\n font-family: var(--ns-font-family, system-ui, -apple-system, sans-serif);\n font-size: var(--ns-font-size, 14px);\n}\n\n* {\n box-sizing: border-box;\n}\n\n.ns-list {\n position: relative;\n overflow: auto;\n max-height: var(--ns-max-height, 300px);\n border: 1px solid var(--ns-border-color, #ccc);\n border-radius: var(--ns-border-radius, 4px);\n background: var(--ns-bg, white);\n outline: none;\n}\n\n.ns-list:focus {\n outline: var(--ns-focus-outline, 2px solid #0066cc);\n outline-offset: -2px;\n}\n\n.ns-item {\n padding: var(--ns-item-padding, 8px 12px);\n min-height: var(--ns-item-height, 40px);\n color: var(--ns-item-color, inherit);\n background: var(--ns-item-bg, transparent);\n cursor: pointer;\n user-select: none;\n display: flex;\n align-items: center;\n transition: background-color 0.15s ease;\n}\n\n.ns-item:hover {\n background: var(--ns-item-hover-bg, rgba(0, 0, 0, 0.05));\n}\n\n.ns-item[aria-selected="true"] {\n background: var(--ns-item-selected-bg, rgba(0, 102, 204, 0.1));\n color: var(--ns-item-selected-color, #0066cc);\n}\n\n.ns-item[data-active="true"] {\n background: var(--ns-item-active-bg, rgba(0, 102, 204, 0.2));\n}\n\n.ns-item[aria-disabled="true"] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ns-viewport {\n position: relative;\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.ns-spacer {\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n pointer-events: none;\n}\n\n/* Screen reader only */\n.ns-sr-only {\n position: absolute;\n left: -9999px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n}\n\n/* Portal mode (teleported outside shadow DOM) */\n.ns-portal {\n position: fixed;\n z-index: var(--ns-portal-z-index, 9999);\n}\n\n/* CSP warning banner (only shown in development) */\n.ns-csp-warning {\n padding: 8px;\n background: #fff3cd;\n border: 1px solid #ffc107;\n border-radius: 4px;\n color: #856404;\n font-size: 12px;\n margin-bottom: 8px;\n}\n';function injectShadowStyles(e){const t=document.createElement("style");t.textContent=shadowDOMStyles,e.appendChild(t)}function hasOverflowHiddenAncestor(e){let t=e.parentElement;for(;t&&t!==document.body;){const e=getComputedStyle(t).overflow;if("hidden"===e||"clip"===e)return!0;t=t.parentElement}return!1}function warnCSPViolation(e,t){"production"!==process.env.NODE_ENV&&console.warn(`[NativeSelect CSP] Feature "${e}" blocked by Content Security Policy. Falling back to "${t}".`)}export{CSPFeatures,CustomOptionPool,DOMPool,EnhancedSelect,FenwickTree,NativeSelectElement,OptionRenderer,PerformanceTelemetry,SelectOption,Virtualizer,WorkerManager,applyClasses,applyDefaultTheme,configureSelect,containsSuspiciousPatterns,createElement,createRendererHelpers,createTextNode,defaultTheme,detectEnvironment,escapeAttribute,escapeHTML,getCustomProperty,getHTMLSanitizer,getTelemetry,getWorkerManager,hasOverflowHiddenAncestor,injectShadowStyles,measureAsync,measureSync,removeCustomProperty,renderTemplate,resetSelectConfig,sanitizeHTML,selectConfig,setCSSProperties,setCustomProperties,setHTMLSanitizer,setTextContent,shadowDOMStyles,toggleClass,validateTemplate,warnCSPViolation};
1
+ const createRendererHelpers=e=>({onSelect:e,getIndex:e=>{const t=e?.closest?.("[data-selectable]");if(!t)return null;const n=Number(t.dataset.index);return Number.isFinite(n)?n:null},keyboardFocus:e=>{const t=document.querySelector(`[data-selectable][data-index="${e}"]`);t?.focus?.()}});function renderTemplate(e,t,n){const s=document.createDocumentFragment();for(let e=0;e<t.length;e++){const i=t[e],o=document.createElement("div");o.innerHTML=n(i,e);let r=o.firstElementChild;if(!r){const t=document.createElement("div");for(t.setAttribute("data-selectable",""),t.setAttribute("data-index",String(e));o.firstChild;)t.appendChild(o.firstChild);s.appendChild(t);continue}r.hasAttribute("data-smilodon-handled")||(r.setAttribute("data-selectable",""),r.setAttribute("data-index",String(e))),s.appendChild(r)}e.replaceChildren(s)}class FenwickTree{constructor(e){this.size=e,this.tree=new Float64Array(e+1)}add(e,t){let n=e+1;for(;n<=this.size;)this.tree[n]+=t,n+=n&-n}sum(e){if(e<0)return 0;let t=e+1,n=0;for(;t>0;)n+=this.tree[t],t-=t&-t;return n}rangeSum(e,t){return e>t?0:this.sum(t)-(e>0?this.sum(e-1):0)}update(e,t,n){this.add(e,n-t)}lowerBound(e){if(e<=0)return 0;let t=0,n=0,s=1<<Math.floor(Math.log2(this.size));for(;s>0;){if(t+s<=this.size){const i=n+this.tree[t+s];i<e&&(t+=s,n=i)}s>>=1}return t}reset(){this.tree.fill(0)}resize(e){if(e===this.size)return;const t=this.tree,n=this.size;this.size=e,this.tree=new Float64Array(e+1);const s=Math.min(n,e);for(let e=1;e<=s;e++)this.tree[e]=t[e]}getSize(){return this.size}exportState(){return{size:this.size,tree:Array.from(this.tree)}}static fromState(e){const t=new FenwickTree(e.size);return t.tree=new Float64Array(e.tree),t}}class DOMPool{constructor(e){this.pool=[],this.hits=0,this.misses=0,this.evictions=0,this.factory=e.factory,this.reset=e.reset||this.defaultReset.bind(this),this.maxSize=e.maxSize||64,this.telemetry=e.telemetry||!1}acquire(){const e=performance.now();for(let t=0;t<this.pool.length;t++){const n=this.pool[t];if(!n.inUse)return n.inUse=!0,n.lastUsed=e,this.reset(n.node),this.telemetry&&this.hits++,n.node}const t=this.factory();return this.pool.push({node:t,lastUsed:e,inUse:!0}),this.telemetry&&this.misses++,this.pool.length>this.maxSize&&this.evictLRU(),t}release(e){const t=this.pool.find(t=>t.node===e);t&&(t.inUse=!1,t.lastUsed=performance.now(),this.reset(t.node))}evictLRU(){let e=-1,t=1/0;for(let n=0;n<this.pool.length;n++){const s=this.pool[n];!s.inUse&&s.lastUsed<t&&(e=n,t=s.lastUsed)}if(e>=0){const t=this.pool.splice(e,1)[0];this.deepCleanup(t.node),this.telemetry&&this.evictions++}}defaultReset(e){e.textContent="",e.removeAttribute("style");const t=Array.from(e.attributes);for(const n of t)n.name.startsWith("data-")&&"data-index"!==n.name&&"data-selectable"!==n.name&&e.removeAttribute(n.name);["aria-selected","aria-checked","aria-disabled"].forEach(t=>e.removeAttribute(t))}deepCleanup(e){const t=e.cloneNode(!0);e.parentNode?.replaceChild(t,e),e.textContent=""}clear(){for(const e of this.pool)this.deepCleanup(e.node);this.pool=[],this.resetTelemetry()}setMaxSize(e){for(this.maxSize=e;this.pool.length>this.maxSize;)this.evictLRU()}getStats(){const e=this.pool.filter(e=>!e.inUse).length,t=this.hits+this.misses>0?this.hits/(this.hits+this.misses):0;return{total:this.pool.length,available:e,inUse:this.pool.length-e,maxSize:this.maxSize,hits:this.hits,misses:this.misses,evictions:this.evictions,hitRate:t}}resetTelemetry(){this.hits=0,this.misses=0,this.evictions=0}}class Virtualizer{constructor(e,t,n,s){this.measuredHeights=new Map,this.activeNodes=new Map,this.container=e,this.itemsLength=t,this.itemGetter=n,this.options=s,this.averageHeight=s.estimatedItemHeight;const i=Math.ceil(1.5*(2*s.buffer+10))+(s.maxPoolExtra??32);if(this.pool=new DOMPool({maxSize:i,factory:()=>{const e=document.createElement("div");return e.setAttribute("data-selectable",""),e},reset:e=>{e.textContent="",e.removeAttribute("style"),e.removeAttribute("aria-selected"),e.removeAttribute("aria-checked")},telemetry:s.enableTelemetry||!1}),t>5e3){this.fenwick=new FenwickTree(t);for(let e=0;e<t;e++)this.fenwick.add(e,s.estimatedItemHeight)}this.container.style.willChange="transform"}computeWindow(e,t){const{buffer:n}=this.options,s=Math.max(Math.floor(e/this.averageHeight)-n,0),i=Math.min(Math.ceil((e+t)/this.averageHeight)+n,this.itemsLength-1),o=Math.max(0,i-s+1),r=o+(this.options.maxPoolExtra??32);return this.pool.setMaxSize(r),{startIndex:s,endIndex:i,windowSize:o}}cumulativeOffset(e){if(e<=0)return 0;if(this.fenwick)return this.fenwick.sum(e-1);let t=0;for(let n=0;n<e;n++)t+=this.measuredHeights.get(n)??this.averageHeight;return t}acquireNode(e){const t=this.activeNodes.get(e);if(t)return t;const n=this.pool.acquire();return n.setAttribute("data-index",String(e)),this.activeNodes.set(e,n),n}releaseNode(e){const t=this.activeNodes.get(e);t&&(this.pool.release(t),this.activeNodes.delete(e))}releaseExcess(e){for(const[t,n]of this.activeNodes)e.has(t)||(this.pool.release(n),this.activeNodes.delete(t))}render(e,t,n){const s=document.createDocumentFragment(),i=new Set;for(let o=e;o<=t;o++){const e=this.acquireNode(o);n(e,this.itemGetter(o),o),s.appendChild(e),i.add(o),queueMicrotask(()=>this.measureOnAppear(e,o))}const o=this.cumulativeOffset(e);this.container.style.transform=`translate3d(0, ${Math.round(100*o)/100}px, 0)`,this.container.replaceChildren(s),requestAnimationFrame(()=>this.releaseExcess(i))}measureOnAppear(e,t){const n=e.offsetHeight,s=this.measuredHeights.get(t),i=this.options.measurementThreshold??5;if(void 0===s||Math.abs(s-n)>i){const e=s??this.averageHeight;this.measuredHeights.set(t,n),this.fenwick&&this.fenwick.update(t,e,n);const i=this.measuredHeights.size,o=Array.from(this.measuredHeights.values()).reduce((e,t)=>e+t,0);this.averageHeight=Math.round(o/i*100)/100}}getPoolStats(){return this.pool.getStats()}setItemsLength(e){if(this.itemsLength=e,this.fenwick)this.fenwick.resize(e);else if(e>5e3&&!this.fenwick){this.fenwick=new FenwickTree(e);for(const[e,t]of this.measuredHeights)this.fenwick.update(e,this.averageHeight,t)}}destroy(){this.pool.clear(),this.activeNodes.clear(),this.measuredHeights.clear(),this.fenwick&&this.fenwick.reset()}}class CustomOptionPool{constructor(e=50){this._pool=new Map,this._activeComponents=new Map,this._maxPoolSize=e}acquire(e,t,n,s,i){const o=this._getFactoryKey(e),r=this._findAvailableComponent(o);let a;if(r)a=r.instance,r.inUse=!0,r.lastUsedIndex=n;else try{a=e(t,n);const s=this._pool.get(o)||[];s.length<this._maxPoolSize&&(s.push({instance:a,inUse:!0,lastUsedIndex:n}),this._pool.set(o,s))}catch(e){throw console.error("[CustomOptionPool] Failed to create component:",e),e}try{a.mountOption(i,s),this._activeComponents.set(n,a)}catch(e){throw console.error(`[CustomOptionPool] Failed to mount component at index ${n}:`,e),e}return a}release(e){const t=this._activeComponents.get(e);if(t){try{t.unmountOption()}catch(t){console.error(`[CustomOptionPool] Failed to unmount component at index ${e}:`,t)}this._activeComponents.delete(e);for(const e of this._pool.values()){const n=e.find(e=>e.instance===t);if(n){n.inUse=!1;break}}}}releaseAll(){Array.from(this._activeComponents.keys()).forEach(e=>this.release(e))}updateSelection(e,t){const n=this._activeComponents.get(e);n&&n.updateSelected(t)}updateFocused(e,t){const n=this._activeComponents.get(e);n&&n.updateFocused&&n.updateFocused(t)}getComponent(e){return this._activeComponents.get(e)}clear(){this.releaseAll(),this._pool.clear()}getStats(){let e=0,t=0;for(const n of this._pool.values())e+=n.length,t+=n.filter(e=>!e.inUse).length;return{totalPooled:e,activeComponents:this._activeComponents.size,availableComponents:t}}_findAvailableComponent(e){const t=this._pool.get(e);if(t)return t.find(e=>!e.inUse)}_getFactoryKey(e){return e.name||`factory_${e.toString().slice(0,50)}`}}class OptionRenderer{constructor(e){this._mountedElements=new Map,this._config=e,this._pool=new CustomOptionPool(e.maxPoolSize)}render(e,t,n,s,i){const o=e,r=this._config.getValue(e),a=this._config.getLabel(e),l=!!this._config.getDisabled&&this._config.getDisabled(e);return o.optionComponent&&"function"==typeof o.optionComponent?this._renderCustomComponent(e,t,r,a,n,s,l,i,o.optionComponent):this._renderLightweightOption(e,t,r,a,n,s,l,i)}updateSelection(e,t){const n=this._mountedElements.get(e);if(!n)return;const s=this._pool.getComponent(e);s?s.updateSelected(t):t?(n.classList.add("selected"),n.setAttribute("aria-selected","true")):(n.classList.remove("selected"),n.setAttribute("aria-selected","false"))}updateFocused(e,t){const n=this._mountedElements.get(e);if(!n)return;const s=this._pool.getComponent(e);s?(s.updateFocused&&s.updateFocused(t),n.classList.toggle("focused",t)):n.classList.toggle("focused",t)}unmount(e){this._pool.release(e),this._mountedElements.delete(e)}unmountAll(){this._pool.releaseAll(),this._mountedElements.clear()}getStats(){return this._pool.getStats()}_renderLightweightOption(e,t,n,s,i,o,r,a){const l=document.createElement("div");return l.className="option",i&&l.classList.add("selected"),o&&l.classList.add("focused"),r&&l.classList.add("disabled"),l.id=`${a}-option-${t}`,l.textContent=s,l.dataset.value=String(n),l.dataset.index=String(t),l.dataset.mode="lightweight",l.setAttribute("role","option"),l.setAttribute("aria-selected",String(i)),r&&l.setAttribute("aria-disabled","true"),r||l.addEventListener("click",()=>{this._config.onSelect(t)}),this._mountedElements.set(t,l),l}_renderCustomComponent(e,t,n,s,i,o,r,a,l){const c=document.createElement("div");c.className="option option-custom",i&&c.classList.add("selected"),o&&c.classList.add("focused"),r&&c.classList.add("disabled"),c.id=`${a}-option-${t}`,c.dataset.value=String(n),c.dataset.index=String(t),c.dataset.mode="component",c.setAttribute("role","option"),c.setAttribute("aria-selected",String(i)),c.setAttribute("aria-label",s),r&&c.setAttribute("aria-disabled","true");const d={item:e,index:t,value:n,label:s,isSelected:i,isFocused:o,isDisabled:r,onSelect:e=>{r||this._config.onSelect(e)},onCustomEvent:(e,n)=>{this._config.onCustomEvent&&this._config.onCustomEvent(t,e,n)}};try{this._pool.acquire(l,e,t,d,c).getElement();r||c.addEventListener("click",e=>{c.contains(e.target)&&this._config.onSelect(t)})}catch(e){console.error(`[OptionRenderer] Failed to render custom component at index ${t}:`,e),c.innerHTML="",c.textContent=s,c.classList.add("component-error"),this._config.onError&&this._config.onError(t,e)}return this._mountedElements.set(t,c),c}}class NativeSelectElement extends HTMLElement{static get observedAttributes(){return["placement","strategy","portal"]}constructor(){super(),this._options={},this._items=[],this._selectedSet=new Set,this._selectedItems=new Map,this._activeIndex=-1,this._multi=!1,this._typeBuffer="",this._shadow=this.attachShadow({mode:"open"}),this._listRoot=document.createElement("div"),this._listRoot.setAttribute("role","listbox"),this._listRoot.setAttribute("tabindex","0"),this._shadow.appendChild(this._listRoot),this._liveRegion=document.createElement("div"),this._liveRegion.setAttribute("role","status"),this._liveRegion.setAttribute("aria-live","polite"),this._liveRegion.style.cssText="position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;",this._shadow.appendChild(this._liveRegion),this._helpers=createRendererHelpers((e,t)=>this._onSelect(e,t)),this._listRoot.addEventListener("click",e=>{const t=e.target.closest("[data-selectable]");if(!t)return;const n=Number(t.dataset.index),s=this._items[n];this._onSelect(s,n)}),this._listRoot.addEventListener("keydown",e=>this._onKeydown(e))}connectedCallback(){this._listRoot.setAttribute("role","listbox"),this._listRoot.setAttribute("aria-label","Options list"),this._multi&&this._listRoot.setAttribute("aria-multiselectable","true"),this._initializeOptionRenderer(),this._emit("open",{})}disconnectedCallback(){this._emit("close",{}),this._unifiedRenderer&&this._unifiedRenderer.unmountAll(),this._typeTimeout&&window.clearTimeout(this._typeTimeout)}_initializeOptionRenderer(){const e={enableRecycling:!0,maxPoolSize:100,getValue:e=>e?.value??e,getLabel:e=>e?.label??String(e),getDisabled:e=>e?.disabled??!1,onSelect:e=>{const t=this._items[e];this._onSelect(t,e)},onCustomEvent:(e,t,n)=>{this.dispatchEvent(new CustomEvent("option:custom-event",{detail:{index:e,eventName:t,data:n},bubbles:!0,composed:!0}))},onError:(e,t)=>{console.error(`[NativeSelect] Error in option ${e}:`,t),this.dispatchEvent(new CustomEvent("option:mount-error",{detail:{index:e,error:t},bubbles:!0,composed:!0}))}};this._unifiedRenderer=new OptionRenderer(e)}attributeChangedCallback(e,t,n){switch(e){case"placement":this._options.placement=n??void 0;break;case"strategy":this._options.strategy=n??void 0;break;case"portal":this._options.portal="true"===n||"false"!==n&&void 0}}set items(e){this._items=e??[],this._virtualizer=new Virtualizer(this._listRoot,this._items.length,e=>this._items[e],{estimatedItemHeight:48,buffer:5}),this.render()}get items(){return this._items}set multi(e){this._multi=e,e?this._listRoot.setAttribute("aria-multiselectable","true"):this._listRoot.removeAttribute("aria-multiselectable")}get multi(){return this._multi}get selectedIndices(){return Array.from(this._selectedSet)}get selectedItems(){return Array.from(this._selectedItems.values())}set optionTemplate(e){this._options.optionTemplate=e,this.render()}set optionRenderer(e){this._options.optionRenderer=e,this.render()}setItems(e){this.items=e??[]}setValue(e){if(null==e||""===e)return this._selectedSet.clear(),this._selectedItems.clear(),this._activeIndex=-1,void this.render();const t=this._items.findIndex(t=>"object"==typeof t&&null!==t&&"value"in t?t.value===e:t===e);if(t>=0){const e=this._items[t];this._multi||(this._selectedSet.clear(),this._selectedItems.clear()),this._selectedSet.add(t),this._selectedItems.set(t,e),this._activeIndex=t,this.render()}}getValue(){const e=Array.from(this._selectedItems.values()).map(e=>"object"==typeof e&&null!==e&&"value"in e?e.value:e);return this._multi?e:e[0]??null}render(){const{optionTemplate:e,optionRenderer:t}=this._options,n=this.getBoundingClientRect().height||300,s=this.scrollTop||0;this._activeIndex>=0?this._listRoot.setAttribute("aria-activedescendant",`option-${this._activeIndex}`):this._listRoot.removeAttribute("aria-activedescendant");if(this._items.some(e=>"object"==typeof e&&null!==e&&Object.prototype.hasOwnProperty.call(e,"optionComponent")&&"function"==typeof e.optionComponent)&&this._unifiedRenderer){this._listRoot.replaceChildren();const e=document.createDocumentFragment();for(let t=0;t<this._items.length;t++){const n=this._items[t],s=this._selectedSet.has(t),i=this._activeIndex===t,o=this._unifiedRenderer.render(n,t,s,i,`native-${this.getAttribute("id")||"default"}`);e.appendChild(o)}return void this._listRoot.appendChild(e)}if(this._virtualizer){const{startIndex:i,endIndex:o}=this._virtualizer.computeWindow(s,n);return void this._virtualizer.render(i,o,(n,s,i)=>{if(this._applyOptionAttrs(n,i),t){const e=t(s,i,this._helpers);n.replaceChildren(e)}else if(e){const t=document.createElement("div");t.innerHTML=e(s,i);const o=t.firstElementChild;n.replaceChildren(o??document.createTextNode(String(s)))}else{const e=String("object"==typeof s&&null!==s&&"label"in s?s.label:s);n.textContent=e}})}const i=document.createDocumentFragment();for(let n=0;n<this._items.length;n++){const s=this._items[n];if(t){const e=t(s,n,this._helpers);e.hasAttribute("data-selectable")||(e.setAttribute("data-selectable",""),e.setAttribute("data-index",String(n))),this._applyOptionAttrs(e,n),i.appendChild(e)}else{if(e)return renderTemplate(this._listRoot,this._items,e),void this._applyAriaToAll();{const e=document.createElement("div"),t=String("object"==typeof s&&null!==s&&"label"in s?s.label:s);e.textContent=t,e.setAttribute("data-selectable",""),e.setAttribute("data-index",String(n)),this._applyOptionAttrs(e,n),i.appendChild(e)}}}this._listRoot.replaceChildren(i)}_applyOptionAttrs(e,t){e.setAttribute("role","option"),e.id=`option-${t}`,this._selectedSet.has(t)?e.setAttribute("aria-selected","true"):e.setAttribute("aria-selected","false")}_applyAriaToAll(){const e=Array.from(this._listRoot.children);for(const t of e){const e=Number(t.dataset.index);Number.isFinite(e)&&this._applyOptionAttrs(t,e)}}_emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0}))}_onSelect(e,t){this._multi?this._selectedSet.has(t)?(this._selectedSet.delete(t),this._selectedItems.delete(t)):(this._selectedSet.add(t),this._selectedItems.set(t,e)):(this._selectedSet.clear(),this._selectedItems.clear(),this._selectedSet.add(t),this._selectedItems.set(t,e)),this._activeIndex=t,this.render();const n=this._selectedSet.has(t),s=e?.value??e,i=e?.label??String(e);this._emit("select",{item:e,index:t,value:s,label:i,selected:n,multi:this._multi}),this._emit("change",{selectedItems:Array.from(this._selectedItems.values()),selectedValues:Array.from(this._selectedItems.values()).map(e=>e?.value??e),selectedIndices:Array.from(this._selectedSet)}),this._announce(`Selected ${i}`)}_onKeydown(e){switch(e.key){case"ArrowDown":e.preventDefault(),this._moveActive(1);break;case"ArrowUp":e.preventDefault(),this._moveActive(-1);break;case"Home":e.preventDefault(),this._setActive(0);break;case"End":e.preventDefault(),this._setActive(this._items.length-1);break;case"PageDown":e.preventDefault(),this._moveActive(10);break;case"PageUp":e.preventDefault(),this._moveActive(-10);break;case"Enter":case" ":if(e.preventDefault(),this._activeIndex>=0){const e=this._items[this._activeIndex];this._onSelect(e,this._activeIndex)}break;case"Escape":e.preventDefault(),this._emit("close",{});break;default:1!==e.key.length||e.ctrlKey||e.altKey||e.metaKey||this._onType(e.key)}}_moveActive(e){const t=Math.max(0,Math.min(this._items.length-1,this._activeIndex+e));this._setActive(t)}_setActive(e){this._activeIndex=e,this.render(),this._scrollToActive(),this._announce(`Navigated to ${String(this._items[e])}`)}_scrollToActive(){const e=this._shadow.getElementById(`option-${this._activeIndex}`);e?.scrollIntoView({block:"nearest",inline:"nearest"})}_onType(e){this._typeTimeout&&window.clearTimeout(this._typeTimeout),this._typeBuffer+=e.toLowerCase(),this._typeTimeout=window.setTimeout(()=>{this._typeBuffer=""},400);const t=this._items.findIndex(e=>String(e).toLowerCase().startsWith(this._typeBuffer));t>=0&&this._setActive(t)}_announce(e){this._liveRegion&&(this._liveRegion.textContent=e,setTimeout(()=>{this._liveRegion&&(this._liveRegion.textContent="")},1e3))}focus(){this._listRoot.focus()}}customElements.define("smilodon-select",NativeSelectElement);const defaultConfig={selection:{mode:"single",allowDeselect:!1,maxSelections:0,showRemoveButton:!0,closeOnSelect:!0},scrollToSelected:{enabled:!0,multiSelectTarget:"first",behavior:"smooth",block:"nearest"},loadMore:{enabled:!1,itemsPerLoad:3,threshold:100,showLoader:!0},busyBucket:{enabled:!0,showSpinner:!0,message:"Loading...",minDisplayTime:200},styles:{classNames:{}},serverSide:{enabled:!1,getValueFromItem:e=>e?.value??e,getLabelFromItem:e=>e?.label??String(e)},infiniteScroll:{enabled:!1,pageSize:20,initialPage:1,cachePages:!0,maxCachedPages:10,preloadAdjacent:!0,scrollRestoration:"auto"},expandable:{enabled:!1,collapsedHeight:"300px",expandedHeight:"500px",expandLabel:"Show more",collapseLabel:"Show less"},callbacks:{},enabled:!0,searchable:!1,placeholder:"Select an option...",virtualize:!0,estimatedItemHeight:48};class SelectConfigManager{constructor(){this.config=this.deepClone(defaultConfig)}getConfig(){return this.config}updateConfig(e){this.config=this.deepMerge(this.config,e)}resetConfig(){this.config=this.deepClone(defaultConfig)}mergeWithComponentConfig(e){return this.deepMerge(this.deepClone(this.config),e)}deepClone(e){return JSON.parse(JSON.stringify(e))}deepMerge(e,t){const n={...e};for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)){const s=t[e],i=n[e];s&&"object"==typeof s&&!Array.isArray(s)?n[e]=this.deepMerge(i&&"object"==typeof i?i:{},s):n[e]=s}return n}}const selectConfig=new SelectConfigManager;function configureSelect(e){selectConfig.updateConfig(e)}function resetSelectConfig(){selectConfig.resetConfig()}class SelectOption extends HTMLElement{constructor(e){super(),this._config=e,this._shadow=this.attachShadow({mode:"open"}),this._container=document.createElement("div"),this._container.className="option-container",this._initializeStyles(),this._render(),this._attachEventListeners(),this._shadow.appendChild(this._container)}_initializeStyles(){const e=document.createElement("style");e.textContent="\n :host {\n display: block;\n position: relative;\n }\n \n .option-container {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n cursor: pointer;\n user-select: none;\n transition: background-color 0.2s ease;\n }\n \n .option-container:hover {\n background-color: var(--select-option-hover-bg, #f0f0f0);\n }\n \n .option-container.selected {\n background-color: var(--select-option-selected-bg, #e3f2fd);\n color: var(--select-option-selected-color, #1976d2);\n }\n \n .option-container.active {\n outline: 2px solid var(--select-option-active-outline, #1976d2);\n outline-offset: -2px;\n }\n \n .option-container.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n \n .option-content {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n \n .remove-button {\n margin-left: 8px;\n padding: 2px 6px;\n border: none;\n background-color: var(--select-remove-btn-bg, transparent);\n color: var(--select-remove-btn-color, #666);\n cursor: pointer;\n border-radius: 3px;\n font-size: 16px;\n line-height: 1;\n transition: all 0.2s ease;\n }\n \n .remove-button:hover {\n background-color: var(--select-remove-btn-hover-bg, #ffebee);\n color: var(--select-remove-btn-hover-color, #c62828);\n }\n \n .remove-button:focus {\n outline: 2px solid var(--select-remove-btn-focus-outline, #1976d2);\n outline-offset: 2px;\n }\n ",this._shadow.appendChild(e)}_render(){const{item:e,index:t,selected:n,disabled:s,active:i,render:o,showRemoveButton:r}=this._config;this._container.innerHTML="",this._container.classList.toggle("selected",n),this._container.classList.toggle("disabled",s||!1),this._container.classList.toggle("active",i||!1),this._config.className&&(this._container.className+=" "+this._config.className),this._config.style&&Object.assign(this._container.style,this._config.style);const a=document.createElement("div");if(a.className="option-content",o){const n=o(e,t);"string"==typeof n?a.innerHTML=n:a.appendChild(n)}else{const e=this._getLabel();a.textContent=e}this._container.appendChild(a),r&&n&&(this._removeButton=document.createElement("button"),this._removeButton.className="remove-button",this._removeButton.innerHTML="×",this._removeButton.setAttribute("aria-label","Remove option"),this._removeButton.setAttribute("type","button"),this._container.appendChild(this._removeButton)),this.setAttribute("role","option"),this.setAttribute("aria-selected",String(n)),s&&this.setAttribute("aria-disabled","true"),this.id=this._config.id||`select-option-${t}`}_attachEventListeners(){this._container.addEventListener("click",e=>{e.target!==this._removeButton&&(this._config.disabled||this._handleSelect())}),this._removeButton&&this._removeButton.addEventListener("click",e=>{e.stopPropagation(),this._handleRemove()}),this.addEventListener("keydown",e=>{this._config.disabled||("Enter"===e.key||" "===e.key?(e.preventDefault(),this._handleSelect()):"Delete"!==e.key&&"Backspace"!==e.key||this._config.selected&&this._config.showRemoveButton&&(e.preventDefault(),this._handleRemove()))})}_handleSelect(){const e={item:this._config.item,index:this._config.index,value:this._getValue(),label:this._getLabel(),selected:!this._config.selected};this.dispatchEvent(new CustomEvent("optionSelect",{detail:e,bubbles:!0,composed:!0}))}_handleRemove(){const e={item:this._config.item,index:this._config.index,value:this._getValue(),label:this._getLabel(),selected:!1};this.dispatchEvent(new CustomEvent("optionRemove",{detail:e,bubbles:!0,composed:!0}))}_getValue(){return this._config.getValue?this._config.getValue(this._config.item):this._config.item?.value??this._config.item}_getLabel(){return this._config.getLabel?this._config.getLabel(this._config.item):this._config.item?.label??String(this._config.item)}updateConfig(e){this._config={...this._config,...e},this._render(),this._attachEventListeners()}getConfig(){return this._config}getValue(){return this._getValue()}getLabel(){return this._getLabel()}setSelected(e){this._config.selected=e,this._render()}setActive(e){this._config.active=e,this._render()}setDisabled(e){this._config.disabled=e,this._render()}}customElements.get("select-option")||customElements.define("select-option",SelectOption);class EnhancedSelect extends HTMLElement{constructor(){super(),this._pageCache={},this._typeBuffer="",this._hasError=!1,this._errorMessage="",this._boundArrowClick=null,this._pendingFirstRenderMark=!1,this._pendingSearchRenderMark=!1,this._rangeAnchorIndex=null,this._shadow=this.attachShadow({mode:"open"}),this._uniqueId=`enhanced-select-${Math.random().toString(36).substr(2,9)}`,this._rendererHelpers=this._buildRendererHelpers(),this._config=selectConfig.getConfig(),this._state={isOpen:!1,isBusy:!1,isSearching:!1,currentPage:this._config.infiniteScroll.initialPage||1,totalPages:1,selectedIndices:new Set,selectedItems:new Map,activeIndex:-1,searchQuery:"",loadedItems:[],groupedItems:[],preserveScrollPosition:!1,lastScrollPosition:0,lastNotifiedQuery:null,lastNotifiedResultCount:0,isExpanded:!1},this._container=this._createContainer(),this._inputContainer=this._createInputContainer(),this._input=this._createInput(),this._arrowContainer=this._createArrowContainer(),this._dropdown=this._createDropdown(),this._optionsContainer=this._createOptionsContainer(),this._liveRegion=this._createLiveRegion(),this._initializeStyles(),this._assembleDOM(),this._attachEventListeners(),this._initializeObservers()}connectedCallback(){this.style.display="block",this.style.width="100%",this._config.serverSide.enabled&&this._config.serverSide.initialSelectedValues&&this._loadInitialSelectedItems(),this._config.callbacks.onOpen&&this._config.callbacks.onOpen()}disconnectedCallback(){this._resizeObserver?.disconnect(),this._intersectionObserver?.disconnect(),this._busyTimeout&&clearTimeout(this._busyTimeout),this._typeTimeout&&clearTimeout(this._typeTimeout),this._searchTimeout&&clearTimeout(this._searchTimeout),this._boundArrowClick&&this._arrowContainer&&this._arrowContainer.removeEventListener("click",this._boundArrowClick)}_createContainer(){const e=document.createElement("div");return e.className="select-container",this._config.styles.classNames?.container&&(e.className+=" "+this._config.styles.classNames.container),this._config.styles.container&&Object.assign(e.style,this._config.styles.container),e}_createInputContainer(){const e=document.createElement("div");return e.className="input-container",e}_createInput(){const e=document.createElement("input");return e.type="text",e.className="select-input",e.id=`${this._uniqueId}-input`,e.placeholder=this._config.placeholder||"Select an option...",e.disabled=!this._config.enabled,e.readOnly=!this._config.searchable,e.addEventListener("focus",()=>{this._config.searchable&&(e.readOnly=!1)}),this._config.styles.classNames?.input&&(e.className+=" "+this._config.styles.classNames.input),this._config.styles.input&&Object.assign(e.style,this._config.styles.input),e.setAttribute("role","combobox"),e.setAttribute("aria-expanded","false"),e.setAttribute("aria-haspopup","listbox"),e.setAttribute("aria-autocomplete",this._config.searchable?"list":"none"),e}_createDropdown(){const e=document.createElement("div");return e.className="select-dropdown",e.style.display="none",this._config.styles.classNames?.dropdown&&(e.className+=" "+this._config.styles.classNames.dropdown),this._config.styles.dropdown&&Object.assign(e.style,this._config.styles.dropdown),e.setAttribute("role","listbox"),e.setAttribute("aria-labelledby",`${this._uniqueId}-input`),"multi"===this._config.selection.mode&&e.setAttribute("aria-multiselectable","true"),e}_createOptionsContainer(){const e=document.createElement("div");return e.className="options-container",e}_createLiveRegion(){const e=document.createElement("div");return e.setAttribute("role","status"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),e.style.cssText="position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;",e}_createArrowContainer(){const e=document.createElement("div");return e.className="dropdown-arrow-container",e.innerHTML='\n <svg class="dropdown-arrow" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ',e}_assembleDOM(){this._inputContainer.appendChild(this._input),this._arrowContainer&&this._inputContainer.appendChild(this._arrowContainer),this._container.appendChild(this._inputContainer),this._dropdown.appendChild(this._optionsContainer),this._container.appendChild(this._dropdown),this._shadow.appendChild(this._container),this._liveRegion&&this._shadow.appendChild(this._liveRegion);const e=`${this._uniqueId}-listbox`;this._dropdown.id=e,this._input.setAttribute("aria-controls",e),this._input.setAttribute("aria-owns",e)}_initializeStyles(){const e=document.createElement("style");e.textContent='\n :host {\n display: block;\n position: relative;\n width: 100%;\n }\n \n .select-container {\n position: relative;\n width: 100%;\n }\n \n .input-container {\n position: relative;\n width: 100%;\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--select-input-gap, 6px);\n padding: var(--select-input-padding, 6px 52px 6px 8px);\n min-height: var(--select-input-min-height, 44px);\n max-height: var(--select-input-max-height, 160px);\n overflow-y: var(--select-input-overflow-y, auto);\n align-content: flex-start;\n background: var(--select-input-bg, white);\n border: var(--select-input-border, 1px solid #d1d5db);\n border-radius: var(--select-input-border-radius, 6px);\n box-sizing: border-box;\n transition: all 0.2s ease;\n }\n \n .input-container:focus-within {\n border-color: var(--select-input-focus-border, #667eea);\n box-shadow: var(--select-input-focus-shadow, 0 0 0 3px rgba(102, 126, 234, 0.1));\n }\n \n /* Gradient separator before arrow */\n .input-container::after {\n content: \'\';\n position: absolute;\n top: 50%;\n right: var(--select-separator-position, 40px);\n transform: translateY(-50%);\n width: var(--select-separator-width, 1px);\n height: var(--select-separator-height, 60%);\n background: var(--select-separator-bg, var(--select-separator-gradient, linear-gradient(\n to bottom,\n transparent 0%,\n rgba(0, 0, 0, 0.1) 20%,\n rgba(0, 0, 0, 0.1) 80%,\n transparent 100%\n )));\n pointer-events: none;\n z-index: 1;\n }\n \n .dropdown-arrow-container {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: var(--select-arrow-width, 40px);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: background-color 0.2s ease;\n border-radius: var(--select-arrow-border-radius, 0 4px 4px 0);\n z-index: 2;\n }\n \n .dropdown-arrow-container:hover {\n background-color: var(--select-arrow-hover-bg, rgba(102, 126, 234, 0.08));\n }\n \n .dropdown-arrow {\n width: var(--select-arrow-size, 16px);\n height: var(--select-arrow-size, 16px);\n color: var(--select-arrow-color, #667eea);\n transition: transform 0.2s ease, color 0.2s ease;\n transform: translateY(0);\n }\n \n .dropdown-arrow path {\n stroke-width: var(--select-arrow-stroke-width, 2);\n }\n \n .dropdown-arrow-container:hover .dropdown-arrow {\n color: var(--select-arrow-hover-color, #667eea);\n }\n \n .dropdown-arrow.open {\n transform: rotate(180deg);\n }\n \n .select-input {\n flex: 1;\n min-width: var(--select-input-min-width, 120px);\n padding: var(--select-input-field-padding, 4px);\n border: none;\n font-size: var(--select-input-font-size, 14px);\n line-height: var(--select-input-line-height, 1.5);\n color: var(--select-input-color, #1f2937);\n background: transparent;\n box-sizing: border-box;\n outline: none;\n font-family: var(--select-font-family, inherit);\n }\n \n .select-input::placeholder {\n color: var(--select-input-placeholder-color, #9ca3af);\n }\n \n .selection-badge {\n display: inline-flex;\n align-items: center;\n gap: var(--select-badge-gap, 4px);\n padding: var(--select-badge-padding, 4px 8px);\n margin: var(--select-badge-margin, 2px);\n background: var(--select-badge-bg, #667eea);\n color: var(--select-badge-color, white);\n border-radius: var(--select-badge-border-radius, 4px);\n font-size: var(--select-badge-font-size, 13px);\n line-height: 1;\n max-width: var(--select-badge-max-width, 100%);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n \n .badge-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--select-badge-remove-size, 16px);\n height: var(--select-badge-remove-size, 16px);\n padding: 0;\n margin-left: 4px;\n background: var(--select-badge-remove-bg, rgba(255, 255, 255, 0.3));\n border: none;\n border-radius: 50%;\n color: var(--select-badge-remove-color, white);\n font-size: var(--select-badge-remove-font-size, 16px);\n line-height: 1;\n cursor: pointer;\n transition: background 0.2s;\n }\n \n .badge-remove:hover {\n background: var(--select-badge-remove-hover-bg, rgba(255, 255, 255, 0.5));\n }\n\n .badge-remove:focus-visible {\n outline: 2px solid var(--select-badge-remove-focus-outline, rgba(255, 255, 255, 0.8));\n outline-offset: 2px;\n }\n \n .select-input:disabled {\n background-color: var(--select-disabled-bg, #f5f5f5);\n cursor: not-allowed;\n }\n \n .select-dropdown {\n position: absolute;\n scroll-behavior: smooth;\n top: 100%;\n left: 0;\n right: 0;\n margin-top: var(--select-dropdown-margin-top, 4px);\n max-height: var(--select-dropdown-max-height, 300px);\n overflow: hidden;\n background: var(--select-dropdown-bg, white);\n border: var(--select-dropdown-border, 1px solid #ccc);\n border-radius: var(--select-dropdown-border-radius, 4px);\n box-shadow: var(--select-dropdown-shadow, 0 4px 6px rgba(0,0,0,0.1));\n z-index: var(--select-dropdown-z-index, 1000);\n }\n \n .options-container {\n position: relative;\n max-height: var(--select-options-max-height, 300px);\n overflow: auto;\n transition: opacity 0.2s ease-in-out;\n background: var(--select-options-bg, white);\n }\n\n .option {\n padding: var(--select-option-padding, 8px 12px);\n cursor: pointer;\n color: var(--select-option-color, #1f2937);\n background: var(--select-option-bg, white);\n transition: var(--select-option-transition, background-color 0.15s ease);\n user-select: none;\n font-size: var(--select-option-font-size, 14px);\n line-height: var(--select-option-line-height, 1.5);\n border: var(--select-option-border, none);\n border-bottom: var(--select-option-border-bottom, none);\n }\n\n .option:hover {\n background-color: var(--select-option-hover-bg, #f3f4f6);\n color: var(--select-option-hover-color, #1f2937);\n }\n\n .option.selected {\n background-color: var(--select-option-selected-bg, #e0e7ff);\n color: var(--select-option-selected-color, #4338ca);\n font-weight: var(--select-option-selected-weight, 500);\n }\n\n .option.active {\n background-color: var(--select-option-active-bg, #f3f4f6);\n color: var(--select-option-active-color, #1f2937);\n outline: var(--select-option-active-outline, 2px solid rgba(99, 102, 241, 0.45));\n outline-offset: -2px;\n }\n\n .option:active {\n background-color: var(--select-option-pressed-bg, #e5e7eb);\n }\n \n .load-more-container {\n padding: var(--select-load-more-padding, 12px);\n text-align: center;\n border-top: var(--select-divider-border, 1px solid #e0e0e0);\n background: var(--select-load-more-bg, white);\n }\n \n .load-more-button {\n padding: var(--select-button-padding, 8px 16px);\n border: var(--select-button-border, 1px solid #1976d2);\n background: var(--select-button-bg, white);\n color: var(--select-button-color, #1976d2);\n border-radius: var(--select-button-border-radius, 4px);\n cursor: pointer;\n font-size: var(--select-button-font-size, 14px);\n font-family: var(--select-font-family, inherit);\n transition: all 0.2s ease;\n }\n \n .load-more-button:hover {\n background: var(--select-button-hover-bg, #1976d2);\n color: var(--select-button-hover-color, white);\n }\n \n .load-more-button:disabled {\n opacity: var(--select-button-disabled-opacity, 0.5);\n cursor: not-allowed;\n }\n \n .busy-bucket {\n padding: var(--select-busy-padding, 16px);\n text-align: center;\n color: var(--select-busy-color, #666);\n background: var(--select-busy-bg, white);\n font-size: var(--select-busy-font-size, 14px);\n }\n \n .spinner {\n display: inline-block;\n width: var(--select-spinner-size, 20px);\n height: var(--select-spinner-size, 20px);\n border: var(--select-spinner-border, 2px solid #ccc);\n border-top-color: var(--select-spinner-active-color, #1976d2);\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n }\n \n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n \n .empty-state {\n padding: var(--select-empty-padding, 24px);\n text-align: center;\n color: var(--select-empty-color, #6b7280);\n font-size: var(--select-empty-font-size, 14px);\n background: var(--select-empty-bg, white);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 6px;\n min-height: var(--select-empty-min-height, 72px);\n }\n \n .searching-state {\n padding: var(--select-searching-padding, 24px);\n text-align: center;\n color: var(--select-searching-color, #667eea);\n font-size: var(--select-searching-font-size, 14px);\n font-style: italic;\n background: var(--select-searching-bg, white);\n animation: pulse 1.5s ease-in-out infinite;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 6px;\n min-height: var(--select-searching-min-height, 72px);\n }\n \n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n \n /* Error states */\n .select-input[aria-invalid="true"] {\n border-color: var(--select-error-border, #dc2626);\n }\n \n .select-input[aria-invalid="true"]:focus {\n border-color: var(--select-error-border, #dc2626);\n box-shadow: 0 0 0 2px var(--select-error-shadow, rgba(220, 38, 38, 0.1));\n outline-color: var(--select-error-border, #dc2626);\n }\n \n /* Accessibility: Reduced motion */\n @media (prefers-reduced-motion: reduce) {\n * {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n }\n \n /* Dark mode - Opt-in via class or data attribute */\n :host(.dark-mode),\n :host([data-theme="dark"]) {\n .input-container {\n background: var(--select-dark-bg, #1f2937);\n border-color: var(--select-dark-border, #4b5563);\n }\n \n .select-input {\n color: var(--select-dark-text, #f9fafb);\n }\n \n .select-input::placeholder {\n color: var(--select-dark-placeholder, #6b7280);\n }\n \n .select-dropdown {\n background: var(--select-dark-dropdown-bg, #1f2937);\n border-color: var(--select-dark-dropdown-border, #4b5563);\n }\n \n .options-container {\n background: var(--select-dark-options-bg, #1f2937);\n }\n \n .option {\n color: var(--select-dark-option-color, #f9fafb);\n background: var(--select-dark-option-bg, #1f2937);\n }\n \n .option:hover {\n background-color: var(--select-dark-option-hover-bg, #374151);\n color: var(--select-dark-option-hover-color, #f9fafb);\n }\n \n .option.selected {\n background-color: var(--select-dark-option-selected-bg, #3730a3);\n color: var(--select-dark-option-selected-text, #e0e7ff);\n }\n \n .option.active {\n background-color: var(--select-dark-option-active-bg, #374151);\n color: var(--select-dark-option-active-color, #f9fafb);\n outline: var(--select-dark-option-active-outline, 2px solid rgba(129, 140, 248, 0.55));\n }\n\n .selection-badge {\n background: var(--select-dark-badge-bg, #4f46e5);\n color: var(--select-dark-badge-color, #eef2ff);\n }\n\n .badge-remove {\n background: var(--select-dark-badge-remove-bg, rgba(255, 255, 255, 0.15));\n color: var(--select-dark-badge-remove-color, #e5e7eb);\n }\n\n .badge-remove:hover {\n background: var(--select-dark-badge-remove-hover-bg, rgba(255, 255, 255, 0.3));\n }\n \n .busy-bucket,\n .empty-state {\n color: var(--select-dark-busy-color, #9ca3af);\n background: var(--select-dark-empty-bg, #111827);\n }\n\n .searching-state {\n background: var(--select-dark-searching-bg, #111827);\n }\n \n .input-container::after {\n background: linear-gradient(\n to bottom,\n transparent 0%,\n rgba(255, 255, 255, 0.1) 20%,\n rgba(255, 255, 255, 0.1) 80%,\n transparent 100%\n );\n }\n }\n \n /* Accessibility: High contrast mode */\n @media (prefers-contrast: high) {\n .select-input:focus {\n outline-width: 3px;\n outline-color: Highlight;\n }\n \n .select-input {\n border-width: 2px;\n }\n }\n \n /* Touch targets (WCAG 2.5.5) */\n .load-more-button,\n select-option {\n min-height: 44px;\n }\n ',this._shadow.firstChild?this._shadow.insertBefore(e,this._shadow.firstChild):this._shadow.appendChild(e)}_attachEventListeners(){this._arrowContainer&&(this._boundArrowClick=e=>{e.stopPropagation(),e.preventDefault();const t=this._state.isOpen;this._state.isOpen=!this._state.isOpen,this._updateDropdownVisibility(),this._updateArrowRotation(),this._state.isOpen&&this._config.callbacks.onOpen?this._config.callbacks.onOpen():!this._state.isOpen&&this._config.callbacks.onClose&&this._config.callbacks.onClose(),!t&&this._state.isOpen&&this._state.selectedIndices.size>0&&setTimeout(()=>this._scrollToSelected(),50)},this._arrowContainer.addEventListener("click",this._boundArrowClick)),this._inputContainer.addEventListener("pointerdown",e=>{const t=e.target;this._config.enabled&&(t&&t.closest(".dropdown-arrow-container")||(this._state.isOpen||this._handleOpen(),this._input.focus()))}),this._container.addEventListener("click",e=>{e.stopPropagation()}),this._input.addEventListener("focus",()=>this._handleOpen()),this._input.addEventListener("blur",e=>{const t=e.relatedTarget;t&&(this._shadow.contains(t)||this._container.contains(t))||setTimeout(()=>{const e=document.activeElement;e&&(this._shadow.contains(e)||this._container.contains(e))||this._handleClose()},0)}),this._input.addEventListener("input",e=>{if(!this._config.searchable)return;const t=e.target.value;this._handleSearch(t)}),this._input.addEventListener("keydown",e=>this._handleKeydown(e)),document.addEventListener("pointerdown",e=>{const t=e.composedPath&&e.composedPath()||[];t.includes(this)||t.includes(this._container)||this._shadow.contains(e.target)||this._handleClose()})}_initializeObservers(){this._intersectionObserver&&(this._intersectionObserver.disconnect(),this._intersectionObserver=void 0),this._config.infiniteScroll.enabled&&(this._intersectionObserver=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting&&(this._state.isBusy||this._loadMoreItems())})},{threshold:.1}))}async _loadInitialSelectedItems(){if(this._config.serverSide.fetchSelectedItems&&this._config.serverSide.initialSelectedValues){this._setBusy(!0);try{(await this._config.serverSide.fetchSelectedItems(this._config.serverSide.initialSelectedValues)).forEach((e,t)=>{this._state.selectedItems.set(t,e),this._state.selectedIndices.add(t)}),this._updateInputDisplay()}catch(e){this._handleError(e)}finally{this._setBusy(!1)}}}_handleOpen(){this._config.enabled&&!this._state.isOpen&&(this._markOpenStart(),this._state.isOpen=!0,this._dropdown.style.display="block",this._input.setAttribute("aria-expanded","true"),this._updateArrowRotation(),this._config.searchable&&(this._state.searchQuery=""),this._renderOptions(),this._setInitialActiveOption(),this._emit("open",{}),this._config.callbacks.onOpen?.(),this._announce("Options expanded"),this._config.scrollToSelected.enabled&&requestAnimationFrame(()=>{requestAnimationFrame(()=>{this._scrollToSelected()})}))}_handleClose(){this._state.isOpen&&(this._state.isOpen=!1,this._dropdown.style.display="none",this._input.setAttribute("aria-expanded","false"),this._input.removeAttribute("aria-activedescendant"),this._updateArrowRotation(),this._emit("close",{}),this._config.callbacks.onClose?.(),this._announce("Options collapsed"))}_updateDropdownVisibility(){this._state.isOpen?(this._dropdown.style.display="block",this._input.setAttribute("aria-expanded","true")):(this._dropdown.style.display="none",this._input.setAttribute("aria-expanded","false"))}_updateArrowRotation(){if(this._arrowContainer){const e=this._arrowContainer.querySelector(".dropdown-arrow");e&&(this._state.isOpen?e.classList.add("open"):e.classList.remove("open"))}}_isPerfEnabled(){return"undefined"!=typeof globalThis&&!0===globalThis.__SMILODON_DEV__&&"undefined"!=typeof performance&&"function"==typeof performance.mark&&"function"==typeof performance.measure}_perfMark(e){this._isPerfEnabled()&&performance.mark(e)}_perfMeasure(e,t,n){this._isPerfEnabled()&&performance.measure(e,t,n)}_markOpenStart(){this._isPerfEnabled()&&(this._pendingFirstRenderMark=!0,this._perfMark("smilodon-dropdown-open-start"))}_finalizePerfMarks(){if(!this._isPerfEnabled())return this._pendingFirstRenderMark=!1,void(this._pendingSearchRenderMark=!1);this._pendingFirstRenderMark&&(this._pendingFirstRenderMark=!1,this._perfMark("smilodon-first-render-complete"),this._perfMeasure("smilodon-dropdown-to-first-render","smilodon-dropdown-open-start","smilodon-first-render-complete")),this._pendingSearchRenderMark&&(this._pendingSearchRenderMark=!1,this._perfMark("smilodon-search-render-complete"),this._perfMeasure("smilodon-search-to-render","smilodon-search-input-last","smilodon-search-render-complete"))}_handleSearch(e){this._state.searchQuery=e,e.length>0?(this._perfMark("smilodon-search-input-last"),this._pendingSearchRenderMark=!0):this._pendingSearchRenderMark=!1,this._searchTimeout&&clearTimeout(this._searchTimeout),this._state.isSearching=!1,this._state.isOpen?this._renderOptions():this._handleOpen();const t=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e)),n=e.toLowerCase(),s=n?this._state.loadedItems.filter(e=>{try{return String(t(e)).toLowerCase().includes(n)}catch(e){return!1}}):this._state.loadedItems,i=s.length;n&&this._announce(`${i} result${1!==i?"s":""} found for "${e}"`),e===this._state.lastNotifiedQuery&&i===this._state.lastNotifiedResultCount||(this._state.lastNotifiedQuery=e,this._state.lastNotifiedResultCount=i,setTimeout(()=>{this._emit("search",{query:e,results:s,count:i}),this._config.callbacks.onSearch?.(e)},0))}_handleKeydown(e){switch(e.key){case"ArrowDown":e.preventDefault(),this._state.isOpen?this._moveActive(1,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey}):this._handleOpen();break;case"ArrowUp":e.preventDefault(),this._state.isOpen?this._moveActive(-1,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey}):this._handleOpen();break;case"Home":e.preventDefault(),this._state.isOpen&&(this._setActive(0),"multi"===this._config.selection.mode&&e.shiftKey&&this._selectRange(this._rangeAnchorIndex??0,0,{clear:!(e.ctrlKey||e.metaKey)}));break;case"End":if(e.preventDefault(),this._state.isOpen){const t=Array.from(this._optionsContainer.children),n=Math.max(0,t.length-1);this._setActive(n),"multi"===this._config.selection.mode&&e.shiftKey&&this._selectRange(this._rangeAnchorIndex??n,n,{clear:!(e.ctrlKey||e.metaKey)})}break;case"PageDown":e.preventDefault(),this._state.isOpen&&this._moveActive(10,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey});break;case"PageUp":e.preventDefault(),this._state.isOpen&&this._moveActive(-10,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey});break;case"Enter":e.preventDefault(),this._state.activeIndex>=0&&this._selectOption(this._state.activeIndex,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey});break;case"Escape":e.preventDefault(),this._handleClose();break;case"Tab":this._state.isOpen&&this._handleClose();break;case"a":case"A":(e.ctrlKey||e.metaKey)&&"multi"===this._config.selection.mode&&(e.preventDefault(),this._selectAll());break;default:1!==e.key.length||e.ctrlKey||e.altKey||e.metaKey||this._handleTypeAhead(e.key)}}_moveActive(e,t){const n=Array.from(this._optionsContainer.children),s=Math.max(0,Math.min(n.length-1,this._state.activeIndex+e));if(this._setActive(s),"multi"===this._config.selection.mode&&t?.shiftKey){const e=this._rangeAnchorIndex??this._state.activeIndex,n=e>=0?e:s;null===this._rangeAnchorIndex&&(this._rangeAnchorIndex=n),this._selectRange(n,s,{clear:!t?.toggleKey})}}_setActive(e){const t=Array.from(this._optionsContainer.children);if(this._state.activeIndex>=0&&t[this._state.activeIndex]){const e=t[this._state.activeIndex];"setActive"in e&&"function"==typeof e.setActive?e.setActive(!1):(e.classList.remove("smilodon-option--active"),e.setAttribute("aria-selected","false"))}if(this._state.activeIndex=e,t[e]){const n=t[e];"setActive"in n&&"function"==typeof n.setActive?n.setActive(!0):(n.classList.add("smilodon-option--active"),n.setAttribute("aria-selected","true")),n.scrollIntoView({block:"nearest",behavior:"smooth"});const s=t.length;this._announce(`Item ${e+1} of ${s}`);const i=n.id||`${this._uniqueId}-option-${e}`;this._input.setAttribute("aria-activedescendant",i)}}_getOptionElementByIndex(e){return this._optionsContainer.querySelector(`[data-index="${e}"]`)}_buildRendererHelpers(){return{onSelect:(e,t)=>this._selectOption(t),getIndex:e=>{const t=e?.closest?.("[data-selectable]");if(!t)return null;const n=Number(t.dataset.index);return Number.isFinite(n)?n:null},keyboardFocus:e=>{this._setActive(e);const t=this._getOptionElementByIndex(e);t?.focus?.()}}}_handleTypeAhead(e){this._typeTimeout&&clearTimeout(this._typeTimeout),this._typeBuffer+=e.toLowerCase(),this._typeTimeout=window.setTimeout(()=>{this._typeBuffer=""},500);const t=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e)),n=this._state.loadedItems.findIndex(e=>t(e).toLowerCase().startsWith(this._typeBuffer));n>=0&&this._setActive(n)}_selectAll(){if("multi"!==this._config.selection.mode)return;const e=Array.from(this._optionsContainer.children),t=this._config.selection.maxSelections||0;e.forEach((e,n)=>{if(!(t>0&&this._state.selectedIndices.size>=t||this._state.selectedIndices.has(n)))if("getConfig"in e&&"function"==typeof e.getConfig){const t=e.getConfig();this._state.selectedIndices.add(n),this._state.selectedItems.set(n,t.item),e.setSelected(!0)}else{const t=this._state.loadedItems[n];t&&(this._state.selectedIndices.add(n),this._state.selectedItems.set(n,t),e.classList.add("smilodon-option--selected"),e.setAttribute("aria-selected","true"))}}),this._updateInputDisplay(),this._emitChange(),this._announce(`Selected all ${e.length} items`)}_selectRange(e,t,n){if("multi"!==this._config.selection.mode)return;const s=this._config.selection.maxSelections||0,[i,o]=e<t?[e,t]:[t,e];n?.clear&&(this._state.selectedIndices.clear(),this._state.selectedItems.clear());for(let e=i;e<=o&&!(s>0&&this._state.selectedIndices.size>=s);e+=1){const t=this._state.loadedItems[e];t&&(this._state.selectedIndices.add(e),this._state.selectedItems.set(e,t))}this._renderOptions(),this._updateInputDisplay(),this._emitChange(),this._announce(`${this._state.selectedIndices.size} items selected`)}_setInitialActiveOption(){const e=Array.from(this._optionsContainer.children);if(0===e.length)return;const t=Array.from(this._state.selectedIndices).sort((e,t)=>e-t);if("multi"===this._config.selection.mode&&0===t.length)return this._state.activeIndex=-1,void this._input.removeAttribute("aria-activedescendant");const n=t.length>0?t[0]:0;this._setActive(Math.min(n,e.length-1))}_announce(e){this._liveRegion&&(this._liveRegion.textContent=e,setTimeout(()=>{this._liveRegion&&(this._liveRegion.textContent="")},1e3))}_selectOption(e,t){const n=this._state.loadedItems[e];if(!n)return;const s=this._state.selectedIndices.has(e);if("single"===this._config.selection.mode){const t=this._state.selectedIndices.has(e);this._state.selectedIndices.clear(),this._state.selectedItems.clear(),t||(this._state.selectedIndices.add(e),this._state.selectedItems.set(e,n)),this._renderOptions(),this._config.selection.closeOnSelect&&this._handleClose()}else{const i=Boolean(t?.toggleKey);if(Boolean(t?.shiftKey)){const t=this._rangeAnchorIndex??e;return this._selectRange(t,e,{clear:!i}),void(this._rangeAnchorIndex=t)}const o=this._config.selection.maxSelections||0;if(s)this._state.selectedIndices.delete(e),this._state.selectedItems.delete(e);else{if(o>0&&this._state.selectedIndices.size>=o)return void this._announce(`Maximum ${o} selections allowed`);this._state.selectedIndices.add(e),this._state.selectedItems.set(e,n)}this._renderOptions()}this._rangeAnchorIndex=e,this._updateInputDisplay(),this._emitChange();const i=this._config.serverSide.getValueFromItem||(e=>e?.value??e),o=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e)),r=o(n);if("single"===this._config.selection.mode)this._announce(`Selected ${r}`);else{const e=this._state.selectedIndices.size,t=s?"Deselected":"Selected";this._announce(`${t} ${r}. ${e} selected`)}this._config.callbacks.onSelect?.({item:n,index:e,value:i(n),label:o(n),selected:this._state.selectedIndices.has(e)})}_handleOptionRemove(e){const t=this._getOptionElementByIndex(e);if(!t)return;this._state.selectedIndices.delete(e),this._state.selectedItems.delete(e),t.setSelected(!1),this._updateInputDisplay(),this._emitChange();const n=t.getConfig();this._emit("remove",{item:n.item,index:e})}_updateInputDisplay(){const e=Array.from(this._state.selectedItems.values()),t=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e));if(0===e.length){this._input.value="",this._input.placeholder=this._config.placeholder||"Select an option...";this._inputContainer.querySelectorAll(".selection-badge").forEach(e=>e.remove())}else if("single"===this._config.selection.mode)this._input.value=t(e[0]);else{this._input.value="",this._input.placeholder="";this._inputContainer.querySelectorAll(".selection-badge").forEach(e=>e.remove());Array.from(this._state.selectedItems.entries()).forEach(([e,n])=>{const s=document.createElement("span");s.className="selection-badge",s.textContent=t(n);const i=document.createElement("button");i.className="badge-remove",i.innerHTML="×",i.setAttribute("aria-label",`Remove ${t(n)}`),i.addEventListener("click",t=>{t.stopPropagation(),this._state.selectedIndices.delete(e),this._state.selectedItems.delete(e),this._updateInputDisplay(),this._renderOptions(),this._emitChange()}),s.appendChild(i),this._inputContainer.insertBefore(s,this._input)})}}_renderOptionsWithAnimation(){this._optionsContainer.style.opacity="0",this._optionsContainer.style.transition="opacity 0.15s ease-out",setTimeout(()=>{this._renderOptions(),this._optionsContainer.style.opacity="1",this._optionsContainer.style.transition="opacity 0.2s ease-in"},150)}_scrollToSelected(){if(0===this._state.selectedIndices.size)return;const e=this._config.scrollToSelected.multiSelectTarget,t=Array.from(this._state.selectedIndices).sort((e,t)=>e-t);let n;if("multi"===this._config.selection.mode&&t.length>1){const e=this._dropdown.getBoundingClientRect(),s=this._dropdown.scrollTop+e.height/2;let i=t[0],o=1/0;for(const e of t){const t=this._getOptionElementByIndex(e);if(t){const n=t.offsetTop,r=Math.abs(n-s);r<o&&(o=r,i=e)}}n=i}else n="first"===e?t[0]:t[t.length-1];const s=this._getOptionElementByIndex(n);s&&(s.scrollIntoView({block:this._config.scrollToSelected.block||"center",behavior:"smooth"}),this._setActive(n))}async _loadMoreItems(){if(!this._state.isBusy){this._setBusy(!0),this._dropdown&&(this._state.lastScrollPosition=this._dropdown.scrollTop,this._state.preserveScrollPosition=!0,this._renderOptions(),this._dropdown.scrollTop=this._state.lastScrollPosition);try{this._state.currentPage++,this._emit("loadMore",{page:this._state.currentPage,items:[]}),this._config.callbacks.onLoadMore?.(this._state.currentPage)}catch(e){this._handleError(e),this._setBusy(!1)}}}_setBusy(e){this._state.isBusy=e,e?this._dropdown.setAttribute("aria-busy","true"):this._dropdown.removeAttribute("aria-busy"),this._renderOptions()}_handleError(e){this._emit("error",{message:e.message,cause:e}),this._config.callbacks.onError?.(e)}_emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}_emitChange(){const e=Array.from(this._state.selectedItems.values()),t=this._config.serverSide.getValueFromItem||(e=>e?.value??e),n=e.map(t),s=Array.from(this._state.selectedIndices);this._emit("change",{selectedItems:e,selectedValues:n,selectedIndices:s}),this._config.callbacks.onChange?.(e,n)}get optionRenderer(){return this._optionRenderer}set optionRenderer(e){this._optionRenderer=e,this._renderOptions()}setItems(e){const t=this._state.loadedItems.length;this._state.loadedItems=e,this._state.groupedItems.length>0&&(this._state.loadedItems=this._state.groupedItems.flatMap(e=>e.options));const n=this._state.loadedItems.length;if(this._state.preserveScrollPosition&&this._dropdown){const e=this._state.lastScrollPosition;n>t&&(this._state.isBusy=!1),this._renderOptions(),this._dropdown.scrollTop=e,requestAnimationFrame(()=>{this._dropdown&&(this._dropdown.scrollTop=e)}),n>t&&(this._state.preserveScrollPosition=!1)}else this._state.isBusy=!1,this._renderOptions()}setGroupedItems(e){this._state.groupedItems=e,this._state.loadedItems=e.flatMap(e=>e.options),this._renderOptions()}getSelectedItems(){return Array.from(this._state.selectedItems.values())}get loadedItems(){return this._state.loadedItems}getSelectedValues(){const e=this._config.serverSide.getValueFromItem||(e=>e?.value??e);return this.getSelectedItems().map(e)}async setSelectedValues(e){if(this._config.serverSide.enabled&&this._config.serverSide.fetchSelectedItems)await this._loadSelectedItemsByValues(e);else{const t=this._config.serverSide.getValueFromItem||(e=>e?.value??e);this._state.selectedIndices.clear(),this._state.selectedItems.clear(),this._state.loadedItems.forEach((n,s)=>{e.includes(t(n))&&(this._state.selectedIndices.add(s),this._state.selectedItems.set(s,n))}),this._renderOptions(),this._updateInputDisplay(),this._emitChange()}}async _loadSelectedItemsByValues(e){if(this._config.serverSide.fetchSelectedItems){this._setBusy(!0);try{const t=await this._config.serverSide.fetchSelectedItems(e);this._state.selectedIndices.clear(),this._state.selectedItems.clear(),t.forEach((e,t)=>{this._state.selectedIndices.add(t),this._state.selectedItems.set(t,e)}),this._renderOptions(),this._updateInputDisplay(),this._emitChange(),this._config.scrollToSelected.enabled&&this._scrollToSelected()}catch(e){this._handleError(e)}finally{this._setBusy(!1)}}}clear(){this._state.selectedIndices.clear(),this._state.selectedItems.clear(),this._renderOptions(),this._updateInputDisplay(),this._emitChange()}open(){this._handleOpen()}close(){this._handleClose()}updateConfig(e){this._config=selectConfig.mergeWithComponentConfig(e),this._input&&(this._input.readOnly=!this._config.searchable,this._input.setAttribute("aria-autocomplete",this._config.searchable?"list":"none"),0===this._state.selectedIndices.size&&(this._input.placeholder=this._config.placeholder||"Select an option...")),this._dropdown&&("multi"===this._config.selection.mode?this._dropdown.setAttribute("aria-multiselectable","true"):this._dropdown.removeAttribute("aria-multiselectable")),this._initializeObservers(),this._renderOptions()}setError(e){this._hasError=!0,this._errorMessage=e,this._input.setAttribute("aria-invalid","true"),this._announce(`Error: ${e}`)}clearError(){this._hasError=!1,this._errorMessage="",this._input.removeAttribute("aria-invalid")}setRequired(e){e?(this._input.setAttribute("aria-required","true"),this._input.setAttribute("required","")):(this._input.removeAttribute("aria-required"),this._input.removeAttribute("required"))}validate(){return this._input.hasAttribute("required")&&0===this._state.selectedIndices.size?(this.setError("Selection is required"),!1):(this.clearError(),!0)}_renderOptions(){if(this._loadMoreTrigger&&this._intersectionObserver&&this._intersectionObserver.unobserve(this._loadMoreTrigger),this._optionsContainer.innerHTML="",Array.from(this._dropdown.children).forEach(e=>{e!==this._optionsContainer&&this._dropdown.removeChild(e)}),this._state.isOpen&&"none"===this._dropdown.style.display&&(this._dropdown.style.display="block"),this._state.isSearching){const e=document.createElement("div");return e.className="searching-state",e.textContent="Searching...",void this._optionsContainer.appendChild(e)}const e=this._config.serverSide.getValueFromItem||(e=>e?.value??e),t=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e)),n=this._state.searchQuery.toLowerCase();if(this._state.groupedItems.length>0&&!n)this._state.groupedItems.forEach(n=>{const s=document.createElement("div");s.className="group-header",s.textContent=n.label,Object.assign(s.style,{padding:"8px 12px",fontWeight:"600",color:"#6b7280",backgroundColor:"#f3f4f6",fontSize:"12px",textTransform:"uppercase",letterSpacing:"0.05em",position:"sticky",top:"0",zIndex:"1",borderBottom:"1px solid #e5e7eb"}),this._optionsContainer.appendChild(s),n.options.forEach(n=>{const s=this._state.loadedItems.indexOf(n);-1!==s&&this._renderSingleOption(n,s,e,t)})});else{let s=!1;if(this._state.loadedItems.forEach((i,o)=>{if(n)try{if(!String(t(i)).toLowerCase().includes(n))return}catch(e){return}s=!0,this._renderSingleOption(i,o,e,t)}),!s&&!this._state.isBusy){const e=document.createElement("div");e.className="empty-state",e.textContent=n?`No results found for "${this._state.searchQuery}"`:"No options available",this._optionsContainer.appendChild(e)}}if(this._state.isBusy&&this._config.busyBucket.enabled){const e=document.createElement("div");if(e.className="busy-bucket",this._config.busyBucket.showSpinner){const t=document.createElement("div");t.className="spinner",e.appendChild(t)}if(this._config.busyBucket.message){const t=document.createElement("div");t.textContent=this._config.busyBucket.message,e.appendChild(t)}this._optionsContainer.appendChild(e)}else(this._config.loadMore.enabled||this._config.infiniteScroll.enabled)&&this._state.loadedItems.length>0&&this._addLoadMoreTrigger();this._finalizePerfMarks()}_renderSingleOption(e,t,n,s){const i=this._state.selectedIndices.has(t),o=Boolean(e?.disabled),r=`${this._uniqueId}-option-${t}`;if(this._optionRenderer){const a=this._optionRenderer(e,t,this._rendererHelpers),l=this._normalizeCustomOptionElement(a,{index:t,value:n(e),label:s(e),selected:i,active:this._state.activeIndex===t,disabled:o,id:r});return void this._optionsContainer.appendChild(l)}const a=new SelectOption({item:e,index:t,id:r,selected:i,disabled:o,active:this._state.activeIndex===t,getValue:n,getLabel:s,showRemoveButton:"multi"===this._config.selection.mode&&this._config.selection.showRemoveButton});a.dataset.index=String(t),a.dataset.value=String(n(e)),a.id=a.id||r,a.addEventListener("click",e=>{const n=e;this._selectOption(t,{shiftKey:n.shiftKey,toggleKey:n.ctrlKey||n.metaKey})}),a.addEventListener("optionRemove",e=>{const n=e.detail,s=n?.index??t;this._handleOptionRemove(s)}),this._optionsContainer.appendChild(a)}_normalizeCustomOptionElement(e,t){const n=e instanceof HTMLElement?e:document.createElement("div");n.classList.add("smilodon-option","option");const s=t.selected,i=t.active,o=t.disabled;return s?n.classList.add("smilodon-option--selected","selected"):n.classList.remove("smilodon-option--selected","selected"),i?n.classList.add("smilodon-option--active","active"):n.classList.remove("smilodon-option--active","active"),o?n.classList.add("smilodon-option--disabled","disabled"):n.classList.remove("smilodon-option--disabled","disabled"),n.hasAttribute("data-selectable")||n.setAttribute("data-selectable",""),n.dataset.index=String(t.index),n.dataset.value=String(t.value),n.id=n.id||t.id,n.getAttribute("role")||n.setAttribute("role","option"),n.getAttribute("aria-label")||n.setAttribute("aria-label",t.label),n.setAttribute("aria-selected",String(t.selected)),t.disabled?n.setAttribute("aria-disabled","true"):n.removeAttribute("aria-disabled"),n.hasAttribute("tabindex")||(n.tabIndex=-1),t.disabled||(n.addEventListener("click",e=>{const n=e;this._selectOption(t.index,{shiftKey:n.shiftKey,toggleKey:n.ctrlKey||n.metaKey})}),n.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this._selectOption(t.index,{shiftKey:e.shiftKey,toggleKey:e.ctrlKey||e.metaKey}))})),n}_addLoadMoreTrigger(){const e=document.createElement("div");if(e.className="load-more-container",this._config.infiniteScroll.enabled){const t=document.createElement("div");t.className="infinite-scroll-sentinel",t.style.height="10px",t.style.width="100%",t.style.opacity="0",this._loadMoreTrigger=t,e.appendChild(t)}else{const t=document.createElement("button");t.className="load-more-button",t.textContent=`Load ${this._config.loadMore.itemsPerLoad} more`,t.addEventListener("click",()=>this._loadMoreItems()),this._loadMoreTrigger=t,e.appendChild(t)}this._optionsContainer.appendChild(e),this._intersectionObserver&&this._loadMoreTrigger&&this._intersectionObserver.observe(this._loadMoreTrigger)}}customElements.get("enhanced-select")||customElements.define("enhanced-select",EnhancedSelect);class WorkerManager{constructor(){this.worker=null,this.pending=new Map,this.supportsWorkers=!1,this.supportsSharedArrayBuffer=!1,this.nextId=0,this.detectFeatures(),this.initWorker()}detectFeatures(){this.supportsWorkers="undefined"!=typeof Worker,this.supportsSharedArrayBuffer="undefined"!=typeof SharedArrayBuffer}initWorker(){if(this.supportsWorkers)try{const e=this.generateWorkerCode(),t=new Blob([e],{type:"application/javascript"}),n=URL.createObjectURL(t);this.worker=new Worker(n),this.worker.onmessage=this.handleMessage.bind(this),this.worker.onerror=this.handleError.bind(this),URL.revokeObjectURL(n)}catch(e){console.warn("Worker initialization failed, falling back to main thread",e),this.worker=null}}generateWorkerCode(){return"\n // Worker code\n self.onmessage = function(e) {\n const start = performance.now();\n const { id, type, payload } = e.data;\n \n try {\n let result;\n \n switch (type) {\n case 'transform':\n result = handleTransform(payload);\n break;\n case 'search':\n result = handleSearch(payload);\n break;\n case 'filter':\n result = handleFilter(payload);\n break;\n case 'sort':\n result = handleSort(payload);\n break;\n default:\n throw new Error('Unknown operation: ' + type);\n }\n \n const duration = performance.now() - start;\n self.postMessage({\n id,\n success: true,\n data: result,\n duration,\n });\n } catch (error) {\n self.postMessage({\n id,\n success: false,\n error: error.message,\n });\n }\n };\n \n function handleTransform({ items, transformer }) {\n const fn = new Function('item', 'index', 'return (' + transformer + ')(item, index)');\n return items.map((item, i) => fn(item, i));\n }\n \n function handleSearch({ items, query, fuzzy, maxResults }) {\n const lowerQuery = query.toLowerCase();\n const results = [];\n \n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const text = String(item).toLowerCase();\n \n if (fuzzy) {\n if (fuzzyMatch(text, lowerQuery)) {\n results.push({ item, index: i, score: fuzzyScore(text, lowerQuery) });\n }\n } else {\n if (text.includes(lowerQuery)) {\n results.push({ item, index: i });\n }\n }\n \n if (maxResults && results.length >= maxResults) break;\n }\n \n if (fuzzy) {\n results.sort((a, b) => b.score - a.score);\n }\n \n return results;\n }\n \n function handleFilter({ items, predicate }) {\n const fn = new Function('item', 'index', 'return (' + predicate + ')(item, index)');\n return items.filter((item, i) => fn(item, i));\n }\n \n function handleSort({ items, comparator }) {\n const fn = new Function('a', 'b', 'return (' + comparator + ')(a, b)');\n return [...items].sort(fn);\n }\n \n // Simple fuzzy matching (Levenshtein-inspired)\n function fuzzyMatch(text, query) {\n let qi = 0;\n for (let ti = 0; ti < text.length && qi < query.length; ti++) {\n if (text[ti] === query[qi]) qi++;\n }\n return qi === query.length;\n }\n \n function fuzzyScore(text, query) {\n let score = 0;\n let qi = 0;\n for (let ti = 0; ti < text.length && qi < query.length; ti++) {\n if (text[ti] === query[qi]) {\n score += 100 - ti; // Earlier matches score higher\n qi++;\n }\n }\n return score;\n }\n "}handleMessage(e){const{id:t,success:n,data:s,error:i}=e.data,o=this.pending.get(t);o&&(clearTimeout(o.timeout),this.pending.delete(t),n?o.resolve(s):o.reject(new Error(i||"Worker error")))}handleError(e){console.error("Worker error:",e);for(const[e,t]of this.pending)clearTimeout(t.timeout),t.reject(new Error("Worker crashed"));this.pending.clear()}async execute(e,t,n=5e3){if(!this.worker)return this.executeFallback(e,t);const s="req_"+this.nextId++;return new Promise((i,o)=>{const r=setTimeout(()=>{this.pending.delete(s),o(new Error("Worker timeout"))},n);this.pending.set(s,{resolve:i,reject:o,timeout:r}),this.worker.postMessage({id:s,type:e,payload:t})})}async executeFallback(e,t){switch(e){case"transform":{const{items:e,transformer:n}=t,s=new Function("item","index",`return (${n})(item, index)`);return e.map((e,t)=>s(e,t))}case"search":{const{items:e,query:n,fuzzy:s}=t,i=n.toLowerCase(),o=[];return e.forEach((e,t)=>{const n=String(e).toLowerCase();if(s){let s=0;for(let e=0;e<n.length&&s<i.length;e++)n[e]===i[s]&&s++;s===i.length&&o.push({item:e,index:t})}else n.includes(i)&&o.push({item:e,index:t})}),o}case"filter":{const{items:e,predicate:n}=t,s=new Function("item","index",`return (${n})(item, index)`);return e.filter((e,t)=>s(e,t))}case"sort":{const{items:e,comparator:n}=t,s=new Function("a","b",`return (${n})(a, b)`);return[...e].sort(s)}default:throw new Error(`Unknown operation: ${e}`)}}async transform(e,t){return this.execute("transform",{items:e,transformer:t.toString()})}async search(e,t,n=!1){return this.execute("search",{items:e,query:t,fuzzy:n})}async filter(e,t){return this.execute("filter",{items:e,predicate:t.toString()})}async sort(e,t){return this.execute("sort",{items:e,comparator:t.toString()})}get hasWorkerSupport(){return this.supportsWorkers&&null!==this.worker}get hasSharedArrayBuffer(){return this.supportsSharedArrayBuffer}destroy(){if(this.worker){for(const[e,t]of this.pending)clearTimeout(t.timeout),t.reject(new Error("Worker terminated"));this.pending.clear(),this.worker.terminate(),this.worker=null}}}let workerManager=null;function getWorkerManager(){return workerManager||(workerManager=new WorkerManager),workerManager}class PerformanceTelemetry{constructor(){this.frameTimes=[],this.longTasks=0,this.lastFrameTime=0,this.rafId=0,this.measuring=!1,this.observer=null,this.workTimes=[],this.measureFrame=()=>{if(!this.measuring)return;const e=performance.now(),t=e-this.lastFrameTime;this.frameTimes.push(t),this.frameTimes.length>60&&this.frameTimes.shift(),this.lastFrameTime=e,this.rafId=requestAnimationFrame(this.measureFrame)},this.setupObserver()}setupObserver(){if("undefined"!=typeof PerformanceObserver)try{this.observer=new PerformanceObserver(e=>{for(const t of e.getEntries())"longtask"===t.entryType&&t.duration>50&&this.longTasks++,"measure"===t.entryType&&this.workTimes.push(t.duration)});try{this.observer.observe({entryTypes:["longtask","measure"]})}catch{this.observer.observe({entryTypes:["measure"]})}}catch(e){console.warn("PerformanceObserver not available",e)}}start(){this.measuring||(this.measuring=!0,this.frameTimes=[],this.workTimes=[],this.longTasks=0,this.lastFrameTime=performance.now(),this.measureFrame())}stop(){this.measuring=!1,this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=0)}markStart(e){performance.mark(`${e}-start`)}markEnd(e){performance.mark(`${e}-end`),performance.measure(e,`${e}-start`,`${e}-end`);const t=performance.getEntriesByName(e,"measure")[0];return t?t.duration:0}getMetrics(){const e=this.frameTimes.length>0?this.frameTimes.reduce((e,t)=>e+t,0)/this.frameTimes.length:0,t={frames:{frameTime:e,fps:e>0?1e3/e:0,longTasks:this.frameTimes.filter(e=>e>16.67).length,droppedFrames:this.frameTimes.filter(e=>e>33.33).length},mainThreadWork:this.workTimes.length>0?this.workTimes.reduce((e,t)=>e+t,0)/this.workTimes.length:0,longTaskCount:this.longTasks};if("memory"in performance&&performance.memory){const e=performance.memory;t.memory={usedJSHeapSize:e.usedJSHeapSize,totalJSHeapSize:e.totalJSHeapSize,jsHeapSizeLimit:e.jsHeapSizeLimit}}return t}isPerformanceGood(){const e=this.getMetrics();return e.frames.fps>=55&&e.mainThreadWork<8&&e.frames.longTasks<3}getReport(){const e=this.getMetrics();let t="=== Performance Report ===\n";if(t+=`FPS: ${e.frames.fps.toFixed(2)}\n`,t+=`Avg Frame Time: ${e.frames.frameTime.toFixed(2)}ms\n`,t+=`Long Frames (>16.67ms): ${e.frames.longTasks}\n`,t+=`Dropped Frames (>33ms): ${e.frames.droppedFrames}\n`,t+=`Avg Main Thread Work: ${e.mainThreadWork.toFixed(2)}ms\n`,t+=`Long Tasks (>50ms): ${e.longTaskCount}\n`,e.memory){t+=`Memory: ${(e.memory.usedJSHeapSize/1024/1024).toFixed(2)}MB / ${(e.memory.jsHeapSizeLimit/1024/1024).toFixed(2)}MB\n`}return t+=`Status: ${this.isPerformanceGood()?"✓ GOOD":"✗ POOR"}\n`,t}reset(){this.frameTimes=[],this.workTimes=[],this.longTasks=0}destroy(){this.stop(),this.observer&&(this.observer.disconnect(),this.observer=null)}}let telemetry=null;function getTelemetry(){return telemetry||(telemetry=new PerformanceTelemetry),telemetry}async function measureAsync(e,t){const n=performance.now();return{result:await t(),duration:performance.now()-n}}function measureSync(e,t){const n=performance.now();return{result:t(),duration:performance.now()-n}}class NoOpSanitizer{sanitize(e){return e}}let globalSanitizer=new NoOpSanitizer;function setHTMLSanitizer(e){globalSanitizer=e}function getHTMLSanitizer(){return globalSanitizer}function sanitizeHTML(e){return globalSanitizer.sanitize(e)}function createTextNode(e){return document.createTextNode(e)}function setTextContent(e,t){e.textContent=t}function createElement(e,t,n){const s=document.createElement(e);if(t)for(const[e,n]of Object.entries(t))e.startsWith("on")||"style"===e?console.warn(`[NativeSelect Security] Blocked attribute: ${e}`):s.setAttribute(e,n);return void 0!==n&&(s.textContent=n),s}function setCSSProperties(e,t){for(const[n,s]of Object.entries(t))n.startsWith("--")?e.style.setProperty(n,s):console.warn(`[NativeSelect Security] CSS property must start with --: ${n}`)}const CSPFeatures={hasInlineScripts(){try{return new Function("return true"),!0}catch{return!1}},hasEval(){try{return eval("true"),!0}catch{return!1}},hasSharedArrayBuffer:()=>"undefined"!=typeof SharedArrayBuffer,hasWorkers(){try{return"undefined"!=typeof Worker}catch{return!1}},isSandboxed(){try{return window!==window.parent&&!window.parent}catch{return!0}},getCSPDirectives(){const e=document.querySelectorAll('meta[http-equiv="Content-Security-Policy"]'),t=[];return e.forEach(e=>{const n=e.getAttribute("content");n&&t.push(n)}),t}};function detectEnvironment(){return{canUseWorkers:CSPFeatures.hasWorkers(),canUseSharedArrayBuffer:CSPFeatures.hasSharedArrayBuffer(),canUseInlineScripts:CSPFeatures.hasInlineScripts(),canUseEval:CSPFeatures.hasEval(),isSandboxed:CSPFeatures.isSandboxed(),cspDirectives:CSPFeatures.getCSPDirectives()}}function validateTemplate(e,t){return globalSanitizer instanceof NoOpSanitizer&&console.warn(`[NativeSelect Security] Template from "${t}" contains HTML but no sanitizer is configured. This may be unsafe if the content is untrusted. Call setHTMLSanitizer() with a sanitizer like DOMPurify.`),sanitizeHTML(e)}function containsSuspiciousPatterns(e){return[/<script/i,/javascript:/i,/on\w+\s*=/i,/eval\s*\(/i,/Function\s*\(/i,/setTimeout\s*\(/i,/setInterval\s*\(/i].some(t=>t.test(e))}function escapeHTML(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function escapeAttribute(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function applyClasses(e,t){e.className=t.filter(Boolean).join(" ")}function toggleClass(e,t,n){e.classList.toggle(t,n)}function setCustomProperties(e,t){for(const[n,s]of Object.entries(t))n.startsWith("--")?e.style.setProperty(n,s):"production"!==process.env.NODE_ENV&&console.warn(`[NativeSelect CSP] Custom property must start with --: "${n}". Skipping.`)}function getCustomProperty(e,t){return getComputedStyle(e).getPropertyValue(t).trim()}function removeCustomProperty(e,t){e.style.removeProperty(t)}const defaultTheme={"--ns-item-height":"40px","--ns-item-padding":"8px 12px","--ns-item-bg":"transparent","--ns-item-hover-bg":"rgba(0, 0, 0, 0.05)","--ns-item-selected-bg":"rgba(0, 102, 204, 0.1)","--ns-item-active-bg":"rgba(0, 102, 204, 0.2)","--ns-item-color":"inherit","--ns-item-selected-color":"#0066cc","--ns-border-color":"#ccc","--ns-border-radius":"4px","--ns-focus-outline":"2px solid #0066cc","--ns-font-size":"14px","--ns-font-family":"system-ui, -apple-system, sans-serif"};function applyDefaultTheme(e){setCustomProperties(e,defaultTheme)}const shadowDOMStyles='\n:host {\n display: block;\n box-sizing: border-box;\n font-family: var(--ns-font-family, system-ui, -apple-system, sans-serif);\n font-size: var(--ns-font-size, 14px);\n}\n\n* {\n box-sizing: border-box;\n}\n\n.ns-list {\n position: relative;\n overflow: auto;\n max-height: var(--ns-max-height, 300px);\n border: 1px solid var(--ns-border-color, #ccc);\n border-radius: var(--ns-border-radius, 4px);\n background: var(--ns-bg, white);\n outline: none;\n}\n\n.ns-list:focus {\n outline: var(--ns-focus-outline, 2px solid #0066cc);\n outline-offset: -2px;\n}\n\n.ns-item {\n padding: var(--ns-item-padding, 8px 12px);\n min-height: var(--ns-item-height, 40px);\n color: var(--ns-item-color, inherit);\n background: var(--ns-item-bg, transparent);\n cursor: pointer;\n user-select: none;\n display: flex;\n align-items: center;\n transition: background-color 0.15s ease;\n}\n\n.ns-item:hover {\n background: var(--ns-item-hover-bg, rgba(0, 0, 0, 0.05));\n}\n\n.ns-item[aria-selected="true"] {\n background: var(--ns-item-selected-bg, rgba(0, 102, 204, 0.1));\n color: var(--ns-item-selected-color, #0066cc);\n}\n\n.ns-item[data-active="true"] {\n background: var(--ns-item-active-bg, rgba(0, 102, 204, 0.2));\n}\n\n.ns-item[aria-disabled="true"] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ns-viewport {\n position: relative;\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.ns-spacer {\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n pointer-events: none;\n}\n\n/* Screen reader only */\n.ns-sr-only {\n position: absolute;\n left: -9999px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n}\n\n/* Portal mode (teleported outside shadow DOM) */\n.ns-portal {\n position: fixed;\n z-index: var(--ns-portal-z-index, 9999);\n}\n\n/* CSP warning banner (only shown in development) */\n.ns-csp-warning {\n padding: 8px;\n background: #fff3cd;\n border: 1px solid #ffc107;\n border-radius: 4px;\n color: #856404;\n font-size: 12px;\n margin-bottom: 8px;\n}\n';function injectShadowStyles(e){const t=document.createElement("style");t.textContent=shadowDOMStyles,e.appendChild(t)}function hasOverflowHiddenAncestor(e){let t=e.parentElement;for(;t&&t!==document.body;){const e=getComputedStyle(t).overflow;if("hidden"===e||"clip"===e)return!0;t=t.parentElement}return!1}function warnCSPViolation(e,t){"production"!==process.env.NODE_ENV&&console.warn(`[NativeSelect CSP] Feature "${e}" blocked by Content Security Policy. Falling back to "${t}".`)}export{CSPFeatures,CustomOptionPool,DOMPool,EnhancedSelect,FenwickTree,NativeSelectElement,OptionRenderer,PerformanceTelemetry,SelectOption,Virtualizer,WorkerManager,applyClasses,applyDefaultTheme,configureSelect,containsSuspiciousPatterns,createElement,createRendererHelpers,createTextNode,defaultTheme,detectEnvironment,escapeAttribute,escapeHTML,getCustomProperty,getHTMLSanitizer,getTelemetry,getWorkerManager,hasOverflowHiddenAncestor,injectShadowStyles,measureAsync,measureSync,removeCustomProperty,renderTemplate,resetSelectConfig,sanitizeHTML,selectConfig,setCSSProperties,setCustomProperties,setHTMLSanitizer,setTextContent,shadowDOMStyles,toggleClass,validateTemplate,warnCSPViolation};
2
2
  //# sourceMappingURL=index.min.js.map