UNPKG

projen

Version:

CDK for software projects

387 lines 51.3 kB
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReactComponent = exports.ReactTypeScriptProject = exports.ReactProject = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path = __importStar(require("path"));
const component_1 = require("../component");
const javascript_1 = require("../javascript");
const sample_file_1 = require("../sample-file");
const source_code_1 = require("../source-code");
const typescript_1 = require("../typescript");
const util_1 = require("../util");
/**
 * React project using JavaScript.
 *
 * @pjid react
 */
class ReactProject extends javascript_1.NodeProject {
    static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.web.ReactProject", version: "0.103.12" };
    /**
     * The directory in which source files reside.
     * @default "src"
     */
    srcdir;
    constructor(options) {
        super({
            jest: false,
            ...options,
        });
        this.srcdir = options.srcdir ?? "src";
        new ReactComponent(this, { typescript: false, rewire: options.rewire });
        // generate sample code in `src` and `public` if these directories are empty or non-existent.
        if (options.sampleCode ?? true) {
            new ReactSampleCode(this, {
                fileExt: "jsx",
                srcdir: this.srcdir,
            });
            new sample_file_1.SampleDir(this, "public", {
                sourceDir: path.join(__dirname, "..", "..", "assets", "web", "react"),
            });
        }
    }
}
exports.ReactProject = ReactProject;
/**
 * React project using TypeScript.
 *
 * @pjid react-ts
 */
