UNPKG

69.6 kBJavaScriptView Raw
1"use strict";
2var _a, _b, _c;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.LambdaEdgeEventType = exports.CachedMethods = exports.AllowedMethods = exports.SecurityPolicyProtocol = exports.SSLMethod = exports.OriginProtocolPolicy = exports.ViewerProtocolPolicy = exports.PriceClass = exports.HttpVersion = exports.Distribution = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7const s3 = require("@aws-cdk/aws-s3");
8const core_1 = require("@aws-cdk/core");
9const cx_api_1 = require("@aws-cdk/cx-api");
10const cloudfront_generated_1 = require("./cloudfront.generated");
11const cache_behavior_1 = require("./private/cache-behavior");
12// v2 - keep this import as a separate section to reduce merge conflict when forward merging with the v2 branch.
13// eslint-disable-next-line
14const core_2 = require("@aws-cdk/core");
15/**
16 * A CloudFront distribution with associated origin(s) and caching behavior(s).
17 */
18class Distribution extends core_1.Resource {
19 constructor(scope, id, props) {
20 super(scope, id);
21 this.additionalBehaviors = [];
22 this.boundOrigins = [];
23 this.originGroups = [];
24 try {
25 jsiiDeprecationWarnings._aws_cdk_aws_cloudfront_DistributionProps(props);
26 }
27 catch (error) {
28 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
29 Error.captureStackTrace(error, Distribution);
30 }
31 throw error;
32 }
33 if (props.certificate) {
34 const certificateRegion = core_1.Stack.of(this).splitArn(props.certificate.certificateArn, core_1.ArnFormat.SLASH_RESOURCE_NAME).region;
35 if (!core_1.Token.isUnresolved(certificateRegion) && certificateRegion !== 'us-east-1') {
36 throw new Error(`Distribution certificates must be in the us-east-1 region and the certificate you provided is in ${certificateRegion}.`);
37 }
38 if ((props.domainNames ?? []).length === 0) {
39 throw new Error('Must specify at least one domain name to use a certificate with a distribution');
40 }
41 }
42 const originId = this.addOrigin(props.defaultBehavior.origin);
43 this.defaultBehavior = new cache_behavior_1.CacheBehavior(originId, { pathPattern: '*', ...props.defaultBehavior });
44 if (props.additionalBehaviors) {
45 Object.entries(props.additionalBehaviors).forEach(([pathPattern, behaviorOptions]) => {
46 this.addBehavior(pathPattern, behaviorOptions.origin, behaviorOptions);
47 });
48 }
49 this.certificate = props.certificate;
50 this.errorResponses = props.errorResponses ?? [];
51 // Comments have an undocumented limit of 128 characters
52 const trimmedComment = props.comment && props.comment.length > 128
53 ? `${props.comment.slice(0, 128 - 3)}...`
54 : props.comment;
55 const distribution = new cloudfront_generated_1.CfnDistribution(this, 'Resource', {
56 distributionConfig: {
57 enabled: props.enabled ?? true,
58 origins: core_1.Lazy.any({ produce: () => this.renderOrigins() }),
59 originGroups: core_1.Lazy.any({ produce: () => this.renderOriginGroups() }),
60 defaultCacheBehavior: this.defaultBehavior._renderBehavior(),
61 aliases: props.domainNames,
62 cacheBehaviors: core_1.Lazy.any({ produce: () => this.renderCacheBehaviors() }),
63 comment: trimmedComment,
64 customErrorResponses: this.renderErrorResponses(),
65 defaultRootObject: props.defaultRootObject,
66 httpVersion: props.httpVersion ?? HttpVersion.HTTP2,
67 ipv6Enabled: props.enableIpv6 ?? true,
68 logging: this.renderLogging(props),
69 priceClass: props.priceClass ?? undefined,
70 restrictions: this.renderRestrictions(props.geoRestriction),
71 viewerCertificate: this.certificate ? this.renderViewerCertificate(this.certificate, props.minimumProtocolVersion, props.sslSupportMethod) : undefined,
72 webAclId: props.webAclId,
73 },
74 });
75 this.domainName = distribution.attrDomainName;
76 this.distributionDomainName = distribution.attrDomainName;
77 this.distributionId = distribution.ref;
78 }
79 /**
80 * Creates a Distribution construct that represents an external (imported) distribution.
81 */
82 static fromDistributionAttributes(scope, id, attrs) {
83 try {
84 jsiiDeprecationWarnings._aws_cdk_aws_cloudfront_DistributionAttributes(attrs);
85 }
86 catch (error) {
87 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
88 Error.captureStackTrace(error, this.fromDistributionAttributes);
89 }
90 throw error;
91 }
92 return new class extends core_1.Resource {
93 constructor() {
94 super(scope, id);
95 this.domainName = attrs.domainName;
96 this.distributionDomainName = attrs.domainName;
97 this.distributionId = attrs.distributionId;
98 }
99 }();
100 }
101 /**
102 * Adds a new behavior to this distribution for the given pathPattern.
103 *
104 * @param pathPattern the path pattern (e.g., 'images/*') that specifies which requests to apply the behavior to.
105 * @param origin the origin to use for this behavior
106 * @param behaviorOptions the options for the behavior at this path.
107 */
108 addBehavior(pathPattern, origin, behaviorOptions = {}) {
109 try {
110 jsiiDeprecationWarnings._aws_cdk_aws_cloudfront_IOrigin(origin);
111 jsiiDeprecationWarnings._aws_cdk_aws_cloudfront_AddBehaviorOptions(behaviorOptions);
112 }
113 catch (error) {
114 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
115 Error.captureStackTrace(error, this.addBehavior);
116 }
117 throw error;
118 }
119 if (pathPattern === '*') {
120 throw new Error('Only the default behavior can have a path pattern of \'*\'');
121 }
122 const originId = this.addOrigin(origin);
123 this.additionalBehaviors.push(new cache_behavior_1.CacheBehavior(originId, { pathPattern, ...behaviorOptions }));
124 }
125 addOrigin(origin, isFailoverOrigin = false) {
126 const ORIGIN_ID_MAX_LENGTH = 128;
127 const existingOrigin = this.boundOrigins.find(boundOrigin => boundOrigin.origin === origin);
128 if (existingOrigin) {
129 return existingOrigin.originGroupId ?? existingOrigin.originId;
130 }
131 else {
132 const originIndex = this.boundOrigins.length + 1;
133 const scope = new core_2.Construct(this, `Origin${originIndex}`);
134 const originId = core_1.Names.uniqueId(scope).slice(-ORIGIN_ID_MAX_LENGTH);
135 const originBindConfig = origin.bind(scope, { originId });
136 if (!originBindConfig.failoverConfig) {
137 this.boundOrigins.push({ origin, originId, ...originBindConfig });
138 }
139 else {
140 if (isFailoverOrigin) {
141 throw new Error('An Origin cannot use an Origin with its own failover configuration as its fallback origin!');
142 }
143 const groupIndex = this.originGroups.length + 1;
144 const originGroupId = core_1.Names.uniqueId(new core_2.Construct(this, `OriginGroup${groupIndex}`)).slice(-ORIGIN_ID_MAX_LENGTH);
145 this.boundOrigins.push({ origin, originId, originGroupId, ...originBindConfig });
146 const failoverOriginId = this.addOrigin(originBindConfig.failoverConfig.failoverOrigin, true);
147 this.addOriginGroup(originGroupId, originBindConfig.failoverConfig.statusCodes, originId, failoverOriginId);
148 return originGroupId;
149 }
150 return originId;
151 }
152 }
153 addOriginGroup(originGroupId, statusCodes, originId, failoverOriginId) {
154 statusCodes = statusCodes ?? [500, 502, 503, 504];
155 if (statusCodes.length === 0) {
156 throw new Error('fallbackStatusCodes cannot be empty');
157 }
158 this.originGroups.push({
159 failoverCriteria: {
160 statusCodes: {
161 items: statusCodes,
162 quantity: statusCodes.length,
163 },
164 },
165 id: originGroupId,
166 members: {
167 items: [
168 { originId },
169 { originId: failoverOriginId },
170 ],
171 quantity: 2,
172 },
173 });
174 }
175 renderOrigins() {
176 const renderedOrigins = [];
177 this.boundOrigins.forEach(boundOrigin => {
178 if (boundOrigin.originProperty) {
179 renderedOrigins.push(boundOrigin.originProperty);
180 }
181 });
182 return renderedOrigins;
183 }
184 renderOriginGroups() {
185 return this.originGroups.length === 0
186 ? undefined
187 : {
188 items: this.originGroups,
189 quantity: this.originGroups.length,
190 };
191 }
192 renderCacheBehaviors() {
193 if (this.additionalBehaviors.length === 0) {
194 return undefined;
195 }
196 return this.additionalBehaviors.map(behavior => behavior._renderBehavior());
197 }
198 renderErrorResponses() {
199 if (this.errorResponses.length === 0) {
200 return undefined;
201 }
202 return this.errorResponses.map(errorConfig => {
203 if (!errorConfig.responseHttpStatus && !errorConfig.ttl && !errorConfig.responsePagePath) {
204 throw new Error('A custom error response without either a \'responseHttpStatus\', \'ttl\' or \'responsePagePath\' is not valid.');
205 }
206 return {
207 errorCachingMinTtl: errorConfig.ttl?.toSeconds(),
208 errorCode: errorConfig.httpStatus,
209 responseCode: errorConfig.responsePagePath
210 ? errorConfig.responseHttpStatus ?? errorConfig.httpStatus
211 : errorConfig.responseHttpStatus,
212 responsePagePath: errorConfig.responsePagePath,
213 };
214 });
215 }
216 renderLogging(props) {
217 if (!props.enableLogging && !props.logBucket) {
218 return undefined;
219 }
220 if (props.enableLogging === false && props.logBucket) {
221 throw new Error('Explicitly disabled logging but provided a logging bucket.');
222 }
223 const bucket = props.logBucket ?? new s3.Bucket(this, 'LoggingBucket', {
224 encryption: s3.BucketEncryption.S3_MANAGED,
225 });
226 return {
227 bucket: bucket.bucketRegionalDomainName,
228 includeCookies: props.logIncludesCookies,
229 prefix: props.logFilePrefix,
230 };
231 }
232 renderRestrictions(geoRestriction) {
233 return geoRestriction ? {
234 geoRestriction: {
235 restrictionType: geoRestriction.restrictionType,
236 locations: geoRestriction.locations,
237 },
238 } : undefined;
239 }
240 renderViewerCertificate(certificate, minimumProtocolVersionProp, sslSupportMethodProp) {
241 const defaultVersion = core_1.FeatureFlags.of(this).isEnabled(cx_api_1.CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021)
242 ? SecurityPolicyProtocol.TLS_V1_2_2021 : SecurityPolicyProtocol.TLS_V1_2_2019;
243 const minimumProtocolVersion = minimumProtocolVersionProp ?? defaultVersion;
244 const sslSupportMethod = sslSupportMethodProp ?? SSLMethod.SNI;
245 return {
246 acmCertificateArn: certificate.certificateArn,
247 minimumProtocolVersion: minimumProtocolVersion,
248 sslSupportMethod: sslSupportMethod,
249 };
250 }
251}
252exports.Distribution = Distribution;
253_a = JSII_RTTI_SYMBOL_1;
254Distribution[_a] = { fqn: "@aws-cdk/aws-cloudfront.Distribution", version: "1.161.0" };
255/** Maximum HTTP version to support */
256var HttpVersion;
257(function (HttpVersion) {
258 /** HTTP 1.1 */
259 HttpVersion["HTTP1_1"] = "http1.1";
260 /** HTTP 2 */
261 HttpVersion["HTTP2"] = "http2";
262})(HttpVersion = exports.HttpVersion || (exports.HttpVersion = {}));
263/**
264 * The price class determines how many edge locations CloudFront will use for your distribution.
265 * See https://aws.amazon.com/cloudfront/pricing/ for full list of supported regions.
266 */
267var PriceClass;
268(function (PriceClass) {
269 /** USA, Canada, Europe, & Israel */
270 PriceClass["PRICE_CLASS_100"] = "PriceClass_100";
271 /** PRICE_CLASS_100 + South Africa, Kenya, Middle East, Japan, Singapore, South Korea, Taiwan, Hong Kong, & Philippines */
272 PriceClass["PRICE_CLASS_200"] = "PriceClass_200";
273 /** All locations */
274 PriceClass["PRICE_CLASS_ALL"] = "PriceClass_All";
275})(PriceClass = exports.PriceClass || (exports.PriceClass = {}));
276/**
277 * How HTTPs should be handled with your distribution.
278 */
279var ViewerProtocolPolicy;
280(function (ViewerProtocolPolicy) {
281 /** HTTPS only */
282 ViewerProtocolPolicy["HTTPS_ONLY"] = "https-only";
283 /** Will redirect HTTP requests to HTTPS */
284 ViewerProtocolPolicy["REDIRECT_TO_HTTPS"] = "redirect-to-https";
285 /** Both HTTP and HTTPS supported */
286 ViewerProtocolPolicy["ALLOW_ALL"] = "allow-all";
287})(ViewerProtocolPolicy = exports.ViewerProtocolPolicy || (exports.ViewerProtocolPolicy = {}));
288/**
289 * Defines what protocols CloudFront will use to connect to an origin.
290 */
291var OriginProtocolPolicy;
292(function (OriginProtocolPolicy) {
293 /** Connect on HTTP only */
294 OriginProtocolPolicy["HTTP_ONLY"] = "http-only";
295 /** Connect with the same protocol as the viewer */
296 OriginProtocolPolicy["MATCH_VIEWER"] = "match-viewer";
297 /** Connect on HTTPS only */
298 OriginProtocolPolicy["HTTPS_ONLY"] = "https-only";
299})(OriginProtocolPolicy = exports.OriginProtocolPolicy || (exports.OriginProtocolPolicy = {}));
300/**
301 * The SSL method CloudFront will use for your distribution.
302 *
303 * Server Name Indication (SNI) - is an extension to the TLS computer networking protocol by which a client indicates
304 * which hostname it is attempting to connect to at the start of the handshaking process. This allows a server to present
305 * multiple certificates on the same IP address and TCP port number and hence allows multiple secure (HTTPS) websites
306 * (or any other service over TLS) to be served by the same IP address without requiring all those sites to use the same certificate.
307 *
308 * CloudFront can use SNI to host multiple distributions on the same IP - which a large majority of clients will support.
309 *
310 * If your clients cannot support SNI however - CloudFront can use dedicated IPs for your distribution - but there is a prorated monthly charge for
311 * using this feature. By default, we use SNI - but you can optionally enable dedicated IPs (VIP).
312 *
313 * See the CloudFront SSL for more details about pricing : https://aws.amazon.com/cloudfront/custom-ssl-domains/
314 *
315 */
316var SSLMethod;
317(function (SSLMethod) {
318 SSLMethod["SNI"] = "sni-only";
319 SSLMethod["VIP"] = "vip";
320})(SSLMethod = exports.SSLMethod || (exports.SSLMethod = {}));
321/**
322 * The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections.
323 * CloudFront serves your objects only to browsers or devices that support at least the SSL version that you specify.
324 */
325var SecurityPolicyProtocol;
326(function (SecurityPolicyProtocol) {
327 SecurityPolicyProtocol["SSL_V3"] = "SSLv3";
328 SecurityPolicyProtocol["TLS_V1"] = "TLSv1";
329 SecurityPolicyProtocol["TLS_V1_2016"] = "TLSv1_2016";
330 SecurityPolicyProtocol["TLS_V1_1_2016"] = "TLSv1.1_2016";
331 SecurityPolicyProtocol["TLS_V1_2_2018"] = "TLSv1.2_2018";
332 SecurityPolicyProtocol["TLS_V1_2_2019"] = "TLSv1.2_2019";
333 SecurityPolicyProtocol["TLS_V1_2_2021"] = "TLSv1.2_2021";
334})(SecurityPolicyProtocol = exports.SecurityPolicyProtocol || (exports.SecurityPolicyProtocol = {}));
335/**
336 * The HTTP methods that the Behavior will accept requests on.
337 */
338class AllowedMethods {
339 constructor(methods) { this.methods = methods; }
340}
341exports.AllowedMethods = AllowedMethods;
342_b = JSII_RTTI_SYMBOL_1;
343AllowedMethods[_b] = { fqn: "@aws-cdk/aws-cloudfront.AllowedMethods", version: "1.161.0" };
344/** HEAD and GET */
345AllowedMethods.ALLOW_GET_HEAD = new AllowedMethods(['GET', 'HEAD']);
346/** HEAD, GET, and OPTIONS */
347AllowedMethods.ALLOW_GET_HEAD_OPTIONS = new AllowedMethods(['GET', 'HEAD', 'OPTIONS']);
348/** All supported HTTP methods */
349AllowedMethods.ALLOW_ALL = new AllowedMethods(['GET', 'HEAD', 'OPTIONS', 'PUT', 'PATCH', 'POST', 'DELETE']);
350/**
351 * The HTTP methods that the Behavior will cache requests on.
352 */
353class CachedMethods {
354 constructor(methods) { this.methods = methods; }
355}
356exports.CachedMethods = CachedMethods;
357_c = JSII_RTTI_SYMBOL_1;
358CachedMethods[_c] = { fqn: "@aws-cdk/aws-cloudfront.CachedMethods", version: "1.161.0" };
359/** HEAD and GET */
360CachedMethods.CACHE_GET_HEAD = new CachedMethods(['GET', 'HEAD']);
361/** HEAD, GET, and OPTIONS */
362CachedMethods.CACHE_GET_HEAD_OPTIONS = new CachedMethods(['GET', 'HEAD', 'OPTIONS']);
363/**
364 * The type of events that a Lambda@Edge function can be invoked in response to.
365 */
366var LambdaEdgeEventType;
367(function (LambdaEdgeEventType) {
368 /**
369 * The origin-request specifies the request to the
370 * origin location (e.g. S3)
371 */
372 LambdaEdgeEventType["ORIGIN_REQUEST"] = "origin-request";
373 /**
374 * The origin-response specifies the response from the
375 * origin location (e.g. S3)
376 */
377 LambdaEdgeEventType["ORIGIN_RESPONSE"] = "origin-response";
378 /**
379 * The viewer-request specifies the incoming request
380 */
381 LambdaEdgeEventType["VIEWER_REQUEST"] = "viewer-request";
382 /**
383 * The viewer-response specifies the outgoing response
384 */
385 LambdaEdgeEventType["VIEWER_RESPONSE"] = "viewer-response";
386})(LambdaEdgeEventType = exports.LambdaEdgeEventType || (exports.LambdaEdgeEventType = {}));
387//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdHJpYnV0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlzdHJpYnV0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBLHNDQUFzQztBQUN0Qyx3Q0FBa0g7QUFDbEgsNENBQW1GO0FBR25GLGlFQUF5RDtBQU16RCw2REFBeUQ7QUFHekQsZ0hBQWdIO0FBQ2hILDJCQUEyQjtBQUMzQix3Q0FBMkQ7QUFpTzNEOztHQUVHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsZUFBUTtJQWdDeEMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF3QjtRQUNoRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBUkYsd0JBQW1CLEdBQW9CLEVBQUUsQ0FBQztRQUMxQyxpQkFBWSxHQUFrQixFQUFFLENBQUM7UUFDakMsaUJBQVksR0FBMEMsRUFBRSxDQUFDOzs7Ozs7K0NBM0IvRCxZQUFZOzs7O1FBbUNyQixJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUU7WUFDckIsTUFBTSxpQkFBaUIsR0FBRyxZQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxnQkFBUyxDQUFDLG1CQUFtQixDQUFDLENBQUMsTUFBTSxDQUFDO1lBQzFILElBQUksQ0FBQyxZQUFLLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLElBQUksaUJBQWlCLEtBQUssV0FBVyxFQUFFO2dCQUMvRSxNQUFNLElBQUksS0FBSyxDQUFDLG9HQUFvRyxpQkFBaUIsR0FBRyxDQUFDLENBQUM7YUFDM0k7WUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUMxQyxNQUFNLElBQUksS0FBSyxDQUFDLGdGQUFnRixDQUFDLENBQUM7YUFDbkc7U0FDRjtRQUVELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxT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LE1BQWEsYUFBYTtJQVN4QixZQUFvQixPQUFpQixJQUFJLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLEVBQUU7O0FBVHBFLHNDQVVDOzs7QUFUQyxtQkFBbUI7QUFDSSw0QkFBYyxHQUFHLElBQUksYUFBYSxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDM0UsNkJBQTZCO0FBQ04sb0NBQXNCLEdBQUcsSUFBSSxhQUFhLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUF1Q2hHOztHQUVHO0FBQ0gsSUFBWSxtQkFzQlg7QUF0QkQsV0FBWSxtQkFBbUI7SUFDN0I7OztPQUdHO0lBQ0gsd0RBQWlDLENBQUE7SUFFakM7OztPQUdHO0lBQ0gsMERBQW1DLENBQUE7SUFFbkM7O09BRUc7SUFDSCx3REFBaUMsQ0FBQTtJQUVqQzs7T0FFRztJQUNILDBEQUFtQyxDQUFBO0FBQ3JDLENBQUMsRUF0QlcsbUJBQW1CLEdBQW5CLDJCQUFtQixLQUFuQiwyQkFBbUIsUUFzQjlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYWNtIGZyb20gJ0Bhd3MtY2RrL2F3cy1jZXJ0aWZpY2F0ZW1hbmFnZXInO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ0Bhd3MtY2RrL2F3cy1sYW1iZGEnO1xuaW1wb3J0ICogYXMgczMgZnJvbSAnQGF3cy1jZGsvYXdzLXMzJztcbmltcG9ydCB7IEFybkZvcm1hdCwgSVJlc291cmNlLCBMYXp5LCBSZXNvdXJjZSwgU3RhY2ssIFRva2VuLCBEdXJhdGlvbiwgTmFtZXMsIEZlYXR1cmVGbGFncyB9IGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuaW1wb3J0IHsgQ0xPVURGUk9OVF9ERUZBVUxUX1NFQ1VSSVRZX1BPTElDWV9UTFNfVjFfMl8yMDIxIH0gZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgSUNhY2hlUG9saWN5IH0gZnJvbSAnLi9jYWNoZS1wb2xpY3knO1xuaW1wb3J0IHsgQ2ZuRGlzdHJpYnV0aW9uIH0gZnJvbSAnLi9jbG91ZGZyb250LmdlbmVyYXRlZCc7XG5pbXBvcnQgeyBGdW5jdGlvbkFzc29jaWF0aW9uIH0gZnJvbSAnLi9mdW5jdGlvbic7XG5pbXBvcnQgeyBHZW9SZXN0cmljdGlvbiB9IGZyb20gJy4vZ2VvLXJlc3RyaWN0aW9uJztcbmltcG9ydCB7IElLZXlHcm91cCB9IGZyb20gJy4va2V5LWdyb3VwJztcbmltcG9ydCB7IElPcmlnaW4sIE9yaWdpbkJpbmRDb25maWcsIE9yaWdpbkJpbmRPcHRpb25zIH0gZnJvbSAnLi9vcmlnaW4nO1xuaW1wb3J0IHsgSU9yaWdpblJlcXVlc3RQb2xpY3kgfSBmcm9tICcuL29yaWdpbi1yZXF1ZXN0LXBvbGljeSc7XG5pbXBvcnQgeyBDYWNoZUJlaGF2aW9yIH0gZnJvbSAnLi9wcml2YXRlL2NhY2hlLWJlaGF2aW9yJztcbmltcG9ydCB7IElSZXNwb25zZUhlYWRlcnNQb2xpY3kgfSBmcm9tICcuL3Jlc3BvbnNlLWhlYWRlcnMtcG9saWN5JztcblxuLy8gdjIgLSBrZWVwIHRoaXMgaW1wb3J0IGFzIGEgc2VwYXJhdGUgc2VjdGlvbiB0byByZWR1Y2UgbWVyZ2UgY29uZmxpY3Qgd2hlbiBmb3J3YXJkIG1lcmdpbmcgd2l0aCB0aGUgdjIgYnJhbmNoLlxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5pbXBvcnQgeyBDb25zdHJ1Y3QgYXMgQ29yZUNvbnN0cnVjdCB9IGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgQ2xvdWRGcm9udCBkaXN0cmlidXRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSURpc3RyaWJ1dGlvbiBleHRlbmRzIElSZXNvdXJjZSB7XG4gIC8qKlxuICAgKiBUaGUgZG9tYWluIG5hbWUgb2YgdGhlIERpc3RyaWJ1dGlvbiwgc3VjaCBhcyBkMTExMTExYWJjZGVmOC5jbG91ZGZyb250Lm5ldC5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKiBAZGVwcmVjYXRlZCAtIFVzZSBgZGlzdHJpYnV0aW9uRG9tYWluTmFtZWAgaW5zdGVhZC5cbiAgICovXG4gIHJlYWRvbmx5IGRvbWFpbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGRvbWFpbiBuYW1lIG9mIHRoZSBEaXN0cmlidXRpb24sIHN1Y2ggYXMgZDExMTExMWFiY2RlZjguY2xvdWRmcm9udC5uZXQuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbkRvbWFpbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGRpc3RyaWJ1dGlvbiBJRCBmb3IgdGhpcyBkaXN0cmlidXRpb24uXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbklkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQXR0cmlidXRlcyB1c2VkIHRvIGltcG9ydCBhIERpc3RyaWJ1dGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEaXN0cmlidXRpb25BdHRyaWJ1dGVzIHtcbiAgLyoqXG4gICAqIFRoZSBnZW5lcmF0ZWQgZG9tYWluIG5hbWUgb2YgdGhlIERpc3RyaWJ1dGlvbiwgc3VjaCBhcyBkMTExMTExYWJjZGVmOC5jbG91ZGZyb250Lm5ldC5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgZG9tYWluTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZGlzdHJpYnV0aW9uIElEIGZvciB0aGlzIGRpc3RyaWJ1dGlvbi5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgZGlzdHJpYnV0aW9uSWQ6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIEJvdW5kT3JpZ2luIGV4dGVuZHMgT3JpZ2luQmluZE9wdGlvbnMsIE9yaWdpbkJpbmRDb25maWcge1xuICByZWFkb25seSBvcmlnaW46IElPcmlnaW47XG4gIHJlYWRvbmx5IG9yaWdpbkdyb3VwSWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgYSBEaXN0cmlidXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEaXN0cmlidXRpb25Qcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBiZWhhdmlvciBmb3IgdGhlIGRpc3RyaWJ1dGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRCZWhhdmlvcjogQmVoYXZpb3JPcHRpb25zO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIGJlaGF2aW9ycyBmb3IgdGhlIGRpc3RyaWJ1dGlvbiwgbWFwcGVkIGJ5IHRoZSBwYXRoUGF0dGVybiB0aGF0IHNwZWNpZmllcyB3aGljaCByZXF1ZXN0cyB0byBhcHBseSB0aGUgYmVoYXZpb3IgdG8uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gYWRkaXRpb25hbCBiZWhhdmlvcnMgYXJlIGFkZGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgYWRkaXRpb25hbEJlaGF2aW9ycz86IFJlY29yZDxzdHJpbmcsIEJlaGF2aW9yT3B0aW9ucz47XG5cbiAgLyoqXG4gICAqIEEgY2VydGlmaWNhdGUgdG8gYXNzb2NpYXRlIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4gVGhlIGNlcnRpZmljYXRlIG11c3QgYmUgbG9jYXRlZCBpbiBOLiBWaXJnaW5pYSAodXMtZWFzdC0xKS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0aGUgQ2xvdWRGcm9udCB3aWxkY2FyZCBjZXJ0aWZpY2F0ZSAoKi5jbG91ZGZyb250Lm5ldCkgd2lsbCBiZSB1c2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgY2VydGlmaWNhdGU/OiBhY20uSUNlcnRpZmljYXRlO1xuXG4gIC8qKlxuICAgKiBBbnkgY29tbWVudHMgeW91IHdhbnQgdG8gaW5jbHVkZSBhYm91dCB0aGUgZGlzdHJpYnV0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGNvbW1lbnRcbiAgICovXG4gIHJlYWRvbmx5IGNvbW1lbnQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBvYmplY3QgdGhhdCB5b3Ugd2FudCBDbG91ZEZyb250IHRvIHJlcXVlc3QgZnJvbSB5b3VyIG9yaWdpbiAoZm9yIGV4YW1wbGUsIGluZGV4Lmh0bWwpXG4gICAqIHdoZW4gYSB2aWV3ZXIgcmVxdWVzdHMgdGhlIHJvb3QgVVJMIGZvciB5b3VyIGRpc3RyaWJ1dGlvbi4gSWYgbm8gZGVmYXVsdCBvYmplY3QgaXMgc2V0LCB0aGVcbiAgICogcmVxdWVzdCBnb2VzIHRvIHRoZSBvcmlnaW4ncyByb290IChlLmcuLCBleGFtcGxlLmNvbS8pLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGRlZmF1bHQgcm9vdCBvYmplY3RcbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRSb290T2JqZWN0Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBbHRlcm5hdGl2ZSBkb21haW4gbmFtZXMgZm9yIHRoaXMgZGlzdHJpYnV0aW9uLlxuICAgKlxuICAgKiBJZiB5b3Ugd2FudCB0byB1c2UgeW91ciBvd24gZG9tYWluIG5hbWUsIHN1Y2ggYXMgd3d3LmV4YW1wbGUuY29tLCBpbnN0ZWFkIG9mIHRoZSBjbG91ZGZyb250Lm5ldCBkb21haW4gbmFtZSxcbiAgICogeW91IGNhbiBhZGQgYW4gYWx0ZXJuYXRlIGRvbWFpbiBuYW1lIHRvIHlvdXIgZGlzdHJpYnV0aW9uLiBJZiB5b3UgYXR0YWNoIGEgY2VydGlmaWNhdGUgdG8gdGhlIGRpc3RyaWJ1dGlvbixcbiAgICogeW91IG11c3QgYWRkIChhdCBsZWFzdCBvbmUgb2YpIHRoZSBkb21haW4gbmFtZXMgb2YgdGhlIGNlcnRpZmljYXRlIHRvIHRoaXMgbGlzdC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGUgZGlzdHJpYnV0aW9uIHdpbGwgb25seSBzdXBwb3J0IHRoZSBkZWZhdWx0IGdlbmVyYXRlZCBuYW1lIChlLmcuLCBkMTExMTExYWJjZGVmOC5jbG91ZGZyb250Lm5ldClcbiAgICovXG4gIHJlYWRvbmx5IGRvbWFpbk5hbWVzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEVuYWJsZSBvciBkaXNhYmxlIHRoZSBkaXN0cmlidXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGVuYWJsZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIENsb3VkRnJvbnQgd2lsbCByZXNwb25kIHRvIElQdjYgRE5TIHJlcXVlc3RzIHdpdGggYW4gSVB2NiBhZGRyZXNzLlxuICAgKlxuICAgKiBJZiB5b3Ugc3BlY2lmeSBmYWxzZSwgQ2xvdWRGcm9udCByZXNwb25kcyB0byBJUHY2IEROUyByZXF1ZXN0cyB3aXRoIHRoZSBETlMgcmVzcG9uc2UgY29kZSBOT0VSUk9SIGFuZCB3aXRoIG5vIElQIGFkZHJlc3Nlcy5cbiAgICogVGhpcyBhbGxvd3Mgdmlld2VycyB0byBzdWJtaXQgYSBzZWNvbmQgcmVxdWVzdCwgZm9yIGFuIElQdjQgYWRkcmVzcyBmb3IgeW91ciBkaXN0cmlidXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGVuYWJsZUlwdjY/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBFbmFibGUgYWNjZXNzIGxvZ2dpbmcgZm9yIHRoZSBkaXN0cmlidXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZmFsc2UsIHVubGVzcyBgbG9nQnVja2V0YCBpcyBzcGVjaWZpZWQuXG4gICAqL1xuICByZWFkb25seSBlbmFibGVMb2dnaW5nPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ29udHJvbHMgdGhlIGNvdW50cmllcyBpbiB3aGljaCB5b3VyIGNvbnRlbnQgaXMgZGlzdHJpYnV0ZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZ2VvZ3JhcGhpYyByZXN0cmljdGlvbnNcbiAgICovXG4gIHJlYWRvbmx5IGdlb1Jlc3RyaWN0aW9uPzogR2VvUmVzdHJpY3Rpb247XG5cbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIG1heGltdW0gSFRUUCB2ZXJzaW9uIHRoYXQgeW91IHdhbnQgdmlld2VycyB0byB1c2UgdG8gY29tbXVuaWNhdGUgd2l0aCBDbG91ZEZyb250LlxuICAgKlxuICAgKiBGb3Igdmlld2VycyBhbmQgQ2xvdWRGcm9udCB0byB1c2UgSFRUUC8yLCB2aWV3ZXJzIG11c3Qgc3VwcG9ydCBUTFMgMS4yIG9yIGxhdGVyLCBhbmQgbXVzdCBzdXBwb3J0IHNlcnZlciBuYW1lIGlkZW50aWZpY2F0aW9uIChTTkkpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBIdHRwVmVyc2lvbi5IVFRQMlxuICAgKi9cbiAgcmVhZG9ubHkgaHR0cFZlcnNpb24/OiBIdHRwVmVyc2lvbjtcblxuICAvKipcbiAgICogVGhlIEFtYXpvbiBTMyBidWNrZXQgdG8gc3RvcmUgdGhlIGFjY2VzcyBsb2dzIGluLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEEgYnVja2V0IGlzIGNyZWF0ZWQgaWYgYGVuYWJsZUxvZ2dpbmdgIGlzIHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGxvZ0J1Y2tldD86IHMzLklCdWNrZXQ7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB3aGV0aGVyIHlvdSB3YW50IENsb3VkRnJvbnQgdG8gaW5jbHVkZSBjb29raWVzIGluIGFjY2VzcyBsb2dzXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBsb2dJbmNsdWRlc0Nvb2tpZXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBbiBvcHRpb25hbCBzdHJpbmcgdGhhdCB5b3Ugd2FudCBDbG91ZEZyb250IHRvIHByZWZpeCB0byB0aGUgYWNjZXNzIGxvZyBmaWxlbmFtZXMgZm9yIHRoaXMgZGlzdHJpYnV0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHByZWZpeFxuICAgKi9cbiAgcmVhZG9ubHkgbG9nRmlsZVByZWZpeD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHByaWNlIGNsYXNzIHRoYXQgY29ycmVzcG9uZHMgd2l0aCB0aGUgbWF4aW11bSBwcmljZSB0aGF0IHlvdSB3YW50IHRvIHBheSBmb3IgQ2xvdWRGcm9udCBzZXJ2aWNlLlxuICAgKiBJZiB5b3Ugc3BlY2lmeSBQcmljZUNsYXNzX0FsbCwgQ2xvdWRGcm9udCByZXNwb25kcyB0byByZXF1ZXN0cyBmb3IgeW91ciBvYmplY3RzIGZyb20gYWxsIENsb3VkRnJvbnQgZWRnZSBsb2NhdGlvbnMuXG4gICAqIElmIHlvdSBzcGVjaWZ5IGEgcHJpY2UgY2xhc3Mgb3RoZXIgdGhhbiBQcmljZUNsYXNzX0FsbCwgQ2xvdWRGcm9udCBzZXJ2ZXMgeW91ciBvYmplY3RzIGZyb20gdGhlIENsb3VkRnJvbnQgZWRnZSBsb2NhdGlvblxuICAgKiB0aGF0IGhhcyB0aGUgbG93ZXN0IGxhdGVuY3kgYW1vbmcgdGhlIGVkZ2UgbG9jYXRpb25zIGluIHlvdXIgcHJpY2UgY2xhc3MuXG4gICAqXG4gICAqIEBkZWZhdWx0IFByaWNlQ2xhc3MuUFJJQ0VfQ0xBU1NfQUxMXG4gICAqL1xuICByZWFkb25seSBwcmljZUNsYXNzPzogUHJpY2VDbGFzcztcblxuICAvKipcbiAgICogVW5pcXVlIGlkZW50aWZpZXIgdGhhdCBzcGVjaWZpZXMgdGhlIEFXUyBXQUYgd2ViIEFDTCB0byBhc3NvY2lhdGUgd2l0aCB0aGlzIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLlxuICAgKlxuICAgKiBUbyBzcGVjaWZ5IGEgd2ViIEFDTCBjcmVhdGVkIHVzaW5nIHRoZSBsYXRlc3QgdmVyc2lvbiBvZiBBV1MgV0FGLCB1c2UgdGhlIEFDTCBBUk4sIGZvciBleGFtcGxlXG4gICAqIGBhcm46YXdzOndhZnYyOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6Z2xvYmFsL3dlYmFjbC9FeGFtcGxlV2ViQUNMLzQ3M2U2NGZkLWYzMGItNDc2NS04MWEwLTYyYWQ5NmRkMTY3YWAuXG4gICAqIFRvIHNwZWNpZnkgYSB3ZWIgQUNMIGNyZWF0ZWQgdXNpbmcgQVdTIFdBRiBDbGFzc2ljLCB1c2UgdGhlIEFDTCBJRCwgZm9yIGV4YW1wbGUgYDQ3M2U2NGZkLWYzMGItNDc2NS04MWEwLTYyYWQ5NmRkMTY3YWAuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvd2hhdC1pcy1hd3Mtd2FmLmh0bWxcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWRmcm9udC9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVEaXN0cmlidXRpb24uaHRtbCNBUElfQ3JlYXRlRGlzdHJpYnV0aW9uX1JlcXVlc3RQYXJhbWV0ZXJzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIEFXUyBXZWIgQXBwbGljYXRpb24gRmlyZXdhbGwgd2ViIGFjY2VzcyBjb250cm9sIGxpc3QgKHdlYiBBQ0wpLlxuICAgKi9cbiAgcmVhZG9ubHkgd2ViQWNsSWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEhvdyBDbG91ZEZyb250IHNob3VsZCBoYW5kbGUgcmVxdWVzdHMgdGhhdCBhcmUgbm90IHN1Y2Nlc3NmdWwgKGUuZy4sIFBhZ2VOb3RGb3VuZCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gY3VzdG9tIGVycm9yIHJlc3BvbnNlcy5cbiAgICovXG4gIHJlYWRvbmx5IGVycm9yUmVzcG9uc2VzPzogRXJyb3JSZXNwb25zZVtdO1xuXG4gIC8qKlxuICAgICogVGhlIG1pbmltdW0gdmVyc2lvbiBvZiB0aGUgU1NMIHByb3RvY29sIHRoYXQgeW91IHdhbnQgQ2xvdWRGcm9udCB0byB1c2UgZm9yIEhUVFBTIGNvbm5lY3Rpb25zLlxuICAgICpcbiAgICAqIENsb3VkRnJvbnQgc2VydmVzIHlvdXIgb2JqZWN0cyBvbmx5IHRvIGJyb3dzZXJzIG9yIGRldmljZXMgdGhhdCBzdXBwb3J0IGF0XG4gICAgKiBsZWFzdCB0aGUgU1NMIHZlcnNpb24gdGhhdCB5b3Ugc3BlY2lmeS5cbiAgICAqXG4gICAgKiBAZGVmYXVsdCAtIFNlY3VyaXR5UG9saWN5UHJvdG9jb2wuVExTX1YxXzJfMjAyMSBpZiB0aGUgJ0Bhd3MtY2RrL2F3cy1jbG91ZGZyb250OmRlZmF1bHRTZWN1cml0eVBvbGljeVRMU3YxLjJfMjAyMScgZmVhdHVyZSBmbGFnIGlzIHNldDsgb3RoZXJ3aXNlLCBTZWN1cml0eVBvbGljeVByb3RvY29sLlRMU19WMV8yXzIwMTkuXG4gICAgKi9cbiAgcmVhZG9ubHkgbWluaW11bVByb3RvY29sVmVyc2lvbj86IFNlY3VyaXR5UG9saWN5UHJvdG9jb2w7XG5cbiAgLyoqXG4gICAgKiBUaGUgU1NMIG1ldGhvZCBDbG91ZEZyb250IHdpbGwgdXNlIGZvciB5b3VyIGRpc3RyaWJ1dGlvbi5cbiAgICAqXG4gICAgKiBTZXJ2ZXIgTmFtZSBJbmRpY2F0aW9uIChTTkkpIC0gaXMgYW4gZXh0ZW5zaW9uIHRvIHRoZSBUTFMgY29tcHV0ZXIgbmV0d29ya2luZyBwcm90b2NvbCBieSB3aGljaCBhIGNsaWVudCBpbmRpY2F0ZXNcbiAgICAqIHdoaWNoIGhvc3RuYW1lIGl0IGlzIGF0dGVtcHRpbmcgdG8gY29ubmVjdCB0byBhdCB0aGUgc3RhcnQgb2YgdGhlIGhhbmRzaGFraW5nIHByb2Nlc3MuIFRoaXMgYWxsb3dzIGEgc2VydmVyIHRvIHByZXNlbnRcbiAgICAqIG11bHRpcGxlIGNlcnRpZmljYXRlcyBvbiB0aGUgc2FtZSBJUCBhZGRyZXNzIGFuZCBUQ1AgcG9ydCBudW1iZXIgYW5kIGhlbmNlIGFsbG93cyBtdWx0aXBsZSBzZWN1cmUgKEhUVFBTKSB3ZWJzaXRlc1xuICAgICogKG9yIGFueSBvdGhlciBzZXJ2aWNlIG92ZXIgVExTKSB0byBiZSBzZXJ2ZWQgYnkgdGhlIHNhbWUgSVAgYWRkcmVzcyB3aXRob3V0IHJlcXVpcmluZyBhbGwgdGhvc2Ugc2l0ZXMgdG8gdXNlIHRoZSBzYW1lIGNlcnRpZmljYXRlLlxuICAgICpcbiAgICAqIENsb3VkRnJvbnQgY2FuIHVzZSBTTkkgdG8gaG9zdCBtdWx0aXBsZSBkaXN0cmlidXRpb25zIG9uIHRoZSBzYW1lIElQIC0gd2hpY2ggYSBsYXJnZSBtYWpvcml0eSBvZiBjbGllbnRzIHdpbGwgc3VwcG9ydC5cbiAgICAqXG4gICAgKiBJZiB5b3VyIGNsaWVudHMgY2Fubm90IHN1cHBvcnQgU05JIGhvd2V2ZXIgLSBDbG91ZEZyb250IGNhbiB1c2UgZGVkaWNhdGVkIElQcyBmb3IgeW91ciBkaXN0cmlidXRpb24gLSBidXQgdGhlcmUgaXMgYSBwcm9yYXRlZCBtb250aGx5IGNoYXJnZSBmb3JcbiAgICAqIHVzaW5nIHRoaXMgZmVhdHVyZS4gQnkgZGVmYXVsdCwgd2UgdXNlIFNOSSAtIGJ1dCB5b3UgY2FuIG9wdGlvbmFsbHkgZW5hYmxlIGRlZGljYXRlZCBJUHMgKFZJUCkuXG4gICAgKlxuICAgICogU2VlIHRoZSBDbG91ZEZyb250IFNTTCBmb3IgbW9yZSBkZXRhaWxzIGFib3V0IHByaWNpbmcgOiBodHRwczovL2F3cy5hbWF6b24uY29tL2Nsb3VkZnJvbnQvY3VzdG9tLXNzbC1kb21haW5zL1xuICAgICpcbiAgICAqIEBkZWZhdWx0IFNTTE1ldGhvZC5TTklcbiAgICAqL1xuICByZWFkb25seSBzc2xTdXBwb3J0TWV0aG9kPzogU1NMTWV0aG9kO1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gd2l0aCBhc3NvY2lhdGVkIG9yaWdpbihzKSBhbmQgY2FjaGluZyBiZWhhdmlvcihzKS5cbiAqL1xuZXhwb3J0IGNsYXNzIERpc3RyaWJ1dGlvbiBleHRlbmRzIFJlc291cmNlIGltcGxlbWVudHMgSURpc3RyaWJ1dGlvbiB7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBEaXN0cmlidXRpb24gY29uc3RydWN0IHRoYXQgcmVwcmVzZW50cyBhbiBleHRlcm5hbCAoaW1wb3J0ZWQpIGRpc3RyaWJ1dGlvbi5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbURpc3RyaWJ1dGlvbkF0dHJpYnV0ZXMoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgYXR0cnM6IERpc3RyaWJ1dGlvbkF0dHJpYnV0ZXMpOiBJRGlzdHJpYnV0aW9uIHtcbiAgICByZXR1cm4gbmV3IGNsYXNzIGV4dGVuZHMgUmVzb3VyY2UgaW1wbGVtZW50cyBJRGlzdHJpYnV0aW9uIHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBkb21haW5OYW1lOiBzdHJpbmc7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZGlzdHJpYnV0aW9uRG9tYWluTmFtZTogc3RyaW5nO1xuICAgICAgcHVibGljIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbklkOiBzdHJpbmc7XG5cbiAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgICAgICB0aGlzLmRvbWFpbk5hbWUgPSBhdHRycy5kb21haW5OYW1lO1xuICAgICAgICB0aGlzLmRpc3RyaWJ1dGlvbkRvbWFpbk5hbWUgPSBhdHRycy5kb21haW5OYW1lO1xuICAgICAgICB0aGlzLmRpc3RyaWJ1dGlvbklkID0gYXR0cnMuZGlzdHJpYnV0aW9uSWQ7XG4gICAgICB9XG4gICAgfSgpO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IGRvbWFpbk5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbkRvbWFpbk5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbklkOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBkZWZhdWx0QmVoYXZpb3I6IENhY2hlQmVoYXZpb3I7XG4gIHByaXZhdGUgcmVhZG9ubHkgYWRkaXRpb25hbEJlaGF2aW9yczogQ2FjaGVCZWhhdmlvcltdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgYm91bmRPcmlnaW5zOiBCb3VuZE9yaWdpbltdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgb3JpZ2luR3JvdXBzOiBDZm5EaXN0cmlidXRpb24uT3JpZ2luR3JvdXBQcm9wZXJ0eVtdID0gW107XG5cbiAgcHJpdmF0ZSByZWFkb25seSBlcnJvclJlc3BvbnNlczogRXJyb3JSZXNwb25zZVtdO1xuICBwcml2YXRlIHJlYWRvbmx5IGNlcnRpZmljYXRlPzogYWNtLklDZXJ0aWZpY2F0ZTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogRGlzdHJpYnV0aW9uUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgaWYgKHByb3BzLmNlcnRpZmljYXRlKSB7XG4gICAgICBjb25zdCBjZXJ0aWZpY2F0ZVJlZ2lvbiA9IFN0YWNrLm9mKHRoaXMpLnNwbGl0QXJuKHByb3BzLmNlcnRpZmljYXRlLmNlcnRpZmljYXRlQXJuLCBBcm5Gb3JtYXQuU0xBU0hfUkVTT1VSQ0VfTkFNRSkucmVnaW9uO1xuICAgICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQoY2VydGlmaWNhdGVSZWdpb24pICYmIGNlcnRpZmljYXRlUmVnaW9uICE9PSAndXMtZWFzdC0xJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERpc3RyaWJ1dGlvbiBjZXJ0aWZpY2F0ZXMgbXVzdCBiZSBpbiB0aGUgdXMtZWFzdC0xIHJlZ2lvbiBhbmQgdGhlIGNlcnRpZmljYXRlIHlvdSBwcm92aWRlZCBpcyBpbiAke2NlcnRpZmljYXRlUmVnaW9ufS5gKTtcbiAgICAgIH1cblxuICAgICAgaWYgKChwcm9wcy5kb21haW5OYW1lcyA/PyBbXSkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTXVzdCBzcGVjaWZ5IGF0IGxlYXN0IG9uZSBkb21haW4gbmFtZSB0byB1c2UgYSBjZXJ0aWZpY2F0ZSB3aXRoIGEgZGlzdHJpYnV0aW9uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgb3JpZ2luSWQgPSB0aGlzLmFkZE9yaWdpbihwcm9wcy5kZWZhdWx0QmVoYXZpb3Iub3JpZ2luKTtcbiAgICB0aGlzLmRlZmF1bHRCZWhhdmlvciA9IG5ldyBDYWNoZUJlaGF2aW9yKG9yaWdpbklkLCB7IHBhdGhQYXR0ZXJuOiAnKicsIC4uLnByb3BzLmRlZmF1bHRCZWhhdmlvciB9KTtcbiAgICBpZiAocHJvcHMuYWRkaXRpb25hbEJlaGF2aW9ycykge1xuICAgICAgT2JqZWN0LmVudHJpZXMocHJvcHMuYWRkaXRpb25hbEJlaGF2aW9ycykuZm9yRWFjaCgoW3BhdGhQYXR0ZXJuLCBiZWhhdmlvck9wdGlvbnNdKSA9PiB7XG4gICAgICAgIHRoaXMuYWRkQmVoYXZpb3IocGF0aFBhdHRlcm4sIGJlaGF2aW9yT3B0aW9ucy5vcmlnaW4sIGJlaGF2aW9yT3B0aW9ucyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmNlcnRpZmljYXRlID0gcHJvcHMuY2VydGlmaWNhdGU7XG4gICAgdGhpcy5lcnJvclJlc3BvbnNlcyA9IHByb3BzLmVycm9yUmVzcG9uc2VzID8/IFtdO1xuXG4gICAgLy8gQ29tbWVudHMgaGF2ZSBhbiB1bmRvY3VtZW50ZWQgbGltaXQgb2YgMTI4IGNoYXJhY3RlcnNcbiAgICBjb25zdCB0cmltbWVkQ29tbWVudCA9XG4gICAgICBwcm9wcy5jb21tZW50ICYmIHByb3BzLmNvbW1lbnQubGVuZ3RoID4gMTI4XG4gICAgICAgID8gYCR7cHJvcHMuY29tbWVudC5zbGljZSgwLCAxMjggLSAzKX0uLi5gXG4gICAgICAgIDogcHJvcHMuY29tbWVudDtcblxuICAgIGNvbnN0IGRpc3RyaWJ1dGlvbiA9IG5ldyBDZm5EaXN0cmlidXRpb24odGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgZGlzdHJpYnV0aW9uQ29uZmlnOiB7XG4gICAgICAgIGVuYWJsZWQ6IHByb3BzLmVuYWJsZWQgPz8gdHJ1ZSxcbiAgICAgICAgb3JpZ2luczogTGF6eS5hbnkoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLnJlbmRlck9yaWdpbnMoKSB9KSxcbiAgICAgICAgb3JpZ2luR3JvdXBzOiBMYXp5LmFueSh7IHByb2R1Y2U6ICgpID0+IHRoaXMucmVuZGVyT3JpZ2luR3JvdXBzKCkgfSksXG4gICAgICAgIGRlZmF1bHRDYWNoZUJlaGF2aW9yOiB0aGlzLmRlZmF1bHRCZWhhdmlvci5fcmVuZGVyQmVoYXZpb3IoKSxcbiAgICAgICAgYWxpYXNlczogcHJvcHMuZG9tYWluTmFtZXMsXG4gICAgICAgIGNhY2hlQmVoYXZpb3JzOiBMYXp5LmFueSh7IHByb2R1Y2U6ICgpID0+IHRoaXMucmVuZGVyQ2FjaGVCZWhhdmlvcnMoKSB9KSxcbiAgICAgICAgY29tbWVudDogdHJpbW1lZENvbW1lbnQsXG4gICAgICAgIGN1c3RvbUVycm9yUmVzcG9uc2VzOiB0aGlzLnJlbmRlckVycm9yUmVzcG9uc2VzKCksXG4gICAgICAgIGRlZmF1bHRSb290T2JqZWN0OiBwcm9wcy5kZWZhdWx0Um9vdE9iamVjdCxcbiAgICAgICAgaHR0cFZlcnNpb246IHByb3BzLmh0dHBWZXJzaW9uID8/IEh0dHBWZXJzaW9uLkhUVFAyLFxuICAgICAgICBpcHY2RW5hYmxlZDogcHJvcHMuZW5hYmxlSXB2NiA/PyB0cnVlLFxuICAgICAgICBsb2dnaW5nOiB0aGlzLnJlbmRlckxvZ2dpbmcocHJvcHMpLFxuICAgICAgICBwcmljZUNsYXNzOiBwcm9wcy5wcmljZUNsYXNzID8/IHVuZGVmaW5lZCxcbiAgICAgICAgcmVzdHJpY3Rpb25zOiB0aGlzLnJlbmRlclJlc3RyaWN0aW9ucyhwcm9wcy5nZW9SZXN0cmljdGlvbiksXG4gICAgICAgIHZpZXdlckNlcnRpZmljYXRlOiB0aGlzLmNlcnRpZmljYXRlID8gdGhpcy5yZW5kZXJWaWV3ZXJDZXJ0aWZpY2F0ZSh0aGlzLmNlcnRpZmljYXRlLFxuICAgICAgICAgIHByb3BzLm1pbmltdW1Qcm90b2NvbFZlcnNpb24sIHByb3BzLnNzbFN1cHBvcnRNZXRob2QpIDogdW5kZWZpbmVkLFxuICAgICAgICB3ZWJBY2xJZDogcHJvcHMud2ViQWNsSWQsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5kb21haW5OYW1lID0gZGlzdHJpYnV0aW9uLmF0dHJEb21haW5OYW1lO1xuICAgIHRoaXMuZGlzdHJpYnV0aW9uRG9tYWluTmFtZSA9IGRpc3RyaWJ1dGlvbi5hdHRyRG9tYWluTmFtZTtcbiAgICB0aGlzLmRpc3RyaWJ1dGlvbklkID0gZGlzdHJpYnV0aW9uLnJlZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgbmV3IGJlaGF2aW9yIHRvIHRoaXMgZGlzdHJpYnV0aW9uIGZvciB0aGUgZ2l2ZW4gcGF0aFBhdHRlcm4uXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoUGF0dGVybiB0aGUgcGF0aCBwYXR0ZXJuIChlLmcuLCAnaW1hZ2VzLyonKSB0aGF0IHNwZWNpZmllcyB3aGljaCByZXF1ZXN0cyB0byBhcHBseSB0aGUgYmVoYXZpb3IgdG8uXG4gICAqIEBwYXJhbSBvcmlnaW4gdGhlIG9yaWdpbiB0byB1c2UgZm9yIHRoaXMgYmVoYXZpb3JcbiAgICogQHBhcmFtIGJlaGF2aW9yT3B0aW9ucyB0aGUgb3B0aW9ucyBmb3IgdGhlIGJlaGF2aW9yIGF0IHRoaXMgcGF0aC5cbiAgICovXG4gIHB1YmxpYyBhZGRCZWhhdmlvcihwYXRoUGF0dGVybjogc3RyaW5nLCBvcmlnaW46IElPcmlnaW4sIGJlaGF2aW9yT3B0aW9uczogQWRkQmVoYXZpb3JPcHRpb25zID0ge30pIHtcbiAgICBpZiAocGF0aFBhdHRlcm4gPT09ICcqJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IHRoZSBkZWZhdWx0IGJlaGF2aW9yIGNhbiBoYXZlIGEgcGF0aCBwYXR0ZXJuIG9mIFxcJypcXCcnKTtcbiAgICB9XG4gICAgY29uc3Qgb3JpZ2luSWQgPSB0aGlzLmFkZE9yaWdpbihvcmlnaW4pO1xuICAgIHRoaXMuYWRkaXRpb25hbEJlaGF2aW9ycy5wdXNoKG5ldyBDYWNoZUJlaGF2aW9yKG9yaWdpbklkLCB7IHBhdGhQYXR0ZXJuLCAuLi5iZWhhdmlvck9wdGlvbnMgfSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRPcmlnaW4ob3JpZ2luOiBJT3JpZ2luLCBpc0ZhaWxvdmVyT3JpZ2luOiBib29sZWFuID0gZmFsc2UpOiBzdHJpbmcge1xuICAgIGNvbnN0IE9SSUdJTl9JRF9NQVhfTEVOR1RIID0gMTI4O1xuXG4gICAgY29uc3QgZXhpc3RpbmdPcmlnaW4gPSB0aGlzLmJvdW5kT3JpZ2lucy5maW5kKGJvdW5kT3JpZ2luID0+IGJvdW5kT3JpZ2luLm9yaWdpbiA9PT0gb3JpZ2luKTtcbiAgICBpZiAoZXhpc3RpbmdPcmlnaW4pIHtcbiAgICAgIHJldHVybiBleGlzdGluZ09yaWdpbi5vcmlnaW5Hcm91cElkID8/IGV4aXN0aW5nT3JpZ2luLm9yaWdpbklkO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBvcmlnaW5JbmRleCA9IHRoaXMuYm91bmRPcmlnaW5zLmxlbmd0aCArIDE7XG4gICAgICBjb25zdCBzY29wZSA9IG5ldyBDb3JlQ29uc3RydWN0KHRoaXMsIGBPcmlnaW4ke29yaWdpbkluZGV4fWApO1xuICAgICAgY29uc3Qgb3JpZ2luSWQgPSBOYW1lcy51bmlxdWVJZChzY29wZSkuc2xpY2UoLU9SSUdJTl9JRF9NQVhfTEVOR1RIKTtcbiAgICAgIGNvbnN0IG9yaWdpbkJpbmRDb25maWcgPSBvcmlnaW4uYmluZChzY29wZSwgeyBvcmlnaW5JZCB9KTtcbiAgICAgIGlmICghb3JpZ2luQmluZENvbmZpZy5mYWlsb3ZlckNvbmZpZykge1xuICAgICAgICB0aGlzLmJvdW5kT3JpZ2lucy5wdXNoKHsgb3JpZ2luLCBvcmlnaW5JZCwgLi4ub3JpZ2luQmluZENvbmZpZyB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpc0ZhaWxvdmVyT3JpZ2luKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBbiBPcmlnaW4gY2Fubm90IHVzZSBhbiBPcmlnaW4gd2l0aCBpdHMgb3duIGZhaWxvdmVyIGNvbmZpZ3VyYXRpb24gYXMgaXRzIGZhbGxiYWNrIG9yaWdpbiEnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBncm91cEluZGV4ID0gdGhpcy5vcmlnaW5Hcm91cHMubGVuZ3RoICsgMTtcbiAgICAgICAgY29uc3Qgb3JpZ2luR3JvdXBJZCA9IE5hbWVzLnVuaXF1ZUlkKG5ldyBDb3JlQ29uc3RydWN0KHRoaXMsIGBPcmlnaW5Hcm91cCR7Z3JvdXBJbmRleH1gKSkuc2xpY2UoLU9SSUdJTl9JRF9NQVhfTEVOR1RIKTtcbiAgICAgICAgdGhpcy5ib3VuZE9yaWdpbnMucHVzaCh7IG9yaWdpbiwgb3JpZ2luSWQsIG9yaWdpbkdyb3VwSWQsIC4uLm9yaWdpbkJpbmRDb25maWcgfSk7XG5cbiAgICAgICAgY29uc3QgZmFpbG92ZXJPcmlnaW5JZCA9IHRoaXMuYWRkT3JpZ2luKG9yaWdpbkJpbmRDb25maWcuZmFpbG92ZXJDb25maWcuZmFpbG92ZXJPcmlnaW4sIHRydWUpO1xuICAgICAgICB0aGlzLmFkZE9yaWdpbkdyb3VwKG9yaWdpbkdyb3VwSWQsIG9yaWdpbkJpbmRDb25maWcuZmFpbG92ZXJDb25maWcuc3RhdHVzQ29kZXMsIG9yaWdpbklkLCBmYWlsb3Zlck9yaWdpbklkKTtcbiAgICAgICAgcmV0dXJuIG9yaWdpbkdyb3VwSWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gb3JpZ2luSWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRPcmlnaW5Hcm91cChvcmlnaW5Hcm91cElkOiBzdHJpbmcsIHN0YXR1c0NvZGVzOiBudW1iZXJbXSB8IHVuZGVmaW5lZCwgb3JpZ2luSWQ6IHN0cmluZywgZmFpbG92ZXJPcmlnaW5JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgc3RhdHVzQ29kZXMgPSBzdGF0dXNDb2RlcyA/PyBbNTAwLCA1MDIsIDUwMywgNTA0XTtcbiAgICBpZiAoc3RhdHVzQ29kZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZhbGxiYWNrU3RhdHVzQ29kZXMgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgfVxuICAgIHRoaXMub3JpZ2luR3JvdXBzLnB1c2goe1xuICAgICAgZmFpbG92ZXJDcml0ZXJpYToge1xuICAgICAgICBzdGF0dXNDb2Rlczoge1xuICAgICAgICAgIGl0ZW1zOiBzdGF0dXNDb2RlcyxcbiAgICAgICAgICBxdWFudGl0eTogc3RhdHVzQ29kZXMubGVuZ3RoLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGlkOiBvcmlnaW5Hcm91cElkLFxuICAgICAgbWVtYmVyczoge1xuICAgICAgICBpdGVtczogW1xuICAgICAgICAgIHsgb3JpZ2luSWQgfSxcbiAgICAgICAgICB7IG9yaWdpbklkOiBmYWlsb3Zlck9yaWdpbklkIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHF1YW50aXR5OiAyLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyT3JpZ2lucygpOiBDZm5EaXN0cmlidXRpb24uT3JpZ2luUHJvcGVydHlbXSB7XG4gICAgY29uc3QgcmVuZGVyZWRPcmlnaW5zOiBDZm5EaXN0cmlidXRpb24uT3JpZ2luUHJvcGVydHlbXSA9IFtdO1xuICAgIHRoaXMuYm91bmRPcmlnaW5zLmZvckVhY2goYm91bmRPcmlnaW4gPT4ge1xuICAgICAgaWYgKGJvdW5kT3JpZ2luLm9yaWdpblByb3BlcnR5KSB7XG4gICAgICAgIHJlbmRlcmVkT3JpZ2lucy5wdXNoKGJvdW5kT3JpZ2luLm9yaWdpblByb3BlcnR5KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVuZGVyZWRPcmlnaW5zO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJPcmlnaW5Hcm91cHMoKTogQ2ZuRGlzdHJpYnV0aW9uLk9yaWdpbkdyb3Vwc1Byb3BlcnR5IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5vcmlnaW5Hcm91cHMubGVuZ3RoID09PSAwXG4gICAgICA/IHVuZGVmaW5lZFxuICAgICAgOiB7XG4gICAgICAgIGl0ZW1zOiB0aGlzLm9yaWdpbkdyb3VwcyxcbiAgICAgICAgcXVhbnRpdHk6IHRoaXMub3JpZ2luR3JvdXBzLmxlbmd0aCxcbiAgICAgIH07XG4gIH1cblxuICBwcml2YXRlIHJlbmRlckNhY2hlQmVoYXZpb3JzKCk6IENmbkRpc3RyaWJ1dGlvbi5DYWNoZUJlaGF2aW9yUHJvcGVydHlbXSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRoaXMuYWRkaXRpb25hbEJlaGF2aW9ycy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICAgIHJldHVybiB0aGlzLmFkZGl0aW9uYWxCZWhhdmlvcnMubWFwKGJlaGF2aW9yID0+IGJlaGF2aW9yLl9yZW5kZXJCZWhhdmlvcigpKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyRXJyb3JSZXNwb25zZXMoKTogQ2ZuRGlzdHJpYnV0aW9uLkN1c3RvbUVycm9yUmVzcG9uc2VQcm9wZXJ0eVtdIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy5lcnJvclJlc3BvbnNlcy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuXG4gICAgcmV0dXJuIHRoaXMuZXJyb3JSZXNwb25zZXMubWFwKGVycm9yQ29uZmlnID0+IHtcbiAgICAgIGlmICghZXJyb3JDb25maWcucmVzcG9uc2VIdHRwU3RhdHVzICYmICFlcnJvckNvbmZpZy50dGwgJiYgIWVycm9yQ29uZmlnLnJlc3BvbnNlUGFnZVBhdGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIGN1c3RvbSBlcnJvciByZXNwb25zZSB3aXRob3V0IGVpdGhlciBhIFxcJ3Jlc3BvbnNlSHR0cFN0YXR1c1xcJywgXFwndHRsXFwnIG9yIFxcJ3Jlc3BvbnNlUGFnZVBhdGhcXCcgaXMgbm90IHZhbGlkLicpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBlcnJvckNhY2hpbmdNaW5UdGw6IGVycm9yQ29uZmlnLnR0bD8udG9TZWNvbmRzKCksXG4gICAgICAgIGVycm9yQ29kZTogZXJyb3JDb25maWcuaHR0cFN0YXR1cyxcbiAgICAgICAgcmVzcG9uc2VDb2RlOiBlcnJvckNvbmZpZy5yZXNwb25zZVBhZ2VQYXRoXG4gICAgICAgICAgPyBlcnJvckNvbmZpZy5yZXNwb25zZUh0dHBTdGF0dXMgPz8gZXJyb3JDb25maWcuaHR0cFN0YXR1c1xuICAgICAgICAgIDogZXJyb3JDb25maWcucmVzcG9uc2VIdHRwU3RhdHVzLFxuICAgICAgICByZXNwb25zZVBhZ2VQYXRoOiBlcnJvckNvbmZpZy5yZXNwb25zZVBhZ2VQYXRoLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyTG9nZ2luZyhwcm9wczogRGlzdHJpYnV0aW9uUHJvcHMpOiBDZm5EaXN0cmlidXRpb24uTG9nZ2luZ1Byb3BlcnR5IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXByb3BzLmVuYWJsZUxvZ2dpbmcgJiYgIXByb3BzLmxvZ0J1Y2tldCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9XG4gICAgaWYgKHByb3BzLmVuYWJsZUxvZ2dpbmcgPT09IGZhbHNlICYmIHByb3BzLmxvZ0J1Y2tldCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBsaWNpdGx5IGRpc2FibGVkIGxvZ2dpbmcgYnV0IHByb3ZpZGVkIGEgbG9nZ2luZyBidWNrZXQuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgYnVja2V0ID0gcHJvcHMubG9nQnVja2V0ID8/IG5ldyBzMy5CdWNrZXQodGhpcywgJ0xvZ2dpbmdCdWNrZXQnLCB7XG4gICAgICBlbmNyeXB0aW9uOiBzMy5CdWNrZXRFbmNyeXB0aW9uLlMzX01BTkFHRUQsXG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGJ1Y2tldDogYnVja2V0LmJ1Y2tldFJlZ2lvbmFsRG9tYWluTmFtZSxcbiAgICAgIGluY2x1ZGVDb29raWVzOiBwcm9wcy5sb2dJbmNsdWRlc0Nvb2tpZXMsXG4gICAgICBwcmVmaXg6IHByb3BzLmxvZ0ZpbGVQcmVmaXgsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyUmVzdHJpY3Rpb25zKGdlb1Jlc3RyaWN0aW9uPzogR2VvUmVzdHJpY3Rpb24pIHtcbiAgICByZXR1cm4gZ2VvUmVzdHJpY3Rpb24gPyB7XG4gICAgICBnZW9SZXN0cmljdGlvbjoge1xuICAgICAgICByZXN0cmljdGlvblR5cGU6IGdlb1Jlc3RyaWN0aW9uLnJlc3RyaWN0aW9uVHlwZSxcbiAgICAgICAgbG9jYXRpb25zOiBnZW9SZXN0cmljdGlvbi5sb2NhdGlvbnMsXG4gICAgICB9LFxuICAgIH0gOiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlclZpZXdlckNlcnRpZmljYXRlKGNlcnRpZmljYXRlOiBhY20uSUNlcnRpZmljYXRlLFxuICAgIG1pbmltdW1Qcm90b2NvbFZlcnNpb25Qcm9wPzogU2VjdXJpdHlQb2xpY3lQcm90b2NvbCwgc3NsU3VwcG9ydE1ldGhvZFByb3A/OiBTU0xNZXRob2QpOiBDZm5EaXN0cmlidXRpb24uVmlld2VyQ2VydGlmaWNhdGVQcm9wZXJ0eSB7XG5cbiAgICBjb25zdCBkZWZhdWx0VmVyc2lvbiA9IEZlYXR1cmVGbGFncy5vZih0aGlzKS5pc0VuYWJsZWQoQ0xPVURGUk9OVF9ERUZBVUxUX1NFQ1VSSVRZX1BPTElDWV9UTFNfVjFfMl8yMDIxKVxuICAgICAgPyBTZWN1cml0eVBvbGljeVByb3RvY29sLlRMU19WMV8yXzIwMjEgOiBTZWN1cml0eVBvbGljeVByb3RvY29sLlRMU19WMV8yXzIwMTk7XG4gICAgY29uc3QgbWluaW11bVByb3RvY29sVmVyc2lvbiA9IG1pbmltdW1Qcm90b2NvbFZlcnNpb25Qcm9wID8/IGRlZmF1bHRWZXJzaW9uO1xuICAgIGNvbnN0IHNzbFN1cHBvcnRNZXRob2QgPSBzc2xTdXBwb3J0TWV0aG9kUHJvcCA/PyBTU0xNZXRob2QuU05JO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFjbUNlcnRpZmljYXRlQXJuOiBjZXJ0aWZpY2F0ZS5jZXJ0aWZpY2F0ZUFybixcbiAgICAgIG1pbmltdW1Qcm90b2NvbFZlcnNpb246IG1pbmltdW1Qcm90b2NvbFZlcnNpb24sXG4gICAgICBzc2xTdXBwb3J0TWV0aG9kOiBzc2xTdXBwb3J0TWV0aG9kLFxuICAgIH07XG4gIH1cbn1cblxuLyoqIE1heGltdW0gSFRUUCB2ZXJzaW9uIHRvIHN1cHBvcnQgKi9cbmV4cG9ydCBlbnVtIEh0dHBWZXJzaW9uIHtcbiAgLyoqIEhUVFAgMS4xICovXG4gIEhUVFAxXzEgPSAnaHR0cDEuMScsXG4gIC8qKiBIVFRQIDIgKi9cbiAgSFRUUDIgPSAnaHR0cDInXG59XG5cbi8qKlxuICogVGhlIHByaWNlIGNsYXNzIGRldGVybWluZXMgaG93IG1hbnkgZWRnZSBsb2NhdGlvbnMgQ2xvdWRGcm9udCB3aWxsIHVzZSBmb3IgeW91ciBkaXN0cmlidXRpb24uXG4gKiBTZWUgaHR0cHM6Ly9hd3MuYW1hem9uLmNvbS9jbG91ZGZyb250L3ByaWNpbmcvIGZvciBmdWxsIGxpc3Qgb2Ygc3VwcG9ydGVkIHJlZ2lvbnMuXG4gKi9cbmV4cG9ydCBlbnVtIFByaWNlQ2xhc3Mge1xuICAvKiogVVNBLCBDYW5hZGEsIEV1cm9wZSwgJiBJc3JhZWwgKi9cbiAgUFJJQ0VfQ0xBU1NfMTAwID0gJ1ByaWNlQ2xhc3NfMTAwJyxcbiAgLyoqIFBSSUNFX0NMQVNTXzEwMCArIFNvdXRoIEFmcmljYSwgS2VueWEsIE1pZGRsZSBFYXN0LCBKYXBhbiwgU2luZ2Fwb3JlLCBTb3V0aCBLb3JlYSwgVGFpd2FuLCBIb25nIEtvbmcsICYgUGhpbGlwcGluZXMgKi9cbiAgUFJJQ0VfQ0xBU1NfMjAwID0gJ1ByaWNlQ2xhc3NfMjAwJyxcbiAgLyoqIEFsbCBsb2NhdGlvbnMgKi9cbiAgUFJJQ0VfQ0xBU1NfQUxMID0gJ1ByaWNlQ2xhc3NfQWxsJ1xufVxuXG4vKipcbiAqIEhvdyBIVFRQcyBzaG91bGQgYmUgaGFuZGxlZCB3aXRoIHlvdXIgZGlzdHJpYnV0aW9uLlxuICovXG5leHBvcnQgZW51bSBWaWV3ZXJQcm90b2NvbFBvbGljeSB7XG4gIC8qKiBIVFRQUyBvbmx5ICovXG4gIEhUVFBTX09OTFkgPSAnaHR0cHMtb25seScsXG4gIC8qKiBXaWxsIHJlZGlyZWN0IEhUVFAgcmVxdWVzdHMgdG8gSFRUUFMgKi9cbiAgUkVESVJFQ1RfVE9fSFRUUFMgPSAncmVkaXJlY3QtdG8taHR0cHMnLFxuICAvKiogQm90aCBIVFRQIGFuZCBIVFRQUyBzdXBwb3J0ZWQgKi9cbiAgQUxMT1dfQUxMID0gJ2FsbG93LWFsbCdcbn1cblxuLyoqXG4gKiBEZWZpbmVzIHdoYXQgcHJvdG9jb2xzIENsb3VkRnJvbnQgd2lsbCB1c2UgdG8gY29ubmVjdCB0byBhbiBvcmlnaW4uXG4gKi9cbmV4cG9ydCBlbnVtIE9yaWdpblByb3RvY29sUG9saWN5IHtcbiAgLyoqIENvbm5lY3Qgb24gSFRUUCBvbmx5ICovXG4gIEhUVFBfT05MWSA9ICdodHRwLW9ubHknLFxuICAvKiogQ29ubmVjdCB3aXRoIHRoZSBzYW1lIHByb3RvY29sIGFzIHRoZSB2aWV3ZXIgKi9cbiAgTUFUQ0hfVklFV0VSID0gJ21hdGNoLXZpZXdlcicsXG4gIC8qKiBDb25uZWN0IG9uIEhUVFBTIG9ubHkgKi9cbiAgSFRUUFNfT05MWSA9ICdodHRwcy1vbmx5Jyxcbn1cblxuLyoqXG4gKiBUaGUgU1NMIG1ldGhvZCBDbG91ZEZyb250IHdpbGwgdXNlIGZvciB5b3VyIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiBTZXJ2ZXIgTmFtZSBJbmRpY2F0aW9uIChTTkkpIC0gaXMgYW4gZXh0ZW5zaW9uIHRvIHRoZSBUTFMgY29tcHV0ZXIgbmV0d29ya2luZyBwcm90b2NvbCBieSB3aGljaCBhIGNsaWVudCBpbmRpY2F0ZXNcbiAqICB3aGljaCBob3N0bmFtZSBpdCBpcyBhdHRlbXB0aW5nIHRvIGNvbm5lY3QgdG8gYXQgdGhlIHN0YXJ0IG9mIHRoZSBoYW5kc2hha2luZyBwcm9jZXNzLiBUaGlzIGFsbG93cyBhIHNlcnZlciB0byBwcmVzZW50XG4gKiAgbXVsdGlwbGUgY2VydGlmaWNhdGVzIG9uIHRoZSBzYW1lIElQIGFkZHJlc3MgYW5kIFRDUCBwb3J0IG51bWJlciBhbmQgaGVuY2UgYWxsb3dzIG11bHRpcGxlIHNlY3VyZSAoSFRUUFMpIHdlYnNpdGVzXG4gKiAob3IgYW55IG90aGVyIHNlcnZpY2Ugb3ZlciBUTFMpIHRvIGJlIHNlcnZlZCBieSB0aGUgc2FtZSBJUCBhZGRyZXNzIHdpdGhvdXQgcmVxdWlyaW5nIGFsbCB0aG9zZSBzaXRlcyB0byB1c2UgdGhlIHNhbWUgY2VydGlmaWNhdGUuXG4gKlxuICogQ2xvdWRGcm9udCBjYW4gdXNlIFNOSSB0byBob3N0IG11bHRpcGxlIGRpc3RyaWJ1dGlvbnMgb24gdGhlIHNhbWUgSVAgLSB3aGljaCBhIGxhcmdlIG1ham9yaXR5IG9mIGNsaWVudHMgd2lsbCBzdXBwb3J0LlxuICpcbiAqIElmIHlvdXIgY2xpZW50cyBjYW5ub3Qgc3VwcG9ydCBTTkkgaG93ZXZlciAtIENsb3VkRnJvbnQgY2FuIHVzZSBkZWRpY2F0ZWQgSVBzIGZvciB5b3VyIGRpc3RyaWJ1dGlvbiAtIGJ1dCB0aGVyZSBpcyBhIHByb3JhdGVkIG1vbnRobHkgY2hhcmdlIGZvclxuICogdXNpbmcgdGhpcyBmZWF0dXJlLiBCeSBkZWZhdWx0LCB3ZSB1c2UgU05JIC0gYnV0IHlvdSBjYW4gb3B0aW9uYWxseSBlbmFibGUgZGVkaWNhdGVkIElQcyAoVklQKS5cbiAqXG4gKiBTZWUgdGhlIENsb3VkRnJvbnQgU1NMIGZvciBtb3JlIGRldGFpbHMgYWJvdXQgcHJpY2luZyA6IGh0dHBzOi8vYXdzLmFtYXpvbi5jb20vY2xvdWRmcm9udC9jdXN0b20tc3NsLWRvbWFpbnMvXG4gKlxuICovXG5leHBvcnQgZW51bSBTU0xNZXRob2Qge1xuICBTTkkgPSAnc25pLW9ubHknLFxuICBWSVAgPSAndmlwJ1xufVxuXG4vKipcbiAqIFRoZSBtaW5pbXVtIHZlcnNpb24gb2YgdGhlIFNTTCBwcm90b2NvbCB0aGF0IHlvdSB3YW50IENsb3VkRnJvbnQgdG8gdXNlIGZvciBIVFRQUyBjb25uZWN0aW9ucy5cbiAqIENsb3VkRnJvbnQgc2VydmVzIHlvdXIgb2JqZWN0cyBvbmx5IHRvIGJyb3dzZXJzIG9yIGRldmljZXMgdGhhdCBzdXBwb3J0IGF0IGxlYXN0IHRoZSBTU0wgdmVyc2lvbiB0aGF0IHlvdSBzcGVjaWZ5LlxuICovXG5leHBvcnQgZW51bSBTZWN1cml0eVBvbGljeVByb3RvY29sIHtcbiAgU1NMX1YzID0gJ1NTTHYzJyxcbiAgVExTX1YxID0gJ1RMU3YxJyxcbiAgVExTX1YxXzIwMTYgPSAnVExTdjFfMjAxNicsXG4gIFRMU19WMV8xXzIwMTYgPSAnVExTdjEuMV8yMDE2JyxcbiAgVExTX1YxXzJfMjAxOCA9ICdUTFN2MS4yXzIwMTgnLFxuICBUTFNfVjFfMl8yMDE5ID0gJ1RMU3YxLjJfMjAxOScsXG4gIFRMU19WMV8yXzIwMjEgPSAnVExTdjEuMl8yMDIxJ1xufVxuXG4vKipcbiAqIFRoZSBIVFRQIG1ldGhvZHMgdGhhdCB0aGUgQmVoYXZpb3Igd2lsbCBhY2NlcHQgcmVxdWVzdHMgb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBBbGxvd2VkTWV0aG9kcyB7XG4gIC8qKiBIRUFEIGFuZCBHRVQgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBBTExPV19HRVRfSEVBRCA9IG5ldyBBbGxvd2VkTWV0aG9kcyhbJ0dFVCcsICdIRUFEJ10pO1xuICAvKiogSEVBRCwgR0VULCBhbmQgT1BUSU9OUyAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEFMTE9XX0dFVF9IRUFEX09QVElPTlMgPSBuZXcgQWxsb3dlZE1ldGhvZHMoWydHRVQnLCAnSEVBRCcsICdPUFRJT05TJ10pO1xuICAvKiogQWxsIHN1cHBvcnRlZCBIVFRQIG1ldGhvZHMgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBBTExPV19BTEwgPSBuZXcgQWxsb3dlZE1ldGhvZHMoWydHRVQnLCAnSEVBRCcsICdPUFRJT05TJywgJ1BVVCcsICdQQVRDSCcsICdQT1NUJywgJ0RFTEVURSddKTtcblxuICAvKiogSFRUUCBtZXRob2RzIHN1cHBvcnRlZCAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbWV0aG9kczogc3RyaW5nW107XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihtZXRob2RzOiBzdHJpbmdbXSkgeyB0aGlzLm1ldGhvZHMgPSBtZXRob2RzOyB9XG59XG5cbi8qKlxuICogVGhlIEhUVFAgbWV0aG9kcyB0aGF0IHRoZSBCZWhhdmlvciB3aWxsIGNhY2hlIHJlcXVlc3RzIG9uLlxuICovXG5leHBvcnQgY2xhc3MgQ2FjaGVkTWV0aG9kcyB7XG4gIC8qKiBIRUFEIGFuZCBHRVQgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBDQUNIRV9HRVRfSEVBRCA9IG5ldyBDYWNoZWRNZXRob2RzKFsnR0VUJywgJ0hFQUQnXSk7XG4gIC8qKiBIRUFELCBHRVQsIGFuZCBPUFRJT05TICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0FDSEVfR0VUX0hFQURfT1BUSU9OUyA9IG5ldyBDYWNoZWRNZXRob2RzKFsnR0VUJywgJ0hFQUQnLCAnT1BUSU9OUyddKTtcblxuICAvKiogSFRUUCBtZXRob2RzIHN1cHBvcnRlZCAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbWV0aG9kczogc3RyaW5nW107XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihtZXRob2RzOiBzdHJpbmdbXSkgeyB0aGlzLm1ldGhvZHMgPSBtZXRob2RzOyB9XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgY29uZmlndXJpbmcgY3VzdG9tIGVycm9yIHJlc3BvbnNlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFcnJvclJlc3BvbnNlIHtcbiAgLyoqXG4gICAqIFRoZSBtaW5pbXVtIGFtb3VudCBvZiB0aW1lLCBpbiBzZWNvbmRzLCB0aGF0IHlvdSB3YW50IENsb3VkRnJvbnQgdG8gY2FjaGUgdGhlIEhUVFAgc3RhdHVzIGNvZGUgc3BlY2lmaWVkIGluIEVycm9yQ29kZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0aGUgZGVmYXVsdCBjYWNoaW5nIFRUTCBiZWhhdmlvciBhcHBsaWVzXG4gICAqL1xuICByZWFkb25seSB0dGw/OiBEdXJhdGlvbjtcbiAgLyoqXG4gICAqIFRoZSBIVFRQIHN0YXR1cyBjb2RlIGZvciB3aGljaCB5b3Ugd2FudCB0byBzcGVjaWZ5IGEgY3VzdG9tIGVycm9yIHBhZ2UgYW5kL29yIGEgY2FjaGluZyBkdXJhdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IGh0dHBTdGF0dXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBIVFRQIHN0YXR1cyBjb2RlIHRoYXQgeW91IHdhbnQgQ2xvdWRGcm9udCB0byByZXR1cm4gdG8gdGhlIHZpZXdlciBhbG9uZyB3aXRoIHRoZSBjdXN0b20gZXJyb3IgcGFnZS5cbiAgICpcbiAgICogSWYgeW91IHNwZWNpZnkgYSB2YWx1ZSBmb3IgYHJlc3BvbnNlSHR0cFN0YXR1c2AsIHlvdSBtdXN0IGFsc28gc3BlY2lmeSBhIHZhbHVlIGZvciBgcmVzcG9uc2VQYWdlUGF0aGAuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIGVycm9yIGNvZGUgd2lsbCBiZSByZXR1cm5lZCBhcyB0aGUgcmVzcG9uc2UgY29kZS5cbiAgICovXG4gIHJlYWRvbmx5IHJlc3BvbnNlSHR0cFN0YXR1cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBwYXRoIHRvIHRoZSBjdXN0b20gZXJyb3IgcGFnZSB0aGF0IHlvdSB3YW50IENsb3VkRnJvbnQgdG8gcmV0dXJuIHRvIGEgdmlld2VyIHdoZW4geW91ciBvcmlnaW4gcmV0dXJucyB0aGVcbiAgICogYGh0dHBTdGF0dXNgLCBmb3IgZXhhbXBsZSwgLzR4eC1lcnJvcnMvNDAzLWZvcmJpZGRlbi5odG1sXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIGRlZmF1bHQgQ2xvdWRGcm9udCByZXNwb25zZSBpcyBzaG93bi5cbiAgICovXG4gIHJlYWRvbmx5IHJlc3BvbnNlUGFnZVBhdGg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIHR5cGUgb2YgZXZlbnRzIHRoYXQgYSBMYW1iZGFARWRnZSBmdW5jdGlvbiBjYW4gYmUgaW52b2tlZCBpbiByZXNwb25zZSB0by5cbiAqL1xuZXhwb3J0IGVudW0gTGFtYmRhRWRnZUV2ZW50VHlwZSB7XG4gIC8qKlxuICAgKiBUaGUgb3JpZ2luLXJlcXVlc3Qgc3BlY2lmaWVzIHRoZSByZXF1ZXN0IHRvIHRoZVxuICAgKiBvcmlnaW4gbG9jYXRpb24gKGUuZy4gUzMpXG4gICAqL1xuICBPUklHSU5fUkVRVUVTVCA9ICdvcmlnaW4tcmVxdWVzdCcsXG5cbiAgLyoqXG4gICAqIFRoZSBvcmlnaW4tcmVzcG9uc2Ugc3BlY2lmaWVzIHRoZSByZXNwb25zZSBmcm9tIHRoZVxuICAgKiBvcmlnaW4gbG9jYXRpb24gKGUuZy4gUzMpXG4gICAqL1xuICBPUklHSU5fUkVTUE9OU0UgPSAnb3JpZ2luLXJlc3BvbnNlJyxcblxuICAvKipcbiAgICogVGhlIHZpZXdlci1yZXF1ZXN0IHNwZWNpZmllcyB0aGUgaW5jb21pbmcgcmVxdWVzdFxuICAgKi9cbiAgVklFV0VSX1JFUVVFU1QgPSAndmlld2VyLXJlcXVlc3QnLFxuXG4gIC8qKlxuICAgKiBUaGUgdmlld2VyLXJlc3BvbnNlIHNwZWNpZmllcyB0aGUgb3V0Z29pbmcgcmVzcG9uc2VcbiAgICovXG4gIFZJRVdFUl9SRVNQT05TRSA9ICd2aWV3ZXItcmVzcG9uc2UnLFxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBMYW1iZGEgZnVuY3Rpb24gdmVyc2lvbiBhbmQgZXZlbnQgdHlwZSB3aGVuIHVzaW5nIExhbWJkYUBFZGdlLlxuICogVGhlIHR5cGUgb2YgdGhlIHtAbGluayBBZGRCZWhhdmlvck9wdGlvbnMuZWRnZUxhbWJkYXN9IHByb3BlcnR5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVkZ2VMYW1iZGEge1xuICAvKipcbiAgICogVGhlIHZlcnNpb24gb2YgdGhlIExhbWJkYSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgaW52b2tlZC5cbiAgICpcbiAgICogKipOb3RlKio6IGl0J3Mgbm90IHBvc3NpYmxlIHRvIHVzZSB0aGUgJyRMQVRFU1QnIGZ1bmN0aW9uIHZlcnNpb24gZm9yIExhbWJkYUBFZGdlIVxuICAgKi9cbiAgcmVhZG9ubHkgZnVuY3Rpb25WZXJzaW9uOiBsYW1iZGEuSVZlcnNpb247XG5cbiAgLyoqIFRoZSB0eXBlIG9mIGV2ZW50IGluIHJlc3BvbnNlIHRvIHdoaWNoIHNob3VsZCB0aGUgZnVuY3Rpb24gYmUgaW52b2tlZC4gKi9cbiAgcmVhZG9ubHkgZXZlbnRUeXBlOiBMYW1iZGFFZGdlRXZlbnRUeXBlO1xuXG4gIC8qKlxuICAgKiBBbGxvd3MgYSBMYW1iZGEgZnVuY3Rpb24gdG8gaGF2ZSByZWFkIGFjY2VzcyB0byB0aGUgYm9keSBjb250ZW50LlxuICAgKiBPbmx5IHZhbGlkIGZvciBcInJlcXVlc3RcIiBldmVudCB0eXBlcyAoYE9SSUdJTl9SRVFVRVNUYCBvciBgVklFV0VSX1JFUVVFU1RgKS5cbiAgICogU2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZEZyb250L2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9sYW1iZGEtaW5jbHVkZS1ib2R5LWFjY2Vzcy5odG1sXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBpbmNsdWRlQm9keT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYWRkaW5nIGEgbmV3IGJlaGF2aW9yIHRvIGEgRGlzdHJpYnV0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFkZEJlaGF2aW9yT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBIVFRQIG1ldGhvZHMgdG8gYWxsb3cgZm9yIHRoaXMgYmVoYXZpb3IuXG4gICAqXG4gICAqIEBkZWZhdWx0IEFsbG93ZWRNZXRob2RzLkFMTE9XX0dFVF9IRUFEXG4gICAqL1xuICByZWFkb25seSBhbGxvd2VkTWV0aG9kcz86IEFsbG93ZWRNZXRob2RzO1xuXG4gIC8qKlxuICAgKiBIVFRQIG1ldGhvZHMgdG8gY2FjaGUgZm9yIHRoaXMgYmVoYXZpb3IuXG4gICAqXG4gICAqIEBkZWZhdWx0IENhY2hlZE1ldGhvZHMuQ0FDSEVfR0VUX0hFQURcbiAgICovXG4gIHJlYWRvbmx5IGNhY2hlZE1ldGhvZHM/OiBDYWNoZWRNZXRob2RzO1xuXG4gIC8qKlxuICAgKiBUaGUgY2FjaGUgcG9saWN5IGZvciB0aGlzIGJlaGF2aW9yLiBUaGUgY2FjaGUgcG9saWN5IGRldGVybWluZXMgd2hhdCB2YWx1ZXMgYXJlIGluY2x1ZGVkIGluIHRoZSBjYWNoZSBrZXksXG4gICAqIGFuZCB0aGUgdGltZS10by1saXZlIChUVEwpIHZhbHVlcyBmb3IgdGhlIGNhY2hlLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZEZyb250L2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9jb250cm9sbGluZy10aGUtY2FjaGUta2V5Lmh0bWwuXG4gICAqIEBkZWZhdWx0IENhY2hlUG9saWN5LkNBQ0hJTkdfT1BUSU1JWkVEXG4gICAqL1xuICByZWFkb25seSBjYWNoZVBvbGljeT86IElDYWNoZVBvbGljeTtcblxuICAvKipcbiAgICogV2hldGhlciB5b3Ugd2FudCBDbG91ZEZyb250IHRvIGF1dG9tYXRpY2FsbHkgY29tcHJlc3MgY2VydGFpbiBmaWxlcyBmb3IgdGhpcyBjYWNoZSBiZWhhdmlvci5cbiAgICogU2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZEZyb250L2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9TZXJ2aW5nQ29tcHJlc3NlZEZpbGVzLmh0bWwjY29tcHJlc3NlZC1jb250ZW50LWNsb3VkZnJvbnQtZmlsZS10eXBlc1xuICAgKiBmb3IgZmlsZSB0eXBlcyBDbG91ZEZyb250IHdpbGwgY29tcHJlc3MuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNvbXByZXNzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIG9yaWdpbiByZXF1ZXN0IHBvbGljeSBmb3IgdGhpcyBiZWhhdmlvci4gVGhlIG9yaWdpbiByZXF1ZXN0IHBvbGljeSBkZXRlcm1pbmVzIHdoaWNoIHZhbHVlcyAoZS5nLiwgaGVhZGVycywgY29va2llcylcbiAgICogYXJlIGluY2x1ZGVkIGluIHJlcXVlc3RzIHRoYXQgQ2xvdWRGcm9udCBzZW5kcyB0byB0aGUgb3JpZ2luLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vbmVcbiAgICovXG4gIHJlYWRvbmx5IG9yaWdpblJlcXVlc3RQb2xpY3k/OiBJT3JpZ2luUmVxdWVzdFBvbGljeTtcblxuICAvKipcbiAgICogVGhlIHJlc3BvbnNlIGhlYWRlcnMgcG9saWN5IGZvciB0aGlzIGJlaGF2aW9yLiBUaGUgcmVzcG9uc2UgaGVhZGVycyBwb2xpY3kgZGV0ZXJtaW5lcyB3aGljaCBoZWFkZXJzIGFyZSBpbmNsdWRlZCBpbiByZXNwb25zZXNcbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICByZWFkb25seSByZXNwb25zZUhlYWRlcnNQb2xpY3k/OiBJUmVzcG9uc2VIZWFkZXJzUG9saWN5O1xuXG4gIC8qKlxuICAgKiBTZXQgdGhpcyB0byB0cnVlIHRvIGluZGljYXRlIHlvdSB3YW50IHRvIGRpc3RyaWJ1dGUgbWVkaWEgZmlsZXMgaW4gdGhlIE1pY3Jvc29mdCBTbW9vdGggU3RyZWFtaW5nIGZvcm1hdCB1c2luZyB0aGlzIGJlaGF2aW9yLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgc21vb3RoU3RyZWFtaW5nPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIHByb3RvY29sIHRoYXQgdmlld2VycyBjYW4gdXNlIHRvIGFjY2VzcyB0aGUgZmlsZXMgY29udHJvbGxlZCBieSB0aGlzIGJlaGF2aW9yLlxuICAgKlxuICAgKiBAZGVmYXVsdCBWaWV3ZXJQcm90b2NvbFBvbGljeS5BTExPV19BTExcbiAgICovXG4gIHJlYWRvbmx5IHZpZXdlclByb3RvY29sUG9saWN5PzogVmlld2VyUHJvdG9jb2xQb2xpY3k7XG5cbiAgLyoqXG4gICAqIFRoZSBDbG91ZEZyb250IGZ1bmN0aW9ucyB0byBpbnZva2UgYmVmb3JlIHNlcnZpbmcgdGhlIGNvbnRlbnRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGZ1bmN0aW9ucyB3aWxsIGJlIGludm9rZWRcbiAgICovXG4gIHJlYWRvbmx5IGZ1bmN0aW9uQXNzb2NpYXRpb25zPzogRnVuY3Rpb25Bc3NvY2lhdGlvbltdO1xuXG4gIC8qKlxuICAgKiBUaGUgTGFtYmRhQEVkZ2UgZnVuY3Rpb25zIHRvIGludm9rZSBiZWZvcmUgc2VydmluZyB0aGUgY29udGVudHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gTGFtYmRhIGZ1bmN0aW9ucyB3aWxsIGJlIGludm9rZWRcbiAgICogQHNlZSBodHRwczovL2F3cy5hbWF6b24uY29tL2xhbWJkYS9lZGdlXG4gICAqL1xuICByZWFkb25seSBlZGdlTGFtYmRhcz86IEVkZ2VMYW1iZGFbXTtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIEtleSBHcm91cHMgdGhhdCBDbG91ZEZyb250IGNhbiB1c2UgdG8gdmFsaWRhdGUgc2lnbmVkIFVSTHMgb3Igc2lnbmVkIGNvb2tpZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gS2V5R3JvdXBzIGFyZSBhc3NvY2lhdGVkIHdpdGggY2FjaGUgYmVoYXZpb3JcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvUHJpdmF0ZUNvbnRlbnQuaHRtbFxuICAgKi9cbiAgcmVhZG9ubHkgdHJ1c3RlZEtleUdyb3Vwcz86IElLZXlHcm91cFtdO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGNyZWF0aW5nIGEgbmV3IGJlaGF2aW9yLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJlaGF2aW9yT3B0aW9ucyBleHRlbmRzIEFkZEJlaGF2aW9yT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgb3JpZ2luIHRoYXQgeW91IHdhbnQgQ2xvdWRGcm9udCB0byByb3V0ZSByZXF1ZXN0cyB0byB3aGVuIHRoZXkgbWF0Y2ggdGhpcyBiZWhhdmlvci5cbiAgICovXG4gIHJlYWRvbmx5IG9yaWdpbjogSU9yaWdpbjtcbn1cbiJdfQ==
\No newline at end of file