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