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

328 lines
48 KiB
Plaintext

import { isStringPropertyInfo } from "/_nuxt/lib/viewer/helpers/sceneExplorer.ts";
import { isNumber, isString, isBoolean, toNumber } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29";
import {
ExistenceFilterCondition,
FilterType
} from "/_nuxt/lib/viewer/helpers/filters/types.ts";
export const revitPropertyRegex = /^parameters\./;
export const revitPropertyRegexDui3000InstanceProps = /^properties\.Instance/;
export const revitPropertyRegexDui3000TypeProps = /^properties\.Type/;
export const isRevitProperty = (key) => {
return revitPropertyRegex.test(key) || revitPropertyRegexDui3000InstanceProps.test(key) || revitPropertyRegexDui3000TypeProps.test(key);
};
export const shouldExcludeFromFiltering = (key) => {
const pathParts = key.split(".");
const lastPart = pathParts[pathParts.length - 1];
if (["definitionId", "transform", "name", "definitionName"].includes(lastPart)) {
return false;
}
if (key.endsWith(".units") || key.endsWith(".speckle_type") || key.includes(".parameters.") || key.includes("renderMaterial") || key.includes(".domain") || key.includes("plane.") || key.includes("baseLine") || key.includes("referenceLine") || key.includes("end.") || key.includes("start.") || key.includes("endPoint.") || key.includes("midPoint.") || key.includes("startPoint.") || key.includes(".materialName") || key.includes(".materialClass") || key.includes(".materialCategory") || key.includes("displayStyle") || key.includes("displayValue") || key.includes("displayMesh") || key.startsWith("__")) {
return true;
}
if (isRevitProperty(key)) {
if (key.endsWith(".value")) return false;
else return true;
}
return false;
};
export const getPropertyName = (key, availableFilters) => {
if (!key) return "Loading";
if (key === "level.name") return "Level Name";
if (key === "speckle_type") return "Object Type";
if (isRevitProperty(key) && key.endsWith(".value")) {
const correspondingProperty = (availableFilters || []).find(
(f) => f.key === key.replace(".value", ".name")
);
if (correspondingProperty && isStringPropertyInfo(correspondingProperty)) {
return correspondingProperty.valueGroups[0]?.value || key.split(".").pop() || key;
}
}
return key.split(".").pop() || key;
};
export const findFilterByDisplayName = (displayKey, availableFilters) => {
if (!availableFilters) return void 0;
const exactDisplayMatch = availableFilters.find((f) => {
const propertyDisplayName = getPropertyName(f.key, availableFilters);
return propertyDisplayName === displayKey;
});
if (exactDisplayMatch) return exactDisplayMatch;
const endMatches = availableFilters.filter((f) => f.key.split(".").pop() === displayKey).sort((a, b) => a.key.length - b.key.length);
return endMatches[0];
};
export const isKvpFilterable = (kvp, availableFilters) => {
const propertyKey = kvp.backendPath || kvp.key;
const directMatch = availableFilters?.some((f) => f.key === propertyKey);
if (directMatch) {
return !shouldExcludeFromFiltering(propertyKey);
}
const displayKey = kvp.key;
const matchByDisplayName = findFilterByDisplayName(displayKey, availableFilters);
if (matchByDisplayName) {
return !shouldExcludeFromFiltering(matchByDisplayName.key);
}
return false;
};
export const getFilterDisabledReason = (kvp, availableFilters) => {
const availableKeys = availableFilters?.map((f) => f.key) || [];
if (kvp.backendPath) {
if (!availableKeys.includes(kvp.backendPath)) {
const propertyName = kvp.key;
const similarPaths = availableKeys.filter(
(key) => key.split(".").pop() === propertyName
);
if (similarPaths.length > 0) {
return `Property path '${kvp.backendPath}' not found. Similar properties: ${similarPaths.slice(0, 3).join(", ")}`;
}
return `Property path '${kvp.backendPath}' is not available in the current scene`;
}
if (shouldExcludeFromFiltering(kvp.backendPath)) {
return `Property '${kvp.backendPath}' is excluded from filtering (technical property)`;
}
} else {
const propertyKey = kvp.key;
if (!availableKeys.includes(propertyKey)) {
const similarKeys = availableKeys.filter(
(key) => key.toLowerCase().includes("type") || key.toLowerCase().includes("category") || key.toLowerCase().includes("class")
);
const debugInfo = similarKeys.length > 0 ? ` (Similar available: ${similarKeys.slice(0, 3).join(", ")})` : "";
return `Property '${propertyKey}' is not available in the current scene${debugInfo}`;
}
if (shouldExcludeFromFiltering(propertyKey)) {
return `Property '${propertyKey}' is excluded from filtering (technical property)`;
}
}
return "This property is not available for filtering";
};
export const findFilterByKvp = (kvp, availableFilters) => {
if (!availableFilters) return void 0;
if (kvp.backendPath) {
const exactMatch = availableFilters.find(
(f) => f.key === kvp.backendPath
);
if (exactMatch) {
return exactMatch;
}
}
const directMatch = availableFilters.find(
(f) => f.key === kvp.key
);
if (directMatch) {
return directMatch;
}
if (kvp.backendPath) {
const pathParts = kvp.backendPath.split(".");
const partialMatches = availableFilters.filter((f) => {
const filterParts = f.key.split(".");
if (pathParts.length === 1) {
return filterParts[filterParts.length - 1] === pathParts[0];
}
if (pathParts.length >= 2 && filterParts.length >= 2) {
const kvpEnd = pathParts.slice(-2).join(".");
const filterEnd = filterParts.slice(-2).join(".");
return kvpEnd === filterEnd;
}
return false;
});
if (partialMatches.length === 1) {
return partialMatches[0];
}
if (partialMatches.length > 1) {
const sortedMatches = partialMatches.sort((a, b) => a.key.length - b.key.length);
return sortedMatches[0];
}
return void 0;
}
const displayKey = kvp.key;
return findFilterByDisplayName(displayKey, availableFilters);
};
export const isBooleanProperty = (filter) => {
return "type" in filter && filter.type === "boolean";
};
export const isValueNumeric = (value) => {
if (isNumber(value)) return Number.isFinite(value);
if (isString(value)) {
const trimmed = value.trim();
if (trimmed === "") return false;
if (/-.*-/.test(trimmed)) return false;
if (trimmed.includes("-") && !trimmed.startsWith("-")) return false;
const converted = toNumber(trimmed);
return Number.isFinite(converted);
}
return false;
};
export const isValueBoolean = (value) => {
if (isBoolean(value)) return true;
if (isString(value)) {
const str = value.toLowerCase();
return str === "true" || str === "false";
}
return false;
};
export const isValueBooleanTrue = (value) => {
return value === true || isString(value) && value.toLowerCase() === "true";
};
export const isValueBooleanFalse = (value) => {
return value === false || isString(value) && value.toLowerCase() === "false";
};
export function getFilterValueCount(filter, value) {
if (!("valueGroups" in filter) || !Array.isArray(filter.valueGroups)) {
return 0;
}
const valueGroups = filter.valueGroups;
for (const vg of valueGroups) {
if (String(vg.value) === value) {
return vg.ids?.length ?? 0;
}
}
return 0;
}
export function getExistenceFilterCount(filter, condition, totalObjectCount) {
if (!("valueGroups" in filter) || !Array.isArray(filter.valueGroups)) {
return filter.objectCount ?? 0;
}
const hasIndividualIds = filter.valueGroups.length > 0 && "id" in filter.valueGroups[0] && !("ids" in filter.valueGroups[0]);
const objectsWithProperty = hasIndividualIds ? filter.valueGroups.length : filter.valueGroups.reduce((total, vg) => {
if ("ids" in vg && Array.isArray(vg.ids)) {
return total + vg.ids.length;
}
return total;
}, 0);
if (condition === ExistenceFilterCondition.IsSet) {
return objectsWithProperty;
} else {
const relevantObjectCount = filter.objectCount ?? totalObjectCount ?? 0;
return Math.max(0, relevantObjectCount - objectsWithProperty);
}
}
export function injectGradientDataIntoDataStore(filteringDataStore, propertyKey, gradientValues) {
if (!filteringDataStore || Object.keys(gradientValues).length === 0) {
return;
}
const store = filteringDataStore;
if (!store.dataSources?.value) {
return;
}
for (const dataSource of store.dataSources.value) {
for (const [objectId, { gradientValue }] of Object.entries(gradientValues)) {
if (dataSource.objectProperties[objectId]) {
dataSource.objectProperties[objectId][propertyKey] = gradientValue;
}
}
if (!dataSource.propertyMap[propertyKey]) {
dataSource.propertyMap[propertyKey] = {
concatenatedPath: propertyKey,
value: Object.values(gradientValues)[0]?.gradientValue || 0,
type: FilterType.Numeric
};
}
}
}
export const extractNestedProperties = (obj, currentPath = [], knownObjectType, rootObj) => {
const properties = [];
rootObj = rootObj ?? obj;
knownObjectType = knownObjectType ?? (obj.speckle_type === "Objects.Data.DataObject:Objects.Data.RevitObject" ? "revit" : void 0);
for (const key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key) || key === "__closure" || key === "displayValue" || knownObjectType === "revit" && (key === "location" || key === "elements"))
continue;
if (knownObjectType === "revit" && key === "Material Quantities") {
extractMaterialProperties(
obj[key],
[...currentPath, key],
properties
);
continue;
}
if (knownObjectType === "revit" && key === "Structure" && currentPath[currentPath.length - 1] === "Type Parameters") {
continue;
}
const value = obj[key];
const newPath = [...currentPath, key];
const isParam = value && isParameter(value);
const isActualObject = typeof value === "object" && value !== null && !Array.isArray(value) && !isParam;
if (isActualObject) {
properties.push(
...extractNestedProperties(
value,
newPath,
knownObjectType,
rootObj
)
);
} else if (isParam) {
const param = value;
properties.push({
name: key,
path: newPath,
concatenatedPath: newPath.join("."),
type: getValueType(param.value),
units: param.units
});
} else {
const valueType = getValueType(value);
properties.push({
name: key,
path: newPath,
concatenatedPath: newPath.join("."),
type: valueType
});
}
}
return properties;
};
function getValueType(value) {
if (value === null) return "null";
if (Array.isArray(value)) return "array";
if (isValueBoolean(value)) return "boolean";
if (isValueNumeric(value)) return "number";
return "string";
}
function extractMaterialProperties(matQuants, path, properties) {
for (const matName in matQuants) {
const matInfo = matQuants[matName];
const areaProp = matInfo.area ? {
path,
concatenatedPath: path.join("."),
type: "number",
name: `${matName} - area`,
value: matInfo.area.value,
units: matInfo.area.units,
materialCategory: matInfo.materialCategory,
materialClass: matInfo.materialClass
} : void 0;
const volumeProp = matInfo.volume ? {
path,
concatenatedPath: path.join("."),
type: "number",
name: `${matName} - volume`,
value: matInfo.volume.value,
units: matInfo.volume.units,
materialCategory: matInfo.materialCategory,
materialClass: matInfo.materialClass
} : void 0;
if (areaProp) properties.push(areaProp);
if (volumeProp) properties.push(volumeProp);
}
}
export function isParameter(value) {
return typeof value === "object" && Object.hasOwn(value, "name") && Object.hasOwn(value, "value");
}
export function isRevitMaterialQuantity(value) {
return typeof value === "object" && isParameter(value) && Object.hasOwn(value, "materialCategory") && Object.hasOwn(value, "materialClass");
}
export function getNestedProperties(obj, properties) {
const values = [];
for (const prop of properties) {
const value = prop.path.reduce(
(current, key) => current?.[key],
obj
);
if (value && isParameter(value)) {
values.push(value.value);
} else {
values.push(value ?? void 0);
}
}
return values;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInV0aWxzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlzU3RyaW5nUHJvcGVydHlJbmZvIH0gZnJvbSAnfi9saWIvdmlld2VyL2hlbHBlcnMvc2NlbmVFeHBsb3JlcidcclxuaW1wb3J0IHsgaXNOdW1iZXIsIGlzU3RyaW5nLCBpc0Jvb2xlYW4sIHRvTnVtYmVyIH0gZnJvbSAnbG9kYXNoLWVzJ1xyXG5pbXBvcnQge1xyXG4gIEV4aXN0ZW5jZUZpbHRlckNvbmRpdGlvbixcclxuICBGaWx0ZXJUeXBlLFxyXG4gIHR5cGUgQm9vbGVhblByb3BlcnR5SW5mbyxcclxuICB0eXBlIERhdGFTb3VyY2UsXHJcbiAgdHlwZSBFeHRlbmRlZFByb3BlcnR5SW5mbyxcclxuICB0eXBlIFByb3BlcnR5SW5mb0Jhc2UsXHJcbiAgdHlwZSBQcm9wZXJ0eUluZm9WYWx1ZSxcclxuICB0eXBlIFBhcmFtZXRlcixcclxuICB0eXBlIFJldml0TWF0ZXJpYWxQcm9wZXJ0eUluZm8sXHJcbiAgdHlwZSBSZXZpdE1hdGVyaWFsSW5mb1xyXG59IGZyb20gJ34vbGliL3ZpZXdlci9oZWxwZXJzL2ZpbHRlcnMvdHlwZXMnXHJcblxyXG5leHBvcnQgY29uc3QgcmV2aXRQcm9wZXJ0eVJlZ2V4ID0gL15wYXJhbWV0ZXJzXFwuL1xyXG5leHBvcnQgY29uc3QgcmV2aXRQcm9wZXJ0eVJlZ2V4RHVpMzAwMEluc3RhbmNlUHJvcHMgPSAvXnByb3BlcnRpZXNcXC5JbnN0YW5jZS9cclxuZXhwb3J0IGNvbnN0IHJldml0UHJvcGVydHlSZWdleER1aTMwMDBUeXBlUHJvcHMgPSAvXnByb3BlcnRpZXNcXC5UeXBlL1xyXG5cclxuLyoqXHJcbiAqIERldGVybWluZXMgaWYgYSBwcm9wZXJ0eSBrZXkgcmVwcmVzZW50cyBhIFJldml0IHByb3BlcnR5XHJcbiAqL1xyXG5leHBvcnQgY29uc3QgaXNSZXZpdFByb3BlcnR5ID0gKGtleTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XHJcbiAgcmV0dXJuIChcclxuICAgIHJldml0UHJvcGVydHlSZWdleC50ZXN0KGtleSkgfHxcclxuICAgIHJldml0UHJvcGVydHlSZWdleER1aTMwMDBJbnN0YW5jZVByb3BzLnRlc3Qoa2V5KSB8fFxyXG4gICAgcmV2aXRQcm9wZXJ0eVJlZ2V4RHVpMzAwMFR5cGVQcm9wcy50ZXN0KGtleSlcclxuICApXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBEZXRlcm1pbmVzIGlmIGEgcHJvcGVydHkgc2hvdWxkIGJlIGV4Y2x1ZGVkIGZyb20gZmlsdGVyaW5nIGJhc2VkIG9uIGl0cyBrZXlcclxuICovXHJcbmV4cG9ydCBjb25zdCBzaG91bGRFeGNsdWRlRnJvbUZpbHRlcmluZyA9IChrZXk6IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xyXG4gIC8vIFdoaXRlbGlzdCBlc3NlbnRpYWwgaW5zdGFuY2UgcHJvcGVydGllc1xyXG4gIGNvbnN0IHBhdGhQYXJ0cyA9IGtleS5zcGxpdCgnLicpXHJcbiAgY29uc3QgbGFzdFBhcnQgPSBwYXRoUGFydHNbcGF0aFBhcnRzLmxlbmd0aCAtIDFdXHJcblxyXG4gIC8vIEFsd2F5cyBpbmNsdWRlIHRoZXNlIGluc3RhbmNlLXJlbGF0ZWQgcHJvcGVydGllc1xyXG4gIGlmIChbJ2RlZmluaXRpb25JZCcsICd0cmFuc2Zvcm0nLCAnbmFtZScsICdkZWZpbml0aW9uTmFtZSddLmluY2x1ZGVzKGxhc3RQYXJ0KSkge1xyXG4gICAgcmV0dXJuIGZhbHNlXHJcbiAgfVxyXG5cclxuICBpZiAoXHJcbiAgICBrZXkuZW5kc1dpdGgoJy51bml0cycpIHx8XHJcbiAgICBrZXkuZW5kc1dpdGgoJy5zcGVja2xlX3R5cGUnKSB8fFxyXG4gICAga2V5LmluY2x1ZGVzKCcucGFyYW1ldGVycy4nKSB8fFxyXG4gICAga2V5LmluY2x1ZGVzKCdyZW5kZXJNYXRlcmlhbCcpIHx8XHJcbiAgICBrZXkuaW5jbHVkZXMoJy5kb21haW4nKSB8fFxyXG4gICAga2V5LmluY2x1ZGVzKCdwbGFuZS4nKSB8fFxyXG4gICAga2V5LmluY2x1ZGVzKCdiYXNlTGluZScpIHx8XHJcbiAgICBrZXkuaW5jbHVkZXMoJ3JlZmVyZW5jZUxpbmUnKSB8fFxyXG4gICAga2V5LmluY2x1ZGVzKCdlbmQuJykgfHxcclxuICAgIGtleS5pbmNsdWRlcygnc3RhcnQuJykgfHxcclxuICAgIGtleS5pbmNsdWRlcygnZW5kUG9pbnQuJykgfHxcclxuICAgIGtleS5pbmNsdWRlcygnbWlkUG9pbnQuJykgfHxcclxuICAgIGtleS5pbmNsdWRlcygnc3RhcnRQb2ludC4nKSB8fFxyXG4gICAga2V5LmluY2x1ZGVzKCcubWF0ZXJpYWxOYW1lJykgfHxcclxuICAgIGtleS5pbmNsdWRlcygnLm1hdGVyaWFsQ2xhc3MnKSB8fFxyXG4gICAga2V5LmluY2x1ZGVzKCcubWF0ZXJpYWxDYXRlZ29yeScpIHx8XHJcbiAgICBrZXkuaW5jbHVkZXMoJ2Rpc3BsYXlTdHlsZScpIHx8XHJcbiAgICBrZXkuaW5jbHVkZXMoJ2Rpc3BsYXlWYWx1ZScpIHx8XHJcbiAgICBrZXkuaW5jbHVkZXMoJ2Rpc3BsYXlNZXNoJykgfHxcclxuICAgIGtleS5zdGFydHNXaXRoKCdfXycpXHJcbiAgKSB7XHJcbiAgICByZXR1cm4gdHJ1ZVxyXG4gIH1cclxuXHJcbiAgaWYgKGlzUmV2aXRQcm9wZXJ0eShrZXkpKSB7XHJcbiAgICBpZiAoa2V5LmVuZHNXaXRoKCcudmFsdWUnKSkgcmV0dXJuIGZhbHNlXHJcbiAgICBlbHNlIHJldHVybiB0cnVlXHJcbiAgfVxyXG5cclxuICByZXR1cm4gZmFsc2VcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgYSB1c2VyLWZyaWVuZGx5IGRpc3BsYXkgbmFtZSBmb3IgYSBwcm9wZXJ0eSBrZXlcclxuICovXHJcbmV4cG9ydCBjb25zdCBnZXRQcm9wZXJ0eU5hbWUgPSAoXHJcbiAga2V5OiBzdHJpbmcsXHJcbiAgYXZhaWxhYmxlRmlsdGVycz86IEV4dGVuZGVkUHJvcGVydHlJbmZvW10gfCBudWxsXHJcbik6IHN0cmluZyA9PiB7XHJcbiAgaWYgKCFrZXkpIHJldHVybiAnTG9hZGluZydcclxuXHJcbiAgaWYgKGtleSA9PT0gJ2xldmVsLm5hbWUnKSByZXR1cm4gJ0xldmVsIE5hbWUnXHJcbiAgaWYgKGtleSA9PT0gJ3NwZWNrbGVfdHlwZScpIHJldHVybiAnT2JqZWN0IFR5cGUnXHJcblxyXG4gIGlmIChpc1Jldml0UHJvcGVydHkoa2V5KSAmJiBrZXkuZW5kc1dpdGgoJy52YWx1ZScpKSB7XHJcbiAgICBjb25zdCBjb3JyZXNwb25kaW5nUHJvcGVydHkgPSAoYXZhaWxhYmxlRmlsdGVycyB8fCBbXSkuZmluZChcclxuICAgICAgKGY6IEV4dGVuZGVkUHJvcGVydHlJbmZvKSA9PiBmLmtleSA9PT0ga2V5LnJlcGxhY2UoJy52YWx1ZScsICcubmFtZScpXHJcbiAgICApXHJcbiAgICBpZiAoY29ycmVzcG9uZGluZ1Byb3BlcnR5ICYmIGlzU3RyaW5nUHJvcGVydHlJbmZvKGNvcnJlc3BvbmRpbmdQcm9wZXJ0eSkpIHtcclxuICAgICAgcmV0dXJuIGNvcnJlc3BvbmRpbmdQcm9wZXJ0eS52YWx1ZUdyb3Vwc1swXT8udmFsdWUgfHwga2V5LnNwbGl0KCcuJykucG9wKCkgfHwga2V5XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4ga2V5LnNwbGl0KCcuJykucG9wKCkgfHwga2V5XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGaW5kcyBhIGZpbHRlciBieSBtYXRjaGluZyBkaXNwbGF5IG5hbWVzXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgZmluZEZpbHRlckJ5RGlzcGxheU5hbWUgPSAoXHJcbiAgZGlzcGxheUtleTogc3RyaW5nLFxyXG4gIGF2YWlsYWJsZUZpbHRlcnM6IEV4dGVuZGVkUHJvcGVydHlJbmZvW10gfCBudWxsIHwgdW5kZWZpbmVkXHJcbik6IEV4dGVuZGVkUHJvcGVydHlJbmZvIHwgdW5kZWZpbmVkID0+IHtcclxuICBpZiAoIWF2YWlsYWJsZUZpbHRlcnMpIHJldHVybiB1bmRlZmluZWRcclxuXHJcbiAgLy8gRmlyc3QsIHRyeSB0byBmaW5kIGFuIGV4YWN0IGRpc3BsYXkgbmFtZSBtYXRjaFxyXG4gIGNvbnN0IGV4YWN0RGlzcGxheU1hdGNoID0gYXZhaWxhYmxlRmlsdGVycy5maW5kKChmKSA9PiB7XHJcbiAgICBjb25zdCBwcm9wZXJ0eURpc3BsYXlOYW1lID0gZ2V0UHJvcGVydHlOYW1lKGYua2V5LCBhdmFpbGFibGVGaWx0ZXJzKVxyXG4gICAgcmV0dXJuIHByb3BlcnR5RGlzcGxheU5hbWUgPT09IGRpc3BsYXlLZXlcclxuICB9KVxyXG4gIGlmIChleGFjdERpc3BsYXlNYXRjaCkgcmV0dXJuIGV4YWN0RGlzcGxheU1hdGNoXHJcblxyXG4gIC8vIFRoZW4gdHJ5IHRvIGZpbmQgYSBtYXRjaCB3aGVyZSB0aGUga2V5IGVuZHMgd2l0aCB0aGUgZGlzcGxheSBrZXlcclxuICBjb25zdCBlbmRNYXRjaGVzID0gYXZhaWxhYmxlRmlsdGVyc1xyXG4gICAgLmZpbHRlcigoZikgPT4gZi5rZXkuc3BsaXQoJy4nKS5wb3AoKSA9PT0gZGlzcGxheUtleSlcclxuICAgIC5zb3J0KChhLCBiKSA9PiBhLmtleS5sZW5ndGggLSBiLmtleS5sZW5ndGgpIC8vIFNob3J0ZXIgcGF0aHMgZmlyc3RcclxuXHJcbiAgcmV0dXJuIGVuZE1hdGNoZXNbMF0gLy8gUmV0dXJuIHRoZSBzaG9ydGVzdCBtYXRjaGluZyBwYXRoXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBEZXRlcm1pbmVzIGlmIGEga2V5LXZhbHVlIHBhaXIgaXMgZmlsdGVyYWJsZSAod2l0aCBzbWFydCBtYXRjaGluZyBmb3IgbmVzdGVkIHByb3BlcnRpZXMpXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgaXNLdnBGaWx0ZXJhYmxlID0gKFxyXG4gIGt2cDogeyBrZXk6IHN0cmluZzsgYmFja2VuZFBhdGg/OiBzdHJpbmcgfSxcclxuICBhdmFpbGFibGVGaWx0ZXJzOiBFeHRlbmRlZFByb3BlcnR5SW5mb1tdIHwgbnVsbCB8IHVuZGVmaW5lZFxyXG4pOiBib29sZWFuID0+IHtcclxuICAvLyBVc2UgYmFja2VuZFBhdGggZm9yIGxlZ2FjeSBjb21wYXRpYmlsaXR5LCBidXQgcHJlZmVyIHRoZSBkaXJlY3Qga2V5XHJcbiAgY29uc3QgcHJvcGVydHlLZXkgPSBrdnAuYmFja2VuZFBhdGggfHwga3ZwLmtleVxyXG5cclxuICBjb25zdCBkaXJlY3RNYXRjaCA9IGF2YWlsYWJsZUZpbHRlcnM/LnNvbWUoKGYpID0+IGYua2V5ID09PSBwcm9wZXJ0eUtleSlcclxuICBpZiAoZGlyZWN0TWF0Y2gpIHtcclxuICAgIHJldHVybiAhc2hvdWxkRXhjbHVkZUZyb21GaWx0ZXJpbmcocHJvcGVydHlLZXkpXHJcbiAgfVxyXG5cclxuICBjb25zdCBkaXNwbGF5S2V5ID0ga3ZwLmtleSBhcyBzdHJpbmdcclxuICBjb25zdCBtYXRjaEJ5RGlzcGxheU5hbWUgPSBmaW5kRmlsdGVyQnlEaXNwbGF5TmFtZShkaXNwbGF5S2V5LCBhdmFpbGFibGVGaWx0ZXJzKVxyXG5cclxuICBpZiAobWF0Y2hCeURpc3BsYXlOYW1lKSB7XHJcbiAgICByZXR1cm4gIXNob3VsZEV4Y2x1ZGVGcm9tRmlsdGVyaW5nKG1hdGNoQnlEaXNwbGF5TmFtZS5rZXkpXHJcbiAgfVxyXG5cclxuICByZXR1cm4gZmFsc2VcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgYSBkZXRhaWxlZCByZWFzb24gd2h5IGEgcHJvcGVydHkgaXMgZGlzYWJsZWQgZm9yIGZpbHRlcmluZ1xyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGdldEZpbHRlckRpc2FibGVkUmVhc29uID0gKFxyXG4gIGt2cDogeyBrZXk6IHN0cmluZzsgYmFja2VuZFBhdGg/OiBzdHJpbmcgfSxcclxuICBhdmFpbGFibGVGaWx0ZXJzOiBFeHRlbmRlZFByb3BlcnR5SW5mb1tdIHwgbnVsbCB8IHVuZGVmaW5lZFxyXG4pOiBzdHJpbmcgPT4ge1xyXG4gIGNvbnN0IGF2YWlsYWJsZUtleXMgPSBhdmFpbGFibGVGaWx0ZXJzPy5tYXAoKGYpID0+IGYua2V5KSB8fCBbXVxyXG5cclxuICBpZiAoa3ZwLmJhY2tlbmRQYXRoKSB7XHJcbiAgICBpZiAoIWF2YWlsYWJsZUtleXMuaW5jbHVkZXMoa3ZwLmJhY2tlbmRQYXRoKSkge1xyXG4gICAgICBjb25zdCBwcm9wZXJ0eU5hbWUgPSBrdnAua2V5XHJcbiAgICAgIGNvbnN0IHNpbWlsYXJQYXRocyA9IGF2YWlsYWJsZUtleXMuZmlsdGVyKFxyXG4gICAgICAgIChrZXkpID0+IGtleS5zcGxpdCgnLicpLnBvcCgpID09PSBwcm9wZXJ0eU5hbWVcclxuICAgICAgKVxyXG5cclxuICAgICAgaWYgKHNpbWlsYXJQYXRocy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuIGBQcm9wZXJ0eSBwYXRoICcke1xyXG4gICAgICAgICAga3ZwLmJhY2tlbmRQYXRoXHJcbiAgICAgICAgfScgbm90IGZvdW5kLiBTaW1pbGFyIHByb3BlcnRpZXM6ICR7c2ltaWxhclBhdGhzLnNsaWNlKDAsIDMpLmpvaW4oJywgJyl9YFxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gYFByb3BlcnR5IHBhdGggJyR7a3ZwLmJhY2tlbmRQYXRofScgaXMgbm90IGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBzY2VuZWBcclxuICAgIH1cclxuXHJcbiAgICBpZiAoc2hvdWxkRXhjbHVkZUZyb21GaWx0ZXJpbmcoa3ZwLmJhY2tlbmRQYXRoKSkge1xyXG4gICAgICByZXR1cm4gYFByb3BlcnR5ICcke2t2cC5iYWNrZW5kUGF0aH0nIGlzIGV4Y2x1ZGVkIGZyb20gZmlsdGVyaW5nICh0ZWNobmljYWwgcHJvcGVydHkpYFxyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICAvLyBGYWxsYmFjayB0byBrZXktYmFzZWQgY2hlY2tpbmdcclxuICAgIGNvbnN0IHByb3BlcnR5S2V5ID0ga3ZwLmtleVxyXG4gICAgaWYgKCFhdmFpbGFibGVLZXlzLmluY2x1ZGVzKHByb3BlcnR5S2V5KSkge1xyXG4gICAgICBjb25zdCBzaW1pbGFyS2V5cyA9IGF2YWlsYWJsZUtleXMuZmlsdGVyKFxyXG4gICAgICAgIChrZXkpID0+XHJcbiAgICAgICAgICBrZXkudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygndHlwZScpIHx8XHJcbiAgICAgICAgICBrZXkudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnY2F0ZWdvcnknKSB8fFxyXG4gICAgICAgICAga2V5LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2NsYXNzJylcclxuICAgICAgKVxyXG5cclxuICAgICAgY29uc3QgZGVidWdJbmZvID1cclxuICAgICAgICBzaW1pbGFyS2V5cy5sZW5ndGggPiAwXHJcbiAgICAgICAgICA/IGAgKFNpbWlsYXIgYXZhaWxhYmxlOiAke3NpbWlsYXJLZXlzLnNsaWNlKDAsIDMpLmpvaW4oJywgJyl9KWBcclxuICAgICAgICAgIDogJydcclxuXHJcbiAgICAgIHJldHVybiBgUHJvcGVydHkgJyR7cHJvcGVydHlLZXl9JyBpcyBub3QgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IHNjZW5lJHtkZWJ1Z0luZm99YFxyXG4gICAgfVxyXG5cclxuICAgIGlmIChzaG91bGRFeGNsdWRlRnJvbUZpbHRlcmluZyhwcm9wZXJ0eUtleSkpIHtcclxuICAgICAgcmV0dXJuIGBQcm9wZXJ0eSAnJHtwcm9wZXJ0eUtleX0nIGlzIGV4Y2x1ZGVkIGZyb20gZmlsdGVyaW5nICh0ZWNobmljYWwgcHJvcGVydHkpYFxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuICdUaGlzIHByb3BlcnR5IGlzIG5vdCBhdmFpbGFibGUgZm9yIGZpbHRlcmluZydcclxufVxyXG5cclxuLyoqXHJcbiAqIEZpbmRzIGEgZmlsdGVyIGZvciBhIGtleS12YWx1ZSBwYWlyIHVzaW5nIHNtYXJ0IG1hdGNoaW5nIGxvZ2ljXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgZmluZEZpbHRlckJ5S3ZwID0gKFxyXG4gIGt2cDogeyBrZXk6IHN0cmluZzsgYmFja2VuZFBhdGg/OiBzdHJpbmcgfSxcclxuICBhdmFpbGFibGVGaWx0ZXJzOiBFeHRlbmRlZFByb3BlcnR5SW5mb1tdIHwgbnVsbCB8IHVuZGVmaW5lZFxyXG4pOiBFeHRlbmRlZFByb3BlcnR5SW5mbyB8IHVuZGVmaW5lZCA9PiB7XHJcbiAgaWYgKCFhdmFpbGFibGVGaWx0ZXJzKSByZXR1cm4gdW5kZWZpbmVkXHJcblxyXG4gIGlmIChrdnAuYmFja2VuZFBhdGgpIHtcclxuICAgIGNvbnN0IGV4YWN0TWF0Y2ggPSBhdmFpbGFibGVGaWx0ZXJzLmZpbmQoXHJcbiAgICAgIChmOiBFeHRlbmRlZFByb3BlcnR5SW5mbykgPT4gZi5rZXkgPT09IGt2cC5iYWNrZW5kUGF0aFxyXG4gICAgKVxyXG4gICAgaWYgKGV4YWN0TWF0Y2gpIHtcclxuICAgICAgcmV0dXJuIGV4YWN0TWF0Y2hcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNvbnN0IGRpcmVjdE1hdGNoID0gYXZhaWxhYmxlRmlsdGVycy5maW5kKFxyXG4gICAgKGY6IEV4dGVuZGVkUHJvcGVydHlJbmZvKSA9PiBmLmtleSA9PT0ga3ZwLmtleVxyXG4gIClcclxuICBpZiAoZGlyZWN0TWF0Y2gpIHtcclxuICAgIHJldHVybiBkaXJlY3RNYXRjaFxyXG4gIH1cclxuXHJcbiAgLy8gSWYgd2UgaGF2ZSBhIGJhY2tlbmRQYXRoIGJ1dCBubyBleGFjdCBtYXRjaCwgdHJ5IHBhcnRpYWwgbWF0Y2hpbmdcclxuICBpZiAoa3ZwLmJhY2tlbmRQYXRoKSB7XHJcbiAgICBjb25zdCBwYXRoUGFydHMgPSBrdnAuYmFja2VuZFBhdGguc3BsaXQoJy4nKVxyXG4gICAgY29uc3QgcGFydGlhbE1hdGNoZXMgPSBhdmFpbGFibGVGaWx0ZXJzLmZpbHRlcigoZjogRXh0ZW5kZWRQcm9wZXJ0eUluZm8pID0+IHtcclxuICAgICAgY29uc3QgZmlsdGVyUGFydHMgPSBmLmtleS5zcGxpdCgnLicpXHJcblxyXG4gICAgICBpZiAocGF0aFBhcnRzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgIHJldHVybiBmaWx0ZXJQYXJ0c1tmaWx0ZXJQYXJ0cy5sZW5ndGggLSAxXSA9PT0gcGF0aFBhcnRzWzBdXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChwYXRoUGFydHMubGVuZ3RoID49IDIgJiYgZmlsdGVyUGFydHMubGVuZ3RoID49IDIpIHtcclxuICAgICAgICBjb25zdCBrdnBFbmQgPSBwYXRoUGFydHMuc2xpY2UoLTIpLmpvaW4oJy4nKVxyXG4gICAgICAgIGNvbnN0IGZpbHRlckVuZCA9IGZpbHRlclBhcnRzLnNsaWNlKC0yKS5qb2luKCcuJylcclxuICAgICAgICByZXR1cm4ga3ZwRW5kID09PSBmaWx0ZXJFbmRcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICB9KVxyXG5cclxuICAgIGlmIChwYXJ0aWFsTWF0Y2hlcy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgcmV0dXJuIHBhcnRpYWxNYXRjaGVzWzBdXHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHBhcnRpYWxNYXRjaGVzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgY29uc3Qgc29ydGVkTWF0Y2hlcyA9IHBhcnRpYWxNYXRjaGVzLnNvcnQoKGEsIGIpID0+IGEua2V5Lmxlbmd0aCAtIGIua2V5Lmxlbmd0aClcclxuICAgICAgcmV0dXJuIHNvcnRlZE1hdGNoZXNbMF1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdW5kZWZpbmVkXHJcbiAgfVxyXG5cclxuICAvLyBPbmx5IGZhbGwgYmFjayB0byBmdXp6eSBtYXRjaGluZyBpZiBubyBiYWNrZW5kUGF0aCBpcyBwcm92aWRlZCAobGVnYWN5IHN1cHBvcnQpXHJcbiAgY29uc3QgZGlzcGxheUtleSA9IGt2cC5rZXkgYXMgc3RyaW5nXHJcbiAgcmV0dXJuIGZpbmRGaWx0ZXJCeURpc3BsYXlOYW1lKGRpc3BsYXlLZXksIGF2YWlsYWJsZUZpbHRlcnMpXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBpc0Jvb2xlYW5Qcm9wZXJ0eSA9IChmaWx0ZXI6IEV4dGVuZGVkUHJvcGVydHlJbmZvKTogYm9vbGVhbiA9PiB7XHJcbiAgcmV0dXJuICd0eXBlJyBpbiBmaWx0ZXIgJiYgKGZpbHRlciBhcyB7IHR5cGU6IHN0cmluZyB9KS50eXBlID09PSAnYm9vbGVhbidcclxufVxyXG5cclxuLyoqXHJcbiAqIERldGVybWluZXMgaWYgYSB2YWx1ZSBzaG91bGQgYmUgdHJlYXRlZCBhcyBudW1lcmljIGZvciBmaWx0ZXJpbmdcclxuICovXHJcbmV4cG9ydCBjb25zdCBpc1ZhbHVlTnVtZXJpYyA9ICh2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4gPT4ge1xyXG4gIGlmIChpc051bWJlcih2YWx1ZSkpIHJldHVybiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpXHJcblxyXG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcclxuICAgIGNvbnN0IHRyaW1tZWQgPSB2YWx1ZS50cmltKClcclxuICAgIGlmICh0cmltbWVkID09PSAnJykgcmV0dXJuIGZhbHNlXHJcblxyXG4gICAgLy8gQWxsb3c6IGRpZ2l0cywgZGVjaW1hbCBwb2ludHMsIG1pbnVzIHNpZ24gYXQgc3RhcnRcclxuICAgIGlmICgvLS4qLS8udGVzdCh0cmltbWVkKSkgcmV0dXJuIGZhbHNlIC8vIE11bHRpcGxlIGRhc2hlcyAoVVVJRCBwYXR0ZXJuKVxyXG4gICAgaWYgKHRyaW1tZWQuaW5jbHVkZXMoJy0nKSAmJiAhdHJpbW1lZC5zdGFydHNXaXRoKCctJykpIHJldHVybiBmYWxzZSAvLyBEYXNoIG5vdCBhdCB0aGUgc3RhcnRcclxuXHJcbiAgICBjb25zdCBjb252ZXJ0ZWQgPSB0b051bWJlcih0cmltbWVkKVxyXG4gICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShjb252ZXJ0ZWQpXHJcbiAgfVxyXG5cclxuICByZXR1cm4gZmFsc2VcclxufVxyXG5cclxuLyoqXHJcbiAqIERldGVybWluZXMgaWYgYSB2YWx1ZSBzaG91bGQgYmUgdHJlYXRlZCBhcyBib29sZWFuIGZvciBmaWx0ZXJpbmcgKGNhc2UtaW5zZW5zaXRpdmUpXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgaXNWYWx1ZUJvb2xlYW4gPSAodmFsdWU6IHVua25vd24pOiBib29sZWFuID0+IHtcclxuICBpZiAoaXNCb29sZWFuKHZhbHVlKSkgcmV0dXJuIHRydWVcclxuICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XHJcbiAgICBjb25zdCBzdHIgPSB2YWx1ZS50b0xvd2VyQ2FzZSgpXHJcbiAgICByZXR1cm4gc3RyID09PSAndHJ1ZScgfHwgc3RyID09PSAnZmFsc2UnXHJcbiAgfVxyXG4gIHJldHVybiBmYWxzZVxyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGlmIGEgdmFsdWUgcmVwcmVzZW50cyBib29sZWFuIHRydWUgKGNhc2UtaW5zZW5zaXRpdmUpXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgaXNWYWx1ZUJvb2xlYW5UcnVlID0gKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiA9PiB7XHJcbiAgcmV0dXJuIHZhbHVlID09PSB0cnVlIHx8IChpc1N0cmluZyh2YWx1ZSkgJiYgdmFsdWUudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnKVxyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGlmIGEgdmFsdWUgcmVwcmVzZW50cyBib29sZWFuIGZhbHNlIChjYXNlLWluc2Vuc2l0aXZlKVxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGlzVmFsdWVCb29sZWFuRmFsc2UgPSAodmFsdWU6IHVua25vd24pOiBib29sZWFuID0+IHtcclxuICByZXR1cm4gdmFsdWUgPT09IGZhbHNlIHx8IChpc1N0cmluZyh2YWx1ZSkgJiYgdmFsdWUudG9Mb3dlckNhc2UoKSA9PT0gJ2ZhbHNlJylcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBjb3VudCBmb3IgYSBzcGVjaWZpYyBmaWx0ZXIgdmFsdWVcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGaWx0ZXJWYWx1ZUNvdW50KFxyXG4gIGZpbHRlcjogRXh0ZW5kZWRQcm9wZXJ0eUluZm8sXHJcbiAgdmFsdWU6IHN0cmluZ1xyXG4pOiBudW1iZXIge1xyXG4gIGlmICghKCd2YWx1ZUdyb3VwcycgaW4gZmlsdGVyKSB8fCAhQXJyYXkuaXNBcnJheShmaWx0ZXIudmFsdWVHcm91cHMpKSB7XHJcbiAgICByZXR1cm4gMFxyXG4gIH1cclxuXHJcbiAgY29uc3QgdmFsdWVHcm91cHMgPSBmaWx0ZXIudmFsdWVHcm91cHMgYXMgQXJyYXk8eyB2YWx1ZTogdW5rbm93bjsgaWRzPzogc3RyaW5nW10gfT5cclxuXHJcbiAgZm9yIChjb25zdCB2ZyBvZiB2YWx1ZUdyb3Vwcykge1xyXG4gICAgaWYgKFN0cmluZyh2Zy52YWx1ZSkgPT09IHZhbHVlKSB7XHJcbiAgICAgIHJldHVybiB2Zy5pZHM/Lmxlbmd0aCA/PyAwXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gMFxyXG59XHJcblxyXG4vKipcclxuICogR2V0IGNvdW50IGZvciBleGlzdGVuY2UgZmlsdGVycyAob2JqZWN0cyB0aGF0IGhhdmUvZG9uJ3QgaGF2ZSBhIHByb3BlcnR5IHNldClcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRFeGlzdGVuY2VGaWx0ZXJDb3VudChcclxuICBmaWx0ZXI6IEV4dGVuZGVkUHJvcGVydHlJbmZvIHwgQm9vbGVhblByb3BlcnR5SW5mbyxcclxuICBjb25kaXRpb246IEV4aXN0ZW5jZUZpbHRlckNvbmRpdGlvbixcclxuICB0b3RhbE9iamVjdENvdW50PzogbnVtYmVyXHJcbik6IG51bWJlciB7XHJcbiAgaWYgKCEoJ3ZhbHVlR3JvdXBzJyBpbiBmaWx0ZXIpIHx8ICFBcnJheS5pc0FycmF5KGZpbHRlci52YWx1ZUdyb3VwcykpIHtcclxuICAgIHJldHVybiBmaWx0ZXIub2JqZWN0Q291bnQgPz8gMFxyXG4gIH1cclxuXHJcbiAgY29uc3QgaGFzSW5kaXZpZHVhbElkcyA9XHJcbiAgICBmaWx0ZXIudmFsdWVHcm91cHMubGVuZ3RoID4gMCAmJlxyXG4gICAgJ2lkJyBpbiBmaWx0ZXIudmFsdWVHcm91cHNbMF0gJiZcclxuICAgICEoJ2lkcycgaW4gZmlsdGVyLnZhbHVlR3JvdXBzWzBdKVxyXG5cclxuICBjb25zdCBvYmplY3RzV2l0aFByb3BlcnR5ID0gaGFzSW5kaXZpZHVhbElkc1xyXG4gICAgPyBmaWx0ZXIudmFsdWVHcm91cHMubGVuZ3RoIC8vIEVhY2ggdmFsdWVHcm91cCA9IG9uZSBvYmplY3RcclxuICAgIDogZmlsdGVyLnZhbHVlR3JvdXBzLnJlZHVjZSgodG90YWwsIHZnKSA9PiB7XHJcbiAgICAgICAgaWYgKCdpZHMnIGluIHZnICYmIEFycmF5LmlzQXJyYXkodmcuaWRzKSkge1xyXG4gICAgICAgICAgcmV0dXJuIHRvdGFsICsgdmcuaWRzLmxlbmd0aFxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdG90YWxcclxuICAgICAgfSwgMClcclxuXHJcbiAgaWYgKGNvbmRpdGlvbiA9PT0gRXhpc3RlbmNlRmlsdGVyQ29uZGl0aW9uLklzU2V0KSB7XHJcbiAgICByZXR1cm4gb2JqZWN0c1dpdGhQcm9wZXJ0eVxyXG4gIH0gZWxzZSB7XHJcbiAgICBjb25zdCByZWxldmFudE9iamVjdENvdW50ID0gZmlsdGVyLm9iamVjdENvdW50ID8/IHRvdGFsT2JqZWN0Q291bnQgPz8gMFxyXG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIHJlbGV2YW50T2JqZWN0Q291bnQgLSBvYmplY3RzV2l0aFByb3BlcnR5KVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEluamVjdHMgZ3JhZGllbnQgZGF0YSBpbnRvIHRoZSBmaWx0ZXJpbmcgZGF0YSBzdG9yZSBzbyBpdCBjYW4gYmUgdXNlZCBmb3IgZmlsdGVyaW5nXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0R3JhZGllbnREYXRhSW50b0RhdGFTdG9yZShcclxuICBmaWx0ZXJpbmdEYXRhU3RvcmU6IHVua25vd24sXHJcbiAgcHJvcGVydHlLZXk6IHN0cmluZyxcclxuICBncmFkaWVudFZhbHVlczogUmVjb3JkPHN0cmluZywgeyBncmFkaWVudFZhbHVlOiBudW1iZXIgfT5cclxuKTogdm9pZCB7XHJcbiAgaWYgKCFmaWx0ZXJpbmdEYXRhU3RvcmUgfHwgT2JqZWN0LmtleXMoZ3JhZGllbnRWYWx1ZXMpLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgcmV0dXJuXHJcbiAgfVxyXG5cclxuICBjb25zdCBzdG9yZSA9IGZpbHRlcmluZ0RhdGFTdG9yZSBhcyB7XHJcbiAgICBkYXRhU291cmNlczoge1xyXG4gICAgICB2YWx1ZTogRGF0YVNvdXJjZVtdXHJcbiAgICB9XHJcbiAgfVxyXG4gIGlmICghc3RvcmUuZGF0YVNvdXJjZXM/LnZhbHVlKSB7XHJcbiAgICByZXR1cm5cclxuICB9XHJcblxyXG4gIGZvciAoY29uc3QgZGF0YVNvdXJjZSBvZiBzdG9yZS5kYXRhU291cmNlcy52YWx1ZSkge1xyXG4gICAgZm9yIChjb25zdCBbb2JqZWN0SWQsIHsgZ3JhZGllbnRWYWx1ZSB9XSBvZiBPYmplY3QuZW50cmllcyhncmFkaWVudFZhbHVlcykpIHtcclxuICAgICAgLy8gQWRkIHRoZSBncmFkaWVudCBwcm9wZXJ0eSB0byB0aGUgb2JqZWN0IGlmIGl0IGV4aXN0cyBpbiB0aGlzIGRhdGEgc291cmNlXHJcbiAgICAgIGlmIChkYXRhU291cmNlLm9iamVjdFByb3BlcnRpZXNbb2JqZWN0SWRdKSB7XHJcbiAgICAgICAgZGF0YVNvdXJjZS5vYmplY3RQcm9wZXJ0aWVzW29iamVjdElkXVtwcm9wZXJ0eUtleV0gPSBncmFkaWVudFZhbHVlXHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBBZGQgcHJvcGVydHkgaW5mbyB0byB0aGUgcHJvcGVydHlNYXAgaWYgbm90IGFscmVhZHkgcHJlc2VudFxyXG4gICAgaWYgKCFkYXRhU291cmNlLnByb3BlcnR5TWFwW3Byb3BlcnR5S2V5XSkge1xyXG4gICAgICBkYXRhU291cmNlLnByb3BlcnR5TWFwW3Byb3BlcnR5S2V5XSA9IHtcclxuICAgICAgICBjb25jYXRlbmF0ZWRQYXRoOiBwcm9wZXJ0eUtleSxcclxuICAgICAgICB2YWx1ZTogT2JqZWN0LnZhbHVlcyhncmFkaWVudFZhbHVlcylbMF0/LmdyYWRpZW50VmFsdWUgfHwgMCxcclxuICAgICAgICB0eXBlOiBGaWx0ZXJUeXBlLk51bWVyaWNcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIE5hc3R5IHNtYXJ0c3kgb2JqZWN0IGZsYXR0ZW5lciB0aGF0IGN1cnJlbnRseSBpbmNsdWRlcyBzcGVjaWFsIGhhbmRsaW5nIGxvZ2ljIGZvciBSZXZpdCBvYmplY3RzXHJcbiAqIEBwYXJhbSBvYmogb2JqZWN0IHlvdSB3YW50IHRvIGV4dHJhY3QgdGhlIHByb3BlcnRpZXMgZnJvbVxyXG4gKiBAcGFyYW0gY3VycmVudFBhdGggZG8gbm90IHBhc3MgaW4gb24gZmlyc3QgY2FsbCwgdXNlZCBpbiByZWN1cnNpb25cclxuICogQHBhcmFtIGtub3duT2JqZWN0VHlwZSBkbyBub3QgcGFzcyBpbiBvbiBmaXJzdCBjYWxsLCB1c2VkIGluIHJlY3Vyc2lvblxyXG4gKiBAcGFyYW0gcm9vdE9iaiBkbyBub3QgcGFzcyBpbiBvbiBmaXJzdCBjYWxsLCB1c2VkIGluIHJlY3Vyc2lvblxyXG4gKiBAcmV0dXJuc1xyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGV4dHJhY3ROZXN0ZWRQcm9wZXJ0aWVzID0gKFxyXG4gIG9iajogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXHJcbiAgY3VycmVudFBhdGg6IHN0cmluZ1tdID0gW10sXHJcbiAga25vd25PYmplY3RUeXBlPzogc3RyaW5nLFxyXG4gIHJvb3RPYmo/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxyXG4pID0+IHtcclxuICBjb25zdCBwcm9wZXJ0aWVzOiAoXHJcbiAgICB8IFByb3BlcnR5SW5mb0Jhc2VcclxuICAgIHwgUHJvcGVydHlJbmZvVmFsdWVcclxuICAgIHwgUGFyYW1ldGVyXHJcbiAgICB8IFJldml0TWF0ZXJpYWxQcm9wZXJ0eUluZm9cclxuICApW10gPSBbXVxyXG4gIHJvb3RPYmogPSByb290T2JqID8/IG9ialxyXG5cclxuICBrbm93bk9iamVjdFR5cGUgPVxyXG4gICAga25vd25PYmplY3RUeXBlID8/XHJcbiAgICAob2JqLnNwZWNrbGVfdHlwZSA9PT0gJ09iamVjdHMuRGF0YS5EYXRhT2JqZWN0Ok9iamVjdHMuRGF0YS5SZXZpdE9iamVjdCdcclxuICAgICAgPyAncmV2aXQnXHJcbiAgICAgIDogdW5kZWZpbmVkKVxyXG5cclxuICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcclxuICAgIGlmIChcclxuICAgICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkgfHxcclxuICAgICAga2V5ID09PSAnX19jbG9zdXJlJyB8fFxyXG4gICAgICBrZXkgPT09ICdkaXNwbGF5VmFsdWUnIHx8XHJcbiAgICAgIChrbm93bk9iamVjdFR5cGUgPT09ICdyZXZpdCcgJiYgKGtleSA9PT0gJ2xvY2F0aW9uJyB8fCBrZXkgPT09ICdlbGVtZW50cycpKVxyXG4gICAgKVxyXG4gICAgICBjb250aW51ZVxyXG5cclxuICAgIC8vIGlmIChrZXkuaW5jbHVkZXMoJy4nKSkge1xyXG4gICAgLy8gICAvLyBMaWZlIGlzIGZ1biwgaXNuJ3QgaXRcclxuICAgIC8vICAgY29uc29sZS53YXJuKFxyXG4gICAgLy8gICAgICdPYmplY3QgY29udGFpbnMgYSBwcm9wZXJ0eSB0aGF0IGhhcyBhIC4gaW4gaXRzIG5hbWUuIFNraXBwaW5nIScsXHJcbiAgICAvLyAgICAga2V5LFxyXG4gICAgLy8gICAgIGN1cnJlbnRQYXRoLFxyXG4gICAgLy8gICAgIHJvb3RPYmpcclxuICAgIC8vICAgKVxyXG4gICAgLy8gICBjb250aW51ZVxyXG4gICAgLy8gfVxyXG5cclxuICAgIGlmIChrbm93bk9iamVjdFR5cGUgPT09ICdyZXZpdCcgJiYga2V5ID09PSAnTWF0ZXJpYWwgUXVhbnRpdGllcycpIHtcclxuICAgICAgZXh0cmFjdE1hdGVyaWFsUHJvcGVydGllcyhcclxuICAgICAgICBvYmpba2V5XSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcclxuICAgICAgICBbLi4uY3VycmVudFBhdGgsIGtleV0sXHJcbiAgICAgICAgcHJvcGVydGllc1xyXG4gICAgICApXHJcbiAgICAgIGNvbnRpbnVlXHJcbiAgICB9XHJcblxyXG4gICAgaWYgKFxyXG4gICAgICBrbm93bk9iamVjdFR5cGUgPT09ICdyZXZpdCcgJiZcclxuICAgICAga2V5ID09PSAnU3RydWN0dXJlJyAmJlxyXG4gICAgICBjdXJyZW50UGF0aFtjdXJyZW50UGF0aC5sZW5ndGggLSAxXSA9PT0gJ1R5cGUgUGFyYW1ldGVycydcclxuICAgICkge1xyXG4gICAgICAvLyBUT0RPOiBoYW5kbGUgbGF0ZXI7IGZvciBub3cgdGhpcyBpbnRyb2R1Y2VzIGdhcmJhZ2VcclxuICAgICAgY29udGludWVcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB2YWx1ZSA9IG9ialtrZXldXHJcbiAgICBjb25zdCBuZXdQYXRoID0gWy4uLmN1cnJlbnRQYXRoLCBrZXldXHJcbiAgICBjb25zdCBpc1BhcmFtID0gdmFsdWUgJiYgaXNQYXJhbWV0ZXIodmFsdWUpXHJcblxyXG4gICAgY29uc3QgaXNBY3R1YWxPYmplY3QgPVxyXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSAmJiAhaXNQYXJhbVxyXG5cclxuICAgIGlmIChpc0FjdHVhbE9iamVjdCkge1xyXG4gICAgICBwcm9wZXJ0aWVzLnB1c2goXHJcbiAgICAgICAgLi4uZXh0cmFjdE5lc3RlZFByb3BlcnRpZXMoXHJcbiAgICAgICAgICB2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcclxuICAgICAgICAgIG5ld1BhdGgsXHJcbiAgICAgICAgICBrbm93bk9iamVjdFR5cGUsXHJcbiAgICAgICAgICByb290T2JqXHJcbiAgICAgICAgKVxyXG4gICAgICApXHJcbiAgICB9IGVsc2UgaWYgKGlzUGFyYW0pIHtcclxuICAgICAgY29uc3QgcGFyYW0gPSB2YWx1ZSBhcyBQYXJhbWV0ZXJcclxuXHJcbiAgICAgIHByb3BlcnRpZXMucHVzaCh7XHJcbiAgICAgICAgbmFtZToga2V5LFxyXG4gICAgICAgIHBhdGg6IG5ld1BhdGgsXHJcbiAgICAgICAgY29uY2F0ZW5hdGVkUGF0aDogbmV3UGF0aC5qb2luKCcuJyksXHJcbiAgICAgICAgdHlwZTogZ2V0VmFsdWVUeXBlKHBhcmFtLnZhbHVlKSxcclxuICAgICAgICB1bml0czogcGFyYW0udW5pdHNcclxuICAgICAgfSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IGdldFZhbHVlVHlwZSh2YWx1ZSlcclxuICAgICAgcHJvcGVydGllcy5wdXNoKHtcclxuICAgICAgICBuYW1lOiBrZXksXHJcbiAgICAgICAgcGF0aDogbmV3UGF0aCxcclxuICAgICAgICBjb25jYXRlbmF0ZWRQYXRoOiBuZXdQYXRoLmpvaW4oJy4nKSxcclxuICAgICAgICB0eXBlOiB2YWx1ZVR5cGVcclxuICAgICAgfSlcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIHByb3BlcnRpZXMgYXMgUHJvcGVydHlJbmZvQmFzZVtdXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldFZhbHVlVHlwZSh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XHJcbiAgaWYgKHZhbHVlID09PSBudWxsKSByZXR1cm4gJ251bGwnXHJcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gJ2FycmF5J1xyXG5cclxuICBpZiAoaXNWYWx1ZUJvb2xlYW4odmFsdWUpKSByZXR1cm4gJ2Jvb2xlYW4nXHJcbiAgaWYgKGlzVmFsdWVOdW1lcmljKHZhbHVlKSkgcmV0dXJuICdudW1iZXInXHJcblxyXG4gIHJldHVybiAnc3RyaW5nJ1xyXG59XHJcblxyXG5mdW5jdGlvbiBleHRyYWN0TWF0ZXJpYWxQcm9wZXJ0aWVzKFxyXG4gIG1hdFF1YW50czogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXHJcbiAgcGF0aDogc3RyaW5nW10sXHJcbiAgcHJvcGVydGllczogKFxyXG4gICAgfCBQcm9wZXJ0eUluZm9CYXNlXHJcbiAgICB8IFByb3BlcnR5SW5mb1ZhbHVlXHJcbiAgICB8IFBhcmFtZXRlclxyXG4gICAgfCBSZXZpdE1hdGVyaWFsUHJvcGVydHlJbmZvXHJcbiAgKVtdXHJcbikge1xyXG4gIGZvciAoY29uc3QgbWF0TmFtZSBpbiBtYXRRdWFudHMpIHtcclxuICAgIGNvbnN0IG1hdEluZm8gPSBtYXRRdWFudHNbbWF0TmFtZV0gYXMgUmV2aXRNYXRlcmlhbEluZm9cclxuXHJcbiAgICBjb25zdCBhcmVhUHJvcDogUmV2aXRNYXRlcmlhbFByb3BlcnR5SW5mbyB8IHVuZGVmaW5lZCA9IG1hdEluZm8uYXJlYVxyXG4gICAgICA/IHtcclxuICAgICAgICAgIHBhdGgsXHJcbiAgICAgICAgICBjb25jYXRlbmF0ZWRQYXRoOiBwYXRoLmpvaW4oJy4nKSxcclxuICAgICAgICAgIHR5cGU6ICdudW1iZXInLFxyXG4gICAgICAgICAgbmFtZTogYCR7bWF0TmFtZX0gLSBhcmVhYCxcclxuICAgICAgICAgIHZhbHVlOiBtYXRJbmZvLmFyZWEudmFsdWUsXHJcbiAgICAgICAgICB1bml0czogbWF0SW5mby5hcmVhLnVuaXRzLFxyXG4gICAgICAgICAgbWF0ZXJpYWxDYXRlZ29yeTogbWF0SW5mby5tYXRlcmlhbENhdGVnb3J5LFxyXG4gICAgICAgICAgbWF0ZXJpYWxDbGFzczogbWF0SW5mby5tYXRlcmlhbENsYXNzXHJcbiAgICAgICAgfVxyXG4gICAgICA6IHVuZGVmaW5lZFxyXG5cclxuICAgIGNvbnN0IHZvbHVtZVByb3A6IFJldml0TWF0ZXJpYWxQcm9wZXJ0eUluZm8gfCB1bmRlZmluZWQgPSBtYXRJbmZvLnZvbHVtZVxyXG4gICAgICA/IHtcclxuICAgICAgICAgIHBhdGgsXHJcbiAgICAgICAgICBjb25jYXRlbmF0ZWRQYXRoOiBwYXRoLmpvaW4oJy4nKSxcclxuICAgICAgICAgIHR5cGU6ICdudW1iZXInLFxyXG4gICAgICAgICAgbmFtZTogYCR7bWF0TmFtZX0gLSB2b2x1bWVgLFxyXG4gICAgICAgICAgdmFsdWU6IG1hdEluZm8udm9sdW1lLnZhbHVlLFxyXG4gICAgICAgICAgdW5pdHM6IG1hdEluZm8udm9sdW1lLnVuaXRzLFxyXG4gICAgICAgICAgbWF0ZXJpYWxDYXRlZ29yeTogbWF0SW5mby5tYXRlcmlhbENhdGVnb3J5LFxyXG4gICAgICAgICAgbWF0ZXJpYWxDbGFzczogbWF0SW5mby5tYXRlcmlhbENsYXNzXHJcbiAgICAgICAgfVxyXG4gICAgICA6IHVuZGVmaW5lZFxyXG4gICAgaWYgKGFyZWFQcm9wKSBwcm9wZXJ0aWVzLnB1c2goYXJlYVByb3ApXHJcbiAgICBpZiAodm9sdW1lUHJvcCkgcHJvcGVydGllcy5wdXNoKHZvbHVtZVByb3ApXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaXNQYXJhbWV0ZXIodmFsdWU6IHVua25vd24pIHtcclxuICByZXR1cm4gKFxyXG4gICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxyXG4gICAgT2JqZWN0Lmhhc093bih2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgJ25hbWUnKSAmJlxyXG4gICAgT2JqZWN0Lmhhc093bih2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgJ3ZhbHVlJylcclxuICApXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpc1Jldml0TWF0ZXJpYWxRdWFudGl0eSh2YWx1ZTogdW5rbm93bikge1xyXG4gIHJldHVybiAoXHJcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXHJcbiAgICBpc1BhcmFtZXRlcih2YWx1ZSkgJiZcclxuICAgIE9iamVjdC5oYXNPd24odmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sICdtYXRlcmlhbENhdGVnb3J5JykgJiZcclxuICAgIE9iamVjdC5oYXNPd24odmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sICdtYXRlcmlhbENsYXNzJylcclxuICApXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXROZXN0ZWRQcm9wZXJ0aWVzKG9iajogdW5rbm93biwgcHJvcGVydGllczogUHJvcGVydHlJbmZvQmFzZVtdKSB7XHJcbiAgY29uc3QgdmFsdWVzID0gW11cclxuICBmb3IgKGNvbnN0IHByb3Agb2YgcHJvcGVydGllcykge1xyXG4gICAgY29uc3QgdmFsdWUgPSBwcm9wLnBhdGgucmVkdWNlKFxyXG4gICAgICAoY3VycmVudDogdW5rbm93biwga2V5OiBzdHJpbmcpID0+IChjdXJyZW50IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KT8uW2tleV0sXHJcbiAgICAgIG9ialxyXG4gICAgKVxyXG4gICAgaWYgKHZhbHVlICYmIGlzUGFyYW1ldGVyKHZhbHVlKSkge1xyXG4gICAgICB2YWx1ZXMucHVzaCgodmFsdWUgYXMgUGFyYW1ldGVyKS52YWx1ZSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHZhbHVlcy5wdXNoKHZhbHVlID8/IHVuZGVmaW5lZClcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIHZhbHVlc1xyXG59XHJcbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBUyw0QkFBNEI7QUFDckMsU0FBUyxVQUFVLFVBQVUsV0FBVyxnQkFBZ0I7QUFDeEQ7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BU0s7QUFFQSxhQUFNLHFCQUFxQjtBQUMzQixhQUFNLHlDQUF5QztBQUMvQyxhQUFNLHFDQUFxQztBQUszQyxhQUFNLGtCQUFrQixDQUFDLFFBQXlCO0FBQ3ZELFNBQ0UsbUJBQW1CLEtBQUssR0FBRyxLQUMzQix1Q0FBdUMsS0FBSyxHQUFHLEtBQy9DLG1DQUFtQyxLQUFLLEdBQUc7QUFFL0M7QUFLTyxhQUFNLDZCQUE2QixDQUFDLFFBQXlCO0FBRWxFLFFBQU0sWUFBWSxJQUFJLE1BQU0sR0FBRztBQUMvQixRQUFNLFdBQVcsVUFBVSxVQUFVLFNBQVMsQ0FBQztBQUcvQyxNQUFJLENBQUMsZ0JBQWdCLGFBQWEsUUFBUSxnQkFBZ0IsRUFBRSxTQUFTLFFBQVEs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