@fly/edge
Version:
Fly's TypeScript Edge
166 lines • 22.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PathPatternMatcher = exports.buildRules = exports.validateRule = void 0;
/**
* @module Config
* @ignore
* */
const text_replacements_1 = require("../text-replacements");
function validateRule(r) {
if (typeof r !== "object") {
throw new Error("must be an object");
}
if (!r.actionType) {
throw new Error("actionType must be defined");
}
if (r.actionType !== "redirect" && r.actionType !== "rewrite") {
throw new Error("actionType must be either `redirect` or `rewrite`");
}
if (r.actionType === "rewrite" && !r.backendKey) {
throw new Error("must inclue `backendKey` when actionType is set to `rewrite`");
}
return true;
}
exports.validateRule = validateRule;
function buildRules(backends, rules) {
const compiled = rules.map(compileRule);
return async function ruleFetch(req, init) {
if (typeof req === "string") {
req = new Request(req, init);
}
const match = compiled.find((r) => r(req));
if (!match) {
return new Response("no routing rule found", { status: 404 });
}
const rule = match.rule;
// do the redirect
if (rule.actionType === "redirect") {
let original = new URL(req.url);
let url = undefined;
if (match.pathPattern && rule.redirectURLPattern) {
url = match.pathPattern.replace(original.pathname, rule.redirectURLPattern);
}
else if (rule.redirectURLPattern) {
url = rule.redirectURLPattern;
}
if (!url || original.toString() === url) {
return new Response("Can't redirect to a bad URL", { status: 500 });
}
const status = rule.redirectStatus || 302;
const redirectTo = new URL(url, original);
return new Response("Redirect", { status: status, headers: { location: redirectTo.toString() } });
}
if (rule.actionType !== "rewrite") {
return new Response("Invalid rule action", { status: 500 });
}
const backend = rule.backendKey && backends ? backends.get(rule.backendKey) : undefined;
if (!backend) {
return new Response("No backend for rule", { status: 502 });
}
// rewrite request if necessary
if (match.pathPattern && rule.pathReplacementPattern) {
let url = new URL(req.url);
url = new URL(match.pathPattern.replace(url.pathname, rule.pathReplacementPattern), url);
req = new Request(url.toString(), req);
}
if (!rule.responseReplacements || rule.responseReplacements.length === 0) {
return await backend(req, init);
}
req.headers.delete("accept-encoding");
let resp = await backend(req, init);
return text_replacements_1.applyReplacements(resp, rule.responseReplacements);
};
}
exports.buildRules = buildRules;
function compileRule(rule) {
const pathPattern = ensurePathPatternMatcher(rule.pathPattern);
const httpHeaderValue = ensureRegExp(rule.httpHeaderValue);
const fn = function compiledRule(req) {
const url = new URL(req.url);
if (rule.matchScheme === "http" || rule.matchScheme === "https") {
const scheme = url.protocol.slice(0, -1);
if (scheme !== rule.matchScheme)
return false;
}
if (rule.hostname && rule.hostname !== "") {
if (url.hostname !== rule.hostname) {
return false;
}
}
if (rule.httpHeaderKey && rule.httpHeaderKey !== "" && httpHeaderValue) {
const header = req.headers.get(rule.httpHeaderKey);
if (!header || !header.match(httpHeaderValue)) {
return false;
}
}
if (pathPattern && !pathPattern.match(url.pathname)) {
return false;
}
return true;
};
return Object.assign(fn, { rule: rule, pathPattern: pathPattern });
}
function ensureRegExp(pattern) {
if (!pattern || pattern == "")
return null;
if (typeof pattern === "string")
return new RegExp(pattern);
if (pattern instanceof RegExp)
return pattern;
throw new Error("Pattern must be a string or RegExp: " + typeof pattern);
}
function ensurePathPatternMatcher(pattern) {
if (!pattern || pattern == "")
return null;
if (typeof pattern === "string")
return new PathPatternMatcher(pattern);
if (pattern instanceof RegExp)
return new PathPatternMatcher(pattern);
throw new Error("Pattern must be a string or RegExp: " + typeof pattern);
}
class PathPatternMatcher {
constructor(pattern) {
this.params = [];
if (pattern instanceof RegExp) {
this.regex = pattern;
}
else {
const matches = pattern.match(/([:\*]\w+)/g);
if (matches) {
for (const match of matches) {
this.params.push(match.substring(1));
if (match.startsWith(":")) {
pattern = pattern.replace(match, "([^/.]+)");
}
else if (match.startsWith("*")) {
pattern = pattern.replace(match, "(.+)");
}
}
}
this.regex = new RegExp(pattern);
}
}
match(path) {
return this.regex.test(path);
}
parse(path) {
const params = {};
const match = this.regex.exec(path);
if (!match) {
return params;
}
for (const [paramIndex, paramName] of this.params.entries()) {
params[paramName] = match[paramIndex + 1];
}
return params;
}
replace(path, replacement) {
const params = this.parse(path);
for (const [name, value] of Object.entries(params)) {
replacement = replacement.replace(`$${name}`, value);
}
return replacement;
}
}
exports.PathPatternMatcher = PathPatternMatcher;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29uZmlnL3J1bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOzs7S0FHSztBQUNMLDREQUF5RDtBQW9CekQsU0FBZ0IsWUFBWSxDQUFDLENBQU07SUFDakMsSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLEVBQUU7UUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0tBQ3JDO0lBQ0QsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUU7UUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFBO0tBQzlDO0lBQ0QsSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLLFVBQVUsSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRTtRQUM3RCxNQUFNLElBQUksS0FBSyxDQUFDLG1EQUFtRCxDQUFDLENBQUE7S0FDckU7SUFDRCxJQUFJLENBQUMsQ0FBQyxVQUFVLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRTtRQUMvQyxNQUFNLElBQUksS0FBSyxDQUFDLDhEQUE4RCxDQUFDLENBQUE7S0FDaEY7SUFDRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFkRCxvQ0FjQztBQUVELFNBQWdCLFVBQVUsQ0FBQyxRQUF3QixFQUFFLEtBQWlCO0lBQ3BFLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDdkMsT0FBTyxLQUFLLFVBQVUsU0FBUyxDQUFDLEdBQWdCLEVBQUUsSUFBa0I7UUFDbEUsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUU7WUFDM0IsR0FBRyxHQUFHLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQTtTQUM3QjtRQUNELE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFD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LE9BQU8sTUFBTSxDQUFBO1NBQ2Q7UUFDRCxLQUFLLE1BQU0sQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUMzRCxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSyxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQztTQUMzQztRQUNELE9BQU8sTUFBTSxDQUFBO0lBQ2YsQ0FBQztJQUVELE9BQU8sQ0FBQyxJQUFZLEVBQUUsV0FBbUI7UUFDdkMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMvQixLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNsRCxXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFBO1NBQ3JEO1FBQ0QsT0FBTyxXQUFXLENBQUE7SUFDcEIsQ0FBQztDQUNGO0FBL0NELGdEQStDQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQG1vZHVsZSBDb25maWdcbiAqIEBpZ25vcmVcbiAqICovXG5pbXBvcnQgeyBhcHBseVJlcGxhY2VtZW50cyB9IGZyb20gXCIuLi90ZXh0LXJlcGxhY2VtZW50c1wiO1xuaW1wb3J0IHsgQmFja2VuZFByb3hpZXMgfSBmcm9tIFwiLi9pbmRleFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJ1bGVJbmZvIHtcbiAgYWN0aW9uVHlwZTogXCJyZWRpcmVjdFwiIHwgXCJyZXdyaXRlXCIsXG4gIGJhY2tlbmRLZXk/OiBzdHJpbmcsXG4gIG1hdGNoU2NoZW1lPzogc3RyaW5nLFxuICBob3N0bmFtZT86IHN0cmluZyxcbiAgcGF0aE1hdGNoTW9kZT86IFwicHJlZml4XCIgfCBcImZ1bGxcIixcbiAgaHR0cEhlYWRlcktleT86IHN0cmluZyxcbiAgaHR0cEhlYWRlclZhbHVlPzogUmVnRXhwIHwgc3RyaW5nLFxuICBwYXRoUGF0dGVybj86IFJlZ0V4cCB8IHN0cmluZyxcbiAgcGF0aFJlcGxhY2VtZW50UGF0dGVybj86IHN0cmluZyxcbiAgcmVkaXJlY3RVUkxQYXR0ZXJuPzogc3RyaW5nLFxuICByZWRpcmVjdFN0YXR1cz86IG51bWJlcixcbiAgcmVzcG9uc2VSZXBsYWNlbWVudHM/OiBbc3RyaW5nLCBzdHJpbmddW10sXG59XG5cbmRlY2xhcmUgdmFyIGFwcDogYW55XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVJ1bGUocjogYW55KTogciBpcyBSdWxlSW5mbyB7XG4gIGlmICh0eXBlb2YgciAhPT0gXCJvYmplY3RcIikge1xuICAgIHRocm93IG5ldyBFcnJvcihcIm11c3QgYmUgYW4gb2JqZWN0XCIpXG4gIH1cbiAgaWYgKCFyLmFjdGlvblR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJhY3Rpb25UeXBlIG11c3QgYmUgZGVmaW5lZFwiKVxuICB9XG4gIGlmIChyLmFjdGlvblR5cGUgIT09IFwicmVkaXJlY3RcIiAmJiByLmFjdGlvblR5cGUgIT09IFwicmV3cml0ZVwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYWN0aW9uVHlwZSBtdXN0IGJlIGVpdGhlciBgcmVkaXJlY3RgIG9yIGByZXdyaXRlYFwiKVxuICB9XG4gIGlmIChyLmFjdGlvblR5cGUgPT09IFwicmV3cml0ZVwiICYmICFyLmJhY2tlbmRLZXkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJtdXN0IGluY2x1ZSBgYmFja2VuZEtleWAgd2hlbiBhY3Rpb25UeXBlIGlzIHNldCB0byBgcmV3cml0ZWBcIilcbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRSdWxlcyhiYWNrZW5kczogQmFja2VuZFByb3hpZXMsIHJ1bGVzOiBSdWxlSW5mb1tdKSB7XG4gIGNvbnN0IGNvbXBpbGVkID0gcnVsZXMubWFwKGNvbXBpbGVSdWxlKVxuICByZXR1cm4gYXN5bmMgZnVuY3Rpb24gcnVsZUZldGNoKHJlcTogUmVxdWVzdEluZm8sIGluaXQ/OiBSZXF1ZXN0SW5pdCkge1xuICAgIGlmICh0eXBlb2YgcmVxID09PSBcInN0cmluZ1wiKSB7XG4gICAgICByZXEgPSBuZXcgUmVxdWVzdChyZXEsIGluaXQpXG4gICAgfVxuICAgIGNvbnN0IG1hdGNoID0gY29tcGlsZWQuZmluZCgocikgPT4gcig8UmVxdWVzdD5yZXEpKVxuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXCJubyByb3V0aW5nIHJ1bGUgZm91bmRcIiwgeyBzdGF0dXM6IDQwNCB9KVxuICAgIH1cbiAgICBjb25zdCBydWxlID0gbWF0Y2gucnVsZVxuICAgIC8vIGRvIHRoZSByZWRpcmVjdFxuICAgIGlmIChydWxlLmFjdGlvblR5cGUgPT09IFwicmVkaXJlY3RcIikge1xuICAgICAgbGV0IG9yaWdpbmFsID0gbmV3IFVSTChyZXEudXJsKVxuICAgICAgbGV0IHVybDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkXG4gICAgICBpZiAobWF0Y2gucGF0aFBhdHRlcm4gJiYgcnVsZS5yZWRpcmVjdFVSTFBhdHRlcm4pIHtcbiAgICAgICAgdXJsID0gbWF0Y2gucGF0aFBhdHRlcm4ucmVwbGFjZShvcmlnaW5hbC5wYXRobmFtZSwgcnVsZS5yZWRpcmVjdFVSTFBhdHRlcm4pXG4gICAgICB9IGVsc2UgaWYgKHJ1bGUucmVkaXJlY3RVUkxQYXR0ZXJuKSB7XG4gICAgICAgIHVybCA9IHJ1bGUucmVkaXJlY3RVUkxQYXR0ZXJuXG4gICAgICB9XG4gICAgICBpZiAoIXVybCB8fCBvcmlnaW5hbC50b1N0cmluZygpID09PSB1cmwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShcIkNhbid0IHJlZGlyZWN0IHRvIGEgYmFkIFVSTFwiLCB7IHN0YXR1czogNTAwIH0pXG4gICAgICB9XG4gICAgICBjb25zdCBzdGF0dXMgPSBydWxlLnJlZGlyZWN0U3RhdHVzIHx8IDMwMlxuICAgICAgY29uc3QgcmVkaXJlY3RUbyA9IG5ldyBVUkwodXJsLCBvcmlnaW5hbClcbiAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXCJSZWRpcmVjdFwiLCB7IHN0YXR1czogc3RhdHVzLCBoZWFkZXJzOiB7IGxvY2F0aW9uOiByZWRpcmVjdFRvLnRvU3RyaW5nKCkgfSB9KVxuICAgIH1cbiAgICBpZiAocnVsZS5hY3Rpb25UeXBlICE9PSBcInJld3JpdGVcIikge1xuICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShcIkludmFsaWQgcnVsZSBhY3Rpb25cIiwgeyBzdGF0dXM6IDUwMCB9KVxuICAgIH1cbiAgICBjb25zdCBiYWNrZW5kID0gcnVsZS5iYWNrZW5kS2V5ICYmIGJhY2tlbmRzID8gYmFja2VuZHMuZ2V0KHJ1bGUuYmFja2VuZEtleSkgOiB1bmRlZmluZWRcbiAgICBpZiAoIWJhY2tlbmQpIHtcbiAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXCJObyBiYWNrZW5kIGZvciBydWxlXCIsIHsgc3RhdHVzOiA1MDIgfSlcbiAgICB9XG4gICAgLy8gcmV3cml0ZSByZXF1ZXN0IGlmIG5lY2Vzc2FyeVxuICAgIGlmIChtYXRjaC5wYXRoUGF0dGVybiAmJiBydWxlLnBhdGhSZXBsYWNlbWVudFBhdHRlcm4pIHtcbiAgICAgIGxldCB1cmwgPSBuZXcgVVJMKHJlcS51cmwpXG4gICAgICB1cmwgPSBuZXcgVVJMKG1hdGNoLnBhdGhQYXR0ZXJuLnJlcGxhY2UodXJsLnBhdGhuYW1lLCBydWxlLnBhdGhSZXBsYWNlbWVudFBhdHRlcm4pLCB1cmwpXG4gICAgICByZXEgPSBuZXcgUmVxdWVzdCh1cmwudG9TdHJpbmcoKSwgPFJlcXVlc3RJbml0PnJlcSlcbiAgICB9XG4gICAgaWYgKCFydWxlLnJlc3BvbnNlUmVwbGFjZW1lbnRzIHx8IHJ1bGUucmVzcG9uc2VSZXBsYWNlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gYXdhaXQgYmFja2VuZChyZXEsIGluaXQpXG4gICAgfVxuXG4gICAgcmVxLmhlYWRlcnMuZGVsZXRlKFwiYWNjZXB0LWVuY29kaW5nXCIpXG4gICAgbGV0IHJlc3AgPSBhd2FpdCBiYWNrZW5kKHJlcSwgaW5pdClcbiAgICByZXR1cm4gYXBwbHlSZXBsYWNlbWVudHMocmVzcCwgcnVsZS5yZXNwb25zZVJlcGxhY2VtZW50cylcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21waWxlUnVsZShydWxlOiBSdWxlSW5mbykge1xuICBjb25zdCBwYXRoUGF0dGVybiA9IGVuc3VyZVBhdGhQYXR0ZXJuTWF0Y2hlcihydWxlLnBhdGhQYXR0ZXJuKVxuICBjb25zdCBodHRwSGVhZGVyVmFsdWUgPSBlbnN1cmVSZWdFeHAocnVsZS5odHRwSGVhZGVyVmFsdWUpXG4gIGNvbnN0IGZuID0gZnVuY3Rpb24gY29tcGlsZWRSdWxlKHJlcTogUmVxdWVzdCkge1xuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxLnVybClcbiAgICBpZiAocnVsZS5tYXRjaFNjaGVtZSA9PT0gXCJodHRwXCIgfHwgcnVsZS5tYXRjaFNjaGVtZSA9PT0gXCJodHRwc1wiKSB7XG4gICAgICBjb25zdCBzY2hlbWUgPSB1cmwucHJvdG9jb2wuc2xpY2UoMCwgLTEpXG4gICAgICBpZiAoc2NoZW1lICE9PSBydWxlLm1hdGNoU2NoZW1lKSByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgaWYgKHJ1bGUuaG9zdG5hbWUgJiYgcnVsZS5ob3N0bmFtZSAhPT0gXCJcIikge1xuICAgICAgaWYgKHVybC5ob3N0bmFtZSAhPT0gcnVsZS5ob3N0bmFtZSkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJ1bGUuaHR0cEhlYWRlcktleSAmJiBydWxlLmh0dHBIZWFkZXJLZXkgIT09IFwiXCIgJiYgaHR0cEhlYWRlclZhbHVlKSB7XG4gICAgICBjb25zdCBoZWFkZXIgPSByZXEuaGVhZGVycy5nZXQocnVsZS5odHRwSGVhZGVyS2V5KVxuICAgICAgaWYgKCFoZWFkZXIgfHwgIWhlYWRlci5tYXRjaChodHRwSGVhZGVyVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAocGF0aFBhdHRlcm4gJiYgIXBhdGhQYXR0ZXJuLm1hdGNoKHVybC5wYXRobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG4gIHJldHVybiBPYmplY3QuYXNzaWduKGZuLCB7IHJ1bGU6IHJ1bGUsIHBhdGhQYXR0ZXJuOiBwYXRoUGF0dGVybiB9KVxufVxuXG5mdW5jdGlvbiBlbnN1cmVSZWdFeHAocGF0dGVybj86IHN0cmluZyB8IFJlZ0V4cCk6IFJlZ0V4cCB8IG51bGwge1xuICBpZiAoIXBhdHRlcm4gfHwgcGF0dGVybiA9PSBcIlwiKSByZXR1cm4gbnVsbFxuICBpZiAodHlwZW9mIHBhdHRlcm4gPT09IFwic3RyaW5nXCIpIHJldHVybiBuZXcgUmVnRXhwKHBhdHRlcm4pXG4gIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgUmVnRXhwKSByZXR1cm4gcGF0dGVyblxuXG4gIHRocm93IG5ldyBFcnJvcihcIlBhdHRlcm4gbXVzdCBiZSBhIHN0cmluZyBvciBSZWdFeHA6IFwiICsgdHlwZW9mIHBhdHRlcm4pXG59XG5cbmZ1bmN0aW9uIGVuc3VyZVBhdGhQYXR0ZXJuTWF0Y2hlcihwYXR0ZXJuPzogc3RyaW5nIHwgUmVnRXhwKTogUGF0aFBhdHRlcm5NYXRjaGVyIHwgbnVsbCB7XG4gIGlmICghcGF0dGVybiB8fCBwYXR0ZXJuID09IFwiXCIpIHJldHVybiBudWxsXG4gIGlmICh0eXBlb2YgcGF0dGVybiA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIG5ldyBQYXRoUGF0dGVybk1hdGNoZXIocGF0dGVybilcbiAgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBSZWdFeHApIHJldHVybiBuZXcgUGF0aFBhdHRlcm5NYXRjaGVyKHBhdHRlcm4pXG5cbiAgdGhyb3cgbmV3IEVycm9yKFwiUGF0dGVybiBtdXN0IGJlIGEgc3RyaW5nIG9yIFJlZ0V4cDogXCIgKyB0eXBlb2YgcGF0dGVybilcbn1cblxuXG5leHBvcnQgY2xhc3MgUGF0aFBhdHRlcm5NYXRjaGVyIHtcbiAgcHJpdmF0ZSByZWdleDogUmVnRXhwXG4gIHByaXZhdGUgcGFyYW1zOiBzdHJpbmdbXSA9IFtdXG5cbiAgY29uc3RydWN0b3IocGF0dGVybjogc3RyaW5nIHwgUmVnRXhwKSB7XG4gICAgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgIHRoaXMucmVnZXggPSBwYXR0ZXJuXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG1hdGNoZXMgPSBwYXR0ZXJuLm1hdGNoKC8oWzpcXCpdXFx3KykvZylcbiAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2YgbWF0Y2hlcykge1xuICAgICAgICAgIHRoaXMucGFyYW1zLnB1c2gobWF0Y2guc3Vic3RyaW5nKDEpKVxuICAgICAgICAgIGlmIChtYXRjaC5zdGFydHNXaXRoKFwiOlwiKSkge1xuICAgICAgICAgICAgcGF0dGVybiA9IHBhdHRlcm4ucmVwbGFjZShtYXRjaCwgXCIoW14vLl0rKVwiKVxuICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2guc3RhcnRzV2l0aChcIipcIikpIHtcbiAgICAgICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnJlcGxhY2UobWF0Y2gsIFwiKC4rKVwiKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5yZWdleCA9IG5ldyBSZWdFeHAocGF0dGVybilcbiAgICB9XG4gIH1cblxuICBtYXRjaChwYXRoOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZWdleC50ZXN0KHBhdGgpXG4gIH1cblxuICBwYXJzZShwYXRoOiBzdHJpbmcpIHtcbiAgICBjb25zdCBwYXJhbXM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9ID0ge31cblxuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5yZWdleC5leGVjKHBhdGgpXG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgcmV0dXJuIHBhcmFtc1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtwYXJhbUluZGV4LCBwYXJhbU5hbWVdIG9mIHRoaXMucGFyYW1zLmVudHJpZXMoKSkge1xuICAgICAgcGFyYW1zW3BhcmFtTmFtZV0gPSBtYXRjaFtwYXJhbUluZGV4ICsgMV07XG4gICAgfVxuICAgIHJldHVybiBwYXJhbXNcbiAgfVxuXG4gIHJlcGxhY2UocGF0aDogc3RyaW5nLCByZXBsYWNlbWVudDogc3RyaW5nKSB7XG4gICAgY29uc3QgcGFyYW1zID0gdGhpcy5wYXJzZShwYXRoKVxuICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhwYXJhbXMpKSB7XG4gICAgICByZXBsYWNlbWVudCA9IHJlcGxhY2VtZW50LnJlcGxhY2UoYCQke25hbWV9YCwgdmFsdWUpXG4gICAgfVxuICAgIHJldHVybiByZXBsYWNlbWVudFxuICB9XG59XG4iXX0=