init.test.js
  1  "use strict";
  2  Object.defineProperty(exports, "__esModule", { value: true });
  3  /**
  4   * The init templates rely on parsing the current major version to find the correct template directory.
  5   * During tests, the current package version is '0.0.0', rather than a specific version.
  6   * The below mocks the versionNumber to return the major version (and so init template version) specified.
  7   */
  8  let mockMajorVersion = '1.0.0';
  9  jest.mock('../lib/version', () => ({
 10      versionNumber: () => mockMajorVersion,
 11  }));
 12  const os = require("os");
 13  const path = require("path");
 14  const cxapi = require("@aws-cdk/cx-api");
 15  const fs = require("fs-extra");
 16  const init_1 = require("../lib/init");
 17  describe.each(['1', '2'])('v%s tests', (majorVersion) => {
 18      beforeEach(() => {
 19          mockMajorVersion = `${majorVersion}.0.0`;
 20          jest.resetAllMocks();
 21      });
 22      cliTest('create a TypeScript library project', async (workDir) => {
 23          await init_1.cliInit('lib', 'typescript', false, undefined /* canUseNetwork */, workDir);
 24          // Check that package.json and lib/ got created in the current directory
 25          expect(await fs.pathExists(path.join(workDir, 'package.json'))).toBeTruthy();
 26          expect(await fs.pathExists(path.join(workDir, 'lib'))).toBeTruthy();
 27      });
 28      cliTest('create a TypeScript app project', async (workDir) => {
 29          await init_1.cliInit('app', 'typescript', false, undefined /* canUseNetwork */, workDir);
 30          // Check that package.json and bin/ got created in the current directory
 31          expect(await fs.pathExists(path.join(workDir, 'package.json'))).toBeTruthy();
 32          expect(await fs.pathExists(path.join(workDir, 'bin'))).toBeTruthy();
 33      });
 34      cliTest('create a JavaScript app project', async (workDir) => {
 35          await init_1.cliInit('app', 'javascript', false, undefined /* canUseNetwork */, workDir);
 36          // Check that package.json and bin/ got created in the current directory
 37          expect(await fs.pathExists(path.join(workDir, 'package.json'))).toBeTruthy();
 38          expect(await fs.pathExists(path.join(workDir, 'bin'))).toBeTruthy();
 39          expect(await fs.pathExists(path.join(workDir, '.git'))).toBeTruthy();
 40      });
 41      cliTest('--generate-only should skip git init', async (workDir) => {
 42          await init_1.cliInit('app', 'javascript', false, true, workDir);
 43          // Check that package.json and bin/ got created in the current directory
 44          expect(await fs.pathExists(path.join(workDir, 'package.json'))).toBeTruthy();
 45          expect(await fs.pathExists(path.join(workDir, 'bin'))).toBeTruthy();
 46          expect(await fs.pathExists(path.join(workDir, '.git'))).toBeFalsy();
 47      });
 48      cliTest('git directory does not throw off the initer!', async (workDir) => {
 49          fs.mkdirSync(path.join(workDir, '.git'));
 50          await init_1.cliInit('app', 'typescript', false, undefined /* canUseNetwork */, workDir);
 51          // Check that package.json and bin/ got created in the current directory
 52          expect(await fs.pathExists(path.join(workDir, 'package.json'))).toBeTruthy();
 53          expect(await fs.pathExists(path.join(workDir, 'bin'))).toBeTruthy();
 54      });
 55      test('verify "future flags" are added to cdk.json', async () => {
 56          // This is a lot to test, and it can be slow-ish, especially when ran with other tests.
 57          jest.setTimeout(30000);
 58          for (const templ of await init_1.availableInitTemplates()) {
 59              for (const lang of templ.languages) {
 60                  await withTempDir(async (tmpDir) => {
 61                      await init_1.cliInit(templ.name, lang, 
 62                      /* canUseNetwork */ false, 
 63                      /* generateOnly */ true, tmpDir);
 64                      // ok if template doesn't have a cdk.json file (e.g. the "lib" template)
 65                      if (!await fs.pathExists(path.join(tmpDir, 'cdk.json'))) {
 66                          return;
 67                      }
 68                      const config = await fs.readJson(path.join(tmpDir, 'cdk.json'));
 69                      const context = config.context || {};
 70                      for (const [key, expected] of Object.entries(context)) {
 71                          const actual = cxapi.FUTURE_FLAGS[key];
 72                          expect(actual).toEqual(expected);
 73                      }
 74                      // assert that expired future flags are not part of the cdk.json
 75                      Object.keys(context).forEach(k => {
 76                          expect(cxapi.FUTURE_FLAGS_EXPIRED.includes(k)).toEqual(false);
 77                      });
 78                  });
 79              }
 80          }
 81      });
 82  });
 83  test('when no version number is present (e.g., local development), the v1 templates are chosen by default', async () => {
 84      mockMajorVersion = '0.0.0';
 85      jest.resetAllMocks();
 86      expect((await init_1.availableInitTemplates()).length).toBeGreaterThan(0);
 87  });
 88  function cliTest(name, handler) {
 89      test(name, () => withTempDir(handler));
 90  }
 91  async function withTempDir(cb) {
 92      const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'aws-cdk-test'));
 93      try {
 94          await cb(tmpDir);
 95      }
 96      finally {
 97          await fs.remove(tmpDir);
 98      }
 99  }
