matrix-react-sdk
Version:
SDK for matrix.org using React
229 lines (193 loc) • 26.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.replaceRangeAndExpandSelection = replaceRangeAndExpandSelection;
exports.replaceRangeAndMoveCaret = replaceRangeAndMoveCaret;
exports.rangeStartsAtBeginningOfLine = rangeStartsAtBeginningOfLine;
exports.rangeEndsAtEndOfLine = rangeEndsAtEndOfLine;
exports.formatRangeAsQuote = formatRangeAsQuote;
exports.formatRangeAsCode = formatRangeAsCode;
exports.toggleInlineFormat = toggleInlineFormat;
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* Some common queries and transformations on the editor model
*/
function replaceRangeAndExpandSelection(range
/*: Range*/
, newParts
/*: Part[]*/
) {
const {
model
} = range;
model.transform(() => {
const oldLen = range.length;
const addedLen = range.replace(newParts);
const firstOffset = range.start.asOffset(model);
const lastOffset = firstOffset.add(oldLen + addedLen);
return model.startRange(firstOffset.asPosition(model), lastOffset.asPosition(model));
});
}
function replaceRangeAndMoveCaret(range
/*: Range*/
, newParts
/*: Part[]*/
) {
const {
model
} = range;
model.transform(() => {
const oldLen = range.length;
const addedLen = range.replace(newParts);
const firstOffset = range.start.asOffset(model);
const lastOffset = firstOffset.add(oldLen + addedLen);
return lastOffset.asPosition(model);
});
}
function rangeStartsAtBeginningOfLine(range
/*: Range*/
) {
const {
model
} = range;
const startsWithPartial = range.start.offset !== 0;
const isFirstPart = range.start.index === 0;
const previousIsNewline = !isFirstPart && model.parts[range.start.index - 1].type === "newline";
return !startsWithPartial && (isFirstPart || previousIsNewline);
}
function rangeEndsAtEndOfLine(range
/*: Range*/
) {
const {
model
} = range;
const lastPart = model.parts[range.end.index];
const endsWithPartial = range.end.offset !== lastPart.text.length;
const isLastPart = range.end.index === model.parts.length - 1;
const nextIsNewline = !isLastPart && model.parts[range.end.index + 1].type === "newline";
return !endsWithPartial && (isLastPart || nextIsNewline);
}
function formatRangeAsQuote(range
/*: Range*/
) {
const {
model,
parts
} = range;
const {
partCreator
} = model;
for (let i = 0; i < parts.length; ++i) {
const part = parts[i];
if (part.type === "newline") {
parts.splice(i + 1, 0, partCreator.plain("> "));
}
}
parts.unshift(partCreator.plain("> "));
if (!rangeStartsAtBeginningOfLine(range)) {
parts.unshift(partCreator.newline());
}
if (!rangeEndsAtEndOfLine(range)) {
parts.push(partCreator.newline());
}
parts.push(partCreator.newline());
replaceRangeAndExpandSelection(range, parts);
}
function formatRangeAsCode(range
/*: Range*/
) {
const {
model,
parts
} = range;
const {
partCreator
} = model;
const needsBlock = parts.some(p => p.type === "newline");
if (needsBlock) {
parts.unshift(partCreator.plain("```"), partCreator.newline());
if (!rangeStartsAtBeginningOfLine(range)) {
parts.unshift(partCreator.newline());
}
parts.push(partCreator.newline(), partCreator.plain("```"));
if (!rangeEndsAtEndOfLine(range)) {
parts.push(partCreator.newline());
}
} else {
parts.unshift(partCreator.plain("`"));
parts.push(partCreator.plain("`"));
}
replaceRangeAndExpandSelection(range, parts);
} // parts helper methods
const isBlank = part => !part.text || !/\S/.test(part.text);
const isNL = part => part.type === "newline";
function toggleInlineFormat(range
/*: Range*/
, prefix
/*: string*/
, suffix = prefix) {
const {
model,
parts
} = range;
const {
partCreator
} = model; // compute paragraph [start, end] indexes
const paragraphIndexes = [];
let startIndex = 0; // start at i=2 because we look at i and up to two parts behind to detect paragraph breaks at their end
for (let i = 2; i < parts.length; i++) {
// paragraph breaks can be denoted in a multitude of ways,
// - 2 newline parts in sequence
// - newline part, plain(<empty or just spaces>), newline part
// bump startIndex onto the first non-blank after the paragraph ending
if (isBlank(parts[i - 2]) && isNL(parts[i - 1]) && !isNL(parts[i]) && !isBlank(parts[i])) {
startIndex = i;
} // if at a paragraph break, store the indexes of the paragraph
if (isNL(parts[i - 1]) && isNL(parts[i])) {
paragraphIndexes.push([startIndex, i - 1]);
startIndex = i + 1;
} else if (isNL(parts[i - 2]) && isBlank(parts[i - 1]) && isNL(parts[i])) {
paragraphIndexes.push([startIndex, i - 2]);
startIndex = i + 1;
}
}
const lastNonEmptyPart = parts.map(isBlank).lastIndexOf(false); // If we have not yet included the final paragraph then add it now
if (startIndex <= lastNonEmptyPart) {
paragraphIndexes.push([startIndex, lastNonEmptyPart + 1]);
} // keep track of how many things we have inserted as an offset:=0
let offset = 0;
paragraphIndexes.forEach(([startIdx, endIdx]) => {
// for each paragraph apply the same rule
const base = startIdx + offset;
const index = endIdx + offset;
const isFormatted = index - base > 0 && parts[base].text.startsWith(prefix) && parts[index - 1].text.endsWith(suffix);
if (isFormatted) {
// remove prefix and suffix
const partWithoutPrefix = parts[base].serialize();
partWithoutPrefix.text = partWithoutPrefix.text.substr(prefix.length);
parts[base] = partCreator.deserializePart(partWithoutPrefix);
const partWithoutSuffix = parts[index - 1].serialize();
const suffixPartText = partWithoutSuffix.text;
partWithoutSuffix.text = suffixPartText.substring(0, suffixPartText.length - suffix.length);
parts[index - 1] = partCreator.deserializePart(partWithoutSuffix);
} else {
parts.splice(index, 0, partCreator.plain(suffix)); // splice in the later one first to not change offset
parts.splice(base, 0, partCreator.plain(prefix));
offset += 2; // offset index to account for the two items we just spliced in
}
});
replaceRangeAndExpandSelection(range, parts);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lZGl0b3Ivb3BlcmF0aW9ucy50cyJdLCJuYW1lcyI6WyJyZXBsYWNlUmFuZ2VBbmRFeHBhbmRTZWxlY3Rpb24iLCJyYW5nZSIsIm5ld1BhcnRzIiwibW9kZWwiLCJ0cmFuc2Zvcm0iLCJvbGRMZW4iLCJsZW5ndGgiLCJhZGRlZExlbiIsInJlcGxhY2UiLCJmaXJzdE9mZnNldCIsInN0YXJ0IiwiYXNPZmZzZXQiLCJsYXN0T2Zmc2V0IiwiYWRkIiwic3RhcnRSYW5nZSIsImFzUG9zaXRpb24iLCJyZXBsYWNlUmFuZ2VBbmRNb3ZlQ2FyZXQiLCJyYW5nZVN0YXJ0c0F0QmVnaW5uaW5nT2ZMaW5lIiwic3RhcnRzV2l0aFBhcnRpYWwiLCJvZmZzZXQiLCJpc0ZpcnN0UGFydCIsImluZGV4IiwicHJldmlvdXNJc05ld2xpbmUiLCJwYXJ0cyIsInR5cGUiLCJyYW5nZUVuZHNBdEVuZE9mTGluZSIsImxhc3RQYXJ0IiwiZW5kIiwiZW5kc1dpdGhQYXJ0aWFsIiwidGV4dCIsImlzTGFzdFBhcnQiLCJuZXh0SXNOZXdsaW5lIiwiZm9ybWF0UmFuZ2VBc1F1b3RlIiwicGFydENyZWF0b3IiLCJpIiwicGFydCIsInNwbGljZSIsInBsYWluIiwidW5zaGlmdCIsIm5ld2xpbmUiLCJwdXNoIiwiZm9ybWF0UmFuZ2VBc0NvZGUiLCJuZWVkc0Jsb2NrIiwic29tZSIsInAiLCJpc0JsYW5rIiwidGVzdCIsImlzTkwiLCJ0b2dnbGVJbmxpbmVGb3JtYXQiLCJwcmVmaXgiLCJzdWZmaXgiLCJwYXJhZ3JhcGhJbmRleGVzIiwic3RhcnRJbmRleCIsImxhc3ROb25FbXB0eVBhcnQiLCJtYXAiLCJsYXN0SW5kZXhPZiIsImZvckVhY2giLCJzdGFydElkeCIsImVuZElkeCIsImJhc2UiLCJpc0Zvcm1hdHRlZCIsInN0YXJ0c1dpdGgiLCJlbmRzV2l0aCIsInBhcnRXaXRob3V0UHJlZml4Iiwic2VyaWFsaXplIiwic3Vic3RyIiwiZGVzZXJpYWxpemVQYXJ0IiwicGFy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QUFBLEtBQUssQ0FBQ0YsS0FBSyxHQUFHLENBQVQsQ0FBTCxHQUFtQlksV0FBVyxDQUFDaUMsZUFBWixDQUE0QkMsaUJBQTVCLENBQW5CO0FBQ0gsS0FWRCxNQVVPO0FBQ0g1QyxNQUFBQSxLQUFLLENBQUNhLE1BQU4sQ0FBYWYsS0FBYixFQUFvQixDQUFwQixFQUF1QlksV0FBVyxDQUFDSSxLQUFaLENBQWtCYSxNQUFsQixDQUF2QixFQURHLENBQ2dEOztBQUNuRDNCLE1BQUFBLEtBQUssQ0FBQ2EsTUFBTixDQUFhdUIsSUFBYixFQUFtQixDQUFuQixFQUFzQjFCLFdBQVcsQ0FBQ0ksS0FBWixDQUFrQlksTUFBbEIsQ0FBdEI7QUFDQTlCLE1BQUFBLE1BQU0sSUFBSSxDQUFWLENBSEcsQ0FHVTtBQUNoQjtBQUNKLEdBeEJEO0FBMEJBbkIsRUFBQUEsOEJBQThCLENBQUNDLEtBQUQsRUFBUXNCLEtBQVIsQ0FBOUI7QUFDSCIsInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAxOSBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBSYW5nZSBmcm9tIFwiLi9yYW5nZVwiO1xuaW1wb3J0IHtQYXJ0fSBmcm9tIFwiLi9wYXJ0c1wiO1xuXG4vKipcbiAqIFNvbWUgY29tbW9uIHF1ZXJpZXMgYW5kIHRyYW5zZm9ybWF0aW9ucyBvbiB0aGUgZWRpdG9yIG1vZGVsXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VSYW5nZUFuZEV4cGFuZFNlbGVjdGlvbihyYW5nZTogUmFuZ2UsIG5ld1BhcnRzOiBQYXJ0W10pIHtcbiAgICBjb25zdCB7bW9kZWx9ID0gcmFuZ2U7XG4gICAgbW9kZWwudHJhbnNmb3JtKCgpID0+IHtcbiAgICAgICAgY29uc3Qgb2xkTGVuID0gcmFuZ2UubGVuZ3RoO1xuICAgICAgICBjb25zdCBhZGRlZExlbiA9IHJhbmdlLnJlcGxhY2UobmV3UGFydHMpO1xuICAgICAgICBjb25zdCBmaXJzdE9mZnNldCA9IHJhbmdlLnN0YXJ0LmFzT2Zmc2V0KG1vZGVsKTtcbiAgICAgICAgY29uc3QgbGFzdE9mZnNldCA9IGZpcnN0T2Zmc2V0LmFkZChvbGRMZW4gKyBhZGRlZExlbik7XG4gICAgICAgIHJldHVybiBtb2RlbC5zdGFydFJhbmdlKGZpcnN0T2Zmc2V0LmFzUG9zaXRpb24obW9kZWwpLCBsYXN0T2Zmc2V0LmFzUG9zaXRpb24obW9kZWwpKTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VSYW5nZUFuZE1vdmVDYXJldChyYW5nZTogUmFuZ2UsIG5ld1BhcnRzOiBQYXJ0W10pIHtcbiAgICBjb25zdCB7bW9kZWx9ID0gcmFuZ2U7XG4gICAgbW9kZWwudHJhbnNmb3JtKCgpID0+IHtcbiAgICAgICAgY29uc3Qgb2xkTGVuID0gcmFuZ2UubGVuZ3RoO1xuICAgICAgICBjb25zdCBhZGRlZExlbiA9IHJhbmdlLnJlcGxhY2UobmV3UGFydHMpO1xuICAgICAgICBjb25zdCBmaXJzdE9mZnNldCA9IHJhbmdlLnN0YXJ0LmFzT2Zmc2V0KG1vZGVsKTtcbiAgICAgICAgY29uc3QgbGFzdE9mZnNldCA9IGZpcnN0T2Zmc2V0LmFkZChvbGRMZW4gKyBhZGRlZExlbik7XG4gICAgICAgIHJldHVybiBsYXN0T2Zmc2V0LmFzUG9zaXRpb24obW9kZWwpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2VTdGFydHNBdEJlZ2lubmluZ09mTGluZShyYW5nZTogUmFuZ2UpIHtcbiAgICBjb25zdCB7bW9kZWx9ID0gcmFuZ2U7XG4gICAgY29uc3Qgc3RhcnRzV2l0aFBhcnRpYWwgPSByYW5nZS5zdGFydC5vZmZzZXQgIT09IDA7XG4gICAgY29uc3QgaXNGaXJzdFBhcnQgPSByYW5nZS5zdGFydC5pbmRleCA9PT0gMDtcbiAgICBjb25zdCBwcmV2aW91c0lzTmV3bGluZSA9ICFpc0ZpcnN0UGFydCAmJiBtb2RlbC5wYXJ0c1tyYW5nZS5zdGFydC5pbmRleCAtIDFdLnR5cGUgPT09IFwibmV3bGluZVwiO1xuICAgIHJldHVybiAhc3RhcnRzV2l0aFBhcnRpYWwgJiYgKGlzRmlyc3RQYXJ0IHx8IHByZXZpb3VzSXNOZXdsaW5lKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmdlRW5kc0F0RW5kT2ZMaW5lKHJhbmdlOiBSYW5nZSkge1xuICAgIGNvbnN0IHttb2RlbH0gPSByYW5nZTtcbiAgICBjb25zdCBsYXN0UGFydCA9IG1vZGVsLnBhcnRzW3JhbmdlLmVuZC5pbmRleF07XG4gICAgY29uc3QgZW5kc1dpdGhQYXJ0aWFsID0gcmFuZ2UuZW5kLm9mZnNldCAhPT0gbGFzdFBhcnQudGV4dC5sZW5ndGg7XG4gICAgY29uc3QgaXNMYXN0UGFydCA9IHJhbmdlLmVuZC5pbmRleCA9PT0gbW9kZWwucGFydHMubGVuZ3RoIC0gMTtcbiAgICBjb25zdCBuZXh0SXNOZXdsaW5lID0gIWlzTGFzdFBhcnQgJiYgbW9kZWwucGFydHNbcmFuZ2UuZW5kLmluZGV4ICsgMV0udHlwZSA9PT0gXCJuZXdsaW5lXCI7XG4gICAgcmV0dXJuICFlbmRzV2l0aFBhcnRpYWwgJiYgKGlzTGFzdFBhcnQgfHwgbmV4dElzTmV3bGluZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRSYW5nZUFzUXVvdGUocmFuZ2U6IFJhbmdlKSB7XG4gICAgY29uc3Qge21vZGVsLCBwYXJ0c30gPSByYW5nZTtcbiAgICBjb25zdCB7cGFydENyZWF0b3J9ID0gbW9kZWw7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7ICsraSkge1xuICAgICAgICBjb25zdCBwYXJ0ID0gcGFydHNbaV07XG4gICAgICAgIGlmIChwYXJ0LnR5cGUgPT09IFwibmV3bGluZVwiKSB7XG4gICAgICAgICAgICBwYXJ0cy5zcGxpY2UoaSArIDEsIDAsIHBhcnRDcmVhdG9yLnBsYWluKFwiPiBcIikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHBhcnRzLnVuc2hpZnQocGFydENyZWF0b3IucGxhaW4oXCI+IFwiKSk7XG4gICAgaWYgKCFyYW5nZVN0YXJ0c0F0QmVnaW5uaW5nT2ZMaW5lKHJhbmdlKSkge1xuICAgICAgICBwYXJ0cy51bnNoaWZ0KHBhcnRDcmVhdG9yLm5ld2xpbmUoKSk7XG4gICAgfVxuICAgIGlmICghcmFuZ2VFbmRzQXRFbmRPZkxpbmUocmFuZ2UpKSB7XG4gICAgICAgIHBhcnRzLnB1c2gocGFydENyZWF0b3IubmV3bGluZSgpKTtcbiAgICB9XG5cbiAgICBwYXJ0cy5wdXNoKHBhcnRDcmVhdG9yLm5ld2xpbmUoKSk7XG4gICAgcmVwbGFjZVJhbmdlQW5kRXhwYW5kU2VsZWN0aW9uKHJhbmdlLCBwYXJ0cyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRSYW5nZUFzQ29kZShyYW5nZTogUmFuZ2UpIHtcbiAgICBjb25zdCB7bW9kZWwsIHBhcnRzfSA9IHJhbmdlO1xuICAgIGNvbnN0IHtwYXJ0Q3JlYXRvcn0gPSBtb2RlbDtcbiAgICBjb25zdCBuZWVkc0Jsb2NrID0gcGFydHMuc29tZShwID0+IHAudHlwZSA9PT0gXCJuZXdsaW5lXCIpO1xuICAgIGlmIChuZWVkc0Jsb2NrKSB7XG4gICAgICAgIHBhcnRzLnVuc2hpZnQocGFydENyZWF0b3IucGxhaW4oXCJgYGBcIiksIHBhcnRDcmVhdG9yLm5ld2xpbmUoKSk7XG4gICAgICAgIGlmICghcmFuZ2VTdGFydHNBdEJlZ2lubmluZ09mTGluZShyYW5nZSkpIHtcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQocGFydENyZWF0b3IubmV3bGluZSgpKTtcbiAgICAgICAgfVxuICAgICAgICBwYXJ0cy5wdXNoKFxuICAgICAgICAgICAgcGFydENyZWF0b3IubmV3bGluZSgpLFxuICAgICAgICAgICAgcGFydENyZWF0b3IucGxhaW4oXCJgYGBcIikpO1xuICAgICAgICBpZiAoIXJhbmdlRW5kc0F0RW5kT2ZMaW5lKHJhbmdlKSkge1xuICAgICAgICAgICAgcGFydHMucHVzaChwYXJ0Q3JlYXRvci5uZXdsaW5lKCkpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcGFydHMudW5zaGlmdChwYXJ0Q3JlYXRvci5wbGFpbihcImBcIikpO1xuICAgICAgICBwYXJ0cy5wdXNoKHBhcnRDcmVhdG9yLnBsYWluKFwiYFwiKSk7XG4gICAgfVxuICAgIHJlcGxhY2VSYW5nZUFuZEV4cGFuZFNlbGVjdGlvbihyYW5nZSwgcGFydHMpO1xufVxuXG4vLyBwYXJ0cyBoZWxwZXIgbWV0aG9kc1xuY29uc3QgaXNCbGFuayA9IHBhcnQgPT4gIXBhcnQudGV4dCB8fCAhL1xcUy8udGVzdChwYXJ0LnRleHQpO1xuY29uc3QgaXNOTCA9IHBhcnQgPT4gcGFydC50eXBlID09PSBcIm5ld2xpbmVcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHRvZ2dsZUlubGluZUZvcm1hdChyYW5nZTogUmFuZ2UsIHByZWZpeDogc3RyaW5nLCBzdWZmaXggPSBwcmVmaXgpIHtcbiAgICBjb25zdCB7bW9kZWwsIHBhcnRzfSA9IHJhbmdlO1xuICAgIGNvbnN0IHtwYXJ0Q3JlYXRvcn0gPSBtb2RlbDtcblxuICAgIC8vIGNvbXB1dGUgcGFyYWdyYXBoIFtzdGFydCwgZW5kXSBpbmRleGVzXG4gICAgY29uc3QgcGFyYWdyYXBoSW5kZXhlcyA9IFtdO1xuICAgIGxldCBzdGFydEluZGV4ID0gMDtcbiAgICAvLyBzdGFydCBhdCBpPTIgYmVjYXVzZSB3ZSBsb29rIGF0IGkgYW5kIHVwIHRvIHR3byBwYXJ0cyBiZWhpbmQgdG8gZGV0ZWN0IHBhcmFncmFwaCBicmVha3MgYXQgdGhlaXIgZW5kXG4gICAgZm9yIChsZXQgaSA9IDI7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAvLyBwYXJhZ3JhcGggYnJlYWtzIGNhbiBiZSBkZW5vdGVkIGluIGEgbXVsdGl0dWRlIG9mIHdheXMsXG4gICAgICAgIC8vIC0gMiBuZXdsaW5lIHBhcnRzIGluIHNlcXVlbmNlXG4gICAgICAgIC8vIC0gbmV3bGluZSBwYXJ0LCBwbGFpbig8ZW1wdHkgb3IganVzdCBzcGFjZXM+KSwgbmV3bGluZSBwYXJ0XG5cbiAgICAgICAgLy8gYnVtcCBzdGFydEluZGV4IG9udG8gdGhlIGZpcnN0IG5vbi1ibGFuayBhZnRlciB0aGUgcGFyYWdyYXBoIGVuZGluZ1xuICAgICAgICBpZiAoaXNCbGFuayhwYXJ0c1tpIC0gMl0pICYmIGlzTkwocGFydHNbaSAtIDFdKSAmJiAhaXNOTChwYXJ0c1tpXSkgJiYgIWlzQmxhbmsocGFydHNbaV0pKSB7XG4gICAgICAgICAgICBzdGFydEluZGV4ID0gaTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIGF0IGEgcGFyYWdyYXBoIGJyZWFrLCBzdG9yZSB0aGUgaW5kZXhlcyBvZiB0aGUgcGFyYWdyYXBoXG4gICAgICAgIGlmIChpc05MKHBhcnRzW2kgLSAxXSkgJiYgaXNOTChwYXJ0c1tpXSkpIHtcbiAgICAgICAgICAgIHBhcmFncmFwaEluZGV4ZXMucHVzaChbc3RhcnRJbmRleCwgaSAtIDFdKTtcbiAgICAgICAgICAgIHN0YXJ0SW5kZXggPSBpICsgMTtcbiAgICAgICAgfSBlbHNlIGlmIChpc05MKHBhcnRzW2kgLSAyXSkgJiYgaXNCbGFuayhwYXJ0c1tpIC0gMV0pICYmIGlzTkwocGFydHNbaV0pKSB7XG4gICAgICAgICAgICBwYXJhZ3JhcGhJbmRleGVzLnB1c2goW3N0YXJ0SW5kZXgsIGkgLSAyXSk7XG4gICAgICAgICAgICBzdGFydEluZGV4ID0gaSArIDE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBsYXN0Tm9uRW1wdHlQYXJ0ID0gcGFydHMubWFwKGlzQmxhbmspLmxhc3RJbmRleE9mKGZhbHNlKTtcbiAgICAvLyBJZiB3ZSBoYXZlIG5vdCB5ZXQgaW5jbHVkZWQgdGhlIGZpbmFsIHBhcmFncmFwaCB0aGVuIGFkZCBpdCBub3dcbiAgICBpZiAoc3RhcnRJbmRleCA8PSBsYXN0Tm9uRW1wdHlQYXJ0KSB7XG4gICAgICAgIHBhcmFncmFwaEluZGV4ZXMucHVzaChbc3RhcnRJbmRleCwgbGFzdE5vbkVtcHR5UGFydCArIDFdKTtcbiAgICB9XG5cbiAgICAvLyBrZWVwIHRyYWNrIG9mIGhvdyBtYW55IHRoaW5ncyB3ZSBoYXZlIGluc2VydGVkIGFzIGFuIG9mZnNldDo9MFxuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIHBhcmFncmFwaEluZGV4ZXMuZm9yRWFjaCgoW3N0YXJ0SWR4LCBlbmRJZHhdKSA9PiB7XG4gICAgICAgIC8vIGZvciBlYWNoIHBhcmFncmFwaCBhcHBseSB0aGUgc2FtZSBydWxlXG4gICAgICAgIGNvbnN0IGJhc2UgPSBzdGFydElkeCArIG9mZnNldDtcbiAgICAgICAgY29uc3QgaW5kZXggPSBlbmRJZHggKyBvZmZzZXQ7XG5cbiAgICAgICAgY29uc3QgaXNGb3JtYXR0ZWQgPSAoaW5kZXggLSBiYXNlID4gMCkgJiZcbiAgICAgICAgICAgIHBhcnRzW2Jhc2VdLnRleHQuc3RhcnRzV2l0aChwcmVmaXgpICYmXG4gICAgICAgICAgICBwYXJ0c1tpbmRleCAtIDFdLnRleHQuZW5kc1dpdGgoc3VmZml4KTtcblxuICAgICAgICBpZiAoaXNGb3JtYXR0ZWQpIHtcbiAgICAgICAgICAgIC8vIHJlbW92ZSBwcmVmaXggYW5kIHN1ZmZpeFxuICAgICAgICAgICAgY29uc3QgcGFydFdpdGhvdXRQcmVmaXggPSBwYXJ0c1tiYXNlXS5zZXJpYWxpemUoKTtcbiAgICAgICAgICAgIHBhcnRXaXRob3V0UHJlZml4LnRleHQgPSBwYXJ0V2l0aG91dFByZWZpeC50ZXh0LnN1YnN0cihwcmVmaXgubGVuZ3RoKTtcbiAgICAgICAgICAgIHBhcnRzW2Jhc2VdID0gcGFydENyZWF0b3IuZGVzZXJpYWxpemVQYXJ0KHBhcnRXaXRob3V0UHJlZml4KTtcblxuICAgICAgICAgICAgY29uc3QgcGFydFdpdGhvdXRTdWZmaXggPSBwYXJ0c1tpbmRleCAtIDFdLnNlcmlhbGl6ZSgpO1xuICAgICAgICAgICAgY29uc3Qgc3VmZml4UGFydFRleHQgPSBwYXJ0V2l0aG91dFN1ZmZpeC50ZXh0O1xuICAgICAgICAgICAgcGFydFdpdGhvdXRTdWZmaXgudGV4dCA9IHN1ZmZpeFBhcnRUZXh0LnN1YnN0cmluZygwLCBzdWZmaXhQYXJ0VGV4dC5sZW5ndGggLSBzdWZmaXgubGVuZ3RoKTtcbiAgICAgICAgICAgIHBhcnRzW2luZGV4IC0gMV0gPSBwYXJ0Q3JlYXRvci5kZXNlcmlhbGl6ZVBhcnQocGFydFdpdGhvdXRTdWZmaXgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFydHMuc3BsaWNlKGluZGV4LCAwLCBwYXJ0Q3JlYXRvci5wbGFpbihzdWZmaXgpKTsgLy8gc3BsaWNlIGluIHRoZSBsYXRlciBvbmUgZmlyc3QgdG8gbm90IGNoYW5nZSBvZmZzZXRcbiAgICAgICAgICAgIHBhcnRzLnNwbGljZShiYXNlLCAwLCBwYXJ0Q3JlYXRvci5wbGFpbihwcmVmaXgpKTtcbiAgICAgICAgICAgIG9mZnNldCArPSAyOyAvLyBvZmZzZXQgaW5kZXggdG8gYWNjb3VudCBmb3IgdGhlIHR3byBpdGVtcyB3ZSBqdXN0IHNwbGljZWQgaW5cbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmVwbGFjZVJhbmdlQW5kRXhwYW5kU2VsZWN0aW9uKHJhbmdlLCBwYXJ0cyk7XG59XG4iXX0=