@hanzo/s3 0.6.4 → 8.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +202 -0
  2. package/MAINTAINERS.md +62 -0
  3. package/README.md +262 -0
  4. package/README_zh_CN.md +192 -0
  5. package/dist/esm/AssumeRoleProvider.d.mts +86 -0
  6. package/dist/esm/AssumeRoleProvider.mjs +183 -0
  7. package/dist/esm/CredentialProvider.d.mts +22 -0
  8. package/dist/esm/CredentialProvider.mjs +48 -0
  9. package/dist/esm/Credentials.d.mts +22 -0
  10. package/dist/esm/Credentials.mjs +38 -0
  11. package/dist/esm/IamAwsProvider.d.mts +27 -0
  12. package/dist/esm/IamAwsProvider.mjs +189 -0
  13. package/dist/esm/errors.d.mts +82 -0
  14. package/dist/esm/errors.mjs +117 -0
  15. package/dist/esm/helpers.d.mts +156 -0
  16. package/dist/esm/helpers.mjs +218 -0
  17. package/dist/esm/internal/async.d.mts +9 -0
  18. package/dist/esm/internal/async.mjs +14 -0
  19. package/dist/esm/internal/callbackify.d.mts +1 -0
  20. package/dist/esm/internal/callbackify.mjs +15 -0
  21. package/dist/esm/internal/client.d.mts +394 -0
  22. package/dist/esm/internal/client.mjs +3007 -0
  23. package/dist/esm/internal/copy-conditions.d.mts +10 -0
  24. package/dist/esm/internal/copy-conditions.mjs +25 -0
  25. package/dist/esm/internal/extensions.d.mts +18 -0
  26. package/dist/esm/internal/extensions.mjs +114 -0
  27. package/dist/esm/internal/helper.d.mts +177 -0
  28. package/dist/esm/internal/helper.mjs +552 -0
  29. package/dist/esm/internal/join-host-port.d.mts +11 -0
  30. package/dist/esm/internal/join-host-port.mjs +23 -0
  31. package/dist/esm/internal/post-policy.d.mts +17 -0
  32. package/dist/esm/internal/post-policy.mjs +98 -0
  33. package/dist/esm/internal/request.d.mts +11 -0
  34. package/dist/esm/internal/request.mjs +75 -0
  35. package/dist/esm/internal/response.d.mts +8 -0
  36. package/dist/esm/internal/response.mjs +16 -0
  37. package/dist/esm/internal/s3-endpoints.d.mts +38 -0
  38. package/dist/esm/internal/s3-endpoints.mjs +68 -0
  39. package/dist/esm/internal/type.d.mts +482 -0
  40. package/dist/esm/internal/type.mjs +30 -0
  41. package/dist/esm/internal/xml-parser.d.mts +93 -0
  42. package/dist/esm/internal/xml-parser.mjs +819 -0
  43. package/dist/esm/notification.d.mts +58 -0
  44. package/dist/esm/notification.mjs +209 -0
  45. package/dist/esm/s3.d.mts +40 -0
  46. package/dist/esm/s3.mjs +86 -0
  47. package/dist/esm/signing.d.mts +5 -0
  48. package/dist/esm/signing.mjs +258 -0
  49. package/dist/main/AssumeRoleProvider.d.ts +86 -0
  50. package/dist/main/AssumeRoleProvider.js +191 -0
  51. package/dist/main/CredentialProvider.d.ts +22 -0
  52. package/dist/main/CredentialProvider.js +55 -0
  53. package/dist/main/Credentials.d.ts +22 -0
  54. package/dist/main/Credentials.js +45 -0
  55. package/dist/main/IamAwsProvider.d.ts +27 -0
  56. package/dist/main/IamAwsProvider.js +198 -0
  57. package/dist/main/errors.d.ts +82 -0
  58. package/dist/main/errors.js +138 -0
  59. package/dist/main/helpers.d.ts +156 -0
  60. package/dist/main/helpers.js +233 -0
  61. package/dist/main/internal/async.d.ts +9 -0
  62. package/dist/main/internal/async.js +24 -0
  63. package/dist/main/internal/callbackify.d.ts +1 -0
  64. package/dist/main/internal/callbackify.js +21 -0
  65. package/dist/main/internal/client.d.ts +394 -0
  66. package/dist/main/internal/client.js +3014 -0
  67. package/dist/main/internal/copy-conditions.d.ts +10 -0
  68. package/dist/main/internal/copy-conditions.js +31 -0
  69. package/dist/main/internal/extensions.d.ts +18 -0
  70. package/dist/main/internal/extensions.js +122 -0
  71. package/dist/main/internal/helper.d.ts +177 -0
  72. package/dist/main/internal/helper.js +608 -0
  73. package/dist/main/internal/join-host-port.d.ts +11 -0
  74. package/dist/main/internal/join-host-port.js +29 -0
  75. package/dist/main/internal/post-policy.d.ts +17 -0
  76. package/dist/main/internal/post-policy.js +107 -0
  77. package/dist/main/internal/request.d.ts +11 -0
  78. package/dist/main/internal/request.js +83 -0
  79. package/dist/main/internal/response.d.ts +8 -0
  80. package/dist/main/internal/response.js +24 -0
  81. package/dist/main/internal/s3-endpoints.d.ts +38 -0
  82. package/dist/main/internal/s3-endpoints.js +73 -0
  83. package/dist/main/internal/type.d.ts +482 -0
  84. package/dist/main/internal/type.js +42 -0
  85. package/dist/main/internal/xml-parser.d.ts +93 -0
  86. package/dist/main/internal/xml-parser.js +849 -0
  87. package/dist/main/notification.d.ts +58 -0
  88. package/dist/main/notification.js +230 -0
  89. package/dist/main/s3.d.ts +40 -0
  90. package/dist/main/s3.js +117 -0
  91. package/dist/main/signing.d.ts +5 -0
  92. package/dist/main/signing.js +269 -0
  93. package/package.json +146 -39
  94. package/src/AssumeRoleProvider.ts +262 -0
  95. package/src/CredentialProvider.ts +54 -0
  96. package/src/Credentials.ts +44 -0
  97. package/src/IamAwsProvider.ts +234 -0
  98. package/src/errors.ts +120 -0
  99. package/src/helpers.ts +354 -0
  100. package/src/internal/async.ts +14 -0
  101. package/src/internal/callbackify.ts +19 -0
  102. package/src/internal/client.ts +3412 -0
  103. package/src/internal/copy-conditions.ts +30 -0
  104. package/src/internal/extensions.ts +140 -0
  105. package/src/internal/helper.ts +606 -0
  106. package/src/internal/join-host-port.ts +23 -0
  107. package/src/internal/post-policy.ts +99 -0
  108. package/src/internal/request.ts +102 -0
  109. package/src/internal/response.ts +26 -0
  110. package/src/internal/s3-endpoints.ts +70 -0
  111. package/src/internal/type.ts +577 -0
  112. package/src/internal/xml-parser.ts +871 -0
  113. package/src/notification.ts +254 -0
  114. package/src/s3.ts +155 -0
  115. package/src/signing.ts +325 -0
  116. package/lib/index.js +0 -450
  117. package/lib/index.js.map +0 -7
  118. package/lib/perfTest.js +0 -91
  119. package/lib/perfTest.js.map +0 -7
