cdk8s-cli
Version:
This is the command line tool for Cloud Development Kit (CDK) for Kubernetes (cdk8s).
143 lines • 19 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.findApiObjectDefinitions = exports.ImportKubernetesApi = exports.DEFAULT_API_VERSION = void 0;
const json2jsii_1 = require("json2jsii");
const base_1 = require("./base");
const codegen_1 = require("./codegen");
const k8s_util_1 = require("./k8s-util");
const util_1 = require("../util");
exports.DEFAULT_API_VERSION = '1.25.0';
const DEFAULT_CLASS_NAME_PREFIX = 'Kube';
class ImportKubernetesApi extends base_1.ImportBase {
static async match(importSpec, argv) {
var _a;
const { source } = importSpec;
if (source !== 'k8s' && !source.startsWith('k8s@')) {
return undefined;
}
let k8sVersion = (_a = source.split('@')[1]) !== null && _a !== void 0 ? _a : exports.DEFAULT_API_VERSION;
const k8sVersionRegex = /^\d+\.\d+\.\d+$/;
if (!k8sVersionRegex.test(k8sVersion)) {
throw new Error(`Expected k8s version "${k8sVersion}" to match format "<major>.<minor>.<patch>".`);
}
console.error(`Importing k8s v${k8sVersion}...`);
return {
apiVersion: k8sVersion,
exclude: argv.exclude,
};
}
constructor(options) {
super();
this.options = options;
}
get moduleNames() {
return ['k8s'];
}
async generateTypeScript(code, moduleName, options) {
var _a;
const schema = await downloadSchema(this.options.apiVersion);
if (moduleName !== 'k8s') {
throw new Error(`unexpected module name "${moduleName}" when importing k8s types (expected "k8s")`);
}
const prefix = (_a = options.classNamePrefix) !== null && _a !== void 0 ? _a : DEFAULT_CLASS_NAME_PREFIX;
const topLevelObjects = findApiObjectDefinitions(schema, prefix);
const typeGenerator = new json2jsii_1.TypeGenerator({
definitions: schema.definitions,
exclude: this.options.exclude,
renderTypeName: (def) => {
const parsed = (0, k8s_util_1.parseApiTypeName)(def);
if (!parsed.version) {
// not a versioned api type. return basename
return parsed.basename;
}
return (0, codegen_1.getTypeName)(false, parsed.basename, parsed.version.raw);
},
});
// rename "Props" type from their original name based on the API object kind
// (e.g. `Deployment`) to their actual props type (`KubeDeploymentProps`) in
// order to avoid confusion between constructs (`KubeDeployment`) and those
// types. This is done by simply replacing their definition in the schema
// with a $ref to the definition of the props type.
for (const o of topLevelObjects) {
typeGenerator.addDefinition(o.fqn, { $ref: `#/definitions/${(0, codegen_1.getPropsTypeName)(o)}` });
}
// emit construct types (recursive)
for (const o of topLevelObjects) {
(0, codegen_1.generateConstruct)(typeGenerator, o);
}
(0, codegen_1.emitHeader)(code, false);
code.line(typeGenerator.render());
}
}
exports.ImportKubernetesApi = ImportKubernetesApi;
/**
* Returns a map of all API objects in the spec (objects that have the
* 'x-kubernetes-group-version-kind' annotation).
*
* The key is the base name of the type (i.e. `Deployment`). Since API objects
* may have multiple versions, each value in the map is an array of type definitions
* along with version information.
*
* @see https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-versioning
*/
function findApiObjectDefinitions(schema, prefix) {
const result = new Array();
for (const [typename, apischema] of Object.entries(schema.definitions || {})) {
const objectName = tryGetObjectName(apischema);
if (!objectName) {
continue;
}
const type = (0, k8s_util_1.parseApiTypeName)(typename);
if (!type.version) {
throw new Error(`Unable to parse version for type: ${typename}`);
}
result.push({
custom: false,
fqn: type.fullname,
group: objectName.group,
kind: objectName.kind,
version: objectName.version,
schema: apischema,
prefix,
});
}
return result;
}
exports.findApiObjectDefinitions = findApiObjectDefinitions;
function tryGetObjectName(def) {
var _a;
const objectNames = def[X_GROUP_VERSION_KIND];
if (!objectNames) {
return undefined;
}
const objectName = objectNames[0];
if (!objectName) {
return undefined;
}
// skip definitions without "metadata". they are not API objects that can be defined
// in manifests (example: io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions)
// they will be treated as data types
if (!((_a = def.properties) === null || _a === void 0 ? void 0 : _a.metadata)) {
return undefined;
}
return objectName;
}
const X_GROUP_VERSION_KIND = 'x-kubernetes-group-version-kind';
async function downloadSchema(apiVersion) {
const url = `https://raw.githubusercontent.com/cdk8s-team/cdk8s/master/kubernetes-schemas/v${apiVersion}/_definitions.json`;
let output;
try {
output = await (0, util_1.download)(url);
}
catch (e) {
console.error(`Could not find a schema for k8s version ${apiVersion}. The current list of available schemas is at https://github.com/cdk8s-team/cdk8s/tree/master/kubernetes-schemas.`);
throw e;
}
try {
return (0, k8s_util_1.safeParseJsonSchema)(output);
}
catch (e) {
throw new Error(`Unable to parse schema at ${url}: ${e}`);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiazhzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ltcG9ydC9rOHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBTUEseUNBQTBDO0FBQzFDLGlDQUFxRDtBQUNyRCx1Q0FBOEc7QUFDOUcseUNBQW1FO0FBRW5FLGtDQUFtQztBQUd0QixRQUFBLG1CQUFtQixHQUFHLFFBQVEsQ0FBQztBQUU1QyxNQUFNLHlCQUF5QixHQUFHLE1BQU0sQ0FBQztBQWdCekMsTUFBYSxtQkFBb0IsU0FBUSxpQkFBVTtJQUUxQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxVQUFzQixFQUFFLElBQVM7O1FBQ3pELE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUM7UUFDOUIsSUFBSSxNQUFNLEtBQUssS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNsRCxPQUFPLFNBQVMsQ0FBQztTQUNsQjtRQUVELElBQUksVUFBVSxHQUFHLE1BQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsbUNBQUksMkJBQW1CLENBQUM7UUFFN0QsTUFBTSxlQUFlLEdBQUcsaUJBQWlCLENBQUM7UUFDMUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDckMsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsVUFBVSw4Q0FBOEMsQ0FBQyxDQUFDO1NBQ3BHO1FBRUQsT0FBTyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsVUFBVSxLQUFLLENBQUMsQ0FBQztRQUVqRCxPQUFPO1lBQ0wsVUFBVSxFQUFFLFVBQVU7WUFDdEIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1NBQ3RCLENBQUM7SUFDSixDQUFDO0lBRUQsWUFBNkIsT0FBbUM7UUFDOUQsS0FBSyxFQUFFLENBQUM7UUFEbUIsWUFBTyxHQUFQLE9BQU8sQ0FBNEI7SUFFaEUs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SUFBQyxPQUFPLENBQUMsRUFBRTtRQUNWLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0tBQzNEO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvZGVNYWtlciB9IGZyb20gJ2NvZGVtYWtlcic7XG5cbi8vIHdlIGp1c3QgbmVlZCB0aGUgdHlwZXMgZnJvbSBqc29uLXNjaGVtYVxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llc1xuaW1wb3J0IHsgSlNPTlNjaGVtYTQgfSBmcm9tICdqc29uLXNjaGVtYSc7XG5cbmltcG9ydCB7IFR5cGVHZW5lcmF0b3IgfSBmcm9tICdqc29uMmpzaWknO1xuaW1wb3J0IHsgR2VuZXJhdGVPcHRpb25zLCBJbXBvcnRCYXNlIH0gZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7IEFwaU9iamVjdERlZmluaXRpb24sIGVtaXRIZWFkZXIsIGdlbmVyYXRlQ29uc3RydWN0LCBnZXRQcm9wc1R5cGVOYW1lLCBnZXRUeXBlTmFtZSB9IGZyb20gJy4vY29kZWdlbic7XG5pbXBvcnQgeyBwYXJzZUFwaVR5cGVOYW1lLCBzYWZlUGFyc2VKc29uU2NoZW1hIH0gZnJvbSAnLi9rOHMtdXRpbCc7XG5pbXBvcnQgeyBJbXBvcnRTcGVjIH0gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCB7IGRvd25sb2FkIH0gZnJvbSAnLi4vdXRpbCc7XG5cblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfQVBJX1ZFUlNJT04gPSAnMS4yNS4wJztcblxuY29uc3QgREVGQVVMVF9DTEFTU19OQU1FX1BSRUZJWCA9ICdLdWJlJztcblxuZXhwb3J0IGludGVyZmFjZSBJbXBvcnRLdWJlcm5ldGVzQXBpT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgQVBJIHZlcnNpb24gdG8gZ2VuZXJhdGUuXG4gICAqL1xuICByZWFkb25seSBhcGlWZXJzaW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERvIG5vdCBpbXBvcnQgdGhlc2UgdHlwZXMuIEluc3RlYWQsIHJlcHJlc2VudCB0aGVtIGFzIFwiYW55XCIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gaW5jbHVkZSBhbGwgdHlwZXMgdGhhdCBkZXJpdmUgZnJvbSB0aGUgcm9vdCB0eXBlcy5cbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGU/OiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGNsYXNzIEltcG9ydEt1YmVybmV0ZXNBcGkgZXh0ZW5kcyBJbXBvcnRCYXNlIHtcblxuICBwdWJsaWMgc3RhdGljIGFzeW5jIG1hdGNoKGltcG9ydFNwZWM6IEltcG9ydFNwZWMsIGFyZ3Y6IGFueSk6IFByb21pc2U8SW1wb3J0S3ViZXJuZXRlc0FwaU9wdGlvbnMgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCB7IHNvdXJjZSB9ID0gaW1wb3J0U3BlYztcbiAgICBpZiAoc291cmNlICE9PSAnazhzJyAmJiAhc291cmNlLnN0YXJ0c1dpdGgoJ2s4c0AnKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBsZXQgazhzVmVyc2lvbiA9IHNvdXJjZS5zcGxpdCgnQCcpWzFdID8/IERFRkFVTFRfQVBJX1ZFUlNJT047XG5cbiAgICBjb25zdCBrOHNWZXJzaW9uUmVnZXggPSAvXlxcZCtcXC5cXGQrXFwuXFxkKyQvO1xuICAgIGlmICghazhzVmVyc2lvblJlZ2V4LnRlc3QoazhzVmVyc2lvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgazhzIHZlcnNpb24gXCIke2s4c1ZlcnNpb259XCIgdG8gbWF0Y2ggZm9ybWF0IFwiPG1ham9yPi48bWlub3I+LjxwYXRjaD5cIi5gKTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmVycm9yKGBJbXBvcnRpbmcgazhzIHYke2s4c1ZlcnNpb259Li4uYCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgYXBpVmVyc2lvbjogazhzVmVyc2lvbixcbiAgICAgIGV4Y2x1ZGU6IGFyZ3YuZXhjbHVkZSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBJbXBvcnRLdWJlcm5ldGVzQXBpT3B0aW9ucykge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IG1vZHVsZU5hbWVzKCkge1xuICAgIHJldHVybiBbJ2s4cyddO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdlbmVyYXRlVHlwZVNjcmlwdChjb2RlOiBDb2RlTWFrZXIsIG1vZHVsZU5hbWU6IHN0cmluZywgb3B0aW9uczogR2VuZXJhdGVPcHRpb25zKSB7XG4gICAgY29uc3Qgc2NoZW1hID0gYXdhaXQgZG93bmxvYWRTY2hlbWEodGhpcy5vcHRpb25zLmFwaVZlcnNpb24pO1xuXG4gICAgaWYgKG1vZHVsZU5hbWUgIT09ICdrOHMnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuZXhwZWN0ZWQgbW9kdWxlIG5hbWUgXCIke21vZHVsZU5hbWV9XCIgd2hlbiBpbXBvcnRpbmcgazhzIHR5cGVzIChleHBlY3RlZCBcIms4c1wiKWApO1xuICAgIH1cblxuICAgIGNvbnN0IHByZWZpeCA9IG9wdGlvbnMuY2xhc3NOYW1lUHJlZml4ID8/IERFRkFVTFRfQ0xBU1NfTkFNRV9QUkVGSVg7XG4gICAgY29uc3QgdG9wTGV2ZWxPYmplY3RzID0gZmluZEFwaU9iamVjdERlZmluaXRpb25zKHNjaGVtYSwgcHJlZml4KTtcblxuICAgIGNvbnN0IHR5cGVHZW5lcmF0b3IgPSBuZXcgVHlwZUdlbmVyYXRvcih7XG4gICAgICBkZWZpbml0aW9uczogc2NoZW1hLmRlZmluaXRpb25zLFxuICAgICAgZXhjbHVkZTogdGhpcy5vcHRpb25zLmV4Y2x1ZGUsXG4gICAgICByZW5kZXJUeXBlTmFtZTogKGRlZjogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlQXBpVHlwZU5hbWUoZGVmKTtcbiAgICAgICAgaWYgKCFwYXJzZWQudmVyc2lvbikge1xuICAgICAgICAgIC8vIG5vdCBhIHZlcnNpb25lZCBhcGkgdHlwZS4gcmV0dXJuIGJhc2VuYW1lXG4gICAgICAgICAgcmV0dXJuIHBhcnNlZC5iYXNlbmFtZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZ2V0VHlwZU5hbWUoZmFsc2UsIHBhcnNlZC5iYXNlbmFtZSwgcGFyc2VkLnZlcnNpb24ucmF3KTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyByZW5hbWUgXCJQcm9wc1wiIHR5cGUgZnJvbSB0aGVpciBvcmlnaW5hbCBuYW1lIGJhc2VkIG9uIHRoZSBBUEkgb2JqZWN0IGtpbmRcbiAgICAvLyAoZS5nLiBgRGVwbG95bWVudGApIHRvIHRoZWlyIGFjdHVhbCBwcm9wcyB0eXBlIChgS3ViZURlcGxveW1lbnRQcm9wc2ApIGluXG4gICAgLy8gb3JkZXIgdG8gYXZvaWQgY29uZnVzaW9uIGJldHdlZW4gY29uc3RydWN0cyAoYEt1YmVEZXBsb3ltZW50YCkgYW5kIHRob3NlXG4gICAgLy8gdHlwZXMuIFRoaXMgaXMgZG9uZSBieSBzaW1wbHkgcmVwbGFjaW5nIHRoZWlyIGRlZmluaXRpb24gaW4gdGhlIHNjaGVtYVxuICAgIC8vIHdpdGggYSAkcmVmIHRvIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBwcm9wcyB0eXBlLlxuICAgIGZvciAoY29uc3QgbyBvZiB0b3BMZXZlbE9iamVjdHMpIHtcbiAgICAgIHR5cGVHZW5lcmF0b3IuYWRkRGVmaW5pdGlvbihvLmZxbiwgeyAkcmVmOiBgIy9kZWZpbml0aW9ucy8ke2dldFByb3BzVHlwZU5hbWUobyl9YCB9KTtcbiAgICB9XG5cbiAgICAvLyBlbWl0IGNvbnN0cnVjdCB0eXBlcyAocmVjdXJzaXZlKVxuICAgIGZvciAoY29uc3QgbyBvZiB0b3BMZXZlbE9iamVjdHMpIHtcbiAgICAgIGdlbmVyYXRlQ29uc3RydWN0KHR5cGVHZW5lcmF0b3IsIG8pO1xuICAgIH1cblxuICAgIGVtaXRIZWFkZXIoY29kZSwgZmFsc2UpO1xuXG4gICAgY29kZS5saW5lKHR5cGVHZW5lcmF0b3IucmVuZGVyKCkpO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBhIG1hcCBvZiBhbGwgQVBJIG9iamVjdHMgaW4gdGhlIHNwZWMgKG9iamVjdHMgdGhhdCBoYXZlIHRoZVxuICogJ3gta3ViZXJuZXRlcy1ncm91cC12ZXJzaW9uLWtpbmQnIGFubm90YXRpb24pLlxuICpcbiAqIFRoZSBrZXkgaXMgdGhlIGJhc2UgbmFtZSBvZiB0aGUgdHlwZSAoaS5lLiBgRGVwbG95bWVudGApLiBTaW5jZSBBUEkgb2JqZWN0c1xuICogbWF5IGhhdmUgbXVsdGlwbGUgdmVyc2lvbnMsIGVhY2ggdmFsdWUgaW4gdGhlIG1hcCBpcyBhbiBhcnJheSBvZiB0eXBlIGRlZmluaXRpb25zXG4gKiBhbG9uZyB3aXRoIHZlcnNpb24gaW5mb3JtYXRpb24uXG4gKlxuICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9jb25jZXB0cy9vdmVydmlldy9rdWJlcm5ldGVzLWFwaS8jYXBpLXZlcnNpb25pbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRBcGlPYmplY3REZWZpbml0aW9ucyhzY2hlbWE6IEpTT05TY2hlbWE0LCBwcmVmaXg6IHN0cmluZyk6IEFwaU9iamVjdERlZmluaXRpb25bXSB7XG4gIGNvbnN0IHJlc3VsdCA9IG5ldyBBcnJheTxBcGlPYmplY3REZWZpbml0aW9uPigpO1xuXG4gIGZvciAoY29uc3QgW3R5cGVuYW1lLCBhcGlzY2hlbWFdIG9mIE9iamVjdC5lbnRyaWVzKHNjaGVtYS5kZWZpbml0aW9ucyB8fCB7IH0pKSB7XG4gICAgY29uc3Qgb2JqZWN0TmFtZSA9IHRyeUdldE9iamVjdE5hbWUoYXBpc2NoZW1hKTtcbiAgICBpZiAoIW9iamVjdE5hbWUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHR5cGUgPSBwYXJzZUFwaVR5cGVOYW1lKHR5cGVuYW1lKTtcbiAgICBpZiAoIXR5cGUudmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gcGFyc2UgdmVyc2lvbiBmb3IgdHlwZTogJHt0eXBlbmFtZX1gKTtcbiAgICB9XG4gICAgcmVzdWx0LnB1c2goe1xuICAgICAgY3VzdG9tOiBmYWxzZSwgLy8gbm90IGEgQ1JEXG4gICAgICBmcW46IHR5cGUuZnVsbG5hbWUsXG4gICAgICBncm91cDogb2JqZWN0TmFtZS5ncm91cCxcbiAgICAgIGtpbmQ6IG9iamVjdE5hbWUua2luZCxcbiAgICAgIHZlcnNpb246IG9iamVjdE5hbWUudmVyc2lvbixcbiAgICAgIHNjaGVtYTogYXBpc2NoZW1hLFxuICAgICAgcHJlZml4LFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gdHJ5R2V0T2JqZWN0TmFtZShkZWY6IEpTT05TY2hlbWE0KTogR3JvdXBWZXJzaW9uS2luZCB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IG9iamVjdE5hbWVzID0gZGVmW1hfR1JPVVBfVkVSU0lPTl9LSU5EXSBhcyBHcm91cFZlcnNpb25LaW5kW107XG4gIGlmICghb2JqZWN0TmFtZXMpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3Qgb2JqZWN0TmFtZSA9IG9iamVjdE5hbWVzWzBdO1xuICBpZiAoIW9iamVjdE5hbWUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gc2tpcCBkZWZpbml0aW9ucyB3aXRob3V0IFwibWV0YWRhdGFcIi4gdGhleSBhcmUgbm90IEFQSSBvYmplY3RzIHRoYXQgY2FuIGJlIGRlZmluZWRcbiAgLy8gaW4gbWFuaWZlc3RzIChleGFtcGxlOiBpby5rOHMuYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuRGVsZXRlT3B0aW9ucylcbiAgLy8gdGhleSB3aWxsIGJlIHRyZWF0ZWQgYXMgZGF0YSB0eXBlc1xuICBpZiAoIWRlZi5wcm9wZXJ0aWVzPy5tZXRhZGF0YSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gb2JqZWN0TmFtZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHcm91cFZlcnNpb25LaW5kIHtcbiAgcmVhZG9ubHkgZ3JvdXA6IHN0cmluZztcbiAgcmVhZG9ubHkga2luZDogc3RyaW5nO1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG59XG5cbmNvbnN0IFhfR1JPVVBfVkVSU0lPTl9LSU5EID0gJ3gta3ViZXJuZXRlcy1ncm91cC12ZXJzaW9uLWtpbmQnO1xuXG5hc3luYyBmdW5jdGlvbiBkb3dubG9hZFNjaGVtYShhcGlWZXJzaW9uOiBzdHJpbmcpIHtcbiAgY29uc3QgdXJsID0gYGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9jZGs4cy10ZWFtL2NkazhzL21hc3Rlci9rdWJlcm5ldGVzLXNjaGVtYXMvdiR7YXBpVmVyc2lvbn0vX2RlZmluaXRpb25zLmpzb25gO1xuICBsZXQgb3V0cHV0O1xuICB0cnkge1xuICAgIG91dHB1dCA9IGF3YWl0IGRvd25sb2FkKHVybCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKGBDb3VsZCBub3QgZmluZCBhIHNjaGVtYSBmb3IgazhzIHZlcnNpb24gJHthcGlWZXJzaW9ufS4gVGhlIGN1cnJlbnQgbGlzdCBvZiBhdmFpbGFibGUgc2NoZW1hcyBpcyBhdCBodHRwczovL2dpdGh1Yi5jb20vY2RrOHMtdGVhbS9jZGs4cy90cmVlL21hc3Rlci9rdWJlcm5ldGVzLXNjaGVtYXMuYCk7XG4gICAgdGhyb3cgZTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBzYWZlUGFyc2VKc29uU2NoZW1hKG91dHB1dCkgYXMgSlNPTlNjaGVtYTQ7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBwYXJzZSBzY2hlbWEgYXQgJHt1cmx9OiAke2V9YCk7XG4gIH1cbn1cbiJdfQ==
;