Files
speckle-server/scratch/edge-debug-selection/Default/Cache/Cache_Data/f_000150
T

494 lines
66 KiB
Plaintext

import { sortBy, flatten, isArray, isString, keyBy } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29";
import { isObjectLike } from "/_nuxt/lib/common/helpers/type.ts";
import { ViewerEvent } from "/_nuxt/@fs/D:/speckle-server/packages/viewer/dist/index.js";
import { useEventListener } from "/_nuxt/node_modules/@vueuse/core/index.mjs?v=e4f18c29";
import { ref } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
const HIDDEN_SPECKLE_TYPES = /* @__PURE__ */ new Set([
"Objects.Other",
"ColorProxy",
"InstanceDefinitionProxy",
"GroupProxy",
"RenderMaterialProxy",
"Objects.BuiltElements.Revit.ProjectInfo",
"Objects.BuiltElements.View",
"Objects.BuiltElements.View3D"
]);
const EXCLUDED_COLLECTION_KEYS = /* @__PURE__ */ new Set(["children", "elements"]);
const DISPLAY_VALUE_KEY = "displayValue";
const MAX_EXPANSION_DEPTH = 20;
const STREAMING_TILE_PREFIX = "tiles/tile_";
const IFC_MODEL_GROUP_TYPE = "IFC.Model";
const IFC_TYPE_GROUP_TYPE = "IFC.TypeGroup";
const IFC_ELEMENT_GROUP_TYPE = "IFC.Element";
const TARGET_OBJECT_IDS_KEY = "targetObjectIds";
const ifcStreamingTreeCache = /* @__PURE__ */ new WeakMap();
const isReferencedIdArray = (value) => {
return isArray(value) && value.length > 0 && isObjectLike(value[0]) && "referencedId" in value[0] && isString(value[0].referencedId);
};
const getRecord = (value) => isObjectLike(value) ? value : {};
const getString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
const getNodeRaw = (node) => getRecord(node.raw);
const getNodeObjectId = (node) => {
const raw = getNodeRaw(node);
const userData = getRecord(raw.userData);
return getString(userData.id) || getString(raw.uuid) || getString(raw.id) || getString(node.id) || node.guid;
};
const isStreamingTileNode = (node) => {
const raw = getNodeRaw(node);
return getString(raw.name)?.startsWith(STREAMING_TILE_PREFIX) ?? false;
};
const setTargetObjectIds = (raw, ids) => {
Object.defineProperty(raw, TARGET_OBJECT_IDS_KEY, {
value: ids,
enumerable: false,
configurable: true
});
};
const isIfcVirtualNode = (raw) => {
const speckleType = getString(getRecord(raw).speckle_type);
return speckleType === IFC_MODEL_GROUP_TYPE || speckleType === IFC_TYPE_GROUP_TYPE || speckleType === IFC_ELEMENT_GROUP_TYPE;
};
const buildIfcStreamingTree = (root) => {
if (!Array.isArray(root.children) || !root.children.some(isStreamingTileNode)) {
return null;
}
const cachedTree = ifcStreamingTreeCache.get(root);
if (cachedTree) return cachedTree;
const rootId = getString(root.id) || "ifc-model";
const typeGroups = /* @__PURE__ */ new Map();
for (const tileNode of root.children.filter(isStreamingTileNode)) {
if (!Array.isArray(tileNode.children)) continue;
for (const partNode of tileNode.children) {
const partRaw = getNodeRaw(partNode);
const userData = getRecord(partRaw.userData);
const partId = getNodeObjectId(partNode);
if (!partId) continue;
const ifcType = getString(userData.ifcType) || getString(partRaw.ifcType) || "IFC";
const ifcGuid = getString(userData.ifcGuid) || getString(partRaw.ifcGuid);
const sourceGuid = getString(userData.sourceGuid) || getString(partRaw.sourceGuid);
const ifcName = getString(userData.ifcName) || getString(partRaw.ifcName);
const ifcElementGuid = getString(userData.ifcElementGuid) || getString(partRaw.ifcElementGuid) || ifcGuid;
const ifcElementSourceGuid = getString(userData.ifcElementSourceGuid) || getString(partRaw.ifcElementSourceGuid) || getString(userData.ifcElementAssemblySourceGuid) || getString(partRaw.ifcElementAssemblySourceGuid) || sourceGuid;
const ifcElementType = getString(userData.ifcElementType) || getString(partRaw.ifcElementType) || ifcType;
const ifcElementName = getString(userData.ifcElementName) || getString(partRaw.ifcElementName) || ifcName;
const ifcElementAssemblyGuid = getString(userData.ifcElementAssemblyGuid) || getString(partRaw.ifcElementAssemblyGuid);
const ifcElementAssemblyType = getString(userData.ifcElementAssemblyType) || getString(partRaw.ifcElementAssemblyType);
const ifcElementAssemblyName = getString(userData.ifcElementAssemblyName) || getString(partRaw.ifcElementAssemblyName);
const ifcElementAssemblySourceGuid = getString(userData.ifcElementAssemblySourceGuid) || getString(partRaw.ifcElementAssemblySourceGuid);
const expressId = userData.expressId || partRaw.expressId;
const elementKey = ifcElementSourceGuid || ifcElementGuid || `express-${expressId || partId}`;
const elementDisplayType = ifcType;
const elementDisplayName = ifcName || ifcElementName;
const typeId = `${rootId}:ifc-type:${elementDisplayType}`;
const elementId = `${rootId}:ifc-element:${elementKey}`;
const elementNodeId = ifcElementSourceGuid || ifcElementGuid || elementId;
let typeGroup = typeGroups.get(typeId);
if (!typeGroup) {
typeGroup = {
node: {
raw: {
id: typeId,
name: elementDisplayType,
speckle_type: IFC_TYPE_GROUP_TYPE,
ifcType: elementDisplayType
},
children: []
},
elementGroups: /* @__PURE__ */ new Map(),
partIds: []
};
typeGroups.set(typeId, typeGroup);
}
let elementGroup = typeGroup.elementGroups.get(elementId);
if (!elementGroup) {
const partIds = [];
const raw2 = {
id: elementNodeId,
name: elementDisplayName ? `${elementDisplayType} ${elementDisplayName}` : `${elementDisplayType} ${elementKey}`,
speckle_type: IFC_ELEMENT_GROUP_TYPE,
ifcGuid: ifcElementGuid,
ifcGlobalId: ifcElementGuid,
sourceGuid: ifcElementSourceGuid,
guid: ifcElementSourceGuid || ifcElementGuid,
applicationId: ifcElementSourceGuid || ifcElementGuid,
ifcType: elementDisplayType,
ifcName: elementDisplayName,
ifcPartGuid: ifcGuid,
ifcPartSourceGuid: sourceGuid,
ifcPartType: ifcType,
ifcPartName: ifcName,
ifcElementGuid,
ifcElementSourceGuid,
ifcElementType,
ifcElementName,
ifcElementAssemblyGuid,
ifcElementAssemblyType,
ifcElementAssemblyName,
ifcElementAssemblySourceGuid,
expressId
};
setTargetObjectIds(raw2, partIds);
const newElementGroup = {
node: {
raw: raw2,
children: []
},
partIds
};
typeGroup.elementGroups.set(elementId, newElementGroup);
typeGroup.node.children.push(newElementGroup.node);
elementGroup = newElementGroup;
}
elementGroup.node.children.push(partNode);
elementGroup.partIds.push(partId);
typeGroup.partIds.push(partId);
}
}
if (typeGroups.size === 0) return null;
const typeNodes = Array.from(typeGroups.values()).sort((a, b) => String(a.node.raw?.name).localeCompare(String(b.node.raw?.name))).map((group) => {
setTargetObjectIds(group.node.raw, group.partIds);
group.node.children.sort(
(a, b) => String(a.raw?.name).localeCompare(String(b.raw?.name))
);
return group.node;
});
const rootRaw = getNodeRaw(root);
const raw = {
id: rootId,
name: getString(rootRaw.name) || rootId,
speckle_type: IFC_MODEL_GROUP_TYPE
};
const virtualRoot = {
...root,
raw,
children: typeNodes
};
ifcStreamingTreeCache.set(root, virtualRoot);
return virtualRoot;
};
function createTreeStateManager() {
const flattenedTreeCache = /* @__PURE__ */ new Map();
const lastCacheKey = ref("");
const isInitialized = ref(false);
let viewer = null;
const clearCache = () => {
flattenedTreeCache.clear();
lastCacheKey.value = "";
};
const getCacheKey = (modelsAndVersionIds, expandedModels, expandedNodes, selectedObjects, detachedObjects) => {
const parts = [
modelsAndVersionIds.map(({ model, versionId }) => `${model.id}:${versionId}`).join("|"),
Array.from(expandedModels).sort().join(","),
Array.from(expandedNodes).sort().join(","),
selectedObjects.map((o) => o.id).sort().join(","),
detachedObjects.map((o) => o.objectId).sort().join(",")
];
return parts.join("#");
};
const initialize = (viewerInstance) => {
if (isInitialized.value || !viewerInstance) return;
viewer = viewerInstance;
isInitialized.value = true;
const onLoadComplete = () => clearCache();
viewer.on(ViewerEvent.LoadComplete, onLoadComplete);
if (true) {
useEventListener("beforeunload", () => {
viewer?.removeListener(ViewerEvent.LoadComplete, onLoadComplete);
clearCache();
});
}
};
const getUnifiedVirtualItems = (modelsAndVersionIds, expandedModels, expandedNodes, selectedObjects, worldTree, stateResourceItems, detachedObjects, getRootNodesForModel, flattenModelTree) => {
const cacheKey = getCacheKey(
modelsAndVersionIds,
expandedModels,
expandedNodes,
selectedObjects,
detachedObjects
);
if (lastCacheKey.value === cacheKey && flattenedTreeCache.has(cacheKey)) {
return flattenedTreeCache.get(cacheKey);
}
const result = [];
modelsAndVersionIds.forEach(({ model, versionId }, index) => {
result.push({
type: "model-header",
id: `model-${model.id}`,
modelId: model.id,
data: { model, versionId },
isFirstModel: index === 0
});
if (expandedModels.has(model.id)) {
const modelRootNodes = getRootNodesForModel(
model.id,
worldTree,
stateResourceItems,
modelsAndVersionIds
);
if (modelRootNodes.length > 0) {
const treeItems = flattenModelTree(
modelRootNodes,
model.id,
expandedNodes,
selectedObjects
);
if (treeItems.length > 0) {
treeItems[0].isFirstChildOfModel = true;
treeItems[treeItems.length - 1].isLastChildOfModel = true;
result.push(...treeItems);
}
}
}
});
detachedObjects.forEach((detachedObject, index) => {
const objectId = detachedObject.objectId;
const isFirstDetachedObject = index === 0 && modelsAndVersionIds.length === 0;
result.push({
type: "detached-object-header",
id: `detached-${objectId}`,
modelId: objectId,
// Use objectId as modelId for detached objects
data: { objectId },
isFirstModel: isFirstDetachedObject
});
if (expandedModels.has(objectId)) {
const detachedRootNodes = getRootNodesForModel(
objectId,
worldTree,
stateResourceItems,
modelsAndVersionIds
);
if (detachedRootNodes.length > 0) {
const treeItems = flattenModelTree(
detachedRootNodes,
objectId,
expandedNodes,
selectedObjects
);
if (treeItems.length > 0) {
treeItems[0].isFirstChildOfModel = true;
treeItems[treeItems.length - 1].isLastChildOfModel = true;
result.push(...treeItems);
}
}
}
});
flattenedTreeCache.set(cacheKey, result);
lastCacheKey.value = cacheKey;
return result;
};
return {
initialize,
getUnifiedVirtualItems,
clearCache
};
}
const treeStateManager = createTreeStateManager();
export function useTreeManagement() {
const typeCheckCache = /* @__PURE__ */ new Map();
const isAllowedType = (node) => {
const speckleType = node.raw?.speckle_type || "";
if (!speckleType) return true;
if (typeCheckCache.has(speckleType)) {
return typeCheckCache.get(speckleType);
}
const isAllowed = !Array.from(HIDDEN_SPECKLE_TYPES).some(
(substring) => speckleType.includes(substring)
);
if (typeCheckCache.size < 1e3) {
typeCheckCache.set(speckleType, isAllowed);
}
return isAllowed;
};
const flattenModelTree = (nodes, modelId, expandedNodes, selectedObjects, indent = 0, isDescendantOfSelected = false) => {
const result = [];
const selectedObjectIds = new Set(selectedObjects.map((obj) => obj.id));
for (const node of nodes) {
const nodeId = node.raw?.id || node.guid || "";
if (!nodeId) continue;
const speckleData = node.raw;
const isNodeSelected = selectedObjectIds.has(nodeId);
const shouldMarkDescendantsAsSelected = isDescendantOfSelected || isNodeSelected;
const isNonEmptyArray = (x) => !!x && Array.isArray(x) && x.length > 0;
const isNonEmptyObjectArray = (x) => isNonEmptyArray(x) && typeof x[0] === "object" && !Array.isArray(x[0]) && x[0] !== null;
const isSingleCollection = isNonEmptyObjectArray(speckleData?.children) || isNonEmptyObjectArray(speckleData?.elements) || isIfcVirtualNode(speckleData) && Array.isArray(node.children) && node.children.length > 0;
const arrayCollections = [];
if (speckleData) {
Object.entries(speckleData).forEach(([k, val]) => {
if (EXCLUDED_COLLECTION_KEYS.has(k) || k.includes(DISPLAY_VALUE_KEY))
return;
if (!isReferencedIdArray(val)) return;
const ids = new Set(val.map((ref2) => ref2.referencedId));
const actualRawRefs = node.children?.filter((childNode) => {
const childId = childNode.raw?.id;
return ids.has(childId) && isAllowedType(childNode);
}) || [];
if (actualRawRefs.length > 0) {
arrayCollections.push({
raw: {
name: k,
id: k,
speckle_type: "Array Collection",
// eslint-disable-line camelcase
children: val
},
children: actualRawRefs
});
}
});
}
const isMultipleCollection = arrayCollections.length > 0;
const hasChildren = isSingleCollection || isMultipleCollection;
const isExpanded = hasChildren && expandedNodes.has(nodeId);
result.push({
type: "tree-item",
id: nodeId,
modelId,
data: node,
indent,
hasChildren,
isExpanded,
isDescendantOfSelected
});
if (isExpanded) {
if (isMultipleCollection) {
result.push(
...flattenModelTree(
arrayCollections,
modelId,
expandedNodes,
selectedObjects,
indent + 1,
shouldMarkDescendantsAsSelected
)
);
}
if (isSingleCollection) {
const treeItems = node.children?.filter((child) => !!child.raw?.id && isAllowedType(child)) || [];
let filteredItems = treeItems;
if (isReferencedIdArray(speckleData?.elements) && speckleData?.atomic === true) {
const elementIds = new Set(
speckleData.elements.map((obj) => obj.referencedId)
);
filteredItems = treeItems.filter(
(item) => elementIds.has(item.raw?.id)
);
}
result.push(
...flattenModelTree(
filteredItems,
modelId,
expandedNodes,
selectedObjects,
indent + 1,
shouldMarkDescendantsAsSelected
)
);
}
}
}
return result;
};
const getRootNodesForModel = (modelId, worldTree, stateResourceItems, modelsAndVersionIds) => {
if (!worldTree) return [];
const resourceItemsMap = keyBy(
stateResourceItems.map((item, index) => ({ ...item, index })),
"objectId"
);
const modelsMap = keyBy(
modelsAndVersionIds.map(({ model }) => model),
"id"
);
const rootNodes = worldTree._root.children;
const results = {};
const unmatchedNodes = [];
rootNodes.forEach((node) => {
const objectId = node.model.id.split("/").reverse()[0];
const resourceData = resourceItemsMap[objectId];
const resourceItem = resourceData;
const resourceItemIdx = resourceData?.index ?? -1;
const raw = node.model?.raw;
if (resourceItem?.modelId) {
const model = modelsMap[resourceItem.modelId];
raw.name = model?.name;
raw.type = model?.id;
if (resourceItem.modelId === modelId) {
const res = buildIfcStreamingTree(node.model) || node.model;
if (resourceItemIdx !== -1) {
;
(results[resourceItemIdx] = results[resourceItemIdx] || []).push(res);
} else {
unmatchedNodes.push(res);
}
}
} else {
Object.assign(raw, { name: "Object", type: "Single object" });
if (resourceItem && resourceItem.objectId === modelId) {
unmatchedNodes.push(
buildIfcStreamingTree(node.model) || node.model
);
}
}
});
return [
...flatten(
sortBy(Object.entries(results), ([index]) => Number(index)).map(
([, nodes]) => nodes
)
),
...unmatchedNodes
];
};
const findObjectInNodes = (nodes, objectId) => {
return nodes.some(
(node) => node.raw?.id === objectId || node.children?.length && findObjectInNodes(node.children, objectId)
);
};
const expandNodesToShowObject = (nodes, objectId, modelId, expandedNodes, depth = 0) => {
if (!nodes?.length || depth > MAX_EXPANSION_DEPTH)
return { found: false, nodesToExpand: [] };
const nodesToExpand = [];
const found = nodes.some((node) => {
if (node.raw?.id === objectId) return true;
if (node.children?.length) {
const result = expandNodesToShowObject(
node.children,
objectId,
modelId,
expandedNodes,
depth + 1
);
if (result.found) {
if (node.raw?.id) nodesToExpand.push(node.raw.id);
nodesToExpand.push(...result.nodesToExpand);
const speckleData = node.raw;
if (speckleData) {
Object.entries(speckleData).forEach(([k, val]) => {
if (EXCLUDED_COLLECTION_KEYS.has(k) || k.includes(DISPLAY_VALUE_KEY))
return;
if (isReferencedIdArray(val)) {
const ids = new Set(val.map((ref2) => ref2.referencedId));
if (node.children?.some((child) => ids.has(child.raw?.id))) {
nodesToExpand.push(k);
}
}
});
}
return true;
}
}
return false;
});
return { found, nodesToExpand };
};
return {
flattenModelTree,
getRootNodesForModel,
findObjectInNodes,
expandNodesToShowObject,
treeStateManager
};
}
//# sourceMappingURL=data:application/json;base64,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W10sInNvdXJjZXMiOlsidHJlZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEV4cGxvcmVyTm9kZSwgU3BlY2tsZU9iamVjdCB9IGZyb20gJ35+L2xpYi92aWV3ZXIvaGVscGVycy9zY2VuZUV4cGxvcmVyJ1xuaW1wb3J0IHR5cGUgeyBWaWV3ZXJMb2FkZWRSZXNvdXJjZXNRdWVyeSB9IGZyb20gJ35+L2xpYi9jb21tb24vZ2VuZXJhdGVkL2dxbC9ncmFwaHFsJ1xyXG5pbXBvcnQgdHlwZSB7IEdldCB9IGZyb20gJ3R5cGUtZmVzdCdcclxuaW1wb3J0IHR5cGUgeyBXb3JsZFRyZWUsIFZpZXdlckV2ZW50UGF5bG9hZCB9IGZyb20gJ0BzcGVja2xlL3ZpZXdlcidcclxuaW1wb3J0IHsgc29ydEJ5LCBmbGF0dGVuLCBpc0FycmF5LCBpc1N0cmluZywga2V5QnkgfSBmcm9tICdsb2Rhc2gtZXMnXHJcbmltcG9ydCB7IGlzT2JqZWN0TGlrZSB9IGZyb20gJ34vbGliL2NvbW1vbi9oZWxwZXJzL3R5cGUnXHJcbmltcG9ydCB7IFZpZXdlckV2ZW50IH0gZnJvbSAnQHNwZWNrbGUvdmlld2VyJ1xyXG5pbXBvcnQgeyB1c2VFdmVudExpc3RlbmVyIH0gZnJvbSAnQHZ1ZXVzZS9jb3JlJ1xyXG5cclxudHlwZSBNb2RlbEl0ZW0gPSBOb25OdWxsYWJsZTxHZXQ8Vmlld2VyTG9hZGVkUmVzb3VyY2VzUXVlcnksICdwcm9qZWN0Lm1vZGVscy5pdGVtc1swXSc+PlxyXG50eXBlIE1vZGVsV2l0aFZlcnNpb24gPSB7IG1vZGVsOiBNb2RlbEl0ZW07IHZlcnNpb25JZDogc3RyaW5nIH1cclxuXHJcbmNvbnN0IEhJRERFTl9TUEVDS0xFX1RZUEVTID0gbmV3IFNldChbXHJcbiAgJ09iamVjdHMuT3RoZXInLFxyXG4gICdDb2xvclByb3h5JyxcclxuICAnSW5zdGFuY2VEZWZpbml0aW9uUHJveHknLFxyXG4gICdHcm91cFByb3h5JyxcclxuICAnUmVuZGVyTWF0ZXJpYWxQcm94eScsXHJcbiAgJ09iamVjdHMuQnVpbHRFbGVtZW50cy5SZXZpdC5Qcm9qZWN0SW5mbycsXHJcbiAgJ09iamVjdHMuQnVpbHRFbGVtZW50cy5WaWV3JyxcclxuICAnT2JqZWN0cy5CdWlsdEVsZW1lbnRzLlZpZXczRCdcclxuXSBhcyBjb25zdClcclxuXHJcbmNvbnN0IEVYQ0xVREVEX0NPTExFQ1RJT05fS0VZUyA9IG5ldyBTZXQoWydjaGlsZHJlbicsICdlbGVtZW50cyddIGFzIGNvbnN0KVxuY29uc3QgRElTUExBWV9WQUxVRV9LRVkgPSAnZGlzcGxheVZhbHVlJ1xuY29uc3QgTUFYX0VYUEFOU0lPTl9ERVBUSCA9IDIwXG5jb25zdCBTVFJFQU1JTkdfVElMRV9QUkVGSVggPSAndGlsZXMvdGlsZV8nXG5jb25zdCBJRkNfTU9ERUxfR1JPVVBfVFlQRSA9ICdJRkMuTW9kZWwnXG5jb25zdCBJRkNfVFlQRV9HUk9VUF9UWVBFID0gJ0lGQy5UeXBlR3JvdXAnXG5jb25zdCBJRkNfRUxFTUVOVF9HUk9VUF9UWVBFID0gJ0lGQy5FbGVtZW50J1xuY29uc3QgVEFSR0VUX09CSkVDVF9JRFNfS0VZID0gJ3RhcmdldE9iamVjdElkcydcbmNvbnN0IGlmY1N0cmVhbWluZ1RyZWVDYWNoZSA9IG5ldyBXZWFrTWFwPG9iamVjdCwgRXhwbG9yZXJOb2RlPigpXG5cclxuY29uc3QgaXNSZWZlcmVuY2VkSWRBcnJheSA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIHsgcmVmZXJlbmNlZElkOiBzdHJpbmcgfVtdID0+IHtcbiAgcmV0dXJuIChcclxuICAgIGlzQXJyYXkodmFsdWUpICYmXHJcbiAgICB2YWx1ZS5sZW5ndGggPiAwICYmXHJcbiAgICBpc09iamVjdExpa2UodmFsdWVbMF0pICYmXHJcbiAgICAncmVmZXJlbmNlZElkJyBpbiB2YWx1ZVswXSAmJlxyXG4gICAgaXNTdHJpbmcodmFsdWVbMF0ucmVmZXJlbmNlZElkKVxyXG4gIClcbn1cblxuY29uc3QgZ2V0UmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT5cbiAgaXNPYmplY3RMaWtlKHZhbHVlKSA/ICh2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgOiB7fVxuXG5jb25zdCBnZXRTdHJpbmcgPSAodmFsdWU6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQgPT5cbiAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5sZW5ndGggPiAwID8gdmFsdWUgOiB1bmRlZmluZWRcblxuY29uc3QgZ2V0Tm9kZVJhdyA9IChub2RlOiBFeHBsb3Jlck5vZGUpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PlxuICBnZXRSZWNvcmQobm9kZS5yYXcpXG5cbmNvbnN0IGdldE5vZGVPYmplY3RJZCA9IChub2RlOiBFeHBsb3Jlck5vZGUpOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuICBjb25zdCByYXcgPSBnZXROb2RlUmF3KG5vZGUpXG4gIGNvbnN0IHVzZXJEYXRhID0gZ2V0UmVjb3JkKHJhdy51c2VyRGF0YSlcbiAgcmV0dXJuIChcbiAgICBnZXRTdHJpbmcodXNlckRhdGEuaWQpIHx8XG4gICAgZ2V0U3RyaW5nKHJhdy51dWlkKSB8fFxuICAgIGdldFN0cmluZyhyYXcuaWQpIHx8XG4gICAgZ2V0U3RyaW5nKChub2RlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5pZCkgfHxcbiAgICBub2RlLmd1aWRcbiAgKVxufVxuXG5jb25zdCBpc1N0cmVhbWluZ1RpbGVOb2RlID0gKG5vZGU6IEV4cGxvcmVyTm9kZSk6IGJvb2xlYW4gPT4ge1xuICBjb25zdCByYXcgPSBnZXROb2RlUmF3KG5vZGUpXG4gIHJldHVybiBnZXRTdHJpbmcocmF3Lm5hbWUpPy5zdGFydHNXaXRoKFNUUkVBTUlOR19USUxFX1BSRUZJWCkgPz8gZmFsc2Vcbn1cblxuY29uc3Qgc2V0VGFyZ2V0T2JqZWN0SWRzID0gKHJhdzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIGlkczogc3RyaW5nW10pID0+IHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJhdywgVEFSR0VUX09CSkVDVF9JRFNfS0VZLCB7XG4gICAgdmFsdWU6IGlkcyxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSlcbn1cblxuY29uc3QgaXNJZmNWaXJ0dWFsTm9kZSA9IChyYXc6IHVua25vd24pOiBib29sZWFuID0+IHtcbiAgY29uc3Qgc3BlY2tsZVR5cGUgPSBnZXRTdHJpbmcoZ2V0UmVjb3JkKHJhdykuc3BlY2tsZV90eXBlKVxuICByZXR1cm4gKFxuICAgIHNwZWNrbGVUeXBlID09PSBJRkNfTU9ERUxfR1JPVVBfVFlQRSB8fFxuICAgIHNwZWNrbGVUeXBlID09PSBJRkNfVFlQRV9HUk9VUF9UWVBFIHx8XG4gICAgc3BlY2tsZVR5cGUgPT09IElGQ19FTEVNRU5UX0dST1VQX1RZUEVcbiAgKVxufVxuXG5jb25zdCBidWlsZElmY1N0cmVhbWluZ1RyZWUgPSAocm9vdDogRXhwbG9yZXJOb2RlKTogRXhwbG9yZXJOb2RlIHwgbnVsbCA9PiB7XG4gIGlmICghQXJyYXkuaXNBcnJheShyb290LmNoaWxkcmVuKSB8fCAhcm9vdC5jaGlsZHJlbi5zb21lKGlzU3RyZWFtaW5nVGlsZU5vZGUpKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGNvbnN0IGNhY2hlZFRyZWUgPSBpZmNTdHJlYW1pbmdUcmVlQ2FjaGUuZ2V0KHJvb3QgYXMgb2JqZWN0KVxuICBpZiAoY2FjaGVkVHJlZSkgcmV0dXJuIGNhY2hlZFRyZWVcblxuICBjb25zdCByb290SWQgPSBnZXRTdHJpbmcoKHJvb3QgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLmlkKSB8fCAnaWZjLW1vZGVsJ1xuICBjb25zdCB0eXBlR3JvdXBzID0gbmV3IE1hcDxcbiAgICBzdHJpbmcsXG4gICAge1xuICAgICAgbm9kZTogRXhwbG9yZXJOb2RlXG4gICAgICBlbGVtZW50R3JvdXBzOiBNYXA8c3RyaW5nLCB7IG5vZGU6IEV4cGxvcmVyTm9kZTsgcGFydElkczogc3RyaW5nW10gfT5cbiAgICAgIHBhcnRJZHM6IHN0cmluZ1tdXG4gICAgfVxuICA+KClcblxuICBmb3IgKGNvbnN0IHRpbGVOb2RlIG9mIHJvb3QuY2hpbGRyZW4uZmlsdGVyKGlzU3RyZWFtaW5nVGlsZU5vZGUpKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRpbGVOb2RlLmNoaWxkcmVuKSkgY29udGludWVcblxuICAgIGZvciAoY29uc3QgcGFydE5vZGUgb2YgdGlsZU5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIGNvbnN0IHBhcnRSYXcgPSBnZXROb2RlUmF3KHBhcnROb2RlKVxuICAgICAgY29uc3QgdXNlckRhdGEgPSBnZXRSZWNvcmQocGFydFJhdy51c2VyRGF0YSlcbiAgICAgIGNvbnN0IHBhcnRJZCA9IGdldE5vZGVPYmplY3RJZChwYXJ0Tm9kZSlcbiAgICAgIGlmICghcGFydElkKSBjb250aW51ZVxuXG4gICAgICBjb25zdCBpZmNUeXBlID0gZ2V0U3RyaW5nKHVzZXJEYXRhLmlmY1R5cGUpIHx8IGdldFN0cmluZyhwYXJ0UmF3LmlmY1R5cGUpIHx8ICdJRkMnXG4gICAgICBjb25zdCBpZmNHdWlkID0gZ2V0U3RyaW5nKHVzZXJEYXRhLmlmY0d1aWQpIHx8IGdldFN0cmluZyhwYXJ0UmF3LmlmY0d1aWQpXG4gICAgICBjb25zdCBzb3VyY2VHdWlkID0gZ2V0U3RyaW5nKHVzZXJEYXRhLnNvdXJjZUd1aWQpIHx8IGdldFN0cmluZyhwYXJ0UmF3LnNvdXJjZUd1aWQpXG4gICAgICBjb25zdCBpZmNOYW1lID0gZ2V0U3RyaW5nKHVzZXJEYXRhLmlmY05hbWUpIHx8IGdldFN0cmluZyhwYXJ0UmF3LmlmY05hbWUpXG4gICAgICBjb25zdCBpZmNFbGVtZW50R3VpZCA9XG4gICAgICAgIGdldFN0cmluZyh1c2VyRGF0YS5pZmNFbGVtZW50R3VpZCkgfHxcbiAgICAgICAgZ2V0U3RyaW5nKHBhcnRSYXcuaWZjRWxlbWVudEd1aWQpIHx8XG4gICAgICAgIGlmY0d1aWRcbiAgICAgIGNvbnN0IGlmY0VsZW1lbnRTb3VyY2VHdWlkID1cbiAgICAgICAgZ2V0U3RyaW5nKHVzZXJEYXRhLmlmY0VsZW1lbnRTb3VyY2VHdWlkKSB8fFxuICAgICAgICBnZXRTdHJpbmcocGFydFJhdy5pZmNFbGVtZW50U291cmNlR3VpZCkgfHxcbiAgICAgICAgZ2V0U3RyaW5nKHVzZXJEYXRhLmlmY0VsZW1lbnRBc3NlbWJseVNvdXJjZUd1aWQpIHx8XG4gICAgICAgIGdldFN0cmluZyhwYXJ0UmF3LmlmY0VsZW1lbnRBc3NlbWJseVNvdXJjZUd1aWQpIHx8XG4gICAgICAgIHNvdXJjZUd1aWRcbiAgICAgIGNvbnN0IGlmY0VsZW1lbnRUeXBlID1cbiAgICAgICAgZ2V0U3RyaW5nKHVzZXJEYXRhLmlmY0VsZW1lbnRUeXBlKSB8fFxuICAgICAgICBnZXRTdHJpbmcocGFydFJhdy5pZmNFbGVtZW50VHlwZSkgfHxcbiAgICAgICAgaWZjVHlwZVxuICAgICAgY29uc3QgaWZjRWxlbWVudE5hbWUgPVxuICAgICAgICBnZXRTdHJpbmcodXNlckRhdGEuaWZjRWxlbWVudE5hbWUpIHx8XG4gICAgICAgIGdldFN0cmluZyhwYXJ0UmF3LmlmY0VsZW1lbnROYW1lKSB8fFxuICAgICAgICBpZmNOYW1lXG4gICAgICBjb25zdCBpZmNFbGVtZW50QXNzZW1ibHlHdWlkID1cbiAgICAgICAgZ2V0U3RyaW5nKHVzZXJEYXRhLmlmY0VsZW1lbnRBc3NlbWJseUd1aWQpIHx8XG4gICAgICAgIGdldFN0cmluZyhwYXJ0UmF3LmlmY0VsZW1lbnRBc3NlbWJseUd1aWQpXG4gICAgICBjb25zdCBpZmNFbGVtZW50QXNzZW1ibHlUeXBlID1cbiAgICAgICAgZ2V0U3RyaW5nKHVzZXJEYXRhLmlmY0VsZW1lbnRBc3NlbWJseVR5cGUpIHx8XG4gICAgICAgIGdldFN0cmluZyhwYXJ0UmF3LmlmY0VsZW1lbnRBc3NlbWJseVR5cGUpXG4gICAgICBjb25zdCBpZmNFbGVtZW50QXNzZW1ibHlOYW1lID1cbiAgICAgICAgZ2V0U3RyaW5nKHVzZXJEYXRhLmlmY0VsZW1lbnRBc3NlbWJseU5hbWUpIHx8XG4gICAgICAgIGdldFN0cmluZyhwYXJ0UmF3LmlmY0VsZW1lbnRBc3NlbWJseU5hbWUpXG4gICAgICBjb25zdCBpZmNFbGVtZW50QXNzZW1ibHlTb3VyY2VHdWlkID1cbiAgICAgICAgZ2V0U3RyaW5nKHVzZXJEYXRhLmlmY0VsZW1lbnRBc3NlbWJseVNvdXJjZUd1aWQpIHx8XG4gICAgICAgIGdldFN0cmluZyhwYXJ0UmF3LmlmY0VsZW1lbnRBc3NlbWJseVNvdXJjZUd1aWQpXG4gICAgICBjb25zdCBleHByZXNzSWQgPSB1c2VyRGF0YS5leHByZXNzSWQgfHwgcGFydFJhdy5leHByZXNzSWRcbiAgICAgIGNvbnN0IGVsZW1lbnRLZXkgPVxuICAgICAgICBpZmNFbGVtZW50U291cmNlR3VpZCB8fCBpZmNFbGVtZW50R3VpZCB8fCBgZXhwcmVzcy0ke2V4cHJlc3NJZCB8fCBwYXJ0SWR9YFxuICAgICAgY29uc3QgZWxlbWVudERpc3BsYXlUeXBlID0gaWZjVHlwZVxuICAgICAgY29uc3QgZWxlbWVudERpc3BsYXlOYW1lID0gaWZjTmFtZSB8fCBpZmNFbGVtZW50TmFtZVxuICAgICAgY29uc3QgdHlwZUlkID0gYCR7cm9vdElkfTppZmMtdHlwZToke2VsZW1lbnREaXNwbGF5VHlwZX1gXG4gICAgICBjb25zdCBlbGVtZW50SWQgPSBgJHtyb290SWR9OmlmYy1lbGVtZW50OiR7ZWxlbWVudEtleX1gXG4gICAgICBjb25zdCBlbGVtZW50Tm9kZUlkID0gaWZjRWxlbWVudFNvdXJjZUd1aWQgfHwgaWZjRWxlbWVudEd1aWQgfHwgZWxlbWVudElkXG5cbiAgICAgIGxldCB0eXBlR3JvdXAgPSB0eXBlR3JvdXBzLmdldCh0eXBlSWQpXG4gICAgICBpZiAoIXR5cGVHcm91cCkge1xuICAgICAgICB0eXBlR3JvdXAgPSB7XG4gICAgICAgICAgbm9kZToge1xuICAgICAgICAgICAgcmF3OiB7XG4gICAgICAgICAgICAgIGlkOiB0eXBlSWQsXG4gICAgICAgICAgICAgIG5hbWU6IGVsZW1lbnREaXNwbGF5VHlwZSxcbiAgICAgICAgICAgICAgc3BlY2tsZV90eXBlOiBJRkNfVFlQRV9HUk9VUF9UWVBFLFxuICAgICAgICAgICAgICBpZmNUeXBlOiBlbGVtZW50RGlzcGxheVR5cGVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjaGlsZHJlbjogW11cbiAgICAgICAgICB9LFxuICAgICAgICAgIGVsZW1lbnRHcm91cHM6IG5ldyBNYXAoKSxcbiAgICAgICAgICBwYXJ0SWRzOiBbXVxuICAgICAgICB9XG4gICAgICAgIHR5cGVHcm91cHMuc2V0KHR5cGVJZCwgdHlwZUdyb3VwKVxuICAgICAgfVxuXG4gICAgICBsZXQgZWxlbWVudEdyb3VwID0gdHlwZUdyb3VwLmVsZW1lbnRHcm91cHMuZ2V0KGVsZW1lbnRJZClcbiAgICAgIGlmICghZWxlbWVudEdyb3VwKSB7XG4gICAgICAgIGNvbnN0IHBhcnRJZHM6IHN0cmluZ1tdID0gW11cbiAgICAgICAgY29uc3QgcmF3OiBTcGVja2xlT2JqZWN0ID0ge1xuICAgICAgICAgIGlkOiBlbGVtZW50Tm9kZUlkLFxuICAgICAgICAgIG5hbWU6IGVsZW1lbnREaXNwbGF5TmFtZVxuICAgICAgICAgICAgPyBgJHtlbGVtZW50RGlzcGxheVR5cGV9ICR7ZWxlbWVudERpc3BsYXlOYW1lfWBcbiAgICAgICAgICAgIDogYCR7ZWxlbWVudERpc3BsYXlUeXBlfSAke2VsZW1lbnRLZXl9YCxcbiAgICAgICAgICBzcGVja2xlX3R5cGU6IElGQ19FTEVNRU5UX0dST1VQX1RZUEUsXG4gICAgICAgICAgaWZjR3VpZDogaWZjRWxlbWVudEd1aWQsXG4gICAgICAgICAgaWZjR2xvYmFsSWQ6IGlmY0VsZW1lbnRHdWlkLFxuICAgICAgICAgIHNvdXJjZUd1aWQ6IGlmY0VsZW1lbnRTb3VyY2VHdWlkLFxuICAgICAgICAgIGd1aWQ6IGlmY0VsZW1lbnRTb3VyY2VHdWlkIHx8IGlmY0VsZW1lbnRHdWlkLFxuICAgICAgICAgIGFwcGxpY2F0aW9uSWQ6IGlmY0VsZW1lbnRTb3VyY2VHdWlkIHx8IGlmY0VsZW1lbnRHdWlkLFxuICAgICAgICAgIGlmY1R5cGU6IGVsZW1lbnREaXNwbGF5VHlwZSxcbiAgICAgICAgICBpZmNOYW1lOiBlbGVtZW50RGlzcGxheU5hbWUsXG4gICAgICAgICAgaWZjUGFydEd1aWQ6IGlmY0d1aWQsXG4gICAgICAgICAgaWZjUGFydFNvdXJjZUd1aWQ6IHNvdXJjZUd1aWQsXG4gICAgICAgICAgaWZjUGFydFR5cGU6IGlmY1R5cGUsXG4gICAgICAgICAgaWZjUGFydE5hbWU6IGlmY05hbWUsXG4gICAgICAgICAgaWZjRWxlbWVudEd1aWQsXG4gICAgICAgICAgaWZjRWxlbWVudFNvdXJjZUd1aWQsXG4gICAgICAgICAgaWZjRWxlbWVudFR5cGUsXG4gICAgICAgICAgaWZjRWxlbWVudE5hbWUsXG4gICAgICAgICAgaWZjRWxlbWVudEFzc2VtYmx5R3VpZCxcbiAgICAgICAgICBpZmNFbGVtZW50QXNzZW1ibHlUeXBlLFxuICAgICAgICAgIGlmY0VsZW1lbnRBc3NlbWJseU5hbWUsXG4gICAgICAgICAgaWZjRWxlbWVudEFzc2VtYmx5U291cmNlR3VpZCxcbiAgICAgICAgICBleHByZXNzSWRcbiAgICAgICAgfVxuICAgICAgICBzZXRUYXJnZXRPYmplY3RJZHMocmF3LCBwYXJ0SWRzKVxuICAgICAgICBjb25zdCBuZXdFbGVtZW50R3JvdXAgPSB7XG4gICAgICAgICAgbm9kZToge1xuICAgICAgICAgICAgcmF3LFxuICAgICAgICAgICAgY2hpbGRyZW46IFtdXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwYXJ0SWRzXG4gICAgICAgIH1cbiAgICAgICAgdHlwZUdyb3VwLmVsZW1lbnRHcm91cHMuc2V0KGVsZW1lbnRJZCwgbmV3RWxlbWVudEdyb3VwKVxuICAgICAgICB0eXBlR3JvdXAubm9kZS5jaGlsZHJlbi5wdXNoKG5ld0VsZW1lbnRHcm91cC5ub2RlKVxuICAgICAgICBlbGVtZW50R3JvdXAgPSBuZXdFbGVtZW50R3JvdXBcbiAgICAgIH1cblxuICAgICAgZWxlbWVudEdyb3VwLm5vZGUuY2hpbGRyZW4ucHVzaChwYXJ0Tm9kZSlcbiAgICAgIGVsZW1lbnRHcm91cC5wYXJ0SWRzLnB1c2gocGFydElkKVxuICAgICAgdHlwZUdyb3VwLnBhcnRJZHMucHVzaChwYXJ0SWQpXG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGVHcm91cHMuc2l6ZSA9PT0gMCkgcmV0dXJuIG51bGxcblxuICBjb25zdCB0eXBlTm9kZXMgPSBBcnJheS5mcm9tKHR5cGVHcm91cHMudmFsdWVzKCkpXG4gICAgLnNvcnQoKGEsIGIpID0+IFN0cmluZyhhLm5vZGUucmF3Py5uYW1lKS5sb2NhbGVDb21wYXJlKFN0cmluZyhiLm5vZGUucmF3Py5uYW1lKSkpXG4gICAgLm1hcCgoZ3JvdXApID0+IHtcbiAgICAgIHNldFRhcmdldE9iamVjdElkcyhncm91cC5ub2RlLnJhdyEsIGdyb3VwLnBhcnRJZHMpXG4gICAgICBncm91cC5ub2RlLmNoaWxkcmVuLnNvcnQoKGEsIGIpID0+XG4gICAgICAgIFN0cmluZyhhLnJhdz8ubmFtZSkubG9jYWxlQ29tcGFyZShTdHJpbmcoYi5yYXc/Lm5hbWUpKVxuICAgICAgKVxuICAgICAgcmV0dXJuIGdyb3VwLm5vZGVcbiAgICB9KVxuXG4gIGNvbnN0IHJvb3RSYXcgPSBnZXROb2RlUmF3KHJvb3QpXG4gIGNvbnN0IHJhdyA9IHtcbiAgICBpZDogcm9vdElkLFxuICAgIG5hbWU6IGdldFN0cmluZyhyb290UmF3Lm5hbWUpIHx8IHJvb3RJZCxcbiAgICBzcGVja2xlX3R5cGU6IElGQ19NT0RFTF9HUk9VUF9UWVBFXG4gIH1cbiAgY29uc3QgdmlydHVhbFJvb3QgPSB7XG4gICAgLi4ucm9vdCxcbiAgICByYXcsXG4gICAgY2hpbGRyZW46IHR5cGVOb2Rlc1xuICB9IGFzIEV4cGxvcmVyTm9kZVxuXG4gIGlmY1N0cmVhbWluZ1RyZWVDYWNoZS5zZXQocm9vdCBhcyBvYmplY3QsIHZpcnR1YWxSb290KVxuICByZXR1cm4gdmlydHVhbFJvb3Rcbn1cblxuZXhwb3J0IHR5cGUgVW5pZmllZFZpcnR1YWxJdGVtID0ge1xuICB0eXBlOiAnbW9kZWwtaGVhZGVyJyB8ICd0cmVlLWl0ZW0nIHwgJ2RldGFjaGVkLW9iamVjdC1oZWFkZXInXHJcbiAgaWQ6IHN0cmluZ1xyXG4gIG1vZGVsSWQ6IHN0cmluZ1xyXG4gIGRhdGE6IEV4cGxvcmVyTm9kZSB8IE1vZGVsV2l0aFZlcnNpb24gfCB7IG9iamVjdElkOiBzdHJpbmcgfVxyXG4gIGluZGVudD86IG51bWJlclxyXG4gIGhhc0NoaWxkcmVuPzogYm9vbGVhblxyXG4gIGlzRXhwYW5kZWQ/OiBib29sZWFuXHJcbiAgaXNEZXNjZW5kYW50T2ZTZWxlY3RlZD86IGJvb2xlYW5cclxuICBpc0ZpcnN0Q2hpbGRPZk1vZGVsPzogYm9vbGVhblxyXG4gIGlzTGFzdENoaWxkT2ZNb2RlbD86IGJvb2xlYW5cclxuICBpc0ZpcnN0TW9kZWw/OiBib29sZWFuXHJcbiAgbmVlZHNUb3BCb3JkZXI/OiBib29sZWFuXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVRyZWVTdGF0ZU1hbmFnZXIoKSB7XHJcbiAgY29uc3QgZmxhdHRlbmVkVHJlZUNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIFVuaWZpZWRWaXJ0dWFsSXRlbVtdPigpXHJcbiAgY29uc3QgbGFzdENhY2hlS2V5ID0gcmVmKCcnKVxyXG4gIGNvbnN0IGlzSW5pdGlhbGl6ZWQgPSByZWYoZmFsc2UpXHJcblxyXG4gIGxldCB2aWV3ZXI6IHtcclxuICAgIG9uOiA8VCBleHRlbmRzIFZpZXdlckV2ZW50PihcclxuICAgICAgZXZlbnRUeXBlOiBULFxyXG4gICAgICBsaXN0ZW5lcjogKGFyZzogVmlld2VyRXZlbnRQYXlsb2FkW1RdKSA9PiB2b2lkXHJcbiAgICApID0+IHZvaWRcclxuICAgIHJlbW92ZUxpc3RlbmVyOiA8VCBleHRlbmRzIFZpZXdlckV2ZW50PihcclxuICAgICAgZXZlbnRUeXBlOiBULFxyXG4gICAgICBsaXN0ZW5lcjogKGFyZzogVmlld2VyRXZlbnRQYXlsb2FkW1RdKSA9PiB2b2lkXHJcbiAgICApID0+IHZvaWRcclxuICB9IHwgbnVsbCA9IG51bGxcclxuXHJcbiAgY29uc3QgY2xlYXJDYWNoZSA9ICgpID0+IHtcclxuICAgIGZsYXR0ZW5lZFRyZWVDYWNoZS5jbGVhcigpXHJcbiAgICBsYXN0Q2FjaGVLZXkudmFsdWUgPSAnJ1xyXG4gIH1cclxuXHJcbiAgY29uc3QgZ2V0Q2FjaGVLZXkgPSAoXHJcbiAgICBtb2RlbHNBbmRWZXJzaW9uSWRzOiB7IG1vZGVsOiBNb2RlbEl0ZW07IHZlcnNpb25JZDogc3RyaW5nIH1bXSxcclxuICAgIGV4cGFuZGVkTW9kZWxzOiBTZXQ8c3RyaW5nPixcclxuICAgIGV4cGFuZGVkTm9kZXM6IFNldDxzdHJpbmc+LFxyXG4gICAgc2VsZWN0ZWRPYmplY3RzOiB7IGlkOiBzdHJpbmcgfVtdLFxyXG4gICAgZGV0YWNoZWRPYmplY3RzOiB7IG9iamVjdElkOiBzdHJpbmcgfVtdXHJcbiAgKTogc3RyaW5nID0+IHtcclxuICAgIGNvbnN0IHBhcnRzID0gW1xyXG4gICAgICBtb2RlbHNBbmRWZXJzaW9uSWRzXHJcbiAgICAgICAgLm1hcCgoeyBtb2RlbCwgdmVyc2lvbklkIH0pID0+IGAke21vZGVsLmlkfToke3ZlcnNpb25JZH1gKVxyXG4gICAgICAgIC5qb2luKCd8JyksXHJcbiAgICAgIEFycmF5LmZyb20oZXhwYW5kZWRNb2RlbHMpLnNvcnQoKS5qb2luKCcsJyksXHJcbiAgICAgIEFycmF5LmZyb20oZXhwYW5kZWROb2Rlcykuc29ydCgpLmpvaW4oJywnKSxcclxuICAgICAgc2VsZWN0ZWRPYmplY3RzXHJcbiAgICAgICAgLm1hcCgobykgPT4gby5pZClcclxuICAgICAgICAuc29ydCgpXHJcbiAgICAgICAgLmpvaW4oJywnKSxcclxuICAgICAgZGV0YWNoZWRPYmplY3RzXHJcbiAgICAgICAgLm1hcCgobykgPT4gby5vYmplY3RJZClcclxuICAgICAgICAuc29ydCgpXHJcbiAgICAgICAgLmpvaW4oJywnKVxyXG4gICAgXVxyXG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oJyMnKVxyXG4gIH1cclxuXHJcbiAgY29uc3QgaW5pdGlhbGl6ZSA9ICh2aWV3ZXJJbnN0YW5jZTogdHlwZW9mIHZpZXdlcikgPT4ge1xyXG4gICAgaWYgKGlzSW5pdGlhbGl6ZWQudmFsdWUgfHwgIXZpZXdlckluc3RhbmNlKSByZXR1cm5cclxuXHJcbiAgICB2aWV3ZXIgPSB2aWV3ZXJJbnN0YW5jZVxyXG4gICAgaXNJbml0aWFsaXplZC52YWx1ZSA9IHRydWVcclxuXHJcbiAgICBjb25zdCBvbkxvYWRDb21wbGV0ZSA9ICgpID0+IGNsZWFyQ2FjaGUoKVxyXG4gICAgdmlld2VyLm9uKFZpZXdlckV2ZW50LkxvYWRDb21wbGV0ZSwgb25Mb2FkQ29tcGxldGUpXHJcblxyXG4gICAgaWYgKGltcG9ydC5tZXRhLmNsaWVudCkge1xyXG4gICAgICB1c2VFdmVudExpc3RlbmVyKCdiZWZvcmV1bmxvYWQnLCAoKSA9PiB7XHJcbiAgICAgICAgdmlld2VyPy5yZW1vdmVMaXN0ZW5lcihWaWV3ZXJFdmVudC5Mb2FkQ29tcGxldGUsIG9uTG9hZENvbXBsZXRlKVxyXG4gICAgICAgIGNsZWFyQ2FjaGUoKVxyXG4gICAgICB9KVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29uc3QgZ2V0VW5pZmllZFZpcnR1YWxJdGVtcyA9IChcclxuICAgIG1vZGVsc0FuZFZlcnNpb25JZHM6IHsgbW9kZWw6IE1vZGVsSXRlbTsgdmVyc2lvbklkOiBzdHJpbmcgfVtdLFxyXG4gICAgZXhwYW5kZWRNb2RlbHM6IFNldDxzdHJpbmc+LFxyXG4gICAgZXhwYW5kZWROb2RlczogU2V0PHN0cmluZz4sXHJcbiAgICBzZWxlY3RlZE9iamVjdHM6IHsgaWQ6IHN0cmluZyB9W10sXHJcbiAgICB3b3JsZFRyZWU6IFdvcmxkVHJlZSB8IG51bGwsXHJcbiAgICBzdGF0ZVJlc291cmNlSXRlbXM6IHsgb2JqZWN0SWQ6IHN0cmluZzsgbW9kZWxJZD86IHN0cmluZyB9W10sXHJcbiAgICBkZXRhY2hlZE9iamVjdHM6IHsgb2JqZWN0SWQ6IHN0cmluZyB9W10sXHJcbiAgICBnZXRSb290Tm9kZXNGb3JNb2RlbDogKFxyXG4gICAgICBtb2RlbElkOiBzdHJpbmcsXHJcbiAgICAgIHdvcmxkVHJlZTogV29ybGRUcmVlIHwgbnVsbCxcclxuICAgICAgc3RhdGVSZXNvdXJjZUl0ZW1zOiB7IG9iamVjdElkOiBzdHJpbmc7IG1vZGVsSWQ/OiBzdHJpbmcgfVtdLFxyXG4gICAgICBtb2RlbHNBbmRWZXJzaW9uSWRzOiB7IG1vZGVsOiBNb2RlbEl0ZW07IHZlcnNpb25JZDogc3RyaW5nIH1bXVxyXG4gICAgKSA9PiBFeHBsb3Jlck5vZGVbXSxcclxuICAgIGZsYXR0ZW5Nb2RlbFRyZWU6IChcclxuICAgICAgbm9kZXM6IEV4cGxvcmVyTm9kZVtdLFxyXG4gICAgICBtb2RlbElkOiBzdHJpbmcsXHJcbiAgICAgIGV4cGFuZGVkTm9kZXM6IFNldDxzdHJpbmc+LFxyXG4gICAgICBzZWxlY3RlZE9iamVjdHM6IHsgaWQ6IHN0cmluZyB9W10sXHJcbiAgICAgIGluZGVudD86IG51bWJlcixcclxuICAgICAgaXNEZXNjZW5kYW50T2ZTZWxlY3RlZD86IGJvb2xlYW5cclxuICAgICkgPT4gVW5pZmllZFZpcnR1YWxJdGVtW11cclxuICApOiBVbmlmaWVkVmlydHVhbEl0ZW1bXSA9PiB7XHJcbiAgICBjb25zdCBjYWNoZUtleSA9IGdldENhY2hlS2V5KFxyXG4gICAgICBtb2RlbHNBbmRWZXJzaW9uSWRzLFxyXG4gICAgICBleHBhbmRlZE1vZGVscyxcclxuICAgICAgZXhwYW5kZWROb2RlcyxcclxuICAgICAgc2VsZWN0ZWRPYmplY3RzLFxyXG4gICAgICBkZXRhY2hlZE9iamVjdHNcclxuICAgIClcclxuXHJcbiAgICBpZiAobGFzdENhY2hlS2V5LnZhbHVlID09PSBjYWNoZUtleSAmJiBmbGF0dGVuZWRUcmVlQ2FjaGUuaGFzKGNhY2hlS2V5KSkge1xyXG4gICAgICByZXR1cm4gZmxhdHRlbmVkVHJlZUNhY2hlLmdldChjYWNoZUtleSkhXHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgcmVzdWx0OiBVbmlmaWVkVmlydHVhbEl0ZW1bXSA9IFtdXHJcblxyXG4gICAgbW9kZWxzQW5kVmVyc2lvbklkcy5mb3JFYWNoKCh7IG1vZGVsLCB2ZXJzaW9uSWQgfSwgaW5kZXgpID0+IHtcclxuICAgICAgcmVzdWx0LnB1c2goe1xyXG4gICAgICAgIHR5cGU6ICdtb2RlbC1oZWFkZXInLFxyXG4gICAgICAgIGlkOiBgbW9kZWwtJHttb2RlbC5pZH1gLFxyXG4gICAgICAgIG1vZGVsSWQ6IG1vZGVsLmlkLFxyXG4gICAgICAgIGRhdGE6IHsgbW9kZWwsIHZlcnNpb25JZCB9LFxyXG4gICAgICAgIGlzRmlyc3RNb2RlbDogaW5kZXggPT09IDBcclxuICAgICAgfSlcclxuXHJcbiAgICAgIGlmIChleHBhbmRlZE1vZGVscy5oYXMobW9kZWwuaWQpKSB7XHJcbiAgICAgICAgY29uc3QgbW9kZWxSb290Tm9kZXMgPSBnZXRSb290Tm9kZXNGb3JNb2RlbChcclxuICAgICAgICAgIG1vZGVsLmlkLFxyXG4gICAgICAgICAgd29ybGRUcmVlLFxyXG4gICAgICAgICAgc3RhdGVSZXNvdXJjZUl0ZW1zLFxyXG4gICAgICAgICAgbW9kZWxzQW5kVmVyc2lvbklkc1xyXG4gICAgICAgIClcclxuXHJcbiAgICAgICAgaWYgKG1vZGVsUm9vdE5vZGVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIGNvbnN0IHRyZWVJdGVtcyA9IGZsYXR0ZW5Nb2RlbFRyZWUoXHJcbiAgICAgICAgICAgIG1vZGVsUm9vdE5vZGVzLFxyXG4gICAgICAgICAgICBtb2RlbC5pZCxcclxuICAgICAgICAgICAgZXhwYW5kZWROb2RlcyxcclxuICAgICAgICAgICAgc2VsZWN0ZWRPYmplY3RzXHJcbiAgICAgICAgICApXHJcblxyXG4gICAgICAgICAgaWYgKHRyZWVJdGVtcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIHRyZWVJdGVtc1swXS5pc0ZpcnN0Q2hpbGRPZk1vZGVsID0gdHJ1ZVxyXG4gICAgICAgICAgICB0cmVlSXRlbXNbdHJlZUl0ZW1zLmxlbmd0aCAtIDFdLmlzTGFzdENoaWxkT2ZNb2RlbCA9IHRydWVcclxuICAgICAgICAgICAgcmVzdWx0LnB1c2goLi4udHJlZUl0ZW1zKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSlcclxuXHJcbiAgICAvLyBIYW5kbGUgZGV0YWNoZWQgb2JqZWN0c1xyXG4gICAgZGV0YWNoZWRPYmplY3RzLmZvckVhY2goKGRldGFjaGVkT2JqZWN0LCBpbmRleCkgPT4ge1xyXG4gICAgICBjb25zdCBvYmplY3RJZCA9IGRldGFjaGVkT2JqZWN0Lm9iamVjdElkXHJcbiAgICAgIGNvbnN0IGlzRmlyc3REZXRhY2hlZE9iamVjdCA9IGluZGV4ID09PSAwICYmIG1vZGVsc0FuZFZlcnNpb25JZHMubGVuZ3RoID09PSAwXHJcblxyXG4gICAgICByZXN1bHQucHVzaCh7XHJcbiAgICAgICAgdHlwZTogJ2RldGFjaGVkLW9iamVjdC1oZWFkZXInLFxyXG4gICAgICAgIGlkOiBgZGV0YWNoZWQtJHtvYmplY3RJZH1gLFxyXG4gICAgICAgIG1vZGVsSWQ6IG9iamVjdElkLCAvLyBVc2Ugb2JqZWN0SWQgYXMgbW9kZWxJZCBmb3IgZGV0YWNoZWQgb2JqZWN0c1xyXG4gICAgICAgIGRhdGE6IHsgb2JqZWN0SWQgfSxcclxuICAgICAgICBpc0ZpcnN0TW9kZWw6IGlzRmlyc3REZXRhY2hlZE9iamVjdFxyXG4gICAgICB9KVxyXG5cclxuICAgICAgaWYgKGV4cGFuZGVkTW9kZWxzLmhhcyhvYmplY3RJZCkpIHtcclxuICAgICAgICBjb25zdCBkZXRhY2hlZFJvb3ROb2RlcyA9IGdldFJvb3ROb2Rlc0Zvck1vZGVsKFxyXG4gICAgICAgICAgb2JqZWN0SWQsXHJcbiAgICAgICAgICB3b3JsZFRyZWUsXHJcbiAgICAgICAgICBzdGF0ZVJlc291cmNlSXRlbXMsXHJcbiAgICAgICAgICBtb2RlbHNBbmRWZXJzaW9uSWRzXHJcbiAgICAgICAgKVxyXG5cclxuICAgICAgICBpZiAoZGV0YWNoZWRSb290Tm9kZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgY29uc3QgdHJlZUl0ZW1zID0gZmxhdHRlbk1vZGVsVHJlZShcclxuICAgICAgICAgICAgZGV0YWNoZWRSb290Tm9kZXMsXHJcbiAgICAgICAgICAgIG9iamVjdElkLFxyXG4gICAgICAgICAgICBleHBhbmRlZE5vZGVzLFxyXG4gICAgICAgICAgICBzZWxlY3RlZE9iamVjdHNcclxuICAgICAgICAgIClcclxuXHJcbiAgICAgICAgICBpZiAodHJlZUl0ZW1zLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgdHJlZUl0ZW1zWzBdLmlzRmlyc3RDaGlsZE9mTW9kZWwgPSB0cnVlXHJcbiAgICAgICAgICAgIHRyZWVJdGVtc1t0cmVlSXRlbXMubGVuZ3RoIC0gMV0uaXNMYXN0Q2hpbGRPZk1vZGVsID0gdHJ1ZVxyXG4gICAgICAgICAgICByZXN1bHQucHVzaCguLi50cmVlSXRlbXMpXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KVxyXG5cclxuICAgIC8vIENhY2hlIHRoZSByZXN1bHRcclxuICAgIGZsYXR0ZW5lZFRyZWVDYWNoZS5zZXQoY2FjaGVLZXksIHJlc3VsdClcclxuICAgIGxhc3RDYWNoZUtleS52YWx1ZSA9IGNhY2hlS2V5XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdFxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGluaXRpYWxpemUsXHJcbiAgICBnZXRVbmlmaWVkVmlydHVhbEl0ZW1zLFxyXG4gICAgY2xlYXJDYWNoZVxyXG4gIH1cclxufVxyXG5cclxuY29uc3QgdHJlZVN0YXRlTWFuYWdlciA9IGNyZWF0ZVRyZWVTdGF0ZU1hbmFnZXIoKVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVzZVRyZWVNYW5hZ2VtZW50KCkge1xyXG4gIGNvbnN0IHR5cGVDaGVja0NhY2hlID0gbmV3IE1hcDxzdHJpbmcsIGJvb2xlYW4+KClcclxuXHJcbiAgY29uc3QgaXNBbGxvd2VkVHlwZSA9IChub2RlOiBFeHBsb3Jlck5vZGUpOiBib29sZWFuID0+IHtcclxuICAgIGNvbnN0IHNwZWNrbGVUeXBlID0gbm9kZS5yYXc/LnNwZWNrbGVfdHlwZSB8fCAnJ1xyXG4gICAgaWYgKCFzcGVja2xlVHlwZSkgcmV0dXJuIHRydWVcclxuXHJcbiAgICBpZiAodHlwZUNoZWNrQ2FjaGUuaGFzKHNwZWNrbGVUeXBlKSkge1xyXG4gICAgICByZXR1cm4gdHlwZUNoZWNrQ2FjaGUuZ2V0KHNwZWNrbGVUeXBlKSFcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBpc0FsbG93ZWQgPSAhQXJyYXkuZnJvbShISURERU5fU1BFQ0tMRV9UWVBFUykuc29tZSgoc3Vic3RyaW5nKSA9PlxyXG4gICAgICBzcGVja2xlVHlwZS5pbmNsdWRlcyhzdWJzdHJpbmcpXHJcbiAgICApXHJcblxyXG4gICAgaWYgKHR5cGVDaGVja0NhY2hlLnNpemUgPCAxMDAwKSB7XHJcbiAgICAgIHR5cGVDaGVja0NhY2hlLnNldChzcGVja2xlVHlwZSwgaXNBbGxvd2VkKVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBpc0FsbG93ZWRcclxuICB9XHJcblxyXG4gIGNvbnN0IGZsYXR0ZW5Nb2RlbFRyZWUgPSAoXHJcbiAgICBub2RlczogRXhwbG9yZXJOb2RlW10sXHJcbiAgICBtb2RlbElkOiBzdHJpbmcsXHJcbiAgICBleHBhbmRlZE5vZGVzOiBTZXQ8c3RyaW5nPixcclxuICAgIHNlbGVjdGVkT2JqZWN0czogeyBpZDogc3RyaW5nIH1bXSxcclxuICAgIGluZGVudCA9IDAsXHJcbiAgICBpc0Rlc2NlbmRhbnRPZlNlbGVjdGVkID0gZmFsc2VcclxuICApOiBVbmlmaWVkVmlydHVhbEl0ZW1bXSA9PiB7XHJcbiAgICBjb25zdCByZXN1bHQ6IFVuaWZpZWRWaXJ0dWFsSXRlbVtdID0gW11cclxuICAgIGNvbnN0IHNlbGVjdGVkT2JqZWN0SWRzID0gbmV3IFNldChzZWxlY3RlZE9iamVjdHMubWFwKChvYmopID0+IG9iai5pZCkpXHJcblxyXG4gICAgZm9yIChjb25zdCBub2RlIG9mIG5vZGVzKSB7XHJcbiAgICAgIGNvbnN0IG5vZGVJZCA9IG5vZGUucmF3Py5pZCB8fCBub2RlLmd1aWQgfHwgJydcclxuICAgICAgaWYgKCFub2RlSWQpIGNvbnRpbnVlXHJcblxyXG4gICAgICBjb25zdCBzcGVja2xlRGF0YSA9IG5vZGUucmF3XHJcbiAgICAgIGNvbnN0IGlzTm9kZVNlbGVjdGVkID0gc2VsZWN0ZWRPYmplY3RJZHMuaGFzKG5vZGVJZClcclxuICAgICAgY29uc3Qgc2hvdWxkTWFya0Rlc2NlbmRhbnRzQXNTZWxlY3RlZCA9IGlzRGVzY2VuZGFudE9mU2VsZWN0ZWQgfHwgaXNOb2RlU2VsZWN0ZWRcclxuXHJcbiAgICAgIGNvbnN0IGlzTm9uRW1wdHlBcnJheSA9ICh4OiB1bmtub3duKTogeCBpcyBBcnJheTx1bmtub3duPiA9PlxyXG4gICAgICAgICEheCAmJiBBcnJheS5pc0FycmF5KHgpICYmIHgubGVuZ3RoID4gMFxyXG4gICAgICBjb25zdCBpc05vbkVtcHR5T2JqZWN0QXJyYXkgPSAoeDogdW5rbm93bikgPT5cclxuICAgICAgICBpc05vbkVtcHR5QXJyYXkoeCkgJiZcclxuICAgICAgICB0eXBlb2YgeFswXSA9PT0gJ29iamVjdCcgJiZcclxuICAgICAgICAhQXJyYXkuaXNBcnJheSh4WzBdKSAmJlxyXG4gICAgICAgIHhbMF0gIT09IG51bGxcclxuXHJcbiAgICAgIGNvbnN0IGlzU2luZ2xlQ29sbGVjdGlvbiA9XG4gICAgICAgIGlzTm9uRW1wdHlPYmplY3RBcnJheShzcGVja2xlRGF0YT8uY2hpbGRyZW4pIHx8XG4gICAgICAgIGlzTm9uRW1wdHlPYmplY3RBcnJheShzcGVja2xlRGF0YT8uZWxlbWVudHMpIHx8XG4gICAgICAgIChpc0lmY1ZpcnR1YWxOb2RlKHNwZWNrbGVEYXRhKSAmJlxuICAgICAgICAgIEFycmF5LmlzQXJyYXkobm9kZS5jaGlsZHJlbikgJiZcbiAgICAgICAgICBub2RlLmNoaWxkcmVuLmxlbmd0aCA+IDApXG4gICAgICBjb25zdCBhcnJheUNvbGxlY3Rpb25zOiBFeHBsb3Jlck5vZGVbXSA9IFtdXHJcblxyXG4gICAgICBpZiAoc3BlY2tsZURhdGEpIHtcclxuICAgICAgICBPYmplY3QuZW50cmllcyhzcGVja2xlRGF0YSkuZm9yRWFjaCgoW2ssIHZhbF0pID0+IHtcclxuICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgRVhDTFVERURfQ09MTEVDVElPTl9LRVlTLmhhcyhrIGFzICdjaGlsZHJlbicgfCAnZWxlbWVudHMnKSB8fFxyXG4gICAgICAgICAgICBrLmluY2x1ZGVzKERJU1BMQVlfVkFMVUVfS0VZKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICAgICByZXR1cm5cclxuICAgICAgICAgIGlmICghaXNSZWZlcmVuY2VkSWRBcnJheSh2YWwpKSByZXR1cm5cclxuXHJcbiAgICAgICAgICBjb25zdCBpZHMgPSBuZXcgU2V0KHZhbC5tYXAoKHJlZikgPT4gcmVmLnJlZmVyZW5jZWRJZCkpXHJcbiAgICAgICAgICBjb25zdCBhY3R1YWxSYXdSZWZzID1cclxuICAgICAgICAgICAgbm9kZS5jaGlsZHJlbj8uZmlsdGVyKChjaGlsZE5vZGUpID0+IHtcclxuICAgICAgICAgICAgICBjb25zdCBjaGlsZElkID0gY2hpbGROb2RlLnJhdz8uaWQgYXMgc3RyaW5nXHJcbiAgICAgICAgICAgICAgcmV0dXJuIGlkcy5oYXMoY2hpbGRJZCkgJiYgaXNBbGxvd2VkVHlwZShjaGlsZE5vZGUpXHJcbiAgICAgICAgICAgIH0pIHx8IFtdXHJcblxyXG4gICAgICAgICAgaWYgKGFjdHVhbFJhd1JlZnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBhcnJheUNvbGxlY3Rpb25zLnB1c2goe1xyXG4gICAgICAgICAgICAgIHJhdzoge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogayxcclxuICAgICAgICAgICAgICAgIGlkOiBrLFxyXG4gICAgICAgICAgICAgICAgc3BlY2tsZV90eXBlOiAnQXJyYXkgQ29sbGVjdGlvbicsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY2FtZWxjYXNlXHJcbiAgICAgICAgICAgICAgICBjaGlsZHJlbjogdmFsXHJcbiAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICBjaGlsZHJlbjogYWN0dWFsUmF3UmVmc1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IGlzTXVsdGlwbGVDb2xsZWN0aW9uID0gYXJyYXlDb2xsZWN0aW9ucy5sZW5ndGggPiAwXHJcbiAgICAgIGNvbnN0IGhhc0NoaWxkcmVuID0gaXNTaW5nbGVDb2xsZWN0aW9uIHx8IGlzTXVsdGlwbGVDb2xsZWN0aW9uXHJcbiAgICAgIGNvbnN0IGlzRXhwYW5kZWQgPSBoYXNDaGlsZHJlbiAmJiBleHBhbmRlZE5vZGVzLmhhcyhub2RlSWQpXHJcblxyXG4gICAgICByZXN1bHQucHVzaCh7XHJcbiAgICAgICAgdHlwZTogJ3RyZWUtaXRlbScsXHJcbiAgICAgICAgaWQ6IG5vZGVJZCxcclxuICAgICAgICBtb2RlbElkLFxyXG4gICAgICAgIGRhdGE6IG5vZGUsXHJcbiAgICAgICAgaW5kZW50LFxyXG4gICAgICAgIGhhc0NoaWxkcmVuLFxyXG4gICAgICAgIGlzRXhwYW5kZWQsXHJcbiAgICAgICAgaXNEZXNjZW5kYW50T2ZTZWxlY3RlZFxyXG4gICAgICB9KVxyXG5cclxuICAgICAgaWYgKGlzRXhwYW5kZWQpIHtcclxuICAgICAgICBpZiAoaXNNdWx0aXBsZUNvbGxlY3Rpb24pIHtcclxuICAgICAgICAgIHJlc3VsdC5wdXNoKFxyXG4gICAgICAgICAgICAuLi5mbGF0dGVuTW9kZWxUcmVlKFxyXG4gICAgICAgICAgICAgIGFycmF5Q29sbGVjdGlvbnMsXHJcbiAgICAgICAgICAgICAgbW9kZWxJZCxcclxuICAgICAgICAgICAgICBleHBhbmRlZE5vZGVzLFxyXG4gICAgICAgICAgICAgIHNlbGVjdGVkT2JqZWN0cyxcclxuICAgICAgICAgICAgICBpbmRlbnQgKyAxLFxyXG4gICAgICAgICAgICAgIHNob3VsZE1hcmtEZXNjZW5kYW50c0FzU2VsZWN0ZWRcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGlzU2luZ2xlQ29sbGVjdGlvbikge1xyXG4gICAgICAgICAgY29uc3QgdHJlZUl0ZW1zID1cclxuICAgICAgICAgICAgbm9kZS5jaGlsZHJlbj8uZmlsdGVyKChjaGlsZCkgPT4gISFjaGlsZC5yYXc/LmlkICYmIGlzQWxsb3dlZFR5cGUoY2hpbGQpKSB8fFxyXG4gICAgICAgICAgICBbXVxyXG5cclxuICAgICAgICAgIGxldCBmaWx0ZXJlZEl0ZW1zID0gdHJlZUl0ZW1zXHJcbiAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgIGlzUmVmZXJlbmNlZElkQXJyYXkoc3BlY2tsZURhdGE/LmVsZW1lbnRzKSAmJlxyXG4gICAgICAgICAgICBzcGVja2xlRGF0YT8uYXRvbWljID09PSB0cnVlXHJcbiAgICAgICAgICApIHtcclxuICAgICAgICAgICAgY29uc3QgZWxlbWVudElkcyA9IG5ldyBTZXQoXHJcbiAgICAgICAgICAgICAgc3BlY2tsZURhdGEuZWxlbWVudHMubWFwKChvYmopID0+IG9iai5yZWZlcmVuY2VkSWQpXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgICAgZmlsdGVyZWRJdGVtcyA9IHRyZWVJdGVtcy5maWx0ZXIoKGl0ZW0pID0+XHJcbiAgICAgICAgICAgICAgZWxlbWVudElkcy5oYXMoaXRlbS5yYXc/LmlkIGFzIHN0cmluZylcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIHJlc3VsdC5wdXNoKFxyXG4gICAgICAgICAgICAuLi5mbGF0dGVuTW9kZWxUcmVlKFxyXG4gICAgICAgICAgICAgIGZpbHRlcmVkSXRlbXMsXHJcbiAgICAgICAgICAgICAgbW9kZWxJZCxcclxuICAgICAgICAgICAgICBleHBhbmRlZE5vZGVzLFxyXG4gICAgICAgICAgICAgIHNlbGVjdGVkT2JqZWN0cyxcclxuICAgICAgICAgICAgICBpbmRlbnQgKyAxLFxyXG4gICAgICAgICAgICAgIHNob3VsZE1hcmtEZXNjZW5kYW50c0FzU2VsZWN0ZWRcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiByZXN1bHRcclxuICB9XHJcblxyXG4gIGNvbnN0IGdldFJvb3ROb2Rlc0Zvck1vZGVsID0gKFxyXG4gICAgbW9kZWxJZDogc3RyaW5nLFxyXG4gICAgd29ybGRUcmVlOiBXb3JsZFRyZWUgfCBudWxsLFxyXG4gICAgc3RhdGVSZXNvdXJjZUl0ZW1zOiB7IG9iamVjdElkOiBzdHJpbmc7IG1vZGVsSWQ/OiBzdHJpbmcgfVtdLFxyXG4gICAgbW9kZWxzQW5kVmVyc2lvbklkczogeyBtb2RlbDogTW9kZWxJdGVtOyB2ZXJzaW9uSWQ6IHN0cmluZyB9W11cclxuICApOiBFeHBsb3Jlck5vZGVbXSA9PiB7XHJcbiAgICBpZiAoIXdvcmxkVHJlZSkgcmV0dXJuIFtdXHJcblxyXG4gICAgY29uc3QgcmVzb3VyY2VJdGVtc01hcCA9IGtleUJ5KFxyXG4gICAgICBzdGF0ZVJlc291cmNlSXRlbXMubWFwKChpdGVtLCBpbmRleCkgPT4gKHsgLi4uaXRlbSwgaW5kZXggfSkpLFxyXG4gICAgICAnb2JqZWN0SWQnXHJcbiAgICApXHJcbiAgICBjb25zdCBtb2RlbHNNYXAgPSBrZXlCeShcclxuICAgICAgbW9kZWxzQW5kVmVyc2lvbklkcy5tYXAoKHsgbW9kZWwgfSkgPT4gbW9kZWwpLFxyXG4gICAgICAnaWQnXHJcbiAgICApXHJcblxyXG4gICAgY29uc3Qgcm9vdE5vZGVzID0gd29ybGRUcmVlLl9yb290LmNoaWxkcmVuIGFzIEV4cGxvcmVyTm9kZVtdXHJcbiAgICBjb25zdCByZXN1bHRzOiBSZWNvcmQ8bnVtYmVyLCBFeHBsb3Jlck5vZGVbXT4gPSB7fVxyXG4gICAgY29uc3QgdW5tYXRjaGVkTm9kZXM6IEV4cGxvcmVyTm9kZVtdID0gW11cclxuXHJcbiAgICByb290Tm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xyXG4gICAgICBjb25zdCBvYmplY3RJZCA9ICgobm9kZS5tb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikuaWQgYXMgc3RyaW5nKVxyXG4gICAgICAgIC5zcGxpdCgnLycpXHJcbiAgICAgICAgLnJldmVyc2UoKVswXSBhcyBzdHJpbmdcclxuXHJcbiAgICAgIGNvbnN0IHJlc291cmNlRGF0YSA9IHJlc291cmNlSXRlbXNNYXBbb2JqZWN0SWRdXHJcbiAgICAgIGNvbnN0IHJlc291cmNlSXRlbSA9IHJlc291cmNlRGF0YVxyXG4gICAgICBjb25zdCByZXNvdXJjZUl0ZW1JZHggPSByZXNvdXJjZURhdGE/LmluZGV4ID8/IC0xXHJcblxyXG4gICAgICBjb25zdCByYXcgPSBub2RlLm1vZGVsPy5yYXcgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5cclxuXHJcbiAgICAgIGlmIChyZXNvdXJjZUl0ZW0/Lm1vZGVsSWQpIHtcclxuICAgICAgICBjb25zdCBtb2RlbCA9IG1vZGVsc01hcFtyZXNvdXJjZUl0ZW0ubW9kZWxJZF1cclxuICAgICAgICByYXcubmFtZSA9IG1vZGVsPy5uYW1lXHJcbiAgICAgICAgcmF3LnR5cGUgPSBtb2RlbD8uaWRcblxuICAgICAgICBpZiAocmVzb3VyY2VJdGVtLm1vZGVsSWQgPT09IG1vZGVsSWQpIHtcbiAgICAgICAgICBjb25zdCByZXMgPVxuICAgICAgICAgICAgYnVpbGRJZmNTdHJlYW1pbmdUcmVlKG5vZGUubW9kZWwgYXMgRXhwbG9yZXJOb2RlKSB8fFxuICAgICAgICAgICAgKG5vZGUubW9kZWwgYXMgRXhwbG9yZXJOb2RlKVxuICAgICAgICAgIGlmIChyZXNvdXJjZUl0ZW1JZHggIT09IC0xKSB7XG4gICAgICAgICAgICA7KHJlc3VsdHNbcmVzb3VyY2VJdGVtSWR4XSA9IHJlc3VsdHNbcmVzb3VyY2VJdGVtSWR4XSB8fCBbXSkucHVzaChyZXMpXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVubWF0Y2hlZE5vZGVzLnB1c2gocmVzKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBPYmplY3QuYXNzaWduKHJhdywgeyBuYW1lOiAnT2JqZWN0JywgdHlwZTogJ1NpbmdsZSBvYmplY3QnIH0pXHJcblxuICAgICAgICBpZiAocmVzb3VyY2VJdGVtICYmIHJlc291cmNlSXRlbS5vYmplY3RJZCA9PT0gbW9kZWxJZCkge1xuICAgICAgICAgIHVubWF0Y2hlZE5vZGVzLnB1c2goXG4gICAgICAgICAgICBidWlsZElmY1N0cmVhbWluZ1RyZWUobm9kZS5tb2RlbCBhcyBFeHBsb3Jlck5vZGUpIHx8XG4gICAgICAgICAgICAgIChub2RlLm1vZGVsIGFzIEV4cGxvcmVyTm9kZSlcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxyXG5cclxuICAgIHJldHVybiBbXHJcbiAgICAgIC4uLmZsYXR0ZW4oXHJcbiAgICAgICAgc29ydEJ5KE9iamVjdC5lbnRyaWVzKHJlc3VsdHMpLCAoW2luZGV4XSkgPT4gTnVtYmVyKGluZGV4KSkubWFwKFxyXG4gICAgICAgICAgKFssIG5vZGVzXSkgPT4gbm9kZXNcclxuICAgICAgICApXHJcbiAgICAgICksXHJcbiAgICAgIC4uLnVubWF0Y2hlZE5vZGVzXHJcbiAgICBdXHJcbiAgfVxyXG5cclxuICBjb25zdCBmaW5kT2JqZWN0SW5Ob2RlcyA9IChub2RlczogRXhwbG9yZXJOb2RlW10sIG9iamVjdElkOiBzdHJpbmcpOiBib29sZWFuID0+IHtcclxuICAgIHJldHVybiBub2Rlcy5zb21lKFxyXG4gICAgICAobm9kZSkgPT5cclxuICAgICAgICBub2RlLnJhdz8uaWQgPT09IG9iamVjdElkIHx8XHJcbiAgICAgICAgKG5vZGUuY2hpbGRyZW4/Lmxlbmd0aCAmJiBmaW5kT2JqZWN0SW5Ob2Rlcyhub2RlLmNoaWxkcmVuLCBvYmplY3RJZCkpXHJcbiAgICApXHJcbiAgfVxyXG5cclxuICBjb25zdCBleHBhbmROb2Rlc1RvU2hvd09iamVjdCA9IChcclxuICAgIG5vZGVzOiBFeHBsb3Jlck5vZGVbXSxcclxuICAgIG9iamVjdElkOiBzdHJpbmcsXHJcbiAgICBtb2RlbElkOiBzdHJpbmcsXHJcbiAgICBleHBhbmRlZE5vZGVzOiBTZXQ8c3RyaW5nPixcclxuICAgIGRlcHRoID0gMFxyXG4gICk6IHsgZm91bmQ6IGJvb2xlYW47IG5vZGVzVG9FeHBhbmQ6IHN0cmluZ1tdIH0gPT4ge1xyXG4gICAgaWYgKCFub2Rlcz8ubGVuZ3RoIHx8IGRlcHRoID4gTUFYX0VYUEFOU0lPTl9ERVBUSClcclxuICAgICAgcmV0dXJuIHsgZm91bmQ6IGZhbHNlLCBub2Rlc1RvRXhwYW5kOiBbXSB9XHJcblxyXG4gICAgY29uc3Qgbm9kZXNUb0V4cGFuZDogc3RyaW5nW10gPSBbXVxyXG5cclxuICAgIGNvbnN0IGZvdW5kID0gbm9kZXMuc29tZSgobm9kZSkgPT4ge1xyXG4gICAgICBpZiAobm9kZS5yYXc/LmlkID09PSBvYmplY3RJZCkgcmV0dXJuIHRydWVcclxuXHJcbiAgICAgIGlmIChub2RlLmNoaWxkcmVuPy5sZW5ndGgpIHtcclxuICAgICAgICBjb25zdCByZXN1bHQgPSBleHBhbmROb2Rlc1RvU2hvd09iamVjdChcclxuICAgICAgICAgIG5vZGUuY2hpbGRyZW4sXHJcbiAgICAgICAgICBvYmplY3RJZCxcclxuICAgICAgICAgIG1vZGVsSWQsXHJcbiAgICAgICAgICBleHBhbmRlZE5vZGVzLFxyXG4gICAgICAgICAgZGVwdGggKyAxXHJcbiAgICAgICAgKVxyXG4gICAgICAgIGlmIChyZXN1bHQuZm91bmQpIHtcclxuICAgICAgICAgIGlmIChub2RlLnJhdz8uaWQpIG5vZGVzVG9FeHBhbmQucHVzaChub2RlLnJhdy5pZClcclxuICAgICAgICAgIG5vZGVzVG9FeHBhbmQucHVzaCguLi5yZXN1bHQubm9kZXNUb0V4cGFuZClcclxuXHJcbiAgICAgICAgICAvLyBIYW5kbGUgYXJyYXkgY29sbGVjdGlvbnNcclxuICAgICAgICAgIGNvbnN0IHNwZWNrbGVEYXRhID0gbm9kZS5yYXdcclxuICAgICAgICAgIGlmIChzcGVja2xlRGF0YSkge1xyXG4gICAgICAgICAgICBPYmplY3QuZW50cmllcyhzcGVja2xlRGF0YSkuZm9yRWFjaCgoW2ssIHZhbF0pID0+IHtcclxuICAgICAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgICAgICBFWENMVURFRF9DT0xMRUNUSU9OX0tFWVMuaGFzKGsgYXMgJ2NoaWxkcmVuJyB8ICdlbGVtZW50cycpIHx8XHJcbiAgICAgICAgICAgICAgICBrLmluY2x1ZGVzKERJU1BMQVlfVkFMVUVfS0VZKVxyXG4gICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgIHJldHVyblxyXG5cclxuICAgICAgICAgICAgICBpZiAoaXNSZWZlcmVuY2VkSWRBcnJheSh2YWwpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpZHMgPSBuZXcgU2V0KHZhbC5tYXAoKHJlZikgPT4gcmVmLnJlZmVyZW5jZWRJZCkpXHJcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5jaGlsZHJlbj8uc29tZSgoY2hpbGQpID0+IGlkcy5oYXMoY2hpbGQucmF3Py5pZCBhcyBzdHJpbmcpKSkge1xyXG4gICAgICAgICAgICAgICAgICBub2Rlc1RvRXhwYW5kLnB1c2goaylcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH0pXHJcblxyXG4gICAgcmV0dXJuIHsgZm91bmQsIG5vZGVzVG9FeHBhbmQgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGZsYXR0ZW5Nb2RlbFRyZWUsXHJcbiAgICBnZXRSb290Tm9kZXNGb3JNb2RlbCxcclxuICAgIGZpbmRPYmplY3RJbk5vZGVzLFxyXG4gICAgZXhwYW5kTm9kZXNUb1Nob3dPYmplY3QsXHJcbiAgICB0cmVlU3RhdGVNYW5hZ2VyXHJcbiAgfVxyXG59XHJcbiJdLCJmaWxlIjoiRDovc3BlY2tsZS1zZXJ2ZXIvcGFja2FnZXMvZnJvbnRlbmQtMi9saWIvdmlld2VyL2NvbXBvc2FibGVzL3RyZWUudHMifQ==