Files
personal_site/frontend/node_modules/@aws-cdk/cx-api/build-tools/flag-report.js
T

199 lines
28 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Generate FEATURE_FLAGS.md, a report of all current feature flags
*/
const fs_1 = require("fs");
const path = require("path");
const validate_flags_1 = require("./validate-flags");
const feats = require("../lib/features");
const flag_modeling_1 = require("../lib/private/flag-modeling");
async function main() {
(0, validate_flags_1.validateFlags)();
await updateMarkdownFile(path.join(__dirname, '..', 'FEATURE_FLAGS.md'), {
table: flagsTable(),
details: flagsDetails(),
json: recommendedJson(),
removed: removedFlags(),
diff: changedFlags(),
migratejson: migrateJson(),
});
// Write to the package root
await updateRecommendedFlagsFile(path.join(__dirname, '..', '..', 'recommended-feature-flags.json'));
}
function flagsTable() {
return renderTable([
['Flag', 'Summary', 'Since', 'Type'],
...v2flags().map(([name, flag]) => [
renderLink(mdEsc(name), githubHeadingLink(flagDetailsHeading(name, flag))),
flag.summary,
flag.introducedIn.v2 ?? '',
renderType(flag.type, 'short'),
]),
]);
}
function removedFlags() {
const removedInV2 = flags(flag => flag.introducedIn.v2 === undefined && flag.introducedIn.v1 !== undefined);
return renderTable([
['Flag', 'Summary', 'Type', 'Since'],
...removedInV2.map(([name, flag]) => [
renderLink(mdEsc(name), githubHeadingLink(flagDetailsHeading(name, flag))),
flag.summary,
renderType(flag.type, 'short'),
flag.introducedIn.v1 ?? '',
]),
]);
}
function changedFlags() {
const changedInV2 = flags(flag => !!flag.unconfiguredBehavesLike?.v2 && !!flag.introducedIn.v2);
return renderTable([
['Flag', 'Summary', 'Type', 'Since', 'v1 default', 'v2 default'],
...changedInV2.map(([name, flag]) => [
renderLink(mdEsc(name), githubHeadingLink(flagDetailsHeading(name, flag))),
flag.summary,
renderType(flag.type, 'short'),
flag.introducedIn.v1 ?? '',
renderValue(false),
renderValue(flag.unconfiguredBehavesLike?.v2),
]),
]);
}
function migrateJson() {
const changedInV2 = flags(flag => !!flag.unconfiguredBehavesLike?.v2 && !!flag.introducedIn.v2 && !!flag.introducedIn.v1);
const context = Object.fromEntries(changedInV2.map(([name, _]) => [name, false]));
return [
'```json',
JSON.stringify({ context }, undefined, 2),
'```',
].join('\n');
}
function flagsDetails() {
const allFlags = flags(_ => true);
return allFlags.flatMap(([name, flag]) => [
`### ${flagDetailsHeading(name, flag)}`,
'',
`*${flag.summary}*`,
'',
`Flag type: ${renderType(flag.type, 'long')}`,
'',
dedent(flag.detailsMd),
'',
renderTable([
['Since', 'Unset behaves like', 'Recommended value'],
// V1
flag.introducedIn.v1
? [flag.introducedIn.v1, renderValue(false), renderValue(flag.recommendedValue)]
: ['(not in v1)', '', ''],
// V2
flag.introducedIn.v2
? [flag.introducedIn.v2, renderValue(flag.unconfiguredBehavesLike?.v2 ?? false), renderValue(flag.recommendedValue)]
: flag.unconfiguredBehavesLike?.v2 !== undefined
? ['(not configurable in v2)', renderValue(flag.unconfiguredBehavesLike?.v2), '']
: ['(not in v2)', '', ''],
]),
...oldBehavior(flag) ? [
`**Compatibility with old behavior:** ${oldBehavior(flag)}`,
'',
] : [],
'',
]).join('\n');
}
function oldBehavior(flag) {
switch (flag.type) {
case flag_modeling_1.FlagType.ApiDefault: return flag.compatibilityWithOldBehaviorMd;
case flag_modeling_1.FlagType.BugFix: return flag.compatibilityWithOldBehaviorMd;
case flag_modeling_1.FlagType.VisibleContext: return undefined;
case flag_modeling_1.FlagType.Temporary: return flag.compatibilityWithOldBehaviorMd;
}
}
function recommendedJson() {
const sortedFlags = Object.fromEntries(Object.entries(feats.CURRENTLY_RECOMMENDED_FLAGS).sort(([a], [b]) => a.localeCompare(b)));
return [
'```json',
JSON.stringify({ context: sortedFlags }, undefined, 2),
'```',
].join('\n');
}
function v2flags() {
return flags(flag => flag.introducedIn.v2 !== undefined);
}
function flags(pred) {
const entries = Object.entries(feats.FLAGS)
.filter(([_, flag]) => pred(flag));
entries.sort((a, b) => firstCmp(
// Sort by versions first
(0, flag_modeling_1.compareVersions)(a[1].introducedIn.v2, b[1].introducedIn.v2), (0, flag_modeling_1.compareVersions)(a[1].introducedIn.v1, b[1].introducedIn.v1),
// Then sort by name
a[0].localeCompare(b[0])));
return entries;
}
function renderType(type, flavor) {
switch (type) {
case flag_modeling_1.FlagType.ApiDefault: return longShort('New default behavior', 'new default');
case flag_modeling_1.FlagType.BugFix: return longShort('Backwards incompatible bugfix', 'fix');
case flag_modeling_1.FlagType.VisibleContext: return longShort('Configuration option', 'config');
case flag_modeling_1.FlagType.Temporary: return longShort('Temporary flag', 'temporary');
}
function longShort(long, short) {
return flavor === 'long' ? long : short;
}
}
function renderTable(rows) {
return [
'',
'| ' + rows[0].join(' | ') + ' |',
'| ' + rows[0].map(_ => '-----').join(' | ') + ' |',
...rows.slice(1).map(row => '| ' + row.join(' | ') + ' |'),
'',
].join('\n');
}
/**
* Return the heading that will be used to caption this flag's details
*/
function flagDetailsHeading(name, _) {
return name;
}
/**
* Return a link that is valid on GitHub to refer to a heading
*/
function githubHeadingLink(heading) {
return `#${heading.toLowerCase().replace(/ /g, '-').replace(/[^a-z0-9_-]/g, '')}`;
}
/**
* Remove shared leading whitespace from all non-empty lines
*/
function dedent(body) {
const lines = body.split('\n').filter((x) => x.trim() !== '');
const leadingWs = lines.map(x => x.match(/^ */)?.[0].length ?? 0);
const sharedWs = Math.min(...leadingWs);
const re = new RegExp('^' + ' '.repeat(sharedWs), 'mg');
return body.replace(re, '').trim();
}
function renderValue(x) {
return `\`${JSON.stringify(x)}\``;
}
function renderLink(caption, link) {
return `[${caption}](${link})`;
}
function mdEsc(x) {
return x.replace(/_/g, '\\_');
}
async function updateMarkdownFile(filename, sections) {
let contents = await fs_1.promises.readFile(filename, { encoding: 'utf-8' });
for (const [section, value] of Object.entries(sections)) {
const re = new RegExp(`<!-- BEGIN ${section} -->(.*)<!-- END ${section} -->`, 's');
contents = contents.replace(re, `<!-- BEGIN ${section} -->\n${value}\n<!-- END ${section} -->`);
}
await fs_1.promises.writeFile(filename, contents, { encoding: 'utf-8' });
}
async function updateRecommendedFlagsFile(filename) {
await fs_1.promises.writeFile(filename, JSON.stringify(feats.CURRENTLY_RECOMMENDED_FLAGS, undefined, 2), { encoding: 'utf-8' });
}
function firstCmp(...xs) {
return xs.find(x => x !== 0) ?? 0;
}
main().catch(e => {
console.error(e);
process.exitCode = 1;
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxhZy1yZXBvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJmbGFnLXJlcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBOztHQUVHO0FBQ0gsMkJBQW9DO0FBQ3BDLDZCQUE2QjtBQUM3QixxREFBaUQ7QUFDakQseUNBQXlDO0FBRXpDLGdFQUF5RTtBQUV6RSxLQUFLLFVBQVUsSUFBSTtJQUNqQixJQUFBLDhCQUFhLEdBQUUsQ0FBQztJQUVoQixNQUFNLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxrQkFBa0IsQ0FBQyxFQUFFO1FBQ3ZFLEtBQUssRUFBRSxVQUFVLEVBQUU7UUFDbkIsT0FBTyxFQUFFLFlBQVksRUFBRTtRQUN2QixJQUFJLEVBQUUsZUFBZSxFQUFFO1FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUU7UUFDdkIsSUFBSSxFQUFFLFlBQVksRUFBRTtRQUNwQixXQUFXLEVBQUUsV0FBVyxFQUFFO0tBQzNCLENBQUMsQ0FBQztJQUVILDRCQUE0QjtJQUM1QixNQUFNLDBCQUEwQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsZ0NBQWdDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZHLENBQUM7QUFFRCxTQUFTLFVBQVU7SUFDakIsT0FBTyxXQUFXLENBQUM7UUFDakIsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUM7UUFDcEMsR0FBRyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFLENBQ2hDO1lBQ0UsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUMxRSxJQUFJLENBQUMsT0FBTztZQUNaLElBQUksQ0FBQyxZ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RUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtJQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakIsT0FBTyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDdkIsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlIEZFQVRVUkVfRkxBR1MubWQsIGEgcmVwb3J0IG9mIGFsbCBjdXJyZW50IGZlYXR1cmUgZmxhZ3NcbiAqL1xuaW1wb3J0IHsgcHJvbWlzZXMgYXMgZnMgfSBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgdmFsaWRhdGVGbGFncyB9IGZyb20gJy4vdmFsaWRhdGUtZmxhZ3MnO1xuaW1wb3J0ICogYXMgZmVhdHMgZnJvbSAnLi4vbGliL2ZlYXR1cmVzJztcbmltcG9ydCB0eXBlIHsgRmxhZ0luZm8gfSBmcm9tICcuLi9saWIvcHJpdmF0ZS9mbGFnLW1vZGVsaW5nJztcbmltcG9ydCB7IEZsYWdUeXBlLCBjb21wYXJlVmVyc2lvbnMgfSBmcm9tICcuLi9saWIvcHJpdmF0ZS9mbGFnLW1vZGVsaW5nJztcblxuYXN5bmMgZnVuY3Rpb24gbWFpbigpIHtcbiAgdmFsaWRhdGVGbGFncygpO1xuXG4gIGF3YWl0IHVwZGF0ZU1hcmtkb3duRmlsZShwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAnRkVBVFVSRV9GTEFHUy5tZCcpLCB7XG4gICAgdGFibGU6IGZsYWdzVGFibGUoKSxcbiAgICBkZXRhaWxzOiBmbGFnc0RldGFpbHMoKSxcbiAgICBqc29uOiByZWNvbW1lbmRlZEpzb24oKSxcbiAgICByZW1vdmVkOiByZW1vdmVkRmxhZ3MoKSxcbiAgICBkaWZmOiBjaGFuZ2VkRmxhZ3MoKSxcbiAgICBtaWdyYXRlanNvbjogbWlncmF0ZUpzb24oKSxcbiAgfSk7XG5cbiAgLy8gV3JpdGUgdG8gdGhlIHBhY2thZ2Ugcm9vdFxuICBhd2FpdCB1cGRhdGVSZWNvbW1lbmRlZEZsYWdzRmlsZShwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAnLi4nLCAncmVjb21tZW5kZWQtZmVhdHVyZS1mbGFncy5qc29uJykpO1xufVxuXG5mdW5jdGlvbiBmbGFnc1RhYmxlKCkge1xuICByZXR1cm4gcmVuZGVyVGFibGUoW1xuICAgIFsnRmxhZycsICdTdW1tYXJ5JywgJ1NpbmNlJywgJ1R5cGUnXSxcbiAgICAuLi52MmZsYWdzKCkubWFwKChbbmFtZSwgZmxhZ10pID0+XG4gICAgICBbXG4gICAgICAgIHJlbmRlckxpbmsobWRFc2MobmFtZSksIGdpdGh1YkhlYWRpbmdMaW5rKGZsYWdEZXRhaWxzSGVhZGluZyhuYW1lLCBmbGFnKSkpLFxuICAgICAgICBmbGFnLnN1bW1hcnksXG4gICAgICAgIGZsYWcuaW50cm9kdWNlZEluLnYyID8/ICcnLFxuICAgICAgICByZW5kZXJUeXBlKGZsYWcudHlwZSwgJ3Nob3J0JyksXG4gICAgICBdLFxuICAgICksXG4gIF0pO1xufVxuXG5mdW5jdGlvbiByZW1vdmVkRmxhZ3MoKSB7XG4gIGNvbnN0IHJlbW92ZWRJblYyID0gZmxhZ3MoZmxhZyA9PiBmbGFnLmludHJvZHVjZWRJbi52MiA9PT0gdW5kZWZpbmVkICYmIGZsYWcuaW50cm9kdWNlZEluLnYxICE9PSB1bmRlZmluZWQpO1xuXG4gIHJldHVybiByZW5kZXJUYWJsZShbXG4gICAgWydGbGFnJywgJ1N1bW1hcnknLCAnVHlwZScsICdTaW5jZSddLFxuICAgIC4uLnJlbW92ZWRJblYyLm1hcCgoW25hbWUsIGZsYWddKSA9PiBbXG4gICAgICByZW5kZXJMaW5rKG1kRXNjKG5hbWUpLCBnaXRodWJIZWFkaW5nTGluayhmbGFnRGV0YWlsc0hlYWRpbmcobmFtZSwgZmxhZykpKSxcbiAgICAgIGZsYWcuc3VtbWFyeSxcbiAgICAgIHJlbmRlclR5cGUoZmxhZy50eXBlLCAnc2hvcnQnKSxcbiAgICAgIGZsYWcuaW50cm9kdWNlZEluLnYxID8/ICcnLFxuICAgIF0pLFxuICBdKTtcbn1cblxuZnVuY3Rpb24gY2hhbmdlZEZsYWdzKCkge1xuICBjb25zdCBjaGFuZ2VkSW5WMiA9IGZsYWdzKGZsYWcgPT4gISFmbGFnLnVuY29uZmlndXJlZEJlaGF2ZXNMaWtlPy52MiAmJiAhIWZsYWcuaW50cm9kdWNlZEluLnYyKTtcblxuICByZXR1cm4gcmVuZGVyVGFibGUoW1xuICAgIFsnRmxhZycsICdTdW1tYXJ5JywgJ1R5cGUnLCAnU2luY2UnLCAndjEgZGVmYXVsdCcsICd2MiBkZWZhdWx0J10sXG4gICAgLi4uY2hhbmdlZEluVjIubWFwKChbbmFtZSwgZmxhZ10pID0+IFtcbiAgICAgIHJlbmRlckxpbmsobWRFc2MobmFtZSksIGdpdGh1YkhlYWRpbmdMaW5rKGZsYWdEZXRhaWxzSGVhZGluZyhuYW1lLCBmbGFnKSkpLFxuICAgICAgZmxhZy5zdW1tYXJ5LFxuICAgICAgcmVuZGVyVHlwZShmbGFnLnR5cGUsICdzaG9ydCcpLFxuICAgICAgZmxhZy5pbnRyb2R1Y2VkSW4udjEgPz8gJycsXG4gICAgICByZW5kZXJWYWx1ZShmYWxzZSksXG4gICAgICByZW5kZXJWYWx1ZShmbGFnLnVuY29uZmlndXJlZEJlaGF2ZXNMaWtlPy52MiksXG4gICAgXSksXG4gIF0pO1xufVxuXG5mdW5jdGlvbiBtaWdyYXRlSnNvbigpIHtcbiAgY29uc3QgY2hhbmdlZEluVjIgPSBmbGFncyhmbGFnID0+ICEhZmxhZy51bmNvbmZpZ3VyZWRCZWhhdmVzTGlrZT8udjIgJiYgISFmbGFnLmludHJvZHVjZWRJbi52MiAmJiAhIWZsYWcuaW50cm9kdWNlZEluLnYxKTtcblxuICBjb25zdCBjb250ZXh0ID0gT2JqZWN0LmZyb21FbnRyaWVzKGNoYW5nZWRJblYyLm1hcCgoW25hbWUsIF9dKSA9PiBbbmFtZSwgZmFsc2VdKSk7XG5cbiAgcmV0dXJuIFtcbiAgICAnYGBganNvbicsXG4gICAgSlNPTi5zdHJpbmdpZnkoeyBjb250ZXh0IH0sIHVuZGVmaW5lZCwgMiksXG4gICAgJ2BgYCcsXG4gIF0uam9pbignXFxuJyk7XG59XG5cbmZ1bmN0aW9uIGZsYWdzRGV0YWlscygpIHtcbiAgY29uc3QgYWxsRmxhZ3MgPSBmbGFncyhfID0+IHRydWUpO1xuXG4gIHJldHVybiBhbGxGbGFncy5mbGF0TWFwKChbbmFtZSwgZmxhZ10pID0+IFtcbiAgICBgIyMjICR7ZmxhZ0RldGFpbHNIZWFkaW5nKG5hbWUsIGZsYWcpfWAsXG4gICAgJycsXG4gICAgYCoke2ZsYWcuc3VtbWFyeX0qYCxcbiAgICAnJyxcbiAgICBgRmxhZyB0eXBlOiAke3JlbmRlclR5cGUoZmxhZy50eXBlLCAnbG9uZycpfWAsXG4gICAgJycsXG4gICAgZGVkZW50KGZsYWcuZGV0YWlsc01kKSxcbiAgICAnJyxcbiAgICByZW5kZXJUYWJsZShbXG4gICAgICBbJ1NpbmNlJywgJ1Vuc2V0IGJlaGF2ZXMgbGlrZScsICdSZWNvbW1lbmRlZCB2YWx1ZSddLFxuXG4gICAgICAvLyBWMVxuICAgICAgZmxhZy5pbnRyb2R1Y2VkSW4udjFcbiAgICAgICAgPyBbZmxhZy5pbnRyb2R1Y2VkSW4udjEsIHJlbmRlclZhbHVlKGZhbHNlKSwgcmVuZGVyVmFsdWUoZmxhZy5yZWNvbW1lbmRlZFZhbHVlKV1cbiAgICAgICAgOiBbJyhub3QgaW4gdjEpJywgJycsICcnXSxcblxuICAgICAgLy8gVjJcbiAgICAgIGZsYWcuaW50cm9kdWNlZEluLnYyXG4gICAgICAgID8gW2ZsYWcuaW50cm9kdWNlZEluLnYyLCByZW5kZXJWYWx1ZShmbGFnLnVuY29uZmlndXJlZEJlaGF2ZXNMaWtlPy52MiA/PyBmYWxzZSksIHJlbmRlclZhbHVlKGZsYWcucmVjb21tZW5kZWRWYWx1ZSldXG4gICAgICAgIDogZmxhZy51bmNvbmZpZ3VyZWRCZWhhdmVzTGlrZT8udjIgIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gWycobm90IGNvbmZpZ3VyYWJsZSBpbiB2MiknLCByZW5kZXJWYWx1ZShmbGFnLnVuY29uZmlndXJlZEJlaGF2ZXNMaWtlPy52MiksICcnXVxuICAgICAgICAgIDogWycobm90IGluIHYyKScsICcnLCAnJ10sXG4gICAgXSksXG4gICAgLi4ub2xkQmVoYXZpb3IoZmxhZykgPyBbXG4gICAgICBgKipDb21wYXRpYmlsaXR5IHdpdGggb2xkIGJlaGF2aW9yOioqICR7b2xkQmVoYXZpb3IoZmxhZyl9YCxcbiAgICAgICcnLFxuICAgIF0gOiBbXSxcbiAgICAnJyxcbiAgXSkuam9pbignXFxuJyk7XG59XG5cbmZ1bmN0aW9uIG9sZEJlaGF2aW9yKGZsYWc6IEZsYWdJbmZvKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgc3dpdGNoIChmbGFnLnR5cGUpIHtcbiAgICBjYXNlIEZsYWdUeXBlLkFwaURlZmF1bHQ6IHJldHVybiBmbGFnLmNvbXBhdGliaWxpdHlXaXRoT2xkQmVoYXZpb3JNZDtcbiAgICBjYXNlIEZsYWdUeXBlLkJ1Z0ZpeDogcmV0dXJuIGZsYWcuY29tcGF0aWJpbGl0eVdpdGhPbGRCZWhhdmlvck1kO1xuICAgIGNhc2UgRmxhZ1R5cGUuVmlzaWJsZUNvbnRleHQ6IHJldHVybiB1bmRlZmluZWQ7XG4gICAgY2FzZSBGbGFnVHlwZS5UZW1wb3Jhcnk6IHJldHVybiBmbGFnLmNvbXBhdGliaWxpdHlXaXRoT2xkQmVoYXZpb3JNZDtcbiAgfVxufVxuXG5mdW5jdGlvbiByZWNvbW1lbmRlZEpzb24oKSB7XG4gIGNvbnN0IHNvcnRlZEZsYWdzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgIE9iamVjdC5lbnRyaWVzKGZlYXRzLkNVUlJFTlRMWV9SRUNPTU1FTkRFRF9GTEFHUykuc29ydCgoW2FdLCBbYl0pID0+IGEubG9jYWxlQ29tcGFyZShiKSksXG4gICk7XG4gIHJldHVybiBbXG4gICAgJ2BgYGpzb24nLFxuICAgIEpTT04uc3RyaW5naWZ5KHsgY29udGV4dDogc29ydGVkRmxhZ3MgfSwgdW5kZWZpbmVkLCAyKSxcbiAgICAnYGBgJyxcbiAgXS5qb2luKCdcXG4nKTtcbn1cblxuZnVuY3Rpb24gdjJmbGFncygpIHtcbiAgcmV0dXJuIGZsYWdzKGZsYWcgPT4gZmxhZy5pbnRyb2R1Y2VkSW4udjIgIT09IHVuZGVmaW5lZCk7XG59XG5cbmZ1bmN0aW9uIGZsYWdzKHByZWQ6ICh4OiBGbGFnSW5mbykgPT4gYm9vbGVhbikge1xuICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXMoZmVhdHMuRkxBR1MpXG4gICAgLmZpbHRlcigoW18sIGZsYWddKSA9PiBwcmVkKGZsYWcpKTtcblxuICBlbnRyaWVzLnNvcnQoKGEsIGIpID0+IGZpcnN0Q21wKFxuICAgIC8vIFNvcnQgYnkgdmVyc2lvbnMgZmlyc3RcbiAgICBjb21wYXJlVmVyc2lvbnMoYVsxXS5pbnRyb2R1Y2VkSW4udjIsIGJbMV0uaW50cm9kdWNlZEluLnYyKSxcbiAgICBjb21wYXJlVmVyc2lvbnMoYVsxXS5pbnRyb2R1Y2VkSW4udjEsIGJbMV0uaW50cm9kdWNlZEluLnYxKSxcbiAgICAvLyBUaGVuIHNvcnQgYnkgbmFtZVxuICAgIGFbMF0ubG9jYWxlQ29tcGFyZShiWzBdKSkpO1xuXG4gIHJldHVybiBlbnRyaWVzO1xufVxuXG5mdW5jdGlvbiByZW5kZXJUeXBlKHR5cGU6IEZsYWdUeXBlLCBmbGF2b3I6ICdzaG9ydCcgfCAnbG9uZycpOiBzdHJpbmcge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIEZsYWdUeXBlLkFwaURlZmF1bHQ6IHJldHVybiBsb25nU2hvcnQoJ05ldyBkZWZhdWx0IGJlaGF2aW9yJywgJ25ldyBkZWZhdWx0Jyk7XG4gICAgY2FzZSBGbGFnVHlwZS5CdWdGaXg6IHJldHVybiBsb25nU2hvcnQoJ0JhY2t3YXJkcyBpbmNvbXBhdGlibGUgYnVnZml4JywgJ2ZpeCcpO1xuICAgIGNhc2UgRmxhZ1R5cGUuVmlzaWJsZUNvbnRleHQ6IHJldHVybiBsb25nU2hvcnQoJ0NvbmZpZ3VyYXRpb24gb3B0aW9uJywgJ2NvbmZpZycpO1xuICAgIGNhc2UgRmxhZ1R5cGUuVGVtcG9yYXJ5OiByZXR1cm4gbG9uZ1Nob3J0KCdUZW1wb3JhcnkgZmxhZycsICd0ZW1wb3JhcnknKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxvbmdTaG9ydChsb25nOiBzdHJpbmcsIHNob3J0OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gZmxhdm9yID09PSAnbG9uZycgPyBsb25nIDogc2hvcnQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyVGFibGUocm93czogc3RyaW5nW11bXSkge1xuICByZXR1cm4gW1xuICAgICcnLFxuICAgICd8ICcgKyByb3dzWzBdLmpvaW4oJyB8ICcpICsgJyB8JyxcbiAgICAnfCAnICsgcm93c1swXS5tYXAoXyA9PiAnLS0tLS0nKS5qb2luKCcgfCAnKSArICcgfCcsXG4gICAgLi4ucm93cy5zbGljZSgxKS5tYXAocm93ID0+ICd8ICcgKyByb3cuam9pbignIHwgJykgKyAnIHwnKSxcbiAgICAnJyxcbiAgXS5qb2luKCdcXG4nKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGhlYWRpbmcgdGhhdCB3aWxsIGJlIHVzZWQgdG8gY2FwdGlvbiB0aGlzIGZsYWcncyBkZXRhaWxzXG4gKi9cbmZ1bmN0aW9uIGZsYWdEZXRhaWxzSGVhZGluZyhuYW1lOiBzdHJpbmcsIF86IEZsYWdJbmZvKSB7XG4gIHJldHVybiBuYW1lO1xufVxuXG4vKipcbiAqIFJldHVybiBhIGxpbmsgdGhhdCBpcyB2YWxpZCBvbiBHaXRIdWIgdG8gcmVmZXIgdG8gYSBoZWFkaW5nXG4gKi9cbmZ1bmN0aW9uIGdpdGh1YkhlYWRpbmdMaW5rKGhlYWRpbmc6IHN0cmluZykge1xuICByZXR1cm4gYCMke2hlYWRpbmcudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC8gL2csICctJykucmVwbGFjZSgvW15hLXowLTlfLV0vZywgJycpfWA7XG59XG5cbi8qKlxuICogUmVtb3ZlIHNoYXJlZCBsZWFkaW5nIHdoaXRlc3BhY2UgZnJvbSBhbGwgbm9uLWVtcHR5IGxpbmVzXG4gKi9cbmZ1bmN0aW9uIGRlZGVudChib2R5OiBzdHJpbmcpIHtcbiAgY29uc3QgbGluZXMgPSBib2R5LnNwbGl0KCdcXG4nKS5maWx0ZXIoKHgpID0+IHgudHJpbSgpICE9PSAnJyk7XG4gIGNvbnN0IGxlYWRpbmdXcyA9IGxpbmVzLm1hcCh4ID0+IHgubWF0Y2goL14gKi8pPy5bMF0ubGVuZ3RoID8/IDApO1xuICBjb25zdCBzaGFyZWRXcyA9IE1hdGgubWluKC4uLmxlYWRpbmdXcyk7XG4gIGNvbnN0IHJlID0gbmV3IFJlZ0V4cCgnXicgKyAnICcucmVwZWF0KHNoYXJlZFdzKSwgJ21nJyk7XG4gIHJldHVybiBib2R5LnJlcGxhY2UocmUsICcnKS50cmltKCk7XG59XG5cbmZ1bmN0aW9uIHJlbmRlclZhbHVlKHg6IGFueSkge1xuICByZXR1cm4gYFxcYCR7SlNPTi5zdHJpbmdpZnkoeCl9XFxgYDtcbn1cblxuZnVuY3Rpb24gcmVuZGVyTGluayhjYXB0aW9uOiBzdHJpbmcsIGxpbms6IHN0cmluZykge1xuICByZXR1cm4gYFske2NhcHRpb259XSgke2xpbmt9KWA7XG59XG5cbmZ1bmN0aW9uIG1kRXNjKHg6IHN0cmluZykge1xuICByZXR1cm4geC5yZXBsYWNlKC9fL2csICdcXFxcXycpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB1cGRhdGVNYXJrZG93bkZpbGUoZmlsZW5hbWU6IHN0cmluZywgc2VjdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pIHtcbiAgbGV0IGNvbnRlbnRzID0gYXdhaXQgZnMucmVhZEZpbGUoZmlsZW5hbWUsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSk7XG5cbiAgZm9yIChjb25zdCBbc2VjdGlvbiwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHNlY3Rpb25zKSkge1xuICAgIGNvbnN0IHJlID0gbmV3IFJlZ0V4cChgPCEtLSBCRUdJTiAke3NlY3Rpb259IC0tPiguKik8IS0tIEVORCAke3NlY3Rpb259IC0tPmAsICdzJyk7XG4gICAgY29udGVudHMgPSBjb250ZW50cy5yZXBsYWNlKHJlLCBgPCEtLSBCRUdJTiAke3NlY3Rpb259IC0tPlxcbiR7dmFsdWV9XFxuPCEtLSBFTkQgJHtzZWN0aW9ufSAtLT5gKTtcbiAgfVxuXG4gIGF3YWl0IGZzLndyaXRlRmlsZShmaWxlbmFtZSwgY29udGVudHMsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVJlY29tbWVuZGVkRmxhZ3NGaWxlKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgYXdhaXQgZnMud3JpdGVGaWxlKGZpbGVuYW1lLCBKU09OLnN0cmluZ2lmeShmZWF0cy5DVVJSRU5UTFlfUkVDT01NRU5ERURfRkxBR1MsIHVuZGVmaW5lZCwgMiksIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSk7XG59XG5cbmZ1bmN0aW9uIGZpcnN0Q21wKC4uLnhzOiBudW1iZXJbXSkge1xuICByZXR1cm4geHMuZmluZCh4ID0+IHggIT09IDApID8/IDA7XG59XG5cbm1haW4oKS5jYXRjaChlID0+IHtcbiAgY29uc29sZS5lcnJvcihlKTtcbiAgcHJvY2Vzcy5leGl0Q29kZSA9IDE7XG59KTtcbiJdfQ==