matrix-react-sdk
Version:
SDK for matrix.org using React
366 lines (363 loc) • 64.8 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.HomeButtonContextMenu = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _react = _interopRequireWildcard(require("react"));
var _reactBeautifulDnd = require("react-beautiful-dnd");
var _classnames = _interopRequireDefault(require("classnames"));
var _languageHandler = require("../../../languageHandler");
var _ContextMenu = require("../../structures/ContextMenu");
var _SpaceCreateMenu = _interopRequireDefault(require("./SpaceCreateMenu"));
var _SpaceTreeLevel = require("./SpaceTreeLevel");
var _useEventEmitter = require("../../../hooks/useEventEmitter");
var _SpaceStore = _interopRequireDefault(require("../../../stores/spaces/SpaceStore"));
var _spaces = require("../../../stores/spaces");
var _RovingTabIndex = require("../../../accessibility/RovingTabIndex");
var _RoomNotificationStateStore = require("../../../stores/notifications/RoomNotificationStateStore");
var _IconizedContextMenu = _interopRequireWildcard(require("../context_menus/IconizedContextMenu"));
var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore"));
var _SettingLevel = require("../../../settings/SettingLevel");
var _UIStore = _interopRequireDefault(require("../../../stores/UIStore"));
var _QuickSettingsButton = _interopRequireDefault(require("./QuickSettingsButton"));
var _useSettings = require("../../../hooks/useSettings");
var _UserMenu = _interopRequireDefault(require("../../structures/UserMenu"));
var _IndicatorScrollbar = _interopRequireDefault(require("../../structures/IndicatorScrollbar"));
var _useDispatcher = require("../../../hooks/useDispatcher");
var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher"));
var _actions = require("../../../dispatcher/actions");
var _KeyboardShortcuts = require("../../../accessibility/KeyboardShortcuts");
var _KeyBindingsManager = require("../../../KeyBindingsManager");
var _UIComponents = require("../../../customisations/helpers/UIComponents");
var _UIFeature = require("../../../settings/UIFeature");
var _threadsActivityCentre = require("./threads-activity-centre/");
var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton"));
var _LandmarkNavigation = require("../../../accessibility/LandmarkNavigation");
var _KeyboardShortcut = require("../settings/KeyboardShortcut");
const _excluded = ["onFinished", "hideHeader"],
_excluded2 = ["selected", "isPanelCollapsed", "size"],
_excluded3 = ["children", "isPanelCollapsed", "setPanelCollapsed", "isDraggingOver", "innerRef"];
/*
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.
*/
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; }
const useSpaces = () => {
const invites = (0, _useEventEmitter.useEventEmitterState)(_SpaceStore.default.instance, _spaces.UPDATE_INVITED_SPACES, () => {
return _SpaceStore.default.instance.invitedSpaces;
});
const [metaSpaces, actualSpaces] = (0, _useEventEmitter.useEventEmitterState)(_SpaceStore.default.instance, _spaces.UPDATE_TOP_LEVEL_SPACES, () => [_SpaceStore.default.instance.enabledMetaSpaces, _SpaceStore.default.instance.spacePanelSpaces]);
const activeSpace = (0, _useEventEmitter.useEventEmitterState)(_SpaceStore.default.instance, _spaces.UPDATE_SELECTED_SPACE, () => {
return _SpaceStore.default.instance.activeSpace;
});
return [invites, metaSpaces, actualSpaces, activeSpace];
};
const HomeButtonContextMenu = _ref => {
let {
onFinished,
hideHeader
} = _ref,
props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
const allRoomsInHome = (0, _useSettings.useSettingValue)("Spaces.allRoomsInHome");
return /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.default, (0, _extends2.default)({}, props, {
onFinished: onFinished,
className: "mx_SpacePanel_contextMenu",
compact: true
}), !hideHeader && /*#__PURE__*/_react.default.createElement("div", {
className: "mx_SpacePanel_contextMenu_header"
}, (0, _languageHandler._t)("common|home")), /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuOptionList, {
first: true
}, /*#__PURE__*/_react.default.createElement(_IconizedContextMenu.IconizedContextMenuCheckbox, {
iconClassName: "mx_SpacePanel_noIcon",
label: (0, _languageHandler._t)("settings|sidebar|metaspaces_home_all_rooms"),
active: allRoomsInHome,
onClick: () => {
onFinished();
_SettingsStore.default.setValue("Spaces.allRoomsInHome", null, _SettingLevel.SettingLevel.ACCOUNT, !allRoomsInHome);
}
})));
};
exports.HomeButtonContextMenu = HomeButtonContextMenu;
const MetaSpaceButton = _ref2 => {
let {
selected,
isPanelCollapsed,
size = "32px"
} = _ref2,
props = (0, _objectWithoutProperties2.default)(_ref2, _excluded2);
return /*#__PURE__*/_react.default.createElement("li", {
className: (0, _classnames.default)("mx_SpaceItem", {
collapsed: isPanelCollapsed
}),
role: "treeitem",
"aria-selected": selected
}, /*#__PURE__*/_react.default.createElement(_SpaceTreeLevel.SpaceButton, (0, _extends2.default)({}, props, {
selected: selected,
isNarrow: isPanelCollapsed,
size: size
})));
};
const getHomeNotificationState = () => {
return _SpaceStore.default.instance.allRoomsInHome ? _RoomNotificationStateStore.RoomNotificationStateStore.instance.globalState : _SpaceStore.default.instance.getNotificationState(_spaces.MetaSpace.Home);
};
const HomeButton = ({
selected,
isPanelCollapsed
}) => {
const allRoomsInHome = (0, _useEventEmitter.useEventEmitterState)(_SpaceStore.default.instance, _spaces.UPDATE_HOME_BEHAVIOUR, () => {
return _SpaceStore.default.instance.allRoomsInHome;
});
const [notificationState, setNotificationState] = (0, _react.useState)(getHomeNotificationState());
const updateNotificationState = (0, _react.useCallback)(() => {
setNotificationState(getHomeNotificationState());
}, []);
(0, _react.useEffect)(updateNotificationState, [updateNotificationState, allRoomsInHome]);
(0, _useEventEmitter.useEventEmitter)(_RoomNotificationStateStore.RoomNotificationStateStore.instance, _RoomNotificationStateStore.UPDATE_STATUS_INDICATOR, updateNotificationState);
return /*#__PURE__*/_react.default.createElement(MetaSpaceButton, {
spaceKey: _spaces.MetaSpace.Home,
className: "mx_SpaceButton_home",
selected: selected,
isPanelCollapsed: isPanelCollapsed,
label: (0, _spaces.getMetaSpaceName)(_spaces.MetaSpace.Home, allRoomsInHome),
notificationState: notificationState,
ContextMenuComponent: HomeButtonContextMenu,
contextMenuTooltip: (0, _languageHandler._t)("common|options"),
size: "32px"
});
};
const FavouritesButton = ({
selected,
isPanelCollapsed
}) => {
return /*#__PURE__*/_react.default.createElement(MetaSpaceButton, {
spaceKey: _spaces.MetaSpace.Favourites,
className: "mx_SpaceButton_favourites",
selected: selected,
isPanelCollapsed: isPanelCollapsed,
label: (0, _spaces.getMetaSpaceName)(_spaces.MetaSpace.Favourites),
notificationState: _SpaceStore.default.instance.getNotificationState(_spaces.MetaSpace.Favourites),
size: "32px"
});
};
const PeopleButton = ({
selected,
isPanelCollapsed
}) => {
return /*#__PURE__*/_react.default.createElement(MetaSpaceButton, {
spaceKey: _spaces.MetaSpace.People,
className: "mx_SpaceButton_people",
selected: selected,
isPanelCollapsed: isPanelCollapsed,
label: (0, _spaces.getMetaSpaceName)(_spaces.MetaSpace.People),
notificationState: _SpaceStore.default.instance.getNotificationState(_spaces.MetaSpace.People),
size: "32px"
});
};
const OrphansButton = ({
selected,
isPanelCollapsed
}) => {
return /*#__PURE__*/_react.default.createElement(MetaSpaceButton, {
spaceKey: _spaces.MetaSpace.Orphans,
className: "mx_SpaceButton_orphans",
selected: selected,
isPanelCollapsed: isPanelCollapsed,
label: (0, _spaces.getMetaSpaceName)(_spaces.MetaSpace.Orphans),
notificationState: _SpaceStore.default.instance.getNotificationState(_spaces.MetaSpace.Orphans),
size: "32px"
});
};
const VideoRoomsButton = ({
selected,
isPanelCollapsed
}) => {
return /*#__PURE__*/_react.default.createElement(MetaSpaceButton, {
spaceKey: _spaces.MetaSpace.VideoRooms,
className: "mx_SpaceButton_videoRooms",
selected: selected,
isPanelCollapsed: isPanelCollapsed,
label: (0, _spaces.getMetaSpaceName)(_spaces.MetaSpace.VideoRooms),
notificationState: _SpaceStore.default.instance.getNotificationState(_spaces.MetaSpace.VideoRooms),
size: "32px"
});
};
const CreateSpaceButton = ({
isPanelCollapsed,
setPanelCollapsed
}) => {
const [menuDisplayed, handle, openMenu, closeMenu] = (0, _ContextMenu.useContextMenu)();
(0, _react.useEffect)(() => {
if (!isPanelCollapsed && menuDisplayed) {
closeMenu();
}
}, [isPanelCollapsed]); // eslint-disable-line react-hooks/exhaustive-deps
let contextMenu;
if (menuDisplayed) {
contextMenu = /*#__PURE__*/_react.default.createElement(_SpaceCreateMenu.default, {
onFinished: closeMenu
});
}
const onNewClick = menuDisplayed ? closeMenu : () => {
if (!isPanelCollapsed) setPanelCollapsed(true);
openMenu();
};
return /*#__PURE__*/_react.default.createElement("li", {
className: (0, _classnames.default)("mx_SpaceItem mx_SpaceItem_new", {
collapsed: isPanelCollapsed
}),
role: "treeitem",
"aria-selected": false
}, /*#__PURE__*/_react.default.createElement(_SpaceTreeLevel.SpaceButton, {
"data-testid": "create-space-button",
className: (0, _classnames.default)("mx_SpaceButton_new", {
mx_SpaceButton_newCancel: menuDisplayed
}),
label: menuDisplayed ? (0, _languageHandler._t)("action|cancel") : (0, _languageHandler._t)("create_space|label"),
onClick: onNewClick,
isNarrow: isPanelCollapsed,
innerRef: handle,
size: "32px"
}), contextMenu);
};
const metaSpaceComponentMap = {
[_spaces.MetaSpace.Home]: HomeButton,
[_spaces.MetaSpace.Favourites]: FavouritesButton,
[_spaces.MetaSpace.People]: PeopleButton,
[_spaces.MetaSpace.Orphans]: OrphansButton,
[_spaces.MetaSpace.VideoRooms]: VideoRoomsButton
};
// Optimisation based on https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/api/droppable.md#recommended-droppable--performance-optimisation
const InnerSpacePanel = /*#__PURE__*/_react.default.memo(_ref3 => {
let {
children,
isPanelCollapsed,
setPanelCollapsed,
isDraggingOver,
innerRef
} = _ref3,
props = (0, _objectWithoutProperties2.default)(_ref3, _excluded3);
const [invites, metaSpaces, actualSpaces, activeSpace] = useSpaces();
const activeSpaces = activeSpace ? [activeSpace] : [];
const metaSpacesSection = metaSpaces.filter(key => !(key === _spaces.MetaSpace.VideoRooms && !_SettingsStore.default.getValue("feature_video_rooms"))).map(key => {
const Component = metaSpaceComponentMap[key];
return /*#__PURE__*/_react.default.createElement(Component, {
key: key,
selected: activeSpace === key,
isPanelCollapsed: isPanelCollapsed
});
});
return /*#__PURE__*/_react.default.createElement(_IndicatorScrollbar.default, (0, _extends2.default)({}, props, {
wrappedRef: innerRef,
className: "mx_SpaceTreeLevel",
style: isDraggingOver ? {
pointerEvents: "none"
} : undefined,
element: "ul",
role: "tree",
"aria-label": (0, _languageHandler._t)("common|spaces")
}), metaSpacesSection, invites.map(s => /*#__PURE__*/_react.default.createElement(_SpaceTreeLevel.SpaceItem, {
key: s.roomId,
space: s,
activeSpaces: activeSpaces,
isPanelCollapsed: isPanelCollapsed,
onExpand: () => setPanelCollapsed(false)
})), actualSpaces.map((s, i) => /*#__PURE__*/_react.default.createElement(_reactBeautifulDnd.Draggable, {
key: s.roomId,
draggableId: s.roomId,
index: i
}, (provided, snapshot) => /*#__PURE__*/_react.default.createElement(_SpaceTreeLevel.SpaceItem, (0, _extends2.default)({}, provided.draggableProps, {
dragHandleProps: provided.dragHandleProps,
key: s.roomId,
innerRef: provided.innerRef,
className: snapshot.isDragging ? "mx_SpaceItem_dragging" : undefined,
space: s,
activeSpaces: activeSpaces,
isPanelCollapsed: isPanelCollapsed,
onExpand: () => setPanelCollapsed(false)
})))), children, (0, _UIComponents.shouldShowComponent)(_UIFeature.UIComponent.CreateSpaces) && /*#__PURE__*/_react.default.createElement(CreateSpaceButton, {
isPanelCollapsed: isPanelCollapsed,
setPanelCollapsed: setPanelCollapsed
}));
});
const SpacePanel = () => {
const [dragging, setDragging] = (0, _react.useState)(false);
const [isPanelCollapsed, setPanelCollapsed] = (0, _react.useState)(true);
const ref = (0, _react.useRef)(null);
(0, _react.useLayoutEffect)(() => {
if (ref.current) _UIStore.default.instance.trackElementDimensions("SpacePanel", ref.current);
return () => _UIStore.default.instance.stopTrackingElementDimensions("SpacePanel");
}, []);
(0, _useDispatcher.useDispatcher)(_dispatcher.default, payload => {
if (payload.action === _actions.Action.ToggleSpacePanel) {
setPanelCollapsed(!isPanelCollapsed);
}
});
return /*#__PURE__*/_react.default.createElement(_RovingTabIndex.RovingTabIndexProvider, {
handleHomeEnd: true,
handleUpDown: !dragging
}, ({
onKeyDownHandler,
onDragEndHandler
}) => /*#__PURE__*/_react.default.createElement(_reactBeautifulDnd.DragDropContext, {
onDragStart: () => {
setDragging(true);
},
onDragEnd: result => {
setDragging(false);
if (!result.destination) return; // dropped outside the list
_SpaceStore.default.instance.moveRootSpace(result.source.index, result.destination.index);
onDragEndHandler();
}
}, /*#__PURE__*/_react.default.createElement("nav", {
className: (0, _classnames.default)("mx_SpacePanel", {
collapsed: isPanelCollapsed
}),
onKeyDown: ev => {
const navAction = (0, _KeyBindingsManager.getKeyBindingsManager)().getNavigationAction(ev);
if (navAction === _KeyboardShortcuts.KeyBindingAction.NextLandmark || navAction === _KeyboardShortcuts.KeyBindingAction.PreviousLandmark) {
_LandmarkNavigation.LandmarkNavigation.findAndFocusNextLandmark(_LandmarkNavigation.Landmark.ACTIVE_SPACE_BUTTON, navAction === _KeyboardShortcuts.KeyBindingAction.PreviousLandmark);
ev.stopPropagation();
ev.preventDefault();
return;
}
onKeyDownHandler(ev);
},
ref: ref,
"aria-label": (0, _languageHandler._t)("common|spaces")
}, /*#__PURE__*/_react.default.createElement(_UserMenu.default, {
isPanelCollapsed: isPanelCollapsed
}, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
className: (0, _classnames.default)("mx_SpacePanel_toggleCollapse", {
expanded: !isPanelCollapsed
}),
onClick: () => setPanelCollapsed(!isPanelCollapsed),
title: isPanelCollapsed ? (0, _languageHandler._t)("action|expand") : (0, _languageHandler._t)("action|collapse"),
caption: /*#__PURE__*/_react.default.createElement(_KeyboardShortcut.KeyboardShortcut, {
value: {
ctrlOrCmdKey: true,
shiftKey: true,
key: "d"
},
className: "mx_SpacePanel_Tooltip_KeyboardShortcut"
})
})), /*#__PURE__*/_react.default.createElement(_reactBeautifulDnd.Droppable, {
droppableId: "top-level-spaces"
}, (provided, snapshot) => /*#__PURE__*/_react.default.createElement(InnerSpacePanel, (0, _extends2.default)({}, provided.droppableProps, {
isPanelCollapsed: isPanelCollapsed,
setPanelCollapsed: setPanelCollapsed,
isDraggingOver: snapshot.isDraggingOver,
innerRef: provided.innerRef
}), provided.placeholder)), /*#__PURE__*/_react.default.createElement(_threadsActivityCentre.ThreadsActivityCentre, {
displayButtonLabel: !isPanelCollapsed
}), /*#__PURE__*/_react.default.createElement(_QuickSettingsButton.default, {
isPanelCollapsed: isPanelCollapsed
}))));
};
var _default = exports.default = SpacePanel;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfcmVhY3RCZWF1dGlmdWxEbmQiLCJfY2xhc3NuYW1lcyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfbGFuZ3VhZ2VIYW5kbGVyIiwiX0NvbnRleHRNZW51IiwiX1NwYWNlQ3JlYXRlTWVudSIsIl9TcGFjZVRyZWVMZXZlbCIsIl91c2VFdmVudEVtaXR0ZXIiLCJfU3BhY2VTdG9yZSIsIl9zcGFjZXMiLCJfUm92aW5nVGFiSW5kZXgiLCJfUm9vbU5vdGlmaWNhdGlvblN0YXRlU3RvcmUiLCJfSWNvbml6ZWRDb250ZXh0TWVudSIsIl9TZXR0aW5nc1N0b3JlIiwiX1NldHRpbmdMZXZlbCIsIl9VSVN0b3JlIiwiX1F1aWNrU2V0dGluZ3NCdXR0b24iLCJfdXNlU2V0dGluZ3MiLCJfVXNlck1lbnUiLCJfSW5kaWNhdG9yU2Nyb2xsYmFyIiwiX3VzZURpc3BhdGNoZXIiLCJfZGlzcGF0Y2hlciIsIl9hY3Rpb25zIiwiX0tleWJvYXJkU2hvcnRjdXRzIiwiX0tleUJpbmRpbmdzTWFuYWdlciIsIl9VSUNvbXBvbmVudHMiLCJfVUlGZWF0dXJlIiwiX3RocmVhZHNBY3Rpdml0eUNlbnRyZSIsIl9BY2Nlc3NpYmxlQnV0dG9uIiwiX0xhbmRtYXJrTmF2aWdhdGlvbiIsIl9LZXlib2FyZFNob3J0Y3V0IiwiX2V4Y2x1ZGVkIiwiX2V4Y2x1ZGVkMiIsIl9leGNsdWRlZDMiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJ1c2VTcGFjZXMiLCJpbnZpdGVzIiwidXNlRXZlbnRFbWl0dGVyU3RhdGUiLCJTcGFjZVN0b3JlIiwiaW5zdGFuY2UiLCJVUERBVEVfSU5WSVRFRF9TUEFDRVMiLCJpbnZpdGVkU3BhY2VzIiwibWV0YVNwYWNlcyIsImFjdHVhbFNwYWNlcyIsIlVQREFURV9UT1BfTEVWRUxfU1BBQ0VTIiwiZW5hYmxlZE1ldGFTcGFjZXMiLCJzcGFjZVBhbmVsU3BhY2VzIiwiYWN0aXZlU3BhY2UiLCJVUERBVEVfU0VMRUNURURfU1BBQ0UiLCJIb21lQnV0dG9uQ29udGV4dE1lbnUiLCJfcmVmIiwib25GaW5pc2hlZCIsImhpZGVIZWFkZXIiLCJwcm9wcyIsIl9vYmplY3RXaXRob3V0UHJvcGVydGllczIiLCJhbGxSb29tc0luSG9tZSIsInVzZVNldHRpbmdWYWx1ZSIsImNyZWF0ZUVsZW1lbnQiLCJfZXh0ZW5kczIiLCJjbGFzc05hbWUiLCJjb21wYWN0IiwiX3QiLCJJY29uaXplZENvbnRleHRNZW51T3B0aW9uTGlzdCIsImZpcnN0IiwiSWNvbml6ZWRDb250ZXh0TWVudUNoZWNrYm94IiwiaWNvbkNsYXNzTmFtZSIsImxhYmVsIiwiYWN0aXZlIiwib25DbGljayIsIlNldHRpbmdzU3RvcmUiLCJzZXRWYWx1ZSIsIlNldHRpbmdMZXZlbCIsIkFDQ09VTlQiLCJleHBvcnRzIiwiTWV0YVNwYWNlQnV0dG9uIiwiX3JlZjIiLCJzZWxlY3RlZCIsImlzUGFuZWxDb2xsYXBzZWQiLCJzaXplIiwiY2xhc3NOYW1lcyIsImNvbGxhcHNlZCIsInJvbGUiLCJTcGFjZUJ1dHRvbiIsImlzTmFycm93IiwiZ2V0SG9tZU5vdGlmaWNhdGlvblN0YXRlIiwiUm9vbU5vdGlmaWNhdGlvblN0YXRlU3RvcmUiLCJnbG9iYWxTdGF0ZSIsImdldE5vdGlmaWNhdGlvblN0YXRlIiwiTWV0YVNwYWNlIiwiSG9tZSIsIkhvbWVCdXR0b24iLCJVUERBVEVfSE9NRV9CRUhBVklPVVIiLCJub3RpZmljYXRpb25TdGF0ZSIsInNldE5vdGlmaWNhdGlvblN0YXRlIiwidXNlU3RhdGUiLCJ1cGRhdGVOb3RpZmljYXRpb25TdGF0ZSIsInVzZUNhbGxiYWNrIiwidXNlRWZmZWN0IiwidXNlRXZlbnRFbWl0dGVyIiwiVVBEQVRFX1NUQVRVU19JTkRJQ0FUT1IiLCJzcGFjZUtleSIsImdldE1ldGFTcGFjZU5hbWUiLCJDb250ZXh0TWVudUNvbXBvbmVudCIsImNvbnRleHRNZW51VG9vbHRpcCIsIkZhdm91cml0ZXNCdXR0b24iLCJGYXZvdXJpdGVzIiwiUGVvcGxlQnV0dG9uIiwiUGVvcGxlIiwiT3JwaGFuc0J1dHRvbiIsIk9ycGhhbnMiLCJWaWRlb1Jvb21zQnV0dG9uIiwiVmlkZW9Sb29tcyIsIkNyZWF0ZVNwYWNlQnV0dG9uIiwic2V0UGFuZWxDb2xsYXBzZWQiLCJtZW51RGlzcGxheWVkIiwiaGFuZGxlIiwib3Blbk1lbnUiLCJjbG9zZU1lbnUiLCJ1c2VDb250ZXh0TWVudSIsImNvbnRleHRNZW51Iiwib25OZXdDbGljayIsIm14X1NwYWNlQnV0dG9uX25ld0NhbmNlbCIsImlubmVyUmVmIiwibWV0YVNwYWNlQ29tcG9uZW50TWFwIiwiSW5uZXJTcGFjZVBhbmVsIiwiUmVhY3QiLCJtZW1vIiwiX3JlZjMiLCJjaGlsZHJlbiIsImlzRHJhZ2dpbmdPdmVyIiwiYWN0aXZlU3BhY2VzIiwibWV0YVNwYWNlc1NlY3Rpb24iLCJmaWx0ZXIiLCJrZXkiLCJnZXRWYWx1ZSIsIm1hcCIsIkNvbXBvbmVudCIsIndyYXBwZWRSZWYiLCJzdHlsZSIsInBvaW50ZXJFdmVudHMiLCJ1bmRlZmluZWQiLCJlbGVtZW50IiwicyIsIlNwYWNlSXRlbSIsInJvb21JZCIsInNwYWNlIiwib25FeHBhbmQiLCJEcmFnZ2FibGUiLCJkcmFnZ2FibGVJZCIsImluZGV4IiwicHJvdmlkZWQiLCJzbmFwc2hvdCIsImRyYWdnYWJsZVByb3BzIiwiZHJhZ0hhbmRsZVByb3BzIiwiaXNEcmFnZ2luZyIsInNob3VsZFNob3dDb21wb25lbnQiLCJVSUNvbXBvbmVudCIsIkNyZWF0ZVNwYWNlcyIsIlNwYWNlUGFuZWwiLCJkcmFnZ2luZyIsInNldERyYWdnaW5nIiwicmVmIiwidXNlUmVmIiwidXNlTGF5b3V0RWZmZWN0IiwiY3VycmVudCIsIlVJU3RvcmUiLCJ0cmFja0VsZW1lbnREaW1lbnNpb25zIiwic3RvcFRyYWNraW5nRWxlbWVudERpbWVuc2lvbnMiLCJ1c2VEaXNwYXRjaGVyIiwiZGVmYXVsdERpc3BhdGNoZXIiLCJwYXlsb2FkIiwiYWN0aW9uIiwiQWN0aW9uIiwiVG9nZ2xlU3BhY2VQYW5lbCIsIlJvdmluZ1RhYkluZGV4UHJvdmlkZXIiLCJoYW5kbGVIb21lRW5kIiwiaGFuZGxlVXBEb3duIiwib25LZXlEb3duSGFuZGxlciIsIm9uRHJhZ0VuZEhhbmRsZXIiLCJEcmFnRHJvcENvbnRleHQiLCJvbkRyYWdTdGFydCIsIm9uRHJhZ0VuZCIsInJlc3VsdCIsImRlc3RpbmF0aW9uIiwibW92ZVJvb3RTcGFjZSIsInNvdXJjZSIsIm9uS2V5RG93biIsImV2IiwibmF2QWN0aW9uIiwiZ2V0S2V5QmluZGluZ3NNYW5hZ2VyIiwiZ2V0TmF2aWdhdGlvbkFjdGlvbiIsIktleUJpbmRpbmdBY3Rpb24iLCJOZXh0TGFuZG1hcmsiLCJQcmV2aW91c0xhbmRtYXJrIiwiTGFuZG1hcmtOYXZpZ2F0aW9uIiwiZmluZEFuZEZvY3VzTmV4dExhbmRtYXJrIiwiTGFuZG1hcmsiLCJBQ1RJVkVfU1BBQ0VfQlVUVE9OIiwic3RvcFByb3BhZ2F0aW9uIiwicHJldmVudERlZmF1bHQiLCJleHBhbmRlZCIsInRpdGxlIiwiY2FwdGlvbiIsIktleWJvYXJkU2hvcnRjdXQiLCJ2YWx1ZSIsImN0cmxPckNtZEtleSIsInNoaWZ0S2V5IiwiRHJvcHBhYmxlIiwiZHJvcHBhYmxlSWQiLCJkcm9wcGFibGVQcm9wcyIsInBsYWNlaG9sZGVyIiwiVGhyZWFkc0FjdGl2aXR5Q2VudHJlIiwiZGlzcGxheUJ1dHRvbkxhYmVsIiwiX2RlZmF1bHQiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy92aWV3cy9zcGFjZXMvU3BhY2VQYW5lbC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjEsIDIwMjIgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7XG4gICAgQ29tcG9uZW50UHJvcHMsXG4gICAgRGlzcGF0Y2gsXG4gICAgUmVhY3ROb2RlLFxuICAgIFJlZkNhbGxiYWNrLFxuICAgIFNldFN0YXRlQWN0aW9uLFxuICAgIHVzZUNhbGxiYWNrLFxuICAgIHVzZUVmZmVjdCxcbiAgICB1c2VMYXlvdXRFZmZlY3QsXG4gICAgdXNlUmVmLFxuICAgIHVzZVN0YXRlLFxufSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IERyYWdEcm9wQ29udGV4dCwgRHJhZ2dhYmxlLCBEcm9wcGFibGUsIERyb3BwYWJsZVByb3ZpZGVkUHJvcHMgfSBmcm9tIFwicmVhY3QtYmVhdXRpZnVsLWRuZFwiO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSBcImNsYXNzbmFtZXNcIjtcbmltcG9ydCB7IFJvb20gfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5cbmltcG9ydCB7IF90IH0gZnJvbSBcIi4uLy4uLy4uL2xhbmd1YWdlSGFuZGxlclwiO1xuaW1wb3J0IHsgdXNlQ29udGV4dE1lbnUgfSBmcm9tIFwiLi4vLi4vc3RydWN0dXJlcy9Db250ZXh0TWVudVwiO1xuaW1wb3J0IFNwYWNlQ3JlYXRlTWVudSBmcm9tIFwiLi9TcGFjZUNyZWF0ZU1lbnVcIjtcbmltcG9ydCB7IFNwYWNlQnV0dG9uLCBTcGFjZUl0ZW0gfSBmcm9tIFwiLi9TcGFjZVRyZWVMZXZlbFwiO1xuaW1wb3J0IHsgdXNlRXZlbnRFbWl0dGVyLCB1c2VFdmVudEVtaXR0ZXJTdGF0ZSB9IGZyb20gXCIuLi8uLi8uLi9ob29rcy91c2VFdmVudEVtaXR0ZXJcIjtcbmltcG9ydCBTcGFjZVN0b3JlIGZyb20gXCIuLi8uLi8uLi9zdG9yZXMvc3BhY2VzL1NwYWNlU3RvcmVcIjtcbmltcG9ydCB7XG4gICAgZ2V0TWV0YVNwYWNlTmFtZSxcbiAgICBNZXRhU3BhY2UsXG4gICAgU3BhY2VLZXksXG4gICAgVVBEQVRFX0hPTUVfQkVIQVZJT1VSLFxuICAgIFVQREFURV9JTlZJVEVEX1NQQUNFUyxcbiAgICBVUERBVEVfU0VMRUNURURfU1BBQ0UsXG4gICAgVVBEQVRFX1RPUF9MRVZFTF9TUEFDRVMsXG59IGZyb20gXCIuLi8uLi8uLi9zdG9yZXMvc3BhY2VzXCI7XG5pbXBvcnQgeyBSb3ZpbmdUYWJJbmRleFByb3ZpZGVyIH0gZnJvbSBcIi4uLy4uLy4uL2FjY2Vzc2liaWxpdHkvUm92aW5nVGFiSW5kZXhcIjtcbmltcG9ydCB7XG4gICAgUm9vbU5vdGlmaWNhdGlvblN0YXRlU3RvcmUsXG4gICAgVVBEQVRFX1NUQVRVU19JTkRJQ0FUT1IsXG59IGZyb20gXCIuLi8uLi8uLi9zdG9yZXMvbm90aWZpY2F0aW9ucy9Sb29tTm90aWZpY2F0aW9uU3RhdGVTdG9yZVwiO1xuaW1wb3J0IFNwYWNlQ29udGV4dE1lbnUgZnJvbSBcIi4uL2NvbnRleHRfbWVudXMvU3BhY2VDb250ZXh0TWVudVwiO1xuaW1wb3J0IEljb25pemVkQ29udGV4dE1lbnUsIHtcbiAgICBJY29uaXplZENvbnRleHRNZW51Q2hlY2tib3gsXG4gICAgSWNvbml6ZWRDb250ZXh0TWVudU9wdGlvbkxpc3QsXG59IGZyb20gXCIuLi9jb250ZXh0X21lbnVzL0ljb25pemVkQ29udGV4dE1lbnVcIjtcbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gXCIuLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgeyBTZXR0aW5nTGV2ZWwgfSBmcm9tIFwiLi4vLi4vLi4vc2V0dGluZ3MvU2V0dGluZ0xldmVsXCI7XG5pbXBvcnQgVUlTdG9yZSBmcm9tIFwiLi4vLi4vLi4vc3RvcmVzL1VJU3RvcmVcIjtcbmltcG9ydCBRdWlja1NldHRpbmdzQnV0dG9uIGZyb20gXCIuL1F1aWNrU2V0dGluZ3NCdXR0b25cIjtcbmltcG9ydCB7IHVzZVNldHRpbmdWYWx1ZSB9IGZyb20gXCIuLi8uLi8uLi9ob29rcy91c2VTZXR0aW5nc1wiO1xuaW1wb3J0IFVzZXJNZW51IGZyb20gXCIuLi8uLi9zdHJ1Y3R1cmVzL1VzZXJNZW51XCI7XG5pbXBvcnQgSW5kaWNhdG9yU2Nyb2xsYmFyIGZyb20gXCIuLi8uLi9zdHJ1Y3R1cmVzL0luZGljYXRvclNjcm9sbGJhclwiO1xuaW1wb3J0IHsgdXNlRGlzcGF0Y2hlciB9IGZyb20gXCIuLi8uLi8uLi9ob29rcy91c2VEaXNwYXRjaGVyXCI7XG5pbXBvcnQgZGVmYXVsdERpc3BhdGNoZXIgZnJvbSBcIi4uLy4uLy4uL2Rpc3BhdGNoZXIvZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgQWN0aW9uUGF5bG9hZCB9IGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL3BheWxvYWRzXCI7XG5pbXBvcnQgeyBBY3Rpb24gfSBmcm9tIFwiLi4vLi4vLi4vZGlzcGF0Y2hlci9hY3Rpb25zXCI7XG5pbXBvcnQgeyBOb3RpZmljYXRpb25TdGF0ZSB9IGZyb20gXCIuLi8uLi8uLi9zdG9yZXMvbm90aWZpY2F0aW9ucy9Ob3RpZmljYXRpb25TdGF0ZVwiO1xuaW1wb3J0IHsgS2V5QmluZGluZ0FjdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9hY2Nlc3NpYmlsaXR5L0tleWJvYXJkU2hvcnRjdXRzXCI7XG5pbXBvcnQgeyBnZXRLZXlCaW5kaW5nc01hbmFnZXIgfSBmcm9tIFwiLi4vLi4vLi4vS2V5QmluZGluZ3NNYW5hZ2VyXCI7XG5pbXBvcnQgeyBzaG91bGRTaG93Q29tcG9uZW50IH0gZnJvbSBcIi4uLy4uLy4uL2N1c3RvbWlzYXRpb25zL2hlbHBlcnMvVUlDb21wb25lbnRzXCI7XG5pbXBvcnQgeyBVSUNvbXBvbmVudCB9IGZyb20gXCIuLi8uLi8uLi9zZXR0aW5ncy9VSUZlYXR1cmVcIjtcbmltcG9ydCB7IFRocmVhZHNBY3Rpdml0eUNlbnRyZSB9IGZyb20gXCIuL3RocmVhZHMtYWN0aXZpdHktY2VudHJlL1wiO1xuaW1wb3J0IEFjY2Vzc2libGVCdXR0b24gZnJvbSBcIi4uL2VsZW1lbnRzL0FjY2Vzc2libGVCdXR0b25cIjtcbmltcG9ydCB7IExhbmRtYXJrLCBMYW5kbWFya05hdmlnYXRpb24gfSBmcm9tIFwiLi4vLi4vLi4vYWNjZXNzaWJpbGl0eS9MYW5kbWFya05hdmlnYXRpb25cIjtcbmltcG9ydCB7IEtleWJvYXJkU2hvcnRjdXQgfSBmcm9tIFwiLi4vc2V0dGluZ3MvS2V5Ym9hcmRTaG9ydGN1dFwiO1xuXG5jb25zdCB1c2VTcGFjZXMgPSAoKTogW1Jvb21bXSwgTWV0YVNwYWNlW10sIFJvb21bXSwgU3BhY2VLZXldID0+IHtcbiAgICBjb25zdCBpbnZpdGVzID0gdXNlRXZlbnRFbWl0dGVyU3RhdGU8Um9vbVtdPihTcGFjZVN0b3JlLmluc3RhbmNlLCBVUERBVEVfSU5WSVRFRF9TUEFDRVMsICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFNwYWNlU3RvcmUuaW5zdGFuY2UuaW52aXRlZFNwYWNlcztcbiAgICB9KTtcbiAgICBjb25zdCBbbWV0YVNwYWNlcywgYWN0dWFsU3BhY2VzXSA9IHVzZUV2ZW50RW1pdHRlclN0YXRlPFtNZXRhU3BhY2VbXSwgUm9vbVtdXT4oXG4gICAgICAgIFNwYWNlU3RvcmUuaW5zdGFuY2UsXG4gICAgICAgIFVQREFURV9UT1BfTEVWRUxfU1BBQ0VTLFxuICAgICAgICAoKSA9PiBbU3BhY2VTdG9yZS5pbnN0YW5jZS5lbmFibGVkTWV0YVNwYWNlcywgU3BhY2VTdG9yZS5pbnN0YW5jZS5zcGFjZVBhbmVsU3BhY2VzXSxcbiAgICApO1xuICAgIGNvbnN0IGFjdGl2ZVNwYWNlID0gdXNlRXZlbnRFbWl0dGVyU3RhdGU8U3BhY2VLZXk+KFNwYWNlU3RvcmUuaW5zdGFuY2UsIFVQREFURV9TRUxFQ1RFRF9TUEFDRSwgKCkgPT4ge1xuICAgICAgICByZXR1cm4gU3BhY2VTdG9yZS5pbnN0YW5jZS5hY3RpdmVTcGFjZTtcbiAgICB9KTtcbiAgICByZXR1cm4gW2ludml0ZXMsIG1ldGFTcGFjZXMsIGFjdHVhbFNwYWNlcywgYWN0aXZlU3BhY2VdO1xufTtcblxuZXhwb3J0IGNvbnN0IEhvbWVCdXR0b25Db250ZXh0TWVudTogUmVhY3QuRkM8Q29tcG9uZW50UHJvcHM8dHlwZW9mIFNwYWNlQ29udGV4dE1lbnU+PiA9ICh7XG4gICAgb25GaW5pc2hlZCxcbiAgICBoaWRlSGVhZGVyLFxuICAgIC4uLnByb3BzXG59KSA9PiB7XG4gICAgY29uc3QgYWxsUm9vbXNJbkhvbWUgPSB1c2VTZXR0aW5nVmFsdWU8Ym9vbGVhbj4oXCJTcGFjZXMuYWxsUm9vbXNJbkhvbWVcIik7XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8SWNvbml6ZWRDb250ZXh0TWVudSB7Li4ucHJvcHN9IG9uRmluaXNoZWQ9e29uRmluaXNoZWR9IGNsYXNzTmFtZT1cIm14X1NwYWNlUGFuZWxfY29udGV4dE1lbnVcIiBjb21wYWN0PlxuICAgICAgICAgICAgeyFoaWRlSGVhZGVyICYmIDxkaXYgY2xhc3NOYW1lPVwibXhfU3BhY2VQYW5lbF9jb250ZXh0TWVudV9oZWFkZXJcIj57X3QoXCJjb21tb258aG9tZVwiKX08L2Rpdj59XG4gICAgICAgICAgICA8SWNvbml6ZWRDb250ZXh0TWVudU9wdGlvbkxpc3QgZmlyc3Q+XG4gICAgICAgICAgICAgICAgPEljb25pemVkQ29udGV4dE1lbnVDaGVja2JveFxuICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lPVwibXhfU3BhY2VQYW5lbF9ub0ljb25cIlxuICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJzZXR0aW5nc3xzaWRlYmFyfG1ldGFzcGFjZXNfaG9tZV9hbGxfcm9vbXNcIil9XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZT17YWxsUm9vbXNJbkhvbWV9XG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eygpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uRmluaXNoZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIFNldHRpbmdzU3RvcmUuc2V0VmFsdWUoXCJTcGFjZXMuYWxsUm9vbXNJbkhvbWVcIiwgbnVsbCwgU2V0dGluZ0xldmVsLkFDQ09VTlQsICFhbGxSb29tc0luSG9tZSk7XG4gICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDwvSWNvbml6ZWRDb250ZXh0TWVudU9wdGlvbkxpc3Q+XG4gICAgICAgIDwvSWNvbml6ZWRDb250ZXh0TWVudT5cbiAgICApO1xufTtcblxuaW50ZXJmYWNlIElNZXRhU3BhY2VCdXR0b25Qcm9wcyBleHRlbmRzIENvbXBvbmVudFByb3BzPHR5cGVvZiBTcGFjZUJ1dHRvbj4ge1xuICAgIHNlbGVjdGVkOiBib29sZWFuO1xuICAgIGlzUGFuZWxDb2xsYXBzZWQ6IGJvb2xlYW47XG59XG5cbnR5cGUgTWV0YVNwYWNlQnV0dG9uUHJvcHMgPSBQaWNrPElNZXRhU3BhY2VCdXR0b25Qcm9wcywgXCJzZWxlY3RlZFwiIHwgXCJpc1BhbmVsQ29sbGFwc2VkXCI+O1xuXG5jb25zdCBNZXRhU3BhY2VCdXR0b246IFJlYWN0LkZDPElNZXRhU3BhY2VCdXR0b25Qcm9wcz4gPSAoeyBzZWxlY3RlZCwgaXNQYW5lbENvbGxhcHNlZCwgc2l6ZSA9IFwiMzJweFwiLCAuLi5wcm9wcyB9KSA9PiB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgPGxpXG4gICAgICAgICAgICBjbGFzc05hbWU9e2NsYXNzTmFtZXMoXCJteF9TcGFjZUl0ZW1cIiwge1xuICAgICAgICAgICAgICAgIGNvbGxhcHNlZDogaXNQYW5lbENvbGxhcHNlZCxcbiAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgcm9sZT1cInRyZWVpdGVtXCJcbiAgICAgICAgICAgIGFyaWEtc2VsZWN0ZWQ9e3NlbGVjdGVkfVxuICAgICAgICA+XG4gICAgICAgICAgICA8U3BhY2VCdXR0b24gey4uLnByb3BzfSBzZWxlY3RlZD17c2VsZWN0ZWR9IGlzTmFycm93PXtpc1BhbmVsQ29sbGFwc2VkfSBzaXplPXtzaXplfSAvPlxuICAgICAgICA8L2xpPlxuICAgICk7XG59O1xuXG5jb25zdCBnZXRIb21lTm90aWZpY2F0aW9uU3RhdGUgPSAoKTogTm90aWZpY2F0aW9uU3RhdGUgPT4ge1xuICAgIHJldHVybiBTcGFjZVN0b3JlLmluc3RhbmNlLmFsbFJvb21zSW5Ib21lXG4gICAgICAgID8gUm9vbU5vdGlmaWNhdGlvblN0YXRlU3RvcmUuaW5zdGFuY2UuZ2xvYmFsU3RhdGVcbiAgICAgICAgOiBTcGFjZVN0b3JlLmluc3RhbmNlLmdldE5vdGlmaWNhdGlvblN0YXRlKE1ldGFTcGFjZS5Ib21lKTtcbn07XG5cbmNvbnN0IEhvbWVCdXR0b246IFJlYWN0LkZDPE1ldGFTcGFjZUJ1dHRvblByb3BzPiA9ICh7IHNlbGVjdGVkLCBpc1BhbmVsQ29sbGFwc2VkIH0pID0+IHtcbiAgICBjb25zdCBhbGxSb29tc0luSG9tZSA9IHVzZUV2ZW50RW1pdHRlclN0YXRlKFNwYWNlU3RvcmUuaW5zdGFuY2UsIFVQREFURV9IT01FX0JFSEFWSU9VUiwgKCkgPT4ge1xuICAgICAgICByZXR1cm4gU3BhY2VTdG9yZS5pbnN0YW5jZS5hbGxSb29tc0luSG9tZTtcbiAgICB9KTtcbiAgICBjb25zdCBbbm90aWZpY2F0aW9uU3RhdGUsIHNldE5vdGlmaWNhdGlvblN0YXRlXSA9IHVzZVN0YXRlKGdldEhvbWVOb3RpZmljYXRpb25TdGF0ZSgpKTtcbiAgICBjb25zdCB1cGRhdGVOb3RpZmljYXRpb25TdGF0ZSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICAgICAgc2V0Tm90aWZpY2F0aW9uU3RhdGUoZ2V0SG9tZU5vdGlmaWNhdGlvblN0YXRlKCkpO1xuICAgIH0sIFtdKTtcbiAgICB1c2VFZmZlY3QodXBkYXRlTm90aWZpY2F0aW9uU3RhdGUsIFt1cGRhdGVOb3RpZmljYXRpb25TdGF0ZSwgYWxsUm9vbXNJbkhvbWVdKTtcbiAgICB1c2VFdmVudEVtaXR0ZXIoUm9vbU5vdGlmaWNhdGlvblN0YXRlU3RvcmUuaW5zdGFuY2UsIFVQREFURV9TVEFUVVNfSU5ESUNBVE9SLCB1cGRhdGVOb3RpZmljYXRpb25TdGF0ZSk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8TWV0YVNwYWNlQnV0dG9uXG4gICAgICAgICAgICBzcGFjZUtleT17TWV0YVNwYWNlLkhvbWV9XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJteF9TcGFjZUJ1dHRvbl9ob21lXCJcbiAgICAgICAgICAgIHNlbGVjdGVkPXtzZWxlY3RlZH1cbiAgICAgICAgICAgIGlzUGFuZWxDb2xsYXBzZWQ9e2lzUGFuZWxDb2xsYXBzZWR9XG4gICAgICAgICAgICBsYWJlbD17Z2V0TWV0YVNwYWNlTmFtZShNZXRhU3BhY2UuSG9tZSwgYWxsUm9vbXNJbkhvbWUpfVxuICAgICAgICAgICAgbm90aWZpY2F0aW9uU3RhdGU9e25vdGlmaWNhdGlvblN0YXRlfVxuICAgICAgICAgICAgQ29udGV4dE1lbnVDb21wb25lbnQ9e0hvbWVCdXR0b25Db250ZXh0TWVudX1cbiAgICAgICAgICAgIGNvbnRleHRNZW51VG9vbHRpcD17X3QoXCJjb21tb258b3B0aW9uc1wiKX1cbiAgICAgICAgICAgIHNpemU9XCIzMnB4XCJcbiAgICAgICAgLz5cbiAgICApO1xufTtcblxuY29uc3QgRmF2b3VyaXRlc0J1dHRvbjogUmVhY3QuRkM8TWV0YVNwYWNlQnV0dG9uUHJvcHM+ID0gKHsgc2VsZWN0ZWQsIGlzUGFuZWxDb2xsYXBzZWQgfSkgPT4ge1xuICAgIHJldHVybiAoXG4gICAgICAgIDxNZXRhU3BhY2VCdXR0b25cbiAgICAgICAgICAgIHNwYWNlS2V5PXtNZXRhU3BhY2UuRmF2b3VyaXRlc31cbiAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1NwYWNlQnV0dG9uX2Zhdm91cml0ZXNcIlxuICAgICAgICAgICAgc2VsZWN0ZWQ9e3NlbGVjdGVkfVxuICAgICAgICAgICAgaXNQYW5lbENvbGxhcHNlZD17aXNQYW5lbENvbGxhcHNlZH1cbiAgICAgICAgICAgIGxhYmVsPXtnZXRNZXRhU3BhY2VOYW1lKE1ldGFTcGFjZS5GYXZvdXJpdGVzKX1cbiAgICAgICAgICAgIG5vdGlmaWNhdGlvblN0YXRlPXtTcGFjZVN0b3JlLmluc3RhbmNlLmdldE5vdGlmaWNhdGlvblN0YXRlKE1ldGFTcGFjZS5GYXZvdXJpdGVzKX1cbiAgICAgICAgICAgIHNpemU9XCIzMnB4XCJcbiAgICAgICAgLz5cbiAgICApO1xufTtcblxuY29uc3QgUGVvcGxlQnV0dG9uOiBSZWFjdC5GQzxNZXRhU3BhY2VCdXR0b25Qcm9wcz4gPSAoeyBzZWxlY3RlZCwgaXNQYW5lbENvbGxhcHNlZCB9KSA9PiB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgPE1ldGFTcGFjZUJ1dHRvblxuICAgICAgICAgICAgc3BhY2VLZXk9e01ldGFTcGFjZS5QZW9wbGV9XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJteF9TcGFjZUJ1dHRvbl9wZW9wbGVcIlxuICAgICAgICAgICAgc2VsZWN0ZWQ9e3NlbGVjdGVkfVxuICAgICAgICAgICAgaXNQYW5lbENvbGxhcHNlZD17aXNQYW5lbENvbGxhcHNlZH1cbiAgICAgICAgICAgIGxhYmVsPXtnZXRNZXRhU3BhY2VOYW1lKE1ldGFTcGFjZS5QZW9wbGUpfVxuICAgICAgICAgICAgbm90aWZpY2F0aW9uU3RhdGU9e1NwYWNlU3RvcmUuaW5zdGFuY2UuZ2V0Tm90aWZpY2F0aW9uU3RhdGUoTWV0YVNwYWNlLlBlb3BsZSl9XG4gICAgICAgICAgICBzaXplPVwiMzJweFwiXG4gICAgICAgIC8+XG4gICAgKTtcbn07XG5cbmNvbnN0IE9ycGhhbnNCdXR0b246IFJlYWN0LkZDPE1ldGFTcGFjZUJ1dHRvblByb3BzPiA9ICh7IHNlbGVjdGVkLCBpc1BhbmVsQ29sbGFwc2VkIH0pID0+IHtcbiAgICByZXR1cm4gKFxuICAgICAgICA8TWV0YVNwYWNlQnV0dG9uXG4gICAgICAgICAgICBzcGFjZUtleT17TWV0YVNwYWNlLk9ycGhhbnN9XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJteF9TcGFjZUJ1dHRvbl9vcnBoYW5zXCJcbiAgICAgICAgICAgIHNlbGVjdGVkPXtzZWxlY3RlZH1cbiAgICAgICAgICAgIGlzUGFuZWxDb2xsYXBzZWQ9e2lzUGFuZWxDb2xsYXBzZWR9XG4gICAgICAgICAgICBsYWJlbD17Z2V0TWV0YVNwYWNlTmFtZShNZXRhU3BhY2UuT3JwaGFucyl9XG4gICAgICAgICAgICBub3RpZmljYXRpb25TdGF0ZT17U3BhY2VTdG9yZS5pbnN0YW5jZS5nZXROb3RpZmljYXRpb25TdGF0ZShNZXRhU3BhY2UuT3JwaGFucyl9XG4gICAgICAgICAgICBzaXplPVwiMzJweFwiXG4gICAgICAgIC8+XG4gICAgKTtcbn07XG5cbmNvbnN0IFZpZGVvUm9vbXNCdXR0b246IFJlYWN0LkZDPE1ldGFTcGFjZUJ1dHRvblByb3BzPiA9ICh7IHNlbGVjdGVkLCBpc1BhbmVsQ29sbGFwc2VkIH0pID0+IHtcbiAgICByZXR1cm4gKFxuICAgICAgICA8TWV0YVNwYWNlQnV0dG9uXG4gICAgICAgICAgICBzcGFjZUtleT17TWV0YVNwYWNlLlZpZGVvUm9vbXN9XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJteF9TcGFjZUJ1dHRvbl92aWRlb1Jvb21zXCJcbiAgICAgICAgICAgIHNlbGVjdGVkPXtzZWxlY3RlZH1cbiAgICAgICAgICAgIGlzUGFuZWxDb2xsYXBzZWQ9e2lzUGFuZWxDb2xsYXBzZWR9XG4gICAgICAgICAgICBsYWJlbD17Z2V0TWV0YVNwYWNlTmFtZShNZXRhU3BhY2UuVmlkZW9Sb29tcyl9XG4gICAgICAgICAgICBub3RpZmljYXRpb25TdGF0ZT17U3BhY2VTdG9yZS5pbnN0YW5jZS5nZXROb3RpZmljYXRpb25TdGF0ZShNZXRhU3BhY2UuVmlkZW9Sb29tcyl9XG4gICAgICAgICAgICBzaXplPVwiMzJweFwiXG4gICAgICAgIC8+XG4gICAgKTtcbn07XG5cbmNvbnN0IENyZWF0ZVNwYWNlQnV0dG9uOiBSZWFjdC5GQzxQaWNrPElJbm5lclNwYWNlUGFuZWxQcm9wcywgXCJpc1BhbmVsQ29sbGFwc2VkXCIgfCBcInNldFBhbmVsQ29sbGFwc2VkXCI+PiA9ICh7XG4gICAgaXNQYW5lbENvbGxhcHNlZCxcbiAgICBzZXRQYW5lbENvbGxhcHNlZCxcbn0pID0+IHtcbiAgICBjb25zdCBbbWVudURpc3BsYXllZCwgaGFuZGxlLCBvcGVuTWVudSwgY2xvc2VNZW51XSA9IHVzZUNvbnRleHRNZW51PEhUTUxFbGVtZW50PigpO1xuXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgaWYgKCFpc1BhbmVsQ29sbGFwc2VkICYmIG1lbnVEaXNwbGF5ZWQpIHtcbiAgICAgICAgICAgIGNsb3NlTWVudSgpO1xuICAgICAgICB9XG4gICAgfSwgW2lzUGFuZWxDb2xsYXBzZWRdKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcblxuICAgIGxldCBjb250ZXh0TWVudTogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgaWYgKG1lbnVEaXNwbGF5ZWQpIHtcbiAgICAgICAgY29udGV4dE1lbnUgPSA8U3BhY2VDcmVhdGVNZW51IG9uRmluaXNoZWQ9e2Nsb3NlTWVudX0gLz47XG4gICAgfVxuXG4gICAgY29uc3Qgb25OZXdDbGljayA9IG1lbnVEaXNwbGF5ZWRcbiAgICAgICAgPyBjbG9zZU1lbnVcbiAgICAgICAgOiAoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghaXNQYW5lbENvbGxhcHNlZCkgc2V0UGFuZWxDb2xsYXBzZWQodHJ1ZSk7XG4gICAgICAgICAgICAgIG9wZW5NZW51KCk7XG4gICAgICAgICAgfTtcblxuICAgIHJldHVybiAoXG4gICAgICAgIDxsaVxuICAgICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWVzKFwibXhfU3BhY2VJdGVtIG14X1NwYWNlSXRlbV9uZXdcIiwge1xuICAgICAgICAgICAgICAgIGNvbGxhcHNlZDogaXNQYW5lbENvbGxhcHNlZCxcbiAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgcm9sZT1cInRyZWVpdGVtXCJcbiAgICAgICAgICAgIGFyaWEtc2VsZWN0ZWQ9e2ZhbHNlfVxuICAgICAgICA+XG4gICAgICAgICAgICA8U3BhY2VCdXR0b25cbiAgICAgICAgICAgICAgICBkYXRhLXRlc3RpZD1cImNyZWF0ZS1zcGFjZS1idXR0b25cIlxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcyhcIm14X1NwYWNlQnV0dG9uX25ld1wiLCB7XG4gICAgICAgICAgICAgICAgICAgIG14X1NwYWNlQnV0dG9uX25ld0NhbmNlbDogbWVudURpc3BsYXllZCxcbiAgICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgICBsYWJlbD17bWVudURpc3BsYXllZCA/IF90KFwiYWN0aW9ufGNhbmNlbFwiKSA6IF90KFwiY3JlYXRlX3NwYWNlfGxhYmVsXCIpfVxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e29uTmV3Q2xpY2t9XG4gICAgICAgICAgICAgICAgaXNOYXJyb3c9e2lzUGFuZWxDb2xsYXBzZWR9XG4gICAgICAgICAgICAgICAgaW5uZXJSZWY9e2hhbmRsZX1cbiAgICAgICAgICAgICAgICBzaXplPVwiMzJweFwiXG4gICAgICAgICAgICAvPlxuXG4gICAgICAgICAgICB7Y29udGV4dE1lbnV9XG4gICAgICAgIDwvbGk+XG4gICAgKTtcbn07XG5cbmNvbnN0IG1ldGFTcGFjZUNvbXBvbmVudE1hcDogUmVjb3JkPE1ldGFTcGFjZSwgdHlwZW9mIEhvbWVCdXR0b24+ID0ge1xuICAgIFtNZXRhU3BhY2UuSG9tZV06IEhvbWVCdXR0b24sXG4gICAgW01ldGFTcGFjZS5GYXZvdXJpdGVzXTogRmF2b3VyaXRlc0J1dHRvbixcbiAgICBbTWV0YVNwYWNlLlBlb3BsZV06IFBlb3BsZUJ1dHRvbixcbiAgICBbTWV0YVNwYWNlLk9ycGhhbnNdOiBPcnBoYW5zQnV0dG9uLFxuICAgIFtNZXRhU3BhY2UuVmlkZW9Sb29tc106IFZpZGVvUm9vbXNCdXR0b24sXG59O1xuXG5pbnRlcmZhY2UgSUlubmVyU3BhY2VQYW5lbFByb3BzIGV4dGVuZHMgRHJvcHBhYmxlUHJvdmlkZWRQcm9wcyB7XG4gICAgY2hpbGRyZW4/OiBSZWFjdE5vZGU7XG4gICAgaXNQYW5lbENvbGxhcHNlZDogYm9vbGVhbjtcbiAgICBzZXRQYW5lbENvbGxhcHNlZDogRGlzcGF0Y2g8U2V0U3RhdGVBY3Rpb248Ym9vbGVhbj4+O1xuICAgIGlzRHJhZ2dpbmdPdmVyOiBib29sZWFuO1xuICAgIGlubmVyUmVmOiBSZWZDYWxsYmFjazxIVE1MRWxlbWVudD47XG59XG5cbi8vIE9wdGltaXNhdGlvbiBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vYXRsYXNzaWFuL3JlYWN0LWJlYXV0aWZ1bC1kbmQvYmxvYi9tYXN0ZXIvZG9jcy9hcGkvZHJvcHBhYmxlLm1kI3JlY29tbWVuZGVkLWRyb3BwYWJsZS0tcGVyZm9ybWFuY2Utb3B0aW1pc2F0aW9uXG5jb25zdCBJbm5lclNwYWNlUGFuZWwgPSBSZWFjdC5tZW1vPElJbm5lclNwYWNlUGFuZWxQcm9wcz4oXG4gICAgKHsgY2hpbGRyZW4sIGlzUGFuZWxDb2xsYXBzZWQsIHNldFBhbmVsQ29sbGFwc2VkLCBpc0RyYWdnaW5nT3ZlciwgaW5uZXJSZWYsIC4uLnByb3BzIH0pID0+IHtcbiAgICAgICAgY29uc3QgW2ludml0ZXMsIG1ldGFTcGFjZXMsIGFjdHVhbFNwYWNlcywgYWN0aXZlU3BhY2VdID0gdXNlU3BhY2VzKCk7XG4gICAgICAgIGNvbnN0IGFjdGl2ZVNwYWNlcyA9IGFjdGl2ZVNwYWNlID8gW2FjdGl2ZVNwYWNlXSA6IFtdO1xuXG4gICAgICAgIGNvbnN0IG1ldGFTcGFjZXNTZWN0aW9uID0gbWV0YVNwYWNlc1xuICAgICAgICAgICAgLmZpbHRlcigoa2V5KSA9PiAhKGtleSA9PT0gTWV0YVNwYWNlLlZpZGVvUm9vbXMgJiYgIVNldHRpbmdzU3RvcmUuZ2V0VmFsdWUoXCJmZWF0dXJlX3ZpZGVvX3Jvb21zXCIpKSlcbiAgICAgICAgICAgIC5tYXAoKGtleSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IENvbXBvbmVudCA9IG1ldGFTcGFjZUNvbXBvbmVudE1hcFtrZXldO1xuICAgICAgICAgICAgICAgIHJldHVybiA8Q29tcG9uZW50IGtleT17a2V5fSBzZWxlY3RlZD17YWN0aXZlU3BhY2UgPT09IGtleX0gaXNQYW5lbENvbGxhcHNlZD17aXNQYW5lbENvbGxhcHNlZH0gLz47XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPEluZGljYXRvclNjcm9sbGJhclxuICAgICAgICAgICAgICAgIHsuLi5wcm9wc31cbiAgICAgICAgICAgICAgICB3cmFwcGVkUmVmPXtpbm5lclJlZn1cbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9TcGFjZVRyZWVMZXZlbFwiXG4gICAgICAgICAgICAgICAgc3R5bGU9e1xuICAgICAgICAgICAgICAgICAgICBpc0RyYWdnaW5nT3ZlclxuICAgICAgICAgICAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludGVyRXZlbnRzOiBcIm5vbmVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxlbWVudD1cInVsXCJcbiAgICAgICAgICAgICAgICByb2xlPVwidHJlZVwiXG4gICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17X3QoXCJjb21tb258c3BhY2VzXCIpfVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHttZXRhU3BhY2VzU2VjdGlvbn1cbiAgICAgICAgICAgICAgICB7aW52aXRlcy5tYXAoKHMpID0+IChcbiAgICAgICAgICAgICAgICAgICAgPFNwYWNlSXRlbVxuICAgICAgICAgICAgICAgICAgICAgICAga2V5PXtzLnJvb21JZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlPXtzfVxuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZlU3BhY2VzPXthY3RpdmVTcGFjZXN9XG4gICAgICAgICAgICAgICAgICAgICAgICBpc1BhbmVsQ29sbGFwc2VkPXtpc1BhbmVsQ29sbGFwc2VkfVxuICAgICAgICAgICAgICAgICAgICAgICAgb25FeHBhbmQ9eygpID0+IHNldFBhbmVsQ29sbGFwc2VkKGZhbHNlKX1cbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICApKX1cbiAgICAgICAgICAgICAgICB7YWN0dWFsU3BhY2VzLm1hcCgocywgaSkgPT4gKFxuICAgICAgICAgICAgICAgICAgICA8RHJhZ2dhYmxlIGtleT17cy5yb29tSWR9IGRyYWdnYWJsZUlkPXtzLnJvb21JZH0gaW5kZXg9e2l9PlxuICAgICAgICAgICAgICAgICAgICAgICAgeyhwcm92aWRlZCwgc25hcHNob3QpID0+IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8U3BhY2VJdGVtXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsuLi5wcm92aWRlZC5kcmFnZ2FibGVQcm9wc31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhZ0hhbmRsZVByb3BzPXtwcm92aWRlZC5kcmFnSGFuZGxlUHJvcHN9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleT17cy5yb29tSWR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlubmVyUmVmPXtwcm92aWRlZC5pbm5lclJlZn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtzbmFwc2hvdC5pc0RyYWdnaW5nID8gXCJteF9TcGFjZUl0ZW1fZHJhZ2dpbmdcIiA6IHVuZGVmaW5lZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhY2U9e3N9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVNwYWNlcz17YWN0aXZlU3BhY2VzfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1BhbmVsQ29sbGFwc2VkPXtpc1BhbmVsQ29sbGFwc2VkfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkV4cGFuZD17KCkgPT4gc2V0UGFuZWxDb2xsYXBzZWQoZmFsc2UpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgICAgICA8L0RyYWdnYWJsZT5cbiAgICAgICAgICAgICAgICApKX1cbiAgICAgICAgICAgICAgICB7Y2hpbGRyZW59XG4gICAgICAgICAgICAgICAge3Nob3VsZFNob3dDb21wb25lbnQoVUlDb21wb25lbnQuQ3JlYXRlU3BhY2VzKSAmJiAoXG4gICAgICAgICAgICAgICAgICAgIDxDcmVhdGVTcGFjZUJ1dHRvbiBpc1BhbmVsQ29sbGFwc2VkPXtpc1BhbmVsQ29sbGFwc2VkfSBzZXRQYW5lbENvbGxhcHNlZD17c2V0UGFuZWxDb2xsYXBzZWR9IC8+XG4gICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDwvSW5kaWNhdG9yU2Nyb2xsYmFyPlxuICAgICAgICApO1xuICAgIH0sXG4pO1xuXG5jb25zdCBTcGFjZVBhbmVsOiBSZWFjdC5GQyA9ICgpID0+IHtcbiAgICBjb25zdCBbZHJhZ2dpbmcsIHNldERyYWdnaW5nXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgICBjb25zdCBbaXNQYW5lbENvbGxhcHNlZCwgc2V0UGFuZWxDb2xsYXBzZWRdID0gdXNlU3RhdGUodHJ1ZSk7XG4gICAgY29uc3QgcmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcbiAgICB1c2VMYXlvdXRFZmZlY3QoKCkgPT4ge1xuICAgICAgICBpZiAocmVmLmN1cnJlbnQpIFVJU3RvcmUuaW5zdGFuY2UudHJhY2tFbGVtZW50RGltZW5zaW9ucyhcIlNwYWNlUGFuZWxcIiwgcmVmLmN1cnJlbnQpO1xuICAgICAgICByZXR1cm4gKCkgPT4gVUlTdG9yZS5pbnN0YW5jZS5zdG9wVHJhY2tpbmdFbGVtZW50RGltZW5zaW9ucyhcIlNwYWNlUGFuZWxcIik7XG4gICAgfSwgW10pO1xuXG4gICAgdXNlRGlzcGF0Y2hlcihkZWZhdWx0RGlzcGF0Y2hlciwgKHBheWxvYWQ6IEFjdGlvblBheWxvYWQpID0+IHtcbiAgICAgICAgaWYgKHBheWxvYWQuYWN0aW9uID09PSBBY3Rpb24uVG9nZ2xlU3BhY2VQYW5lbCkge1xuICAgICAgICAgICAgc2V0UGFuZWxDb2xsYXBzZWQoIWlzUGFuZWxDb2xsYXBzZWQpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8Um92aW5nVGFiSW5kZXhQcm92aWRlciBoYW5kbGVIb21lRW5kIGhhbmRsZVVwRG93bj17IWRyYWdnaW5nfT5cbiAgICAgICAgICAgIHsoeyBvbktleURvd25IYW5kbGVyLCBvbkRyYWdFbmRIYW5kbGVyIH0pID0+IChcbiAgICAgICAgICAgICAgICA8RHJhZ0Ryb3BDb250ZXh0XG4gICAgICAgICAgICAgICAgICAgIG9uRHJhZ1N0YXJ0PXsoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXREcmFnZ2luZyh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgb25EcmFnRW5kPXsocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXREcmFnZ2luZyhmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdC5kZXN0aW5hdGlvbikgcmV0dXJuOyAvLyBkcm9wcGVkIG91dHNpZGUgdGhlIGxpc3RcbiAgICAgICAgICAgICAgICAgICAgICAgIFNwYWNlU3RvcmUuaW5zdGFuY2UubW92ZVJvb3RTcGFjZShyZXN1bHQuc291cmNlLmluZGV4LCByZXN1bHQuZGVzdGluYXRpb24uaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgb25EcmFnRW5kSGFuZGxlcigpO1xuICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPG5hdlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWVzKFwibXhfU3BhY2VQYW5lbFwiLCB7IGNvbGxhcHNlZDogaXNQYW5lbENvbGxhcHNlZCB9KX1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uS2V5RG93bj17KGV2KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF2QWN0aW9uID0gZ2V0S2V5QmluZGluZ3NNYW5hZ2VyKCkuZ2V0TmF2aWdhdGlvbkFjdGlvbihldik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXZBY3Rpb24gPT09IEtleUJpbmRpbmdBY3Rpb24uTmV4dExhbmRtYXJrIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdkFjdGlvbiA9PT0gS2V5QmluZGluZ0FjdGlvbi5QcmV2aW91c0xhbmRtYXJrXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhbmRtYXJrTmF2aWdhdGlvbi5maW5kQW5kRm9jdXNOZXh0TGFuZG1hcmsoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYW5kbWFyay5BQ1RJVkVfU1BBQ0VfQlVUVE9OLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2QWN0aW9uID09PSBLZXlCaW5kaW5nQWN0aW9uLlByZXZpb3VzTGFuZG1hcmssXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uS2V5RG93bkhhbmRsZXIoZXYpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZj17cmVmfVxuICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17X3QoXCJjb21tb258c3BhY2VzXCIpfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8VXNlck1lbnUgaXNQYW5lbENvbGxhcHNlZD17aXNQYW5lbENvbGxhcHNlZH0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWVzKFwibXhfU3BhY2VQYW5lbF90b2dnbGVDb2xsYXBzZVwiLCB7IGV4cGFuZGVkOiAhaXNQYW5lbENvbGxhcHNlZCB9KX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KCkgPT4gc2V0UGFuZWxDb2xsYXBzZWQoIWlzUGFuZWxDb2xsYXBzZWQpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT17aXNQYW5lbENvbGxhcHNlZCA/IF90KFwiYWN0aW9ufGV4cGFuZFwiKSA6IF90KFwiYWN0aW9ufGNvbGxhcHNlXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXB0aW9uPXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxLZXlib2FyZFNob3J0Y3V0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3sgY3RybE9yQ21kS2V5OiB0cnVlLCBzaGlmdEtleTogdHJ1ZSwga2V5OiBcImRcIiB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1NwYWNlUGFuZWxfVG9vbHRpcF9LZXlib2FyZFNob3J0Y3V0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9Vc2VyTWVudT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxEcm9wcGFibGUgZHJvcHBhYmxlSWQ9XCJ0b3AtbGV2ZWwtc3BhY2VzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeyhwcm92aWRlZCwgc25hcHNob3QpID0+IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPElubmVyU3BhY2VQYW5lbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgey4uLnByb3ZpZGVkLmRyb3BwYWJsZVByb3BzfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNQYW5lbENvbGxhcHNlZD17aXNQYW5lbENvbGxhcHNlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFBhbmVsQ29sbGFwc2VkPXtzZXRQYW5lbENvbGxhcHNlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmdPdmVyPXtzbmFwc2hvdC5pc0RyYWdnaW5nT3Zlcn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlubmVyUmVmPXtwcm92aWRlZC5pbm5lclJlZn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3Byb3ZpZGVkLnBsYWNlaG9sZGVyfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L0lubmVyU3BhY2VQYW5lbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9Ecm9wcGFibGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxUaHJlYWRzQWN0aXZpdHlDZW50cmUgZGlzcGxheUJ1dHRvbkxhYmVsPXshaXNQYW5lbENvbGxhcHNlZH0gLz5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPFF1aWNrU2V0dGluZ3NCdXR0b24gaXNQYW5lbENvbGxhcHNlZD17aXNQYW5lbENvbGxhcHNlZH0gLz5cbiAgICAgICAgICAgICAgICAgICAgPC9uYXY+XG4gICAgICAgICAgICAgICAgPC9EcmFnRHJvcENvbnRleHQ+XG4gICAgICAgICAgICApfVxuICAgICAgICA8L1JvdmluZ1RhYkluZGV4UHJvdmlkZXI+XG4gICAgKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNwYWNlUGFuZWw7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQVFBLElBQUFBLE1BQUEsR0FBQUMsdUJBQUEsQ0FBQUMsT0FBQTtBQVlBLElBQUFDLGtCQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxXQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFHQSxJQUFBSSxnQkFBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssWUFBQSxHQUFBTCxPQUFBO0FBQ0EsSUFBQU0sZ0JBQUEsR0FBQUgsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFPLGVBQUEsR0FBQVAsT0FBQTtBQUNBLElBQUFRLGdCQUFBLEdBQUFSLE9BQUE7QUFDQSxJQUFBUyxXQUFBLEdBQUFOLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBVSxPQUFBLEdBQUFWLE9BQUE7QUFTQSxJQUFBVyxlQUFBLEdBQUFYLE9BQUE7QUFDQSxJQUFBWSwyQkFBQSxHQUFBWixPQUFBO0FBS0EsSUFBQWEsb0JBQUEsR0FBQWQsdUJBQUEsQ0FBQUMsT0FBQTtBQUlBLElBQUFjLGNBQUEsR0FBQVgsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFlLGFBQUEsR0FBQWYsT0FBQTtBQUNBLElBQUFnQixRQUFBLEdBQUFiLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBaUIsb0JBQUEsR0FBQWQsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFrQixZQUFBLEdBQUFsQixPQUFBO0FBQ0EsSUFBQW1CLFNBQUEsR0FBQWhCLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBb0IsbUJBQUEsR0FBQWpCLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBcUIsY0FBQSxHQUFBckIsT0FBQTtBQUNBLElBQUFzQixXQUFBLEdBQUFuQixzQkFBQSxDQUFBSCxPQUFBO0FBRUEsSUFBQXVCLFFBQUEsR0FBQXZCLE9BQUE7QUFFQSxJQUFBd0Isa0JBQUEsR0FBQXhCLE9BQUE7QUFDQSxJQUFBeUIsbUJBQUEsR0FBQXpCLE9BQUE7QUFDQSxJQUFBMEIsYUFBQSxHQUFBMUIsT0FBQTtBQUNBLElBQUEyQixVQUFBLEdBQUEzQixPQUFBO0FBQ0EsSUFBQTRCLHNCQUFBLEdBQUE1QixPQUFBO0FBQ0EsSUFBQTZCLGlCQUFBLEdBQUExQixzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQThCLG1CQUFBLEdBQUE5QixPQUFBO0FBQ0EsSUFBQStCLGlCQUFBLEdBQUEvQixPQUFBO0FBQWdFLE1BQUFnQyxTQUFBO0VBQUFDLFVBQUE7RUFBQUMsVUFBQTtBQXBFaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFOQSxTQUFBQyx5QkFBQUMsQ0FBQSw2QkFBQUMsT0FBQSxtQkFBQUMsQ0FBQSxPQUFBRCxPQUFBLElBQUFFLENBQUEsT0FBQUYsT0FBQSxZQUFBRix3QkFBQSxZQUFBQSxDQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBckMsd0JBQUFxQyxDQUFBLEVBQUFFLENBQUEsU0FBQUEsQ0FBQSxJQUFBRixDQUFBLElBQUFBLENBQUEsQ0FBQUksVUFBQSxTQUFBSixDQUFBLGVBQUFBLENBQUEsdUJBQUFBLENBQUEseUJBQUFBLENBQUEsV0FBQUssT0FBQSxFQUFBTCxDQUFBLFFBQUFHLENBQUEsR0FBQUosd0JBQUEsQ0FBQUcsQ0FBQSxPQUFBQyxDQUFBLElBQUFBLENBQUEsQ0FBQUcsR0FBQSxDQUFBTixDQUFBLFVBQUFHLENBQUEsQ0FBQUksR0FBQSxDQUFBUCxDQUFBLE9BQUFRLENBQUEsS0FBQUMsU0FBQSxVQUFBQyxDQUFBLEdBQUFDLE1BQUEsQ0FBQUMsY0FBQSxJQUFBRCxNQUFBLENBQUFFLHdCQUFBLFdBQUFDLENBQUEsSUFBQWQsQ0FBQSxvQkFBQWMsQ0FBQSxPQUFBQyxjQUFBLENBQUFDLElBQUEsQ0FBQWhCLENBQUEsRUFBQWMsQ0FBQSxTQUFBRyxDQUFBLEdBQUFQLENBQUEsR0FBQUMsTUFBQSxDQUFBRSx3QkFBQSxDQUFBYixDQUFBLEVBQUFjLENBQUEsVUFBQUcsQ0FBQSxLQUFBQSxDQUFBLENBQUFWLEdBQUEsSUFBQVUsQ0FBQSxDQUFBQyxHQUFBLElBQUFQLE1BQUEsQ0FBQUMsY0FBQSxDQUFBSixDQUFBLEVBQUFNLENBQUEsRUFBQUcsQ0FBQSxJQUFBVCxDQUFBLENBQUFNLENBQUEsSUFBQWQsQ0FBQSxDQUFBYyxDQUFBLFlBQUFOLENBQUEsQ0FBQUgsT0FBQSxHQUFBTCxDQUFBLEVBQUFHLENBQUEsSUFBQUEsQ0FBQSxDQUFBZSxHQUFBLENBQUFsQixDQUFBLEVBQUFRLENBQUEsR0FBQUEsQ0FBQTtBQXNFQSxNQUFNVyxTQUFTLEdBQUdBLENBQUEsS0FBK0M7RUFDN0QsTUFBTUMsT0FBTyxHQUFHLElBQUFDLHFDQUFvQixFQUFTQyxtQkFBVSxDQUFDQyxRQUFRLEVBQUVDLDZCQUFxQixFQUFFLE1BQU07SUFDM0YsT0FBT0YsbUJBQVUsQ0FBQ0MsUUFBUSxDQUFDRSxhQUFhO0VBQzVDLENBQUMsQ0FBQztFQUNGLE1BQU0sQ0FBQ0MsVUFBVSxFQUFFQyxZQUFZLENBQUMsR0FBRyxJQUFBTixxQ0FBb0IsR