UNPKG

svogv

Version:

A decorator based approach for model driven forms, including an advanced DataGrid and a TreeView component.

152 lines 21.8 kB
import { Component, Input, Output } from '@angular/core'; import { FormGroup } from '@angular/forms'; /** * The Editor Widget. Creates a field with all required validators using decorators and forms service. */ export class EditorComponent { constructor() { /** * Editor type. Default is 'text'; */ this.type = 'text'; /** * A character after the fields label. Default is ': ' (colon plus space); */ this.labelDivider = ': '; /** * If set to true the label and the field appears in one row. * Otherwise the label is above the field. Default is `true`. */ this.inline = true; /** * The start value for a range field. Other field types ignore this value. */ this.fromValue = 0; /** * The end value for a range field. Other field types ignore this value. */ this.toValue = 100; /** * An optional placeholder for empty field. The default is empty (no watermark). */ this.waterMark = ''; /** * Renders the field as read only. */ this.readonly = false; this.params = new Array(); } getParams(key) { return this.first(this.params.filter((e) => e.key === key), 0); } first(array, n) { if (array == null) { return void 0; } if (n == null) { return array[0]; } if (n < 0) { return []; } return array.slice(0, n); } ngOnInit() { this.formGroup.valueChanges.subscribe((data) => this.onValueChanged(data)); // this is set by FormValidatorService const editorModel = this.formGroup.__editorModel__; // get type from form if (editorModel) { // get elementary types, this might get overwritten later according to decorators found if (typeof editorModel[this.name] === 'string') { this.type = 'text'; } if (typeof editorModel[this.name] === 'boolean') { this.type = 'boolean'; } if (typeof editorModel[this.name] === 'number') { this.type = 'number'; } if (editorModel[this.name] instanceof Date) { this.type = 'calendar'; } // make an instance to read the properties this.label = editorModel[`__displayName__${this.name}`] || this.label || this.name; this.tooltip = editorModel[`__displayDesc__${this.name}`] || this.tooltip || this.name; // render as range id there is a range definition if (editorModel[`__hasRangeFrom__${this.name}`] && Number(editorModel[`__hasRangeFrom__${this.name}`])) { this.fromValue = editorModel[`__hasRangeFrom__${this.name}`]; this.type = 'range'; } if (editorModel[`__hasRangeTo__${this.name}`] && Number(editorModel[`__hasRangeTo__${this.name}`])) { this.toValue = editorModel[`__hasRangeTo__${this.name}`]; this.type = 'range'; } // placeholder if (editorModel[`__hasWatermark__${this.name}`]) { this.waterMark = editorModel[`__watermark__${this.name}`]; } // templates if (editorModel[`__hasTemplateHint__${this.name}`]) { this.type = editorModel[`__templatehint__${this.name}`].toLowerCase(); if (editorModel[`__templatehintParams__${this.name}`]) { this.params = editorModel[`__templatehintParams__${this.name}`]; } } // render hidden fields as hidden even in forms if (editorModel[`__isHidden__${this.name}`]) { this.type = 'hidden'; } // check readonly if (editorModel[`__isReadonly__${this.name}`]) { this.readonly = !!editorModel[`__isReadonly__${this.name}`]; } } } onValueChanged(data) { // check validation on change this.errors = new Array(); // tslint:disable-next-line:forin for (const error in this.formGroup.controls[this.name].errors) { this.errors.push(error); } } } EditorComponent.decorators = [ { type: Component, args: [{ selector: 'ac-editor', template: "<div class=\"form-group row\"\n [formGroup]=\"formGroup\"\n *ngIf=\"type != 'hidden' && formGroup\"\n [ngClass]=\"{ 'has-danger': !formGroup.controls[name].valid && formGroup.controls[name].touched }\">\n <label class=\"col-form-label col-md-3 col-sm-10\"\n [attr.for]=\"name\"\n [attr.title]=\"tooltip\" >{{ label }}{{ labelDivider }} </label>\n <div [ngClass]=\"{ 'col-md-7 col-sm-10': inline }\">\n <textarea *ngIf=\"type == 'textarea'\"\n class=\"form-control\"\n [id]=\"name\"\n [readOnly]='readonly'\n [formControlName]=\"name\"\n [attr.rows]=\"getParams('rows')\"\n [attr.cols]=\"getParams('cols')\">\n </textarea>\n <select *ngIf=\"type == 'enum' && enumValues\" class=\"form-control\" [id]=\"name\"\n [formControlName]=\"name\" [disabled]='readonly'>\n <option *ngFor=\"let option of enumValues\" [value]=\"option.key\">{{option.val}}</option>\n </select>\n <select *ngIf=\"type == 'list' && listValues\" class=\"form-control\" [id]=\"name\"\n [formControlName]=\"name\" [disabled]='readonly'>\n <option *ngFor=\"let option of listValues\" [value]=\"option.key\">{{option.val}}</option>\n </select>\n <input *ngIf=\"type == 'range'\" type=\"range\"\n class=\"form-control\"\n [placeholder]=\"waterMark\"\n [attr.minvalue]=\"fromValue\"\n [attr.maxvalue]=\"toValue\"\n [attr.min]=\"fromValue\"\n [attr.max]=\"toValue\"\n [id]=\"name\"\n [formControlName]=\"name\"\n [title]=\"tooltip\" />\n <input *ngIf=\"type == 'calendar'\" type=\"date\"\n class=\"form-control\"\n [placeholder]=\"waterMark\"\n [readOnly]='readonly'\n [id]=\"name\"\n [formControlName]=\"name\"\n [title]=\"tooltip\" />\n <input *ngIf=\"type == 'number'\" type=\"number\"\n class=\"form-control\"\n [placeholder]=\"waterMark\"\n [readOnly]='readonly'\n [id]=\"name\"\n [formControlName]=\"name\"\n [title]=\"tooltip\" />\n <input *ngIf=\"type == 'boolean'\" type=\"checkbox\"\n class=\"form-control\"\n [readOnly]='readonly'\n [id]=\"name\"\n [formControlName]=\"name\"\n [title]=\"tooltip\" />\n <label *ngIf=\"type == 'boolean'\" [attr.for]=\"name\"></label>\n <input *ngIf=\"type == 'text' || type == ''\" [placeholder]=\"waterMark\"\n [readOnly]='readonly'\n type=\"text\" class=\"form-control\" [id]=\"name\" [formControlName]=\"name\" />\n <ng-container *ngIf=\"type == 'template'\">\n <ng-content></ng-content>\n </ng-container>\n <span class=\"fa fa-warning text-danger form-control-feedback\"\n [hidden]=\"formGroup.controls[name].valid || formGroup.controls[name].pristine\"></span>\n <small class=\"text-danger\"\n [hidden]=\"formGroup.controls[name].valid || formGroup.controls[name].pristine\">\n <span *ngFor=\"let error of errors\">{{ formGroup.controls[name]['messages'][error] }}</span>\n </small>\n </div>\n</div>\n<div>\n <input *ngIf=\"type == 'hidden'\" [id]=\"name\" [formControlName]=\"name\" type=\"hidden\" />\n</div>\n", styles: ['input[type="checkbox"] { display: none; }', 'input[type="checkbox"] + label:before { font-family: FontAwesome; }', 'input[type="checkbox"] + label:before { content: "\\f096"; }', 'input[type="checkbox"]:checked + label:before { content: "\\f046"; }', ` input[type='checkbox'] + label { display: inline-block; width: 15px; height: 20px; margin: -1px 4px 0 0; vertical-align: middle; cursor: pointer; } `] },] } ]; EditorComponent.ctorParameters = () => []; EditorComponent.propDecorators = { name: [{ type: Input }], type: [{ type: Input }], labelDivider: [{ type: Input }], label: [{ type: Input }], tooltip: [{ type: Input }], formGroup: [{ type: Input }], inline: [{ type: Input }], enumValues: [{ type: Input }], listValues: [{ type: Input }], fromValue: [{ type: Input }], toValue: [{ type: Input }], waterMark: [{ type: Input }], readonly: [{ type: Input }], value: [{ type: Output }, { type: Input }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLi8uLi9wcm9qZWN0cy9zdm9ndi9zcmMvIiwic291cmNlcyI6WyJsaWIvd2lkZ2V0cy9lZGl0b3JzL2VkaXRvci9lZGl0b3IuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUNqRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0M7O0dBRUc7QUFxQkgsTUFBTSxPQUFPLGVBQWU7SUFtRTFCO1FBOURBOztXQUVHO1FBQ2EsU0FBSSxHQUFHLE1BQU0sQ0FBQztRQUM5Qjs7V0FFRztRQUNhLGlCQUFZLEdBQUcsSUFBSSxDQUFDO1FBYXBDOzs7V0FHRztRQUNhLFdBQU0sR0FBRyxJQUFJLENBQUM7UUFVOUI7O1dBRUc7UUFDYSxjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQzlCOztXQUVHO1FBQ2EsWUFBTyxHQUFHLEdBQUcsQ0FBQztRQUM5Qjs7V0FFRztRQUNhLGNBQVMsR0FBRyxFQUFFLENBQUM7UUFDL0I7O1dBRUc7UUFDYSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBYy9CLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQStCLENBQUM7SUFDekQsQ0FBQztJQUVNLFNBQVMsQ0FBQyxHQUFXO1FBQzFCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRU0sS0FBSyxDQUFDLEtBQW9DLEVBQUUsQ0FBUztRQUMxRCxJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUU7WUFDakIsT0FBTyxLQUFLLENBQUMsQ0FBQztTQUNmO1FBQ0QsSUFB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QUFLO29CQUlMLEtBQUs7c0JBSUwsS0FBSzt3QkFJTCxLQUFLO3FCQUtMLEtBQUs7eUJBSUwsS0FBSzt5QkFLTCxLQUFLO3dCQUlMLEtBQUs7c0JBSUwsS0FBSzt3QkFJTCxLQUFLO3VCQUlMLEtBQUs7b0JBSUwsTUFBTSxZQUNOLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG4vKipcbiAqIFRoZSBFZGl0b3IgV2lkZ2V0LiBDcmVhdGVzIGEgZmllbGQgd2l0aCBhbGwgcmVxdWlyZWQgdmFsaWRhdG9ycyB1c2luZyBkZWNvcmF0b3JzIGFuZCBmb3JtcyBzZXJ2aWNlLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhYy1lZGl0b3InLFxuICBzdHlsZXM6IFtcbiAgICAnaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdIHsgZGlzcGxheTogbm9uZTsgfScsXG4gICAgJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXSArIGxhYmVsOmJlZm9yZSB7IGZvbnQtZmFtaWx5OiBGb250QXdlc29tZTsgfScsXG4gICAgJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXSArIGxhYmVsOmJlZm9yZSB7IGNvbnRlbnQ6IFwiXFxcXGYwOTZcIjsgfScsXG4gICAgJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXTpjaGVja2VkICsgbGFiZWw6YmVmb3JlIHsgY29udGVudDogXCJcXFxcZjA0NlwiOyB9JyxcbiAgICBgXG4gICAgICBpbnB1dFt0eXBlPSdjaGVja2JveCddICsgbGFiZWwge1xuICAgICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgICAgIHdpZHRoOiAxNXB4O1xuICAgICAgICBoZWlnaHQ6IDIwcHg7XG4gICAgICAgIG1hcmdpbjogLTFweCA0cHggMCAwO1xuICAgICAgICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICB9XG4gICAgYFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vZWRpdG9yLmNvbXBvbmVudC5odG1sJ1xufSkgLy9cbmV4cG9ydCBjbGFzcyBFZGl0b3JDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvKipcbiAgICogRmllbGQgbmFtZVxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIEVkaXRvciB0eXBlLiBEZWZhdWx0IGlzICd0ZXh0JztcbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyB0eXBlID0gJ3RleHQnO1xuICAvKipcbiAgICogQSBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGZpZWxkcyBsYWJlbC4gRGVmYXVsdCBpcyAnOiAnIChjb2xvbiBwbHVzIHNwYWNlKTtcbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBsYWJlbERpdmlkZXIgPSAnOiAnO1xuICAvKipcbiAgICogVGhlIGxhYmVsJ3MgbmFtZS5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBsYWJlbDogc3RyaW5nO1xuICAvKipcbiAgICogQSB0b29sdGlwXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgdG9vbHRpcDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGZvcm0ncyBncm91cCBvYmplY3QuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgZm9ybUdyb3VwOiBGb3JtR3JvdXA7XG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gdHJ1ZSB0aGUgbGFiZWwgYW5kIHRoZSBmaWVsZCBhcHBlYXJzIGluIG9uZSByb3cuXG4gICAqIE90aGVyd2lzZSB0aGUgbGFiZWwgaXMgYWJvdmUgdGhlIGZpZWxkLiBEZWZhdWx0IGlzIGB0cnVlYC5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBpbmxpbmUgPSB0cnVlO1xuICAvKipcbiAgICogVGhlIHZhbHVlcyBvZiB0aGUgc2VsZWN0IGZpZWxkIHByb3ZpZGVkIGJ5IGFuIGVudW0uIEZvciBvdGhlciBmaWVsZHR5cGVzIGl0J3MgYmVpbmcgaWdub3JlZC5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBlbnVtVmFsdWVzOiBhbnk7XG4gIC8qKlxuICAgKiBUaGUgdmFsdWVzIG9mIHRoZSBzZWxlY3QgZmllbGQgcHJvdmlkZWQgYnkgYSBsaXN0LiBGb3Igb3RoZXIgZmllbGR0eXBlcyBpdCdzIGJlaW5nIGlnbm9yZWQuXG4gICAqIFRoZSB2YWx1ZSBzaGFsbCBiZSBhbiBBcnJheSB0aGF0IGEgYCpuZ0ZvcmAgZGlyZWN0aXZlIGNhbiBleGVjdXRlLlxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIGxpc3RWYWx1ZXM6IGFueVtdO1xuICAvKipcbiAgICogVGhlIHN0YXJ0IHZhbHVlIGZvciBhIHJhbmdlIGZpZWxkLiBPdGhlciBmaWVsZCB0eXBlcyBpZ25vcmUgdGhpcyB2YWx1ZS5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBmcm9tVmFsdWUgPSAwO1xuICAvKipcbiAgICogVGhlIGVuZCB2YWx1ZSBmb3IgYSByYW5nZSBmaWVsZC4gT3RoZXIgZmllbGQgdHlwZXMgaWdub3JlIHRoaXMgdmFsdWUuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgdG9WYWx1ZSA9IDEwMDtcbiAgLyoqXG4gICAqIEFuIG9wdGlvbmFsIHBsYWNlaG9sZGVyIGZvciBlbXB0eSBmaWVsZC4gVGhlIGRlZmF1bHQgaXMgZW1wdHkgKG5vIHdhdGVybWFyaykuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgd2F0ZXJNYXJrID0gJyc7XG4gIC8qKlxuICAgKiBSZW5kZXJzIHRoZSBmaWVsZCBhcyByZWFkIG9ubHkuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgcmVhZG9ubHkgPSBmYWxzZTtcbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSBzZXQgdG8gYW5kIHJlYWQgZnJvbSB0aGUgZmllbGQuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgQElucHV0KClcbiAgcHVibGljIHZhbHVlOiBhbnk7XG5cbiAgLy8gYWRkaXRpb25hbCB2YWx1ZXMgcHJvdmlkZWQgYnkgVGVtcGxhdGVIaW50IGRlY29yYXRvclxuICBwdWJsaWMgcGFyYW1zOiB7IGtleTogc3RyaW5nOyB2YWx1ZTogYW55IH1bXTtcblxuICBwdWJsaWMgZXJyb3JzOiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLnBhcmFtcyA9IG5ldyBBcnJheTx7IGtleTogc3RyaW5nOyB2YWx1ZTogYW55IH0+KCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0UGFyYW1zKGtleTogc3RyaW5nKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5maXJzdCh0aGlzLnBhcmFtcy5maWx0ZXIoKGUpID0+IGUua2V5ID09PSBrZXkpLCAwKTtcbiAgfVxuXG4gIHB1YmxpYyBmaXJzdChhcnJheTogeyBrZXk6IHN0cmluZzsgdmFsdWU6IGFueSB9W10sIG46IG51bWJlcik6IGFueSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHtcbiAgICAgIHJldHVybiB2b2lkIDA7XG4gICAgfVxuICAgIGlmIChuID09IG51bGwpIHtcbiAgICAgIHJldHVybiBhcnJheVswXTtcbiAgICB9XG4gICAgaWYgKG4gPCAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHJldHVybiBhcnJheS5zbGljZSgwLCBuKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmZvcm1Hcm91cC52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKChkYXRhKSA9PiB0aGlzLm9uVmFsdWVDaGFuZ2VkKGRhdGEpKTtcbiAgICAvLyB0aGlzIGlzIHNldCBieSBGb3JtVmFsaWRhdG9yU2VydmljZVxuICAgIGNvbnN0IGVkaXRvck1vZGVsID0gKHRoaXMuZm9ybUdyb3VwIGFzIGFueSkuX19lZGl0b3JNb2RlbF9fO1xuICAgIC8vIGdldCB0eXBlIGZyb20gZm9ybVxuICAgIGlmIChlZGl0b3JNb2RlbCkge1xuICAgICAgLy8gZ2V0IGVsZW1lbnRhcnkgdHlwZXMsIHRoaXMgbWlnaHQgZ2V0IG92ZXJ3cml0dGVuIGxhdGVyIGFjY29yZGluZyB0byBkZWNvcmF0b3JzIGZvdW5kXG4gICAgICBpZiAodHlwZW9mIGVkaXRvck1vZGVsW3RoaXMubmFtZV0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICd0ZXh0JztcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgZWRpdG9yTW9kZWxbdGhpcy5uYW1lXSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdib29sZWFuJztcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgZWRpdG9yTW9kZWxbdGhpcy5uYW1lXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ251bWJlcic7XG4gICAgICB9XG4gICAgICBpZiAoZWRpdG9yTW9kZWxbdGhpcy5uYW1lXSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ2NhbGVuZGFyJztcbiAgICAgIH1cbiAgICAgIC8vIG1ha2UgYW4gaW5zdGFuY2UgdG8gcmVhZCB0aGUgcHJvcGVydGllc1xuICAgICAgdGhpcy5sYWJlbCA9IGVkaXRvck1vZGVsW2BfX2Rpc3BsYXlOYW1lX18ke3RoaXMubmFtZX1gXSB8fCB0aGlzLmxhYmVsIHx8IHRoaXMubmFtZTtcbiAgICAgIHRoaXMudG9vbHRpcCA9IGVkaXRvck1vZGVsW2BfX2Rpc3BsYXlEZXNjX18ke3RoaXMubmFtZX1gXSB8fCB0aGlzLnRvb2x0aXAgfHwgdGhpcy5uYW1lO1xuICAgICAgLy8gcmVuZGVyIGFzIHJhbmdlIGlkIHRoZXJlIGlzIGEgcmFuZ2UgZGVmaW5pdGlvblxuICAgICAgaWYgKGVkaXRvck1vZGVsW2BfX2hhc1JhbmdlRnJvbV9fJHt0aGlzLm5hbWV9YF0gJiYgTnVtYmVyKGVkaXRvck1vZGVsW2BfX2hhc1JhbmdlRnJvbV9fJHt0aGlzLm5hbWV9YF0pKSB7XG4gICAgICAgIHRoaXMuZnJvbVZhbHVlID0gZWRpdG9yTW9kZWxbYF9faGFzUmFuZ2VGcm9tX18ke3RoaXMubmFtZX1gXSBhcyBudW1iZXI7XG4gICAgICAgIHRoaXMudHlwZSA9ICdyYW5nZSc7XG4gICAgICB9XG4gICAgICBpZiAoZWRpdG9yTW9kZWxbYF9faGFzUmFuZ2VUb19fJHt0aGlzLm5hbWV9YF0gJiYgTnVtYmVyKGVkaXRvck1vZGVsW2BfX2hhc1JhbmdlVG9fXyR7dGhpcy5uYW1lfWBdKSkge1xuICAgICAgICB0aGlzLnRvVmFsdWUgPSBlZGl0b3JNb2RlbFtgX19oYXNSYW5nZVRvX18ke3RoaXMubmFtZX1gXSBhcyBudW1iZXI7XG4gICAgICAgIHRoaXMudHlwZSA9ICdyYW5nZSc7XG4gICAgICB9XG4gICAgICAvLyBwbGFjZWhvbGRlclxuICAgICAgaWYgKGVkaXRvck1vZGVsW2BfX2hhc1dhdGVybWFya19fJHt0aGlzLm5hbWV9YF0pIHtcbiAgICAgICAgdGhpcy53YXRlck1hcmsgPSBlZGl0b3JNb2RlbFtgX193YXRlcm1hcmtfXyR7dGhpcy5uYW1lfWBdO1xuICAgICAgfVxuICAgICAgLy8gdGVtcGxhdGVzXG4gICAgICBpZiAoZWRpdG9yTW9kZWxbYF9faGFzVGVtcGxhdGVIaW50X18ke3RoaXMubmFtZX1gXSkge1xuICAgICAgICB0aGlzLnR5cGUgPSAoZWRpdG9yTW9kZWxbYF9fdGVtcGxhdGVoaW50X18ke3RoaXMubmFtZX1gXSBhcyBzdHJpbmcpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmIChlZGl0b3JNb2RlbFtgX190ZW1wbGF0ZWhpbnRQYXJhbXNfXyR7dGhpcy5uYW1lfWBdKSB7XG4gICAgICAgICAgdGhpcy5wYXJhbXMgPSBlZGl0b3JNb2RlbFtgX190ZW1wbGF0ZWhpbnRQYXJhbXNfXyR7dGhpcy5uYW1lfWBdIGFzIHsga2V5OiBzdHJpbmc7IHZhbHVlOiBhbnkgfVtdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHJlbmRlciBoaWRkZW4gZmllbGRzIGFzIGhpZGRlbiBldmVuIGluIGZvcm1zXG4gICAgICBpZiAoZWRpdG9yTW9kZWxbYF9faXNIaWRkZW5fXyR7dGhpcy5uYW1lfWBdKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdoaWRkZW4nO1xuICAgICAgfVxuICAgICAgLy8gY2hlY2sgcmVhZG9ubHlcbiAgICAgIGlmIChlZGl0b3JNb2RlbFtgX19pc1JlYWRvbmx5X18ke3RoaXMubmFtZX1gXSkge1xuICAgICAgICB0aGlzLnJlYWRvbmx5ID0gISFlZGl0b3JNb2RlbFtgX19pc1JlYWRvbmx5X18ke3RoaXMubmFtZX1gXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uVmFsdWVDaGFuZ2VkKGRhdGE6IGFueSkge1xuICAgIC8vIGNoZWNrIHZhbGlkYXRpb24gb24gY2hhbmdlXG4gICAgdGhpcy5lcnJvcnMgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpmb3JpblxuICAgIGZvciAoY29uc3QgZXJyb3IgaW4gdGhpcy5mb3JtR3JvdXAuY29udHJvbHNbdGhpcy5uYW1lXS5lcnJvcnMpIHtcbiAgICAgIHRoaXMuZXJyb3JzLnB1c2goZXJyb3IpO1xuICAgIH1cbiAgfVxufVxuIl19