ngx-text-diff
Version:
A Text Diff component for Angular.
207 lines • 28.5 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Injectable } from '@angular/core';
import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diff_match_patch } from 'diff-match-patch';
import { isEmpty } from './ngx-text-diff.utils';
import * as i0 from "@angular/core";
var NgxTextDiffService = /** @class */ (function () {
function NgxTextDiffService() {
this.initParser();
}
NgxTextDiffService.prototype.initParser = function () {
this.diffParser = new diff_match_patch();
};
NgxTextDiffService.prototype.getDiffsByLines = function (left, right) {
var _this = this;
return new Promise(function (resolve, reject) {
var a = _this.diffParser.diff_linesToChars_(left, right);
var lineText1 = a.chars1;
var lineText2 = a.chars2;
var linesArray = a.lineArray;
var diffs = _this.diffParser.diff_main(lineText1, lineText2, true);
_this.diffParser.diff_charsToLines_(diffs, linesArray);
var rows = _this.formatOutput(diffs);
if (!rows) {
reject('Error');
}
resolve(rows);
});
};
NgxTextDiffService.prototype.formatOutput = function (diffs) {
var _this = this;
var lineLeft = 1;
var lineRight = 1;
return diffs.reduce(function (rows, diff) {
if (!rows) {
rows = [];
}
var diffType = diff[0];
var diffValue = diff[1];
var leftDiffRow = null;
var rightDiffRow = null;
var leftContent = null;
var rightContent = null;
var rowTemp = null;
switch (diffType) {
case DIFF_EQUAL: // 0
diffValue
.split('\n')
.filter(function (value, index, array) {
if (index === array.length - 1) {
return !isEmpty(value);
}
return true;
})
.forEach(function (line) {
leftContent = {
lineNumber: lineLeft,
lineContent: line,
lineDiffs: [],
prefix: ''
};
rightContent = {
lineNumber: lineRight,
lineContent: line,
lineDiffs: [],
prefix: ''
};
rowTemp = {
leftContent: leftContent,
rightContent: rightContent,
belongTo: 'both',
hasDiffs: false,
numDiffs: 0,
};
rows.push(rowTemp);
lineRight = lineRight + 1;
lineLeft = lineLeft + 1;
});
break;
case DIFF_DELETE: // -1
diffValue
.split('\n')
.filter(function (value, index, array) {
if (index === array.length - 1) {
return !isEmpty(value);
}
return true;
})
.forEach(function (line) {
rightDiffRow = rows.find(function (row) { return !row.leftContent && row.rightContent && row.rightContent.lineNumber === lineLeft && row.rightContent.prefix !== ''; });
leftContent = {
lineNumber: lineLeft,
lineContent: line,
lineDiffs: [{ content: line, isDiff: true }],
prefix: '-'
};
if (rightDiffRow) {
rightDiffRow.leftContent = leftContent;
rightDiffRow.leftContent.lineDiffs = _this.getDiffParts(rightDiffRow.leftContent.lineContent, rightDiffRow.rightContent.lineContent);
rightDiffRow.rightContent.lineDiffs = _this.getDiffParts(rightDiffRow.rightContent.lineContent, rightDiffRow.leftContent.lineContent);
rightDiffRow.belongTo = 'both';
rightDiffRow.numDiffs = _this.countDiffs(rightDiffRow);
}
else {
rows.push({
leftContent: leftContent,
rightContent: null,
hasDiffs: true,
belongTo: 'left',
numDiffs: 1,
});
}
lineLeft = lineLeft + 1;
});
break;
case DIFF_INSERT: // 1
diffValue
.split('\n')
.filter(function (value, index, array) {
if (index === array.length - 1) {
return !isEmpty(value);
}
return true;
})
.forEach(function (line) {
leftDiffRow = rows.find(function (row) { return row.leftContent && !row.rightContent && row.leftContent.lineNumber === lineRight && row.leftContent.prefix !== ''; });
rightContent = {
lineNumber: lineRight,
lineContent: line,
lineDiffs: [{ content: line, isDiff: true }],
prefix: '+'
};
if (leftDiffRow) {
leftDiffRow.rightContent = rightContent;
leftDiffRow.leftContent.lineDiffs = _this.getDiffParts(leftDiffRow.leftContent.lineContent, leftDiffRow.rightContent.lineContent);
leftDiffRow.rightContent.lineDiffs = _this.getDiffParts(leftDiffRow.rightContent.lineContent, leftDiffRow.leftContent.lineContent);
leftDiffRow.belongTo = 'both';
leftDiffRow.numDiffs = _this.countDiffs(leftDiffRow);
}
else {
rows.push({
leftContent: null,
rightContent: rightContent,
hasDiffs: true,
belongTo: 'right',
numDiffs: 1,
});
}
lineRight = lineRight + 1;
});
break;
}
return rows;
}, []);
};
NgxTextDiffService.prototype.countDiffs = function (result) {
var diffCount = 0;
if (result.leftContent) {
diffCount += result.leftContent.lineDiffs.filter(function (diff) { return diff.isDiff; }).length;
}
if (result.leftContent) {
diffCount += result.rightContent.lineDiffs.filter(function (diff) { return diff.isDiff; }).length;
}
return diffCount;
};
NgxTextDiffService.prototype.getDiffParts = function (value, compareValue) {
var diffParts = [];
var i = 0;
var j = 0;
var shared = '';
var diff = '';
while (i < value.length) {
if (value[i] === compareValue[j] && j < compareValue.length) {
if (diff !== '') {
diffParts.push({ content: diff, isDiff: true });
diff = '';
}
shared += value[i];
}
else {
if (shared !== '') {
diffParts.push({ content: shared, isDiff: false });
shared = '';
}
diff += value[i];
}
i++;
j++;
}
if (diff !== '') {
diffParts.push({ content: diff, isDiff: true });
}
else if (shared !== '') {
diffParts.push({ content: shared, isDiff: false });
}
return diffParts;
};
NgxTextDiffService.ɵprov = i0.ɵɵdefineInjectable({ factory: function NgxTextDiffService_Factory() { return new NgxTextDiffService(); }, token: NgxTextDiffService, providedIn: "root" });
NgxTextDiffService = __decorate([
Injectable({
providedIn: 'root'
}),
__metadata("design:paramtypes", [])
], NgxTextDiffService);
return NgxTextDiffService;
}());
export { NgxTextDiffService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXRleHQtZGlmZi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LXRleHQtZGlmZi8iLCJzb3VyY2VzIjpbImxpYi9uZ3gtdGV4dC1kaWZmLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFRLFdBQVcsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFaEcsT0FBTyxFQUFFLE9BQU8sRUFBUyxNQUFNLHVCQUF1QixDQUFDOztBQUt2RDtJQUdFO1FBQ0UsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFTyx1Q0FBVSxHQUFsQjtRQUNFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFRCw0Q0FBZSxHQUFmLFVBQWdCLElBQVksRUFBRSxLQUFhO1FBQTNDLGlCQWVDO1FBZEMsT0FBTyxJQUFJLE9BQU8sQ0FBdUIsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUN2RCxJQUFNLENBQUMsR0FBRyxLQUFJLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMxRCxJQUFNLFNBQVMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO1lBQzNCLElBQU0sU0FBUyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7WUFDM0IsSUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUMvQixJQUFNLEtBQUssR0FBVyxLQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzVFLEtBQUksQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3RELElBQU0sSUFBSSxHQUF5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QUFFLEtBQUssRUFBRSxDQUFDLENBQUM7U0FDcEQ7UUFFRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDOztJQW5OVSxrQkFBa0I7UUFIOUIsVUFBVSxDQUFDO1lBQ1YsVUFBVSxFQUFFLE1BQU07U0FDbkIsQ0FBQzs7T0FDVyxrQkFBa0IsQ0FvTjlCOzZCQTVORDtDQTROQyxBQXBORCxJQW9OQztTQXBOWSxrQkFBa0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERpZmYsIERJRkZfREVMRVRFLCBESUZGX0VRVUFMLCBESUZGX0lOU0VSVCwgZGlmZl9tYXRjaF9wYXRjaCB9IGZyb20gJ2RpZmYtbWF0Y2gtcGF0Y2gnO1xyXG5pbXBvcnQgeyBEaWZmTGluZVJlc3VsdCwgRGlmZlBhcnQsIERpZmZUYWJsZVJvd1Jlc3VsdCB9IGZyb20gJy4vbmd4LXRleHQtZGlmZi5tb2RlbCc7XHJcbmltcG9ydCB7IGlzRW1wdHksIGlzTmlsIH0gZnJvbSAnLi9uZ3gtdGV4dC1kaWZmLnV0aWxzJztcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIE5neFRleHREaWZmU2VydmljZSB7XHJcbiAgZGlmZlBhcnNlcjogZGlmZl9tYXRjaF9wYXRjaDtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICB0aGlzLmluaXRQYXJzZXIoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaW5pdFBhcnNlcigpIHtcclxuICAgIHRoaXMuZGlmZlBhcnNlciA9IG5ldyBkaWZmX21hdGNoX3BhdGNoKCk7XHJcbiAgfVxyXG5cclxuICBnZXREaWZmc0J5TGluZXMobGVmdDogc3RyaW5nLCByaWdodDogc3RyaW5nKTogUHJvbWlzZTxEaWZmVGFibGVSb3dSZXN1bHRbXT4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPERpZmZUYWJsZVJvd1Jlc3VsdFtdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIGNvbnN0IGEgPSB0aGlzLmRpZmZQYXJzZXIuZGlmZl9saW5lc1RvQ2hhcnNfKGxlZnQsIHJpZ2h0KTtcclxuICAgICAgY29uc3QgbGluZVRleHQxID0gYS5jaGFyczE7XHJcbiAgICAgIGNvbnN0IGxpbmVUZXh0MiA9IGEuY2hhcnMyO1xyXG4gICAgICBjb25zdCBsaW5lc0FycmF5ID0gYS5saW5lQXJyYXk7XHJcbiAgICAgIGNvbnN0IGRpZmZzOiBEaWZmW10gPSB0aGlzLmRpZmZQYXJzZXIuZGlmZl9tYWluKGxpbmVUZXh0MSwgbGluZVRleHQyLCB0cnVlKTtcclxuICAgICAgdGhpcy5kaWZmUGFyc2VyLmRpZmZfY2hhcnNUb0xpbmVzXyhkaWZmcywgbGluZXNBcnJheSk7XHJcbiAgICAgIGNvbnN0IHJvd3M6IERpZmZUYWJsZVJvd1Jlc3VsdFtdID0gdGhpcy5mb3JtYXRPdXRwdXQoZGlmZnMpO1xyXG4gICAgICBpZiAoIXJvd3MpIHtcclxuICAgICAgICByZWplY3QoJ0Vycm9yJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJlc29sdmUocm93cyk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZm9ybWF0T3V0cHV0KGRpZmZzOiBEaWZmW10pOiBEaWZmVGFibGVSb3dSZXN1bHRbXSB7XHJcbiAgICBsZXQgbGluZUxlZnQgPSAxO1xyXG4gICAgbGV0IGxpbmVSaWdodCA9IDE7XHJcbiAgICByZXR1cm4gZGlmZnMucmVkdWNlKChyb3dzOiBEaWZmVGFibGVSb3dSZXN1bHRbXSwgZGlmZjogRGlmZikgPT4ge1xyXG4gICAgICBpZiAoIXJvd3MpIHtcclxuICAgICAgICByb3dzID0gW107XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgZGlmZlR5cGU6IG51bWJlciA9IGRpZmZbMF07XHJcbiAgICAgIGNvbnN0IGRpZmZWYWx1ZTogc3RyaW5nID0gZGlmZlsxXTtcclxuICAgICAgbGV0IGxlZnREaWZmUm93OiBEaWZmVGFibGVSb3dSZXN1bHQgPSBudWxsO1xyXG4gICAgICBsZXQgcmlnaHREaWZmUm93OiBEaWZmVGFibGVSb3dSZXN1bHQgPSBudWxsO1xyXG4gICAgICBsZXQgbGVmdENvbnRlbnQ6IERpZmZMaW5lUmVzdWx0ID0gbnVsbDtcclxuICAgICAgbGV0IHJpZ2h0Q29udGVudDogRGlmZkxpbmVSZXN1bHQgPSBudWxsO1xyXG4gICAgICBsZXQgcm93VGVtcDogRGlmZlRhYmxlUm93UmVzdWx0ID0gbnVsbDtcclxuICAgICAgc3dpdGNoIChkaWZmVHlwZSkge1xyXG4gICAgICAgIGNhc2UgRElGRl9FUVVBTDogLy8gMFxyXG4gICAgICAgICAgZGlmZlZhbHVlXHJcbiAgICAgICAgICAgIC5zcGxpdCgnXFxuJylcclxuICAgICAgICAgICAgLmZpbHRlcigodmFsdWUsIGluZGV4LCBhcnJheSkgPT4ge1xyXG4gICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gYXJyYXkubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICFpc0VtcHR5KHZhbHVlKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5mb3JFYWNoKGxpbmUgPT4ge1xyXG4gICAgICAgICAgICAgIGxlZnRDb250ZW50ID0ge1xyXG4gICAgICAgICAgICAgICAgbGluZU51bWJlcjogbGluZUxlZnQsXHJcbiAgICAgICAgICAgICAgICBsaW5lQ29udGVudDogbGluZSxcclxuICAgICAgICAgICAgICAgIGxpbmVEaWZmczogW10sXHJcbiAgICAgICAgICAgICAgICBwcmVmaXg6ICcnXHJcbiAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICByaWdodENvbnRlbnQgPSB7XHJcbiAgICAgICAgICAgICAgICBsaW5lTnVtYmVyOiBsaW5lUmlnaHQsXHJcbiAgICAgICAgICAgICAgICBsaW5lQ29udGVudDogbGluZSxcclxuICAgICAgICAgICAgICAgIGxpbmVEaWZmczogW10sXHJcbiAgICAgICAgICAgICAgICBwcmVmaXg6ICcnXHJcbiAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICByb3dUZW1wID0ge1xyXG4gICAgICAgICAgICAgICAgbGVmdENvbnRlbnQsXHJcbiAgICAgICAgICAgICAgICByaWdodENvbnRlbnQsXHJcbiAgICAgICAgICAgICAgICBiZWxvbmdUbzogJ2JvdGgnLFxyXG4gICAgICAgICAgICAgICAgaGFzRGlmZnM6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgbnVtRGlmZnM6IDAsXHJcbiAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICByb3dzLnB1c2gocm93VGVtcCk7XHJcbiAgICAgICAgICAgICAgbGluZVJpZ2h0ID0gbGluZVJpZ2h0ICsgMTtcclxuICAgICAgICAgICAgICBsaW5lTGVmdCA9IGxpbmVMZWZ0ICsgMTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIERJRkZfREVMRVRFOiAvLyAtMVxyXG4gICAgICAgICAgZGlmZlZhbHVlXHJcbiAgICAgICAgICAgIC5zcGxpdCgnXFxuJylcclxuICAgICAgICAgICAgLmZpbHRlcigodmFsdWUsIGluZGV4LCBhcnJheSkgPT4ge1xyXG4gICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gYXJyYXkubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICFpc0VtcHR5KHZhbHVlKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5mb3JFYWNoKGxpbmUgPT4ge1xyXG4gICAgICAgICAgICAgIHJpZ2h0RGlmZlJvdyA9IHJvd3MuZmluZChcclxuICAgICAgICAgICAgICAgIHJvdyA9PiAhcm93LmxlZnRDb250ZW50ICYmIHJvdy5yaWdodENvbnRlbnQgJiYgcm93LnJpZ2h0Q29udGVudC5saW5lTnVtYmVyID09PSBsaW5lTGVmdCAmJiByb3cucmlnaHRDb250ZW50LnByZWZpeCAhPT0gJydcclxuICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgIGxlZnRDb250ZW50ID0ge1xyXG4gICAgICAgICAgICAgICAgbGluZU51bWJlcjogbGluZUxlZnQsXHJcbiAgICAgICAgICAgICAgICBsaW5lQ29udGVudDogbGluZSxcclxuICAgICAgICAgICAgICAgIGxpbmVEaWZmczogW3sgY29udGVudDogbGluZSwgaXNEaWZmOiB0cnVlIH1dLFxyXG4gICAgICAgICAgICAgICAgcHJlZml4OiAnLSdcclxuICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgIGlmIChyaWdodERpZmZSb3cpIHtcclxuICAgICAgICAgICAgICAgIHJpZ2h0RGlmZlJvdy5sZWZ0Q29udGVudCA9IGxlZnRDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgcmlnaHREaWZmUm93LmxlZnRDb250ZW50LmxpbmVEaWZmcyA9IHRoaXMuZ2V0RGlmZlBhcnRzKFxyXG4gICAgICAgICAgICAgICAgICByaWdodERpZmZSb3cubGVmdENvbnRlbnQubGluZUNvbnRlbnQsXHJcbiAgICAgICAgICAgICAgICAgIHJpZ2h0RGlmZlJvdy5yaWdodENvbnRlbnQubGluZUNvbnRlbnRcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICByaWdodERpZmZSb3cucmlnaHRDb250ZW50LmxpbmVEaWZmcyA9IHRoaXMuZ2V0RGlmZlBhcnRzKFxyXG4gICAgICAgICAgICAgICAgICByaWdodERpZmZSb3cucmlnaHRDb250ZW50LmxpbmVDb250ZW50LFxyXG4gICAgICAgICAgICAgICAgICByaWdodERpZmZSb3cubGVmdENvbnRlbnQubGluZUNvbnRlbnRcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICByaWdodERpZmZSb3cuYmVsb25nVG8gPSAnYm90aCc7XHJcbiAgICAgICAgICAgICAgICByaWdodERpZmZSb3cubnVtRGlmZnMgPSB0aGlzLmNvdW50RGlmZnMocmlnaHREaWZmUm93KTtcclxuICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcm93cy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgbGVmdENvbnRlbnQsXHJcbiAgICAgICAgICAgICAgICAgIHJpZ2h0Q29udGVudDogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgaGFzRGlmZnM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgIGJlbG9uZ1RvOiAnbGVmdCcsXHJcbiAgICAgICAgICAgICAgICAgIG51bURpZmZzOiAxLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGxpbmVMZWZ0ID0gbGluZUxlZnQgKyAxO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgRElGRl9JTlNFUlQ6IC8vIDFcclxuICAgICAgICAgIGRpZmZWYWx1ZVxyXG4gICAgICAgICAgICAuc3BsaXQoJ1xcbicpXHJcbiAgICAgICAgICAgIC5maWx0ZXIoKHZhbHVlLCBpbmRleCwgYXJyYXkpID0+IHtcclxuICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IGFycmF5Lmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAhaXNFbXB0eSh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuZm9yRWFjaChsaW5lID0+IHtcclxuICAgICAgICAgICAgICBsZWZ0RGlmZlJvdyA9IHJvd3MuZmluZChcclxuICAgICAgICAgICAgICAgIHJvdyA9PiByb3cubGVmdENvbnRlbnQgJiYgIXJvdy5yaWdodENvbnRlbnQgJiYgcm93LmxlZnRDb250ZW50LmxpbmVOdW1iZXIgPT09IGxpbmVSaWdodCAmJiByb3cubGVmdENvbnRlbnQucHJlZml4ICE9PSAnJ1xyXG4gICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgcmlnaHRDb250ZW50ID0ge1xyXG4gICAgICAgICAgICAgICAgbGluZU51bWJlcjogbGluZVJpZ2h0LFxyXG4gICAgICAgICAgICAgICAgbGluZUNvbnRlbnQ6IGxpbmUsXHJcbiAgICAgICAgICAgICAgICBsaW5lRGlmZnM6IFt7IGNvbnRlbnQ6IGxpbmUsIGlzRGlmZjogdHJ1ZSB9XSxcclxuICAgICAgICAgICAgICAgIHByZWZpeDogJysnXHJcbiAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICBpZiAobGVmdERpZmZSb3cpIHtcclxuICAgICAgICAgICAgICAgIGxlZnREaWZmUm93LnJpZ2h0Q29udGVudCA9IHJpZ2h0Q29udGVudDtcclxuICAgICAgICAgICAgICAgIGxlZnREaWZmUm93LmxlZnRDb250ZW50LmxpbmVEaWZmcyA9IHRoaXMuZ2V0RGlmZlBhcnRzKFxyXG4gICAgICAgICAgICAgICAgICBsZWZ0RGlmZlJvdy5sZWZ0Q29udGVudC5saW5lQ29udGVudCxcclxuICAgICAgICAgICAgICAgICAgbGVmdERpZmZSb3cucmlnaHRDb250ZW50LmxpbmVDb250ZW50XHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgbGVmdERpZmZSb3cucmlnaHRDb250ZW50LmxpbmVEaWZmcyA9IHRoaXMuZ2V0RGlmZlBhcnRzKFxyXG4gICAgICAgICAgICAgICAgICBsZWZ0RGlmZlJvdy5yaWdodENvbnRlbnQubGluZUNvbnRlbnQsXHJcbiAgICAgICAgICAgICAgICAgIGxlZnREaWZmUm93LmxlZnRDb250ZW50LmxpbmVDb250ZW50XHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgbGVmdERpZmZSb3cuYmVsb25nVG8gPSAnYm90aCc7XHJcbiAgICAgICAgICAgICAgICBsZWZ0RGlmZlJvdy5udW1EaWZmcyA9IHRoaXMuY291bnREaWZmcyhsZWZ0RGlmZlJvdyk7XHJcbiAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJvd3MucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgIGxlZnRDb250ZW50OiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICByaWdodENvbnRlbnQsXHJcbiAgICAgICAgICAgICAgICAgIGhhc0RpZmZzOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICBiZWxvbmdUbzogJ3JpZ2h0JyxcclxuICAgICAgICAgICAgICAgICAgbnVtRGlmZnM6IDEsXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgbGluZVJpZ2h0ID0gbGluZVJpZ2h0ICsgMTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gcm93cztcclxuICAgIH0sIFtdKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY291bnREaWZmcyhyZXN1bHQ6IERpZmZUYWJsZVJvd1Jlc3VsdCk6IG51bWJlciB7XHJcbiAgICBsZXQgZGlmZkNvdW50ID0gMDtcclxuICAgIGlmIChyZXN1bHQubGVmdENvbnRlbnQpIHtcclxuICAgICAgZGlmZkNvdW50ICs9IHJlc3VsdC5sZWZ0Q29udGVudC5saW5lRGlmZnMuZmlsdGVyKGRpZmYgPT4gZGlmZi5pc0RpZmYpLmxlbmd0aDtcclxuICAgIH1cclxuICAgIGlmIChyZXN1bHQubGVmdENvbnRlbnQpIHtcclxuICAgICAgZGlmZkNvdW50ICs9IHJlc3VsdC5yaWdodENvbnRlbnQubGluZURpZmZzLmZpbHRlcihkaWZmID0+IGRpZmYuaXNEaWZmKS5sZW5ndGg7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZGlmZkNvdW50O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXREaWZmUGFydHModmFsdWU6IHN0cmluZywgY29tcGFyZVZhbHVlOiBzdHJpbmcpOiBEaWZmUGFydFtdIHtcclxuICAgIGNvbnN0IGRpZmZQYXJ0czogRGlmZlBhcnRbXSA9IFtdO1xyXG4gICAgbGV0IGkgPSAwO1xyXG4gICAgbGV0IGogPSAwO1xyXG4gICAgbGV0IHNoYXJlZCA9ICcnO1xyXG4gICAgbGV0IGRpZmYgPSAnJztcclxuXHJcbiAgICB3aGlsZSAoaSA8IHZhbHVlLmxlbmd0aCkge1xyXG4gICAgICBpZiAodmFsdWVbaV0gPT09IGNvbXBhcmVWYWx1ZVtqXSAmJiBqIDwgY29tcGFyZVZhbHVlLmxlbmd0aCkge1xyXG4gICAgICAgIGlmIChkaWZmICE9PSAnJykge1xyXG4gICAgICAgICAgZGlmZlBhcnRzLnB1c2goeyBjb250ZW50OiBkaWZmLCBpc0RpZmY6IHRydWUgfSk7XHJcbiAgICAgICAgICBkaWZmID0gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNoYXJlZCArPSB2YWx1ZVtpXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAoc2hhcmVkICE9PSAnJykge1xyXG4gICAgICAgICAgZGlmZlBhcnRzLnB1c2goeyBjb250ZW50OiBzaGFyZWQsIGlzRGlmZjogZmFsc2UgfSk7XHJcbiAgICAgICAgICBzaGFyZWQgPSAnJztcclxuICAgICAgICB9XHJcbiAgICAgICAgZGlmZiArPSB2YWx1ZVtpXTtcclxuICAgICAgfVxyXG4gICAgICBpKys7XHJcbiAgICAgIGorKztcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZGlmZiAhPT0gJycpIHtcclxuICAgICAgZGlmZlBhcnRzLnB1c2goeyBjb250ZW50OiBkaWZmLCBpc0RpZmY6IHRydWUgfSk7XHJcbiAgICB9IGVsc2UgaWYgKHNoYXJlZCAhPT0gJycpIHtcclxuICAgICAgZGlmZlBhcnRzLnB1c2goeyBjb250ZW50OiBzaGFyZWQsIGlzRGlmZjogZmFsc2UgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGRpZmZQYXJ0cztcclxuICB9XHJcbn1cclxuIl19