1 | ;
|
2 | var _a, _b, _c;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | exports.LambdaEdgeEventType = exports.CachedMethods = exports.AllowedMethods = exports.SecurityPolicyProtocol = exports.SSLMethod = exports.OriginProtocolPolicy = exports.ViewerProtocolPolicy = exports.PriceClass = exports.HttpVersion = exports.Distribution = void 0;
|
5 | const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
|
6 | const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
7 | const s3 = require("@aws-cdk/aws-s3");
|
8 | const core_1 = require("@aws-cdk/core");
|
9 | const cx_api_1 = require("@aws-cdk/cx-api");
|
10 | const cloudfront_generated_1 = require("./cloudfront.generated");
|
11 | const 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
|
14 | const core_2 = require("@aws-cdk/core");
|
15 | /**
|
16 | * A CloudFront distribution with associated origin(s) and caching behavior(s).
|
17 | */
|
18 | class 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 | }
|
252 | exports.Distribution = Distribution;
|
253 | _a = JSII_RTTI_SYMBOL_1;
|
254 | Distribution[_a] = { fqn: "@aws-cdk/aws-cloudfront.Distribution", version: "1.161.0" };
|
255 | /** Maximum HTTP version to support */
|
256 | var 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 | */
|
267 | var 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 | */
|
279 | var 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 | */
|
291 | var 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 | */
|
316 | var 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 | */
|
325 | var 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 | */
|
338 | class AllowedMethods {
|
339 | constructor(methods) { this.methods = methods; }
|
340 | }
|
341 | exports.AllowedMethods = AllowedMethods;
|
342 | _b = JSII_RTTI_SYMBOL_1;
|
343 | AllowedMethods[_b] = { fqn: "@aws-cdk/aws-cloudfront.AllowedMethods", version: "1.161.0" };
|
344 | /** HEAD and GET */
|
345 | AllowedMethods.ALLOW_GET_HEAD = new AllowedMethods(['GET', 'HEAD']);
|
346 | /** HEAD, GET, and OPTIONS */
|
347 | AllowedMethods.ALLOW_GET_HEAD_OPTIONS = new AllowedMethods(['GET', 'HEAD', 'OPTIONS']);
|
348 | /** All supported HTTP methods */
|
349 | AllowedMethods.ALLOW_ALL = new AllowedMethods(['GET', 'HEAD', 'OPTIONS', 'PUT', 'PATCH', 'POST', 'DELETE']);
|
350 | /**
|
351 | * The HTTP methods that the Behavior will cache requests on.
|
352 | */
|
353 | class CachedMethods {
|
354 | constructor(methods) { this.methods = methods; }
|
355 | }
|
356 | exports.CachedMethods = CachedMethods;
|
357 | _c = JSII_RTTI_SYMBOL_1;
|
358 | CachedMethods[_c] = { fqn: "@aws-cdk/aws-cloudfront.CachedMethods", version: "1.161.0" };
|
359 | /** HEAD and GET */
|
360 | CachedMethods.CACHE_GET_HEAD = new CachedMethods(['GET', 'HEAD']);
|
361 | /** HEAD, GET, and OPTIONS */
|
362 | CachedMethods.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 | */
|
366 | var 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 |