carbon-components-angular
Version:
Next generation components
454 lines • 40 kB
JavaScript
import { ContentChildren, Component, EventEmitter, forwardRef, Input, Output, HostBinding, HostListener, TemplateRef } from "@angular/core";
import { NG_VALUE_ACCESSOR } from "@angular/forms";
import { Radio } from "./radio.component";
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "carbon-components-angular/icon";
/**
* Get started with importing the module:
*
* ```typescript
* import { RadioModule } from 'carbon-components-angular';
* ```
*
* Ex:
*
* ```html
* <cds-radio-group [(ngModel)]="radio">
* <cds-radio *ngFor="let one of manyRadios" [value]="one">
* Radio {{one}}
* </cds-radio>
* </cds-radio-group>
*
* Radio selected: {{radio}}
* ```
*
* ```ts
* const manyRadios = ["one", "two", "three", "four", "five", "six"];
* ```
*
* [See demo](../../?path=/story/components-radio--basic)
*/
export class RadioGroup {
constructor() {
this.orientation = "horizontal";
this.labelPlacement = "right";
/**
* Set to `true` to show the invalid state.
*/
this.invalid = false;
/**
* Set to `true` to show a warning (contents set by warnText)
*/
this.warn = false;
/**
* Emits event notifying other classes of a change using a `RadioChange` class.
*/
this.change = new EventEmitter();
/**
* Binds 'cds--form-item' value to the class for `RadioGroup`.
*/
this.radioButtonGroupClass = true;
/**
* To track whether the `RadioGroup` has been initialized.
*/
this.isInitialized = false;
/**
* Reflects whether or not the input is disabled and cannot be selected.
*/
this._disabled = false;
/**
* Reflects whether or not the dropdown is loading.
*/
this._skeleton = false;
/**
* The value of the selected option within the `RadioGroup`.
*/
this._value = null;
/**
* The `Radio` within the `RadioGroup` that is selected.
*/
this._selected = null;
/**
* The name attribute associated with the `RadioGroup`.
*/
this._name = `radio-group-${RadioGroup.radioGroupCount++}`;
/**
* Needed to properly implement ControlValueAccessor.
*/
this.onTouched = () => { };
/**
* Method set in registerOnChange to propagate changes back to the form.
*/
this.propagateChange = (_) => { };
}
/**
* Sets the passed in `Radio` item as the selected input within the `RadioGroup`.
*/
set selected(selected) {
const alreadySelected = (this._selected && this._selected.value) === (selected && selected.value);
if (alreadySelected) {
// no need to redo
return;
}
if (this._selected) {
this._selected.checked = false;
}
this._selected = selected;
this.value = selected ? selected.value : null;
this.checkSelectedRadio();
}
/**
* Returns the `Radio` that is selected within the `RadioGroup`.
*/
get selected() {
return this._selected;
}
/**
* Sets the value/state of the selected `Radio` within the `RadioGroup` to the passed in value.
*/
set value(newValue) {
if (this._value !== newValue) {
this._value = newValue;
this.updateSelectedRadioFromValue();
this.checkSelectedRadio();
}
}
/**
* Returns the value/state of the selected `Radio` within the `RadioGroup`.
*/
get value() {
return this._value;
}
/**
* Replaces the name associated with the `RadioGroup` with the provided parameter.
*/
set name(name) {
this._name = name;
this.updateRadios();
}
/**
* Returns the associated name of the `RadioGroup`.
*/
get name() {
return this._name;
}
/**
* Set to true to disable the whole radio group
*/
set disabled(disabled) {
this._disabled = disabled;
this.updateRadios();
}
/**
* Returns the disabled value for the `RadioGroup`.
*/
get disabled() {
return this._disabled;
}
/**
* Returns the skeleton value in the `RadioGroup` if there is one.
*/
get skeleton() {
return this._skeleton;
}
/**
* Sets the skeleton value for all `Radio` to the skeleton value of `RadioGroup`.
*/
set skeleton(value) {
this._skeleton = value;
this.updateChildren();
}
/**
* Updates the selected `Radio` to be checked (selected).
*/
checkSelectedRadio() {
if (this.selected && !this._selected.checked) {
this.selected.checked = true;
}
}
/**
* Use the value of the `RadioGroup` to update the selected radio to the right state (selected state).
*/
updateSelectedRadioFromValue() {
let alreadySelected = this._selected != null && this._selected.value === this._value;
if (this.radios && !alreadySelected) {
if (this.selected && this.value) {
this.selected.checked = false;
}
this._selected = null;
this.radios.forEach(radio => {
if (radio.checked || radio.value === this._value) {
this._selected = radio;
}
});
if (this.selected && !this.value) {
this._value = this.selected.value;
}
}
}
/**
* `ControlValueAccessor` method to programmatically disable the `RadioGroup`.
*
* ex: `this.formGroup.get("myRadioGroup").disable();`
*
* @param isDisabled `true` to disable the inputs
*/
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
/**
* Creates a class of `RadioChange` to emit the change in the `RadioGroup`.
*/
emitChangeEvent(event) {
this.change.emit(event);
this.propagateChange(event.value);
this.onTouched();
}
/**
* Synchronizes radio properties.
*/
updateRadios() {
if (this.radios) {
setTimeout(() => {
this.radios.forEach(radio => {
radio.name = this.name;
radio.setDisabledFromGroup(this.disabled);
if (this.labelPlacement === "left") {
radio.labelPlacement = "left";
}
});
});
}
}
/**
* Updates the value of the `RadioGroup` using the provided parameter.
*/
writeValue(value) {
this.value = value;
setTimeout(() => {
this.updateSelectedRadioFromValue();
this.checkSelectedRadio();
});
}
ngAfterContentInit() {
this.radios.changes.subscribe(() => {
this.updateRadios();
this.updateRadioChangeHandler();
});
this.updateChildren();
this.updateRadioChangeHandler();
}
ngAfterViewInit() {
this.updateRadios();
}
/**
* Used to set method to propagate changes back to the form.
*/
registerOnChange(fn) {
this.propagateChange = fn;
}
/**
* Registers a callback to be triggered when the control has been touched.
* @param fn Callback to be triggered when the checkbox is touched.
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
focusOut() {
this.onTouched();
}
isTemplate(value) {
return value instanceof TemplateRef;
}
updateChildren() {
if (this.radios) {
this.radios.forEach(child => child.skeleton = this.skeleton);
}
}
updateRadioChangeHandler() {
this.radios.forEach(radio => {
radio.registerRadioChangeHandler((event) => {
if ((this.selected && this.selected.value) === event.value) {
// no need to redo
return;
}
// deselect previous radio
if (this.selected) {
this.selected.checked = false;
}
// update selected and value from the event
this._selected = event.source;
this._value = event.value;
// bubble the event
this.emitChangeEvent(event);
});
});
}
}
/**
* Used for creating the `RadioGroup` 'name' property dynamically.
*/
RadioGroup.radioGroupCount = 0;
RadioGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: RadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
RadioGroup.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: RadioGroup, selector: "cds-radio-group, ibm-radio-group", inputs: { selected: "selected", value: "value", name: "name", disabled: "disabled", skeleton: "skeleton", orientation: "orientation", labelPlacement: "labelPlacement", legend: "legend", ariaLabel: "ariaLabel", ariaLabelledby: "ariaLabelledby", helperText: "helperText", invalid: "invalid", invalidText: "invalidText", warn: "warn", warnText: "warnText" }, outputs: { change: "change" }, host: { listeners: { "focusout": "focusOut()" }, properties: { "class.cds--form-item": "this.radioButtonGroupClass" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: RadioGroup,
multi: true
}
], queries: [{ propertyName: "radios", predicate: i0.forwardRef(function () { return Radio; }) }], ngImport: i0, template: `
<fieldset
class="cds--radio-button-group"
[attr.aria-label]="ariaLabel"
[attr.aria-labelledby]="ariaLabelledby"
[ngClass]="{
'cds--radio-button-group--vertical': orientation === 'vertical',
'cds--radio-button-group--label-left': labelPlacement === 'left',
'cds--radio-button-group--invalid': invalid,
'cds--radio-button-group--warning': !invalid && warn
}"
[attr.data-invalid]="invalid ? true : null">
<legend *ngIf="legend" class="cds--label">
<ng-template *ngIf="isTemplate(legend); else legendLabel;" [ngTemplateOutlet]="legend"></ng-template>
<ng-template #legendLabel>{{legend}}</ng-template>
</legend>
<ng-content></ng-content>
</fieldset>
<div class="cds--radio-button__validation-msg">
<ng-container *ngIf="invalid">
<svg
cdsIcon="warning--filled"
size="16"
class="cds--radio-button__invalid-icon">
</svg>
<div class="cds--form-requirement">
<ng-container *ngIf="!isTemplate(invalidText)">{{ invalidText }}</ng-container>
<ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template>
</div>
</ng-container>
<ng-container *ngIf="!invalid && warn">
<svg
cdsIcon="warning--alt--filled"
class="cds--radio-button__invalid-icon cds--radio-button__invalid-icon--warning"
size="16">
</svg>
<div class="cds--form-requirement">
<ng-container *ngIf="!isTemplate(warnText)">{{warnText}}</ng-container>
<ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template>
</div>
</ng-container>
</div>
<div
*ngIf="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>
`, 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: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: RadioGroup, decorators: [{
type: Component,
args: [{
selector: "cds-radio-group, ibm-radio-group",
template: `
<fieldset
class="cds--radio-button-group"
[attr.aria-label]="ariaLabel"
[attr.aria-labelledby]="ariaLabelledby"
[ngClass]="{
'cds--radio-button-group--vertical': orientation === 'vertical',
'cds--radio-button-group--label-left': labelPlacement === 'left',
'cds--radio-button-group--invalid': invalid,
'cds--radio-button-group--warning': !invalid && warn
}"
[attr.data-invalid]="invalid ? true : null">
<legend *ngIf="legend" class="cds--label">
<ng-template *ngIf="isTemplate(legend); else legendLabel;" [ngTemplateOutlet]="legend"></ng-template>
<ng-template #legendLabel>{{legend}}</ng-template>
</legend>
<ng-content></ng-content>
</fieldset>
<div class="cds--radio-button__validation-msg">
<ng-container *ngIf="invalid">
<svg
cdsIcon="warning--filled"
size="16"
class="cds--radio-button__invalid-icon">
</svg>
<div class="cds--form-requirement">
<ng-container *ngIf="!isTemplate(invalidText)">{{ invalidText }}</ng-container>
<ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template>
</div>
</ng-container>
<ng-container *ngIf="!invalid && warn">
<svg
cdsIcon="warning--alt--filled"
class="cds--radio-button__invalid-icon cds--radio-button__invalid-icon--warning"
size="16">
</svg>
<div class="cds--form-requirement">
<ng-container *ngIf="!isTemplate(warnText)">{{warnText}}</ng-container>
<ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template>
</div>
</ng-container>
</div>
<div
*ngIf="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>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: RadioGroup,
multi: true
}
]
}]
}], propDecorators: { selected: [{
type: Input
}], value: [{
type: Input
}], name: [{
type: Input
}], disabled: [{
type: Input
}], skeleton: [{
type: Input
}], orientation: [{
type: Input
}], labelPlacement: [{
type: Input
}], legend: [{
type: Input
}], ariaLabel: [{
type: Input
}], ariaLabelledby: [{
type: Input
}], helperText: [{
type: Input
}], invalid: [{
type: Input
}], invalidText: [{
type: Input
}], warn: [{
type: Input
}], warnText: [{
type: Input
}], change: [{
type: Output
}], radios: [{
type: ContentChildren,
args: [forwardRef(() => Radio)]
}], radioButtonGroupClass: [{
type: HostBinding,
args: ["class.cds--form-item"]
}], focusOut: [{
type: HostListener,
args: ["focusout"]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFkaW8tZ3JvdXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3JhZGlvL3JhZGlvLWdyb3VwLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRU4sZUFBZSxFQUNmLFNBQVMsRUFDVCxZQUFZLEVBQ1osVUFBVSxFQUNWLEtBQUssRUFDTCxNQUFNLEVBRU4sV0FBVyxFQUVYLFlBQVksRUFDWixXQUFXLEVBQ1gsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGlCQUFpQixFQUF3QixNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7OztBQUcxQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBNkRILE1BQU0sT0FBTyxVQUFVO0lBNUR2QjtRQThKVSxnQkFBVyxHQUE4QixZQUFZLENBQUM7UUFFdEQsbUJBQWMsR0FBc0IsT0FBTyxDQUFDO1FBbUJyRDs7V0FFRztRQUNNLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFPekI7O1VBRUU7UUFDTyxTQUFJLEdBQUcsS0FBSyxDQUFDO1FBT3RCOztXQUVHO1FBQ08sV0FBTSxHQUE4QixJQUFJLFlBQVksRUFBZSxDQUFDO1FBUTlFOztXQUVHO1FBQ2tDLDBCQUFxQixHQUFHLElBQUksQ0FBQztRQUVsRTs7V0FFRztRQUNPLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBQ2hDOztXQUVHO1FBQ08sY0FBUyxHQUFHLEtBQUssQ0FBQztRQUM1Qjs7V0FFRztRQUNPLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFDNUI7O1dBRUc7UUFDTyxXQUFNLEdBQVEsSUFBSSxDQUFDO1FBQzdCOztXQUVHO1FBQ08sY0FBUyxHQUFVLElBQUksQ0FBQztRQUNsQzs7V0FFRztRQUNPLFVBQUssR0FBRyxlQUFlLFVBQVUsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDO1FBa0hoRTs7V0FFRztR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Ozs7Ozs7Ozs7Ozs7Ozs7O0VBaURUOzJGQVNXLFVBQVU7a0JBNUR0QixTQUFTO21CQUFDO29CQUNWLFFBQVEsRUFBRSxrQ0FBa0M7b0JBQzVDLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQWlEVDtvQkFDRCxTQUFTLEVBQUU7d0JBQ1Y7NEJBQ0MsT0FBTyxFQUFFLGlCQUFpQjs0QkFDMUIsV0FBVyxZQUFZOzRCQUN2QixLQUFLLEVBQUUsSUFBSTt5QkFDWDtxQkFDRDtpQkFDRDs4QkFPSSxRQUFRO3NCQURYLEtBQUs7Z0JBMkJGLEtBQUs7c0JBRFIsS0FBSztnQkFxQkYsSUFBSTtzQkFEUCxLQUFLO2dCQWdCRixRQUFRO3NCQURYLEtBQUs7Z0JBZ0JGLFFBQVE7c0JBRFgsS0FBSztnQkFpQkcsV0FBVztzQkFBbkIsS0FBSztnQkFFRyxjQUFjO3NCQUF0QixLQUFLO2dCQUVHLE1BQU07c0JBQWQsS0FBSztnQkFLRyxTQUFTO3NCQUFqQixLQUFLO2dCQUtHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBS0csVUFBVTtzQkFBbEIsS0FBSztnQkFLRyxPQUFPO3NCQUFmLEtBQUs7Z0JBS0csV0FBVztzQkFBbkIsS0FBSztnQkFLRyxJQUFJO3NCQUFaLEtBQUs7Z0JBS0csUUFBUTtzQkFBaEIsS0FBSztnQkFLSSxNQUFNO3NCQUFmLE1BQU07Z0JBTW1DLE1BQU07c0JBQS9DLGVBQWU7dUJBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQztnQkFLSCxxQkFBcUI7c0JBQXpELFdBQVc7dUJBQUMsc0JBQXNCO2dCQXVJbkMsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuXHRBZnRlckNvbnRlbnRJbml0LFxuXHRDb250ZW50Q2hpbGRyZW4sXG5cdENvbXBvbmVudCxcblx0RXZlbnRFbWl0dGVyLFxuXHRmb3J3YXJkUmVmLFxuXHRJbnB1dCxcblx0T3V0cHV0LFxuXHRRdWVyeUxpc3QsXG5cdEhvc3RCaW5kaW5nLFxuXHRBZnRlclZpZXdJbml0LFxuXHRIb3N0TGlzdGVuZXIsXG5cdFRlbXBsYXRlUmVmXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBOR19WQUxVRV9BQ0NFU1NPUiwgQ29udHJvbFZhbHVlQWNjZXNzb3IgfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcbmltcG9ydCB7IFJhZGlvIH0gZnJvbSBcIi4vcmFkaW8uY29tcG9uZW50XCI7XG5pbXBvcnQgeyBSYWRpb0NoYW5nZSB9IGZyb20gXCIuL3JhZGlvLWNoYW5nZS5jbGFzc1wiO1xuXG4vKipcbiAqIEdldCBzdGFydGVkIHdpdGggaW1wb3J0aW5nIHRoZSBtb2R1bGU6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgUmFkaW9Nb2R1bGUgfSBmcm9tICdjYXJib24tY29tcG9uZW50cy1hbmd1bGFyJztcbiAqIGBgYFxuICpcbiAqIEV4OlxuICpcbiAqIGBgYGh0bWxcbiAqIDxjZHMtcmFkaW8tZ3JvdXAgWyhuZ01vZGVsKV09XCJyYWRpb1wiPlxuICogXHQ8Y2RzLXJhZGlvICpuZ0Zvcj1cImxldCBvbmUgb2YgbWFueVJhZGlvc1wiIFt2YWx1ZV09XCJvbmVcIj5cbiAqXHRcdFJhZGlvIHt7b25lfX1cbiAqIFx0PC9jZHMtcmFkaW8+XG4gKiA8L2Nkcy1yYWRpby1ncm91cD5cbiAqXG4gKiBSYWRpbyBzZWxlY3RlZDoge3tyYWRpb319XG4gKiBgYGBcbiAqXG4gKiBgYGB0c1xuICpcdGNvbnN0IG1hbnlSYWRpb3MgPSBbXCJvbmVcIiwgXCJ0d29cIiwgXCJ0aHJlZVwiLCBcImZvdXJcIiwgXCJmaXZlXCIsIFwic2l4XCJdO1xuICogYGBgXG4gKlxuICogW1NlZSBkZW1vXSguLi8uLi8/cGF0aD0vc3RvcnkvY29tcG9uZW50cy1yYWRpby0tYmFzaWMpXG4gKi9cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogXCJjZHMtcmFkaW8tZ3JvdXAsIGlibS1yYWRpby1ncm91cFwiLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdDxmaWVsZHNldFxuXHRcdFx0Y2xhc3M9XCJjZHMtLXJhZGlvLWJ1dHRvbi1ncm91cFwiXG5cdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbFwiXG5cdFx0XHRbYXR0ci5hcmlhLWxhYmVsbGVkYnldPVwiYXJpYUxhYmVsbGVkYnlcIlxuXHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHQnY2RzLS1yYWRpby1idXR0b24tZ3JvdXAtLXZlcnRpY2FsJzogb3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCcsXG5cdFx0XHRcdCdjZHMtLXJhZGlvLWJ1dHRvbi1ncm91cC0tbGFiZWwtbGVmdCc6IGxhYmVsUGxhY2VtZW50ID09PSAnbGVmdCcsXG5cdFx0XHRcdCdjZHMtLXJhZGlvLWJ1dHRvbi1ncm91cC0taW52YWxpZCc6IGludmFsaWQsXG5cdFx0XHRcdCdjZHMtLXJhZGlvLWJ1dHRvbi1ncm91cC0td2FybmluZyc6ICFpbnZhbGlkICYmIHdhcm5cblx0XHRcdH1cIlxuXHRcdFx0W2F0dHIuZGF0YS1pbnZhbGlkXT1cImludmFsaWQgPyB0cnVlIDogbnVsbFwiPlxuXHRcdFx0PGxlZ2VuZCAqbmdJZj1cImxlZ2VuZFwiIGNsYXNzPVwiY2RzLS1sYWJlbFwiPlxuXHRcdFx0XHQ8bmctdGVtcGxhdGUgKm5nSWY9XCJpc1RlbXBsYXRlKGxlZ2VuZCk7IGVsc2UgbGVnZW5kTGFiZWw7XCIgW25nVGVtcGxhdGVPdXRsZXRdPVwibGVnZW5kXCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdFx0PG5nLXRlbXBsYXRlICNsZWdlbmRMYWJlbD57e2xlZ2VuZH19PC9uZy10ZW1wbGF0ZT5cblx0XHRcdDwvbGVnZW5kPlxuXHRcdFx0PG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuXHRcdDwvZmllbGRzZXQ+XG5cdFx0PGRpdiBjbGFzcz1cImNkcy0tcmFkaW8tYnV0dG9uX192YWxpZGF0aW9uLW1zZ1wiPlxuXHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cImludmFsaWRcIj5cblx0XHRcdFx0PHN2Z1xuXHRcdFx0XHRcdGNkc0ljb249XCJ3YXJuaW5nLS1maWxsZWRcIlxuXHRcdFx0XHRcdHNpemU9XCIxNlwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLXJhZGlvLWJ1dHRvbl9faW52YWxpZC1pY29uXCI+XG5cdFx0XHRcdDwvc3ZnPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwiY2RzLS1mb3JtLXJlcXVpcmVtZW50XCI+XG5cdFx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKGludmFsaWRUZXh0KVwiPnt7IGludmFsaWRUZXh0IH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdFx0PG5nLXRlbXBsYXRlICpuZ0lmPVwiaXNUZW1wbGF0ZShpbnZhbGlkVGV4dClcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJpbnZhbGlkVGV4dFwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9uZy1jb250YWluZXI+XG5cdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWludmFsaWQgJiYgd2FyblwiPlxuXHRcdFx0XHQ8c3ZnXG5cdFx0XHRcdFx0Y2RzSWNvbj1cIndhcm5pbmctLWFsdC0tZmlsbGVkXCJcblx0XHRcdFx0XHRjbGFzcz1cImNkcy0tcmFkaW8tYnV0dG9uX19pbnZhbGlkLWljb24gY2RzLS1yYWRpby1idXR0b25fX2ludmFsaWQtaWNvbi0td2FybmluZ1wiXG5cdFx0XHRcdFx0c2l6ZT1cIjE2XCI+XG5cdFx0XHRcdDwvc3ZnPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwiY2RzLS1mb3JtLXJlcXVpcmVtZW50XCI+XG5cdFx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKHdhcm5UZXh0KVwiPnt7d2FyblRleHR9fTwvbmctY29udGFpbmVyPlxuXHRcdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUod2FyblRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwid2FyblRleHRcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdDwvZGl2PlxuXHRcdDxkaXZcblx0XHRcdCpuZ0lmPVwiaGVscGVyVGV4dCAmJiAhaW52YWxpZCAmJiAhd2FyblwiXG5cdFx0XHRjbGFzcz1cImNkcy0tZm9ybV9faGVscGVyLXRleHRcIlxuXHRcdFx0W25nQ2xhc3NdPVwieydjZHMtLWZvcm1fX2hlbHBlci10ZXh0LS1kaXNhYmxlZCc6IGRpc2FibGVkfVwiPlxuXHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKGhlbHBlclRleHQpXCI+e3toZWxwZXJUZXh0fX08L25nLWNvbnRhaW5lcj5cblx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaGVscGVyVGV4dClcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJoZWxwZXJUZXh0XCI+PC9uZy10ZW1wbGF0ZT5cblx0XHQ8L2Rpdj5cblx0YCxcblx0cHJvdmlkZXJzOiBbXG5cdFx0e1xuXHRcdFx0cHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG5cdFx0XHR1c2VFeGlzdGluZzogUmFkaW9Hcm91cCxcblx0XHRcdG11bHRpOiB0cnVlXG5cdFx0fVxuXHRdXG59KVxuZXhwb3J0IGNsYXNzIFJhZGlvR3JvdXAgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBBZnRlclZpZXdJbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHBhc3NlZCBpbiBgUmFkaW9gIGl0ZW0gYXMgdGhlIHNlbGVjdGVkIGlucHV0IHdpdGhpbiB0aGUgYFJhZGlvR3JvdXBgLlxuXHQgKi9cblx0QElucHV0KClcblx0c2V0IHNlbGVjdGVkKHNlbGVjdGVkOiBSYWRpbyB8IG51bGwpIHtcblx0XHRjb25zdCBhbHJlYWR5U2VsZWN0ZWQgPSAodGhpcy5fc2VsZWN0ZWQgJiYgdGhpcy5fc2VsZWN0ZWQudmFsdWUpID09PSAoc2VsZWN0ZWQgJiYgc2VsZWN0ZWQudmFsdWUpO1xuXHRcdGlmIChhbHJlYWR5U2VsZWN0ZWQpIHtcblx0XHRcdC8vIG5vIG5lZWQgdG8gcmVkb1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9zZWxlY3RlZCkge1xuXHRcdFx0dGhpcy5fc2VsZWN0ZWQuY2hlY2tlZCA9IGZhbHNlO1xuXHRcdH1cblx0XHR0aGlzLl9zZWxlY3RlZCA9IHNlbGVjdGVkO1xuXHRcdHRoaXMudmFsdWUgPSBzZWxlY3RlZCA/IHNlbGVjdGVkLnZhbHVlIDogbnVsbDtcblx0XHR0aGlzLmNoZWNrU2VsZWN0ZWRSYWRpbygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGBSYWRpb2AgdGhhdCBpcyBzZWxlY3RlZCB3aXRoaW4gdGhlIGBSYWRpb0dyb3VwYC5cblx0ICovXG5cdGdldCBzZWxlY3RlZCgpIHtcblx0XHRyZXR1cm4gdGhpcy5fc2VsZWN0ZWQ7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgdmFsdWUvc3RhdGUgb2YgdGhlIHNlbGVjdGVkIGBSYWRpb2Agd2l0aGluIHRoZSBgUmFkaW9Hcm91cGAgdG8gdGhlIHBhc3NlZCBpbiB2YWx1ZS5cblx0ICovXG5cdEBJbnB1dCgpXG5cdHNldCB2YWx1ZShuZXdWYWx1ZTogYW55KSB7XG5cdFx0aWYgKHRoaXMuX3ZhbHVlICE9PSBuZXdWYWx1ZSkge1xuXHRcdFx0dGhpcy5fdmFsdWUgPSBuZXdWYWx1ZTtcblxuXHRcdFx0dGhpcy51cGRhdGVTZWxlY3RlZFJhZGlvRnJvbVZhbHVlKCk7XG5cdFx0XHR0aGlzLmNoZWNrU2VsZWN0ZWRSYWRpbygpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSB2YWx1ZS9zdGF0ZSBvZiB0aGUgc2VsZWN0ZWQgYFJhZGlvYCB3aXRoaW4gdGhlIGBSYWRpb0dyb3VwYC5cblx0ICovXG5cdGdldCB2YWx1ZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5fdmFsdWU7XG5cdH1cblxuXHQvKipcblx0ICogUmVwbGFjZXMgdGhlIG5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBgUmFkaW9Hcm91cGAgd2l0aCB0aGUgcHJvdmlkZWQgcGFyYW1ldGVyLlxuXHQgKi9cblx0QElucHV0KClcblx0c2V0IG5hbWUobmFtZTogc3RyaW5nKSB7XG5cdFx0dGhpcy5fbmFtZSA9IG5hbWU7XG5cdFx0dGhpcy51cGRhdGVSYWRpb3MoKTtcblx0fVxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgYXNzb2NpYXRlZCBuYW1lIG9mIHRoZSBgUmFkaW9Hcm91cGAuXG5cdCAqL1xuXHRnZXQgbmFtZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5fbmFtZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXQgdG8gdHJ1ZSB0byBkaXNhYmxlIHRoZSB3aG9sZSByYWRpbyBncm91cFxuXHQgKi9cblx0QElucHV0KClcblx0c2V0IGRpc2FibGVkKGRpc2FibGVkOiBib29sZWFuKSB7XG5cdFx0dGhpcy5fZGlzYWJsZWQgPSBkaXNhYmxlZDtcblx0XHR0aGlzLnVwZGF0ZVJhZGlvcygpO1xuXHR9XG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBkaXNhYmxlZCB2YWx1ZSBmb3IgdGhlIGBSYWRpb0dyb3VwYC5cblx0ICovXG5cdGdldCBkaXNhYmxlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5fZGlzYWJsZWQ7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgc2tlbGV0b24gdmFsdWUgaW4gdGhlIGBSYWRpb0dyb3VwYCBpZiB0aGVyZSBpcyBvbmUuXG5cdCAqL1xuXHRASW5wdXQoKVxuXHRnZXQgc2tlbGV0b24oKTogYW55IHtcblx0XHRyZXR1cm4gdGhpcy5fc2tlbGV0b247XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgc2tlbGV0b24gdmFsdWUgZm9yIGFsbCBgUmFkaW9gIHRvIHRoZSBza2VsZXRvbiB2YWx1ZSBvZiBgUmFkaW9Hcm91cGAuXG5cdCAqL1xuXHRzZXQgc2tlbGV0b24odmFsdWU6IGFueSkge1xuXHRcdHRoaXMuX3NrZWxldG9uID0gdmFsdWU7XG5cdFx0dGhpcy51cGRhdGVDaGlsZHJlbigpO1xuXHR9XG5cdC8qKlxuXHQgKiBVc2VkIGZvciBjcmVhdGluZyB0aGUgYFJhZGlvR3JvdXBgICduYW1lJyBwcm9wZXJ0eSBkeW5hbWljYWxseS5cblx0ICovXG5cdHN0YXRpYyByYWRpb0dyb3VwQ291bnQgPSAwO1xuXG5cdEBJbnB1dCgpIG9yaWVudGF0aW9uOiBcImhvcml6b250YWxcIiB8IFwidmVydGljYWxcIiA9IFwiaG9yaXpvbnRhbFwiO1xuXG5cdEBJbnB1dCgpIGxhYmVsUGxhY2VtZW50OiBcInJpZ2h0XCIgfCBcImxlZnRcIiA9ICBcInJpZ2h0XCI7XG5cblx0QElucHV0KCkgbGVnZW5kOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuXG5cdC8qKlxuXHQgKiBVc2VkIHRvIHNldCB0aGUgYGFyaWEtbGFiZWxgIGF0dHJpYnV0ZSBvbiB0aGUgcmFkaW8gZ3JvdXAgZWxlbWVudC5cblx0ICovXG5cdEBJbnB1dCgpIGFyaWFMYWJlbDogc3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBVc2VkIHRvIHNldCB0aGUgYGFyaWEtbGFiZWxsZWRieWAgYXR0cmlidXRlIG9uIHRoZSByYWRpbyBncm91cCBlbGVtZW50LlxuXHQgKi9cblx0QElucHV0KCkgYXJpYUxhYmVsbGVkYnk6IHN0cmluZztcblxuXHQvKipcblx0ICogU2V0cyB0aGUgb3B0aW9uYWwgaGVscGVyIHRleHQuXG5cdCAqL1xuXHRASW5wdXQoKSBoZWxwZXJUZXh0OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuXG5cdC8qKlxuXHQgKiBTZXQgdG8gYHRydWVgIHRvIHNob3cgdGhlIGludmFsaWQgc3RhdGUuXG5cdCAqL1xuXHRASW5wdXQoKSBpbnZhbGlkID0gZmFsc2U7XG5cblx0LyoqXG5cdCAqIFZhbHVlIGRpc3BsYXllZCBpZiBjb21ib2JveCBpcyBpbiBhbiBpbnZhbGlkIHN0YXRlLlxuXHQgKi9cblx0QElucHV0KCkgaW52YWxpZFRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cblx0LyoqXG5cdCogU2V0IHRvIGB0cnVlYCB0byBzaG93IGEgd2FybmluZyAoY29udGVudHMgc2V0IGJ5IHdhcm5UZXh0KVxuXHQqL1xuXHRASW5wdXQoKSB3YXJuID0gZmFsc2U7XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHdhcm5pbmcgdGV4dFxuXHQgKi9cblx0QElucHV0KCkgd2FyblRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cblx0LyoqXG5cdCAqIEVtaXRzIGV2ZW50IG5vdGlmeWluZyBvdGhlciBjbGFzc2VzIG9mIGEgY2hhbmdlIHVzaW5nIGEgYFJhZGlvQ2hhbmdlYCBjbGFzcy5cblx0ICovXG5cdEBPdXRwdXQoKSBjaGFuZ2U6IEV2ZW50RW1pdHRlcjxSYWRpb0NoYW5nZT4gPSBuZXcgRXZlbnRFbWl0dGVyPFJhZGlvQ2hhbmdlPigpO1xuXG5cdC8qKlxuXHQgKiBUaGUgYFJhZGlvYCBpbnB1dCBpdGVtcyBpbiB0aGUgYFJhZGlvR3JvdXBgLlxuXHQgKi9cblx0Ly8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWZvcndhcmQtcmVmXG5cdEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBSYWRpbykpIHJhZGlvczogUXVlcnlMaXN0PFJhZGlvPjtcblxuXHQvKipcblx0ICogQmluZHMgJ2Nkcy0tZm9ybS1pdGVtJyB2YWx1ZSB0byB0aGUgY2xhc3MgZm9yIGBSYWRpb0dyb3VwYC5cblx0ICovXG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tZm9ybS1pdGVtXCIpIHJhZGlvQnV0dG9uR3JvdXBDbGFzcyA9IHRydWU7XG5cblx0LyoqXG5cdCAqIFRvIHRyYWNrIHdoZXRoZXIgdGhlIGBSYWRpb0dyb3VwYCBoYXMgYmVlbiBpbml0aWFsaXplZC5cblx0ICovXG5cdHByb3RlY3RlZCBpc0luaXRpYWxpemVkID0gZmFsc2U7XG5cdC8qKlxuXHQgKiBSZWZsZWN0cyB3aGV0aGVyIG9yIG5vdCB0aGUgaW5wdXQgaXMgZGlzYWJsZWQgYW5kIGNhbm5vdCBiZSBzZWxlY3RlZC5cblx0ICovXG5cdHByb3RlY3RlZCBfZGlzYWJsZWQgPSBmYWxzZTtcblx0LyoqXG5cdCAqIFJlZmxlY3RzIHdoZXRoZXIgb3Igbm90IHRoZSBkcm9wZG93biBpcyBsb2FkaW5nLlxuXHQgKi9cblx0cHJvdGVjdGVkIF9za2VsZXRvbiA9IGZhbHNlO1xuXHQvKipcblx0ICogVGhlIHZhbHVlIG9mIHRoZSBzZWxlY3RlZCBvcHRpb24gd2l0aGluIHRoZSBgUmFkaW9Hcm91cGAuXG5cdCAqL1xuXHRwcm90ZWN0ZWQgX3ZhbHVlOiBhbnkgPSBudWxsO1xuXHQvKipcblx0ICogVGhlIGBSYWRpb2Agd2l0aGluIHRoZSBgUmFkaW9Hcm91cGAgdGhhdCBpcyBzZWxlY3RlZC5cblx0ICovXG5cdHByb3RlY3RlZCBfc2VsZWN0ZWQ6IFJhZGlvID0gbnVsbDtcblx0LyoqXG5cdCAqIFRoZSBuYW1lIGF0dHJpYnV0ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGBSYWRpb0dyb3VwYC5cblx0ICovXG5cdHByb3RlY3RlZCBfbmFtZSA9IGByYWRpby1ncm91cC0ke1JhZGlvR3JvdXAucmFkaW9Hcm91cENvdW50Kyt9YDtcblxuXHQvKipcblx0ICogVXBkYXRlcyB0aGUgc2VsZWN0ZWQgYFJhZGlvYCB0byBiZSBjaGVja2VkIChzZWxlY3RlZCkuXG5cdCAqL1xuXHRjaGVja1NlbGVjdGVkUmFkaW8oKSB7XG5cdFx0aWYgKHRoaXMuc2VsZWN0ZWQgJiYgIXRoaXMuX3NlbGVjdGVkLmNoZWNrZWQpIHtcblx0XHRcdHRoaXMuc2VsZWN0ZWQuY2hlY2tlZCA9IHRydWU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFVzZSB0aGUgdmFsdWUgb2YgdGhlIGBSYWRpb0dyb3VwYCB0byB1cGRhdGUgdGhlIHNlbGVjdGVkIHJhZGlvIHRvIHRoZSByaWdodCBzdGF0ZSAoc2VsZWN0ZWQgc3RhdGUpLlxuXHQgKi9cblx0dXBkYXRlU2VsZWN0ZWRSYWRpb0Zyb21WYWx1ZSgpIHtcblx0XHRsZXQgYWxyZWFkeVNlbGVjdGVkID0gdGhpcy5fc2VsZWN0ZWQgIT0gbnVsbCAmJiB0aGlzLl9zZWxlY3RlZC52YWx1ZSA9PT0gdGhpcy5fdmFsdWU7XG5cdFx0aWYgKHRoaXMucmFkaW9zICYmICFhbHJlYWR5U2VsZWN0ZWQpIHtcblx0XHRcdGlmICh0aGlzLnNlbGVjdGVkICYmIHRoaXMudmFsdWUpIHtcblx0XHRcdFx0dGhpcy5zZWxlY3RlZC5jaGVja2VkID0gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLl9zZWxlY3RlZCA9IG51bGw7XG5cdFx0XHR0aGlzLnJhZGlvcy5mb3JFYWNoKHJhZGlvID0+IHtcblx0XHRcdFx0aWYgKHJhZGlvLmNoZWNrZWQgfHwgcmFkaW8udmFsdWUgPT09IHRoaXMuX3ZhbHVlKSB7XG5cdFx0XHRcdFx0dGhpcy5fc2VsZWN0ZWQgPSByYWRpbztcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRpZiAodGhpcy5zZWxlY3RlZCAmJiAhdGhpcy52YWx1ZSkge1xuXHRcdFx0XHR0aGlzLl92YWx1ZSA9IHRoaXMuc2VsZWN0ZWQudmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIGBDb250cm9sVmFsdWVBY2Nlc3NvcmAgbWV0aG9kIHRvIHByb2dyYW1tYXRpY2FsbHkgZGlzYWJsZSB0aGUgYFJhZGlvR3JvdXBgLlxuXHQgKlxuXHQgKiBleDogYHRoaXMuZm9ybUdyb3VwLmdldChcIm15UmFkaW9Hcm91cFwiKS5kaXNhYmxlKCk7YFxuXHQgKlxuXHQgKiBAcGFyYW0gaXNEaXNhYmxlZCBgdHJ1ZWAgdG8gZGlzYWJsZSB0aGUgaW5wdXRzXG5cdCAqL1xuXHRzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pIHtcblx0XHR0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgY2xhc3Mgb2YgYFJhZGlvQ2hhbmdlYCB0byBlbWl0IHRoZSBjaGFuZ2UgaW4gdGhlIGBSYWRpb0dyb3VwYC5cblx0ICovXG5cdGVtaXRDaGFuZ2VFdmVudChldmVudDogUmFkaW9DaGFuZ2UpIHtcblx0XHR0aGlzLmNoYW5nZS5lbWl0KGV2ZW50KTtcblx0XHR0aGlzLnByb3BhZ2F0ZUNoYW5nZShldmVudC52YWx1ZSk7XG5cdFx0dGhpcy5vblRvdWNoZWQoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTeW5jaHJvbml6ZXMgcmFkaW8gcHJvcGVydGllcy5cblx0ICovXG5cdHVwZGF0ZVJhZGlvcygpIHtcblx0XHRpZiAodGhpcy5yYWRpb3MpIHtcblx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnJhZGlvcy5mb3JFYWNoKHJhZGlvID0+IHtcblx0XHRcdFx0XHRyYWRpby5uYW1lID0gdGhpcy5uYW1lO1xuXHRcdFx0XHRcdHJhZGlvLnNldERpc2FibGVkRnJvbUdyb3VwKHRoaXMuZGlzYWJsZWQpO1xuXHRcdFx0XHRcdGlmICh0aGlzLmxhYmVsUGxhY2VtZW50ID09PSBcImxlZnRcIikge1xuXHRcdFx0XHRcdFx0cmFkaW8ubGFiZWxQbGFjZW1lbnQgPSBcImxlZnRcIjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZXMgdGhlIHZhbHVlIG9mIHRoZSBgUmFkaW9Hcm91cGAgdXNpbmcgdGhlIHByb3ZpZGVkIHBhcmFtZXRlci5cblx0ICovXG5cdHdyaXRlVmFsdWUodmFsdWU6IGFueSkge1xuXHRcdHRoaXMudmFsdWUgPSB2YWx1ZTtcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMudXBkYXRlU2VsZWN0ZWRSYWRpb0Zyb21WYWx1ZSgpO1xuXHRcdFx0dGhpcy5jaGVja1NlbGVjdGVkUmFkaW8oKTtcblx0XHR9KTtcblx0fVxuXG5cdG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcblx0XHR0aGlzLnJhZGlvcy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHR0aGlzLnVwZGF0ZVJhZGlvcygpO1xuXHRcdFx0dGhpcy51cGRhdGVSYWRpb0NoYW5nZUhhbmRsZXIoKTtcblx0XHR9KTtcblxuXHRcdHRoaXMudXBkYXRlQ2hpbGRyZW4oKTtcblx0XHR0aGlzLnVwZGF0ZVJhZGlvQ2hhbmdlSGFuZGxlcigpO1xuXHR9XG5cblx0bmdBZnRlclZpZXdJbml0KCkge1xuXHRcdHRoaXMudXBkYXRlUmFkaW9zKCk7XG5cdH1cblxuXHQvKipcblx0ICogVXNlZCB0byBzZXQgbWV0aG9kIHRvIHByb3BhZ2F0ZSBjaGFuZ2VzIGJhY2sgdG8gdGhlIGZvcm0uXG5cdCAqL1xuXHRwdWJsaWMgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KSB7XG5cdFx0dGhpcy5wcm9wYWdhdGVDaGFuZ2UgPSBmbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZWdpc3RlcnMgYSBjYWxsYmFjayB0byBiZSB0cmlnZ2VyZWQgd2hlbiB0aGUgY29udHJvbCBoYXMgYmVlbiB0b3VjaGVkLlxuXHQgKiBAcGFyYW0gZm4gQ2FsbGJhY2sgdG8gYmUgdHJpZ2dlcmVkIHdoZW4gdGhlIGNoZWNrYm94IGlzIHRvdWNoZWQuXG5cdCAqL1xuXHRwdWJsaWMgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSkge1xuXHRcdHRoaXMub25Ub3VjaGVkID0gZm47XG5cdH1cblxuXHRASG9zdExpc3RlbmVyKFwiZm9jdXNvdXRcIilcblx0Zm9jdXNPdXQoKSB7XG5cdFx0dGhpcy5vblRvdWNoZWQoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBOZWVkZWQgdG8gcHJvcGVybHkgaW1wbGVtZW50IENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuXHQgKi9cblx0b25Ub3VjaGVkOiAoKSA9PiBhbnkgPSAoKSA9PiB7fTtcblxuXHQvKipcblx0ICogTWV0aG9kIHNldCBpbiByZWdpc3Rlck9uQ2hhbmdlIHRvIHByb3BhZ2F0ZSBjaGFuZ2VzIGJhY2sgdG8gdGhlIGZvcm0uXG5cdCAqL1xuXHRwcm9wYWdhdGVDaGFuZ2UgPSAoXzogYW55KSA9PiB7fTtcblxuXHRwdWJsaWMgaXNUZW1wbGF0ZSh2YWx1ZSkge1xuXHRcdHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFRlbXBsYXRlUmVmO1xuXHR9XG5cblx0cHJvdGVjdGVkIHVwZGF0ZUNoaWxkcmVuKCkge1xuXHRcdGlmICh0aGlzLnJhZGlvcykge1xuXHRcdFx0dGhpcy5yYWRpb3MuZm9yRWFjaChjaGlsZCA9PiBjaGlsZC5za2VsZXRvbiA9IHRoaXMuc2tlbGV0b24pO1xuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCB1cGRhdGVSYWRpb0NoYW5nZUhhbmRsZXIoKSB7XG5cdFx0dGhpcy5yYWRpb3MuZm9yRWFjaChyYWRpbyA9PiB7XG5cdFx0XHRyYWRpby5yZWdpc3RlclJhZGlvQ2hhbmdlSGFuZGxlcigoZXZlbnQ6IFJhZGlvQ2hhbmdlKSA9PiB7XG5cdFx0XHRcdGlmICgodGhpcy5zZWxlY3RlZCAmJiB0aGlzLnNlbGVjdGVkLnZhbHVlKSA9PT0gZXZlbnQudmFsdWUpIHtcblx0XHRcdFx0XHQvLyBubyBuZWVkIHRvIHJlZG9cblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly8gZGVzZWxlY3QgcHJldmlvdXMgcmFkaW9cblx0XHRcdFx0aWYgKHRoaXMuc2VsZWN0ZWQpIHtcblx0XHRcdFx0XHR0aGlzLnNlbGVjdGVkLmNoZWNrZWQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvLyB1cGRhdGUgc2VsZWN0ZWQgYW5kIHZhbHVlIGZyb20gdGhlIGV2ZW50XG5cdFx0XHRcdHRoaXMuX3NlbGVjdGVkID0gZXZlbnQuc291cmNlO1xuXHRcdFx0XHR0aGlzLl92YWx1ZSA9IGV2ZW50LnZhbHVlO1xuXHRcdFx0XHQvLyBidWJibGUgdGhlIGV2ZW50XG5cdFx0XHRcdHRoaXMuZW1pdENoYW5nZUV2ZW50KGV2ZW50KTtcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG59XG4iXX0=