vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
272 lines (269 loc) • 36.7 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { Root } from '../components/root.js';
import { Html } from '../components/html.js';
import { parse } from 'react-server-loader/transformer';
import { detectClientModule } from 'react-server-loader/directives';
import { pluginRoot } from '../root.js';
import { getNodeEnv } from './getNodeEnv.js';
import { getCondition } from './getCondition.js';
import { createLogger } from 'vite';
const LOGGER = createLogger();
const DIRECTIVE_PATTERNS = {
// Client directive must be at start of file
CLIENT: /^\s*(?:"use client"|'use client')\s*(?:\n|;|$)/,
// Server directive can be anywhere but must be properly terminated
SERVER: /(?:"use server"|'use server')\s*(?:\n|;|$)/,
// Generic pattern for both directives
ANY: /(?:"use\s+(?:client|server)"|'use\s+(?:client|server)')\s*(?:\n|;|$)/g
};
const SERVER_ACTION_FILE = /(\.|\/)?server(\.|\/)?/;
const IS_SERVER_ACTION_CODE = (code, moduleId) => code.match(SERVER_ACTION_FILE) != null || moduleId && SERVER_ACTION_FILE.test(moduleId.toLowerCase()) || false;
const IS_CLIENT_COMPONENT_CODE = (code, moduleId) => detectClientModule({ source: code, moduleId });
const IS_CLIENT_COMPONENT_BY_CODE = (code) => detectClientModule({ source: code });
const IS_CLIENT_COMPONENT_BY_NAME = (moduleId, _transformedModuleId) => detectClientModule({ moduleId });
const DIRECTIVE_CONFIGS = {
client: {
functionLevel: false,
target: "client",
validate: (params) => {
return params.index === 0;
},
warning: "'use client' directive is only allowed at the top of a file"
},
server: {
functionLevel: true,
target: "server",
validate: (params) => {
const before = params.code.slice(0, params.index).trim();
return before === "" || before.endsWith("\n");
},
warning: "File-level directives must be at the top of the file, before any other code"
}
};
const getDirectiveType = (directive) => {
if (directive.includes("client")) return "client";
if (directive.includes("server")) return "server";
return void 0;
};
const MODE = getNodeEnv();
const CONDITION = getCondition();
const IS_SERVER = CONDITION === "react-server";
const IS_CLIENT = CONDITION === "react-client";
const IS_BUILD = process.argv.includes("build");
const IS_SERVE = !IS_BUILD;
const DEFAULT_LOADER_CONFIG = {
serverDirective: DIRECTIVE_PATTERNS.SERVER,
clientDirective: DIRECTIVE_PATTERNS.CLIENT,
directivePattern: DIRECTIVE_PATTERNS.ANY,
isServerFunctionCode: IS_SERVER_ACTION_CODE,
isClientComponentCode: IS_CLIENT_COMPONENT_CODE,
isClientComponentByCode: IS_CLIENT_COMPONENT_BY_CODE,
isClientComponentByName: IS_CLIENT_COMPONENT_BY_NAME,
allowedDirectives: DIRECTIVE_CONFIGS,
importServerPath: "react-server-dom-esm/server",
importClientPath: "react-server-dom-esm/server",
registerClientReferenceName: "registerClientReference",
registerServerReferenceName: "registerServerReference",
getDirectiveType,
parse,
mode: MODE,
verbose: false,
logger: LOGGER,
moduleID: (moduleId, _sourceContent) => typeof moduleId === "string" ? moduleId : String(moduleId)
};
const BASE_PATTERNS = {
MODULE: "\\.(m|c)?(j|t)sx?$",
SERVER: "(?:\\.|\\/)?server(?:\\.(m|c)?(j|t)sx?)?$",
CLIENT: "(?:\\.|\\/)?client(?:\\.(m|c)?(j|t)sx?)?$",
PAGE: "(?:\\.|\\/)?(P|p)age(?:\\.(m|c)?(j|t)sx?)?$",
PROPS: "(?:\\.|\\/)?props(?:\\.(m|c)?(j|t)sx?)?$",
DIRECTIVE: '^"use (client|server)"[\\s;]*\\n?/m',
VENDOR: "node_modules|@",
VIRTUAL: "@",
DOT_FILES: "\\.",
EXT: {
JS: ".js",
CSS: ".css",
CSS_MODULE: ".module.css.js",
JSON: ".json",
HTML: ".html",
RSC: ".rsc",
NODE: ".node"
}
};
const DEFAULT_CONFIG = {
CLIENT_ASSETS_DIR: "assets",
RSC_DIR: "rsc",
MODULE_BASE: "src",
// Both default to "/" so emitted client-reference moduleIDs ("/foo.client.js")
// concatenate cleanly with the consumer's moduleBaseURL ("/") in
// `react-server-dom-esm`'s client (literal string concat at
// `react-server-dom-esm-client.*.development.js`). When MODULE_BASE_PATH was
// "", `createModuleID`'s Step-5 prepend was skipped, the transformer's
// hosting step added the leading "/" on its own, and the resulting
// moduleID + moduleBaseURL combination produced "//foo.client.js" in dev —
// browsers ESM-import that literally, Vite's dev catch-all returns its
// index.html, and the module loader rejects on MIME mismatch
// (`NS_ERROR_CORRUPTED_CONTENT`). Consumers that explicitly set
// moduleBasePath (mmc historically did, bidoof always has) sidestepped it;
// consumers leaning on the default tripped over it.
MODULE_BASE_PATH: "/",
MODULE_BASE_URL: "/",
PUBLIC_ORIGIN: "",
PAGE: "page.tsx",
PROPS: "props.ts",
CLIENT_ENTRY: void 0,
SERVER_ENTRY: void 0,
PAGE_EXPORT_NAME: "Page",
PROPS_EXPORT_NAME: "props",
HTML_EXPORT_NAME: "Html",
ROOT_EXPORT_NAME: "Root",
HTML_WORKER_PATH: `worker/html/html-worker.${process.env["NODE_ENV"] === "production" ? "production" : "development"}.js`,
RSC_WORKER_PATH: `worker/rsc/rsc-worker.${process.env["NODE_ENV"] === "production" ? "production" : "development"}.js`,
LOADER_PATH: "worker/loader.js",
RSC_EXTENSION: ".rsc",
ROOT: void 0,
HTML: void 0,
ON_METRICS: void 0,
ON_EVENT: void 0,
DEV_PORT: 5173,
PREVIEW_PORT: 4173,
DEV_HOST: "localhost",
PREVIEW_HOST: "localhost",
ENV_PREFIX: "VITE_",
REACT_DIRECTIVES: /* @__PURE__ */ new Set(["use client", "use server"]),
RSC_TIMEOUT: 5e3,
// 5 seconds default timeout for RSC operations
HTML_TIMEOUT: 15e3,
// 15 seconds default timeout for HTML generation operations
HTML_WORKER_STARTUP_TIMEOUT: 3e3,
// 3 seconds default timeout for HTML worker startup
RSC_WORKER_STARTUP_TIMEOUT: 3e3,
// 3 seconds default timeout for RSC worker startup
FILE_WRITE_TIMEOUT: 1e4,
// 10 seconds default timeout for file write operations
WORKER_SHUTDOWN_TIMEOUT: 1e3,
// Reduced to 1 second for faster test cleanup
COMPONENTS: {
Html,
Root
},
BUILD: {
pages: [],
client: "client",
server: "server",
static: "static",
api: "api",
outDir: "dist",
assetsDir: "assets",
hash: "hash",
preserveModulesRoot: false,
rscOutputPath: "index.rsc",
htmlOutputPath: "index.html",
extensionMap: {
// Module patterns
[BASE_PATTERNS.MODULE]: BASE_PATTERNS.EXT.JS,
// Client/Server patterns
[BASE_PATTERNS.CLIENT]: BASE_PATTERNS.EXT.JS,
[BASE_PATTERNS.SERVER]: BASE_PATTERNS.EXT.JS,
// File extensions
[BASE_PATTERNS.EXT.CSS]: BASE_PATTERNS.EXT.CSS,
[BASE_PATTERNS.EXT.JSON]: BASE_PATTERNS.EXT.JSON,
[BASE_PATTERNS.EXT.HTML]: BASE_PATTERNS.EXT.HTML,
[BASE_PATTERNS.EXT.RSC]: BASE_PATTERNS.EXT.RSC,
[BASE_PATTERNS.EXT.NODE]: BASE_PATTERNS.EXT.NODE + BASE_PATTERNS.EXT.JS,
// Special cases
".client": ".client" + BASE_PATTERNS.EXT.JS,
".server": ".server" + BASE_PATTERNS.EXT.JS
},
moduleExtension: BASE_PATTERNS.EXT.JS,
jsExtension: BASE_PATTERNS.EXT.JS,
cssExtension: BASE_PATTERNS.EXT.CSS,
htmlExtension: BASE_PATTERNS.EXT.HTML,
jsonExtension: BASE_PATTERNS.EXT.JSON,
rscExtension: BASE_PATTERNS.EXT.RSC,
cssModuleExtension: BASE_PATTERNS.EXT.CSS_MODULE,
nodeExtension: BASE_PATTERNS.EXT.NODE,
// these defaults rely on process.argv
// even better is to use configEnv.command === "build"
// which will be done in createHandlerOptions.server.ts and createHandlerOptions.client.ts
useRscWorker: !IS_SERVER && IS_BUILD,
useHtmlWorker: IS_SERVER && IS_BUILD
},
DEV: {
// these defaults rely on process.argv
useHtmlWorker: false,
// during dev, the browser is the html-worker..
// if the user opts-in to creating the html-worker, the stream utilities
// will be able to stream html during development - the plugin never does this
// so we don't have to create the html-worker during dev by default
useRscWorker: !IS_SERVER && IS_SERVE
// during dev without server-conditions,
// the rsc-worker is created during dev by default
// this is because the rsc-worker is used to stream rsc during development
},
CSS: {
inlineCss: void 0,
purgeCss: false,
inlineThreshold: 4096,
// 4KB
inlinePatterns: [],
// Always inline CSS modules
linkPatterns: []
// Always link node_modules CSS
},
AUTO_DISCOVER: {
clientEntry: "**/*.client.*",
serverEntry: "**/*.server.*",
cssEntry: "**/*.css",
jsonEntry: "**/*.json",
htmlEntry: "**/*.html",
// Pattern matchers
modulePattern: new RegExp(BASE_PATTERNS.MODULE),
serverPattern: new RegExp(BASE_PATTERNS.SERVER),
clientPattern: new RegExp(BASE_PATTERNS.CLIENT),
pagePattern: new RegExp(BASE_PATTERNS.PAGE),
propsPattern: new RegExp(BASE_PATTERNS.PROPS),
// File patterns
cssPattern: new RegExp(`\\${BASE_PATTERNS.EXT.CSS}$`),
jsonPattern: new RegExp(`\\${BASE_PATTERNS.EXT.JSON}$`),
htmlPattern: new RegExp(`\\${BASE_PATTERNS.EXT.HTML}$`),
rscPattern: new RegExp(`\\${BASE_PATTERNS.EXT.RSC}$`),
nodeOnly: new RegExp(`\\${BASE_PATTERNS.EXT.NODE}$`),
cssModulePattern: new RegExp(
`\\${BASE_PATTERNS.EXT.CSS}\\${BASE_PATTERNS.EXT.JS}$`
),
vendorPattern: /^\/node_modules\//,
virtualPattern: /^\/@\//,
dotFiles: new RegExp(`${BASE_PATTERNS.DOT_FILES}`)
},
MODULE_ID: (id) => id,
VERBOSE: false,
PANIC_THRESHOLD: MODE === "development" ? "critical_errors" : "all_errors",
// Centralized loader config for RSC boundaries
RSC_LOADER: {
development: {
...DEFAULT_LOADER_CONFIG,
mode: "development"
},
test: {
...DEFAULT_LOADER_CONFIG,
importServerPath: "react-server-dom-esm/server.node",
importClientPath: "react-server-dom-esm/server.node",
mode: "test"
},
production: {
...DEFAULT_LOADER_CONFIG,
mode: "production"
}
},
REACT_LOADER_PATH: pluginRoot + "/loader/react-loader.js",
CSS_LOADER_PATH: pluginRoot + "/loader/css-loader.js",
ENV_LOADER_PATH: pluginRoot + "/loader/env-loader.js"
};
export { BASE_PATTERNS, CONDITION, DEFAULT_CONFIG, DEFAULT_LOADER_CONFIG, DIRECTIVE_CONFIGS, IS_BUILD, IS_CLIENT, IS_SERVE, IS_SERVER, MODE, getDirectiveType };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdHMuanMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3BsdWdpbi9jb25maWcvZGVmYXVsdHMudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJvb3QgfSBmcm9tIFwiLi4vY29tcG9uZW50cy9yb290LmpzXCI7XG5pbXBvcnQgeyBIdG1sIH0gZnJvbSBcIi4uL2NvbXBvbmVudHMvaHRtbC5qc1wiO1xuaW1wb3J0IHsgcGFyc2UgfSBmcm9tIFwicmVhY3Qtc2VydmVyLWxvYWRlci90cmFuc2Zvcm1lclwiO1xuaW1wb3J0IHsgZGV0ZWN0Q2xpZW50TW9kdWxlIH0gZnJvbSBcInJlYWN0LXNlcnZlci1sb2FkZXIvZGlyZWN0aXZlc1wiO1xuaW1wb3J0IHsgcGx1Z2luUm9vdCB9IGZyb20gXCIuLi9yb290LmpzXCI7XG5pbXBvcnQgeyBnZXROb2RlRW52IH0gZnJvbSBcIi4vZ2V0Tm9kZUVudi5qc1wiO1xuaW1wb3J0IHsgZ2V0Q29uZGl0aW9uIH0gZnJvbSBcIi4vZ2V0Q29uZGl0aW9uLmpzXCI7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tIFwidml0ZVwiO1xuY29uc3QgTE9HR0VSID0gY3JlYXRlTG9nZ2VyKCk7XG4vLyBEaXJlY3RpdmUgcGF0dGVybnMgLSBtYXRjaGluZyB0aGUgbG9naWMgaW4gZmluZERpcmVjdGl2ZU1hdGNoZXMudHNcbmNvbnN0IERJUkVDVElWRV9QQVRURVJOUyA9IHtcbiAgLy8gQ2xpZW50IGRpcmVjdGl2ZSBtdXN0IGJlIGF0IHN0YXJ0IG9mIGZpbGVcbiAgQ0xJRU5UOiAvXlxccyooPzpcInVzZSBjbGllbnRcInwndXNlIGNsaWVudCcpXFxzKig/Olxcbnw7fCQpLyxcbiAgLy8gU2VydmVyIGRpcmVjdGl2ZSBjYW4gYmUgYW55d2hlcmUgYnV0IG11c3QgYmUgcHJvcGVybHkgdGVybWluYXRlZFxuICBTRVJWRVI6IC8oPzpcInVzZSBzZXJ2ZXJcInwndXNlIHNlcnZlcicpXFxzKig/Olxcbnw7fCQpLyxcbiAgLy8gR2VuZXJpYyBwYXR0ZXJuIGZvciBib3RoIGRpcmVjdGl2ZXNcbiAgQU5ZOiAvKD86XCJ1c2VcXHMrKD86Y2xpZW50fHNlcnZlcilcInwndXNlXFxzKyg/OmNsaWVudHxzZXJ2ZXIpJylcXHMqKD86XFxufDt8JCkvZyxcbn0gYXMgY29uc3Q7XG5cbmNvbnN0IFNFUlZFUl9BQ1RJT05fRklMRSA9IC8oXFwufFxcLyk/c2VydmVyKFxcLnxcXC8pPy87XG5jb25zdCBJU19TRVJWRVJfQUNUSU9OX0NPREUgPSAoY29kZTogc3RyaW5nLCBtb2R1bGVJZD86IHN0cmluZykgPT5cbiAgY29kZS5tYXRjaChTRVJWRVJfQUNUSU9OX0ZJTEUpICE9IG51bGwgfHxcbiAgKG1vZHVsZUlkICYmIFNFUlZFUl9BQ1RJT05fRklMRS50ZXN0KG1vZHVsZUlkLnRvTG93ZXJDYXNlKCkpKSB8fFxuICBmYWxzZTtcblxuLy8gRGVmYXVsdHMgZm9yIHRoZSB1c2VyLW92ZXJyaWRhYmxlIGBsb2FkZXIuaXNDbGllbnRDb21wb25lbnQqYCBob29rcy4gQWxsXG4vLyB0aHJlZSBkZWxlZ2F0ZSB0byB0aGUgc2luZ2xlIGRldGVjdG9yIGF0XG4vLyBgbG9hZGVyL2RpcmVjdGl2ZXMvZGV0ZWN0Q2xpZW50TW9kdWxlYCwgd2hpY2ggcmVjb2duaXNlcyBhIG1vZHVsZSBhc1xuLy8gY2xpZW50IHdoZW4gaXRzIGZpbGVuYW1lIG1hdGNoZXMgYC5jbGllbnQuW2NtXT9banRdc3g/JGAgT1IgaXRzIHNvdXJjZVxuLy8gZGVjbGFyZXMgYSB0b3Atb2YtZmlsZSBgXCJ1c2UgY2xpZW50XCJgIGRpcmVjdGl2ZSAoQVNULXZhbGlkYXRlZCB3aGVuIGFcbi8vIHBhcnNlciBpcyBhdmFpbGFibGUsIGNoYXItc2Nhbm5lciBvdGhlcndpc2UpLiBBIHBhdGggd2l0aCBcImNsaWVudFwiIGFzIGFcbi8vIHN1YnN0cmluZyBvZiBhbiBpZGVudGlmaWVyLCBjb21tZW50LCBvciBkaXJlY3RvcnkgbmFtZSAoZS5nLlxuLy8gYHNyYy9saWIvY2xpZW50SWQudHNgKSBpcyBOT1QgYSBjbGllbnQgbW9kdWxlLlxuY29uc3QgSVNfQ0xJRU5UX0NPTVBPTkVOVF9DT0RFID0gKGNvZGU6IHN0cmluZywgbW9kdWxlSWQ/OiBzdHJpbmcpID0+XG4gIGRldGVjdENsaWVudE1vZHVsZSh7IHNvdXJjZTogY29kZSwgbW9kdWxlSWQgfSk7XG5cbmNvbnN0IElTX0NMSUVOVF9DT01QT05FTlRfQllfQ09ERSA9IChjb2RlOiBzdHJpbmcpID0+XG4gIGRldGVjdENsaWVudE1vZHVsZSh7IHNvdXJjZTogY29kZSB9KTtcblxuY29uc3QgSVNfQ0xJRU5UX0NPTVBPTkVOVF9CWV9OQU1FID0gKFxuICBtb2R1bGVJZDogc3RyaW5nLFxuICBfdHJhbnNmb3JtZWRNb2R1bGVJZD86IHN0cmluZyxcbikgPT4gZGV0ZWN0Q2xpZW50TW9kdWxlKHsgbW9kdWxlSWQgfSk7XG4vLyBEaXJlY3RpdmUgY29uZmlndXJhdGlvbnNcbmV4cG9ydCBjb25zdCBESVJFQ1RJVkVfQ09ORklHUyA9IHtcbiAgY2xpZW50OiB7XG4gICAgZnVuY3Rpb25MZXZlbDogZmFsc2UsXG4gICAgdGFyZ2V0OiBcImNsaWVudFwiIGFzIGNvbnN0LFxuICAgIHZhbGlkYXRlOiAocGFyYW1zOiB7XG4gICAgICBjb2RlOiBzdHJpbmc7XG4gICAgICBtb2R1bGVJZD86IHN0cmluZztcbiAgICAgIGluZGV4OiBudW1iZXI7XG4gICAgICBtYXRjaDogUmVnRXhwRXhlY0FycmF5O1xuICAgIH0pID0+IHtcbiAgICAgIC8vIENsaWVudCBkaXJlY3RpdmUgbXVzdCBiZSBhdCB2ZXJ5IHN0YXJ0IG9mIGZpbGVcbiAgICAgIHJldHVybiBwYXJhbXMuaW5kZXggPT09IDA7XG4gICAgfSxcbiAgICB3YXJuaW5nOiBcIid1c2UgY2xpZW50JyBkaXJlY3RpdmUgaXMgb25seSBhbGxvd2VkIGF0IHRoZSB0b3Agb2YgYSBmaWxlXCIsXG4gIH0sXG4gIHNlcnZlcjoge1xuICAgIGZ1bmN0aW9uTGV2ZWw6IHRydWUsXG4gICAgdGFyZ2V0OiBcInNlcnZlclwiIGFzIGNvbnN0LFxuICAgIHZhbGlkYXRlOiAocGFyYW1zOiB7XG4gICAgICBjb2RlOiBzdHJpbmc7XG4gICAgICBtb2R1bGVJZD86IHN0cmluZztcbiAgICAgIGluZGV4OiBudW1iZXI7XG4gICAgICBtYXRjaDogUmVnRXhwRXhlY0FycmF5O1xuICAgIH0pID0+IHtcbiAgICAgIC8vIENoZWNrIGlmIGRpcmVjdGl2ZSBpcyBhdCBzdGFydCBvZiBmaWxlIG9yIGFmdGVyIG5ld2xpbmVcbiAgICAgIGNvbnN0IGJlZm9yZSA9IHBhcmFtcy5jb2RlLnNsaWNlKDAsIHBhcmFtcy5pbmRleCkudHJpbSgpO1xuICAgICAgcmV0dXJuIGJlZm9yZSA9PT0gXCJcIiB8fCBiZWZvcmUuZW5kc1dpdGgoXCJcXG5cIik7XG4gICAgfSxcbiAgICB3YXJuaW5nOlxuICAgICAgXCJGaWxlLWxldmVsIGRpcmVjdGl2ZXMgbXVzdCBiZSBhdCB0aGUgdG9wIG9mIHRoZSBmaWxlLCBiZWZvcmUgYW55IG90aGVyIGNvZGVcIixcbiAgfSxcbn0gYXMgY29uc3Q7XG5cbi8vIEhlbHBlciB0byBnZXQgZGlyZWN0aXZlIHR5cGUgZnJvbSBzdHJpbmdcbmV4cG9ydCBjb25zdCBnZXREaXJlY3RpdmVUeXBlID0gKFxuICBkaXJlY3RpdmU6IHN0cmluZ1xuKTogXCJjbGllbnRcIiB8IFwic2VydmVyXCIgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoZGlyZWN0aXZlLmluY2x1ZGVzKFwiY2xpZW50XCIpKSByZXR1cm4gXCJjbGllbnRcIjtcbiAgaWYgKGRpcmVjdGl2ZS5pbmNsdWRlcyhcInNlcnZlclwiKSkgcmV0dXJuIFwic2VydmVyXCI7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59O1xuXG5leHBvcnQgY29uc3QgTU9ERSA9IGdldE5vZGVFbnYoKTtcbmV4cG9ydCBjb25zdCBDT05ESVRJT04gPSBnZXRDb25kaXRpb24oKTtcbmV4cG9ydCBjb25zdCBJU19TRVJWRVIgPSBDT05ESVRJT04gPT09IFwicmVhY3Qtc2VydmVyXCI7XG5leHBvcnQgY29uc3QgSVNfQ0xJRU5UID0gQ09ORElUSU9OID09PSBcInJlYWN0LWNsaWVudFwiO1xuLy8gTm90ZTogVGhpcyBzaG91bGQgYmUgcmVwbGFjZWQgd2l0aCBjb25maWdFbnYuY29tbWFuZCA9PT0gXCJidWlsZFwiIGluIGZ1bmN0aW9ucyB0aGF0IHJlY2VpdmUgY29uZmlnRW52XG4vLyBUaGlzIGlzIGtlcHQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgYnV0IHNob3VsZCBub3QgYmUgdXNlZCBpbiBuZXcgY29kZVxuZXhwb3J0IGNvbnN0IElTX0JVSUxEID0gcHJvY2Vzcy5hcmd2LmluY2x1ZGVzKFwiYnVpbGRcIik7XG5leHBvcnQgY29uc3QgSVNfU0VSVkUgPSAhSVNfQlVJTEQ7IC8vIGRvbnQgaGF2ZSB0byBjaGVjayBmb3IgZGV2IHNpbmNlIGl0J3MgdGhlIGRlZmF1bHRcblxuLy8gSGVscGVyIHRvIG5vcm1hbGl6ZSBkaXJlY3RpdmUgc3RyaW5nc1xuLy8gY29uc3Qgbm9ybWFsaXplRGlyZWN0aXZlID0gKGRpcmVjdGl2ZTogc3RyaW5nKSA9PiBkaXJlY3RpdmUucmVwbGFjZSgvXFxzKy9nLCAnJykudG9Mb3dlckNhc2UoKTtcblxuLy8gRGVmYXVsdCBsb2FkZXIgY29uZmlndXJhdGlvblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfTE9BREVSX0NPTkZJRyA9IHtcbiAgc2VydmVyRGlyZWN0aXZlOiBESVJFQ1RJVkVfUEFUVEVSTlMuU0VSVkVSLFxuICBjbGllbnREaXJlY3RpdmU6IERJUkVDVElWRV9QQVRURVJOUy5DTElFTlQsXG4gIGRpcmVjdGl2ZVBhdHRlcm46IERJUkVDVElWRV9QQVRURVJOUy5BTlksXG4gIGlzU2VydmVyRnVuY3Rpb25Db2RlOiBJU19TRVJWRVJfQUNUSU9OX0NPREUsXG4gIGlzQ2xpZW50Q29tcG9uZW50Q29kZTogSVNfQ0xJRU5UX0NPTVBPTkVOVF9DT0RFLFxuICBpc0NsaWVudENvbXBvbmVudEJ5Q29kZTogSVNfQ0xJRU5UX0NPTVBPTkVOVF9CWV9DT0RFLFxuICBpc0NsaWVudENvbXBvbmVudEJ5TmFtZTogSVNfQ0xJRU5UX0NPTVBPTkVOVF9CWV9OQU1FLFxuICBhbGxvd2VkRGlyZWN0aXZlczogRElSRUNUSVZFX0NPTkZJR1MsXG4gIGltcG9ydFNlcnZlclBhdGg6IFwicmVhY3Qtc2VydmVyLWRvbS1lc20vc2VydmVyXCIsXG4gIGltcG9ydENsaWVudFBhdGg6IFwicmVhY3Qtc2VydmVyLWRvbS1lc20vc2VydmVyXCIsXG4gIHJlZ2lzdGVyQ2xpZW50UmVmZXJlbmNlTmFtZTogXCJyZWdpc3RlckNsaWVudFJlZmVyZW5jZVwiLFxuICByZWdpc3RlclNlcnZlclJlZmVyZW5jZU5hbWU6IFwicmVnaXN0ZXJTZXJ2ZXJSZWZlcmVuY2VcIixcbiAgZ2V0RGlyZWN0aXZlVHlwZSxcbiAgcGFyc2U6IHBhcnNlLFxuICBtb2RlOiBNT0RFLFxuICB2ZXJib3NlOiBmYWxzZSxcbiAgbG9nZ2VyOiBMT0dHRVIsXG4gIG1vZHVsZUlEOiAobW9kdWxlSWQ6IHN0cmluZywgX3NvdXJjZUNvbnRlbnQ/OiBzdHJpbmcpID0+XG4gICAgdHlwZW9mIG1vZHVsZUlkID09PSBcInN0cmluZ1wiID8gbW9kdWxlSWQgOiBTdHJpbmcobW9kdWxlSWQpLFxufSBhcyBjb25zdDtcblxuLy8gRGVmaW5lIGJhc2UgcGF0dGVybnMgdGhhdCBjYW4gYmUgcmV1c2VkXG5leHBvcnQgY29uc3QgQkFTRV9QQVRURVJOUyA9IHtcbiAgTU9EVUxFOiBcIlxcXFwuKG18Yyk/KGp8dClzeD8kXCIsXG4gIFNFUlZFUjogXCIoPzpcXFxcLnxcXFxcLyk/c2VydmVyKD86XFxcXC4obXxjKT8oanx0KXN4Pyk/JFwiLFxuICBDTElFTlQ6IFwiKD86XFxcXC58XFxcXC8pP2NsaWVudCg/OlxcXFwuKG18Yyk/KGp8dClzeD8pPyRcIixcbiAgUEFHRTogXCIoPzpcXFxcLnxcXFxcLyk/KFB8cClhZ2UoPzpcXFxcLihtfGMpPyhqfHQpc3g/KT8kXCIsXG4gIFBST1BTOiBcIig/OlxcXFwufFxcXFwvKT9wcm9wcyg/OlxcXFwuKG18Yyk/KGp8dClzeD8pPyRcIixcbiAgRElSRUNUSVZFOiAnXlwidXNlIChjbGllbnR8c2VydmVyKVwiW1xcXFxzO10qXFxcXG4/L20nLFxuICBWRU5ET1I6IFwibm9kZV9tb2R1bGVzfEBcIixcbiAgVklSVFVBTDogXCJAXCIsXG4gIERPVF9GSUxFUzogXCJcXFxcLlwiLFxuICBFWFQ6IHtcbiAgICBKUzogXCIuanNcIixcbiAgICBDU1M6IFwiLmNzc1wiLFxuICAgIENTU19NT0RVTEU6IFwiLm1vZHVsZS5jc3MuanNcIixcbiAgICBKU09OOiBcIi5qc29uXCIsXG4gICAgSFRNTDogXCIuaHRtbFwiLFxuICAgIFJTQzogXCIucnNjXCIsXG4gICAgTk9ERTogXCIubm9kZVwiLFxuICB9LFxufSBhcyBjb25zdDtcbmV4cG9ydCBjb25zdCBERUZBVUxUX0NPTkZJRyA9IHtcbiAgQ0xJRU5UX0FTU0VUU19ESVI6IFwiYXNzZXRzXCIsXG4gIFJTQ19ESVI6IFwicnNjXCIsXG4gIE1PRFVMRV9CQVNFOiBcInNyY1wiLFxuICAvLyBCb3RoIGRlZmF1bHQgdG8gXCIvXCIgc28gZW1pdHRlZCBjbGllbnQtcmVmZXJlbmNlIG1vZHVsZUlEcyAoXCIvZm9vLmNsaWVudC5qc1wiKVxuICAvLyBjb25jYXRlbmF0ZSBjbGVhbmx5IHdpdGggdGhlIGNvbnN1bWVyJ3MgbW9kdWxlQmFzZVVSTCAoXCIvXCIpIGluXG4gIC8vIGByZWFjdC1zZXJ2ZXItZG9tLWVzbWAncyBjbGllbnQgKGxpdGVyYWwgc3RyaW5nIGNvbmNhdCBhdFxuICAvLyBgcmVhY3Qtc2VydmVyLWRvbS1lc20tY2xpZW50LiouZGV2ZWxvcG1lbnQuanNgKS4gV2hlbiBNT0RVTEVfQkFTRV9QQVRIIHdhc1xuICAvLyBcIlwiLCBgY3JlYXRlTW9kdWxlSURgJ3MgU3RlcC01IHByZXBlbmQgd2FzIHNraXBwZWQsIHRoZSB0cmFuc2Zvcm1lcidzXG4gIC8vIGhvc3Rpbmcgc3RlcCBhZGRlZCB0aGUgbGVhZGluZyBcIi9cIiBvbiBpdHMgb3duLCBhbmQgdGhlIHJlc3VsdGluZ1xuICAvLyBtb2R1bGVJRCArIG1vZHVsZUJhc2VVUkwgY29tYmluYXRpb24gcHJvZHVjZWQgXCIvL2Zvby5jbGllbnQuanNcIiBpbiBkZXYg4oCUXG4gIC8vIGJyb3dzZXJzIEVTTS1pbXBvcnQgdGhhdCBsaXRlcmFsbHksIFZpdGUncyBkZXYgY2F0Y2gtYWxsIHJldHVybnMgaXRzXG4gIC8vIGluZGV4Lmh0bWwsIGFuZCB0aGUgbW9kdWxlIGxvYWRlciByZWplY3RzIG9uIE1JTUUgbWlzbWF0Y2hcbiAgLy8gKGBOU19FUlJPUl9DT1JSVVBURURfQ09OVEVOVGApLiBDb25zdW1lcnMgdGhhdCBleHBsaWNpdGx5IHNldFxuICAvLyBtb2R1bGVCYXNlUGF0aCAobW1jIGhpc3RvcmljYWxseSBkaWQsIGJpZG9vZiBhbHdheXMgaGFzKSBzaWRlc3RlcHBlZCBpdDtcbiAgLy8gY29uc3VtZXJzIGxlYW5pbmcgb24gdGhlIGRlZmF1bHQgdHJpcHBlZCBvdmVyIGl0LlxuICBNT0RVTEVfQkFTRV9QQVRIOiBcIi9cIixcbiAgTU9EVUxFX0JBU0VfVVJMOiBcIi9cIixcbiAgUFVCTElDX09SSUdJTjogXCJcIixcbiAgUEFHRTogXCJwYWdlLnRzeFwiLFxuICBQUk9QUzogXCJwcm9wcy50c1wiLFxuICBDTElFTlRfRU5UUlk6IHVuZGVmaW5lZCxcbiAgU0VSVkVSX0VOVFJZOiB1bmRlZmluZWQsXG4gIFBBR0VfRVhQT1JUX05BTUU6IFwiUGFnZVwiLFxuICBQUk9QU19FWFBPUlRfTkFNRTogXCJwcm9wc1wiLFxuICBIVE1MX0VYUE9SVF9OQU1FOiBcIkh0bWxcIixcbiAgUk9PVF9FWFBPUlRfTkFNRTogXCJSb290XCIsXG4gIEhUTUxfV09SS0VSX1BBVEg6IGB3b3JrZXIvaHRtbC9odG1sLXdvcmtlci4ke1xuICAgIHByb2Nlc3MuZW52W1wiTk9ERV9FTlZcIl0gPT09IFwicHJvZHVjdGlvblwiID8gXCJwcm9kdWN0aW9uXCIgOiBcImRldmVsb3BtZW50XCJcbiAgfS5qc2AsXG4gIFJTQ19XT1JLRVJfUEFUSDogYHdvcmtlci9yc2MvcnNjLXdvcmtlci4ke1xuICAgIHByb2Nlc3MuZW52W1wiTk9ERV9FTlZcIl0gPT09IFwicHJvZHVjdGlvblwiID8gXCJwcm9kdWN0aW9uXCIgOiBcImRldmVsb3BtZW50XCJcbiAgfS5qc2AsXG4gIExPQURFUl9QQVRIOiBcIndvcmtlci9sb2FkZXIuanNcIixcbiAgUlNDX0VYVEVOU0lPTjogXCIucnNjXCIsXG4gIFJPT1Q6IHVuZGVmaW5lZCxcbiAgSFRNTDogdW5kZWZpbmVkLFxuICBPTl9NRVRSSUNTOiB1bmRlZmluZWQsXG4gIE9OX0VWRU5UOiB1bmRlZmluZWQsXG4gIERFVl9QT1JUOiA1MTczLFxuICBQUkVWSUVXX1BPUlQ6IDQxNzMsXG4gIERFVl9IT1NUOiBcImxvY2FsaG9zdFwiLFxuICBQUkVWSUVXX0hPU1Q6IFwibG9jYWxob3N0XCIsXG4gIEVOVl9QUkVGSVg6IFwiVklURV9cIixcbiAgUkVBQ1RfRElSRUNUSVZFUzogbmV3IFNldChbXCJ1c2UgY2xpZW50XCIsIFwidXNlIHNlcnZlclwiXSksXG4gIFJTQ19USU1FT1VUOiA1MDAwLCAvLyA1IHNlY29uZHMgZGVmYXVsdCB0aW1lb3V0IGZvciBSU0Mgb3BlcmF0aW9uc1xuICBIVE1MX1RJTUVPVVQ6IDE1MDAwLCAvLyAxNSBzZWNvbmRzIGRlZmF1bHQgdGltZW91dCBmb3IgSFRNTCBnZW5lcmF0aW9uIG9wZXJhdGlvbnNcbiAgSFRNTF9XT1JLRVJfU1RBUlRVUF9USU1FT1VUOiAzMDAwLCAvLyAzIHNlY29uZHMgZGVmYXVsdCB0aW1lb3V0IGZvciBIVE1MIHdvcmtlciBzdGFydHVwXG4gIFJTQ19XT1JLRVJfU1RBUlRVUF9USU1FT1VUOiAzMDAwLCAvLyAzIHNlY29uZHMgZGVmYXVsdCB0aW1lb3V0IGZvciBSU0Mgd29ya2VyIHN0YXJ0dXBcbiAgRklMRV9XUklURV9USU1FT1VUOiAxMDAwMCwgLy8gMTAgc2Vjb25kcyBkZWZhdWx0IHRpbWVvdXQgZm9yIGZpbGUgd3JpdGUgb3BlcmF0aW9uc1xuICBXT1JLRVJfU0hVVERPV05fVElNRU9VVDogMTAwMCwgLy8gUmVkdWNlZCB0byAxIHNlY29uZCBmb3IgZmFzdGVyIHRlc3QgY2xlYW51cFxuICBDT01QT05FTlRTOiB7XG4gICAgSHRtbDogSHRtbCxcbiAgICBSb290OiBSb290LFxuICB9LFxuICBCVUlMRDoge1xuICAgIHBhZ2VzOiBbXSxcbiAgICBjbGllbnQ6IFwiY2xpZW50XCIsXG4gICAgc2VydmVyOiBcInNlcnZlclwiLFxuICAgIHN0YXRpYzogXCJzdGF0aWNcIixcbiAgICBhcGk6IFwiYXBpXCIsXG4gICAgb3V0RGlyOiBcImRpc3RcIixcbiAgICBhc3NldHNEaXI6IFwiYXNzZXRzXCIsXG4gICAgaGFzaDogXCJoYXNoXCIsXG4gICAgcHJlc2VydmVNb2R1bGVzUm9vdDogZmFsc2UsXG4gICAgcnNjT3V0cHV0UGF0aDogXCJpbmRleC5yc2NcIixcbiAgICBodG1sT3V0cHV0UGF0aDogXCJpbmRleC5odG1sXCIsXG4gICAgZXh0ZW5zaW9uTWFwOiB7XG4gICAgICAvLyBNb2R1bGUgcGF0dGVybnNcbiAgICAgIFtCQVNFX1BBVFRFUk5TLk1PRFVMRV06IEJBU0VfUEFUVEVSTlMuRVhULkpTLFxuICAgICAgLy8gQ2xpZW50L1NlcnZlciBwYXR0ZXJuc1xuICAgICAgW0JBU0VfUEFUVEVSTlMuQ0xJRU5UXTogQkFTRV9QQVRURVJOUy5FWFQuSlMsXG4gICAgICBbQkFTRV9QQVRURVJOUy5TRVJWRVJdOiBCQVNFX1BBVFRFUk5TLkVYVC5KUyxcbiAgICAgIC8vIEZpbGUgZXh0ZW5zaW9uc1xuICAgICAgW0JBU0VfUEFUVEVSTlMuRVhULkNTU106IEJBU0VfUEFUVEVSTlMuRVhULkNTUyxcbiAgICAgIFtCQVNFX1BBVFRFUk5TLkVYVC5KU09OXTogQkFTRV9QQVRURVJOUy5FWFQuSlNPTixcbiAgICAgIFtCQVNFX1BBVFRFUk5TLkVYVC5IVE1MXTogQkFTRV9QQVRURVJOUy5FWFQuSFRNTCxcbiAgICAgIFtCQVNFX1BBVFRFUk5TLkVYVC5SU0NdOiBCQVNFX1BBVFRFUk5TLkVYVC5SU0MsXG4gICAgICBbQkFTRV9QQVRURVJOUy5FWFQuTk9ERV06IEJBU0VfUEFUVEVSTlMuRVhULk5PREUgKyBCQVNFX1BBVFRFUk5TLkVYVC5KUyxcbiAgICAgIC8vIFNwZWNpYWwgY2FzZXNcbiAgICAgIFwiLmNsaWVudFwiOiBcIi5jbGllbnRcIiArIEJBU0VfUEFUVEVSTlMuRVhULkpTLFxuICAgICAgXCIuc2VydmVyXCI6IFwiLnNlcnZlclwiICsgQkFTRV9QQVRURVJOUy5FWFQuSlMsXG4gICAgfSxcbiAgICBtb2R1bGVFeHRlbnNpb246IEJBU0VfUEFUVEVSTlMuRVhULkpTLFxuICAgIGpzRXh0ZW5zaW9uOiBCQVNFX1BBVFRFUk5TLkVYVC5KUyxcbiAgICBjc3NFeHRlbnNpb246IEJBU0VfUEFUVEVSTlMuRVhULkNTUyxcbiAgICBodG1sRXh0ZW5zaW9uOiBCQVNFX1BBVFRFUk5TLkVYVC5IVE1MLFxuICAgIGpzb25FeHRlbnNpb246IEJBU0VfUEFUVEVSTlMuRVhULkpTT04sXG4gICAgcnNjRXh0ZW5zaW9uOiBCQVNFX1BBVFRFUk5TLkVYVC5SU0MsXG4gICAgY3NzTW9kdWxlRXh0ZW5zaW9uOiBCQVNFX1BBVFRFUk5TLkVYVC5DU1NfTU9EVUxFLFxuICAgIG5vZGVFeHRlbnNpb246IEJBU0VfUEFUVEVSTlMuRVhULk5PREUsXG4gICAgLy8gdGhlc2UgZGVmYXVsdHMgcmVseSBvbiBwcm9jZXNzLmFyZ3ZcbiAgICAvLyBldmVuIGJldHRlciBpcyB0byB1c2UgY29uZmlnRW52LmNvbW1hbmQgPT09IFwiYnVpbGRcIlxuICAgIC8vIHdoaWNoIHdpbGwgYmUgZG9uZSBpbiBjcmVhdGVIYW5kbGVyT3B0aW9ucy5zZXJ2ZXIudHMgYW5kIGNyZWF0ZUhhbmRsZXJPcHRpb25zLmNsaWVudC50c1xuICAgIHVzZVJzY1dvcmtlcjogIUlTX1NFUlZFUiAmJiBJU19CVUlMRCxcbiAgICB1c2VIdG1sV29ya2VyOiBJU19TRVJWRVIgJiYgSVNfQlVJTEQsXG4gIH0sXG4gIERFVjoge1xuICAgIC8vIHRoZXNlIGRlZmF1bHRzIHJlbHkgb24gcHJvY2Vzcy5hcmd2XG4gICAgdXNlSHRtbFdvcmtlcjogZmFsc2UsIC8vIGR1cmluZyBkZXYsIHRoZSBicm93c2VyIGlzIHRoZSBodG1sLXdvcmtlci4uXG4gICAgLy8gaWYgdGhlIHVzZXIgb3B0cy1pbiB0byBjcmVhdGluZyB0aGUgaHRtbC13b3JrZXIsIHRoZSBzdHJlYW0gdXRpbGl0aWVzXG4gICAgLy8gd2lsbCBiZSBhYmxlIHRvIHN0cmVhbSBodG1sIGR1cmluZyBkZXZlbG9wbWVudCAtIHRoZSBwbHVnaW4gbmV2ZXIgZG9lcyB0aGlzXG4gICAgLy8gc28gd2UgZG9uJ3QgaGF2ZSB0byBjcmVhdGUgdGhlIGh0bWwtd29ya2VyIGR1cmluZyBkZXYgYnkgZGVmYXVsdFxuICAgIHVzZVJzY1dvcmtlcjogIUlTX1NFUlZFUiAmJiBJU19TRVJWRSwgLy8gZHVyaW5nIGRldiB3aXRob3V0IHNlcnZlci1jb25kaXRpb25zLFxuICAgIC8vIHRoZSByc2Mtd29ya2VyIGlzIGNyZWF0ZWQgZHVyaW5nIGRldiBieSBkZWZhdWx0XG4gICAgLy8gdGhpcyBpcyBiZWNhdXNlIHRoZSByc2Mtd29ya2VyIGlzIHVzZWQgdG8gc3RyZWFtIHJzYyBkdXJpbmcgZGV2ZWxvcG1lbnRcbiAgfSxcbiAgQ1NTOiB7XG4gICAgaW5saW5lQ3NzOiB1bmRlZmluZWQsXG4gICAgcHVyZ2VDc3M6IGZhbHNlLFxuICAgIGlubGluZVRocmVzaG9sZDogNDA5NiwgLy8gNEtCXG4gICAgaW5saW5lUGF0dGVybnM6IFtdIGFzIFJlZ0V4cFtdLCAvLyBBbHdheXMgaW5saW5lIENTUyBtb2R1bGVzXG4gICAgbGlua1BhdHRlcm5zOiBbXSBhcyBSZWdFeHBbXSwgLy8gQWx3YXlzIGxpbmsgbm9kZV9tb2R1bGVzIENTU1xuICB9LFxuXG4gIEFVVE9fRElTQ09WRVI6IHtcbiAgICBjbGllbnRFbnRyeTogXCIqKi8qLmNsaWVudC4qXCIsXG4gICAgc2VydmVyRW50cnk6IFwiKiovKi5zZXJ2ZXIuKlwiLFxuICAgIGNzc0VudHJ5OiBcIioqLyouY3NzXCIsXG4gICAganNvbkVudHJ5OiBcIioqLyouanNvblwiLFxuICAgIGh0bWxFbnRyeTogXCIqKi8qLmh0bWxcIixcbiAgICAvLyBQYXR0ZXJuIG1hdGNoZXJzXG4gICAgbW9kdWxlUGF0dGVybjogbmV3IFJlZ0V4cChCQVNFX1BBVFRFUk5TLk1PRFVMRSksXG4gICAgc2VydmVyUGF0dGVybjogbmV3IFJlZ0V4cChCQVNFX1BBVFRFUk5TLlNFUlZFUiksXG4gICAgY2xpZW50UGF0dGVybjogbmV3IFJlZ0V4cChCQVNFX1BBVFRFUk5TLkNMSUVOVCksXG4gICAgcGFnZVBhdHRlcm46IG5ldyBSZWdFeHAoQkFTRV9QQVRURVJOUy5QQUdFKSxcbiAgICBwcm9wc1BhdHRlcm46IG5ldyBSZWdFeHAoQkFTRV9QQVRURVJOUy5QUk9QUyksXG5cbiAgICAvLyBGaWxlIHBhdHRlcm5zXG4gICAgY3NzUGF0dGVybjogbmV3IFJlZ0V4cChgXFxcXCR7QkFTRV9QQVRURVJOUy5FWFQuQ1NTfSRgKSxcbiAgICBqc29uUGF0dGVybjogbmV3IFJlZ0V4cChgXFxcXCR7QkFTRV9QQVRURVJOUy5FWFQuSlNPTn0kYCksXG4gICAgaHRtbFBhdHRlcm46IG5ldyBSZWdFeHAoYFxcXFwke0JBU0VfUEFUVEVSTlMuRVhULkhUTUx9JGApLFxuICAgIHJzY1BhdHRlcm46IG5ldyBSZWdFeHAoYFxcXFwke0JBU0VfUEFUVEVSTlMuRVhULlJTQ30kYCksXG4gICAgbm9kZU9ubHk6IG5ldyBSZWdFeHAoYFxcXFwke0JBU0VfUEFUVEVSTlMuRVhULk5PREV9JGApLFxuICAgIGNzc01vZHVsZVBhdHRlcm46IG5ldyBSZWdFeHAoXG4gICAgICBgXFxcXCR7QkFTRV9QQVRURVJOUy5FWFQuQ1NTfVxcXFwke0JBU0VfUEFUVEVSTlMuRVhULkpTfSRgXG4gICAgKSxcbiAgICB2ZW5kb3JQYXR0ZXJuOiAvXlxcL25vZGVfbW9kdWxlc1xcLy8sXG4gICAgdmlydHVhbFBhdHRlcm46IC9eXFwvQFxcLy8sXG4gICAgZG90RmlsZXM6IG5ldyBSZWdFeHAoYCR7QkFTRV9QQVRURVJOUy5ET1RfRklMRVN9YCksXG4gIH0sXG4gIE1PRFVMRV9JRDogKGlkOiBzdHJpbmcpID0+IGlkLFxuICBWRVJCT1NFOiBmYWxzZSxcbiAgUEFOSUNfVEhSRVNIT0xEOiAoTU9ERSA9PT0gXCJkZXZlbG9wbWVudFwiXG4gICAgPyBcImNyaXRpY2FsX2Vycm9yc1wiXG4gICAgOiBcImFsbF9lcnJvcnNcIikgYXMgXCJjcml0aWNhbF9lcnJvcnNcIiB8IFwiYWxsX2Vycm9yc1wiLFxuICAvLyBDZW50cmFsaXplZCBsb2FkZXIgY29uZmlnIGZvciBSU0MgYm91bmRhcmllc1xuICBSU0NfTE9BREVSOiB7XG4gICAgZGV2ZWxvcG1lbnQ6IHtcbiAgICAgIC4uLkRFRkFVTFRfTE9BREVSX0NPTkZJRyxcbiAgICAgIG1vZGU6IFwiZGV2ZWxvcG1lbnRcIiBhcyBjb25zdCxcbiAgICB9LFxuICAgIHRlc3Q6IHtcbiAgICAgIC4uLkRFRkFVTFRfTE9BREVSX0NPTkZJRyxcbiAgICAgIGltcG9ydFNlcnZlclBhdGg6IFwicmVhY3Qtc2VydmVyLWRvbS1lc20vc2VydmVyLm5vZGVcIixcbiAgICAgIGltcG9ydENsaWVudFBhdGg6IFwicmVhY3Qtc2VydmVyLWRvbS1lc20vc2VydmVyLm5vZGVcIixcbiAgICAgIG1vZGU6IFwidGVzdFwiIGFzIGNvbnN0LFxuICAgIH0sXG4gICAgcHJvZHVjdGlvbjoge1xuICAgICAgLi4uREVGQVVMVF9MT0FERVJfQ09ORklHLFxuICAgICAgbW9kZTogXCJwcm9kdWN0aW9uXCIgYXMgY29uc3QsXG4gICAgfSxcbiAgfSxcbiAgUkVBQ1RfTE9BREVSX1BBVEg6IHBsdWdpblJvb3QgKyBcIi9sb2FkZXIvcmVhY3QtbG9hZGVyLmpzXCIsXG4gIENTU19MT0FERVJfUEFUSDogcGx1Z2luUm9vdCArIFwiL2xvYWRlci9jc3MtbG9hZGVyLmpzXCIsXG4gIEVOVl9MT0FERVJfUEFUSDogcGx1Z2luUm9vdCArIFwiL2xvYWRlci9lbnYtbG9hZGVyLmpzXCIsXG4gIFxufTtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQVFBLE1BQU0sU0FBUyxZQUFhLEVBQUE7QUFFNUIsTUFBTSxrQkFBcUIsR0FBQTtBQUFBO0FBQUEsRUFFekIsTUFBUSxFQUFBLGdEQUFBO0FBQUE7QUFBQSxFQUVSLE1BQVEsRUFBQSw0Q0FBQTtBQUFBO0FBQUEsRUFFUixHQUFLLEVBQUE7QUFDUCxDQUFBO0FBRUEsTUFBTSxrQkFBcUIsR0FBQSx3QkFBQTtBQUMzQixNQUFNLHFCQUF3QixHQUFBLENBQUMsSUFBYyxFQUFBLFFBQUEsS0FDM0MsS0FBSyxLQUFNLENBQUEsa0JBQWtCLENBQUssSUFBQSxJQUFBLElBQ2pDLFlBQVksa0JBQW1CLENBQUEsSUFBQSxDQUFLLFFBQVMsQ0FBQSxXQUFBLEVBQWEsQ0FDM0QsSUFBQSxLQUFBO0FBVUYsTUFBTSx3QkFBQSxHQUEyQixDQUFDLElBQWMsRUFBQSxRQUFBLEtBQzlDLG1CQUFtQixFQUFFLE1BQUEsRUFBUSxJQUFNLEVBQUEsUUFBQSxFQUFVLENBQUE7QUFFL0MsTUFBTSw4QkFBOEIsQ0FBQyxJQUFBLEtBQ25DLG1CQUFtQixFQUFFLE1BQUEsRUFBUSxNQUFNLENBQUE7QUFFckMsTUFBTSw4QkFBOEIsQ0FDbEMsUUFBQSxFQUNBLHlCQUNHLGtCQUFtQixDQUFBLEVBQUUsVUFBVSxDQUFBO0FBRTdCLE1BQU0saUJBQW9CLEdBQUE7QUFBQSxFQUMvQixNQUFRLEVBQUE7QUFBQSxJQUNOLGFBQWUsRUFBQSxLQUFBO0FBQUEsSUFDZixNQUFRLEVBQUEsUUFBQTtBQUFBLElBQ1IsUUFBQSxFQUFVLENBQUMsTUFLTCxLQUFBO0FBRUosTUFBQSxPQUFPLE9BQU8sS0FBVSxLQUFBLENBQUE7QUFBQSxLQUMxQjtBQUFBLElBQ0EsT0FBUyxFQUFBO0FBQUEsR0FDWDtBQUFBLEVBQ0EsTUFBUSxFQUFBO0FBQUEsSUFD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