carbon-components-angular
Version:
Next generation components
431 lines (425 loc) • 34.2 kB
JavaScript
import { Component, Input, HostBinding, TemplateRef, ViewChild, ContentChild } from "@angular/core";
import { TextArea } from "./text-area.directive";
import { TextInput } from "./input.directive";
import { PasswordInput } from "./password.directive";
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "carbon-components-angular/icon";
import * as i3 from "./textarea-label.component";
import * as i4 from "./text-input-label.component";
import * as i5 from "./password-input-label.component";
/**
* Get started with importing the module:
*
* ```typescript
* import { InputModule } from 'carbon-components-angular';
* ```
*
* To prevent attribute drilling, use `ibm-text-label` or `ibm-textarea-label` components
*
* ```html
* <cds-label>
* Label
* <input cdsText type="text" class="input-field">
* </cds-label>
* ```
*
* [See demo](../../?path=/story/components-input--basic)
*/
export class Label {
/**
* Creates an instance of Label.
*/
constructor(changeDetectorRef) {
this.changeDetectorRef = changeDetectorRef;
/**
* The id of the input item associated with the `Label`. This value is also used to associate the `Label` with
* its input counterpart through the 'for' attribute.
*/
this.labelInputID = `cds-label-${Label.labelCounter++}`;
/**
* Set to `true` for disabled state.
*/
this.disabled = false;
/**
* Set to `true` for a loading label.
*/
this.skeleton = false;
/**
* Set to `true` for an invalid label component.
*/
this.invalid = false;
/**
* Set to `true` to show a warning (contents set by warningText)
*/
this.warn = false;
/**
* Set to `true` to hide the label visually, but keep accessible to
* screen readers.
*/
this.hideLabel = false;
/**
* Set to `true` to render the label and field side-by-side instead of stacked.
* Applies to `TextInput` and `PasswordInput` label variants.
*/
this.inline = false;
/**
* The render size for the `TextInput`. Used to compute INLINE label size
* variant classes.
*/
this.size = "md";
/**
* Set to `true` (`maxCount` must be set) to displays a live character/word
* counter alongside the label.
*/
this.enableCounter = false;
/**
* Determines whether the `TextArea` counter counts characters or words.
*/
this.counterMode = "character";
}
get labelClass() {
return this.type === undefined;
}
/**
* Update wrapper class if a textarea is hosted.
*/
ngAfterContentInit() {
if (this.textArea) {
this.type = "TextArea";
}
else if (this.textInput) {
this.type = "TextInput";
}
else if (this.passwordInput) {
this.type = "PasswordInput";
}
}
/**
* Sets the id on the input item associated with the `Label`.
*/
ngAfterViewInit() {
// Will only be called when `default` template is being used
if (this.wrapper) {
// Prioritize setting id to `input` & `textarea` over div
const inputElement = this.wrapper.nativeElement.querySelector("input,textarea");
if (inputElement) {
// avoid overriding ids already set by the user reuse it instead
if (inputElement.id) {
this.labelInputID = inputElement.id;
this.changeDetectorRef.detectChanges();
}
inputElement.setAttribute("id", this.labelInputID);
return;
}
const divElement = this.wrapper.nativeElement.querySelector("div");
if (divElement) {
if (divElement.id) {
this.labelInputID = divElement.id;
this.changeDetectorRef.detectChanges();
}
divElement.setAttribute("id", this.labelInputID);
}
}
}
isTemplate(value) {
return value instanceof TemplateRef;
}
}
/**
* Used to build the id of the input item associated with the `Label`.
*/
Label.labelCounter = 0;
Label.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Label, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
Label.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Label, selector: "cds-label, ibm-label", inputs: { labelInputID: "labelInputID", disabled: "disabled", skeleton: "skeleton", helperText: "helperText", invalidText: "invalidText", invalid: "invalid", warn: "warn", warnText: "warnText", ariaLabel: "ariaLabel", hideLabel: "hideLabel", inline: "inline", size: "size", enableCounter: "enableCounter", maxCount: "maxCount", counterMode: "counterMode", decorator: "decorator" }, host: { properties: { "class.cds--form-item": "this.labelClass" } }, queries: [{ propertyName: "textArea", first: true, predicate: TextArea, descendants: true }, { propertyName: "textInput", first: true, predicate: TextInput, descendants: true }, { propertyName: "passwordInput", first: true, predicate: PasswordInput, descendants: true }], viewQueries: [{ propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true }], ngImport: i0, template: `
<ng-template #inputContentTemplate>
<ng-content select="input,textarea,div"></ng-content>
</ng-template>
<ng-template #labelContentTemplate>
<ng-content></ng-content>
</ng-template>
<ng-container [ngSwitch]="type">
<ng-container *ngSwitchCase="'TextArea'">
<cds-textarea-label
[labelInputID]="labelInputID"
[disabled]="disabled"
[skeleton]="skeleton"
[helperText]="helperText"
[invalid]="invalid"
[invalidText]="invalidText"
[warn]="warn"
[warnText]="warnText"
[ariaLabel]="ariaLabel"
[hideLabel]="hideLabel"
[enableCounter]="enableCounter"
[maxCount]="maxCount"
[counterMode]="counterMode"
[decorator]="decorator"
[labelTemplate]="labelContentTemplate"
[textAreaTemplate]="inputContentTemplate">
</cds-textarea-label>
</ng-container>
<ng-container *ngSwitchCase="'TextInput'">
<cds-text-label
[labelInputID]="labelInputID"
[disabled]="disabled"
[skeleton]="skeleton"
[helperText]="helperText"
[invalid]="invalid"
[invalidText]="invalidText"
[warn]="warn"
[warnText]="warnText"
[ariaLabel]="ariaLabel"
[hideLabel]="hideLabel"
[inline]="inline"
[size]="size"
[enableCounter]="enableCounter"
[maxCount]="maxCount"
[decorator]="decorator"
[labelTemplate]="labelContentTemplate"
[textInputTemplate]="inputContentTemplate">
</cds-text-label>
</ng-container>
<ng-container *ngSwitchCase="'PasswordInput'">
<cds-password-label
[labelInputID]="labelInputID"
[disabled]="disabled"
[skeleton]="skeleton"
[helperText]="helperText"
[invalid]="invalid"
[invalidText]="invalidText"
[warn]="warn"
[warnText]="warnText"
[ariaLabel]="ariaLabel"
[hideLabel]="hideLabel"
[inline]="inline"
[labelTemplate]="labelContentTemplate"
[passwordInputTemplate]="inputContentTemplate">
</cds-password-label>
</ng-container>
<ng-container *ngSwitchDefault>
<ng-template [ngTemplateOutlet]="default"></ng-template>
</ng-container>
</ng-container>
<ng-template #default>
<label
[for]="labelInputID"
[attr.aria-label]="ariaLabel"
class="cds--label"
[ngClass]="{
'cds--label--disabled': disabled,
'cds--skeleton': skeleton
}">
<ng-template [ngTemplateOutlet]="labelContentTemplate"></ng-template>
</label>
<div
class="cds--text-input__field-wrapper"
[ngClass]="{
'cds--text-input__field-wrapper--warning': warn
}"
[attr.data-invalid]="(invalid ? true : null)"
#wrapper>
<svg
*ngIf="invalid"
cdsIcon="warning--filled"
size="16"
class="cds--text-input__invalid-icon">
</svg>
<svg
*ngIf="!invalid && warn"
cdsIcon="warning--alt--filled"
size="16"
class="cds--text-input__invalid-icon cds--text-input__invalid-icon--warning">
</svg>
<ng-template [ngTemplateOutlet]="inputContentTemplate"></ng-template>
</div>
<div
*ngIf="!skeleton && helperText && !invalid && !warn"
class="cds--form__helper-text"
[ngClass]="{'cds--form__helper-text--disabled': disabled}">
<ng-container *ngIf="!isTemplate(helperText)">{{helperText}}</ng-container>
<ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template>
</div>
<div *ngIf="invalid" class="cds--form-requirement">
<ng-container *ngIf="!isTemplate(invalidText)">{{invalidText}}</ng-container>
<ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template>
</div>
<div *ngIf="!invalid && warn" class="cds--form-requirement">
<ng-container *ngIf="!isTemplate(warnText)">{{warnText}}</ng-container>
<ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template>
</div>
</ng-template>
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: i3.TextareaLabelComponent, selector: "cds-textarea-label, ibm-textarea-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "textAreaTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "fluid", "hideLabel", "enableCounter", "maxCount", "counterMode", "decorator"] }, { kind: "component", type: i4.TextInputLabelComponent, selector: "cds-text-label, ibm-text-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "textInputTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "fluid", "decorator", "hideLabel", "inline", "size", "enableCounter", "maxCount"] }, { kind: "component", type: i5.PasswordInputLabelComponent, selector: "cds-password-label, ibm-password-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "passwordInputTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "hidePasswordLabel", "showPasswordLabel", "fluid", "hideLabel", "inline"], outputs: ["togglePasswordVisibility"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Label, decorators: [{
type: Component,
args: [{
selector: "cds-label, ibm-label",
template: `
<ng-template #inputContentTemplate>
<ng-content select="input,textarea,div"></ng-content>
</ng-template>
<ng-template #labelContentTemplate>
<ng-content></ng-content>
</ng-template>
<ng-container [ngSwitch]="type">
<ng-container *ngSwitchCase="'TextArea'">
<cds-textarea-label
[labelInputID]="labelInputID"
[disabled]="disabled"
[skeleton]="skeleton"
[helperText]="helperText"
[invalid]="invalid"
[invalidText]="invalidText"
[warn]="warn"
[warnText]="warnText"
[ariaLabel]="ariaLabel"
[hideLabel]="hideLabel"
[enableCounter]="enableCounter"
[maxCount]="maxCount"
[counterMode]="counterMode"
[decorator]="decorator"
[labelTemplate]="labelContentTemplate"
[textAreaTemplate]="inputContentTemplate">
</cds-textarea-label>
</ng-container>
<ng-container *ngSwitchCase="'TextInput'">
<cds-text-label
[labelInputID]="labelInputID"
[disabled]="disabled"
[skeleton]="skeleton"
[helperText]="helperText"
[invalid]="invalid"
[invalidText]="invalidText"
[warn]="warn"
[warnText]="warnText"
[ariaLabel]="ariaLabel"
[hideLabel]="hideLabel"
[inline]="inline"
[size]="size"
[enableCounter]="enableCounter"
[maxCount]="maxCount"
[decorator]="decorator"
[labelTemplate]="labelContentTemplate"
[textInputTemplate]="inputContentTemplate">
</cds-text-label>
</ng-container>
<ng-container *ngSwitchCase="'PasswordInput'">
<cds-password-label
[labelInputID]="labelInputID"
[disabled]="disabled"
[skeleton]="skeleton"
[helperText]="helperText"
[invalid]="invalid"
[invalidText]="invalidText"
[warn]="warn"
[warnText]="warnText"
[ariaLabel]="ariaLabel"
[hideLabel]="hideLabel"
[inline]="inline"
[labelTemplate]="labelContentTemplate"
[passwordInputTemplate]="inputContentTemplate">
</cds-password-label>
</ng-container>
<ng-container *ngSwitchDefault>
<ng-template [ngTemplateOutlet]="default"></ng-template>
</ng-container>
</ng-container>
<ng-template #default>
<label
[for]="labelInputID"
[attr.aria-label]="ariaLabel"
class="cds--label"
[ngClass]="{
'cds--label--disabled': disabled,
'cds--skeleton': skeleton
}">
<ng-template [ngTemplateOutlet]="labelContentTemplate"></ng-template>
</label>
<div
class="cds--text-input__field-wrapper"
[ngClass]="{
'cds--text-input__field-wrapper--warning': warn
}"
[attr.data-invalid]="(invalid ? true : null)"
#wrapper>
<svg
*ngIf="invalid"
cdsIcon="warning--filled"
size="16"
class="cds--text-input__invalid-icon">
</svg>
<svg
*ngIf="!invalid && warn"
cdsIcon="warning--alt--filled"
size="16"
class="cds--text-input__invalid-icon cds--text-input__invalid-icon--warning">
</svg>
<ng-template [ngTemplateOutlet]="inputContentTemplate"></ng-template>
</div>
<div
*ngIf="!skeleton && helperText && !invalid && !warn"
class="cds--form__helper-text"
[ngClass]="{'cds--form__helper-text--disabled': disabled}">
<ng-container *ngIf="!isTemplate(helperText)">{{helperText}}</ng-container>
<ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template>
</div>
<div *ngIf="invalid" class="cds--form-requirement">
<ng-container *ngIf="!isTemplate(invalidText)">{{invalidText}}</ng-container>
<ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template>
</div>
<div *ngIf="!invalid && warn" class="cds--form-requirement">
<ng-container *ngIf="!isTemplate(warnText)">{{warnText}}</ng-container>
<ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template>
</div>
</ng-template>
`
}]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { labelInputID: [{
type: Input
}], disabled: [{
type: Input
}], skeleton: [{
type: Input
}], helperText: [{
type: Input
}], invalidText: [{
type: Input
}], invalid: [{
type: Input
}], warn: [{
type: Input
}], warnText: [{
type: Input
}], ariaLabel: [{
type: Input
}], hideLabel: [{
type: Input
}], inline: [{
type: Input
}], size: [{
type: Input
}], enableCounter: [{
type: Input
}], maxCount: [{
type: Input
}], counterMode: [{
type: Input
}], decorator: [{
type: Input
}], wrapper: [{
type: ViewChild,
args: ["wrapper"]
}], textArea: [{
type: ContentChild,
args: [TextArea]
}], textInput: [{
type: ContentChild,
args: [TextInput, { static: false }]
}], passwordInput: [{
type: ContentChild,
args: [PasswordInput, { static: false }]
}], labelClass: [{
type: HostBinding,
args: ["class.cds--form-item"]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGFiZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2lucHV0L2xhYmVsLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ04sU0FBUyxFQUNULEtBQUssRUFHTCxXQUFXLEVBQ1gsV0FBVyxFQUNYLFNBQVMsRUFDVCxZQUFZLEVBR1osTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7Ozs7Ozs7QUFFckQ7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBOEhILE1BQU0sT0FBTyxLQUFLO0lBbUdqQjs7T0FFRztJQUNILFlBQXNCLGlCQUFvQztRQUFwQyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBakcxRDs7O1dBR0c7UUFDTSxpQkFBWSxHQUFHLGFBQWEsS0FBSyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUM7UUFDNUQ7O1dBRUc7UUFDTSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQzFCOztXQUVHO1FBQ00sYUFBUSxHQUFHLEtBQUssQ0FBQztRQVMxQjs7V0FFRztRQUNNLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDekI7O1dBRUc7UUFDTSxTQUFJLEdBQUcsS0FBSyxDQUFDO1FBVXRCOzs7V0FHRztRQUNNLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFFM0I7OztXQUdHO1FBQ00sV0FBTSxHQUFHLEtBQUssQ0FBQztRQUV4Qjs7O1dBR0c7UUFDTSxTQUFJLEdBQXVCLElBQUksQ0FBQztRQUV6Qzs7O1dBR0c7UUFDTSxrQkFBYSxHQUFHLEtBQUssQ0FBQztRQVEvQjs7V0FFRztRQUNNLGdCQUFXLEdBQXlCLFdBQVcsQ0FBQztJQTBCSSxDQUFDO0lBVDlELElBQXlDLFVB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QkFNRyxRQUFRO3NCQUFoQixLQUFLO2dCQUtHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBS0csU0FBUztzQkFBakIsS0FBSztnQkFFZ0IsT0FBTztzQkFBNUIsU0FBUzt1QkFBQyxTQUFTO2dCQUVJLFFBQVE7c0JBQS9CLFlBQVk7dUJBQUMsUUFBUTtnQkFHc0IsU0FBUztzQkFBcEQsWUFBWTt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO2dCQUcxQyxhQUFhO3NCQURaLFlBQVk7dUJBQUMsYUFBYSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFHTCxVQUFVO3NCQUFsRCxXQUFXO3VCQUFDLHNCQUFzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0SW5wdXQsXG5cdEFmdGVyVmlld0luaXQsXG5cdEVsZW1lbnRSZWYsXG5cdEhvc3RCaW5kaW5nLFxuXHRUZW1wbGF0ZVJlZixcblx0Vmlld0NoaWxkLFxuXHRDb250ZW50Q2hpbGQsXG5cdEFmdGVyQ29udGVudEluaXQsXG5cdENoYW5nZURldGVjdG9yUmVmXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5cbmltcG9ydCB7IFRleHRBcmVhIH0gZnJvbSBcIi4vdGV4dC1hcmVhLmRpcmVjdGl2ZVwiO1xuaW1wb3J0IHsgVGV4dElucHV0IH0gZnJvbSBcIi4vaW5wdXQuZGlyZWN0aXZlXCI7XG5pbXBvcnQgeyBQYXNzd29yZElucHV0IH0gZnJvbSBcIi4vcGFzc3dvcmQuZGlyZWN0aXZlXCI7XG5cbi8qKlxuICogR2V0IHN0YXJ0ZWQgd2l0aCBpbXBvcnRpbmcgdGhlIG1vZHVsZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBJbnB1dE1vZHVsZSB9IGZyb20gJ2NhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXInO1xuICogYGBgXG4gKlxuICogVG8gcHJldmVudCBhdHRyaWJ1dGUgZHJpbGxpbmcsIHVzZSBgaWJtLXRleHQtbGFiZWxgIG9yIGBpYm0tdGV4dGFyZWEtbGFiZWxgIGNvbXBvbmVudHNcbiAqXG4gKiBgYGBodG1sXG4gKiA8Y2RzLWxhYmVsPlxuICogXHRMYWJlbFxuICogXHQ8aW5wdXQgY2RzVGV4dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiaW5wdXQtZmllbGRcIj5cbiAqIDwvY2RzLWxhYmVsPlxuICogYGBgXG4gKlxuICogW1NlZSBkZW1vXSguLi8uLi8/cGF0aD0vc3RvcnkvY29tcG9uZW50cy1pbnB1dC0tYmFzaWMpXG4gKi9cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogXCJjZHMtbGFiZWwsIGlibS1sYWJlbFwiLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdDxuZy10ZW1wbGF0ZSAjaW5wdXRDb250ZW50VGVtcGxhdGU+XG5cdFx0XHQ8bmctY29udGVudCBzZWxlY3Q9XCJpbnB1dCx0ZXh0YXJlYSxkaXZcIj48L25nLWNvbnRlbnQ+XG5cdFx0PC9uZy10ZW1wbGF0ZT5cblxuXHRcdDxuZy10ZW1wbGF0ZSAjbGFiZWxDb250ZW50VGVtcGxhdGU+XG5cdFx0XHQ8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG5cdFx0PC9uZy10ZW1wbGF0ZT5cblxuXHRcdDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInR5cGVcIj5cblx0XHRcdDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidUZXh0QXJlYSdcIj5cblx0XHRcdFx0PGNkcy10ZXh0YXJlYS1sYWJlbFxuXHRcdFx0XHRcdFtsYWJlbElucHV0SURdPVwibGFiZWxJbnB1dElEXCJcblx0XHRcdFx0XHRbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuXHRcdFx0XHRcdFtza2VsZXRvbl09XCJza2VsZXRvblwiXG5cdFx0XHRcdFx0W2hlbHBlclRleHRdPVwiaGVscGVyVGV4dFwiXG5cdFx0XHRcdFx0W2ludmFsaWRdPVwiaW52YWxpZFwiXG5cdFx0XHRcdFx0W2ludmFsaWRUZXh0XT1cImludmFsaWRUZXh0XCJcblx0XHRcdFx0XHRbd2Fybl09XCJ3YXJuXCJcblx0XHRcdFx0XHRbd2FyblRleHRdPVwid2FyblRleHRcIlxuXHRcdFx0XHRcdFthcmlhTGFiZWxdPVwiYXJpYUxhYmVsXCJcblx0XHRcdFx0XHRbaGlkZUxhYmVsXT1cImhpZGVMYWJlbFwiXG5cdFx0XHRcdFx0W2VuYWJsZUNvdW50ZXJdPVwiZW5hYmxlQ291bnRlclwiXG5cdFx0XHRcdFx0W21heENvdW50XT1cIm1heENvdW50XCJcblx0XHRcdFx0XHRbY291bnRlck1vZGVdPVwiY291bnRlck1vZGVcIlxuXHRcdFx0XHRcdFtkZWNvcmF0b3JdPVwiZGVjb3JhdG9yXCJcblx0XHRcdFx0XHRbbGFiZWxUZW1wbGF0ZV09XCJsYWJlbENvbnRlbnRUZW1wbGF0ZVwiXG5cdFx0XHRcdFx0W3RleHRBcmVhVGVtcGxhdGVdPVwiaW5wdXRDb250ZW50VGVtcGxhdGVcIj5cblx0XHRcdFx0PC9jZHMtdGV4dGFyZWEtbGFiZWw+XG5cdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHRcdDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidUZXh0SW5wdXQnXCI+XG5cdFx0XHRcdDxjZHMtdGV4dC1sYWJlbFxuXHRcdFx0XHRcdFtsYWJlbElucHV0SURdPVwibGFiZWxJbnB1dElEXCJcblx0XHRcdFx0XHRbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuXHRcdFx0XHRcdFtza2VsZXRvbl09XCJza2VsZXRvblwiXG5cdFx0XHRcdFx0W2hlbHBlclRleHRdPVwiaGVscGVyVGV4dFwiXG5cdFx0XHRcdFx0W2ludmFsaWRdPVwiaW52YWxpZFwiXG5cdFx0XHRcdFx0W2ludmFsaWRUZXh0XT1cImludmFsaWRUZXh0XCJcblx0XHRcdFx0XHRbd2Fybl09XCJ3YXJuXCJcblx0XHRcdFx0XHRbd2FyblRleHRdPVwid2FyblRleHRcIlxuXHRcdFx0XHRcdFthcmlhTGFiZWxdPVwiYXJpYUxhYmVsXCJcblx0XHRcdFx0XHRbaGlkZUxhYmVsXT1cImhpZGVMYWJlbFwiXG5cdFx0XHRcdFx0W2lubGluZV09XCJpbmxpbmVcIlxuXHRcdFx0XHRcdFtzaXplXT1cInNpemVcIlxuXHRcdFx0XHRcdFtlbmFibGVDb3VudGVyXT1cImVuYWJsZUNvdW50ZXJcIlxuXHRcdFx0XHRcdFttYXhDb3VudF09XCJtYXhDb3VudFwiXG5cdFx0XHRcdFx0W2RlY29yYXRvcl09XCJkZWNvcmF0b3JcIlxuXHRcdFx0XHRcdFtsYWJlbFRlbXBsYXRlXT1cImxhYmVsQ29udGVudFRlbXBsYXRlXCJcblx0XHRcdFx0XHRbdGV4dElucHV0VGVtcGxhdGVdPVwiaW5wdXRDb250ZW50VGVtcGxhdGVcIj5cblx0XHRcdFx0PC9jZHMtdGV4dC1sYWJlbD5cblx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdFx0PG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ1Bhc3N3b3JkSW5wdXQnXCI+XG5cdFx0XHRcdDxjZHMtcGFzc3dvcmQtbGFiZWxcblx0XHRcdFx0XHRbbGFiZWxJbnB1dElEXT1cImxhYmVsSW5wdXRJRFwiXG5cdFx0XHRcdFx0W2Rpc2FibGVkXT1cImRpc2FibGVkXCJcblx0XHRcdFx0XHRbc2tlbGV0b25dPVwic2tlbGV0b25cIlxuXHRcdFx0XHRcdFtoZWxwZXJUZXh0XT1cImhlbHBlclRleHRcIlxuXHRcdFx0XHRcdFtpbnZhbGlkXT1cImludmFsaWRcIlxuXHRcdFx0XHRcdFtpbnZhbGlkVGV4dF09XCJpbnZhbGlkVGV4dFwiXG5cdFx0XHRcdFx0W3dhcm5dPVwid2FyblwiXG5cdFx0XHRcdFx0W3dhcm5UZXh0XT1cIndhcm5UZXh0XCJcblx0XHRcdFx0XHRbYXJpYUxhYmVsXT1cImFyaWFMYWJlbFwiXG5cdFx0XHRcdFx0W2hpZGVMYWJlbF09XCJoaWRlTGFiZWxcIlxuXHRcdFx0XHRcdFtpbmxpbmVdPVwiaW5saW5lXCJcblx0XHRcdFx0XHRbbGFiZWxUZW1wbGF0ZV09XCJsYWJlbENvbnRlbnRUZW1wbGF0ZVwiXG5cdFx0XHRcdFx0W3Bhc3N3b3JkSW5wdXRUZW1wbGF0ZV09XCJpbnB1dENvbnRlbnRUZW1wbGF0ZVwiPlxuXHRcdFx0XHQ8L2Nkcy1wYXNzd29yZC1sYWJlbD5cblx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdFx0PG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hEZWZhdWx0PlxuXHRcdFx0XHQ8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiZGVmYXVsdFwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHQ8L25nLWNvbnRhaW5lcj5cblxuXHRcdDxuZy10ZW1wbGF0ZSAjZGVmYXVsdD5cblx0XHRcdDxsYWJlbFxuXHRcdFx0XHRbZm9yXT1cImxhYmVsSW5wdXRJRFwiXG5cdFx0XHRcdFthdHRyLmFyaWEtbGFiZWxdPVwiYXJpYUxhYmVsXCJcblx0XHRcdFx0Y2xhc3M9XCJjZHMtLWxhYmVsXCJcblx0XHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHRcdCdjZHMtLWxhYmVsLS1kaXNhYmxlZCc6IGRpc2FibGVkLFxuXHRcdFx0XHRcdCdjZHMtLXNrZWxldG9uJzogc2tlbGV0b25cblx0XHRcdFx0fVwiPlxuXHRcdFx0XHQ8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwibGFiZWxDb250ZW50VGVtcGxhdGVcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0PC9sYWJlbD5cblx0XHRcdDxkaXZcblx0XHRcdFx0Y2xhc3M9XCJjZHMtLXRleHQtaW5wdXRfX2ZpZWxkLXdyYXBwZXJcIlxuXHRcdFx0XHRbbmdDbGFzc109XCJ7XG5cdFx0XHRcdFx0J2Nkcy0tdGV4dC1pbnB1dF9fZmllbGQtd3JhcHBlci0td2FybmluZyc6IHdhcm5cblx0XHRcdFx0fVwiXG5cdFx0XHRcdFthdHRyLmRhdGEtaW52YWxpZF09XCIoaW52YWxpZCA/IHRydWUgOiBudWxsKVwiXG5cdFx0XHRcdCN3cmFwcGVyPlxuXHRcdFx0XHQ8c3ZnXG5cdFx0XHRcdFx0Km5nSWY9XCJpbnZhbGlkXCJcblx0XHRcdFx0XHRjZHNJY29uPVwid2FybmluZy0tZmlsbGVkXCJcblx0XHRcdFx0XHRzaXplPVwiMTZcIlxuXHRcdFx0XHRcdGNsYXNzPVwiY2RzLS10ZXh0LWlucHV0X19pbnZhbGlkLWljb25cIj5cblx0XHRcdFx0PC9zdmc+XG5cdFx0XHRcdDxzdmdcblx0XHRcdFx0XHQqbmdJZj1cIiFpbnZhbGlkICYmIHdhcm5cIlxuXHRcdFx0XHRcdGNkc0ljb249XCJ3YXJuaW5nLS1hbHQtLWZpbGxlZFwiXG5cdFx0XHRcdFx0c2l6ZT1cIjE2XCJcblx0XHRcdFx0XHRjbGFzcz1cImNkcy0tdGV4dC1pbnB1dF9faW52YWxpZC1pY29uIGNkcy0tdGV4dC1pbnB1dF9faW52YWxpZC1pY29uLS13YXJuaW5nXCI+XG5cdFx0XHRcdDwvc3ZnPlxuXHRcdFx0XHQ8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiaW5wdXRDb250ZW50VGVtcGxhdGVcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0PC9kaXY+XG5cdFx0XHQ8ZGl2XG5cdFx0XHRcdCpuZ0lmPVwiIXNrZWxldG9uICYmIGhlbHBlclRleHQgJiYgIWludmFsaWQgJiYgIXdhcm5cIlxuXHRcdFx0XHRjbGFzcz1cImNkcy0tZm9ybV9faGVscGVyLXRleHRcIlxuXHRcdFx0XHRbbmdDbGFzc109XCJ7J2Nkcy0tZm9ybV9faGVscGVyLXRleHQtLWRpc2FibGVkJzogZGlzYWJsZWR9XCI+XG5cdFx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNUZW1wbGF0ZShoZWxwZXJUZXh0KVwiPnt7aGVscGVyVGV4dH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaGVscGVyVGV4dClcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJoZWxwZXJUZXh0XCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PGRpdiAqbmdJZj1cImludmFsaWRcIiBjbGFzcz1cImNkcy0tZm9ybS1yZXF1aXJlbWVudFwiPlxuXHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUoaW52YWxpZFRleHQpXCI+e3tpbnZhbGlkVGV4dH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaW52YWxpZFRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiaW52YWxpZFRleHRcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0PC9kaXY+XG5cdFx0XHQ8ZGl2ICpuZ0lmPVwiIWludmFsaWQgJiYgd2FyblwiIGNsYXNzPVwiY2RzLS1mb3JtLXJlcXVpcmVtZW50XCI+XG5cdFx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNUZW1wbGF0ZSh3YXJuVGV4dClcIj57e3dhcm5UZXh0fX08L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0PG5nLXRlbXBsYXRlICpuZ0lmPVwiaXNUZW1wbGF0ZSh3YXJuVGV4dClcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJ3YXJuVGV4dFwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHQ8L2Rpdj5cblx0XHQ8L25nLXRlbXBsYXRlPlxuXHRgXG59KVxuZXhwb3J0IGNsYXNzIExhYmVsIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgQWZ0ZXJWaWV3SW5pdCB7XG5cdC8qKlxuXHQgKiBVc2VkIHRvIGJ1aWxkIHRoZSBpZCBvZiB0aGUgaW5wdXQgaXRlbSBhc3NvY2lhdGVkIHdpdGggdGhlIGBMYWJlbGAuXG5cdCAqL1xuXHRzdGF0aWMgbGFiZWxDb3VudGVyID0gMDtcblx0LyoqXG5cdCAqIFRoZSBpZCBvZiB0aGUgaW5wdXQgaXRlbSBhc3NvY2lhdGVkIHdpdGggdGhlIGBMYWJlbGAuIFRoaXMgdmFsdWUgaXMgYWxzbyB1c2VkIHRvIGFzc29jaWF0ZSB0aGUgYExhYmVsYCB3aXRoXG5cdCAqIGl0cyBpbnB1dCBjb3VudGVycGFydCB0aHJvdWdoIHRoZSAnZm9yJyBhdHRyaWJ1dGUuXG5cdCAqL1xuXHRASW5wdXQoKSBsYWJlbElucHV0SUQgPSBgY2RzLWxhYmVsLSR7TGFiZWwubGFiZWxDb3VudGVyKyt9YDtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgZm9yIGRpc2FibGVkIHN0YXRlLlxuXHQgKi9cblx0QElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgZm9yIGEgbG9hZGluZyBsYWJlbC5cblx0ICovXG5cdEBJbnB1dCgpIHNrZWxldG9uID0gZmFsc2U7XG5cdC8qKlxuXHQgKiBPcHRpb25hbCBoZWxwZXIgdGV4dCB0aGF0IGFwcGVhcnMgdW5kZXIgdGhlIGxhYmVsLlxuXHQgKi9cblx0QElucHV0KCkgaGVscGVyVGV4dDogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pjtcblx0LyoqXG5cdCAqIFNldHMgdGhlIGludmFsaWQgdGV4dC5cblx0ICovXG5cdEBJbnB1dCgpIGludmFsaWRUZXh0OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuXHQvKipcblx0ICogU2V0IHRvIGB0cnVlYCBmb3IgYW4gaW52YWxpZCBsYWJlbCBjb21wb25lbnQuXG5cdCAqL1xuXHRASW5wdXQoKSBpbnZhbGlkID0gZmFsc2U7XG5cdC8qKlxuXHQgKiBTZXQgdG8gYHRydWVgIHRvIHNob3cgYSB3YXJuaW5nIChjb250ZW50cyBzZXQgYnkgd2FybmluZ1RleHQpXG5cdCAqL1xuXHRASW5wdXQoKSB3YXJuID0gZmFsc2U7XG5cdC8qKlxuXHQgKiBTZXRzIHRoZSB3YXJuaW5nIHRleHRcblx0ICovXG5cdEBJbnB1dCgpIHdhcm5UZXh0OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuXHQvKipcblx0ICogU2V0IHRoZSBhcmlhbGFiZWwgZm9yIGxhYmVsXG5cdCAqL1xuXHRASW5wdXQoKSBhcmlhTGFiZWw6IHN0cmluZztcblxuXHQvKipcblx0ICogU2V0IHRvIGB0cnVlYCB0byBoaWRlIHRoZSBsYWJlbCB2aXN1YWxseSwgYnV0IGtlZXAgYWNjZXNzaWJsZSB0b1xuXHQgKiBzY3JlZW4gcmVhZGVycy5cblx0ICovXG5cdEBJbnB1dCgpIGhpZGVMYWJlbCA9IGZhbHNlO1xuXG5cdC8qKlxuXHQgKiBTZXQgdG8gYHRydWVgIHRvIHJlbmRlciB0aGUgbGFiZWwgYW5kIGZpZWxkIHNpZGUtYnktc2lkZSBpbnN0ZWFkIG9mIHN0YWNrZWQuXG5cdCAqIEFwcGxpZXMgdG8gYFRleHRJbnB1dGAgYW5kIGBQYXNzd29yZElucHV0YCBsYWJlbCB2YXJpYW50cy5cblx0ICovXG5cdEBJbnB1dCgpIGlubGluZSA9IGZhbHNlO1xuXG5cdC8qKlxuXHQgKiBUaGUgcmVuZGVyIHNpemUgZm9yIHRoZSBgVGV4dElucHV0YC4gVXNlZCB0byBjb21wdXRlIElOTElORSBsYWJlbCBzaXplXG5cdCAqIHZhcmlhbnQgY2xhc3Nlcy5cblx0ICovXG5cdEBJbnB1dCgpIHNpemU6IFwic21cIiB8IFwibWRcIiB8IFwibGdcIiA9IFwibWRcIjtcblxuXHQvKipcblx0ICogU2V0IHRvIGB0cnVlYCAoYG1heENvdW50YCBtdXN0IGJlIHNldCkgdG8gZGlzcGxheXMgYSBsaXZlIGNoYXJhY3Rlci93b3JkXG5cdCAqIGNvdW50ZXIgYWxvbmdzaWRlIHRoZSBsYWJlbC5cblx0ICovXG5cdEBJbnB1dCgpIGVuYWJsZUNvdW50ZXIgPSBmYWxzZTtcblxuXHQvKipcblx0ICogTWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyAob3Igd29yZHMpIGFsbG93ZWQuIFJlcXVpcmVkIGZvciB0aGVcblx0ICogY291bnRlciB0byBkaXNwbGF5LlxuXHQgKi9cblx0QElucHV0KCkgbWF4Q291bnQ6IG51bWJlcjtcblxuXHQvKipcblx0ICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBgVGV4dEFyZWFgIGNvdW50ZXIgY291bnRzIGNoYXJhY3RlcnMgb3Igd29yZHMuXG5cdCAqL1xuXHRASW5wdXQoKSBjb3VudGVyTW9kZTogXCJjaGFyYWN0ZXJcIiB8IFwid29yZFwiID0gXCJjaGFyYWN0ZXJcIjtcblxuXHQvKipcblx0ICogKipFeHBlcmltZW50YWwqKjogT3B0aW9uYWwgZGVjb3JhdG9yIChlLmcuIEFJIGxhYmVsKS5cblx0ICovXG5cdEBJbnB1dCgpIGRlY29yYXRvcjogVGVtcGxhdGVSZWY8YW55PjtcblxuXHRAVmlld0NoaWxkKFwid3JhcHBlclwiKSB3cmFwcGVyOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcblxuXHRAQ29udGVudENoaWxkKFRleHRBcmVhKSB0ZXh0QXJlYTogVGV4dEFyZWE7XG5cblx0Ly8gQHRzLWlnbm9yZVxuXHRAQ29udGVudENoaWxkKFRleHRJbnB1dCwgeyBzdGF0aWM6IGZhbHNlIH0pIHRleHRJbnB1dDogVGV4dElucHV0O1xuXG5cdEBDb250ZW50Q2hpbGQoUGFzc3dvcmRJbnB1dCwgeyBzdGF0aWM6IGZhbHNlIH0pXG5cdHBhc3N3b3JkSW5wdXQ6IFBhc3N3b3JkSW5wdXQ7XG5cblx0QEhvc3RCaW5kaW5nKFwiY2xhc3MuY2RzLS1mb3JtLWl0ZW1cIikgZ2V0IGxhYmVsQ2xhc3MoKSB7XG5cdFx0cmV0dXJuIHRoaXMudHlwZSA9PT0gdW5kZWZpbmVkO1xuXHR9XG5cblx0dHlwZTogXCJUZXh0QXJlYVwiIHwgXCJUZXh0SW5wdXRcIiB8IFwiUGFzc3dvcmRJbnB1dFwiO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIExhYmVsLlxuXHQgKi9cblx0Y29uc3RydWN0b3IocHJvdGVjdGVkIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge31cblxuXHQvKipcblx0ICogVXBkYXRlIHdyYXBwZXIgY2xhc3MgaWYgYSB0ZXh0YXJlYSBpcyBob3N0ZWQuXG5cdCAqL1xuXHRuZ0FmdGVyQ29udGVudEluaXQoKSB7XG5cdFx0aWYgKHRoaXMudGV4dEFyZWEpIHtcblx0XHRcdHRoaXMudHlwZSA9IFwiVGV4dEFyZWFcIjtcblx0XHR9IGVsc2UgaWYgKHRoaXMudGV4dElucHV0KSB7XG5cdFx0XHR0aGlzLnR5cGUgPSBcIlRleHRJbnB1dFwiO1xuXHRcdH0gZWxzZSBpZiAodGhpcy5wYXNzd29yZElucHV0KSB7XG5cdFx0XHR0aGlzLnR5cGUgPSBcIlBhc3N3b3JkSW5wdXRcIjtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgaWQgb24gdGhlIGlucHV0IGl0ZW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBgTGFiZWxgLlxuXHQgKi9cblx0bmdBZnRlclZpZXdJbml0KCkge1xuXHRcdC8vIFdpbGwgb25seSBiZSBjYWxsZWQgd2hlbiBgZGVmYXVsdGAgdGVtcGxhdGUgaXMgYmVpbmcgdXNlZFxuXHRcdGlmICh0aGlzLndyYXBwZXIpIHtcblx0XHRcdC8vIFByaW9yaXRpemUgc2V0dGluZyBpZCB0byBgaW5wdXRgICYgYHRleHRhcmVhYCBvdmVyIGRpdlxuXHRcdFx0Y29uc3QgaW5wdXRFbGVtZW50ID0gdGhpcy53cmFwcGVyLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcImlucHV0LHRleHRhcmVhXCIpO1xuXHRcdFx0aWYgKGlucHV0RWxlbWVudCkge1xuXHRcdFx0XHQvLyBhdm9pZCBvdmVycmlkaW5nIGlkcyBhbHJlYWR5IHNldCBieSB0aGUgdXNlciByZXVzZSBpdCBpbnN0ZWFkXG5cdFx0XHRcdGlmIChpbnB1dEVsZW1lbnQuaWQpIHtcblx0XHRcdFx0XHR0aGlzLmxhYmVsSW5wdXRJRCA9IGlucHV0RWxlbWVudC5pZDtcblx0XHRcdFx0XHR0aGlzLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpbnB1dEVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgdGhpcy5sYWJlbElucHV0SUQpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IGRpdkVsZW1lbnQgPSB0aGlzLndyYXBwZXIubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiZGl2XCIpO1xuXHRcdFx0aWYgKGRpdkVsZW1lbnQpIHtcblx0XHRcdFx0aWYgKGRpdkVsZW1lbnQuaWQpIHtcblx0XHRcdFx0XHR0aGlzLmxhYmVsSW5wdXRJRCA9IGRpdkVsZW1lbnQuaWQ7XG5cdFx0XHRcdFx0dGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGl2RWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCB0aGlzLmxhYmVsSW5wdXRJRCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGlzVGVtcGxhdGUodmFsdWUpIHtcblx0XHRyZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBUZW1wbGF0ZVJlZjtcblx0fVxufVxuIl19