@smilodon/core 1.3.2 → 1.3.3

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,console.log(`[CustomOptionPool] Reusing component for index ${n}`);else try{a=e(t,n),console.log(`[CustomOptionPool] Created new component for index ${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 n of this._pool.values()){const s=n.find(e=>e.instance===t);if(s){s.inUse=!1,console.log(`[CustomOptionPool] Released component from index ${e}`);break}}}}releaseAll(){console.log(`[CustomOptionPool] Releasing ${this._activeComponents.size} active components`);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(),console.log("[CustomOptionPool] Pool cleared")}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),console.log(`[OptionRenderer] Rendered lightweight option ${t}: ${s}`),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)}),console.log(`[OptionRenderer] Rendered custom component option ${t}: ${s}`)}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(t.hasOwnProperty(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 EnhancedSelect extends HTMLElement{constructor(){super(),this._pageCache={},this._typeBuffer="",this._hasError=!1,this._errorMessage="",this._boundArrowClick=null,console.log("[EnhancedSelect] Constructor called"),this._shadow=this.attachShadow({mode:"open"}),console.log("[EnhancedSelect] Shadow root attached:",this._shadow),this._uniqueId=`enhanced-select-${Math.random().toString(36).substr(2,9)}`,this._config=selectConfig.getConfig(),console.log("[EnhancedSelect] Config loaded"),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},console.log("[EnhancedSelect] State initialized"),this._container=this._createContainer(),console.log("[EnhancedSelect] Container created:",this._container),this._inputContainer=this._createInputContainer(),console.log("[EnhancedSelect] Input container created"),this._input=this._createInput(),console.log("[EnhancedSelect] Input created:",this._input),this._arrowContainer=this._createArrowContainer(),console.log("[EnhancedSelect] Arrow container created"),this._dropdown=this._createDropdown(),console.log("[EnhancedSelect] Dropdown created"),this._optionsContainer=this._createOptionsContainer(),console.log("[EnhancedSelect] Options container created"),this._liveRegion=this._createLiveRegion(),console.log("[EnhancedSelect] Live region created"),this._initializeStyles(),console.log("[EnhancedSelect] Styles initialized"),this._assembleDOM(),console.log("[EnhancedSelect] DOM assembled"),this._attachEventListeners(),console.log("[EnhancedSelect] Event listeners attached"),this._initializeObservers(),console.log("[EnhancedSelect] Observers initialized"),console.log("[EnhancedSelect] Constructor complete, shadow DOM children:",this._shadow.children.length)}connectedCallback(){console.log("[EnhancedSelect] connectedCallback called"),this.style.display="block",this.style.width="100%",console.log("[EnhancedSelect] Forced host display styles"),this._config.serverSide.enabled&&this._config.serverSide.initialSelectedValues&&this._loadInitialSelectedItems(),this._config.callbacks.onOpen&&this._config.callbacks.onOpen(),console.log("[EnhancedSelect] connectedCallback complete")}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.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"),"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" width="16" height="16" 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(){console.log("[EnhancedSelect] _assembleDOM: Starting DOM assembly"),console.log("[EnhancedSelect] _assembleDOM: Elements to assemble:",{inputContainer:!!this._inputContainer,input:!!this._input,arrowContainer:!!this._arrowContainer,container:!!this._container,dropdown:!!this._dropdown,optionsContainer:!!this._optionsContainer,shadow:!!this._shadow,liveRegion:!!this._liveRegion}),this._inputContainer.appendChild(this._input),console.log("[EnhancedSelect] _assembleDOM: Appended input to inputContainer"),this._arrowContainer&&(this._inputContainer.appendChild(this._arrowContainer),console.log("[EnhancedSelect] _assembleDOM: Appended arrowContainer to inputContainer")),this._container.appendChild(this._inputContainer),console.log("[EnhancedSelect] _assembleDOM: Appended inputContainer to container"),this._dropdown.appendChild(this._optionsContainer),console.log("[EnhancedSelect] _assembleDOM: Appended optionsContainer to dropdown"),this._container.appendChild(this._dropdown),console.log("[EnhancedSelect] _assembleDOM: Appended dropdown to container"),this._shadow.appendChild(this._container),console.log("[EnhancedSelect] _assembleDOM: Appended container to shadow root"),this._liveRegion&&(this._shadow.appendChild(this._liveRegion),console.log("[EnhancedSelect] _assembleDOM: Appended liveRegion to shadow root")),console.log("[EnhancedSelect] _assembleDOM: Shadow root children count:",this._shadow.children.length),console.log("[EnhancedSelect] _assembleDOM: Shadow root HTML length:",this._shadow.innerHTML.length);const e=`${this._uniqueId}-listbox`;this._dropdown.id=e,this._input.setAttribute("aria-controls",e),this._input.setAttribute("aria-owns",e),console.log("[EnhancedSelect] _assembleDOM: Set ARIA relationships with listboxId:",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: 6px;\n padding: 6px 52px 6px 8px;\n min-height: 44px;\n background: white;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n box-sizing: border-box;\n transition: all 0.2s ease;\n }\n \n .input-container:focus-within {\n border-color: #667eea;\n box-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: 40px;\n transform: translateY(-50%);\n width: 1px;\n height: 60%;\n background: 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: 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: 0 4px 4px 0;\n z-index: 2;\n }\n \n .dropdown-arrow-container:hover {\n background-color: rgba(102, 126, 234, 0.08);\n }\n \n .dropdown-arrow {\n width: 16px;\n height: 16px;\n color: #667eea;\n transition: transform 0.2s ease, color 0.2s ease;\n transform: translateY(0);\n }\n \n .dropdown-arrow-container:hover .dropdown-arrow {\n color: #667eea;\n }\n \n .dropdown-arrow.open {\n transform: rotate(180deg);\n }\n \n .select-input {\n flex: 1;\n min-width: 120px;\n padding: 4px;\n border: none;\n font-size: 14px;\n line-height: 1.5;\n color: #1f2937;\n background: transparent;\n box-sizing: border-box;\n outline: none;\n }\n \n .select-input::placeholder {\n color: #9ca3af;\n }\n \n .selection-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n margin: 2px;\n background: #667eea;\n color: white;\n border-radius: 4px;\n font-size: 13px;\n line-height: 1;\n }\n \n .badge-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n padding: 0;\n margin-left: 4px;\n background: rgba(255, 255, 255, 0.3);\n border: none;\n border-radius: 50%;\n color: white;\n font-size: 16px;\n line-height: 1;\n cursor: pointer;\n transition: background 0.2s;\n }\n \n .badge-remove:hover {\n background: rgba(255, 255, 255, 0.5);\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: 4px;\n max-height: 300px;\n overflow: hidden;\n background: var(--select-dropdown-bg, white);\n border: 1px solid var(--select-dropdown-border, #ccc);\n border-radius: var(--select-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: 300px;\n overflow: auto;\n transition: opacity 0.2s ease-in-out;\n }\n\n .option {\n padding: 8px 12px;\n cursor: pointer;\n color: inherit;\n transition: background-color 0.15s ease;\n user-select: none;\n }\n\n .option:hover {\n background-color: #f3f4f6;\n }\n\n .option.selected {\n background-color: #e0e7ff;\n color: #4338ca;\n font-weight: 500;\n }\n\n .option.active {\n background-color: #f3f4f6;\n }\n \n .load-more-container {\n padding: 12px;\n text-align: center;\n border-top: 1px solid var(--select-divider-color, #e0e0e0);\n }\n \n .load-more-button {\n padding: 8px 16px;\n border: 1px solid var(--select-button-border, #1976d2);\n background: var(--select-button-bg, white);\n color: var(--select-button-color, #1976d2);\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\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: 0.5;\n cursor: not-allowed;\n }\n \n .busy-bucket {\n padding: 16px;\n text-align: center;\n color: var(--select-busy-color, #666);\n }\n \n .spinner {\n display: inline-block;\n width: 20px;\n height: 20px;\n border: 2px solid var(--select-spinner-color, #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: 24px;\n text-align: center;\n color: var(--select-empty-color, #999);\n }\n \n .searching-state {\n padding: 24px;\n text-align: center;\n color: #667eea;\n font-style: italic;\n animation: pulse 1.5s ease-in-out infinite;\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 /* Accessibility: Dark mode */\n @media (prefers-color-scheme: dark) {\n .select-input {\n background: var(--select-dark-bg, #1f2937);\n color: var(--select-dark-text, #f9fafb);\n border-color: var(--select-dark-border, #4b5563);\n }\n \n .select-dropdown {\n background: var(--select-dark-dropdown-bg, #1f2937);\n border-color: var(--select-dark-dropdown-border, #4b5563);\n color: var(--select-dark-text, #f9fafb);\n }\n \n .option:hover {\n background-color: var(--select-dark-option-hover-bg, #374151);\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 }\n \n .busy-bucket {\n color: var(--select-dark-busy-color, #9ca3af);\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 ',console.log("[EnhancedSelect] _initializeStyles: Created style element, content length:",e.textContent?.length||0),console.log("[EnhancedSelect] _initializeStyles: Shadow root children BEFORE:",this._shadow.children.length),this._shadow.firstChild?this._shadow.insertBefore(e,this._shadow.firstChild):this._shadow.appendChild(e),console.log("[EnhancedSelect] _initializeStyles: Style inserted, shadow root children AFTER:",this._shadow.children.length),console.log("[EnhancedSelect] _initializeStyles: Shadow root has style element:",!!this._shadow.querySelector("style")),console.log("[EnhancedSelect] _initializeStyles: Style sheet rules:",e.sheet?.cssRules?.length||"NOT PARSED")}_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._container.addEventListener("click",e=>{e.stopPropagation()}),this._input.addEventListener("focus",()=>this._handleOpen()),this._input.addEventListener("blur",e=>{setTimeout(()=>{this._dropdown.contains(document.activeElement)||this._handleClose()},200)}),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("click",e=>{const t=e.target;this._shadow.contains(t)||this._container.contains(t)||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._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._emit("open",{}),this._config.callbacks.onOpen?.(),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._updateArrowRotation(),this._emit("close",{}),this._config.callbacks.onClose?.())}_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"))}}_handleSearch(e){this._state.searchQuery=e,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):this._handleOpen();break;case"ArrowUp":e.preventDefault(),this._state.isOpen?this._moveActive(-1):this._handleOpen();break;case"Home":e.preventDefault(),this._state.isOpen&&this._setActive(0);break;case"End":if(e.preventDefault(),this._state.isOpen){const e=Array.from(this._optionsContainer.children);this._setActive(e.length-1)}break;case"PageDown":e.preventDefault(),this._state.isOpen&&this._moveActive(10);break;case"PageUp":e.preventDefault(),this._state.isOpen&&this._moveActive(-10);break;case"Enter":e.preventDefault(),this._state.activeIndex>=0&&this._selectOption(this._state.activeIndex);break;case"Escape":e.preventDefault(),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){const t=Array.from(this._optionsContainer.children),n=Math.max(0,Math.min(t.length-1,this._state.activeIndex+e));this._setActive(n)}_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=`${this._uniqueId}-option-${e}`;this._input.setAttribute("aria-activedescendant",i)}}_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`)}_announce(e){this._liveRegion&&(this._liveRegion.textContent=e,setTimeout(()=>{this._liveRegion&&(this._liveRegion.textContent="")},1e3))}_selectOption(e){const t=this._state.loadedItems[e];if(!t)return;const n=this._state.selectedIndices.has(e);if("single"===this._config.selection.mode){const n=this._state.selectedIndices.has(e);this._state.selectedIndices.clear(),this._state.selectedItems.clear(),n||(this._state.selectedIndices.add(e),this._state.selectedItems.set(e,t)),this._renderOptions(),this._config.selection.closeOnSelect&&this._handleClose()}else{const s=this._config.selection.maxSelections||0;if(n)this._state.selectedIndices.delete(e),this._state.selectedItems.delete(e);else{if(s>0&&this._state.selectedIndices.size>=s)return void this._announce(`Maximum ${s} selections allowed`);this._state.selectedIndices.add(e),this._state.selectedItems.set(e,t)}this._renderOptions()}this._updateInputDisplay(),this._emitChange();const s=this._config.serverSide.getValueFromItem||(e=>e?.value??e),i=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e));this._config.callbacks.onSelect?.({item:t,index:e,value:s(t),label:i(t),selected:this._state.selectedIndices.has(e)})}_handleOptionRemove(e){const t=this._optionsContainer.children[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._uniqueId}-option-${e}`,n=this._optionsContainer.querySelector(`[id="${t}"]`);if(n){const t=n.offsetTop,r=Math.abs(t-s);r<o&&(o=r,i=e)}}n=i}else n="first"===e?t[0]:t[t.length-1];const s=`${this._uniqueId}-option-${n}`,i=this._optionsContainer.querySelector(`[id="${s}"]`);i&&(i.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,this._renderOptions()}_showBusyBucket(){}_hideBusyBucket(){}_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)}setItems(e){console.log("[EnhancedSelect] setItems called with",e?.length||0,"items"),console.log("[EnhancedSelect] Items:",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),console.log("[EnhancedSelect] Flattened grouped items to",this._state.loadedItems.length,"items"));const n=this._state.loadedItems.length;if(console.log("[EnhancedSelect] State.loadedItems updated:",t,"→",n),this._state.preserveScrollPosition&&this._dropdown){const e=this._state.lastScrollPosition;console.log("[EnhancedSelect] Preserving scroll position:",e),n>t&&(this._state.isBusy=!1),console.log("[EnhancedSelect] Calling _renderOptions (with scroll preservation)..."),this._renderOptions(),this._dropdown.scrollTop=e,requestAnimationFrame(()=>{this._dropdown&&(this._dropdown.scrollTop=e)}),n>t&&(this._state.preserveScrollPosition=!1)}else this._state.isBusy=!1,console.log("[EnhancedSelect] Calling _renderOptions (normal)..."),this._renderOptions();console.log("[EnhancedSelect] setItems complete")}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")),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(console.log("[EnhancedSelect] _renderOptions called"),console.log("[EnhancedSelect] State:",{loadedItems:this._state.loadedItems.length,groupedItems:this._state.groupedItems.length,isOpen:this._state.isOpen,isSearching:this._state.isSearching,searchQuery:this._state.searchQuery,isBusy:this._state.isBusy}),this._loadMoreTrigger&&this._intersectionObserver&&this._intersectionObserver.unobserve(this._loadMoreTrigger),console.log("[EnhancedSelect] Clearing options container, previous children:",this._optionsContainer.children.length),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",console.log("[EnhancedSelect] Dropdown display set to block")),this._state.isSearching){const e=document.createElement("div");return e.className="searching-state",e.textContent="Searching...",this._optionsContainer.appendChild(e),void console.log("[EnhancedSelect] Added searching state")}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)console.log("[EnhancedSelect] Rendering grouped items:",this._state.groupedItems.length,"groups"),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{console.log("[EnhancedSelect] Rendering flat list:",this._state.loadedItems.length,"items");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)}),console.log("[EnhancedSelect] Rendered",s?"items":"no items"),!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),console.log("[EnhancedSelect] Added empty state")}}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),console.log("[EnhancedSelect] Added busy bucket")}else(this._config.loadMore.enabled||this._config.infiniteScroll.enabled)&&this._state.loadedItems.length>0&&this._addLoadMoreTrigger();console.log("[EnhancedSelect] _renderOptions complete, optionsContainer children:",this._optionsContainer.children.length)}_renderSingleOption(e,t,n,s){const i=document.createElement("div");i.className="option",i.id=`${this._uniqueId}-option-${t}`;const o=n(e),r=s(e);console.log("[EnhancedSelect] Rendering option",t,":",{value:o,label:r}),i.textContent=r,i.dataset.value=String(o),i.dataset.index=String(t);this._state.selectedIndices.has(t)?(i.classList.add("selected"),i.setAttribute("aria-selected","true")):i.setAttribute("aria-selected","false"),i.addEventListener("click",()=>{this._selectOption(t)}),this._optionsContainer.appendChild(i),console.log("[EnhancedSelect] Option",t,"appended to optionsContainer")}_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 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=`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 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(),s=await t(),i=performance.now()-n;return console.log(`[Perf] ${e}: ${i.toFixed(2)}ms`),{result:s,duration:i}}function measureSync(e,t){const n=performance.now(),s=t(),i=performance.now()-n;return console.log(`[Perf] ${e}: ${i.toFixed(2)}ms`),{result:s,duration:i}}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 s=Number(t.dataset.index);return Number.isFinite(s)?s:null},keyboardFocus:e=>{const t=document.querySelector(`[data-selectable][data-index="${e}"]`);t?.focus?.()}});function renderTemplate(e,t,s){const n=document.createDocumentFragment();for(let e=0;e<t.length;e++){const i=t[e],o=document.createElement("div");o.innerHTML=s(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);n.appendChild(t);continue}r.hasAttribute("data-smilodon-handled")||(r.setAttribute("data-selectable",""),r.setAttribute("data-index",String(e))),n.appendChild(r)}e.replaceChildren(n)}class FenwickTree{constructor(e){this.size=e,this.tree=new Float64Array(e+1)}add(e,t){let s=e+1;for(;s<=this.size;)this.tree[s]+=t,s+=s&-s}sum(e){if(e<0)return 0;let t=e+1,s=0;for(;t>0;)s+=this.tree[t],t-=t&-t;return s}rangeSum(e,t){return e>t?0:this.sum(t)-(e>0?this.sum(e-1):0)}update(e,t,s){this.add(e,s-t)}lowerBound(e){if(e<=0)return 0;let t=0,s=0,n=1<<Math.floor(Math.log2(this.size));for(;n>0;){if(t+n<=this.size){const i=s+this.tree[t+n];i<e&&(t+=n,s=i)}n>>=1}return t}reset(){this.tree.fill(0)}resize(e){if(e===this.size)return;const t=this.tree,s=this.size;this.size=e,this.tree=new Float64Array(e+1);const n=Math.min(s,e);for(let e=1;e<=n;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 s=this.pool[t];if(!s.inUse)return s.inUse=!0,s.lastUsed=e,this.reset(s.node),this.telemetry&&this.hits++,s.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 s=0;s<this.pool.length;s++){const n=this.pool[s];!n.inUse&&n.lastUsed<t&&(e=s,t=n.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 s of t)s.name.startsWith("data-")&&"data-index"!==s.name&&"data-selectable"!==s.name&&e.removeAttribute(s.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,s,n){this.measuredHeights=new Map,this.activeNodes=new Map,this.container=e,this.itemsLength=t,this.itemGetter=s,this.options=n,this.averageHeight=n.estimatedItemHeight;const i=Math.ceil(1.5*(2*n.buffer+10))+(n.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:n.enableTelemetry||!1}),t>5e3){this.fenwick=new FenwickTree(t);for(let e=0;e<t;e++)this.fenwick.add(e,n.estimatedItemHeight)}this.container.style.willChange="transform"}computeWindow(e,t){const{buffer:s}=this.options,n=Math.max(Math.floor(e/this.averageHeight)-s,0),i=Math.min(Math.ceil((e+t)/this.averageHeight)+s,this.itemsLength-1),o=Math.max(0,i-n+1),r=o+(this.options.maxPoolExtra??32);return this.pool.setMaxSize(r),{startIndex:n,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 s=0;s<e;s++)t+=this.measuredHeights.get(s)??this.averageHeight;return t}acquireNode(e){const t=this.activeNodes.get(e);if(t)return t;const s=this.pool.acquire();return s.setAttribute("data-index",String(e)),this.activeNodes.set(e,s),s}releaseNode(e){const t=this.activeNodes.get(e);t&&(this.pool.release(t),this.activeNodes.delete(e))}releaseExcess(e){for(const[t,s]of this.activeNodes)e.has(t)||(this.pool.release(s),this.activeNodes.delete(t))}render(e,t,s){const n=document.createDocumentFragment(),i=new Set;for(let o=e;o<=t;o++){const e=this.acquireNode(o);s(e,this.itemGetter(o),o),n.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(n),requestAnimationFrame(()=>this.releaseExcess(i))}measureOnAppear(e,t){const s=e.offsetHeight,n=this.measuredHeights.get(t),i=this.options.measurementThreshold??5;if(void 0===n||Math.abs(n-s)>i){const e=n??this.averageHeight;this.measuredHeights.set(t,s),this.fenwick&&this.fenwick.update(t,e,s);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,s,n,i){const o=this._getFactoryKey(e),r=this._findAvailableComponent(o);let a;if(r)a=r.instance,r.inUse=!0,r.lastUsedIndex=s;else try{a=e(t,s);const n=this._pool.get(o)||[];n.length<this._maxPoolSize&&(n.push({instance:a,inUse:!0,lastUsedIndex:s}),this._pool.set(o,n))}catch(e){throw console.error("[CustomOptionPool] Failed to create component:",e),e}try{a.mountOption(i,n),this._activeComponents.set(s,a)}catch(e){throw console.error(`[CustomOptionPool] Failed to mount component at index ${s}:`,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 s=e.find(e=>e.instance===t);if(s){s.inUse=!1;break}}}}releaseAll(){Array.from(this._activeComponents.keys()).forEach(e=>this.release(e))}updateSelection(e,t){const s=this._activeComponents.get(e);s&&s.updateSelected(t)}updateFocused(e,t){const s=this._activeComponents.get(e);s&&s.updateFocused&&s.updateFocused(t)}getComponent(e){return this._activeComponents.get(e)}clear(){this.releaseAll(),this._pool.clear()}getStats(){let e=0,t=0;for(const s of this._pool.values())e+=s.length,t+=s.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,s,n,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,s,n,l,i,o.optionComponent):this._renderLightweightOption(e,t,r,a,s,n,l,i)}updateSelection(e,t){const s=this._mountedElements.get(e);if(!s)return;const n=this._pool.getComponent(e);n?n.updateSelected(t):t?(s.classList.add("selected"),s.setAttribute("aria-selected","true")):(s.classList.remove("selected"),s.setAttribute("aria-selected","false"))}updateFocused(e,t){const s=this._mountedElements.get(e);if(!s)return;const n=this._pool.getComponent(e);n?(n.updateFocused&&n.updateFocused(t),s.classList.toggle("focused",t)):s.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,s,n,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=n,l.dataset.value=String(s),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,s,n,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(s),c.dataset.index=String(t),c.dataset.mode="component",c.setAttribute("role","option"),c.setAttribute("aria-selected",String(i)),c.setAttribute("aria-label",n),r&&c.setAttribute("aria-disabled","true");const d={item:e,index:t,value:s,label:n,isSelected:i,isFocused:o,isDisabled:r,onSelect:e=>{r||this._config.onSelect(e)},onCustomEvent:(e,s)=>{this._config.onCustomEvent&&this._config.onCustomEvent(t,e,s)}};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=n,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 s=Number(t.dataset.index),n=this._items[s];this._onSelect(n,s)}),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,s)=>{this.dispatchEvent(new CustomEvent("option:custom-event",{detail:{index:e,eventName:t,data:s},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,s){switch(e){case"placement":this._options.placement=s??void 0;break;case"strategy":this._options.strategy=s??void 0;break;case"portal":this._options.portal="true"===s||"false"!==s&&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,s=this.getBoundingClientRect().height||300,n=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 s=this._items[t],n=this._selectedSet.has(t),i=this._activeIndex===t,o=this._unifiedRenderer.render(s,t,n,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(n,s);return void this._virtualizer.render(i,o,(s,n,i)=>{if(this._applyOptionAttrs(s,i),t){const e=t(n,i,this._helpers);s.replaceChildren(e)}else if(e){const t=document.createElement("div");t.innerHTML=e(n,i);const o=t.firstElementChild;s.replaceChildren(o??document.createTextNode(String(n)))}else{const e=String("object"==typeof n&&null!==n&&"label"in n?n.label:n);s.textContent=e}})}const i=document.createDocumentFragment();for(let s=0;s<this._items.length;s++){const n=this._items[s];if(t){const e=t(n,s,this._helpers);e.hasAttribute("data-selectable")||(e.setAttribute("data-selectable",""),e.setAttribute("data-index",String(s))),this._applyOptionAttrs(e,s),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 n&&null!==n&&"label"in n?n.label:n);e.textContent=t,e.setAttribute("data-selectable",""),e.setAttribute("data-index",String(s)),this._applyOptionAttrs(e,s),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 s=this._selectedSet.has(t),n=e?.value??e,i=e?.label??String(e);this._emit("select",{item:e,index:t,value:n,label:i,selected:s,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 s={...e};for(const e in t)if(t.hasOwnProperty(e)){const n=t[e],i=s[e];n&&"object"==typeof n&&!Array.isArray(n)?s[e]=this.deepMerge(i&&"object"==typeof i?i:{},n):s[e]=n}return s}}const selectConfig=new SelectConfigManager;function configureSelect(e){selectConfig.updateConfig(e)}function resetSelectConfig(){selectConfig.resetConfig()}class EnhancedSelect extends HTMLElement{constructor(){super(),this._pageCache={},this._typeBuffer="",this._hasError=!1,this._errorMessage="",this._boundArrowClick=null,this._shadow=this.attachShadow({mode:"open"}),this._uniqueId=`enhanced-select-${Math.random().toString(36).substr(2,9)}`,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.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"),"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" width="16" height="16" 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: 6px;\n padding: 6px 52px 6px 8px;\n min-height: 44px;\n background: white;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n box-sizing: border-box;\n transition: all 0.2s ease;\n }\n \n .input-container:focus-within {\n border-color: #667eea;\n box-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: 40px;\n transform: translateY(-50%);\n width: 1px;\n height: 60%;\n background: 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: 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: 0 4px 4px 0;\n z-index: 2;\n }\n \n .dropdown-arrow-container:hover {\n background-color: rgba(102, 126, 234, 0.08);\n }\n \n .dropdown-arrow {\n width: 16px;\n height: 16px;\n color: #667eea;\n transition: transform 0.2s ease, color 0.2s ease;\n transform: translateY(0);\n }\n \n .dropdown-arrow-container:hover .dropdown-arrow {\n color: #667eea;\n }\n \n .dropdown-arrow.open {\n transform: rotate(180deg);\n }\n \n .select-input {\n flex: 1;\n min-width: 120px;\n padding: 4px;\n border: none;\n font-size: 14px;\n line-height: 1.5;\n color: #1f2937;\n background: transparent;\n box-sizing: border-box;\n outline: none;\n }\n \n .select-input::placeholder {\n color: #9ca3af;\n }\n \n .selection-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n margin: 2px;\n background: #667eea;\n color: white;\n border-radius: 4px;\n font-size: 13px;\n line-height: 1;\n }\n \n .badge-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n padding: 0;\n margin-left: 4px;\n background: rgba(255, 255, 255, 0.3);\n border: none;\n border-radius: 50%;\n color: white;\n font-size: 16px;\n line-height: 1;\n cursor: pointer;\n transition: background 0.2s;\n }\n \n .badge-remove:hover {\n background: rgba(255, 255, 255, 0.5);\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: 4px;\n max-height: 300px;\n overflow: hidden;\n background: var(--select-dropdown-bg, white);\n border: 1px solid var(--select-dropdown-border, #ccc);\n border-radius: var(--select-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: 300px;\n overflow: auto;\n transition: opacity 0.2s ease-in-out;\n }\n\n .option {\n padding: 8px 12px;\n cursor: pointer;\n color: inherit;\n transition: background-color 0.15s ease;\n user-select: none;\n }\n\n .option:hover {\n background-color: #f3f4f6;\n }\n\n .option.selected {\n background-color: #e0e7ff;\n color: #4338ca;\n font-weight: 500;\n }\n\n .option.active {\n background-color: #f3f4f6;\n }\n \n .load-more-container {\n padding: 12px;\n text-align: center;\n border-top: 1px solid var(--select-divider-color, #e0e0e0);\n }\n \n .load-more-button {\n padding: 8px 16px;\n border: 1px solid var(--select-button-border, #1976d2);\n background: var(--select-button-bg, white);\n color: var(--select-button-color, #1976d2);\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\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: 0.5;\n cursor: not-allowed;\n }\n \n .busy-bucket {\n padding: 16px;\n text-align: center;\n color: var(--select-busy-color, #666);\n }\n \n .spinner {\n display: inline-block;\n width: 20px;\n height: 20px;\n border: 2px solid var(--select-spinner-color, #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: 24px;\n text-align: center;\n color: var(--select-empty-color, #999);\n }\n \n .searching-state {\n padding: 24px;\n text-align: center;\n color: #667eea;\n font-style: italic;\n animation: pulse 1.5s ease-in-out infinite;\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 /* Accessibility: Dark mode */\n @media (prefers-color-scheme: dark) {\n .select-input {\n background: var(--select-dark-bg, #1f2937);\n color: var(--select-dark-text, #f9fafb);\n border-color: var(--select-dark-border, #4b5563);\n }\n \n .select-dropdown {\n background: var(--select-dark-dropdown-bg, #1f2937);\n border-color: var(--select-dark-dropdown-border, #4b5563);\n color: var(--select-dark-text, #f9fafb);\n }\n \n .option:hover {\n background-color: var(--select-dark-option-hover-bg, #374151);\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 }\n \n .busy-bucket {\n color: var(--select-dark-busy-color, #9ca3af);\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._container.addEventListener("click",e=>{e.stopPropagation()}),this._input.addEventListener("focus",()=>this._handleOpen()),this._input.addEventListener("blur",e=>{setTimeout(()=>{this._dropdown.contains(document.activeElement)||this._handleClose()},200)}),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("click",e=>{const t=e.target;this._shadow.contains(t)||this._container.contains(t)||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._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._emit("open",{}),this._config.callbacks.onOpen?.(),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._updateArrowRotation(),this._emit("close",{}),this._config.callbacks.onClose?.())}_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"))}}_handleSearch(e){this._state.searchQuery=e,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)),s=e.toLowerCase(),n=s?this._state.loadedItems.filter(e=>{try{return String(t(e)).toLowerCase().includes(s)}catch(e){return!1}}):this._state.loadedItems,i=n.length;s&&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:n,count:i}),this._config.callbacks.onSearch?.(e)},0))}_handleKeydown(e){switch(e.key){case"ArrowDown":e.preventDefault(),this._state.isOpen?this._moveActive(1):this._handleOpen();break;case"ArrowUp":e.preventDefault(),this._state.isOpen?this._moveActive(-1):this._handleOpen();break;case"Home":e.preventDefault(),this._state.isOpen&&this._setActive(0);break;case"End":if(e.preventDefault(),this._state.isOpen){const e=Array.from(this._optionsContainer.children);this._setActive(e.length-1)}break;case"PageDown":e.preventDefault(),this._state.isOpen&&this._moveActive(10);break;case"PageUp":e.preventDefault(),this._state.isOpen&&this._moveActive(-10);break;case"Enter":e.preventDefault(),this._state.activeIndex>=0&&this._selectOption(this._state.activeIndex);break;case"Escape":e.preventDefault(),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){const t=Array.from(this._optionsContainer.children),s=Math.max(0,Math.min(t.length-1,this._state.activeIndex+e));this._setActive(s)}_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 s=t[e];"setActive"in s&&"function"==typeof s.setActive?s.setActive(!0):(s.classList.add("smilodon-option--active"),s.setAttribute("aria-selected","true")),s.scrollIntoView({block:"nearest",behavior:"smooth"});const n=t.length;this._announce(`Item ${e+1} of ${n}`);const i=`${this._uniqueId}-option-${e}`;this._input.setAttribute("aria-activedescendant",i)}}_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)),s=this._state.loadedItems.findIndex(e=>t(e).toLowerCase().startsWith(this._typeBuffer));s>=0&&this._setActive(s)}_selectAll(){if("multi"!==this._config.selection.mode)return;const e=Array.from(this._optionsContainer.children),t=this._config.selection.maxSelections||0;e.forEach((e,s)=>{if(!(t>0&&this._state.selectedIndices.size>=t||this._state.selectedIndices.has(s)))if("getConfig"in e&&"function"==typeof e.getConfig){const t=e.getConfig();this._state.selectedIndices.add(s),this._state.selectedItems.set(s,t.item),e.setSelected(!0)}else{const t=this._state.loadedItems[s];t&&(this._state.selectedIndices.add(s),this._state.selectedItems.set(s,t),e.classList.add("smilodon-option--selected"),e.setAttribute("aria-selected","true"))}}),this._updateInputDisplay(),this._emitChange(),this._announce(`Selected all ${e.length} items`)}_announce(e){this._liveRegion&&(this._liveRegion.textContent=e,setTimeout(()=>{this._liveRegion&&(this._liveRegion.textContent="")},1e3))}_selectOption(e){const t=this._state.loadedItems[e];if(!t)return;const s=this._state.selectedIndices.has(e);if("single"===this._config.selection.mode){const s=this._state.selectedIndices.has(e);this._state.selectedIndices.clear(),this._state.selectedItems.clear(),s||(this._state.selectedIndices.add(e),this._state.selectedItems.set(e,t)),this._renderOptions(),this._config.selection.closeOnSelect&&this._handleClose()}else{const n=this._config.selection.maxSelections||0;if(s)this._state.selectedIndices.delete(e),this._state.selectedItems.delete(e);else{if(n>0&&this._state.selectedIndices.size>=n)return void this._announce(`Maximum ${n} selections allowed`);this._state.selectedIndices.add(e),this._state.selectedItems.set(e,t)}this._renderOptions()}this._updateInputDisplay(),this._emitChange();const n=this._config.serverSide.getValueFromItem||(e=>e?.value??e),i=this._config.serverSide.getLabelFromItem||(e=>e?.label??String(e));this._config.callbacks.onSelect?.({item:t,index:e,value:n(t),label:i(t),selected:this._state.selectedIndices.has(e)})}_handleOptionRemove(e){const t=this._optionsContainer.children[e];if(!t)return;this._state.selectedIndices.delete(e),this._state.selectedItems.delete(e),t.setSelected(!1),this._updateInputDisplay(),this._emitChange();const s=t.getConfig();this._emit("remove",{item:s.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,s])=>{const n=document.createElement("span");n.className="selection-badge",n.textContent=t(s);const i=document.createElement("button");i.className="badge-remove",i.innerHTML="×",i.setAttribute("aria-label",`Remove ${t(s)}`),i.addEventListener("click",t=>{t.stopPropagation(),this._state.selectedIndices.delete(e),this._state.selectedItems.delete(e),this._updateInputDisplay(),this._renderOptions(),this._emitChange()}),n.appendChild(i),this._inputContainer.insertBefore(n,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 s;if("multi"===this._config.selection.mode&&t.length>1){const e=this._dropdown.getBoundingClientRect(),n=this._dropdown.scrollTop+e.height/2;let i=t[0],o=1/0;for(const e of t){const t=`${this._uniqueId}-option-${e}`,s=this._optionsContainer.querySelector(`[id="${t}"]`);if(s){const t=s.offsetTop,r=Math.abs(t-n);r<o&&(o=r,i=e)}}s=i}else s="first"===e?t[0]:t[t.length-1];const n=`${this._uniqueId}-option-${s}`,i=this._optionsContainer.querySelector(`[id="${n}"]`);i&&(i.scrollIntoView({block:this._config.scrollToSelected.block||"center",behavior:"smooth"}),this._setActive(s))}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,this._renderOptions()}_showBusyBucket(){}_hideBusyBucket(){}_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),s=e.map(t),n=Array.from(this._state.selectedIndices);this._emit("change",{selectedItems:e,selectedValues:s,selectedIndices:n}),this._config.callbacks.onChange?.(e,s)}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 s=this._state.loadedItems.length;if(this._state.preserveScrollPosition&&this._dropdown){const e=this._state.lastScrollPosition;s>t&&(this._state.isBusy=!1),this._renderOptions(),this._dropdown.scrollTop=e,requestAnimationFrame(()=>{this._dropdown&&(this._dropdown.scrollTop=e)}),s>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((s,n)=>{e.includes(t(s))&&(this._state.selectedIndices.add(n),this._state.selectedItems.set(n,s))}),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")),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)),s=this._state.searchQuery.toLowerCase();if(this._state.groupedItems.length>0&&!s)this._state.groupedItems.forEach(s=>{const n=document.createElement("div");n.className="group-header",n.textContent=s.label,Object.assign(n.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(n),s.options.forEach(s=>{const n=this._state.loadedItems.indexOf(s);-1!==n&&this._renderSingleOption(s,n,e,t)})});else{let n=!1;if(this._state.loadedItems.forEach((i,o)=>{if(s)try{if(!String(t(i)).toLowerCase().includes(s))return}catch(e){return}n=!0,this._renderSingleOption(i,o,e,t)}),!n&&!this._state.isBusy){const e=document.createElement("div");e.className="empty-state",e.textContent=s?`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()}_renderSingleOption(e,t,s,n){const i=document.createElement("div");i.className="option",i.id=`${this._uniqueId}-option-${t}`;const o=s(e),r=n(e);i.textContent=r,i.dataset.value=String(o),i.dataset.index=String(t);this._state.selectedIndices.has(t)?(i.classList.add("selected"),i.setAttribute("aria-selected","true")):i.setAttribute("aria-selected","false"),i.addEventListener("click",()=>{this._selectOption(t)}),this._optionsContainer.appendChild(i)}_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 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:s,disabled:n,active:i,render:o,showRemoveButton:r}=this._config;this._container.innerHTML="",this._container.classList.toggle("selected",s),this._container.classList.toggle("disabled",n||!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 s=o(e,t);"string"==typeof s?a.innerHTML=s:a.appendChild(s)}else{const e=this._getLabel();a.textContent=e}this._container.appendChild(a),r&&s&&(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(s)),n&&this.setAttribute("aria-disabled","true"),this.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 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"}),s=URL.createObjectURL(t);this.worker=new Worker(s),this.worker.onmessage=this.handleMessage.bind(this),this.worker.onerror=this.handleError.bind(this),URL.revokeObjectURL(s)}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:s,data:n,error:i}=e.data,o=this.pending.get(t);o&&(clearTimeout(o.timeout),this.pending.delete(t),s?o.resolve(n):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,s=5e3){if(!this.worker)return this.executeFallback(e,t);const n="req_"+this.nextId++;return new Promise((i,o)=>{const r=setTimeout(()=>{this.pending.delete(n),o(new Error("Worker timeout"))},s);this.pending.set(n,{resolve:i,reject:o,timeout:r}),this.worker.postMessage({id:n,type:e,payload:t})})}async executeFallback(e,t){switch(e){case"transform":{const{items:e,transformer:s}=t,n=new Function("item","index",`return (${s})(item, index)`);return e.map((e,t)=>n(e,t))}case"search":{const{items:e,query:s,fuzzy:n}=t,i=s.toLowerCase(),o=[];return e.forEach((e,t)=>{const s=String(e).toLowerCase();if(n){let n=0;for(let e=0;e<s.length&&n<i.length;e++)s[e]===i[n]&&n++;n===i.length&&o.push({item:e,index:t})}else s.includes(i)&&o.push({item:e,index:t})}),o}case"filter":{const{items:e,predicate:s}=t,n=new Function("item","index",`return (${s})(item, index)`);return e.filter((e,t)=>n(e,t))}case"sort":{const{items:e,comparator:s}=t,n=new Function("a","b",`return (${s})(a, b)`);return[...e].sort(n)}default:throw new Error(`Unknown operation: ${e}`)}}async transform(e,t){return this.execute("transform",{items:e,transformer:t.toString()})}async search(e,t,s=!1){return this.execute("search",{items:e,query:t,fuzzy:s})}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 s=performance.now();return{result:await t(),duration:performance.now()-s}}function measureSync(e,t){const s=performance.now();return{result:t(),duration:performance.now()-s}}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,s){const n=document.createElement(e);if(t)for(const[e,s]of Object.entries(t))e.startsWith("on")||"style"===e?console.warn(`[NativeSelect Security] Blocked attribute: ${e}`):n.setAttribute(e,s);return void 0!==s&&(n.textContent=s),n}function setCSSProperties(e,t){for(const[s,n]of Object.entries(t))s.startsWith("--")?e.style.setProperty(s,n):console.warn(`[NativeSelect Security] CSS property must start with --: ${s}`)}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 s=e.getAttribute("content");s&&t.push(s)}),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,s){e.classList.toggle(t,s)}function setCustomProperties(e,t){for(const[s,n]of Object.entries(t))s.startsWith("--")?e.style.setProperty(s,n):"production"!==process.env.NODE_ENV&&console.warn(`[NativeSelect CSP] Custom property must start with --: "${s}". 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