matrix-react-sdk
Version:
SDK for matrix.org using React
340 lines (335 loc) • 63 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _matrix = require("matrix-js-sdk/src/matrix");
var _react = _interopRequireWildcard(require("react"));
var _compoundWeb = require("@vector-im/compound-web");
var _MatrixClientContext = _interopRequireDefault(require("../../../contexts/MatrixClientContext"));
var _UIComponents = require("../../../customisations/helpers/UIComponents");
var _actions = require("../../../dispatcher/actions");
var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher"));
var _useDispatcher = require("../../../hooks/useDispatcher");
var _useEventEmitter = require("../../../hooks/useEventEmitter");
var _useSettings = require("../../../hooks/useSettings");
var _languageHandler = require("../../../languageHandler");
var _PosthogTrackers = _interopRequireDefault(require("../../../PosthogTrackers"));
var _UIFeature = require("../../../settings/UIFeature");
var _spaces = require("../../../stores/spaces");
var _SpaceStore = _interopRequireDefault(require("../../../stores/spaces/SpaceStore"));
var _space = require("../../../utils/space");
var _ContextMenu = require("../../structures/ContextMenu");
var _BetaCard = require("../beta/BetaCard");
var _IconizedContextMenu = _interopRequireWildcard(require("../context_menus/IconizedContextMenu"));
var _SpaceContextMenu = _interopRequireDefault(require("../context_menus/SpaceContextMenu"));
var _InlineSpinner = _interopRequireDefault(require("../elements/InlineSpinner"));
var _SpacePanel = require("../spaces/SpacePanel");
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, 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.
*/
const contextMenuBelow = elementRect => {
// align the context menu's icons with the icon which opened the context menu
const left = elementRect.left + window.scrollX;
const top = elementRect.bottom + window.scrollY + 12;
const chevronFace = _ContextMenu.ChevronFace.None;
return {
left,
top,
chevronFace
};
};
// Long-running actions that should trigger a spinner
var PendingActionType = /*#__PURE__*/function (PendingActionType) {
PendingActionType[PendingActionType["JoinRoom"] = 0] = "JoinRoom";
PendingActionType[PendingActionType["BulkRedact"] = 1] = "BulkRedact";
return PendingActionType;
}(PendingActionType || {});
const usePendingActions = () => {
const cli = (0, _react.useContext)(_MatrixClientContext.default);
const [actions, setActions] = (0, _react.useState)(new Map());
const addAction = (type, key) => {
const keys = new Set(actions.get(type));
keys.add(key);
setActions(new Map(actions).set(type, keys));
};
const removeAction = (type, key) => {
const keys = new Set(actions.get(type));
if (keys.delete(key)) {
setActions(new Map(actions).set(type, keys));
}
};
(0, _useDispatcher.useDispatcher)(_dispatcher.default, payload => {
switch (payload.action) {
case _actions.Action.JoinRoom:
addAction(PendingActionType.JoinRoom, payload.roomId);
break;
case _actions.Action.JoinRoomReady:
case _actions.Action.JoinRoomError:
removeAction(PendingActionType.JoinRoom, payload.roomId);
break;
case _actions.Action.BulkRedactStart:
addAction(PendingActionType.BulkRedact, payload.roomId);
break;
case _actions.Action.BulkRedactEnd:
removeAction(PendingActionType.BulkRedact, payload.roomId);
break;
}
});
(0, _useEventEmitter.useTypedEventEmitter)(cli, _matrix.ClientEvent.Room, room => removeAction(PendingActionType.JoinRoom, room.roomId));
return actions;
};
const RoomListHeader = ({
onVisibilityChange
}) => {
const cli = (0, _react.useContext)(_MatrixClientContext.default);
const [mainMenuDisplayed, mainMenuHandle, openMainMenu, closeMainMenu] = (0, _ContextMenu.useContextMenu)();
const [plusMenuDisplayed, plusMenuHandle, openPlusMenu, closePlusMenu] = (0, _ContextMenu.useContextMenu)();
const [spaceKey, activeSpace] = (0, _useEventEmitter.useEventEmitterState)(_SpaceStore.default.instance, _spaces.UPDATE_SELECTED_SPACE, () => [_SpaceStore.default.instance.activeSpace, _SpaceStore.default.instance.activeSpaceRoom]);
const allRoomsInHome = (0, _useEventEmitter.useEventEmitterState)(_SpaceStore.default.instance, _spaces.UPDATE_HOME_BEHAVIOUR, () => {
return _SpaceStore.default.instance.allRoomsInHome;
});
const videoRoomsEnabled = (0, _useSettings.useFeatureEnabled)("feature_video_rooms");
const elementCallVideoRoomsEnabled = (0, _useSettings.useFeatureEnabled)("feature_element_call_video_rooms");
const pendingActions = usePendingActions();
const canShowMainMenu = activeSpace || spaceKey === _spaces.MetaSpace.Home;
(0, _react.useEffect)(() => {
if (mainMenuDisplayed && !canShowMainMenu) {
// Space changed under us and we no longer has a main menu to draw
closeMainMenu();
}
}, [closeMainMenu, canShowMainMenu, mainMenuDisplayed]);
const spaceName = (0, _useEventEmitter.useTypedEventEmitterState)(activeSpace ?? undefined, _matrix.RoomEvent.Name, () => activeSpace?.name);
(0, _react.useEffect)(() => {
onVisibilityChange?.();
}, [onVisibilityChange]);
const canExploreRooms = (0, _UIComponents.shouldShowComponent)(_UIFeature.UIComponent.ExploreRooms);
const canCreateRooms = (0, _UIComponents.shouldShowComponent)(_UIFeature.UIComponent.CreateRooms);
const canCreateSpaces = (0, _UIComponents.shouldShowComponent)(_UIFeature.UIComponent.CreateSpaces);
const hasPermissionToAddSpaceChild = activeSpace?.currentState?.maySendStateEvent(_matrix.EventType.SpaceChild, cli.getUserId());
const canAddSubRooms = hasPermissionToAddSpaceChild && canCreateRooms;
const canAddSubSpaces = hasPermissionToAddSpaceChild && canCreateSpaces;
// If the user can't do anything on the plus menu, don't show it. This aims to target the
// plus menu shown on the Home tab primarily: the user has options to use the menu for
// communities and spaces, but is at risk of no options on the Home tab.
const canShowPlusMenu = canCreateRooms || canExploreRooms || canCreateSpaces || activeSpace;
let contextMenu;
if (mainMenuDisplayed && mainMenuHandle.current) {
let ContextMenuComponent;
if (activeSpace) {
ContextMenuComponent = _SpaceContextMenu.default;
} else {
ContextMenuComponent = _SpacePanel.HomeButtonContextMenu;
}
contextMenu = /*#__PURE__*/_react.default.createElement(ContextMenuComponent, (0, _extends2.default)({}, contextMenuBelow(mainMenuHandle.current.getBoundingClientRect()), {
space: activeSpace,
onFinished: closeMainMenu,
hideHeader: true
}));
} else if (plusMenuDisplayed && activeSpace) {
let inviteOption;
if ((0, _space.shouldShowSpaceInvite)(activeSpace)) {
inviteOption = /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
label: (0, _languageHandler._t)("action|invite"),
iconClassName: "mx_RoomListHeader_iconInvite",
onClick: e => {
e.preventDefault();
e.stopPropagation();
(0, _space.showSpaceInvite)(activeSpace);
closePlusMenu();
}
});
}
let newRoomOptions;
if (activeSpace?.currentState.maySendStateEvent(_matrix.EventType.RoomAvatar, cli.getUserId())) {
newRoomOptions = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
iconClassName: "mx_RoomListHeader_iconNewRoom",
label: (0, _languageHandler._t)("action|new_room"),
onClick: e => {
e.preventDefault();
e.stopPropagation();
(0, _space.showCreateNewRoom)(activeSpace);
_PosthogTrackers.default.trackInteraction("WebRoomListHeaderPlusMenuCreateRoomItem", e);
closePlusMenu();
}
}), videoRoomsEnabled && /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
iconClassName: "mx_RoomListHeader_iconNewVideoRoom",
label: (0, _languageHandler._t)("action|new_video_room"),
onClick: e => {
e.preventDefault();
e.stopPropagation();
(0, _space.showCreateNewRoom)(activeSpace, elementCallVideoRoomsEnabled ? _matrix.RoomType.UnstableCall : _matrix.RoomType.ElementVideo);
closePlusMenu();
}
}, /*#__PURE__*/_react.default.createElement(_BetaCard.BetaPill, null)));
}
contextMenu = /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.default, (0, _extends2.default)({}, contextMenuBelow(plusMenuHandle.current.getBoundingClientRect()), {
onFinished: closePlusMenu,
compact: true
}), /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOptionList, {
first: true
}, inviteOption, newRoomOptions, /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
label: (0, _languageHandler._t)("action|explore_rooms"),
iconClassName: "mx_RoomListHeader_iconExplore",
onClick: e => {
e.preventDefault();
e.stopPropagation();
_dispatcher.default.dispatch({
action: _actions.Action.ViewRoom,
room_id: activeSpace.roomId,
metricsTrigger: undefined // other
});
closePlusMenu();
_PosthogTrackers.default.trackInteraction("WebRoomListHeaderPlusMenuExploreRoomsItem", e);
}
}), /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
label: (0, _languageHandler._t)("action|add_existing_room"),
iconClassName: "mx_RoomListHeader_iconPlus",
onClick: e => {
e.preventDefault();
e.stopPropagation();
(0, _space.showAddExistingRooms)(activeSpace);
closePlusMenu();
},
disabled: !canAddSubRooms,
title: !canAddSubRooms ? (0, _languageHandler._t)("spaces|error_no_permission_add_room") : undefined
}), canCreateSpaces && /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
label: (0, _languageHandler._t)("room_list|add_space_label"),
iconClassName: "mx_RoomListHeader_iconPlus",
onClick: e => {
e.preventDefault();
e.stopPropagation();
(0, _space.showCreateNewSubspace)(activeSpace);
closePlusMenu();
},
disabled: !canAddSubSpaces,
title: !canAddSubSpaces ? (0, _languageHandler._t)("spaces|error_no_permission_add_space") : undefined
}, /*#__PURE__*/_react.default.createElement(_BetaCard.BetaPill, null))));
} else if (plusMenuDisplayed) {
let newRoomOpts;
let joinRoomOpt;
if (canCreateRooms) {
newRoomOpts = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
label: (0, _languageHandler._t)("action|start_new_chat"),
iconClassName: "mx_RoomListHeader_iconStartChat",
onClick: e => {
e.preventDefault();
e.stopPropagation();
_dispatcher.default.dispatch({
action: "view_create_chat"
});
_PosthogTrackers.default.trackInteraction("WebRoomListHeaderPlusMenuCreateChatItem", e);
closePlusMenu();
}
}), /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
label: (0, _languageHandler._t)("action|new_room"),
iconClassName: "mx_RoomListHeader_iconNewRoom",
onClick: e => {
e.preventDefault();
e.stopPropagation();
_dispatcher.default.dispatch({
action: "view_create_room"
});
_PosthogTrackers.default.trackInteraction("WebRoomListHeaderPlusMenuCreateRoomItem", e);
closePlusMenu();
}
}), videoRoomsEnabled && /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
label: (0, _languageHandler._t)("action|new_video_room"),
iconClassName: "mx_RoomListHeader_iconNewVideoRoom",
onClick: e => {
e.preventDefault();
e.stopPropagation();
_dispatcher.default.dispatch({
action: "view_create_room",
type: elementCallVideoRoomsEnabled ? _matrix.RoomType.UnstableCall : _matrix.RoomType.ElementVideo
});
closePlusMenu();
}
}, /*#__PURE__*/_react.default.createElement(_BetaCard.BetaPill, null)));
}
if (canExploreRooms) {
joinRoomOpt = /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOption, {
label: (0, _languageHandler._t)("room_list|join_public_room_label"),
iconClassName: "mx_RoomListHeader_iconExplore",
onClick: e => {
e.preventDefault();
e.stopPropagation();
_dispatcher.default.dispatch({
action: _actions.Action.ViewRoomDirectory
});
_PosthogTrackers.default.trackInteraction("WebRoomListHeaderPlusMenuExploreRoomsItem", e);
closePlusMenu();
}
});
}
contextMenu = /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.default, (0, _extends2.default)({}, contextMenuBelow(plusMenuHandle.current.getBoundingClientRect()), {
onFinished: closePlusMenu,
compact: true
}), /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOptionList, {
first: true
}, newRoomOpts, joinRoomOpt));
}
let title;
if (activeSpace && spaceName) {
title = spaceName;
} else {
title = (0, _spaces.getMetaSpaceName)(spaceKey, allRoomsInHome);
}
const pendingActionSummary = [...pendingActions.entries()].filter(([type, keys]) => keys.size > 0).map(([type, keys]) => {
switch (type) {
case PendingActionType.JoinRoom:
return (0, _languageHandler._t)("room_list|joining_rooms_status", {
count: keys.size
});
case PendingActionType.BulkRedact:
return (0, _languageHandler._t)("room_list|redacting_messages_status", {
count: keys.size
});
}
}).join("\n");
let contextMenuButton = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_RoomListHeader_contextLessTitle"
}, title);
if (canShowMainMenu) {
const commonProps = {
ref: mainMenuHandle,
onClick: openMainMenu,
isExpanded: mainMenuDisplayed,
className: "mx_RoomListHeader_contextMenuButton",
children: title
};
if (!!activeSpace) {
contextMenuButton = /*#__PURE__*/_react.default.createElement(_ContextMenu.ContextMenuButton, (0, _extends2.default)({}, commonProps, {
label: (0, _languageHandler._t)("room_list|space_menu_label", {
spaceName: spaceName ?? activeSpace.name
})
}));
} else {
contextMenuButton = /*#__PURE__*/_react.default.createElement(_ContextMenu.ContextMenuTooltipButton, (0, _extends2.default)({}, commonProps, {
title: (0, _languageHandler._t)("room_list|home_menu_label")
}));
}
}
return /*#__PURE__*/_react.default.createElement("aside", {
className: "mx_RoomListHeader",
"aria-label": (0, _languageHandler._t)("room|context_menu|title")
}, contextMenuButton, pendingActionSummary ? /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: pendingActionSummary,
isTriggerInteractive: false
}, /*#__PURE__*/_react.default.createElement(_InlineSpinner.default, null)) : null, canShowPlusMenu && /*#__PURE__*/_react.default.createElement(_ContextMenu.ContextMenuTooltipButton, {
ref: plusMenuHandle,
onClick: openPlusMenu,
isExpanded: plusMenuDisplayed,
className: "mx_RoomListHeader_plusButton",
title: (0, _languageHandler._t)("action|add")
}), contextMenu);
};
var _default = exports.default = RoomListHeader;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbWF0cml4IiwicmVxdWlyZSIsIl9yZWFjdCIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwiX2NvbXBvdW5kV2ViIiwiX01hdHJpeENsaWVudENvbnRleHQiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX1VJQ29tcG9uZW50cyIsIl9hY3Rpb25zIiwiX2Rpc3BhdGNoZXIiLCJfdXNlRGlzcGF0Y2hlciIsIl91c2VFdmVudEVtaXR0ZXIiLCJfdXNlU2V0dGluZ3MiLCJfbGFuZ3VhZ2VIYW5kbGVyIiwiX1Bvc3Rob2dUcmFja2VycyIsIl9VSUZlYXR1cmUiLCJfc3BhY2VzIiwiX1NwYWNlU3RvcmUiLCJfc3BhY2UiLCJfQ29udGV4dE1lbnUiLCJfQmV0YUNhcmQiLCJfSWNvbml6ZWRDb250ZXh0TWVudSIsIl9TcGFjZUNvbnRleHRNZW51IiwiX0lubGluZVNwaW5uZXIiLCJfU3BhY2VQYW5lbCIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsImNvbnRleHRNZW51QmVsb3ciLCJlbGVtZW50UmVjdCIsImxlZnQiLCJ3aW5kb3ciLCJzY3JvbGxYIiwidG9wIiwiYm90dG9tIiwic2Nyb2xsWSIsImNoZXZyb25GYWNlIiwiQ2hldnJvbkZhY2UiLCJOb25lIiwiUGVuZGluZ0FjdGlvblR5cGUiLCJ1c2VQZW5kaW5nQWN0aW9ucyIsImNsaSIsInVzZUNvbnRleHQiLCJNYXRyaXhDbGllbnRDb250ZXh0IiwiYWN0aW9ucyIsInNldEFjdGlvbnMiLCJ1c2VTdGF0ZSIsIk1hcCIsImFkZEFjdGlvbiIsInR5cGUiLCJrZXkiLCJrZXlzIiwiU2V0IiwiYWRkIiwicmVtb3ZlQWN0aW9uIiwiZGVsZXRlIiwidXNlRGlzcGF0Y2hlciIsImRlZmF1bHREaXNwYXRjaGVyIiwicGF5bG9hZCIsImFjdGlvbiIsIkFjdGlvbiIsIkpvaW5Sb29tIiwicm9vbUlkIiwiSm9pblJvb21SZWFkeSIsIkpvaW5Sb29tRXJyb3IiLCJCdWxrUmVkYWN0U3RhcnQiLCJCdWxrUmVkYWN0IiwiQnVsa1JlZGFjdEVuZCIsInVzZVR5cGVkRXZlbnRFbWl0dGVyIiwiQ2xpZW50RXZlbnQiLCJSb29tIiwicm9vbSIsIlJvb21MaXN0SGVhZGVyIiwib25WaXNpYmlsaXR5Q2hhbmdlIiwibWFpbk1lbnVEaXNwbGF5ZWQiLCJtYWluTWVudUhhbmRsZSIsIm9wZW5NYWluTWVudSIsImNsb3NlTWFpbk1lbnUiLCJ1c2VDb250ZXh0TWVudSIsInBsdXNNZW51RGlzcGxheWVkIiwicGx1c01lbnVIYW5kbGUiLCJvcGVuUGx1c01lbnUiLCJjbG9zZVBsdXNNZW51Iiwic3BhY2VLZXkiLCJhY3RpdmVTcGFjZSIsInVzZUV2ZW50RW1pdHRlclN0YXRlIiwiU3BhY2VTdG9yZSIsImluc3RhbmNlIiwiVVBEQVRFX1NFTEVDVEVEX1NQQUNFIiwiYWN0aXZlU3BhY2VSb29tIiwiYWxsUm9vbXNJbkhvbWUiLCJVUERBVEVfSE9NRV9CRUhBVklPVVIiLCJ2aWRlb1Jvb21zRW5hYmxlZCIsInVzZUZlYXR1cmVFbmFibGVkIiwiZWxlbWVudENhbGxWaWRlb1Jvb21zRW5hYmxlZCIsInBlbmRpbmdBY3Rpb25zIiwiY2FuU2hvd01haW5NZW51IiwiTWV0YVNwYWNlIiwiSG9tZSIsInVzZUVmZmVjdCIsInNwYWNlTmFtZSIsInVzZVR5cGVkRXZlbnRFbWl0dGVyU3RhdGUiLCJ1bmRlZmluZWQiLCJSb29tRXZlbnQiLCJOYW1lIiwibmFtZSIsImNhbkV4cGxvcmVSb29tcyIsInNob3VsZFNob3dDb21wb25lbnQiLCJVSUNvbXBvbmVudCIsIkV4cGxvcmVSb29tcyIsImNhbkNyZWF0ZVJvb21zIiwiQ3JlYXRlUm9vbXMiLCJjYW5DcmVhdGVTcGFjZXMiLCJDcmVhdGVTcGFjZXMiLCJoYXNQZXJtaXNzaW9uVG9BZGRTcGFjZUNoaWxkIiwiY3VycmVudFN0YXRlIiwibWF5U2VuZFN0YXRlRXZlbnQiLCJFdmVudFR5cGUiLCJTcGFjZUNoaWxkIiwiZ2V0VXNlcklkIiwiY2FuQWRkU3ViUm9vbXMiLCJjYW5BZGRTdWJTcGFjZXMiLCJjYW5TaG93UGx1c01lbnUiLCJjb250ZXh0TWVudSIsImN1cnJlbnQiLCJDb250ZXh0TWVudUNvbXBvbmVudCIsIlNwYWNlQ29udGV4dE1lbnUiLCJIb21lQnV0dG9uQ29udGV4dE1lbnUiLCJjcmVhdGVFbGVtZW50IiwiX2V4dGVuZHMyIiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0Iiwic3BhY2UiLCJvbkZpbmlzaGVkIiwiaGlkZUhlYWRlciIsImludml0ZU9wdGlvbiIsInNob3VsZFNob3dTcGFjZUludml0ZSIsIkljb25pemVkQ29udGV4dE1lbnVPcHRpb24iLCJsYWJlbCIsIl90IiwiaWNvbkNsYXNzTmFtZSIsIm9uQ2xpY2siLCJwcmV2ZW50RGVmYXVsdCIsInN0b3BQcm9wYWdhdGlvbiIsInNob3dTcGFjZUludml0ZSIsIm5ld1Jvb21PcHRpb25zIiwiUm9vbUF2YXRhciIsIkZyYWdtZW50Iiwic2hvd0NyZWF0ZU5ld1Jvb20iLCJQb3N0aG9nVHJhY2tlcnMiLCJ0cmFja0ludGVyYWN0aW9uIiwiUm9vbVR5cGUiLCJVbnN0YWJsZUNhbGwiLCJFbGVtZW50VmlkZW8iLCJCZXRhUGlsbCIsImNvbXBhY3QiLCJJY29uaXplZENvbnRleHRNZW51T3B0aW9uTGlzdCIsImZpcnN0IiwiZGlzcGF0Y2giLCJWaWV3Um9vbSIsInJvb21faWQiLCJtZXRyaWNzVHJpZ2dlciIsInNob3dBZGRFeGlzdGluZ1Jvb21zIiwiZGlzYWJsZWQiLCJ0aXRsZSIsInNob3dDcmVhdGVOZXdTdWJzcGFjZSIsIm5ld1Jvb21PcHRzIiwiam9pblJvb21PcHQiLCJWaWV3Um9vbURpcmVjdG9yeSIsImdldE1ldGFTcGFjZU5hbWUiLCJwZW5kaW5nQWN0aW9uU3VtbWFyeSIsImVudHJpZXMiLCJmaWx0ZXIiLCJzaXplIiwibWFwIiwiY291bnQiLCJqb2luIiwiY29udGV4dE1lbnVCdXR0b24iLCJjbGFzc05hbWUiLCJjb21tb25Qcm9wcyIsInJlZiIsImlzRXhwYW5kZWQiLCJjaGlsZHJlbiIsIkNvbnRleHRNZW51QnV0dG9uIiwiQ29udGV4dE1lbnVUb29sdGlwQnV0dG9uIiwiVG9vbHRpcCIsImlzVHJpZ2dlckludGVyYWN0aXZlIiwiX2RlZmF1bHQiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdmlld3Mvcm9vbXMvUm9vbUxpc3RIZWFkZXIudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDIxLCAyMDIyIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCB7IEV2ZW50VHlwZSwgUm9vbVR5cGUsIFJvb20sIFJvb21FdmVudCwgQ2xpZW50RXZlbnQgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgUmVhY3QsIHsgdXNlQ29udGV4dCwgdXNlRWZmZWN0LCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgVG9vbHRpcCB9IGZyb20gXCJAdmVjdG9yLWltL2NvbXBvdW5kLXdlYlwiO1xuXG5pbXBvcnQgTWF0cml4Q2xpZW50Q29udGV4dCBmcm9tIFwiLi4vLi4vLi4vY29udGV4dHMvTWF0cml4Q2xpZW50Q29udGV4dFwiO1xuaW1wb3J0IHsgc2hvdWxkU2hvd0NvbXBvbmVudCB9IGZyb20gXCIuLi8uLi8uLi9jdXN0b21pc2F0aW9ucy9oZWxwZXJzL1VJQ29tcG9uZW50c1wiO1xuaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSBcIi4uLy4uLy4uL2Rpc3BhdGNoZXIvYWN0aW9uc1wiO1xuaW1wb3J0IGRlZmF1bHREaXNwYXRjaGVyIGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL2Rpc3BhdGNoZXJcIjtcbmltcG9ydCB7IFZpZXdSb29tUGF5bG9hZCB9IGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL3BheWxvYWRzL1ZpZXdSb29tUGF5bG9hZFwiO1xuaW1wb3J0IHsgdXNlRGlzcGF0Y2hlciB9IGZyb20gXCIuLi8uLi8uLi9ob29rcy91c2VEaXNwYXRjaGVyXCI7XG5pbXBvcnQgeyB1c2VFdmVudEVtaXR0ZXJTdGF0ZSwgdXNlVHlwZWRFdmVudEVtaXR0ZXIsIHVzZVR5cGVkRXZlbnRFbWl0dGVyU3RhdGUgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlRXZlbnRFbWl0dGVyXCI7XG5pbXBvcnQgeyB1c2VGZWF0dXJlRW5hYmxlZCB9IGZyb20gXCIuLi8uLi8uLi9ob29rcy91c2VTZXR0aW5nc1wiO1xuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgUG9zdGhvZ1RyYWNrZXJzIGZyb20gXCIuLi8uLi8uLi9Qb3N0aG9nVHJhY2tlcnNcIjtcbmltcG9ydCB7IFVJQ29tcG9uZW50IH0gZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL1VJRmVhdHVyZVwiO1xuaW1wb3J0IHtcbiAgICBnZXRNZXRhU3BhY2VOYW1lLFxuICAgIE1ldGFTcGFjZSxcbiAgICBTcGFjZUtleSxcbiAgICBVUERBVEVfSE9NRV9CRUhBVklPVVIsXG4gICAgVVBEQVRFX1NFTEVDVEVEX1NQQUNFLFxufSBmcm9tIFwiLi4vLi4vLi4vc3RvcmVzL3NwYWNlc1wiO1xuaW1wb3J0IFNwYWNlU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3N0b3Jlcy9zcGFjZXMvU3BhY2VTdG9yZVwiO1xuaW1wb3J0IHtcbiAgICBzaG91bGRTaG93U3BhY2VJbnZpdGUsXG4gICAgc2hvd0FkZEV4aXN0aW5nUm9vbXMsXG4gICAgc2hvd0NyZWF0ZU5ld1Jvb20sXG4gICAgc2hvd0NyZWF0ZU5ld1N1YnNwYWNlLFxuICAgIHNob3dTcGFjZUludml0ZSxcbn0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL3NwYWNlXCI7XG5pbXBvcnQge1xuICAgIENoZXZyb25GYWNlLFxuICAgIENvbnRleHRNZW51VG9vbHRpcEJ1dHRvbixcbiAgICB1c2VDb250ZXh0TWVudSxcbiAgICBNZW51UHJvcHMsXG4gICAgQ29udGV4dE1lbnVCdXR0b24sXG59IGZyb20gXCIuLi8uLi9zdHJ1Y3R1cmVzL0NvbnRleHRNZW51XCI7XG5pbXBvcnQgeyBCZXRhUGlsbCB9IGZyb20gXCIuLi9iZXRhL0JldGFDYXJkXCI7XG5pbXBvcnQgSWNvbml6ZWRDb250ZXh0TWVudSwge1xuICAgIEljb25pemVkQ29udGV4dE1lbnVPcHRpb24sXG4gICAgSWNvbml6ZWRDb250ZXh0TWVudU9wdGlvbkxpc3QsXG59IGZyb20gXCIuLi9jb250ZXh0X21lbnVzL0ljb25pemVkQ29udGV4dE1lbnVcIjtcbmltcG9ydCBTcGFjZUNvbnRleHRNZW51IGZyb20gXCIuLi9jb250ZXh0X21lbnVzL1NwYWNlQ29udGV4dE1lbnVcIjtcbmltcG9ydCBJbmxpbmVTcGlubmVyIGZyb20gXCIuLi9lbGVtZW50cy9JbmxpbmVTcGlubmVyXCI7XG5pbXBvcnQgeyBIb21lQnV0dG9uQ29udGV4dE1lbnUgfSBmcm9tIFwiLi4vc3BhY2VzL1NwYWNlUGFuZWxcIjtcblxuY29uc3QgY29udGV4dE1lbnVCZWxvdyA9IChlbGVtZW50UmVjdDogRE9NUmVjdCk6IE1lbnVQcm9wcyA9PiB7XG4gICAgLy8gYWxpZ24gdGhlIGNvbnRleHQgbWVudSdzIGljb25zIHdpdGggdGhlIGljb24gd2hpY2ggb3BlbmVkIHRoZSBjb250ZXh0IG1lbnVcbiAgICBjb25zdCBsZWZ0ID0gZWxlbWVudFJlY3QubGVmdCArIHdpbmRvdy5zY3JvbGxYO1xuICAgIGNvbnN0IHRvcCA9IGVsZW1lbnRSZWN0LmJvdHRvbSArIHdpbmRvdy5zY3JvbGxZICsgMTI7XG4gICAgY29uc3QgY2hldnJvbkZhY2UgPSBDaGV2cm9uRmFjZS5Ob25lO1xuICAgIHJldHVybiB7IGxlZnQsIHRvcCwgY2hldnJvbkZhY2UgfTtcbn07XG5cbi8vIExvbmctcnVubmluZyBhY3Rpb25zIHRoYXQgc2hvdWxkIHRyaWdnZXIgYSBzcGlubmVyXG5lbnVtIFBlbmRpbmdBY3Rpb25UeXBlIHtcbiAgICBKb2luUm9vbSxcbiAgICBCdWxrUmVkYWN0LFxufVxuXG5jb25zdCB1c2VQZW5kaW5nQWN0aW9ucyA9ICgpOiBNYXA8UGVuZGluZ0FjdGlvblR5cGUsIFNldDxzdHJpbmc+PiA9PiB7XG4gICAgY29uc3QgY2xpID0gdXNlQ29udGV4dChNYXRyaXhDbGllbnRDb250ZXh0KTtcbiAgICBjb25zdCBbYWN0aW9ucywgc2V0QWN0aW9uc10gPSB1c2VTdGF0ZShuZXcgTWFwPFBlbmRpbmdBY3Rpb25UeXBlLCBTZXQ8c3RyaW5nPj4oKSk7XG5cbiAgICBjb25zdCBhZGRBY3Rpb24gPSAodHlwZTogUGVuZGluZ0FjdGlvblR5cGUsIGtleTogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgICAgIGNvbnN0IGtleXMgPSBuZXcgU2V0KGFjdGlvbnMuZ2V0KHR5cGUpKTtcbiAgICAgICAga2V5cy5hZGQoa2V5KTtcbiAgICAgICAgc2V0QWN0aW9ucyhuZXcgTWFwKGFjdGlvbnMpLnNldCh0eXBlLCBrZXlzKSk7XG4gICAgfTtcbiAgICBjb25zdCByZW1vdmVBY3Rpb24gPSAodHlwZTogUGVuZGluZ0FjdGlvblR5cGUsIGtleTogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgICAgIGNvbnN0IGtleXMgPSBuZXcgU2V0KGFjdGlvbnMuZ2V0KHR5cGUpKTtcbiAgICAgICAgaWYgKGtleXMuZGVsZXRlKGtleSkpIHtcbiAgICAgICAgICAgIHNldEFjdGlvbnMobmV3IE1hcChhY3Rpb25zKS5zZXQodHlwZSwga2V5cykpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHVzZURpc3BhdGNoZXIoZGVmYXVsdERpc3BhdGNoZXIsIChwYXlsb2FkKSA9PiB7XG4gICAgICAgIHN3aXRjaCAocGF5bG9hZC5hY3Rpb24pIHtcbiAgICAgICAgICAgIGNhc2UgQWN0aW9uLkpvaW5Sb29tOlxuICAgICAgICAgICAgICAgIGFkZEFjdGlvbihQZW5kaW5nQWN0aW9uVHlwZS5Kb2luUm9vbSwgcGF5bG9hZC5yb29tSWQpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBBY3Rpb24uSm9pblJvb21SZWFkeTpcbiAgICAgICAgICAgIGNhc2UgQWN0aW9uLkpvaW5Sb29tRXJyb3I6XG4gICAgICAgICAgICAgICAgcmVtb3ZlQWN0aW9uKFBlbmRpbmdBY3Rpb25UeXBlLkpvaW5Sb29tLCBwYXlsb2FkLnJvb21JZCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEFjdGlvbi5CdWxrUmVkYWN0U3RhcnQ6XG4gICAgICAgICAgICAgICAgYWRkQWN0aW9uKFBlbmRpbmdBY3Rpb25UeXBlLkJ1bGtSZWRhY3QsIHBheWxvYWQucm9vbUlkKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgQWN0aW9uLkJ1bGtSZWRhY3RFbmQ6XG4gICAgICAgICAgICAgICAgcmVtb3ZlQWN0aW9uKFBlbmRpbmdBY3Rpb25UeXBlLkJ1bGtSZWRhY3QsIHBheWxvYWQucm9vbUlkKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHVzZVR5cGVkRXZlbnRFbWl0dGVyKGNsaSwgQ2xpZW50RXZlbnQuUm9vbSwgKHJvb206IFJvb20pID0+IHJlbW92ZUFjdGlvbihQZW5kaW5nQWN0aW9uVHlwZS5Kb2luUm9vbSwgcm9vbS5yb29tSWQpKTtcblxuICAgIHJldHVybiBhY3Rpb25zO1xufTtcblxuaW50ZXJmYWNlIElQcm9wcyB7XG4gICAgb25WaXNpYmlsaXR5Q2hhbmdlPygpOiB2b2lkO1xufVxuXG5jb25zdCBSb29tTGlzdEhlYWRlcjogUmVhY3QuRkM8SVByb3BzPiA9ICh7IG9uVmlzaWJpbGl0eUNoYW5nZSB9KSA9PiB7XG4gICAgY29uc3QgY2xpID0gdXNlQ29udGV4dChNYXRyaXhDbGllbnRDb250ZXh0KTtcbiAgICBjb25zdCBbbWFpbk1lbnVEaXNwbGF5ZWQsIG1haW5NZW51SGFuZGxlLCBvcGVuTWFpbk1lbnUsIGNsb3NlTWFpbk1lbnVdID0gdXNlQ29udGV4dE1lbnU8SFRNTERpdkVsZW1lbnQ+KCk7XG4gICAgY29uc3QgW3BsdXNNZW51RGlzcGxheWVkLCBwbHVzTWVudUhhbmRsZSwgb3BlblBsdXNNZW51LCBjbG9zZVBsdXNNZW51XSA9IHVzZUNvbnRleHRNZW51PEhUTUxEaXZFbGVtZW50PigpO1xuICAgIGNvbnN0IFtzcGFjZUtleSwgYWN0aXZlU3BhY2VdID0gdXNlRXZlbnRFbWl0dGVyU3RhdGU8W1NwYWNlS2V5LCBSb29tIHwgbnVsbF0+KFxuICAgICAgICBTcGFjZVN0b3JlLmluc3RhbmNlLFxuICAgICAgICBVUERBVEVfU0VMRUNURURfU1BBQ0UsXG4gICAgICAgICgpID0+IFtTcGFjZVN0b3JlLmluc3RhbmNlLmFjdGl2ZVNwYWNlLCBTcGFjZVN0b3JlLmluc3RhbmNlLmFjdGl2ZVNwYWNlUm9vbV0sXG4gICAgKTtcbiAgICBjb25zdCBhbGxSb29tc0luSG9tZSA9IHVzZUV2ZW50RW1pdHRlclN0YXRlKFNwYWNlU3RvcmUuaW5zdGFuY2UsIFVQREFURV9IT01FX0JFSEFWSU9VUiwgKCkgPT4ge1xuICAgICAgICByZXR1cm4gU3BhY2VTdG9yZS5pbnN0YW5jZS5hbGxSb29tc0luSG9tZTtcbiAgICB9KTtcbiAgICBjb25zdCB2aWRlb1Jvb21zRW5hYmxlZCA9IHVzZUZlYXR1cmVFbmFibGVkKFwiZmVhdHVyZV92aWRlb19yb29tc1wiKTtcbiAgICBjb25zdCBlbGVtZW50Q2FsbFZpZGVvUm9vbXNFbmFibGVkID0gdXNlRmVhdHVyZUVuYWJsZWQoXCJmZWF0dXJlX2VsZW1lbnRfY2FsbF92aWRlb19yb29tc1wiKTtcbiAgICBjb25zdCBwZW5kaW5nQWN0aW9ucyA9IHVzZVBlbmRpbmdBY3Rpb25zKCk7XG5cbiAgICBjb25zdCBjYW5TaG93TWFpbk1lbnUgPSBhY3RpdmVTcGFjZSB8fCBzcGFjZUtleSA9PT0gTWV0YVNwYWNlLkhvbWU7XG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBpZiAobWFpbk1lbnVEaXNwbGF5ZWQgJiYgIWNhblNob3dNYWluTWVudSkge1xuICAgICAgICAgICAgLy8gU3BhY2UgY2hhbmdlZCB1bmRlciB1cyBhbmQgd2Ugbm8gbG9uZ2VyIGhhcyBhIG1haW4gbWVudSB0byBkcmF3XG4gICAgICAgICAgICBjbG9zZU1haW5NZW51KCk7XG4gICAgICAgIH1cbiAgICB9LCBbY2xvc2VNYWluTWVudSwgY2FuU2hvd01haW5NZW51LCBtYWluTWVudURpc3BsYXllZF0pO1xuXG4gICAgY29uc3Qgc3BhY2VOYW1lID0gdXNlVHlwZWRFdmVudEVtaXR0ZXJTdGF0ZShhY3RpdmVTcGFjZSA/PyB1bmRlZmluZWQsIFJvb21FdmVudC5OYW1lLCAoKSA9PiBhY3RpdmVTcGFjZT8ubmFtZSk7XG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBvblZpc2liaWxpdHlDaGFuZ2U/LigpO1xuICAgIH0sIFtvblZpc2liaWxpdHlDaGFuZ2VdKTtcblxuICAgIGNvbnN0IGNhbkV4cGxvcmVSb29tcyA9IHNob3VsZFNob3dDb21wb25lbnQoVUlDb21wb25lbnQuRXhwbG9yZVJvb21zKTtcbiAgICBjb25zdCBjYW5DcmVhdGVSb29tcyA9IHNob3VsZFNob3dDb21wb25lbnQoVUlDb21wb25lbnQuQ3JlYXRlUm9vbXMpO1xuICAgIGNvbnN0IGNhbkNyZWF0ZVNwYWNlcyA9IHNob3VsZFNob3dDb21wb25lbnQoVUlDb21wb25lbnQuQ3JlYXRlU3BhY2VzKTtcblxuICAgIGNvbnN0IGhhc1Blcm1pc3Npb25Ub0FkZFNwYWNlQ2hpbGQgPSBhY3RpdmVTcGFjZT8uY3VycmVudFN0YXRlPy5tYXlTZW5kU3RhdGVFdmVudChcbiAgICAgICAgRXZlbnRUeXBlLlNwYWNlQ2hpbGQsXG4gICAgICAgIGNsaS5nZXRVc2VySWQoKSEsXG4gICAgKTtcbiAgICBjb25zdCBjYW5BZGRTdWJSb29tcyA9IGhhc1Blcm1pc3Npb25Ub0FkZFNwYWNlQ2hpbGQgJiYgY2FuQ3JlYXRlUm9vbXM7XG4gICAgY29uc3QgY2FuQWRkU3ViU3BhY2VzID0gaGFzUGVybWlzc2lvblRvQWRkU3BhY2VDaGlsZCAmJiBjYW5DcmVhdGVTcGFjZXM7XG5cbiAgICAvLyBJZiB0aGUgdXNlciBjYW4ndCBkbyBhbnl0aGluZyBvbiB0aGUgcGx1cyBtZW51LCBkb24ndCBzaG93IGl0LiBUaGlzIGFpbXMgdG8gdGFyZ2V0IHRoZVxuICAgIC8vIHBsdXMgbWVudSBzaG93biBvbiB0aGUgSG9tZSB0YWIgcHJpbWFyaWx5OiB0aGUgdXNlciBoYXMgb3B0aW9ucyB0byB1c2UgdGhlIG1lbnUgZm9yXG4gICAgLy8gY29tbXVuaXRpZXMgYW5kIHNwYWNlcywgYnV0IGlzIGF0IHJpc2sgb2Ygbm8gb3B0aW9ucyBvbiB0aGUgSG9tZSB0YWIuXG4gICAgY29uc3QgY2FuU2hvd1BsdXNNZW51ID0gY2FuQ3JlYXRlUm9vbXMgfHwgY2FuRXhwbG9yZVJvb21zIHx8IGNhbkNyZWF0ZVNwYWNlcyB8fCBhY3RpdmVTcGFjZTtcblxuICAgIGxldCBjb250ZXh0TWVudTogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgaWYgKG1haW5NZW51RGlzcGxheWVkICYmIG1haW5NZW51SGFuZGxlLmN1cnJlbnQpIHtcbiAgICAgICAgbGV0IENvbnRleHRNZW51Q29tcG9uZW50O1xuICAgICAgICBpZiAoYWN0aXZlU3BhY2UpIHtcbiAgICAgICAgICAgIENvbnRleHRNZW51Q29tcG9uZW50ID0gU3BhY2VDb250ZXh0TWVudTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIENvbnRleHRNZW51Q29tcG9uZW50ID0gSG9tZUJ1dHRvbkNvbnRleHRNZW51O1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dE1lbnUgPSAoXG4gICAgICAgICAgICA8Q29udGV4dE1lbnVDb21wb25lbnRcbiAgICAgICAgICAgICAgICB7Li4uY29udGV4dE1lbnVCZWxvdyhtYWluTWVudUhhbmRsZS5jdXJyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKX1cbiAgICAgICAgICAgICAgICBzcGFjZT17YWN0aXZlU3BhY2UhfVxuICAgICAgICAgICAgICAgIG9uRmluaXNoZWQ9e2Nsb3NlTWFpbk1lbnV9XG4gICAgICAgICAgICAgICAgaGlkZUhlYWRlcj17dHJ1ZX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICk7XG4gICAgfSBlbHNlIGlmIChwbHVzTWVudURpc3BsYXllZCAmJiBhY3RpdmVTcGFjZSkge1xuICAgICAgICBsZXQgaW52aXRlT3B0aW9uOiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHNob3VsZFNob3dTcGFjZUludml0ZShhY3RpdmVTcGFjZSkpIHtcbiAgICAgICAgICAgIGludml0ZU9wdGlvbiA9IChcbiAgICAgICAgICAgICAgICA8SWNvbml6ZWRDb250ZXh0TWVudU9wdGlvblxuICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJhY3Rpb258aW52aXRlXCIpfVxuICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfUm9vbUxpc3RIZWFkZXJfaWNvbkludml0ZVwiXG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eyhlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2hvd1NwYWNlSW52aXRlKGFjdGl2ZVNwYWNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlUGx1c01lbnUoKTtcbiAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBuZXdSb29tT3B0aW9uczogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChhY3RpdmVTcGFjZT8uY3VycmVudFN0YXRlLm1heVNlbmRTdGF0ZUV2ZW50KEV2ZW50VHlwZS5Sb29tQXZhdGFyLCBjbGkuZ2V0VXNlcklkKCkhKSkge1xuICAgICAgICAgICAgbmV3Um9vbU9wdGlvbnMgPSAoXG4gICAgICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgICAgICAgPEljb25pemVkQ29udGV4dE1lbnVPcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU9XCJteF9Sb29tTGlzdEhlYWRlcl9pY29uTmV3Um9vbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJhY3Rpb258bmV3X3Jvb21cIil9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3dDcmVhdGVOZXdSb29tKGFjdGl2ZVNwYWNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3N0aG9nVHJhY2tlcnMudHJhY2tJbnRlcmFjdGlvbihcIldlYlJvb21MaXN0SGVhZGVyUGx1c01lbnVDcmVhdGVSb29tSXRlbVwiLCBlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zZVBsdXNNZW51KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICB7dmlkZW9Sb29tc0VuYWJsZWQgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgPEljb25pemVkQ29udGV4dE1lbnVPcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfUm9vbUxpc3RIZWFkZXJfaWNvbk5ld1ZpZGVvUm9vbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9e190KFwiYWN0aW9ufG5ld192aWRlb19yb29tXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eyhlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0NyZWF0ZU5ld1Jvb20oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVTcGFjZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRDYWxsVmlkZW9Sb29tc0VuYWJsZWQgPyBSb29tVHlwZS5VbnN0YWJsZUNhbGwgOiBSb29tVHlwZS5FbGVtZW50VmlkZW8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlUGx1c01lbnUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxCZXRhUGlsbCAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9JY29uaXplZENvbnRleHRNZW51T3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgIDwvPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHRNZW51ID0gKFxuICAgICAgICAgICAgPEljb25pemVkQ29udGV4dE1lbnVcbiAgICAgICAgICAgICAgICB7Li4uY29udGV4dE1lbnVCZWxvdyhwbHVzTWVudUhhbmRsZS5jdXJyZW50IS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSl9XG4gICAgICAgICAgICAgICAgb25GaW5pc2hlZD17Y2xvc2VQbHVzTWVudX1cbiAgICAgICAgICAgICAgICBjb21wYWN0XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPEljb25pemVkQ29udGV4dE1lbnVPcHRpb25MaXN0IGZpcnN0PlxuICAgICAgICAgICAgICAgICAgICB7aW52aXRlT3B0aW9ufVxuICAgICAgICAgICAgICAgICAgICB7bmV3Um9vbU9wdGlvbnN9XG4gICAgICAgICAgICAgICAgICAgIDxJY29uaXplZENvbnRleHRNZW51T3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJhY3Rpb258ZXhwbG9yZV9yb29tc1wiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU9XCJteF9Sb29tTGlzdEhlYWRlcl9pY29uRXhwbG9yZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHREaXNwYXRjaGVyLmRpc3BhdGNoPFZpZXdSb29tUGF5bG9hZD4oe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IEFjdGlvbi5WaWV3Um9vbSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9vbV9pZDogYWN0aXZlU3BhY2Uucm9vbUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzVHJpZ2dlcjogdW5kZWZpbmVkLCAvLyBvdGhlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlUGx1c01lbnUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3N0aG9nVHJhY2tlcnMudHJhY2tJbnRlcmFjdGlvbihcIldlYlJvb21MaXN0SGVhZGVyUGx1c01lbnVFeHBsb3JlUm9vbXNJdGVtXCIsIGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPEljb25pemVkQ29udGV4dE1lbnVPcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcImFjdGlvbnxhZGRfZXhpc3Rpbmdfcm9vbVwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU9XCJteF9Sb29tTGlzdEhlYWRlcl9pY29uUGx1c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3dBZGRFeGlzdGluZ1Jvb21zKGFjdGl2ZVNwYWNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zZVBsdXNNZW51KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9eyFjYW5BZGRTdWJSb29tc31cbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPXshY2FuQWRkU3ViUm9vbXMgPyBfdChcInNwYWNlc3xlcnJvcl9ub19wZXJtaXNzaW9uX2FkZF9yb29tXCIpIDogdW5kZWZpbmVkfVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICB7Y2FuQ3JlYXRlU3BhY2VzICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIDxJY29uaXplZENvbnRleHRNZW51T3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9e190KFwicm9vbV9saXN0fGFkZF9zcGFjZV9sYWJlbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfUm9vbUxpc3RIZWFkZXJfaWNvblBsdXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eyhlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0NyZWF0ZU5ld1N1YnNwYWNlKGFjdGl2ZVNwYWNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvc2VQbHVzTWVudSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9eyFjYW5BZGRTdWJTcGFjZXN9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9eyFjYW5BZGRTdWJTcGFjZXMgPyBfdChcInNwYWNlc3xlcnJvcl9ub19wZXJtaXNzaW9uX2FkZF9zcGFjZVwiKSA6IHVuZGVmaW5lZH1cbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8QmV0YVBpbGwgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvSWNvbml6ZWRDb250ZXh0TWVudU9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICA8L0ljb25pemVkQ29udGV4dE1lbnVPcHRpb25MaXN0PlxuICAgICAgICAgICAgPC9JY29uaXplZENvbnRleHRNZW51PlxuICAgICAgICApO1xuICAgIH0gZWxzZSBpZiAocGx1c01lbnVEaXNwbGF5ZWQpIHtcbiAgICAgICAgbGV0IG5ld1Jvb21PcHRzOiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGpvaW5Sb29tT3B0OiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAoY2FuQ3JlYXRlUm9vbXMpIHtcbiAgICAgICAgICAgIG5ld1Jvb21PcHRzID0gKFxuICAgICAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgICAgIDxJY29uaXplZENvbnRleHRNZW51T3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJhY3Rpb258c3RhcnRfbmV3X2NoYXRcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfUm9vbUxpc3RIZWFkZXJfaWNvblN0YXJ0Q2hhdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHREaXNwYXRjaGVyLmRpc3BhdGNoKHsgYWN0aW9uOiBcInZpZXdfY3JlYXRlX2NoYXRcIiB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3N0aG9nVHJhY2tlcnMudHJhY2tJbnRlcmFjdGlvbihcIldlYlJvb21MaXN0SGVhZGVyUGx1c01lbnVDcmVhdGVDaGF0SXRlbVwiLCBlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zZVBsdXNNZW51KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICA8SWNvbml6ZWRDb250ZXh0TWVudU9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9e190KFwiYWN0aW9ufG5ld19yb29tXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZT1cIm14X1Jvb21MaXN0SGVhZGVyX2ljb25OZXdSb29tXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eyhlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdERpc3BhdGNoZXIuZGlzcGF0Y2goeyBhY3Rpb246IFwidmlld19jcmVhdGVfcm9vbVwiIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvc3Rob2dUcmFja2Vycy50cmFja0ludGVyYWN0aW9uKFwiV2ViUm9vbUxpc3RIZWFkZXJQbHVzTWVudUNyZWF0ZVJvb21JdGVtXCIsIGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlUGx1c01lbnUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIHt2aWRlb1Jvb21zRW5hYmxlZCAmJiAoXG4gICAgICAgICAgICAgICAgICAgICAgICA8SWNvbml6ZWRDb250ZXh0TWVudU9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcImFjdGlvbnxuZXdfdmlkZW9fcm9vbVwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfUm9vbUxpc3RIZWFkZXJfaWNvbk5ld1ZpZGVvUm9vbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0RGlzcGF0Y2hlci5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IFwidmlld19jcmVhdGVfcm9vbVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogZWxlbWVudENhbGxWaWRlb1Jvb21zRW5hYmxlZCA/IFJvb21UeXBlLlVuc3RhYmxlQ2FsbCA6IFJvb21UeXBlLkVsZW1lbnRWaWRlbyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlUGx1c01lbnUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxCZXRhUGlsbCAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9JY29uaXplZENvbnRleHRNZW51T3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgIDwvPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FuRXhwbG9yZVJvb21zKSB7XG4gICAgICAgICAgICBqb2luUm9vbU9wdCA9IChcbiAgICAgICAgICAgICAgICA8SWNvbml6ZWRDb250ZXh0TWVudU9wdGlvblxuICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJyb29tX2xpc3R8am9pbl9wdWJsaWNfcm9vbV9sYWJlbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZT1cIm14X1Jvb21MaXN0SGVhZGVyX2ljb25FeHBsb3JlXCJcbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0RGlzcGF0Y2hlci5kaXNwYXRjaCh7IGFjdGlvbjogQWN0aW9uLlZpZXdSb29tRGlyZWN0b3J5IH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgUG9zdGhvZ1RyYWNrZXJzLnRyYWNrSW50ZXJhY3Rpb24oXCJXZWJSb29tTGlzdEhlYWRlclBsdXNNZW51RXhwbG9yZVJvb21zSXRlbVwiLCBlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlUGx1c01lbnUoKTtcbiAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHRNZW51ID0gKFxuICAgICAgICAgICAgPEljb25pemVkQ29udGV4dE1lbnVcbiAgICAgICAgICAgICAgICB7Li4uY29udGV4dE1lbnVCZWxvdyhwbHVzTWVudUhhbmRsZS5jdXJyZW50IS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSl9XG4gICAgICAgICAgICAgICAgb25GaW5pc2hlZD17Y2xvc2VQbHVzTWVudX1cbiAgICAgICAgICAgICAgICBjb21wYWN0XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPEljb25pemVkQ29udGV4dE1lbnVPcHRpb25MaXN0IGZpcnN0PlxuICAgICAgICAgICAgICAgICAgICB7bmV3Um9vbU9wdHN9XG4gICAgICAgICAgICAgICAgICAgIHtqb2luUm9vbU9wdH1cbiAgICAgICAgICAgICAgICA8L0ljb25pemVkQ29udGV4dE1lbnVPcHRpb25MaXN0PlxuICAgICAgICAgICAgPC9JY29uaXplZENvbnRleHRNZW51PlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGxldCB0aXRsZTogc3RyaW5nO1xuICAgIGlmIChhY3RpdmVTcGFjZSAmJiBzcGFjZU5hbWUpIHtcbiAgICAgICAgdGl0bGUgPSBzcGFjZU5hbWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGl0bGUgPSBnZXRNZXRhU3BhY2VOYW1lKHNwYWNlS2V5IGFzIE1ldGFTcGFjZSwgYWxsUm9vbXNJbkhvbWUpO1xuICAgIH1cblxuICAgIGNvbnN0IHBlbmRpbmdBY3Rpb25TdW1tYXJ5ID0gWy4uLnBlbmRpbmdBY3Rpb25zLmVudHJpZXMoKV1cbiAgICAgICAgLmZpbHRlcigoW3R5cGUsIGtleXNdKSA9PiBrZXlzLnNpemUgPiAwKVxuICAgICAgICAubWFwKChbdHlwZSwga2V5c10pID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgUGVuZGluZ0FjdGlvblR5cGUuSm9pblJvb206XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfdChcInJvb21fbGlzdHxqb2luaW5nX3Jvb21zX3N0YXR1c1wiLCB7IGNvdW50OiBrZXlzLnNpemUgfSk7XG4gICAgICAgICAgICAgICAgY2FzZSBQZW5kaW5nQWN0aW9uVHlwZS5CdWxrUmVkYWN0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3QoXCJyb29tX2xpc3R8cmVkYWN0aW5nX21lc3NhZ2VzX3N0YXR1c1wiLCB7IGNvdW50OiBrZXlzLnNpemUgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5qb2luKFwiXFxuXCIpO1xuXG4gICAgbGV0IGNvbnRleHRNZW51QnV0dG9uOiBKU1guRWxlbWVudCA9IDxkaXYgY2xhc3NOYW1lPVwibXhfUm9vbUxpc3RIZWFkZXJfY29udGV4dExlc3NUaXRsZVwiPnt0aXRsZX08L2Rpdj47XG4gICAgaWYgKGNhblNob3dNYWluTWVudSkge1xuICAgICAgICBjb25zdCBjb21tb25Qcm9wcyA9IHtcbiAgICAgICAgICAgIHJlZjogbWFpbk1lbnVIYW5kbGUsXG4gICAgICAgICAgICBvbkNsaWNrOiBvcGVuTWFpbk1lbnUsXG4gICAgICAgICAgICBpc0V4cGFuZGVkOiBtYWluTWVudURpc3BsYXllZCxcbiAgICAgICAgICAgIGNsYXNzTmFtZTogXCJteF9Sb29tTGlzdEhlYWRlcl9jb250ZXh0TWVudUJ1dHRvblwiLFxuICAgICAgICAgICAgY2hpbGRyZW46IHRpdGxlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghIWFjdGl2ZVNwYWNlKSB7XG4gICAgICAgICAgICBjb250ZXh0TWVudUJ1dHRvbiA9IChcbiAgICAgICAgICAgICAgICA8Q29udGV4dE1lbnVCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgey4uLmNvbW1vblByb3BzfVxuICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJyb29tX2xpc3R8c3BhY2VfbWVudV9sYWJlbFwiLCB7IHNwYWNlTmFtZTogc3BhY2VOYW1lID8/IGFjdGl2ZVNwYWNlLm5hbWUgfSl9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb250ZXh0TWVudUJ1dHRvbiA9IDxDb250ZXh0TWVudVRvb2x0aXBCdXR0b24gey4uLmNvbW1vblByb3BzfSB0aXRsZT17X3QoXCJyb29tX2xpc3R8aG9tZV9tZW51X2xhYmVsXCIpfSAvPjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICAgIDxhc2lkZSBjbGFzc05hbWU9XCJteF9Sb29tTGlzdEhlYWRlclwiIGFyaWEtbGFiZWw9e190KFwicm9vbXxjb250ZXh0X21lbnV8dGl0bGVcIil9PlxuICAgICAgICAgICAge2NvbnRleHRNZW51QnV0dG9ufVxuICAgICAgICAgICAge3BlbmRpbmdBY3Rpb25TdW1tYXJ5ID8gKFxuICAgICAgICAgICAgICAgIDxUb29sdGlwIGxhYmVsPXtwZW5kaW5nQWN0aW9uU3VtbWFyeX0gaXNUcmlnZ2VySW50ZXJhY3RpdmU9e2ZhbHNlfT5cbiAgICAgICAgICAgICAgICAgICAgPElubGluZVNwaW5uZXIgLz5cbiAgICAgICAgICAgICAgICA8L1Rvb2x0aXA+XG4gICAgICAgICAgICApIDogbnVsbH1cbiAgICAgICAgICAgIHtjYW5TaG93UGx1c01lbnUgJiYgKFxuICAgICAgICAgICAgICAgIDxDb250ZXh0TWVudVRvb2x0aXBCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgcmVmPXtwbHVzTWVudUhhbmRsZX1cbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17b3BlblBsdXNNZW51fVxuICAgICAgICAgICAgICAgICAgICBpc0V4cGFuZGVkPXtwbHVzTWVudURpc3BsYXllZH1cbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfUm9vbUxpc3RIZWFkZXJfcGx1c0J1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPXtfdChcImFjdGlvbnxhZGRcIil9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICl9XG5cbiAgICAgICAgICAgIHtjb250ZXh0TWVudX1cbiAgICAgICAgPC9hc2lkZT5cbiAgICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgUm9vbUxpc3RIZWFkZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBUUEsSUFBQUEsT0FBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsTUFBQSxHQUFBQyx1QkFBQSxDQUFBRixPQUFBO0FBQ0EsSUFBQUcsWUFBQSxHQUFBSCxPQUFBO0FBRUEsSUFBQUksb0JBQUEsR0FBQUMsc0JBQUEsQ0FBQUwsT0FBQTtBQUNBLElBQUFNLGFBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLFFBQUEsR0FB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