UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

194 lines 28.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Arn = void 0; const cfn_fn_1 = require("./cfn-fn"); const token_1 = require("./token"); const util_1 = require("./util"); /** * */ class Arn { /** * Creates an ARN from components. * * If `partition`, `region` or `account` are not specified, the stack's * partition, region and account will be used. * * If any component is the empty string, an empty string will be inserted * into the generated ARN at the location that component corresponds to. * * The ARN will be formatted as follows: * * arn:{partition}:{service}:{region}:{account}:{resource}{sep}{resource-name} * * The required ARN pieces that are omitted will be taken from the stack that * the 'scope' is attached to. If all ARN pieces are supplied, the supplied scope * can be 'undefined'. */ static format(components, stack) { const partition = components.partition !== undefined ? components.partition : stack.partition; const region = components.region !== undefined ? components.region : stack.region; const account = components.account !== undefined ? components.account : stack.account; const sep = components.sep !== undefined ? components.sep : '/'; const values = ['arn', ':', partition, ':', components.service, ':', region, ':', account, ':', components.resource]; if (sep !== '/' && sep !== ':' && sep !== '') { throw new Error('resourcePathSep may only be ":", "/" or an empty string'); } if (components.resourceName != null) { values.push(sep); values.push(components.resourceName); } return values.join(''); } /** * Given an ARN, parses it and returns components. * * If the ARN is a concrete string, it will be parsed and validated. The * separator (`sep`) will be set to '/' if the 6th component includes a '/', * in which case, `resource` will be set to the value before the '/' and * `resourceName` will be the rest. In case there is no '/', `resource` will * be set to the 6th components and `resourceName` will be set to the rest * of the string. * * If the ARN includes tokens (or is a token), the ARN cannot be validated, * since we don't have the actual value yet at the time of this function * call. You will have to know the separator and the type of ARN. The * resulting `ArnComponents` object will contain tokens for the * subexpressions of the ARN, not string literals. In this case this * function cannot properly parse the complete final resourceName (path) out * of ARNs that use '/' to both separate the 'resource' from the * 'resourceName' AND to subdivide the resourceName further. For example, in * S3 ARNs: * * arn:aws:s3:::my_corporate_bucket/path/to/exampleobject.png * * After parsing the resourceName will not contain * 'path/to/exampleobject.png' but simply 'path'. This is a limitation * because there is no slicing functionality in CloudFormation templates. * * @param arn The ARN to parse. * @param sepIfToken The separator used to separate resource from resourceName. * @param hasName Whether there is a name component in the ARN at all. * @returns an ArnComponents object which allows access to the various * components of the ARN. */ static parse(arn, sepIfToken = '/', hasName = true) { const components = arn.split(':'); const looksLikeArn = arn.startsWith('arn:') && components.length >= 6 && components.length <= 7; if (token_1.Token.isUnresolved(arn) && !looksLikeArn) { return parseToken(arn, sepIfToken, hasName); } // If the ARN merely contains Tokens, but otherwise *looks* mostly like an ARN, // it's a string of the form 'arn:${partition}:service:${region}:${account}:abc/xyz'. // Parse fields out to the best of our ability. // Tokens won't contain ":", so this won't break them. if (components.length < 6) { throw new Error('ARNs must have at least 6 components: ' + arn); } const [arnPrefix, partition, service, region, account, sixth, ...rest] = components; if (arnPrefix !== 'arn') { throw new Error('ARNs must start with "arn:": ' + arn); } if (!service) { throw new Error('The `service` component (3rd component) is required: ' + arn); } if (!sixth) { throw new Error('The `resource` component (6th component) is required: ' + arn); } let resource; let resourceName; let sep; let sepIndex = sixth.indexOf('/'); if (sepIndex !== -1) { sep = '/'; } else if (rest.length > 0) { sep = ':'; sepIndex = -1; } if (sepIndex !== -1) { resource = sixth.substr(0, sepIndex); resourceName = sixth.substr(sepIndex + 1); } else { resource = sixth; } if (rest.length > 0) { if (!resourceName) { resourceName = ''; } else { resourceName += ':'; } resourceName += rest.join(':'); } // "|| undefined" will cause empty strings to be treated as "undefined". // Optional ARN attributes (e.g. region, account) should return as empty string // if they are provided as such. return util_1.filterUndefined({ service: service || undefined, resource: resource || undefined, partition: partition || undefined, region, account, resourceName, sep, }); } constructor() { } } exports.Arn = Arn; /** * Given a Token evaluating to ARN, parses it and returns components. * * The ARN cannot be validated, since we don't have the actual value yet * at the time of this function call. You will have to know the separator * and the type of ARN. * * The resulting `ArnComponents` object will contain tokens for the * subexpressions of the ARN, not string literals. * * WARNING: this function cannot properly parse the complete final * resourceName (path) out of ARNs that use '/' to both separate the * 'resource' from the 'resourceName' AND to subdivide the resourceName * further. For example, in S3 ARNs: * * arn:aws:s3:::my_corporate_bucket/path/to/exampleobject.png * * After parsing the resourceName will not contain 'path/to/exampleobject.png' * but simply 'path'. This is a limitation because there is no slicing * functionality in CloudFormation templates. * * @param arnToken The input token that contains an ARN * @param sep The separator used to separate resource from resourceName * @param hasName Whether there is a name component in the ARN at all. * For example, SNS Topics ARNs have the 'resource' component contain the * topic name, and no 'resourceName' component. * @returns an ArnComponents object which allows access to the various * components of the ARN. */ function parseToken(arnToken, sep = '/', hasName = true) { // Arn ARN looks like: // arn:partition:service:region:account-id:resource // arn:partition:service:region:account-id:resourcetype/resource // arn:partition:service:region:account-id:resourcetype:resource // We need the 'hasName' argument because {Fn::Select}ing a nonexistent field // throws an error. const components = cfn_fn_1.Fn.split(':', arnToken); const partition = cfn_fn_1.Fn.select(1, components).toString(); const service = cfn_fn_1.Fn.select(2, components).toString(); const region = cfn_fn_1.Fn.select(3, components).toString(); const account = cfn_fn_1.Fn.select(4, components).toString(); if (sep === ':') { const resource = cfn_fn_1.Fn.select(5, components).toString(); const resourceName = hasName ? cfn_fn_1.Fn.select(6, components).toString() : undefined; return { partition, service, region, account, resource, resourceName, sep }; } else { const lastComponents = cfn_fn_1.Fn.split(sep, cfn_fn_1.Fn.select(5, components)); const resource = cfn_fn_1.Fn.select(0, lastComponents).toString(); const resourceName = hasName ? cfn_fn_1.Fn.select(1, lastComponents).toString() : undefined; return { partition, service, region, account, resource, resourceName, sep }; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYXJuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFDQUE4QjtBQUU5QixtQ0FBZ0M7QUFDaEMsaUNBQXlDOzs7O0FBeUR6QyxNQUFhLEdBQUc7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQWtCUCxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQXlCLEVBQUUsS0FBWTtRQUMxRCxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUM5RixNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUNsRixNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsT0FBTyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUN0RixNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsR0FBRyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBRWhFLE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLFVBQVUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFckgsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLEVBQUUsRUFBRTtZQUM1QyxNQUFNLElBQUksS0FBSyxDQUFD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LFVBQVUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3JELE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsV0FBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUUvRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLENBQUM7S0FDN0U7U0FBTTtRQUNMLE1BQU0sY0FBYyxHQUFHLFdBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLFdBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFFL0QsTUFBTSxRQUFRLEdBQUcsV0FBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDekQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxXQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBRW5GLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxHQUFHLEVBQUUsQ0FBQztLQUM3RTtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGbiB9IGZyb20gJy4vY2ZuLWZuJztcbmltcG9ydCB7IFN0YWNrIH0gZnJvbSAnLi9zdGFjayc7XG5pbXBvcnQgeyBUb2tlbiB9IGZyb20gJy4vdG9rZW4nO1xuaW1wb3J0IHsgZmlsdGVyVW5kZWZpbmVkIH0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IGludGVyZmFjZSBBcm5Db21wb25lbnRzIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBwYXJ0aXRpb24/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgc2VydmljZTogc3RyaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSByZWdpb24/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBhY2NvdW50Pzogc3RyaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSByZXNvdXJjZTogc3RyaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgc2VwPzogc3RyaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSByZXNvdXJjZU5hbWU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBBcm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBmb3JtYXQoY29tcG9uZW50czogQXJuQ29tcG9uZW50cywgc3RhY2s6IFN0YWNrKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXJ0aXRpb24gPSBjb21wb25lbnRzLnBhcnRpdGlvbiAhPT0gdW5kZWZpbmVkID8gY29tcG9uZW50cy5wYXJ0aXRpb24gOiBzdGFjay5wYXJ0aXRpb247XG4gICAgY29uc3QgcmVnaW9uID0gY29tcG9uZW50cy5yZWdpb24gIT09IHVuZGVmaW5lZCA/IGNvbXBvbmVudHMucmVnaW9uIDogc3RhY2sucmVnaW9uO1xuICAgIGNvbnN0IGFjY291bnQgPSBjb21wb25lbnRzLmFjY291bnQgIT09IHVuZGVmaW5lZCA/IGNvbXBvbmVudHMuYWNjb3VudCA6IHN0YWNrLmFjY291bnQ7XG4gICAgY29uc3Qgc2VwID0gY29tcG9uZW50cy5zZXAgIT09IHVuZGVmaW5lZCA/IGNvbXBvbmVudHMuc2VwIDogJy8nO1xuXG4gICAgY29uc3QgdmFsdWVzID0gWydhcm4nLCAnOicsIHBhcnRpdGlvbiwgJzonLCBjb21wb25lbnRzLnNlcnZpY2UsICc6JywgcmVnaW9uLCAnOicsIGFjY291bnQsICc6JywgY29tcG9uZW50cy5yZXNvdXJjZV07XG5cbiAgICBpZiAoc2VwICE9PSAnLycgJiYgc2VwICE9PSAnOicgJiYgc2VwICE9PSAnJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdyZXNvdXJjZVBhdGhTZXAgbWF5IG9ubHkgYmUgXCI6XCIsIFwiL1wiIG9yIGFuIGVtcHR5IHN0cmluZycpO1xuICAgIH1cblxuICAgIGlmIChjb21wb25lbnRzLnJlc291cmNlTmFtZSAhPSBudWxsKSB7XG4gICAgICB2YWx1ZXMucHVzaChzZXApO1xuICAgICAgdmFsdWVzLnB1c2goY29tcG9uZW50cy5yZXNvdXJjZU5hbWUpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZXMuam9pbignJyk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIHBhcnNlKGFybjogc3RyaW5nLCBzZXBJZlRva2VuOiBzdHJpbmcgPSAnLycsIGhhc05hbWU6IGJvb2xlYW4gPSB0cnVlKTogQXJuQ29tcG9uZW50cyB7XG4gICAgY29uc3QgY29tcG9uZW50cyA9IGFybi5zcGxpdCgnOicpIGFzIEFycmF5PHN0cmluZyB8IHVuZGVmaW5lZD47XG4gICAgY29uc3QgbG9va3NMaWtlQXJuID0gYXJuLnN0YXJ0c1dpdGgoJ2FybjonKSAmJiBjb21wb25lbnRzLmxlbmd0aCA+PSA2ICYmIGNvbXBvbmVudHMubGVuZ3RoIDw9IDc7XG4gICAgaWYgKFRva2VuLmlzVW5yZXNvbHZlZChhcm4pICYmICFsb29rc0xpa2VBcm4pIHtcbiAgICAgIHJldHVybiBwYXJzZVRva2VuKGFybiwgc2VwSWZUb2tlbiwgaGFzTmFtZSk7XG4gICAgfVxuICAgIC8vIElmIHRoZSBBUk4gbWVyZWx5IGNvbnRhaW5zIFRva2VucywgYnV0IG90aGVyd2lzZSAqbG9va3MqIG1vc3RseSBsaWtlIGFuIEFSTixcbiAgICAvLyBpdCdzIGEgc3RyaW5nIG9mIHRoZSBmb3JtICdhcm46JHtwYXJ0aXRpb259OnNlcnZpY2U6JHtyZWdpb259OiR7YWNjb3VudH06YWJjL3h5eicuXG4gICAgLy8gUGFyc2UgZmllbGRzIG91dCB0byB0aGUgYmVzdCBvZiBvdXIgYWJpbGl0eS5cbiAgICAvLyBUb2tlbnMgd29uJ3QgY29udGFpbiBcIjpcIiwgc28gdGhpcyB3b24ndCBicmVhayB0aGVtLlxuXG4gICAgaWYgKGNvbXBvbmVudHMubGVuZ3RoIDwgNikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBUk5zIG11c3QgaGF2ZSBhdCBsZWFzdCA2IGNvbXBvbmVudHM6ICcgKyBhcm4pO1xuICAgIH1cblxuICAgIGNvbnN0IFthcm5QcmVmaXgsIHBhcnRpdGlvbiwgc2VydmljZSwgcmVnaW9uLCBhY2NvdW50LCBzaXh0aCwgLi4ucmVzdF0gPSBjb21wb25lbnRzO1xuXG4gICAgaWYgKGFyblByZWZpeCAhPT0gJ2FybicpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQVJOcyBtdXN0IHN0YXJ0IHdpdGggXCJhcm46XCI6ICcgKyBhcm4pO1xuICAgIH1cblxuICAgIGlmICghc2VydmljZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgYHNlcnZpY2VgIGNvbXBvbmVudCAoM3JkIGNvbXBvbmVudCkgaXMgcmVxdWlyZWQ6ICcgKyBhcm4pO1xuICAgIH1cblxuICAgIGlmICghc2l4dGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGByZXNvdXJjZWAgY29tcG9uZW50ICg2dGggY29tcG9uZW50KSBpcyByZXF1aXJlZDogJyArIGFybik7XG4gICAgfVxuXG4gICAgbGV0IHJlc291cmNlOiBzdHJpbmc7XG4gICAgbGV0IHJlc291cmNlTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGxldCBzZXA6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGxldCBzZXBJbmRleCA9IHNpeHRoLmluZGV4T2YoJy8nKTtcbiAgICBpZiAoc2VwSW5kZXggIT09IC0xKSB7XG4gICAgICBzZXAgPSAnLyc7XG4gICAgfSBlbHNlIGlmIChyZXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgIHNlcCA9ICc6JztcbiAgICAgIHNlcEluZGV4ID0gLTE7XG4gICAgfVxuXG4gICAgaWYgKHNlcEluZGV4ICE9PSAtMSkge1xuICAgICAgcmVzb3VyY2UgPSBzaXh0aC5zdWJzdHIoMCwgc2VwSW5kZXgpO1xuICAgICAgcmVzb3VyY2VOYW1lID0gc2l4dGguc3Vic3RyKHNlcEluZGV4ICsgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc291cmNlID0gc2l4dGg7XG4gICAgfVxuXG4gICAgaWYgKHJlc3QubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKCFyZXNvdXJjZU5hbWUpIHtcbiAgICAgICAgcmVzb3VyY2VOYW1lID0gJyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNvdXJjZU5hbWUgKz0gJzonO1xuICAgICAgfVxuXG4gICAgICByZXNvdXJjZU5hbWUgKz0gcmVzdC5qb2luKCc6Jyk7XG4gICAgfVxuXG4gICAgLy8gXCJ8fCB1bmRlZmluZWRcIiB3aWxsIGNhdXNlIGVtcHR5IHN0cmluZ3MgdG8gYmUgdHJlYXRlZCBhcyBcInVuZGVmaW5lZFwiLlxuICAgIC8vIE9wdGlvbmFsIEFSTiBhdHRyaWJ1dGVzIChlLmcuIHJlZ2lvbiwgYWNjb3VudCkgc2hvdWxkIHJldHVybiBhcyBlbXB0eSBzdHJpbmdcbiAgICAvLyBpZiB0aGV5IGFyZSBwcm92aWRlZCBhcyBzdWNoLlxuICAgIHJldHVybiBmaWx0ZXJVbmRlZmluZWQoe1xuICAgICAgc2VydmljZTogc2VydmljZSB8fCB1bmRlZmluZWQsXG4gICAgICByZXNvdXJjZTogcmVzb3VyY2UgfHwgdW5kZWZpbmVkLFxuICAgICAgcGFydGl0aW9uOiBwYXJ0aXRpb24gfHwgdW5kZWZpbmVkLFxuICAgICAgcmVnaW9uLFxuICAgICAgYWNjb3VudCxcbiAgICAgIHJlc291cmNlTmFtZSxcbiAgICAgIHNlcCxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7IH1cbn1cblxuLyoqXG4gKiBHaXZlbiBhIFRva2VuIGV2YWx1YXRpbmcgdG8gQVJOLCBwYXJzZXMgaXQgYW5kIHJldHVybnMgY29tcG9uZW50cy5cbiAqXG4gKiBUaGUgQVJOIGNhbm5vdCBiZSB2YWxpZGF0ZWQsIHNpbmNlIHdlIGRvbid0IGhhdmUgdGhlIGFjdHVhbCB2YWx1ZSB5ZXRcbiAqIGF0IHRoZSB0aW1lIG9mIHRoaXMgZnVuY3Rpb24gY2FsbC4gWW91IHdpbGwgaGF2ZSB0byBrbm93IHRoZSBzZXBhcmF0b3JcbiAqIGFuZCB0aGUgdHlwZSBvZiBBUk4uXG4gKlxuICogVGhlIHJlc3VsdGluZyBgQXJuQ29tcG9uZW50c2Agb2JqZWN0IHdpbGwgY29udGFpbiB0b2tlbnMgZm9yIHRoZVxuICogc3ViZXhwcmVzc2lvbnMgb2YgdGhlIEFSTiwgbm90IHN0cmluZyBsaXRlcmFscy5cbiAqXG4gKiBXQVJOSU5HOiB0aGlzIGZ1bmN0aW9uIGNhbm5vdCBwcm9wZXJseSBwYXJzZSB0aGUgY29tcGxldGUgZmluYWxcbiAqIHJlc291cmNlTmFtZSAocGF0aCkgb3V0IG9mIEFSTnMgdGhhdCB1c2UgJy8nIHRvIGJvdGggc2VwYXJhdGUgdGhlXG4gKiAncmVzb3VyY2UnIGZyb20gdGhlICdyZXNvdXJjZU5hbWUnIEFORCB0byBzdWJkaXZpZGUgdGhlIHJlc291cmNlTmFtZVxuICogZnVydGhlci4gRm9yIGV4YW1wbGUsIGluIFMzIEFSTnM6XG4gKlxuICogICAgYXJuOmF3czpzMzo6Om15X2NvcnBvcmF0ZV9idWNrZXQvcGF0aC90by9leGFtcGxlb2JqZWN0LnBuZ1xuICpcbiAqIEFmdGVyIHBhcnNpbmcgdGhlIHJlc291cmNlTmFtZSB3aWxsIG5vdCBjb250YWluICdwYXRoL3RvL2V4YW1wbGVvYmplY3QucG5nJ1xuICogYnV0IHNpbXBseSAncGF0aCcuIFRoaXMgaXMgYSBsaW1pdGF0aW9uIGJlY2F1c2UgdGhlcmUgaXMgbm8gc2xpY2luZ1xuICogZnVuY3Rpb25hbGl0eSBpbiBDbG91ZEZvcm1hdGlvbiB0ZW1wbGF0ZXMuXG4gKlxuICogQHBhcmFtIGFyblRva2VuIFRoZSBpbnB1dCB0b2tlbiB0aGF0IGNvbnRhaW5zIGFuIEFSTlxuICogQHBhcmFtIHNlcCBUaGUgc2VwYXJhdG9yIHVzZWQgdG8gc2VwYXJhdGUgcmVzb3VyY2UgZnJvbSByZXNvdXJjZU5hbWVcbiAqIEBwYXJhbSBoYXNOYW1lIFdoZXRoZXIgdGhlcmUgaXMgYSBuYW1lIGNvbXBvbmVudCBpbiB0aGUgQVJOIGF0IGFsbC5cbiAqIEZvciBleGFtcGxlLCBTTlMgVG9waWNzIEFSTnMgaGF2ZSB0aGUgJ3Jlc291cmNlJyBjb21wb25lbnQgY29udGFpbiB0aGVcbiAqIHRvcGljIG5hbWUsIGFuZCBubyAncmVzb3VyY2VOYW1lJyBjb21wb25lbnQuXG4gKiBAcmV0dXJucyBhbiBBcm5Db21wb25lbnRzIG9iamVjdCB3aGljaCBhbGxvd3MgYWNjZXNzIHRvIHRoZSB2YXJpb3VzXG4gKiBjb21wb25lbnRzIG9mIHRoZSBBUk4uXG4gKi9cbmZ1bmN0aW9uIHBhcnNlVG9rZW4oYXJuVG9rZW46IHN0cmluZywgc2VwOiBzdHJpbmcgPSAnLycsIGhhc05hbWU6IGJvb2xlYW4gPSB0cnVlKTogQXJuQ29tcG9uZW50cyB7XG4gIC8vIEFybiBBUk4gbG9va3MgbGlrZTpcbiAgLy8gYXJuOnBhcnRpdGlvbjpzZXJ2aWNlOnJlZ2lvbjphY2NvdW50LWlkOnJlc291cmNlXG4gIC8vIGFybjpwYXJ0aXRpb246c2VydmljZTpyZWdpb246YWNjb3VudC1pZDpyZXNvdXJjZXR5cGUvcmVzb3VyY2VcbiAgLy8gYXJuOnBhcnRpdGlvbjpzZXJ2aWNlOnJlZ2lvbjphY2NvdW50LWlkOnJlc291cmNldHlwZTpyZXNvdXJjZVxuXG4gIC8vIFdlIG5lZWQgdGhlICdoYXNOYW1lJyBhcmd1bWVudCBiZWNhdXNlIHtGbjo6U2VsZWN0fWluZyBhIG5vbmV4aXN0ZW50IGZpZWxkXG4gIC8vIHRocm93cyBhbiBlcnJvci5cblxuICBjb25zdCBjb21wb25lbnRzID0gRm4uc3BsaXQoJzonLCBhcm5Ub2tlbik7XG5cbiAgY29uc3QgcGFydGl0aW9uID0gRm4uc2VsZWN0KDEsIGNvbXBvbmVudHMpLnRvU3RyaW5nKCk7XG4gIGNvbnN0IHNlcnZpY2UgPSBGbi5zZWxlY3QoMiwgY29tcG9uZW50cykudG9TdHJpbmcoKTtcbiAgY29uc3QgcmVnaW9uID0gRm4uc2VsZWN0KDMsIGNvbXBvbmVudHMpLnRvU3RyaW5nKCk7XG4gIGNvbnN0IGFjY291bnQgPSBGbi5zZWxlY3QoNCwgY29tcG9uZW50cykudG9TdHJpbmcoKTtcblxuICBpZiAoc2VwID09PSAnOicpIHtcbiAgICBjb25zdCByZXNvdXJjZSA9IEZuLnNlbGVjdCg1LCBjb21wb25lbnRzKS50b1N0cmluZygpO1xuICAgIGNvbnN0IHJlc291cmNlTmFtZSA9IGhhc05hbWUgPyBGbi5zZWxlY3QoNiwgY29tcG9uZW50cykudG9TdHJpbmcoKSA6IHVuZGVmaW5lZDtcblxuICAgIHJldHVybiB7IHBhcnRpdGlvbiwgc2VydmljZSwgcmVnaW9uLCBhY2NvdW50LCByZXNvdXJjZSwgcmVzb3VyY2VOYW1lLCBzZXAgfTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBsYXN0Q29tcG9uZW50cyA9IEZuLnNwbGl0KHNlcCwgRm4uc2VsZWN0KDUsIGNvbXBvbmVudHMpKTtcblxuICAgIGNvbnN0IHJlc291cmNlID0gRm4uc2VsZWN0KDAsIGxhc3RDb21wb25lbnRzKS50b1N0cmluZygpO1xuICAgIGNvbnN0IHJlc291cmNlTmFtZSA9IGhhc05hbWUgPyBGbi5zZWxlY3QoMSwgbGFzdENvbXBvbmVudHMpLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4geyBwYXJ0aXRpb24sIHNlcnZpY2UsIHJlZ2lvbiwgYWNjb3VudCwgcmVzb3VyY2UsIHJlc291cmNlTmFtZSwgc2VwIH07XG4gIH1cbn1cbiJdfQ==