@visa/nova-angular
Version:
Visa Product Design System Nova Angular library
817 lines • 109 kB
JavaScript
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { ContentChild, ContentChildren, Directive, EventEmitter, forwardRef, HostBinding, HostListener, Input, Output, QueryList, Renderer2 } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { AppReadyService } from '../_utilities/services/app-stable-check.service';
import { UUIDService } from '../_utilities/services/uuid.service';
import { FloatingUIContainer } from '../floating-ui-container/floating-ui-container.directive';
import { InputContainerComponent } from '../input-container/input-container.component';
import { InputDirective } from '../input/input.directive';
import { LabelDirective } from '../label/label.directive';
import { ListboxContainerDirective } from '../listbox-container/listbox-container.directive';
import { ListboxDirective } from '../listbox/listbox.directive';
import { ListboxService } from '../listbox/listbox.service';
import { BACKSPACE_KEY, DOWN_ARROW_KEY, ENTER_KEY, LEFT_ARROW_KEY, RIGHT_ARROW_KEY, TAB_KEY, UP_ARROW_KEY } from '../nova-lib.constants';
import { NovaLibService } from '../nova-lib.service';
import { ComboboxFilterType } from './combobox.constants';
import { ButtonDirective } from '../button/button.directive';
import { ChipDirective } from '../chip/chip.directive';
import * as i0 from "@angular/core";
import * as i1 from "../nova-lib.service";
import * as i2 from "../listbox/listbox.service";
import * as i3 from "../_utilities/services/app-stable-check.service";
import * as i4 from "../_utilities/services/uuid.service";
import * as i5 from "../floating-ui-container/floating-ui-container.directive";
var STATE;
(function (STATE) {
STATE["READONLY"] = "readonly";
STATE["DISABLED"] = "disabled";
STATE["INVALID"] = "invalid";
STATE["REQUIRED"] = "required";
})(STATE || (STATE = {}));
export class ComboboxDirective {
/**
* Provides custom class(es) for custom styling.
* @default .v-combobox
*/
get class() {
return [this._class, 'v-combobox'].join(' ');
}
set class(value) {
this._class = value;
}
get hostClass() {
return this.class;
}
/**
* Removes appended screenreader readonly text when true. <br>
* By default (when <code>removeReadonlyText="false"</code>), if a combobox is readonly, a span element with text '(readonly)' will be appended to the label element for screenreader support.
* @default false
*/
get removeReadonlyText() {
return this._removeReadonlyText;
}
set removeReadonlyText(value) {
this._removeReadonlyText = coerceBooleanProperty(value);
}
/**
* Temporary prop to opt into new **multiselect** behavior. <br>
* Will be deprecated and defaulted to in the next breaking change release.
*/
get EXPERIMENTAL_ADA_OPT_IN() {
return this._EXPERIMENTAL_ADA_OPT_IN;
}
set EXPERIMENTAL_ADA_OPT_IN(value) {
this._EXPERIMENTAL_ADA_OPT_IN = coerceBooleanProperty(value);
}
/**
* Sets component as readonly when true.
* @default false
*/
get readonly() {
return this._readonly;
}
set readonly(value) {
this._readonly = coerceBooleanProperty(value);
if (!this.removeReadonlyText)
this.appendReadonlyText();
this.updateChildrenStates(STATE.READONLY);
}
/**
* Sets component as disabled when true.
* @default false
*/
get disabled() {
return this._disabled;
}
set disabled(value) {
this._disabled = coerceBooleanProperty(value);
this.updateChildrenStates(STATE.DISABLED);
}
get hostDisabled() {
return this.disabled ? 'disabled' : null;
}
/** Fires when a formControl's disabled state updates */
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
/**
* Marks component as invalid when true.
* @default false
*/
get invalid() {
return this._invalid;
}
set invalid(value) {
this._invalid = coerceBooleanProperty(value);
this.updateChildrenStates(STATE.INVALID);
}
get ariaInvalid() {
return this.invalid;
}
/**
* Marks component as required when true.
* @default false
*/
get required() {
return this._required;
}
set required(value) {
this._required = coerceBooleanProperty(value);
this.updateChildrenStates(STATE.REQUIRED);
}
/**
* Value of combobox.
*/
get value() {
return this._value;
}
set value(value) {
this.updateValue(value);
}
// keep val for backwards compatibility
get val() {
return this._value;
}
set val(value) {
this.updateValue(value);
}
updateValue(value) {
this._value = value;
if (this.input && this.listbox) {
if (value &&
!this._fromInput &&
((value['label'] && this.input.value !== value['label']) ||
(value['value'] && this.listbox.value !== value['value']))) {
const selectIndex = this.getList()?.findIndex((item) => item.value === value['value']);
if (selectIndex != -1) {
this.selectItem(selectIndex);
}
else {
// deselect also reset aria active descendant
if (this._activeIndex) {
this.novaLibService.deselectItem(this.getList(), this._activeIndex, 'active');
this._activeIndex = null;
if (this.input)
this.input.ariaActiveDescendant = null;
if (this.listbox)
this.listbox.ariaActiveDescendant.set(null);
}
}
}
else if (!value) {
this.clearCombobox();
}
}
this.onChange(value);
}
constructor(novaLibService, listboxService, appReadyService, renderer, UUIDService, floatingContainer) {
this.novaLibService = novaLibService;
this.listboxService = listboxService;
this.appReadyService = appReadyService;
this.renderer = renderer;
this.UUIDService = UUIDService;
this.floatingContainer = floatingContainer;
this._highlightedIndex = null;
this._activeIndex = null;
this._fromInput = false;
this._inputFocused = false;
this._class = '';
this._removeReadonlyText = false;
this._EXPERIMENTAL_ADA_OPT_IN = false;
this._readonly = false;
this._disabled = false;
this._invalid = false;
this._required = false;
this._value = null;
/**
* Emits value of selected item(s).
*/
this.itemSelected = new EventEmitter();
/**
* Emitted when a listbox item is selected, when an input value is entered, and when the combobox is reset. <br />
* Subscribe to provide your own filter function when this event is emitted. <br />
* Emits { type: 'selection' | 'input' | 'reset'; listbox: string; input: string } where type is the type of filter event, listbox is the value of the selected item(s), and input is the value of the input.
*/
this.filter = new EventEmitter();
/**
* Emits the filtered array of ListboxItemComponents when the list is filtered by ComboboxService.
*/
this.filteredListEmitter = new EventEmitter();
this.onChange = (_) => { };
this.onTouched = (_) => { };
}
handleFocus(event) {
this.onTouched(event);
}
ngOnInit() {
if (this.floatingContainer) {
this.floatingContainer._isCombobox = true;
if (!this.floatingContainer.eventsArray) {
this.floatingContainer.eventsArray = [];
}
}
}
ngAfterContentInit() {
if (this.input) {
this.setUpInput();
}
if (this.listbox) {
if (!this.listbox.multiselect) {
this.listbox.value = '';
}
this.initialListItems = this.listbox.listItems.toArray();
this.currentListItems = this.listbox.listItems;
this.setUpListItems();
this.listbox.listItems.changes.subscribe(() => {
if (!this.listbox.multiselect) {
// remove previous subscription
this.listboxSubscription.unsubscribe();
this.setUpListItems();
}
});
}
if (this.inputContainer?.buttons.length > 0 && this.floatingContainer) {
// last button should be toggle button
this.inputContainer.buttons.last._inCombobox = true;
this.inputContainer.buttons.last.clicked.subscribe(() => {
this.input?.el.nativeElement.focus();
this.floatingContainer?.floatingUIService.toggleFloatingUI();
});
}
if (this.floatingContainer) {
this.setUpFloatingContainer();
}
if (this.chips) {
this.chips.changes.subscribe(() => {
if (this.chips.length === 0 && this.appReadyService.isBrowserAndDomAvailable()) {
this.input?.el.nativeElement.focus();
}
});
}
this.setState();
}
setUpInput() {
this.input._inCombobox = true;
this.input.role = this.input.role ? this.input.role : 'combobox';
this.input.inputEvent.subscribe((val) => {
this.filter.emit({ type: ComboboxFilterType.INPUT, listbox: this.listbox?.value || [], input: this.input.value });
this._fromInput = true;
// if the listbox has a value (probably only multiselect..), retain that value
if ((!this.listbox?.multiselect && this.listbox.value) ||
(this.listbox?.multiselect && Array.isArray(this.listbox.value) && this.listbox.value.length > 0)) {
this.writeValue({ label: this.input.value, value: this.listbox.value });
}
else {
//otherwise pass the input value to the value
this.writeValue({ value: this.input.value });
}
this.floatingContainer?.floatingUIService.showfloatingUI();
this._fromInput = false;
});
if (this.listboxContainer) {
this.input.ariaOwns = this.listboxContainer.id;
}
if (this.label) {
this.label.for = this.input.id;
}
this.input.focused.subscribe(() => {
this._inputFocused = true;
});
this.input.blurred.subscribe(() => {
this._inputFocused = false;
});
this.input.communicateState.subscribe((state) => {
if (this.readonly !== state.readonly) {
this.readonly = state.readonly;
}
if (this.disabled !== state.disabled) {
this.disabled = state.disabled;
}
if (this.invalid !== state.invalid) {
this.invalid = state.invalid;
}
if (this.required !== state.required) {
this.required = state.required;
}
});
}
setUpListItems() {
this.listbox._inCombobox = true;
this.listboxSubscription = this.listbox.valueUpdated.subscribe((val) => {
if (!this.listbox.multiselect && !val)
return;
// wait for app to be ready before accessing list item native elements
if (this.appReadyService.isBrowserAndDomAvailable()) {
if (this.listbox?.multiselect && Array.isArray(val) && val.length > 0) {
if (this.input.value)
this.input.value = ''; // make optional?
}
else if (!this.listbox?.multiselect && val) {
const index = this.listbox.listItems.toArray().findIndex((item) => item.value === val);
this.input.value = this.getListItem(index)?.el.nativeElement.innerText.trim();
}
this.writeValue({ label: this.input.value || '', value: this.listbox.value });
this.filter.emit({
type: ComboboxFilterType.SELECTION,
listbox: this.listbox.value,
input: this.input.value || ''
});
// @TODO: remove first if statement in next major release
if (this.listbox.multiselect && Array.isArray(this.listbox.value) && !this.EXPERIMENTAL_ADA_OPT_IN) {
return; // handled in docs
}
else if (this.listbox?.multiselect && this.input?.value) {
// if a multiselect still has a value, that means no item is selected and the user is typing; return.
return;
}
else {
this.itemSelected.emit(this.listbox.value);
}
}
});
this.listbox.listItems.forEach((item, index) => {
item.clicked.subscribe(() => {
if (this.appReadyService.isBrowserAndDomAvailable()) {
// wait for app to be ready before accessing input native elements
this.input?.el.nativeElement.focus();
}
});
item.itemChanged.subscribe((isSelected) => {
// any time an item is clicked, entered, or programmatically selected, the below will set the value of the combobox
if (!this.listbox?.multiselect && isSelected && this.getListItem(index)) {
this.novaLibService.deselectItems(this.getList(), index, 'highlighted');
this._activeIndex = index;
}
});
});
this.setInitialValue();
if (this._highlightedIndex !== null)
this.highlightIndex(this._highlightedIndex);
}
setUpFloatingContainer() {
if (this.input)
this.input.ariaExpanded = this.floatingContainer.isShown;
this.floatingContainer.floatingUIService.isShownEmitter.subscribe((isShown) => {
if (this.input)
this.input.ariaExpanded = isShown;
if (!isShown) {
// when menu is closed, unhighlight all items
if (this._highlightedIndex !== null)
this._lastHighlightedOnClose = this._highlightedIndex;
this._highlightedIndex = null;
this.listbox?.listItems.forEach((item) => {
item.highlighted = false;
});
// remove aria-controls from input and reset aria-activeDescendant to null or active item id
if (this.input) {
this.input.ariaControls = null;
const listItem = this.getListItem(this._activeIndex);
if (this._activeIndex === null) {
if (this.input)
this.input.ariaActiveDescendant = null;
if (this.listbox)
this.listbox.ariaActiveDescendant.set(null);
}
else if (this.listbox && listItem) {
this.input.ariaActiveDescendant = listItem.id;
this.listbox.ariaActiveDescendant.set(listItem.id);
}
}
}
else {
if (this.input)
this.input.ariaControls = this.listbox?.id;
}
});
}
setInitialValue() {
let selectedIndex = -1;
// note that initial value precedence is combobox initial value, input initial value, and then listbox
if (this.value) {
// initial value given to combobox directly
if (this.listbox) {
if (this.listbox.multiselect) {
if (Array.isArray(this.value['value'])) {
const selectedItems = this.value['value'].filter((val) => {
return this.getList()?.some((item) => item.value === val);
});
this.listbox.value = selectedItems;
}
else {
// allow a non-array value (single value) to propagate the multiselect
selectedIndex = this.getList()?.findIndex((item) => item.value === this.value['value']);
if (selectedIndex > -1) {
this.selectItem(selectedIndex);
}
}
if (this.value['label']) {
this.input.value = this.value['label'];
}
}
else {
selectedIndex = this.getList()?.findIndex((item) => item.value === this.value['value']); // check is within if statement?
// allow input to still have initial value even if it doesn't match a listbox item
if (selectedIndex < 0 && this.value['label']) {
this.input.value = this.value['label'];
}
}
}
}
else if (this.input?.value) {
// initial value given to input
selectedIndex = this.findListItem(this.input.value);
}
else if (this.listbox?.value) {
if (this.listbox.multiselect && Array.isArray(this.listbox.value) && this.listbox.value.length > 0) {
// if value is an array, select all items that match the value
return;
}
else {
// initial value given to listbox
selectedIndex = this.getList()?.findIndex((item) => item.active);
}
}
// if the item is already selected, no need to select it again
if (selectedIndex > -1 && !this.getListItem(selectedIndex)?.active) {
this.selectItem(selectedIndex);
}
}
setState() {
if (this.input && this.listbox) {
// set initial state of input and listbox based on what's passed to combobox
// if input or listbox is readonly or disabled, set combobox to readonly or disabled
if (this.readonly) {
this.input.readonly = true;
}
else if (this.input.readonly) {
this.readonly = true;
}
if (this.disabled) {
this.input.disabled = true;
this.listbox.disabled = true;
}
else if (this.input.disabled) {
this.disabled = true;
}
else if (this.listbox.disabled) {
this.disabled = true;
}
if (this.invalid) {
this.input.invalid = true;
this.listbox.invalid = true;
}
else if (this.input.invalid) {
this.invalid = true;
}
else if (this.listbox.invalid) {
this.invalid = true;
}
if (this.required) {
this.input.required = true;
this.listbox.required = true;
}
else if (this.input.required) {
this.required = true;
}
else if (this.listbox.required) {
this.required = true;
}
}
}
hostKeyDown(event) {
// don't perform any keboard functions if readonly or disabled
// also don't open menu if no floating container exists
if (this.input.readonly || this.input.disabled || !this._inputFocused || !this.floatingContainer) {
return;
}
if (event.key === DOWN_ARROW_KEY || event.key === RIGHT_ARROW_KEY) {
// highlight next item and show menu
if (event.key === DOWN_ARROW_KEY)
event.preventDefault(); // allow right arrow to navigate through input
this.highlightNextPrevItem('next');
if (!this.floatingContainer?.isShown)
this.floatingContainer.floatingUIService.showfloatingUI();
if (this._highlightedIndex !== null && this.listbox)
this.listboxService.scrollItemIntoView(this.listbox, this._highlightedIndex);
}
else if (event.key === UP_ARROW_KEY || event.key === LEFT_ARROW_KEY) {
// highlight previous item and show menu
if (event.key === UP_ARROW_KEY)
event.preventDefault(); // allow left arrow to navigate through input
this.highlightNextPrevItem('prev');
if (!this.floatingContainer?.isShown)
this.floatingContainer.floatingUIService.showfloatingUI();
if (this._highlightedIndex !== null && this.listbox) {
this.listboxService.scrollItemIntoView(this.listbox, this._highlightedIndex);
}
}
else if (event.key === ENTER_KEY) {
if (this.floatingContainer?.isShown) {
event.preventDefault(); // prevent form submission if enter is triggered on list item
}
// select currently highlighted item
if (this._highlightedIndex !== null) {
this.selectItem(this._highlightedIndex);
this.getListItem(this._highlightedIndex)?.clicked.emit(); // emit click event (closes item when close on click is called)
}
}
else if (event.key === TAB_KEY && event.shiftKey) {
if (this.listbox?.multiselect && this.chips.length > 0) {
// if shift+tab is pressed and there is a chip (aka a value), close the menu
// @note, possibly make this optional by providing an opt-out input
this._highlightedIndex = null;
this.floatingContainer.floatingUIService.hidefloatingUI();
}
}
else if (event.key === BACKSPACE_KEY) {
if (this.listbox?.multiselect && !this.input.value && this.chips.length > 0) {
// remove last chip if backspace is pressed on empty input and there are chips (aka a value)
// I know there's a better way to do this but it's not working??
const lastValue = this.value.value[this.value.value.length - 1];
const lastItem = this.listbox?.listItems?.find((item) => item.value === lastValue);
lastItem?.selectItem();
}
}
}
hostKeyup(event) {
if (event.key === BACKSPACE_KEY && !this.listbox?.multiselect) {
// remove highlight for any backspace event?
if (this.input.value === '' || !this.input.value) {
if (this.value)
this.value = '';
}
const selectedItems = this.getList()?.filter((item) => item.active);
if (selectedItems) {
selectedItems.forEach((item) => (item.active = false));
if (this.listbox)
this.listbox.value = this.listbox.multiselect ? [] : null;
}
}
}
documentKeydown(event) {
if (
// if we press escape while on this combobox
event.key === 'Escape' &&
this.floatingContainer?.el.nativeElement.contains(event.target)) {
// return focus to input when escape is pressed and menu (was) open
if (!this._inputFocused && this.floatingContainer?.isShown) {
this.input?.el.nativeElement.focus();
}
else if (!this.floatingContainer?.isShown) {
// if menu is already closed, do not select "highlighted" option
this._highlightedIndex = null;
this._lastHighlightedOnClose = null;
}
}
}
/**
* Highlight next enabled item or previous enabled item depending on type.
* @param type 'next' | 'prev'
*/
highlightNextPrevItem(type) {
let filteredIndex = null;
if (this._highlightedIndex !== null) {
// find next item given current item
if (type === 'next')
filteredIndex = this.novaLibService.nextEnabledItem(this.getList(), this._highlightedIndex);
if (type === 'prev')
filteredIndex = this.novaLibService.previousEnabledItem(this.getList(), this._highlightedIndex);
}
else if (this._activeIndex !== null) {
filteredIndex = this._activeIndex;
}
else {
// find next item initially
if (type === 'next')
filteredIndex = this.novaLibService.nextEnabledItem(this.getList());
if (type === 'prev')
filteredIndex = this.novaLibService.previousEnabledItem(this.getList());
}
if (filteredIndex !== null)
this.highlightIndex(filteredIndex);
}
highlightIndex(index) {
if (this.getListItem(index)) {
this._highlightedIndex = index;
const item = this.getListItem(this._highlightedIndex);
if (item) {
if (this.input)
this.input.ariaActiveDescendant = item.id;
if (this.listbox)
this.listbox.ariaActiveDescendant.set(item.id);
}
if (this._highlightedIndex !== null) {
this.novaLibService.selectItem(this.getList(), this._highlightedIndex, 'highlighted');
this.novaLibService.deselectItems(this.getList(), this._highlightedIndex, 'highlighted');
}
}
}
selectItem(index) {
this.getListItem(index)?.selectItem();
}
/**
* @param index
* @returns ListboxItemComponent at index given.
*/
getListItem(index) {
if (index === null || !this.currentListItems?.toArray()[index]) {
return;
}
return this.currentListItems.toArray()[index];
}
/**
* Update children (input and listbox) state based on parent state.
*/
updateChildrenStates(prop) {
if (!this.input || !this.listbox)
return;
switch (prop) {
case STATE.READONLY:
this.input.readonly = this.readonly;
break;
case STATE.DISABLED:
this.input.disabled = this.disabled;
this.listbox.disabled = this.disabled;
break;
case STATE.INVALID:
this.input.invalid = this.invalid;
this.listbox.invalid = this.invalid;
break;
case STATE.REQUIRED:
this.input.required = this.required;
this.listbox.required = this.required;
break;
default:
break;
}
}
appendReadonlyText() {
if (this.appReadyService.isBrowserAndDomAvailable()) {
if (this.readonly) {
const span = this.renderer.createElement('span');
this.renderer.addClass(span, 'v-sr');
this.currentID = this.UUIDService.getUUID('v-label-');
this.renderer.setAttribute(span, 'id', this.currentID);
const text = this.renderer.createText(' (read-only)');
this.renderer.appendChild(span, text);
this.renderer.appendChild(this.label.el.nativeElement, span);
}
else {
this.renderer.removeChild(this.label.el.nativeElement, document.getElementById(this.currentID));
}
}
}
clearCombobox() {
this._activeIndex = null;
this._highlightedIndex = null;
this._prevActiveItem = null;
// unhighlight items, listbox will set all active items to false
if (this.input && this.listbox) {
this.input.ariaActiveDescendant = null;
this.listbox.ariaActiveDescendant.set(null);
}
this.novaLibService.deselectItems(this.getList(), undefined, 'highlighted');
if (this.input && this.input.value !== '') {
this.input.value = '';
}
if (this.listbox) {
if (this.listbox.multiselect && Array.isArray(this.listbox.value) && this.listbox.value.length > 0) {
this.listbox.value = [];
}
else if (this.listbox.value) {
this.listbox.value = null;
}
}
this.filter.emit({
type: ComboboxFilterType.RESET,
listbox: this.listbox?.value || [],
input: this.input?.value || ''
});
}
/**
* @returns ListboxDirective
*/
getList() {
return this.currentListItems?.toArray() || [];
}
findListItem(text) {
if (!this.appReadyService.isBrowserAndDomAvailable())
return -1; // return if app is not bootstrapped and therefore we cannot access item native element
return this.currentListItems
?.toArray()
.findIndex((item) => item.el.nativeElement.innerText.trim().toLowerCase() == text.toLowerCase());
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
writeValue(value) {
this.value = value;
this.onChange(value);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComboboxDirective, deps: [{ token: i1.NovaLibService }, { token: i2.ListboxService }, { token: i3.AppReadyService }, { token: i0.Renderer2 }, { token: i4.UUIDService }, { token: i5.FloatingUIContainer }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ComboboxDirective, isStandalone: true, selector: "[v-combobox]", inputs: { class: "class", removeReadonlyText: "removeReadonlyText", EXPERIMENTAL_ADA_OPT_IN: "EXPERIMENTAL_ADA_OPT_IN", readonly: "readonly", disabled: "disabled", invalid: "invalid", required: "required", value: "value" }, outputs: { itemSelected: "itemSelected", filter: "filter", filteredListEmitter: "filteredListEmitter" }, host: { listeners: { "focus": "handleFocus($event)", "keydown": "hostKeyDown($event)", "keyup": "hostKeyup($event)", "document:keydown": "documentKeydown($event)" }, properties: { "class": "this.hostClass", "attr.disabled": "this.hostDisabled", "attr.aria-invalid": "this.ariaInvalid" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ComboboxDirective),
multi: true
}
], queries: [{ propertyName: "inputContainer", first: true, predicate: InputContainerComponent, descendants: true }, { propertyName: "input", first: true, predicate: InputDirective, descendants: true }, { propertyName: "listboxContainer", first: true, predicate: ListboxContainerDirective, descendants: true }, { propertyName: "listbox", first: true, predicate: ListboxDirective, descendants: true }, { propertyName: "label", first: true, predicate: LabelDirective, descendants: true }, { propertyName: "interactiveChildren", predicate: ButtonDirective, descendants: true }, { propertyName: "chips", predicate: ChipDirective, descendants: true }], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComboboxDirective, decorators: [{
type: Directive,
args: [{
standalone: true,
selector: '[v-combobox]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ComboboxDirective),
multi: true
}
]
}]
}], ctorParameters: () => [{ type: i1.NovaLibService }, { type: i2.ListboxService }, { type: i3.AppReadyService }, { type: i0.Renderer2 }, { type: i4.UUIDService }, { type: i5.FloatingUIContainer }], propDecorators: { inputContainer: [{
type: ContentChild,
args: [InputContainerComponent]
}], input: [{
type: ContentChild,
args: [InputDirective]
}], listboxContainer: [{
type: ContentChild,
args: [ListboxContainerDirective]
}], listbox: [{
type: ContentChild,
args: [ListboxDirective]
}], label: [{
type: ContentChild,
args: [LabelDirective]
}], interactiveChildren: [{
type: ContentChildren,
args: [ButtonDirective, { descendants: true }]
}], chips: [{
type: ContentChildren,
args: [ChipDirective, { descendants: true }]
}], class: [{
type: Input
}], hostClass: [{
type: HostBinding,
args: ['class']
}], removeReadonlyText: [{
type: Input
}], EXPERIMENTAL_ADA_OPT_IN: [{
type: Input
}], readonly: [{
type: Input
}], disabled: [{
type: Input
}], hostDisabled: [{
type: HostBinding,
args: ['attr.disabled']
}], invalid: [{
type: Input
}], ariaInvalid: [{
type: HostBinding,
args: ['attr.aria-invalid']
}], required: [{
type: Input
}], value: [{
type: Input
}], itemSelected: [{
type: Output
}], filter: [{
type: Output
}], filteredListEmitter: [{
type: Output
}], handleFocus: [{
type: HostListener,
args: ['focus', ['$event']]
}], hostKeyDown: [{
type: HostListener,
args: ['keydown', ['$event']]
}], hostKeyup: [{
type: HostListener,
args: ['keyup', ['$event']]
}], documentKeydown: [{
type: HostListener,
args: ['document:keydown', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tYm9ib3guZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9ub3ZhLWxpYi9zcmMvbGliL2NvbWJvYm94L2NvbWJvYm94LmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0lBZUk7QUFDSixPQUFPLEVBQWdCLHFCQUFxQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUUsT0FBTyxFQUVMLFlBQVksRUFDWixlQUFlLEVBQ2YsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUNsRixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMERBQTBELENBQUM7QUFDL0YsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdkYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzFELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUU3RixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDNUQsT0FBTyxFQUNMLGFBQWEsRUFDYixjQUFjLEVBQ2QsU0FBUyxFQUNULGNBQWMsRUFDZCxlQUFlLEVBQ2YsT0FBTyxFQUNQLFlBQVksRUFDYixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDOzs7Ozs7O0FBRXZELElBQUssS0FLSjtBQUxELFdBQUssS0FBSztJQUNSLDhCQUFxQixDQUFBO0lBQ3JCLDhCQUFxQixDQUFBO0lBQ3JCLDRCQUFtQixDQUFBO0lBQ25CLDhCQUFxQixDQUFBO0FBQ3ZCLENBQUMsRUFMSSxLQUFLLEtBQUwsS0FBSyxRQUtUO0FBYUQsTUFBTSxPQUFPLGlCQUFpQjtJQW9CNUI7OztPQUdHO0lBQ0gsSUFDSSxLQUFLO1FBQ1AsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFDRCxJQUFJLEtBQUssQ0FBQyxLQUFhO1FBQ3JCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxJQUNJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxJQUNJLGtCQUFrQjtRQUNwQixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztJQUNsQyxDQUFDO0lBQ0QsSUFBSSxrQkFBa0IsQ0FBQyxLQUFtQjtRQUN4QyxJQUFJLENBQUMsbUJBQW1CLEdBQUcscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUdEOzs7T0FHRztJQUNILElBQ0ksdUJBQXVCO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLHdCQUF3QixDQUFDO0lBQ3ZDLENBQUM7SUFDRCxJQUFJLHVCQUF1QixDQUFDLEtBQW1CO1FBQzdDLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBR0Q7OztPQUdHO0lBQ0gsSUFDSSxRQUFRO1FBQ1YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUFDRCxJQUFJLFFBQVEsQ0FBQyxLQUFtQjtRQUM5QixJQUFJLENBQUMsU0FBUyxHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCO1lBQUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDeEQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBR0Q7OztPQUdHO0lBQ0gsSUFDSSxRQUFRO1FBQ1YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUFDRCxJQUFJLFFBQVEsQ0FBQyxLQUFtQjtRQUM5QixJQUFJLENBQUMsU0FBUyxHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELElBQ0ksWUFBWTtRQUNkLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDM0MsQ0FBQztJQUNELHlEQUF5RDtJQUN6RCxnQkFBZ0IsQ0FBQyxVQUFtQjtRQUNsQyxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQztJQUM3QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFDSSxPQUFPO1FBQ1QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7SUFDRCxJQUFJLE9BQU8sQ0FBQyxLQUFtQjtRQUM3QixJQUFJLENBQUMsUUFBUSxHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVELElBQ0ksV0FBVztRQUNiLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFDSSxRQUFRO1FBQ1YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUFDRCxJQUFJLFFBQVEsQ0FBQyxLQUFtQjtRQUM5QixJQUFJLENBQUMsU0FBUyxHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUdEOztPQUVHO0lBQ0gsSUFDSSxLQUFLO1FBQ1AsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFDRCxJQUFJLEtBQUssQ0FBQyxLQUFVO1FBQ2xCLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVELHVDQUF1QztJQUN2QyxJQUFJLEdBQUc7UUFDTCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztJQUNELElBQUksR0FBRyxDQUFDLEtBQVU7UUFDaEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBR0QsV0FBVyxDQUFDLEtBQVU7UUFDcEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDcEIsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUMvQixJQUNFLEtBQUs7Z0JBQ0wsQ0FBQyxJQUFJLENBQUMsVUFBVTtnQkFDaEIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3RELENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQzVELENBQUM7Z0JBQ0QsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDdkYsSUFBSSxXQUFXLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDdEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDL0IsQ0FBQztxQkFBTSxDQUFDO29CQUNOLDZDQUE2QztvQkFDN0MsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7d0JBQ3RCLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxJQUFJLENBQUMsWUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO3dCQUMvRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQzt3QkFDekIsSUFBSSxJQUFJLENBQUMsS0FBSzs0QkFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQzt3QkFDdkQsSUFBSSxJQUFJLENBQUMsT0FBTzs0QkFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDaEUsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQXVCRCxZQUNTLGNBQThCLEVBQzdCLGNBQThCLEVBQzlCLGVBQWdDLEVBQ2hDLFFBQW1CLEVBQ25CLFdBQXdCLEVBQ3pCLGlCQUF1QztRQUx2QyxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDN0IsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUNoQyxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQ25CLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3pCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBc0I7UUF2TWhELHNCQUFpQixHQUFrQixJQUFJLENBQUM7UUFDeEMsaUJBQVksR0FBa0IsSUFBSSxDQUFDO1FBTzNCLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFZOUIsV0FBTSxHQUFXLEVBQUUsQ0FBQztRQWtCcEIsd0JBQW1CLEdBQVksS0FBSyxDQUFDO1FBYXJDLDZCQUF3QixHQUFZLEtBQUssQ0FBQztRQWUxQyxjQUFTLEdBQVksS0FBSyxDQUFDO1FBYzNCLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFzQjNCLGFBQVEsR0FBWSxLQUFLLENBQUM7UUFrQjFCLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFvQjNCLFdBQU0sR0FBaUQsSUFBSSxDQUFDO1FBK0I1RDs7V0FFRztRQUNPLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQWdELENBQUM7UUFFMUY7Ozs7V0FJRztRQUNPLFdBQU0sR0FBRyxJQUFJLFlBQVksRUFJL0IsQ0FBQztRQUVMOztXQUVHO1FBQ08sd0JBQW1CLEdBQXlDLElBQUksWUFBWSxFQUEwQixDQUFDO1FBNmZqSCxhQUFRLEdBQUcsQ0FBQyxDQUFNLEVBQUUsRUFBRSxHQUFFLENBQUMsQ0FBQztRQUUxQixjQUFTLEdBQUcsQ0FBQyxDQUFNLEVBQUUsRUFBRSxHQUFFLENBQUMsQ0FBQztJQXRmeEIsQ0FBQztJQUdKLFdBQVcsQ0FBQyxLQUFZO1FBQ3RCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1lBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3hDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO1lBQzFDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELGtCQUFrQjtRQUNoQixJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNwQixDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUMxQixDQUFDO1lBQ0QsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3pELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztZQUMvQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFFdEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7Z0JBQzVDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUM5QiwrQkFBK0I7b0JBQy9CLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztvQkFDdkMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN4QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3RFLHNDQUFzQztZQUN0QyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztZQUNwRCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3RELElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDckMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLGlCQUFpQixDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDL0QsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUNoQyxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO2dCQUNoQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLHdCQUF3QixFQUFFLEVBQUUsQ0FBQztvQkFDL0UsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN2QyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxVQUFVO1FBQ1IsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQzlCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO1FBQ2pFLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ3RDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbEgsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7WUFFdkIsOEVBQThFO1lBQzlFLElBQ0UsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsV0FBVyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO2dCQUNsRCxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsV0FBVyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQ2pHLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQzFFLENBQUM7aUJBQU0sQ0FBQztnQkFDTiw2Q0FBNkM7Z0JBQzdDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQy9DLENBQUM7WUFDRCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsaUJBQWlCLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDM0QsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7UUFDakQsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDakMsQ0FBQztRQUVELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDaEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUM5QyxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNyQyxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7WUFDakMsQ0FBQztZQUNELElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3JDLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQztZQUNqQyxDQUFDO1lBQ0QsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDbkMsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1lBQy9CLENBQUM7WUFDRCxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNyQyxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7WUFDakMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGNBQWM7UUFDWixJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFDaEMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ3JFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsSUFBSSxDQUFDLEdBQUc7Z0JBQUUsT0FBTztZQUM5QyxzRUFBc0U7WUFDdEUsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLHdCQUF3QixFQUFFLEVBQUUsQ0FBQztnQkFDcEQsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLFdBQVcsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ3RFLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLO3dCQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLGlCQUFpQjtnQkFDaEUsQ0FBQztxQkFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxXQUFXLElBQUksR0FBRyxFQUFFLENBQUM7b0JBQzdDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxHQUFHLENBQUMsQ0FBQztvQkFDdkYsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDaEYsQ0FBQztnQkFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUM5RSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztvQkFDZixJQUFJLEVBQUUsa0JBQWtCLENBQUMsU0FBUztvQkFDbEMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSztvQkFDM0IsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLEVBQUU7aUJBQzlCLENBQUMsQ0FBQztnQkFDSCx5REFBeUQ7Z0JBQ3pELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7b0JBQ25HLE9BQU8sQ0FBQyxrQkFBa0I7Z0JBQzVCLENBQUM7cUJBQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLFdBQVcsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDO29CQUMxRCxxR0FBcUc7b0JBQ3JHLE9BQU87Z0JBQ1QsQ0FBQztxQkFBTSxDQUFDO29CQUNOLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzdDLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO2dCQUMxQixJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsd0JBQXdCLEVBQUUsRUFBRSxDQUFDO29CQUNwRCxrRUFBa0U7b0JBQ2xFLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDdkMsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBRUgsSUFBSSxDQUFDLFdBQVcsQ0