primeng
Version:
[](https://badge.fury.io/js/primeng) [](https://www.npmjs.com/package/primeng) [ {
return this._label;
}
set label(val) {
this._label = val;
if (this.initialized) {
this.updateLabel();
this.updateIcon();
this.setStyleClass();
}
}
/**
* Name of the icon.
* @group Props
*/
get icon() {
return this._icon;
}
set icon(val) {
this._icon = val;
if (this.initialized) {
this.updateIcon();
this.setStyleClass();
}
}
/**
* Whether the button is in loading state.
* @group Props
*/
get loading() {
return this._loading;
}
set loading(val) {
this._loading = val;
if (this.initialized) {
this.updateIcon();
this.setStyleClass();
}
}
_label;
_icon;
_loading = false;
initialized;
get htmlElement() {
return this.el.nativeElement;
}
_internalClasses = Object.values(INTERNAL_BUTTON_CLASSES);
spinnerIcon = `<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="p-icon-spin">
<g clip-path="url(#clip0_417_21408)">
<path
d="M6.99701 14C5.85441 13.999 4.72939 13.7186 3.72012 13.1832C2.71084 12.6478 1.84795 11.8737 1.20673 10.9284C0.565504 9.98305 0.165424 8.89526 0.041387 7.75989C-0.0826496 6.62453 0.073125 5.47607 0.495122 4.4147C0.917119 3.35333 1.59252 2.4113 2.46241 1.67077C3.33229 0.930247 4.37024 0.413729 5.4857 0.166275C6.60117 -0.0811796 7.76026 -0.0520535 8.86188 0.251112C9.9635 0.554278 10.9742 1.12227 11.8057 1.90555C11.915 2.01493 11.9764 2.16319 11.9764 2.31778C11.9764 2.47236 11.915 2.62062 11.8057 2.73C11.7521 2.78503 11.688 2.82877 11.6171 2.85864C11.5463 2.8885 11.4702 2.90389 11.3933 2.90389C11.3165 2.90389 11.2404 2.8885 11.1695 2.85864C11.0987 2.82877 11.0346 2.78503 10.9809 2.73C9.9998 1.81273 8.73246 1.26138 7.39226 1.16876C6.05206 1.07615 4.72086 1.44794 3.62279 2.22152C2.52471 2.99511 1.72683 4.12325 1.36345 5.41602C1.00008 6.70879 1.09342 8.08723 1.62775 9.31926C2.16209 10.5513 3.10478 11.5617 4.29713 12.1803C5.48947 12.7989 6.85865 12.988 8.17414 12.7157C9.48963 12.4435 10.6711 11.7264 11.5196 10.6854C12.3681 9.64432 12.8319 8.34282 12.8328 7C12.8328 6.84529 12.8943 6.69692 13.0038 6.58752C13.1132 6.47812 13.2616 6.41667 13.4164 6.41667C13.5712 6.41667 13.7196 6.47812 13.8291 6.58752C13.9385 6.69692 14 6.84529 14 7C14 8.85651 13.2622 10.637 11.9489 11.9497C10.6356 13.2625 8.85432 14 6.99701 14Z"
fill="currentColor"
/>
</g>
<defs>
<clipPath id="clip0_417_21408">
<rect width="14" height="14" fill="white" />
</clipPath>
</defs>
</svg>`;
constructor(el, document) {
this.el = el;
this.document = document;
}
ngAfterViewInit() {
DomHandler.addMultipleClasses(this.htmlElement, this.getStyleClass().join(' '));
this.createIcon();
this.createLabel();
this.initialized = true;
}
getStyleClass() {
const styleClass = [INTERNAL_BUTTON_CLASSES.button, INTERNAL_BUTTON_CLASSES.component];
if (this.icon && !this.label && ObjectUtils.isEmpty(this.htmlElement.textContent)) {
styleClass.push(INTERNAL_BUTTON_CLASSES.iconOnly);
}
if (this.loading) {
styleClass.push(INTERNAL_BUTTON_CLASSES.disabled, INTERNAL_BUTTON_CLASSES.loading);
if (!this.icon && this.label) {
styleClass.push(INTERNAL_BUTTON_CLASSES.labelOnly);
}
if (this.icon && !this.label && !ObjectUtils.isEmpty(this.htmlElement.textContent)) {
styleClass.push(INTERNAL_BUTTON_CLASSES.iconOnly);
}
}
return styleClass;
}
setStyleClass() {
const styleClass = this.getStyleClass();
this.htmlElement.classList.remove(...this._internalClasses);
this.htmlElement.classList.add(...styleClass);
}
createLabel() {
if (this.label) {
let labelElement = this.document.createElement('span');
if (this.icon && !this.label) {
labelElement.setAttribute('aria-hidden', 'true');
}
labelElement.className = 'p-button-label';
labelElement.appendChild(this.document.createTextNode(this.label));
this.htmlElement.appendChild(labelElement);
}
}
createIcon() {
if (this.icon || this.loading) {
let iconElement = this.document.createElement('span');
iconElement.className = 'p-button-icon';
iconElement.setAttribute('aria-hidden', 'true');
let iconPosClass = this.label ? 'p-button-icon-' + this.iconPos : null;
if (iconPosClass) {
DomHandler.addClass(iconElement, iconPosClass);
}
let iconClass = this.getIconClass();
if (iconClass) {
DomHandler.addMultipleClasses(iconElement, iconClass);
}
if (!this.loadingIcon && this.loading) {
iconElement.innerHTML = this.spinnerIcon;
}
this.htmlElement.insertBefore(iconElement, this.htmlElement.firstChild);
}
}
updateLabel() {
let labelElement = DomHandler.findSingle(this.htmlElement, '.p-button-label');
if (!this.label) {
labelElement && this.htmlElement.removeChild(labelElement);
return;
}
labelElement ? (labelElement.textContent = this.label) : this.createLabel();
}
updateIcon() {
let iconElement = DomHandler.findSingle(this.htmlElement, '.p-button-icon');
let labelElement = DomHandler.findSingle(this.htmlElement, '.p-button-label');
if (this.loading && !this.loadingIcon && iconElement) {
iconElement.innerHTML = this.spinnerIcon;
}
else if (iconElement?.innerHTML) {
iconElement.innerHTML = '';
}
if (iconElement) {
if (this.iconPos) {
iconElement.className = 'p-button-icon ' + (labelElement ? 'p-button-icon-' + this.iconPos : '') + ' ' + this.getIconClass();
}
else {
iconElement.className = 'p-button-icon ' + this.getIconClass();
}
}
else {
this.createIcon();
}
}
getIconClass() {
return this.loading ? 'p-button-loading-icon ' + (this.loadingIcon ? this.loadingIcon : 'p-icon') : this.icon || 'p-hidden';
}
ngOnDestroy() {
this.initialized = false;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.5", ngImport: i0, type: ButtonDirective, deps: [{ token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.5", type: ButtonDirective, selector: "[pButton]", inputs: { iconPos: "iconPos", loadingIcon: "loadingIcon", label: "label", icon: "icon", loading: "loading" }, host: { classAttribute: "p-element" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.5", ngImport: i0, type: ButtonDirective, decorators: [{
type: Directive,
args: [{
selector: '[pButton]',
host: {
class: 'p-element'
}
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { iconPos: [{
type: Input
}], loadingIcon: [{
type: Input
}], label: [{
type: Input
}], icon: [{
type: Input
}], loading: [{
type: Input
}] } });
/**
* Button is an extension to standard button element with icons and theming.
* @group Components
*/
export class Button {
/**
* Type of the button.
* @group Props
*/
type = 'button';
/**
* Position of the icon.
* @group Props
*/
iconPos = 'left';
/**
* Name of the icon.
* @group Props
*/
icon;
/**
* Value of the badge.
* @group Props
*/
badge;
/**
* Uses to pass attributes to the label's DOM element.
* @group Props
*/
label;
/**
* When present, it specifies that the component should be disabled.
* @group Props
*/
disabled;
/**
* Whether the button is in loading state.
* @group Props
*/
loading = false;
/**
* Icon to display in loading state.
* @group Props
*/
loadingIcon;
/**
* Add a shadow to indicate elevation.
* @group Props
*/
raised = false;
/**
* Add a circular border radius to the button.
* @group Props
*/
rounded = false;
/**
* Add a textual class to the button without a background initially.
* @group Props
*/
text = false;
/**
* Add a plain textual class to the button without a background initially.
* @group Props
*/
plain = false;
/**
* Defines the style of the button.
* @group Props
*/
severity;
/**
* Add a border class without a background initially.
* @group Props
*/
outlined = false;
/**
* Add a link style to the button.
* @group Props
*/
link = false;
/**
* Defines the size of the button.
* @group Props
*/
size;
/**
* Inline style of the element.
* @group Props
*/
style;
/**
* Class of the element.
* @group Props
*/
styleClass;
/**
* Style class of the badge.
* @group Props
*/
badgeClass;
/**
* Used to define a string that autocomplete attribute the current element.
* @group Props
*/
ariaLabel;
/**
* Callback to execute when button is clicked.
* This event is intended to be used with the <p-button> component. Using a regular <button> element, use (click).
* @param {MouseEvent} event - Mouse event.
* @group Emits
*/
onClick = new EventEmitter();
/**
* Callback to execute when button is focused.
* This event is intended to be used with the <p-button> component. Using a regular <button> element, use (focus).
* @param {FocusEvent} event - Focus event.
* @group Emits
*/
onFocus = new EventEmitter();
/**
* Callback to execute when button loses focus.
* This event is intended to be used with the <p-button> component. Using a regular <button> element, use (blur).
* @param {FocusEvent} event - Focus event.
* @group Emits
*/
onBlur = new EventEmitter();
contentTemplate;
loadingIconTemplate;
iconTemplate;
templates;
spinnerIconClass() {
return Object.entries(this.iconClass())
.filter(([, value]) => !!value)
.reduce((acc, [key]) => acc + ` ${key}`, 'p-button-loading-icon');
}
iconClass() {
return {
'p-button-icon': true,
'p-button-icon-left': this.iconPos === 'left' && this.label,
'p-button-icon-right': this.iconPos === 'right' && this.label,
'p-button-icon-top': this.iconPos === 'top' && this.label,
'p-button-icon-bottom': this.iconPos === 'bottom' && this.label
};
}
buttonClass() {
return {
'p-button p-component': true,
'p-button-icon-only': (this.icon || this.iconTemplate || this.loadingIcon || this.loadingIconTemplate) && !this.label,
'p-button-vertical': (this.iconPos === 'top' || this.iconPos === 'bottom') && this.label,
'p-disabled': this.disabled || this.loading,
'p-button-loading': this.loading,
'p-button-loading-label-only': this.loading && !this.icon && this.label && !this.loadingIcon && this.iconPos === 'left',
'p-button-link': this.link,
[`p-button-${this.severity}`]: this.severity,
'p-button-raised': this.raised,
'p-button-rounded': this.rounded,
'p-button-text': this.text,
'p-button-outlined': this.outlined,
'p-button-sm': this.size === 'small',
'p-button-lg': this.size === 'large',
'p-button-plain': this.plain,
[`${this.styleClass}`]: this.styleClass
};
}
ngAfterContentInit() {
this.templates?.forEach((item) => {
switch (item.getType()) {
case 'content':
this.contentTemplate = item.template;
break;
case 'icon':
this.iconTemplate = item.template;
break;
case 'loadingicon':
this.loadingIconTemplate = item.template;
break;
default:
this.contentTemplate = item.template;
break;
}
});
}
badgeStyleClass() {
return {
'p-badge p-component': true,
'p-badge-no-gutter': this.badge && String(this.badge).length === 1
};
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.5", ngImport: i0, type: Button, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.5", type: Button, selector: "p-button", inputs: { type: "type", iconPos: "iconPos", icon: "icon", badge: "badge", label: "label", disabled: "disabled", loading: "loading", loadingIcon: "loadingIcon", raised: "raised", rounded: "rounded", text: "text", plain: "plain", severity: "severity", outlined: "outlined", link: "link", size: "size", style: "style", styleClass: "styleClass", badgeClass: "badgeClass", ariaLabel: "ariaLabel" }, outputs: { onClick: "onClick", onFocus: "onFocus", onBlur: "onBlur" }, host: { properties: { "class.p-disabled": "disabled" }, classAttribute: "p-element" }, queries: [{ propertyName: "templates", predicate: PrimeTemplate }], ngImport: i0, template: `
<button
[attr.type]="type"
[attr.aria-label]="ariaLabel"
[class]="styleClass"
[ngStyle]="style"
[disabled]="disabled || loading"
[ngClass]="buttonClass()"
(click)="onClick.emit($event)"
(focus)="onFocus.emit($event)"
(blur)="onBlur.emit($event)"
pRipple
[attr.data-pc-name]="'button'"
[attr.data-pc-section]="'root'"
>
<ng-content></ng-content>
<ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
<ng-container *ngIf="loading">
<ng-container *ngIf="!loadingIconTemplate">
<span *ngIf="loadingIcon" [class]="'p-button-loading-icon pi-spin ' + loadingIcon" [ngClass]="iconClass()" [attr.aria-hidden]="true" [attr.data-pc-section]="'loadingicon'"></span>
<SpinnerIcon *ngIf="!loadingIcon" [styleClass]="spinnerIconClass()" [spin]="true" [attr.aria-hidden]="true" [attr.data-pc-section]="'loadingicon'" />
</ng-container>
<span *ngIf="loadingIconTemplate" class="p-button-loading-icon" [ngClass]="iconClass()" [attr.aria-hidden]="true" [attr.data-pc-section]="'loadingicon'">
<ng-template *ngTemplateOutlet="loadingIconTemplate"></ng-template>
</span>
</ng-container>
<ng-container *ngIf="!loading">
<span *ngIf="icon && !iconTemplate" [class]="icon" [ngClass]="iconClass()" [attr.data-pc-section]="'icon'"></span>
<span *ngIf="!icon && iconTemplate" [ngClass]="iconClass()" [attr.data-pc-section]="'icon'">
<ng-template [ngIf]="!icon" *ngTemplateOutlet="iconTemplate"></ng-template>
</span>
</ng-container>
<span class="p-button-label" [attr.aria-hidden]="icon && !label" *ngIf="!contentTemplate && label" [attr.data-pc-section]="'label'">{{ label }}</span>
<span [ngClass]="badgeStyleClass()" [class]="badgeClass" *ngIf="!contentTemplate && badge" [attr.data-pc-section]="'badge'">{{ badge }}</span>
</button>
`, isInline: true, dependencies: [{ kind: "directive", type: i0.forwardRef(() => i1.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(() => i1.NgIf), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(() => i1.NgTemplateOutlet), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(() => i1.NgStyle), selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i0.forwardRef(() => i2.Ripple), selector: "[pRipple]" }, { kind: "component", type: i0.forwardRef(() => SpinnerIcon), selector: "SpinnerIcon" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.5", ngImport: i0, type: Button, decorators: [{
type: Component,
args: [{
selector: 'p-button',
template: `
<button
[attr.type]="type"
[attr.aria-label]="ariaLabel"
[class]="styleClass"
[ngStyle]="style"
[disabled]="disabled || loading"
[ngClass]="buttonClass()"
(click)="onClick.emit($event)"
(focus)="onFocus.emit($event)"
(blur)="onBlur.emit($event)"
pRipple
[attr.data-pc-name]="'button'"
[attr.data-pc-section]="'root'"
>
<ng-content></ng-content>
<ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
<ng-container *ngIf="loading">
<ng-container *ngIf="!loadingIconTemplate">
<span *ngIf="loadingIcon" [class]="'p-button-loading-icon pi-spin ' + loadingIcon" [ngClass]="iconClass()" [attr.aria-hidden]="true" [attr.data-pc-section]="'loadingicon'"></span>
<SpinnerIcon *ngIf="!loadingIcon" [styleClass]="spinnerIconClass()" [spin]="true" [attr.aria-hidden]="true" [attr.data-pc-section]="'loadingicon'" />
</ng-container>
<span *ngIf="loadingIconTemplate" class="p-button-loading-icon" [ngClass]="iconClass()" [attr.aria-hidden]="true" [attr.data-pc-section]="'loadingicon'">
<ng-template *ngTemplateOutlet="loadingIconTemplate"></ng-template>
</span>
</ng-container>
<ng-container *ngIf="!loading">
<span *ngIf="icon && !iconTemplate" [class]="icon" [ngClass]="iconClass()" [attr.data-pc-section]="'icon'"></span>
<span *ngIf="!icon && iconTemplate" [ngClass]="iconClass()" [attr.data-pc-section]="'icon'">
<ng-template [ngIf]="!icon" *ngTemplateOutlet="iconTemplate"></ng-template>
</span>
</ng-container>
<span class="p-button-label" [attr.aria-hidden]="icon && !label" *ngIf="!contentTemplate && label" [attr.data-pc-section]="'label'">{{ label }}</span>
<span [ngClass]="badgeStyleClass()" [class]="badgeClass" *ngIf="!contentTemplate && badge" [attr.data-pc-section]="'badge'">{{ badge }}</span>
</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
class: 'p-element',
'[class.p-disabled]': 'disabled' || 'loading'
}
}]
}], propDecorators: { type: [{
type: Input
}], iconPos: [{
type: Input
}], icon: [{
type: Input
}], badge: [{
type: Input
}], label: [{
type: Input
}], disabled: [{
type: Input
}], loading: [{
type: Input
}], loadingIcon: [{
type: Input
}], raised: [{
type: Input
}], rounded: [{
type: Input
}], text: [{
type: Input
}], plain: [{
type: Input
}], severity: [{
type: Input
}], outlined: [{
type: Input
}], link: [{
type: Input
}], size: [{
type: Input
}], style: [{
type: Input
}], styleClass: [{
type: Input
}], badgeClass: [{
type: Input
}], ariaLabel: [{
type: Input
}], onClick: [{
type: Output
}], onFocus: [{
type: Output
}], onBlur: [{
type: Output
}], templates: [{
type: ContentChildren,
args: [PrimeTemplate]
}] } });
export class ButtonModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.5", ngImport: i0, type: ButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.5", ngImport: i0, type: ButtonModule, declarations: [ButtonDirective, Button], imports: [CommonModule, RippleModule, SharedModule, SpinnerIcon], exports: [ButtonDirective, Button, SharedModule] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.5", ngImport: i0, type: ButtonModule, imports: [CommonModule, RippleModule, SharedModule, SpinnerIcon, SharedModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.5", ngImport: i0, type: ButtonModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule, RippleModule, SharedModule, SpinnerIcon],
exports: [ButtonDirective, Button, SharedModule],
declarations: [ButtonDirective, Button]
}]
}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcC9jb21wb25lbnRzL2J1dHRvbi9idXR0b24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQW1DLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBYSxNQUFNLEVBQTBCLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pQLE9BQU8sRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzFELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDekMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3BELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7O0FBSTVDLE1BQU0sdUJBQXVCLEdBQUc7SUFDNUIsTUFBTSxFQUFFLFVBQVU7SUFDbEIsU0FBUyxFQUFFLGFBQWE7SUFDeEIsUUFBUSxFQUFFLG9CQUFvQjtJQUM5QixRQUFRLEVBQUUsWUFBWTtJQUN0QixPQUFPLEVBQUUsa0JBQWtCO0lBQzNCLFNBQVMsRUFBRSw2QkFBNkI7Q0FDbEMsQ0FBQztBQUNYOzs7R0FHRztBQU9ILE1BQU0sT0FBTyxlQUFlO0lBc0ZMO0lBQTBDO0lBckY3RDs7O09BR0c7SUFDTSxPQUFPLEdBQXVCLE1BQU0sQ0FBQztJQUM5Qzs7O09BR0c7SUFDTSxXQUFXLENBQXFCO0lBQ3pDOzs7T0FHRztJQUNILElBQWEsS0FBSztRQUNkLE9BQU8sSUFBSSxDQUFDLE1BQWdCLENBQUM7SUFDakMsQ0FBQztJQUNELElBQUks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LENBQUMsZUFBZSxFQUFFLE1BQU0sRUFBRSxZQUFZLENBQUM7b0JBQ2hELFlBQVksRUFBRSxDQUFDLGVBQWUsRUFBRSxNQUFNLENBQUM7aUJBQzFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlLCBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBBZnRlckNvbnRlbnRJbml0LCBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBDb250ZW50Q2hpbGRyZW4sIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbmplY3QsIElucHV0LCBOZ01vZHVsZSwgT25EZXN0cm95LCBPdXRwdXQsIFF1ZXJ5TGlzdCwgVGVtcGxhdGVSZWYsIFZpZXdFbmNhcHN1bGF0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBQcmltZVRlbXBsYXRlLCBTaGFyZWRNb2R1bGUgfSBmcm9tICdwcmltZW5nL2FwaSc7XG5pbXBvcnQgeyBEb21IYW5kbGVyIH0gZnJvbSAncHJpbWVuZy9kb20nO1xuaW1wb3J0IHsgU3Bpbm5lckljb24gfSBmcm9tICdwcmltZW5nL2ljb25zL3NwaW5uZXInO1xuaW1wb3J0IHsgUmlwcGxlTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9yaXBwbGUnO1xuaW1wb3J0IHsgT2JqZWN0VXRpbHMgfSBmcm9tICdwcmltZW5nL3V0aWxzJztcblxudHlwZSBCdXR0b25JY29uUG9zaXRpb24gPSAnbGVmdCcgfCAncmlnaHQnIHwgJ3RvcCcgfCAnYm90dG9tJztcblxuY29uc3QgSU5URVJOQUxfQlVUVE9OX0NMQVNTRVMgPSB7XG4gICAgYnV0dG9uOiAncC1idXR0b24nLFxuICAgIGNvbXBvbmVudDogJ3AtY29tcG9uZW50JyxcbiAgICBpY29uT25seTogJ3AtYnV0dG9uLWljb24tb25seScsXG4gICAgZGlzYWJsZWQ6ICdwLWRpc2FibGVkJyxcbiAgICBsb2FkaW5nOiAncC1idXR0b24tbG9hZGluZycsXG4gICAgbGFiZWxPbmx5OiAncC1idXR0b24tbG9hZGluZy1sYWJlbC1vbmx5J1xufSBhcyBjb25zdDtcbi8qKlxuICogQnV0dG9uIGRpcmVjdGl2ZSBpcyBhbiBleHRlbnNpb24gdG8gYnV0dG9uIGNvbXBvbmVudC5cbiAqIEBncm91cCBDb21wb25lbnRzXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW3BCdXR0b25dJyxcbiAgICBob3N0OiB7XG4gICAgICAgIGNsYXNzOiAncC1lbGVtZW50J1xuICAgIH1cbn0pXG5leHBvcnQgY2xhc3MgQnV0dG9uRGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgICAvKipcbiAgICAgKiBQb3NpdGlvbiBvZiB0aGUgaWNvbi5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBpY29uUG9zOiBCdXR0b25JY29uUG9zaXRpb24gPSAnbGVmdCc7XG4gICAgLyoqXG4gICAgICogVXNlcyB0byBwYXNzIGF0dHJpYnV0ZXMgdG8gdGhlIGxvYWRpbmcgaWNvbidzIERPTSBlbGVtZW50LlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIGxvYWRpbmdJY29uOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogVGV4dCBvZiB0aGUgYnV0dG9uLlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIGdldCBsYWJlbCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGFiZWwgYXMgc3RyaW5nO1xuICAgIH1cbiAgICBzZXQgbGFiZWwodmFsOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5fbGFiZWwgPSB2YWw7XG5cbiAgICAgICAgaWYgKHRoaXMuaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlTGFiZWwoKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlSWNvbigpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdHlsZUNsYXNzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogTmFtZSBvZiB0aGUgaWNvbi5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBnZXQgaWNvbigpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5faWNvbiBhcyBzdHJpbmc7XG4gICAgfVxuICAgIHNldCBpY29uKHZhbDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX2ljb24gPSB2YWw7XG5cbiAgICAgICAgaWYgKHRoaXMuaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlSWNvbigpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdHlsZUNsYXNzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgYnV0dG9uIGlzIGluIGxvYWRpbmcgc3RhdGUuXG4gICAgICogQGdyb3VwIFByb3BzXG4gICAgICovXG4gICAgQElucHV0KCkgZ2V0IGxvYWRpbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkaW5nO1xuICAgIH1cbiAgICBzZXQgbG9hZGluZyh2YWw6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fbG9hZGluZyA9IHZhbDtcblxuICAgICAgICBpZiAodGhpcy5pbml0aWFsaXplZCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVJY29uKCk7XG4gICAgICAgICAgICB0aGlzLnNldFN0eWxlQ2xhc3MoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBfbGFiZWw6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIHB1YmxpYyBfaWNvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgcHVibGljIF9sb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBwdWJsaWMgaW5pdGlhbGl6ZWQ6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgICBwcml2YXRlIGdldCBodG1sRWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfaW50ZXJuYWxDbGFzc2VzOiBzdHJpbmdbXSA9IE9iamVjdC52YWx1ZXMoSU5URVJOQUxfQlVUVE9OX0NMQVNTRVMpO1xuXG4gICAgc3Bpbm5lckljb24gPSBgPHN2ZyB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDE0IDE0XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgY2xhc3M9XCJwLWljb24tc3BpblwiPlxuICAgICAgICA8ZyBjbGlwLXBhdGg9XCJ1cmwoI2NsaXAwXzQxN18yMTQwOClcIj5cbiAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgZD1cIk02Ljk5NzAxIDE0QzUuODU0NDEgMTMuOTk5IDQuNzI5MzkgMTMuNzE4NiAzLjcyMDEyIDEzLjE4MzJDMi43MTA4NCAxMi42NDc4IDEuODQ3OTUgMTEuODczNyAxLjIwNjczIDEwLjkyODRDMC41NjU1MDQgOS45ODMwNSAwLjE2NTQyNCA4Ljg5NTI2IDAuMDQxMzg3IDcuNzU5ODlDLTAuMDgyNjQ5NiA2LjYyNDUzIDAuMDczMTI1IDUuNDc2MDcgMC40OTUxMjIgNC40MTQ3QzAuOTE3MTE5IDMuMzUzMzMgMS41OTI1MiAyLjQxMTMgMi40NjI0MSAxLjY3MDc3QzMuMzMyMjkgMC45MzAyNDcgNC4zNzAyNCAwLjQxMzcyOSA1LjQ4NTcgMC4xNjYyNzVDNi42MDExNyAtMC4wODExNzk2IDcuNzYwMjYgLTAuMDUyMDUzNSA4Ljg2MTg4IDAuMjUxMTEyQzkuOTYzNSAwLjU1NDI3OCAxMC45NzQyIDEuMTIyMjcgMTEuODA1NyAxLjkwNTU1QzExLjkxNSAyLjAxNDkzIDExLjk3NjQgMi4xNjMxOSAxMS45NzY0IDIuMzE3NzhDMTEuOTc2NCAyLjQ3MjM2IDExLjkxNSAyLjYyMDYyIDExLjgwNTcgMi43M0MxMS43NTIxIDIuNzg1MDMgMTEuNjg4IDIuODI4NzcgMTEuNjE3MSAyLjg1ODY0QzExLjU0NjMgMi44ODg1IDExLjQ3MDIgMi45MDM4OSAxMS4zOTMzIDIuOTAzODlDMTEuMzE2NSAyLjkwMzg5IDExLjI0MDQgMi44ODg1IDExLjE2OTUgMi44NTg2NEMxMS4wOTg3IDIuODI4NzcgMTEuMDM0NiAyLjc4NTAzIDEwLjk4MDkgMi43M0M5Ljk5OTggMS44MTI3MyA4LjczMjQ2IDEuMjYxMzggNy4zOTIyNiAxLjE2ODc2QzYuMDUyMDYgMS4wNzYxNSA0LjcyMDg2IDEuNDQ3OTQgMy42MjI3OSAyLjIyMTUyQzIuNTI0NzEgMi45OTUxMSAxLjcyNjgzIDQuMTIzMjUgMS4zNjM0NSA1LjQxNjAyQzEuMDAwMDggNi43MDg3OSAxLjA5MzQyIDguMDg3MjMgMS42Mjc3NSA5LjMxOTI2QzIuMTYyMDkgMTAuNTUxMyAzLjEwNDc4IDExLjU2MTcgNC4yOTcxMyAxMi4xODAzQzUuNDg5NDcgMTIuNzk4OSA2Ljg1ODY1IDEyLjk4OCA4LjE3NDE0IDEyLjcxNTdDOS40ODk2MyAxMi40NDM1IDEwLjY3MTEgMTEuNzI2NCAxMS41MTk2IDEwLjY4NTRDMTIuMzY4MSA5LjY0NDMyIDEyLjgzMTkgOC4zNDI4MiAxMi44MzI4IDdDMTIuODMyOCA2Ljg0NTI5IDEyLjg5NDMgNi42OTY5MiAxMy4wMDM4IDYuNTg3NTJDMTMuMTEzMiA2LjQ3ODEyIDEzLjI2MTYgNi40MTY2NyAxMy40MTY0IDYuNDE2NjdDMTMuNTcxMiA2LjQxNjY3IDEzLjcxOTYgNi40NzgxMiAxMy44MjkxIDYuNTg3NTJDMTMuOTM4NSA2LjY5NjkyIDE0IDYuODQ1MjkgMTQgN0MxNCA4Ljg1NjUxIDEzLjI2MjIgMTAuNjM3IDExLjk0ODkgMTEuOTQ5N0MxMC42MzU2IDEzLjI2MjUgOC44NTQzMiAxNCA2Ljk5NzAxIDE0WlwiXG4gICAgICAgICAgICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiXG4gICAgICAgICAgICAvPlxuICAgICAgICA8L2c+XG4gICAgICAgIDxkZWZzPlxuICAgICAgICAgICAgPGNsaXBQYXRoIGlkPVwiY2xpcDBfNDE3XzIxNDA4XCI+XG4gICAgICAgICAgICAgICAgPHJlY3Qgd2lkdGg9XCIxNFwiIGhlaWdodD1cIjE0XCIgZmlsbD1cIndoaXRlXCIgLz5cbiAgICAgICAgICAgIDwvY2xpcFBhdGg+XG4gICAgICAgIDwvZGVmcz5cbiAgICA8L3N2Zz5gO1xuXG4gICAgY29uc3RydWN0b3IocHVibGljIGVsOiBFbGVtZW50UmVmLCBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudCkge31cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgRG9tSGFuZGxlci5hZGRNdWx0aXBsZUNsYXNzZXModGhpcy5odG1sRWxlbWVudCwgdGhpcy5nZXRTdHlsZUNsYXNzKCkuam9pbignICcpKTtcblxuICAgICAgICB0aGlzLmNyZWF0ZUljb24oKTtcbiAgICAgICAgdGhpcy5jcmVhdGVMYWJlbCgpO1xuXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGdldFN0eWxlQ2xhc3MoKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCBzdHlsZUNsYXNzOiBzdHJpbmdbXSA9IFtJTlRFUk5BTF9CVVRUT05fQ0xBU1NFUy5idXR0b24sIElOVEVSTkFMX0JVVFRPTl9DTEFTU0VTLmNvbXBvbmVudF07XG5cbiAgICAgICAgaWYgKHRoaXMuaWNvbiAmJiAhdGhpcy5sYWJlbCAmJiBPYmplY3RVdGlscy5pc0VtcHR5KHRoaXMuaHRtbEVsZW1lbnQudGV4dENvbnRlbnQpKSB7XG4gICAgICAgICAgICBzdHlsZUNsYXNzLnB1c2goSU5URVJOQUxfQlVUVE9OX0NMQVNTRVMuaWNvbk9ubHkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMubG9hZGluZykge1xuICAgICAgICAgICAgc3R5bGVDbGFzcy5wdXNoKElOVEVSTkFMX0JVVFRPTl9DTEFTU0VTLmRpc2FibGVkLCBJTlRFUk5BTF9CVVRUT05fQ0xBU1NFUy5sb2FkaW5nKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmljb24gJiYgdGhpcy5sYWJlbCkge1xuICAgICAgICAgICAgICAgIHN0eWxlQ2xhc3MucHVzaChJTlRFUk5BTF9CVVRUT05fQ0xBU1NFUy5sYWJlbE9ubHkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5pY29uICYmICF0aGlzLmxhYmVsICYmICFPYmplY3RVdGlscy5pc0VtcHR5KHRoaXMuaHRtbEVsZW1lbnQudGV4dENvbnRlbnQpKSB7XG4gICAgICAgICAgICAgICAgc3R5bGVDbGFzcy5wdXNoKElOVEVSTkFMX0JVVFRPTl9DTEFTU0VTLmljb25Pbmx5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzdHlsZUNsYXNzO1xuICAgIH1cblxuICAgIHNldFN0eWxlQ2xhc3MoKSB7XG4gICAgICAgIGNvbnN0IHN0eWxlQ2xhc3MgPSB0aGlzLmdldFN0eWxlQ2xhc3MoKTtcbiAgICAgICAgdGhpcy5odG1sRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKC4uLnRoaXMuX2ludGVybmFsQ2xhc3Nlcyk7XG4gICAgICAgIHRoaXMuaHRtbEVsZW1lbnQuY2xhc3NMaXN0LmFkZCguLi5zdHlsZUNsYXNzKTtcbiAgICB9XG5cbiAgICBjcmVhdGVMYWJlbCgpIHtcbiAgICAgICAgaWYgKHRoaXMubGFiZWwpIHtcbiAgICAgICAgICAgIGxldCBsYWJlbEVsZW1lbnQgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmljb24gJiYgIXRoaXMubGFiZWwpIHtcbiAgICAgICAgICAgICAgICBsYWJlbEVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsICd0cnVlJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxhYmVsRWxlbWVudC5jbGFzc05hbWUgPSAncC1idXR0b24tbGFiZWwnO1xuICAgICAgICAgICAgbGFiZWxFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGhpcy5sYWJlbCkpO1xuXG4gICAgICAgICAgICB0aGlzLmh0bWxFbGVtZW50LmFwcGVuZENoaWxkKGxhYmVsRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjcmVhdGVJY29uKCkge1xuICAgICAgICBpZiAodGhpcy5pY29uIHx8IHRoaXMubG9hZGluZykge1xuICAgICAgICAgICAgbGV0IGljb25FbGVtZW50ID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICAgICAgICBpY29uRWxlbWVudC5jbGFzc05hbWUgPSAncC1idXR0b24taWNvbic7XG4gICAgICAgICAgICBpY29uRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcbiAgICAgICAgICAgIGxldCBpY29uUG9zQ2xhc3MgPSB0aGlzLmxhYmVsID8gJ3AtYnV0dG9uLWljb24tJyArIHRoaXMuaWNvblBvcyA6IG51bGw7XG5cbiAgICAgICAgICAgIGlmIChpY29uUG9zQ2xhc3MpIHtcbiAgICAgICAgICAgICAgICBEb21IYW5kbGVyLmFkZENsYXNzKGljb25FbGVtZW50LCBpY29uUG9zQ2xhc3MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgaWNvbkNsYXNzID0gdGhpcy5nZXRJY29uQ2xhc3MoKTtcblxuICAgICAgICAgICAgaWYgKGljb25DbGFzcykge1xuICAgICAgICAgICAgICAgIERvbUhhbmRsZXIuYWRkTXVsdGlwbGVDbGFzc2VzKGljb25FbGVtZW50LCBpY29uQ2xhc3MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXRoaXMubG9hZGluZ0ljb24gJiYgdGhpcy5sb2FkaW5nKSB7XG4gICAgICAgICAgICAgICAgaWNvbkVsZW1lbnQuaW5uZXJIVE1MID0gdGhpcy5zcGlubmVySWNvbjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5odG1sRWxlbWVudC5pbnNlcnRCZWZvcmUoaWNvbkVsZW1lbnQsIHRoaXMuaHRtbEVsZW1lbnQuZmlyc3RDaGlsZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVMYWJlbCgpIHtcbiAgICAgICAgbGV0IGxhYmVsRWxlbWVudCA9IERvbUhhbmRsZXIuZmluZFNpbmdsZSh0aGlzLmh0bWxFbGVtZW50LCAnLnAtYnV0dG9uLWxhYmVsJyk7XG5cbiAgICAgICAgaWYgKCF0aGlzLmxhYmVsKSB7XG4gICAgICAgICAgICBsYWJlbEVsZW1lbnQgJiYgdGhpcy5odG1sRWxlbWVudC5yZW1vdmVDaGlsZChsYWJlbEVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGFiZWxFbGVtZW50ID8gKGxhYmVsRWxlbWVudC50ZXh0Q29udGVudCA9IHRoaXMubGFiZWwpIDogdGhpcy5jcmVhdGVMYWJlbCgpO1xuICAgIH1cblxuICAgIHVwZGF0ZUljb24oKSB7XG4gICAgICAgIGxldCBpY29uRWxlbWVudCA9IERvbUhhbmRsZXIuZmluZFNpbmdsZSh0aGlzLmh0bWxFbGVtZW50LCAnLnAtYnV0dG9uLWljb24nKTtcbiAgICAgICAgbGV0IGxhYmVsRWxlbWVudCA9IERvbUhhbmRsZXIuZmluZFNpbmdsZSh0aGlzLmh0bWxFbGVtZW50LCAnLnAtYnV0dG9uLWxhYmVsJyk7XG5cbiAgICAgICAgaWYgKHRoaXMubG9hZGluZyAmJiAhdGhpcy5sb2FkaW5nSWNvbiAmJiBpY29uRWxlbWVudCkge1xuICAgICAgICAgICAgaWNvbkVsZW1lbnQuaW5uZXJIVE1MID0gdGhpcy5zcGlubmVySWNvbjtcbiAgICAgICAgfSBlbHNlIGlmIChpY29uRWxlbWVudD8uaW5uZXJIVE1MKSB7XG4gICAgICAgICAgICBpY29uRWxlbWVudC5pbm5lckhUTUwgPSAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpY29uRWxlbWVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaWNvblBvcykge1xuICAgICAgICAgICAgICAgIGljb25FbGVtZW50LmNsYXNzTmFtZSA9ICdwLWJ1dHRvbi1pY29uICcgKyAobGFiZWxFbGVtZW50ID8gJ3AtYnV0dG9uLWljb24tJyArIHRoaXMuaWNvblBvcyA6ICcnKSArICcgJyArIHRoaXMuZ2V0SWNvbkNsYXNzKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGljb25FbGVtZW50LmNsYXNzTmFtZSA9ICdwLWJ1dHRvbi1pY29uICcgKyB0aGlzLmdldEljb25DbGFzcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVJY29uKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRJY29uQ2xhc3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvYWRpbmcgPyAncC1idXR0b24tbG9hZGluZy1pY29uICcgKyAodGhpcy5sb2FkaW5nSWNvbiA/IHRoaXMubG9hZGluZ0ljb24gOiAncC1pY29uJykgOiB0aGlzLmljb24gfHwgJ3AtaGlkZGVuJztcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIH1cbn1cbi8qKlxuICogQnV0dG9uIGlzIGFuIGV4dGVuc2lvbiB0byBzdGFuZGFyZCBidXR0b24gZWxlbWVudCB3aXRoIGljb25zIGFuZCB0aGVtaW5nLlxuICogQGdyb3VwIENvbXBvbmVudHNcbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdwLWJ1dHRvbicsXG4gICAgdGVtcGxhdGU6IGBcbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgW2F0dHIudHlwZV09XCJ0eXBlXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiYXJpYUxhYmVsXCJcbiAgICAgICAgICAgIFtjbGFzc109XCJzdHlsZUNsYXNzXCJcbiAgICAgICAgICAgIFtuZ1N0eWxlXT1cInN0eWxlXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZCB8fCBsb2FkaW5nXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cImJ1dHRvbkNsYXNzKClcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2xpY2suZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChmb2N1cyk9XCJvbkZvY3VzLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAoYmx1cik9XCJvbkJsdXIuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgICAgIHBSaXBwbGVcbiAgICAgICAgICAgIFthdHRyLmRhdGEtcGMtbmFtZV09XCInYnV0dG9uJ1wiXG4gICAgICAgICAgICBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ3Jvb3QnXCJcbiAgICAgICAgPlxuICAgICAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImNvbnRlbnRUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvYWRpbmdcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWxvYWRpbmdJY29uVGVtcGxhdGVcIj5cbiAgICAgICAgICAg