@linid-dm/directory-manager-client-core
Version:
Core package by providing a set of angular components for the Directory Manager app.
410 lines • 68.2 kB
JavaScript
/**
* Copyright (C) 2020-2024 Linagora
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version, provided you comply with the Additional Terms applicable for
* LinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU
* Affero General Public License, subsections (b), (c), and (e), pursuant to
* which these Appropriate Legal Notices must notably (i) retain the display of
* the "LinID™" trademark/logo at the top of the interface window, the display
* of the “You are using the Open Source and free version of LinID™, powered by
* Linagora © 2009–2013. Contribute to LinID R&D by subscribing to an Enterprise
* offer!” infobox and in the e-mails sent with the Program, notice appended to
* any type of outbound messages (e.g. e-mail and meeting requests) as well as
* in the LinID Directory Manager user interface, (ii) retain all hypertext
* links between LinID Directory Manager and https://linid.org/, as well as
* between LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA
* intellectual property rights over its trademarks and commercial brands. Other
* Additional Terms apply, see <http://www.linagora.com/licenses/> for more
* details.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License and
* its applicable Additional Terms for LinID Directory Manager along with this
* program. If not, see <http://www.gnu.org/licenses/> for the GNU Affero
* General Public License version 3 and <http://www.linagora.com/licenses/> for
* the Additional Terms applicable to the LinID Directory Manager software.
*/
import _ from 'lodash';
export function buildTree(dataTree, configs, treeRequestsDetails) {
let dataTreeNode = [];
if (dataTree.allIds.length > 0) {
const treeResourcesTypesEndpoints = treeRequestsDetails.reduce((acc, curr) => ({
...acc,
[curr.resourceTypeId]: curr.endpoint,
}), {});
const treeResourcesNamesModelRef = treeRequestsDetails.reduce((acc, curr) => ({
...acc,
[curr.resourceTypeId]: configs.byId[curr.resourceTypeId].attributes.find((attribute) => attribute.props.isTreeNodeName)?.modelRef,
}), {});
let flattenJsTable = dataTree.allIds.length > 1
? _.flattenDeep(dataTree.allIds.map((resourceTypeId) => dataTree.byId[resourceTypeId].Resources))
: dataTree.byId[dataTree.allIds[0]].Resources;
const nodesByParentId = _.groupBy(flattenJsTable, (node) => node.parentId === undefined || node.meta.topAvailableLevel
? 'root'
: node.parentId);
dataTreeNode =
flattenJsTable.length > 0
? sortDataNodeByName(buildTreeLevel(nodesByParentId, treeResourcesTypesEndpoints, dataTree.allIds, dataTree.allIds[0], treeResourcesNamesModelRef))
: [];
}
return dataTreeNode;
}
export function buildTreeLevel(nodesByParentId, typesEndpoint, allIds, currentResourceTypeId, nameModelRef, parentIdForDisplay = null, parentIds = { id: 'root', externalId: null }, levelForPadding = 0, parentLink = '') {
let childrenType;
if (allIds.length > 1) {
const currentResourceTypeIdIndex = allIds.indexOf(currentResourceTypeId);
childrenType =
currentResourceTypeIdIndex < allIds.length - 1
? allIds[currentResourceTypeIdIndex + 1]
: null;
}
else {
childrenType = currentResourceTypeId;
}
let linkPrefix = parentLink;
if (levelForPadding > 0) {
linkPrefix = linkPrefix.concat('/');
if (allIds.length > 1) {
linkPrefix = linkPrefix.concat(typesEndpoint[currentResourceTypeId], '/');
}
}
return nodesByParentId[parentIds.id].map((data) => {
const link = linkPrefix.concat(encodeURIComponent(data.externalId.toLowerCase()));
return {
ids: { id: data.id, externalId: data.externalId },
name: data[nameModelRef[currentResourceTypeId]],
children: data.id in nodesByParentId
? sortDataNodeByName(buildTreeLevel(nodesByParentId, typesEndpoint, allIds, childrenType, nameModelRef, data.id, { id: data.id, externalId: data.externalId }, levelForPadding + 1, link))
: [],
link,
type: currentResourceTypeId,
canDelete: data.meta.isDeletable,
childrenType: childrenType,
levelForPadding,
parentIdForDisplay,
parentIds,
};
});
}
export function sortDataNodeByName(dataNode) {
return dataNode.sort((nodeA, nodeB) => compareDataNodesNames(nodeA, nodeB));
}
export function compareDataNodesNames(nodeA, nodeB) {
return nodeA.name
.toLocaleUpperCase()
.localeCompare(nodeB.name.toLocaleUpperCase());
}
// TODO need to be adapted for tree with more than two levels
export function cleanAssignDialogTree(dataTree, assignedResourceTypeId) {
return dataTree.filter((node) => !(node.type !== assignedResourceTypeId &&
node.childrenType === assignedResourceTypeId &&
(node.children == null || node.children.length === 0)));
}
export function convertDataNodeToDataItem(node, displayedFieldId) {
return {
ids: node.ids,
name: node[displayedFieldId],
link: node.link,
canDelete: node.canDelete,
};
}
export function getFlattenTreeIds(dataTree) {
return dataTree.reduce((acc, node) => acc.concat(node.ids.id, getFlattenTreeIds(node.children)), []);
}
export function getFlattenTree(dataTree) {
return dataTree.reduce((acc, node) => {
node.children.length > 0
? (acc = acc.concat(node, getFlattenTree(node.children)))
: acc.push(node);
return acc;
}, []);
}
export function getNodeById(id, tree) {
let node = tree.find((node) => node.ids.id.toLocaleUpperCase() === id.toLocaleUpperCase());
for (let i = 0; i < tree.length && node === undefined; i++) {
node = getNodeById(id, tree[i].children);
}
return node;
}
export function addNodeInDataTree(rootNodes, parentNodeId, nodeToAdd) {
if (parentNodeId !== null) {
const parentNode = getNodeById(parentNodeId, rootNodes);
parentNode.children = sortDataNodeByName([
...parentNode.children,
nodeToAdd,
]);
}
else {
rootNodes.push(nodeToAdd);
sortDataNodeByName(rootNodes);
}
}
export function cloneDataTree(dataTree) {
let clonedDataTree = [];
dataTree.forEach((node) => {
node.children = cloneDataTree(node.children);
clonedDataTree.push(deepCopy(node));
});
return clonedDataTree;
}
export function deepCopy(obj) {
let copy;
// Handle the 3 simple types, and null or undefined
if (null == obj || 'object' != typeof obj)
return obj;
// Handle Date
if (obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// Handle Array
if (obj instanceof Array) {
copy = [];
for (let i = 0, len = obj.length; i < len; i++) {
copy[i] = deepCopy(obj[i]);
}
return copy;
}
// Handle Object
if (obj instanceof Object) {
copy = {};
for (let attr in obj) {
if ((Object.prototype.hasOwnProperty.call(obj), attr)) {
copy[attr] = deepCopy(obj[attr]);
}
}
return copy;
}
throw new Error("Unable to copy obj! Its type isn't supported.");
}
export function filterTree(dataTree, allNodesIdsNames, searchFilter, isFilteringOnExternalId = false, isAdvancedSearchActivated, idsMatchingAdvancedSearch) {
const displayedNodesIds = getDisplayedNodesIdsOnFiltering(allNodesIdsNames, searchFilter, isFilteringOnExternalId, isAdvancedSearchActivated, idsMatchingAdvancedSearch);
const displayedNodesIdsExists = _.fromPairs(displayedNodesIds.map((id) => [id, true]));
return filterNodes(dataTree, displayedNodesIdsExists);
}
function filterNodes(dataTree, displayedNodesIdsExists) {
return dataTree
.filter((node) => displayedNodesIdsExists[node.ids.id])
.map((node) => ({
...node,
children: node.children.length > 0
? filterNodes(node.children, displayedNodesIdsExists)
: [],
}));
}
function getDisplayedNodesIdsOnFiltering(allNodesIdsNames, searchFilter, isFilteringOnExternalId = false, isAdvancedSearchActivated = false, idsMatchingAdvancedSearch = {}) {
const allDisplayedNodesIds = [];
const allDisplayedNodesIdsExists = {};
const allNodeById = _.fromPairs(allNodesIdsNames.map((node) => [node.ids.id, node]));
const nodesMatchingSearch = allNodesIdsNames.filter((nodeIds) => isNodeMatchingSearch(searchFilter, nodeIds.name, isFilteringOnExternalId, nodeIds.ids, isAdvancedSearchActivated, idsMatchingAdvancedSearch, false));
nodesMatchingSearch.forEach((node) => {
let currentNode = node;
while (currentNode.parentId !== null &&
allNodeById[currentNode.parentId] !== undefined &&
!allDisplayedNodesIdsExists[currentNode.ids.id]) {
allDisplayedNodesIds.push(currentNode.ids.id);
allDisplayedNodesIdsExists[currentNode.ids.id] = true;
currentNode = allNodeById[currentNode.parentId];
}
if ((currentNode.parentId === null ||
!(allNodeById[currentNode.parentId] !== undefined)) &&
!allDisplayedNodesIdsExists[currentNode.ids.id]) {
allDisplayedNodesIds.push(currentNode.ids.id);
allDisplayedNodesIdsExists[currentNode.ids.id] = true;
}
});
return allDisplayedNodesIds;
}
export function isNodeMatchingSearch(searchValue, nodeName, isFilteringOnExternalId = false, nodeIds = null, isAdvancedSearchActivated = false, idsMatchingAdvancedSearch = {}, checkEmptySearch = true) {
const upperCaseFilter = searchValue
.getRidOfDiacritics()
.toLocaleUpperCase();
const isNameMatchingSearchValue = nodeName
.toLocaleUpperCase()
.getRidOfDiacritics()
.includes(upperCaseFilter);
const isMatchingSearchValue = isFilteringOnExternalId
? isNameMatchingSearchValue ||
nodeIds.externalId
.toLocaleUpperCase()
.getRidOfDiacritics()
.includes(upperCaseFilter)
: isNameMatchingSearchValue;
const isMatchingAdvancedSearch = (isAdvancedSearchActivated && idsMatchingAdvancedSearch[nodeIds.id]) ||
!isAdvancedSearchActivated;
return checkEmptySearch
? (searchValue === '' || isMatchingSearchValue) && isMatchingAdvancedSearch
: isMatchingSearchValue && isMatchingAdvancedSearch;
}
export function getAllChildrenLength(node, expandedNodesIds = null) {
let nbChildren = 0;
if (expandedNodesIds === null || expandedNodesIds.includes(node.ids.id)) {
nbChildren =
node.children.length +
node.children.reduce((acc, curr) => acc + getAllChildrenLength(curr, expandedNodesIds), 0);
}
return nbChildren;
}
export function getFirstDisplayedIndex(flattenDataTreeIds, selectedNodeId, nbMaxDisplayedNodes) {
if (selectedNodeId === null || selectedNodeId === undefined) {
return 0;
}
const index = flattenDataTreeIds.indexOf(selectedNodeId);
const isNodeInFirstBatch = index < nbMaxDisplayedNodes;
return isNodeInFirstBatch ? 0 : index;
}
export function getFlattenDisplayedTreeIds(dataTree, expandedNodesIds) {
return dataTree.reduce((acc, node) => {
node.children.length > 0 && expandedNodesIds.has(node.ids.id)
? (acc = acc.concat(node.ids.id, getFlattenDisplayedTreeIds(node.children, expandedNodesIds)))
: acc.push(node.ids.id);
return acc;
}, []);
}
export function getGreatestNodesMinWidth(nodeWidthMap, currentNodeMaxWidth) {
if (nodeWidthMap.size > 0) {
return Math.max(...nodeWidthMap.values());
}
return currentNodeMaxWidth;
}
export function getSelectedNodes(selectedNodeId, tree, currentNodeUuId = null) {
let selectedNodesId = [];
if (tree.some((child) => child.ids.id === selectedNodeId) &&
!!currentNodeUuId) {
selectedNodesId.push(currentNodeUuId);
}
else {
for (const node of tree) {
selectedNodesId = getSelectedNodes(selectedNodeId, node.children, node.ids.id);
if (selectedNodesId.length > 0) {
return (selectedNodesId = !selectedNodesId.includes(node.ids.id)
? [node.ids.id, ...selectedNodesId]
: selectedNodesId);
}
}
}
return selectedNodesId;
}
export function setNodeIdWidthMap(nodeWidthMap, flattenDataTreeIds, isSelectOnlyModeEnabled) {
[...nodeWidthMap.keys()].forEach((id) => {
if (!flattenDataTreeIds.includes(id)) {
nodeWidthMap.delete(id);
}
});
const allNodesNames = document.getElementsByClassName('data-name');
Array.from(allNodesNames).forEach((nodeName) => {
if (nodeName.id !== '' && flattenDataTreeIds.includes(nodeName.id)) {
const nodeInTemplateId = isSelectOnlyModeEnabled
? 'selected-mode-node-' + nodeName.id
: 'node-' + nodeName.id;
const nodeInTemplate = document.getElementById(nodeInTemplateId);
if (nodeInTemplate) {
nodeWidthMap.set(nodeName.id, getNodeWidth(nodeName.clientWidth, nodeInTemplate));
}
}
});
}
function getNodeWidth(nodeNameWidth, nodeInTemplate) {
const nodePadding = Number(window.getComputedStyle(nodeInTemplate).paddingLeft.replace('px', ''));
let nodeActionButtonsWidth = 0;
const nodeActionButtons = nodeInTemplate.getElementsByClassName('mdc-icon-button');
if (nodeActionButtons.length > 0) {
Array.from(nodeActionButtons).forEach((button) => (nodeActionButtonsWidth += button.clientWidth));
}
let btnNodePadding = 0;
const btnNode = nodeInTemplate.getElementsByClassName('btn-node');
if (btnNode.length > 0) {
Array.from(btnNode).forEach((button) => {
const paddingLeft = Number(window.getComputedStyle(button).paddingLeft.replace('px', ''));
const paddingRight = Number(window.getComputedStyle(button).paddingRight.replace('px', ''));
btnNodePadding = btnNodePadding + paddingLeft + paddingRight;
});
}
return (getMatTreePadding() +
nodePadding +
nodeActionButtonsWidth +
btnNodePadding +
nodeNameWidth);
}
export function getMatTreePadding() {
let matTreePadding = 0;
const matTree = document.getElementsByClassName('gnc-tree');
if (matTree.length > 0) {
const paddingLeft = Number(window.getComputedStyle(matTree.item(0)).paddingLeft.replace('px', ''));
const paddingRight = Number(window.getComputedStyle(matTree.item(0)).paddingRight.replace('px', ''));
matTreePadding = paddingLeft + paddingRight;
}
return matTreePadding;
}
export function updateNodeName(selectedNodeId, dataTree, newNodeName) {
let selectedNode = getNodeById(selectedNodeId, dataTree);
selectedNode.name = newNodeName;
}
export function updateSubTreelinks(nodeId, dataTree, newExternalId = null) {
let node = getNodeById(nodeId, dataTree);
if (newExternalId) {
node.ids.externalId = newExternalId;
updateNodeLink(node, newExternalId);
node = getUpdatedChildrenParentIds(node, newExternalId);
}
else {
let parentNode = getNodeById(node.parentIds.id, dataTree);
updateNodeLinkOnParentChange(node, parentNode);
}
updateChildrenLinks(node);
}
function getUpdatedChildrenParentIds(node, newNodeExternalId) {
return {
...node,
children: node.children.map((childNode) => {
childNode.parentIds.externalId = newNodeExternalId;
return childNode;
}),
};
}
function updateNodeLink(node, newNodeExternalId) {
node.link = node.link.replace(/[^/]+$/g, encodeURIComponent(newNodeExternalId));
}
function updateNodeLinkOnParentChange(node, parentNode) {
const parentLink = parentNode ? parentNode.link.concat('/') : '';
const parentType = parentNode ? parentNode.type : null;
node.link = parentLink.concat(getUrlLastParts(parentType, node));
}
function updateChildrenLinks(node) {
node.children.forEach((childNode) => {
childNode.link = node.link.concat('/', getUrlLastParts(node.type, childNode));
updateChildrenLinks(childNode);
});
}
function getUrlLastParts(parentType, childNode) {
if (parentType === null || parentType === childNode.type) {
return childNode.ids.externalId;
}
else {
const urlLastPartsRegex = new RegExp('[^/]+/[^/]+$', 'g');
return childNode.link.match(urlLastPartsRegex).toString();
}
}
export function getFlattenTreeWithoutTriggeredNodeChildren(dataTree, triggerNodeId) {
return dataTree.reduce((acc, node) => {
if (node.ids.id.toLocaleUpperCase() !== triggerNodeId.toLocaleUpperCase()) {
node.children.length > 0
? (acc = acc.concat(node, getFlattenTreeWithoutTriggeredNodeChildren(node.children, triggerNodeId)))
: acc.push(node);
}
return acc;
}, []);
}
export function getParentNodeId(childNodeId, dataTree) {
const childNode = getNodeById(childNodeId, dataTree);
return !!childNode ? childNode.parentIds.id : 'root';
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS10cmVlLmhlbHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2xpYnMvY2xpZW50LWNvcmUvc3JjL2xpYi9zaGFyZWQvaGVscGVycy9kYXRhLXRyZWUuaGVscGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdDRztBQUVILE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQztBQVl2QixNQUFNLFVBQVUsU0FBUyxDQUN2QixRQUF3QixFQUN4QixPQUF5QixFQUN6QixtQkFBaUQ7SUFFakQsSUFBSSxZQUFZLEdBQWdCLEVBQUUsQ0FBQztJQUNuQyxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQy9CLE1BQU0sMkJBQTJCLEdBRTdCLG1CQUFtQixDQUFDLE1BQU0sQ0FDNUIsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2QsR0FBRyxHQUFHO1lBQ04sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVE7U0FDckMsQ0FBQyxFQUNGLEVBQUUsQ0FDSCxDQUFDO1FBRUYsTUFBTSwwQkFBMEIsR0FFNUIsbUJBQW1CLENBQUMsTUFBTSxDQUM1QixDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDZCxHQUFHLEdBQUc7WUFDTixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUNqQyxJQUFJLENBQUMsY0FBYyxDQUNwQixDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQ2YsQ0FBQyxTQUFxQixFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FDMUQsRUFBRSxRQUFRO1NBQ1osQ0FBQyxFQUNGLEVBQUUsQ0FDSCxDQUFDO1FBRUYsSUFBSSxjQUFjLEdBQ2hCLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7WUFDeEIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQ1gsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQ2pCLENBQUMsY0FBc0IsRUFBRSxFQUFFLENBQ3pCLFFBQVEsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsU0FBUyxDQUMxQyxDQUNGO1lBQ0gsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUVsRCxNQUFNLGVBQWUsR0FFakIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUNyQyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQjtZQUN4RCxDQUFDLENBQUMsTUFBTTtZQUNSLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUNsQixDQUFDO1FBRUYsWUFBWTtZQUNWLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFDdkIsQ0FBQyxDQUFDLGtCQUFrQixDQUNoQixjQUFjLENBQ1osZUFBZSxFQUNmLDJCQUEyQixFQUMzQixRQUFRLENBQUMsTUFBTSxFQUNmLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQ2xCLDBCQUEwQixDQUMzQixDQUNGO2dCQUNILENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDWCxDQUFDO0lBQ0QsT0FBTyxZQUFZLENBQUM7QUFDdEIsQ0FBQztBQUVELE1BQU0sVUFBVSxjQUFjLENBQzVCLGVBQXdDLEVBQ3hDLGFBQXVDLEVBQ3ZDLE1BQWdCLEVBQ2hCLHFCQUE2QixFQUM3QixZQUFzQyxFQUN0QyxrQkFBa0IsR0FBRyxJQUFJLEVBQ3pCLFlBQXVCLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLEVBQ3ZELGVBQWUsR0FBRyxDQUFDLEVBQ25CLFVBQVUsR0FBRyxFQUFFO0lBRWYsSUFBSSxZQUFvQixDQUFDO0lBQ3pCLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN0QixNQUFNLDBCQUEwQixHQUFXLE1BQU0sQ0FBQyxPQUFPLENBQ3ZELHFCQUFxQixDQUN0QixDQUFDO1FBQ0YsWUFBWTtZQUNWLDBCQUEwQixHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFDNUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQywwQkFBMEIsR0FBRyxDQUFDLENBQUM7Z0JBQ3hDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDYixDQUFDO1NBQU0sQ0FBQztRQUNOLFlBQVksR0FBRyxxQkFBcUIsQ0FBQztJQUN2QyxDQUFDO0lBQ0QsSUFBSSxVQUFVLEdBQVcsVUFBVSxDQUFDO0lBQ3BDLElBQUksZUFBZSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3hCLFVBQVUsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3BDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN0QixVQUFVLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMscUJBQXFCLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUM1RSxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sZUFBZSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFTLEVBQUUsRUFBRTtRQUNyRCxNQUFNLElBQUksR0FBVyxVQUFVLENBQUMsTUFBTSxDQUNwQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQ2xELENBQUM7UUFDRixPQUFPO1lBQ0wsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDakQsSUFBSSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUMvQyxRQUFRLEVBQ04sSUFBSSxDQUFDLEVBQUUsSUFBSSxlQUFlO2dCQUN4QixDQUFDLENBQUMsa0JBQWtCLENBQ2hCLGNBQWMsQ0FDWixlQUFlLEVBQ2YsYUFBYSxFQUNiLE1BQU0sRUFDTixZQUFZLEVBQ1osWUFBWSxFQUNaLElBQUksQ0FBQyxFQUFFLEVBQ1AsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUM1QyxlQUFlLEdBQUcsQ0FBQyxFQUNuQixJQUFJLENBQ0wsQ0FDRjtnQkFDSCxDQUFDLENBQUMsRUFBRTtZQUNSLElBQUk7WUFDSixJQUFJLEVBQUUscUJBQXFCO1lBQzNCLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVc7WUFDaEMsWUFBWSxFQUFFLFlBQVk7WUFDMUIsZUFBZTtZQUNmLGtCQUFrQjtZQUNsQixTQUFTO1NBQ1YsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxRQUFxQjtJQUN0RCxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFnQixFQUFFLEtBQWdCLEVBQUUsRUFBRSxDQUMxRCxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQ3BDLENBQUM7QUFDSixDQUFDO0FBRUQsTUFBTSxVQUFVLHFCQUFxQixDQUNuQyxLQUFnQixFQUNoQixLQUFnQjtJQUVoQixPQUFPLEtBQUssQ0FBQyxJQUFJO1NBQ2QsaUJBQWlCLEVBQUU7U0FDbkIsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFRCw2REFBNkQ7QUFDN0QsTUFBTSxVQUFVLHFCQUFxQixDQUNuQyxRQUFxQixFQUNyQixzQkFBOEI7SUFFOUIsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUNwQixDQUFDLElBQWUsRUFBRSxFQUFFLENBQ2xCLENBQUMsQ0FDQyxJQUFJLENBQUMsSUFBSSxLQUFLLHNCQUFzQjtRQUNwQyxJQUFJLENBQUMsWUFBWSxLQUFLLHNCQUFzQjtRQUM1QyxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUN0RCxDQUNKLENBQUM7QUFDSixDQUFDO0FBRUQsTUFBTSxVQUFVLHlCQUF5QixDQUN2QyxJQUFlLEVBQ2YsZ0JBQXdCO0lBRXhCLE9BQU87UUFDTCxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUc7UUFDYixJQUFJLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBQzVCLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtRQUNmLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztLQUMxQixDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxRQUFxQjtJQUNyRCxPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQ3BCLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFDeEUsRUFBRSxDQUNILENBQUM7QUFDSixDQUFDO0FBRUQsTUFBTSxVQUFVLGNBQWMsQ0FBQyxRQUFxQjtJQUNsRCxPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUU7UUFDbkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUN0QixDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ3pELENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25CLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ1QsQ0FBQztBQUVELE1BQU0sVUFBVSxXQUFXLENBQUMsRUFBVSxFQUFFLElBQWlCO0lBQ3ZELElBQUksSUFBSSxHQUFjLElBQUksQ0FBQyxJQUFJLENBQzdCLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxLQUFLLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUNyRSxDQUFDO0lBQ0YsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQzNELElBQUksR0FBRyxXQUFXLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixTQUFzQixFQUN0QixZQUFvQixFQUNwQixTQUFvQjtJQUVwQixJQUFJLFlBQVksS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUMxQixNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3hELFVBQVUsQ0FBQyxRQUFRLEdBQUcsa0JBQWtCLENBQUM7WUFDdkMsR0FBRyxVQUFVLENBQUMsUUFBUTtZQUN0QixTQUFTO1NBQ1YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztTQUFNLENBQUM7UUFDTixTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFCLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxRQUFxQjtJQUNqRCxJQUFJLGNBQWMsR0FBZ0IsRUFBRSxDQUFDO0lBQ3JDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFlLEVBQUUsRUFBRTtRQUNuQyxJQUFJLENBQUMsUUFBUSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0MsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sY0FBYyxDQUFDO0FBQ3hCLENBQUM7QUFFRCxNQUFNLFVBQVUsUUFBUSxDQUFDLEdBQVE7SUFDL0IsSUFBSSxJQUFJLENBQUM7SUFFVCxtREFBbUQ7SUFDbkQsSUFBSSxJQUFJLElBQUksR0FBRyxJQUFJLFFBQVEsSUFBSSxPQUFPLEdBQUc7UUFBRSxPQUFPLEdBQUcsQ0FBQztJQUV0RCxjQUFjO0lBQ2QsSUFBSSxHQUFHLFlBQVksSUFBSSxFQUFFLENBQUM7UUFDeEIsSUFBSSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDbEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUM1QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxlQUFlO0lBQ2YsSUFBSSxHQUFHLFlBQVksS0FBSyxFQUFFLENBQUM7UUFDekIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNWLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsSUFBSSxHQUFHLFlBQVksTUFBTSxFQUFFLENBQUM7UUFDMUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNWLEtBQUssSUFBSSxJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUN0RCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ25DLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO0FBQ25FLENBQUM7QUFFRCxNQUFNLFVBQVUsVUFBVSxDQUN4QixRQUFxQixFQUNyQixnQkFBc0MsRUFDdEMsWUFBb0IsRUFDcEIsdUJBQXVCLEdBQUcsS0FBSyxFQUMvQix5QkFBa0MsRUFDbEMseUJBQWlEO0lBRWpELE1BQU0saUJBQWlCLEdBQWEsK0JBQStCLENBQ2pFLGdCQUFnQixFQUNoQixZQUFZLEVBQ1osdUJBQXVCLEVBQ3ZCLHlCQUF5QixFQUN6Qix5QkFBeUIsQ0FDMUIsQ0FBQztJQUNGLE1BQU0sdUJBQXVCLEdBQTJCLENBQUMsQ0FBQyxTQUFTLENBQ2pFLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FDMUMsQ0FBQztJQUVGLE9BQU8sV0FBVyxDQUFDLFFBQVEsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO0FBQ3hELENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FDbEIsUUFBcUIsRUFDckIsdUJBQStDO0lBRS9DLE9BQU8sUUFBUTtTQUNaLE1BQU0sQ0FBQyxDQUFDLElBQWUsRUFBRSxFQUFFLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUNqRSxHQUFHLENBQUMsQ0FBQyxJQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDekIsR0FBRyxJQUFJO1FBQ1AsUUFBUSxFQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUM7WUFDdEIsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLHVCQUF1QixDQUFDO1lBQ3JELENBQUMsQ0FBQyxFQUFFO0tBQ1QsQ0FBQyxDQUFDLENBQUM7QUFDUixDQUFDO0FBRUQsU0FBUywrQkFBK0IsQ0FDdEMsZ0JBQXNDLEVBQ3RDLFlBQW9CLEVBQ3BCLHVCQUF1QixHQUFHLEtBQUssRUFDL0IseUJBQXlCLEdBQUcsS0FBSyxFQUNqQyw0QkFBb0QsRUFBRTtJQUV0RCxNQUFNLG9CQUFvQixHQUFhLEVBQUUsQ0FBQztJQUMxQyxNQUFNLDBCQUEwQixHQUEyQixFQUFFLENBQUM7SUFDOUQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FDN0IsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQ3BELENBQUM7SUFFRixNQUFNLG1CQUFtQixHQUF5QixnQkFBZ0IsQ0FBQyxNQUFNLENBQ3ZFLENBQUMsT0FBMkIsRUFBRSxFQUFFLENBQzlCLG9CQUFvQixDQUNsQixZQUFZLEVBQ1osT0FBTyxDQUFDLElBQUksRUFDWix1QkFBdUIsRUFDdkIsT0FBTyxDQUFDLEdBQUcsRUFDWCx5QkFBeUIsRUFDekIseUJBQXlCLEVBQ3pCLEtBQUssQ0FDTixDQUNKLENBQUM7SUFFRixtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUF3QixFQUFFLEVBQUU7UUFDdkQsSUFBSSxXQUFXLEdBQXVCLElBQUksQ0FBQztRQUUzQyxPQUNFLFdBQVcsQ0FBQyxRQUFRLEtBQUssSUFBSTtZQUM3QixXQUFXLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxLQUFLLFNBQVM7WUFDL0MsQ0FBQywwQkFBMEIsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUMvQyxDQUFDO1lBQ0Qsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDOUMsMEJBQTBCLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDdEQsV0FBVyxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDbEQsQ0FBQztRQUNELElBQ0UsQ0FBQyxXQUFXLENBQUMsUUFBUSxLQUFLLElBQUk7WUFDNUIsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUM7WUFDckQsQ0FBQywwQkFBMEIsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUMvQyxDQUFDO1lBQ0Qsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDOUMsMEJBQTBCLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDeEQsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxvQkFBb0IsQ0FBQztBQUM5QixDQUFDO0FBRUQsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxXQUFtQixFQUNuQixRQUFnQixFQUNoQix1QkFBdUIsR0FBRyxLQUFLLEVBQy9CLFVBQXFCLElBQUksRUFDekIseUJBQXlCLEdBQUcsS0FBSyxFQUNqQyw0QkFBb0QsRUFBRSxFQUN0RCxnQkFBZ0IsR0FBRyxJQUFJO0lBRXZCLE1BQU0sZUFBZSxHQUFXLFdBQVc7U0FDeEMsa0JBQWtCLEVBQUU7U0FDcEIsaUJBQWlCLEVBQUUsQ0FBQztJQUV2QixNQUFNLHlCQUF5QixHQUFZLFFBQVE7U0FDaEQsaUJBQWlCLEVBQUU7U0FDbkIsa0JBQWtCLEVBQUU7U0FDcEIsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBRTdCLE1BQU0scUJBQXFCLEdBQVksdUJBQXVCO1FBQzVELENBQUMsQ0FBQyx5QkFBeUI7WUFDekIsT0FBTyxDQUFDLFVBQVU7aUJBQ2YsaUJBQWlCLEVBQUU7aUJBQ25CLGtCQUFrQixFQUFFO2lCQUNwQixRQUFRLENBQUMsZUFBZSxDQUFDO1FBQzlCLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQztJQUU5QixNQUFNLHdCQUF3QixHQUM1QixDQUFDLHlCQUF5QixJQUFJLHlCQUF5QixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwRSxDQUFDLHlCQUF5QixDQUFDO0lBRTdCLE9BQU8sZ0JBQWdCO1FBQ3JCLENBQUMsQ0FBQyxDQUFDLFdBQVcsS0FBSyxFQUFFLElBQUkscUJBQXFCLENBQUMsSUFBSSx3QkFBd0I7UUFDM0UsQ0FBQyxDQUFDLHFCQUFxQixJQUFJLHdCQUF3QixDQUFDO0FBQ3hELENBQUM7QUFFRCxNQUFNLFVBQVUsb0JBQW9CLENBQ2xDLElBQWUsRUFDZixtQkFBNkIsSUFBSTtJQUVqQyxJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDbkIsSUFBSSxnQkFBZ0IsS0FBSyxJQUFJLElBQUksZ0JBQWdCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUN4RSxVQUFVO1lBQ1IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNO2dCQUNwQixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FDbEIsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsb0JBQW9CLENBQUMsSUFBSSxFQUFFLGdCQUFnQixDQUFDLEVBQ2pFLENBQUMsQ0FDRixDQUFDO0lBQ04sQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxNQUFNLFVBQVUsc0JBQXNCLENBQ3BDLGtCQUE0QixFQUM1QixjQUFzQixFQUN0QixtQkFBMkI7SUFFM0IsSUFBSSxjQUFjLEtBQUssSUFBSSxJQUFJLGNBQWMsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUM1RCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFDRCxNQUFNLEtBQUssR0FBRyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDekQsTUFBTSxrQkFBa0IsR0FBWSxLQUFLLEdBQUcsbUJBQW1CLENBQUM7SUFDaEUsT0FBTyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7QUFDeEMsQ0FBQztBQUVELE1BQU0sVUFBVSwwQkFBMEIsQ0FDeEMsUUFBcUIsRUFDckIsZ0JBQTZCO0lBRTdCLE9BQU8sUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRTtRQUNuQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksZ0JBQWdCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzNELENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUNmLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUNYLDBCQUEwQixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsZ0JBQWdCLENBQUMsQ0FDNUQsQ0FBQztZQUNKLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDMUIsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDVCxDQUFDO0FBRUQsTUFBTSxVQUFVLHdCQUF3QixDQUN0QyxZQUFpQyxFQUNqQyxtQkFBMkI7SUFFM0IsSUFBSSxZQUFZLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzFCLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFDRCxPQUFPLG1CQUFtQixDQUFDO0FBQzdCLENBQUM7QUFFRCxNQUFNLFVBQVUsZ0JBQWdCLENBQzlCLGNBQXNCLEVBQ3RCLElBQWlCLEVBQ2pCLGtCQUEwQixJQUFJO0lBRTlCLElBQUksZUFBZSxHQUFHLEVBQUUsQ0FBQztJQUN6QixJQUNFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLGNBQWMsQ0FBQztRQUNyRCxDQUFDLENBQUMsZUFBZSxFQUNqQixDQUFDO1FBQ0QsZUFBZSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN4QyxDQUFDO1NBQU0sQ0FBQztRQUNOLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7WUFDeEIsZUFBZSxHQUFHLGdCQUFnQixDQUNoQyxjQUFjLEVBQ2QsSUFBSSxDQUFDLFFBQVEsRUFDYixJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FDWixDQUFDO1lBQ0YsSUFBSSxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMvQixPQUFPLENBQUMsZUFBZSxHQUFHLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDOUQsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxlQUFlLENBQUM7b0JBQ25DLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUN2QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLGVBQWUsQ0FBQztBQUN6QixDQUFDO0FBRUQsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixZQUFpQyxFQUNqQyxrQkFBNEIsRUFDNUIsdUJBQWdDO0lBRWhDLENBQUMsR0FBRyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFVLEVBQUUsRUFBRTtRQUM5QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDckMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxNQUFNLGFBQWEsR0FDakIsUUFBUSxDQUFDLHNCQUFzQixDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQy9DLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBaUIsRUFBRSxFQUFFO1FBQ3RELElBQUksUUFBUSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksa0JBQWtCLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ25FLE1BQU0sZ0JBQWdCLEdBQVcsdUJBQXVCO2dCQUN0RCxDQUFDLENBQUMscUJBQXFCLEdBQUcsUUFBUSxDQUFDLEVBQUU7Z0JBQ3JDLENBQUMsQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUMxQixNQUFNLGNBQWMsR0FBWSxRQUFRLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDMUUsSUFBSSxjQUFjLEVBQUUsQ0FBQztnQkFDbkIsWUFBWSxDQUFDLEdBQUcsQ0FDZCxRQUFRLENBQUMsRUFBRSxFQUNYLFlBQVksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLGNBQWMsQ0FBQyxDQUNuRCxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxTQUFTLFlBQVksQ0FBQyxhQUFxQixFQUFFLGNBQXVCO0lBQ2xFLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FDeEIsTUFBTSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUN0RSxDQUFDO0lBRUYsSUFBSSxzQkFBc0IsR0FBRyxDQUFDLENBQUM7SUFDL0IsTUFBTSxpQkFBaUIsR0FDckIsY0FBYyxDQUFDLHNCQUFzQixDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDM0QsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDakMsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLE9BQU8sQ0FDbkMsQ0FBQyxNQUFlLEVBQUUsRUFBRSxDQUFDLENBQUMsc0JBQXNCLElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUNwRSxDQUFDO0lBQ0osQ0FBQztJQUVELElBQUksY0FBYyxHQUFHLENBQUMsQ0FBQztJQUN2QixNQUFNLE9BQU8sR0FDWCxjQUFjLENBQUMsc0JBQXNCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDcEQsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBZSxFQUFFLEVBQUU7WUFDOUMsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUN4QixNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQzlELENBQUM7WUFDRixNQUFNLFlBQVksR0FBRyxNQUFNLENBQ3pCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FDL0QsQ0FBQztZQUNGLGNBQWMsR0FBRyxjQUFjLEdBQUcsV0FBVyxHQUFHLFlBQVksQ0FBQztRQUMvRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFDRCxPQUFPLENBQ0wsaUJBQWlCLEVBQUU7UUFDbkIsV0FBVztRQUNYLHNCQUFzQjtRQUN0QixjQUFjO1FBQ2QsYUFBYSxDQUNkLENBQUM7QUFDSixDQUFDO0FBRUQsTUFBTSxVQUFVLGlCQUFpQjtJQUMvQixJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUM7SUFDdkIsTUFBTSxPQUFPLEdBQ1gsUUFBUSxDQUFDLHNCQUFzQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzlDLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN2QixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQ3hCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQ3ZFLENBQUM7UUFDRixNQUFNLFlBQVksR0FBRyxNQUFNLENBQ3pCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQ3hFLENBQUM7UUFDRixjQUFjLEdBQUcsV0FBVyxHQUFHLFlBQVksQ0FBQztJQUM5QyxDQUFDO0lBQ0QsT0FBTyxjQUFjLENBQUM7QUFDeEIsQ0FBQztBQUVELE1BQU0sVUFBVSxjQUFjLENBQzVCLGNBQXNCLEVBQ3RCLFFBQXFCLEVBQ3JCLFdBQW1CO0lBRW5CLElBQUksWUFBWSxHQUFjLFdBQVcsQ0FBQyxjQUFjLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDcEUsWUFBWSxDQUFDLElBQUksR0FBRyxXQUFXLENBQUM7QUFDbEMsQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FDaEMsTUFBYyxFQUNkLFFBQXFCLEVBQ3JCLGdCQUF3QixJQUFJO0lBRTVCLElBQUksSUFBSSxHQUFjLFdBQVcsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDcEQsSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsR0FBRyxhQUFhLENBQUM7UUFDcEMsY0FBYyxDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsQ0FBQztRQUNwQyxJQUFJLEdBQUcsMkJBQTJCLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQzFELENBQUM7U0FBTSxDQUFDO1FBQ04sSUFBSSxVQUFVLEdBQWMsV0FBVyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3JFLDRCQUE0QixDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBQ0QsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUIsQ0FBQztBQUVELFNBQVMsMkJBQTJCLENBQ2xDLElBQWUsRUFDZixpQkFBeUI7SUFFekIsT0FBTztRQUNMLEdBQUcsSUFBSTtRQUNQLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQW9CLEVBQUUsRUFBRTtZQUNuRCxTQUFTLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxpQkFBaUIsQ0FBQztZQUNuRCxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDLENBQUM7S0FDSCxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsY0FBYyxDQUFDLElBQWUsRUFBRSxpQkFBeUI7SUFDaEUsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FDM0IsU0FBUyxFQUNULGtCQUFrQixDQUFDLGlCQUFpQixDQUFDLENBQ3RDLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyw0QkFBNEIsQ0FDbkMsSUFBZSxFQUNmLFVBQXFCO0lBRXJCLE1BQU0sVUFBVSxHQUFXLFVBQVUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUN6RSxNQUFNLFVBQVUsR0FBVyxVQUFVLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUMvRCxJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ25FLENBQUM7QUFFRCxTQUFTLG1CQUFtQixDQUFDLElBQWU7SUFDMUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxTQUFvQixFQUFFLEVBQUU7UUFDN0MsU0FBUyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FDL0IsR0FBRyxFQUNILGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUN0QyxDQUFDO1FBQ0YsbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDakMsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsVUFBa0IsRUFBRSxTQUFvQjtJQUMvRCxJQUFJLFVBQVUsS0FBSyxJQUFJLElBQUksVUFBVSxLQUFLLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN6RCxPQUFPLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDO0lBQ2xDLENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxpQkFBaUIsR0FBRyxJQUFJLE1BQU0sQ0FBQyxjQUFjLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDMUQsT0FBTyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzVELENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLDBDQUEwQyxDQUN4RCxRQUFxQixFQUNyQixhQUFxQjtJQUVyQixPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUU7UUFDbkMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxLQUFLLGFBQWEsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLENBQUM7WUFDMUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFDdEIsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQ2YsSUFBSSxFQUNKLDBDQUEwQyxDQUN4QyxJQUFJLENBQUMsUUFBUSxFQUNiLGFBQWEsQ0FDZCxDQUNGLENBQUM7Z0JBQ0osQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckIsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ1QsQ0FBQztBQUVELE1BQU0sVUFBVSxlQUFlLENBQzdCLFdBQW1CLEVBQ25CLFFBQXFCO0lBRXJCLE1BQU0sU0FBUyxHQUFjLFdBQVcsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDaEUsT0FBTyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0FBQ3ZELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoQykgMjAyMC0yMDI0IExpbmFnb3JhXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXJcbiAqIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZVxuICogU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnlcbiAqIGxhdGVyIHZlcnNpb24sIHByb3ZpZGVkIHlvdSBjb21wbHkgd2l0aCB0aGUgQWRkaXRpb25hbCBUZXJtcyBhcHBsaWNhYmxlIGZvclxuICogTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgc29mdHdhcmUgYnkgTElOQUdPUkEgcHVyc3VhbnQgdG8gU2VjdGlvbiA3IG9mIHRoZSBHTlVcbiAqIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLCBzdWJzZWN0aW9ucyAoYiksIChjKSwgYW5kIChlKSwgcHVyc3VhbnQgdG9cbiAqIHdoaWNoIHRoZXNlIEFwcHJvcHJpYXRlIExlZ2FsIE5vdGljZXMgbXVzdCBub3RhYmx5IChpKSByZXRhaW4gdGhlIGRpc3BsYXkgb2ZcbiAqIHRoZSBcIkxpbklE4oSiXCIgdHJhZGVtYXJrL2xvZ28gYXQgdGhlIHRvcCBvZiB0aGUgaW50ZXJmYWNlIHdpbmRvdywgdGhlIGRpc3BsYXlcbiAqIG9mIHRoZSDigJxZb3UgYXJlIHVzaW5nIHRoZSBPcGVuIFNvdXJjZSBhbmQgZnJlZSB2ZXJzaW9uIG9mIExpbklE4oSiLCBwb3dlcmVkIGJ5XG4gKiBMaW5hZ29yYSDCqSAyMDA54oCTMjAxMy4gQ29udHJpYnV0ZSB0byBMaW5JRCBSJkQgYnkgc3Vic2NyaWJpbmcgdG8gYW4gRW50ZXJwcmlzZVxuICogb2ZmZXIh4oCdIGluZm9ib3ggYW5kIGluIHRoZSBlLW1haWxzIHNlbnQgd2l0aCB0aGUgUHJvZ3JhbSwgbm90aWNlIGFwcGVuZGVkIHRvXG4gKiBhbnkgdHlwZSBvZiBvdXRib3VuZCBtZXNzYWdlcyAoZS5nLiBlLW1haWwgYW5kIG1lZXRpbmcgcmVxdWVzdHMpIGFzIHdlbGwgYXNcbiAqIGluIHRoZSBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciB1c2VyIGludGVyZmFjZSwgKGlpKSByZXRhaW4gYWxsIGh5cGVydGV4dFxuICogbGlua3MgYmV0d2VlbiBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBhbmQgaHR0cHM6Ly9saW5pZC5vcmcvLCBhcyB3ZWxsIGFzXG4gKiBiZXR3ZWVuIExJTkFHT1JBIGFuZCBMSU5BR09SQS5jb20sIGFuZCAoaWlpKSByZWZyYWluIGZyb20gaW5mcmluZ2luZyBMSU5BR09SQVxuICogaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBvdmVyIGl0cyB0cmFkZW1hcmtzIGFuZCBjb21tZXJjaWFsIGJyYW5kcy4gT3RoZXJcbiAqIEFkZGl0aW9uYWwgVGVybXMgYXBwbHksIHNlZSA8aHR0cDovL3d3dy5saW5hZ29yYS5jb20vbGljZW5zZXMvPiBmb3IgbW9yZVxuICogZGV0YWlscy5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVRcbiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTXG4gKiBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlXG4gKiBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhbmRcbiAqIGl0cyBhcHBsaWNhYmxlIEFkZGl0aW9uYWwgVGVybXMgZm9yIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIGFsb25nIHdpdGggdGhpc1xuICogcHJvZ3JhbS4gSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+IGZvciB0aGUgR05VIEFmZmVyb1xuICogR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDMgYW5kIDxodHRwOi8vd3d3LmxpbmFnb3JhLmNvbS9saWNlbnNlcy8+IGZvclxuICogdGhlIEFkZGl0aW9uYWwgVGVybXMgYXBwbGljYWJsZSB0byB0aGUgTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgc29mdHdhcmUuXG4gKi9cblxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IElBdHRyaWJ1dGUsIElDb25maWcgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2NvbmZpZ3MuaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIElEYXRhLFxuICBJRGF0YUl0ZW0sXG4gIElEYXRhTm9kZSxcbiAgSURhdGFOb2RlSWRzRmllbGRzLFxuICBJRW50cnlJZHMsXG59IGZyb20gJy4uL2ludGVyZmFjZXMvZGF0YS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgSVJlc291cmNlVHlwZVJlcXVlc3REZXRhaWwgfSBmcm9tICcuLi9pbnRlcmZhY2VzL3Jlc291cmNlcy10eXBlcy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgSnNUYWJsZSB9IGZyb20gJy4vanN0YWJsZS5oZWxwZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRUcmVlKFxuICBkYXRhVHJlZTogSnNUYWJsZTxJRGF0YT4sXG4gIGNvbmZpZ3M6IEpzVGFibGU8SUNvbmZpZz4sXG4gIHRyZWVSZXF1ZXN0c0RldGFpbHM6IElSZXNvdXJjZVR5cGVSZXF1ZXN0RGV0YWlsW11cbikge1xuICBsZXQgZGF0YVRyZWVOb2RlOiBJRGF0YU5vZGVbXSA9IFtdO1xuICBpZiAoZGF0YVRyZWUuYWxsSWRzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCB0cmVlUmVzb3VyY2VzVHlwZXNFbmRwb2ludHM6IHtcbiAgICAgIFtpZDogc3RyaW5nXTogc3RyaW5nO1xuICAgIH0gPSB0cmVlUmVxdWVzdHNEZXRhaWxzLnJlZHVjZShcbiAgICAgIChhY2MsIGN1cnIpID0+ICh7XG4gICAgICAgIC4uLmFjYyxcbiAgICAgICAgW2N1cnIucmVzb3VyY2VUeXBlSWRdOiBjdXJyLmVuZHBvaW50LFxuICAgICAgfSksXG4gICAgICB7fVxuICAgICk7XG5cbiAgICBjb25zdCB0cmVlUmVzb3VyY2VzTmFtZXNNb2RlbFJlZjoge1xuICAgICAgW2lkOiBzdHJpbmddOiBzdHJpbmc7XG4gICAgfSA9IHRyZWVSZXF1ZXN0c0RldGFpbHMucmVkdWNlKFxuICAgICAgKGFjYywgY3VycikgPT4gKHtcbiAgICAgICAgLi4uYWNjLFxuICAgICAgICBbY3Vyci5yZXNvdXJjZVR5cGVJZF06IGNvbmZpZ3MuYnlJZFtcbiAgICAgICAgICBjdXJyLnJlc291cmNlVHlwZUlkXG4gICAgICAgIF0uYXR0cmlidXRlcy5maW5kKFxuICAgICAgICAgIChhdHRyaWJ1dGU6IElBdHRyaWJ1dGUpID0+IGF0dHJpYnV0ZS5wcm9wcy5pc1RyZWVOb2RlTmFtZVxuICAgICAgICApPy5tb2RlbFJlZixcbiAgICAgIH0pLFxuICAgICAge31cbiAgICApO1xuXG4gICAgbGV0IGZsYXR0ZW5Kc1RhYmxlOiBhbnlbXSA9XG4gICAgICBkYXRhVHJlZS5hbGxJZHMubGVuZ3RoID4gMVxuICAgICAgICA/IF8uZmxhdHRlbkRlZXAoXG4gICAgICAgICAgICBkYXRhVHJlZS5hbGxJZHMubWFwKFxuICAgICAgICAgICAgICAocmVzb3VyY2VUeXBlSWQ6IHN0cmluZykgPT5cbiAgICAgICAgICAgICAgICBkYXRhVHJlZS5ieUlkW3Jlc291cmNlVHlwZUlkXS5SZXNvdXJjZXNcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgIDogZGF0YVRyZWUuYnlJZFtkYXRhVHJlZS5hbGxJZHNbMF1dLlJlc291cmNlcztcblxuICAgIGNvbnN0IG5vZGVzQnlQYXJlbnRJZDoge1xuICAgICAgW2lkOiBzdHJpbmddOiBhbnlbXTtcbiAgICB9ID0gXy5ncm91cEJ5KGZsYXR0ZW5Kc1RhYmxlLCAobm9kZSkgPT5cbiAgICAgIG5vZGUucGFyZW50SWQgPT09IHVuZGVmaW5lZCB8fCBub2RlLm1ldGEudG9wQXZhaWxhYmxlTGV2ZWxcbiAgICAgICAgPyAncm9vdCdcbiAgICAgICAgOiBub2RlLnBhcmVudElkXG4gICAgKTtcblxuICAgIGRhdGFUcmVlTm9kZSA9XG4gICAgICBmbGF0dGVuSnNUYWJsZS5sZW5ndGggPiAwXG4gICAgICAgID8gc29ydERhdGFOb2RlQnlOYW1lKFxuICAgICAgICAgICAgYnVpbGRUcmVlTGV2ZWwoXG4gICAgICAgICAgICAgIG5vZGVzQnlQYXJlbnRJZCxcbiAgICAgICAgICAgICAgdHJlZVJlc291cmNlc1R5cGVzRW5kcG9pbnRzLFxuICAgICAgICAgICAgICBkYXRhVHJlZS5hbGxJZHMsXG4gICAgICAgICAgICAgIGRhdGFUcmVlLmFsbElkc1swXSxcbiAgICAgICAgICAgICAgdHJlZVJlc291cmNlc05hbWVzTW9kZWxSZWZcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgIDogW107XG4gIH1cbiAgcmV0dXJuIGRhdGFUcmVlTm9kZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkVHJlZUxldmVsKFxuICBub2Rlc0J5UGFyZW50SWQ6IHsgW2lkOiBzdHJpbmddOiBhbnlbXSB9LFxuICB0eXBlc0VuZHBvaW50OiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0sXG4gIGFsbElkczogc3RyaW5nW10sXG4gIGN1cnJlbnRSZXNvdXJjZVR5cGVJZDogc3RyaW5nLFxuICBuYW1lTW9kZWxSZWY6IHsgW2lkOiBzdHJpbmddOiBzdHJpbmcgfSxcbiAgcGFyZW50SWRGb3JEaXNwbGF5ID0gbnVsbCxcbiAgcGFyZW50SWRzOiBJRW50cnlJZHMgPSB7IGlkOiAncm9vdCcsIGV4dGVybmFsSWQ6IG51bGwgfSxcbiAgbGV2ZWxGb3JQYWRkaW5nID0gMCxcbiAgcGFyZW50TGluayA9ICcnXG4pOiBJRGF0YU5vZGVbXSB7XG4gIGxldCBjaGlsZHJlblR5cGU6IHN0cmluZztcbiAgaWYgKGFsbElkcy5sZW5ndGggPiAxKSB7XG4gICAgY29uc3QgY3VycmVudFJlc291cmNlVHlwZUlkSW5kZXg6IG51bWJlciA9IGFsbElkcy5pbmRleE9mKFxuICAgICAgY3VycmVudFJlc291cmNlVHlwZUlkXG4gICAgKTtcbiAgICBjaGlsZHJlblR5cGUgPVxuICAgICAgY3VycmVudFJlc291cmNlVHlwZUlkSW5kZXggPCBhbGxJZHMubGVuZ3RoIC0gMVxuICAgICAgICA/IGFsbElkc1tjdXJyZW50UmVzb3VyY2VUeXBlSWRJbmRleCArIDFdXG4gICAgICAgIDogbnVsbDtcbiAgfSBlbHNlIHtcbiAgICBjaGlsZHJlblR5cGUgPSBjdXJyZW50UmVzb3VyY2VUeXBlSWQ7XG4gIH1cbiAgbGV0IGxpbmtQcmVmaXg6IHN0cmluZyA9IHBhcmVudExpbms7XG4gIGlmIChsZXZlbEZvclBhZGRpbmcgPiAwKSB7XG4gICAgbGlua1ByZWZpeCA9IGxpbmtQcmVmaXguY29uY2F0KCcvJyk7XG4gICAgaWYgKGFsbElkcy5sZW5ndGggPiAxKSB7XG4gICAgICBsaW5rUHJlZml4ID0gbGlua1ByZWZpeC5jb25jYXQodHlwZXNFbmRwb2ludFtjdXJyZW50UmVzb3VyY2VUeXBlSWRdLCAnLycpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbm9kZXNCeVBhcmVudElkW3BhcmVudElkcy5pZF0ubWFwKChkYXRhOiBhbnkpID0+IHtcbiAgICBjb25zdCBsaW5rOiBzdHJpbmcgPSBsaW5rUHJlZml4LmNvbmNhdChcbiAgICAgIGVuY29kZVVSSUNvbXBvbmVudChkYXRhLmV4dGVybmFsSWQudG9Mb3dlckNhc2UoKSlcbiAgICApO1xuICAgIHJldHVybiB7XG4gICAgICBpZHM6IHsgaWQ6IGRhdGEuaWQsIGV4dGVybmFsSWQ6IGRhdGEuZXh0ZXJuYWxJZCB9LFxuICAgICAgbmFtZTogZGF0YVtuYW1lTW9kZWxSZWZbY3VycmVudFJlc291cmNlVHlwZUlkXV0sXG4gICAgICBjaGlsZHJlbjpcbiAgICAgICAgZGF0YS5pZCBpbiBub2Rlc0J5UGFyZW50SWRcbiAgICAgICAgICA/IHNvcnREYXRhTm9kZUJ5TmFtZShcbiAgICAgICAgICAgICAgYnVpbGRUcmVlTGV2ZWwoXG4gICAgICAgICAgICAgICAgbm9kZXNCeVBhcmVudElkLFxuICAgICAgICAgICAgICAgIHR5cGVzRW5kcG9pbnQsXG4gICAgICAgICAgICAgICAgYWxsSWRzLFxuICAgICAgICAgICAgICAgIGNoaWxkcmVuVHlwZSxcbiAgICAgICAgICAgICAgICBuYW1lTW9kZWxSZWYsXG4gICAgICAgICAgICAgICAgZGF0YS5pZCxcbiAgICAgICAgICAgICAgICB7IGlkOiBkYXRhLmlkLCBleHRlcm5hbElkOiBkYXRhLmV4dGVybmFsSWQgfSxcbiAgICAgICAgICAgICAgICBsZXZlbEZvclBhZGRpbmcgKyAxLFxuICAgICAgICAgICAgICAgIGxpbmtcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogW10sXG4gICAgICBsaW5rLFxuICAgICAgdHlwZTogY3VycmVudFJlc291cmNlVHlwZUlkLFxuICAgICAgY2FuRGVsZXRlOiBkYXRhLm1ldGEuaXNEZWxldGFibGUsXG4gICAgICBjaGlsZHJlblR5cGU6IGNoaWxkcmVuVHlwZSxcbiAgICAgIGxldmVsRm9yUGFkZGluZyxcbiAgICAgIHBhcmVudElkRm9yRGlzcGxheSxcbiAgICAgIHBhcmVudElkcyxcbiAgICB9O1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNvcnREYXRhTm9kZUJ5TmFtZShkYXRhTm9kZTogSURhdGFOb2RlW10pOiBJRGF0YU5vZGVbXSB7XG4gIHJldHVybiBkYXRhTm9kZS5zb3J0KChub2RlQTogSURhdGFOb2RlLCBub2RlQjogSURhdGFOb2RlKSA9PlxuICAgIGNvbXBhcmVEYXRhTm9kZXNOYW1lcyhub2RlQSwgbm9kZUIpXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb21wYXJlRGF0YU5vZGVzTmFtZXMoXG4gIG5vZGVBOiBJRGF0YU5vZGUsXG4gIG5vZGVCOiBJRGF0YU5vZGVcbik6IG51bWJlciB7XG4gIHJldHVybiBub2RlQS5uYW1lXG4gICAgLnRvTG9jYWxlVXBwZXJDYXNlKClcbiAgICAubG9jYWxlQ29tcGFyZShub2RlQi5uYW1lLnRvTG9jYWxlVXBwZXJDYXNlKCkpO1xufVxuXG4vLyBUT0RPIG5lZWQgdG8gYmUgYWRhcHRlZCBmb3IgdHJlZSB3aXRoIG1vcmUgdGhhbiB0d28gbGV2ZWxzXG5leHBvcnQgZnVuY3Rpb24gY2xlYW5Bc3NpZ25EaWFsb2dUcmVlKFxuICBkYXRhVHJlZTogSURhdGFOb2RlW10sXG4gIGFzc2lnbmVkUmVzb3VyY2VUeXBlSWQ6IHN0cmluZ1xuKTogSURhdGFOb2RlW10ge1xuICByZXR1cm4gZGF0YVRyZWUuZmlsdGVyKFxuICAgIChub2RlOiBJRGF0YU5vZGUpID0+XG4gICAgICAhKFxuICAgICAgICBub2RlLnR5cGUgIT09IGFzc2lnbmVkUmVzb3VyY2VUeXBlSWQgJiZcbiAgICAgICAgbm9kZS5jaGlsZHJlblR5cGUgPT09IGFzc2lnbmVkUmVzb3VyY2VUeXBlSWQgJiZcbiAgICAgICAgKG5vZGUuY2hpbGRyZW4gPT0gbnVsbCB8fCBub2RlLmNoaWxkcmVuLmxlbmd0aCA9PT0gMClcbiAgICAgIClcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnREYXRhTm9kZVRvRGF0YUl0ZW0oXG4gIG5vZGU6IElEYXRhTm9kZSxcbiAgZGlzcGxheWVkRmllbGRJZDogc3RyaW5nXG4pOiBJRGF0YUl0ZW0ge1xuICByZXR1cm4ge1xuICAgIGlkczogbm9kZS5pZHMsXG4gICAgbmFtZTogbm9kZVtkaXNwbGF5ZWRGaWVsZElkXSxcbiAgICBsaW5rOiBub2RlLmxpbmssXG4gICAgY2FuRGVsZXRlOiBub2RlLmNhbkRlbGV0ZSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZsYXR0ZW5UcmVlSWRzKGRhdGFUcmVlOiBJRGF0YU5vZGVbXSk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGRhdGFUcmVlLnJlZHVjZShcbiAgICAoYWNjLCBub2RlKSA9PiBhY2MuY29uY2F0KG5vZGUuaWRzLmlkLCBnZXRGbGF0dGVuVHJlZUlkcyhub2RlLmNoaWxkcmVuKSksXG4gICAgW11cbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZsYXR0ZW5UcmVlKGRhdGFUcmVlOiBJRGF0YU5vZGVbXSk6IElEYXRhTm9kZVtdIHtcbiAgcmV0dXJuIGRhdGFUcmVlLnJlZHVjZSgoYWNjLCBub2RlKSA9PiB7XG4gICAgbm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwXG4gICAgICA/IChhY2MgPSBhY2MuY29uY2F0KG5vZGUsIGdldEZsYXR0ZW5UcmVlKG5vZGUuY2hpbGRyZW4pKSlcbiAgICAgIDogYWNjLnB1c2gobm9kZSk7XG4gICAgcmV0dXJuIGFjYztcbiAgfSwgW10pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Tm9kZUJ5SWQoaWQ6IHN0cmluZywgdHJlZTogSURhdGFOb2RlW10pOiBJRGF0YU5vZGUge1xuICBsZXQgbm9kZTogSURhdGFOb2RlID0gdHJlZS5maW5kKFxuICAgIChub2RlKSA9PiBub2RlLmlkcy5pZC50b0xvY2FsZVVwcGVyQ2FzZSgpID09PSBpZC50b0xvY2FsZVVwcGVyQ2FzZSgpXG4gICk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdHJlZS5sZW5ndGggJiYgbm9kZSA9PT0gdW5kZWZpbmVkOyBpKyspIHtcbiAgICBub2RlID0gZ2V0Tm9kZUJ5SWQoaWQsIHRyZWVbaV0uY2hpbGRyZW4pO1xuICB9XG4gIHJldHVybiBub2RlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkTm9kZUluRGF0YVRyZWUoXG4gIHJvb3ROb2RlczogSURhdGFOb2RlW10sXG4gIHBhcmVudE5vZGVJZDogc3RyaW5nLFxuICBub2RlVG9BZGQ6IElEYXRhTm9kZVxuKTogdm9pZCB7XG4gIGlmIChwYXJlbnROb2RlSWQgIT09IG51bGwpIHtcbiAgICBjb25zdCBwYXJlbnROb2RlID0gZ2V0Tm9kZUJ5SWQocGFyZW50Tm9kZUlkLCByb290Tm9kZXMpO1xuICAgIHBhcmVudE5vZGUuY2hpbGRyZW4gPSBzb3J0RGF0YU5vZGVCeU5hbWUoW1xuICAgICAgLi4ucGFyZW50Tm9kZS5jaGlsZHJlbixcbiAgICAgIG5vZGVUb0FkZCxcbiAgICBdKTtcbiAgfSBlbHNlIHtcbiAgICByb290Tm9kZXMucHVzaChub2RlVG9BZGQpO1xuICAgIHNvcnREYXRhTm9kZUJ5TmFtZShyb290Tm9kZXMpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZURhdGFUcmVlKGRhdGFUcmVlOiBJRGF0YU5vZGVbXSk6IElEYXRhTm9kZVtdIHtcbiAgbGV0IGNsb25lZERhdGFUcmVlOiBJRGF0YU5vZGVbXSA9IFtdO1xuICBkYXRhVHJlZS5mb3JFYWNoKChub2RlOiBJRGF0YU5vZGUpID0+IHtcbiAgICBub2RlLmNoaWxkcmVuID0gY2xvbmVEYXRhVHJlZShub2RlLmNoaWxkcmVuKTtcbiAgICBjbG9uZWREYXRhVHJlZS5wdXNoKGRlZXBDb3B5KG5vZGUpKTtcbiAgfSk7XG4gIHJldHVybiBjbG9uZWREYXRhVHJlZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZXBDb3B5KG9iajogYW55KSB7XG4gIGxldCBjb3B5O1xuXG4gIC8vIEhhbmRsZSB0aGUgMyBzaW1wbGUgdHlwZXMsIGFuZCBudWxsIG9yIHVuZGVmaW5lZFxuICBpZiAobnVsbCA9PSBvYmogfHwgJ29iamVjdCcgIT0gdHlwZW9mIG9iaikgcmV0dXJuIG9iajtcblxuICAvLyBIYW5kbGUgRGF0ZVxuICBpZiAob2JqIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIGNvcHkgPSBuZXcgRGF0ZSgpO1xuICAgIGNvcHkuc2V0VGltZShvYmouZ2V0VGltZSgpKTtcbiAgICByZXR1cm4gY29weTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBBcnJheVxuICBpZiAob2JqIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICBjb3B5ID0gW107XG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IG9iai5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgY29weVtpXSA9IGRlZXBDb3B5KG9ialtpXSk7XG4gICAgfVxuICAgIHJldHVybiBjb3B5O1xuICB9XG5cbiAgLy8gSGFuZGxlIE9iamVjdFxuICBpZiAob2JqIGluc3RhbmNlb2YgT2JqZWN0KSB7XG4gICAgY29weSA9IHt9O1xuICAgIGZvciAobGV0IGF0dHIgaW4gb2JqKSB7XG4gICAgICBpZiAoKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmopLCBhdHRyKSkge1xuICAgICAgICBjb3B5W2F0dHJdID0gZGVlcENvcHkob2JqW2F0dHJdKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNvcHk7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXCJVbmFibGUgdG8gY29weSBvYmohIEl0cyB0eXBlIGlzbid0IHN1cHBvcnRlZC5cIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJUcmVlKFxuICBkYXRhVHJlZTogSURhdGFOb2RlW10sXG4gIGFsbE5vZGVzSWRzTmFtZXM6IElEYXRhTm9kZUlkc0ZpZWxkc1tdLFxuICBzZWFyY2hGaWx0ZXI6IHN0cmluZyxcbiAgaXNGaWx0ZXJpbmdPbkV4dGVybmFsSWQgPSBmYWxzZSxcbiAgaXNBZHZhbmNlZFNlYXJjaEFjdGl2YXRlZDogYm9vbGVhbixcbiAgaWRzTWF0Y2hpbmdBZHZhbmNlZFNlYXJjaDogeyBbaWQ6IHN0cmluZ106IHRydWUgfVxuKTogSURhdGFOb2RlW10ge1xuICBjb25zdCBkaXNwbGF5ZWROb2Rlc0lkczogc3RyaW5nW10gPSBnZXREaXNwbGF5ZWROb2Rlc0lkc09uRmlsdGVyaW5nKFxuICAgIGFsbE5vZGVzSWRzTmFtZXMsXG4gICAgc2VhcmNoRmlsdGVyLFxuICAgIGlzRmlsdGVyaW5nT25FeHRlcm5hbElkLFxuICAgIGlzQWR2YW5jZWRTZWFyY2hBY3RpdmF0ZWQsXG4gICAgaWRzTWF0Y2hpbmdBZHZhbmNlZFNlYXJjaFxuICApO1xuICBjb25zdCBkaXNwbGF5ZWROb2Rlc0lkc0V4aXN0czogeyBbaWQ6IHN0cmluZ106IHRydWUgfSA9IF8uZnJvbVBhaXJzKFxuICAgIGRpc3BsYXllZE5vZGVzSWRzLm1hcCgoaWQpID0+IFtpZCwgdHJ1ZV0pXG4gICk7XG5cbiAgcmV0dXJuIGZpbHRlck5vZGVzKGRhdGFUcmVlLCBkaXNwbGF5ZWROb2Rlc0lkc0V4aXN0cyk7XG59XG5cbmZ1bmN0aW9uIGZpbHRlck5vZGVzKFxuICBkYXRhVHJlZTogSURhdGFOb2RlW10sXG4gIGRpc3BsYXllZE5vZGVzSWRzRXhpc3RzOiB7IFtpZDogc3RyaW5nXTogdHJ1ZSB9XG4pOiBJRGF0YU5vZGVbXSB7XG4gIHJldHVybiBkYXRhVHJlZVxuICAgIC5maWx0ZXIoKG5vZGU6IElEYXRhTm9kZSkgPT4gZGlzcGxheWVkTm9kZXNJZHNFeGlzdHNbbm9kZS5pZHMuaWRdKVxuICAgIC5tYXAoKG5vZGU6IElEYXRhTm9kZSkgPT4gKHtcbiAgICAgIC4uLm5vZGUsXG4gICAgICBjaGlsZHJlbjpcbiAgICAgICAgbm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwXG4gICAgICAgICAgPyBmaWx0ZXJOb2Rlcyhub2RlLmNoaWxkcmVuLCBkaXNwbGF5ZWROb2Rlc0lkc0V4aXN0cylcbiAgICAgICAgICA6IFtdLFxuICAgIH0pKTtcbn1cblxuZnVuY3Rpb24gZ2V0RGlzcGxheWVkTm9kZXNJZHNPbkZpbHRlcmluZyhcbiAgYWxsTm9kZXNJZHNOYW1lczogSURhdGFOb2RlSWRzRmllbGRzW10sXG4gIHNlYXJjaEZpbHRlcjogc3RyaW5nLFxuICBpc0ZpbHRlcmluZ09uRXh0ZXJuYWxJZCA9IGZhbHNlLFxuICBpc0FkdmFuY2VkU2VhcmNoQWN0aXZhdGVkID0gZmFsc2UsXG4gIGlkc01hdGNoaW5nQWR2YW5jZWRTZWFyY2g6IHsgW2lkOiBzdHJpbmddOiB0cnVlIH0gPSB7fVxuKTogc3RyaW5nW10ge1xuICBjb25zdCBhbGxEaXNwbGF5ZWROb2Rlc0lkczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgYWxsRGlzcGxheWVkTm9kZXNJZHNFeGlzdHM6IHsgW2lkOiBzdHJpbmddOiB0cnVlIH0gPSB7fTtcbiAgY29uc3QgYWxsTm9kZUJ5SWQgPSBfLmZyb21QYWlycyhcbiAgICBhbGxOb2Rlc0lkc05hbWVzLm1hcCgobm9kZSkgPT4gW25vZGUuaWRzLmlkLCBub2RlXSlcbiAgKTtcblxuICBjb25zdCBub2Rlc01hdGNoaW5nU2VhcmNoOiBJRGF0YU5vZGVJZHNGaWVsZHNbXSA9IGFsbE5vZGVzSWRzTmFtZXMuZmlsdGVyKFxuICAgIChub2RlSWRzOiBJRGF0YU5vZGVJZHNGaWVsZHMpID0+XG4gICAgICBpc05vZGVNYXRjaGluZ1NlYXJjaChcbiAgICAgICAgc2VhcmNoRmlsdGVyLFxuICAgICAgICBub2RlSWRzLm5hbWUsXG4gICAgICAgIGlzRmlsdGVyaW5nT25FeHRlcm5hbElkLFxuICAgICAgICBub2RlSWRzLmlkcyxcbiAgICAgICAgaXNBZHZhbmNlZFNlYXJjaEFjdGl2YXRlZCxcbiAgICAgICAgaWRzTWF0Y2hpbmdBZHZhbmNlZFNlYXJjaCxcbiAgICAgICAgZmFsc2VcbiAgICAgIClcbiAgKTtcblxuICBub2Rlc01hdGNoaW5nU2VhcmNoLmZvckVhY2goKG5vZGU6IElEYXRhTm9kZUlkc0ZpZWxkcykgPT4ge1xuICAgIGxldCBjdXJyZW50Tm9kZTogSURhdGFOb2RlSWRzRmllbGRzID0gbm9kZTtcblxuICAgIHdoaWxlIChcbiAgICAgIGN1cnJlbnROb2RlLnBhcmVudElkICE9PSBudWxsICYmXG4gICAgICBhbGxOb2RlQnlJZFtjdXJyZW50Tm9kZS5wYXJlbnRJZF0gIT09IHVuZGVmaW5lZCAmJlxuICAgICAgIWFsbERpc3BsYXllZE5vZGVzSWRzRXhpc3RzW2N1cnJlbnROb2RlLmlkcy5pZF1cbiAgICApIHtcbiAgICAgIGFsbERpc3BsYXllZE5vZGVzSWRzLnB1c2goY3VycmVudE5vZGUuaWRzLmlkKTtcbiAgICAgIGFsbERpc3BsYXllZE5vZGVzSWRzRXhpc3RzW2N1cnJlbnROb2RlLmlkcy5pZF0gPSB0cnVlO1xuICAgICAgY3VycmVudE5vZGUgPSBhbGxOb2RlQnlJZFtjdXJyZW50Tm9kZS5wYXJlbnRJZF07XG4gICAgfVxuICAgIGlmIChcbiAgICAgIChjdXJyZW50Tm9kZS5wYXJlbnRJZCA9PT0gbnVsbCB8fFxuICAgICAgICAhKGFsbE5vZGVCeUlkW2N1cnJlbnROb2RlLnBhcmVudElkXSAhPT0gdW5kZWZpbmVkKSkgJiZcbiAgICAgICFhbGxEaXNwbGF5ZWROb2Rlc0lkc0V4aXN0c1tjdXJyZW50Tm9kZS5pZHMuaWRdXG4gICAgKSB7XG4gICAgICBhbGxEaXNwbGF5ZWROb2Rlc0lkcy5wdXNoKGN1cnJlbnROb2RlLmlkcy5pZCk7XG4gICAgICBhbGxEaXNwbGF5ZWROb2Rlc0lkc0V4aXN0c1tjdXJyZW50Tm9kZS5pZHMuaWRdID0gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBhbGxEaXNwbGF5ZWROb2Rlc0lkcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTm9kZU1hdGNoaW5nU2VhcmNoKFxuICBzZWFyY2hWYWx1ZTogc3RyaW5nLFxuICBub2RlTmFtZTogc3RyaW5nLFxuICBpc0ZpbHRlcmluZ09uRXh0ZXJuYWxJZCA9IGZhbHNlLFxuICBub2RlSWRzOiBJRW50cnlJZHMgPSBudWxsLFxuICBpc0FkdmFuY2VkU2VhcmNoQWN0aXZhdGVkID0gZmFsc2UsXG4gIGlkc01hdGNoaW5nQWR2YW5jZWRTZWFyY2g6IHsgW2lkOiBzdHJpbmddOiB0cnVlIH0gPSB7fSxcbiAgY2hlY2tFbXB0eVNlYXJjaCA9IHRydWVcbik6IGJvb2xlYW4ge1xuICBjb25zdCB1cHBlckNhc2VGaWx0ZXI6IHN0cmluZyA9IHNlYXJjaFZhbHVlXG4gICAgLmdldFJpZE9mRGlhY3JpdGljcygpXG4gICAgLnRvTG9jYWxlVXBwZXJDYXNlKCk7XG5cbiAgY29uc3QgaXNOYW1lTWF0Y2hpbmdTZWFyY2hWYWx1ZTogYm9vbGVhbiA9IG5vZGVOYW1lXG4gICAgLnRvTG9jYWxlVXBwZXJDYXNlKClcbiAgICAuZ2V0UmlkT2ZEaWFjcml0aWNzKClcbiAgICAuaW5jbHVkZXModXBwZXJDYXNlRmlsdGVyKTtcblxuICBjb25zdCBpc01hdGNoaW5nU2VhcmNoVmFsdWU6IGJvb2xlYW4gPSBpc0ZpbHRlcmluZ09uRXh0ZXJuYWxJZFxuICAgID8gaXNOYW1lTWF0Y2hpbmdTZWFyY2hWYWx1ZSB8fFxuICAgICAgbm9kZUlkcy5leHRlcm5hbElkXG4gICAgICAgIC50b0xvY2FsZVVwcGVyQ2FzZSgpXG4gICAgICAgIC5nZXRSaWRPZkRpYWNyaXRpY3MoKVxuICAgICAgICAuaW5jbHVkZXModXBwZXJDYXNlRmlsdGVyKVxuICAgIDogaXNOYW1lTWF0Y2hpbmdTZWFyY2hWYWx1ZTtcblxuICBjb25zdCBpc01hdGNoaW5nQWR2YW5jZWRTZWFyY2g6IGJvb2xlYW4gPVxuICAgIChpc0FkdmFuY2VkU2VhcmNoQWN0aXZhdGVkICYmIGlkc01hdGNoaW5nQWR2YW5jZWRTZWFyY2hbbm9kZUlkcy5pZF0pIHx8XG4gICAgIWlzQWR2YW5jZWRTZWFyY2hBY3RpdmF0ZWQ7XG5cbiAgcmV0dXJuIGNoZWNrRW1wdHlTZWFyY2hcbiAgICA/IChzZWFyY2hWYWx1ZSA9PT0gJycgfHwgaXNNYXRjaGluZ1NlYXJjaFZhbHVlKSAmJiBpc01hdGNoaW5nQWR2YW5jZWRTZWFyY2hcbiAgICA6IGlzTWF0Y2hpbmdTZWFyY2hWYWx1ZSAmJiBpc01hdGNoaW5nQWR2YW5jZWRTZWFyY2g7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBbGxDaGlsZHJlbkxlbmd0aChcbiAgbm9kZTogSURhdGFOb2RlLFxuICBleHBhbmRlZE5vZGVzSWRzOiBzdHJpbmdbXSA9IG51bGxcbik6IG51bWJlciB7XG4gIGxldCBuYkNoaWxkcmVuID0gMDtcbiAgaWYgKGV4cGFuZGVkTm9kZXNJZHMgPT09IG51bGwgfHwgZXhwYW5kZWROb2Rlc0lkcy5pbmNsdWRlcyhub2RlLmlkcy5pZCkpIHtcbiAgICBuYkNoaWxkcmVuID1cbiAgICAgIG5vZGUuY2hpbGRyZW4ubGVuZ3RoICtcbiAgICAgIG5vZGUuY2hpbGRyZW4ucmVkdWNlKFxuICAgICAgICAoYWNjLCBjdXJyKSA9PiBhY2MgKyBnZXRBbGxDaGlsZHJlbkxlbmd0aChjdXJyLCBleHBhbmRlZE5vZGVzSWRzKSxcbiAgICAgICAgMFxuICAgICAgKTtcbiAgfVxuICByZXR1cm4gbmJDaGlsZHJlbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZpcnN0RGlzcGxheWVkSW5kZXgoXG4gIGZsYXR0ZW5EYXRhVHJlZUlkczogc3RyaW5nW10sXG4gIHNlbGVjdGVkTm9kZUlkOiBzdHJpbmcsXG4gIG5iTWF4RGlzcGxheWVkTm9kZXM6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgaWYgKHNlbGVjdGVkTm9kZUlkID09PSBudWxsIHx8IHNlbGVjdGVkTm9kZUlkID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuICBjb25zdCBpbmRleCA9IGZsYXR0ZW5EYXRhVHJlZUlkcy5pbmRleE9mKHNlbGVjdGVkTm9kZUlkKTtcbiAgY29uc3QgaXNOb2RlSW5GaXJzdEJhdGNoOiBib29sZWFuID0gaW5kZXggPCBuYk1heERpc3BsYXllZE5vZGVzO1xuICByZXR1cm4gaXNOb2RlSW5GaXJzdEJhdGNoID8gMCA6IGluZGV4O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmxhdHRlbkRpc3BsYXllZFRyZWVJZHMoXG4gIGRhdGFUcmVlOiBJRGF0YU5vZGVbXSxcbiAgZXhwYW5kZWROb2Rlc0lkczogU2V0PHN0cmluZz5cbik6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGRhdGFUcmVlLnJlZHVjZSgoYWNjLCBub2RlKSA9PiB7XG4gICAgbm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwICYmIGV4cGFuZGVkTm9kZXNJZHMuaGFzKG5vZGUuaWRzLmlkKVxuICAgICAgPyAoYWNjID0gYWNjLmNvbmNhdChcbiAgICAgICAgICBub2RlLmlkcy5pZCxcbiAgICAgICAgICBnZXRGbGF0dGVuRGlzcGxheWVkVHJlZUlkcyhub2RlLmNoaWxkcmVuLCBleHBhbmRlZE5vZGVzSWRzKVxuICAgICAgICApKVxuICAgICAgOiBhY2MucHVzaChub2RlLmlkcy5pZCk7XG4gICAgcmV0dXJuIGFjYztcbiAgfSwgW10pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0R3JlYXRlc3ROb2Rlc01pbldpZHRoKFxuICBub2RlV2lkdGhNYXA6IE1hcDxzdHJpbmcsIG51bWJlcj4sXG4gIGN1cnJlbnROb2RlTWF4V2lkdGg6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgaWYgKG5vZGVXaWR0aE1hcC5zaXplID4gMCkge1xuICAgIHJldHVybiBNYXRoLm1heCguLi5ub2RlV2lkdGhNYXAudmFsdWVzKCkpO1xuICB9XG4gIHJldHVybiBjdXJyZW50Tm9kZU1heFdpZHRoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VsZWN0ZWROb2RlcyhcbiAgc2VsZWN0ZWROb2RlSWQ6IHN0cmluZyxcbiAgdHJlZTogSURhdGFOb2RlW10sXG4gIGN1cnJlbnROb2RlVXVJZDogc3RyaW5nID0gbnVsbFxuKTogc3RyaW5nW10ge1xuICBsZXQgc2VsZWN0ZWROb2Rlc0lkID0gW107XG4gIGlmIChcbiAgICB0cmVlLnNvbWUoKGNoaWxkKSA9PiBjaGlsZC5pZHMuaWQgPT09IHNlbGVjdGVkTm9kZUlkKSAmJlxuICAgICEhY3VycmVudE5vZGVVdUlkXG4gICkge1xuICAgIHNlbGVjdGVkTm9kZXNJZC5wdXNoKGN1cnJlbnROb2RlVXVJZCk7XG4gIH0gZWxzZSB7XG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRyZWUpIHtcbiAgICAgIHNlbGVjdGVkTm9kZXNJZCA9IGdldFNlbGVjdGVkTm9kZXMoXG4gICAgICAgIHNlbGVjdGVkTm9kZUlkLFxuICAgICAgICBub2RlLmNoaWxkcmVuLFxuICAgICAgICBub2RlLmlkcy5pZFxuICAgICAgKTtcbiAgICAgIGlmIChzZWxlY3RlZE5vZGVzSWQubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gKHNlbGVjdGVkTm9kZXNJZCA9ICFzZWxlY3RlZE5vZGVzSWQuaW5jbHVkZXMobm9kZS5pZHMuaWQpXG4gICAgICAgICAgPyBbbm9kZS5pZHMuaWQsIC4uLnNlbGVjdGVkTm9kZXNJZF1cbiAgICAgICAgICA6IHNlbGVjdGVkTm9kZXNJZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBzZWxlY3RlZE5vZGVzSWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXROb2RlSWRXaWR0aE1hcChcbiAgbm9kZVdpZHRoTWFwOiBNYXA8c3RyaW5nLCBudW1iZXI+LFxuICBmbGF0dGVuRGF0YVRyZWVJZHM6IHN0cmluZ1tdLFxuICBpc1NlbGVjdE9ubHlNb2RlRW5hYmxlZDogYm9vbGVhblxuKTogdm9pZCB7XG4gIFsuLi5ub2RlV2lkdGhNYXAua2V5cygpXS5mb3JFYWNoKChpZDogc3RyaW5nKSA9PiB7XG4gICAgaWYgKCFmbGF0dGVuRGF0YVRyZWVJZHMuaW5jbHVkZXMoaWQpKSB7XG4gICAgICBub2RlV2lkdGhNYXAuZGVsZXRlKGlkKTtcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGFsbE5vZGVzTmFtZXM6IEhUTUxDb2xsZWN0aW9uT2Y8RWxlbWVudD4gPVxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ2RhdGEtbmFtZScpO1xuICBBcnJheS5mcm9tKGFsbE5vZGVzTmFtZXMpLmZvckVhY2goKG5vZGVOYW1lOiBFbGVtZW50KSA9PiB7XG4gICAgaWYgKG5vZGVOYW1lLmlkICE9PSAnJyAmJiBmbGF0dGVuRGF0YVRyZWVJZHMuaW5jbHVkZXMobm9kZU5hbWUuaWQpKSB7XG4gICAgICBjb25zdCBub2RlSW5UZW1wbGF0ZUlkOiBzdHJpbmcgPSBpc1NlbGVjdE9ubHlNb2RlRW5hYmxlZFxuICAgICAgICA/ICdzZWxlY3RlZC1tb2RlLW5vZGUtJyArIG5vZGVOYW1lLmlkXG4gICAgICAgIDogJ25vZGUtJyArIG5vZGVOYW1lLmlkO1xuICAgICAgY29uc3Qgbm9kZUluVGVtcGxhdGU6IEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChub2RlSW5UZW1wbGF0ZUlkKTtcbiAgICAgIGlmIChub2RlSW5UZW1wbGF0ZSkge1xuICAgICAgICBub2RlV2lkdGhNYXAuc2V0KFxuICAgICAgICAgIG5vZGVOYW1lLmlkLFxuICAgICAgICAgIGdldE5vZGVXaWR0aChub2RlTmFtZS5jbGllbnRXaWR0aCwgbm9kZUluVGVtcGxhdGUpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0Tm9kZVdpZHRoKG5vZGVOYW1lV2lkdGg6IG51bWJlciwgbm9kZUluVGVtcGxhdGU6IEVsZW1lbnQpOiBudW1iZXIge1xuICBjb25zdCBub2RlUGFkZGluZyA9IE51bWJlcihcbiAgICB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShub2RlSW5UZW1wbGF0ZSkucGFkZGluZ0xlZnQucmVwbGFjZSgncHgnLCAnJylcbiAgKTtcblxuICBsZXQgbm9kZUFjdGlvbkJ1dHRvbnNXaWR0aCA9IDA7XG4gIGNvbnN0IG5vZGVBY3Rpb25CdXR0b25zOiBIVE1MQ29sbGVjdGlvbk9mPEVsZW1lbnQ+ID1cbiAgICBub2RlSW5UZW1wbGF0ZS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdtZGMtaWNvbi1idXR0b24nKTtcbiAgaWYgKG5vZGVBY3Rpb25CdXR0b25zLmxlbmd0aCA+IDApIHtcbiAgICBBcnJheS5mcm9tKG5vZGVBY3Rpb25CdXR0b25zKS5mb3JFYWNoKFxuICAgICAgKGJ1dHRvbjogRWxlbWVudCkgPT4gKG5vZGVBY3Rpb25CdXR0b25zV2lkdGggKz0gYnV0dG9uLmNsaWVudFdpZHRoKVxuICAgICk7XG4gIH1cblxuICBsZXQgYnRuTm9kZVBhZGRpbmcgPSAwO1xuICBjb25zdCBidG5Ob2RlOiBIVE1MQ29sbGVjdGlvbk9mPEVsZW1lbnQ+ID1cbiAgICBub2RlSW5UZW1wbGF0ZS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdidG4tbm9kZScpO1xuICBpZiAoYnRuTm9kZS5sZW5ndGggPiAwKSB7XG4gICAgQXJyYXkuZnJvbShidG5Ob2RlKS5mb3JFYWNoKChidXR0b246IEVsZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IHBhZGRpbmdMZWZ0ID0gTnVtYmVyKFxuICAgICAgICB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShidXR0b24pLnBhZGRpbmdMZWZ0LnJlcGxhY2UoJ3B4JywgJycpXG4gICAgICApO1xuICAgICAgY29uc3QgcGFkZGluZ1JpZ2h0ID0gTnVtYmVyKFxuICAgICAgICB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShidXR0b24pLnBhZGRpbmdSaWdodC5yZXBsYWNlKCdweCcsICcnKVxuICAgICAgKTtcbiAgICAgIGJ0bk5vZGVQYWRkaW5nID0gYnRuTm9kZVBhZGRpbmcgKyBwYWRkaW5nTGVmdCArIHBhZGRpbmdSaWdodDtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gKFxuICAgIGdldE1hdFRyZWVQYWRkaW5nKCkgK1xuICAgIG5vZGVQYWRkaW5nICtcbiAgICBub2RlQWN0aW9uQnV0dG9uc1dpZHRoICtcbiAgICBidG5Ob2RlUGFkZGluZyArXG4gICAgbm9kZU5hbWVXaWR0aFxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWF0VHJlZVBhZGRpbmcoKTogbnVtYmVyIHtcbiAgbGV0IG1hdFRyZWVQYWRkaW5nID0gMDtcbiAgY29uc3QgbWF0VHJlZTogSFRNTENvbGxlY3Rpb25PZjxFbGVtZW50PiA9XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnZ25jLXRyZWUnKTtcbiAgaWYgKG1hdFRyZWUubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IHBhZGRpbmdMZWZ0ID0gTnVtYmVyKFxuICAgICAgd2luZG93LmdldENvbXB1dGVkU3R5bGUobWF0VHJlZS5pdGVtKDApKS5wYWRkaW5nTGVmdC5yZXBsYWNlKCdweCcsICcnKVxuICAgICk7XG4gICAgY29uc3QgcGFkZGluZ1JpZ2h0ID0gTnVtYmVyKFxuICAgICAgd2luZG93LmdldENvbXB1dGVkU3R5bGUobWF0VHJlZS5pdGVtKDApKS5wYWRkaW5nUmlnaHQucmVwbGFjZSgncHgnLCAnJylcbiAgICApO1xuICAgIG1hdFRyZWVQYWRkaW5nID0gcGFkZGluZ0xlZnQgKyBwYWRkaW5nUmlnaHQ7XG4gIH1cbiAgcmV0dXJuIG1hdFRyZWVQYWRkaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlTm9kZU5hbWUoXG4gIHNlbGVjdGVkTm9kZUlkOiBzdHJpbmcsXG4gIGRhdGFUcmVlOiBJRGF0YU5vZGVbXSxcbiAgbmV3Tm9kZU5hbWU6IHN0cmluZ1xuKTogdm9pZCB7XG4gIGxldCBzZWxlY3RlZE5vZGU6IElEYXRhTm9kZSA9IGdldE5vZGVCeUlkKHNlbGVjdGVkTm9kZUlkLCBkYXRhVHJlZSk7XG4gIHNlbGVjdGVkTm9kZS5uYW1lID0gbmV3Tm9kZU5hbWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVTdWJUcmVlbGlua3MoXG4gIG5vZGVJZDogc3RyaW5nLFxuICBkYXRhVHJlZTogSURhdGFOb2RlW10sXG4gIG5ld0V4dGVybmFsSWQ6IHN0cmluZyA9IG51bGxcbikge1xuICBsZXQgbm9kZTogSURhdGFOb2RlID0gZ2V0Tm9kZUJ5SWQobm9kZUlkLCBkYXRhVHJlZSk7XG4gIGlmIChuZXdFeHRlcm5hbElkKSB7XG4gICAgbm9kZS5pZHMuZXh0ZXJuYWxJZCA9IG5ld0V4dGVybmFsSWQ7XG4gICAgdXBkYXRlTm9kZUxpbmsobm9kZSwgbmV3RXh0ZXJuYWxJZCk7XG4gICAgbm9kZSA9IGdldFVwZGF0ZWRDaGlsZHJlblBhcmVudElkcyhub2RlLCBuZXdFeHRlcm5hbElkKTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgcGFyZW50Tm9kZTogSURhdGFOb2RlID0gZ2V0Tm9kZUJ5SWQobm9kZS5wYXJlbnRJZHMuaWQsIGRhdGFUcmVlKTtcbiAgICB1cGRhdGVOb2RlTGlua09uUGFyZW50Q2hhbmdlKG5vZGUsIHBhcmVudE5vZGUpO1xuICB9XG4gIHVwZGF0ZUNoaWxkcmVuTGlua3Mobm9kZSk7XG59XG5cbmZ1bmN0aW9uIGdldFVwZGF0ZWRDaGlsZHJlblBhcmVudElkcyhcbiAgbm9kZTogSURhdGFOb2RlLFxuICBuZXdOb2RlRXh0ZXJuYWxJZDogc3RyaW5nXG4pOiBJRGF0YU5vZGUge1xuICByZXR1cm4ge1xuICAgIC4uLm5vZGUsXG4gICAgY2hpbGRyZW46IG5vZGUuY2hpbGRyZW4ubWFwKChjaGlsZE5vZGU6IElEYXRhTm9kZSkgPT4ge1xuICAgICAgY2hpbGROb2RlLnBhcmVudElkcy5leHRlcm5hbElkID0gbmV3Tm9kZUV4dGVybmFsSWQ7XG4gICAgICByZXR1cm4gY2hpbGROb2RlO1xuICAgIH0pLFxuICB9O1xufVxuXG5mdW5jdGlvbiB1cGRhdGVOb2RlTGluayhub2RlOiBJRGF0YU5vZGUsIG5ld05vZGVFeHRlcm5hbElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgbm9kZS5saW5rID0gbm9kZS5saW5rLnJlcGxhY2UoXG4gICAgL1teL10rJC9nLFxuICAgIGVuY29kZVVSSUNvbXBvbmVudChuZXdOb2RlRXh0ZXJuYWxJZClcbiAgKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlTm9kZUxpbmtPblBhcmVudENoYW5nZShcbiAgbm9kZTogSURhdGFOb2RlLFxuICBwYXJlbnROb2RlOiBJRGF0YU5vZGVcbik6IHZvaWQge1xuICBjb25zdCBwYXJlbnRMaW5rOiBzdHJpbmcgPSBwYXJlbnROb2RlID8gcGFyZW50Tm9kZS5saW5rLmNvbmNhdCgnLycpIDogJyc7XG4gIGNvbnN0IHBhcmVudFR5cGU6IHN0cmluZyA9IHBhcmVudE5vZGUgPyBwYXJlbnROb2RlLnR5cGUgOiBudWxsO1xuICBub2RlLmxpbmsgPSBwYXJlbnRMaW5rLmNvbmNhdChnZXRVcmxMYXN0UGFydHMocGFyZW50VHlwZSwgbm9kZSkpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVDaGlsZHJlbkxpbmtzKG5vZGU6IElEYXRhTm9kZSk6IHZvaWQge1xuICBub2RlLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkTm9kZTogSURhdGFOb2RlKSA9PiB7XG4gICAgY2hpbGROb2RlLmxpbmsgPSBub2RlLmxpbmsuY29uY2F0KFxuICAgICAgJy8nLFxuICAgICAgZ2V0VXJsTGFzdFBhcnRzKG5vZGUudHlwZSwgY2hpbGROb2RlKVxuICAgICk7XG4gICAgdXBkYXRlQ2hpbGRyZW5MaW5rcyhjaGlsZE5vZGUpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0VXJsTGFzdFBhcnRzKHBhcmVudFR5cGU6IHN0cmluZywgY2hpbGROb2RlOiBJRGF0YU5vZGUpOiBzdHJpbmcge1xuICBpZiAocGFyZW50VHlwZSA9PT0gbnVsbCB8fCBwYXJlbnRUeXBlID09PSBjaGlsZE5vZGUudHlwZSkge1xuICAgIHJldHVybiBjaGlsZE5vZGUuaWRzLmV4dGVybmFsSWQ7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgdXJsTGFzdFBhcnRzUmVnZXggPSBuZXcgUmVnRXhwKCdbXi9dKy9bXi9dKyQnLCAnZycpO1xuICAgIHJldHVybiBjaGlsZE5vZGUubGluay5tYXRjaCh1cmxMYXN0UGFydHNSZWdleCkudG9TdHJpbmcoKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmxhdHRlblRyZWVXaXRob3V0VHJpZ2dlcmVkTm9kZUNoaWxkcmVuKFxuICBkYXRhVHJlZTogSURhdGFOb2RlW10sXG4gIHRyaWdnZXJOb2RlSWQ6IHN0cmluZ1xuKTogSURhdGFOb2RlW10ge1xuICByZXR1cm4gZGF0YVRyZWUucmVkdWNlKChhY2MsIG5vZGUpID0+IHtcbiAgICBpZiAobm9kZS5pZHMuaWQudG9Mb2NhbGVVcHBlckNhc2UoKSAhPT0gdHJpZ2dlck5vZGVJZC50b0xvY2FsZVVwcGVyQ2FzZSgpKSB7XG4gICAgICBub2RlLmNoaWxkcmVuLmxlbmd0aCA+IDBcbiAgICAgICAgPyAoYWNjID0gYWNjLmNvbmNhdChcbiAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICBnZXRGbGF0dGVuVHJlZVdpdGhvdXRUcmlnZ2VyZWROb2RlQ2hpbGRyZW4oXG4gICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4sXG4gICAgICAgICAgICAgIHRyaWdnZXJOb2RlSWRcbiAgICAgICAgICAgIClcbiAgICAgICAgICApKVxuICAgICAgICA6IGFjYy5wdXNoKG5vZGUpO1xuICAgIH1cbiAgICByZXR1cm4gYWNjO1xuICB9LCBbXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYXJlbnROb2RlSWQoXG4gIGNoaWxkTm9kZUlkOiBzdHJpbmcsXG4gIGRhdGFUcmVlOiBJRGF0YU5vZGVbXVxuKTogc3RyaW5nIHtcbiAgY29uc3QgY2hpbGROb2RlOiBJRGF0YU5vZGUgPSBnZXROb2RlQnlJZChjaGlsZE5vZGVJZCwgZGF0YVRyZWUpO1xuICByZXR1cm4gISFjaGlsZE5vZGUgPyBjaGlsZE5vZGUucGFyZW50SWRzLmlkIDogJ3Jvb3QnO1xufVxuIl19