1 | ;
|
2 | var _a, _b, _c, _d;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | exports.AwsCustomResource = exports.AwsCustomResourcePolicy = exports.PhysicalResourceId = exports.PhysicalResourceIdReference = void 0;
|
5 | const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
|
6 | const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
7 | const fs = require("fs");
|
8 | const path = require("path");
|
9 | const iam = require("@aws-cdk/aws-iam");
|
10 | const lambda = require("@aws-cdk/aws-lambda");
|
11 | const cdk = require("@aws-cdk/core");
|
12 | const runtime_1 = require("./runtime");
|
13 | // keep this import separate from other imports to reduce chance for merge conflicts with v2-main
|
14 | // eslint-disable-next-line no-duplicate-imports, import/order
|
15 | const core_1 = require("@aws-cdk/core");
|
16 | /**
|
17 | * Reference to the physical resource id that can be passed to the AWS operation as a parameter.
|
18 | */
|
19 | class PhysicalResourceIdReference {
|
20 | constructor() {
|
21 | this.creationStack = cdk.captureStackTrace();
|
22 | }
|
23 | /**
|
24 | * toJSON serialization to replace `PhysicalResourceIdReference` with a magic string.
|
25 | */
|
26 | toJSON() {
|
27 | return runtime_1.PHYSICAL_RESOURCE_ID_REFERENCE;
|
28 | }
|
29 | resolve(_) {
|
30 | return runtime_1.PHYSICAL_RESOURCE_ID_REFERENCE;
|
31 | }
|
32 | toString() {
|
33 | return runtime_1.PHYSICAL_RESOURCE_ID_REFERENCE;
|
34 | }
|
35 | }
|
36 | exports.PhysicalResourceIdReference = PhysicalResourceIdReference;
|
37 | _a = JSII_RTTI_SYMBOL_1;
|
38 | PhysicalResourceIdReference[_a] = { fqn: "@aws-cdk/custom-resources.PhysicalResourceIdReference", version: "1.191.0" };
|
39 | /**
|
40 | * Physical ID of the custom resource.
|
41 | */
|
42 | class PhysicalResourceId {
|
43 | /**
|
44 | * @param responsePath Path to a response data element to be used as the physical id.
|
45 | * @param id Literal string to be used as the physical id.
|
46 | */
|
47 | constructor(responsePath, id) {
|
48 | this.responsePath = responsePath;
|
49 | this.id = id;
|
50 | }
|
51 | /**
|
52 | * Extract the physical resource id from the path (dot notation) to the data in the API call response.
|
53 | */
|
54 | static fromResponse(responsePath) {
|
55 | return new PhysicalResourceId(responsePath, undefined);
|
56 | }
|
57 | /**
|
58 | * Explicit physical resource id.
|
59 | */
|
60 | static of(id) {
|
61 | return new PhysicalResourceId(undefined, id);
|
62 | }
|
63 | }
|
64 | exports.PhysicalResourceId = PhysicalResourceId;
|
65 | _b = JSII_RTTI_SYMBOL_1;
|
66 | PhysicalResourceId[_b] = { fqn: "@aws-cdk/custom-resources.PhysicalResourceId", version: "1.191.0" };
|
67 | /**
|
68 | * The IAM Policy that will be applied to the different calls.
|
69 | */
|
70 | class AwsCustomResourcePolicy {
|
71 | /**
|
72 | * @param statements statements for explicit policy.
|
73 | * @param resources resources for auto-generated from SDK calls.
|
74 | */
|
75 | constructor(statements, resources) {
|
76 | this.statements = statements;
|
77 | this.resources = resources;
|
78 | }
|
79 | /**
|
80 | * Explicit IAM Policy Statements.
|
81 | *
|
82 | * @param statements the statements to propagate to the SDK calls.
|
83 | */
|
84 | static fromStatements(statements) {
|
85 | return new AwsCustomResourcePolicy(statements, undefined);
|
86 | }
|
87 | /**
|
88 | * Generate IAM Policy Statements from the configured SDK calls.
|
89 | *
|
90 | * Each SDK call with be translated to an IAM Policy Statement in the form of: `call.service:call.action` (e.g `s3:PutObject`).
|
91 | *
|
92 | * This policy generator assumes the IAM policy name has the same name as the API
|
93 | * call. This is true in 99% of cases, but there are exceptions (for example,
|
94 | * S3's `PutBucketLifecycleConfiguration` requires
|
95 | * `s3:PutLifecycleConfiguration` permissions, Lambda's `Invoke` requires
|
96 | * `lambda:InvokeFunction` permissions). Use `fromStatements` if you want to
|
97 | * do a call that requires different IAM action names.
|
98 | *
|
99 | * @param options options for the policy generation
|
100 | */
|
101 | static fromSdkCalls(options) {
|
102 | try {
|
103 | jsiiDeprecationWarnings._aws_cdk_custom_resources_SdkCallsPolicyOptions(options);
|
104 | }
|
105 | catch (error) {
|
106 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
107 | Error.captureStackTrace(error, this.fromSdkCalls);
|
108 | }
|
109 | throw error;
|
110 | }
|
111 | return new AwsCustomResourcePolicy([], options.resources);
|
112 | }
|
113 | }
|
114 | exports.AwsCustomResourcePolicy = AwsCustomResourcePolicy;
|
115 | _c = JSII_RTTI_SYMBOL_1;
|
116 | AwsCustomResourcePolicy[_c] = { fqn: "@aws-cdk/custom-resources.AwsCustomResourcePolicy", version: "1.191.0" };
|
117 | /**
|
118 | * Use this constant to configure access to any resource.
|
119 | */
|
120 | AwsCustomResourcePolicy.ANY_RESOURCE = ['*'];
|
121 | /**
|
122 | * Defines a custom resource that is materialized using specific AWS API calls. These calls are created using
|
123 | * a singleton Lambda function.
|
124 | *
|
125 | * Use this to bridge any gap that might exist in the CloudFormation Coverage.
|
126 | * You can specify exactly which calls are invoked for the 'CREATE', 'UPDATE' and 'DELETE' life cycle events.
|
127 | *
|
128 | */
|
129 | class AwsCustomResource extends core_1.Construct {
|
130 | // 'props' cannot be optional, even though all its properties are optional.
|
131 | // this is because at least one sdk call must be provided.
|
132 | constructor(scope, id, props) {
|
133 | super(scope, id);
|
134 | try {
|
135 | jsiiDeprecationWarnings._aws_cdk_custom_resources_AwsCustomResourceProps(props);
|
136 | }
|
137 | catch (error) {
|
138 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
139 | Error.captureStackTrace(error, AwsCustomResource);
|
140 | }
|
141 | throw error;
|
142 | }
|
143 | if (!props.onCreate && !props.onUpdate && !props.onDelete) {
|
144 | throw new Error('At least `onCreate`, `onUpdate` or `onDelete` must be specified.');
|
145 | }
|
146 | for (const call of [props.onCreate, props.onUpdate]) {
|
147 | if (call && !call.physicalResourceId) {
|
148 | throw new Error('`physicalResourceId` must be specified for onCreate and onUpdate calls.');
|
149 | }
|
150 | }
|
151 | for (const call of [props.onCreate, props.onUpdate, props.onDelete]) {
|
152 | if (call?.physicalResourceId?.responsePath) {
|
153 | AwsCustomResource.breakIgnoreErrorsCircuit([call], 'PhysicalResourceId.fromResponse');
|
154 | }
|
155 | }
|
156 | if (includesPhysicalResourceIdRef(props.onCreate?.parameters)) {
|
157 | throw new Error('`PhysicalResourceIdReference` must not be specified in `onCreate` parameters.');
|
158 | }
|
159 | this.props = props;
|
160 | const provider = new lambda.SingletonFunction(this, 'Provider', {
|
161 | code: lambda.Code.fromAsset(path.join(__dirname, 'runtime'), {
|
162 | exclude: ['*.ts'],
|
163 | }),
|
164 | runtime: lambda.Runtime.NODEJS_14_X,
|
165 | handler: 'index.handler',
|
166 | uuid: '679f53fa-c002-430c-b0da-5b7982bd2287',
|
167 | lambdaPurpose: 'AWS',
|
168 | timeout: props.timeout || cdk.Duration.minutes(2),
|
169 | role: props.role,
|
170 | logRetention: props.logRetention,
|
171 | functionName: props.functionName,
|
172 | });
|
173 | this.grantPrincipal = provider.grantPrincipal;
|
174 | // Create the policy statements for the custom resource function role, or use the user-provided ones
|
175 | const statements = [];
|
176 | if (props.policy.statements.length !== 0) {
|
177 | // Use custom statements provided by the user
|
178 | for (const statement of props.policy.statements) {
|
179 | statements.push(statement);
|
180 | }
|
181 | }
|
182 | else {
|
183 | // Derive statements from AWS SDK calls
|
184 | for (const call of [props.onCreate, props.onUpdate, props.onDelete]) {
|
185 | if (call && call.assumedRoleArn == null) {
|
186 | const statement = new iam.PolicyStatement({
|
187 | actions: [awsSdkToIamAction(call.service, call.action)],
|
188 | resources: props.policy.resources,
|
189 | });
|
190 | statements.push(statement);
|
191 | }
|
192 | else if (call && call.assumedRoleArn != null) {
|
193 | const statement = new iam.PolicyStatement({
|
194 | actions: ['sts:AssumeRole'],
|
195 | resources: [call.assumedRoleArn],
|
196 | });
|
197 | statements.push(statement);
|
198 | }
|
199 | }
|
200 | }
|
201 | const policy = new iam.Policy(this, 'CustomResourcePolicy', {
|
202 | statements: statements,
|
203 | });
|
204 | if (provider.role !== undefined) {
|
205 | policy.attachToRole(provider.role);
|
206 | }
|
207 | const create = props.onCreate || props.onUpdate;
|
208 | this.customResource = new cdk.CustomResource(this, 'Resource', {
|
209 | resourceType: props.resourceType || 'Custom::AWS',
|
210 | serviceToken: provider.functionArn,
|
211 | pascalCaseProperties: true,
|
212 | properties: {
|
213 | create: create && this.encodeJson(create),
|
214 | update: props.onUpdate && this.encodeJson(props.onUpdate),
|
215 | delete: props.onDelete && this.encodeJson(props.onDelete),
|
216 | installLatestAwsSdk: props.installLatestAwsSdk ?? true,
|
217 | },
|
218 | });
|
219 | // If the policy was deleted first, then the function might lose permissions to delete the custom resource
|
220 | // This is here so that the policy doesn't get removed before onDelete is called
|
221 | this.customResource.node.addDependency(policy);
|
222 | }
|
223 | static breakIgnoreErrorsCircuit(sdkCalls, caller) {
|
224 | for (const call of sdkCalls) {
|
225 | if (call?.ignoreErrorCodesMatching) {
|
226 | throw new Error(`\`${caller}\`` + ' cannot be called along with `ignoreErrorCodesMatching`.');
|
227 | }
|
228 | }
|
229 | }
|
230 | /**
|
231 | * Returns response data for the AWS SDK call.
|
232 | *
|
233 | * Example for S3 / listBucket : 'Buckets.0.Name'
|
234 | *
|
235 | * Use `Token.asXxx` to encode the returned `Reference` as a specific type or
|
236 | * use the convenience `getDataString` for string attributes.
|
237 | *
|
238 | * Note that you cannot use this method if `ignoreErrorCodesMatching`
|
239 | * is configured for any of the SDK calls. This is because in such a case,
|
240 | * the response data might not exist, and will cause a CloudFormation deploy time error.
|
241 | *
|
242 | * @param dataPath the path to the data
|
243 | */
|
244 | getResponseFieldReference(dataPath) {
|
245 | AwsCustomResource.breakIgnoreErrorsCircuit([this.props.onCreate, this.props.onUpdate], 'getData');
|
246 | return this.customResource.getAtt(dataPath);
|
247 | }
|
248 | /**
|
249 | * Returns response data for the AWS SDK call as string.
|
250 | *
|
251 | * Example for S3 / listBucket : 'Buckets.0.Name'
|
252 | *
|
253 | * Note that you cannot use this method if `ignoreErrorCodesMatching`
|
254 | * is configured for any of the SDK calls. This is because in such a case,
|
255 | * the response data might not exist, and will cause a CloudFormation deploy time error.
|
256 | *
|
257 | * @param dataPath the path to the data
|
258 | */
|
259 | getResponseField(dataPath) {
|
260 | AwsCustomResource.breakIgnoreErrorsCircuit([this.props.onCreate, this.props.onUpdate], 'getDataString');
|
261 | return this.customResource.getAttString(dataPath);
|
262 | }
|
263 | encodeJson(obj) {
|
264 | return cdk.Lazy.uncachedString({ produce: () => cdk.Stack.of(this).toJsonString(obj) });
|
265 | }
|
266 | }
|
267 | exports.AwsCustomResource = AwsCustomResource;
|
268 | _d = JSII_RTTI_SYMBOL_1;
|
269 | AwsCustomResource[_d] = { fqn: "@aws-cdk/custom-resources.AwsCustomResource", version: "1.191.0" };
|
270 | /**
|
271 | * Gets awsSdkMetaData from file or from cache
|
272 | */
|
273 | let getAwsSdkMetadata = (() => {
|
274 | let _awsSdkMetadata;
|
275 | return function () {
|
276 | if (_awsSdkMetadata) {
|
277 | return _awsSdkMetadata;
|
278 | }
|
279 | else {
|
280 | return _awsSdkMetadata = JSON.parse(fs.readFileSync(path.join(__dirname, 'sdk-api-metadata.json'), 'utf-8'));
|
281 | }
|
282 | };
|
283 | })();
|
284 | /**
|
285 | * Returns true if `obj` includes a `PhysicalResourceIdReference` in one of the
|
286 | * values.
|
287 | * @param obj Any object.
|
288 | */
|
289 | function includesPhysicalResourceIdRef(obj) {
|
290 | if (obj === undefined) {
|
291 | return false;
|
292 | }
|
293 | let foundRef = false;
|
294 | // we use JSON.stringify as a way to traverse all values in the object.
|
295 | JSON.stringify(obj, (_, v) => {
|
296 | if (v === runtime_1.PHYSICAL_RESOURCE_ID_REFERENCE) {
|
297 | foundRef = true;
|
298 | }
|
299 | return v;
|
300 | });
|
301 | return foundRef;
|
302 | }
|
303 | /**
|
304 | * Transform SDK service/action to IAM action using metadata from aws-sdk module.
|
305 | * Example: CloudWatchLogs with putRetentionPolicy => logs:PutRetentionPolicy
|
306 | *
|
307 | * TODO: is this mapping correct for all services?
|
308 | */
|
309 | function awsSdkToIamAction(service, action) {
|
310 | const srv = service.toLowerCase();
|
311 | const awsSdkMetadata = getAwsSdkMetadata();
|
312 | const iamService = (awsSdkMetadata[srv] && awsSdkMetadata[srv].prefix) || srv;
|
313 | const iamAction = action.charAt(0).toUpperCase() + action.slice(1);
|
314 | return `${iamService}:${iamAction}`;
|
315 | }
|
316 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLWN1c3RvbS1yZXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImF3cy1jdXN0b20tcmVzb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qix3Q0FBd0M7QUFDeEMsOENBQThDO0FBRTlDLHFDQUFxQztBQUVyQyx1Q0FBMkQ7QUFFM0QsaUdBQWlHO0FBQ2pHLDhEQUE4RDtBQUM5RCx3Q0FBMkQ7QUFFM0Q7O0dBRUc7QUFDSCxNQUFhLDJCQUEyQjtJQUF4QztRQUNrQixrQkFBYSxHQUFhLEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0tBZ0JuRTtJQWRDOztPQUVHO0lBQ0ksTUFBTTtRQUNYLE9BQU8sd0NBQThCLENBQUM7S0FDdkM7SUFFTSxPQUFPLENBQUMsQ0FBc0I7UUFDbkMsT0FBTyx3Q0FBOEIsQ0FBQztLQUN2QztJQUVNLFFBQVE7UUFDYixPQUFPLHdDQUE4QixDQUFDO0tBQ3ZDOztBQWhCSCxrRUFpQkM7OztBQUVEOztHQUVHO0FBQ0gsTUFBYSxrQkFBa0I7SUFnQjdCOzs7T0FHRztJQUNILFlBQW9DLFlBQXFCLEVBQWtCLEVBQVc7UUFBbEQsaUJBQVksR0FBWixZQUFZLENBQVM7UUFBa0IsT0FBRSxHQUFGLEVBQUUsQ0FBUztLQUFLO0lBbEIzRjs7T0FFRztJQUNJLE1BQU0sQ0FBQyxZQUFZLENBQUMsWUFBb0I7UUFDN0MsT0FBTyxJQUFJLGtCQUFrQixDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztLQUN4RDtJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFVO1FBQ3pCLE9BQU8sSUFBSSxrQkFBa0IsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7S0FDOUM7O0FBZEgsZ0RBcUJDOzs7QUFzSEQ7O0dBRUc7QUFDSCxNQUFhLHVCQUF1QjtJQWtDbEM7OztPQUdHO0lBQ0gsWUFBb0MsVUFBaUMsRUFBa0IsU0FBb0I7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LENBQUMsQ0FBQyxDQUFDO1NBQzlHO0lBQ0gsQ0FBQyxDQUFDO0FBQ0osQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUVMOzs7O0dBSUc7QUFDSCxTQUFTLDZCQUE2QixDQUFDLEdBQW9CO0lBQ3pELElBQUksR0FBRyxLQUFLLFNBQVMsRUFBRTtRQUNyQixPQUFPLEtBQUssQ0FBQztLQUNkO0lBRUQsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDO0lBRXJCLHVFQUF1RTtJQUN2RSxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUMzQixJQUFJLENBQUMsS0FBSyx3Q0FBOEIsRUFBRTtZQUN4QyxRQUFRLEdBQUcsSUFBSSxDQUFDO1NBQ2pCO1FBRUQsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsaUJBQWlCLENBQUMsT0FBZSxFQUFFLE1BQWM7SUFDeEQsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ2xDLE1BQU0sY0FBYyxHQUFHLGlCQUFpQixFQUFFLENBQUM7SUFDM0MsTUFBTSxVQUFVLEdBQUcsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsQ0FBQztJQUM5RSxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkUsT0FBTyxHQUFHLFVBQVUsSUFBSSxTQUFTLEVBQUUsQ0FBQztBQUN0QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdAYXdzLWNkay9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdAYXdzLWNkay9hd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIGxvZ3MgZnJvbSAnQGF3cy1jZGsvYXdzLWxvZ3MnO1xuaW1wb3J0ICogYXMgY2RrIGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBQSFlTSUNBTF9SRVNPVVJDRV9JRF9SRUZFUkVOQ0UgfSBmcm9tICcuL3J1bnRpbWUnO1xuXG4vLyBrZWVwIHRoaXMgaW1wb3J0IHNlcGFyYXRlIGZyb20gb3RoZXIgaW1wb3J0cyB0byByZWR1Y2UgY2hhbmNlIGZvciBtZXJnZSBjb25mbGljdHMgd2l0aCB2Mi1tYWluXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZHVwbGljYXRlLWltcG9ydHMsIGltcG9ydC9vcmRlclxuaW1wb3J0IHsgQ29uc3RydWN0IGFzIENvcmVDb25zdHJ1Y3QgfSBmcm9tICdAYXdzLWNkay9jb3JlJztcblxuLyoqXG4gKiBSZWZlcmVuY2UgdG8gdGhlIHBoeXNpY2FsIHJlc291cmNlIGlkIHRoYXQgY2FuIGJlIHBhc3NlZCB0byB0aGUgQVdTIG9wZXJhdGlvbiBhcyBhIHBhcmFtZXRlci5cbiAqL1xuZXhwb3J0IGNsYXNzIFBoeXNpY2FsUmVzb3VyY2VJZFJlZmVyZW5jZSBpbXBsZW1lbnRzIGNkay5JUmVzb2x2YWJsZSB7XG4gIHB1YmxpYyByZWFkb25seSBjcmVhdGlvblN0YWNrOiBzdHJpbmdbXSA9IGNkay5jYXB0dXJlU3RhY2tUcmFjZSgpO1xuXG4gIC8qKlxuICAgKiB0b0pTT04gc2VyaWFsaXphdGlvbiB0byByZXBsYWNlIGBQaHlzaWNhbFJlc291cmNlSWRSZWZlcmVuY2VgIHdpdGggYSBtYWdpYyBzdHJpbmcuXG4gICAqL1xuICBwdWJsaWMgdG9KU09OKCkge1xuICAgIHJldHVybiBQSFlTSUNBTF9SRVNPVVJDRV9JRF9SRUZFUkVOQ0U7XG4gIH1cblxuICBwdWJsaWMgcmVzb2x2ZShfOiBjZGsuSVJlc29sdmVDb250ZXh0KTogYW55IHtcbiAgICByZXR1cm4gUEhZU0lDQUxfUkVTT1VSQ0VfSURfUkVGRVJFTkNFO1xuICB9XG5cbiAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFBIWVNJQ0FMX1JFU09VUkNFX0lEX1JFRkVSRU5DRTtcbiAgfVxufVxuXG4vKipcbiAqIFBoeXNpY2FsIElEIG9mIHRoZSBjdXN0b20gcmVzb3VyY2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBQaHlzaWNhbFJlc291cmNlSWQge1xuXG4gIC8qKlxuICAgKiBFeHRyYWN0IHRoZSBwaHlzaWNhbCByZXNvdXJjZSBpZCBmcm9tIHRoZSBwYXRoIChkb3Qgbm90YXRpb24pIHRvIHRoZSBkYXRhIGluIHRoZSBBUEkgY2FsbCByZXNwb25zZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVJlc3BvbnNlKHJlc3BvbnNlUGF0aDogc3RyaW5nKTogUGh5c2ljYWxSZXNvdXJjZUlkIHtcbiAgICByZXR1cm4gbmV3IFBoeXNpY2FsUmVzb3VyY2VJZChyZXNwb25zZVBhdGgsIHVuZGVmaW5lZCk7XG4gIH1cblxuICAvKipcbiAgICogRXhwbGljaXQgcGh5c2ljYWwgcmVzb3VyY2UgaWQuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIG9mKGlkOiBzdHJpbmcpOiBQaHlzaWNhbFJlc291cmNlSWQge1xuICAgIHJldHVybiBuZXcgUGh5c2ljYWxSZXNvdXJjZUlkKHVuZGVmaW5lZCwgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSByZXNwb25zZVBhdGggUGF0aCB0byBhIHJlc3BvbnNlIGRhdGEgZWxlbWVudCB0byBiZSB1c2VkIGFzIHRoZSBwaHlzaWNhbCBpZC5cbiAgICogQHBhcmFtIGlkIExpdGVyYWwgc3RyaW5nIHRvIGJlIHVzZWQgYXMgdGhlIHBoeXNpY2FsIGlkLlxuICAgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgcmVzcG9uc2VQYXRoPzogc3RyaW5nLCBwdWJsaWMgcmVhZG9ubHkgaWQ/OiBzdHJpbmcpIHsgfVxufVxuXG4vKipcbiAqIEFuIEFXUyBTREsgY2FsbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBd3NTZGtDYWxsIHtcbiAgLyoqXG4gICAqIFRoZSBzZXJ2aWNlIHRvIGNhbGxcbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTSmF2YVNjcmlwdFNESy9sYXRlc3QvaW5kZXguaHRtbFxuICAgKi9cbiAgcmVhZG9ubHkgc2VydmljZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgc2VydmljZSBhY3Rpb24gdG8gY2FsbFxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NKYXZhU2NyaXB0U0RLL2xhdGVzdC9pbmRleC5odG1sXG4gICAqL1xuICByZWFkb25seSBhY3Rpb246IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBhcmFtZXRlcnMgZm9yIHRoZSBzZXJ2aWNlIGFjdGlvblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHBhcmFtZXRlcnNcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTSmF2YVNjcmlwdFNESy9sYXRlc3QvaW5kZXguaHRtbFxuICAgKi9cbiAgcmVhZG9ubHkgcGFyYW1ldGVycz86IGFueTtcblxuICAvKipcbiAgICogVGhlIHBoeXNpY2FsIHJlc291cmNlIGlkIG9mIHRoZSBjdXN0b20gcmVzb3VyY2UgZm9yIHRoaXMgY2FsbC5cbiAgICogTWFuZGF0b3J5IGZvciBvbkNyZWF0ZSBvciBvblVwZGF0ZSBjYWxscy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBwaHlzaWNhbCByZXNvdXJjZSBpZFxuICAgKi9cbiAgcmVhZG9ubHkgcGh5c2ljYWxSZXNvdXJjZUlkPzogUGh5c2ljYWxSZXNvdXJjZUlkO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVnZXggcGF0dGVybiB0byB1c2UgdG8gY2F0Y2ggQVBJIGVycm9ycy4gVGhlIGBjb2RlYCBwcm9wZXJ0eSBvZiB0aGVcbiAgICogYEVycm9yYCBvYmplY3Qgd2lsbCBiZSB0ZXN0ZWQgYWdhaW5zdCB0aGlzIHBhdHRlcm4uIElmIHRoZXJlIGlzIGEgbWF0Y2ggYW5cbiAgICogZXJyb3Igd2lsbCBub3QgYmUgdGhyb3duLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGRvIG5vdCBjYXRjaCBlcnJvcnNcbiAgICovXG4gIHJlYWRvbmx5IGlnbm9yZUVycm9yQ29kZXNNYXRjaGluZz86IHN0cmluZztcblxuICAvKipcbiAgICogQVBJIHZlcnNpb24gdG8gdXNlIGZvciB0aGUgc2VydmljZVxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZGstZm9yLWphdmFzY3JpcHQvdjIvZGV2ZWxvcGVyLWd1aWRlL2xvY2tpbmctYXBpLXZlcnNpb25zLmh0bWxcbiAgICogQGRlZmF1bHQgLSB1c2UgbGF0ZXN0IGF2YWlsYWJsZSBBUEkgdmVyc2lvblxuICAgKi9cbiAgcmVhZG9ubHkgYXBpVmVyc2lvbj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlZ2lvbiB0byBzZW5kIHNlcnZpY2UgcmVxdWVzdHMgdG8uXG4gICAqICoqTm90ZTogQ3Jvc3MtcmVnaW9uIG9wZXJhdGlvbnMgYXJlIGdlbmVyYWxseSBjb25zaWRlcmVkIGFuIGFudGktcGF0dGVybi4qKlxuICAgKiAqKkNvbnNpZGVyIGZpcnN0IGRlcGxveWluZyBhIHN0YWNrIGluIHRoYXQgcmVnaW9uLioqXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIHJlZ2lvbiB3aGVyZSB0aGlzIGN1c3RvbSByZXNvdXJjZSBpcyBkZXBsb3llZFxuICAgKi9cbiAgcmVhZG9ubHkgcmVnaW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBSZXN0cmljdCB0aGUgZGF0YSByZXR1cm5lZCBieSB0aGUgY3VzdG9tIHJlc291cmNlIHRvIGEgc3BlY2lmaWMgcGF0aCBpblxuICAgKiB0aGUgQVBJIHJlc3BvbnNlLiBVc2UgdGhpcyB0byBsaW1pdCB0aGUgZGF0YSByZXR1cm5lZCBieSB0aGUgY3VzdG9tXG4gICAqIHJlc291cmNlIGlmIHdvcmtpbmcgd2l0aCBBUEkgY2FsbHMgdGhhdCBjb3VsZCBwb3RlbnRpYWxseSByZXN1bHQgaW4gY3VzdG9tXG4gICAqIHJlc3BvbnNlIG9iamVjdHMgZXhjZWVkaW5nIHRoZSBoYXJkIGxpbWl0IG9mIDQwOTYgYnl0ZXMuXG4gICAqXG4gICAqIEV4YW1wbGUgZm9yIEVDUyAvIHVwZGF0ZVNlcnZpY2U6ICdzZXJ2aWNlLmRlcGxveW1lbnRDb25maWd1cmF0aW9uLm1heGltdW1QZXJjZW50J1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIHJldHVybiBhbGwgZGF0YVxuICAgKlxuICAgKiBAZGVwcmVjYXRlZCB1c2Ugb3V0cHV0UGF0aHMgaW5zdGVhZFxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0UGF0aD86IHN0cmluZztcblxuICAvKipcbiAgICogUmVzdHJpY3QgdGhlIGRhdGEgcmV0dXJuZWQgYnkgdGhlIGN1c3RvbSByZXNvdXJjZSB0byBzcGVjaWZpYyBwYXRocyBpblxuICAgKiB0aGUgQVBJIHJlc3BvbnNlLiBVc2UgdGhpcyB0byBsaW1pdCB0aGUgZGF0YSByZXR1cm5lZCBieSB0aGUgY3VzdG9tXG4gICAqIHJlc291cmNlIGlmIHdvcmtpbmcgd2l0aCBBUEkgY2FsbHMgdGhhdCBjb3VsZCBwb3RlbnRpYWxseSByZXN1bHQgaW4gY3VzdG9tXG4gICAqIHJlc3BvbnNlIG9iamVjdHMgZXhjZWVkaW5nIHRoZSBoYXJkIGxpbWl0IG9mIDQwOTYgYnl0ZXMuXG4gICAqXG4gICAqIEV4YW1wbGUgZm9yIEVDUyAvIHVwZGF0ZVNlcnZpY2U6IFsnc2VydmljZS5kZXBsb3ltZW50Q29uZmlndXJhdGlvbi5tYXhpbXVtUGVyY2VudCddXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gcmV0dXJuIGFsbCBkYXRhXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRQYXRocz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBVc2VkIGZvciBydW5uaW5nIHRoZSBTREsgY2FsbHMgaW4gdW5kZXJseWluZyBsYW1iZGEgd2l0aCBhIGRpZmZlcmVudCByb2xlXG4gICAqIENhbiBiZSB1c2VkIHByaW1hcmlseSBmb3IgY3Jvc3MtYWNjb3VudCByZXF1ZXN0cyB0byBmb3IgZXhhbXBsZSBjb25uZWN0XG4gICAqIGhvc3RlZHpvbmUgd2l0aCBhIHNoYXJlZCB2cGNcbiAgICpcbiAgICogRXhhbXBsZSBmb3IgUm91dGU1MyAvIGFzc29jaWF0ZVZQQ1dpdGhIb3N0ZWRab25lXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gcnVuIHdpdGhvdXQgYXNzdW1pbmcgcm9sZVxuICAgKi9cbiAgcmVhZG9ubHkgYXNzdW1lZFJvbGVBcm4/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgdGhlIGF1dG8tZ2VuZXJhdGlvbiBvZiBwb2xpY2llcyBiYXNlZCBvbiB0aGUgY29uZmlndXJlZCBTREsgY2FsbHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2RrQ2FsbHNQb2xpY3lPcHRpb25zIHtcblxuICAvKipcbiAgICogVGhlIHJlc291cmNlcyB0aGF0IHRoZSBjYWxscyB3aWxsIGhhdmUgYWNjZXNzIHRvLlxuICAgKlxuICAgKiBJdCBpcyBiZXN0IHRvIHVzZSBzcGVjaWZpYyByZXNvdXJjZSBBUk4ncyB3aGVuIHBvc3NpYmxlLiBIb3dldmVyLCB5b3UgY2FuIGFsc28gdXNlIGBBd3NDdXN0b21SZXNvdXJjZVBvbGljeS5BTllfUkVTT1VSQ0VgXG4gICAqIHRvIGFsbG93IGFjY2VzcyB0byBhbGwgcmVzb3VyY2VzLiBGb3IgZXhhbXBsZSwgd2hlbiBgb25DcmVhdGVgIGlzIHVzZWQgdG8gY3JlYXRlIGEgcmVzb3VyY2Ugd2hpY2ggeW91IGRvbid0XG4gICAqIGtub3cgdGhlIHBoeXNpY2FsIG5hbWUgb2YgaW4gYWR2YW5jZS5cbiAgICpcbiAgICogTm90ZSB0aGF0IHdpbGwgYXBwbHkgdG8gQUxMIFNESyBjYWxscy5cbiAgICovXG4gIHJlYWRvbmx5IHJlc291cmNlczogc3RyaW5nW11cblxufVxuXG4vKipcbiAqIFRoZSBJQU0gUG9saWN5IHRoYXQgd2lsbCBiZSBhcHBsaWVkIHRvIHRoZSBkaWZmZXJlbnQgY2FsbHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBBd3NDdXN0b21SZXNvdXJjZVBvbGljeSB7XG5cbiAgLyoqXG4gICAqIFVzZSB0aGlzIGNvbnN0YW50IHRvIGNvbmZpZ3VyZSBhY2Nlc3MgdG8gYW55IHJlc291cmNlLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBBTllfUkVTT1VSQ0UgPSBbJyonXTtcblxuICAvKipcbiAgICogRXhwbGljaXQgSUFNIFBvbGljeSBTdGF0ZW1lbnRzLlxuICAgKlxuICAgKiBAcGFyYW0gc3RhdGVtZW50cyB0aGUgc3RhdGVtZW50cyB0byBwcm9wYWdhdGUgdG8gdGhlIFNESyBjYWxscy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVN0YXRlbWVudHMoc3RhdGVtZW50czogaWFtLlBvbGljeVN0YXRlbWVudFtdKSB7XG4gICAgcmV0dXJuIG5ldyBBd3NDdXN0b21SZXNvdXJjZVBvbGljeShzdGF0ZW1lbnRzLCB1bmRlZmluZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIElBTSBQb2xpY3kgU3RhdGVtZW50cyBmcm9tIHRoZSBjb25maWd1cmVkIFNESyBjYWxscy5cbiAgICpcbiAgICogRWFjaCBTREsgY2FsbCB3aXRoIGJlIHRyYW5zbGF0ZWQgdG8gYW4gSUFNIFBvbGljeSBTdGF0ZW1lbnQgaW4gdGhlIGZvcm0gb2Y6IGBjYWxsLnNlcnZpY2U6Y2FsbC5hY3Rpb25gIChlLmcgYHMzOlB1dE9iamVjdGApLlxuICAgKlxuICAgKiBUaGlzIHBvbGljeSBnZW5lcmF0b3IgYXNzdW1lcyB0aGUgSUFNIHBvbGljeSBuYW1lIGhhcyB0aGUgc2FtZSBuYW1lIGFzIHRoZSBBUElcbiAgICogY2FsbC4gVGhpcyBpcyB0cnVlIGluIDk5JSBvZiBjYXNlcywgYnV0IHRoZXJlIGFyZSBleGNlcHRpb25zIChmb3IgZXhhbXBsZSxcbiAgICogUzMncyBgUHV0QnVja2V0TGlmZWN5Y2xlQ29uZmlndXJhdGlvbmAgcmVxdWlyZXNcbiAgICogYHMzOlB1dExpZmVjeWNsZUNvbmZpZ3VyYXRpb25gIHBlcm1pc3Npb25zLCBMYW1iZGEncyBgSW52b2tlYCByZXF1aXJlc1xuICAgKiBgbGFtYmRhOkludm9rZUZ1bmN0aW9uYCBwZXJtaXNzaW9ucykuIFVzZSBgZnJvbVN0YXRlbWVudHNgIGlmIHlvdSB3YW50IHRvXG4gICAqIGRvIGEgY2FsbCB0aGF0IHJlcXVpcmVzIGRpZmZlcmVudCBJQU0gYWN0aW9uIG5hbWVzLlxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyBvcHRpb25zIGZvciB0aGUgcG9saWN5IGdlbmVyYXRpb25cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVNka0NhbGxzKG9wdGlvbnM6IFNka0NhbGxzUG9saWN5T3B0aW9ucykge1xuICAgIHJldHVybiBuZXcgQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3koW10sIG9wdGlvbnMucmVzb3VyY2VzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gc3RhdGVtZW50cyBzdGF0ZW1lbnRzIGZvciBleHBsaWNpdCBwb2xpY3kuXG4gICAqIEBwYXJhbSByZXNvdXJjZXMgcmVzb3VyY2VzIGZvciBhdXRvLWdlbmVyYXRlZCBmcm9tIFNESyBjYWxscy5cbiAgICovXG4gIHByaXZhdGUgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHN0YXRlbWVudHM6IGlhbS5Qb2xpY3lTdGF0ZW1lbnRbXSwgcHVibGljIHJlYWRvbmx5IHJlc291cmNlcz86IHN0cmluZ1tdKSB7fVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIEF3c0N1c3RvbVJlc291cmNlLlxuICpcbiAqIE5vdGUgdGhhdCBhdCBsZWFzdCBvbkNyZWF0ZSwgb25VcGRhdGUgb3Igb25EZWxldGUgbXVzdCBiZSBzcGVjaWZpZWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXdzQ3VzdG9tUmVzb3VyY2VQcm9wcyB7XG4gIC8qKlxuICAgKiBDbG91ZGZvcm1hdGlvbiBSZXNvdXJjZSB0eXBlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEN1c3RvbTo6QVdTXG4gICAqL1xuICByZWFkb25seSByZXNvdXJjZVR5cGU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBBV1MgU0RLIGNhbGwgdG8gbWFrZSB3aGVuIHRoZSByZXNvdXJjZSBpcyBjcmVhdGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRoZSBjYWxsIHdoZW4gdGhlIHJlc291cmNlIGlzIHVwZGF0ZWRcbiAgICovXG4gIHJlYWRvbmx5IG9uQ3JlYXRlPzogQXdzU2RrQ2FsbDtcblxuICAvKipcbiAgICogVGhlIEFXUyBTREsgY2FsbCB0byBtYWtlIHdoZW4gdGhlIHJlc291cmNlIGlzIHVwZGF0ZWRcbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBjYWxsXG4gICAqL1xuICByZWFkb25seSBvblVwZGF0ZT86IEF3c1Nka0NhbGw7XG5cbiAgLyoqXG4gICAqIFRoZSBBV1MgU0RLIGNhbGwgdG8gbWFrZSB3aGVuIHRoZSByZXNvdXJjZSBpcyBkZWxldGVkXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gY2FsbFxuICAgKi9cbiAgcmVhZG9ubHkgb25EZWxldGU/OiBBd3NTZGtDYWxsO1xuXG4gIC8qKlxuICAgKiBUaGUgcG9saWN5IHRoYXQgd2lsbCBiZSBhZGRlZCB0byB0aGUgZXhlY3V0aW9uIHJvbGUgb2YgdGhlIExhbWJkYVxuICAgKiBmdW5jdGlvbiBpbXBsZW1lbnRpbmcgdGhpcyBjdXN0b20gcmVzb3VyY2UgcHJvdmlkZXIuXG4gICAqXG4gICAqIFRoZSBjdXN0b20gcmVzb3VyY2UgYWxzbyBpbXBsZW1lbnRzIGBpYW0uSUdyYW50YWJsZWAsIG1ha2luZyBpdCBwb3NzaWJsZVxuICAgKiB0byB1c2UgdGhlIGBncmFudFh4eCgpYCBtZXRob2RzLlxuICAgKlxuICAgKiBBcyB0aGlzIGN1c3RvbSByZXNvdXJjZSB1c2VzIGEgc2luZ2xldG9uIExhbWJkYSBmdW5jdGlvbiwgaXQncyBpbXBvcnRhbnRcbiAgICogdG8gbm90ZSB0aGUgdGhhdCBmdW5jdGlvbidzIHJvbGUgd2lsbCBldmVudHVhbGx5IGFjY3VtdWxhdGUgdGhlXG4gICAqIHBlcm1pc3Npb25zL2dyYW50cyBmcm9tIGFsbCByZXNvdXJjZXMuXG4gICAqXG4gICAqIEBzZWUgUG9saWN5LmZyb21TdGF0ZW1lbnRzXG4gICAqIEBzZWUgUG9saWN5LmZyb21TZGtDYWxsc1xuICAgKi9cbiAgcmVhZG9ubHkgcG9saWN5OiBBd3NDdXN0b21SZXNvdXJjZVBvbGljeTtcblxuICAvKipcbiAgICogVGhlIGV4ZWN1dGlvbiByb2xlIGZvciB0aGUgc2luZ2xldG9uIExhbWJkYSBmdW5jdGlvbiBpbXBsZW1lbnRpbmcgdGhpcyBjdXN0b21cbiAgICogcmVzb3VyY2UgcHJvdmlkZXIuIFRoaXMgcm9sZSB3aWxsIGFwcGx5IHRvIGFsbCBgQXdzQ3VzdG9tUmVzb3VyY2VgXG4gICAqIGluc3RhbmNlcyBpbiB0aGUgc3RhY2suIFRoZSByb2xlIG11c3QgYmUgYXNzdW1hYmxlIGJ5IHRoZVxuICAgKiBgbGFtYmRhLmFtYXpvbmF3cy5jb21gIHNlcnZpY2UgcHJpbmNpcGFsLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGEgbmV3IHJvbGUgaXMgY3JlYXRlZFxuICAgKi9cbiAgcmVhZG9ubHkgcm9sZT86IGlhbS5JUm9sZTtcblxuICAvKipcbiAgICogVGhlIHRpbWVvdXQgZm9yIHRoZSBzaW5nbGV0b24gTGFtYmRhIGZ1bmN0aW9uIGltcGxlbWVudGluZyB0aGlzIGN1c3RvbSByZXNvdXJjZS5cbiAgICpcbiAgICogQGRlZmF1bHQgRHVyYXRpb24ubWludXRlcygyKVxuICAgKi9cbiAgcmVhZG9ubHkgdGltZW91dD86IGNkay5EdXJhdGlvblxuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGRheXMgbG9nIGV2ZW50cyBvZiB0aGUgc2luZ2xldG9uIExhbWJkYSBmdW5jdGlvbiBpbXBsZW1lbnRpbmdcbiAgICogdGhpcyBjdXN0b20gcmVzb3VyY2UgYXJlIGtlcHQgaW4gQ2xvdWRXYXRjaCBMb2dzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBsb2dzLlJldGVudGlvbkRheXMuSU5GSU5JVEVcbiAgICovXG4gIHJlYWRvbmx5IGxvZ1JldGVudGlvbj86IGxvZ3MuUmV0ZW50aW9uRGF5cztcblxuICAvKipcbiAgICogV2hldGhlciB0byBpbnN0YWxsIHRoZSBsYXRlc3QgQVdTIFNESyB2Mi4gQWxsb3dzIHRvIHVzZSB0aGUgbGF0ZXN0IEFQSVxuICAgKiBjYWxscyBkb2N1bWVudGVkIGF0IGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NKYXZhU2NyaXB0U0RLL2xhdGVzdC9pbmRleC5odG1sLlxuICAgKlxuICAgKiBUaGUgaW5zdGFsbGF0aW9uIHRha2VzIGFyb3VuZCA2MCBzZWNvbmRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBpbnN0YWxsTGF0ZXN0QXdzU2RrPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQSBuYW1lIGZvciB0aGUgc2luZ2xldG9uIExhbWJkYSBmdW5jdGlvbiBpbXBsZW1lbnRpbmcgdGhpcyBjdXN0b20gcmVzb3VyY2UuXG4gICAqIFRoZSBmdW5jdGlvbiBuYW1lIHdpbGwgcmVtYWluIHRoZSBzYW1lIGFmdGVyIHRoZSBmaXJzdCBBd3NDdXN0b21SZXNvdXJjZSBpcyBjcmVhdGVkIGluIGEgc3RhY2suXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQVdTIENsb3VkRm9ybWF0aW9uIGdlbmVyYXRlcyBhIHVuaXF1ZSBwaHlzaWNhbCBJRCBhbmQgdXNlcyB0aGF0XG4gICAqIElEIGZvciB0aGUgZnVuY3Rpb24ncyBuYW1lLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIE5hbWUgVHlwZS5cbiAgICovXG4gIHJlYWRvbmx5IGZ1bmN0aW9uTmFtZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZWZpbmVzIGEgY3VzdG9tIHJlc291cmNlIHRoYXQgaXMgbWF0ZXJpYWxpemVkIHVzaW5nIHNwZWNpZmljIEFXUyBBUEkgY2FsbHMuIFRoZXNlIGNhbGxzIGFyZSBjcmVhdGVkIHVzaW5nXG4gKiBhIHNpbmdsZXRvbiBMYW1iZGEgZnVuY3Rpb24uXG4gKlxuICogVXNlIHRoaXMgdG8gYnJpZGdlIGFueSBnYXAgdGhhdCBtaWdodCBleGlzdCBpbiB0aGUgQ2xvdWRGb3JtYXRpb24gQ292ZXJhZ2UuXG4gKiBZb3UgY2FuIHNwZWNpZnkgZXhhY3RseSB3aGljaCBjYWxscyBhcmUgaW52b2tlZCBmb3IgdGhlICdDUkVBVEUnLCAnVVBEQVRFJyBhbmQgJ0RFTEVURScgbGlmZSBjeWNsZSBldmVudHMuXG4gKlxuICovXG5leHBvcnQgY2xhc3MgQXdzQ3VzdG9tUmVzb3VyY2UgZXh0ZW5kcyBDb3JlQ29uc3RydWN0IGltcGxlbWVudHMgaWFtLklHcmFudGFibGUge1xuXG4gIHByaXZhdGUgc3RhdGljIGJyZWFrSWdub3JlRXJyb3JzQ2lyY3VpdChzZGtDYWxsczogQXJyYXk8QXdzU2RrQ2FsbCB8IHVuZGVmaW5lZD4sIGNhbGxlcjogc3RyaW5nKSB7XG5cbiAgICBmb3IgKGNvbnN0IGNhbGwgb2Ygc2RrQ2FsbHMpIHtcbiAgICAgIGlmIChjYWxsPy5pZ25vcmVFcnJvckNvZGVzTWF0Y2hpbmcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBcXGAke2NhbGxlcn1cXGBgICsgJyBjYW5ub3QgYmUgY2FsbGVkIGFsb25nIHdpdGggYGlnbm9yZUVycm9yQ29kZXNNYXRjaGluZ2AuJyk7XG4gICAgICB9XG4gICAgfVxuXG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRQcmluY2lwYWw6IGlhbS5JUHJpbmNpcGFsO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY3VzdG9tUmVzb3VyY2U6IGNkay5DdXN0b21SZXNvdXJjZTtcbiAgcHJpdmF0ZSByZWFkb25seSBwcm9wczogQXdzQ3VzdG9tUmVzb3VyY2VQcm9wcztcblxuICAvLyAncHJvcHMnIGNhbm5vdCBiZSBvcHRpb25hbCwgZXZlbiB0aG91Z2ggYWxsIGl0cyBwcm9wZXJ0aWVzIGFyZSBvcHRpb25hbC5cbiAgLy8gdGhpcyBpcyBiZWNhdXNlIGF0IGxlYXN0IG9uZSBzZGsgY2FsbCBtdXN0IGJlIHByb3ZpZGVkLlxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQXdzQ3VzdG9tUmVzb3VyY2VQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBpZiAoIXByb3BzLm9uQ3JlYXRlICYmICFwcm9wcy5vblVwZGF0ZSAmJiAhcHJvcHMub25EZWxldGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQXQgbGVhc3QgYG9uQ3JlYXRlYCwgYG9uVXBkYXRlYCBvciBgb25EZWxldGVgIG11c3QgYmUgc3BlY2lmaWVkLicpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgY2FsbCBvZiBbcHJvcHMub25DcmVhdGUsIHByb3BzLm9uVXBkYXRlXSkge1xuICAgICAgaWYgKGNhbGwgJiYgIWNhbGwucGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYHBoeXNpY2FsUmVzb3VyY2VJZGAgbXVzdCBiZSBzcGVjaWZpZWQgZm9yIG9uQ3JlYXRlIGFuZCBvblVwZGF0ZSBjYWxscy4nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNhbGwgb2YgW3Byb3BzLm9uQ3JlYXRlLCBwcm9wcy5vblVwZGF0ZSwgcHJvcHMub25EZWxldGVdKSB7XG4gICAgICBpZiAoY2FsbD8ucGh5c2ljYWxSZXNvdXJjZUlkPy5yZXNwb25zZVBhdGgpIHtcbiAgICAgICAgQXdzQ3VzdG9tUmVzb3VyY2UuYnJlYWtJZ25vcmVFcnJvcnNDaXJjdWl0KFtjYWxsXSwgJ1BoeXNpY2FsUmVzb3VyY2VJZC5mcm9tUmVzcG9uc2UnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaW5jbHVkZXNQaHlzaWNhbFJlc291cmNlSWRSZWYocHJvcHMub25DcmVhdGU/LnBhcmFtZXRlcnMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2BQaHlzaWNhbFJlc291cmNlSWRSZWZlcmVuY2VgIG11c3Qgbm90IGJlIHNwZWNpZmllZCBpbiBgb25DcmVhdGVgIHBhcmFtZXRlcnMuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5wcm9wcyA9IHByb3BzO1xuXG4gICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgbGFtYmRhLlNpbmdsZXRvbkZ1bmN0aW9uKHRoaXMsICdQcm92aWRlcicsIHtcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCAncnVudGltZScpLCB7XG4gICAgICAgIGV4Y2x1ZGU6IFsnKi50cyddLFxuICAgICAgfSksXG4gICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5OT0RFSlNfMTRfWCxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIHV1aWQ6ICc2NzlmNTNmYS1jMDAyLTQzMGMtYjBkYS01Yjc5ODJiZDIyODcnLFxuICAgICAgbGFtYmRhUHVycG9zZTogJ0FXUycsXG4gICAgICB0aW1lb3V0OiBwcm9wcy50aW1lb3V0IHx8IGNkay5EdXJhdGlvbi5taW51dGVzKDIpLFxuICAgICAgcm9sZTogcHJvcHMucm9sZSxcbiAgICAgIGxvZ1JldGVudGlvbjogcHJvcHMubG9nUmV0ZW50aW9uLFxuICAgICAgZnVuY3Rpb25OYW1lOiBwcm9wcy5mdW5jdGlvbk5hbWUsXG4gICAgfSk7XG4gICAgdGhpcy5ncmFudFByaW5jaXBhbCA9IHByb3ZpZGVyLmdyYW50UHJpbmNpcGFsO1xuXG4gICAgLy8gQ3JlYXRlIHRoZSBwb2xpY3kgc3RhdGVtZW50cyBmb3IgdGhlIGN1c3RvbSByZXNvdXJjZSBmdW5jdGlvbiByb2xlLCBvciB1c2UgdGhlIHVzZXItcHJvdmlkZWQgb25lc1xuICAgIGNvbnN0IHN0YXRlbWVudHMgPSBbXTtcbiAgICBpZiAocHJvcHMucG9saWN5LnN0YXRlbWVudHMubGVuZ3RoICE9PSAwKSB7XG4gICAgICAvLyBVc2UgY3VzdG9tIHN0YXRlbWVudHMgcHJvdmlkZWQgYnkgdGhlIHVzZXJcbiAgICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIHByb3BzLnBvbGljeS5zdGF0ZW1lbnRzKSB7XG4gICAgICAgIHN0YXRlbWVudHMucHVzaChzdGF0ZW1lbnQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZXJpdmUgc3RhdGVtZW50cyBmcm9tIEFXUyBTREsgY2FsbHNcbiAgICAgIGZvciAoY29uc3QgY2FsbCBvZiBbcHJvcHMub25DcmVhdGUsIHByb3BzLm9uVXBkYXRlLCBwcm9wcy5vbkRlbGV0ZV0pIHtcbiAgICAgICAgaWYgKGNhbGwgJiYgY2FsbC5hc3N1bWVkUm9sZUFybiA9PSBudWxsKSB7XG4gICAgICAgICAgY29uc3Qgc3RhdGVtZW50ID0gbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW2F3c1Nka1RvSWFtQWN0aW9uKGNhbGwuc2VydmljZSwgY2FsbC5hY3Rpb24pXSxcbiAgICAgICAgICAgIHJlc291cmNlczogcHJvcHMucG9saWN5LnJlc291cmNlcyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzdGF0ZW1lbnRzLnB1c2goc3RhdGVtZW50KTtcbiAgICAgICAgfSBlbHNlIGlmIChjYWxsICYmIGNhbGwuYXNzdW1lZFJvbGVBcm4gIT0gbnVsbCkge1xuICAgICAgICAgIGNvbnN0IHN0YXRlbWVudCA9IG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFsnc3RzOkFzc3VtZVJvbGUnXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW2NhbGwuYXNzdW1lZFJvbGVBcm5dLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHN0YXRlbWVudHMucHVzaChzdGF0ZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHBvbGljeSA9IG5ldyBpYW0uUG9saWN5KHRoaXMsICdDdXN0b21SZXNvdXJjZVBvbGljeScsIHtcbiAgICAgIHN0YXRlbWVudHM6IHN0YXRlbWVudHMsXG4gICAgfSk7XG4gICAgaWYgKHByb3ZpZGVyLnJvbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcG9saWN5LmF0dGFjaFRvUm9sZShwcm92aWRlci5yb2xlKTtcbiAgICB9XG4gICAgY29uc3QgY3JlYXRlID0gcHJvcHMub25DcmVhdGUgfHwgcHJvcHMub25VcGRhdGU7XG4gICAgdGhpcy5jdXN0b21SZXNvdXJjZSA9IG5ldyBjZGsuQ3VzdG9tUmVzb3VyY2UodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgcmVzb3VyY2VUeXBlOiBwcm9wcy5yZXNvdXJjZVR5cGUgfHwgJ0N1c3RvbTo6QVdTJyxcbiAgICAgIHNlcnZpY2VUb2tlbjogcHJvdmlkZXIuZnVuY3Rpb25Bcm4sXG4gICAgICBwYXNjYWxDYXNlUHJvcGVydGllczogdHJ1ZSxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgY3JlYXRlOiBjcmVhdGUgJiYgdGhpcy5lbmNvZGVKc29uKGNyZWF0ZSksXG4gICAgICAgIHVwZGF0ZTogcHJvcHMub25VcGRhdGUgJiYgdGhpcy5lbmNvZGVKc29uKHByb3BzLm9uVXBkYXRlKSxcbiAgICAgICAgZGVsZXRlOiBwcm9wcy5vbkRlbGV0ZSAmJiB0aGlzLmVuY29kZUpzb24ocHJvcHMub25EZWxldGUpLFxuICAgICAgICBpbnN0YWxsTGF0ZXN0QXdzU2RrOiBwcm9wcy5pbnN0YWxsTGF0ZXN0QXdzU2RrID8/IHRydWUsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gSWYgdGhlIHBvbGljeSB3YXMgZGVsZXRlZCBmaXJzdCwgdGhlbiB0aGUgZnVuY3Rpb24gbWlnaHQgbG9zZSBwZXJtaXNzaW9ucyB0byBkZWxldGUgdGhlIGN1c3RvbSByZXNvdXJjZVxuICAgIC8vIFRoaXMgaXMgaGVyZSBzbyB0aGF0IHRoZSBwb2xpY3kgZG9lc24ndCBnZXQgcmVtb3ZlZCBiZWZvcmUgb25EZWxldGUgaXMgY2FsbGVkXG4gICAgdGhpcy5jdXN0b21SZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3kocG9saWN5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHJlc3BvbnNlIGRhdGEgZm9yIHRoZSBBV1MgU0RLIGNhbGwuXG4gICAqXG4gICAqIEV4YW1wbGUgZm9yIFMzIC8gbGlzdEJ1Y2tldCA6ICdCdWNrZXRzLjAuTmFtZSdcbiAgICpcbiAgICogVXNlIGBUb2tlbi5hc1h4eGAgdG8gZW5jb2RlIHRoZSByZXR1cm5lZCBgUmVmZXJlbmNlYCBhcyBhIHNwZWNpZmljIHR5cGUgb3JcbiAgICogdXNlIHRoZSBjb252ZW5pZW5jZSBgZ2V0RGF0YVN0cmluZ2AgZm9yIHN0cmluZyBhdHRyaWJ1dGVzLlxuICAgKlxuICAgKiBOb3RlIHRoYXQgeW91IGNhbm5vdCB1c2UgdGhpcyBtZXRob2QgaWYgYGlnbm9yZUVycm9yQ29kZXNNYXRjaGluZ2BcbiAgICogaXMgY29uZmlndXJlZCBmb3IgYW55IG9mIHRoZSBTREsgY2FsbHMuIFRoaXMgaXMgYmVjYXVzZSBpbiBzdWNoIGEgY2FzZSxcbiAgICogdGhlIHJlc3BvbnNlIGRhdGEgbWlnaHQgbm90IGV4aXN0LCBhbmQgd2lsbCBjYXVzZSBhIENsb3VkRm9ybWF0aW9uIGRlcGxveSB0aW1lIGVycm9yLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YVBhdGggdGhlIHBhdGggdG8gdGhlIGRhdGFcbiAgICovXG4gIHB1YmxpYyBnZXRSZXNwb25zZUZpZWxkUmVmZXJlbmNlKGRhdGFQYXRoOiBzdHJpbmcpIHtcbiAgICBBd3NDdXN0b21SZXNvdXJjZS5icmVha0lnbm9yZUVycm9yc0NpcmN1aXQoW3RoaXMucHJvcHMub25DcmVhdGUsIHRoaXMucHJvcHMub25VcGRhdGVdLCAnZ2V0RGF0YScpO1xuICAgIHJldHVybiB0aGlzLmN1c3RvbVJlc291cmNlLmdldEF0dChkYXRhUGF0aCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyByZXNwb25zZSBkYXRhIGZvciB0aGUgQVdTIFNESyBjYWxsIGFzIHN0cmluZy5cbiAgICpcbiAgICogRXhhbXBsZSBmb3IgUzMgLyBsaXN0QnVja2V0IDogJ0J1Y2tldHMuMC5OYW1lJ1xuICAgKlxuICAgKiBOb3RlIHRoYXQgeW91IGNhbm5vdCB1c2UgdGhpcyBtZXRob2QgaWYgYGlnbm9yZUVycm9yQ29kZXNNYXRjaGluZ2BcbiAgICogaXMgY29uZmlndXJlZCBmb3IgYW55IG9mIHRoZSBTREsgY2FsbHMuIFRoaXMgaXMgYmVjYXVzZSBpbiBzdWNoIGEgY2FzZSxcbiAgICogdGhlIHJlc3BvbnNlIGRhdGEgbWlnaHQgbm90IGV4aXN0LCBhbmQgd2lsbCBjYXVzZSBhIENsb3VkRm9ybWF0aW9uIGRlcGxveSB0aW1lIGVycm9yLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YVBhdGggdGhlIHBhdGggdG8gdGhlIGRhdGFcbiAgICovXG4gIHB1YmxpYyBnZXRSZXNwb25zZUZpZWxkKGRhdGFQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIEF3c0N1c3RvbVJlc291cmNlLmJyZWFrSWdub3JlRXJyb3JzQ2lyY3VpdChbdGhpcy5wcm9wcy5vbkNyZWF0ZSwgdGhpcy5wcm9wcy5vblVwZGF0ZV0sICdnZXREYXRhU3RyaW5nJyk7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUmVzb3VyY2UuZ2V0QXR0U3RyaW5nKGRhdGFQYXRoKTtcbiAgfVxuXG4gIHByaXZhdGUgZW5jb2RlSnNvbihvYmo6IGFueSkge1xuICAgIHJldHVybiBjZGsuTGF6eS51bmNhY2hlZFN0cmluZyh7IHByb2R1Y2U6ICgpID0+IGNkay5TdGFjay5vZih0aGlzKS50b0pzb25TdHJpbmcob2JqKSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIEFXUyBTREsgc2VydmljZSBtZXRhZGF0YS5cbiAqL1xuZXhwb3J0IHR5cGUgQXdzU2RrTWV0YWRhdGEgPSB7W2tleTogc3RyaW5nXTogYW55fTtcblxuLyoqXG4gKiBHZXRzIGF3c1Nka01ldGFEYXRhIGZyb20gZmlsZSBvciBmcm9tIGNhY2hlXG4gKi9cbmxldCBnZXRBd3NTZGtNZXRhZGF0YSA9ICgoKSA9PiB7XG4gIGxldCBfYXdzU2RrTWV0YWRhdGE6IEF3c1Nka01ldGFkYXRhO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmIChfYXdzU2RrTWV0YWRhdGEpIHtcbiAgICAgIHJldHVybiBfYXdzU2RrTWV0YWRhdGE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBfYXdzU2RrTWV0YWRhdGEgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oX19kaXJuYW1lLCAnc2RrLWFwaS1tZXRhZGF0YS5qc29uJyksICd1dGYtOCcpKTtcbiAgICB9XG4gIH07XG59KSgpO1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBgb2JqYCBpbmNsdWRlcyBhIGBQaHlzaWNhbFJlc291cmNlSWRSZWZlcmVuY2VgIGluIG9uZSBvZiB0aGVcbiAqIHZhbHVlcy5cbiAqIEBwYXJhbSBvYmogQW55IG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gaW5jbHVkZXNQaHlzaWNhbFJlc291cmNlSWRSZWYob2JqOiBhbnkgfCB1bmRlZmluZWQpIHtcbiAgaWYgKG9iaiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgbGV0IGZvdW5kUmVmID0gZmFsc2U7XG5cbiAgLy8gd2UgdXNlIEpTT04uc3RyaW5naWZ5IGFzIGEgd2F5IHRvIHRyYXZlcnNlIGFsbCB2YWx1ZXMgaW4gdGhlIG9iamVjdC5cbiAgSlNPTi5zdHJpbmdpZnkob2JqLCAoXywgdikgPT4ge1xuICAgIGlmICh2ID09PSBQSFlTSUNBTF9SRVNPVVJDRV9JRF9SRUZFUkVOQ0UpIHtcbiAgICAgIGZvdW5kUmVmID0gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdjtcbiAgfSk7XG5cbiAgcmV0dXJuIGZvdW5kUmVmO1xufVxuXG4vKipcbiAqIFRyYW5zZm9ybSBTREsgc2VydmljZS9hY3Rpb24gdG8gSUFNIGFjdGlvbiB1c2luZyBtZXRhZGF0YSBmcm9tIGF3cy1zZGsgbW9kdWxlLlxuICogRXhhbXBsZTogQ2xvdWRXYXRjaExvZ3Mgd2l0aCBwdXRSZXRlbnRpb25Qb2xpY3kgPT4gbG9nczpQdXRSZXRlbnRpb25Qb2xpY3lcbiAqXG4gKiBUT0RPOiBpcyB0aGlzIG1hcHBpbmcgY29ycmVjdCBmb3IgYWxsIHNlcnZpY2VzP1xuICovXG5mdW5jdGlvbiBhd3NTZGtUb0lhbUFjdGlvbihzZXJ2aWNlOiBzdHJpbmcsIGFjdGlvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgc3J2ID0gc2VydmljZS50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBhd3NTZGtNZXRhZGF0YSA9IGdldEF3c1Nka01ldGFkYXRhKCk7XG4gIGNvbnN0IGlhbVNlcnZpY2UgPSAoYXdzU2RrTWV0YWRhdGFbc3J2XSAmJiBhd3NTZGtNZXRhZGF0YVtzcnZdLnByZWZpeCkgfHwgc3J2O1xuICBjb25zdCBpYW1BY3Rpb24gPSBhY3Rpb24uY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBhY3Rpb24uc2xpY2UoMSk7XG4gIHJldHVybiBgJHtpYW1TZXJ2aWNlfToke2lhbUFjdGlvbn1gO1xufVxuIl19 |
\ | No newline at end of file |