UNPKG

ng-diff-match-patch-att

Version:

A Diff-Match-Patch component for your Angular 6+ applications

285 lines (284 loc) 28.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Component, Input } from '@angular/core'; import { DiffMatchPatchService } from './diffMatchPatch.service'; /** @typedef {?} */ var DiffCalculation; export class LineCompareComponent { /** * @param {?} dmp */ constructor(dmp) { this.dmp = dmp; } /** * @return {?} */ ngOnInit() { this.updateHtml(); } /** * @return {?} */ ngOnChanges() { this.updateHtml(); } /** * @return {?} */ updateHtml() { if (typeof this.left === 'number' || typeof this.left === 'boolean') { this.left = this.left.toString(); } if (typeof this.right === 'number' || typeof this.right === 'boolean') { this.right = this.right.toString(); } this.calculateLineDiff(this.dmp.getLineDiff(this.left, this.right)); } /** * @param {?} diffs * @return {?} */ calculateLineDiff(diffs) { /** @type {?} */ const diffCalculation = { lines: [], lineLeft: 1, lineRight: 1 }; this.isContentEqual = diffs.length === 1 && diffs[0][0] === 0 /* Equal */; if (this.isContentEqual) { this.calculatedDiff = []; return; } for (let i = 0; i < diffs.length; i++) { /** @type {?} */ const diff = diffs[i]; /** @type {?} */ let diffLines = diff[1].split(/\r?\n/); // If the original line had a \r\n at the end then remove the // empty string after it. if (diffLines[diffLines.length - 1].length == 0) { diffLines.pop(); } switch (diff[0]) { case 0 /* Equal */: { /** @type {?} */ const isFirstDiff = i === 0; /** @type {?} */ const isLastDiff = i === diffs.length - 1; this.outputEqualDiff(diffLines, diffCalculation, isFirstDiff, isLastDiff); break; } case -1 /* Delete */: { this.outputDeleteDiff(diffLines, diffCalculation); break; } case 1 /* Insert */: { this.outputInsertDiff(diffLines, diffCalculation); break; } } } this.calculatedDiff = diffCalculation.lines; } /** * @param {?} diffLines * @param {?} diffCalculation * @param {?} isFirstDiff * @param {?} isLastDiff * @return {?} */ outputEqualDiff(diffLines, diffCalculation, isFirstDiff, isLastDiff) { if (this.lineContextSize && diffLines.length > this.lineContextSize) { if (isFirstDiff) { /** @type {?} */ const lineIncrement = diffLines.length - this.lineContextSize; diffCalculation.lineLeft += lineIncrement; diffCalculation.lineRight += lineIncrement; diffLines = diffLines.slice(diffLines.length - this.lineContextSize, diffLines.length); } else if (isLastDiff) { // Take only the first 'lineContextSize' lines from the final diff diffLines = diffLines.slice(0, this.lineContextSize); } else if (diffLines.length > 2 * this.lineContextSize) { // Take the first 'lineContextSize' lines from this diff to provide context for the last diff this.outputEqualDiffLines(diffLines.slice(0, this.lineContextSize), diffCalculation); // Output a special line indicating that some content is equal and has been skipped diffCalculation.lines.push(['dmp-line-compare-equal', '...', '...', '...']); /** @type {?} */ const numberOfSkippedLines = diffLines.length - (2 * this.lineContextSize); diffCalculation.lineLeft += numberOfSkippedLines; diffCalculation.lineRight += numberOfSkippedLines; // Take the last 'lineContextSize' lines from this diff to provide context for the next diff this.outputEqualDiffLines(diffLines.slice(diffLines.length - this.lineContextSize), diffCalculation); // This if branch has already output the diff lines so we return early to avoid outputting the lines // at the end of the method. return; } } this.outputEqualDiffLines(diffLines, diffCalculation); } /** * @param {?} diffLines * @param {?} diffCalculation * @return {?} */ outputEqualDiffLines(diffLines, diffCalculation) { for (const line of diffLines) { diffCalculation.lines.push(['dmp-line-compare-equal', `${diffCalculation.lineLeft}`, `${diffCalculation.lineRight}`, line]); diffCalculation.lineLeft++; diffCalculation.lineRight++; } } /** * @param {?} diffLines * @param {?} diffCalculation * @return {?} */ outputDeleteDiff(diffLines, diffCalculation) { for (const line of diffLines) { diffCalculation.lines.push(['dmp-line-compare-delete', `${diffCalculation.lineLeft}`, '-', line]); diffCalculation.lineLeft++; } } /** * @param {?} diffLines * @param {?} diffCalculation * @return {?} */ outputInsertDiff(diffLines, diffCalculation) { for (const line of diffLines) { diffCalculation.lines.push(['dmp-line-compare-insert', '-', `${diffCalculation.lineRight}`, line]); diffCalculation.lineRight++; } } } LineCompareComponent.decorators = [ { type: Component, args: [{ selector: 'dmp-line-compare', styles: [` div.dmp-line-compare { display: flex; flex-direction: row; border: 1px solid #808080; font-family: Consolas, Courier, monospace; width: 911px; } div.dmp-line-compare-margin { width: 101px; } div.dmp-line-compare-content { position: relative; top: 0px; left: 0px; flex-grow: 1; overflow-x: scroll; } div.dmp-line-compare-content-wrapper { position: absolute; top: 0px; left: 0px; display: flex; flex-direction: column; align-items: stretch; } div.dmp-line-compare-left { width: 50px; text-align: center; color: #484848; } div.dmp-line-compare-equal>div.dmp-line-compare-left, div.dmp-line-compare-equal>div.dmp-line-compare-right { background-color: #dedede; } div.dmp-line-compare-insert>div.dmp-line-compare-left, div.dmp-line-compare-insert>div.dmp-line-compare-right { background-color: #8bfb6f; } div.dmp-line-compare-delete>div.dmp-line-compare-left, div.dmp-line-compare-delete>div.dmp-line-compare-right { background-color: #f56868; } div.dmp-line-compare-right { width: 50px; text-align: center; color: #484848; border-right: 1px solid #888888; } div.dmp-line-compare-text { white-space: pre; padding-left: 10px; min-width: 800px; } .dmp-line-compare-delete { background-color: #ff8c8c; } .dmp-line-compare-insert { background-color: #9dff97; } .dmp-line-compare-delete>div { display: inline-block; } .dmp-line-compare-insert>div { display: inline-block; } .dmp-line-compare-equal>div { display: inline-block; } .dmp-margin-bottom-spacer { height: 20px; background-color: #dedede; border-right: 1px solid #888888; } `], template: ` <div class="dmp-line-compare-no-changes-text" *ngIf="isContentEqual"> There are no changes to display. </div> <div class="dmp-line-compare" *ngIf="!isContentEqual"> <div class="dmp-line-compare-margin"> <div [ngClass]="lineDiff[0]" *ngFor="let lineDiff of calculatedDiff"> <div class="dmp-line-compare-left">{{lineDiff[1]}}</div><!-- No space --><div class="dmp-line-compare-right">{{lineDiff[2]}}</div> </div> <div class="dmp-margin-bottom-spacer"></div> </div><!-- No space --><div class="dmp-line-compare-content"> <div class="dmp-line-compare-content-wrapper"> <div [ngClass]="lineDiff[0]" *ngFor="let lineDiff of calculatedDiff"> <div class="dmp-line-compare-text">{{lineDiff[3]}}</div> </div> </div> </div> </div> ` },] }, ]; /** @nocollapse */ LineCompareComponent.ctorParameters = () => [ { type: DiffMatchPatchService } ]; LineCompareComponent.propDecorators = { left: [{ type: Input }], right: [{ type: Input }], lineContextSize: [{ type: Input }] }; if (false) { /** @type {?} */ LineCompareComponent.prototype.left; /** @type {?} */ LineCompareComponent.prototype.right; /** @type {?} */ LineCompareComponent.prototype.lineContextSize; /** @type {?} */ LineCompareComponent.prototype.calculatedDiff; /** @type {?} */ LineCompareComponent.prototype.isContentEqual; /** @type {?} */ LineCompareComponent.prototype.dmp; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGluZUNvbXBhcmUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctZGlmZi1tYXRjaC1wYXRjaC1hdHQvIiwic291cmNlcyI6WyJsaWIvbGluZUNvbXBhcmUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFFcEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7OztBQWdIakUsTUFBTTs7OztnQkFjUTtRQUFBLFFBQUcsR0FBSCxHQUFHOzs7OztJQUVSLFFBQVE7UUFDYixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Ozs7O0lBR2IsV0FBVztRQUNoQixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Ozs7O0lBR1osVUFBVTtRQUNoQixFQUFFLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ3BFLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztTQUNsQztRQUNELEVBQUUsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLEtBQUssS0FBSyxRQUFRLElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDdEUsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ3BDO1FBQ0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Ozs7OztJQUc5RCxpQkFBaUIsQ0FBQyxLQUFrQjs7UUFDMUMsTUFBTSxlQUFlLEdBQW9CO1lB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QWdDO1FBQ2xDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sSUFBSSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDN0IsZUFBZSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyx5QkFBeUIsRUFBRSxHQUFHLGVBQWUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNsRyxlQUFlLENBQUMsUUFBUSxFQUFFLENBQUM7U0FDNUI7Ozs7Ozs7SUFHSyxnQkFBZ0IsQ0FDcEIsU0FBbUIsRUFDbkIsZUFBZ0M7UUFDbEMsR0FBRyxDQUFDLENBQUMsTUFBTSxJQUFJLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQztZQUM3QixlQUFlLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLHlCQUF5QixFQUFFLEdBQUcsRUFBRSxHQUFHLGVBQWUsQ0FBQyxTQUFTLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ25HLGVBQWUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztTQUM3Qjs7OztZQTdQSixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGtCQUFrQjtnQkFDNUIsTUFBTSxFQUFFLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEVSLENBQUM7Z0JBQ0YsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CVDthQUNGOzs7O1lBL0dRLHFCQUFxQjs7O21CQWlIM0IsS0FBSztvQkFFTCxLQUFLOzhCQUlMLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkluaXQsIE9uQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRGlmZiwgRGlmZk9wIH0gZnJvbSAnLi9kaWZmTWF0Y2hQYXRjaCc7XG5pbXBvcnQgeyBEaWZmTWF0Y2hQYXRjaFNlcnZpY2UgfSBmcm9tICcuL2RpZmZNYXRjaFBhdGNoLnNlcnZpY2UnO1xuXG4vKiBIb2xkcyB0aGUgc3RhdGUgb2YgdGhlIGNhbGN1bGF0aW9uIG9mIHRoZSBkaWZmIHJlc3VsdCB3ZSBpbnRlbmQgdG8gZGlzcGxheS5cbiAqICA+IGxpbmVzIGNvbnRhaW5zIHRoZSBkYXRhIHRoYXQgd2lsbCBiZSBkaXNwbGF5ZWQgb24gc2NyZWVuLlxuICogID4gbGluZUxlZnQga2VlcHMgdHJhY2sgb2YgdGhlIGRvY3VtZW50IGxpbmUgbnVtYmVyIGluIHRoZSBbbGVmdF0gaW5wdXQuXG4gKiAgPiBsaW5lUmlnaHQga2VlcHMgdHJhY2sgb2YgdGhlIGRvY3VtZW50IGxpbmUgbnVtYmVyIGluIHRoZSBbcmlnaHRdIGlucHV0LlxuICovXG50eXBlIERpZmZDYWxjdWxhdGlvbiA9IHtcbiAgbGluZXM6IEFycmF5PFtzdHJpbmcsIHN0cmluZywgc3RyaW5nLCBzdHJpbmddPixcbiAgbGluZUxlZnQ6IG51bWJlcixcbiAgbGluZVJpZ2h0OiBudW1iZXJcbn07XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2RtcC1saW5lLWNvbXBhcmUnLFxuICBzdHlsZXM6IFtgXG4gICAgZGl2LmRtcC1saW5lLWNvbXBhcmUge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAjODA4MDgwO1xuICAgICAgZm9udC1mYW1pbHk6IENvbnNvbGFzLCBDb3VyaWVyLCBtb25vc3BhY2U7XG4gICAgICB3aWR0aDogOTExcHg7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLW1hcmdpbiB7XG4gICAgICB3aWR0aDogMTAxcHg7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWNvbnRlbnQge1xuICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgdG9wOiAwcHg7XG4gICAgICBsZWZ0OiAwcHg7XG4gICAgICBmbGV4LWdyb3c6IDE7XG4gICAgICBvdmVyZmxvdy14OiBzY3JvbGw7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWNvbnRlbnQtd3JhcHBlciB7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICB0b3A6IDBweDtcbiAgICAgIGxlZnQ6IDBweDtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgYWxpZ24taXRlbXM6IHN0cmV0Y2g7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWxlZnQge1xuICAgICAgd2lkdGg6IDUwcHg7XG4gICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICBjb2xvcjogIzQ4NDg0ODtcbiAgICB9XG4gICAgZGl2LmRtcC1saW5lLWNvbXBhcmUtZXF1YWw+ZGl2LmRtcC1saW5lLWNvbXBhcmUtbGVmdCxcbiAgICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWVxdWFsPmRpdi5kbXAtbGluZS1jb21wYXJlLXJpZ2h0IHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICNkZWRlZGU7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWluc2VydD5kaXYuZG1wLWxpbmUtY29tcGFyZS1sZWZ0LFxuICAgICAgZGl2LmRtcC1saW5lLWNvbXBhcmUtaW5zZXJ0PmRpdi5kbXAtbGluZS1jb21wYXJlLXJpZ2h0IHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICM4YmZiNmY7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLWRlbGV0ZT5kaXYuZG1wLWxpbmUtY29tcGFyZS1sZWZ0LFxuICAgICAgZGl2LmRtcC1saW5lLWNvbXBhcmUtZGVsZXRlPmRpdi5kbXAtbGluZS1jb21wYXJlLXJpZ2h0IHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICNmNTY4Njg7XG4gICAgfVxuICAgIGRpdi5kbXAtbGluZS1jb21wYXJlLXJpZ2h0IHtcbiAgICAgIHdpZHRoOiA1MHB4O1xuICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgY29sb3I6ICM0ODQ4NDg7XG4gICAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjODg4ODg4O1xuICAgIH1cbiAgICBkaXYuZG1wLWxpbmUtY29tcGFyZS10ZXh0IHtcbiAgICAgIHdoaXRlLXNwYWNlOiBwcmU7XG4gICAgICBwYWRkaW5nLWxlZnQ6IDEwcHg7XG4gICAgICBtaW4td2lkdGg6IDgwMHB4O1xuICAgIH1cbiAgICAuZG1wLWxpbmUtY29tcGFyZS1kZWxldGUge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2ZmOGM4YztcbiAgICB9XG4gICAgLmRtcC1saW5lLWNvbXBhcmUtaW5zZXJ0IHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICM5ZGZmOTc7XG4gICAgfVxuICAgIC5kbXAtbGluZS1jb21wYXJlLWRlbGV0ZT5kaXYge1xuICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIH0gIFxuICAgIC5kbXAtbGluZS1jb21wYXJlLWluc2VydD5kaXYge1xuICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIH1cbiAgICAuZG1wLWxpbmUtY29tcGFyZS1lcXVhbD5kaXYge1xuICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIH1cbiAgICAuZG1wLW1hcmdpbi1ib3R0b20tc3BhY2VyIHtcbiAgICAgIGhlaWdodDogMjBweDtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICNkZWRlZGU7XG4gICAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjODg4ODg4O1xuICAgIH1cbiAgYF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImRtcC1saW5lLWNvbXBhcmUtbm8tY2hhbmdlcy10ZXh0XCIgKm5nSWY9XCJpc0NvbnRlbnRFcXVhbFwiPlxuICAgICAgVGhlcmUgYXJlIG5vIGNoYW5nZXMgdG8gZGlzcGxheS5cbiAgICA8L2Rpdj4gICAgXG4gICAgPGRpdiBjbGFzcz1cImRtcC1saW5lLWNvbXBhcmVcIiAqbmdJZj1cIiFpc0NvbnRlbnRFcXVhbFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImRtcC1saW5lLWNvbXBhcmUtbWFyZ2luXCI+XG4gICAgICAgIDxkaXYgW25nQ2xhc3NdPVwibGluZURpZmZbMF1cIiAqbmdGb3I9XCJsZXQgbGluZURpZmYgb2YgY2FsY3VsYXRlZERpZmZcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG1wLWxpbmUtY29tcGFyZS1sZWZ0XCI+e3tsaW5lRGlmZlsxXX19PC9kaXY+PCEtLSBObyBzcGFjZVxuICAgICAgICAtLT48ZGl2IGNsYXNzPVwiZG1wLWxpbmUtY29tcGFyZS1yaWdodFwiPnt7bGluZURpZmZbMl19fTwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRtcC1tYXJnaW4tYm90dG9tLXNwYWNlclwiPjwvZGl2PlxuICAgICAgPC9kaXY+PCEtLSBObyBzcGFjZVxuICAgLS0+PGRpdiBjbGFzcz1cImRtcC1saW5lLWNvbXBhcmUtY29udGVudFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZG1wLWxpbmUtY29tcGFyZS1jb250ZW50LXdyYXBwZXJcIj5cbiAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cImxpbmVEaWZmWzBdXCIgKm5nRm9yPVwibGV0IGxpbmVEaWZmIG9mIGNhbGN1bGF0ZWREaWZmXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG1wLWxpbmUtY29tcGFyZS10ZXh0XCI+e3tsaW5lRGlmZlszXX19PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGBcbn0pXG5leHBvcnQgY2xhc3MgTGluZUNvbXBhcmVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBsZWZ0OiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuO1xuICBASW5wdXQoKVxuICBwdWJsaWMgcmlnaHQ6IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW47XG4gIC8vIFRoZSBudW1iZXIgb2YgbGluZXMgb2YgY29udGV4dCB0byBwcm92aWRlIGVpdGhlciBzaWRlIG9mIGEgRGlmZk9wLkluc2VydCBvciBEaWZmT3AuRGVsZXRlIGRpZmYuXG4gIC8vIENvbnRleHQgaXMgdGFrZW4gZnJvbSBhIERpZmZPcC5FcXVhbCBzZWN0aW9uLlxuICBASW5wdXQoKVxuICBwdWJsaWMgbGluZUNvbnRleHRTaXplOiBudW1iZXI7XG5cbiAgcHVibGljIGNhbGN1bGF0ZWREaWZmOiBBcnJheTxbc3RyaW5nLCBzdHJpbmcsIHN0cmluZywgc3RyaW5nXT47XG4gIHB1YmxpYyBpc0NvbnRlbnRFcXVhbDogYm9vbGVhbjtcblxuICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIGRtcDogRGlmZk1hdGNoUGF0Y2hTZXJ2aWNlKSB7fVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUh0bWwoKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUh0bWwoKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlSHRtbCgpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIHRoaXMubGVmdCA9PT0gJ251bWJlcicgfHwgdHlwZW9mIHRoaXMubGVmdCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aGlzLmxlZnQgPSB0aGlzLmxlZnQudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB0aGlzLnJpZ2h0ID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgdGhpcy5yaWdodCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aGlzLnJpZ2h0ID0gdGhpcy5yaWdodC50b1N0cmluZygpO1xuICAgIH1cbiAgICB0aGlzLmNhbGN1bGF0ZUxpbmVEaWZmKHRoaXMuZG1wLmdldExpbmVEaWZmKHRoaXMubGVmdCwgdGhpcy5yaWdodCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVMaW5lRGlmZihkaWZmczogQXJyYXk8RGlmZj4pOiB2b2lkIHtcbiAgICBjb25zdCBkaWZmQ2FsY3VsYXRpb246IERpZmZDYWxjdWxhdGlvbiA9IHtcbiAgICAgIGxpbmVzOiBbXSxcbiAgICAgIGxpbmVMZWZ0OiAxLFxuICAgICAgbGluZVJpZ2h0OiAxXG4gICAgfTtcblxuICAgIHRoaXMuaXNDb250ZW50RXF1YWwgPSBkaWZmcy5sZW5ndGggPT09IDEgJiYgZGlmZnNbMF1bMF0gPT09IERpZmZPcC5FcXVhbDtcbiAgICBpZiAodGhpcy5pc0NvbnRlbnRFcXVhbCkge1xuICAgICAgdGhpcy5jYWxjdWxhdGVkRGlmZiA9IFtdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGlmZnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGRpZmYgPSBkaWZmc1tpXTtcbiAgICAgIGxldCBkaWZmTGluZXM6IHN0cmluZ1tdID0gZGlmZlsxXS5zcGxpdCgvXFxyP1xcbi8pO1xuXG4gICAgICAvLyBJZiB0aGUgb3JpZ2luYWwgbGluZSBoYWQgYSBcXHJcXG4gYXQgdGhlIGVuZCB0aGVuIHJlbW92ZSB0aGVcbiAgICAgIC8vIGVtcHR5IHN0cmluZyBhZnRlciBpdC5cbiAgICAgIGlmIChkaWZmTGluZXNbZGlmZkxpbmVzLmxlbmd0aCAtIDFdLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIGRpZmZMaW5lcy5wb3AoKTtcbiAgICAgIH1cblxuICAgICAgc3dpdGNoIChkaWZmWzBdKSB7XG4gICAgICAgIGNhc2UgRGlmZk9wLkVxdWFsOiB7XG4gICAgICAgICAgY29uc3QgaXNGaXJzdERpZmYgPSBpID09PSAwO1xuICAgICAgICAgIGNvbnN0IGlzTGFzdERpZmYgPSBpID09PSBkaWZmcy5sZW5ndGggLSAxO1xuICAgICAgICAgIHRoaXMub3V0cHV0RXF1YWxEaWZmKGRpZmZMaW5lcywgZGlmZkNhbGN1bGF0aW9uLCBpc0ZpcnN0RGlmZiwgaXNMYXN0RGlmZik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBEaWZmT3AuRGVsZXRlOiB7XG4gICAgICAgICAgdGhpcy5vdXRwdXREZWxldGVEaWZmKGRpZmZMaW5lcywgZGlmZkNhbGN1bGF0aW9uKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIERpZmZPcC5JbnNlcnQ6IHtcbiAgICAgICAgICB0aGlzLm91dHB1dEluc2VydERpZmYoZGlmZkxpbmVzLCBkaWZmQ2FsY3VsYXRpb24pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jYWxjdWxhdGVkRGlmZiA9IGRpZmZDYWxjdWxhdGlvbi5saW5lcztcbiAgfVxuXG4gIC8qIElmIHRoZSBudW1iZXIgb2YgZGlmZkxpbmVzIGlzIGdyZWF0ZXIgdGhhbiBsaW5lQ29udGV4dFNpemUgdGhlbiB3ZSBtYXkgbmVlZCB0byBhZGp1c3QgdGhlIGRpZmZcbiAgICogdGhhdCBpcyBvdXRwdXQuXG4gICAqICAgPiBJZiB0aGUgZmlyc3QgZGlmZiBvZiBhIGRvY3VtZW50IGlzIERpZmZPcC5FcXVhbCB0aGVuIHRoZSBsZWFkaW5nIGxpbmVzIGNhbiBiZSBkcm9wcGVkXG4gICAqICAgICBsZWF2aW5nIHRoZSBsYXN0ICdsaW5lQ29udGV4dFNpemUnIGxpbmVzIGZvciBjb250ZXh0LlxuICAgKiAgID4gSWYgdGhlIGxhc3QgZGlmZiBvZiBhIGRvY3VtZW50IGlzIERpZmZPcC5FcXVhbCB0aGVuIHRoZSB0cmFpbGluZyBsaW5lcyBjYW4gYmUgZHJvcHBlZFxuICAgKiAgICAgbGVhdmluZyB0aGUgZmlyc3QgJ2xpbmVDb250ZXh0U2l6ZScgbGluZXMgZm9yIGNvbnRleHQuXG4gICAqICAgPiBJZiB0aGUgZGlmZiBpcyBhIERpZmZPcC5FcXVhbCBvY2N1cnMgaW4gdGhlIG1pZGRsZSB0aGVuIHRoZSBkaWZmcyBlaXRoZXIgc2lkZSBvZiBpdCBtdXN0IGJlXG4gICAqICAgICBEaWZmT3AuSW5zZXJ0IG9yIERpZmZPcC5EZWxldGUuIElmIGl0IGhhcyBtb3JlIHRoYW4gMiAqICdsaW5lQ29udGV4dFNpemUnIGxpbmVzIG9mIGNvbnRlbnRcbiAgICogICAgIHRoZW4gdGhlIG1pZGRsZSBsaW5lcyBhcmUgZHJvcHBlZCBsZWF2aW5nIHRoZSBmaXJzdCAnbGluZUNvbnRleHRTaXplJyBhbmQgbGFzdCAnbGluZUNvbnRleHRTaXplJ1xuICAgKiAgICAgbGluZXMgZm9yIGNvbnRleHQuIEEgc3BlY2lhbCBsaW5lIGlzIGluc2VydGVkIHdpdGggJy4uLicgaW5kaWNhdGluZyB0aGF0IGNvbnRlbnQgaXMgc2tpcHBlZC5cbiAgICpcbiAgICogQSBkb2N1bWVudCBjYW5ub3QgY29uc2lzdCBvZiBhIHNpbmdsZSBEaWZmIHdpdGggRGlmZk9wLkVxdWFsIGFuZCByZWFjaCB0aGlzIGZ1bmN0aW9uIGJlY2F1c2VcbiAgICogaW4gdGhpcyBjYXNlIHRoZSBjYWxjdWxhdGVMaW5lRGlmZiBtZXRob2QgcmV0dXJucyBlYXJseS5cbiAgICovXG4gIHByaXZhdGUgb3V0cHV0RXF1YWxEaWZmKFxuICAgICAgZGlmZkxpbmVzOiBzdHJpbmdbXSxcbiAgICAgIGRpZmZDYWxjdWxhdGlvbjogRGlmZkNhbGN1bGF0aW9uLFxuICAgICAgaXNGaXJzdERpZmY6IGJvb2xlYW4sXG4gICAgICBpc0xhc3REaWZmOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubGluZUNvbnRleHRTaXplICYmIGRpZmZMaW5lcy5sZW5ndGggPiB0aGlzLmxpbmVDb250ZXh0U2l6ZSkge1xuICAgICAgaWYgKGlzRmlyc3REaWZmKSB7XG4gICAgICAgIC8vIFRha2UgdGhlIGxhc3QgJ2xpbmVDb250ZXh0U2l6ZScgbGluZXMgZnJvbSB0aGUgZmlyc3QgZGlmZlxuICAgICAgICBjb25zdCBsaW5lSW5jcmVtZW50ID0gZGlmZkxpbmVzLmxlbmd0aCAtIHRoaXMubGluZUNvbnRleHRTaXplO1xuICAgICAgICBkaWZmQ2FsY3VsYXRpb24ubGluZUxlZnQgKz0gbGluZUluY3JlbWVudDtcbiAgICAgICAgZGlmZkNhbGN1bGF0aW9uLmxpbmVSaWdodCArPSBsaW5lSW5jcmVtZW50O1xuICAgICAgICBkaWZmTGluZXMgPSBkaWZmTGluZXMuc2xpY2UoZGlmZkxpbmVzLmxlbmd0aCAtIHRoaXMubGluZUNvbnRleHRTaXplLCBkaWZmTGluZXMubGVuZ3RoKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGlzTGFzdERpZmYpIHtcbiAgICAgICAgLy8gVGFrZSBvbmx5IHRoZSBmaXJzdCAnbGluZUNvbnRleHRTaXplJyBsaW5lcyBmcm9tIHRoZSBmaW5hbCBkaWZmXG4gICAgICAgIGRpZmZMaW5lcyA9IGRpZmZMaW5lcy5zbGljZSgwLCB0aGlzLmxpbmVDb250ZXh0U2l6ZSk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChkaWZmTGluZXMubGVuZ3RoID4gMiAqIHRoaXMubGluZUNvbnRleHRTaXplKSB7XG4gICAgICAgIC8vIFRha2UgdGhlIGZpcnN0ICdsaW5lQ29udGV4dFNpemUnIGxpbmVzIGZyb20gdGhpcyBkaWZmIHRvIHByb3ZpZGUgY29udGV4dCBmb3IgdGhlIGxhc3QgZGlmZlxuICAgICAgICB0aGlzLm91dHB1dEVxdWFsRGlmZkxpbmVzKGRpZmZMaW5lcy5zbGljZSgwLCB0aGlzLmxpbmVDb250ZXh0U2l6ZSksIGRpZmZDYWxjdWxhdGlvbik7XG5cbiAgICAgICAgLy8gT3V0cHV0IGEgc3BlY2lhbCBsaW5lIGluZGljYXRpbmcgdGhhdCBzb21lIGNvbnRlbnQgaXMgZXF1YWwgYW5kIGhhcyBiZWVuIHNraXBwZWRcbiAgICAgICAgZGlmZkNhbGN1bGF0aW9uLmxpbmVzLnB1c2goWydkbXAtbGluZS1jb21wYXJlLWVxdWFsJywgJy4uLicsICcuLi4nLCAnLi4uJ10pO1xuICAgICAgICBjb25zdCBudW1iZXJPZlNraXBwZWRMaW5lcyA9IGRpZmZMaW5lcy5sZW5ndGggLSAoMiAqIHRoaXMubGluZUNvbnRleHRTaXplKTtcbiAgICAgICAgZGlmZkNhbGN1bGF0aW9uLmxpbmVMZWZ0ICs9IG51bWJlck9mU2tpcHBlZExpbmVzO1xuICAgICAgICBkaWZmQ2FsY3VsYXRpb24ubGluZVJpZ2h0ICs9IG51bWJlck9mU2tpcHBlZExpbmVzO1xuXG4gICAgICAgIC8vIFRha2UgdGhlIGxhc3QgJ2xpbmVDb250ZXh0U2l6ZScgbGluZXMgZnJvbSB0aGlzIGRpZmYgdG8gcHJvdmlkZSBjb250ZXh0IGZvciB0aGUgbmV4dCBkaWZmXG4gICAgICAgIHRoaXMub3V0cHV0RXF1YWxEaWZmTGluZXMoZGlmZkxpbmVzLnNsaWNlKGRpZmZMaW5lcy5sZW5ndGggLSB0aGlzLmxpbmVDb250ZXh0U2l6ZSksIGRpZmZDYWxjdWxhdGlvbik7XG4gICAgICAgIC8vIFRoaXMgaWYgYnJhbmNoIGhhcyBhbHJlYWR5IG91dHB1dCB0aGUgZGlmZiBsaW5lcyBzbyB3ZSByZXR1cm4gZWFybHkgdG8gYXZvaWQgb3V0cHV0dGluZyB0aGUgbGluZXNcbiAgICAgICAgLy8gYXQgdGhlIGVuZCBvZiB0aGUgbWV0aG9kLlxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMub3V0cHV0RXF1YWxEaWZmTGluZXMoZGlmZkxpbmVzLCBkaWZmQ2FsY3VsYXRpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBvdXRwdXRFcXVhbERpZmZMaW5lcyhcbiAgICAgIGRpZmZMaW5lczogc3RyaW5nW10sXG4gICAgICBkaWZmQ2FsY3VsYXRpb246IERpZmZDYWxjdWxhdGlvbik6IHZvaWQge1xuICAgIGZvciAoY29uc3QgbGluZSBvZiBkaWZmTGluZXMpIHtcbiAgICAgIGRpZmZDYWxjdWxhdGlvbi5saW5lcy5wdXNoKFsnZG1wLWxpbmUtY29tcGFyZS1lcXVhbCcsIGAke2RpZmZDYWxjdWxhdGlvbi5saW5lTGVmdH1gLCBgJHtkaWZmQ2FsY3VsYXRpb24ubGluZVJpZ2h0fWAsIGxpbmVdKTtcbiAgICAgIGRpZmZDYWxjdWxhdGlvbi5saW5lTGVmdCsrO1xuICAgICAgZGlmZkNhbGN1bGF0aW9uLmxpbmVSaWdodCsrO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb3V0cHV0RGVsZXRlRGlmZihcbiAgICAgIGRpZmZMaW5lczogc3RyaW5nW10sXG4gICAgICBkaWZmQ2FsY3VsYXRpb246IERpZmZDYWxjdWxhdGlvbik6IHZvaWQge1xuICAgIGZvciAoY29uc3QgbGluZSBvZiBkaWZmTGluZXMpIHtcbiAgICAgIGRpZmZDYWxjdWxhdGlvbi5saW5lcy5wdXNoKFsnZG1wLWxpbmUtY29tcGFyZS1kZWxldGUnLCBgJHtkaWZmQ2FsY3VsYXRpb24ubGluZUxlZnR9YCwgJy0nLCBsaW5lXSk7XG4gICAgICBkaWZmQ2FsY3VsYXRpb24ubGluZUxlZnQrKztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG91dHB1dEluc2VydERpZmYoXG4gICAgICBkaWZmTGluZXM6IHN0cmluZ1tdLFxuICAgICAgZGlmZkNhbGN1bGF0aW9uOiBEaWZmQ2FsY3VsYXRpb24pOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGxpbmUgb2YgZGlmZkxpbmVzKSB7XG4gICAgICBkaWZmQ2FsY3VsYXRpb24ubGluZXMucHVzaChbJ2RtcC1saW5lLWNvbXBhcmUtaW5zZXJ0JywgJy0nLCBgJHtkaWZmQ2FsY3VsYXRpb24ubGluZVJpZ2h0fWAsIGxpbmVdKTtcbiAgICAgIGRpZmZDYWxjdWxhdGlvbi5saW5lUmlnaHQrKztcbiAgICB9XG4gIH1cbn1cbiJdfQ==