UNPKG

@hpe/angular-toolkit

Version:

Hewlett-Packard Enterprise : Angular toolkit for rapid project development

715 lines (700 loc) 80.5 kB
import { Component, Input, NgModule } from '@angular/core'; import { __extends } from 'tslib'; import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import { Lib } from '@hpe/angular-toolkit/lib'; import { AppEvent, Credentials } from '@hpe/angular-toolkit/model'; import { AbstractSubscriber, EventBusService, HttpService, LabelService, NotificationService, SessionService, HpeServiceModule } from '@hpe/angular-toolkit/service'; import { CommonModule } from '@angular/common'; import { MatCheckboxModule, MatButtonModule } from '@angular/material'; import { DropdownModule, InputTextModule } from 'primeng/primeng'; import { HpePanelModule } from '@hpe/angular-toolkit/gui/panel'; import { HpeDirectiveModule } from '@hpe/angular-toolkit/gui/directive'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FormColumn = /** @class */ (function () { function FormColumn() { } FormColumn.decorators = [ { type: Component, args: [{ selector: 'hpe-form-column', template: "<!--\n=============================================================================\n===\n=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.\n===\n=== Use of this source code is governed by an MIT-style license that can be\n=== found in the LICENSE file\n=============================================================================\n-->\n\n<div class=\"formColumn\" [style.width]=\"width\">\n <ng-content></ng-content>\n</div>\n", styles: [".formColumn{display:flex;flex-direction:column;align-content:center;justify-content:flex-start;margin:8px}"], },] }, ]; /** @nocollapse */ FormColumn.propDecorators = { "width": [{ type: Input },], }; return FormColumn; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FormLabel = /** @class */ (function () { //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function FormLabel() { } FormLabel.decorators = [ { type: Component, args: [{ selector: 'hpe-form-label', template: "<!--\n=============================================================================\n===\n=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.\n===\n=== Use of this source code is governed by an MIT-style license that can be\n=== found in the LICENSE file\n=============================================================================\n-->\n\n<span class=\"ui-inputgroup-addon label\">\n\t<hpe-icon name=\"{{icon}}\"></hpe-icon> {{label}}\n</span>\n", styles: [".label{width:12rem;text-align:start!important}:host ::ng-deep .iconStyle{vertical-align:baseline}"], },] }, ]; //------------------------------------------------------------------------- //--- //--- API methods //--- //------------------------------------------------------------------------- /** @nocollapse */ FormLabel.ctorParameters = function () { return []; }; FormLabel.propDecorators = { "icon": [{ type: Input },], "label": [{ type: Input },], }; return FormLabel; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FormPanel = /** @class */ (function () { function FormPanel() { } FormPanel.decorators = [ { type: Component, args: [{ selector: 'hpe-form-panel', template: "<!--\n=============================================================================\n===\n=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.\n===\n=== Use of this source code is governed by an MIT-style license that can be\n=== found in the LICENSE file\n=============================================================================\n-->\n\n<div class=\"formBody\">\n\t<ng-content></ng-content>\n</div>\n", styles: [".formBody{display:flex;align-content:center;justify-content:center;flex-wrap:wrap;box-sizing:border-box;width:100%;max-width:100%;padding:1rem;background:#fafafa;color:#000;font-size:1rem}"], },] }, ]; return FormPanel; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var FormText = /** @class */ (function () { //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function FormText() { } Object.defineProperty(FormText.prototype, "value", { get: /** * @return {?} */ function () { return this._value; }, //------------------------------------------------------------------------- set: /** * @param {?} value * @return {?} */ function (value) { if (this.transcoder && value != null) { value = this.transcoder.transcode(value); } this._value = value; }, enumerable: true, configurable: true }); FormText.decorators = [ { type: Component, args: [{ selector: 'hpe-form-text', template: "<!--\n=============================================================================\n===\n=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.\n===\n=== Use of this source code is governed by an MIT-style license that can be\n=== found in the LICENSE file\n=============================================================================\n-->\n\n<div class=\"ui-inputgroup spacing\">\n\t<hpe-form-label [icon]=\"icon\" [label]=\"label\"></hpe-form-label>\n\t<span class=\"ui-inputgroup-addon text\">{{value}}</span>\n</div>\n", styles: [".spacing{margin-bottom:1rem}.text{background-color:#f5f5f5;width:100%;color:#202020}"] },] }, ]; /** @nocollapse */ FormText.ctorParameters = function () { return []; }; FormText.propDecorators = { "icon": [{ type: Input },], "label": [{ type: Input },], "transcoder": [{ type: Input },], "value": [{ type: Input },], }; return FormText; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @abstract */ var AbstractFormComponent = /** @class */ (function () { //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function AbstractFormComponent() { this.enabled = true; this._required = false; } //------------------------------------------------------------------------- //--- //--- API methods //--- //------------------------------------------------------------------------- /** * @param {?} fn * @return {?} */ AbstractFormComponent.prototype.registerOnChange = /** * @param {?} fn * @return {?} */ function (fn) { this.onChange = fn; }; //------------------------------------------------------------------------- /** * @param {?} fn * @return {?} */ AbstractFormComponent.prototype.registerOnTouched = /** * @param {?} fn * @return {?} */ function (fn) { }; /** * @return {?} */ AbstractFormComponent.prototype.getComponentClass = /** * @return {?} */ function () { var /** @type {?} */ styles = ['control']; if (this.enabled) { if (this.required) { if (this.isProvided()) { styles.push("provided"); } else { styles.push("required"); } } } else { styles.push("disabled"); } return styles; }; Object.defineProperty(AbstractFormComponent.prototype, "required", { get: /** * @return {?} */ function () { return this._required; }, //------------------------------------------------------------------------- set: /** * @param {?} value * @return {?} */ function (value) { var /** @type {?} */ str = "" + value; if (str == "") { //--- Ok, '' means value not provided --> true value = true; } this._required = value; }, enumerable: true, configurable: true }); AbstractFormComponent.propDecorators = { "icon": [{ type: Input },], "label": [{ type: Input },], "enabled": [{ type: Input },], "required": [{ type: Input },], }; return AbstractFormComponent; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var InputText = /** @class */ (function (_super) { __extends(InputText, _super); //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function InputText() { return _super.call(this) || this; } /** * @param {?} value * @return {?} */ InputText.prototype.writeValue = /** * @param {?} value * @return {?} */ function (value) { this._value = value; }; Object.defineProperty(InputText.prototype, "value", { //------------------------------------------------------------------------- get: /** * @return {?} */ function () { return this._value; }, //------------------------------------------------------------------------- set: /** * @param {?} newValue * @return {?} */ function (newValue) { if (newValue == "") { newValue = null; } this._value = newValue; this.onChange(newValue); }, enumerable: true, configurable: true }); //------------------------------------------------------------------------- //--- //--- Protected methods //--- //------------------------------------------------------------------------- /** * @return {?} */ InputText.prototype.isProvided = /** * @return {?} */ function () { return Lib.str.isProvided(this.value); }; InputText.decorators = [ { type: Component, args: [{ selector: 'hpe-input-text', template: "<!--\n=============================================================================\n===\n=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.\n===\n=== Use of this source code is governed by an MIT-style license that can be\n=== found in the LICENSE file\n=============================================================================\n-->\n\n<div class=\"ui-inputgroup spacing\">\n <hpe-form-label [icon]=\"icon\" [label]=\"label\"></hpe-form-label>\n\t<input pInputText [(ngModel)]=\"value\" [ngClass]=\"getComponentClass()\" [disabled]=\"!enabled\">\n</div>\n\n", styles: [".spacing{margin-bottom:1rem}.control{width:100%}.required,.required:focus{border-right:5px solid #ff8d6d}.provided,.provided:focus{border-right:5px solid #00a982}"], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: InputText, multi: true }] },] }, ]; /** @nocollapse */ InputText.ctorParameters = function () { return []; }; return InputText; }(AbstractFormComponent)); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var InputArea = /** @class */ (function (_super) { __extends(InputArea, _super); //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function InputArea() { return _super.call(this) || this; } InputArea.decorators = [ { type: Component, args: [{ selector: 'hpe-input-area', template: "<!--\n=============================================================================\n===\n=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.\n===\n=== Use of this source code is governed by an MIT-style license that can be\n=== found in the LICENSE file\n=============================================================================\n-->\n\n<div class=\"ui-inputgroup spacing\" >\n\t<hpe-form-label [icon]=\"icon\" [label]=\"label\"></hpe-form-label>\n <textarea pInputTextarea [style.height]=\"height\" [(ngModel)]=\"value\" [ngClass]=\"getComponentClass()\" [disabled]=\"!enabled\"></textarea>\n</div>\n", styles: [".spacing{margin-bottom:1rem}.control{width:100%}.required,.required:focus{border-right:5px solid #ff8d6d}.provided,.provided:focus{border-right:5px solid #00a982}"], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: InputArea, multi: true }] },] }, ]; /** @nocollapse */ InputArea.ctorParameters = function () { return []; }; InputArea.propDecorators = { "height": [{ type: Input },], }; return InputArea; }(InputText)); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var InputCheckbox = /** @class */ (function (_super) { __extends(InputCheckbox, _super); //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function InputCheckbox() { return _super.call(this) || this; } InputCheckbox.decorators = [ { type: Component, args: [{ selector: 'hpe-input-checkbox', template: "<!--\n=============================================================================\n===\n=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.\n===\n=== Use of this source code is governed by an MIT-style license that can be\n=== found in the LICENSE file\n=============================================================================\n-->\n\n<div class=\"ui-inputgroup spacing\">\n\t<hpe-form-label [icon]=\"icon\" [label]=\"label\"></hpe-form-label>\n\t<mat-checkbox [(ngModel)]=\"value\" [ngClass]=\"getComponentClass()\" [disabled]=\"!enabled\"></mat-checkbox>\n</div>\n", styles: [".spacing{margin-bottom:1rem}.control{width:100%;margin-top:4px;margin-left:10px}.required{border-right:5px solid #ff8d6d}.provided{border-right:5px solid #00a982}:host ::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background{background-color:#80746e}"], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: InputCheckbox, multi: true }] },] }, ]; /** @nocollapse */ InputCheckbox.ctorParameters = function () { return []; }; return InputCheckbox; }(InputText)); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var InputCombo = /** @class */ (function (_super) { __extends(InputCombo, _super); //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function InputCombo() { return _super.call(this) || this; } Object.defineProperty(InputCombo.prototype, "dataMap", { get: /** * @return {?} */ function () { return this._dataMap; }, //------------------------------------------------------------------------- set: /** * @param {?} map * @return {?} */ function (map) { this._dataMap = map; this.key = "id"; this.value = "value"; var /** @type {?} */ list = []; if (!this.required) { list.push({ "id": null, "value": null }); } for (var /** @type {?} */ key in map) { var /** @type {?} */ name_1 = Number(key); var /** @type {?} */ value = map[key]; if (isNaN(name_1)) { name_1 = key; } list.push({ "id": name_1, "value": value }); } this.data = list; }, enumerable: true, configurable: true }); /** * @param {?} keyValue * @return {?} */ InputCombo.prototype.writeValue = /** * @param {?} keyValue * @return {?} */ function (keyValue) { var _this = this; var /** @type {?} */ item = this.data.find(function (item) { return (item[_this.key] == keyValue); }); //--- Select first entry in case there is no match if (item == null) { if (this.data != null && this.data.length > 0) { item = this.data[0]; } } this._selectedItem = item; }; Object.defineProperty(InputCombo.prototype, "selectedItem", { //------------------------------------------------------------------------- get: /** * @return {?} */ function () { return this._selectedItem; }, //------------------------------------------------------------------------- set: /** * @param {?} newItem * @return {?} */ function (newItem) { this._selectedItem = newItem; this.onChange(newItem[this.key]); }, enumerable: true, configurable: true }); //------------------------------------------------------------------------- //--- //--- Protected methods //--- //------------------------------------------------------------------------- /** * @return {?} */ InputCombo.prototype.isProvided = /** * @return {?} */ function () { return (this.selectedItem != null && this.selectedItem[this.key] != null); }; InputCombo.decorators = [ { type: Component, args: [{ selector: 'hpe-input-combo', template: "<!--\n=============================================================================\n===\n=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.\n===\n=== Use of this source code is governed by an MIT-style license that can be\n=== found in the LICENSE file\n=============================================================================\n-->\n\n<div class=\"ui-inputgroup spacing\">\n\t<hpe-form-label [icon]=\"icon\" [label]=\"label\"></hpe-form-label>\n\n\t<p-dropdown [options] = \"data\"\n\t\t\t\t[dataKey] = \"key\"\n\t\t\t\t[optionLabel]= \"value\"\n\t\t\t\t[(ngModel)] = \"selectedItem\"\n\t\t\t\t[ngClass] = \"getComponentClass()\"\n\t\t\t\t[style] = \"{ 'width':'100%' }\"\n\t\t\t\t[disabled] = \"!enabled\">\n\t</p-dropdown>\n</div>\n", styles: [".spacing{margin-bottom:1rem}.control{width:100%}.required{border-right:5px solid #ff8d6d}.provided{border-right:5px solid #00a982}"], providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: InputCombo, multi: true }] },] }, ]; /** @nocollapse */ InputCombo.ctorParameters = function () { return []; }; InputCombo.propDecorators = { "key": [{ type: Input },], "value": [{ type: Input },], "data": [{ type: Input },], "dataMap": [{ type: Input },], }; return InputCombo; }(AbstractFormComponent)); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var LoginPanel = /** @class */ (function (_super) { __extends(LoginPanel, _super); //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function LoginPanel(eventBusService, sessionService, notificationService, labelService, httpService) { var _this = _super.call(this, eventBusService) || this; _this.sessionService = sessionService; _this.notificationService = notificationService; _this.labelService = labelService; _this.httpService = httpService; //------------------------------------------------------------------------- //--- //--- Variables //--- //------------------------------------------------------------------------- _this.cred = new Credentials(); _super.prototype.subscribeToApp.call(_this, AppEvent.LOGIN_FAILED, function (event) { return _this.onLoginFailed(event); }); return _this; } /** * @return {?} */ LoginPanel.prototype.login = /** * @return {?} */ function () { if (!this.areCredentialsValid()) { var /** @type {?} */ msg = this.labelService.getLabel("login-panel", "missing.info"); this.notificationService.showWarn(msg["title"], msg["descr"]); } else { this.sessionService.login(this.cred); } }; Object.defineProperty(LoginPanel.prototype, "title", { //------------------------------------------------------------------------- //--- Localized strings //------------------------------------------------------------------------- get: /** * @return {?} */ function () { return this.loc("title"); }, enumerable: true, configurable: true }); Object.defineProperty(LoginPanel.prototype, "username", { //------------------------------------------------------------------------- get: /** * @return {?} */ function () { return this.loc("username"); }, enumerable: true, configurable: true }); Object.defineProperty(LoginPanel.prototype, "password", { //------------------------------------------------------------------------- get: /** * @return {?} */ function () { return this.loc("password"); }, enumerable: true, configurable: true }); Object.defineProperty(LoginPanel.prototype, "button", { //------------------------------------------------------------------------- get: /** * @return {?} */ function () { return this.loc("button"); }, enumerable: true, configurable: true }); /** * @param {?} event * @return {?} */ LoginPanel.prototype.onLoginFailed = /** * @param {?} event * @return {?} */ function (event) { var /** @type {?} */ msg = this.labelService.getLabel("login-panel", "login.error"); this.notificationService.showError(msg["title"], msg["descr"]); }; /** * @return {?} */ LoginPanel.prototype.areCredentialsValid = /** * @return {?} */ function () { return Lib.str.isProvided(this.cred.username) && Lib.str.isProvided(this.cred.password); }; /** * @param {?} code * @return {?} */ LoginPanel.prototype.loc = /** * @param {?} code * @return {?} */ function (code) { return this.labelService.getLabel("login-panel", code); }; LoginPanel.decorators = [ { type: Component, args: [{ selector: 'hpe-login', template: "<!--\n=============================================================================\n===\n=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.\n===\n=== Use of this source code is governed by an MIT-style license that can be\n=== found in the LICENSE file\n=============================================================================\n-->\n\n<hpe-card-panel icon=\"fa-sign-in\" [title]=\"title\" [toggleButton]=\"false\">\n\t<div cpBody>\n\t\t<hpe-form-panel>\n\n\t\t\t<hpe-form-column width=\"500px\">\n\t\t\t\t<hpe-input-text icon=\"fa-user\" [label]=\"username\" [(ngModel)]=\"cred.username\" required></hpe-input-text>\n\t\t\t\t<hpe-input-text icon=\"fa-key\" [label]=\"password\" [(ngModel)]=\"cred.password\" required></hpe-input-text>\n\t\t\t</hpe-form-column>\n\n\t\t</hpe-form-panel>\n\n\t\t<hpe-button-panel>\n\t\t\t<div class=\"spinner\" *ngIf=\"httpService.loading\">\n\t\t\t\t<i class=\"fa fa-circle-o-notch fa-pulse\"></i>\n\t\t\t</div>\n\t\t\t<button mat-button hpeButton (click)=\"login()\">{{button}}</button>\n\t\t</hpe-button-panel>\n\t</div>\n</hpe-card-panel>\n\n\n\n", styles: [".spinner{position:absolute;left:16px;bottom:16px;font-size:32px}"] },] }, ]; /** @nocollapse */ LoginPanel.ctorParameters = function () { return [ { type: EventBusService, }, { type: SessionService, }, { type: NotificationService, }, { type: LabelService, }, { type: HttpService, }, ]; }; return LoginPanel; }(AbstractSubscriber)); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var HpeFormModule = /** @class */ (function () { function HpeFormModule() { } HpeFormModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule, FormsModule, MatCheckboxModule, MatButtonModule, DropdownModule, InputTextModule, HpePanelModule, HpeDirectiveModule, HpeServiceModule ], declarations: [ FormColumn, FormLabel, FormPanel, FormText, InputArea, InputCheckbox, InputCombo, InputText, LoginPanel ], exports: [ FormColumn, FormLabel, FormPanel, FormText, InputArea, InputCheckbox, InputCombo, InputText, LoginPanel ], providers: [], },] }, ]; return HpeFormModule; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ export { HpeFormModule, FormColumn, FormLabel, FormPanel, FormText, InputArea, InputCheckbox, InputCombo, InputText, LoginPanel, AbstractFormComponent as ɵa }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHBlLWFuZ3VsYXItdG9vbGtpdC1ndWktZm9ybS5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQGhwZS9hbmd1bGFyLXRvb2xraXQvZ3VpL2Zvcm0vZm9ybS1jb2x1bW4vZm9ybS1jb2x1bW4udHMiLCJuZzovL0BocGUvYW5ndWxhci10b29sa2l0L2d1aS9mb3JtL2Zvcm0tbGFiZWwvZm9ybS1sYWJlbC50cyIsIm5nOi8vQGhwZS9hbmd1bGFyLXRvb2xraXQvZ3VpL2Zvcm0vZm9ybS1wYW5lbC9mb3JtLXBhbmVsLnRzIiwibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9ndWkvZm9ybS9mb3JtLXRleHQvZm9ybS10ZXh0LnRzIiwibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9ndWkvZm9ybS9hYnN0cmFjdC1mb3JtLWNvbXBvbmVudC50cyIsIm5nOi8vQGhwZS9hbmd1bGFyLXRvb2xraXQvZ3VpL2Zvcm0vaW5wdXQtdGV4dC9pbnB1dC10ZXh0LnRzIiwibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9ndWkvZm9ybS9pbnB1dC1hcmVhL2lucHV0LWFyZWEudHMiLCJuZzovL0BocGUvYW5ndWxhci10b29sa2l0L2d1aS9mb3JtL2lucHV0LWNoZWNrYm94L2lucHV0LWNoZWNrYm94LnRzIiwibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9ndWkvZm9ybS9pbnB1dC1jb21iby9pbnB1dC1jb21iby50cyIsIm5nOi8vQGhwZS9hbmd1bGFyLXRvb2xraXQvZ3VpL2Zvcm0vbG9naW4vbG9naW4udHMiLCJuZzovL0BocGUvYW5ndWxhci10b29sa2l0L2d1aS9mb3JtL21vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLz09PVxuLy89PT0gKEMpIENvcHlyaWdodCAyMDE4IEhld2xldHQgUGFja2FyZCBFbnRlcnByaXNlIERldmVsb3BtZW50IExQLlxuLy89PT1cbi8vPT09IFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4vLz09PSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmltcG9ydCB7Q29tcG9uZW50LCBJbnB1dH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yICAgIDogICAgICdocGUtZm9ybS1jb2x1bW4nLFxuXHR0ZW1wbGF0ZTogYDwhLS1cbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG49PT1cbj09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG49PT1cbj09PSBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4tLT5cblxuPGRpdiBjbGFzcz1cImZvcm1Db2x1bW5cIiBbc3R5bGUud2lkdGhdPVwid2lkdGhcIj5cbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG48L2Rpdj5cbmAsXG5cdHN0eWxlczogW2AuZm9ybUNvbHVtbntkaXNwbGF5OmZsZXg7ZmxleC1kaXJlY3Rpb246Y29sdW1uO2FsaWduLWNvbnRlbnQ6Y2VudGVyO2p1c3RpZnktY29udGVudDpmbGV4LXN0YXJ0O21hcmdpbjo4cHh9YF0sXG59KVxuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmV4cG9ydCBjbGFzcyBGb3JtQ29sdW1uICAgIHtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gVmFyaWFibGVzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdEBJbnB1dCgpIHdpZHRoIDogc3RyaW5nO1xufVxuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iLCIvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLz09PVxuLy89PT0gKEMpIENvcHlyaWdodCAyMDE4IEhld2xldHQgUGFja2FyZCBFbnRlcnByaXNlIERldmVsb3BtZW50IExQLlxuLy89PT1cbi8vPT09IFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4vLz09PSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmltcG9ydCB7Q29tcG9uZW50LCBJbnB1dH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yICAgIDogICAgICdocGUtZm9ybS1sYWJlbCcsXG5cdHRlbXBsYXRlOiBgPCEtLVxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbj09PVxuPT09IChDKSBDb3B5cmlnaHQgMjAxOCBIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBEZXZlbG9wbWVudCBMUC5cbj09PVxuPT09IFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG49PT0gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi0tPlxuXG48c3BhbiBjbGFzcz1cInVpLWlucHV0Z3JvdXAtYWRkb24gbGFiZWxcIj5cblx0PGhwZS1pY29uIG5hbWU9XCJ7e2ljb259fVwiPjwvaHBlLWljb24+IHt7bGFiZWx9fVxuPC9zcGFuPlxuYCxcblx0c3R5bGVzOiBbYC5sYWJlbHt3aWR0aDoxMnJlbTt0ZXh0LWFsaWduOnN0YXJ0IWltcG9ydGFudH06aG9zdCA6Om5nLWRlZXAgLmljb25TdHlsZXt2ZXJ0aWNhbC1hbGlnbjpiYXNlbGluZX1gXSxcbn0pXG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGNsYXNzIEZvcm1MYWJlbCAgICB7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFZhcmlhYmxlc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRASW5wdXQoKSBpY29uICA6IHN0cmluZztcblx0QElucHV0KCkgbGFiZWwgOiBzdHJpbmc7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIENvbnN0cnVjdG9yXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdGNvbnN0cnVjdG9yKCkge31cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQVBJIG1ldGhvZHNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG59XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIsIi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vPT09XG4vLz09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG4vLz09PVxuLy89PT0gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbi8vPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW1wb3J0IHtDb21wb25lbnR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvciAgICA6ICAgICAnaHBlLWZvcm0tcGFuZWwnLFxuXHR0ZW1wbGF0ZTogYDwhLS1cbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG49PT1cbj09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG49PT1cbj09PSBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4tLT5cblxuPGRpdiBjbGFzcz1cImZvcm1Cb2R5XCI+XG5cdDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbjwvZGl2PlxuYCxcblx0c3R5bGVzOiBbYC5mb3JtQm9keXtkaXNwbGF5OmZsZXg7YWxpZ24tY29udGVudDpjZW50ZXI7anVzdGlmeS1jb250ZW50OmNlbnRlcjtmbGV4LXdyYXA6d3JhcDtib3gtc2l6aW5nOmJvcmRlci1ib3g7d2lkdGg6MTAwJTttYXgtd2lkdGg6MTAwJTtwYWRkaW5nOjFyZW07YmFja2dyb3VuZDojZmFmYWZhO2NvbG9yOiMwMDA7Zm9udC1zaXplOjFyZW19YF0sXG59KVxuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmV4cG9ydCBjbGFzcyBGb3JtUGFuZWwgICAge1xufVxuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iLCIvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLz09PVxuLy89PT0gKEMpIENvcHlyaWdodCAyMDE4IEhld2xldHQgUGFja2FyZCBFbnRlcnByaXNlIERldmVsb3BtZW50IExQLlxuLy89PT1cbi8vPT09IFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4vLz09PSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmltcG9ydCB7Q29tcG9uZW50LElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1RyYW5zY29kZXJ9ICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvciAgICA6ICAgICAnaHBlLWZvcm0tdGV4dCcsXG5cdHRlbXBsYXRlOiBgPCEtLVxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbj09PVxuPT09IChDKSBDb3B5cmlnaHQgMjAxOCBIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBEZXZlbG9wbWVudCBMUC5cbj09PVxuPT09IFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG49PT0gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi0tPlxuXG48ZGl2IGNsYXNzPVwidWktaW5wdXRncm91cCBzcGFjaW5nXCI+XG5cdDxocGUtZm9ybS1sYWJlbCBbaWNvbl09XCJpY29uXCIgW2xhYmVsXT1cImxhYmVsXCI+PC9ocGUtZm9ybS1sYWJlbD5cblx0PHNwYW4gY2xhc3M9XCJ1aS1pbnB1dGdyb3VwLWFkZG9uIHRleHRcIj57e3ZhbHVlfX08L3NwYW4+XG48L2Rpdj5cbmAsXG5cdHN0eWxlczogW2Auc3BhY2luZ3ttYXJnaW4tYm90dG9tOjFyZW19LnRleHR7YmFja2dyb3VuZC1jb2xvcjojZjVmNWY1O3dpZHRoOjEwMCU7Y29sb3I6IzIwMjAyMH1gXVxufSlcblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgY2xhc3MgRm9ybVRleHQge1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBWYXJpYWJsZXNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0QElucHV0KCkgaWNvbiAgICAgICA6IHN0cmluZztcblx0QElucHV0KCkgbGFiZWwgICAgICA6IHN0cmluZztcblx0QElucHV0KCkgdHJhbnNjb2RlciA6IFRyYW5zY29kZXI7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSBfdmFsdWUgOiBzdHJpbmc7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIENvbnN0cnVjdG9yXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdGNvbnN0cnVjdG9yKCkge31cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQVBJIG1ldGhvZHNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0QElucHV0KClcblx0Z2V0IHZhbHVlKCkgOiBzdHJpbmcge1xuXHRcdHJldHVybiB0aGlzLl92YWx1ZTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHNldCB2YWx1ZSh2YWx1ZSkge1xuXG5cdFx0aWYgKHRoaXMudHJhbnNjb2RlciAmJiB2YWx1ZSE9bnVsbCkge1xuXHRcdFx0dmFsdWUgPSAgdGhpcy50cmFuc2NvZGVyLnRyYW5zY29kZSh2YWx1ZSk7XG5cdFx0fVxuXG5cdFx0dGhpcy5fdmFsdWUgPSB2YWx1ZTtcblx0fVxufVxuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iLCIvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLz09PVxuLy89PT0gKEMpIENvcHlyaWdodCAyMDE4IEhld2xldHQgUGFja2FyZCBFbnRlcnByaXNlIERldmVsb3BtZW50IExQLlxuLy89PT1cbi8vPT09IFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4vLz09PSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmltcG9ydCB7SW5wdXR9ICAgICAgICAgICAgICAgIGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtDb250cm9sVmFsdWVBY2Nlc3Nvcn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdEZvcm1Db21wb25lbnQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFZhcmlhYmxlc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRASW5wdXQoKSBpY29uICAgIDogc3RyaW5nO1xuXHRASW5wdXQoKSBsYWJlbCAgIDogc3RyaW5nO1xuXHRASW5wdXQoKSBlbmFibGVkIDogYm9vbGVhbjtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIF9yZXF1aXJlZCA6IGJvb2xlYW47XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJvdGVjdGVkIG9uQ2hhbmdlIDogYW55O1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBDb25zdHJ1Y3RvclxuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHR0aGlzLmVuYWJsZWQgICA9IHRydWU7XG5cdFx0dGhpcy5fcmVxdWlyZWQgPSBmYWxzZTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBBUEkgbWV0aG9kc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRyZWdpc3Rlck9uQ2hhbmdlKGZuKSB7XG5cdFx0dGhpcy5vbkNoYW5nZSA9IGZuO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cmVnaXN0ZXJPblRvdWNoZWQoZm4pIHt9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIGdldENvbXBvbmVudENsYXNzKCkgOiBzdHJpbmdbXSB7XG5cblx0XHRsZXQgc3R5bGVzIDogc3RyaW5nW10gPSBbICdjb250cm9sJyBdO1xuXG5cdFx0aWYgKHRoaXMuZW5hYmxlZCkge1xuXHRcdFx0aWYgKHRoaXMucmVxdWlyZWQpIHtcblx0XHRcdFx0aWYgKHRoaXMuaXNQcm92aWRlZCgpKSB7XG5cdFx0XHRcdFx0c3R5bGVzLnB1c2goXCJwcm92aWRlZFwiKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRzdHlsZXMucHVzaChcInJlcXVpcmVkXCIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0c3R5bGVzLnB1c2goXCJkaXNhYmxlZFwiKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gc3R5bGVzO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tICdyZXF1aXJlZCcgYXR0cmlidXRlXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdEBJbnB1dCgpXG5cdGdldCByZXF1aXJlZCgpIDogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuX3JlcXVpcmVkO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0c2V0IHJlcXVpcmVkKHZhbHVlOmJvb2xlYW4pIHtcblxuXHRcdGxldCBzdHIgOiBzdHJpbmcgPSBcIlwiK3ZhbHVlO1xuXG5cdFx0aWYgKHN0ciA9PSBcIlwiKSB7XG5cdFx0XHQvLy0tLSBPaywgJycgbWVhbnMgdmFsdWUgbm90IHByb3ZpZGVkIC0tPiB0cnVlXG5cdFx0XHR2YWx1ZSA9IHRydWU7XG5cdFx0fVxuXG5cdFx0dGhpcy5fcmVxdWlyZWQgPSB2YWx1ZTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLSBBYnN0cmFjdCBtZXRob2RzXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBhYnN0cmFjdCB3cml0ZVZhbHVlKHZhbHVlKSA6IHZvaWQ7XG5cblx0cHJvdGVjdGVkIGFic3RyYWN0IGlzUHJvdmlkZWQoKSA6IGJvb2xlYW47XG59XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIsIi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vPT09XG4vLz09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG4vLz09PVxuLy89PT0gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbi8vPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW1wb3J0IHtDb21wb25lbnQgfSAgICAgICAgZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge05HX1ZBTFVFX0FDQ0VTU09SfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge0xpYn0gICAgICAgICAgICAgICBmcm9tIFwiQGhwZS9hbmd1bGFyLXRvb2xraXQvbGliXCI7XG5cbmltcG9ydCB7QWJzdHJhY3RGb3JtQ29tcG9uZW50fSBmcm9tIFwiLi4vYWJzdHJhY3QtZm9ybS1jb21wb25lbnRcIjtcblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3IgICAgOiAgICAgJ2hwZS1pbnB1dC10ZXh0Jyxcblx0dGVtcGxhdGU6IGA8IS0tXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuPT09XG49PT0gKEMpIENvcHlyaWdodCAyMDE4IEhld2xldHQgUGFja2FyZCBFbnRlcnByaXNlIERldmVsb3BtZW50IExQLlxuPT09XG49PT0gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbj09PSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLS0+XG5cbjxkaXYgY2xhc3M9XCJ1aS1pbnB1dGdyb3VwIHNwYWNpbmdcIj5cbiAgICA8aHBlLWZvcm0tbGFiZWwgW2ljb25dPVwiaWNvblwiIFtsYWJlbF09XCJsYWJlbFwiPjwvaHBlLWZvcm0tbGFiZWw+XG5cdDxpbnB1dCBwSW5wdXRUZXh0IFsobmdNb2RlbCldPVwidmFsdWVcIiBbbmdDbGFzc109XCJnZXRDb21wb25lbnRDbGFzcygpXCIgW2Rpc2FibGVkXT1cIiFlbmFibGVkXCI+XG48L2Rpdj5cblxuYCxcblx0c3R5bGVzOiBbYC5zcGFjaW5ne21hcmdpbi1ib3R0b206MXJlbX0uY29udHJvbHt3aWR0aDoxMDAlfS5yZXF1aXJlZCwucmVxdWlyZWQ6Zm9jdXN7Ym9yZGVyLXJpZ2h0OjVweCBzb2xpZCAjZmY4ZDZkfS5wcm92aWRlZCwucHJvdmlkZWQ6Zm9jdXN7Ym9yZGVyLXJpZ2h0OjVweCBzb2xpZCAjMDBhOTgyfWBdLFxuXHRwcm92aWRlcnMgICA6IFsge1xuXHRcdHByb3ZpZGUgICAgOiBOR19WQUxVRV9BQ0NFU1NPUixcblx0XHR1c2VFeGlzdGluZzogSW5wdXRUZXh0LFxuXHRcdG11bHRpICAgICAgOiB0cnVlXG5cdH1dXG59KVxuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmV4cG9ydCBjbGFzcyBJbnB1dFRleHQgZXh0ZW5kcyBBYnN0cmFjdEZvcm1Db21wb25lbnQge1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBWYXJpYWJsZXNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSBfdmFsdWUgOiBzdHJpbmc7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIENvbnN0cnVjdG9yXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQVBJIG1ldGhvZHNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIHdyaXRlVmFsdWUodmFsdWUpIHtcblx0XHR0aGlzLl92YWx1ZSA9IHZhbHVlO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0Z2V0IHZhbHVlKCkgOiBzdHJpbmcge1xuXHRcdHJldHVybiB0aGlzLl92YWx1ZTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHNldCB2YWx1ZShuZXdWYWx1ZSkge1xuXHRcdGlmKG5ld1ZhbHVlPT1cIlwiKXtcbiAgICAgICAgICAgIG5ld1ZhbHVlPW51bGw7XG4gICAgICAgIH1cblx0XHR0aGlzLl92YWx1ZSA9IG5ld1ZhbHVlO1xuXHRcdHRoaXMub25DaGFuZ2UobmV3VmFsdWUpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFByb3RlY3RlZCBtZXRob2RzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByb3RlY3RlZCBpc1Byb3ZpZGVkKCkgOiBib29sZWFuIHtcblx0XHRyZXR1cm4gTGliLnN0ci5pc1Byb3ZpZGVkKHRoaXMudmFsdWUpO1xuXHR9XG59XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIsIi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vPT09XG4vLz09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG4vLz09PVxuLy89PT0gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbi8vPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW1wb3J0IHtDb21wb25lbnQsIElucHV0fSAgZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge05HX1ZBTFVFX0FDQ0VTU09SfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7SW5wdXRUZXh0fSBmcm9tIFwiLi4vaW5wdXQtdGV4dC9pbnB1dC10ZXh0XCI7XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICAgICAgJ2hwZS1pbnB1dC1hcmVhJyxcbiAgICB0ZW1wbGF0ZTogYDwhLS1cbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG49PT1cbj09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG49PT1cbj09PSBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0