carbon-components-angular
Version:
Next generation components
425 lines (419 loc) • 33.7 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" }, 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"
[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"
[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"] }, { 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", "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"
[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"
[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
}], 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGFiZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2lucHV0L2xhYmVsLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ04sU0FBUyxFQUNULEtBQUssRUFHTCxXQUFXLEVBQ1gsV0FBVyxFQUNYLFNBQVMsRUFDVCxZQUFZLEVBR1osTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7Ozs7Ozs7QUFFckQ7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBNEhILE1BQU0sT0FBTyxLQUFLO0lBOEZqQjs7T0FFRztJQUNILFlBQXNCLGlCQUFvQztRQUFwQyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBNUYxRDs7O1dBR0c7UUFDTSxpQkFBWSxHQUFHLGFBQWEsS0FBSyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUM7UUFDNUQ7O1dBRUc7UUFDTSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQzFCOztXQUVHO1FBQ00sYUFBUSxHQUFHLEtBQUssQ0FBQztRQVMxQjs7V0FFRztRQUNNLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDekI7O1dBRUc7UUFDTSxTQUFJLEdBQUcsS0FBSyxDQUFDO1FBVXRCOzs7V0FHRztRQUNNLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFFM0I7OztXQUdHO1FBQ00sV0FBTSxHQUFHLEtBQUssQ0FBQztRQUV4Qjs7O1dBR0c7UUFDTSxTQUFJLEdBQXVCLElBQUksQ0FBQztRQUV6Qzs7O1dBR0c7UUFDTSxrQkFBYSxHQUFHLEtBQUssQ0FBQztRQVEvQjs7V0FFRztRQUNNLGdCQUFXLEdBQXlCLFdBQVcsQ0FBQztJQXFCSSxDQUFDO0lBVDlELElBQXlDLFVBQVU7UUFDbEQsT0FBTyxJQUFJLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQztJQUNoQyxDQUFDO0lBU0Q7O09BRUc7SUFDSCxrQkFBa0I7UUFDakIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2xCLElBQUksQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDO1NBQ3ZCO2FBQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQzFCLElBQUksQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDO1NBQ3hCO2FBQU0sSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQzlCLElBQUksQ0FBQyxJQUFJLEdBQUcsZUFBZSxDQUFDO1NBQzVCO0lBQ0YsQ0FBQztJQUVEOztPQUVHO0lBQ0gsZUFBZTtRQUNkLDREQUE0RDtRQUM1RCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDakIseURBQXlEO1lBQ3pELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2hGLElBQUksWUFBWSxFQUFFO2dCQUNqQixnRUFBZ0U7Z0JBQ2hFLElBQUksWUFBWSxDQUFDLEVBQUUsRUFBRTtvQkFDcEIsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUMsRUFBRSxDQUFDO29CQUNwQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7aUJBQ3ZDO2dCQUNELFlBQVksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDbkQsT0FBTzthQUNQO1lBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25FLElBQUksVUFBVSxFQUFFO2dCQUNmLElBQUksVUFBVSxDQUFDLEVBQUUsRUFBRTtvQkFDbEIsSUFBSSxDQUFDLFlBQVksR0FBRyxVQUFVLENBQUMsRUFBRSxDQUFDO29CQUNsQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7aUJBQ3ZDO2dCQUNELFVBQVUsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQzthQUNqRDtTQUNEO0lBQ0YsQ0FBQztJQUVNLFVBQVUsQ0FBQyxLQUFLO1FBQ3RCLE9BQU8sS0FBSyxZQUFZLFdBQVcsQ0FBQztJQUNyQyxDQUFDOztBQTlJRDs7R0FFRztBQUNJLGtCQUFZLEdBQUcsQ0FBQyxDQUFDO2tHQUpaLEtBQUs7c0ZBQUwsS0FBSyw2Z0JBZ0ZILFFBQVEsNEVBR1IsU0FBUyxnRkFFVCxhQUFhLG9KQTlNakI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBdUhUOzJGQUVXLEtBQUs7a0JBM0hqQixTQUFTO21CQUFDO29CQUNWLFFBQVEsRUFBRSxzQkFBc0I7b0JBQ2hDLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUF1SFQ7aUJBQ0Q7d0dBVVMsWUFBWTtzQkFBcEIsS0FBSztnQkFJRyxRQUFRO3NCQUFoQixLQUFLO2dCQUlHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBSUcsVUFBVTtzQkFBbEIsS0FBSztnQkFJRyxXQUFXO3NCQUFuQixLQUFLO2dCQUlHLE9BQU87c0JBQWYsS0FBSztnQkFJRyxJQUFJO3NCQUFaLEtBQUs7Z0JBSUcsUUFBUTtzQkFBaEIsS0FBSztnQkFJRyxTQUFTO3NCQUFqQixLQUFLO2dCQU1HLFNBQVM7c0JBQWpCLEtBQUs7Z0JBTUcsTUFBTTtzQkFBZCxLQUFLO2dCQU1HLElBQUk7c0JBQVosS0FBSztnQkFNRyxhQUFhO3NCQUFyQixLQUFLO2dCQU1HLFFBQVE7c0JBQWhCLEtBQUs7Z0JBS0csV0FBVztzQkFBbkIsS0FBSztnQkFFZ0IsT0FBTztzQkFBNUIsU0FBUzt1QkFBQyxTQUFTO2dCQUVJLFFBQVE7c0JBQS9CLFlBQVk7dUJBQUMsUUFBUTtnQkFHc0IsU0FBUztzQkFBcEQsWUFBWTt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO2dCQUcxQyxhQUFhO3NCQURaLFlBQVk7dUJBQUMsYUFBYSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFHTCxVQUFVO3NCQUFsRCxXQUFXO3VCQUFDLHNCQUFzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0SW5wdXQsXG5cdEFmdGVyVmlld0luaXQsXG5cdEVsZW1lbnRSZWYsXG5cdEhvc3RCaW5kaW5nLFxuXHRUZW1wbGF0ZVJlZixcblx0Vmlld0NoaWxkLFxuXHRDb250ZW50Q2hpbGQsXG5cdEFmdGVyQ29udGVudEluaXQsXG5cdENoYW5nZURldGVjdG9yUmVmXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5cbmltcG9ydCB7IFRleHRBcmVhIH0gZnJvbSBcIi4vdGV4dC1hcmVhLmRpcmVjdGl2ZVwiO1xuaW1wb3J0IHsgVGV4dElucHV0IH0gZnJvbSBcIi4vaW5wdXQuZGlyZWN0aXZlXCI7XG5pbXBvcnQgeyBQYXNzd29yZElucHV0IH0gZnJvbSBcIi4vcGFzc3dvcmQuZGlyZWN0aXZlXCI7XG5cbi8qKlxuICogR2V0IHN0YXJ0ZWQgd2l0aCBpbXBvcnRpbmcgdGhlIG1vZHVsZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBJbnB1dE1vZHVsZSB9IGZyb20gJ2NhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXInO1xuICogYGBgXG4gKlxuICogVG8gcHJldmVudCBhdHRyaWJ1dGUgZHJpbGxpbmcsIHVzZSBgaWJtLXRleHQtbGFiZWxgIG9yIGBpYm0tdGV4dGFyZWEtbGFiZWxgIGNvbXBvbmVudHNcbiAqXG4gKiBgYGBodG1sXG4gKiA8Y2RzLWxhYmVsPlxuICogXHRMYWJlbFxuICogXHQ8aW5wdXQgY2RzVGV4dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiaW5wdXQtZmllbGRcIj5cbiAqIDwvY2RzLWxhYmVsPlxuICogYGBgXG4gKlxuICogW1NlZSBkZW1vXSguLi8uLi8/cGF0aD0vc3RvcnkvY29tcG9uZW50cy1pbnB1dC0tYmFzaWMpXG4gKi9cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogXCJjZHMtbGFiZWwsIGlibS1sYWJlbFwiLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdDxuZy10ZW1wbGF0ZSAjaW5wdXRDb250ZW50VGVtcGxhdGU+XG5cdFx0XHQ8bmctY29udGVudCBzZWxlY3Q9XCJpbnB1dCx0ZXh0YXJlYSxkaXZcIj48L25nLWNvbnRlbnQ+XG5cdFx0PC9uZy10ZW1wbGF0ZT5cblxuXHRcdDxuZy10ZW1wbGF0ZSAjbGFiZWxDb250ZW50VGVtcGxhdGU+XG5cdFx0XHQ8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG5cdFx0PC9uZy10ZW1wbGF0ZT5cblxuXHRcdDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cInR5cGVcIj5cblx0XHRcdDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidUZXh0QXJlYSdcIj5cblx0XHRcdFx0PGNkcy10ZXh0YXJlYS1sYWJlbFxuXHRcdFx0XHRcdFtsYWJlbElucHV0SURdPVwibGFiZWxJbnB1dElEXCJcblx0XHRcdFx0XHRbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuXHRcdFx0XHRcdFtza2VsZXRvbl09XCJza2VsZXRvblwiXG5cdFx0XHRcdFx0W2hlbHBlclRleHRdPVwiaGVscGVyVGV4dFwiXG5cdFx0XHRcdFx0W2ludmFsaWRdPVwiaW52YWxpZFwiXG5cdFx0XHRcdFx0W2ludmFsaWRUZXh0XT1cImludmFsaWRUZXh0XCJcblx0XHRcdFx0XHRbd2Fybl09XCJ3YXJuXCJcblx0XHRcdFx0XHRbd2FyblRleHRdPVwid2FyblRleHRcIlxuXHRcdFx0XHRcdFthcmlhTGFiZWxdPVwiYXJpYUxhYmVsXCJcblx0XHRcdFx0XHRbaGlkZUxhYmVsXT1cImhpZGVMYWJlbFwiXG5cdFx0XHRcdFx0W2VuYWJsZUNvdW50ZXJdPVwiZW5hYmxlQ291bnRlclwiXG5cdFx0XHRcdFx0W21heENvdW50XT1cIm1heENvdW50XCJcblx0XHRcdFx0XHRbY291bnRlck1vZGVdPVwiY291bnRlck1vZGVcIlxuXHRcdFx0XHRcdFtsYWJlbFRlbXBsYXRlXT1cImxhYmVsQ29udGVudFRlbXBsYXRlXCJcblx0XHRcdFx0XHRbdGV4dEFyZWFUZW1wbGF0ZV09XCJpbnB1dENvbnRlbnRUZW1wbGF0ZVwiPlxuXHRcdFx0XHQ8L2Nkcy10ZXh0YXJlYS1sYWJlbD5cblx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdFx0PG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ1RleHRJbnB1dCdcIj5cblx0XHRcdFx0PGNkcy10ZXh0LWxhYmVsXG5cdFx0XHRcdFx0W2xhYmVsSW5wdXRJRF09XCJsYWJlbElucHV0SURcIlxuXHRcdFx0XHRcdFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG5cdFx0XHRcdFx0W3NrZWxldG9uXT1cInNrZWxldG9uXCJcblx0XHRcdFx0XHRbaGVscGVyVGV4dF09XCJoZWxwZXJUZXh0XCJcblx0XHRcdFx0XHRbaW52YWxpZF09XCJpbnZhbGlkXCJcblx0XHRcdFx0XHRbaW52YWxpZFRleHRdPVwiaW52YWxpZFRleHRcIlxuXHRcdFx0XHRcdFt3YXJuXT1cIndhcm5cIlxuXHRcdFx0XHRcdFt3YXJuVGV4dF09XCJ3YXJuVGV4dFwiXG5cdFx0XHRcdFx0W2FyaWFMYWJlbF09XCJhcmlhTGFiZWxcIlxuXHRcdFx0XHRcdFtoaWRlTGFiZWxdPVwiaGlkZUxhYmVsXCJcblx0XHRcdFx0XHRbaW5saW5lXT1cImlubGluZVwiXG5cdFx0XHRcdFx0W3NpemVdPVwic2l6ZVwiXG5cdFx0XHRcdFx0W2VuYWJsZUNvdW50ZXJdPVwiZW5hYmxlQ291bnRlclwiXG5cdFx0XHRcdFx0W21heENvdW50XT1cIm1heENvdW50XCJcblx0XHRcdFx0XHRbbGFiZWxUZW1wbGF0ZV09XCJsYWJlbENvbnRlbnRUZW1wbGF0ZVwiXG5cdFx0XHRcdFx0W3RleHRJbnB1dFRlbXBsYXRlXT1cImlucHV0Q29udGVudFRlbXBsYXRlXCI+XG5cdFx0XHRcdDwvY2RzLXRleHQtbGFiZWw+XG5cdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHRcdDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidQYXNzd29yZElucHV0J1wiPlxuXHRcdFx0XHQ8Y2RzLXBhc3N3b3JkLWxhYmVsXG5cdFx0XHRcdFx0W2xhYmVsSW5wdXRJRF09XCJsYWJlbElucHV0SURcIlxuXHRcdFx0XHRcdFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG5cdFx0XHRcdFx0W3NrZWxldG9uXT1cInNrZWxldG9uXCJcblx0XHRcdFx0XHRbaGVscGVyVGV4dF09XCJoZWxwZXJUZXh0XCJcblx0XHRcdFx0XHRbaW52YWxpZF09XCJpbnZhbGlkXCJcblx0XHRcdFx0XHRbaW52YWxpZFRleHRdPVwiaW52YWxpZFRleHRcIlxuXHRcdFx0XHRcdFt3YXJuXT1cIndhcm5cIlxuXHRcdFx0XHRcdFt3YXJuVGV4dF09XCJ3YXJuVGV4dFwiXG5cdFx0XHRcdFx0W2FyaWFMYWJlbF09XCJhcmlhTGFiZWxcIlxuXHRcdFx0XHRcdFtoaWRlTGFiZWxdPVwiaGlkZUxhYmVsXCJcblx0XHRcdFx0XHRbaW5saW5lXT1cImlubGluZVwiXG5cdFx0XHRcdFx0W2xhYmVsVGVtcGxhdGVdPVwibGFiZWxDb250ZW50VGVtcGxhdGVcIlxuXHRcdFx0XHRcdFtwYXNzd29yZElucHV0VGVtcGxhdGVdPVwiaW5wdXRDb250ZW50VGVtcGxhdGVcIj5cblx0XHRcdFx0PC9jZHMtcGFzc3dvcmQtbGFiZWw+XG5cdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHRcdDxuZy1jb250YWluZXIgKm5nU3dpdGNoRGVmYXVsdD5cblx0XHRcdFx0PG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImRlZmF1bHRcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0PC9uZy1jb250YWluZXI+XG5cdFx0PC9uZy1jb250YWluZXI+XG5cblx0XHQ8bmctdGVtcGxhdGUgI2RlZmF1bHQ+XG5cdFx0XHQ8bGFiZWxcblx0XHRcdFx0W2Zvcl09XCJsYWJlbElucHV0SURcIlxuXHRcdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbFwiXG5cdFx0XHRcdGNsYXNzPVwiY2RzLS1sYWJlbFwiXG5cdFx0XHRcdFtuZ0NsYXNzXT1cIntcblx0XHRcdFx0XHQnY2RzLS1sYWJlbC0tZGlzYWJsZWQnOiBkaXNhYmxlZCxcblx0XHRcdFx0XHQnY2RzLS1za2VsZXRvbic6IHNrZWxldG9uXG5cdFx0XHRcdH1cIj5cblx0XHRcdFx0PG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImxhYmVsQ29udGVudFRlbXBsYXRlXCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdDwvbGFiZWw+XG5cdFx0XHQ8ZGl2XG5cdFx0XHRcdGNsYXNzPVwiY2RzLS10ZXh0LWlucHV0X19maWVsZC13cmFwcGVyXCJcblx0XHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHRcdCdjZHMtLXRleHQtaW5wdXRfX2ZpZWxkLXdyYXBwZXItLXdhcm5pbmcnOiB3YXJuXG5cdFx0XHRcdH1cIlxuXHRcdFx0XHRbYXR0ci5kYXRhLWludmFsaWRdPVwiKGludmFsaWQgPyB0cnVlIDogbnVsbClcIlxuXHRcdFx0XHQjd3JhcHBlcj5cblx0XHRcdFx0PHN2Z1xuXHRcdFx0XHRcdCpuZ0lmPVwiaW52YWxpZFwiXG5cdFx0XHRcdFx0Y2RzSWNvbj1cIndhcm5pbmctLWZpbGxlZFwiXG5cdFx0XHRcdFx0c2l6ZT1cIjE2XCJcblx0XHRcdFx0XHRjbGFzcz1cImNkcy0tdGV4dC1pbnB1dF9faW52YWxpZC1pY29uXCI+XG5cdFx0XHRcdDwvc3ZnPlxuXHRcdFx0XHQ8c3ZnXG5cdFx0XHRcdFx0Km5nSWY9XCIhaW52YWxpZCAmJiB3YXJuXCJcblx0XHRcdFx0XHRjZHNJY29uPVwid2FybmluZy0tYWx0LS1maWxsZWRcIlxuXHRcdFx0XHRcdHNpemU9XCIxNlwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLXRleHQtaW5wdXRfX2ludmFsaWQtaWNvbiBjZHMtLXRleHQtaW5wdXRfX2ludmFsaWQtaWNvbi0td2FybmluZ1wiPlxuXHRcdFx0XHQ8L3N2Zz5cblx0XHRcdFx0PG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImlucHV0Q29udGVudFRlbXBsYXRlXCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PGRpdlxuXHRcdFx0XHQqbmdJZj1cIiFza2VsZXRvbiAmJiBoZWxwZXJUZXh0ICYmICFpbnZhbGlkICYmICF3YXJuXCJcblx0XHRcdFx0Y2xhc3M9XCJjZHMtLWZvcm1fX2hlbHBlci10ZXh0XCJcblx0XHRcdFx0W25nQ2xhc3NdPVwieydjZHMtLWZvcm1fX2hlbHBlci10ZXh0LS1kaXNhYmxlZCc6IGRpc2FibGVkfVwiPlxuXHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUoaGVscGVyVGV4dClcIj57e2hlbHBlclRleHR9fTwvbmctY29udGFpbmVyPlxuXHRcdFx0XHQ8bmctdGVtcGxhdGUgKm5nSWY9XCJpc1RlbXBsYXRlKGhlbHBlclRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiaGVscGVyVGV4dFwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHQ8L2Rpdj5cblx0XHRcdDxkaXYgKm5nSWY9XCJpbnZhbGlkXCIgY2xhc3M9XCJjZHMtLWZvcm0tcmVxdWlyZW1lbnRcIj5cblx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKGludmFsaWRUZXh0KVwiPnt7aW52YWxpZFRleHR9fTwvbmctY29udGFpbmVyPlxuXHRcdFx0XHQ8bmctdGVtcGxhdGUgKm5nSWY9XCJpc1RlbXBsYXRlKGludmFsaWRUZXh0KVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImludmFsaWRUZXh0XCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PGRpdiAqbmdJZj1cIiFpbnZhbGlkICYmIHdhcm5cIiBjbGFzcz1cImNkcy0tZm9ybS1yZXF1aXJlbWVudFwiPlxuXHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUod2FyblRleHQpXCI+e3t3YXJuVGV4dH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUod2FyblRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwid2FyblRleHRcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0PC9kaXY+XG5cdFx0PC9uZy10ZW1wbGF0ZT5cblx0YFxufSlcbmV4cG9ydCBjbGFzcyBMYWJlbCBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQsIEFmdGVyVmlld0luaXQge1xuXHQvKipcblx0ICogVXNlZCB0byBidWlsZCB0aGUgaWQgb2YgdGhlIGlucHV0IGl0ZW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBgTGFiZWxgLlxuXHQgKi9cblx0c3RhdGljIGxhYmVsQ291bnRlciA9IDA7XG5cdC8qKlxuXHQgKiBUaGUgaWQgb2YgdGhlIGlucHV0IGl0ZW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBgTGFiZWxgLiBUaGlzIHZhbHVlIGlzIGFsc28gdXNlZCB0byBhc3NvY2lhdGUgdGhlIGBMYWJlbGAgd2l0aFxuXHQgKiBpdHMgaW5wdXQgY291bnRlcnBhcnQgdGhyb3VnaCB0aGUgJ2ZvcicgYXR0cmlidXRlLlxuXHQgKi9cblx0QElucHV0KCkgbGFiZWxJbnB1dElEID0gYGNkcy1sYWJlbC0ke0xhYmVsLmxhYmVsQ291bnRlcisrfWA7XG5cdC8qKlxuXHQgKiBTZXQgdG8gYHRydWVgIGZvciBkaXNhYmxlZCBzdGF0ZS5cblx0ICovXG5cdEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG5cdC8qKlxuXHQgKiBTZXQgdG8gYHRydWVgIGZvciBhIGxvYWRpbmcgbGFiZWwuXG5cdCAqL1xuXHRASW5wdXQoKSBza2VsZXRvbiA9IGZhbHNlO1xuXHQvKipcblx0ICogT3B0aW9uYWwgaGVscGVyIHRleHQgdGhhdCBhcHBlYXJzIHVuZGVyIHRoZSBsYWJlbC5cblx0ICovXG5cdEBJbnB1dCgpIGhlbHBlclRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBpbnZhbGlkIHRleHQuXG5cdCAqL1xuXHRASW5wdXQoKSBpbnZhbGlkVGV4dDogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pjtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgZm9yIGFuIGludmFsaWQgbGFiZWwgY29tcG9uZW50LlxuXHQgKi9cblx0QElucHV0KCkgaW52YWxpZCA9IGZhbHNlO1xuXHQvKipcblx0ICogU2V0IHRvIGB0cnVlYCB0byBzaG93IGEgd2FybmluZyAoY29udGVudHMgc2V0IGJ5IHdhcm5pbmdUZXh0KVxuXHQgKi9cblx0QElucHV0KCkgd2FybiA9IGZhbHNlO1xuXHQvKipcblx0ICogU2V0cyB0aGUgd2FybmluZyB0ZXh0XG5cdCAqL1xuXHRASW5wdXQoKSB3YXJuVGV4dDogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pjtcblx0LyoqXG5cdCAqIFNldCB0aGUgYXJpYWxhYmVsIGZvciBsYWJlbFxuXHQgKi9cblx0QElucHV0KCkgYXJpYUxhYmVsOiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgdG8gaGlkZSB0aGUgbGFiZWwgdmlzdWFsbHksIGJ1dCBrZWVwIGFjY2Vzc2libGUgdG9cblx0ICogc2NyZWVuIHJlYWRlcnMuXG5cdCAqL1xuXHRASW5wdXQoKSBoaWRlTGFiZWwgPSBmYWxzZTtcblxuXHQvKipcblx0ICogU2V0IHRvIGB0cnVlYCB0byByZW5kZXIgdGhlIGxhYmVsIGFuZCBmaWVsZCBzaWRlLWJ5LXNpZGUgaW5zdGVhZCBvZiBzdGFja2VkLlxuXHQgKiBBcHBsaWVzIHRvIGBUZXh0SW5wdXRgIGFuZCBgUGFzc3dvcmRJbnB1dGAgbGFiZWwgdmFyaWFudHMuXG5cdCAqL1xuXHRASW5wdXQoKSBpbmxpbmUgPSBmYWxzZTtcblxuXHQvKipcblx0ICogVGhlIHJlbmRlciBzaXplIGZvciB0aGUgYFRleHRJbnB1dGAuIFVzZWQgdG8gY29tcHV0ZSBJTkxJTkUgbGFiZWwgc2l6ZVxuXHQgKiB2YXJpYW50IGNsYXNzZXMuXG5cdCAqL1xuXHRASW5wdXQoKSBzaXplOiBcInNtXCIgfCBcIm1kXCIgfCBcImxnXCIgPSBcIm1kXCI7XG5cblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgKGBtYXhDb3VudGAgbXVzdCBiZSBzZXQpIHRvIGRpc3BsYXlzIGEgbGl2ZSBjaGFyYWN0ZXIvd29yZFxuXHQgKiBjb3VudGVyIGFsb25nc2lkZSB0aGUgbGFiZWwuXG5cdCAqL1xuXHRASW5wdXQoKSBlbmFibGVDb3VudGVyID0gZmFsc2U7XG5cblx0LyoqXG5cdCAqIE1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgKG9yIHdvcmRzKSBhbGxvd2VkLiBSZXF1aXJlZCBmb3IgdGhlXG5cdCAqIGNvdW50ZXIgdG8gZGlzcGxheS5cblx0ICovXG5cdEBJbnB1dCgpIG1heENvdW50OiBudW1iZXI7XG5cblx0LyoqXG5cdCAqIERldGVybWluZXMgd2hldGhlciB0aGUgYFRleHRBcmVhYCBjb3VudGVyIGNvdW50cyBjaGFyYWN0ZXJzIG9yIHdvcmRzLlxuXHQgKi9cblx0QElucHV0KCkgY291bnRlck1vZGU6IFwiY2hhcmFjdGVyXCIgfCBcIndvcmRcIiA9IFwiY2hhcmFjdGVyXCI7XG5cblx0QFZpZXdDaGlsZChcIndyYXBwZXJcIikgd3JhcHBlcjogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cblx0QENvbnRlbnRDaGlsZChUZXh0QXJlYSkgdGV4dEFyZWE6IFRleHRBcmVhO1xuXG5cdC8vIEB0cy1pZ25vcmVcblx0QENvbnRlbnRDaGlsZChUZXh0SW5wdXQsIHsgc3RhdGljOiBmYWxzZSB9KSB0ZXh0SW5wdXQ6IFRleHRJbnB1dDtcblxuXHRAQ29udGVudENoaWxkKFBhc3N3b3JkSW5wdXQsIHsgc3RhdGljOiBmYWxzZSB9KVxuXHRwYXNzd29yZElucHV0OiBQYXNzd29yZElucHV0O1xuXG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tZm9ybS1pdGVtXCIpIGdldCBsYWJlbENsYXNzKCkge1xuXHRcdHJldHVybiB0aGlzLnR5cGUgPT09IHVuZGVmaW5lZDtcblx0fVxuXG5cdHR5cGU6IFwiVGV4dEFyZWFcIiB8IFwiVGV4dElucHV0XCIgfCBcIlBhc3N3b3JkSW5wdXRcIjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBMYWJlbC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKHByb3RlY3RlZCBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZSB3cmFwcGVyIGNsYXNzIGlmIGEgdGV4dGFyZWEgaXMgaG9zdGVkLlxuXHQgKi9cblx0bmdBZnRlckNvbnRlbnRJbml0KCkge1xuXHRcdGlmICh0aGlzLnRleHRBcmVhKSB7XG5cdFx0XHR0aGlzLnR5cGUgPSBcIlRleHRBcmVhXCI7XG5cdFx0fSBlbHNlIGlmICh0aGlzLnRleHRJbnB1dCkge1xuXHRcdFx0dGhpcy50eXBlID0gXCJUZXh0SW5wdXRcIjtcblx0XHR9IGVsc2UgaWYgKHRoaXMucGFzc3dvcmRJbnB1dCkge1xuXHRcdFx0dGhpcy50eXBlID0gXCJQYXNzd29yZElucHV0XCI7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGlkIG9uIHRoZSBpbnB1dCBpdGVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgYExhYmVsYC5cblx0ICovXG5cdG5nQWZ0ZXJWaWV3SW5pdCgpIHtcblx0XHQvLyBXaWxsIG9ubHkgYmUgY2FsbGVkIHdoZW4gYGRlZmF1bHRgIHRlbXBsYXRlIGlzIGJlaW5nIHVzZWRcblx0XHRpZiAodGhpcy53cmFwcGVyKSB7XG5cdFx0XHQvLyBQcmlvcml0aXplIHNldHRpbmcgaWQgdG8gYGlucHV0YCAmIGB0ZXh0YXJlYWAgb3ZlciBkaXZcblx0XHRcdGNvbnN0IGlucHV0RWxlbWVudCA9IHRoaXMud3JhcHBlci5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJpbnB1dCx0ZXh0YXJlYVwiKTtcblx0XHRcdGlmIChpbnB1dEVsZW1lbnQpIHtcblx0XHRcdFx0Ly8gYXZvaWQgb3ZlcnJpZGluZyBpZHMgYWxyZWFkeSBzZXQgYnkgdGhlIHVzZXIgcmV1c2UgaXQgaW5zdGVhZFxuXHRcdFx0XHRpZiAoaW5wdXRFbGVtZW50LmlkKSB7XG5cdFx0XHRcdFx0dGhpcy5sYWJlbElucHV0SUQgPSBpbnB1dEVsZW1lbnQuaWQ7XG5cdFx0XHRcdFx0dGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aW5wdXRFbGVtZW50LnNldEF0dHJpYnV0ZShcImlkXCIsIHRoaXMubGFiZWxJbnB1dElEKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCBkaXZFbGVtZW50ID0gdGhpcy53cmFwcGVyLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihcImRpdlwiKTtcblx0XHRcdGlmIChkaXZFbGVtZW50KSB7XG5cdFx0XHRcdGlmIChkaXZFbGVtZW50LmlkKSB7XG5cdFx0XHRcdFx0dGhpcy5sYWJlbElucHV0SUQgPSBkaXZFbGVtZW50LmlkO1xuXHRcdFx0XHRcdHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGRpdkVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgdGhpcy5sYWJlbElucHV0SUQpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBpc1RlbXBsYXRlKHZhbHVlKSB7XG5cdFx0cmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgVGVtcGxhdGVSZWY7XG5cdH1cbn1cbiJdfQ==