This repository has been archived on 2024-11-13. You can view files and clone it, but cannot push or open issues or pull requests.
fediversity.eu/node_modules/prettier-plugin-go-template/lib/index.js
2024-03-26 16:28:28 +01:00

256 lines
35 KiB
JavaScript

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.printers = exports.parsers = exports.languages = exports.options = void 0;
const prettier_1 = require("prettier");
const doc_1 = require("prettier/doc");
const parser_html_1 = require("prettier/parser-html");
const parse_1 = require("./parse");
const htmlParser = parser_html_1.parsers.html;
const PLUGIN_KEY = "go-template";
exports.options = {
goTemplateBracketSpacing: {
type: "boolean",
category: "Global",
description: "Specifies whether the brackets should have spacing around the statement.",
default: true,
},
};
exports.languages = [
{
name: "GoTemplate",
parsers: [PLUGIN_KEY],
extensions: [
".go.html",
".gohtml",
".gotmpl",
".go.tmpl",
".tmpl",
".tpl",
".html.tmpl",
".html.tpl",
],
vscodeLanguageIds: ["gotemplate", "gohtml", "GoTemplate", "GoHTML"],
},
];
exports.parsers = {
[PLUGIN_KEY]: {
astFormat: PLUGIN_KEY,
preprocess: (text) => text.endsWith("\n") ? text.slice(0, text.length - 1) : text,
parse: parse_1.parseGoTemplate,
locStart: (node) => node.index,
locEnd: (node) => node.index + node.length,
},
};
exports.printers = {
[PLUGIN_KEY]: {
print: (path, options, print) => {
const node = path.getNode();
switch (node === null || node === void 0 ? void 0 : node.type) {
case "inline":
return printInline(node, path, options, print);
case "double-block":
return printMultiBlock(node, path, print);
case "unformattable":
return printUnformattable(node, options);
}
throw new Error(`An error occured during printing. Found invalid node ${node === null || node === void 0 ? void 0 : node.type}.`);
},
embed: (path, options) => {
try {
return embed(path, options);
}
catch (e) {
console.error("Formatting failed.", e);
throw e;
}
},
},
};
const embed = () => {
return (textToDoc, print, path, optionsA) => __awaiter(void 0, void 0, void 0, function* () {
const node = path.getNode();
const options = optionsA;
if (!node) {
return undefined;
}
if (hasPrettierIgnoreLine(node)) {
return options.originalText.substring(options.locStart(node), options.locEnd(node));
}
if (node.type !== "block" && node.type !== "root") {
return undefined;
}
const html = yield textToDoc(node.aliasedContent, Object.assign(Object.assign({}, options), { parser: "html", parentParser: "go-template" }));
const mapped = doc_1.utils.stripTrailingHardline(doc_1.utils.mapDoc(html, (currentDoc) => {
if (typeof currentDoc !== "string") {
return currentDoc;
}
let result = currentDoc;
Object.keys(node.children).forEach((key) => (result = prettier_1.doc.utils.mapDoc(result, (docNode) => typeof docNode !== "string" || !docNode.includes(key)
? docNode
: [
docNode.substring(0, docNode.indexOf(key)),
path.call(print, "children", key),
docNode.substring(docNode.indexOf(key) + key.length),
])));
return result;
}));
if ((0, parse_1.isRoot)(node)) {
return [mapped, doc_1.builders.hardline];
}
const startStatement = path.call(print, "start");
const endStatement = node.end ? path.call(print, "end") : "";
if (isPrettierIgnoreBlock(node)) {
return [
doc_1.utils.removeLines(path.call(print, "start")),
printPlainBlock(node.content),
endStatement,
];
}
const content = node.aliasedContent.trim()
? doc_1.builders.indent([doc_1.builders.softline, mapped])
: "";
const result = [startStatement, content, doc_1.builders.softline, endStatement];
const emptyLine = !!node.end && isFollowedByEmptyLine(node.end, options.originalText)
? doc_1.builders.softline
: "";
if ((0, parse_1.isMultiBlock)(node.parent)) {
return [result, emptyLine];
}
return doc_1.builders.group([doc_1.builders.group(result), emptyLine], {
shouldBreak: !!node.end && hasNodeLinebreak(node.end, options.originalText),
});
});
};
function printMultiBlock(node, path, print) {
return [...path.map(print, "blocks")];
}
function isFollowedByNode(node) {
const parent = getFirstBlockParent(node).parent;
const start = parent.aliasedContent.indexOf(node.id) + node.id.length;
let nextNodeIndex = -1;
Object.keys(parent.children).forEach((key) => {
const index = parent.aliasedContent.indexOf(key, start);
if (nextNodeIndex == -1 || index < nextNodeIndex) {
nextNodeIndex = index;
}
});
return !!parent.aliasedContent
.substring(start, nextNodeIndex)
.match(/^\s+$/m);
}
function printInline(node, path, options, print) {
const isBlockNode = isBlockEnd(node) || isBlockStart(node);
const emptyLine = isFollowedByEmptyLine(node, options.originalText) && isFollowedByNode(node)
? doc_1.builders.softline
: "";
const result = [
printStatement(node.statement, options.goTemplateBracketSpacing, {
start: node.startDelimiter,
end: node.endDelimiter,
}),
];
return doc_1.builders.group([...result, emptyLine], {
shouldBreak: hasNodeLinebreak(node, options.originalText) && !isBlockNode,
});
}
function isBlockEnd(node) {
const { parent } = getFirstBlockParent(node);
return (0, parse_1.isBlock)(parent) && parent.end === node;
}
function isBlockStart(node) {
const { parent } = getFirstBlockParent(node);
return (0, parse_1.isBlock)(parent) && parent.start === node;
}
function printStatement(statement, addSpaces, delimiter = {
start: "",
end: "",
}) {
const space = addSpaces ? " " : "";
const shouldBreak = statement.includes("\n");
const content = shouldBreak
? statement
.trim()
.split("\n")
.map((line, _, array) => array.indexOf(line) === array.length - 1
? [line.trim(), doc_1.builders.softline]
: doc_1.builders.indent([line.trim(), doc_1.builders.softline]))
: [statement.trim()];
return doc_1.builders.group([
"{{",
delimiter.start,
space,
...content,
shouldBreak ? "" : space,
delimiter.end,
"}}",
], { shouldBreak });
}
function hasPrettierIgnoreLine(node) {
if ((0, parse_1.isRoot)(node)) {
return false;
}
const { parent, child } = getFirstBlockParent(node);
const regex = new RegExp(`(?:<!--|{{).*?prettier-ignore.*?(?:-->|}})\n.*${child.id}`);
return !!parent.aliasedContent.match(regex);
}
function isPrettierIgnoreBlock(node) {
return (0, parse_1.isBlock)(node) && node.keyword === "prettier-ignore-start";
}
function hasNodeLinebreak(node, source) {
const start = node.index + node.length;
const end = source.indexOf("\n", start);
const suffix = source.substring(start, end);
return !suffix;
}
function isFollowedByEmptyLine(node, source) {
const start = node.index + node.length;
const firstLineBreak = source.indexOf("\n", start);
const secondLineBreak = source.indexOf("\n", firstLineBreak + 1);
const emptyLine = source
.substring(firstLineBreak + 1, secondLineBreak)
.trim();
const isLastNode = !!source.substring(start).match(/^\s*$/);
return (firstLineBreak !== -1 && secondLineBreak !== -1 && !emptyLine && !isLastNode);
}
function getFirstBlockParent(node) {
let previous = node;
let current = node.parent;
while (!(0, parse_1.isBlock)(current) && !(0, parse_1.isRoot)(current)) {
previous = current;
current = current.parent;
}
return {
child: previous,
parent: current,
};
}
function printUnformattable(node, options) {
var _a, _b;
const start = options.originalText.lastIndexOf("\n", node.index - 1);
const line = options.originalText.substring(start, node.index + node.length);
const lineWithoutAdditionalContent = (_b = (_a = line.replace(node.content, "").match(/\s*$/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : "";
return printPlainBlock(lineWithoutAdditionalContent + node.content, false);
}
function printPlainBlock(text, hardlines = true) {
const isTextEmpty = (input) => !!input.match(/^\s*$/);
const lines = text.split("\n");
const segments = lines.filter((value, i) => !(i == 0 || i == lines.length - 1) || !isTextEmpty(value));
return [
...segments.map((content, i) => [
hardlines || i ? doc_1.builders.hardline : "",
doc_1.builders.trim,
content,
]),
hardlines ? doc_1.builders.hardline : "",
];
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsdUNBT2tCO0FBQ2xCLHNDQUErQztBQUMvQyxzREFBOEQ7QUFDOUQsbUNBYWlCO0FBRWpCLE1BQU0sVUFBVSxHQUFHLHFCQUFXLENBQUMsSUFBSSxDQUFDO0FBQ3BDLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQztBQVNwQixRQUFBLE9BQU8sR0FFaEI7SUFDRix3QkFBd0IsRUFBRTtRQUN4QixJQUFJLEVBQUUsU0FBUztRQUNmLFFBQVEsRUFBRSxRQUFRO1FBQ2xCLFdBQVcsRUFDVCwwRUFBMEU7UUFDNUUsT0FBTyxFQUFFLElBQUk7S0FDZDtDQUNGLENBQUM7QUFFVyxRQUFBLFNBQVMsR0FBc0I7SUFDMUM7UUFDRSxJQUFJLEVBQUUsWUFBWTtRQUNsQixPQUFPLEVBQUUsQ0FBQyxVQUFVLENBQUM7UUFDckIsVUFBVSxFQUFFO1lBQ1YsVUFBVTtZQUNWLFNBQVM7WUFDVCxTQUFTO1lBQ1QsVUFBVTtZQUNWLE9BQU87WUFDUCxNQUFNO1lBQ04sWUFBWTtZQUNaLFdBQVc7U0FDWjtRQUNELGlCQUFpQixFQUFFLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsUUFBUSxDQUFDO0tBQ3BFO0NBQ0YsQ0FBQztBQUNXLFFBQUEsT0FBTyxHQUFHO0lBQ3JCLENBQUMsVUFBVSxDQUFDLEVBQWtCO1FBQzVCLFNBQVMsRUFBRSxVQUFVO1FBQ3JCLFVBQVUsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBRW5CLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUk7UUFDN0QsS0FBSyxFQUFFLHVCQUFlO1FBQ3RCLFFBQVEs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QUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFL0IsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FDM0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FDeEUsQ0FBQztJQUVGLE9BQU87UUFDTCxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUM5QixTQUFTLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ3ZDLGNBQVEsQ0FBQyxJQUFJO1lBQ2IsT0FBTztTQUNSLENBQUM7UUFDRixTQUFTLENBQUMsQ0FBQyxDQUFDLGNBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUU7S0FDbkMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBkb2MsXG4gIEZhc3RQYXRoLFxuICBQYXJzZXIsXG4gIFBhcnNlck9wdGlvbnMsXG4gIFByaW50ZXIsXG4gIFN1cHBvcnRMYW5ndWFnZSxcbn0gZnJvbSBcInByZXR0aWVyXCI7XG5pbXBvcnQgeyBidWlsZGVycywgdXRpbHMgfSBmcm9tIFwicHJldHRpZXIvZG9jXCI7XG5pbXBvcnQgeyBwYXJzZXJzIGFzIGh0bWxQYXJzZXJzIH0gZnJvbSBcInByZXR0aWVyL3BhcnNlci1odG1sXCI7XG5pbXBvcnQge1xuICBHb0Jsb2NrLFxuICBHb0lubGluZSxcbiAgR29JbmxpbmVFbmREZWxpbWl0ZXIsXG4gIEdvSW5saW5lU3RhcnREZWxpbWl0ZXIsXG4gIEdvTXVsdGlCbG9jayxcbiAgR29Ob2RlLFxuICBHb1Jvb3QsXG4gIEdvVW5mb3JtYXR0YWJsZSxcbiAgaXNCbG9jayxcbiAgaXNNdWx0aUJsb2NrLFxuICBpc1Jvb3QsXG4gIHBhcnNlR29UZW1wbGF0ZSxcbn0gZnJvbSBcIi4vcGFyc2VcIjtcblxuY29uc3QgaHRtbFBhcnNlciA9IGh0bWxQYXJzZXJzLmh0bWw7XG5jb25zdCBQTFVHSU5fS0VZID0gXCJnby10ZW1wbGF0ZVwiO1xuXG50eXBlIEV4dGVuZGVkUGFyc2VyT3B0aW9ucyA9IFBhcnNlck9wdGlvbnM8R29Ob2RlPiAmXG4gIFByZXR0aWVyUGx1Z2luR29UZW1wbGF0ZVBhcnNlck9wdGlvbnM7XG5cbmV4cG9ydCB0eXBlIFByZXR0aWVyUGx1Z2luR29UZW1wbGF0ZVBhcnNlck9wdGlvbnMgPSB7XG4gIGdvVGVtcGxhdGVCcmFja2V0U3BhY2luZzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBjb25zdCBvcHRpb25zOiB7XG4gIFtLIGluIGtleW9mIFByZXR0aWVyUGx1Z2luR29UZW1wbGF0ZVBhcnNlck9wdGlvbnNdOiBhbnk7XG59ID0ge1xuICBnb1RlbXBsYXRlQnJhY2tldFNwYWNpbmc6IHtcbiAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICBjYXRlZ29yeTogXCJHbG9iYWxcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiU3BlY2lmaWVzIHdoZXRoZXIgdGhlIGJyYWNrZXRzIHNob3VsZCBoYXZlIHNwYWNpbmcgYXJvdW5kIHRoZSBzdGF0ZW1lbnQuXCIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbn07XG5cbmV4cG9ydCBjb25zdCBsYW5ndWFnZXM6IFN1cHBvcnRMYW5ndWFnZVtdID0gW1xuICB7XG4gICAgbmFtZTogXCJHb1RlbXBsYXRlXCIsXG4gICAgcGFyc2VyczogW1BMVUdJTl9LRVldLFxuICAgIGV4dGVuc2lvbnM6IFtcbiAgICAgIFwiLmdvLmh0bWxcIixcbiAgICAgIFwiLmdvaHRtbFwiLFxuICAgICAgXCIuZ290bXBsXCIsXG4gICAgICBcIi5nby50bXBsXCIsXG4gICAgICBcIi50bXBsXCIsXG4gICAgICBcIi50cGxcIixcbiAgICAgIFwiLmh0bWwudG1wbFwiLFxuICAgICAgXCIuaHRtbC50cGxcIixcbiAgICBdLFxuICAgIHZzY29kZUxhbmd1YWdlSWRzOiBbXCJnb3RlbXBsYXRlXCIsIFwiZ29odG1sXCIsIFwiR29UZW1wbGF0ZVwiLCBcIkdvSFRNTFwiXSxcbiAgfSxcbl07XG5leHBvcnQgY29uc3QgcGFyc2VycyA9IHtcbiAgW1BMVUdJTl9LRVldOiA8UGFyc2VyPEdvTm9kZT4+e1xuICAgIGFzdEZvcm1hdDogUExVR0lOX0tFWSxcbiAgICBwcmVwcm9jZXNzOiAodGV4dCkgPT5cbiAgICAgIC8vIEN1dCBhd2F5IHRyYWlsaW5nIG5ld2xpbmUgdG8gbm9ybWFsaXplIGZvcm1hdHRpbmcuXG4gICAgICB0ZXh0LmVuZHNXaXRoKFwiXFxuXCIpID8gdGV4dC5zbGljZSgwLCB0ZXh0Lmxlbmd0aCAtIDEpIDogdGV4dCxcbiAgICBwYXJzZTogcGFyc2VHb1RlbXBsYXRlLFxuICAgIGxvY1N0YXJ0OiAobm9kZSkgPT4gbm9kZS5pbmRleCxcbiAgICBsb2NFbmQ6IChub2RlKSA9PiBub2RlLmluZGV4ICsgbm9kZS5sZW5ndGgsXG4gIH0sXG59O1xuZXhwb3J0IGNvbnN0IHByaW50ZXJzID0ge1xuICBbUExVR0lOX0tFWV06IDxQcmludGVyPEdvTm9kZT4+e1xuICAgIHByaW50OiAocGF0aCwgb3B0aW9uczogRXh0ZW5kZWRQYXJzZXJPcHRpb25zLCBwcmludCkgPT4ge1xuICAgICAgY29uc3Qgbm9kZSA9IHBhdGguZ2V0Tm9kZSgpO1xuXG4gICAgICBzd2l0Y2ggKG5vZGU/LnR5cGUpIHtcbiAgICAgICAgY2FzZSBcImlubGluZVwiOlxuICAgICAgICAgIHJldHVybiBwcmludElubGluZShub2RlLCBwYXRoLCBvcHRpb25zLCBwcmludCk7XG4gICAgICAgIGNhc2UgXCJkb3VibGUtYmxvY2tcIjpcbiAgICAgICAgICByZXR1cm4gcHJpbnRNdWx0aUJsb2NrKG5vZGUsIHBhdGgsIHByaW50KTtcbiAgICAgICAgY2FzZSBcInVuZm9ybWF0dGFibGVcIjpcbiAgICAgICAgICByZXR1cm4gcHJpbnRVbmZvcm1hdHRhYmxlKG5vZGUsIG9wdGlvbnMpO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBBbiBlcnJvciBvY2N1cmVkIGR1cmluZyBwcmludGluZy4gRm91bmQgaW52YWxpZCBub2RlICR7bm9kZT8udHlwZX0uYCxcbiAgICAgICk7XG4gICAgfSxcbiAgICBlbWJlZDogKHBhdGgsIG9wdGlvbnMpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBlbWJlZChwYXRoLCBvcHRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkZvcm1hdHRpbmcgZmFpbGVkLlwiLCBlKTtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9LFxuICB9LFxufTtcblxuY29uc3QgZW1iZWQ6IEV4Y2x1ZGU8UHJpbnRlcjxHb05vZGU+W1wiZW1iZWRcIl0sIHVuZGVmaW5lZD4gPSAoKSA9PiB7XG4gIHJldHVybiBhc3luYyAodGV4dFRvRG9jLCBwcmludCwgcGF0aCwgb3B0aW9uc0EpID0+IHtcbiAgICBjb25zdCBub2RlID0gcGF0aC5nZXROb2RlKCk7XG5cbiAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0EgYXMgUGFyc2VyT3B0aW9ucztcblxuICAgIGlmICghbm9kZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoaGFzUHJldHRpZXJJZ25vcmVMaW5lKG5vZGUpKSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5vcmlnaW5hbFRleHQuc3Vic3RyaW5nKFxuICAgICAgICBvcHRpb25zLmxvY1N0YXJ0KG5vZGUpLFxuICAgICAgICBvcHRpb25zLmxvY0VuZChub2RlKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUudHlwZSAhPT0gXCJibG9ja1wiICYmIG5vZGUudHlwZSAhPT0gXCJyb290XCIpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgaHRtbCA9IGF3YWl0IHRleHRUb0RvYyhub2RlLmFsaWFzZWRDb250ZW50LCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgcGFyc2VyOiBcImh0bWxcIixcbiAgICAgIHBhcmVudFBhcnNlcjogXCJnby10ZW1wbGF0ZVwiLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWFwcGVkID0gdXRpbHMuc3RyaXBUcmFpbGluZ0hhcmRsaW5lKFxuICAgICAgdXRpbHMubWFwRG9jKGh0bWwsIChjdXJyZW50RG9jKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgY3VycmVudERvYyAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHJldHVybiBjdXJyZW50RG9jO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJlc3VsdDogYnVpbGRlcnMuRG9jID0gY3VycmVudERvYztcblxuICAgICAgICBPYmplY3Qua2V5cyhub2RlLmNoaWxkcmVuKS5mb3JFYWNoKFxuICAgICAgICAgIChrZXkpID0+XG4gICAgICAgICAgICAocmVzdWx0ID0gZG9jLnV0aWxzLm1hcERvYyhyZXN1bHQsIChkb2NOb2RlKSA9PlxuICAgICAgICAgICAgICB0eXBlb2YgZG9jTm9kZSAhPT0gXCJzdHJpbmdcIiB8fCAhZG9jTm9kZS5pbmNsdWRlcyhrZXkpXG4gICAgICAgICAgICAgICAgPyBkb2NOb2RlXG4gICAgICAgICAgICAgICAgOiBbXG4gICAgICAgICAgICAgICAgICAgIGRvY05vZGUuc3Vic3RyaW5nKDAsIGRvY05vZGUuaW5kZXhPZihrZXkpKSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aC5jYWxsKHByaW50LCBcImNoaWxkcmVuXCIsIGtleSksXG4gICAgICAgICAgICAgICAgICAgIGRvY05vZGUuc3Vic3RyaW5nKGRvY05vZGUuaW5kZXhPZihrZXkpICsga2V5Lmxlbmd0aCksXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgKSksXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBpZiAoaXNSb290KG5vZGUpKSB7XG4gICAgICByZXR1cm4gW21hcHBlZCwgYnVpbGRlcnMuaGFyZGxpbmVdO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0U3RhdGVtZW50ID0gcGF0aC5jYWxsKHByaW50LCBcInN0YXJ0XCIpO1xuICAgIGNvbnN0IGVuZFN0YXRlbWVudCA9IG5vZGUuZW5kID8gcGF0aC5jYWxsKHByaW50LCBcImVuZFwiKSA6IFwiXCI7XG5cbiAgICBpZiAoaXNQcmV0dGllcklnbm9yZUJsb2NrKG5vZGUpKSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB1dGlscy5yZW1vdmVMaW5lcyhwYXRoLmNhbGwocHJpbnQsIFwic3RhcnRcIikpLFxuICAgICAgICBwcmludFBsYWluQmxvY2sobm9kZS5jb250ZW50KSxcbiAgICAgICAgZW5kU3RhdGVtZW50LFxuICAgICAgXTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250ZW50ID0gbm9kZS5hbGlhc2VkQ29udGVudC50cmltKClcbiAgICAgID8gYnVpbGRlcnMuaW5kZW50KFtidWlsZGVycy5zb2Z0bGluZSwgbWFwcGVkXSlcbiAgICAgIDogXCJcIjtcblxuICAgIGNvbnN0IHJlc3VsdCA9IFtzdGFydFN0YXRlbWVudCwgY29udGVudCwgYnVpbGRlcnMuc29mdGxpbmUsIGVuZFN0YXRlbWVudF07XG5cbiAgICBjb25zdCBlbXB0eUxpbmUgPVxuICAgICAgISFub2RlLmVuZCAmJiBpc0ZvbGxvd2VkQnlFbXB0eUxpbmUobm9kZS5lbmQsIG9wdGlvbnMub3JpZ2luYWxUZXh0KVxuICAgICAgICA/IGJ1aWxkZXJzLnNvZnRsaW5lXG4gICAgICAgIDogXCJcIjtcblxuICAgIGlmIChpc011bHRpQmxvY2sobm9kZS5wYXJlbnQpKSB7XG4gICAgICByZXR1cm4gW3Jlc3VsdCwgZW1wdHlMaW5lXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVpbGRlcnMuZ3JvdXAoW2J1aWxkZXJzLmdyb3VwKHJlc3VsdCksIGVtcHR5TGluZV0sIHtcbiAgICAgIHNob3VsZEJyZWFrOlxuICAgICAgICAhIW5vZGUuZW5kICYmIGhhc05vZGVMaW5lYnJlYWsobm9kZS5lbmQsIG9wdGlvbnMub3JpZ2luYWxUZXh0KSxcbiAgICB9KTtcbiAgfTtcbn07XG5cbnR5cGUgUHJpbnRGbiA9IChwYXRoOiBGYXN0UGF0aDxHb05vZGU+KSA9PiBidWlsZGVycy5Eb2M7XG5cbmZ1bmN0aW9uIHByaW50TXVsdGlCbG9jayhcbiAgbm9kZTogR29NdWx0aUJsb2NrLFxuICBwYXRoOiBGYXN0UGF0aDxHb05vZGU+LFxuICBwcmludDogUHJpbnRGbixcbik6IGJ1aWxkZXJzLkRvYyB7XG4gIHJldHVybiBbLi4ucGF0aC5tYXAocHJpbnQsIFwiYmxvY2tzXCIpXTtcbn1cblxuZnVuY3Rpb24gaXNGb2xsb3dlZEJ5Tm9kZShub2RlOiBHb0lubGluZSk6IGJvb2xlYW4ge1xuICBjb25zdCBwYXJlbnQgPSBnZXRGaXJzdEJsb2NrUGFyZW50KG5vZGUpLnBhcmVudDtcbiAgY29uc3Qgc3RhcnQgPSBwYXJlbnQuYWxpYXNlZENvbnRlbnQuaW5kZXhPZihub2RlLmlkKSArIG5vZGUuaWQubGVuZ3RoO1xuXG4gIGxldCBuZXh0Tm9kZUluZGV4ID0gLTE7XG4gIE9iamVjdC5rZXlzKHBhcmVudC5jaGlsZHJlbikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgY29uc3QgaW5kZXggPSBwYXJlbnQuYWxpYXNlZENvbnRlbnQuaW5kZXhPZihrZXksIHN0YXJ0KTtcbiAgICBpZiAobmV4dE5vZGVJbmRleCA9PSAtMSB8fCBpbmRleCA8IG5leHROb2RlSW5kZXgpIHtcbiAgICAgIG5leHROb2RlSW5kZXggPSBpbmRleDtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiAhIXBhcmVudC5hbGlhc2VkQ29udGVudFxuICAgIC5zdWJzdHJpbmcoc3RhcnQsIG5leHROb2RlSW5kZXgpXG4gICAgLm1hdGNoKC9eXFxzKyQvbSk7XG59XG5cbmZ1bmN0aW9uIHByaW50SW5saW5lKFxuICBub2RlOiBHb0lubGluZSxcbiAgcGF0aDogRmFzdFBhdGg8R29Ob2RlPixcbiAgb3B0aW9uczogRXh0ZW5kZWRQYXJzZXJPcHRpb25zLFxuICBwcmludDogUHJpbnRGbixcbik6IGJ1aWxkZXJzLkRvYyB7XG4gIGNvbnN0IGlzQmxvY2tOb2RlID0gaXNCbG9ja0VuZChub2RlKSB8fCBpc0Jsb2NrU3RhcnQobm9kZSk7XG4gIGNvbnN0IGVtcHR5TGluZSA9XG4gICAgaXNGb2xsb3dlZEJ5RW1wdHlMaW5lKG5vZGUsIG9wdGlvbnMub3JpZ2luYWxUZXh0KSAmJiBpc0ZvbGxvd2VkQnlOb2RlKG5vZGUpXG4gICAgICA/IGJ1aWxkZXJzLnNvZnRsaW5lXG4gICAgICA6IFwiXCI7XG5cbiAgY29uc3QgcmVzdWx0OiBidWlsZGVycy5Eb2NbXSA9IFtcbiAgICBwcmludFN0YXRlbWVudChub2RlLnN0YXRlbWVudCwgb3B0aW9ucy5nb1RlbXBsYXRlQnJhY2tldFNwYWNpbmcsIHtcbiAgICAgIHN0YXJ0OiBub2RlLnN0YXJ0RGVsaW1pdGVyLFxuICAgICAgZW5kOiBub2RlLmVuZERlbGltaXRlcixcbiAgICB9KSxcbiAgXTtcblxuICByZXR1cm4gYnVpbGRlcnMuZ3JvdXAoWy4uLnJlc3VsdCwgZW1wdHlMaW5lXSwge1xuICAgIHNob3VsZEJyZWFrOiBoYXNOb2RlTGluZWJyZWFrKG5vZGUsIG9wdGlvbnMub3JpZ2luYWxUZXh0KSAmJiAhaXNCbG9ja05vZGUsXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBpc0Jsb2NrRW5kKG5vZGU6IEdvSW5saW5lKSB7XG4gIGNvbnN0IHsgcGFyZW50IH0gPSBnZXRGaXJzdEJsb2NrUGFyZW50KG5vZGUpO1xuICByZXR1cm4gaXNCbG9jayhwYXJlbnQpICYmIHBhcmVudC5lbmQgPT09IG5vZGU7XG59XG5cbmZ1bmN0aW9uIGlzQmxvY2tTdGFydChub2RlOiBHb0lubGluZSkge1xuICBjb25zdCB7IHBhcmVudCB9ID0gZ2V0Rmlyc3RCbG9ja1BhcmVudChub2RlKTtcbiAgcmV0dXJuIGlzQmxvY2socGFyZW50KSAmJiBwYXJlbnQuc3RhcnQgPT09IG5vZGU7XG59XG5cbmZ1bmN0aW9uIHByaW50U3RhdGVtZW50KFxuICBzdGF0ZW1lbnQ6IHN0cmluZyxcbiAgYWRkU3BhY2VzOiBib29sZWFuLFxuICBkZWxpbWl0ZXI6IHsgc3RhcnQ6IEdvSW5saW5lU3RhcnREZWxpbWl0ZXI7IGVuZDogR29JbmxpbmVFbmREZWxpbWl0ZXIgfSA9IHtcbiAgICBzdGFydDogXCJcIixcbiAgICBlbmQ6IFwiXCIsXG4gIH0sXG4pIHtcbiAgY29uc3Qgc3BhY2UgPSBhZGRTcGFjZXMgPyBcIiBcIiA6IFwiXCI7XG4gIGNvbnN0IHNob3VsZEJyZWFrID0gc3RhdGVtZW50LmluY2x1ZGVzKFwiXFxuXCIpO1xuXG4gIGNvbnN0IGNvbnRlbnQgPSBzaG91bGRCcmVha1xuICAgID8gc3RhdGVtZW50XG4gICAgICAgIC50cmltKClcbiAgICAgICAgLnNwbGl0KFwiXFxuXCIpXG4gICAgICAgIC5tYXAoKGxpbmUsIF8sIGFycmF5KSA9PlxuICAgICAgICAgIGFycmF5LmluZGV4T2YobGluZSkgPT09IGFycmF5Lmxlbmd0aCAtIDFcbiAgICAgICAgICAgID8gW2xpbmUudHJpbSgpLCBidWlsZGVycy5zb2Z0bGluZV1cbiAgICAgICAgICAgIDogYnVpbGRlcnMuaW5kZW50KFtsaW5lLnRyaW0oKSwgYnVpbGRlcnMuc29mdGxpbmVdKSxcbiAgICAgICAgKVxuICAgIDogW3N0YXRlbWVudC50cmltKCldO1xuXG4gIHJldHVybiBidWlsZGVycy5ncm91cChcbiAgICBbXG4gICAgICBcInt7XCIsXG4gICAgICBkZWxpbWl0ZXIuc3RhcnQsXG4gICAgICBzcGFjZSxcbiAgICAgIC4uLmNvbnRlbnQsXG4gICAgICBzaG91bGRCcmVhayA/IFwiXCIgOiBzcGFjZSxcbiAgICAgIGRlbGltaXRlci5lbmQsXG4gICAgICBcIn19XCIsXG4gICAgXSxcbiAgICB7IHNob3VsZEJyZWFrIH0sXG4gICk7XG59XG5cbmZ1bmN0aW9uIGhhc1ByZXR0aWVySWdub3JlTGluZShub2RlOiBHb05vZGUpIHtcbiAgaWYgKGlzUm9vdChub2RlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHsgcGFyZW50LCBjaGlsZCB9ID0gZ2V0Rmlyc3RCbG9ja1BhcmVudChub2RlKTtcblxuICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgYCg/OjwhLS18e3spLio/cHJldHRpZXItaWdub3JlLio/KD86LS0+fH19KVxcbi4qJHtjaGlsZC5pZH1gLFxuICApO1xuXG4gIHJldHVybiAhIXBhcmVudC5hbGlhc2VkQ29udGVudC5tYXRjaChyZWdleCk7XG59XG5cbmZ1bmN0aW9uIGlzUHJldHRpZXJJZ25vcmVCbG9jayhub2RlOiBHb05vZGUpIHtcbiAgcmV0dXJuIGlzQmxvY2sobm9kZSkgJiYgbm9kZS5rZXl3b3JkID09PSBcInByZXR0aWVyLWlnbm9yZS1zdGFydFwiO1xufVxuXG5mdW5jdGlvbiBoYXNOb2RlTGluZWJyZWFrKG5vZGU6IEdvSW5saW5lLCBzb3VyY2U6IHN0cmluZykge1xuICBjb25zdCBzdGFydCA9IG5vZGUuaW5kZXggKyBub2RlLmxlbmd0aDtcbiAgY29uc3QgZW5kID0gc291cmNlLmluZGV4T2YoXCJcXG5cIiwgc3RhcnQpO1xuICBjb25zdCBzdWZmaXggPSBzb3VyY2Uuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpO1xuXG4gIHJldHVybiAhc3VmZml4O1xufVxuXG5mdW5jdGlvbiBpc0ZvbGxvd2VkQnlFbXB0eUxpbmUobm9kZTogR29JbmxpbmUsIHNvdXJjZTogc3RyaW5nKSB7XG4gIGNvbnN0IHN0YXJ0ID0gbm9kZS5pbmRleCArIG5vZGUubGVuZ3RoO1xuICBjb25zdCBmaXJzdExpbmVCcmVhayA9IHNvdXJjZS5pbmRleE9mKFwiXFxuXCIsIHN0YXJ0KTtcbiAgY29uc3Qgc2Vjb25kTGluZUJyZWFrID0gc291cmNlLmluZGV4T2YoXCJcXG5cIiwgZmlyc3RMaW5lQnJlYWsgKyAxKTtcbiAgY29uc3QgZW1wdHlMaW5lID0gc291cmNlXG4gICAgLnN1YnN0cmluZyhmaXJzdExpbmVCcmVhayArIDEsIHNlY29uZExpbmVCcmVhaylcbiAgICAudHJpbSgpO1xuICBjb25zdCBpc0xhc3ROb2RlID0gISFzb3VyY2Uuc3Vic3RyaW5nKHN0YXJ0KS5tYXRjaCgvXlxccyokLyk7XG5cbiAgcmV0dXJuIChcbiAgICBmaXJzdExpbmVCcmVhayAhPT0gLTEgJiYgc2Vjb25kTGluZUJyZWFrICE9PSAtMSAmJiAhZW1wdHlMaW5lICYmICFpc0xhc3ROb2RlXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldEZpcnN0QmxvY2tQYXJlbnQobm9kZTogRXhjbHVkZTxHb05vZGUsIEdvUm9vdD4pOiB7XG4gIHBhcmVudDogR29CbG9jayB8IEdvUm9vdDtcbiAgY2hpbGQ6IHR5cGVvZiBub2RlO1xufSB7XG4gIGxldCBwcmV2aW91cyA9IG5vZGU7XG4gIGxldCBjdXJyZW50ID0gbm9kZS5wYXJlbnQ7XG5cbiAgd2hpbGUgKCFpc0Jsb2NrKGN1cnJlbnQpICYmICFpc1Jvb3QoY3VycmVudCkpIHtcbiAgICBwcmV2aW91cyA9IGN1cnJlbnQ7XG4gICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBjaGlsZDogcHJldmlvdXMsXG4gICAgcGFyZW50OiBjdXJyZW50LFxuICB9O1xufVxuXG5mdW5jdGlvbiBwcmludFVuZm9ybWF0dGFibGUoXG4gIG5vZGU6IEdvVW5mb3JtYXR0YWJsZSxcbiAgb3B0aW9uczogRXh0ZW5kZWRQYXJzZXJPcHRpb25zLFxuKSB7XG4gIGNvbnN0IHN0YXJ0ID0gb3B0aW9ucy5vcmlnaW5hbFRleHQubGFzdEluZGV4T2YoXCJcXG5cIiwgbm9kZS5pbmRleCAtIDEpO1xuICBjb25zdCBsaW5lID0gb3B0aW9ucy5vcmlnaW5hbFRleHQuc3Vic3RyaW5nKHN0YXJ0LCBub2RlLmluZGV4ICsgbm9kZS5sZW5ndGgpO1xuICBjb25zdCBsaW5lV2l0aG91dEFkZGl0aW9uYWxDb250ZW50ID1cbiAgICBsaW5lLnJlcGxhY2Uobm9kZS5jb250ZW50LCBcIlwiKS5tYXRjaCgvXFxzKiQvKT8uWzBdID8/IFwiXCI7XG5cbiAgcmV0dXJuIHByaW50UGxhaW5CbG9jayhsaW5lV2l0aG91dEFkZGl0aW9uYWxDb250ZW50ICsgbm9kZS5jb250ZW50LCBmYWxzZSk7XG59XG5cbmZ1bmN0aW9uIHByaW50UGxhaW5CbG9jayh0ZXh0OiBzdHJpbmcsIGhhcmRsaW5lcyA9IHRydWUpOiBidWlsZGVycy5Eb2Mge1xuICBjb25zdCBpc1RleHRFbXB0eSA9IChpbnB1dDogc3RyaW5nKSA9PiAhIWlucHV0Lm1hdGNoKC9eXFxzKiQvKTtcblxuICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoXCJcXG5cIik7XG5cbiAgY29uc3Qgc2VnbWVudHMgPSBsaW5lcy5maWx0ZXIoXG4gICAgKHZhbHVlLCBpKSA9PiAhKGkgPT0gMCB8fCBpID09IGxpbmVzLmxlbmd0aCAtIDEpIHx8ICFpc1RleHRFbXB0eSh2YWx1ZSksXG4gICk7XG5cbiAgcmV0dXJuIFtcbiAgICAuLi5zZWdtZW50cy5tYXAoKGNvbnRlbnQsIGkpID0+IFtcbiAgICAgIGhhcmRsaW5lcyB8fCBpID8gYnVpbGRlcnMuaGFyZGxpbmUgOiBcIlwiLFxuICAgICAgYnVpbGRlcnMudHJpbSxcbiAgICAgIGNvbnRlbnQsXG4gICAgXSksXG4gICAgaGFyZGxpbmVzID8gYnVpbGRlcnMuaGFyZGxpbmUgOiBcIlwiLFxuICBdO1xufVxuIl19