projen
Version:
CDK for software projects
192 lines • 31.8 kB
JavaScript
;
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReleasableCommits = exports.Version = exports.CHANGES_SINCE_LAST_RELEASE = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path_1 = require("path");
const component_1 = require("./component");
const dependencies_1 = require("./dependencies");
const node_package_1 = require("./javascript/node-package");
/**
* This command determines if there were any changes since the last release in a cross-platform compatible way.
* It is used as a condition for both the `bump` and the `release` tasks.
*
* Explanation:
* - log commits | git log
* - limit log output to a single line per commit | --oneline
* - looks only at the most recent commit | -1
* - silent grep output | grep -q
* - exits with code 0 if a match is found | grep -q "chore(release):"
* - exits with code 1 if a match is found (reverse-match) | grep -qv "chore(release):"
*/
exports.CHANGES_SINCE_LAST_RELEASE = 'git log --oneline -1 | grep -qv "chore(release):"';
/**
* The default package to be used for commit-and-tag-version
*/
const COMMIT_AND_TAG_VERSION_DEFAULT = "commit-and-tag-version@^12";
class Version extends component_1.Component {
constructor(scope, options) {
super(scope);
this.changelogFileName = "changelog.md";
this.versionFileName = "version.txt";
this.releaseTagFileName = "releasetag.txt";
this.bumpPackage = options.bumpPackage ?? COMMIT_AND_TAG_VERSION_DEFAULT;
this.nextVersionCommand = options.nextVersionCommand;
// This component is language independent.
// However, when in the Node.js ecosystem, we can improve the experience by adding a dev dependency on the bump package.
const node = node_package_1.NodePackage.of(this.project);
if (node) {
const { name: bumpName, version: bumpVersion } = dependencies_1.Dependencies.parseDependency(this.bumpPackage);
if (!node.project.deps.isDependencySatisfied(bumpName, dependencies_1.DependencyType.BUILD, bumpVersion ?? "*")) {
node.project.deps.addDependency(this.bumpPackage, dependencies_1.DependencyType.BUILD);
}
}
const versionInputFile = options.versionInputFile;
const changelogFile = path_1.posix.join(options.artifactsDirectory, this.changelogFileName);
const bumpFile = path_1.posix.join(options.artifactsDirectory, this.versionFileName);
const releaseTagFile = path_1.posix.join(options.artifactsDirectory, this.releaseTagFileName);
const commonEnv = {
OUTFILE: versionInputFile,
CHANGELOG: changelogFile,
BUMPFILE: bumpFile,
RELEASETAG: releaseTagFile,
RELEASE_TAG_PREFIX: options.tagPrefix ?? "",
// doesn't work if custom configuration is long
VERSIONRCOPTIONS: JSON.stringify(options.versionrcOptions),
BUMP_PACKAGE: this.bumpPackage,
};
if (options.nextVersionCommand) {
commonEnv.NEXT_VERSION_COMMAND = options.nextVersionCommand;
}
if (options.releasableCommits) {
commonEnv.RELEASABLE_COMMITS = options.releasableCommits.cmd;
}
this.bumpTask = this.project.addTask("bump", {
description: "Bumps version based on latest git tag and generates a changelog entry",
condition: exports.CHANGES_SINCE_LAST_RELEASE,
env: { ...commonEnv },
});
this.bumpTask.builtin("release/bump-version");
this.unbumpTask = this.project.addTask("unbump", {
description: "Restores version to 0.0.0",
env: { ...commonEnv },
});
this.unbumpTask.builtin("release/reset-version");
this.project.addGitIgnore(`/${changelogFile}`);
this.project.addGitIgnore(`/${bumpFile}`);
this.project.addPackageIgnore(`/${changelogFile}`);
this.project.addPackageIgnore(`/${bumpFile}`);
}
/**
* Return the environment variables to modify the bump command for release branches.
*
* These options are used to modify the behavior of the version bumping script
* for additional branches, by setting environment variables.
*
* No settings are inherited from the base `Version` object (but any parameters that
* control versions do conflict with the use of a `nextVersionCommand`).
*/
envForBranch(branchOptions) {
if (this.nextVersionCommand && branchOptions.minMajorVersion) {
throw new Error("minMajorVersion and nextVersionCommand cannot be used together.");
}
const env = {};
if (branchOptions.majorVersion !== undefined) {
env.MAJOR = branchOptions.majorVersion.toString();
}
if (branchOptions.minMajorVersion !== undefined) {
if (branchOptions.majorVersion !== undefined) {
throw new Error(`minMajorVersion and majorVersion cannot be used together.`);
}
env.MIN_MAJOR = branchOptions.minMajorVersion.toString();
}
if (branchOptions.prerelease) {
env.PRERELEASE = branchOptions.prerelease;
}
if (branchOptions.tagPrefix) {
env.RELEASE_TAG_PREFIX = branchOptions.tagPrefix;
}
return env;
}
}
exports.Version = Version;
_a = JSII_RTTI_SYMBOL_1;
Version[_a] = { fqn: "projen.Version", version: "0.91.20" };
/**
* @deprecated use `version.bumpPackage` on the component instance instead
*/
Version.STANDARD_VERSION = COMMIT_AND_TAG_VERSION_DEFAULT;
/**
* Find commits that should be considered releasable to decide if a release is required.
*/
class ReleasableCommits {
/**
* Release every commit
*
* This will only not release if the most recent commit is tagged with the latest matching tag.
*
* @param path Consider only commits that are enough to explain how the files that match the specified paths came to be.
* This path is relative to the current working dir of the `bump` task, i.e. to only consider commits of a subproject use `"."`.
*/
static everyCommit(path) {
const cmd = `git log --oneline $LATEST_TAG..HEAD`;
return new ReleasableCommits(withPath(cmd, path));
}
/**
* Limit commits by their conventional commit type
*
* This will only release commit that match one of the provided types.
* Commits are required to follow the conventional commit spec and will be ignored otherwise.
*
* @param types List of conventional commit types that should be released
* @param path Consider only commits that are enough to explain how the files that match the specified paths came to be.
* This path is relative to the current working dir of the `bump` task, i.e. to only consider commits of a subproject use `"."`.
*/
static ofType(types, path) {
const allowedTypes = types.join("|");
// @see: https://github.com/conventional-commits/parser/blob/eeefb961ebf5b9dfea0fea8b06f8ad34a1e439b9/lib/parser.js
// -E requires this to be POSIX Extended Regular Expression, which comes with certain limitations
// see https://en.wikibooks.org/wiki/Regular_Expressions/POSIX-Extended_Regular_Expressions for details
const cmd = `git log --no-merges --oneline $LATEST_TAG..HEAD -E --grep "^(${allowedTypes}){1}(\\([^()[:space:]]+\\))?(!)?:[[:blank:]]+.+"`;
return new ReleasableCommits(withPath(cmd, path));
}
/**
* Release only features and fixes
*
* Shorthand for `ReleasableCommits.onlyOfType(['feat', 'fix'])`.
*
* @param path Consider only commits that are enough to explain how the files that match the specified paths came to be.
* This path is relative to the current working dir of the `bump` task, i.e. to only consider commits of a subproject use `"."`.
*/
static featuresAndFixes(path) {
return ReleasableCommits.ofType(["feat", "fix"], path);
}
/**
* Use an arbitrary shell command to find releasable commits since the latest tag.
*
* A new release will be initiated, if the number of returned commits is greater than zero.
* Must return a newline separate list of commits that should considered releasable.
* `$LATEST_TAG` will be replaced with the actual latest tag for the given prefix.*
*
* @example "git log --oneline $LATEST_TAG..HEAD -- ."
*/
static exec(cmd) {
return new ReleasableCommits(cmd);
}
constructor(cmd) {
this.cmd = cmd;
}
}
exports.ReleasableCommits = ReleasableCommits;
_b = JSII_RTTI_SYMBOL_1;
ReleasableCommits[_b] = { fqn: "projen.ReleasableCommits", version: "0.91.20" };
/**
* Append a path argument to a git command if one is provided
*/
function withPath(cmd, path) {
if (path !== undefined) {
return `${cmd} -- ${path}`;
}
return cmd;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0JBQTZCO0FBRTdCLDJDQUF3QztBQUN4QyxpREFBOEQ7QUFDOUQsNERBQXdEO0FBR3hEOzs7Ozs7Ozs7OztHQVdHO0FBQ1UsUUFBQSwwQkFBMEIsR0FDckMsbURBQW1ELENBQUM7QUFFdEQ7O0dBRUc7QUFDSCxNQUFNLDhCQUE4QixHQUFHLDRCQUE0QixDQUFDO0FBcUVwRSxNQUFhLE9BQVEsU0FBUSxxQkFBUztJQWdDcEMsWUFBWSxLQUFpQixFQUFFLE9BQXVCO1FBQ3BELEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUViLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxjQUFjLENBQUM7UUFDeEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxhQUFhLENBQUM7UUFDckMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGdCQUFnQixDQUFDO1FBQzNDLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsSUFBSSw4QkFBOEIsQ0FBQztRQUN6RSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBRXJELDBDQUEwQztRQUMxQyx3SEFBd0g7UUFDeEgsTUFBTSxJQUFJLEdBQUcsMEJBQVcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLElBQUksSUFBSSxFQUFFLENBQUM7WUFDVCxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLEdBQzVDLDJCQUFZLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNqRCxJQUNFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQ3RDLFFBQVEsRUFDUiw2QkFBYyxDQUFDLEtBQUssRUFDcEIsV0FBVyxJQUFJLEdB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SCxpR0FBaUc7UUFDakcsdUdBQXVHO1FBQ3ZHLE1BQU0sR0FBRyxHQUFHLGdFQUFnRSxZQUFZLGtEQUFrRCxDQUFDO1FBRTNJLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsSUFBYTtRQUNuQyxPQUFPLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQVc7UUFDckIsT0FBTyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxZQUEyQixHQUFXO1FBQVgsUUFBRyxHQUFILEdBQUcsQ0FBUTtJQUFHLENBQUM7O0FBNUQ1Qyw4Q0E2REM7OztBQUVEOztHQUVHO0FBQ0gsU0FBUyxRQUFRLENBQUMsR0FBVyxFQUFFLElBQWE7SUFDMUMsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDdkIsT0FBTyxHQUFHLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcG9zaXggfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgSUNvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi9jb21wb25lbnRcIjtcbmltcG9ydCB7IERlcGVuZGVuY2llcywgRGVwZW5kZW5jeVR5cGUgfSBmcm9tIFwiLi9kZXBlbmRlbmNpZXNcIjtcbmltcG9ydCB7IE5vZGVQYWNrYWdlIH0gZnJvbSBcIi4vamF2YXNjcmlwdC9ub2RlLXBhY2thZ2VcIjtcbmltcG9ydCB7IFRhc2sgfSBmcm9tIFwiLi90YXNrXCI7XG5cbi8qKlxuICogVGhpcyBjb21tYW5kIGRldGVybWluZXMgaWYgdGhlcmUgd2VyZSBhbnkgY2hhbmdlcyBzaW5jZSB0aGUgbGFzdCByZWxlYXNlIGluIGEgY3Jvc3MtcGxhdGZvcm0gY29tcGF0aWJsZSB3YXkuXG4gKiBJdCBpcyB1c2VkIGFzIGEgY29uZGl0aW9uIGZvciBib3RoIHRoZSBgYnVtcGAgYW5kIHRoZSBgcmVsZWFzZWAgdGFza3MuXG4gKlxuICogRXhwbGFuYXRpb246XG4gKiAgLSBsb2cgY29tbWl0cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBnaXQgbG9nXG4gKiAgLSBsaW1pdCBsb2cgb3V0cHV0IHRvIGEgc2luZ2xlIGxpbmUgcGVyIGNvbW1pdCAgICAgICAgICAgICAgfCAtLW9uZWxpbmVcbiAqICAtIGxvb2tzIG9ubHkgYXQgdGhlIG1vc3QgcmVjZW50IGNvbW1pdCAgICAgICAgICAgICAgICAgICAgICB8IC0xXG4gKiAgLSBzaWxlbnQgZ3JlcCBvdXRwdXQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBncmVwIC1xXG4gKiAgLSBleGl0cyB3aXRoIGNvZGUgMCBpZiBhIG1hdGNoIGlzIGZvdW5kICAgICAgICAgICAgICAgICAgICAgfCBncmVwIC1xIFwiY2hvcmUocmVsZWFzZSk6XCJcbiAqICAtIGV4aXRzIHdpdGggY29kZSAxIGlmIGEgbWF0Y2ggaXMgZm91bmQgKHJldmVyc2UtbWF0Y2gpICAgICB8IGdyZXAgLXF2IFwiY2hvcmUocmVsZWFzZSk6XCJcbiAqL1xuZXhwb3J0IGNvbnN0IENIQU5HRVNfU0lOQ0VfTEFTVF9SRUxFQVNFID1cbiAgJ2dpdCBsb2cgLS1vbmVsaW5lIC0xIHwgZ3JlcCAtcXYgXCJjaG9yZShyZWxlYXNlKTpcIic7XG5cbi8qKlxuICogVGhlIGRlZmF1bHQgcGFja2FnZSB0byBiZSB1c2VkIGZvciBjb21taXQtYW5kLXRhZy12ZXJzaW9uXG4gKi9cbmNvbnN0IENPTU1JVF9BTkRfVEFHX1ZFUlNJT05fREVGQVVMVCA9IFwiY29tbWl0LWFuZC10YWctdmVyc2lvbkBeMTJcIjtcblxuLyoqXG4gKiBPcHRpb25zIGZvciBgVmVyc2lvbmAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmVyc2lvbk9wdGlvbnMge1xuICAvKipcbiAgICogQSBuYW1lIG9mIGEgLmpzb24gZmlsZSB0byBzZXQgdGhlIGB2ZXJzaW9uYCBmaWVsZCBpbiBhZnRlciBhIGJ1bXAuXG4gICAqXG4gICAqIEBleGFtcGxlIFwicGFja2FnZS5qc29uXCJcbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb25JbnB1dEZpbGU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGRpcmVjdG9yeSBpbnRvIHdoaWNoIGBjaGFuZ2Vsb2cubWRgIGFuZCBgdmVyc2lvbi50eHRgIGZpbGVzXG4gICAqIGFyZSBlbWl0dGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgYXJ0aWZhY3RzRGlyZWN0b3J5OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBjb25maWd1cmF0aW9uIGZvciB2ZXJzaW9ucmMgZmlsZSB1c2VkIGJ5IHN0YW5kYXJkLXJlbGVhc2VcbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb25yY09wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG4gIC8qKlxuICAgKiBUaGUgdGFnIHByZWZpeCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgdmVyc2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IHRhZ1ByZWZpeD86IHN0cmluZztcblxuICAvKipcbiAgICogRmluZCBjb21taXRzIHRoYXQgc2hvdWxkIGJlIGNvbnNpZGVyZWQgcmVsZWFzYWJsZVxuICAgKiBVc2VkIHRvIGRlY2lkZSBpZiBhIHJlbGVhc2UgaXMgcmVxdWlyZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IFJlbGVhc2FibGVDb21taXRzLmV2ZXJ5Q29tbWl0KClcbiAgICovXG4gIHJlYWRvbmx5IHJlbGVhc2FibGVDb21taXRzPzogUmVsZWFzYWJsZUNvbW1pdHM7XG5cbiAgLyoqXG4gICAqIFRoZSBgY29tbWl0LWFuZC10YWctdmVyc2lvbmAgY29tcGF0aWJsZSBwYWNrYWdlIHVzZWQgdG8gYnVtcCB0aGUgcGFja2FnZSB2ZXJzaW9uLCBhcyBhIGRlcGVuZGVuY3kgc3RyaW5nLlxuICAgKlxuICAgKiBUaGlzIGNhbiBiZSBhbnkgY29tcGF0aWJsZSBwYWNrYWdlIHZlcnNpb24sIGluY2x1ZGluZyB0aGUgZGVwcmVjYXRlZCBgc3RhbmRhcmQtdmVyc2lvbkA5YC5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJjb21taXQtYW5kLXRhZy12ZXJzaW9uQDEyXCJcbiAgICovXG4gIHJlYWRvbmx5IGJ1bXBQYWNrYWdlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIHNoZWxsIGNvbW1hbmQgdG8gY29udHJvbCB0aGUgbmV4dCB2ZXJzaW9uIHRvIHJlbGVhc2UuXG4gICAqXG4gICAqIElmIHByZXNlbnQsIHRoaXMgc2hlbGwgY29tbWFuZCB3aWxsIGJlIHJ1biBiZWZvcmUgdGhlIGJ1bXAgaXMgZXhlY3V0ZWQsIGFuZFxuICAgKiBpdCBkZXRlcm1pbmVzIHdoYXQgdmVyc2lvbiB0byByZWxlYXNlLiBJdCB3aWxsIGJlIGV4ZWN1dGVkIGluIHRoZSBmb2xsb3dpbmdcbiAgICogZW52aXJvbm1lbnQ6XG4gICAqXG4gICAqIC0gV29ya2luZyBkaXJlY3Rvcnk6IHRoZSBwcm9qZWN0IGRpcmVjdG9yeS5cbiAgICogLSBgJFZFUlNJT05gOiB0aGUgY3VycmVudCB2ZXJzaW9uLiBMb29rcyBsaWtlIGAxLjIuM2AuXG4gICAqIC0gYCRMQVRFU1RfVEFHYDogdGhlIG1vc3QgcmVjZW50IHRhZy4gTG9va3MgbGlrZSBgcHJlZml4LXYxLjIuM2AsIG9yIG1heSBiZSB1bnNldC5cbiAgICpcbiAgICogVGhlIGNvbW1hbmQgc2hvdWxkIHByaW50IG9uZSBvZiB0aGUgZm9sbG93aW5nIHRvIGBzdGRvdXRgOlxuICAgKlxuICAgKiAtIE5vdGhpbmc6IHRoZSBuZXh0IHZlcnNpb24gbnVtYmVyIHdpbGwgYmUgZGV0ZXJtaW5lZCBiYXNlZCBvbiBjb21taXQgaGlzdG9yeS5cbiAgICogLSBgeC55LnpgOiB0aGUgbmV4dCB2ZXJzaW9uIG51bWJlciB3aWxsIGJlIGB4LnkuemAuXG4gICAqIC0gYG1ham9yfG1pbm9yfHBhdGNoYDogdGhlIG5leHQgdmVyc2lvbiBudW1iZXIgd2lsbCBiZSB0aGUgY3VycmVudCB2ZXJzaW9uIG51bWJlclxuICAgKiAgIHdpdGggdGhlIGluZGljYXRlZCBjb21wb25lbnQgYnVtcGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoZSBuZXh0IHZlcnNpb24gd2lsbCBiZSBkZXRlcm1pbmVkIGJhc2VkIG9uIHRoZSBjb21taXQgaGlzdG9yeSBhbmQgcHJvamVjdCBzZXR0aW5ncy5cbiAgICovXG4gIHJlYWRvbmx5IG5leHRWZXJzaW9uQ29tbWFuZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFZlcnNpb24gZXh0ZW5kcyBDb21wb25lbnQge1xuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgdXNlIGB2ZXJzaW9uLmJ1bXBQYWNrYWdlYCBvbiB0aGUgY29tcG9uZW50IGluc3RhbmNlIGluc3RlYWRcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgU1RBTkRBUkRfVkVSU0lPTiA9IENPTU1JVF9BTkRfVEFHX1ZFUlNJT05fREVGQVVMVDtcblxuICBwdWJsaWMgcmVhZG9ubHkgYnVtcFRhc2s6IFRhc2s7XG4gIHB1YmxpYyByZWFkb25seSB1bmJ1bXBUYXNrOiBUYXNrO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgY2hhbmdlbG9nIGZpbGUgKHVuZGVyIGBhcnRpZmFjdHNEaXJlY3RvcnlgKS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjaGFuZ2Vsb2dGaWxlTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgZmlsZSB0aGF0IGNvbnRhaW5zIHRoZSB2ZXJzaW9uICh1bmRlciBgYXJ0aWZhY3RzRGlyZWN0b3J5YCkuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdmVyc2lvbkZpbGVOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBmaWxlIHRoYXQgY29udGFpbnMgdGhlIHJlbGVhc2UgdGFnICh1bmRlciBgYXJ0aWZhY3RzRGlyZWN0b3J5YCkuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcmVsZWFzZVRhZ0ZpbGVOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwYWNrYWdlIHVzZWQgdG8gYnVtcCBwYWNrYWdlIHZlcnNpb25zLCBhcyBhIGRlcGVuZGVuY3kgc3RyaW5nLlxuICAgKiBUaGlzIGlzIGEgYGNvbW1pdC1hbmQtdGFnLXZlcnNpb25gIGNvbXBhdGlibGUgcGFja2FnZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBidW1wUGFja2FnZTogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgbmV4dFZlcnNpb25Db21tYW5kPzogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBJQ29uc3RydWN0LCBvcHRpb25zOiBWZXJzaW9uT3B0aW9ucykge1xuICAgIHN1cGVyKHNjb3BlKTtcblxuICAgIHRoaXMuY2hhbmdlbG9nRmlsZU5hbWUgPSBcImNoYW5nZWxvZy5tZFwiO1xuICAgIHRoaXMudmVyc2lvbkZpbGVOYW1lID0gXCJ2ZXJzaW9uLnR4dFwiO1xuICAgIHRoaXMucmVsZWFzZVRhZ0ZpbGVOYW1lID0gXCJyZWxlYXNldGFnLnR4dFwiO1xuICAgIHRoaXMuYnVtcFBhY2thZ2UgPSBvcHRpb25zLmJ1bXBQYWNrYWdlID8/IENPTU1JVF9BTkRfVEFHX1ZFUlNJT05fREVGQVVMVDtcbiAgICB0aGlzLm5leHRWZXJzaW9uQ29tbWFuZCA9IG9wdGlvbnMubmV4dFZlcnNpb25Db21tYW5kO1xuXG4gICAgLy8gVGhpcyBjb21wb25lbnQgaXMgbGFuZ3VhZ2UgaW5kZXBlbmRlbnQuXG4gICAgLy8gSG93ZXZlciwgd2hlbiBpbiB0aGUgTm9kZS5qcyBlY29zeXN0ZW0sIHdlIGNhbiBpbXByb3ZlIHRoZSBleHBlcmllbmNlIGJ5IGFkZGluZyBhIGRldiBkZXBlbmRlbmN5IG9uIHRoZSBidW1wIHBhY2thZ2UuXG4gICAgY29uc3Qgbm9kZSA9IE5vZGVQYWNrYWdlLm9mKHRoaXMucHJvamVjdCk7XG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIGNvbnN0IHsgbmFtZTogYnVtcE5hbWUsIHZlcnNpb246IGJ1bXBWZXJzaW9uIH0gPVxuICAgICAgICBEZXBlbmRlbmNpZXMucGFyc2VEZXBlbmRlbmN5KHRoaXMuYnVtcFBhY2thZ2UpO1xuICAgICAgaWYgKFxuICAgICAgICAhbm9kZS5wcm9qZWN0LmRlcHMuaXNEZXBlbmRlbmN5U2F0aXNmaWVkKFxuICAgICAgICAgIGJ1bXBOYW1lLFxuICAgICAgICAgIERlcGVuZGVuY3lUeXBlLkJVSUxELFxuICAgICAgICAgIGJ1bXBWZXJzaW9uID8/IFwiKlwiXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICBub2RlLnByb2plY3QuZGVwcy5hZGREZXBlbmRlbmN5KHRoaXMuYnVtcFBhY2thZ2UsIERlcGVuZGVuY3lUeXBlLkJVSUxEKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB2ZXJzaW9uSW5wdXRGaWxlID0gb3B0aW9ucy52ZXJzaW9uSW5wdXRGaWxlO1xuXG4gICAgY29uc3QgY2hhbmdlbG9nRmlsZSA9IHBvc2l4LmpvaW4oXG4gICAgICBvcHRpb25zLmFydGlmYWN0c0RpcmVjdG9yeSxcbiAgICAgIHRoaXMuY2hhbmdlbG9nRmlsZU5hbWVcbiAgICApO1xuICAgIGNvbnN0IGJ1bXBGaWxlID0gcG9zaXguam9pbihcbiAgICAgIG9wdGlvbnMuYXJ0aWZhY3RzRGlyZWN0b3J5LFxuICAgICAgdGhpcy52ZXJzaW9uRmlsZU5hbWVcbiAgICApO1xuICAgIGNvbnN0IHJlbGVhc2VUYWdGaWxlID0gcG9zaXguam9pbihcbiAgICAgIG9wdGlvbnMuYXJ0aWZhY3RzRGlyZWN0b3J5LFxuICAgICAgdGhpcy5yZWxlYXNlVGFnRmlsZU5hbWVcbiAgICApO1xuXG4gICAgY29uc3QgY29tbW9uRW52OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgT1VURklMRTogdmVyc2lvbklucHV0RmlsZSxcbiAgICAgIENIQU5HRUxPRzogY2hhbmdlbG9nRmlsZSxcbiAgICAgIEJVTVBGSUxFOiBidW1wRmlsZSxcbiAgICAgIFJFTEVBU0VUQUc6IHJlbGVhc2VUYWdGaWxlLFxuICAgICAgUkVMRUFTRV9UQUdfUFJFRklYOiBvcHRpb25zLnRhZ1ByZWZpeCA/PyBcIlwiLFxuICAgICAgLy8gZG9lc24ndCB3b3JrIGlmIGN1c3RvbSBjb25maWd1cmF0aW9uIGlzIGxvbmdcbiAgICAgIFZFUlNJT05SQ09QVElPTlM6IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMudmVyc2lvbnJjT3B0aW9ucyksXG4gICAgICBCVU1QX1BBQ0tBR0U6IHRoaXMuYnVtcFBhY2thZ2UsXG4gICAgfTtcbiAgICBpZiAob3B0aW9ucy5uZXh0VmVyc2lvbkNvbW1hbmQpIHtcbiAgICAgIGNvbW1vbkVudi5ORVhUX1ZFUlNJT05fQ09NTUFORCA9IG9wdGlvbnMubmV4dFZlcnNpb25Db21tYW5kO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5yZWxlYXNhYmxlQ29tbWl0cykge1xuICAgICAgY29tbW9uRW52LlJFTEVBU0FCTEVfQ09NTUlUUyA9IG9wdGlvbnMucmVsZWFzYWJsZUNvbW1pdHMuY21kO1xuICAgIH1cblxuICAgIHRoaXMuYnVtcFRhc2sgPSB0aGlzLnByb2plY3QuYWRkVGFzayhcImJ1bXBcIiwge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiQnVtcHMgdmVyc2lvbiBiYXNlZCBvbiBsYXRlc3QgZ2l0IHRhZyBhbmQgZ2VuZXJhdGVzIGEgY2hhbmdlbG9nIGVudHJ5XCIsXG4gICAgICBjb25kaXRpb246IENIQU5HRVNfU0lOQ0VfTEFTVF9SRUxFQVNFLFxuICAgICAgZW52OiB7IC4uLmNvbW1vbkVudiB9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5idW1wVGFzay5idWlsdGluKFwicmVsZWFzZS9idW1wLXZlcnNpb25cIik7XG5cbiAgICB0aGlzLnVuYnVtcFRhc2sgPSB0aGlzLnByb2plY3QuYWRkVGFzayhcInVuYnVtcFwiLCB7XG4gICAgICBkZXNjcmlwdGlvbjogXCJSZXN0b3JlcyB2ZXJzaW9uIHRvIDAuMC4wXCIsXG4gICAgICBlbnY6IHsgLi4uY29tbW9uRW52IH0sXG4gICAgfSk7XG5cbiAgICB0aGlzLnVuYnVtcFRhc2suYnVpbHRpbihcInJlbGVhc2UvcmVzZXQtdmVyc2lvblwiKTtcblxuICAgIHRoaXMucHJvamVjdC5hZGRHaXRJZ25vcmUoYC8ke2NoYW5nZWxvZ0ZpbGV9YCk7XG4gICAgdGhpcy5wcm9qZWN0LmFkZEdpdElnbm9yZShgLyR7YnVtcEZpbGV9YCk7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFBhY2thZ2VJZ25vcmUoYC8ke2NoYW5nZWxvZ0ZpbGV9YCk7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFBhY2thZ2VJZ25vcmUoYC8ke2J1bXBGaWxlfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIG1vZGlmeSB0aGUgYnVtcCBjb21tYW5kIGZvciByZWxlYXNlIGJyYW5jaGVzLlxuICAgKlxuICAgKiBUaGVzZSBvcHRpb25zIGFyZSB1c2VkIHRvIG1vZGlmeSB0aGUgYmVoYXZpb3Igb2YgdGhlIHZlcnNpb24gYnVtcGluZyBzY3JpcHRcbiAgICogZm9yIGFkZGl0aW9uYWwgYnJhbmNoZXMsIGJ5IHNldHRpbmcgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgKlxuICAgKiBObyBzZXR0aW5ncyBhcmUgaW5oZXJpdGVkIGZyb20gdGhlIGJhc2UgYFZlcnNpb25gIG9iamVjdCAoYnV0IGFueSBwYXJhbWV0ZXJzIHRoYXRcbiAgICogY29udHJvbCB2ZXJzaW9ucyBkbyBjb25mbGljdCB3aXRoIHRoZSB1c2Ugb2YgYSBgbmV4dFZlcnNpb25Db21tYW5kYCkuXG4gICAqL1xuICBwdWJsaWMgZW52Rm9yQnJhbmNoKFxuICAgIGJyYW5jaE9wdGlvbnM6IFZlcnNpb25CcmFuY2hPcHRpb25zXG4gICk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICAgIGlmICh0aGlzLm5leHRWZXJzaW9uQ29tbWFuZCAmJiBicmFuY2hPcHRpb25zLm1pbk1ham9yVmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIm1pbk1ham9yVmVyc2lvbiBhbmQgbmV4dFZlcnNpb25Db21tYW5kIGNhbm5vdCBiZSB1c2VkIHRvZ2V0aGVyLlwiXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGVudjogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgIGlmIChicmFuY2hPcHRpb25zLm1ham9yVmVyc2lvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBlbnYuTUFKT1IgPSBicmFuY2hPcHRpb25zLm1ham9yVmVyc2lvbi50b1N0cmluZygpO1xuICAgIH1cblxuICAgIGlmIChicmFuY2hPcHRpb25zLm1pbk1ham9yVmVyc2lvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoYnJhbmNoT3B0aW9ucy5tYWpvclZlcnNpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYG1pbk1ham9yVmVyc2lvbiBhbmQgbWFqb3JWZXJzaW9uIGNhbm5vdCBiZSB1c2VkIHRvZ2V0aGVyLmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgZW52Lk1JTl9NQUpPUiA9IGJyYW5jaE9wdGlvbnMubWluTWFqb3JWZXJzaW9uLnRvU3RyaW5nKCk7XG4gICAgfVxuXG4gICAgaWYgKGJyYW5jaE9wdGlvbnMucHJlcmVsZWFzZSkge1xuICAgICAgZW52LlBSRVJFTEVBU0UgPSBicmFuY2hPcHRpb25zLnByZXJlbGVhc2U7XG4gICAgfVxuXG4gICAgaWYgKGJyYW5jaE9wdGlvbnMudGFnUHJlZml4KSB7XG4gICAgICBlbnYuUkVMRUFTRV9UQUdfUFJFRklYID0gYnJhbmNoT3B0aW9ucy50YWdQcmVmaXg7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVudjtcbiAgfVxufVxuXG4vKipcbiAqIE9wdGlvbnMgdG8gcGFzcyB0byBgbW9kaWZ5QnJhbmNoRW52aXJvbm1lbnRgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmVyc2lvbkJyYW5jaE9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIG1ham9yIHZlcnNpb25zIHJlbGVhc2VkIGZyb20gdGhpcyBicmFuY2guXG4gICAqL1xuICByZWFkb25seSBtYWpvclZlcnNpb24/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBtaW5pbXVtIG1ham9yIHZlcnNpb24gdG8gcmVsZWFzZS5cbiAgICovXG4gIHJlYWRvbmx5IG1pbk1ham9yVmVyc2lvbj86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIG1pbm9yIHZlcnNpb25zIHJlbGVhc2VkIGZyb20gdGhpcyBicmFuY2guXG4gICAqL1xuICByZWFkb25seSBtaW5vclZlcnNpb24/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEJ1bXAgdGhlIHZlcnNpb24gYXMgYSBwcmUtcmVsZWFzZSB0YWcuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm9ybWFsIHJlbGVhc2VzXG4gICAqL1xuICByZWFkb25seSBwcmVyZWxlYXNlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBdXRvbWF0aWNhbGx5IGFkZCB0aGUgZ2l2ZW4gcHJlZml4IHRvIHJlbGVhc2UgdGFncy5cbiAgICogVXNlZnVsIGlmIHlvdSBhcmUgcmVsZWFzaW5nIG9uIG11bHRpcGxlIGJyYW5jaGVzIHdpdGggb3ZlcmxhcHBpbmdcbiAgICogdmVyc2lvbiBudW1iZXJzLlxuICAgKlxuICAgKiBOb3RlOiB0aGlzIHByZWZpeCBpcyB1c2VkIHRvIGRldGVjdCB0aGUgbGF0ZXN0IHRhZ2dlZCB2ZXJzaW9uXG4gICAqIHdoZW4gYnVtcGluZywgc28gaWYgeW91IGNoYW5nZSB0aGlzIG9uIGEgcHJvamVjdCB3aXRoIGFuIGV4aXN0aW5nIHZlcnNpb25cbiAgICogaGlzdG9yeSwgeW91IG1heSBuZWVkIHRvIG1hbnVhbGx5IHRhZyB5b3VyIGxhdGVzdCByZWxlYXNlXG4gICAqIHdpdGggdGhlIG5ldyBwcmVmaXguXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gcHJlZml4XG4gICAqL1xuICByZWFkb25seSB0YWdQcmVmaXg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogRmluZCBjb21taXRzIHRoYXQgc2hvdWxkIGJlIGNvbnNpZGVyZWQgcmVsZWFzYWJsZSB0byBkZWNpZGUgaWYgYSByZWxlYXNlIGlzIHJlcXVpcmVkLlxuICovXG5leHBvcnQgY2xhc3MgUmVsZWFzYWJsZUNvbW1pdHMge1xuICAvKipcbiAgICogUmVsZWFzZSBldmVyeSBjb21taXRcbiAgICpcbiAgICogVGhpcyB3aWxsIG9ubHkgbm90IHJlbGVhc2UgaWYgdGhlIG1vc3QgcmVjZW50IGNvbW1pdCBpcyB0YWdnZWQgd2l0aCB0aGUgbGF0ZXN0IG1hdGNoaW5nIHRhZy5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggQ29uc2lkZXIgb25seSBjb21taXRzIHRoYXQgYXJlIGVub3VnaCB0byBleHBsYWluIGhvdyB0aGUgZmlsZXMgdGhhdCBtYXRjaCB0aGUgc3BlY2lmaWVkIHBhdGhzIGNhbWUgdG8gYmUuXG4gICAqIFRoaXMgcGF0aCBpcyByZWxhdGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpciBvZiB0aGUgYGJ1bXBgIHRhc2ssIGkuZS4gdG8gb25seSBjb25zaWRlciBjb21taXRzIG9mIGEgc3VicHJvamVjdCB1c2UgYFwiLlwiYC5cbiAgICovXG4gIHN0YXRpYyBldmVyeUNvbW1pdChwYXRoPzogc3RyaW5nKSB7XG4gICAgY29uc3QgY21kID0gYGdpdCBsb2cgLS1vbmVsaW5lICRMQVRFU1RfVEFHLi5IRUFEYDtcbiAgICByZXR1cm4gbmV3IFJlbGVhc2FibGVDb21taXRzKHdpdGhQYXRoKGNtZCwgcGF0aCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpbWl0IGNvbW1pdHMgYnkgdGhlaXIgY29udmVudGlvbmFsIGNvbW1pdCB0eXBlXG4gICAqXG4gICAqIFRoaXMgd2lsbCBvbmx5IHJlbGVhc2UgY29tbWl0IHRoYXQgbWF0Y2ggb25lIG9mIHRoZSBwcm92aWRlZCB0eXBlcy5cbiAgICogQ29tbWl0cyBhcmUgcmVxdWlyZWQgdG8gZm9sbG93IHRoZSBjb252ZW50aW9uYWwgY29tbWl0IHNwZWMgYW5kIHdpbGwgYmUgaWdub3JlZCBvdGhlcndpc2UuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlcyBMaXN0IG9mIGNvbnZlbnRpb25hbCBjb21taXQgdHlwZXMgdGhhdCBzaG91bGQgYmUgcmVsZWFzZWRcbiAgICogQHBhcmFtIHBhdGggQ29uc2lkZXIgb25seSBjb21taXRzIHRoYXQgYXJlIGVub3VnaCB0byBleHBsYWluIGhvdyB0aGUgZmlsZXMgdGhhdCBtYXRjaCB0aGUgc3BlY2lmaWVkIHBhdGhzIGNhbWUgdG8gYmUuXG4gICAqIFRoaXMgcGF0aCBpcyByZWxhdGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpciBvZiB0aGUgYGJ1bXBgIHRhc2ssIGkuZS4gdG8gb25seSBjb25zaWRlciBjb21taXRzIG9mIGEgc3VicHJvamVjdCB1c2UgYFwiLlwiYC5cbiAgICovXG4gIHN0YXRpYyBvZlR5cGUodHlwZXM6IHN0cmluZ1tdLCBwYXRoPzogc3RyaW5nKSB7XG4gICAgY29uc3QgYWxsb3dlZFR5cGVzID0gdHlwZXMuam9pbihcInxcIik7XG5cbiAgICAvLyBAc2VlOiBodHRwczovL2dpdGh1Yi5jb20vY29udmVudGlvbmFsLWNvbW1pdHMvcGFyc2VyL2Jsb2IvZWVlZmI5NjFlYmY1YjlkZmVhMGZlYThiMDZmOGFkMzRhMWU0MzliOS9saWIvcGFyc2VyLmpzXG4gICAgLy8gLUUgcmVxdWlyZXMgdGhpcyB0byBiZSBQT1NJWCBFeHRlbmRlZCBSZWd1bGFyIEV4cHJlc3Npb24sIHdoaWNoIGNvbWVzIHdpdGggY2VydGFpbiBsaW1pdGF0aW9uc1xuICAgIC8vIHNlZSBodHRwczovL2VuLndpa2lib29rcy5vcmcvd2lraS9SZWd1bGFyX0V4cHJlc3Npb25zL1BPU0lYLUV4dGVuZGVkX1JlZ3VsYXJfRXhwcmVzc2lvbnMgZm9yIGRldGFpbHNcbiAgICBjb25zdCBjbWQgPSBgZ2l0IGxvZyAtLW5vLW1lcmdlcyAtLW9uZWxpbmUgJExBVEVTVF9UQUcuLkhFQUQgLUUgLS1ncmVwIFwiXigke2FsbG93ZWRUeXBlc30pezF9KFxcXFwoW14oKVs6c3BhY2U6XV0rXFxcXCkpPyghKT86W1s6Ymxhbms6XV0rLitcImA7XG5cbiAgICByZXR1cm4gbmV3IFJlbGVhc2FibGVDb21taXRzKHdpdGhQYXRoKGNtZCwgcGF0aCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGVhc2Ugb25seSBmZWF0dXJlcyBhbmQgZml4ZXNcbiAgICpcbiAgICogU2hvcnRoYW5kIGZvciBgUmVsZWFzYWJsZUNvbW1pdHMub25seU9mVHlwZShbJ2ZlYXQnLCAnZml4J10pYC5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggQ29uc2lkZXIgb25seSBjb21taXRzIHRoYXQgYXJlIGVub3VnaCB0byBleHBsYWluIGhvdyB0aGUgZmlsZXMgdGhhdCBtYXRjaCB0aGUgc3BlY2lmaWVkIHBhdGhzIGNhbWUgdG8gYmUuXG4gICAqIFRoaXMgcGF0aCBpcyByZWxhdGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpciBvZiB0aGUgYGJ1bXBgIHRhc2ssIGkuZS4gdG8gb25seSBjb25zaWRlciBjb21taXRzIG9mIGEgc3VicHJvamVjdCB1c2UgYFwiLlwiYC5cbiAgICovXG4gIHN0YXRpYyBmZWF0dXJlc0FuZEZpeGVzKHBhdGg/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gUmVsZWFzYWJsZUNvbW1pdHMub2ZUeXBlKFtcImZlYXRcIiwgXCJmaXhcIl0sIHBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZSBhbiBhcmJpdHJhcnkgc2hlbGwgY29tbWFuZCB0byBmaW5kIHJlbGVhc2FibGUgY29tbWl0cyBzaW5jZSB0aGUgbGF0ZXN0IHRhZy5cbiAgICpcbiAgICogQSBuZXcgcmVsZWFzZSB3aWxsIGJlIGluaXRpYXRlZCwgaWYgdGhlIG51bWJlciBvZiByZXR1cm5lZCBjb21taXRzIGlzIGdyZWF0ZXIgdGhhbiB6ZXJvLlxuICAgKiBNdXN0IHJldHVybiBhIG5ld2xpbmUgc2VwYXJhdGUgbGlzdCBvZiBjb21taXRzIHRoYXQgc2hvdWxkIGNvbnNpZGVyZWQgcmVsZWFzYWJsZS5cbiAgICogYCRMQVRFU1RfVEFHYCB3aWxsIGJlIHJlcGxhY2VkIHdpdGggdGhlIGFjdHVhbCBsYXRlc3QgdGFnIGZvciB0aGUgZ2l2ZW4gcHJlZml4LipcbiAgICpcbiAgICogQGV4YW1wbGUgXCJnaXQgbG9nIC0tb25lbGluZSAkTEFURVNUX1RBRy4uSEVBRCAtLSAuXCJcbiAgICovXG4gIHN0YXRpYyBleGVjKGNtZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBSZWxlYXNhYmxlQ29tbWl0cyhjbWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihwdWJsaWMgY21kOiBzdHJpbmcpIHt9XG59XG5cbi8qKlxuICogQXBwZW5kIGEgcGF0aCBhcmd1bWVudCB0byBhIGdpdCBjb21tYW5kIGlmIG9uZSBpcyBwcm92aWRlZFxuICovXG5mdW5jdGlvbiB3aXRoUGF0aChjbWQ6IHN0cmluZywgcGF0aD86IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChwYXRoICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gYCR7Y21kfSAtLSAke3BhdGh9YDtcbiAgfVxuXG4gIHJldHVybiBjbWQ7XG59XG4iXX0=