aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
116 lines • 20 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable import/order */
const path = require("path");
const timers_1 = require("timers");
const util_1 = require("util");
const fs = require("fs-extra");
const sinon = require("sinon");
const logging = require("../lib/logging");
const npm = require("../lib/util/npm");
const version_1 = require("../lib/version");
jest.setTimeout(10000);
const setTimeout = (0, util_1.promisify)(timers_1.setTimeout);
function tmpfile() {
return `/tmp/version-${Math.floor(Math.random() * 10000)}`;
}
afterEach(done => {
sinon.restore();
done();
});
test('initialization fails on unwritable directory', () => {
const cacheFile = tmpfile();
sinon.stub(fs, 'mkdirsSync').withArgs(path.dirname(cacheFile)).throws('Cannot make directory');
expect(() => new version_1.VersionCheckTTL(cacheFile)).toThrow(/not writable/);
});
test('cache file responds correctly when file is not present', async () => {
const cache = new version_1.VersionCheckTTL(tmpfile(), 1);
expect(await cache.hasExpired()).toBeTruthy();
});
test('cache file honours the specified TTL', async () => {
const cache = new version_1.VersionCheckTTL(tmpfile(), 1);
await cache.update();
expect(await cache.hasExpired()).toBeFalsy();
await setTimeout(1001); // Just above 1 sec in ms
expect(await cache.hasExpired()).toBeTruthy();
});
test('Skip version check if cache has not expired', async () => {
const cache = new version_1.VersionCheckTTL(tmpfile(), 100);
await cache.update();
expect(await (0, version_1.latestVersionIfHigher)('0.0.0', cache)).toBeNull();
});
test('Return later version when exists & skip recent re-check', async () => {
const cache = new version_1.VersionCheckTTL(tmpfile(), 100);
const result = await (0, version_1.latestVersionIfHigher)('0.0.0', cache);
expect(result).not.toBeNull();
expect(result.length).toBeGreaterThan(0);
const result2 = await (0, version_1.latestVersionIfHigher)('0.0.0', cache);
expect(result2).toBeNull();
});
test('Return null if version is higher than npm', async () => {
const cache = new version_1.VersionCheckTTL(tmpfile(), 100);
const result = await (0, version_1.latestVersionIfHigher)('100.100.100', cache);
expect(result).toBeNull();
});
test('Version specified is stored in the TTL file', async () => {
const cacheFile = tmpfile();
const cache = new version_1.VersionCheckTTL(cacheFile, 1);
await cache.update('1.1.1');
const storedVersion = fs.readFileSync(cacheFile, 'utf8');
expect(storedVersion).toBe('1.1.1');
});
test('No Version specified for storage in the TTL file', async () => {
const cacheFile = tmpfile();
const cache = new version_1.VersionCheckTTL(cacheFile, 1);
await cache.update();
const storedVersion = fs.readFileSync(cacheFile, 'utf8');
expect(storedVersion).toBe('');
});
test('Skip version check if environment variable is set', async () => {
sinon.stub(process, 'stdout').value({ ...process.stdout, isTTY: true });
sinon.stub(process, 'env').value({ ...process.env, CDK_DISABLE_VERSION_CHECK: '1' });
const printStub = sinon.stub(logging, 'print');
await (0, version_1.displayVersionMessage)();
expect(printStub.called).toEqual(false);
});
describe('version message', () => {
const previousIsTty = process.stdout.isTTY;
beforeAll(() => {
process.stdout.isTTY = true;
});
afterAll(() => {
process.stdout.isTTY = previousIsTty;
});
test('Prints a message when a new version is available', async () => {
// Given the current version is 1.0.0 and the latest version is 1.1.0
const currentVersion = '1.0.0';
jest.spyOn(npm, 'getLatestVersionFromNpm').mockResolvedValue('1.1.0');
const printSpy = jest.spyOn(logging, 'print');
// When displayVersionMessage is called
await (0, version_1.displayVersionMessage)(currentVersion, new version_1.VersionCheckTTL(tmpfile(), 0));
// Then the new version message is printed to stdout
expect(printSpy).toHaveBeenCalledWith(expect.stringContaining('1.1.0'));
});
test('Includes major upgrade documentation when available', async () => {
// Given the current version is 1.0.0 and the latest version is 2.0.0
const currentVersion = '1.0.0';
jest.spyOn(npm, 'getLatestVersionFromNpm').mockResolvedValue('2.0.0');
const printSpy = jest.spyOn(logging, 'print');
// When displayVersionMessage is called
await (0, version_1.displayVersionMessage)(currentVersion, new version_1.VersionCheckTTL(tmpfile(), 0));
// Then the V1 -> V2 documentation is printed
expect(printSpy).toHaveBeenCalledWith(expect.stringContaining('Information about upgrading from version 1.x to version 2.x is available here: https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html'));
});
test('Does not include major upgrade documentation when unavailable', async () => {
// Given current version is 99.0.0 and the latest version is 100.0.0
const currentVersion = '99.0.0';
jest.spyOn(npm, 'getLatestVersionFromNpm').mockResolvedValue('100.0.0');
const printSpy = jest.spyOn(logging, 'print');
// When displayVersionMessage is called
await (0, version_1.displayVersionMessage)(currentVersion, new version_1.VersionCheckTTL(tmpfile(), 0));
// Then no upgrade documentation is printed
expect(printSpy).toHaveBeenCalledWith(expect.stringContaining('100.0.0'));
expect(printSpy).not.toHaveBeenCalledWith(expect.stringContaining('Information about upgrading from 99.x to 100.x'));
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidmVyc2lvbi50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaUNBQWlDO0FBQ2pDLDZCQUE2QjtBQUM3QixtQ0FBbUQ7QUFDbkQsK0JBQWlDO0FBQ2pDLCtCQUErQjtBQUMvQiwrQkFBK0I7QUFDL0IsMENBQTBDO0FBQzFDLHVDQUF1QztBQUN2Qyw0Q0FBK0Y7QUFFL0YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFNLENBQUMsQ0FBQztBQUV4QixNQUFNLFVBQVUsR0FBRyxJQUFBLGdCQUFTLEVBQUMsbUJBQVcsQ0FBQyxDQUFDO0FBRTFDLFNBQVMsT0FBTztJQUNkLE9BQU8sZ0JBQWdCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7QUFDN0QsQ0FBQztBQUVELFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRTtJQUNmLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNoQixJQUFJLEVBQUUsQ0FBQztBQUNULENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLDhDQUE4QyxFQUFFLEdBQUcsRUFBRTtJQUN4RCxNQUFNLFNBQVMsR0FBRyxPQUFPLEVBQUUsQ0FBQztJQUM1QixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQy9GLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLHlCQUFlLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDdkUsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsd0RBQXdELEVBQUUsS0FBSyxJQUFJLEVBQUU7SUFDeEUsTUFBTSxLQUFL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QTZDO1FBQzdDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsMklBQTJJLENBQUMsQ0FBQyxDQUFDO0lBQzlNLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLCtEQUErRCxFQUFFLEtBQUssSUFBRyxFQUFFO1FBQzlFLG9FQUFvRTtRQUNwRSxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUM7UUFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUseUJBQXlCLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4RSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUU5Qyx1Q0FBdUM7UUFDdkMsTUFBTSxJQUFBLCtCQUFxQixFQUFDLGNBQWMsRUFBRSxJQUFJLHlCQUFlLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUvRSwyQ0FBMkM7UUFDM0MsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQzFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLGdEQUFnRCxDQUFDLENBQUMsQ0FBQztJQUN2SCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L29yZGVyICovXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgc2V0VGltZW91dCBhcyBfc2V0VGltZW91dCB9IGZyb20gJ3RpbWVycyc7XG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICd1dGlsJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCAqIGFzIGxvZ2dpbmcgZnJvbSAnLi4vbGliL2xvZ2dpbmcnO1xuaW1wb3J0ICogYXMgbnBtIGZyb20gJy4uL2xpYi91dGlsL25wbSc7XG5pbXBvcnQgeyBsYXRlc3RWZXJzaW9uSWZIaWdoZXIsIFZlcnNpb25DaGVja1RUTCwgZGlzcGxheVZlcnNpb25NZXNzYWdlIH0gZnJvbSAnLi4vbGliL3ZlcnNpb24nO1xuXG5qZXN0LnNldFRpbWVvdXQoMTBfMDAwKTtcblxuY29uc3Qgc2V0VGltZW91dCA9IHByb21pc2lmeShfc2V0VGltZW91dCk7XG5cbmZ1bmN0aW9uIHRtcGZpbGUoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAvdG1wL3ZlcnNpb24tJHtNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxMDAwMCl9YDtcbn1cblxuYWZ0ZXJFYWNoKGRvbmUgPT4ge1xuICBzaW5vbi5yZXN0b3JlKCk7XG4gIGRvbmUoKTtcbn0pO1xuXG50ZXN0KCdpbml0aWFsaXphdGlvbiBmYWlscyBvbiB1bndyaXRhYmxlIGRpcmVjdG9yeScsICgpID0+IHtcbiAgY29uc3QgY2FjaGVGaWxlID0gdG1wZmlsZSgpO1xuICBzaW5vbi5zdHViKGZzLCAnbWtkaXJzU3luYycpLndpdGhBcmdzKHBhdGguZGlybmFtZShjYWNoZUZpbGUpKS50aHJvd3MoJ0Nhbm5vdCBtYWtlIGRpcmVjdG9yeScpO1xuICBleHBlY3QoKCkgPT4gbmV3IFZlcnNpb25DaGVja1RUTChjYWNoZUZpbGUpKS50b1Rocm93KC9ub3Qgd3JpdGFibGUvKTtcbn0pO1xuXG50ZXN0KCdjYWNoZSBmaWxlIHJlc3BvbmRzIGNvcnJlY3RseSB3aGVuIGZpbGUgaXMgbm90IHByZXNlbnQnLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IGNhY2hlID0gbmV3IFZlcnNpb25DaGVja1RUTCh0bXBmaWxlKCksIDEpO1xuICBleHBlY3QoYXdhaXQgY2FjaGUuaGFzRXhwaXJlZCgpKS50b0JlVHJ1dGh5KCk7XG59KTtcblxudGVzdCgnY2FjaGUgZmlsZSBob25vdXJzIHRoZSBzcGVjaWZpZWQgVFRMJywgYXN5bmMgKCkgPT4ge1xuICBjb25zdCBjYWNoZSA9IG5ldyBWZXJzaW9uQ2hlY2tUVEwodG1wZmlsZSgpLCAxKTtcbiAgYXdhaXQgY2FjaGUudXBkYXRlKCk7XG4gIGV4cGVjdChhd2FpdCBjYWNoZS5oYXNFeHBpcmVkKCkpLnRvQmVGYWxzeSgpO1xuICBhd2FpdCBzZXRUaW1lb3V0KDEwMDEpOyAvLyBKdXN0IGFib3ZlIDEgc2VjIGluIG1zXG4gIGV4cGVjdChhd2FpdCBjYWNoZS5oYXNFeHBpcmVkKCkpLnRvQmVUcnV0aHkoKTtcbn0pO1xuXG50ZXN0KCdTa2lwIHZlcnNpb24gY2hlY2sgaWYgY2FjaGUgaGFzIG5vdCBleHBpcmVkJywgYXN5bmMgKCkgPT4ge1xuICBjb25zdCBjYWNoZSA9IG5ldyBWZXJzaW9uQ2hlY2tUVEwodG1wZmlsZSgpLCAxMDApO1xuICBhd2FpdCBjYWNoZS51cGRhdGUoKTtcbiAgZXhwZWN0KGF3YWl0IGxhdGVzdFZlcnNpb25JZkhpZ2hlcignMC4wLjAnLCBjYWNoZSkpLnRvQmVOdWxsKCk7XG59KTtcblxudGVzdCgnUmV0dXJuIGxhdGVyIHZlcnNpb24gd2hlbiBleGlzdHMgJiBza2lwIHJlY2VudCByZS1jaGVjaycsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgY2FjaGUgPSBuZXcgVmVyc2lvbkNoZWNrVFRMKHRtcGZpbGUoKSwgMTAwKTtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbGF0ZXN0VmVyc2lvbklmSGlnaGVyKCcwLjAuMCcsIGNhY2hlKTtcbiAgZXhwZWN0KHJlc3VsdCkubm90LnRvQmVOdWxsKCk7XG4gIGV4cGVjdCgocmVzdWx0IGFzIHN0cmluZykubGVuZ3RoKS50b0JlR3JlYXRlclRoYW4oMCk7XG5cbiAgY29uc3QgcmVzdWx0MiA9IGF3YWl0IGxhdGVzdFZlcnNpb25JZkhpZ2hlcignMC4wLjAnLCBjYWNoZSk7XG4gIGV4cGVjdChyZXN1bHQyKS50b0JlTnVsbCgpO1xufSk7XG5cbnRlc3QoJ1JldHVybiBudWxsIGlmIHZlcnNpb24gaXMgaGlnaGVyIHRoYW4gbnBtJywgYXN5bmMgKCkgPT4ge1xuICBjb25zdCBjYWNoZSA9IG5ldyBWZXJzaW9uQ2hlY2tUVEwodG1wZmlsZSgpLCAxMDApO1xuICBjb25zdCByZXN1bHQgPSBhd2FpdCBsYXRlc3RWZXJzaW9uSWZIaWdoZXIoJzEwMC4xMDAuMTAwJywgY2FjaGUpO1xuICBleHBlY3QocmVzdWx0KS50b0JlTnVsbCgpO1xufSk7XG5cbnRlc3QoJ1ZlcnNpb24gc3BlY2lmaWVkIGlzIHN0b3JlZCBpbiB0aGUgVFRMIGZpbGUnLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IGNhY2hlRmlsZSA9IHRtcGZpbGUoKTtcbiAgY29uc3QgY2FjaGUgPSBuZXcgVmVyc2lvbkNoZWNrVFRMKGNhY2hlRmlsZSwgMSk7XG4gIGF3YWl0IGNhY2hlLnVwZGF0ZSgnMS4xLjEnKTtcbiAgY29uc3Qgc3RvcmVkVmVyc2lvbiA9IGZzLnJlYWRGaWxlU3luYyhjYWNoZUZpbGUsICd1dGY4Jyk7XG4gIGV4cGVjdChzdG9yZWRWZXJzaW9uKS50b0JlKCcxLjEuMScpO1xufSk7XG5cbnRlc3QoJ05vIFZlcnNpb24gc3BlY2lmaWVkIGZvciBzdG9yYWdlIGluIHRoZSBUVEwgZmlsZScsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgY2FjaGVGaWxlID0gdG1wZmlsZSgpO1xuICBjb25zdCBjYWNoZSA9IG5ldyBWZXJzaW9uQ2hlY2tUVEwoY2FjaGVGaWxlLCAxKTtcbiAgYXdhaXQgY2FjaGUudXBkYXRlKCk7XG4gIGNvbnN0IHN0b3JlZFZlcnNpb24gPSBmcy5yZWFkRmlsZVN5bmMoY2FjaGVGaWxlLCAndXRmOCcpO1xuICBleHBlY3Qoc3RvcmVkVmVyc2lvbikudG9CZSgnJyk7XG59KTtcblxudGVzdCgnU2tpcCB2ZXJzaW9uIGNoZWNrIGlmIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIHNldCcsIGFzeW5jICgpID0+IHtcbiAgc2lub24uc3R1Yihwcm9jZXNzLCAnc3Rkb3V0JykudmFsdWUoeyAuLi5wcm9jZXNzLnN0ZG91dCwgaXNUVFk6IHRydWUgfSk7XG4gIHNpbm9uLnN0dWIocHJvY2VzcywgJ2VudicpLnZhbHVlKHsgLi4ucHJvY2Vzcy5lbnYsIENES19ESVNBQkxFX1ZFUlNJT05fQ0hFQ0s6ICcxJyB9KTtcbiAgY29uc3QgcHJpbnRTdHViID0gc2lub24uc3R1Yihsb2dnaW5nLCAncHJpbnQnKTtcbiAgYXdhaXQgZGlzcGxheVZlcnNpb25NZXNzYWdlKCk7XG4gIGV4cGVjdChwcmludFN0dWIuY2FsbGVkKS50b0VxdWFsKGZhbHNlKTtcbn0pO1xuXG5kZXNjcmliZSgndmVyc2lvbiBtZXNzYWdlJywgKCkgPT4ge1xuICBjb25zdCBwcmV2aW91c0lzVHR5ID0gcHJvY2Vzcy5zdGRvdXQuaXNUVFk7XG4gIGJlZm9yZUFsbCgoKSA9PiB7XG4gICAgcHJvY2Vzcy5zdGRvdXQuaXNUVFkgPSB0cnVlO1xuICB9KTtcblxuICBhZnRlckFsbCgoKSA9PiB7XG4gICAgcHJvY2Vzcy5zdGRvdXQuaXNUVFkgPSBwcmV2aW91c0lzVHR5O1xuICB9KTtcblxuICB0ZXN0KCdQcmludHMgYSBtZXNzYWdlIHdoZW4gYSBuZXcgdmVyc2lvbiBpcyBhdmFpbGFibGUnLCBhc3luYyAoKSA9PiB7XG4gICAgLy8gR2l2ZW4gdGhlIGN1cnJlbnQgdmVyc2lvbiBpcyAxLjAuMCBhbmQgdGhlIGxhdGVzdCB2ZXJzaW9uIGlzIDEuMS4wXG4gICAgY29uc3QgY3VycmVudFZlcnNpb24gPSAnMS4wLjAnO1xuICAgIGplc3Quc3B5T24obnBtLCAnZ2V0TGF0ZXN0VmVyc2lvbkZyb21OcG0nKS5tb2NrUmVzb2x2ZWRWYWx1ZSgnMS4xLjAnKTtcbiAgICBjb25zdCBwcmludFNweSA9IGplc3Quc3B5T24obG9nZ2luZywgJ3ByaW50Jyk7XG5cbiAgICAvLyBXaGVuIGRpc3BsYXlWZXJzaW9uTWVzc2FnZSBpcyBjYWxsZWRcbiAgICBhd2FpdCBkaXNwbGF5VmVyc2lvbk1lc3NhZ2UoY3VycmVudFZlcnNpb24sIG5ldyBWZXJzaW9uQ2hlY2tUVEwodG1wZmlsZSgpLCAwKSk7XG5cbiAgICAvLyBUaGVuIHRoZSBuZXcgdmVyc2lvbiBtZXNzYWdlIGlzIHByaW50ZWQgdG8gc3Rkb3V0XG4gICAgZXhwZWN0KHByaW50U3B5KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChleHBlY3Quc3RyaW5nQ29udGFpbmluZygnMS4xLjAnKSk7XG4gIH0pO1xuXG4gIHRlc3QoJ0luY2x1ZGVzIG1ham9yIHVwZ3JhZGUgZG9jdW1lbnRhdGlvbiB3aGVuIGF2YWlsYWJsZScsIGFzeW5jKCkgPT4ge1xuICAgIC8vIEdpdmVuIHRoZSBjdXJyZW50IHZlcnNpb24gaXMgMS4wLjAgYW5kIHRoZSBsYXRlc3QgdmVyc2lvbiBpcyAyLjAuMFxuICAgIGNvbnN0IGN1cnJlbnRWZXJzaW9uID0gJzEuMC4wJztcbiAgICBqZXN0LnNweU9uKG5wbSwgJ2dldExhdGVzdFZlcnNpb25Gcm9tTnBtJykubW9ja1Jlc29sdmVkVmFsdWUoJzIuMC4wJyk7XG4gICAgY29uc3QgcHJpbnRTcHkgPSBqZXN0LnNweU9uKGxvZ2dpbmcsICdwcmludCcpO1xuXG4gICAgLy8gV2hlbiBkaXNwbGF5VmVyc2lvbk1lc3NhZ2UgaXMgY2FsbGVkXG4gICAgYXdhaXQgZGlzcGxheVZlcnNpb25NZXNzYWdlKGN1cnJlbnRWZXJzaW9uLCBuZXcgVmVyc2lvbkNoZWNrVFRMKHRtcGZpbGUoKSwgMCkpO1xuXG4gICAgLy8gVGhlbiB0aGUgVjEgLT4gVjIgZG9jdW1lbnRhdGlvbiBpcyBwcmludGVkXG4gICAgZXhwZWN0KHByaW50U3B5KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChleHBlY3Quc3RyaW5nQ29udGFpbmluZygnSW5mb3JtYXRpb24gYWJvdXQgdXBncmFkaW5nIGZyb20gdmVyc2lvbiAxLnggdG8gdmVyc2lvbiAyLnggaXMgYXZhaWxhYmxlIGhlcmU6IGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jZGsvdjIvZ3VpZGUvbWlncmF0aW5nLXYyLmh0bWwnKSk7XG4gIH0pO1xuXG4gIHRlc3QoJ0RvZXMgbm90IGluY2x1ZGUgbWFqb3IgdXBncmFkZSBkb2N1bWVudGF0aW9uIHdoZW4gdW5hdmFpbGFibGUnLCBhc3luYygpID0+IHtcbiAgICAvLyBHaXZlbiBjdXJyZW50IHZlcnNpb24gaXMgOTkuMC4wIGFuZCB0aGUgbGF0ZXN0IHZlcnNpb24gaXMgMTAwLjAuMFxuICAgIGNvbnN0IGN1cnJlbnRWZXJzaW9uID0gJzk5LjAuMCc7XG4gICAgamVzdC5zcHlPbihucG0sICdnZXRMYXRlc3RWZXJzaW9uRnJvbU5wbScpLm1vY2tSZXNvbHZlZFZhbHVlKCcxMDAuMC4wJyk7XG4gICAgY29uc3QgcHJpbnRTcHkgPSBqZXN0LnNweU9uKGxvZ2dpbmcsICdwcmludCcpO1xuXG4gICAgLy8gV2hlbiBkaXNwbGF5VmVyc2lvbk1lc3NhZ2UgaXMgY2FsbGVkXG4gICAgYXdhaXQgZGlzcGxheVZlcnNpb25NZXNzYWdlKGN1cnJlbnRWZXJzaW9uLCBuZXcgVmVyc2lvbkNoZWNrVFRMKHRtcGZpbGUoKSwgMCkpO1xuXG4gICAgLy8gVGhlbiBubyB1cGdyYWRlIGRvY3VtZW50YXRpb24gaXMgcHJpbnRlZFxuICAgIGV4cGVjdChwcmludFNweSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoZXhwZWN0LnN0cmluZ0NvbnRhaW5pbmcoJzEwMC4wLjAnKSk7XG4gICAgZXhwZWN0KHByaW50U3B5KS5ub3QudG9IYXZlQmVlbkNhbGxlZFdpdGgoZXhwZWN0LnN0cmluZ0NvbnRhaW5pbmcoJ0luZm9ybWF0aW9uIGFib3V0IHVwZ3JhZGluZyBmcm9tIDk5LnggdG8gMTAwLngnKSk7XG4gIH0pO1xufSk7XG4iXX0=