@riddance/deploy
Version:
277 lines (275 loc) • 41 kB
JavaScript
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import virtual from '@rollup/plugin-virtual';
import { rollup } from '@rollup/wasm-node';
import { createHash } from 'node:crypto';
import { mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { dirname, join, relative } from 'node:path';
import { isDeepStrictEqual } from 'node:util';
import zlib from 'node:zlib';
// eslint-disable-next-line camelcase
import { minify_sync } from 'terser';
import { install } from './npm.js';
const aws = {
entry: (type, service, fn, revision, config) => `
import { awsHandler } from '@riddance/aws-host/${type}'
import * as host from '@riddance/aws-host/${type}'
if('setMeta' in host) {
host.setMeta('${service.replaceAll("'", "\\'")}','${fn}','${revision}',${JSON.stringify(config)})
}
import('./${fn}.js')
export const handler = awsHandler
`,
patch: (code) => `/*global fetch AbortController*/${code}`,
};
export async function stage(path, revision, implementations, service, types) {
const stagePath = join(tmpdir(), 'riddance', 'stage', service);
console.log(`stage dir: ${stagePath}`);
console.log('staging...');
const { functions, hashes, config } = await copyAndPatchProject(path, stagePath, implementations);
console.log('syncing dependencies...');
await install(stagePath);
hashes['package-lock.json'] = createHash('sha256')
.update(await readFile(join(stagePath, 'package-lock.json')))
.digest('base64');
let previous = {};
try {
previous = JSON.parse(await readFile(join(stagePath, '.hashes.json'), 'utf-8'));
}
catch (e) {
if (e.code !== 'ENOENT') {
throw e;
}
}
const packageChange = previous['package.json'] !== hashes['package.json'] ||
previous['package-lock.json'] !== hashes['package-lock.json'];
const hashesJson = JSON.stringify(hashes, undefined, ' ');
const changed = [];
const unchanged = [];
for (const fn of functions) {
const file = fn + '.js';
if (previous[file] !== hashes[file] || packageChange) {
changed.push(fn);
}
else {
unchanged.push(fn);
}
delete previous[file];
delete hashes[file];
}
const nonFunctionFilesUnchanged = isDeepStrictEqual(previous, hashes);
if (nonFunctionFilesUnchanged) {
const code = [
...(await rollupAndMinify(aws, path, stagePath, service, revision, config, changed, types)),
...(await Promise.all(unchanged.map(async (fn) => ({
fn,
code: await readFile(join(stagePath, fn + '.min.js'), 'utf-8'),
})))),
];
await writeFile(join(stagePath, '.hashes.json'), hashesJson);
return code;
}
else {
const code = await rollupAndMinify(aws, path, stagePath, service, revision, config, functions, types);
await writeFile(join(stagePath, '.hashes.json'), hashesJson);
return code;
}
}
async function copyAndPatchProject(path, target, implementations) {
const hashes = {};
const sourceFiles = (await find(path)).map(f => f.slice(path.length + 1));
const serviceFiles = sourceFiles.filter(f => f.endsWith('.js') && !f.includes('/'));
for (const sf of sourceFiles) {
hashes[sf] = await mkDirCopyFile(join(path, sf), join(target, sf), implementations);
}
const packageFile = join(target, 'package.json');
const packageJson = JSON.parse(await readFile(packageFile, 'utf-8'));
for (const [pkg, sub] of Object.entries(implementations)) {
if (packageJson.dependencies[pkg]) {
delete packageJson.dependencies[pkg];
packageJson.dependencies[sub.implementation] = sub.version;
}
}
delete packageJson.devDependencies;
const updated = JSON.stringify(packageJson);
hashes['package.json'] = createHash('sha256').update(updated).digest('base64');
await writeFile(packageFile, updated);
return { functions: serviceFiles.map(f => f.slice(0, -3)), hashes, config: packageJson.config };
}
async function mkDirCopyFile(source, target, implementations) {
let code = await readFile(source, 'utf-8');
for (const [fromPackage, toPackage] of Object.entries(implementations)) {
code = code.replaceAll(new RegExp(`import \\{ ([^}]+) \\} from '${fromPackage.replaceAll('/', '\\/')}(|/[^']+)';`, 'gu'), `import { $1 } from '${toPackage.implementation}$2';`);
}
try {
await writeFile(target, code);
}
catch {
await mkdir(dirname(target), { recursive: true });
await writeFile(target, code);
}
return createHash('sha256').update(code).digest('base64');
}
async function find(dir) {
let results = [];
let i = 0;
for (;;) {
const list = (await readdir(dir)).filter(f => !f.startsWith('.') &&
!f.endsWith('.ts') &&
!f.endsWith('.gz') &&
!f.endsWith('.min.js') &&
f !== 'tsconfig.json' &&
f !== 'cspell.json' &&
f !== 'eslint.config.mjs' &&
f !== 'dictionary.txt' &&
f !== 'node_modules' &&
f !== 'test' &&
f !== 'bin');
let file = list[i++];
if (!file) {
return results;
}
file = dir + '/' + file;
const stats = await stat(file);
if (stats.isDirectory()) {
results = [...results, ...(await find(file))];
}
else {
results.push(file);
}
}
}
async function rollupAndMinify(host, _path, stagePath, service, revision, config, functions, types) {
const minified = [];
let rollupCache;
for (const fn of functions) {
let seriousWarnings = false;
const bundler = await rollup({
input: 'entry',
cache: rollupCache,
treeshake: {
correctVarValueBeforeDeclaration: false,
propertyReadSideEffects: false,
unknownGlobalSideEffects: false,
moduleSideEffects: true,
},
plugins: [
virtual({
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
entry: aws.entry(types[fn], service, fn, revision, config),
}),
nodeResolve({
exportConditions: ['node'],
rootDir: stagePath,
}),
commonjs(),
json(),
],
onwarn: warning => {
if (warning.code === 'THIS_IS_UNDEFINED') {
return;
}
if (warning.code === 'MISSING_EXPORT' &&
warning.id === '\u0000virtual:entry' &&
warning.binding === 'setMeta') {
return;
}
console.warn(`${warning.code ?? warning.message} [${fn}]`);
if (warning.code === 'CIRCULAR_DEPENDENCY' &&
warning.ids &&
warning.ids.length !== 0) {
console.warn(warning.ids.map(p => relative(stagePath, p)).join(' -> '));
}
else {
if (warning.code) {
console.warn(warning.message);
}
if (warning.frame) {
console.warn(warning.frame);
}
}
if (warning.code === 'UNRESOLVED_IMPORT') {
seriousWarnings = true;
}
},
});
rollupCache = bundler.cache;
const { output } = await bundler.generate({
format: 'cjs',
compact: true,
sourcemap: true,
manualChunks: () => 'entry.js',
generatedCode: {
preset: 'es2015',
arrowFunctions: true,
constBindings: true,
objectShorthand: true,
},
});
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (seriousWarnings) {
throw new Error('Suspicious bundler warnings.');
}
if (output.length !== 2) {
console.error(output[2]);
throw new Error('Weird');
}
if (output[1]?.type !== 'asset' || output[1].fileName !== '_virtual_entry.js.map') {
console.error(output[2]);
throw new Error('Weird');
}
const [{ code, map }] = output;
if (!map || map.version !== 3) {
throw new Error('Source map missing.');
}
minified.push(pack(host, stagePath, fn, code, { ...map, version: 3 }));
}
return await Promise.all(minified);
}
async function pack(host, stagePath, fn, source, map) {
console.log(`minifying ${fn}`);
const min = minify_sync({ [`${fn}.js`]: source }, {
compress: {
module: true,
ecma: 2020,
// eslint-disable-next-line camelcase
hoist_funs: true,
passes: 2,
},
mangle: {
module: true,
},
sourceMap: {
content: map,
filename: `${fn}.js.map`,
},
format: {
ecma: 2020,
comments: false,
},
});
if (!min.code) {
throw new Error('Weird');
}
const code = host.patch ? host.patch(min.code) : min.code;
console.log(`${fn} minified`);
await Promise.all([
writeFile(join(stagePath, fn + '.min.js'), code),
writeFile(join(stagePath, fn + '.min.js.map.gz'), await gzip(min.map)),
]);
return { fn, code };
}
function gzip(data) {
return new Promise((resolve, reject) => {
zlib.gzip(data, { level: 9 }, (err, buf) => {
if (err) {
reject(err);
return;
}
resolve(buf);
});
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzdGFnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFFBQVEsTUFBTSx5QkFBeUIsQ0FBQTtBQUM5QyxPQUFPLElBQUksTUFBTSxxQkFBcUIsQ0FBQTtBQUN0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNkJBQTZCLENBQUE7QUFDekQsT0FBTyxPQUFPLE1BQU0sd0JBQXdCLENBQUE7QUFDNUMsT0FBTyxFQUFFLE1BQU0sRUFBdUMsTUFBTSxtQkFBbUIsQ0FBQTtBQUMvRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQ3hDLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDNUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUNoQyxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDbkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQzdDLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQTtBQUM1QixxQ0FBcUM7QUFDckMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUNwQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBT2xDLE1BQU0sR0FBRyxHQUFHO0lBQ1IsS0FBSyxFQUFFLENBQ0gsSUFBWSxFQUNaLE9BQWUsRUFDZixFQUFVLEVBQ1YsUUFBNEIsRUFDNUIsTUFBZSxFQUNqQixFQUFFLENBQUM7aURBQ3dDLElBQUk7NENBQ1QsSUFBSTs7b0JBRTVCLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsTUFBTSxRQUFRLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENB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QUFDO1FBQ2QsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxHQUFHLFNBQVMsQ0FBQyxFQUFFLElBQUksQ0FBQztRQUNoRCxTQUFTLENBQ0wsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLEdBQUcsZ0JBQWdCLENBQUMsRUFDdEMsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQTZCLENBQUMsQ0FDaEQ7S0FDSixDQUFDLENBQUE7SUFFRixPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFBO0FBQ3ZCLENBQUM7QUFFRCxTQUFTLElBQUksQ0FBQyxJQUFpQjtJQUMzQixPQUFPLElBQUksT0FBTyxDQUFTLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQzNDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQ3ZDLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ04sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNYLE9BQU07WUFDVixDQUFDO1lBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ2hCLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNvbW1vbmpzIGZyb20gJ0Byb2xsdXAvcGx1Z2luLWNvbW1vbmpzJ1xuaW1wb3J0IGpzb24gZnJvbSAnQHJvbGx1cC9wbHVnaW4tanNvbidcbmltcG9ydCB7IG5vZGVSZXNvbHZlIH0gZnJvbSAnQHJvbGx1cC9wbHVnaW4tbm9kZS1yZXNvbHZlJ1xuaW1wb3J0IHZpcnR1YWwgZnJvbSAnQHJvbGx1cC9wbHVnaW4tdmlydHVhbCdcbmltcG9ydCB7IHJvbGx1cCwgUm9sbHVwQ2FjaGUsIFNvdXJjZU1hcCwgdHlwZSBQbHVnaW4gfSBmcm9tICdAcm9sbHVwL3dhc20tbm9kZSdcbmltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tICdub2RlOmNyeXB0bydcbmltcG9ydCB7IG1rZGlyLCByZWFkZGlyLCByZWFkRmlsZSwgc3RhdCwgd3JpdGVGaWxlIH0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcydcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gJ25vZGU6b3MnXG5pbXBvcnQgeyBkaXJuYW1lLCBqb2luLCByZWxhdGl2ZSB9IGZyb20gJ25vZGU6cGF0aCdcbmltcG9ydCB7IGlzRGVlcFN0cmljdEVxdWFsIH0gZnJvbSAnbm9kZTp1dGlsJ1xuaW1wb3J0IHpsaWIgZnJvbSAnbm9kZTp6bGliJ1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxuaW1wb3J0IHsgbWluaWZ5X3N5bmMgfSBmcm9tICd0ZXJzZXInXG5pbXBvcnQgeyBpbnN0YWxsIH0gZnJvbSAnLi9ucG0uanMnXG5cbnR5cGUgSW1wbGVtZW50YXRpb24gPSB7XG4gICAgaW1wbGVtZW50YXRpb246IHN0cmluZ1xuICAgIHZlcnNpb246IHN0cmluZ1xufVxuXG5jb25zdCBhd3MgPSB7XG4gICAgZW50cnk6IChcbiAgICAgICAgdHlwZTogc3RyaW5nLFxuICAgICAgICBzZXJ2aWNlOiBzdHJpbmcsXG4gICAgICAgIGZuOiBzdHJpbmcsXG4gICAgICAgIHJldmlzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgICAgIGNvbmZpZzogdW5rbm93bixcbiAgICApID0+IGBcbmltcG9ydCB7IGF3c0hhbmRsZXIgfSBmcm9tICdAcmlkZGFuY2UvYXdzLWhvc3QvJHt0eXBlfSdcbmltcG9ydCAqIGFzIGhvc3QgZnJvbSAnQHJpZGRhbmNlL2F3cy1ob3N0LyR7dHlwZX0nXG5pZignc2V0TWV0YScgaW4gaG9zdCkge1xuICAgIGhvc3Quc2V0TWV0YSgnJHtzZXJ2aWNlLnJlcGxhY2VBbGwoXCInXCIsIFwiXFxcXCdcIil9JywnJHtmbn0nLCcke3JldmlzaW9ufScsJHtKU09OLnN0cmluZ2lmeShjb25maWcpfSlcbn1cblxuaW1wb3J0KCcuLyR7Zm59LmpzJylcblxuZXhwb3J0IGNvbnN0IGhhbmRsZXIgPSBhd3NIYW5kbGVyXG5gLFxuICAgIHBhdGNoOiAoY29kZTogc3RyaW5nKSA9PiBgLypnbG9iYWwgZmV0Y2ggQWJvcnRDb250cm9sbGVyKi8ke2NvZGV9YCxcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YWdlKFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICByZXZpc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIGltcGxlbWVudGF0aW9uczogeyBbZnJvbVBhY2thZ2U6IHN0cmluZ106IEltcGxlbWVudGF0aW9uIH0sXG4gICAgc2VydmljZTogc3RyaW5nLFxuICAgIHR5cGVzOiB7IFtuYW1lOiBzdHJpbmddOiAnaHR0cCcgfCAndGltZXInIHwgJ2V2ZW50JyB9LFxuKSB7XG4gICAgY29uc3Qgc3RhZ2VQYXRoID0gam9pbih0bXBkaXIoKSwgJ3JpZGRhbmNlJywgJ3N0YWdlJywgc2VydmljZSlcbiAgICBjb25zb2xlLmxvZyhgc3RhZ2UgZGlyOiAke3N0YWdlUGF0aH1gKVxuICAgIGNvbnNvbGUubG9nKCdzdGFnaW5nLi4uJylcbiAgICBjb25zdCB7IGZ1bmN0aW9ucywgaGFzaGVzLCBjb25maWcgfSA9IGF3YWl0IGNvcHlBbmRQYXRjaFByb2plY3QoXG4gICAgICAgIHBhdGgsXG4gICAgICAgIHN0YWdlUGF0aCxcbiAgICAgICAgaW1wbGVtZW50YXRpb25zLFxuICAgIClcblxuICAgIGNvbnNvbGUubG9nKCdzeW5jaW5nIGRlcGVuZGVuY2llcy4uLicpXG4gICAgYXdhaXQgaW5zdGFsbChzdGFnZVBhdGgpXG4gICAgaGFzaGVzWydwYWNrYWdlLWxvY2suanNvbiddID0gY3JlYXRlSGFzaCgnc2hhMjU2JylcbiAgICAgICAgLnVwZGF0ZShhd2FpdCByZWFkRmlsZShqb2luKHN0YWdlUGF0aCwgJ3BhY2thZ2UtbG9jay5qc29uJykpKVxuICAgICAgICAuZGlnZXN0KCdiYXNlNjQnKVxuXG4gICAgbGV0IHByZXZpb3VzOiB7IFtzb3VyY2U6IHN0cmluZ106IHN0cmluZyB9ID0ge31cbiAgICB0cnkge1xuICAgICAgICBwcmV2aW91cyA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUoam9pbihzdGFnZVBhdGgsICcuaGFzaGVzLmpzb24nKSwgJ3V0Zi04JykpIGFzIHtcbiAgICAgICAgICAgIFtzb3VyY2U6IHN0cmluZ106IHN0cmluZ1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoKGUgYXMgeyBjb2RlPzogc3RyaW5nIH0pLmNvZGUgIT09ICdFTk9FTlQnKSB7XG4gICAgICAgICAgICB0aHJvdyBlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBwYWNrYWdlQ2hhbmdlID1cbiAgICAgICAgcHJldmlvdXNbJ3BhY2thZ2UuanNvbiddICE9PSBoYXNoZXNbJ3BhY2thZ2UuanNvbiddIHx8XG4gICAgICAgIHByZXZpb3VzWydwYWNrYWdlLWxvY2suanNvbiddICE9PSBoYXNoZXNbJ3BhY2thZ2UtbG9jay5qc29uJ11cblxuICAgIGNvbnN0IGhhc2hlc0pzb24gPSBKU09OLnN0cmluZ2lmeShoYXNoZXMsIHVuZGVmaW5lZCwgJyAgJylcbiAgICBjb25zdCBjaGFuZ2VkID0gW11cbiAgICBjb25zdCB1bmNoYW5nZWQgPSBbXVxuICAgIGZvciAoY29uc3QgZm4gb2YgZnVuY3Rpb25zKSB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSBmbiArICcuanMnXG4gICAgICAgIGlmIChwcmV2aW91c1tmaWxlXSAhPT0gaGFzaGVzW2ZpbGVdIHx8IHBhY2thZ2VDaGFuZ2UpIHtcbiAgICAgICAgICAgIGNoYW5nZWQucHVzaChmbilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVuY2hhbmdlZC5wdXNoKGZuKVxuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZSBwcmV2aW91c1tmaWxlXVxuICAgICAgICBkZWxldGUgaGFzaGVzW2ZpbGVdXG4gICAgfVxuICAgIGNvbnN0IG5vbkZ1bmN0aW9uRmlsZXNVbmNoYW5nZWQgPSBpc0RlZXBTdHJpY3RFcXVhbChwcmV2aW91cywgaGFzaGVzKVxuICAgIGlmIChub25GdW5jdGlvbkZpbGVzVW5jaGFuZ2VkKSB7XG4gICAgICAgIGNvbnN0IGNvZGUgPSBbXG4gICAgICAgICAgICAuLi4oYXdhaXQgcm9sbHVwQW5kTWluaWZ5KFxuICAgICAgICAgICAgICAgIGF3cyxcbiAgICAgICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgICAgIHN0YWdlUGF0aCxcbiAgICAgICAgICAgICAgICBzZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHJldmlzaW9uLFxuICAgICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgICBjaGFuZ2VkLFxuICAgICAgICAgICAgICAgIHR5cGVzLFxuICAgICAgICAgICAgKSksXG4gICAgICAgICAgICAuLi4oYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICAgICAgdW5jaGFuZ2VkLm1hcChhc3luYyBmbiA9PiAoe1xuICAgICAgICAgICAgICAgICAgICBmbixcbiAgICAgICAgICAgICAgICAgICAgY29kZTogYXdhaXQgcmVhZEZpbGUoam9pbihzdGFnZVBhdGgsIGZuICsgJy5taW4uanMnKSwgJ3V0Zi04JyksXG4gICAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgKSksXG4gICAgICAgIF1cbiAgICAgICAgYXdhaXQgd3JpdGVGaWxlKGpvaW4oc3RhZ2VQYXRoLCAnLmhhc2hlcy5qc29uJyksIGhhc2hlc0pzb24pXG4gICAgICAgIHJldHVybiBjb2RlXG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY29kZSA9IGF3YWl0IHJvbGx1cEFuZE1pbmlmeShcbiAgICAgICAgICAgIGF3cyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBzdGFnZVBhdGgsXG4gICAgICAgICAgICBzZXJ2aWNlLFxuICAgICAgICAgICAgcmV2aXNpb24sXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBmdW5jdGlvbnMsXG4gICAgICAgICAgICB0eXBlcyxcbiAgICAgICAgKVxuICAgICAgICBhd2FpdCB3cml0ZUZpbGUoam9pbihzdGFnZVBhdGgsICcuaGFzaGVzLmpzb24nKSwgaGFzaGVzSnNvbilcbiAgICAgICAgcmV0dXJuIGNvZGVcbiAgICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNvcHlBbmRQYXRjaFByb2plY3QoXG4gICAgcGF0aDogc3RyaW5nLFxuICAgIHRhcmdldDogc3RyaW5nLFxuICAgIGltcGxlbWVudGF0aW9uczogeyBbZnJvbVBhY2thZ2U6IHN0cmluZ106IEltcGxlbWVudGF0aW9uIH0sXG4pIHtcbiAgICBjb25zdCBoYXNoZXM6IHsgW3NvdXJjZTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fVxuICAgIGNvbnN0IHNvdXJjZUZpbGVzID0gKGF3YWl0IGZpbmQocGF0aCkpLm1hcChmID0+IGYuc2xpY2UocGF0aC5sZW5ndGggKyAxKSlcbiAgICBjb25zdCBzZXJ2aWNlRmlsZXMgPSBzb3VyY2VGaWxlcy5maWx0ZXIoZiA9PiBmLmVuZHNXaXRoKCcuanMnKSAmJiAhZi5pbmNsdWRlcygnLycpKVxuXG4gICAgZm9yIChjb25zdCBzZiBvZiBzb3VyY2VGaWxlcykge1xuICAgICAgICBoYXNoZXNbc2ZdID0gYXdhaXQgbWtEaXJDb3B5RmlsZShqb2luKHBhdGgsIHNmKSwgam9pbih0YXJnZXQsIHNmKSwgaW1wbGVtZW50YXRpb25zKVxuICAgIH1cblxuICAgIGNvbnN0IHBhY2thZ2VGaWxlID0gam9pbih0YXJnZXQsICdwYWNrYWdlLmpzb24nKVxuICAgIGNvbnN0IHBhY2thZ2VKc29uID0gSlNPTi5wYXJzZShhd2FpdCByZWFkRmlsZShwYWNrYWdlRmlsZSwgJ3V0Zi04JykpIGFzIHtcbiAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgIGNvbmZpZz86IHVua25vd25cbiAgICAgICAgZGVwZW5kZW5jaWVzOiB7IFtwYWNrYWdlTmFtZTogc3RyaW5nXTogc3RyaW5nIH1cbiAgICAgICAgZGV2RGVwZW5kZW5jaWVzPzogdW5rbm93blxuICAgIH1cblxuICAgIGZvciAoY29uc3QgW3BrZywgc3ViXSBvZiBPYmplY3QuZW50cmllcyhpbXBsZW1lbnRhdGlvbnMpKSB7XG4gICAgICAgIGlmIChwYWNrYWdlSnNvbi5kZXBlbmRlbmNpZXNbcGtnXSkge1xuICAgICAgICAgICAgZGVsZXRlIHBhY2thZ2VKc29uLmRlcGVuZGVuY2llc1twa2ddXG4gICAgICAgICAgICBwYWNrYWdlSnNvbi5kZXBlbmRlbmNpZXNbc3ViLmltcGxlbWVudGF0aW9uXSA9IHN1Yi52ZXJzaW9uXG4gICAgICAgIH1cbiAgICB9XG4gICAgZGVsZXRlIHBhY2thZ2VKc29uLmRldkRlcGVuZGVuY2llc1xuXG4gICAgY29uc3QgdXBkYXRlZCA9IEpTT04uc3RyaW5naWZ5KHBhY2thZ2VKc29uKVxuICAgIGhhc2hlc1sncGFja2FnZS5qc29uJ10gPSBjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUodXBkYXRlZCkuZGlnZXN0KCdiYXNlNjQnKVxuICAgIGF3YWl0IHdyaXRlRmlsZShwYWNrYWdlRmlsZSwgdXBkYXRlZClcblxuICAgIHJldHVybiB7IGZ1bmN0aW9uczogc2VydmljZUZpbGVzLm1hcChmID0+IGYuc2xpY2UoMCwgLTMpKSwgaGFzaGVzLCBjb25maWc6IHBhY2thZ2VKc29uLmNvbmZpZyB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1rRGlyQ29weUZpbGUoXG4gICAgc291cmNlOiBzdHJpbmcsXG4gICAgdGFyZ2V0OiBzdHJpbmcsXG4gICAgaW1wbGVtZW50YXRpb25zOiB7IFtmcm9tUGFja2FnZTogc3RyaW5nXTogSW1wbGVtZW50YXRpb24gfSxcbikge1xuICAgIGxldCBjb2RlID0gYXdhaXQgcmVhZEZpbGUoc291cmNlLCAndXRmLTgnKVxuICAgIGZvciAoY29uc3QgW2Zyb21QYWNrYWdlLCB0b1BhY2thZ2VdIG9mIE9iamVjdC5lbnRyaWVzKGltcGxlbWVudGF0aW9ucykpIHtcbiAgICAgICAgY29kZSA9IGNvZGUucmVwbGFjZUFsbChcbiAgICAgICAgICAgIG5ldyBSZWdFeHAoXG4gICAgICAgICAgICAgICAgYGltcG9ydCBcXFxceyAoW159XSspIFxcXFx9IGZyb20gJyR7ZnJvbVBhY2thZ2UucmVwbGFjZUFsbCgnLycsICdcXFxcLycpfSh8L1teJ10rKSc7YCxcbiAgICAgICAgICAgICAgICAnZ3UnLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGBpbXBvcnQgeyAkMSB9IGZyb20gJyR7dG9QYWNrYWdlLmltcGxlbWVudGF0aW9ufSQyJztgLFxuICAgICAgICApXG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdyaXRlRmlsZSh0YXJnZXQsIGNvZGUpXG4gICAgfSBjYXRjaCB7XG4gICAgICAgIGF3YWl0IG1rZGlyKGRpcm5hbWUodGFyZ2V0KSwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgICAgICAgYXdhaXQgd3JpdGVGaWxlKHRhcmdldCwgY29kZSlcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShjb2RlKS5kaWdlc3QoJ2Jhc2U2NCcpXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZpbmQoZGlyOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgbGV0IHJlc3VsdHM6IHN0cmluZ1tdID0gW11cbiAgICBsZXQgaSA9IDBcbiAgICBmb3IgKDs7KSB7XG4gICAgICAgIGNvbnN0IGxpc3QgPSAoYXdhaXQgcmVhZGRpcihkaXIpKS5maWx0ZXIoXG4gICAgICAgICAgICBmID0+XG4gICAgICAgICAgICAgICAgIWYuc3RhcnRzV2l0aCgnLicpICYmXG4gICAgICAgICAgICAgICAgIWYuZW5kc1dpdGgoJy50cycpICYmXG4gICAgICAgICAgICAgICAgIWYuZW5kc1dpdGgoJy5neicpICYmXG4gICAgICAgICAgICAgICAgIWYuZW5kc1dpdGgoJy5taW4uanMnKSAmJlxuICAgICAgICAgICAgICAgIGYgIT09ICd0c2NvbmZpZy5qc29uJyAmJlxuICAgICAgICAgICAgICAgIGYgIT09ICdjc3BlbGwuanNvbicgJiZcbiAgICAgICAgICAgICAgICBmICE9PSAnZXNsaW50LmNvbmZpZy5tanMnICYmXG4gICAgICAgICAgICAgICAgZiAhPT0gJ2RpY3Rpb25hcnkudHh0JyAmJlxuICAgICAgICAgICAgICAgIGYgIT09ICdub2RlX21vZHVsZXMnICYmXG4gICAgICAgICAgICAgICAgZiAhPT0gJ3Rlc3QnICYmXG4gICAgICAgICAgICAgICAgZiAhPT0gJ2JpbicsXG4gICAgICAgIClcbiAgICAgICAgbGV0IGZpbGUgPSBsaXN0W2krK11cbiAgICAgICAgaWYgKCFmaWxlKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0c1xuICAgICAgICB9XG4gICAgICAgIGZpbGUgPSBkaXIgKyAnLycgKyBmaWxlXG4gICAgICAgIGNvbnN0IHN0YXRzID0gYXdhaXQgc3RhdChmaWxlKVxuICAgICAgICBpZiAoc3RhdHMuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAgICAgcmVzdWx0cyA9IFsuLi5yZXN1bHRzLCAuLi4oYXdhaXQgZmluZChmaWxlKSldXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goZmlsZSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxudHlwZSBIb3N0ID0ge1xuICAgIGVudHJ5OiAoXG4gICAgICAgIHR5cGU6IHN0cmluZyxcbiAgICAgICAgc2VydmljZTogc3RyaW5nLFxuICAgICAgICBuYW1lOiBzdHJpbmcsXG4gICAgICAgIHJldmlzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgICAgIGNvbmZpZzogb2JqZWN0IHwgdW5kZWZpbmVkLFxuICAgICkgPT4gc3RyaW5nXG4gICAgcGF0Y2g/OiAoYnVuZGxlZDogc3RyaW5nKSA9PiBzdHJpbmdcbn1cblxuYXN5bmMgZnVuY3Rpb24gcm9sbHVwQW5kTWluaWZ5KFxuICAgIGhvc3Q6IEhvc3QsXG4gICAgX3BhdGg6IHN0cmluZyxcbiAgICBzdGFnZVBhdGg6IHN0cmluZyxcbiAgICBzZXJ2aWNlOiBzdHJpbmcsXG4gICAgcmV2aXNpb246IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICBjb25maWc6IHVua25vd24sXG4gICAgZnVuY3Rpb25zOiBzdHJpbmdbXSxcbiAgICB0eXBlczogeyBbbmFtZTogc3RyaW5nXTogJ2h0dHAnIHwgJ3RpbWVyJyB8ICdldmVudCcgfSxcbikge1xuICAgIGNvbnN0IG1pbmlmaWVkID0gW11cbiAgICBsZXQgcm9sbHVwQ2FjaGU6IFJvbGx1cENhY2hlIHwgdW5kZWZpbmVkXG4gICAgZm9yIChjb25zdCBmbiBvZiBmdW5jdGlvbnMpIHtcbiAgICAgICAgbGV0IHNlcmlvdXNXYXJuaW5ncyA9IGZhbHNlXG4gICAgICAgIGNvbnN0IGJ1bmRsZXIgPSBhd2FpdCByb2xsdXAoe1xuICAgICAgICAgICAgaW5wdXQ6ICdlbnRyeScsXG4gICAgICAgICAgICBjYWNoZTogcm9sbHVwQ2FjaGUsXG4gICAgICAgICAgICB0cmVlc2hha2U6IHtcbiAgICAgICAgICAgICAgICBjb3JyZWN0VmFyVmFsdWVCZWZvcmVEZWNsYXJhdGlvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgcHJvcGVydHlSZWFkU2lkZUVmZmVjdHM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHVua25vd25HbG9iYWxTaWRlRWZmZWN0czogZmFsc2UsXG4gICAgICAgICAgICAgICAgbW9kdWxlU2lkZUVmZmVjdHM6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGx1Z2luczogW1xuICAgICAgICAgICAgICAgICh2aXJ0dWFsIGFzIHVua25vd24gYXMgKG9wdGlvbnM6IHVua25vd24pID0+IFBsdWdpbikoe1xuICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgICAgICAgICBlbnRyeTogYXdzLmVudHJ5KHR5cGVzW2ZuXSEsIHNlcnZpY2UsIGZuLCByZXZpc2lvbiwgY29uZmlnKSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBub2RlUmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIGV4cG9ydENvbmRpdGlvbnM6IFsnbm9kZSddLFxuICAgICAgICAgICAgICAgICAgICByb290RGlyOiBzdGFnZVBhdGgsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKGNvbW1vbmpzIGFzIHVua25vd24gYXMgKCkgPT4gUGx1Z2luKSgpLFxuICAgICAgICAgICAgICAgIChqc29uIGFzIHVua25vd24gYXMgKCkgPT4gUGx1Z2luKSgpLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIG9ud2Fybjogd2FybmluZyA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHdhcm5pbmcuY29kZSA9PT0gJ1RISVNfSVNfVU5ERUZJTkVEJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICB3YXJuaW5nLmNvZGUgPT09ICdNSVNTSU5HX0VYUE9SVCcgJiZcbiAgICAgICAgICAgICAgICAgICAgd2FybmluZy5pZCA9PT0gJ1xcdTAwMDB2aXJ0dWFsOmVudHJ5JyAmJlxuICAgICAgICAgICAgICAgICAgICB3YXJuaW5nLmJpbmRpbmcgPT09ICdzZXRNZXRhJ1xuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGAke3dhcm5pbmcuY29kZSA/PyB3YXJuaW5nLm1lc3NhZ2V9IFske2ZufV1gKVxuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgd2FybmluZy5jb2RlID09PSAnQ0lSQ1VMQVJfREVQRU5ERU5DWScgJiZcbiAgICAgICAgICAgICAgICAgICAgd2FybmluZy5pZHMgJiZcbiAgICAgICAgICAgICAgICAgICAgd2FybmluZy5pZHMubGVuZ3RoICE9PSAwXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nLmlkcy5tYXAocCA9PiByZWxhdGl2ZShzdGFnZVBhdGgsIHApKS5qb2luKCcgLT4gJykpXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdhcm5pbmcuY29kZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHdhcm5pbmcubWVzc2FnZSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAod2FybmluZy5mcmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHdhcm5pbmcuZnJhbWUpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHdhcm5pbmcuY29kZSA9PT0gJ1VOUkVTT0xWRURfSU1QT1JUJykge1xuICAgICAgICAgICAgICAgICAgICBzZXJpb3VzV2FybmluZ3MgPSB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgcm9sbHVwQ2FjaGUgPSBidW5kbGVyLmNhY2hlXG4gICAgICAgIGNvbnN0IHsgb3V0cHV0IH0gPSBhd2FpdCBidW5kbGVyLmdlbmVyYXRlKHtcbiAgICAgICAgICAgIGZvcm1hdDogJ2NqcycsXG4gICAgICAgICAgICBjb21wYWN0OiB0cnVlLFxuICAgICAgICAgICAgc291cmNlbWFwOiB0cnVlLFxuICAgICAgICAgICAgbWFudWFsQ2h1bmtzOiAoKSA9PiAnZW50cnkuanMnLFxuICAgICAgICAgICAgZ2VuZXJhdGVkQ29kZToge1xuICAgICAgICAgICAgICAgIHByZXNldDogJ2VzMjAxNScsXG4gICAgICAgICAgICAgICAgYXJyb3dGdW5jdGlvbnM6IHRydWUsXG4gICAgICAgICAgICAgICAgY29uc3RCaW5kaW5nczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvYmplY3RTaG9ydGhhbmQ6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVubmVjZXNzYXJ5LWNvbmRpdGlvblxuICAgICAgICBpZiAoc2VyaW91c1dhcm5pbmdzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N1c3BpY2lvdXMgYnVuZGxlciB3YXJuaW5ncy4nKVxuICAgICAgICB9XG4gICAgICAgIGlmIChvdXRwdXQubGVuZ3RoICE9PSAyKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKG91dHB1dFsyXSlcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV2VpcmQnKVxuICAgICAgICB9XG4gICAgICAgIGlmIChvdXRwdXRbMV0/LnR5cGUgIT09ICdhc3NldCcgfHwgb3V0cHV0WzFdLmZpbGVOYW1lICE9PSAnX3ZpcnR1YWxfZW50cnkuanMubWFwJykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihvdXRwdXRbMl0pXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlaXJkJylcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBbeyBjb2RlLCBtYXAgfV0gPSBvdXRwdXRcbiAgICAgICAgaWYgKCFtYXAgfHwgbWFwLnZlcnNpb24gIT09IDMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU291cmNlIG1hcCBtaXNzaW5nLicpXG4gICAgICAgIH1cbiAgICAgICAgbWluaWZpZWQucHVzaChwYWNrKGhvc3QsIHN0YWdlUGF0aCwgZm4sIGNvZGUsIHsgLi4ubWFwLCB2ZXJzaW9uOiAzIH0pKVxuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwobWluaWZpZWQpXG59XG5cbmFzeW5jIGZ1bmN0aW9uIHBhY2soXG4gICAgaG9zdDogSG9zdCxcbiAgICBzdGFnZVBhdGg6IHN0cmluZyxcbiAgICBmbjogc3RyaW5nLFxuICAgIHNvdXJjZTogc3RyaW5nLFxuICAgIG1hcDogU291cmNlTWFwICYgeyB2ZXJzaW9uOiAzIH0sXG4pIHtcbiAgICBjb25zb2xlLmxvZyhgbWluaWZ5aW5nICR7Zm59YClcbiAgICBjb25zdCBtaW4gPSBtaW5pZnlfc3luYyhcbiAgICAgICAgeyBbYCR7Zm59LmpzYF06IHNvdXJjZSB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBjb21wcmVzczoge1xuICAgICAgICAgICAgICAgIG1vZHVsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlY21hOiAyMDIwLFxuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjYW1lbGNhc2VcbiAgICAgICAgICAgICAgICBob2lzdF9mdW5zOiB0cnVlLFxuICAgICAgICAgICAgICAgIHBhc3NlczogMixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtYW5nbGU6IHtcbiAgICAgICAgICAgICAgICBtb2R1bGU6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc291cmNlTWFwOiB7XG4gICAgICAgICAgICAgICAgY29udGVudDogbWFwLFxuICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBgJHtmbn0uanMubWFwYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmb3JtYXQ6IHtcbiAgICAgICAgICAgICAgICBlY21hOiAyMDIwLFxuICAgICAgICAgICAgICAgIGNvbW1lbnRzOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgKVxuICAgIGlmICghbWluLmNvZGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWlyZCcpXG4gICAgfVxuICAgIGNvbnN0IGNvZGUgPSBob3N0LnBhdGNoID8gaG9zdC5wYXRjaChtaW4uY29kZSkgOiBtaW4uY29kZVxuICAgIGNvbnNvbGUubG9nKGAke2ZufSBtaW5pZmllZGApXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICB3cml0ZUZpbGUoam9pbihzdGFnZVBhdGgsIGZuICsgJy5taW4uanMnKSwgY29kZSksXG4gICAgICAgIHdyaXRlRmlsZShcbiAgICAgICAgICAgIGpvaW4oc3RhZ2VQYXRoLCBmbiArICcubWluLmpzLm1hcC5neicpLFxuICAgICAgICAgICAgYXdhaXQgZ3ppcChtaW4ubWFwIGFzIHVua25vd24gYXMgQXJyYXlCdWZmZXIpLFxuICAgICAgICApLFxuICAgIF0pXG5cbiAgICByZXR1cm4geyBmbiwgY29kZSB9XG59XG5cbmZ1bmN0aW9uIGd6aXAoZGF0YTogQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8QnVmZmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHpsaWIuZ3ppcChkYXRhLCB7IGxldmVsOiA5IH0sIChlcnIsIGJ1ZikgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpXG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNvbHZlKGJ1ZilcbiAgICAgICAgfSlcbiAgICB9KVxufVxuIl19