vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
164 lines (161 loc) • 24.9 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { resolve } from 'node:path';
import 'vite';
import { MIME_TYPES } from '../config/mimeTypes.js';
import { requestToRoute } from './requestToRoute.js';
import { routeToURL } from '../utils/routeToURL.js';
function requestInfo(req, handlerOptions, hostDir) {
const route = requestToRoute(req, {
moduleBasePath: handlerOptions.moduleBasePath,
moduleBaseURL: handlerOptions.moduleBaseURL,
build: handlerOptions.build
});
if (!route) {
return {
route: "/",
url: routeToURL("/", handlerOptions.moduleBaseURL, handlerOptions.build.rscOutputPath),
ext: ""
};
}
const [, value] = handlerOptions.normalizer(route);
if (handlerOptions.verbose) {
if (value && value !== "") {
handlerOptions.logger.info(`[requestInfo] Value: "${value}"`);
}
if (hostDir && hostDir !== "") {
handlerOptions.logger.info(`[requestInfo] Host Dir: "${hostDir}"`);
}
if (req.url && req.url !== "") {
handlerOptions.logger.info(`[requestInfo] Request URL: "${req.url}"`);
}
}
const dotIndex = value.lastIndexOf(".");
const ext = dotIndex === -1 ? "" : value.slice(dotIndex);
const isVendor = handlerOptions.autoDiscover.vendorPattern.test(value);
const isVirtual = handlerOptions.autoDiscover.virtualPattern.test(value);
const isJS = handlerOptions.autoDiscover.modulePattern.test(value);
const isHtml = handlerOptions.autoDiscover.htmlPattern.test(value);
const isCss = handlerOptions.autoDiscover.cssPattern.test(value);
const isJson = handlerOptions.autoDiscover.jsonPattern.test(value);
const isRsc = handlerOptions.autoDiscover.rscPattern.test(value);
const hasJsHeader = req.headers["sec-fetch-dest"] === "script" || req.headers["accept"]?.includes("*/*") || req.headers["accept"]?.includes("text/javascript");
const hasJsonHeader = req.headers["accept"]?.includes("application/json");
const hasHtmlHeader = req.headers.accept?.includes("text/html");
const hasRscHeader = req.headers.accept?.includes("text/x-component");
const hasRscQueryParam = /[?&]_rsc\b/.test(req.url || "");
const hasCssHeader = req.headers.accept?.includes("text/css");
const isFolder = !ext;
const isFormContentType = req.headers["content-type"]?.includes(
"application/x-www-form-urlencoded"
) || !!req.headers["content-type"]?.includes("multipart/form-data");
const hasRscActionHeader = !!req.headers["x-rsc-action"];
const hasServerActionHeaders = req.method === "POST" && (hasRscActionHeader || (req.headers["sec-fetch-dest"] === "empty" || req.headers["sec-fetch-dest"] === "") && req.headers["sec-fetch-mode"] === "cors");
const isServerActionRequest = hasServerActionHeaders;
const isFormActionRequest = !isServerActionRequest && (req.method === "POST" || isFormContentType && req.headers["sec-fetch-dest"] === "document" && req.headers["sec-fetch-mode"] === "navigate");
const isJsRequest = !isFormActionRequest && !isJson && !isHtml && !isCss && !isRsc && (isJS || hasJsHeader);
const isJsonRequest = isJson || hasJsonHeader && !isJsRequest;
const isHtmlRequest = !hasRscQueryParam && (isHtml || hasHtmlHeader || isFolder && !hasRscHeader && !isRsc && !isJsRequest && !isFormActionRequest);
const isRscRequest = hasRscQueryParam || !isJsRequest && !isHtmlRequest && (isRsc || hasRscHeader);
const isCssRequest = !isHtmlRequest && !isRscRequest && !isJsRequest && !isJsonRequest && (isCss || hasCssHeader);
const routeForFilePath = value;
let filePath = resolve(hostDir, routeForFilePath);
let contentType;
if (isServerActionRequest) {
filePath = resolve(hostDir, routeForFilePath);
contentType = "application/json; charset=utf-8";
} else if (isHtmlRequest) {
if (!isHtml) {
filePath = resolve(
hostDir,
routeForFilePath,
handlerOptions.build.htmlOutputPath
);
}
contentType = "text/html; charset=utf-8";
} else if (isRscRequest) {
if (!isRsc) {
filePath = resolve(
hostDir,
routeForFilePath,
handlerOptions.build.rscOutputPath
);
}
contentType = "text/x-component; charset=utf-8";
} else if (isCssRequest) {
if (!isCss) {
filePath = resolve(hostDir, routeForFilePath + ".css");
}
contentType = "text/css; charset=utf-8";
} else if (isJsRequest) {
if (!isJS) {
filePath = resolve(hostDir, routeForFilePath + ".js");
}
contentType = "application/javascript; charset=utf-8";
} else if (isJsonRequest) {
if (!isJson) {
filePath = resolve(hostDir, routeForFilePath + ".json");
}
contentType = "application/json; charset=utf-8";
} else {
const mimeType = MIME_TYPES[ext];
if (mimeType) {
contentType = mimeType + "; charset=utf-8";
} else {
contentType = "application/octet-stream";
}
}
if (handlerOptions.verbose) {
if (isFormActionRequest) {
handlerOptions.logger.info(`[react-dev-server] (form-action) ${route}`);
} else if (isServerActionRequest) {
handlerOptions.logger.info(`[react-dev-server] (server-action) ${route}`);
} else if (isHtmlRequest) {
handlerOptions.logger.info(`[react-dev-server] (html) ${route}`);
} else if (isRscRequest) {
handlerOptions.logger.info(`[react-dev-server] (rsc) ${route}`);
} else if (isCssRequest) {
handlerOptions.logger.info(`[react-dev-server] (css) ${route}`);
} else if (isJsRequest) {
handlerOptions.logger.info(`[react-dev-server] (js) ${route}`);
} else if (isJsonRequest) {
handlerOptions.logger.info(`[react-dev-server] (json) ${route}`);
} else {
handlerOptions.logger.info(`[react-dev-server] (other) ${route}`);
}
}
return {
route,
url: routeToURL(route, handlerOptions.moduleBaseURL, handlerOptions.build.rscOutputPath),
ext,
isHtmlRequest,
isRscRequest,
isCssRequest,
isCss,
isHtml,
isRsc,
isFolder,
contentType,
filePath,
isJS,
isVendor,
isVirtual,
hasJsHeader,
isJsRequest,
isJson,
isJsonRequest,
hasCssHeader,
hasJsonHeader,
hasHtmlHeader,
hasRscHeader,
hasServerActionHeaders,
isServerActionRequest,
isFormContentType,
isFormActionRequest
};
}
export { requestInfo };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdEluZm8uanMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3BsdWdpbi9oZWxwZXJzL3JlcXVlc3RJbmZvLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgdHlwZSB7IENyZWF0ZUhhbmRsZXJPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzLmpzXCI7XG5pbXBvcnQgeyB0eXBlIENvbm5lY3QgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHsgTUlNRV9UWVBFUyB9IGZyb20gXCIuLi9jb25maWcvbWltZVR5cGVzLmpzXCI7XG5pbXBvcnQgeyByZXF1ZXN0VG9Sb3V0ZSB9IGZyb20gXCIuL3JlcXVlc3RUb1JvdXRlLmpzXCI7XG5pbXBvcnQgeyByb3V0ZVRvVVJMIH0gZnJvbSBcIi4uL3V0aWxzL3JvdXRlVG9VUkwuanNcIjtcblxuLyoqXG4gKiAjIFJlcXVlc3QgaW5mb1xuICpcbiAqIERvZXMgdGhlIGluaXRpYWwgd29yayB0byBjaGVjayBpZiB0aGUgcmVxdWVzdCBpcyBmb3IgaHRtbCwgcnNjLCBqc29uLCBqcywgY3NzLCBzZXJ2ZXItYWN0aW9uLCBvciBzb21ldGhpbmcgZWxzZSBub3QgaGFuZGxlZCBieSB0aGlzIHBsdWdpbi5cbiAqXG4gKiBAcGFyYW0gcmVxXG4gKiBAcGFyYW0gaGFuZGxlck9wdGlvbnNcbiAqIEBwYXJhbSBob3N0RGlyXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWVzdEluZm8oXG4gIHJlcTogQ29ubmVjdC5JbmNvbWluZ01lc3NhZ2UsXG4gIGhhbmRsZXJPcHRpb25zOiBQaWNrPFxuICAgIENyZWF0ZUhhbmRsZXJPcHRpb25zLFxuICAgIHwgXCJub3JtYWxpemVyXCJcbiAgICB8IFwiYnVpbGRcIlxuICAgIHwgXCJhdXRvRGlzY292ZXJcIlxuICAgIHwgXCJ2ZXJib3NlXCJcbiAgICB8IFwibW9kdWxlQmFzZVBhdGhcIlxuICAgIHwgXCJtb2R1bGVCYXNlVVJMXCJcbiAgICB8IFwidmVyYm9zZVwiXG4gICAgfCBcImxvZ2dlclwiXG4gID4sXG4gIGhvc3REaXI6IHN0cmluZyxcbikge1xuICBjb25zdCByb3V0ZSA9IHJlcXVlc3RUb1JvdXRlKHJlcSwge1xuICAgIG1vZHVsZUJhc2VQYXRoOiBoYW5kbGVyT3B0aW9ucy5tb2R1bGVCYXNlUGF0aCxcbiAgICBtb2R1bGVCYXNlVVJMOiBoYW5kbGVyT3B0aW9ucy5tb2R1bGVCYXNlVVJMLFxuICAgIGJ1aWxkOiBoYW5kbGVyT3B0aW9ucy5idWlsZCxcbiAgfSk7XG5cbiAgaWYgKCFyb3V0ZSkge1xuICAgIHJldHVybiB7XG4gICAgICByb3V0ZTogXCIvXCIsXG4gICAgICB1cmw6IHJvdXRlVG9VUkwoXCIvXCIsIGhhbmRsZXJPcHRpb25zLm1vZHVsZUJhc2VVUkwsIGhhbmRsZXJPcHRpb25zLmJ1aWxkLnJzY091dHB1dFBhdGgpLFxuICAgICAgZXh0OiBcIlwiLFxuICAgIH07XG4gIH1cblxuICAvLyBVc2UgdGhlIGNsZWFuZWQgcm91dGUgZm9yIG5vcm1hbGl6YXRpb24sIG5vdCB0aGUgcmF3IHJlcS51cmxcbiAgLy8gVGhpcyBlbnN1cmVzIGJhc2UgVVJMIGlzIHByb3Blcmx5IHN0cmlwcGVkIGJlZm9yZSBub3JtYWxpemF0aW9uXG4gIGNvbnN0IFssIHZhbHVlXSA9IGhhbmRsZXJPcHRpb25zLm5vcm1hbGl6ZXIocm91dGUpO1xuICBpZiAoaGFuZGxlck9wdGlvbnMudmVyYm9zZSkge1xuICAgIGlmICh2YWx1ZSAmJiB2YWx1ZSAhPT0gXCJcIikge1xuICAgICAgaGFuZGxlck9wdGlvbnMubG9nZ2VyLmluZm8oYFtyZXF1ZXN0SW5mb10gVmFsdWU6IFxcXCIke3ZhbHVlfVxcXCJgKTtcbiAgICB9XG4gICAgaWYgKGhvc3REaXIgJiYgaG9zdERpciAhPT0gXCJcIikge1xuICAgICAgaGFuZGxlck9wdGlvbnMubG9nZ2VyLmluZm8oYFtyZXF1ZXN0SW5mb10gSG9zdCBEaXI6IFxcXCIke2hvc3REaXJ9XFxcImApO1xuICAgIH1cbiAgICBpZiAocmVxLnVybCAmJiByZXEudXJsICE9PSBcIlwiKSB7XG4gICAgICBoYW5kbGVyT3B0aW9ucy5sb2dnZXIuaW5mbyhgW3JlcXVlc3RJbmZvXSBSZXF1ZXN0IFVSTDogXFxcIiR7cmVxLnVybH1cXFwiYCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZG90SW5kZXggPSB2YWx1ZS5sYXN0SW5kZXhPZihcIi5cIik7XG4gIGNvbnN0IGV4dCA9IGRvdEluZGV4ID09PSAtMSA/IFwiXCIgOiB2YWx1ZS5zbGljZShkb3RJbmRleCk7XG4gIC8vIGhhbmRsZSBpbmRleC5odG1sXG4gIGNvbnN0IGlzVmVuZG9yID0gaGFuZGxlck9wdGlvbnMuYXV0b0Rpc2NvdmVyLnZlbmRvclBhdHRlcm4udGVzdCh2YWx1ZSk7XG4gIGNvbnN0IGlzVmlydHVhbCA9IGhhbmRsZXJPcHRpb25zLmF1dG9EaXNjb3Zlci52aXJ0dWFsUGF0dGVybi50ZXN0KHZhbHVlKTtcbiAgY29uc3QgaXNKUyA9IGhhbmRsZXJPcHRpb25zLmF1dG9EaXNjb3Zlci5tb2R1bGVQYXR0ZXJuLnRlc3QodmFsdWUpO1xuICBjb25zdCBpc0h0bWwgPSBoYW5kbGVyT3B0aW9ucy5hdXRvRGlzY292ZXIuaHRtbFBhdHRlcm4udGVzdCh2YWx1ZSk7XG4gIGNvbnN0IGlzQ3NzID0gaGFuZGxlck9wdGlvbnMuYXV0b0Rpc2NvdmVyLmNzc1BhdHRlcm4udGVzdCh2YWx1ZSk7XG4gIGNvbnN0IGlzSnNvbiA9IGhhbmRsZXJPcHRpb25zLmF1dG9EaXNjb3Zlci5qc29uUGF0dGVybi50ZXN0KHZhbHVlKTtcbiAgY29uc3QgaXNSc2MgPSBoYW5kbGVyT3B0aW9ucy5hdXRvRGlzY292ZXIucnNjUGF0dGVybi50ZXN0KHZhbHVlKTtcbiAgY29uc3QgaGFzSnNIZWFkZXIgPVxuICAgIHJlcS5oZWFkZXJzW1wic2VjLWZldGNoLWRlc3RcIl0gPT09IFwic2NyaXB0XCIgfHxcbiAgICByZXEuaGVhZGVyc1tcImFjY2VwdFwiXT8uaW5jbHVkZXMoXCIqLypcIikgfHxcbiAgICByZXEuaGVhZGVyc1tcImFjY2VwdFwiXT8uaW5jbHVkZXMoXCJ0ZXh0L2phdmFzY3JpcHRcIik7XG4gIGNvbnN0IGhhc0pzb25IZWFkZXIgPSByZXEuaGVhZGVyc1tcImFjY2VwdFwiXT8uaW5jbHVkZXMoXCJhcHBsaWNhdGlvbi9qc29uXCIpO1xuICBjb25zdCBoYXNIdG1sSGVhZGVyID0gcmVxLmhlYWRlcnMuYWNjZXB0Py5pbmNsdWRlcyhcInRleHQvaHRtbFwiKTtcbiAgY29uc3QgaGFzUnNjSGVhZGVyID0gcmVxLmhlYWRlcnMuYWNjZXB0Py5pbmNsdWRlcyhcInRleHQveC1jb21wb25lbnRcIik7XG4gIC8vIFN1cHBvcnQgP19yc2MgcXVlcnkgcGFyYW0gKGUuZy4gLz9fcnNjIGZvciBicm93c2VyIGRlYnVnZ2luZykgYXMgYWx0ZXJuYXRpdmUgdG8gQWNjZXB0IGhlYWRlciAodXNlZnVsIGZvciBicm93c2VyIGRlYnVnZ2luZylcbiAgY29uc3QgaGFzUnNjUXVlcnlQYXJhbSA9IC9bPyZdX3JzY1xcYi8udGVzdChyZXEudXJsIHx8IFwiXCIpO1xuICBjb25zdCBoYXNDc3NIZWFkZXIgPSByZXEuaGVhZGVycy5hY2NlcHQ/LmluY2x1ZGVzKFwidGV4dC9jc3NcIik7XG4gIGNvbnN0IGlzRm9sZGVyID0gIWV4dDtcbiAgY29uc3QgaXNGb3JtQ29udGVudFR5cGUgPVxuICAgIHJlcS5oZWFkZXJzW1wiY29udGVudC10eXBlXCJdPy5pbmNsdWRlcyhcbiAgICAgIFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXCJcbiAgICApIHx8ICEhcmVxLmhlYWRlcnNbXCJjb250ZW50LXR5cGVcIl0/LmluY2x1ZGVzKFwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiKTtcblxuICAvLyBTZXJ2ZXIgYWN0aW9uIGRldGVjdGlvblxuICBjb25zdCBoYXNSc2NBY3Rpb25IZWFkZXIgPSAhIXJlcS5oZWFkZXJzW1wieC1yc2MtYWN0aW9uXCJdO1xuICBjb25zdCBoYXNTZXJ2ZXJBY3Rpb25IZWFkZXJzID1cbiAgICByZXEubWV0aG9kID09PSBcIlBPU1RcIiAmJlxuICAgIChoYXNSc2NBY3Rpb25IZWFkZXIgfHwgKFxuICAgICAgKHJlcS5oZWFkZXJzW1wic2VjLWZldGNoLWRlc3RcIl0gPT09IFwiZW1wdHlcIiB8fFxuICAgICAgICByZXEuaGVhZGVyc1tcInNlYy1mZXRjaC1kZXN0XCJdID09PSBcIlwiKSAmJlxuICAgICAgcmVxLmhlYWRlcnNbXCJzZWMtZmV0Y2gtbW9kZVwiXSA9PT0gXCJjb3JzXCJcbiAgICApKTtcbiAgY29uc3QgaXNTZXJ2ZXJBY3Rpb25SZXF1ZXN0ID0gaGFzU2VydmVyQWN0aW9uSGVhZGVycztcblxuICBjb25zdCBpc0Zvcm1BY3Rpb25SZXF1ZXN0ID1cbiAgICAhaXNTZXJ2ZXJBY3Rpb25SZXF1ZXN0ICYmXG4gICAgKHJlcS5tZXRob2QgPT09IFwiUE9TVFwiIHx8XG4gICAgICAoaXNGb3JtQ29udGVudFR5cGUgJiZcbiAgICAgICAgcmVxLmhlYWRlcnNbXCJzZWMtZmV0Y2gtZGVzdFwiXSA9PT0gXCJkb2N1bWVudFwiICYmXG4gICAgICAgIHJlcS5oZWFkZXJzW1wic2VjLWZldGNoLW1vZGVcIl0gPT09IFwibmF2aWdhdGVcIikpO1xuXG4gIGNvbnN0IGlzSnNSZXF1ZXN0ID1cbiAgICAhaXNGb3JtQWN0aW9uUmVxdWVzdCAmJlxuICAgICFpc0pzb24gJiZcbiAgICAhaXNIdG1sICYmXG4gICAgIWlzQ3NzICYmXG4gICAgIWlzUnNjICYmXG4gICAgKGlzSlMgfHwgaGFzSnNIZWFkZXIpO1xuICBjb25zdCBpc0pzb25SZXF1ZXN0ID0gaXNKc29uIHx8IChoYXNKc29uSGVhZGVyICYmICFpc0pzUmVxdWVzdCk7XG4gIC8vIEZvcm0gYWN0aW9uIGRldGVjdGlvblxuXG4gIGNvbnN0IGlzSHRtbFJlcXVlc3QgPVxuICAgICFoYXNSc2NRdWVyeVBhcmFtICYmIChpc0h0bWwgfHxcbiAgICBoYXNIdG1sSGVhZGVyIHx8XG4gICAgKGlzRm9sZGVyICYmXG4gICAgICAhaGFzUnNjSGVhZGVyICYmXG4gICAgICAhaXNSc2MgJiZcbiAgICAgICFpc0pzUmVxdWVzdCAmJlxuICAgICAgIWlzRm9ybUFjdGlvblJlcXVlc3QpKTtcbiAgY29uc3QgaXNSc2NSZXF1ZXN0ID1cbiAgICBoYXNSc2NRdWVyeVBhcmFtIHx8ICghaXNKc1JlcXVlc3QgJiYgIWlzSHRtbFJlcXVlc3QgJiYgKGlzUnNjIHx8IGhhc1JzY0hlYWRlcikpO1xuICBjb25zdCBpc0Nzc1JlcXVlc3QgPVxuICAgICFpc0h0bWxSZXF1ZXN0ICYmXG4gICAgIWlzUnNjUmVxdWVzdCAmJlxuICAgICFpc0pzUmVxdWVzdCAmJlxuICAgICFpc0pzb25SZXF1ZXN0ICYmXG4gICAgKGlzQ3NzIHx8IGhhc0Nzc0hlYWRlcik7XG5cbiAgLy8gVXNlIHRoZSBub3JtYWxpemVkIHZhbHVlIGZvciBmaWxlIHBhdGggY29uc3RydWN0aW9uXG4gIC8vIFRoZSBub3JtYWxpemVyIHNob3VsZCBoYXZlIGFscmVhZHkgc3RyaXBwZWQgYmFzZSBVUkxzIHByb3Blcmx5XG4gIGNvbnN0IHJvdXRlRm9yRmlsZVBhdGggPSB2YWx1ZTtcblxuICBsZXQgZmlsZVBhdGggPSByZXNvbHZlKGhvc3REaXIsIHJvdXRlRm9yRmlsZVBhdGgpO1xuICBsZXQgY29udGVudFR5cGU7XG4gIGlmIChpc1NlcnZlckFjdGlvblJlcXVlc3QpIHtcbiAgICAvLyBGb3Igc2VydmVyIGFjdGlvbnMsIHdlJ2xsIGdldCB0aGUgYWN0dWFsIGZpbGUgcGF0aCBmcm9tIHRoZSByZXF1ZXN0IGJvZHlcbiAgICAvLyBUaGUgcm91dGUgaXMganVzdCBhIHBsYWNlaG9sZGVyXG4gICAgZmlsZVBhdGggPSByZXNvbHZlKGhvc3REaXIsIHJvdXRlRm9yRmlsZVBhdGgpO1xuICAgIGNvbnRlbnRUeXBlID0gXCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04XCI7XG4gIH0gZWxzZSBpZiAoaXNIdG1sUmVxdWVzdCkge1xuICAgIGlmICghaXNIdG1sKSB7XG4gICAgICBmaWxlUGF0aCA9IHJlc29sdmUoXG4gICAgICAgIGhvc3REaXIsXG4gICAgICAgIHJvdXRlRm9yRmlsZVBhdGgsXG4gICAgICAgIGhhbmRsZXJPcHRpb25zLmJ1aWxkLmh0bWxPdXRwdXRQYXRoXG4gICAgICApO1xuICAgIH1cbiAgICBjb250ZW50VHlwZSA9IFwidGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04XCI7XG4gIH0gZWxzZSBpZiAoaXNSc2NSZXF1ZXN0KSB7XG4gICAgaWYgKCFpc1JzYykge1xuICAgICAgLy8gVmFsdWUgZG9lc24ndCBlbmQgd2l0aCAucnNjLCBhcHBlbmQgdGhlIHJzYyBvdXRwdXQgcGF0aFxuICAgICAgZmlsZVBhdGggPSByZXNvbHZlKFxuICAgICAgICBob3N0RGlyLFxuICAgICAgICByb3V0ZUZvckZpbGVQYXRoLFxuICAgICAgICBoYW5kbGVyT3B0aW9ucy5idWlsZC5yc2NPdXRwdXRQYXRoXG4gICAgICApO1xuICAgIH1cbiAgICBjb250ZW50VHlwZSA9IFwidGV4dC94LWNvbXBvbmVudDsgY2hhcnNldD11dGYtOFwiO1xuICB9IGVsc2UgaWYgKGlzQ3NzUmVxdWVzdCkge1xuICAgIGlmICghaXNDc3MpIHtcbiAgICAgIGZpbGVQYXRoID0gcmVzb2x2ZShob3N0RGlyLCByb3V0ZUZvckZpbGVQYXRoICsgXCIuY3NzXCIpO1xuICAgIH1cbiAgICBjb250ZW50VHlwZSA9IFwidGV4dC9jc3M7IGNoYXJzZXQ9dXRmLThcIjtcbiAgfSBlbHNlIGlmIChpc0pzUmVxdWVzdCkge1xuICAgIGlmICghaXNKUykge1xuICAgICAgZmlsZVBhdGggPSByZXNvbHZlKGhvc3REaXIsIHJvdXRlRm9yRmlsZVBhdGggKyBcIi5qc1wiKTtcbiAgICB9XG4gICAgY29udGVudFR5cGUgPSBcImFwcGxpY2F0aW9uL2phdmFzY3JpcHQ7IGNoYXJzZXQ9dXRmLThcIjtcbiAgfSBlbHNlIGlmIChpc0pzb25SZXF1ZXN0KSB7XG4gICAgaWYgKCFpc0pzb24pIHtcbiAgICAgIGZpbGVQYXRoID0gcmVzb2x2ZShob3N0RGlyLCByb3V0ZUZvckZpbGVQYXRoICsgXCIuanNvblwiKTtcbiAgICB9XG4gICAgY29udGVudFR5cGUgPSBcImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLThcIjtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBtaW1lVHlwZSA9IE1JTUVfVFlQRVNbZXh0XTtcbiAgICBpZiAobWltZVR5cGUpIHtcbiAgICAgIGNvbnRlbnRUeXBlID0gbWltZVR5cGUgKyBcIjsgY2hhcnNldD11dGYtOFwiO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50VHlwZSA9IFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCI7XG4gICAgfVxuICB9XG5cbiAgaWYgKGhhbmRsZXJPcHRpb25zLnZlcmJvc2UpIHtcbiAgICBpZiAoaXNGb3JtQWN0aW9uUmVxdWVzdCkge1xuICAgICAgaGFuZGxlck9wdGlvbnMubG9nZ2VyLmluZm8oYFtyZWFjdC1kZXYtc2VydmVyXSAoZm9ybS1hY3Rpb24pICR7cm91dGV9YCk7XG4gICAgfSBlbHNlIGlmIChpc1NlcnZlckFjdGlvblJlcXVlc3QpIHtcbiAgICAgIGhhbmRsZXJPcHRpb25zLmxvZ2dlci5pbmZvKGBbcmVhY3QtZGV2LXNlcnZlcl0gKHNlcnZlci1hY3Rpb24pICR7cm91dGV9YCk7XG4gICAgfSBlbHNlIGlmIChpc0h0bWxSZXF1ZXN0KSB7XG4gICAgICBoYW5kbGVyT3B0aW9ucy5sb2dnZXIuaW5mbyhgW3JlYWN0LWRldi1zZXJ2ZXJdIChodG1sKSAke3JvdXRlfWApO1xuICAgIH0gZWxzZSBpZiAoaXNSc2NSZXF1ZXN0KSB7XG4gICAgICBoYW5kbGVyT3B0aW9ucy5sb2dnZXIuaW5mbyhgW3JlYWN0LWRldi1zZXJ2ZXJdIChyc2MpICR7cm91dGV9YCk7XG4gICAgfSBlbHNlIGlmIChpc0Nzc1JlcXVlc3QpIHtcbiAgICAgIGhhbmRsZXJPcHRpb25zLmxvZ2dlci5pbmZvKGBbcmVhY3QtZGV2LXNlcnZlcl0gKGNzcykgJHtyb3V0ZX1gKTtcbiAgICB9IGVsc2UgaWYgKGlzSnNSZXF1ZXN0KSB7XG4gICAgICBoYW5kbGVyT3B0aW9ucy5sb2dnZXIuaW5mbyhgW3JlYWN0LWRldi1zZXJ2ZXJdIChqcykgJHtyb3V0ZX1gKTtcbiAgICB9IGVsc2UgaWYgKGlzSnNvblJlcXVlc3QpIHtcbiAgICAgIGhhbmRsZXJPcHRpb25zLmxvZ2dlci5pbmZvKGBbcmVhY3QtZGV2LXNlcnZlcl0gKGpzb24pICR7cm91dGV9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhhbmRsZXJPcHRpb25zLmxvZ2dlci5pbmZvKGBbcmVhY3QtZGV2LXNlcnZlcl0gKG90aGVyKSAke3JvdXRlfWApO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIHJvdXRlLFxuICAgIHVybDogcm91dGVUb1VSTChyb3V0ZSwgaGFuZGxlck9wdGlvbnMubW9kdWxlQmFzZVVSTCwgaGFuZGxlck9wdGlvbnMuYnVpbGQucnNjT3V0cHV0UGF0aCksXG4gICAgZXh0LFxuICAgIGlzSHRtbFJlcXVlc3QsXG4gICAgaXNSc2NSZXF1ZXN0LFxuICAgIGlzQ3NzUmVxdWVzdCxcbiAgICBpc0NzcyxcbiAgICBpc0h0bWwsXG4gICAgaXNSc2MsXG4gICAgaXNGb2xkZXIsXG4gICAgY29udGVudFR5cGUsXG4gICAgZmlsZVBhdGgsXG4gICAgaXNKUyxcbiAgICBpc1ZlbmRvcixcbiAgICBpc1ZpcnR1YWwsXG4gICAgaGFzSnNIZWFkZXIsXG4gICAgaXNKc1JlcXVlc3QsXG4gICAgaXNKc29uLFxuICAgIGlzSnNvblJlcXVlc3QsXG4gICAgaGFzQ3NzSGVhZGVyLFxuICAgIGhhc0pzb25IZWFkZXIsXG4gICAgaGFzSHRtbEhlYWRlcixcbiAgICBoYXNSc2NIZWFkZXIsXG4gICAgaGFzU2VydmVyQWN0aW9uSGVhZGVycyxcbiAgICBpc1NlcnZlckFjdGlvblJlcXVlc3QsXG4gICAgaXNGb3JtQ29udGVudFR5cGUsXG4gICAgaXNGb3JtQWN0aW9uUmVxdWVzdCxcbiAg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