UNPKG

@aws-cdk/aws-codebuild

Version:

The CDK Construct Library for AWS::CodeBuild

630 lines 76.7 kB
"use strict"; var _a, _b; Object.defineProperty(exports, "__esModule", { value: true }); exports.FilterGroup = exports.EventAction = exports.Source = void 0; const jsiiDeprecationWarnings = require("../.warnings.jsii.js"); const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const iam = require("@aws-cdk/aws-iam"); const source_types_1 = require("./source-types"); /** * Source provider definition for a CodeBuild Project. */ class Source { constructor(props) { this.badgeSupported = false; try { jsiiDeprecationWarnings._aws_cdk_aws_codebuild_SourceProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, Source); } throw error; } this.identifier = props.identifier; } static s3(props) { try { jsiiDeprecationWarnings._aws_cdk_aws_codebuild_S3SourceProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.s3); } throw error; } return new S3Source(props); } static codeCommit(props) { try { jsiiDeprecationWarnings._aws_cdk_aws_codebuild_CodeCommitSourceProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.codeCommit); } throw error; } return new CodeCommitSource(props); } static gitHub(props) { try { jsiiDeprecationWarnings._aws_cdk_aws_codebuild_GitHubSourceProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.gitHub); } throw error; } return new GitHubSource(props); } static gitHubEnterprise(props) { try { jsiiDeprecationWarnings._aws_cdk_aws_codebuild_GitHubEnterpriseSourceProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.gitHubEnterprise); } throw error; } return new GitHubEnterpriseSource(props); } static bitBucket(props) { try { jsiiDeprecationWarnings._aws_cdk_aws_codebuild_BitBucketSourceProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.bitBucket); } throw error; } return new BitBucketSource(props); } /** * Called by the project when the source is added so that the source can perform * binding operations on the source. For example, it can grant permissions to the * code build project to read from the S3 bucket. */ bind(_scope, _project) { try { jsiiDeprecationWarnings._aws_cdk_aws_codebuild_IProject(_project); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.bind); } throw error; } return { sourceProperty: { sourceIdentifier: this.identifier, type: this.type, }, }; } } exports.Source = Source; _a = JSII_RTTI_SYMBOL_1; Source[_a] = { fqn: "@aws-cdk/aws-codebuild.Source", version: "1.204.0" }; /** * A common superclass of all build sources that are backed by Git. */ class GitSource extends Source { constructor(props) { super(props); this.cloneDepth = props.cloneDepth; this.branchOrRef = props.branchOrRef; this.fetchSubmodules = props.fetchSubmodules; } bind(_scope, _project) { const superConfig = super.bind(_scope, _project); return { sourceVersion: this.branchOrRef, sourceProperty: { ...superConfig.sourceProperty, gitCloneDepth: this.cloneDepth, gitSubmodulesConfig: this.fetchSubmodules ? { fetchSubmodules: this.fetchSubmodules, } : undefined, }, }; } } /** * The types of webhook event actions. */ var EventAction; (function (EventAction) { /** * A push (of a branch, or a tag) to the repository. */ EventAction["PUSH"] = "PUSH"; /** * Creating a Pull Request. */ EventAction["PULL_REQUEST_CREATED"] = "PULL_REQUEST_CREATED"; /** * Updating a Pull Request. */ EventAction["PULL_REQUEST_UPDATED"] = "PULL_REQUEST_UPDATED"; /** * Merging a Pull Request. */ EventAction["PULL_REQUEST_MERGED"] = "PULL_REQUEST_MERGED"; /** * Re-opening a previously closed Pull Request. * Note that this event is only supported for GitHub and GitHubEnterprise sources. */ EventAction["PULL_REQUEST_REOPENED"] = "PULL_REQUEST_REOPENED"; })(EventAction = exports.EventAction || (exports.EventAction = {})); var WebhookFilterTypes; (function (WebhookFilterTypes) { WebhookFilterTypes["FILE_PATH"] = "FILE_PATH"; WebhookFilterTypes["COMMIT_MESSAGE"] = "COMMIT_MESSAGE"; WebhookFilterTypes["HEAD_REF"] = "HEAD_REF"; WebhookFilterTypes["ACTOR_ACCOUNT_ID"] = "ACTOR_ACCOUNT_ID"; WebhookFilterTypes["BASE_REF"] = "BASE_REF"; })(WebhookFilterTypes || (WebhookFilterTypes = {})); /** * An object that represents a group of filter conditions for a webhook. * Every condition in a given FilterGroup must be true in order for the whole group to be true. * You construct instances of it by calling the {@link #inEventOf} static factory method, * and then calling various `andXyz` instance methods to create modified instances of it * (this class is immutable). * * You pass instances of this class to the `webhookFilters` property when constructing a source. */ class FilterGroup { constructor(actions, filters) { if (actions.size === 0) { throw new Error('A filter group must contain at least one event action'); } this.actions = actions; this.filters = filters; } /** * Creates a new event FilterGroup that triggers on any of the provided actions. * * @param actions the actions to trigger the webhook on */ static inEventOf(...actions) { try { jsiiDeprecationWarnings._aws_cdk_aws_codebuild_EventAction(actions); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.inEventOf); } throw error; } return new FilterGroup(new Set(actions), []); } /** * Create a new FilterGroup with an added condition: * the event must affect the given branch. * * @param branchName the name of the branch (can be a regular expression) */ andBranchIs(branchName) { return this.addHeadBranchFilter(branchName, true); } /** * Create a new FilterGroup with an added condition: * the event must not affect the given branch. * * @param branchName the name of the branch (can be a regular expression) */ andBranchIsNot(branchName) { return this.addHeadBranchFilter(branchName, false); } /** * Create a new FilterGroup with an added condition: * the event must affect a head commit with the given message. * * @param commitMessage the commit message (can be a regular expression) */ andCommitMessageIs(commitMessage) { return this.addCommitMessageFilter(commitMessage, true); } /** * Create a new FilterGroup with an added condition: * the event must not affect a head commit with the given message. * * @param commitMessage the commit message (can be a regular expression) */ andCommitMessageIsNot(commitMessage) { return this.addCommitMessageFilter(commitMessage, false); } /** * Create a new FilterGroup with an added condition: * the event must affect the given tag. * * @param tagName the name of the tag (can be a regular expression) */ andTagIs(tagName) { return this.addHeadTagFilter(tagName, true); } /** * Create a new FilterGroup with an added condition: * the event must not affect the given tag. * * @param tagName the name of the tag (can be a regular expression) */ andTagIsNot(tagName) { return this.addHeadTagFilter(tagName, false); } /** * Create a new FilterGroup with an added condition: * the event must affect a Git reference (ie., a branch or a tag) * that matches the given pattern. * * @param pattern a regular expression */ andHeadRefIs(pattern) { return this.addHeadRefFilter(pattern, true); } /** * Create a new FilterGroup with an added condition: * the event must not affect a Git reference (ie., a branch or a tag) * that matches the given pattern. * * @param pattern a regular expression */ andHeadRefIsNot(pattern) { return this.addHeadRefFilter(pattern, false); } /** * Create a new FilterGroup with an added condition: * the account ID of the actor initiating the event must match the given pattern. * * @param pattern a regular expression */ andActorAccountIs(pattern) { return this.addActorAccountId(pattern, true); } /** * Create a new FilterGroup with an added condition: * the account ID of the actor initiating the event must not match the given pattern. * * @param pattern a regular expression */ andActorAccountIsNot(pattern) { return this.addActorAccountId(pattern, false); } /** * Create a new FilterGroup with an added condition: * the Pull Request that is the source of the event must target the given base branch. * Note that you cannot use this method if this Group contains the `PUSH` event action. * * @param branchName the name of the branch (can be a regular expression) */ andBaseBranchIs(branchName) { return this.addBaseBranchFilter(branchName, true); } /** * Create a new FilterGroup with an added condition: * the Pull Request that is the source of the event must not target the given base branch. * Note that you cannot use this method if this Group contains the `PUSH` event action. * * @param branchName the name of the branch (can be a regular expression) */ andBaseBranchIsNot(branchName) { return this.addBaseBranchFilter(branchName, false); } /** * Create a new FilterGroup with an added condition: * the Pull Request that is the source of the event must target the given Git reference. * Note that you cannot use this method if this Group contains the `PUSH` event action. * * @param pattern a regular expression */ andBaseRefIs(pattern) { return this.addBaseRefFilter(pattern, true); } /** * Create a new FilterGroup with an added condition: * the Pull Request that is the source of the event must not target the given Git reference. * Note that you cannot use this method if this Group contains the `PUSH` event action. * * @param pattern a regular expression */ andBaseRefIsNot(pattern) { return this.addBaseRefFilter(pattern, false); } /** * Create a new FilterGroup with an added condition: * the push that is the source of the event must affect a file that matches the given pattern. * Note that you can only use this method if this Group contains only the `PUSH` event action, * and only for GitHub, Bitbucket and GitHubEnterprise sources. * * @param pattern a regular expression */ andFilePathIs(pattern) { return this.addFilePathFilter(pattern, true); } /** * Create a new FilterGroup with an added condition: * the push that is the source of the event must not affect a file that matches the given pattern. * Note that you can only use this method if this Group contains only the `PUSH` event action, * and only for GitHub, Bitbucket and GitHubEnterprise sources. * * @param pattern a regular expression */ andFilePathIsNot(pattern) { return this.addFilePathFilter(pattern, false); } /** @internal */ get _actions() { return set2Array(this.actions); } /** @internal */ get _filters() { return this.filters.slice(); } /** @internal */ _toJson() { const eventFilter = { type: 'EVENT', pattern: set2Array(this.actions).join(', '), }; return [eventFilter].concat(this.filters); } addCommitMessageFilter(commitMessage, include) { return this.addFilter(WebhookFilterTypes.COMMIT_MESSAGE, commitMessage, include); } addHeadBranchFilter(branchName, include) { return this.addHeadRefFilter(`refs/heads/${branchName}`, include); } addHeadTagFilter(tagName, include) { return this.addHeadRefFilter(`refs/tags/${tagName}`, include); } addHeadRefFilter(refName, include) { return this.addFilter(WebhookFilterTypes.HEAD_REF, refName, include); } addActorAccountId(accountId, include) { return this.addFilter(WebhookFilterTypes.ACTOR_ACCOUNT_ID, accountId, include); } addBaseBranchFilter(branchName, include) { return this.addBaseRefFilter(`refs/heads/${branchName}`, include); } addBaseRefFilter(refName, include) { if (this.actions.has(EventAction.PUSH)) { throw new Error('A base reference condition cannot be added if a Group contains a PUSH event action'); } return this.addFilter(WebhookFilterTypes.BASE_REF, refName, include); } addFilePathFilter(pattern, include) { return this.addFilter(WebhookFilterTypes.FILE_PATH, pattern, include); } addFilter(type, pattern, include) { return new FilterGroup(this.actions, this.filters.concat([{ type, pattern, excludeMatchedPattern: include ? undefined : true, }])); } } exports.FilterGroup = FilterGroup; _b = JSII_RTTI_SYMBOL_1; FilterGroup[_b] = { fqn: "@aws-cdk/aws-codebuild.FilterGroup", version: "1.204.0" }; /** * A common superclass of all third-party build sources that are backed by Git. */ class ThirdPartyGitSource extends GitSource { constructor(props) { super(props); this.badgeSupported = true; this.webhook = props.webhook; this.reportBuildStatus = props.reportBuildStatus ?? true; this.webhookFilters = props.webhookFilters || []; this.webhookTriggersBatchBuild = props.webhookTriggersBatchBuild; this.buildStatusUrl = props.buildStatusUrl; } bind(_scope, project) { const anyFilterGroupsProvided = this.webhookFilters.length > 0; const webhook = this.webhook ?? (anyFilterGroupsProvided ? true : undefined); if (!webhook && anyFilterGroupsProvided) { throw new Error('`webhookFilters` cannot be used when `webhook` is `false`'); } if (!webhook && this.webhookTriggersBatchBuild) { throw new Error('`webhookTriggersBatchBuild` cannot be used when `webhook` is `false`'); } const superConfig = super.bind(_scope, project); if (this.webhookTriggersBatchBuild) { project.enableBatchBuilds(); } return { sourceProperty: { ...superConfig.sourceProperty, reportBuildStatus: this.reportBuildStatus, }, sourceVersion: superConfig.sourceVersion, buildTriggers: webhook === undefined ? undefined : { webhook, buildType: this.webhookTriggersBatchBuild ? 'BUILD_BATCH' : undefined, filterGroups: anyFilterGroupsProvided ? this.webhookFilters.map(fg => fg._toJson()) : undefined, }, }; } } /** * CodeCommit Source definition for a CodeBuild project. */ class CodeCommitSource extends GitSource { constructor(props) { super(props); this.badgeSupported = true; this.type = source_types_1.CODECOMMIT_SOURCE_TYPE; this.repo = props.repository; } bind(_scope, project) { // https://docs.aws.amazon.com/codebuild/latest/userguide/setting-up.html project.addToRolePolicy(new iam.PolicyStatement({ actions: ['codecommit:GitPull'], resources: [this.repo.repositoryArn], })); const superConfig = super.bind(_scope, project); return { sourceProperty: { ...superConfig.sourceProperty, location: this.repo.repositoryCloneUrlHttp, }, sourceVersion: superConfig.sourceVersion, }; } } /** * S3 bucket definition for a CodeBuild project. */ class S3Source extends Source { constructor(props) { super(props); this.type = source_types_1.S3_SOURCE_TYPE; this.bucket = props.bucket; this.path = props.path; this.version = props.version; } bind(_scope, project) { this.bucket.grantRead(project, this.path); const superConfig = super.bind(_scope, project); return { sourceProperty: { ...superConfig.sourceProperty, location: `${this.bucket.bucketName}/${this.path}`, }, sourceVersion: this.version, }; } } class CommonGithubSource extends ThirdPartyGitSource { constructor(props) { super(props); this.buildStatusContext = props.buildStatusContext; } bind(scope, project) { const superConfig = super.bind(scope, project); return { sourceProperty: { ...superConfig.sourceProperty, buildStatusConfig: this.buildStatusContext !== undefined || this.buildStatusUrl !== undefined ? { context: this.buildStatusContext, targetUrl: this.buildStatusUrl, } : undefined, }, sourceVersion: superConfig.sourceVersion, buildTriggers: superConfig.buildTriggers, }; } } /** * GitHub Source definition for a CodeBuild project. */ class GitHubSource extends CommonGithubSource { constructor(props) { super(props); this.type = source_types_1.GITHUB_SOURCE_TYPE; this.httpsCloneUrl = `https://github.com/${props.owner}/${props.repo}.git`; } bind(_scope, project) { const superConfig = super.bind(_scope, project); return { sourceProperty: { ...superConfig.sourceProperty, location: this.httpsCloneUrl, }, sourceVersion: superConfig.sourceVersion, buildTriggers: superConfig.buildTriggers, }; } } /** * GitHub Enterprise Source definition for a CodeBuild project. */ class GitHubEnterpriseSource extends CommonGithubSource { constructor(props) { super(props); this.type = source_types_1.GITHUB_ENTERPRISE_SOURCE_TYPE; this.httpsCloneUrl = props.httpsCloneUrl; this.ignoreSslErrors = props.ignoreSslErrors; } bind(_scope, _project) { if (this.hasCommitMessageFilterAndPrEvent()) { throw new Error('COMMIT_MESSAGE filters cannot be used with GitHub Enterprise Server pull request events'); } if (this.hasFilePathFilterAndPrEvent()) { throw new Error('FILE_PATH filters cannot be used with GitHub Enterprise Server pull request events'); } const superConfig = super.bind(_scope, _project); return { sourceProperty: { ...superConfig.sourceProperty, location: this.httpsCloneUrl, insecureSsl: this.ignoreSslErrors, }, sourceVersion: superConfig.sourceVersion, buildTriggers: superConfig.buildTriggers, }; } hasCommitMessageFilterAndPrEvent() { return this.webhookFilters.some(fg => (fg._filters.some(fp => fp.type === WebhookFilterTypes.COMMIT_MESSAGE) && this.hasPrEvent(fg._actions))); } hasFilePathFilterAndPrEvent() { return this.webhookFilters.some(fg => (fg._filters.some(fp => fp.type === WebhookFilterTypes.FILE_PATH) && this.hasPrEvent(fg._actions))); } hasPrEvent(actions) { return actions.includes(EventAction.PULL_REQUEST_CREATED || EventAction.PULL_REQUEST_MERGED || EventAction.PULL_REQUEST_REOPENED || EventAction.PULL_REQUEST_UPDATED); } } /** * BitBucket Source definition for a CodeBuild project. */ class BitBucketSource extends ThirdPartyGitSource { constructor(props) { super(props); this.type = source_types_1.BITBUCKET_SOURCE_TYPE; this.httpsCloneUrl = `https://bitbucket.org/${props.owner}/${props.repo}.git`; this.buildStatusName = props.buildStatusName; } bind(_scope, _project) { // BitBucket sources don't support the PULL_REQUEST_REOPENED event action if (this.anyWebhookFilterContainsPrReopenedEventAction()) { throw new Error('BitBucket sources do not support the PULL_REQUEST_REOPENED webhook event action'); } const superConfig = super.bind(_scope, _project); return { sourceProperty: { ...superConfig.sourceProperty, location: this.httpsCloneUrl, buildStatusConfig: this.buildStatusName !== undefined || this.buildStatusUrl !== undefined ? { context: this.buildStatusName, targetUrl: this.buildStatusUrl, } : undefined, }, sourceVersion: superConfig.sourceVersion, buildTriggers: superConfig.buildTriggers, }; } anyWebhookFilterContainsPrReopenedEventAction() { return this.webhookFilters.findIndex(fg => { return fg._actions.findIndex(a => a === EventAction.PULL_REQUEST_REOPENED) !== -1; }) !== -1; } } function set2Array(set) { const ret = []; set.forEach(el => ret.push(el)); return ret; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLHdDQUF3QztBQUl4QyxpREFNd0I7QUErQ3hCOztHQUVHO0FBQ0gsTUFBc0IsTUFBTTtJQXlCMUIsWUFBc0IsS0FBa0I7UUFGeEIsbUJBQWMsR0FBWSxLQUFLLENBQUM7Ozs7OzsrQ0F2QjVCLE1BQU07Ozs7UUEwQnhCLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQztLQUNwQztJQTFCTSxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQW9COzs7Ozs7Ozs7O1FBQ25DLE9BQU8sSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDNUI7SUFFTSxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQTRCOzs7Ozs7Ozs7O1FBQ25ELE9BQU8sSUFBSSxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNwQztJQUVNLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBd0I7Ozs7Ozs7Ozs7UUFDM0MsT0FBTyxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNoQztJQUVNLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFrQzs7Ozs7Ozs7OztRQUMvRCxPQUFPLElBQUksc0JBQXNCLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDMUM7SUFFTSxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQTJCOzs7Ozs7Ozs7O1FBQ2pELE9BQU8sSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDbkM7SUFVRDs7OztPQUlHO0lBQ0ksSUFBSSxDQUFDLE1BQXFCLEVBQUUsUUFBa0I7Ozs7Ozs7Ozs7UUFDbkQsT0FBTztZQUNMLGNBQWMsRUFBRTtnQkFDZCxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsVUFBVTtnQkFDakMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO2FBQ2hCO1NBQ0YsQ0FBQztLQUNIOztBQXpDSCx3QkEwQ0M7OztB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LE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNqRCxPQUFPO1lBQ0wsY0FBYyxFQUFFO2dCQUNkLEdBQUcsV0FBVyxDQUFDLGNBQWM7Z0JBQzdCLFFBQVEsRUFBRSxJQUFJLENBQUMsYUFBYTtnQkFDNUIsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLGVBQWUsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxTQUFTO29CQUN4RixDQUFDLENBQUM7d0JBQ0EsT0FBTyxFQUFFLElBQUksQ0FBQyxlQUFlO3dCQUM3QixTQUFTLEVBQUUsSUFBSSxDQUFDLGNBQWM7cUJBQy9CO29CQUNELENBQUMsQ0FBQyxTQUFTO2FBQ2Q7WUFDRCxhQUFhLEVBQUUsV0FBVyxDQUFDLGFBQWE7WUFDeEMsYUFBYSxFQUFFLFdBQVcsQ0FBQyxhQUFhO1NBQ3pDLENBQUM7S0FDSDtJQUVPLDZDQUE2QztRQUNuRCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ3hDLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssV0FBVyxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDcEYsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7S0FDWDtDQUNGO0FBRUQsU0FBUyxTQUFTLENBQUksR0FBVztJQUMvQixNQUFNLEdBQUcsR0FBUSxFQUFFLENBQUM7SUFDcEIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNoQyxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjb2RlY29tbWl0IGZyb20gJ0Bhd3MtY2RrL2F3cy1jb2RlY29tbWl0JztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdAYXdzLWNkay9hd3MtaWFtJztcbmltcG9ydCAqIGFzIHMzIGZyb20gJ0Bhd3MtY2RrL2F3cy1zMyc7XG5pbXBvcnQgeyBDZm5Qcm9qZWN0IH0gZnJvbSAnLi9jb2RlYnVpbGQuZ2VuZXJhdGVkJztcbmltcG9ydCB7IElQcm9qZWN0IH0gZnJvbSAnLi9wcm9qZWN0JztcbmltcG9ydCB7XG4gIEJJVEJVQ0tFVF9TT1VSQ0VfVFlQRSxcbiAgQ09ERUNPTU1JVF9TT1VSQ0VfVFlQRSxcbiAgR0lUSFVCX0VOVEVSUFJJU0VfU09VUkNFX1RZUEUsXG4gIEdJVEhVQl9TT1VSQ0VfVFlQRSxcbiAgUzNfU09VUkNFX1RZUEUsXG59IGZyb20gJy4vc291cmNlLXR5cGVzJztcblxuLy8gdjIgLSBrZWVwIHRoaXMgaW1wb3J0IGFzIGEgc2VwYXJhdGUgc2VjdGlvbiB0byByZWR1Y2UgbWVyZ2UgY29uZmxpY3Qgd2hlbiBmb3J3YXJkIG1lcmdpbmcgd2l0aCB0aGUgdjIgYnJhbmNoLlxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5pbXBvcnQgeyBDb25zdHJ1Y3QgYXMgQ29yZUNvbnN0cnVjdCB9IGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuXG4vKipcbiAqIFRoZSB0eXBlIHJldHVybmVkIGZyb20ge0BsaW5rIElTb3VyY2UjYmluZH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU291cmNlQ29uZmlnIHtcbiAgcmVhZG9ubHkgc291cmNlUHJvcGVydHk6IENmblByb2plY3QuU291cmNlUHJvcGVydHk7XG5cbiAgcmVhZG9ubHkgYnVpbGRUcmlnZ2Vycz86IENmblByb2plY3QuUHJvamVjdFRyaWdnZXJzUHJvcGVydHk7XG5cbiAgLyoqXG4gICAqIGBBV1M6OkNvZGVCdWlsZDo6UHJvamVjdC5Tb3VyY2VWZXJzaW9uYFxuICAgKiBAc2VlIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWNvZGVidWlsZC1wcm9qZWN0Lmh0bWwjY2ZuLWNvZGVidWlsZC1wcm9qZWN0LXNvdXJjZXZlcnNpb25cbiAgICogQGRlZmF1bHQgdGhlIGxhdGVzdCB2ZXJzaW9uXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VWZXJzaW9uPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSBhYnN0cmFjdCBpbnRlcmZhY2Ugb2YgYSBDb2RlQnVpbGQgc291cmNlLlxuICogSW1wbGVtZW50ZWQgYnkge0BsaW5rIFNvdXJjZX0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVNvdXJjZSB7XG4gIHJlYWRvbmx5IGlkZW50aWZpZXI/OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xuXG4gIHJlYWRvbmx5IGJhZGdlU3VwcG9ydGVkOiBib29sZWFuO1xuXG4gIGJpbmQoc2NvcGU6IENvcmVDb25zdHJ1Y3QsIHByb2plY3Q6IElQcm9qZWN0KTogU291cmNlQ29uZmlnO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgY29tbW9uIHRvIGFsbCBTb3VyY2UgY2xhc3Nlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTb3VyY2VQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgc291cmNlIGlkZW50aWZpZXIuXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgcmVxdWlyZWQgb24gc2Vjb25kYXJ5IHNvdXJjZXMuXG4gICAqL1xuICByZWFkb25seSBpZGVudGlmaWVyPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFNvdXJjZSBwcm92aWRlciBkZWZpbml0aW9uIGZvciBhIENvZGVCdWlsZCBQcm9qZWN0LlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgU291cmNlIGltcGxlbWVudHMgSVNvdXJjZSB7XG4gIHB1YmxpYyBzdGF0aWMgczMocHJvcHM6IFMzU291cmNlUHJvcHMpOiBJU291cmNlIHtcbiAgICByZXR1cm4gbmV3IFMzU291cmNlKHByb3BzKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgY29kZUNvbW1pdChwcm9wczogQ29kZUNvbW1pdFNvdXJjZVByb3BzKTogSVNvdXJjZSB7XG4gICAgcmV0dXJuIG5ldyBDb2RlQ29tbWl0U291cmNlKHByb3BzKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgZ2l0SHViKHByb3BzOiBHaXRIdWJTb3VyY2VQcm9wcyk6IElTb3VyY2Uge1xuICAgIHJldHVybiBuZXcgR2l0SHViU291cmNlKHByb3BzKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgZ2l0SHViRW50ZXJwcmlzZShwcm9wczogR2l0SHViRW50ZXJwcmlzZVNvdXJjZVByb3BzKTogSVNvdXJjZSB7XG4gICAgcmV0dXJuIG5ldyBHaXRIdWJFbnRlcnByaXNlU291cmNlKHByb3BzKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgYml0QnVja2V0KHByb3BzOiBCaXRCdWNrZXRTb3VyY2VQcm9wcyk6IElTb3VyY2Uge1xuICAgIHJldHVybiBuZXcgQml0QnVja2V0U291cmNlKHByb3BzKTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBpZGVudGlmaWVyPzogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgYmFkZ2VTdXBwb3J0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IocHJvcHM6IFNvdXJjZVByb3BzKSB7XG4gICAgdGhpcy5pZGVudGlmaWVyID0gcHJvcHMuaWRlbnRpZmllcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgYnkgdGhlIHByb2plY3Qgd2hlbiB0aGUgc291cmNlIGlzIGFkZGVkIHNvIHRoYXQgdGhlIHNvdXJjZSBjYW4gcGVyZm9ybVxuICAgKiBiaW5kaW5nIG9wZXJhdGlvbnMgb24gdGhlIHNvdXJjZS4gRm9yIGV4YW1wbGUsIGl0IGNhbiBncmFudCBwZXJtaXNzaW9ucyB0byB0aGVcbiAgICogY29kZSBidWlsZCBwcm9qZWN0IHRvIHJlYWQgZnJvbSB0aGUgUzMgYnVja2V0LlxuICAgKi9cbiAgcHVibGljIGJpbmQoX3Njb3BlOiBDb3JlQ29uc3RydWN0LCBfcHJvamVjdDogSVByb2plY3QpOiBTb3VyY2VDb25maWcge1xuICAgIHJldHVybiB7XG4gICAgICBzb3VyY2VQcm9wZXJ0eToge1xuICAgICAgICBzb3VyY2VJZGVudGlmaWVyOiB0aGlzLmlkZW50aWZpZXIsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIFRoZSBjb25zdHJ1Y3Rpb24gcHJvcGVydGllcyBjb21tb24gdG8gYWxsIGJ1aWxkIHNvdXJjZXMgdGhhdCBhcmUgYmFja2VkIGJ5IEdpdC5cbiAqL1xuaW50ZXJmYWNlIEdpdFNvdXJjZVByb3BzIGV4dGVuZHMgU291cmNlUHJvcHMge1xuICAvKipcbiAgICogVGhlIGRlcHRoIG9mIGhpc3RvcnkgdG8gZG93bmxvYWQuIE1pbmltdW0gdmFsdWUgaXMgMC5cbiAgICogSWYgdGhpcyB2YWx1ZSBpcyAwLCBncmVhdGVyIHRoYW4gMjUsIG9yIG5vdCBwcm92aWRlZCxcbiAgICogdGhlbiB0aGUgZnVsbCBoaXN0b3J5IGlzIGRvd25sb2FkZWQgd2l0aCBlYWNoIGJ1aWxkIG9mIHRoZSBwcm9qZWN0LlxuICAgKi9cbiAgcmVhZG9ubHkgY2xvbmVEZXB0aD86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGNvbW1pdCBJRCwgcHVsbCByZXF1ZXN0IElELCBicmFuY2ggbmFtZSwgb3IgdGFnIG5hbWUgdGhhdCBjb3JyZXNwb25kcyB0b1xuICAgKiB0aGUgdmVyc2lvbiBvZiB0aGUgc291cmNlIGNvZGUgeW91IHdhbnQgdG8gYnVpbGRcbiAgICpcbiAgICogQGV4YW1wbGUgJ215YnJhbmNoJ1xuICAgKiBAZGVmYXVsdCB0aGUgZGVmYXVsdCBicmFuY2gncyBIRUFEIGNvbW1pdCBJRCBpcyB1c2VkXG4gICAqL1xuICByZWFkb25seSBicmFuY2hPclJlZj86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0byBmZXRjaCBzdWJtb2R1bGVzIHdoaWxlIGNsb25pbmcgZ2l0IHJlcG8uXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBmZXRjaFN1Ym1vZHVsZXM/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEEgY29tbW9uIHN1cGVyY2xhc3Mgb2YgYWxsIGJ1aWxkIHNvdXJjZXMgdGhhdCBhcmUgYmFja2VkIGJ5IEdpdC5cbiAqL1xuYWJzdHJhY3QgY2xhc3MgR2l0U291cmNlIGV4dGVuZHMgU291cmNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBjbG9uZURlcHRoPzogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGJyYW5jaE9yUmVmPzogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGZldGNoU3VibW9kdWxlcz86IGJvb2xlYW47XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3BzOiBHaXRTb3VyY2VQcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcblxuICAgIHRoaXMuY2xvbmVEZXB0aCA9IHByb3BzLmNsb25lRGVwdGg7XG4gICAgdGhpcy5icmFuY2hPclJlZiA9IHByb3BzLmJyYW5jaE9yUmVmO1xuICAgIHRoaXMuZmV0Y2hTdWJtb2R1bGVzID0gcHJvcHMuZmV0Y2hTdWJtb2R1bGVzO1xuICB9XG5cbiAgcHVibGljIGJpbmQoX3Njb3BlOiBDb3JlQ29uc3RydWN0LCBfcHJvamVjdDogSVByb2plY3QpOiBTb3VyY2VDb25maWcge1xuICAgIGNvbnN0IHN1cGVyQ29uZmlnID0gc3VwZXIuYmluZChfc2NvcGUsIF9wcm9qZWN0KTtcbiAgICByZXR1cm4ge1xuICAgICAgc291cmNlVmVyc2lvbjogdGhpcy5icmFuY2hPclJlZixcbiAgICAgIHNvdXJjZVByb3BlcnR5OiB7XG4gICAgICAgIC4uLnN1cGVyQ29uZmlnLnNvdXJjZVByb3BlcnR5LFxuICAgICAgICBnaXRDbG9uZURlcHRoOiB0aGlzLmNsb25lRGVwdGgsXG4gICAgICAgIGdpdFN1Ym1vZHVsZXNDb25maWc6IHRoaXMuZmV0Y2hTdWJtb2R1bGVzID8ge1xuICAgICAgICAgIGZldGNoU3VibW9kdWxlczogdGhpcy5mZXRjaFN1Ym1vZHVsZXMsXG4gICAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICB9LFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBUaGUgdHlwZXMgb2Ygd2ViaG9vayBldmVudCBhY3Rpb25zLlxuICovXG5leHBvcnQgZW51bSBFdmVudEFjdGlvbiB7XG4gIC8qKlxuICAgKiBBIHB1c2ggKG9mIGEgYnJhbmNoLCBvciBhIHRhZykgdG8gdGhlIHJlcG9zaXRvcnkuXG4gICAqL1xuICBQVVNIID0gJ1BVU0gnLFxuXG4gIC8qKlxuICAgKiBDcmVhdGluZyBhIFB1bGwgUmVxdWVzdC5cbiAgICovXG4gIFBVTExfUkVRVUVTVF9DUkVBVEVEID0gJ1BVTExfUkVRVUVTVF9DUkVBVEVEJyxcblxuICAvKipcbiAgICogVXBkYXRpbmcgYSBQdWxsIFJlcXVlc3QuXG4gICAqL1xuICBQVUxMX1JFUVVFU1RfVVBEQVRFRCA9ICdQVUxMX1JFUVVFU1RfVVBEQVRFRCcsXG5cbiAgLyoqXG4gICAqIE1lcmdpbmcgYSBQdWxsIFJlcXVlc3QuXG4gICAqL1xuICBQVUxMX1JFUVVFU1RfTUVSR0VEID0gJ1BVTExfUkVRVUVTVF9NRVJHRUQnLFxuXG4gIC8qKlxuICAgKiBSZS1vcGVuaW5nIGEgcHJldmlvdXNseSBjbG9zZWQgUHVsbCBSZXF1ZXN0LlxuICAgKiBOb3RlIHRoYXQgdGhpcyBldmVudCBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgR2l0SHViIGFuZCBHaXRIdWJFbnRlcnByaXNlIHNvdXJjZXMuXG4gICAqL1xuICBQVUxMX1JFUVVFU1RfUkVPUEVORUQgPSAnUFVMTF9SRVFVRVNUX1JFT1BFTkVEJyxcbn1cblxuZW51bSBXZWJob29rRmlsdGVyVHlwZXMge1xuICBGSUxFX1BBVEggPSAnRklMRV9QQVRIJyxcbiAgQ09NTUlUX01FU1NBR0UgPSAnQ09NTUlUX01FU1NBR0UnLFxuICBIRUFEX1JFRiA9ICdIRUFEX1JFRicsXG4gIEFDVE9SX0FDQ09VTlRfSUQgPSAnQUNUT1JfQUNDT1VOVF9JRCcsXG4gIEJBU0VfUkVGID0gJ0JBU0VfUkVGJyxcbn1cblxuLyoqXG4gKiBBbiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgZ3JvdXAgb2YgZmlsdGVyIGNvbmRpdGlvbnMgZm9yIGEgd2ViaG9vay5cbiAqIEV2ZXJ5IGNvbmRpdGlvbiBpbiBhIGdpdmVuIEZpbHRlckdyb3VwIG11c3QgYmUgdHJ1ZSBpbiBvcmRlciBmb3IgdGhlIHdob2xlIGdyb3VwIHRvIGJlIHRydWUuXG4gKiBZb3UgY29uc3RydWN0IGluc3RhbmNlcyBvZiBpdCBieSBjYWxsaW5nIHRoZSB7QGxpbmsgI2luRXZlbnRPZn0gc3RhdGljIGZhY3RvcnkgbWV0aG9kLFxuICogYW5kIHRoZW4gY2FsbGluZyB2YXJpb3VzIGBhbmRYeXpgIGluc3RhbmNlIG1ldGhvZHMgdG8gY3JlYXRlIG1vZGlmaWVkIGluc3RhbmNlcyBvZiBpdFxuICogKHRoaXMgY2xhc3MgaXMgaW1tdXRhYmxlKS5cbiAqXG4gKiBZb3UgcGFzcyBpbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyB0byB0aGUgYHdlYmhvb2tGaWx0ZXJzYCBwcm9wZXJ0eSB3aGVuIGNvbnN0cnVjdGluZyBhIHNvdXJjZS5cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbHRlckdyb3VwIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgZXZlbnQgRmlsdGVyR3JvdXAgdGhhdCB0cmlnZ2VycyBvbiBhbnkgb2YgdGhlIHByb3ZpZGVkIGFjdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBhY3Rpb25zIHRoZSBhY3Rpb25zIHRvIHRyaWdnZXIgdGhlIHdlYmhvb2sgb25cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgaW5FdmVudE9mKC4uLmFjdGlvbnM6IEV2ZW50QWN0aW9uW10pOiBGaWx0ZXJHcm91cCB7XG4gICAgcmV0dXJuIG5ldyBGaWx0ZXJHcm91cChuZXcgU2V0KGFjdGlvbnMpLCBbXSk7XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IGFjdGlvbnM6IFNldDxFdmVudEFjdGlvbj47XG4gIHByaXZhdGUgcmVhZG9ubHkgZmlsdGVyczogQ2ZuUHJvamVjdC5XZWJob29rRmlsdGVyUHJvcGVydHlbXTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKGFjdGlvbnM6IFNldDxFdmVudEFjdGlvbj4sIGZpbHRlcnM6IENmblByb2plY3QuV2ViaG9va0ZpbHRlclByb3BlcnR5W10pIHtcbiAgICBpZiAoYWN0aW9ucy5zaXplID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgZmlsdGVyIGdyb3VwIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgZXZlbnQgYWN0aW9uJyk7XG4gICAgfVxuICAgIHRoaXMuYWN0aW9ucyA9IGFjdGlvbnM7XG4gICAgdGhpcy5maWx0ZXJzID0gZmlsdGVycztcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgRmlsdGVyR3JvdXAgd2l0aCBhbiBhZGRlZCBjb25kaXRpb246XG4gICAqIHRoZSBldmVudCBtdXN0IGFmZmVjdCB0aGUgZ2l2ZW4gYnJhbmNoLlxuICAgKlxuICAgKiBAcGFyYW0gYnJhbmNoTmFtZSB0aGUgbmFtZSBvZiB0aGUgYnJhbmNoIChjYW4gYmUgYSByZWd1bGFyIGV4cHJlc3Npb24pXG4gICAqL1xuICBwdWJsaWMgYW5kQnJhbmNoSXMoYnJhbmNoTmFtZTogc3RyaW5nKTogRmlsdGVyR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmFkZEhlYWRCcmFuY2hGaWx0ZXIoYnJhbmNoTmFtZSwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IEZpbHRlckdyb3VwIHdpdGggYW4gYWRkZWQgY29uZGl0aW9uOlxuICAgKiB0aGUgZXZlbnQgbXVzdCBub3QgYWZmZWN0IHRoZSBnaXZlbiBicmFuY2guXG4gICAqXG4gICAqIEBwYXJhbSBicmFuY2hOYW1lIHRoZSBuYW1lIG9mIHRoZSBicmFuY2ggKGNhbiBiZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbilcbiAgICovXG4gIHB1YmxpYyBhbmRCcmFuY2hJc05vdChicmFuY2hOYW1lOiBzdHJpbmcpOiBGaWx0ZXJHcm91cCB7XG4gICAgcmV0dXJuIHRoaXMuYWRkSGVhZEJyYW5jaEZpbHRlcihicmFuY2hOYW1lLCBmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IEZpbHRlckdyb3VwIHdpdGggYW4gYWRkZWQgY29uZGl0aW9uOlxuICAgKiB0aGUgZXZlbnQgbXVzdCBhZmZlY3QgYSBoZWFkIGNvbW1pdCB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLlxuICAgKlxuICAgKiBAcGFyYW0gY29tbWl0TWVzc2FnZSB0aGUgY29tbWl0IG1lc3NhZ2UgKGNhbiBiZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbilcbiAgICovXG4gIHB1YmxpYyBhbmRDb21taXRNZXNzYWdlSXMoY29tbWl0TWVzc2FnZTogc3RyaW5nKTogRmlsdGVyR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmFkZENvbW1pdE1lc3NhZ2VGaWx0ZXIoY29tbWl0TWVzc2FnZSwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IEZpbHRlckdyb3VwIHdpdGggYW4gYWRkZWQgY29uZGl0aW9uOlxuICAgKiB0aGUgZXZlbnQgbXVzdCBub3QgYWZmZWN0IGEgaGVhZCBjb21taXQgd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS5cbiAgICpcbiAgICogQHBhcmFtIGNvbW1pdE1lc3NhZ2UgdGhlIGNvbW1pdCBtZXNzYWdlIChjYW4gYmUgYSByZWd1bGFyIGV4cHJlc3Npb24pXG4gICAqL1xuICBwdWJsaWMgYW5kQ29tbWl0TWVzc2FnZUlzTm90KGNvbW1pdE1lc3NhZ2U6IHN0cmluZyk6IEZpbHRlckdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy5hZGRDb21taXRNZXNzYWdlRmlsdGVyKGNvbW1pdE1lc3NhZ2UsIGZhbHNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgRmlsdGVyR3JvdXAgd2l0aCBhbiBhZGRlZCBjb25kaXRpb246XG4gICAqIHRoZSBldmVudCBtdXN0IGFmZmVjdCB0aGUgZ2l2ZW4gdGFnLlxuICAgKlxuICAgKiBAcGFyYW0gdGFnTmFtZSB0aGUgbmFtZSBvZiB0aGUgdGFnIChjYW4gYmUgYSByZWd1bGFyIGV4cHJlc3Npb24pXG4gICAqL1xuICBwdWJsaWMgYW5kVGFnSXModGFnTmFtZTogc3RyaW5nKTogRmlsdGVyR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmFkZEhlYWRUYWdGaWx0ZXIodGFnTmFtZSwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IEZpbHRlckdyb3VwIHdpdGggYW4gYWRkZWQgY29uZGl0aW9uOlxuICAgKiB0aGUgZXZlbnQgbXVzdCBub3QgYWZmZWN0IHRoZSBnaXZlbiB0YWcuXG4gICAqXG4gICAqIEBwYXJhbSB0YWdOYW1lIHRoZSBuYW1lIG9mIHRoZSB0YWcgKGNhbiBiZSBhIHJlZ3VsYXIgZXhwc