@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
406 lines • 43.6 kB
JavaScript
import { __decorate, __metadata, __param } from "tslib";
import { CommonModule } from '@angular/common';
import { AfterContentInit, AfterViewInit, Component, ContentChildren, ChangeDetectorRef, EventEmitter, HostBinding, Inject, Input, NgModule, Output, Optional, QueryList, Renderer2, ViewChildren, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { IgxButtonDirective, IgxButtonModule } from '../directives/button/button.directive';
import { IgxRippleModule } from '../directives/ripple/ripple.directive';
import { IgxIconModule } from '../icon/index';
import { takeUntil } from 'rxjs/operators';
import { DisplayDensityBase, DisplayDensityToken } from '../core/density';
export var ButtonGroupAlignment;
(function (ButtonGroupAlignment) {
ButtonGroupAlignment[ButtonGroupAlignment["horizontal"] = 0] = "horizontal";
ButtonGroupAlignment[ButtonGroupAlignment["vertical"] = 1] = "vertical";
})(ButtonGroupAlignment || (ButtonGroupAlignment = {}));
let NEXT_ID = 0;
/**
* **Ignite UI for Angular Button Group** -
* [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/buttongroup.html)
*
* The Ignite UI Button Group displays a group of buttons either vertically or horizontally. The group supports
* single, multiple and toggle selection.
*
* Example:
* ```html
* <igx-buttongroup multiSelection="true" [values]="fontOptions">
* </igx-buttongroup>
* ```
* The `fontOptions` value shown above is defined as:
* ```typescript
* this.fontOptions = [
* { icon: 'format_bold', selected: false },
* { icon: 'format_italic', selected: false },
* { icon: 'format_underlined', selected: false }];
* ```
*/
let IgxButtonGroupComponent = class IgxButtonGroupComponent extends DisplayDensityBase {
constructor(_cdr, _renderer, _displayDensityOptions) {
super(_displayDensityOptions);
this._cdr = _cdr;
this._renderer = _renderer;
this._displayDensityOptions = _displayDensityOptions;
this._disabled = false;
this.buttonClickNotifier$ = new Subject();
this.queryListNotifier$ = new Subject();
/**
* An @Input property that sets the value of the `id` attribute. If not set it will be automatically generated.
* ```html
* <igx-buttongroup [id]="'igx-dialog-56'" [multiSelection]="!multi" [values]="alignOptions">
* ```
*/
this.id = `igx-buttongroup-${NEXT_ID++}`;
/**
* @hidden
*/
this.zIndex = 0;
/**
* An @Input property that enables selecting multiple buttons. By default, multi-selection is false.
* ```html
* <igx-buttongroup [multiSelection]="false" [alignment]="alignment"></igx-buttongroup>
* ```
*/
this.multiSelection = false;
/**
* @hidden
*/
this.selectedIndexes = [];
/**
* An @Ouput property that emits an event when a button is selected.
*```typescript
*@ViewChild("toast")
*private toast: IgxToastComponent;
*public onSelect(buttongroup){
* this.toast.show()
*}
* //...
*```
*```html
* <igx-buttongroup #MyChild [multiSelection]="!multi" (onSelect)="onSelect($event)"></igx-buttongroup>
*<igx-toast #toast message="You have made a selection!"></igx-toast>
*```
*/
this.onSelect = new EventEmitter();
/**
* An @Ouput property that emits an event when a button is deselected.
*```typescript
*@ViewChild("toast")
*private toast: IgxToastComponent;
*public onUnselect(buttongroup){
* this.toast.show()
*}
* //...
*```
*```html
* igx-buttongroup #MyChild [multiSelection]="multi" (onUnselect)="onUnselect($event)"></igx-buttongroup>
*<igx-toast #toast message="You have deselected a button!"></igx-toast>
*```
*/
this.onUnselect = new EventEmitter();
}
/**
* A collection containing all buttons inside the button group.
*/
get buttons() {
return [...this.viewButtons.toArray(), ...this.templateButtons.toArray()];
}
/**
* Allows you to set a style using the `itemContentCssClass` input.
* The value should be the CSS class name that will be applied to the button group.
*```typescript
*public style1 = "styleClass";
* //..
*```
* ```html
*<igx-buttongroup [itemContentCssClass]="style1" [multiSelection]="!multi" [values]="alignOptions">
*```
*/
set itemContentCssClass(value) {
this._itemContentCssClass = value || this._itemContentCssClass;
}
/**
* Returns the CSS class of the item content of the `IgxButtonGroup`.
*```typescript
*@ViewChild("MyChild")
*public buttonG: IgxButtonGroupComponent;
*ngAfterViewInit(){
* let buttonSelect = this.buttonG.itemContentCssClass;
*}
*```
*/
get itemContentCssClass() {
return this._itemContentCssClass;
}
/**
* An @Input property that allows you to disable the `igx-buttongroup` component. By default it's false.
* ```html
* <igx-buttongroup [disabled]="true" [multiSelection]="multi" [values]="fontOptions"></igx-buttongroup>
* ```
*/
get disabled() {
return this._disabled;
}
set disabled(value) {
if (this._disabled !== value) {
this._disabled = value;
if (this.viewButtons && this.templateButtons) {
this.buttons.forEach((b) => b.disabled = this._disabled);
}
}
}
/**
* Allows you to set the button group alignment.
* Available options are `ButtonGroupAlignment.horizontal` (default) and `ButtonGroupAlignment.vertical`.
* ```typescript
*public alignment = ButtonGroupAlignment.vertical;
* //..
* ```
* ```html
*<igx-buttongroup [multiSelection]="false" [values]="cities" [alignment]="alignment"></igx-buttongroup>
* ```
*/
set alignment(value) {
this._isVertical = value === ButtonGroupAlignment.vertical;
}
/**
* Returns the alignment of the `igx-buttongroup`.
*```typescript
*@ViewChild("MyChild")
*public buttonG: IgxButtonGroupComponent;
*ngAfterViewInit(){
* let buttonAlignment = this.buttonG.alignment;
*}
*```
*/
get alignment() {
return this._isVertical ? ButtonGroupAlignment.vertical : ButtonGroupAlignment.horizontal;
}
/**
* Returns true if the `igx-buttongroup` alignment is vertical.
* Note that in order for the accessor to work correctly the property should be set explicitly.
* ```html
* <igx-buttongroup #MyChild [alignment]="alignment" [values]="alignOptions">
* ```
* ```typescript
* //...
*@ViewChild("MyChild")
*private buttonG: IgxButtonGroupComponent;
*ngAfterViewInit(){
* let orientation = this.buttonG.isVertical;
*}
*```
*/
get isVertical() {
return this._isVertical;
}
/**
* Gets the selected button/buttons.
*```typescript
*@ViewChild("MyChild")
*private buttonG: IgxButtonGroupComponent;
*ngAfterViewInit(){
* let selectedButton = this.buttonG.selectedButtons;
*}
*```
*/
get selectedButtons() {
return this.buttons.filter((b, i) => {
return this.selectedIndexes.indexOf(i) !== -1;
});
}
/**
* Selects a button by its index.
*```typescript
*@ViewChild("MyChild")
*private buttonG: IgxButtonGroupComponent;
*ngAfterViewInit(){
* this.buttonG.selectButton(2);
* this.cdr.detectChanges();
*}
*```
* @memberOf {@link IgxButtonGroupComponent}
*/
selectButton(index) {
if (index >= this.buttons.length || index < 0) {
return;
}
const button = this.buttons[index];
const buttonElement = button.nativeElement;
this.selectedIndexes.push(index);
button.selected = true;
this._renderer.setAttribute(buttonElement, 'aria-pressed', 'true');
this._renderer.addClass(buttonElement, 'igx-button-group__item--selected');
this.onSelect.emit({ button: button, index: index });
const indexInViewButtons = this.viewButtons.toArray().indexOf(button);
if (indexInViewButtons !== -1) {
this.values[indexInViewButtons].selected = true;
}
// deselect other buttons if multiSelection is not enabled
if (!this.multiSelection && this.selectedIndexes.length > 1) {
this.buttons.forEach((b, i) => {
if (i !== index && this.selectedIndexes.indexOf(i) !== -1) {
this.deselectButton(i);
}
});
}
}
/**
* Deselects a button by its index.
* ```typescript
*@ViewChild("MyChild")
*private buttonG: IgxButtonGroupComponent;
*ngAfterViewInit(){
* this.buttonG.deselectButton(2);
* this.cdr.detectChanges();
*}
* ```
* @memberOf {@link IgxButtonGroupComponent}
*/
deselectButton(index) {
if (index >= this.buttons.length || index < 0) {
return;
}
const button = this.buttons[index];
const buttonElement = button.nativeElement;
this.selectedIndexes.splice(this.selectedIndexes.indexOf(index), 1);
button.selected = false;
this._renderer.setAttribute(buttonElement, 'aria-pressed', 'false');
this._renderer.removeClass(buttonElement, 'igx-button-group__item--selected');
this.onUnselect.emit({ button: button, index: index });
const indexInViewButtons = this.viewButtons.toArray().indexOf(button);
if (indexInViewButtons !== -1) {
this.values[indexInViewButtons].selected = false;
}
}
/**
* @hidden
*/
ngAfterContentInit() {
this.templateButtons.forEach((button) => {
if (!button.initialDensity) {
button.displayDensity = this.displayDensity;
}
});
}
/**
* @hidden
*/
ngAfterViewInit() {
const initButtons = () => {
// Cancel any existing buttonClick subscriptions
this.buttonClickNotifier$.next();
this.selectedIndexes.splice(0, this.selectedIndexes.length);
// initial configuration
this.buttons.forEach((button, index) => {
const buttonElement = button.nativeElement;
if (this.disabled) {
button.disabled = true;
}
if (button.selected) {
this.selectButton(index);
}
button.buttonClick.pipe(takeUntil(this.buttonClickNotifier$)).subscribe((ev) => this._clickHandler(ev, index));
this._renderer.addClass(buttonElement, 'igx-button-group__item');
});
};
this.viewButtons.changes.pipe(takeUntil(this.queryListNotifier$)).subscribe(() => initButtons());
this.templateButtons.changes.pipe(takeUntil(this.queryListNotifier$)).subscribe(() => initButtons());
initButtons();
this._cdr.detectChanges();
}
/**
* @hidden
*/
ngOnDestroy() {
this.buttonClickNotifier$.next();
this.buttonClickNotifier$.complete();
this.queryListNotifier$.next();
this.queryListNotifier$.complete();
}
/**
*@hidden
*/
_clickHandler(event, i) {
if (this.selectedIndexes.indexOf(i) !== -1) {
this.deselectButton(i);
}
else {
this.selectButton(i);
}
}
};
IgxButtonGroupComponent.ctorParameters = () => [
{ type: ChangeDetectorRef },
{ type: Renderer2 },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DisplayDensityToken,] }] }
];
__decorate([
ViewChildren(IgxButtonDirective),
__metadata("design:type", QueryList)
], IgxButtonGroupComponent.prototype, "viewButtons", void 0);
__decorate([
ContentChildren(IgxButtonDirective),
__metadata("design:type", QueryList)
], IgxButtonGroupComponent.prototype, "templateButtons", void 0);
__decorate([
HostBinding('attr.id'),
Input(),
__metadata("design:type", Object)
], IgxButtonGroupComponent.prototype, "id", void 0);
__decorate([
HostBinding('style.zIndex'),
__metadata("design:type", Object)
], IgxButtonGroupComponent.prototype, "zIndex", void 0);
__decorate([
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], IgxButtonGroupComponent.prototype, "itemContentCssClass", null);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxButtonGroupComponent.prototype, "multiSelection", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxButtonGroupComponent.prototype, "values", void 0);
__decorate([
Input(),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [Boolean])
], IgxButtonGroupComponent.prototype, "disabled", null);
__decorate([
Input(),
__metadata("design:type", Number),
__metadata("design:paramtypes", [Number])
], IgxButtonGroupComponent.prototype, "alignment", null);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxButtonGroupComponent.prototype, "onSelect", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxButtonGroupComponent.prototype, "onUnselect", void 0);
IgxButtonGroupComponent = __decorate([
Component({
selector: 'igx-buttongroup',
template: "<div class=\"igx-button-group\" role=\"group\" [class.igx-button-group--vertical]=\"isVertical\">\n <button *ngFor=\"let button of values; let i = 'index'\"\n type=\"button\"\n igxButton=\"flat\"\n [displayDensity]=\"displayDensity\"\n [selected]=\"button.selected\"\n [attr.data-togglable]=\"button.togglable\"\n [disabled]=\"disabled || button.disabled\"\n [igxButtonColor]=\"button.color\"\n [igxButtonBackground]=\"button.bgcolor\"\n [igxLabel]=\"button.label\"\n [igxRipple]=\"button.ripple\"\n >\n <div class=\"igx-button-group__item-content {{ itemContentCssClass }}\">\n <igx-icon *ngIf=\"button.icon\" fontSet=\"material\">{{button.icon}}</igx-icon>\n <span *ngIf=\"button.label\">{{button.label}}</span>\n </div>\n </button>\n <ng-content></ng-content>\n</div>\n"
}),
__param(2, Optional()), __param(2, Inject(DisplayDensityToken)),
__metadata("design:paramtypes", [ChangeDetectorRef, Renderer2, Object])
], IgxButtonGroupComponent);
export { IgxButtonGroupComponent };
/**
* @hidden
*/
let IgxButtonGroupModule = class IgxButtonGroupModule {
};
IgxButtonGroupModule = __decorate([
NgModule({
declarations: [IgxButtonGroupComponent],
exports: [IgxButtonGroupComponent],
imports: [IgxButtonModule, CommonModule, IgxRippleModule, IgxIconModule]
})
], IgxButtonGroupModule);
export { IgxButtonGroupModule };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uR3JvdXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vaWduaXRldWktYW5ndWxhci8iLCJzb3VyY2VzIjpbImxpYi9idXR0b25Hcm91cC9idXR0b25Hcm91cC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0gsZ0JBQWdCLEVBQ2hCLGFBQWEsRUFDYixTQUFTLEVBQ1QsZUFBZSxFQUNmLGlCQUFpQixFQUNqQixZQUFZLEVBQ1osV0FBVyxFQUNYLE1BQU0sRUFDTixLQUFLLEVBQ0wsUUFBUSxFQUNSLE1BQU0sRUFDTixRQUFRLEVBQ1IsU0FBUyxFQUNULFNBQVMsRUFDVCxZQUFZLEVBQ1osU0FBUyxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzVGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUN4RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsbUJBQW1CLEVBQTBCLE1BQU0saUJBQWlCLENBQUM7QUFHbEcsTUFBTSxDQUFOLElBQVksb0JBQTZDO0FBQXpELFdBQVksb0JBQW9CO0lBQUcsMkVBQVUsQ0FBQTtJQUFFLHVFQUFRLENBQUE7QUFBQyxDQUFDLEVBQTdDLG9CQUFvQixLQUFwQixvQkFBb0IsUUFBeUI7QUFDekQsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBRWhCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBTUgsSUFBYSx1QkFBdUIsR0FBcEMsTUFBYSx1QkFBd0Is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ZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENvbXBvbmVudCxcbiAgICBDb250ZW50Q2hpbGRyZW4sXG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIEluamVjdCxcbiAgICBJbnB1dCxcbiAgICBOZ01vZHVsZSxcbiAgICBPdXRwdXQsXG4gICAgT3B0aW9uYWwsXG4gICAgUXVlcnlMaXN0LFxuICAgIFJlbmRlcmVyMixcbiAgICBWaWV3Q2hpbGRyZW4sXG4gICAgT25EZXN0cm95XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSWd4QnV0dG9uRGlyZWN0aXZlLCBJZ3hCdXR0b25Nb2R1bGUgfSBmcm9tICcuLi9kaXJlY3RpdmVzL2J1dHRvbi9idXR0b24uZGlyZWN0aXZlJztcbmltcG9ydCB7IElneFJpcHBsZU1vZHVsZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvcmlwcGxlL3JpcHBsZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgSWd4SWNvbk1vZHVsZSB9IGZyb20gJy4uL2ljb24vaW5kZXgnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgRGlzcGxheURlbnNpdHlCYXNlLCBEaXNwbGF5RGVuc2l0eVRva2VuLCBJRGlzcGxheURlbnNpdHlPcHRpb25zIH0gZnJvbSAnLi4vY29yZS9kZW5zaXR5JztcbmltcG9ydCB7IElCYXNlRXZlbnRBcmdzIH0gZnJvbSAnLi4vY29yZS91dGlscyc7XG5cbmV4cG9ydCBlbnVtIEJ1dHRvbkdyb3VwQWxpZ25tZW50IHsgaG9yaXpvbnRhbCwgdmVydGljYWwgfVxubGV0IE5FWFRfSUQgPSAwO1xuXG4vKipcbiAqICoqSWduaXRlIFVJIGZvciBBbmd1bGFyIEJ1dHRvbiBHcm91cCoqIC1cbiAqIFtEb2N1bWVudGF0aW9uXShodHRwczovL3d3dy5pbmZyYWdpc3RpY3MuY29tL3Byb2R1Y3RzL2lnbml0ZS11aS1hbmd1bGFyL2FuZ3VsYXIvY29tcG9uZW50cy9idXR0b25ncm91cC5odG1sKVxuICpcbiAqIFRoZSBJZ25pdGUgVUkgQnV0dG9uIEdyb3VwIGRpc3BsYXlzIGEgZ3JvdXAgb2YgYnV0dG9ucyBlaXRoZXIgdmVydGljYWxseSBvciBob3Jpem9udGFsbHkuICBUaGUgZ3JvdXAgc3VwcG9ydHNcbiAqIHNpbmdsZSwgbXVsdGlwbGUgYW5kIHRvZ2dsZSBzZWxlY3Rpb24uXG4gKlxuICogRXhhbXBsZTpcbiAqIGBgYGh0bWxcbiAqIDxpZ3gtYnV0dG9uZ3JvdXAgbXVsdGlTZWxlY3Rpb249XCJ0cnVlXCIgW3ZhbHVlc109XCJmb250T3B0aW9uc1wiPlxuICogPC9pZ3gtYnV0dG9uZ3JvdXA+XG4gKiBgYGBcbiAqIFRoZSBgZm9udE9wdGlvbnNgIHZhbHVlIHNob3duIGFib3ZlIGlzIGRlZmluZWQgYXM6XG4gKiBgYGB0eXBlc2NyaXB0XG4gKiB0aGlzLmZvbnRPcHRpb25zID0gW1xuICogICB7IGljb246ICdmb3JtYXRfYm9sZCcsIHNlbGVjdGVkOiBmYWxzZSB9LFxuICogICB7IGljb246ICdmb3JtYXRfaXRhbGljJywgc2VsZWN0ZWQ6IGZhbHNlIH0sXG4gKiAgIHsgaWNvbjogJ2Zvcm1hdF91bmRlcmxpbmVkJywgc2VsZWN0ZWQ6IGZhbHNlIH1dO1xuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnaWd4LWJ1dHRvbmdyb3VwJyxcbiAgICB0ZW1wbGF0ZVVybDogJ2J1dHRvbmdyb3VwLWNvbnRlbnQuY29tcG9uZW50Lmh0bWwnXG59KVxuXG5leHBvcnQgY2xhc3MgSWd4QnV0dG9uR3JvdXBDb21wb25lbnQgZXh0ZW5kcyBEaXNwbGF5RGVuc2l0eUJhc2UgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gICAgcHJpdmF0ZSBfZGlzYWJsZWQgPSBmYWxzZTtcbiAgICBwcm90ZWN0ZWQgYnV0dG9uQ2xpY2tOb3RpZmllciQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuICAgIHByb3RlY3RlZCBxdWVyeUxpc3ROb3RpZmllciQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuXG4gICAgQFZpZXdDaGlsZHJlbihJZ3hCdXR0b25EaXJlY3RpdmUpIHByaXZhdGUgdmlld0J1dHRvbnM6IFF1ZXJ5TGlzdDxJZ3hCdXR0b25EaXJlY3RpdmU+O1xuICAgIEBDb250ZW50Q2hpbGRyZW4oSWd4QnV0dG9uRGlyZWN0aXZlKSBwcml2YXRlIHRlbXBsYXRlQnV0dG9uczogUXVlcnlMaXN0PElneEJ1dHRvbkRpcmVjdGl2ZT47XG5cbiAgICAvKipcbiAgICAgKiBBIGNvbGxlY3Rpb24gY29udGFpbmluZyBhbGwgYnV0dG9ucyBpbnNpZGUgdGhlIGJ1dHRvbiBncm91cC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGJ1dHRvbnMoKTogSWd4QnV0dG9uRGlyZWN0aXZlW10ge1xuICAgICAgICByZXR1cm4gWy4uLnRoaXMudmlld0J1dHRvbnMudG9BcnJheSgpLCAuLi50aGlzLnRlbXBsYXRlQnV0dG9ucy50b0FycmF5KCldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IHNldHMgdGhlIHZhbHVlIG9mIHRoZSBgaWRgIGF0dHJpYnV0ZS4gSWYgbm90IHNldCBpdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiAgPGlneC1idXR0b25ncm91cCBbaWRdPVwiJ2lneC1kaWFsb2ctNTYnXCIgW211bHRpU2VsZWN0aW9uXT1cIiFtdWx0aVwiIFt2YWx1ZXNdPVwiYWxpZ25PcHRpb25zXCI+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmlkJylcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBpZCA9IGBpZ3gtYnV0dG9uZ3JvdXAtJHtORVhUX0lEKyt9YDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLnpJbmRleCcpXG4gICAgcHVibGljIHpJbmRleCA9IDA7XG5cbiAgICAvKipcbiAgICAgKiBBbGxvd3MgeW91IHRvIHNldCBhIHN0eWxlIHVzaW5nIHRoZSBgaXRlbUNvbnRlbnRDc3NDbGFzc2AgaW5wdXQuXG4gICAgICogVGhlIHZhbHVlIHNob3VsZCBiZSB0aGUgQ1NTIGNsYXNzIG5hbWUgdGhhdCB3aWxsIGJlIGFwcGxpZWQgdG8gdGhlIGJ1dHRvbiBncm91cC5cbiAgICAgKmBgYHR5cGVzY3JpcHRcbiAgICAgKnB1YmxpYyBzdHlsZTEgPSBcInN0eWxlQ2xhc3NcIjtcbiAgICAgKiAvLy4uXG4gICAgICpgYGBcbiAgICAgKiBgYGBodG1sXG4gICAgICo8aWd4LWJ1dHRvbmdyb3VwIFtpdGVtQ29udGVudENzc0NsYXNzXT1cInN0eWxlMVwiIFttdWx0aVNlbGVjdGlvbl09XCIhbXVsdGlcIiBbdmFsdWVzXT1cImFsaWduT3B0aW9uc1wiPlxuICAgICAqYGBgXG4gICAgICovXG4gICAgQElucHV0KCkgc2V0IGl0ZW1Db250ZW50Q3NzQ2xhc3ModmFsdWU6IHN0cmluZykge1xuICAgICAgICB0aGlzLl9pdGVtQ29udGVudENzc0NsYXNzID0gdmFsdWUgfHwgdGhpcy5faXRlbUNvbnRlbnRDc3NDbGFzcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBDU1MgY2xhc3Mgb2YgdGhlIGl0ZW0gY29udGVudCBvZiB0aGUgYElneEJ1dHRvbkdyb3VwYC5cbiAgICAgKmBgYHR5cGVzY3JpcHRcbiAgICAgKkBWaWV3Q2hpbGQoXCJNeUNoaWxkXCIpXG4gICAgICpwdWJsaWMgYnV0dG9uRzogSWd4QnV0dG9uR3JvdXBDb21wb25lbnQ7XG4gICAgICpuZ0FmdGVyVmlld0luaXQoKXtcbiAgICAgKiAgIGxldCBidXR0b25TZWxlY3QgPSB0aGlzLmJ1dHRvbkcuaXRlbUNvbnRlbnRDc3NDbGFzcztcbiAgICAgKn1cbiAgICAgKmBgYFxuICAgICAqL1xuICAgIGdldCBpdGVtQ29udGVudENzc0NsYXNzKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pdGVtQ29udGVudENzc0NsYXNzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IGVuYWJsZXMgc2VsZWN0aW5nIG11bHRpcGxlIGJ1dHRvbnMuIEJ5IGRlZmF1bHQsIG11bHRpLXNlbGVjdGlvbiBpcyBmYWxzZS5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1idXR0b25ncm91cCBbbXVsdGlTZWxlY3Rpb25dPVwiZmFsc2VcIiBbYWxpZ25tZW50XT1cImFsaWdubWVudFwiPjwvaWd4LWJ1dHRvbmdyb3VwPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBtdWx0aVNlbGVjdGlvbiA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IGFsbG93cyBzZXR0aW5nIHRoZSBidXR0b25zIGluIHRoZSBidXR0b24gZ3JvdXAuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgICogICAgICB0aGlzLmNpdGllcyA9IFtcbiAgICAgKiAgICAgICAgbmV3IEJ1dHRvbih7XG4gICAgICogICAgICAgICAgbGFiZWw6IFwiU29maWFcIlxuICAgICAqICAgICAgfSksXG4gICAgICogICAgICAgIG5ldyBCdXR0b24oe1xuICAgICAqICAgICAgICAgIGxhYmVsOiBcIkxvbmRvblwiXG4gICAgICogICAgICB9KSxcbiAgICAgKiAgICAgICAgbmV3IEJ1dHRvbih7XG4gICAgICogICAgICAgICAgbGFiZWw6IFwiTmV3IFlvcmtcIixcbiAgICAgKiAgICAgICAgICBzZWxlY3RlZDogdHJ1ZVxuICAgICAqICAgICAgfSksXG4gICAgICogICAgICAgIG5ldyBCdXR0b24oe1xuICAgICAqICAgICAgICAgIGxhYmVsOiBcIlRva3lvXCJcbiAgICAgKiAgICAgIH0pXG4gICAgICogIF07XG4gICAgICogIH1cbiAgICAgKiAgLy8uLlxuICAgICAqIGBgYFxuICAgICAqIGBgYGh0bWxcbiAgICAgKiAgPGlneC1idXR0b25ncm91cCBbbXVsdGlTZWxlY3Rpb25dPVwiZmFsc2VcIiBbdmFsdWVzXT1cImNpdGllc1wiPjwvaWd4LWJ1dHRvbmdyb3VwPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyB2YWx1ZXM6IGFueTtcbiAgICAvKipcbiAgICAgKiBBbiBASW5wdXQgcHJvcGVydHkgdGhhdCBhbGxvd3MgeW91IHRvIGRpc2FibGUgdGhlIGBpZ3gtYnV0dG9uZ3JvdXBgIGNvbXBvbmVudC4gQnkgZGVmYXVsdCBpdCdzIGZhbHNlLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWJ1dHRvbmdyb3VwIFtkaXNhYmxlZF09XCJ0cnVlXCIgW211bHRpU2VsZWN0aW9uXT1cIm11bHRpXCIgW3ZhbHVlc109XCJmb250T3B0aW9uc1wiPjwvaWd4LWJ1dHRvbmdyb3VwPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGdldCBkaXNhYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc2FibGVkO1xuICAgIH1cbiAgICBwdWJsaWMgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIGlmICh0aGlzLl9kaXNhYmxlZCAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX2Rpc2FibGVkID0gdmFsdWU7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnZpZXdCdXR0b25zICYmIHRoaXMudGVtcGxhdGVCdXR0b25zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5idXR0b25zLmZvckVhY2goKGIpID0+IGIuZGlzYWJsZWQgPSB0aGlzLl9kaXNhYmxlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHNlbGVjdGVkSW5kZXhlczogbnVtYmVyW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIEFsbG93cyB5b3UgdG8gc2V0IHRoZSBidXR0b24gZ3JvdXAgYWxpZ25tZW50LlxuICAgICAqIEF2YWlsYWJsZSBvcHRpb25zIGFyZSBgQnV0dG9uR3JvdXBBbGlnbm1lbnQuaG9yaXpvbnRhbGAgKGRlZmF1bHQpIGFuZCBgQnV0dG9uR3JvdXBBbGlnbm1lbnQudmVydGljYWxgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKnB1YmxpYyBhbGlnbm1lbnQgPSBCdXR0b25Hcm91cEFsaWdubWVudC52ZXJ0aWNhbDtcbiAgICAgKiAvLy4uXG4gICAgICogYGBgXG4gICAgICogYGBgaHRtbFxuICAgICAqPGlneC1idXR0b25ncm91cCBbbXVsdGlTZWxlY3Rpb25dPVwiZmFsc2VcIiBbdmFsdWVzXT1cImNpdGllc1wiIFthbGlnbm1lbnRdPVwiYWxpZ25tZW50XCI+PC9pZ3gtYnV0dG9uZ3JvdXA+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KCkgc2V0IGFsaWdubWVudCh2YWx1ZTogQnV0dG9uR3JvdXBBbGlnbm1lbnQpIHtcbiAgICAgICAgdGhpcy5faXNWZXJ0aWNhbCA9IHZhbHVlID09PSBCdXR0b25Hcm91cEFsaWdubWVudC52ZXJ0aWNhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgYWxpZ25tZW50IG9mIHRoZSBgaWd4LWJ1dHRvbmdyb3VwYC5cbiAgICAgKmBgYHR5cGVzY3JpcHRcbiAgICAgKkBWaWV3Q2hpbGQoXCJNeUNoaWxkXCIpXG4gICAgICpwdWJsaWMgYnV0dG9uRzogSWd4QnV0dG9uR3JvdXBDb21wb25lbnQ7XG4gICAgICpuZ0FmdGVyVmlld0luaXQoKXtcbiAgICAgKiAgICBsZXQgYnV0dG9uQWxpZ25tZW50ID0gdGhpcy5idXR0b25HLmFsaWdubWVudDtcbiAgICAgKn1cbiAgICAgKmBgYFxuICAgICAqL1xuICAgIGdldCBhbGlnbm1lbnQoKTogQnV0dG9uR3JvdXBBbGlnbm1lbnQge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNWZXJ0aWNhbCA/IEJ1dHRvbkdyb3VwQWxpZ25tZW50LnZlcnRpY2FsIDogQnV0dG9uR3JvdXBBbGlnbm1lbnQuaG9yaXpvbnRhbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbiBAT3VwdXQgcHJvcGVydHkgdGhhdCBlbWl0cyBhbiBldmVudCB3aGVuIGEgYnV0dG9uIGlzIHNlbGVjdGVkLlxuICAgICAqYGBgdHlwZXNjcmlwdFxuICAgICAqQFZpZXdDaGlsZChcInRvYXN0XCIpXG4gICAgICpwcml2YXRlIHRvYXN0OiBJZ3hUb2FzdENvbXBvbmVudDtcbiAgICAgKnB1YmxpYyBvblNlbGVjdChidXR0b25ncm91cCl7XG4gICAgICogICAgdGhpcy50b2FzdC5zaG93KClcbiAgICAgKn1cbiAgICAgKiAvLy4uLlxuICAgICAqYGBgXG4gICAgICpgYGBodG1sXG4gICAgICogPGlneC1idXR0b25ncm91cCAjTXlDaGlsZCBbbXVsdGlTZWxlY3Rpb25dPVwiIW11bHRpXCIgKG9uU2VsZWN0KT1cIm9uU2VsZWN0KCRldmVudClcIj48L2lneC1idXR0b25ncm91cD5cbiAgICAgKjxpZ3gtdG9hc3QgI3RvYXN0IG1lc3NhZ2U9XCJZb3UgaGF2ZSBtYWRlIGEgc2VsZWN0aW9uIVwiPjwvaWd4LXRvYXN0PlxuICAgICAqYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvblNlbGVjdCA9IG5ldyBFdmVudEVtaXR0ZXI8SUJ1dHRvbkdyb3VwRXZlbnRBcmdzPigpO1xuXG4gICAgLyoqXG4gICAgICogQW4gQE91cHV0IHByb3BlcnR5IHRoYXQgZW1pdHMgYW4gZXZlbnQgd2hlbiBhIGJ1dHRvbiBpcyBkZXNlbGVjdGVkLlxuICAgICAqYGBgdHlwZXNjcmlwdFxuICAgICAqQFZpZXdDaGlsZChcInRvYXN0XCIpXG4gICAgICpwcml2YXRlIHRvYXN0OiBJZ3hUb2FzdENvbXBvbmVudDtcbiAgICAgKnB1YmxpYyBvblVuc2VsZWN0KGJ1dHRvbmdyb3VwKXtcbiAgICAgKiAgICB0aGlzLnRvYXN0LnNob3coKVxuICAgICAqfVxuICAgICAqIC8vLi4uXG4gICAgICpgYGBcbiAgICAgKmBgYGh0bWxcbiAgICAgKiBpZ3gtYnV0dG9uZ3JvdXAgI015Q2hpbGQgW211bHRpU2VsZWN0aW9uXT1cIm11bHRpXCIgKG9uVW5zZWxlY3QpPVwib25VbnNlbGVjdCgkZXZlbnQpXCI+PC9pZ3gtYnV0dG9uZ3JvdXA+XG4gICAgICo8aWd4LXRvYXN0ICN0b2FzdCBtZXNzYWdlPVwiWW91IGhhdmUgZGVzZWxlY3RlZCBhIGJ1dHRvbiFcIj48L2lneC10b2FzdD5cbiAgICAgKmBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25VbnNlbGVjdCA9IG5ldyBFdmVudEVtaXR0ZXI8SUJ1dHRvbkdyb3VwRXZlbnRBcmdzPigpO1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBgaWd4LWJ1dHRvbmdyb3VwYCBhbGlnbm1lbnQgaXMgdmVydGljYWwuXG4gICAgICogTm90ZSB0aGF0IGluIG9yZGVyIGZvciB0aGUgYWNjZXNzb3IgdG8gd29yayBjb3JyZWN0bHkgdGhlIHByb3BlcnR5IHNob3VsZCBiZSBzZXQgZXhwbGljaXRseS5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1idXR0b25ncm91cCAjTXlDaGlsZCBbYWxpZ25tZW50XT1cImFsaWdubWVudFwiIFt2YWx1ZXNdPVwiYWxpZ25PcHRpb25zXCI+XG4gICAgICogYGBgXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIC8vLi4uXG4gICAgICpAVmlld0NoaWxkKFwiTXlDaGlsZFwiKVxuICAgICAqcHJpdmF0ZSBidXR0b25HOiBJZ3hCdXR0b25Hcm91cENvbXBvbmVudDtcbiAgICAgKm5nQWZ0ZXJWaWV3SW5pdCgpe1xuICAgICAqICAgIGxldCBvcmllbnRhdGlvbiA9IHRoaXMuYnV0dG9uRy5pc1ZlcnRpY2FsO1xuICAgICAqfVxuICAgICAqYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBpc1ZlcnRpY2FsKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNWZXJ0aWNhbDtcbiAgICB9XG4gICAgcHJpdmF0ZSBfaXNWZXJ0aWNhbDogYm9vbGVhbjtcbiAgICBwcml2YXRlIF9pdGVtQ29udGVudENzc0NsYXNzOiBzdHJpbmc7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9jZHI6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIF9yZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERpc3BsYXlEZW5zaXR5VG9rZW4pIHByb3RlY3RlZCBfZGlzcGxheURlbnNpdHlPcHRpb25zOiBJRGlzcGxheURlbnNpdHlPcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKF9kaXNwbGF5RGVuc2l0eU9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHNlbGVjdGVkIGJ1dHRvbi9idXR0b25zLlxuICAgICAqYGBgdHlwZXNjcmlwdFxuICAgICAqQFZpZXdDaGlsZChcIk15Q2hpbGRcIilcbiAgICAgKnByaXZhdGUgYnV0dG9uRzogSWd4QnV0dG9uR3JvdXBDb21wb25lbnQ7XG4gICAgICpuZ0FmdGVyVmlld0luaXQoKXtcbiAgICAgKiAgICBsZXQgc2VsZWN0ZWRCdXR0b24gPSB0aGlzLmJ1dHRvbkcuc2VsZWN0ZWRCdXR0b25zO1xuICAgICAqfVxuICAgICAqYGBgXG4gICAgICovXG4gICAgZ2V0IHNlbGVjdGVkQnV0dG9ucygpOiBJZ3hCdXR0b25EaXJlY3RpdmVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1dHRvbnMuZmlsdGVyKChiLCBpKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RlZEluZGV4ZXMuaW5kZXhPZihpKSAhPT0gLTE7XG4gICAgICAgIH0pO1xuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VsZWN0cyBhIGJ1dHRvbiBieSBpdHMgaW5kZXguXG4gICAgICpgYGB0eXBlc2NyaXB0XG4gICAgICpAVmlld0NoaWxkKFwiTXlDaGlsZFwiKVxuICAgICAqcHJpdmF0ZSBidXR0b25HOiBJZ3hCdXR0b25Hcm91cENvbXBvbmVudDtcbiAgICAgKm5nQWZ0ZXJWaWV3SW5pdCgpe1xuICAgICAqICAgIHRoaXMuYnV0dG9uRy5zZWxlY3RCdXR0b24oMik7XG4gICAgICogICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAqfVxuICAgICAqYGBgXG4gICAgICogQG1lbWJlck9mIHtAbGluayBJZ3hCdXR0b25Hcm91cENvbXBvbmVudH1cbiAgICAgKi9cbiAgICBwdWJsaWMgc2VsZWN0QnV0dG9uKGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKGluZGV4ID49IHRoaXMuYnV0dG9ucy5sZW5ndGggfHwgaW5kZXggPCAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBidXR0b24gPSB0aGlzLmJ1dHRvbnNbaW5kZXhdO1xuICAgICAgICBjb25zdCBidXR0b25FbGVtZW50ID0gYnV0dG9uLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ZXMucHVzaChpbmRleCk7XG4gICAgICAgIGJ1dHRvbi5zZWxlY3RlZCA9IHRydWU7XG5cbiAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKGJ1dHRvbkVsZW1lbnQsICdhcmlhLXByZXNzZWQnLCAndHJ1ZScpO1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5hZGRDbGFzcyhidXR0b25FbGVtZW50LCAnaWd4LWJ1dHRvbi1ncm91cF9faXRlbS0tc2VsZWN0ZWQnKTtcblxuICAgICAgICB0aGlzLm9uU2VsZWN0LmVtaXQoeyBidXR0b246IGJ1dHRvbiwgaW5kZXg6IGluZGV4IH0pO1xuXG4gICAgICAgIGNvbnN0IGluZGV4SW5WaWV3QnV0dG9ucyA9IHRoaXMudmlld0J1dHRvbnMudG9BcnJheSgpLmluZGV4T2YoYnV0dG9uKTtcbiAgICAgICAgaWYgKGluZGV4SW5WaWV3QnV0dG9ucyAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWVzW2luZGV4SW5WaWV3QnV0dG9uc10uc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZGVzZWxlY3Qgb3RoZXIgYnV0dG9ucyBpZiBtdWx0aVNlbGVjdGlvbiBpcyBub3QgZW5hYmxlZFxuICAgICAgICBpZiAoIXRoaXMubXVsdGlTZWxlY3Rpb24gJiYgdGhpcy5zZWxlY3RlZEluZGV4ZXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgdGhpcy5idXR0b25zLmZvckVhY2goKGIsIGkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaSAhPT0gaW5kZXggJiYgdGhpcy5zZWxlY3RlZEluZGV4ZXMuaW5kZXhPZihpKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXNlbGVjdEJ1dHRvbihpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlc2VsZWN0cyBhIGJ1dHRvbiBieSBpdHMgaW5kZXguXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqQFZpZXdDaGlsZChcIk15Q2hpbGRcIilcbiAgICAgKnByaXZhdGUgYnV0dG9uRzogSWd4QnV0dG9uR3JvdXBDb21wb25lbnQ7XG4gICAgICpuZ0FmdGVyVmlld0luaXQoKXtcbiAgICAgKiAgICB0aGlzLmJ1dHRvbkcuZGVzZWxlY3RCdXR0b24oMik7XG4gICAgICogICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAqfVxuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJPZiB7QGxpbmsgSWd4QnV0dG9uR3JvdXBDb21wb25lbnR9XG4gICAgICovXG4gICAgcHVibGljIGRlc2VsZWN0QnV0dG9uKGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKGluZGV4ID49IHRoaXMuYnV0dG9ucy5sZW5ndGggfHwgaW5kZXggPCAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBidXR0b24gPSB0aGlzLmJ1dHRvbnNbaW5kZXhdO1xuICAgICAgICBjb25zdCBidXR0b25FbGVtZW50ID0gYnV0dG9uLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ZXMuc3BsaWNlKHRoaXMuc2VsZWN0ZWRJbmRleGVzLmluZGV4T2YoaW5kZXgpLCAxKTtcbiAgICAgICAgYnV0dG9uLnNlbGVjdGVkID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKGJ1dHRvbkVsZW1lbnQsICdhcmlhLXByZXNzZWQnLCAnZmFsc2UnKTtcbiAgICAgICAgdGhpcy5fcmVuZGVyZXIucmVtb3ZlQ2xhc3MoYnV0dG9uRWxlbWVudCwgJ2lneC1idXR0b24tZ3JvdXBfX2l0ZW0tLXNlbGVjdGVkJyk7XG5cbiAgICAgICAgdGhpcy5vblVuc2VsZWN0LmVtaXQoeyBidXR0b246IGJ1dHRvbiwgaW5kZXg6IGluZGV4IH0pO1xuXG4gICAgICAgIGNvbnN0IGluZGV4SW5WaWV3QnV0dG9ucyA9IHRoaXMudmlld0J1dHRvbnMudG9BcnJheSgpLmluZGV4T2YoYnV0dG9uKTtcbiAgICAgICAgaWYgKGluZGV4SW5WaWV3QnV0dG9ucyAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWVzW2luZGV4SW5WaWV3QnV0dG9uc10uc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICB0aGlzLnRlbXBsYXRlQnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgICAgICAgIGlmICghYnV0dG9uLmluaXRpYWxEZW5zaXR5KSB7XG4gICAgICAgICAgICAgICAgYnV0dG9uLmRpc3BsYXlEZW5zaXR5ID0gdGhpcy5kaXNwbGF5RGVuc2l0eTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICAgIGNvbnN0IGluaXRCdXR0b25zID0gKCkgPT4ge1xuICAgICAgICAgICAgLy8gQ2FuY2VsIGFueSBleGlzdGluZyBidXR0b25DbGljayBzdWJzY3JpcHRpb25zXG4gICAgICAgICAgICB0aGlzLmJ1dHRvbkNsaWNrTm90aWZpZXIkLm5leHQoKTtcblxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ZXMuc3BsaWNlKDAsIHRoaXMuc2VsZWN0ZWRJbmRleGVzLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIC8vIGluaXRpYWwgY29uZmlndXJhdGlvblxuICAgICAgICAgICAgdGhpcy5idXR0b25zLmZvckVhY2goKGJ1dHRvbiwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBidXR0b25FbGVtZW50ID0gYnV0dG9uLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICBidXR0b24uZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChidXR0b24uc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RCdXR0b24oaW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJ1dHRvbi5idXR0b25DbGljay5waXBlKHRha2VVbnRpbCh0aGlzLmJ1dHRvbkNsaWNrTm90aWZpZXIkKSkuc3Vic2NyaWJlKChldikgPT4gdGhpcy5fY2xpY2tIYW5kbGVyKGV2LCBpbmRleCkpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3JlbmRlcmVyLmFkZENsYXNzKGJ1dHRvbkVsZW1lbnQsICdpZ3gtYnV0dG9uLWdyb3VwX19pdGVtJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnZpZXdCdXR0b25zLmNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5xdWVyeUxpc3ROb3RpZmllciQpKS5zdWJzY3JpYmUoKCkgPT4gaW5pdEJ1dHRvbnMoKSk7XG4gICAgICAgIHRoaXMudGVtcGxhdGVCdXR0b25zLmNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5xdWVyeUxpc3ROb3RpZmllciQpKS5zdWJzY3JpYmUoKCkgPT4gaW5pdEJ1dHRvbnMoKSk7XG4gICAgICAgIGluaXRCdXR0b25zKCk7XG5cbiAgICAgICAgdGhpcy5fY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmJ1dHRvbkNsaWNrTm90aWZpZXIkLm5leHQoKTtcbiAgICAgICAgdGhpcy5idXR0b25DbGlja05vdGlmaWVyJC5jb21wbGV0ZSgpO1xuXG4gICAgICAgIHRoaXMucXVlcnlMaXN0Tm90aWZpZXIkLm5leHQoKTtcbiAgICAgICAgdGhpcy5xdWVyeUxpc3ROb3RpZmllciQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKkBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgX2NsaWNrSGFuZGxlcihldmVudCwgaSkge1xuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZEluZGV4ZXMuaW5kZXhPZihpKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuZGVzZWxlY3RCdXR0b24oaSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdEJ1dHRvbihpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJQnV0dG9uR3JvdXBFdmVudEFyZ3MgZXh0ZW5kcyBJQmFzZUV2ZW50QXJncyB7XG4gICAgYnV0dG9uOiBJZ3hCdXR0b25EaXJlY3RpdmU7XG4gICAgaW5kZXg6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbkBOZ01vZHVsZSh7XG4gICAgZGVjbGFyYXRpb25zOiBbSWd4QnV0dG9uR3JvdXBDb21wb25lbnRdLFxuICAgIGV4cG9ydHM6IFtJZ3hCdXR0b25Hcm91cENvbXBvbmVudF0sXG4gICAgaW1wb3J0czogW0lneEJ1dHRvbk1vZHVsZSwgQ29tbW9uTW9kdWxlLCBJZ3hSaXBwbGVNb2R1bGUsIElneEljb25Nb2R1bGVdXG59KVxuXG5leHBvcnQgY2xhc3MgSWd4QnV0dG9uR3JvdXBNb2R1bGUge1xufVxuIl19