1/*istanbul ignore start*/ 2"use strict"; 3 4Object.defineProperty(exports, "__esModule", { 5 value: true 6}); 7exports["default"] = Diff; 8 9/*istanbul ignore end*/ 10function Diff() {} 11 12Diff.prototype = { 13 /*istanbul ignore start*/ 14 15 /*istanbul ignore end*/ 16 diff: function diff(oldString, newString) { 17 /*istanbul ignore start*/ 18 var _options$timeout; 19 20 var 21 /*istanbul ignore end*/ 22 options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 23 var callback = options.callback; 24 25 if (typeof options === 'function') { 26 callback = options; 27 options = {}; 28 } 29 30 this.options = options; 31 var self = this; 32 33 function done(value) { 34 if (callback) { 35 setTimeout(function () { 36 callback(undefined, value); 37 }, 0); 38 return true; 39 } else { 40 return value; 41 } 42 } // Allow subclasses to massage the input prior to running 43 44 45 oldString = this.castInput(oldString); 46 newString = this.castInput(newString); 47 oldString = this.removeEmpty(this.tokenize(oldString)); 48 newString = this.removeEmpty(this.tokenize(newString)); 49 var newLen = newString.length, 50 oldLen = oldString.length; 51 var editLength = 1; 52 var maxEditLength = newLen + oldLen; 53 54 if (options.maxEditLength) { 55 maxEditLength = Math.min(maxEditLength, options.maxEditLength); 56 } 57 58 var maxExecutionTime = 59 /*istanbul ignore start*/ 60 (_options$timeout = 61 /*istanbul ignore end*/ 62 options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : Infinity; 63 var abortAfterTimestamp = Date.now() + maxExecutionTime; 64 var bestPath = [{ 65 oldPos: -1, 66 lastComponent: undefined 67 }]; // Seed editLength = 0, i.e. the content starts with the same values 68 69 var newPos = this.extractCommon(bestPath[0], newString, oldString, 0); 70 71 if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 72 // Identity per the equality and tokenizer 73 return done([{ 74 value: this.join(newString), 75 count: newString.length 76 }]); 77 } // Once we hit the right edge of the edit graph on some diagonal k, we can 78 // definitely reach the end of the edit graph in no more than k edits, so 79 // there's no point in considering any moves to diagonal k+1 any more (from 80 // which we're guaranteed to need at least k+1 more edits). 81 // Similarly, once we've reached the bottom of the edit graph, there's no 82 // point considering moves to lower diagonals. 83 // We record this fact by setting minDiagonalToConsider and 84 // maxDiagonalToConsider to some finite value once we've hit the edge of 85 // the edit graph. 86 // This optimization is not faithful to the original algorithm presented in 87 // Myers's paper, which instead pointlessly extends D-paths off the end of 88 // the edit graph - see page 7 of Myers's paper which notes this point 89 // explicitly and illustrates it with a diagram. This has major performance 90 // implications for some common scenarios. For instance, to compute a diff 91 // where the new text simply appends d characters on the end of the 92 // original text of length n, the true Myers algorithm will take O(n+d^2) 93 // time while this optimization needs only O(n+d) time. 94 95 96 var minDiagonalToConsider = -Infinity, 97 maxDiagonalToConsider = Infinity; // Main worker method. checks all permutations of a given edit length for acceptance. 98 99 function execEditLength() { 100 for (var diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { 101 var basePath = 102 /*istanbul ignore start*/ 103 void 0 104 /*istanbul ignore end*/ 105 ; 106 var removePath = bestPath[diagonalPath - 1], 107 addPath = bestPath[diagonalPath + 1]; 108 109 if (removePath) { 110 // No one else is going to attempt to use this value, clear it 111 bestPath[diagonalPath - 1] = undefined; 112 } 113 114 var canAdd = false; 115 116 if (addPath) { 117 // what newPos will be after we do an insertion: 118 var addPathNewPos = addPath.oldPos - diagonalPath; 119 canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; 120 } 121 122 var canRemove = removePath && removePath.oldPos + 1 < oldLen; 123 124 if (!canAdd && !canRemove) { 125 // If this path is a terminal then prune 126 bestPath[diagonalPath] = undefined; 127 continue; 128 } // Select the diagonal that we want to branch from. We select the prior 129 // path whose position in the old string is the farthest from the origin 130 // and does not pass the bounds of the diff graph 131 // TODO: Remove the `+ 1` here to make behavior match Myers algorithm 132 // and prefer to order removals before insertions. 133 134 135 if (!canRemove || canAdd && removePath.oldPos + 1 < addPath.oldPos) { 136 basePath = self.addToPath(addPath, true, undefined, 0); 137 } else { 138 basePath = self.addToPath(removePath, undefined, true, 1); 139 } 140 141 newPos = self.extractCommon(basePath, newString, oldString, diagonalPath); 142 143 if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 144 // If we have hit the end of both strings, then we are done 145 return done(buildValues(self, basePath.lastComponent, newString, oldString, self.useLongestToken)); 146 } else { 147 bestPath[diagonalPath] = basePath; 148 149 if (basePath.oldPos + 1 >= oldLen) { 150 maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); 151 } 152 153 if (newPos + 1 >= newLen) { 154 minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); 155 } 156 } 157 } 158 159 editLength++; 160 } // Performs the length of edit iteration. Is a bit fugly as this has to support the 161 // sync and async mode which is never fun. Loops over execEditLength until a value 162 // is produced, or until the edit length exceeds options.maxEditLength (if given), 163 // in which case it will return undefined. 164 165 166 if (callback) { 167 (function exec() { 168 setTimeout(function () { 169 if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { 170 return callback(); 171 } 172 173 if (!execEditLength()) { 174 exec(); 175 } 176 }, 0); 177 })(); 178 } else { 179 while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { 180 var ret = execEditLength(); 181 182 if (ret) { 183 return ret; 184 } 185 } 186 } 187 }, 188 189 /*istanbul ignore start*/ 190 191 /*istanbul ignore end*/ 192 addToPath: function addToPath(path, added, removed, oldPosInc) { 193 var last = path.lastComponent; 194 195 if (last && last.added === added && last.removed === removed) { 196 return { 197 oldPos: path.oldPos + oldPosInc, 198 lastComponent: { 199 count: last.count + 1, 200 added: added, 201 removed: removed, 202 previousComponent: last.previousComponent 203 } 204 }; 205 } else { 206 return { 207 oldPos: path.oldPos + oldPosInc, 208 lastComponent: { 209 count: 1, 210 added: added, 211 removed: removed, 212 previousComponent: last 213 } 214 }; 215 } 216 }, 217 218 /*istanbul ignore start*/ 219 220 /*istanbul ignore end*/ 221 extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { 222 var newLen = newString.length, 223 oldLen = oldString.length, 224 oldPos = basePath.oldPos, 225 newPos = oldPos - diagonalPath, 226 commonCount = 0; 227 228 while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { 229 newPos++; 230 oldPos++; 231 commonCount++; 232 } 233 234 if (commonCount) { 235 basePath.lastComponent = { 236 count: commonCount, 237 previousComponent: basePath.lastComponent 238 }; 239 } 240 241 basePath.oldPos = oldPos; 242 return newPos; 243 }, 244 245 /*istanbul ignore start*/ 246 247 /*istanbul ignore end*/ 248 equals: function equals(left, right) { 249 if (this.options.comparator) { 250 return this.options.comparator(left, right); 251 } else { 252 return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase(); 253 } 254 }, 255 256 /*istanbul ignore start*/ 257 258 /*istanbul ignore end*/ 259 removeEmpty: function removeEmpty(array) { 260 var ret = []; 261 262 for (var i = 0; i < array.length; i++) { 263 if (array[i]) { 264 ret.push(array[i]); 265 } 266 } 267 268 return ret; 269 }, 270 271 /*istanbul ignore start*/ 272 273 /*istanbul ignore end*/ 274 castInput: function castInput(value) { 275 return value; 276 }, 277 278 /*istanbul ignore start*/ 279 280 /*istanbul ignore end*/ 281 tokenize: function tokenize(value) { 282 return value.split(''); 283 }, 284 285 /*istanbul ignore start*/ 286 287 /*istanbul ignore end*/ 288 join: function join(chars) { 289 return chars.join(''); 290 } 291}; 292 293function buildValues(diff, lastComponent, newString, oldString, useLongestToken) { 294 // First we convert our linked list of components in reverse order to an 295 // array in the right order: 296 var components = []; 297 var nextComponent; 298 299 while (lastComponent) { 300 components.push(lastComponent); 301 nextComponent = lastComponent.previousComponent; 302 delete lastComponent.previousComponent; 303 lastComponent = nextComponent; 304 } 305 306 components.reverse(); 307 var componentPos = 0, 308 componentLen = components.length, 309 newPos = 0, 310 oldPos = 0; 311 312 for (; componentPos < componentLen; componentPos++) { 313 var component = components[componentPos]; 314 315 if (!component.removed) { 316 if (!component.added && useLongestToken) { 317 var value = newString.slice(newPos, newPos + component.count); 318 value = value.map(function (value, i) { 319 var oldValue = oldString[oldPos + i]; 320 return oldValue.length > value.length ? oldValue : value; 321 }); 322 component.value = diff.join(value); 323 } else { 324 component.value = diff.join(newString.slice(newPos, newPos + component.count)); 325 } 326 327 newPos += component.count; // Common case 328 329 if (!component.added) { 330 oldPos += component.count; 331 } 332 } else { 333 component.value = diff.join(oldString.slice(oldPos, oldPos + component.count)); 334 oldPos += component.count; // Reverse add and remove so removes are output first to match common convention 335 // The diffing algorithm is tied to add then remove output and this is the simplest 336 // route to get the desired output with minimal overhead. 337 338 if (componentPos && components[componentPos - 1].added) { 339 var tmp = components[componentPos - 1]; 340 components[componentPos - 1] = components[componentPos]; 341 components[componentPos] = tmp; 342 } 343 } 344 } // Special case handle for when one terminal is ignored (i.e. whitespace). 345 // For this case we merge the terminal into the prior string and drop the change. 346 // This is only available for string mode. 347 348 349 var finalComponent = components[componentLen - 1]; 350 351 if (componentLen > 1 && typeof finalComponent.value === 'string' && (finalComponent.added || finalComponent.removed) && diff.equals('', finalComponent.value)) { 352 components[componentLen - 2].value += finalComponent.value; 353 components.pop(); 354 } 355 356 return components; 357} 358//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWZmL2Jhc2UuanMiXSwibmFtZXMiOlsiRGlmZiIsInByb3RvdHlwZSIsImRpZmYiLCJvbGRTdHJpbmciLCJuZXdTdHJpbmciLCJvcHRpb25zIiwiY2FsbGJhY2siLCJzZWxmIiwiZG9uZSIsInZhbHVlIiwic2V0VGltZW91dCIsInVuZGVmaW5lZCIsImNhc3RJbnB1dCIsInJlbW92ZUVtcHR5IiwidG9rZW5pemUiLCJuZXdMZW4iLCJsZW5ndGgiLCJvbGRMZW4iLCJlZGl0TGVuZ3RoIiwibWF4RWRpdExlbmd0aCIsIk1hdGgiLCJtaW4iLCJtYXhFeGVjdXRpb25UaW1lIiwidGltZW91dCIsIkluZmluaXR5IiwiYWJvcnRBZnRlclRpbWVzdGFtcCIsIkRhdGUiLCJub3ciLCJiZXN0UGF0aCIsIm9sZFBvcyIsImxhc3RDb21wb25lbnQiLCJuZXdQb3MiLCJleHRyYWN0Q29tbW9uIiwiam9pbiIsImNvdW50IiwibWluRGlhZ29uYWxUb0NvbnNpZGVyIiwibWF4RGlhZ29uYWxUb0NvbnNpZGVyIiwiZXhlY0VkaXRMZW5ndGgiLCJkaWFnb25hbFBhdGgiLCJtYXgiLCJiYXNlUGF0aCIsInJlbW92ZVBhdGgiLCJhZGRQYXRoIiwiY2FuQWRkIiwiYWRkUGF0aE5ld1BvcyIsImNhblJlbW92ZSIsImFkZFRvUGF0aCIsImJ1aWxkVmFsdWVzIiwidXNlTG9uZ2VzdFRva2VuIiwiZXhlYyIsInJldCIsInBhdGgiLCJhZGRlZCIsInJlbW92ZWQiLCJvbGRQb3NJbmMiLCJsYXN0IiwicHJldmlvdXNDb21wb25lbnQiLCJjb21tb25Db3VudCIsImVxdWFscyIsImxlZnQiLCJyaWdodCIsImNvbXBhcmF0b3IiLCJpZ25vcmVDYXNlIiwidG9Mb3dlckNhc2UiLCJhcnJheSIsImkiLCJwdXNoIiwic3BsaXQiLCJjaGFycyIsImNvbXBvbmVudHMiLCJuZXh0Q29tcG9uZW50IiwicmV2ZXJzZSIsImNvbXBvbmVudFBvcyIsImNvbXBvbmVudExlbiIsImNvbXBv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IERpZmYoKSB7fVxuXG5EaWZmLnByb3RvdHlwZSA9IHtcbiAgZGlmZihvbGRTdHJpbmcsIG5ld1N0cmluZywgb3B0aW9ucyA9IHt9KSB7XG4gICAgbGV0IGNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNhbGxiYWNrID0gb3B0aW9ucztcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuICAgIGxldCBzZWxmID0gdGhpcztcblxuICAgIGZ1bmN0aW9uIGRvbmUodmFsdWUpIHtcbiAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBjYWxsYmFjayh1bmRlZmluZWQsIHZhbHVlKTsgfSwgMCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFsbG93IHN1YmNsYXNzZXMgdG8gbWFzc2FnZSB0aGUgaW5wdXQgcHJpb3IgdG8gcnVubmluZ1xuICAgIG9sZFN0cmluZyA9IHRoaXMuY2FzdElucHV0KG9sZFN0cmluZyk7XG4gICAgbmV3U3RyaW5nID0gdGhpcy5jYXN0SW5wdXQobmV3U3RyaW5nKTtcblxuICAgIG9sZFN0cmluZyA9IHRoaXMucmVtb3ZlRW1wdHkodGhpcy50b2tlbml6ZShvbGRTdHJpbmcpKTtcbiAgICBuZXdTdHJpbmcgPSB0aGlzLnJlbW92ZUVtcHR5KHRoaXMudG9rZW5pemUobmV3U3RyaW5nKSk7XG5cbiAgICBsZXQgbmV3TGVuID0gbmV3U3RyaW5nLmxlbmd0aCwgb2xkTGVuID0gb2xkU3RyaW5nLmxlbmd0aDtcbiAgICBsZXQgZWRpdExlbmd0aCA9IDE7XG4gICAgbGV0IG1heEVkaXRMZW5ndGggPSBuZXdMZW4gKyBvbGRMZW47XG4gICAgaWYob3B0aW9ucy5tYXhFZGl0TGVuZ3RoKSB7XG4gICAgICBtYXhFZGl0TGVuZ3RoID0gTWF0aC5taW4obWF4RWRpdExlbmd0aCwgb3B0aW9ucy5tYXhFZGl0TGVuZ3RoKTtcbiAgICB9XG4gICAgY29uc3QgbWF4RXhlY3V0aW9uVGltZSA9IG9wdGlvbnMudGltZW91dCA/PyBJbmZpbml0eTtcbiAgICBjb25zdCBhYm9ydEFmdGVyVGltZXN0YW1wID0gRGF0ZS5ub3coKSArIG1heEV4ZWN1dGlvblRpbWU7XG5cbiAgICBsZXQgYmVzdFBhdGggPSBbeyBvbGRQb3M6IC0xLCBsYXN0Q29tcG9uZW50OiB1bmRlZmluZWQgfV07XG5cbiAgICAvLyBTZWVkIGVkaXRMZW5ndGggPSAwLCBpLmUuIHRoZSBjb250ZW50IHN0YXJ0cyB3aXRoIHRoZSBzYW1lIHZhbHVlc1xuICAgIGxldCBuZXdQb3MgPSB0aGlzLmV4dHJhY3RDb21tb24oYmVzdFBhdGhbMF0sIG5ld1N0cmluZywgb2xkU3RyaW5nLCAwKTtcbiAgICBpZiAoYmVzdFBhdGhbMF0ub2xkUG9zICsgMSA+PSBvbGRMZW4gJiYgbmV3UG9zICsgMSA+PSBuZXdMZW4pIHtcbiAgICAgIC8vIElkZW50aXR5IHBlciB0aGUgZXF1YWxpdHkgYW5kIHRva2VuaXplclxuICAgICAgcmV0dXJuIGRvbmUoW3t2YWx1ZTogdGhpcy5qb2luKG5ld1N0cmluZyksIGNvdW50OiBuZXdTdHJpbmcubGVuZ3RofV0pO1xuICAgIH1cblxuICAgIC8vIE9uY2Ugd2UgaGl0IHRoZSByaWdodCBlZGdlIG9mIHRoZSBlZGl0IGdyYXBoIG9uIHNvbWUgZGlhZ29uYWwgaywgd2UgY2FuXG4gICAgLy8gZGVmaW5pdGVseSByZWFjaCB0aGUgZW5kIG9mIHRoZSBlZGl0IGdyYXBoIGluIG5vIG1vcmUgdGhhbiBrIGVkaXRzLCBzb1xuICAgIC8vIHRoZXJlJ3Mgbm8gcG9pbnQgaW4gY29uc2lkZXJpbmcgYW55IG1vdmVzIHRvIGRpYWdvbmFsIGsrMSBhbnkgbW9yZSAoZnJvbVxuICAgIC8vIHdoaWNoIHdlJ3JlIGd1YXJhbnRlZWQgdG8gbmVlZCBhdCBsZWFzdCBrKzEgbW9yZSBlZGl0cykuXG4gICAgLy8gU2ltaWxhcmx5LCBvbmNlIHdlJ3ZlIHJlYWNoZWQgdGhlIGJvdHRvbSBvZiB0aGUgZWRpdCBncmFwaCwgdGhlcmUncyBub1xuICAgIC8vIHBvaW50IGNvbnNpZGVyaW5nIG1vdmVzIHRvIGxvd2VyIGRpYWdvbmFscy5cbiAgICAvLyBXZSByZWNvcmQgdGhpcyBmYWN0IGJ5IHNldHRpbmcgbWluRGlhZ29uYWxUb0NvbnNpZGVyIGFuZFxuICAgIC8vIG1heERpYWdvbmFsVG9Db25zaWRlciB0byBzb21lIGZpbml0ZSB2YWx1ZSBvbmNlIHdlJ3ZlIGhpdCB0aGUgZWRnZSBvZlxuICAgIC8vIHRoZSBlZGl0IGdyYXBoLlxuICAgIC8vIFRoaXMgb3B0aW1pemF0aW9uIGlzIG5vdCBmYWl0aGZ1bCB0byB0aGUgb3JpZ2luYWwgYWxnb3JpdGhtIHByZXNlbnRlZCBpblxuICAgIC8vIE15ZXJzJ3MgcGFwZXIsIHdoaWNoIGluc3RlYWQgcG9pbnRsZXNzbHkgZXh0ZW5kcyBELXBhdGhzIG9mZiB0aGUgZW5kIG9mXG4gICAgLy8gdGhlIGVkaXQgZ3JhcGggLSBzZWUgcGFnZSA3IG9mIE15ZXJzJ3MgcGFwZXIgd2hpY2ggbm90ZXMgdGhpcyBwb2ludFxuICAgIC8vIGV4cGxpY2l0bHkgYW5kIGlsbHVzdHJhdGVzIGl0IHdpdGggYSBkaWFncmFtLiBUaGlzIGhhcyBtYWpvciBwZXJmb3JtYW5jZVxuICAgIC8vIGltcGxpY2F0aW9ucyBmb3Igc29tZSBjb21tb24gc2NlbmFyaW9zLiBGb3IgaW5zdGFuY2UsIHRvIGNvbXB1dGUgYSBkaWZmXG4gICAgLy8gd2hlcmUgdGhlIG5ldyB0ZXh0IHNpbXBseSBhcHBlbmRzIGQgY2hhcmFjdGVycyBvbiB0aGUgZW5kIG9mIHRoZVxuICAgIC8vIG9yaWdpbmFsIHRleHQgb2YgbGVuZ3RoIG4sIHRoZSB0cnVlIE15ZXJzIGFsZ29yaXRobSB3aWxsIHRha2UgTyhuK2ReMilcbiAgICAvLyB0aW1lIHdoaWxlIHRoaXMgb3B0aW1pemF0aW9uIG5lZWRzIG9ubHkgTyhuK2QpIHRpbWUuXG4gICAgbGV0IG1pbkRpYWdvbmFsVG9Db25zaWRlciA9IC1JbmZpbml0eSwgbWF4RGlhZ29uYWxUb0NvbnNpZGVyID0gSW5maW5pdHk7XG5cbiAgICAvLyBNYWluIHdvcmtlciBtZXRob2QuIGNoZWNrcyBhbGwgcGVybXV0YXRpb25zIG9mIGEgZ2l2ZW4gZWRpdCBsZW5ndGggZm9yIGFjY2VwdGFuY2UuXG4gICAgZnVuY3Rpb24gZXhlY0VkaXRMZW5ndGgoKSB7XG4gICAgICBmb3IgKFxuICAgICAgICBsZXQgZGlhZ29uYWxQYXRoID0gTWF0aC5tYXgobWluRGlhZ29uYWxUb0NvbnNpZGVyLCAtZWRpdExlbmd0aCk7XG4gICAgICAgIGRpYWdvbmFsUGF0aCA8PSBNYXRoLm1pbihtYXhEaWFnb25hbFRvQ29uc2lkZXIsIGVkaXRMZW5ndGgpO1xuICAgICAgICBkaWFnb25hbFBhdGggKz0gMlxuICAgICAgKSB7XG4gICAgICAgIGxldCBiYXNlUGF0aDtcbiAgICAgICAgbGV0IHJlbW92ZVBhdGggPSBiZXN0UGF0aFtkaWFnb25hbFBhdGggLSAxXSxcbiAgICAgICAgICAgIGFkZFBhdGggPSBiZXN0UGF0aFtkaWFnb25hbFBhdGggKyAxXTtcbiAgICAgICAgaWYgKHJlbW92ZVBhdGgpIHtcbiAgICAgICAgICAvLyBObyBvbmUgZWxzZSBpcyBnb2luZyB0byBhdHRlbXB0IHRvIHVzZSB0aGlzIHZhbHVlLCBjbGVhciBpdFxuICAgICAgICAgIGJlc3RQYXRoW2RpYWdvbmFsUGF0aCAtIDFdID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNhbkFkZCA9IGZhbHNlO1xuICAgICAgICBpZiAoYWRkUGF0aCkge1xuICAgICAgICAgIC8vIHdoYXQgbmV3UG9zIHdpbGwgYmUgYWZ0ZXIgd2UgZG8gYW4gaW5zZXJ0aW9uOlxuICAgICAgICAgIGNvbnN0IGFkZFBhdGhOZXdQb3MgPSBhZGRQYXRoLm9sZFBvcyAtIGRpYWdvbmFsUGF0aDtcbiAgICAgICAgICBjYW5BZGQgPSBhZGRQYXRoICYmIDAgPD0gYWRkUGF0aE5ld1BvcyAmJiBhZGRQYXRoTmV3UG9zIDwgbmV3TGVuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNhblJlbW92ZSA9IHJlbW92ZVBhdGggJiYgcmVtb3ZlUGF0aC5vbGRQb3MgKyAxIDwgb2xkTGVuO1xuICAgICAgICBpZiAoIWNhbkFkZCAmJiAhY2FuUmVtb3ZlKSB7XG4gICAgICAgICAgLy8gSWYgdGhpcyBwYXRoIGlzIGEgdGVybWluYWwgdGhlbiBwcnVuZVxuICAgICAgICAgIGJlc3RQYXRoW2RpYWdvbmFsUGF0aF0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZWxlY3QgdGhlIGRpYWdvbmFsIHRoYXQgd2Ugd2FudCB0byBicmFuY2ggZnJvbS4gV2Ugc2VsZWN0IHRoZSBwcmlvclxuICAgICAgICAvLyBwYXRoIHdob3NlIHBvc2l0aW9uIGluIHRoZSBvbGQgc3RyaW5nIGlzIHRoZSBmYXJ0aGVzdCBmcm9tIHRoZSBvcmlnaW5cbiAgICAgICAgLy8gYW5kIGRvZXMgbm90IHBhc3MgdGhlIGJvdW5kcyBvZiB0aGUgZGlmZiBncmFwaFxuICAgICAgICAvLyBUT0RPOiBSZW1vdmUgdGhlIGArIDFgIGhlcmUgdG8gbWFrZSBiZWhhdmlvciBtYXRjaCBNeWVycyBhbGdvcml0aG1cbiAgICAgICAgLy8gICAgICAgYW5kIHByZWZlciB0byBvcmRlciByZW1vdmFscyBiZWZvcmUgaW5zZXJ0aW9ucy5cbiAgICAgICAgaWYgKCFjYW5SZW1vdmUgfHwgKGNhbkFkZCAmJiByZW1vdmVQYXRoLm9sZFBvcyArIDEgPCBhZGRQYXRoLm9sZFBvcykpIHtcbiAgICAgICAgICBiYXNlUGF0aCA9IHNlbGYuYWRkVG9QYXRoKGFkZFBhdGgsIHRydWUsIHVuZGVmaW5lZCwgMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYmFzZVBhdGggPSBzZWxmLmFkZFRvUGF0aChyZW1vdmVQYXRoLCB1bmRlZmluZWQsIHRydWUsIDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3UG9zID0gc2VsZi5leHRyYWN0Q29tbW9uKGJhc2VQYXRoLCBuZXdTdHJpbmcsIG9sZFN0cmluZywgZGlhZ29uYWxQYXRoKTtcblxuICAgICAgICBpZiAoYmFzZVBhdGgub2xkUG9zICsgMSA+PSBvbGRMZW4gJiYgbmV3UG9zICsgMSA+PSBuZXdMZW4pIHtcbiAgICAgICAgICAvLyBJZiB3ZSBoYXZlIGhpdCB0aGUgZW5kIG9mIGJvdGggc3RyaW5ncywgdGhlbiB3ZSBhcmUgZG9uZVxuICAgICAgICAgIHJldHVybiBkb25lKGJ1aWxkVmFsdWVzKHNlbGYsIGJhc2VQYXRoLmxhc3RDb21wb25lbnQsIG5ld1N0cmluZywgb2xkU3RyaW5nLCBzZWxmLnVzZUxvbmdlc3RUb2tlbikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJlc3RQYXRoW2RpYWdvbmFsUGF0aF0gPSBiYXNlUGF0aDtcbiAgICAgICAgICBpZiAoYmFzZVBhdGgub2xkUG9zICsgMSA+PSBvbGRMZW4pIHtcbiAgICAgICAgICAgIG1heERpYWdvbmFsVG9Db25zaWRlciA9IE1hdGgubWluKG1heERpYWdvbmFsVG9Db25zaWRlciwgZGlhZ29uYWxQYXRoIC0gMSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChuZXdQb3MgKyAxID49IG5ld0xlbikge1xuICAgICAgICAgICAgbWluRGlhZ29uYWxUb0NvbnNpZGVyID0gTWF0aC5tYXgobWluRGlhZ29uYWxUb0NvbnNpZGVyLCBkaWFnb25hbFBhdGggKyAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZWRpdExlbmd0aCsrO1xuICAgIH1cblxuICAgIC8vIFBlcmZvcm1zIHRoZSBsZW5ndGggb2YgZWRpdCBpdGVyYXRpb24uIElzIGEgYml0IGZ1Z2x5IGFzIHRoaXMgaGFzIHRvIHN1cHBvcnQgdGhlXG4gICAgLy8gc3luYyBhbmQgYXN5bmMgbW9kZSB3aGljaCBpcyBuZXZlciBmdW4uIExvb3BzIG92ZXIgZXhlY0VkaXRMZW5ndGggdW50aWwgYSB2YWx1ZVxuICAgIC8vIGlzIHByb2R1Y2VkLCBvciB1bnRpbCB0aGUgZWRpdCBsZW5ndGggZXhjZWVkcyBvcHRpb25zLm1heEVkaXRMZW5ndGggKGlmIGdpdmVuKSxcbiAgICAvLyBpbiB3aGljaCBjYXNlIGl0IHdpbGwgcmV0dXJuIHVuZGVmaW5lZC5cbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIChmdW5jdGlvbiBleGVjKCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGlmIChlZGl0TGVuZ3RoID4gbWF4RWRpdExlbmd0aCB8fCBEYXRlLm5vdygpID4gYWJvcnRBZnRlclRpbWVzdGFtcCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFleGVjRWRpdExlbmd0aCgpKSB7XG4gICAgICAgICAgICBleGVjKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCAwKTtcbiAgICAgIH0oKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlIChlZGl0TGVuZ3RoIDw9IG1heEVkaXRMZW5ndGggJiYgRGF0ZS5ub3coKSA8PSBhYm9ydEFmdGVyVGltZXN0YW1wKSB7XG4gICAgICAgIGxldCByZXQgPSBleGVjRWRpdExlbmd0aCgpO1xuICAgICAgICBpZiAocmV0KSB7XG4gICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBhZGRUb1BhdGgocGF0aCwgYWRkZWQsIHJlbW92ZWQsIG9sZFBvc0luYykge1xuICAgIGxldCBsYXN0ID0gcGF0aC5sYXN0Q29tcG9uZW50O1xuICAgIGlmIChsYXN0ICYmIGxhc3QuYWRkZWQgPT09IGFkZGVkICYmIGxhc3QucmVtb3ZlZCA9PT0gcmVtb3ZlZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb2xkUG9zOiBwYXRoLm9sZFBvcyArIG9sZFBvc0luYyxcbiAgICAgICAgbGFzdENvbXBvbmVudDoge2NvdW50OiBsYXN0LmNvdW50ICsgMSwgYWRkZWQ6IGFkZGVkLCByZW1vdmVkOiByZW1vdmVkLCBwcmV2aW91c0NvbXBvbmVudDogbGFzdC5wcmV2aW91c0NvbXBvbmVudCB9XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvbGRQb3M6IHBhdGgub2xkUG9zICsgb2xkUG9zSW5jLFxuICAgICAgICBsYXN0Q29tcG9uZW50OiB7Y291bnQ6IDEsIGFkZGVkOiBhZGRlZCwgcmVtb3ZlZDogcmVtb3ZlZCwgcHJldmlvdXNDb21wb25lbnQ6IGxhc3QgfVxuICAgICAgfTtcbiAgICB9XG4gIH0sXG4gIGV4dHJhY3RDb21tb24oYmFzZVBhdGgsIG5ld1N0cmluZywgb2xkU3RyaW5nLCBkaWFnb25hbFBhdGgpIHtcbiAgICBsZXQgbmV3TGVuID0gbmV3U3RyaW5nLmxlbmd0aCxcbiAgICAgICAgb2xkTGVuID0gb2xkU3RyaW5nLmxlbmd0aCxcbiAgICAgICAgb2xkUG9zID0gYmFzZVBhdGgub2xkUG9zLFxuICAgICAgICBuZXdQb3MgPSBvbGRQb3MgLSBkaWFnb25hbFBhdGgsXG5cbiAgICAgICAgY29tbW9uQ291bnQgPSAwO1xuICAgIHdoaWxlIChuZXdQb3MgKyAxIDwgbmV3TGVuICYmIG9sZFBvcyArIDEgPCBvbGRMZW4gJiYgdGhpcy5lcXVhbHMobmV3U3RyaW5nW25ld1BvcyArIDFdLCBvbGRTdHJpbmdbb2xkUG9zICsgMV0pKSB7XG4gICAgICBuZXdQb3MrKztcbiAgICAgIG9sZFBvcysrO1xuICAgICAgY29tbW9uQ291bnQrKztcbiAgICB9XG5cbiAgICBpZiAoY29tbW9uQ291bnQpIHtcbiAgICAgIGJhc2VQYXRoLmxhc3RDb21wb25lbnQgPSB7Y291bnQ6IGNvbW1vbkNvdW50LCBwcmV2aW91c0NvbXBvbmVudDogYmFzZVBhdGgubGFzdENvbXBvbmVudH07XG4gICAgfVxuXG4gICAgYmFzZVBhdGgub2xkUG9zID0gb2xkUG9zO1xuICAgIHJldHVybiBuZXdQb3M7XG4gIH0sXG5cbiAgZXF1YWxzKGxlZnQsIHJpZ2h0KSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5jb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmNvbXBhcmF0b3IobGVmdCwgcmlnaHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbGVmdCA9PT0gcmlnaHRcbiAgICAgICAgfHwgKHRoaXMub3B0aW9ucy5pZ25vcmVDYXNlICYmIGxlZnQudG9Mb3dlckNhc2UoKSA9PT0gcmlnaHQudG9Mb3dlckNhc2UoKSk7XG4gICAgfVxuICB9LFxuICByZW1vdmVFbXB0eShhcnJheSkge1xuICAgIGxldCByZXQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJyYXlbaV0pIHtcbiAgICAgICAgcmV0LnB1c2goYXJyYXlbaV0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9LFxuICBjYXN0SW5wdXQodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIHRva2VuaXplKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlLnNwbGl0KCcnKTtcbiAgfSxcbiAgam9pbihjaGFycykge1xuICAgIHJldHVybiBjaGFycy5qb2luKCcnKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gYnVpbGRWYWx1ZXMoZGlmZiwgbGFzdENvbXBvbmVudCwgbmV3U3RyaW5nLCBvbGRTdHJpbmcsIHVzZUxvbmdlc3RUb2tlbikge1xuICAvLyBGaXJzdCB3ZSBjb252ZXJ0IG91ciBsaW5rZWQgbGlzdCBvZiBjb21wb25lbnRzIGluIHJldmVyc2Ugb3JkZXIgdG8gYW5cbiAgLy8gYXJyYXkgaW4gdGhlIHJpZ2h0IG9yZGVyOlxuICBjb25zdCBjb21wb25lbnRzID0gW107XG4gIGxldCBuZXh0Q29tcG9uZW50O1xuICB3aGlsZSAobGFzdENvbXBvbmVudCkge1xuICAgIGNvbXBvbmVudHMucHVzaChsYXN0Q29tcG9uZW50KTtcbiAgICBuZXh0Q29tcG9uZW50ID0gbGFzdENvbXBvbmVudC5wcmV2aW91c0NvbXBvbmVudDtcbiAgICBkZWxldGUgbGFzdENvbXBvbmVudC5wcmV2aW91c0NvbXBvbmVudDtcbiAgICBsYXN0Q29tcG9uZW50ID0gbmV4dENvbXBvbmVudDtcbiAgfVxuICBjb21wb25lbnRzLnJldmVyc2UoKTtcblxuICBsZXQgY29tcG9uZW50UG9zID0gMCxcbiAgICAgIGNvbXBvbmVudExlbiA9IGNvbXBvbmVudHMubGVuZ3RoLFxuICAgICAgbmV3UG9zID0gMCxcbiAgICAgIG9sZFBvcyA9IDA7XG5cbiAgZm9yICg7IGNvbXBvbmVudFBvcyA8IGNvbXBvbmVudExlbjsgY29tcG9uZW50UG9zKyspIHtcbiAgICBsZXQgY29tcG9uZW50ID0gY29tcG9uZW50c1tjb21wb25lbnRQb3NdO1xuICAgIGlmICghY29tcG9uZW50LnJlbW92ZWQpIHtcbiAgICAgIGlmICghY29tcG9uZW50LmFkZGVkICYmIHVzZUxvbmdlc3RUb2tlbikge1xuICAgICAgICBsZXQgdmFsdWUgPSBuZXdTdHJpbmcuc2xpY2UobmV3UG9zLCBuZXdQb3MgKyBjb21wb25lbnQuY291bnQpO1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLm1hcChmdW5jdGlvbih2YWx1ZSwgaSkge1xuICAgICAgICAgIGxldCBvbGRWYWx1ZSA9IG9sZFN0cmluZ1tvbGRQb3MgKyBpXTtcbiAgICAgICAgICByZXR1cm4gb2xkVmFsdWUubGVuZ3RoID4gdmFsdWUubGVuZ3RoID8gb2xkVmFsdWUgOiB2YWx1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29tcG9uZW50LnZhbHVlID0gZGlmZi5qb2luKHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbXBvbmVudC52YWx1ZSA9IGRpZmYuam9pbihuZXdTdHJpbmcuc2xpY2UobmV3UG9zLCBuZXdQb3MgKyBjb21wb25lbnQuY291bnQpKTtcbiAgICAgIH1cbiAgICAgIG5ld1BvcyArPSBjb21wb25lbnQuY291bnQ7XG5cbiAgICAgIC8vIENvbW1vbiBjYXNlXG4gICAgICBpZiAoIWNvbXBvbmVudC5hZGRlZCkge1xuICAgICAgICBvbGRQb3MgKz0gY29tcG9uZW50LmNvdW50O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb21wb25lbnQudmFsdWUgPSBkaWZmLmpvaW4ob2xkU3RyaW5nLnNsaWNlKG9sZFBvcywgb2xkUG9zICsgY29tcG9uZW50LmNvdW50KSk7XG4gICAgICBvbGRQb3MgKz0gY29tcG9uZW50LmNvdW50O1xuXG4gICAgICAvLyBSZXZlcnNlIGFkZCBhbmQgcmVtb3ZlIHNvIHJlbW92ZXMgYXJlIG91dHB1dCBmaXJzdCB0byBtYXRjaCBjb21tb24gY29udmVudGlvblxuICAgICAgLy8gVGhlIGRpZmZpbmcgYWxnb3JpdGhtIGlzIHRpZWQgdG8gYWRkIHRoZW4gcmVtb3ZlIG91dHB1dCBhbmQgdGhpcyBpcyB0aGUgc2ltcGxlc3RcbiAgICAgIC8vIHJvdXRlIHRvIGdldCB0aGUgZGVzaXJlZCBvdXRwdXQgd2l0aCBtaW5pbWFsIG92ZXJoZWFkLlxuICAgICAgaWYgKGNvbXBvbmVudFBvcyAmJiBjb21wb25lbnRzW2NvbXBvbmVudFBvcyAtIDFdLmFkZGVkKSB7XG4gICAgICAgIGxldCB0bXAgPSBjb21wb25lbnRzW2NvbXBvbmVudFBvcyAtIDFdO1xuICAgICAgICBjb21wb25lbnRzW2NvbXBvbmVudFBvcyAtIDFdID0gY29tcG9uZW50c1tjb21wb25lbnRQb3NdO1xuICAgICAgICBjb21wb25lbnRzW2NvbXBvbmVudFBvc10gPSB0bXA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gU3BlY2lhbCBjYXNlIGhhbmRsZSBmb3Igd2hlbiBvbmUgdGVybWluYWwgaXMgaWdub3JlZCAoaS5lLiB3aGl0ZXNwYWNlKS5cbiAgLy8gRm9yIHRoaXMgY2FzZSB3ZSBtZXJnZSB0aGUgdGVybWluYWwgaW50byB0aGUgcHJpb3Igc3RyaW5nIGFuZCBkcm9wIHRoZSBjaGFuZ2UuXG4gIC8vIFRoaXMgaXMgb25seSBhdmFpbGFibGUgZm9yIHN0cmluZyBtb2RlLlxuICBsZXQgZmluYWxDb21wb25lbnQgPSBjb21wb25lbnRzW2NvbXBvbmVudExlbiAtIDFdO1xuICBpZiAoY29tcG9uZW50TGVuID4gMVxuICAgICAgJiYgdHlwZW9mIGZpbmFsQ29tcG9uZW50LnZhbHVlID09PSAnc3RyaW5nJ1xuICAgICAgJiYgKGZpbmFsQ29tcG9uZW50LmFkZGVkIHx8IGZpbmFsQ29tcG9uZW50LnJlbW92ZWQpXG4gICAgICAmJiBkaWZmLmVxdWFscygnJywgZmluYWxDb21wb25lbnQudmFsdWUpKSB7XG4gICAgY29tcG9uZW50c1tjb21wb25lbnRMZW4gLSAyXS52YWx1ZSArPSBmaW5hbENvbXBvbmVudC52YWx1ZTtcbiAgICBjb21wb25lbnRzLnBvcCgpO1xuICB9XG5cbiAgcmV0dXJuIGNvbXBvbmVudHM7XG59XG4iXX0= 359