UNPKG

@hxui/angular

Version:

An Angular library based on the [HXUI design system](https://hxui.io).

272 lines (269 loc) 24.7 kB
import { Component, ContentChildren, forwardRef, Input, QueryList, } from '@angular/core'; import { TabDirective } from './tab.directive'; import { TabsetConfig } from './tabset.config'; import * as i0 from "@angular/core"; import * as i1 from "./tabset.config"; import * as i2 from "@angular/common"; import * as i3 from "./ng-transclude.directive"; export class TabsetComponent { constructor(config) { /** if true tabs will be placed vertically */ this.vertical = false; /** if true tabs fill the container and have a consistent width */ this.justified = false; this.hasInfo = false; this.stickyHeader = false; this.stickyHeaderOffset = 0; this.tag = 'link'; this.changeFn = async () => true; this.tabs = []; Object.assign(this, config); } /** navigation context class: 'tabs' or 'pills' */ get type() { return this._type; } set type(value) { this._type = value; } ngAfterContentInit() { // get all active tabs const activeTabs = this._tabList.filter(tab => tab.active); // if there is no active tab set, activate the first if (activeTabs.length === 0) { this._selectTab(this._tabList.last); } } _selectTab(tab) { // deactivate all tabs this._tabList.toArray().forEach(tab => (tab.active = false)); // activate the tab the user has clicked on. tab.active = true; } selectTab(tab) { this.changeFn().then(res => !!res && this._selectTab(tab)); } ngOnDestroy() { this.isDestroyed = true; } addTab(tab) { this.tabs.push(tab); tab.active = this.tabs.length === 1 && tab.active !== false; } removeTab(tab, options = { reselect: true, emit: true }) { const index = this.tabs.indexOf(tab); if (index === -1 || this.isDestroyed) { return; } // Select a new tab if the tab to be removed is selected and not destroyed if (options.reselect && tab.active && this.hasAvailableTabs(index)) { const newActiveIndex = this.getClosestTabIndex(index); this.tabs[newActiveIndex].active = true; } if (options.emit) { tab.removed.emit(tab); } this.tabs.splice(index, 1); if (tab.elementRef.nativeElement && tab.elementRef.nativeElement.remove) { tab.elementRef.nativeElement.remove(); } } getStickyHeaderPosition() { return this.stickyHeader ? 'sticky' : 'relative'; } getClosestTabIndex(index) { const tabsLength = this.tabs.length; if (!tabsLength) { return -1; } for (let step = 1; step <= tabsLength; step += 1) { const prevIndex = index - step; const nextIndex = index + step; if (this.tabs[prevIndex] && !this.tabs[prevIndex].disabled) { return prevIndex; } if (this.tabs[nextIndex] && !this.tabs[nextIndex].disabled) { return nextIndex; } } return -1; } hasAvailableTabs(index) { const tabsLength = this.tabs.length; if (!tabsLength) { return false; } for (let i = 0; i < tabsLength; i += 1) { if (!this.tabs[i].disabled && i !== index) { return true; } } return false; } } TabsetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: TabsetComponent, deps: [{ token: i1.TabsetConfig }], target: i0.ɵɵFactoryTarget.Component }); TabsetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: TabsetComponent, selector: "hx-tabset", inputs: { vertical: "vertical", justified: "justified", hasInfo: "hasInfo", type: "type", contentCustomClass: "contentCustomClass", stickyHeader: "stickyHeader", stickyHeaderOffset: "stickyHeaderOffset", tag: "tag", changeFn: "changeFn" }, host: { classAttribute: "hx-tab-container" }, queries: [{ propertyName: "_tabList", predicate: i0.forwardRef(function () { return TabDirective; }) }], ngImport: i0, template: ` <ul class="hx-nav hx-nav-{{ type }}" [ngStyle]="{ position: getStickyHeaderPosition(), 'top.rem': stickyHeaderOffset }" [class.is-vertical]="vertical" [class.is-justified]="justified" [class.has-info]="hasInfo" > <li *ngFor="let tab of tabs" [ngClass]="['hx-nav-item', tab.customClass || '']" [class.is-active]="!!tab?.active" [class.is-disabled]="!!tab?.disabled" [class.is-button]="tag === 'button'" > <button *ngIf="tag === 'button'" class="hx-nav-link" [class.is-active]="!!tab?.active" [class.is-disabled]="!!tab?.disabled" [attr.disabled]="!!tab?.disabled ? '' : null" (click)="selectTab(tab)" > <span [ngTransclude]="tab.headingRef">{{ tab.heading }}</span> <span *ngIf="tab.removable"> <span (click)="removeTab(tab)" class="icon close-outline is-small" ></span> </span> </button> <a *ngIf="tag === 'link'" class="hx-nav-link" [class.is-active]="!!tab?.active" [class.is-disabled]="!!tab?.disabled" [attr.disabled]="!!tab?.disabled ? '' : null" (click)="selectTab(tab)" > <span [ngTransclude]="tab.headingRef">{{ tab.heading }}</span> <span *ngIf="tab.removable"> <span (click)="removeTab(tab)" class="icon close-outline is-small" ></span> </span> </a> </li> </ul> <div class="hx-tab-content {{ contentCustomClass }}"> <ng-content></ng-content> </div> `, isInline: true, styles: [":host,ul.hx-nav{background-color:inherit}button.hx-nav-link{border-width:0;border-bottom-width:1px;border-color:transparent;background-color:transparent;line-height:1.5;cursor:pointer}:where(.is-justified) .is-button.hx-nav-item{display:flex}:where(.is-justified .is-button) button.hx-nav-link{display:flex}\n"], directives: [{ type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTranscludeDirective, selector: "[ngTransclude]", inputs: ["ngTransclude"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: TabsetComponent, decorators: [{ type: Component, args: [{ selector: 'hx-tabset', host: { class: 'hx-tab-container', }, template: ` <ul class="hx-nav hx-nav-{{ type }}" [ngStyle]="{ position: getStickyHeaderPosition(), 'top.rem': stickyHeaderOffset }" [class.is-vertical]="vertical" [class.is-justified]="justified" [class.has-info]="hasInfo" > <li *ngFor="let tab of tabs" [ngClass]="['hx-nav-item', tab.customClass || '']" [class.is-active]="!!tab?.active" [class.is-disabled]="!!tab?.disabled" [class.is-button]="tag === 'button'" > <button *ngIf="tag === 'button'" class="hx-nav-link" [class.is-active]="!!tab?.active" [class.is-disabled]="!!tab?.disabled" [attr.disabled]="!!tab?.disabled ? '' : null" (click)="selectTab(tab)" > <span [ngTransclude]="tab.headingRef">{{ tab.heading }}</span> <span *ngIf="tab.removable"> <span (click)="removeTab(tab)" class="icon close-outline is-small" ></span> </span> </button> <a *ngIf="tag === 'link'" class="hx-nav-link" [class.is-active]="!!tab?.active" [class.is-disabled]="!!tab?.disabled" [attr.disabled]="!!tab?.disabled ? '' : null" (click)="selectTab(tab)" > <span [ngTransclude]="tab.headingRef">{{ tab.heading }}</span> <span *ngIf="tab.removable"> <span (click)="removeTab(tab)" class="icon close-outline is-small" ></span> </span> </a> </li> </ul> <div class="hx-tab-content {{ contentCustomClass }}"> <ng-content></ng-content> </div> `, styles: [ ` :host, ul.hx-nav { background-color: inherit; } button.hx-nav-link { border-width: 0; border-bottom-width: 1px; border-color: transparent; background-color: transparent; line-height: 1.5; cursor: pointer; } :where(.is-justified) .is-button.hx-nav-item { display: flex; } :where(.is-justified .is-button) button.hx-nav-link { display: flex; } `, ], }] }], ctorParameters: function () { return [{ type: i1.TabsetConfig }]; }, propDecorators: { vertical: [{ type: Input }], justified: [{ type: Input }], hasInfo: [{ type: Input }], type: [{ type: Input }], contentCustomClass: [{ type: Input }], stickyHeader: [{ type: Input }], stickyHeaderOffset: [{ type: Input }], tag: [{ type: Input }], changeFn: [{ type: Input }], _tabList: [{ type: ContentChildren, args: [forwardRef(() => TabDirective)] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFic2V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2h4LXVpL3NyYy9saWIvdGFicy90YWJzZXQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxTQUFTLEVBQ1QsZUFBZSxFQUNmLFVBQVUsRUFDVixLQUFLLEVBRUwsU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7O0FBeUYvQyxNQUFNLE9BQU8sZUFBZTtJQW1DMUIsWUFBWSxNQUFvQjtRQWxDaEMsNkNBQTZDO1FBQ3BDLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFFMUIsa0VBQWtFO1FBQ3pELGNBQVMsR0FBRyxLQUFLLENBQUM7UUFFbEIsWUFBTyxHQUFHLEtBQUssQ0FBQztRQVloQixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQix1QkFBa0IsR0FBRyxDQUFDLENBQUM7UUFFdkIsUUFBRyxHQUFzQixNQUFNLENBQUM7UUFHekMsYUFBUSxHQUFHLEtBQUssSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDO1FBSzVCLFNBQUksR0FBbUIsRUFBRSxDQUFDO1FBTXhCLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUE1QkQsa0RBQWtEO0lBQ2xELElBQ0ksSUFBSTtRQUNOLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsS0FBYTtRQUNwQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNyQixDQUFDO0lBdUJELGtCQUFrQjtRQUNoQixzQkFBc0I7UUFDdEIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxN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QUFFO3dCQUNKLEtBQUssRUFBRSxrQkFBa0I7cUJBQzFCO29CQUNELFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVEVDtvQkFDRCxNQUFNLEVBQUU7d0JBQ047Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0FzQkM7cUJBQ0Y7aUJBQ0Y7bUdBR1UsUUFBUTtzQkFBaEIsS0FBSztnQkFHRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFJRixJQUFJO3NCQURQLEtBQUs7Z0JBUUcsa0JBQWtCO3NCQUExQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUVHLEdBQUc7c0JBQVgsS0FBSztnQkFHTixRQUFRO3NCQURQLEtBQUs7Z0JBSUUsUUFBUTtzQkFEZixlQUFlO3VCQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEFmdGVyQ29udGVudEluaXQsXHJcbiAgQ29tcG9uZW50LFxyXG4gIENvbnRlbnRDaGlsZHJlbixcclxuICBmb3J3YXJkUmVmLFxyXG4gIElucHV0LFxyXG4gIE9uRGVzdHJveSxcclxuICBRdWVyeUxpc3QsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFRhYkRpcmVjdGl2ZSB9IGZyb20gJy4vdGFiLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IFRhYnNldENvbmZpZyB9IGZyb20gJy4vdGFic2V0LmNvbmZpZyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2h4LXRhYnNldCcsXHJcbiAgaG9zdDoge1xyXG4gICAgY2xhc3M6ICdoeC10YWItY29udGFpbmVyJyxcclxuICB9LFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8dWxcclxuICAgICAgY2xhc3M9XCJoeC1uYXYgaHgtbmF2LXt7IHR5cGUgfX1cIlxyXG4gICAgICBbbmdTdHlsZV09XCJ7XHJcbiAgICAgICAgcG9zaXRpb246IGdldFN0aWNreUhlYWRlclBvc2l0aW9uKCksXHJcbiAgICAgICAgJ3RvcC5yZW0nOiBzdGlja3lIZWFkZXJPZmZzZXRcclxuICAgICAgfVwiXHJcbiAgICAgIFtjbGFzcy5pcy12ZXJ0aWNhbF09XCJ2ZXJ0aWNhbFwiXHJcbiAgICAgIFtjbGFzcy5pcy1qdXN0aWZpZWRdPVwianVzdGlmaWVkXCJcclxuICAgICAgW2NsYXNzLmhhcy1pbmZvXT1cImhhc0luZm9cIlxyXG4gICAgPlxyXG4gICAgICA8bGlcclxuICAgICAgICAqbmdGb3I9XCJsZXQgdGFiIG9mIHRhYnNcIlxyXG4gICAgICAgIFtuZ0NsYXNzXT1cIlsnaHgtbmF2LWl0ZW0nLCB0YWIuY3VzdG9tQ2xhc3MgfHwgJyddXCJcclxuICAgICAgICBbY2xhc3MuaXMtYWN0aXZlXT1cIiEhdGFiPy5hY3RpdmVcIlxyXG4gICAgICAgIFtjbGFzcy5pcy1kaXNhYmxlZF09XCIhIXRhYj8uZGlzYWJsZWRcIlxyXG4gICAgICAgIFtjbGFzcy5pcy1idXR0b25dPVwidGFnID09PSAnYnV0dG9uJ1wiXHJcbiAgICAgID5cclxuICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAqbmdJZj1cInRhZyA9PT0gJ2J1dHRvbidcIlxyXG4gICAgICAgICAgY2xhc3M9XCJoeC1uYXYtbGlua1wiXHJcbiAgICAgICAgICBbY2xhc3MuaXMtYWN0aXZlXT1cIiEhdGFiPy5hY3RpdmVcIlxyXG4gICAgICAgICAgW2NsYXNzLmlzLWRpc2FibGVkXT1cIiEhdGFiPy5kaXNhYmxlZFwiXHJcbiAgICAgICAgICBbYXR0ci5kaXNhYmxlZF09XCIhIXRhYj8uZGlzYWJsZWQgPyAnJyA6IG51bGxcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFRhYih0YWIpXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8c3BhbiBbbmdUcmFuc2NsdWRlXT1cInRhYi5oZWFkaW5nUmVmXCI+e3sgdGFiLmhlYWRpbmcgfX08L3NwYW4+XHJcbiAgICAgICAgICA8c3BhbiAqbmdJZj1cInRhYi5yZW1vdmFibGVcIj5cclxuICAgICAgICAgICAgPHNwYW5cclxuICAgICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlVGFiKHRhYilcIlxyXG4gICAgICAgICAgICAgIGNsYXNzPVwiaWNvbiBjbG9zZS1vdXRsaW5lIGlzLXNtYWxsXCJcclxuICAgICAgICAgICAgPjwvc3Bhbj5cclxuICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8YVxyXG4gICAgICAgICAgKm5nSWY9XCJ0YWcgPT09ICdsaW5rJ1wiXHJcbiAgICAgICAgICBjbGFzcz1cImh4LW5hdi1saW5rXCJcclxuICAgICAgICAgIFtjbGFzcy5pcy1hY3RpdmVdPVwiISF0YWI/LmFjdGl2ZVwiXHJcbiAgICAgICAgICBbY2xhc3MuaXMtZGlzYWJsZWRdPVwiISF0YWI/LmRpc2FibGVkXCJcclxuICAgICAgICAgIFthdHRyLmRpc2FibGVkXT1cIiEhdGFiPy5kaXNhYmxlZCA/ICcnIDogbnVsbFwiXHJcbiAgICAgICAgICAoY2xpY2spPVwic2VsZWN0VGFiKHRhYilcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxzcGFuIFtuZ1RyYW5zY2x1ZGVdPVwidGFiLmhlYWRpbmdSZWZcIj57eyB0YWIuaGVhZGluZyB9fTwvc3Bhbj5cclxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwidGFiLnJlbW92YWJsZVwiPlxyXG4gICAgICAgICAgICA8c3BhblxyXG4gICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVUYWIodGFiKVwiXHJcbiAgICAgICAgICAgICAgY2xhc3M9XCJpY29uIGNsb3NlLW91dGxpbmUgaXMtc21hbGxcIlxyXG4gICAgICAgICAgICA+PC9zcGFuPlxyXG4gICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgIDwvYT5cclxuICAgICAgPC9saT5cclxuICAgIDwvdWw+XHJcbiAgICA8ZGl2IGNsYXNzPVwiaHgtdGFiLWNvbnRlbnQge3sgY29udGVudEN1c3RvbUNsYXNzIH19XCI+XHJcbiAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuICAgIDwvZGl2PlxyXG4gIGAsXHJcbiAgc3R5bGVzOiBbXHJcbiAgICBgXHJcbiAgICAgIDpob3N0LFxyXG4gICAgICB1bC5oeC1uYXYge1xyXG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IGluaGVyaXQ7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGJ1dHRvbi5oeC1uYXYtbGluayB7XHJcbiAgICAgICAgYm9yZGVyLXdpZHRoOiAwO1xyXG4gICAgICAgIGJvcmRlci1ib3R0b20td2lkdGg6IDFweDtcclxuICAgICAgICBib3JkZXItY29sb3I6IHRyYW5zcGFyZW50O1xyXG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xyXG4gICAgICAgIGxpbmUtaGVpZ2h0OiAxLjU7XHJcbiAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xyXG4gICAgICB9XHJcblxyXG4gICAgICA6d2hlcmUoLmlzLWp1c3RpZmllZCkgLmlzLWJ1dHRvbi5oeC1uYXYtaXRlbSB7XHJcbiAgICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgfVxyXG5cclxuICAgICAgOndoZXJlKC5pcy1qdXN0aWZpZWQgLmlzLWJ1dHRvbikgYnV0dG9uLmh4LW5hdi1saW5rIHtcclxuICAgICAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgICB9XHJcbiAgICBgLFxyXG4gIF0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUYWJzZXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIEFmdGVyQ29udGVudEluaXQge1xyXG4gIC8qKiBpZiB0cnVlIHRhYnMgd2lsbCBiZSBwbGFjZWQgdmVydGljYWxseSAqL1xyXG4gIEBJbnB1dCgpIHZlcnRpY2FsID0gZmFsc2U7XHJcblxyXG4gIC8qKiBpZiB0cnVlIHRhYnMgZmlsbCB0aGUgY29udGFpbmVyIGFuZCBoYXZlIGEgY29uc2lzdGVudCB3aWR0aCAqL1xyXG4gIEBJbnB1dCgpIGp1c3RpZmllZCA9IGZhbHNlO1xyXG5cclxuICBASW5wdXQoKSBoYXNJbmZvID0gZmFsc2U7XHJcblxyXG4gIC8qKiBuYXZpZ2F0aW9uIGNvbnRleHQgY2xhc3M6ICd0YWJzJyBvciAncGlsbHMnICovXHJcbiAgQElucHV0KClcclxuICBnZXQgdHlwZSgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuX3R5cGU7XHJcbiAgfVxyXG4gIHNldCB0eXBlKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuX3R5cGUgPSB2YWx1ZTtcclxuICB9XHJcblxyXG4gIEBJbnB1dCgpIGNvbnRlbnRDdXN0b21DbGFzczogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIHN0aWNreUhlYWRlciA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHN0aWNreUhlYWRlck9mZnNldCA9IDA7XHJcblxyXG4gIEBJbnB1dCgpIHRhZzogJ2xpbmsnIHwgJ2J1dHRvbicgPSAnbGluayc7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgY2hhbmdlRm4gPSBhc3luYyAoKSA9PiB0cnVlO1xyXG5cclxuICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gVGFiRGlyZWN0aXZlKSlcclxuICBwcml2YXRlIF90YWJMaXN0OiBRdWVyeUxpc3Q8VGFiRGlyZWN0aXZlPjtcclxuXHJcbiAgdGFiczogVGFiRGlyZWN0aXZlW10gPSBbXTtcclxuXHJcbiAgcHJvdGVjdGVkIGlzRGVzdHJveWVkOiBib29sZWFuO1xyXG4gIHByb3RlY3RlZCBfdHlwZTogc3RyaW5nO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFRhYnNldENvbmZpZykge1xyXG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBjb25maWcpO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xyXG4gICAgLy8gZ2V0IGFsbCBhY3RpdmUgdGFic1xyXG4gICAgY29uc3QgYWN0aXZlVGFicyA9IHRoaXMuX3RhYkxpc3QuZmlsdGVyKHRhYiA9PiB0YWIuYWN0aXZlKTtcclxuXHJcbiAgICAvLyBpZiB0aGVyZSBpcyBubyBhY3RpdmUgdGFiIHNldCwgYWN0aXZhdGUgdGhlIGZpcnN0XHJcbiAgICBpZiAoYWN0aXZlVGFicy5sZW5ndGggPT09IDApIHtcclxuICAgICAgdGhpcy5fc2VsZWN0VGFiKHRoaXMuX3RhYkxpc3QubGFzdCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9zZWxlY3RUYWIodGFiOiBUYWJEaXJlY3RpdmUpIHtcclxuICAgIC8vIGRlYWN0aXZhdGUgYWxsIHRhYnNcclxuICAgIHRoaXMuX3RhYkxpc3QudG9BcnJheSgpLmZvckVhY2godGFiID0+ICh0YWIuYWN0aXZlID0gZmFsc2UpKTtcclxuXHJcbiAgICAvLyBhY3RpdmF0ZSB0aGUgdGFiIHRoZSB1c2VyIGhhcyBjbGlja2VkIG9uLlxyXG4gICAgdGFiLmFjdGl2ZSA9IHRydWU7XHJcbiAgfVxyXG5cclxuICBzZWxlY3RUYWIodGFiOiBUYWJEaXJlY3RpdmUpIHtcclxuICAgIHRoaXMuY2hhbmdlRm4oKS50aGVuKHJlcyA9PiAhIXJlcyAmJiB0aGlzLl9zZWxlY3RUYWIodGFiKSk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMuaXNEZXN0cm95ZWQgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgYWRkVGFiKHRhYjogVGFiRGlyZWN0aXZlKTogdm9pZCB7XHJcbiAgICB0aGlzLnRhYnMucHVzaCh0YWIpO1xyXG4gICAgdGFiLmFjdGl2ZSA9IHRoaXMudGFicy5sZW5ndGggPT09IDEgJiYgdGFiLmFjdGl2ZSAhPT0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICByZW1vdmVUYWIodGFiOiBUYWJEaXJlY3RpdmUsIG9wdGlvbnMgPSB7IHJlc2VsZWN0OiB0cnVlLCBlbWl0OiB0cnVlIH0pOiB2b2lkIHtcclxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy50YWJzLmluZGV4T2YodGFiKTtcclxuICAgIGlmIChpbmRleCA9PT0gLTEgfHwgdGhpcy5pc0Rlc3Ryb3llZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICAvLyBTZWxlY3QgYSBuZXcgdGFiIGlmIHRoZSB0YWIgdG8gYmUgcmVtb3ZlZCBpcyBzZWxlY3RlZCBhbmQgbm90IGRlc3Ryb3llZFxyXG4gICAgaWYgKG9wdGlvbnMucmVzZWxlY3QgJiYgdGFiLmFjdGl2ZSAmJiB0aGlzLmhhc0F2YWlsYWJsZVRhYnMoaW5kZXgpKSB7XHJcbiAgICAgIGNvbnN0IG5ld0FjdGl2ZUluZGV4ID0gdGhpcy5nZXRDbG9zZXN0VGFiSW5kZXgoaW5kZXgpO1xyXG4gICAgICB0aGlzLnRhYnNbbmV3QWN0aXZlSW5kZXhdLmFjdGl2ZSA9IHRydWU7XHJcbiAgICB9XHJcbiAgICBpZiAob3B0aW9ucy5lbWl0KSB7XHJcbiAgICAgIHRhYi5yZW1vdmVkLmVtaXQodGFiKTtcclxuICAgIH1cclxuICAgIHRoaXMudGFicy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgaWYgKHRhYi5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgJiYgdGFiLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5yZW1vdmUpIHtcclxuICAgICAgdGFiLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5yZW1vdmUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldFN0aWNreUhlYWRlclBvc2l0aW9uKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5zdGlja3lIZWFkZXIgPyAnc3RpY2t5JyA6ICdyZWxhdGl2ZSc7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgZ2V0Q2xvc2VzdFRhYkluZGV4KGluZGV4OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgY29uc3QgdGFic0xlbmd0aCA9IHRoaXMudGFicy5sZW5ndGg7XHJcbiAgICBpZiAoIXRhYnNMZW5ndGgpIHtcclxuICAgICAgcmV0dXJuIC0xO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAobGV0IHN0ZXAgPSAxOyBzdGVwIDw9IHRhYnNMZW5ndGg7IHN0ZXAgKz0gMSkge1xyXG4gICAgICBjb25zdCBwcmV2SW5kZXggPSBpbmRleCAtIHN0ZXA7XHJcbiAgICAgIGNvbnN0IG5leHRJbmRleCA9IGluZGV4ICsgc3RlcDtcclxuICAgICAgaWYgKHRoaXMudGFic1twcmV2SW5kZXhdICYmICF0aGlzLnRhYnNbcHJldkluZGV4XS5kaXNhYmxlZCkge1xyXG4gICAgICAgIHJldHVybiBwcmV2SW5kZXg7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHRoaXMudGFic1tuZXh0SW5kZXhdICYmICF0aGlzLnRhYnNbbmV4dEluZGV4XS5kaXNhYmxlZCkge1xyXG4gICAgICAgIHJldHVybiBuZXh0SW5kZXg7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiAtMTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBoYXNBdmFpbGFibGVUYWJzKGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcclxuICAgIGNvbnN0IHRhYnNMZW5ndGggPSB0aGlzLnRhYnMubGVuZ3RoO1xyXG4gICAgaWYgKCF0YWJzTGVuZ3RoKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRhYnNMZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgICBpZiAoIXRoaXMudGFic1tpXS5kaXNhYmxlZCAmJiBpICE9PSBpbmRleCkge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG59XHJcbiJdfQ==