UNPKG

@riddance/env

Version:

Too much code slows you down, creates risks, increases maintainability burdens, confuses AI. So let's commit less of it.

241 lines 34.9 kB
import { access, constants, copyFile, mkdir, readdir, readFile, rm, stat, unlink, writeFile, } from 'node:fs/promises'; import { EOL, platform } from 'node:os'; import { join } from 'node:path'; import { managedFiles as managedAgentFiles, setupAgents } from './agents.js'; import { writeTSConfig } from './compiler.js'; import { dependantPackages } from './dependencies.js'; import { isFileNotFound } from './fs.js'; import { install } from './npm.js'; import { vote } from './siblings.js'; import { setupSpelling } from './spelling.js'; import { writeTestConfig } from './tester.js'; const dirs = ['.vscode', '.zed', '.devcontainer', '.idea/codeStyles/', '.idea/inspectionProfiles/']; const files = [ 'tsconfig.json', '.prettierrc.json', '.editorconfig', '.nvmrc', '.vscode/settings.json', '.vscode/tasks.json', '.vscode/extensions.json', '.zed/settings.json', '.zed/tasks.json', '.devcontainer/Dockerfile', '.devcontainer/devcontainer.json', '.idea/compiler.xml', '.idea/codeStyles/codeStyleConfig.xml', '.idea/inspectionProfiles/Project_Default.xml', ]; const overridableFiles = []; const legacyFiles = [ '.prettierrc', 'Dockerfile.integration', '.eslintrc.json', 'eslint.config.js', ['.gitattributes', '* text=auto eol=lf\n'], ]; const managedFiles = [ '.gitignore', ...files, ...legacyFiles.map(lf => (Array.isArray(lf) ? lf[0] : lf)), 'cspell.json', 'eslint.config.mjs', '.mocharc.json', ...managedAgentFiles, ]; export async function prepare() { await createTemplate(); await makeWindowsNpmPackFriendly('template'); } async function createTemplate() { await rm('template', { recursive: true, force: true }); await mkdir('template'); await Promise.all(dirs.map(dir => mkdir(join('template', dir), { recursive: true }))); await Promise.all([...files, ...overridableFiles.map(f => f[0])].map(file => copyFile(file, join('template', file)))); await writeFile('template/gitignore', [ ...files.map(f => `/${f}`), ...(await readFile('.gitignore', 'utf-8')) .split('\n') .filter(l => !!l && l.trim() !== '/template' && l.trim() !== '!/eslint.config.mjs'), '/eslint.config.mjs', '/.gitignore', '', ].join('\n')); await writeFile('template/eslint.config', (await readFile('eslint.config.mjs', 'utf-8')) .split('\n') .map(l => l .replace(/import \{ [^}]+ \} from '\.\/lib\/eslint-config.js'/u, `import { configuration } from '@riddance/env/lib/eslint-config.js'`) .trim()) .join('\n')); } export async function setup(targetDir, firstInstall, myself) { if (firstInstall && !myself) { // eslint-disable-next-line no-bitwise const mod = constants.R_OK | constants.W_OK; const accessResult = await Promise.allSettled(managedFiles.map(f => access(join(targetDir, f), mod))); const existing = []; accessResult.forEach((r, ix) => { if (r.status === 'fulfilled') { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion existing.push(managedFiles[ix]); } }); if (existing.length !== 0) { return existing; } } await Promise.all(legacyFiles.map(file => ensureUnlinked(targetDir, file))); await Promise.all(dirs.map(dir => mkdir(join(targetDir, dir), { recursive: true }))); const dependencies = dependantPackages(targetDir); await Promise.all([ ...(myself ? [] : [copyFromTemplate(targetDir)]), setupSpelling(targetDir), writeTestConfig(targetDir, dependencies), syncGitUser(targetDir), setupAgents(targetDir, dependencies, myself), makeWindowsNpmPackAndDevcontainerFriendly(targetDir), ensureUnlinked(targetDir, '.timestamps.json'), ]); await writeTSConfig(targetDir, dependencies); return []; } async function copyFromTemplate(targetDir) { await Promise.all(files.map(file => copyFile(join('template', file), join(targetDir, file)))); await copyFile('template/gitignore', join(targetDir, '.gitignore')); await copyFile('template/eslint.config', join(targetDir, 'eslint.config.mjs')); for (const [file, belongsHere] of overridableFiles) { try { const existing = await readFile(join(targetDir, file), 'utf-8'); if (!belongsHere(existing)) { continue; } } catch (e) { if (!isFileNotFound(e)) { throw e; } } await copyFile(join('template', file), join(targetDir, file)); } } async function syncGitUser(path) { try { const [ws, core, ...sections] = (await readFile(join(path, '.git/config'), 'utf-8')).split('['); if (!ws || !core || sections[0]?.startsWith('user]')) { return; } const user = await vote(path, '.git/config', content => content .split('[') .filter(section => section.startsWith('user]')) .join('[')); if (!user) { return; } await writeFile(join(path, '.git/config'), [ws, core, user, ...sections].join('['), 'utf-8'); } catch (e) { if (isFileNotFound(e)) { return; } throw e; } } export async function uninstall(reporter, targetDir) { reporter.status('Uninstalling...'); const packageJson = JSON.parse(await readFile(join(targetDir, 'package.json'), 'utf-8')); await ensureUnlinked(targetDir, '.timestamps.json'); await writeFile(join(targetDir, '.gitignore'), `.DS_Store node_modules/ *.js *.js.map *.d.ts `, 'utf-8'); let modified = false; if (packageJson.scripts) { for (const [key, value] of Object.entries(packageJson.scripts)) { if (value.includes('@riddance/') || value.startsWith('riddance-')) { delete packageJson.scripts[key]; modified = true; } } } if (packageJson.devDependencies?.['@riddance/env']) { delete packageJson.devDependencies['@riddance/env']; modified = true; if (Object.keys(packageJson.devDependencies).length === 0) { delete packageJson.devDependencies; } } if (modified) { await writeFile(join(targetDir, 'package.json'), JSON.stringify(packageJson, undefined, ' '), 'utf-8'); await install(reporter, targetDir); } } async function makeWindowsNpmPackAndDevcontainerFriendly(targetDir) { if (platform() !== 'win32') { return; } const path = join(targetDir, '.git', 'info', 'attributes'); if (!(await stat(path).catch(isFileNotFound))) { return; } await mkdir(join(targetDir, '.git', 'info'), { recursive: true }); await writeFile(path, sourceExtensions.map(ext => `*${ext} text=auto eol=lf\n`).join('')); for await (const sourceFile of findFiles(targetDir, isSource)) { await dos2unix(sourceFile); } } async function makeWindowsNpmPackFriendly(targetDir) { if (platform() !== 'win32') { return; } for await (const sourceFile of findFiles(targetDir, () => true)) { await dos2unix(sourceFile); } } async function dos2unix(file) { const dos = await readFile(file, 'utf-8'); const unix = dos.replaceAll(EOL, '\n'); if (unix.length !== dos.length) { await writeFile(file, unix, 'utf-8'); } } const sourceExtensions = ['.ts', '.json', '.txt', '.md']; const otherSources = new Set(['LICENSE', 'eslint.config.mjs']); function isSource(file) { return ((sourceExtensions.some(ext => file.name.endsWith(ext)) && !file.name.endsWith('.d.ts')) || otherSources.has(file.name)); } async function* findFiles(path, predicate) { const entries = await readdir(path, { withFileTypes: true }); for (const entry of entries) { if (entry.isDirectory() && entry.name !== 'node_modules') { yield* findFiles(join(path, entry.name), predicate); } if (entry.isFile() && predicate(entry)) { yield join(path, entry.name); } } } async function ensureUnlinked(dir, file) { try { if (Array.isArray(file)) { const [filename, expectedContents] = file; const path = join(dir, filename); if ((await readFile(path, 'utf-8')) !== expectedContents) { return; } await unlink(join(dir, filename)); } else { await unlink(join(dir, file)); } } catch (e) { if (isFileNotFound(e)) { return; } throw e; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW52LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZW52LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFDSCxNQUFNLEVBQ04sU0FBUyxFQUNULFFBQVEsRUFDUixLQUFLLEVBQ0wsT0FBTyxFQUNQLFFBQVEsRUFDUixFQUFFLEVBQ0YsSUFBSSxFQUNKLE1BQU0sRUFDTixTQUFTLEdBQ1osTUFBTSxrQkFBa0IsQ0FBQTtBQUN6QixPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUN2QyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ2hDLE9BQU8sRUFBRSxZQUFZLElBQUksaUJBQWlCLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQzVFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDN0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDckQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUN4QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBRWxDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDcEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUM3QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBRTdDLE1BQU0sSUFBSSxHQUFHLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsMkJBQTJCLENBQUMsQ0FBQTtBQUNuRyxNQUFNLEtBQUssR0FBRztJQUNWLGVBQWU7SUFDZixrQkFBa0I7SUFDbEIsZUFBZTtJQUNmLFFBQVE7SUFDUix1QkFBdUI7SUFDdkIsb0JBQW9CO0lBQ3BCLHlCQUF5QjtJQUN6QixvQkFBb0I7SUFDcEIsaUJBQWlCO0lBQ2pCLDBCQUEwQjtJQUMxQixp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QUUsSUFBK0I7SUFDdEUsSUFBSSxDQUFDO1FBQ0QsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDdEIsTUFBTSxDQUFDLFFBQVEsRUFBRSxnQkFBZ0IsQ0FBQyxHQUFHLElBQUksQ0FBQTtZQUN6QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFBO1lBQ2hDLElBQUksQ0FBQyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsS0FBSyxnQkFBZ0IsRUFBRSxDQUFDO2dCQUN2RCxPQUFNO1lBQ1YsQ0FBQztZQUNELE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQTtRQUNyQyxDQUFDO2FBQU0sQ0FBQztZQUNKLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQTtRQUNqQyxDQUFDO0lBQ0wsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDVCxJQUFJLGNBQWMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3BCLE9BQU07UUFDVixDQUFDO1FBQ0QsTUFBTSxDQUFDLENBQUE7SUFDWCxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLWltcG9ydHNcbmltcG9ydCB7IHR5cGUgRGlyZW50IH0gZnJvbSAnbm9kZTpmcydcbmltcG9ydCB7XG4gICAgYWNjZXNzLFxuICAgIGNvbnN0YW50cyxcbiAgICBjb3B5RmlsZSxcbiAgICBta2RpcixcbiAgICByZWFkZGlyLFxuICAgIHJlYWRGaWxlLFxuICAgIHJtLFxuICAgIHN0YXQsXG4gICAgdW5saW5rLFxuICAgIHdyaXRlRmlsZSxcbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcydcbmltcG9ydCB7IEVPTCwgcGxhdGZvcm0gfSBmcm9tICdub2RlOm9zJ1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCdcbmltcG9ydCB7IG1hbmFnZWRGaWxlcyBhcyBtYW5hZ2VkQWdlbnRGaWxlcywgc2V0dXBBZ2VudHMgfSBmcm9tICcuL2FnZW50cy5qcydcbmltcG9ydCB7IHdyaXRlVFNDb25maWcgfSBmcm9tICcuL2NvbXBpbGVyLmpzJ1xuaW1wb3J0IHsgZGVwZW5kYW50UGFja2FnZXMgfSBmcm9tICcuL2RlcGVuZGVuY2llcy5qcydcbmltcG9ydCB7IGlzRmlsZU5vdEZvdW5kIH0gZnJvbSAnLi9mcy5qcydcbmltcG9ydCB7IGluc3RhbGwgfSBmcm9tICcuL25wbS5qcydcbmltcG9ydCB0eXBlIHsgUmVwb3J0ZXIgfSBmcm9tICcuL3JlcG9ydGVyLmpzJ1xuaW1wb3J0IHsgdm90ZSB9IGZyb20gJy4vc2libGluZ3MuanMnXG5pbXBvcnQgeyBzZXR1cFNwZWxsaW5nIH0gZnJvbSAnLi9zcGVsbGluZy5qcydcbmltcG9ydCB7IHdyaXRlVGVzdENvbmZpZyB9IGZyb20gJy4vdGVzdGVyLmpzJ1xuXG5jb25zdCBkaXJzID0gWycudnNjb2RlJywgJy56ZWQnLCAnLmRldmNvbnRhaW5lcicsICcuaWRlYS9jb2RlU3R5bGVzLycsICcuaWRlYS9pbnNwZWN0aW9uUHJvZmlsZXMvJ11cbmNvbnN0IGZpbGVzID0gW1xuICAgICd0c2NvbmZpZy5qc29uJyxcbiAgICAnLnByZXR0aWVycmMuanNvbicsXG4gICAgJy5lZGl0b3Jjb25maWcnLFxuICAgICcubnZtcmMnLFxuICAgICcudnNjb2RlL3NldHRpbmdzLmpzb24nLFxuICAgICcudnNjb2RlL3Rhc2tzLmpzb24nLFxuICAgICcudnNjb2RlL2V4dGVuc2lvbnMuanNvbicsXG4gICAgJy56ZWQvc2V0dGluZ3MuanNvbicsXG4gICAgJy56ZWQvdGFza3MuanNvbicsXG4gICAgJy5kZXZjb250YWluZXIvRG9ja2VyZmlsZScsXG4gICAgJy5kZXZjb250YWluZXIvZGV2Y29udGFpbmVyLmpzb24nLFxuICAgICcuaWRlYS9jb21waWxlci54bWwnLFxuICAgICcuaWRlYS9jb2RlU3R5bGVzL2NvZGVTdHlsZUNvbmZpZy54bWwnLFxuICAgICcuaWRlYS9pbnNwZWN0aW9uUHJvZmlsZXMvUHJvamVjdF9EZWZhdWx0LnhtbCcsXG5dXG5jb25zdCBvdmVycmlkYWJsZUZpbGVzOiBbc3RyaW5nLCAoY29udGVudDogc3RyaW5nKSA9PiBib29sZWFuXVtdID0gW11cbmNvbnN0IGxlZ2FjeUZpbGVzOiAoc3RyaW5nIHwgW3N0cmluZywgc3RyaW5nXSlbXSA9IFtcbiAgICAnLnByZXR0aWVycmMnLFxuICAgICdEb2NrZXJmaWxlLmludGVncmF0aW9uJyxcbiAgICAnLmVzbGludHJjLmpzb24nLFxuICAgICdlc2xpbnQuY29uZmlnLmpzJyxcbiAgICBbJy5naXRhdHRyaWJ1dGVzJywgJyogdGV4dD1hdXRvIGVvbD1sZlxcbiddLFxuXVxuXG5jb25zdCBtYW5hZ2VkRmlsZXMgPSBbXG4gICAgJy5naXRpZ25vcmUnLFxuICAgIC4uLmZpbGVzLFxuICAgIC4uLmxlZ2FjeUZpbGVzLm1hcChsZiA9PiAoQXJyYXkuaXNBcnJheShsZikgPyBsZlswXSA6IGxmKSksXG4gICAgJ2NzcGVsbC5qc29uJyxcbiAgICAnZXNsaW50LmNvbmZpZy5tanMnLFxuICAgICcubW9jaGFyYy5qc29uJyxcbiAgICAuLi5tYW5hZ2VkQWdlbnRGaWxlcyxcbl1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByZXBhcmUoKSB7XG4gICAgYXdhaXQgY3JlYXRlVGVtcGxhdGUoKVxuICAgIGF3YWl0IG1ha2VXaW5kb3dzTnBtUGFja0ZyaWVuZGx5KCd0ZW1wbGF0ZScpXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVRlbXBsYXRlKCkge1xuICAgIGF3YWl0IHJtKCd0ZW1wbGF0ZScsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KVxuICAgIGF3YWl0IG1rZGlyKCd0ZW1wbGF0ZScpXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoZGlycy5tYXAoZGlyID0+IG1rZGlyKGpvaW4oJ3RlbXBsYXRlJywgZGlyKSwgeyByZWN1cnNpdmU6IHRydWUgfSkpKVxuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBbLi4uZmlsZXMsIC4uLm92ZXJyaWRhYmxlRmlsZXMubWFwKGYgPT4gZlswXSldLm1hcChmaWxlID0+XG4gICAgICAgICAgICBjb3B5RmlsZShmaWxlLCBqb2luKCd0ZW1wbGF0ZScsIGZpbGUpKSxcbiAgICAgICAgKSxcbiAgICApXG4gICAgYXdhaXQgd3JpdGVGaWxlKFxuICAgICAgICAndGVtcGxhdGUvZ2l0aWdub3JlJyxcbiAgICAgICAgW1xuICAgICAgICAgICAgLi4uZmlsZXMubWFwKGYgPT4gYC8ke2Z9YCksXG4gICAgICAgICAgICAuLi4oYXdhaXQgcmVhZEZpbGUoJy5naXRpZ25vcmUnLCAndXRmLTgnKSlcbiAgICAgICAgICAgICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAgICAgICAgICAgLmZpbHRlcihsID0+ICEhbCAmJiBsLnRyaW0oKSAhPT0gJy90ZW1wbGF0ZScgJiYgbC50cmltKCkgIT09ICchL2VzbGludC5jb25maWcubWpzJyksXG4gICAgICAgICAgICAnL2VzbGludC5jb25maWcubWpzJyxcbiAgICAgICAgICAgICcvLmdpdGlnbm9yZScsXG4gICAgICAgICAgICAnJyxcbiAgICAgICAgXS5qb2luKCdcXG4nKSxcbiAgICApXG4gICAgYXdhaXQgd3JpdGVGaWxlKFxuICAgICAgICAndGVtcGxhdGUvZXNsaW50LmNvbmZpZycsXG4gICAgICAgIChhd2FpdCByZWFkRmlsZSgnZXNsaW50LmNvbmZpZy5tanMnLCAndXRmLTgnKSlcbiAgICAgICAgICAgIC5zcGxpdCgnXFxuJylcbiAgICAgICAgICAgIC5tYXAobCA9PlxuICAgICAgICAgICAgICAgIGxcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgICAgICAgICAvaW1wb3J0IFxceyBbXn1dKyBcXH0gZnJvbSAnXFwuXFwvbGliXFwvZXNsaW50LWNvbmZpZy5qcycvdSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGBpbXBvcnQgeyBjb25maWd1cmF0aW9uIH0gZnJvbSAnQHJpZGRhbmNlL2Vudi9saWIvZXNsaW50LWNvbmZpZy5qcydgLFxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIC50cmltKCksXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuam9pbignXFxuJyksXG4gICAgKVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0dXAodGFyZ2V0RGlyOiBzdHJpbmcsIGZpcnN0SW5zdGFsbDogYm9vbGVhbiwgbXlzZWxmOiBib29sZWFuKSB7XG4gICAgaWYgKGZpcnN0SW5zdGFsbCAmJiAhbXlzZWxmKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgICAgIGNvbnN0IG1vZCA9IGNvbnN0YW50cy5SX09LIHwgY29uc3RhbnRzLldfT0tcbiAgICAgICAgY29uc3QgYWNjZXNzUmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFxuICAgICAgICAgICAgbWFuYWdlZEZpbGVzLm1hcChmID0+IGFjY2Vzcyhqb2luKHRhcmdldERpciwgZiksIG1vZCkpLFxuICAgICAgICApXG4gICAgICAgIGNvbnN0IGV4aXN0aW5nOiBzdHJpbmdbXSA9IFtdXG4gICAgICAgIGFjY2Vzc1Jlc3VsdC5mb3JFYWNoKChyLCBpeCkgPT4ge1xuICAgICAgICAgICAgaWYgKHIuc3RhdHVzID09PSAnZnVsZmlsbGVkJykge1xuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICAgICAgZXhpc3RpbmcucHVzaChtYW5hZ2VkRmlsZXNbaXhdISlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgaWYgKGV4aXN0aW5nLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIH1cbiAgICB9XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobGVnYWN5RmlsZXMubWFwKGZpbGUgPT4gZW5zdXJlVW5saW5rZWQodGFyZ2V0RGlyLCBmaWxlKSkpXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoZGlycy5tYXAoZGlyID0+IG1rZGlyKGpvaW4odGFyZ2V0RGlyLCBkaXIpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KSkpXG4gICAgY29uc3QgZGVwZW5kZW5jaWVzID0gZGVwZW5kYW50UGFja2FnZXModGFyZ2V0RGlyKVxuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgLi4uKG15c2VsZiA/IFtdIDogW2NvcHlGcm9tVGVtcGxhdGUodGFyZ2V0RGlyKV0pLFxuICAgICAgICBzZXR1cFNwZWxsaW5nKHRhcmdldERpciksXG4gICAgICAgIHdyaXRlVGVzdENvbmZpZyh0YXJnZXREaXIsIGRlcGVuZGVuY2llcyksXG4gICAgICAgIHN5bmNHaXRVc2VyKHRhcmdldERpciksXG4gICAgICAgIHNldHVwQWdlbnRzKHRhcmdldERpciwgZGVwZW5kZW5jaWVzLCBteXNlbGYpLFxuICAgICAgICBtYWtlV2luZG93c05wbVBhY2tBbmREZXZjb250YWluZXJGcmllbmRseSh0YXJnZXREaXIpLFxuICAgICAgICBlbnN1cmVVbmxpbmtlZCh0YXJnZXREaXIsICcudGltZXN0YW1wcy5qc29uJyksXG4gICAgXSlcbiAgICBhd2FpdCB3cml0ZVRTQ29uZmlnKHRhcmdldERpciwgZGVwZW5kZW5jaWVzKVxuICAgIHJldHVybiBbXVxufVxuXG5hc3luYyBmdW5jdGlvbiBjb3B5RnJvbVRlbXBsYXRlKHRhcmdldERpcjogc3RyaW5nKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoZmlsZXMubWFwKGZpbGUgPT4gY29weUZpbGUoam9pbigndGVtcGxhdGUnLCBmaWxlKSwgam9pbih0YXJnZXREaXIsIGZpbGUpKSkpXG4gICAgYXdhaXQgY29weUZpbGUoJ3RlbXBsYXRlL2dpdGlnbm9yZScsIGpvaW4odGFyZ2V0RGlyLCAnLmdpdGlnbm9yZScpKVxuICAgIGF3YWl0IGNvcHlGaWxlKCd0ZW1wbGF0ZS9lc2xpbnQuY29uZmlnJywgam9pbih0YXJnZXREaXIsICdlc2xpbnQuY29uZmlnLm1qcycpKVxuICAgIGZvciAoY29uc3QgW2ZpbGUsIGJlbG9uZ3NIZXJlXSBvZiBvdmVycmlkYWJsZUZpbGVzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHJlYWRGaWxlKGpvaW4odGFyZ2V0RGlyLCBmaWxlKSwgJ3V0Zi04JylcbiAgICAgICAgICAgIGlmICghYmVsb25nc0hlcmUoZXhpc3RpbmcpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKCFpc0ZpbGVOb3RGb3VuZChlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IGVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBjb3B5RmlsZShqb2luKCd0ZW1wbGF0ZScsIGZpbGUpLCBqb2luKHRhcmdldERpciwgZmlsZSkpXG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBzeW5jR2l0VXNlcihwYXRoOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBbd3MsIGNvcmUsIC4uLnNlY3Rpb25zXSA9IChhd2FpdCByZWFkRmlsZShqb2luKHBhdGgsICcuZ2l0L2NvbmZpZycpLCAndXRmLTgnKSkuc3BsaXQoXG4gICAgICAgICAgICAnWycsXG4gICAgICAgIClcbiAgICAgICAgaWYgKCF3cyB8fCAhY29yZSB8fCBzZWN0aW9uc1swXT8uc3RhcnRzV2l0aCgndXNlcl0nKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXNlciA9IGF3YWl0IHZvdGUocGF0aCwgJy5naXQvY29uZmlnJywgY29udGVudCA9PlxuICAgICAgICAgICAgY29udGVudFxuICAgICAgICAgICAgICAgIC5zcGxpdCgnWycpXG4gICAgICAgICAgICAgICAgLmZpbHRlcihzZWN0aW9uID0+IHNlY3Rpb24uc3RhcnRzV2l0aCgndXNlcl0nKSlcbiAgICAgICAgICAgICAgICAuam9pbignWycpLFxuICAgICAgICApXG4gICAgICAgIGlmICghdXNlcikge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgd3JpdGVGaWxlKGpvaW4ocGF0aCwgJy5naXQvY29uZmlnJyksIFt3cywgY29yZSwgdXNlciwgLi4uc2VjdGlvbnNdLmpvaW4oJ1snKSwgJ3V0Zi04JylcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChpc0ZpbGVOb3RGb3VuZChlKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZVxuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVuaW5zdGFsbChyZXBvcnRlcjogUmVwb3J0ZXIsIHRhcmdldERpcjogc3RyaW5nKSB7XG4gICAgcmVwb3J0ZXIuc3RhdHVzKCdVbmluc3RhbGxpbmcuLi4nKVxuICAgIGNvbnN0IHBhY2thZ2VKc29uID0gSlNPTi5wYXJzZShhd2FpdCByZWFkRmlsZShqb2luKHRhcmdldERpciwgJ3BhY2thZ2UuanNvbicpLCAndXRmLTgnKSkgYXMge1xuICAgICAgICBzY3JpcHRzPzogeyBbczogc3RyaW5nXTogc3RyaW5nIH1cbiAgICAgICAgZGV2RGVwZW5kZW5jaWVzPzoge1xuICAgICAgICAgICAgJ0ByaWRkYW5jZS9lbnYnPzogc3RyaW5nXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhd2FpdCBlbnN1cmVVbmxpbmtlZCh0YXJnZXREaXIsICcudGltZXN0YW1wcy5qc29uJylcblxuICAgIGF3YWl0IHdyaXRlRmlsZShcbiAgICAgICAgam9pbih0YXJnZXREaXIsICcuZ2l0aWdub3JlJyksXG4gICAgICAgIGAuRFNfU3RvcmVcbm5vZGVfbW9kdWxlcy9cbiouanNcbiouanMubWFwXG4qLmQudHNcbmAsXG4gICAgICAgICd1dGYtOCcsXG4gICAgKVxuXG4gICAgbGV0IG1vZGlmaWVkID0gZmFsc2VcbiAgICBpZiAocGFja2FnZUpzb24uc2NyaXB0cykge1xuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhwYWNrYWdlSnNvbi5zY3JpcHRzKSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlLmluY2x1ZGVzKCdAcmlkZGFuY2UvJykgfHwgdmFsdWUuc3RhcnRzV2l0aCgncmlkZGFuY2UtJykpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgcGFja2FnZUpzb24uc2NyaXB0c1trZXldXG4gICAgICAgICAgICAgICAgbW9kaWZpZWQgPSB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHBhY2thZ2VKc29uLmRldkRlcGVuZGVuY2llcz8uWydAcmlkZGFuY2UvZW52J10pIHtcbiAgICAgICAgZGVsZXRlIHBhY2thZ2VKc29uLmRldkRlcGVuZGVuY2llc1snQHJpZGRhbmNlL2VudiddXG4gICAgICAgIG1vZGlmaWVkID0gdHJ1ZVxuICAgICAgICBpZiAoT2JqZWN0LmtleXMocGFja2FnZUpzb24uZGV2RGVwZW5kZW5jaWVzKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGRlbGV0ZSBwYWNrYWdlSnNvbi5kZXZEZXBlbmRlbmNpZXNcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAobW9kaWZpZWQpIHtcbiAgICAgICAgYXdhaXQgd3JpdGVGaWxlKFxuICAgICAgICAgICAgam9pbih0YXJnZXREaXIsICdwYWNrYWdlLmpzb24nKSxcbiAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHBhY2thZ2VKc29uLCB1bmRlZmluZWQsICcgICcpLFxuICAgICAgICAgICAgJ3V0Zi04JyxcbiAgICAgICAgKVxuICAgICAgICBhd2FpdCBpbnN0YWxsKHJlcG9ydGVyLCB0YXJnZXREaXIpXG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBtYWtlV2luZG93c05wbVBhY2tBbmREZXZjb250YWluZXJGcmllbmRseSh0YXJnZXREaXI6IHN0cmluZykge1xuICAgIGlmIChwbGF0Zm9ybSgpICE9PSAnd2luMzInKSB7XG4gICAgICAgIHJldHVyblxuICAgIH1cbiAgICBjb25zdCBwYXRoID0gam9pbih0YXJnZXREaXIsICcuZ2l0JywgJ2luZm8nLCAnYXR0cmlidXRlcycpXG4gICAgaWYgKCEoYXdhaXQgc3RhdChwYXRoKS5jYXRjaChpc0ZpbGVOb3RGb3VuZCkpKSB7XG4gICAgICAgIHJldHVyblxuICAgIH1cbiAgICBhd2FpdCBta2Rpcihqb2luKHRhcmdldERpciwgJy5naXQnLCAnaW5mbycpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuICAgIGF3YWl0IHdyaXRlRmlsZShwYXRoLCBzb3VyY2VFeHRlbnNpb25zLm1hcChleHQgPT4gYCoke2V4dH0gdGV4dD1hdXRvIGVvbD1sZlxcbmApLmpvaW4oJycpKVxuICAgIGZvciBhd2FpdCAoY29uc3Qgc291cmNlRmlsZSBvZiBmaW5kRmlsZXModGFyZ2V0RGlyLCBpc1NvdXJjZSkpIHtcbiAgICAgICAgYXdhaXQgZG9zMnVuaXgoc291cmNlRmlsZSlcbiAgICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1ha2VXaW5kb3dzTnBtUGFja0ZyaWVuZGx5KHRhcmdldERpcjogc3RyaW5nKSB7XG4gICAgaWYgKHBsYXRmb3JtKCkgIT09ICd3aW4zMicpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGZvciBhd2FpdCAoY29uc3Qgc291cmNlRmlsZSBvZiBmaW5kRmlsZXModGFyZ2V0RGlyLCAoKSA9PiB0cnVlKSkge1xuICAgICAgICBhd2FpdCBkb3MydW5peChzb3VyY2VGaWxlKVxuICAgIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZG9zMnVuaXgoZmlsZTogc3RyaW5nKSB7XG4gICAgY29uc3QgZG9zID0gYXdhaXQgcmVhZEZpbGUoZmlsZSwgJ3V0Zi04JylcbiAgICBjb25zdCB1bml4ID0gZG9zLnJlcGxhY2VBbGwoRU9MLCAnXFxuJylcbiAgICBpZiAodW5peC5sZW5ndGggIT09IGRvcy5sZW5ndGgpIHtcbiAgICAgICAgYXdhaXQgd3JpdGVGaWxlKGZpbGUsIHVuaXgsICd1dGYtOCcpXG4gICAgfVxufVxuXG5jb25zdCBzb3VyY2VFeHRlbnNpb25zID0gWycudHMnLCAnLmpzb24nLCAnLnR4dCcsICcubWQnXVxuY29uc3Qgb3RoZXJTb3VyY2VzID0gbmV3IFNldChbJ0xJQ0VOU0UnLCAnZXNsaW50LmNvbmZpZy5tanMnXSlcblxuZnVuY3Rpb24gaXNTb3VyY2UoZmlsZTogRGlyZW50KSB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgKHNvdXJjZUV4dGVuc2lvbnMuc29tZShleHQgPT4gZmlsZS5uYW1lLmVuZHNXaXRoKGV4dCkpICYmICFmaWxlLm5hbWUuZW5kc1dpdGgoJy5kLnRzJykpIHx8XG4gICAgICAgIG90aGVyU291cmNlcy5oYXMoZmlsZS5uYW1lKVxuICAgIClcbn1cblxuYXN5bmMgZnVuY3Rpb24qIGZpbmRGaWxlcyhcbiAgICBwYXRoOiBzdHJpbmcsXG4gICAgcHJlZGljYXRlOiAoZW50cnk6IERpcmVudCkgPT4gYm9vbGVhbixcbik6IEFzeW5jR2VuZXJhdG9yPHN0cmluZywgdm9pZD4ge1xuICAgIGNvbnN0IGVudHJpZXMgPSBhd2FpdCByZWFkZGlyKHBhdGgsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KVxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICBpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSAmJiBlbnRyeS5uYW1lICE9PSAnbm9kZV9tb2R1bGVzJykge1xuICAgICAgICAgICAgeWllbGQqIGZpbmRGaWxlcyhqb2luKHBhdGgsIGVudHJ5Lm5hbWUpLCBwcmVkaWNhdGUpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVudHJ5LmlzRmlsZSgpICYmIHByZWRpY2F0ZShlbnRyeSkpIHtcbiAgICAgICAgICAgIHlpZWxkIGpvaW4ocGF0aCwgZW50cnkubmFtZSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZW5zdXJlVW5saW5rZWQoZGlyOiBzdHJpbmcsIGZpbGU6IHN0cmluZyB8IFtzdHJpbmcsIHN0cmluZ10pIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShmaWxlKSkge1xuICAgICAgICAgICAgY29uc3QgW2ZpbGVuYW1lLCBleHBlY3RlZENvbnRlbnRzXSA9IGZpbGVcbiAgICAgICAgICAgIGNvbnN0IHBhdGggPSBqb2luKGRpciwgZmlsZW5hbWUpXG4gICAgICAgICAgICBpZiAoKGF3YWl0IHJlYWRGaWxlKHBhdGgsICd1dGYtOCcpKSAhPT0gZXhwZWN0ZWRDb250ZW50cykge1xuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgdW5saW5rKGpvaW4oZGlyLCBmaWxlbmFtZSkpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB1bmxpbmsoam9pbihkaXIsIGZpbGUpKVxuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoaXNGaWxlTm90Rm91bmQoZSkpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIHRocm93IGVcbiAgICB9XG59XG4iXX0=