vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
128 lines (125 loc) • 18.9 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { configureReactServer } from './configureReactServer.server.js';
import { resolveOptions } from '../config/resolveOptions.js';
import { detectClientModule } from 'react-server-loader/directives';
import { readFileSync } from 'node:fs';
const vitePluginReactDevServer = function _vitePluginReactServerDevServer(options) {
if (options == null) {
throw new Error("options is required");
}
const resolvedOptions = resolveOptions(options);
if (resolvedOptions.type === "error") {
if (resolvedOptions.error != null) {
throw resolvedOptions.error;
}
throw new Error("Failed to resolve options");
}
const userOptions = resolvedOptions.userOptions;
const hmrPlugin = {
name: "vite-plugin-react-server:server-hmr",
apply: "serve",
// Server-level handleHotUpdate — sends custom WS event to client
// Vite 6 Environment API: hotUpdate runs per-environment.
// Prevent server/ssr environments from triggering page reload for client components.
hotUpdate(ctx) {
const { file, server } = ctx;
const envName = ctx.environment?.name ?? "unknown";
const moduleBase = userOptions.moduleBase || "src";
const projectRoot = userOptions.projectRoot || server?.config?.root || "";
const normalizedFile = file.replace(projectRoot, "").replace(/^\/+/, "");
const isSourceFile = normalizedFile.startsWith(moduleBase + "/");
if (!isSourceFile) return;
if (envName === "client") {
const isClient = (file.endsWith(".tsx") || file.endsWith(".ts") || file.endsWith(".jsx") || file.endsWith(".js")) && (() => {
try {
const source = readFileSync(file, "utf-8");
return detectClientModule({ source, moduleId: file });
} catch {
return false;
}
})();
if (isClient) return;
const kind = file.endsWith(".css") || file.endsWith(".scss") || file.endsWith(".sass") || file.endsWith(".less") ? "css" : "component";
if (userOptions.verbose) {
server.config.logger.info(`[vite-plugin-react-server] File changed (RSC refetch): ${normalizedFile}`);
}
server.ws.send({
type: "custom",
event: "vite-plugin-react-server:server-component-update",
data: { file: normalizedFile, path: file, kind }
});
return [];
}
if (envName === "server") {
const mod = ctx.environment?.moduleGraph?.getModulesByFile(file);
if (mod) {
for (const m of mod) {
ctx.environment.moduleGraph.invalidateModule(m);
}
}
}
return [];
}
};
const serverPlugin = {
name: "vite-plugin-react-server:dev-server-server",
apply: "serve",
applyToEnvironment(partialEnvironment) {
return partialEnvironment?.consumer === "server";
},
configureServer(server) {
server.config.logger.info(`[vite-plugin-react-server] Dev server plugin configured for server environment (react-server condition)`);
configureReactServer({
server,
autoDiscoveredFiles: {
propsMap: /* @__PURE__ */ new Map(),
pageMap: /* @__PURE__ */ new Map(),
rootMap: /* @__PURE__ */ new Map(),
htmlMap: /* @__PURE__ */ new Map(),
routeMap: /* @__PURE__ */ new Map(),
urlMap: /* @__PURE__ */ new Map(),
errors: [],
workerPaths: {},
serverEntry: null,
clientEntry: {},
clientInputs: {},
staticInputs: {},
serverInputs: {},
// staticManifest removed from AutoDiscoveredFiles
serverActions: {}
},
userOptions,
serverManifest: {},
resolvedConfig: server.config
});
}
};
const cjsFixPlugin = {
name: "vite-plugin-react-server:server-cjs-fix",
apply: "serve",
enforce: "post",
applyToEnvironment(env) {
return env?.name === "server";
},
transform(code, id) {
if (id.includes("node_modules")) return;
if (!id.match(/\.[jt]sx?$/)) return;
const namedImportRe = /import\s*\{([^}]+)\}\s*from\s*["']react["']\s*;?/g;
if (!namedImportRe.test(code)) return;
namedImportRe.lastIndex = 0;
let counter = 0;
const result = code.replace(namedImportRe, (_match, imports) => {
const alias = `__react_cjs_${counter++}`;
return `import ${alias} from "react"; const {${imports}} = ${alias};`;
});
return { code: result, map: null };
}
};
return [hmrPlugin, cjsFixPlugin, serverPlugin];
};
export { vitePluginReactDevServer };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLnNlcnZlci5qcyIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcGx1Z2luL2Rldi1zZXJ2ZXIvcGx1Z2luLnNlcnZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFN0cmVhbVBsdWdpbk9wdGlvbnMgfSBmcm9tIFwiLi4vLi4vdHlwZXMuanNcIjtcbmltcG9ydCB7IGNvbmZpZ3VyZVJlYWN0U2VydmVyIH0gZnJvbSBcIi4vY29uZmlndXJlUmVhY3RTZXJ2ZXIuc2VydmVyLmpzXCI7XG5pbXBvcnQgeyByZXNvbHZlT3B0aW9ucyB9IGZyb20gXCIuLi9jb25maWcvcmVzb2x2ZU9wdGlvbnMuanNcIjtcbmltcG9ydCB7IGRldGVjdENsaWVudE1vZHVsZSB9IGZyb20gXCJyZWFjdC1zZXJ2ZXItbG9hZGVyL2RpcmVjdGl2ZXNcIjtcbmltcG9ydCB0eXBlIHsgUGx1Z2luLCBWaXRlRGV2U2VydmVyIH0gZnJvbSBcInZpdGVcIjtcbmltcG9ydCB7IHJlYWRGaWxlU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5cbi8qKlxuICogRGV2IHNlcnZlciBwbHVnaW4gZm9yIHNlcnZlciBlbnZpcm9ubWVudC5cbiAqIFJldHVybnMgdHdvIHBsdWdpbnM6IG9uZSBmb3IgSE1SIGhhbmRsaW5nIChhbGwgZW52aXJvbm1lbnRzKSBhbmQgb25lIGZvciBzZXJ2ZXIgY29uZmlnLlxuICovXG5leHBvcnQgY29uc3Qgdml0ZVBsdWdpblJlYWN0RGV2U2VydmVyID0gZnVuY3Rpb24gX3ZpdGVQbHVnaW5SZWFjdFNlcnZlckRldlNlcnZlcihvcHRpb25zOiBTdHJlYW1QbHVnaW5PcHRpb25zKTogUGx1Z2luW10ge1xuICBpZiAob3B0aW9ucyA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwib3B0aW9ucyBpcyByZXF1aXJlZFwiKTtcbiAgfVxuXG4gIGNvbnN0IHJlc29sdmVkT3B0aW9ucyA9IHJlc29sdmVPcHRpb25zKG9wdGlvbnMpO1xuICBpZiAocmVzb2x2ZWRPcHRpb25zLnR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgIGlmIChyZXNvbHZlZE9wdGlvbnMuZXJyb3IgIT0gbnVsbCkge1xuICAgICAgdGhyb3cgcmVzb2x2ZWRPcHRpb25zLmVycm9yO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gcmVzb2x2ZSBvcHRpb25zXCIpO1xuICB9XG4gIGNvbnN0IHVzZXJPcHRpb25zID0gcmVzb2x2ZWRPcHRpb25zLnVzZXJPcHRpb25zO1xuXG4gIC8vIFNlcGFyYXRlIHBsdWdpbiBmb3IgSE1SIGhhbmRsaW5nIChtdXN0IGFwcGx5IHRvIGFsbCBlbnZpcm9ubWVudHMpXG4gIGNvbnN0IGhtclBsdWdpbiA9IHtcbiAgICBuYW1lOiBcInZpdGUtcGx1Z2luLXJlYWN0LXNlcnZlcjpzZXJ2ZXItaG1yXCIsXG4gICAgYXBwbHk6IFwic2VydmVcIiBhcyBjb25zdCxcbiAgICAvLyBTZXJ2ZXItbGV2ZWwgaGFuZGxlSG90VXBkYXRlIOKAlCBzZW5kcyBjdXN0b20gV1MgZXZlbnQgdG8gY2xpZW50XG4gICAgLy8gVml0ZSA2IEVudmlyb25tZW50IEFQSTogaG90VXBkYXRlIHJ1bnMgcGVyLWVudmlyb25tZW50LlxuICAgIC8vIFByZXZlbnQgc2VydmVyL3NzciBlbnZpcm9ubWVudHMgZnJvbSB0cmlnZ2VyaW5nIHBhZ2UgcmVsb2FkIGZvciBjbGllbnQgY29tcG9uZW50cy5cbiAgICBob3RVcGRhdGUoY3R4OiBhbnkpIHtcbiAgICAgIGNvbnN0IHsgZmlsZSwgc2VydmVyIH0gPSBjdHg7XG4gICAgICBjb25zdCBlbnZOYW1lID0gY3R4LmVudmlyb25tZW50Py5uYW1lID8/ICd1bmtub3duJztcbiAgICAgIFxuICAgICAgY29uc3QgbW9kdWxlQmFzZSA9IHVzZXJPcHRpb25zLm1vZHVsZUJhc2UgfHwgXCJzcmNcIjtcbiAgICAgIGNvbnN0IHByb2plY3RSb290ID0gdXNlck9wdGlvbnMucHJvamVjdFJvb3QgfHwgc2VydmVyPy5jb25maWc/LnJvb3QgfHwgJyc7XG4gICAgICBjb25zdCBub3JtYWxpemVkRmlsZSA9IGZpbGUucmVwbGFjZShwcm9qZWN0Um9vdCwgJycpLnJlcGxhY2UoL15cXC8rLywgJycpO1xuICAgICAgY29uc3QgaXNTb3VyY2VGaWxlID0gbm9ybWFsaXplZEZpbGUuc3RhcnRzV2l0aChtb2R1bGVCYXNlICsgJy8nKTtcbiAgICAgIFxuICAgICAgaWYgKCFpc1NvdXJjZUZpbGUpIHJldHVybjtcbiAgICAgIFxuICAgICAgLy8gQ2xpZW50IGVudmlyb25tZW50OiBWaXRlIG93bnMgY2xpZW50LXNpZGUgSE1SIChGYXN0IFJlZnJlc2ggaWZcbiAgICAgIC8vIGBAdml0ZWpzL3BsdWdpbi1yZWFjdGAgaXMgaW5zdGFsbGVkOyBwbGFpbiByZWxvYWQgb3RoZXJ3aXNlKS5cbiAgICAgIGlmIChlbnZOYW1lID09PSAnY2xpZW50Jykge1xuICAgICAgICBjb25zdCBpc0NsaWVudCA9IChmaWxlLmVuZHNXaXRoKCcudHN4JykgfHwgZmlsZS5lbmRzV2l0aCgnLnRzJykgfHwgZmlsZS5lbmRzV2l0aCgnLmpzeCcpIHx8IGZpbGUuZW5kc1dpdGgoJy5qcycpKSAmJiAoKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2UgPSByZWFkRmlsZVN5bmMoZmlsZSwgXCJ1dGYtOFwiKTtcbiAgICAgICAgICAgIHJldHVybiBkZXRlY3RDbGllbnRNb2R1bGUoeyBzb3VyY2UsIG1vZHVsZUlkOiBmaWxlIH0pO1xuICAgICAgICAgIH0gY2F0Y2ggeyByZXR1cm4gZmFsc2U7IH1cbiAgICAgICAgfSkoKTtcblxuICAgICAgICBpZiAoaXNDbGllbnQpIHJldHVybjsgLy8gVml0ZSdzIGNsaWVudC1zaWRlIEhNUiBvd25zIHRoaXMgdXBkYXRlXG5cbiAgICAgICAgLy8gQ1NTIGZpbGVzIHRoYXQgYXJlbid0IGltcG9ydGVkIHZpYSB0aGUgY2xpZW50IG1vZHVsZSBncmFwaCAodnBycydzXG4gICAgICAgIC8vIDxDc3MgY3NzRmlsZXM9ey4uLn0vPiBwYXR0ZXJuIGNvbGxlY3RzIHRoZW0gc2VydmVyLXNpZGUpIGFyZW4ndFxuICAgICAgICAvLyB0cmFja2VkIGJ5IFZpdGUncyBDU1MgSE1SLCBzbyBhIGNvbnRlbnQgZWRpdCBsZWF2ZXMgdGhlIDxsaW5rPlxuICAgICAgICAvLyB0YWcncyBocmVmIHVuY2hhbmdlZC4gVGFnIHRoZSBldmVudCBzbyB1c2VSc2NIbXIga25vd3MgdG8gcmVmcmVzaFxuICAgICAgICAvLyBtYXRjaGluZyBsaW5rIHRhZ3MgYnkgY2FjaGUtYnVzdGluZyB0aGVpciBocmVmLlxuICAgICAgICBjb25zdCBraW5kOiAnY3NzJyB8ICdjb21wb25lbnQnID1cbiAgICAgICAgICBmaWxlLmVuZHNXaXRoKCcuY3NzJykgfHwgZmlsZS5lbmRzV2l0aCgnLnNjc3MnKSB8fFxuICAgICAgICAgIGZpbGUuZW5kc1dpdGgoJy5zYXNzJykgfHwgZmlsZS5lbmRzV2l0aCgnLmxlc3MnKVxuICAgICAgICAgICAgPyAnY3NzJ1xuICAgICAgICAgICAgOiAnY29tcG9uZW50JztcblxuICAgICAgICAvLyBTZXJ2ZXIgY29tcG9uZW50IGNoYW5nZWQg4oCUIHNlbmQgUlNDIHJlZmV0Y2ggZXZlbnQgdG8gY2xpZW50XG4gICAgICAgIC8vIE9ubHkgZG8gdGhpcyBvbmNlIChmcm9tIGNsaWVudCBlbnYpIHRvIGF2b2lkIGR1cGxpY2F0ZSBldmVudHNcbiAgICAgICAgaWYgKHVzZXJPcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgICBzZXJ2ZXIuY29uZmlnLmxvZ2dlci5pbmZvKGBbdml0ZS1wbHVnaW4tcmVhY3Qtc2VydmVyXSBGaWxlIGNoYW5nZWQgKFJTQyByZWZldGNoKTogJHtub3JtYWxpemVkRmlsZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBzZXJ2ZXIud3Muc2VuZCh7XG4gICAgICAgICAgdHlwZTogJ2N1c3RvbScsXG4gICAgICAgICAgZXZlbnQ6ICd2aXRlLXBsdWdpbi1yZWFjdC1zZXJ2ZXI6c2VydmVyLWNvbXBvbmVudC11cGRhdGUnLFxuICAgICAgICAgIGRhdGE6IHsgZmlsZTogbm9ybWFsaXplZEZpbGUsIHBhdGg6IGZpbGUsIGtpbmQgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIFtdOyAvLyBEb24ndCB0cmlnZ2VyIGNsaWVudC1zaWRlIHBhZ2UgcmVsb2FkXG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIFNlcnZlci9TU1IgZW52aXJvbm1lbnRzOiBzdXBwcmVzcyBwYWdlIHJlbG9hZCBmb3IgYWxsIHNvdXJjZSBmaWxlc1xuICAgICAgLy8gU2VydmVyIGNvbXBvbmVudHMgYXJlIGhhbmRsZWQgYnkgdGhlIFJTQyByZWZldGNoIGV2ZW50IHNlbnQgYWJvdmVcbiAgICAgIC8vIEludmFsaWRhdGUgdGhlIHNlcnZlciBtb2R1bGUgc28gbmV4dCBSU0MgcmVxdWVzdCBnZXRzIGZyZXNoIGNvbnRlbnRcbiAgICAgIGlmIChlbnZOYW1lID09PSAnc2VydmVyJykge1xuICAgICAgICBjb25zdCBtb2QgPSBjdHguZW52aXJvbm1lbnQ/Lm1vZHVsZUdyYXBoPy5nZXRNb2R1bGVzQnlGaWxlKGZpbGUpO1xuICAgICAgICBpZiAobW9kKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBtIG9mIG1vZCkge1xuICAgICAgICAgICAgY3R4LmVudmlyb25tZW50Lm1vZHVsZUdyYXBoLmludmFsaWRhdGVNb2R1bGUobSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gW107XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBzZXJ2ZXJQbHVnaW4gPSB7XG4gICAgbmFtZTogXCJ2aXRlLXBsdWdpbi1yZWFjdC1zZXJ2ZXI6ZGV2LXNlcnZlci1zZXJ2ZXJcIixcbiAgICBhcHBseTogXCJzZXJ2ZVwiIGFzIGNvbnN0LFxuYXBwbHlUb0Vudmlyb25tZW50KHBhcnRpYWxFbnZpcm9ubWVudDogYW55KSB7XG4gICAgICByZXR1cm4gcGFydGlhbEVudmlyb25tZW50Py5jb25zdW1lciA9PT0gJ3NlcnZlcic7XG4gICAgfSxcbiAgICBjb25maWd1cmVTZXJ2ZXIoc2VydmVyOiBWaXRlRGV2U2VydmVyKSB7XG4gICAgICAvLyBMb2cgdGhhdCBwbHVnaW4gaXMgYmVpbmcgY29uZmlndXJlZFxuICAgICAgc2VydmVyLmNvbmZpZy5sb2dnZXIuaW5mbyhgW3ZpdGUtcGx1Z2luLXJlYWN0LXNlcnZlcl0gRGV2IHNlcnZlciBwbHVnaW4gY29uZmlndXJlZCBmb3Igc2VydmVyIGVudmlyb25tZW50IChyZWFjdC1zZXJ2ZXIgY29uZGl0aW9uKWApO1xuICAgICAgXG4gICAgICAvLyBDb25maWd1cmUgdGhlIFJlYWN0IHNlcnZlciBmb3Igc2VydmVyIGVudmlyb25tZW50IChkaXJlY3QgUlNDIHByb2Nlc3NpbmcpXG4gICAgICAvLyBUaGlzIHVzZXMgdGhlIGV4aXN0aW5nIGNvbmZpZ3VyZVJlYWN0U2VydmVyLnNlcnZlci5qcyBpbXBsZW1lbnRhdGlvblxuICAgICAgY29uZmlndXJlUmVhY3RTZXJ2ZXIoe1xuICAgICAgICBzZXJ2ZXIsXG4gICAgICAgIGF1dG9EaXNjb3ZlcmVkRmlsZXM6IHtcbiAgICAgICAgICBwcm9wc01hcDogbmV3IE1hcCgpLFxuICAgICAgICAgIHBhZ2VNYXA6IG5ldyBNYXAoKSxcbiAgICAgICAgICByb290TWFwOiBuZXcgTWFwKCksXG4gICAgICAgICAgaHRtbE1hcDogbmV3IE1hcCgpLFxuICAgICAgICAgIHJvdXRlTWFwOiBuZXcgTWFwKCksXG4gICAgICAgICAgdXJsTWFwOiBuZXcgTWFwKCksXG4gICAgICAgICAgZXJyb3JzOiBbXSxcbiAgICAgICAgICB3b3JrZXJQYXRoczoge30sXG4gICAgICAgICAgc2VydmVyRW50cnk6IG51bGwsXG4gICAgICAgICAgY2xpZW50RW50cnk6IHt9LFxuICAgICAgICAgIGNsaWVudElucHV0czoge30sXG4gICAgICAgICAgc3RhdGljSW5wdXRzOiB7fSxcbiAgICAgICAgICBzZXJ2ZXJJbnB1dHM6IHt9LFxuICAgICAgICAgIC8vIHN0YXRpY01hbmlmZXN0IHJlbW92ZWQgZnJvbSBBdXRvRGlzY292ZXJlZEZpbGVzXG4gICAgICAgICAgc2VydmVyQWN0aW9uczoge30sXG4gICAgICAgIH0sXG4gICAgICAgIHVzZXJPcHRpb25zLFxuICAgICAgICBzZXJ2ZXJNYW5pZmVzdDoge30sXG4gICAgICAgIHJlc29sdmVkQ29uZmlnOiBzZXJ2ZXIuY29uZmlnLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfTtcblxuICAvLyBGaXggQ0pTIG5hbWVkIGltcG9ydHMgaW4gc2VydmVyIGVudmlyb25tZW50LlxuICAvLyBWaXRlJ3MgZXNidWlsZCBKU1ggdHJhbnNmb3JtIChhbmQgQHZpdGVqcy9wbHVnaW4tcmVhY3QgaWYgcHJlc2VudCkgZ2VuZXJhdGVzXG4gIC8vIG5hbWVkIGltcG9ydHMgbGlrZSBgaW1wb3J0IHsgdXNlRWZmZWN0IH0gZnJvbSBcInJlYWN0XCJgLiBJbiB0aGUgc2VydmVyIGVudmlyb25tZW50LFxuICAvLyByZWFjdCdzIHJlYWN0LXNlcnZlciBleHBvcnQgaXMgQ0pTLW9ubHksIGFuZCBOb2RlJ3MgRVNNIGludGVyb3AgZG9lc24ndCBzdXBwb3J0XG4gIC8vIG5hbWVkIGV4cG9ydHMgZnJvbSBDSlMuIFRoaXMgcG9zdC10cmFuc2Zvcm0gcmV3cml0ZXMgdGhlbS5cbiAgY29uc3QgY2pzRml4UGx1Z2luOiBQbHVnaW4gPSB7XG4gICAgbmFtZTogXCJ2aXRlLXBsdWdpbi1yZWFjdC1zZXJ2ZXI6c2VydmVyLWNqcy1maXhcIixcbiAgICBhcHBseTogXCJzZXJ2ZVwiIGFzIGNvbnN0LFxuICAgIGVuZm9yY2U6IFwicG9zdFwiIGFzIGNvbnN0LFxuICAgIGFwcGx5VG9FbnZpcm9ubWVudChlbnY6IGFueSkge1xuICAgICAgcmV0dXJuIGVudj8ubmFtZSA9PT0gJ3NlcnZlcic7XG4gICAgfSxcbiAgICB0cmFuc2Zvcm0oY29kZTogc3RyaW5nLCBpZDogc3RyaW5nKSB7XG4gICAgICBpZiAoaWQuaW5jbHVkZXMoJ25vZGVfbW9kdWxlcycpKSByZXR1cm47XG4gICAgICBpZiAoIWlkLm1hdGNoKC9cXC5banRdc3g/JC8pKSByZXR1cm47XG4gICAgICBcbiAgICAgIGNvbnN0IG5hbWVkSW1wb3J0UmUgPSAvaW1wb3J0XFxzKlxceyhbXn1dKylcXH1cXHMqZnJvbVxccypbXCInXXJlYWN0W1wiJ11cXHMqOz8vZztcbiAgICAgIGlmICghbmFtZWRJbXBvcnRSZS50ZXN0KGNvZGUpKSByZXR1cm47XG4gICAgICBcbiAgICAgIG5hbWVkSW1wb3J0UmUubGFzdEluZGV4ID0gMDtcbiAgICAgIGxldCBjb3VudGVyID0gMDtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGNvZGUucmVwbGFjZShuYW1lZEltcG9ydFJlLCAoX21hdGNoLCBpbXBvcnRzKSA9PiB7XG4gICAgICAgIGNvbnN0IGFsaWFzID0gYF9fcmVhY3RfY2pzXyR7Y291bnRlcisrfWA7XG4gICAgICAgIHJldHVybiBgaW1wb3J0ICR7YWxpYXN9IGZyb20gXCJyZWFjdFwiOyBjb25zdCB7JHtpbXBvcnRzfX0gPSAke2FsaWFzfTtgO1xuICAgICAgfSk7XG4gICAgICBcbiAgICAgIHJldHVybiB7IGNvZGU6IHJlc3VsdCwgbWFwOiBudWxsIH07XG4gICAgfSxcbiAgfTtcblxuICByZXR1cm4gW2htclBsdWdpbiwgY2pzRml4UGx1Z2luLCBzZXJ2ZXJQbHVnaW5dO1xufTtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBV2EsTUFBQSx3QkFBQSxHQUEyQixTQUFTLCtCQUFBLENBQWdDLE9BQXdDLEVBQUE7QUFDdkgsRUFBQSxJQUFJLFdBQVcsSUFBTSxFQUFBO0FBQ25CLElBQU0sTUFBQSxJQUFJLE1BQU0scUJBQXFCLENBQUE7QUFBQTtBQUd2QyxFQUFNLE1BQUEsZUFBQSxHQUFrQixlQUFlLE9BQU8sQ0FBQTtBQUM5QyxFQUFJLElBQUEsZUFBQSxDQUFnQixTQUFTLE9BQVMsRUFBQTtBQUNwQyxJQUFJLElBQUEsZUFBQSxDQUFnQixTQUFTLElB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