matrix-react-sdk
Version:
SDK for matrix.org using React
169 lines (158 loc) • 25.7 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.EMOTE_PREFIX = void 0;
exports.createMessageContent = createMessageContent;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _matrixWysiwyg = require("@vector-im/matrix-wysiwyg");
var _matrix = require("matrix-js-sdk/src/matrix");
var _SettingsStore = _interopRequireDefault(require("../../../../../settings/SettingsStore"));
var _Permalinks = require("../../../../../utils/permalinks/Permalinks");
var _Reply = require("../../../../../utils/Reply");
var _Typeguards = require("../../../../../Typeguards");
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /*
Copyright 2024 New Vector Ltd.
Copyright 2022 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
const EMOTE_PREFIX = exports.EMOTE_PREFIX = "/me ";
// Merges favouring the given relation
function attachRelation(content, relation) {
if (relation) {
content["m.relates_to"] = _objectSpread(_objectSpread({}, content["m.relates_to"] || {}), relation);
}
}
function getHtmlReplyFallback(mxEvent) {
const html = mxEvent.getContent().formatted_body;
if (!html) {
return "";
}
const rootNode = new DOMParser().parseFromString(html, "text/html").body;
const mxReply = rootNode.querySelector("mx-reply");
return mxReply && mxReply.outerHTML || "";
}
function getTextReplyFallback(mxEvent) {
const body = mxEvent.getContent().body;
if (typeof body !== "string") {
return "";
}
const lines = body.split("\n").map(l => l.trim());
if (lines.length > 2 && lines[0].startsWith("> ") && lines[1].length === 0) {
return `${lines[0]}\n\n`;
}
return "";
}
const isMatrixEvent = e => e instanceof _matrix.MatrixEvent;
async function createMessageContent(message, isHTML, {
relation,
replyToEvent,
permalinkCreator,
includeReplyLegacyFallback = true,
editedEvent
}) {
const isEditing = isMatrixEvent(editedEvent);
const isReply = isEditing ? Boolean(editedEvent.replyEventId) : isMatrixEvent(replyToEvent);
const isReplyAndEditing = isEditing && isReply;
const isEmote = message.startsWith(EMOTE_PREFIX);
if (isEmote) {
// if we are dealing with an emote we want to remove the prefix so that `/me` does not
// appear after the `* <userName>` text in the timeline
message = message.slice(EMOTE_PREFIX.length);
}
if (message.startsWith("//")) {
// if user wants to enter a single slash at the start of a message, this
// is how they have to do it (due to it clashing with commands), so here we
// remove the first character to make sure //word displays as /word
message = message.slice(1);
}
// if we're editing rich text, the message content is pure html
// BUT if we're not, the message content will be plain text where we need to convert the mentions
const body = isHTML ? await (0, _matrixWysiwyg.richToPlain)(message, false) : convertPlainTextToBody(message);
const bodyPrefix = isReplyAndEditing && getTextReplyFallback(editedEvent) || "";
const formattedBodyPrefix = isReplyAndEditing && getHtmlReplyFallback(editedEvent) || "";
const content = {
msgtype: isEmote ? _matrix.MsgType.Emote : _matrix.MsgType.Text,
body: isEditing ? `${bodyPrefix} * ${body}` : body
};
// TODO markdown support
const isMarkdownEnabled = _SettingsStore.default.getValue("MessageComposerInput.useMarkdown");
const formattedBody = isHTML ? message : isMarkdownEnabled ? await (0, _matrixWysiwyg.plainToRich)(message, true) : null;
if (formattedBody) {
content.format = "org.matrix.custom.html";
content.formatted_body = isEditing ? `${formattedBodyPrefix} * ${formattedBody}` : formattedBody;
}
if (isEditing) {
content["m.new_content"] = {
msgtype: content.msgtype,
body: body
};
if (formattedBody) {
content["m.new_content"].format = "org.matrix.custom.html";
content["m.new_content"]["formatted_body"] = formattedBody;
}
}
const newRelation = isEditing ? _objectSpread(_objectSpread({}, relation), {}, {
rel_type: "m.replace",
event_id: editedEvent.getId()
}) : relation;
// TODO Do we need to attach mentions here?
// TODO Handle editing?
attachRelation(content, newRelation);
if (!isEditing && replyToEvent && permalinkCreator) {
(0, _Reply.addReplyToMessageContent)(content, replyToEvent, {
permalinkCreator,
includeLegacyFallback: includeReplyLegacyFallback
});
}
return content;
}
/**
* Without a model, we need to manually amend mentions in uncontrolled message content
* to make sure that mentions meet the matrix specification.
*
* @param content - the output from the `MessageComposer` state when in plain text mode
* @returns - a string formatted with the mentions replaced as required
*/
function convertPlainTextToBody(content) {
const document = new DOMParser().parseFromString(content, "text/html");
const mentions = Array.from(document.querySelectorAll("a[data-mention-type]"));
mentions.forEach(mention => {
const mentionType = mention.getAttribute("data-mention-type");
switch (mentionType) {
case "at-room":
{
mention.replaceWith("@room");
break;
}
case "user":
{
const innerText = mention.innerHTML;
mention.replaceWith(innerText);
break;
}
case "room":
{
// for this case we use parsePermalink to try and get the mx id
const href = mention.getAttribute("href");
// if the mention has no href attribute, leave it alone
if (href === null) break;
// otherwise, attempt to parse the room alias or id from the href
const permalinkParts = (0, _Permalinks.parsePermalink)(href);
// then if we have permalink parts with a valid roomIdOrAlias, replace the
// room mention with that text
if ((0, _Typeguards.isNotNull)(permalinkParts) && (0, _Typeguards.isNotNull)(permalinkParts.roomIdOrAlias)) {
mention.replaceWith(permalinkParts.roomIdOrAlias);
}
break;
}
default:
break;
}
});
return document.body.innerHTML;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbWF0cml4V3lzaXd5ZyIsInJlcXVpcmUiLCJfbWF0cml4IiwiX1NldHRpbmdzU3RvcmUiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX1Blcm1hbGlua3MiLCJfUmVwbHkiLCJfVHlwZWd1YXJkcyIsIm93bktleXMiLCJlIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsIkVNT1RFX1BSRUZJWCIsImV4cG9ydHMiLCJhdHRhY2hSZWxhdGlvbiIsImNvbnRlbnQiLCJyZWxhdGlvbiIsImdldEh0bWxSZXBseUZhbGxiYWNrIiwibXhFdmVudCIsImh0bWwiLCJnZXRDb250ZW50IiwiZm9ybWF0dGVkX2JvZHkiLCJyb290Tm9kZSIsIkRPTVBhcnNlciIsInBhcnNlRnJvbVN0cmluZyIsImJvZHkiLCJteFJlcGx5IiwicXVlcnlTZWxlY3RvciIsIm91dGVySFRNTCIsImdldFRleHRSZXBseUZhbGxiYWNrIiwibGluZXMiLCJzcGxpdCIsIm1hcCIsImwiLCJ0cmltIiwic3RhcnRzV2l0aCIsImlzTWF0cml4RXZlbnQiLCJNYXRyaXhFdmVudCIsImNyZWF0ZU1lc3NhZ2VDb250ZW50IiwibWVzc2FnZSIsImlzSFRNTCIsInJlcGx5VG9FdmVudCIsInBlcm1hbGlua0NyZWF0b3IiLCJpbmNsdWRlUmVwbHlMZWdhY3lGYWxsYmFjayIsImVkaXRlZEV2ZW50IiwiaXNFZGl0aW5nIiwiaXNSZXBseSIsIkJvb2xlYW4iLCJyZXBseUV2ZW50SWQiLCJpc1JlcGx5QW5kRWRpdGluZyIsImlzRW1vdGUiLCJzbGljZSIsInJpY2hUb1BsYWluIiwiY29udmVydFBsYWluVGV4dFRvQm9keSIsImJvZHlQcmVmaXgiLCJmb3JtYXR0ZWRCb2R5UHJlZml4IiwibXNndHlwZSIsIk1zZ1R5cGUiLCJFbW90ZSIsIlRleHQiLCJpc01hcmtkb3duRW5hYmxlZCIsIlNldHRpbmdzU3RvcmUiLCJnZXRWYWx1ZSIsImZvcm1hdHRlZEJvZHkiLCJwbGFpblRvUmljaCIsImZvcm1hdCIsIm5ld1JlbGF0aW9uIiwicmVsX3R5cGUiLCJldmVudF9pZCIsImdldElkIiwiYWRkUmVwbHlUb01lc3NhZ2VDb250ZW50IiwiaW5jbHVkZUxlZ2FjeUZhbGxiYWNrIiwiZG9jdW1lbnQiLCJtZW50aW9ucyIsIkFycmF5IiwiZnJvbSIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJtZW50aW9uIiwibWVudGlvblR5cGUiLCJnZXRBdHRyaWJ1dGUiLCJyZXBsYWNlV2l0aCIsImlubmVyVGV4dCIsImlubmVySFRNTCIsImhyZWYiLCJwZXJtYWxpbmtQYXJ0cyIsInBhcnNlUGVybWFsaW5rIiwiaXNOb3ROdWxsIiwicm9vbUlkT3JBbGlhcyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3Jvb21zL3d5c2l3eWdfY29tcG9zZXIvdXRpbHMvY3JlYXRlTWVzc2FnZUNvbnRlbnQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjIgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IHsgcmljaFRvUGxhaW4sIHBsYWluVG9SaWNoIH0gZnJvbSBcIkB2ZWN0b3ItaW0vbWF0cml4LXd5c2l3eWdcIjtcbmltcG9ydCB7IElDb250ZW50LCBJRXZlbnRSZWxhdGlvbiwgTWF0cml4RXZlbnQsIE1zZ1R5cGUgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgeyBSZXBsYWNlbWVudEV2ZW50LCBSb29tTWVzc2FnZUV2ZW50Q29udGVudCwgUm9vbU1lc3NhZ2VUZXh0RXZlbnRDb250ZW50IH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL3R5cGVzXCI7XG5cbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gXCIuLi8uLi8uLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgeyBwYXJzZVBlcm1hbGluaywgUm9vbVBlcm1hbGlua0NyZWF0b3IgfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vdXRpbHMvcGVybWFsaW5rcy9QZXJtYWxpbmtzXCI7XG5pbXBvcnQgeyBhZGRSZXBseVRvTWVzc2FnZUNvbnRlbnQgfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vdXRpbHMvUmVwbHlcIjtcbmltcG9ydCB7IGlzTm90TnVsbCB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9UeXBlZ3VhcmRzXCI7XG5cbmV4cG9ydCBjb25zdCBFTU9URV9QUkVGSVggPSBcIi9tZSBcIjtcblxuLy8gTWVyZ2VzIGZhdm91cmluZyB0aGUgZ2l2ZW4gcmVsYXRpb25cbmZ1bmN0aW9uIGF0dGFjaFJlbGF0aW9uKGNvbnRlbnQ6IElDb250ZW50LCByZWxhdGlvbj86IElFdmVudFJlbGF0aW9uKTogdm9pZCB7XG4gICAgaWYgKHJlbGF0aW9uKSB7XG4gICAgICAgIGNvbnRlbnRbXCJtLnJlbGF0ZXNfdG9cIl0gPSB7XG4gICAgICAgICAgICAuLi4oY29udGVudFtcIm0ucmVsYXRlc190b1wiXSB8fCB7fSksXG4gICAgICAgICAgICAuLi5yZWxhdGlvbixcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldEh0bWxSZXBseUZhbGxiYWNrKG14RXZlbnQ6IE1hdHJpeEV2ZW50KTogc3RyaW5nIHtcbiAgICBjb25zdCBodG1sID0gbXhFdmVudC5nZXRDb250ZW50KCkuZm9ybWF0dGVkX2JvZHk7XG4gICAgaWYgKCFodG1sKSB7XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cbiAgICBjb25zdCByb290Tm9kZSA9IG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcoaHRtbCwgXCJ0ZXh0L2h0bWxcIikuYm9keTtcbiAgICBjb25zdCBteFJlcGx5ID0gcm9vdE5vZGUucXVlcnlTZWxlY3RvcihcIm14LXJlcGx5XCIpO1xuICAgIHJldHVybiAobXhSZXBseSAmJiBteFJlcGx5Lm91dGVySFRNTCkgfHwgXCJcIjtcbn1cblxuZnVuY3Rpb24gZ2V0VGV4dFJlcGx5RmFsbGJhY2sobXhFdmVudDogTWF0cml4RXZlbnQpOiBzdHJpbmcge1xuICAgIGNvbnN0IGJvZHkgPSBteEV2ZW50LmdldENvbnRlbnQoKS5ib2R5O1xuICAgIGlmICh0eXBlb2YgYm9keSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG4gICAgY29uc3QgbGluZXMgPSBib2R5LnNwbGl0KFwiXFxuXCIpLm1hcCgobCkgPT4gbC50cmltKCkpO1xuICAgIGlmIChsaW5lcy5sZW5ndGggPiAyICYmIGxpbmVzWzBdLnN0YXJ0c1dpdGgoXCI+IFwiKSAmJiBsaW5lc1sxXS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGAke2xpbmVzWzBdfVxcblxcbmA7XG4gICAgfVxuICAgIHJldHVybiBcIlwiO1xufVxuXG5pbnRlcmZhY2UgQ3JlYXRlTWVzc2FnZUNvbnRlbnRQYXJhbXMge1xuICAgIHJlbGF0aW9uPzogSUV2ZW50UmVsYXRpb247XG4gICAgcmVwbHlUb0V2ZW50PzogTWF0cml4RXZlbnQ7XG4gICAgcGVybWFsaW5rQ3JlYXRvcj86IFJvb21QZXJtYWxpbmtDcmVhdG9yO1xuICAgIGluY2x1ZGVSZXBseUxlZ2FjeUZhbGxiYWNrPzogYm9vbGVhbjtcbiAgICBlZGl0ZWRFdmVudD86IE1hdHJpeEV2ZW50O1xufVxuXG5jb25zdCBpc01hdHJpeEV2ZW50ID0gKGU6IE1hdHJpeEV2ZW50IHwgdW5kZWZpbmVkKTogZSBpcyBNYXRyaXhFdmVudCA9PiBlIGluc3RhbmNlb2YgTWF0cml4RXZlbnQ7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVNZXNzYWdlQ29udGVudChcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgaXNIVE1MOiBib29sZWFuLFxuICAgIHtcbiAgICAgICAgcmVsYXRpb24sXG4gICAgICAgIHJlcGx5VG9FdmVudCxcbiAgICAgICAgcGVybWFsaW5rQ3JlYXRvcixcbiAgICAgICAgaW5jbHVkZVJlcGx5TGVnYWN5RmFsbGJhY2sgPSB0cnVlLFxuICAgICAgICBlZGl0ZWRFdmVudCxcbiAgICB9OiBDcmVhdGVNZXNzYWdlQ29udGVudFBhcmFtcyxcbik6IFByb21pc2U8Um9vbU1lc3NhZ2VFdmVudENvbnRlbnQ+IHtcbiAgICBjb25zdCBpc0VkaXRpbmcgPSBpc01hdHJpeEV2ZW50KGVkaXRlZEV2ZW50KTtcbiAgICBjb25zdCBpc1JlcGx5ID0gaXNFZGl0aW5nID8gQm9vbGVhbihlZGl0ZWRFdmVudC5yZXBseUV2ZW50SWQpIDogaXNNYXRyaXhFdmVudChyZXBseVRvRXZlbnQpO1xuICAgIGNvbnN0IGlzUmVwbHlBbmRFZGl0aW5nID0gaXNFZGl0aW5nICYmIGlzUmVwbHk7XG5cbiAgICBjb25zdCBpc0Vtb3RlID0gbWVzc2FnZS5zdGFydHNXaXRoKEVNT1RFX1BSRUZJWCk7XG4gICAgaWYgKGlzRW1vdGUpIHtcbiAgICAgICAgLy8gaWYgd2UgYXJlIGRlYWxpbmcgd2l0aCBhbiBlbW90ZSB3ZSB3YW50IHRvIHJlbW92ZSB0aGUgcHJlZml4IHNvIHRoYXQgYC9tZWAgZG9lcyBub3RcbiAgICAgICAgLy8gYXBwZWFyIGFmdGVyIHRoZSBgKiA8dXNlck5hbWU+YCB0ZXh0IGluIHRoZSB0aW1lbGluZVxuICAgICAgICBtZXNzYWdlID0gbWVzc2FnZS5zbGljZShFTU9URV9QUkVGSVgubGVuZ3RoKTtcbiAgICB9XG4gICAgaWYgKG1lc3NhZ2Uuc3RhcnRzV2l0aChcIi8vXCIpKSB7XG4gICAgICAgIC8vIGlmIHVzZXIgd2FudHMgdG8gZW50ZXIgYSBzaW5nbGUgc2xhc2ggYXQgdGhlIHN0YXJ0IG9mIGEgbWVzc2FnZSwgdGhpc1xuICAgICAgICAvLyBpcyBob3cgdGhleSBoYXZlIHRvIGRvIGl0IChkdWUgdG8gaXQgY2xhc2hpbmcgd2l0aCBjb21tYW5kcyksIHNvIGhlcmUgd2VcbiAgICAgICAgLy8gcmVtb3ZlIHRoZSBmaXJzdCBjaGFyYWN0ZXIgdG8gbWFrZSBzdXJlIC8vd29yZCBkaXNwbGF5cyBhcyAvd29yZFxuICAgICAgICBtZXNzYWdlID0gbWVzc2FnZS5zbGljZSgxKTtcbiAgICB9XG5cbiAgICAvLyBpZiB3ZSdyZSBlZGl0aW5nIHJpY2ggdGV4dCwgdGhlIG1lc3NhZ2UgY29udGVudCBpcyBwdXJlIGh0bWxcbiAgICAvLyBCVVQgaWYgd2UncmUgbm90LCB0aGUgbWVzc2FnZSBjb250ZW50IHdpbGwgYmUgcGxhaW4gdGV4dCB3aGVyZSB3ZSBuZWVkIHRvIGNvbnZlcnQgdGhlIG1lbnRpb25zXG4gICAgY29uc3QgYm9keSA9IGlzSFRNTCA/IGF3YWl0IHJpY2hUb1BsYWluKG1lc3NhZ2UsIGZhbHNlKSA6IGNvbnZlcnRQbGFpblRleHRUb0JvZHkobWVzc2FnZSk7XG4gICAgY29uc3QgYm9keVByZWZpeCA9IChpc1JlcGx5QW5kRWRpdGluZyAmJiBnZXRUZXh0UmVwbHlGYWxsYmFjayhlZGl0ZWRFdmVudCkpIHx8IFwiXCI7XG4gICAgY29uc3QgZm9ybWF0dGVkQm9keVByZWZpeCA9IChpc1JlcGx5QW5kRWRpdGluZyAmJiBnZXRIdG1sUmVwbHlGYWxsYmFjayhlZGl0ZWRFdmVudCkpIHx8IFwiXCI7XG5cbiAgICBjb25zdCBjb250ZW50ID0ge1xuICAgICAgICBtc2d0eXBlOiBpc0Vtb3RlID8gTXNnVHlwZS5FbW90ZSA6IE1zZ1R5cGUuVGV4dCxcbiAgICAgICAgYm9keTogaXNFZGl0aW5nID8gYCR7Ym9keVByZWZpeH0gKiAke2JvZHl9YCA6IGJvZHksXG4gICAgfSBhcyBSb29tTWVzc2FnZVRleHRFdmVudENvbnRlbnQgJiBSZXBsYWNlbWVudEV2ZW50PFJvb21NZXNzYWdlVGV4dEV2ZW50Q29udGVudD47XG5cbiAgICAvLyBUT0RPIG1hcmtkb3duIHN1cHBvcnRcblxuICAgIGNvbnN0IGlzTWFya2Rvd25FbmFibGVkID0gU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZTxib29sZWFuPihcIk1lc3NhZ2VDb21wb3NlcklucHV0LnVzZU1hcmtkb3duXCIpO1xuICAgIGNvbnN0IGZvcm1hdHRlZEJvZHkgPSBpc0hUTUwgPyBtZXNzYWdlIDogaXNNYXJrZG93bkVuYWJsZWQgPyBhd2FpdCBwbGFpblRvUmljaChtZXNzYWdlLCB0cnVlKSA6IG51bGw7XG5cbiAgICBpZiAoZm9ybWF0dGVkQm9keSkge1xuICAgICAgICBjb250ZW50LmZvcm1hdCA9IFwib3JnLm1hdHJpeC5jdXN0b20uaHRtbFwiO1xuICAgICAgICBjb250ZW50LmZvcm1hdHRlZF9ib2R5ID0gaXNFZGl0aW5nID8gYCR7Zm9ybWF0dGVkQm9keVByZWZpeH0gKiAke2Zvcm1hdHRlZEJvZHl9YCA6IGZvcm1hdHRlZEJvZHk7XG4gICAgfVxuXG4gICAgaWYgKGlzRWRpdGluZykge1xuICAgICAgICBjb250ZW50W1wibS5uZXdfY29udGVudFwiXSA9IHtcbiAgICAgICAgICAgIG1zZ3R5cGU6IGNvbnRlbnQubXNndHlwZSxcbiAgICAgICAgICAgIGJvZHk6IGJvZHksXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGZvcm1hdHRlZEJvZHkpIHtcbiAgICAgICAgICAgIGNvbnRlbnRbXCJtLm5ld19jb250ZW50XCJdLmZvcm1hdCA9IFwib3JnLm1hdHJpeC5jdXN0b20uaHRtbFwiO1xuICAgICAgICAgICAgY29udGVudFtcIm0ubmV3X2NvbnRlbnRcIl1bXCJmb3JtYXR0ZWRfYm9keVwiXSA9IGZvcm1hdHRlZEJvZHk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBuZXdSZWxhdGlvbiA9IGlzRWRpdGluZyA/IHsgLi4ucmVsYXRpb24sIHJlbF90eXBlOiBcIm0ucmVwbGFjZVwiLCBldmVudF9pZDogZWRpdGVkRXZlbnQuZ2V0SWQoKSB9IDogcmVsYXRpb247XG5cbiAgICAvLyBUT0RPIERvIHdlIG5lZWQgdG8gYXR0YWNoIG1lbnRpb25zIGhlcmU/XG4gICAgLy8gVE9ETyBIYW5kbGUgZWRpdGluZz9cbiAgICBhdHRhY2hSZWxhdGlvbihjb250ZW50LCBuZXdSZWxhdGlvbik7XG5cbiAgICBpZiAoIWlzRWRpdGluZyAmJiByZXBseVRvRXZlbnQgJiYgcGVybWFsaW5rQ3JlYXRvcikge1xuICAgICAgICBhZGRSZXBseVRvTWVzc2FnZUNvbnRlbnQoY29udGVudCwgcmVwbHlUb0V2ZW50LCB7XG4gICAgICAgICAgICBwZXJtYWxpbmtDcmVhdG9yLFxuICAgICAgICAgICAgaW5jbHVkZUxlZ2FjeUZhbGxiYWNrOiBpbmNsdWRlUmVwbHlMZWdhY3lGYWxsYmFjayxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRlbnQ7XG59XG5cbi8qKlxuICogV2l0aG91dCBhIG1vZGVsLCB3ZSBuZWVkIHRvIG1hbnVhbGx5IGFtZW5kIG1lbnRpb25zIGluIHVuY29udHJvbGxlZCBtZXNzYWdlIGNvbnRlbnRcbiAqIHRvIG1ha2Ugc3VyZSB0aGF0IG1lbnRpb25zIG1lZXQgdGhlIG1hdHJpeCBzcGVjaWZpY2F0aW9uLlxuICpcbiAqIEBwYXJhbSBjb250ZW50IC0gdGhlIG91dHB1dCBmcm9tIHRoZSBgTWVzc2FnZUNvbXBvc2VyYCBzdGF0ZSB3aGVuIGluIHBsYWluIHRleHQgbW9kZVxuICogQHJldHVybnMgLSBhIHN0cmluZyBmb3JtYXR0ZWQgd2l0aCB0aGUgbWVudGlvbnMgcmVwbGFjZWQgYXMgcmVxdWlyZWRcbiAqL1xuZnVuY3Rpb24gY29udmVydFBsYWluVGV4dFRvQm9keShjb250ZW50OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRvY3VtZW50ID0gbmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZyhjb250ZW50LCBcInRleHQvaHRtbFwiKTtcbiAgICBjb25zdCBtZW50aW9ucyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcImFbZGF0YS1tZW50aW9uLXR5cGVdXCIpKTtcblxuICAgIG1lbnRpb25zLmZvckVhY2goKG1lbnRpb24pID0+IHtcbiAgICAgICAgY29uc3QgbWVudGlvblR5cGUgPSBtZW50aW9uLmdldEF0dHJpYnV0ZShcImRhdGEtbWVudGlvbi10eXBlXCIpO1xuICAgICAgICBzd2l0Y2ggKG1lbnRpb25UeXBlKSB7XG4gICAgICAgICAgICBjYXNlIFwiYXQtcm9vbVwiOiB7XG4gICAgICAgICAgICAgICAgbWVudGlvbi5yZXBsYWNlV2l0aChcIkByb29tXCIpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInVzZXJcIjoge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlubmVyVGV4dCA9IG1lbnRpb24uaW5uZXJIVE1MO1xuICAgICAgICAgICAgICAgIG1lbnRpb24ucmVwbGFjZVdpdGgoaW5uZXJUZXh0KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJyb29tXCI6IHtcbiAgICAgICAgICAgICAgICAvLyBmb3IgdGhpcyBjYXNlIHdlIHVzZSBwYXJzZVBlcm1hbGluayB0byB0cnkgYW5kIGdldCB0aGUgbXggaWRcbiAgICAgICAgICAgICAgICBjb25zdCBocmVmID0gbWVudGlvbi5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpO1xuXG4gICAgICAgICAgICAgICAgLy8gaWYgdGhlIG1lbnRpb24gaGFzIG5vIGhyZWYgYXR0cmlidXRlLCBsZWF2ZSBpdCBhbG9uZVxuICAgICAgICAgICAgICAgIGlmIChocmVmID09PSBudWxsKSBicmVhaztcblxuICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSwgYXR0ZW1wdCB0byBwYXJzZSB0aGUgcm9vbSBhbGlhcyBvciBpZCBmcm9tIHRoZSBocmVmXG4gICAgICAgICAgICAgICAgY29uc3QgcGVybWFsaW5rUGFydHMgPSBwYXJzZVBlcm1hbGluayhocmVmKTtcblxuICAgICAgICAgICAgICAgIC8vIHRoZW4gaWYgd2UgaGF2ZSBwZXJtYWxpbmsgcGFydHMgd2l0aCBhIHZhbGlkIHJvb21JZE9yQWxpYXMsIHJlcGxhY2UgdGhlXG4gICAgICAgICAgICAgICAgLy8gcm9vbSBtZW50aW9uIHdpdGggdGhhdCB0ZXh0XG4gICAgICAgICAgICAgICAgaWYgKGlzTm90TnVsbChwZXJtYWxpbmtQYXJ0cykgJiYgaXNOb3ROdWxsKHBlcm1hbGlua1BhcnRzLnJvb21JZE9yQWxpYXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lbnRpb24ucmVwbGFjZVdpdGgocGVybWFsaW5rUGFydHMucm9vbUlkT3JBbGlhcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRvY3VtZW50LmJvZHkuaW5uZXJIVE1MO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFRQSxJQUFBQSxjQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFHQSxJQUFBRSxjQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSSxXQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxNQUFBLEdBQUFMLE9BQUE7QUFDQSxJQUFBTSxXQUFBLEdBQUFOLE9BQUE7QUFBc0QsU0FBQU8sUUFBQUMsQ0FBQSxF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