UNPKG

@visa/nova-angular

Version:

Visa Product Design System Nova Angular library

220 lines 28 kB
/** * 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 { ChangeDetectorRef, ContentChildren, Directive, ElementRef, EventEmitter, HostBinding, Input, Output, QueryList } from '@angular/core'; import { ButtonDirective } from '../button/button.directive'; import { NovaLibService } from '../nova-lib.service'; import { TabItemDirective } from '../tab-item/tab-item.directive'; import * as i0 from "@angular/core"; import * as i1 from "../nova-lib.service"; export class TabListDirective { /** * Provides custom class(es) for custom styling. * @default .v-tabs.v-tabs-<orientation> */ get class() { return [this._class, 'v-tabs', this.vertical ? 'v-tabs-vertical' : 'v-tabs-horizontal'].join(' '); } set class(value) { this._class = value; } get hostClass() { return this.class; } /** * Sets tab list to vertical orientation when true. * @default false */ get vertical() { return this._vertical; } set vertical(value) { this._vertical = coerceBooleanProperty(value); } get hostOrientation() { if (this.vertical && !this._inNav) return 'vertical'; } /** * Sets custom role. * @default 'tablist' * @default null if nested tab list or within Navigation. * @builtin true */ get role() { return this._role; } set role(value) { this._role = value; this._roleSetByUser = true; } get hostRole() { return this.role; } constructor(novaLibService, cdRef, el) { this.novaLibService = novaLibService; this.cdRef = cdRef; this.el = el; this._roleSetByUser = false; // prevents parent component from overriding if role if role is given directly by user this.clickSubscriptions = []; this.activeSubscriptions = []; this._nestedTabs = false; this._inNav = false; this._class = ''; this._vertical = false; this._role = 'tablist'; /** * Emits selected tab index when new tab is selected. */ this.activeTabIndex = new EventEmitter(); } ngAfterContentInit() { if (this.tabLists) { if (this.tabLists.length > 0) { this._nestedTabs = true; this.setUpNestedTabs(); } this.tabLists.changes.subscribe(() => { if (this.tabLists.length > 0) { this._nestedTabs = true; this.setUpNestedTabs(); } }); } if (this.tabs) { if (this.tabs.length > 0) this.setUpTabs(); this.tabs.changes.subscribe(() => { this.activeSubscriptions.forEach((subscription) => subscription.unsubscribe()); this.clickSubscriptions.forEach((subscription) => subscription.unsubscribe()); this.activeSubscriptions = []; this.clickSubscriptions = []; this.setUpTabs(); this.cdRef.detectChanges(); }); } } setUpNestedTabs() { // remove tab/tablist roles in nested tab lists // child button/a tags use aria-current="page" instead of aria-selected this.role = this._roleSetByUser ? this.role : null; this.tabLists.forEach((tablist) => { tablist.role = tablist._roleSetByUser ? tablist.role : null; tablist.tabs.toArray().forEach((tab) => { tab.role = tab._roleSetByUser && !tab._roleSetByTab ? tab.role : null; if (tab.button) { tab.button._isInNavOrNested = true; tab.button.role = tab.button._roleSetByUser && !tab.button._roleSetByTab ? tab.button.role : null; tab.button.ariaCurrent = tab.button.ariaSelected ? 'page' : null; } }); }); } setUpTabs() { if (this.buttons.length > 0) { if (!this._inNav) { this.setUpFocusListener(); this.novaLibService.addArrowKeyNavigation(this.buttons.toArray(), true, this.vertical ? 'vertical' : 'horizontal'); } } this.tabs.toArray().forEach((tab, index) => { if (tab._roleSetByUser && !tab._roleSetByTab) { return; } else if (this.role && !tab.sectionTitle && !tab.disclosureTab && !tab.trigger) { tab.role = 'none'; } else { tab.role = null; } this.activeSubscriptions[index] = tab.tabActive.subscribe(() => { this.novaLibService.deselectItems(this.tabs.toArray(), index); }); this.clickSubscriptions[index] = tab.clicked.subscribe(() => { this.novaLibService.selectItem(this.tabs.toArray(), index); }); if (tab.button) { if (!tab.button._roleSetByUser) { tab.button.role = this._nestedTabs ? null : 'tab'; tab.button._roleSetByTab = true; } // if uer did not set button role on vertical tab, make medium if (this.vertical && (!tab.button._buttonSizeSetByUser || (tab.button._buttonSizeSetByUser && tab._sizeSetByTab))) { tab.button.buttonSize = 'medium'; } if (!tab.disclosureTab && !tab.trigger && !tab.button.toggleIcon) { if (this.tabLists.length > 0) { tab.button.ariaCurrent = tab.active ? 'page' : null; } else { tab.button.ariaSelected = tab.active; } } this.cdRef.detectChanges(); } }); } setUpFocusListener() { this.buttons.toArray().forEach((button) => { button.listeners.push(button.blurred.subscribe((event) => { // if focus is leaving the tab list, find the starting focusable tab for when the list receives focus again // if focus stays in the tab list, relatedTarget will be a button within the tab list if (!event.relatedTarget || !!this.el.nativeElement.contains(event.target)) { this.novaLibService.findStartingFocus(this.buttons.toArray()); } })); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TabListDirective, deps: [{ token: i1.NovaLibService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: TabListDirective, isStandalone: true, selector: "[v-tabs]", inputs: { class: "class", vertical: "vertical", role: "role" }, outputs: { activeTabIndex: "activeTabIndex" }, host: { properties: { "class": "this.hostClass", "attr.aria-orientation": "this.hostOrientation", "attr.role": "this.hostRole" } }, queries: [{ propertyName: "tabLists", predicate: TabListDirective, descendants: true }, { propertyName: "tabs", predicate: TabItemDirective }, { propertyName: "buttons", predicate: ButtonDirective, descendants: true }], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TabListDirective, decorators: [{ type: Directive, args: [{ standalone: true, // tslint:disable-next-line:directive-selector selector: '[v-tabs]' }] }], ctorParameters: () => [{ type: i1.NovaLibService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { tabLists: [{ type: ContentChildren, args: [TabListDirective, { descendants: true }] }], tabs: [{ type: ContentChildren, args: [TabItemDirective] }], buttons: [{ type: ContentChildren, args: [ButtonDirective, { descendants: true }] }], class: [{ type: Input }], hostClass: [{ type: HostBinding, args: ['class'] }], vertical: [{ type: Input }], hostOrientation: [{ type: HostBinding, args: ['attr.aria-orientation'] }], role: [{ type: Input }], hostRole: [{ type: HostBinding, args: ['attr.role'] }], activeTabIndex: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiLWxpc3QuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9ub3ZhLWxpYi9zcmMvbGliL3RhYi1saXN0L3RhYi1saXN0LmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0lBZUk7QUFDSixPQUFPLEVBQWdCLHFCQUFxQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUUsT0FBTyxFQUVMLGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osV0FBVyxFQUNYLEtBQUssRUFDTCxNQUFNLEVBQ04sU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7OztBQU9sRSxNQUFNLE9BQU8sZ0JBQWdCO0lBVTNCOzs7T0FHRztJQUNILElBQ0ksS0FBSztRQUNQLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDcEcsQ0FBQztJQUNELElBQUksS0FBSyxDQUFDLEtBQWE7UUFDckIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFDdEIsQ0FBQztJQUVELElBQ0ksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFDSSxRQUFRO1FBQ1YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUFDRCxJQUFJ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ZUFBZSxFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRTtnQkFZbkQsS0FBSztzQkFEUixLQUFLO2dCQVNGLFNBQVM7c0JBRFosV0FBVzt1QkFBQyxPQUFPO2dCQVVoQixRQUFRO3NCQURYLEtBQUs7Z0JBU0YsZUFBZTtzQkFEbEIsV0FBVzt1QkFBQyx1QkFBdUI7Z0JBWWhDLElBQUk7c0JBRFAsS0FBSztnQkFVRixRQUFRO3NCQURYLFdBQVc7dUJBQUMsV0FBVztnQkFRZCxjQUFjO3NCQUF2QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgICAgICAgICAgICAgQ29weXJpZ2h0IChjKSAyMDI1IFZpc2EsIEluYy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqKi9cbmltcG9ydCB7IEJvb2xlYW5JbnB1dCwgY29lcmNlQm9vbGVhblByb3BlcnR5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0QmluZGluZyxcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQnV0dG9uRGlyZWN0aXZlIH0gZnJvbSAnLi4vYnV0dG9uL2J1dHRvbi5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTm92YUxpYlNlcnZpY2UgfSBmcm9tICcuLi9ub3ZhLWxpYi5zZXJ2aWNlJztcbmltcG9ydCB7IFRhYkl0ZW1EaXJlY3RpdmUgfSBmcm9tICcuLi90YWItaXRlbS90YWItaXRlbS5kaXJlY3RpdmUnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRpcmVjdGl2ZS1zZWxlY3RvclxuICBzZWxlY3RvcjogJ1t2LXRhYnNdJ1xufSlcbmV4cG9ydCBjbGFzcyBUYWJMaXN0RGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCB7XG4gIEBDb250ZW50Q2hpbGRyZW4oVGFiTGlzdERpcmVjdGl2ZSwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KSB0YWJMaXN0czogUXVlcnlMaXN0PFRhYkxpc3REaXJlY3RpdmU+O1xuICBAQ29udGVudENoaWxkcmVuKFRhYkl0ZW1EaXJlY3RpdmUpIHRhYnM6IFF1ZXJ5TGlzdDxUYWJJdGVtRGlyZWN0aXZlPjtcbiAgQENvbnRlbnRDaGlsZHJlbihCdXR0b25EaXJlY3RpdmUsIHsgZGVzY2VuZGFudHM6IHRydWUgfSkgYnV0dG9uczogUXVlcnlMaXN0PEJ1dHRvbkRpcmVjdGl2ZT47XG4gIF9yb2xlU2V0QnlVc2VyID0gZmFsc2U7IC8vIHByZXZlbnRzIHBhcmVudCBjb21wb25lbnQgZnJvbSBvdmVycmlkaW5nIGlmIHJvbGUgaWYgcm9sZSBpcyBnaXZlbiBkaXJlY3RseSBieSB1c2VyXG4gIGNsaWNrU3Vic2NyaXB0aW9uczogYW55W10gPSBbXTtcbiAgYWN0aXZlU3Vic2NyaXB0aW9uczogYW55W10gPSBbXTtcbiAgX25lc3RlZFRhYnM6IGJvb2xlYW4gPSBmYWxzZTtcbiAgX2luTmF2OiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIFByb3ZpZGVzIGN1c3RvbSBjbGFzcyYjNDA7ZXMmIzQxOyBmb3IgY3VzdG9tIHN0eWxpbmcuXG4gICAqIEBkZWZhdWx0IC52LXRhYnMudi10YWJzLSZsdDtvcmllbnRhdGlvbiZndDtcbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBjbGFzcygpOiBzdHJpbmcge1xuICAgIHJldHVybiBbdGhpcy5fY2xhc3MsICd2LXRhYnMnLCB0aGlzLnZlcnRpY2FsID8gJ3YtdGFicy12ZXJ0aWNhbCcgOiAndi10YWJzLWhvcml6b250YWwnXS5qb2luKCcgJyk7XG4gIH1cbiAgc2V0IGNsYXNzKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9jbGFzcyA9IHZhbHVlO1xuICB9XG4gIF9jbGFzczogc3RyaW5nID0gJyc7XG4gIEBIb3N0QmluZGluZygnY2xhc3MnKVxuICBnZXQgaG9zdENsYXNzKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY2xhc3M7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0YWIgbGlzdCB0byB2ZXJ0aWNhbCBvcmllbnRhdGlvbiB3aGVuIHRydWUuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgdmVydGljYWwoKTogQm9vbGVhbklucHV0IHtcbiAgICByZXR1cm4gdGhpcy5fdmVydGljYWw7XG4gIH1cbiAgc2V0IHZlcnRpY2FsKHZhbHVlOiBCb29sZWFuSW5wdXQpIHtcbiAgICB0aGlzLl92ZXJ0aWNhbCA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG4gIH1cbiAgX3ZlcnRpY2FsOiBCb29sZWFuSW5wdXQgPSBmYWxzZTtcbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtb3JpZW50YXRpb24nKVxuICBnZXQgaG9zdE9yaWVudGF0aW9uKCk6IHN0cmluZyB8IHZvaWQge1xuICAgIGlmICh0aGlzLnZlcnRpY2FsICYmICF0aGlzLl9pbk5hdikgcmV0dXJuICd2ZXJ0aWNhbCc7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBjdXN0b20gcm9sZS5cbiAgICogQGRlZmF1bHQgJ3RhYmxpc3QnXG4gICAqIEBkZWZhdWx0IG51bGwgaWYgbmVzdGVkIHRhYiBsaXN0IG9yIHdpdGhpbiBOYXZpZ2F0aW9uLlxuICAgKiBAYnVpbHRpbiB0cnVlXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgcm9sZSgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fcm9sZTtcbiAgfVxuICBzZXQgcm9sZSh2YWx1ZTogc3RyaW5nIHwgbnVsbCkge1xuICAgIHRoaXMuX3JvbGUgPSB2YWx1ZTtcbiAgICB0aGlzLl9yb2xlU2V0QnlVc2VyID0gdHJ1ZTtcbiAgfVxuICBfcm9sZTogc3RyaW5nIHwgbnVsbCA9ICd0YWJsaXN0JztcbiAgQEhvc3RCaW5kaW5nKCdhdHRyLnJvbGUnKVxuICBnZXQgaG9zdFJvbGUoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMucm9sZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyBzZWxlY3RlZCB0YWIgaW5kZXggd2hlbiBuZXcgdGFiIGlzIHNlbGVjdGVkLlxuICAgKi9cbiAgQE91dHB1dCgpIGFjdGl2ZVRhYkluZGV4ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBub3ZhTGliU2VydmljZTogTm92YUxpYlNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjZFJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZlxuICApIHt9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnRhYkxpc3RzKSB7XG4gICAgICBpZiAodGhpcy50YWJMaXN0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuX25lc3RlZFRhYnMgPSB0cnVlO1xuICAgICAgICB0aGlzLnNldFVwTmVzdGVkVGFicygpO1xuICAgICAgfVxuICAgICAgdGhpcy50YWJMaXN0cy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnRhYkxpc3RzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aGlzLl9uZXN0ZWRUYWJzID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLnNldFVwTmVzdGVkVGFicygpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHRoaXMudGFicykge1xuICAgICAgaWYgKHRoaXMudGFicy5sZW5ndGggPiAwKSB0aGlzLnNldFVwVGFicygpO1xuICAgICAgdGhpcy50YWJzLmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5hY3RpdmVTdWJzY3JpcHRpb25zLmZvckVhY2goKHN1YnNjcmlwdGlvbikgPT4gc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCkpO1xuICAgICAgICB0aGlzLmNsaWNrU3Vic2NyaXB0aW9ucy5mb3JFYWNoKChzdWJzY3JpcHRpb24pID0+IHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpKTtcbiAgICAgICAgdGhpcy5hY3RpdmVTdWJzY3JpcHRpb25zID0gW107XG4gICAgICAgIHRoaXMuY2xpY2tTdWJzY3JpcHRpb25zID0gW107XG4gICAgICAgIHRoaXMuc2V0VXBUYWJzKCk7XG4gICAgICAgIHRoaXMuY2RSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc2V0VXBOZXN0ZWRUYWJzKCkge1xuICAgIC8vIHJlbW92ZSB0YWIvdGFibGlzdCByb2xlcyBpbiBuZXN0ZWQgdGFiIGxpc3RzXG4gICAgLy8gY2hpbGQgYnV0dG9uL2EgdGFncyB1c2UgYXJpYS1jdXJyZW50PVwicGFnZVwiIGluc3RlYWQgb2YgYXJpYS1zZWxlY3RlZFxuICAgIHRoaXMucm9sZSA9IHRoaXMuX3JvbGVTZXRCeVVzZXIgPyB0aGlzLnJvbGUgOiBudWxsO1xuICAgIHRoaXMudGFiTGlzdHMuZm9yRWFjaCgodGFibGlzdCkgPT4ge1xuICAgICAgdGFibGlzdC5yb2xlID0gdGFibGlzdC5fcm9sZVNldEJ5VXNlciA/IHRhYmxpc3Qucm9sZSA6IG51bGw7XG5cbiAgICAgIHRhYmxpc3QudGFicy50b0FycmF5KCkuZm9yRWFjaCgodGFiKSA9PiB7XG4gICAgICAgIHRhYi5yb2xlID0gdGFiLl9yb2xlU2V0QnlVc2VyICYmICF0YWIuX3JvbGVTZXRCeVRhYiA/IHRhYi5yb2xlIDogbnVsbDtcbiAgICAgICAgaWYgKHRhYi5idXR0b24pIHtcbiAgICAgICAgICB0YWIuYnV0dG9uLl9pc0luTmF2T3JOZXN0ZWQgPSB0cnVlO1xuICAgICAgICAgIHRhYi5idXR0b24ucm9sZSA9IHRhYi5idXR0b24uX3JvbGVTZXRCeVVzZXIgJiYgIXRhYi5idXR0b24uX3JvbGVTZXRCeVRhYiA/IHRhYi5idXR0b24ucm9sZSA6IG51bGw7XG4gICAgICAgICAgdGFiLmJ1dHRvbi5hcmlhQ3VycmVudCA9IHRhYi5idXR0b24uYXJpYVNlbGVjdGVkID8gJ3BhZ2UnIDogbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBzZXRVcFRhYnMoKSB7XG4gICAgaWYgKHRoaXMuYnV0dG9ucy5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoIXRoaXMuX2luTmF2KSB7XG4gICAgICAgIHRoaXMuc2V0VXBGb2N1c0xpc3RlbmVyKCk7XG4gICAgICAgIHRoaXMubm92YUxpYlNlcnZpY2UuYWRkQXJyb3dLZXlOYXZpZ2F0aW9uKFxuICAgICAgICAgIHRoaXMuYnV0dG9ucy50b0FycmF5KCksXG4gICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICB0aGlzLnZlcnRpY2FsID8gJ3ZlcnRpY2FsJyA6ICdob3Jpem9udGFsJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnRhYnMudG9BcnJheSgpLmZvckVhY2goKHRhYiwgaW5kZXgpID0+IHtcbiAgICAgIGlmICh0YWIuX3JvbGVTZXRCeVVzZXIgJiYgIXRhYi5fcm9sZVNldEJ5VGFiKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5yb2xlICYmICF0YWIuc2VjdGlvblRpdGxlICYmICF0YWIuZGlzY2xvc3VyZVRhYiAmJiAhdGFiLnRyaWdnZXIpIHtcbiAgICAgICAgdGFiLnJvbGUgPSAnbm9uZSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YWIucm9sZSA9IG51bGw7XG4gICAgICB9XG4gICAgICB0aGlzLmFjdGl2ZVN1YnNjcmlwdGlvbnNbaW5kZXhdID0gdGFiLnRhYkFjdGl2ZS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLm5vdmFMaWJTZXJ2aWNlLmRlc2VsZWN0SXRlbXModGhpcy50YWJzLnRvQXJyYXkoKSwgaW5kZXgpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuY2xpY2tTdWJzY3JpcHRpb25zW2luZGV4XSA9IHRhYi5jbGlja2VkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMubm92YUxpYlNlcnZpY2Uuc2VsZWN0SXRlbSh0aGlzLnRhYnMudG9BcnJheSgpLCBpbmRleCk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKHRhYi5idXR0b24pIHtcbiAgICAgICAgaWYgKCF0YWIuYnV0dG9uLl9yb2xlU2V0QnlVc2VyKSB7XG4gICAgICAgICAgdGFiLmJ1dHRvbi5yb2xlID0gdGhpcy5fbmVzdGVkVGFicyA/IG51bGwgOiAndGFiJztcbiAgICAgICAgICB0YWIuYnV0dG9uLl9yb2xlU2V0QnlUYWIgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgdWVyIGRpZCBub3Qgc2V0IGJ1dHRvbiByb2xlIG9uIHZlcnRpY2FsIHRhYiwgbWFrZSBtZWRpdW1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMudmVydGljYWwgJiZcbiAgICAgICAgICAoIXRhYi5idXR0b24uX2J1dHRvblNpemVTZXRCeVVzZXIgfHwgKHRhYi5idXR0b24uX2J1dHRvblNpemVTZXRCeVVzZXIgJiYgdGFiLl9zaXplU2V0QnlUYWIpKVxuICAgICAgICApIHtcbiAgICAgICAgICB0YWIuYnV0dG9uLmJ1dHRvblNpemUgPSAnbWVkaXVtJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGFiLmRpc2Nsb3N1cmVUYWIgJiYgIXRhYi50cmlnZ2VyICYmICF0YWIuYnV0dG9uLnRvZ2dsZUljb24pIHtcbiAgICAgICAgICBpZiAodGhpcy50YWJMaXN0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0YWIuYnV0dG9uLmFyaWFDdXJyZW50ID0gdGFiLmFjdGl2ZSA/ICdwYWdlJyA6IG51bGw7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRhYi5idXR0b24uYXJpYVNlbGVjdGVkID0gdGFiLmFjdGl2ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzZXRVcEZvY3VzTGlzdGVuZXIoKSB7XG4gICAgdGhpcy5idXR0b25zLnRvQXJyYXkoKS5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgIGJ1dHRvbi5saXN0ZW5lcnMucHVzaChcbiAgICAgICAgYnV0dG9uLmJsdXJyZWQuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgICAgIC8vIGlmIGZvY3VzIGlzIGxlYXZpbmcgdGhlIHRhYiBsaXN0LCBmaW5kIHRoZSBzdGFydGluZyBmb2N1c2FibGUgdGFiIGZvciB3aGVuIHRoZSBsaXN0IHJlY2VpdmVzIGZvY3VzIGFnYWluXG4gICAgICAgICAgLy8gaWYgZm9jdXMgc3RheXMgaW4gdGhlIHRhYiBsaXN0LCByZWxhdGVkVGFyZ2V0IHdpbGwgYmUgYSBidXR0b24gd2l0aGluIHRoZSB0YWIgbGlzdFxuICAgICAgICAgIGlmICghZXZlbnQucmVsYXRlZFRhcmdldCB8fCAhIXRoaXMuZWwubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpKSB7XG4gICAgICAgICAgICB0aGlzLm5vdmFMaWJTZXJ2aWNlLmZpbmRTdGFydGluZ0ZvY3VzKHRoaXMuYnV0dG9ucy50b0FycmF5KCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==