UNPKG

projen

Version:

CDK for software projects

355 lines • 40.6 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.DependencyType = exports.Dependencies = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const path = __importStar(require("path")); const chalk_1 = require("chalk"); const semver = __importStar(require("semver")); const common_1 = require("./common"); const component_1 = require("./component"); const json_1 = require("./json"); /** * The `Dependencies` component is responsible to track the list of dependencies * a project has, and then used by project types as the model for rendering * project-specific dependency manifests such as the dependencies section * `package.json` files. * * To add a dependency you can use a project-type specific API such as * `nodeProject.addDeps()` or use the generic API of `project.deps`: */ class Dependencies extends component_1.Component { static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.Dependencies", version: "0.103.12" }; /** * The project-relative path of the deps manifest file. */ static MANIFEST_FILE = path.posix.join(common_1.PROJEN_DIR, "deps.json"); /** * Returns the coordinates of a dependency spec. * * Given `foo@^3.4.0` returns `{ name: "foo", version: "^3.4.0" }`. * Given `bar@npm:@bar/legacy` returns `{ name: "bar", version: "npm:@bar/legacy" }`. */ static parseDependency(spec) { const scope = spec.startsWith("@"); if (scope) { spec = spec.substring(1); } const [module, ...version] = spec.split("@"); const name = scope ? `@${module}` : module; if (version.length == 0) { return { name }; } else { return { name, version: version?.join("@") }; } } _deps = new Array(); /** * Adds a dependencies component to the project. * @param project The parent project */ constructor(project) { super(project); // this is not really required at the moment, but actually quite useful as a // checked-in source of truth for dependencies and will potentially be // valuable in the future for CLI tools. if (!project.ejected) { new json_1.JsonFile(project, Dependencies.MANIFEST_FILE, { omitEmpty: true, obj: () => this.toJson(), }); } } /** * A copy of all dependencies recorded for this project. * * The list is sorted by type->name->version */ get all() { return [...this._deps].sort(compareDeps).map(normalizeDep); } /** * Returns a dependency by name. * * Fails if there is no dependency defined by that name or if `type` is not * provided and there is more then one dependency type for this dependency. * * @param name The name of the dependency * @param type The dependency type. If this dependency is defined only for a * single type, this argument can be omitted. * * @returns a copy (cannot be modified) */ getDependency(name, type) { const dep = this.tryGetDependency(name, type); if (!dep) { const msg = type ? `there is no ${type} dependency defined on "${name}"` : `there is no dependency defined on "${name}"`; throw new Error(msg); } return dep; } /** * Returns a dependency by name. * * Returns `undefined` if there is no dependency defined by that name or if * `type` is not provided and there is more then one dependency type for this * dependency. * * @param name The name of the dependency * @param type The dependency type. If this dependency is defined only for a * single type, this argument can be omitted. * * @returns a copy (cannot be modified) or undefined if there is no match */ tryGetDependency(name, type) { const idx = this.tryGetDependencyIndex(name, type); if (idx === -1) { return undefined; } return { ...normalizeDep(this._deps[idx]), }; } /** * Adds a dependency to this project. * @param spec The dependency spec in the format `MODULE[@VERSION]` where * `MODULE` is the package-manager-specific module name and `VERSION` is an * optional semantic version requirement (e.g. `^3.4.0`). * @param type The type of the dependency. */ addDependency(spec, type, metadata = {}) { this.project.logger.verbose(`${(0, chalk_1.underline)("Dependency")} | Adding ${type}-dep \`${spec}\``); const dep = { ...Dependencies.parseDependency(spec), type, metadata, }; const existingDepIndex = this.tryGetDependencyIndex(dep.name, type); if (existingDepIndex !== -1) { this.project.logger.debug(`${(0, chalk_1.underline)("Dependency")} | Updating existing ${dep.type}-dep \`${dep.name}\` with more specific request.`); this._deps[existingDepIndex] = dep; } else { this._deps.push(dep); } return dep; } /** * Removes a dependency. * @param name The name of the module to remove (without the version) * @param type The dependency type. This is only required if there the * dependency is defined for multiple types. */ removeDependency(name, type) { const removeIndex = this.tryGetDependencyIndex(name, type); if (removeIndex === -1) { return; } this._deps.splice(removeIndex, 1); } /** * Checks if an existing dependency satisfies a dependency requirement. * @param name The name of the dependency to check (without the version). * @param type The dependency type. * @param expectedRange The version constraint to check (e.g. `^3.4.0`). * The constraint of the dependency must be a subset of the expected range to satisfy the requirements. * @returns `true` if the dependency exists and its version satisfies the provided constraint. `false` otherwise. * Notably returns `false` if a dependency exists, but has no version. */ isDependencySatisfied(name, type, expectedRange) { const dep = this.tryGetDependency(name, type); return dep?.version != null && semver.subset(dep.version, expectedRange); } /** * Request a dependency. Unlike `addDependency`, this merges intelligently * with existing dependencies of the same name and type: * * - If the dep exists with a version that already satisfies the request, * the version is not changed. * - If the dep doesn't exist, it is added with the requested type/version. * - If the dep exists but the versions don't intersect, an error is thrown. * - If no type is provided, an existing dependency of any type will satisfy * the request. If none exists, it is added as BUILD. * * @param request The dependency request. * @returns The resulting dependency after merging. */ requestDependency(request) { // When type is not specified, find any existing dep with this name const requestedType = request.type ?? this.findExistingInstallableType(request.name) ?? DependencyType.BUILD; const existing = this.tryGetDependency(request.name, requestedType); if (!existing) { const spec = request.version ? `${request.name}@${request.version}` : request.name; return this.addDependency(spec, requestedType, request.metadata ?? {}); } // Version merging let effectiveVersion; if (!request.version) { effectiveVersion = existing.version; } else if (this.isDependencySatisfied(request.name, requestedType, request.version)) { effectiveVersion = existing.version; } else if (!existing.version) { effectiveVersion = request.version; } else if (semver.intersects(existing.version, request.version)) { effectiveVersion = request.version; } else { throw new Error(`Dependency "${request.name}" version conflict: existing "${existing.version}" ` + `does not intersect with requested "${request.version}"`); } const spec = effectiveVersion ? `${request.name}@${effectiveVersion}` : request.name; return this.addDependency(spec, requestedType, { ...existing.metadata, ...request.metadata, }); } /** * Finds the type of an existing installable dependency by name. * Excludes PEER, OVERRIDE, and OPTIONAL types. * Returns undefined if no dependency with this name exists. */ findExistingInstallableType(name) { return this._deps.find((d) => d.name === name && d.type !== DependencyType.PEER && d.type !== DependencyType.OVERRIDE && d.type !== DependencyType.OPTIONAL)?.type; } tryGetDependencyIndex(name, type) { const deps = this._deps.filter((d) => d.name === name); if (deps.length === 0) { return -1; // not found } if (!type) { if (deps.length > 1) { throw new Error(`"${name}" is defined for multiple dependency types: ${deps .map((d) => d.type) .join(",")}. Please specify dependency type`); } type = deps[0].type; } return this._deps.findIndex((dep) => dep.name === name && dep.type === type); } toJson() { if (this._deps.length === 0) { return undefined; } return { dependencies: this._deps.sort(compareDeps).map(normalizeDep), }; } } exports.Dependencies = Dependencies; function normalizeDep(d) { const obj = {}; for (const [k, v] of Object.entries(d)) { if (v == undefined) { continue; } if (typeof v === "object" && Object.keys(v).length === 0) { continue; } if (Array.isArray(v) && v.length === 0) { continue; } obj[k] = v; } return obj; } function compareDeps(d1, d2) { return specOf(d1).localeCompare(specOf(d2)); function specOf(dep) { let spec = dep.type + ":" + dep.name; if (dep.version) { spec += "@" + dep.version; } return spec; } } /** * Type of dependency. */ var DependencyType; (function (DependencyType) { /** * The dependency is required for the program/library during runtime. */ DependencyType["RUNTIME"] = "runtime"; /** * The dependency is required at runtime but expected to be installed by the * consumer. */ DependencyType["PEER"] = "peer"; /** * The dependency is bundled and shipped with the module, so consumers are not * required to install it. */ DependencyType["BUNDLED"] = "bundled"; /** * The dependency is required to run the `build` task. */ DependencyType["BUILD"] = "build"; /** * The dependency is required to run the `test` task. */ DependencyType["TEST"] = "test"; /** * The dependency is required for development (e.g. IDE plugins). */ DependencyType["DEVENV"] = "devenv"; /** * Transient dependency that needs to be overwritten. * * Available for Node packages */ DependencyType["OVERRIDE"] = "override"; /** * An optional dependency that may be used at runtime if available, but is not required. * It is expected to be installed by the consumer. */ DependencyType["OPTIONAL"] = "optional"; })(DependencyType || (exports.DependencyType = DependencyType = {})); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwZW5kZW5jaWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2RlcGVuZGVuY2llcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsMkNBQTZCO0FBQzdCLGlDQUFrQztBQUNsQywrQ0FBaUM7QUFDakMscUNBQXNDO0FBQ3RDLDJDQUF3QztBQUN4QyxpQ0FBa0M7QUFHbEM7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFhLFlBQWEsU0FBUSxxQkFBUzs7SUFDekM7O09BRUc7SUFDSSxNQUFNLENBQVUsYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUNwRCxtQkFBVSxFQUNWLFdBQVcsQ0FDWixDQUFDO0lBRUY7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsZUFBZSxDQUFDLElBQVk7UUFDeEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuQyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0IsQ0FBQztRQUVELE1BQU0sQ0FBQyxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQzNDLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN4QixPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDbEIsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDL0MsQ0FBQztJ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QyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFNUMsU0FBUyxNQUFNLENBQUMsR0FBZTtRQUM3QixJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQ3JDLElBQUksR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2hCLElBQUksSUFBSSxHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQztRQUM1QixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQThDRDs7R0FFRztBQUNILElBQVksY0E2Q1g7QUE3Q0QsV0FBWSxjQUFjO0lBQ3hCOztPQUVHO0lBQ0gscUNBQW1CLENBQUE7SUFFbkI7OztPQUdHO0lBQ0gsK0JBQWEsQ0FBQTtJQUViOzs7T0FHRztJQUNILHFDQUFtQixDQUFBO0lBRW5COztPQUVHO0lBQ0gsaUNBQWUsQ0FBQTtJQUVmOztPQUVHO0lBQ0gsK0JBQWEsQ0FBQTtJQUViOztPQUVHO0lBQ0gsbUNBQWlCLENBQUE7SUFFakI7Ozs7T0FJRztJQUNILHVDQUFxQixDQUFBO0lBRXJCOzs7T0FHRztJQUNILHVDQUFxQixDQUFBO0FBQ3ZCLENBQUMsRUE3Q1csY0FBYyw4QkFBZCxjQUFjLFFBNkN6QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IHVuZGVybGluZSB9IGZyb20gXCJjaGFsa1wiO1xuaW1wb3J0ICogYXMgc2VtdmVyIGZyb20gXCJzZW12ZXJcIjtcbmltcG9ydCB7IFBST0pFTl9ESVIgfSBmcm9tIFwiLi9jb21tb25cIjtcbmltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gXCIuL2NvbXBvbmVudFwiO1xuaW1wb3J0IHsgSnNvbkZpbGUgfSBmcm9tIFwiLi9qc29uXCI7XG5pbXBvcnQgdHlwZSB7IFByb2plY3QgfSBmcm9tIFwiLi9wcm9qZWN0XCI7XG5cbi8qKlxuICogVGhlIGBEZXBlbmRlbmNpZXNgIGNvbXBvbmVudCBpcyByZXNwb25zaWJsZSB0byB0cmFjayB0aGUgbGlzdCBvZiBkZXBlbmRlbmNpZXNcbiAqIGEgcHJvamVjdCBoYXMsIGFuZCB0aGVuIHVzZWQgYnkgcHJvamVjdCB0eXBlcyBhcyB0aGUgbW9kZWwgZm9yIHJlbmRlcmluZ1xuICogcHJvamVjdC1zcGVjaWZpYyBkZXBlbmRlbmN5IG1hbmlmZXN0cyBzdWNoIGFzIHRoZSBkZXBlbmRlbmNpZXMgc2VjdGlvblxuICogYHBhY2thZ2UuanNvbmAgZmlsZXMuXG4gKlxuICogVG8gYWRkIGEgZGVwZW5kZW5jeSB5b3UgY2FuIHVzZSBhIHByb2plY3QtdHlwZSBzcGVjaWZpYyBBUEkgc3VjaCBhc1xuICogYG5vZGVQcm9qZWN0LmFkZERlcHMoKWAgb3IgdXNlIHRoZSBnZW5lcmljIEFQSSBvZiBgcHJvamVjdC5kZXBzYDpcbiAqL1xuZXhwb3J0IGNsYXNzIERlcGVuZGVuY2llcyBleHRlbmRzIENvbXBvbmVudCB7XG4gIC8qKlxuICAgKiBUaGUgcHJvamVjdC1yZWxhdGl2ZSBwYXRoIG9mIHRoZSBkZXBzIG1hbmlmZXN0IGZpbGUuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IE1BTklGRVNUX0ZJTEUgPSBwYXRoLnBvc2l4LmpvaW4oXG4gICAgUFJPSkVOX0RJUixcbiAgICBcImRlcHMuanNvblwiLFxuICApO1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb29yZGluYXRlcyBvZiBhIGRlcGVuZGVuY3kgc3BlYy5cbiAgICpcbiAgICogR2l2ZW4gYGZvb0BeMy40LjBgIHJldHVybnMgYHsgbmFtZTogXCJmb29cIiwgdmVyc2lvbjogXCJeMy40LjBcIiB9YC5cbiAgICogR2l2ZW4gYGJhckBucG06QGJhci9sZWdhY3lgIHJldHVybnMgYHsgbmFtZTogXCJiYXJcIiwgdmVyc2lvbjogXCJucG06QGJhci9sZWdhY3lcIiB9YC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcGFyc2VEZXBlbmRlbmN5KHNwZWM6IHN0cmluZyk6IERlcGVuZGVuY3lDb29yZGluYXRlcyB7XG4gICAgY29uc3Qgc2NvcGUgPSBzcGVjLnN0YXJ0c1dpdGgoXCJAXCIpO1xuICAgIGlmIChzY29wZSkge1xuICAgICAgc3BlYyA9IHNwZWMuc3Vic3RyaW5nKDEpO1xuICAgIH1cblxuICAgIGNvbnN0IFttb2R1bGUsIC4uLnZlcnNpb25dID0gc3BlYy5zcGxpdChcIkBcIik7XG4gICAgY29uc3QgbmFtZSA9IHNjb3BlID8gYEAke21vZHVsZX1gIDogbW9kdWxlO1xuICAgIGlmICh2ZXJzaW9uLmxlbmd0aCA9PSAwKSB7XG4gICAgICByZXR1cm4geyBuYW1lIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IG5hbWUsIHZlcnNpb246IHZlcnNpb24/LmpvaW4oXCJAXCIpIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGVwcyA9IG5ldyBBcnJheTxEZXBlbmRlbmN5PigpO1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgZGVwZW5kZW5jaWVzIGNvbXBvbmVudCB0byB0aGUgcHJvamVjdC5cbiAgICogQHBhcmFtIHByb2plY3QgVGhlIHBhcmVudCBwcm9qZWN0XG4gICAqL1xuICBjb25zdHJ1Y3Rvcihwcm9qZWN0OiBQcm9qZWN0KSB7XG4gICAgc3VwZXIocHJvamVjdCk7XG5cbiAgICAvLyB0aGlzIGlzIG5vdCByZWFsbHkgcmVxdWlyZWQgYXQgdGhlIG1vbWVudCwgYnV0IGFjdHVhbGx5IHF1aXRlIHVzZWZ1bCBhcyBhXG4gICAgLy8gY2hlY2tlZC1pbiBzb3VyY2Ugb2YgdHJ1dGggZm9yIGRlcGVuZGVuY2llcyBhbmQgd2lsbCBwb3RlbnRpYWxseSBiZVxuICAgIC8vIHZhbHVhYmxlIGluIHRoZSBmdXR1cmUgZm9yIENMSSB0b29scy5cbiAgICBpZiAoIXByb2plY3QuZWplY3RlZCkge1xuICAgICAgbmV3IEpzb25GaWxlKHByb2plY3QsIERlcGVuZGVuY2llcy5NQU5JRkVTVF9GSUxFLCB7XG4gICAgICAgIG9taXRFbXB0eTogdHJ1ZSxcbiAgICAgICAgb2JqOiAoKSA9PiB0aGlzLnRvSnNvbigpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEEgY29weSBvZiBhbGwgZGVwZW5kZW5jaWVzIHJlY29yZGVkIGZvciB0aGlzIHByb2plY3QuXG4gICAqXG4gICAqIFRoZSBsaXN0IGlzIHNvcnRlZCBieSB0eXBlLT5uYW1lLT52ZXJzaW9uXG4gICAqL1xuICBwdWJsaWMgZ2V0IGFsbCgpOiBEZXBlbmRlbmN5W10ge1xuICAgIHJldHVybiBbLi4udGhpcy5fZGVwc10uc29ydChjb21wYXJlRGVwcykubWFwKG5vcm1hbGl6ZURlcCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGRlcGVuZGVuY3kgYnkgbmFtZS5cbiAgICpcbiAgICogRmFpbHMgaWYgdGhlcmUgaXMgbm8gZGVwZW5kZW5jeSBkZWZpbmVkIGJ5IHRoYXQgbmFtZSBvciBpZiBgdHlwZWAgaXMgbm90XG4gICAqIHByb3ZpZGVkIGFuZCB0aGVyZSBpcyBtb3JlIHRoZW4gb25lIGRlcGVuZGVuY3kgdHlwZSBmb3IgdGhpcyBkZXBlbmRlbmN5LlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVwZW5kZW5jeVxuICAgKiBAcGFyYW0gdHlwZSBUaGUgZGVwZW5kZW5jeSB0eXBlLiBJZiB0aGlzIGRlcGVuZGVuY3kgaXMgZGVmaW5lZCBvbmx5IGZvciBhXG4gICAqIHNpbmdsZSB0eXBlLCB0aGlzIGFyZ3VtZW50IGNhbiBiZSBvbWl0dGVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIGNvcHkgKGNhbm5vdCBiZSBtb2RpZmllZClcbiAgICovXG4gIHB1YmxpYyBnZXREZXBlbmRlbmN5KG5hbWU6IHN0cmluZywgdHlwZT86IERlcGVuZGVuY3lUeXBlKTogRGVwZW5kZW5jeSB7XG4gICAgY29uc3QgZGVwID0gdGhpcy50cnlHZXREZXBlbmRlbmN5KG5hbWUsIHR5cGUpO1xuICAgIGlmICghZGVwKSB7XG4gICAgICBjb25zdCBtc2cgPSB0eXBlXG4gICAgICAgID8gYHRoZXJlIGlzIG5vICR7dHlwZX0gZGVwZW5kZW5jeSBkZWZpbmVkIG9uIFwiJHtuYW1lfVwiYFxuICAgICAgICA6IGB0aGVyZSBpcyBubyBkZXBlbmRlbmN5IGRlZmluZWQgb24gXCIke25hbWV9XCJgO1xuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVwO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBkZXBlbmRlbmN5IGJ5IG5hbWUuXG4gICAqXG4gICAqIFJldHVybnMgYHVuZGVmaW5lZGAgaWYgdGhlcmUgaXMgbm8gZGVwZW5kZW5jeSBkZWZpbmVkIGJ5IHRoYXQgbmFtZSBvciBpZlxuICAgKiBgdHlwZWAgaXMgbm90IHByb3ZpZGVkIGFuZCB0aGVyZSBpcyBtb3JlIHRoZW4gb25lIGRlcGVuZGVuY3kgdHlwZSBmb3IgdGhpc1xuICAgKiBkZXBlbmRlbmN5LlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVwZW5kZW5jeVxuICAgKiBAcGFyYW0gdHlwZSBUaGUgZGVwZW5kZW5jeSB0eXBlLiBJZiB0aGlzIGRlcGVuZGVuY3kgaXMgZGVmaW5lZCBvbmx5IGZvciBhXG4gICAqIHNpbmdsZSB0eXBlLCB0aGlzIGFyZ3VtZW50IGNhbiBiZSBvbWl0dGVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIGNvcHkgKGNhbm5vdCBiZSBtb2RpZmllZCkgb3IgdW5kZWZpbmVkIGlmIHRoZXJlIGlzIG5vIG1hdGNoXG4gICAqL1xuICBwdWJsaWMgdHJ5R2V0RGVwZW5kZW5jeShcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgdHlwZT86IERlcGVuZGVuY3lUeXBlLFxuICApOiBEZXBlbmRlbmN5IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBpZHggPSB0aGlzLnRyeUdldERlcGVuZGVuY3lJbmRleChuYW1lLCB0eXBlKTtcbiAgICBpZiAoaWR4ID09PSAtMSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ubm9ybWFsaXplRGVwKHRoaXMuX2RlcHNbaWR4XSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgZGVwZW5kZW5jeSB0byB0aGlzIHByb2plY3QuXG4gICAqIEBwYXJhbSBzcGVjIFRoZSBkZXBlbmRlbmN5IHNwZWMgaW4gdGhlIGZvcm1hdCBgTU9EVUxFW0BWRVJTSU9OXWAgd2hlcmVcbiAgICogYE1PRFVMRWAgaXMgdGhlIHBhY2thZ2UtbWFuYWdlci1zcGVjaWZpYyBtb2R1bGUgbmFtZSBhbmQgYFZFUlNJT05gIGlzIGFuXG4gICAqIG9wdGlvbmFsIHNlbWFudGljIHZlcnNpb24gcmVxdWlyZW1lbnQgKGUuZy4gYF4zLjQuMGApLlxuICAgKiBAcGFyYW0gdHlwZSBUaGUgdHlwZSBvZiB0aGUgZGVwZW5kZW5jeS5cbiAgICovXG4gIHB1YmxpYyBhZGREZXBlbmRlbmN5KFxuICAgIHNwZWM6IHN0cmluZyxcbiAgICB0eXBlOiBEZXBlbmRlbmN5VHlwZSxcbiAgICBtZXRhZGF0YTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9LFxuICApOiBEZXBlbmRlbmN5IHtcbiAgICB0aGlzLnByb2plY3QubG9nZ2VyLnZlcmJvc2UoXG4gICAgICBgJHt1bmRlcmxpbmUoXCJEZXBlbmRlbmN5XCIpfSB8IEFkZGluZyAke3R5cGV9LWRlcCBcXGAke3NwZWN9XFxgYCxcbiAgICApO1xuXG4gICAgY29uc3QgZGVwOiBEZXBlbmRlbmN5ID0ge1xuICAgICAgLi4uRGVwZW5kZW5jaWVzLnBhcnNlRGVwZW5kZW5jeShzcGVjKSxcbiAgICAgIHR5cGUsXG4gICAgICBtZXRhZGF0YSxcbiAgICB9O1xuXG4gICAgY29uc3QgZXhpc3RpbmdEZXBJbmRleCA9IHRoaXMudHJ5R2V0RGVwZW5kZW5jeUluZGV4KGRlcC5uYW1lLCB0eXBlKTtcblxuICAgIGlmIChleGlzdGluZ0RlcEluZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5wcm9qZWN0LmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYCR7dW5kZXJsaW5lKFwiRGVwZW5kZW5jeVwiKX0gfCBVcGRhdGluZyBleGlzdGluZyAke2RlcC50eXBlfS1kZXAgXFxgJHtkZXAubmFtZX1cXGAgd2l0aCBtb3JlIHNwZWNpZmljIHJlcXVlc3QuYCxcbiAgICAgICk7XG4gICAgICB0aGlzLl9kZXBzW2V4aXN0aW5nRGVwSW5kZXhdID0gZGVwO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9kZXBzLnB1c2goZGVwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVwO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSBkZXBlbmRlbmN5LlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgbW9kdWxlIHRvIHJlbW92ZSAod2l0aG91dCB0aGUgdmVyc2lvbilcbiAgICogQHBhcmFtIHR5cGUgVGhlIGRlcGVuZGVuY3kgdHlwZS4gVGhpcyBpcyBvbmx5IHJlcXVpcmVkIGlmIHRoZXJlIHRoZVxuICAgKiBkZXBlbmRlbmN5IGlzIGRlZmluZWQgZm9yIG11bHRpcGxlIHR5cGVzLlxuICAgKi9cbiAgcHVibGljIHJlbW92ZURlcGVuZGVuY3kobmFtZTogc3RyaW5nLCB0eXBlPzogRGVwZW5kZW5jeVR5cGUpIHtcbiAgICBjb25zdCByZW1vdmVJbmRleCA9IHRoaXMudHJ5R2V0RGVwZW5kZW5jeUluZGV4KG5hbWUsIHR5cGUpO1xuICAgIGlmIChyZW1vdmVJbmRleCA9PT0gLTEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9kZXBzLnNwbGljZShyZW1vdmVJbmRleCwgMSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGFuIGV4aXN0aW5nIGRlcGVuZGVuY3kgc2F0aXNmaWVzIGEgZGVwZW5kZW5jeSByZXF1aXJlbWVudC5cbiAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGRlcGVuZGVuY3kgdG8gY2hlY2sgKHdpdGhvdXQgdGhlIHZlcnNpb24pLlxuICAgKiBAcGFyYW0gdHlwZSBUaGUgZGVwZW5kZW5jeSB0eXBlLlxuICAgKiBAcGFyYW0gZXhwZWN0ZWRSYW5nZSBUaGUgdmVyc2lvbiBjb25zdHJhaW50IHRvIGNoZWNrIChlLmcuIGBeMy40LjBgKS5cbiAgICogVGhlIGNvbnN0cmFpbnQgb2YgdGhlIGRlcGVuZGVuY3kgbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUgZXhwZWN0ZWQgcmFuZ2UgdG8gc2F0aXNmeSB0aGUgcmVxdWlyZW1lbnRzLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGRlcGVuZGVuY3kgZXhpc3RzIGFuZCBpdHMgdmVyc2lvbiBzYXRpc2ZpZXMgdGhlIHByb3ZpZGVkIGNvbnN0cmFpbnQuIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKiBOb3RhYmx5IHJldHVybnMgYGZhbHNlYCBpZiBhIGRlcGVuZGVuY3kgZXhpc3RzLCBidXQgaGFzIG5vIHZlcnNpb24uXG4gICAqL1xuICBwdWJsaWMgaXNEZXBlbmRlbmN5U2F0aXNmaWVkKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB0eXBlOiBEZXBlbmRlbmN5VHlwZSxcbiAgICBleHBlY3RlZFJhbmdlOiBzdHJpbmcsXG4gICk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGRlcCA9IHRoaXMudHJ5R2V0RGVwZW5kZW5jeShuYW1lLCB0eXBlKTtcbiAgICByZXR1cm4gZGVwPy52ZXJzaW9uICE9IG51bGwgJiYgc2VtdmVyLnN1YnNldChkZXAudmVyc2lvbiwgZXhwZWN0ZWRSYW5nZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVxdWVzdCBhIGRlcGVuZGVuY3kuIFVubGlrZSBgYWRkRGVwZW5kZW5jeWAsIHRoaXMgbWVyZ2VzIGludGVsbGlnZW50bHlcbiAgICogd2l0aCBleGlzdGluZyBkZXBlbmRlbmNpZXMgb2YgdGhlIHNhbWUgbmFtZSBhbmQgdHlwZTpcbiAgICpcbiAgICogLSBJZiB0aGUgZGVwIGV4aXN0cyB3aXRoIGEgdmVyc2lvbiB0aGF0IGFscmVhZHkgc2F0aXNmaWVzIHRoZSByZXF1ZXN0LFxuICAgKiAgIHRoZSB2ZXJzaW9uIGlzIG5vdCBjaGFuZ2VkLlxuICAgKiAtIElmIHRoZSBkZXAgZG9lc24ndCBleGlzdCwgaXQgaXMgYWRkZWQgd2l0aCB0aGUgcmVxdWVzdGVkIHR5cGUvdmVyc2lvbi5cbiAgICogLSBJZiB0aGUgZGVwIGV4aXN0cyBidXQgdGhlIHZlcnNpb25zIGRvbid0IGludGVyc2VjdCwgYW4gZXJyb3IgaXMgdGhyb3duLlxuICAgKiAtIElmIG5vIHR5cGUgaXMgcHJvdmlkZWQsIGFuIGV4aXN0aW5nIGRlcGVuZGVuY3kgb2YgYW55IHR5cGUgd2lsbCBzYXRpc2Z5XG4gICAqICAgdGhlIHJlcXVlc3QuIElmIG5vbmUgZXhpc3RzLCBpdCBpcyBhZGRlZCBhcyBCVUlMRC5cbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3QgVGhlIGRlcGVuZGVuY3kgcmVxdWVzdC5cbiAgICogQHJldHVybnMgVGhlIHJlc3VsdGluZyBkZXBlbmRlbmN5IGFmdGVyIG1lcmdpbmcuXG4gICAqL1xuICBwdWJsaWMgcmVxdWVzdERlcGVuZGVuY3kocmVxdWVzdDogRGVwZW5kZW5jeVJlcXVlc3QpOiBEZXBlbmRlbmN5IHtcbiAgICAvLyBXaGVuIHR5cGUgaXMgbm90IHNwZWNpZmllZCwgZmluZCBhbnkgZXhpc3RpbmcgZGVwIHdpdGggdGhpcyBuYW1lXG4gICAgY29uc3QgcmVxdWVzdGVkVHlwZSA9XG4gICAgICByZXF1ZXN0LnR5cGUgPz9cbiAgICAgIHRoaXMuZmluZEV4aXN0aW5nSW5zdGFsbGFibGVUeXBlKHJlcXVlc3QubmFtZSkgPz9cbiAgICAgIERlcGVuZGVuY3lUeXBlLkJVSUxEO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy50cnlHZXREZXBlbmRlbmN5KHJlcXVlc3QubmFtZSwgcmVxdWVzdGVkVHlwZSk7XG5cbiAgICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgICBjb25zdCBzcGVjID0gcmVxdWVzdC52ZXJzaW9uXG4gICAgICAgID8gYCR7cmVxdWVzdC5uYW1lfUAke3JlcXVlc3QudmVyc2lvbn1gXG4gICAgICAgIDogcmVxdWVzdC5uYW1lO1xuICAgICAgcmV0dXJuIHRoaXMuYWRkRGVwZW5kZW5jeShzcGVjLCByZXF1ZXN0ZWRUeXBlLCByZXF1ZXN0Lm1ldGFkYXRhID8/IHt9KTtcbiAgICB9XG5cbiAgICAvLyBWZXJzaW9uIG1lcmdpbmdcbiAgICBsZXQgZWZmZWN0aXZlVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKCFyZXF1ZXN0LnZlcnNpb24pIHtcbiAgICAgIGVmZmVjdGl2ZVZlcnNpb24gPSBleGlzdGluZy52ZXJzaW9uO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0aGlzLmlzRGVwZW5kZW5jeVNhdGlzZmllZChyZXF1ZXN0Lm5hbWUsIHJlcXVlc3RlZFR5cGUsIHJlcXVlc3QudmVyc2lvbilcbiAgICApIHtcbiAgICAgIGVmZmVjdGl2ZVZlcnNpb24gPSBleGlzdGluZy52ZXJzaW9uO1xuICAgIH0gZWxzZSBpZiAoIWV4aXN0aW5nLnZlcnNpb24pIHtcbiAgICAgIGVmZmVjdGl2ZVZlcnNpb24gPSByZXF1ZXN0LnZlcnNpb247XG4gICAgfSBlbHNlIGlmIChzZW12ZXIuaW50ZXJzZWN0cyhleGlzdGluZy52ZXJzaW9uLCByZXF1ZXN0LnZlcnNpb24pKSB7XG4gICAgICBlZmZlY3RpdmVWZXJzaW9uID0gcmVxdWVzdC52ZXJzaW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBEZXBlbmRlbmN5IFwiJHtyZXF1ZXN0Lm5hbWV9XCIgdmVyc2lvbiBjb25mbGljdDogZXhpc3RpbmcgXCIke2V4aXN0aW5nLnZlcnNpb259XCIgYCArXG4gICAgICAgICAgYGRvZXMgbm90IGludGVyc2VjdCB3aXRoIHJlcXVlc3RlZCBcIiR7cmVxdWVzdC52ZXJzaW9ufVwiYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3BlYyA9IGVmZmVjdGl2ZVZlcnNpb25cbiAgICAgID8gYCR7cmVxdWVzdC5uYW1lfUAke2VmZmVjdGl2ZVZlcnNpb259YFxuICAgICAgOiByZXF1ZXN0Lm5hbWU7XG4gICAgcmV0dXJuIHRoaXMuYWRkRGVwZW5kZW5jeShzcGVjLCByZXF1ZXN0ZWRUeXBlLCB7XG4gICAgICAuLi5leGlzdGluZy5tZXRhZGF0YSxcbiAgICAgIC4uLnJlcXVlc3QubWV0YWRhdGEsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRmluZHMgdGhlIHR5cGUgb2YgYW4gZXhpc3RpbmcgaW5zdGFsbGFibGUgZGVwZW5kZW5jeSBieSBuYW1lLlxuICAgKiBFeGNsdWRlcyBQRUVSLCBPVkVSUklERSwgYW5kIE9QVElPTkFMIHR5cGVzLlxuICAgKiBSZXR1cm5zIHVuZGVmaW5lZCBpZiBubyBkZXBlbmRlbmN5IHdpdGggdGhpcyBuYW1lIGV4aXN0cy5cbiAgICovXG4gIHByaXZhdGUgZmluZEV4aXN0aW5nSW5zdGFsbGFibGVUeXBlKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgKTogRGVwZW5kZW5jeVR5cGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9kZXBzLmZpbmQoXG4gICAgICAoZCkgPT5cbiAgICAgICAgZC5uYW1lID09PSBuYW1lICYmXG4gICAgICAgIGQudHlwZSAhPT0gRGVwZW5kZW5jeVR5cGUuUEVFUiAmJlxuICAgICAgICBkLnR5cGUgIT09IERlcGVuZGVuY3lUeXBlLk9WRVJSSURFICYmXG4gICAgICAgIGQudHlwZSAhPT0gRGVwZW5kZW5jeVR5cGUuT1BUSU9OQUwsXG4gICAgKT8udHlwZTtcbiAgfVxuXG4gIHByaXZhdGUgdHJ5R2V0RGVwZW5kZW5jeUluZGV4KG5hbWU6IHN0cmluZywgdHlwZT86IERlcGVuZGVuY3lUeXBlKTogbnVtYmVyIHtcbiAgICBjb25zdCBkZXBzID0gdGhpcy5fZGVwcy5maWx0ZXIoKGQpID0+IGQubmFtZSA9PT0gbmFtZSk7XG4gICAgaWYgKGRlcHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTE7IC8vIG5vdCBmb3VuZFxuICAgIH1cblxuICAgIGlmICghdHlwZSkge1xuICAgICAgaWYgKGRlcHMubGVuZ3RoID4gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFwiJHtuYW1lfVwiIGlzIGRlZmluZWQgZm9yIG11bHRpcGxlIGRlcGVuZGVuY3kgdHlwZXM6ICR7ZGVwc1xuICAgICAgICAgICAgLm1hcCgoZCkgPT4gZC50eXBlKVxuICAgICAgICAgICAgLmpvaW4oXCIsXCIpfS4gUGxlYXNlIHNwZWNpZnkgZGVwZW5kZW5jeSB0eXBlYCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgdHlwZSA9IGRlcHNbMF0udHlwZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fZGVwcy5maW5kSW5kZXgoXG4gICAgICAoZGVwKSA9PiBkZXAubmFtZSA9PT0gbmFtZSAmJiBkZXAudHlwZSA9PT0gdHlwZSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSB0b0pzb24oKTogRGVwc01hbmlmZXN0IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy5fZGVwcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBkZXBlbmRlbmNpZXM6IHRoaXMuX2RlcHMuc29ydChjb21wYXJlRGVwcykubWFwKG5vcm1hbGl6ZURlcCksXG4gICAgfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBub3JtYWxpemVEZXAoZDogRGVwZW5kZW5jeSkge1xuICBjb25zdCBvYmo6IGFueSA9IHt9O1xuICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhkKSkge1xuICAgIGlmICh2ID09IHVuZGVmaW5lZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdiA9PT0gXCJvYmplY3RcIiAmJiBPYmplY3Qua2V5cyh2KS5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2KSAmJiB2Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIG9ialtrXSA9IHY7XG4gIH1cblxuICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiBjb21wYXJlRGVwcyhkMTogRGVwZW5kZW5jeSwgZDI6IERlcGVuZGVuY3kpIHtcbiAgcmV0dXJuIHNwZWNPZihkMSkubG9jYWxlQ29tcGFyZShzcGVjT2YoZDIpKTtcblxuICBmdW5jdGlvbiBzcGVjT2YoZGVwOiBEZXBlbmRlbmN5KSB7XG4gICAgbGV0IHNwZWMgPSBkZXAudHlwZSArIFwiOlwiICsgZGVwLm5hbWU7XG4gICAgaWYgKGRlcC52ZXJzaW9uKSB7XG4gICAgICBzcGVjICs9IFwiQFwiICsgZGVwLnZlcnNpb247XG4gICAgfVxuICAgIHJldHVybiBzcGVjO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwc01hbmlmZXN0IHtcbiAgLyoqXG4gICAqIEFsbCBkZXBlbmRlbmNpZXMgb2YgdGhpcyBtb2R1bGUuXG4gICAqL1xuICByZWFkb25seSBkZXBlbmRlbmNpZXM6IERlcGVuZGVuY3lbXTtcbn1cblxuLyoqXG4gKiBDb29yZGluYXRlcyBvZiB0aGUgZGVwZW5kZW5jeSAobmFtZSBhbmQgdmVyc2lvbikuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGVwZW5kZW5jeUNvb3JkaW5hdGVzIHtcbiAgLyoqXG4gICAqIFRoZSBwYWNrYWdlIG1hbmFnZXIgbmFtZSBvZiB0aGUgZGVwZW5kZW5jeSAoZS5nLiBgbGVmdHBhZGAgZm9yIG5wbSkuXG4gICAqXG4gICAqIE5PVEU6IEZvciBwYWNrYWdlIG1hbmFnZXJzIHRoYXQgdXNlIGNvbXBsZXggY29vcmRpbmF0ZXMgKGxpa2UgTWF2ZW4pLCB3ZVxuICAgKiB3aWxsIGNvZGlmeSBpdCBpbnRvIGEgc3RyaW5nIHNvbWVob3cuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNlbWFudGljIHZlcnNpb24gdmVyc2lvbiByZXF1aXJlbWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSByZXF1aXJlbWVudCBpcyBtYW5hZ2VkIGJ5IHRoZSBwYWNrYWdlIG1hbmFnZXIgKGUuZy4gbnBtL3lhcm4pLlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgcHJvamVjdCBkZXBlbmRlbmN5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERlcGVuZGVuY3kgZXh0ZW5kcyBEZXBlbmRlbmN5Q29vcmRpbmF0ZXMge1xuICAvKipcbiAgICogV2hpY2ggdHlwZSBvZiBkZXBlbmRlbmN5IHRoaXMgaXMgKHJ1bnRpbWUsIGJ1aWxkLXRpbWUsIGV0YykuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiBEZXBlbmRlbmN5VHlwZTtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBKU09OIG1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGVwZW5kZW5jeSAocGFja2FnZSBtYW5hZ2VyXG4gICAqIHNwZWNpZmljKS5cbiAgICogQGRlZmF1bHQge31cbiAgICovXG4gIHJlYWRvbmx5IG1ldGFkYXRhPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfTtcbn1cblxuLyoqXG4gKiBUeXBlIG9mIGRlcGVuZGVuY3kuXG4gKi9cbmV4cG9ydCBlbnVtIERlcGVuZGVuY3lUeXBlIHtcbiAgLyoqXG4gICAqIFRoZSBkZXBlbmRlbmN5IGlzIHJlcXVpcmVkIGZvciB0aGUgcHJvZ3JhbS9saWJyYXJ5IGR1cmluZyBydW50aW1lLlxuICAgKi9cbiAgUlVOVElNRSA9IFwicnVudGltZVwiLFxuXG4gIC8qKlxuICAgKiBUaGUgZGVwZW5kZW5jeSBpcyByZXF1aXJlZCBhdCBydW50aW1lIGJ1dCBleHBlY3RlZCB0byBiZSBpbnN0YWxsZWQgYnkgdGhlXG4gICAqIGNvbnN1bWVyLlxuICAgKi9cbiAgUEVFUiA9IFwicGVlclwiLFxuXG4gIC8qKlxuICAgKiBUaGUgZGVwZW5kZW5jeSBpcyBidW5kbGVkIGFuZCBzaGlwcGVkIHdpdGggdGhlIG1vZHVsZSwgc28gY29uc3VtZXJzIGFyZSBub3RcbiAgICogcmVxdWlyZWQgdG8gaW5zdGFsbCBpdC5cbiAgICovXG4gIEJVTkRMRUQgPSBcImJ1bmRsZWRcIixcblxuICAvKipcbiAgICogVGhlIGRlcGVuZGVuY3kgaXMgcmVxdWlyZWQgdG8gcnVuIHRoZSBgYnVpbGRgIHRhc2suXG4gICAqL1xuICBCVUlMRCA9IFwiYnVpbGRcIixcblxuICAvKipcbiAgICogVGhlIGRlcGVuZGVuY3kgaXMgcmVxdWlyZWQgdG8gcnVuIHRoZSBgdGVzdGAgdGFzay5cbiAgICovXG4gIFRFU1QgPSBcInRlc3RcIixcblxuICAvKipcbiAgICogVGhlIGRlcGVuZGVuY3kgaXMgcmVxdWlyZWQgZm9yIGRldmVsb3BtZW50IChlLmcuIElERSBwbHVnaW5zKS5cbiAgICovXG4gIERFVkVOViA9IFwiZGV2ZW52XCIsXG5cbiAgLyoqXG4gICAqIFRyYW5zaWVudCBkZXBlbmRlbmN5IHRoYXQgbmVlZHMgdG8gYmUgb3ZlcndyaXR0ZW4uXG4gICAqXG4gICAqIEF2YWlsYWJsZSBmb3IgTm9kZSBwYWNrYWdlc1xuICAgKi9cbiAgT1ZFUlJJREUgPSBcIm92ZXJyaWRlXCIsXG5cbiAgLyoqXG4gICAqIEFuIG9wdGlvbmFsIGRlcGVuZGVuY3kgdGhhdCBtYXkgYmUgdXNlZCBhdCBydW50aW1lIGlmIGF2YWlsYWJsZSwgYnV0IGlzIG5vdCByZXF1aXJlZC5cbiAgICogSXQgaXMgZXhwZWN0ZWQgdG8gYmUgaW5zdGFsbGVkIGJ5IHRoZSBjb25zdW1lci5cbiAgICovXG4gIE9QVElPTkFMID0gXCJvcHRpb25hbFwiLFxufVxuXG4vKipcbiAqIEEgcmVxdWVzdCBmb3IgYSBkZXBlbmRlbmN5LiBVbmxpa2UgYWRkaW5nIGEgZGVwZW5kZW5jeSBkaXJlY3RseSxcbiAqIHJlcXVlc3RpbmcgYSBkZXBlbmRlbmN5IHdpbGwgaW50ZWxsaWdlbnRseSBtZXJnZSB3aXRoIGV4aXN0aW5nXG4gKiBkZXBlbmRlbmNpZXMgb2YgdGhlIHNhbWUgbmFtZSBhbmQgdHlwZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZXBlbmRlbmN5UmVxdWVzdCB7XG4gIC8qKlxuICAgKiBUaGUgcGFja2FnZSBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTZW1hbnRpYyB2ZXJzaW9uIGNvbnN0cmFpbnQuXG4gICAqIEBkZWZhdWx0IC0gYW55IHZlcnNpb25cbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERlcGVuZGVuY3kgdHlwZS4gSWYgbm90IHByb3ZpZGVkLCBhbiBleGlzdGluZyBkZXBlbmRlbmN5IG9mIGFueSB0eXBlXG4gICAqIHdpbGwgc2F0aXNmeSB0aGUgcmVxdWVzdC4gSWYgbm9uZSBleGlzdHMsIGl0IGlzIGFkZGVkIGFzIEJVSUxELlxuICAgKiBAZGVmYXVsdCAtIGFueSBleGlzdGluZyB0eXBlLCBvciBEZXBlbmRlbmN5VHlwZS5CVUlMRFxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZT86IERlcGVuZGVuY3lUeXBlO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIG1ldGFkYXRhLlxuICAgKiBAZGVmYXVsdCAtIG5vbmVcbiAgICovXG4gIHJlYWRvbmx5IG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgYW55Pjtcbn1cbiJdfQ==