@tailng-ui/primitives 0.20.0 → 0.21.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailng-ui/primitives",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,7 +16,7 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "@tailng-ui/cdk": "^0.16.0"
19
+ "@tailng-ui/cdk": "^0.17.0"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "@angular/core": "^21.1.0",
@@ -1 +1 @@
1
- {"version":3,"file":"listbox.directive.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/listbox.directive.ts"],"names":[],"mappings":";AAsBA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;AAEtD,qBAIa,mBAAmB,CAAC,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0D;IACzF,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CACsC;IAChF,QAAQ,CAAC,aAAa,+CAAgD;IACtE,QAAQ,CAAC,QAAQ,0CAA+D;IAEhF,WAAW,iEAAgD;IAC3D,SAAS,qDAA+B;IACxC,QAAQ,+CAAyB;IACjC,IAAI,+CAAwB;IAE5B;;;;OAIG;IACH,SAAS,+CAAwB;IAEjC,QAAQ,CAAC,KAAK,uDAAgC;IAE9C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAmC;IAEtD,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,OAAO,CAA6D;IAC5E,OAAO,CAAC,UAAU,CAAsE;IACxF,OAAO,CAAC,QAAQ,CAA+B;IAO/C,IAAI,SAAa;IAEjB,IACI,SAAS,kBAEZ;IAED,IACI,YAAY,kBAEf;IAED,IACI,gBAAgB,kBAEnB;;IAuHD,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,wBAAwB;IAgBhC,OAAO,CAAC,wBAAwB;IAMhC,OAAO,CAAC,yBAAyB;IAejC,cAAc,CACZ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,OAAO,EACjB,IAAI,CAAC,EAAE,MAAM,EACb,EAAE,CAAC,EAAE,WAAW,GACf,IAAI;IAoBP,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAgBlC,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAyBzD,aAAa,CAAC,KAAK,EAAE,aAAa;IAyClC,aAAa;IAgBb,cAAc,CAAC,KAAK,EAAE,UAAU;IAchC,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO;IAyBhD,OAAO,CAAC,6BAA6B;IAsDrC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQ/B,eAAe,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO;IAYlC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAItB,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,YAAY,CAAC,IAAI,GAAE,OAAO,GAAG,MAAgB,GAAG,IAAI;IAQpD,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO;IAa/D,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQ3C,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAOpC,cAAc,IAAI,CAAC,GAAG,SAAS;yCApf3B,mBAAmB;2CAAnB,mBAAmB;CA0f/B"}
1
+ {"version":3,"file":"listbox.directive.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/listbox.directive.ts"],"names":[],"mappings":";AAsBA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;AAEtD,qBAIa,mBAAmB,CAAC,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0D;IACzF,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CACsC;IAChF,QAAQ,CAAC,aAAa,+CAAgD;IACtE,QAAQ,CAAC,QAAQ,0CAA+D;IAEhF,WAAW,iEAAgD;IAC3D,SAAS,qDAA+B;IACxC,QAAQ,+CAAyB;IACjC,IAAI,+CAAwB;IAE5B;;;;OAIG;IACH,SAAS,+CAAwB;IAEjC,QAAQ,CAAC,KAAK,uDAAgC;IAE9C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAmC;IAEtD,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,OAAO,CAA6D;IAC5E,OAAO,CAAC,UAAU,CAAsE;IACxF,OAAO,CAAC,QAAQ,CAA+B;IAO/C,IAAI,SAAa;IAEjB,IACI,SAAS,kBAEZ;IAED,IACI,YAAY,kBAEf;IAED,IACI,gBAAgB,kBAEnB;;IA2HD,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,wBAAwB;IAgBhC,OAAO,CAAC,wBAAwB;IAMhC,OAAO,CAAC,yBAAyB;IAejC,cAAc,CACZ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,OAAO,EACjB,IAAI,CAAC,EAAE,MAAM,EACb,EAAE,CAAC,EAAE,WAAW,GACf,IAAI;IAoBP,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAgBlC,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAyBzD,aAAa,CAAC,KAAK,EAAE,aAAa;IAyClC,aAAa;IAgBb,cAAc,CAAC,KAAK,EAAE,UAAU;IAchC,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO;IAyBhD,OAAO,CAAC,6BAA6B;IAsDrC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQ/B,eAAe,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO;IAYlC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAItB,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,YAAY,CAAC,IAAI,GAAE,OAAO,GAAG,MAAgB,GAAG,IAAI;IAQpD,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO;IAa/D,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQ3C,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAOpC,cAAc,IAAI,CAAC,GAAG,SAAS;yCAxf3B,mBAAmB;2CAAnB,mBAAmB;CA8f/B"}
@@ -62,6 +62,9 @@ export class TngListboxDirective {
62
62
  const isMulti = this.multiple();
63
63
  const opts = this.options();
64
64
  const external = this.value();
65
+ if (opts.length === 0) {
66
+ return;
67
+ }
65
68
  if (!isMulti) {
66
69
  if (external === null)
67
70
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"listbox.directive.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/listbox.directive.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Directive,\n ElementRef,\n HostBinding,\n HostListener,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { createListboxController } from '@tailng-ui/cdk';\nimport type { TngListNavigationAction } from '@tailng-ui/cdk';\nimport {\n TNG_LISTBOX,\n TNG_LISTBOX_FORCE_MULTIPLE,\n TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER,\n} from './tokens';\n\nexport type ListboxValue<T> = T | readonly T[] | null;\n\n@Directive({\n selector: '[tngListbox]',\n providers: [{ provide: TNG_LISTBOX, useExisting: TngListboxDirective }],\n})\nexport class TngListboxDirective<T> {\n private readonly _forceMultiple = inject(TNG_LISTBOX_FORCE_MULTIPLE, { optional: true });\n private readonly preserveValueOnUnregister =\n inject(TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, { optional: true }) ?? false;\n readonly multipleInput = input<boolean>(false, { alias: 'multiple' });\n readonly multiple = computed(() => this._forceMultiple ?? this.multipleInput());\n\n orientation = input<'vertical' | 'horizontal'>('vertical');\n direction = input<'ltr' | 'rtl'>('ltr');\n disabled = input<boolean>(false);\n loop = input<boolean>(true);\n\n /**\n * Enable listbox typeahead (printable key moves active option by option text).\n * Default true for Select compatibility.\n * Autocomplete should set this to false (input owns typing/filtering).\n */\n typeahead = input<boolean>(true);\n\n readonly value = model<ListboxValue<T>>(null);\n\n private readonly el = inject(ElementRef<HTMLElement>);\n\n private idToElement = new Map<string, HTMLElement>();\n private options = signal<{ id: string; value: T; disabled: boolean }[]>([]);\n private controller = signal<ReturnType<typeof createListboxController<T>> | null>(null);\n private activeId = signal<string | null>(null);\n\n // ----------------------------------------------------\n // Host bindings\n // ----------------------------------------------------\n\n @HostBinding('attr.role')\n role = 'listbox';\n\n @HostBinding('attr.aria-multiselectable')\n get ariaMulti() {\n return this.multiple() ? 'true' : null;\n }\n\n @HostBinding('attr.aria-disabled')\n get ariaDisabled() {\n return this.disabled() ? 'true' : null;\n }\n\n @HostBinding('attr.aria-activedescendant')\n get activeDescendant() {\n return this.activeId();\n }\n\n // ----------------------------------------------------\n // Constructor\n // ----------------------------------------------------\n\n constructor() {\n const hostId = `tng-listbox-${Math.random().toString(36).slice(2)}`;\n\n // Controller creation effect\n effect(() => {\n const ctrl = createListboxController<T>({\n hostId,\n selectionMode: this.multiple() ? 'multiple' : 'single',\n orientation: this.orientation(),\n direction: this.direction(),\n disabled: this.disabled(),\n loop: this.loop(),\n });\n\n this.controller.set(ctrl);\n\n const opts = untracked(this.options);\n for (const option of opts) {\n ctrl.registerOption(option);\n }\n });\n\n // Controlled value sanitizer\n effect(() => {\n const isMulti = this.multiple();\n const opts = this.options();\n const external = this.value();\n\n if (!isMulti) {\n if (external === null) return;\n\n const v = external as T;\n const opt = this.findOptionByValue(v, opts);\n\n if (!opt && this.preserveValueOnUnregister) {\n return;\n }\n\n if (!opt || opt.disabled) {\n this.value.set(null);\n }\n return;\n }\n\n if (external === null) return;\n\n const arr = Array.isArray(external)\n ? (external as readonly T[])\n : ([external as T] as readonly T[]);\n\n const filtered = arr.filter((v) => {\n const opt = this.findOptionByValue(v, opts);\n\n if (!opt) {\n return this.preserveValueOnUnregister;\n }\n\n return !opt.disabled;\n });\n\n if (filtered.length !== arr.length) {\n this.value.set(filtered as readonly T[]);\n }\n });\n\n // External value -> controller selection\n effect(() => {\n const ctrl = this.controller();\n if (!ctrl) return;\n\n const opts = this.options();\n const external = this.value();\n\n const toIds = (v: ListboxValue<T>): string[] => {\n if (v === null) return [];\n const arr = Array.isArray(v) ? (v as readonly T[]) : ([v as T] as const);\n\n const ids: string[] = [];\n for (const val of arr) {\n const opt = opts.find((o) => Object.is(o.value, val));\n if (!opt) continue;\n if (opt.disabled) continue;\n ids.push(opt.id);\n }\n return ids;\n };\n\n const nextIds = toIds(external);\n\n if (nextIds.length === 0) {\n ctrl.clearSelection();\n return;\n }\n\n ctrl.setSelectedIds(nextIds);\n });\n\n // Scroll when active changes\n effect(() => {\n const id = this.activeId();\n if (!id) return;\n\n const el = this.idToElement.get(id);\n if (!el) return;\n\n el.scrollIntoView?.({ block: 'nearest' });\n });\n }\n\n // ----------------------------------------------------\n // Helpers\n // ----------------------------------------------------\n\n private findOptionByValue(\n value: T,\n opts: readonly { value: T; disabled: boolean }[],\n ) {\n return opts.find((o) => Object.is(o.value, value));\n }\n\n private isSelectableValue(\n value: T,\n opts: readonly { value: T; disabled: boolean }[],\n ): boolean {\n const opt = this.findOptionByValue(value, opts);\n return !!opt && !opt.disabled;\n }\n\n private syncDomOrderToController(): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n\n const root = this.el.nativeElement;\n const optionEls = Array.from(\n root.querySelectorAll('[role=\"option\"][id]'),\n ) as HTMLElement[];\n\n const ids = optionEls.map((x) => x.id).filter(Boolean);\n\n if (ids.length > 0) {\n ctrl.setItemOrder(ids);\n }\n }\n\n private syncActiveFromController(): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n this.activeId.set(ctrl.getActiveId());\n }\n\n private shouldSyncValueFromAction(action: TngListNavigationAction | null): boolean {\n if (!action) return false;\n if (action.extendSelection) return true;\n\n return (\n action.type === 'select-active' ||\n action.type === 'toggle-active' ||\n action.type === 'select-all'\n );\n }\n\n // ----------------------------------------------------\n // Option registration\n // ----------------------------------------------------\n\n registerOption(\n id: string,\n value: T,\n disabled: boolean,\n text?: string,\n el?: HTMLElement,\n ): void {\n if (el) {\n this.idToElement.set(id, el);\n }\n\n this.options.update((list) => {\n const idx = list.findIndex((x) => x.id === id);\n if (idx === -1) return [...list, { id, value, disabled }];\n const copy = list.slice();\n copy[idx] = { id, value, disabled };\n return copy;\n });\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.unregisterOption(id);\n ctrl.registerOption({ id, value, disabled, text });\n }\n\n unregisterOption(id: string): void {\n this.options.update((list) => list.filter((x) => x.id !== id));\n this.idToElement.delete(id);\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.unregisterOption(id);\n\n this.syncActiveFromController();\n\n if (!this.preserveValueOnUnregister) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n }\n\n updateOptionDisabled(id: string, disabled: boolean): void {\n let exists = false;\n\n this.options.update((list) =>\n list.map((o) => {\n if (o.id !== id) return o;\n exists = true;\n return { ...o, disabled };\n }),\n );\n\n if (!exists) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.setOptionDisabled(id, disabled);\n this.syncActiveFromController();\n }\n\n // ----------------------------------------------------\n // Events\n // ----------------------------------------------------\n\n @HostListener('keydown', ['$event'])\n handleKeydown(event: KeyboardEvent) {\n if (this.disabled()) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n this.syncDomOrderToController();\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n // ✅ Typeahead (optional)\n if (\n this.typeahead() &&\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n const moved = ctrl.typeahead(event.key);\n if (moved) {\n this.syncActiveFromController();\n event.preventDefault();\n return;\n }\n }\n\n const action = ctrl.handleKeyDown(event);\n this.syncActiveFromController();\n\n if (action?.preventDefault) {\n event.preventDefault();\n }\n\n if (this.shouldSyncValueFromAction(action)) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n }\n\n @HostListener('focusin')\n handleFocusIn() {\n if (this.disabled()) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n if (ctrl.getActiveId() !== null) {\n this.syncActiveFromController();\n return;\n }\n\n ctrl.handleKeyDown({ key: 'Home' });\n this.syncActiveFromController();\n }\n\n @HostListener('focusout', ['$event'])\n handleFocusOut(event: FocusEvent) {\n const nextTarget = event.relatedTarget;\n if (nextTarget instanceof Node && this.el.nativeElement.contains(nextTarget)) {\n return;\n }\n\n const ctrl = this.controller();\n if (!ctrl) return;\n if (ctrl.getActiveId() === null) return;\n\n ctrl.setActiveId(null);\n this.syncActiveFromController();\n }\n\n handleOptionClick(id: string, shiftKey?: boolean) {\n if (this.disabled()) return;\n\n this.syncDomOrderToController();\n\n const opt = this.options().find((o) => o.id === id);\n if (opt?.disabled) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n // Pointer selection should transfer keyboard focus to this listbox so\n // subsequent Arrow keys continue from the clicked list.\n this.el.nativeElement.focus();\n\n ctrl.handleClick(id, shiftKey);\n\n this.syncActiveFromController();\n this.syncExternalValueFromInternal(ctrl, true);\n }\n\n // ----------------------------------------------------\n // Selection sync\n // ----------------------------------------------------\n\n private syncExternalValueFromInternal(\n ctrl: ReturnType<typeof createListboxController<T>>,\n fromClick: boolean,\n ) {\n const selected = ctrl.getSelectedValues();\n\n if (this.multiple()) {\n if (!this.preserveValueOnUnregister) {\n this.value.set([...selected] as readonly T[]);\n return;\n }\n\n const opts = this.options();\n const current = this.value();\n const currentArr =\n current === null\n ? ([] as readonly T[])\n : Array.isArray(current)\n ? (current as readonly T[])\n : ([current as T] as const);\n\n const next: T[] = [];\n\n // Preserve hidden selections in their current order, and keep any currently\n // visible selections that remain selected after the interaction.\n for (const val of currentArr) {\n const isHidden = !opts.some((opt) => Object.is(opt.value, val));\n const isStillSelected = selected.some((entry) => Object.is(entry, val));\n\n if (isHidden || isStillSelected) {\n next.push(val);\n }\n }\n\n // Append newly selected visible values that were not already present.\n for (const val of selected) {\n const alreadyPresent = currentArr.some((entry) => Object.is(entry, val));\n if (!alreadyPresent) {\n next.push(val);\n }\n }\n\n this.value.set(next as readonly T[]);\n } else {\n const newVal = selected[0] ?? null;\n const current = this.value();\n this.value.set(newVal);\n if (fromClick && Object.is(newVal, current)) {\n this.value.set(null);\n this.value.set(newVal);\n }\n }\n }\n\n isSelected(id: string): boolean {\n const ctrl = this.controller();\n if (!ctrl) return false;\n \n // ✅ selection truth is IDs, not value equality\n return ctrl.getSelectedIds().includes(id);\n }\n\n isValueSelected(value: T): boolean {\n const selected = this.value();\n\n if (selected === null) return false;\n\n if (Array.isArray(selected)) {\n return selected.some((entry) => Object.is(entry, value));\n }\n\n return Object.is(selected, value);\n }\n\n isActive(id: string): boolean {\n return this.activeId() === id;\n }\n\n public getActiveId(): string | null {\n return this.activeId();\n }\n\n public ensureActive(pref: 'first' | 'last' = 'first'): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n if (ctrl.getActiveId() !== null) return;\n ctrl.handleKeyDown({ key: pref === 'last' ? 'End' : 'Home' });\n this.syncActiveFromController();\n }\n\n public handleKeyFromCombobox(key: string, shiftKey?: boolean): boolean {\n this.syncDomOrderToController();\n\n const ctrl = this.controller();\n if (!ctrl) return false;\n const action = ctrl.handleKeyDown({ key, shiftKey } as any);\n this.syncActiveFromController();\n if (this.shouldSyncValueFromAction(action)) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n return !!action;\n }\n\n public typeaheadFromCombobox(key: string): boolean {\n const ctrl = this.controller();\n if (!ctrl) return false;\n const moved = ctrl.typeahead(key);\n if (moved) this.syncActiveFromController();\n return moved;\n }\n\n public setActiveId(id: string | null): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n ctrl.setActiveId(id);\n this.syncActiveFromController();\n }\n\n public getActiveValue(): T | undefined {\n const active = this.activeId();\n if (!active) return undefined;\n const opt = this.options().find((o) => o.id === active);\n return opt?.value;\n }\n}\n"]}
1
+ {"version":3,"file":"listbox.directive.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/form/listbox/listbox.directive.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,UAAU,EACV,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,MAAM,EACN,KAAK,EACL,KAAK,EACL,MAAM,EACN,SAAS,GACV,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EACL,WAAW,EACX,0BAA0B,EAC1B,wCAAwC,GACzC,MAAM,UAAU,CAAC;;AAQlB,MAAM,OAAO,mBAAmB;IACb,cAAc,GAAG,MAAM,CAAC,0BAA0B,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,yBAAyB,GACxC,MAAM,CAAC,wCAAwC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC;IACvE,aAAa,GAAG,KAAK,CAAU,KAAK,0DAAI,KAAK,EAAE,UAAU,GAAG,CAAC;IAC7D,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,aAAa,EAAE,oDAAC,CAAC;IAEhF,WAAW,GAAG,KAAK,CAA4B,UAAU,uDAAC,CAAC;IAC3D,SAAS,GAAG,KAAK,CAAgB,KAAK,qDAAC,CAAC;IACxC,QAAQ,GAAG,KAAK,CAAU,KAAK,oDAAC,CAAC;IACjC,IAAI,GAAG,KAAK,CAAU,IAAI,gDAAC,CAAC;IAE5B;;;;OAIG;IACH,SAAS,GAAG,KAAK,CAAU,IAAI,qDAAC,CAAC;IAExB,KAAK,GAAG,KAAK,CAAkB,IAAI,iDAAC,CAAC;IAE7B,EAAE,GAAG,MAAM,CAAC,CAAA,UAAuB,CAAA,CAAC,CAAC;IAE9C,WAAW,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC7C,OAAO,GAAG,MAAM,CAAgD,EAAE,mDAAC,CAAC;IACpE,UAAU,GAAG,MAAM,CAAuD,IAAI,sDAAC,CAAC;IAChF,QAAQ,GAAG,MAAM,CAAgB,IAAI,oDAAC,CAAC;IAE/C,uDAAuD;IACvD,gBAAgB;IAChB,uDAAuD;IAGvD,IAAI,GAAG,SAAS,CAAC;IAEjB,IACI,SAAS;QACX,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAED,IACI,YAAY;QACd,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAED,IACI,gBAAgB;QAClB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,uDAAuD;IACvD,cAAc;IACd,uDAAuD;IAEvD;QACE,MAAM,MAAM,GAAG,eAAe,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAEpE,6BAA6B;QAC7B,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,IAAI,GAAG,uBAAuB,CAAI;gBACtC,MAAM;gBACN,aAAa,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;gBACtD,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;gBAC/B,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;gBAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;gBACzB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;aAClB,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE1B,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;gBAC1B,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,6BAA6B;QAC7B,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAE9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO;YACT,CAAC;YAED,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,QAAQ,KAAK,IAAI;oBAAE,OAAO;gBAE9B,MAAM,CAAC,GAAG,QAAa,CAAC;gBACxB,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;gBAE5C,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;oBAC3C,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;oBACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACvB,CAAC;gBACD,OAAO;YACT,CAAC;YAED,IAAI,QAAQ,KAAK,IAAI;gBAAE,OAAO;YAE9B,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACjC,CAAC,CAAE,QAAyB;gBAC5B,CAAC,CAAE,CAAC,QAAa,CAAkB,CAAC;YAEtC,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;gBAChC,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;gBAE5C,IAAI,CAAC,GAAG,EAAE,CAAC;oBACT,OAAO,IAAI,CAAC,yBAAyB,CAAC;gBACxC,CAAC;gBAED,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YACvB,CAAC,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;gBACnC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAwB,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,yCAAyC;QACzC,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,IAAI;gBAAE,OAAO;YAElB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAE9B,MAAM,KAAK,GAAG,CAAC,CAAkB,EAAY,EAAE;gBAC7C,IAAI,CAAC,KAAK,IAAI;oBAAE,OAAO,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAkB,CAAC,CAAC,CAAE,CAAC,CAAM,CAAW,CAAC;gBAEzE,MAAM,GAAG,GAAa,EAAE,CAAC;gBACzB,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;oBACtB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;oBACtD,IAAI,CAAC,GAAG;wBAAE,SAAS;oBACnB,IAAI,GAAG,CAAC,QAAQ;wBAAE,SAAS;oBAC3B,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACnB,CAAC;gBACD,OAAO,GAAG,CAAC;YACb,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;YAEhC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,OAAO;YACT,CAAC;YAED,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,6BAA6B;QAC7B,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC,EAAE;gBAAE,OAAO;YAEhB,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpC,IAAI,CAAC,EAAE;gBAAE,OAAO;YAEhB,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,uDAAuD;IACvD,UAAU;IACV,uDAAuD;IAE/C,iBAAiB,CACvB,KAAQ,EACR,IAAgD;QAEhD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IACrD,CAAC;IAEO,iBAAiB,CACvB,KAAQ,EACR,IAAgD;QAEhD,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAChD,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;IAChC,CAAC;IAEO,wBAAwB;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC;QACnC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAC1B,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAC5B,CAAC;QAEnB,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEvD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAEO,wBAAwB;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACxC,CAAC;IAEO,yBAAyB,CAAC,MAAsC;QACtE,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,IAAI,MAAM,CAAC,eAAe;YAAE,OAAO,IAAI,CAAC;QAExC,OAAO,CACL,MAAM,CAAC,IAAI,KAAK,eAAe;YAC/B,MAAM,CAAC,IAAI,KAAK,eAAe;YAC/B,MAAM,CAAC,IAAI,KAAK,YAAY,CAC7B,CAAC;IACJ,CAAC;IAED,uDAAuD;IACvD,sBAAsB;IACtB,uDAAuD;IAEvD,cAAc,CACZ,EAAU,EACV,KAAQ,EACR,QAAiB,EACjB,IAAa,EACb,EAAgB;QAEhB,IAAI,EAAE,EAAE,CAAC;YACP,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/C,IAAI,GAAG,KAAK,CAAC,CAAC;gBAAE,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,gBAAgB,CAAC,EAAU;QACzB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAE5B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAE1B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACpC,IAAI,CAAC,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,oBAAoB,CAAC,EAAU,EAAE,QAAiB;QAChD,IAAI,MAAM,GAAG,KAAK,CAAC;QAEnB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACb,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC1B,MAAM,GAAG,IAAI,CAAC;YACd,OAAO,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CACH,CAAC;QAEF,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAED,uDAAuD;IACvD,SAAS;IACT,uDAAuD;IAGvD,aAAa,CAAC,KAAoB;QAChC,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpB,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,yBAAyB;QACzB,IACE,IAAI,CAAC,SAAS,EAAE;YAChB,KAAK,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;YACtB,CAAC,KAAK,CAAC,OAAO;YACd,CAAC,KAAK,CAAC,OAAO;YACd,CAAC,KAAK,CAAC,MAAM,EACb,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAChC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,IAAI,MAAM,EAAE,cAAc,EAAE,CAAC;YAC3B,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,CAAC;QAED,IAAI,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAGD,aAAa;QACX,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE,OAAO;QAE5B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAChC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAGD,cAAc,CAAC,KAAiB;QAC9B,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC;QACvC,IAAI,UAAU,YAAY,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7E,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI;YAAE,OAAO;QAExC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAED,iBAAiB,CAAC,EAAU,EAAE,QAAkB;QAC9C,IAAI,IAAI,CAAC,QAAQ,EAAE;YAAE,OAAO;QAE5B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,IAAI,GAAG,EAAE,QAAQ;YAAE,OAAO;QAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,sEAAsE;QACtE,wDAAwD;QACxD,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAE9B,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAE/B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,CAAC,6BAA6B,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,uDAAuD;IACvD,iBAAiB;IACjB,uDAAuD;IAE/C,6BAA6B,CACnC,IAAmD,EACnD,SAAkB;QAElB,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAE1C,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC;gBACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAiB,CAAC,CAAC;gBAC9C,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC7B,MAAM,UAAU,GACd,OAAO,KAAK,IAAI;gBACd,CAAC,CAAE,EAAmB;gBACtB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;oBACtB,CAAC,CAAE,OAAwB;oBAC3B,CAAC,CAAE,CAAC,OAAY,CAAW,CAAC;YAElC,MAAM,IAAI,GAAQ,EAAE,CAAC;YAErB,4EAA4E;YAC5E,iEAAiE;YACjE,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAC7B,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;gBAChE,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;gBAExE,IAAI,QAAQ,IAAI,eAAe,EAAE,CAAC;oBAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACjB,CAAC;YACH,CAAC;YAED,sEAAsE;YACtE,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;gBACzE,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACjB,CAAC;YACH,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAoB,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YACnC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACvB,IAAI,SAAS,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACrB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,UAAU,CAAC,EAAU;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAExB,+CAA+C;QAC/C,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,eAAe,CAAC,KAAQ;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAE9B,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAEpC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,QAAQ,CAAC,EAAU;QACjB,OAAO,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;IAChC,CAAC;IAEM,WAAW;QAChB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAEM,YAAY,CAAC,OAAyB,OAAO;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI;YAAE,OAAO;QACxC,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAEM,qBAAqB,CAAC,GAAW,EAAE,QAAkB;QAC1D,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAS,CAAC,CAAC;QAC5D,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAEM,qBAAqB,CAAC,GAAW;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,KAAK;YAAE,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAC;IACf,CAAC;IAEM,WAAW,CAAC,EAAiB;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACrB,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAEM,cAAc;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QACxD,OAAO,GAAG,EAAE,KAAK,CAAC;IACpB,CAAC;uGA7fU,mBAAmB;2FAAnB,mBAAmB,izCAFnB,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC;;2FAE5D,mBAAmB;kBAJ/B,SAAS;mBAAC;oBACT,QAAQ,EAAE,cAAc;oBACxB,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,qBAAqB,EAAE,CAAC;iBACxE;;sBAiCE,WAAW;uBAAC,WAAW;;sBAGvB,WAAW;uBAAC,2BAA2B;;sBAKvC,WAAW;uBAAC,oBAAoB;;sBAKhC,WAAW;uBAAC,4BAA4B;;sBAoPxC,YAAY;uBAAC,SAAS,EAAE,CAAC,QAAQ,CAAC;;sBAyClC,YAAY;uBAAC,SAAS;;sBAgBtB,YAAY;uBAAC,UAAU,EAAE,CAAC,QAAQ,CAAC","sourcesContent":["import {\n Directive,\n ElementRef,\n HostBinding,\n HostListener,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { createListboxController } from '@tailng-ui/cdk';\nimport type { TngListNavigationAction } from '@tailng-ui/cdk';\nimport {\n TNG_LISTBOX,\n TNG_LISTBOX_FORCE_MULTIPLE,\n TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER,\n} from './tokens';\n\nexport type ListboxValue<T> = T | readonly T[] | null;\n\n@Directive({\n selector: '[tngListbox]',\n providers: [{ provide: TNG_LISTBOX, useExisting: TngListboxDirective }],\n})\nexport class TngListboxDirective<T> {\n private readonly _forceMultiple = inject(TNG_LISTBOX_FORCE_MULTIPLE, { optional: true });\n private readonly preserveValueOnUnregister =\n inject(TNG_LISTBOX_PRESERVE_VALUE_ON_UNREGISTER, { optional: true }) ?? false;\n readonly multipleInput = input<boolean>(false, { alias: 'multiple' });\n readonly multiple = computed(() => this._forceMultiple ?? this.multipleInput());\n\n orientation = input<'vertical' | 'horizontal'>('vertical');\n direction = input<'ltr' | 'rtl'>('ltr');\n disabled = input<boolean>(false);\n loop = input<boolean>(true);\n\n /**\n * Enable listbox typeahead (printable key moves active option by option text).\n * Default true for Select compatibility.\n * Autocomplete should set this to false (input owns typing/filtering).\n */\n typeahead = input<boolean>(true);\n\n readonly value = model<ListboxValue<T>>(null);\n\n private readonly el = inject(ElementRef<HTMLElement>);\n\n private idToElement = new Map<string, HTMLElement>();\n private options = signal<{ id: string; value: T; disabled: boolean }[]>([]);\n private controller = signal<ReturnType<typeof createListboxController<T>> | null>(null);\n private activeId = signal<string | null>(null);\n\n // ----------------------------------------------------\n // Host bindings\n // ----------------------------------------------------\n\n @HostBinding('attr.role')\n role = 'listbox';\n\n @HostBinding('attr.aria-multiselectable')\n get ariaMulti() {\n return this.multiple() ? 'true' : null;\n }\n\n @HostBinding('attr.aria-disabled')\n get ariaDisabled() {\n return this.disabled() ? 'true' : null;\n }\n\n @HostBinding('attr.aria-activedescendant')\n get activeDescendant() {\n return this.activeId();\n }\n\n // ----------------------------------------------------\n // Constructor\n // ----------------------------------------------------\n\n constructor() {\n const hostId = `tng-listbox-${Math.random().toString(36).slice(2)}`;\n\n // Controller creation effect\n effect(() => {\n const ctrl = createListboxController<T>({\n hostId,\n selectionMode: this.multiple() ? 'multiple' : 'single',\n orientation: this.orientation(),\n direction: this.direction(),\n disabled: this.disabled(),\n loop: this.loop(),\n });\n\n this.controller.set(ctrl);\n\n const opts = untracked(this.options);\n for (const option of opts) {\n ctrl.registerOption(option);\n }\n });\n\n // Controlled value sanitizer\n effect(() => {\n const isMulti = this.multiple();\n const opts = this.options();\n const external = this.value();\n\n if (opts.length === 0) {\n return;\n }\n\n if (!isMulti) {\n if (external === null) return;\n\n const v = external as T;\n const opt = this.findOptionByValue(v, opts);\n\n if (!opt && this.preserveValueOnUnregister) {\n return;\n }\n\n if (!opt || opt.disabled) {\n this.value.set(null);\n }\n return;\n }\n\n if (external === null) return;\n\n const arr = Array.isArray(external)\n ? (external as readonly T[])\n : ([external as T] as readonly T[]);\n\n const filtered = arr.filter((v) => {\n const opt = this.findOptionByValue(v, opts);\n\n if (!opt) {\n return this.preserveValueOnUnregister;\n }\n\n return !opt.disabled;\n });\n\n if (filtered.length !== arr.length) {\n this.value.set(filtered as readonly T[]);\n }\n });\n\n // External value -> controller selection\n effect(() => {\n const ctrl = this.controller();\n if (!ctrl) return;\n\n const opts = this.options();\n const external = this.value();\n\n const toIds = (v: ListboxValue<T>): string[] => {\n if (v === null) return [];\n const arr = Array.isArray(v) ? (v as readonly T[]) : ([v as T] as const);\n\n const ids: string[] = [];\n for (const val of arr) {\n const opt = opts.find((o) => Object.is(o.value, val));\n if (!opt) continue;\n if (opt.disabled) continue;\n ids.push(opt.id);\n }\n return ids;\n };\n\n const nextIds = toIds(external);\n\n if (nextIds.length === 0) {\n ctrl.clearSelection();\n return;\n }\n\n ctrl.setSelectedIds(nextIds);\n });\n\n // Scroll when active changes\n effect(() => {\n const id = this.activeId();\n if (!id) return;\n\n const el = this.idToElement.get(id);\n if (!el) return;\n\n el.scrollIntoView?.({ block: 'nearest' });\n });\n }\n\n // ----------------------------------------------------\n // Helpers\n // ----------------------------------------------------\n\n private findOptionByValue(\n value: T,\n opts: readonly { value: T; disabled: boolean }[],\n ) {\n return opts.find((o) => Object.is(o.value, value));\n }\n\n private isSelectableValue(\n value: T,\n opts: readonly { value: T; disabled: boolean }[],\n ): boolean {\n const opt = this.findOptionByValue(value, opts);\n return !!opt && !opt.disabled;\n }\n\n private syncDomOrderToController(): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n\n const root = this.el.nativeElement;\n const optionEls = Array.from(\n root.querySelectorAll('[role=\"option\"][id]'),\n ) as HTMLElement[];\n\n const ids = optionEls.map((x) => x.id).filter(Boolean);\n\n if (ids.length > 0) {\n ctrl.setItemOrder(ids);\n }\n }\n\n private syncActiveFromController(): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n this.activeId.set(ctrl.getActiveId());\n }\n\n private shouldSyncValueFromAction(action: TngListNavigationAction | null): boolean {\n if (!action) return false;\n if (action.extendSelection) return true;\n\n return (\n action.type === 'select-active' ||\n action.type === 'toggle-active' ||\n action.type === 'select-all'\n );\n }\n\n // ----------------------------------------------------\n // Option registration\n // ----------------------------------------------------\n\n registerOption(\n id: string,\n value: T,\n disabled: boolean,\n text?: string,\n el?: HTMLElement,\n ): void {\n if (el) {\n this.idToElement.set(id, el);\n }\n\n this.options.update((list) => {\n const idx = list.findIndex((x) => x.id === id);\n if (idx === -1) return [...list, { id, value, disabled }];\n const copy = list.slice();\n copy[idx] = { id, value, disabled };\n return copy;\n });\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.unregisterOption(id);\n ctrl.registerOption({ id, value, disabled, text });\n }\n\n unregisterOption(id: string): void {\n this.options.update((list) => list.filter((x) => x.id !== id));\n this.idToElement.delete(id);\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.unregisterOption(id);\n\n this.syncActiveFromController();\n\n if (!this.preserveValueOnUnregister) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n }\n\n updateOptionDisabled(id: string, disabled: boolean): void {\n let exists = false;\n\n this.options.update((list) =>\n list.map((o) => {\n if (o.id !== id) return o;\n exists = true;\n return { ...o, disabled };\n }),\n );\n\n if (!exists) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n ctrl.setOptionDisabled(id, disabled);\n this.syncActiveFromController();\n }\n\n // ----------------------------------------------------\n // Events\n // ----------------------------------------------------\n\n @HostListener('keydown', ['$event'])\n handleKeydown(event: KeyboardEvent) {\n if (this.disabled()) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n this.syncDomOrderToController();\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n // ✅ Typeahead (optional)\n if (\n this.typeahead() &&\n event.key.length === 1 &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n const moved = ctrl.typeahead(event.key);\n if (moved) {\n this.syncActiveFromController();\n event.preventDefault();\n return;\n }\n }\n\n const action = ctrl.handleKeyDown(event);\n this.syncActiveFromController();\n\n if (action?.preventDefault) {\n event.preventDefault();\n }\n\n if (this.shouldSyncValueFromAction(action)) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n }\n\n @HostListener('focusin')\n handleFocusIn() {\n if (this.disabled()) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n if (ctrl.getActiveId() !== null) {\n this.syncActiveFromController();\n return;\n }\n\n ctrl.handleKeyDown({ key: 'Home' });\n this.syncActiveFromController();\n }\n\n @HostListener('focusout', ['$event'])\n handleFocusOut(event: FocusEvent) {\n const nextTarget = event.relatedTarget;\n if (nextTarget instanceof Node && this.el.nativeElement.contains(nextTarget)) {\n return;\n }\n\n const ctrl = this.controller();\n if (!ctrl) return;\n if (ctrl.getActiveId() === null) return;\n\n ctrl.setActiveId(null);\n this.syncActiveFromController();\n }\n\n handleOptionClick(id: string, shiftKey?: boolean) {\n if (this.disabled()) return;\n\n this.syncDomOrderToController();\n\n const opt = this.options().find((o) => o.id === id);\n if (opt?.disabled) return;\n\n const ctrl = this.controller();\n if (!ctrl) return;\n\n // Pointer selection should transfer keyboard focus to this listbox so\n // subsequent Arrow keys continue from the clicked list.\n this.el.nativeElement.focus();\n\n ctrl.handleClick(id, shiftKey);\n\n this.syncActiveFromController();\n this.syncExternalValueFromInternal(ctrl, true);\n }\n\n // ----------------------------------------------------\n // Selection sync\n // ----------------------------------------------------\n\n private syncExternalValueFromInternal(\n ctrl: ReturnType<typeof createListboxController<T>>,\n fromClick: boolean,\n ) {\n const selected = ctrl.getSelectedValues();\n\n if (this.multiple()) {\n if (!this.preserveValueOnUnregister) {\n this.value.set([...selected] as readonly T[]);\n return;\n }\n\n const opts = this.options();\n const current = this.value();\n const currentArr =\n current === null\n ? ([] as readonly T[])\n : Array.isArray(current)\n ? (current as readonly T[])\n : ([current as T] as const);\n\n const next: T[] = [];\n\n // Preserve hidden selections in their current order, and keep any currently\n // visible selections that remain selected after the interaction.\n for (const val of currentArr) {\n const isHidden = !opts.some((opt) => Object.is(opt.value, val));\n const isStillSelected = selected.some((entry) => Object.is(entry, val));\n\n if (isHidden || isStillSelected) {\n next.push(val);\n }\n }\n\n // Append newly selected visible values that were not already present.\n for (const val of selected) {\n const alreadyPresent = currentArr.some((entry) => Object.is(entry, val));\n if (!alreadyPresent) {\n next.push(val);\n }\n }\n\n this.value.set(next as readonly T[]);\n } else {\n const newVal = selected[0] ?? null;\n const current = this.value();\n this.value.set(newVal);\n if (fromClick && Object.is(newVal, current)) {\n this.value.set(null);\n this.value.set(newVal);\n }\n }\n }\n\n isSelected(id: string): boolean {\n const ctrl = this.controller();\n if (!ctrl) return false;\n \n // ✅ selection truth is IDs, not value equality\n return ctrl.getSelectedIds().includes(id);\n }\n\n isValueSelected(value: T): boolean {\n const selected = this.value();\n\n if (selected === null) return false;\n\n if (Array.isArray(selected)) {\n return selected.some((entry) => Object.is(entry, value));\n }\n\n return Object.is(selected, value);\n }\n\n isActive(id: string): boolean {\n return this.activeId() === id;\n }\n\n public getActiveId(): string | null {\n return this.activeId();\n }\n\n public ensureActive(pref: 'first' | 'last' = 'first'): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n if (ctrl.getActiveId() !== null) return;\n ctrl.handleKeyDown({ key: pref === 'last' ? 'End' : 'Home' });\n this.syncActiveFromController();\n }\n\n public handleKeyFromCombobox(key: string, shiftKey?: boolean): boolean {\n this.syncDomOrderToController();\n\n const ctrl = this.controller();\n if (!ctrl) return false;\n const action = ctrl.handleKeyDown({ key, shiftKey } as any);\n this.syncActiveFromController();\n if (this.shouldSyncValueFromAction(action)) {\n this.syncExternalValueFromInternal(ctrl, false);\n }\n return !!action;\n }\n\n public typeaheadFromCombobox(key: string): boolean {\n const ctrl = this.controller();\n if (!ctrl) return false;\n const moved = ctrl.typeahead(key);\n if (moved) this.syncActiveFromController();\n return moved;\n }\n\n public setActiveId(id: string | null): void {\n const ctrl = this.controller();\n if (!ctrl) return;\n ctrl.setActiveId(id);\n this.syncActiveFromController();\n }\n\n public getActiveValue(): T | undefined {\n const active = this.activeId();\n if (!active) return undefined;\n const opt = this.options().find((o) => o.id === active);\n return opt?.value;\n }\n}\n"]}