matrix-react-sdk
Version:
SDK for matrix.org using React
242 lines (230 loc) • 34.1 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.options = exports.linkify = exports._linkifyString = exports._linkifyElement = exports.Type = exports.ELEMENT_URL_PATTERN = void 0;
var _linkifyjs = _interopRequireWildcard(require("linkifyjs"));
var linkifyjs = _linkifyjs;
var _linkifyElement2 = _interopRequireDefault(require("linkify-element"));
var _linkifyString2 = _interopRequireDefault(require("linkify-string"));
var _matrix = require("matrix-js-sdk/src/matrix");
var _Permalinks = require("./utils/permalinks/Permalinks");
var _dispatcher = _interopRequireDefault(require("./dispatcher/dispatcher"));
var _actions = require("./dispatcher/actions");
var _MatrixClientPeg = require("./MatrixClientPeg");
var _UrlUtils = require("./utils/UrlUtils");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/*
Copyright 2024 New Vector Ltd.
Copyright 2019 The Matrix.org Foundation C.I.C.
Copyright 2015, 2016 OpenMarket Ltd
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
let Type = exports.Type = /*#__PURE__*/function (Type) {
Type["URL"] = "url";
Type["UserId"] = "userid";
Type["RoomAlias"] = "roomalias";
return Type;
}({});
function matrixOpaqueIdLinkifyParser({
scanner,
parser,
token,
name
}) {
const {
DOT,
// IPV4 necessity
NUM,
COLON,
SYM,
SLASH,
EQUALS,
HYPHEN,
UNDERSCORE
} = scanner.tokens;
// Contains NUM, WORD, UWORD, EMOJI, TLD, UTLD, SCHEME, SLASH_SCHEME and LOCALHOST plus custom protocols (e.g. "matrix")
const {
domain
} = scanner.tokens.groups;
// Tokens we need that are not contained in the domain group
const additionalLocalpartTokens = [DOT, SYM, SLASH, EQUALS, UNDERSCORE, HYPHEN];
const additionalDomainpartTokens = [HYPHEN];
const matrixToken = linkifyjs.createTokenClass(name, {
isLink: true
});
const matrixTokenState = new linkifyjs.State(matrixToken); // linkify doesn't appear to type this correctly
const matrixTokenWithPort = linkifyjs.createTokenClass(name, {
isLink: true
});
const matrixTokenWithPortState = new linkifyjs.State(matrixTokenWithPort); // linkify doesn't appear to type this correctly
const INITIAL_STATE = parser.start.tt(token);
// Localpart
const LOCALPART_STATE = new linkifyjs.State();
INITIAL_STATE.ta(domain, LOCALPART_STATE);
INITIAL_STATE.ta(additionalLocalpartTokens, LOCALPART_STATE);
LOCALPART_STATE.ta(domain, LOCALPART_STATE);
LOCALPART_STATE.ta(additionalLocalpartTokens, LOCALPART_STATE);
// Domainpart
const DOMAINPART_STATE_DOT = LOCALPART_STATE.tt(COLON);
DOMAINPART_STATE_DOT.ta(domain, matrixTokenState);
DOMAINPART_STATE_DOT.ta(additionalDomainpartTokens, matrixTokenState);
matrixTokenState.ta(domain, matrixTokenState);
matrixTokenState.ta(additionalDomainpartTokens, matrixTokenState);
matrixTokenState.tt(DOT, DOMAINPART_STATE_DOT);
// Port suffixes
matrixTokenState.tt(COLON).tt(NUM, matrixTokenWithPortState);
}
function onUserClick(event, userId) {
event.preventDefault();
_dispatcher.default.dispatch({
action: _actions.Action.ViewUser,
member: new _matrix.User(userId)
});
}
function onAliasClick(event, roomAlias) {
event.preventDefault();
_dispatcher.default.dispatch({
action: _actions.Action.ViewRoom,
room_alias: roomAlias,
metricsTrigger: "Timeline",
metricsViaKeyboard: false
});
}
const escapeRegExp = function (s) {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
};
// Recognise URLs from both our local and official Element deployments.
// Anyone else really should be using matrix.to. vector:// allowed to support Element Desktop relative links.
const ELEMENT_URL_PATTERN = exports.ELEMENT_URL_PATTERN = "^(?:vector://|https?://)?(?:" + escapeRegExp(window.location.host + window.location.pathname) + "|" + "(?:www\\.)?(?:riot|vector)\\.im/(?:app|beta|staging|develop)/|" + "(?:app|beta|staging|develop)\\.element\\.io/" + ")(#.*)";
const options = exports.options = {
events: function (href, type) {
switch (type) {
case Type.URL:
{
// intercept local permalinks to users and show them like userids (in userinfo of current room)
try {
const permalink = (0, _Permalinks.parsePermalink)(href);
if (permalink?.userId) {
return {
click: function (e) {
onUserClick(e, permalink.userId);
}
};
} else {
// for events, rooms etc. (anything other than users)
const localHref = (0, _Permalinks.tryTransformPermalinkToLocalHref)(href);
if (localHref !== href) {
// it could be converted to a localHref -> therefore handle locally
return {
click: function (e) {
e.preventDefault();
window.location.hash = localHref;
}
};
}
}
} catch (e) {
// OK fine, it's not actually a permalink
}
break;
}
case Type.UserId:
return {
click: function (e) {
const userId = (0, _Permalinks.parsePermalink)(href)?.userId ?? href;
if (userId) onUserClick(e, userId);
}
};
case Type.RoomAlias:
return {
click: function (e) {
const alias = (0, _Permalinks.parsePermalink)(href)?.roomIdOrAlias ?? href;
if (alias) onAliasClick(e, alias);
}
};
}
return {};
},
formatHref: function (href, type) {
switch (type) {
case "url":
if (href.startsWith("mxc://") && _MatrixClientPeg.MatrixClientPeg.get()) {
return (0, _matrix.getHttpUriForMxc)(_MatrixClientPeg.MatrixClientPeg.get().baseUrl, href, undefined, undefined, undefined, false, true);
}
// fallthrough
case Type.RoomAlias:
case Type.UserId:
default:
{
return (0, _Permalinks.tryTransformEntityToPermalink)(_MatrixClientPeg.MatrixClientPeg.safeGet(), href) ?? "";
}
}
},
attributes: {
rel: "noreferrer noopener"
},
ignoreTags: ["pre", "code"],
className: "linkified",
target: function (href, type) {
if (type === Type.URL) {
try {
const transformed = (0, _Permalinks.tryTransformPermalinkToLocalHref)(href);
if (transformed !== href ||
// if it could be converted to handle locally for matrix symbols e.g. @user:server.tdl and matrix.to
decodeURIComponent(href).match(ELEMENT_URL_PATTERN) // for https links to Element domains
) {
return "";
} else {
return "_blank";
}
} catch (e) {
// malformed URI
}
}
return "";
}
};
// Run the plugins
(0, _linkifyjs.registerPlugin)(Type.RoomAlias, ({
scanner,
parser
}) => {
const token = scanner.tokens.POUND;
matrixOpaqueIdLinkifyParser({
scanner,
parser,
token,
name: Type.RoomAlias
});
});
(0, _linkifyjs.registerPlugin)(Type.UserId, ({
scanner,
parser
}) => {
const token = scanner.tokens.AT;
matrixOpaqueIdLinkifyParser({
scanner,
parser,
token,
name: Type.UserId
});
});
// Linkify supports some common protocols but not others, register all permitted url schemes if unsupported
// https://github.com/Hypercontext/linkifyjs/blob/f4fad9df1870259622992bbfba38bfe3d0515609/packages/linkifyjs/src/scanner.js#L133-L141
// This also handles registering the `matrix:` protocol scheme
const linkifySupportedProtocols = ["file", "mailto", "http", "https", "ftp", "ftps"];
const optionalSlashProtocols = ["bitcoin", "geo", "im", "magnet", "mailto", "matrix", "news", "openpgp4fpr", "sip", "sms", "smsto", "tel", "urn", "xmpp"];
_UrlUtils.PERMITTED_URL_SCHEMES.forEach(scheme => {
if (!linkifySupportedProtocols.includes(scheme)) {
(0, _linkifyjs.registerCustomProtocol)(scheme, optionalSlashProtocols.includes(scheme));
}
});
(0, _linkifyjs.registerCustomProtocol)("mxc", false);
const linkify = exports.linkify = linkifyjs;
const _linkifyElement = exports._linkifyElement = _linkifyElement2.default;
const _linkifyString = exports._linkifyString = _linkifyString2.default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbGlua2lmeWpzIiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJyZXF1aXJlIiwibGlua2lmeWpzIiwiX2xpbmtpZnlFbGVtZW50MiIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfbGlua2lmeVN0cmluZzIiLCJfbWF0cml4IiwiX1Blcm1hbGlua3MiLCJfZGlzcGF0Y2hlciIsIl9hY3Rpb25zIiwiX01hdHJpeENsaWVudFBlZyIsIl9VcmxVdGlscyIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIlR5cGUiLCJleHBvcnRzIiwibWF0cml4T3BhcXVlSWRMaW5raWZ5UGFyc2VyIiwic2Nhbm5lciIsInBhcnNlciIsInRva2VuIiwibmFtZSIsIkRPVCIsIk5VTSIsIkNPTE9OIiwiU1lNIiwiU0xBU0giLCJFUVVBTFMiLCJIWVBIRU4iLCJVTkRFUlNDT1JFIiwidG9rZW5zIiwiZG9tYWluIiwiZ3JvdXBzIiwiYWRkaXRpb25hbExvY2FscGFydFRva2VucyIsImFkZGl0aW9uYWxEb21haW5wYXJ0VG9rZW5zIiwibWF0cml4VG9rZW4iLCJjcmVhdGVUb2tlbkNsYXNzIiwiaXNMaW5rIiwibWF0cml4VG9rZW5TdGF0ZSIsIlN0YXRlIiwibWF0cml4VG9rZW5XaXRoUG9ydCIsIm1hdHJpeFRva2VuV2l0aFBvcnRTdGF0ZSIsIklOSVRJQUxfU1RBVEUiLCJzdGFydCIsInR0IiwiTE9DQUxQQVJUX1NUQVRFIiwidGEiLCJET01BSU5QQVJUX1NUQVRFX0RPVCIsIm9uVXNlckNsaWNrIiwiZXZlbnQiLCJ1c2VySWQiLCJwcmV2ZW50RGVmYXVsdCIsImRpcyIsImRpc3BhdGNoIiwiYWN0aW9uIiwiQWN0aW9uIiwiVmlld1VzZXIiLCJtZW1iZXIiLCJVc2VyIiwib25BbGlhc0NsaWNrIiwicm9vbUFsaWFzIiwiVmlld1Jvb20iLCJyb29tX2FsaWFzIiwibWV0cmljc1RyaWdnZXIiLCJtZXRyaWNzVmlhS2V5Ym9hcmQiLCJlc2NhcGVSZWdFeHAiLCJzIiwicmVwbGFjZSIsIkVMRU1FTlRfVVJMX1BBVFRFUk4iLCJ3aW5kb3ciLCJsb2NhdGlvbiIsImhvc3QiLCJwYXRobmFtZSIsIm9wdGlvbnMiLCJldmVudHMiLCJocmVmIiwidHlwZSIsIlVSTCIsInBlcm1hbGluayIsInBhcnNlUGVybWFsaW5rIiwiY2xpY2siLCJsb2NhbEhyZWYiLCJ0cnlUcmFuc2Zvcm1QZXJtYWxpbmtUb0xvY2FsSHJlZiIsImhhc2giLCJVc2VySWQiLCJSb29tQWxpYXMiLCJhbGlhcyIsInJvb21JZE9yQWxpYXMiLCJmb3JtYXRIcmVmIiwic3RhcnRzV2l0aCIsIk1hdHJpeENsaWVudFBlZyIsImdldEh0dHBVcmlGb3JNeGMiLCJiYXNlVXJsIiwidW5kZWZpbmVkIiwidHJ5VHJhbnNmb3JtRW50aXR5VG9QZXJtYWxpbmsiLCJzYWZlR2V0IiwiYXR0cmlidXRlcyIsInJlbCIsImlnbm9yZVRhZ3MiLCJjbGFzc05hbWUiLCJ0YXJnZXQiLCJ0cmFuc2Zvcm1lZCIsImRlY29kZVVSSUNvbXBvbmVudCIsIm1hdGNoIiwicmVnaXN0ZXJQbHVnaW4iLCJQT1VORCIsIkFUIiwibGlua2lmeVN1cHBvcnRlZFByb3RvY29scyIsIm9wdGlvbmFsU2xhc2hQcm90b2NvbHMiLCJQRVJNSVRURURfVVJMX1NDSEVNRVMiLCJmb3JFYWNoIiwic2NoZW1lIiwiaW5jbHVkZXMiLCJyZWdpc3RlckN1c3RvbVByb3RvY29sIiwibGlua2lmeSIsIl9saW5raWZ5RWxlbWVudCIsImxpbmtpZnlFbGVtZW50IiwiX2xpbmtpZnlTdHJpbmciLCJsaW5raWZ5U3RyaW5nIl0sInNvdXJjZXMiOlsiLi4vc3JjL2xpbmtpZnktbWF0cml4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE5IFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5Db3B5cmlnaHQgMjAxNSwgMjAxNiBPcGVuTWFya2V0IEx0ZFxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgKiBhcyBsaW5raWZ5anMgZnJvbSBcImxpbmtpZnlqc1wiO1xuaW1wb3J0IHsgRXZlbnRMaXN0ZW5lcnMsIE9wdHMsIHJlZ2lzdGVyQ3VzdG9tUHJvdG9jb2wsIHJlZ2lzdGVyUGx1Z2luIH0gZnJvbSBcImxpbmtpZnlqc1wiO1xuaW1wb3J0IGxpbmtpZnlFbGVtZW50IGZyb20gXCJsaW5raWZ5LWVsZW1lbnRcIjtcbmltcG9ydCBsaW5raWZ5U3RyaW5nIGZyb20gXCJsaW5raWZ5LXN0cmluZ1wiO1xuaW1wb3J0IHsgZ2V0SHR0cFVyaUZvck14YywgVXNlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcblxuaW1wb3J0IHtcbiAgICBwYXJzZVBlcm1hbGluayxcbiAgICB0cnlUcmFuc2Zvcm1FbnRpdHlUb1Blcm1hbGluayxcbiAgICB0cnlUcmFuc2Zvcm1QZXJtYWxpbmtUb0xvY2FsSHJlZixcbn0gZnJvbSBcIi4vdXRpbHMvcGVybWFsaW5rcy9QZXJtYWxpbmtzXCI7XG5pbXBvcnQgZGlzIGZyb20gXCIuL2Rpc3BhdGNoZXIvZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSBcIi4vZGlzcGF0Y2hlci9hY3Rpb25zXCI7XG5pbXBvcnQgeyBWaWV3VXNlclBheWxvYWQgfSBmcm9tIFwiLi9kaXNwYXRjaGVyL3BheWxvYWRzL1ZpZXdVc2VyUGF5bG9hZFwiO1xuaW1wb3J0IHsgVmlld1Jvb21QYXlsb2FkIH0gZnJvbSBcIi4vZGlzcGF0Y2hlci9wYXlsb2Fkcy9WaWV3Um9vbVBheWxvYWRcIjtcbmltcG9ydCB7IE1hdHJpeENsaWVudFBlZyB9IGZyb20gXCIuL01hdHJpeENsaWVudFBlZ1wiO1xuaW1wb3J0IHsgUEVSTUlUVEVEX1VSTF9TQ0hFTUVTIH0gZnJvbSBcIi4vdXRpbHMvVXJsVXRpbHNcIjtcblxuZXhwb3J0IGVudW0gVHlwZSB7XG4gICAgVVJMID0gXCJ1cmxcIixcbiAgICBVc2VySWQgPSBcInVzZXJpZFwiLFxuICAgIFJvb21BbGlhcyA9IFwicm9vbWFsaWFzXCIsXG59XG5cbmZ1bmN0aW9uIG1hdHJpeE9wYXF1ZUlkTGlua2lmeVBhcnNlcih7XG4gICAgc2Nhbm5lcixcbiAgICBwYXJzZXIsXG4gICAgdG9rZW4sXG4gICAgbmFtZSxcbn06IHtcbiAgICBzY2FubmVyOiBsaW5raWZ5anMuU2Nhbm5lckluaXQ7XG4gICAgcGFyc2VyOiBsaW5raWZ5anMuUGFyc2VySW5pdDtcbiAgICB0b2tlbjogXCIjXCIgfCBcIitcIiB8IFwiQFwiO1xuICAgIG5hbWU6IFR5cGU7XG59KTogdm9pZCB7XG4gICAgY29uc3Qge1xuICAgICAgICBET1QsXG4gICAgICAgIC8vIElQVjQgbmVjZXNzaXR5XG4gICAgICAgIE5VTSxcbiAgICAgICAgQ09MT04sXG4gICAgICAgIFNZTSxcbiAgICAgICAgU0xBU0gsXG4gICAgICAgIEVRVUFMUyxcbiAgICAgICAgSFlQSEVOLFxuICAgICAgICBVTkRFUlNDT1JFLFxuICAgIH0gPSBzY2FubmVyLnRva2VucztcblxuICAgIC8vIENvbnRhaW5zIE5VTSwgV09SRCwgVVdPUkQsIEVNT0pJLCBUTEQsIFVUTEQsIFNDSEVNRSwgU0xBU0hfU0NIRU1FIGFuZCBMT0NBTEhPU1QgcGx1cyBjdXN0b20gcHJvdG9jb2xzIChlLmcuIFwibWF0cml4XCIpXG4gICAgY29uc3QgeyBkb21haW4gfSA9IHNjYW5uZXIudG9rZW5zLmdyb3VwcztcblxuICAgIC8vIFRva2VucyB3ZSBuZWVkIHRoYXQgYXJlIG5vdCBjb250YWluZWQgaW4gdGhlIGRvbWFpbiBncm91cFxuICAgIGNvbnN0IGFkZGl0aW9uYWxMb2NhbHBhcnRUb2tlbnMgPSBbRE9ULCBTWU0sIFNMQVNILCBFUVVBTFMsIFVOREVSU0NPUkUsIEhZUEhFTl07XG4gICAgY29uc3QgYWRkaXRpb25hbERvbWFpbnBhcnRUb2tlbnMgPSBbSFlQSEVOXTtcblxuICAgIGNvbnN0IG1hdHJpeFRva2VuID0gbGlua2lmeWpzLmNyZWF0ZVRva2VuQ2xhc3MobmFtZSwgeyBpc0xpbms6IHRydWUgfSk7XG4gICAgY29uc3QgbWF0cml4VG9rZW5TdGF0ZSA9IG5ldyBsaW5raWZ5anMuU3RhdGUobWF0cml4VG9rZW4pIGFzIGFueSBhcyBsaW5raWZ5anMuU3RhdGU8bGlua2lmeWpzLk11bHRpVG9rZW4+OyAvLyBsaW5raWZ5IGRvZXNuJ3QgYXBwZWFyIHRvIHR5cGUgdGhpcyBjb3JyZWN0bHlcblxuICAgIGNvbnN0IG1hdHJpeFRva2VuV2l0aFBvcnQgPSBsaW5raWZ5anMuY3JlYXRlVG9rZW5DbGFzcyhuYW1lLCB7IGlzTGluazogdHJ1ZSB9KTtcbiAgICBjb25zdCBtYXRyaXhUb2tlbldpdGhQb3J0U3RhdGUgPSBuZXcgbGlua2lmeWpzLlN0YXRlKFxuICAgICAgICBtYXRyaXhUb2tlbldpdGhQb3J0LFxuICAgICkgYXMgYW55IGFzIGxpbmtpZnlqcy5TdGF0ZTxsaW5raWZ5anMuTXVsdGlUb2tlbj47IC8vIGxpbmtpZnkgZG9lc24ndCBhcHBlYXIgdG8gdHlwZSB0aGlzIGNvcnJlY3RseVxuXG4gICAgY29uc3QgSU5JVElBTF9TVEFURSA9IHBhcnNlci5zdGFydC50dCh0b2tlbik7XG5cbiAgICAvLyBMb2NhbHBhcnRcbiAgICBjb25zdCBMT0NBTFBBUlRfU1RBVEUgPSBuZXcgbGlua2lmeWpzLlN0YXRlPGxpbmtpZnlqcy5NdWx0aVRva2VuPigpO1xuICAgIElOSVRJQUxfU1RBVEUudGEoZG9tYWluLCBMT0NBTFBBUlRfU1RBVEUpO1xuICAgIElOSVRJQUxfU1RBVEUudGEoYWRkaXRpb25hbExvY2FscGFydFRva2VucywgTE9DQUxQQVJUX1NUQVRFKTtcbiAgICBMT0NBTFBBUlRfU1RBVEUudGEoZG9tYWluLCBMT0NBTFBBUlRfU1RBVEUpO1xuICAgIExPQ0FMUEFSVF9TVEFURS50YShhZGRpdGlvbmFsTG9jYWxwYXJ0VG9rZW5zLCBMT0NBTFBBUlRfU1RBVEUpO1xuXG4gICAgLy8gRG9tYWlucGFydFxuICAgIGNvbnN0IERPTUFJTlBBUlRfU1RBVEVfRE9UID0gTE9DQUxQQVJUX1NUQVRFLnR0KENPTE9OKTtcbiAgICBET01BSU5QQVJUX1NUQVRFX0RPVC50YShkb21haW4sIG1hdHJpeFRva2VuU3RhdGUpO1xuICAgIERPTUFJTlBBUlRfU1RBVEVfRE9ULnRhKGFkZGl0aW9uYWxEb21haW5wYXJ0VG9rZW5zLCBtYXRyaXhUb2tlblN0YXRlKTtcbiAgICBtYXRyaXhUb2tlblN0YXRlLnRhKGRvbWFpbiwgbWF0cml4VG9rZW5TdGF0ZSk7XG4gICAgbWF0cml4VG9rZW5TdGF0ZS50YShhZGRpdGlvbmFsRG9tYWlucGFydFRva2VucywgbWF0cml4VG9rZW5TdGF0ZSk7XG4gICAgbWF0cml4VG9rZW5TdGF0ZS50dChET1QsIERPTUFJTlBBUlRfU1RBVEVfRE9UKTtcblxuICAgIC8vIFBvcnQgc3VmZml4ZXNcbiAgICBtYXRyaXhUb2tlblN0YXRlLnR0KENPTE9OKS50dChOVU0sIG1hdHJpeFRva2VuV2l0aFBvcnRTdGF0ZSk7XG59XG5cbmZ1bmN0aW9uIG9uVXNlckNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50LCB1c2VySWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZGlzLmRpc3BhdGNoPFZpZXdVc2VyUGF5bG9hZD4oe1xuICAgICAgICBhY3Rpb246IEFjdGlvbi5WaWV3VXNlcixcbiAgICAgICAgbWVtYmVyOiBuZXcgVXNlcih1c2VySWQpLFxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBvbkFsaWFzQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIHJvb21BbGlhczogc3RyaW5nKTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBkaXMuZGlzcGF0Y2g8Vmlld1Jvb21QYXlsb2FkPih7XG4gICAgICAgIGFjdGlvbjogQWN0aW9uLlZpZXdSb29tLFxuICAgICAgICByb29tX2FsaWFzOiByb29tQWxpYXMsXG4gICAgICAgIG1ldHJpY3NUcmlnZ2VyOiBcIlRpbWVsaW5lXCIsXG4gICAgICAgIG1ldHJpY3NWaWFLZXlib2FyZDogZmFsc2UsXG4gICAgfSk7XG59XG5cbmNvbnN0IGVzY2FwZVJlZ0V4cCA9IGZ1bmN0aW9uIChzOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBzLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKTtcbn07XG5cbi8vIFJlY29nbmlzZSBVUkxzIGZyb20gYm90aCBvdXIgbG9jYWwgYW5kIG9mZmljaWFsIEVsZW1lbnQgZGVwbG95bWVudHMuXG4vLyBBbnlvbmUgZWxzZSByZWFsbHkgc2hvdWxkIGJlIHVzaW5nIG1hdHJpeC50by4gdmVjdG9yOi8vIGFsbG93ZWQgdG8gc3VwcG9ydCBFbGVtZW50IERlc2t0b3AgcmVsYXRpdmUgbGlua3MuXG5leHBvcnQgY29uc3QgRUxFTUVOVF9VUkxfUEFUVEVSTiA9XG4gICAgXCJeKD86dmVjdG9yOi8vfGh0dHBzPzovLyk/KD86XCIgK1xuICAgIGVzY2FwZVJlZ0V4cCh3aW5kb3cubG9jYXRpb24uaG9zdCArIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSkgK1xuICAgIFwifFwiICtcbiAgICBcIig/Ond3d1xcXFwuKT8oPzpyaW90fHZlY3RvcilcXFxcLmltLyg/OmFwcHxiZXRhfHN0YWdpbmd8ZGV2ZWxvcCkvfFwiICtcbiAgICBcIig/OmFwcHxiZXRhfHN0YWdpbmd8ZGV2ZWxvcClcXFxcLmVsZW1lbnRcXFxcLmlvL1wiICtcbiAgICBcIikoIy4qKVwiO1xuXG5leHBvcnQgY29uc3Qgb3B0aW9uczogT3B0cyA9IHtcbiAgICBldmVudHM6IGZ1bmN0aW9uIChocmVmOiBzdHJpbmcsIHR5cGU6IHN0cmluZyk6IEV2ZW50TGlzdGVuZXJzIHtcbiAgICAgICAgc3dpdGNoICh0eXBlIGFzIFR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgVHlwZS5VUkw6IHtcbiAgICAgICAgICAgICAgICAvLyBpbnRlcmNlcHQgbG9jYWwgcGVybWFsaW5rcyB0byB1c2VycyBhbmQgc2hvdyB0aGVtIGxpa2UgdXNlcmlkcyAoaW4gdXNlcmluZm8gb2YgY3VycmVudCByb29tKVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBlcm1hbGluayA9IHBhcnNlUGVybWFsaW5rKGhyZWYpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGVybWFsaW5rPy51c2VySWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uIChlOiBNb3VzZUV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVXNlckNsaWNrKGUsIHBlcm1hbGluay51c2VySWQhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBldmVudHMsIHJvb21zIGV0Yy4gKGFueXRoaW5nIG90aGVyIHRoYW4gdXNlcnMpXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbEhyZWYgPSB0cnlUcmFuc2Zvcm1QZXJtYWxpbmtUb0xvY2FsSHJlZihocmVmKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbEhyZWYgIT09IGhyZWYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpdCBjb3VsZCBiZSBjb252ZXJ0ZWQgdG8gYSBsb2NhbEhyZWYgLT4gdGhlcmVmb3JlIGhhbmRsZSBsb2NhbGx5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uIChlOiBNb3VzZUV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaGFzaCA9IGxvY2FsSHJlZjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBPSyBmaW5lLCBpdCdzIG5vdCBhY3R1YWxseSBhIHBlcm1hbGlua1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgVHlwZS5Vc2VySWQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uIChlOiBNb3VzZUV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1c2VySWQgPSBwYXJzZVBlcm1hbGluayhocmVmKT8udXNlcklkID8/IGhyZWY7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlcklkKSBvblVzZXJDbGljayhlLCB1c2VySWQpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjYXNlIFR5cGUuUm9vbUFsaWFzOlxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbiAoZTogTW91c2VFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWxpYXMgPSBwYXJzZVBlcm1hbGluayhocmVmKT8ucm9vbUlkT3JBbGlhcyA/PyBocmVmO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFsaWFzKSBvbkFsaWFzQ2xpY2soZSwgYWxpYXMpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge307XG4gICAgfSxcblxuICAgIGZvcm1hdEhyZWY6IGZ1bmN0aW9uIChocmVmOiBzdHJpbmcsIHR5cGU6IFR5cGUgfCBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgXCJ1cmxcIjpcbiAgICAgICAgICAgICAgICBpZiAoaHJlZi5zdGFydHNXaXRoKFwibXhjOi8vXCIpICYmIE1hdHJpeENsaWVudFBlZy5nZXQoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0SHR0cFVyaUZvck14YyhcbiAgICAgICAgICAgICAgICAgICAgICAgIE1hdHJpeENsaWVudFBlZy5nZXQoKSEuYmFzZVVybCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhyZWYsXG4gICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZmFsbHRocm91Z2hcbiAgICAgICAgICAgIGNhc2UgVHlwZS5Sb29tQWxpYXM6XG4gICAgICAgICAgICBjYXNlIFR5cGUuVXNlcklkOlxuICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnlUcmFuc2Zvcm1FbnRpdHlUb1Blcm1hbGluayhNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLCBocmVmKSA/PyBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgcmVsOiBcIm5vcmVmZXJyZXIgbm9vcGVuZXJcIixcbiAgICB9LFxuXG4gICAgaWdub3JlVGFnczogW1wicHJlXCIsIFwiY29kZVwiXSxcblxuICAgIGNsYXNzTmFtZTogXCJsaW5raWZpZWRcIixcblxuICAgIHRhcmdldDogZnVuY3Rpb24gKGhyZWY6IHN0cmluZywgdHlwZTogVHlwZSB8IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGlmICh0eXBlID09PSBUeXBlLlVSTCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZCA9IHRyeVRyYW5zZm9ybVBlcm1hbGlua1RvTG9jYWxIcmVmKGhyZWYpO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWQgIT09IGhyZWYgfHwgLy8gaWYgaXQgY291bGQgYmUgY29udmVydGVkIHRvIGhhbmRsZSBsb2NhbGx5IGZvciBtYXRyaXggc3ltYm9scyBlLmcuIEB1c2VyOnNlcnZlci50ZGwgYW5kIG1hdHJpeC50b1xuICAgICAgICAgICAgICAgICAgICBkZWNvZGVVUklDb21wb25lbnQoaHJlZikubWF0Y2goRUxFTUVOVF9VUkxfUEFUVEVSTikgLy8gZm9yIGh0dHBzIGxpbmtzIHRvIEVsZW1lbnQgZG9tYWluc1xuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJfYmxhbmtcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gbWFsZm9ybWVkIFVSSVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgIH0sXG59O1xuXG4vLyBSdW4gdGhlIHBsdWdpbnNcbnJlZ2lzdGVyUGx1Z2luKFR5cGUuUm9vbUFsaWFzLCAoeyBzY2FubmVyLCBwYXJzZXIgfSkgPT4ge1xuICAgIGNvbnN0IHRva2VuID0gc2Nhbm5lci50b2tlbnMuUE9VTkQgYXMgXCIjXCI7XG4gICAgbWF0cml4T3BhcXVlSWRMaW5raWZ5UGFyc2VyKHtcbiAgICAgICAgc2Nhbm5lcixcbiAgICAgICAgcGFyc2VyLFxuICAgICAgICB0b2tlbixcbiAgICAgICAgbmFtZTogVHlwZS5Sb29tQWxpYXMsXG4gICAgfSk7XG59KTtcblxucmVnaXN0ZXJQbHVnaW4oVHlwZS5Vc2VySWQsICh7IHNjYW5uZXIsIHBhcnNlciB9KSA9PiB7XG4gICAgY29uc3QgdG9rZW4gPSBzY2FubmVyLnRva2Vucy5BVCBhcyBcIkBcIjtcbiAgICBtYXRyaXhPcGFxdWVJZExpbmtpZnlQYXJzZXIoe1xuICAgICAgICBzY2FubmVyLFxuICAgICAgICBwYXJzZXIsXG4gICAgICAgIHRva2VuLFxuICAgICAgICBuYW1lOiBUeXBlLlVzZXJJZCxcbiAgICB9KTtcbn0pO1xuXG4vLyBMaW5raWZ5IHN1cHBvcnRzIHNvbWUgY29tbW9uIHByb3RvY29scyBidXQgbm90IG90aGVycywgcmVnaXN0ZXIgYWxsIHBlcm1pdHRlZCB1cmwgc2NoZW1lcyBpZiB1bnN1cHBvcnRlZFxuLy8gaHR0cHM6Ly9naXRodWIuY29tL0h5cGVyY29udGV4dC9saW5raWZ5anMvYmxvYi9mNGZhZDlkZjE4NzAyNTk2MjI5OTJiYmZiYTM4YmZlM2QwNTE1NjA5L3BhY2thZ2VzL2xpbmtpZnlqcy9zcmMvc2Nhbm5lci5qcyNMMTMzLUwxNDFcbi8vIFRoaXMgYWxzbyBoYW5kbGVzIHJlZ2lzdGVyaW5nIHRoZSBgbWF0cml4OmAgcHJvdG9jb2wgc2NoZW1lXG5jb25zdCBsaW5raWZ5U3VwcG9ydGVkUHJvdG9jb2xzID0gW1wiZmlsZVwiLCBcIm1haWx0b1wiLCBcImh0dHBcIiwgXCJodHRwc1wiLCBcImZ0cFwiLCBcImZ0cHNcIl07XG5jb25zdCBvcHRpb25hbFNsYXNoUHJvdG9jb2xzID0gW1xuICAgIFwiYml0Y29pblwiLFxuICAgIFwiZ2VvXCIsXG4gICAgXCJpbVwiLFxuICAgIFwibWFnbmV0XCIsXG4gICAgXCJtYWlsdG9cIixcbiAgICBcIm1hdHJpeFwiLFxuICAgIFwibmV3c1wiLFxuICAgIFwib3BlbnBncDRmcHJcIixcbiAgICBcInNpcFwiLFxuICAgIFwic21zXCIsXG4gICAgXCJzbXN0b1wiLFxuICAgIFwidGVsXCIsXG4gICAgXCJ1cm5cIixcbiAgICBcInhtcHBcIixcbl07XG5cblBFUk1JVFRFRF9VUkxfU0NIRU1FUy5mb3JFYWNoKChzY2hlbWUpID0+IHtcbiAgICBpZiAoIWxpbmtpZnlTdXBwb3J0ZWRQcm90b2NvbHMuaW5jbHVkZXMoc2NoZW1lKSkge1xuICAgICAgICByZWdpc3RlckN1c3RvbVByb3RvY29sKHNjaGVtZSwgb3B0aW9uYWxTbGFzaFByb3RvY29scy5pbmNsdWRlcyhzY2hlbWUpKTtcbiAgICB9XG59KTtcblxucmVnaXN0ZXJDdXN0b21Qcm90b2NvbChcIm14Y1wiLCBmYWxzZSk7XG5cbmV4cG9ydCBjb25zdCBsaW5raWZ5ID0gbGlua2lmeWpzO1xuZXhwb3J0IGNvbnN0IF9saW5raWZ5RWxlbWVudCA9IGxpbmtpZnlFbGVtZW50O1xuZXhwb3J0IGNvbnN0IF9saW5raWZ5U3RyaW5nID0gbGlua2lmeVN0cmluZztcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVNBLElBQUFBLFVBQUEsR0FBQUMsdUJBQUEs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