UNPKG

matrix-react-sdk

Version:
182 lines (177 loc) 28.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _classnames = _interopRequireDefault(require("classnames")); var _react = _interopRequireDefault(require("react")); var _callFeed = require("matrix-js-sdk/src/webrtc/callFeed"); var _logger = require("matrix-js-sdk/src/logger"); var _callEventTypes = require("matrix-js-sdk/src/webrtc/callEventTypes"); var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore")); var _LegacyCallHandler = _interopRequireDefault(require("../../../LegacyCallHandler")); var _MatrixClientPeg = require("../../../MatrixClientPeg"); var _RoomAvatar = _interopRequireDefault(require("../avatars/RoomAvatar")); /* Copyright 2024 New Vector Ltd. Copyright 2021, 2022 Šimon Brandner <simon.bra.ag@gmail.com> Copyright 2015, 2016 , 2019, 2020, 2021 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. */ class VideoFeed extends _react.default.PureComponent { constructor(props) { super(props); (0, _defineProperty2.default)(this, "element", void 0); (0, _defineProperty2.default)(this, "setElementRef", element => { if (!element) { this.element?.removeEventListener("resize", this.onResize); return; } this.element = element; element.addEventListener("resize", this.onResize); }); (0, _defineProperty2.default)(this, "onNewStream", () => { this.setState({ audioMuted: this.props.feed.isAudioMuted(), videoMuted: this.props.feed.isVideoMuted() }); this.playMedia(); }); (0, _defineProperty2.default)(this, "onMuteStateChanged", () => { this.setState({ audioMuted: this.props.feed.isAudioMuted(), videoMuted: this.props.feed.isVideoMuted() }); }); (0, _defineProperty2.default)(this, "onResize", e => { if (this.props.onResize && !this.props.feed.isLocal()) { this.props.onResize(e); } }); this.state = { audioMuted: this.props.feed.isAudioMuted(), videoMuted: this.props.feed.isVideoMuted() }; } componentDidMount() { this.updateFeed(null, this.props.feed); this.playMedia(); } componentWillUnmount() { this.updateFeed(this.props.feed, null); } componentDidUpdate(prevProps, prevState) { this.updateFeed(prevProps.feed, this.props.feed); // If the mutes state has changed, we try to playMedia() if (prevState.videoMuted !== this.state.videoMuted || prevProps.feed.stream !== this.props.feed.stream) { this.playMedia(); } } static getDerivedStateFromProps(props) { return { audioMuted: props.feed.isAudioMuted(), videoMuted: props.feed.isVideoMuted() }; } updateFeed(oldFeed, newFeed) { if (oldFeed === newFeed) return; if (oldFeed) { this.props.feed.removeListener(_callFeed.CallFeedEvent.NewStream, this.onNewStream); this.props.feed.removeListener(_callFeed.CallFeedEvent.MuteStateChanged, this.onMuteStateChanged); if (this.props.feed.purpose === _callEventTypes.SDPStreamMetadataPurpose.Usermedia) { this.props.feed.measureVolumeActivity(false); } this.stopMedia(); } if (newFeed) { this.props.feed.addListener(_callFeed.CallFeedEvent.NewStream, this.onNewStream); this.props.feed.addListener(_callFeed.CallFeedEvent.MuteStateChanged, this.onMuteStateChanged); if (this.props.feed.purpose === _callEventTypes.SDPStreamMetadataPurpose.Usermedia) { this.props.feed.measureVolumeActivity(true); } this.playMedia(); } } async playMedia() { const element = this.element; if (!element) return; // We play audio in AudioFeed, not here element.muted = true; element.srcObject = this.props.feed.stream; element.autoplay = true; try { // A note on calling methods on media elements: // We used to have queues per media element to serialise all calls on those elements. // The reason given for this was that load() and play() were racing. However, we now // never call load() explicitly so this seems unnecessary. However, serialising every // operation was causing bugs where video would not resume because some play command // had got stuck and all media operations were queued up behind it. If necessary, we // should serialise the ones that need to be serialised but then be able to interrupt // them with another load() which will cancel the pending one, but since we don't call // load() explicitly, it shouldn't be a problem. - Dave await element.play(); } catch (e) { _logger.logger.info(`Failed to play media element with feed for userId ` + `${this.props.feed.userId} with purpose ${this.props.feed.purpose}`, e); } } stopMedia() { const element = this.element; if (!element) return; element.pause(); element.removeAttribute("src"); // As per comment in componentDidMount, setting the sink ID back to the // default once the call is over makes setSinkId work reliably. - Dave // Since we are not using the same element anymore, the above doesn't // seem to be necessary - Šimon } render() { const { pipMode, primary, secondary, feed } = this.props; const wrapperClasses = (0, _classnames.default)("mx_VideoFeed", { mx_VideoFeed_primary: primary, mx_VideoFeed_secondary: secondary, mx_VideoFeed_voice: this.state.videoMuted }); const micIconClasses = (0, _classnames.default)("mx_VideoFeed_mic", { mx_VideoFeed_mic_muted: this.state.audioMuted, mx_VideoFeed_mic_unmuted: !this.state.audioMuted }); let micIcon; if (feed.purpose !== _callEventTypes.SDPStreamMetadataPurpose.Screenshare && !pipMode) { micIcon = /*#__PURE__*/_react.default.createElement("div", { className: micIconClasses }); } let content; if (this.state.videoMuted) { const callRoomId = _LegacyCallHandler.default.instance.roomIdForCall(this.props.call); const callRoom = (callRoomId ? _MatrixClientPeg.MatrixClientPeg.safeGet().getRoom(callRoomId) : undefined) ?? undefined; let avatarSize; if (pipMode && primary) avatarSize = "76px";else if (pipMode && !primary) avatarSize = "16px";else if (!pipMode && primary) avatarSize = "160px";else ; // TBD content = /*#__PURE__*/_react.default.createElement(_RoomAvatar.default, { room: callRoom, size: avatarSize }); } else { const videoClasses = (0, _classnames.default)("mx_VideoFeed_video", { mx_VideoFeed_video_mirror: this.props.feed.isLocal() && this.props.feed.purpose === _callEventTypes.SDPStreamMetadataPurpose.Usermedia && _SettingsStore.default.getValue("VideoView.flipVideoHorizontally") }); content = /*#__PURE__*/_react.default.createElement("video", { className: videoClasses, ref: this.setElementRef }); } return /*#__PURE__*/_react.default.createElement("div", { className: wrapperClasses }, micIcon, content); } } exports.default = VideoFeed; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY2xhc3NuYW1lcyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX3JlYWN0IiwiX2NhbGxGZWVkIiwiX2xvZ2dlciIsIl9jYWxsRXZlbnRUeXBlcyIsIl9TZXR0aW5nc1N0b3JlIiwiX0xlZ2FjeUNhbGxIYW5kbGVyIiwiX01hdHJpeENsaWVudFBlZyIsIl9Sb29tQXZhdGFyIiwiVmlkZW9GZWVkIiwiUmVhY3QiLCJQdXJlQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0IiwiZWxlbWVudCIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJvblJlc2l6ZSIsImFkZEV2ZW50TGlzdGVuZXIiLCJzZXRTdGF0ZSIsImF1ZGlvTXV0ZWQiLCJmZWVkIiwiaXNBdWRpb011dGVkIiwidmlkZW9NdXRlZCIsImlzVmlkZW9NdXRlZCIsInBsYXlNZWRpYSIsImUiLCJpc0xvY2FsIiwic3RhdGUiLCJjb21wb25lbnREaWRNb3VudCIsInVwZGF0ZUZlZWQiLCJjb21wb25lbnRXaWxsVW5tb3VudCIsImNvbXBvbmVudERpZFVwZGF0ZSIsInByZXZQcm9wcyIsInByZXZTdGF0ZSIsInN0cmVhbSIsImdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyIsIm9sZEZlZWQiLCJuZXdGZWVkIiwicmVtb3ZlTGlzdGVuZXIiLCJDYWxsRmVlZEV2ZW50IiwiTmV3U3RyZWFtIiwib25OZXdTdHJlYW0iLCJNdXRlU3RhdGVDaGFuZ2VkIiwib25NdXRlU3RhdGVDaGFuZ2VkIiwicHVycG9zZSIsIlNEUFN0cmVhbU1ldGFkYXRhUHVycG9zZSIsIlVzZXJtZWRpYSIsIm1lYXN1cmVWb2x1bWVBY3Rpdml0eSIsInN0b3BNZWRpYSIsImFkZExpc3RlbmVyIiwibXV0ZWQiLCJzcmNPYmplY3QiLCJhdXRvcGxheSIsInBsYXkiLCJsb2dnZXIiLCJpbmZvIiwidXNlcklkIiwicGF1c2UiLCJyZW1vdmVBdHRyaWJ1dGUiLCJyZW5kZXIiLCJwaXBNb2RlIiwicHJpbWFyeSIsInNlY29uZGFyeSIsIndyYXBwZXJDbGFzc2VzIiwiY2xhc3NuYW1lcyIsIm14X1ZpZGVvRmVlZF9wcmltYXJ5IiwibXhfVmlkZW9GZWVkX3NlY29uZGFyeSIsIm14X1ZpZGVvRmVlZF92b2ljZSIsIm1pY0ljb25DbGFzc2VzIiwibXhfVmlkZW9GZWVkX21pY19tdXRlZCIsIm14X1ZpZGVvRmVlZF9taWNfdW5tdXRlZCIsIm1pY0ljb24iLCJTY3JlZW5zaGFyZSIsImNyZWF0ZUVsZW1lbnQiLCJjbGFzc05hbWUiLCJjb250ZW50IiwiY2FsbFJvb21JZCIsIkxlZ2FjeUNhbGxIYW5kbGVyIiwiaW5zdGFuY2UiLCJyb29tSWRGb3JDYWxsIiwiY2FsbCIsImNhbGxSb29tIiwiTWF0cml4Q2xpZW50UGVnIiwic2FmZUdldCIsImdldFJvb20iLCJ1bmRlZmluZWQiLCJhdmF0YXJTaXplIiwicm9vbSIsInNpemUiLCJ2aWRlb0NsYXNzZXMiLCJteF9WaWRlb0ZlZWRfdmlkZW9fbWlycm9yIiwiU2V0dGluZ3NTdG9yZSIsImdldFZhbHVlIiwicmVmIiwic2V0RWxlbWVudFJlZiIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy92aWV3cy92b2lwL1ZpZGVvRmVlZC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjEsIDIwMjIgxaBpbW9uIEJyYW5kbmVyIDxzaW1vbi5icmEuYWdAZ21haWwuY29tPlxuQ29weXJpZ2h0IDIwMTUsIDIwMTYgLCAyMDE5LCAyMDIwLCAyMDIxIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBjbGFzc25hbWVzIGZyb20gXCJjbGFzc25hbWVzXCI7XG5pbXBvcnQgeyBNYXRyaXhDYWxsIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL3dlYnJ0Yy9jYWxsXCI7XG5pbXBvcnQgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBDYWxsRmVlZCwgQ2FsbEZlZWRFdmVudCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy93ZWJydGMvY2FsbEZlZWRcIjtcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9sb2dnZXJcIjtcbmltcG9ydCB7IFNEUFN0cmVhbU1ldGFkYXRhUHVycG9zZSB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy93ZWJydGMvY2FsbEV2ZW50VHlwZXNcIjtcblxuaW1wb3J0IFNldHRpbmdzU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL1NldHRpbmdzU3RvcmVcIjtcbmltcG9ydCBMZWdhY3lDYWxsSGFuZGxlciBmcm9tIFwiLi4vLi4vLi4vTGVnYWN5Q2FsbEhhbmRsZXJcIjtcbmltcG9ydCB7IE1hdHJpeENsaWVudFBlZyB9IGZyb20gXCIuLi8uLi8uLi9NYXRyaXhDbGllbnRQZWdcIjtcbmltcG9ydCBSb29tQXZhdGFyIGZyb20gXCIuLi9hdmF0YXJzL1Jvb21BdmF0YXJcIjtcblxuaW50ZXJmYWNlIElQcm9wcyB7XG4gICAgY2FsbDogTWF0cml4Q2FsbDtcblxuICAgIGZlZWQ6IENhbGxGZWVkO1xuXG4gICAgLy8gV2hldGhlciB0aGlzIGNhbGwgdmlldyBpcyBmb3IgcGljdHVyZS1pbi1waWN0dXJlIG1vZGVcbiAgICAvLyBvdGhlcndpc2UsIGl0J3MgdGhlIGxhcmdlciBjYWxsIHZpZXcgd2hlbiB2aWV3aW5nIHRoZSByb29tIHRoZSBjYWxsIGlzIGluLlxuICAgIC8vIFRoaXMgaXMgc29ydCBvZiBhIHByb3h5IGZvciBhIG51bWJlciBvZiB0aGluZ3MgYnV0IHdlIGN1cnJlbnRseSBoYXZlIG5vXG4gICAgLy8gbmVlZCB0byBjb250cm9sIHRob3NlIHRoaW5ncyBzZXBhcmF0ZWx5LCBzbyB0aGlzIGlzIHNpbXBsZXIuXG4gICAgcGlwTW9kZT86IGJvb2xlYW47XG5cbiAgICAvLyBhIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCB3aGVuIHRoZSB2aWRlbyBlbGVtZW50IGlzIHJlc2l6ZWRcbiAgICAvLyBkdWUgdG8gYSBjaGFuZ2UgaW4gdmlkZW8gbWV0YWRhdGFcbiAgICBvblJlc2l6ZT86IChlOiBFdmVudCkgPT4gdm9pZDtcblxuICAgIHByaW1hcnk/OiBib29sZWFuO1xuICAgIHNlY29uZGFyeT86IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBJU3RhdGUge1xuICAgIGF1ZGlvTXV0ZWQ6IGJvb2xlYW47XG4gICAgdmlkZW9NdXRlZDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmlkZW9GZWVkIGV4dGVuZHMgUmVhY3QuUHVyZUNvbXBvbmVudDxJUHJvcHMsIElTdGF0ZT4ge1xuICAgIHByaXZhdGUgZWxlbWVudD86IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJvcHM6IElQcm9wcykge1xuICAgICAgICBzdXBlcihwcm9wcyk7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIGF1ZGlvTXV0ZWQ6IHRoaXMucHJvcHMuZmVlZC5pc0F1ZGlvTXV0ZWQoKSxcbiAgICAgICAgICAgIHZpZGVvTXV0ZWQ6IHRoaXMucHJvcHMuZmVlZC5pc1ZpZGVvTXV0ZWQoKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50RGlkTW91bnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMudXBkYXRlRmVlZChudWxsLCB0aGlzLnByb3BzLmZlZWQpO1xuICAgICAgICB0aGlzLnBsYXlNZWRpYSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBjb21wb25lbnRXaWxsVW5tb3VudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy51cGRhdGVGZWVkKHRoaXMucHJvcHMuZmVlZCwgbnVsbCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHM6IElQcm9wcywgcHJldlN0YXRlOiBJU3RhdGUpOiB2b2lkIHtcbiAgICAgICAgdGhpcy51cGRhdGVGZWVkKHByZXZQcm9wcy5mZWVkLCB0aGlzLnByb3BzLmZlZWQpO1xuICAgICAgICAvLyBJZiB0aGUgbXV0ZXMgc3RhdGUgaGFzIGNoYW5nZWQsIHdlIHRyeSB0byBwbGF5TWVkaWEoKVxuICAgICAgICBpZiAocHJldlN0YXRlLnZpZGVvTXV0ZWQgIT09IHRoaXMuc3RhdGUudmlkZW9NdXRlZCB8fCBwcmV2UHJvcHMuZmVlZC5zdHJlYW0gIT09IHRoaXMucHJvcHMuZmVlZC5zdHJlYW0pIHtcbiAgICAgICAgICAgIHRoaXMucGxheU1lZGlhKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyhwcm9wczogSVByb3BzKTogSVN0YXRlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGF1ZGlvTXV0ZWQ6IHByb3BzLmZlZWQuaXNBdWRpb011dGVkKCksXG4gICAgICAgICAgICB2aWRlb011dGVkOiBwcm9wcy5mZWVkLmlzVmlkZW9NdXRlZCgpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0RWxlbWVudFJlZiA9IChlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCA9PiB7XG4gICAgICAgIGlmICghZWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5lbGVtZW50Py5yZW1vdmVFdmVudExpc3RlbmVyKFwicmVzaXplXCIsIHRoaXMub25SZXNpemUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsIHRoaXMub25SZXNpemUpO1xuICAgIH07XG5cbiAgICBwcml2YXRlIHVwZGF0ZUZlZWQob2xkRmVlZDogQ2FsbEZlZWQgfCBudWxsLCBuZXdGZWVkOiBDYWxsRmVlZCB8IG51bGwpOiB2b2lkIHtcbiAgICAgICAgaWYgKG9sZEZlZWQgPT09IG5ld0ZlZWQpIHJldHVybjtcblxuICAgICAgICBpZiAob2xkRmVlZCkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5mZWVkLnJlbW92ZUxpc3RlbmVyKENhbGxGZWVkRXZlbnQuTmV3U3RyZWFtLCB0aGlzLm9uTmV3U3RyZWFtKTtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZmVlZC5yZW1vdmVMaXN0ZW5lcihDYWxsRmVlZEV2ZW50Lk11dGVTdGF0ZUNoYW5nZWQsIHRoaXMub25NdXRlU3RhdGVDaGFuZ2VkKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmZlZWQucHVycG9zZSA9PT0gU0RQU3RyZWFtTWV0YWRhdGFQdXJwb3NlLlVzZXJtZWRpYSkge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZmVlZC5tZWFzdXJlVm9sdW1lQWN0aXZpdHkoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdG9wTWVkaWEoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmV3RmVlZCkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5mZWVkLmFkZExpc3RlbmVyKENhbGxGZWVkRXZlbnQuTmV3U3RyZWFtLCB0aGlzLm9uTmV3U3RyZWFtKTtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZmVlZC5hZGRMaXN0ZW5lcihDYWxsRmVlZEV2ZW50Lk11dGVTdGF0ZUNoYW5nZWQsIHRoaXMub25NdXRlU3RhdGVDaGFuZ2VkKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmZlZWQucHVycG9zZSA9PT0gU0RQU3RyZWFtTWV0YWRhdGFQdXJwb3NlLlVzZXJtZWRpYSkge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZmVlZC5tZWFzdXJlVm9sdW1lQWN0aXZpdHkodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnBsYXlNZWRpYSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBwbGF5TWVkaWEoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQ7XG4gICAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuO1xuICAgICAgICAvLyBXZSBwbGF5IGF1ZGlvIGluIEF1ZGlvRmVlZCwgbm90IGhlcmVcbiAgICAgICAgZWxlbWVudC5tdXRlZCA9IHRydWU7XG4gICAgICAgIGVsZW1lbnQuc3JjT2JqZWN0ID0gdGhpcy5wcm9wcy5mZWVkLnN0cmVhbTtcbiAgICAgICAgZWxlbWVudC5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBBIG5vdGUgb24gY2FsbGluZyBtZXRob2RzIG9uIG1lZGlhIGVsZW1lbnRzOlxuICAgICAgICAgICAgLy8gV2UgdXNlZCB0byBoYXZlIHF1ZXVlcyBwZXIgbWVkaWEgZWxlbWVudCB0byBzZXJpYWxpc2UgYWxsIGNhbGxzIG9uIHRob3NlIGVsZW1lbnRzLlxuICAgICAgICAgICAgLy8gVGhlIHJlYXNvbiBnaXZlbiBmb3IgdGhpcyB3YXMgdGhhdCBsb2FkKCkgYW5kIHBsYXkoKSB3ZXJlIHJhY2luZy4gSG93ZXZlciwgd2Ugbm93XG4gICAgICAgICAgICAvLyBuZXZlciBjYWxsIGxvYWQoKSBleHBsaWNpdGx5IHNvIHRoaXMgc2VlbXMgdW5uZWNlc3NhcnkuIEhvd2V2ZXIsIHNlcmlhbGlzaW5nIGV2ZXJ5XG4gICAgICAgICAgICAvLyBvcGVyYXRpb24gd2FzIGNhdXNpbmcgYnVncyB3aGVyZSB2aWRlbyB3b3VsZCBub3QgcmVzdW1lIGJlY2F1c2Ugc29tZSBwbGF5IGNvbW1hbmRcbiAgICAgICAgICAgIC8vIGhhZCBnb3Qgc3R1Y2sgYW5kIGFsbCBtZWRpYSBvcGVyYXRpb25zIHdlcmUgcXVldWVkIHVwIGJlaGluZCBpdC4gSWYgbmVjZXNzYXJ5LCB3ZVxuICAgICAgICAgICAgLy8gc2hvdWxkIHNlcmlhbGlzZSB0aGUgb25lcyB0aGF0IG5lZWQgdG8gYmUgc2VyaWFsaXNlZCBidXQgdGhlbiBiZSBhYmxlIHRvIGludGVycnVwdFxuICAgICAgICAgICAgLy8gdGhlbSB3aXRoIGFub3RoZXIgbG9hZCgpIHdoaWNoIHdpbGwgY2FuY2VsIHRoZSBwZW5kaW5nIG9uZSwgYnV0IHNpbmNlIHdlIGRvbid0IGNhbGxcbiAgICAgICAgICAgIC8vIGxvYWQoKSBleHBsaWNpdGx5LCBpdCBzaG91bGRuJ3QgYmUgYSBwcm9ibGVtLiAtIERhdmVcbiAgICAgICAgICAgIGF3YWl0IGVsZW1lbnQucGxheSgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgICBgRmFpbGVkIHRvIHBsYXkgbWVkaWEgZWxlbWVudCB3aXRoIGZlZWQgZm9yIHVzZXJJZCBgICtcbiAgICAgICAgICAgICAgICAgICAgYCR7dGhpcy5wcm9wcy5mZWVkLnVzZXJJZH0gd2l0aCBwdXJwb3NlICR7dGhpcy5wcm9wcy5mZWVkLnB1cnBvc2V9YCxcbiAgICAgICAgICAgICAgICBlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3RvcE1lZGlhKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50O1xuICAgICAgICBpZiAoIWVsZW1lbnQpIHJldHVybjtcblxuICAgICAgICBlbGVtZW50LnBhdXNlKCk7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKFwic3JjXCIpO1xuXG4gICAgICAgIC8vIEFzIHBlciBjb21tZW50IGluIGNvbXBvbmVudERpZE1vdW50LCBzZXR0aW5nIHRoZSBzaW5rIElEIGJhY2sgdG8gdGhlXG4gICAgICAgIC8vIGRlZmF1bHQgb25jZSB0aGUgY2FsbCBpcyBvdmVyIG1ha2VzIHNldFNpbmtJZCB3b3JrIHJlbGlhYmx5LiAtIERhdmVcbiAgICAgICAgLy8gU2luY2Ugd2UgYXJlIG5vdCB1c2luZyB0aGUgc2FtZSBlbGVtZW50IGFueW1vcmUsIHRoZSBhYm92ZSBkb2Vzbid0XG4gICAgICAgIC8vIHNlZW0gdG8gYmUgbmVjZXNzYXJ5IC0gxaBpbW9uXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbk5ld1N0cmVhbSA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBhdWRpb011dGVkOiB0aGlzLnByb3BzLmZlZWQuaXNBdWRpb011dGVkKCksXG4gICAgICAgICAgICB2aWRlb011dGVkOiB0aGlzLnByb3BzLmZlZWQuaXNWaWRlb011dGVkKCksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBsYXlNZWRpYSgpO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uTXV0ZVN0YXRlQ2hhbmdlZCA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBhdWRpb011dGVkOiB0aGlzLnByb3BzLmZlZWQuaXNBdWRpb011dGVkKCksXG4gICAgICAgICAgICB2aWRlb011dGVkOiB0aGlzLnByb3BzLmZlZWQuaXNWaWRlb011dGVkKCksXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uUmVzaXplID0gKGU6IEV2ZW50KTogdm9pZCA9PiB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uUmVzaXplICYmICF0aGlzLnByb3BzLmZlZWQuaXNMb2NhbCgpKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uUmVzaXplKGUpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHB1YmxpYyByZW5kZXIoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgICAgICAgY29uc3QgeyBwaXBNb2RlLCBwcmltYXJ5LCBzZWNvbmRhcnksIGZlZWQgfSA9IHRoaXMucHJvcHM7XG5cbiAgICAgICAgY29uc3Qgd3JhcHBlckNsYXNzZXMgPSBjbGFzc25hbWVzKFwibXhfVmlkZW9GZWVkXCIsIHtcbiAgICAgICAgICAgIG14X1ZpZGVvRmVlZF9wcmltYXJ5OiBwcmltYXJ5LFxuICAgICAgICAgICAgbXhfVmlkZW9GZWVkX3NlY29uZGFyeTogc2Vjb25kYXJ5LFxuICAgICAgICAgICAgbXhfVmlkZW9GZWVkX3ZvaWNlOiB0aGlzLnN0YXRlLnZpZGVvTXV0ZWQsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBtaWNJY29uQ2xhc3NlcyA9IGNsYXNzbmFtZXMoXCJteF9WaWRlb0ZlZWRfbWljXCIsIHtcbiAgICAgICAgICAgIG14X1ZpZGVvRmVlZF9taWNfbXV0ZWQ6IHRoaXMuc3RhdGUuYXVkaW9NdXRlZCxcbiAgICAgICAgICAgIG14X1ZpZGVvRmVlZF9taWNfdW5tdXRlZDogIXRoaXMuc3RhdGUuYXVkaW9NdXRlZCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGV0IG1pY0ljb247XG4gICAgICAgIGlmIChmZWVkLnB1cnBvc2UgIT09IFNEUFN0cmVhbU1ldGFkYXRhUHVycG9zZS5TY3JlZW5zaGFyZSAmJiAhcGlwTW9kZSkge1xuICAgICAgICAgICAgbWljSWNvbiA9IDxkaXYgY2xhc3NOYW1lPXttaWNJY29uQ2xhc3Nlc30gLz47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgY29udGVudDtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUudmlkZW9NdXRlZCkge1xuICAgICAgICAgICAgY29uc3QgY2FsbFJvb21JZCA9IExlZ2FjeUNhbGxIYW5kbGVyLmluc3RhbmNlLnJvb21JZEZvckNhbGwodGhpcy5wcm9wcy5jYWxsKTtcbiAgICAgICAgICAgIGNvbnN0IGNhbGxSb29tID0gKGNhbGxSb29tSWQgPyBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLmdldFJvb20oY2FsbFJvb21JZCkgOiB1bmRlZmluZWQpID8/IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgbGV0IGF2YXRhclNpemU7XG4gICAgICAgICAgICBpZiAocGlwTW9kZSAmJiBwcmltYXJ5KSBhdmF0YXJTaXplID0gXCI3NnB4XCI7XG4gICAgICAgICAgICBlbHNlIGlmIChwaXBNb2RlICYmICFwcmltYXJ5KSBhdmF0YXJTaXplID0gXCIxNnB4XCI7XG4gICAgICAgICAgICBlbHNlIGlmICghcGlwTW9kZSAmJiBwcmltYXJ5KSBhdmF0YXJTaXplID0gXCIxNjBweFwiO1xuICAgICAgICAgICAgZWxzZTsgLy8gVEJEXG5cbiAgICAgICAgICAgIGNvbnRlbnQgPSA8Um9vbUF2YXRhciByb29tPXtjYWxsUm9vbX0gc2l6ZT17YXZhdGFyU2l6ZX0gLz47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB2aWRlb0NsYXNzZXMgPSBjbGFzc25hbWVzKFwibXhfVmlkZW9GZWVkX3ZpZGVvXCIsIHtcbiAgICAgICAgICAgICAgICBteF9WaWRlb0ZlZWRfdmlkZW9fbWlycm9yOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmZlZWQuaXNMb2NhbCgpICYmXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZmVlZC5wdXJwb3NlID09PSBTRFBTdHJlYW1NZXRhZGF0YVB1cnBvc2UuVXNlcm1lZGlhICYmXG4gICAgICAgICAgICAgICAgICAgIFNldHRpbmdzU3RvcmUuZ2V0VmFsdWUoXCJWaWRlb1ZpZXcuZmxpcFZpZGVvSG9yaXpvbnRhbGx5XCIpLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnRlbnQgPSA8dmlkZW8gY2xhc3NOYW1lPXt2aWRlb0NsYXNzZXN9IHJlZj17dGhpcy5zZXRFbGVtZW50UmVmfSAvPjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT17d3JhcHBlckNsYXNzZXN9PlxuICAgICAgICAgICAgICAgIHttaWNJY29ufVxuICAgICAgICAgICAgICAgIHtjb250ZW50fVxuICAgICAg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