@@ -0,0 +1,819 @@
1
+ import crc32 from 'buffer-crc32';
2
+ import { XMLParser } from 'fast-xml-parser';
3
+ import * as errors from "../errors.mjs";
4
+ import { SelectResults } from "../helpers.mjs";
5
+ import { isObject, parseXml, readableStream, sanitizeETag, sanitizeObjectKey, sanitizeSize, toArray } from "./helper.mjs";
6
+ import { readAsString } from "./response.mjs";
7
+ import { RETENTION_VALIDITY_UNITS } from "./type.mjs";
8
+
9
+ // parse XML response for bucket region
10
+ export function parseBucketRegion(xml) {
11
+ // return region information
12
+ return parseXml(xml).LocationConstraint;
13
+ }
14
+ const fxp = new XMLParser();
15
+ const fxpWithoutNumParser = new XMLParser({
16
+ // @ts-ignore
17
+ numberParseOptions: {
18
+ skipLike: /./
19
+ }
20
+ });
21
+
22
+ // Parse XML and return information as Javascript types
23
+ // parse error XML response
24
+ export function parseError(xml, headerInfo) {
25
+ let xmlErr = {};
26
+ const xmlObj = fxp.parse(xml);
27
+ if (xmlObj.Error) {
28
+ xmlErr = xmlObj.Error;
29
+ }
30
+ const e = new errors.S3Error();
31
+ Object.entries(xmlErr).forEach(([key, value]) => {
32
+ e[key.toLowerCase()] = value;
33
+ });
34
+ Object.entries(headerInfo).forEach(([key, value]) => {
35
+ e[key] = value;
36
+ });
37
+ return e;
38
+ }
39
+
40
+ // Generates an Error object depending on http statusCode and XML body
41
+ export async function parseResponseError(response) {
42
+ const statusCode = response.statusCode;
43
+ let code = '',
44
+ message = '';
45
+ if (statusCode === 301) {
46
+ code = 'MovedPermanently';
47
+ message = 'Moved Permanently';
48
+ } else if (statusCode === 307) {
49
+ code = 'TemporaryRedirect';
50
+ message = 'Are you using the correct endpoint URL?';
51
+ } else if (statusCode === 403) {
52
+ code = 'AccessDenied';
53
+ message = 'Valid and authorized credentials required';
54
+ } else if (statusCode === 404) {
55
+ code = 'NotFound';
56
+ message = 'Not Found';
57
+ } else if (statusCode === 405) {
58
+ code = 'MethodNotAllowed';
59
+ message = 'Method Not Allowed';
60
+ } else if (statusCode === 501) {
61
+ code = 'MethodNotAllowed';
62
+ message = 'Method Not Allowed';
63
+ } else if (statusCode === 503) {
64
+ code = 'SlowDown';
65
+ message = 'Please reduce your request rate.';
66
+ } else {
67
+ // Server-side error headers (protocol-level, sent by S3-compatible servers)
68
+ const hErrCode = response.headers['x-s3-error-code'] ?? response.headers['x-minio-error-code'];
69
+ const hErrDesc = response.headers['x-s3-error-desc'] ?? response.headers['x-minio-error-desc'];
70
+ if (hErrCode && hErrDesc) {
71
+ code = hErrCode;
72
+ message = hErrDesc;
73
+ }
74
+ }
75
+ const headerInfo = {};
76
+ // A value created by S3 compatible server that uniquely identifies the request.
77
+ headerInfo.amzRequestid = response.headers['x-amz-request-id'];
78
+ // A special token that helps troubleshoot API replies and issues.
79
+ headerInfo.amzId2 = response.headers['x-amz-id-2'];
80
+
81
+ // Region where the bucket is located. This header is returned only
82
+ // in HEAD bucket and ListObjects response.
83
+ headerInfo.amzBucketRegion = response.headers['x-amz-bucket-region'];
84
+ const xmlString = await readAsString(response);
85
+ if (xmlString) {
86
+ throw parseError(xmlString, headerInfo);
87
+ }
88
+
89
+ // Message should be instantiated for each S3Errors.
90
+ const e = new errors.S3Error(message, {
91
+ cause: headerInfo
92
+ });
93
+ // S3 Error code.
94
+ e.code = code;
95
+ Object.entries(headerInfo).forEach(([key, value]) => {
96
+ // @ts-expect-error force set error properties
97
+ e[key] = value;
98
+ });
99
+ throw e;
100
+ }
101
+
102
+ /**
103
+ * parse XML response for list objects v2 with metadata in a bucket
104
+ */
105
+ export function parseListObjectsV2WithMetadata(xml) {
106
+ const result = {
107
+ objects: [],
108
+ isTruncated: false,
109
+ nextContinuationToken: ''
110
+ };
111
+ let xmlobj = parseXml(xml);
112
+ if (!xmlobj.ListBucketResult) {
113
+ throw new errors.InvalidXMLError('Missing tag: "ListBucketResult"');
114
+ }
115
+ xmlobj = xmlobj.ListBucketResult;
116
+ if (xmlobj.IsTruncated) {
117
+ result.isTruncated = xmlobj.IsTruncated;
118
+ }
119
+ if (xmlobj.NextContinuationToken) {
120
+ result.nextContinuationToken = xmlobj.NextContinuationToken;
121
+ }
122
+ if (xmlobj.Contents) {
123
+ toArray(xmlobj.Contents).forEach(content => {
124
+ const name = sanitizeObjectKey(content.Key);
125
+ const lastModified = new Date(content.LastModified);
126
+ const etag = sanitizeETag(content.ETag);
127
+ const size = content.Size;
128
+ let tags = {};
129
+ if (content.UserTags != null) {
130
+ toArray(content.UserTags.split('&')).forEach(tag => {
131
+ const [key, value] = tag.split('=');
132
+ tags[key] = value;
133
+ });
134
+ } else {
135
+ tags = {};
136
+ }
137
+ let metadata;
138
+ if (content.UserMetadata != null) {
139
+ metadata = toArray(content.UserMetadata)[0];
140
+ } else {
141
+ metadata = null;
142
+ }
143
+ result.objects.push({
144
+ name,
145
+ lastModified,
146
+ etag,
147
+ size,
148
+ metadata,
149
+ tags
150
+ });
151
+ });
152
+ }
153
+ if (xmlobj.CommonPrefixes) {
154
+ toArray(xmlobj.CommonPrefixes).forEach(commonPrefix => {
155
+ result.objects.push({
156
+ prefix: sanitizeObjectKey(toArray(commonPrefix.Prefix)[0]),
157
+ size: 0
158
+ });
159
+ });
160
+ }
161
+ return result;
162
+ }
163
+ export function parseListObjectsV2(xml) {
164
+ const result = {
165
+ objects: [],
166
+ isTruncated: false,
167
+ nextContinuationToken: ''
168
+ };
169
+ let xmlobj = parseXml(xml);
170
+ if (!xmlobj.ListBucketResult) {
171
+ throw new errors.InvalidXMLError('Missing tag: "ListBucketResult"');
172
+ }
173
+ xmlobj = xmlobj.ListBucketResult;
174
+ if (xmlobj.IsTruncated) {
175
+ result.isTruncated = xmlobj.IsTruncated;
176
+ }
177
+ if (xmlobj.NextContinuationToken) {
178
+ result.nextContinuationToken = xmlobj.NextContinuationToken;
179
+ }
180
+ if (xmlobj.Contents) {
181
+ toArray(xmlobj.Contents).forEach(content => {
182
+ const name = sanitizeObjectKey(toArray(content.Key)[0]);
183
+ const lastModified = new Date(content.LastModified);
184
+ const etag = sanitizeETag(content.ETag);
185
+ const size = content.Size;
186
+ result.objects.push({
187
+ name,
188
+ lastModified,
189
+ etag,
190
+ size
191
+ });
192
+ });
193
+ }
194
+ if (xmlobj.CommonPrefixes) {
195
+ toArray(xmlobj.CommonPrefixes).forEach(commonPrefix => {
196
+ result.objects.push({
197
+ prefix: sanitizeObjectKey(toArray(commonPrefix.Prefix)[0]),
198
+ size: 0
199
+ });
200
+ });
201
+ }
202
+ return result;
203
+ }
204
+ export function parseBucketNotification(xml) {
205
+ const result = {
206
+ TopicConfiguration: [],
207
+ QueueConfiguration: [],
208
+ CloudFunctionConfiguration: []
209
+ };
210
+ const genEvents = events => {
211
+ if (!events) {
212
+ return [];
213
+ }
214
+ return toArray(events);
215
+ };
216
+ const genFilterRules = filters => {
217
+ var _filterArr$;
218
+ const rules = [];
219
+ if (!filters) {
220
+ return rules;
221
+ }
222
+ const filterArr = toArray(filters);
223
+ if ((_filterArr$ = filterArr[0]) !== null && _filterArr$ !== void 0 && _filterArr$.S3Key) {
224
+ var _s3KeyArr$;
225
+ const s3KeyArr = toArray(filterArr[0].S3Key);
226
+ if ((_s3KeyArr$ = s3KeyArr[0]) !== null && _s3KeyArr$ !== void 0 && _s3KeyArr$.FilterRule) {
227
+ toArray(s3KeyArr[0].FilterRule).forEach(rule => {
228
+ const r = rule;
229
+ const Name = toArray(r.Name)[0];
230
+ const Value = toArray(r.Value)[0];
231
+ rules.push({
232
+ Name,
233
+ Value
234
+ });
235
+ });
236
+ }
237
+ }
238
+ return rules;
239
+ };
240
+ let xmlobj = parseXml(xml);
241
+ xmlobj = xmlobj.NotificationConfiguration;
242
+ if (xmlobj.TopicConfiguration) {
243
+ toArray(xmlobj.TopicConfiguration).forEach(config => {
244
+ const Id = toArray(config.Id)[0];
245
+ const Topic = toArray(config.Topic)[0];
246
+ const Event = genEvents(config.Event);
247
+ const Filter = genFilterRules(config.Filter);
248
+ result.TopicConfiguration.push({
249
+ Id,
250
+ Topic,
251
+ Event,
252
+ Filter
253
+ });
254
+ });
255
+ }
256
+ if (xmlobj.QueueConfiguration) {
257
+ toArray(xmlobj.QueueConfiguration).forEach(config => {
258
+ const Id = toArray(config.Id)[0];
259
+ const Queue = toArray(config.Queue)[0];
260
+ const Event = genEvents(config.Event);
261
+ const Filter = genFilterRules(config.Filter);
262
+ result.QueueConfiguration.push({
263
+ Id,
264
+ Queue,
265
+ Event,
266
+ Filter
267
+ });
268
+ });
269
+ }
270
+ if (xmlobj.CloudFunctionConfiguration) {
271
+ toArray(xmlobj.CloudFunctionConfiguration).forEach(config => {
272
+ const Id = toArray(config.Id)[0];
273
+ const CloudFunction = toArray(config.CloudFunction)[0];
274
+ const Event = genEvents(config.Event);
275
+ const Filter = genFilterRules(config.Filter);
276
+ result.CloudFunctionConfiguration.push({
277
+ Id,
278
+ CloudFunction,
279
+ Event,
280
+ Filter
281
+ });
282
+ });
283
+ }
284
+ return result;
285
+ }
286
+ // parse XML response for list parts of an in progress multipart upload
287
+ export function parseListParts(xml) {
288
+ let xmlobj = parseXml(xml);
289
+ const result = {
290
+ isTruncated: false,
291
+ parts: [],
292
+ marker: 0
293
+ };
294
+ if (!xmlobj.ListPartsResult) {
295
+ throw new errors.InvalidXMLError('Missing tag: "ListPartsResult"');
296
+ }
297
+ xmlobj = xmlobj.ListPartsResult;
298
+ if (xmlobj.IsTruncated) {
299
+ result.isTruncated = xmlobj.IsTruncated;
300
+ }
301
+ if (xmlobj.NextPartNumberMarker) {
302
+ result.marker = toArray(xmlobj.NextPartNumberMarker)[0] || '';
303
+ }
304
+ if (xmlobj.Part) {
305
+ toArray(xmlobj.Part).forEach(p => {
306
+ const part = parseInt(toArray(p.PartNumber)[0], 10);
307
+ const lastModified = new Date(p.LastModified);
308
+ const etag = p.ETag.replace(/^"/g, '').replace(/"$/g, '').replace(/^"/g, '').replace(/"$/g, '').replace(/^"/g, '').replace(/"$/g, '');
309
+ result.parts.push({
310
+ part,
311
+ lastModified,
312
+ etag,
313
+ size: parseInt(p.Size, 10)
314
+ });
315
+ });
316
+ }
317
+ return result;
318
+ }
319
+ export function parseListBucket(xml) {
320
+ let result = [];
321
+ const listBucketResultParser = new XMLParser({
322
+ parseTagValue: true,
323
+ // Enable parsing of values
324
+ numberParseOptions: {
325
+ leadingZeros: false,
326
+ // Disable number parsing for values with leading zeros
327
+ hex: false,
328
+ // Disable hex number parsing - Invalid bucket name
329
+ skipLike: /^[0-9]+$/ // Skip number parsing if the value consists entirely of digits
330
+ },
331
+
332
+ tagValueProcessor: (tagName, tagValue = '') => {
333
+ // Ensure that the Name tag is always treated as a string
334
+ if (tagName === 'Name') {
335
+ return tagValue.toString();
336
+ }
337
+ return tagValue;
338
+ },
339
+ ignoreAttributes: false // Ensure that all attributes are parsed
340
+ });
341
+
342
+ const parsedXmlRes = listBucketResultParser.parse(xml);
343
+ if (!parsedXmlRes.ListAllMyBucketsResult) {
344
+ throw new errors.InvalidXMLError('Missing tag: "ListAllMyBucketsResult"');
345
+ }
346
+ const {
347
+ ListAllMyBucketsResult: {
348
+ Buckets = {}
349
+ } = {}
350
+ } = parsedXmlRes;
351
+ if (Buckets.Bucket) {
352
+ result = toArray(Buckets.Bucket).map((bucket = {}) => {
353
+ const {
354
+ Name: bucketName,
355
+ CreationDate
356
+ } = bucket;
357
+ const creationDate = new Date(CreationDate);
358
+ return {
359
+ name: bucketName,
360
+ creationDate
361
+ };
362
+ });
363
+ }
364
+ return result;
365
+ }
366
+ export function parseInitiateMultipart(xml) {
367
+ let xmlobj = parseXml(xml);
368
+ if (!xmlobj.InitiateMultipartUploadResult) {
369
+ throw new errors.InvalidXMLError('Missing tag: "InitiateMultipartUploadResult"');
370
+ }
371
+ xmlobj = xmlobj.InitiateMultipartUploadResult;
372
+ if (xmlobj.UploadId) {
373
+ return xmlobj.UploadId;
374
+ }
375
+ throw new errors.InvalidXMLError('Missing tag: "UploadId"');
376
+ }
377
+ export function parseReplicationConfig(xml) {
378
+ const xmlObj = parseXml(xml);
379
+ const {
380
+ Role,
381
+ Rule
382
+ } = xmlObj.ReplicationConfiguration;
383
+ return {
384
+ ReplicationConfiguration: {
385
+ role: Role,
386
+ rules: toArray(Rule)
387
+ }
388
+ };
389
+ }
390
+ export function parseObjectLegalHoldConfig(xml) {
391
+ const xmlObj = parseXml(xml);
392
+ return xmlObj.LegalHold;
393
+ }
394
+ export function parseTagging(xml) {
395
+ const xmlObj = parseXml(xml);
396
+ let result = [];
397
+ if (xmlObj.Tagging && xmlObj.Tagging.TagSet && xmlObj.Tagging.TagSet.Tag) {
398
+ const tagResult = xmlObj.Tagging.TagSet.Tag;
399
+ // if it is a single tag convert into an array so that the return value is always an array.
400
+ if (Array.isArray(tagResult)) {
401
+ result = [...tagResult];
402
+ } else {
403
+ result.push(tagResult);
404
+ }
405
+ }
406
+ return result;
407
+ }
408
+
409
+ // parse XML response when a multipart upload is completed
410
+ export function parseCompleteMultipart(xml) {
411
+ const xmlobj = parseXml(xml).CompleteMultipartUploadResult;
412
+ if (xmlobj.Location) {
413
+ const location = toArray(xmlobj.Location)[0];
414
+ const bucket = toArray(xmlobj.Bucket)[0];
415
+ const key = xmlobj.Key;
416
+ const etag = xmlobj.ETag.replace(/^"/g, '').replace(/"$/g, '').replace(/^"/g, '').replace(/"$/g, '').replace(/^"/g, '').replace(/"$/g, '');
417
+ return {
418
+ location,
419
+ bucket,
420
+ key,
421
+ etag
422
+ };
423
+ }
424
+ // Complete Multipart can return XML Error after a 200 OK response
425
+ if (xmlobj.Code && xmlobj.Message) {
426
+ const errCode = toArray(xmlobj.Code)[0];
427
+ const errMessage = toArray(xmlobj.Message)[0];
428
+ return {
429
+ errCode,
430
+ errMessage
431
+ };
432
+ }
433
+ }
434
+ // parse XML response for listing in-progress multipart uploads
435
+ export function parseListMultipart(xml) {
436
+ const result = {
437
+ prefixes: [],
438
+ uploads: [],
439
+ isTruncated: false,
440
+ nextKeyMarker: '',
441
+ nextUploadIdMarker: ''
442
+ };
443
+ let xmlobj = parseXml(xml);
444
+ if (!xmlobj.ListMultipartUploadsResult) {
445
+ throw new errors.InvalidXMLError('Missing tag: "ListMultipartUploadsResult"');
446
+ }
447
+ xmlobj = xmlobj.ListMultipartUploadsResult;
448
+ if (xmlobj.IsTruncated) {
449
+ result.isTruncated = xmlobj.IsTruncated;
450
+ }
451
+ if (xmlobj.NextKeyMarker) {
452
+ result.nextKeyMarker = xmlobj.NextKeyMarker;
453
+ }
454
+ if (xmlobj.NextUploadIdMarker) {
455
+ result.nextUploadIdMarker = xmlobj.nextUploadIdMarker || '';
456
+ }
457
+ if (xmlobj.CommonPrefixes) {
458
+ toArray(xmlobj.CommonPrefixes).forEach(prefix => {
459
+ // @ts-expect-error index check
460
+ result.prefixes.push({
461
+ prefix: sanitizeObjectKey(toArray(prefix.Prefix)[0])
462
+ });
463
+ });
464
+ }
465
+ if (xmlobj.Upload) {
466
+ toArray(xmlobj.Upload).forEach(upload => {
467
+ const uploadItem = {
468
+ key: upload.Key,
469
+ uploadId: upload.UploadId,
470
+ storageClass: upload.StorageClass,
471
+ initiated: new Date(upload.Initiated)
472
+ };
473
+ if (upload.Initiator) {
474
+ uploadItem.initiator = {
475
+ id: upload.Initiator.ID,
476
+ displayName: upload.Initiator.DisplayName
477
+ };
478
+ }
479
+ if (upload.Owner) {
480
+ uploadItem.owner = {
481
+ id: upload.Owner.ID,
482
+ displayName: upload.Owner.DisplayName
483
+ };
484
+ }
485
+ result.uploads.push(uploadItem);
486
+ });
487
+ }
488
+ return result;
489
+ }
490
+ export function parseObjectLockConfig(xml) {
491
+ const xmlObj = parseXml(xml);
492
+ let lockConfigResult = {};
493
+ if (xmlObj.ObjectLockConfiguration) {
494
+ lockConfigResult = {
495
+ objectLockEnabled: xmlObj.ObjectLockConfiguration.ObjectLockEnabled
496
+ };
497
+ let retentionResp;
498
+ if (xmlObj.ObjectLockConfiguration && xmlObj.ObjectLockConfiguration.Rule && xmlObj.ObjectLockConfiguration.Rule.DefaultRetention) {
499
+ retentionResp = xmlObj.ObjectLockConfiguration.Rule.DefaultRetention || {};
500
+ lockConfigResult.mode = retentionResp.Mode;
501
+ }
502
+ if (retentionResp) {
503
+ const isUnitYears = retentionResp.Years;
504
+ if (isUnitYears) {
505
+ lockConfigResult.validity = isUnitYears;
506
+ lockConfigResult.unit = RETENTION_VALIDITY_UNITS.YEARS;
507
+ } else {
508
+ lockConfigResult.validity = retentionResp.Days;
509
+ lockConfigResult.unit = RETENTION_VALIDITY_UNITS.DAYS;
510
+ }
511
+ }
512
+ }
513
+ return lockConfigResult;
514
+ }
515
+ export function parseBucketVersioningConfig(xml) {
516
+ const xmlObj = parseXml(xml);
517
+ return xmlObj.VersioningConfiguration;
518
+ }
519
+
520
+ // Used only in selectObjectContent API.
521
+ // extractHeaderType extracts the first half of the header message, the header type.
522
+ function extractHeaderType(stream) {
523
+ const headerNameLen = Buffer.from(stream.read(1)).readUInt8();
524
+ const headerNameWithSeparator = Buffer.from(stream.read(headerNameLen)).toString();
525
+ const splitBySeparator = (headerNameWithSeparator || '').split(':');
526
+ return splitBySeparator.length >= 1 ? splitBySeparator[1] : '';
527
+ }
528
+ function extractHeaderValue(stream) {
529
+ const bodyLen = Buffer.from(stream.read(2)).readUInt16BE();
530
+ return Buffer.from(stream.read(bodyLen)).toString();
531
+ }
532
+ export function parseSelectObjectContentResponse(res) {
533
+ const selectResults = new SelectResults({}); // will be returned
534
+
535
+ const responseStream = readableStream(res); // convert byte array to a readable responseStream
536
+ // @ts-ignore
537
+ while (responseStream._readableState.length) {
538
+ // Top level responseStream read tracker.
539
+ let msgCrcAccumulator; // accumulate from start of the message till the message crc start.
540
+
541
+ const totalByteLengthBuffer = Buffer.from(responseStream.read(4));
542
+ msgCrcAccumulator = crc32(totalByteLengthBuffer);
543
+ const headerBytesBuffer = Buffer.from(responseStream.read(4));
544
+ msgCrcAccumulator = crc32(headerBytesBuffer, msgCrcAccumulator);
545
+ const calculatedPreludeCrc = msgCrcAccumulator.readInt32BE(); // use it to check if any CRC mismatch in header itself.
546
+
547
+ const preludeCrcBuffer = Buffer.from(responseStream.read(4)); // read 4 bytes i.e 4+4 =8 + 4 = 12 ( prelude + prelude crc)
548
+ msgCrcAccumulator = crc32(preludeCrcBuffer, msgCrcAccumulator);
549
+ const totalMsgLength = totalByteLengthBuffer.readInt32BE();
550
+ const headerLength = headerBytesBuffer.readInt32BE();
551
+ const preludeCrcByteValue = preludeCrcBuffer.readInt32BE();
552
+ if (preludeCrcByteValue !== calculatedPreludeCrc) {
553
+ // Handle Header CRC mismatch Error
554
+ throw new Error(`Header Checksum Mismatch, Prelude CRC of ${preludeCrcByteValue} does not equal expected CRC of ${calculatedPreludeCrc}`);
555
+ }
556
+ const headers = {};
557
+ if (headerLength > 0) {
558
+ const headerBytes = Buffer.from(responseStream.read(headerLength));
559
+ msgCrcAccumulator = crc32(headerBytes, msgCrcAccumulator);
560
+ const headerReaderStream = readableStream(headerBytes);
561
+ // @ts-ignore
562
+ while (headerReaderStream._readableState.length) {
563
+ const headerTypeName = extractHeaderType(headerReaderStream);
564
+ headerReaderStream.read(1); // just read and ignore it.
565
+ if (headerTypeName) {
566
+ headers[headerTypeName] = extractHeaderValue(headerReaderStream);
567
+ }
568
+ }
569
+ }
570
+ let payloadStream;
571
+ const payLoadLength = totalMsgLength - headerLength - 16;
572
+ if (payLoadLength > 0) {
573
+ const payLoadBuffer = Buffer.from(responseStream.read(payLoadLength));
574
+ msgCrcAccumulator = crc32(payLoadBuffer, msgCrcAccumulator);
575
+ // read the checksum early and detect any mismatch so we can avoid unnecessary further processing.
576
+ const messageCrcByteValue = Buffer.from(responseStream.read(4)).readInt32BE();
577
+ const calculatedCrc = msgCrcAccumulator.readInt32BE();
578
+ // Handle message CRC Error
579
+ if (messageCrcByteValue !== calculatedCrc) {
580
+ throw new Error(`Message Checksum Mismatch, Message CRC of ${messageCrcByteValue} does not equal expected CRC of ${calculatedCrc}`);
581
+ }
582
+ payloadStream = readableStream(payLoadBuffer);
583
+ }
584
+ const messageType = headers['message-type'];
585
+ switch (messageType) {
586
+ case 'error':
587
+ {
588
+ const errorMessage = headers['error-code'] + ':"' + headers['error-message'] + '"';
589
+ throw new Error(errorMessage);
590
+ }
591
+ case 'event':
592
+ {
593
+ const contentType = headers['content-type'];
594
+ const eventType = headers['event-type'];
595
+ switch (eventType) {
596
+ case 'End':
597
+ {
598
+ selectResults.setResponse(res);
599
+ return selectResults;
600
+ }
601
+ case 'Records':
602
+ {
603
+ var _payloadStream;
604
+ const readData = (_payloadStream = payloadStream) === null || _payloadStream === void 0 ? void 0 : _payloadStream.read(payLoadLength);
605
+ selectResults.setRecords(readData);
606
+ break;
607
+ }
608
+ case 'Progress':
609
+ {
610
+ switch (contentType) {
611
+ case 'text/xml':
612
+ {
613
+ var _payloadStream2;
614
+ const progressData = (_payloadStream2 = payloadStream) === null || _payloadStream2 === void 0 ? void 0 : _payloadStream2.read(payLoadLength);
615
+ selectResults.setProgress(progressData.toString());
616
+ break;
617
+ }
618
+ default:
619
+ {
620
+ const errorMessage = `Unexpected content-type ${contentType} sent for event-type Progress`;
621
+ throw new Error(errorMessage);
622
+ }
623
+ }
624
+ }
625
+ break;
626
+ case 'Stats':
627
+ {
628
+ switch (contentType) {
629
+ case 'text/xml':
630
+ {
631
+ var _payloadStream3;
632
+ const statsData = (_payloadStream3 = payloadStream) === null || _payloadStream3 === void 0 ? void 0 : _payloadStream3.read(payLoadLength);
633
+ selectResults.setStats(statsData.toString());
634
+ break;
635
+ }
636
+ default:
637
+ {
638
+ const errorMessage = `Unexpected content-type ${contentType} sent for event-type Stats`;
639
+ throw new Error(errorMessage);
640
+ }
641
+ }
642
+ }
643
+ break;
644
+ default:
645
+ {
646
+ // Continuation message: Not sure if it is supported. did not find a reference or any message in response.
647
+ // It does not have a payload.
648
+ const warningMessage = `Un implemented event detected ${messageType}.`;
649
+ // eslint-disable-next-line no-console
650
+ console.warn(warningMessage);
651
+ }
652
+ }
653
+ }
654
+ }
655
+ }
656
+ }
657
+ export function parseLifecycleConfig(xml) {
658
+ const xmlObj = parseXml(xml);
659
+ return xmlObj.LifecycleConfiguration;
660
+ }
661
+ export function parseBucketEncryptionConfig(xml) {
662
+ return parseXml(xml);
663
+ }
664
+ export function parseObjectRetentionConfig(xml) {
665
+ const xmlObj = parseXml(xml);
666
+ const retentionConfig = xmlObj.Retention;
667
+ return {
668
+ mode: retentionConfig.Mode,
669
+ retainUntilDate: retentionConfig.RetainUntilDate
670
+ };
671
+ }
672
+ export function removeObjectsParser(xml) {
673
+ const xmlObj = parseXml(xml);
674
+ if (xmlObj.DeleteResult && xmlObj.DeleteResult.Error) {
675
+ // return errors as array always. as the response is object in case of single object passed in removeObjects
676
+ return toArray(xmlObj.DeleteResult.Error);
677
+ }
678
+ return [];
679
+ }
680
+
681
+ // parse XML response for copy object
682
+ export function parseCopyObject(xml) {
683
+ const result = {
684
+ etag: '',
685
+ lastModified: ''
686
+ };
687
+ let xmlobj = parseXml(xml);
688
+ if (!xmlobj.CopyObjectResult) {
689
+ throw new errors.InvalidXMLError('Missing tag: "CopyObjectResult"');
690
+ }
691
+ xmlobj = xmlobj.CopyObjectResult;
692
+ if (xmlobj.ETag) {
693
+ result.etag = xmlobj.ETag.replace(/^"/g, '').replace(/"$/g, '').replace(/^"/g, '').replace(/"$/g, '').replace(/^"/g, '').replace(/"$/g, '');
694
+ }
695
+ if (xmlobj.LastModified) {
696
+ result.lastModified = new Date(xmlobj.LastModified);
697
+ }
698
+ return result;
699
+ }
700
+ const formatObjInfo = (content, opts = {}) => {
701
+ const {
702
+ Key,
703
+ LastModified,
704
+ ETag,
705
+ Size,
706
+ VersionId,
707
+ IsLatest
708
+ } = content;
709
+ if (!isObject(opts)) {
710
+ opts = {};
711
+ }
712
+ const name = sanitizeObjectKey(toArray(Key)[0] || '');
713
+ const lastModified = LastModified ? new Date(toArray(LastModified)[0] || '') : undefined;
714
+ const etag = sanitizeETag(toArray(ETag)[0] || '');
715
+ const size = sanitizeSize(Size || '');
716
+ return {
717
+ name,
718
+ lastModified,
719
+ etag,
720
+ size,
721
+ versionId: VersionId,
722
+ isLatest: IsLatest,
723
+ isDeleteMarker: opts.IsDeleteMarker ? opts.IsDeleteMarker : false
724
+ };
725
+ };
726
+
727
+ // parse XML response for list objects in a bucket
728
+ export function parseListObjects(xml) {
729
+ const result = {
730
+ objects: [],
731
+ isTruncated: false,
732
+ nextMarker: undefined,
733
+ versionIdMarker: undefined,
734
+ keyMarker: undefined
735
+ };
736
+ let isTruncated = false;
737
+ let nextMarker;
738
+ const xmlobj = fxpWithoutNumParser.parse(xml);
739
+ const parseCommonPrefixesEntity = commonPrefixEntry => {
740
+ if (commonPrefixEntry) {
741
+ toArray(commonPrefixEntry).forEach(commonPrefix => {
742
+ result.objects.push({
743
+ prefix: sanitizeObjectKey(toArray(commonPrefix.Prefix)[0] || ''),
744
+ size: 0
745
+ });
746
+ });
747
+ }
748
+ };
749
+ const listBucketResult = xmlobj.ListBucketResult;
750
+ const listVersionsResult = xmlobj.ListVersionsResult;
751
+ if (listBucketResult) {
752
+ if (listBucketResult.IsTruncated) {
753
+ isTruncated = listBucketResult.IsTruncated;
754
+ }
755
+ if (listBucketResult.Contents) {
756
+ toArray(listBucketResult.Contents).forEach(content => {
757
+ const name = sanitizeObjectKey(toArray(content.Key)[0] || '');
758
+ const lastModified = new Date(toArray(content.LastModified)[0] || '');
759
+ const etag = sanitizeETag(toArray(content.ETag)[0] || '');
760
+ const size = sanitizeSize(content.Size || '');
761
+ result.objects.push({
762
+ name,
763
+ lastModified,
764
+ etag,
765
+ size
766
+ });
767
+ });
768
+ }
769
+ if (listBucketResult.Marker) {
770
+ nextMarker = listBucketResult.Marker;
771
+ }
772
+ if (listBucketResult.NextMarker) {
773
+ nextMarker = listBucketResult.NextMarker;
774
+ } else if (isTruncated && result.objects.length > 0) {
775
+ var _result$objects;
776
+ nextMarker = (_result$objects = result.objects[result.objects.length - 1]) === null || _result$objects === void 0 ? void 0 : _result$objects.name;
777
+ }
778
+ if (listBucketResult.CommonPrefixes) {
779
+ parseCommonPrefixesEntity(listBucketResult.CommonPrefixes);
780
+ }
781
+ }
782
+ if (listVersionsResult) {
783
+ if (listVersionsResult.IsTruncated) {
784
+ isTruncated = listVersionsResult.IsTruncated;
785
+ }
786
+ if (listVersionsResult.Version) {
787
+ toArray(listVersionsResult.Version).forEach(content => {
788
+ result.objects.push(formatObjInfo(content));
789
+ });
790
+ }
791
+ if (listVersionsResult.DeleteMarker) {
792
+ toArray(listVersionsResult.DeleteMarker).forEach(content => {
793
+ result.objects.push(formatObjInfo(content, {
794
+ IsDeleteMarker: true
795
+ }));
796
+ });
797
+ }
798
+ if (listVersionsResult.NextKeyMarker) {
799
+ result.keyMarker = listVersionsResult.NextKeyMarker;
800
+ }
801
+ if (listVersionsResult.NextVersionIdMarker) {
802
+ result.versionIdMarker = listVersionsResult.NextVersionIdMarker;
803
+ }
804
+ if (listVersionsResult.CommonPrefixes) {
805
+ parseCommonPrefixesEntity(listVersionsResult.CommonPrefixes);
806
+ }
807
+ }
808
+ result.isTruncated = isTruncated;
809
+ if (isTruncated) {
810
+ result.nextMarker = nextMarker;
811
+ }
812
+ return result;
813
+ }
814
+ export function uploadPartParser(xml) {
815
+ const xmlObj = parseXml(xml);
816
+ const respEl = xmlObj.CopyPartResult;
817
+ return respEl;
818
+ }
819
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjcmMzMiIsIlhNTFBhcnNlciIsImVycm9ycyIsIlNlbGVjdFJlc3VsdHMiLCJpc09iamVjdCIsInBhcnNlWG1sIiwicmVhZGFibGVTdHJlYW0iLCJzYW5pdGl6ZUVUYWciLCJzYW5pdGl6ZU9iamVjdEtleSIsInNhbml0aXplU2l6ZSIsInRvQXJyYXkiLCJyZWFkQXNTdHJpbmciLCJSRVRFTlRJT05fVkFMSURJVFlfVU5JVFMiLCJwYXJzZUJ1Y2tldFJlZ2lvbiIsInhtbCIsIkxvY2F0aW9uQ29uc3RyYWludCIsImZ4cCIsImZ4cFdpdGhvdXROdW1QYXJzZXIiLCJudW1iZXJQYXJzZU9wdGlvbnMiLCJza2lwTGlrZSIsInBhcnNlRXJyb3IiLCJoZWFkZXJJbmZvIiwieG1sRXJyIiwieG1sT2JqIiwicGFyc2UiLCJFcnJvciIsImUiLCJTM0Vycm9yIiwiT2JqZWN0IiwiZW50cmllcyIsImZvckVhY2giLCJrZXkiLCJ2YWx1ZSIsInRvTG93ZXJDYXNlIiwicGFyc2VSZXNwb25zZUVycm9yIiwicmVzcG9uc2UiLCJzdGF0dXNDb2RlIiwiY29kZSIsIm1lc3NhZ2UiLCJoRXJyQ29kZSIsImhlYWRlcnMiLCJoRXJyRGVzYyIsImFtelJlcXVlc3RpZCIsImFteklkMiIsImFtekJ1Y2tldFJlZ2lvbiIsInhtbFN0cmluZyIsImNhdXNlIiwicGFyc2VMaXN0T2JqZWN0c1YyV2l0aE1ldGFkYXRhIiwicmVzdWx0Iiwib2JqZWN0cyIsImlzVHJ1bmNhdGVkIiwibmV4dENvbnRpbnVhdGlvblRva2VuIiwieG1sb2JqIiwiTGlzdEJ1Y2tldFJlc3VsdCIsIkludmFsaWRYTUxFcnJvciIsIklzVHJ1bmNhdGVkIiwiTmV4dENvbnRpbnVhdGlvblRva2VuIiwiQ29udGVudHMiLCJjb250ZW50IiwibmFtZSIsIktleSIsImxhc3RNb2RpZmllZCIsIkRhdGUiLCJMYXN0TW9kaWZpZWQiLCJldGFnIiwiRVRhZyIsInNpemUiLCJTaXplIiwidGFncyIsIlVzZXJUYWdzIiwic3BsaXQiLCJ0YWciLCJtZXRhZGF0YSIsIlVzZXJNZXRhZGF0YSIsInB1c2giLCJDb21tb25QcmVmaXhlcyIsImNvbW1vblByZWZpeCIsInByZWZpeCIsIlByZWZpeCIsInBhcnNlTGlzdE9iamVjdHNWMiIsInBhcnNlQnVja2V0Tm90aWZpY2F0aW9uIiwiVG9waWNDb25maWd1cmF0aW9uIiwiUXVldWVDb25maWd1cmF0aW9uIiwiQ2xvdWRGdW5jdGlvbkNvbmZpZ3VyYXRpb24iLCJnZW5FdmVudHMiLCJldmVudHMiLCJnZW5GaWx0ZXJSdWxlcyIsImZpbHRlcnMiLCJfZmlsdGVyQXJyJCIsInJ1bGVzIiwiZmlsdGVyQXJyIiwiUzNLZXkiLCJfczNLZXlBcnIkIiwiczNLZXlBcnIiLCJGaWx0ZXJSdWxlIiwicnVsZSIsInIiLCJOYW1lIiwiVmFsdWUiLCJOb3RpZmljYXRpb25Db25maWd1cmF0aW9uIiwiY29uZmlnIiwiSWQiLCJUb3BpYyIsIkV2ZW50IiwiRmlsdGVyIiwiUXVldWUiLCJDbG91ZEZ1bmN0aW9uIiwicGFyc2VMaXN0UGFydHMiLCJwYXJ0cyIsIm1hcmtlciIsIkxpc3RQYXJ0c1Jlc3VsdCIsIk5leHRQYXJ0TnVtYmVyTWFya2VyIiwiUGFydCIsInAiLCJwYXJ0IiwicGFyc2VJbnQiLCJQYXJ0TnVtYmVyIiwicmVwbGFjZSIsInBhcnNlTGlzdEJ1Y2tldCIsImxpc3RCdWNrZXRSZXN1bHRQYXJzZXIiLCJwYXJzZVRhZ1ZhbHVlIiwibGVhZGluZ1plcm9zIiwiaGV4IiwidGFnVmFsdWVQcm9jZXNzb3IiLCJ0YWdOYW1lIiwidGFnVmFsdWUiLCJ0b1N0cmluZyIsImlnbm9yZUF0dHJpYnV0ZXMiLCJwYXJzZWRYbWxSZXMiLCJMaXN0QWxsTXlCdWNrZXRzUmVzdWx0IiwiQnVja2V0cyIsIkJ1Y2tldCIsIm1hcCIsImJ1Y2tldCIsImJ1Y2tldE5hbWUiLCJDcmVhdGlvbkRhdGUiLCJjcmVhdGlvbkRhdGUiLCJwYXJzZUluaXRpYXRlTXVsdGlwYXJ0IiwiSW5pdGlhdGVNdWx0aXBhcnRVcGxvYWRSZXN1bHQiLCJVcGxvYWRJZCIsInBhcnNlUmVwbGljYXRpb25Db25maWciLCJSb2xlIiwiUnVsZSIsIlJlcGxpY2F0aW9uQ29uZmlndXJhdGlvbiIsInJvbGUiLCJwYXJzZU9iamVjdExlZ2FsSG9sZENvbmZpZyIsIkxlZ2FsSG9sZCIsInBhcnNlVGFnZ2luZyIsIlRhZ2dpbmciLCJUYWdTZXQiLCJUYWciLCJ0YWdSZXN1bHQiLCJBcnJheSIsImlzQXJyYXkiLCJwYXJzZUNvbXBsZXRlTXVsdGlwYXJ0IiwiQ29tcGxldGVNdWx0aXBhcnRVcGxvYWRSZXN1bHQiLCJMb2NhdGlvbiIsImxvY2F0aW9uIiwiQ29kZSIsIk1lc3NhZ2UiLCJlcnJDb2RlIiwiZXJyTWVzc2FnZSIsInBhcnNlTGlzdE11bHRpcGFydCIsInByZWZpeGVzIiwidXBsb2FkcyIsIm5leHRLZXlNYXJrZXIiLCJuZXh0VXBsb2FkSWRNYXJrZXIiLCJMaXN0TXVsdGlwYXJ0VXBsb2Fkc1Jlc3VsdCIsIk5leHRLZXlNYXJrZXIiLCJOZXh0VXBsb2FkSWRNYXJrZXIiLCJVcGxvYWQiLCJ1cGxvYWQiLCJ1cGxvYWRJdGVtIiwidXBsb2FkSWQiLCJzdG9yYWdlQ2xhc3MiLCJTdG9yYWdlQ2xhc3MiLCJpbml0aWF0ZWQiLCJJbml0aWF0ZWQiLCJJbml0aWF0b3IiLCJpbml0aWF0b3IiLCJpZCIsIklEIiwiZGlzcGxheU5hbWUiLCJEaXNwbGF5TmFtZSIsIk93bmVyIiwib3duZXIiLCJwYXJzZU9iamVjdExvY2tDb25maWciLCJsb2NrQ29uZmlnUmVzdWx0IiwiT2JqZWN0TG9ja0NvbmZpZ3VyYXRpb24iLCJvYmplY3RMb2NrRW5hYmxlZCIsIk9iamVjdExvY2tFbmFibGVkIiwicmV0ZW50aW9uUmVzcCIsIkRlZmF1bHRSZXRlbnRpb24iLCJtb2RlIiwiTW9kZSIsImlzVW5pdFllYXJzIiwiWWVhcnMiLCJ2YWxpZGl0eSIsInVuaXQiLCJZRUFSUyIsIkRheXMiLCJEQVlTIiwicGFyc2VCdWNrZXRWZXJzaW9uaW5nQ29uZmlnIiwiVmVyc2lvbmluZ0NvbmZpZ3VyYXRpb24iLCJleHRyYWN0SGVhZGVyVHlwZSIsInN0cmVhbSIsImhlYWRlck5hbWVMZW4iLCJCdWZmZXIiLCJmcm9tIiwicmVhZCIsInJlYWRVSW50OCIsImhlYWRlck5hbWVXaXRoU2VwYXJhdG9yIiwic3BsaXRCeVNlcGFyYXRvciIsImxlbmd0aCIsImV4dHJhY3RIZWFkZXJWYWx1ZSIsImJvZHlMZW4iLCJyZWFkVUludDE2QkUiLCJwYXJzZVNlbGVjdE9iamVjdENvbnRlbnRSZXNwb25zZSIsInJlcyIsInNlbGVjdFJlc3VsdHMiLCJyZXNwb25zZVN0cmVhbSIsIl9yZWFkYWJsZVN0YXRlIiwibXNnQ3JjQWNjdW11bGF0b3IiLCJ0b3RhbEJ5dGVMZW5ndGhCdWZmZXIiLCJoZWFkZXJCeXRlc0J1ZmZlciIsImNhbGN1bGF0ZWRQcmVsdWRlQ3JjIiwicmVhZEludDMyQkUiLCJwcmVsdWRlQ3JjQnVmZmVyIiwidG90YWxNc2dMZW5ndGgiLCJoZWFkZXJMZW5ndGgiLCJwcmVsdWRlQ3JjQnl0ZVZhbHVlIiwiaGVhZGVyQnl0ZXMiLCJoZWFkZXJSZWFkZXJTdHJlYW0iLCJoZWFkZXJUeXBlTmFtZSIsInBheWxvYWRTdHJlYW0iLCJwYXlMb2FkTGVuZ3RoIiwicGF5TG9hZEJ1ZmZlciIsIm1lc3NhZ2VDcmNCeXRlVmFsdWUiLCJjYWxjdWxhdGVkQ3JjIiwibWVzc2FnZVR5cGUiLCJlcnJvck1lc3NhZ2UiLCJjb250ZW50VHlwZSIsImV2ZW50VHlwZSIsInNldFJlc3BvbnNlIiwiX3BheWxvYWRTdHJlYW0iLCJyZWFkRGF0YSIsInNldFJlY29yZHMiLCJfcGF5bG9hZFN0cmVhbTIiLCJwcm9ncmVzc0RhdGEiLCJzZXRQcm9ncmVzcyIsIl9wYXlsb2FkU3RyZWFtMyIsInN0YXRzRGF0YSIsInNldFN0YXRzIiwid2FybmluZ01lc3NhZ2UiLCJjb25zb2xlIiwid2FybiIsInBhcnNlTGlmZWN5Y2xlQ29uZmlnIiwiTGlmZWN5Y2xlQ29uZmlndXJhdGlvbiIsInBhcnNlQnVja2V0RW5jcnlwdGlvbkNvbmZpZyIsInBhcnNlT2JqZWN0UmV0ZW50aW9uQ29uZmlnIiwicmV0ZW50aW9uQ29uZmlnIiwiUmV0ZW50aW9uIiwicmV0YWluVW50aWxEYXRlIiwiUmV0YWluVW50aWxEYXRlIiwicmVtb3ZlT2JqZWN0c1BhcnNlciIsIkRlbGV0ZVJlc3VsdCIsInBhcnNlQ29weU9iamVjdCIsIkNvcHlPYmplY3RSZXN1bHQiLCJmb3JtYXRPYmpJbmZvIiwib3B0cyIsIlZlcnNpb25JZCIsIklzTGF0ZXN0IiwidW5kZWZpbmVkIiwidmVyc2lvbklkIiwiaXNMYXRlc3QiLCJpc0RlbGV0ZU1hcmtlciIsIklzRGVsZXRlTWFya2VyIiwicGFyc2VMaXN0T2JqZWN0cyIsIm5leHRNYXJrZXIiLCJ2ZXJzaW9uSWRNYXJrZXIiLCJrZXlNYXJrZXIiLCJwYXJzZUNvbW1vblByZWZpeGVzRW50aXR5IiwiY29tbW9uUHJlZml4RW50cnkiLCJsaXN0QnVja2V0UmVzdWx0IiwibGlzdFZlcnNpb25zUmVzdWx0IiwiTGlzdFZlcnNpb25zUmVzdWx0IiwiTWFya2VyIiwiTmV4dE1hcmtlciIsIl9yZXN1bHQkb2JqZWN0cyIsIlZlcnNpb24iLCJEZWxldGVNYXJrZXIiLCJOZXh0VmVyc2lvbklkTWFya2VyIiwidXBsb2FkUGFydFBhcnNlciIsInJlc3BFbCIsIkNvcHlQYXJ0UmVzdWx0Il0sInNvdXJjZXMiOlsieG1sLXBhcnNlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSAqIGFzIGh0dHAgZnJvbSAnbm9kZTpodHRwJ1xuaW1wb3J0IHR5cGUgc3RyZWFtIGZyb20gJ25vZGU6c3RyZWFtJ1xuXG5pbXBvcnQgY3JjMzIgZnJvbSAnYnVmZmVyLWNyYzMyJ1xuaW1wb3J0IHsgWE1MUGFyc2VyIH0gZnJvbSAnZmFzdC14bWwtcGFyc2VyJ1xuXG5pbXBvcnQgKiBhcyBlcnJvcnMgZnJvbSAnLi4vZXJyb3JzLnRzJ1xuaW1wb3J0IHsgU2VsZWN0UmVzdWx0cyB9IGZyb20gJy4uL2hlbHBlcnMudHMnXG5pbXBvcnQgeyBpc09iamVjdCwgcGFyc2VYbWwsIHJlYWRhYmxlU3RyZWFtLCBzYW5pdGl6ZUVUYWcsIHNhbml0aXplT2JqZWN0S2V5LCBzYW5pdGl6ZVNpemUsIHRvQXJyYXkgfSBmcm9tICcuL2hlbHBlci50cydcbmltcG9ydCB7IHJlYWRBc1N0cmluZyB9IGZyb20gJy4vcmVzcG9uc2UudHMnXG5pbXBvcnQgdHlwZSB7XG4gIEJ1Y2tldEl0ZW1Gcm9tTGlzdCxcbiAgQnVja2V0SXRlbVdpdGhNZXRhZGF0YSxcbiAgQ2xvdWRGdW5jdGlvbkNvbmZpZ0VudHJ5LFxuICBDb21tb25QcmVmaXgsXG4gIENvcHlPYmplY3RSZXN1bHRWMSxcbiAgTGlzdEJ1Y2tldFJlc3VsdFYxLFxuICBMaXN0T2JqZWN0VjJSZXMsXG4gIE5vdGlmaWNhdGlvbkNvbmZpZ1Jlc3VsdCxcbiAgT2JqZWN0SW5mbyxcbiAgT2JqZWN0TG9ja0luZm8sXG4gIE9iamVjdFJvd0VudHJ5LFxuICBRdWV1ZUNvbmZpZ0VudHJ5LFxuICBSZXBsaWNhdGlvbkNvbmZpZyxcbiAgVGFnLFxuICBUYWdzLFxuICBUb3BpY0NvbmZpZ0VudHJ5LFxufSBmcm9tICcuL3R5cGUudHMnXG5pbXBvcnQgeyBSRVRFTlRJT05fVkFMSURJVFlfVU5JVFMgfSBmcm9tICcuL3R5cGUudHMnXG5cbi8vIHBhcnNlIFhNTCByZXNwb25zZSBmb3IgYnVja2V0IHJlZ2lvblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQnVja2V0UmVnaW9uKHhtbDogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gcmV0dXJuIHJlZ2lvbiBpbmZvcm1hdGlvblxuICByZXR1cm4gcGFyc2VYbWwoeG1sKS5Mb2NhdGlvbkNvbnN0cmFpbnRcbn1cblxuY29uc3QgZnhwID0gbmV3IFhNTFBhcnNlcigpXG5cbmNvbnN0IGZ4cFdpdGhvdXROdW1QYXJzZXIgPSBuZXcgWE1MUGFyc2VyKHtcbiAgLy8gQHRzLWlnbm9yZVxuICBudW1iZXJQYXJzZU9wdGlvbnM6IHtcbiAgICBza2lwTGlrZTogLy4vLFxuICB9LFxufSlcblxuLy8gUGFyc2UgWE1MIGFuZCByZXR1cm4gaW5mb3JtYXRpb24gYXMgSmF2YXNjcmlwdCB0eXBlc1xuLy8gcGFyc2UgZXJyb3IgWE1MIHJlc3BvbnNlXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VFcnJvcih4bWw6IHN0cmluZywgaGVhZGVySW5mbzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pIHtcbiAgbGV0IHhtbEVyciA9IHt9XG4gIGNvbnN0IHhtbE9iaiA9IGZ4cC5wYXJzZSh4bWwpXG4gIGlmICh4bWxPYmouRXJyb3IpIHtcbiAgICB4bWxFcnIgPSB4bWxPYmouRXJyb3JcbiAgfVxuICBjb25zdCBlID0gbmV3IGVycm9ycy5TM0Vycm9yKCkgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICBPYmplY3QuZW50cmllcyh4bWxFcnIpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgIGVba2V5LnRvTG93ZXJDYXNlKCldID0gdmFsdWVcbiAgfSlcbiAgT2JqZWN0LmVudHJpZXMoaGVhZGVySW5mbykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgZVtrZXldID0gdmFsdWVcbiAgfSlcbiAgcmV0dXJuIGVcbn1cblxuLy8gR2VuZXJhdGVzIGFuIEVycm9yIG9iamVjdCBkZXBlbmRpbmcgb24gaHR0cCBzdGF0dXNDb2RlIGFuZCBYTUwgYm9keVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBhcnNlUmVzcG9uc2VFcnJvcihyZXNwb25zZTogaHR0cC5JbmNvbWluZ01lc3NhZ2UpOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+IHtcbiAgY29uc3Qgc3RhdHVzQ29kZSA9IHJlc3BvbnNlLnN0YXR1c0NvZGVcbiAgbGV0IGNvZGUgPSAnJyxcbiAgICBtZXNzYWdlID0gJydcbiAgaWYgKHN0YXR1c0NvZGUgPT09IDMwMSkge1xuICAgIGNvZGUgPSAnTW92ZWRQZXJtYW5lbnRseSdcbiAgICBtZXNzYWdlID0gJ01vdmVkIFBlcm1hbmVudGx5J1xuICB9IGVsc2UgaWYgKHN0YXR1c0NvZGUgPT09IDMwNykge1xuICAgIGNvZGUgPSAnVGVtcG9yYXJ5UmVkaXJlY3QnXG4gICAgbWVzc2FnZSA9ICdBcmUgeW91IHVzaW5nIHRoZSBjb3JyZWN0IGVuZHBvaW50IFVSTD8nXG4gIH0gZWxzZSBpZiAoc3RhdHVzQ29kZSA9PT0gNDAzKSB7XG4gICAgY29kZSA9ICdBY2Nlc3NEZW5pZWQnXG4gICAgbWVzc2FnZSA9ICdWYWxpZCBhbmQgYXV0aG9yaXplZCBjcmVkZW50aWFscyByZXF1aXJlZCdcbiAgfSBlbHNlIGlmIChzdGF0dXNDb2RlID09PSA0MDQpIHtcbiAgICBjb2RlID0gJ05vdEZvdW5kJ1xuICAgIG1lc3NhZ2UgPSAnTm90IEZvdW5kJ1xuICB9IGVsc2UgaWYgKHN0YXR1c0NvZGUgPT09IDQwNSkge1xuICAgIGNvZGUgPSAnTWV0aG9kTm90QWxsb3dlZCdcbiAgICBtZXNzYWdlID0gJ01ldGhvZCBOb3QgQWxsb3dlZCdcbiAgfSBlbHNlIGlmIChzdGF0dXNDb2RlID09PSA1MDEpIHtcbiAgICBjb2RlID0gJ01ldGhvZE5vdEFsbG93ZWQnXG4gICAgbWVzc2FnZSA9ICdNZXRob2QgTm90IEFsbG93ZWQnXG4gIH0gZWxzZSBpZiAoc3RhdHVzQ29kZSA9PT0gNTAzKSB7XG4gICAgY29kZSA9ICdTbG93RG93bidcbiAgICBtZXNzYWdlID0gJ1BsZWFzZSByZWR1Y2UgeW91ciByZXF1ZXN0IHJhdGUuJ1xuICB9IGVsc2Uge1xuICAgIC8vIFNlcnZlci1zaWRlIGVycm9yIGhlYWRlcnMgKHByb3RvY29sLWxldmVsLCBzZW50IGJ5IFMzLWNvbXBhdGlibGUgc2VydmVycylcbiAgICBjb25zdCBoRXJyQ29kZSA9IChyZXNwb25zZS5oZWFkZXJzWyd4LXMzLWVycm9yLWNvZGUnXSA/PyByZXNwb25zZS5oZWFkZXJzWyd4LW1pbmlvLWVycm9yLWNvZGUnXSkgYXMgc3RyaW5nXG4gICAgY29uc3QgaEVyckRlc2MgPSAocmVzcG9uc2UuaGVhZGVyc1sneC1zMy1lcnJvci1kZXNjJ10gPz8gcmVzcG9uc2UuaGVhZGVyc1sneC1taW5pby1lcnJvci1kZXNjJ10pIGFzIHN0cmluZ1xuXG4gICAgaWYgKGhFcnJDb2RlICYmIGhFcnJEZXNjKSB7XG4gICAgICBjb2RlID0gaEVyckNvZGVcbiAgICAgIG1lc3NhZ2UgPSBoRXJyRGVzY1xuICAgIH1cbiAgfVxuICBjb25zdCBoZWFkZXJJbmZvOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQgfCBudWxsPiA9IHt9XG4gIC8vIEEgdmFsdWUgY3JlYXRlZCBieSBTMyBjb21wYXRpYmxlIHNlcnZlciB0aGF0IHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhlIHJlcXVlc3QuXG4gIGhlYWRlckluZm8uYW16UmVxdWVzdGlkID0gcmVzcG9uc2UuaGVhZGVyc1sneC1hbXotcmVxdWVzdC1pZCddIGFzIHN0cmluZyB8IHVuZGVmaW5lZFxuICAvLyBBIHNwZWNpYWwgdG9rZW4gdGhhdCBoZWxwcyB0cm91Ymxlc2hvb3QgQVBJIHJlcGxpZXMgYW5kIGlzc3Vlcy5cbiAgaGVhZGVySW5mby5hbXpJZDIgPSByZXNwb25zZS5oZWFkZXJzWyd4LWFtei1pZC0yJ10gYXMgc3RyaW5nIHwgdW5kZWZpbmVkXG5cbiAgLy8gUmVnaW9uIHdoZXJlIHRoZSBidWNrZXQgaXMgbG9jYXRlZC4gVGhpcyBoZWFkZXIgaXMgcmV0dXJuZWQgb25seVxuICAvLyBpbiBIRUFEIGJ1Y2tldCBhbmQgTGlzdE9iamVjdHMgcmVzcG9uc2UuXG4gIGhlYWRlckluZm8uYW16QnVja2V0UmVnaW9uID0gcmVzcG9uc2UuaGVhZGVyc1sneC1hbXotYnVja2V0LXJlZ2lvbiddIGFzIHN0cmluZyB8IHVuZGVmaW5lZFxuXG4gIGNvbnN0IHhtbFN0cmluZyA9IGF3YWl0IHJlYWRBc1N0cmluZyhyZXNwb25zZSlcblxuICBpZiAoeG1sU3RyaW5nKSB7XG4gICAgdGhyb3cgcGFyc2VFcnJvcih4bWxTdHJpbmcsIGhlYWRlckluZm8pXG4gIH1cblxuICAvLyBNZXNzYWdlIHNob3VsZCBiZSBpbnN0YW50aWF0ZWQgZm9yIGVhY2ggUzNFcnJvcnMuXG4gIGNvbnN0IGUgPSBuZXcgZXJyb3JzLlMzRXJyb3IobWVzc2FnZSwgeyBjYXVzZTogaGVhZGVySW5mbyB9KVxuICAvLyBTMyBFcnJvciBjb2RlLlxuICBlLmNvZGUgPSBjb2RlXG4gIE9iamVjdC5lbnRyaWVzKGhlYWRlckluZm8pLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgZm9yY2Ugc2V0IGVycm9yIHByb3BlcnRpZXNcbiAgICBlW2tleV0gPSB2YWx1ZVxuICB9KVxuXG4gIHRocm93IGVcbn1cblxuLyoqXG4gKiBwYXJzZSBYTUwgcmVzcG9uc2UgZm9yIGxpc3Qgb2JqZWN0cyB2MiB3aXRoIG1ldGFkYXRhIGluIGEgYnVja2V0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxpc3RPYmplY3RzVjJXaXRoTWV0YWRhdGEoeG1sOiBzdHJpbmcpIHtcbiAgY29uc3QgcmVzdWx0OiB7XG4gICAgb2JqZWN0czogQXJyYXk8QnVja2V0SXRlbVdpdGhNZXRhZGF0YT5cbiAgICBpc1RydW5jYXRlZDogYm9vbGVhblxuICAgIG5leHRDb250aW51YXRpb25Ub2tlbjogc3RyaW5nXG4gIH0gPSB7XG4gICAgb2JqZWN0czogW10sXG4gICAgaXNUcnVuY2F0ZWQ6IGZhbHNlLFxuICAgIG5leHRDb250aW51YXRpb25Ub2tlbjogJycsXG4gIH1cblxuICBsZXQgeG1sb2JqID0gcGFyc2VYbWwoeG1sKVxuICBpZiAoIXhtbG9iai5MaXN0QnVja2V0UmVzdWx0KSB7XG4gICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkWE1MRXJyb3IoJ01pc3NpbmcgdGFnOiBcIkxpc3RCdWNrZXRSZXN1bHRcIicpXG4gIH1cbiAgeG1sb2JqID0geG1sb2JqLkxpc3RCdWNrZXRSZXN1bHRcbiAgaWYgKHhtbG9iai5Jc1RydW5jYXRlZCkge1xuICAgIHJlc3VsdC5pc1RydW5jYXRlZCA9IHhtbG9iai5Jc1RydW5jYXRlZFxuICB9XG4gIGlmICh4bWxvYmouTmV4dENvbnRpbnVhdGlvblRva2VuKSB7XG4gICAgcmVzdWx0Lm5leHRDb250aW51YXRpb25Ub2tlbiA9IHhtbG9iai5OZXh0Q29udGludWF0aW9uVG9rZW5cbiAgfVxuXG4gIGlmICh4bWxvYmouQ29udGVudHMpIHtcbiAgICB0b0FycmF5KHhtbG9iai5Db250ZW50cykuZm9yRWFjaCgoY29udGVudCkgPT4ge1xuICAgICAgY29uc3QgbmFtZSA9IHNhbml0aXplT2JqZWN0S2V5KGNvbnRlbnQuS2V5KVxuICAgICAgY29uc3QgbGFzdE1vZGlmaWVkID0gbmV3IERhdGUoY29udGVudC5MYXN0TW9kaWZpZWQpXG4gICAgICBjb25zdCBldGFnID0gc2FuaXRpemVFVGFnKGNvbnRlbnQuRVRhZylcbiAgICAgIGNvbnN0IHNpemUgPSBjb250ZW50LlNpemVcblxuICAgICAgbGV0IHRhZ3M6IFRhZ3MgPSB7fVxuICAgICAgaWYgKGNvbnRlbnQuVXNlclRhZ3MgIT0gbnVsbCkge1xuICAgICAgICB0b0FycmF5KGNvbnRlbnQuVXNlclRhZ3Muc3BsaXQoJyYnKSkuZm9yRWFjaCgodGFnKSA9PiB7XG4gICAgICAgICAgY29uc3QgW2tleSwgdmFsdWVdID0gdGFnLnNwbGl0KCc9JylcbiAgICAgICAgICB0YWdzW2tleV0gPSB2YWx1ZVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFncyA9IHt9XG4gICAgICB9XG5cbiAgICAgIGxldCBtZXRhZGF0YVxuICAgICAgaWYgKGNvbnRlbnQuVXNlck1ldGFkYXRhICE9IG51bGwpIHtcbiAgICAgICAgbWV0YWRhdGEgPSB0b0FycmF5KGNvbnRlbnQuVXNlck1ldGFkYXRhKVswXVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWV0YWRhdGEgPSBudWxsXG4gICAgICB9XG4gICAgICByZXN1bHQub2JqZWN0cy5wdXNoKHsgbmFtZSwgbGFzdE1vZGlmaWVkLCBldGFnLCBzaXplLCBtZXRhZGF0YSwgdGFncyB9KVxuICAgIH0pXG4gIH1cblxuICBpZiAoeG1sb2JqLkNvbW1vblByZWZpeGVzKSB7XG4gICAgdG9BcnJheSh4bWxvYmouQ29tbW9uUHJlZml4ZXMpLmZvckVhY2goKGNvbW1vblByZWZpeCkgPT4ge1xuICAgICAgcmVzdWx0Lm9iamVjdHMucHVzaCh7IHByZWZpeDogc2FuaXRpemVPYmplY3RLZXkodG9BcnJheShjb21tb25QcmVmaXguUHJlZml4KVswXSksIHNpemU6IDAgfSlcbiAgICB9KVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTGlzdE9iamVjdHNWMih4bWw6IHN0cmluZyk6IExpc3RPYmplY3RWMlJlcyB7XG4gIGNvbnN0IHJlc3VsdDogTGlzdE9iamVjdFYyUmVzID0ge1xuICAgIG9iamVjdHM6IFtdLFxuICAgIGlzVHJ1bmNhdGVkOiBmYWxzZSxcbiAgICBuZXh0Q29udGludWF0aW9uVG9rZW46ICcnLFxuICB9XG5cbiAgbGV0IHhtbG9iaiA9IHBhcnNlWG1sKHhtbClcbiAgaWYgKCF4bWxvYmouTGlzdEJ1Y2tldFJlc3VsdCkge1xuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZFhNTEVycm9yKCdNaXNzaW5nIHRhZzogXCJMaXN0QnVja2V0UmVzdWx0XCInKVxuICB9XG4gIHhtbG9iaiA9IHhtbG9iai5MaXN0QnVja2V0UmVzdWx0XG4gIGlmICh4bWxvYmouSXNUcnVuY2F0ZWQpIHtcbiAgICByZXN1bHQuaXNUcnVuY2F0ZWQgPSB4bWxvYmouSXNUcnVuY2F0ZWRcbiAgfVxuICBpZiAoeG1sb2JqLk5leHRDb250aW51YXRpb25Ub2tlbikge1xuICAgIHJlc3VsdC5uZXh0Q29udGludWF0aW9uVG9rZW4gPSB4bWxvYmouTmV4dENvbnRpbnVhdGlvblRva2VuXG4gIH1cbiAgaWYgKHhtbG9iai5Db250ZW50cykge1xuICAgIHRvQXJyYXkoeG1sb2JqLkNvbnRlbnRzKS5mb3JFYWNoKChjb250ZW50KSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gc2FuaXRpemVPYmplY3RLZXkodG9BcnJheShjb250ZW50LktleSlbMF0pXG4gICAgICBjb25zdCBsYXN0TW9kaWZpZWQgPSBuZXcgRGF0ZShjb250ZW50Lkxhc3RNb2RpZmllZClcbiAgICAgIGNvbnN0IGV0YWcgPSBzYW5pdGl6ZUVUYWcoY29udGVudC5FVGFnKVxuICAgICAgY29uc3Qgc2l6ZSA9IGNvbnRlbnQuU2l6ZVxuICAgICAgcmVzdWx0Lm9iamVjdHMucHVzaCh7IG5hbWUsIGxhc3RNb2RpZmllZCwgZXRhZywgc2l6ZSB9KVxuICAgIH0pXG4gIH1cbiAgaWYgKHhtbG9iai5Db21tb25QcmVmaXhlcykge1xuICAgIHRvQXJyYXkoeG1sb2JqLkNvbW1vblByZWZpeGVzKS5mb3JFYWNoKChjb21tb25QcmVmaXgpID0+IHtcbiAgICAgIHJlc3VsdC5vYmplY3RzLnB1c2goeyBwcmVmaXg6IHNhbml0aXplT2JqZWN0S2V5KHRvQXJyYXkoY29tbW9uUHJlZml4LlByZWZpeClbMF0pLCBzaXplOiAwIH0pXG4gICAgfSlcbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJ1Y2tldE5vdGlmaWNhdGlvbih4bWw6IHN0cmluZyk6IE5vdGlmaWNhdGlvbkNvbmZpZ1Jlc3VsdCB7XG4gIGNvbnN0IHJlc3VsdDogTm90aWZpY2F0aW9uQ29uZmlnUmVzdWx0ID0ge1xuICAgIFRvcGljQ29uZmlndXJhdGlvbjogW10sXG4gICAgUXVldWVDb25maWd1cmF0aW9uOiBbXSxcbiAgICBDbG91ZEZ1bmN0aW9uQ29uZmlndXJhdGlvbjogW10sXG4gIH1cblxuICBjb25zdCBnZW5FdmVudHMgPSAoZXZlbnRzOiB1bmtub3duKTogc3RyaW5nW10gPT4ge1xuICAgIGlmICghZXZlbnRzKSB7XG4gICAgICByZXR1cm4gW11cbiAgICB9XG4gICAgcmV0dXJuIHRvQXJyYXkoZXZlbnRzKSBhcyBzdHJpbmdbXVxuICB9XG5cbiAgY29uc3QgZ2VuRmlsdGVyUnVsZXMgPSAoZmlsdGVyczogdW5rbm93bik6IHsgTmFtZTogc3RyaW5nOyBWYWx1ZTogc3RyaW5nIH1bXSA9PiB7XG4gICAgY29uc3QgcnVsZXM6IHsgTmFtZTogc3RyaW5nOyBWYWx1ZTogc3RyaW5nIH1bXSA9IFtdXG4gICAgaWYgKCFmaWx0ZXJzKSB7XG4gICAgICByZXR1cm4gcnVsZXNcbiAgICB9XG4gICAgY29uc3QgZmlsdGVyQXJyID0gdG9BcnJheShmaWx0ZXJzKSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdXG4gICAgaWYgKGZpbHRlckFyclswXT8uUzNLZXkpIHtcbiAgICAgIGNvbnN0IHMzS2V5QXJyID0gdG9BcnJheSgoZmlsdGVyQXJyWzBdIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5TM0tleSkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXVxuICAgICAgaWYgKHMzS2V5QXJyWzBdPy5GaWx0ZXJSdWxlKSB7XG4gICAgICAgIHRvQXJyYXkoczNLZXlBcnJbMF0uRmlsdGVyUnVsZSkuZm9yRWFjaCgocnVsZTogdW5rbm93bikgPT4ge1xuICAgICAgICAgIGNvbnN0IHIgPSBydWxlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICAgICAgICAgY29uc3QgTmFtZSA9IHRvQXJyYXkoci5OYW1lKVswXSBhcyBzdHJpbmdcbiAgICAgICAgICBjb25zdCBWYWx1ZSA9IHRvQXJyYXkoci5WYWx1ZSlbMF0gYXMgc3RyaW5nXG4gICAgICAgICAgcnVsZXMucHVzaCh7IE5hbWUsIFZhbHVlIH0pXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBydWxlc1xuICB9XG5cbiAgbGV0IHhtbG9iaiA9IHBhcnNlWG1sKHhtbClcbiAgeG1sb2JqID0geG1sb2JqLk5vdGlmaWNhdGlvbkNvbmZpZ3VyYXRpb25cblxuICBpZiAoeG1sb2JqLlRvcGljQ29uZmlndXJhdGlvbikge1xuICAgIHRvQXJyYXkoeG1sb2JqLlRvcGljQ29uZmlndXJhdGlvbikuZm9yRWFjaCgoY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4ge1xuICAgICAgY29uc3QgSWQgPSB0b0FycmF5KGNvbmZpZy5JZClbMF0gYXMgc3RyaW5nXG4gICAgICBjb25zdCBUb3BpYyA9IHRvQXJyYXkoY29uZmlnLlRvcGljKVswXSBhcyBzdHJpbmdcbiAgICAgIGNvbnN0IEV2ZW50ID0gZ2VuRXZlbnRzKGNvbmZpZy5FdmVudClcbiAgICAgIGNvbnN0IEZpbHRlciA9IGdlbkZpbHRlclJ1bGVzKGNvbmZpZy5GaWx0ZXIpXG4gICAgICByZXN1bHQuVG9waWNDb25maWd1cmF0aW9uLnB1c2goeyBJZCwgVG9waWMsIEV2ZW50LCBGaWx0ZXIgfSBhcyBUb3BpY0NvbmZpZ0VudHJ5KVxuICAgIH0pXG4gIH1cbiAgaWYgKHhtbG9iai5RdWV1ZUNvbmZpZ3VyYXRpb24pIHtcbiAgICB0b0FycmF5KHhtbG9iai5RdWV1ZUNvbmZpZ3VyYXRpb24pLmZvckVhY2goKGNvbmZpZzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHtcbiAgICAgIGNvbnN0IElkID0gdG9BcnJheShjb25maWcuSWQpWzBdIGFzIHN0cmluZ1xuICAgICAgY29uc3QgUXVldWUgPSB0b0FycmF5KGNvbmZpZy5RdWV1ZSlbMF0gYXMgc3RyaW5nXG4gICAgICBjb25zdCBFdmVudCA9IGdlbkV2ZW50cyhjb25maWcuRXZlbnQpXG4gICAgICBjb25zdCBGaWx0ZXIgPSBnZW5GaWx0ZXJSdWxlcyhjb25maWcuRmlsdGVyKVxuICAgICAgcmVzdWx0LlF1ZXVlQ29uZmlndXJhdGlvbi5wdXNoKHsgSWQsIFF1ZXVlLCBFdmVudCwgRmlsdGVyIH0gYXMgUXVldWVDb25maWdFbnRyeSlcbiAgICB9KVxuICB9XG4gIGlmICh4bWxvYmouQ2xvdWRGdW5jdGlvbkNvbmZpZ3VyYXRpb24pIHtcbiAgICB0b0FycmF5KHhtbG9iai5DbG91ZEZ1bmN0aW9uQ29uZmlndXJhdGlvbikuZm9yRWFjaCgoY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4ge1xuICAgICAgY29uc3QgSWQgPSB0b0FycmF5KGNvbmZpZy5JZClbMF0gYXMgc3RyaW5nXG4gICAgICBjb25zdCBDbG91ZEZ1bmN0aW9uID0gdG9BcnJheShjb25maWcuQ2xvdWRGdW5jdGlvbilbMF0gYXMgc3RyaW5nXG4gICAgICBjb25zdCBFdmVudCA9IGdlbkV2ZW50cyhjb25maWcuRXZlbnQpXG4gICAgICBjb25zdCBGaWx0ZXIgPSBnZW5GaWx0ZXJSdWxlcyhjb25maWcuRmlsdGVyKVxuICAgICAgcmVzdWx0LkNsb3VkRnVuY3Rpb25Db25maWd1cmF0aW9uLnB1c2goeyBJZCwgQ2xvdWRGdW5jdGlvbiwgRXZlbnQsIEZpbHRlciB9IGFzIENsb3VkRnVuY3Rpb25Db25maWdFbnRyeSlcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG5leHBvcnQgdHlwZSBVcGxvYWRlZFBhcnQgPSB7XG4gIHBhcnQ6IG51bWJlclxuICBsYXN0TW9kaWZpZWQ/OiBEYXRlXG4gIGV0YWc6IHN0cmluZ1xuICBzaXplOiBudW1iZXJcbn1cblxuLy8gcGFyc2UgWE1MIHJlc3BvbnNlIGZvciBsaXN0IHBhcnRzIG9mIGFuIGluIHByb2dyZXNzIG11bHRpcGFydCB1cGxvYWRcbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxpc3RQYXJ0cyh4bWw6IHN0cmluZyk6IHtcbiAgaXNUcnVuY2F0ZWQ6IGJvb2xlYW5cbiAgbWFya2VyOiBudW1iZXJcbiAgcGFydHM6IFVwbG9hZGVkUGFydFtdXG59IHtcbiAgbGV0IHhtbG9iaiA9IHBhcnNlWG1sKHhtbClcbiAgY29uc3QgcmVzdWx0OiB7XG4gICAgaXNUcnVuY2F0ZWQ6IGJvb2xlYW5cbiAgICBtYXJrZXI6IG51bWJlclxuICAgIHBhcnRzOiBVcGxvYWRlZFBhcnRbXVxuICB9ID0ge1xuICAgIGlzVHJ1bmNhdGVkOiBmYWxzZSxcbiAgICBwYXJ0czogW10sXG4gICAgbWFya2VyOiAwLFxuICB9XG4gIGlmICgheG1sb2JqLkxpc3RQYXJ0c1Jlc3VsdCkge1xuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZFhNTEVycm9yKCdNaXNzaW5nIHRhZzogXCJMaXN0UGFydHNSZXN1bHRcIicpXG4gIH1cbiAgeG1sb2JqID0geG1sb2JqLkxpc3RQYXJ0c1Jlc3VsdFxuICBpZiAoeG1sb2JqLklzVHJ1bmNhdGVkKSB7XG4gICAgcmVzdWx0LmlzVHJ1bmNhdGVkID0geG1sb2JqLklzVHJ1bmNhdGVkXG4gIH1cbiAgaWYgKHhtbG9iai5OZXh0UGFydE51bWJlck1hcmtlcikge1xuICAgIHJlc3VsdC5tYXJrZXIgPSB0b0FycmF5KHhtbG9iai5OZXh0UGFydE51bWJlck1hcmtlcilbMF0gfHwgJydcbiAgfVxuICBpZiAoeG1sb2JqLlBhcnQpIHtcbiAgICB0b0FycmF5KHhtbG9iai5QYXJ0KS5mb3JFYWNoKChwKSA9PiB7XG4gICAgICBjb25zdCBwYXJ0ID0gcGFyc2VJbnQodG9BcnJheShwLlBhcnROdW1iZXIpWzBdLCAxMClcbiAgICAgIGNvbnN0IGxhc3RNb2RpZmllZCA9IG5ldyBEYXRlKHAuTGFzdE1vZGlmaWVkKVxuICAgICAgY29uc3QgZXRhZyA9IHAuRVRhZy5yZXBsYWNlKC9eXCIvZywgJycpXG4gICAgICAgIC5yZXBsYWNlKC9cIiQvZywgJycpXG4gICAgICAgIC5yZXBsYWNlKC9eJnF1b3Q7L2csICcnKVxuICAgICAgICAucmVwbGFjZSgvJnF1b3Q7JC9nLCAnJylcbiAgICAgICAgLnJlcGxhY2UoL14mIzM0Oy9nLCAnJylcbiAgICAgICAgLnJlcGxhY2UoLyYjMzQ7JC9nLCAnJylcbiAgICAgIHJlc3VsdC5wYXJ0cy5wdXNoKHsgcGFydCwgbGFzdE1vZGlmaWVkLCBldGFnLCBzaXplOiBwYXJzZUludChwLlNpemUsIDEwKSB9KVxuICAgIH0pXG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VMaXN0QnVja2V0KHhtbDogc3RyaW5nKTogQnVja2V0SXRlbUZyb21MaXN0W10ge1xuICBsZXQgcmVzdWx0OiBCdWNrZXRJdGVtRnJvbUxpc3RbXSA9IFtdXG4gIGNvbnN0IGxpc3RCdWNrZXRSZXN1bHRQYXJzZXIgPSBuZXcgWE1MUGFyc2VyKHtcbiAgICBwYXJzZVRhZ1ZhbHVlOiB0cnVlLCAvLyBFbmFibGUgcGFyc2luZyBvZiB2YWx1ZXNcbiAgICBudW1iZXJQYXJzZU9wdGlvbnM6IHtcbiAgICAgIGxlYWRpbmdaZXJvczogZmFsc2UsIC8vIERpc2FibGUgbnVtYmVyIHBhcnNpbmcgZm9yIHZhbHVlcyB3aXRoIGxlYWRpbmcgemVyb3NcbiAgICAgIGhleDogZmFsc2UsIC8vIERpc2FibGUgaGV4IG51bWJlciBwYXJzaW5nIC0gSW52YWxpZCBidWNrZXQgbmFtZVxuICAgICAgc2tpcExpa2U6IC9eWzAtOV0rJC8sIC8vIFNraXAgbnVtYmVyIHBhcnNpbmcgaWYgdGhlIHZhbHVlIGNvbnNpc3RzIGVudGlyZWx5IG9mIGRpZ2l0c1xuICAgIH0sXG4gICAgdGFnVmFsdWVQcm9jZXNzb3I6ICh0YWdOYW1lLCB0YWdWYWx1ZSA9ICcnKSA9PiB7XG4gICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgTmFtZSB0YWcgaXMgYWx3YXlzIHRyZWF0ZWQgYXMgYSBzdHJpbmdcbiAgICAgIGlmICh0YWdOYW1lID09PSAnTmFtZScpIHtcbiAgICAgICAgcmV0dXJuIHRhZ1ZhbHVlLnRvU3RyaW5nKClcbiAgICAgIH1cbiAgICAgIHJldHVybiB0YWdWYWx1ZVxuICAgIH0sXG4gICAgaWdub3JlQXR0cmlidXRlczogZmFsc2UsIC8vIEVuc3VyZSB0aGF0IGFsbCBhdHRyaWJ1dGVzIGFyZSBwYXJzZWRcbiAgfSlcblxuICBjb25zdCBwYXJzZWRYbWxSZXMgPSBsaXN0QnVja2V0UmVzdWx0UGFyc2VyLnBhcnNlKHhtbClcblxuICBpZiAoIXBhcnNlZFhtbFJlcy5MaXN0QWxsTXlCdWNrZXRzUmVzdWx0KSB7XG4gICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkWE1MRXJyb3IoJ01pc3NpbmcgdGFnOiBcIkxpc3RBbGxNeUJ1Y2tldHNSZXN1bHRcIicpXG4gIH1cblxuICBjb25zdCB7IExpc3RBbGxNeUJ1Y2tldHNSZXN1bHQ6IHsgQnVja2V0cyA9IHt9IH0gPSB7fSB9ID0gcGFyc2VkWG1sUmVzXG5cbiAgaWYgKEJ1Y2tldHMuQnVja2V0KSB7XG4gICAgcmVzdWx0ID0gdG9BcnJheShCdWNrZXRzLkJ1Y2tldCkubWFwKChidWNrZXQgPSB7fSkgPT4ge1xuICAgICAgY29uc3QgeyBOYW1lOiBidWNrZXROYW1lLCBDcmVhdGlvbkRhdGUgfSA9IGJ1Y2tldFxuICAgICAgY29uc3QgY3JlYXRpb25EYXRlID0gbmV3IERhdGUoQ3JlYXRpb25EYXRlKVxuXG4gICAgICByZXR1cm4geyBuYW1lOiBidWNrZXROYW1lLCBjcmVhdGlvbkRhdGUgfVxuICAgIH0pXG4gIH1cblxuICByZXR1cm4gcmVzdWx0XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUluaXRpYXRlTXVsdGlwYXJ0KHhtbDogc3RyaW5nKTogc3RyaW5nIHtcbiAgbGV0IHhtbG9iaiA9IHBhcnNlWG1sKHhtbClcblxuICBpZiAoIXhtbG9iai5Jbml0aWF0ZU11bHRpcGFydFVwbG9hZFJlc3VsdCkge1xuICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZFhNTEVycm9yKCdNaXNzaW5nIHRhZzogXCJJbml0aWF0ZU11bHRpcGFydFVwbG9hZFJlc3VsdFwiJylcbiAgfVxuICB4bWxvYmogPSB4bWxvYmouSW5pdGlhdGVNdWx0aXBhcnRVcGxvYWRSZXN1bHRcblxuICBpZiAoeG1sb2JqLlVwbG9hZElkKSB7XG4gICAgcmV0dXJuIHhtbG9iai5VcGxvYWRJZFxuICB9XG4gIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZFhNTEVycm9yKCdNaXNzaW5nIHRhZzogXCJVcGxvYWRJZFwiJylcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUmVwbGljYXRpb25Db25maWcoeG1sOiBzdHJpbmcpOiBSZXBsaWNhdGlvbkNvbmZpZyB7XG4gIGNvbnN0IHhtbE9iaiA9IHBhcnNlWG1sKHhtbClcbiAgY29uc3QgeyBSb2xlLCBSdWxlIH0gPSB4bWxPYmouUmVwbGljYXRpb25Db25maWd1cmF0aW9uXG4gIHJldHVybiB7XG4gICAgUmVwbGljYXRpb25Db25maWd1cmF0aW9uOiB7XG4gICAgICByb2xlOiBSb2xlLFxuICAgICAgcnVsZXM6IHRvQXJyYXkoUnVsZSksXG4gICAgfSxcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VPYmplY3RMZWdhbEhvbGRDb25maWcoeG1sOiBzdHJpbmcpIHtcbiAgY29uc3QgeG1sT2JqID0gcGFyc2VYbWwoeG1sKVxuICByZXR1cm4geG1sT2JqLkxlZ2FsSG9sZFxufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUYWdnaW5nKHhtbDogc3RyaW5nKSB7XG4gIGNvbnN0IHhtbE9iaiA9IHBhcnNlWG1sKHhtbClcbiAgbGV0IHJlc3VsdDogVGFnW10gPSBbXVxuICBpZiAoeG1sT2JqLlRhZ2dpbmcgJiYgeG1sT2JqLlRhZ2dpbmcuVGFnU2V0ICYmIHhtbE9iai5UYWdnaW5nLlRhZ1NldC5UYWcpIHtcbiAgICBjb25zdCB0YWdSZXN1bHQ6IFRhZyA9IHhtbE9iai5UYWdnaW5nLlRhZ1NldC5UYWdcbiAgICAvLyBpZiBpdCBpcyBhIHNpbmdsZSB0YWcgY29udmVydCBpbnRvIGFuIGFycmF5IHNvIHRoYXQgdGhlIHJldHVybiB2YWx1ZSBpcyBhbHdheXMgYW4gYXJyYXkuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGFnUmVzdWx0KSkge1xuICAgICAgcmVzdWx0ID0gWy4uLnRhZ1Jlc3VsdF1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0LnB1c2godGFnUmVzdWx0KVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbi8vIHBhcnNlIFhNTCByZXNwb25zZSB3aGVuIGEgbXVsdGlwYXJ0IHVwbG9hZCBpcyBjb21wbGV0ZWRcbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUNvbXBsZXRlTXVsdGlwYXJ0KHhtbDogc3RyaW5nKSB7XG4gIGNvbnN0IHhtbG9iaiA9IHBhcnNlWG1sKHhtbCkuQ29tcGxldGVNdWx0aXBhcnRVcGxvYWRSZXN1bHRcbiAgaWYgKHhtbG9iai5Mb2NhdGlvbikge1xuICAgIGNvbnN0IGxvY2F0aW9uID0gdG9BcnJheSh4bWxvYmouTG9jYXRpb24pWzBdXG4gICAgY29uc3QgYnVja2V0ID0gdG9BcnJheSh4bWxvYmouQnVja2V0KVswXVxuICAgIGNvbnN0IGtleSA9IHhtbG9iai5LZXlcbiAgICBjb25zdCBldGFnID0geG1sb2JqLkVUYWcucmVwbGFjZSgvXlwiL2csICcnKVxuICAgICAgLnJlcGxhY2UoL1wiJC9nLCAnJylcbiAgICAgIC5yZXBsYWNlKC9eJnF1b3Q7L2csICcnKVxuICAgICAgLnJlcGxhY2UoLyZxdW90OyQvZywgJycpXG4gICAgICAucmVwbGFjZSgvXiYjMzQ7L2csICcnKVxuICAgICAgLnJlcGxhY2UoLyYjMzQ7JC9nLCAnJylcblxuICAgIHJldHVybiB7IGxvY2F0aW9uLCBidWNrZXQsIGtleSwgZXRhZyB9XG4gIH1cbiAgLy8gQ29tcGxldGUgTXVsdGlwYXJ0IGNhbiByZXR1cm4gWE1MIEVycm9yIGFmdGVyIGEgMjAwIE9LIHJlc3BvbnNlXG4gIGlmICh4bWxvYmouQ29kZSAmJiB4bWxvYmouTWVzc2FnZSkge1xuICAgIGNvbnN0IGVyckNvZGUgPSB0b0FycmF5KHhtbG9iai5Db2RlKVswXVxuICAgIGNvbnN0IGVyck1lc3NhZ2UgPSB0b0FycmF5KHhtbG9iai5NZXNzYWdlKVswXVxuICAgIHJldHVybiB7IGVyckNvZGUsIGVyck1lc3NhZ2UgfVxuICB9XG59XG5cbnR5cGUgVXBsb2FkSUQgPSBzdHJpbmdcblxuZXhwb3J0IHR5cGUgTGlzdE11bHRpcGFydFJlc3VsdCA9IHtcbiAgdXBsb2Fkczoge1xuICAgIGtleTogc3RyaW5nXG4gICAgdXBsb2FkSWQ6IFVwbG9hZElEXG4gICAgaW5pdGlhdG9yPzogeyBpZDogc3RyaW5nOyBkaXNwbGF5TmFtZTogc3RyaW5nIH1cbiAgICBvd25lcj86IHsgaWQ6IHN0cmluZzsgZGlzcGxheU5hbWU6IHN0cmluZyB9XG4gICAgc3RvcmFnZUNsYXNzOiB1bmtub3duXG4gICAgaW5pdGlhdGVkOiBEYXRlXG4gIH1bXVxuICBwcmVmaXhlczoge1xuICAgIHByZWZpeDogc3RyaW5nXG4gIH1bXVxuICBpc1RydW5jYXRlZDogYm9vbGVhblxuICBuZXh0S2V5TWFya2VyOiBzdHJpbmdcbiAgbmV4dFVwbG9hZElkTWFya2VyOiBzdHJpbmdcbn1cblxuLy8gcGFyc2UgWE1MIHJlc3BvbnNlIGZvciBsaXN0aW5nIGluLXByb2dyZXNzIG11bHRpcGFydCB1cGxvYWRzXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VMaXN0TXVsdGlwYXJ0KHhtbDogc3RyaW5nKTogTGlzdE11bHRpcGFydFJlc3VsdCB7XG4gIGNvbnN0IHJlc3VsdDogTGlzdE11bHRpcGFydFJlc3VsdCA9IHtcbiAgICBwcmVmaXhlczogW10sXG4gICAgdXBsb2FkczogW10sXG4gICAgaXNUcnVuY2F0ZWQ6IGZhbHNlLFxuICAgIG5leHRLZXlNYXJrZXI6ICcnLFxuICAgIG5leHRVcGxvYWRJZE1hcmtlcjogJycsXG4gIH1cblxuICBsZXQgeG1sb2JqID0gcGFyc2VYbWwoeG1sKVxuXG4gIGlmICgheG1sb2JqLkxpc3RNdWx0aXBhcnRVcGxvYWRzUmVzdWx0KSB7XG4gICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkWE1MRXJyb3IoJ01pc3NpbmcgdGFnOiBcIkxpc3RNdWx0aXBhcnRVcGxvYWRzUmVzdWx0XCInKVxuICB9XG4gIHhtbG9iaiA9IHhtbG9iai5MaXN0TXVsdGlwYXJ0VXBsb2Fkc1Jlc3VsdFxuICBpZiAoeG1sb2JqLklzVHJ1bmNhdGVkKSB7XG4gICAgcmVzdWx0LmlzVHJ1bmNhdGVkID0geG1sb2JqLklzVHJ1bmNhdGVkXG4gIH1cbiAgaWYgKHhtbG9iai5OZXh0S2V5TWFya2VyKSB7XG4gICAgcmVzdWx0Lm5leHRLZXlNYXJrZXIgPSB4bWxvYmouTmV4dEtleU1hcmtlclxuICB9XG4gIGlmICh4bWxvYmouTmV4dFVwbG9hZElkTWFya2VyKSB7XG4gICAgcmVzdWx0Lm5leHRVcGxvYWRJZE1hcmtlciA9IHhtbG9iai5uZXh0VXBsb2FkSWRNYXJrZXIgfHwgJydcbiAgfVxuXG4gIGlmICh4bWxvYmouQ29tbW9uUHJlZml4ZXMpIHtcbiAgICB0b0FycmF5KHhtbG9iai5Db21tb25QcmVmaXhlcykuZm9yRWFjaCgocHJlZml4KSA9PiB7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGluZGV4IGNoZWNrXG4gICAgICByZXN1bHQucHJlZml4ZXMucHVzaCh7IHByZWZpeDogc2FuaXRpemVPYmplY3RLZXkodG9BcnJheTxzdHJpbmc+KHByZWZpeC5QcmVmaXgpWzBdKSB9KVxuICAgIH0pXG4gIH1cblxuICBpZiAoeG1sb2JqLlVwbG9hZCkge1xuICAgIHRvQXJyYXkoeG1sb2JqLlVwbG9hZCkuZm9yRWFjaCgodXBsb2FkKSA9PiB7XG4gICAgICBjb25zdCB1cGxvYWRJdGVtOiBMaXN0TXVsdGlwYXJ0UmVzdWx0Wyd1cGxvYWRzJ11bbnVtYmVyXSA9IHtcbiAgICAgICAga2V5OiB1cGxvYWQuS2V5LFxuICAgICAgICB1cGxvYWRJZDogdXBsb2FkLlVwbG9hZElkLFxuICAgICAgICBzdG9yYWdlQ2xhc3M6IHVwbG9hZC5TdG9yYWdlQ2xhc3MsXG4gICAgICAgIGluaXRpYXRlZDogbmV3IERhdGUodXBsb2FkLkluaXRpYXRlZCksXG4gICAgICB9XG4gICAgICBpZiAodXBsb2FkLkluaXRpYXRvcikge1xuICAgICAgICB1cGxvYWRJdGVtLmluaXRpYXRvciA9IHsgaWQ6IHVwbG9hZC5Jbml0aWF0b3IuSUQsIGRpc3BsYXlOYW1lOiB1cGxvYWQuSW5pdGlhdG9yLkRpc3BsYXlOYW1lIH1cbiAgICAgIH1cbiAgICAgIGlmICh1cGxvYWQuT3duZXIpIHtcbiAgICAgICAgdXBsb2FkSXRlbS5vd25lciA9IHsgaWQ6IHVwbG9hZC5Pd25lci5JRCwgZGlzcGxheU5hbWU6IHVwbG9hZC5Pd25lci5EaXNwbGF5TmFtZSB9XG4gICAgICB9XG4gICAgICByZXN1bHQudXBsb2Fkcy5wdXNoKHVwbG9hZEl0ZW0pXG4gICAgfSlcbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU9iamVjdExvY2tDb25maWcoeG1sOiBzdHJpbmcpOiBPYmplY3RMb2NrSW5mbyB7XG4gIGNvbnN0IHhtbE9iaiA9IHBhcnNlWG1sKHhtbClcbiAgbGV0IGxvY2tDb25maWdSZXN1bHQgPSB7fSBhcyBPYmplY3RMb2NrSW5mb1xuICBpZiAoeG1sT2JqLk9iamVjdExvY2tDb25maWd1cmF0aW9uKSB7XG4gICAgbG9ja0NvbmZpZ1Jlc3VsdCA9IHtcbiAgICAgIG9iamVjdExvY2tFbmFibGVkOiB4bWxPYmouT2JqZWN0TG9ja0NvbmZpZ3VyYXRpb24uT2JqZWN0TG9ja0VuYWJsZWQsXG4gICAgfSBhcyBPYmplY3RMb2NrSW5mb1xuICAgIGxldCByZXRlbnRpb25SZXNwXG4gICAgaWYgKFxuICAgICAgeG1sT2JqLk9iamVjdExvY2tDb25maWd1cmF0aW9uICYmXG4gICAgICB4bWxPYmouT2JqZWN0TG9ja0NvbmZpZ3VyYXRpb24uUnVsZSAmJlxuICAgICAgeG1sT2JqLk9iamVjdExvY2tDb25maWd1cmF0aW9uLlJ1bGUuRGVmYXVsdFJldGVudGlvblxuICAgICkge1xuICAgICAgcmV0ZW50aW9uUmVzcCA9IHhtbE9iai5PYmplY3RMb2NrQ29uZmlndXJhdGlvbi5SdWxlLkRlZmF1bHRSZXRlbnRpb24gfHwge31cbiAgICAgIGxvY2tDb25maWdSZXN1bHQubW9kZSA9IHJldGVudGlvblJlc3AuTW9kZVxuICAgIH1cbiAgICBpZiAocmV0ZW50aW9uUmVzcCkge1xuICAgICAgY29uc3QgaXNVbml0WWVhcnMgPSByZXRlbnRpb25SZXNwLlllYXJzXG4gICAgICBpZiAoaXNVbml0WWVhcnMpIHtcbiAgICAgICAgbG9ja0NvbmZpZ1Jlc3VsdC52YWxpZGl0eSA9IGlzVW5pdFllYXJzXG4gICAgICAgIGxvY2tDb25maWdSZXN1bHQudW5pdCA9IFJFVEVOVElPTl9WQUxJRElUWV9VTklUUy5ZRUFSU1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9ja0NvbmZpZ1Jlc3VsdC52YWxpZGl0eSA9IHJldGVudGlvblJlc3AuRGF5c1xuICAgICAgICBsb2NrQ29uZmlnUmVzdWx0LnVuaXQgPSBSRVRFTlRJT05fVkFMSURJVFlfVU5JVFMuREFZU1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBsb2NrQ29uZmlnUmVzdWx0XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJ1Y2tldFZlcnNpb25pbmdDb25maWcoeG1sOiBzdHJpbmcpIHtcbiAgY29uc3QgeG1sT2JqID0gcGFyc2VYbWwoeG1sKVxuICByZXR1cm4geG1sT2JqLlZlcnNpb25pbmdDb25maWd1cmF0aW9uXG59XG5cbi8vIFVzZWQgb25seSBpbiBzZWxlY3RPYmplY3RDb250ZW50IEFQSS5cbi8vIGV4dHJhY3RIZWFkZXJUeXBlIGV4dHJhY3RzIHRoZSBmaXJzdCBoYWxmIG9mIHRoZSBoZWFkZXIgbWVzc2FnZSwgdGhlIGhlYWRlciB0eXBlLlxuZnVuY3Rpb24gZXh0cmFjdEhlYWRlclR5cGUoc3RyZWFtOiBzdHJlYW0uUmVhZGFibGUpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBoZWFkZXJOYW1lTGVuID0gQnVmZmVyLmZyb20oc3RyZWFtLnJlYWQoMSkpLnJlYWRVSW50OCgpXG4gIGNvbnN0IGhlYWRlck5hbWVXaXRoU2VwYXJhdG9yID0gQnVmZmVyLmZyb20oc3RyZWFtLnJlYWQoaGVhZGVyTmFtZUxlbikpLnRvU3RyaW5nKClcbiAgY29uc3Qgc3BsaXRCeVNlcGFyYXRvciA9IChoZWFkZXJOYW1lV2l0aFNlcGFyYXRvciB8fCAnJykuc3BsaXQoJzonKVxuICByZXR1cm4gc3BsaXRCeVNlcGFyYXRvci5sZW5ndGggPj0gMSA/IHNwbGl0QnlTZXBhcmF0b3JbMV0gOiAnJ1xufVxuXG5mdW5jdGlvbiBleHRyYWN0SGVhZGVyVmFsdWUoc3RyZWFtOiBzdHJlYW0uUmVhZGFibGUpIHtcbiAgY29uc3QgYm9keUxlbiA9IEJ1ZmZlci5mcm9tKHN0cmVhbS5yZWFkKDIpKS5yZWFkVUludDE2QkUoKVxuICByZXR1cm4gQnVmZmVyLmZyb20oc3RyZWFtLnJlYWQoYm9keUxlbikpLnRvU3RyaW5nKClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU2VsZWN0T2JqZWN0Q29udGVudFJlc3BvbnNlKHJlczogQnVmZmVyKSB7XG4gIGNvbnN0IHNlbGVjdFJlc3VsdHMgPSBuZXcgU2VsZWN0UmVzdWx0cyh7fSkgLy8gd2lsbCBiZSByZXR1cm5lZFxuXG4gIGNvbnN0IHJlc3BvbnNlU3RyZWFtID0gcmVhZGFibGVTdHJlYW0ocmVzKSAvLyBjb252ZXJ0IGJ5dGUgYXJyYXkgdG8gYSByZWFkYWJsZSByZXNwb25zZVN0cmVhbVxuICAvLyBAdHMtaWdub3JlXG4gIHdoaWxlIChyZXNwb25zZVN0cmVhbS5fcmVhZGFibGVTdGF0ZS5sZW5ndGgpIHtcbiAgICAvLyBUb3AgbGV2ZWwgcmVzcG9uc2VTdHJlYW0gcmVhZCB0cmFja2VyLlxuICAgIGxldCBtc2dDcmNBY2N1bXVsYXRvciAvLyBhY2N1bXVsYXRlIGZyb20gc3RhcnQgb2YgdGhlIG1lc3NhZ2UgdGlsbCB0aGUgbWVzc2FnZSBjcmMgc3RhcnQuXG5cbiAgICBjb25zdCB0b3RhbEJ5dGVMZW5ndGhCdWZmZXIgPSBCdWZmZXIuZnJvbShyZXNwb25zZVN0cmVhbS5yZWFkKDQpKVxuICAgIG1zZ0NyY0FjY3VtdWxhdG9yID0gY3JjMzIodG90YWxCeXRlTGVuZ3RoQnVmZmVyKVxuXG4gICAgY29uc3QgaGVhZGVyQnl0ZXNCdWZmZXIgPSBCdWZmZXIuZnJvbShyZXNwb25zZVN0cmVhbS5yZWFkKDQpKVxuICAgIG1zZ0NyY0FjY3VtdWxhdG9yID0gY3JjMzIoaGVhZGVyQnl0ZXNCdWZmZXIsIG1zZ0NyY0FjY3VtdWxhdG9yKVxuXG4gICAgY29uc3QgY2FsY3VsYXRlZFByZWx1ZGVDcmMgPSBtc2dDcmNBY2N1bXVsYXRvci5yZWFkSW50MzJCRSgpIC8vIHVzZSBpdCB0byBjaGVjayBpZiBhbnkgQ1JDIG1pc21hdGNoIGluIGhlYWRlciBpdHNlbGYuXG5cbiAgICBjb25zdCBwcmVsdWRlQ3JjQnVmZmVyID0gQnVmZmVyLmZyb20ocmVzcG9uc2VTdHJlYW0ucmVhZCg0KSkgLy8gcmVhZCA0IGJ5dGVzICAgIGkuZSA0KzQgPTggKyA0ID0gMTIgKCBwcmVsdWRlICsgcHJlbHVkZSBjcmMpXG4gICAgbXNnQ3JjQWNjdW11bGF0b3IgPSBjcmMzMihwcmVsdWRlQ3JjQnVmZmVyLCBtc2dDcmNBY2N1bXVsYXRvcilcblxuICAgIGNvbnN0IHRvdGFsTXNnTGVuZ3RoID0gdG90YWxCeXRlTGVuZ3RoQnVmZmVyLnJlYWRJbnQzMkJFKClcbiAgICBjb25zdCBoZWFkZXJMZW5ndGggPSBoZWFkZXJCeXRlc0J1ZmZlci5yZWFkSW50MzJCRSgpXG4gICAgY29uc3QgcHJlbHVkZUNyY0J5dGVWYWx1ZSA9IHByZWx1ZGVDcmNCdWZmZXIucmVhZEludDMyQkUoKVxuXG4gICAgaWYgKHByZWx1ZGVDcmNCeXRlVmFsdWUgIT09IGNhbGN1bGF0ZWRQcmVsdWRlQ3JjKSB7XG4gICAgICAvLyBIYW5kbGUgSGVhZGVyIENSQyBtaXNtYXRjaCBFcnJvclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgSGVhZGVyIENoZWNrc3VtIE1pc21hdGNoLCBQcmVsdWRlIENSQyBvZiAke3ByZWx1ZGVDcmNCeXRlVmFsdWV9IGRvZXMgbm90IGVxdWFsIGV4cGVjdGVkIENSQyBvZiAke2NhbGN1bGF0ZWRQcmVsdWRlQ3JjfWAsXG4gICAgICApXG4gICAgfVxuXG4gICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fVxuICAgIGlmIChoZWFkZXJMZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBoZWFkZXJCeXRlcyA9IEJ1ZmZlci5mcm9tKHJlc3BvbnNlU3RyZWFtLnJlYWQoaGVhZGVyTGVuZ3RoKSlcbiAgICAgIG1zZ0NyY0FjY3VtdWxhdG9yID0gY3JjMzIoaGVhZGVyQnl0ZXMsIG1zZ0NyY0FjY3VtdWxhdG9yKVxuICAgICAgY29uc3QgaGVhZGVyUmVhZGVyU3RyZWFtID0gcmVhZGFibGVTdHJlYW0oaGVhZGVyQnl0ZXMpXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICB3aGlsZSAoaGVhZGVyUmVhZGVyU3RyZWFtLl9yZWFkYWJsZVN0YXRlLmxlbmd0aCkge1xuICAgICAgICBjb25zdCBoZWFkZXJUeXBlTmFtZSA9IGV4dHJhY3RIZWFkZXJUeXBlKGhlYWRlclJlYWRlclN0cmVhbSlcbiAgICAgICAgaGVhZGVyUmVhZGVyU3RyZWFtLnJlYWQoMSkgLy8ganVzdCByZWFkIGFuZCBpZ25vcmUgaXQuXG4gICAgICAgIGlmIChoZWFkZXJUeXBlTmFtZSkge1xuICAgICAgICAgIGhlYWRlcnNbaGVhZGVyVHlwZU5hbWVdID0gZXh0cmFjdEhlYWRlclZhbHVlKGhlYWRlclJlYWRlclN0cmVhbSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBwYXlsb2FkU3RyZWFtXG4gICAgY29uc3QgcGF5TG9hZExlbmd0aCA9IHRvdGFsTXNnTGVuZ3RoIC0gaGVhZGVyTGVuZ3RoIC0gMTZcbiAgICBpZiAocGF5TG9hZExlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHBheUxvYWRCdWZmZXIgPSBCdWZmZXIuZnJvbShyZXNwb25zZVN0cmVhbS5yZWFkKHBheUxvYWRMZW5ndGgpKVxuICAgICAgbXNnQ3JjQWNjdW11bGF0b3IgPSBjcmMzMihwYXlMb2FkQnVmZmVyLCBtc2dDcmNBY2N1bXVsYXRvcilcbiAgICAgIC8vIHJlYWQgdGhlIGNoZWNrc3VtIGVhcmx5IGFuZCBkZXRlY3QgYW55IG1pc21hdGNoIHNvIHdlIGNhbiBhdm9pZCB1bm5lY2Vzc2FyeSBmdXJ0aGVyIHByb2Nlc3NpbmcuXG4gICAgICBjb25zdCBtZXNzYWdlQ3JjQnl0ZVZhbHVlID0gQnVmZmVyLmZyb20ocmVzcG9uc2VTdHJlYW0ucmVhZCg0KSkucmVhZEludDMyQkUoKVxuICAgICAgY29uc3QgY2FsY3VsYXRlZENyYyA9IG1zZ0NyY0FjY3VtdWxhdG9yLnJlYWRJbnQzMkJFKClcbiAgICAgIC8vIEhhbmRsZSBtZXNzYWdlIENSQyBFcnJvclxuICAgICAgaWYgKG1lc3NhZ2VDcmNCeXRlVmFsdWUgIT09IGNhbGN1bGF0ZWRDcmMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBNZXNzYWdlIENoZWNrc3VtIE1pc21hdGNoLCBNZXNzYWdlIENSQyBvZiAke21lc3NhZ2VDcmNCeXRlVmFsdWV9IGRvZXMgbm90IGVxdWFsIGV4cGVjdGVkIENSQyBvZiAke2NhbGN1bGF0ZWRDcmN9YCxcbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgcGF5bG9hZFN0cmVhbSA9IHJlYWRhYmxlU3RyZWFtKHBheUxvYWRCdWZmZXIpXG4gICAgfVxuICAgIGNvbnN0IG1lc3NhZ2VUeXBlID0gaGVhZGVyc1snbWVzc2FnZS10eXBlJ11cblxuICAgIHN3aXRjaCAobWVzc2FnZVR5cGUpIHtcbiAgICAgIGNhc2UgJ2Vycm9yJzoge1xuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBoZWFkZXJzWydlcnJvci1jb2RlJ10gKyAnOlwiJyArIGhlYWRlcnNbJ2Vycm9yLW1lc3NhZ2UnXSArICdcIidcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTWVzc2FnZSlcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2V2ZW50Jzoge1xuICAgICAgICBjb25zdCBjb250ZW50VHlwZSA9IGhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddXG4gICAgICAgIGNvbnN0IGV2ZW50VHlwZSA9IGhlYWRlcnNbJ2V2ZW50LXR5cGUnXVxuXG4gICAgICAgIHN3aXRjaCAoZXZlbnRUeXBlKSB7XG4gICAgICAgICAgY2FzZSAnRW5kJzoge1xuICAgICAgICAgICAgc2VsZWN0UmVzdWx0cy5zZXRSZXNwb25zZShyZXMpXG4gICAgICAgICAgICByZXR1cm4gc2VsZWN0UmVzdWx0c1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNhc2UgJ1JlY29yZHMnOiB7XG4gICAgICAgICAgICBjb25zdCByZWFkRGF0YSA9IHBheWxvYWRTdHJlYW0/LnJlYWQocGF5TG9hZExlbmd0aClcbiAgICAgICAgICAgIHNlbGVjdFJlc3VsdHMuc2V0UmVjb3JkcyhyZWFkRGF0YSlcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSAnUHJvZ3Jlc3MnOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBzd2l0Y2ggKGNvbnRlbnRUeXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAndGV4dC94bWwnOiB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBwcm9ncmVzc0RhdGEgPSBwYXlsb2FkU3RyZWFtPy5yZWFkKHBheUxvYWRMZW5ndGgpXG4gICAgICAgICAgICAgICAgICBzZWxlY3RSZXN1bHRzLnNldFByb2dyZXNzKHByb2dyZXNzRGF0YS50b1N0cmluZygpKVxuICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gYFVuZXhwZWN0ZWQgY29udGVudC10eXBlICR7Y29udGVudFR5cGV9IHNlbnQgZm9yIGV2ZW50LXR5cGUgUHJvZ3Jlc3NgXG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICBjYXNlICdTdGF0cyc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHN3aXRjaCAoY29udGVudFR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICd0ZXh0L3htbCc6IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXRzRGF0YSA9IHBheWxvYWRTdHJlYW0/LnJlYWQocGF5TG9hZExlbmd0aClcbiAgICAgICAgICAgICAgICAgIHNlbGVjdFJlc3VsdHMuc2V0U3RhdHMoc3RhdHNEYXRhLnRvU3RyaW5nKCkpXG4gICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBgVW5leHBlY3RlZCBjb250ZW50LXR5cGUgJHtjb250ZW50VHlwZX0gc2VudCBmb3IgZXZlbnQtdHlwZSBTdGF0c2BcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1lc3NhZ2UpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgIC8vIENvbnRpbnVhdGlvbiBtZXNzYWdlOiBOb3Qgc3VyZSBpZiBpdCBpcyBzdXBwb3J0ZWQuIGRpZCBub3QgZmluZCBhIHJlZmVyZW5jZSBvciBhbnkgbWVzc2FnZSBpbiByZXNwb25zZS5cbiAgICAgICAgICAgIC8vIEl0IGRvZXMgbm90IGhhdmUgYSBwYXlsb2FkLlxuICAgICAgICAgICAgY29uc3Qgd2FybmluZ01lc3NhZ2UgPSBgVW4gaW1wbGVtZW50ZWQgZXZlbnQgZGV0ZWN0ZWQgICR7bWVzc2FnZVR5cGV9LmBcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLndhcm4od2FybmluZ01lc3NhZ2UpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxpZmVjeWNsZUNvbmZpZyh4bWw6IHN0cmluZykge1xuICBjb25zdCB4bWxPYmogPSBwYXJzZVhtbCh4bWwpXG4gIHJldHVybiB4bWxPYmouTGlmZWN5Y2xlQ29uZmlndXJhdGlvblxufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCdWNrZXRFbmNyeXB0aW9uQ29uZmlnKHhtbDogc3RyaW5nKSB7XG4gIHJldHVybiBwYXJzZVhtbCh4bWwpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU9iamVjdFJldGVudGlvbkNvbmZpZyh4bWw6IHN0cmluZykge1xuICBjb25zdCB4bWxPYmogPSBwYXJzZVhtbCh4bWwpXG4gIGNvbnN0IHJldGVudGlvbkNvbmZpZyA9IHhtbE9iai5SZXRlbnRpb25cbiAgcmV0dXJuIHtcbiAgICBtb2RlOiByZXRlbnRpb25Db25maWcuTW9kZSxcbiAgICByZXRhaW5VbnRpbERhdGU6IHJldGVudGlvbkNvbmZpZy5SZXRhaW5VbnRpbERhdGUsXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZU9iamVjdHNQYXJzZXIoeG1sOiBzdHJpbmcpIHtcbiAgY29uc3QgeG1sT2JqID0gcGFyc2VYbWwoeG1sKVxuICBpZiAoeG1sT2JqLkRlbGV0ZVJlc3VsdCAmJiB4bWxPYmouRGVsZXRlUmVzdWx0LkVycm9yKSB7XG4gICAgLy8gcmV0dXJuIGVycm9ycyBhcyBhcnJheSBhbHdheXMuIGFzIHRoZSByZXNwb25zZSBpcyBvYmplY3QgaW4gY2FzZSBvZiBzaW5nbGUgb2JqZWN0IHBhc3NlZCBpbiByZW1vdmVPYmplY3RzXG4gICAgcmV0dXJuIHRvQXJyYXkoeG1sT2JqLkRlbGV0ZVJlc3VsdC5FcnJvcilcbiAgfVxuICByZXR1cm4gW11cbn1cblxuLy8gcGFyc2UgWE1MIHJlc3BvbnNlIGZvciBjb3B5IG9iamVjdFxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQ29weU9iamVjdCh4bWw6IHN0cmluZyk6IENvcHlPYmplY3RSZXN1bHRWMSB7XG4gIGNvbnN0IHJlc3VsdDogQ29weU9iamVjdFJlc3VsdFYxID0ge1xuICAgIGV0YWc6ICcnLFxuICAgIGxhc3RNb2RpZmllZDogJycsXG4gIH1cblxuICBsZXQgeG1sb2JqID0gcGFyc2VYbWwoeG1sKVxuICBpZiAoIXhtbG9iai5Db3B5T2JqZWN0UmVzdWx0KSB7XG4gICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkWE1MRXJyb3IoJ01pc3NpbmcgdGFnOiBcIkNvcHlPYmplY3RSZXN1bHRcIicpXG4gIH1cbiAgeG1sb2JqID0geG1sb2JqLkNvcHlPYmplY3RSZXN1bHRcbiAgaWYgKHhtbG9iai5FVGFnKSB7XG4gICAgcmVzdWx0LmV0YWcgPSB4bWxvYmouRVRhZy5yZXBsYWNlKC9eXCIvZywgJycpXG4gICAgICAucmVwbGFjZSgvXCIkL2csICcnKVxuICAgICAgLnJlcGxhY2UoL14mcXVvdDsvZywgJycpXG4gICAgICAucmVwbGFjZSgvJnF1b3Q7JC9nLCAnJylcbiAgICAgIC5yZXBsYWNlKC9eJiMzNDsvZywgJycpXG4gICAgICAucmVwbGFjZSgvJiMzNDskL2csICcnKVxuICB9XG4gIGlmICh4bWxvYmouTGFzdE1vZGlmaWVkKSB7XG4gICAgcmVzdWx0Lmxhc3RNb2RpZmllZCA9IG5ldyBEYXRlKHhtbG9iai5MYXN0TW9kaWZpZWQpXG4gIH1cblxuICByZXR1cm4gcmVzdWx0XG59XG5cbmNvbnN0IGZvcm1hdE9iakluZm8gPSAoY29udGVudDogT2JqZWN0Um93RW50cnksIG9wdHM6IHsgSXNEZWxldGVNYXJrZXI/OiBib29sZWFuIH0gPSB7fSkgPT4ge1xuICBjb25zdCB7IEtleSwgTGFzdE1vZGlmaWVkLCBFVGFnLCBTaXplLCBWZXJzaW9uSWQsIElzTGF0ZXN0IH0gPSBjb250ZW50XG5cbiAgaWYgKCFpc09iamVjdChvcHRzKSkge1xuICAgIG9wdHMgPSB7fVxuICB9XG5cbiAgY29uc3QgbmFtZSA9IHNhbml0aXplT2JqZWN0S2V5KHRvQXJyYXkoS2V5KVswXSB8fCAnJylcbiAgY29uc3QgbGFzdE1vZGlmaWVkID0gTGFzdE1vZGlmaWVkID8gbmV3IERhdGUodG9BcnJheShMYXN0TW9kaWZpZWQpWzBdIHx8ICcnKSA6IHVuZGVmaW5lZFxuICBjb25zdCBldGFnID0gc2FuaXRpemVFVGFnKHRvQXJyYXkoRVRhZylbMF0gfHwgJycpXG4gIGNvbnN0IHNpemUgPSBzYW5pdGl6ZVNpemUoU2l6ZSB8fCAnJylcblxuICByZXR1cm4ge1xuICAgIG5hbWUsXG4gICAgbGFzdE1vZGlmaWVkLFxuICAgIGV0YWcsXG4gICAgc2l6ZSxcbiAgICB2ZXJzaW9uSWQ6IFZlcnNpb25JZCxcbiAgICBpc0xhdGVzdDogSXNMYXRlc3QsXG4gICAgaXNEZWxldGVNYXJrZXI6IG9wdHMuSXNEZWxldGVNYXJrZXIgPyBvcHRzLklzRGVsZXRlTWFya2VyIDogZmFsc2UsXG4gIH1cbn1cblxuLy8gcGFyc2UgWE1MIHJlc3BvbnNlIGZvciBsaXN0IG9iamVjdHMgaW4gYSBidWNrZXRcbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxpc3RPYmplY3RzKHhtbDogc3RyaW5nKSB7XG4gIGNvbnN0IHJlc3VsdDoge1xuICAgIG9iamVjdHM6IE9iamVjdEluZm9bXVxuICAgIGlzVHJ1bmNhdGVkPzogYm9vbGVhblxuICAgIG5leHRNYXJrZXI/OiBzdHJpbmdcbiAgICB2ZXJzaW9uSWRNYXJrZXI/OiBzdHJpbmdcbiAgICBrZXlNYXJrZXI/OiBzdHJpbmdcbiAgfSA9IHtcbiAgICBvYmplY3RzOiBbXSxcbiAgICBpc1RydW5jYXRlZDogZmFsc2UsXG4gICAgbmV4dE1hcmtlcjogdW5kZWZpbmVkLFxuICAgIHZlcnNpb25JZE1hcmtlcjogdW5kZWZpbmVkLFxuICAgIGtleU1hcmtlcjogdW5kZWZpbmVkLFxuICB9XG4gIGxldCBpc1RydW5jYXRlZCA9IGZhbHNlXG4gIGxldCBuZXh0TWFya2VyXG4gIGNvbnN0IHhtbG9iaiA9IGZ4cFdpdGhvdXROdW1QYXJzZXIucGFyc2UoeG1sKVxuXG4gIGNvbnN0IHBhcnNlQ29tbW9uUHJlZml4ZXNFbnRpdHkgPSAoY29tbW9uUHJlZml4RW50cnk6IENvbW1vblByZWZpeFtdKSA9PiB7XG4gICAgaWYgKGNvbW1vblByZWZpeEVudHJ5KSB7XG4gICAgICB0b0FycmF5KGNvbW1vblByZWZpeEVudHJ5KS5mb3JFYWNoKChjb21tb25QcmVmaXgpID0+IHtcbiAgICAgICAgcmVzdWx0Lm9iamVjdHMucHVzaCh7IHByZWZpeDogc2FuaXRpemVPYmplY3RLZXkodG9BcnJheShjb21tb25QcmVmaXguUHJlZml4KVswXSB8fCAnJyksIHNpemU6IDAgfSlcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgY29uc3QgbGlzdEJ1Y2tldFJlc3VsdDogTGlzdEJ1Y2tldFJlc3VsdFYxID0geG1sb2JqLkxpc3RCdWNrZXRSZXN1bHRcbiAgY29uc3QgbGlzdFZlcnNpb25zUmVzdWx0OiBMaXN0QnVja2V0UmVzdWx0VjEgPSB4bWxvYmouTGlzdFZlcnNpb25zUmVzdWx0XG5cbiAgaWYgKGxpc3RCdWNrZXRSZXN1bHQpIHtcbiAgICBpZiAobGlzdEJ1Y2tldFJlc3VsdC5Jc1RydW5jYXRlZCkge1xuICAgICAgaXNUcnVuY2F0ZWQgPSBsaXN0QnVja2V0UmVzdWx0LklzVHJ1bmNhdGVkXG4gICAgfVxuICAgIGlmIChsaXN0QnVja2V0UmVzdWx0LkNvbnRlbnRzKSB7XG4gICAgICB0b0FycmF5KGxpc3RCdWNrZXRSZXN1bHQuQ29udGVudHMpLmZvckVhY2goKGNvbnRlbnQpID0+IHtcbiAgICAgICAgY29uc3QgbmFtZSA9IHNhbml0aXplT2JqZWN0S2V5KHRvQXJyYXkoY29udGVudC5LZXkpWzBdIHx8ICcnKVxuICAgICAgICBjb25zdCBsYXN0TW9kaWZpZWQgPSBuZXcgRGF0ZSh0b0FycmF5KGNvbnRlbnQuTGFzdE1vZGlmaWVkKVswXSB8fCAnJylcbiAgICAgICAgY29uc3QgZXRhZyA9IHNhbml0aXplRVRhZyh0b0FycmF5KGNvbnRlbnQuRVRhZylbMF0gfHwgJycpXG4gICAgICAgIGNvbnN0IHNpemUgPSBzYW5pdGl6ZVNpemUoY29udGVudC5TaXplIHx8ICcnKVxuICAgICAgICByZXN1bHQub2JqZWN0cy5wdXNoKHsgbmFtZSwgbGFzdE1vZGlmaWVkLCBldGFnLCBzaXplIH0pXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChsaXN0QnVja2V0UmVzdWx0Lk1hcmtlcikge1xuICAgICAgbmV4dE1hcmtlciA9IGxpc3RCdWNrZXRSZXN1bHQuTWFya2VyXG4gICAgfVxuICAgIGlmIChsaXN0QnVja2V0UmVzdWx0Lk5leHRNYXJrZXIpIHtcbiAgICAgIG5leHRNYXJrZXIgPSBsaXN0QnVja2V0UmVzdWx0Lk5leHRNYXJrZXJcbiAgICB9IGVsc2UgaWYgKGlzVHJ1bmNhdGVkICYmIHJlc3VsdC5vYmplY3RzLmxlbmd0aCA+IDApIHtcbiAgICAgIG5leHRNYXJrZXIgPSByZXN1bHQub2JqZWN0c1tyZXN1bHQub2JqZWN0cy5sZW5ndGggLSAxXT8ubmFtZVxuICAgIH1cbiAgICBpZiAobGlzdEJ1Y2tldFJlc3VsdC5Db21tb25QcmVmaXhlcykge1xuICAgICAgcGFyc2VDb21tb25QcmVmaXhlc0VudGl0eShsaXN0QnVja2V0UmVzdWx0LkNvbW1vblByZWZpeGVzKVxuICAgIH1cbiAgfVxuXG4gIGlmIChsaXN0VmVyc2lvbnNSZXN1bHQpIHtcbiAgICBpZiAobGlzdFZlcnNpb25zUmVzdWx0LklzVHJ1bmNhdGVkKSB7XG4gICAgICBpc1RydW5jYXRlZCA9IGxpc3RWZXJzaW9uc1Jlc3VsdC5Jc1RydW5jYXRlZFxuICAgIH1cblxuICAgIGlmIChsaXN0VmVyc2lvbnNSZXN1bHQuVmVyc2lvbikge1xuICAgICAgdG9BcnJheShsaXN0VmVyc2lvbnNSZXN1bHQuVmVyc2lvbikuZm9yRWFjaCgoY29udGVudCkgPT4ge1xuICAgICAgICByZXN1bHQub2JqZWN0cy5wdXNoKGZvcm1hdE9iakluZm8oY29udGVudCkpXG4gICAgICB9KVxuICAgIH1cbiAgICBpZiAobGlzdFZlcnNpb25zUmVzdWx0LkRlbGV0ZU1hcmtlcikge1xuICAgICAgdG9BcnJheShsaXN0VmVyc2lvbnNSZXN1bHQuRGVsZXRlTWFya2VyKS5mb3JFYWNoKChjb250ZW50KSA9PiB7XG4gICAgICAgIHJlc3VsdC5vYmplY3RzLnB1c2goZm9ybWF0T2JqSW5mbyhjb250ZW50LCB7IElzRGVsZXRlTWFya2VyOiB0cnVlIH0pKVxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAobGlzdFZlcnNpb25zUmVzdWx0Lk5leHRLZXlNYXJrZXIpIHtcbiAgICAgIHJlc3VsdC5rZXlNYXJrZXIgPSBsaXN0VmVyc2lvbnNSZXN1bHQuTmV4dEtleU1hcmtlclxuICAgIH1cbiAgICBpZiAobGlzdFZlcnNpb25zUmVzdWx0Lk5leHRWZXJzaW9uSWRNYXJrZXIpIHtcbiAgICAgIHJlc3VsdC52ZXJzaW9uSWRNYXJrZXIgPSBsaXN0VmVyc2lvbnNSZXN1bHQuTmV4dFZlcnNpb25JZE1hcmtlclxuICAgIH1cbiAgICBpZiAobGlzdFZlcnNpb25zUmVzdWx0LkNvbW1vblByZWZpeGVzKSB7XG4gICAgICBwYXJzZUNvbW1vblByZWZpeGVzRW50aXR5KGxpc3RWZXJzaW9uc1Jlc3VsdC5Db21tb25QcmVmaXhlcylcbiAgICB9XG4gIH1cblxuICByZXN1bHQuaXNUcnVuY2F0ZWQgPSBpc1RydW5jYXRlZFxuICBpZiAoaXNUcnVuY2F0ZWQpIHtcbiAgICByZXN1bHQubmV4dE1hcmtlciA9IG5leHRNYXJrZXJcbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGxvYWRQYXJ0UGFyc2VyKHhtbDogc3RyaW5nKSB7XG4gIGNvbnN0IHhtbE9iaiA9IHBhcnNlWG1sKHhtbClcbiAgY29uc3QgcmVzcEVsID0geG1sT2JqLkNvcHlQYXJ0UmVzdWx0XG4gIHJldHVybiByZXNwRWxcbn1cbiJdLCJtYXBwaW5ncyI6IkFBR0EsT0FBT0EsS0FBSyxNQUFNLGNBQWM7QUFDaEMsU0FBU0MsU0FBUyxRQUFRLGlCQUFpQjtBQUUzQyxPQUFPLEtBQUtDLE1BQU0sTUFBTSxlQUFjO0FBQ3RDLFNBQVNDLGFBQWEsUUFBUSxnQkFBZTtBQUM3QyxTQUFTQyxRQUFRLEVBQUVDLFFBQVEsRUFBRUMsY0FBYyxFQUFFQyxZQUFZLEVBQUVDLGlCQUFpQixFQUFFQyxZQUFZLEVBQUVDLE9BQU8s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