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
JavaScript
"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=