class ReactTypeScriptProject extends typescript_1.TypeScriptAppProject {
    static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.web.ReactTypeScriptProject", version: "0.103.12" };
    /**
     * The directory in which source files reside.
     */
    srcdir;
    constructor(options) {
        const defaultOptions = {
            srcdir: "src",
            eslint: true,
            jest: false,
            tsconfig: {
                include: ["src"],
                compilerOptions: {
                    target: "es5",
                    lib: ["dom", "dom.iterable", "esnext"],
                    allowJs: true,
                    skipLibCheck: true,
                    esModuleInterop: true,
                    allowSyntheticDefaultImports: true,
                    strict: true,
                    forceConsistentCasingInFileNames: true,
                    noFallthroughCasesInSwitch: true,
                    module: "commonjs",
                    moduleResolution: javascript_1.TypeScriptModuleResolution.NODE,
                    resolveJsonModule: true,
                    isolatedModules: true,
                    noEmit: true,
                    jsx: javascript_1.TypeScriptJsxMode.REACT_JSX,
                },
            },
            typescriptVersion: options.typescriptVersion ?? "^4.0.3",
        };
        // never generate default TypeScript sample code, since this class provides its own
        super((0, util_1.deepMerge)([
            defaultOptions,
            options,
            { sampleCode: false },
        ]));
        this.srcdir = options.srcdir ?? "src";
        this.eslint?.addRules({
            "import/no-extraneous-dependencies": [
                "error",
                {
                    devDependencies: ["**/src/**/*.test.tsx", "**/src/setupTests.ts"],
                    optionalDependencies: false,
                    peerDependencies: true,
                },
            ],
        });
        new ReactComponent(this, { typescript: true, rewire: options.rewire });
        // generate sample code in `src` and `public` if these directories are empty or non-existent.
        if (options.sampleCode ?? true) {
            new ReactSampleCode(this, {
                fileExt: "tsx",
                srcdir: this.srcdir,
            });
            new sample_file_1.SampleDir(this, "public", {
                sourceDir: path.join(__dirname, "..", "..", "assets", "web", "react"),
            });
        }
        this.package.addPackageResolutions(
        // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/62300
        "@types/express@4.17.13", "@types/express-serve-static-core@4.17.30");
    }
}
exports.ReactTypeScriptProject = ReactTypeScriptProject;
class ReactComponent extends component_1.Component {
    static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.web.ReactComponent", version: "0.103.12" };
    typescript;
    constructor(project, options) {
        super(project);
        this.typescript = options.typescript ?? false;
        // No compile for react app
        project.compileTask.reset();
        project.addDeps("react", "react-dom", "web-vitals");
        project.addDevDeps("react-scripts@^5", "@testing-library/dom", "@testing-library/jest-dom", "@testing-library/react", "@testing-library/user-event");
        if (this.typescript) {
            project.addDevDeps("@types/jest", "@types/react", "@types/react-dom");
        }
        const rewire = options.rewire ?? false;
        if (rewire) {
            const overridesPath = ".projen/react-config-overrides.js";
            project.addDevDeps("react-app-rewired");
            project.addFields({ "config-overrides-path": overridesPath });
            const configOverrides = new source_code_1.SourceCode(this.project, overridesPath);
            if (!configOverrides.marker) {
                configOverrides.line(`// ${configOverrides.marker}`);
            }
            configOverrides.line("/**");
            configOverrides.line(" * Override CRA configuration without needing to eject.");
            configOverrides.line(" *");
            configOverrides.line(" * @see https://www.npmjs.com/package/react-app-rewired");
            configOverrides.line(" */");
            configOverrides.open("module.exports = function override(config, env) {");
            for (const [key, value] of Object.entries(rewire)) {
                configOverrides.line(`config.${key} = ${JSON.stringify(value)};`);
            }
            configOverrides.line("return config;");
            configOverrides.close("};");
        }
        const reactScripts = rewire ? "react-app-rewired" : "react-scripts";
        // Create React App CLI commands, see: https://create-react-app.dev/docs/available-scripts/
        project.addTask("dev", {
            description: "Starts the react application",
            execArgs: [reactScripts, "start"],
        });
        project.compileTask.execArgs([reactScripts, "build"]);
        project.testTask.execArgs([reactScripts, "test", "--watchAll=false"]);
        const testWatch = project.tasks.tryFind("test:watch");
        testWatch?.reset(`${reactScripts} test`);
        project.npmignore?.exclude("# Build", "/build/");
        project.gitignore.exclude("# Build", "/build/");
        project.package.addField("eslintConfig", {
            extends: ["react-app", "react-app/jest"],
        });
        project.package.addField("browserslist", {
            production: [">0.2%", "not dead", "not op_mini all"],
            development: [
                "last 1 chrome version",
                "last 1 firefox version",
                "last 1 safari version",
            ],
        });
    }
}
exports.ReactComponent = ReactComponent;
class ReactSampleCode extends component_1.Component {
    fileExt;
    srcdir;
    constructor(project, options) {
        super(project);
        this.fileExt = options.fileExt ?? "jsx";
        this.srcdir = options.srcdir;
        const logoSvg = [
            '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">',
            '    <g fill="#61DAFB">',
            '        <path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>',
            '        <circle cx="420.9" cy="296.5" r="45.7"/>',
            '        <path d="M520.5 78.1z"/>',
            "    </g>",
            "</svg>",
            "",
        ];
        const appJsx = [
            "import logo from './logo.svg';",
            "import './App.css'",
            "",
            "function App() {",
            "  return (",
            '   <div className="App">',
            '      <header className="App-header">',
            '        <img src={logo} className="App-logo" alt="logo" />',
            "        <p>",
            `          Edit <code>src/App.${this.fileExt}</code> and save to reload.`,
            "        </p>",
            '        <a className="App-link"',
            '          href="https://reactjs.org"',
            '          target="_blank"',
            '          rel="noopener noreferrer"',
            "        >",
            "          Learn React",
            "        </a>",
            "      </header>",
            "    </div>",
            "  );",
            "}",
            "",
            "export default App;",
            "",
        ];
        const appCss = [
            ".App {",
            "  text-align: center;",
            "}",
            "",
            ".App-logo {",
            "  height: 40vmin;",
            "  pointer-events: none;",
            "}",
            "",
            "@media (prefers-reduced-motion: no-preference) {",
            "  .App-logo {",
            "    animation: App-logo-spin infinite 20s linear;",
            "  }",
            "}",
            "",
            ".App-header {",
            "  background-color: #282c34;",
            "  min-height: 100vh;",
            "  display: flex;",
            "  flex-direction: column;",
            "  align-items: center;",
            "  justify-content: center;",
            "  font-size: calc(10px + 2vmin);",
            "  color: white;",
            "}",
            "",
            ".App-link {",
            "  color: #61dafb;",
            "}",
            "",
            "@keyframes App-logo-spin {",
            "  from {",
            "    transform: rotate(0deg);",
            "  }",
            "  to {",
            "    transform: rotate(360deg);",
            "  }",
            "}",
            "",
        ];
        const appTestJsx = [
            "import { render, screen } from '@testing-library/react';",
            "import App from './App';",
            "",
            "test('renders learn react link', () => {",
            "  render(<App />);",
            "  const linkElement = screen.getByText(/learn react/i);",
            "  expect(linkElement).toBeInTheDocument();",
            "});",
            "",
        ];
        const indexJsx = [
            "import React from 'react';",
            "import ReactDOM from 'react-dom';",
            "import './index.css';",
            "import App from './App';",
            "import reportWebVitals from './reportWebVitals';",
            "",
            "ReactDOM.render(",
            "  <React.StrictMode>",
            "    <App />",
            "  </React.StrictMode>,",
            "  document.getElementById('root')",
            ");",
            "",
            "// If you want to start measuring performance in your app, pass a function",
            "// to log results (for example: reportWebVitals(console.log))",
            "// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals",
            "reportWebVitals();",
            "",
        ];
        const indexCss = [
            "body {",
            "  margin: 0;",
            "  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',",
            "    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',",
            "    sans-serif;",
            "  -webkit-font-smoothing: antialiased;",
            "  -moz-osx-font-smoothing: grayscale;",
            "}",
            "",
            "code {",
            "  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',",
            "    monospace;",
            "}",
            "",
        ];
        const reportWebVitalsJs = [
            "import { ReportHandler } from 'web-vitals';",
            "",
            "const reportWebVitals = (onPerfEntry?: ReportHandler) => {",
            "  if (onPerfEntry && onPerfEntry instanceof Function) {",
            "    import('web-vitals').then(",
            "      ({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {",
            "        getCLS(onPerfEntry);",
            "        getFID(onPerfEntry);",
            "        getFCP(onPerfEntry);",
            "        getLCP(onPerfEntry);",
            "        getTTFB(onPerfEntry);",
            "      },",
            "      () => {}",
            "    );",
            "  }",
            "};",
            "",
            "export default reportWebVitals;",
        ];
        const setupTestsJs = [
            "// jest-dom adds custom jest matchers for asserting on DOM nodes.",
            "// allows you to do things like:",
            "// expect(element).toHaveTextContent(/react/i)",
            "// learn more: https://github.com/testing-library/jest-dom",
            "import '@testing-library/jest-dom';",
            "",
        ];
        const reactTypeDef = ['/// <reference types="react-scripts" />'];
        // js/ts not jsx/tsx
        const fileExtWithoutX = this.fileExt.replace("x", "");
        new sample_file_1.SampleDir(project, this.srcdir, {
            files: {
                "react-app-env.d.ts": reactTypeDef.join("\n"),
                "logo.svg": logoSvg.join("\n"),
                ["App." + this.fileExt]: appJsx.join("\n"),
                ["App.test." + this.fileExt]: appTestJsx.join("\n"),
                "App.css": appCss.join("\n"),
                ["index." + this.fileExt]: indexJsx.join("\n"),
                "index.css": indexCss.join("\n"),
                ["reportWebVitals." + fileExtWithoutX]: reportWebVitalsJs.join("\n"),
                ["setupTests." + fileExtWithoutX]: setupTestsJs.join("\n"),
            },
        });
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd2ViL3JlYWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFDN0IsNENBQXlDO0FBRXpDLDhDQUl1QjtBQUN2QixnREFBMkM7QUFDM0MsZ0RBQTRDO0FBRTVDLDhDQUFxRDtBQUNyRCxrQ0FBb0M7QUF3RHBDOzs7O0dBSUc7QUFDSCxNQUFhLFlBQWEsU0FBUSx3QkFBVzs7SUFDM0M7OztPQUdHO0lBQ2EsTUFBTSxDQUFTO0lBRS9CLFlBQVksT0FBNEI7UUFDdEMsS0FBSyxDQUFDO1lBQ0osSUFBSSxFQUFFLEtBQUs7WUFDWCxHQUFHLE9BQU87U0FDWCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDO1FBRXRDLElBQUksY0FBYyxDQUFDLElBQUksRUFBRSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBRXhFLDZGQUE2RjtRQUM3RixJQUFJLE9BQU8sQ0FBQyxVQUFVLElBQUksSUFBSSxFQUFFLENBQUM7WUFDL0IsSUFBSSxlQUFlLENBQUMsSUFBSSxFQUFFO2dCQUN4QixPQUFPLEVBQUUsS0FBSztnQkFDZCxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07YUFDcEIsQ0FBQyxDQUFDO1lBQ0gsSUFBSSx1QkFBUyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7Z0JBQzVCLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDO2FBQ3RFLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDOztBQTNCSCxvQ0E0QkM7QUFFRDs7OztHQUlHO0FB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QyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUMxQyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ25ELFNBQVMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDNUIsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUM5QyxXQUFXLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ2hDLENBQUMsa0JBQWtCLEdBQUcsZUFBZSxDQUFDLEVBQUUsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDcEUsQ0FBQyxhQUFhLEdBQUcsZUFBZSxDQUFDLEVBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7YUFDM0Q7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi4vY29tcG9uZW50XCI7XG5pbXBvcnQgdHlwZSB7IE5vZGVQcm9qZWN0T3B0aW9ucyB9IGZyb20gXCIuLi9qYXZhc2NyaXB0XCI7XG5pbXBvcnQge1xuICBOb2RlUHJvamVjdCxcbiAgVHlwZVNjcmlwdEpzeE1vZGUsXG4gIFR5cGVTY3JpcHRNb2R1bGVSZXNvbHV0aW9uLFxufSBmcm9tIFwiLi4vamF2YXNjcmlwdFwiO1xuaW1wb3J0IHsgU2FtcGxlRGlyIH0gZnJvbSBcIi4uL3NhbXBsZS1maWxlXCI7XG5pbXBvcnQgeyBTb3VyY2VDb2RlIH0gZnJvbSBcIi4uL3NvdXJjZS1jb2RlXCI7XG5pbXBvcnQgdHlwZSB7IFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc2NyaXB0XCI7XG5pbXBvcnQgeyBUeXBlU2NyaXB0QXBwUHJvamVjdCB9IGZyb20gXCIuLi90eXBlc2NyaXB0XCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UgfSBmcm9tIFwiLi4vdXRpbFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlYWN0UmV3aXJlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBSZXdpcmUgd2VicGFjayBjb25maWd1cmF0aW9uLlxuICAgKlxuICAgKiBVc2UgdGhpcyBwcm9wZXJ0eSB0byBvdmVycmlkZSB3ZWJwYWNrIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllcyBwcm92aWRlZFxuICAgKiBieSBjcmVhdGUtcmVhY3QtYXBwLCB3aXRob3V0IG5lZWRpbmcgdG8gZWplY3QuXG4gICAqXG4gICAqIFRoaXMgcHJvcGVydHkgd2lsbCBjcmVhdGUgYSBgY29uZmlnLW92ZXJyaWRlcy5qc2AgZmlsZSBpbiB5b3VyIHJvb3QgZGlyZWN0b3J5LFxuICAgKiB3aGljaCB3aWxsIGNvbnRhaW4gdGhlIGRlc2lyZWQgcmV3aXJpbmcgY29kZS5cbiAgICpcbiAgICogVG8gKipvdmVycmlkZSoqIHRoZSBjb25maWd1cmF0aW9uLCB5b3UgY2FuIHByb3ZpZGUgc2ltcGxlIGtleSB2YWx1ZSBwYWlycy5cbiAgICogS2V5cyB0YWtlIHRoZSBmb3JtIG9mIGpzIGNvZGUgZGlyZWN0aXZlcyB0aGF0IHRyYXZlcnNlIHRvIHRoZSBkZXNpcmVkIHByb3BlcnR5LlxuICAgKiBWYWx1ZXMgc2hvdWxkIGJlIEpTT04gc2VyaWFsaXphYmxlIG9iamVjdHMuXG4gICAqXG4gICAqIEZvciBleGFtcGxlLCB0aGUgZm9sbG93aW5nIGNvbmZpZzpcbiAgICpcbiAgICogYGBganNvblxuICAgKiByZXdpcmU6IHsgXCJtb2R1bGUudW5rbm93bkNvbnRleHRDcml0aWNhbFwiOiBmYWxzZSB9XG4gICAqIGBgYFxuICAgKlxuICAgKiBXaWxsIHRyYW5zbGF0ZSB0byB0aGUgZm9sbG93aW5nIGBjb25maWctb3ZlcnJpZGVzLmpzYCBmaWxlOlxuICAgKlxuICAgKiBgYGBqc1xuICAgKiBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG92ZXJyaWRlKGNvbmZpZywgZW52KSB7XG4gICAqICAgY29uZmlnLm1vZHVsZS51bmtub3duQ29udGV4dENyaXRpY2FsID0gZmFsc2U7XG4gICAqIH1cbiAgICogYGBgXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gcmV3aXJlZCBjb25maWcuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly93ZWJwYWNrLmpzLm9yZy9jb25maWd1cmF0aW9uL1xuICAgKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS90aW1hcm5leS9yZWFjdC1hcHAtcmV3aXJlZFxuICAgKi9cbiAgcmVhZG9ubHkgcmV3aXJlPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWFjdFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9uc1xuICBleHRlbmRzIFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9ucywgUmVhY3RSZXdpcmVPcHRpb25zIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVhY3RQcm9qZWN0T3B0aW9uc1xuICBleHRlbmRzIE5vZGVQcm9qZWN0T3B0aW9ucywgUmVhY3RSZXdpcmVPcHRpb25zIHtcbiAgLyoqXG4gICAqIFNvdXJjZSBkaXJlY3RvcnkuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwic3JjXCJcbiAgICovXG4gIHJlYWRvbmx5IHNyY2Rpcj86IHN0cmluZztcbiAgLyoqXG4gICAqIEdlbmVyYXRlIG9uZS10aW1lIHNhbXBsZSBpbiBgc3JjL2AgYW5kIGBwdWJsaWMvYCBpZiB0aGVyZSBhcmUgbm8gZmlsZXMgdGhlcmUuXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHNhbXBsZUNvZGU/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFJlYWN0IHByb2plY3QgdXNpbmcgSmF2YVNjcmlwdC5cbiAqXG4gKiBAcGppZCByZWFjdFxuICovXG5leHBvcnQgY2xhc3MgUmVhY3RQcm9qZWN0IGV4dGVuZHMgTm9kZVByb2plY3Qge1xuICAvKipcbiAgICogVGhlIGRpcmVjdG9yeSBpbiB3aGljaCBzb3VyY2UgZmlsZXMgcmVzaWRlLlxuICAgKiBAZGVmYXVsdCBcInNyY1wiXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3JjZGlyOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogUmVhY3RQcm9qZWN0T3B0aW9ucykge1xuICAgIHN1cGVyKHtcbiAgICAgIGplc3Q6IGZhbHNlLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcblxuICAgIHRoaXMuc3JjZGlyID0gb3B0aW9ucy5zcmNkaXIgPz8gXCJzcmNcIjtcblxuICAgIG5ldyBSZWFjdENvbXBvbmVudCh0aGlzLCB7IHR5cGVzY3JpcHQ6IGZhbHNlLCByZXdpcmU6IG9wdGlvbnMucmV3aXJlIH0pO1xuXG4gICAgLy8gZ2VuZXJhdGUgc2FtcGxlIGNvZGUgaW4gYHNyY2AgYW5kIGBwdWJsaWNgIGlmIHRoZXNlIGRpcmVjdG9yaWVzIGFyZSBlbXB0eSBvciBub24tZXhpc3RlbnQuXG4gICAgaWYgKG9wdGlvbnMuc2FtcGxlQ29kZSA/PyB0cnVlKSB7XG4gICAgICBuZXcgUmVhY3RTYW1wbGVDb2RlKHRoaXMsIHtcbiAgICAgICAgZmlsZUV4dDogXCJqc3hcIixcbiAgICAgICAgc3JjZGlyOiB0aGlzLnNyY2RpcixcbiAgICAgIH0pO1xuICAgICAgbmV3IFNhbXBsZURpcih0aGlzLCBcInB1YmxpY1wiLCB7XG4gICAgICAgIHNvdXJjZURpcjogcGF0aC5qb2luKF9fZGlybmFtZSwgXCIuLlwiLCBcIi4uXCIsIFwiYXNzZXRzXCIsIFwid2ViXCIsIFwicmVhY3RcIiksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZWFjdCBwcm9qZWN0IHVzaW5nIFR5cGVTY3JpcHQuXG4gKlxuICogQHBqaWQgcmVhY3QtdHNcbiAqL1xuZXhwb3J0IGNsYXNzIFJlYWN0VHlwZVNjcmlwdFByb2plY3QgZXh0ZW5kcyBUeXBlU2NyaXB0QXBwUHJvamVjdCB7XG4gIC8qKlxuICAgKiBUaGUgZGlyZWN0b3J5IGluIHdoaWNoIHNvdXJjZSBmaWxlcyByZXNpZGUuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3JjZGlyOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogUmVhY3RUeXBlU2NyaXB0UHJvamVjdE9wdGlvbnMpIHtcbiAgICBjb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICAgIHNyY2RpcjogXCJzcmNcIixcbiAgICAgIGVzbGludDogdHJ1ZSxcbiAgICAgIGplc3Q6IGZhbHNlLFxuICAgICAgdHNjb25maWc6IHtcbiAgICAgICAgaW5jbHVkZTogW1wic3JjXCJdLFxuICAgICAgICBjb21waWxlck9wdGlvbnM6IHtcbiAgICAgICAgICB0YXJnZXQ6IFwiZXM1XCIsXG4gICAgICAgICAgbGliOiBbXCJkb21cIiwgXCJkb20uaXRlcmFibGVcIiwgXCJlc25leHRcIl0sXG4gICAgICAgICAgYWxsb3dKczogdHJ1ZSxcbiAgICAgICAgICBza2lwTGliQ2hlY2s6IHRydWUsXG4gICAgICAgICAgZXNNb2R1bGVJbnRlcm9wOiB0cnVlLFxuICAgICAgICAgIGFsbG93U3ludGhldGljRGVmYXVsdEltcG9ydHM6IHRydWUsXG4gICAgICAgICAgc3RyaWN0OiB0cnVlLFxuICAgICAgICAgIGZvcmNlQ29uc2lzdGVudENhc2luZ0luRmlsZU5hbWVzOiB0cnVlLFxuICAgICAgICAgIG5vRmFsbHRocm91Z2hDYXNlc0luU3dpdGNoOiB0cnVlLFxuICAgICAgICAgIG1vZHVsZTogXCJjb21tb25qc1wiLFxuICAgICAgICAgIG1vZHVsZVJlc29sdXRpb246IFR5cGVTY3JpcHRNb2R1bGVSZXNvbHV0aW9uLk5PREUsXG4gICAgICAgICAgcmVzb2x2ZUpzb25Nb2R1bGU6IHRydWUsXG4gICAgICAgICAgaXNvbGF0ZWRNb2R1bGVzOiB0cnVlLFxuICAgICAgICAgIG5vRW1pdDogdHJ1ZSxcbiAgICAgICAgICBqc3g6IFR5cGVTY3JpcHRKc3hNb2RlLlJFQUNUX0pTWCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB0eXBlc2NyaXB0VmVyc2lvbjogb3B0aW9ucy50eXBlc2NyaXB0VmVyc2lvbiA/PyBcIl40LjAuM1wiLFxuICAgIH07XG5cbiAgICAvLyBuZXZlciBnZW5lcmF0ZSBkZWZhdWx0IFR5cGVTY3JpcHQgc2FtcGxlIGNvZGUsIHNpbmNlIHRoaXMgY2xhc3MgcHJvdmlkZXMgaXRzIG93blxuICAgIHN1cGVyKFxuICAgICAgZGVlcE1lcmdlKFtcbiAgICAgICAgZGVmYXVsdE9wdGlvbnMsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHsgc2FtcGxlQ29kZTogZmFsc2UgfSxcbiAgICAgIF0pIGFzIFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9ucyxcbiAgICApO1xuXG4gICAgdGhpcy5zcmNkaXIgPSBvcHRpb25zLnNyY2RpciA/PyBcInNyY1wiO1xuXG4gICAgdGhpcy5lc2xpbnQ/LmFkZFJ1bGVzKHtcbiAgICAgIFwiaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXCI6IFtcbiAgICAgICAgXCJlcnJvclwiLFxuICAgICAgICB7XG4gICAgICAgICAgZGV2RGVwZW5kZW5jaWVzOiBbXCIqKi9zcmMvKiovKi50ZXN0LnRzeFwiLCBcIioqL3NyYy9zZXR1cFRlc3RzLnRzXCJdLFxuICAgICAgICAgIG9wdGlvbmFsRGVwZW5kZW5jaWVzOiBmYWxzZSxcbiAgICAgICAgICBwZWVyRGVwZW5kZW5jaWVzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIG5ldyBSZWFjdENvbXBvbmVudCh0aGlzLCB7IHR5cGVzY3JpcHQ6IHRydWUsIHJld2lyZTogb3B0aW9ucy5yZXdpcmUgfSk7XG5cbiAgICAvLyBnZW5lcmF0ZSBzYW1wbGUgY29kZSBpbiBgc3JjYCBhbmQgYHB1YmxpY2AgaWYgdGhlc2UgZGlyZWN0b3JpZXMgYXJlIGVtcHR5IG9yIG5vbi1leGlzdGVudC5cbiAgICBpZiAob3B0aW9ucy5zYW1wbGVDb2RlID8/IHRydWUpIHtcbiAgICAgIG5ldyBSZWFjdFNhbXBsZUNvZGUodGhpcywge1xuICAgICAgICBmaWxlRXh0OiBcInRzeFwiLFxuICAgICAgICBzcmNkaXI6IHRoaXMuc3JjZGlyLFxuICAgICAgfSk7XG4gICAgICBuZXcgU2FtcGxlRGlyKHRoaXMsIFwicHVibGljXCIsIHtcbiAgICAgICAgc291cmNlRGlyOiBwYXRoLmpvaW4oX19kaXJuYW1lLCBcIi4uXCIsIFwiLi5cIiwgXCJhc3NldHNcIiwgXCJ3ZWJcIiwgXCJyZWFjdFwiKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMucGFja2FnZS5hZGRQYWNrYWdlUmVzb2x1dGlvbnMoXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vRGVmaW5pdGVseVR5cGVkL0RlZmluaXRlbHlUeXBlZC9pc3N1ZXMvNjIzMDBcbiAgICAgIFwiQHR5cGVzL2V4cHJlc3NANC4xNy4xM1wiLFxuICAgICAgXCJAdHlwZXMvZXhwcmVzcy1zZXJ2ZS1zdGF0aWMtY29yZUA0LjE3LjMwXCIsXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlYWN0Q29tcG9uZW50T3B0aW9ucyBleHRlbmRzIFJlYWN0UmV3aXJlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGFwcGx5IG9wdGlvbnMgc3BlY2lmaWMgZm9yIFR5cGVTY3JpcHQgUmVhY3QgcHJvamVjdHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSB0eXBlc2NyaXB0PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIFJlYWN0Q29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSB0eXBlc2NyaXB0OiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKHByb2plY3Q6IE5vZGVQcm9qZWN0LCBvcHRpb25zOiBSZWFjdENvbXBvbmVudE9wdGlvbnMpIHtcbiAgICBzdXBlcihwcm9qZWN0KTtcblxuICAgIHRoaXMudHlwZXNjcmlwdCA9IG9wdGlvbnMudHlwZXNjcmlwdCA/PyBmYWxzZTtcblxuICAgIC8vIE5vIGNvbXBpbGUgZm9yIHJlYWN0IGFwcFxuICAgIHByb2plY3QuY29tcGlsZVRhc2sucmVzZXQoKTtcblxuICAgIHByb2plY3QuYWRkRGVwcyhcInJlYWN0XCIsIFwicmVhY3QtZG9tXCIsIFwid2ViLXZpdGFsc1wiKTtcbiAgICBwcm9qZWN0LmFkZERldkRlcHMoXG4gICAgICBcInJlYWN0LXNjcmlwdHNAXjVcIixcbiAgICAgIFwiQHRlc3RpbmctbGlicmFyeS9kb21cIixcbiAgICAgIFwiQHRlc3RpbmctbGlicmFyeS9qZXN0LWRvbVwiLFxuICAgICAgXCJAdGVzdGluZy1saWJyYXJ5L3JlYWN0XCIsXG4gICAgICBcIkB0ZXN0aW5nLWxpYnJhcnkvdXNlci1ldmVudFwiLFxuICAgICk7XG4gICAgaWYgKHRoaXMudHlwZXNjcmlwdCkge1xuICAgICAgcHJvamVjdC5hZGREZXZEZXBzKFwiQHR5cGVzL2plc3RcIiwgXCJAdHlwZXMvcmVhY3RcIiwgXCJAdHlwZXMvcmVhY3QtZG9tXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHJld2lyZSA9IG9wdGlvbnMucmV3aXJlID8/IGZhbHNlO1xuXG4gICAgaWYgKHJld2lyZSkge1xuICAgICAgY29uc3Qgb3ZlcnJpZGVzUGF0aCA9IFwiLnByb2plbi9yZWFjdC1jb25maWctb3ZlcnJpZGVzLmpzXCI7XG4gICAgICBwcm9qZWN0LmFkZERldkRlcHMoXCJyZWFjdC1hcHAtcmV3aXJlZFwiKTtcbiAgICAgIHByb2plY3QuYWRkRmllbGRzKHsgXCJjb25maWctb3ZlcnJpZGVzLXBhdGhcIjogb3ZlcnJpZGVzUGF0aCB9KTtcblxuICAgICAgY29uc3QgY29uZmlnT3ZlcnJpZGVzID0gbmV3IFNvdXJjZUNvZGUodGhpcy5wcm9qZWN0LCBvdmVycmlkZXNQYXRoKTtcbiAgICAgIGlmICghY29uZmlnT3ZlcnJpZGVzLm1hcmtlcikge1xuICAgICAgICBjb25maWdPdmVycmlkZXMubGluZShgLy8gJHtjb25maWdPdmVycmlkZXMubWFya2VyfWApO1xuICAgICAgfVxuICAgICAgY29uZmlnT3ZlcnJpZGVzLmxpbmUoXCIvKipcIik7XG4gICAgICBjb25maWdPdmVycmlkZXMubGluZShcbiAgICAgICAgXCIgKiBPdmVycmlkZSBDUkEgY29uZmlndXJhdGlvbiB3aXRob3V0IG5lZWRpbmcgdG8gZWplY3QuXCIsXG4gICAgICApO1xuICAgICAgY29uZmlnT3ZlcnJpZGVzLmxpbmUoXCIgKlwiKTtcbiAgICAgIGNvbmZpZ092ZXJyaWRlcy5saW5lKFxuICAgICAgICBcIiAqIEBzZWUgaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvcmVhY3QtYXBwLXJld2lyZWRcIixcbiAgICAgICk7XG4gICAgICBjb25maWdPdmVycmlkZXMubGluZShcIiAqL1wiKTtcbiAgICAgIGNvbmZpZ092ZXJyaWRlcy5vcGVuKFwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBvdmVycmlkZShjb25maWcsIGVudikge1wiKTtcbiAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHJld2lyZSkpIHtcbiAgICAgICAgY29uZmlnT3ZlcnJpZGVzLmxpbmUoYGNvbmZpZy4ke2tleX0gPSAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX07YCk7XG4gICAgICB9XG4gICAgICBjb25maWdPdmVycmlkZXMubGluZShcInJldHVybiBjb25maWc7XCIpO1xuICAgICAgY29uZmlnT3ZlcnJpZGVzLmNsb3NlKFwifTtcIik7XG4gICAgfVxuXG4gICAgY29uc3QgcmVhY3RTY3JpcHRzID0gcmV3aXJlID8gXCJyZWFjdC1hcHAtcmV3aXJlZFwiIDogXCJyZWFjdC1zY3JpcHRzXCI7XG5cbiAgICAvLyBDcmVhdGUgUmVhY3QgQXBwIENMSSBjb21tYW5kcywgc2VlOiBodHRwczovL2NyZWF0ZS1yZWFjdC1hcHAuZGV2L2RvY3MvYXZhaWxhYmxlLXNjcmlwdHMvXG4gICAgcHJvamVjdC5hZGRUYXNrKFwiZGV2XCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlN0YXJ0cyB0aGUgcmVhY3QgYXBwbGljYXRpb25cIixcbiAgICAgIGV4ZWNBcmdzOiBbcmVhY3RTY3JpcHRzLCBcInN0YXJ0XCJdLFxuICAgIH0pO1xuXG4gICAgcHJvamVjdC5jb21waWxlVGFzay5leGVjQXJncyhbcmVhY3RTY3JpcHRzLCBcImJ1aWxkXCJdKTtcblxuICAgIHByb2plY3QudGVzdFRhc2suZXhlY0FyZ3MoW3JlYWN0U2NyaXB0cywgXCJ0ZXN0XCIsIFwiLS13YXRjaEFsbD1mYWxzZVwiXSk7XG5cbiAgICBjb25zdCB0ZXN0V2F0Y2ggPSBwcm9qZWN0LnRhc2tzLnRyeUZpbmQoXCJ0ZXN0OndhdGNoXCIpO1xuICAgIHRlc3RXYXRjaD8ucmVzZXQoYCR7cmVhY3RTY3JpcHRzfSB0ZXN0YCk7XG5cbiAgICBwcm9qZWN0Lm5wbWlnbm9yZT8uZXhjbHVkZShcIiMgQnVpbGRcIiwgXCIvYnVpbGQvXCIpO1xuICAgIHByb2plY3QuZ2l0aWdub3JlLmV4Y2x1ZGUoXCIjIEJ1aWxkXCIsIFwiL2J1aWxkL1wiKTtcblxuICAgIHByb2plY3QucGFja2FnZS5hZGRGaWVsZChcImVzbGludENvbmZpZ1wiLCB7XG4gICAgICBleHRlbmRzOiBbXCJyZWFjdC1hcHBcIiwgXCJyZWFjdC1hcHAvamVzdFwiXSxcbiAgICB9KTtcblxuICAgIHByb2plY3QucGFja2FnZS5hZGRGaWVsZChcImJyb3dzZXJzbGlzdFwiLCB7XG4gICAgICBwcm9kdWN0aW9uOiBbXCI+MC4yJVwiLCBcIm5vdCBkZWFkXCIsIFwibm90IG9wX21pbmkgYWxsXCJdLFxuICAgICAgZGV2ZWxvcG1lbnQ6IFtcbiAgICAgICAgXCJsYXN0IDEgY2hyb21lIHZlcnNpb25cIixcbiAgICAgICAgXCJsYXN0IDEgZmlyZWZveCB2ZXJzaW9uXCIsXG4gICAgICAgIFwibGFzdCAxIHNhZmFyaSB2ZXJzaW9uXCIsXG4gICAgICBdLFxuICAgIH0pO1xuICB9XG59XG5cbmludGVyZmFjZSBSZWFjdFNhbXBsZUNvZGVPcHRpb25zIHtcbiAgLyoqXG4gICAqIEZpbGUgZXh0ZW5zaW9uIGZvciBzYW1wbGUgamF2YXNjcmlwdCBjb2RlIHRvIGJlIHNhdmVkIGFzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcImpzeFwiXG4gICAqL1xuICByZWFkb25seSBmaWxlRXh0Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZGlyZWN0b3J5IGluIHdoaWNoIFJlYWN0IGpzeCBmaWxlcyBhcmUgZGVjbGFyZWQuXG4gICAqL1xuICByZWFkb25seSBzcmNkaXI6IHN0cmluZztcbn1cblxuY2xhc3MgUmVhY3RTYW1wbGVDb2RlIGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSBmaWxlRXh0OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3JjZGlyOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocHJvamVjdDogTm9kZVByb2plY3QsIG9wdGlvbnM6IFJlYWN0U2FtcGxlQ29kZU9wdGlvbnMpIHtcbiAgICBzdXBlcihwcm9qZWN0KTtcblxuICAgIHRoaXMuZmlsZUV4dCA9IG9wdGlvbnMuZmlsZUV4dCA/PyBcImpzeFwiO1xuICAgIHRoaXMuc3JjZGlyID0gb3B0aW9ucy5zcmNkaXI7XG5cbiAgICBjb25zdCBsb2dvU3ZnID0gW1xuICAgICAgJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgODQxLjkgNTk1LjNcIj4nLFxuICAgICAgJyAgICA8ZyBmaWxsPVwiIzYxREFGQlwiPicsXG4gICAgICAnICAgICAgICA8cGF0aCBkPVwiTTY2Ni4zIDI5Ni41YzAtMzIuNS00MC43LTYzLjMtMTAzLjEtODIuNCAxNC40LTYzLjYgOC0xMTQuMi0yMC4yLTEzMC40LTYuNS0zLjgtMTQuMS01LjYtMjIuNC01LjZ2MjIuM2M0LjYgMCA4LjMuOSAxMS40IDIuNiAxMy42IDcuOCAxOS41IDM3LjUgMTQuOSA3NS43LTEuMSA5LjQtMi45IDE5LjMtNS4xIDI5LjQtMTkuNi00LjgtNDEtOC41LTYzLjUtMTAuOS0xMy41LTE4LjUtMjcuNS0zNS4zLTQxLjYtNTAgMzIuNi0zMC4zIDYzLjItNDYuOSA4NC00Ni45Vjc4Yy0yNy41IDAtNjMuNSAxOS42LTk5LjkgNTMuNi0zNi40LTMzLjgtNzIuNC01My4yLTk5LjktNTMuMnYyMi4zYzIwLjcgMCA1MS40IDE2LjUgODQgNDYuNi0xNCAxNC43LTI4IDMxLjQtNDEuMyA0OS45LTIyLjYgMi40LTQ0IDYuMS02My42IDExLTIuMy0xMC00LTE5LjctNS4yLTI5LTQuNy0zOC4yIDEuMS02Ny45IDE0LjYtNzUuOCAzLTEuOCA2LjktMi42IDExLjUtMi42Vjc4LjVjLTguNCAwLTE2IDEuOC0yMi42IDUuNi0yOC4xIDE2LjItMzQuNCA2Ni43LTE5LjkgMTMwLjEtNjIuMiAxOS4yLTEwMi43IDQ5LjktMTAyLjcgODIuMyAwIDMyLjUgNDAuNyA2My4zIDEwMy4xIDgyLjQtMTQuNCA2My42LTggMTE0LjIgMjAuMiAxMzAuNCA2LjUgMy44IDE0LjEgNS42IDIyLjUgNS42IDI3LjUgMCA2My41LTE5LjYgOTkuOS01My42IDM2LjQgMzMuOCA3Mi40IDUzLjIgOTkuOSA1My4yIDguNCAwIDE2LTEuOCAyMi42LTUuNiAyOC4xLTE2LjIgMzQuNC02Ni43IDE5LjktMTMwLjEgNjItMTkuMSAxMDIuNS00OS45IDEwMi41LTgyLjN6bS0xMzAuMi02Ni43Yy0zLjcgMTIuOS04LjMgMjYuMi0xMy41IDM5LjUtNC4xLTgtOC40LTE2LTEzLjEtMjQtNC42LTgtOS41LTE1LjgtMTQuNC0yMy40IDE0LjIgMi4xIDI3LjkgNC43IDQxIDcuOXptLTQ1LjggMTA2LjVjLTcuOCAxMy41LTE1LjggMjYuMy0yNC4xIDM4LjItMTQuOSAxLjMtMzAgMi00NS4yIDItMTUuMSAwLTMwLjItLjctNDUtMS45LTguMy0xMS45LTE2LjQtMjQuNi0yNC4yLTM4LTcuNi0xMy4xLTE0LjUtMjYuNC0yMC44LTM5LjggNi4yLTEzLjQgMTMuMi0yNi44IDIwLjctMzkuOSA3LjgtMTMuNSAxNS44LTI2LjMgMjQuMS0zOC4yIDE0LjktMS4zIDMwLTIgNDUuMi0yIDE1LjEgMCAzMC4yLjcgNDUgMS45IDguMyAxMS45IDE2LjQgMjQuNiAyNC4yIDM4IDcuNiAxMy4xIDE0LjUgMjYuNCAyMC44IDM5LjgtNi4zIDEzLjQtMTMuMiAyNi44LTIwLjcgMzkuOXptMzIuMy0xM2M1LjQgMTMuNCAxMCAyNi44IDEzLjggMzkuOC0xMy4xIDMuMi0yNi45IDUuOS00MS4yIDggNC45LTcuNyA5LjgtMTUuNiAxNC40LTIzLjcgNC42LTggOC45LTE2LjEgMTMtMjQuMXpNNDIxLjIgNDMwYy05LjMtOS42LTE4LjYtMjAuMy0yNy44LTMyIDkgLjQgMTguMi43IDI3LjUuNyA5LjQgMCAxOC43LS4yIDI3LjgtLjctOSAxMS43LTE4LjMgMjIuNC0yNy41IDMyem0tNzQuNC01OC45Yy0xNC4yLTIuMS0yNy45LTQuNy00MS03LjkgMy43LTEyLjkgOC4zLTI2LjIgMTMuNS0zOS41IDQuMSA4IDguNCAxNiAxMy4xIDI0IDQuNyA4IDkuNSAxNS44IDE0LjQgMjMuNHpNNDIwLjcgMTYzYzkuMyA5LjYgMTguNiAyMC4zIDI3LjggMzItOS0uNC0xOC4yLS43LTI3LjUtLjctOS40IDAtMTguNy4yLTI3LjguNyA5LTExLjcgMTguMy0yMi40IDI3LjUtMzJ6bS03NCA1OC45Yy00LjkgNy43LTkuOCAxNS42LTE0LjQgMjMuNy00LjYgOC04LjkgMTYtMTMgMjQtNS40LTEzLjQtMTAtMjYuOC0xMy44LTM5LjggMTMuMS0zLjEgMjYuOS01LjggNDEuMi03Ljl6bS05MC41IDEyNS4yYy0zNS40LTE1LjEtNTguMy0zNC45LTU4LjMtNTAuNiAwLTE1LjcgMjIuOS0zNS42IDU4LjMtNTAuNiA4LjYtMy43IDE4LTcgMjcuNy0xMC4xIDUuNyAxOS42IDEzLjIgNDAgMjIuNSA2MC45LTkuMiAyMC44LTE2LjYgNDEuMS0yMi4yIDYwLjYtOS45LTMuMS0xOS4zLTYuNS0yOC0xMC4yek0zMTAgNDkwYy0xMy42LTcuOC0xOS41LTM3LjUtMTQuOS03NS43IDEuMS05LjQgMi45LTE5LjMgNS4xLTI5LjQgMTkuNiA0LjggNDEgOC41IDYzLjUgMTAuOSAxMy41IDE4LjUgMjcuNSAzNS4zIDQxLjYgNTAtMzIuNiAzMC4zLTYzLjIgNDYuOS04NCA0Ni45LTQuNS0uMS04LjMtMS0xMS4zLTIuN3ptMjM3LjItNzYuMmM0LjcgMzguMi0xLjEgNjcuOS0xNC42IDc1LjgtMyAxLjgtNi45IDIuNi0xMS41IDIuNi0yMC43IDAtNTEuNC0xNi41LTg0LTQ2LjYgMTQtMTQuNyAyOC0zMS40IDQxLjMtNDkuOSAyMi42LTIuNCA0NC02LjEgNjMuNi0xMSAyLjMgMTAuMSA0LjEgMTkuOCA1LjIgMjkuMXptMzguNS02Ni43Yy04LjYgMy43LTE4IDctMjcuNyAxMC4xLTUuNy0xOS42LTEzLjItNDAtMjIuNS02MC45IDkuMi0yMC44IDE2LjYtNDEuMSAyMi4yLTYwLjYgOS45IDMuMSAxOS4zIDYuNSAyOC4xIDEwLjIgMzUuNCAxNS4xIDU4LjMgMzQuOSA1OC4zIDUwLjYtLjEgMTUuNy0yMyAzNS42LTU4LjQgNTAuNnpNMzIwLjggNzguNHpcIi8+JyxcbiAgICAgICcgICAgICAgIDxjaXJjbGUgY3g9XCI0MjAuOVwiIGN5PVwiMjk2LjVcIiByPVwiNDUuN1wiLz4nLFxuICAgICAgJyAgICAgICAgPHBhdGggZD1cIk01MjAuNSA3OC4xelwiLz4nLFxuICAgICAgXCIgICAgPC9nPlwiLFxuICAgICAgXCI8L3N2Zz5cIixcbiAgICAgIFwiXCIsXG4gICAgXTtcblxuICAgIGNvbnN0IGFwcEpzeCA9IFtcbiAgICAgIFwiaW1wb3J0IGxvZ28gZnJvbSAnLi9sb2dvLnN2Zyc7XCIsXG4gICAgICBcImltcG9ydCAnLi9BcHAuY3NzJ1wiLFxuICAgICAgXCJcIixcbiAgICAgIFwiZnVuY3Rpb24gQXBwKCkge1wiLFxuICAgICAgXCIgIHJldHVybiAoXCIsXG4gICAgICAnICAgPGRpdiBjbGFzc05hbWU9XCJBcHBcIj4nLFxuICAgICAgJyAgICAgIDxoZWFkZXIgY2xhc3NOYW1lPVwiQXBwLWhlYWRlclwiPicsXG4gICAgICAnICAgICAgICA8aW1nIHNyYz17bG9nb30gY2xhc3NOYW1lPVwiQXBwLWxvZ29cIiBhbHQ9XCJsb2dvXCIgLz4nLFxuICAgICAgXCIgICAgICAgIDxwPlwiLFxuICAgICAgYCAgICAgICAgICBFZGl0IDxjb2RlPnNyYy9BcHAuJHt0aGlzLmZpbGVFeHR9PC9jb2RlPiBhbmQgc2F2ZSB0byByZWxvYWQuYCxcbiAgICAgIFwiICAgICAgICA8L3A+XCIsXG4gICAgICAnICAgICAgICA8YSBjbGFzc05hbWU9XCJBcHAtbGlua1wiJyxcbiAgICAgICcgICAgICAgICAgaHJlZj1cImh0dHBzOi8vcmVhY3Rqcy5vcmdcIicsXG4gICAgICAnICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiJyxcbiAgICAgICcgICAgICAgICAgcmVsPVwibm9vcGVuZXIgbm9yZWZlcnJlclwiJyxcbiAgICAgIFwiICAgICAgICA+XCIsXG4gICAgICBcIiAgICAgICAgICBMZWFybiBSZWFjdFwiLFxuICAgICAgXCIgICAgICAgIDwvYT5cIixcbiAgICAgIFwiICAgICAgPC9oZWFkZXI+XCIsXG4gICAgICBcIiAgICA8L2Rpdj5cIixcbiAgICAgIFwiICApO1wiLFxuICAgICAgXCJ9XCIsXG4gICAgICBcIlwiLFxuICAgICAgXCJleHBvcnQgZGVmYXVsdCBBcHA7XCIsXG4gICAgICBcIlwiLFxuICAgIF07XG5cbiAgICBjb25zdCBhcHBDc3MgPSBbXG4gICAgICBcIi5BcHAge1wiLFxuICAgICAgXCIgIHRleHQtYWxpZ246IGNlbnRlcjtcIixcbiAgICAgIFwifVwiLFxuICAgICAgXCJcIixcbiAgICAgIFwiLkFwcC1sb2dvIHtcIixcbiAgICAgIFwiICBoZWlnaHQ6IDQwdm1pbjtcIixcbiAgICAgIFwiICBwb2ludGVyLWV2ZW50czogbm9uZTtcIixcbiAgICAgIFwifVwiLFxuICAgICAgXCJcIixcbiAgICAgIFwiQG1lZGlhIChwcmVmZXJzLXJlZHVjZWQtbW90aW9uOiBuby1wcmVmZXJlbmNlKSB7XCIsXG4gICAgICBcIiAgLkFwcC1sb2dvIHtcIixcbiAgICAgIFwiICAgIGFuaW1hdGlvbjogQXBwLWxvZ28tc3BpbiBpbmZpbml0ZSAyMHMgbGluZWFyO1wiLFxuICAgICAgXCIgIH1cIixcbiAgICAgIFwifVwiLFxuICAgICAgXCJcIixcbiAgICAgIFwiLkFwcC1oZWFkZXIge1wiLFxuICAgICAgXCIgIGJhY2tncm91bmQtY29sb3I6ICMyODJjMzQ7XCIsXG4gICAgICBcIiAgbWluLWhlaWdodDogMTAwdmg7XCIsXG4gICAgICBcIiAgZGlzcGxheTogZmxleDtcIixcbiAgICAgIFwiICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1wiLFxuICAgICAgXCIgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XCIsXG4gICAgICBcIiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XCIsXG4gICAgICBcIiAgZm9udC1zaXplOiBjYWxjKDEwcHggKyAydm1pbik7XCIsXG4gICAgICBcIiAgY29sb3I6IHdoaXRlO1wiLFxuICAgICAgXCJ9XCIsXG4gICAgICBcIlwiLFxuICAgICAgXCIuQXBwLWxpbmsge1wiLFxuICAgICAgXCIgIGNvbG9yOiAjNjFkYWZiO1wiLFxuICAgICAgXCJ9XCIsXG4gICAgICBcIlwiLFxuICAgICAgXCJAa2V5ZnJhbWVzIEFwcC1sb2dvLXNwaW4ge1wiLFxuICAgICAgXCIgIGZyb20ge1wiLFxuICAgICAgXCIgICAgdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7XCIsXG4gICAgICBcIiAgfVwiLFxuICAgICAgXCIgIHRvIHtcIixcbiAgICAgIFwiICAgIHRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7XCIsXG4gICAgICBcIiAgfVwiLFxuICAgICAgXCJ9XCIsXG4gICAgICBcIlwiLFxuICAgIF07XG5cbiAgICBjb25zdCBhcHBUZXN0SnN4ID0gW1xuICAgICAgXCJpbXBvcnQgeyByZW5kZXIsIHNjcmVlbiB9IGZyb20gJ0B0ZXN0aW5nLWxpYnJhcnkvcmVhY3QnO1wiLFxuICAgICAgXCJpbXBvcnQgQXBwIGZyb20gJy4vQXBwJztcIixcbiAgICAgIFwiXCIsXG4gICAgICBcInRlc3QoJ3JlbmRlcnMgbGVhcm4gcmVhY3QgbGluaycsICgpID0+IHtcIixcbiAgICAgIFwiICByZW5kZXIoPEFwcCAvPik7XCIsXG4gICAgICBcIiAgY29uc3QgbGlua0VsZW1lbnQgPSBzY3JlZW4uZ2V0QnlUZXh0KC9sZWFybiByZWFjdC9pKTtcIixcbiAgICAgIFwiICBleHBlY3QobGlua0VsZW1lbnQpLnRvQmVJblRoZURvY3VtZW50KCk7XCIsXG4gICAgICBcIn0pO1wiLFxuICAgICAgXCJcIixcbiAgICBdO1xuXG4gICAgY29uc3QgaW5kZXhKc3ggPSBbXG4gICAgICBcImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XCIsXG4gICAgICBcImltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1wiLFxuICAgICAgXCJpbXBvcnQgJy4vaW5kZXguY3NzJztcIixcbiAgICAgIFwiaW1wb3J0IEFwcCBmcm9tICcuL0FwcCc7XCIsXG4gICAgICBcImltcG9ydCByZXBvcnRXZWJWaXRhbHMgZnJvbSAnLi9yZXBvcnRXZWJWaXRhbHMnO1wiLFxuICAgICAgXCJcIixcbiAgICAgIFwiUmVhY3RET00ucmVuZGVyKFwiLFxuICAgICAgXCIgIDxSZWFjdC5TdHJpY3RNb2RlPlwiLFxuICAgICAgXCIgICAgPEFwcCAvPlwiLFxuICAgICAgXCIgIDwvUmVhY3QuU3RyaWN0TW9kZT4sXCIsXG4gICAgICBcIiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Jvb3QnKVwiLFxuICAgICAgXCIpO1wiLFxuICAgICAgXCJcIixcbiAgICAgIFwiLy8gSWYgeW91IHdhbnQgdG8gc3RhcnQgbWVhc3VyaW5nIHBlcmZvcm1hbmNlIGluIHlvdXIgYXBwLCBwYXNzIGEgZnVuY3Rpb25cIixcbiAgICAgIFwiLy8gdG8gbG9nIHJlc3VsdHMgKGZvciBleGFtcGxlOiByZXBvcnRXZWJWaXRhbHMoY29uc29sZS5sb2cpKVwiLFxuICAgICAgXCIvLyBvciBzZW5kIHRvIGFuIGFuYWx5dGljcyBlbmRwb2ludC4gTGVhcm4gbW9yZTogaHR0cHM6Ly9iaXQubHkvQ1JBLXZpdGFsc1wiLFxuICAgICAgXCJyZXBvcnRXZWJWaXRhbHMoKTtcIixcbiAgICAgIFwiXCIsXG4gICAgXTtcblxuICAgIGNvbnN0IGluZGV4Q3NzID0gW1xuICAgICAgXCJib2R5IHtcIixcbiAgICAgIFwiICBtYXJnaW46IDA7XCIsXG4gICAgICBcIiAgZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgJ1NlZ29lIFVJJywgJ1JvYm90bycsICdPeHlnZW4nLFwiLFxuICAgICAgXCIgICAgJ1VidW50dScsICdDYW50YXJlbGwnLCAnRmlyYSBTYW5zJywgJ0Ryb2lkIFNhbnMnLCAnSGVsdmV0aWNhIE5ldWUnLFwiLFxuICAgICAgXCIgICAgc2Fucy1zZXJpZjtcIixcbiAgICAgIFwiICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDtcIixcbiAgICAgIFwiICAtbW96LW9zeC1mb250LXNtb290aGluZzogZ3JheXNjYWxlO1wiLFxuICAgICAgXCJ9XCIsXG4gICAgICBcIlwiLFxuICAgICAgXCJjb2RlIHtcIixcbiAgICAgIFwiICBmb250LWZhbWlseTogc291cmNlLWNvZGUtcHJvLCBNZW5sbywgTW9uYWNvLCBDb25zb2xhcywgJ0NvdXJpZXIgTmV3JyxcIixcbiAgICAgIFwiICAgIG1vbm9zcGFjZTtcIixcbiAgICAgIFwifVwiLFxuICAgICAgXCJcIixcbiAgICBdO1xuXG4gICAgY29uc3QgcmVwb3J0V2ViVml0YWxzSnMgPSBbXG4gICAgICBcImltcG9ydCB7IFJlcG9ydEhhbmRsZXIgfSBmcm9tICd3ZWItdml0YWxzJztcIixcbiAgICAgIFwiXCIsXG4gICAgICBcImNvbnN0IHJlcG9ydFdlYlZpdGFscyA9IChvblBlcmZFbnRyeT86IFJlcG9ydEhhbmRsZXIpID0+IHtcIixcbiAgICAgIFwiICBpZiAob25QZXJmRW50cnkgJiYgb25QZXJmRW50cnkgaW5zdGFuY2VvZiBGdW5jdGlvbikge1wiLFxuICAgICAgXCIgICAgaW1wb3J0KCd3ZWItdml0YWxzJykudGhlbihcIixcbiAgICAgIFwiICAgICAgKHsgZ2V0Q0xTLCBnZXRGSUQsIGdldEZDUCwgZ2V0TENQLCBnZXRUVEZCIH0pID0+IHtcIixcbiAgICAgIFwiICAgICAgICBnZXRDTFMob25QZXJmRW50cnkpO1wiLFxuICAgICAgXCIgICAgICAgIGdldEZJRChvblBlcmZFbnRyeSk7XCIsXG4gICAgICBcIiAgICAgICAgZ2V0RkNQKG9uUGVyZkVudHJ5KTtcIixcbiAgICAgIFwiICAgICAgICBnZXRMQ1Aob25QZXJmRW50cnkpO1wiLFxuICAgICAgXCIgICAgICAgIGdldFRURkIob25QZXJmRW50cnkpO1wiLFxuICAgICAgXCIgICAgICB9LFwiLFxuICAgICAgXCIgICAgICAoKSA9PiB7fVwiLFxuICAgICAgXCIgICAgKTtcIixcbiAgICAgIFwiICB9XCIsXG4gICAgICBcIn07XCIsXG4gICAgICBcIlwiLFxuICAgICAgXCJleHBvcnQgZGVmYXVsdCByZXBvcnRXZWJWaXRhbHM7XCIsXG4gICAgXTtcblxuICAgIGNvbnN0IHNldHVwVGVzdHNKcyA9IFtcbiAgICAgIFwiLy8gamVzdC1kb20gYWRkcyBjdXN0b20gamVzdCBtYXRjaGVycyBmb3IgYXNzZXJ0aW5nIG9uIERPTSBub2Rlcy5cIixcbiAgICAgIFwiLy8gYWxsb3dzIHlvdSB0byBkbyB0aGluZ3MgbGlrZTpcIixcbiAgICAgIFwiLy8gZXhwZWN0KGVsZW1lbnQpLnRvSGF2ZVRleHRDb250ZW50KC9yZWFjdC9pKVwiLFxuICAgICAgXCIvLyBsZWFybiBtb3JlOiBodHRwczovL2dpdGh1Yi5jb20vdGVzdGluZy1saWJyYXJ5L2plc3QtZG9tXCIsXG4gICAgICBcImltcG9ydCAnQHRlc3RpbmctbGlicmFyeS9qZXN0LWRvbSc7XCIsXG4gICAgICBcIlwiLFxuICAgIF07XG5cbiAgICBjb25zdCByZWFjdFR5cGVEZWYgPSBbJy8vLyA8cmVmZXJlbmNlIHR5cGVzPVwicmVhY3Qtc2NyaXB0c1wiIC8+J107XG5cbiAgICAvLyBqcy90cyBub3QganN4L3RzeFxuICAgIGNvbnN0IGZpbGVFeHRXaXRob3V0WCA9IHRoaXMuZmlsZUV4dC5yZXBsYWNlKFwieFwiLCBcIlwiKTtcblxuICAgIG5ldyBTYW1wbGVEaXIocHJvamVjdCwgdGhpcy5zcmNkaXIsIHtcbiAgICAgIGZpbGVzOiB7XG4gICAgICAgIFwicmVhY3QtYXBwLWVudi5kLnRzXCI6IHJlYWN0VHlwZURlZi5qb2luKFwiXFxuXCIpLFxuICAgICAgICBcImxvZ28uc3ZnXCI6IGxvZ29Tdmcuam9pbihcIlxcblwiKSxcbiAgICAgICAgW1wiQXBwLlwiICsgdGhpcy5maWxlRXh0XTogYXBwSnN4LmpvaW4oXCJcXG5cIiksXG4gICAgICAgIFtcIkFwcC50ZXN0LlwiICsgdGhpcy5maWxlRXh0XTogYXBwVGVzdEpzeC5qb2luKFwiXFxuXCIpLFxuICAgICAgICBcIkFwcC5jc3NcIjogYXBwQ3NzLmpvaW4oXCJcXG5cIiksXG4gICAgICAgIFtcImluZGV4LlwiICsgdGhpcy5maWxlRXh0XTogaW5kZXhKc3guam9pbihcIlxcblwiKSxcbiAgICAgICAgXCJpbmRleC5jc3NcIjogaW5kZXhDc3Muam9pbihcIlxcblwiKSxcbiAgICAgICAgW1wicmVwb3J0V2ViVml0YWxzLlwiICsgZmlsZUV4dFdpdGhvdXRYXTogcmVwb3J0V2ViVml0YWxzSnMuam9pbihcIlxcblwiKSxcbiAgICAgICAgW1wic2V0dXBUZXN0cy5cIiArIGZpbGVFeHRXaXRob3V0WF06IHNldHVwVGVzdHNKcy5qb2luKFwiXFxuXCIpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuIl19