UNPKG

matrix-react-sdk

Version:
238 lines (235 loc) 47 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 _react = _interopRequireWildcard(require("react")); var _call = require("matrix-js-sdk/src/webrtc/call"); var _classnames = _interopRequireDefault(require("classnames")); var _languageHandler = require("../../../languageHandler"); var _MemberAvatar = _interopRequireDefault(require("../avatars/MemberAvatar")); var _LegacyCallEventGrouper = require("../../structures/LegacyCallEventGrouper"); var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton")); var _InfoTooltip = _interopRequireWildcard(require("../elements/InfoTooltip")); var _DateUtils = require("../../../DateUtils"); var _Clock = _interopRequireDefault(require("../audio_messages/Clock")); 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 2021 Šimon Brandner <simon.bra.ag@gmail.com> SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ const MAX_NON_NARROW_WIDTH = 450 / 70 * 100; class LegacyCallEvent extends _react.default.PureComponent { constructor(props) { super(props); (0, _defineProperty2.default)(this, "wrapperElement", /*#__PURE__*/(0, _react.createRef)()); (0, _defineProperty2.default)(this, "resizeObserver", void 0); (0, _defineProperty2.default)(this, "onLengthChanged", length => { this.setState({ length }); }); (0, _defineProperty2.default)(this, "resizeObserverCallback", entries => { const wrapperElementEntry = entries.find(entry => entry.target === this.wrapperElement.current); if (!wrapperElementEntry) return; this.setState({ narrow: wrapperElementEntry.contentRect.width < MAX_NON_NARROW_WIDTH }); }); (0, _defineProperty2.default)(this, "onSilencedChanged", newState => { this.setState({ silenced: newState }); }); (0, _defineProperty2.default)(this, "onStateChanged", newState => { this.setState({ callState: newState }); }); this.state = { callState: this.props.callEventGrouper.state, silenced: false, narrow: false, length: 0 }; } componentDidMount() { this.props.callEventGrouper.addListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.StateChanged, this.onStateChanged); this.props.callEventGrouper.addListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.SilencedChanged, this.onSilencedChanged); this.props.callEventGrouper.addListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.LengthChanged, this.onLengthChanged); this.resizeObserver = new ResizeObserver(this.resizeObserverCallback); this.wrapperElement.current && this.resizeObserver.observe(this.wrapperElement.current); } componentWillUnmount() { this.props.callEventGrouper.removeListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.StateChanged, this.onStateChanged); this.props.callEventGrouper.removeListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.SilencedChanged, this.onSilencedChanged); this.props.callEventGrouper.removeListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.LengthChanged, this.onLengthChanged); this.resizeObserver?.disconnect(); } renderCallBackButton(text) { return /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { className: "mx_LegacyCallEvent_content_button mx_LegacyCallEvent_content_button_callBack", onClick: this.props.callEventGrouper.callBack, kind: "primary" }, /*#__PURE__*/_react.default.createElement("span", null, " ", text, " ")); } renderSilenceIcon() { const silenceClass = (0, _classnames.default)({ mx_LegacyCallEvent_iconButton: true, mx_LegacyCallEvent_unSilence: this.state.silenced, mx_LegacyCallEvent_silence: !this.state.silenced }); return /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { className: silenceClass, onClick: this.props.callEventGrouper.toggleSilenced, title: this.state.silenced ? (0, _languageHandler._t)("voip|unsilence") : (0, _languageHandler._t)("voip|silence") }); } renderContent() { if (this.state.callState === _call.CallState.Ringing) { let silenceIcon; if (!this.state.narrow) { silenceIcon = this.renderSilenceIcon(); } return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_content" }, silenceIcon, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { className: "mx_LegacyCallEvent_content_button mx_LegacyCallEvent_content_button_reject", onClick: this.props.callEventGrouper.rejectCall, kind: "danger" }, /*#__PURE__*/_react.default.createElement("span", null, " ", (0, _languageHandler._t)("action|decline"), " ")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { className: "mx_LegacyCallEvent_content_button mx_LegacyCallEvent_content_button_answer", onClick: this.props.callEventGrouper.answerCall, kind: "primary" }, /*#__PURE__*/_react.default.createElement("span", null, " ", (0, _languageHandler._t)("action|accept"), " ")), this.props.timestamp); } if (this.state.callState === _call.CallState.Ended) { const hangupReason = this.props.callEventGrouper.hangupReason; const gotRejected = this.props.callEventGrouper.gotRejected; if (gotRejected) { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_content" }, (0, _languageHandler._t)("timeline|m.call.invite|declined"), this.renderCallBackButton((0, _languageHandler._t)("timeline|m.call.invite|call_back_prompt")), this.props.timestamp); } else if (hangupReason === _call.CallErrorCode.AnsweredElsewhere) { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_content" }, (0, _languageHandler._t)("timeline|m.call.invite|answered_elsewhere"), this.props.timestamp); } else if (this.props.callEventGrouper.callWasMissed) { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_content" }, (0, _languageHandler._t)("timeline|m.call.invite|missed_call"), this.renderCallBackButton((0, _languageHandler._t)("timeline|m.call.invite|call_back_prompt")), this.props.timestamp); } else if (!hangupReason || [_call.CallErrorCode.UserHangup, "user hangup"].includes(hangupReason)) { // workaround for https://github.com/vector-im/element-web/issues/5178 // it seems Android randomly sets a reason of "user hangup" which is // interpreted as an error code :( // https://github.com/vector-im/riot-android/issues/2623 // Also the correct hangup code as of VoIP v1 (with underscore) // Also, if we don't have a reason const duration = this.props.callEventGrouper.duration; let text = (0, _languageHandler._t)("timeline|m.call.hangup|dm"); if (duration) { text += " • " + (0, _DateUtils.formatPreciseDuration)(duration); } return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_content" }, text, this.props.timestamp); } else if (hangupReason === _call.CallErrorCode.InviteTimeout) { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_content" }, (0, _languageHandler._t)("timeline|m.call.invite|no_answer"), this.renderCallBackButton((0, _languageHandler._t)("timeline|m.call.invite|call_back_prompt")), this.props.timestamp); } let reason; if (hangupReason === _call.CallErrorCode.IceFailed) { // We couldn't establish a connection at all reason = (0, _languageHandler._t)("timeline|m.call.invite|failed_connect_media"); } else if (hangupReason === "ice_timeout") { // We established a connection but it died reason = (0, _languageHandler._t)("timeline|m.call.invite|failed_connection"); } else if (hangupReason === _call.CallErrorCode.NoUserMedia) { // The other side couldn't open capture devices reason = (0, _languageHandler._t)("timeline|m.call.invite|failed_opponent_media"); } else if (hangupReason === "unknown_error") { // An error code the other side doesn't have a way to express // (as opposed to an error code they gave but we don't know about, // in which case we show the error code) reason = (0, _languageHandler._t)("timeline|m.call.invite|unknown_error"); } else if (hangupReason === _call.CallErrorCode.UserBusy) { reason = (0, _languageHandler._t)("voip|user_busy_description"); } else { reason = (0, _languageHandler._t)("timeline|m.call.invite|unknown_failure", { reason: hangupReason }); } return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_content" }, /*#__PURE__*/_react.default.createElement(_InfoTooltip.default, { tooltip: reason, className: "mx_LegacyCallEvent_content_tooltip", kind: _InfoTooltip.InfoTooltipKind.Warning }), (0, _languageHandler._t)("timeline|m.call.invite|failed_connection"), this.renderCallBackButton((0, _languageHandler._t)("action|retry")), this.props.timestamp); } if (this.state.callState === _call.CallState.Connected) { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_content" }, /*#__PURE__*/_react.default.createElement(_Clock.default, { seconds: this.state.length, "aria-live": "off" }), this.props.timestamp); } if (this.state.callState === _call.CallState.Connecting) { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_content" }, (0, _languageHandler._t)("voip|connecting"), this.props.timestamp); } return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_content" }, (0, _languageHandler._t)("timeline|m.call.invite|unknown_state"), this.props.timestamp); } render() { const event = this.props.mxEvent; const sender = event.sender ? event.sender.name : event.getSender(); const isVoice = this.props.callEventGrouper.isVoice; const callType = isVoice ? (0, _languageHandler._t)("voip|voice_call") : (0, _languageHandler._t)("voip|video_call"); const callState = this.state.callState; const hangupReason = this.props.callEventGrouper.hangupReason; const content = this.renderContent(); const className = (0, _classnames.default)("mx_LegacyCallEvent", { mx_LegacyCallEvent_voice: isVoice, mx_LegacyCallEvent_video: !isVoice, mx_LegacyCallEvent_narrow: this.state.narrow, mx_LegacyCallEvent_missed: this.props.callEventGrouper.callWasMissed, mx_LegacyCallEvent_noAnswer: callState === _call.CallState.Ended && hangupReason === _call.CallErrorCode.InviteTimeout, mx_LegacyCallEvent_rejected: callState === _call.CallState.Ended && this.props.callEventGrouper.gotRejected }); let silenceIcon; if (this.state.narrow && this.state.callState === _call.CallState.Ringing) { silenceIcon = this.renderSilenceIcon(); } return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_wrapper", ref: this.wrapperElement }, /*#__PURE__*/_react.default.createElement("div", { className: className }, silenceIcon, /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_info" }, /*#__PURE__*/_react.default.createElement(_MemberAvatar.default, { member: event.sender, size: "32px" }), /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_info_basic" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_sender" }, sender), /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_type" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_LegacyCallEvent_type_icon" }), callType))), content)); } } exports.default = LegacyCallEvent; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY2FsbCIsIl9jbGFzc25hbWVzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfTWVtYmVyQXZhdGFyIiwiX0xlZ2FjeUNhbGxFdmVudEdyb3VwZXIiLCJfQWNjZXNzaWJsZUJ1dHRvbiIsIl9JbmZvVG9vbHRpcCIsIl9EYXRlVXRpbHMiLCJfQ2xvY2siLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJNQVhfTk9OX05BUlJPV19XSURUSCIsIkxlZ2FjeUNhbGxFdmVudCIsIlJlYWN0IiwiUHVyZUNvbXBvbmVudCIsImNvbnN0cnVjdG9yIiwicHJvcHMiLCJfZGVmaW5lUHJvcGVydHkyIiwiY3JlYXRlUmVmIiwibGVuZ3RoIiwic2V0U3RhdGUiLCJlbnRyaWVzIiwid3JhcHBlckVsZW1lbnRFbnRyeSIsImZpbmQiLCJlbnRyeSIsInRhcmdldCIsIndyYXBwZXJFbGVtZW50IiwiY3VycmVudCIsIm5hcnJvdyIsImNvbnRlbnRSZWN0Iiwid2lkdGgiLCJuZXdTdGF0ZSIsInNpbGVuY2VkIiwiY2FsbFN0YXRlIiwic3RhdGUiLCJjYWxsRXZlbnRHcm91cGVyIiwiY29tcG9uZW50RGlkTW91bnQiLCJhZGRMaXN0ZW5lciIsIkxlZ2FjeUNhbGxFdmVudEdyb3VwZXJFdmVudCIsIlN0YXRlQ2hhbmdlZCIsIm9uU3RhdGVDaGFuZ2VkIiwiU2lsZW5jZWRDaGFuZ2VkIiwib25TaWxlbmNlZENoYW5nZWQiLCJMZW5ndGhDaGFuZ2VkIiwib25MZW5ndGhDaGFuZ2VkIiwicmVzaXplT2JzZXJ2ZXIiLCJSZXNpemVPYnNlcnZlciIsInJlc2l6ZU9ic2VydmVyQ2FsbGJhY2siLCJvYnNlcnZlIiwiY29tcG9uZW50V2lsbFVubW91bnQiLCJyZW1vdmVMaXN0ZW5lciIsImRpc2Nvbm5lY3QiLCJyZW5kZXJDYWxsQmFja0J1dHRvbiIsInRleHQiLCJjcmVhdGVFbGVtZW50IiwiY2xhc3NOYW1lIiwib25DbGljayIsImNhbGxCYWNrIiwia2luZCIsInJlbmRlclNpbGVuY2VJY29uIiwic2lsZW5jZUNsYXNzIiwiY2xhc3NOYW1lcyIsIm14X0xlZ2FjeUNhbGxFdmVudF9pY29uQnV0dG9uIiwibXhfTGVnYWN5Q2FsbEV2ZW50X3VuU2lsZW5jZSIsIm14X0xlZ2FjeUNhbGxFdmVudF9zaWxlbmNlIiwidG9nZ2xlU2lsZW5jZWQiLCJ0aXRsZSIsIl90IiwicmVuZGVyQ29udGVudCIsIkNhbGxTdGF0ZSIsIlJpbmdpbmciLCJzaWxlbmNlSWNvbiIsInJlamVjdENhbGwiLCJhbnN3ZXJDYWxsIiwidGltZXN0YW1wIiwiRW5kZWQiLCJoYW5ndXBSZWFzb24iLCJnb3RSZWplY3RlZCIsIkNhbGxFcnJvckNvZGUiLCJBbnN3ZXJlZEVsc2V3aGVyZSIsImNhbGxXYXNNaXNzZWQiLCJVc2VySGFuZ3VwIiwiaW5jbHVkZXMiLCJkdXJhdGlvbiIsImZvcm1hdFByZWNpc2VEdXJhdGlvbiIsIkludml0ZVRpbWVvdXQiLCJyZWFzb24iLCJJY2VGYWlsZWQiLCJOb1VzZXJNZWRpYSIsIlVzZXJCdXN5IiwidG9vbHRpcCIsIkluZm9Ub29sdGlwS2luZCIsIldhcm5pbmciLCJDb25uZWN0ZWQiLCJzZWNvbmRzIiwiQ29ubmVjdGluZyIsInJlbmRlciIsImV2ZW50IiwibXhFdmVudCIsInNlbmRlciIsIm5hbWUiLCJnZXRTZW5kZXIiLCJpc1ZvaWNlIiwiY2FsbFR5cGUiLCJjb250ZW50IiwibXhfTGVnYWN5Q2FsbEV2ZW50X3ZvaWNlIiwibXhfTGVnYWN5Q2FsbEV2ZW50X3ZpZGVvIiwibXhfTGVnYWN5Q2FsbEV2ZW50X25hcnJvdyIsIm14X0xlZ2FjeUNhbGxFdmVudF9taXNzZWQiLCJteF9MZWdhY3lDYWxsRXZlbnRfbm9BbnN3ZXIiLCJteF9MZWdhY3lDYWxsRXZlbnRfcmVqZWN0ZWQiLCJyZWYiLCJtZW1iZXIiLCJzaXplIiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL21lc3NhZ2VzL0xlZ2FjeUNhbGxFdmVudC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjEgxaBpbW9uIEJyYW5kbmVyIDxzaW1vbi5icmEuYWdAZ21haWwuY29tPlxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgUmVhY3QsIHsgY3JlYXRlUmVmIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBNYXRyaXhFdmVudCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcbmltcG9ydCB7IENhbGxFcnJvckNvZGUsIENhbGxTdGF0ZSB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy93ZWJydGMvY2FsbFwiO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSBcImNsYXNzbmFtZXNcIjtcblxuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgTWVtYmVyQXZhdGFyIGZyb20gXCIuLi9hdmF0YXJzL01lbWJlckF2YXRhclwiO1xuaW1wb3J0IExlZ2FjeUNhbGxFdmVudEdyb3VwZXIsIHsgTGVnYWN5Q2FsbEV2ZW50R3JvdXBlckV2ZW50IH0gZnJvbSBcIi4uLy4uL3N0cnVjdHVyZXMvTGVnYWN5Q2FsbEV2ZW50R3JvdXBlclwiO1xuaW1wb3J0IEFjY2Vzc2libGVCdXR0b24gZnJvbSBcIi4uL2VsZW1lbnRzL0FjY2Vzc2libGVCdXR0b25cIjtcbmltcG9ydCBJbmZvVG9vbHRpcCwgeyBJbmZvVG9vbHRpcEtpbmQgfSBmcm9tIFwiLi4vZWxlbWVudHMvSW5mb1Rvb2x0aXBcIjtcbmltcG9ydCB7IGZvcm1hdFByZWNpc2VEdXJhdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9EYXRlVXRpbHNcIjtcbmltcG9ydCBDbG9jayBmcm9tIFwiLi4vYXVkaW9fbWVzc2FnZXMvQ2xvY2tcIjtcblxuY29uc3QgTUFYX05PTl9OQVJST1dfV0lEVEggPSAoNDUwIC8gNzApICogMTAwO1xuXG5pbnRlcmZhY2UgSVByb3BzIHtcbiAgICBteEV2ZW50OiBNYXRyaXhFdmVudDtcbiAgICBjYWxsRXZlbnRHcm91cGVyOiBMZWdhY3lDYWxsRXZlbnRHcm91cGVyO1xuICAgIHRpbWVzdGFtcD86IEpTWC5FbGVtZW50O1xufVxuXG5pbnRlcmZhY2UgSVN0YXRlIHtcbiAgICBjYWxsU3RhdGU/OiBDYWxsU3RhdGU7XG4gICAgc2lsZW5jZWQ6IGJvb2xlYW47XG4gICAgbmFycm93OiBib29sZWFuO1xuICAgIGxlbmd0aDogbnVtYmVyO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMZWdhY3lDYWxsRXZlbnQgZXh0ZW5kcyBSZWFjdC5QdXJlQ29tcG9uZW50PElQcm9wcywgSVN0YXRlPiB7XG4gICAgcHJpdmF0ZSB3cmFwcGVyRWxlbWVudCA9IGNyZWF0ZVJlZjxIVE1MRGl2RWxlbWVudD4oKTtcbiAgICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyPzogUmVzaXplT2JzZXJ2ZXI7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJvcHM6IElQcm9wcykge1xuICAgICAgICBzdXBlcihwcm9wcyk7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIGNhbGxTdGF0ZTogdGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLnN0YXRlLFxuICAgICAgICAgICAgc2lsZW5jZWQ6IGZhbHNlLFxuICAgICAgICAgICAgbmFycm93OiBmYWxzZSxcbiAgICAgICAgICAgIGxlbmd0aDogMCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50RGlkTW91bnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5hZGRMaXN0ZW5lcihMZWdhY3lDYWxsRXZlbnRHcm91cGVyRXZlbnQuU3RhdGVDaGFuZ2VkLCB0aGlzLm9uU3RhdGVDaGFuZ2VkKTtcbiAgICAgICAgdGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLmFkZExpc3RlbmVyKExlZ2FjeUNhbGxFdmVudEdyb3VwZXJFdmVudC5TaWxlbmNlZENoYW5nZWQsIHRoaXMub25TaWxlbmNlZENoYW5nZWQpO1xuICAgICAgICB0aGlzLnByb3BzLmNhbGxFdmVudEdyb3VwZXIuYWRkTGlzdGVuZXIoTGVnYWN5Q2FsbEV2ZW50R3JvdXBlckV2ZW50Lkxlbmd0aENoYW5nZWQsIHRoaXMub25MZW5ndGhDaGFuZ2VkKTtcblxuICAgICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKHRoaXMucmVzaXplT2JzZXJ2ZXJDYWxsYmFjayk7XG4gICAgICAgIHRoaXMud3JhcHBlckVsZW1lbnQuY3VycmVudCAmJiB0aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy53cmFwcGVyRWxlbWVudC5jdXJyZW50KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50V2lsbFVubW91bnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5yZW1vdmVMaXN0ZW5lcihMZWdhY3lDYWxsRXZlbnRHcm91cGVyRXZlbnQuU3RhdGVDaGFuZ2VkLCB0aGlzLm9uU3RhdGVDaGFuZ2VkKTtcbiAgICAgICAgdGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLnJlbW92ZUxpc3RlbmVyKExlZ2FjeUNhbGxFdmVudEdyb3VwZXJFdmVudC5TaWxlbmNlZENoYW5nZWQsIHRoaXMub25TaWxlbmNlZENoYW5nZWQpO1xuICAgICAgICB0aGlzLnByb3BzLmNhbGxFdmVudEdyb3VwZXIucmVtb3ZlTGlzdGVuZXIoTGVnYWN5Q2FsbEV2ZW50R3JvdXBlckV2ZW50Lkxlbmd0aENoYW5nZWQsIHRoaXMub25MZW5ndGhDaGFuZ2VkKTtcblxuICAgICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkxlbmd0aENoYW5nZWQgPSAobGVuZ3RoOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxlbmd0aCB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSByZXNpemVPYnNlcnZlckNhbGxiYWNrID0gKGVudHJpZXM6IFJlc2l6ZU9ic2VydmVyRW50cnlbXSk6IHZvaWQgPT4ge1xuICAgICAgICBjb25zdCB3cmFwcGVyRWxlbWVudEVudHJ5ID0gZW50cmllcy5maW5kKChlbnRyeSkgPT4gZW50cnkudGFyZ2V0ID09PSB0aGlzLndyYXBwZXJFbGVtZW50LmN1cnJlbnQpO1xuICAgICAgICBpZiAoIXdyYXBwZXJFbGVtZW50RW50cnkpIHJldHVybjtcblxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbmFycm93OiB3cmFwcGVyRWxlbWVudEVudHJ5LmNvbnRlbnRSZWN0LndpZHRoIDwgTUFYX05PTl9OQVJST1dfV0lEVEggfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25TaWxlbmNlZENoYW5nZWQgPSAobmV3U3RhdGU6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNpbGVuY2VkOiBuZXdTdGF0ZSB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblN0YXRlQ2hhbmdlZCA9IChuZXdTdGF0ZTogQ2FsbFN0YXRlKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjYWxsU3RhdGU6IG5ld1N0YXRlIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIHJlbmRlckNhbGxCYWNrQnV0dG9uKHRleHQ6IHN0cmluZyk6IEpTWC5FbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2NvbnRlbnRfYnV0dG9uIG14X0xlZ2FjeUNhbGxFdmVudF9jb250ZW50X2J1dHRvbl9jYWxsQmFja1wiXG4gICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLmNhbGxCYWNrfVxuICAgICAgICAgICAgICAgIGtpbmQ9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3Bhbj4ge3RleHR9IDwvc3Bhbj5cbiAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbmRlclNpbGVuY2VJY29uKCk6IEpTWC5FbGVtZW50IHtcbiAgICAgICAgY29uc3Qgc2lsZW5jZUNsYXNzID0gY2xhc3NOYW1lcyh7XG4gICAgICAgICAgICBteF9MZWdhY3lDYWxsRXZlbnRfaWNvbkJ1dHRvbjogdHJ1ZSxcbiAgICAgICAgICAgIG14X0xlZ2FjeUNhbGxFdmVudF91blNpbGVuY2U6IHRoaXMuc3RhdGUuc2lsZW5jZWQsXG4gICAgICAgICAgICBteF9MZWdhY3lDYWxsRXZlbnRfc2lsZW5jZTogIXRoaXMuc3RhdGUuc2lsZW5jZWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17c2lsZW5jZUNsYXNzfVxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci50b2dnbGVTaWxlbmNlZH1cbiAgICAgICAgICAgICAgICB0aXRsZT17dGhpcy5zdGF0ZS5zaWxlbmNlZCA/IF90KFwidm9pcHx1bnNpbGVuY2VcIikgOiBfdChcInZvaXB8c2lsZW5jZVwiKX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZW5kZXJDb250ZW50KCk6IEpTWC5FbGVtZW50IHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuY2FsbFN0YXRlID09PSBDYWxsU3RhdGUuUmluZ2luZykge1xuICAgICAgICAgICAgbGV0IHNpbGVuY2VJY29uO1xuICAgICAgICAgICAgaWYgKCF0aGlzLnN0YXRlLm5hcnJvdykge1xuICAgICAgICAgICAgICAgIHNpbGVuY2VJY29uID0gdGhpcy5yZW5kZXJTaWxlbmNlSWNvbigpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2NvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAge3NpbGVuY2VJY29ufVxuICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2NvbnRlbnRfYnV0dG9uIG14X0xlZ2FjeUNhbGxFdmVudF9jb250ZW50X2J1dHRvbl9yZWplY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLnJlamVjdENhbGx9XG4gICAgICAgICAgICAgICAgICAgICAgICBraW5kPVwiZGFuZ2VyXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+IHtfdChcImFjdGlvbnxkZWNsaW5lXCIpfSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X0xlZ2FjeUNhbGxFdmVudF9jb250ZW50X2J1dHRvbiBteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudF9idXR0b25fYW5zd2VyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5hbnN3ZXJDYWxsfVxuICAgICAgICAgICAgICAgICAgICAgICAga2luZD1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj4ge190KFwiYWN0aW9ufGFjY2VwdFwiKX0gPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnRpbWVzdGFtcH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuY2FsbFN0YXRlID09PSBDYWxsU3RhdGUuRW5kZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGhhbmd1cFJlYXNvbiA9IHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5oYW5ndXBSZWFzb247XG4gICAgICAgICAgICBjb25zdCBnb3RSZWplY3RlZCA9IHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5nb3RSZWplY3RlZDtcblxuICAgICAgICAgICAgaWYgKGdvdFJlamVjdGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxkZWNsaW5lZFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnJlbmRlckNhbGxCYWNrQnV0dG9uKF90KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxjYWxsX2JhY2tfcHJvbXB0XCIpKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnRpbWVzdGFtcH1cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaGFuZ3VwUmVhc29uID09PSBDYWxsRXJyb3JDb2RlLkFuc3dlcmVkRWxzZXdoZXJlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxhbnN3ZXJlZF9lbHNld2hlcmVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy50aW1lc3RhbXB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5jYWxsV2FzTWlzc2VkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxtaXNzZWRfY2FsbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnJlbmRlckNhbGxCYWNrQnV0dG9uKF90KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxjYWxsX2JhY2tfcHJvbXB0XCIpKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnRpbWVzdGFtcH1cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWhhbmd1cFJlYXNvbiB8fCBbQ2FsbEVycm9yQ29kZS5Vc2VySGFuZ3VwLCBcInVzZXIgaGFuZ3VwXCJdLmluY2x1ZGVzKGhhbmd1cFJlYXNvbikpIHtcbiAgICAgICAgICAgICAgICAvLyB3b3JrYXJvdW5kIGZvciBodHRwczovL2dpdGh1Yi5jb20vdmVjdG9yLWltL2VsZW1lbnQtd2ViL2lzc3Vlcy81MTc4XG4gICAgICAgICAgICAgICAgLy8gaXQgc2VlbXMgQW5kcm9pZCByYW5kb21seSBzZXRzIGEgcmVhc29uIG9mIFwidXNlciBoYW5ndXBcIiB3aGljaCBpc1xuICAgICAgICAgICAgICAgIC8vIGludGVycHJldGVkIGFzIGFuIGVycm9yIGNvZGUgOihcbiAgICAgICAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vdmVjdG9yLWltL3Jpb3QtYW5kcm9pZC9pc3N1ZXMvMjYyM1xuICAgICAgICAgICAgICAgIC8vIEFsc28gdGhlIGNvcnJlY3QgaGFuZ3VwIGNvZGUgYXMgb2YgVm9JUCB2MSAod2l0aCB1bmRlcnNjb3JlKVxuICAgICAgICAgICAgICAgIC8vIEFsc28sIGlmIHdlIGRvbid0IGhhdmUgYSByZWFzb25cbiAgICAgICAgICAgICAgICBjb25zdCBkdXJhdGlvbiA9IHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5kdXJhdGlvbiE7XG4gICAgICAgICAgICAgICAgbGV0IHRleHQgPSBfdChcInRpbWVsaW5lfG0uY2FsbC5oYW5ndXB8ZG1cIik7XG4gICAgICAgICAgICAgICAgaWYgKGR1cmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHQgKz0gXCIg4oCiIFwiICsgZm9ybWF0UHJlY2lzZUR1cmF0aW9uKGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3RleHR9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy50aW1lc3RhbXB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGhhbmd1cFJlYXNvbiA9PT0gQ2FsbEVycm9yQ29kZS5JbnZpdGVUaW1lb3V0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxub19hbnN3ZXJcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5yZW5kZXJDYWxsQmFja0J1dHRvbihfdChcInRpbWVsaW5lfG0uY2FsbC5pbnZpdGV8Y2FsbF9iYWNrX3Byb21wdFwiKSl9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy50aW1lc3RhbXB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCByZWFzb247XG4gICAgICAgICAgICBpZiAoaGFuZ3VwUmVhc29uID09PSBDYWxsRXJyb3JDb2RlLkljZUZhaWxlZCkge1xuICAgICAgICAgICAgICAgIC8vIFdlIGNvdWxkbid0IGVzdGFibGlzaCBhIGNvbm5lY3Rpb24gYXQgYWxsXG4gICAgICAgICAgICAgICAgcmVhc29uID0gX3QoXCJ0aW1lbGluZXxtLmNhbGwuaW52aXRlfGZhaWxlZF9jb25uZWN0X21lZGlhXCIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChoYW5ndXBSZWFzb24gPT09IFwiaWNlX3RpbWVvdXRcIikge1xuICAgICAgICAgICAgICAgIC8vIFdlIGVzdGFibGlzaGVkIGEgY29ubmVjdGlvbiBidXQgaXQgZGllZFxuICAgICAgICAgICAgICAgIHJlYXNvbiA9IF90KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxmYWlsZWRfY29ubmVjdGlvblwiKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaGFuZ3VwUmVhc29uID09PSBDYWxsRXJyb3JDb2RlLk5vVXNlck1lZGlhKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIG90aGVyIHNpZGUgY291bGRuJ3Qgb3BlbiBjYXB0dXJlIGRldmljZXNcbiAgICAgICAgICAgICAgICByZWFzb24gPSBfdChcInRpbWVsaW5lfG0uY2FsbC5pbnZpdGV8ZmFpbGVkX29wcG9uZW50X21lZGlhXCIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChoYW5ndXBSZWFzb24gPT09IFwidW5rbm93bl9lcnJvclwiKSB7XG4gICAgICAgICAgICAgICAgLy8gQW4gZXJyb3IgY29kZSB0aGUgb3RoZXIgc2lkZSBkb2Vzbid0IGhhdmUgYSB3YXkgdG8gZXhwcmVzc1xuICAgICAgICAgICAgICAgIC8vIChhcyBvcHBvc2VkIHRvIGFuIGVycm9yIGNvZGUgdGhleSBnYXZlIGJ1dCB3ZSBkb24ndCBrbm93IGFib3V0LFxuICAgICAgICAgICAgICAgIC8vIGluIHdoaWNoIGNhc2Ugd2Ugc2hvdyB0aGUgZXJyb3IgY29kZSlcbiAgICAgICAgICAgICAgICByZWFzb24gPSBfdChcInRpbWVsaW5lfG0uY2FsbC5pbnZpdGV8dW5rbm93bl9lcnJvclwiKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaGFuZ3VwUmVhc29uID09PSBDYWxsRXJyb3JDb2RlLlVzZXJCdXN5KSB7XG4gICAgICAgICAgICAgICAgcmVhc29uID0gX3QoXCJ2b2lwfHVzZXJfYnVzeV9kZXNjcmlwdGlvblwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVhc29uID0gX3QoXCJ0aW1lbGluZXxtLmNhbGwuaW52aXRlfHVua25vd25fZmFpbHVyZVwiLCB7IHJlYXNvbjogaGFuZ3VwUmVhc29uIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2NvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPEluZm9Ub29sdGlwXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwPXtyZWFzb259XG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudF90b29sdGlwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ9e0luZm9Ub29sdGlwS2luZC5XYXJuaW5nfVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJ0aW1lbGluZXxtLmNhbGwuaW52aXRlfGZhaWxlZF9jb25uZWN0aW9uXCIpfVxuICAgICAgICAgICAgICAgICAgICB7dGhpcy5yZW5kZXJDYWxsQmFja0J1dHRvbihfdChcImFjdGlvbnxyZXRyeVwiKSl9XG4gICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnRpbWVzdGFtcH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuY2FsbFN0YXRlID09PSBDYWxsU3RhdGUuQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2NvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPENsb2NrIHNlY29uZHM9e3RoaXMuc3RhdGUubGVuZ3RofSBhcmlhLWxpdmU9XCJvZmZcIiAvPlxuICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy50aW1lc3RhbXB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmNhbGxTdGF0ZSA9PT0gQ2FsbFN0YXRlLkNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJ2b2lwfGNvbm5lY3RpbmdcIil9XG4gICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnRpbWVzdGFtcH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgIHtfdChcInRpbWVsaW5lfG0uY2FsbC5pbnZpdGV8dW5rbm93bl9zdGF0ZVwiKX1cbiAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy50aW1lc3RhbXB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVuZGVyKCk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5wcm9wcy5teEV2ZW50O1xuICAgICAgICBjb25zdCBzZW5kZXIgPSBldmVudC5zZW5kZXIgPyBldmVudC5zZW5kZXIubmFtZSA6IGV2ZW50LmdldFNlbmRlcigpO1xuICAgICAgICBjb25zdCBpc1ZvaWNlID0gdGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLmlzVm9pY2U7XG4gICAgICAgIGNvbnN0IGNhbGxUeXBlID0gaXNWb2ljZSA/IF90KFwidm9pcHx2b2ljZV9jYWxsXCIpIDogX3QoXCJ2b2lwfHZpZGVvX2NhbGxcIik7XG4gICAgICAgIGNvbnN0IGNhbGxTdGF0ZSA9IHRoaXMuc3RhdGUuY2FsbFN0YXRlO1xuICAgICAgICBjb25zdCBoYW5ndXBSZWFzb24gPSB0aGlzLnByb3BzLmNhbGxFdmVudEdyb3VwZXIuaGFuZ3VwUmVhc29uO1xuICAgICAgICBjb25zdCBjb250ZW50ID0gdGhpcy5yZW5kZXJDb250ZW50KCk7XG4gICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IGNsYXNzTmFtZXMoXCJteF9MZWdhY3lDYWxsRXZlbnRcIiwge1xuICAgICAgICAgICAgbXhfTGVnYWN5Q2FsbEV2ZW50X3ZvaWNlOiBpc1ZvaWNlLFxuICAgICAgICAgICAgbXhfTGVnYWN5Q2FsbEV2ZW50X3ZpZGVvOiAhaXNWb2ljZSxcbiAgICAgICAgICAgIG14X0xlZ2FjeUNhbGxFdmVudF9uYXJyb3c6IHRoaXMuc3RhdGUubmFycm93LFxuICAgICAgICAgICAgbXhfTGVnYWN5Q2FsbEV2ZW50X21pc3NlZDogdGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLmNhbGxXYXNNaXNzZWQsXG4gICAgICAgICAgICBteF9MZWdhY3lDYWxsRXZlbnRfbm9BbnN3ZXI6IGNhbGxTdGF0ZSA9PT0gQ2FsbFN0YXRlLkVuZGVkICYmIGhhbmd1cFJlYXNvbiA9PT0gQ2FsbEVycm9yQ29kZS5JbnZpdGVUaW1lb3V0LFxuICAgICAgICAgICAgbXhfTGVnYWN5Q2FsbEV2ZW50X3JlamVjdGVkOiBjYWxsU3RhdGUgPT09IENhbGxTdGF0ZS5FbmRlZCAmJiB0aGlzLnByb3BzLmNhbGxFdmVudEdyb3VwZXIuZ290UmVqZWN0ZWQsXG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgc2lsZW5jZUljb247XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLm5hcnJvdyAmJiB0aGlzLnN0YXRlLmNhbGxTdGF0ZSA9PT0gQ2FsbFN0YXRlLlJpbmdpbmcpIHtcbiAgICAgICAgICAgIHNpbGVuY2VJY29uID0gdGhpcy5yZW5kZXJTaWxlbmNlSWNvbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X3dyYXBwZXJcIiByZWY9e3RoaXMud3JhcHBlckVsZW1lbnR9PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtjbGFzc05hbWV9PlxuICAgICAgICAgICAgICAgICAgICB7c2lsZW5jZUljb259XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2luZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxNZW1iZXJBdmF0YXIgbWVtYmVyPXtldmVudC5zZW5kZXJ9IHNpemU9XCIzMnB4XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2luZm9fYmFzaWNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X0xlZ2FjeUNhbGxFdmVudF9zZW5kZXJcIj57c2VuZGVyfTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X3R5cGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfdHlwZV9pY29uXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2NhbGxUeXBlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB7Y29udGVudH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFRQSxJ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