UNPKG

@visa/nova-angular

Version:

Visa Product Design System Nova Angular library

517 lines 62.6 kB
/** * © 2025 Visa * * 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 { ChangeDetectorRef, ContentChildren, Directive, ElementRef, EventEmitter, HostBinding, HostListener, Input, Output, QueryList, forwardRef, signal } 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 { ListboxItemComponent } from '../listbox-item/listbox-item.component'; import { NovaLibService } from '../nova-lib.service'; import { ListboxService } from './listbox.service'; import * as i0 from "@angular/core"; import * as i1 from "../_utilities/services/uuid.service"; import * as i2 from "../nova-lib.service"; import * as i3 from "./listbox.service"; import * as i4 from "../_utilities/services/app-stable-check.service"; export class ListboxDirective { /** * Provides custom class&#40;es&#41; for custom styling. * @default .v-listbox */ get class() { return [this._class, 'v-listbox', this.containHeight ? 'v-listbox-scroll' : ''].join(' '); } set class(value) { this._class = value; } get hostClass() { return this.class; } get hostId() { return this.id; } /** * Sets listbox to multiselect variant when true. * @default false */ get multiselect() { return this._multiselect; } set multiselect(value) { this._multiselect = coerceBooleanProperty(value); } /** * Sets component and any ListboxItemComponent children as disabled when true. <br> * Will automatically become true if all children are disabled. * @default false */ get disabled() { return this._disabled; } set disabled(value) { this._disabled = coerceBooleanProperty(value); if (this.listItems && this.disabled !== this._childrenDisabled) this.setChildrenDisabled(); this.informState(); } /** Fires when a formControl's disabled state updates */ setDisabledState(isDisabled) { this.disabled = isDisabled; if (this.listItems && this.disabled !== this._childrenDisabled) this.setChildrenDisabled(); this.informState(); } /** * Sets component and any ListboxItemComponent children as invalid when true. <br> * Will automatically become true if any child is invalid. * @default false */ get invalid() { return this._invalid; } set invalid(value) { this._invalid = coerceBooleanProperty(value); if (this.listItems && this.invalid !== this._childrenInvalid) this.setChildrenInvalid(); this.informState(); } /** * Marks component as required when true. * @default false */ get required() { return this._required; } set required(value) { this._required = coerceBooleanProperty(value); this.informState(); } get hostRole() { if (this._isRoleListboxVariant() && !this.role) { this.role = 'group'; } return this.role; } /** * Sets CSS variable <code>--v-listbox-block-size-scroll</code>. <br /> * If true, the default 180px will be the listbox's <code>max-block-size</code>. <br /> * If set to a number or string representing a number (ie <code>[containHeight]="250"</code>), the variable will be set to that amount of pixels. */ get containHeight() { return this._containHeight; } set containHeight(value) { if (value && value !== true) { this._containHeight = value; } else { this._containHeight = coerceBooleanProperty(value); } } get scrollHeight() { if (this.containHeight && this.containHeight !== true) { return parseInt(this.containHeight.toString()) + 'px'; // allows "250" or "250px" for example } } /** * Value of listbox. */ get value() { return this._value; } set value(value) { this.setValue(value); } // keep val for backwards compatibility get val() { return this._value; } set val(value) { this.setValue(value); } setValue(value) { this._value = value; if (this.appReadyService.isBrowserAndDomAvailable()) { this.el.nativeElement.value = value; } if (this.listItems && this._internalValue !== value) { if (Array.isArray(value)) { // multiselect this.listItems .filter((item) => value?.includes(item.value)) .forEach((item) => { item.active = true; }); } else if (value) { // single select const selectedItem = this.listItems.find((item) => item.value === value); if (selectedItem) selectedItem.active = true; } this._internalValue = value; } if (!value || (this.multiselect && Array.isArray(value) && value.length === 0)) { // reset items this.resetListbox(); } this.valueUpdated.emit(this.value); this.onChange(value); } /** * Overrides default scroll control behavior. <br /> * By default the listbox will scroll to the last selected item. * @default false */ get customScrollControl() { return this._customScrollControl; } set customScrollControl(value) { this._customScrollControl = coerceBooleanProperty(value); } constructor(uuidService, novaLibService, listboxService, cdRef, el, appReadyService) { this.uuidService = uuidService; this.novaLibService = novaLibService; this.listboxService = listboxService; this.cdRef = cdRef; this.el = el; this.appReadyService = appReadyService; this._isRoleListboxVariant = signal(false); this._childrenDisabled = false; this._childrenInvalid = false; this._inCombobox = false; this._listboxScrollStylesSet = false; this._keyword = ''; this._highlightIndex = null; this._isHotkeyEvent = false; this._recentSelectedIndex = null; this._timeoutId = 0; this.ariaActiveDescendant = signal(null); this._class = ''; /** * Sets custom id. * @default uuidService.getUUID('v-listbox-') * @builtin true */ this.id = this.uuidService.getUUID('v-listbox-'); this._multiselect = false; this._disabled = false; this._invalid = false; this._required = false; this._customScrollControl = false; /** * Emits disabled, invalid, and required state of input when updated. */ this.communicateState = new EventEmitter(); /** * Emits new listbox value. */ this.valueUpdated = new EventEmitter(); this.onChange = (_) => { }; this.onTouched = (_) => { }; } handleFocus(event) { this.onTouched(event); } handleBlur(event) { } ngAfterContentInit() { if (this.listItems) { this.setUpListbox(); this.listItems.changes.subscribe(() => { this.setUpListbox(); }); } } setUpListbox() { if (this.disabled) { // if listbox disabled is true, disable all items this.setChildrenDisabled(); } else if ( // if all items are disabled, set listbox disabled to true this.listItems.length > 0 && this.listItems.toArray().length === this.listItems.toArray().filter((item) => item.disabled).length) { this._childrenDisabled = true; this.disabled = true; } else { this._childrenDisabled = false; this.disabled = false; } if (this.invalid) { // if listbox invalid is true, set children as invalid this.setChildrenInvalid(); } else if (this.listItems.find((item) => item.invalid)) { // if any item is invalid, set invalid class this._childrenInvalid = true; this.invalid = true; } else { this._childrenInvalid = false; this.invalid = false; } this._invalid = this.listItems.find((item) => item.invalid) ? true : false; this.addListItemSubscriptions(); this.setInitialValue(); // if standard listbox and not in combobox, add arrow key navigation if (this._isRoleListboxVariant() && !this._inCombobox) { this.listboxService.setUpListbox(this); } if (!this.customScrollControl) { setTimeout(() => { this.listboxService.scrollItemIntoView(this); }, 500); // on initial load, extra time is needed for getComputedStyle } } setInitialValue() { if ( /** * If value is an array, make sure the array is not empty * If value is not an array, make sure value exists. * This check ensures the function isn't called when value = [] */ (this.multiselect && Array.isArray(this.value) && this.value.length > 0) || (!this.multiselect && this.value)) { this.updateItemsFromValue(); } else { // if no value is given, find any active items and set value to those this.updateValueFromItems(); } this.cdRef.detectChanges(); } addListItemSubscriptions() { this.listItems.forEach((item, index) => { item.onFocus.subscribe((event) => { if (this._highlightIndex === null) this._highlightIndex = this.novaLibService.firstEnabledItem(this.listItems.toArray()); }); // subscribe to changes in disabled and invalid item._disabledEmitter.subscribe(() => { // if ALL children are disabled, entire listbox is disabled if (this.listItems.toArray().length === this.listItems.filter((item) => item.disabled).length) { this._childrenDisabled = true; this.disabled = true; } else { this._childrenDisabled = false; this.disabled = false; } }); item._invalidEmitter.subscribe(() => { // if ANY child is invalid, listbox shows as invalid if (this.listItems.find((item) => item.invalid)) { this._childrenInvalid = true; this.invalid = true; } else { this._childrenInvalid = false; this.invalid = false; } }); // if standard listbox, add role="listbox" and change underlying class to radio or checkbox accordingly if (item._isRoleOptionVariant) { if (!this._isRoleListboxVariant()) this._isRoleListboxVariant.set(true); item._multi = this.multiselect; item.index = index; // subscribe to when item is selected or clicked item.itemChanged.subscribe((isSelected) => { if (index !== item.index) return; // subscription is still being triggered for old rendered item this.novaLibService.deselectItems(this.listItems.toArray(), index, 'highlighted'); if (!this.multiselect && isSelected) { this.novaLibService.deselectItems(this.listItems.toArray(), index); this.updateValueFromItems(); } else if (this.multiselect) { // not calling update value because we need to maintain order if (isSelected) { if (Array.isArray(this.value)) { if (!this.value.includes(item.value)) this.value = [...this.value, item.value]; } else { this.value = [item.value]; } } else { if (Array.isArray(this.value)) { this.value = this.value.filter((val) => val !== item.value); } else { this.value = []; } } // set aria-activedescendant to first value this.ariaActiveDescendant.set(this.listItems.find((item) => item.active)?.id || null); } // Update highlight index if indexes do not match and click event is not triggered by hot key // Used for click event if (this._highlightIndex !== index && !this._isHotkeyEvent) { this._highlightIndex = index; // item.highlighted = true; this._recentSelectedIndex = item.index; } }); this.cdRef.detectChanges(); } }); } // value is given, update items so active items reflect listbox value updateItemsFromValue() { if (this.multiselect && Array.isArray(this.value) && this.value.length > 0) { // if value is an array, select all items that match the value this.listItems .filter((item) => this.value.includes(item.value)) .forEach((item) => { item.active = true; }); } else if (!this.multiselect && this.value) { // if item is string, select item that matches the value this.listItems .filter((item) => this.value === item.value) .forEach((item) => { item.active = true; }); } // set aria-activedescendant to first value this.ariaActiveDescendant.set(this.listItems.find((item) => item.active)?.id || null); } // no value is given, update value so it reflects active items updateValueFromItems() { // if multiselect, return value in array if (this.multiselect) { this.value = this.listItems.filter((item) => item.active).map((item) => item.value); } else { // if single select, return single value this.value = this.listItems.find((item) => item.active)?.value || null; } // set aria-activedescendant to first value this.ariaActiveDescendant.set(this.listItems.find((item) => item.active)?.id || null); } setChildrenDisabled() { this.listItems.forEach((item) => item.checkbox ? (item.checkbox.disabled = this.disabled) : item.radio ? (item.radio.disabled = this.disabled) : (item.disabled = this.disabled)); this._childrenDisabled = this.listItems.toArray().length === this.listItems.filter((item) => item.disabled).length; } setChildrenInvalid() { this.listItems.forEach((item) => item.checkbox ? (item.checkbox.invalid = this.invalid) : item.radio ? (item.radio.invalid = this.invalid) : (item.invalid = this.invalid)); this._childrenInvalid = this.listItems.some((item) => item.invalid); } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } writeValue(value) { this.value = value; } resetListbox() { if (this.listItems?.find((item) => item.active)) { // reset items this.novaLibService.deselectItems(this.listItems.toArray()); } this.ariaActiveDescendant.set(null); } informState() { this.communicateState.emit({ disabled: this.disabled, invalid: this.invalid, required: this.required }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ListboxDirective, deps: [{ token: i1.UUIDService }, { token: i2.NovaLibService }, { token: i3.ListboxService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i4.AppReadyService }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ListboxDirective, isStandalone: true, selector: "[v-listbox] ", inputs: { class: "class", id: "id", multiselect: "multiselect", disabled: "disabled", invalid: "invalid", required: "required", role: "role", containHeight: "containHeight", value: "value", customScrollControl: "customScrollControl" }, outputs: { communicateState: "communicateState", valueUpdated: "valueUpdated" }, host: { listeners: { "focus": "handleFocus($event)", "blur": "handleBlur($event)" }, properties: { "class": "this.hostClass", "attr.id": "this.hostId", "attr.role": "this.hostRole", "style.--v-listbox-block-size-scroll": "this.scrollHeight" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ListboxDirective), multi: true } ], queries: [{ propertyName: "listItems", predicate: ListboxItemComponent }], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ListboxDirective, decorators: [{ type: Directive, args: [{ standalone: true, selector: '[v-listbox] ', providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ListboxDirective), multi: true } ] }] }], ctorParameters: () => [{ type: i1.UUIDService }, { type: i2.NovaLibService }, { type: i3.ListboxService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i4.AppReadyService }], propDecorators: { listItems: [{ type: ContentChildren, args: [ListboxItemComponent] }], class: [{ type: Input }], hostClass: [{ type: HostBinding, args: ['class'] }], id: [{ type: Input }], hostId: [{ type: HostBinding, args: ['attr.id'] }], multiselect: [{ type: Input }], disabled: [{ type: Input }], invalid: [{ type: Input }], required: [{ type: Input }], role: [{ type: Input }], hostRole: [{ type: HostBinding, args: ['attr.role'] }], containHeight: [{ type: Input }], scrollHeight: [{ type: HostBinding, args: ['style.--v-listbox-block-size-scroll'] }], value: [{ type: Input }], customScrollControl: [{ type: Input }], communicateState: [{ type: Output }], valueUpdated: [{ type: Output }], handleFocus: [{ type: HostListener, args: ['focus', ['$event']] }], handleBlur: [{ type: HostListener, args: ['blur', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdGJveC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL25vdmEtbGliL3NyYy9saWIvbGlzdGJveC9saXN0Ym94LmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0lBZUk7QUFDSixPQUFPLEVBQTZCLHFCQUFxQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDekYsT0FBTyxFQUVMLGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLFNBQVMsRUFFVCxVQUFVLEVBQ1YsTUFBTSxFQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0saURBQWlELENBQUM7QUFDbEYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7Ozs7OztBQWFuRCxNQUFNLE9BQU8sZ0JBQWdCO0lBcUIzQjs7O09BR0c7SUFDSCxJQUNJLEtBQUs7UUFDUCxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM1RixDQUFDO0lBQ0QsSUFBSSxLQUFLLENBQUMsS0FBYTtRQUNyQixJQUFJLENBQUMsTUFB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QVg1QixTQUFTO21CQUFDO29CQUNULFVBQVUsRUFBRSxJQUFJO29CQUNoQixRQUFRLEVBQUUsY0FBYztvQkFDeEIsU0FBUyxFQUFFO3dCQUNUOzRCQUNFLE9BQU8sRUFBRSxpQkFBaUI7NEJBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLGlCQUFpQixDQUFDOzRCQUMvQyxLQUFLLEVBQUUsSUFBSTt5QkFDWjtxQkFDRjtpQkFDRjtpT0FFd0MsU0FBUztzQkFBL0MsZUFBZTt1QkFBQyxvQkFBb0I7Z0JBeUJqQyxLQUFLO3NCQURSLEtBQUs7Z0JBU0YsU0FBUztzQkFEWixXQUFXO3VCQUFDLE9BQU87Z0JBV3BCLEVBQUU7c0JBREQsS0FBSztnQkFHRixNQUFNO3NCQURULFdBQVc7dUJBQUMsU0FBUztnQkFVbEIsV0FBVztzQkFEZCxLQUFLO2dCQWVGLFFBQVE7c0JBRFgsS0FBSztnQkF1QkYsT0FBTztzQkFEVixLQUFLO2dCQWdCRixRQUFRO3NCQURYLEtBQUs7Z0JBZ0JHLElBQUk7c0JBQVosS0FBSztnQkFFRixRQUFRO3NCQURYLFdBQVc7dUJBQUMsV0FBVztnQkFjcEIsYUFBYTtzQkFEaEIsS0FBSztnQkFhRixZQUFZO3NCQURmLFdBQVc7dUJBQUMscUNBQXFDO2dCQVc5QyxLQUFLO3NCQURSLEtBQUs7Z0JBcURGLG1CQUFtQjtzQkFEdEIsS0FBSztnQkFZSSxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBS0csWUFBWTtzQkFBckIsTUFBTTtnQkFZUCxXQUFXO3NCQURWLFlBQVk7dUJBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQUtqQyxVQUFVO3NCQURULFlBQVk7dUJBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgICAgICAgICAgICAgwqkgMjAyNSBWaXNhXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKiovXG5pbXBvcnQgeyBCb29sZWFuSW5wdXQsIE51bWJlcklucHV0LCBjb2VyY2VCb29sZWFuUHJvcGVydHkgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RCaW5kaW5nLFxuICBIb3N0TGlzdGVuZXIsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgV3JpdGFibGVTaWduYWwsXG4gIGZvcndhcmRSZWYsXG4gIHNpZ25hbFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEFwcFJlYWR5U2VydmljZSB9IGZyb20gJy4uL191dGlsaXRpZXMvc2VydmljZXMvYXBwLXN0YWJsZS1jaGVjay5zZXJ2aWNlJztcbmltcG9ydCB7IFVVSURTZXJ2aWNlIH0gZnJvbSAnLi4vX3V0aWxpdGllcy9zZXJ2aWNlcy91dWlkLnNlcnZpY2UnO1xuaW1wb3J0IHsgTGlzdGJveEl0ZW1Db21wb25lbnQgfSBmcm9tICcuLi9saXN0Ym94LWl0ZW0vbGlzdGJveC1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOb3ZhTGliU2VydmljZSB9IGZyb20gJy4uL25vdmEtbGliLnNlcnZpY2UnO1xuaW1wb3J0IHsgTGlzdGJveFNlcnZpY2UgfSBmcm9tICcuL2xpc3Rib3guc2VydmljZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogJ1t2LWxpc3Rib3hdICcsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTGlzdGJveERpcmVjdGl2ZSksXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH1cbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBMaXN0Ym94RGlyZWN0aXZlIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEFmdGVyQ29udGVudEluaXQge1xuICBAQ29udGVudENoaWxkcmVuKExpc3Rib3hJdGVtQ29tcG9uZW50KSBsaXN0SXRlbXM6IFF1ZXJ5TGlzdDxMaXN0Ym94SXRlbUNvbXBvbmVudD47XG4gIF9pc1JvbGVMaXN0Ym94VmFyaWFudCA9IHNpZ25hbChmYWxzZSk7XG4gIF9jaGlsZHJlbkRpc2FibGVkID0gZmFsc2U7XG4gIF9jaGlsZHJlbkludmFsaWQgPSBmYWxzZTtcbiAgX2ludGVybmFsVmFsdWU6IChzdHJpbmcgfCBudW1iZXIpW10gfCBzdHJpbmcgfCBudW1iZXIgfCBudWxsO1xuICBfaW5Db21ib2JveCA9IGZhbHNlO1xuXG4gIC8vIHVzZWQgaW4gc2VydmljZVxuICBfbGlzdGJveEhlaWdodDogbnVtYmVyO1xuICBfbGlzdGJveEl0ZW1IZWlnaHQ6IG51bWJlcjtcbiAgX2xpc3Rib3hHYXA6IG51bWJlcjtcbiAgX2xpc3Rib3hTY3JvbGxTdHlsZXNTZXQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBfa2V5d29yZDogU3RyaW5nID0gJyc7XG4gIF9oaWdobGlnaHRJbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIF9pc0hvdGtleUV2ZW50OiBCb29sZWFuID0gZmFsc2U7XG4gIF9yZWNlbnRTZWxlY3RlZEluZGV4OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgX3RpbWVvdXRJZDogbnVtYmVyID0gMDtcbiAgYXJpYUFjdGl2ZURlc2NlbmRhbnQ6IFdyaXRhYmxlU2lnbmFsPHN0cmluZyB8IG51bGw+ID0gc2lnbmFsKG51bGwpO1xuXG4gIC8qKlxuICAgKiBQcm92aWRlcyBjdXN0b20gY2xhc3MmIzQwO2VzJiM0MTsgZm9yIGN1c3RvbSBzdHlsaW5nLlxuICAgKiBAZGVmYXVsdCAudi1saXN0Ym94XG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgY2xhc3MoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gW3RoaXMuX2NsYXNzLCAndi1saXN0Ym94JywgdGhpcy5jb250YWluSGVpZ2h0ID8gJ3YtbGlzdGJveC1zY3JvbGwnIDogJyddLmpvaW4oJyAnKTtcbiAgfVxuICBzZXQgY2xhc3ModmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuX2NsYXNzID0gdmFsdWU7XG4gIH1cbiAgX2NsYXNzOiBzdHJpbmcgPSAnJztcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcycpXG4gIGdldCBob3N0Q2xhc3MoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jbGFzcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGN1c3RvbSBpZC5cbiAgICogQGRlZmF1bHQgdXVpZFNlcnZpY2UuZ2V0VVVJRCgndi1saXN0Ym94LScpXG4gICAqIEBidWlsdGluIHRydWVcbiAgICovXG4gIEBJbnB1dCgpXG4gIGlkOiBzdHJpbmcgPSB0aGlzLnV1aWRTZXJ2aWNlLmdldFVVSUQoJ3YtbGlzdGJveC0nKTtcbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmlkJylcbiAgZ2V0IGhvc3RJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmlkO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgbGlzdGJveCB0byBtdWx0aXNlbGVjdCB2YXJpYW50IHdoZW4gdHJ1ZS5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBtdWx0aXNlbGVjdCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fbXVsdGlzZWxlY3Q7XG4gIH1cbiAgc2V0IG11bHRpc2VsZWN0KHZhbHVlOiBCb29sZWFuSW5wdXQpIHtcbiAgICB0aGlzLl9tdWx0aXNlbGVjdCA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG4gIH1cbiAgX211bHRpc2VsZWN0OiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIFNldHMgY29tcG9uZW50IGFuZCBhbnkgTGlzdGJveEl0ZW1Db21wb25lbnQgY2hpbGRyZW4gYXMgZGlzYWJsZWQgd2hlbiB0cnVlLiA8YnI+XG4gICAqIFdpbGwgYXV0b21hdGljYWxseSBiZWNvbWUgdHJ1ZSBpZiBhbGwgY2hpbGRyZW4gYXJlIGRpc2FibGVkLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgQElucHV0KClcbiAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9kaXNhYmxlZDtcbiAgfVxuICBzZXQgZGlzYWJsZWQodmFsdWU6IEJvb2xlYW5JbnB1dCkge1xuICAgIHRoaXMuX2Rpc2FibGVkID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgICBpZiAodGhpcy5saXN0SXRlbXMgJiYgdGhpcy5kaXNhYmxlZCAhPT0gdGhpcy5fY2hpbGRyZW5EaXNhYmxlZCkgdGhpcy5zZXRDaGlsZHJlbkRpc2FibGVkKCk7XG4gICAgdGhpcy5pbmZvcm1TdGF0ZSgpO1xuICB9XG4gIF9kaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICAvKiogRmlyZXMgd2hlbiBhIGZvcm1Db250cm9sJ3MgZGlzYWJsZWQgc3RhdGUgdXBkYXRlcyAgKi9cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgaWYgKHRoaXMubGlzdEl0ZW1zICYmIHRoaXMuZGlzYWJsZWQgIT09IHRoaXMuX2NoaWxkcmVuRGlzYWJsZWQpIHRoaXMuc2V0Q2hpbGRyZW5EaXNhYmxlZCgpO1xuICAgIHRoaXMuaW5mb3JtU3RhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGNvbXBvbmVudCBhbmQgYW55IExpc3Rib3hJdGVtQ29tcG9uZW50IGNoaWxkcmVuIGFzIGludmFsaWQgd2hlbiB0cnVlLiA8YnI+XG4gICAqIFdpbGwgYXV0b21hdGljYWxseSBiZWNvbWUgdHJ1ZSBpZiBhbnkgY2hpbGQgaXMgaW52YWxpZC5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBpbnZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9pbnZhbGlkO1xuICB9XG4gIHNldCBpbnZhbGlkKHZhbHVlOiBCb29sZWFuSW5wdXQpIHtcbiAgICB0aGlzLl9pbnZhbGlkID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgICBpZiAodGhpcy5saXN0SXRlbXMgJiYgdGhpcy5pbnZhbGlkICE9PSB0aGlzLl9jaGlsZHJlbkludmFsaWQpIHRoaXMuc2V0Q2hpbGRyZW5JbnZhbGlkKCk7XG4gICAgdGhpcy5pbmZvcm1TdGF0ZSgpO1xuICB9XG4gIF9pbnZhbGlkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIE1hcmtzIGNvbXBvbmVudCBhcyByZXF1aXJlZCB3aGVuIHRydWUuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgcmVxdWlyZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3JlcXVpcmVkO1xuICB9XG4gIHNldCByZXF1aXJlZCh2YWx1ZTogQm9vbGVhbklucHV0KSB7XG4gICAgdGhpcy5fcmVxdWlyZWQgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xuICAgIHRoaXMuaW5mb3JtU3RhdGUoKTtcbiAgfVxuICBfcmVxdWlyZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKipcbiAgICogU2V0cyBjdXN0b20gcm9sZS5cbiAgICogQGRlZmF1bHQgJ2dyb3VwJyBpZiBubyBjaGlsZCBsaXN0IGl0ZW0gY29udGFpbnMgYSBjaGlsZCByYWRpbyBvciBjaGVja2JveC5cbiAgICogQGRlZmF1bHQgbm90IHByZXNlbnQgaWYgYW55IGNoaWxkIGxpc3QgaXRlbSBjb250YWlucyBhIGNoaWxkIHJhZGlvIG9yIGNoZWNrYm94LlxuICAgKiBAYnVpbHRpbiB0cnVlXG4gICAqL1xuICBASW5wdXQoKSByb2xlOiBzdHJpbmc7XG4gIEBIb3N0QmluZGluZygnYXR0ci5yb2xlJylcbiAgZ2V0IGhvc3RSb2xlKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuX2lzUm9sZUxpc3Rib3hWYXJpYW50KCkgJiYgIXRoaXMucm9sZSkge1xuICAgICAgdGhpcy5yb2xlID0gJ2dyb3VwJztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucm9sZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIENTUyB2YXJpYWJsZSA8Y29kZT4tLXYtbGlzdGJveC1ibG9jay1zaXplLXNjcm9sbDwvY29kZT4uIDxiciAvPlxuICAgKiBJZiB0cnVlLCB0aGUgZGVmYXVsdCAxODBweCB3aWxsIGJlIHRoZSBsaXN0Ym94J3MgPGNvZGU+bWF4LWJsb2NrLXNpemU8L2NvZGU+LiA8YnIgLz5cbiAgICogSWYgc2V0IHRvIGEgbnVtYmVyIG9yIHN0cmluZyByZXByZXNlbnRpbmcgYSBudW1iZXIgKGllIDxjb2RlPltjb250YWluSGVpZ2h0XT1cIjI1MFwiPC9jb2RlPiksIHRoZSB2YXJpYWJsZSB3aWxsIGJlIHNldCB0byB0aGF0IGFtb3VudCBvZiBwaXhlbHMuXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgY29udGFpbkhlaWdodCgpOiBOdW1iZXJJbnB1dCB8IEJvb2xlYW5JbnB1dCB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbnRhaW5IZWlnaHQ7XG4gIH1cbiAgc2V0IGNvbnRhaW5IZWlnaHQodmFsdWU6IE51bWJlcklucHV0IHwgQm9vbGVhbklucHV0KSB7XG4gICAgaWYgKHZhbHVlICYmIHZhbHVlICE9PSB0cnVlKSB7XG4gICAgICB0aGlzLl9jb250YWluSGVpZ2h0ID0gdmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2NvbnRhaW5IZWlnaHQgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xuICAgIH1cbiAgfVxuICBfY29udGFpbkhlaWdodDogTnVtYmVySW5wdXQgfCBCb29sZWFuSW5wdXQ7XG4gIEBIb3N0QmluZGluZygnc3R5bGUuLS12LWxpc3Rib3gtYmxvY2stc2l6ZS1zY3JvbGwnKVxuICBnZXQgc2Nyb2xsSGVpZ2h0KCk6IE51bWJlcklucHV0IHwgdm9pZCB8IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmNvbnRhaW5IZWlnaHQgJiYgdGhpcy5jb250YWluSGVpZ2h0ICE9PSB0cnVlKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5jb250YWluSGVpZ2h0LnRvU3RyaW5nKCkpICsgJ3B4JzsgLy8gYWxsb3dzIFwiMjUwXCIgb3IgXCIyNTBweFwiIGZvciBleGFtcGxlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbHVlIG9mIGxpc3Rib3guXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICB9XG4gIHNldCB2YWx1ZSh2YWx1ZTogKHN0cmluZyB8IG51bWJlcilbXSB8IHN0cmluZyB8IG51bWJlciB8IG51bGwpIHtcbiAgICB0aGlzLnNldFZhbHVlKHZhbHVlKTtcbiAgfVxuXG4gIC8vIGtlZXAgdmFsIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuICBnZXQgdmFsKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgfVxuICBzZXQgdmFsKHZhbHVlOiAoc3RyaW5nIHwgbnVtYmVyKVtdIHwgc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCkge1xuICAgIHRoaXMuc2V0VmFsdWUodmFsdWUpO1xuICB9XG5cbiAgc2V0VmFsdWUodmFsdWU6IChzdHJpbmcgfCBudW1iZXIpW10gfCBzdHJpbmcgfCBudW1iZXIgfCBudWxsKSB7XG4gICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcblxuICAgIGlmICh0aGlzLmFwcFJlYWR5U2VydmljZS5pc0Jyb3dzZXJBbmREb21BdmFpbGFibGUoKSkge1xuICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnZhbHVlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGlzdEl0ZW1zICYmIHRoaXMuX2ludGVybmFsVmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgLy8gbXVsdGlzZWxlY3RcbiAgICAgICAgdGhpcy5saXN0SXRlbXNcbiAgICAgICAgICAuZmlsdGVyKChpdGVtKSA9PiB2YWx1ZT8uaW5jbHVkZXMoaXRlbS52YWx1ZSkpXG4gICAgICAgICAgLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgICAgICAgIGl0ZW0uYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUpIHtcbiAgICAgICAgLy8gc2luZ2xlIHNlbGVjdFxuICAgICAgICBjb25zdCBzZWxlY3RlZEl0ZW0gPSB0aGlzLmxpc3RJdGVtcy5maW5kKChpdGVtKSA9PiBpdGVtLnZhbHVlID09PSB2YWx1ZSk7XG4gICAgICAgIGlmIChzZWxlY3RlZEl0ZW0pIHNlbGVjdGVkSXRlbS5hY3RpdmUgPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5faW50ZXJuYWxWYWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgICBpZiAoIXZhbHVlIHx8ICh0aGlzLm11bHRpc2VsZWN0ICYmIEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA9PT0gMCkpIHtcbiAgICAgIC8vIHJlc2V0IGl0ZW1zXG4gICAgICB0aGlzLnJlc2V0TGlzdGJveCgpO1xuICAgIH1c