UNPKG

cdk8s-plus-29

Version:

cdk8s+ is a software development framework that provides high level abstractions for authoring Kubernetes applications. cdk8s-plus-29 synthesizes Kubernetes manifests for Kubernetes 1.29.0

182 lines 30.2 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.Service = exports.ServiceType = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const cdk8s_1 = require("cdk8s"); const base = require("./base"); const k8s = require("./imports/k8s"); const ingress = require("./ingress"); /** * For some parts of your application (for example, frontends) you may want to expose a Service onto an * external IP address, that's outside of your cluster. * Kubernetes ServiceTypes allow you to specify what kind of Service you want. * The default is ClusterIP. */ var ServiceType; (function (ServiceType) { /** * Exposes the Service on a cluster-internal IP. * Choosing this value makes the Service only reachable from within the cluster. * This is the default ServiceType */ ServiceType["CLUSTER_IP"] = "ClusterIP"; /** * Exposes the Service on each Node's IP at a static port (the NodePort). * A ClusterIP Service, to which the NodePort Service routes, is automatically created. * You'll be able to contact the NodePort Service, from outside the cluster, * by requesting <NodeIP>:<NodePort>. */ ServiceType["NODE_PORT"] = "NodePort"; /** * Exposes the Service externally using a cloud provider's load balancer. * NodePort and ClusterIP Services, to which the external load balancer routes, * are automatically created. */ ServiceType["LOAD_BALANCER"] = "LoadBalancer"; /** * Maps the Service to the contents of the externalName field (e.g. foo.bar.example.com), by returning a CNAME record with its value. * No proxying of any kind is set up. * * > Note: You need either kube-dns version 1.7 or CoreDNS version 0.0.8 or higher to use the ExternalName type. */ ServiceType["EXTERNAL_NAME"] = "ExternalName"; })(ServiceType || (exports.ServiceType = ServiceType = {})); /** * An abstract way to expose an application running on a set of Pods as a network service. * With Kubernetes you don't need to modify your application to use an unfamiliar service discovery mechanism. * Kubernetes gives Pods their own IP addresses and a single DNS name for a set of Pods, and can load-balance across them. * * For example, consider a stateless image-processing backend which is running with 3 replicas. Those replicas are fungible—frontends do not care which backend they use. * While the actual Pods that compose the backend set may change, the frontend clients should not need to be aware of that, * nor should they need to keep track of the set of backends themselves. * The Service abstraction enables this decoupling. * * If you're able to use Kubernetes APIs for service discovery in your application, you can query the API server for Endpoints, * that get updated whenever the set of Pods in a Service changes. For non-native applications, Kubernetes offers ways to place a network port * or load balancer in between your application and the backend Pods. */ class Service extends base.Resource { constructor(scope, id, props = {}) { super(scope, id); this.resourceType = 'services'; this.apiObject = new k8s.KubeService(this, 'Resource', { metadata: props.metadata, spec: cdk8s_1.Lazy.any({ produce: () => this._toKube() }), }); this.clusterIP = props.clusterIP; this.externalName = props.externalName; if (props.externalName !== undefined) { this.type = ServiceType.EXTERNAL_NAME; } else { this.type = props.type ?? ServiceType.CLUSTER_IP; } this._externalIPs = props.externalIPs ?? []; this._ports = []; this._selector = {}; this._loadBalancerSourceRanges = props.loadBalancerSourceRanges; this._publishNotReadyAddresses = props.publishNotReadyAddresses; if (props.selector) { this.select(props.selector); } for (const port of props.ports ?? []) { this.bind(port.port, port); } } /** * Expose a service via an ingress using the specified path. * * @param path The path to expose the service under. * @param options Additional options. * * @returns The `Ingress` resource that was used. */ exposeViaIngress(path, options = {}) { const ingr = options.ingress ?? new ingress.Ingress(this, 'Ingress'); ingr.addRule(path, ingress.IngressBackend.fromService(this), options.pathType); return ingr; } /** * Ports for this service. * * Use `bind()` to bind additional service ports. */ get ports() { return [...this._ports]; } /** * Return the first port of the service. */ get port() { return [...this._ports][0].port; } /** * Configure a port the service will bind to. * This method can be called multiple times. * * @param port The port definition. */ bind(port, options = {}) { this._ports.push({ ...options, port }); } /** * Require this service to select pods matching the selector. * * Note that invoking this method multiple times acts as an AND operator * on the resulting labels. */ select(selector) { const labels = selector.toPodSelectorConfig().labelSelector._toKube().matchLabels ?? {}; for (const [key, value] of Object.entries(labels)) { this._selector[key] = value; } } /** * Require this service to select pods with this label. * * Note that invoking this method multiple times acts as an AND operator * on the resulting labels. */ selectLabel(key, value) { this._selector[key] = value; } /** * @internal */ _toKube() { if (this._ports.length === 0 && this.type !== ServiceType.EXTERNAL_NAME) { throw new Error('A service must be configured with a port'); } if (this.type === ServiceType.EXTERNAL_NAME && this.externalName === undefined) { throw new Error('A service with type EXTERNAL_NAME requires an externalName prop'); } const ports = []; for (const port of this._ports) { ports.push({ name: port.name, port: port.port, targetPort: port.targetPort ? k8s.IntOrString.fromNumber(port.targetPort) : undefined, nodePort: port.nodePort, protocol: port.protocol, }); } return this.type !== ServiceType.EXTERNAL_NAME ? { clusterIp: this.clusterIP, externalIPs: this._externalIPs, externalName: this.externalName, type: this.type, selector: this._selector, ports: ports, loadBalancerSourceRanges: this._loadBalancerSourceRanges, publishNotReadyAddresses: this._publishNotReadyAddresses, } : { type: this.type, externalName: this.externalName, }; } } exports.Service = Service; _a = JSII_RTTI_SYMBOL_1; Service[_a] = { fqn: "cdk8s-plus-29.Service", version: "2.6.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsaUNBQXdDO0FBRXhDLCtCQUErQjtBQUUvQixxQ0FBcUM7QUFDckMscUNBQXFDO0FBMkhyQzs7Ozs7R0FLRztBQUNILElBQVksV0ErQlg7QUEvQkQsV0FBWSxXQUFXO0lBRXJCOzs7O09BSUc7SUFDSCx1Q0FBd0IsQ0FBQTtJQUV4Qjs7Ozs7T0FLRztJQUNILHFDQUFzQixDQUFBO0lBRXRCOzs7O09BSUc7SUFDSCw2Q0FBOEIsQ0FBQTtJQUU5Qjs7Ozs7T0FLRztJQUNILDZDQUE4QixDQUFBO0FBQ2hDLENBQUMsRUEvQlcsV0FBVywyQkFBWCxXQUFXLFFBK0J0QjtBQWNEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxNQUFhLE9BQVEsU0FBUSxJQUFJLENBQUMsUUFBUTtJQStCeEMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxRQUFzQixFQUFFO1FBQ2hFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFUSCxpQkFBWSxHQUFHLFVBQVUsQ0FBQztRQVd4QyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ3JELFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtZQUN4QixJQUFJLEVBQUUsWUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztTQUNsRCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDakMsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDO1FBRXZDLElBQUksS0FBSyxDQUFDLFlBQVksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNyQyxJ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S0gsMEJBb0tDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXBpT2JqZWN0LCBMYXp5IH0gZnJvbSAnY2RrOHMnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgKiBhcyBiYXNlIGZyb20gJy4vYmFzZSc7XG5pbXBvcnQgKiBhcyBjb250YWluZXIgZnJvbSAnLi9jb250YWluZXInO1xuaW1wb3J0ICogYXMgazhzIGZyb20gJy4vaW1wb3J0cy9rOHMnO1xuaW1wb3J0ICogYXMgaW5ncmVzcyBmcm9tICcuL2luZ3Jlc3MnO1xuaW1wb3J0ICogYXMgcG9kIGZyb20gJy4vcG9kJztcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBgU2VydmljZWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VydmljZVByb3BzIGV4dGVuZHMgYmFzZS5SZXNvdXJjZVByb3BzIHtcbiAgLyoqXG4gICAqIFdoaWNoIHBvZHMgc2hvdWxkIHRoZSBzZXJ2aWNlIHNlbGVjdCBhbmQgcm91dGUgdG8uXG4gICAqXG4gICAqIFlvdSBjYW4gcGFzcyBvbmUgb2YgdGhlIGZvbGxvd2luZzpcbiAgICpcbiAgICogLSBBbiBpbnN0YW5jZSBvZiBgUG9kYCBvciBhbnkgd29ya2xvYWQgcmVzb3VyY2UgKGUuZyBgRGVwbG95bWVudGAsIGBTdGF0ZWZ1bFNldGAsIC4uLilcbiAgICogLSBQb2RzIHNlbGVjdGVkIGJ5IHRoZSBgUG9kcy5zZWxlY3RgIGZ1bmN0aW9uLiBOb3RlIHRoYXQgaW4gdGhpcyBjYXNlIG9ubHkgbGFiZWxzIGNhbiBiZSBzcGVjaWZpZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdW5zZXQsIHRoZSBzZXJ2aWNlIGlzIGFzc3VtZWQgdG8gaGF2ZSBhbiBleHRlcm5hbCBwcm9jZXNzIG1hbmFnaW5nXG4gICAqIGl0cyBlbmRwb2ludHMsIHdoaWNoIEt1YmVybmV0ZXMgd2lsbCBub3QgbW9kaWZ5LlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiAvLyBzZWxlY3QgdGhlIHBvZHMgb2YgYSBzcGVjaWZpYyBkZXBsb3ltZW50XG4gICAqIGNvbnN0IGJhY2tlbmQgPSBuZXcga3BsdXMuRGVwbG95bWVudCh0aGlzLCAnQmFja2VuZCcsIC4uLik7XG4gICAqIG5ldyBrcGx1cy5TZXJ2aWNlKHRoaXMsICdTZXJ2aWNlJywgeyBzZWxlY3RvcjogYmFja2VuZCB9KTtcbiAgICpcbiAgICogLy8gc2VsZWN0IGFsbCBwb2RzIGxhYmVsZWQgd2l0aCB0aGUgYHRpZXI9YmFja2VuZGAgbGFiZWxcbiAgICogY29uc3QgYmFja2VuZCA9IGtwbHVzLlBvZC5sYWJlbGVkKHsgdGllcjogJ2JhY2tlbmQnIH0pO1xuICAgKiBuZXcga3BsdXMuU2VydmljZSh0aGlzLCAnU2VydmljZScsIHsgc2VsZWN0b3I6IGJhY2tlbmQgfSk7XG4gICAqL1xuICByZWFkb25seSBzZWxlY3Rvcj86IHBvZC5JUG9kU2VsZWN0b3I7XG5cbiAgLyoqXG4gICAqIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSBzZXJ2aWNlIGFuZCBpcyB1c3VhbGx5IGFzc2lnbmVkIHJhbmRvbWx5IGJ5IHRoZVxuICAgKiBtYXN0ZXIuIElmIGFuIGFkZHJlc3MgaXMgc3BlY2lmaWVkIG1hbnVhbGx5IGFuZCBpcyBub3QgaW4gdXNlIGJ5IG90aGVycywgaXRcbiAgICogd2lsbCBiZSBhbGxvY2F0ZWQgdG8gdGhlIHNlcnZpY2U7IG90aGVyd2lzZSwgY3JlYXRpb24gb2YgdGhlIHNlcnZpY2Ugd2lsbFxuICAgKiBmYWlsLiBUaGlzIGZpZWxkIGNhbiBub3QgYmUgY2hhbmdlZCB0aHJvdWdoIHVwZGF0ZXMuIFZhbGlkIHZhbHVlcyBhcmVcbiAgICogXCJOb25lXCIsIGVtcHR5IHN0cmluZyAoXCJcIiksIG9yIGEgdmFsaWQgSVAgYWRkcmVzcy4gXCJOb25lXCIgY2FuIGJlIHNwZWNpZmllZFxuICAgKiBmb3IgaGVhZGxlc3Mgc2VydmljZXMgd2hlbiBwcm94eWluZyBpcyBub3QgcmVxdWlyZWQuIE9ubHkgYXBwbGllcyB0byB0eXBlc1xuICAgKiBDbHVzdGVySVAsIE5vZGVQb3J0LCBhbmQgTG9hZEJhbGFuY2VyLiBJZ25vcmVkIGlmIHR5cGUgaXMgRXh0ZXJuYWxOYW1lLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8va3ViZXJuZXRlcy5pby9kb2NzL2NvbmNlcHRzL3NlcnZpY2VzLW5ldHdvcmtpbmcvc2VydmljZS8jdmlydHVhbC1pcHMtYW5kLXNlcnZpY2UtcHJveGllc1xuICAgKiBAZGVmYXVsdCAtIEF1dG9tYXRpY2FsbHkgYXNzaWduZWQuXG4gICAqXG4gICAqL1xuICByZWFkb25seSBjbHVzdGVySVA/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBJUCBhZGRyZXNzZXMgZm9yIHdoaWNoIG5vZGVzIGluIHRoZSBjbHVzdGVyIHdpbGwgYWxzbyBhY2NlcHRcbiAgICogdHJhZmZpYyBmb3IgdGhpcyBzZXJ2aWNlLiBUaGVzZSBJUHMgYXJlIG5vdCBtYW5hZ2VkIGJ5IEt1YmVybmV0ZXMuIFRoZSB1c2VyXG4gICAqIGlzIHJlc3BvbnNpYmxlIGZvciBlbnN1cmluZyB0aGF0IHRyYWZmaWMgYXJyaXZlcyBhdCBhIG5vZGUgd2l0aCB0aGlzIElQLiBBXG4gICAqIGNvbW1vbiBleGFtcGxlIGlzIGV4dGVybmFsIGxvYWQtYmFsYW5jZXJzIHRoYXQgYXJlIG5vdCBwYXJ0IG9mIHRoZVxuICAgKiBLdWJlcm5ldGVzIHN5c3RlbS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBleHRlcm5hbCBJUHMuXG4gICAqL1xuICByZWFkb25seSBleHRlcm5hbElQcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGhvdyB0aGUgU2VydmljZSBpcyBleHBvc2VkLlxuICAgKlxuICAgKiBNb3JlIGluZm86IGh0dHBzOi8va3ViZXJuZXRlcy5pby9kb2NzL2NvbmNlcHRzL3NlcnZpY2VzLW5ldHdvcmtpbmcvc2VydmljZS8jcHVibGlzaGluZy1zZXJ2aWNlcy1zZXJ2aWNlLXR5cGVzXG4gICAqXG4gICAqIEBkZWZhdWx0IFNlcnZpY2VUeXBlLkNsdXN0ZXJJUFxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZT86IFNlcnZpY2VUeXBlO1xuXG4gIC8qKlxuICAgKiBUaGUgcG9ydHMgdGhpcyBzZXJ2aWNlIGJpbmRzIHRvLlxuICAgKlxuICAgKiBJZiB0aGUgc2VsZWN0b3Igb2YgdGhlIHNlcnZpY2UgaXMgYSBtYW5hZ2VkIHBvZCAvIHdvcmtsb2FkLFxuICAgKiBpdHMgcG9ydHMgd2lsbCBhcmUgYXV0b21hdGljYWxseSBleHRyYWN0ZWQgYW5kIHVzZWQgYXMgdGhlIGRlZmF1bHQgdmFsdWUuXG4gICAqIE90aGVyd2lzZSwgbm8gcG9ydHMgYXJlIGJvdW5kLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGVpdGhlciB0aGUgc2VsZWN0b3IgcG9ydHMsIG9yIG5vbmUuXG4gICAqL1xuICByZWFkb25seSBwb3J0cz86IFNlcnZpY2VQb3J0W107XG5cbiAgLyoqXG4gICAqIFRoZSBleHRlcm5hbE5hbWUgdG8gYmUgdXNlZCB3aGVuIFNlcnZpY2VUeXBlLkVYVEVSTkFMX05BTUUgaXMgc2V0XG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZXh0ZXJuYWwgbmFtZS5cbiAgICovXG4gIHJlYWRvbmx5IGV4dGVybmFsTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogQSBsaXN0IG9mIENJRFIgSVAgYWRkcmVzc2VzLCBpZiBzcGVjaWZpZWQgYW5kIHN1cHBvcnRlZCBieSB0aGUgcGxhdGZvcm0sXG4gICAqIHdpbGwgcmVzdHJpY3QgdHJhZmZpYyB0aHJvdWdoIHRoZSBjbG91ZC1wcm92aWRlciBsb2FkLWJhbGFuY2VyIHRvIHRoZSBzcGVjaWZpZWQgY2xpZW50IElQcy5cbiAgICpcbiAgICogTW9yZSBpbmZvOiBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy90YXNrcy9hY2Nlc3MtYXBwbGljYXRpb24tY2x1c3Rlci9jb25maWd1cmUtY2xvdWQtcHJvdmlkZXItZmlyZXdhbGwvXG4gICAqL1xuICByZWFkb25seSBsb2FkQmFsYW5jZXJTb3VyY2VSYW5nZXM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIHB1Ymxpc2hOb3RSZWFkeUFkZHJlc3NlcyBpbmRpY2F0ZXMgdGhhdCBhbnkgYWdlbnQgd2hpY2ggZGVhbHMgd2l0aCBlbmRwb2ludHMgZm9yIHRoaXMgU2VydmljZVxuICAgKiBzaG91bGQgZGlzcmVnYXJkIGFueSBpbmRpY2F0aW9ucyBvZiByZWFkeS9ub3QtcmVhZHlcbiAgICpcbiAgICogTW9yZSBpbmZvOiBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9yZWZlcmVuY2UvZ2VuZXJhdGVkL2t1YmVybmV0ZXMtYXBpL3YxLjMwLyNzZXJ2aWNlc3BlYy12MS1jb3JlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHB1Ymxpc2hOb3RSZWFkeUFkZHJlc3Nlcz86IGJvb2xlYW47XG5cbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBleHBvc2luZyBhIHNlcnZpY2UgdXNpbmcgYW4gaW5ncmVzcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFeHBvc2VTZXJ2aWNlVmlhSW5ncmVzc09wdGlvbnMge1xuXG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiB0aGUgcGF0aFxuICAgKlxuICAgKiBAZGVmYXVsdCBIdHRwSW5ncmVzc1BhdGhUeXBlLlBSRUZJWFxuICAgKi9cbiAgcmVhZG9ubHkgcGF0aFR5cGU/OiBpbmdyZXNzLkh0dHBJbmdyZXNzUGF0aFR5cGU7XG5cbiAgLyoqXG4gICAqIFRoZSBpbmdyZXNzIHRvIGFkZCBydWxlcyB0by5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBBbiBpbmdyZXNzIHdpbGwgYmUgYXV0b21hdGljYWxseSBjcmVhdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5ncmVzcz86IGluZ3Jlc3MuSW5ncmVzcztcbn1cblxuLyoqXG4gKiBGb3Igc29tZSBwYXJ0cyBvZiB5b3VyIGFwcGxpY2F0aW9uIChmb3IgZXhhbXBsZSwgZnJvbnRlbmRzKSB5b3UgbWF5IHdhbnQgdG8gZXhwb3NlIGEgU2VydmljZSBvbnRvIGFuXG4gKiBleHRlcm5hbCBJUCBhZGRyZXNzLCB0aGF0J3Mgb3V0c2lkZSBvZiB5b3VyIGNsdXN0ZXIuXG4gKiBLdWJlcm5ldGVzIFNlcnZpY2VUeXBlcyBhbGxvdyB5b3UgdG8gc3BlY2lmeSB3aGF0IGtpbmQgb2YgU2VydmljZSB5b3Ugd2FudC5cbiAqIFRoZSBkZWZhdWx0IGlzIENsdXN0ZXJJUC5cbiAqL1xuZXhwb3J0IGVudW0gU2VydmljZVR5cGUge1xuXG4gIC8qKlxuICAgKiBFeHBvc2VzIHRoZSBTZXJ2aWNlIG9uIGEgY2x1c3Rlci1pbnRlcm5hbCBJUC5cbiAgICogQ2hvb3NpbmcgdGhpcyB2YWx1ZSBtYWtlcyB0aGUgU2VydmljZSBvbmx5IHJlYWNoYWJsZSBmcm9tIHdpdGhpbiB0aGUgY2x1c3Rlci5cbiAgICogVGhpcyBpcyB0aGUgZGVmYXVsdCBTZXJ2aWNlVHlwZVxuICAgKi9cbiAgQ0xVU1RFUl9JUCA9ICdDbHVzdGVySVAnLFxuXG4gIC8qKlxuICAgKiBFeHBvc2VzIHRoZSBTZXJ2aWNlIG9uIGVhY2ggTm9kZSdzIElQIGF0IGEgc3RhdGljIHBvcnQgKHRoZSBOb2RlUG9ydCkuXG4gICAqIEEgQ2x1c3RlcklQIFNlcnZpY2UsIHRvIHdoaWNoIHRoZSBOb2RlUG9ydCBTZXJ2aWNlIHJvdXRlcywgaXMgYXV0b21hdGljYWxseSBjcmVhdGVkLlxuICAgKiBZb3UnbGwgYmUgYWJsZSB0byBjb250YWN0IHRoZSBOb2RlUG9ydCBTZXJ2aWNlLCBmcm9tIG91dHNpZGUgdGhlIGNsdXN0ZXIsXG4gICAqIGJ5IHJlcXVlc3RpbmcgPE5vZGVJUD46PE5vZGVQb3J0Pi5cbiAgICovXG4gIE5PREVfUE9SVCA9ICdOb2RlUG9ydCcsXG5cbiAgLyoqXG4gICAqIEV4cG9zZXMgdGhlIFNlcnZpY2UgZXh0ZXJuYWxseSB1c2luZyBhIGNsb3VkIHByb3ZpZGVyJ3MgbG9hZCBiYWxhbmNlci5cbiAgICogTm9kZVBvcnQgYW5kIENsdXN0ZXJJUCBTZXJ2aWNlcywgdG8gd2hpY2ggdGhlIGV4dGVybmFsIGxvYWQgYmFsYW5jZXIgcm91dGVzLFxuICAgKiBhcmUgYXV0b21hdGljYWxseSBjcmVhdGVkLlxuICAgKi9cbiAgTE9BRF9CQUxBTkNFUiA9ICdMb2FkQmFsYW5jZXInLFxuXG4gIC8qKlxuICAgKiBNYXBzIHRoZSBTZXJ2aWNlIHRvIHRoZSBjb250ZW50cyBvZiB0aGUgZXh0ZXJuYWxOYW1lIGZpZWxkIChlLmcuIGZvby5iYXIuZXhhbXBsZS5jb20pLCBieSByZXR1cm5pbmcgYSBDTkFNRSByZWNvcmQgd2l0aCBpdHMgdmFsdWUuXG4gICAqIE5vIHByb3h5aW5nIG9mIGFueSBraW5kIGlzIHNldCB1cC5cbiAgICpcbiAgICogPiBOb3RlOiBZb3UgbmVlZCBlaXRoZXIga3ViZS1kbnMgdmVyc2lvbiAxLjcgb3IgQ29yZUROUyB2ZXJzaW9uIDAuMC44IG9yIGhpZ2hlciB0byB1c2UgdGhlIEV4dGVybmFsTmFtZSB0eXBlLlxuICAgKi9cbiAgRVhURVJOQUxfTkFNRSA9ICdFeHRlcm5hbE5hbWUnXG59XG5cbi8qKlxuICogT3B0aW9ucyB0byBhZGQgYSBkZXBsb3ltZW50IHRvIGEgc2VydmljZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBZGREZXBsb3ltZW50T3B0aW9ucyBleHRlbmRzIFNlcnZpY2VCaW5kT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgcG9ydCBudW1iZXIgdGhlIHNlcnZpY2Ugd2lsbCBiaW5kIHRvLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIENvcGllZCBmcm9tIHRoZSBmaXJzdCBjb250YWluZXIgb2YgdGhlIGRlcGxveW1lbnQuXG4gICAqL1xuICByZWFkb25seSBwb3J0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEFuIGFic3RyYWN0IHdheSB0byBleHBvc2UgYW4gYXBwbGljYXRpb24gcnVubmluZyBvbiBhIHNldCBvZiBQb2RzIGFzIGEgbmV0d29yayBzZXJ2aWNlLlxuICogV2l0aCBLdWJlcm5ldGVzIHlvdSBkb24ndCBuZWVkIHRvIG1vZGlmeSB5b3VyIGFwcGxpY2F0aW9uIHRvIHVzZSBhbiB1bmZhbWlsaWFyIHNlcnZpY2UgZGlzY292ZXJ5IG1lY2hhbmlzbS5cbiAqIEt1YmVybmV0ZXMgZ2l2ZXMgUG9kcyB0aGVpciBvd24gSVAgYWRkcmVzc2VzIGFuZCBhIHNpbmdsZSBETlMgbmFtZSBmb3IgYSBzZXQgb2YgUG9kcywgYW5kIGNhbiBsb2FkLWJhbGFuY2UgYWNyb3NzIHRoZW0uXG4gKlxuICogRm9yIGV4YW1wbGUsIGNvbnNpZGVyIGEgc3RhdGVsZXNzIGltYWdlLXByb2Nlc3NpbmcgYmFja2VuZCB3aGljaCBpcyBydW5uaW5nIHdpdGggMyByZXBsaWNhcy4gVGhvc2UgcmVwbGljYXMgYXJlIGZ1bmdpYmxl4oCUZnJvbnRlbmRzIGRvIG5vdCBjYXJlIHdoaWNoIGJhY2tlbmQgdGhleSB1c2UuXG4gKiBXaGlsZSB0aGUgYWN0dWFsIFBvZHMgdGhhdCBjb21wb3NlIHRoZSBiYWNrZW5kIHNldCBtYXkgY2hhbmdlLCB0aGUgZnJvbnRlbmQgY2xpZW50cyBzaG91bGQgbm90IG5lZWQgdG8gYmUgYXdhcmUgb2YgdGhhdCxcbiAqIG5vciBzaG91bGQgdGhleSBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIHNldCBvZiBiYWNrZW5kcyB0aGVtc2VsdmVzLlxuICogVGhlIFNlcnZpY2UgYWJzdHJhY3Rpb24gZW5hYmxlcyB0aGlzIGRlY291cGxpbmcuXG4gKlxuICogSWYgeW91J3JlIGFibGUgdG8gdXNlIEt1YmVybmV0ZXMgQVBJcyBmb3Igc2VydmljZSBkaXNjb3ZlcnkgaW4geW91ciBhcHBsaWNhdGlvbiwgeW91IGNhbiBxdWVyeSB0aGUgQVBJIHNlcnZlciBmb3IgRW5kcG9pbnRzLFxuICogdGhhdCBnZXQgdXBkYXRlZCB3aGVuZXZlciB0aGUgc2V0IG9mIFBvZHMgaW4gYSBTZXJ2aWNlIGNoYW5nZXMuIEZvciBub24tbmF0aXZlIGFwcGxpY2F0aW9ucywgS3ViZXJuZXRlcyBvZmZlcnMgd2F5cyB0byBwbGFjZSBhIG5ldHdvcmsgcG9ydFxuICogb3IgbG9hZCBiYWxhbmNlciBpbiBiZXR3ZWVuIHlvdXIgYXBwbGljYXRpb24gYW5kIHRoZSBiYWNrZW5kIFBvZHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXJ2aWNlIGV4dGVuZHMgYmFzZS5SZXNvdXJjZSB7XG5cbiAgLyoqXG4gICAqIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSBzZXJ2aWNlIGFuZCBpcyB1c3VhbGx5IGFzc2lnbmVkIHJhbmRvbWx5IGJ5IHRoZVxuICAgKiBtYXN0ZXIuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2x1c3RlcklQPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGhvdyB0aGUgU2VydmljZSBpcyBleHBvc2VkLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHR5cGU6IFNlcnZpY2VUeXBlO1xuXG4gIC8qKlxuICAgKiBUaGUgZXh0ZXJuYWxOYW1lIHRvIGJlIHVzZWQgZm9yIEVYVEVSTkFMX05BTUUgdHlwZXNcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBleHRlcm5hbE5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBzZWUgYmFzZS5SZXNvdXJjZS5hcGlPYmplY3RcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBhcGlPYmplY3Q6IEFwaU9iamVjdDtcblxuICBwdWJsaWMgcmVhZG9ubHkgcmVzb3VyY2VUeXBlID0gJ3NlcnZpY2VzJztcblxuICBwcml2YXRlIHJlYWRvbmx5IF9leHRlcm5hbElQczogc3RyaW5nW107XG4gIHByaXZhdGUgcmVhZG9ubHkgX3NlbGVjdG9yOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICBwcml2YXRlIHJlYWRvbmx5IF9wb3J0czogU2VydmljZVBvcnRbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBfbG9hZEJhbGFuY2VyU291cmNlUmFuZ2VzPzogc3RyaW5nW107XG4gIHByaXZhdGUgcmVhZG9ubHkgX3B1Ymxpc2hOb3RSZWFkeUFkZHJlc3Nlcz86IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFNlcnZpY2VQcm9wcyA9IHt9KSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIHRoaXMuYXBpT2JqZWN0ID0gbmV3IGs4cy5LdWJlU2VydmljZSh0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBtZXRhZGF0YTogcHJvcHMubWV0YWRhdGEsXG4gICAgICBzcGVjOiBMYXp5LmFueSh7IHByb2R1Y2U6ICgpID0+IHRoaXMuX3RvS3ViZSgpIH0pLFxuICAgIH0pO1xuXG4gICAgdGhpcy5jbHVzdGVySVAgPSBwcm9wcy5jbHVzdGVySVA7XG4gICAgdGhpcy5leHRlcm5hbE5hbWUgPSBwcm9wcy5leHRlcm5hbE5hbWU7XG5cbiAgICBpZiAocHJvcHMuZXh0ZXJuYWxOYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMudHlwZSA9IFNlcnZpY2VUeXBlLkVYVEVSTkFMX05BTUU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudHlwZSA9IHByb3BzLnR5cGUgPz8gU2VydmljZVR5cGUuQ0xVU1RFUl9JUDtcbiAgICB9XG5cbiAgICB0aGlzLl9leHRlcm5hbElQcyA9IHByb3BzLmV4dGVybmFsSVBzID8/IFtdO1xuICAgIHRoaXMuX3BvcnRzID0gW107XG4gICAgdGhpcy5fc2VsZWN0b3IgPSB7IH07XG4gICAgdGhpcy5fbG9hZEJhbGFuY2VyU291cmNlUmFuZ2VzID0gcHJvcHMubG9hZEJhbGFuY2VyU291cmNlUmFuZ2VzO1xuICAgIHRoaXMuX3B1Ymxpc2hOb3RSZWFkeUFkZHJlc3NlcyA9IHByb3BzLnB1Ymxpc2hOb3RSZWFkeUFkZHJlc3NlcztcblxuICAgIGlmIChwcm9wcy5zZWxlY3Rvcikge1xuICAgICAgdGhpcy5zZWxlY3QocHJvcHMuc2VsZWN0b3IpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcG9ydCBvZiBwcm9wcy5wb3J0cyA/PyBbXSkge1xuICAgICAgdGhpcy5iaW5kKHBvcnQucG9ydCwgcG9ydCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV4cG9zZSBhIHNlcnZpY2UgdmlhIGFuIGluZ3Jlc3MgdXNpbmcgdGhlIHNwZWNpZmllZCBwYXRoLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCBUaGUgcGF0aCB0byBleHBvc2UgdGhlIHNlcnZpY2UgdW5kZXIuXG4gICAqIEBwYXJhbSBvcHRpb25zIEFkZGl0aW9uYWwgb3B0aW9ucy5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGBJbmdyZXNzYCByZXNvdXJjZSB0aGF0IHdhcyB1c2VkLlxuICAgKi9cbiAgcHVibGljIGV4cG9zZVZpYUluZ3Jlc3MocGF0aDogc3RyaW5nLCBvcHRpb25zOiBFeHBvc2VTZXJ2aWNlVmlhSW5ncmVzc09wdGlvbnMgPSB7fSk6IGluZ3Jlc3MuSW5ncmVzcyB7XG4gICAgY29uc3QgaW5nciA9IG9wdGlvbnMuaW5ncmVzcyA/PyBuZXcgaW5ncmVzcy5JbmdyZXNzKHRoaXMsICdJbmdyZXNzJyk7XG4gICAgaW5nci5hZGRSdWxlKHBhdGgsIGluZ3Jlc3MuSW5ncmVzc0JhY2tlbmQuZnJvbVNlcnZpY2UodGhpcyksIG9wdGlvbnMucGF0aFR5cGUpO1xuICAgIHJldHVybiBpbmdyO1xuICB9XG5cbiAgLyoqXG4gICAqIFBvcnRzIGZvciB0aGlzIHNlcnZpY2UuXG4gICAqXG4gICAqIFVzZSBgYmluZCgpYCB0byBiaW5kIGFkZGl0aW9uYWwgc2VydmljZSBwb3J0cy5cbiAgICovXG4gIHB1YmxpYyBnZXQgcG9ydHMoKSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLl9wb3J0c107XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBmaXJzdCBwb3J0IG9mIHRoZSBzZXJ2aWNlLlxuICAgKi9cbiAgcHVibGljIGdldCBwb3J0KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIFsuLi50aGlzLl9wb3J0c11bMF0ucG9ydDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmUgYSBwb3J0IHRoZSBzZXJ2aWNlIHdpbGwgYmluZCB0by5cbiAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBtdWx0aXBsZSB0aW1lcy5cbiAgICpcbiAgICogQHBhcmFtIHBvcnQgVGhlIHBvcnQgZGVmaW5pdGlvbi5cbiAgICovXG4gIHB1YmxpYyBiaW5kKHBvcnQ6IG51bWJlciwgb3B0aW9uczogU2VydmljZUJpbmRPcHRpb25zID0geyB9KSB7XG4gICAgdGhpcy5fcG9ydHMucHVzaCh7IC4uLm9wdGlvbnMsIHBvcnQgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZSB0aGlzIHNlcnZpY2UgdG8gc2VsZWN0IHBvZHMgbWF0Y2hpbmcgdGhlIHNlbGVjdG9yLlxuICAgKlxuICAgKiBOb3RlIHRoYXQgaW52b2tpbmcgdGhpcyBtZXRob2QgbXVsdGlwbGUgdGltZXMgYWN0cyBhcyBhbiBBTkQgb3BlcmF0b3JcbiAgICogb24gdGhlIHJlc3VsdGluZyBsYWJlbHMuXG4gICAqL1xuICBwdWJsaWMgc2VsZWN0KHNlbGVjdG9yOiBwb2QuSVBvZFNlbGVjdG9yKSB7XG4gICAgY29uc3QgbGFiZWxzID0gc2VsZWN0b3IudG9Qb2RTZWxlY3RvckNvbmZpZygpLmxhYmVsU2VsZWN0b3IuX3RvS3ViZSgpLm1hdGNoTGFiZWxzID8/IHt9O1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGxhYmVscykpIHtcbiAgICAgIHRoaXMuX3NlbGVjdG9yW2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZSB0aGlzIHNlcnZpY2UgdG8gc2VsZWN0IHBvZHMgd2l0aCB0aGlzIGxhYmVsLlxuICAgKlxuICAgKiBOb3RlIHRoYXQgaW52b2tpbmcgdGhpcyBtZXRob2QgbXVsdGlwbGUgdGltZXMgYWN0cyBhcyBhbiBBTkQgb3BlcmF0b3JcbiAgICogb24gdGhlIHJlc3VsdGluZyBsYWJlbHMuXG4gICAqL1xuICBwdWJsaWMgc2VsZWN0TGFiZWwoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9zZWxlY3RvcltrZXldID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgX3RvS3ViZSgpOiBrOHMuU2VydmljZVNwZWMge1xuICAgIGlmICh0aGlzLl9wb3J0cy5sZW5ndGggPT09IDAgJiYgdGhpcy50eXBlICE9PSBTZXJ2aWNlVHlwZS5FWFRFUk5BTF9OQU1FKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Egc2VydmljZSBtdXN0IGJlIGNvbmZpZ3VyZWQgd2l0aCBhIHBvcnQnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy50eXBlID09PSBTZXJ2aWNlVHlwZS5FWFRFUk5BTF9OQU1FICYmIHRoaXMuZXh0ZXJuYWxOYW1lID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQSBzZXJ2aWNlIHdpdGggdHlwZSBFWFRFUk5BTF9OQU1FIHJlcXVpcmVzIGFuIGV4dGVybmFsTmFtZSBwcm9wJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcG9ydHM6IGs4cy5TZXJ2aWNlUG9ydFtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHBvcnQgb2YgdGhpcy5fcG9ydHMpIHtcbiAgICAgIHBvcnRzLnB1c2goe1xuICAgICAgICBuYW1lOiBwb3J0Lm5hbWUsXG4gICAgICAgIHBvcnQ6IHBvcnQucG9ydCxcbiAgICAgICAgdGFyZ2V0UG9ydDogcG9ydC50YXJnZXRQb3J0ID8gazhzLkludE9yU3RyaW5nLmZyb21OdW1iZXIocG9ydC50YXJnZXRQb3J0KSA6IHVuZGVmaW5lZCxcbiAgICAgICAgbm9kZVBvcnQ6IHBvcnQubm9kZVBvcnQsXG4gICAgICAgIHByb3RvY29sOiBwb3J0LnByb3RvY29sLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMudHlwZSAhPT0gU2VydmljZVR5cGUuRVhURVJOQUxfTkFNRSA/IHtcbiAgICAgIGNsdXN0ZXJJcDogdGhpcy5jbHVzdGVySVAsXG4gICAgICBleHRlcm5hbElQczogdGhpcy5fZXh0ZXJuYWxJUHMsXG4gICAgICBleHRlcm5hbE5hbWU6IHRoaXMuZXh0ZXJuYWxOYW1lLFxuICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgc2VsZWN0b3I6IHRoaXMuX3NlbGVjdG9yLFxuICAgICAgcG9ydHM6IHBvcnRzLFxuICAgICAgbG9hZEJhbGFuY2VyU291cmNlUmFuZ2VzOiB0aGlzLl9sb2FkQmFsYW5jZXJTb3VyY2VSYW5nZXMsXG4gICAgICBwdWJsaXNoTm90UmVhZHlBZGRyZXNzZXM6IHRoaXMuX3B1Ymxpc2hOb3RSZWFkeUFkZHJlc3NlcyxcbiAgICB9IDoge1xuICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgZXh0ZXJuYWxOYW1lOiB0aGlzLmV4dGVybmFsTmFtZSxcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYFNlcnZpY2UuYmluZGAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VydmljZUJpbmRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoaXMgcG9ydCB3aXRoaW4gdGhlIHNlcnZpY2UuIFRoaXMgbXVzdCBiZSBhIEROU19MQUJFTC4gQWxsXG4gICAqIHBvcnRzIHdpdGhpbiBhIFNlcnZpY2VTcGVjIG11c3QgaGF2ZSB1bmlxdWUgbmFtZXMuIFRoaXMgbWFwcyB0byB0aGUgJ05hbWUnXG4gICAqIGZpZWxkIGluIEVuZHBvaW50UG9ydCBvYmplY3RzLiBPcHRpb25hbCBpZiBvbmx5IG9uZSBTZXJ2aWNlUG9ydCBpcyBkZWZpbmVkXG4gICAqIG9uIHRoaXMgc2VydmljZS5cbiAgICovXG4gIHJlYWRvbmx5IG5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwb3J0IG9uIGVhY2ggbm9kZSBvbiB3aGljaCB0aGlzIHNlcnZpY2UgaXMgZXhwb3NlZCB3aGVuIHR5cGU9Tm9kZVBvcnRcbiAgICogb3IgTG9hZEJhbGFuY2VyLiBVc3VhbGx5IGFzc2lnbmVkIGJ5IHRoZSBzeXN0ZW0uIElmIHNwZWNpZmllZCwgaXQgd2lsbCBiZVxuICAgKiBhbGxvY2F0ZWQgdG8gdGhlIHNlcnZpY2UgaWYgdW51c2VkIG9yIGVsc2UgY3JlYXRpb24gb2YgdGhlIHNlcnZpY2Ugd2lsbFxuICAgKiBmYWlsLiBEZWZhdWx0IGlzIHRvIGF1dG8tYWxsb2NhdGUgYSBwb3J0IGlmIHRoZSBTZXJ2aWNlVHlwZSBvZiB0aGlzIFNlcnZpY2VcbiAgICogcmVxdWlyZXMgb25lLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8va3ViZXJuZXRlcy5pby9kb2NzL2NvbmNlcHRzL3NlcnZpY2VzLW5ldHdvcmtpbmcvc2VydmljZS8jdHlwZS1ub2RlcG9ydFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGF1dG8tYWxsb2NhdGUgYSBwb3J0IGlmIHRoZSBTZXJ2aWNlVHlwZSBvZiB0aGlzIFNlcnZpY2UgcmVxdWlyZXMgb25lLlxuICAgKi9cbiAgcmVhZG9ubHkgbm9kZVBvcnQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBJUCBwcm90b2NvbCBmb3IgdGhpcyBwb3J0LiBTdXBwb3J0cyBcIlRDUFwiLCBcIlVEUFwiLCBhbmQgXCJTQ1RQXCIuIERlZmF1bHQgaXMgVENQLlxuICAgKlxuICAgKiBAZGVmYXVsdCBQcm90b2NvbC5UQ1BcbiAgICovXG4gIHJlYWRvbmx5IHByb3RvY29sPzogY29udGFpbmVyLlByb3RvY29sO1xuXG4gIC8qKlxuICAgKiBUaGUgcG9ydCBudW1iZXIgdGhlIHNlcnZpY2Ugd2lsbCByZWRpcmVjdCB0by5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGUgdmFsdWUgb2YgYHBvcnRgIHdpbGwgYmUgdXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IHRhcmdldFBvcnQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogRGVmaW5pdGlvbiBvZiBhIHNlcnZpY2UgcG9ydC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlUG9ydCBleHRlbmRzIFNlcnZpY2VCaW5kT3B0aW9ucyB7XG5cbiAgLyoqXG4gICAqIFRoZSBwb3J0IG51bWJlciB0aGUgc2VydmljZSB3aWxsIGJpbmQgdG8uXG4gICAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG59XG4iXX0=