UNPKG

@rangertechnologies/ngnxt

Version:

This library was used for creating dymanic UI based on the input JSON/data

279 lines 48 kB
import { Component, Input, Output, EventEmitter, signal } from "@angular/core"; // VD 23JAN24 removed httpClient import used service file for callout import { ChangeWrapper } from "../../model/changeWrapper"; import { CommonModule } from "@angular/common"; import { FormsModule } from "@angular/forms"; import { NxtInput } from "../nxt-input/nxt-input.component"; import * as i0 from "@angular/core"; import * as i1 from "../../services/data.service"; import * as i2 from "../../i18n.service"; import * as i3 from "../../services/country.service"; import * as i4 from "@angular/common"; export class NxtSearchBox { dataService; i18nService; countryService; placeHolderText; question; apiMeta; id; readOnly = false; // VD 12Jun24 - readonly change mode = 'edit'; // SKS11JUN25 New mode input searchValueChange = new EventEmitter(); SearchItem; filterName; // VD 20Aug default filter value as input finalResults = signal([]); searchKeyWord = ''; newResult; showResult = false; noResult = false; showSuggestion = false; el; serv = 'api'; tkn = ''; isLoading = false; viewFilterName; isSingleFieldChange = false; valueObj; constructor(dataService, i18nService, countryService) { this.dataService = dataService; this.i18nService = i18nService; this.countryService = countryService; } ngOnInit() { // VD 03May- search changes // AP-26MAR25 Ensure ques.subText is always an object by parsing it if it's a string if (this.apiMeta) { this.apiMeta = typeof this.apiMeta === 'object' ? this.apiMeta : JSON.parse(this.apiMeta); this.SearchItem = this.apiMeta.field; } } ////RS 03FEB2025 // Resets state when filterName or apiMeta changes to reflect updated data // AP-26MAR25 Ensure ques.subText is always an object by parsing it if it's a string ngOnChanges(changes) { if (changes['mode']) { this.mode = changes['mode'].currentValue; } if (this.mode !== 'edit' && this.isSingleFieldChange && (changes.filterName.previousValue !== changes.filterName.currentValue)) { this.filterName = changes.filterName.previousValue; } if (changes['apiMeta'] && this.apiMeta) { this.apiMeta = typeof this.apiMeta === 'object' ? this.apiMeta : JSON.parse(this.apiMeta); this.SearchItem = this.apiMeta?.field; } } //RS 03FEB2025 // Clears search-related data, including results, search term, and suggestions. resetComponentState() { this.finalResults.set([]); ; this.filterName = ''; this.searchKeyWord = ''; this.showSuggestion = false; this.noResult = false; } clearList() { setTimeout(() => { this.finalResults.set([]); ; }, 1000); } getSourceDataLocal(event) { if (event.value.length > 2 && !this.isSingleFieldChange) { event.question?.singleFieldChange ? this.showSuggestion = false : this.showSuggestion = true; this.finalResults.set([]); this.searchKeyWord = event.value; this.showResult = false; this.getSourceData(event.value); } else { this.isSingleFieldChange = false; this.showSuggestion = false; this.finalResults.set([]); this.noResult = false; } } // VD 03May- search changes // VD 31NOV24 null check // RS 29JAN25 //Multi-word search across all object values getSourceData = (keyword) => { // MSM-27MAR25 Ensure ques.subText is always an object by parsing it if it's a string if (this.apiMeta) { this.apiMeta = typeof this.apiMeta === 'object' ? this.apiMeta : JSON.parse(this.apiMeta); if (!this.apiMeta.isStaticData) { this.isLoading = true; this.dataService.apiResponse(this.apiMeta.endpoint).subscribe((apiResponse) => { this.isLoading = false; let response; if (this.apiMeta.variable) { response = this.dataService.getValue(apiResponse, this.apiMeta.variable); } else { response = apiResponse; } let results = []; let searchTerms = keyword.toLowerCase()?.split(" "); for (let i = 0; i < response.length; i++) { let obj = response[i]; let combinedValues = this.getCombinedValuesFromColumns(obj, this.apiMeta.field); let match = searchTerms.every(term => combinedValues.includes(term)); if (match) { results.push(obj); } } this.noResult = results.length === 0; this.finalResults.set(results); }, (error) => { console.error('API error:', error); this.isLoading = false; this.noResult = true; this.finalResults.set([]); ; }); } else { // SKS24JUN25 Get language and country name locally from data let response; response = this.countryService.getCountryData(this.apiMeta.field); let results = []; let searchTerms = keyword.toLowerCase()?.split(" "); for (let i = 0; i < response.length; i++) { let obj = response[i]; let combinedValues = this.getCombinedValuesFromColumns(obj, this.apiMeta.field); let match = searchTerms.every(term => combinedValues.includes(term)); if (match) { results.push(obj); } } this.noResult = results.length === 0; this.finalResults.set(results); } } }; // SKS27FEB Helper functions getNestedValue(obj, path) { //SKS27FEB Convert array indexes to dot notation (e.g., [0] -> .0) const processedPath = path.replace(/\[(\d+)\]/g, '.$1'); const parts = processedPath.split('.'); let current = obj; for (const part of parts) { if (!current || typeof current !== 'object') return ''; current = current[part]; } return current !== null && current !== undefined ? String(current).toLowerCase().trim() : ''; } getCombinedValuesFromColumns(obj, columns) { const values = []; // SKS28FEB check if columns is an array if (typeof columns === 'string' && !Array.isArray(columns)) { columns = [columns]; } for (const column of columns) { const value = this.getNestedValue(obj, column); if (value) { values.push(value); } } return values.join(' '); } // SKS27FEB get value from data specific column getValues(element, columns) { const result = {}; // SKS28FEB check if columns is an array if (typeof columns === 'string' && !Array.isArray(columns)) { columns = [columns]; } columns.forEach((column) => { let tempElement = element; let flds = column?.split('.'); for (let i = 0; i < flds.length; i++) { let splitFlds = flds[i]?.split('['); if (splitFlds.length === 1) { tempElement = tempElement[flds[i]] || ''; } else { let index = Number(splitFlds[1]?.split(']')[0]); tempElement = tempElement[splitFlds[0]]?.[index] || ''; } } result[column] = tempElement; }); return result; } // SKS27FEB column value get funtion getKeys(obj) { return Object.keys(obj); } clickItem(event) { // console.log('inside clickItem of ' + JSON.stringify(event, null, 2)); // MSM-27MAR25 Ensure ques.subText is always an object by parsing it if it's a string if (this.apiMeta) { this.apiMeta = typeof this.apiMeta === 'object' ? this.apiMeta : JSON.parse(this.apiMeta); if (this.mode !== 'edit') { this.viewFilterName = this.dataService.getValue(event, this.apiMeta.defaultField || Array.isArray(this.apiMeta?.field) ? this.apiMeta?.field?.[0] : this.apiMeta.field); } else { this.filterName = this.dataService.getValue(event, this.apiMeta.defaultField || Array.isArray(this.apiMeta?.field) ? this.apiMeta?.field?.[0] : this.apiMeta.field); //SKS27FEB defaultField is used for showing a search field input if field have array of data } let change = new ChangeWrapper(); // ChangeWrapper = JSON.parse('{}'); change.fromQuestionId = this.id; change.valueObj = event; this.valueObj = event; change.field = this.apiMeta.defaultField || Array.isArray(this.apiMeta?.field) ? this.apiMeta?.field?.[0] : this.apiMeta.field; this.searchValueChange.emit({ question: this.question, value: change }); } } //RS 03FEB2025 // Resets component state when the component is destroyed ngOnDestroy() { this.resetComponentState(); } removeCharacters(questionText) { let updatedText = questionText?.replace(/<[^>]*>/g, ''); return updatedText; } inputValue(event, ques) { if (ques.singleFieldChange) { this.isSingleFieldChange = true; if (this.apiMeta) { this.apiMeta = typeof this.apiMeta === 'object' ? this.apiMeta : JSON.parse(this.apiMeta); let change = new ChangeWrapper(); // ChangeWrapper = JSON.parse('{}'); change.fromQuestionId = this.id; change.valueObj = this.valueObj; change.field = this.apiMeta.defaultField || Array.isArray(this.apiMeta?.field) ? this.apiMeta?.field?.[0] : this.apiMeta.field; change.referenceField = this.question.referenceField; this.filterName = this.viewFilterName; this.searchValueChange.emit({ question: ques, value: change }); } } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NxtSearchBox, deps: [{ token: i1.DataService }, { token: i2.I18nService }, { token: i3.CountryService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NxtSearchBox, isStandalone: true, selector: "nxt-search-box", inputs: { placeHolderText: "placeHolderText", question: "question", apiMeta: "apiMeta", id: "id", readOnly: "readOnly", mode: "mode", filterName: "filterName" }, outputs: { searchValueChange: "searchValueChange" }, usesOnChanges: true, ngImport: i0, template: "<!-- VD 12Jun24 - readonly change -->\n<div class=\"search-wrapper\">\n <nxt-input [type]=\"'list'\" [mode]=\"mode\" [value]=\"filterName\"\n [labelFont]=\"question.font\" [label]=\"removeCharacters(question?.questionText)\" [labelColor]=\"question.fontColor\"\n [labelSize]=\"question.fontSize\" [inputValueSize]=\"question.fontSize\" [labelWeight]=\"question.fontWeight\"\n [inputWeight]=\"question.fontWeight\" [showLabel]=\"question.style?.showLabel\" inputBorder=\"none\" svgHeight=\"20px\"\n svgWidth=\"20px\" [placeholder]=\"placeHolderText\" [required]=\"question.isOptional\" inputBgColor=\"#FAFAFA\"\n [inputId]=\"question.trackingId\" [errorMessages]=\"{ required: 'This field is required' }\"\n [inputIconLeftSrc]=\"question.iconLeftSrc\" (inputValue)=\"getSourceDataLocal($event); inputValue($event.value,$event.question)\" (onBlur)=\"clearList()\"\n [showSuggestion]=\"showSuggestion\" ariaOwns=\"selectList\" ariaHasPopup=\"listbox\" [isLoading]=\"isLoading\" [question]=\"question\">\n </nxt-input>\n\n <div id=\"selectList\" class=\"suggestion-wrapper\" role=\"listbox\">\n <div *ngIf=\"finalResults().length > 0 && showSuggestion\" class=\"suggestions-container\">\n <div *ngFor=\"let item of finalResults()\" (click)=\"clickItem(item)\" class=\"suggestion-item\" role=\"option\">\n <div class=\"grid-x align-middle\">\n <div *ngIf=\"item.thumbnail\" class=\"cell shrink thumbnail-wrapper\">\n <img [src]=\"item.thumbnail\" alt=\"Thumbnail\">\n </div>\n\n <div class=\"cell auto item-details\">\n <div *ngFor=\"let key of getKeys(getValues(item, SearchItem))\" class=\"item-value\">\n {{ getValues(item, SearchItem)[key] }}\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".suggestion-wrapper{position:absolute;top:100%;left:0;background:#fff;z-index:2}.search-wrapper{position:relative}.suggestions-container{max-height:20vh;border:1px solid #d2d4d6;overflow:auto;min-width:100px}.suggestion-item{cursor:pointer}.thumbnail-wrapper{width:60px;margin-right:1.6rem}.thumbnail-wrapper img{width:60px}.item-details{text-align:left;padding:5px 8px 0;display:flex;gap:5px}.item-value{display:flex}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: NxtInput, selector: "nxt-input", inputs: ["label", "labelFont", "labelWeight", "inputWeight", "labelSize", "inputValueSize", "labelColor", "showLabel", "svgHeight", "svgWidth", "type", "inputIconRightSrc", "inputIconLeftSrc", "required", "minLength", "pattern", "errorMessages", "maxLength", "placeholder", "inputBgColor", "inputBorder", "placeholderColor", "placeholderFont", "placeholderWeight", "placeholderSize", "inputTextColor", "inputHeight", "inputWidth", "inputId", "inputBorderSize", "inputConfig", "confPassVal", "confPass", "mode", "value", "question", "showSuggestion", "ariaOwns", "ariaHasPopup", "isLoading", "options", "minDate", "maxDate", "rows", "size"], outputs: ["valueChange", "inputValue", "onBlur", "onFocus", "toggleEmit", "nativeInputRef"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NxtSearchBox, decorators: [{ type: Component, args: [{ selector: 'nxt-search-box', standalone: true, imports: [ CommonModule, FormsModule, NxtInput ], template: "<!-- VD 12Jun24 - readonly change -->\n<div class=\"search-wrapper\">\n <nxt-input [type]=\"'list'\" [mode]=\"mode\" [value]=\"filterName\"\n [labelFont]=\"question.font\" [label]=\"removeCharacters(question?.questionText)\" [labelColor]=\"question.fontColor\"\n [labelSize]=\"question.fontSize\" [inputValueSize]=\"question.fontSize\" [labelWeight]=\"question.fontWeight\"\n [inputWeight]=\"question.fontWeight\" [showLabel]=\"question.style?.showLabel\" inputBorder=\"none\" svgHeight=\"20px\"\n svgWidth=\"20px\" [placeholder]=\"placeHolderText\" [required]=\"question.isOptional\" inputBgColor=\"#FAFAFA\"\n [inputId]=\"question.trackingId\" [errorMessages]=\"{ required: 'This field is required' }\"\n [inputIconLeftSrc]=\"question.iconLeftSrc\" (inputValue)=\"getSourceDataLocal($event); inputValue($event.value,$event.question)\" (onBlur)=\"clearList()\"\n [showSuggestion]=\"showSuggestion\" ariaOwns=\"selectList\" ariaHasPopup=\"listbox\" [isLoading]=\"isLoading\" [question]=\"question\">\n </nxt-input>\n\n <div id=\"selectList\" class=\"suggestion-wrapper\" role=\"listbox\">\n <div *ngIf=\"finalResults().length > 0 && showSuggestion\" class=\"suggestions-container\">\n <div *ngFor=\"let item of finalResults()\" (click)=\"clickItem(item)\" class=\"suggestion-item\" role=\"option\">\n <div class=\"grid-x align-middle\">\n <div *ngIf=\"item.thumbnail\" class=\"cell shrink thumbnail-wrapper\">\n <img [src]=\"item.thumbnail\" alt=\"Thumbnail\">\n </div>\n\n <div class=\"cell auto item-details\">\n <div *ngFor=\"let key of getKeys(getValues(item, SearchItem))\" class=\"item-value\">\n {{ getValues(item, SearchItem)[key] }}\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".suggestion-wrapper{position:absolute;top:100%;left:0;background:#fff;z-index:2}.search-wrapper{position:relative}.suggestions-container{max-height:20vh;border:1px solid #d2d4d6;overflow:auto;min-width:100px}.suggestion-item{cursor:pointer}.thumbnail-wrapper{width:60px;margin-right:1.6rem}.thumbnail-wrapper img{width:60px}.item-details{text-align:left;padding:5px 8px 0;display:flex;gap:5px}.item-value{display:flex}\n"] }] }], ctorParameters: () => [{ type: i1.DataService }, { type: i2.I18nService }, { type: i3.CountryService }], propDecorators: { placeHolderText: [{ type: Input }], question: [{ type: Input }], apiMeta: [{ type: Input }], id: [{ type: Input }], readOnly: [{ type: Input }], mode: [{ type: Input }], searchValueChange: [{ type: Output }], filterName: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLWJveC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ueHQtYXBwL3NyYy9saWIvY29tcG9uZW50cy9zZWFyY2gtYm94L3NlYXJjaC1ib3guY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL2NvbXBvbmVudHMvc2VhcmNoLWJveC9zZWFyY2gtYm94LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBRVQsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBRUUsTUFBTSxFQUNyQixNQUFNLGVBQWUsQ0FBQztBQUV2QixxRUFBcUU7QUFDckUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRzFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtDQUFrQyxDQUFDOzs7Ozs7QUFjNUQsTUFBTSxPQUFPLFlBQVk7SUEwQkY7SUFBaUM7SUFBaUM7SUF6QjlFLGVBQWUsQ0FBUztJQUV4QixRQUFRLENBQUM7SUFDVCxPQUFPLENBQU07SUFDYixFQUFFLENBQVM7SUFDWCxRQUFRLEdBQUcsS0FBSyxDQUFDLENBQUMsK0JBQStCO0lBQ2pELElBQUksR0FBOEIsTUFBTSxDQUFDLENBQUMsNEJBQTRCO0lBQ3JFLGlCQUFpQixHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO0lBQ3hFLFVBQVUsQ0FBTTtJQUVSLFVBQVUsQ0FBUyxDQUFDLHlDQUF5QztJQUMvRCxZQUFZLEdBQTBCLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNqRCxhQUFhLEdBQVcsRUFBRSxDQUFDO0lBQzNCLFNBQVMsQ0FBTTtJQUNm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QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEVBQUMsUUFBUSxFQUFHLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFDLENBQUMsQ0FBQztZQUNoRSxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7d0dBMU9VLFlBQVk7NEZBQVosWUFBWSxzVEM5QnpCLGt6REE2Qk0sNmRETkYsWUFBWSwrUEFDWixXQUFXLCtCQUNYLFFBQVE7OzRGQUtDLFlBQVk7a0JBWHhCLFNBQVM7K0JBQ0UsZ0JBQWdCLGNBQ2QsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCxRQUFRO3FCQUNUO3VJQUtRLGVBQWU7c0JBQXZCLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csRUFBRTtzQkFBVixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNJLGlCQUFpQjtzQkFBMUIsTUFBTTtnQkFHRSxVQUFVO3NCQUFsQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBPbkluaXQsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgVmlld0NoaWxkLFxuICBTaW1wbGVDaGFuZ2VzLHNpZ25hbCwgV3JpdGFibGVTaWduYWxcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IERhdGFTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZGF0YS5zZXJ2aWNlJztcbi8vIFZEIDIzSkFOMjQgcmVtb3ZlZCBodHRwQ2xpZW50IGltcG9ydCB1c2VkIHNlcnZpY2UgZmlsZSBmb3IgY2FsbG91dFxuaW1wb3J0IHsgQ2hhbmdlV3JhcHBlciB9IGZyb20gXCIuLi8uLi9tb2RlbC9jaGFuZ2VXcmFwcGVyXCI7XG4vLyBIQSAxOURFQzIzIGltcG9ydGVkIHRyYW5zbGF0aW9uIHNlcnZpY2VcbmltcG9ydCB7IEkxOG5TZXJ2aWNlIH0gZnJvbSBcIi4uLy4uL2kxOG4uc2VydmljZVwiO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcbmltcG9ydCB7IE54dElucHV0IH0gZnJvbSBcIi4uL254dC1pbnB1dC9ueHQtaW5wdXQuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBDb3VudHJ5U2VydmljZSB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9jb3VudHJ5LnNlcnZpY2VcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbnh0LXNlYXJjaC1ib3gnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIE54dElucHV0XG4gIF0sXG4gIHRlbXBsYXRlVXJsOiAnLi9zZWFyY2gtYm94LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc2VhcmNoLWJveC5jb21wb25lbnQuY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgTnh0U2VhcmNoQm94IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgcGxhY2VIb2xkZXJUZXh0OiBzdHJpbmc7XG5cbiAgQElucHV0KCkgcXVlc3Rpb247XG4gIEBJbnB1dCgpIGFwaU1ldGE6IGFueTtcbiAgQElucHV0KCkgaWQ6IHN0cmluZztcbiAgQElucHV0KCkgcmVhZE9ubHkgPSBmYWxzZTsgLy8gVkQgMTJKdW4yNCAtIHJlYWRvbmx5IGNoYW5nZVxuICBASW5wdXQoKSBtb2RlOiAndmlldycgfCAnZWRpdCcgfCAncHJpbnQnID0gJ2VkaXQnOyAvLyBTS1MxMUpVTjI1IE5ldyBtb2RlIGlucHV0XG4gIEBPdXRwdXQoKSBzZWFyY2hWYWx1ZUNoYW5nZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgIFNlYXJjaEl0ZW06IGFueTtcblxuICBASW5wdXQoKSBmaWx0ZXJOYW1lOiBzdHJpbmc7IC8vIFZEIDIwQXVnIGRlZmF1bHQgZmlsdGVyIHZhbHVlIGFzIGlucHV0XG4gIHB1YmxpYyBmaW5hbFJlc3VsdHM6IFdyaXRhYmxlU2lnbmFsPGFueVtdPiA9IHNpZ25hbChbXSk7XG4gIHB1YmxpYyBzZWFyY2hLZXlXb3JkOiBzdHJpbmcgPSAnJztcbiAgcHVibGljIG5ld1Jlc3VsdDogYW55O1xuICBwdWJsaWMgc2hvd1Jlc3VsdCA9IGZhbHNlO1xuICBwdWJsaWMgbm9SZXN1bHQgPSBmYWxzZTtcbiAgcHVibGljIHNob3dTdWdnZXN0aW9uID0gZmFsc2U7XG4gIHByaXZhdGUgZWw6IEhUTUxFbGVtZW50O1xuICBwcml2YXRlIHNlcnY6IHN0cmluZyA9ICdhcGknO1xuICBwcml2YXRlIHRrbjogc3RyaW5nID0gJyc7XG4gIGlzTG9hZGluZyA9IGZhbHNlXG4gIHZpZXdGaWx0ZXJOYW1lIDogc3RyaW5nO1xuICBpc1NpbmdsZUZpZWxkQ2hhbmdlID0gZmFsc2U7XG4gIHZhbHVlT2JqIDogYW55O1xuICBcbiAgY29uc3RydWN0b3IoIHByaXZhdGUgZGF0YVNlcnZpY2U6IERhdGFTZXJ2aWNlLCBwdWJsaWMgaTE4blNlcnZpY2U6IEkxOG5TZXJ2aWNlLHByaXZhdGUgY291bnRyeVNlcnZpY2U6IENvdW50cnlTZXJ2aWNlKSB7IH1cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgLy8gIFZEIDAzTWF5LSBzZWFyY2ggY2hhbmdlc1xuICAgICAvLyBBUC0yNk1BUjI1IEVuc3VyZSBxdWVzLnN1YlRleHQgaXMgYWx3YXlzIGFuIG9iamVjdCBieSBwYXJzaW5nIGl0IGlmIGl0J3MgYSBzdHJpbmdcbiAgICBpZih0aGlzLmFwaU1ldGEpe1xuICAgICAgdGhpcy5hcGlNZXRhID0gdHlwZW9mIHRoaXMuYXBpTWV0YSA9PT0gJ29iamVjdCcgPyB0aGlzLmFwaU1ldGEgOiBKU09OLnBhcnNlKHRoaXMuYXBpTWV0YSk7XG4gICAgICB0aGlzLlNlYXJjaEl0ZW0gPSB0aGlzLmFwaU1ldGEuZmllbGQ7XG4gICAgfVxuICB9XG4vLy8vUlMgMDNGRUIyMDI1XG4vLyBSZXNldHMgc3RhdGUgd2hlbiBmaWx0ZXJOYW1lIG9yIGFwaU1ldGEgY2hhbmdlcyB0byByZWZsZWN0IHVwZGF0ZWQgZGF0YVxuIC8vIEFQLTI2TUFSMjUgRW5zdXJlIHF1ZXMuc3ViVGV4dCBpcyBhbHdheXMgYW4gb2JqZWN0IGJ5IHBhcnNpbmcgaXQgaWYgaXQncyBhIHN0cmluZ1xubmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICBpZiAoY2hhbmdlc1snbW9kZSddKSB7XG4gICAgdGhpcy5tb2RlID0gY2hhbmdlc1snbW9kZSddLmN1cnJlbnRWYWx1ZTtcbiAgfVxuICBpZih0aGlzLm1vZGUgIT09ICdlZGl0JyAmJiB0aGlzLmlzU2luZ2xlRmllbGRDaGFuZ2UgJiYgKGNoYW5nZXMuZmlsdGVyTmFtZS5wcmV2aW91c1ZhbHVlICE9PSAgY2hhbmdlcy5maWx0ZXJOYW1lLmN1cnJlbnRWYWx1ZSkpIHtcbiAgICB0aGlzLmZpbHRlck5hbWUgPSBjaGFuZ2VzLmZpbHRlck5hbWUucHJldmlvdXNWYWx1ZVxuICB9XG4gIGlmIChjaGFuZ2VzWydhcGlNZXRhJ10gJiYgdGhpcy5hcGlNZXRhKSB7XG4gICAgdGhpcy5hcGlNZXRhID0gdHlwZW9mIHRoaXMuYXBpTWV0YSA9PT0gJ29iamVjdCcgPyB0aGlzLmFwaU1ldGEgOiBKU09OLnBhcnNlKHRoaXMuYXBpTWV0YSk7XG4gICAgdGhpcy5TZWFyY2hJdGVtID0gdGhpcy5hcGlNZXRhPy5maWVsZDtcbiAgfVxufVxuLy9SUyAwM0ZFQjIwMjVcbi8vIENsZWFycyBzZWFyY2gtcmVsYXRlZCBkYXRhLCBpbmNsdWRpbmcgcmVzdWx0cywgc2VhcmNoIHRlcm0sIGFuZCBzdWdnZXN0aW9ucy5cbnByaXZhdGUgcmVzZXRDb21wb25lbnRTdGF0ZSgpOiB2b2lkIHtcbiAgdGhpcy5maW5hbFJlc3VsdHMuc2V0KFtdKTs7XG4gIHRoaXMuZmlsdGVyTmFtZSA9ICcnOyBcbiAgdGhpcy5zZWFyY2hLZXlXb3JkID0gJyc7ICBcbiAgdGhpcy5zaG93U3VnZ2VzdGlvbiA9IGZhbHNlO1xuICB0aGlzLm5vUmVzdWx0ID0gZmFsc2U7XG59XG5jbGVhckxpc3QoKXtcbiAgc2V0VGltZW91dCgoKT0+IHtcbiAgICB0aGlzLmZpbmFsUmVzdWx0cy5zZXQoW10pOztcbiAgfSwgMTAwMCk7XG59XG5cbmdldFNvdXJjZURhdGFMb2NhbChldmVudDogYW55KSB7IC8vdG8gZ2V0IHJlc3VsdHMgbGlzdCBmcm9tIGJhY2tlbmQgQVBJIHdoZW5ldmVyIGtleSBpcyB1cCBhZnRlciB0aGUgZW50ZXJpbmcgYXRsZWFzdCBvbmUga2V5XG4gIGlmIChldmVudC52YWx1ZS5sZW5ndGggPiAyICYmICF0aGlzLmlzU2luZ2xlRmllbGRDaGFuZ2UpIHtcbiAgICBldmVudC5xdWVzdGlvbj8uc2luZ2xlRmllbGRDaGFuZ2UgPyB0aGlzLnNob3dTdWdnZXN0aW9uID0gZmFsc2UgOiB0aGlzLnNob3dTdWdnZXN0aW9uID0gdHJ1ZTtcbiAgICB0aGlzLmZpbmFsUmVzdWx0cy5zZXQoW10pO1xuICAgIHRoaXMuc2VhcmNoS2V5V29yZCA9IGV2ZW50LnZhbHVlO1xuICAgIHRoaXMuc2hvd1Jlc3VsdCA9IGZhbHNlO1xuICAgIHRoaXMuZ2V0U291cmNlRGF0YShldmVudC52YWx1ZSk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5pc1NpbmdsZUZpZWxkQ2hhbmdlID0gZmFsc2VcbiAgICB0aGlzLnNob3dTdWdnZXN0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5maW5hbFJlc3VsdHMuc2V0KFtdKTtcbiAgICB0aGlzLm5vUmVzdWx0ID0gZmFsc2U7XG4gIH1cbn1cbi8vIFZEIDAzTWF5LSBzZWFyY2ggY2hhbmdlc1xuLy8gVkQgMzFOT1YyNCBudWxsIGNoZWNrXG4vLyBSUyAyOUpBTjI1XG4vL011bHRpLXdvcmQgc2VhcmNoIGFjcm9zcyBhbGwgb2JqZWN0IHZhbHVlc1xucHVibGljIGdldFNvdXJjZURhdGEgPSAoa2V5d29yZDogc3RyaW5nKSA9PiB7XG4gICAvLyBNU00tMjdNQVIyNSBFbnN1cmUgcXVlcy5zdWJUZXh0IGlzIGFsd2F5cyBhbiBvYmplY3QgYnkgcGFyc2luZyBpdCBpZiBpdCdzIGEgc3RyaW5nXG4gIGlmICh0aGlzLmFwaU1ldGEpIHtcbiAgICAgIHRoaXMuYXBpTWV0YSA9IHR5cGVvZiB0aGlzLmFwaU1ldGEgPT09ICdvYmplY3QnID8gdGhpcy5hcGlNZXRhIDogSlNPTi5wYXJzZSh0aGlzLmFwaU1ldGEpO1xuICAgICAgaWYoIXRoaXMuYXBpTWV0YS5pc1N0YXRpY0RhdGEpe1xuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMuZGF0YVNlcnZpY2UuYXBpUmVzcG9uc2UodGhpcy5hcGlNZXRhLmVuZHBvaW50KS5zdWJzY3JpYmUoKGFwaVJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICBsZXQgcmVzcG9uc2U7XG4gICAgICAgICAgaWYgKHRoaXMuYXBpTWV0YS52YXJpYWJsZSkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSB0aGlzLmRhdGFTZXJ2aWNlLmdldFZhbHVlKGFwaVJlc3BvbnNlLCB0aGlzLmFwaU1ldGEudmFyaWFibGUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IGFwaVJlc3BvbnNlO1xuICAgICAgICAgIH0gICAgICBcbiAgICAgICAgICBsZXQgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgIGxldCBzZWFyY2hUZXJtcyA9IGtleXdvcmQudG9Mb3dlckNhc2UoKT8uc3BsaXQoXCIgXCIpO1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVzcG9uc2UubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBvYmogPSByZXNwb25zZVtpXTtcbiAgICAgICAgICAgIGxldCBjb21iaW5lZFZhbHVlcyA9IHRoaXMuZ2V0Q29tYmluZWRWYWx1ZXNGcm9tQ29sdW1ucyhvYmosIHRoaXMuYXBpTWV0YS5maWVsZCk7XG4gICAgICAgICAgICBsZXQgbWF0Y2ggPSBzZWFyY2hUZXJtcy5ldmVyeSh0ZXJtID0+IGNvbWJpbmVkVmFsdWVzLmluY2x1ZGVzKHRlcm0pKTtcbiAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICByZXN1bHRzLnB1c2gob2JqKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5ub1Jlc3VsdCA9IHJlc3VsdHMubGVuZ3RoID09PSAwO1xuICAgICAgICAgIHRoaXMuZmluYWxSZXN1bHRzLnNldChyZXN1bHRzKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignQVBJIGVycm9yOicsIGVycm9yKTtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMubm9SZXN1bHQgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuZmluYWxSZXN1bHRzLnNldChbXSk7O1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7IC8vIFNLUzI0SlVOMjUgR2V0IGxhbmd1YWdlIGFuZCBjb3VudHJ5IG5hbWUgbG9jYWxseSBmcm9tIGRhdGFcbiAgICAgICAgbGV0IHJlc3BvbnNlOyAgXG4gICAgICAgIHJlc3BvbnNlID0gdGhpcy5jb3VudHJ5U2VydmljZS5nZXRDb3VudHJ5RGF0YSh0aGlzLmFwaU1ldGEuZmllbGQpICBcbiAgICAgICAgbGV0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgbGV0IHNlYXJjaFRlcm1zID0ga2V5d29yZC50b0xvd2VyQ2FzZSgpPy5zcGxpdChcIiBcIik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVzcG9uc2UubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBsZXQgb2JqID0gcmVzcG9uc2VbaV07XG4gICAgICAgICAgbGV0IGNvbWJpbmVkVmFsdWVzID0gdGhpcy5nZXRDb21iaW5lZFZhbHVlc0Zyb21Db2x1bW5zKG9iaiwgdGhpcy5hcGlNZXRhLmZpZWxkKTtcbiAgICAgICAgICBsZXQgbWF0Y2ggPSBzZWFyY2hUZXJtcy5ldmVyeSh0ZXJtID0+IGNvbWJpbmVkVmFsdWVzLmluY2x1ZGVzKHRlcm0pKTtcbiAgICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChvYmopO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5vUmVzdWx0ID0gcmVzdWx0cy5sZW5ndGggPT09IDA7XG4gICAgICAgIHRoaXMuZmluYWxSZXN1bHRzLnNldChyZXN1bHRzKTtcbiAgICAgIH1cbiAgfVxufTtcbi8vIFNLUzI3RkVCIEhlbHBlciBmdW5jdGlvbnNcbnByaXZhdGUgZ2V0TmVzdGVkVmFsdWUob2JqOiBhbnksIHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vU0tTMjdGRUIgQ29udmVydCBhcnJheSBpbmRleGVzIHRvIGRvdCBub3RhdGlvbiAoZS5nLiwgWzBdIC0+IC4wKVxuICBjb25zdCBwcm9jZXNzZWRQYXRoID0gcGF0aC5yZXBsYWNlKC9cXFsoXFxkKylcXF0vZywgJy4kMScpO1xuICBjb25zdCBwYXJ0cyA9IHByb2Nlc3NlZFBhdGguc3BsaXQoJy4nKTtcbiAgbGV0IGN1cnJlbnQgPSBvYmo7XG4gIFxuICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICBpZiAoIWN1cnJlbnQgfHwgdHlwZW9mIGN1cnJlbnQgIT09ICdvYmplY3QnKSByZXR1cm4gJyc7XG4gICAgY3VycmVudCA9IGN1cnJlbnRbcGFydF07XG4gIH1cbiAgXG4gIHJldHVybiBjdXJyZW50ICE9PSBudWxsICYmIGN1cnJlbnQgIT09IHVuZGVmaW5lZCBcbiAgICA/IFN0cmluZyhjdXJyZW50KS50b0xvd2VyQ2FzZSgpLnRyaW0oKSBcbiAgICA6ICcnO1xufVxuXG5wcml2YXRlIGdldENvbWJpbmVkVmFsdWVzRnJvbUNvbHVtbnMob2JqOiBhbnksIGNvbHVtbnM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgY29uc3QgdmFsdWVzOiBzdHJpbmdbXSA9IFtdO1xuICAvLyBTS1MyOEZFQiBjaGVjayBpZiBjb2x1bW5zIGlzIGFuIGFycmF5XG4gIGlmKHR5cGVvZiBjb2x1bW5zID09PSAnc3RyaW5nJyAmJiAhQXJyYXkuaXNBcnJheShjb2x1bW5zKSAgKSB7XG4gICAgY29sdW1ucyA9IFtjb2x1bW5zXTtcbiAgfVxuICBcbiAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1ucykge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXROZXN0ZWRWYWx1ZShvYmosIGNvbHVtbik7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIFxuICByZXR1cm4gdmFsdWVzLmpvaW4oJyAnKTtcbn1cbi8vIFNLUzI3RkVCIGdldCB2YWx1ZSBmcm9tIGRhdGEgc3BlY2lmaWMgY29sdW1uXG5wdWJsaWMgZ2V0VmFsdWVzKGVsZW1lbnQ6IGFueSwgY29sdW1uczogYW55KTogYW55IHtcbiAgY29uc3QgcmVzdWx0OiBhbnkgPSB7fTtcbiAgLy8gU0tTMjhGRUIgY2hlY2sgaWYgY29sdW1ucyBpcyBhbiBhcnJheVxuICBpZih0eXBlb2YgY29sdW1ucyA9PT0gJ3N0cmluZycgJiYgIUFycmF5LmlzQXJyYXkoY29sdW1ucykgICkge1xuICAgIGNvbHVtbnMgPSBbY29sdW1uc107XG4gIH1cbiAgY29sdW1ucy5mb3JFYWNoKChjb2x1bW4pID0+IHtcbiAgICBsZXQgdGVtcEVsZW1lbnQgPSBlbGVtZW50O1xuICAgIGxldCBmbGRzID0gY29sdW1uPy5zcGxpdCgnLicpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmxkcy5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IHNwbGl0RmxkcyA9IGZsZHNbaV0/LnNwbGl0KCdbJyk7XG4gICAgICBpZiAoc3BsaXRGbGRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICB0ZW1wRWxlbWVudCA9IHRlbXBFbGVtZW50W2ZsZHNbaV1dIHx8ICcnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IGluZGV4ID0gTnVtYmVyKHNwbGl0Rmxkc1sxXT8uc3BsaXQoJ10nKVswXSk7XG4gICAgICAgIHRlbXBFbGVtZW50ID0gdGVtcEVsZW1lbnRbc3BsaXRGbGRzWzBdXT8uW2luZGV4XSB8fCAnJztcbiAgICAgIH1cbiAgICB9XG4gICAgcmVzdWx0W2NvbHVtbl0gPSB0ZW1wRWxlbWVudDtcbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbi8vIFNLUzI3RkVCIGNvbHVtbiB2YWx1ZSBnZXQgZnVudGlvblxuZ2V0S2V5cyhvYmo6IGFueSk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKG9iaik7XG59XG4gIHB1YmxpYyBjbGlja0l0ZW0oZXZlbnQpIHtcbiAgICAvLyBjb25zb2xlLmxvZygnaW5zaWRlIGNsaWNrSXRlbSBvZiAnICsgSlNPTi5zdHJpbmdpZnkoZXZlbnQsIG51bGwsIDIpKTtcbiAgICAvLyBNU00tMjdNQVIyNSBFbnN1cmUgcXVlcy5zdWJUZXh0IGlzIGFsd2F5cyBhbiBvYmplY3QgYnkgcGFyc2luZyBpdCBpZiBpdCdzIGEgc3RyaW5nXG4gICAgaWYodGhpcy5hcGlNZXRhKXtcbiAgICAgIHRoaXMuYXBpTWV0YSA9IHR5cGVvZiB0aGlzLmFwaU1ldGEgPT09ICdvYmplY3QnID8gdGhpcy5hcGlNZXRhIDogSlNPTi5wYXJzZSh0aGlzLmFwaU1ldGEpOyAgICBcbiAgICAgIGlmKHRoaXMubW9kZSAhPT0gJ2VkaXQnKXtcbiAgICAgICAgdGhpcy52aWV3RmlsdGVyTmFtZSA9IHRoaXMuZGF0YVNlcnZpY2UuZ2V0VmFsdWUoZXZlbnQsdGhpcy5hcGlNZXRhLmRlZmF1bHRGaWVsZCB8fCAgIEFycmF5LmlzQXJyYXkodGhpcy5hcGlNZXRhPy5maWVsZCkgPyB0aGlzLmFwaU1ldGE/LmZpZWxkPy5bMF0gOiB0aGlzLmFwaU1ldGEuZmllbGQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmZpbHRlck5hbWUgPSB0aGlzLmRhdGFTZXJ2aWNlLmdldFZhbHVlKGV2ZW50LHRoaXMuYXBpTWV0YS5kZWZhdWx0RmllbGQgfHwgQXJyYXkuaXNBcnJheSh0aGlzLmFwaU1ldGE/LmZpZWxkKSA/IHRoaXMuYXBpTWV0YT8uZmllbGQ/LlswXSA6IHRoaXMuYXBpTWV0YS5maWVsZCk7IC8vU0tTMjdGRUIgZGVmYXVsdEZpZWxkIGlzIHVzZWQgZm9yIHNob3dpbmcgYSBzZWFyY2ggZmllbGQgaW5wdXQgaWYgZmllbGQgaGF2ZSBhcnJheSBvZiBkYXRhXG4gICAgICB9XG4gICAgbGV0IGNoYW5nZSA9IG5ldyBDaGFuZ2VXcmFwcGVyKCk7IC8vIENoYW5nZVdyYXBwZXIgPSBKU09OLnBhcnNlKCd7fScpO1xuICAgIGNoYW5nZS5mcm9tUXVlc3Rpb25JZCA9IHRoaXMuaWQ7XG4gICAgY2hhbmdlLnZhbHVlT2JqID0gZXZlbnQ7XG4gICAgdGhpcy52YWx1ZU9iaiA9IGV2ZW50O1xuICAgIGNoYW5nZS5maWVsZCA9IHRoaXMuYXBpTWV0YS5kZWZhdWx0RmllbGQgfHwgIEFycmF5LmlzQXJyYXkodGhpcy5hcGlNZXRhPy5maWVsZCkgPyB0aGlzLmFwaU1ldGE/LmZpZWxkPy5bMF0gOiB0aGlzLmFwaU1ldGEuZmllbGQ7XG4gICAgdGhpcy5zZWFyY2hWYWx1ZUNoYW5nZS5lbWl0KHtxdWVzdGlvbiA6IHRoaXMucXVlc3Rpb24sIHZhbHVlOiBjaGFuZ2V9KTtcbiAgfVxuICB9XG4gIC8vUlMgMDNGRUIyMDI1XG4gIC8vIFJlc2V0cyBjb21wb25lbnQgc3RhdGUgd2hlbiB0aGUgY29tcG9uZW50IGlzIGRlc3Ryb3llZFxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHsgdGhpcy5yZXNldENvbXBvbmVudFN0YXRlKCk7ICB9XG4gIHJlbW92ZUNoYXJhY3RlcnMocXVlc3Rpb25UZXh0OnN0cmluZyl7XG4gICAgbGV0IHVwZGF0ZWRUZXh0ID0gcXVlc3Rpb25UZXh0Py5yZXBsYWNlKC88W14+XSo+L2csICcnKTtcbiAgICByZXR1cm4gdXBkYXRlZFRleHQ7XG4gIH1cbiAgaW5wdXRWYWx1ZShldmVudCxxdWVzKXtcbiAgICBpZihxdWVzLnNpbmdsZUZpZWxkQ2hhbmdlKXtcbiAgICAgIHRoaXMuaXNTaW5nbGVGaWVsZENoYW5nZSA9IHRydWU7XG4gICAgICBpZih0aGlzLmFwaU1ldGEpe1xuICAgICAgICB0aGlzLmFwaU1ldGEgPSB0eXBlb2YgdGhpcy5hcGlNZXRhID09PSAnb2JqZWN0JyA/IHRoaXMuYXBpTWV0YSA6IEpTT04ucGFyc2UodGhpcy5hcGlNZXRhKTsgICAgICBcbiAgICAgICAgbGV0IGNoYW5nZSA9IG5ldyBDaGFuZ2VXcmFwcGVyKCk7IC8vIENoYW5nZVdyYXBwZXIgPSBKU09OLnBhcnNlKCd7fScpO1xuICAgICAgICBjaGFuZ2UuZnJvbVF1ZXN0aW9uSWQgPSB0aGlzLmlkO1xuICAgICAgICBjaGFuZ2UudmFsdWVPYmogPSB0aGlzLnZhbHVlT2JqO1xuICAgICAgICBjaGFuZ2UuZmllbGQgPSB0aGlzLmFwaU1ldGEuZGVmYXVsdEZpZWxkIHx8ICBBcnJheS5pc0FycmF5KHRoaXMuYXBpTWV0YT8uZmllbGQpID8gdGhpcy5hcGlNZXRhPy5maWVsZD8uWzBdIDogdGhpcy5hcGlNZXRhLmZpZWxkO1xuICAgICAgICBjaGFuZ2UucmVmZXJlbmNlRmllbGQgPSB0aGlzLnF1ZXN0aW9uLnJlZmVyZW5jZUZpZWxkO1xuICAgICAgICB0aGlzLmZpbHRlck5hbWUgPSB0aGlzLnZpZXdGaWx0ZXJOYW1lXG4gICAgICAgIHRoaXMuc2VhcmNoVmFsdWVDaGFuZ2UuZW1pdCh7cXVlc3Rpb24gOiBxdWVzLCB2YWx1ZTogY2hhbmdlfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4gICAgIiwiPCEtLSBWRCAxMkp1bjI0IC0gcmVhZG9ubHkgY2hhbmdlIC0tPlxuPGRpdiBjbGFzcz1cInNlYXJjaC13cmFwcGVyXCI+XG4gIDxueHQtaW5wdXQgW3R5cGVdPVwiJ2xpc3QnXCIgW21vZGVdPVwibW9kZVwiIFt2YWx1ZV09XCJmaWx0ZXJOYW1lXCJcbiAgICBbbGFiZWxGb250XT1cInF1ZXN0aW9uLmZvbnRcIiBbbGFiZWxdPVwicmVtb3ZlQ2hhcmFjdGVycyhxdWVzdGlvbj8ucXVlc3Rpb25UZXh0KVwiIFtsYWJlbENvbG9yXT1cInF1ZXN0aW9uLmZvbnRDb2xvclwiXG4gICAgW2xhYmVsU2l6ZV09XCJxdWVzdGlvbi5mb250U2l6ZVwiIFtpbnB1dFZhbHVlU2l6ZV09XCJxdWVzdGlvbi5mb250U2l6ZVwiIFtsYWJlbFdlaWdodF09XCJxdWVzdGlvbi5mb250V2VpZ2h0XCJcbiAgICBbaW5wdXRXZWlnaHRdPVwicXVlc3Rpb24uZm9udFdlaWdodFwiIFtzaG93TGFiZWxdPVwicXVlc3Rpb24uc3R5bGU/LnNob3dMYWJlbFwiIGlucHV0Qm9yZGVyPVwibm9uZVwiIHN2Z0hlaWdodD1cIjIwcHhcIlxuICAgIHN2Z1dpZHRoPVwiMjBweFwiIFtwbGFjZWhvbGRlcl09XCJwbGFjZUhvbGRlclRleHRcIiBbcmVxdWlyZWRdPVwicXVlc3Rpb24uaXNPcHRpb25hbFwiIGlucHV0QmdDb2xvcj1cIiNGQUZBRkFcIlxuICAgIFtpbnB1dElkXT1cInF1ZXN0aW9uLnRyYWNraW5nSWRcIiBbZXJyb3JNZXNzYWdlc109XCJ7IHJlcXVpcmVkOiAnVGhpcyBmaWVsZCBpcyByZXF1aXJlZCcgfVwiXG4gICAgW2lucHV0SWNvbkxlZnRTcmNdPVwicXVlc3Rpb24uaWNvbkxlZnRTcmNcIiAoaW5wdXRWYWx1ZSk9XCJnZXRTb3VyY2VEYXRhTG9jYWwoJGV2ZW50KTsgaW5wdXRWYWx1ZSgkZXZlbnQudmFsdWUsJGV2ZW50LnF1ZXN0aW9uKVwiIChvbkJsdXIpPVwiY2xlYXJMaXN0KClcIlxuICAgIFtzaG93U3VnZ2VzdGlvbl09XCJzaG93U3VnZ2VzdGlvblwiIGFyaWFPd25zPVwic2VsZWN0TGlzdFwiIGFyaWFIYXNQb3B1cD1cImxpc3Rib3hcIiBbaXNMb2FkaW5nXT1cImlzTG9hZGluZ1wiIFtxdWVzdGlvbl09XCJxdWVzdGlvblwiPlxuICA8L254dC1pbnB1dD5cblxuICA8ZGl2IGlkPVwic2VsZWN0TGlzdFwiIGNsYXNzPVwic3VnZ2VzdGlvbi13cmFwcGVyXCIgcm9sZT1cImxpc3Rib3hcIj5cbiAgICA8ZGl2ICpuZ0lmPVwiZmluYWxSZXN1bHRzKCkubGVuZ3RoID4gMCAmJiBzaG93U3VnZ2VzdGlvblwiIGNsYXNzPVwic3VnZ2VzdGlvbnMtY29udGFpbmVyXCI+XG4gICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBpdGVtIG9mIGZpbmFsUmVzdWx0cygpXCIgKGNsaWNrKT1cImNsaWNrSXRlbShpdGVtKVwiIGNsYXNzPVwic3VnZ2VzdGlvbi1pdGVtXCIgcm9sZT1cIm9wdGlvblwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZC14IGFsaWduLW1pZGRsZVwiPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJpdGVtLnRodW1ibmFpbFwiIGNsYXNzPVwiY2VsbCBzaHJpbmsgdGh1bWJuYWlsLXdyYXBwZXJcIj5cbiAgICAgICAgICAgIDxpbWcgW3NyY109XCJpdGVtLnRodW1ibmFpbFwiIGFsdD1cIlRodW1ibmFpbFwiPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNlbGwgYXV0byBpdGVtLWRldGFpbHNcIj5cbiAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGtleSBvZiBnZXRLZXlzKGdldFZhbHVlcyhpdGVtLCBTZWFyY2hJdGVtKSlcIiBjbGFzcz1cIml0ZW0tdmFsdWVcIj5cbiAgICAgICAgICAgICAge3sgZ2V0VmFsdWVzKGl0ZW0sIFNlYXJjaEl0ZW0pW2tleV0gfX1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PiJdfQ==