UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

261 lines 33.6 kB
import { Component, ContentChildren, ElementRef, HostListener, Input, QueryList, Renderer2, ViewChild } from '@angular/core'; import { KeyCode } from '@microsoft/windows-admin-center-sdk/core/data/accessibility-manager'; import { DropdownComponent } from '../../../dropdown/dropdown.component'; import { ActionBarComponent } from '../../containers/action-bar/action-bar.component'; import { ActionItem, ActionItemComponent, ActionItemRendererComponent } from '../action-item.component'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "../../../dropdown/dropdown.component"; import * as i3 from "../../../../directives/disabled/disabled.directive"; import * as i4 from "../../../tooltip/tooltip.directive"; import * as i5 from "../../containers/action-menu/action-menu.component"; import * as i6 from "../../containers/action-bar/action-bar.component"; const _c0 = ["dropDown"]; const _c1 = ["dropDownButton"]; function ActionDropdownRendererComponent_p_4_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "p", 10); i0.ɵɵtext(1); i0.ɵɵelementEnd(); } if (rf & 2) { const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵadvance(1); i0.ɵɵtextInterpolate(ctx_r2.actionTitle); } } function ActionDropdownRendererComponent_span_8_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelement(0, "span", 11); } } function ActionDropdownRendererComponent_span_9_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelement(0, "span", 12); } } const _c2 = ["action"]; export class ActionDropdown extends ActionItem { /** * Constructor for ActionDropdown. */ constructor() { super(ActionDropdownRendererComponent); } } export class ActionDropdownRendererComponent extends ActionItemRendererComponent { /** * Constructor of ActionDropdownRendererComponent. */ constructor(renderer, hostElement) { super(); this.renderer = renderer; this.hostElement = hostElement; this.isHovering = false; renderer.addClass(hostElement.nativeElement, 'sme-position-stretch'); } get actionTitle() { return this.item.name && this.item.name !== this.item.text ? this.item.name : null; } get actionDropdownId() { return this.item.actionId; } get actionDropdownUtaId() { return this.item.actionId + ActionDropdownRendererComponent.dropdownUtaIdSuffix; } /** * Method called to register a change with the ActionButton. * @param item The ActionButton to register change for. */ itemChanged(item) { super.itemChanged(item); } ngDoCheck() { const offsetWidth = this.hostElement.nativeElement.offsetWidth; if (offsetWidth === 0) { return; } // It looks like the CSS icon isn't being included in the offsetWidth, nor the clientWidth. // Adding here for simplicity and clarity. const cssIconWidth = 14; const calculatedWidth = offsetWidth + cssIconWidth; if (this.item.width !== calculatedWidth) { this.item.width = calculatedWidth; } } /** * Host listener to handle keyboard events. */ onToggleKeydown(event) { // accessibility, take focus to the action button after a selection in dropdown elements. switch (event.keyCode) { case KeyCode.Enter: { if (this.dropDown && this.dropDownButtonElement && this.dropDownButtonElement.nativeElement && this.dropDown.isOpen && this.dropDown.contentElement) { this.dropDownButtonElement.nativeElement.focus(); } break; } } } /** * Host listeners to handle mouse events. */ onMouseEvent(event) { if (this.item.container.orientation === 'vertical') { return; } this.isHovering = event.type === 'mouseenter'; this.yieldToggleDropdown(this.isHovering); } yieldToggleDropdown(wasHovering) { setTimeout(_ => { if (this.isHovering !== wasHovering) { return; } if (wasHovering) { this.dropDown.open(); } else { this.dropDown.close(); } }, ActionDropdownRendererComponent.hoverTimeToActivate); } } ActionDropdownRendererComponent.hoverTimeToActivate = 500; ActionDropdownRendererComponent.dropdownUtaIdSuffix = '-dropdown'; /** @nocollapse */ ActionDropdownRendererComponent.ɵfac = function ActionDropdownRendererComponent_Factory(t) { return new (t || ActionDropdownRendererComponent)(i0.ɵɵdirectiveInject(i0.Renderer2), i0.ɵɵdirectiveInject(i0.ElementRef)); }; /** @nocollapse */ ActionDropdownRendererComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: ActionDropdownRendererComponent, selectors: [["sme-action-dropdown-renderer"]], viewQuery: function ActionDropdownRendererComponent_Query(rf, ctx) { if (rf & 1) { i0.ɵɵviewQuery(_c0, 5); i0.ɵɵviewQuery(_c1, 5); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.dropDown = _t.first); i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.dropDownButtonElement = _t.first); } }, hostBindings: function ActionDropdownRendererComponent_HostBindings(rf, ctx) { if (rf & 1) { i0.ɵɵlistener("keydown", function ActionDropdownRendererComponent_keydown_HostBindingHandler($event) { return ctx.onToggleKeydown($event); })("mouseenter", function ActionDropdownRendererComponent_mouseenter_HostBindingHandler($event) { return ctx.onMouseEvent($event); })("mouseleave", function ActionDropdownRendererComponent_mouseleave_HostBindingHandler($event) { return ctx.onMouseEvent($event); }); } }, features: [i0.ɵɵInheritDefinitionFeature], decls: 11, vars: 17, consts: [["role", "presentation", 1, "sme-position-flex-none", 3, "displayToSide"], ["dropDown", ""], ["role", "menuitem", "type", "button", "aria-haspopup", "true", 1, "sme-button-trigger", "sme-layout-action-bar-item-height", "sme-button-auto-width", "sme-button-align-left", "sme-position-stretch-h", "sme-dropdown-toggle", 3, "smeDisabled", "title"], ["dropDownButton", ""], ["class", "sme-screen-reader", 4, "ngIf"], [3, "ngClass"], [1, "sme-arrange-ellipsis", "sme-action-button-text-span"], ["class", "sme-icon sme-icon-size-xxs sme-icon-chevronDown sme-margin-left-xs", 4, "ngIf"], ["class", "sme-icon sme-icon-size-xxs sme-icon-chevronRight sme-position-right-inline", 4, "ngIf"], ["role", "menu", 1, "sme-dropdown-content", 3, "actions", "target", "targetChange", "error", "executed"], [1, "sme-screen-reader"], [1, "sme-icon", "sme-icon-size-xxs", "sme-icon-chevronDown", "sme-margin-left-xs"], [1, "sme-icon", "sme-icon-size-xxs", "sme-icon-chevronRight", "sme-position-right-inline"]], template: function ActionDropdownRendererComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "sme-dropdown", 0, 1)(2, "button", 2, 3); i0.ɵɵtemplate(4, ActionDropdownRendererComponent_p_4_Template, 2, 1, "p", 4); i0.ɵɵelement(5, "span", 5); i0.ɵɵelementStart(6, "span", 6); i0.ɵɵtext(7); i0.ɵɵelementEnd(); i0.ɵɵtemplate(8, ActionDropdownRendererComponent_span_8_Template, 1, 0, "span", 7); i0.ɵɵtemplate(9, ActionDropdownRendererComponent_span_9_Template, 1, 0, "span", 8); i0.ɵɵelementEnd(); i0.ɵɵelementStart(10, "sme-action-menu", 9); i0.ɵɵlistener("targetChange", function ActionDropdownRendererComponent_Template_sme_action_menu_targetChange_10_listener($event) { return ctx.item.container.target = $event; })("error", function ActionDropdownRendererComponent_Template_sme_action_menu_error_10_listener($event) { return ctx.item.container.error.emit($event); })("executed", function ActionDropdownRendererComponent_Template_sme_action_menu_executed_10_listener($event) { return ctx.item.container.executed.emit($event); }); i0.ɵɵelementEnd()(); } if (rf & 2) { const _r0 = i0.ɵɵreference(1); i0.ɵɵproperty("displayToSide", (ctx.item.container == null ? null : ctx.item.container.orientation) === "horizontal"); i0.ɵɵattribute("data-uta-id", ctx.actionDropdownUtaId); i0.ɵɵadvance(2); i0.ɵɵclassProp("sme-toggled", _r0.isOpen); i0.ɵɵproperty("smeDisabled", !ctx.item.enabled || ctx.item.busy || !ctx.item.ready)("title", ctx.actionTitle); i0.ɵɵattribute("aria-expanded", _r0.isOpen)("data-uta-id", ctx.actionDropdownId); i0.ɵɵadvance(2); i0.ɵɵproperty("ngIf", ctx.actionTitle); i0.ɵɵadvance(1); i0.ɵɵproperty("ngClass", ctx.item.iconClass || ""); i0.ɵɵadvance(1); i0.ɵɵclassProp("sme-screen-reader", ctx.item.container.compact); i0.ɵɵadvance(1); i0.ɵɵtextInterpolate(ctx.item.text); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", (ctx.item.container == null ? null : ctx.item.container.orientation) === "vertical"); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", (ctx.item.container == null ? null : ctx.item.container.orientation) === "horizontal"); i0.ɵɵadvance(1); i0.ɵɵproperty("actions", ctx.item.actions)("target", ctx.item.container.target); } }, dependencies: [i1.NgClass, i1.NgIf, i2.DropdownComponent, i3.DisabledDirective, i4.TooltipDirective, i5.ActionMenuComponent], encapsulation: 2 }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ActionDropdownRendererComponent, [{ type: Component, args: [{ selector: 'sme-action-dropdown-renderer', template: "<sme-dropdown [attr.data-uta-id]=\"actionDropdownUtaId\" #dropDown class=\"sme-position-flex-none\" role=\"presentation\" [displayToSide]=\"item.container?.orientation === 'horizontal'\">\r\n <button #dropDownButton role=\"menuitem\" type=\"button\" class=\"sme-button-trigger sme-layout-action-bar-item-height sme-button-auto-width sme-button-align-left sme-position-stretch-h sme-dropdown-toggle\"\r\n [class.sme-toggled]=\"dropDown.isOpen\" [attr.aria-expanded]=\"dropDown.isOpen\" aria-haspopup=\"true\" [smeDisabled]=\"!item.enabled || item.busy || !item.ready\" [title]=\"actionTitle\" [attr.data-uta-id]=\"actionDropdownId\">\r\n <p *ngIf=\"actionTitle\" class=\"sme-screen-reader\">{{ actionTitle }}</p>\r\n <span [ngClass]=\"item.iconClass || ''\"></span>\r\n <span [class.sme-screen-reader]=\"item.container.compact\" class=\"sme-arrange-ellipsis sme-action-button-text-span\">{{ item.text }}</span>\r\n <span *ngIf=\"item.container?.orientation === 'vertical'\" class=\"sme-icon sme-icon-size-xxs sme-icon-chevronDown sme-margin-left-xs\"></span>\r\n <span *ngIf=\"item.container?.orientation === 'horizontal'\" class=\"sme-icon sme-icon-size-xxs sme-icon-chevronRight sme-position-right-inline\"></span>\r\n </button>\r\n <sme-action-menu [actions]=\"item.actions\" role=\"menu\" class=\"sme-dropdown-content\" [(target)]=\"item.container.target\" (error)=\"item.container.error.emit($event)\"\r\n (executed)=\"item.container.executed.emit($event)\"></sme-action-menu>\r\n</sme-dropdown>\r\n" }] }], function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }]; }, { dropDown: [{ type: ViewChild, args: ['dropDown'] }], dropDownButtonElement: [{ type: ViewChild, args: ['dropDownButton'] }], onToggleKeydown: [{ type: HostListener, args: ['keydown', ['$event']] }], onMouseEvent: [{ type: HostListener, args: ['mouseenter', ['$event']] }, { type: HostListener, args: ['mouseleave', ['$event']] }] }); })(); export class ActionDropdownComponent extends ActionItemComponent { constructor(actionBarComponent) { super(); this.actionBarComponent = actionBarComponent; this.actions = []; this.childActions = new QueryList(); } ngAfterViewInit() { setTimeout(() => { this.actionBarComponent.updateActionBar(); }); } ngAfterContentInit() { this.childActions.changes.subscribe(val => { this.updateActions(); }); this.updateActions(); } ngOnChanges(changes) { const props = Object.keys(changes); props.forEach(prop => { if (prop === 'actions') { this.updateActions(); return; } const change = changes[prop]; this.action[prop] = change.currentValue; }); } ngOnDestroy() { setTimeout(() => { this.actionBarComponent.updateActionBar(); }); } createActionItem() { const dropdown = new ActionDropdown(); dropdown.actions = []; return dropdown; } updateActions() { // QuerySelector currently includes self, but this should be fixed in Angular 8 // @see https://stackoverflow.com/questions/40660093/why-does-contentchildren-include-self-this-when-querying-a-matching-selector const combinedActions = this.actions.concat(this.childActions.filter(item => item !== this).map(item => item.action)); this.action.actions = combinedActions; } } /** @nocollapse */ ActionDropdownComponent.ɵfac = function ActionDropdownComponent_Factory(t) { return new (t || ActionDropdownComponent)(i0.ɵɵdirectiveInject(i6.ActionBarComponent)); }; /** @nocollapse */ ActionDropdownComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: ActionDropdownComponent, selectors: [["sme-action-dropdown"]], contentQueries: function ActionDropdownComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { i0.ɵɵcontentQuery(dirIndex, _c2, 4); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.childActions = _t); } }, viewQuery: function ActionDropdownComponent_Query(rf, ctx) { if (rf & 1) { i0.ɵɵviewQuery(_c0, 5); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.dropDown = _t.first); } }, inputs: { actions: "actions" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 0, vars: 0, template: function ActionDropdownComponent_Template(rf, ctx) { }, encapsulation: 2 }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ActionDropdownComponent, [{ type: Component, args: [{ selector: 'sme-action-dropdown', template: '' }] }], function () { return [{ type: i6.ActionBarComponent }]; }, { dropDown: [{ type: ViewChild, args: ['dropDown'] }], childActions: [{ type: ContentChildren, args: ['action'] }], actions: [{ type: Input }] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWRyb3Bkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2FuZ3VsYXIvc3JjL2NvbnRyb2xzL2FjdGlvbnMvaXRlbXMvYWN0aW9uLWRyb3Bkb3duL2FjdGlvbi1kcm9wZG93bi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9hbmd1bGFyL3NyYy9jb250cm9scy9hY3Rpb25zL2l0ZW1zL2FjdGlvbi1kcm9wZG93bi9hY3Rpb24tZHJvcGRvd24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdILFNBQVMsRUFDVCxlQUFlLEVBRWYsVUFBVSxFQUNWLFlBQVksRUFDWixLQUFLLEVBR0wsU0FBUyxFQUNULFNBQVMsRUFFVCxTQUFTLEVBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFFQUFxRSxDQUFDO0FBQzlGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtEQUFrRCxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxVQUFVLEVBQUUsbUJBQW1CLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7Ozs7Ozs7Ozs7SUNoQnBHLDZCQUFpRDtJQUFBLFlBQWlCO0lBQUEsaUJBQUk7OztJQUFyQixlQUFpQjtJQUFqQix3Q0FBaUI7OztJQUdsRSwyQkFBMkk7OztJQUMzSSwyQkFBcUo7OztBRGN6SixNQUFNLE9BQU8sY0FBZSxTQUFRLFVBQVU7SUFNMUM7O09BRUc7SUFDSDtRQUNJLEtBQUssQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0lBQzNDLENBQUM7Q0FDSjtBQU1ELE1BQU0sT0FBTywrQkFBZ0MsU0FBUSwyQkFBMkM7SUF3QjVGOztPQUVHO0lBQ0gsWUFBb0IsUUFB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O0lBRVMsZ0JBQWdCO1FBQ3RCLE1BQU0sUUFBUSxHQUFHLElBQUksY0FBYyxFQUFFLENBQUM7UUFDdEMsUUFBUSxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDdEIsT0FBTyxRQUFRLENBQUM7SUFDcEIsQ0FBQztJQUVPLGFBQWE7UUFDakIsK0VBQStFO1FBQy9FLGlJQUFpSTtRQUNqSSxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUNyRyxJQUFJLENBQUMsTUFBTyxDQUFDLE9BQU8sR0FBRyxlQUFlLENBQUM7SUFDNUQsQ0FBQzs7aUhBMURRLHVCQUF1Qjt5R0FBdkIsdUJBQXVCOzs7Ozs7Ozs7Ozt1RkFBdkIsdUJBQXVCO2NBSm5DLFNBQVM7ZUFBQztnQkFDUCxRQUFRLEVBQUUscUJBQXFCO2dCQUMvQixRQUFRLEVBQUUsRUFBRTthQUNmO3FFQUdpQyxRQUFRO2tCQUFyQyxTQUFTO21CQUFDLFVBQVU7WUFHZCxZQUFZO2tCQURsQixlQUFlO21CQUFDLFFBQVE7WUFJbEIsT0FBTztrQkFEYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgIEFmdGVyQ29udGVudEluaXQsXHJcbiAgICBBZnRlclZpZXdJbml0LFxyXG4gICAgQ29tcG9uZW50LFxyXG4gICAgQ29udGVudENoaWxkcmVuLFxyXG4gICAgRG9DaGVjayxcclxuICAgIEVsZW1lbnRSZWYsXHJcbiAgICBIb3N0TGlzdGVuZXIsXHJcbiAgICBJbnB1dCxcclxuICAgIE9uQ2hhbmdlcyxcclxuICAgIE9uRGVzdHJveSxcclxuICAgIFF1ZXJ5TGlzdCxcclxuICAgIFJlbmRlcmVyMixcclxuICAgIFNpbXBsZUNoYW5nZXMsXHJcbiAgICBWaWV3Q2hpbGRcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgS2V5Q29kZSB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvZGF0YS9hY2Nlc3NpYmlsaXR5LW1hbmFnZXInO1xyXG5pbXBvcnQgeyBEcm9wZG93bkNvbXBvbmVudCB9IGZyb20gJy4uLy4uLy4uL2Ryb3Bkb3duL2Ryb3Bkb3duLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEFjdGlvbkJhckNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbnRhaW5lcnMvYWN0aW9uLWJhci9hY3Rpb24tYmFyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEFjdGlvbkl0ZW0sIEFjdGlvbkl0ZW1Db21wb25lbnQsIEFjdGlvbkl0ZW1SZW5kZXJlckNvbXBvbmVudCB9IGZyb20gJy4uL2FjdGlvbi1pdGVtLmNvbXBvbmVudCc7XHJcblxyXG5leHBvcnQgY2xhc3MgQWN0aW9uRHJvcGRvd24gZXh0ZW5kcyBBY3Rpb25JdGVtIHtcclxuICAgIC8qKlxyXG4gICAgICogTGlzdCBvZiBjaGlsZCBBY3Rpb25JdGVtIG9iamVjdHMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhY3Rpb25zOiBBY3Rpb25JdGVtW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgQWN0aW9uRHJvcGRvd24uXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHN1cGVyKEFjdGlvbkRyb3Bkb3duUmVuZGVyZXJDb21wb25lbnQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnc21lLWFjdGlvbi1kcm9wZG93bi1yZW5kZXJlcicsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vYWN0aW9uLWRyb3Bkb3duLmNvbXBvbmVudC5odG1sJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgQWN0aW9uRHJvcGRvd25SZW5kZXJlckNvbXBvbmVudCBleHRlbmRzIEFjdGlvbkl0ZW1SZW5kZXJlckNvbXBvbmVudDxBY3Rpb25Ecm9wZG93bj4gaW1wbGVtZW50cyBEb0NoZWNrIHtcclxuICAgIHByaXZhdGUgc3RhdGljIGhvdmVyVGltZVRvQWN0aXZhdGUgPSA1MDA7XHJcbiAgICBwdWJsaWMgc3RhdGljIGRyb3Bkb3duVXRhSWRTdWZmaXggPSAnLWRyb3Bkb3duJztcclxuXHJcbiAgICAvKipcclxuICAgICAqIERyb3Bkb3duIGNvbXBvbmVudCB1c2VkIGluIEFjdGlvbkRyb3Bkb3duLlxyXG4gICAgICovXHJcbiAgICBAVmlld0NoaWxkKCdkcm9wRG93bicpIHB1YmxpYyBkcm9wRG93bjogRHJvcGRvd25Db21wb25lbnQ7XHJcbiAgICBAVmlld0NoaWxkKCdkcm9wRG93bkJ1dHRvbicpIHByaXZhdGUgZHJvcERvd25CdXR0b25FbGVtZW50OiBFbGVtZW50UmVmO1xyXG5cclxuICAgIHByaXZhdGUgaXNIb3ZlcmluZyA9IGZhbHNlO1xyXG5cclxuICAgIHB1YmxpYyBnZXQgYWN0aW9uVGl0bGUoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pdGVtLm5hbWUgJiYgdGhpcy5pdGVtLm5hbWUgIT09IHRoaXMuaXRlbS50ZXh0ID8gdGhpcy5pdGVtLm5hbWUgOiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgYWN0aW9uRHJvcGRvd25JZCgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLml0ZW0uYWN0aW9uSWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldCBhY3Rpb25Ecm9wZG93blV0YUlkKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaXRlbS5hY3Rpb25JZCArIEFjdGlvbkRyb3Bkb3duUmVuZGVyZXJDb21wb25lbnQuZHJvcGRvd25VdGFJZFN1ZmZpeDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdG9yIG9mIEFjdGlvbkRyb3Bkb3duUmVuZGVyZXJDb21wb25lbnQuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMiwgcHJpdmF0ZSBob3N0RWxlbWVudDogRWxlbWVudFJlZikge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgcmVuZGVyZXIuYWRkQ2xhc3MoaG9zdEVsZW1lbnQubmF0aXZlRWxlbWVudCwgJ3NtZS1wb3NpdGlvbi1zdHJldGNoJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRob2QgY2FsbGVkIHRvIHJlZ2lzdGVyIGEgY2hhbmdlIHdpdGggdGhlIEFjdGlvbkJ1dHRvbi5cclxuICAgICAqIEBwYXJhbSBpdGVtIFRoZSBBY3Rpb25CdXR0b24gdG8gcmVnaXN0ZXIgY2hhbmdlIGZvci5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGl0ZW1DaGFuZ2VkKGl0ZW06IEFjdGlvbkRyb3Bkb3duKSB7XHJcbiAgICAgICAgc3VwZXIuaXRlbUNoYW5nZWQoaXRlbSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIG5nRG9DaGVjaygpIHtcclxuICAgICAgICBjb25zdCBvZmZzZXRXaWR0aCA9ICg8SFRNTEVsZW1lbnQ+dGhpcy5ob3N0RWxlbWVudC5uYXRpdmVFbGVtZW50KS5vZmZzZXRXaWR0aDtcclxuICAgICAgICBpZiAob2Zmc2V0V2lkdGggPT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSXQgbG9va3MgbGlrZSB0aGUgQ1NTIGljb24gaXNuJ3QgYmVpbmcgaW5jbHVkZWQgaW4gdGhlIG9mZnNldFdpZHRoLCBub3IgdGhlIGNsaWVudFdpZHRoLlxyXG4gICAgICAgIC8vIEFkZGluZyBoZXJlIGZvciBzaW1wbGljaXR5IGFuZCBjbGFyaXR5LlxyXG4gICAgICAgIGNvbnN0IGNzc0ljb25XaWR0aCA9IDE0O1xyXG4gICAgICAgIGNvbnN0IGNhbGN1bGF0ZWRXaWR0aCA9IG9mZnNldFdpZHRoICsgY3NzSWNvbldpZHRoO1xyXG4gICAgICAgIGlmICh0aGlzLml0ZW0ud2lkdGggIT09IGNhbGN1bGF0ZWRXaWR0aCkge1xyXG4gICAgICAgICAgICB0aGlzLml0ZW0ud2lkdGggPSBjYWxjdWxhdGVkV2lkdGg7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSG9zdCBsaXN0ZW5lciB0byBoYW5kbGUga2V5Ym9hcmQgZXZlbnRzLlxyXG4gICAgICovXHJcbiAgICBASG9zdExpc3RlbmVyKCdrZXlkb3duJywgWyckZXZlbnQnXSlcclxuICAgIHB1YmxpYyBvblRvZ2dsZUtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcclxuICAgICAgICAvLyBhY2Nlc3NpYmlsaXR5LCB0YWtlIGZvY3VzIHRvIHRoZSBhY3Rpb24gYnV0dG9uIGFmdGVyIGEgc2VsZWN0aW9uIGluIGRyb3Bkb3duIGVsZW1lbnRzLlxyXG4gICAgICAgIHN3aXRjaCAoZXZlbnQua2V5Q29kZSkge1xyXG4gICAgICAgICAgICBjYXNlIEtleUNvZGUuRW50ZXI6IHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRyb3BEb3duICYmXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcm9wRG93bkJ1dHRvbkVsZW1lbnQgJiZcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyb3BEb3duQnV0dG9uRWxlbWVudC5uYXRpdmVFbGVtZW50ICYmXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcm9wRG93bi5pc09wZW4gJiZcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyb3BEb3duLmNvbnRlbnRFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcm9wRG93bkJ1dHRvbkVsZW1lbnQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIb3N0IGxpc3RlbmVycyB0byBoYW5kbGUgbW91c2UgZXZlbnRzLlxyXG4gICAgICovXHJcbiAgICBASG9zdExpc3RlbmVyKCdtb3VzZWVudGVyJywgWyckZXZlbnQnXSlcclxuICAgIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBbJyRldmVudCddKVxyXG4gICAgcHVibGljIG9uTW91c2VFdmVudChldmVudDogRXZlbnQpIHtcclxuICAgICAgICBpZiAodGhpcy5pdGVtLmNvbnRhaW5lci5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuaXNIb3ZlcmluZyA9IGV2ZW50LnR5cGUgPT09ICdtb3VzZWVudGVyJztcclxuICAgICAgICB0aGlzLnlpZWxkVG9nZ2xlRHJvcGRvd24odGhpcy5pc0hvdmVyaW5nKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHlpZWxkVG9nZ2xlRHJvcGRvd24od2FzSG92ZXJpbmc6IGJvb2xlYW4pIHtcclxuICAgICAgICBzZXRUaW1lb3V0KF8gPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc0hvdmVyaW5nICE9PSB3YXNIb3ZlcmluZykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh3YXNIb3ZlcmluZykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kcm9wRG93bi5vcGVuKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRyb3BEb3duLmNsb3NlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LCBBY3Rpb25Ecm9wZG93blJlbmRlcmVyQ29tcG9uZW50LmhvdmVyVGltZVRvQWN0aXZhdGUpO1xyXG4gICAgfVxyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnc21lLWFjdGlvbi1kcm9wZG93bicsXHJcbiAgICB0ZW1wbGF0ZTogJydcclxufSlcclxuZXhwb3J0IGNsYXNzIEFjdGlvbkRyb3Bkb3duQ29tcG9uZW50IGV4dGVuZHMgQWN0aW9uSXRlbUNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBBZnRlckNvbnRlbnRJbml0IHtcclxuXHJcbiAgICBAVmlld0NoaWxkKCdkcm9wRG93bicpIHB1YmxpYyBkcm9wRG93bjogRHJvcGRvd25Db21wb25lbnQ7XHJcblxyXG4gICAgQENvbnRlbnRDaGlsZHJlbignYWN0aW9uJylcclxuICAgIHB1YmxpYyBjaGlsZEFjdGlvbnM6IFF1ZXJ5TGlzdDxBY3Rpb25JdGVtQ29tcG9uZW50PjtcclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGFjdGlvbnM6IEFjdGlvbkl0ZW1bXSA9IFtdO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgYWN0aW9uQmFyQ29tcG9uZW50OiBBY3Rpb25CYXJDb21wb25lbnQpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG5cclxuICAgICAgICB0aGlzLmNoaWxkQWN0aW9ucyA9IG5ldyBRdWVyeUxpc3Q8QWN0aW9uSXRlbUNvbXBvbmVudD4oKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmFjdGlvbkJhckNvbXBvbmVudC51cGRhdGVBY3Rpb25CYXIoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbmdBZnRlckNvbnRlbnRJbml0KCkge1xyXG4gICAgICAgIHRoaXMuY2hpbGRBY3Rpb25zLmNoYW5nZXMuc3Vic2NyaWJlKHZhbCA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQWN0aW9ucygpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQWN0aW9ucygpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICAgICAgY29uc3QgcHJvcHMgPSBPYmplY3Qua2V5cyhjaGFuZ2VzKTtcclxuICAgICAgICBwcm9wcy5mb3JFYWNoKHByb3AgPT4ge1xyXG4gICAgICAgICAgICBpZiAocHJvcCA9PT0gJ2FjdGlvbnMnKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUFjdGlvbnMoKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBjaGFuZ2UgPSBjaGFuZ2VzW3Byb3BdO1xyXG4gICAgICAgICAgICB0aGlzLmFjdGlvbltwcm9wXSA9IGNoYW5nZS5jdXJyZW50VmFsdWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmFjdGlvbkJhckNvbXBvbmVudC51cGRhdGVBY3Rpb25CYXIoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgY3JlYXRlQWN0aW9uSXRlbSgpOiBBY3Rpb25Ecm9wZG93biB7XHJcbiAgICAgICAgY29uc3QgZHJvcGRvd24gPSBuZXcgQWN0aW9uRHJvcGRvd24oKTtcclxuICAgICAgICBkcm9wZG93bi5hY3Rpb25zID0gW107XHJcbiAgICAgICAgcmV0dXJuIGRyb3Bkb3duO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgdXBkYXRlQWN0aW9ucygpIHtcclxuICAgICAgICAvLyBRdWVyeVNlbGVjdG9yIGN1cnJlbnRseSBpbmNsdWRlcyBzZWxmLCBidXQgdGhpcyBzaG91bGQgYmUgZml4ZWQgaW4gQW5ndWxhciA4XHJcbiAgICAgICAgLy8gQHNlZSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80MDY2MDA5My93aHktZG9lcy1jb250ZW50Y2hpbGRyZW4taW5jbHVkZS1zZWxmLXRoaXMtd2hlbi1xdWVyeWluZy1hLW1hdGNoaW5nLXNlbGVjdG9yXHJcbiAgICAgICAgY29uc3QgY29tYmluZWRBY3Rpb25zID0gdGhpcy5hY3Rpb25zLmNvbmNhdCh0aGlzLmNoaWxkQWN0aW9ucy5maWx0ZXIoaXRlbSA9PiBpdGVtICE9PSB0aGlzKS5tYXAoaXRlbSA9PiBpdGVtLmFjdGlvbikpO1xyXG4gICAgICAgICg8QWN0aW9uRHJvcGRvd24+dGhpcy5hY3Rpb24pLmFjdGlvbnMgPSBjb21iaW5lZEFjdGlvbnM7XHJcbiAgICB9XHJcbn1cclxuIiwiPHNtZS1kcm9wZG93biBbYXR0ci5kYXRhLXV0YS1pZF09XCJhY3Rpb25Ecm9wZG93blV0YUlkXCIgI2Ryb3BEb3duIGNsYXNzPVwic21lLXBvc2l0aW9uLWZsZXgtbm9uZVwiIHJvbGU9XCJwcmVzZW50YXRpb25cIiBbZGlzcGxheVRvU2lkZV09XCJpdGVtLmNvbnRhaW5lcj8ub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJ1wiPlxyXG4gIDxidXR0b24gI2Ryb3BEb3duQnV0dG9uIHJvbGU9XCJtZW51aXRlbVwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNtZS1idXR0b24tdHJpZ2dlciBzbWUtbGF5b3V0LWFjdGlvbi1iYXItaXRlbS1oZWlnaHQgc21lLWJ1dHRvbi1hdXRvLXdpZHRoIHNtZS1idXR0b24tYWxpZ24tbGVmdCBzbWUtcG9zaXRpb24tc3RyZXRjaC1oIHNtZS1kcm9wZG93bi10b2dnbGVcIlxyXG4gICAgW2NsYXNzLnNtZS10b2dnbGVkXT1cImRyb3BEb3duLmlzT3BlblwiIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwiZHJvcERvd24uaXNPcGVuXCIgYXJpYS1oYXNwb3B1cD1cInRydWVcIiBbc21lRGlzYWJsZWRdPVwiIWl0ZW0uZW5hYmxlZCB8fCBpdGVtLmJ1c3kgfHwgIWl0ZW0ucmVhZHlcIiBbdGl0bGVdPVwiYWN0aW9uVGl0bGVcIiBbYXR0ci5kYXRhLXV0YS1pZF09XCJhY3Rpb25Ecm9wZG93bklkXCI+XHJcbiAgICA8cCAqbmdJZj1cImFjdGlvblRpdGxlXCIgY2xhc3M9XCJzbWUtc2NyZWVuLXJlYWRlclwiPnt7IGFjdGlvblRpdGxlIH19PC9wPlxyXG4gICAgPHNwYW4gW25nQ2xhc3NdPVwiaXRlbS5pY29uQ2xhc3MgfHwgJydcIj48L3NwYW4+XHJcbiAgICA8c3BhbiBbY2xhc3Muc21lLXNjcmVlbi1yZWFkZXJdPVwiaXRlbS5jb250YWluZXIuY29tcGFjdFwiIGNsYXNzPVwic21lLWFycmFuZ2UtZWxsaXBzaXMgc21lLWFjdGlvbi1idXR0b24tdGV4dC1zcGFuXCI+e3sgaXRlbS50ZXh0IH19PC9zcGFuPlxyXG4gICAgPHNwYW4gKm5nSWY9XCJpdGVtLmNvbnRhaW5lcj8ub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCdcIiBjbGFzcz1cInNtZS1pY29uIHNtZS1pY29uLXNpemUteHhzIHNtZS1pY29uLWNoZXZyb25Eb3duIHNtZS1tYXJnaW4tbGVmdC14c1wiPjwvc3Bhbj5cclxuICAgIDxzcGFuICpuZ0lmPVwiaXRlbS5jb250YWluZXI/Lm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCdcIiBjbGFzcz1cInNtZS1pY29uIHNtZS1pY29uLXNpemUteHhzIHNtZS1pY29uLWNoZXZyb25SaWdodCBzbWUtcG9zaXRpb24tcmlnaHQtaW5saW5lXCI+PC9zcGFuPlxyXG4gIDwvYnV0dG9uPlxyXG4gIDxzbWUtYWN0aW9uLW1lbnUgW2FjdGlvbnNdPVwiaXRlbS5hY3Rpb25zXCIgcm9sZT1cIm1lbnVcIiBjbGFzcz1cInNtZS1kcm9wZG93bi1jb250ZW50XCIgWyh0YXJnZXQpXT1cIml0ZW0uY29udGFpbmVyLnRhcmdldFwiIChlcnJvcik9XCJpdGVtLmNvbnRhaW5lci5lcnJvci5lbWl0KCRldmVudClcIlxyXG4gICAgKGV4ZWN1dGVkKT1cIml0ZW0uY29udGFpbmVyLmV4ZWN1dGVkLmVtaXQoJGV2ZW50KVwiPjwvc21lLWFjdGlvbi1tZW51PlxyXG48L3NtZS1kcm9wZG93bj5cclxuIl19