100  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiaW5pdC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7R0FJRztBQUNILElBQUksZ0JBQWdCLEdBQUcsT0FBTyxDQUFDO0FBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNqQyxhQUFhLEVBQUUsR0FBRyxFQUFFLENBQUMsZ0JBQWdCO0NBQ3RDLENBQUMsQ0FBQyxDQUFDO0FBRUoseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qix5Q0FBeUM7QUFDekMsK0JBQStCO0FBQy9CLHNDQUE4RDtBQUU5RCxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsWUFBWSxFQUFFLEVBQUU7SUFDdEQsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLGdCQUFnQixHQUFHLEdBQUcsWUFBWSxNQUFNLENBQUM7UUFDekMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZCLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxDQUFDLHFDQUFxQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtRQUMvRCxNQUFNLGNBQU8sQ0FBQyxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsbUJBQW1CLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFbEYsd0VBQXdFO1FBQ3hFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzdFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3RFLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxDQUFDLGlDQUFpQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtRQUMzRCxNQUFNLGNBQU8sQ0FBQyxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsbUJBQW1CLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFbEYsd0VBQXdFO1FBQ3hFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzdFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3RFLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxDQUFDLGlDQUFpQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtRQUMzRCxNQUFNLGNBQU8sQ0FBQyxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsbUJBQW1CLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFbEYsd0VBQXdFO1FBQ3hFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzdFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3BFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVB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OlsiLyoqXG4gKiBUaGUgaW5pdCB0ZW1wbGF0ZXMgcmVseSBvbiBwYXJzaW5nIHRoZSBjdXJyZW50IG1ham9yIHZlcnNpb24gdG8gZmluZCB0aGUgY29ycmVjdCB0ZW1wbGF0ZSBkaXJlY3RvcnkuXG4gKiBEdXJpbmcgdGVzdHMsIHRoZSBjdXJyZW50IHBhY2thZ2UgdmVyc2lvbiBpcyAnMC4wLjAnLCByYXRoZXIgdGhhbiBhIHNwZWNpZmljIHZlcnNpb24uXG4gKiBUaGUgYmVsb3cgbW9ja3MgdGhlIHZlcnNpb25OdW1iZXIgdG8gcmV0dXJuIHRoZSBtYWpvciB2ZXJzaW9uIChhbmQgc28gaW5pdCB0ZW1wbGF0ZSB2ZXJzaW9uKSBzcGVjaWZpZWQuXG4gKi9cbmxldCBtb2NrTWFqb3JWZXJzaW9uID0gJzEuMC4wJztcbmplc3QubW9jaygnLi4vbGliL3ZlcnNpb24nLCAoKSA9PiAoe1xuICB2ZXJzaW9uTnVtYmVyOiAoKSA9PiBtb2NrTWFqb3JWZXJzaW9uLFxufSkpO1xuXG5pbXBvcnQgKiBhcyBvcyBmcm9tICdvcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgY3hhcGkgZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCB7IGF2YWlsYWJsZUluaXRUZW1wbGF0ZXMsIGNsaUluaXQgfSBmcm9tICcuLi9saWIvaW5pdCc7XG5cbmRlc2NyaWJlLmVhY2goWycxJywgJzInXSkoJ3YlcyB0ZXN0cycsIChtYWpvclZlcnNpb24pID0+IHtcbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgbW9ja01ham9yVmVyc2lvbiA9IGAke21ham9yVmVyc2lvbn0uMC4wYDtcbiAgICBqZXN0LnJlc2V0QWxsTW9ja3MoKTtcbiAgfSk7XG5cbiAgY2xpVGVzdCgnY3JlYXRlIGEgVHlwZVNjcmlwdCBsaWJyYXJ5IHByb2plY3QnLCBhc3luYyAod29ya0RpcikgPT4ge1xuICAgIGF3YWl0IGNsaUluaXQoJ2xpYicsICd0eXBlc2NyaXB0JywgZmFsc2UsIHVuZGVmaW5lZCAvKiBjYW5Vc2VOZXR3b3JrICovLCB3b3JrRGlyKTtcblxuICAgIC8vIENoZWNrIHRoYXQgcGFja2FnZS5qc29uIGFuZCBsaWIvIGdvdCBjcmVhdGVkIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeVxuICAgIGV4cGVjdChhd2FpdCBmcy5wYXRoRXhpc3RzKHBhdGguam9pbih3b3JrRGlyLCAncGFja2FnZS5qc29uJykpKS50b0JlVHJ1dGh5KCk7XG4gICAgZXhwZWN0KGF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5qb2luKHdvcmtEaXIsICdsaWInKSkpLnRvQmVUcnV0aHkoKTtcbiAgfSk7XG5cbiAgY2xpVGVzdCgnY3JlYXRlIGEgVHlwZVNjcmlwdCBhcHAgcHJvamVjdCcsIGFzeW5jICh3b3JrRGlyKSA9PiB7XG4gICAgYXdhaXQgY2xpSW5pdCgnYXBwJywgJ3R5cGVzY3JpcHQnLCBmYWxzZSwgdW5kZWZpbmVkIC8qIGNhblVzZU5ldHdvcmsgKi8sIHdvcmtEaXIpO1xuXG4gICAgLy8gQ2hlY2sgdGhhdCBwYWNrYWdlLmpzb24gYW5kIGJpbi8gZ290IGNyZWF0ZWQgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5XG4gICAgZXhwZWN0KGF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5qb2luKHdvcmtEaXIsICdwYWNrYWdlLmpzb24nKSkpLnRvQmVUcnV0aHkoKTtcbiAgICBleHBlY3QoYXdhaXQgZnMucGF0aEV4aXN0cyhwYXRoLmpvaW4od29ya0RpciwgJ2JpbicpKSkudG9CZVRydXRoeSgpO1xuICB9KTtcblxuICBjbGlUZXN0KCdjcmVhdGUgYSBKYXZhU2NyaXB0IGFwcCBwcm9qZWN0JywgYXN5bmMgKHdvcmtEaXIpID0+IHtcbiAgICBhd2FpdCBjbGlJbml0KCdhcHAnLCAnamF2YXNjcmlwdCcsIGZhbHNlLCB1bmRlZmluZWQgLyogY2FuVXNlTmV0d29yayAqLywgd29ya0Rpcik7XG5cbiAgICAvLyBDaGVjayB0aGF0IHBhY2thZ2UuanNvbiBhbmQgYmluLyBnb3QgY3JlYXRlZCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnlcbiAgICBleHBlY3QoYXdhaXQgZnMucGF0aEV4aXN0cyhwYXRoLmpvaW4od29ya0RpciwgJ3BhY2thZ2UuanNvbicpKSkudG9CZVRydXRoeSgpO1xuICAgIGV4cGVjdChhd2FpdCBmcy5wYXRoRXhpc3RzKHBhdGguam9pbih3b3JrRGlyLCAnYmluJykpKS50b0JlVHJ1dGh5KCk7XG4gICAgZXhwZWN0KGF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5qb2luKHdvcmtEaXIsICcuZ2l0JykpKS50b0JlVHJ1dGh5KCk7XG4gIH0pO1xuXG4gIGNsaVRlc3QoJy0tZ2VuZXJhdGUtb25seSBzaG91bGQgc2tpcCBnaXQgaW5pdCcsIGFzeW5jICh3b3JrRGlyKSA9PiB7XG4gICAgYXdhaXQgY2xpSW5pdCgnYXBwJywgJ2phdmFzY3JpcHQnLCBmYWxzZSwgdHJ1ZSwgd29ya0Rpcik7XG5cbiAgICAvLyBDaGVjayB0aGF0IHBhY2thZ2UuanNvbiBhbmQgYmluLyBnb3QgY3JlYXRlZCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnlcbiAgICBleHBlY3QoYXdhaXQgZnMucGF0aEV4aXN0cyhwYXRoLmpvaW4od29ya0RpciwgJ3BhY2thZ2UuanNvbicpKSkudG9CZVRydXRoeSgpO1xuICAgIGV4cGVjdChhd2FpdCBmcy5wYXRoRXhpc3RzKHBhdGguam9pbih3b3JrRGlyLCAnYmluJykpKS50b0JlVHJ1dGh5KCk7XG4gICAgZXhwZWN0KGF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5qb2luKHdvcmtEaXIsICcuZ2l0JykpKS50b0JlRmFsc3koKTtcbiAgfSk7XG5cbiAgY2xpVGVzdCgnZ2l0IGRpcmVjdG9yeSBkb2VzIG5vdCB0aHJvdyBvZmYgdGhlIGluaXRlciEnLCBhc3luYyAod29ya0RpcikgPT4ge1xuICAgIGZzLm1rZGlyU3luYyhwYXRoLmpvaW4od29ya0RpciwgJy5naXQnKSk7XG5cbiAgICBhd2FpdCBjbGlJbml0KCdhcHAnLCAndHlwZXNjcmlwdCcsIGZhbHNlLCB1bmRlZmluZWQgLyogY2FuVXNlTmV0d29yayAqLywgd29ya0Rpcik7XG5cbiAgICAvLyBDaGVjayB0aGF0IHBhY2thZ2UuanNvbiBhbmQgYmluLyBnb3QgY3JlYXRlZCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnlcbiAgICBleHBlY3QoYXdhaXQgZnMucGF0aEV4aXN0cyhwYXRoLmpvaW4od29ya0RpciwgJ3BhY2thZ2UuanNvbicpKSkudG9CZVRydXRoeSgpO1xuICAgIGV4cGVjdChhd2FpdCBmcy5wYXRoRXhpc3RzKHBhdGguam9pbih3b3JrRGlyLCAnYmluJykpKS50b0JlVHJ1dGh5KCk7XG4gIH0pO1xuXG4gIHRlc3QoJ3ZlcmlmeSBcImZ1dHVyZSBmbGFnc1wiIGFyZSBhZGRlZCB0byBjZGsuanNvbicsIGFzeW5jICgpID0+IHtcbiAgICAvLyBUaGlzIGlzIGEgbG90IHRvIHRlc3QsIGFuZCBpdCBjYW4gYmUgc2xvdy1pc2gsIGVzcGVjaWFsbHkgd2hlbiByYW4gd2l0aCBvdGhlciB0ZXN0cy5cbiAgICBqZXN0LnNldFRpbWVvdXQoMzBfMDAwKTtcblxuICAgIGZvciAoY29uc3QgdGVtcGwgb2YgYXdhaXQgYXZhaWxhYmxlSW5pdFRlbXBsYXRlcygpKSB7XG4gICAgICBmb3IgKGNvbnN0IGxhbmcgb2YgdGVtcGwubGFuZ3VhZ2VzKSB7XG4gICAgICAgIGF3YWl0IHdpdGhUZW1wRGlyKGFzeW5jIHRtcERpciA9PiB7XG4gICAgICAgICAgYXdhaXQgY2xpSW5pdCh0ZW1wbC5uYW1lLCBsYW5nLFxuICAgICAgICAgICAgLyogY2FuVXNlTmV0d29yayAqLyBmYWxzZSxcbiAgICAgICAgICAgIC8qIGdlbmVyYXRlT25seSAqLyB0cnVlLFxuICAgICAgICAgICAgdG1wRGlyKTtcblxuICAgICAgICAgIC8vIG9rIGlmIHRlbXBsYXRlIGRvZXNuJ3QgaGF2ZSBhIGNkay5qc29uIGZpbGUgKGUuZy4gdGhlIFwibGliXCIgdGVtcGxhdGUpXG4gICAgICAgICAgaWYgKCFhd2FpdCBmcy5wYXRoRXhpc3RzKHBhdGguam9pbih0bXBEaXIsICdjZGsuanNvbicpKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IGF3YWl0IGZzLnJlYWRKc29uKHBhdGguam9pbih0bXBEaXIsICdjZGsuanNvbicpKTtcbiAgICAgICAgICBjb25zdCBjb250ZXh0ID0gY29uZmlnLmNvbnRleHQgfHwge307XG4gICAgICAgICAgZm9yIChjb25zdCBba2V5LCBleHBlY3RlZF0gb2YgT2JqZWN0LmVudHJpZXMoY29udGV4dCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGFjdHVhbCA9IGN4YXBpLkZVVFVSRV9GTEFHU1trZXldO1xuICAgICAgICAgICAgZXhwZWN0KGFjdHVhbCkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gYXNzZXJ0IHRoYXQgZXhwaXJlZCBmdXR1cmUgZmxhZ3MgYXJlIG5vdCBwYXJ0IG9mIHRoZSBjZGsuanNvblxuICAgICAgICAgIE9iamVjdC5rZXlzKGNvbnRleHQpLmZvckVhY2goayA9PiB7XG4gICAgICAgICAgICBleHBlY3QoY3hhcGkuRlVUVVJFX0ZMQUdTX0VYUElSRUQuaW5jbHVkZXMoaykpLnRvRXF1YWwoZmFsc2UpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufSk7XG5cbnRlc3QoJ3doZW4gbm8gdmVyc2lvbiBudW1iZXIgaXMgcHJlc2VudCAoZS5nLiwgbG9jYWwgZGV2ZWxvcG1lbnQpLCB0aGUgdjEgdGVtcGxhdGVzIGFyZSBjaG9zZW4gYnkgZGVmYXVsdCcsIGFzeW5jICgpID0+IHtcbiAgbW9ja01ham9yVmVyc2lvbiA9ICcwLjAuMCc7XG4gIGplc3QucmVzZXRBbGxNb2NrcygpO1xuXG4gIGV4cGVjdCgoYXdhaXQgYXZhaWxhYmxlSW5pdFRlbXBsYXRlcygpKS5sZW5ndGgpLnRvQmVHcmVhdGVyVGhhbigwKTtcbn0pO1xuXG5mdW5jdGlvbiBjbGlUZXN0KG5hbWU6IHN0cmluZywgaGFuZGxlcjogKGRpcjogc3RyaW5nKSA9PiB2b2lkIHwgUHJvbWlzZTxhbnk+KTogdm9pZCB7XG4gIHRlc3QobmFtZSwgKCkgPT4gd2l0aFRlbXBEaXIoaGFuZGxlcikpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3aXRoVGVtcERpcihjYjogKGRpcjogc3RyaW5nKSA9PiB2b2lkIHwgUHJvbWlzZTxhbnk+KSB7XG4gIGNvbnN0IHRtcERpciA9IGF3YWl0IGZzLm1rZHRlbXAocGF0aC5qb2luKG9zLnRtcGRpcigpLCAnYXdzLWNkay10ZXN0JykpO1xuICB0cnkge1xuICAgIGF3YWl0IGNiKHRtcERpcik7XG4gIH0gZmluYWxseSB7XG4gICAgYXdhaXQgZnMucmVtb3ZlKHRtcERpcik7XG4gIH1cbn1cbiJdfQ==