forge-select 0.6.0 → 0.7.1

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.d.cts CHANGED
@@ -23,13 +23,13 @@ interface OptionGroup {
23
23
  type DataItem = Option | OptionGroup;
24
24
  interface AjaxConfig {
25
25
  /** GET endpoint. Optional when `request` supplies a custom transport. */
26
- url?: string | ((query: string, page: number) => string);
26
+ url?: string | ((query: string, page: number, cursor?: string) => string);
27
27
  /**
28
28
  * Custom transport for POST/authenticated/GraphQL requests. Takes precedence
29
29
  * over `url`; the returned payload is passed through `transform`.
30
30
  */
31
- request?: (query: string, page: number, signal: AbortSignal) => Promise<unknown>;
32
- params?: (query: string, page: number) => Record<string, unknown>;
31
+ request?: (query: string, page: number, signal: AbortSignal, cursor?: string) => Promise<unknown>;
32
+ params?: (query: string, page: number, cursor?: string) => Record<string, unknown>;
33
33
  /** Debounce in milliseconds. Default 250. */
34
34
  debounce?: number;
35
35
  /** Load the initial empty query when the dropdown opens. Default true. */
@@ -54,7 +54,8 @@ interface AjaxConfig {
54
54
  */
55
55
  transform?: (response: unknown) => Option[] | {
56
56
  options: Option[];
57
- hasMore: boolean;
57
+ hasMore?: boolean;
58
+ nextCursor?: string | null;
58
59
  };
59
60
  }
60
61
  interface ForgeSelectPlugin {
@@ -65,6 +66,10 @@ interface ForgeSelectPlugin {
65
66
  onDestroy?(select: ForgeSelect): void;
66
67
  }
67
68
  type TemplateFn = (option: Option) => string | Node;
69
+ type TemplateSanitizer = (html: string, option: Option) => string;
70
+ type SelectionGuard = (option: Option) => boolean;
71
+ type CreateOption = (label: string) => Option | undefined | Promise<Option | undefined>;
72
+ type MissingSelectionPolicy = "preserve" | "prune" | "error";
68
73
  type SearchField = "label" | "description" | `meta.${string}`;
69
74
  type SearchScorer = (option: Option, query: string, normalizedQuery: string) => number;
70
75
  interface ForgeSelectOptions {
@@ -107,6 +112,20 @@ interface ForgeSelectOptions {
107
112
  ajax?: AjaxConfig;
108
113
  templateResult?: TemplateFn;
109
114
  templateSelection?: TemplateFn;
115
+ /** Sanitizes string template output before it is assigned to innerHTML. */
116
+ sanitizeTemplate?: TemplateSanitizer;
117
+ /** Return false to cancel an interactive selection. */
118
+ beforeSelect?: SelectionGuard;
119
+ /** Return false to cancel an interactive removal. */
120
+ beforeUnselect?: SelectionGuard;
121
+ /** Return false to cancel creation before createOption is called. */
122
+ beforeCreate?: (label: string) => boolean;
123
+ /** Creates or validates a tag, synchronously or asynchronously. */
124
+ createOption?: CreateOption;
125
+ /** Behavior when setData() no longer contains selected values. Default preserve. */
126
+ missingSelectionPolicy?: MissingSelectionPolicy;
127
+ /** Warn in development, throw, or ignore duplicate option values. Default warn. */
128
+ duplicateValuePolicy?: "ignore" | "warn" | "error";
110
129
  /**
111
130
  * Custom match predicate, replacing the built-in label/description
112
131
  * substring match. Receives the trimmed (not lowercased) query.
@@ -199,6 +218,8 @@ declare class ForgeSelect {
199
218
  private opts;
200
219
  private strings;
201
220
  private data;
221
+ private optionByValue;
222
+ private optionByLabel;
202
223
  private selected;
203
224
  private selectedOptions;
204
225
  private suppressNextTagClick;
@@ -224,6 +245,7 @@ declare class ForgeSelect {
224
245
  private typeaheadBuffer;
225
246
  private typeaheadTimer;
226
247
  private rowContentCache;
248
+ private rowElementCache;
227
249
  private rowHeightCache;
228
250
  private rowOffsetsCache;
229
251
  private scrollRafId;
@@ -239,6 +261,9 @@ declare class ForgeSelect {
239
261
  private ajaxController;
240
262
  private remoteLoaded;
241
263
  private remoteCache;
264
+ private remoteInFlight;
265
+ private nextCursor;
266
+ private prefetchControllers;
242
267
  private loadError;
243
268
  private originalDisplay;
244
269
  private originalDisabled;
@@ -337,9 +362,12 @@ declare class ForgeSelect {
337
362
  private syncNativeSelect;
338
363
  private findOption;
339
364
  private findOptionByLabel;
365
+ private rebuildOptionIndexes;
340
366
  /** Selects an existing option matching `label` exactly, or creates and selects a new one. */
341
367
  private createTag;
368
+ private addCreatedOption;
342
369
  private createFromQuery;
370
+ private finishCreateFromQuery;
343
371
  private activateNavItem;
344
372
  private renderValue;
345
373
  /**
@@ -359,6 +387,13 @@ declare class ForgeSelect {
359
387
  private buildRows;
360
388
  private hasExactMatch;
361
389
  private usesVirtualScroll;
390
+ /**
391
+ * Drops every per-row cache at once. Rendered content, recycled <li>
392
+ * elements, and measured heights are all keyed off the current `data`, so
393
+ * they must be invalidated together whenever `data` is replaced — clearing
394
+ * only some of them leaves recycled rows carrying state from the old list.
395
+ */
396
+ private clearRowCaches;
362
397
  private rowKey;
363
398
  private measuredRowHeight;
364
399
  private rowOffset;
@@ -367,6 +402,7 @@ declare class ForgeSelect {
367
402
  private announceStatus;
368
403
  private renderRows;
369
404
  private renderRow;
405
+ private renderOptionRow;
370
406
  /**
371
407
  * Rendered row content is cached per option value and cloned on each render,
372
408
  * so templates run once per option instead of once per scroll frame.
@@ -381,6 +417,7 @@ declare class ForgeSelect {
381
417
  private scheduleRemoteLoad;
382
418
  private setLoading;
383
419
  private remoteCacheKey;
420
+ private fetchRemoteResult;
384
421
  private requestRemote;
385
422
  private prefetchRemote;
386
423
  /**
@@ -392,4 +429,4 @@ declare class ForgeSelect {
392
429
  private loadRemote;
393
430
  }
394
431
 
395
- export { type AjaxConfig, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectEventHandler, type ForgeSelectEventMap, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectUpdateOptions, type ForgeSelectValue, type MaximumSelectionEvent, type Option, type OptionGroup, type SearchField, type SearchScorer, type SetSearchQueryOptions, type SetValueOptions, type TemplateFn, ForgeSelect as default };
432
+ export { type AjaxConfig, type CreateOption, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectEventHandler, type ForgeSelectEventMap, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectUpdateOptions, type ForgeSelectValue, type MaximumSelectionEvent, type MissingSelectionPolicy, type Option, type OptionGroup, type SearchField, type SearchScorer, type SelectionGuard, type SetSearchQueryOptions, type SetValueOptions, type TemplateFn, type TemplateSanitizer, ForgeSelect as default };
package/dist/index.d.ts CHANGED
@@ -23,13 +23,13 @@ interface OptionGroup {
23
23
  type DataItem = Option | OptionGroup;
24
24
  interface AjaxConfig {
25
25
  /** GET endpoint. Optional when `request` supplies a custom transport. */
26
- url?: string | ((query: string, page: number) => string);
26
+ url?: string | ((query: string, page: number, cursor?: string) => string);
27
27
  /**
28
28
  * Custom transport for POST/authenticated/GraphQL requests. Takes precedence
29
29
  * over `url`; the returned payload is passed through `transform`.
30
30
  */
31
- request?: (query: string, page: number, signal: AbortSignal) => Promise<unknown>;
32
- params?: (query: string, page: number) => Record<string, unknown>;
31
+ request?: (query: string, page: number, signal: AbortSignal, cursor?: string) => Promise<unknown>;
32
+ params?: (query: string, page: number, cursor?: string) => Record<string, unknown>;
33
33
  /** Debounce in milliseconds. Default 250. */
34
34
  debounce?: number;
35
35
  /** Load the initial empty query when the dropdown opens. Default true. */
@@ -54,7 +54,8 @@ interface AjaxConfig {
54
54
  */
55
55
  transform?: (response: unknown) => Option[] | {
56
56
  options: Option[];
57
- hasMore: boolean;
57
+ hasMore?: boolean;
58
+ nextCursor?: string | null;
58
59
  };
59
60
  }
60
61
  interface ForgeSelectPlugin {
@@ -65,6 +66,10 @@ interface ForgeSelectPlugin {
65
66
  onDestroy?(select: ForgeSelect): void;
66
67
  }
67
68
  type TemplateFn = (option: Option) => string | Node;
69
+ type TemplateSanitizer = (html: string, option: Option) => string;
70
+ type SelectionGuard = (option: Option) => boolean;
71
+ type CreateOption = (label: string) => Option | undefined | Promise<Option | undefined>;
72
+ type MissingSelectionPolicy = "preserve" | "prune" | "error";
68
73
  type SearchField = "label" | "description" | `meta.${string}`;
69
74
  type SearchScorer = (option: Option, query: string, normalizedQuery: string) => number;
70
75
  interface ForgeSelectOptions {
@@ -107,6 +112,20 @@ interface ForgeSelectOptions {
107
112
  ajax?: AjaxConfig;
108
113
  templateResult?: TemplateFn;
109
114
  templateSelection?: TemplateFn;
115
+ /** Sanitizes string template output before it is assigned to innerHTML. */
116
+ sanitizeTemplate?: TemplateSanitizer;
117
+ /** Return false to cancel an interactive selection. */
118
+ beforeSelect?: SelectionGuard;
119
+ /** Return false to cancel an interactive removal. */
120
+ beforeUnselect?: SelectionGuard;
121
+ /** Return false to cancel creation before createOption is called. */
122
+ beforeCreate?: (label: string) => boolean;
123
+ /** Creates or validates a tag, synchronously or asynchronously. */
124
+ createOption?: CreateOption;
125
+ /** Behavior when setData() no longer contains selected values. Default preserve. */
126
+ missingSelectionPolicy?: MissingSelectionPolicy;
127
+ /** Warn in development, throw, or ignore duplicate option values. Default warn. */
128
+ duplicateValuePolicy?: "ignore" | "warn" | "error";
110
129
  /**
111
130
  * Custom match predicate, replacing the built-in label/description
112
131
  * substring match. Receives the trimmed (not lowercased) query.
@@ -199,6 +218,8 @@ declare class ForgeSelect {
199
218
  private opts;
200
219
  private strings;
201
220
  private data;
221
+ private optionByValue;
222
+ private optionByLabel;
202
223
  private selected;
203
224
  private selectedOptions;
204
225
  private suppressNextTagClick;
@@ -224,6 +245,7 @@ declare class ForgeSelect {
224
245
  private typeaheadBuffer;
225
246
  private typeaheadTimer;
226
247
  private rowContentCache;
248
+ private rowElementCache;
227
249
  private rowHeightCache;
228
250
  private rowOffsetsCache;
229
251
  private scrollRafId;
@@ -239,6 +261,9 @@ declare class ForgeSelect {
239
261
  private ajaxController;
240
262
  private remoteLoaded;
241
263
  private remoteCache;
264
+ private remoteInFlight;
265
+ private nextCursor;
266
+ private prefetchControllers;
242
267
  private loadError;
243
268
  private originalDisplay;
244
269
  private originalDisabled;
@@ -337,9 +362,12 @@ declare class ForgeSelect {
337
362
  private syncNativeSelect;
338
363
  private findOption;
339
364
  private findOptionByLabel;
365
+ private rebuildOptionIndexes;
340
366
  /** Selects an existing option matching `label` exactly, or creates and selects a new one. */
341
367
  private createTag;
368
+ private addCreatedOption;
342
369
  private createFromQuery;
370
+ private finishCreateFromQuery;
343
371
  private activateNavItem;
344
372
  private renderValue;
345
373
  /**
@@ -359,6 +387,13 @@ declare class ForgeSelect {
359
387
  private buildRows;
360
388
  private hasExactMatch;
361
389
  private usesVirtualScroll;
390
+ /**
391
+ * Drops every per-row cache at once. Rendered content, recycled <li>
392
+ * elements, and measured heights are all keyed off the current `data`, so
393
+ * they must be invalidated together whenever `data` is replaced — clearing
394
+ * only some of them leaves recycled rows carrying state from the old list.
395
+ */
396
+ private clearRowCaches;
362
397
  private rowKey;
363
398
  private measuredRowHeight;
364
399
  private rowOffset;
@@ -367,6 +402,7 @@ declare class ForgeSelect {
367
402
  private announceStatus;
368
403
  private renderRows;
369
404
  private renderRow;
405
+ private renderOptionRow;
370
406
  /**
371
407
  * Rendered row content is cached per option value and cloned on each render,
372
408
  * so templates run once per option instead of once per scroll frame.
@@ -381,6 +417,7 @@ declare class ForgeSelect {
381
417
  private scheduleRemoteLoad;
382
418
  private setLoading;
383
419
  private remoteCacheKey;
420
+ private fetchRemoteResult;
384
421
  private requestRemote;
385
422
  private prefetchRemote;
386
423
  /**
@@ -392,4 +429,4 @@ declare class ForgeSelect {
392
429
  private loadRemote;
393
430
  }
394
431
 
395
- export { type AjaxConfig, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectEventHandler, type ForgeSelectEventMap, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectUpdateOptions, type ForgeSelectValue, type MaximumSelectionEvent, type Option, type OptionGroup, type SearchField, type SearchScorer, type SetSearchQueryOptions, type SetValueOptions, type TemplateFn, ForgeSelect as default };
432
+ export { type AjaxConfig, type CreateOption, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectEventHandler, type ForgeSelectEventMap, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectUpdateOptions, type ForgeSelectValue, type MaximumSelectionEvent, type MissingSelectionPolicy, type Option, type OptionGroup, type SearchField, type SearchScorer, type SelectionGuard, type SetSearchQueryOptions, type SetValueOptions, type TemplateFn, type TemplateSanitizer, ForgeSelect as default };
@@ -1,2 +1,2 @@
1
- "use strict";var ForgeSelectBundle=(()=>{var L=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var Q=(a,e)=>{for(var t in e)L(a,t,{get:e[t],enumerable:!0})},G=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of K(e))!U.call(a,s)&&s!==t&&L(a,s,{get:()=>e[s],enumerable:!(i=z(e,s))||i.enumerable});return a};var W=a=>G(L({},"__esModule",{value:!0}),a);var ie={};Q(ie,{ForgeSelect:()=>v,default:()=>v});var S=class{constructor(){this.handlers=new Map}on(e,t){let i=this.handlers.get(e);i||(i=new Set,this.handlers.set(e,i)),i.add(t)}off(e,t){this.handlers.get(e)?.delete(t)}emit(e,...t){let i=this.handlers.get(e);if(i)for(let s of[...i])s(...t)}clear(){this.handlers.clear()}};function N(a,e,t,i=4){let s=t-a.bottom,n=a.top,r=e>s&&n>s;return{dropUp:r,top:r?a.top-e-i:a.bottom+i}}var C={en:{noResults:"No results found",loading:"Loading\u2026",loadingMore:"Loading more\u2026",errorLoading:"Could not load options",createOption:'Create "{query}"',clearSelection:"Clear selection",removeItem:"Remove {label}",search:"Search",reorderHint:"{label}. Press Alt+Left or Alt+Right to reorder.",minSearchLength:"Type {count} or more characters to search",maximumSelected:"Maximum of {count} selections reached"},vi:{noResults:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3",loading:"\u0110ang t\u1EA3i\u2026",loadingMore:"\u0110ang t\u1EA3i th\xEAm\u2026",errorLoading:"Kh\xF4ng th\u1EC3 t\u1EA3i t\xF9y ch\u1ECDn",createOption:'T\u1EA1o "{query}"',clearSelection:"X\xF3a l\u1EF1a ch\u1ECDn",removeItem:"X\xF3a {label}",search:"T\xECm ki\u1EBFm",reorderHint:"{label}. Nh\u1EA5n Alt+Tr\xE1i ho\u1EB7c Alt+Ph\u1EA3i \u0111\u1EC3 s\u1EAFp x\u1EBFp l\u1EA1i.",minSearchLength:"Nh\u1EADp th\xEAm {count} k\xFD t\u1EF1 \u0111\u1EC3 t\xECm ki\u1EBFm",maximumSelected:"\u0110\xE3 \u0111\u1EA1t t\u1ED1i \u0111a {count} l\u1EF1a ch\u1ECDn"}};function T(a){return typeof a=="string"?C[a]??C.en:{...C.en,...a}}function p(a,e){return a.replace(/\{(\w+)\}/g,(t,i)=>e[i]??t)}function V(a){let e=[];for(let t of Array.from(a.children))t instanceof HTMLOptGroupElement?e.push({label:t.label,options:Array.from(t.querySelectorAll("option")).map(F)}):t instanceof HTMLOptionElement&&e.push(F(t));return e}function F(a){let e=a.parentElement instanceof HTMLOptGroupElement&&a.parentElement.disabled;return{value:a.value,label:a.textContent?.trim()??a.value,disabled:a.disabled||e||void 0}}function b(a,e,t,i="row"){if(t){let s=t(e);typeof s=="string"?a.innerHTML=s:a.append(s);return}if(!e.avatar&&!e.description){a.textContent=e.label;return}if(e.avatar){let s=document.createElement("img");s.className=i==="row"?"forge-select__option-avatar":"forge-select__inline-avatar",s.src=e.avatar,s.alt="",s.setAttribute("loading","lazy"),s.setAttribute("decoding","async"),a.append(s)}if(i==="row"&&e.description){let s=document.createElement("span");s.className="forge-select__option-body";let n=document.createElement("span");n.className="forge-select__option-label",n.textContent=e.label;let r=document.createElement("span");r.className="forge-select__option-desc",r.textContent=e.description,s.append(n,r),a.append(s)}else{let s=document.createElement("span");s.className="forge-select__option-label",s.textContent=e.label,a.append(s)}}function j(a,e,t){if(!a.url)throw new Error("ForgeSelect: ajax requires either url or request.");if(typeof a.url=="function")return a.url(e,t);if(!a.params)return a.url;let i=new URLSearchParams;for(let[n,r]of Object.entries(a.params(e,t)))i.set(n,String(r));let s=a.url.includes("?")?"&":"?";return`${a.url}${s}${i.toString()}`}function A(a,e){let t=a.transform?a.transform(e):e;if(Array.isArray(t))return{options:t,hasMore:!1};if(!t||!Array.isArray(t.options))throw new Error("ForgeSelect: ajax.transform must return an array of options, or an object shaped like { options: Option[], hasMore?: boolean }.");return{options:t.options,hasMore:a.pagination?!!t.hasMore:!1}}var y=class{constructor(){this.entries=new Map}get(e,t=Date.now()){let i=this.entries.get(e);if(i){if(i.expiresAt<=t){this.entries.delete(e);return}return i.value}}set(e,t,i,s=Date.now()){if(!(i<=0)){if(this.entries.size>=50&&!this.entries.has(e)){let n=this.entries.keys().next().value;this.entries.delete(n)}this.entries.set(e,{value:t,expiresAt:s+i})}}clear(){this.entries.clear()}};function f(a,e=!0){let t=a.toLocaleLowerCase();return e?t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/đ/g,"d"):t}function X(a,e){if(e==="label")return a.label;if(e==="description")return a.description??"";let t=e.slice(5).split("."),i=a.meta;for(let s of t){if(!i||typeof i!="object")return"";i=i[s]}return i==null?"":String(i)}var I=class{constructor(){this.cache=new WeakMap}clear(){this.cache=new WeakMap}score(e,t,i){let s=f(t.trim(),i.accentInsensitive);if(!s)return 1;if(i.scorer)return i.scorer(e,t.trim(),s);let n=`${i.accentInsensitive?"1":"0"}:${i.fields.join("\0")}`,r=this.cache.get(e);r||(r=new Map,this.cache.set(e,r));let o=r.get(n);if(o||(o=i.fields.map(c=>f(X(e,c),i.accentInsensitive)),r.set(n,o)),!(i.tokenSearch?s.split(/\s+/).filter(Boolean):[s]).every(c=>o.some(d=>d.includes(c))))return 0;let l=o[i.fields.indexOf("label")];return l===s?4:l?.startsWith(s)?3:l?.includes(s)?2:1}};function q(a,e,t=!0){let i=f(e.trim(),t).split(/\s+/).filter(Boolean);if(!i.length)return[];let s=f(a,t),n=[];for(let r of i){let o=s.indexOf(r);o>=0&&n.push([o,o+r.length])}return n.sort((r,o)=>r[0]-o[0])}function g(a){return a.options!==void 0}var R=a=>!!a.disabled;function x(a,e=R){if(!a.children)return[];let t=[];for(let i of a.children)e(i)||t.push(i.value),t.push(...x(i,e));return t}function w(a,e,t=R){if(!a.children?.length)return e.includes(a.value)?"all":"none";let i=a.children.filter(s=>!t(s)).map(s=>w(s,e,t));return i.length===0?"none":i.every(s=>s==="all")?"all":i.every(s=>s==="none")?"none":"some"}function P(a,e){let t=i=>{for(let s of i){if(s.value===e)return s;let n=s.children?t(s.children):void 0;if(n)return n}};for(let i of a){let s=t(g(i)?i.options:[i]);if(s)return s}}function H(a,e,t=R){let i=s=>{if(!s.children?.length)return;for(let o of s.children)i(o);let n=w(s,e,t),r=e.indexOf(s.value);n==="all"&&r===-1?e.push(s.value):n!=="all"&&r!==-1&&e.splice(r,1)};for(let s of a)(g(s)?s.options:[s]).forEach(i)}function M(a){let e=new Set,t=i=>{e.add(i.value),i.children?.forEach(t)};for(let i of a)(g(i)?i.options:[i]).forEach(t);return e}function B(a,e){return a.length===e.length&&a.every((t,i)=>t===e[i])}var Y=36,O=5,Z=100,J=2e3,$=10,ee=500,te=0,v=class{constructor(e,t={}){this.selected=[];this.selectedOptions=new Map;this.suppressNextTagClick=!1;this.emitter=new S;this.uid=`forge-select-${++te}`;this.searchInput=null;this.portalHost=null;this.isOpen=!1;this.isDisabled=!1;this.destroyed=!1;this.query="";this.rows=[];this.navItems=[];this.highlightedIndex=-1;this.typeaheadBuffer="";this.typeaheadTimer=null;this.rowContentCache=new Map;this.rowHeightCache=new Map;this.rowOffsetsCache=null;this.scrollRafId=null;this.ancestorScrollRafId=null;this.searchIndex=new I;this.expandedValues=new Set;this.loading=!1;this.loadingMore=!1;this.page=0;this.hasMore=!0;this.ajaxTimer=null;this.ajaxRequestId=0;this.ajaxController=null;this.remoteLoaded=!1;this.remoteCache=new y;this.loadError=null;this.originalDisplay="";this.originalDisabled=!1;this.nativeSelect=null;this.nativeForm=null;this.syncingNative=!1;this.isOptionDisabled=e=>e.disabled===!0||(this.opts.isOptionDisabled?.(e)??!1);this.pointerDownOnControl=!1;this.onDocumentMouseDown=e=>{let t=e.target;!this.root.contains(t)&&!this.portalHost?.contains(t)&&this.close()};this.onWindowResize=()=>{this.positionDropdown()};this.onAncestorScroll=()=>{this.portalHost&&this.ancestorScrollRafId==null&&(this.ancestorScrollRafId=requestAnimationFrame(()=>{this.ancestorScrollRafId=null,this.positionDropdown()}))};this.onNativeInvalid=e=>{e.preventDefault(),this.control.classList.add("forge-select__control--invalid"),this.control.setAttribute("aria-invalid","true"),this.isOpen||this.open(),this.control.focus(),this.emitter.emit("invalid",this.nativeSelect?.validationMessage??"")};this.onNativeChange=()=>{if(!this.nativeSelect||this.destroyed||this.syncingNative)return;let e=Array.from(this.nativeSelect.selectedOptions,t=>t.value);this.applyNativeValues(e)};this.onFormReset=()=>{if(!this.nativeSelect||this.destroyed)return;let e=Array.from(this.nativeSelect.options).filter(t=>t.defaultSelected).map(t=>t.value);this.applyNativeValues(e)};let i=typeof e=="string"?document.querySelector(e):e;if(!i)throw new Error(`ForgeSelect: target element not found: ${String(e)}`);this.el=i;let s=i instanceof HTMLSelectElement?i:null;if(this.nativeSelect=s,this.nativeForm=s?.form??null,this.originalDisplay=i.style.display,this.originalDisabled=s?.disabled??!1,this.opts={placeholder:t.placeholder??"",searchable:t.searchable??!0,multiple:t.multiple??s?.multiple??!1,clearable:t.clearable??!1,allowCreate:t.allowCreate??!1,sortable:t.sortable??!1,closeOnSelect:t.closeOnSelect??!1,maxSelections:t.maxSelections==null||!Number.isFinite(t.maxSelections)?void 0:Math.max(0,Math.floor(t.maxSelections)),theme:t.theme??"default",disabled:t.disabled??s?.disabled??!1,required:t.required??s?.required??!1,data:t.data,ajax:t.ajax,templateResult:t.templateResult,templateSelection:t.templateSelection,filterOption:t.filterOption,searchFields:t.searchFields??["label","description"],tokenSearch:t.tokenSearch??!0,accentInsensitive:t.accentInsensitive??!0,searchScorer:t.searchScorer,highlightSearch:t.highlightSearch??!1,minSearchLength:Math.max(0,Math.floor(t.minSearchLength??0)),minResultsForSearch:Math.max(0,Math.floor(t.minResultsForSearch??0)),isOptionDisabled:t.isOptionDisabled,virtualScroll:t.virtualScroll,itemHeight:typeof t.itemHeight=="number"?Math.max(1,t.itemHeight):Y,variableItemHeight:t.itemHeight==="auto",language:t.language??"en",plugins:t.plugins??[],openOnFocus:t.openOnFocus??!1,dropdownParent:t.dropdownParent},this.strings=T(this.opts.language),this.plugins=this.opts.plugins,s&&(s.required=this.opts.required),this.data=this.opts.data??(s?V(s):[]),s&&!this.opts.data){let n=Array.from(s.options),r=s.multiple||s.selectedIndex>0||n.some(o=>o.defaultSelected);for(let o of n)r&&o.selected&&this.selectValue(o.value,!1)}this.buildDom(),this.renderValue(),this.opts.disabled&&this.disable(),s?.addEventListener("change",this.onNativeChange),s?.addEventListener("invalid",this.onNativeInvalid),this.nativeForm?.addEventListener("reset",this.onFormReset);for(let n of this.plugins)n.onInit?.(this);for(let n of this.opts.ajax?.prefetch??[])this.prefetchRemote(n)}applyNativeValues(e){this.selected=[];for(let t of this.opts.multiple?e:e.slice(0,1))this.selectValue(t,!1);this.renderValue(),this.isOpen&&this.renderList(),this.emitter.emit("change",this.getValue())}open(){if(!(this.isOpen||this.isDisabled||this.destroyed)){this.isOpen=!0,this.dropdown.hidden=!1,this.root.classList.add("forge-select--open"),this.control.setAttribute("aria-expanded","true"),document.addEventListener("mousedown",this.onDocumentMouseDown),this.opts.ajax&&(this.opts.ajax.loadOnOpen??!0)&&!this.remoteLoaded&&this.scheduleRemoteLoad(this.query,0),this.renderList(),this.positionDropdown(),window.addEventListener("resize",this.onWindowResize),document.addEventListener("scroll",this.onAncestorScroll,!0),this.searchInput&&!this.searchInput.hidden&&this.searchInput.focus(),this.emitter.emit("open");for(let e of this.plugins)e.onOpen?.(this)}}close(){if(this.isOpen){this.isOpen=!1,this.dropdown.hidden=!0,this.root.classList.remove("forge-select--open"),this.root.classList.remove("forge-select--drop-up"),this.control.setAttribute("aria-expanded","false"),document.removeEventListener("mousedown",this.onDocumentMouseDown),window.removeEventListener("resize",this.onWindowResize),document.removeEventListener("scroll",this.onAncestorScroll,!0),this.ancestorScrollRafId!=null&&(cancelAnimationFrame(this.ancestorScrollRafId),this.ancestorScrollRafId=null),this.scrollRafId!=null&&(cancelAnimationFrame(this.scrollRafId),this.scrollRafId=null),this.typeaheadTimer&&(clearTimeout(this.typeaheadTimer),this.typeaheadTimer=null),this.typeaheadBuffer="",this.highlightedIndex=-1,this.searchInput&&(this.searchInput.value="",this.query=""),this.emitter.emit("close");for(let e of this.plugins)e.onClose?.(this)}}positionDropdown(){let e=this.control.getBoundingClientRect(),t=N(e,this.dropdown.offsetHeight,window.innerHeight);this.root.classList.toggle("forge-select--drop-up",t.dropUp),this.portalHost&&(this.portalHost.style.top=`${t.top}px`,this.portalHost.style.left=`${e.left}px`,this.portalHost.style.width=`${e.width}px`)}destroy(){if(!this.destroyed){this.close();for(let e of this.plugins)e.onDestroy?.(this);this.destroyed=!0,this.ajaxTimer&&clearTimeout(this.ajaxTimer),this.ajaxController?.abort(),this.scrollRafId!=null&&cancelAnimationFrame(this.scrollRafId),this.typeaheadTimer&&clearTimeout(this.typeaheadTimer),this.nativeSelect?.removeEventListener("change",this.onNativeChange),this.nativeSelect?.removeEventListener("invalid",this.onNativeInvalid),this.nativeForm?.removeEventListener("reset",this.onFormReset),this.rowContentCache.clear(),this.rowHeightCache.clear(),this.searchIndex.clear(),this.portalHost?.remove(),this.root.remove(),this.el.style.display=this.originalDisplay,this.nativeSelect&&(this.nativeSelect.disabled=this.originalDisabled),this.emitter.clear()}}getValue(){return this.opts.multiple?[...this.selected]:this.selected[0]??null}getSearchQuery(){return this.query}setSearchQuery(e,t={}){this.applySearchQuery(e,t.emitSearch??!0)}isDropdownOpen(){return this.isOpen}updateOptions(e){e.data&&this.setData(e.data),"ajax"in e&&e.ajax!==this.opts.ajax&&(this.opts.ajax=e.ajax,this.remoteLoaded=!1,this.clearRemoteCache()),e.placeholder!==void 0&&(this.opts.placeholder=e.placeholder),e.clearable!==void 0&&(this.opts.clearable=e.clearable),e.allowCreate!==void 0&&(this.opts.allowCreate=e.allowCreate),e.sortable!==void 0&&(this.opts.sortable=e.sortable),e.closeOnSelect!==void 0&&(this.opts.closeOnSelect=e.closeOnSelect),"maxSelections"in e&&(this.opts.maxSelections=e.maxSelections==null||!Number.isFinite(e.maxSelections)?void 0:Math.max(0,Math.floor(e.maxSelections))),e.theme!==void 0&&(this.opts.theme=e.theme,this.root.dataset.theme=e.theme,this.portalHost&&(this.portalHost.dataset.theme=e.theme)),e.required!==void 0&&(this.opts.required=e.required,e.required?this.control.setAttribute("aria-required","true"):this.control.removeAttribute("aria-required"),this.nativeSelect&&(this.nativeSelect.required=e.required)),e.templateResult!==void 0&&(this.opts.templateResult=e.templateResult),e.templateSelection!==void 0&&(this.opts.templateSelection=e.templateSelection),e.filterOption!==void 0&&(this.opts.filterOption=e.filterOption),e.searchFields!==void 0&&(this.opts.searchFields=e.searchFields),e.tokenSearch!==void 0&&(this.opts.tokenSearch=e.tokenSearch),e.accentInsensitive!==void 0&&(this.opts.accentInsensitive=e.accentInsensitive),e.searchScorer!==void 0&&(this.opts.searchScorer=e.searchScorer),e.highlightSearch!==void 0&&(this.opts.highlightSearch=e.highlightSearch),e.minSearchLength!==void 0&&(this.opts.minSearchLength=Math.max(0,Math.floor(e.minSearchLength))),e.minResultsForSearch!==void 0&&(this.opts.minResultsForSearch=Math.max(0,Math.floor(e.minResultsForSearch))),e.isOptionDisabled!==void 0&&(this.opts.isOptionDisabled=e.isOptionDisabled),e.virtualScroll!==void 0&&(this.opts.virtualScroll=e.virtualScroll),e.itemHeight!==void 0&&(this.opts.variableItemHeight=e.itemHeight==="auto",typeof e.itemHeight=="number"&&(this.opts.itemHeight=Math.max(1,e.itemHeight)),this.root.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.portalHost?.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`)),e.language!==void 0&&(this.opts.language=e.language,this.strings=T(e.language),this.clearBtn.setAttribute("aria-label",this.strings.clearSelection),this.searchInput?.setAttribute("aria-label",this.strings.search)),e.openOnFocus!==void 0&&(this.opts.openOnFocus=e.openOnFocus),e.disabled!==void 0&&(e.disabled?this.disable():this.enable()),this.root.classList.toggle("forge-select--sortable",this.opts.sortable&&this.opts.multiple),this.updateSearchVisibility(),this.rowContentCache.clear(),this.rowHeightCache.clear(),this.searchIndex.clear(),this.renderValue(),this.isOpen&&this.renderList()}validate(){let e=(!this.opts.required||this.selected.length>0)&&(this.control.dataset.validationMessage??"")==="";return this.control.classList.toggle("forge-select__control--invalid",!e),this.control.setAttribute("aria-invalid",String(!e)),e}setCustomValidity(e){this.nativeSelect?.setCustomValidity(e),this.control.dataset.validationMessage=e}reportValidity(){let e=this.validate()&&(this.nativeSelect?.checkValidity()??!0);if(!e){let t=this.nativeSelect?.validationMessage??this.control.dataset.validationMessage??"";if(this.nativeSelect)return this.nativeSelect.reportValidity();this.emitter.emit("invalid",t)}return e}reload(){this.opts.ajax&&(this.clearRemoteCache(),this.remoteLoaded=!1,this.scheduleRemoteLoad(this.query,0))}clearRemoteCache(){this.remoteCache.clear()}setValue(e,t={}){let i=e==null?[]:Array.isArray(e)?e:[e],s=this.opts.multiple?i:i.slice(0,1);if(!B(s,this.selected)){this.selected=[];for(let n of s)this.selectValue(n,!1);this.afterSelectionChange(t.emitChange??!0)}}setData(e){this.ajaxTimer&&(clearTimeout(this.ajaxTimer),this.ajaxTimer=null),this.ajaxController?.abort(),this.ajaxController=null,this.ajaxRequestId+=1,this.setLoading(!1),this.loadingMore=!1,this.loadError=null,this.remoteLoaded=!0,this.page=0,this.hasMore=!1,this.data=e,this.opts.data=e,this.updateSearchVisibility(),this.rowContentCache.clear(),this.rowHeightCache.clear(),this.searchIndex.clear(),this.highlightedIndex=-1,this.isOpen&&this.renderList()}selectAll(){if(this.opts.multiple){this.selected=[];for(let e of this.allSelectableValues()){let t=this.findOption(e);t&&this.canSelectOption(t)&&this.selectValue(e,!1)}this.afterSelectionChange()}}clearAll(){this.clearSelection()}enable(){this.isDisabled=!1,this.root.classList.remove("forge-select--disabled"),this.control.tabIndex=0,this.control.setAttribute("aria-disabled","false"),this.nativeSelect&&(this.nativeSelect.disabled=!1)}disable(){this.close(),this.isDisabled=!0,this.root.classList.add("forge-select--disabled"),this.control.tabIndex=-1,this.control.setAttribute("aria-disabled","true"),this.nativeSelect&&(this.nativeSelect.disabled=!0)}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}applyAccessibleName(){let e=this.el.getAttribute("aria-labelledby"),t=this.el.getAttribute("aria-label");if(e)this.control.setAttribute("aria-labelledby",e);else if(t)this.control.setAttribute("aria-label",t);else if(this.el.id){let i=Array.from(document.getElementsByTagName("label")).find(s=>s.htmlFor===this.el.id);i&&(i.id||(i.id=`${this.uid}-label`),this.control.setAttribute("aria-labelledby",i.id))}}shouldShowSearch(){return this.opts.searchable&&(this.opts.ajax!=null||M(this.data).size>=this.opts.minResultsForSearch)}updateSearchVisibility(){this.searchInput&&(this.searchInput.hidden=!this.shouldShowSearch(),this.searchInput.hidden&&(this.searchInput.value="",this.query=""))}buildDom(){let e=typeof this.opts.dropdownParent=="string"?document.querySelector(this.opts.dropdownParent):this.opts.dropdownParent;if(this.opts.dropdownParent&&!e)throw new Error(`ForgeSelect: dropdown parent not found: ${String(this.opts.dropdownParent)}`);this.root=document.createElement("div"),this.root.className="forge-select",this.root.dataset.theme=this.opts.theme,this.root.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.opts.sortable&&this.opts.multiple&&this.root.classList.add("forge-select--sortable"),this.control=document.createElement("div"),this.control.className="forge-select__control",this.control.setAttribute("role","combobox"),this.control.setAttribute("aria-haspopup","listbox"),this.control.setAttribute("aria-expanded","false"),this.control.setAttribute("aria-controls",`${this.uid}-list`),this.opts.required&&this.control.setAttribute("aria-required","true"),this.control.tabIndex=0,this.applyAccessibleName(),this.valueEl=document.createElement("div"),this.valueEl.className="forge-select__value",this.clearBtn=document.createElement("button"),this.clearBtn.type="button",this.clearBtn.className="forge-select__clear",this.clearBtn.setAttribute("aria-label",this.strings.clearSelection),this.clearBtn.textContent="\xD7",this.clearBtn.hidden=!0;let t=document.createElement("span");t.className="forge-select__arrow",t.setAttribute("aria-hidden","true"),this.control.append(this.valueEl,this.clearBtn,t),this.dropdown=document.createElement("div"),this.dropdown.className="forge-select__dropdown",this.dropdown.hidden=!0,this.opts.searchable&&(this.searchInput=document.createElement("input"),this.searchInput.type="search",this.searchInput.className="forge-select__search",this.searchInput.setAttribute("aria-label",this.strings.search),this.searchInput.setAttribute("aria-autocomplete","list"),this.searchInput.setAttribute("aria-controls",`${this.uid}-list`),this.searchInput.hidden=!this.shouldShowSearch(),this.dropdown.append(this.searchInput)),this.list=document.createElement("ul"),this.list.className="forge-select__list",this.list.id=`${this.uid}-list`,this.list.setAttribute("role","listbox"),this.opts.multiple&&this.list.setAttribute("aria-multiselectable","true"),this.dropdown.append(this.list),this.liveRegion=document.createElement("div"),this.liveRegion.className="forge-select__sr-only",this.liveRegion.setAttribute("role","status"),this.liveRegion.setAttribute("aria-live","polite"),this.root.append(this.control,this.liveRegion),e||this.root.append(this.dropdown),this.el.style.display="none",this.el.insertAdjacentElement("afterend",this.root),e&&(this.portalHost=document.createElement("div"),this.portalHost.className="forge-select forge-select--portal-host",this.portalHost.dataset.theme=this.opts.theme,this.portalHost.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.portalHost.append(this.dropdown),e.append(this.portalHost)),this.bindEvents()}bindEvents(){this.control.addEventListener("click",e=>{if(e.target!==this.clearBtn){if(this.suppressNextTagClick){this.suppressNextTagClick=!1;return}this.isDisabled||(this.isOpen?this.close():this.open())}}),this.control.addEventListener("keydown",e=>this.handleKeydown(e)),this.control.addEventListener("mousedown",()=>{this.pointerDownOnControl=!0}),this.control.addEventListener("focus",()=>{this.opts.openOnFocus&&!this.pointerDownOnControl&&!this.isOpen&&!this.isDisabled&&this.open(),this.pointerDownOnControl=!1}),this.clearBtn.addEventListener("click",e=>{e.stopPropagation(),this.clearSelection()}),this.searchInput&&(this.searchInput.addEventListener("input",()=>{this.applySearchQuery(this.searchInput.value,!0)}),this.searchInput.addEventListener("keydown",e=>this.handleKeydown(e)),this.searchInput.addEventListener("paste",e=>{if(!this.opts.multiple||!this.opts.allowCreate)return;let i=(e.clipboardData?.getData("text")??"").split(/[,\n]+/).map(n=>n.trim()).filter(Boolean);if(i.length<2)return;e.preventDefault();let s=[];for(let n of i){let r=this.createTag(n);r&&s.push(r)}if(s.length!==0){this.searchInput.value="",this.query="",this.afterSelectionChange();for(let n of s)n.created&&this.emitter.emit("create",n.option),this.emitter.emit("select",n.option);this.opts.closeOnSelect?this.close():this.renderList()}})),this.list.addEventListener("click",e=>{let t=e.target,i=t.closest("[data-twisty]");if(i){let r=i.dataset.twisty;this.expandedValues.has(r)?this.expandedValues.delete(r):this.expandedValues.add(r),this.renderList();return}let s=t.closest("li[data-nav-index]");if(!s){let r=t.closest("li[data-option-value]"),o=r?this.findOption(r.dataset.optionValue):void 0;o&&this.hasReachedMaximum()&&!this.selected.includes(o.value)&&this.announceMaximum(o);return}let n=Number(s.dataset.navIndex);this.activateNavItem(n)}),this.list.addEventListener("scroll",()=>{this.scrollRafId==null&&(this.scrollRafId=requestAnimationFrame(()=>{this.scrollRafId=null,this.usesVirtualScroll()&&this.renderRows(),this.maybeLoadNextPage()}))})}applySearchQuery(e,t){this.query=e,this.searchInput&&this.searchInput.value!==e&&(this.searchInput.value=e),this.highlightedIndex=-1,this.list.scrollTop=0,t&&this.emitter.emit("search",e);let i=e.trim(),s=i!==""&&i.length<this.opts.minSearchLength;if(this.opts.ajax&&!s){this.scheduleRemoteLoad(e,this.opts.ajax.debounce??250);return}s&&(this.ajaxTimer&&(clearTimeout(this.ajaxTimer),this.ajaxTimer=null),this.ajaxController?.abort(),this.setLoading(!1)),this.renderList()}handleKeydown(e){if(!this.isDisabled)switch(e.key){case"Enter":e.preventDefault(),this.isOpen?this.highlightedIndex>=0&&this.activateNavItem(this.highlightedIndex):this.open();break;case" ":e.target===this.control&&(e.preventDefault(),this.isOpen||this.open());break;case"ArrowDown":e.preventDefault(),this.isOpen?this.moveHighlight(1):this.open();break;case"ArrowUp":e.preventDefault(),this.isOpen&&this.moveHighlight(-1);break;case"Escape":this.isOpen&&(e.preventDefault(),this.close(),this.control.focus());break;case"ArrowRight":this.isOpen&&this.navigateTree("right")&&e.preventDefault();break;case"ArrowLeft":this.isOpen&&this.navigateTree("left")&&e.preventDefault();break;case"Home":this.isOpen&&(e.preventDefault(),this.focusNavIndex(0));break;case"End":this.isOpen&&(e.preventDefault(),this.focusNavIndex(this.navItems.length-1));break;case"PageDown":this.isOpen&&(e.preventDefault(),this.focusNavIndex(Math.min(this.navItems.length-1,(this.highlightedIndex===-1?0:this.highlightedIndex)+$)));break;case"PageUp":this.isOpen&&(e.preventDefault(),this.focusNavIndex(Math.max(0,(this.highlightedIndex===-1?0:this.highlightedIndex)-$)));break;case"Tab":this.close();break;default:this.isOpen&&e.target===this.control&&e.key.length===1&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&this.handleTypeahead(e.key);break}}handleTypeahead(e){this.typeaheadTimer&&clearTimeout(this.typeaheadTimer),this.typeaheadBuffer+=f(e,this.opts.accentInsensitive),this.typeaheadTimer=setTimeout(()=>{this.typeaheadBuffer="",this.typeaheadTimer=null},ee);let t=[...this.typeaheadBuffer].every(s=>s===this.typeaheadBuffer[0])?this.typeaheadBuffer[0]:this.typeaheadBuffer,i=this.navItems.length;for(let s=1;s<=i;s+=1){let n=(this.highlightedIndex+s+i)%i,r=this.navItems[n];if(r.kind==="option"&&f(r.option.label,this.opts.accentInsensitive).startsWith(t)){this.focusNavIndex(n);return}}}canSelectOption(e){if(this.opts.maxSelections==null)return!0;let t=[...this.selected];t.includes(e.value)||t.push(e.value);for(let i of x(e,this.isOptionDisabled))t.includes(i)||t.push(i);return H(this.data,t,this.isOptionDisabled),t.length<=this.opts.maxSelections}hasReachedMaximum(){return this.opts.maxSelections!=null&&this.selected.length>=this.opts.maxSelections}announceMaximum(e){let t=this.opts.maxSelections;t!=null&&(this.liveRegion.textContent=p(this.strings.maximumSelected,{count:String(t)}),this.emitter.emit("maximum",{limit:t,option:e}))}selectValue(e,t){if(this.selected.includes(e))return;let i=this.findOption(e)??this.selectedOptions.get(e)??{value:e,label:e};if(this.selectedOptions.set(e,i),this.opts.multiple){this.selected.push(e);for(let s of x(i,this.isOptionDisabled))this.selected.includes(s)||this.selected.push(s);this.syncTreeAncestors()}else this.selected=[e];t&&(this.afterSelectionChange(),this.emitter.emit("select",i))}deselectValue(e,t){let i=this.selected.indexOf(e);if(i===-1)return;let s=this.findOption(e)??this.selectedOptions.get(e);if(this.selected.splice(i,1),this.opts.multiple){if(s)for(let n of x(s,this.isOptionDisabled)){let r=this.selected.indexOf(n);r!==-1&&this.selected.splice(r,1)}this.syncTreeAncestors()}t&&(this.afterSelectionChange(),this.emitter.emit("unselect",s??{value:e,label:e}))}syncTreeAncestors(){H(this.data,this.selected,this.isOptionDisabled)}clearSelection(){this.selected.length!==0&&(this.selected=[],this.emitter.emit("clear"),this.afterSelectionChange())}allSelectableValues(){let e=[],t=i=>{this.isOptionDisabled(i)||e.push(i.value),i.children?.forEach(t)};for(let i of this.data)(g(i)?i.options:[i]).forEach(t);return e}afterSelectionChange(e=!0){this.renderValue(),this.syncNativeSelect(e),(!this.opts.required||this.selected.length>0)&&(this.control.classList.remove("forge-select__control--invalid"),this.control.removeAttribute("aria-invalid")),this.isOpen&&(this.opts.maxSelections!=null?this.renderList():this.renderRows()),e&&this.emitter.emit("change",this.getValue())}syncNativeSelect(e=!0){if(!(this.el instanceof HTMLSelectElement))return;let t=new Set;for(let i of Array.from(this.el.options))t.add(i.value),i.selected=this.selected.includes(i.value);for(let i of this.selected){if(t.has(i))continue;let s=document.createElement("option");s.value=i,s.textContent=this.selectedOptions.get(i)?.label??i,s.selected=!0,this.el.append(s)}if(this.opts.sortable&&this.opts.multiple)for(let i of this.selected){let s=Array.from(this.el.options).find(n=>n.value===i);s&&this.el.append(s)}if(e){this.syncingNative=!0;try{this.el.dispatchEvent(new Event("change",{bubbles:!0}))}finally{this.syncingNative=!1}}}findOption(e){return P(this.data,e)}findOptionByLabel(e){let t=e.toLowerCase(),i=s=>{for(let n of s){if(n.label.toLowerCase()===t)return n;let r=n.children?i(n.children):void 0;if(r)return r}};for(let s of this.data){let n=i(g(s)?s.options:[s]);if(n)return n}}createTag(e){let t=e.trim();if(!t)return;let i=this.findOptionByLabel(t);if(i){if(this.selected.includes(i.value))return;if(this.opts.multiple&&!this.canSelectOption(i)){this.announceMaximum(i);return}return this.selectValue(i.value,!1),{option:i,created:!1}}let s={value:t,label:t};if(this.opts.multiple&&!this.canSelectOption(s)){this.announceMaximum(s);return}return this.data.push(s),this.selectValue(s.value,!1),{option:s,created:!0}}createFromQuery(){let e=this.query.trim();if(!e)return;let t=this.createTag(e);t&&(this.searchInput&&(this.searchInput.value="",this.query=""),this.afterSelectionChange(),t.created&&this.emitter.emit("create",t.option),this.emitter.emit("select",t.option),!this.opts.multiple||this.opts.closeOnSelect?this.close():this.isOpen&&this.renderList())}activateNavItem(e){let t=this.navItems[e];if(!t)return;if(t.kind==="create"){this.createFromQuery();return}let{value:i}=t.option;if(this.opts.multiple){let s=!1;this.selected.includes(i)?(this.deselectValue(i,!0),s=!0):this.canSelectOption(t.option)?(this.selectValue(i,!0),s=!0):this.announceMaximum(t.option),s&&this.opts.closeOnSelect&&this.close()}else this.selectValue(i,!0),this.close(),this.control.focus()}renderValue(){this.valueEl.textContent="";let e=this.selected.length>0;if(this.clearBtn.hidden=!(this.opts.clearable&&e),!e){let t=document.createElement("span");t.className="forge-select__placeholder",t.textContent=this.opts.placeholder,this.valueEl.append(t);return}if(this.opts.multiple)for(let t of this.selected){let i=this.selectedOptions.get(t)??{value:t,label:t},s=document.createElement("span");s.className="forge-select__tag";let n=document.createElement("span");n.className="forge-select__tag-label",b(n,i,this.opts.templateSelection,"inline");let r=document.createElement("button");r.type="button",r.className="forge-select__tag-remove",r.setAttribute("aria-label",p(this.strings.removeItem,{label:i.label})),r.textContent="\xD7",r.addEventListener("click",o=>{o.stopPropagation(),this.isDisabled||this.deselectValue(t,!0)}),s.append(n,r),this.opts.sortable&&(s.dataset.value=t,s.tabIndex=0,s.setAttribute("aria-roledescription","draggable item"),s.setAttribute("aria-label",p(this.strings.reorderHint,{label:i.label})),s.addEventListener("keydown",o=>this.handleTagKeydown(o,t)),this.bindTagDrag(s,t)),this.valueEl.append(s)}else{let t=this.selectedOptions.get(this.selected[0])??{value:this.selected[0],label:this.selected[0]},i=document.createElement("span");i.className="forge-select__single-value",b(i,t,this.opts.templateSelection,"inline"),this.valueEl.append(i)}}bindTagDrag(e,t){let s=0,n=!1,r=[],o=l=>{if(!n){if(Math.abs(l.clientX-s)<4)return;n=!0,r=[...this.selected],typeof this.valueEl.setPointerCapture=="function"&&this.valueEl.setPointerCapture(l.pointerId),e.classList.add("forge-select__tag--dragging")}l.preventDefault();let c=r.indexOf(t),d=Array.from(this.valueEl.querySelectorAll(".forge-select__tag"));for(let u of d){if(u===e)continue;let m=u.dataset.value;if(!m)continue;let E=r.indexOf(m);if(E===-1)continue;let D=u.getBoundingClientRect(),k=D.left+D.width/2,_=c<E;if(_?l.clientX>k:l.clientX<k){r.splice(c,1),r.splice(E,0,t),_?this.valueEl.insertBefore(e,u.nextSibling):this.valueEl.insertBefore(e,u);break}}},h=l=>{this.valueEl.removeEventListener("pointermove",o),this.valueEl.removeEventListener("pointerup",h),this.valueEl.removeEventListener("pointercancel",h),n&&(typeof this.valueEl.releasePointerCapture=="function"&&this.valueEl.releasePointerCapture(l.pointerId),e.classList.remove("forge-select__tag--dragging"),this.selected=r,this.suppressNextTagClick=!0,this.afterSelectionChange(),this.emitter.emit("reorder",[...this.selected]))};e.addEventListener("pointerdown",l=>{this.isDisabled||l.button!==0||l.target.closest(".forge-select__tag-remove")||(s=l.clientX,n=!1,this.valueEl.addEventListener("pointermove",o),this.valueEl.addEventListener("pointerup",h),this.valueEl.addEventListener("pointercancel",h))})}handleTagKeydown(e,t){if(!e.altKey||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;let i=this.selected.indexOf(t),s=e.key==="ArrowLeft"?i-1:i+1;if(i===-1||s<0||s>=this.selected.length)return;e.preventDefault(),e.stopPropagation();let n=[...this.selected];[n[i],n[s]]=[n[s],n[i]],this.selected=n,this.afterSelectionChange(),this.emitter.emit("reorder",[...this.selected]),this.focusTagByValue(t)}focusTagByValue(e){for(let t of Array.from(this.valueEl.querySelectorAll(".forge-select__tag")))if(t.dataset.value===e){t.focus();return}}buildRows(){this.rows=[],this.navItems=[],this.rowOffsetsCache=null;let e=this.query.trim(),t=f(e,this.opts.accentInsensitive),i=r=>t===""||(this.opts.filterOption?this.opts.filterOption(r,e):this.searchIndex.score(r,e,{fields:this.opts.searchFields,tokenSearch:this.opts.tokenSearch,accentInsensitive:this.opts.accentInsensitive,scorer:this.opts.searchScorer})>0),s=r=>t===""||i(r)||(r.children??[]).some(s),n=(r,o,h)=>{let l=-1;this.isOptionDisabled(r)||this.hasReachedMaximum()&&!this.selected.includes(r.value)||(l=this.navItems.length,this.navItems.push({kind:"option",option:r,parentValue:h}));let d=!!r.children&&r.children.length>0;if(this.rows.push({kind:"option",option:r,navIndex:l,depth:o,hasChildren:d}),d&&(t!==""||this.expandedValues.has(r.value)))for(let m of r.children)s(m)&&n(m,o+1,r.value)};if(e!==""&&e.length<this.opts.minSearchLength){this.rows.push({kind:"min-length"});return}if(this.loading){this.rows.push({kind:"loading"});return}if(this.loadError){this.rows.push({kind:"error"});return}for(let r of this.data)if(g(r)){let o=r.options.filter(s);if(o.length===0)continue;this.rows.push({kind:"group",label:r.label}),o.forEach(h=>n(h,0))}else s(r)&&n(r,0);if(this.opts.allowCreate&&t!==""&&!this.hasExactMatch(t)){let r=this.navItems.length;this.navItems.push({kind:"create"}),this.rows.push({kind:"create",navIndex:r})}this.rows.length===0?this.rows.push({kind:"empty"}):this.loadingMore&&this.rows.push({kind:"loading-more"})}hasExactMatch(e){return!!this.findOptionByLabel(e)}usesVirtualScroll(){return this.opts.virtualScroll!==!1&&this.rows.length>Z}rowKey(e,t){return e.kind==="option"?`option:${e.option.value}`:e.kind==="group"?`group:${e.label}:${t}`:`${e.kind}:${t}`}measuredRowHeight(e){return this.opts.variableItemHeight?this.rowHeightCache.get(this.rowKey(this.rows[e],e))??this.opts.itemHeight:this.opts.itemHeight}rowOffset(e){if(!this.opts.variableItemHeight)return e*this.opts.itemHeight;let t=0;for(let i=0;i<e;i+=1)t+=this.measuredRowHeight(i);return t}rowOffsets(){if(this.rowOffsetsCache)return this.rowOffsetsCache;let e=[0];for(let t=0;t<this.rows.length;t+=1)e.push(e[t]+this.measuredRowHeight(t));return this.rowOffsetsCache=e,e}renderList(){this.buildRows(),this.renderRows(),this.announceStatus()}announceStatus(){let e=this.rows[0],t=this.hasReachedMaximum()?p(this.strings.maximumSelected,{count:String(this.opts.maxSelections)}):e?.kind==="loading"?this.strings.loading:e?.kind==="error"?this.strings.errorLoading:e?.kind==="empty"?this.strings.noResults:e?.kind==="min-length"?p(this.strings.minSearchLength,{count:String(this.opts.minSearchLength)}):"";this.liveRegion.textContent!==t&&(this.liveRegion.textContent=t)}renderRows(){let e=this.list.scrollTop,t=this.list.clientHeight,i=this.usesVirtualScroll();this.list.textContent="";let s=this.opts.itemHeight,n=this.opts.variableItemHeight?this.rowOffsets():null,r=0,o=this.rows.length;if(i){let l=t||s*8;if(this.opts.variableItemHeight){for(;r<this.rows.length&&n[r+1]<e;)r+=1;r=Math.max(0,r-O),o=r;let d=e+l+O*s;for(;o<this.rows.length&&n[o]<d;)o+=1}else r=Math.max(0,Math.floor(e/s)-O),o=Math.min(this.rows.length,r+Math.ceil(l/s)+O*2);let c=document.createElement("li");c.className="forge-select__spacer",c.setAttribute("aria-hidden","true"),c.style.height=`${n?.[r]??this.rowOffset(r)}px`,this.list.append(c)}let h=[];for(let l=r;l<o;l++){let c=this.renderRow(this.rows[l]);this.list.append(c),h.push(c)}if(this.opts.variableItemHeight)for(let l=r;l<o;l++){let c=h[l-r],d=c.getBoundingClientRect().height||c.offsetHeight;if(d>0){let u=this.rowKey(this.rows[l],l);this.rowHeightCache.get(u)!==d&&(this.rowOffsetsCache=null),this.rowHeightCache.set(u,d)}}if(i){let l=document.createElement("li");l.className="forge-select__spacer",l.setAttribute("aria-hidden","true"),l.style.height=`${n?n[this.rows.length]-n[o]:this.rowOffset(this.rows.length)-this.rowOffset(o)}px`,this.list.append(l),this.list.scrollTop!==e&&(this.list.scrollTop=e)}this.updateActiveDescendant()}renderRow(e){let t=document.createElement("li");switch(e.kind){case"group":t.className="forge-select__group-label",t.setAttribute("role","presentation"),t.textContent=e.label;break;case"empty":t.className="forge-select__empty",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.noResults;break;case"min-length":t.className="forge-select__min-length",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=p(this.strings.minSearchLength,{count:String(this.opts.minSearchLength)});break;case"error":t.className="forge-select__error",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.errorLoading;break;case"loading":t.className="forge-select__loading",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.loading;break;case"loading-more":t.className="forge-select__loading-more",t.setAttribute("aria-hidden","true"),t.textContent=this.strings.loadingMore;break;case"create":t.className="forge-select__option forge-select__option--create",t.setAttribute("role","option"),t.id=`${this.uid}-nav-${e.navIndex}`,t.dataset.navIndex=String(e.navIndex),t.textContent=p(this.strings.createOption,{query:this.query.trim()}),e.navIndex===this.highlightedIndex&&t.classList.add("forge-select__option--highlighted");break;case"option":{t.className="forge-select__option",t.dataset.optionValue=e.option.value,e.option.className&&t.classList.add(...e.option.className.trim().split(/\s+/).filter(Boolean)),t.setAttribute("role","option");let i=this.selected.includes(e.option.value);if(t.setAttribute("aria-selected",String(i)),i&&t.classList.add("forge-select__option--selected"),this.opts.multiple&&e.hasChildren&&w(e.option,this.selected,this.isOptionDisabled)==="some"&&(t.classList.add("forge-select__option--indeterminate"),t.dataset.selectionState="mixed"),e.depth>0&&(t.style.paddingLeft=`calc(12px + ${e.depth} * var(--fs-tree-indent, 18px))`),this.isOptionDisabled(e.option)||this.hasReachedMaximum()&&!this.selected.includes(e.option.value)?(t.classList.add("forge-select__option--disabled"),t.setAttribute("aria-disabled","true")):(t.id=`${this.uid}-nav-${e.navIndex}`,t.dataset.navIndex=String(e.navIndex),e.navIndex===this.highlightedIndex&&t.classList.add("forge-select__option--highlighted")),e.hasChildren){let s=this.query!==""||this.expandedValues.has(e.option.value);t.setAttribute("aria-expanded",String(s));let n=document.createElement("span");n.className="forge-select__twisty",n.dataset.twisty=e.option.value,n.setAttribute("aria-hidden","true"),n.textContent=s?"\u25BC":"\u25B6",t.append(n)}t.append(this.optionContent(e.option));break}}return t}optionContent(e){if(this.opts.highlightSearch&&this.query.trim()&&!this.opts.templateResult){let i=document.createElement("span");i.className="forge-select__option-content",b(i,e,void 0);let s=i.querySelector(".forge-select__option-label")??i,n=q(e.label,this.query,this.opts.accentInsensitive);if(n.length){s.textContent="";let r=0;for(let[o,h]of n){if(o<r)continue;s.append(document.createTextNode(e.label.slice(r,o)));let l=document.createElement("mark");l.className="forge-select__match",l.textContent=e.label.slice(o,h),s.append(l),r=h}s.append(document.createTextNode(e.label.slice(r)))}return i}let t=this.rowContentCache.get(e.value);if(!t){let i=document.createElement("span");if(i.className="forge-select__option-content",b(i,e,this.opts.templateResult),this.rowContentCache.size>=J){let s=this.rowContentCache.keys().next().value;this.rowContentCache.delete(s)}this.rowContentCache.set(e.value,i),t=i}return t.cloneNode(!0)}moveHighlight(e){if(this.navItems.length===0)return;let t=this.highlightedIndex===-1?e>0?0:this.navItems.length-1:(this.highlightedIndex+e+this.navItems.length)%this.navItems.length;this.focusNavIndex(t)}focusNavIndex(e){if(this.navItems.length!==0)if(this.highlightedIndex=e,this.usesVirtualScroll()){let t=this.rows.findIndex(i=>(i.kind==="option"||i.kind==="create")&&i.navIndex===e);if(t>=0){let i=this.measuredRowHeight(t),s=this.rowOffset(t),n=this.list.clientHeight||i*8,r=this.list.scrollTop;s<r?r=s:s+i>r+n&&(r=s+i-n),r!==this.list.scrollTop&&(this.list.scrollTop=r)}this.renderRows()}else this.renderRows(),this.list.querySelector(".forge-select__option--highlighted")?.scrollIntoView?.({block:"nearest"})}navigateTree(e){let t=this.navItems[this.highlightedIndex];if(!t||t.kind!=="option")return!1;let{option:i,parentValue:s}=t,n=!!i.children?.length,r=this.query!==""||this.expandedValues.has(i.value);if(e==="right"){if(n&&!r)return this.expandedValues.add(i.value),this.renderList(),!0;if(n){let o=this.navItems.findIndex(h=>h.kind==="option"&&h.parentValue===i.value);if(o>=0)return this.focusNavIndex(o),!0}return!1}if(n&&r&&this.query==="")return this.expandedValues.delete(i.value),this.renderList(),!0;if(s){let o=this.navItems.findIndex(h=>h.kind==="option"&&h.option.value===s);if(o>=0)return this.focusNavIndex(o),!0}return!1}updateActiveDescendant(){let e=this.searchInput??this.control;this.highlightedIndex>=0?e.setAttribute("aria-activedescendant",`${this.uid}-nav-${this.highlightedIndex}`):e.removeAttribute("aria-activedescendant")}scheduleRemoteLoad(e,t){this.ajaxTimer&&clearTimeout(this.ajaxTimer);let i=++this.ajaxRequestId;this.ajaxController?.abort(),this.ajaxController=null,this.page=0,this.hasMore=!0,this.setLoading(!0),this.loadingMore=!1,this.loadError=null,this.renderList(),this.ajaxTimer=setTimeout(()=>{this.ajaxTimer=null,this.loadRemote(e,{requestId:i})},t)}setLoading(e){this.loading!==e&&(this.loading=e,this.emitter.emit("loading",e))}remoteCacheKey(e,t){return`${e}\0${t}`}async requestRemote(e,t,i){let s=this.opts.ajax,n=Math.max(0,Math.floor(s.retry??0))+1,r;for(let o=0;o<n;o+=1)try{if(s.request)return await s.request(e,t,i);let h=await fetch(j(s,e,t),{signal:i});if(h.ok===!1)throw new Error(`ForgeSelect: remote request failed with HTTP ${h.status}`);return await h.json()}catch(h){if(r=h,i.aborted||o===n-1)throw h;let l=Math.max(0,s.retryDelay??250)*2**o;await new Promise((c,d)=>{let u=setTimeout(c,l);i.addEventListener("abort",()=>{clearTimeout(u),d(new DOMException("Aborted","AbortError"))},{once:!0})})}throw r}async prefetchRemote(e){let t=this.opts.ajax;if(!t||(t.cacheTtl??3e4)<=0)return;let i=this.remoteCacheKey(e,0);if(this.remoteCache.get(i))return;let s=new AbortController;try{let n=await this.requestRemote(e,0,s.signal);this.remoteCache.set(i,A(t,n),t.cacheTtl??3e4)}catch{}}maybeLoadNextPage(){if(!this.opts.ajax?.pagination||!this.hasMore||this.loading||this.loadingMore)return;let{scrollHeight:t,scrollTop:i,clientHeight:s}=this.list,n=this.opts.itemHeight*2;t-i-s>=n||(this.loadingMore=!0,this.renderList(),this.loadRemote(this.query,{append:!0}))}async loadRemote(e,{append:t=!1,requestId:i}={}){let s=this.opts.ajax,n=i??++this.ajaxRequestId;if(n!==this.ajaxRequestId)return;this.ajaxController?.abort();let r=new AbortController;this.ajaxController=r;let o=t?this.page+1:0;try{let h=this.remoteCacheKey(e,o),l=this.remoteCache.get(h);if(!l){let u=await this.requestRemote(e,o,r.signal);l=A(s,u),this.remoteCache.set(h,l,s.cacheTtl??3e4)}if(n!==this.ajaxRequestId||this.destroyed)return;let{options:c,hasMore:d}=l;if(t){let u=M(this.data);this.data=[...this.data,...c.filter(m=>!u.has(m.value))]}else this.data=c,this.rowContentCache.clear(),this.rowHeightCache.clear();this.page=o,this.hasMore=d,this.remoteLoaded=!0,this.loadError=null}catch(h){if(n!==this.ajaxRequestId||this.destroyed||r.signal.aborted)return;let l=h instanceof Error?h:new Error(String(h));t||(this.data=[],this.rowContentCache.clear(),this.rowHeightCache.clear()),this.hasMore=!1,this.loadError=l,this.emitter.emit("error",l)}finally{n===this.ajaxRequestId&&!this.destroyed&&(this.ajaxController=null,this.setLoading(!1),this.loadingMore=!1,this.isOpen&&this.renderList())}}};return W(ie);})();
1
+ "use strict";var ForgeSelectBundle=(()=>{var C=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var Q=(o,e)=>{for(var t in e)C(o,t,{get:e[t],enumerable:!0})},G=(o,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of U(e))!K.call(o,s)&&s!==t&&C(o,s,{get:()=>e[s],enumerable:!(i=$(e,s))||i.enumerable});return o};var W=o=>G(C({},"__esModule",{value:!0}),o);var te={};Q(te,{ForgeSelect:()=>b,default:()=>b});var y=class{constructor(){this.handlers=new Map}on(e,t){let i=this.handlers.get(e);i||(i=new Set,this.handlers.set(e,i)),i.add(t)}off(e,t){this.handlers.get(e)?.delete(t)}emit(e,...t){let i=this.handlers.get(e);if(i)for(let s of[...i])s(...t)}clear(){this.handlers.clear()}};function _(o,e,t,i=4){let s=t-o.bottom,r=o.top,n=e>s&&r>s;return{dropUp:n,top:n?o.top-e-i:o.bottom+i}}var L={en:{noResults:"No results found",loading:"Loading\u2026",loadingMore:"Loading more\u2026",errorLoading:"Could not load options",createOption:'Create "{query}"',clearSelection:"Clear selection",removeItem:"Remove {label}",search:"Search",reorderHint:"{label}. Press Alt+Left or Alt+Right to reorder.",minSearchLength:"Type {count} or more characters to search",maximumSelected:"Maximum of {count} selections reached"},vi:{noResults:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3",loading:"\u0110ang t\u1EA3i\u2026",loadingMore:"\u0110ang t\u1EA3i th\xEAm\u2026",errorLoading:"Kh\xF4ng th\u1EC3 t\u1EA3i t\xF9y ch\u1ECDn",createOption:'T\u1EA1o "{query}"',clearSelection:"X\xF3a l\u1EF1a ch\u1ECDn",removeItem:"X\xF3a {label}",search:"T\xECm ki\u1EBFm",reorderHint:"{label}. Nh\u1EA5n Alt+Tr\xE1i ho\u1EB7c Alt+Ph\u1EA3i \u0111\u1EC3 s\u1EAFp x\u1EBFp l\u1EA1i.",minSearchLength:"Nh\u1EADp th\xEAm {count} k\xFD t\u1EF1 \u0111\u1EC3 t\xECm ki\u1EBFm",maximumSelected:"\u0110\xE3 \u0111\u1EA1t t\u1ED1i \u0111a {count} l\u1EF1a ch\u1ECDn"}};function T(o){return typeof o=="string"?L[o]??L.en:{...L.en,...o}}function g(o,e){return o.replace(/\{(\w+)\}/g,(t,i)=>e[i]??t)}function V(o){let e=[];for(let t of Array.from(o.children))t instanceof HTMLOptGroupElement?e.push({label:t.label,options:Array.from(t.querySelectorAll("option")).map(F)}):t instanceof HTMLOptionElement&&e.push(F(t));return e}function F(o){let e=o.parentElement instanceof HTMLOptGroupElement&&o.parentElement.disabled;return{value:o.value,label:o.textContent?.trim()??o.value,disabled:o.disabled||e||void 0}}function S(o,e,t,i="row",s){if(t){let r=t(e);typeof r=="string"?o.innerHTML=s?s(r,e):r:o.append(r);return}if(!e.avatar&&!e.description){o.textContent=e.label;return}if(e.avatar){let r=document.createElement("img");r.className=i==="row"?"forge-select__option-avatar":"forge-select__inline-avatar",r.src=e.avatar,r.alt="",r.setAttribute("loading","lazy"),r.setAttribute("decoding","async"),o.append(r)}if(i==="row"&&e.description){let r=document.createElement("span");r.className="forge-select__option-body";let n=document.createElement("span");n.className="forge-select__option-label",n.textContent=e.label;let a=document.createElement("span");a.className="forge-select__option-desc",a.textContent=e.description,r.append(n,a),o.append(r)}else{let r=document.createElement("span");r.className="forge-select__option-label",r.textContent=e.label,o.append(r)}}function N(o,e,t,i){if(!o.url)throw new Error("ForgeSelect: ajax requires either url or request.");if(typeof o.url=="function")return o.url(e,t,i);if(!o.params)return o.url;let s=new URLSearchParams;for(let[n,a]of Object.entries(o.params(e,t,i)))s.set(n,String(a));let r=o.url.includes("?")?"&":"?";return`${o.url}${r}${s.toString()}`}function P(o,e){let t=o.transform?o.transform(e):e;if(Array.isArray(t))return{options:t,hasMore:!1};if(!t||!Array.isArray(t.options))throw new Error("ForgeSelect: ajax.transform must return an array of options, or an object shaped like { options: Option[], hasMore?: boolean }.");let i=t.nextCursor==null?void 0:String(t.nextCursor);return{options:t.options,hasMore:o.pagination?t.hasMore??i!==void 0:!1,nextCursor:i}}var w=class{constructor(){this.entries=new Map}get(e,t=Date.now()){let i=this.entries.get(e);if(i){if(i.expiresAt<=t){this.entries.delete(e);return}return i.value}}set(e,t,i,s=Date.now()){if(!(i<=0)){if(this.entries.size>=50&&!this.entries.has(e)){let r=this.entries.keys().next().value;this.entries.delete(r)}this.entries.set(e,{value:t,expiresAt:s+i})}}clear(){this.entries.clear()}};function f(o,e=!0){let t=o.toLocaleLowerCase();return e?t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/đ/g,"d"):t}function X(o,e){if(e==="label")return o.label;if(e==="description")return o.description??"";let t=e.slice(5).split("."),i=o.meta;for(let s of t){if(!i||typeof i!="object")return"";i=i[s]}return i==null?"":String(i)}var O=class{constructor(){this.cache=new WeakMap}clear(){this.cache=new WeakMap}score(e,t,i){let s=f(t.trim(),i.accentInsensitive);if(!s)return 1;if(i.scorer)return i.scorer(e,t.trim(),s);let r=`${i.accentInsensitive?"1":"0"}:${i.fields.join("\0")}`,n=this.cache.get(e);n||(n=new Map,this.cache.set(e,n));let a=n.get(r);if(a||(a=i.fields.map(c=>f(X(e,c),i.accentInsensitive)),n.set(r,a)),!(i.tokenSearch?s.split(/\s+/).filter(Boolean):[s]).every(c=>a.some(d=>d.includes(c))))return 0;let l=a[i.fields.indexOf("label")];return l===s?4:l?.startsWith(s)?3:l?.includes(s)?2:1}};function j(o,e,t=!0){let i=f(e.trim(),t).split(/\s+/).filter(Boolean);if(!i.length)return[];let s=f(o,t),r=[];for(let n of i){let a=s.indexOf(n);a>=0&&r.push([a,a+n.length])}return r.sort((n,a)=>n[0]-a[0])}function v(o){return o.options!==void 0}var R=o=>!!o.disabled;function x(o,e=R){if(!o.children)return[];let t=[];for(let i of o.children)e(i)||t.push(i.value),t.push(...x(i,e));return t}function I(o,e,t=R){if(!o.children?.length)return e.includes(o.value)?"all":"none";let i=o.children.filter(s=>!t(s)).map(s=>I(s,e,t));return i.length===0?"none":i.every(s=>s==="all")?"all":i.every(s=>s==="none")?"none":"some"}function M(o,e,t=R){let i=s=>{if(!s.children?.length)return;for(let a of s.children)i(a);let r=I(s,e,t),n=e.indexOf(s.value);r==="all"&&n===-1?e.push(s.value):r!=="all"&&n!==-1&&e.splice(n,1)};for(let s of o)(v(s)?s.options:[s]).forEach(i)}function A(o){let e=new Set,t=i=>{e.add(i.value),i.children?.forEach(t)};for(let i of o)(v(i)?i.options:[i]).forEach(t);return e}function q(o,e){return o.length===e.length&&o.every((t,i)=>t===e[i])}var Y=36,E=5,Z=100,B=2e3,z=10,J=500,ee=0,b=class{constructor(e,t={}){this.optionByValue=new Map;this.optionByLabel=new Map;this.selected=[];this.selectedOptions=new Map;this.suppressNextTagClick=!1;this.emitter=new y;this.uid=`forge-select-${++ee}`;this.searchInput=null;this.portalHost=null;this.isOpen=!1;this.isDisabled=!1;this.destroyed=!1;this.query="";this.rows=[];this.navItems=[];this.highlightedIndex=-1;this.typeaheadBuffer="";this.typeaheadTimer=null;this.rowContentCache=new Map;this.rowElementCache=new Map;this.rowHeightCache=new Map;this.rowOffsetsCache=null;this.scrollRafId=null;this.ancestorScrollRafId=null;this.searchIndex=new O;this.expandedValues=new Set;this.loading=!1;this.loadingMore=!1;this.page=0;this.hasMore=!0;this.ajaxTimer=null;this.ajaxRequestId=0;this.ajaxController=null;this.remoteLoaded=!1;this.remoteCache=new w;this.remoteInFlight=new Map;this.prefetchControllers=new Set;this.loadError=null;this.originalDisplay="";this.originalDisabled=!1;this.nativeSelect=null;this.nativeForm=null;this.syncingNative=!1;this.isOptionDisabled=e=>e.disabled===!0||(this.opts.isOptionDisabled?.(e)??!1);this.pointerDownOnControl=!1;this.onDocumentMouseDown=e=>{let t=e.target;!this.root.contains(t)&&!this.portalHost?.contains(t)&&this.close()};this.onWindowResize=()=>{this.positionDropdown()};this.onAncestorScroll=()=>{this.portalHost&&this.ancestorScrollRafId==null&&(this.ancestorScrollRafId=requestAnimationFrame(()=>{this.ancestorScrollRafId=null,this.positionDropdown()}))};this.onNativeInvalid=e=>{e.preventDefault(),this.control.classList.add("forge-select__control--invalid"),this.control.setAttribute("aria-invalid","true"),this.isOpen||this.open(),this.control.focus(),this.emitter.emit("invalid",this.nativeSelect?.validationMessage??"")};this.onNativeChange=()=>{if(!this.nativeSelect||this.destroyed||this.syncingNative)return;let e=Array.from(this.nativeSelect.selectedOptions,t=>t.value);this.applyNativeValues(e)};this.onFormReset=()=>{if(!this.nativeSelect||this.destroyed)return;let e=Array.from(this.nativeSelect.options).filter(t=>t.defaultSelected).map(t=>t.value);this.applyNativeValues(e)};let i=typeof e=="string"?document.querySelector(e):e;if(!i)throw new Error(`ForgeSelect: target element not found: ${String(e)}`);this.el=i;let s=i instanceof HTMLSelectElement?i:null;if(this.nativeSelect=s,this.nativeForm=s?.form??null,this.originalDisplay=i.style.display,this.originalDisabled=s?.disabled??!1,this.opts={placeholder:t.placeholder??"",searchable:t.searchable??!0,multiple:t.multiple??s?.multiple??!1,clearable:t.clearable??!1,allowCreate:t.allowCreate??!1,sortable:t.sortable??!1,closeOnSelect:t.closeOnSelect??!1,maxSelections:t.maxSelections==null||!Number.isFinite(t.maxSelections)?void 0:Math.max(0,Math.floor(t.maxSelections)),theme:t.theme??"default",disabled:t.disabled??s?.disabled??!1,required:t.required??s?.required??!1,data:t.data,ajax:t.ajax,templateResult:t.templateResult,templateSelection:t.templateSelection,sanitizeTemplate:t.sanitizeTemplate,beforeSelect:t.beforeSelect,beforeUnselect:t.beforeUnselect,beforeCreate:t.beforeCreate,createOption:t.createOption,missingSelectionPolicy:t.missingSelectionPolicy??"preserve",duplicateValuePolicy:t.duplicateValuePolicy??"warn",filterOption:t.filterOption,searchFields:t.searchFields??["label","description"],tokenSearch:t.tokenSearch??!0,accentInsensitive:t.accentInsensitive??!0,searchScorer:t.searchScorer,highlightSearch:t.highlightSearch??!1,minSearchLength:Math.max(0,Math.floor(t.minSearchLength??0)),minResultsForSearch:Math.max(0,Math.floor(t.minResultsForSearch??0)),isOptionDisabled:t.isOptionDisabled,virtualScroll:t.virtualScroll,itemHeight:typeof t.itemHeight=="number"?Math.max(1,t.itemHeight):Y,variableItemHeight:t.itemHeight==="auto",language:t.language??"en",plugins:t.plugins??[],openOnFocus:t.openOnFocus??!1,dropdownParent:t.dropdownParent},this.strings=T(this.opts.language),this.plugins=this.opts.plugins,s&&(s.required=this.opts.required),this.data=this.opts.data??(s?V(s):[]),this.rebuildOptionIndexes(),s&&!this.opts.data){let r=Array.from(s.options),n=s.multiple||s.selectedIndex>0||r.some(a=>a.defaultSelected);for(let a of r)n&&a.selected&&this.selectValue(a.value,!1)}this.buildDom(),this.renderValue(),this.opts.disabled&&this.disable(),s?.addEventListener("change",this.onNativeChange),s?.addEventListener("invalid",this.onNativeInvalid),this.nativeForm?.addEventListener("reset",this.onFormReset);for(let r of this.plugins)r.onInit?.(this);for(let r of this.opts.ajax?.prefetch??[])this.prefetchRemote(r)}applyNativeValues(e){this.selected=[];for(let t of this.opts.multiple?e:e.slice(0,1))this.selectValue(t,!1);this.renderValue(),this.isOpen&&this.renderList(),this.emitter.emit("change",this.getValue())}open(){if(!(this.isOpen||this.isDisabled||this.destroyed)){this.isOpen=!0,this.dropdown.hidden=!1,this.root.classList.add("forge-select--open"),this.control.setAttribute("aria-expanded","true"),document.addEventListener("mousedown",this.onDocumentMouseDown),this.opts.ajax&&(this.opts.ajax.loadOnOpen??!0)&&!this.remoteLoaded&&this.scheduleRemoteLoad(this.query,0),this.renderList(),this.positionDropdown(),window.addEventListener("resize",this.onWindowResize),window.visualViewport?.addEventListener("resize",this.onWindowResize),window.visualViewport?.addEventListener("scroll",this.onWindowResize),document.addEventListener("scroll",this.onAncestorScroll,!0),this.searchInput&&!this.searchInput.hidden&&this.searchInput.focus(),this.emitter.emit("open");for(let e of this.plugins)e.onOpen?.(this)}}close(){if(this.isOpen){this.isOpen=!1,this.dropdown.hidden=!0,this.root.classList.remove("forge-select--open"),this.root.classList.remove("forge-select--drop-up"),this.control.setAttribute("aria-expanded","false"),document.removeEventListener("mousedown",this.onDocumentMouseDown),window.removeEventListener("resize",this.onWindowResize),window.visualViewport?.removeEventListener("resize",this.onWindowResize),window.visualViewport?.removeEventListener("scroll",this.onWindowResize),document.removeEventListener("scroll",this.onAncestorScroll,!0),this.ancestorScrollRafId!=null&&(cancelAnimationFrame(this.ancestorScrollRafId),this.ancestorScrollRafId=null),this.scrollRafId!=null&&(cancelAnimationFrame(this.scrollRafId),this.scrollRafId=null),this.typeaheadTimer&&(clearTimeout(this.typeaheadTimer),this.typeaheadTimer=null),this.typeaheadBuffer="",this.highlightedIndex=-1,this.searchInput&&(this.searchInput.value="",this.query=""),this.emitter.emit("close");for(let e of this.plugins)e.onClose?.(this)}}positionDropdown(){let e=this.control.getBoundingClientRect(),t=window.visualViewport,i=_(e,this.dropdown.offsetHeight,t?.height??window.innerHeight);this.root.classList.toggle("forge-select--drop-up",i.dropUp),this.portalHost&&(this.portalHost.style.top=`${i.top+(t?.offsetTop??0)}px`,this.portalHost.style.left=`${e.left+(t?.offsetLeft??0)}px`,this.portalHost.style.width=`${e.width}px`)}destroy(){if(!this.destroyed){this.close();for(let e of this.plugins)e.onDestroy?.(this);this.destroyed=!0,this.ajaxTimer&&clearTimeout(this.ajaxTimer),this.ajaxController?.abort();for(let e of this.prefetchControllers)e.abort();this.prefetchControllers.clear(),this.remoteInFlight.clear(),this.scrollRafId!=null&&cancelAnimationFrame(this.scrollRafId),this.typeaheadTimer&&clearTimeout(this.typeaheadTimer),this.nativeSelect?.removeEventListener("change",this.onNativeChange),this.nativeSelect?.removeEventListener("invalid",this.onNativeInvalid),this.nativeForm?.removeEventListener("reset",this.onFormReset),this.clearRowCaches(),this.searchIndex.clear(),this.portalHost?.remove(),this.root.remove(),this.el.style.display=this.originalDisplay,this.nativeSelect&&(this.nativeSelect.disabled=this.originalDisabled),this.emitter.clear()}}getValue(){return this.opts.multiple?[...this.selected]:this.selected[0]??null}getSearchQuery(){return this.query}setSearchQuery(e,t={}){this.applySearchQuery(e,t.emitSearch??!0)}isDropdownOpen(){return this.isOpen}updateOptions(e){e.data&&this.setData(e.data),"ajax"in e&&e.ajax!==this.opts.ajax&&(this.opts.ajax=e.ajax,this.remoteLoaded=!1,this.clearRemoteCache()),e.placeholder!==void 0&&(this.opts.placeholder=e.placeholder),e.clearable!==void 0&&(this.opts.clearable=e.clearable),e.allowCreate!==void 0&&(this.opts.allowCreate=e.allowCreate),e.sortable!==void 0&&(this.opts.sortable=e.sortable),e.closeOnSelect!==void 0&&(this.opts.closeOnSelect=e.closeOnSelect),"maxSelections"in e&&(this.opts.maxSelections=e.maxSelections==null||!Number.isFinite(e.maxSelections)?void 0:Math.max(0,Math.floor(e.maxSelections))),e.theme!==void 0&&(this.opts.theme=e.theme,this.root.dataset.theme=e.theme,this.portalHost&&(this.portalHost.dataset.theme=e.theme)),e.required!==void 0&&(this.opts.required=e.required,e.required?this.control.setAttribute("aria-required","true"):this.control.removeAttribute("aria-required"),this.nativeSelect&&(this.nativeSelect.required=e.required)),e.templateResult!==void 0&&(this.opts.templateResult=e.templateResult),e.templateSelection!==void 0&&(this.opts.templateSelection=e.templateSelection),e.sanitizeTemplate!==void 0&&(this.opts.sanitizeTemplate=e.sanitizeTemplate),e.beforeSelect!==void 0&&(this.opts.beforeSelect=e.beforeSelect),e.beforeUnselect!==void 0&&(this.opts.beforeUnselect=e.beforeUnselect),e.beforeCreate!==void 0&&(this.opts.beforeCreate=e.beforeCreate),e.createOption!==void 0&&(this.opts.createOption=e.createOption),e.missingSelectionPolicy!==void 0&&(this.opts.missingSelectionPolicy=e.missingSelectionPolicy),e.duplicateValuePolicy!==void 0&&(this.opts.duplicateValuePolicy=e.duplicateValuePolicy,this.rebuildOptionIndexes()),e.filterOption!==void 0&&(this.opts.filterOption=e.filterOption),e.searchFields!==void 0&&(this.opts.searchFields=e.searchFields),e.tokenSearch!==void 0&&(this.opts.tokenSearch=e.tokenSearch),e.accentInsensitive!==void 0&&(this.opts.accentInsensitive=e.accentInsensitive,this.rebuildOptionIndexes()),e.searchScorer!==void 0&&(this.opts.searchScorer=e.searchScorer),e.highlightSearch!==void 0&&(this.opts.highlightSearch=e.highlightSearch),e.minSearchLength!==void 0&&(this.opts.minSearchLength=Math.max(0,Math.floor(e.minSearchLength))),e.minResultsForSearch!==void 0&&(this.opts.minResultsForSearch=Math.max(0,Math.floor(e.minResultsForSearch))),e.isOptionDisabled!==void 0&&(this.opts.isOptionDisabled=e.isOptionDisabled),e.virtualScroll!==void 0&&(this.opts.virtualScroll=e.virtualScroll),e.itemHeight!==void 0&&(this.opts.variableItemHeight=e.itemHeight==="auto",typeof e.itemHeight=="number"&&(this.opts.itemHeight=Math.max(1,e.itemHeight)),this.root.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.portalHost?.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`)),e.language!==void 0&&(this.opts.language=e.language,this.strings=T(e.language),this.clearBtn.setAttribute("aria-label",this.strings.clearSelection),this.searchInput?.setAttribute("aria-label",this.strings.search)),e.openOnFocus!==void 0&&(this.opts.openOnFocus=e.openOnFocus),e.disabled!==void 0&&(e.disabled?this.disable():this.enable()),this.root.classList.toggle("forge-select--sortable",this.opts.sortable&&this.opts.multiple),this.updateSearchVisibility(),this.clearRowCaches(),this.searchIndex.clear(),this.renderValue(),this.isOpen&&this.renderList()}validate(){let e=(!this.opts.required||this.selected.length>0)&&(this.control.dataset.validationMessage??"")==="";return this.control.classList.toggle("forge-select__control--invalid",!e),this.control.setAttribute("aria-invalid",String(!e)),e}setCustomValidity(e){this.nativeSelect?.setCustomValidity(e),this.control.dataset.validationMessage=e}reportValidity(){let e=this.validate()&&(this.nativeSelect?.checkValidity()??!0);if(!e){let t=this.nativeSelect?.validationMessage??this.control.dataset.validationMessage??"";if(this.nativeSelect)return this.nativeSelect.reportValidity();this.emitter.emit("invalid",t)}return e}reload(){this.opts.ajax&&(this.clearRemoteCache(),this.remoteLoaded=!1,this.scheduleRemoteLoad(this.query,0))}clearRemoteCache(){this.remoteCache.clear(),this.remoteInFlight.clear()}setValue(e,t={}){let i=e==null?[]:Array.isArray(e)?e:[e],s=this.opts.multiple?i:i.slice(0,1);if(!q(s,this.selected)){this.selected=[];for(let r of s)this.selectValue(r,!1);this.afterSelectionChange(t.emitChange??!0)}}setData(e){this.ajaxTimer&&(clearTimeout(this.ajaxTimer),this.ajaxTimer=null),this.ajaxController?.abort(),this.ajaxController=null,this.ajaxRequestId+=1,this.setLoading(!1),this.loadingMore=!1,this.loadError=null,this.remoteLoaded=!0,this.page=0,this.hasMore=!1,this.nextCursor=void 0;let t=this.data;this.data=e;try{this.rebuildOptionIndexes()}catch(s){throw this.data=t,this.rebuildOptionIndexes(),s}let i=this.selected.filter(s=>!this.optionByValue.has(s));if(i.length>0&&this.opts.missingSelectionPolicy==="error")throw this.data=t,this.rebuildOptionIndexes(),new Error(`ForgeSelect: setData() is missing selected value(s): ${i.join(", ")}`);this.opts.data=e,i.length>0&&this.opts.missingSelectionPolicy==="prune"&&(this.selected=this.selected.filter(s=>this.optionByValue.has(s)),this.afterSelectionChange()),this.updateSearchVisibility(),this.clearRowCaches(),this.searchIndex.clear(),this.highlightedIndex=-1,this.isOpen&&this.renderList()}selectAll(){if(this.opts.multiple){this.selected=[];for(let e of this.allSelectableValues()){let t=this.findOption(e);t&&this.canSelectOption(t)&&this.selectValue(e,!1)}this.afterSelectionChange()}}clearAll(){this.clearSelection()}enable(){this.isDisabled=!1,this.root.classList.remove("forge-select--disabled"),this.control.tabIndex=0,this.control.setAttribute("aria-disabled","false"),this.nativeSelect&&(this.nativeSelect.disabled=!1)}disable(){this.close(),this.isDisabled=!0,this.root.classList.add("forge-select--disabled"),this.control.tabIndex=-1,this.control.setAttribute("aria-disabled","true"),this.nativeSelect&&(this.nativeSelect.disabled=!0)}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}applyAccessibleName(){let e=this.el.getAttribute("aria-labelledby"),t=this.el.getAttribute("aria-label");if(e)this.control.setAttribute("aria-labelledby",e);else if(t)this.control.setAttribute("aria-label",t);else if(this.el.id){let i=Array.from(document.getElementsByTagName("label")).find(s=>s.htmlFor===this.el.id);i&&(i.id||(i.id=`${this.uid}-label`),this.control.setAttribute("aria-labelledby",i.id))}}shouldShowSearch(){return this.opts.searchable&&(this.opts.ajax!=null||A(this.data).size>=this.opts.minResultsForSearch)}updateSearchVisibility(){this.searchInput&&(this.searchInput.hidden=!this.shouldShowSearch(),this.searchInput.hidden&&(this.searchInput.value="",this.query=""))}buildDom(){let e=typeof this.opts.dropdownParent=="string"?document.querySelector(this.opts.dropdownParent):this.opts.dropdownParent;if(this.opts.dropdownParent&&!e)throw new Error(`ForgeSelect: dropdown parent not found: ${String(this.opts.dropdownParent)}`);this.root=document.createElement("div"),this.root.className="forge-select",this.root.dataset.theme=this.opts.theme,this.root.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.opts.sortable&&this.opts.multiple&&this.root.classList.add("forge-select--sortable"),this.control=document.createElement("div"),this.control.className="forge-select__control",this.control.setAttribute("role","combobox"),this.control.setAttribute("aria-haspopup","listbox"),this.control.setAttribute("aria-expanded","false"),this.control.setAttribute("aria-controls",`${this.uid}-list`),this.opts.required&&this.control.setAttribute("aria-required","true"),this.control.tabIndex=0,this.applyAccessibleName(),this.valueEl=document.createElement("div"),this.valueEl.className="forge-select__value",this.clearBtn=document.createElement("button"),this.clearBtn.type="button",this.clearBtn.className="forge-select__clear",this.clearBtn.setAttribute("aria-label",this.strings.clearSelection),this.clearBtn.textContent="\xD7",this.clearBtn.hidden=!0;let t=document.createElement("span");t.className="forge-select__arrow",t.setAttribute("aria-hidden","true"),this.control.append(this.valueEl,this.clearBtn,t),this.dropdown=document.createElement("div"),this.dropdown.className="forge-select__dropdown",this.dropdown.hidden=!0,this.opts.searchable&&(this.searchInput=document.createElement("input"),this.searchInput.type="search",this.searchInput.className="forge-select__search",this.searchInput.setAttribute("aria-label",this.strings.search),this.searchInput.setAttribute("aria-autocomplete","list"),this.searchInput.setAttribute("aria-controls",`${this.uid}-list`),this.searchInput.hidden=!this.shouldShowSearch(),this.dropdown.append(this.searchInput)),this.list=document.createElement("ul"),this.list.className="forge-select__list",this.list.id=`${this.uid}-list`,this.list.setAttribute("role","listbox"),this.opts.multiple&&this.list.setAttribute("aria-multiselectable","true"),this.dropdown.append(this.list),this.liveRegion=document.createElement("div"),this.liveRegion.className="forge-select__sr-only",this.liveRegion.setAttribute("role","status"),this.liveRegion.setAttribute("aria-live","polite"),this.root.append(this.control,this.liveRegion),e||this.root.append(this.dropdown),this.el.style.display="none",this.el.insertAdjacentElement("afterend",this.root),e&&(this.portalHost=document.createElement("div"),this.portalHost.className="forge-select forge-select--portal-host",this.portalHost.style.direction=getComputedStyle(this.root).direction,this.portalHost.dataset.theme=this.opts.theme,this.portalHost.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.portalHost.append(this.dropdown),e.append(this.portalHost)),this.bindEvents()}bindEvents(){if(this.control.addEventListener("click",e=>{if(e.target!==this.clearBtn){if(this.suppressNextTagClick){this.suppressNextTagClick=!1;return}this.isDisabled||(this.isOpen?this.close():this.open())}}),this.control.addEventListener("keydown",e=>this.handleKeydown(e)),this.control.addEventListener("mousedown",()=>{this.pointerDownOnControl=!0}),this.control.addEventListener("focus",()=>{this.opts.openOnFocus&&!this.pointerDownOnControl&&!this.isOpen&&!this.isDisabled&&this.open(),this.pointerDownOnControl=!1}),this.clearBtn.addEventListener("click",e=>{e.stopPropagation(),!this.selected.some(t=>{let i=this.findOption(t)??this.selectedOptions.get(t)??{value:t,label:t};return this.opts.beforeUnselect?.(i)===!1})&&this.clearSelection()}),this.searchInput){let e=!1;this.searchInput.addEventListener("compositionstart",()=>{e=!0}),this.searchInput.addEventListener("compositionend",()=>{e=!1,this.applySearchQuery(this.searchInput.value,!0)}),this.searchInput.addEventListener("input",()=>{e||this.applySearchQuery(this.searchInput.value,!0)}),this.searchInput.addEventListener("keydown",t=>this.handleKeydown(t)),this.searchInput.addEventListener("paste",t=>{if(!this.opts.multiple||!this.opts.allowCreate)return;let s=(t.clipboardData?.getData("text")??"").split(/[,\n]+/).map(r=>r.trim()).filter(Boolean);s.length<2||(t.preventDefault(),Promise.all(s.map(r=>this.createTag(r))).then(r=>{let n=r.filter(a=>a!==void 0);if(!(n.length===0||this.destroyed)){this.searchInput.value="",this.query="",this.afterSelectionChange();for(let a of n)a.created&&this.emitter.emit("create",a.option),this.emitter.emit("select",a.option);this.opts.closeOnSelect?this.close():this.renderList()}}).catch(r=>{let n=r instanceof Error?r:new Error(String(r));this.emitter.emit("error",n)}))})}this.list.addEventListener("click",e=>{let t=e.target,i=t.closest("[data-twisty]");if(i){let n=i.dataset.twisty;this.expandedValues.has(n)?this.expandedValues.delete(n):this.expandedValues.add(n),this.renderList();return}let s=t.closest("li[data-nav-index]");if(!s){let n=t.closest("li[data-option-value]"),a=n?this.findOption(n.dataset.optionValue):void 0;a&&this.hasReachedMaximum()&&!this.selected.includes(a.value)&&this.announceMaximum(a);return}let r=Number(s.dataset.navIndex);this.activateNavItem(r)}),this.list.addEventListener("scroll",()=>{this.scrollRafId==null&&(this.scrollRafId=requestAnimationFrame(()=>{this.scrollRafId=null,this.usesVirtualScroll()&&this.renderRows(),this.maybeLoadNextPage()}))})}applySearchQuery(e,t){this.query=e,this.searchInput&&this.searchInput.value!==e&&(this.searchInput.value=e),this.highlightedIndex=-1,this.list.scrollTop=0,t&&this.emitter.emit("search",e);let i=e.trim(),s=i!==""&&i.length<this.opts.minSearchLength;if(this.opts.ajax&&!s){this.scheduleRemoteLoad(e,this.opts.ajax.debounce??250);return}s&&(this.ajaxTimer&&(clearTimeout(this.ajaxTimer),this.ajaxTimer=null),this.ajaxController?.abort(),this.setLoading(!1)),this.renderList()}handleKeydown(e){if(!(this.isDisabled||e.isComposing||e.keyCode===229))switch(e.key){case"Enter":e.preventDefault(),this.isOpen?this.highlightedIndex>=0&&this.activateNavItem(this.highlightedIndex):this.open();break;case" ":e.target===this.control&&(e.preventDefault(),this.isOpen||this.open());break;case"ArrowDown":e.preventDefault(),this.isOpen?this.moveHighlight(1):this.open();break;case"ArrowUp":e.preventDefault(),this.isOpen&&this.moveHighlight(-1);break;case"Escape":this.isOpen&&(e.preventDefault(),this.close(),this.control.focus());break;case"ArrowRight":this.isOpen&&this.navigateTree("right")&&e.preventDefault();break;case"ArrowLeft":this.isOpen&&this.navigateTree("left")&&e.preventDefault();break;case"Home":this.isOpen&&(e.preventDefault(),this.focusNavIndex(0));break;case"End":this.isOpen&&(e.preventDefault(),this.focusNavIndex(this.navItems.length-1));break;case"PageDown":this.isOpen&&(e.preventDefault(),this.focusNavIndex(Math.min(this.navItems.length-1,(this.highlightedIndex===-1?0:this.highlightedIndex)+z)));break;case"PageUp":this.isOpen&&(e.preventDefault(),this.focusNavIndex(Math.max(0,(this.highlightedIndex===-1?0:this.highlightedIndex)-z)));break;case"Tab":this.close();break;default:this.isOpen&&e.target===this.control&&e.key.length===1&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&this.handleTypeahead(e.key);break}}handleTypeahead(e){this.typeaheadTimer&&clearTimeout(this.typeaheadTimer),this.typeaheadBuffer+=f(e,this.opts.accentInsensitive),this.typeaheadTimer=setTimeout(()=>{this.typeaheadBuffer="",this.typeaheadTimer=null},J);let t=[...this.typeaheadBuffer].every(s=>s===this.typeaheadBuffer[0])?this.typeaheadBuffer[0]:this.typeaheadBuffer,i=this.navItems.length;for(let s=1;s<=i;s+=1){let r=(this.highlightedIndex+s+i)%i,n=this.navItems[r];if(n.kind==="option"&&f(n.option.label,this.opts.accentInsensitive).startsWith(t)){this.focusNavIndex(r);return}}}canSelectOption(e){if(this.opts.maxSelections==null)return!0;let t=[...this.selected];t.includes(e.value)||t.push(e.value);for(let i of x(e,this.isOptionDisabled))t.includes(i)||t.push(i);return M(this.data,t,this.isOptionDisabled),t.length<=this.opts.maxSelections}hasReachedMaximum(){return this.opts.maxSelections!=null&&this.selected.length>=this.opts.maxSelections}announceMaximum(e){let t=this.opts.maxSelections;t!=null&&(this.liveRegion.textContent=g(this.strings.maximumSelected,{count:String(t)}),this.emitter.emit("maximum",{limit:t,option:e}))}selectValue(e,t){if(this.selected.includes(e))return;let i=this.findOption(e)??this.selectedOptions.get(e)??{value:e,label:e};if(this.selectedOptions.set(e,i),this.opts.multiple){this.selected.push(e);for(let s of x(i,this.isOptionDisabled))this.selected.includes(s)||this.selected.push(s);this.syncTreeAncestors()}else this.selected=[e];t&&(this.afterSelectionChange(),this.emitter.emit("select",i))}deselectValue(e,t){let i=this.selected.indexOf(e);if(i===-1)return;let s=this.findOption(e)??this.selectedOptions.get(e);if(this.selected.splice(i,1),this.opts.multiple){if(s)for(let r of x(s,this.isOptionDisabled)){let n=this.selected.indexOf(r);n!==-1&&this.selected.splice(n,1)}this.syncTreeAncestors()}t&&(this.afterSelectionChange(),this.emitter.emit("unselect",s??{value:e,label:e}))}syncTreeAncestors(){M(this.data,this.selected,this.isOptionDisabled)}clearSelection(){this.selected.length!==0&&(this.selected=[],this.emitter.emit("clear"),this.afterSelectionChange())}allSelectableValues(){let e=[],t=i=>{this.isOptionDisabled(i)||e.push(i.value),i.children?.forEach(t)};for(let i of this.data)(v(i)?i.options:[i]).forEach(t);return e}afterSelectionChange(e=!0){this.renderValue(),this.syncNativeSelect(e),(!this.opts.required||this.selected.length>0)&&(this.control.classList.remove("forge-select__control--invalid"),this.control.removeAttribute("aria-invalid")),this.isOpen&&(this.opts.maxSelections!=null?this.renderList():this.renderRows()),e&&this.emitter.emit("change",this.getValue())}syncNativeSelect(e=!0){if(!(this.el instanceof HTMLSelectElement))return;let t=new Set;for(let i of Array.from(this.el.options))t.add(i.value),i.selected=this.selected.includes(i.value);for(let i of this.selected){if(t.has(i))continue;let s=document.createElement("option");s.value=i,s.textContent=this.selectedOptions.get(i)?.label??i,s.selected=!0,this.el.append(s)}if(this.opts.sortable&&this.opts.multiple)for(let i of this.selected){let s=Array.from(this.el.options).find(r=>r.value===i);s&&this.el.append(s)}if(e){this.syncingNative=!0;try{this.el.dispatchEvent(new Event("change",{bubbles:!0}))}finally{this.syncingNative=!1}}}findOption(e){return this.optionByValue.get(e)}findOptionByLabel(e){return this.optionByLabel.get(f(e,this.opts.accentInsensitive))}rebuildOptionIndexes(){this.optionByValue.clear(),this.optionByLabel.clear();let e=new Set,t=s=>{this.optionByValue.has(s.value)?e.add(s.value):this.optionByValue.set(s.value,s);let r=f(s.label,this.opts.accentInsensitive);this.optionByLabel.has(r)||this.optionByLabel.set(r,s),s.children?.forEach(t)};for(let s of this.data)(v(s)?s.options:[s]).forEach(t);if(e.size===0||this.opts.duplicateValuePolicy==="ignore")return;let i=`ForgeSelect: duplicate option value(s): ${[...e].join(", ")}`;if(this.opts.duplicateValuePolicy==="error")throw new Error(i);console.warn(i)}createTag(e){let t=e.trim();if(!t)return;let i=this.findOptionByLabel(t);if(i){if(this.selected.includes(i.value))return;if(this.opts.multiple&&!this.canSelectOption(i)){this.announceMaximum(i);return}return this.opts.beforeSelect?.(i)===!1?void 0:(this.selectValue(i.value,!1),{option:i,created:!1})}if(this.opts.beforeCreate?.(t)===!1)return;let s=this.opts.createOption?.(t)??{value:t,label:t};return s instanceof Promise?s.then(r=>r?this.addCreatedOption(r):void 0):s?this.addCreatedOption(s):void 0}addCreatedOption(e){if(this.opts.multiple&&!this.canSelectOption(e)){this.announceMaximum(e);return}let t=this.findOption(e.value);return t?this.selected.includes(t.value)||this.opts.beforeSelect?.(t)===!1?void 0:(this.selectValue(t.value,!1),{option:t,created:!1}):(this.data.push(e),this.rebuildOptionIndexes(),this.selectValue(e.value,!1),{option:e,created:!0})}createFromQuery(){let e=this.query.trim();if(!e)return;let t=this.createTag(e);if(t instanceof Promise){t.then(i=>this.finishCreateFromQuery(i,e)).catch(i=>{let s=i instanceof Error?i:new Error(String(i));this.emitter.emit("error",s)});return}this.finishCreateFromQuery(t,e)}finishCreateFromQuery(e,t){!e||this.destroyed||(this.searchInput&&this.query.trim()===t&&(this.searchInput.value="",this.query=""),this.afterSelectionChange(),e.created&&this.emitter.emit("create",e.option),this.emitter.emit("select",e.option),!this.opts.multiple||this.opts.closeOnSelect?this.close():this.isOpen&&this.renderList())}activateNavItem(e){let t=this.navItems[e];if(!t)return;if(t.kind==="create"){this.createFromQuery();return}let{value:i}=t.option;if(this.opts.multiple){let s=!1;if(this.selected.includes(i)){if(this.opts.beforeUnselect?.(t.option)===!1)return;this.deselectValue(i,!0),s=!0}else if(this.canSelectOption(t.option)){if(this.opts.beforeSelect?.(t.option)===!1)return;this.selectValue(i,!0),s=!0}else this.announceMaximum(t.option);s&&this.opts.closeOnSelect&&this.close()}else{if(this.opts.beforeSelect?.(t.option)===!1)return;this.selectValue(i,!0),this.close(),this.control.focus()}}renderValue(){this.valueEl.textContent="";let e=this.selected.length>0;if(this.clearBtn.hidden=!(this.opts.clearable&&e),!e){let t=document.createElement("span");t.className="forge-select__placeholder",t.textContent=this.opts.placeholder,this.valueEl.append(t);return}if(this.opts.multiple)for(let t of this.selected){let i=this.selectedOptions.get(t)??{value:t,label:t},s=document.createElement("span");s.className="forge-select__tag";let r=document.createElement("span");r.className="forge-select__tag-label",S(r,i,this.opts.templateSelection,"inline",this.opts.sanitizeTemplate);let n=document.createElement("button");n.type="button",n.className="forge-select__tag-remove",n.setAttribute("aria-label",g(this.strings.removeItem,{label:i.label})),n.textContent="\xD7",n.addEventListener("click",a=>{a.stopPropagation(),!this.isDisabled&&this.opts.beforeUnselect?.(i)!==!1&&this.deselectValue(t,!0)}),s.append(r,n),this.opts.sortable&&(s.dataset.value=t,s.tabIndex=0,s.setAttribute("aria-roledescription","draggable item"),s.setAttribute("aria-label",g(this.strings.reorderHint,{label:i.label})),s.addEventListener("keydown",a=>this.handleTagKeydown(a,t)),this.bindTagDrag(s,t)),this.valueEl.append(s)}else{let t=this.selectedOptions.get(this.selected[0])??{value:this.selected[0],label:this.selected[0]},i=document.createElement("span");i.className="forge-select__single-value",S(i,t,this.opts.templateSelection,"inline",this.opts.sanitizeTemplate),this.valueEl.append(i)}}bindTagDrag(e,t){let s=0,r=!1,n=[],a=l=>{if(!r){if(Math.abs(l.clientX-s)<4)return;r=!0,n=[...this.selected],typeof this.valueEl.setPointerCapture=="function"&&this.valueEl.setPointerCapture(l.pointerId),e.classList.add("forge-select__tag--dragging")}l.preventDefault();let c=n.indexOf(t),d=Array.from(this.valueEl.querySelectorAll(".forge-select__tag"));for(let u of d){if(u===e)continue;let m=u.dataset.value;if(!m)continue;let p=n.indexOf(m);if(p===-1)continue;let H=u.getBoundingClientRect(),k=H.left+H.width/2,D=c<p;if(D?l.clientX>k:l.clientX<k){n.splice(c,1),n.splice(p,0,t),D?this.valueEl.insertBefore(e,u.nextSibling):this.valueEl.insertBefore(e,u);break}}},h=l=>{this.valueEl.removeEventListener("pointermove",a),this.valueEl.removeEventListener("pointerup",h),this.valueEl.removeEventListener("pointercancel",h),r&&(typeof this.valueEl.releasePointerCapture=="function"&&this.valueEl.releasePointerCapture(l.pointerId),e.classList.remove("forge-select__tag--dragging"),this.selected=n,this.suppressNextTagClick=!0,this.afterSelectionChange(),this.emitter.emit("reorder",[...this.selected]))};e.addEventListener("pointerdown",l=>{this.isDisabled||l.button!==0||l.target.closest(".forge-select__tag-remove")||(s=l.clientX,r=!1,this.valueEl.addEventListener("pointermove",a),this.valueEl.addEventListener("pointerup",h),this.valueEl.addEventListener("pointercancel",h))})}handleTagKeydown(e,t){if(!e.altKey||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;let i=this.selected.indexOf(t),s=e.key==="ArrowLeft"?i-1:i+1;if(i===-1||s<0||s>=this.selected.length)return;e.preventDefault(),e.stopPropagation();let r=[...this.selected];[r[i],r[s]]=[r[s],r[i]],this.selected=r,this.afterSelectionChange(),this.emitter.emit("reorder",[...this.selected]),this.focusTagByValue(t)}focusTagByValue(e){for(let t of Array.from(this.valueEl.querySelectorAll(".forge-select__tag")))if(t.dataset.value===e){t.focus();return}}buildRows(){this.rows=[],this.navItems=[],this.rowOffsetsCache=null;let e=this.query.trim(),t=f(e,this.opts.accentInsensitive),i=a=>t===""||(this.opts.filterOption?this.opts.filterOption(a,e):this.searchIndex.score(a,e,{fields:this.opts.searchFields,tokenSearch:this.opts.tokenSearch,accentInsensitive:this.opts.accentInsensitive,scorer:this.opts.searchScorer})>0),s=new Map,r=a=>{let h=s.get(a);if(h!==void 0)return h;let l=t===""||i(a)||(a.children??[]).some(r);return s.set(a,l),l},n=(a,h,l)=>{let c=-1;this.isOptionDisabled(a)||this.hasReachedMaximum()&&!this.selected.includes(a.value)||(c=this.navItems.length,this.navItems.push({kind:"option",option:a,parentValue:l}));let u=!!a.children&&a.children.length>0;if(this.rows.push({kind:"option",option:a,navIndex:c,depth:h,hasChildren:u}),u&&(t!==""||this.expandedValues.has(a.value)))for(let p of a.children)r(p)&&n(p,h+1,a.value)};if(e!==""&&e.length<this.opts.minSearchLength){this.rows.push({kind:"min-length"});return}if(this.loading){this.rows.push({kind:"loading"});return}if(this.loadError){this.rows.push({kind:"error"});return}for(let a of this.data)if(v(a)){let h=a.options.filter(r);if(h.length===0)continue;this.rows.push({kind:"group",label:a.label}),h.forEach(l=>n(l,0))}else r(a)&&n(a,0);if(this.opts.allowCreate&&t!==""&&!this.hasExactMatch(t)){let a=this.navItems.length;this.navItems.push({kind:"create"}),this.rows.push({kind:"create",navIndex:a})}this.rows.length===0?this.rows.push({kind:"empty"}):this.loadingMore&&this.rows.push({kind:"loading-more"})}hasExactMatch(e){return!!this.findOptionByLabel(e)}usesVirtualScroll(){return this.opts.virtualScroll!==!1&&this.rows.length>Z}clearRowCaches(){this.rowContentCache.clear(),this.rowElementCache.clear(),this.rowHeightCache.clear(),this.rowOffsetsCache=null}rowKey(e,t){return e.kind==="option"?`option:${e.option.value}:${t}`:e.kind==="group"?`group:${e.label}:${t}`:`${e.kind}:${t}`}measuredRowHeight(e){return this.opts.variableItemHeight?this.rowHeightCache.get(this.rowKey(this.rows[e],e))??this.opts.itemHeight:this.opts.itemHeight}rowOffset(e){if(!this.opts.variableItemHeight)return e*this.opts.itemHeight;let t=0;for(let i=0;i<e;i+=1)t+=this.measuredRowHeight(i);return t}rowOffsets(){if(this.rowOffsetsCache)return this.rowOffsetsCache;let e=[0];for(let t=0;t<this.rows.length;t+=1)e.push(e[t]+this.measuredRowHeight(t));return this.rowOffsetsCache=e,e}renderList(){this.buildRows(),this.renderRows(),this.announceStatus()}announceStatus(){let e=this.rows[0],t=this.hasReachedMaximum()?g(this.strings.maximumSelected,{count:String(this.opts.maxSelections)}):e?.kind==="loading"?this.strings.loading:e?.kind==="error"?this.strings.errorLoading:e?.kind==="empty"?this.strings.noResults:e?.kind==="min-length"?g(this.strings.minSearchLength,{count:String(this.opts.minSearchLength)}):"";this.liveRegion.textContent!==t&&(this.liveRegion.textContent=t)}renderRows(){let e=this.list.scrollTop,t=this.list.clientHeight,i=this.usesVirtualScroll();this.list.textContent="";let s=this.opts.itemHeight,r=this.opts.variableItemHeight?this.rowOffsets():null,n=0,a=this.rows.length;if(i){let l=t||s*8;if(this.opts.variableItemHeight){let d=0,u=this.rows.length;for(;d<u;){let p=d+u>>>1;r[p+1]<e?d=p+1:u=p}n=d,n=Math.max(0,n-E),a=n;let m=e+l+E*s;for(;a<this.rows.length&&r[a]<m;)a+=1}else n=Math.max(0,Math.floor(e/s)-E),a=Math.min(this.rows.length,n+Math.ceil(l/s)+E*2);let c=document.createElement("li");c.className="forge-select__spacer",c.setAttribute("aria-hidden","true"),c.style.height=`${r?.[n]??this.rowOffset(n)}px`,this.list.append(c)}let h=[];for(let l=n;l<a;l++){let c=this.rowKey(this.rows[l],l),d=this.renderRow(this.rows[l],this.rowElementCache.get(c));if(this.rowElementCache.set(c,d),this.rowElementCache.size>B){let u=this.rowElementCache.keys().next().value;this.rowElementCache.delete(u)}this.list.append(d),h.push(d)}if(this.opts.variableItemHeight)for(let l=n;l<a;l++){let c=h[l-n],d=c.getBoundingClientRect().height||c.offsetHeight;if(d>0){let u=this.rowKey(this.rows[l],l);this.rowHeightCache.get(u)!==d&&(this.rowOffsetsCache=null),this.rowHeightCache.set(u,d)}}if(i){let l=document.createElement("li");l.className="forge-select__spacer",l.setAttribute("aria-hidden","true"),l.style.height=`${r?r[this.rows.length]-r[a]:this.rowOffset(this.rows.length)-this.rowOffset(a)}px`,this.list.append(l),this.list.scrollTop!==e&&(this.list.scrollTop=e)}this.updateActiveDescendant()}renderRow(e,t){let i=t??document.createElement("li");i.replaceChildren(),i.className="";for(let s of["role","id","aria-hidden","aria-selected","aria-disabled","aria-expanded","aria-level","data-nav-index","data-option-value","data-selection-state","style"])i.removeAttribute(s);switch(e.kind){case"group":i.className="forge-select__group-label",i.setAttribute("role","presentation"),i.textContent=e.label;break;case"empty":i.className="forge-select__empty",i.setAttribute("role","option"),i.setAttribute("aria-disabled","true"),i.setAttribute("aria-selected","false"),i.textContent=this.strings.noResults;break;case"min-length":i.className="forge-select__min-length",i.setAttribute("role","option"),i.setAttribute("aria-disabled","true"),i.setAttribute("aria-selected","false"),i.textContent=g(this.strings.minSearchLength,{count:String(this.opts.minSearchLength)});break;case"error":i.className="forge-select__error",i.setAttribute("role","option"),i.setAttribute("aria-disabled","true"),i.setAttribute("aria-selected","false"),i.textContent=this.strings.errorLoading;break;case"loading":i.className="forge-select__loading",i.setAttribute("role","option"),i.setAttribute("aria-disabled","true"),i.setAttribute("aria-selected","false"),i.textContent=this.strings.loading;break;case"loading-more":i.className="forge-select__loading-more",i.setAttribute("aria-hidden","true"),i.textContent=this.strings.loadingMore;break;case"create":i.className="forge-select__option forge-select__option--create",i.setAttribute("role","option"),i.id=`${this.uid}-nav-${e.navIndex}`,i.dataset.navIndex=String(e.navIndex),i.textContent=g(this.strings.createOption,{query:this.query.trim()}),e.navIndex===this.highlightedIndex&&i.classList.add("forge-select__option--highlighted");break;case"option":this.renderOptionRow(i,e);break}return i}renderOptionRow(e,t){e.className="forge-select__option",e.dataset.optionValue=t.option.value,t.option.className&&e.classList.add(...t.option.className.trim().split(/\s+/).filter(Boolean)),e.setAttribute("role","option");let i=this.selected.includes(t.option.value);if(e.setAttribute("aria-selected",String(i)),i&&e.classList.add("forge-select__option--selected"),this.opts.multiple&&t.hasChildren&&I(t.option,this.selected,this.isOptionDisabled)==="some"&&(e.classList.add("forge-select__option--indeterminate"),e.dataset.selectionState="mixed"),t.depth>0&&(e.style.paddingLeft=`calc(12px + ${t.depth} * var(--fs-tree-indent, 18px))`),this.isOptionDisabled(t.option)||this.hasReachedMaximum()&&!this.selected.includes(t.option.value)?(e.classList.add("forge-select__option--disabled"),e.setAttribute("aria-disabled","true")):(e.id=`${this.uid}-nav-${t.navIndex}`,e.dataset.navIndex=String(t.navIndex),t.navIndex===this.highlightedIndex&&e.classList.add("forge-select__option--highlighted")),t.hasChildren){let s=this.query!==""||this.expandedValues.has(t.option.value);e.setAttribute("aria-expanded",String(s));let r=document.createElement("span");r.className="forge-select__twisty",r.dataset.twisty=t.option.value,r.setAttribute("aria-hidden","true"),r.textContent=s?"\u25BC":"\u25B6",e.append(r)}e.append(this.optionContent(t.option))}optionContent(e){if(this.opts.highlightSearch&&this.query.trim()&&!this.opts.templateResult){let i=document.createElement("span");i.className="forge-select__option-content",S(i,e,void 0);let s=i.querySelector(".forge-select__option-label")??i,r=j(e.label,this.query,this.opts.accentInsensitive);if(r.length){s.textContent="";let n=0;for(let[a,h]of r){if(a<n)continue;s.append(document.createTextNode(e.label.slice(n,a)));let l=document.createElement("mark");l.className="forge-select__match",l.textContent=e.label.slice(a,h),s.append(l),n=h}s.append(document.createTextNode(e.label.slice(n)))}return i}let t=this.rowContentCache.get(e.value);if(!t){let i=document.createElement("span");if(i.className="forge-select__option-content",S(i,e,this.opts.templateResult,"row",this.opts.sanitizeTemplate),this.rowContentCache.size>=B){let s=this.rowContentCache.keys().next().value;this.rowContentCache.delete(s)}this.rowContentCache.set(e.value,i),t=i}return t.cloneNode(!0)}moveHighlight(e){if(this.navItems.length===0)return;let t=this.highlightedIndex===-1?e>0?0:this.navItems.length-1:(this.highlightedIndex+e+this.navItems.length)%this.navItems.length;this.focusNavIndex(t)}focusNavIndex(e){if(this.navItems.length!==0)if(this.highlightedIndex=e,this.usesVirtualScroll()){let t=this.rows.findIndex(i=>(i.kind==="option"||i.kind==="create")&&i.navIndex===e);if(t>=0){let i=this.measuredRowHeight(t),s=this.rowOffset(t),r=this.list.clientHeight||i*8,n=this.list.scrollTop;s<n?n=s:s+i>n+r&&(n=s+i-r),n!==this.list.scrollTop&&(this.list.scrollTop=n)}this.renderRows()}else this.renderRows(),this.list.querySelector(".forge-select__option--highlighted")?.scrollIntoView?.({block:"nearest"})}navigateTree(e){let t=this.navItems[this.highlightedIndex];if(!t||t.kind!=="option")return!1;let{option:i,parentValue:s}=t,r=!!i.children?.length,n=this.query!==""||this.expandedValues.has(i.value);if(e==="right"){if(r&&!n)return this.expandedValues.add(i.value),this.renderList(),!0;if(r){let a=this.navItems.findIndex(h=>h.kind==="option"&&h.parentValue===i.value);if(a>=0)return this.focusNavIndex(a),!0}return!1}if(r&&n&&this.query==="")return this.expandedValues.delete(i.value),this.renderList(),!0;if(s){let a=this.navItems.findIndex(h=>h.kind==="option"&&h.option.value===s);if(a>=0)return this.focusNavIndex(a),!0}return!1}updateActiveDescendant(){let e=this.searchInput??this.control;this.highlightedIndex>=0?e.setAttribute("aria-activedescendant",`${this.uid}-nav-${this.highlightedIndex}`):e.removeAttribute("aria-activedescendant")}scheduleRemoteLoad(e,t){this.ajaxTimer&&clearTimeout(this.ajaxTimer);let i=++this.ajaxRequestId;this.ajaxController?.abort(),this.ajaxController=null,this.page=0,this.hasMore=!0,this.nextCursor=void 0,this.setLoading(!0),this.loadingMore=!1,this.loadError=null,this.renderList(),this.ajaxTimer=setTimeout(()=>{this.ajaxTimer=null,this.loadRemote(e,{requestId:i})},t)}setLoading(e){this.loading!==e&&(this.loading=e,this.emitter.emit("loading",e))}remoteCacheKey(e,t,i){return`${e}\0${i??t}`}fetchRemoteResult(e,t,i,s){let r=this.remoteCacheKey(e,t,s),n=this.remoteInFlight.get(r);if(n)return n;let a=this.opts.ajax,h=this.requestRemote(e,t,i,s).then(l=>P(a,l)).finally(()=>this.remoteInFlight.delete(r));return this.remoteInFlight.set(r,h),h}async requestRemote(e,t,i,s){let r=this.opts.ajax,n=Math.max(0,Math.floor(r.retry??0))+1,a;for(let h=0;h<n;h+=1)try{if(r.request)return s===void 0?await r.request(e,t,i):await r.request(e,t,i,s);let l=await fetch(N(r,e,t,s),{signal:i});if(l.ok===!1)throw new Error(`ForgeSelect: remote request failed with HTTP ${l.status}`);return await l.json()}catch(l){if(a=l,i.aborted||h===n-1)throw l;let c=Math.max(0,r.retryDelay??250)*2**h;await new Promise((d,u)=>{let m=setTimeout(d,c);i.addEventListener("abort",()=>{clearTimeout(m),u(new DOMException("Aborted","AbortError"))},{once:!0})})}throw a}async prefetchRemote(e){let t=this.opts.ajax;if(!t||(t.cacheTtl??3e4)<=0)return;let i=this.remoteCacheKey(e,0);if(this.remoteCache.get(i))return;let s=new AbortController;this.prefetchControllers.add(s);try{let r=await this.fetchRemoteResult(e,0,s.signal);this.remoteCache.set(i,r,t.cacheTtl??3e4)}catch{}finally{this.prefetchControllers.delete(s)}}maybeLoadNextPage(){if(!this.opts.ajax?.pagination||!this.hasMore||this.loading||this.loadingMore)return;let{scrollHeight:t,scrollTop:i,clientHeight:s}=this.list,r=this.opts.itemHeight*2;t-i-s>=r||(this.loadingMore=!0,this.renderList(),this.loadRemote(this.query,{append:!0}))}async loadRemote(e,{append:t=!1,requestId:i}={}){let s=this.opts.ajax,r=i??++this.ajaxRequestId;if(r!==this.ajaxRequestId)return;this.ajaxController?.abort();let n=new AbortController;this.ajaxController=n;let a=t?this.page+1:0,h=t?this.nextCursor:void 0;try{let l=this.remoteCacheKey(e,a,h),c=this.remoteCache.get(l);if(c||(c=await this.fetchRemoteResult(e,a,n.signal,h),this.remoteCache.set(l,c,s.cacheTtl??3e4)),r!==this.ajaxRequestId||this.destroyed)return;let{options:d,hasMore:u}=c;if(t){let m=A(this.data);this.data=[...this.data,...d.filter(p=>!m.has(p.value))]}else this.data=d,this.clearRowCaches();this.page=a,this.hasMore=u,this.nextCursor=c.nextCursor,this.remoteLoaded=!0,this.loadError=null,this.rebuildOptionIndexes()}catch(l){if(r!==this.ajaxRequestId||this.destroyed||n.signal.aborted)return;let c=l instanceof Error?l:new Error(String(l));t||(this.data=[],this.clearRowCaches()),this.hasMore=!1,this.loadError=c,this.emitter.emit("error",c)}finally{r===this.ajaxRequestId&&!this.destroyed&&(this.ajaxController=null,this.setLoading(!1),this.loadingMore=!1,this.isOpen&&this.renderList())}}};return W(te);})();
2
2
  //# sourceMappingURL=index.global.js.map