UNPKG

com.phloxui

Version:

PhloxUI Ng2+ Framework

617 lines (615 loc) 51.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import * as tslib_1 from "tslib"; import { Component, ElementRef, Input, Output, EventEmitter } from '@angular/core'; import { Option } from '../../../../../decorator/Option.decorator'; import { SimpleRadioButtons } from '../../../../../component/dataview/input/SimpleRadioButtons.component'; import { EventUtils } from '../../../../../share/utils/EventUtils'; import { CLICK_EVENT, BEFORE_CLICK_EVENT } from '../../../../../share/CustomEventType'; import { NeedFocusService } from '../../../../../service/NeedFocusService.service'; import { I18N } from '../../../../../decorator/I18N.decorator'; import { FormControl } from '@angular/forms'; import { MatRadioButton } from '@angular/material'; const /** @type {?} */ TYPE_NAME = "material-radio-buttons"; const /** @type {?} */ DEFAULT_LABEL_POSITION = 'after'; export class MaterialRadioButtons extends SimpleRadioButtons { /** * @param {?} elementRef * @param {?} needFocusService */ constructor(elementRef, needFocusService) { super(elementRef, needFocusService); this.beforeClickEvent = new EventEmitter(); this.clickEvent = new EventEmitter(); this.beforeFocusEvent = new EventEmitter(); this.focusEvent = new EventEmitter(); this.beforeLostFocusEvent = new EventEmitter(); this.lostFocusEvent = new EventEmitter(); this.beforeChangeEvent = new EventEmitter(); this.changeEvent = new EventEmitter(); this.formControl = new FormControl(); this.labelPosition = DEFAULT_LABEL_POSITION; this.disabled = false; this.disableRipple = false; this.vertical = false; } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { setTimeout(() => { this.initEventHandlers(); }, 20); } /** * @return {?} */ initEventHandlers() { $(this.elementRef.nativeElement).find('input.mat-radio-input').focus(($event) => { this.onFocusing($event); }); $(this.elementRef.nativeElement).find('input.mat-radio-input').blur(($event) => { this.onLostFocusing($event); }); } /** * @return {?} */ getValue() { return this.value; } /** * @param {?} value * @return {?} */ setValue(value) { this.value = value; } /** * @return {?} */ isDisable() { return this.disabled; } /** * @param {?} disable * @return {?} */ setDisable(disable) { this.disabled = disable; } /** * @return {?} */ isDisableRipple() { return this.disableRipple; } /** * @param {?} disableRipple * @return {?} */ setDisableRipple(disableRipple) { this.disableRipple = disableRipple; } /** * @return {?} */ getLabelPosition() { return this.labelPosition; } /** * @param {?} position * @return {?} */ setLabelPosition(position) { if (position === "before") { this.labelPosition = "before"; } else { this.labelPosition = "after"; } } /** * @param {?} index * @param {?=} $event * @param {?=} fireEvent * @return {?} */ onRadioClicked(index, $event, fireEvent) { if (fireEvent === null || fireEvent === undefined) { fireEvent = true; } $event.preventDefault(); if (this.isReadOnly()) { return; } if (this.isDisabled()) { return; } let /** @type {?} */ oldIndex = this.getSelectedIndex(); let /** @type {?} */ newIndex = index; EventUtils.handleBrowserEvent(this, 'beforeClickEvent', $event, fireEvent, ($event) => { // doEvent this.setSelectedIndex(newIndex, $event); }, ($event) => { // emitBeforeEvent this.emitBeforeClickEvent(oldIndex, newIndex, $event); }, ($event, result) => { // emitAfterEvent this.emitClickEvent(oldIndex, newIndex, $event); }, ($event) => { // doPrevented }); } /** * @param {?} selectedItems * @param {?=} $event * @param {?=} fireEvent * @param {?=} fireChangeEvent * @return {?} */ _setRadioSelectedItems(selectedItems, $event, fireEvent, fireChangeEvent) { this.setSelectedItems(selectedItems, $event, fireEvent, fireChangeEvent); } /** * @param {?} selectedItems * @param {?=} $event * @param {?=} fireEvent * @param {?=} fireChangeEvent * @return {?} */ setSelectedItems(selectedItems, $event, fireEvent, fireChangeEvent) { if (selectedItems === null || selectedItems === undefined || !Array.isArray(selectedItems)) { selectedItems = []; } if (fireEvent === null || fireEvent === undefined) { fireEvent = true; } let /** @type {?} */ sItems = []; let /** @type {?} */ newIndices = []; for (let /** @type {?} */ item of selectedItems) { let /** @type {?} */ idx = this.getItemIndex(item); if (idx >= 0) { newIndices.push(idx); sItems.push(item); } } // Only allow "item" which actually exists. selectedItems = sItems; let /** @type {?} */ oldIndex = this.getSelectedIndexes(); EventUtils.handleBrowserEvent(this, 'beforeSelectEvent', $event, fireEvent, ($event) => { // doEvent this._setSelectedItemsSaveData(selectedItems, true, $event, fireChangeEvent); }, ($event) => { // emitBeforeEvent this.emitBeforeSelectEvent(oldIndex, newIndices, $event); }, ($event, result) => { // emitAfterEvent this.emitSelectEvent(oldIndex, newIndices, $event); }, ($event) => { // doPrevented this.formControl.setValue(this.getSelectedData()); }); } /** * @param {?} oldIndex * @param {?} newIndex * @param {?=} $event * @return {?} */ emitBeforeClickEvent(oldIndex, newIndex, $event) { let /** @type {?} */ eventData = { oldIndex: oldIndex, oldItem: this.getItemAtIndex(oldIndex), index: newIndex, item: this.getItemAtIndex(newIndex) }; // emit event let /** @type {?} */ data = eventData; let /** @type {?} */ ev = EventUtils.newCustomEvent(BEFORE_CLICK_EVENT, this, data, $event); if (this.beforeClickEvent !== null && this.beforeClickEvent !== undefined) { this.beforeClickEvent.emit(ev); } } /** * @param {?} oldIndex * @param {?} newIndex * @param {?=} $event * @return {?} */ emitClickEvent(oldIndex, newIndex, $event) { let /** @type {?} */ eventData = { oldIndex: oldIndex, oldItem: this.getItemAtIndex(oldIndex), index: newIndex, item: this.getItemAtIndex(newIndex) }; // emit event let /** @type {?} */ data = eventData; let /** @type {?} */ ev = EventUtils.newCustomEvent(CLICK_EVENT, this, data, $event); if (this.clickEvent !== null && this.clickEvent !== undefined) { this.clickEvent.emit(ev); } } /** * @param {?} $event * @return {?} */ onChanged($event) { } /** * @param {?} $event * @return {?} */ onFocusing($event) { this.needFocusService.setFocusingComponent(this, $event); } /** * @param {?} $event * @return {?} */ onLostFocusing($event) { this.needFocusService.resetFocusingComponent($event); } /** * @param {?} $event * @return {?} */ doFocus($event) { if ($(this.elementRef.nativeElement).find('input.mat-radio-input:focus').length <= 0) { $(this.elementRef.nativeElement).find('input.mat-radio-input').focus(); } } /** * @param {?} $event * @return {?} */ doLostFocus($event) { if ($(this.elementRef.nativeElement).find('input.mat-radio-input:focus').length > 0) { $(this.elementRef.nativeElement).find('input.mat-radio-input').blur(); } } /** * @return {?} */ isVertical() { return this.vertical; } /** * @param {?} vertical * @return {?} */ setVertical(vertical) { this.vertical = vertical; } } MaterialRadioButtons.TYPE_NAME = TYPE_NAME; MaterialRadioButtons.decorators = [ { type: Component, args: [{ moduleId: module.id, selector: TYPE_NAME, template: `<div class="material-input material-radio-buttons"> <mat-radio-group #mcomp [formControl]="formControl" [phxDisableControl]="isDisable()" [labelPosition]="getLabelPosition()" [value]="getValue()"> <mat-radio-button *ngFor="let item of getItems(); let i = index;" [class.vertical]="isVertical()" [disableRipple]="isDisableRipple()" [checked]="getSelectedIndex()===i" [value]="item.getValue()" (click)="onRadioClicked(i, $event)" (change)="_setRadioSelectedItems(item, $event)">{{ item.label }}</mat-radio-button> </mat-radio-group> <div class="validation" [style.display]="getValidationResultMessage() ? undefined : 'none'" [class.normal]="isNormal() && !isDisabled()" [class.success]="isSuccess() && !isDisabled()" [class.warning]="isWarning() && !isDisabled()" [class.error]="isError() && !isDisabled()"> <ng-template [ngIf]="getValidationResultMessage()" [ngIfElse]="validation_else"> {{getValidationResultMessage() | phx_text}} </ng-template> <ng-template #validation_else> <!-- We've to put whitespace if there is no validation msg to prevent empty dom --> <!-- since if validate msg's <div> dom is empty, the component positioning --> <!-- will be misplaced. --> {{ '&nbsp;' }} </ng-template> </div> <div class="description" [style.display]="getValidationResultMessage() ? 'none' : undefined" [class.normal]="isNormal() && !isDisabled()" [class.success]="isSuccess() && !isDisabled()" [class.warning]="isWarning() && !isDisabled()" [class.error]="isError() && !isDisabled()"> <ng-template [ngIf]="getDescription()" [ngIfElse]="description_else"> {{ getDescription() | phx_text }} </ng-template> <ng-template #description_else> <!-- We've to put whitespace if there is no description to prevent empty dom --> <!-- since if description's <div> dom is empty, the component positioning --> <!-- will be misplaced. --> {{ '&nbsp;' }} </ng-template> </div> <div class="help"> {{getHelp() | phx_text}} </div> </div> `, },] }, ]; /** @nocollapse */ MaterialRadioButtons.ctorParameters = () => [ { type: ElementRef, }, { type: NeedFocusService, }, ]; MaterialRadioButtons.propDecorators = { "dataParent": [{ type: Input },], "ignoreParentData": [{ type: Input },], "data": [{ type: Input },], "ignoreParentDisabled": [{ type: Input },], "delegateHistory": [{ type: Input },], "onDisabled": [{ type: Input },], "onEnabled": [{ type: Input },], "loadingEnabled": [{ type: Input },], "i18nKey": [{ type: Input },], "bypass": [{ type: Input, args: ['i18nBypass',] },], "options": [{ type: Input },], "disabled": [{ type: Input },], "field": [{ type: Input },], "name": [{ type: Input },], "typeOfData": [{ type: Input },], "readOnly": [{ type: Input },], "help": [{ type: Input },], "dataComparator": [{ type: Input, args: ['comparator',] },], "items": [{ type: Input },], "description": [{ type: Input },], "value": [{ type: Input },], "labelPosition": [{ type: Input },], "disableRipple": [{ type: Input },], "selected": [{ type: Input },], "vertical": [{ type: Input, args: ['vertical',] },], "loadEvent": [{ type: Output, args: ['phxLoad',] },], "startValidateEvent": [{ type: Output, args: ['phxStartValidate',] },], "endValidateEvent": [{ type: Output, args: ['phxEndValidate',] },], "beforeFocusEvent": [{ type: Output, args: ['phxBeforeFocus',] },], "focusEvent": [{ type: Output, args: ['phxFocus',] },], "beforeLostFocusEvent": [{ type: Output, args: ['phxBeforeLostFocus',] },], "lostFocusEvent": [{ type: Output, args: ['phxLostFocus',] },], "beforeChangeEvent": [{ type: Output, args: ['phxBeforeChange',] },], "changeEvent": [{ type: Output, args: ['phxChange',] },], "beforeSelectEvent": [{ type: Output, args: ['phxBeforeSelect',] },], "selectEvent": [{ type: Output, args: ['phxSelect',] },], "beforeClickEvent": [{ type: Output, args: ['phxBeforeClick',] },], "clickEvent": [{ type: Output, args: ['phxClick',] },], }; tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Object) ], MaterialRadioButtons.prototype, "dataParent", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Boolean) ], MaterialRadioButtons.prototype, "ignoreParentData", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Object) ], MaterialRadioButtons.prototype, "data", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Boolean) ], MaterialRadioButtons.prototype, "ignoreParentDisabled", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Boolean) ], MaterialRadioButtons.prototype, "delegateHistory", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Function) ], MaterialRadioButtons.prototype, "onDisabled", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Function) ], MaterialRadioButtons.prototype, "onEnabled", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Boolean) ], MaterialRadioButtons.prototype, "loadingEnabled", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", String) ], MaterialRadioButtons.prototype, "i18nKey", void 0); tslib_1.__decorate([ Option('i18nBypass'), tslib_1.__metadata("design:type", Boolean) ], MaterialRadioButtons.prototype, "bypass", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Boolean) ], MaterialRadioButtons.prototype, "disabled", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", String) ], MaterialRadioButtons.prototype, "field", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", String) ], MaterialRadioButtons.prototype, "name", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", String) ], MaterialRadioButtons.prototype, "typeOfData", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Boolean) ], MaterialRadioButtons.prototype, "readOnly", void 0); tslib_1.__decorate([ I18N(), Option(), tslib_1.__metadata("design:type", Object) ], MaterialRadioButtons.prototype, "help", void 0); tslib_1.__decorate([ Option('comparator'), tslib_1.__metadata("design:type", Object) ], MaterialRadioButtons.prototype, "dataComparator", void 0); tslib_1.__decorate([ Option(), I18N(), tslib_1.__metadata("design:type", Array) ], MaterialRadioButtons.prototype, "items", void 0); tslib_1.__decorate([ I18N(), Option(), tslib_1.__metadata("design:type", String) ], MaterialRadioButtons.prototype, "description", void 0); tslib_1.__decorate([ I18N(), Option(), tslib_1.__metadata("design:type", Object) ], MaterialRadioButtons.prototype, "value", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", String) ], MaterialRadioButtons.prototype, "labelPosition", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", Boolean) ], MaterialRadioButtons.prototype, "disableRipple", void 0); tslib_1.__decorate([ Option(), tslib_1.__metadata("design:type", MatRadioButton) ], MaterialRadioButtons.prototype, "selected", void 0); tslib_1.__decorate([ Option('vertical'), tslib_1.__metadata("design:type", Boolean) ], MaterialRadioButtons.prototype, "vertical", void 0); tslib_1.__decorate([ Option('load'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "loadEvent", void 0); tslib_1.__decorate([ Option('startValidate'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "startValidateEvent", void 0); tslib_1.__decorate([ Option('endValidate'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "endValidateEvent", void 0); tslib_1.__decorate([ Option('beforeFocus'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "beforeFocusEvent", void 0); tslib_1.__decorate([ Option('focus'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "focusEvent", void 0); tslib_1.__decorate([ Option('beforeLostFocus'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "beforeLostFocusEvent", void 0); tslib_1.__decorate([ Option('lostFocus'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "lostFocusEvent", void 0); tslib_1.__decorate([ Option('beforeChange'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "beforeChangeEvent", void 0); tslib_1.__decorate([ Option('change'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "changeEvent", void 0); tslib_1.__decorate([ Option('beforeSelect'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "beforeSelectEvent", void 0); tslib_1.__decorate([ Option('select'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "selectEvent", void 0); tslib_1.__decorate([ Option('beforeClick'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "beforeClickEvent", void 0); tslib_1.__decorate([ Option('click'), tslib_1.__metadata("design:type", EventEmitter) ], MaterialRadioButtons.prototype, "clickEvent", void 0); function MaterialRadioButtons_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ MaterialRadioButtons.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ MaterialRadioButtons.ctorParameters; /** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */ MaterialRadioButtons.propDecorators; /** @type {?} */ MaterialRadioButtons.TYPE_NAME; /** @type {?} */ MaterialRadioButtons.prototype.dataParent; /** @type {?} */ MaterialRadioButtons.prototype.ignoreParentData; /** @type {?} */ MaterialRadioButtons.prototype.data; /** @type {?} */ MaterialRadioButtons.prototype.ignoreParentDisabled; /** @type {?} */ MaterialRadioButtons.prototype.delegateHistory; /** @type {?} */ MaterialRadioButtons.prototype.onDisabled; /** @type {?} */ MaterialRadioButtons.prototype.onEnabled; /** @type {?} */ MaterialRadioButtons.prototype.loadingEnabled; /** @type {?} */ MaterialRadioButtons.prototype.i18nKey; /** @type {?} */ MaterialRadioButtons.prototype.bypass; /** @type {?} */ MaterialRadioButtons.prototype.options; /** @type {?} */ MaterialRadioButtons.prototype.disabled; /** @type {?} */ MaterialRadioButtons.prototype.field; /** @type {?} */ MaterialRadioButtons.prototype.name; /** @type {?} */ MaterialRadioButtons.prototype.typeOfData; /** @type {?} */ MaterialRadioButtons.prototype.readOnly; /** @type {?} */ MaterialRadioButtons.prototype.help; /** @type {?} */ MaterialRadioButtons.prototype.dataComparator; /** @type {?} */ MaterialRadioButtons.prototype.items; /** @type {?} */ MaterialRadioButtons.prototype.description; /** @type {?} */ MaterialRadioButtons.prototype.value; /** @type {?} */ MaterialRadioButtons.prototype.labelPosition; /** @type {?} */ MaterialRadioButtons.prototype.disableRipple; /** @type {?} */ MaterialRadioButtons.prototype.selected; /** @type {?} */ MaterialRadioButtons.prototype.vertical; /** @type {?} */ MaterialRadioButtons.prototype.formControl; /** @type {?} */ MaterialRadioButtons.prototype.loadEvent; /** @type {?} */ MaterialRadioButtons.prototype.startValidateEvent; /** @type {?} */ MaterialRadioButtons.prototype.endValidateEvent; /** @type {?} */ MaterialRadioButtons.prototype.beforeFocusEvent; /** @type {?} */ MaterialRadioButtons.prototype.focusEvent; /** @type {?} */ MaterialRadioButtons.prototype.beforeLostFocusEvent; /** @type {?} */ MaterialRadioButtons.prototype.lostFocusEvent; /** @type {?} */ MaterialRadioButtons.prototype.beforeChangeEvent; /** @type {?} */ MaterialRadioButtons.prototype.changeEvent; /** @type {?} */ MaterialRadioButtons.prototype.beforeSelectEvent; /** @type {?} */ MaterialRadioButtons.prototype.selectEvent; /** @type {?} */ MaterialRadioButtons.prototype.beforeClickEvent; /** @type {?} */ MaterialRadioButtons.prototype.clickEvent; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWF0ZXJpYWxSYWRpb0J1dHRvbnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vY29tLnBobG94dWkvIiwic291cmNlcyI6WyJsaWIvdGhlbWUvbWF0ZXJpYWwvY29tcG9uZW50L2RhdGF2aWV3L2lucHV0L01hdGVyaWFsUmFkaW9CdXR0b25zLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsVUFBVSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQWlCLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sc0VBQXNFLENBQUM7QUFDMUcsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxXQUFXLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQTtBQUN0RixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUluRixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDL0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTdDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVuRCx1QkFBTSxTQUFTLEdBQVcsd0JBQXdCLENBQUM7QUFDbkQsdUJBQU0sc0JBQXNCLEdBQUcsT0FBTyxDQUFDO0FBc0N2QyxNQUFNLDJCQUE0QixTQUFRLGtCQUFrQjs7Ozs7SUE2STFELFlBQVksVUFBc0IsRUFBRSxnQkFBa0M7UUFDcEUsS0FBSyxDQUFDLFVBQVUsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBRXBDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzNDLElBQUksQ0FBQyxVQUFVLEdBQUcs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LFFBQVEsQ0FBQztzQ0FDTSxZQUFZOzs7SUFLbEMsTUFBTSxDQUFDLGFBQWEsQ0FBQztzQ0FDTSxZQUFZOzs7SUFFdkMsTUFBTSxDQUFDLE9BQU8sQ0FBQztzQ0FDTSxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIEVsZW1lbnRSZWYsIElucHV0LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBPcHRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9kZWNvcmF0b3IvT3B0aW9uLmRlY29yYXRvcic7XHJcbmltcG9ydCB7IFNpbXBsZVJhZGlvQnV0dG9ucyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uL2NvbXBvbmVudC9kYXRhdmlldy9pbnB1dC9TaW1wbGVSYWRpb0J1dHRvbnMuY29tcG9uZW50JztcclxuaW1wb3J0IHsgRXZlbnRVdGlscyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uL3NoYXJlL3V0aWxzL0V2ZW50VXRpbHMnO1xyXG5pbXBvcnQgeyBDTElDS19FVkVOVCwgQkVGT1JFX0NMSUNLX0VWRU5UIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vc2hhcmUvQ3VzdG9tRXZlbnRUeXBlJ1xyXG5pbXBvcnQgeyBOZWVkRm9jdXNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vc2VydmljZS9OZWVkRm9jdXNTZXJ2aWNlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBEZWZhdWx0U2VsZWN0SXRlbU1vZGVsIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vY29tcG9uZW50L21vZGVsL0RlZmF1bHRTZWxlY3RJdGVtTW9kZWwnO1xyXG5pbXBvcnQgeyBJSGFzRGF0YSB9IGZyb20gJy4uLy4uLy4uLy4uLy4uL2NvbXBvbmVudC9JSGFzRGF0YSc7XHJcbmltcG9ydCB7IElEYXRhQ29tcGFyYXRvciB9IGZyb20gJy4uLy4uLy4uLy4uLy4uL2NvbXBvbmVudC9JRGF0YUNvbXBhcmF0b3InO1xyXG5pbXBvcnQgeyBJMThOIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vZGVjb3JhdG9yL0kxOE4uZGVjb3JhdG9yJztcclxuaW1wb3J0IHsgRm9ybUNvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IElTZWxlY3RJdGVtTW9kZWwgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9jb21wb25lbnQvY29tcG9uZW50cyc7XHJcbmltcG9ydCB7IE1hdFJhZGlvQnV0dG9uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwnO1xyXG5cclxuY29uc3QgVFlQRV9OQU1FOiBzdHJpbmcgPSBcIm1hdGVyaWFsLXJhZGlvLWJ1dHRvbnNcIjtcclxuY29uc3QgREVGQVVMVF9MQUJFTF9QT1NJVElPTiA9ICdhZnRlcic7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBtb2R1bGVJZDogbW9kdWxlLmlkLFxyXG4gIHNlbGVjdG9yOiBUWVBFX05BTUUsXHJcbiAgdGVtcGxhdGU6IGA8ZGl2IGNsYXNzPVwibWF0ZXJpYWwtaW5wdXQgbWF0ZXJpYWwtcmFkaW8tYnV0dG9uc1wiPlxyXG4gICAgPG1hdC1yYWRpby1ncm91cCAjbWNvbXAgW2Zvcm1Db250cm9sXT1cImZvcm1Db250cm9sXCIgW3BoeERpc2FibGVDb250cm9sXT1cImlzRGlzYWJsZSgpXCIgW2xhYmVsUG9zaXRpb25dPVwiZ2V0TGFiZWxQb3NpdGlvbigpXCIgW3ZhbHVlXT1cImdldFZhbHVlKClcIj5cclxuICAgICAgICA8bWF0LXJhZGlvLWJ1dHRvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBnZXRJdGVtcygpOyBsZXQgaSA9IGluZGV4O1wiIFtjbGFzcy52ZXJ0aWNhbF09XCJpc1ZlcnRpY2FsKClcIiBbZGlzYWJsZVJpcHBsZV09XCJpc0Rpc2FibGVSaXBwbGUoKVwiIFtjaGVja2VkXT1cImdldFNlbGVjdGVkSW5kZXgoKT09PWlcIiBbdmFsdWVdPVwiaXRlbS5nZXRWYWx1ZSgpXCIgKGNsaWNrKT1cIm9uUmFkaW9DbGlja2VkKGksICRldmVudClcIiAoY2hhbmdlKT1cIl9zZXRSYWRpb1NlbGVjdGVkSXRlbXMoaXRlbSwgJGV2ZW50KVwiPnt7IGl0ZW0ubGFiZWwgfX08L21hdC1yYWRpby1idXR0b24+XHJcbiAgICA8L21hdC1yYWRpby1ncm91cD5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwidmFsaWRhdGlvblwiIFtzdHlsZS5kaXNwbGF5XT1cImdldFZhbGlkYXRpb25SZXN1bHRNZXNzYWdlKCkgPyB1bmRlZmluZWQgOiAnbm9uZSdcIiBbY2xhc3Mubm9ybWFsXT1cImlzTm9ybWFsKCkgJiYgIWlzRGlzYWJsZWQoKVwiIFtjbGFzcy5zdWNjZXNzXT1cImlzU3VjY2VzcygpICYmICFpc0Rpc2FibGVkKClcIiBbY2xhc3Mud2FybmluZ109XCJpc1dhcm5pbmcoKSAmJiAhaXNEaXNhYmxlZCgpXCIgW2NsYXNzLmVycm9yXT1cImlzRXJyb3IoKSAmJiAhaXNEaXNhYmxlZCgpXCI+XHJcbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImdldFZhbGlkYXRpb25SZXN1bHRNZXNzYWdlKClcIiBbbmdJZkVsc2VdPVwidmFsaWRhdGlvbl9lbHNlXCI+XHJcbiAgICAgICAgICAgIHt7Z2V0VmFsaWRhdGlvblJlc3VsdE1lc3NhZ2UoKSB8IHBoeF90ZXh0fX1cclxuICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjdmFsaWRhdGlvbl9lbHNlPlxyXG4gICAgICAgICAgICA8IS0tIFdlJ3ZlIHRvIHB1dCB3aGl0ZXNwYWNlIGlmIHRoZXJlIGlzIG5vIHZhbGlkYXRpb24gbXNnIHRvIHByZXZlbnQgZW1wdHkgZG9tIC0tPlxyXG4gICAgICAgICAgICA8IS0tIHNpbmNlIGlmIHZhbGlkYXRlIG1zZydzIDxkaXY+IGRvbSBpcyBlbXB0eSwgdGhlIGNvbXBvbmVudCBwb3NpdGlvbmluZyAtLT5cclxuICAgICAgICAgICAgPCEtLSB3aWxsIGJlIG1pc3BsYWNlZC4gLS0+XHJcbiAgICAgICAgICAgIHt7ICcmbmJzcDsnIH19XHJcbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgIDwvZGl2PlxyXG4gICAgPGRpdiBjbGFzcz1cImRlc2NyaXB0aW9uXCIgW3N0eWxlLmRpc3BsYXldPVwiZ2V0VmFsaWRhdGlvblJlc3VsdE1lc3NhZ2UoKSA/ICdub25lJyA6IHVuZGVmaW5lZFwiIFtjbGFzcy5ub3JtYWxdPVwiaXNOb3JtYWwoKSAmJiAhaXNEaXNhYmxlZCgpXCIgW2NsYXNzLnN1Y2Nlc3NdPVwiaXNTdWNjZXNzKCkgJiYgIWlzRGlzYWJsZWQoKVwiIFtjbGFzcy53YXJuaW5nXT1cImlzV2FybmluZygpICYmICFpc0Rpc2FibGVkKClcIiBbY2xhc3MuZXJyb3JdPVwiaXNFcnJvcigpICYmICFpc0Rpc2FibGVkKClcIj5cclxuICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiZ2V0RGVzY3JpcHRpb24oKVwiIFtuZ0lmRWxzZV09XCJkZXNjcmlwdGlvbl9lbHNlXCI+XHJcbiAgICAgICAgICAgIHt7IGdldERlc2NyaXB0aW9uKCkgfCBwaHhfdGV4dCB9fVxyXG4gICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgPG5nLXRlbXBsYXRlICNkZXNjcmlwdGlvbl9lbHNlPlxyXG4gICAgICAgICAgICA8IS0tIFdlJ3ZlIHRvIHB1dCB3aGl0ZXNwYWNlIGlmIHRoZXJlIGlzIG5vIGRlc2NyaXB0aW9uIHRvIHByZXZlbnQgZW1wdHkgZG9tIC0tPlxyXG4gICAgICAgICAgICA8IS0tIHNpbmNlIGlmIGRlc2NyaXB0aW9uJ3MgPGRpdj4gZG9tIGlzIGVtcHR5LCB0aGUgY29tcG9uZW50IHBvc2l0aW9uaW5nIC0tPlxyXG4gICAgICAgICAgICA8IS0tIHdpbGwgYmUgbWlzcGxhY2VkLiAtLT5cclxuICAgICAgICAgICAge3sgJyZuYnNwOycgfX1cclxuICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8ZGl2IGNsYXNzPVwiaGVscFwiPlxyXG4gICAgICAgIHt7Z2V0SGVscCgpIHwgcGh4X3RleHR9fVxyXG4gICAgPC9kaXY+XHJcbjwvZGl2PlxyXG5gLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTWF0ZXJpYWxSYWRpb0J1dHRvbnMgZXh0ZW5kcyBTaW1wbGVSYWRpb0J1dHRvbnMgaW1wbGVtZW50cyBPbkluaXQge1xyXG5cclxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFRZUEVfTkFNRTogc3RyaW5nID0gVFlQRV9OQU1FO1xyXG4gXHJcbiAgLy8gUmUtZGVjbGFyZSBmaWVsZCB0byBkZWNsYXJlIG5nIEBJbnB1dC5cclxuICAvLyAtLS0gZnJvbSBBYnN0cmFjdEhhc0RhdGFcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCBkYXRhUGFyZW50OiBJSGFzRGF0YTtcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCBpZ25vcmVQYXJlbnREYXRhOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpXHJcbiAgQE9wdGlvbigpXHJcbiAgcHJvdGVjdGVkIGRhdGE6IGFueTtcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCBpZ25vcmVQYXJlbnREaXNhYmxlZDogYm9vbGVhbjtcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCBkZWxlZ2F0ZUhpc3Rvcnk6IGJvb2xlYW47XHJcbiAgQElucHV0KClcclxuICBAT3B0aW9uKClcclxuICBwcm90ZWN0ZWQgb25EaXNhYmxlZDogRnVuY3Rpb247XHJcbiAgQElucHV0KClcclxuICBAT3B0aW9uKClcclxuICBwcm90ZWN0ZWQgb25FbmFibGVkOiBGdW5jdGlvbjtcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCBsb2FkaW5nRW5hYmxlZDogYm9vbGVhbjtcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCBpMThuS2V5OiBzdHJpbmc7XHJcbiAgQElucHV0KCdpMThuQnlwYXNzJylcclxuICBAT3B0aW9uKCdpMThuQnlwYXNzJylcclxuICBwcm90ZWN0ZWQgYnlwYXNzOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpXHJcbiAgcHJvdGVjdGVkIG9wdGlvbnM6IGFueTtcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCBkaXNhYmxlZDogYm9vbGVhbjtcclxuICAvLyAtLS0gZnJvbSBBYnN0cmFjdERhdGFWaWV3XHJcbiAgQElucHV0KClcclxuICBAT3B0aW9uKClcclxuICBwcm90ZWN0ZWQgZmllbGQ6IHN0cmluZztcclxuICAvLyAtLS0gZnJvbSBBYnN0cmFjdElucHV0RGF0YVZpZXdcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCBuYW1lOiBzdHJpbmc7XHJcbiAgQElucHV0KClcclxuICBAT3B0aW9uKClcclxuICBwcm90ZWN0ZWQgdHlwZU9mRGF0YTogc3RyaW5nO1xyXG4gIEBJbnB1dCgpXHJcbiAgQE9wdGlvbigpXHJcbiAgcHJvdGVjdGVkIHJlYWRPbmx5OiBib29sZWFuO1xyXG4gIEBJbnB1dCgpXHJcbiAgQEkxOE4oKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCBoZWxwOiBhbnk7XHJcbiAgLy8gLS0tIGZyb20gQWJzdHJhY3RTZWxlY3RJdGVtc1xyXG4gIEBJbnB1dCgnY29tcGFyYXRvcicpXHJcbiAgQE9wdGlvbignY29tcGFyYXRvcicpXHJcbiAgcHJvdGVjdGVkIGRhdGFDb21wYXJhdG9yOiBJRGF0YUNvbXBhcmF0b3I8YW55PjtcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIEBJMThOKClcclxuICBwcm90ZWN0ZWQgaXRlbXM6IERlZmF1bHRTZWxlY3RJdGVtTW9kZWxbXTtcclxuXHJcbiAgLy8gLS0tIGZyb20gU2VsZlxyXG4gIEBJMThOKClcclxuICBAT3B0aW9uKClcclxuICBASW5wdXQoKVxyXG4gIHByb3RlY3RlZCBkZXNjcmlwdGlvbjogc3RyaW5nO1xyXG4gIEBJMThOKClcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCB2YWx1ZTogYW55O1xyXG4gIEBJbnB1dCgpXHJcbiAgQE9wdGlvbigpXHJcbiAgcHJvdGVjdGVkIGxhYmVsUG9zaXRpb246ICdiZWZvcmUnIHwgJ2FmdGVyJztcclxuICBASW5wdXQoKVxyXG4gIEBPcHRpb24oKVxyXG4gIHByb3RlY3RlZCBkaXNhYmxlUmlwcGxlOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpXHJcbiAgQE9wdGlvbigpXHJcbiAgcHJvdGVjdGVkIHNlbGVjdGVkOiBNYXRSYWRpb0J1dHRvbjtcclxuICBASW5wdXQoJ3ZlcnRpY2FsJylcclxuICBAT3B0aW9uKCd2ZXJ0aWNhbCcpXHJcbiAgcHJvdGVjdGVkIHZlcnRpY2FsOiBib29sZWFuO1xyXG5cclxuICBwdWJsaWMgZm9ybUNvbnRyb2w6IEZvcm1Db250cm9sO1xyXG5cclxuICAvLyBSZS1kZWNsYXJlIGZpZWxkIHRvIGRlY2xhcmUgbmcgQE91dHB1dC5cclxuICAvLyAtLS0gZnJvbSBBYnN0cmFjdEhhc0RhdGFcclxuICBAT3V0cHV0KCdwaHhMb2FkJylcclxuICBAT3B0aW9uKCdsb2FkJylcclxuICBwcm90ZWN0ZWQgbG9hZEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PjtcclxuICAvLyAtLS0gZnJvbSBBYnN0cmFjdERhdGFWaWV3XHJcbiAgLy8gLS0tIGZyb20gQWJzdHJhY3RJbnB1dERhdGFWaWV3XHJcbiAgQE91dHB1dCgncGh4U3RhcnRWYWxpZGF0ZScpXHJcbiAgQE9wdGlvbignc3RhcnRWYWxpZGF0ZScpXHJcbiAgcHJvdGVjdGVkIHN0YXJ0VmFsaWRhdGVFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XHJcbiAgQE91dHB1dCgncGh4RW5kVmFsaWRhdGUnKVxyXG4gIEBPcHRpb24oJ2VuZFZhbGlkYXRlJylcclxuICBwcm90ZWN0ZWQgZW5kVmFsaWRhdGVFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XHJcbiAgQE91dHB1dCgncGh4QmVmb3JlRm9jdXMnKVxyXG4gIEBPcHRpb24oJ2JlZm9yZUZvY3VzJylcclxuICBwcm90ZWN0ZWQgYmVmb3JlRm9jdXNFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XHJcbiAgQE91dHB1dCgncGh4Rm9jdXMnKVxyXG4gIEBPcHRpb24oJ2ZvY3VzJylcclxuICBwcm90ZWN0ZWQgZm9jdXNFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XHJcbiAgQE91dHB1dCgncGh4QmVmb3JlTG9zdEZvY3VzJylcclxuICBAT3B0aW9uKCdiZWZvcmVMb3N0Rm9jdXMnKVxyXG4gIHByb3RlY3RlZCBiZWZvcmVMb3N0Rm9jdXNFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XHJcbiAgQE91dHB1dCgncGh4TG9zdEZvY3VzJylcclxuICBAT3B0aW9uKCdsb3N0Rm9jdXMnKVxyXG4gIHByb3RlY3RlZCBsb3N0Rm9jdXNFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XHJcbiAgQE91dHB1dCgncGh4QmVmb3JlQ2hhbmdlJylcclxuICBAT3B0aW9uKCdiZWZvcmVDaGFuZ2UnKVxyXG4gIHByb3RlY3RlZCBiZWZvcmVDaGFuZ2VFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XHJcbiAgQE91dHB1dCgncGh4Q2hhbmdlJylcclxuICBAT3B0aW9uKCdjaGFuZ2UnKVxyXG4gIHByb3RlY3RlZCBjaGFuZ2VFdmVudDogRXZlbnRFbWl0dGVyPGFueT47XHJcbiAgLy8gLS0tIGZyb20gQWJzdHJhY3RTZWxlY3RJdGVtc1xyXG4gIC8vIC0tLSBmcm9tIEFic3RyYWN0U2VsZWN0T25lSXRlbVxyXG4gIEBPdXRwdXQoJ3BoeEJlZm9yZVNlbGVjdCcpXHJcbiAgQE9wdGlvbignYmVmb3JlU2VsZWN0JylcclxuICBwcm90ZWN0ZWQgYmVmb3JlU2VsZWN0RXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xyXG4gIEBPdXRwdXQoJ3BoeFNlbGVjdCcpXHJcbiAgQE9wdGlvbignc2VsZWN0JylcclxuICBwcm90ZWN0ZWQgc2VsZWN0RXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xyXG5cclxuICAvLyAtLS0gZnJvbSBTZWxmXHJcblxyXG4gIEBPdXRwdXQoJ3BoeEJlZm9yZUNsaWNrJylcclxuICBAT3B0aW9uKCdiZWZvcmVDbGljaycpXHJcbiAgcHJvdGVjdGVkIGJlZm9yZUNsaWNrRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xyXG4gIEBPdXRwdXQoJ3BoeENsaWNrJylcclxuICBAT3B0aW9uKCdjbGljaycpXHJcbiAgcHJvdGVjdGVkIGNsaWNrRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xyXG5cclxuICBjb25zdHJ1Y3RvcihlbGVtZW50UmVmOiBFbGVtZW50UmVmLCBuZWVkRm9jdXNTZXJ2aWNlOiBOZWVkRm9jdXNTZXJ2aWNlKSB7XHJcbiAgICBzdXBlcihlbGVtZW50UmVmLCBuZWVkRm9jdXNTZXJ2aWNlKTtcclxuXHJcbiAgICB0aGlzLmJlZm9yZUNsaWNrRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgICB0aGlzLmNsaWNrRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgICB0aGlzLmJlZm9yZUZvY3VzRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgICB0aGlzLmZvY3VzRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgICB0aGlzLmJlZm9yZUxvc3RGb2N1c0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gICAgdGhpcy5sb3N0Rm9jdXNFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICAgIHRoaXMuYmVmb3JlQ2hhbmdlRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgICB0aGlzLmNoYW5nZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gICAgdGhpcy5mb3JtQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbCgpO1xyXG5cclxuICAgIHRoaXMubGFiZWxQb3NpdGlvbiA9IERFRkFVTFRfTEFCRUxfUE9TSVRJT047XHJcbiAgICB0aGlzLmRpc2FibGVkID0gZmFsc2U7XHJcbiAgICB0aGlzLmRpc2FibGVSaXBwbGUgPSBmYWxzZTtcclxuICAgIHRoaXMudmVydGljYWwgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICBzZXRUaW1lb3V0KCgpPT57XHJcbiAgICAgIHRoaXMuaW5pdEV2ZW50SGFuZGxlcnMoKTtcclxuICAgIH0sMjApXHJcbiAgfSBcclxuXHJcbiAgcHJpdmF0ZSBpbml0RXZlbnRIYW5kbGVycygpOiB2b2lkIHtcclxuICAgICQodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpLmZpbmQoJ2lucHV0Lm1hdC1yYWRpby1pbnB1dCcpLmZvY3VzKCgkZXZlbnQpPT57XHJcbiAgICAgIHRoaXMub25Gb2N1c2luZygkZXZlbnQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgJCh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCkuZmluZCgnaW5wdXQubWF0LXJhZGlvLWlucHV0JykuYmx1cigoJGV2ZW50KT0+e1xyXG4gICAgICB0aGlzLm9uTG9zdEZvY3VzaW5nKCRldmVudCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXRWYWx1ZSgpOiBhbnkge1xyXG4gICAgcmV0dXJuIHRoaXMudmFsdWU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0VmFsdWUodmFsdWU6IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGlzRGlzYWJsZSgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmRpc2FibGVkO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldERpc2FibGUoZGlzYWJsZTogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgdGhpcy5kaXNhYmxlZCA9IGRpc2FibGU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgaXNEaXNhYmxlUmlwcGxlKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZGlzYWJsZVJpcHBsZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXREaXNhYmxlUmlwcGxlKGRpc2FibGVSaXBwbGU6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIHRoaXMuZGlzYWJsZVJpcHBsZSA9IGRpc2FibGVSaXBwbGU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0TGFiZWxQb3NpdGlvbigpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMubGFiZWxQb3NpdGlvbjtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXRMYWJlbFBvc2l0aW9uKHBvc2l0aW9uOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGlmKHBvc2l0aW9uID09PSBcImJlZm9yZVwiKXtcclxuICAgICAgdGhpcy5sYWJlbFBvc2l0aW9uID0gXCJiZWZvcmVcIjtcclxuICAgIH0gZWxzZXtcclxuICAgICAgdGhpcy5sYWJlbFBvc2l0aW9uID0gXCJhZnRlclwiO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uUmFkaW9DbGlja2VkKGluZGV4OiBudW1iZXIsICRldmVudD86IEV2ZW50LCBmaXJlRXZlbnQ/OiBib29sZWFuKTogdm9pZCB7XHJcbiAgICBpZiAoZmlyZUV2ZW50ID09PSBudWxsIHx8IGZpcmVFdmVudCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIGZpcmVFdmVudCA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgaWYodGhpcy5pc1JlYWRPbmx5KCkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmKHRoaXMuaXNEaXNhYmxlZCgpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgb2xkSW5kZXggPSB0aGlzLmdldFNlbGVjdGVkSW5kZXgoKTtcclxuICAgIGxldCBuZXdJbmRleCA9IGluZGV4O1xyXG4gICAgXHJcbiAgICBFdmVudFV0aWxzLmhhbmRsZUJyb3dzZXJFdmVudCh0aGlzLCAnYmVmb3JlQ2xpY2tFdmVudCcsICRldmVudCwgZmlyZUV2ZW50LCAoJGV2ZW50OiBFdmVudCkgPT4ge1xyXG4gICAgICAvLyBkb0V2ZW50XHJcbiAgICAgIHRoaXMuc2V0U2VsZWN0ZWRJbmRleChuZXdJbmRleCwgJGV2ZW50KTtcclxuICAgIH0sICgkZXZlbnQ6IEV2ZW50KSA9PiB7XHJcbiAgICAgIC8vIGVtaXRCZWZvcmVFdmVudFxyXG4gICAgICB0aGlzLmVtaXRCZWZvcmVDbGlja0V2ZW50KG9sZEluZGV4LCBuZXdJbmRleCwgJGV2ZW50KTtcclxuICAgIH0sICgkZXZlbnQ6IEV2ZW50LCByZXN1bHQ6IGFueSkgPT4ge1xyXG4gICAgICAvLyBlbWl0QWZ0ZXJFdmVudFxyXG4gICAgICB0aGlzLmVtaXRDbGlja0V2ZW50KG9sZEluZGV4LCBuZXdJbmRleCwgJGV2ZW50KTtcclxuICAgIH0sICgkZXZlbnQ6IEV2ZW50KSA9PiB7XHJcbiAgICAgIC8vIGRvUHJldmVudGVkXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8vIHdyYXAgc2V0U2VsZWN0ZWRJdGVtcyBpbnRvIHB1YmxpY1xyXG4gIHB1YmxpYyBfc2V0UmFkaW9TZWxlY3RlZEl0ZW1zKHNlbGVjdGVkSXRlbXM6IElTZWxlY3RJdGVtTW9kZWxbXSwgJGV2ZW50PzogRXZlbnQsIGZpcmVFdmVudD86IGJvb2xlYW4sIGZpcmVDaGFuZ2VFdmVudD86IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIHRoaXMuc2V0U2VsZWN0ZWRJdGVtcyhzZWxlY3RlZEl0ZW1zLCAkZXZlbnQsIGZpcmVFdmVudCwgZmlyZUNoYW5nZUV2ZW50KTtcclxuICB9XHJcblxyXG4gIC8vIHVzZSBmb3IgcHJldmVudEV2ZW50IG9mIEZvcm1Db250cm9sXHJcbiAgcHJvdGVjdGVkIHNldFNlbGVjdGVkSXRlbXMoc2VsZWN0ZWRJdGVtczogSVNlbGVjdEl0ZW1Nb2RlbFtdLCAkZXZlbnQ/OiBFdmVudCwgZmlyZUV2ZW50PzogYm9vbGVhbiwgZmlyZUNoYW5nZUV2ZW50PzogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgaWYgKHNlbGVjdGVkSXRlbXMgPT09IG51bGwgfHwgc2VsZWN0ZWRJdGVtcyA9PT0gdW5kZWZpbmVkIHx8ICFBcnJheS5pc0FycmF5KHNlbGVjdGVkSXRlbXMpKSB7XHJcbiAgICAgIHNlbGVjdGVkSXRlbXMgPSBbXTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZmlyZUV2ZW50ID09PSBudWxsIHx8IGZpcmVFdmVudCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIGZpcmVFdmVudCA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHNJdGVtczogSVNlbGVjdEl0ZW1Nb2RlbFtdID0gW107XHJcbiAgICBsZXQgbmV3SW5kaWNlczogbnVtYmVyW10gPSBbXTtcclxuXHJcbiAgICBmb3IgKGxldCBpdGVtIG9mIHNlbGVjdGVkSXRlbXMpIHtcclxuICAgICAgbGV0IGlkeDogbnVtYmVyID0gdGhpcy5nZXRJdGVtSW5kZXgoaXRlbSk7XHJcblxyXG4gICAgICBpZiAoaWR4ID49IDApIHtcclxuICAgICAgICBuZXdJbmRpY2VzLnB1c2goaWR4KTtcclxuICAgICAgICBzSXRlbXMucHVzaChpdGVtKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIE9ubHkgYWxsb3cgXCJpdGVtXCIgd2hpY2ggYWN0dWFsbHkgZXhpc3RzLlxyXG4gICAgc2VsZWN0ZWRJdGVtcyA9IHNJdGVtcztcclxuXHJcbiAgICBsZXQgb2xkSW5kZXggPSB0aGlzLmdldFNlbGVjdGVkSW5kZXhlcygpO1xyXG4gICAgXHJcbiAgICBFdmVudFV0aWxzLmhhbmRsZUJyb3dzZXJFdmVudCh0aGlzLCAnYmVmb3JlU2VsZWN0RXZlbnQnLCAkZXZlbnQsIGZpcmVFdmVudCwgKCRldmVudDogRXZlbnQpID0+IHtcclxuICAgICAgLy8gZG9FdmVudFxyXG4gICAgICB0aGlzLl9zZXRTZWxlY3RlZEl0ZW1zU2F2ZURhdGEoc2VsZWN0ZWRJdGVtcywgdHJ1ZSwgJGV2ZW50LCBmaXJlQ2hhbmdlRXZlbnQpO1xyXG4gICAgfSwgKCRldmVudDogRXZlbnQpID0+IHtcclxuICAgICAgLy8gZW1pdEJlZm9yZUV2ZW50XHJcbiAgICAgIHRoaXMuZW1pdEJlZm9yZVNlbGVjdEV2ZW50KG9sZEluZGV4LCBuZXdJbmRpY2VzLCAkZXZlbnQpO1xyXG4gICAgfSwgKCRldmVudDogRXZlbnQsIHJlc3VsdDogYW55KSA9PiB7XHJcbiAgICAgIC8vIGVtaXRBZnRlckV2ZW50XHJcbiAgICAgIHRoaXMuZW1pdFNlbGVjdEV2ZW50KG9sZEluZGV4LCBuZXdJbmRpY2VzLCAkZXZlbnQpO1xyXG4gICAgfSwgKCRldmVudDogRXZlbnQpID0+IHtcclxuICAgICAgLy8gZG9QcmV2ZW50ZWRcclxuICAgICAgdGhpcy5mb3JtQ29udHJvbC5zZXRWYWx1ZSh0aGlzLmdldFNlbGVjdGVkRGF0YSgpKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGVtaXRCZWZvcmVDbGlja0V2ZW50KG9sZEluZGV4OiBudW1iZXIsIG5ld0luZGV4IDogbnVtYmVyLCAkZXZlbnQ/OiBFdmVudCk6IHZvaWQge1xyXG4gICAgbGV0IGV2ZW50RGF0YTogYW55ID0ge1xyXG4gICAgICBvbGRJbmRleDogb2xkSW5kZXgsXHJcbiAgICAgIG9sZEl0ZW06IHRoaXMuZ2V0SXRlbUF0SW5kZXgob2xkSW5kZXgpLFxyXG4gICAgICBpbmRleDogbmV3SW5kZXgsXHJcbiAgICAgIGl0ZW06IHRoaXMuZ2V0SXRlbUF0SW5kZXgobmV3SW5kZXgpXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIGVtaXQgZXZlbnRcclxuICAgIGxldCBkYXRhOiBhbnkgPSBldmVudERhdGE7XHJcbiAgICBsZXQgZXYgPSBFdmVudFV0aWxzLm5ld0N1c3RvbUV2ZW50KEJFRk9SRV9DTElDS19FVkVOVCwgdGhpcywgZGF0YSwgJGV2ZW50KTtcclxuXHJcbiAgICBpZiAodGhpcy5iZWZvcmVDbGlja0V2ZW50ICE9PSBudWxsICYmIHRoaXMuYmVmb3JlQ2xpY2tFdmVudCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHRoaXMuYmVmb3JlQ2xpY2tFdmVudC5lbWl0KGV2KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBlbWl0Q2xpY2tFdmVudChvbGRJbmRleDogbnVtYmVyLCBuZXdJbmRleCA6IG51bWJlciwgJGV2ZW50PzogYW55KTogdm9pZCB7XHJcbiAgICBsZXQgZXZlbnREYXRhOiBhbnkgPSB7XHJcbiAgICAgIG9sZEluZGV4OiBvbGRJbmRleCxcclxuICAgICAgb2xk