matrix-react-sdk
Version:
SDK for matrix.org using React
963 lines (955 loc) • 155 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "Command", {
enumerable: true,
get: function () {
return _command.Command;
}
});
Object.defineProperty(exports, "CommandCategories", {
enumerable: true,
get: function () {
return _interface.CommandCategories;
}
});
exports.Commands = exports.CommandMap = void 0;
exports.getCommand = getCommand;
exports.parseCommandString = parseCommandString;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var React = _interopRequireWildcard(require("react"));
var _matrix = require("matrix-js-sdk/src/matrix");
var _logger = require("matrix-js-sdk/src/logger");
var _types = require("matrix-js-sdk/src/types");
var _dispatcher = _interopRequireDefault(require("./dispatcher/dispatcher"));
var _languageHandler = require("./languageHandler");
var _Modal = _interopRequireDefault(require("./Modal"));
var _MultiInviter = _interopRequireDefault(require("./utils/MultiInviter"));
var _HtmlUtils = require("./HtmlUtils");
var _QuestionDialog = _interopRequireDefault(require("./components/views/dialogs/QuestionDialog"));
var _WidgetUtils = _interopRequireDefault(require("./utils/WidgetUtils"));
var _colour = require("./utils/colour");
var _UserAddress = require("./UserAddress");
var _UrlUtils = require("./utils/UrlUtils");
var _IdentityServerUtils = require("./utils/IdentityServerUtils");
var _WidgetType = require("./widgets/WidgetType");
var _Jitsi = require("./widgets/Jitsi");
var _BugReportDialog = _interopRequireDefault(require("./components/views/dialogs/BugReportDialog"));
var _createRoom = require("./createRoom");
var _actions = require("./dispatcher/actions");
var _SdkConfig = _interopRequireDefault(require("./SdkConfig"));
var _SettingsStore = _interopRequireDefault(require("./settings/SettingsStore"));
var _UIFeature = require("./settings/UIFeature");
var _effects = require("./effects");
var _LegacyCallHandler = _interopRequireDefault(require("./LegacyCallHandler"));
var _Rooms = require("./Rooms");
var _RoomUpgrade = require("./utils/RoomUpgrade");
var _DevtoolsDialog = _interopRequireDefault(require("./components/views/dialogs/DevtoolsDialog"));
var _RoomUpgradeWarningDialog = _interopRequireDefault(require("./components/views/dialogs/RoomUpgradeWarningDialog"));
var _InfoDialog = _interopRequireDefault(require("./components/views/dialogs/InfoDialog"));
var _SlashCommandHelpDialog = _interopRequireDefault(require("./components/views/dialogs/SlashCommandHelpDialog"));
var _UIComponents = require("./customisations/helpers/UIComponents");
var _RoomContext = require("./contexts/RoomContext");
var _VoipUserMapper = _interopRequireDefault(require("./VoipUserMapper"));
var _serialize = require("./editor/serialize");
var _leaveBehaviour = require("./utils/leave-behaviour");
var _MatrixClientPeg = require("./MatrixClientPeg");
var _deviceInfo = require("./utils/crypto/deviceInfo");
var _utils = require("./slash-commands/utils");
var _op = require("./slash-commands/op");
var _interface = require("./slash-commands/interface");
var _command = require("./slash-commands/command");
var _join = require("./slash-commands/join");
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; }
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 2020 The Matrix.org Foundation C.I.C.
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
Copyright 2018 New Vector Ltd
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.
*/
const Commands = exports.Commands = [new _command.Command({
command: "spoiler",
args: "<message>",
description: (0, _languageHandler._td)("slash_command|spoiler"),
runFn: function (cli, roomId, threadId, message = "") {
return (0, _utils.successSync)(_matrix.ContentHelpers.makeHtmlMessage(message, `<span data-mx-spoiler>${message}</span>`));
},
category: _interface.CommandCategories.messages
}), new _command.Command({
command: "shrug",
args: "<message>",
description: (0, _languageHandler._td)("slash_command|shrug"),
runFn: function (cli, roomId, threadId, args) {
let message = "¯\\_(ツ)_/¯";
if (args) {
message = message + " " + args;
}
return (0, _utils.successSync)(_matrix.ContentHelpers.makeTextMessage(message));
},
category: _interface.CommandCategories.messages
}), new _command.Command({
command: "tableflip",
args: "<message>",
description: (0, _languageHandler._td)("slash_command|tableflip"),
runFn: function (cli, roomId, threadId, args) {
let message = "(╯°□°)╯︵ ┻━┻";
if (args) {
message = message + " " + args;
}
return (0, _utils.successSync)(_matrix.ContentHelpers.makeTextMessage(message));
},
category: _interface.CommandCategories.messages
}), new _command.Command({
command: "unflip",
args: "<message>",
description: (0, _languageHandler._td)("slash_command|unflip"),
runFn: function (cli, roomId, threadId, args) {
let message = "┬──┬ ノ( ゜-゜ノ)";
if (args) {
message = message + " " + args;
}
return (0, _utils.successSync)(_matrix.ContentHelpers.makeTextMessage(message));
},
category: _interface.CommandCategories.messages
}), new _command.Command({
command: "lenny",
args: "<message>",
description: (0, _languageHandler._td)("slash_command|lenny"),
runFn: function (cli, roomId, threadId, args) {
let message = "( ͡° ͜ʖ ͡°)";
if (args) {
message = message + " " + args;
}
return (0, _utils.successSync)(_matrix.ContentHelpers.makeTextMessage(message));
},
category: _interface.CommandCategories.messages
}), new _command.Command({
command: "plain",
args: "<message>",
description: (0, _languageHandler._td)("slash_command|plain"),
runFn: function (cli, roomId, threadId, messages = "") {
return (0, _utils.successSync)(_matrix.ContentHelpers.makeTextMessage(messages));
},
category: _interface.CommandCategories.messages
}), new _command.Command({
command: "html",
args: "<message>",
description: (0, _languageHandler._td)("slash_command|html"),
runFn: function (cli, roomId, threadId, messages = "") {
return (0, _utils.successSync)(_matrix.ContentHelpers.makeHtmlMessage(messages, messages));
},
category: _interface.CommandCategories.messages
}), new _command.Command({
command: "upgraderoom",
args: "<new_version>",
description: (0, _languageHandler._td)("slash_command|upgraderoom"),
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli) && _SettingsStore.default.getValue("developerMode"),
runFn: function (cli, roomId, threadId, args) {
if (args) {
const room = cli.getRoom(roomId);
if (!room?.currentState.mayClientSendStateEvent("m.room.tombstone", cli)) {
return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|upgraderoom_permission_error"));
}
const {
finished
} = _Modal.default.createDialog(_RoomUpgradeWarningDialog.default, {
roomId: roomId,
targetVersion: args
}, /*className=*/undefined, /*isPriority=*/false, /*isStatic=*/true);
return (0, _utils.success)(finished.then(async ([resp]) => {
if (!resp?.continue) return;
await (0, _RoomUpgrade.upgradeRoom)(room, args, resp.invite);
}));
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.admin,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "jumptodate",
args: "<YYYY-MM-DD>",
description: (0, _languageHandler._td)("slash_command|jumptodate"),
isEnabled: () => _SettingsStore.default.getValue("feature_jump_to_date"),
runFn: function (cli, roomId, threadId, args) {
if (args) {
return (0, _utils.success)((async () => {
const unixTimestamp = Date.parse(args);
if (!unixTimestamp) {
throw new _languageHandler.UserFriendlyError("slash_command|jumptodate_invalid_input", {
inputDate: args,
cause: undefined
});
}
const {
event_id: eventId,
origin_server_ts: originServerTs
} = await cli.timestampToEvent(roomId, unixTimestamp, _matrix.Direction.Forward);
_logger.logger.log(`/timestamp_to_event: found ${eventId} (${originServerTs}) for timestamp=${unixTimestamp}`);
_dispatcher.default.dispatch({
action: _actions.Action.ViewRoom,
event_id: eventId,
highlighted: true,
room_id: roomId,
metricsTrigger: "SlashCommand",
metricsViaKeyboard: true
});
})());
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.actions
}), new _command.Command({
command: "nick",
args: "<display_name>",
description: (0, _languageHandler._td)("slash_command|nick"),
runFn: function (cli, roomId, threadId, args) {
if (args) {
return (0, _utils.success)(cli.setDisplayName(args));
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.actions,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "myroomnick",
aliases: ["roomnick"],
args: "<display_name>",
description: (0, _languageHandler._td)("slash_command|myroomnick"),
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
if (args) {
const ev = cli.getRoom(roomId)?.currentState.getStateEvents(_matrix.EventType.RoomMember, cli.getSafeUserId());
const content = _objectSpread(_objectSpread({}, ev ? ev.getContent() : {
membership: _types.KnownMembership.Join
}), {}, {
displayname: args
});
return (0, _utils.success)(cli.sendStateEvent(roomId, _matrix.EventType.RoomMember, content, cli.getSafeUserId()));
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.actions,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "roomavatar",
args: "[<mxc_url>]",
description: (0, _languageHandler._td)("slash_command|roomavatar"),
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
let promise = Promise.resolve(args ?? null);
if (!args) {
promise = (0, _utils.singleMxcUpload)(cli);
}
return (0, _utils.success)(promise.then(url => {
if (!url) return;
return cli.sendStateEvent(roomId, _matrix.EventType.RoomAvatar, {
url
}, "");
}));
},
category: _interface.CommandCategories.actions,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "myroomavatar",
args: "[<mxc_url>]",
description: (0, _languageHandler._td)("slash_command|myroomavatar"),
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
const room = cli.getRoom(roomId);
const userId = cli.getSafeUserId();
let promise = Promise.resolve(args ?? null);
if (!args) {
promise = (0, _utils.singleMxcUpload)(cli);
}
return (0, _utils.success)(promise.then(url => {
if (!url) return;
const ev = room?.currentState.getStateEvents(_matrix.EventType.RoomMember, userId);
const content = _objectSpread(_objectSpread({}, ev ? ev.getContent() : {
membership: _types.KnownMembership.Join
}), {}, {
avatar_url: url
});
return cli.sendStateEvent(roomId, _matrix.EventType.RoomMember, content, userId);
}));
},
category: _interface.CommandCategories.actions,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "myavatar",
args: "[<mxc_url>]",
description: (0, _languageHandler._td)("slash_command|myavatar"),
runFn: function (cli, roomId, threadId, args) {
let promise = Promise.resolve(args ?? null);
if (!args) {
promise = (0, _utils.singleMxcUpload)(cli);
}
return (0, _utils.success)(promise.then(url => {
if (!url) return;
return cli.setAvatarUrl(url);
}));
},
category: _interface.CommandCategories.actions,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "topic",
args: "[<topic>]",
description: (0, _languageHandler._td)("slash_command|topic"),
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
if (args) {
const html = (0, _serialize.htmlSerializeFromMdIfNeeded)(args, {
forceHTML: false
});
return (0, _utils.success)(cli.setRoomTopic(roomId, args, html));
}
const room = cli.getRoom(roomId);
if (!room) {
return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|topic_room_error", {
roomId,
cause: undefined
}));
}
const content = room.currentState.getStateEvents("m.room.topic", "")?.getContent();
const topic = !!content ? _matrix.ContentHelpers.parseTopicContent(content) : {
text: (0, _languageHandler._t)("slash_command|topic_none")
};
const body = (0, _HtmlUtils.topicToHtml)(topic.text, topic.html, undefined, true);
_Modal.default.createDialog(_InfoDialog.default, {
title: room.name,
description: /*#__PURE__*/React.createElement(_HtmlUtils.Linkify, null, body),
hasCloseButton: true,
className: "markdown-body"
});
return (0, _utils.success)();
},
category: _interface.CommandCategories.admin,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "roomname",
args: "<name>",
description: (0, _languageHandler._td)("slash_command|roomname"),
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
if (args) {
return (0, _utils.success)(cli.setRoomName(roomId, args));
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.admin,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "invite",
args: "<user-id> [<reason>]",
description: (0, _languageHandler._td)("slash_command|invite"),
analyticsName: "Invite",
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli) && (0, _UIComponents.shouldShowComponent)(_UIFeature.UIComponent.InviteUsers),
runFn: function (cli, roomId, threadId, args) {
if (args) {
const [address, reason] = args.split(/\s+(.+)/);
if (address) {
// We use a MultiInviter to re-use the invite logic, even though
// we're only inviting one user.
// If we need an identity server but don't have one, things
// get a bit more complex here, but we try to show something
// meaningful.
let prom = Promise.resolve();
if ((0, _UserAddress.getAddressType)(address) === _UserAddress.AddressType.Email && !cli.getIdentityServerUrl()) {
const defaultIdentityServerUrl = (0, _IdentityServerUtils.getDefaultIdentityServerUrl)();
if (defaultIdentityServerUrl) {
const {
finished
} = _Modal.default.createDialog(_QuestionDialog.default, {
title: (0, _languageHandler._t)("slash_command|invite_3pid_use_default_is_title"),
description: /*#__PURE__*/React.createElement("p", null, (0, _languageHandler._t)("slash_command|invite_3pid_use_default_is_title_description", {
defaultIdentityServerName: (0, _UrlUtils.abbreviateUrl)(defaultIdentityServerUrl)
})),
button: (0, _languageHandler._t)("action|continue")
});
prom = finished.then(([useDefault]) => {
if (useDefault) {
(0, _IdentityServerUtils.setToDefaultIdentityServer)(cli);
return;
}
throw new _languageHandler.UserFriendlyError("slash_command|invite_3pid_needs_is_error");
});
} else {
return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|invite_3pid_needs_is_error"));
}
}
const inviter = new _MultiInviter.default(cli, roomId);
return (0, _utils.success)(prom.then(() => {
return inviter.invite([address], reason);
}).then(() => {
if (inviter.getCompletionState(address) !== "invited") {
const errorStringFromInviterUtility = inviter.getErrorText(address);
if (errorStringFromInviterUtility) {
throw new Error(errorStringFromInviterUtility);
} else {
throw new _languageHandler.UserFriendlyError("slash_command|invite_failed", {
user: address,
roomId,
cause: undefined
});
}
}
}));
}
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.actions,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), _join.goto, _join.join, new _command.Command({
command: "part",
args: "[<room-address>]",
description: (0, _languageHandler._td)("action|leave_room"),
analyticsName: "Part",
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
let targetRoomId;
if (args) {
const matches = args.match(/^(\S+)$/);
if (matches) {
let roomAlias = matches[1];
if (roomAlias[0] !== "#") return (0, _utils.reject)(this.getUsage());
if (!roomAlias.includes(":")) {
roomAlias += ":" + cli.getDomain();
}
// Try to find a room with this alias
const rooms = cli.getRooms();
targetRoomId = rooms.find(room => {
return room.getCanonicalAlias() === roomAlias || room.getAltAliases().includes(roomAlias);
})?.roomId;
if (!targetRoomId) {
return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|part_unknown_alias", {
roomAlias,
cause: undefined
}));
}
}
}
if (!targetRoomId) targetRoomId = roomId;
return (0, _utils.success)((0, _leaveBehaviour.leaveRoomBehaviour)(cli, targetRoomId));
},
category: _interface.CommandCategories.actions,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "remove",
aliases: ["kick"],
args: "<user-id> [reason]",
description: (0, _languageHandler._td)("slash_command|remove"),
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
if (args) {
const matches = args.match(/^(\S+?)( +(.*))?$/);
if (matches) {
return (0, _utils.success)(cli.kick(roomId, matches[1], matches[3]));
}
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.admin,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "ban",
args: "<user-id> [reason]",
description: (0, _languageHandler._td)("slash_command|ban"),
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
if (args) {
const matches = args.match(/^(\S+?)( +(.*))?$/);
if (matches) {
return (0, _utils.success)(cli.ban(roomId, matches[1], matches[3]));
}
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.admin,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "unban",
args: "<user-id>",
description: (0, _languageHandler._td)("slash_command|unban"),
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
if (args) {
const matches = args.match(/^(\S+)$/);
if (matches) {
// Reset the user membership to "leave" to unban him
return (0, _utils.success)(cli.unban(roomId, matches[1]));
}
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.admin,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "ignore",
args: "<user-id>",
description: (0, _languageHandler._td)("slash_command|ignore"),
runFn: function (cli, roomId, threadId, args) {
if (args) {
const matches = args.match(/^(@[^:]+:\S+)$/);
if (matches) {
const userId = matches[1];
const ignoredUsers = cli.getIgnoredUsers();
ignoredUsers.push(userId); // de-duped internally in the js-sdk
return (0, _utils.success)(cli.setIgnoredUsers(ignoredUsers).then(() => {
_Modal.default.createDialog(_InfoDialog.default, {
title: (0, _languageHandler._t)("slash_command|ignore_dialog_title"),
description: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("p", null, (0, _languageHandler._t)("slash_command|ignore_dialog_description", {
userId
})))
});
}));
}
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.actions
}), new _command.Command({
command: "unignore",
args: "<user-id>",
description: (0, _languageHandler._td)("slash_command|unignore"),
runFn: function (cli, roomId, threadId, args) {
if (args) {
const matches = args.match(/(^@[^:]+:\S+$)/);
if (matches) {
const userId = matches[1];
const ignoredUsers = cli.getIgnoredUsers();
const index = ignoredUsers.indexOf(userId);
if (index !== -1) ignoredUsers.splice(index, 1);
return (0, _utils.success)(cli.setIgnoredUsers(ignoredUsers).then(() => {
_Modal.default.createDialog(_InfoDialog.default, {
title: (0, _languageHandler._t)("slash_command|unignore_dialog_title"),
description: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("p", null, (0, _languageHandler._t)("slash_command|unignore_dialog_description", {
userId
})))
});
}));
}
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.actions
}), _op.op, _op.deop, new _command.Command({
command: "devtools",
description: (0, _languageHandler._td)("slash_command|devtools"),
runFn: function (cli, roomId, threadRootId) {
_Modal.default.createDialog(_DevtoolsDialog.default, {
roomId,
threadRootId
}, "mx_DevtoolsDialog_wrapper");
return (0, _utils.success)();
},
category: _interface.CommandCategories.advanced
}), new _command.Command({
command: "addwidget",
args: "<url | embed code | Jitsi url>",
description: (0, _languageHandler._td)("slash_command|addwidget"),
isEnabled: cli => _SettingsStore.default.getValue(_UIFeature.UIFeature.Widgets) && (0, _UIComponents.shouldShowComponent)(_UIFeature.UIComponent.AddIntegrations) && !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, widgetUrl) {
if (!widgetUrl) {
return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|addwidget_missing_url"));
}
// Try and parse out a widget URL from iframes
if (widgetUrl.toLowerCase().startsWith("<iframe ")) {
const embed = new DOMParser().parseFromString(widgetUrl, "text/html").body;
if (embed?.childNodes?.length === 1) {
const iframe = embed.firstElementChild;
if (iframe?.tagName.toLowerCase() === "iframe") {
_logger.logger.log("Pulling URL out of iframe (embed code)");
if (!iframe.hasAttribute("src")) {
return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|addwidget_iframe_missing_src"));
}
widgetUrl = iframe.getAttribute("src");
}
}
}
if (!widgetUrl.startsWith("https://") && !widgetUrl.startsWith("http://")) {
return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|addwidget_invalid_protocol"));
}
if (_WidgetUtils.default.canUserModifyWidgets(cli, roomId)) {
const userId = cli.getUserId();
const nowMs = new Date().getTime();
const widgetId = encodeURIComponent(`${roomId}_${userId}_${nowMs}`);
let type = _WidgetType.WidgetType.CUSTOM;
let name = "Custom";
let data = {};
// Make the widget a Jitsi widget if it looks like a Jitsi widget
const jitsiData = _Jitsi.Jitsi.getInstance().parsePreferredConferenceUrl(widgetUrl);
if (jitsiData) {
_logger.logger.log("Making /addwidget widget a Jitsi conference");
type = _WidgetType.WidgetType.JITSI;
name = "Jitsi";
data = jitsiData;
widgetUrl = _WidgetUtils.default.getLocalJitsiWrapperUrl();
}
return (0, _utils.success)(_WidgetUtils.default.setRoomWidget(cli, roomId, widgetId, type, widgetUrl, name, data));
} else {
return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|addwidget_no_permissions"));
}
},
category: _interface.CommandCategories.admin,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "verify",
args: "<user-id> <device-id> <device-signing-key>",
description: (0, _languageHandler._td)("slash_command|verify"),
runFn: function (cli, roomId, threadId, args) {
if (args) {
const matches = args.match(/^(\S+) +(\S+) +(\S+)$/);
if (matches) {
const userId = matches[1];
const deviceId = matches[2];
const fingerprint = matches[3];
return (0, _utils.success)((async () => {
const device = await (0, _deviceInfo.getDeviceCryptoInfo)(cli, userId, deviceId);
if (!device) {
throw new _languageHandler.UserFriendlyError("slash_command|verify_unknown_pair", {
userId,
deviceId,
cause: undefined
});
}
const deviceTrust = await cli.getCrypto()?.getDeviceVerificationStatus(userId, deviceId);
if (deviceTrust?.isVerified()) {
if (device.getFingerprint() === fingerprint) {
throw new _languageHandler.UserFriendlyError("slash_command|verify_nop");
} else {
throw new _languageHandler.UserFriendlyError("slash_command|verify_nop_warning_mismatch");
}
}
if (device.getFingerprint() !== fingerprint) {
const fprint = device.getFingerprint();
throw new _languageHandler.UserFriendlyError("slash_command|verify_mismatch", {
fprint,
userId,
deviceId,
fingerprint,
cause: undefined
});
}
await cli.setDeviceVerified(userId, deviceId, true);
// Tell the user we verified everything
_Modal.default.createDialog(_InfoDialog.default, {
title: (0, _languageHandler._t)("slash_command|verify_success_title"),
description: /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("p", null, (0, _languageHandler._t)("slash_command|verify_success_description", {
userId,
deviceId
})))
});
})());
}
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.advanced,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "discardsession",
description: (0, _languageHandler._td)("slash_command|discardsession"),
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId) {
try {
cli.forceDiscardSession(roomId);
} catch (e) {
return (0, _utils.reject)(e instanceof Error ? e.message : e);
}
return (0, _utils.success)();
},
category: _interface.CommandCategories.advanced,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "remakeolm",
description: (0, _languageHandler._td)("slash_command|remakeolm"),
isEnabled: cli => {
return _SettingsStore.default.getValue("developerMode") && !(0, _utils.isCurrentLocalRoom)(cli);
},
runFn: (cli, roomId) => {
try {
const room = cli.getRoom(roomId);
cli.forceDiscardSession(roomId);
return (0, _utils.success)(room?.getEncryptionTargetMembers().then(members => {
// noinspection JSIgnoredPromiseFromCall
cli.crypto?.ensureOlmSessionsForUsers(members.map(m => m.userId), true);
}));
} catch (e) {
return (0, _utils.reject)(e instanceof Error ? e.message : e);
}
},
category: _interface.CommandCategories.advanced,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "rainbow",
description: (0, _languageHandler._td)("slash_command|rainbow"),
args: "<message>",
runFn: function (cli, roomId, threadId, args) {
if (!args) return (0, _utils.reject)(this.getUsage());
return (0, _utils.successSync)(_matrix.ContentHelpers.makeHtmlMessage(args, (0, _colour.textToHtmlRainbow)(args)));
},
category: _interface.CommandCategories.messages
}), new _command.Command({
command: "rainbowme",
description: (0, _languageHandler._td)("slash_command|rainbowme"),
args: "<message>",
runFn: function (cli, roomId, threadId, args) {
if (!args) return (0, _utils.reject)(this.getUsage());
return (0, _utils.successSync)(_matrix.ContentHelpers.makeHtmlEmote(args, (0, _colour.textToHtmlRainbow)(args)));
},
category: _interface.CommandCategories.messages
}), new _command.Command({
command: "help",
description: (0, _languageHandler._td)("slash_command|help"),
runFn: function () {
_Modal.default.createDialog(_SlashCommandHelpDialog.default);
return (0, _utils.success)();
},
category: _interface.CommandCategories.advanced
}), new _command.Command({
command: "whois",
description: (0, _languageHandler._td)("slash_command|whois"),
args: "<user-id>",
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, userId) {
if (!userId || !userId.startsWith("@") || !userId.includes(":")) {
return (0, _utils.reject)(this.getUsage());
}
const member = cli.getRoom(roomId)?.getMember(userId);
_dispatcher.default.dispatch({
action: _actions.Action.ViewUser,
// XXX: We should be using a real member object and not assuming what the receiver wants.
member: member || {
userId
}
});
return (0, _utils.success)();
},
category: _interface.CommandCategories.advanced
}), new _command.Command({
command: "rageshake",
aliases: ["bugreport"],
description: (0, _languageHandler._td)("slash_command|rageshake"),
isEnabled: () => !!_SdkConfig.default.get().bug_report_endpoint_url,
args: "<description>",
runFn: function (cli, roomId, threadId, args) {
return (0, _utils.success)(_Modal.default.createDialog(_BugReportDialog.default, {
initialText: args
}).finished);
},
category: _interface.CommandCategories.advanced
}), new _command.Command({
command: "tovirtual",
description: (0, _languageHandler._td)("slash_command|tovirtual"),
category: _interface.CommandCategories.advanced,
isEnabled(cli) {
return !!_LegacyCallHandler.default.instance.getSupportsVirtualRooms() && !(0, _utils.isCurrentLocalRoom)(cli);
},
runFn: (cli, roomId) => {
return (0, _utils.success)((async () => {
const room = await _VoipUserMapper.default.sharedInstance().getVirtualRoomForRoom(roomId);
if (!room) throw new _languageHandler.UserFriendlyError("slash_command|tovirtual_not_found");
_dispatcher.default.dispatch({
action: _actions.Action.ViewRoom,
room_id: room.roomId,
metricsTrigger: "SlashCommand",
metricsViaKeyboard: true
});
})());
}
}), new _command.Command({
command: "query",
description: (0, _languageHandler._td)("slash_command|query"),
args: "<user-id>",
runFn: function (cli, roomId, threadId, userId) {
// easter-egg for now: look up phone numbers through the thirdparty API
// (very dumb phone number detection...)
const isPhoneNumber = userId && /^\+?[0123456789]+$/.test(userId);
if (!userId || (!userId.startsWith("@") || !userId.includes(":")) && !isPhoneNumber) {
return (0, _utils.reject)(this.getUsage());
}
return (0, _utils.success)((async () => {
if (isPhoneNumber) {
const results = await _LegacyCallHandler.default.instance.pstnLookup(userId);
if (!results || results.length === 0 || !results[0].userid) {
throw new _languageHandler.UserFriendlyError("slash_command|query_not_found_phone_number");
}
userId = results[0].userid;
}
const roomId = await (0, _createRoom.ensureDMExists)(cli, userId);
if (!roomId) throw new Error("Failed to ensure DM exists");
_dispatcher.default.dispatch({
action: _actions.Action.ViewRoom,
room_id: roomId,
metricsTrigger: "SlashCommand",
metricsViaKeyboard: true
});
})());
},
category: _interface.CommandCategories.actions
}), new _command.Command({
command: "msg",
description: (0, _languageHandler._td)("slash_command|msg"),
args: "<user-id> [<message>]",
runFn: function (cli, roomId, threadId, args) {
if (args) {
// matches the first whitespace delimited group and then the rest of the string
const matches = args.match(/^(\S+?)(?: +(.*))?$/s);
if (matches) {
const [userId, msg] = matches.slice(1);
if (userId && userId.startsWith("@") && userId.includes(":")) {
return (0, _utils.success)((async () => {
const roomId = await (0, _createRoom.ensureDMExists)(cli, userId);
if (!roomId) throw new Error("Failed to ensure DM exists");
_dispatcher.default.dispatch({
action: _actions.Action.ViewRoom,
room_id: roomId,
metricsTrigger: "SlashCommand",
metricsViaKeyboard: true
});
if (msg) {
cli.sendTextMessage(roomId, msg);
}
})());
}
}
}
return (0, _utils.reject)(this.getUsage());
},
category: _interface.CommandCategories.actions
}), new _command.Command({
command: "holdcall",
description: (0, _languageHandler._td)("slash_command|holdcall"),
category: _interface.CommandCategories.other,
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
const call = _LegacyCallHandler.default.instance.getCallForRoom(roomId);
if (!call) {
return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|no_active_call"));
}
call.setRemoteOnHold(true);
return (0, _utils.success)();
},
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "unholdcall",
description: (0, _languageHandler._td)("slash_command|unholdcall"),
category: _interface.CommandCategories.other,
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
const call = _LegacyCallHandler.default.instance.getCallForRoom(roomId);
if (!call) {
return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|no_active_call"));
}
call.setRemoteOnHold(false);
return (0, _utils.success)();
},
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "converttodm",
description: (0, _languageHandler._td)("slash_command|converttodm"),
category: _interface.CommandCategories.other,
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
const room = cli.getRoom(roomId);
if (!room) return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|could_not_find_room"));
return (0, _utils.success)((0, _Rooms.guessAndSetDMRoom)(room, true));
},
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}), new _command.Command({
command: "converttoroom",
description: (0, _languageHandler._td)("slash_command|converttoroom"),
category: _interface.CommandCategories.other,
isEnabled: cli => !(0, _utils.isCurrentLocalRoom)(cli),
runFn: function (cli, roomId, threadId, args) {
const room = cli.getRoom(roomId);
if (!room) return (0, _utils.reject)(new _languageHandler.UserFriendlyError("slash_command|could_not_find_room"));
return (0, _utils.success)((0, _Rooms.guessAndSetDMRoom)(room, false));
},
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
}),
// Command definitions for autocompletion ONLY:
// /me is special because its not handled by SlashCommands.js and is instead done inside the Composer classes
new _command.Command({
command: "me",
args: "<message>",
description: (0, _languageHandler._td)("slash_command|me"),
category: _interface.CommandCategories.messages,
hideCompletionAfterSpace: true
}), ..._effects.CHAT_EFFECTS.map(effect => {
return new _command.Command({
command: effect.command,
description: effect.description(),
args: "<message>",
runFn: function (cli, roomId, threadId, args) {
let content;
if (!args) {
content = _matrix.ContentHelpers.makeEmoteMessage(effect.fallbackMessage());
} else {
content = {
msgtype: effect.msgType,
body: args
};
}
_dispatcher.default.dispatch({
action: `effects.${effect.command}`
});
return (0, _utils.successSync)(content);
},
category: _interface.CommandCategories.effects,
renderingTypes: [_RoomContext.TimelineRenderingType.Room]
});
})];
// build a map from names and aliases to the Command objects.
const CommandMap = exports.CommandMap = new Map();
Commands.forEach(cmd => {
CommandMap.set(cmd.command, cmd);
cmd.aliases.forEach(alias => {
CommandMap.set(alias, cmd);
});
});
function parseCommandString(input) {
// trim any trailing whitespace, as it can confuse the parser for IRC-style commands
input = input.trimEnd();
if (input[0] !== "/") return {}; // not a command
const bits = input.match(/^(\S+?)(?:[ \n]+((.|\n)*))?$/);
let cmd;
let args;
if (bits) {
cmd = bits[1].substring(1).toLowerCase();
args = bits[2];
} else {
cmd = input;
}
return {
cmd,
args
};
}
/**
* Process the given text for /commands and returns a parsed command that can be used for running the operation.
* @param {string} input The raw text input by the user.
* @return {ICmd} The parsed command object.
* Returns an empty object if the input didn't match a command.
*/
function getCommand(input) {
const {
cmd,
args
} = parseCommandString(input);
if (cmd && CommandMap.has(cmd) && CommandMap.get(cmd).isEnabled(_MatrixClientPeg.MatrixClientPeg.get())) {
return {
cmd: CommandMap.get(cmd),
args
};
}
return {};
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwicmVxdWlyZSIsIl9tYXRyaXgiLCJfbG9nZ2VyIiwiX3R5cGVzIiwiX2Rpc3BhdGNoZXIiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX2xhbmd1YWdlSGFuZGxlciIsIl9Nb2RhbCIsIl9NdWx0aUludml0ZXIiLCJfSHRtbFV0aWxzIiwiX1F1ZXN0aW9uRGlhbG9nIiwiX1dpZGdldFV0aWxzIiwiX2NvbG91ciIsIl9Vc2VyQWRkcmVzcyIsIl9VcmxVdGlscyIsIl9JZGVudGl0eVNlcnZlclV0aWxzIiwiX1dpZGdldFR5cGUiLCJfSml0c2kiLCJfQnVnUmVwb3J0RGlhbG9nIiwiX2NyZWF0ZVJvb20iLCJfYWN0aW9ucyIsIl9TZGtDb25maWciLCJfU2V0dGluZ3NTdG9yZSIsIl9VSUZlYXR1cmUiLCJfZWZmZWN0cyIsIl9MZWdhY3lDYWxsSGFuZGxlciIsIl9Sb29tcyIsIl9Sb29tVXBncmFkZSIsIl9EZXZ0b29sc0RpYWxvZyIsIl9Sb29tVXBncmFkZVdhcm5pbmdEaWFsb2ciLCJfSW5mb0RpYWxvZyIsIl9TbGFzaENvbW1hbmRIZWxwRGlhbG9nIiwiX1VJQ29tcG9uZW50cyIsIl9Sb29tQ29udGV4dCIsIl9Wb2lwVXNlck1hcHBlciIsIl9zZXJpYWxpemUiLCJfbGVhdmVCZWhhdmlvdXIiLCJfTWF0cml4Q2xpZW50UGVnIiwiX2RldmljZUluZm8iLCJfdXRpbHMiLCJfb3AiLCJfaW50ZXJmYWNlIiwiX2NvbW1hbmQiLCJfam9pbiIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIm93bktleXMiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsIkNvbW1hbmRzIiwiZXhwb3J0cyIsIkNvbW1hbmQiLCJjb21tYW5kIiwiYXJncyIsImRlc2NyaXB0aW9uIiwiX3RkIiwicnVuRm4iLCJjbGkiLCJyb29tSWQiLCJ0aHJlYWRJZCIsIm1lc3NhZ2UiLCJzdWNjZXNzU3luYyIsIkNvbnRlbnRIZWxwZXJzIiwibWFrZUh0bWxNZXNzYWdlIiwiY2F0ZWdvcnkiLCJDb21tYW5kQ2F0ZWdvcmllcyIsIm1lc3NhZ2VzIiwibWFrZVRleHRNZXNzYWdlIiwiaXNFbmFibGVkIiwiaXNDdXJyZW50TG9jYWxSb29tIiwiU2V0dGluZ3NTdG9yZSIsImdldFZhbHVlIiwicm9vbSIsImdldFJvb20iLCJjdXJyZW50U3RhdGUiLCJtYXlDbGllbnRTZW5kU3RhdGVFdmVudCIsInJlamVjdCIsIlVzZXJGcmllbmRseUVycm9yIiwiZmluaXNoZWQiLCJNb2RhbCIsImNyZWF0ZURpYWxvZyIsIlJvb21VcGdyYWRlV2FybmluZ0RpYWxvZyIsInRhcmdldFZlcnNpb24iLCJ1bmRlZmluZWQiLCJzdWNjZXNzIiwidGhlbiIsInJlc3AiLCJjb250aW51ZSIsInVwZ3JhZGVSb29tIiwiaW52aXRlIiwiZ2V0VXNhZ2UiLCJhZG1pbiIsInJlbmRlcmluZ1R5cGVzIiwiVGltZWxpbmVSZW5kZXJpbmdUeXBlIiwiUm9vbSIsInVuaXhUaW1lc3RhbXAiLCJEYXRlIiwicGFyc2UiLCJpbnB1dERhdGUiLCJjYXVzZSIsImV2ZW50X2lkIiwiZXZlbnRJZCIsIm9yaWdpbl9zZXJ2ZXJfdHMiLCJvcmlnaW5TZXJ2ZXJUcyIsInRpbWVzdGFtcFRvRXZlbnQiLCJEaXJlY3Rpb24iLCJGb3J3YXJkIiwibG9nZ2VyIiwibG9nIiwiZGlzIiwiZGlzcGF0Y2giLCJhY3Rpb24iLCJBY3Rpb24iLCJWaWV3Um9vbSIsImhpZ2hsaWdodGVkIiwicm9vbV9pZCIsIm1ldHJpY3NUcmlnZ2VyIiwibWV0cmljc1ZpYUtleWJvYXJkIiwiYWN0aW9ucyIsInNldERpc3BsYXlOYW1lIiwiYWxpYXNlcyIsImV2IiwiZ2V0U3RhdGVFdmVudHMiLCJFdmVudFR5cGUiLCJSb29tTWVtYmVyIiwiZ2V0U2FmZVVzZXJJZCIsImNvbnRlbnQiLCJnZXRDb250ZW50IiwibWVtYmVyc2hpcCIsIktub3duTWVtYmVyc2hpcCIsIkpvaW4iLCJkaXNwbGF5bmFtZSIsInNlbmRTdGF0ZUV2ZW50IiwicHJvbWlzZSIsIlByb21pc2UiLCJyZXNvbHZlIiwic2luZ2xlTXhjVXBsb2FkIiwidXJsIiwiUm9vbUF2YXRhciIsInVzZXJJZCIsImF2YXRhcl91cmwiLCJzZXRBdmF0YXJVcmwiLCJodG1sIiwiaHRtbFNlcmlhbGl6ZUZyb21NZElmTmVlZGVkIiwiZm9yY2VIVE1MIiwic2V0Um9vbVRvcGljIiwidG9waWMiLCJwYXJzZVRvcGljQ29udGVudCIsInRleHQiLCJfdCIsImJvZHkiLCJ0b3BpY1RvSHRtbCIsIkluZm9EaWFsb2ciLCJ0aXRsZSIsIm5hbWUiLCJjcmVhdGVFbGVtZW50IiwiTGlua2lmeSIsImhhc0Nsb3NlQnV0dG9uIiwiY2xhc3NOYW1lIiwic2V0Um9vbU5hbWUiLCJhbmFseXRpY3NOYW1lIiwic2hvdWxkU2hvd0NvbXBvbmVudCIsIlVJQ29tcG9uZW50IiwiSW52aXRlVXNlcnMiLCJhZGRyZXNzIiwicmVhc29uIiwic3BsaXQiLCJwcm9tIiwiZ2V0QWRkcmVzc1R5cGUiLCJBZGRyZXNzVHlwZSIsIkVtYWlsIiwiZ2V0SWRlbnRpdHlTZXJ2ZXJVcmwiLCJkZWZhdWx0SWRlbnRpdHlTZXJ2ZXJVcmwiLCJnZXREZWZhdWx0SWRlbnRpdHlTZXJ2ZXJVcmwiLCJRdWVzdGlvbkRpYWxvZyIsImRlZmF1bHRJZGVudGl0eVNlcnZlck5hbWUiLCJhYmJyZXZpYXRlVXJsIiwiYnV0dG9uIiwidXNlRGVmYXVsdCIsInNldFRvRGVmYXVsdElkZW50aXR5U2VydmVyIiwiaW52aXRlciIsIk11bHRpSW52aXRlciIsImdldENvbXBsZXRpb25TdGF0ZSIsImVycm9yU3RyaW5nRnJvbUludml0ZXJVdGlsaXR5IiwiZ2V0RXJyb3JUZXh0IiwiRXJyb3IiLCJ1c2VyIiwiZ290byIsImpvaW4iLCJ0YXJnZXRSb29tSWQiLCJtYXRjaGVzIiwibWF0Y2giLCJyb29tQWxpYXMiLCJpbmNsdWRlcyIsImdldERvbWFpbiIsInJvb21zIiwiZ2V0Um9vbXMiLCJmaW5kIiwiZ2V0Q2Fub25pY2FsQWxpYXMiLCJnZXRBbHRBbGlhc2VzIiwibGVhdmVSb29tQmVoYXZpb3VyIiwia2ljayIsImJhbiIsInVuYmFuIiwiaWdub3JlZFVzZXJzIiwiZ2V0SWdub3JlZFVzZXJzIiwic2V0SWdub3JlZFVzZXJzIiwiaW5kZXgiLCJpbmRleE9mIiwic3BsaWNlIiwib3AiLCJkZW9wIiwidGhyZWFkUm9vdElkIiwiRGV2dG9vbHNEaWFsb2ciLCJhZHZhbmNlZCIsIlVJRmVhdHVyZSIsIldpZGdldHMiLCJBZGRJbnRlZ3JhdGlvbnMiLCJ3aWRnZXRVcmwiLCJ0b0xvd2VyQ2FzZSIsInN0YXJ0c1dpdGgiLCJlbWJlZCIsIkRPTVBhcnNlciIsInBhcnNlRnJvbVN0cmluZyIsImNoaWxkTm9kZXMiLCJpZnJhbWUiLCJmaXJzdEVsZW1lbnRDaGlsZCIsInRhZ05hbWUiLCJoYXNBdHRyaWJ1dGUiLCJnZXRBdHRyaWJ1dGUiLCJXaWRnZXRVdGlscyIsImNhblVzZXJNb2RpZnlXaWRnZXRzIiwiZ2V0VXNlcklkIiwibm93TXMiLCJnZXRUaW1lIiwid2lkZ2V0SWQiLCJlbmNvZGVVUklDb21wb25lbnQiLCJ0eXBlIiwiV2lkZ2V0VHlwZSIsIkNVU1RPTSIsImRhdGEiLCJqaXRzaURhdGEiLCJKaXRzaSIsImdldEluc3RhbmNlIiwicGFyc2VQcmVmZXJyZWRDb25mZXJlbmNlVXJsIiwiSklUU0kiLCJnZXRMb2NhbEppdHNpV3JhcHBlclVybCIsInNldFJvb21XaWRnZXQiLCJkZXZpY2VJZCIsImZpbmdlcnByaW50IiwiZGV2aWNlIiwiZ2V0RGV2aWNlQ3J5cHRvSW5mbyIsImRldmljZVRydXN0IiwiZ2V0Q3J5cHRvIiwiZ2V0RGV2aWNlVmVyaWZpY2F0aW9uU3RhdHVzIiwiaXNWZXJpZmllZCIsImdldEZpbmdlcnByaW50IiwiZnByaW50Iiwic2V0RGV2aWNlVmVyaWZpZWQiLCJmb3JjZURpc2NhcmRTZXNzaW9uIiwiZ2V0RW5jcnlwdGlvblRhcmdldE1lbWJlcnMiLCJtZW1iZXJzIiwiY3J5cHRvIiwiZW5zdXJlT2xtU2Vzc2lvbnNGb3JVc2VycyIsIm1hcCIsIm0iLCJ0ZXh0VG9IdG1sUmFpbmJvdyIsIm1ha2VIdG1sRW1vdGUiLCJTbGFzaENvbW1hbmRIZWxwRGlhbG9nIiwibWVtYmVyIiwiZ2V0TWVtYmVyIiwiVmlld1VzZXIiLCJTZGtDb25maWciLCJidWdfcmVwb3J0X2VuZHBvaW50X3VybCIsIkJ1Z1JlcG9ydERpYWxvZyIsImluaXRpYWxUZXh0IiwiTGVnYWN5Q2FsbEhhbmRsZXIiLCJpbnN0YW5jZSIsImdldFN1cHBvcnRzVmlydHVhbFJvb21zIiwiVm9pcFVzZXJNYXBwZXIiLCJzaGFyZWRJbnN0YW5jZSIsImdldFZpcnR1YWxSb29tRm9yUm9vbSIsImlzUGhvbmVOdW1iZXIiLCJ0ZXN0IiwicmVzdWx0cyIsInBzdG5Mb29rdXAiLCJ1c2VyaWQiLCJlbnN1cmVETUV4aXN0cyIsIm1zZyIsInNsaWNlIiwic2VuZFRleHRNZXNzYWdlIiwib3RoZXIiLCJnZXRDYWxsRm9yUm9vbSIsInNldFJlbW90ZU9uSG9sZCIsImd1ZXNzQW5kU2V0RE1Sb29tIiwiaGlkZUNvbXBsZXRpb25BZnRlclNwYWNlIiwiQ0hBVF9FRkZFQ1RTIiwiZWZmZWN0IiwibWFrZUVtb3RlTWVzc2FnZSIsImZhbGxiYWNrTWVzc2FnZSIsIm1zZ3R5cGUiLCJtc2dUeXBlIiwiZWZmZWN0cyIsIkNvbW1hbmRNYXAiLCJNYXAiLCJjbWQiLCJhbGlhcyIsInBhcnNlQ29tbWFuZFN0cmluZyIsImlucHV0IiwidHJpbUVuZCIsImJpdHMiLCJzdWJzdHJpbmciLCJnZXRDb21tYW5kIiwiTWF0cml4Q2xpZW50UGVnIl0sInNvdXJjZXMiOlsiLi4vc3JjL1NsYXNoQ29tbWFuZHMudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDIwIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5Db3B5cmlnaHQgMjAxOSBNaWNoYWVsIFRlbGF0eW5za2kgPDd0M2NoZ3V5QGdtYWlsLmNvbT5cbkNvcHlyaWdodCAyMDE4IE5ldyBWZWN0b3IgTHRkXG5Db3B5cmlnaHQgMjAxNSwgMjAxNiBPcGVuTWFya2V0IEx0ZFxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IENvbnRlbnRIZWxwZXJzLCBEaXJlY3Rpb24sIEV2ZW50VHlwZSwgSUNvbnRlbnQsIE1Sb29tVG9waWNFdmVudENvbnRlbnQsIFVzZXIgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbG9nZ2VyXCI7XG5pbXBvcnQgeyBLbm93bk1lbWJlcnNoaXAsIFJvb21NZW1iZXJFdmVudENvbnRlbnQgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvdHlwZXNcIjtcblxuaW1wb3J0IGRpcyBmcm9tIFwiLi9kaXNwYXRjaGVyL2Rpc3BhdGNoZXJcIjtcbmltcG9ydCB7IF90LCBfdGQsIFVzZXJGcmllbmRseUVycm9yIH0gZnJvbSBcIi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgTW9kYWwgZnJvbSBcIi4vTW9kYWxcIjtcbmltcG9ydCBNdWx0aUludml0ZXIgZnJvbSBcIi4vdXRpbHMvTXVsdGlJbnZpdGVyXCI7XG5pbXBvcnQgeyBMaW5raWZ5LCB0b3BpY1RvSHRtbCB9IGZyb20gXCIuL0h0bWxVdGlsc1wiO1xuaW1wb3J0IFF1ZXN0aW9uRGlhbG9nIGZyb20gXCIuL2NvbXBvbmVudHMvdmlld3MvZGlhbG9ncy9RdWVzdGlvbkRpYWxvZ1wiO1xuaW1wb3J0IFdpZGdldFV0aWxzIGZyb20gXCIuL3V0aWxzL1dpZGdldFV0aWxzXCI7XG5pbXBvcnQgeyB0ZXh0VG9IdG1sUmFpbmJvdyB9IGZyb20gXCIuL3V0aWxzL2NvbG91clwiO1xuaW1wb3J0IHsgQWRkcmVzc1R5cGUsIGdldEFkZHJlc3NUeXBlIH0gZnJvbSBcIi4vVXNlckFkZHJlc3NcIjtcbmltcG9ydCB7IGFiYnJldmlhdGVVcmwgfSBmcm9tIFwiLi91dGlscy9VcmxVdGlsc1wiO1xuaW1wb3J0IHsgZ2V0RGVmYXVsdElkZW50aXR5U2VydmVyVXJsLCBzZXRUb0RlZmF1bHRJZGVudGl0eVNlcnZlciB9IGZyb20gXCIuL3V0aWxzL0lkZW50aXR5U2VydmVyVXRpbHNcIjtcbmltcG9ydCB7IFdpZGdldFR5cGUgfSBmcm9tIFwiLi93aWRnZXRzL1dpZGdldFR5cGVcIjtcbmltcG9ydCB7IEppdHNpIH0gZnJvbSBcIi4vd2lkZ2V0cy9KaXRzaVwiO1xuaW1wb3J0IEJ1Z1JlcG9ydERpYWxvZyBmcm9tIFwiLi9jb21wb25lbnRzL3ZpZXdzL2RpYWxvZ3MvQnVnUmVwb3J0RGlhbG9nXCI7XG5pbXBvcnQgeyBlbnN1cmVETUV4aXN0cyB9IGZyb20gXCIuL2NyZWF0ZVJvb21cIjtcbmltcG9ydCB7IFZpZXdVc2VyUGF5bG9hZCB9IGZyb20gXCIuL2Rpc3BhdGNoZXIvcGF5bG9hZHMvVmlld1VzZXJQYXlsb2FkXCI7XG5pbXBvcnQgeyBBY3Rpb24gfSBmcm9tIFwiLi9kaXNwYXRjaGVyL2FjdGlvbnNcIjtcbmltcG9ydCBTZGtDb25maWcgZnJvbSBcIi4vU2RrQ29uZmlnXCI7XG5pbXBvcnQgU2V0dGluZ3NTdG9yZSBmcm9tIFwiLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgeyBVSUNvbXBvbmVudCwgVUlGZWF0dXJlIH0gZnJvbSBcIi4vc2V0dGluZ3MvVUlGZWF0dXJlXCI7XG5pbXBvcnQgeyBDSEFUX0VGRkVDVFMgfSBmcm9tIFwiLi9lZmZlY3RzXCI7XG5pbXBvcnQgTGVnYWN5Q2FsbEhhbmRsZXIgZnJvbSBcIi4vTGVnYWN5Q2FsbEhhbmRsZXJcIjtcbmltcG9ydCB7IGd1ZXNzQW5kU2V0RE1Sb29tIH0gZnJvbSBcIi4vUm9vbXNcIjtcbmltcG9ydCB7IHVwZ3JhZGVSb29tIH0gZnJvbSBcIi4vdXRpbHMvUm9vbVVwZ3JhZGVcIjtcbmltcG9ydCBEZXZ0b29sc0RpYWxvZyBmcm9tIFwiLi9jb21wb25lbnRzL3ZpZXdzL2RpYWxvZ3MvRGV2dG9vbHNEaWFsb2dcIjtcbmltcG9ydCBSb29tVXBn