@valueflows/vf-graphql-holochain
Version:
GraphQL schema bindings for the Holochain implementation of ValueFlows
426 lines • 48.1 kB
JavaScript
import { decode } from '@msgpack/msgpack';
import { decodeHashFromBase64, encodeHashToBase64 } from '@holochain/client';
import { getEntryFromStore, addEntryToStore, updateLatestRevision } from './store.js';
export function extractIds(obj) {
// extract the ids from the object
let id = obj.id;
let revisionId = obj.revisionId;
let output = { id, revisionId, entry: {} };
let args = { ...obj };
delete args.id;
delete args.revisionId;
output.entry = args;
return output;
}
export async function getPaginatedCollection(cell, linkFunc, entryFunc, paginated) {
const collection = await getCollection(cell, linkFunc, null, paginated);
const paginatedCollection = paginateCollection(collection, paginated);
return paginatedCollection;
}
export function paginateCollection(collection, args) {
const paginated = collection.map((item) => {
return {
__typename: 'AgentEdge',
cursor: item.id,
node: {
...item,
__typename: item.agentType
}
};
});
return {
pageInfo: {
endCursor: null,
hasNextPage: false,
hasPreviousPage: false,
pageLimit: null,
startCursor: null,
totalCount: null,
},
edges: paginated
};
}
export async function getCollectionLinks(cell, linkFunc, payload, paginated) {
const result = await cell.callZome({
zome_name: 'hrea',
fn_name: linkFunc,
payload,
});
const dedupedLinks = Array.from(result.reduce((map, link) => {
const encodedTarget = encodeHashToBase64(link.tag);
if (!map.has(encodedTarget) || (map.get(encodedTarget)?.timestamp ?? 0) < link.timestamp) {
map.set(encodedTarget, link);
}
return map;
}, new Map()).values());
return dedupedLinks;
}
export async function getCollection(cell, linkFunc, payload, paginated) {
const dedupedLinks = await getCollectionLinks(cell, linkFunc, payload, paginated);
// handle pagination
if (paginated) {
const allLinkTags = dedupedLinks.map((link) => encodeHashToBase64(link.tag));
let sliceBegins = 0;
let sliceEnds = dedupedLinks.length;
if (paginated?.first) {
sliceBegins = Math.max(paginated?.first - 1, sliceBegins);
}
else if (paginated?.after) {
sliceBegins = Math.max((allLinkTags.indexOf(paginated?.after || "") + 1), sliceBegins);
}
if (paginated?.last) {
sliceEnds = Math.min(paginated?.last, sliceEnds);
}
else if (paginated?.before) {
sliceEnds = Math.min(allLinkTags.indexOf(paginated?.before || ""), sliceEnds);
}
const paginatedLinks = dedupedLinks.slice(sliceBegins, sliceEnds);
const entries = await getEntries(cell, paginatedLinks);
return entries;
}
else {
const entries = await getEntries(cell, dedupedLinks);
return entries;
}
}
export async function getEntries(cell, list) {
// for each entry in the list, check the store, and if not found, fetch it
let entries = [];
let toFetch = [];
list.forEach((link) => {
const revisionId = encodeHashToBase64(link.target);
let entry = getEntryFromStore(revisionId);
if (entry) {
entries.push(entry);
// console.log("======================got entry from store=======================", entry)
}
else {
toFetch.push(revisionId);
// console.log("--------------------------fetching entry from zome---------------------", revisionId)
}
});
if (toFetch.length > 0) {
let entriesRes = await cell.callZome({
zome_name: 'hrea',
fn_name: 'get_generic_entries',
payload: toFetch,
});
entriesRes.forEach((res) => {
if (res?.entry?.Present) {
const decoded = decode(res.entry.Present.entry);
const camelCased = snakeToCamel(decoded);
const withIds = {
...camelCased,
// @ts-ignore
id: decoded?.id ? encodeHashToBase64(decoded.id) : encodeHashToBase64(res.signed_action.hashed.hash),
revisionId: encodeHashToBase64(res.signed_action.hashed.hash)
};
const withFormattedDates = formatDates(withIds);
addEntryToStore(withIds.revisionId, withFormattedDates);
updateLatestRevision(withFormattedDates.id, withFormattedDates);
entries.push(withFormattedDates);
}
else {
console.log(`No entry for items (${list})`, res);
}
});
}
return entries;
}
export function formatResItem(resItem, id) {
if (!resItem?.entry?.Present?.entry) {
return null;
}
let decoded = decode(resItem.entry.Present.entry);
let camel = snakeToCamel(decoded);
let withId = {
...camel,
id: id,
revisionId: encodeHashToBase64(resItem.signed_action.hashed.hash),
};
let encoded = formatDates(withId);
return encoded;
}
export function snakeToCamelString(str) {
// convert a snake_case string to camelCase
return str.replace(/_([a-z])/g, function (g) { return g[1].toUpperCase(); });
}
export function snakeToCamel(lib) {
// Recursively convert all keys from snake_case to camelCase
// Do not convert if it's a hash (object with only numeric keys)
if (Array.isArray(lib)) {
return lib.map(snakeToCamel);
}
else if (lib !== null && typeof lib === 'object') {
// Check if all keys are numeric (hash object)
const keys = Object.keys(lib);
const allNumeric = keys.length > 0 && keys.every(k => /^\d+$/.test(k));
if (allNumeric) {
return lib;
}
let camel = {};
for (let key in lib) {
let camelKey = key.replace(/_([a-z])/g, function (g) { return g[1].toUpperCase(); });
// convert rea_action
if (camelKey === "reaAction") {
camelKey = "action";
}
const value = lib[key];
camel[camelKey] = (typeof value === 'object' && value !== null)
? snakeToCamel(value)
: value;
}
return camel;
}
return lib;
}
export function camelToSnake(lib) {
// Recursively convert all keys from camelCase to snake_case
if (Array.isArray(lib)) {
return lib.map(camelToSnake);
}
else if (lib !== null && typeof lib === 'object') {
let snake = {};
for (let key in lib) {
let snakeKey = key.replace(/([A-Z])/g, "_$1").toLowerCase();
// convert action
if (snakeKey === "action") {
snakeKey = "rea_action";
}
// turn null values into undefined
let value = lib[key] === null ? undefined : lib[key];
// recursively convert objects and arrays
if (typeof value === 'object' && value !== null) {
value = camelToSnake(value);
}
snake[snakeKey] = value;
}
return snake;
}
return lib;
}
export function detectQuantityValueField(field) {
if (field.has_numerical_value !== undefined && field.has_unit !== undefined) {
return true;
}
return false;
}
export function decodePotentialQuantityValueField(field) {
if (field.hasNumericalValue !== undefined && field.hasUnit !== undefined) {
return {
has_numerical_value: field.hasNumericalValue,
has_unit: field.hasUnit?.id ? field.hasUnit.id : (field.hasUnit ? field.hasUnit : null)
};
}
return field;
}
export function findAndDecodeQuantityValueFields(obj) {
for (let key in obj) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
if (obj[key].hasNumericalValue !== undefined && obj[key].hasUnit !== undefined) {
obj[key] = decodePotentialQuantityValueField(obj[key]);
}
}
}
return obj;
}
const dateFields = ['due', 'hasBeginning', 'hasEnd'];
export function formatDates(obj) {
dateFields.forEach(field => {
if (obj[field]) {
obj[field] = new Date(obj[field] / 1000);
}
});
return obj;
}
export function reverseFormatDates(obj) {
dateFields.forEach(field => {
if (obj[field]) {
obj[field] = new Date(obj[field]).getTime() * 1000;
}
});
return obj;
}
export function pluralize(str) {
if (str === 'person') {
return 'people';
}
else if (str.endsWith('s')) {
return str + 'es';
}
else if (str.endsWith('y')) {
return str.slice(0, -1) + 'ies';
}
else if (str.endsWith('o')) {
return str + 'es';
}
else if (str.endsWith('ch')) {
return str + 'es';
}
else if (str.endsWith('sh')) {
return str + 'es';
}
else {
return str + 's';
}
}
export function decodeHashFields(obj, hashFields) {
hashFields.forEach(field => {
if (obj[field]) {
const decodedField = decodeHashFromBase64(obj[field]);
obj[field] = decodedField;
obj[`${field}Id`] = decodedField;
}
});
return obj;
}
const actions = {
"dropoff": {
id: "dropoff",
label: "dropoff",
resourceEffect: "decrement",
onhandEffect: "decrement",
inputOutput: "output",
pairsWith: "pickup"
},
"pickup": {
id: "pickup",
label: "pickup",
resourceEffect: "increment",
onhandEffect: "increment",
inputOutput: "input",
pairsWith: "dropoff"
},
"consume": {
id: "consume",
label: "consume",
resourceEffect: "decrement",
onhandEffect: "decrement",
inputOutput: "input",
pairsWith: "notApplicable"
},
"use": {
id: "use",
label: "use",
resourceEffect: "noEffect",
onhandEffect: "noEffect",
inputOutput: "input",
pairsWith: "notApplicable"
},
"work": {
id: "work",
label: "work",
resourceEffect: "noEffect",
onhandEffect: "noEffect",
inputOutput: "input",
pairsWith: "notApplicable"
},
"cite": {
id: "cite",
label: "cite",
resourceEffect: "noEffect",
onhandEffect: "noEffect",
inputOutput: "input",
pairsWith: "notApplicable"
},
"produce": {
id: "produce",
label: "produce",
resourceEffect: "increment",
onhandEffect: "increment",
inputOutput: "output",
pairsWith: "notApplicable"
},
"accept": {
id: "accept",
label: "accept",
resourceEffect: "noEffect",
onhandEffect: "decrement",
inputOutput: "input",
pairsWith: "modify"
},
"modify": {
id: "modify",
label: "modify",
resourceEffect: "noEffect",
onhandEffect: "increment",
inputOutput: "output",
pairsWith: "accept"
},
"pass": {
id: "pass",
label: "pass",
resourceEffect: "noEffect",
onhandEffect: "noEffect",
inputOutput: "output",
pairsWith: "accept"
},
"fail": {
id: "fail",
label: "fail",
resourceEffect: "noEffect",
onhandEffect: "noEffect",
inputOutput: "output",
pairsWith: "accept"
},
"deliver-service": {
id: "deliver-service",
label: "deliver-service",
resourceEffect: "noEffect",
onhandEffect: "noEffect",
inputOutput: "output",
pairsWith: "notApplicable"
},
"transfer-all-rights": {
id: "transfer-all-rights",
label: "transfer-all-rights",
resourceEffect: "decrementIncrement",
onhandEffect: "noEffect",
inputOutput: "notApplicable",
pairsWith: "notApplicable"
},
"transfer-custody": {
id: "transfer-custody",
label: "transfer-custody",
resourceEffect: "noEffect",
onhandEffect: "decrementIncrement",
inputOutput: "notApplicable",
pairsWith: "notApplicable"
},
"transfer": {
id: "transfer",
label: "transfer",
resourceEffect: "decrementIncrement",
onhandEffect: "decrementIncrement",
inputOutput: "notApplicable",
pairsWith: "notApplicable"
},
"move": {
id: "move",
label: "move",
resourceEffect: "decrementIncrement",
onhandEffect: "decrementIncrement",
inputOutput: "notApplicable",
pairsWith: "notApplicable"
},
"raise": {
id: "raise",
label: "raise",
resourceEffect: "increment",
onhandEffect: "increment",
inputOutput: "notApplicable",
pairsWith: "notApplicable"
},
"lower": {
id: "lower",
label: "lower",
resourceEffect: "decrement",
onhandEffect: "decrement",
inputOutput: "notApplicable",
pairsWith: "notApplicable"
}
};
export function getAction(id) {
return actions[id];
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQVUsTUFBTSxrQkFBa0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsa0JBQWtCLEVBQThCLE1BQU0sbUJBQW1CLENBQUE7QUFHeEcsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLFlBQVksQ0FBQztBQWN0RixNQUFNLFVBQVUsVUFBVSxDQUFDLEdBQW9CO0lBQzdDLGtDQUFrQztJQUNsQyxJQUFJLEVBQUUsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFBO0lBQ2YsSUFBSSxVQUFVLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQTtJQUMvQixJQUFJLE1BQU0sR0FBRyxFQUFDLEVBQUUsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBQyxDQUFBO0lBQ3hDLElBQUksSUFBSSxHQUFHLEVBQUUsR0FBRyxHQUFHLEVBQXlCLENBQUE7SUFDNUMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFBO0lBQ2QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFBO0lBQ3RCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFBO0lBQ25CLE9BQU8sTUFBTSxDQUFBO0FBQ2YsQ0FBQztBQUVELE1BQU0sQ0FBQyxLQUFLLFVBQVUsc0JBQXNCLENBQUMsSUFBUyxFQUFFLFFBQWdCLEVBQUUsU0FBaUIsRUFBRSxTQUF1QjtJQUNsSCxNQUFNLFVBQVUsR0FBRyxNQUFNLGFBQWEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN4RSxNQUFNLG1CQUFtQixHQUFHLGtCQUFrQixDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN0RSxPQUFPLG1CQUFtQixDQUFBO0FBQzVCLENBQUM7QUFFRCxNQUFNLFVB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QUFFLGtCQUFrQjtRQUN6QixjQUFjLEVBQUUsVUFBVTtRQUMxQixZQUFZLEVBQUUsb0JBQW9CO1FBQ2xDLFdBQVcsRUFBRSxlQUFlO1FBQzVCLFNBQVMsRUFBRSxlQUFlO0tBQzNCO0lBQ0QsVUFBVSxFQUFFO1FBQ1YsRUFBRSxFQUFFLFVBQVU7UUFDZCxLQUFLLEVBQUUsVUFBVTtRQUNqQixjQUFjLEVBQUUsb0JBQW9CO1FBQ3BDLFlBQVksRUFBRSxvQkFBb0I7UUFDbEMsV0FBVyxFQUFFLGVBQWU7UUFDNUIsU0FBUyxFQUFFLGVBQWU7S0FDM0I7SUFDRCxNQUFNLEVBQUU7UUFDTixFQUFFLEVBQUUsTUFBTTtRQUNWLEtBQUssRUFBRSxNQUFNO1FBQ2IsY0FBYyxFQUFFLG9CQUFvQjtRQUNwQyxZQUFZLEVBQUUsb0JBQW9CO1FBQ2xDLFdBQVcsRUFBRSxlQUFlO1FBQzVCLFNBQVMsRUFBRSxlQUFlO0tBQzNCO0lBQ0QsT0FBTyxFQUFFO1FBQ1AsRUFBRSxFQUFFLE9BQU87UUFDWCxLQUFLLEVBQUUsT0FBTztRQUNkLGNBQWMsRUFBRSxXQUFXO1FBQzNCLFlBQVksRUFBRSxXQUFXO1FBQ3pCLFdBQVcsRUFBRSxlQUFlO1FBQzVCLFNBQVMsRUFBRSxlQUFlO0tBQzNCO0lBQ0QsT0FBTyxFQUFFO1FBQ1AsRUFBRSxFQUFFLE9BQU87UUFDWCxLQUFLLEVBQUUsT0FBTztRQUNkLGNBQWMsRUFBRSxXQUFXO1FBQzNCLFlBQVksRUFBRSxXQUFXO1FBQ3pCLFdBQVcsRUFBRSxlQUFlO1FBQzVCLFNBQVMsRUFBRSxlQUFlO0tBQzNCO0NBQ0YsQ0FBQTtBQUVELE1BQU0sVUFBVSxTQUFTLENBQUMsRUFBVTtJQUNsQyxPQUFPLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQTtBQUNwQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGVjb2RlLCBlbmNvZGUgfSBmcm9tICdAbXNncGFjay9tc2dwYWNrJztcbmltcG9ydCB7IGRlY29kZUhhc2hGcm9tQmFzZTY0LCBlbmNvZGVIYXNoVG9CYXNlNjQsIHR5cGUgQWN0aW9uSGFzaCwgdHlwZSBMaW5rIH0gZnJvbSAnQGhvbG9jaGFpbi9jbGllbnQnXG5pbXBvcnQgeyBnZXQgfSBmcm9tICdzdmVsdGUvc3RvcmUnO1xuaW1wb3J0IHsgUGFnaW5nUGFyYW1zIH0gZnJvbSAnLi90eXBlcy5qcydcbmltcG9ydCB7IGdldEVudHJ5RnJvbVN0b3JlLCBhZGRFbnRyeVRvU3RvcmUsIHVwZGF0ZUxhdGVzdFJldmlzaW9uIH0gZnJvbSAnLi9zdG9yZS5qcyc7XG5cbnR5cGUgRXh0cmFjdElkc091dHB1dCA9IHtcbiAgaWQ6IHN0cmluZztcbiAgcmV2aXNpb25JZDogc3RyaW5nO1xuICBlbnRyeTogYW55O1xufVxuXG50eXBlIEV4dHJhY3RJZHNJbnB1dCA9IHtcbiAgaWQ6IHN0cmluZztcbiAgcmV2aXNpb25JZDogc3RyaW5nO1xuICBba2V5OiBzdHJpbmddOiBhbnk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0SWRzKG9iajogRXh0cmFjdElkc0lucHV0KTogRXh0cmFjdElkc091dHB1dCB7XG4gIC8vIGV4dHJhY3QgdGhlIGlkcyBmcm9tIHRoZSBvYmplY3RcbiAgbGV0IGlkID0gb2JqLmlkXG4gIGxldCByZXZpc2lvbklkID0gb2JqLnJldmlzaW9uSWRcbiAgbGV0IG91dHB1dCA9IHtpZCwgcmV2aXNpb25JZCwgZW50cnk6IHt9fVxuICBsZXQgYXJncyA9IHsgLi4ub2JqIH0gYXMgUGFydGlhbDx0eXBlb2Ygb2JqPlxuICBkZWxldGUgYXJncy5pZFxuICBkZWxldGUgYXJncy5yZXZpc2lvbklkXG4gIG91dHB1dC5lbnRyeSA9IGFyZ3NcbiAgcmV0dXJuIG91dHB1dFxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0UGFnaW5hdGVkQ29sbGVjdGlvbihjZWxsOiBhbnksIGxpbmtGdW5jOiBzdHJpbmcsIGVudHJ5RnVuYzogc3RyaW5nLCBwYWdpbmF0ZWQ6IFBhZ2luZ1BhcmFtcykge1xuICBjb25zdCBjb2xsZWN0aW9uID0gYXdhaXQgZ2V0Q29sbGVjdGlvbihjZWxsLCBsaW5rRnVuYywgbnVsbCwgcGFnaW5hdGVkKTtcbiAgY29uc3QgcGFnaW5hdGVkQ29sbGVjdGlvbiA9IHBhZ2luYXRlQ29sbGVjdGlvbihjb2xsZWN0aW9uLCBwYWdpbmF0ZWQpO1xuICByZXR1cm4gcGFnaW5hdGVkQ29sbGVjdGlvblxufVxuICBcbmV4cG9ydCBmdW5jdGlvbiBwYWdpbmF0ZUNvbGxlY3Rpb24oY29sbGVjdGlvbjogYW55LCBhcmdzOiBQYWdpbmdQYXJhbXMpIHtcbiAgY29uc3QgcGFnaW5hdGVkID0gY29sbGVjdGlvbi5tYXAoKGl0ZW06IGFueSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBfX3R5cGVuYW1lOiAnQWdlbnRFZGdlJyxcbiAgICAgICAgICBjdXJzb3I6IGl0ZW0uaWQsXG4gICAgICAgICAgbm9kZToge1xuICAgICAgICAgICAgICAuLi5pdGVtLFxuICAgICAgICAgICAgICBfX3R5cGVuYW1lOiBpdGVtLmFnZW50VHlwZVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgfSlcbiAgcmV0dXJuIHtcbiAgICAgIHBhZ2VJbmZvOiB7XG4gICAgICAgICAgZW5kQ3Vyc29yOiBudWxsLFxuICAgICAgICAgIGhhc05leHRQYWdlOiBmYWxzZSxcbiAgICAgICAgICBoYXNQcmV2aW91c1BhZ2U6IGZhbHNlLFxuICAgICAgICAgIHBhZ2VMaW1pdDogbnVsbCxcbiAgICAgICAgICBzdGFydEN1cnNvcjogbnVsbCxcbiAgICAgICAgICB0b3RhbENvdW50OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGVkZ2VzOiBwYWdpbmF0ZWRcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0Q29sbGVjdGlvbkxpbmtzKFxuICBjZWxsOiBhbnksIFxuICBsaW5rRnVuYzogc3RyaW5nLCBcbiAgcGF5bG9hZDogYW55LCBcbiAgcGFnaW5hdGVkPzogUGFnaW5nUGFyYW1zXG4pIHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjZWxsLmNhbGxab21lKHtcbiAgICAgICAgem9tZV9uYW1lOiAnaHJlYScsXG4gICAgICAgIGZuX25hbWU6IGxpbmtGdW5jLFxuICAgICAgICBwYXlsb2FkLFxuICAgIH0pXG4gICAgY29uc3QgZGVkdXBlZExpbmtzOiBBcnJheTxMaW5rPiA9IEFycmF5LmZyb20oXG4gICAgICAgIHJlc3VsdC5yZWR1Y2UoKG1hcDogTWFwPHN0cmluZywgTGluaz4sIGxpbms6IExpbmspID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVuY29kZWRUYXJnZXQgPSBlbmNvZGVIYXNoVG9CYXNlNjQobGluay50YWcpO1xuICAgICAgICAgICAgaWYgKCFtYXAuaGFzKGVuY29kZWRUYXJnZXQpIHx8IChtYXAuZ2V0KGVuY29kZWRUYXJnZXQpPy50aW1lc3RhbXAgPz8gMCkgPCBsaW5rLnRpbWVzdGFtcCkge1xuICAgICAgICAgICAgICAgIG1hcC5zZXQoZW5jb2RlZFRhcmdldCwgbGluayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWFwO1xuICAgICAgICB9LCBuZXcgTWFwKCkpLnZhbHVlcygpXG4gICAgKTtcbiAgICByZXR1cm4gZGVkdXBlZExpbmtzXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRDb2xsZWN0aW9uKFxuICBjZWxsOiBhbnksIFxuICBsaW5rRnVuYzogc3RyaW5nLCBcbiAgcGF5bG9hZDogYW55LCBcbiAgcGFnaW5hdGVkPzogUGFnaW5nUGFyYW1zXG4pIHtcbiAgICBjb25zdCBkZWR1cGVkTGlua3MgPSBhd2FpdCBnZXRDb2xsZWN0aW9uTGlua3MoY2VsbCwgbGlua0Z1bmMsIHBheWxvYWQsIHBhZ2luYXRlZCk7XG5cbiAgICAvLyBoYW5kbGUgcGFnaW5hdGlvblxuICAgIGlmIChwYWdpbmF0ZWQpIHtcbiAgICAgIGNvbnN0IGFsbExpbmtUYWdzID0gZGVkdXBlZExpbmtzLm1hcCgobGluazogTGluaykgPT4gZW5jb2RlSGFzaFRvQmFzZTY0KGxpbmsudGFnKSlcbiAgICAgIGxldCBzbGljZUJlZ2lucyA9IDBcbiAgICAgIGxldCBzbGljZUVuZHMgPSBkZWR1cGVkTGlua3MubGVuZ3RoXG4gICAgICBpZiAocGFnaW5hdGVkPy5maXJzdCkge1xuICAgICAgICBzbGljZUJlZ2lucyA9IE1hdGgubWF4KHBhZ2luYXRlZD8uZmlyc3QgLSAxLCBzbGljZUJlZ2lucylcbiAgICAgIH0gZWxzZSBpZiAocGFnaW5hdGVkPy5hZnRlcikge1xuICAgICAgICBzbGljZUJlZ2lucyA9IE1hdGgubWF4KChhbGxMaW5rVGFncy5pbmRleE9mKHBhZ2luYXRlZD8uYWZ0ZXIgfHwgXCJcIikgKyAxKSwgc2xpY2VCZWdpbnMpXG4gICAgICB9XG4gICAgICBpZiAocGFnaW5hdGVkPy5sYXN0KSB7XG4gICAgICAgIHNsaWNlRW5kcyA9IE1hdGgubWluKHBhZ2luYXRlZD8ubGFzdCwgc2xpY2VFbmRzKVxuICAgICAgfSBlbHNlIGlmIChwYWdpbmF0ZWQ/LmJlZm9yZSkge1xuICAgICAgICBzbGljZUVuZHMgPSBNYXRoLm1pbihhbGxMaW5rVGFncy5pbmRleE9mKHBhZ2luYXRlZD8uYmVmb3JlIHx8IFwiXCIpLCBzbGljZUVuZHMpXG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnN0IHBhZ2luYXRlZExpbmtzID0gZGVkdXBlZExpbmtzLnNsaWNlKHNsaWNlQmVnaW5zLCBzbGljZUVuZHMpXG4gICAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgZ2V0RW50cmllcyhjZWxsLCBwYWdpbmF0ZWRMaW5rcyk7XG4gICAgICByZXR1cm4gZW50cmllc1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgZ2V0RW50cmllcyhjZWxsLCBkZWR1cGVkTGlua3MpO1xuICAgICAgcmV0dXJuIGVudHJpZXNcbiAgICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRFbnRyaWVzKGNlbGw6IGFueSwgbGlzdDogTGlua1tdKSB7XG4gIC8vIGZvciBlYWNoIGVudHJ5IGluIHRoZSBsaXN0LCBjaGVjayB0aGUgc3RvcmUsIGFuZCBpZiBub3QgZm91bmQsIGZldGNoIGl0XG4gIGxldCBlbnRyaWVzOiBhbnlbXSA9IFtdXG4gIGxldCB0b0ZldGNoOiBzdHJpbmdbXSA9IFtdXG5cbiAgbGlzdC5mb3JFYWNoKChsaW5rKSA9PiB7XG4gICAgY29uc3QgcmV2aXNpb25JZCA9IGVuY29kZUhhc2hUb0Jhc2U2NChsaW5rLnRhcmdldClcbiAgICBsZXQgZW50cnkgPSBnZXRFbnRyeUZyb21TdG9yZShyZXZpc2lvbklkKVxuICAgIGlmIChlbnRyeSkge1xuICAgICAgZW50cmllcy5wdXNoKGVudHJ5KVxuICAgICAgLy8gY29uc29sZS5sb2coXCI9PT09PT09PT09PT09PT09PT09PT09Z290IGVudHJ5IGZyb20gc3RvcmU9PT09PT09PT09PT09PT09PT09PT09PVwiLCBlbnRyeSlcbiAgICB9IGVsc2Uge1xuICAgICAgdG9GZXRjaC5wdXNoKHJldmlzaW9uSWQpXG4gICAgICAvLyBjb25zb2xlLmxvZyhcIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tZmV0Y2hpbmcgZW50cnkgZnJvbSB6b21lLS0tLS0tLS0tLS0tLS0tLS0tLS0tXCIsIHJldmlzaW9uSWQpXG4gICAgfVxuICB9KVxuXG4gIGlmICh0b0ZldGNoLmxlbmd0aCA+IDApIHtcbiAgICBsZXQgZW50cmllc1JlcyA9IGF3YWl0IGNlbGwuY2FsbFpvbWUoe1xuICAgICAgem9tZV9uYW1lOiAnaHJlYScsXG4gICAgICBmbl9uYW1lOiAnZ2V0X2dlbmVyaWNfZW50cmllcycsXG4gICAgICBwYXlsb2FkOiB0b0ZldGNoLFxuICAgIH0pXG5cbiAgICBlbnRyaWVzUmVzLmZvckVhY2goKHJlczogYW55KSA9PiB7XG4gICAgICBpZiAocmVzPy5lbnRyeT8uUHJlc2VudCkge1xuICAgICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlKHJlcy5lbnRyeS5QcmVzZW50LmVudHJ5KVxuICAgICAgICBjb25zdCBjYW1lbENhc2VkID0gc25ha2VUb0NhbWVsKGRlY29kZWQpXG4gICAgICAgIGNvbnN0IHdpdGhJZHMgPSB7XG4gICAgICAgICAgLi4uY2FtZWxDYXNlZCwgXG4gICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgIGlkOiBkZWNvZGVkPy5pZCA/IGVuY29kZUhhc2hUb0Jhc2U2NChkZWNvZGVkLmlkKSA6IGVuY29kZUhhc2hUb0Jhc2U2NChyZXMuc2lnbmVkX2FjdGlvbi5oYXNoZWQuaGFzaCksIFxuICAgICAgICAgIHJldmlzaW9uSWQ6IGVuY29kZUhhc2hUb0Jhc2U2NChyZXMuc2lnbmVkX2FjdGlvbi5oYXNoZWQuaGFzaCkgXG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd2l0aEZvcm1hdHRlZERhdGVzID0gZm9ybWF0RGF0ZXMod2l0aElkcylcbiAgICAgICAgYWRkRW50cnlUb1N0b3JlKHdpdGhJZHMucmV2aXNpb25JZCwgd2l0aEZvcm1hdHRlZERhdGVzKVxuICAgICAgICB1cGRhdGVMYXRlc3RSZXZpc2lvbihcbiAgICAgICAgICB3aXRoRm9ybWF0dGVkRGF0ZXMuaWQsXG4gICAgICAgICAgd2l0aEZvcm1hdHRlZERhdGVzXG4gICAgICAgIClcbiAgICAgICAgZW50cmllcy5wdXNoKHdpdGhGb3JtYXR0ZWREYXRlcylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBObyBlbnRyeSBmb3IgaXRlbXMgKCR7bGlzdH0pYCwgcmVzKVxuICAgICAgfVxuICAgIH0pXG4gIH1cbiAgcmV0dXJuIGVudHJpZXNcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFJlc0l0ZW0ocmVzSXRlbTogYW55LCBpZDogQWN0aW9uSGFzaCkge1xuICBpZiAoIXJlc0l0ZW0/LmVudHJ5Py5QcmVzZW50Py5lbnRyeSkgeyByZXR1cm4gbnVsbCB9XG4gIGxldCBkZWNvZGVkID0gZGVjb2RlKHJlc0l0ZW0uZW50cnkuUHJlc2VudC5lbnRyeSlcbiAgbGV0IGNhbWVsID0gc25ha2VUb0NhbWVsKGRlY29kZWQpXG4gIGxldCB3aXRoSWQgPSB7XG4gICAgLi4uY2FtZWwsIFxuICAgIGlkOiAgaWQsXG4gICAgcmV2aXNpb25JZDogZW5jb2RlSGFzaFRvQmFzZTY0KHJlc0l0ZW0uc2lnbmVkX2FjdGlvbi5oYXNoZWQuaGFzaCksXG4gIH1cbiAgbGV0IGVuY29kZWQgPSBmb3JtYXREYXRlcyh3aXRoSWQpXG4gIHJldHVybiBlbmNvZGVkXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzbmFrZVRvQ2FtZWxTdHJpbmcoc3RyOiBzdHJpbmcpIHtcbiAgLy8gY29udmVydCBhIHNuYWtlX2Nhc2Ugc3RyaW5nIHRvIGNhbWVsQ2FzZVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL18oW2Etel0pL2csIGZ1bmN0aW9uIChnKSB7IHJldHVybiBnWzFdLnRvVXBwZXJDYXNlKCk7IH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc25ha2VUb0NhbWVsKGxpYjogYW55KTogYW55IHtcbiAgLy8gUmVjdXJzaXZlbHkgY29udmVydCBhbGwga2V5cyBmcm9tIHNuYWtlX2Nhc2UgdG8gY2FtZWxDYXNlXG4gIC8vIERvIG5vdCBjb252ZXJ0IGlmIGl0J3MgYSBoYXNoIChvYmplY3Qgd2l0aCBvbmx5IG51bWVyaWMga2V5cylcbiAgaWYgKEFycmF5LmlzQXJyYXkobGliKSkge1xuICAgIHJldHVybiBsaWIubWFwKHNuYWtlVG9DYW1lbCk7XG4gIH0gZWxzZSBpZiAobGliICE9PSBudWxsICYmIHR5cGVvZiBsaWIgPT09ICdvYmplY3QnKSB7XG4gICAgLy8gQ2hlY2sgaWYgYWxsIGtleXMgYXJlIG51bWVyaWMgKGhhc2ggb2JqZWN0KVxuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhsaWIpO1xuICAgIGNvbnN0IGFsbE51bWVyaWMgPSBrZXlzLmxlbmd0aCA+IDAgJiYga2V5cy5ldmVyeShrID0+IC9eXFxkKyQvLnRlc3QoaykpO1xuICAgIGlmIChhbGxOdW1lcmljKSB7XG4gICAgICByZXR1cm4gbGliO1xuICAgIH1cbiAgICBsZXQgY2FtZWw6IGFueSA9IHt9O1xuICAgIGZvciAobGV0IGtleSBpbiBsaWIpIHtcbiAgICAgIGxldCBjYW1lbEtleSA9IGtleS5yZXBsYWNlKC9fKFthLXpdKS9nLCBmdW5jdGlvbiAoZykgeyByZXR1cm4gZ1sxXS50b1VwcGVyQ2FzZSgpOyB9KTtcbiAgICAgIC8vIGNvbnZlcnQgcmVhX2FjdGlvblxuICAgICAgaWYgKGNhbWVsS2V5ID09PSBcInJlYUFjdGlvblwiKSB7XG4gICAgICAgIGNhbWVsS2V5ID0gXCJhY3Rpb25cIjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZhbHVlID0gbGliW2tleV07XG4gICAgICBjYW1lbFtjYW1lbEtleV0gPSAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbClcbiAgICAgICAgPyBzbmFrZVRvQ2FtZWwodmFsdWUpXG4gICAgICAgIDogdmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBjYW1lbDtcbiAgfVxuICByZXR1cm4gbGliO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FtZWxUb1NuYWtlKGxpYjogYW55KTogYW55IHtcbiAgLy8gUmVjdXJzaXZlbHkgY29udmVydCBhbGwga2V5cyBmcm9tIGNhbWVsQ2FzZSB0byBzbmFrZV9jYXNlXG4gIGlmIChBcnJheS5pc0FycmF5KGxpYikpIHtcbiAgICByZXR1cm4gbGliLm1hcChjYW1lbFRvU25ha2UpO1xuICB9IGVsc2UgaWYgKGxpYiAhPT0gbnVsbCAmJiB0eXBlb2YgbGliID09PSAnb2JqZWN0Jykge1xuICAgIGxldCBzbmFrZTogYW55ID0ge307XG4gICAgZm9yIChsZXQga2V5IGluIGxpYikge1xuICAgICAgbGV0IHNuYWtlS2V5ID0ga2V5LnJlcGxhY2UoLyhbQS1aXSkvZywgXCJfJDFcIikudG9Mb3dlckNhc2UoKTtcbiAgICAgIC8vIGNvbnZlcnQgYWN0aW9uXG4gICAgICBpZiAoc25ha2VLZXkgPT09IFwiYWN0aW9uXCIpIHtcbiAgICAgICAgc25ha2VLZXkgPSBcInJlYV9hY3Rpb25cIjtcbiAgICAgIH1cbiAgICAgIC8vIHR1cm4gbnVsbCB2YWx1ZXMgaW50byB1bmRlZmluZWRcbiAgICAgIGxldCB2YWx1ZSA9IGxpYltrZXldID09PSBudWxsID8gdW5kZWZpbmVkIDogbGliW2tleV07XG4gICAgICAvLyByZWN1cnNpdmVseSBjb252ZXJ0IG9iamVjdHMgYW5kIGFycmF5c1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgdmFsdWUgPSBjYW1lbFRvU25ha2UodmFsdWUpO1xuICAgICAgfVxuICAgICAgc25ha2Vbc25ha2VLZXldID0gdmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBzbmFrZTtcbiAgfVxuICByZXR1cm4gbGliO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0UXVhbnRpdHlWYWx1ZUZpZWxkKGZpZWxkOiBhbnkpIHtcbiAgaWYgKGZpZWxkLmhhc19udW1lcmljYWxfdmFsdWUgIT09IHVuZGVmaW5lZCAmJiBmaWVsZC5oYXNfdW5pdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZVBvdGVudGlhbFF1YW50aXR5VmFsdWVGaWVsZChmaWVsZDogYW55KSB7XG4gIGlmIChmaWVsZC5oYXNOdW1lcmljYWxWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIGZpZWxkLmhhc1VuaXQgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB7XG4gICAgICBoYXNfbnVtZXJpY2FsX3ZhbHVlOiBmaWVsZC5oYXNOdW1lcmljYWxWYWx1ZSxcbiAgICAgIGhhc191bml0OiBmaWVsZC5oYXNVbml0Py5pZCA/IGZpZWxkLmhhc1VuaXQuaWQgOiAoZmllbGQuaGFzVW5pdCA/IGZpZWxkLmhhc1VuaXQgOiBudWxsKVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmllbGRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRBbmREZWNvZGVRdWFudGl0eVZhbHVlRmllbGRzKG9iajogYW55KSB7XG4gIGZvciAobGV0IGtleSBpbiBvYmopIHtcbiAgICBpZiAodHlwZW9mIG9ialtrZXldID09PSAnb2JqZWN0JyAmJiBvYmpba2V5XSAhPT0gbnVsbCkge1xuICAgICAgaWYgKG9ialtrZXldLmhhc051bWVyaWNhbFZhbHVlICE9PSB1bmRlZmluZWQgJiYgb2JqW2tleV0uaGFzVW5pdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG9ialtrZXldID0gZGVjb2RlUG90ZW50aWFsUXVhbnRpdHlWYWx1ZUZpZWxkKG9ialtrZXldKVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gb2JqXG59XG5cbmNvbnN0IGRhdGVGaWVsZHMgPSBbJ2R1ZScsICdoYXNCZWdpbm5pbmcnLCAnaGFzRW5kJ11cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXREYXRlcyhvYmo6IGFueSkge1xuICBkYXRlRmllbGRzLmZvckVhY2goZmllbGQgPT4ge1xuICAgIGlmIChvYmpbZmllbGRdKSB7XG4gICAgICBvYmpbZmllbGRdID0gbmV3IERhdGUob2JqW2ZpZWxkXSAvIDEwMDApXG4gICAgfVxuICB9KVxuICByZXR1cm4gb2JqXG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXZlcnNlRm9ybWF0RGF0ZXMob2JqOiBhbnkpIHtcbiAgZGF0ZUZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICBpZiAob2JqW2ZpZWxkXSkge1xuICAgICAgb2JqW2ZpZWxkXSA9IG5ldyBEYXRlKG9ialtmaWVsZF0pLmdldFRpbWUoKSAqIDEwMDBcbiAgICB9XG4gIH0pXG4gIHJldHVybiBvYmpcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBsdXJhbGl6ZShzdHI6IHN0cmluZykge1xuICBpZiAoc3RyID09PSAncGVyc29uJykge1xuICAgIHJldHVybiAncGVvcGxlJ1xuICB9IGVsc2UgaWYgKHN0ci5lbmRzV2l0aCgncycpKSB7XG4gICAgcmV0dXJuIHN0ciArICdlcydcbiAgfSBlbHNlIGlmIChzdHIuZW5kc1dpdGgoJ3knKSkge1xuICAgIHJldHVybiBzdHIuc2xpY2UoMCwgLTEpICsgJ2llcydcbiAgfSBlbHNlIGlmIChzdHIuZW5kc1dpdGgoJ28nKSkge1xuICAgIHJldHVybiBzdHIgKyAnZXMnXG4gIH0gZWxzZSBpZiAoc3RyLmVuZHNXaXRoKCdjaCcpKSB7XG4gICAgcmV0dXJuIHN0ciArICdlcydcbiAgfSBlbHNlIGlmIChzdHIuZW5kc1dpdGgoJ3NoJykpIHtcbiAgICByZXR1cm4gc3RyICsgJ2VzJ1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHIgKyAncydcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlSGFzaEZpZWxkcyhvYmo6IGFueSwgaGFzaEZpZWxkczogc3RyaW5nW10pIHtcbiAgaGFzaEZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICBpZiAob2JqW2ZpZWxkXSkge1xuICAgICAgY29uc3QgZGVjb2RlZEZpZWxkID0gZGVjb2RlSGFzaEZyb21CYXNlNjQob2JqW2ZpZWxkXSlcbiAgICAgIG9ialtmaWVsZF0gPSBkZWNvZGVkRmllbGRcbiAgICAgIG9ialtgJHtmaWVsZH1JZGBdID0gZGVjb2RlZEZpZWxkXG4gICAgfVxuICB9KVxuICByZXR1cm4gb2JqXG59XG5cbmNvbnN0IGFjdGlvbnMgPSB7XG4gIFwiZHJvcG9mZlwiOiB7XG4gICAgaWQ6IFwiZHJvcG9mZlwiLFxuICAgIGxhYmVsOiBcImRyb3BvZmZcIixcbiAgICByZXNvdXJjZUVmZmVjdDogXCJkZWNyZW1lbnRcIixcbiAgICBvbmhhbmRFZmZlY3Q6IFwiZGVjcmVtZW50XCIsXG4gICAgaW5wdXRPdXRwdXQ6IFwib3V0cHV0XCIsXG4gICAgcGFpcnNXaXRoOiBcInBpY2t1cFwiXG4gIH0sXG4gIFwicGlja3VwXCI6IHtcbiAgICBpZDogXCJwaWNrdXBcIixcbiAgICBsYWJlbDogXCJwaWNrdXBcIixcbiAgICByZXNvdXJjZUVmZmVjdDogXCJpbmNyZW1lbnRcIixcbiAgICBvbmhhbmRFZmZlY3Q6IFwiaW5jcmVtZW50XCIsXG4gICAgaW5wdXRPdXRwdXQ6IFwiaW5wdXRcIixcbiAgICBwYWlyc1dpdGg6IFwiZHJvcG9mZlwiXG4gIH0sXG4gIFwiY29uc3VtZVwiOiB7XG4gICAgaWQ6IFwiY29uc3VtZVwiLFxuICAgIGxhYmVsOiBcImNvbnN1bWVcIixcbiAgICByZXNvdXJjZUVmZmVjdDogXCJkZWNyZW1lbnRcIixcbiAgICBvbmhhbmRFZmZlY3Q6IFwiZGVjcmVtZW50XCIsXG4gICAgaW5wdXRPdXRwdXQ6IFwiaW5wdXRcIixcbiAgICBwYWlyc1dpdGg6IFwibm90QXBwbGljYWJsZVwiXG4gIH0sXG4gIFwidXNlXCI6IHtcbiAgICBpZDogXCJ1c2VcIixcbiAgICBsYWJlbDogXCJ1c2VcIixcbiAgICByZXNvdXJjZUVmZmVjdDogXCJub0VmZmVjdFwiLFxuICAgIG9uaGFuZEVmZmVjdDogXCJub0VmZmVjdFwiLFxuICAgIGlucHV0T3V0cHV0OiBcImlucHV0XCIsXG4gICAgcGFpcnNXaXRoOiBcIm5vdEFwcGxpY2FibGVcIlxuICB9LFxuICBcIndvcmtcIjoge1xuICAgIGlkOiBcIndvcmtcIixcbiAgICBsYWJlbDogXCJ3b3JrXCIsXG4gICAgcmVzb3VyY2VFZmZlY3Q6IFwibm9FZmZlY3RcIixcbiAgICBvbmhhbmRFZmZlY3Q6IFwibm9FZmZlY3RcIixcbiAgICBpbnB1dE91dHB1dDogXCJpbnB1dFwiLFxuICAgIHBhaXJzV2l0aDogXCJub3RBcHBsaWNhYmxlXCJcbiAgfSxcbiAgXCJjaXRlXCI6IHtcbiAgICBpZDogXCJjaXRlXCIsXG4gICAgbGFiZWw6IFwiY2l0ZVwiLFxuICAgIHJlc291cmNlRWZmZWN0OiBcIm5vRWZmZWN0XCIsXG4gICAgb25oYW5kRWZmZWN0OiBcIm5vRWZmZWN0XCIsXG4gICAgaW5wdXRPdXRwdXQ6IFwiaW5wdXRcIixcbiAgICBwYWlyc1dpdGg6IFwibm90QXBwbGljYWJsZVwiXG4gIH0sXG4gIFwicHJvZHVjZVwiOiB7XG4gICAgaWQ6IFwicHJvZHVjZVwiLFxuICAgIGxhYmVsOiBcInByb2R1Y2VcIixcbiAgICByZXNvdXJjZUVmZmVjdDogXCJpbmNyZW1lbnRcIixcbiAgICBvbmhhbmRFZmZlY3Q6IFwiaW5jcmVtZW50XCIsXG4gICAgaW5wdXRPdXRwdXQ6IFwib3V0cHV0XCIsXG4gICAgcGFpcnNXaXRoOiBcIm5vdEFwcGxpY2FibGVcIlxuICB9LFxuICBcImFjY2VwdFwiOiB7XG4gICAgaWQ6IFwiYWNjZXB0XCIsXG4gICAgbGFiZWw6IFwiYWNjZXB0XCIsXG4gICAgcmVzb3VyY2VFZmZlY3Q6IFwibm9FZmZlY3RcIixcbiAgICBvbmhhbmRFZmZlY3Q6IFwiZGVjcmVtZW50XCIsXG4gICAgaW5wdXRPdXRwdXQ6IFwiaW5wdXRcIixcbiAgICBwYWlyc1dpdGg6IFwibW9kaWZ5XCJcbiAgfSxcbiAgXCJtb2RpZnlcIjoge1xuICAgIGlkOiBcIm1vZGlmeVwiLFxuICAgIGxhYmVsOiBcIm1vZGlmeVwiLFxuICAgIHJlc291cmNlRWZmZWN0OiBcIm5vRWZmZWN0XCIsXG4gICAgb25oYW5kRWZmZWN0OiBcImluY3JlbWVudFwiLFxuICAgIGlucHV0T3V0cHV0OiBcIm91dHB1dFwiLFxuICAgIHBhaXJzV2l0aDogXCJhY2NlcHRcIlxuICB9LFxuICBcInBhc3NcIjoge1xuICAgIGlkOiBcInBhc3NcIixcbiAgICBsYWJlbDogXCJwYXNzXCIsXG4gICAgcmVzb3VyY2VFZmZlY3Q6IFwibm9FZmZlY3RcIixcbiAgICBvbmhhbmRFZmZlY3Q6IFwibm9FZmZlY3RcIixcbiAgICBpbnB1dE91dHB1dDogXCJvdXRwdXRcIixcbiAgICBwYWlyc1dpdGg6IFwiYWNjZXB0XCJcbiAgfSxcbiAgXCJmYWlsXCI6IHtcbiAgICBpZDogXCJmYWlsXCIsXG4gICAgbGFiZWw6IFwiZmFpbFwiLFxuICAgIHJlc291cmNlRWZmZWN0OiBcIm5vRWZmZWN0XCIsXG4gICAgb25oYW5kRWZmZWN0OiBcIm5vRWZmZWN0XCIsXG4gICAgaW5wdXRPdXRwdXQ6IFwib3V0cHV0XCIsXG4gICAgcGFpcnNXaXRoOiBcImFjY2VwdFwiXG4gIH0sXG4gIFwiZGVsaXZlci1zZXJ2aWNlXCI6IHtcbiAgICBpZDogXCJkZWxpdmVyLXNlcnZpY2VcIixcbiAgICBsYWJlbDogXCJkZWxpdmVyLXNlcnZpY2VcIixcbiAgICByZXNvdXJjZUVmZmVjdDogXCJub0VmZmVjdFwiLFxuICAgIG9uaGFuZEVmZmVjdDogXCJub0VmZmVjdFwiLFxuICAgIGlucHV0T3V0cHV0OiBcIm91dHB1dFwiLFxuICAgIHBhaXJzV2l0aDogXCJub3RBcHBsaWNhYmxlXCJcbiAgfSxcbiAgXCJ0cmFuc2Zlci1hbGwtcmlnaHRzXCI6IHtcbiAgICBpZDogXCJ0cmFuc2Zlci1hbGwtcmlnaHRzXCIsXG4gICAgbGFiZWw6IFwidHJhbnNmZXItYWxsLXJpZ2h0c1wiLFxuICAgIHJlc291cmNlRWZmZWN0OiBcImRlY3JlbWVudEluY3JlbWVudFwiLFxuICAgIG9uaGFuZEVmZmVjdDogXCJub0VmZmVjdFwiLFxuICAgIGlucHV0T3V0cHV0OiBcIm5vdEFwcGxpY2FibGVcIixcbiAgICBwYWlyc1dpdGg6IFwibm90QXBwbGljYWJsZVwiXG4gIH0sXG4gIFwidHJhbnNmZXItY3VzdG9keVwiOiB7XG4gICAgaWQ6IFwidHJhbnNmZXItY3VzdG9keVwiLFxuICAgIGxhYmVsOiBcInRyYW5zZmVyLWN1c3RvZHlcIixcbiAgICByZXNvdXJjZUVmZmVjdDogXCJub0VmZmVjdFwiLFxuICAgIG9uaGFuZEVmZmVjdDogXCJkZWNyZW1lbnRJbmNyZW1lbnRcIixcbiAgICBpbnB1dE91dHB1dDogXCJub3RBcHBsaWNhYmxlXCIsXG4gICAgcGFpcnNXaXRoOiBcIm5vdEFwcGxpY2FibGVcIlxuICB9LFxuICBcInRyYW5zZmVyXCI6IHtcbiAgICBpZDogXCJ0cmFuc2ZlclwiLFxuICAgIGxhYmVsOiBcInRyYW5zZmVyXCIsXG4gICAgcmVzb3VyY2VFZmZlY3Q6IFwiZGVjcmVtZW50SW5jcmVtZW50XCIsXG4gICAgb25oYW5kRWZmZWN0OiBcImRlY3JlbWVudEluY3JlbWVudFwiLFxuICAgIGlucHV0T3V0cHV0OiBcIm5vdEFwcGxpY2FibGVcIixcbiAgICBwYWlyc1dpdGg6IFwibm90QXBwbGljYWJsZVwiXG4gIH0sXG4gIFwibW92ZVwiOiB7XG4gICAgaWQ6IFwibW92ZVwiLFxuICAgIGxhYmVsOiBcIm1vdmVcIixcbiAgICByZXNvdXJjZUVmZmVjdDogXCJkZWNyZW1lbnRJbmNyZW1lbnRcIixcbiAgICBvbmhhbmRFZmZlY3Q6IFwiZGVjcmVtZW50SW5jcmVtZW50XCIsXG4gICAgaW5wdXRPdXRwdXQ6IFwibm90QXBwbGljYWJsZVwiLFxuICAgIHBhaXJzV2l0aDogXCJub3RBcHBsaWNhYmxlXCJcbiAgfSxcbiAgXCJyYWlzZVwiOiB7XG4gICAgaWQ6IFwicmFpc2VcIixcbiAgICBsYWJlbDogXCJyYWlzZVwiLFxuICAgIHJlc291cmNlRWZmZWN0OiBcImluY3JlbWVudFwiLFxuICAgIG9uaGFuZEVmZmVjdDogXCJpbmNyZW1lbnRcIixcbiAgICBpbnB1dE91dHB1dDogXCJub3RBcHBsaWNhYmxlXCIsXG4gICAgcGFpcnNXaXRoOiBcIm5vdEFwcGxpY2FibGVcIlxuICB9LFxuICBcImxvd2VyXCI6IHtcbiAgICBpZDogXCJsb3dlclwiLFxuICAgIGxhYmVsOiBcImxvd2VyXCIsXG4gICAgcmVzb3VyY2VFZmZlY3Q6IFwiZGVjcmVtZW50XCIsXG4gICAgb25oYW5kRWZmZWN0OiBcImRlY3JlbWVudFwiLFxuICAgIGlucHV0T3V0cHV0OiBcIm5vdEFwcGxpY2FibGVcIixcbiAgICBwYWlyc1dpdGg6IFwibm90QXBwbGljYWJsZVwiXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFjdGlvbihpZDogc3RyaW5nKSB7XG4gIHJldHVybiBhY3Rpb25zW2lkXVxufSJdfQ==