UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

264 lines 33.2 kB
import { Component, ElementRef, EventEmitter, HostBinding, HostListener, Inject, Input, Optional, Output, Renderer2, ViewChild } from '@angular/core'; import { KeyCode } from '@microsoft/windows-admin-center-sdk/core/data/accessibility-manager'; import { SME_LAYOUT_PROVIDER } from '../common/layout'; import { DropdownService } from './dropdown.service'; import * as i0 from "@angular/core"; import * as i1 from "./dropdown.service"; import * as i2 from "@angular/common"; const _c0 = ["smeDropdownContent"]; const _c1 = ["smeDropdownToggle"]; const _c2 = [[["", 8, "sme-dropdown-toggle"]], [["", 8, "sme-dropdown-content"]]]; const _c3 = function (a0, a1, a2, a3) { return { "sme-layout-hidden": a0, "sme-layout-inline-block": a1, "sme-arrange-overflow-auto-x": a2, "sme-arrange-overflow-auto-y": a3 }; }; const _c4 = [".sme-dropdown-toggle", ".sme-dropdown-content"]; /** * * @smeDoc {@label Dropdown @id sme-dropdown-component @internal} * * @overview * @file {@filepath ./examples/dropdown-overview.md} * * @example {@label Basic Usage @id basic-usage} * @file {@filename component.html @filepath ./examples/basic-usage.component.html} * * @example {@label Dropdown with advanced content @id advanced-dropdown} * @file {@filename component.html @filepath ./examples/advanced-dropdown.component.html} * @file {@filename component.ts @filepath ./examples/advanced-dropdown.component.ts} * */ /** * Component to create an dropdown */ export class DropdownComponent { /** * Initializes a new instance of the DropdownDirective */ constructor(renderer, element, dropdownService, layout) { this.renderer = renderer; this.element = element; this.dropdownService = dropdownService; this.layout = layout; this.toggled = new EventEmitter(); this.isContextMenu = false; /** * Determine if the dropdown will use the sme-form-field to limit its max-width */ this.dropdownApplyFormFieldOffsetWidth = true; /** * Indicates the open state of the dropdown */ this.isOpen = false; /** * Indicates how far the dropdown content has been translated to remain fully on screen */ this.left = 0; /** * Indicates how far the dropdown content has been translated to remain fully on screen */ this.top = 0; /** * Indicates if the dropdown is larger than the horizontal space available */ this.overflowX = false; /** * Indicates if the dropdown is larger than the vertical space available */ this.overflowY = false; /** * Indicates that dropdown should be disabled. */ this.disabled = false; renderer.addClass(element.nativeElement, 'sme-layout-relative'); this.autoToggle = true; } /** * Event Emitter for when the dropdown opens or closes. Emits a boolean to indicate if the dropdown is open * @deprecated since 9/25/2019. Please use 'toggled' instead */ // eslint-disable-next-line @angular-eslint/no-output-on-prefix get onToggled() { return this.toggled; } /** * Angulars On Init Lifecycle Hook */ ngOnInit() { if (this.layout) { this.layoutChangeSubscriber = this.layout.layoutChanged.subscribe(() => { // Use setTimeout to postponed the dropdown UI update to next refresh cycle. // This the current refresh cycle can be used for any components to update its own UI which may impact dropdown UI. setTimeout(() => { this.dropdownService.updatePosition(this, this.calculateHeight, this.displayToSide); }); }); } } ngAfterViewInit() { // load the context menu code here so as to allow all child views to be completely initialized if (!this.isContextMenu) { this.renderer.setAttribute(this.toggleElement.nativeElement, 'aria-haspopup', 'true'); this.unsubscribeToggleClick = this.renderer.listen(this.toggleElement.nativeElement, 'click', (event) => this.onToggleClick(event)); } else { this.dropdownService.open(this, this.calculateHeight, this.displayToSide).then(() => { this.isOpen = true; }); } } /** * Angulars On Destroy Lifecycle Hook */ ngOnDestroy() { this.close(); // this.unsubscribeToggleClick(); if (this.layoutChangeSubscriber) { this.layoutChangeSubscriber.unsubscribe(); } } /** * Opens this dropdown */ open() { this.toggle(true, this.calculateHeight, this.displayToSide); } /** * Listen to keyboard event and close dropdown when users do not focus on dropdown list */ onKeyup(event) { if (event.keyCode === KeyCode.Tab) { let element = event.target; while (!this.contentElement.nativeElement.isSameNode(element) && !this.element.nativeElement.isSameNode(element)) { if (element.classList.contains('sme-focus-trap')) { return; } element = element.parentElement; } this.close(event); } else if ((event.keyCode === KeyCode.LeftArrow && event.target.className.indexOf('sme-dropdown-toggle') > -1)) { this.close(event); } else if (event.keyCode === KeyCode.Escape) { // prevent event propagation when inside a dialog event.preventDefault(); event.stopPropagation(); event.stopImmediatePropagation(); } } /** * Closes this dropdown * @param event keyboard event including the current event target */ close(event) { this.toggle(false, null, this.displayToSide, event); } /** * Toggles the dropdown * @param open Optional. If provided, forces the dropdown open or closed. */ toggle(open, calculateHeight, displayToSide, event) { // If we are already in the correct state, return if (!MsftSme.isNullOrUndefined(open) && open === this.isOpen) { return; } if (this.isOpen) { // close if opened this.dropdownService.close(this); this.renderer.setAttribute(this.toggleElement.nativeElement, 'aria-expanded', 'false'); if (event) { this.dropdownService.closeNested(this, event); } // emit the current state of the dropdown this.onToggled.emit(this.isOpen); } else { // open if closed this.dropdownService.open(this, calculateHeight, displayToSide).then(() => { this.renderer.setAttribute(this.toggleElement.nativeElement, 'aria-expanded', 'true'); this.toggleElement.nativeElement.addEventListener('closeEvent', () => { this.isOpen = false; }, false); // emit the current state of the dropdown this.onToggled.emit(this.isOpen); }); } } /** * Handler for the click event for the toggle element * @param event the mouse event of the click * @param manualToggle determine whether this is manually toggle */ onToggleClick(event, manualToggle) { event.stopPropagation(); if (this.autoToggle || manualToggle) { // toggle the dropdown if not disabled if (!this.disabled) { this.toggle(null, this.calculateHeight, this.displayToSide); } } return false; } } /** @nocollapse */ DropdownComponent.ɵfac = function DropdownComponent_Factory(t) { return new (t || DropdownComponent)(i0.ɵɵdirectiveInject(i0.Renderer2), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.DropdownService), i0.ɵɵdirectiveInject(SME_LAYOUT_PROVIDER, 8)); }; /** @nocollapse */ DropdownComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: DropdownComponent, selectors: [["sme-dropdown"]], viewQuery: function DropdownComponent_Query(rf, ctx) { if (rf & 1) { i0.ɵɵviewQuery(_c0, 5); i0.ɵɵviewQuery(_c1, 7); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.contentElement = _t.first); i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.toggleElement = _t.first); } }, hostVars: 2, hostBindings: function DropdownComponent_HostBindings(rf, ctx) { if (rf & 1) { i0.ɵɵlistener("keyup", function DropdownComponent_keyup_HostBindingHandler($event) { return ctx.onKeyup($event); }); } if (rf & 2) { i0.ɵɵclassProp("sme-disabled", ctx.disabled); } }, inputs: { autoToggle: "autoToggle", autoWidth: "autoWidth", calculateHeight: "calculateHeight", displayToSide: "displayToSide", isContextMenu: "isContextMenu", dropdownApplyFormFieldOffsetWidth: "dropdownApplyFormFieldOffsetWidth", disabled: "disabled" }, outputs: { onToggled: "onToggled", toggled: "toggled" }, ngContentSelectors: _c4, decls: 6, vars: 6, consts: [["data-uta-id", "dropdown-toggle", 1, "sme-dropdown-toggle-container"], ["smeDropdownToggle", ""], ["data-uta-id", "dropdown-content", 1, "sme-layout-dropdown", "sme-layout-fixed", "sme-position-below", "sme-scheme-dropdown", "sme-layer-nav", "sme-shadow-dropdown", 3, "ngClass"], ["smeDropdownContent", ""]], template: function DropdownComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵprojectionDef(_c2); i0.ɵɵelementStart(0, "div", 0, 1); i0.ɵɵprojection(2); i0.ɵɵelementEnd(); i0.ɵɵelementStart(3, "div", 2, 3); i0.ɵɵprojection(5, 1); i0.ɵɵelementEnd(); } if (rf & 2) { i0.ɵɵadvance(3); i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction4(1, _c3, !ctx.isOpen, ctx.isOpen, ctx.overflowX, ctx.overflowY)); } }, dependencies: [i2.NgClass], encapsulation: 2 }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DropdownComponent, [{ type: Component, args: [{ selector: 'sme-dropdown', template: "<div #smeDropdownToggle class=\"sme-dropdown-toggle-container\" data-uta-id=\"dropdown-toggle\">\r\n <ng-content select=\".sme-dropdown-toggle\"></ng-content>\r\n</div>\r\n<div #smeDropdownContent\r\n class=\"sme-layout-dropdown sme-layout-fixed sme-position-below sme-scheme-dropdown sme-layer-nav sme-shadow-dropdown\"\r\n [ngClass]=\"{'sme-layout-hidden': !isOpen, 'sme-layout-inline-block': isOpen, 'sme-arrange-overflow-auto-x': overflowX, 'sme-arrange-overflow-auto-y': overflowY}\"\r\n data-uta-id=\"dropdown-content\">\r\n <ng-content select=\".sme-dropdown-content\"></ng-content>\r\n</div>\r\n" }] }], function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.DropdownService }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [SME_LAYOUT_PROVIDER] }] }]; }, { onToggled: [{ type: Output }], toggled: [{ type: Output }], autoToggle: [{ type: Input }], autoWidth: [{ type: Input }], calculateHeight: [{ type: Input }], displayToSide: [{ type: Input }], isContextMenu: [{ type: Input }], contentElement: [{ type: ViewChild, args: ['smeDropdownContent'] }], toggleElement: [{ type: ViewChild, args: ['smeDropdownToggle', { static: true }] }], dropdownApplyFormFieldOffsetWidth: [{ type: Input }], disabled: [{ type: HostBinding, args: ['class.sme-disabled'] }, { type: Input }], onKeyup: [{ type: HostListener, args: ['keyup', ['$event']] }] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvZHJvcGRvd24vZHJvcGRvd24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvZHJvcGRvd24vZHJvcGRvd24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVILFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFdBQVcsRUFDWCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFFQUFxRSxDQUFDO0FBQzlGLE9BQU8sRUFBVSxtQkFBbUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQy9ELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7Ozs7Ozs7O0FBR3JEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBRUg7O0dBRUc7QUFLSCxNQUFNLE9BQU8saUJBQWlCO0lBd0YxQjs7T0FFRztJQUNILFlBQ1ksUUFBbUIsRUFDbkIsT0FBbUIsRUFDbkIsZUFBZ0MsRUFDUyxNQUFjO1FBSHZELGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsWUFBTyxHQUFQLE9BQU8sQ0FBWTtRQUNuQixvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDUyxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBcEZsRCxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQXlCaEQsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFhN0I7O1dBRUc7UUFFSSxzQ0FBaUMsR0FBRyxJQUFJLENBQUM7UUFFaEQ7O1dBRUc7UUFDSSxXQUFNLEdBQUcsS0FBSyxDQUFDO1FB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QyxDQUFDO2FBQy9EO1NBQ0o7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDOztxR0FwT1EsaUJBQWlCLDBJQStGRixtQkFBbUI7bUdBL0ZsQyxpQkFBaUI7Ozs7Ozs7O29HQUFqQixtQkFBZTs7Ozs7UUM1QzVCLGlDQUE0RjtRQUMxRixrQkFBdUQ7UUFDekQsaUJBQU07UUFDTixpQ0FHaUM7UUFDL0IscUJBQXdEO1FBQzFELGlCQUFNOztRQUhKLGVBQWlLO1FBQWpLLDJHQUFpSzs7dUZEdUN0SixpQkFBaUI7Y0FKN0IsU0FBUzsyQkFDSSxjQUFjOztzQkFrR25CLFFBQVE7O3NCQUFJLE1BQU07dUJBQUMsbUJBQW1CO3dCQXZGdEIsU0FBUztrQkFBN0IsTUFBTTtZQUdVLE9BQU87a0JBQXZCLE1BQU07WUFLUyxVQUFVO2tCQUF6QixLQUFLO1lBS1UsU0FBUztrQkFBeEIsS0FBSztZQU1DLGVBQWU7a0JBRHJCLEtBQUs7WUFPQyxhQUFhO2tCQURuQixLQUFLO1lBSUMsYUFBYTtrQkFEbkIsS0FBSztZQU1DLGNBQWM7a0JBRHBCLFNBQVM7bUJBQUMsb0JBQW9CO1lBT3hCLGFBQWE7a0JBRG5CLFNBQVM7bUJBQUMsbUJBQW1CLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO1lBT3pDLGlDQUFpQztrQkFEdkMsS0FBSztZQWdDVSxRQUFRO2tCQUR2QixXQUFXO21CQUFDLG9CQUFvQjs7a0JBQ2hDLEtBQUs7WUFtRUMsT0FBTztrQkFEYixZQUFZO21CQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgICBBZnRlclZpZXdJbml0LFxyXG4gICAgQ29tcG9uZW50LFxyXG4gICAgRWxlbWVudFJlZixcclxuICAgIEV2ZW50RW1pdHRlcixcclxuICAgIEhvc3RCaW5kaW5nLFxyXG4gICAgSG9zdExpc3RlbmVyLFxyXG4gICAgSW5qZWN0LFxyXG4gICAgSW5wdXQsXHJcbiAgICBPbkRlc3Ryb3ksXHJcbiAgICBPbkluaXQsXHJcbiAgICBPcHRpb25hbCxcclxuICAgIE91dHB1dCxcclxuICAgIFJlbmRlcmVyMixcclxuICAgIFZpZXdDaGlsZFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBLZXlDb2RlIH0gZnJvbSAnQG1pY3Jvc29mdC93aW5kb3dzLWFkbWluLWNlbnRlci1zZGsvY29yZS9kYXRhL2FjY2Vzc2liaWxpdHktbWFuYWdlcic7XHJcbmltcG9ydCB7IExheW91dCwgU01FX0xBWU9VVF9QUk9WSURFUiB9IGZyb20gJy4uL2NvbW1vbi9sYXlvdXQnO1xyXG5pbXBvcnQgeyBEcm9wZG93blNlcnZpY2UgfSBmcm9tICcuL2Ryb3Bkb3duLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBEcm9wZG93biB9IGZyb20gJy4vbW9kZWxzJztcclxuXHJcbi8qKlxyXG4gKlxyXG4gKiBAc21lRG9jIHtAbGFiZWwgRHJvcGRvd24gQGlkIHNtZS1kcm9wZG93bi1jb21wb25lbnQgQGludGVybmFsfVxyXG4gKlxyXG4gKiBAb3ZlcnZpZXdcclxuICogQGZpbGUge0BmaWxlcGF0aCAuL2V4YW1wbGVzL2Ryb3Bkb3duLW92ZXJ2aWV3Lm1kfVxyXG4gKlxyXG4gKiBAZXhhbXBsZSB7QGxhYmVsIEJhc2ljIFVzYWdlIEBpZCBiYXNpYy11c2FnZX1cclxuICogQGZpbGUge0BmaWxlbmFtZSBjb21wb25lbnQuaHRtbCBAZmlsZXBhdGggLi9leGFtcGxlcy9iYXNpYy11c2FnZS5jb21wb25lbnQuaHRtbH1cclxuICpcclxuICogQGV4YW1wbGUge0BsYWJlbCBEcm9wZG93biB3aXRoIGFkdmFuY2VkIGNvbnRlbnQgQGlkIGFkdmFuY2VkLWRyb3Bkb3dufVxyXG4gKiBAZmlsZSB7QGZpbGVuYW1lIGNvbXBvbmVudC5odG1sIEBmaWxlcGF0aCAuL2V4YW1wbGVzL2FkdmFuY2VkLWRyb3Bkb3duLmNvbXBvbmVudC5odG1sfVxyXG4gKiBAZmlsZSB7QGZpbGVuYW1lIGNvbXBvbmVudC50cyBAZmlsZXBhdGggLi9leGFtcGxlcy9hZHZhbmNlZC1kcm9wZG93bi5jb21wb25lbnQudHN9XHJcbiAqXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIENvbXBvbmVudCB0byBjcmVhdGUgYW4gZHJvcGRvd25cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdzbWUtZHJvcGRvd24nLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2Ryb3Bkb3duLmNvbXBvbmVudC5odG1sJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRHJvcGRvd25Db21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uSW5pdCwgRHJvcGRvd24sIEFmdGVyVmlld0luaXQge1xyXG4gICAgcHJpdmF0ZSBsYXlvdXRDaGFuZ2VTdWJzY3JpYmVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXZlbnQgRW1pdHRlciBmb3Igd2hlbiB0aGUgZHJvcGRvd24gb3BlbnMgb3IgY2xvc2VzLiBFbWl0cyBhIGJvb2xlYW4gdG8gaW5kaWNhdGUgaWYgdGhlIGRyb3Bkb3duIGlzIG9wZW5cclxuICAgICAqIEBkZXByZWNhdGVkIHNpbmNlIDkvMjUvMjAxOS4gUGxlYXNlIHVzZSAndG9nZ2xlZCcgaW5zdGVhZFxyXG4gICAgICovXHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L25vLW91dHB1dC1vbi1wcmVmaXhcclxuICAgIEBPdXRwdXQoKSBwdWJsaWMgZ2V0IG9uVG9nZ2xlZCgpOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRvZ2dsZWQ7XHJcbiAgICB9XHJcbiAgICBAT3V0cHV0KCkgcHVibGljIHRvZ2dsZWQgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJdCBpbmRpY2F0ZXMgc2hvdWxkIGF1dG9tYXRpY2FsbHkgdG9nZ2xlIHRvIGRyb3Bkb3duIHdoZW4gdGhlIHRvZ2dsZSBlbGVtZW50IGlzIGNsaWNrZWQuIERlZmF1bHRzIHRvIHRydWVcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgcHVibGljIGF1dG9Ub2dnbGU6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJdCBpbmRpY2F0ZXMgd2hldGhlciB0byBzZXQgdGhlIGRyb3Bkb3duIGNvbnRlbnQgd2lkdGggdG8gYmUgYmFzZWQgb24gdGhlIGFjdHVhbCBjb250ZW50XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIHB1YmxpYyBhdXRvV2lkdGg6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJdCBkZXRlcm1pbmUgd2hldGhlciB0byBjYWxjdWxhdGUgaGVpZ2h0IGZvciB0aGUgZHJvcGRvd25cclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBjYWxjdWxhdGVIZWlnaHQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJdCBkZXRlcm1pbmVzIHdoZXRoZXIgdG8gZGlzcGxheSBkcm9wZG93biBtZW51IHRvIHNpZGUgb2YgdG9nZ2xlLiBEZWZhdWx0cyB0byBiZWxvd1xyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGRpc3BsYXlUb1NpZGU6IGJvb2xlYW47XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBpc0NvbnRleHRNZW51ID0gZmFsc2U7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBjb250ZW50IGVsZW1lbnQuIFRoaXMgbXVzdCBiZSBwcm92aWRlZCBieSB0aGUgRHJvcGRvd25Db250ZW50RGlyZWN0aXZlIG9yIHBvc3NpYmx5IHNvbWUgY3VzdG9tIGltcGxlbWVudGF0aW9uXHJcbiAgICAgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ3NtZURyb3Bkb3duQ29udGVudCcpXHJcbiAgICBwdWJsaWMgY29udGVudEVsZW1lbnQ6IEVsZW1lbnRSZWY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgdG9nZ2xlIGVsZW1lbnQuIFRoaXMgbXVzdCBiZSBwcm92aWRlZCBieSB0aGUgRHJvcGRvd25Ub2dnbGVEaXJlY3RpdmUgb3IgcG9zc2libHkgc29tZSBjdXN0b20gaW1wbGVtZW50YXRpb25cclxuICAgICAqL1xyXG4gICAgQFZpZXdDaGlsZCgnc21lRHJvcGRvd25Ub2dnbGUnLCB7IHN0YXRpYzogdHJ1ZSB9KVxyXG4gICAgcHVibGljIHRvZ2dsZUVsZW1lbnQ6IEVsZW1lbnRSZWY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIGRyb3Bkb3duIHdpbGwgdXNlIHRoZSBzbWUtZm9ybS1maWVsZCB0byBsaW1pdCBpdHMgbWF4LXdpZHRoXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZHJvcGRvd25BcHBseUZvcm1GaWVsZE9mZnNldFdpZHRoID0gdHJ1ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYXRlcyB0aGUgb3BlbiBzdGF0ZSBvZiB0aGUgZHJvcGRvd25cclxuICAgICAqL1xyXG4gICAgcHVibGljIGlzT3BlbiA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhdGVzIGhvdyBmYXIgdGhlIGRyb3Bkb3duIGNvbnRlbnQgaGFzIGJlZW4gdHJhbnNsYXRlZCB0byByZW1haW4gZnVsbHkgb24gc2NyZWVuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsZWZ0ID0gMDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYXRlcyBob3cgZmFyIHRoZSBkcm9wZG93biBjb250ZW50IGhhcyBiZWVuIHRyYW5zbGF0ZWQgdG8gcmVtYWluIGZ1bGx5IG9uIHNjcmVlblxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdG9wID0gMDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYXRlcyBpZiB0aGUgZHJvcGRvd24gaXMgbGFyZ2VyIHRoYW4gdGhlIGhvcml6b250YWwgc3BhY2UgYXZhaWxhYmxlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvdmVyZmxvd1ggPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYXRlcyBpZiB0aGUgZHJvcGRvd24gaXMgbGFyZ2VyIHRoYW4gdGhlIHZlcnRpY2FsIHNwYWNlIGF2YWlsYWJsZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3ZlcmZsb3dZID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbmRpY2F0ZXMgdGhhdCBkcm9wZG93biBzaG91bGQgYmUgZGlzYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIEBIb3N0QmluZGluZygnY2xhc3Muc21lLWRpc2FibGVkJylcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBkaXNhYmxlZCA9IGZhbHNlO1xyXG5cclxuICAgIHByaXZhdGUgdW5zdWJzY3JpYmVUb2dnbGVDbGljazogRnVuY3Rpb247XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgRHJvcGRvd25EaXJlY3RpdmVcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxyXG4gICAgICAgIHByaXZhdGUgZWxlbWVudDogRWxlbWVudFJlZixcclxuICAgICAgICBwcml2YXRlIGRyb3Bkb3duU2VydmljZTogRHJvcGRvd25TZXJ2aWNlLFxyXG4gICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU01FX0xBWU9VVF9QUk9WSURFUikgcHJpdmF0ZSBsYXlvdXQ6IExheW91dCkge1xyXG4gICAgICAgIHJlbmRlcmVyLmFkZENsYXNzKGVsZW1lbnQubmF0aXZlRWxlbWVudCwgJ3NtZS1sYXlvdXQtcmVsYXRpdmUnKTtcclxuICAgICAgICB0aGlzLmF1dG9Ub2dnbGUgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgKiBBbmd1bGFycyBPbiBJbml0IExpZmVjeWNsZSBIb29rXHJcbiAgICAqL1xyXG4gICAgcHVibGljIG5nT25Jbml0KCkge1xyXG4gICAgICAgIGlmICh0aGlzLmxheW91dCkge1xyXG4gICAgICAgICAgICB0aGlzLmxheW91dENoYW5nZVN1YnNjcmliZXIgPSB0aGlzLmxheW91dC5sYXlvdXRDaGFuZ2VkLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBVc2Ugc2V0VGltZW91dCB0byBwb3N0cG9uZWQgdGhlIGRyb3Bkb3duIFVJIHVwZGF0ZSB0byBuZXh0IHJlZnJlc2ggY3ljbGUuXHJcbiAgICAgICAgICAgICAgICAvLyBUaGlzIHRoZSBjdXJyZW50IHJlZnJlc2ggY3ljbGUgY2FuIGJlIHVzZWQgZm9yIGFueSBjb21wb25lbnRzIHRvIHVwZGF0ZSBpdHMgb3duIFVJIHdoaWNoIG1heSBpbXBhY3QgZHJvcGRvd24gVUkuXHJcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyb3Bkb3duU2VydmljZS51cGRhdGVQb3NpdGlvbih0aGlzLCB0aGlzLmNhbGN1bGF0ZUhlaWdodCwgdGhpcy5kaXNwbGF5VG9TaWRlKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgICAgICAvLyBsb2FkIHRoZSBjb250ZXh0IG1lbnUgY29kZSBoZXJlIHNvIGFzIHRvIGFsbG93IGFsbCBjaGlsZCB2aWV3cyB0byBiZSBjb21wbGV0ZWx5IGluaXRpYWxpemVkXHJcbiAgICAgICAgaWYgKCF0aGlzLmlzQ29udGV4dE1lbnUpIHtcclxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUodGhpcy50b2dnbGVFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsICdhcmlhLWhhc3BvcHVwJywgJ3RydWUnKTtcclxuICAgICAgICAgICAgdGhpcy51bnN1YnNjcmliZVRvZ2dsZUNsaWNrID0gdGhpcy5yZW5kZXJlci5saXN0ZW4odGhpcy50b2dnbGVFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsICdjbGljaycsXHJcbiAgICAgICAgICAgICAgICAoZXZlbnQpID0+IHRoaXMub25Ub2dnbGVDbGljayhldmVudCkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZHJvcGRvd25TZXJ2aWNlLm9wZW4odGhpcywgdGhpcy5jYWxjdWxhdGVIZWlnaHQsIHRoaXMuZGlzcGxheVRvU2lkZSkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzT3BlbiA9IHRydWU7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFuZ3VsYXJzIE9uIERlc3Ryb3kgTGlmZWN5Y2xlIEhvb2tcclxuICAgICAqL1xyXG4gICAgcHVibGljIG5nT25EZXN0cm95KCkge1xyXG4gICAgICAgIHRoaXMuY2xvc2UoKTtcclxuICAgICAgICAvLyB0aGlzLnVuc3Vic2NyaWJlVG9nZ2xlQ2xpY2soKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMubGF5b3V0Q2hhbmdlU3Vic2NyaWJlcikge1xyXG4gICAgICAgICAgICB0aGlzLmxheW91dENoYW5nZVN1YnNjcmliZXIudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPcGVucyB0aGlzIGRyb3Bkb3duXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcGVuKCkge1xyXG4gICAgICAgIHRoaXMudG9nZ2xlKHRydWUsIHRoaXMuY2FsY3VsYXRlSGVpZ2h0LCB0aGlzLmRpc3BsYXlUb1NpZGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTGlzdGVuIHRvIGtleWJvYXJkIGV2ZW50IGFuZCBjbG9zZSBkcm9wZG93biB3aGVuIHVzZXJzIGRvIG5vdCBmb2N1cyBvbiBkcm9wZG93biBsaXN0XHJcbiAgICAgKi9cclxuICAgIEBIb3N0TGlzdGVuZXIoJ2tleXVwJywgWyckZXZlbnQnXSlcclxuICAgIHB1YmxpYyBvbktleXVwKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XHJcbiAgICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IEtleUNvZGUuVGFiKSB7XHJcbiAgICAgICAgICAgIGxldCBlbGVtZW50ID0gPEhUTUxFbGVtZW50PmV2ZW50LnRhcmdldDtcclxuICAgICAgICAgICAgd2hpbGUgKCF0aGlzLmNvbnRlbnRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuaXNTYW1lTm9kZShlbGVtZW50KSAmJiAhdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQuaXNTYW1lTm9kZShlbGVtZW50KSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdzbWUtZm9jdXMtdHJhcCcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50RWxlbWVudDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmNsb3NlKGV2ZW50KTtcclxuICAgICAgICB9IGVsc2UgaWYgKChldmVudC5rZXlDb2RlID09PSBLZXlDb2RlLkxlZnRBcnJvdyAmJiAoPEhUTUxFbGVtZW50PmV2ZW50LnRhcmdldCkuY2xhc3NOYW1lLmluZGV4T2YoJ3NtZS1kcm9wZG93bi10b2dnbGUnKSA+IC0xKSkge1xyXG4gICAgICAgICAgICB0aGlzLmNsb3NlKGV2ZW50KTtcclxuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleUNvZGUgPT09IEtleUNvZGUuRXNjYXBlKSB7XHJcbiAgICAgICAgICAgIC8vIHByZXZlbnQgZXZlbnQgcHJvcGFnYXRpb24gd2hlbiBpbnNpZGUgYSBkaWFsb2dcclxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENsb3NlcyB0aGlzIGRyb3Bkb3duXHJcbiAgICAgKiBAcGFyYW0gZXZlbnQga2V5Ym9hcmQgZXZlbnQgaW5jbHVkaW5nIHRoZSBjdXJyZW50IGV2ZW50IHRhcmdldFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY2xvc2UoZXZlbnQ/OiBLZXlib2FyZEV2ZW50KSB7XHJcbiAgICAgICAgdGhpcy50b2dnbGUoZmFsc2UsIG51bGwsIHRoaXMuZGlzcGxheVRvU2lkZSwgZXZlbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVG9nZ2xlcyB0aGUgZHJvcGRvd25cclxuICAgICAqIEBwYXJhbSBvcGVuIE9wdGlvbmFsLiBJZiBwcm92aWRlZCwgZm9yY2VzIHRoZSBkcm9wZG93biBvcGVuIG9yIGNsb3NlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHRvZ2dsZShvcGVuPzogYm9vbGVhbiwgY2FsY3VsYXRlSGVpZ2h0PzogYm9vbGVhbiwgZGlzcGxheVRvU2lkZT86IGJvb2xlYW4sIGV2ZW50PzogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgICAgIC8vIElmIHdlIGFyZSBhbHJlYWR5IGluIHRoZSBjb3JyZWN0IHN0YXRlLCByZXR1cm5cclxuICAgICAgICBpZiAoIU1zZnRTbWUuaXNOdWxsT3JVbmRlZmluZWQob3BlbikgJiYgb3BlbiA9PT0gdGhpcy5pc09wZW4pIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaXNPcGVuKSB7XHJcbiAgICAgICAgICAgIC8vIGNsb3NlIGlmIG9wZW5lZFxyXG4gICAgICAgICAgICB0aGlzLmRyb3Bkb3duU2VydmljZS5jbG9zZSh0aGlzKTtcclxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUodGhpcy50b2dnbGVFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsICdhcmlhLWV4cGFuZGVkJywgJ2ZhbHNlJyk7XHJcbiAgICAgICAgICAgIGlmIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kcm9wZG93blNlcnZpY2UuY2xvc2VOZXN0ZWQodGhpcywgZXZlbnQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGVtaXQgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGRyb3Bkb3duXHJcbiAgICAgICAgICAgIHRoaXMub25Ub2dnbGVkLmVtaXQodGhpcy5pc09wZW4pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIG9wZW4gaWYgY2xvc2VkXHJcbiAgICAgICAgICAgIHRoaXMuZHJvcGRvd25TZXJ2aWNlLm9wZW4odGhpcywgY2FsY3VsYXRlSGVpZ2h0LCBkaXNwbGF5VG9TaWRlKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHRoaXMudG9nZ2xlRWxlbWVudC5uYXRpdmVFbGVtZW50LCAnYXJpYS1leHBhbmRlZCcsICd0cnVlJyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZUVsZW1lbnQubmF0aXZlRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbG9zZUV2ZW50JywgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9LCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAvLyBlbWl0IHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBkcm9wZG93blxyXG4gICAgICAgICAgICAgICAgdGhpcy5vblRvZ2dsZWQuZW1pdCh0aGlzLmlzT3Blbik7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVyIGZvciB0aGUgY2xpY2sgZXZlbnQgZm9yIHRoZSB0b2dnbGUgZWxlbWVudFxyXG4gICAgICogQHBhcmFtIGV2ZW50IHRoZSBtb3VzZSBldmVudCBvZiB0aGUgY2xpY2tcclxuICAgICAqIEBwYXJhbSBtYW51YWxUb2dnbGUgZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBpcyBtYW51YWxseSB0b2dnbGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uVG9nZ2xlQ2xpY2soZXZlbnQ6IGFueSwgbWFudWFsVG9nZ2xlPzogYm9vbGVhbikge1xyXG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5hdXRvVG9nZ2xlIHx8IG1hbnVhbFRvZ2dsZSkge1xyXG4gICAgICAgICAgICAvLyB0b2dnbGUgdGhlIGRyb3Bkb3duIGlmIG5vdCBkaXNhYmxlZFxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzYWJsZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlKG51bGwsIHRoaXMuY2FsY3VsYXRlSGVpZ2h0LCB0aGlzLmRpc3BsYXlUb1NpZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbn1cclxuIiwiPGRpdiAjc21lRHJvcGRvd25Ub2dnbGUgY2xhc3M9XCJzbWUtZHJvcGRvd24tdG9nZ2xlLWNvbnRhaW5lclwiIGRhdGEtdXRhLWlkPVwiZHJvcGRvd24tdG9nZ2xlXCI+XHJcbiAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiLnNtZS1kcm9wZG93bi10b2dnbGVcIj48L25nLWNvbnRlbnQ+XHJcbjwvZGl2PlxyXG48ZGl2ICNzbWVEcm9wZG93bkNvbnRlbnRcclxuICBjbGFzcz1cInNtZS1sYXlvdXQtZHJvcGRvd24gc21lLWxheW91dC1maXhlZCBzbWUtcG9zaXRpb24tYmVsb3cgc21lLXNjaGVtZS1kcm9wZG93biBzbWUtbGF5ZXItbmF2IHNtZS1zaGFkb3ctZHJvcGRvd25cIlxyXG4gIFtuZ0NsYXNzXT1cInsnc21lLWxheW91dC1oaWRkZW4nOiAhaXNPcGVuLCAnc21lLWxheW91dC1pbmxpbmUtYmxvY2snOiBpc09wZW4sICdzbWUtYXJyYW5nZS1vdmVyZmxvdy1hdXRvLXgnOiBvdmVyZmxvd1gsICdzbWUtYXJyYW5nZS1vdmVyZmxvdy1hdXRvLXknOiBvdmVyZmxvd1l9XCJcclxuICBkYXRhLXV0YS1pZD1cImRyb3Bkb3duLWNvbnRlbnRcIj5cclxuICA8bmctY29udGVudCBzZWxlY3Q9XCIuc21lLWRyb3Bkb3duLWNvbnRlbnRcIj48L25nLWNvbnRlbnQ+XHJcbjwvZGl2PlxyXG4iXX0=