vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
294 lines (291 loc) • 38.9 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { getRouteFiles } from '../helpers/getRouteFiles.js';
import { routeToURL } from '../utils/routeToURL.js';
import { resolveAutoDiscover } from './autoDiscover/resolveAutoDiscover.js';
import { createWorker } from '../worker/createWorker.js';
import { serializedOptions, serializeResolvedConfig } from '../helpers/serializeUserOptions.js';
import { getEnvironmentId, getStashedUserOptions, getStashedHandlerOptions, stashHandlerOptions } from './stashedOptionsState.js';
import { getNodeEnv } from './getNodeEnv.js';
import { createLogger } from 'vite';
import { DEFAULT_CONFIG } from './defaults.js';
import { getCondition } from './getCondition.js';
function createDefaultOptions() {
return {
pageExportName: DEFAULT_CONFIG.PAGE_EXPORT_NAME,
propsExportName: DEFAULT_CONFIG.PROPS_EXPORT_NAME,
rootExportName: DEFAULT_CONFIG.ROOT_EXPORT_NAME,
htmlExportName: DEFAULT_CONFIG.HTML_EXPORT_NAME,
cssFiles: /* @__PURE__ */ new Map(),
globalCss: /* @__PURE__ */ new Map(),
manifest: {},
css: DEFAULT_CONFIG.CSS
};
}
async function resolveAutoDiscoveredFiles(options, stashedOptions, logger) {
if (options.autoDiscoveredFiles) {
return options.autoDiscoveredFiles;
}
const result = await resolveAutoDiscover({
config: options.config || {},
configEnv: options.configEnv || { mode: "production", command: "build" },
userOptions: stashedOptions,
logger
});
if (result.type === "error") {
throw result.error || new Error("Failed to resolve autoDiscover");
}
return result.autoDiscoveredFiles;
}
async function createHandlerOptions(route, options = {}) {
const {
mode = getNodeEnv(),
logger = createLogger(),
configEnv = { mode: mode || "production", command: "build" },
children,
id = `${route}-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
condition = getCondition(),
envId = getEnvironmentId(condition, mode),
userOptions = getStashedUserOptions(envId),
config = void 0
} = options;
const cachedOptions = getStashedHandlerOptions(id);
if (cachedOptions) {
return cachedOptions;
}
if (!userOptions) {
throw new Error(
`No stashed userOptions found for environment: ${envId}. Make sure resolveOptions() has been called first.`
);
}
const defaults = { ...createDefaultOptions(), ...options.defaults };
const autoDiscoveredFiles = await resolveAutoDiscoveredFiles(
options,
userOptions,
logger
);
const url = routeToURL(
route,
userOptions.moduleBaseURL,
userOptions.build.rscOutputPath
);
const routeFilesResult = await getRouteFiles(
route,
autoDiscoveredFiles,
userOptions,
logger
);
if (routeFilesResult.type === "error") {
throw routeFilesResult.error || new Error("Failed to get route files");
}
let rscWorker = void 0;
let htmlWorker = void 0;
const isServeMode = configEnv?.command === "serve" || configEnv?.mode === "development" || mode === "development";
const isBuildMode = configEnv?.command === "build";
const shouldCreateRscWorker = userOptions.dev?.useRscWorker && isServeMode || userOptions.build?.useRscWorker && isBuildMode;
if (shouldCreateRscWorker) {
if (userOptions.verbose) {
logger.info(
`[createHandlerOptions.client] Creating RSC worker for route: ${route}`
);
}
try {
const serializedUserOptions = userOptions ? serializedOptions(userOptions, autoDiscoveredFiles) : void 0;
const serializedResolvedConfig = config ? serializeResolvedConfig(config) : void 0;
const workerResult = await createWorker({
currentCondition: "react-client",
workerPath: userOptions.rscWorkerPath,
verbose: userOptions.verbose,
logger,
workerData: {
id: route,
userOptions: serializedUserOptions,
resolvedConfig: serializedResolvedConfig,
configEnv
}
});
if (workerResult.type === "error") {
logger.warn(
`[createHandlerOptions.client] Failed to create RSC worker: ${workerResult.error?.message}`
);
rscWorker = void 0;
} else if (workerResult.type === "skip") {
logger.warn(
`[createHandlerOptions.client] RSC worker creation skipped: ${workerResult.reason}`
);
rscWorker = void 0;
} else {
rscWorker = workerResult.worker;
if (userOptions.verbose) {
logger.info(
`[createHandlerOptions.client] RSC worker created successfully`
);
}
}
} catch (error) {
logger.warn(
`[createHandlerOptions.client] RSC worker creation failed: ${error instanceof Error ? error.message : String(error)}`
);
rscWorker = void 0;
}
}
const shouldCreateHtmlWorker = userOptions.dev?.useHtmlWorker && isServeMode || userOptions.build?.useHtmlWorker && isBuildMode;
if (shouldCreateHtmlWorker) {
if (userOptions.verbose) {
logger.info(
`[createHandlerOptions.client] Creating HTML worker for route: ${route}`
);
}
try {
const fallbackDefaults = {
verbose: false,
panicThreshold: 1e3,
moduleRootPath: "",
moduleBaseURL: "",
moduleBasePath: "",
projectRoot: process.cwd(),
htmlTimeout: 3e4,
serverPipeableStreamOptions: {},
clientPipeableStreamOptions: {},
build: {
useHtmlWorker: isBuildMode,
useRscWorker: isBuildMode,
pages: []
},
dev: {
useHtmlWorker: false,
useRscWorker: true
}
};
const serializedUserOptions = userOptions ? serializedOptions(userOptions, autoDiscoveredFiles) : serializedOptions(fallbackDefaults, autoDiscoveredFiles);
const serializedResolvedConfig = config ? serializeResolvedConfig(config) : {
mode: configEnv?.mode || mode || "development",
root: process.cwd(),
logLevel: "info",
env: {},
envPrefix: "VITE_",
base: "/",
publicDir: "public",
cacheDir: "node_modules/.vite",
command: configEnv?.command || "serve",
isSsrBuild: configEnv?.command === "build",
isPreview: false
};
const htmlWorkerResult = await createWorker({
currentCondition: "react-client",
// We are in a .client file
reverseCondition: "react-client",
// The user still requested a worker, which uses the same condition
workerPath: userOptions.htmlWorkerPath,
verbose: userOptions.verbose,
logger,
workerData: {
id: route,
userOptions: serializedUserOptions,
resolvedConfig: serializedResolvedConfig,
configEnv
}
});
if (htmlWorkerResult.type === "error") {
logger.warn(
`[createHandlerOptions.client] Failed to create HTML worker: ${htmlWorkerResult.error?.message}`
);
htmlWorker = void 0;
} else if (htmlWorkerResult.type === "skip") {
logger.warn(
`[createHandlerOptions.client] HTML worker creation skipped: ${htmlWorkerResult.reason}`
);
htmlWorker = void 0;
} else {
htmlWorker = htmlWorkerResult.worker;
if (userOptions.verbose) {
logger.info(
`[createHandlerOptions.client] HTML worker created successfully`
);
}
}
} catch (error) {
logger.warn(
`[createHandlerOptions.client] HTML worker creation failed: ${error instanceof Error ? error.message : String(error)}`
);
htmlWorker = void 0;
}
}
const handlerOptions = {
...userOptions,
// File paths - these are passed directly to the worker for component resolution
// The worker handles the distinction between undefined vs "" for Root and Html:
// - undefined = use built-in default component
// - "" = explicitly disable (headless mode for Html, React.Fragment for Root)
// - string path = resolve custom component from specified path
// This approach maintains consistency between server and client paradigms
pagePath: routeFilesResult.page,
propsPath: routeFilesResult.props,
rootPath: routeFilesResult.root,
htmlPath: routeFilesResult.html,
// Export names
pageExportName: userOptions.pageExportName,
propsExportName: userOptions.propsExportName,
rootExportName: userOptions.rootExportName,
htmlExportName: userOptions.htmlExportName,
// Route and loader
route,
loader: defaults.loader || (() => Promise.resolve({})),
// Configuration
panicThreshold: userOptions.panicThreshold,
verbose: userOptions.verbose,
moduleBaseURL: userOptions.moduleBaseURL,
build: userOptions.build,
dev: {
useHtmlWorker: userOptions.dev.useHtmlWorker,
useRscWorker: userOptions.dev.useRscWorker
},
logger,
// Required properties
normalizer: userOptions.normalizer,
onEvent: userOptions.onEvent,
onMetrics: userOptions.onMetrics,
autoDiscover: userOptions.autoDiscover,
css: userOptions.css,
projectRoot: userOptions.projectRoot,
moduleBase: userOptions.moduleBase,
moduleBasePath: userOptions.moduleBasePath,
moduleRootPath: userOptions.moduleRootPath,
moduleID: userOptions.moduleID,
url,
manifest: defaults.manifest,
cssFiles: defaults.cssFiles,
globalCss: defaults.globalCss,
// Timeouts and paths
rscTimeout: userOptions.rscTimeout,
htmlTimeout: userOptions.htmlTimeout,
fileWriteTimeout: userOptions.fileWriteTimeout,
workerShutdownTimeout: userOptions.workerShutdownTimeout,
rscWorkerPath: userOptions.rscWorkerPath,
htmlWorkerPath: userOptions.htmlWorkerPath,
publicOrigin: userOptions.publicOrigin,
// Stream options
serverPipeableStreamOptions: userOptions.serverPipeableStreamOptions,
clientPipeableStreamOptions: userOptions.clientPipeableStreamOptions,
// Client-specific
id,
// Client needs component placeholders since it can't load server modules directly
HtmlComponent: void 0,
PageComponent: void 0,
RootComponent: void 0,
// Workers for client environment - provide both for specific use cases
worker: condition === "react-server" ? rscWorker : htmlWorker,
// Backward compatibility: prefer HTML worker if available
rscWorker,
htmlWorker,
// Children provided directly via options
children
};
stashHandlerOptions(id, handlerOptions);
return handlerOptions;
}
export { createHandlerOptions };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlSGFuZGxlck9wdGlvbnMuY2xpZW50LmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW4vY29uZmlnL2NyZWF0ZUhhbmRsZXJPcHRpb25zLmNsaWVudC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IENyZWF0ZUhhbmRsZXJPcHRpb25zLCBBdXRvRGlzY292ZXJlZEZpbGVzIH0gZnJvbSBcIi4uL3R5cGVzLmpzXCI7XG5pbXBvcnQgdHlwZSB7IExvZ2dlciB9IGZyb20gXCJ2aXRlXCI7XG5pbXBvcnQgeyBnZXRSb3V0ZUZpbGVzIH0gZnJvbSBcIi4uL2hlbHBlcnMvZ2V0Um91dGVGaWxlcy5qc1wiO1xuaW1wb3J0IHsgcm91dGVUb1VSTCB9IGZyb20gXCIuLi91dGlscy9yb3V0ZVRvVVJMLmpzXCI7XG5pbXBvcnQgeyByZXNvbHZlQXV0b0Rpc2NvdmVyIH0gZnJvbSBcIi4vYXV0b0Rpc2NvdmVyL3Jlc29sdmVBdXRvRGlzY292ZXIuanNcIjtcbmltcG9ydCB7IGNyZWF0ZVdvcmtlciB9IGZyb20gXCIuLi93b3JrZXIvY3JlYXRlV29ya2VyLmpzXCI7XG5pbXBvcnQge1xuICBzZXJpYWxpemVkT3B0aW9ucyxcbiAgc2VyaWFsaXplUmVzb2x2ZWRDb25maWcsXG59IGZyb20gXCIuLi9oZWxwZXJzL3NlcmlhbGl6ZVVzZXJPcHRpb25zLmpzXCI7XG5cbmltcG9ydCB7XG4gIGdldFN0YXNoZWRVc2VyT3B0aW9ucyxcbiAgZ2V0U3Rhc2hlZEhhbmRsZXJPcHRpb25zLFxuICBzdGFzaEhhbmRsZXJPcHRpb25zLFxuICBnZXRFbnZpcm9ubWVudElkLFxufSBmcm9tIFwiLi9zdGFzaGVkT3B0aW9uc1N0YXRlLmpzXCI7XG5pbXBvcnQgeyBnZXROb2RlRW52IH0gZnJvbSBcIi4vZ2V0Tm9kZUVudi5qc1wiO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSBcInZpdGVcIjtcbmltcG9ydCB7IERFRkFVTFRfQ09ORklHIH0gZnJvbSBcIi4vZGVmYXVsdHMuanNcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ3JlYXRlSGFuZGxlck9wdGlvbnNQYXJhbXMsXG4gIFJlc29sdmVkRGVmYXVsdHMsXG59IGZyb20gXCIuL2NyZWF0ZUhhbmRsZXJPcHRpb25zLnR5cGVzLmpzXCI7XG5pbXBvcnQgeyBnZXRDb25kaXRpb24gfSBmcm9tIFwiLi9nZXRDb25kaXRpb24uanNcIjtcblxuLyoqXG4gKiBDbGllbnQtc3BlY2lmaWMgaGFuZGxlciBvcHRpb25zIGNyZWF0aW9uIGZvciBIVE1MIGdlbmVyYXRpb24uXG4gKlxuICogV0hBVCBUSElTIERPRVM6XG4gKiAtIENyZWF0ZXMgaGFuZGxlciBvcHRpb25zIG9wdGltaXplZCBmb3IgY2xpZW50LXNpZGUgcmVuZGVyaW5nXG4gKiAtIFJlc29sdmVzIGZpbGUgcGF0aHMgZm9yIHBhZ2VzLCBwcm9wcywgcm9vdCwgYW5kIEhUTUwgY29tcG9uZW50c1xuICogLSBTZXRzIHVwIGNsaWVudC1zcGVjaWZpYyBsb2FkZXJzIGFuZCBjb25maWd1cmF0aW9uXG4gKiAtIEhhbmRsZXMgY2FjaGluZyB3aXRoIHVuaXF1ZSBJRHNcbiAqIC0gUHJvdmlkZXMgY29tcG9uZW50IHBsYWNlaG9sZGVycyAoc2luY2UgY2xpZW50IGNhbid0IGxvYWQgc2VydmVyIG1vZHVsZXMpXG4gKiAtIFByb3ZpZGVzIGFsbCBuZWNlc3Nhcnkgb3B0aW9ucyBmb3IgSFRNTCBzdHJlYW0gY3JlYXRpb25cbiAqXG4gKiBXSEFUIFRISVMgRE9FU04nVCBETzpcbiAqIC0gRG9lcyBOT1QgbG9hZCBSZWFjdCBjb21wb25lbnRzICh0aGF0IGhhcHBlbnMgaW4gd29ya2VycyBvciBoYW5kbGVycylcbiAqIC0gRG9lcyBOT1QgY3JlYXRlIEhUTUwgc3RyZWFtcyAodXNlIGNyZWF0ZUhhbmRsZXIgZm9yIHRoYXQpXG4gKiAtIERvZXMgTk9UIGhhbmRsZSBzZXJ2ZXItc2lkZSByZW5kZXJpbmcgKHVzZSAuc2VydmVyLnRzIGZvciB0aGF0KVxuICogLSBEb2VzIE5PVCBtYW5hZ2UgY29tcG9uZW50IGxpZmVjeWNsZSBvciBzdGF0ZVxuICpcbiAqIFVTQUdFOlxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgaGFuZGxlck9wdGlvbnMgPSBhd2FpdCBjcmVhdGVIYW5kbGVyT3B0aW9ucyhcIi9teS1yb3V0ZVwiLCB7XG4gKiAgIGxvZ2dlcjogbXlMb2dnZXIsXG4gKiAgIGRlZmF1bHRzOiB7IGxvYWRlcjogKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHt9KSB9XG4gKiB9KTtcbiAqIGBgYFxuICovXG5cbmZ1bmN0aW9uIGNyZWF0ZURlZmF1bHRPcHRpb25zKCk6IFJlc29sdmVkRGVmYXVsdHMge1xuICByZXR1cm4ge1xuICAgIHBhZ2VFeHBvcnROYW1lOiBERUZBVUxUX0NPTkZJRy5QQUdFX0VYUE9SVF9OQU1FLFxuICAgIHByb3BzRXhwb3J0TmFtZTogREVGQVVMVF9DT05GSUcuUFJPUFNfRVhQT1JUX05BTUUsXG4gICAgcm9vdEV4cG9ydE5hbWU6IERFRkFVTFRfQ09ORklHLlJPT1RfRVhQT1JUX05BTUUsXG4gICAgaHRtbEV4cG9ydE5hbWU6IERFRkFVTFRfQ09ORklHLkhUTUxfRVhQT1JUX05BTUUsXG4gICAgY3NzRmlsZXM6IG5ldyBNYXAoKSxcbiAgICBnbG9iYWxDc3M6IG5ldyBNYXAoKSxcbiAgICBtYW5pZmVzdDoge30sXG4gICAgY3NzOiBERUZBVUxUX0NPTkZJRy5DU1MsXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVBdXRvRGlzY292ZXJlZEZpbGVzKFxuICBvcHRpb25zOiBDcmVhdGVIYW5kbGVyT3B0aW9uc1BhcmFtcyxcbiAgc3Rhc2hlZE9wdGlvbnM6IGFueSxcbiAgbG9nZ2VyOiBMb2dnZXJcbik6IFByb21pc2U8QXV0b0Rpc2NvdmVyZWRGaWxlcz4ge1xuICBpZiAob3B0aW9ucy5hdXRvRGlzY292ZXJlZEZpbGVzKSB7XG4gICAgcmV0dXJuIG9wdGlvbnMuYXV0b0Rpc2NvdmVyZWRGaWxlcztcbiAgfVxuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc29sdmVBdXRvRGlzY292ZXIoe1xuICAgIGNvbmZpZzogb3B0aW9ucy5jb25maWcgfHwge30sXG4gICAgY29uZmlnRW52OiBvcHRpb25zLmNvbmZpZ0VudiB8fCB7IG1vZGU6IFwicHJvZHVjdGlvblwiLCBjb21tYW5kOiBcImJ1aWxkXCIgfSxcbiAgICB1c2VyT3B0aW9uczogc3Rhc2hlZE9wdGlvbnMsXG4gICAgbG9nZ2VyLFxuICB9KTtcblxuICBpZiAocmVzdWx0LnR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgIHRocm93IHJlc3VsdC5lcnJvciB8fCBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gcmVzb2x2ZSBhdXRvRGlzY292ZXJcIik7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0LmF1dG9EaXNjb3ZlcmVkRmlsZXM7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVIYW5kbGVyT3B0aW9ucyhcbiAgcm91dGU6IHN0cmluZyxcbiAgb3B0aW9uczogQ3JlYXRlSGFuZGxlck9wdGlvbnNQYXJhbXMgPSB7fVxuKTogUHJvbWlzZTxDcmVhdGVIYW5kbGVyT3B0aW9ucz4ge1xuICBjb25zdCB7XG4gICAgbW9kZSA9IGdldE5vZGVFbnYoKSxcbiAgICBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoKSxcbiAgICBjb25maWdFbnYgPSB7IG1vZGU6IG1vZGUgfHwgXCJwcm9kdWN0aW9uXCIsIGNvbW1hbmQ6IFwiYnVpbGRcIiB9LFxuICAgIGNoaWxkcmVuLFxuICAgIGlkID0gYCR7cm91dGV9LSR7RGF0ZS5ub3coKX0tJHtNYXRoLnJhbmRvbSgpXG4gICAgICAudG9TdHJpbmcoMzYpXG4gICAgICAuc3Vic3RyaW5nKDIsIDExKX1gLFxuICAgIGNvbmRpdGlvbiA9IGdldENvbmRpdGlvbigpLFxuICAgIGVudklkID0gZ2V0RW52aXJvbm1lbnRJZChjb25kaXRpb24sIG1vZGUpLFxuICAgIHVzZXJPcHRpb25zID0gZ2V0U3Rhc2hlZFVzZXJPcHRpb25zKGVudklkKSxcbiAgICBjb25maWcgPSB1bmRlZmluZWQsXG4gIH0gPSBvcHRpb25zO1xuXG4gIC8vIENoZWNrIGNhY2hlIGZpcnN0XG4gIGNvbnN0IGNhY2hlZE9wdGlvbnMgPSBnZXRTdGFzaGVkSGFuZGxlck9wdGlvbnMoaWQpO1xuICBpZiAoY2FjaGVkT3B0aW9ucykge1xuICAgIHJldHVybiBjYWNoZWRPcHRpb25zO1xuICB9XG5cbiAgaWYgKCF1c2VyT3B0aW9ucykge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBObyBzdGFzaGVkIHVzZXJPcHRpb25zIGZvdW5kIGZvciBlbnZpcm9ubWVudDogJHtlbnZJZH0uIE1ha2Ugc3VyZSByZXNvbHZlT3B0aW9ucygpIGhhcyBiZWVuIGNhbGxlZCBmaXJzdC5gXG4gICAgKTtcbiAgfVxuXG4gIC8vIFJlc29sdmUgZGVmYXVsdHNcbiAgY29uc3QgZGVmYXVsdHMgPSB7IC4uLmNyZWF0ZURlZmF1bHRPcHRpb25zKCksIC4uLm9wdGlvbnMuZGVmYXVsdHMgfTtcblxuICAvLyBSZXNvbHZlIGF1dG8tZGlzY292ZXJlZCBmaWxlc1xuICBjb25zdCBhdXRvRGlzY292ZXJlZEZpbGVzID0gYXdhaXQgcmVzb2x2ZUF1dG9EaXNjb3ZlcmVkRmlsZXMoXG4gICAgb3B0aW9ucyxcbiAgICB1c2VyT3B0aW9ucyxcbiAgICBsb2dnZXJcbiAgKTtcblxuICAvLyBDcmVhdGUgVVJMXG4gIGNvbnN0IHVybCA9IHJvdXRlVG9VUkwoXG4gICAgcm91dGUsXG4gICAgdXNlck9wdGlvbnMubW9kdWxlQmFzZVVSTCxcbiAgICB1c2VyT3B0aW9ucy5idWlsZC5yc2NPdXRwdXRQYXRoXG4gICk7XG5cbiAgLy8gR2V0IHJvdXRlIGZpbGVzXG4gIGNvbnN0IHJvdXRlRmlsZXNSZXN1bHQgPSBhd2FpdCBnZXRSb3V0ZUZpbGVzKFxuICAgIHJvdXRlLFxuICAgIGF1dG9EaXNjb3ZlcmVkRmlsZXMsXG4gICAgdXNlck9wdGlvbnMsXG4gICAgbG9nZ2VyXG4gICk7XG5cbiAgaWYgKHJvdXRlRmlsZXNSZXN1bHQudHlwZSA9PT0gXCJlcnJvclwiKSB7XG4gICAgdGhyb3cgcm91dGVGaWxlc1Jlc3VsdC5lcnJvciB8fCBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gZ2V0IHJvdXRlIGZpbGVzXCIpO1xuICB9XG5cbiAgLy8gQ3JlYXRlIHdvcmtlcnMgZm9yIGNsaWVudCBlbnZpcm9ubWVudCBiYXNlZCBvbiBjb25maWd1cmF0aW9uIGFuZCBjb25maWdFbnZcbiAgbGV0IHJzY1dvcmtlcjogYW55ID0gdW5kZWZpbmVkO1xuICBsZXQgaHRtbFdvcmtlcjogYW55ID0gdW5kZWZpbmVkO1xuXG4gIC8vIERldGVybWluZSBpZiB3ZSBuZWVkIHdvcmtlcnMgYmFzZWQgb24gY29uZmlnRW52IGFuZCBkZXYgY29uZmlnXG4gIGNvbnN0IGlzU2VydmVNb2RlID1cbiAgICBjb25maWdFbnY/LmNvbW1hbmQgPT09IFwic2VydmVcIiB8fFxuICAgIGNvbmZpZ0Vudj8ubW9kZSA9PT0gXCJkZXZlbG9wbWVudFwiIHx8XG4gICAgbW9kZSA9PT0gXCJkZXZlbG9wbWVudFwiO1xuICBjb25zdCBpc0J1aWxkTW9kZSA9IGNvbmZpZ0Vudj8uY29tbWFuZCA9PT0gXCJidWlsZFwiO1xuXG4gIC8vIENyZWF0ZSBSU0Mgd29ya2VyIGlmOlxuICAvLyAxLiB1c2VSc2NXb3JrZXIgaXMgZW5hYmxlZCBpbiBkZXYgY29uZmlnIEFORCB3ZSdyZSBpbiBzZXJ2ZSBtb2RlLCBPUlxuICAvLyAyLiB1c2VSc2NXb3JrZXIgaXMgZW5hYmxlZCBpbiBidWlsZCBjb25maWcgQU5EIHdlJ3JlIGluIGJ1aWxkIG1vZGVcbiAgY29uc3Qgc2hvdWxkQ3JlYXRlUnNjV29ya2VyID1cbiAgICAodXNlck9wdGlvbnMuZGV2Py51c2VSc2NXb3JrZXIgJiYgaXNTZXJ2ZU1vZGUpIHx8XG4gICAgKHVzZXJPcHRpb25zLmJ1aWxkPy51c2VSc2NXb3JrZXIgJiYgaXNCdWlsZE1vZGUpO1xuXG4gIGlmIChzaG91bGRDcmVhdGVSc2NXb3JrZXIpIHtcbiAgICBpZiAodXNlck9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgIGBbY3JlYXRlSGFuZGxlck9wdGlvbnMuY2xpZW50XSBDcmVhdGluZyBSU0Mgd29ya2VyIGZvciByb3V0ZTogJHtyb3V0ZX1gXG4gICAgICApO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBzZXJpYWxpemVkVXNlck9wdGlvbnMgPSB1c2VyT3B0aW9uc1xuICAgICAgICA/IHNlcmlhbGl6ZWRPcHRpb25zKHVzZXJPcHRpb25zLCBhdXRvRGlzY292ZXJlZEZpbGVzKVxuICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgY29uc3Qgc2VyaWFsaXplZFJlc29sdmVkQ29uZmlnID0gY29uZmlnXG4gICAgICAgID8gc2VyaWFsaXplUmVzb2x2ZWRDb25maWcoY29uZmlnKVxuICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgY29uc3Qgd29ya2VyUmVzdWx0ID0gYXdhaXQgY3JlYXRlV29ya2VyKHtcbiAgICAgICAgY3VycmVudENvbmRpdGlvbjogXCJyZWFjdC1jbGllbnRcIixcbiAgICAgICAgd29ya2VyUGF0aDogdXNlck9wdGlvbnMucnNjV29ya2VyUGF0aCxcbiAgICAgICAgdmVyYm9zZTogdXNlck9wdGlvbnMudmVyYm9zZSxcbiAgICAgICAgbG9nZ2VyLFxuICAgICAgICB3b3JrZXJEYXRhOiB7XG4gICAgICAgICAgaWQ6IHJvdXRlLFxuICAgICAgICAgIHVzZXJPcHRpb25zOiBzZXJpYWxpemVkVXNlck9wdGlvbnMsXG4gICAgICAgICAgcmVzb2x2ZWRDb25maWc6IHNlcmlhbGl6ZWRSZXNvbHZlZENvbmZpZyxcbiAgICAgICAgICBjb25maWdFbnYsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgaWYgKHdvcmtlclJlc3VsdC50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5jbGllbnRdIEZhaWxlZCB0byBjcmVhdGUgUlNDIHdvcmtlcjogJHt3b3JrZXJSZXN1bHQuZXJyb3I/Lm1lc3NhZ2V9YFxuICAgICAgICApO1xuICAgICAgICByc2NXb3JrZXIgPSB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2UgaWYgKHdvcmtlclJlc3VsdC50eXBlID09PSBcInNraXBcIikge1xuICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICBgW2NyZWF0ZUhhbmRsZXJPcHRpb25zLmNsaWVudF0gUlNDIHdvcmtlciBjcmVhdGlvbiBza2lwcGVkOiAke3dvcmtlclJlc3VsdC5yZWFzb259YFxuICAgICAgICApO1xuICAgICAgICByc2NXb3JrZXIgPSB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByc2NXb3JrZXIgPSB3b3JrZXJSZXN1bHQud29ya2VyO1xuICAgICAgICBpZiAodXNlck9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5jbGllbnRdIFJTQyB3b3JrZXIgY3JlYXRlZCBzdWNjZXNzZnVsbHlgXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihcbiAgICAgICAgYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5jbGllbnRdIFJTQyB3b3JrZXIgY3JlYXRpb24gZmFpbGVkOiAke1xuICAgICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKVxuICAgICAgICB9YFxuICAgICAgKTtcbiAgICAgIHJzY1dvcmtlciA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvLyBDcmVhdGUgSFRNTCB3b3JrZXIgaWY6XG4gIC8vIDEuIHVzZUh0bWxXb3JrZXIgaXMgZW5hYmxlZCBpbiBkZXYgY29uZmlnIEFORCB3ZSdyZSBpbiBzZXJ2ZSBtb2RlLCBPUlxuICAvLyAyLiB1c2VIdG1sV29ya2VyIGlzIGVuYWJsZWQgaW4gYnVpbGQgY29uZmlnIEFORCB3ZSdyZSBpbiBidWlsZCBtb2RlXG4gIGNvbnN0IHNob3VsZENyZWF0ZUh0bWxXb3JrZXIgPVxuICAgICh1c2VyT3B0aW9ucy5kZXY/LnVzZUh0bWxXb3JrZXIgJiYgaXNTZXJ2ZU1vZGUpIHx8XG4gICAgKHVzZXJPcHRpb25zLmJ1aWxkPy51c2VIdG1sV29ya2VyICYmIGlzQnVpbGRNb2RlKTtcblxuICBpZiAoc2hvdWxkQ3JlYXRlSHRtbFdvcmtlcikge1xuICAgIGlmICh1c2VyT3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5jbGllbnRdIENyZWF0aW5nIEhUTUwgd29ya2VyIGZvciByb3V0ZTogJHtyb3V0ZX1gXG4gICAgICApO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBDcmVhdGUgZmFsbGJhY2sgZGVmYXVsdHMgYmFzZWQgb24gY29uZmlnRW52XG4gICAgICBjb25zdCBmYWxsYmFja0RlZmF1bHRzID0ge1xuICAgICAgICB2ZXJib3NlOiBmYWxzZSxcbiAgICAgICAgcGFuaWNUaHJlc2hvbGQ6IDEwMDAsXG4gICAgICAgIG1vZHVsZVJvb3RQYXRoOiBcIlwiLFxuICAgICAgICBtb2R1bGVCYXNlVVJMOiBcIlwiLFxuICAgICAgICBtb2R1bGVCYXNlUGF0aDogXCJcIixcbiAgICAgICAgcHJvamVjdFJvb3Q6IHByb2Nlc3MuY3dkKCksXG4gICAgICAgIGh0bWxUaW1lb3V0OiAzMDAwMCxcbiAgICAgICAgc2VydmVyUGlwZWFibGVTdHJlYW1PcHRpb25zOiB7fSxcbiAgICAgICAgY2xpZW50UGlwZWFibGVTdHJlYW1PcHRpb25zOiB7fSxcbiAgICAgICAgYnVpbGQ6IHtcbiAgICAgICAgICB1c2VIdG1sV29ya2VyOiBpc0J1aWxkTW9kZSxcbiAgICAgICAgICB1c2VSc2NXb3JrZXI6IGlzQnVpbGRNb2RlLFxuICAgICAgICAgIHBhZ2VzOiBbXSxcbiAgICAgICAgfSxcbiAgICAgICAgZGV2OiB7XG4gICAgICAgICAgdXNlSHRtbFdvcmtlcjogZmFsc2UsXG4gICAgICAgICAgdXNlUnNjV29ya2VyOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2VyaWFsaXplZFVzZXJPcHRpb25zID0gdXNlck9wdGlvbnNcbiAgICAgICAgPyBzZXJpYWxpemVkT3B0aW9ucyh1c2VyT3B0aW9ucywgYXV0b0Rpc2NvdmVyZWRGaWxlcylcbiAgICAgICAgOiBzZXJpYWxpemVkT3B0aW9ucyhmYWxsYmFja0RlZmF1bHRzIGFzIGFueSwgYXV0b0Rpc2NvdmVyZWRGaWxlcyk7XG5cbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRSZXNvbHZlZENvbmZpZyA9IGNvbmZpZ1xuICAgICAgICA/IHNlcmlhbGl6ZVJlc29sdmVkQ29uZmlnKGNvbmZpZylcbiAgICAgICAgOiB7XG4gICAgICAgICAgICBtb2RlOiBjb25maWdFbnY/Lm1vZGUgfHwgbW9kZSB8fCBcImRldmVsb3BtZW50XCIsXG4gICAgICAgICAgICByb290OiBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICAgICAgbG9nTGV2ZWw6IFwiaW5mb1wiLFxuICAgICAgICAgICAgZW52OiB7fSxcbiAgICAgICAgICAgIGVudlByZWZpeDogXCJWSVRFX1wiLFxuICAgICAgICAgICAgYmFzZTogXCIvXCIsXG4gICAgICAgICAgICBwdWJsaWNEaXI6IFwicHVibGljXCIsXG4gICAgICAgICAgICBjYWNoZURpcjogXCJub2RlX21vZHVsZXMvLnZpdGVcIixcbiAgICAgICAgICAgIGNvbW1hbmQ6IGNvbmZpZ0Vudj8uY29tbWFuZCB8fCBcInNlcnZlXCIsXG4gICAgICAgICAgICBpc1NzckJ1aWxkOiBjb25maWdFbnY/LmNvbW1hbmQgPT09IFwiYnVpbGRcIixcbiAgICAgICAgICAgIGlzUHJldmlldzogZmFsc2UsXG4gICAgICAgICAgfTtcblxuICAgICAgY29uc3QgaHRtbFdvcmtlclJlc3VsdCA9IGF3YWl0IGNyZWF0ZVdvcmtlcih7XG4gICAgICAgIGN1cnJlbnRDb25kaXRpb246IFwicmVhY3QtY2xpZW50XCIsIC8vIFdlIGFyZSBpbiBhIC5jbGllbnQgZmlsZVxuICAgICAgICByZXZlcnNlQ29uZGl0aW9uOiBcInJlYWN0LWNsaWVudFwiLCAvLyBUaGUgdXNlciBzdGlsbCByZXF1ZXN0ZWQgYSB3b3JrZXIsIHdoaWNoIHVzZXMgdGhlIHNhbWUgY29uZGl0aW9uXG4gICAgICAgIHdvcmtlclBhdGg6IHVzZXJPcHRpb25zLmh0bWxXb3JrZXJQYXRoLFxuICAgICAgICB2ZXJib3NlOiB1c2VyT3B0aW9ucy52ZXJib3NlLFxuICAgICAgICBsb2dnZXIsXG4gICAgICAgIHdvcmtlckRhdGE6IHtcbiAgICAgICAgICBpZDogcm91dGUsXG4gICAgICAgICAgdXNlck9wdGlvbnM6IHNlcmlhbGl6ZWRVc2VyT3B0aW9ucyxcbiAgICAgICAgICByZXNvbHZlZENvbmZpZzogc2VyaWFsaXplZFJlc29sdmVkQ29uZmlnLFxuICAgICAgICAgIGNvbmZpZ0VudixcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaHRtbFdvcmtlclJlc3VsdC50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5jbGllbnRdIEZhaWxlZCB0byBjcmVhdGUgSFRNTCB3b3JrZXI6ICR7aHRtbFdvcmtlclJlc3VsdC5lcnJvcj8ubWVzc2FnZX1gXG4gICAgICAgICk7XG4gICAgICAgIGh0bWxXb3JrZXIgPSB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2UgaWYgKGh0bWxXb3JrZXJSZXN1bHQudHlwZSA9PT0gXCJza2lwXCIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5jbGllbnRdIEhUTUwgd29ya2VyIGNyZWF0aW9uIHNraXBwZWQ6ICR7aHRtbFdvcmtlclJlc3VsdC5yZWFzb259YFxuICAgICAgICApO1xuICAgICAgICBodG1sV29ya2VyID0gdW5kZWZpbmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaHRtbFdvcmtlciA9IGh0bWxXb3JrZXJSZXN1bHQud29ya2VyO1xuICAgICAgICBpZiAodXNlck9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5jbGllbnRdIEhUTUwgd29ya2VyIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgIGBbY3JlYXRlSGFuZGxlck9wdGlvbnMuY2xpZW50XSBIVE1MIHdvcmtlciBjcmVhdGlvbiBmYWlsZWQ6ICR7XG4gICAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgICAgIH1gXG4gICAgICApO1xuICAgICAgaHRtbFdvcmtlciA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvLyBDcmVhdGUgY2xpZW50LXNwZWNpZmljIGhhbmRsZXIgb3B0aW9uc1xuICBjb25zdCBoYW5kbGVyT3B0aW9uczogQ3JlYXRlSGFuZGxlck9wdGlvbnMgPSB7XG4gICAgLi4udXNlck9wdGlvbnMsXG4gICAgLy8gRmlsZSBwYXRocyAtIHRoZXNlIGFyZSBwYXNzZWQgZGlyZWN0bHkgdG8gdGhlIHdvcmtlciBmb3IgY29tcG9uZW50IHJlc29sdXRpb25cbiAgICAvLyBUaGUgd29ya2VyIGhhbmRsZXMgdGhlIGRpc3RpbmN0aW9uIGJldHdlZW4gdW5kZWZpbmVkIHZzIFwiXCIgZm9yIFJvb3QgYW5kIEh0bWw6XG4gICAgLy8gLSB1bmRlZmluZWQgPSB1c2UgYnVpbHQtaW4gZGVmYXVsdCBjb21wb25lbnRcbiAgICAvLyAtIFwiXCIgPSBleHBsaWNpdGx5IGRpc2FibGUgKGhlYWRsZXNzIG1vZGUgZm9yIEh0bWwsIFJlYWN0LkZyYWdtZW50IGZvciBSb290KVxuICAgIC8vIC0gc3RyaW5nIHBhdGggPSByZXNvbHZlIGN1c3RvbSBjb21wb25lbnQgZnJvbSBzcGVjaWZpZWQgcGF0aFxuICAgIC8vIFRoaXMgYXBwcm9hY2ggbWFpbnRhaW5zIGNvbnNpc3RlbmN5IGJldHdlZW4gc2VydmVyIGFuZCBjbGllbnQgcGFyYWRpZ21zXG4gICAgcGFnZVBhdGg6IHJvdXRlRmlsZXNSZXN1bHQucGFnZSxcbiAgICBwcm9wc1BhdGg6IHJvdXRlRmlsZXNSZXN1bHQucHJvcHMsXG4gICAgcm9vdFBhdGg6IHJvdXRlRmlsZXNSZXN1bHQucm9vdCxcbiAgICBodG1sUGF0aDogcm91dGVGaWxlc1Jlc3VsdC5odG1sLFxuXG4gICAgLy8gRXhwb3J0IG5hbWVzXG4gICAgcGFnZUV4cG9ydE5hbWU6IHVzZXJPcHRpb25zLnBhZ2VFeHBvcnROYW1lLFxuICAgIHByb3BzRXhwb3J0TmFtZTogdXNlck9wdGlvbnMucHJvcHNFeHBvcnROYW1lLFxuICAgIHJvb3RFeHBvcnROYW1lOiB1c2VyT3B0aW9ucy5yb290RXhwb3J0TmFtZSxcbiAgICBodG1sRXhwb3J0TmFtZTogdXNlck9wdGlvbnMuaHRtbEV4cG9ydE5hbWUsXG5cbiAgICAvLyBSb3V0ZSBhbmQgbG9hZGVyXG4gICAgcm91dGUsXG4gICAgbG9hZGVyOiBkZWZhdWx0cy5sb2FkZXIgfHwgKCgpID0+IFByb21pc2UucmVzb2x2ZSh7fSkpLFxuXG4gICAgLy8gQ29uZmlndXJhdGlvblxuICAgIHBhbmljVGhyZXNob2xkOiB1c2VyT3B0aW9ucy5wYW5pY1RocmVzaG9sZCxcbiAgICB2ZXJib3NlOiB1c2VyT3B0aW9ucy52ZXJib3NlLFxuICAgIG1vZHVsZUJhc2VVUkw6IHVzZXJPcHRpb25zLm1vZHVsZUJhc2VVUkwsXG4gICAgYnVpbGQ6IHVzZXJPcHRpb25zLmJ1aWxkLFxuICAgIGRldjoge1xuICAgICAgdXNlSHRtbFdvcmtlcjogdXNlck9wdGlvbnMuZGV2LnVzZUh0bWxXb3JrZXIsXG4gICAgICB1c2VSc2NXb3JrZXI6IHVzZXJPcHRpb25zLmRldi51c2VSc2NXb3JrZXIsXG4gICAgfSxcbiAgICBsb2dnZXIsXG5cbiAgICAvLyBSZXF1aXJlZCBwcm9wZXJ0aWVzXG4gICAgbm9ybWFsaXplcjogdXNlck9wdGlvbnMubm9ybWFsaXplcixcbiAgICBvbkV2ZW50OiB1c2VyT3B0aW9ucy5vbkV2ZW50LFxuICAgIG9uTWV0cmljczogdXNlck9wdGlvbnMub25NZXRyaWNzLFxuICAgIGF1dG9EaXNjb3ZlcjogdXNlck9wdGlvbnMuYXV0b0Rpc2NvdmVyLFxuICAgIGNzczogdXNlck9wdGlvbnMuY3NzLFxuICAgIHByb2plY3RSb290OiB1c2VyT3B0aW9ucy5wcm9qZWN0Um9vdCxcbiAgICBtb2R1bGVCYXNlOiB1c2VyT3B0aW9ucy5tb2R1bGVCYXNlLFxuICAgIG1vZHVsZUJhc2VQYXRoOiB1c2VyT3B0aW9ucy5tb2R1bGVCYXNlUGF0aCxcbiAgICBtb2R1bGVSb290UGF0aDogdXNlck9wdGlvbnMubW9kdWxlUm9vdFBhdGgsXG4gICAgbW9kdWxlSUQ6IHVzZXJPcHRpb25zLm1vZHVsZUlELFxuICAgIHVybCxcbiAgICBtYW5pZmVzdDogZGVmYXVsdHMubWFuaWZlc3QsXG4gICAgY3NzRmlsZXM6IGRlZmF1bHRzLmNzc0ZpbGVzLFxuICAgIGdsb2JhbENzczogZGVmYXVsdHMuZ2xvYmFsQ3NzLFxuXG4gICAgLy8gVGltZW91dHMgYW5kIHBhdGhzXG4gICAgcnNjVGltZW91dDogdXNlck9wdGlvbnMucnNjVGltZW91dCxcbiAgICBodG1sVGltZW91dDogdXNlck9wdGlvbnMuaHRtbFRpbWVvdXQsXG4gICAgZmlsZVdyaXRlVGltZW91dDogdXNlck9wdGlvbnMuZmlsZVdyaXRlVGltZW91dCxcbiAgICB3b3JrZXJTaHV0ZG93blRpbWVvdXQ6IHVzZXJPcHRpb25zLndvcmtlclNodXRkb3duVGltZW91dCxcbiAgICByc2NXb3JrZXJQYXRoOiB1c2VyT3B0aW9ucy5yc2NXb3JrZXJQYXRoLFxuICAgIGh0bWxXb3JrZXJQYXRoOiB1c2VyT3B0aW9ucy5odG1sV29ya2VyUGF0aCxcbiAgICBwdWJsaWNPcmlnaW46IHVzZXJPcHRpb25zLnB1YmxpY09yaWdpbixcblxuICAgIC8vIFN0cmVhbSBvcHRpb25zXG4gICAgc2VydmVyUGlwZWFibGVTdHJlYW1PcHRpb25zOiB1c2VyT3B0aW9ucy5zZXJ2ZXJQaXBlYWJsZVN0cmVhbU9wdGlvbnMsXG4gICAgY2xpZW50UGlwZWFibGVTdHJlYW1PcHRpb25zOiB1c2VyT3B0aW9ucy5jbGllbnRQaXBlYWJsZVN0cmVhbU9wdGlvbnMsXG5cbiAgICAvLyBDbGllbnQtc3BlY2lmaWNcbiAgICBpZCxcbiAgICAvLyBDbGllbnQgbmVlZHMgY29tcG9uZW50IHBsYWNlaG9sZGVycyBzaW5jZSBpdCBjYW4ndCBsb2FkIHNlcnZlciBtb2R1bGVzIGRpcmVjdGx5XG4gICAgSHRtbENvbXBvbmVudDogdW5kZWZpbmVkLFxuICAgIFBhZ2VDb21wb25lbnQ6IHVuZGVmaW5lZCxcbiAgICBSb290Q29tcG9uZW50OiB1bmRlZmluZWQsXG4gICAgLy8gV29ya2VycyBmb3IgY2xpZW50IGVudmlyb25tZW50IC0gcHJvdmlkZSBib3RoIGZvciBzcGVjaWZpYyB1c2UgY2FzZXNcbiAgICB3b3JrZXI6IGNvbmRpdGlvbiA9PT0gXCJyZWFjdC1zZXJ2ZXJcIiA/IHJzY1dvcmtlciA6IGh0bWxXb3JrZXIsIC8vIEJhY2t3YXJkIGNvbXBhdGliaWxpdHk6IHByZWZlciBIVE1MIHdvcmtlciBpZiBhdmFpbGFibGVcbiAgICByc2NXb3JrZXIsXG4gICAgaHRtbFdvcmtlcixcbiAgICAvLyBDaGlsZHJlbiBwcm92aWRlZCBkaXJlY3RseSB2aWEgb3B0aW9uc1xuICAgIGNoaWxkcmVuLFxuICB9O1xuXG4gIC8vIENhY2hlIGFuZCByZXR1cm5cbiAgc3Rhc2hIYW5kbGVyT3B0aW9ucyhpZCwgaGFuZGxlck9wdGlvbnMpO1xuICByZXR1cm4gaGFuZGxlck9wdGlvbnM7XG59XG5cblxuZXhwb3J0IHR5cGUge1xuICBDcmVhdGVIYW5kbGVyT3B0aW9uc1BhcmFtcyxcbiAgQ3JlYXRlSGFuZGxlck9wdGlvbnNTZXJ2ZXJGbixcbiAgQ3JlYXRlSGFuZGxlck9wdGlvbnNDbGllbnRGbixcbn0gZnJvbSBcIi4vY3JlYXRlSGFuZGxlck9wdGlvbnMudHlwZXMuanNcIjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBb0RBLFNBQVMsb0JBQXlDLEdBQUE7QUFDaEQsRUFBTyxPQUFBO0FBQUEsSUFDTCxnQkFBZ0IsY0FBZSxDQUFBLGdCQUFBO0FBQUEsSUFDL0IsaUJBQWlCLGNBQWUsQ0FBQSxpQkFBQTtBQUFBLElBQ2hDLGdCQUFnQixjQUFlLENBQUEsZ0JBQUE7QUFBQSxJQUMvQixnQkFBZ0IsY0FBZSxDQUFBLGdCQUFBO0FBQUEsSUFDL0IsUUFBQSxzQkFBYyxHQUFJLEVBQUE7QUFBQSxJQUNsQixTQUFBLHNCQUFlLEdBQUksRUFBQTtBQUFBLElBQ25CLFVBQVUsRUFBQztBQUFBLElBQ1gsS0FBSyxjQUFlLENBQUE7QUFBQSxHQUN0QjtBQUNGO0FBRUEsZUFBZSwwQkFBQSxDQUNiLE9BQ0EsRUFBQSxjQUFBLEVBQ0EsTUFDOEIsRUFBQTtBQUM5QixFQUFBLElBQUksUUFBUSxtQkFBcUIsRUFBQTtBQUMvQixJQUFBLE9BQU8sT0FBUSxDQUFBLG1CQUFBO0FBQUE7QUFHakIsRUFBTSxNQUFBLE1BQUEsR0FBUyxNQUFNLG1CQUFvQixDQUFBO0FBQUEsSUFDdkMsTUFBQSxFQUFRLE9BQVEsQ0FBQSxNQUFBLElBQVUsRUFBQztBQUFBLElBQzNCLFdBQVcsT0FBUSxDQUFBLFNBQUEsSUFBYSxFQUFFLElBQU0sRUFBQSxZQUFBLEVBQWMsU0FBUyxPQUFRLEVBQUE7QUFBQSxJQUN2RSxXQUFhLEVBQUEsY0FBQTtBQUFBLElBQ2I7QUFBQSxHQUNELENBQUE7QUFFRCxFQUFJLElBQUEs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