UNPKG

cdk8s-cli

Version:

This is the command line tool for Cloud Development Kit (CDK) for Kubernetes (cdk8s).

140 lines • 18.8 kB
"use strict"; 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) { const { source } = importSpec; if (source !== 'k8s' && !source.startsWith('k8s@')) { return undefined; } let k8sVersion = source.split('@')[1] ?? 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) { 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 = options.classNamePrefix ?? 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) { 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 (!def.properties?.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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiazhzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ltcG9ydC9rOHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBTUEseUNBQTBDO0FBQzFDLGlDQUFxRDtBQUNyRCx1Q0FBOEc7QUFDOUcseUNBQW1FO0FBRW5FLGtDQUFtQztBQUd0QixRQUFBLG1CQUFtQixHQUFHLFFBQVEsQ0FBQztBQUU1QyxNQUFNLHlCQUF5QixHQUFHLE1BQU0sQ0FBQztBQWdCekMsTUFBYSxtQkFBb0IsU0FBUSxpQkFBVTtJQUUxQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxVQUFzQixFQUFFLElBQVM7UUFDekQsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLFVBQVUsQ0FBQztRQUM5QixJQUFJLE1BQU0sS0FBSyxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ2xELE9BQU8sU0FBUyxDQUFDO1NBQ2xCO1FBRUQsSUFBSSxVQUFVLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSwyQkFBbUIsQ0FBQztRQUU3RCxNQUFNLGVBQWUsR0FBRyxpQkFBaUIsQ0FBQztRQUMxQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUNyQyxNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixVQUFVLDhDQUE4QyxDQUFDLENBQUM7U0FDcEc7UUFFRCxPQUFPLENBQUMsS0FBSyxDQUFDLGtCQUFrQixVQUFVLEtBQUssQ0FBQyxDQUFDO1FBRWpELE9BQU87WUFDTCxVQUFVLEVBQUUsVUFBVTtZQUN0QixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87U0FDdEIsQ0FBQztJQUNKLENBQUM7SUFFRCxZQUE2QixPQUFtQztRQUM5RCxLQUFLLEVBQUUsQ0FBQztRQURtQixZQUFPLEdBQVAsT0FBTyxDQUE0QjtJQUVoRSxDQUFDO0lB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QUFJLEtBQUssQ0FBQyw2QkFBNkIsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7S0FDM0Q7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29kZU1ha2VyIH0gZnJvbSAnY29kZW1ha2VyJztcblxuLy8gd2UganVzdCBuZWVkIHRoZSB0eXBlcyBmcm9tIGpzb24tc2NoZW1hXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyBKU09OU2NoZW1hNCB9IGZyb20gJ2pzb24tc2NoZW1hJztcblxuaW1wb3J0IHsgVHlwZUdlbmVyYXRvciB9IGZyb20gJ2pzb24yanNpaSc7XG5pbXBvcnQgeyBHZW5lcmF0ZU9wdGlvbnMsIEltcG9ydEJhc2UgfSBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IHsgQXBpT2JqZWN0RGVmaW5pdGlvbiwgZW1pdEhlYWRlciwgZ2VuZXJhdGVDb25zdHJ1Y3QsIGdldFByb3BzVHlwZU5hbWUsIGdldFR5cGVOYW1lIH0gZnJvbSAnLi9jb2RlZ2VuJztcbmltcG9ydCB7IHBhcnNlQXBpVHlwZU5hbWUsIHNhZmVQYXJzZUpzb25TY2hlbWEgfSBmcm9tICcuL2s4cy11dGlsJztcbmltcG9ydCB7IEltcG9ydFNwZWMgfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0IHsgZG93bmxvYWQgfSBmcm9tICcuLi91dGlsJztcblxuXG5leHBvcnQgY29uc3QgREVGQVVMVF9BUElfVkVSU0lPTiA9ICcxLjI1LjAnO1xuXG5jb25zdCBERUZBVUxUX0NMQVNTX05BTUVfUFJFRklYID0gJ0t1YmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEltcG9ydEt1YmVybmV0ZXNBcGlPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBBUEkgdmVyc2lvbiB0byBnZW5lcmF0ZS5cbiAgICovXG4gIHJlYWRvbmx5IGFwaVZlcnNpb246IHN0cmluZztcblxuICAvKipcbiAgICogRG8gbm90IGltcG9ydCB0aGVzZSB0eXBlcy4gSW5zdGVhZCwgcmVwcmVzZW50IHRoZW0gYXMgXCJhbnlcIi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBpbmNsdWRlIGFsbCB0eXBlcyB0aGF0IGRlcml2ZSBmcm9tIHRoZSByb290IHR5cGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgZXhjbHVkZT86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY2xhc3MgSW1wb3J0S3ViZXJuZXRlc0FwaSBleHRlbmRzIEltcG9ydEJhc2Uge1xuXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgbWF0Y2goaW1wb3J0U3BlYzogSW1wb3J0U3BlYywgYXJndjogYW55KTogUHJvbWlzZTxJbXBvcnRLdWJlcm5ldGVzQXBpT3B0aW9ucyB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHsgc291cmNlIH0gPSBpbXBvcnRTcGVjO1xuICAgIGlmIChzb3VyY2UgIT09ICdrOHMnICYmICFzb3VyY2Uuc3RhcnRzV2l0aCgnazhzQCcpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGxldCBrOHNWZXJzaW9uID0gc291cmNlLnNwbGl0KCdAJylbMV0gPz8gREVGQVVMVF9BUElfVkVSU0lPTjtcblxuICAgIGNvbnN0IGs4c1ZlcnNpb25SZWdleCA9IC9eXFxkK1xcLlxcZCtcXC5cXGQrJC87XG4gICAgaWYgKCFrOHNWZXJzaW9uUmVnZXgudGVzdChrOHNWZXJzaW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBrOHMgdmVyc2lvbiBcIiR7azhzVmVyc2lvbn1cIiB0byBtYXRjaCBmb3JtYXQgXCI8bWFqb3I+LjxtaW5vcj4uPHBhdGNoPlwiLmApO1xuICAgIH1cblxuICAgIGNvbnNvbGUuZXJyb3IoYEltcG9ydGluZyBrOHMgdiR7azhzVmVyc2lvbn0uLi5gKTtcblxuICAgIHJldHVybiB7XG4gICAgICBhcGlWZXJzaW9uOiBrOHNWZXJzaW9uLFxuICAgICAgZXhjbHVkZTogYXJndi5leGNsdWRlLFxuICAgIH07XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IEltcG9ydEt1YmVybmV0ZXNBcGlPcHRpb25zKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgbW9kdWxlTmFtZXMoKSB7XG4gICAgcmV0dXJuIFsnazhzJ107XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2VuZXJhdGVUeXBlU2NyaXB0KGNvZGU6IENvZGVNYWtlciwgbW9kdWxlTmFtZTogc3RyaW5nLCBvcHRpb25zOiBHZW5lcmF0ZU9wdGlvbnMpIHtcbiAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCBkb3dubG9hZFNjaGVtYSh0aGlzLm9wdGlvbnMuYXBpVmVyc2lvbik7XG5cbiAgICBpZiAobW9kdWxlTmFtZSAhPT0gJ2s4cycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdW5leHBlY3RlZCBtb2R1bGUgbmFtZSBcIiR7bW9kdWxlTmFtZX1cIiB3aGVuIGltcG9ydGluZyBrOHMgdHlwZXMgKGV4cGVjdGVkIFwiazhzXCIpYCk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJlZml4ID0gb3B0aW9ucy5jbGFzc05hbWVQcmVmaXggPz8gREVGQVVMVF9DTEFTU19OQU1FX1BSRUZJWDtcbiAgICBjb25zdCB0b3BMZXZlbE9iamVjdHMgPSBmaW5kQXBpT2JqZWN0RGVmaW5pdGlvbnMoc2NoZW1hLCBwcmVmaXgpO1xuXG4gICAgY29uc3QgdHlwZUdlbmVyYXRvciA9IG5ldyBUeXBlR2VuZXJhdG9yKHtcbiAgICAgIGRlZmluaXRpb25zOiBzY2hlbWEuZGVmaW5pdGlvbnMsXG4gICAgICBleGNsdWRlOiB0aGlzLm9wdGlvbnMuZXhjbHVkZSxcbiAgICAgIHJlbmRlclR5cGVOYW1lOiAoZGVmOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gcGFyc2VBcGlUeXBlTmFtZShkZWYpO1xuICAgICAgICBpZiAoIXBhcnNlZC52ZXJzaW9uKSB7XG4gICAgICAgICAgLy8gbm90IGEgdmVyc2lvbmVkIGFwaSB0eXBlLiByZXR1cm4gYmFzZW5hbWVcbiAgICAgICAgICByZXR1cm4gcGFyc2VkLmJhc2VuYW1lO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnZXRUeXBlTmFtZShmYWxzZSwgcGFyc2VkLmJhc2VuYW1lLCBwYXJzZWQudmVyc2lvbi5yYXcpO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIHJlbmFtZSBcIlByb3BzXCIgdHlwZSBmcm9tIHRoZWlyIG9yaWdpbmFsIG5hbWUgYmFzZWQgb24gdGhlIEFQSSBvYmplY3Qga2luZFxuICAgIC8vIChlLmcuIGBEZXBsb3ltZW50YCkgdG8gdGhlaXIgYWN0dWFsIHByb3BzIHR5cGUgKGBLdWJlRGVwbG95bWVudFByb3BzYCkgaW5cbiAgICAvLyBvcmRlciB0byBhdm9pZCBjb25mdXNpb24gYmV0d2VlbiBjb25zdHJ1Y3RzIChgS3ViZURlcGxveW1lbnRgKSBhbmQgdGhvc2VcbiAgICAvLyB0eXBlcy4gVGhpcyBpcyBkb25lIGJ5IHNpbXBseSByZXBsYWNpbmcgdGhlaXIgZGVmaW5pdGlvbiBpbiB0aGUgc2NoZW1hXG4gICAgLy8gd2l0aCBhICRyZWYgdG8gdGhlIGRlZmluaXRpb24gb2YgdGhlIHByb3BzIHR5cGUuXG4gICAgZm9yIChjb25zdCBvIG9mIHRvcExldmVsT2JqZWN0cykge1xuICAgICAgdHlwZUdlbmVyYXRvci5hZGREZWZpbml0aW9uKG8uZnFuLCB7ICRyZWY6IGAjL2RlZmluaXRpb25zLyR7Z2V0UHJvcHNUeXBlTmFtZShvKX1gIH0pO1xuICAgIH1cblxuICAgIC8vIGVtaXQgY29uc3RydWN0IHR5cGVzIChyZWN1cnNpdmUpXG4gICAgZm9yIChjb25zdCBvIG9mIHRvcExldmVsT2JqZWN0cykge1xuICAgICAgZ2VuZXJhdGVDb25zdHJ1Y3QodHlwZUdlbmVyYXRvciwgbyk7XG4gICAgfVxuXG4gICAgZW1pdEhlYWRlcihjb2RlLCBmYWxzZSk7XG5cbiAgICBjb2RlLmxpbmUodHlwZUdlbmVyYXRvci5yZW5kZXIoKSk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbWFwIG9mIGFsbCBBUEkgb2JqZWN0cyBpbiB0aGUgc3BlYyAob2JqZWN0cyB0aGF0IGhhdmUgdGhlXG4gKiAneC1rdWJlcm5ldGVzLWdyb3VwLXZlcnNpb24ta2luZCcgYW5ub3RhdGlvbikuXG4gKlxuICogVGhlIGtleSBpcyB0aGUgYmFzZSBuYW1lIG9mIHRoZSB0eXBlIChpLmUuIGBEZXBsb3ltZW50YCkuIFNpbmNlIEFQSSBvYmplY3RzXG4gKiBtYXkgaGF2ZSBtdWx0aXBsZSB2ZXJzaW9ucywgZWFjaCB2YWx1ZSBpbiB0aGUgbWFwIGlzIGFuIGFycmF5IG9mIHR5cGUgZGVmaW5pdGlvbnNcbiAqIGFsb25nIHdpdGggdmVyc2lvbiBpbmZvcm1hdGlvbi5cbiAqXG4gKiBAc2VlIGh0dHBzOi8va3ViZXJuZXRlcy5pby9kb2NzL2NvbmNlcHRzL292ZXJ2aWV3L2t1YmVybmV0ZXMtYXBpLyNhcGktdmVyc2lvbmluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZEFwaU9iamVjdERlZmluaXRpb25zKHNjaGVtYTogSlNPTlNjaGVtYTQsIHByZWZpeDogc3RyaW5nKTogQXBpT2JqZWN0RGVmaW5pdGlvbltdIHtcbiAgY29uc3QgcmVzdWx0ID0gbmV3IEFycmF5PEFwaU9iamVjdERlZmluaXRpb24+KCk7XG5cbiAgZm9yIChjb25zdCBbdHlwZW5hbWUsIGFwaXNjaGVtYV0gb2YgT2JqZWN0LmVudHJpZXMoc2NoZW1hLmRlZmluaXRpb25zIHx8IHsgfSkpIHtcbiAgICBjb25zdCBvYmplY3ROYW1lID0gdHJ5R2V0T2JqZWN0TmFtZShhcGlzY2hlbWEpO1xuICAgIGlmICghb2JqZWN0TmFtZSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgdHlwZSA9IHBhcnNlQXBpVHlwZU5hbWUodHlwZW5hbWUpO1xuICAgIGlmICghdHlwZS52ZXJzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBwYXJzZSB2ZXJzaW9uIGZvciB0eXBlOiAke3R5cGVuYW1lfWApO1xuICAgIH1cbiAgICByZXN1bHQucHVzaCh7XG4gICAgICBjdXN0b206IGZhbHNlLCAvLyBub3QgYSBDUkRcbiAgICAgIGZxbjogdHlwZS5mdWxsbmFtZSxcbiAgICAgIGdyb3VwOiBvYmplY3ROYW1lLmdyb3VwLFxuICAgICAga2luZDogb2JqZWN0TmFtZS5raW5kLFxuICAgICAgdmVyc2lvbjogb2JqZWN0TmFtZS52ZXJzaW9uLFxuICAgICAgc2NoZW1hOiBhcGlzY2hlbWEsXG4gICAgICBwcmVmaXgsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiB0cnlHZXRPYmplY3ROYW1lKGRlZjogSlNPTlNjaGVtYTQpOiBHcm91cFZlcnNpb25LaW5kIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgb2JqZWN0TmFtZXMgPSBkZWZbWF9HUk9VUF9WRVJTSU9OX0tJTkRdIGFzIEdyb3VwVmVyc2lvbktpbmRbXTtcbiAgaWYgKCFvYmplY3ROYW1lcykge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBvYmplY3ROYW1lID0gb2JqZWN0TmFtZXNbMF07XG4gIGlmICghb2JqZWN0TmFtZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvLyBza2lwIGRlZmluaXRpb25zIHdpdGhvdXQgXCJtZXRhZGF0YVwiLiB0aGV5IGFyZSBub3QgQVBJIG9iamVjdHMgdGhhdCBjYW4gYmUgZGVmaW5lZFxuICAvLyBpbiBtYW5pZmVzdHMgKGV4YW1wbGU6IGlvLms4cy5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5EZWxldGVPcHRpb25zKVxuICAvLyB0aGV5IHdpbGwgYmUgdHJlYXRlZCBhcyBkYXRhIHR5cGVzXG4gIGlmICghZGVmLnByb3BlcnRpZXM/Lm1ldGFkYXRhKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBvYmplY3ROYW1lO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdyb3VwVmVyc2lvbktpbmQge1xuICByZWFkb25seSBncm91cDogc3RyaW5nO1xuICByZWFkb25seSBraW5kOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZztcbn1cblxuY29uc3QgWF9HUk9VUF9WRVJTSU9OX0tJTkQgPSAneC1rdWJlcm5ldGVzLWdyb3VwLXZlcnNpb24ta2luZCc7XG5cbmFzeW5jIGZ1bmN0aW9uIGRvd25sb2FkU2NoZW1hKGFwaVZlcnNpb246IHN0cmluZykge1xuICBjb25zdCB1cmwgPSBgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2NkazhzLXRlYW0vY2RrOHMvbWFzdGVyL2t1YmVybmV0ZXMtc2NoZW1hcy92JHthcGlWZXJzaW9ufS9fZGVmaW5pdGlvbnMuanNvbmA7XG4gIGxldCBvdXRwdXQ7XG4gIHRyeSB7XG4gICAgb3V0cHV0ID0gYXdhaXQgZG93bmxvYWQodXJsKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYENvdWxkIG5vdCBmaW5kIGEgc2NoZW1hIGZvciBrOHMgdmVyc2lvbiAke2FwaVZlcnNpb259LiBUaGUgY3VycmVudCBsaXN0IG9mIGF2YWlsYWJsZSBzY2hlbWFzIGlzIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9jZGs4cy10ZWFtL2NkazhzL3RyZWUvbWFzdGVyL2t1YmVybmV0ZXMtc2NoZW1hcy5gKTtcbiAgICB0aHJvdyBlO1xuICB9XG4gIHRyeSB7XG4gICAgcmV0dXJuIHNhZmVQYXJzZUpzb25TY2hlbWEob3V0cHV0KSBhcyBKU09OU2NoZW1hNDtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHBhcnNlIHNjaGVtYSBhdCAke3VybH06ICR7ZX1gKTtcbiAgfVxufVxuIl19