ngx-gem-spaas
Version:
This library contains services, components, images and styles to provide a unified look and way-of-working throughout GEM SPaaS.
170 lines • 26.2 kB
JavaScript
import * as ExcelJS from 'exceljs';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { BaseComponent } from 'ngx-gem-spaas';
import { takeUntil } from "rxjs/operators";
import * as i0 from "@angular/core";
import * as i1 from "ngx-gem-spaas";
import * as i2 from "@angular/material/icon";
import * as i3 from "@angular/material/tooltip";
export class ExcelImportComponent extends BaseComponent {
static parseWorksheet(worksheet) {
const newSheet = { sheetData: [], sheetName: worksheet.name };
const sheetColumns = [];
worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
// set columns if not set yet
// do not rely on rowNumber to define the first row (being zero or one), it's the actual row number in excel
if (!sheetColumns.length) {
// take column header values from first row as attributes for the rows
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
sheetColumns.push('' + cell.value);
});
}
else {
// parse all other rows (so except the first one, which is considered to contain headers)
let rowData = {};
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
// colNumber is 1-based !!
if (sheetColumns[colNumber - 1] !== 'null') {
rowData[sheetColumns[colNumber - 1]] = cell.formula ? cell.result : cell.value;
}
});
newSheet.sheetData.push(rowData);
}
});
return newSheet;
}
constructor(settingsService, snackbarService) {
super();
this.settingsService = settingsService;
this.snackbarService = snackbarService;
// TOOLTIP MESSAGE
this.tooltipMsg = '';
// EMIT THE IMPORTED SHEETS
this.sheetsImported = new EventEmitter();
this.rawFileContent = null;
this.settings = null;
this.getSettings();
}
// ********************************************************************************************************
// LOAD DATA
// ********************************************************************************************************
getSettings() {
this.settingsService.onNewSettings()
.pipe(takeUntil(this.onDestroy$))
.subscribe((settings) => {
this.settings = settings;
if (!this.tooltipMsg) {
// set default label
this.tooltipMsg = 'import from ' + settings.exportExtension;
}
});
}
// ********************************************************************************************************
// PROCESS DATA
// ********************************************************************************************************
readFile(e) {
this.rawFileContent = null;
if (e?.target?.files && e.target.files.length === 1) {
const file = e.target.files[0];
// READ FILE IF EXCEL
const reader = new FileReader();
const isExcel = this.settings?.exportExtension === 'xlsx' && file.type.match('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
const isCsv = this.settings?.exportExtension === 'csv' && file.type.match('text/csv');
if (isExcel) {
reader.onloadend = () => {
// RESET UPLOADER
e.target.value = null;
// THEN PROCESS RESULT
this.rawFileContent = reader.result;
if (this.rawFileContent) {
this.parseExcel();
}
else {
this.snackbarService.message('File does not contain valid data');
}
};
reader.readAsArrayBuffer(file);
}
else if (isCsv) {
reader.onloadend = () => {
// RESET UPLOADER
e.target.value = null;
// THEN PROCESS RESULT
this.rawFileContent = reader.result;
if (this.rawFileContent) {
this.parseCsv();
}
else {
this.snackbarService.message('File does not contain valid data');
}
};
reader.readAsText(file);
}
else {
// neither a valid xlsx, nor a valid csv
this.snackbarService.message(`File type not supported (should be .${this.settings?.exportExtension})`);
}
}
}
parseExcel() {
const sheets = [];
const workBook = new ExcelJS.Workbook();
let hasAnyData = false;
workBook.xlsx.load(this.rawFileContent)
.then((wb) => {
if (wb.worksheets.length) {
wb.eachSheet((worksheet, sheetId) => {
const newSheet = ExcelImportComponent.parseWorksheet(worksheet);
hasAnyData = hasAnyData || newSheet.sheetData.length > 0;
sheets.push(newSheet);
});
this.emitSheets(hasAnyData, sheets);
}
else {
this.snackbarService.error('Your file does not contain any sheets');
}
})
.catch((reason) => {
this.snackbarService.error('There was an error importing your file: ' + reason);
return;
});
}
parseCsv() {
const sheet = { sheetName: 'csv import', sheetData: [] };
let dataHeaders = [];
const rows = ('' + this.rawFileContent).split('\n') || [];
for (const row of rows) {
const cells = row.split(this.settings?.getCsvDelimiter() || ',');
if (!dataHeaders.length) {
// take first row with data as headers
dataHeaders = cells;
continue;
}
const newRow = {};
for (let cellIdx = 0; cellIdx < cells.length; cellIdx++) {
newRow[dataHeaders[cellIdx]] = cells[cellIdx];
}
sheet.sheetData.push(newRow);
}
this.emitSheets(sheet.sheetData.length > 0, [sheet]);
}
emitSheets(hasAnyData, sheets) {
if (!hasAnyData) {
this.snackbarService.error('Your file does not contain any data, are you sure you uploaded the correct one?');
}
else {
this.sheetsImported.emit(sheets.sort((a, b) => a.sheetName < b.sheetName ? -1 : 1));
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ExcelImportComponent, deps: [{ token: i1.SettingsService }, { token: i1.SnackbarService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ExcelImportComponent, selector: "spaas-excel-import", inputs: { tooltipMsg: "tooltipMsg" }, outputs: { sheetsImported: "sheetsImported" }, usesInheritance: true, ngImport: i0, template: "<label>\r\n <mat-icon [matTooltip]=\"tooltipMsg\"\r\n matTooltipPosition=\"below\"\r\n fontIcon=\"file_upload\">\r\n </mat-icon>\r\n <input type=\"file\"\r\n (change)=\"readFile($event);\">\r\n</label>\r\n", styles: ["input[type=file]{display:none}\n"], dependencies: [{ kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i3.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ExcelImportComponent, decorators: [{
type: Component,
args: [{ selector: 'spaas-excel-import', template: "<label>\r\n <mat-icon [matTooltip]=\"tooltipMsg\"\r\n matTooltipPosition=\"below\"\r\n fontIcon=\"file_upload\">\r\n </mat-icon>\r\n <input type=\"file\"\r\n (change)=\"readFile($event);\">\r\n</label>\r\n", styles: ["input[type=file]{display:none}\n"] }]
}], ctorParameters: () => [{ type: i1.SettingsService }, { type: i1.SnackbarService }], propDecorators: { tooltipMsg: [{
type: Input
}], sheetsImported: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhjZWwtaW1wb3J0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1nZW0tc3BhYXMvZXhjZWwvc3JjL2V4Y2VsLWltcG9ydC9leGNlbC1pbXBvcnQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWdlbS1zcGFhcy9leGNlbC9zcmMvZXhjZWwtaW1wb3J0L2V4Y2VsLWltcG9ydC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLFNBQVMsQ0FBQztBQUNuQyxPQUFPLEVBQUMsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3JFLE9BQU8sRUFBQyxhQUFhLEVBQWtELE1BQU0sZUFBZSxDQUFDO0FBQzdGLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7QUFTekMsTUFBTSxPQUFPLG9CQUFxQixTQUFRLGFBQWE7SUFZN0MsTUFBTSxDQUFDLGNBQWMsQ0FDM0IsU0FBNEI7UUFHNUIsTUFBTSxRQUFRLEdBQW9CLEVBQUMsU0FBUyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLElBQUksRUFBQyxDQUFDO1FBQzdFLE1BQU0sWUFBWSxHQUFhLEVBQUUsQ0FBQTtRQUVqQyxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUMsWUFBWSxFQUFFLEtBQUssRUFBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFNBQVMsRUFBRSxFQUFFO1lBRTFELDZCQUE2QjtZQUM3Qiw0R0FBNEc7WUFDNUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDekIsc0VBQXNFO2dCQUN0RSxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUMsWUFBWSxFQUFFLElBQUksRUFBQyxFQUFFLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFB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QUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RGLENBQUM7SUFDSCxDQUFDOytHQTNMVSxvQkFBb0I7bUdBQXBCLG9CQUFvQixzS0NaakMsZ1BBUUE7OzRGRElhLG9CQUFvQjtrQkFOaEMsU0FBUzsrQkFDRSxvQkFBb0I7a0hBUXJCLFVBQVU7c0JBQWxCLEtBQUs7Z0JBR0ksY0FBYztzQkFBdkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIEV4Y2VsSlMgZnJvbSAnZXhjZWxqcyc7XHJcbmltcG9ydCB7Q29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0Jhc2VDb21wb25lbnQsIFNldHRpbmdzTW9kZWwsIFNldHRpbmdzU2VydmljZSwgU25hY2tiYXJTZXJ2aWNlfSBmcm9tICduZ3gtZ2VtLXNwYWFzJztcclxuaW1wb3J0IHt0YWtlVW50aWx9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5pbXBvcnQge0V4Y2VsU2hlZXRNb2RlbH0gZnJvbSBcIi4uL19tb2RlbHMvZXhjZWwubW9kZWxcIjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnc3BhYXMtZXhjZWwtaW1wb3J0JyxcclxuICBzdHlsZVVybHM6IFsnLi9leGNlbC1pbXBvcnQuY29tcG9uZW50LnNjc3MnXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vZXhjZWwtaW1wb3J0LmNvbXBvbmVudC5odG1sJyxcclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBFeGNlbEltcG9ydENvbXBvbmVudCBleHRlbmRzIEJhc2VDb21wb25lbnQge1xyXG5cclxuICAvLyBUT09MVElQIE1FU1NBR0VcclxuICBASW5wdXQoKSB0b29sdGlwTXNnID0gJyc7XHJcblxyXG4gIC8vIEVNSVQgVEhFIElNUE9SVEVEIFNIRUVUU1xyXG4gIEBPdXRwdXQoKSBzaGVldHNJbXBvcnRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8RXhjZWxTaGVldE1vZGVsW10+KCk7XHJcblxyXG4gIHJhd0ZpbGVDb250ZW50OiBBcnJheUJ1ZmZlciB8IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG5cclxuICBwcml2YXRlIHNldHRpbmdzOiBTZXR0aW5nc01vZGVsIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIHByaXZhdGUgc3RhdGljIHBhcnNlV29ya3NoZWV0KFxyXG4gICAgd29ya3NoZWV0OiBFeGNlbEpTLldvcmtzaGVldFxyXG4gICk6IEV4Y2VsU2hlZXRNb2RlbCB7XHJcblxyXG4gICAgY29uc3QgbmV3U2hlZXQ6IEV4Y2VsU2hlZXRNb2RlbCA9IHtzaGVldERhdGE6IFtdLCBzaGVldE5hbWU6IHdvcmtzaGVldC5uYW1lfTtcclxuICAgIGNvbnN0IHNoZWV0Q29sdW1uczogc3RyaW5nW10gPSBbXVxyXG5cclxuICAgIHdvcmtzaGVldC5lYWNoUm93KHtpbmNsdWRlRW1wdHk6IGZhbHNlfSwgKHJvdywgcm93TnVtYmVyKSA9PiB7XHJcblxyXG4gICAgICAvLyBzZXQgY29sdW1ucyBpZiBub3Qgc2V0IHlldFxyXG4gICAgICAvLyBkbyBub3QgcmVseSBvbiByb3dOdW1iZXIgdG8gZGVmaW5lIHRoZSBmaXJzdCByb3cgKGJlaW5nIHplcm8gb3Igb25lKSwgaXQncyB0aGUgYWN0dWFsIHJvdyBudW1iZXIgaW4gZXhjZWxcclxuICAgICAgaWYgKCFzaGVldENvbHVtbnMubGVuZ3RoKSB7XHJcbiAgICAgICAgLy8gdGFrZSBjb2x1bW4gaGVhZGVyIHZhbHVlcyBmcm9tIGZpcnN0IHJvdyBhcyBhdHRyaWJ1dGVzIGZvciB0aGUgcm93c1xyXG4gICAgICAgIHJvdy5lYWNoQ2VsbCh7aW5jbHVkZUVtcHR5OiB0cnVlfSwgKGNlbGwsIGNvbE51bWJlcikgPT4ge1xyXG4gICAgICAgICAgc2hlZXRDb2x1bW5zLnB1c2goJycgKyBjZWxsLnZhbHVlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBwYXJzZSBhbGwgb3RoZXIgcm93cyAoc28gZXhjZXB0IHRoZSBmaXJzdCBvbmUsIHdoaWNoIGlzIGNvbnNpZGVyZWQgdG8gY29udGFpbiBoZWFkZXJzKVxyXG4gICAgICAgIGxldCByb3dEYXRhOiBhbnkgPSB7fTtcclxuICAgICAgICByb3cuZWFjaENlbGwoe2luY2x1ZGVFbXB0eTogdHJ1ZX0sIChjZWxsLCBjb2xOdW1iZXIpID0+IHtcclxuICAgICAgICAgIC8vIGNvbE51bWJlciBpcyAxLWJhc2VkICEhXHJcbiAgICAgICAgICBpZiAoc2hlZXRDb2x1bW5zW2NvbE51bWJlciAtIDFdICE9PSAnbnVsbCcpIHtcclxuICAgICAgICAgICAgcm93RGF0YVtzaGVldENvbHVtbnNbY29sTnVtYmVyIC0gMV1dID0gY2VsbC5mb3JtdWxhID8gY2VsbC5yZXN1bHQgOiBjZWxsLnZhbHVlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIG5ld1NoZWV0LnNoZWV0RGF0YS5wdXNoKHJvd0RhdGEpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBuZXdTaGVldDtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBzZXR0aW5nc1NlcnZpY2U6IFNldHRpbmdzU2VydmljZSxcclxuICAgIHByaXZhdGUgc25hY2tiYXJTZXJ2aWNlOiBTbmFja2JhclNlcnZpY2UsXHJcbiAgKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gICAgdGhpcy5nZXRTZXR0aW5ncygpO1xyXG4gIH1cclxuXHJcbiAgLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuICAvLyBMT0FEIERBVEFcclxuICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5cclxuICBwcml2YXRlIGdldFNldHRpbmdzKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zZXR0aW5nc1NlcnZpY2Uub25OZXdTZXR0aW5ncygpXHJcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSQpKVxyXG4gICAgICAuc3Vic2NyaWJlKChzZXR0aW5ncykgPT4ge1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICBpZiAoIXRoaXMudG9vbHRpcE1zZykge1xyXG4gICAgICAgICAgLy8gc2V0IGRlZmF1bHQgbGFiZWxcclxuICAgICAgICAgIHRoaXMudG9vbHRpcE1zZyA9ICdpbXBvcnQgZnJvbSAnICsgc2V0dGluZ3MuZXhwb3J0RXh0ZW5zaW9uXHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbiAgLy8gUFJPQ0VTUyBEQVRBXHJcbiAgLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuXHJcbiAgcmVhZEZpbGUoZTogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLnJhd0ZpbGVDb250ZW50ID0gbnVsbDtcclxuICAgIGlmIChlPy50YXJnZXQ/LmZpbGVzICYmIGUudGFyZ2V0LmZpbGVzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICBjb25zdCBmaWxlID0gZS50YXJnZXQuZmlsZXNbMF07XHJcbiAgICAgIC8vIFJFQUQgRklMRSBJRiBFWENFTFxyXG4gICAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xyXG4gICAgICBjb25zdCBpc0V4Y2VsID0gdGhpcy5zZXR0aW5ncz8uZXhwb3J0RXh0ZW5zaW9uID09PSAneGxzeCcgJiYgZmlsZS50eXBlLm1hdGNoKCdhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGVldCcpO1xyXG4gICAgICBjb25zdCBpc0NzdiA9IHRoaXMuc2V0dGluZ3M/LmV4cG9ydEV4dGVuc2lvbiA9PT0gJ2NzdicgJiYgZmlsZS50eXBlLm1hdGNoKCd0ZXh0L2NzdicpO1xyXG5cclxuICAgICAgaWYgKGlzRXhjZWwpIHtcclxuXHJcbiAgICAgICAgcmVhZGVyLm9ubG9hZGVuZCA9ICgpID0+IHtcclxuICAgICAgICAgIC8vIFJFU0VUIFVQTE9BREVSXHJcbiAgICAgICAgICBlLnRhcmdldC52YWx1ZSA9IG51bGw7XHJcbiAgICAgICAgICAvLyBUSEVOIFBST0NFU1MgUkVTVUxUXHJcbiAgICAgICAgICB0aGlzLnJhd0ZpbGVDb250ZW50ID0gcmVhZGVyLnJlc3VsdDtcclxuICAgICAgICAgIGlmICh0aGlzLnJhd0ZpbGVDb250ZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMucGFyc2VFeGNlbCgpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5zbmFja2JhclNlcnZpY2UubWVzc2FnZSgnRmlsZSBkb2VzIG5vdCBjb250YWluIHZhbGlkIGRhdGEnKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihmaWxlKTtcclxuXHJcbiAgICAgIH0gZWxzZSBpZiAoaXNDc3YpIHtcclxuXHJcbiAgICAgICAgcmVhZGVyLm9ubG9hZGVuZCA9ICgpID0+IHtcclxuICAgICAgICAgIC8vIFJFU0VUIFVQTE9BREVSXHJcbiAgICAgICAgICBlLnRhcmdldC52YWx1ZSA9IG51bGw7XHJcbiAgICAgICAgICAvLyBUSEVOIFBST0NFU1MgUkVTVUxUXHJcbiAgICAgICAgICB0aGlzLnJhd0ZpbGVDb250ZW50ID0gcmVhZGVyLnJlc3VsdDtcclxuICAgICAgICAgIGlmICh0aGlzLnJhd0ZpbGVDb250ZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMucGFyc2VDc3YoKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuc25hY2tiYXJTZXJ2aWNlLm1lc3NhZ2UoJ0ZpbGUgZG9lcyBub3QgY29udGFpbiB2YWxpZCBkYXRhJyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZWFkZXIucmVhZEFzVGV4dChmaWxlKTtcclxuXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gbmVpdGhlciBhIHZhbGlkIHhsc3gsIG5vciBhIHZhbGlkIGNzdlxyXG4gICAgICAgIHRoaXMuc25hY2tiYXJTZXJ2aWNlLm1lc3NhZ2UoYEZpbGUgdHlwZSBub3Qgc3VwcG9ydGVkIChzaG91bGQgYmUgLiR7dGhpcy5zZXR0aW5ncz8uZXhwb3J0RXh0ZW5zaW9ufSlgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBwYXJzZUV4Y2VsKCk6IHZvaWQge1xyXG5cclxuICAgIGNvbnN0IHNoZWV0czogRXhjZWxTaGVldE1vZGVsW10gPSBbXTtcclxuICAgIGNvbnN0IHdvcmtCb29rID0gbmV3IEV4Y2VsSlMuV29ya2Jvb2soKTtcclxuICAgIGxldCBoYXNBbnlEYXRhID0gZmFsc2U7XHJcblxyXG4gICAgd29ya0Jvb2sueGxzeC5sb2FkKHRoaXMucmF3RmlsZUNvbnRlbnQgYXMgQnVmZmVyKVxyXG4gICAgICAudGhlbigod2IpID0+IHtcclxuXHJcbiAgICAgICAgaWYgKHdiLndvcmtzaGVldHMubGVuZ3RoKSB7XHJcblxyXG4gICAgICAgICAgd2IuZWFjaFNoZWV0KCh3b3Jrc2hlZXQsIHNoZWV0SWQpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgbmV3U2hlZXQ6IEV4Y2VsU2hlZXRNb2RlbCA9IEV4Y2VsSW1wb3J0Q29tcG9uZW50LnBhcnNlV29ya3NoZWV0KHdvcmtzaGVldCk7XHJcbiAgICAgICAgICAgIGhhc0FueURhdGEgPSBoYXNBbnlEYXRhIHx8IG5ld1NoZWV0LnNoZWV0RGF0YS5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICBzaGVldHMucHVzaChuZXdTaGVldCk7XHJcbiAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICB0aGlzLmVtaXRTaGVldHMoXHJcbiAgICAgICAgICAgIGhhc0FueURhdGEsXHJcbiAgICAgICAgICAgIHNoZWV0cyxcclxuICAgICAgICAgIClcclxuXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuc25hY2tiYXJTZXJ2aWNlLmVycm9yKCdZb3VyIGZpbGUgZG9lcyBub3QgY29udGFpbiBhbnkgc2hlZXRzJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKChyZWFzb24pID0+IHtcclxuICAgICAgICB0aGlzLnNuYWNrYmFyU2VydmljZS5lcnJvcignVGhlcmUgd2FzIGFuIGVycm9yIGltcG9ydGluZyB5b3VyIGZpbGU6ICcgKyByZWFzb24pO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfSlcclxuXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHBhcnNlQ3N2KCk6IHZvaWQge1xyXG5cclxuICAgIGNvbnN0IHNoZWV0OiBFeGNlbFNoZWV0TW9kZWwgPSB7c2hlZXROYW1lOiAnY3N2IGltcG9ydCcsIHNoZWV0RGF0YTogW119O1xyXG4gICAgbGV0IGRhdGFIZWFkZXJzOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgY29uc3Qgcm93cyA9ICgnJyArIHRoaXMucmF3RmlsZUNvbnRlbnQpLnNwbGl0KCdcXG4nKSB8fCBbXTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XHJcbiAgICAgIGNvbnN0IGNlbGxzID0gcm93LnNwbGl0KHRoaXMuc2V0dGluZ3M/LmdldENzdkRlbGltaXRlcigpIHx8ICcsJyk7XHJcbiAgICAgIGlmICghZGF0YUhlYWRlcnMubGVuZ3RoKSB7XHJcbiAgICAgICAgLy8gdGFrZSBmaXJzdCByb3cgd2l0aCBkYXRhIGFzIGhlYWRlcnNcclxuICAgICAgICBkYXRhSGVhZGVycyA9IGNlbGxzO1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IG5ld1JvdzogYW55ID0ge307XHJcbiAgICAgIGZvciAobGV0IGNlbGxJZHggPSAwOyBjZWxsSWR4IDwgY2VsbHMubGVuZ3RoOyBjZWxsSWR4KyspIHtcclxuICAgICAgICBuZXdSb3dbZGF0YUhlYWRlcnNbY2VsbElkeF1dID0gY2VsbHNbY2VsbElkeF07XHJcbiAgICAgIH1cclxuICAgICAgc2hlZXQuc2hlZXREYXRhLnB1c2gobmV3Um93KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmVtaXRTaGVldHMoXHJcbiAgICAgIHNoZWV0LnNoZWV0RGF0YS5sZW5ndGggPiAwLFxyXG4gICAgICBbc2hlZXRdLFxyXG4gICAgKVxyXG5cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZW1pdFNoZWV0cyhcclxuICAgIGhhc0FueURhdGE6IGJvb2xlYW4sXHJcbiAgICBzaGVldHM6IEV4Y2VsU2hlZXRNb2RlbFtdLFxyXG4gICk6IHZvaWQge1xyXG4gICAgaWYgKCFoYXNBbnlEYXRhKSB7XHJcbiAgICAgIHRoaXMuc25hY2tiYXJTZXJ2aWNlLmVycm9yKCdZb3VyIGZpbGUgZG9lcyBub3QgY29udGFpbiBhbnkgZGF0YSwgYXJlIHlvdSBzdXJlIHlvdSB1cGxvYWRlZCB0aGUgY29ycmVjdCBvbmU/Jyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNoZWV0c0ltcG9ydGVkLmVtaXQoc2hlZXRzLnNvcnQoKGEsIGIpID0+IGEuc2hlZXROYW1lIDwgYi5zaGVldE5hbWUgPyAtMSA6IDEpKTtcclxuICAgIH1cclxuICB9XHJcblxyXG59XHJcbiIsIjxsYWJlbD5cclxuICA8bWF0LWljb24gW21hdFRvb2x0aXBdPVwidG9vbHRpcE1zZ1wiXHJcbiAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImJlbG93XCJcclxuICAgICAgICAgICAgZm9udEljb249XCJmaWxlX3VwbG9hZFwiPlxyXG4gIDwvbWF0LWljb24+XHJcbiAgPGlucHV0IHR5cGU9XCJmaWxlXCJcclxuICAgICAgICAgKGNoYW5nZSk9XCJyZWFkRmlsZSgkZXZlbnQpO1wiPlxyXG48L2xhYmVsPlxyXG4iXX0=