UNPKG

matrix-react-sdk

Version:
308 lines (305 loc) 64.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RoomHeader; var _react = _interopRequireWildcard(require("react")); var _compoundWeb = require("@vector-im/compound-web"); var _videoCallSolid = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/video-call-solid")); var _voiceCall = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/voice-call")); var _close = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/close")); var _threadsSolid = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/threads-solid")); var _infoSolid = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/info-solid")); var _notificationsSolid = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/notifications-solid")); var _verified = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/verified")); var _error = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/error")); var _public = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/public")); var _matrix = require("matrix-js-sdk/src/matrix"); var _useRoomName = require("../../../hooks/useRoomName"); var _RightPanelStorePhases = require("../../../stores/right-panel/RightPanelStorePhases"); var _MatrixClientContext = require("../../../contexts/MatrixClientContext"); var _useRoomMembers = require("../../../hooks/useRoomMembers"); var _languageHandler = require("../../../languageHandler"); var _Flex = require("../../utils/Flex"); var _Box = require("../../utils/Box"); var _useRoomCall = require("../../../hooks/room/useRoomCall"); var _useRoomThreadNotifications = require("../../../hooks/room/useRoomThreadNotifications"); var _useGlobalNotificationState = require("../../../hooks/useGlobalNotificationState"); var _SdkConfig = _interopRequireDefault(require("../../../SdkConfig")); var _useSettings = require("../../../hooks/useSettings"); var _useEncryptionStatus = require("../../../hooks/useEncryptionStatus"); var _ShieldUtils = require("../../../utils/ShieldUtils"); var _FacePile = _interopRequireDefault(require("../elements/FacePile")); var _useRoomState = require("../../../hooks/useRoomState"); var _RoomAvatar = _interopRequireDefault(require("../avatars/RoomAvatar")); var _FormattingUtils = require("../../../utils/FormattingUtils"); var _RightPanelStore = _interopRequireDefault(require("../../../stores/right-panel/RightPanelStore")); var _PosthogTrackers = _interopRequireDefault(require("../../../PosthogTrackers")); var _VideoRoomChatButton = require("./RoomHeader/VideoRoomChatButton"); var _RoomKnocksBar = require("./RoomKnocksBar"); var _videoRooms = require("../../../utils/video-rooms"); var _notifications = require("../../../utils/notifications"); var _CallGuestLinkButton = require("./RoomHeader/CallGuestLinkButton"); var _WithPresenceIndicator = _interopRequireWildcard(require("../avatars/WithPresenceIndicator")); var _RoomContext = _interopRequireDefault(require("../../../contexts/RoomContext")); var _RoomView = require("../../structures/RoomView"); var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher.ts")); var _RoomSettingsDialog = require("../dialogs/RoomSettingsDialog.tsx"); 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 2023 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. */ function RoomHeader({ room, additionalButtons, oobData }) { const client = (0, _MatrixClientContext.useMatrixClientContext)(); const roomName = (0, _useRoomName.useRoomName)(room); const joinRule = (0, _useRoomState.useRoomState)(room, state => state.getJoinRule()); const members = (0, _useRoomMembers.useRoomMembers)(room, 2500); const memberCount = (0, _useRoomMembers.useRoomMemberCount)(room, { throttleWait: 2500 }); const { voiceCallDisabledReason, voiceCallClick, videoCallDisabledReason, videoCallClick, toggleCallMaximized: toggleCall, isViewingCall, isConnectedToCall, hasActiveCallSession, callOptions, showVoiceCallButton, showVideoCallButton } = (0, _useRoomCall.useRoomCall)(room); const groupCallsEnabled = (0, _useSettings.useFeatureEnabled)("feature_group_calls"); /** * A special mode where only Element Call is used. In this case we want to * hide the voice call button */ const useElementCallExclusively = (0, _react.useMemo)(() => { return _SdkConfig.default.get("element_call").use_exclusively && groupCallsEnabled; }, [groupCallsEnabled]); const threadNotifications = (0, _useRoomThreadNotifications.useRoomThreadNotifications)(room); const globalNotificationState = (0, _useGlobalNotificationState.useGlobalNotificationState)(); const dmMember = (0, _WithPresenceIndicator.useDmMember)(room); const isDirectMessage = !!dmMember; const e2eStatus = (0, _useEncryptionStatus.useEncryptionStatus)(client, room); const notificationsEnabled = (0, _useSettings.useFeatureEnabled)("feature_notifications"); const askToJoinEnabled = (0, _useSettings.useFeatureEnabled)("feature_ask_to_join"); const videoClick = (0, _react.useCallback)(ev => videoCallClick(ev, callOptions[0]), [callOptions, videoCallClick]); const toggleCallButton = /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: isViewingCall ? (0, _languageHandler._t)("voip|minimise_call") : (0, _languageHandler._t)("voip|maximise_call") }, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, { onClick: toggleCall }, /*#__PURE__*/_react.default.createElement(_videoCallSolid.default, null))); const joinCallButton = /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: videoCallDisabledReason ?? (0, _languageHandler._t)("voip|video_call") }, /*#__PURE__*/_react.default.createElement(_compoundWeb.Button, { size: "sm", onClick: videoClick, Icon: _videoCallSolid.default, className: "mx_RoomHeader_join_button", disabled: !!videoCallDisabledReason, color: "primary", "aria-label": videoCallDisabledReason ?? (0, _languageHandler._t)("action|join") }, (0, _languageHandler._t)("action|join"))); const callIconWithTooltip = /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: videoCallDisabledReason ?? (0, _languageHandler._t)("voip|video_call") }, /*#__PURE__*/_react.default.createElement(_videoCallSolid.default, null)); const [menuOpen, setMenuOpen] = (0, _react.useState)(false); const onOpenChange = (0, _react.useCallback)(newOpen => { if (!videoCallDisabledReason) setMenuOpen(newOpen); }, [videoCallDisabledReason]); const startVideoCallButton = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, callOptions.length > 1 ? /*#__PURE__*/_react.default.createElement(_compoundWeb.Menu, { open: menuOpen, onOpenChange: onOpenChange, title: (0, _languageHandler._t)("voip|video_call_using"), trigger: /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, { disabled: !!videoCallDisabledReason, "aria-label": videoCallDisabledReason ?? (0, _languageHandler._t)("voip|video_call") }, callIconWithTooltip), side: "left", align: "start" }, callOptions.map(option => /*#__PURE__*/_react.default.createElement(_compoundWeb.MenuItem, { key: option, label: (0, _useRoomCall.getPlatformCallTypeLabel)(option), "aria-label": (0, _useRoomCall.getPlatformCallTypeLabel)(option), onClick: ev => videoCallClick(ev, option), Icon: _videoCallSolid.default, onSelect: () => {} /* Dummy handler since we want the click event.*/ }))) : /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, { disabled: !!videoCallDisabledReason, "aria-label": videoCallDisabledReason ?? (0, _languageHandler._t)("voip|video_call"), onClick: videoClick }, callIconWithTooltip)); let voiceCallButton = /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: voiceCallDisabledReason ?? (0, _languageHandler._t)("voip|voice_call") }, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton // We need both: isViewingCall and isConnectedToCall // - in the Lobby we are viewing a call but are not connected to it. // - in pip view we are connected to the call but not viewing it. , { disabled: !!voiceCallDisabledReason || isViewingCall || isConnectedToCall, "aria-label": voiceCallDisabledReason ?? (0, _languageHandler._t)("voip|voice_call"), onClick: ev => voiceCallClick(ev, callOptions[0]) }, /*#__PURE__*/_react.default.createElement(_voiceCall.default, null))); const closeLobbyButton = /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: (0, _languageHandler._t)("voip|close_lobby") }, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, { onClick: toggleCall }, /*#__PURE__*/_react.default.createElement(_close.default, null))); let videoCallButton = startVideoCallButton; if (isConnectedToCall) { videoCallButton = toggleCallButton; } else if (isViewingCall) { videoCallButton = closeLobbyButton; } if (!showVideoCallButton) { videoCallButton = undefined; } if (!showVoiceCallButton) { voiceCallButton = undefined; } const roomContext = (0, _react.useContext)(_RoomContext.default); const isVideoRoom = (0, _videoRooms.isVideoRoom)(room); const showChatButton = isVideoRoom || roomContext.mainSplitContentType === _RoomView.MainSplitContentType.MaximisedWidget || roomContext.mainSplitContentType === _RoomView.MainSplitContentType.Call; const onAvatarClick = () => { _dispatcher.default.dispatch({ action: "open_room_settings", initial_tab_id: _RoomSettingsDialog.RoomSettingsTab.General }); }; return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Flex.Flex, { as: "header", align: "center", gap: "var(--cpd-space-3x)", className: "mx_RoomHeader light-panel" }, /*#__PURE__*/_react.default.createElement(_WithPresenceIndicator.default, { room: room, size: "8px" }, /*#__PURE__*/_react.default.createElement(_RoomAvatar.default, { room: room, size: "40px", oobData: oobData, onClick: onAvatarClick, tabIndex: -1, "aria-label": (0, _languageHandler._t)("room|header_avatar_open_settings_label") })), /*#__PURE__*/_react.default.createElement("button", { "aria-label": (0, _languageHandler._t)("right_panel|room_summary_card|title"), tabIndex: 0, onClick: () => _RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.RoomSummary), className: "mx_RoomHeader_infoWrapper" }, /*#__PURE__*/_react.default.createElement(_Box.Box, { flex: "1", className: "mx_RoomHeader_info" }, /*#__PURE__*/_react.default.createElement(_compoundWeb.Body, { as: "div", size: "lg", weight: "semibold", dir: "auto", role: "heading", "aria-level": 1, className: "mx_RoomHeader_heading" }, /*#__PURE__*/_react.default.createElement("span", { className: "mx_RoomHeader_truncated mx_lineClamp" }, roomName), !isDirectMessage && joinRule === _matrix.JoinRule.Public && /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: (0, _languageHandler._t)("common|public_room"), placement: "right" }, /*#__PURE__*/_react.default.createElement(_public.default, { width: "16px", height: "16px", className: "mx_RoomHeader_icon text-secondary", "aria-label": (0, _languageHandler._t)("common|public_room") })), isDirectMessage && e2eStatus === _ShieldUtils.E2EStatus.Verified && /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: (0, _languageHandler._t)("common|verified"), placement: "right" }, /*#__PURE__*/_react.default.createElement(_verified.default, { width: "16px", height: "16px", className: "mx_RoomHeader_icon mx_Verified", "aria-label": (0, _languageHandler._t)("common|verified") })), isDirectMessage && e2eStatus === _ShieldUtils.E2EStatus.Warning && /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: (0, _languageHandler._t)("room|header_untrusted_label"), placement: "right" }, /*#__PURE__*/_react.default.createElement(_error.default, { width: "16px", height: "16px", className: "mx_RoomHeader_icon mx_Untrusted", "aria-label": (0, _languageHandler._t)("room|header_untrusted_label") }))))), /*#__PURE__*/_react.default.createElement(_Flex.Flex, { align: "center", gap: "var(--cpd-space-2x)" }, additionalButtons?.map(props => { const label = props.label(); return /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: label, key: props.id }, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, { "aria-label": label, onClick: event => { event.stopPropagation(); props.onClick(); } }, typeof props.icon === "function" ? props.icon() : props.icon)); }), isViewingCall && /*#__PURE__*/_react.default.createElement(_CallGuestLinkButton.CallGuestLinkButton, { room: room }), hasActiveCallSession && !isConnectedToCall && !isViewingCall ? joinCallButton : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, !isVideoRoom && videoCallButton, !useElementCallExclusively && !isVideoRoom && voiceCallButton), /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: (0, _languageHandler._t)("right_panel|room_summary_card|title") }, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, { onClick: evt => { evt.stopPropagation(); _RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.RoomSummary); }, "aria-label": (0, _languageHandler._t)("right_panel|room_summary_card|title") }, /*#__PURE__*/_react.default.createElement(_infoSolid.default, null))), showChatButton && /*#__PURE__*/_react.default.createElement(_VideoRoomChatButton.VideoRoomChatButton, { room: room }), /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: (0, _languageHandler._t)("common|threads") }, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, { indicator: (0, _notifications.notificationLevelToIndicator)(threadNotifications), onClick: evt => { evt.stopPropagation(); _RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.ThreadPanel); _PosthogTrackers.default.trackInteraction("WebRoomHeaderButtonsThreadsButton", evt); }, "aria-label": (0, _languageHandler._t)("common|threads") }, /*#__PURE__*/_react.default.createElement(_threadsSolid.default, null))), notificationsEnabled && /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, { label: (0, _languageHandler._t)("notifications|enable_prompt_toast_title") }, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, { indicator: (0, _notifications.notificationLevelToIndicator)(globalNotificationState.level), onClick: evt => { evt.stopPropagation(); _RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.NotificationPanel); }, "aria-label": (0, _languageHandler._t)("notifications|enable_prompt_toast_title") }, /*#__PURE__*/_react.default.createElement(_notificationsSolid.default, null)))), !isDirectMessage && /*#__PURE__*/_react.default.createElement(_compoundWeb.Body, { as: "div", size: "sm", weight: "medium" }, /*#__PURE__*/_react.default.createElement(_FacePile.default, { className: "mx_RoomHeader_members", members: members.slice(0, 3), size: "20px", overflow: false, viewUserOnClick: false, tooltipLabel: (0, _languageHandler._t)("room|header_face_pile_tooltip"), onClick: e => { _RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.RoomMemberList); e.stopPropagation(); }, "aria-label": (0, _languageHandler._t)("common|n_members", { count: memberCount }) }, (0, _FormattingUtils.formatCount)(memberCount)))), askToJoinEnabled && /*#__PURE__*/_react.default.createElement(_RoomKnocksBar.RoomKnocksBar, { room: room })); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY29tcG91bmRXZWIiLCJfdmlkZW9DYWxsU29saWQiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX3ZvaWNlQ2FsbCIsIl9jbG9zZSIsIl90aHJlYWRzU29saWQiLCJfaW5mb1NvbGlkIiwiX25vdGlmaWNhdGlvbnNTb2xpZCIsIl92ZXJpZmllZCIsIl9lcnJvciIsIl9wdWJsaWMiLCJfbWF0cml4IiwiX3VzZVJvb21OYW1lIiwiX1JpZ2h0UGFuZWxTdG9yZVBoYXNlcyIsIl9NYXRyaXhDbGllbnRDb250ZXh0IiwiX3VzZVJvb21NZW1iZXJzIiwiX2xhbmd1YWdlSGFuZGxlciIsIl9GbGV4IiwiX0JveCIsIl91c2VSb29tQ2FsbCIsIl91c2VSb29tVGhyZWFkTm90aWZpY2F0aW9ucyIsIl91c2VHbG9iYWxOb3RpZmljYXRpb25TdGF0ZSIsIl9TZGtDb25maWciLCJfdXNlU2V0dGluZ3MiLCJfdXNlRW5jcnlwdGlvblN0YXR1cyIsIl9TaGllbGRVdGlscyIsIl9GYWNlUGlsZSIsIl91c2VSb29tU3RhdGUiLCJfUm9vbUF2YXRhciIsIl9Gb3JtYXR0aW5nVXRpbHMiLCJfUmlnaHRQYW5lbFN0b3JlIiwiX1Bvc3Rob2dUcmFja2VycyIsIl9WaWRlb1Jvb21DaGF0QnV0dG9uIiwiX1Jvb21Lbm9ja3NCYXIiLCJfdmlkZW9Sb29tcyIsIl9ub3RpZmljYXRpb25zIiwiX0NhbGxHdWVzdExpbmtCdXR0b24iLCJfV2l0aFByZXNlbmNlSW5kaWNhdG9yIiwiX1Jvb21Db250ZXh0IiwiX1Jvb21WaWV3IiwiX2Rpc3BhdGNoZXIiLCJfUm9vbVNldHRpbmdzRGlhbG9nIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0IiwiUm9vbUhlYWRlciIsInJvb20iLCJhZGRpdGlvbmFsQnV0dG9ucyIsIm9vYkRhdGEiLCJjbGllbnQiLCJ1c2VNYXRyaXhDbGllbnRDb250ZXh0Iiwicm9vbU5hbWUiLCJ1c2VSb29tTmFtZSIsImpvaW5SdWxlIiwidXNlUm9vbVN0YXRlIiwic3RhdGUiLCJnZXRKb2luUnVsZSIsIm1lbWJlcnMiLCJ1c2VSb29tTWVtYmVycyIsIm1lbWJlckNvdW50IiwidXNlUm9vbU1lbWJlckNvdW50IiwidGhyb3R0bGVXYWl0Iiwidm9pY2VDYWxsRGlzYWJsZWRSZWFzb24iLCJ2b2ljZUNhbGxDbGljayIsInZpZGVvQ2FsbERpc2FibGVkUmVhc29uIiwidmlkZW9DYWxsQ2xpY2siLCJ0b2dnbGVDYWxsTWF4aW1pemVkIiwidG9nZ2xlQ2FsbCIsImlzVmlld2luZ0NhbGwiLCJpc0Nvbm5lY3RlZFRvQ2FsbCIsImhhc0FjdGl2ZUNhbGxTZXNzaW9uIiwiY2FsbE9wdGlvbnMiLCJzaG93Vm9pY2VDYWxsQnV0dG9uIiwic2hvd1ZpZGVvQ2FsbEJ1dHRvbiIsInVzZVJvb21DYWxsIiwiZ3JvdXBDYWxsc0VuYWJsZWQiLCJ1c2VGZWF0dXJlRW5hYmxlZCIsInVzZUVsZW1lbnRDYWxsRXhjbHVzaXZlbHkiLCJ1c2VNZW1vIiwiU2RrQ29uZmlnIiwidXNlX2V4Y2x1c2l2ZWx5IiwidGhyZWFkTm90aWZpY2F0aW9ucyIsInVzZVJvb21UaHJlYWROb3RpZmljYXRpb25zIiwiZ2xvYmFsTm90aWZpY2F0aW9uU3RhdGUiLCJ1c2VHbG9iYWxOb3RpZmljYXRpb25TdGF0ZSIsImRtTWVtYmVyIiwidXNlRG1NZW1iZXIiLCJpc0RpcmVjdE1lc3NhZ2UiLCJlMmVTdGF0dXMiLCJ1c2VFbmNyeXB0aW9uU3RhdHVzIiwibm90aWZpY2F0aW9uc0VuYWJsZWQiLCJhc2tUb0pvaW5FbmFibGVkIiwidmlkZW9DbGljayIsInVzZUNhbGxiYWNrIiwiZXYiLCJ0b2dnbGVDYWxsQnV0dG9uIiwiY3JlYXRlRWxlbWVudCIsIlRvb2x0aXAiLCJsYWJlbCIsIl90IiwiSWNvbkJ1dHRvbiIsIm9uQ2xpY2siLCJqb2luQ2FsbEJ1dHRvbiIsIkJ1dHRvbiIsInNpemUiLCJJY29uIiwiVmlkZW9DYWxsSWNvbiIsImNsYXNzTmFtZSIsImRpc2FibGVkIiwiY29sb3IiLCJjYWxsSWNvbldpdGhUb29sdGlwIiwibWVudU9wZW4iLCJzZXRNZW51T3BlbiIsInVzZVN0YXRlIiwib25PcGVuQ2hhbmdlIiwibmV3T3BlbiIsInN0YXJ0VmlkZW9DYWxsQnV0dG9uIiwiRnJhZ21lbnQiLCJsZW5ndGgiLCJNZW51Iiwib3BlbiIsInRpdGxlIiwidHJpZ2dlciIsInNpZGUiLCJhbGlnbiIsIm1hcCIsIm9wdGlvbiIsIk1lbnVJdGVtIiwia2V5IiwiZ2V0UGxhdGZvcm1DYWxsVHlwZUxhYmVsIiwib25TZWxlY3QiLCJ2b2ljZUNhbGxCdXR0b24iLCJjbG9zZUxvYmJ5QnV0dG9uIiwidmlkZW9DYWxsQnV0dG9uIiwidW5kZWZpbmVkIiwicm9vbUNvbnRleHQiLCJ1c2VDb250ZXh0IiwiUm9vbUNvbnRleHQiLCJpc1ZpZGVvUm9vbSIsImNhbGNJc1ZpZGVvUm9vbSIsInNob3dDaGF0QnV0dG9uIiwibWFpblNwbGl0Q29udGVudFR5cGUiLCJNYWluU3BsaXRDb250ZW50VHlwZSIsIk1heGltaXNlZFdpZGdldCIsIkNhbGwiLCJvbkF2YXRhckNsaWNrIiwiZGVmYXVsdERpc3BhdGNoZXIiLCJkaXNwYXRjaCIsImFjdGlvbiIsImluaXRpYWxfdGFiX2lkIiwiUm9vbVNldHRpbmdzVGFiIiwiR2VuZXJhbCIsIkZsZXgiLCJhcyIsImdhcCIsInRhYkluZGV4IiwiUmlnaHRQYW5lbFN0b3JlIiwiaW5zdGFuY2UiLCJzaG93T3JIaWRlUGhhc2UiLCJSaWdodFBhbmVsUGhhc2VzIiwiUm9vbVN1bW1hcnkiLCJCb3giLCJmbGV4IiwiQm9keSIsIndlaWdodCIsImRpciIsInJvbGUiLCJKb2luUnVsZSIsIlB1YmxpYyIsInBsYWNlbWVudCIsIndpZHRoIiwiaGVpZ2h0IiwiRTJFU3RhdHVzIiwiVmVyaWZpZWQiLCJXYXJuaW5nIiwicHJvcHMiLCJpZCIsImV2ZW50Iiwic3RvcFByb3BhZ2F0aW9uIiwiaWNvbiIsIkNhbGxHdWVzdExpbmtCdXR0b24iLCJldnQiLCJWaWRlb1Jvb21DaGF0QnV0dG9uIiwiaW5kaWNhdG9yIiwibm90aWZpY2F0aW9uTGV2ZWxUb0luZGljYXRvciIsIlRocmVhZFBhbmVsIiwiUG9zdGhvZ1RyYWNrZXJzIiwidHJhY2tJbnRlcmFjdGlvbiIsImxldmVsIiwiTm90aWZpY2F0aW9uUGFuZWwiLCJzbGljZSIsIm92ZXJmbG93Iiwidmlld1VzZXJPbkNsaWNrIiwidG9vbHRpcExhYmVsIiwiUm9vbU1lbWJlckxpc3QiLCJjb3VudCIsImZvcm1hdENvdW50IiwiUm9vbUtub2Nrc0JhciJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3Jvb21zL1Jvb21IZWFkZXIudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDIzIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBSZWFjdCwgeyB1c2VDYWxsYmFjaywgdXNlQ29udGV4dCwgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IEJvZHkgYXMgQm9keVRleHQsIEJ1dHRvbiwgSWNvbkJ1dHRvbiwgTWVudSwgTWVudUl0ZW0sIFRvb2x0aXAgfSBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC13ZWJcIjtcbmltcG9ydCBWaWRlb0NhbGxJY29uIGZyb20gXCJAdmVjdG9yLWltL2NvbXBvdW5kLWRlc2lnbi10b2tlbnMvYXNzZXRzL3dlYi9pY29ucy92aWRlby1jYWxsLXNvbGlkXCI7XG5pbXBvcnQgVm9pY2VDYWxsSWNvbiBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC1kZXNpZ24tdG9rZW5zL2Fzc2V0cy93ZWIvaWNvbnMvdm9pY2UtY2FsbFwiO1xuaW1wb3J0IENsb3NlQ2FsbEljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL2Nsb3NlXCI7XG5pbXBvcnQgVGhyZWFkc0ljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL3RocmVhZHMtc29saWRcIjtcbmltcG9ydCBSb29tSW5mb0ljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL2luZm8tc29saWRcIjtcbmltcG9ydCBOb3RpZmljYXRpb25zSWNvbiBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC1kZXNpZ24tdG9rZW5zL2Fzc2V0cy93ZWIvaWNvbnMvbm90aWZpY2F0aW9ucy1zb2xpZFwiO1xuaW1wb3J0IFZlcmlmaWVkSWNvbiBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC1kZXNpZ24tdG9rZW5zL2Fzc2V0cy93ZWIvaWNvbnMvdmVyaWZpZWRcIjtcbmltcG9ydCBFcnJvckljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL2Vycm9yXCI7XG5pbXBvcnQgUHVibGljSWNvbiBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC1kZXNpZ24tdG9rZW5zL2Fzc2V0cy93ZWIvaWNvbnMvcHVibGljXCI7XG5pbXBvcnQgeyBKb2luUnVsZSwgdHlwZSBSb29tIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuaW1wb3J0IHsgVmlld1Jvb21PcHRzIH0gZnJvbSBcIkBtYXRyaXgtb3JnL3JlYWN0LXNkay1tb2R1bGUtYXBpL2xpYi9saWZlY3ljbGVzL1Jvb21WaWV3TGlmZWN5Y2xlXCI7XG5cbmltcG9ydCB7IHVzZVJvb21OYW1lIH0gZnJvbSBcIi4uLy4uLy4uL2hvb2tzL3VzZVJvb21OYW1lXCI7XG5pbXBvcnQgeyBSaWdodFBhbmVsUGhhc2VzIH0gZnJvbSBcIi4uLy4uLy4uL3N0b3Jlcy9yaWdodC1wYW5lbC9SaWdodFBhbmVsU3RvcmVQaGFzZXNcIjtcbmltcG9ydCB7IHVzZU1hdHJpeENsaWVudENvbnRleHQgfSBmcm9tIFwiLi4vLi4vLi4vY29udGV4dHMvTWF0cml4Q2xpZW50Q29udGV4dFwiO1xuaW1wb3J0IHsgdXNlUm9vbU1lbWJlckNvdW50LCB1c2VSb29tTWVtYmVycyB9IGZyb20gXCIuLi8uLi8uLi9ob29rcy91c2VSb29tTWVtYmVyc1wiO1xuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgeyBGbGV4IH0gZnJvbSBcIi4uLy4uL3V0aWxzL0ZsZXhcIjtcbmltcG9ydCB7IEJveCB9IGZyb20gXCIuLi8uLi91dGlscy9Cb3hcIjtcbmltcG9ydCB7IGdldFBsYXRmb3JtQ2FsbFR5cGVMYWJlbCwgdXNlUm9vbUNhbGwgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3Mvcm9vbS91c2VSb29tQ2FsbFwiO1xuaW1wb3J0IHsgdXNlUm9vbVRocmVhZE5vdGlmaWNhdGlvbnMgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3Mvcm9vbS91c2VSb29tVGhyZWFkTm90aWZpY2F0aW9uc1wiO1xuaW1wb3J0IHsgdXNlR2xvYmFsTm90aWZpY2F0aW9uU3RhdGUgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlR2xvYmFsTm90aWZpY2F0aW9uU3RhdGVcIjtcbmltcG9ydCBTZGtDb25maWcgZnJvbSBcIi4uLy4uLy4uL1Nka0NvbmZpZ1wiO1xuaW1wb3J0IHsgdXNlRmVhdHVyZUVuYWJsZWQgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlU2V0dGluZ3NcIjtcbmltcG9ydCB7IHVzZUVuY3J5cHRpb25TdGF0dXMgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlRW5jcnlwdGlvblN0YXR1c1wiO1xuaW1wb3J0IHsgRTJFU3RhdHVzIH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL1NoaWVsZFV0aWxzXCI7XG5pbXBvcnQgRmFjZVBpbGUgZnJvbSBcIi4uL2VsZW1lbnRzL0ZhY2VQaWxlXCI7XG5pbXBvcnQgeyB1c2VSb29tU3RhdGUgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlUm9vbVN0YXRlXCI7XG5pbXBvcnQgUm9vbUF2YXRhciBmcm9tIFwiLi4vYXZhdGFycy9Sb29tQXZhdGFyXCI7XG5pbXBvcnQgeyBmb3JtYXRDb3VudCB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9Gb3JtYXR0aW5nVXRpbHNcIjtcbmltcG9ydCBSaWdodFBhbmVsU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3N0b3Jlcy9yaWdodC1wYW5lbC9SaWdodFBhbmVsU3RvcmVcIjtcbmltcG9ydCBQb3N0aG9nVHJhY2tlcnMgZnJvbSBcIi4uLy4uLy4uL1Bvc3Rob2dUcmFja2Vyc1wiO1xuaW1wb3J0IHsgVmlkZW9Sb29tQ2hhdEJ1dHRvbiB9IGZyb20gXCIuL1Jvb21IZWFkZXIvVmlkZW9Sb29tQ2hhdEJ1dHRvblwiO1xuaW1wb3J0IHsgUm9vbUtub2Nrc0JhciB9IGZyb20gXCIuL1Jvb21Lbm9ja3NCYXJcIjtcbmltcG9ydCB7IGlzVmlkZW9Sb29tIGFzIGNhbGNJc1ZpZGVvUm9vbSB9IGZyb20gXCIuLi8uLi8uLi91dGlscy92aWRlby1yb29tc1wiO1xuaW1wb3J0IHsgbm90aWZpY2F0aW9uTGV2ZWxUb0luZGljYXRvciB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9ub3RpZmljYXRpb25zXCI7XG5pbXBvcnQgeyBDYWxsR3Vlc3RMaW5rQnV0dG9uIH0gZnJvbSBcIi4vUm9vbUhlYWRlci9DYWxsR3Vlc3RMaW5rQnV0dG9uXCI7XG5pbXBvcnQgeyBCdXR0b25FdmVudCB9IGZyb20gXCIuLi9lbGVtZW50cy9BY2Nlc3NpYmxlQnV0dG9uXCI7XG5pbXBvcnQgV2l0aFByZXNlbmNlSW5kaWNhdG9yLCB7IHVzZURtTWVtYmVyIH0gZnJvbSBcIi4uL2F2YXRhcnMvV2l0aFByZXNlbmNlSW5kaWNhdG9yXCI7XG5pbXBvcnQgeyBJT09CRGF0YSB9IGZyb20gXCIuLi8uLi8uLi9zdG9yZXMvVGhyZWVwaWRJbnZpdGVTdG9yZVwiO1xuaW1wb3J0IFJvb21Db250ZXh0IGZyb20gXCIuLi8uLi8uLi9jb250ZXh0cy9Sb29tQ29udGV4dFwiO1xuaW1wb3J0IHsgTWFpblNwbGl0Q29udGVudFR5cGUgfSBmcm9tIFwiLi4vLi4vc3RydWN0dXJlcy9Sb29tVmlld1wiO1xuaW1wb3J0IGRlZmF1bHREaXNwYXRjaGVyIGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL2Rpc3BhdGNoZXIudHNcIjtcbmltcG9ydCB7IFJvb21TZXR0aW5nc1RhYiB9IGZyb20gXCIuLi9kaWFsb2dzL1Jvb21TZXR0aW5nc0RpYWxvZy50c3hcIjtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUm9vbUhlYWRlcih7XG4gICAgcm9vbSxcbiAgICBhZGRpdGlvbmFsQnV0dG9ucyxcbiAgICBvb2JEYXRhLFxufToge1xuICAgIHJvb206IFJvb207XG4gICAgYWRkaXRpb25hbEJ1dHRvbnM/OiBWaWV3Um9vbU9wdHNbXCJidXR0b25zXCJdO1xuICAgIG9vYkRhdGE/OiBJT09CRGF0YTtcbn0pOiBKU1guRWxlbWVudCB7XG4gICAgY29uc3QgY2xpZW50ID0gdXNlTWF0cml4Q2xpZW50Q29udGV4dCgpO1xuXG4gICAgY29uc3Qgcm9vbU5hbWUgPSB1c2VSb29tTmFtZShyb29tKTtcbiAgICBjb25zdCBqb2luUnVsZSA9IHVzZVJvb21TdGF0ZShyb29tLCAoc3RhdGUpID0+IHN0YXRlLmdldEpvaW5SdWxlKCkpO1xuXG4gICAgY29uc3QgbWVtYmVycyA9IHVzZVJvb21NZW1iZXJzKHJvb20sIDI1MDApO1xuICAgIGNvbnN0IG1lbWJlckNvdW50ID0gdXNlUm9vbU1lbWJlckNvdW50KHJvb20sIHsgdGhyb3R0bGVXYWl0OiAyNTAwIH0pO1xuXG4gICAgY29uc3Qge1xuICAgICAgICB2b2ljZUNhbGxEaXNhYmxlZFJlYXNvbixcbiAgICAgICAgdm9pY2VDYWxsQ2xpY2ssXG4gICAgICAgIHZpZGVvQ2FsbERpc2FibGVkUmVhc29uLFxuICAgICAgICB2aWRlb0NhbGxDbGljayxcbiAgICAgICAgdG9nZ2xlQ2FsbE1heGltaXplZDogdG9nZ2xlQ2FsbCxcbiAgICAgICAgaXNWaWV3aW5nQ2FsbCxcbiAgICAgICAgaXNDb25uZWN0ZWRUb0NhbGwsXG4gICAgICAgIGhhc0FjdGl2ZUNhbGxTZXNzaW9uLFxuICAgICAgICBjYWxsT3B0aW9ucyxcbiAgICAgICAgc2hvd1ZvaWNlQ2FsbEJ1dHRvbixcbiAgICAgICAgc2hvd1ZpZGVvQ2FsbEJ1dHRvbixcbiAgICB9ID0gdXNlUm9vbUNhbGwocm9vbSk7XG5cbiAgICBjb25zdCBncm91cENhbGxzRW5hYmxlZCA9IHVzZUZlYXR1cmVFbmFibGVkKFwiZmVhdHVyZV9ncm91cF9jYWxsc1wiKTtcbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWwgbW9kZSB3aGVyZSBvbmx5IEVsZW1lbnQgQ2FsbCBpcyB1c2VkLiBJbiB0aGlzIGNhc2Ugd2Ugd2FudCB0b1xuICAgICAqIGhpZGUgdGhlIHZvaWNlIGNhbGwgYnV0dG9uXG4gICAgICovXG4gICAgY29uc3QgdXNlRWxlbWVudENhbGxFeGNsdXNpdmVseSA9IHVzZU1lbW8oKCkgPT4ge1xuICAgICAgICByZXR1cm4gU2RrQ29uZmlnLmdldChcImVsZW1lbnRfY2FsbFwiKS51c2VfZXhjbHVzaXZlbHkgJiYgZ3JvdXBDYWxsc0VuYWJsZWQ7XG4gICAgfSwgW2dyb3VwQ2FsbHNFbmFibGVkXSk7XG5cbiAgICBjb25zdCB0aHJlYWROb3RpZmljYXRpb25zID0gdXNlUm9vbVRocmVhZE5vdGlmaWNhdGlvbnMocm9vbSk7XG4gICAgY29uc3QgZ2xvYmFsTm90aWZpY2F0aW9uU3RhdGUgPSB1c2VHbG9iYWxOb3RpZmljYXRpb25TdGF0ZSgpO1xuXG4gICAgY29uc3QgZG1NZW1iZXIgPSB1c2VEbU1lbWJlcihyb29tKTtcbiAgICBjb25zdCBpc0RpcmVjdE1lc3NhZ2UgPSAhIWRtTWVtYmVyO1xuICAgIGNvbnN0IGUyZVN0YXR1cyA9IHVzZUVuY3J5cHRpb25TdGF0dXMoY2xpZW50LCByb29tKTtcblxuICAgIGNvbnN0IG5vdGlmaWNhdGlvbnNFbmFibGVkID0gdXNlRmVhdHVyZUVuYWJsZWQoXCJmZWF0dXJlX25vdGlmaWNhdGlvbnNcIik7XG5cbiAgICBjb25zdCBhc2tUb0pvaW5FbmFibGVkID0gdXNlRmVhdHVyZUVuYWJsZWQoXCJmZWF0dXJlX2Fza190b19qb2luXCIpO1xuXG4gICAgY29uc3QgdmlkZW9DbGljayA9IHVzZUNhbGxiYWNrKFxuICAgICAgICAoZXY6IFJlYWN0Lk1vdXNlRXZlbnQpID0+IHZpZGVvQ2FsbENsaWNrKGV2LCBjYWxsT3B0aW9uc1swXSksXG4gICAgICAgIFtjYWxsT3B0aW9ucywgdmlkZW9DYWxsQ2xpY2tdLFxuICAgICk7XG5cbiAgICBjb25zdCB0b2dnbGVDYWxsQnV0dG9uID0gKFxuICAgICAgICA8VG9vbHRpcCBsYWJlbD17aXNWaWV3aW5nQ2FsbCA/IF90KFwidm9pcHxtaW5pbWlzZV9jYWxsXCIpIDogX3QoXCJ2b2lwfG1heGltaXNlX2NhbGxcIil9PlxuICAgICAgICAgICAgPEljb25CdXR0b24gb25DbGljaz17dG9nZ2xlQ2FsbH0+XG4gICAgICAgICAgICAgICAgPFZpZGVvQ2FsbEljb24gLz5cbiAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgPC9Ub29sdGlwPlxuICAgICk7XG5cbiAgICBjb25zdCBqb2luQ2FsbEJ1dHRvbiA9IChcbiAgICAgICAgPFRvb2x0aXAgbGFiZWw9e3ZpZGVvQ2FsbERpc2FibGVkUmVhc29uID8/IF90KFwidm9pcHx2aWRlb19jYWxsXCIpfT5cbiAgICAgICAgICAgIDxCdXR0b25cbiAgICAgICAgICAgICAgICBzaXplPVwic21cIlxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3ZpZGVvQ2xpY2t9XG4gICAgICAgICAgICAgICAgSWNvbj17VmlkZW9DYWxsSWNvbn1cbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2pvaW5fYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBkaXNhYmxlZD17ISF2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbn1cbiAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e3ZpZGVvQ2FsbERpc2FibGVkUmVhc29uID8/IF90KFwiYWN0aW9ufGpvaW5cIil9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAge190KFwiYWN0aW9ufGpvaW5cIil9XG4gICAgICAgICAgICA8L0J1dHRvbj5cbiAgICAgICAgPC9Ub29sdGlwPlxuICAgICk7XG5cbiAgICBjb25zdCBjYWxsSWNvbldpdGhUb29sdGlwID0gKFxuICAgICAgICA8VG9vbHRpcCBsYWJlbD17dmlkZW9DYWxsRGlzYWJsZWRSZWFzb24gPz8gX3QoXCJ2b2lwfHZpZGVvX2NhbGxcIil9PlxuICAgICAgICAgICAgPFZpZGVvQ2FsbEljb24gLz5cbiAgICAgICAgPC9Ub29sdGlwPlxuICAgICk7XG5cbiAgICBjb25zdCBbbWVudU9wZW4sIHNldE1lbnVPcGVuXSA9IHVzZVN0YXRlKGZhbHNlKTtcblxuICAgIGNvbnN0IG9uT3BlbkNoYW5nZSA9IHVzZUNhbGxiYWNrKFxuICAgICAgICAobmV3T3BlbjogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgaWYgKCF2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbikgc2V0TWVudU9wZW4obmV3T3Blbik7XG4gICAgICAgIH0sXG4gICAgICAgIFt2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbl0sXG4gICAgKTtcblxuICAgIGNvbnN0IHN0YXJ0VmlkZW9DYWxsQnV0dG9uID0gKFxuICAgICAgICA8PlxuICAgICAgICAgICAgey8qIENhbiBiZSBlaXRoZXIgYSBtZW51IG9yIGp1c3QgYSBidXR0b24gZGVwZW5kaW5nIG9uIHRoZSBudW1iZXIgb2YgY2FsbCBvcHRpb25zLiovfVxuICAgICAgICAgICAge2NhbGxPcHRpb25zLmxlbmd0aCA+IDEgPyAoXG4gICAgICAgICAgICAgICAgPE1lbnVcbiAgICAgICAgICAgICAgICAgICAgb3Blbj17bWVudU9wZW59XG4gICAgICAgICAgICAgICAgICAgIG9uT3BlbkNoYW5nZT17b25PcGVuQ2hhbmdlfVxuICAgICAgICAgICAgICAgICAgICB0aXRsZT17X3QoXCJ2b2lwfHZpZGVvX2NhbGxfdXNpbmdcIil9XG4gICAgICAgICAgICAgICAgICAgIHRyaWdnZXI9e1xuICAgICAgICAgICAgICAgICAgICAgICAgPEljb25CdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17ISF2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXt2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbiA/PyBfdChcInZvaXB8dmlkZW9fY2FsbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2FsbEljb25XaXRoVG9vbHRpcH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzaWRlPVwibGVmdFwiXG4gICAgICAgICAgICAgICAgICAgIGFsaWduPVwic3RhcnRcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge2NhbGxPcHRpb25zLm1hcCgob3B0aW9uKSA9PiAoXG4gICAgICAgICAgICAgICAgICAgICAgICA8TWVudUl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk9e29wdGlvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17Z2V0UGxhdGZvcm1DYWxsVHlwZUxhYmVsKG9wdGlvbil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17Z2V0UGxhdGZvcm1DYWxsVHlwZUxhYmVsKG9wdGlvbil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KGV2KSA9PiB2aWRlb0NhbGxDbGljayhldiwgb3B0aW9uKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJY29uPXtWaWRlb0NhbGxJY29ufVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uU2VsZWN0PXsoKSA9PiB7fSAvKiBEdW1teSBoYW5kbGVyIHNpbmNlIHdlIHdhbnQgdGhlIGNsaWNrIGV2ZW50LiovfVxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgKSl9XG4gICAgICAgICAgICAgICAgPC9NZW51PlxuICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgICA8SWNvbkJ1dHRvblxuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17ISF2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbn1cbiAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17dmlkZW9DYWxsRGlzYWJsZWRSZWFzb24gPz8gX3QoXCJ2b2lwfHZpZGVvX2NhbGxcIil9XG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3ZpZGVvQ2xpY2t9XG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7Y2FsbEljb25XaXRoVG9vbHRpcH1cbiAgICAgICAgICAgICAgICA8L0ljb25CdXR0b24+XG4gICAgICAgICAgICApfVxuICAgICAgICA8Lz5cbiAgICApO1xuICAgIGxldCB2b2ljZUNhbGxCdXR0b246IEpTWC5FbGVtZW50IHwgdW5kZWZpbmVkID0gKFxuICAgICAgICA8VG9vbHRpcCBsYWJlbD17dm9pY2VDYWxsRGlzYWJsZWRSZWFzb24gPz8gX3QoXCJ2b2lwfHZvaWNlX2NhbGxcIil9PlxuICAgICAgICAgICAgPEljb25CdXR0b25cbiAgICAgICAgICAgICAgICAvLyBXZSBuZWVkIGJvdGg6IGlzVmlld2luZ0NhbGwgYW5kIGlzQ29ubmVjdGVkVG9DYWxsXG4gICAgICAgICAgICAgICAgLy8gIC0gaW4gdGhlIExvYmJ5IHdlIGFyZSB2aWV3aW5nIGEgY2FsbCBidXQgYXJlIG5vdCBjb25uZWN0ZWQgdG8gaXQuXG4gICAgICAgICAgICAgICAgLy8gIC0gaW4gcGlwIHZpZXcgd2UgYXJlIGNvbm5lY3RlZCB0byB0aGUgY2FsbCBidXQgbm90IHZpZXdpbmcgaXQuXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ9eyEhdm9pY2VDYWxsRGlzYWJsZWRSZWFzb24gfHwgaXNWaWV3aW5nQ2FsbCB8fCBpc0Nvbm5lY3RlZFRvQ2FsbH1cbiAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXt2b2ljZUNhbGxEaXNhYmxlZFJlYXNvbiA/PyBfdChcInZvaXB8dm9pY2VfY2FsbFwiKX1cbiAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZXYpID0+IHZvaWNlQ2FsbENsaWNrKGV2LCBjYWxsT3B0aW9uc1swXSl9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPFZvaWNlQ2FsbEljb24gLz5cbiAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgPC9Ub29sdGlwPlxuICAgICk7XG4gICAgY29uc3QgY2xvc2VMb2JieUJ1dHRvbiA9IChcbiAgICAgICAgPFRvb2x0aXAgbGFiZWw9e190KFwidm9pcHxjbG9zZV9sb2JieVwiKX0+XG4gICAgICAgICAgICA8SWNvbkJ1dHRvbiBvbkNsaWNrPXt0b2dnbGVDYWxsfT5cbiAgICAgICAgICAgICAgICA8Q2xvc2VDYWxsSWNvbiAvPlxuICAgICAgICAgICAgPC9JY29uQnV0dG9uPlxuICAgICAgICA8L1Rvb2x0aXA+XG4gICAgKTtcbiAgICBsZXQgdmlkZW9DYWxsQnV0dG9uOiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZCA9IHN0YXJ0VmlkZW9DYWxsQnV0dG9uO1xuICAgIGlmIChpc0Nvbm5lY3RlZFRvQ2FsbCkge1xuICAgICAgICB2aWRlb0NhbGxCdXR0b24gPSB0b2dnbGVDYWxsQnV0dG9uO1xuICAgIH0gZWxzZSBpZiAoaXNWaWV3aW5nQ2FsbCkge1xuICAgICAgICB2aWRlb0NhbGxCdXR0b24gPSBjbG9zZUxvYmJ5QnV0dG9uO1xuICAgIH1cblxuICAgIGlmICghc2hvd1ZpZGVvQ2FsbEJ1dHRvbikge1xuICAgICAgICB2aWRlb0NhbGxCdXR0b24gPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmICghc2hvd1ZvaWNlQ2FsbEJ1dHRvbikge1xuICAgICAgICB2b2ljZUNhbGxCdXR0b24gPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3Qgcm9vbUNvbnRleHQgPSB1c2VDb250ZXh0KFJvb21Db250ZXh0KTtcbiAgICBjb25zdCBpc1ZpZGVvUm9vbSA9IGNhbGNJc1ZpZGVvUm9vbShyb29tKTtcbiAgICBjb25zdCBzaG93Q2hhdEJ1dHRvbiA9XG4gICAgICAgIGlzVmlkZW9Sb29tIHx8XG4gICAgICAgIHJvb21Db250ZXh0Lm1haW5TcGxpdENvbnRlbnRUeXBlID09PSBNYWluU3BsaXRDb250ZW50VHlwZS5NYXhpbWlzZWRXaWRnZXQgfHxcbiAgICAgICAgcm9vbUNvbnRleHQubWFpblNwbGl0Q29udGVudFR5cGUgPT09IE1haW5TcGxpdENvbnRlbnRUeXBlLkNhbGw7XG5cbiAgICBjb25zdCBvbkF2YXRhckNsaWNrID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBkZWZhdWx0RGlzcGF0Y2hlci5kaXNwYXRjaCh7XG4gICAgICAgICAgICBhY3Rpb246IFwib3Blbl9yb29tX3NldHRpbmdzXCIsXG4gICAgICAgICAgICBpbml0aWFsX3RhYl9pZDogUm9vbVNldHRpbmdzVGFiLkdlbmVyYWwsXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8PlxuICAgICAgICAgICAgPEZsZXggYXM9XCJoZWFkZXJcIiBhbGlnbj1cImNlbnRlclwiIGdhcD1cInZhcigtLWNwZC1zcGFjZS0zeClcIiBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyIGxpZ2h0LXBhbmVsXCI+XG4gICAgICAgICAgICAgICAgPFdpdGhQcmVzZW5jZUluZGljYXRvciByb29tPXtyb29tfSBzaXplPVwiOHB4XCI+XG4gICAgICAgICAgICAgICAgICAgIHsvKiBXZSBoaWRlIHRoaXMgZnJvbSB0aGUgdGFiSW5kZXggbGlzdCBhcyBpdCBpcyBhIHBvaW50ZXIgc2hvcnRjdXQgYW5kIHN1cGVyZmx1b3VzIGZvciBhMTF5ICovfVxuICAgICAgICAgICAgICAgICAgICA8Um9vbUF2YXRhclxuICAgICAgICAgICAgICAgICAgICAgICAgcm9vbT17cm9vbX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9XCI0MHB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9vYkRhdGE9e29vYkRhdGF9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXtvbkF2YXRhckNsaWNrfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGFiSW5kZXg9ey0xfVxuICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17X3QoXCJyb29tfGhlYWRlcl9hdmF0YXJfb3Blbl9zZXR0aW5nc19sYWJlbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8L1dpdGhQcmVzZW5jZUluZGljYXRvcj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e190KFwicmlnaHRfcGFuZWx8cm9vbV9zdW1tYXJ5X2NhcmR8dGl0bGVcIil9XG4gICAgICAgICAgICAgICAgICAgIHRhYkluZGV4PXswfVxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBSaWdodFBhbmVsU3RvcmUuaW5zdGFuY2Uuc2hvd09ySGlkZVBoYXNlKFJpZ2h0UGFuZWxQaGFzZXMuUm9vbVN1bW1hcnkpfVxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2luZm9XcmFwcGVyXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxCb3ggZmxleD1cIjFcIiBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2luZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxCb2R5VGV4dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzPVwiZGl2XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPVwibGdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlaWdodD1cInNlbWlib2xkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXI9XCJhdXRvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2xlPVwiaGVhZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sZXZlbD17MX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2hlYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cIm14X1Jvb21IZWFkZXJfdHJ1bmNhdGVkIG14X2xpbmVDbGFtcFwiPntyb29tTmFtZX08L3NwYW4+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IWlzRGlyZWN0TWVzc2FnZSAmJiBqb2luUnVsZSA9PT0gSm9pblJ1bGUuUHVibGljICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPFRvb2x0aXAgbGFiZWw9e190KFwiY29tbW9ufHB1YmxpY19yb29tXCIpfSBwbGFjZW1lbnQ9XCJyaWdodFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPFB1YmxpY0ljb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aD1cIjE2cHhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodD1cIjE2cHhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1Jvb21IZWFkZXJfaWNvbiB0ZXh0LXNlY29uZGFyeVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17X3QoXCJjb21tb258cHVibGljX3Jvb21cIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L1Rvb2x0aXA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKX1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtpc0RpcmVjdE1lc3NhZ2UgJiYgZTJlU3RhdHVzID09PSBFMkVTdGF0dXMuVmVyaWZpZWQgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8VG9vbHRpcCBsYWJlbD17X3QoXCJjb21tb258dmVyaWZpZWRcIil9IHBsYWNlbWVudD1cInJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8VmVyaWZpZWRJY29uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg9XCIxNnB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9XCIxNnB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2ljb24gbXhfVmVyaWZpZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e190KFwiY29tbW9ufHZlcmlmaWVkXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9Ub29sdGlwPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICl9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7aXNEaXJlY3RNZXNzYWdlICYmIGUyZVN0YXR1cyA9PT0gRTJFU3RhdHVzLldhcm5pbmcgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8VG9vbHRpcCBsYWJlbD17X3QoXCJyb29tfGhlYWRlcl91bnRydXN0ZWRfbGFiZWxcIil9IHBsYWNlbWVudD1cInJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8RXJyb3JJY29uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg9XCIxNnB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9XCIxNnB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2ljb24gbXhfVW50cnVzdGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXtfdChcInJvb218aGVhZGVyX3VudHJ1c3RlZF9sYWJlbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvVG9vbHRpcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9Cb2R5VGV4dD5cbiAgICAgICAgICAgICAgICAgICAgPC9Cb3g+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPEZsZXggYWxpZ249XCJjZW50ZXJcIiBnYXA9XCJ2YXIoLS1jcGQtc3BhY2UtMngpXCI+XG4gICAgICAgICAgICAgICAgICAgIHthZGRpdGlvbmFsQnV0dG9ucz8ubWFwKChwcm9wcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGFiZWwgPSBwcm9wcy5sYWJlbCgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxUb29sdGlwIGxhYmVsPXtsYWJlbH0ga2V5PXtwcm9wcy5pZH0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxJY29uQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXtsYWJlbH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eyhldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BzLm9uQ2xpY2soKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt0eXBlb2YgcHJvcHMuaWNvbiA9PT0gXCJmdW5jdGlvblwiID8gcHJvcHMuaWNvbigpIDogcHJvcHMuaWNvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9JY29uQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvVG9vbHRpcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pfVxuXG4gICAgICAgICAgICAgICAgICAgIHtpc1ZpZXdpbmdDYWxsICYmIDxDYWxsR3Vlc3RMaW5rQnV0dG9uIHJvb209e3Jvb219IC8+fVxuXG4gICAgICAgICAgICAgICAgICAgIHtoYXNBY3RpdmVDYWxsU2Vzc2lvbiAmJiAhaXNDb25uZWN0ZWRUb0NhbGwgJiYgIWlzVmlld2luZ0NhbGwgPyAoXG4gICAgICAgICAgICAgICAgICAgICAgICBqb2luQ2FsbEJ1dHRvblxuICAgICAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IWlzVmlkZW9Sb29tICYmIHZpZGVvQ2FsbEJ1dHRvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IXVzZUVsZW1lbnRDYWxsRXhjbHVzaXZlbHkgJiYgIWlzVmlkZW9Sb29tICYmIHZvaWNlQ2FsbEJ1dHRvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvPlxuICAgICAgICAgICAgICAgICAgICApfVxuXG4gICAgICAgICAgICAgICAgICAgIDxUb29sdGlwIGxhYmVsPXtfdChcInJpZ2h0X3BhbmVsfHJvb21fc3VtbWFyeV9jYXJkfHRpdGxlXCIpfT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxJY29uQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KGV2dCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJpZ2h0UGFuZWxTdG9yZS5pbnN0YW5jZS5zaG93T3JIaWRlUGhhc2UoUmlnaHRQYW5lbFBoYXNlcy5Sb29tU3VtbWFyeSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXtfdChcInJpZ2h0X3BhbmVsfHJvb21fc3VtbWFyeV9jYXJkfHRpdGxlXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxSb29tSW5mb0ljb24gLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9Ub29sdGlwPlxuXG4gICAgICAgICAgICAgICAgICAgIHtzaG93Q2hhdEJ1dHRvbiAmJiA8VmlkZW9Sb29tQ2hhdEJ1dHRvbiByb29tPXtyb29tfSAvPn1cblxuICAgICAgICAgICAgICAgICAgICA8VG9vbHRpcCBsYWJlbD17X3QoXCJjb21tb258dGhyZWFkc1wiKX0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8SWNvbkJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGljYXRvcj17bm90aWZpY2F0aW9uTGV2ZWxUb0luZGljYXRvcih0aHJlYWROb3RpZmljYXRpb25zKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZXZ0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmlnaHRQYW5lbFN0b3JlLmluc3RhbmNlLnNob3dPckhpZGVQaGFzZShSaWdodFBhbmVsUGhhc2VzLlRocmVhZFBhbmVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9zdGhvZ1RyYWNrZXJzLnRyYWNrSW50ZXJhY3Rpb24oXCJXZWJSb29tSGVhZGVyQnV0dG9uc1RocmVhZHNCdXR0b25cIiwgZXZ0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e190KFwiY29tbW9ufHRocmVhZHNcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPFRocmVhZHNJY29uIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L0ljb25CdXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvVG9vbHRpcD5cbiAgICAgICAgICAgICAgICAgICAge25vdGlmaWNhdGlvbnNFbmFibGVkICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIDxUb29sdGlwIGxhYmVsPXtfdChcIm5vdGlmaWNhdGlvbnN8ZW5hYmxlX3Byb21wdF90b2FzdF90aXRsZVwiKX0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPEljb25CdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kaWNhdG9yPXtub3RpZmljYXRpb25MZXZlbFRvSW5kaWNhdG9yKGdsb2JhbE5vdGlmaWNhdGlvblN0YXRlLmxldmVsKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KGV2dCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmlnaHRQYW5lbFN0b3JlLmluc3RhbmNlLnNob3dPckhpZGVQaGFzZShSaWdodFBhbmVsUGhhc2VzLk5vdGlmaWNhdGlvblBhbmVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17X3QoXCJub3RpZmljYXRpb25zfGVuYWJsZV9wcm9tcHRfdG9hc3RfdGl0bGVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Tm90aWZpY2F0aW9uc0ljb24gLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L0ljb25CdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L1Rvb2x0aXA+XG4gICAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgPC9GbGV4PlxuICAgICAgICAgICAgICAgIHshaXNEaXJlY3RNZXNzYWdlICYmIChcbiAgICAgICAgICAgICAgICAgICAgPEJvZHlUZXh0IGFzPVwiZGl2XCIgc2l6ZT1cInNtXCIgd2VpZ2h0PVwibWVkaXVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8RmFjZVBpbGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX21lbWJlcnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbWJlcnM9e21lbWJlcnMuc2xpY2UoMCwgMyl9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT1cIjIwcHhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJmbG93PXtmYWxzZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3VXNlck9uQ2xpY2s9e2ZhbHNlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBMYWJlbD17X3QoXCJyb29tfGhlYWRlcl9mYWNlX3BpbGVfdG9vbHRpcFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZTogQnV0dG9uRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmlnaHRQYW5lbFN0b3JlLmluc3RhbmNlLnNob3dPckhpZGVQaGFzZShSaWdodFBhbmVsUGhhc2VzLlJvb21NZW1iZXJMaXN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e190KFwiY29tbW9ufG5fbWVtYmVyc1wiLCB7IGNvdW50OiBtZW1iZXJDb3VudCB9KX1cbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Zm9ybWF0Q291bnQobWVtYmVyQ291bnQpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9GYWNlUGlsZT5cbiAgICAgICAgICAgICAgICAgICAgPC9Cb2R5VGV4dD5cbiAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgPC9GbGV4PlxuICAgICAgICAgICAge2Fza1RvSm9pbkVuYWJsZWQgJiYgPFJvb21Lbm9ja3NCYXIgcm9vbT17cm9vbX0gLz59XG4gICAgICAgIDwvPlxuICAgICk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxZQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxlQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSSxVQUFBLEdBQUFELHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSyxNQUFBLEdBQUFGLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBTSxhQUFBLEdBQUFILHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBTyxVQUFBLEdBQUFKLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBUSxtQkFBQSxHQUFBTCxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQVMsU0FBQSxHQUFBTixzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQVUsTUFBQSxHQUFBUCxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQVcsT0FBQSxHQUFBUixzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQVksT0FBQSxHQUFBWixPQUFBO0FBR0EsSUFBQWEsWUFBQSxHQUFBYixPQUFBO0FBQ0EsSUFBQWMsc0JBQUEsR0FBQWQsT0FBQTtBQUNBLElBQUFlLG9CQUFBLEdBQUFmLE9BQUE7QUFDQSxJQUFBZ0IsZUFBQSxHQUFBaEIsT0FB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