UNPKG

matrix-react-sdk

Version:
626 lines (620 loc) 109 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.WYSIWYG_EDITOR_STATE_STORAGE_PREFIX = exports.MessageComposer = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _matrix = require("matrix-js-sdk/src/matrix"); var _compoundWeb = require("@vector-im/compound-web"); var _logger = require("matrix-js-sdk/src/logger"); var _languageHandler = require("../../../languageHandler"); var _MatrixClientPeg = require("../../../MatrixClientPeg"); var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher")); var _Stickerpicker = _interopRequireDefault(require("./Stickerpicker")); var _Permalinks = require("../../../utils/permalinks/Permalinks"); var _E2EIcon = _interopRequireDefault(require("./E2EIcon")); var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore")); var _ContextMenu = require("../../structures/ContextMenu"); var _ReplyPreview = _interopRequireDefault(require("./ReplyPreview")); var _AsyncStore = require("../../../stores/AsyncStore"); var _VoiceRecordComposerTile = _interopRequireDefault(require("./VoiceRecordComposerTile")); var _VoiceRecordingStore = require("../../../stores/VoiceRecordingStore"); var _VoiceRecording = require("../../../audio/VoiceRecording"); var _SendMessageComposer = _interopRequireDefault(require("./SendMessageComposer")); var _actions = require("../../../dispatcher/actions"); var _UIStore = _interopRequireWildcard(require("../../../stores/UIStore")); var _RoomContext = _interopRequireDefault(require("../../../contexts/RoomContext")); var _MessageComposerButtons = _interopRequireDefault(require("./MessageComposerButtons")); var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton")); var _isLocalRoom = require("../../../utils/localRoom/isLocalRoom"); var _Settings = require("../../../settings/Settings"); var _wysiwyg_composer = require("./wysiwyg_composer/"); var _MatrixClientContext = require("../../../contexts/MatrixClientContext"); var _setUpVoiceBroadcastPreRecording = require("../../../voice-broadcast/utils/setUpVoiceBroadcastPreRecording"); var _SDKContext = require("../../../contexts/SDKContext"); var _voiceBroadcast = require("../../../voice-broadcast"); var _CantStartVoiceMessageBroadcastDialog = require("../dialogs/CantStartVoiceMessageBroadcastDialog"); var _UIFeature = require("../../../settings/UIFeature"); var _DateUtils = require("../../../DateUtils"); 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 2015-2022 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ // The prefix used when persisting editor drafts to localstorage. const WYSIWYG_EDITOR_STATE_STORAGE_PREFIX = exports.WYSIWYG_EDITOR_STATE_STORAGE_PREFIX = "mx_wysiwyg_state_"; let instanceCount = 0; function SendButton(props) { return /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { className: "mx_MessageComposer_sendMessage", onClick: props.onClick, title: props.title ?? (0, _languageHandler._t)("composer|send_button_title"), "data-testid": "sendmessagebtn" }); } class MessageComposer extends _react.default.Component { constructor(props, context) { super(props, context); (0, _defineProperty2.default)(this, "dispatcherRef", void 0); (0, _defineProperty2.default)(this, "messageComposerInput", /*#__PURE__*/(0, _react.createRef)()); (0, _defineProperty2.default)(this, "voiceRecordingButton", /*#__PURE__*/(0, _react.createRef)()); (0, _defineProperty2.default)(this, "ref", /*#__PURE__*/(0, _react.createRef)()); (0, _defineProperty2.default)(this, "instanceId", void 0); (0, _defineProperty2.default)(this, "_voiceRecording", void 0); (0, _defineProperty2.default)(this, "saveWysiwygEditorState", () => { if (this.shouldSaveWysiwygEditorState()) { const { isRichTextEnabled, composerContent } = this.state; const replyEventId = this.props.replyToEvent ? this.props.replyToEvent.getId() : undefined; const item = { content: composerContent, isRichText: isRichTextEnabled, replyEventId: replyEventId }; localStorage.setItem(this.editorStateKey, JSON.stringify(item)); } else { this.clearStoredEditorState(); } }); // should save state when wysiwyg is enabled and has contents or reply is open (0, _defineProperty2.default)(this, "shouldSaveWysiwygEditorState", () => { const { isWysiwygLabEnabled, isComposerEmpty } = this.state; return isWysiwygLabEnabled && (!isComposerEmpty || !!this.props.replyToEvent); }); (0, _defineProperty2.default)(this, "onResize", (type, entry) => { if (type === _UIStore.UI_EVENTS.Resize) { const { narrow } = this.context; this.setState({ isMenuOpen: !narrow ? false : this.state.isMenuOpen, isStickerPickerOpen: false }); } }); (0, _defineProperty2.default)(this, "onAction", payload => { switch (payload.action) { case "reply_to_event": if (payload.context === this.context.timelineRenderingType) { // add a timeout for the reply preview to be rendered, so // that the ScrollPanel listening to the resizeNotifier can // correctly measure it's new height and scroll down to keep // at the bottom if it already is window.setTimeout(() => { this.props.resizeNotifier.notifyTimelineHeightChanged(); }, 100); } break; case _actions.Action.SettingUpdated: { const settingUpdatedPayload = payload; switch (settingUpdatedPayload.settingName) { case "MessageComposerInput.showStickersButton": { const showStickersButton = _SettingsStore.default.getValue("MessageComposerInput.showStickersButton"); if (this.state.showStickersButton !== showStickersButton) { this.setState({ showStickersButton }); } break; } case "MessageComposerInput.showPollsButton": { const showPollsButton = _SettingsStore.default.getValue("MessageComposerInput.showPollsButton"); if (this.state.showPollsButton !== showPollsButton) { this.setState({ showPollsButton }); } break; } case _Settings.Features.VoiceBroadcast: { if (this.state.showVoiceBroadcastButton !== settingUpdatedPayload.newValue) { this.setState({ showVoiceBroadcastButton: !!settingUpdatedPayload.newValue }); } break; } case "feature_wysiwyg_composer": { if (this.state.isWysiwygLabEnabled !== settingUpdatedPayload.newValue) { this.setState({ isWysiwygLabEnabled: Boolean(settingUpdatedPayload.newValue) }); } break; } } } } }); (0, _defineProperty2.default)(this, "onTombstoneClick", ev => { ev.preventDefault(); const replacementRoomId = this.context.tombstone?.getContent()["replacement_room"]; const replacementRoom = _MatrixClientPeg.MatrixClientPeg.safeGet().getRoom(replacementRoomId); let createEventId; if (replacementRoom) { const createEvent = replacementRoom.currentState.getStateEvents(_matrix.EventType.RoomCreate, ""); if (createEvent?.getId()) createEventId = createEvent.getId(); } const sender = this.context.tombstone?.getSender(); const viaServers = sender ? [sender.split(":").slice(1).join(":")] : undefined; _dispatcher.default.dispatch({ action: _actions.Action.ViewRoom, highlighted: true, event_id: createEventId, room_id: replacementRoomId, auto_join: true, // Try to join via the server that sent the event. This converts @something:example.org // into a server domain by splitting on colons and ignoring the first entry ("@something"). via_servers: viaServers, metricsTrigger: "Tombstone", metricsViaKeyboard: ev.type !== "click" }); }); (0, _defineProperty2.default)(this, "renderPlaceholderText", () => { if (this.props.replyToEvent) { const replyingToThread = this.props.relation?.rel_type === _matrix.THREAD_RELATION_TYPE.name; if (replyingToThread && this.props.e2eStatus) { return (0, _languageHandler._t)("composer|placeholder_thread_encrypted"); } else if (replyingToThread) { return (0, _languageHandler._t)("composer|placeholder_thread"); } else if (this.props.e2eStatus) { return (0, _languageHandler._t)("composer|placeholder_reply_encrypted"); } else { return (0, _languageHandler._t)("composer|placeholder_reply"); } } else { if (this.props.e2eStatus) { return (0, _languageHandler._t)("composer|placeholder_encrypted"); } else { return (0, _languageHandler._t)("composer|placeholder"); } } }); (0, _defineProperty2.default)(this, "addEmoji", emoji => { _dispatcher.default.dispatch({ action: _actions.Action.ComposerInsert, text: emoji, timelineRenderingType: this.context.timelineRenderingType }); return true; }); (0, _defineProperty2.default)(this, "sendMessage", async () => { if (this.state.haveRecording && this.voiceRecordingButton.current) { // There shouldn't be any text message to send when a voice recording is active, so // just send out the voice recording. await this.voiceRecordingButton.current?.send(); return; } this.messageComposerInput.current?.sendMessage(); if (this.state.isWysiwygLabEnabled) { const { permalinkCreator, relation, replyToEvent } = this.props; const composerContent = this.state.composerContent; this.setState({ composerContent: "", initialComposerContent: "" }); _dispatcher.default.dispatch({ action: _actions.Action.ClearAndFocusSendMessageComposer, timelineRenderingType: this.context.timelineRenderingType }); await (0, _wysiwyg_composer.sendMessage)(composerContent, this.state.isRichTextEnabled, { mxClient: this.props.mxClient, roomContext: this.context, permalinkCreator, relation, replyToEvent }); } }); (0, _defineProperty2.default)(this, "onChange", model => { this.setState({ isComposerEmpty: model.isEmpty }); }); (0, _defineProperty2.default)(this, "onWysiwygChange", content => { this.setState({ composerContent: content, isComposerEmpty: content?.length === 0 }); }); (0, _defineProperty2.default)(this, "onRichTextToggle", async () => { const { richToPlain, plainToRich } = await (0, _wysiwyg_composer.getConversionFunctions)(); const { isRichTextEnabled, composerContent } = this.state; const convertedContent = isRichTextEnabled ? await richToPlain(composerContent, false) : await plainToRich(composerContent, false); this.setState({ isRichTextEnabled: !isRichTextEnabled, composerContent: convertedContent, initialComposerContent: convertedContent }); }); (0, _defineProperty2.default)(this, "onVoiceStoreUpdate", () => { this.updateRecordingState(); }); (0, _defineProperty2.default)(this, "onRecordingStarted", () => { // update the recording instance, just in case const voiceRecordingId = _VoiceRecordingStore.VoiceRecordingStore.getVoiceRecordingId(this.props.room, this.props.relation); this.voiceRecording = _VoiceRecordingStore.VoiceRecordingStore.instance.getActiveRecording(voiceRecordingId); this.setState({ haveRecording: !!this.voiceRecording }); }); (0, _defineProperty2.default)(this, "onRecordingEndingSoon", ({ secondsLeft }) => { this.setState({ recordingTimeLeftSeconds: secondsLeft }); window.setTimeout(() => this.setState({ recordingTimeLeftSeconds: undefined }), 3000); }); (0, _defineProperty2.default)(this, "setStickerPickerOpen", isStickerPickerOpen => { this.setState({ isStickerPickerOpen, isMenuOpen: false }); }); (0, _defineProperty2.default)(this, "toggleStickerPickerOpen", () => { this.setStickerPickerOpen(!this.state.isStickerPickerOpen); }); (0, _defineProperty2.default)(this, "toggleButtonMenu", () => { this.setState({ isMenuOpen: !this.state.isMenuOpen }); }); (0, _defineProperty2.default)(this, "onRecordStartEndClick", () => { const currentBroadcastRecording = _SDKContext.SdkContextClass.instance.voiceBroadcastRecordingsStore.getCurrent(); if (currentBroadcastRecording && currentBroadcastRecording.getState() !== _voiceBroadcast.VoiceBroadcastInfoState.Stopped) { (0, _CantStartVoiceMessageBroadcastDialog.createCantStartVoiceMessageBroadcastDialog)(); } else { this.voiceRecordingButton.current?.onRecordStartEndClick(); } if (this.context.narrow) { this.toggleButtonMenu(); } }); this.context = context; // otherwise React will only set it prior to render due to type def above _VoiceRecordingStore.VoiceRecordingStore.instance.on(_AsyncStore.UPDATE_EVENT, this.onVoiceStoreUpdate); window.addEventListener("beforeunload", this.saveWysiwygEditorState); const _isWysiwygLabEnabled = _SettingsStore.default.getValue("feature_wysiwyg_composer"); let _isRichTextEnabled = true; let initialComposerContent = ""; if (_isWysiwygLabEnabled) { const wysiwygState = this.restoreWysiwygEditorState(); if (wysiwygState) { _isRichTextEnabled = wysiwygState.isRichText; initialComposerContent = wysiwygState.content; if (wysiwygState.replyEventId) { _dispatcher.default.dispatch({ action: "reply_to_event", event: this.props.room.findEventById(wysiwygState.replyEventId), context: this.context.timelineRenderingType }); } } } this.state = { isComposerEmpty: initialComposerContent?.length === 0, composerContent: initialComposerContent, haveRecording: false, recordingTimeLeftSeconds: undefined, // when set to a number, shows a toast isMenuOpen: false, isStickerPickerOpen: false, showStickersButton: _SettingsStore.default.getValue("MessageComposerInput.showStickersButton"), showPollsButton: _SettingsStore.default.getValue("MessageComposerInput.showPollsButton"), showVoiceBroadcastButton: _SettingsStore.default.getValue(_Settings.Features.VoiceBroadcast), isWysiwygLabEnabled: _isWysiwygLabEnabled, isRichTextEnabled: _isRichTextEnabled, initialComposerContent: initialComposerContent }; this.instanceId = instanceCount++; _SettingsStore.default.monitorSetting("MessageComposerInput.showStickersButton", null); _SettingsStore.default.monitorSetting("MessageComposerInput.showPollsButton", null); _SettingsStore.default.monitorSetting(_Settings.Features.VoiceBroadcast, null); _SettingsStore.default.monitorSetting("feature_wysiwyg_composer", null); } get editorStateKey() { let key = WYSIWYG_EDITOR_STATE_STORAGE_PREFIX + this.props.room.roomId; if (this.props.relation?.rel_type === _matrix.THREAD_RELATION_TYPE.name) { key += `_${this.props.relation.event_id}`; } return key; } restoreWysiwygEditorState() { const json = localStorage.getItem(this.editorStateKey); if (json) { try { const state = JSON.parse(json); return state; } catch (e) { _logger.logger.error(e); } } return undefined; } clearStoredEditorState() { localStorage.removeItem(this.editorStateKey); } get voiceRecording() { return this._voiceRecording; } set voiceRecording(rec) { if (this._voiceRecording) { this._voiceRecording.off(_VoiceRecording.RecordingState.Started, this.onRecordingStarted); this._voiceRecording.off(_VoiceRecording.RecordingState.EndingSoon, this.onRecordingEndingSoon); } this._voiceRecording = rec; if (rec) { // Delay saying we have a recording until it is started, as we might not yet // have A/V permissions rec.on(_VoiceRecording.RecordingState.Started, this.onRecordingStarted); // We show a little heads up that the recording is about to automatically end soon. The 3s // display time is completely arbitrary. rec.on(_VoiceRecording.RecordingState.EndingSoon, this.onRecordingEndingSoon); } } componentDidMount() { this.dispatcherRef = _dispatcher.default.register(this.onAction); this.waitForOwnMember(); _UIStore.default.instance.trackElementDimensions(`MessageComposer${this.instanceId}`, this.ref.current); _UIStore.default.instance.on(`MessageComposer${this.instanceId}`, this.onResize); this.updateRecordingState(); // grab any cached recordings } waitForOwnMember() { // If we have the member already, do that const me = this.props.room.getMember(_MatrixClientPeg.MatrixClientPeg.safeGet().getUserId()); if (me) { this.setState({ me }); return; } // Otherwise, wait for member loading to finish and then update the member for the avatar. // The members should already be loading, and loadMembersIfNeeded // will return the promise for the existing operation this.props.room.loadMembersIfNeeded().then(() => { const me = this.props.room.getMember(_MatrixClientPeg.MatrixClientPeg.safeGet().getSafeUserId()) ?? undefined; this.setState({ me }); }); } componentWillUnmount() { _VoiceRecordingStore.VoiceRecordingStore.instance.off(_AsyncStore.UPDATE_EVENT, this.onVoiceStoreUpdate); if (this.dispatcherRef) _dispatcher.default.unregister(this.dispatcherRef); _UIStore.default.instance.stopTrackingElementDimensions(`MessageComposer${this.instanceId}`); _UIStore.default.instance.removeListener(`MessageComposer${this.instanceId}`, this.onResize); window.removeEventListener("beforeunload", this.saveWysiwygEditorState); this.saveWysiwygEditorState(); // clean up our listeners by setting our cached recording to falsy (see internal setter) this.voiceRecording = null; } updateRecordingState() { const voiceRecordingId = _VoiceRecordingStore.VoiceRecordingStore.getVoiceRecordingId(this.props.room, this.props.relation); this.voiceRecording = _VoiceRecordingStore.VoiceRecordingStore.instance.getActiveRecording(voiceRecordingId); if (this.voiceRecording) { // If the recording has already started, it's probably a cached one. if (this.voiceRecording.hasRecording && !this.voiceRecording.isRecording) { this.setState({ haveRecording: true }); } // Note: Listeners for recording states are set by the `this.voiceRecording` setter. } else { this.setState({ haveRecording: false }); } } get showStickersButton() { return this.state.showStickersButton && !(0, _isLocalRoom.isLocalRoom)(this.props.room); } getMenuPosition() { if (this.ref.current) { const hasFormattingButtons = this.state.isWysiwygLabEnabled && this.state.isRichTextEnabled; const contentRect = this.ref.current.getBoundingClientRect(); // Here we need to remove the all the extra space above the editor // Instead of doing a querySelector or pass a ref to find the compute the height formatting buttons // We are using an arbitrary value, the formatting buttons height doesn't change during the lifecycle of the component // It's easier to just use a constant here instead of an over-engineering way to find the height const heightToRemove = hasFormattingButtons ? 36 : 0; const fixedRect = new DOMRect(contentRect.x, contentRect.y + heightToRemove, contentRect.width, contentRect.height - heightToRemove); return (0, _ContextMenu.aboveLeftOf)(fixedRect); } } render() { const hasE2EIcon = Boolean(!this.state.isWysiwygLabEnabled && this.props.e2eStatus); const e2eIcon = hasE2EIcon && /*#__PURE__*/_react.default.createElement("div", { className: "mx_MessageComposer_e2eIconWrapper" }, /*#__PURE__*/_react.default.createElement(_E2EIcon.default, { key: "e2eIcon", status: this.props.e2eStatus, className: "mx_MessageComposer_e2eIcon" })); const controls = []; const menuPosition = this.getMenuPosition(); const canSendMessages = this.context.canSendMessages && !this.context.tombstone; let composer; if (canSendMessages) { if (this.state.isWysiwygLabEnabled && menuPosition) { composer = /*#__PURE__*/_react.default.createElement(_wysiwyg_composer.SendWysiwygComposer, { key: "controls_input", disabled: this.state.haveRecording, onChange: this.onWysiwygChange, onSend: this.sendMessage, isRichTextEnabled: this.state.isRichTextEnabled, initialContent: this.state.initialComposerContent, e2eStatus: this.props.e2eStatus, menuPosition: menuPosition, placeholder: this.renderPlaceholderText(), eventRelation: this.props.relation }); } else { composer = /*#__PURE__*/_react.default.createElement(_SendMessageComposer.default, { ref: this.messageComposerInput, key: "controls_input", room: this.props.room, placeholder: this.renderPlaceholderText(), permalinkCreator: this.props.permalinkCreator, relation: this.props.relation, replyToEvent: this.props.replyToEvent, onChange: this.onChange, disabled: this.state.haveRecording, toggleStickerPickerOpen: this.toggleStickerPickerOpen }); } controls.push( /*#__PURE__*/_react.default.createElement(_VoiceRecordComposerTile.default, { key: "controls_voice_record", ref: this.voiceRecordingButton, room: this.props.room, permalinkCreator: this.props.permalinkCreator, relation: this.props.relation, replyToEvent: this.props.replyToEvent })); } else if (this.context.tombstone) { const replacementRoomId = this.context.tombstone.getContent()["replacement_room"]; const continuesLink = replacementRoomId ? /*#__PURE__*/_react.default.createElement("a", { href: (0, _Permalinks.makeRoomPermalink)(_MatrixClientPeg.MatrixClientPeg.safeGet(), replacementRoomId), className: "mx_MessageComposer_roomReplaced_link", onClick: this.onTombstoneClick }, (0, _languageHandler._t)("composer|room_upgraded_link")) : ""; controls.push( /*#__PURE__*/_react.default.createElement("div", { className: "mx_MessageComposer_replaced_wrapper", key: "room_replaced" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_MessageComposer_replaced_valign" }, /*#__PURE__*/_react.default.createElement("img", { "aria-hidden": true, alt: "", className: "mx_MessageComposer_roomReplaced_icon", src: require("../../../../res/img/room_replaced.svg").default }), /*#__PURE__*/_react.default.createElement("span", { className: "mx_MessageComposer_roomReplaced_header" }, (0, _languageHandler._t)("composer|room_upgraded_notice")), /*#__PURE__*/_react.default.createElement("br", null), continuesLink))); } else { controls.push( /*#__PURE__*/_react.default.createElement("div", { key: "controls_error", className: "mx_MessageComposer_noperm_error" }, (0, _languageHandler._t)("composer|no_perms_notice"))); } let recordingTooltip; const isTooltipOpen = Boolean(this.state.recordingTimeLeftSeconds); const secondsLeft = this.state.recordingTimeLeftSeconds ? Math.round(this.state.recordingTimeLeftSeconds) : 0; const threadId = this.props.relation?.rel_type === _matrix.THREAD_RELATION_TYPE.name ? this.props.relation.event_id : null; controls.push( /*#__PURE__*/_react.default.createElement(_Stickerpicker.default, { room: this.props.room, threadId: threadId, isStickerPickerOpen: this.state.isStickerPickerOpen, setStickerPickerOpen: this.setStickerPickerOpen, menuPosition: menuPosition, key: "stickers" })); const showSendButton = canSendMessages && (!this.state.isComposerEmpty || this.state.haveRecording); const classes = (0, _classnames.default)({ "mx_MessageComposer": true, "mx_MessageComposer--compact": this.props.compact, "mx_MessageComposer_e2eStatus": hasE2EIcon, "mx_MessageComposer_wysiwyg": this.state.isWysiwygLabEnabled }); return /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { open: isTooltipOpen, description: (0, _DateUtils.formatTimeLeft)(secondsLeft), placement: "bottom" }, /*#__PURE__*/_react.default.createElement("div", { className: classes, ref: this.ref, role: "region", "aria-label": (0, _languageHandler._t)("a11y|message_composer") }, recordingTooltip, /*#__PURE__*/_react.default.createElement("div", { className: "mx_MessageComposer_wrapper" }, /*#__PURE__*/_react.default.createElement(_ReplyPreview.default, { replyToEvent: this.props.replyToEvent, permalinkCreator: this.props.permalinkCreator }), /*#__PURE__*/_react.default.createElement("div", { className: "mx_MessageComposer_row" }, e2eIcon, composer, /*#__PURE__*/_react.default.createElement("div", { className: "mx_MessageComposer_actions" }, controls, canSendMessages && /*#__PURE__*/_react.default.createElement(_MessageComposerButtons.default, { addEmoji: this.addEmoji, haveRecording: this.state.haveRecording, isMenuOpen: this.state.isMenuOpen, isStickerPickerOpen: this.state.isStickerPickerOpen, menuPosition: menuPosition, relation: this.props.relation, onRecordStartEndClick: this.onRecordStartEndClick, setStickerPickerOpen: this.setStickerPickerOpen, showLocationButton: !window.electron && _SettingsStore.default.getValue(_UIFeature.UIFeature.LocationSharing), showPollsButton: this.state.showPollsButton, showStickersButton: this.showStickersButton, isRichTextEnabled: this.state.isRichTextEnabled, onComposerModeClick: this.onRichTextToggle, toggleButtonMenu: this.toggleButtonMenu, showVoiceBroadcastButton: this.state.showVoiceBroadcastButton, onStartVoiceBroadcastClick: () => { (0, _setUpVoiceBroadcastPreRecording.setUpVoiceBroadcastPreRecording)(this.props.room, _MatrixClientPeg.MatrixClientPeg.safeGet(), _SDKContext.SdkContextClass.instance.voiceBroadcastPlaybacksStore, _SDKContext.SdkContextClass.instance.voiceBroadcastRecordingsStore, _SDKContext.SdkContextClass.instance.voiceBroadcastPreRecordingStore); this.toggleButtonMenu(); } }), showSendButton && /*#__PURE__*/_react.default.createElement(SendButton, { key: "controls_send", onClick: this.sendMessage, title: this.state.haveRecording ? (0, _languageHandler._t)("composer|send_button_voice_message") : undefined })))))); } } exports.MessageComposer = MessageComposer; (0, _defineProperty2.default)(MessageComposer, "contextType", _RoomContext.default); (0, _defineProperty2.default)(MessageComposer, "defaultProps", { compact: false, showVoiceBroadcastButton: false, isRichTextEnabled: true }); const MessageComposerWithMatrixClient = (0, _MatrixClientContext.withMatrixClientHOC)(MessageComposer); var _default = exports.default = MessageComposerWithMatrixClient; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY2xhc3NuYW1lcyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfbWF0cml4IiwiX2NvbXBvdW5kV2ViIiwiX2xvZ2dlciIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfTWF0cml4Q2xpZW50UGVnIiwiX2Rpc3BhdGNoZXIiLCJfU3RpY2tlcnBpY2tlciIsIl9QZXJtYWxpbmtzIiwiX0UyRUljb24iLCJfU2V0dGluZ3NTdG9yZSIsIl9Db250ZXh0TWVudSIsIl9SZXBseVByZXZpZXciLCJfQXN5bmNTdG9yZSIsIl9Wb2ljZVJlY29yZENvbXBvc2VyVGlsZSIsIl9Wb2ljZVJlY29yZGluZ1N0b3JlIiwiX1ZvaWNlUmVjb3JkaW5nIiwiX1NlbmRNZXNzYWdlQ29tcG9zZXIiLCJfYWN0aW9ucyIsIl9VSVN0b3JlIiwiX1Jvb21Db250ZXh0IiwiX01lc3NhZ2VDb21wb3NlckJ1dHRvbnMiLCJfQWNjZXNzaWJsZUJ1dHRvbiIsIl9pc0xvY2FsUm9vbSIsIl9TZXR0aW5ncyIsIl93eXNpd3lnX2NvbXBvc2VyIiwiX01hdHJpeENsaWVudENvbnRleHQiLCJfc2V0VXBWb2ljZUJyb2FkY2FzdFByZVJlY29yZGluZyIsIl9TREtDb250ZXh0IiwiX3ZvaWNlQnJvYWRjYXN0IiwiX0NhbnRTdGFydFZvaWNlTWVzc2FnZUJyb2FkY2FzdERpYWxvZyIsIl9VSUZlYXR1cmUiLCJfRGF0ZVV0aWxzIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0IiwiV1lTSVdZR19FRElUT1JfU1RBVEVfU1RPUkFHRV9QUkVGSVgiLCJleHBvcnRzIiwiaW5zdGFuY2VDb3VudCIsIlNlbmRCdXR0b24iLCJwcm9wcyIsImNyZWF0ZUVsZW1lbnQiLCJjbGFzc05hbWUiLCJvbkNsaWNrIiwidGl0bGUiLCJfdCIsIk1lc3NhZ2VDb21wb3NlciIsIlJlYWN0IiwiQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJjb250ZXh0IiwiX2RlZmluZVByb3BlcnR5MiIsImNyZWF0ZVJlZiIsInNob3VsZFNhdmVXeXNpd3lnRWRpdG9yU3RhdGUiLCJpc1JpY2hUZXh0RW5hYmxlZCIsImNvbXBvc2VyQ29udGVudCIsInN0YXRlIiwicmVwbHlFdmVudElkIiwicmVwbHlUb0V2ZW50IiwiZ2V0SWQiLCJ1bmRlZmluZWQiLCJpdGVtIiwiY29udGVudCIsImlzUmljaFRleHQiLCJsb2NhbFN0b3JhZ2UiLCJzZXRJdGVtIiwiZWRpdG9yU3RhdGVLZXkiLCJKU09OIiwic3RyaW5naWZ5IiwiY2xlYXJTdG9yZWRFZGl0b3JTdGF0ZSIsImlzV3lzaXd5Z0xhYkVuYWJsZWQiLCJpc0NvbXBvc2VyRW1wdHkiLCJ0eXBlIiwiZW50cnkiLCJVSV9FVkVOVFMiLCJSZXNpemUiLCJuYXJyb3ciLCJzZXRTdGF0ZSIsImlzTWVudU9wZW4iLCJpc1N0aWNrZXJQaWNrZXJPcGVuIiwicGF5bG9hZCIsImFjdGlvbiIsInRpbWVsaW5lUmVuZGVyaW5nVHlwZSIsIndpbmRvdyIsInNldFRpbWVvdXQiLCJyZXNpemVOb3RpZmllciIsIm5vdGlmeVRpbWVsaW5lSGVpZ2h0Q2hhbmdlZCIsIkFjdGlvbiIsIlNldHRpbmdVcGRhdGVkIiwic2V0dGluZ1VwZGF0ZWRQYXlsb2FkIiwic2V0dGluZ05hbWUiLCJzaG93U3RpY2tlcnNCdXR0b24iLCJTZXR0aW5nc1N0b3JlIiwiZ2V0VmFsdWUiLCJzaG93UG9sbHNCdXR0b24iLCJGZWF0dXJlcyIsIlZvaWNlQnJvYWRjYXN0Iiwic2hvd1ZvaWNlQnJvYWRjYXN0QnV0dG9uIiwibmV3VmFsdWUiLCJCb29sZWFuIiwiZXYiLCJwcmV2ZW50RGVmYXVsdCIsInJlcGxhY2VtZW50Um9vbUlkIiwidG9tYnN0b25lIiwiZ2V0Q29udGVudCIsInJlcGxhY2VtZW50Um9vbSIsIk1hdHJpeENsaWVudFBlZyIsInNhZmVHZXQiLCJnZXRSb29tIiwiY3JlYXRlRXZlbnRJZCIsImNyZWF0ZUV2ZW50IiwiY3VycmVudFN0YXRlIiwiZ2V0U3RhdGVFdmVudHMiLCJFdmVudFR5cGUiLCJSb29tQ3JlYXRlIiwic2VuZGVyIiwiZ2V0U2VuZGVyIiwidmlhU2VydmVycyIsInNwbGl0Iiwic2xpY2UiLCJqb2luIiwiZGlzIiwiZGlzcGF0Y2giLCJWaWV3Um9vbSIsImhpZ2hsaWdodGVkIiwiZXZlbnRfaWQiLCJyb29tX2lkIiwiYXV0b19qb2luIiwidmlhX3NlcnZlcnMiLCJtZXRyaWNzVHJpZ2dlciIsIm1ldHJpY3NWaWFLZXlib2FyZCIsInJlcGx5aW5nVG9UaHJlYWQiLCJyZWxhdGlvbiIsInJlbF90eXBlIiwiVEhSRUFEX1JFTEFUSU9OX1RZUEUiLCJuYW1lIiwiZTJlU3RhdHVzIiwiZW1vamkiLCJDb21wb3Nlckluc2VydCIsInRleHQiLCJoYXZlUmVjb3JkaW5nIiwidm9pY2VSZWNvcmRpbmdCdXR0b24iLCJjdXJyZW50Iiwic2VuZCIsIm1lc3NhZ2VDb21wb3NlcklucHV0Iiwic2VuZE1lc3NhZ2UiLCJwZXJtYWxpbmtDcmVhdG9yIiwiaW5pdGlhbENvbXBvc2VyQ29udGVudCIsIkNsZWFyQW5kRm9jdXNTZW5kTWVzc2FnZUNvbXBvc2VyIiwibXhDbGllbnQiLCJyb29tQ29udGV4dCIsIm1vZGVsIiwiaXNFbXB0eSIsImxlbmd0aCIsInJpY2hUb1BsYWluIiwicGxhaW5Ub1JpY2giLCJnZXRDb252ZXJzaW9uRnVuY3Rpb25zIiwiY29udmVydGVkQ29udGVudCIsInVwZGF0ZVJlY29yZGluZ1N0YXRlIiwidm9pY2VSZWNvcmRpbmdJZCIsIlZvaWNlUmVjb3JkaW5nU3RvcmUiLCJnZXRWb2ljZVJlY29yZGluZ0lkIiwicm9vbSIsInZvaWNlUmVjb3JkaW5nIiwiaW5zdGFuY2UiLCJnZXRBY3RpdmVSZWNvcmRpbmciLCJzZWNvbmRzTGVmdCIsInJlY29yZGluZ1RpbWVMZWZ0U2Vjb25kcyIsInNldFN0aWNrZXJQaWNrZXJPcGVuIiwiY3VycmVudEJyb2FkY2FzdFJlY29yZGluZyIsIlNka0NvbnRleHRDbGFzcyIsInZvaWNlQnJvYWRjYXN0UmVjb3JkaW5nc1N0b3JlIiwiZ2V0Q3VycmVudCIsImdldFN0YXRlIiwiVm9pY2VCcm9hZGNhc3RJbmZvU3RhdGUiLCJTdG9wcGVkIiwiY3JlYXRlQ2FudFN0YXJ0Vm9pY2VNZXNzYWdlQnJvYWRjYXN0RGlhbG9nIiwib25SZWNvcmRTdGFydEVuZENsaWNrIiwidG9nZ2xlQnV0dG9uTWVudSIsIm9uIiwiVVBEQVRFX0VWRU5UIiwib25Wb2ljZVN0b3JlVXBkYXRlIiwiYWRkRXZlbnRMaXN0ZW5lciIsInNhdmVXeXNpd3lnRWRpdG9yU3RhdGUiLCJ3eXNpd3lnU3RhdGUiLCJyZXN0b3JlV3lzaXd5Z0VkaXRvclN0YXRlIiwiZXZlbnQiLCJmaW5kRXZlbnRCeUlkIiwiaW5zdGFuY2VJZCIsIm1vbml0b3JTZXR0aW5nIiwia2V5Iiwicm9vbUlkIiwianNvbiIsImdldEl0ZW0iLCJwYXJzZSIsImxvZ2dlciIsImVycm9yIiwicmVtb3ZlSXRlbSIsIl92b2ljZVJlY29yZGluZyIsInJlYyIsIm9mZiIsIlJlY29yZGluZ1N0YXRlIiwiU3RhcnRlZCIsIm9uUmVjb3JkaW5nU3RhcnRlZCIsIkVuZGluZ1Nvb24iLCJvblJlY29yZGluZ0VuZGluZ1Nvb24iLCJjb21wb25lbnREaWRNb3VudCIsImRpc3BhdGNoZXJSZWYiLCJyZWdpc3RlciIsIm9uQWN0aW9uIiwid2FpdEZvck93bk1lbWJlciIsIlVJU3RvcmUiLCJ0cmFja0VsZW1lbnREaW1lbnNpb25zIiwicmVmIiwib25SZXNpemUiLCJtZSIsImdldE1lbWJlciIsImdldFVzZXJJZCIsImxvYWRNZW1iZXJzSWZOZWVkZWQiLCJ0aGVuIiwiZ2V0U2FmZVVzZXJJZCIsImNvbXBvbmVudFdpbGxVbm1vdW50IiwidW5yZWdpc3RlciIsInN0b3BUcmFja2luZ0VsZW1lbnREaW1lbnNpb25zIiwicmVtb3ZlTGlzdGVuZXIiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiaGFzUmVjb3JkaW5nIiwiaXNSZWNvcmRpbmciLCJpc0xvY2FsUm9vbSIsImdldE1lbnVQb3NpdGlvbiIsImhhc0Zvcm1hdHRpbmdCdXR0b25zIiwiY29udGVudFJlY3QiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJoZWlnaHRUb1JlbW92ZSIsImZpeGVkUmVjdCIsIkRPTVJlY3QiLCJ4IiwieSIsIndpZHRoIiwiaGVpZ2h0IiwiYWJvdmVMZWZ0T2YiLCJyZW5kZXIiLCJoYXNFMkVJY29uIiwiZTJlSWNvbiIsInN0YXR1cyIsImNvbnRyb2xzIiwibWVudVBvc2l0aW9uIiwiY2FuU2VuZE1lc3NhZ2VzIiwiY29tcG9zZXIiLCJTZW5kV3lzaXd5Z0NvbXBvc2VyIiwiZGlzYWJsZWQiLCJvbkNoYW5nZSIsIm9uV3lzaXd5Z0NoYW5nZSIsIm9uU2VuZCIsImluaXRpYWxDb250ZW50IiwicGxhY2Vob2xkZXIiLCJyZW5kZXJQbGFjZWhvbGRlclRleHQiLCJldmVudFJlbGF0aW9uIiwidG9nZ2xlU3RpY2tlclBpY2tlck9wZW4iLCJwdXNoIiwiY29udGludWVzTGluayIsImhyZWYiLCJtYWtlUm9vbVBlcm1hbGluayIsIm9uVG9tYnN0b25lQ2xpY2siLCJhbHQiLCJzcmMiLCJyZWNvcmRpbmdUb29sdGlwIiwiaXNUb29sdGlwT3BlbiIsIk1hdGgiLCJyb3VuZCIsInRocmVhZElkIiwic2hvd1NlbmRCdXR0b24iLCJjbGFzc2VzIiwiY2xhc3NOYW1lcyIsImNvbXBhY3QiLCJUb29sdGlwIiwib3BlbiIsImRlc2NyaXB0aW9uIiwiZm9ybWF0VGltZUxlZnQiLCJwbGFjZW1lbnQiLCJyb2xlIiwiYWRkRW1vamkiLCJzaG93TG9jYXRpb25CdXR0b24iLCJlbGVjdHJvbiIsIlVJRmVhdHVyZSIsIkxvY2F0aW9uU2hhcmluZyIsIm9uQ29tcG9zZXJNb2RlQ2xpY2siLCJvblJpY2hUZXh0VG9nZ2xlIiwib25TdGFydFZvaWNlQnJvYWRjYXN0Q2xpY2siLCJzZXRVcFZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nIiwidm9pY2VCcm9hZGNhc3RQbGF5YmFja3NTdG9yZSIsInZvaWNlQnJvYWRjYXN0UHJlUmVjb3JkaW5nU3RvcmUiLCJSb29tQ29udGV4dCIsIk1lc3NhZ2VDb21wb3NlcldpdGhNYXRyaXhDbGllbnQiLCJ3aXRoTWF0cml4Q2xpZW50SE9DIiwiX2RlZmF1bHQiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy92aWV3cy9yb29tcy9NZXNzYWdlQ29tcG9zZXIudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE1LTIwMjIgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7IGNyZWF0ZVJlZiwgUmVhY3ROb2RlIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tIFwiY2xhc3NuYW1lc1wiO1xuaW1wb3J0IHtcbiAgICBJRXZlbnRSZWxhdGlvbixcbiAgICBNYXRyaXhFdmVudCxcbiAgICBSb29tLFxuICAgIFJvb21NZW1iZXIsXG4gICAgRXZlbnRUeXBlLFxuICAgIFRIUkVBRF9SRUxBVElPTl9UWVBFLFxufSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgeyBPcHRpb25hbCB9IGZyb20gXCJtYXRyaXgtZXZlbnRzLXNka1wiO1xuaW1wb3J0IHsgVG9vbHRpcCB9IGZyb20gXCJAdmVjdG9yLWltL2NvbXBvdW5kLXdlYlwiO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL2xvZ2dlclwiO1xuXG5pbXBvcnQgeyBfdCB9IGZyb20gXCIuLi8uLi8uLi9sYW5ndWFnZUhhbmRsZXJcIjtcbmltcG9ydCB7IE1hdHJpeENsaWVudFBlZyB9IGZyb20gXCIuLi8uLi8uLi9NYXRyaXhDbGllbnRQZWdcIjtcbmltcG9ydCBkaXMgZnJvbSBcIi4uLy4uLy4uL2Rpc3BhdGNoZXIvZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgQWN0aW9uUGF5bG9hZCB9IGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL3BheWxvYWRzXCI7XG5pbXBvcnQgU3RpY2tlcnBpY2tlciBmcm9tIFwiLi9TdGlja2VycGlja2VyXCI7XG5pbXBvcnQgeyBtYWtlUm9vbVBlcm1hbGluaywgUm9vbVBlcm1hbGlua0NyZWF0b3IgfSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvcGVybWFsaW5rcy9QZXJtYWxpbmtzXCI7XG5pbXBvcnQgRTJFSWNvbiBmcm9tIFwiLi9FMkVJY29uXCI7XG5pbXBvcnQgU2V0dGluZ3NTdG9yZSBmcm9tIFwiLi4vLi4vLi4vc2V0dGluZ3MvU2V0dGluZ3NTdG9yZVwiO1xuaW1wb3J0IHsgYWJvdmVMZWZ0T2YsIE1lbnVQcm9wcyB9IGZyb20gXCIuLi8uLi9zdHJ1Y3R1cmVzL0NvbnRleHRNZW51XCI7XG5pbXBvcnQgUmVwbHlQcmV2aWV3IGZyb20gXCIuL1JlcGx5UHJldmlld1wiO1xuaW1wb3J0IHsgVVBEQVRFX0VWRU5UIH0gZnJvbSBcIi4uLy4uLy4uL3N0b3Jlcy9Bc3luY1N0b3JlXCI7XG5pbXBvcnQgVm9pY2VSZWNvcmRDb21wb3NlclRpbGUgZnJvbSBcIi4vVm9pY2VSZWNvcmRDb21wb3NlclRpbGVcIjtcbmltcG9ydCB7IFZvaWNlUmVjb3JkaW5nU3RvcmUgfSBmcm9tIFwiLi4vLi4vLi4vc3RvcmVzL1ZvaWNlUmVjb3JkaW5nU3RvcmVcIjtcbmltcG9ydCB7IFJlY29yZGluZ1N0YXRlIH0gZnJvbSBcIi4uLy4uLy4uL2F1ZGlvL1ZvaWNlUmVjb3JkaW5nXCI7XG5pbXBvcnQgUmVzaXplTm90aWZpZXIgZnJvbSBcIi4uLy4uLy4uL3V0aWxzL1Jlc2l6ZU5vdGlmaWVyXCI7XG5pbXBvcnQgeyBFMkVTdGF0dXMgfSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvU2hpZWxkVXRpbHNcIjtcbmltcG9ydCBTZW5kTWVzc2FnZUNvbXBvc2VyLCB7IFNlbmRNZXNzYWdlQ29tcG9zZXIgYXMgU2VuZE1lc3NhZ2VDb21wb3NlckNsYXNzIH0gZnJvbSBcIi4vU2VuZE1lc3NhZ2VDb21wb3NlclwiO1xuaW1wb3J0IHsgQ29tcG9zZXJJbnNlcnRQYXlsb2FkIH0gZnJvbSBcIi4uLy4uLy4uL2Rpc3BhdGNoZXIvcGF5bG9hZHMvQ29tcG9zZXJJbnNlcnRQYXlsb2FkXCI7XG5pbXBvcnQgeyBBY3Rpb24gfSBmcm9tIFwiLi4vLi4vLi4vZGlzcGF0Y2hlci9hY3Rpb25zXCI7XG5pbXBvcnQgRWRpdG9yTW9kZWwgZnJvbSBcIi4uLy4uLy4uL2VkaXRvci9tb2RlbFwiO1xuaW1wb3J0IFVJU3RvcmUsIHsgVUlfRVZFTlRTIH0gZnJvbSBcIi4uLy4uLy4uL3N0b3Jlcy9VSVN0b3JlXCI7XG5pbXBvcnQgUm9vbUNvbnRleHQgZnJvbSBcIi4uLy4uLy4uL2NvbnRleHRzL1Jvb21Db250ZXh0XCI7XG5pbXBvcnQgeyBTZXR0aW5nVXBkYXRlZFBheWxvYWQgfSBmcm9tIFwiLi4vLi4vLi4vZGlzcGF0Y2hlci9wYXlsb2Fkcy9TZXR0aW5nVXBkYXRlZFBheWxvYWRcIjtcbmltcG9ydCBNZXNzYWdlQ29tcG9zZXJCdXR0b25zIGZyb20gXCIuL01lc3NhZ2VDb21wb3NlckJ1dHRvbnNcIjtcbmltcG9ydCBBY2Nlc3NpYmxlQnV0dG9uLCB7IEJ1dHRvbkV2ZW50IH0gZnJvbSBcIi4uL2VsZW1lbnRzL0FjY2Vzc2libGVCdXR0b25cIjtcbmltcG9ydCB7IFZpZXdSb29tUGF5bG9hZCB9IGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL3BheWxvYWRzL1ZpZXdSb29tUGF5bG9hZFwiO1xuaW1wb3J0IHsgaXNMb2NhbFJvb20gfSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvbG9jYWxSb29tL2lzTG9jYWxSb29tXCI7XG5pbXBvcnQgeyBGZWF0dXJlcyB9IGZyb20gXCIuLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1wiO1xuaW1wb3J0IHsgVm9pY2VNZXNzYWdlUmVjb3JkaW5nIH0gZnJvbSBcIi4uLy4uLy4uL2F1ZGlvL1ZvaWNlTWVzc2FnZVJlY29yZGluZ1wiO1xuaW1wb3J0IHsgU2VuZFd5c2l3eWdDb21wb3Nlciwgc2VuZE1lc3NhZ2UsIGdldENvbnZlcnNpb25GdW5jdGlvbnMgfSBmcm9tIFwiLi93eXNpd3lnX2NvbXBvc2VyL1wiO1xuaW1wb3J0IHsgTWF0cml4Q2xpZW50UHJvcHMsIHdpdGhNYXRyaXhDbGllbnRIT0MgfSBmcm9tIFwiLi4vLi4vLi4vY29udGV4dHMvTWF0cml4Q2xpZW50Q29udGV4dFwiO1xuaW1wb3J0IHsgc2V0VXBWb2ljZUJyb2FkY2FzdFByZVJlY29yZGluZyB9IGZyb20gXCIuLi8uLi8uLi92b2ljZS1icm9hZGNhc3QvdXRpbHMvc2V0VXBWb2ljZUJyb2FkY2FzdFByZVJlY29yZGluZ1wiO1xuaW1wb3J0IHsgU2RrQ29udGV4dENsYXNzIH0gZnJvbSBcIi4uLy4uLy4uL2NvbnRleHRzL1NES0NvbnRleHRcIjtcbmltcG9ydCB7IFZvaWNlQnJvYWRjYXN0SW5mb1N0YXRlIH0gZnJvbSBcIi4uLy4uLy4uL3ZvaWNlLWJyb2FkY2FzdFwiO1xuaW1wb3J0IHsgY3JlYXRlQ2FudFN0YXJ0Vm9pY2VNZXNzYWdlQnJvYWRjYXN0RGlhbG9nIH0gZnJvbSBcIi4uL2RpYWxvZ3MvQ2FudFN0YXJ0Vm9pY2VNZXNzYWdlQnJvYWRjYXN0RGlhbG9nXCI7XG5pbXBvcnQgeyBVSUZlYXR1cmUgfSBmcm9tIFwiLi4vLi4vLi4vc2V0dGluZ3MvVUlGZWF0dXJlXCI7XG5pbXBvcnQgeyBmb3JtYXRUaW1lTGVmdCB9IGZyb20gXCIuLi8uLi8uLi9EYXRlVXRpbHNcIjtcblxuLy8gVGhlIHByZWZpeCB1c2VkIHdoZW4gcGVyc2lzdGluZyBlZGl0b3IgZHJhZnRzIHRvIGxvY2Fsc3RvcmFnZS5cbmV4cG9ydCBjb25zdCBXWVNJV1lHX0VESVRPUl9TVEFURV9TVE9SQUdFX1BSRUZJWCA9IFwibXhfd3lzaXd5Z19zdGF0ZV9cIjtcblxubGV0IGluc3RhbmNlQ291bnQgPSAwO1xuXG5pbnRlcmZhY2UgSVNlbmRCdXR0b25Qcm9wcyB7XG4gICAgb25DbGljazogKGV2OiBCdXR0b25FdmVudCkgPT4gdm9pZDtcbiAgICB0aXRsZT86IHN0cmluZzsgLy8gZGVmYXVsdHMgdG8gc29tZXRoaW5nIGdlbmVyaWNcbn1cblxuZnVuY3Rpb24gU2VuZEJ1dHRvbihwcm9wczogSVNlbmRCdXR0b25Qcm9wcyk6IEpTWC5FbGVtZW50IHtcbiAgICByZXR1cm4gKFxuICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfTWVzc2FnZUNvbXBvc2VyX3NlbmRNZXNzYWdlXCJcbiAgICAgICAgICAgIG9uQ2xpY2s9e3Byb3BzLm9uQ2xpY2t9XG4gICAgICAgICAgICB0aXRsZT17cHJvcHMudGl0bGUgPz8gX3QoXCJjb21wb3NlcnxzZW5kX2J1dHRvbl90aXRsZVwiKX1cbiAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwic2VuZG1lc3NhZ2VidG5cIlxuICAgICAgICAvPlxuICAgICk7XG59XG5cbmludGVyZmFjZSBJUHJvcHMgZXh0ZW5kcyBNYXRyaXhDbGllbnRQcm9wcyB7XG4gICAgcm9vbTogUm9vbTtcbiAgICByZXNpemVOb3RpZmllcjogUmVzaXplTm90aWZpZXI7XG4gICAgcGVybWFsaW5rQ3JlYXRvcj86IFJvb21QZXJtYWxpbmtDcmVhdG9yO1xuICAgIHJlcGx5VG9FdmVudD86IE1hdHJpeEV2ZW50O1xuICAgIHJlbGF0aW9uPzogSUV2ZW50UmVsYXRpb247XG4gICAgZTJlU3RhdHVzPzogRTJFU3RhdHVzO1xuICAgIGNvbXBhY3Q/OiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgSVN0YXRlIHtcbiAgICBjb21wb3NlckNvbnRlbnQ6IHN0cmluZztcbiAgICBpc0NvbXBvc2VyRW1wdHk6IGJvb2xlYW47XG4gICAgaGF2ZVJlY29yZGluZzogYm9vbGVhbjtcbiAgICByZWNvcmRpbmdUaW1lTGVmdFNlY29uZHM/OiBudW1iZXI7XG4gICAgbWU/OiBSb29tTWVtYmVyO1xuICAgIGlzTWVudU9wZW46IGJvb2xlYW47XG4gICAgaXNTdGlja2VyUGlja2VyT3BlbjogYm9vbGVhbjtcbiAgICBzaG93U3RpY2tlcnNCdXR0b246IGJvb2xlYW47XG4gICAgc2hvd1BvbGxzQnV0dG9uOiBib29sZWFuO1xuICAgIHNob3dWb2ljZUJyb2FkY2FzdEJ1dHRvbjogYm9vbGVhbjtcbiAgICBpc1d5c2l3eWdMYWJFbmFibGVkOiBib29sZWFuO1xuICAgIGlzUmljaFRleHRFbmFibGVkOiBib29sZWFuO1xuICAgIGluaXRpYWxDb21wb3NlckNvbnRlbnQ6IHN0cmluZztcbn1cblxudHlwZSBXeXNpd3lnQ29tcG9zZXJTdGF0ZSA9IHtcbiAgICBjb250ZW50OiBzdHJpbmc7XG4gICAgaXNSaWNoVGV4dDogYm9vbGVhbjtcbiAgICByZXBseUV2ZW50SWQ/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgY2xhc3MgTWVzc2FnZUNvbXBvc2VyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50PElQcm9wcywgSVN0YXRlPiB7XG4gICAgcHJpdmF0ZSBkaXNwYXRjaGVyUmVmPzogc3RyaW5nO1xuICAgIHByaXZhdGUgbWVzc2FnZUNvbXBvc2VySW5wdXQgPSBjcmVhdGVSZWY8U2VuZE1lc3NhZ2VDb21wb3NlckNsYXNzPigpO1xuICAgIHByaXZhdGUgdm9pY2VSZWNvcmRpbmdCdXR0b24gPSBjcmVhdGVSZWY8Vm9pY2VSZWNvcmRDb21wb3NlclRpbGU+KCk7XG4gICAgcHJpdmF0ZSByZWY6IFJlYWN0LlJlZk9iamVjdDxIVE1MRGl2RWxlbWVudD4gPSBjcmVhdGVSZWYoKTtcbiAgICBwcml2YXRlIGluc3RhbmNlSWQ6IG51bWJlcjtcblxuICAgIHByaXZhdGUgX3ZvaWNlUmVjb3JkaW5nOiBPcHRpb25hbDxWb2ljZU1lc3NhZ2VSZWNvcmRpbmc+O1xuXG4gICAgcHVibGljIHN0YXRpYyBjb250ZXh0VHlwZSA9IFJvb21Db250ZXh0O1xuICAgIHB1YmxpYyBkZWNsYXJlIGNvbnRleHQ6IFJlYWN0LkNvbnRleHRUeXBlPHR5cGVvZiBSb29tQ29udGV4dD47XG5cbiAgICBwdWJsaWMgc3RhdGljIGRlZmF1bHRQcm9wcyA9IHtcbiAgICAgICAgY29tcGFjdDogZmFsc2UsXG4gICAgICAgIHNob3dWb2ljZUJyb2FkY2FzdEJ1dHRvbjogZmFsc2UsXG4gICAgICAgIGlzUmljaFRleHRFbmFibGVkOiB0cnVlLFxuICAgIH07XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJvcHM6IElQcm9wcywgY29udGV4dDogUmVhY3QuQ29udGV4dFR5cGU8dHlwZW9mIFJvb21Db250ZXh0Pikge1xuICAgICAgICBzdXBlcihwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7IC8vIG90aGVyd2lzZSBSZWFjdCB3aWxsIG9ubHkgc2V0IGl0IHByaW9yIHRvIHJlbmRlciBkdWUgdG8gdHlwZSBkZWYgYWJvdmVcblxuICAgICAgICBWb2ljZVJlY29yZGluZ1N0b3JlLmluc3RhbmNlLm9uKFVQREFURV9FVkVOVCwgdGhpcy5vblZvaWNlU3RvcmVVcGRhdGUpO1xuXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiYmVmb3JldW5sb2FkXCIsIHRoaXMuc2F2ZVd5c2l3eWdFZGl0b3JTdGF0ZSk7XG4gICAgICAgIGNvbnN0IGlzV3lzaXd5Z0xhYkVuYWJsZWQgPSBTZXR0aW5nc1N0b3JlLmdldFZhbHVlPGJvb2xlYW4+KFwiZmVhdHVyZV93eXNpd3lnX2NvbXBvc2VyXCIpO1xuICAgICAgICBsZXQgaXNSaWNoVGV4dEVuYWJsZWQgPSB0cnVlO1xuICAgICAgICBsZXQgaW5pdGlhbENvbXBvc2VyQ29udGVudCA9IFwiXCI7XG4gICAgICAgIGlmIChpc1d5c2l3eWdMYWJFbmFibGVkKSB7XG4gICAgICAgICAgICBjb25zdCB3eXNpd3lnU3RhdGUgPSB0aGlzLnJlc3RvcmVXeXNpd3lnRWRpdG9yU3RhdGUoKTtcbiAgICAgICAgICAgIGlmICh3eXNpd3lnU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBpc1JpY2hUZXh0RW5hYmxlZCA9IHd5c2l3eWdTdGF0ZS5pc1JpY2hUZXh0O1xuICAgICAgICAgICAgICAgIGluaXRpYWxDb21wb3NlckNvbnRlbnQgPSB3eXNpd3lnU3RhdGUuY29udGVudDtcbiAgICAgICAgICAgICAgICBpZiAod3lzaXd5Z1N0YXRlLnJlcGx5RXZlbnRJZCkge1xuICAgICAgICAgICAgICAgICAgICBkaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiBcInJlcGx5X3RvX2V2ZW50XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudDogdGhpcy5wcm9wcy5yb29tLmZpbmRFdmVudEJ5SWQod3lzaXd5Z1N0YXRlLnJlcGx5RXZlbnRJZCksXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQudGltZWxpbmVSZW5kZXJpbmdUeXBlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgaXNDb21wb3NlckVtcHR5OiBpbml0aWFsQ29tcG9zZXJDb250ZW50Py5sZW5ndGggPT09IDAsXG4gICAgICAgICAgICBjb21wb3NlckNvbnRlbnQ6IGluaXRpYWxDb21wb3NlckNvbnRlbnQsXG4gICAgICAgICAgICBoYXZlUmVjb3JkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgIHJlY29yZGluZ1RpbWVMZWZ0U2Vjb25kczogdW5kZWZpbmVkLCAvLyB3aGVuIHNldCB0byBhIG51bWJlciwgc2hvd3MgYSB0b2FzdFxuICAgICAgICAgICAgaXNNZW51T3BlbjogZmFsc2UsXG4gICAgICAgICAgICBpc1N0aWNrZXJQaWNrZXJPcGVuOiBmYWxzZSxcbiAgICAgICAgICAgIHNob3dTdGlja2Vyc0J1dHRvbjogU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcIk1lc3NhZ2VDb21wb3NlcklucHV0LnNob3dTdGlja2Vyc0J1dHRvblwiKSxcbiAgICAgICAgICAgIHNob3dQb2xsc0J1dHRvbjogU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcIk1lc3NhZ2VDb21wb3NlcklucHV0LnNob3dQb2xsc0J1dHRvblwiKSxcbiAgICAgICAgICAgIHNob3dWb2ljZUJyb2FkY2FzdEJ1dHRvbjogU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShGZWF0dXJlcy5Wb2ljZUJyb2FkY2FzdCksXG4gICAgICAgICAgICBpc1d5c2l3eWdMYWJFbmFibGVkOiBpc1d5c2l3eWdMYWJFbmFibGVkLFxuICAgICAgICAgICAgaXNSaWNoVGV4dEVuYWJsZWQ6IGlzUmljaFRleHRFbmFibGVkLFxuICAgICAgICAgICAgaW5pdGlhbENvbXBvc2VyQ29udGVudDogaW5pdGlhbENvbXBvc2VyQ29udGVudCxcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmluc3RhbmNlSWQgPSBpbnN0YW5jZUNvdW50Kys7XG5cbiAgICAgICAgU2V0dGluZ3NTdG9yZS5tb25pdG9yU2V0dGluZyhcIk1lc3NhZ2VDb21wb3NlcklucHV0LnNob3dTdGlja2Vyc0J1dHRvblwiLCBudWxsKTtcbiAgICAgICAgU2V0dGluZ3NTdG9yZS5tb25pdG9yU2V0dGluZyhcIk1lc3NhZ2VDb21wb3NlcklucHV0LnNob3dQb2xsc0J1dHRvblwiLCBudWxsKTtcbiAgICAgICAgU2V0dGluZ3NTdG9yZS5tb25pdG9yU2V0dGluZyhGZWF0dXJlcy5Wb2ljZUJyb2FkY2FzdCwgbnVsbCk7XG4gICAgICAgIFNldHRpbmdzU3RvcmUubW9uaXRvclNldHRpbmcoXCJmZWF0dXJlX3d5c2l3eWdfY29tcG9zZXJcIiwgbnVsbCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXQgZWRpdG9yU3RhdGVLZXkoKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IGtleSA9IFdZU0lXWUdfRURJVE9SX1NUQVRFX1NUT1JBR0VfUFJFRklYICsgdGhpcy5wcm9wcy5yb29tLnJvb21JZDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMucmVsYXRpb24/LnJlbF90eXBlID09PSBUSFJFQURfUkVMQVRJT05fVFlQRS5uYW1lKSB7XG4gICAgICAgICAgICBrZXkgKz0gYF8ke3RoaXMucHJvcHMucmVsYXRpb24uZXZlbnRfaWR9YDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ga2V5O1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVzdG9yZVd5c2l3eWdFZGl0b3JTdGF0ZSgpOiBXeXNpd3lnQ29tcG9zZXJTdGF0ZSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGNvbnN0IGpzb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmVkaXRvclN0YXRlS2V5KTtcbiAgICAgICAgaWYgKGpzb24pIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhdGU6IFd5c2l3eWdDb21wb3NlclN0YXRlID0gSlNPTi5wYXJzZShqc29uKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzYXZlV3lzaXd5Z0VkaXRvclN0YXRlID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAodGhpcy5zaG91bGRTYXZlV3lzaXd5Z0VkaXRvclN0YXRlKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgaXNSaWNoVGV4dEVuYWJsZWQsIGNvbXBvc2VyQ29udGVudCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgICAgICAgIGNvbnN0IHJlcGx5RXZlbnRJZCA9IHRoaXMucHJvcHMucmVwbHlUb0V2ZW50ID8gdGhpcy5wcm9wcy5yZXBseVRvRXZlbnQuZ2V0SWQoKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW06IFd5c2l3eWdDb21wb3NlclN0YXRlID0ge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGNvbXBvc2VyQ29udGVudCxcbiAgICAgICAgICAgICAgICBpc1JpY2hUZXh0OiBpc1JpY2hUZXh0RW5hYmxlZCxcbiAgICAgICAgICAgICAgICByZXBseUV2ZW50SWQ6IHJlcGx5RXZlbnRJZCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLmVkaXRvclN0YXRlS2V5LCBKU09OLnN0cmluZ2lmeShpdGVtKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNsZWFyU3RvcmVkRWRpdG9yU3RhdGUoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBzaG91bGQgc2F2ZSBzdGF0ZSB3aGVuIHd5c2l3eWcgaXMgZW5hYmxlZCBhbmQgaGFzIGNvbnRlbnRzIG9yIHJlcGx5IGlzIG9wZW5cbiAgICBwcml2YXRlIHNob3VsZFNhdmVXeXNpd3lnRWRpdG9yU3RhdGUgPSAoKTogYm9vbGVhbiA9PiB7XG4gICAgICAgIGNvbnN0IHsgaXNXeXNpd3lnTGFiRW5hYmxlZCwgaXNDb21wb3NlckVtcHR5IH0gPSB0aGlzLnN0YXRlO1xuICAgICAgICByZXR1cm4gaXNXeXNpd3lnTGFiRW5hYmxlZCAmJiAoIWlzQ29tcG9zZXJFbXB0eSB8fCAhIXRoaXMucHJvcHMucmVwbHlUb0V2ZW50KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBjbGVhclN0b3JlZEVkaXRvclN0YXRlKCk6IHZvaWQge1xuICAgICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbSh0aGlzLmVkaXRvclN0YXRlS2V5KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldCB2b2ljZVJlY29yZGluZygpOiBPcHRpb25hbDxWb2ljZU1lc3NhZ2VSZWNvcmRpbmc+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZvaWNlUmVjb3JkaW5nO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0IHZvaWNlUmVjb3JkaW5nKHJlYzogT3B0aW9uYWw8Vm9pY2VNZXNzYWdlUmVjb3JkaW5nPikge1xuICAgICAgICBpZiAodGhpcy5fdm9pY2VSZWNvcmRpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuX3ZvaWNlUmVjb3JkaW5nLm9mZihSZWNvcmRpbmdTdGF0ZS5TdGFydGVkLCB0aGlzLm9uUmVjb3JkaW5nU3RhcnRlZCk7XG4gICAgICAgICAgICB0aGlzLl92b2ljZVJlY29yZGluZy5vZmYoUmVjb3JkaW5nU3RhdGUuRW5kaW5nU29vbiwgdGhpcy5vblJlY29yZGluZ0VuZGluZ1Nvb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdm9pY2VSZWNvcmRpbmcgPSByZWM7XG5cbiAgICAgICAgaWYgKHJlYykge1xuICAgICAgICAgICAgLy8gRGVsYXkgc2F5aW5nIHdlIGhhdmUgYSByZWNvcmRpbmcgdW50aWwgaXQgaXMgc3RhcnRlZCwgYXMgd2UgbWlnaHQgbm90IHlldFxuICAgICAgICAgICAgLy8gaGF2ZSBBL1YgcGVybWlzc2lvbnNcbiAgICAgICAgICAgIHJlYy5vbihSZWNvcmRpbmdTdGF0ZS5TdGFydGVkLCB0aGlzLm9uUmVjb3JkaW5nU3RhcnRlZCk7XG5cbiAgICAgICAgICAgI