UNPKG

matrix-react-sdk

Version:
963 lines (955 loc) 155 kB
"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