UNPKG

vite-plugin-react-server

Version:
344 lines (342 loc) 51 kB
/** * 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 { getStashedUserOptions, getEnvironmentId, getStashedHandlerOptions, stashHandlerOptions } from './stashedOptionsState.js'; import { getNodeEnv } from './getNodeEnv.js'; import { createLogger } from 'vite'; import { DEFAULT_CONFIG } from './defaults.js'; import { resolveComponent } from '../helpers/resolveComponent.js'; import { serializedOptions } from '../helpers/serializeUserOptions.js'; import { createWorker } from '../worker/createWorker.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" }, id = `${route}-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`, envId = getEnvironmentId("react-server", mode), userOptions = getStashedUserOptions(envId) } = 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 PageComponent = userOptions.components?.Page; let RootComponent = userOptions.components?.Root; let HtmlComponent = userOptions.components?.Html; if (routeFilesResult.page && !PageComponent) { try { if (userOptions.verbose) { logger.info(`[createHandlerOptions] Attempting to load component from: ${routeFilesResult.page} export: ${userOptions.pageExportName}`); } const isServeMode2 = configEnv?.command === "serve" || configEnv?.mode === "development" || mode === "development"; const componentLoader = isServeMode2 ? async (path) => { if (userOptions.verbose) { logger.info(`[createHandlerOptions] Development mode: loading ${path} via dynamic import`); } return await import(path); } : defaults.loader || (() => Promise.resolve({})); const pageResult = await resolveComponent({ componentPath: routeFilesResult.page, exportName: userOptions.pageExportName, loader: componentLoader }); if (pageResult.type === "success") { PageComponent = pageResult.component; logger.info(`[createHandlerOptions] Loaded Page component from ${routeFilesResult.page}`); } else { logger.warn( `[createHandlerOptions] Failed to load Page component from ${routeFilesResult.page}: ${pageResult.error?.message || "Unknown error"}` ); } } catch (error) { logger.warn( `[createHandlerOptions] Error loading Page component from ${routeFilesResult.page}: ${error instanceof Error ? error.message : String(error)}` ); } } if (!RootComponent && routeFilesResult.root !== void 0) { if (routeFilesResult.root === "") { if (userOptions.verbose) { logger.info(`[createHandlerOptions] Root component explicitly disabled (headless mode)`); } RootComponent = void 0; } else { try { const isServeMode2 = configEnv?.command === "serve" || configEnv?.mode === "development" || mode === "development"; const componentLoader = isServeMode2 ? async (path) => import(path) : defaults.loader || (() => Promise.resolve({})); const rootResult = await resolveComponent({ componentPath: routeFilesResult.root, exportName: userOptions.rootExportName, loader: componentLoader }); if (rootResult.type === "success") { RootComponent = rootResult.component; logger.info(`[createHandlerOptions] Loaded custom Root component from ${routeFilesResult.root}`); } } catch (error) { logger.warn( `[createHandlerOptions] Error loading custom Root component: ${error instanceof Error ? error.message : String(error)}` ); } } } else if (!RootComponent) { try { const { Root } = await import('../components/root.js'); RootComponent = Root; if (userOptions.verbose) { logger.info(`[createHandlerOptions] Using default Root component`); } } catch (error) { logger.warn( `[createHandlerOptions] Error loading default Root component: ${error instanceof Error ? error.message : String(error)}` ); } } if (!HtmlComponent && routeFilesResult.html !== void 0) { if (routeFilesResult.html === "") { if (userOptions.verbose) { logger.info(`[createHandlerOptions] Html component explicitly disabled (headless mode)`); } HtmlComponent = void 0; } else { try { const isServeMode2 = configEnv?.command === "serve" || configEnv?.mode === "development" || mode === "development"; const componentLoader = isServeMode2 ? async (path) => await import(path) : defaults.loader || (() => Promise.resolve({})); const htmlResult = await resolveComponent({ componentPath: routeFilesResult.html, exportName: userOptions.htmlExportName, loader: componentLoader }); if (htmlResult.type === "success") { HtmlComponent = htmlResult.component; logger.info(`[createHandlerOptions] Loaded custom Html component from ${routeFilesResult.html}`); } } catch (error) { logger.warn( `[createHandlerOptions] Error loading custom Html component: ${error instanceof Error ? error.message : String(error)}` ); } } } else if (!HtmlComponent) { try { const { Html } = await import('../components/html.js'); HtmlComponent = Html; if (userOptions.verbose) { logger.info(`[createHandlerOptions] Using default Html component`); } } catch (error) { logger.warn( `[createHandlerOptions] Error loading default Html component: ${error instanceof Error ? error.message : String(error)}` ); } } 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.server] Creating RSC worker for route: ${route}`); } try { const serializedUserOptions = serializedOptions(userOptions, autoDiscoveredFiles); const workerResult = await createWorker({ currentCondition: "react-server", // same CONDITION as the current one (this worker may be redundant) reverseCondition: "react-server", workerPath: userOptions.rscWorkerPath, verbose: userOptions.verbose, logger, workerData: { id: route, userOptions: serializedUserOptions, resolvedConfig: { configEnv, mode } } }); if (workerResult.type === "error") { logger.warn(`[createHandlerOptions.server] Failed to create RSC worker: ${workerResult.error?.message}`); rscWorker = void 0; } else if (workerResult.type === "skip") { logger.warn(`[createHandlerOptions.server] RSC worker creation skipped: ${workerResult.reason}`); rscWorker = void 0; } else { rscWorker = workerResult.worker; if (userOptions.verbose) { logger.info(`[createHandlerOptions.server] RSC worker created successfully`); } } } catch (error) { logger.warn(`[createHandlerOptions.server] 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.server] Creating HTML worker for route: ${route}`); } try { const serializedUserOptions = serializedOptions(userOptions, autoDiscoveredFiles); const workerResult = await createWorker({ currentCondition: "react-server", reverseCondition: "react-client", // HTML worker needs react-client condition workerPath: userOptions.htmlWorkerPath, verbose: userOptions.verbose, logger, workerData: { id: route, userOptions: serializedUserOptions, resolvedConfig: { configEnv, mode } } }); if (workerResult.type === "error") { logger.warn(`[createHandlerOptions.server] Failed to create HTML worker: ${workerResult.error?.message}`); htmlWorker = void 0; } else if (workerResult.type === "skip") { logger.warn(`[createHandlerOptions.server] HTML worker creation skipped: ${workerResult.reason}`); htmlWorker = void 0; } else { htmlWorker = workerResult.worker; if (userOptions.verbose) { logger.info(`[createHandlerOptions.server] HTML worker created successfully`); } } } catch (error) { logger.warn(`[createHandlerOptions.server] HTML worker creation failed: ${error instanceof Error ? error.message : String(error)}`); htmlWorker = void 0; } } const handlerOptions = { ...userOptions, // File paths 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 || {}, components: userOptions.components, // Server-specific id, // Always use the inverse worker for the main "worker" field worker: htmlWorker, rscWorker, htmlWorker, // Loaded components (server loads them at configuration time) PageComponent, RootComponent, HtmlComponent }; stashHandlerOptions(id, handlerOptions); return handlerOptions; } export { createHandlerOptions }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlSGFuZGxlck9wdGlvbnMuc2VydmVyLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW4vY29uZmlnL2NyZWF0ZUhhbmRsZXJPcHRpb25zLnNlcnZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IENyZWF0ZUhhbmRsZXJPcHRpb25zLCBBdXRvRGlzY292ZXJlZEZpbGVzLCBSb290Q29tcG9uZW50VHlwZSwgSHRtbENvbXBvbmVudFR5cGUgfSBmcm9tIFwiLi4vdHlwZXMuanNcIjtcbmltcG9ydCB0eXBlIHsgTG9nZ2VyIH0gZnJvbSBcInZpdGVcIjtcbmltcG9ydCB7IGdldFJvdXRlRmlsZXMgfSBmcm9tIFwiLi4vaGVscGVycy9nZXRSb3V0ZUZpbGVzLmpzXCI7XG5pbXBvcnQgeyByb3V0ZVRvVVJMIH0gZnJvbSBcIi4uL3V0aWxzL3JvdXRlVG9VUkwuanNcIjtcbmltcG9ydCB7IHJlc29sdmVBdXRvRGlzY292ZXIgfSBmcm9tIFwiLi9hdXRvRGlzY292ZXIvcmVzb2x2ZUF1dG9EaXNjb3Zlci5qc1wiO1xuaW1wb3J0IHtcbiAgZ2V0U3Rhc2hlZFVzZXJPcHRpb25zLFxuICBnZXRTdGFzaGVkSGFuZGxlck9wdGlvbnMsXG4gIHN0YXNoSGFuZGxlck9wdGlvbnMsXG4gIGdldEVudmlyb25tZW50SWQsXG59IGZyb20gXCIuL3N0YXNoZWRPcHRpb25zU3RhdGUuanNcIjtcblxuaW1wb3J0IHsgZ2V0Tm9kZUVudiB9IGZyb20gXCIuL2dldE5vZGVFbnYuanNcIjtcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gXCJ2aXRlXCI7XG5pbXBvcnQgeyBERUZBVUxUX0NPTkZJRyB9IGZyb20gXCIuL2RlZmF1bHRzLmpzXCI7XG5pbXBvcnQgdHlwZSB7IENyZWF0ZUhhbmRsZXJPcHRpb25zUGFyYW1zLCBSZXNvbHZlZERlZmF1bHRzIH0gZnJvbSBcIi4vY3JlYXRlSGFuZGxlck9wdGlvbnMudHlwZXMuanNcIjtcbmltcG9ydCB7IHJlc29sdmVDb21wb25lbnQgfSBmcm9tIFwiLi4vaGVscGVycy9yZXNvbHZlQ29tcG9uZW50LmpzXCI7XG5pbXBvcnQgeyBzZXJpYWxpemVkT3B0aW9ucyB9IGZyb20gXCIuLi9oZWxwZXJzL3NlcmlhbGl6ZVVzZXJPcHRpb25zLmpzXCI7XG5pbXBvcnQgeyBjcmVhdGVXb3JrZXIgfSBmcm9tIFwiLi4vd29ya2VyL2NyZWF0ZVdvcmtlci5qc1wiO1xuXG4vKipcbiAqIFNlcnZlci1zcGVjaWZpYyBoYW5kbGVyIG9wdGlvbnMgY3JlYXRpb24gZm9yIFJlYWN0IFNlcnZlciBDb21wb25lbnRzIChSU0MpLlxuICogXG4gKiBXSEFUIFRISVMgRE9FUzpcbiAqIC0gQ3JlYXRlcyBoYW5kbGVyIG9wdGlvbnMgb3B0aW1pemVkIGZvciBzZXJ2ZXItc2lkZSByZW5kZXJpbmdcbiAqIC0gUmVzb2x2ZXMgZmlsZSBwYXRocyBmb3IgcGFnZXMsIHByb3BzLCByb290LCBhbmQgSFRNTCBjb21wb25lbnRzXG4gKiAtIFNldHMgdXAgc2VydmVyLXNwZWNpZmljIGxvYWRlcnMgYW5kIGNvbmZpZ3VyYXRpb25cbiAqIC0gSGFuZGxlcyBjYWNoaW5nIHdpdGggdW5pcXVlIElEc1xuICogLSBQcm92aWRlcyBhbGwgbmVjZXNzYXJ5IG9wdGlvbnMgZm9yIFJTQyBzdHJlYW0gY3JlYXRpb25cbiAqIFxuICogV0hBVCBUSElTIERPRVNOJ1QgRE86XG4gKiAtIERvZXMgTk9UIGxvYWQgUmVhY3QgY29tcG9uZW50cyAodGhhdCBoYXBwZW5zIGluIHRoZSBhY3R1YWwgaGFuZGxlcnMpXG4gKiAtIERvZXMgTk9UIGNyZWF0ZSBSU0Mgc3RyZWFtcyAodXNlIGNyZWF0ZUhhbmRsZXIgZm9yIHRoYXQpXG4gKiAtIERvZXMgTk9UIGhhbmRsZSBjbGllbnQtc2lkZSByZW5kZXJpbmcgKHVzZSAuY2xpZW50LnRzIGZvciB0aGF0KVxuICogLSBEb2VzIE5PVCBtYW5hZ2UgY29tcG9uZW50IGxpZmVjeWNsZSBvciBzdGF0ZVxuICogXG4gKiBVU0FHRTpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGhhbmRsZXJPcHRpb25zID0gYXdhaXQgY3JlYXRlSGFuZGxlck9wdGlvbnMoXCIvbXktcm91dGVcIiwge1xuICogICBsb2dnZXI6IG15TG9nZ2VyLFxuICogICBkZWZhdWx0czogeyBsb2FkZXI6IHNlcnZlci5zc3JMb2FkTW9kdWxlIH1cbiAqIH0pO1xuICogYGBgXG4gKi9cblxuZnVuY3Rpb24gY3JlYXRlRGVmYXVsdE9wdGlvbnMoKTogUmVzb2x2ZWREZWZhdWx0cyB7XG4gIHJldHVybiB7XG4gICAgcGFnZUV4cG9ydE5hbWU6IERFRkFVTFRfQ09ORklHLlBBR0VfRVhQT1JUX05BTUUsXG4gICAgcHJvcHNFeHBvcnROYW1lOiBERUZBVUxUX0NPTkZJRy5QUk9QU19FWFBPUlRfTkFNRSxcbiAgICByb290RXhwb3J0TmFtZTogREVGQVVMVF9DT05GSUcuUk9PVF9FWFBPUlRfTkFNRSxcbiAgICBodG1sRXhwb3J0TmFtZTogREVGQVVMVF9DT05GSUcuSFRNTF9FWFBPUlRfTkFNRSxcbiAgICBjc3NGaWxlczogbmV3IE1hcCgpLFxuICAgIGdsb2JhbENzczogbmV3IE1hcCgpLFxuICAgIG1hbmlmZXN0OiB7fSxcbiAgICBjc3M6IERFRkFVTFRfQ09ORklHLkNTUyxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUF1dG9EaXNjb3ZlcmVkRmlsZXMoXG4gIG9wdGlvbnM6IENyZWF0ZUhhbmRsZXJPcHRpb25zUGFyYW1zLFxuICBzdGFzaGVkT3B0aW9uczogYW55LFxuICBsb2dnZXI6IExvZ2dlclxuKTogUHJvbWlzZTxBdXRvRGlzY292ZXJlZEZpbGVzPiB7XG4gIGlmIChvcHRpb25zLmF1dG9EaXNjb3ZlcmVkRmlsZXMpIHtcbiAgICByZXR1cm4gb3B0aW9ucy5hdXRvRGlzY292ZXJlZEZpbGVzO1xuICB9XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzb2x2ZUF1dG9EaXNjb3Zlcih7XG4gICAgY29uZmlnOiBvcHRpb25zLmNvbmZpZyB8fCB7fSxcbiAgICBjb25maWdFbnY6IG9wdGlvbnMuY29uZmlnRW52IHx8IHsgbW9kZTogXCJwcm9kdWN0aW9uXCIsIGNvbW1hbmQ6IFwiYnVpbGRcIiB9LFxuICAgIHVzZXJPcHRpb25zOiBzdGFzaGVkT3B0aW9ucyxcbiAgICBsb2dnZXIsXG4gIH0pO1xuXG4gIGlmIChyZXN1bHQudHlwZSA9PT0gXCJlcnJvclwiKSB7XG4gICAgdGhyb3cgcmVzdWx0LmVycm9yIHx8IG5ldyBFcnJvcihcIkZhaWxlZCB0byByZXNvbHZlIGF1dG9EaXNjb3ZlclwiKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQuYXV0b0Rpc2NvdmVyZWRGaWxlcztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUhhbmRsZXJPcHRpb25zKFxuICByb3V0ZTogc3RyaW5nLFxuICBvcHRpb25zOiBDcmVhdGVIYW5kbGVyT3B0aW9uc1BhcmFtcyA9IHt9XG4pOiBQcm9taXNlPENyZWF0ZUhhbmRsZXJPcHRpb25zPiB7XG4gIGNvbnN0IHtcbiAgICBtb2RlID0gZ2V0Tm9kZUVudigpLFxuICAgIGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigpLFxuICAgIGNvbmZpZ0VudiA9IHsgbW9kZTogbW9kZSB8fCBcInByb2R1Y3Rpb25cIiwgY29tbWFuZDogXCJidWlsZFwiIH0sXG4gICAgaWQgPSBgJHtyb3V0ZX0tJHtEYXRlLm5vdygpfS0ke01hdGgucmFuZG9tKClcbiAgICAgIC50b1N0cmluZygzNilcbiAgICAgIC5zdWJzdHJpbmcoMiwgMTEpfWAsXG4gICAgZW52SWQgPSBnZXRFbnZpcm9ubWVudElkKFwicmVhY3Qtc2VydmVyXCIsIG1vZGUpLFxuICAgIHVzZXJPcHRpb25zID0gZ2V0U3Rhc2hlZFVzZXJPcHRpb25zKGVudklkKSxcbiAgfSA9IG9wdGlvbnM7XG5cbiAgLy8gQ2hlY2sgY2FjaGUgZmlyc3RcbiAgY29uc3QgY2FjaGVkT3B0aW9ucyA9IGdldFN0YXNoZWRIYW5kbGVyT3B0aW9ucyhpZCk7XG4gIGlmIChjYWNoZWRPcHRpb25zKSB7XG4gICAgcmV0dXJuIGNhY2hlZE9wdGlvbnM7XG4gIH1cblxuXG4gIGlmICghdXNlck9wdGlvbnMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTm8gc3Rhc2hlZCB1c2VyT3B0aW9ucyBmb3VuZCBmb3IgZW52aXJvbm1lbnQ6ICR7ZW52SWR9LiBNYWtlIHN1cmUgcmVzb2x2ZU9wdGlvbnMoKSBoYXMgYmVlbiBjYWxsZWQgZmlyc3QuYFxuICAgICk7XG4gIH1cblxuICAvLyBSZXNvbHZlIGRlZmF1bHRzXG4gIGNvbnN0IGRlZmF1bHRzID0geyAuLi5jcmVhdGVEZWZhdWx0T3B0aW9ucygpLCAuLi5vcHRpb25zLmRlZmF1bHRzIH07XG5cbiAgLy8gUmVzb2x2ZSBhdXRvLWRpc2NvdmVyZWQgZmlsZXNcbiAgY29uc3QgYXV0b0Rpc2NvdmVyZWRGaWxlcyA9IGF3YWl0IHJlc29sdmVBdXRvRGlzY292ZXJlZEZpbGVzKFxuICAgIG9wdGlvbnMsXG4gICAgdXNlck9wdGlvbnMsXG4gICAgbG9nZ2VyXG4gICk7XG5cbiAgLy8gQ3JlYXRlIFVSTFxuICBjb25zdCB1cmwgPSByb3V0ZVRvVVJMKFxuICAgIHJvdXRlLFxuICAgIHVzZXJPcHRpb25zLm1vZHVsZUJhc2VVUkwsXG4gICAgdXNlck9wdGlvbnMuYnVpbGQucnNjT3V0cHV0UGF0aFxuICApO1xuXG4gIC8vIEdldCByb3V0ZSBmaWxlc1xuICBjb25zdCByb3V0ZUZpbGVzUmVzdWx0ID0gYXdhaXQgZ2V0Um91dGVGaWxlcyhcbiAgICByb3V0ZSxcbiAgICBhdXRvRGlzY292ZXJlZEZpbGVzLFxuICAgIHVzZXJPcHRpb25zLFxuICAgIGxvZ2dlclxuICApO1xuXG4gIGlmIChyb3V0ZUZpbGVzUmVzdWx0LnR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgIHRocm93IHJvdXRlRmlsZXNSZXN1bHQuZXJyb3IgfHwgbmV3IEVycm9yKFwiRmFpbGVkIHRvIGdldCByb3V0ZSBmaWxlc1wiKTtcbiAgfVxuXG4gIC8vIExvYWQgY29tcG9uZW50cyBmcm9tIHJlc29sdmVkIGZpbGUgcGF0aHNcbiAgbGV0IFBhZ2VDb21wb25lbnQgPSB1c2VyT3B0aW9ucy5jb21wb25lbnRzPy5QYWdlO1xuICBsZXQgUm9vdENvbXBvbmVudCA9IHVzZXJPcHRpb25zLmNvbXBvbmVudHM/LlJvb3Q7XG4gIGxldCBIdG1sQ29tcG9uZW50ID0gdXNlck9wdGlvbnMuY29tcG9uZW50cz8uSHRtbDtcblxuICAvLyBMb2FkIFBhZ2UgY29tcG9uZW50IGlmIHBhZ2VQYXRoIGlzIGF2YWlsYWJsZVxuICBpZiAocm91dGVGaWxlc1Jlc3VsdC5wYWdlICYmICFQYWdlQ29tcG9uZW50KSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh1c2VyT3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKGBbY3JlYXRlSGFuZGxlck9wdGlvbnNdIEF0dGVtcHRpbmcgdG8gbG9hZCBjb21wb25lbnQgZnJvbTogJHtyb3V0ZUZpbGVzUmVzdWx0LnBhZ2V9IGV4cG9ydDogJHt1c2VyT3B0aW9ucy5wYWdlRXhwb3J0TmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gSW4gZGV2ZWxvcG1lbnQgbW9kZSAoc2VydmUpLCB1c2UgZHluYW1pYyBpbXBvcnQgbG9hZGVyIGZvciBUeXBlU2NyaXB0IHN1cHBvcnRcbiAgICAgIGNvbnN0IGlzU2VydmVNb2RlID0gY29uZmlnRW52Py5jb21tYW5kID09PSBcInNlcnZlXCIgfHwgY29uZmlnRW52Py5tb2RlID09PSBcImRldmVsb3BtZW50XCIgfHwgbW9kZSA9PT0gXCJkZXZlbG9wbWVudFwiO1xuICAgICAgY29uc3QgY29tcG9uZW50TG9hZGVyID0gaXNTZXJ2ZU1vZGUgXG4gICAgICAgID8gYXN5bmMgKHBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgaWYgKHVzZXJPcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYFtjcmVhdGVIYW5kbGVyT3B0aW9uc10gRGV2ZWxvcG1lbnQgbW9kZTogbG9hZGluZyAke3BhdGh9IHZpYSBkeW5hbWljIGltcG9ydGApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGltcG9ydChwYXRoKTtcbiAgICAgICAgICB9XG4gICAgICAgIDogZGVmYXVsdHMubG9hZGVyIHx8ICgoKSA9PiBQcm9taXNlLnJlc29sdmUoe30pKTtcbiAgICAgIFxuICAgICAgY29uc3QgcGFnZVJlc3VsdCA9IGF3YWl0IHJlc29sdmVDb21wb25lbnQoe1xuICAgICAgICBjb21wb25lbnRQYXRoOiByb3V0ZUZpbGVzUmVzdWx0LnBhZ2UsXG4gICAgICAgIGV4cG9ydE5hbWU6IHVzZXJPcHRpb25zLnBhZ2VFeHBvcnROYW1lLFxuICAgICAgICBsb2FkZXI6IGNvbXBvbmVudExvYWRlcixcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocGFnZVJlc3VsdC50eXBlID09PSBcInN1Y2Nlc3NcIikge1xuICAgICAgICBQYWdlQ29tcG9uZW50ID0gcGFnZVJlc3VsdC5jb21wb25lbnQ7XG4gICAgICAgIGxvZ2dlci5pbmZvKGBbY3JlYXRlSGFuZGxlck9wdGlvbnNdIExvYWRlZCBQYWdlIGNvbXBvbmVudCBmcm9tICR7cm91dGVGaWxlc1Jlc3VsdC5wYWdlfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgYFtjcmVhdGVIYW5kbGVyT3B0aW9uc10gRmFpbGVkIHRvIGxvYWQgUGFnZSBjb21wb25lbnQgZnJvbSAke3JvdXRlRmlsZXNSZXN1bHQucGFnZX06ICR7XG4gICAgICAgICAgICBwYWdlUmVzdWx0LmVycm9yPy5tZXNzYWdlIHx8IFwiVW5rbm93biBlcnJvclwiXG4gICAgICAgICAgfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgIGBbY3JlYXRlSGFuZGxlck9wdGlvbnNdIEVycm9yIGxvYWRpbmcgUGFnZSBjb21wb25lbnQgZnJvbSAke3JvdXRlRmlsZXNSZXN1bHQucGFnZX06ICR7XG4gICAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgICAgIH1gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIExvYWQgUm9vdCBjb21wb25lbnQgaWYgcm9vdFBhdGggaXMgYXZhaWxhYmxlLCBvciB1c2UgZGVmYXVsdCBSb290IGNvbXBvbmVudCBpZiByb290UGF0aCBpcyB1bmRlZmluZWRcbiAgaWYgKCFSb290Q29tcG9uZW50ICYmIHJvdXRlRmlsZXNSZXN1bHQucm9vdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gSWYgcm9vdFBhdGggaXMgZXhwbGljaXRseSBzZXQgdG8gZW1wdHkgc3RyaW5nLCBkb24ndCBsb2FkIGFueSBSb290IGNvbXBvbmVudCAoaGVhZGxlc3MgbW9kZSlcbiAgICBpZiAocm91dGVGaWxlc1Jlc3VsdC5yb290ID09PSAnJykge1xuICAgICAgaWYgKHVzZXJPcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oYFtjcmVhdGVIYW5kbGVyT3B0aW9uc10gUm9vdCBjb21wb25lbnQgZXhwbGljaXRseSBkaXNhYmxlZCAoaGVhZGxlc3MgbW9kZSlgKTtcbiAgICAgIH1cbiAgICAgIFJvb3RDb21wb25lbnQgPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIExvYWQgY3VzdG9tIFJvb3QgY29tcG9uZW50IGZyb20gc3BlY2lmaWVkIHBhdGhcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIFVzZSBzYW1lIGRldmVsb3BtZW50IG1vZGUgbG9hZGVyIGxvZ2ljXG4gICAgICAgIGNvbnN0IGlzU2VydmVNb2RlID0gY29uZmlnRW52Py5jb21tYW5kID09PSBcInNlcnZlXCIgfHwgY29uZmlnRW52Py5tb2RlID09PSBcImRldmVsb3BtZW50XCIgfHwgbW9kZSA9PT0gXCJkZXZlbG9wbWVudFwiO1xuICAgICAgICBjb25zdCBjb21wb25lbnRMb2FkZXIgPSBpc1NlcnZlTW9kZSBcbiAgICAgICAgICA/IGFzeW5jIChwYXRoOiBzdHJpbmcpID0+IGltcG9ydChwYXRoKVxuICAgICAgICAgIDogZGVmYXVsdHMubG9hZGVyIHx8ICgoKSA9PiBQcm9taXNlLnJlc29sdmUoe30pKTtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IHJvb3RSZXN1bHQgPSBhd2FpdCByZXNvbHZlQ29tcG9uZW50KHtcbiAgICAgICAgICBjb21wb25lbnRQYXRoOiByb3V0ZUZpbGVzUmVzdWx0LnJvb3QsXG4gICAgICAgICAgZXhwb3J0TmFtZTogdXNlck9wdGlvbnMucm9vdEV4cG9ydE5hbWUsXG4gICAgICAgICAgbG9hZGVyOiBjb21wb25lbnRMb2FkZXIsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChyb290UmVzdWx0LnR5cGUgPT09IFwic3VjY2Vzc1wiKSB7XG4gICAgICAgICAgUm9vdENvbXBvbmVudCA9IHJvb3RSZXN1bHQuY29tcG9uZW50IGFzIFJvb3RDb21wb25lbnRUeXBlO1xuICAgICAgICAgIGxvZ2dlci5pbmZvKGBbY3JlYXRlSGFuZGxlck9wdGlvbnNdIExvYWRlZCBjdXN0b20gUm9vdCBjb21wb25lbnQgZnJvbSAke3JvdXRlRmlsZXNSZXN1bHQucm9vdH1gKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgYFtjcmVhdGVIYW5kbGVyT3B0aW9uc10gRXJyb3IgbG9hZGluZyBjdXN0b20gUm9vdCBjb21wb25lbnQ6ICR7XG4gICAgICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcilcbiAgICAgICAgICB9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmKCFSb290Q29tcG9uZW50KSB7XG4gICAgLy8gcm9vdFBhdGggaXMgdW5kZWZpbmVkLCB1c2UgZGVmYXVsdCBSb290IGNvbXBvbmVudFxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IFJvb3QgfSA9IGF3YWl0IGltcG9ydChcIi4uL2NvbXBvbmVudHMvcm9vdC5qc1wiKTtcbiAgICAgIFJvb3RDb21wb25lbnQgPSBSb290O1xuICAgICAgaWYgKHVzZXJPcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oYFtjcmVhdGVIYW5kbGVyT3B0aW9uc10gVXNpbmcgZGVmYXVsdCBSb290IGNvbXBvbmVudGApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihcbiAgICAgICAgYFtjcmVhdGVIYW5kbGVyT3B0aW9uc10gRXJyb3IgbG9hZGluZyBkZWZhdWx0IFJvb3QgY29tcG9uZW50OiAke1xuICAgICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKVxuICAgICAgICB9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvLyBMb2FkIEh0bWwgY29tcG9uZW50IGlmIGh0bWxQYXRoIGlzIGF2YWlsYWJsZSwgb3IgdXNlIGRlZmF1bHQgSHRtbCBjb21wb25lbnQgaWYgaHRtbFBhdGggaXMgdW5kZWZpbmVkXG4gIGlmICghSHRtbENvbXBvbmVudCAmJiByb3V0ZUZpbGVzUmVzdWx0Lmh0bWwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIElmIGh0bWxQYXRoIGlzIGV4cGxpY2l0bHkgc2V0IHRvIGVtcHR5IHN0cmluZywgZG9uJ3QgbG9hZCBhbnkgSHRtbCBjb21wb25lbnQgKGhlYWRsZXNzIG1vZGUpXG4gICAgaWYgKHJvdXRlRmlsZXNSZXN1bHQuaHRtbCA9PT0gJycpIHtcbiAgICAgIGlmICh1c2VyT3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKGBbY3JlYXRlSGFuZGxlck9wdGlvbnNdIEh0bWwgY29tcG9uZW50IGV4cGxpY2l0bHkgZGlzYWJsZWQgKGhlYWRsZXNzIG1vZGUpYCk7XG4gICAgICB9XG4gICAgICBIdG1sQ29tcG9uZW50ID0gdW5kZWZpbmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBMb2FkIGN1c3RvbSBIdG1sIGNvbXBvbmVudCBmcm9tIHNwZWNpZmllZCBwYXRoXG4gICAgICB0cnkge1xuICAgICAgICBcbiAgICAgICAgLy8gVXNlIHNhbWUgZGV2ZWxvcG1lbnQgbW9kZSBsb2FkZXIgbG9naWNcbiAgICAgICAgY29uc3QgaXNTZXJ2ZU1vZGUgPSBjb25maWdFbnY/LmNvbW1hbmQgPT09IFwic2VydmVcIiB8fCBjb25maWdFbnY/Lm1vZGUgPT09IFwiZGV2ZWxvcG1lbnRcIiB8fCBtb2RlID09PSBcImRldmVsb3BtZW50XCI7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudExvYWRlciA9IGlzU2VydmVNb2RlIFxuICAgICAgICAgID8gYXN5bmMgKHBhdGg6IHN0cmluZykgPT4gYXdhaXQgaW1wb3J0KHBhdGgpXG4gICAgICAgICAgOiBkZWZhdWx0cy5sb2FkZXIgfHwgKCgpID0+IFByb21pc2UucmVzb2x2ZSh7fSkpO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgaHRtbFJlc3VsdCA9IGF3YWl0IHJlc29sdmVDb21wb25lbnQoe1xuICAgICAgICAgIGNvbXBvbmVudFBhdGg6IHJvdXRlRmlsZXNSZXN1bHQuaHRtbCxcbiAgICAgICAgICBleHBvcnROYW1lOiB1c2VyT3B0aW9ucy5odG1sRXhwb3J0TmFtZSxcbiAgICAgICAgICBsb2FkZXI6IGNvbXBvbmVudExvYWRlcixcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGh0bWxSZXN1bHQudHlwZSA9PT0gXCJzdWNjZXNzXCIpIHtcbiAgICAgICAgICBIdG1sQ29tcG9uZW50ID0gaHRtbFJlc3VsdC5jb21wb25lbnQgYXMgSHRtbENvbXBvbmVudFR5cGU7XG4gICAgICAgICAgbG9nZ2VyLmluZm8oYFtjcmVhdGVIYW5kbGVyT3B0aW9uc10gTG9hZGVkIGN1c3RvbSBIdG1sIGNvbXBvbmVudCBmcm9tICR7cm91dGVGaWxlc1Jlc3VsdC5odG1sfWApO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICBgW2NyZWF0ZUhhbmRsZXJPcHRpb25zXSBFcnJvciBsb2FkaW5nIGN1c3RvbSBIdG1sIGNvbXBvbmVudDogJHtcbiAgICAgICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKVxuICAgICAgICAgIH1gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYoIUh0bWxDb21wb25lbnQpIHtcbiAgICAvLyBodG1sUGF0aCBpcyB1bmRlZmluZWQsIHVzZSBkZWZhdWx0IEh0bWwgY29tcG9uZW50XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgSHRtbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vY29tcG9uZW50cy9odG1sLmpzXCIpO1xuICAgICAgSHRtbENvbXBvbmVudCA9IEh0bWw7XG4gICAgICBpZiAodXNlck9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICBsb2dnZXIuaW5mbyhgW2NyZWF0ZUhhbmRsZXJPcHRpb25zXSBVc2luZyBkZWZhdWx0IEh0bWwgY29tcG9uZW50YCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICBgW2NyZWF0ZUhhbmRsZXJPcHRpb25zXSBFcnJvciBsb2FkaW5nIGRlZmF1bHQgSHRtbCBjb21wb25lbnQ6ICR7XG4gICAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgICAgIH1gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIENyZWF0ZSB3b3JrZXJzIGZvciBzZXJ2ZXIgZW52aXJvbm1lbnQgYmFzZWQgb24gY29uZmlndXJhdGlvbiBhbmQgY29uZmlnRW52XG4gIGxldCByc2NXb3JrZXI6IGFueSA9IHVuZGVmaW5lZDtcbiAgbGV0IGh0bWxXb3JrZXI6IGFueSA9IHVuZGVmaW5lZDtcbiAgXG4gIC8vIERldGVybWluZSBpZiB3ZSBuZWVkIHdvcmtlcnMgYmFzZWQgb24gY29uZmlnRW52IGFuZCBkZXYgY29uZmlnXG4gIGNvbnN0IGlzU2VydmVNb2RlID0gY29uZmlnRW52Py5jb21tYW5kID09PSBcInNlcnZlXCIgfHwgY29uZmlnRW52Py5tb2RlID09PSBcImRldmVsb3BtZW50XCIgfHwgbW9kZSA9PT0gXCJkZXZlbG9wbWVudFwiO1xuICBjb25zdCBpc0J1aWxkTW9kZSA9IGNvbmZpZ0Vudj8uY29tbWFuZCA9PT0gXCJidWlsZFwiO1xuICBcbiAgLy8gQ3JlYXRlIFJTQyB3b3JrZXIgaWY6XG4gIC8vIDEuIHVzZVJzY1dvcmtlciBpcyBlbmFibGVkIGluIGRldiBjb25maWcgQU5EIHdlJ3JlIGluIHNlcnZlIG1vZGUsIE9SXG4gIC8vIDIuIHVzZVJzY1dvcmtlciBpcyBlbmFibGVkIGluIGJ1aWxkIGNvbmZpZyBBTkQgd2UncmUgaW4gYnVpbGQgbW9kZVxuICBjb25zdCBzaG91bGRDcmVhdGVSc2NXb3JrZXIgPSAodXNlck9wdGlvbnMuZGV2Py51c2VSc2NXb3JrZXIgJiYgaXNTZXJ2ZU1vZGUpIHx8IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1c2VyT3B0aW9ucy5idWlsZD8udXNlUnNjV29ya2VyICYmIGlzQnVpbGRNb2RlKTtcbiAgXG4gIGlmIChzaG91bGRDcmVhdGVSc2NXb3JrZXIpIHtcbiAgICBpZiAodXNlck9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgbG9nZ2VyLmluZm8oYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5zZXJ2ZXJdIENyZWF0aW5nIFJTQyB3b3JrZXIgZm9yIHJvdXRlOiAke3JvdXRlfWApO1xuICAgIH1cbiAgICBcbiAgICB0cnkge1xuICAgICAgXG4gICAgICBjb25zdCBzZXJpYWxpemVkVXNlck9wdGlvbnMgPSBzZXJpYWxpemVkT3B0aW9ucyh1c2VyT3B0aW9ucywgYXV0b0Rpc2NvdmVyZWRGaWxlcyk7XG4gICAgICBcbiAgICAgIC8vIFdlIGRvbid0IG5lZWQgdG8gY3JlYXRlIHRoZSBSU0Mgd29ya2VyLCBidXQgaWYgdGhlIHVzZXIgd2FudHMgdG8gdXNlIHRoZWlyIG93biB3b3JrZXJcbiAgICAgIC8vIGl0IGNhbiBiZSBkb25lIGJ5IHNldHRpbmcgZGV2LnVzZVJzY1dvcmtlcj10cnVlIG9yIGJ1aWxkLnVzZVJzY1dvcmtlcj10cnVlXG4gICAgICBjb25zdCB3b3JrZXJSZXN1bHQgPSBhd2FpdCBjcmVhdGVXb3JrZXIoe1xuICAgICAgICBjdXJyZW50Q29uZGl0aW9uOiBcInJlYWN0LXNlcnZlclwiLFxuICAgICAgICAvLyBzYW1lIENPTkRJVElPTiBhcyB0aGUgY3VycmVudCBvbmUgKHRoaXMgd29ya2VyIG1heSBiZSByZWR1bmRhbnQpXG4gICAgICAgIHJldmVyc2VDb25kaXRpb246IFwicmVhY3Qtc2VydmVyXCIsXG4gICAgICAgIHdvcmtlclBhdGg6IHVzZXJPcHRpb25zLnJzY1dvcmtlclBhdGgsXG4gICAgICAgIHZlcmJvc2U6IHVzZXJPcHRpb25zLnZlcmJvc2UsXG4gICAgICAgIGxvZ2dlcixcbiAgICAgICAgd29ya2VyRGF0YToge1xuICAgICAgICAgIGlkOiByb3V0ZSxcbiAgICAgICAgICB1c2VyT3B0aW9uczogc2VyaWFsaXplZFVzZXJPcHRpb25zLFxuICAgICAgICAgIHJlc29sdmVkQ29uZmlnOiB7XG4gICAgICAgICAgICBjb25maWdFbnYsXG4gICAgICAgICAgICBtb2RlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgaWYgKHdvcmtlclJlc3VsdC50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5zZXJ2ZXJdIEZhaWxlZCB0byBjcmVhdGUgUlNDIHdvcmtlcjogJHt3b3JrZXJSZXN1bHQuZXJyb3I/Lm1lc3NhZ2V9YCk7XG4gICAgICAgIHJzY1dvcmtlciA9IHVuZGVmaW5lZDtcbiAgICAgIH0gZWxzZSBpZiAod29ya2VyUmVzdWx0LnR5cGUgPT09IFwic2tpcFwiKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBbY3JlYXRlSGFuZGxlck9wdGlvbnMuc2VydmVyXSBSU0Mgd29ya2VyIGNyZWF0aW9uIHNraXBwZWQ6ICR7d29ya2VyUmVzdWx0LnJlYXNvbn1gKTtcbiAgICAgICAgcnNjV29ya2VyID0gdW5kZWZpbmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcnNjV29ya2VyID0gd29ya2VyUmVzdWx0LndvcmtlcjtcbiAgICAgICAgaWYgKHVzZXJPcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgICBsb2dnZXIuaW5mbyhgW2NyZWF0ZUhhbmRsZXJPcHRpb25zLnNlcnZlcl0gUlNDIHdvcmtlciBjcmVhdGVkIHN1Y2Nlc3NmdWxseWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBbY3JlYXRlSGFuZGxlck9wdGlvbnMuc2VydmVyXSBSU0Mgd29ya2VyIGNyZWF0aW9uIGZhaWxlZDogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCk7XG4gICAgICByc2NXb3JrZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLy8gQ3JlYXRlIEhUTUwgd29ya2VyIGlmOlxuICAvLyBDcmVhdGUgSFRNTCB3b3JrZXIgaWY6XG4gIC8vIDEuIHVzZUh0bWxXb3JrZXIgaXMgZW5hYmxlZCBpbiBkZXYgY29uZmlnIEFORCB3ZSdyZSBpbiBzZXJ2ZSBtb2RlLCBPUlxuICAvLyAyLiB1c2VIdG1sV29ya2VyIGlzIGVuYWJsZWQgaW4gYnVpbGQgY29uZmlnIEFORCB3ZSdyZSBpbiBidWlsZCBtb2RlXG4gIGNvbnN0IHNob3VsZENyZWF0ZUh0bWxXb3JrZXIgPSAodXNlck9wdGlvbnMuZGV2Py51c2VIdG1sV29ya2VyICYmIGlzU2VydmVNb2RlKSB8fCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVzZXJPcHRpb25zLmJ1aWxkPy51c2VIdG1sV29ya2VyICYmIGlzQnVpbGRNb2RlKTtcbiAgXG4gIGlmIChzaG91bGRDcmVhdGVIdG1sV29ya2VyKSB7XG4gICAgaWYgKHVzZXJPcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgIGxvZ2dlci5pbmZvKGBbY3JlYXRlSGFuZGxlck9wdGlvbnMuc2VydmVyXSBDcmVhdGluZyBIVE1MIHdvcmtlciBmb3Igcm91dGU6ICR7cm91dGV9YCk7XG4gICAgfVxuICAgIFxuICAgIHRyeSB7XG4gICAgICBcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRVc2VyT3B0aW9ucyA9IHNlcmlhbGl6ZWRPcHRpb25zKHVzZXJPcHRpb25zLCBhdXRvRGlzY292ZXJlZEZpbGVzKTtcbiAgICAgIFxuICAgICAgY29uc3Qgd29ya2VyUmVzdWx0ID0gYXdhaXQgY3JlYXRlV29ya2VyKHtcbiAgICAgICAgY3VycmVudENvbmRpdGlvbjogXCJyZWFjdC1zZXJ2ZXJcIixcbiAgICAgICAgcmV2ZXJzZUNvbmRpdGlvbjogXCJyZWFjdC1jbGllbnRcIiwgLy8gSFRNTCB3b3JrZXIgbmVlZHMgcmVhY3QtY2xpZW50IGNvbmRpdGlvblxuICAgICAgICB3b3JrZXJQYXRoOiB1c2VyT3B0aW9ucy5odG1sV29ya2VyUGF0aCxcbiAgICAgICAgdmVyYm9zZTogdXNlck9wdGlvbnMudmVyYm9zZSxcbiAgICAgICAgbG9nZ2VyLFxuICAgICAgICB3b3JrZXJEYXRhOiB7XG4gICAgICAgICAgaWQ6IHJvdXRlLFxuICAgICAgICAgIHVzZXJPcHRpb25zOiBzZXJpYWxpemVkVXNlck9wdGlvbnMsXG4gICAgICAgICAgcmVzb2x2ZWRDb25maWc6IHtcbiAgICAgICAgICAgIGNvbmZpZ0VudixcbiAgICAgICAgICAgIG1vZGUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAod29ya2VyUmVzdWx0LnR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgICAgICBsb2dnZXIud2FybihgW2NyZWF0ZUhhbmRsZXJPcHRpb25zLnNlcnZlcl0gRmFpbGVkIHRvIGNyZWF0ZSBIVE1MIHdvcmtlcjogJHt3b3JrZXJSZXN1bHQuZXJyb3I/Lm1lc3NhZ2V9YCk7XG4gICAgICAgIGh0bWxXb3JrZXIgPSB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2UgaWYgKHdvcmtlclJlc3VsdC50eXBlID09PSBcInNraXBcIikge1xuICAgICAgICBsb2dnZXIud2FybihgW2NyZWF0ZUhhbmRsZXJPcHRpb25zLnNlcnZlcl0gSFRNTCB3b3JrZXIgY3JlYXRpb24gc2tpcHBlZDogJHt3b3JrZXJSZXN1bHQucmVhc29ufWApO1xuICAgICAgICBodG1sV29ya2VyID0gdW5kZWZpbmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaHRtbFdvcmtlciA9IHdvcmtlclJlc3VsdC53b3JrZXI7XG4gICAgICAgIGlmICh1c2VyT3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgICAgbG9nZ2VyLmluZm8oYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5zZXJ2ZXJdIEhUTUwgd29ya2VyIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYFtjcmVhdGVIYW5kbGVyT3B0aW9ucy5zZXJ2ZXJdIEhUTUwgd29ya2VyIGNyZWF0aW9uIGZhaWxlZDogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCk7XG4gICAgICBodG1sV29ya2VyID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8vIENyZWF0ZSBzZXJ2ZXItc3BlY2lmaWMgaGFuZGxlciBvcHRpb25zXG4gIGNvbnN0IGhhbmRsZXJPcHRpb25zOiBDcmVhdGVIYW5kbGVyT3B0aW9ucyA9IHtcbiAgICAuLi51c2VyT3B0aW9ucyxcbiAgICAvLyBGaWxlIHBhdGhzXG4gICAgcGFnZVBhdGg6IHJvdXRlRmlsZXNSZXN1bHQucGFnZSxcbiAgICBwcm9wc1BhdGg6IHJvdXRlRmlsZXNSZXN1bHQucHJvcHMsXG4gICAgcm9vdFBhdGg6IHJvdXRlRmlsZXNSZXN1bHQucm9vdCxcbiAgICBodG1sUGF0aDogcm91dGVGaWxlc1Jlc3VsdC5odG1sLFxuICAgIFxuICAgIC8vIEV4cG9ydCBuYW1lc1xuICAgIHBhZ2VFeHBvcnROYW1lOiB1c2VyT3B0aW9ucy5wYWdlRXhwb3J0TmFtZSxcbiAgICBwcm9wc0V4cG9ydE5hbWU6IHVzZXJPcHRpb25zLnByb3BzRXhwb3J0TmFtZSxcbiAgICByb290RXhwb3J0TmFtZTogdXNlck9wdGlvbnMucm9vdEV4cG9ydE5hbWUsXG4gICAgaHRtbEV4cG9ydE5hbWU6IHVzZXJPcHRpb25zLmh0bWxFeHBvcnROYW1lLFxuICAgIFxuICAgIC8vIFJvdXRlIGFuZCBsb2FkZXJcbiAgICByb3V0ZSxcbiAgICBsb2FkZXI6IGRlZmF1bHRzLmxvYWRlciB8fCAoKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHt9KSksXG4gICAgXG4gICAgLy8gQ29uZmlndXJhdGlvblxuICAgIHBhbmljVGhyZXNob2xkOiB1c2VyT3B0aW9ucy5wYW5pY1RocmVzaG9sZCxcbiAgICB2ZXJib3NlOiB1c2VyT3B0aW9ucy52ZXJib3NlLFxuICAgIG1vZHVsZUJhc2VVUkw6IHVzZXJPcHRpb25zLm1vZHVsZUJhc2VVUkwsXG4gICAgYnVpbGQ6IHVzZXJPcHRpb25zLmJ1aWxkLFxuICAgIGRldjoge1xuICAgICAgdXNlSHRtbFdvcmtlcjogdXNlck9wdGlvbnMuZGV2LnVzZUh0bWxXb3JrZXIsXG4gICAgICB1c2VSc2NXb3JrZXI6IHVzZXJPcHRpb25zLmRldi51c2VSc2NXb3JrZXIsXG4gICAgfSxcbiAgICBsb2dnZXIsXG4gICAgXG4gICAgLy8gUmVxdWlyZWQgcHJvcGVydGllc1xuICAgIG5vcm1hbGl6ZXI6IHVzZXJPcHRpb25zLm5vcm1hbGl6ZXIsXG4gICAgb25FdmVudDogdXNlck9wdGlvbnMub25FdmVudCxcbiAgICBvbk1ldHJpY3M6IHVzZXJPcHRpb25zLm9uTWV0cmljcyxcbiAgICBhdXRvRGlzY292ZXI6IHVzZXJPcHRpb25zLmF1dG9EaXNjb3ZlcixcbiAgICBjc3M6IHVzZXJPcHRpb25zLmNzcyxcbiAgICBwcm9qZWN0Um9vdDogdXNlck9wdGlvbnMucHJvamVjdFJvb3QsXG4gICAgbW9kdWxlQmFzZTogdXNlck9wdGlvbnMubW9kdWxlQmFzZSxcbiAgICBtb2R1bGVCYXNlUGF0aDogdXNlck9wdGlvbnMubW9kdWxlQmFzZVBhdGgsXG4gICAgbW9kdWxlUm9vdFBhdGg6IHVzZXJPcHRpb25zLm1vZHVsZVJvb3RQYXRoLFxuICAgIG1vZHVsZUlEOiB1c2VyT3B0aW9ucy5tb2R1bGVJRCxcbiAgICB1cmwsXG4gICAgbWFuaWZlc3Q6IGRlZmF1bHRzLm1hbmlmZXN0LFxuICAgIGNzc0ZpbGVzOiBkZWZhdWx0cy5jc3NGaWxlcyxcbiAgICBnbG9iYWxDc3M6IGRlZmF1bHRzLmdsb2JhbENzcyxcbiAgICBcbiAgICAvLyBUaW1lb3V0cyBhbmQgcGF0aHNcbiAgICByc2NUaW1lb3V0OiB1c2VyT3B0aW9ucy5yc2NUaW1lb3V0LFxuICAgIGh0bWxUaW1lb3V0OiB1c2VyT3B0aW9ucy5odG1sVGltZW91dCxcbiAgICBmaWxlV3JpdGVUaW1lb3V0OiB1c2VyT3B0aW9ucy5maWxlV3JpdGVUaW1lb3V0LFxuICAgIHdvcmtlclNodXRkb3duVGltZW91dDogdXNlck9wdGlvbnMud29ya2VyU2h1dGRvd25UaW1lb3V0LFxuICAgIHJzY1dvcmtlclBhdGg6IHVzZXJPcHRpb25zLnJzY1dvcmtlclBhdGgsXG4gICAgaHRtbFdvcmtlclBhdGg6IHVzZXJPcHRpb25zLmh0bWxXb3JrZXJQYXRoLFxuICAgIHB1YmxpY09yaWdpbjogdXNlck9wdGlvbnMucHVibGljT3JpZ2luLFxuICAgIFxuICAgIC8vIFN0cmVhbSBvcHRpb25zXG4gICAgc2VydmVyUGlwZWFibGVTdHJlYW1PcHRpb25zOiB1c2VyT3B0aW9ucy5zZXJ2ZXJQaXBlYWJsZVN0cmVhbU9wdGlvbnMsXG4gICAgY2xpZW50UGlwZWFibGVTdHJlYW1PcHRpb25zOiB1c2VyT3B0aW9ucy5jbGllbnRQaXBlYWJsZVN0cmVhbU9wdGlvbnMgfHwge30sXG4gICAgY29tcG9uZW50czogdXNlck9wdGlvbnMuY29tcG9uZW50cyxcbiAgICBcbiAgICAvLyBTZXJ2ZXItc3BlY2lmaWNcbiAgICBpZCxcbiAgICAvLyBBbHdheXMgdXNlIHRoZSBpbnZlcnNlIHdvcmtlciBmb3IgdGhlIG1haW4gXCJ3b3JrZXJcIiBmaWVsZFxuICAgIHdvcmtlcjogaHRtbFdvcmtlcixcbiAgICByc2NXb3JrZXIsXG4gICAgaHRtbFdvcmtlcixcbiAgICAvLyBMb2FkZWQgY29tcG9uZW50cyAoc2VydmVyIGxvYWRzIHRoZW0gYXQgY29uZmlndXJhdGlvbiB0aW1lKVxuICAgIFBhZ2VDb21wb25lbnQsXG4gICAgUm9vdENvbXBvbmVudCwgXG4gICAgSHRtbENvbXBvbmVudFxuICB9O1xuXG4gIC8vIENhY2hlIGFuZCByZXR1cm5cbiAgc3Rhc2hIYW5kbGVyT3B0aW9ucyhpZCwgaGFuZGxlck9wdGlvbnMpO1xuICByZXR1cm4gaGFuZGxlck9wdGlvbnM7XG59XG5cblxuZXhwb3J0IHR5cGUge1xuICBDcmVhdGVIYW5kbGVyT3B0aW9uc1BhcmFtcyxcbiAgQ3JlYXRlSGFuZGxlck9wdGlvbnNTZXJ2ZXJGbixcbiAgQ3JlYXRlSGFuZGxlck9wdGlvbnNDbGllbnRGbixcbn0gZnJvbSBcIi4vY3JlYXRlSGFuZGxlck9wdGlvbnMudHlwZXMuanNcIjtcbiJdLCJuYW1lcyI6WyJpc1NlcnZlTW9kZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQTZDQSxTQUFTLG9CQUF5QyxHQUFBO0FBQ2hELEVBQU8sT0FBQTtBQUFBLElBQ0wsZ0JBQWdCLGNBQWUsQ0FB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