@clr/angular
Version:
Angular components for Clarity
165 lines • 27.4 kB
JavaScript
/*
* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { Component, ContentChildren, Input, ViewChild, } from '@angular/core';
import { takeUntil } from 'rxjs/operators';
import { ClrDestroyService } from '../../utils/destroy/destroy.service';
import { FOCUS_SERVICE_PROVIDER } from '../../utils/focus/focus.service';
import { uniqueIdFactory } from '../../utils/id-generator/id-generator.service';
import { ClrPopoverPositions } from '../../utils/popover/enums/positions.enum';
import { ClrPopoverHostDirective } from '../../utils/popover/popover-host.directive';
import { BUTTON_GROUP_FOCUS_HANDLER_PROVIDER, } from '../providers/button-group-focus-handler.service';
import { InitialFocus } from '../providers/button-group-focus.enum';
import { ButtonInGroupService } from '../providers/button-in-group.service';
import { ClrButton } from './button';
import * as i0 from "@angular/core";
import * as i1 from "../providers/button-in-group.service";
import * as i2 from "../../utils/popover/providers/popover-toggle.service";
import * as i3 from "../../utils/i18n/common-strings.service";
import * as i4 from "../../utils/destroy/destroy.service";
import * as i5 from "../providers/button-group-focus-handler.service";
import * as i6 from "../../utils/popover/popover-host.directive";
import * as i7 from "@angular/common";
import * as i8 from "../../icon/icon";
import * as i9 from "../../utils/popover/popover-anchor";
import * as i10 from "../../utils/popover/popover-open-close-button";
import * as i11 from "../../utils/popover/popover-content";
export class ClrButtonGroup {
constructor(buttonGroupNewService, toggleService, commonStrings, destroy$, focusHandler) {
this.buttonGroupNewService = buttonGroupNewService;
this.toggleService = toggleService;
this.commonStrings = commonStrings;
this.destroy$ = destroy$;
this.focusHandler = focusHandler;
this.clrToggleButtonAriaLabel = this.commonStrings.keys.rowActions;
this.popoverId = uniqueIdFactory();
this.InitialFocus = InitialFocus;
this.popoverPosition = ClrPopoverPositions['bottom-left'];
this.inlineButtons = [];
this.menuButtons = [];
}
get menuPosition() {
return this._menuPosition;
}
set menuPosition(pos) {
if (pos && ClrPopoverPositions[pos]) {
this._menuPosition = pos;
}
else {
this._menuPosition = 'bottom-left';
}
this.popoverPosition = ClrPopoverPositions[this._menuPosition];
}
get open() {
return this.toggleService.open;
}
/**
* 1. Initializes the initial Button Group View
* 2. Subscribes to changes on the ContentChildren
* in case the user content projection changes
*/
ngAfterContentInit() {
this.initializeButtons();
this.buttonGroupNewService.changes.pipe(takeUntil(this.destroy$)).subscribe(button => this.rearrangeButton(button));
this.buttons.changes.subscribe(() => {
this.initializeButtons();
});
}
ngAfterViewInit() {
this.handleFocusOnMenuOpen();
}
/**
* Moves the button into the other ViewContainer
* when an update is received.
*
* @param button
*/
rearrangeButton(button) {
let fromView;
let toView;
if (button.inMenu) {
fromView = this.inlineButtons;
toView = this.menuButtons;
}
else {
fromView = this.menuButtons;
toView = this.inlineButtons;
}
const index = fromView.indexOf(button);
if (index > -1) {
fromView.splice(index, 1);
const moveIndex = this.getMoveIndex(button);
if (moveIndex <= toView.length) {
toView.splice(moveIndex, 0, button);
}
}
}
openMenu(event, initialFocus) {
this.focusHandler.initialFocus = initialFocus;
if (!this.toggleService.open) {
this.toggleService.toggleWithEvent(event);
}
}
/**
* Author: Eudes
*
* Finds the order of a button w.r.t other buttons
*
* @param buttonToMove
* @returns
*/
getMoveIndex(buttonToMove) {
const tempArr = this.buttons.filter(button => button.inMenu === buttonToMove.inMenu);
return tempArr.indexOf(buttonToMove);
}
initializeButtons() {
const tempInlineButtons = [];
const tempInMenuButtons = [];
this.buttons.forEach(button => {
if (button.inMenu) {
tempInMenuButtons.push(button);
}
else {
tempInlineButtons.push(button);
}
});
this.inlineButtons = tempInlineButtons;
this.menuButtons = tempInMenuButtons;
}
handleFocusOnMenuOpen() {
if (this.menuButtons.length) {
this.toggleService.popoverVisible.pipe(takeUntil(this.destroy$)).subscribe(visible => {
if (visible) {
this.focusHandler.initialize({
menu: this.menu.nativeElement,
menuToggle: this.menuToggle.nativeElement,
});
}
});
}
}
}
ClrButtonGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrButtonGroup, deps: [{ token: i1.ButtonInGroupService }, { token: i2.ClrPopoverToggleService }, { token: i3.ClrCommonStringsService }, { token: i4.ClrDestroyService }, { token: i5.ButtonGroupFocusHandler }], target: i0.ɵɵFactoryTarget.Component });
ClrButtonGroup.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrButtonGroup, selector: "clr-button-group", inputs: { clrToggleButtonAriaLabel: "clrToggleButtonAriaLabel", menuPosition: ["clrMenuPosition", "menuPosition"] }, host: { properties: { "class.btn-group": "true" } }, providers: [ButtonInGroupService, ClrDestroyService, BUTTON_GROUP_FOCUS_HANDLER_PROVIDER, FOCUS_SERVICE_PROVIDER], queries: [{ propertyName: "buttons", predicate: ClrButton }], viewQueries: [{ propertyName: "menuToggle", first: true, predicate: ["menuToggle"], descendants: true }, { propertyName: "menu", first: true, predicate: ["menu"], descendants: true }], hostDirectives: [{ directive: i6.ClrPopoverHostDirective }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-container *ngFor=\"let inlineButton of inlineButtons\">\n <ng-template [ngTemplateOutlet]=\"inlineButton.templateRef\"></ng-template>\n</ng-container>\n<ng-container *ngIf=\"menuButtons.length > 0\">\n <div class=\"btn-group-overflow open\" [ngClass]=\"menuPosition\" #anchor>\n <button\n #menuToggle\n class=\"btn dropdown-toggle\"\n clrPopoverAnchor\n clrPopoverOpenCloseButton\n (keydown.arrowup)=\"openMenu($event, InitialFocus.LAST_ITEM)\"\n (keydown.arrowdown)=\"openMenu($event, InitialFocus.FIRST_ITEM)\"\n [attr.aria-controls]=\"popoverId\"\n [attr.aria-expanded]=\"open\"\n [attr.aria-label]=\"clrToggleButtonAriaLabel\"\n >\n <cds-icon shape=\"ellipsis-horizontal\" [attr.title]=\"commonStrings.keys.more\"></cds-icon>\n </button>\n <div\n #menu\n role=\"menu\"\n class=\"dropdown-menu clr-button-group-menu\"\n [id]=\"popoverId\"\n [attr.id]=\"popoverId\"\n [attr.aria-hidden]=\"!open\"\n *clrPopoverContent=\"open at popoverPosition; outsideClickToClose: true; scrollToClose: true\"\n >\n <ng-template [ngTemplateOutlet]=\"ref\"></ng-template>\n </div>\n </div>\n</ng-container>\n<ng-template #ref>\n <ng-container *ngFor=\"let menuButton of menuButtons\">\n <ng-template [ngTemplateOutlet]=\"menuButton.templateRef\"></ng-template>\n </ng-container>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i8.CdsIconCustomTag, selector: "cds-icon" }, { kind: "directive", type: i9.ClrPopoverAnchor, selector: "[clrPopoverAnchor]" }, { kind: "directive", type: i10.ClrPopoverOpenCloseButton, selector: "[clrPopoverOpenCloseButton]", outputs: ["clrPopoverOpenCloseChange"] }, { kind: "directive", type: i11.ClrPopoverContent, selector: "[clrPopoverContent]", inputs: ["clrPopoverContent", "clrPopoverContentAt", "clrPopoverContentOutsideClickToClose", "clrPopoverContentScrollToClose"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrButtonGroup, decorators: [{
type: Component,
args: [{ selector: 'clr-button-group', providers: [ButtonInGroupService, ClrDestroyService, BUTTON_GROUP_FOCUS_HANDLER_PROVIDER, FOCUS_SERVICE_PROVIDER], hostDirectives: [ClrPopoverHostDirective], host: { '[class.btn-group]': 'true' }, template: "<!--\n ~ Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<ng-container *ngFor=\"let inlineButton of inlineButtons\">\n <ng-template [ngTemplateOutlet]=\"inlineButton.templateRef\"></ng-template>\n</ng-container>\n<ng-container *ngIf=\"menuButtons.length > 0\">\n <div class=\"btn-group-overflow open\" [ngClass]=\"menuPosition\" #anchor>\n <button\n #menuToggle\n class=\"btn dropdown-toggle\"\n clrPopoverAnchor\n clrPopoverOpenCloseButton\n (keydown.arrowup)=\"openMenu($event, InitialFocus.LAST_ITEM)\"\n (keydown.arrowdown)=\"openMenu($event, InitialFocus.FIRST_ITEM)\"\n [attr.aria-controls]=\"popoverId\"\n [attr.aria-expanded]=\"open\"\n [attr.aria-label]=\"clrToggleButtonAriaLabel\"\n >\n <cds-icon shape=\"ellipsis-horizontal\" [attr.title]=\"commonStrings.keys.more\"></cds-icon>\n </button>\n <div\n #menu\n role=\"menu\"\n class=\"dropdown-menu clr-button-group-menu\"\n [id]=\"popoverId\"\n [attr.id]=\"popoverId\"\n [attr.aria-hidden]=\"!open\"\n *clrPopoverContent=\"open at popoverPosition; outsideClickToClose: true; scrollToClose: true\"\n >\n <ng-template [ngTemplateOutlet]=\"ref\"></ng-template>\n </div>\n </div>\n</ng-container>\n<ng-template #ref>\n <ng-container *ngFor=\"let menuButton of menuButtons\">\n <ng-template [ngTemplateOutlet]=\"menuButton.templateRef\"></ng-template>\n </ng-container>\n</ng-template>\n" }]
}], ctorParameters: function () { return [{ type: i1.ButtonInGroupService }, { type: i2.ClrPopoverToggleService }, { type: i3.ClrCommonStringsService }, { type: i4.ClrDestroyService }, { type: i5.ButtonGroupFocusHandler }]; }, propDecorators: { clrToggleButtonAriaLabel: [{
type: Input,
args: ['clrToggleButtonAriaLabel']
}], menuToggle: [{
type: ViewChild,
args: ['menuToggle']
}], menu: [{
type: ViewChild,
args: ['menu']
}], buttons: [{
type: ContentChildren,
args: [ClrButton]
}], menuPosition: [{
type: Input,
args: ['clrMenuPosition']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uLWdyb3VwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci9zcmMvYnV0dG9uL2J1dHRvbi1ncm91cC9idXR0b24tZ3JvdXAudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyL3NyYy9idXR0b24vYnV0dG9uLWdyb3VwL2J1dHRvbi1ncm91cC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBR0wsU0FBUyxFQUNULGVBQWUsRUFFZixLQUFLLEVBRUwsU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN4RSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUV6RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFDaEYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFFL0UsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFFckYsT0FBTyxFQUNMLG1DQUFtQyxHQUVwQyxNQUFNLGlEQUFpRCxDQUFDO0FBQ3pELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUM1RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sVUFBVSxDQUFDOzs7Ozs7Ozs7Ozs7O0FBU3JDLE1BQU0sT0FBTyxjQUFjO0lBa0J6QixZQUNTLHFCQUEyQyxFQUMxQyxhQUFzQyxFQUN2QyxhQUFzQyxFQUNyQyxRQUEyQixFQUMzQixZQUFxQztRQUp0QywwQkFBcUIsR0FBckIscUJBQXFCLENBQXNCO1FBQzFD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QyxhQUFhO3dCQUM3QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhO3FCQUMxQyxDQUFDLENBQUM7aUJBQ0o7WUFDSCxDQUFDLENBQUMsQ0FBQztTQUNKO0lBQ0gsQ0FBQzs7MkdBcElVLGNBQWM7K0ZBQWQsY0FBYyxxTkFKZCxDQUFDLG9CQUFvQixFQUFFLGlCQUFpQixFQUFFLG1DQUFtQyxFQUFFLHNCQUFzQixDQUFDLGtEQVVoRyxTQUFTLG1SQy9DNUIsNGxEQTBDQTsyRkREYSxjQUFjO2tCQVAxQixTQUFTOytCQUNFLGtCQUFrQixhQUVqQixDQUFDLG9CQUFvQixFQUFFLGlCQUFpQixFQUFFLG1DQUFtQyxFQUFFLHNCQUFzQixDQUFDLGtCQUNqRyxDQUFDLHVCQUF1QixDQUFDLFFBQ25DLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxFQUFFOzZQQUdGLHdCQUF3QjtzQkFBMUQsS0FBSzt1QkFBQywwQkFBMEI7Z0JBRVIsVUFBVTtzQkFBbEMsU0FBUzt1QkFBQyxZQUFZO2dCQUNKLElBQUk7c0JBQXRCLFNBQVM7dUJBQUMsTUFBTTtnQkFFVyxPQUFPO3NCQUFsQyxlQUFlO3VCQUFDLFNBQVM7Z0JBcUJ0QixZQUFZO3NCQURmLEtBQUs7dUJBQUMsaUJBQWlCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDIzIFZNd2FyZSwgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogVGhpcyBzb2Z0d2FyZSBpcyByZWxlYXNlZCB1bmRlciBNSVQgbGljZW5zZS5cbiAqIFRoZSBmdWxsIGxpY2Vuc2UgaW5mb3JtYXRpb24gY2FuIGJlIGZvdW5kIGluIExJQ0VOU0UgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgcHJvamVjdC5cbiAqL1xuXG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgRWxlbWVudFJlZixcbiAgSW5wdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgQ2xyRGVzdHJveVNlcnZpY2UgfSBmcm9tICcuLi8uLi91dGlscy9kZXN0cm95L2Rlc3Ryb3kuc2VydmljZSc7XG5pbXBvcnQgeyBGT0NVU19TRVJWSUNFX1BST1ZJREVSIH0gZnJvbSAnLi4vLi4vdXRpbHMvZm9jdXMvZm9jdXMuc2VydmljZSc7XG5pbXBvcnQgeyBDbHJDb21tb25TdHJpbmdzU2VydmljZSB9IGZyb20gJy4uLy4uL3V0aWxzL2kxOG4vY29tbW9uLXN0cmluZ3Muc2VydmljZSc7XG5pbXBvcnQgeyB1bmlxdWVJZEZhY3RvcnkgfSBmcm9tICcuLi8uLi91dGlscy9pZC1nZW5lcmF0b3IvaWQtZ2VuZXJhdG9yLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2xyUG9wb3ZlclBvc2l0aW9ucyB9IGZyb20gJy4uLy4uL3V0aWxzL3BvcG92ZXIvZW51bXMvcG9zaXRpb25zLmVudW0nO1xuaW1wb3J0IHsgQ2xyUG9wb3ZlclBvc2l0aW9uIH0gZnJvbSAnLi4vLi4vdXRpbHMvcG9wb3Zlci9pbnRlcmZhY2VzL3BvcG92ZXItcG9zaXRpb24uaW50ZXJmYWNlJztcbmltcG9ydCB7IENsclBvcG92ZXJIb3N0RGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vdXRpbHMvcG9wb3Zlci9wb3BvdmVyLWhvc3QuZGlyZWN0aXZlJztcbmltcG9ydCB7IENsclBvcG92ZXJUb2dnbGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vdXRpbHMvcG9wb3Zlci9wcm92aWRlcnMvcG9wb3Zlci10b2dnbGUuc2VydmljZSc7XG5pbXBvcnQge1xuICBCVVRUT05fR1JPVVBfRk9DVVNfSEFORExFUl9QUk9WSURFUixcbiAgQnV0dG9uR3JvdXBGb2N1c0hhbmRsZXIsXG59IGZyb20gJy4uL3Byb3ZpZGVycy9idXR0b24tZ3JvdXAtZm9jdXMtaGFuZGxlci5zZXJ2aWNlJztcbmltcG9ydCB7IEluaXRpYWxGb2N1cyB9IGZyb20gJy4uL3Byb3ZpZGVycy9idXR0b24tZ3JvdXAtZm9jdXMuZW51bSc7XG5pbXBvcnQgeyBCdXR0b25Jbkdyb3VwU2VydmljZSB9IGZyb20gJy4uL3Byb3ZpZGVycy9idXR0b24taW4tZ3JvdXAuc2VydmljZSc7XG5pbXBvcnQgeyBDbHJCdXR0b24gfSBmcm9tICcuL2J1dHRvbic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2Nsci1idXR0b24tZ3JvdXAnLFxuICB0ZW1wbGF0ZVVybDogJ2J1dHRvbi1ncm91cC5odG1sJyxcbiAgcHJvdmlkZXJzOiBbQnV0dG9uSW5Hcm91cFNlcnZpY2UsIENsckRlc3Ryb3lTZXJ2aWNlLCBCVVRUT05fR1JPVVBfRk9DVVNfSEFORExFUl9QUk9WSURFUiwgRk9DVVNfU0VSVklDRV9QUk9WSURFUl0sXG4gIGhvc3REaXJlY3RpdmVzOiBbQ2xyUG9wb3Zlckhvc3REaXJlY3RpdmVdLFxuICBob3N0OiB7ICdbY2xhc3MuYnRuLWdyb3VwXSc6ICd0cnVlJyB9LFxufSlcbmV4cG9ydCBjbGFzcyBDbHJCdXR0b25Hcm91cCBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQsIEFmdGVyVmlld0luaXQge1xuICBASW5wdXQoJ2NsclRvZ2dsZUJ1dHRvbkFyaWFMYWJlbCcpIGNsclRvZ2dsZUJ1dHRvbkFyaWFMYWJlbDogc3RyaW5nID0gdGhpcy5jb21tb25TdHJpbmdzLmtleXMucm93QWN0aW9ucztcblxuICBAVmlld0NoaWxkKCdtZW51VG9nZ2xlJykgbWVudVRvZ2dsZTogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ21lbnUnKSBtZW51OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICBAQ29udGVudENoaWxkcmVuKENsckJ1dHRvbikgYnV0dG9uczogUXVlcnlMaXN0PENsckJ1dHRvbj47XG5cbiAgcG9wb3ZlcklkID0gdW5pcXVlSWRGYWN0b3J5KCk7XG4gIEluaXRpYWxGb2N1cyA9IEluaXRpYWxGb2N1cztcblxuICBwb3BvdmVyUG9zaXRpb246IENsclBvcG92ZXJQb3NpdGlvbiA9IENsclBvcG92ZXJQb3NpdGlvbnNbJ2JvdHRvbS1sZWZ0J107XG4gIGlubGluZUJ1dHRvbnM6IENsckJ1dHRvbltdID0gW107XG4gIG1lbnVCdXR0b25zOiBDbHJCdXR0b25bXSA9IFtdO1xuXG4gIC8vIEluZGljYXRlcyB0aGUgcG9zaXRpb24gb2YgdGhlIG92ZXJmbG93IG1lbnVcbiAgcHJpdmF0ZSBfbWVudVBvc2l0aW9uOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGJ1dHRvbkdyb3VwTmV3U2VydmljZTogQnV0dG9uSW5Hcm91cFNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0b2dnbGVTZXJ2aWNlOiBDbHJQb3BvdmVyVG9nZ2xlU2VydmljZSxcbiAgICBwdWJsaWMgY29tbW9uU3RyaW5nczogQ2xyQ29tbW9uU3RyaW5nc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBkZXN0cm95JDogQ2xyRGVzdHJveVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBmb2N1c0hhbmRsZXI6IEJ1dHRvbkdyb3VwRm9jdXNIYW5kbGVyXG4gICkge31cblxuICBASW5wdXQoJ2Nsck1lbnVQb3NpdGlvbicpXG4gIGdldCBtZW51UG9zaXRpb24oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fbWVudVBvc2l0aW9uO1xuICB9XG4gIHNldCBtZW51UG9zaXRpb24ocG9zOiBzdHJpbmcpIHtcbiAgICBpZiAocG9zICYmIChDbHJQb3BvdmVyUG9zaXRpb25zIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Bvc10pIHtcbiAgICAgIHRoaXMuX21lbnVQb3NpdGlvbiA9IHBvcztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fbWVudVBvc2l0aW9uID0gJ2JvdHRvbS1sZWZ0JztcbiAgICB9XG5cbiAgICB0aGlzLnBvcG92ZXJQb3NpdGlvbiA9IChDbHJQb3BvdmVyUG9zaXRpb25zIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3RoaXMuX21lbnVQb3NpdGlvbl07XG4gIH1cblxuICBnZXQgb3BlbigpIHtcbiAgICByZXR1cm4gdGhpcy50b2dnbGVTZXJ2aWNlLm9wZW47XG4gIH1cblxuICAvKipcbiAgICogMS4gSW5pdGlhbGl6ZXMgdGhlIGluaXRpYWwgQnV0dG9uIEdyb3VwIFZpZXdcbiAgICogMi4gU3Vic2NyaWJlcyB0byBjaGFuZ2VzIG9uIHRoZSBDb250ZW50Q2hpbGRyZW5cbiAgICogICAgaW4gY2FzZSB0aGUgdXNlciBjb250ZW50IHByb2plY3Rpb24gY2hhbmdlc1xuICAgKi9cbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgIHRoaXMuaW5pdGlhbGl6ZUJ1dHRvbnMoKTtcbiAgICB0aGlzLmJ1dHRvbkdyb3VwTmV3U2VydmljZS5jaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoYnV0dG9uID0+IHRoaXMucmVhcnJhbmdlQnV0dG9uKGJ1dHRvbikpO1xuICAgIHRoaXMuYnV0dG9ucy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLmluaXRpYWxpemVCdXR0b25zKCk7XG4gICAgfSk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5oYW5kbGVGb2N1c09uTWVudU9wZW4oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlcyB0aGUgYnV0dG9uIGludG8gdGhlIG90aGVyIFZpZXdDb250YWluZXJcbiAgICogd2hlbiBhbiB1cGRhdGUgaXMgcmVjZWl2ZWQuXG4gICAqXG4gICAqIEBwYXJhbSBidXR0b25cbiAgICovXG4gIHJlYXJyYW5nZUJ1dHRvbihidXR0b246IENsckJ1dHRvbik6IHZvaWQge1xuICAgIGxldCBmcm9tVmlldzogQ2xyQnV0dG9uW107XG4gICAgbGV0IHRvVmlldzogQ2xyQnV0dG9uW107XG4gICAgaWYgKGJ1dHRvbi5pbk1lbnUpIHtcbiAgICAgIGZyb21WaWV3ID0gdGhpcy5pbmxpbmVCdXR0b25zO1xuICAgICAgdG9WaWV3ID0gdGhpcy5tZW51QnV0dG9ucztcbiAgICB9IGVsc2Uge1xuICAgICAgZnJvbVZpZXcgPSB0aGlzLm1lbnVCdXR0b25zO1xuICAgICAgdG9WaWV3ID0gdGhpcy5pbmxpbmVCdXR0b25zO1xuICAgIH1cbiAgICBjb25zdCBpbmRleDogbnVtYmVyID0gZnJvbVZpZXcuaW5kZXhPZihidXR0b24pO1xuICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICBmcm9tVmlldy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgY29uc3QgbW92ZUluZGV4ID0gdGhpcy5nZXRNb3ZlSW5kZXgoYnV0dG9uKTtcbiAgICAgIGlmIChtb3ZlSW5kZXggPD0gdG9WaWV3Lmxlbmd0aCkge1xuICAgICAgICB0b1ZpZXcuc3BsaWNlKG1vdmVJbmRleCwgMCwgYnV0dG9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvcGVuTWVudShldmVudDogRXZlbnQsIGluaXRpYWxGb2N1czogSW5pdGlhbEZvY3VzKSB7XG4gICAgdGhpcy5mb2N1c0hhbmRsZXIuaW5pdGlhbEZvY3VzID0gaW5pdGlhbEZvY3VzO1xuICAgIGlmICghdGhpcy50b2dnbGVTZXJ2aWNlLm9wZW4pIHtcbiAgICAgIHRoaXMudG9nZ2xlU2VydmljZS50b2dnbGVXaXRoRXZlbnQoZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBdXRob3I6IEV1ZGVzXG4gICAqXG4gICAqIEZpbmRzIHRoZSBvcmRlciBvZiBhIGJ1dHRvbiB3LnIudCBvdGhlciBidXR0b25zXG4gICAqXG4gICAqIEBwYXJhbSBidXR0b25Ub01vdmVcbiAgICogQHJldHVybnNcbiAgICovXG4gIGdldE1vdmVJbmRleChidXR0b25Ub01vdmU6IENsckJ1dHRvbik6IG51bWJlciB7XG4gICAgY29uc3QgdGVtcEFycjogQ2xyQnV0dG9uW10gPSB0aGlzLmJ1dHRvbnMuZmlsdGVyKGJ1dHRvbiA9PiBidXR0b24uaW5NZW51ID09PSBidXR0b25Ub01vdmUuaW5NZW51KTtcbiAgICByZXR1cm4gdGVtcEFyci5pbmRleE9mKGJ1dHRvblRvTW92ZSk7XG4gIH1cblxuICBpbml0aWFsaXplQnV0dG9ucygpOiB2b2lkIHtcbiAgICBjb25zdCB0ZW1wSW5saW5lQnV0dG9uczogQ2xyQnV0dG9uW10gPSBbXTtcbiAgICBjb25zdCB0ZW1wSW5NZW51QnV0dG9uczogQ2xyQnV0dG9uW10gPSBbXTtcbiAgICB0aGlzLmJ1dHRvbnMuZm9yRWFjaChidXR0b24gPT4ge1xuICAgICAgaWYgKGJ1dHRvbi5pbk1lbnUpIHtcbiAgICAgICAgdGVtcEluTWVudUJ1dHRvbnMucHVzaChidXR0b24pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGVtcElubGluZUJ1dHRvbnMucHVzaChidXR0b24pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMuaW5saW5lQnV0dG9ucyA9IHRlbXBJbmxpbmVCdXR0b25zO1xuICAgIHRoaXMubWVudUJ1dHRvbnMgPSB0ZW1wSW5NZW51QnV0dG9ucztcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlRm9jdXNPbk1lbnVPcGVuKCkge1xuICAgIGlmICh0aGlzLm1lbnVCdXR0b25zLmxlbmd0aCkge1xuICAgICAgdGhpcy50b2dnbGVTZXJ2aWNlLnBvcG92ZXJWaXNpYmxlLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUodmlzaWJsZSA9PiB7XG4gICAgICAgIGlmICh2aXNpYmxlKSB7XG4gICAgICAgICAgdGhpcy5mb2N1c0hhbmRsZXIuaW5pdGlhbGl6ZSh7XG4gICAgICAgICAgICBtZW51OiB0aGlzLm1lbnUubmF0aXZlRWxlbWVudCxcbiAgICAgICAgICAgIG1lbnVUb2dnbGU6IHRoaXMubWVudVRvZ2dsZS5uYXRpdmVFbGVtZW50LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiIsIjwhLS1cbiAgfiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAyMyBWTXdhcmUsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAgfiBUaGlzIHNvZnR3YXJlIGlzIHJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlLlxuICB+IFRoZSBmdWxsIGxpY2Vuc2UgaW5mb3JtYXRpb24gY2FuIGJlIGZvdW5kIGluIExJQ0VOU0UgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgcHJvamVjdC5cbiAgLS0+XG5cbjxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGlubGluZUJ1dHRvbiBvZiBpbmxpbmVCdXR0b25zXCI+XG4gIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJpbmxpbmVCdXR0b24udGVtcGxhdGVSZWZcIj48L25nLXRlbXBsYXRlPlxuPC9uZy1jb250YWluZXI+XG48bmctY29udGFpbmVyICpuZ0lmPVwibWVudUJ1dHRvbnMubGVuZ3RoID4gMFwiPlxuICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwLW92ZXJmbG93IG9wZW5cIiBbbmdDbGFzc109XCJtZW51UG9zaXRpb25cIiAjYW5jaG9yPlxuICAgIDxidXR0b25cbiAgICAgICNtZW51VG9nZ2xlXG4gICAgICBjbGFzcz1cImJ0biBkcm9wZG93bi10b2dnbGVcIlxuICAgICAgY2xyUG9wb3ZlckFuY2hvclxuICAgICAgY2xyUG9wb3Zlck9wZW5DbG9zZUJ1dHRvblxuICAgICAgKGtleWRvd24uYXJyb3d1cCk9XCJvcGVuTWVudSgkZXZlbnQsIEluaXRpYWxGb2N1cy5MQVNUX0lURU0pXCJcbiAgICAgIChrZXlkb3duLmFycm93ZG93bik9XCJvcGVuTWVudSgkZXZlbnQsIEluaXRpYWxGb2N1cy5GSVJTVF9JVEVNKVwiXG4gICAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cInBvcG92ZXJJZFwiXG4gICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cIm9wZW5cIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJjbHJUb2dnbGVCdXR0b25BcmlhTGFiZWxcIlxuICAgID5cbiAgICAgIDxjZHMtaWNvbiBzaGFwZT1cImVsbGlwc2lzLWhvcml6b250YWxcIiBbYXR0ci50aXRsZV09XCJjb21tb25TdHJpbmdzLmtleXMubW9yZVwiPjwvY2RzLWljb24+XG4gICAgPC9idXR0b24+XG4gICAgPGRpdlxuICAgICAgI21lbnVcbiAgICAgIHJvbGU9XCJtZW51XCJcbiAgICAgIGNsYXNzPVwiZHJvcGRvd24tbWVudSBjbHItYnV0dG9uLWdyb3VwLW1lbnVcIlxuICAgICAgW2lkXT1cInBvcG92ZXJJZFwiXG4gICAgICBbYXR0ci5pZF09XCJwb3BvdmVySWRcIlxuICAgICAgW2F0dHIuYXJpYS1oaWRkZW5dPVwiIW9wZW5cIlxuICAgICAgKmNsclBvcG92ZXJDb250ZW50PVwib3BlbiBhdCBwb3BvdmVyUG9zaXRpb247IG91dHNpZGVDbGlja1RvQ2xvc2U6IHRydWU7IHNjcm9sbFRvQ2xvc2U6IHRydWVcIlxuICAgID5cbiAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJyZWZcIj48L25nLXRlbXBsYXRlPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPlxuPG5nLXRlbXBsYXRlICNyZWY+XG4gIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IG1lbnVCdXR0b24gb2YgbWVudUJ1dHRvbnNcIj5cbiAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwibWVudUJ1dHRvbi50ZW1wbGF0ZVJlZlwiPjwvbmctdGVtcGxhdGU+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==