UNPKG

matrix-react-sdk

Version:
224 lines (219 loc) 34.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.READ_AVATAR_SIZE = void 0; exports.ReadReceiptGroup = ReadReceiptGroup; exports.ReadReceiptPerson = ReadReceiptPerson; exports.determineAvatarPosition = determineAvatarPosition; exports.readReceiptTooltip = readReceiptTooltip; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _react = _interopRequireDefault(require("react")); var _compoundWeb = require("@vector-im/compound-web"); var _ReadReceiptMarker = _interopRequireDefault(require("./ReadReceiptMarker")); var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton")); var _MemberAvatar = _interopRequireDefault(require("../avatars/MemberAvatar")); var _AutoHideScrollbar = _interopRequireDefault(require("../../structures/AutoHideScrollbar")); var _DateUtils = require("../../../DateUtils"); var _actions = require("../../../dispatcher/actions"); var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher")); var _ContextMenu = _interopRequireWildcard(require("../../structures/ContextMenu")); var _languageHandler = require("../../../languageHandler"); var _RovingTabIndex = require("../../../accessibility/RovingTabIndex"); var _FormattingUtils = require("../../../utils/FormattingUtils"); 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 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. */ // #20547 Design specified that we should show the three latest read receipts const MAX_READ_AVATARS_PLUS_N = 3; // #21935 If we’ve got just 4, don’t show +1, just show all of them const MAX_READ_AVATARS = MAX_READ_AVATARS_PLUS_N + 1; const READ_AVATAR_OFFSET = 10; const READ_AVATAR_SIZE = exports.READ_AVATAR_SIZE = 16; function determineAvatarPosition(index, max) { if (index < max) { return { hidden: false, position: index }; } else { return { hidden: true, position: 0 }; } } function readReceiptTooltip(members, maxAvatars) { return (0, _FormattingUtils.formatList)(members, maxAvatars); } function ReadReceiptGroup({ readReceipts, readReceiptMap, checkUnmounting, suppressAnimation, isTwelveHour }) { const [menuDisplayed, button, openMenu, closeMenu] = (0, _ContextMenu.useContextMenu)(); // If we are above MAX_READ_AVATARS, we’ll have to remove a few to have space for the +n count. const hasMore = readReceipts.length > MAX_READ_AVATARS; const maxAvatars = hasMore ? MAX_READ_AVATARS_PLUS_N : MAX_READ_AVATARS; const tooltipMembers = readReceipts.map(it => it.roomMember?.name ?? it.userId); const tooltipText = readReceiptTooltip(tooltipMembers, maxAvatars); // return early if there are no read receipts if (readReceipts.length === 0) { // We currently must include `mx_ReadReceiptGroup_container` in // the DOM of all events, as it is the positioned parent of the // animated read receipts. We can't let it unmount when a receipt // moves events, so for now we mount it for all events. Without // it, the animation will start from the top of the timeline // (because it lost its container). // See also https://github.com/vector-im/element-web/issues/17561 return /*#__PURE__*/_react.default.createElement("div", { className: "mx_EventTile_msgOption" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_ReadReceiptGroup" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_ReadReceiptGroup_button" }, /*#__PURE__*/_react.default.createElement("span", { className: "mx_ReadReceiptGroup_container" })))); } const avatars = readReceipts.map((receipt, index) => { const { hidden, position } = determineAvatarPosition(index, maxAvatars); const userId = receipt.userId; let readReceiptPosition; if (readReceiptMap) { readReceiptPosition = readReceiptMap[userId]; if (!readReceiptPosition) { readReceiptPosition = {}; readReceiptMap[userId] = readReceiptPosition; } } return /*#__PURE__*/_react.default.createElement(_ReadReceiptMarker.default, { key: userId, member: receipt.roomMember, fallbackUserId: userId, offset: position * READ_AVATAR_OFFSET, hidden: hidden, readReceiptPosition: readReceiptPosition, checkUnmounting: checkUnmounting, suppressAnimation: suppressAnimation, timestamp: receipt.ts, showTwelveHour: isTwelveHour }); }).reverse(); let remText; const remainder = readReceipts.length - maxAvatars; if (remainder > 0) { remText = /*#__PURE__*/_react.default.createElement("span", { className: "mx_ReadReceiptGroup_remainder", "aria-live": "off" }, "+", remainder); } let contextMenu; if (menuDisplayed && button.current) { const buttonRect = button.current.getBoundingClientRect(); contextMenu = /*#__PURE__*/_react.default.createElement(_ContextMenu.default, (0, _extends2.default)({ menuClassName: "mx_ReadReceiptGroup_popup", onFinished: closeMenu }, (0, _ContextMenu.aboveLeftOf)(buttonRect)), /*#__PURE__*/_react.default.createElement(_AutoHideScrollbar.default, null, /*#__PURE__*/_react.default.createElement(SectionHeader, { className: "mx_ReadReceiptGroup_title" }, (0, _languageHandler._t)("timeline|read_receipt_title", { count: readReceipts.length })), readReceipts.map(receipt => /*#__PURE__*/_react.default.createElement(ReadReceiptPerson, (0, _extends2.default)({ key: receipt.userId }, receipt, { isTwelveHour: isTwelveHour, onAfterClick: closeMenu }))))); } return /*#__PURE__*/_react.default.createElement("div", { className: "mx_EventTile_msgOption" }, /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: (0, _languageHandler._t)("timeline|read_receipt_title", { count: readReceipts.length }), caption: tooltipText, placement: "top-end" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_ReadReceiptGroup", role: "group", "aria-label": (0, _languageHandler._t)("timeline|read_receipts_label") }, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { className: "mx_ReadReceiptGroup_button", ref: button, "aria-label": tooltipText, "aria-haspopup": "true", onClick: openMenu }, remText, /*#__PURE__*/_react.default.createElement("span", { className: "mx_ReadReceiptGroup_container", style: { width: Math.min(maxAvatars, readReceipts.length) * READ_AVATAR_OFFSET + READ_AVATAR_SIZE - READ_AVATAR_OFFSET } }, avatars)), contextMenu))); } // Export for testing function ReadReceiptPerson({ userId, roomMember, ts, isTwelveHour, onAfterClick }) { return /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { description: roomMember?.rawDisplayName ?? userId, caption: userId, placement: "top" }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_ContextMenu.MenuItem, { className: "mx_ReadReceiptGroup_person", onClick: () => { _dispatcher.default.dispatch({ action: _actions.Action.ViewUser, // XXX: We should be using a real member object and not assuming what the receiver wants. // The ViewUser action leads to the RightPanelStore, and RightPanelStoreIPanelState defines the // member property of IRightPanelCardState as `RoomMember | User`, so we’re fine for now, but we // should definitely clean this up later member: roomMember ?? { userId }, push: false }); onAfterClick?.(); } }, /*#__PURE__*/_react.default.createElement(_MemberAvatar.default, { member: roomMember, fallbackUserId: userId, size: "24px", "aria-hidden": "true", "aria-live": "off", resizeMethod: "crop", hideTitle: true }), /*#__PURE__*/_react.default.createElement("div", { className: "mx_ReadReceiptGroup_name" }, /*#__PURE__*/_react.default.createElement("p", null, roomMember?.name ?? userId), /*#__PURE__*/_react.default.createElement("p", { className: "mx_ReadReceiptGroup_secondary" }, (0, _DateUtils.formatDate)(new Date(ts), isTwelveHour)))))); } function SectionHeader({ className, children }) { const [onFocus,, ref] = (0, _RovingTabIndex.useRovingTabIndex)(); return /*#__PURE__*/_react.default.createElement("h3", { className: className, role: "menuitem", onFocus: onFocus, tabIndex: -1, ref: ref }, children); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9jb21wb3VuZFdlYiIsIl9SZWFkUmVjZWlwdE1hcmtlciIsIl9BY2Nlc3NpYmxlQnV0dG9uIiwiX01lbWJlckF2YXRhciIsIl9BdXRvSGlkZVNjcm9sbGJhciIsIl9EYXRlVXRpbHMiLCJfYWN0aW9ucyIsIl9kaXNwYXRjaGVyIiwiX0NvbnRleHRNZW51IiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJfbGFuZ3VhZ2VIYW5kbGVyIiwiX1JvdmluZ1RhYkluZGV4IiwiX0Zvcm1hdHRpbmdVdGlscyIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIk1BWF9SRUFEX0FWQVRBUlNfUExVU19OIiwiTUFYX1JFQURfQVZBVEFSUyIsIlJFQURfQVZBVEFSX09GRlNFVCIsIlJFQURfQVZBVEFSX1NJWkUiLCJleHBvcnRzIiwiZGV0ZXJtaW5lQXZhdGFyUG9zaXRpb24iLCJpbmRleCIsIm1heCIsImhpZGRlbiIsInBvc2l0aW9uIiwicmVhZFJlY2VpcHRUb29sdGlwIiwibWVtYmVycyIsIm1heEF2YXRhcnMiLCJmb3JtYXRMaXN0IiwiUmVhZFJlY2VpcHRHcm91cCIsInJlYWRSZWNlaXB0cyIsInJlYWRSZWNlaXB0TWFwIiwiY2hlY2tVbm1vdW50aW5nIiwic3VwcHJlc3NBbmltYXRpb24iLCJpc1R3ZWx2ZUhvdXIiLCJtZW51RGlzcGxheWVkIiwiYnV0dG9uIiwib3Blbk1lbnUiLCJjbG9zZU1lbnUiLCJ1c2VDb250ZXh0TWVudSIsImhhc01vcmUiLCJsZW5ndGgiLCJ0b29sdGlwTWVtYmVycyIsIm1hcCIsIml0Iiwicm9vbU1lbWJlciIsIm5hbWUiLCJ1c2VySWQiLCJ0b29sdGlwVGV4dCIsImNyZWF0ZUVsZW1lbnQiLCJjbGFzc05hbWUiLCJhdmF0YXJzIiwicmVjZWlwdCIsInJlYWRSZWNlaXB0UG9zaXRpb24iLCJrZXkiLCJtZW1iZXIiLCJmYWxsYmFja1VzZXJJZCIsIm9mZnNldCIsInRpbWVzdGFtcCIsInRzIiwic2hvd1R3ZWx2ZUhvdXIiLCJyZXZlcnNlIiwicmVtVGV4dCIsInJlbWFpbmRlciIsImNvbnRleHRNZW51IiwiY3VycmVudCIsImJ1dHRvblJlY3QiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJfZXh0ZW5kczIiLCJtZW51Q2xhc3NOYW1lIiwib25GaW5pc2hlZCIsImFib3ZlTGVmdE9mIiwiU2VjdGlvbkhlYWRlciIsIl90IiwiY291bnQiLCJSZWFkUmVjZWlwdFBlcnNvbiIsIm9uQWZ0ZXJDbGljayIsIlRvb2x0aXAiLCJsYWJlbCIsImNhcHRpb24iLCJwbGFjZW1lbnQiLCJyb2xlIiwicmVmIiwib25DbGljayIsInN0eWxlIiwid2lkdGgiLCJNYXRoIiwibWluIiwiZGVzY3JpcHRpb24iLCJyYXdEaXNwbGF5TmFtZSIsIk1lbnVJdGVtIiwiZGlzIiwiZGlzcGF0Y2giLCJhY3Rpb24iLCJBY3Rpb24iLCJWaWV3VXNlciIsInB1c2giLCJzaXplIiwicmVzaXplTWV0aG9kIiwiaGlkZVRpdGxlIiwiZm9ybWF0RGF0ZSIsIkRhdGUiLCJjaGlsZHJlbiIsIm9uRm9jdXMiLCJ1c2VSb3ZpbmdUYWJJbmRleCIsInRhYkluZGV4Il0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdmlld3Mvcm9vbXMvUmVhZFJlY2VpcHRHcm91cC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjIgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7IFByb3BzV2l0aENoaWxkcmVuIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuaW1wb3J0IHsgVG9vbHRpcCB9IGZyb20gXCJAdmVjdG9yLWltL2NvbXBvdW5kLXdlYlwiO1xuXG5pbXBvcnQgUmVhZFJlY2VpcHRNYXJrZXIsIHsgSVJlYWRSZWNlaXB0UG9zaXRpb24gfSBmcm9tIFwiLi9SZWFkUmVjZWlwdE1hcmtlclwiO1xuaW1wb3J0IHsgSVJlYWRSZWNlaXB0UHJvcHMgfSBmcm9tIFwiLi9FdmVudFRpbGVcIjtcbmltcG9ydCBBY2Nlc3NpYmxlQnV0dG9uIGZyb20gXCIuLi9lbGVtZW50cy9BY2Nlc3NpYmxlQnV0dG9uXCI7XG5pbXBvcnQgTWVtYmVyQXZhdGFyIGZyb20gXCIuLi9hdmF0YXJzL01lbWJlckF2YXRhclwiO1xuaW1wb3J0IEF1dG9IaWRlU2Nyb2xsYmFyIGZyb20gXCIuLi8uLi9zdHJ1Y3R1cmVzL0F1dG9IaWRlU2Nyb2xsYmFyXCI7XG5pbXBvcnQgeyBmb3JtYXREYXRlIH0gZnJvbSBcIi4uLy4uLy4uL0RhdGVVdGlsc1wiO1xuaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSBcIi4uLy4uLy4uL2Rpc3BhdGNoZXIvYWN0aW9uc1wiO1xuaW1wb3J0IGRpcyBmcm9tIFwiLi4vLi4vLi4vZGlzcGF0Y2hlci9kaXNwYXRjaGVyXCI7XG5pbXBvcnQgQ29udGV4dE1lbnUsIHsgYWJvdmVMZWZ0T2YsIE1lbnVJdGVtLCB1c2VDb250ZXh0TWVudSB9IGZyb20gXCIuLi8uLi9zdHJ1Y3R1cmVzL0NvbnRleHRNZW51XCI7XG5pbXBvcnQgeyBfdCB9IGZyb20gXCIuLi8uLi8uLi9sYW5ndWFnZUhhbmRsZXJcIjtcbmltcG9ydCB7IHVzZVJvdmluZ1RhYkluZGV4IH0gZnJvbSBcIi4uLy4uLy4uL2FjY2Vzc2liaWxpdHkvUm92aW5nVGFiSW5kZXhcIjtcbmltcG9ydCB7IGZvcm1hdExpc3QgfSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvRm9ybWF0dGluZ1V0aWxzXCI7XG5cbi8vICMyMDU0NyBEZXNpZ24gc3BlY2lmaWVkIHRoYXQgd2Ugc2hvdWxkIHNob3cgdGhlIHRocmVlIGxhdGVzdCByZWFkIHJlY2VpcHRzXG5jb25zdCBNQVhfUkVBRF9BVkFUQVJTX1BMVVNfTiA9IDM7XG4vLyAjMjE5MzUgSWYgd2XigJl2ZSBnb3QganVzdCA0LCBkb27igJl0IHNob3cgKzEsIGp1c3Qgc2hvdyBhbGwgb2YgdGhlbVxuY29uc3QgTUFYX1JFQURfQVZBVEFSUyA9IE1BWF9SRUFEX0FWQVRBUlNfUExVU19OICsgMTtcblxuY29uc3QgUkVBRF9BVkFUQVJfT0ZGU0VUID0gMTA7XG5leHBvcnQgY29uc3QgUkVBRF9BVkFUQVJfU0laRSA9IDE2O1xuXG5pbnRlcmZhY2UgUHJvcHMge1xuICAgIHJlYWRSZWNlaXB0czogSVJlYWRSZWNlaXB0UHJvcHNbXTtcbiAgICByZWFkUmVjZWlwdE1hcDogeyBbdXNlcklkOiBzdHJpbmddOiBJUmVhZFJlY2VpcHRQb3NpdGlvbiB9O1xuICAgIGNoZWNrVW5tb3VudGluZz86ICgpID0+IGJvb2xlYW47XG4gICAgc3VwcHJlc3NBbmltYXRpb246IGJvb2xlYW47XG4gICAgaXNUd2VsdmVIb3VyPzogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIElBdmF0YXJQb3NpdGlvbiB7XG4gICAgaGlkZGVuOiBib29sZWFuO1xuICAgIHBvc2l0aW9uOiBudW1iZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZXRlcm1pbmVBdmF0YXJQb3NpdGlvbihpbmRleDogbnVtYmVyLCBtYXg6IG51bWJlcik6IElBdmF0YXJQb3NpdGlvbiB7XG4gICAgaWYgKGluZGV4IDwgbWF4KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoaWRkZW46IGZhbHNlLFxuICAgICAgICAgICAgcG9zaXRpb246IGluZGV4LFxuICAgICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoaWRkZW46IHRydWUsXG4gICAgICAgICAgICBwb3NpdGlvbjogMCxcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkUmVjZWlwdFRvb2x0aXAobWVtYmVyczogc3RyaW5nW10sIG1heEF2YXRhcnM6IG51bWJlcik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGZvcm1hdExpc3QobWVtYmVycywgbWF4QXZhdGFycyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBSZWFkUmVjZWlwdEdyb3VwKHtcbiAgICByZWFkUmVjZWlwdHMsXG4gICAgcmVhZFJlY2VpcHRNYXAsXG4gICAgY2hlY2tVbm1vdW50aW5nLFxuICAgIHN1cHByZXNzQW5pbWF0aW9uLFxuICAgIGlzVHdlbHZlSG91cixcbn06IFByb3BzKTogSlNYLkVsZW1lbnQge1xuICAgIGNvbnN0IFttZW51RGlzcGxheWVkLCBidXR0b24sIG9wZW5NZW51LCBjbG9zZU1lbnVdID0gdXNlQ29udGV4dE1lbnUoKTtcblxuICAgIC8vIElmIHdlIGFyZSBhYm92ZSBNQVhfUkVBRF9BVkFUQVJTLCB3ZeKAmWxsIGhhdmUgdG8gcmVtb3ZlIGEgZmV3IHRvIGhhdmUgc3BhY2UgZm9yIHRoZSArbiBjb3VudC5cbiAgICBjb25zdCBoYXNNb3JlID0gcmVhZFJlY2VpcHRzLmxlbmd0aCA+IE1BWF9SRUFEX0FWQVRBUlM7XG4gICAgY29uc3QgbWF4QXZhdGFycyA9IGhhc01vcmUgPyBNQVhfUkVBRF9BVkFUQVJTX1BMVVNfTiA6IE1BWF9SRUFEX0FWQVRBUlM7XG5cbiAgICBjb25zdCB0b29sdGlwTWVtYmVyczogc3RyaW5nW10gPSByZWFkUmVjZWlwdHMubWFwKChpdCkgPT4gaXQucm9vbU1lbWJlcj8ubmFtZSA/PyBpdC51c2VySWQpO1xuICAgIGNvbnN0IHRvb2x0aXBUZXh0ID0gcmVhZFJlY2VpcHRUb29sdGlwKHRvb2x0aXBNZW1iZXJzLCBtYXhBdmF0YXJzKTtcblxuICAgIC8vIHJldHVybiBlYXJseSBpZiB0aGVyZSBhcmUgbm8gcmVhZCByZWNlaXB0c1xuICAgIGlmIChyZWFkUmVjZWlwdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIC8vIFdlIGN1cnJlbnRseSBtdXN0IGluY2x1ZGUgYG14X1JlYWRSZWNlaXB0R3JvdXBfY29udGFpbmVyYCBpblxuICAgICAgICAvLyB0aGUgRE9NIG9mIGFsbCBldmVudHMsIGFzIGl0IGlzIHRoZSBwb3NpdGlvbmVkIHBhcmVudCBvZiB0aGVcbiAgICAgICAgLy8gYW5pbWF0ZWQgcmVhZCByZWNlaXB0cy4gV2UgY2FuJ3QgbGV0IGl0IHVubW91bnQgd2hlbiBhIHJlY2VpcHRcbiAgICAgICAgLy8gbW92ZXMgZXZlbnRzLCBzbyBmb3Igbm93IHdlIG1vdW50IGl0IGZvciBhbGwgZXZlbnRzLiBXaXRob3V0XG4gICAgICAgIC8vIGl0LCB0aGUgYW5pbWF0aW9uIHdpbGwgc3RhcnQgZnJvbSB0aGUgdG9wIG9mIHRoZSB0aW1lbGluZVxuICAgICAgICAvLyAoYmVjYXVzZSBpdCBsb3N0IGl0cyBjb250YWluZXIpLlxuICAgICAgICAvLyBTZWUgYWxzbyBodHRwczovL2dpdGh1Yi5jb20vdmVjdG9yLWltL2VsZW1lbnQtd2ViL2lzc3Vlcy8xNzU2MVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9FdmVudFRpbGVfbXNnT3B0aW9uXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9SZWFkUmVjZWlwdEdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfUmVhZFJlY2VpcHRHcm91cF9idXR0b25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cIm14X1JlYWRSZWNlaXB0R3JvdXBfY29udGFpbmVyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBhdmF0YXJzID0gcmVhZFJlY2VpcHRzXG4gICAgICAgIC5tYXAoKHJlY2VpcHQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGhpZGRlbiwgcG9zaXRpb24gfSA9IGRldGVybWluZUF2YXRhclBvc2l0aW9uKGluZGV4LCBtYXhBdmF0YXJzKTtcblxuICAgICAgICAgICAgY29uc3QgdXNlcklkID0gcmVjZWlwdC51c2VySWQ7XG4gICAgICAgICAgICBsZXQgcmVhZFJlY2VpcHRQb3NpdGlvbjogSVJlYWRSZWNlaXB0UG9zaXRpb24gfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIGlmIChyZWFkUmVjZWlwdE1hcCkge1xuICAgICAgICAgICAgICAgIHJlYWRSZWNlaXB0UG9zaXRpb24gPSByZWFkUmVjZWlwdE1hcFt1c2VySWRdO1xuICAgICAgICAgICAgICAgIGlmICghcmVhZFJlY2VpcHRQb3NpdGlvbikge1xuICAgICAgICAgICAgICAgICAgICByZWFkUmVjZWlwdFBvc2l0aW9uID0ge307XG4gICAgICAgICAgICAgICAgICAgIHJlYWRSZWNlaXB0TWFwW3VzZXJJZF0gPSByZWFkUmVjZWlwdFBvc2l0aW9uO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8UmVhZFJlY2VpcHRNYXJrZXJcbiAgICAgICAgICAgICAgICAgICAga2V5PXt1c2VySWR9XG4gICAgICAgICAgICAgICAgICAgIG1lbWJlcj17cmVjZWlwdC5yb29tTWVtYmVyfVxuICAgICAgICAgICAgICAgICAgICBmYWxsYmFja1VzZXJJZD17dXNlcklkfVxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ9e3Bvc2l0aW9uICogUkVBRF9BVkFUQVJfT0ZGU0VUfVxuICAgICAgICAgICAgICAgICAgICBoaWRkZW49e2hpZGRlbn1cbiAgICAgICAgICAgICAgICAgICAgcmVhZFJlY2VpcHRQb3NpdGlvbj17cmVhZFJlY2VpcHRQb3NpdGlvbn1cbiAgICAgICAgICAgICAgICAgICAgY2hlY2tVbm1vdW50aW5nPXtjaGVja1VubW91bnRpbmd9XG4gICAgICAgICAgICAgICAgICAgIHN1cHByZXNzQW5pbWF0aW9uPXtzdXBwcmVzc0FuaW1hdGlvbn1cbiAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wPXtyZWNlaXB0LnRzfVxuICAgICAgICAgICAgICAgICAgICBzaG93VHdlbHZlSG91cj17aXNUd2VsdmVIb3VyfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApO1xuICAgICAgICB9KVxuICAgICAgICAucmV2ZXJzZSgpO1xuXG4gICAgbGV0IHJlbVRleHQ6IEpTWC5FbGVtZW50IHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHJlbWFpbmRlciA9IHJlYWRSZWNlaXB0cy5sZW5ndGggLSBtYXhBdmF0YXJzO1xuICAgIGlmIChyZW1haW5kZXIgPiAwKSB7XG4gICAgICAgIHJlbVRleHQgPSAoXG4gICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJteF9SZWFkUmVjZWlwdEdyb3VwX3JlbWFpbmRlclwiIGFyaWEtbGl2ZT1cIm9mZlwiPlxuICAgICAgICAgICAgICAgICt7cmVtYWluZGVyfVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGxldCBjb250ZXh0TWVudTogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgaWYgKG1lbnVEaXNwbGF5ZWQgJiYgYnV0dG9uLmN1cnJlbnQpIHtcbiAgICAgICAgY29uc3QgYnV0dG9uUmVjdCA9IGJ1dHRvbi5jdXJyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBjb250ZXh0TWVudSA9IChcbiAgICAgICAgICAgIDxDb250ZXh0TWVudSBtZW51Q2xhc3NOYW1lPVwibXhfUmVhZFJlY2VpcHRHcm91cF9wb3B1cFwiIG9uRmluaXNoZWQ9e2Nsb3NlTWVudX0gey4uLmFib3ZlTGVmdE9mKGJ1dHRvblJlY3QpfT5cbiAgICAgICAgICAgICAgICA8QXV0b0hpZGVTY3JvbGxiYXI+XG4gICAgICAgICAgICAgICAgICAgIDxTZWN0aW9uSGVhZGVyIGNsYXNzTmFtZT1cIm14X1JlYWRSZWNlaXB0R3JvdXBfdGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcInRpbWVsaW5lfHJlYWRfcmVjZWlwdF90aXRsZVwiLCB7IGNvdW50OiByZWFkUmVjZWlwdHMubGVuZ3RoIH0pfVxuICAgICAgICAgICAgICAgICAgICA8L1NlY3Rpb25IZWFkZXI+XG4gICAgICAgICAgICAgICAgICAgIHtyZWFkUmVjZWlwdHMubWFwKChyZWNlaXB0KSA9PiAoXG4gICAgICAgICAgICAgICAgICAgICAgICA8UmVhZFJlY2VpcHRQZXJzb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk9e3JlY2VpcHQudXNlcklkfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsuLi5yZWNlaXB0fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzVHdlbHZlSG91cj17aXNUd2VsdmVIb3VyfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQWZ0ZXJDbGljaz17Y2xvc2VNZW51fVxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgKSl9XG4gICAgICAgICAgICAgICAgPC9BdXRvSGlkZVNjcm9sbGJhcj5cbiAgICAgICAgICAgIDwvQ29udGV4dE1lbnU+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9FdmVudFRpbGVfbXNnT3B0aW9uXCI+XG4gICAgICAgICAgICA8VG9vbHRpcFxuICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcInRpbWVsaW5lfHJlYWRfcmVjZWlwdF90aXRsZVwiLCB7IGNvdW50OiByZWFkUmVjZWlwdHMubGVuZ3RoIH0pfVxuICAgICAgICAgICAgICAgIGNhcHRpb249e3Rvb2x0aXBUZXh0fVxuICAgICAgICAgICAgICAgIHBsYWNlbWVudD1cInRvcC1lbmRcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfUmVhZFJlY2VpcHRHcm91cFwiIHJvbGU9XCJncm91cFwiIGFyaWEtbGFiZWw9e190KFwidGltZWxpbmV8cmVhZF9yZWNlaXB0c19sYWJlbFwiKX0+XG4gICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9SZWFkUmVjZWlwdEdyb3VwX2J1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICByZWY9e2J1dHRvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e3Rvb2x0aXBUZXh0fVxuICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1oYXNwb3B1cD1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17b3Blbk1lbnV9XG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIHtyZW1UZXh0fVxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9SZWFkUmVjZWlwdEdyb3VwX2NvbnRhaW5lclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLm1pbihtYXhBdmF0YXJzLCByZWFkUmVjZWlwdHMubGVuZ3RoKSAqIFJFQURfQVZBVEFSX09GRlNFVCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUFEX0FWQVRBUl9TSVpFIC1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQURfQVZBVEFSX09GRlNFVCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHthdmF0YXJzfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgIHtjb250ZXh0TWVudX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvVG9vbHRpcD5cbiAgICAgICAgPC9kaXY+XG4gICAgKTtcbn1cblxuaW50ZXJmYWNlIFJlYWRSZWNlaXB0UGVyc29uUHJvcHMgZXh0ZW5kcyBJUmVhZFJlY2VpcHRQcm9wcyB7XG4gICAgaXNUd2VsdmVIb3VyPzogYm9vbGVhbjtcbiAgICBvbkFmdGVyQ2xpY2s/OiAoKSA9PiB2b2lkO1xufVxuXG4vLyBFeHBvcnQgZm9yIHRlc3RpbmdcbmV4cG9ydCBmdW5jdGlvbiBSZWFkUmVjZWlwdFBlcnNvbih7XG4gICAgdXNlcklkLFxuICAgIHJvb21NZW1iZXIsXG4gICAgdHMsXG4gICAgaXNUd2VsdmVIb3VyLFxuICAgIG9uQWZ0ZXJDbGljayxcbn06IFJlYWRSZWNlaXB0UGVyc29uUHJvcHMpOiBKU1guRWxlbWVudCB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgPFRvb2x0aXAgZGVzY3JpcHRpb249e3Jvb21NZW1iZXI/LnJhd0Rpc3BsYXlOYW1lID8/IHVzZXJJZH0gY2FwdGlvbj17dXNlcklkfSBwbGFjZW1lbnQ9XCJ0b3BcIj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPE1lbnVJdGVtXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1JlYWRSZWNlaXB0R3JvdXBfcGVyc29uXCJcbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlzLmRpc3BhdGNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IEFjdGlvbi5WaWV3VXNlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBYWFg6IFdlIHNob3VsZCBiZSB1c2luZyBhIHJlYWwgbWVtYmVyIG9iamVjdCBhbmQgbm90IGFzc3VtaW5nIHdoYXQgdGhlIHJlY2VpdmVyIHdhbnRzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBWaWV3VXNlciBhY3Rpb24gbGVhZHMgdG8gdGhlIFJpZ2h0UGFuZWxTdG9yZSwgYW5kIFJpZ2h0UGFuZWxTdG9yZUlQYW5lbFN0YXRlIGRlZmluZXMgdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWVtYmVyIHByb3BlcnR5IG9mIElSaWdodFBhbmVsQ2FyZFN0YXRlIGFzIGBSb29tTWVtYmVyIHwgVXNlcmAsIHNvIHdl4oCZcmUgZmluZSBmb3Igbm93LCBidXQgd2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaG91bGQgZGVmaW5pdGVseSBjbGVhbiB0aGlzIHVwIGxhdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtYmVyOiByb29tTWVtYmVyID8/ICh7IHVzZXJJZCB9IGFzIFVzZXIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1c2g6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkFmdGVyQ2xpY2s/LigpO1xuICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPE1lbWJlckF2YXRhclxuICAgICAgICAgICAgICAgICAgICAgICAgbWVtYmVyPXtyb29tTWVtYmVyfVxuICAgICAgICAgICAgICAgICAgICAgICAgZmFsbGJhY2tVc2VySWQ9e3VzZXJJZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9XCIyNHB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxpdmU9XCJvZmZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzaXplTWV0aG9kPVwiY3JvcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBoaWRlVGl0bGVcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9SZWFkUmVjZWlwdEdyb3VwX25hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPntyb29tTWVtYmVyPy5uYW1lID8/IHVzZXJJZH08L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9XCJteF9SZWFkUmVjZWlwdEdyb3VwX3NlY29uZGFyeVwiPntmb3JtYXREYXRlKG5ldyBEYXRlKHRzKSwgaXNUd2VsdmVIb3VyKX08L3A+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvTWVudUl0ZW0+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9Ub29sdGlwPlxuICAgICk7XG59XG5cbmludGVyZmFjZSBJU2VjdGlvbkhlYWRlclByb3BzIHtcbiAgICBjbGFzc05hbWU/OiBzdHJpbmc7XG59XG5cbmZ1bmN0aW9uIFNlY3Rpb25IZWFkZXIoeyBjbGFzc05hbWUsIGNoaWxkcmVuIH06IFByb3BzV2l0aENoaWxkcmVuPElTZWN0aW9uSGVhZGVyUHJvcHM+KTogSlNYLkVsZW1lbnQge1xuICAgIGNvbnN0IFtvbkZvY3VzLCAsIHJlZl0gPSB1c2VSb3ZpbmdUYWJJbmRleDxIVE1MSGVhZGluZ0VsZW1lbnQ+KCk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8aDMgY2xhc3NOYW1lPXtjbGFzc05hbWV9IHJvbGU9XCJtZW51aXRlbVwiIG9uRm9jdXM9e29uRm9jdXN9IHRhYkluZGV4PXstMX0gcmVmPXtyZWZ9PlxuICAgICAgICAgICAge2NoaWxkcmVufVxuICAgICAgICA8L2gzPlxuICAgICk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQVFBLElBQUFBLE1BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUVBLElBQUFDLFlBQUEsR0FBQUQsT0FBQTtBQUVBLElBQUFFLGtCQUFBLEdBQUFILHNCQUFBLENBQUFDLE9BQUE7QUFFQSxJQUFBRyxpQkFBQSxHQUFBSixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUksYUFBQSxHQUFBTCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUssa0JBQUEsR0FBQU4sc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFNLFVBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLFFBQUEsR0FBQVAsT0FBQTtBQUNBLElBQUFRLFdBQUEsR0FBQVQsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFTLFlBQUEsR0FBQUMsdUJBQUEsQ0FBQVYsT0FBQTtBQUNBLElBQUFXLGdCQUFBLEdBQUFYLE9BQUE7QUFDQSxJQUFBWSxlQUFBLEdBQUFaLE9BQUE7QUFDQSxJQUFBYSxnQkFBQSxHQUFBYixPQUFBO0FBQTRELFNBQUFjLHlCQUFBQyxDQUFBLDZCQUFBQyxPQUFBLG1CQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFGLHdCQUFBLFlBQUFBLENBQUFDLENBQUEsV0FBQUEsQ0FBQSxHQUFBRyxDQUFBLEdBQUFELENBQUEsS0FBQUYsQ0FBQTtBQUFBLFNBQUFMLHdCQUFBSyxDQUFBLEVBQUFFLENBQUEsU0FBQUEsQ0FBQSxJQUFBRixDQUFBLElBQUFBLENB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