UNPKG

projen

Version:

CDK for software projects

302 lines • 41.8 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.CiConfiguration = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const path = require("path"); const case_1 = require("case"); const component_1 = require("../component"); const yaml_1 = require("../yaml"); /** * CI for GitLab. * A CI is a configurable automated process made up of one or more stages/jobs. * @see https://docs.gitlab.com/ee/ci/yaml/ */ class CiConfiguration extends component_1.Component { get defaultCache() { return this._defaultCache; } constructor(project, name, options) { super(project); /** * Defines default scripts that should run *after* all jobs. Can be overriden by the job level `afterScript`. */ this.defaultAfterScript = []; /** * Defines default scripts that should run *before* all jobs. Can be overriden by the job level `afterScript`. */ this.defaultBeforeScript = []; /** * A default list of additional Docker images to run scripts in. The service image is linked to the image specified in the image parameter. */ this.defaultServices = []; /** * Used to select a specific runner from the list of all runners that are available for the project. */ this.defaultTags = []; /** * Can be `Include` or `Include[]`. Each `Include` will be a string, or an * object with properties for the method if including external YAML file. The external * content will be fetched, included and evaluated along the `.gitlab-ci.yml`. */ this.include = []; /** * Groups jobs into stages. All jobs in one stage must complete before next stage is * executed. Defaults to ['build', 'test', 'deploy']. */ this.stages = []; /** * Global variables that are passed to jobs. * If the job already has that variable defined, the job-level variable takes precedence. */ this.variables = {}; /** * The jobs in the CI configuration. */ this.jobs = {}; this.name = path.parse(name).name; const derivedPath = this.name === "gitlab-ci" ? ".gitlab-ci.yml" : `.gitlab/ci-templates/${name.toLocaleLowerCase()}.yml`; this.path = options?.path ?? derivedPath; this.file = new yaml_1.YamlFile(this.project, this.path, { obj: () => this.renderCI(), // GitLab needs to read the file from the repository in order to work. committed: true, }); const defaults = options?.default; if (defaults) { this.defaultAfterScript.push(...(defaults.afterScript ?? [])); this.defaultArtifacts = defaults.artifacts; defaults.beforeScript && this.defaultBeforeScript.push(...defaults.beforeScript); defaults.cache && this.addDefaultCaches(defaults.cache); this.defaultIdTokens = defaults.idTokens; this.defaultImage = defaults.image; this.defaultInterruptible = defaults.interruptible; this.defaultRetry = defaults.retry; defaults.services && this.addServices(...defaults.services); defaults.tags && this.defaultTags.push(...defaults.tags); this.defaultTimeout = defaults.timeout; } this.pages = options?.pages; this.workflow = options?.workflow; if (options?.stages) { this.addStages(...options.stages); } if (options?.variables) { this.addGlobalVariables(options.variables); } if (options?.jobs) { this.addJobs(options.jobs); } } /** * Add additional yml/yaml files to the CI includes * @param includes The includes to add. */ addIncludes(...includes) { for (const additional of includes) { this.assertIsValidInclude(additional); for (const existing of this.include) { if (this.areEqualIncludes(existing, additional)) { throw new Error(`${this.name}: GitLab CI ${existing} already contains one or more templates specified in ${additional}.`); } } this.include.push(additional); } } /** * Throw an error if the provided Include is invalid. * @see https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/config/external/mapper.rb * @param include the Include to validate. */ assertIsValidInclude(include) { const combos = [ include.local, include.file && include.project, include.remote, include.template, ]; const len = combos.filter((x) => Boolean(x)).length; if (len !== 1) { throw new Error(`${this.name}: GitLab CI include ${include} contains ${len} property combination(s). A valid include configuration specifies *one* of the following property combinations. * local * file, project * remote * template `); } } /** * Check if the equality of Includes. * @see https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/config/external/mapper.rb * @param x First include to compare. * @param y Second include to compare. * @returns Whether the includes are equal. */ areEqualIncludes(x, y) { if (x.local === y.local && x.local !== undefined) { return true; } else if (x.template === y.template && x.template !== undefined) { return true; } else if (x.remote === y.remote && x.remote !== undefined) { return true; } else if (x.project === y.project && x.ref === y.ref) { const xFiles = x.file ? x.file : []; const yFiles = y.file ? y.file : []; const allFiles = xFiles.concat(yFiles); return new Set(allFiles).size !== allFiles.length; } return false; } /** * Add additional services. * @param services The services to add. */ addServices(...services) { for (const additional of services) { for (const existing of this.defaultServices) { if (additional.name === existing.name && additional.alias === existing.alias) { throw new Error(`${this.name}: GitLab CI already contains service ${additional}.`); } } this.defaultServices.push(additional); } } /** * Add a globally defined variable to the CI configuration. * @param variables The variables to add. */ addGlobalVariables(variables) { for (const [key, value] of Object.entries(variables)) { if (this.variables[key] !== undefined) { throw new Error(`${this.name}: GitLab CI already contains variable ${key}.`); } this.variables[key] = value; } } /** * Add stages to the CI configuration if not already present. * @param stages stages to add. */ addStages(...stages) { for (const stage of stages) { if (!this.stages.includes(stage)) { this.stages.push(stage); } } } /** * Add jobs and their stages to the CI configuration. * @param jobs Jobs to add. */ addJobs(jobs) { for (const [key, value] of Object.entries(jobs)) { if (this.jobs[key] !== undefined) { throw new Error(`${this.name}: GitLab CI already contains job ${key}.`); } this.jobs[key] = value; if (value.stage) { this.addStages(value.stage); } if (value.cache) { this.assertIsValidCacheSetup(value.cache); } } } isValidCacheSetup(caches) { const MAX_CONFIGURABLE_CACHES = 4; return caches.length <= MAX_CONFIGURABLE_CACHES; } assertIsValidCacheSetup(caches) { if (!this.isValidCacheSetup(caches)) { throw new Error(`${this.name}: GitLab CI can only define up to 4 caches, got: ${caches.length}`); } } /** * Adds up to 4 default caches configuration to the CI configuration. * @param caches Caches to add. */ addDefaultCaches(caches) { this.assertIsValidCacheSetup(caches); this._defaultCache = caches; } /** * Specify a list of commands to execute on the runner before cloning the Git repository and any submodules * https://docs.gitlab.com/ci/yaml/#hookspre_get_sources_script * @param hooks */ addDefaultHooks(hooks) { this.defaultHooks = hooks; } renderCI() { return { default: this.renderDefault(), include: this.include.length > 0 ? snakeCaseKeys(this.include) : undefined, pages: snakeCaseKeys(this.pages), services: this.defaultServices.length > 0 ? snakeCaseKeys(this.defaultServices) : undefined, variables: Object.entries(this.variables).length > 0 ? this.variables : undefined, workflow: snakeCaseKeys(this.workflow), stages: this.stages.length > 0 ? this.stages : undefined, // we do not want to change job names // as they can be hidden (https://docs.gitlab.com/ee/ci/jobs/index.html#hide-jobs) // or referenced in extends ...snakeCaseKeys(this.jobs, true), }; } renderDefault() { const defaults = { afterScript: this.defaultAfterScript.length > 0 ? this.defaultAfterScript : undefined, artifacts: this.defaultArtifacts, beforeScript: this.defaultBeforeScript.length > 0 ? this.defaultBeforeScript : undefined, cache: this.defaultCache, idTokens: this.defaultIdTokens, image: this.defaultImage, interruptible: this.defaultInterruptible, retry: this.defaultRetry, services: this.defaultServices.length > 0 ? this.defaultServices : undefined, tags: this.defaultTags.length > 0 ? this.defaultTags : undefined, timeout: this.defaultTimeout, hooks: this.defaultHooks, }; return Object.values(defaults).filter((x) => x).length ? snakeCaseKeys(defaults) : undefined; } } exports.CiConfiguration = CiConfiguration; _a = JSII_RTTI_SYMBOL_1; CiConfiguration[_a] = { fqn: "projen.gitlab.CiConfiguration", version: "0.98.32" }; function snakeCaseKeys(obj, skipTopLevel = false) { if (typeof obj !== "object" || obj == null) { return obj; } if (Array.isArray(obj)) { return obj.map((o) => snakeCaseKeys(o)); } const result = {}; for (let [k, v] of Object.entries(obj)) { if (typeof v === "object" && v != null && k !== "variables" && k !== "idTokens" && k !== "inputs") { v = snakeCaseKeys(v); } result[skipTopLevel ? k : (0, case_1.snake)(k)] = v; } return result; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9naXRsYWIvY29uZmlndXJhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZCQUE2QjtBQUM3QiwrQkFBNkI7QUFlN0IsNENBQXlDO0FBRXpDLGtDQUFtQztBQXVDbkM7Ozs7R0FJRztBQUNILE1BQWEsZUFBZ0IsU0FBUSxxQkFBUztJQThCNUMsSUFBVyxZQUFZO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBZ0VELFlBQ0UsT0FBZ0IsRUFDaEIsSUFBWSxFQUNaLE9BQWdDO1FBRWhDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQXhGakI7O1dBRUc7UUFDYSx1QkFBa0IsR0FBYSxFQUFFLENBQUM7UUFLbEQ7O1dBRUc7UUFDYSx3QkFBbUIsR0FBYSxFQUFFLENBQUM7UUFxQm5EOztXQUVHO1FBQ0ssb0JBQWUsR0FBYyxFQUFFLENBQUM7UUFDeEM7O1dBRUc7UUFDTSxnQkFBVyxHQUFhLEVBQUUsQ0FBQztRQWFwQzs7OztXQUlHO1FBQ0ssWUFBTyxHQUFjLEVBQUUsQ0FBQztRQU1oQzs7O1dBR0c7UUFDYSxXQUFNLEdBQWEsRUFBRSxDQUFDO1FBQ3RDOzs7V0FHRztRQUNhLGNBQVMsR0FDdkIsRUFBRSxDQUFDO1FBS0w7O1dBRUc7UUFDYSxTQUFJLEdBQXdCLEVBQUUsQ0FBQztRQVE3QyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ2xDLE1BQU0sV0FBVyxHQUNmLElBQUksQ0FBQyxJQUFJLEtBQUssV0FBVztZQUN2QixDQUFDLENBQUMsZ0JBQWdCO1lBQ2xCLENBQUMsQ0FBQyx3QkFBd0IsSUFBSSxDQUFDLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztRQUM3RCxJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sRUFBRSxJQUFJLElB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QUMsQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7UUFDRCxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUEsWUFBSyxFQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFDRCxPQUFPLE1BQWEsQ0FBQztBQUN2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgc25ha2UgfSBmcm9tIFwiY2FzZVwiO1xuaW1wb3J0IHtcbiAgQXJ0aWZhY3RzLFxuICBDYWNoZSxcbiAgRGVmYXVsdCxcbiAgRGVmYXVsdEhvb2tzLFxuICBJRFRva2VuLFxuICBJbWFnZSxcbiAgSW5jbHVkZSxcbiAgSm9iLFxuICBSZXRyeSxcbiAgU2VydmljZSxcbiAgVmFyaWFibGVDb25maWcsXG4gIFdvcmtmbG93LFxufSBmcm9tIFwiLi9jb25maWd1cmF0aW9uLW1vZGVsXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi4vY29tcG9uZW50XCI7XG5pbXBvcnQgeyBQcm9qZWN0IH0gZnJvbSBcIi4uL3Byb2plY3RcIjtcbmltcG9ydCB7IFlhbWxGaWxlIH0gZnJvbSBcIi4uL3lhbWxcIjtcblxuLyoqXG4gKiBPcHRpb25zIGZvciBgQ2lDb25maWd1cmF0aW9uYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDaUNvbmZpZ3VyYXRpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIERlZmF1bHQgc2V0dGluZ3MgZm9yIHRoZSBDSSBDb25maWd1cmF0aW9uLiBKb2JzIHRoYXQgZG8gbm90IGRlZmluZSBvbmUgb3IgbW9yZSBvZiB0aGUgbGlzdGVkIGtleXdvcmRzIHVzZSB0aGUgdmFsdWUgZGVmaW5lZCBpbiB0aGUgZGVmYXVsdCBzZWN0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdD86IERlZmF1bHQ7XG4gIC8qKlxuICAgKiBBIHNwZWNpYWwgam9iIHVzZWQgdG8gdXBsb2FkIHN0YXRpYyBzaXRlcyB0byBHaXRsYWIgcGFnZXMuIFJlcXVpcmVzIGEgYHB1YmxpYy9gIGRpcmVjdG9yeVxuICAgKiB3aXRoIGBhcnRpZmFjdHMucGF0aGAgcG9pbnRpbmcgdG8gaXQuXG4gICAqL1xuICByZWFkb25seSBwYWdlcz86IEpvYjtcbiAgLyoqXG4gICAqIFVzZWQgdG8gY29udHJvbCBwaXBlbGluZSBiZWhhdmlvci5cbiAgICovXG4gIHJlYWRvbmx5IHdvcmtmbG93PzogV29ya2Zsb3c7XG4gIC8qKlxuICAgKiBHcm91cHMgam9icyBpbnRvIHN0YWdlcy4gQWxsIGpvYnMgaW4gb25lIHN0YWdlIG11c3QgY29tcGxldGUgYmVmb3JlIG5leHQgc3RhZ2UgaXNcbiAgICogZXhlY3V0ZWQuIElmIG5vIHN0YWdlcyBhcmUgc3BlY2lmaWVkLiBEZWZhdWx0cyB0byBbJ2J1aWxkJywgJ3Rlc3QnLCAnZGVwbG95J10uXG4gICAqL1xuICByZWFkb25seSBzdGFnZXM/OiBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIEdsb2JhbCB2YXJpYWJsZXMgdGhhdCBhcmUgcGFzc2VkIHRvIGpvYnMuXG4gICAqIElmIHRoZSBqb2IgYWxyZWFkeSBoYXMgdGhhdCB2YXJpYWJsZSBkZWZpbmVkLCB0aGUgam9iLWxldmVsIHZhcmlhYmxlIHRha2VzIHByZWNlZGVuY2UuXG4gICAqL1xuICByZWFkb25seSB2YXJpYWJsZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAvKipcbiAgICogQW4gaW5pdGlhbCBzZXQgb2Ygam9icyB0byBhZGQgdG8gdGhlIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBqb2JzPzogUmVjb3JkPHN0cmluZywgSm9iPjtcbiAgLyoqXG4gICAqIFRoZSBwYXRoIG9mIHRoZSBmaWxlIHRvIGdlbmVyYXRlLlxuICAgKi9cbiAgcmVhZG9ubHkgcGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBDSSBmb3IgR2l0TGFiLlxuICogQSBDSSBpcyBhIGNvbmZpZ3VyYWJsZSBhdXRvbWF0ZWQgcHJvY2VzcyBtYWRlIHVwIG9mIG9uZSBvciBtb3JlIHN0YWdlcy9qb2JzLlxuICogQHNlZSBodHRwczovL2RvY3MuZ2l0bGFiLmNvbS9lZS9jaS95YW1sL1xuICovXG5leHBvcnQgY2xhc3MgQ2lDb25maWd1cmF0aW9uIGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIFBhdGggdG8gQ0kgZmlsZSBnZW5lcmF0ZWQgYnkgdGhlIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcGF0aDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHdvcmtmbG93IFlBTUwgZmlsZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBmaWxlOiBZYW1sRmlsZTtcbiAgLyoqXG4gICAqIERlZmluZXMgZGVmYXVsdCBzY3JpcHRzIHRoYXQgc2hvdWxkIHJ1biAqYWZ0ZXIqIGFsbCBqb2JzLiBDYW4gYmUgb3ZlcnJpZGVuIGJ5IHRoZSBqb2IgbGV2ZWwgYGFmdGVyU2NyaXB0YC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkZWZhdWx0QWZ0ZXJTY3JpcHQ6IHN0cmluZ1tdID0gW107XG4gIC8qKlxuICAgKiBEZWZhdWx0IGxpc3Qgb2YgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIHRoYXQgc2hvdWxkIGJlIGF0dGFjaGVkIHRvIHRoZSBqb2IgaWYgaXQgc3VjY2VlZHMuIEFydGlmYWN0cyBhcmUgc2VudCB0byBHaXRsYWIgd2hlcmUgdGhleSBjYW4gYmUgZG93bmxvYWRlZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkZWZhdWx0QXJ0aWZhY3RzPzogQXJ0aWZhY3RzO1xuICAvKipcbiAgICogRGVmaW5lcyBkZWZhdWx0IHNjcmlwdHMgdGhhdCBzaG91bGQgcnVuICpiZWZvcmUqIGFsbCBqb2JzLiBDYW4gYmUgb3ZlcnJpZGVuIGJ5IHRoZSBqb2IgbGV2ZWwgYGFmdGVyU2NyaXB0YC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkZWZhdWx0QmVmb3JlU2NyaXB0OiBzdHJpbmdbXSA9IFtdO1xuICAvKipcbiAgICogQSBkZWZhdWx0IGxpc3Qgb2YgY2FjaGUgZGVmaW5pdGlvbnMgKG3DoXguIDQpIHdpdGggdGhlIGZpbGVzIGFuZCBkaXJlY3RvcmllcyB0byBjYWNoZSBiZXR3ZWVuIGpvYnMuIFlvdSBjYW4gb25seSB1c2UgcGF0aHMgdGhhdCBhcmUgaW4gdGhlIGxvY2FsIHdvcmtpbmcgY29weS5cbiAgICovXG4gIHByaXZhdGUgX2RlZmF1bHRDYWNoZT86IENhY2hlW107XG5cbiAgcHVibGljIGdldCBkZWZhdWx0Q2FjaGUoKTogQ2FjaGVbXSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRDYWNoZTtcbiAgfVxuICAvKipcbiAgICogU3BlY2lmaWVzIHRoZSBkZWZhdWx0IGRvY2tlciBpbWFnZSB0byB1c2UgZ2xvYmFsbHkgZm9yIGFsbCBqb2JzLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRlZmF1bHRJbWFnZT86IEltYWdlO1xuICAvKipcbiAgICogVGhlIGRlZmF1bHQgYmVoYXZpb3IgZm9yIHdoZXRoZXIgYSBqb2Igc2hvdWxkIGJlIGNhbmNlbGVkIHdoZW4gYSBuZXdlciBwaXBlbGluZSBzdGFydHMgYmVmb3JlIHRoZSBqb2IgY29tcGxldGVzIChEZWZhdWx0OiBmYWxzZSkuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZGVmYXVsdEludGVycnVwdGlibGU/OiBib29sZWFuO1xuICAvKipcbiAgICogSG93IG1hbnkgdGltZXMgYSBqb2IgaXMgcmV0cmllZCBpZiBpdCBmYWlscy4gSWYgbm90IGRlZmluZWQsIGRlZmF1bHRzIHRvIDAgYW5kIGpvYnMgZG8gbm90IHJldHJ5LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRlZmF1bHRSZXRyeT86IFJldHJ5O1xuICAvKipcbiAgICogQSBkZWZhdWx0IGxpc3Qgb2YgYWRkaXRpb25hbCBEb2NrZXIgaW1hZ2VzIHRvIHJ1biBzY3JpcHRzIGluLiBUaGUgc2VydmljZSBpbWFnZSBpcyBsaW5rZWQgdG8gdGhlIGltYWdlIHNwZWNpZmllZCBpbiB0aGUgIGltYWdlIHBhcmFtZXRlci5cbiAgICovXG4gIHByaXZhdGUgZGVmYXVsdFNlcnZpY2VzOiBTZXJ2aWNlW10gPSBbXTtcbiAgLyoqXG4gICAqIFVzZWQgdG8gc2VsZWN0IGEgc3BlY2lmaWMgcnVubmVyIGZyb20gdGhlIGxpc3Qgb2YgYWxsIHJ1bm5lcnMgdGhhdCBhcmUgYXZhaWxhYmxlIGZvciB0aGUgcHJvamVjdC5cbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRUYWdzOiBzdHJpbmdbXSA9IFtdO1xuICAvKipcbiAgICogQSBkZWZhdWx0IHRpbWVvdXQgam9iIHdyaXR0ZW4gaW4gbmF0dXJhbCBsYW5ndWFnZSAoRXguIG9uZSBob3VyLCAzNjAwIHNlY29uZHMsIDYwIG1pbnV0ZXMpLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdFRpbWVvdXQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBEZWZhdWx0IElEIHRva2VucyAoSlNPTiBXZWIgVG9rZW5zKSB0aGF0IGFyZSB1c2VkIGZvciBDSS9DRCBhdXRoZW50aWNhdGlvbiB0byB1c2UgZ2xvYmFsbHkgZm9yIGFsbCBqb2JzLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdElkVG9rZW5zPzogUmVjb3JkPHN0cmluZywgSURUb2tlbj47XG4gIC8qKlxuICAgKiBTcGVjaWZ5IGEgbGlzdCBvZiBjb21tYW5kcyB0byBleGVjdXRlIG9uIHRoZSBydW5uZXIgYmVmb3JlIGNsb25pbmcgdGhlIEdpdCByZXBvc2l0b3J5IGFuZCBhbnkgc3VibW9kdWxlcyBodHRwczovL2RvY3MuZ2l0bGFiLmNvbS9jaS95YW1sLyNob29rc3ByZV9nZXRfc291cmNlc19zY3JpcHRcbiAgICovXG4gIHByaXZhdGUgZGVmYXVsdEhvb2tzPzogRGVmYXVsdFtcImhvb2tzXCJdO1xuICAvKipcbiAgICogQ2FuIGJlIGBJbmNsdWRlYCBvciBgSW5jbHVkZVtdYC4gRWFjaCBgSW5jbHVkZWAgd2lsbCBiZSBhIHN0cmluZywgb3IgYW5cbiAgICogb2JqZWN0IHdpdGggcHJvcGVydGllcyBmb3IgdGhlIG1ldGhvZCBpZiBpbmNsdWRpbmcgZXh0ZXJuYWwgWUFNTCBmaWxlLiBUaGUgZXh0ZXJuYWxcbiAgICogY29udGVudCB3aWxsIGJlIGZldGNoZWQsIGluY2x1ZGVkIGFuZCBldmFsdWF0ZWQgYWxvbmcgdGhlIGAuZ2l0bGFiLWNpLnltbGAuXG4gICAqL1xuICBwcml2YXRlIGluY2x1ZGU6IEluY2x1ZGVbXSA9IFtdO1xuICAvKipcbiAgICogQSBzcGVjaWFsIGpvYiB1c2VkIHRvIHVwbG9hZCBzdGF0aWMgc2l0ZXMgdG8gR2l0bGFiIHBhZ2VzLiBSZXF1aXJlcyBhIGBwdWJsaWMvYCBkaXJlY3RvcnlcbiAgICogd2l0aCBgYXJ0aWZhY3RzLnBhdGhgIHBvaW50aW5nIHRvIGl0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHBhZ2VzPzogSm9iO1xuICAvKipcbiAgICogR3JvdXBzIGpvYnMgaW50byBzdGFnZXMuIEFsbCBqb2JzIGluIG9uZSBzdGFnZSBtdXN0IGNvbXBsZXRlIGJlZm9yZSBuZXh0IHN0YWdlIGlzXG4gICAqIGV4ZWN1dGVkLiBEZWZhdWx0cyB0byBbJ2J1aWxkJywgJ3Rlc3QnLCAnZGVwbG95J10uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3RhZ2VzOiBzdHJpbmdbXSA9IFtdO1xuICAvKipcbiAgICogR2xvYmFsIHZhcmlhYmxlcyB0aGF0IGFyZSBwYXNzZWQgdG8gam9icy5cbiAgICogSWYgdGhlIGpvYiBhbHJlYWR5IGhhcyB0aGF0IHZhcmlhYmxlIGRlZmluZWQsIHRoZSBqb2ItbGV2ZWwgdmFyaWFibGUgdGFrZXMgcHJlY2VkZW5jZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB2YXJpYWJsZXM6IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IFZhcmlhYmxlQ29uZmlnIHwgc3RyaW5nPiA9XG4gICAge307XG4gIC8qKlxuICAgKiBVc2VkIHRvIGNvbnRyb2wgcGlwZWxpbmUgYmVoYXZpb3IuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgd29ya2Zsb3c/OiBXb3JrZmxvdztcbiAgLyoqXG4gICAqIFRoZSBqb2JzIGluIHRoZSBDSSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGpvYnM6IFJlY29yZDxzdHJpbmcsIEpvYj4gPSB7fTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm9qZWN0OiBQcm9qZWN0LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBvcHRpb25zPzogQ2lDb25maWd1cmF0aW9uT3B0aW9uc1xuICApIHtcbiAgICBzdXBlcihwcm9qZWN0KTtcbiAgICB0aGlzLm5hbWUgPSBwYXRoLnBhcnNlKG5hbWUpLm5hbWU7XG4gICAgY29uc3QgZGVyaXZlZFBhdGggPVxuICAgICAgdGhpcy5uYW1lID09PSBcImdpdGxhYi1jaVwiXG4gICAgICAgID8gXCIuZ2l0bGFiLWNpLnltbFwiXG4gICAgICAgIDogYC5naXRsYWIvY2ktdGVtcGxhdGVzLyR7bmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpfS55bWxgO1xuICAgIHRoaXMucGF0aCA9IG9wdGlvbnM/LnBhdGggPz8gZGVyaXZlZFBhdGg7XG4gICAgdGhpcy5maWxlID0gbmV3IFlhbWxGaWxlKHRoaXMucHJvamVjdCwgdGhpcy5wYXRoLCB7XG4gICAgICBvYmo6ICgpID0+IHRoaXMucmVuZGVyQ0koKSxcbiAgICAgIC8vIEdpdExhYiBuZWVkcyB0byByZWFkIHRoZSBmaWxlIGZyb20gdGhlIHJlcG9zaXRvcnkgaW4gb3JkZXIgdG8gd29yay5cbiAgICAgIGNvbW1pdHRlZDogdHJ1ZSxcbiAgICB9KTtcbiAgICBjb25zdCBkZWZhdWx0cyA9IG9wdGlvbnM/LmRlZmF1bHQ7XG4gICAgaWYgKGRlZmF1bHRzKSB7XG4gICAgICB0aGlzLmRlZmF1bHRBZnRlclNjcmlwdC5wdXNoKC4uLihkZWZhdWx0cy5hZnRlclNjcmlwdCA/PyBbXSkpO1xuICAgICAgdGhpcy5kZWZhdWx0QXJ0aWZhY3RzID0gZGVmYXVsdHMuYXJ0aWZhY3RzO1xuICAgICAgZGVmYXVsdHMuYmVmb3JlU2NyaXB0ICYmXG4gICAgICAgIHRoaXMuZGVmYXVsdEJlZm9yZVNjcmlwdC5wdXNoKC4uLmRlZmF1bHRzLmJlZm9yZVNjcmlwdCk7XG4gICAgICBkZWZhdWx0cy5jYWNoZSAmJiB0aGlzLmFkZERlZmF1bHRDYWNoZXMoZGVmYXVsdHMuY2FjaGUpO1xuICAgICAgdGhpcy5kZWZhdWx0SWRUb2tlbnMgPSBkZWZhdWx0cy5pZFRva2VucztcbiAgICAgIHRoaXMuZGVmYXVsdEltYWdlID0gZGVmYXVsdHMuaW1hZ2U7XG4gICAgICB0aGlzLmRlZmF1bHRJbnRlcnJ1cHRpYmxlID0gZGVmYXVsdHMuaW50ZXJydXB0aWJsZTtcbiAgICAgIHRoaXMuZGVmYXVsdFJldHJ5ID0gZGVmYXVsdHMucmV0cnk7XG4gICAgICBkZWZhdWx0cy5zZXJ2aWNlcyAmJiB0aGlzLmFkZFNlcnZpY2VzKC4uLmRlZmF1bHRzLnNlcnZpY2VzKTtcbiAgICAgIGRlZmF1bHRzLnRhZ3MgJiYgdGhpcy5kZWZhdWx0VGFncy5wdXNoKC4uLmRlZmF1bHRzLnRhZ3MpO1xuICAgICAgdGhpcy5kZWZhdWx0VGltZW91dCA9IGRlZmF1bHRzLnRpbWVvdXQ7XG4gICAgfVxuICAgIHRoaXMucGFnZXMgPSBvcHRpb25zPy5wYWdlcztcbiAgICB0aGlzLndvcmtmbG93ID0gb3B0aW9ucz8ud29ya2Zsb3c7XG4gICAgaWYgKG9wdGlvbnM/LnN0YWdlcykge1xuICAgICAgdGhpcy5hZGRTdGFnZXMoLi4ub3B0aW9ucy5zdGFnZXMpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucz8udmFyaWFibGVzKSB7XG4gICAgICB0aGlzLmFkZEdsb2JhbFZhcmlhYmxlcyhvcHRpb25zLnZhcmlhYmxlcyk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zPy5qb2JzKSB7XG4gICAgICB0aGlzLmFkZEpvYnMob3B0aW9ucy5qb2JzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkIGFkZGl0aW9uYWwgeW1sL3lhbWwgZmlsZXMgdG8gdGhlIENJIGluY2x1ZGVzXG4gICAqIEBwYXJhbSBpbmNsdWRlcyBUaGUgaW5jbHVkZXMgdG8gYWRkLlxuICAgKi9cbiAgcHVibGljIGFkZEluY2x1ZGVzKC4uLmluY2x1ZGVzOiBJbmNsdWRlW10pIHtcbiAgICBmb3IgKGNvbnN0IGFkZGl0aW9uYWwgb2YgaW5jbHVkZXMpIHtcbiAgICAgIHRoaXMuYXNzZXJ0SXNWYWxpZEluY2x1ZGUoYWRkaXRpb25hbCk7XG4gICAgICBmb3IgKGNvbnN0IGV4aXN0aW5nIG9mIHRoaXMuaW5jbHVkZSkge1xuICAgICAgICBpZiAodGhpcy5hcmVFcXVhbEluY2x1ZGVzKGV4aXN0aW5nLCBhZGRpdGlvbmFsKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGAke3RoaXMubmFtZX06IEdpdExhYiBDSSAke2V4aXN0aW5nfSBhbHJlYWR5IGNvbnRhaW5zIG9uZSBvciBtb3JlIHRlbXBsYXRlcyBzcGVjaWZpZWQgaW4gJHthZGRpdGlvbmFsfS5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5pbmNsdWRlLnB1c2goYWRkaXRpb25hbCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRocm93IGFuIGVycm9yIGlmIHRoZSBwcm92aWRlZCBJbmNsdWRlIGlzIGludmFsaWQuXG4gICAqIEBzZWUgaHR0cHM6Ly9naXRsYWIuY29tL2dpdGxhYi1vcmcvZ2l0bGFiLy0vYmxvYi9tYXN0ZXIvbGliL2dpdGxhYi9jaS9jb25maWcvZXh0ZXJuYWwvbWFwcGVyLnJiXG4gICAqIEBwYXJhbSBpbmNsdWRlIHRoZSBJbmNsdWRlIHRvIHZhbGlkYXRlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3NlcnRJc1ZhbGlkSW5jbHVkZShpbmNsdWRlOiBJbmNsdWRlKSB7XG4gICAgY29uc3QgY29tYm9zID0gW1xuICAgICAgaW5jbHVkZS5sb2NhbCxcbiAgICAgIGluY2x1ZGUuZmlsZSAmJiBpbmNsdWRlLnByb2plY3QsXG4gICAgICBpbmNsdWRlLnJlbW90ZSxcbiAgICAgIGluY2x1ZGUudGVtcGxhdGUsXG4gICAgXTtcbiAgICBjb25zdCBsZW4gPSBjb21ib3MuZmlsdGVyKCh4KSA9PiBCb29sZWFuKHgpKS5sZW5ndGg7XG4gICAgaWYgKGxlbiAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgJHt0aGlzLm5hbWV9OiBHaXRMYWIgQ0kgaW5jbHVkZSAke2luY2x1ZGV9IGNvbnRhaW5zICR7bGVufSBwcm9wZXJ0eSBjb21iaW5hdGlvbihzKS5cbiAgICAgICAgQSB2YWxpZCBpbmNsdWRlIGNvbmZpZ3VyYXRpb24gc3BlY2lmaWVzICpvbmUqIG9mIHRoZSBmb2xsb3dpbmcgcHJvcGVydHkgY29tYmluYXRpb25zLlxuICAgICAgICAqIGxvY2FsXG4gICAgICAgICogZmlsZSwgcHJvamVjdFxuICAgICAgICAqIHJlbW90ZVxuICAgICAgICAqIHRlbXBsYXRlXG4gICAgICAgIGBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRoZSBlcXVhbGl0eSBvZiBJbmNsdWRlcy5cbiAgICogQHNlZSBodHRwczovL2dpdGxhYi5jb20vZ2l0bGFiLW9yZy9naXRsYWIvLS9ibG9iL21hc3Rlci9saWIvZ2l0bGFiL2NpL2NvbmZpZy9leHRlcm5hbC9tYXBwZXIucmJcbiAgICogQHBhcmFtIHggRmlyc3QgaW5jbHVkZSB0byBjb21wYXJlLlxuICAgKiBAcGFyYW0geSBTZWNvbmQgaW5jbHVkZSB0byBjb21wYXJlLlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBpbmNsdWRlcyBhcmUgZXF1YWwuXG4gICAqL1xuICBwcml2YXRlIGFyZUVxdWFsSW5jbHVkZXMoeDogSW5jbHVkZSwgeTogSW5jbHVkZSk6IGJvb2xlYW4ge1xuICAgIGlmICh4LmxvY2FsID09PSB5LmxvY2FsICYmIHgubG9jYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmICh4LnRlbXBsYXRlID09PSB5LnRlbXBsYXRlICYmIHgudGVtcGxhdGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmICh4LnJlbW90ZSA9PT0geS5yZW1vdGUgJiYgeC5yZW1vdGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmICh4LnByb2plY3QgPT09IHkucHJvamVjdCAmJiB4LnJlZiA9PT0geS5yZWYpIHtcbiAgICAgIGNvbnN0IHhGaWxlcyA9IHguZmlsZSA/IHguZmlsZSA6IFtdO1xuICAgICAgY29uc3QgeUZpbGVzID0geS5maWxlID8geS5maWxlIDogW107XG4gICAgICBjb25zdCBhbGxGaWxlcyA9IHhGaWxlcy5jb25jYXQoeUZpbGVzKTtcbiAgICAgIHJldHVybiBuZXcgU2V0KGFsbEZpbGVzKS5zaXplICE9PSBhbGxGaWxlcy5sZW5ndGg7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYWRkaXRpb25hbCBzZXJ2aWNlcy5cbiAgICogQHBhcmFtIHNlcnZpY2VzIFRoZSBzZXJ2aWNlcyB0byBhZGQuXG4gICAqL1xuICBwdWJsaWMgYWRkU2VydmljZXMoLi4uc2VydmljZXM6IFNlcnZpY2VbXSkge1xuICAgIGZvciAoY29uc3QgYWRkaXRpb25hbCBvZiBzZXJ2aWNlcykge1xuICAgICAgZm9yIChjb25zdCBleGlzdGluZyBvZiB0aGlzLmRlZmF1bHRTZXJ2aWNlcykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgYWRkaXRpb25hbC5uYW1lID09PSBleGlzdGluZy5uYW1lICYmXG4gICAgICAgICAgYWRkaXRpb25hbC5hbGlhcyA9PT0gZXhpc3RpbmcuYWxpYXNcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYCR7dGhpcy5uYW1lfTogR2l0TGFiIENJIGFscmVhZHkgY29udGFpbnMgc2VydmljZSAke2FkZGl0aW9uYWx9LmBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmRlZmF1bHRTZXJ2aWNlcy5wdXNoKGFkZGl0aW9uYWwpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBnbG9iYWxseSBkZWZpbmVkIHZhcmlhYmxlIHRvIHRoZSBDSSBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0gdmFyaWFibGVzIFRoZSB2YXJpYWJsZXMgdG8gYWRkLlxuICAgKi9cbiAgcHVibGljIGFkZEdsb2JhbFZhcmlhYmxlcyh2YXJpYWJsZXM6IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh2YXJpYWJsZXMpKSB7XG4gICAgICBpZiAodGhpcy52YXJpYWJsZXNba2V5XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgJHt0aGlzLm5hbWV9OiBHaXRMYWIgQ0kgYWxyZWFkeSBjb250YWlucyB2YXJpYWJsZSAke2tleX0uYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdGhpcy52YXJpYWJsZXNba2V5XSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgc3RhZ2VzIHRvIHRoZSBDSSBjb25maWd1cmF0aW9uIGlmIG5vdCBhbHJlYWR5IHByZXNlbnQuXG4gICAqIEBwYXJhbSBzdGFnZXMgc3RhZ2VzIHRvIGFkZC5cbiAgICovXG4gIHB1YmxpYyBhZGRTdGFnZXMoLi4uc3RhZ2VzOiBzdHJpbmdbXSkge1xuICAgIGZvciAoY29uc3Qgc3RhZ2Ugb2Ygc3RhZ2VzKSB7XG4gICAgICBpZiAoIXRoaXMuc3RhZ2VzLmluY2x1ZGVzKHN0YWdlKSkge1xuICAgICAgICB0aGlzLnN0YWdlcy5wdXNoKHN0YWdlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkIGpvYnMgYW5kIHRoZWlyIHN0YWdlcyB0byB0aGUgQ0kgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIGpvYnMgSm9icyB0byBhZGQuXG4gICAqL1xuICBwdWJsaWMgYWRkSm9icyhqb2JzOiBSZWNvcmQ8c3RyaW5nLCBKb2I+KSB7XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoam9icykpIHtcbiAgICAgIGlmICh0aGlzLmpvYnNba2V5XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLm5hbWV9OiBHaXRMYWIgQ0kgYWxyZWFkeSBjb250YWlucyBqb2IgJHtrZXl9LmApO1xuICAgICAgfVxuICAgICAgdGhpcy5qb2JzW2tleV0gPSB2YWx1ZTtcbiAgICAgIGlmICh2YWx1ZS5zdGFnZSkge1xuICAgICAgICB0aGlzLmFkZFN0YWdlcyh2YWx1ZS5zdGFnZSk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUuY2FjaGUpIHtcbiAgICAgICAgdGhpcy5hc3NlcnRJc1ZhbGlkQ2FjaGVTZXR1cCh2YWx1ZS5jYWNoZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc1ZhbGlkQ2FjaGVTZXR1cChjYWNoZXM6IENhY2hlW10pOiBCb29sZWFuIHtcbiAgICBjb25zdCBNQVhfQ09ORklHVVJBQkxFX0NBQ0hFUyA9IDQ7XG4gICAgcmV0dXJuIGNhY2hlcy5sZW5ndGggPD0gTUFYX0NPTkZJR1VSQUJMRV9DQUNIRVM7XG4gIH1cblxuICBwcml2YXRlIGFzc2VydElzVmFsaWRDYWNoZVNldHVwKGNhY2hlczogQ2FjaGVbXSkge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkQ2FjaGVTZXR1cChjYWNoZXMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGAke3RoaXMubmFtZX06IEdpdExhYiBDSSBjYW4gb25seSBkZWZpbmUgdXAgdG8gNCBjYWNoZXMsIGdvdDogJHtjYWNoZXMubGVuZ3RofWBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgdXAgdG8gNCBkZWZhdWx0IGNhY2hlcyBjb25maWd1cmF0aW9uIHRvIHRoZSBDSSBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0gY2FjaGVzIENhY2hlcyB0byBhZGQuXG4gICAqL1xuICBwdWJsaWMgYWRkRGVmYXVsdENhY2hlcyhjYWNoZXM6IENhY2hlW10pIHtcbiAgICB0aGlzLmFzc2VydElzVmFsaWRDYWNoZVNldHVwKGNhY2hlcyk7XG4gICAgdGhpcy5fZGVmYXVsdENhY2hlID0gY2FjaGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwZWNpZnkgYSBsaXN0IG9mIGNvbW1hbmRzIHRvIGV4ZWN1dGUgb24gdGhlIHJ1bm5lciBiZWZvcmUgY2xvbmluZyB0aGUgR2l0IHJlcG9zaXRvcnkgYW5kIGFueSBzdWJtb2R1bGVzXG4gICAqIGh0dHBzOi8vZG9jcy5naXRsYWIuY29tL2NpL3lhbWwvI2hvb2tzcHJlX2dldF9zb3VyY2VzX3NjcmlwdFxuICAgKiBAcGFyYW0gaG9va3NcbiAgICovXG4gIHB1YmxpYyBhZGREZWZhdWx0SG9va3MoaG9va3M6IERlZmF1bHRIb29rcykge1xuICAgIHRoaXMuZGVmYXVsdEhvb2tzID0gaG9va3M7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlckNJKCkge1xuICAgIHJldHVybiB7XG4gICAgICBkZWZhdWx0OiB0aGlzLnJlbmRlckRlZmF1bHQoKSxcbiAgICAgIGluY2x1ZGU6XG4gICAgICAgIHRoaXMuaW5jbHVkZS5sZW5ndGggPiAwID8gc25ha2VDYXNlS2V5cyh0aGlzLmluY2x1ZGUpIDogdW5kZWZpbmVkLFxuICAgICAgcGFnZXM6IHNuYWtlQ2FzZUtleXModGhpcy5wYWdlcyksXG4gICAgICBzZXJ2aWNlczpcbiAgICAgICAgdGhpcy5kZWZhdWx0U2VydmljZXMubGVuZ3RoID4gMFxuICAgICAgICAgID8gc25ha2VDYXNlS2V5cyh0aGlzLmRlZmF1bHRTZXJ2aWNlcylcbiAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgIHZhcmlhYmxlczpcbiAgICAgICAgT2JqZWN0LmVudHJpZXModGhpcy52YXJpYWJsZXMpLmxlbmd0aCA+IDAgPyB0aGlzLnZhcmlhYmxlcyA6IHVuZGVmaW5lZCxcbiAgICAgIHdvcmtmbG93OiBzbmFrZUNhc2VLZXlzKHRoaXMud29ya2Zsb3cpLFxuICAgICAgc3RhZ2VzOiB0aGlzLnN0YWdlcy5sZW5ndGggPiAwID8gdGhpcy5zdGFnZXMgOiB1bmRlZmluZWQsXG4gICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBjaGFuZ2Ugam9iIG5hbWVzXG4gICAgICAvLyBhcyB0aGV5IGNhbiBiZSBoaWRkZW4gKGh0dHBzOi8vZG9jcy5naXRsYWIuY29tL2VlL2NpL2pvYnMvaW5kZXguaHRtbCNoaWRlLWpvYnMpXG4gICAgICAvLyBvciByZWZlcmVuY2VkIGluIGV4dGVuZHNcbiAgICAgIC4uLnNuYWtlQ2FzZUtleXModGhpcy5qb2JzLCB0cnVlKSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJEZWZhdWx0KCkge1xuICAgIGNvbnN0IGRlZmF1bHRzOiBEZWZhdWx0ID0ge1xuICAgICAgYWZ0ZXJTY3JpcHQ6XG4gICAgICAgIHRoaXMuZGVmYXVsdEFmdGVyU2NyaXB0Lmxlbmd0aCA+IDBcbiAgICAgICAgICA/IHRoaXMuZGVmYXVsdEFmdGVyU2NyaXB0XG4gICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICBhcnRpZmFjdHM6IHRoaXMuZGVmYXVsdEFydGlmYWN0cyxcbiAgICAgIGJlZm9yZVNjcmlwdDpcbiAgICAgICAgdGhpcy5kZWZhdWx0QmVmb3JlU2NyaXB0Lmxlbmd0aCA+IDBcbiAgICAgICAgICA/IHRoaXMuZGVmYXVsdEJlZm9yZVNjcmlwdFxuICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgY2FjaGU6IHRoaXMuZGVmYXVsdENhY2hlLFxuICAgICAgaWRUb2tlbnM6IHRoaXMuZGVmYXVsdElkVG9rZW5zLFxuICAgICAgaW1hZ2U6IHRoaXMuZGVmYXVsdEltYWdlLFxuICAgICAgaW50ZXJydXB0aWJsZTogdGhpcy5kZWZhdWx0SW50ZXJydXB0aWJsZSxcbiAgICAgIHJldHJ5OiB0aGlzLmRlZmF1bHRSZXRyeSxcbiAgICAgIHNlcnZpY2VzOlxuICAgICAgICB0aGlzLmRlZmF1bHRTZXJ2aWNlcy5sZW5ndGggPiAwID8gdGhpcy5kZWZhdWx0U2VydmljZXMgOiB1bmRlZmluZWQsXG4gICAgICB0YWdzOiB0aGlzLmRlZmF1bHRUYWdzLmxlbmd0aCA+IDAgPyB0aGlzLmRlZmF1bHRUYWdzIDogdW5kZWZpbmVkLFxuICAgICAgdGltZW91dDogdGhpcy5kZWZhdWx0VGltZW91dCxcbiAgICAgIGhvb2tzOiB0aGlzLmRlZmF1bHRIb29rcyxcbiAgICB9O1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKGRlZmF1bHRzKS5maWx0ZXIoKHgpID0+IHgpLmxlbmd0aFxuICAgICAgPyBzbmFrZUNhc2VLZXlzKGRlZmF1bHRzKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gc25ha2VDYXNlS2V5czxUID0gdW5rbm93bj4ob2JqOiBULCBza2lwVG9wTGV2ZWw6IGJvb2xlYW4gPSBmYWxzZSk6IFQge1xuICBpZiAodHlwZW9mIG9iaiAhPT0gXCJvYmplY3RcIiB8fCBvYmogPT0gbnVsbCkge1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuIG9iai5tYXAoKG8pID0+IHNuYWtlQ2FzZUtleXMobykpIGFzIGFueTtcbiAgfVxuXG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgZm9yIChsZXQgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKG9iaikpIHtcbiAgICBpZiAoXG4gICAgICB0eXBlb2YgdiA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgdiAhPSBudWxsICYmXG4gICAgICBrICE9PSBcInZhcmlhYmxlc1wiICYmXG4gICAgICBrICE9PSBcImlkVG9rZW5zXCIgJiZcbiAgICAgIGsgIT09IFwiaW5wdXRzXCJcbiAgICApIHtcbiAgICAgIHYgPSBzbmFrZUNhc2VLZXlzKHYpO1xuICAgIH1cbiAgICByZXN1bHRbc2tpcFRvcExldmVsID8gayA6IHNuYWtlKGspXSA9IHY7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdCBhcyBhbnk7XG59XG4iXX0=