@circuitly/diff
Version:
A javascript text diff implementation.
147 lines (142 loc) • 17.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.hasOnlyUnixLineEndings = hasOnlyUnixLineEndings;
exports.hasOnlyWinLineEndings = hasOnlyWinLineEndings;
exports.leadingWs = leadingWs;
exports.longestCommonPrefix = longestCommonPrefix;
exports.longestCommonSuffix = longestCommonSuffix;
exports.maximumOverlap = maximumOverlap;
exports.removePrefix = removePrefix;
exports.removeSuffix = removeSuffix;
exports.replacePrefix = replacePrefix;
exports.replaceSuffix = replaceSuffix;
exports.trailingWs = trailingWs;
function longestCommonPrefix(str1, str2) {
var i;
for (i = 0; i < str1.length && i < str2.length; i++) {
if (str1[i] != str2[i]) {
return str1.slice(0, i);
}
}
return str1.slice(0, i);
}
function longestCommonSuffix(str1, str2) {
var i;
// Unlike longestCommonPrefix, we need a special case to handle all scenarios
// where we return the empty string since str1.slice(-0) will return the
// entire string.
if (!str1 || !str2 || str1[str1.length - 1] != str2[str2.length - 1]) {
return '';
}
for (i = 0; i < str1.length && i < str2.length; i++) {
if (str1[str1.length - (i + 1)] != str2[str2.length - (i + 1)]) {
return str1.slice(-i);
}
}
return str1.slice(-i);
}
function replacePrefix(string, oldPrefix, newPrefix) {
if (string.slice(0, oldPrefix.length) != oldPrefix) {
throw Error("string ".concat(JSON.stringify(string), " doesn't start with prefix ").concat(JSON.stringify(oldPrefix), "; this is a bug"));
}
return newPrefix + string.slice(oldPrefix.length);
}
function replaceSuffix(string, oldSuffix, newSuffix) {
if (!oldSuffix) {
return string + newSuffix;
}
if (string.slice(-oldSuffix.length) != oldSuffix) {
throw Error("string ".concat(JSON.stringify(string), " doesn't end with suffix ").concat(JSON.stringify(oldSuffix), "; this is a bug"));
}
return string.slice(0, -oldSuffix.length) + newSuffix;
}
function removePrefix(string, oldPrefix) {
return replacePrefix(string, oldPrefix, '');
}
function removeSuffix(string, oldSuffix) {
return replaceSuffix(string, oldSuffix, '');
}
function maximumOverlap(string1, string2) {
return string2.slice(0, overlapCount(string1, string2));
}
// Nicked from https://stackoverflow.com/a/60422853/1709587
function overlapCount(a, b) {
// Deal with cases where the strings differ in length
var startA = 0;
if (a.length > b.length) {
startA = a.length - b.length;
}
var endB = b.length;
if (a.length < b.length) {
endB = a.length;
}
// Create a back-reference for each index
// that should be followed in case of a mismatch.
// We only need B to make these references:
var map = Array(endB);
var k = 0; // Index that lags behind j
map[0] = 0;
for (var j = 1; j < endB; j++) {
if (b[j] == b[k]) {
map[j] = map[k]; // skip over the same character (optional optimisation)
} else {
map[j] = k;
}
while (k > 0 && b[j] != b[k]) {
k = map[k];
}
if (b[j] == b[k]) {
k++;
}
}
// Phase 2: use these references while iterating over A
k = 0;
for (var i = startA; i < a.length; i++) {
while (k > 0 && a[i] != b[k]) {
k = map[k];
}
if (a[i] == b[k]) {
k++;
}
}
return k;
}
/**
* Returns true if the string consistently uses Windows line endings.
*/
function hasOnlyWinLineEndings(string) {
return string.includes('\r\n') && !string.startsWith('\n') && !string.match(/[^\r]\n/);
}
/**
* Returns true if the string consistently uses Unix line endings.
*/
function hasOnlyUnixLineEndings(string) {
return !string.includes('\r\n') && string.includes('\n');
}
function trailingWs(string) {
// Yes, this looks overcomplicated and dumb - why not replace the whole function with
// return string match(/\s*$/)[0]
// you ask? Because:
// 1. the trap described at https://markamery.com/blog/quadratic-time-regexes/ would mean doing
// this would cause this function to take O(n²) time in the worst case (specifically when
// there is a massive run of NON-TRAILING whitespace in `string`), and
// 2. the fix proposed in the same blog post, of using a negative lookbehind, is incompatible
// with old Safari versions that we'd like to not break if possible (see
// https://github.com/kpdecker/jsdiff/pull/550)
// It feels absurd to do this with an explicit loop instead of a regex, but I really can't see a
// better way that doesn't result in broken behaviour.
var i;
for (i = string.length - 1; i >= 0; i--) {
if (!string[i].match(/\s/)) {
break;
}
}
return string.substring(i + 1);
}
function leadingWs(string) {
// Thankfully the annoying considerations described in trailingWs don't apply here:
return string.match(/^\s*/)[0];
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJsb25nZXN0Q29tbW9uUHJlZml4Iiwic3RyMSIsInN0cjIiLCJpIiwibGVuZ3RoIiwic2xpY2UiLCJsb25nZXN0Q29tbW9uU3VmZml4IiwicmVwbGFjZVByZWZpeCIsInN0cmluZyIsIm9sZFByZWZpeCIsIm5ld1ByZWZpeCIsIkVycm9yIiwiY29uY2F0IiwiSlNPTiIsInN0cmluZ2lmeSIsInJlcGxhY2VTdWZmaXgiLCJvbGRTdWZmaXgiLCJuZXdTdWZmaXgiLCJyZW1vdmVQcmVmaXgiLCJyZW1vdmVTdWZmaXgiLCJtYXhpbXVtT3ZlcmxhcCIsInN0cmluZzEiLCJzdHJpbmcyIiwib3ZlcmxhcENvdW50IiwiYSIsImIiLCJzdGFydEEiLCJlbmRCIiwibWFwIiwiQXJyYXkiLCJrIiwiaiIsImhhc09ubHlXaW5MaW5lRW5kaW5ncyIsImluY2x1ZGVzIiwic3RhcnRzV2l0aCIsIm1hdGNoIiwiaGFzT25seVVuaXhMaW5lRW5kaW5ncyIsInRyYWlsaW5nV3MiLCJzdWJzdHJpbmciLCJsZWFkaW5nV3MiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbC9zdHJpbmcuanMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGZ1bmN0aW9uIGxvbmdlc3RDb21tb25QcmVmaXgoc3RyMSwgc3RyMikge1xuICBsZXQgaTtcbiAgZm9yIChpID0gMDsgaSA8IHN0cjEubGVuZ3RoICYmIGkgPCBzdHIyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHN0cjFbaV0gIT0gc3RyMltpXSkge1xuICAgICAgcmV0dXJuIHN0cjEuc2xpY2UoMCwgaSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHIxLnNsaWNlKDAsIGkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9uZ2VzdENvbW1vblN1ZmZpeChzdHIxLCBzdHIyKSB7XG4gIGxldCBpO1xuXG4gIC8vIFVubGlrZSBsb25nZXN0Q29tbW9uUHJlZml4LCB3ZSBuZWVkIGEgc3BlY2lhbCBjYXNlIHRvIGhhbmRsZSBhbGwgc2NlbmFyaW9zXG4gIC8vIHdoZXJlIHdlIHJldHVybiB0aGUgZW1wdHkgc3RyaW5nIHNpbmNlIHN0cjEuc2xpY2UoLTApIHdpbGwgcmV0dXJuIHRoZVxuICAvLyBlbnRpcmUgc3RyaW5nLlxuICBpZiAoIXN0cjEgfHwgIXN0cjIgfHwgc3RyMVtzdHIxLmxlbmd0aCAtIDFdICE9IHN0cjJbc3RyMi5sZW5ndGggLSAxXSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCBzdHIxLmxlbmd0aCAmJiBpIDwgc3RyMi5sZW5ndGg7IGkrKykge1xuICAgIGlmIChzdHIxW3N0cjEubGVuZ3RoIC0gKGkgKyAxKV0gIT0gc3RyMltzdHIyLmxlbmd0aCAtIChpICsgMSldKSB7XG4gICAgICByZXR1cm4gc3RyMS5zbGljZSgtaSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHIxLnNsaWNlKC1pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VQcmVmaXgoc3RyaW5nLCBvbGRQcmVmaXgsIG5ld1ByZWZpeCkge1xuICBpZiAoc3RyaW5nLnNsaWNlKDAsIG9sZFByZWZpeC5sZW5ndGgpICE9IG9sZFByZWZpeCkge1xuICAgIHRocm93IEVycm9yKGBzdHJpbmcgJHtKU09OLnN0cmluZ2lmeShzdHJpbmcpfSBkb2Vzbid0IHN0YXJ0IHdpdGggcHJlZml4ICR7SlNPTi5zdHJpbmdpZnkob2xkUHJlZml4KX07IHRoaXMgaXMgYSBidWdgKTtcbiAgfVxuICByZXR1cm4gbmV3UHJlZml4ICsgc3RyaW5nLnNsaWNlKG9sZFByZWZpeC5sZW5ndGgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZVN1ZmZpeChzdHJpbmcsIG9sZFN1ZmZpeCwgbmV3U3VmZml4KSB7XG4gIGlmICghb2xkU3VmZml4KSB7XG4gICAgcmV0dXJuIHN0cmluZyArIG5ld1N1ZmZpeDtcbiAgfVxuXG4gIGlmIChzdHJpbmcuc2xpY2UoLW9sZFN1ZmZpeC5sZW5ndGgpICE9IG9sZFN1ZmZpeCkge1xuICAgIHRocm93IEVycm9yKGBzdHJpbmcgJHtKU09OLnN0cmluZ2lmeShzdHJpbmcpfSBkb2Vzbid0IGVuZCB3aXRoIHN1ZmZpeCAke0pTT04uc3RyaW5naWZ5KG9sZFN1ZmZpeCl9OyB0aGlzIGlzIGEgYnVnYCk7XG4gIH1cbiAgcmV0dXJuIHN0cmluZy5zbGljZSgwLCAtb2xkU3VmZml4Lmxlbmd0aCkgKyBuZXdTdWZmaXg7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVQcmVmaXgoc3RyaW5nLCBvbGRQcmVmaXgpIHtcbiAgcmV0dXJuIHJlcGxhY2VQcmVmaXgoc3RyaW5nLCBvbGRQcmVmaXgsICcnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVN1ZmZpeChzdHJpbmcsIG9sZFN1ZmZpeCkge1xuICByZXR1cm4gcmVwbGFjZVN1ZmZpeChzdHJpbmcsIG9sZFN1ZmZpeCwgJycpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWF4aW11bU92ZXJsYXAoc3RyaW5nMSwgc3RyaW5nMikge1xuICByZXR1cm4gc3RyaW5nMi5zbGljZSgwLCBvdmVybGFwQ291bnQoc3RyaW5nMSwgc3RyaW5nMikpO1xufVxuXG4vLyBOaWNrZWQgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNjA0MjI4NTMvMTcwOTU4N1xuZnVuY3Rpb24gb3ZlcmxhcENvdW50KGEsIGIpIHtcbiAgLy8gRGVhbCB3aXRoIGNhc2VzIHdoZXJlIHRoZSBzdHJpbmdzIGRpZmZlciBpbiBsZW5ndGhcbiAgbGV0IHN0YXJ0QSA9IDA7XG4gIGlmIChhLmxlbmd0aCA+IGIubGVuZ3RoKSB7IHN0YXJ0QSA9IGEubGVuZ3RoIC0gYi5sZW5ndGg7IH1cbiAgbGV0IGVuZEIgPSBiLmxlbmd0aDtcbiAgaWYgKGEubGVuZ3RoIDwgYi5sZW5ndGgpIHsgZW5kQiA9IGEubGVuZ3RoOyB9XG4gIC8vIENyZWF0ZSBhIGJhY2stcmVmZXJlbmNlIGZvciBlYWNoIGluZGV4XG4gIC8vICAgdGhhdCBzaG91bGQgYmUgZm9sbG93ZWQgaW4gY2FzZSBvZiBhIG1pc21hdGNoLlxuICAvLyAgIFdlIG9ubHkgbmVlZCBCIHRvIG1ha2UgdGhlc2UgcmVmZXJlbmNlczpcbiAgbGV0IG1hcCA9IEFycmF5KGVuZEIpO1xuICBsZXQgayA9IDA7IC8vIEluZGV4IHRoYXQgbGFncyBiZWhpbmQgalxuICBtYXBbMF0gPSAwO1xuICBmb3IgKGxldCBqID0gMTsgaiA8IGVuZEI7IGorKykge1xuICAgICAgaWYgKGJbal0gPT0gYltrXSkge1xuICAgICAgICAgIG1hcFtqXSA9IG1hcFtrXTsgLy8gc2tpcCBvdmVyIHRoZSBzYW1lIGNoYXJhY3RlciAob3B0aW9uYWwgb3B0aW1pc2F0aW9uKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtYXBbal0gPSBrO1xuICAgICAgfVxuICAgICAgd2hpbGUgKGsgPiAwICYmIGJbal0gIT0gYltrXSkgeyBrID0gbWFwW2tdOyB9XG4gICAgICBpZiAoYltqXSA9PSBiW2tdKSB7IGsrKzsgfVxuICB9XG4gIC8vIFBoYXNlIDI6IHVzZSB0aGVzZSByZWZlcmVuY2VzIHdoaWxlIGl0ZXJhdGluZyBvdmVyIEFcbiAgayA9IDA7XG4gIGZvciAobGV0IGkgPSBzdGFydEE7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICB3aGlsZSAoayA+IDAgJiYgYVtpXSAhPSBiW2tdKSB7IGsgPSBtYXBba107IH1cbiAgICAgIGlmIChhW2ldID09IGJba10pIHsgaysrOyB9XG4gIH1cbiAgcmV0dXJuIGs7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmluZyBjb25zaXN0ZW50bHkgdXNlcyBXaW5kb3dzIGxpbmUgZW5kaW5ncy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc09ubHlXaW5MaW5lRW5kaW5ncyhzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy5pbmNsdWRlcygnXFxyXFxuJykgJiYgIXN0cmluZy5zdGFydHNXaXRoKCdcXG4nKSAmJiAhc3RyaW5nLm1hdGNoKC9bXlxccl1cXG4vKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmluZyBjb25zaXN0ZW50bHkgdXNlcyBVbml4IGxpbmUgZW5kaW5ncy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc09ubHlVbml4TGluZUVuZGluZ3Moc3RyaW5nKSB7XG4gIHJldHVybiAhc3RyaW5nLmluY2x1ZGVzKCdcXHJcXG4nKSAmJiBzdHJpbmcuaW5jbHVkZXMoJ1xcbicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdHJhaWxpbmdXcyhzdHJpbmcpIHtcbiAgLy8gWWVzLCB0aGlzIGxvb2tzIG92ZXJjb21wbGljYXRlZCBhbmQgZHVtYiAtIHdoeSBub3QgcmVwbGFjZSB0aGUgd2hvbGUgZnVuY3Rpb24gd2l0aFxuICAvLyAgICAgcmV0dXJuIHN0cmluZyBtYXRjaCgvXFxzKiQvKVswXVxuICAvLyB5b3UgYXNrPyBCZWNhdXNlOlxuICAvLyAxLiB0aGUgdHJhcCBkZXNjcmliZWQgYXQgaHR0cHM6Ly9tYXJrYW1lcnkuY29tL2Jsb2cvcXVhZHJhdGljLXRpbWUtcmVnZXhlcy8gd291bGQgbWVhbiBkb2luZ1xuICAvLyAgICB0aGlzIHdvdWxkIGNhdXNlIHRoaXMgZnVuY3Rpb24gdG8gdGFrZSBPKG7CsikgdGltZSBpbiB0aGUgd29yc3QgY2FzZSAoc3BlY2lmaWNhbGx5IHdoZW5cbiAgLy8gICAgdGhlcmUgaXMgYSBtYXNzaXZlIHJ1biBvZiBOT04tVFJBSUxJTkcgd2hpdGVzcGFjZSBpbiBgc3RyaW5nYCksIGFuZFxuICAvLyAyLiB0aGUgZml4IHByb3Bvc2VkIGluIHRoZSBzYW1lIGJsb2cgcG9zdCwgb2YgdXNpbmcgYSBuZWdhdGl2ZSBsb29rYmVoaW5kLCBpcyBpbmNvbXBhdGlibGVcbiAgLy8gICAgd2l0aCBvbGQgU2FmYXJpIHZlcnNpb25zIHRoYXQgd2UnZCBsaWtlIHRvIG5vdCBicmVhayBpZiBwb3NzaWJsZSAoc2VlXG4gIC8vICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9rcGRlY2tlci9qc2RpZmYvcHVsbC81NTApXG4gIC8vIEl0IGZlZWxzIGFic3VyZCB0byBkbyB0aGlzIHdpdGggYW4gZXhwbGljaXQgbG9vcCBpbnN0ZWFkIG9mIGEgcmVnZXgsIGJ1dCBJIHJlYWxseSBjYW4ndCBzZWUgYVxuICAvLyBiZXR0ZXIgd2F5IHRoYXQgZG9lc24ndCByZXN1bHQgaW4gYnJva2VuIGJlaGF2aW91ci5cbiAgbGV0IGk7XG4gIGZvciAoaSA9IHN0cmluZy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGlmICghc3RyaW5nW2ldLm1hdGNoKC9cXHMvKSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHJpbmcuc3Vic3RyaW5nKGkgKyAxKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxlYWRpbmdXcyhzdHJpbmcpIHtcbiAgLy8gVGhhbmtmdWxseSB0aGUgYW5ub3lpbmcgY29uc2lkZXJhdGlvbnMgZGVzY3JpYmVkIGluIHRyYWlsaW5nV3MgZG9uJ3QgYXBwbHkgaGVyZTpcbiAgcmV0dXJuIHN0cmluZy5tYXRjaCgvXlxccyovKVswXTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFPLFNBQVNBLG1CQUFtQkEsQ0FBQ0MsSUFBSSxFQUFFQyxJQUFJLEVBQUU7RUFDOUMsSUFBSUMsQ0FBQztFQUNMLEtBQUtBLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBR0YsSUFBSSxDQUFDRyxNQUFNLElBQUlELENBQUMsR0FBR0QsSUFBSSxDQUFDRSxNQUFNLEVBQUVELENBQUMsRUFBRSxFQUFFO0lBQ25ELElBQUlGLElBQUksQ0FBQ0UsQ0FBQyxDQUFDLElBQUlELElBQUksQ0FBQ0MsQ0FBQyxDQUFDLEVBQUU7TUFDdEIsT0FBT0YsSUFBSSxDQUFDSSxLQUFLLENBQUMsQ0FBQyxFQUFFRixDQUFDLENBQUM7SUFDekI7RUFDRjtFQUNBLE9BQU9GLElBQUksQ0FBQ0ksS0FBSyxDQUFDLENBQUMsRUFBRUYsQ0FBQyxDQUFDO0FBQ3pCO0FBRU8sU0FBU0csbUJBQW1CQSxDQUFDTCxJQUFJLEVBQUVDLElBQUksRUFBRTtFQUM5QyxJ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QUFFRCxDQUFDLEVBQUUsRUFBRTtJQUNwQyxPQUFPMkIsQ0FBQyxHQUFHLENBQUMsSUFBSU4sQ0FBQyxDQUFDckIsQ0FBQyxDQUFDLElBQUlzQixDQUFDLENBQUNLLENBQUMsQ0FBQyxFQUFFO01BQUVBLENBQUMsR0FBR0YsR0FBRyxDQUFDRSxDQUFDLENBQUM7SUFBRTtJQUM1QyxJQUFJTixDQUFDLENBQUNyQixDQUFDLENBQUMsSUFBSXNCLENBQUMsQ0FBQ0ssQ0FBQyxDQUFDLEVBQUU7TUFBRUEsQ0FBQyxFQUFFO0lBQUU7RUFDN0I7RUFDQSxPQUFPQSxDQUFDO0FBQ1Y7O0FBR0E7QUFDQTtBQUNBO0FBQ08sU0FBU0UscUJBQXFCQSxDQUFDeEIsTUFBTSxFQUFFO0VBQzVDLE9BQU9BLE1BQU0sQ0FBQ3lCLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDekIsTUFBTSxDQUFDMEIsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMxQixNQUFNLENBQUMyQixLQUFLLENBQUMsU0FBUyxDQUFDO0FBQ3hGOztBQUVBO0FBQ0E7QUFDQTtBQUNPLFNBQVNDLHNCQUFzQkEsQ0FBQzVCLE1BQU0sRUFBRTtFQUM3QyxPQUFPLENBQUNBLE1BQU0sQ0FBQ3lCLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSXpCLE1BQU0sQ0FBQ3lCLFFBQVEsQ0FBQyxJQUFJLENBQUM7QUFDMUQ7QUFFTyxTQUFTSSxVQUFVQSxDQUFDN0IsTUFBTSxFQUFFO0VBQ2pDO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQSxJQUFJTCxDQUFDO0VBQ0wsS0FBS0EsQ0FBQyxHQUFHSyxNQUFNLENBQUNKLE1BQU0sR0FBRyxDQUFDLEVBQUVELENBQUMsSUFBSSxDQUFDLEVBQUVBLENBQUMsRUFBRSxFQUFFO0lBQ3ZDLElBQUksQ0FBQ0ssTUFBTSxDQUFDTCxDQUFDLENBQUMsQ0FBQ2dDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRTtNQUMxQjtJQUNGO0VBQ0Y7RUFDQSxPQUFPM0IsTUFBTSxDQUFDOEIsU0FBUyxDQUFDbkMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNoQztBQUVPLFNBQVNvQyxTQUFTQSxDQUFDL0IsTUFBTSxFQUFFO0VBQ2hDO0VBQ0EsT0FBT0EsTUFBTSxDQUFDMkIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQyIsImlnbm9yZUxpc3QiOltdfQ==