@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,608 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.calculateEvenSplits = calculateEvenSplits;
7
+ exports.extractMetadata = extractMetadata;
8
+ exports.getContentLength = getContentLength;
9
+ exports.getEncryptionHeaders = getEncryptionHeaders;
10
+ exports.getScope = getScope;
11
+ exports.getSourceVersionId = getSourceVersionId;
12
+ exports.getVersionId = getVersionId;
13
+ exports.hashBinary = hashBinary;
14
+ exports.insertContentType = insertContentType;
15
+ exports.isAmazonEndpoint = isAmazonEndpoint;
16
+ exports.isAmzHeader = isAmzHeader;
17
+ exports.isBoolean = isBoolean;
18
+ exports.isDefined = isDefined;
19
+ exports.isEmpty = isEmpty;
20
+ exports.isEmptyObject = isEmptyObject;
21
+ exports.isFunction = isFunction;
22
+ exports.isNumber = isNumber;
23
+ exports.isObject = isObject;
24
+ exports.isPlainObject = isPlainObject;
25
+ exports.isReadableStream = isReadableStream;
26
+ exports.isStorageClassHeader = isStorageClassHeader;
27
+ exports.isString = isString;
28
+ exports.isSupportedHeader = isSupportedHeader;
29
+ exports.isValidBucketName = isValidBucketName;
30
+ exports.isValidDate = isValidDate;
31
+ exports.isValidDomain = isValidDomain;
32
+ exports.isValidEndpoint = isValidEndpoint;
33
+ exports.isValidIP = isValidIP;
34
+ exports.isValidObjectName = isValidObjectName;
35
+ exports.isValidPort = isValidPort;
36
+ exports.isValidPrefix = isValidPrefix;
37
+ exports.isVirtualHostStyle = isVirtualHostStyle;
38
+ exports.makeDateLong = makeDateLong;
39
+ exports.makeDateShort = makeDateShort;
40
+ exports.parseXml = parseXml;
41
+ exports.partsRequired = partsRequired;
42
+ exports.pipesetup = pipesetup;
43
+ exports.prependXAMZMeta = prependXAMZMeta;
44
+ exports.probeContentType = probeContentType;
45
+ exports.readableStream = readableStream;
46
+ exports.sanitizeETag = sanitizeETag;
47
+ exports.sanitizeObjectKey = sanitizeObjectKey;
48
+ exports.sanitizeSize = sanitizeSize;
49
+ exports.toArray = toArray;
50
+ exports.toMd5 = toMd5;
51
+ exports.toSha256 = toSha256;
52
+ exports.uriEscape = uriEscape;
53
+ exports.uriResourceEscape = uriResourceEscape;
54
+ var crypto = _interopRequireWildcard(require("crypto"), true);
55
+ var stream = _interopRequireWildcard(require("stream"), true);
56
+ var _fastXmlParser = require("fast-xml-parser");
57
+ var _ipaddr = require("ipaddr.js");
58
+ var _lodash = require("lodash");
59
+ var mime = _interopRequireWildcard(require("mime-types"), true);
60
+ var _async = require("./async.js");
61
+ var _type = require("./type.js");
62
+ 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); }
63
+ 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; }
64
+ /*
65
+ * Hanzo S3 Javascript Library for Amazon S3 Compatible Cloud Storage, (C) 2015 Hanzo AI, Inc.
66
+ *
67
+ * Licensed under the Apache License, Version 2.0 (the "License");
68
+ * you may not use this file except in compliance with the License.
69
+ * You may obtain a copy of the License at
70
+ *
71
+ * http://www.apache.org/licenses/LICENSE-2.0
72
+ *
73
+ * Unless required by applicable law or agreed to in writing, software
74
+ * distributed under the License is distributed on an "AS IS" BASIS,
75
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76
+ * See the License for the specific language governing permissions and
77
+ * limitations under the License.
78
+ */
79
+
80
+ const MetaDataHeaderPrefix = 'x-amz-meta-';
81
+ function hashBinary(buf, enableSHA256) {
82
+ let sha256sum = '';
83
+ if (enableSHA256) {
84
+ sha256sum = crypto.createHash('sha256').update(buf).digest('hex');
85
+ }
86
+ const md5sum = crypto.createHash('md5').update(buf).digest('base64');
87
+ return {
88
+ md5sum,
89
+ sha256sum
90
+ };
91
+ }
92
+
93
+ // S3 percent-encodes some extra non-standard characters in a URI . So comply with S3.
94
+ const encodeAsHex = c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`;
95
+ function uriEscape(uriStr) {
96
+ return encodeURIComponent(uriStr).replace(/[!'()*]/g, encodeAsHex);
97
+ }
98
+ function uriResourceEscape(string) {
99
+ return uriEscape(string).replace(/%2F/g, '/');
100
+ }
101
+ function getScope(region, date, serviceName = 's3') {
102
+ return `${makeDateShort(date)}/${region}/${serviceName}/aws4_request`;
103
+ }
104
+
105
+ /**
106
+ * isAmazonEndpoint - true if endpoint is 's3.amazonaws.com' or 's3.cn-north-1.amazonaws.com.cn'
107
+ */
108
+ function isAmazonEndpoint(endpoint) {
109
+ return endpoint === 's3.amazonaws.com' || endpoint === 's3.cn-north-1.amazonaws.com.cn';
110
+ }
111
+
112
+ /**
113
+ * isVirtualHostStyle - verify if bucket name is support with virtual
114
+ * hosts. bucketNames with periods should be always treated as path
115
+ * style if the protocol is 'https:', this is due to SSL wildcard
116
+ * limitation. For all other buckets and Amazon S3 endpoint we will
117
+ * default to virtual host style.
118
+ */
119
+ function isVirtualHostStyle(endpoint, protocol, bucket, pathStyle) {
120
+ if (protocol === 'https:' && bucket.includes('.')) {
121
+ return false;
122
+ }
123
+ return isAmazonEndpoint(endpoint) || !pathStyle;
124
+ }
125
+ function isValidIP(ip) {
126
+ return _ipaddr.isValid(ip);
127
+ }
128
+
129
+ /**
130
+ * @returns if endpoint is valid domain.
131
+ */
132
+ function isValidEndpoint(endpoint) {
133
+ return isValidDomain(endpoint) || isValidIP(endpoint);
134
+ }
135
+
136
+ /**
137
+ * @returns if input host is a valid domain.
138
+ */
139
+ function isValidDomain(host) {
140
+ if (!isString(host)) {
141
+ return false;
142
+ }
143
+ // See RFC 1035, RFC 3696.
144
+ if (host.length === 0 || host.length > 255) {
145
+ return false;
146
+ }
147
+ // Host cannot start or end with a '-'
148
+ if (host[0] === '-' || host.slice(-1) === '-') {
149
+ return false;
150
+ }
151
+ // Host cannot start or end with a '_'
152
+ if (host[0] === '_' || host.slice(-1) === '_') {
153
+ return false;
154
+ }
155
+ // Host cannot start with a '.'
156
+ if (host[0] === '.') {
157
+ return false;
158
+ }
159
+ const nonAlphaNumerics = '`~!@#$%^&*()+={}[]|\\"\';:><?/';
160
+ // All non alphanumeric characters are invalid.
161
+ for (const char of nonAlphaNumerics) {
162
+ if (host.includes(char)) {
163
+ return false;
164
+ }
165
+ }
166
+ // No need to regexp match, since the list is non-exhaustive.
167
+ // We let it be valid and fail later.
168
+ return true;
169
+ }
170
+
171
+ /**
172
+ * Probes contentType using file extensions.
173
+ *
174
+ * @example
175
+ * ```
176
+ * // return 'image/png'
177
+ * probeContentType('file.png')
178
+ * ```
179
+ */
180
+ function probeContentType(path) {
181
+ let contentType = mime.lookup(path);
182
+ if (!contentType) {
183
+ contentType = 'application/octet-stream';
184
+ }
185
+ return contentType;
186
+ }
187
+
188
+ /**
189
+ * is input port valid.
190
+ */
191
+ function isValidPort(port) {
192
+ // Convert string port to number if needed
193
+ const portNum = typeof port === 'string' ? parseInt(port, 10) : port;
194
+
195
+ // verify if port is a valid number
196
+ if (!isNumber(portNum) || isNaN(portNum)) {
197
+ return false;
198
+ }
199
+
200
+ // port `0` is valid and special case
201
+ return 0 <= portNum && portNum <= 65535;
202
+ }
203
+ function isValidBucketName(bucket) {
204
+ if (!isString(bucket)) {
205
+ return false;
206
+ }
207
+
208
+ // bucket length should be less than and no more than 63
209
+ // characters long.
210
+ if (bucket.length < 3 || bucket.length > 63) {
211
+ return false;
212
+ }
213
+ // bucket with successive periods is invalid.
214
+ if (bucket.includes('..')) {
215
+ return false;
216
+ }
217
+ // bucket cannot have ip address style.
218
+ if (/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/.test(bucket)) {
219
+ return false;
220
+ }
221
+ // bucket should begin with alphabet/number and end with alphabet/number,
222
+ // with alphabet/number/.- in the middle.
223
+ if (/^[a-z0-9][a-z0-9.-]+[a-z0-9]$/.test(bucket)) {
224
+ return true;
225
+ }
226
+ return false;
227
+ }
228
+
229
+ /**
230
+ * check if objectName is a valid object name
231
+ */
232
+ function isValidObjectName(objectName) {
233
+ if (!isValidPrefix(objectName)) {
234
+ return false;
235
+ }
236
+ return objectName.length !== 0;
237
+ }
238
+
239
+ /**
240
+ * check if prefix is valid
241
+ */
242
+ function isValidPrefix(prefix) {
243
+ if (!isString(prefix)) {
244
+ return false;
245
+ }
246
+ if (prefix.length > 1024) {
247
+ return false;
248
+ }
249
+ return true;
250
+ }
251
+
252
+ /**
253
+ * check if typeof arg number
254
+ */
255
+ function isNumber(arg) {
256
+ return typeof arg === 'number';
257
+ }
258
+
259
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
260
+
261
+ /**
262
+ * check if typeof arg function
263
+ */
264
+ function isFunction(arg) {
265
+ return typeof arg === 'function';
266
+ }
267
+
268
+ /**
269
+ * check if typeof arg string
270
+ */
271
+ function isString(arg) {
272
+ return typeof arg === 'string';
273
+ }
274
+
275
+ /**
276
+ * check if typeof arg object
277
+ */
278
+ function isObject(arg) {
279
+ return typeof arg === 'object' && arg !== null;
280
+ }
281
+ /**
282
+ * check if typeof arg is plain object
283
+ */
284
+ function isPlainObject(arg) {
285
+ return Object.prototype.toString.call(arg) === '[object Object]';
286
+ }
287
+ /**
288
+ * check if object is readable stream
289
+ */
290
+ function isReadableStream(arg) {
291
+ // eslint-disable-next-line @typescript-eslint/unbound-method
292
+ return isObject(arg) && isFunction(arg._read);
293
+ }
294
+
295
+ /**
296
+ * check if arg is boolean
297
+ */
298
+ function isBoolean(arg) {
299
+ return typeof arg === 'boolean';
300
+ }
301
+ function isEmpty(o) {
302
+ return _lodash.isEmpty(o);
303
+ }
304
+ function isEmptyObject(o) {
305
+ return Object.values(o).filter(x => x !== undefined).length !== 0;
306
+ }
307
+ function isDefined(o) {
308
+ return o !== null && o !== undefined;
309
+ }
310
+
311
+ /**
312
+ * check if arg is a valid date
313
+ */
314
+ function isValidDate(arg) {
315
+ // @ts-expect-error checknew Date(Math.NaN)
316
+ return arg instanceof Date && !isNaN(arg);
317
+ }
318
+
319
+ /**
320
+ * Create a Date string with format: 'YYYYMMDDTHHmmss' + Z
321
+ */
322
+ function makeDateLong(date) {
323
+ date = date || new Date();
324
+
325
+ // Gives format like: '2017-08-07T16:28:59.889Z'
326
+ const s = date.toISOString();
327
+ return s.slice(0, 4) + s.slice(5, 7) + s.slice(8, 13) + s.slice(14, 16) + s.slice(17, 19) + 'Z';
328
+ }
329
+
330
+ /**
331
+ * Create a Date string with format: 'YYYYMMDD'
332
+ */
333
+ function makeDateShort(date) {
334
+ date = date || new Date();
335
+
336
+ // Gives format like: '2017-08-07T16:28:59.889Z'
337
+ const s = date.toISOString();
338
+ return s.slice(0, 4) + s.slice(5, 7) + s.slice(8, 10);
339
+ }
340
+
341
+ /**
342
+ * pipesetup sets up pipe() from left to right os streams array
343
+ * pipesetup will also make sure that error emitted at any of the upstream Stream
344
+ * will be emitted at the last stream. This makes error handling simple
345
+ */
346
+ function pipesetup(...streams) {
347
+ // @ts-expect-error ts can't narrow this
348
+ return streams.reduce((src, dst) => {
349
+ src.on('error', err => dst.emit('error', err));
350
+ return src.pipe(dst);
351
+ });
352
+ }
353
+
354
+ /**
355
+ * return a Readable stream that emits data
356
+ */
357
+ function readableStream(data) {
358
+ const s = new stream.Readable();
359
+ s._read = () => {};
360
+ s.push(data);
361
+ s.push(null);
362
+ return s;
363
+ }
364
+
365
+ /**
366
+ * Process metadata to insert appropriate value to `content-type` attribute
367
+ */
368
+ function insertContentType(metaData, filePath) {
369
+ // check if content-type attribute present in metaData
370
+ for (const key in metaData) {
371
+ if (key.toLowerCase() === 'content-type') {
372
+ return metaData;
373
+ }
374
+ }
375
+
376
+ // if `content-type` attribute is not present in metadata, then infer it from the extension in filePath
377
+ return {
378
+ ...metaData,
379
+ 'content-type': probeContentType(filePath)
380
+ };
381
+ }
382
+
383
+ /**
384
+ * Function prepends metadata with the appropriate prefix if it is not already on
385
+ */
386
+ function prependXAMZMeta(metaData) {
387
+ if (!metaData) {
388
+ return {};
389
+ }
390
+ return _lodash.mapKeys(metaData, (value, key) => {
391
+ if (isAmzHeader(key) || isSupportedHeader(key) || isStorageClassHeader(key)) {
392
+ return key;
393
+ }
394
+ return MetaDataHeaderPrefix + key;
395
+ });
396
+ }
397
+
398
+ /**
399
+ * Checks if it is a valid header according to the AmazonS3 API
400
+ */
401
+ function isAmzHeader(key) {
402
+ const temp = key.toLowerCase();
403
+ return temp.startsWith(MetaDataHeaderPrefix) || temp === 'x-amz-acl' || temp.startsWith('x-amz-server-side-encryption-') || temp === 'x-amz-server-side-encryption';
404
+ }
405
+
406
+ /**
407
+ * Checks if it is a supported Header
408
+ */
409
+ function isSupportedHeader(key) {
410
+ const supported_headers = ['content-type', 'cache-control', 'content-encoding', 'content-disposition', 'content-language', 'x-amz-website-redirect-location', 'if-none-match', 'if-match'];
411
+ return supported_headers.includes(key.toLowerCase());
412
+ }
413
+
414
+ /**
415
+ * Checks if it is a storage header
416
+ */
417
+ function isStorageClassHeader(key) {
418
+ return key.toLowerCase() === 'x-amz-storage-class';
419
+ }
420
+ function extractMetadata(headers) {
421
+ return _lodash.mapKeys(_lodash.pickBy(headers, (value, key) => isSupportedHeader(key) || isStorageClassHeader(key) || isAmzHeader(key)), (value, key) => {
422
+ const lower = key.toLowerCase();
423
+ if (lower.startsWith(MetaDataHeaderPrefix)) {
424
+ return lower.slice(MetaDataHeaderPrefix.length);
425
+ }
426
+ return key;
427
+ });
428
+ }
429
+ function getVersionId(headers = {}) {
430
+ return headers['x-amz-version-id'] || null;
431
+ }
432
+ function getSourceVersionId(headers = {}) {
433
+ return headers['x-amz-copy-source-version-id'] || null;
434
+ }
435
+ function sanitizeETag(etag = '') {
436
+ const replaceChars = {
437
+ '"': '',
438
+ '&quot;': '',
439
+ '&#34;': '',
440
+ '&QUOT;': '',
441
+ '&#x00022': ''
442
+ };
443
+ return etag.replace(/^("|&quot;|&#34;)|("|&quot;|&#34;)$/g, m => replaceChars[m]);
444
+ }
445
+ function toMd5(payload) {
446
+ // use string from browser and buffer from nodejs
447
+ // browser support is tested only against Hanzo S3 server
448
+ return crypto.createHash('md5').update(Buffer.from(payload)).digest().toString('base64');
449
+ }
450
+ function toSha256(payload) {
451
+ return crypto.createHash('sha256').update(payload).digest('hex');
452
+ }
453
+
454
+ /**
455
+ * toArray returns a single element array with param being the element,
456
+ * if param is just a string, and returns 'param' back if it is an array
457
+ * So, it makes sure param is always an array
458
+ */
459
+ function toArray(param) {
460
+ if (!Array.isArray(param)) {
461
+ return [param];
462
+ }
463
+ return param;
464
+ }
465
+ function sanitizeObjectKey(objectName) {
466
+ // + symbol characters are not decoded as spaces in JS. so replace them first and decode to get the correct result.
467
+ const asStrName = (objectName ? objectName.toString() : '').replace(/\+/g, ' ');
468
+ return decodeURIComponent(asStrName);
469
+ }
470
+ function sanitizeSize(size) {
471
+ return size ? Number.parseInt(size) : undefined;
472
+ }
473
+ const PART_CONSTRAINTS = {
474
+ // absMinPartSize - absolute minimum part size (5 MiB)
475
+ ABS_MIN_PART_SIZE: 1024 * 1024 * 5,
476
+ // MIN_PART_SIZE - minimum part size 16MiB per object after which
477
+ MIN_PART_SIZE: 1024 * 1024 * 16,
478
+ // MAX_PARTS_COUNT - maximum number of parts for a single multipart session.
479
+ MAX_PARTS_COUNT: 10000,
480
+ // MAX_PART_SIZE - maximum part size 5GiB for a single multipart upload
481
+ // operation.
482
+ MAX_PART_SIZE: 1024 * 1024 * 1024 * 5,
483
+ // MAX_SINGLE_PUT_OBJECT_SIZE - maximum size 5GiB of object per PUT
484
+ // operation.
485
+ MAX_SINGLE_PUT_OBJECT_SIZE: 1024 * 1024 * 1024 * 5,
486
+ // MAX_MULTIPART_PUT_OBJECT_SIZE - maximum size 5TiB of object for
487
+ // Multipart operation.
488
+ MAX_MULTIPART_PUT_OBJECT_SIZE: 1024 * 1024 * 1024 * 1024 * 5
489
+ };
490
+ exports.PART_CONSTRAINTS = PART_CONSTRAINTS;
491
+ const GENERIC_SSE_HEADER = 'X-Amz-Server-Side-Encryption';
492
+ const ENCRYPTION_HEADERS = {
493
+ // sseGenericHeader is the AWS SSE header used for SSE-S3 and SSE-KMS.
494
+ sseGenericHeader: GENERIC_SSE_HEADER,
495
+ // sseKmsKeyID is the AWS SSE-KMS key id.
496
+ sseKmsKeyID: GENERIC_SSE_HEADER + '-Aws-Kms-Key-Id'
497
+ };
498
+
499
+ /**
500
+ * Return Encryption headers
501
+ * @param encConfig
502
+ * @returns an object with key value pairs that can be used in headers.
503
+ */
504
+ function getEncryptionHeaders(encConfig) {
505
+ const encType = encConfig.type;
506
+ if (!isEmpty(encType)) {
507
+ if (encType === _type.ENCRYPTION_TYPES.SSEC) {
508
+ return {
509
+ [ENCRYPTION_HEADERS.sseGenericHeader]: 'AES256'
510
+ };
511
+ } else if (encType === _type.ENCRYPTION_TYPES.KMS) {
512
+ return {
513
+ [ENCRYPTION_HEADERS.sseGenericHeader]: encConfig.SSEAlgorithm,
514
+ [ENCRYPTION_HEADERS.sseKmsKeyID]: encConfig.KMSMasterKeyID
515
+ };
516
+ }
517
+ }
518
+ return {};
519
+ }
520
+ function partsRequired(size) {
521
+ const maxPartSize = PART_CONSTRAINTS.MAX_MULTIPART_PUT_OBJECT_SIZE / (PART_CONSTRAINTS.MAX_PARTS_COUNT - 1);
522
+ let requiredPartSize = size / maxPartSize;
523
+ if (size % maxPartSize > 0) {
524
+ requiredPartSize++;
525
+ }
526
+ requiredPartSize = Math.trunc(requiredPartSize);
527
+ return requiredPartSize;
528
+ }
529
+
530
+ /**
531
+ * calculateEvenSplits - computes splits for a source and returns
532
+ * start and end index slices. Splits happen evenly to be sure that no
533
+ * part is less than 5MiB, as that could fail the multipart request if
534
+ * it is not the last part.
535
+ */
536
+ function calculateEvenSplits(size, objInfo) {
537
+ if (size === 0) {
538
+ return null;
539
+ }
540
+ const reqParts = partsRequired(size);
541
+ const startIndexParts = [];
542
+ const endIndexParts = [];
543
+ let start = objInfo.Start;
544
+ if (isEmpty(start) || start === -1) {
545
+ start = 0;
546
+ }
547
+ const divisorValue = Math.trunc(size / reqParts);
548
+ const reminderValue = size % reqParts;
549
+ let nextStart = start;
550
+ for (let i = 0; i < reqParts; i++) {
551
+ let curPartSize = divisorValue;
552
+ if (i < reminderValue) {
553
+ curPartSize++;
554
+ }
555
+ const currentStart = nextStart;
556
+ const currentEnd = currentStart + curPartSize - 1;
557
+ nextStart = currentEnd + 1;
558
+ startIndexParts.push(currentStart);
559
+ endIndexParts.push(currentEnd);
560
+ }
561
+ return {
562
+ startIndex: startIndexParts,
563
+ endIndex: endIndexParts,
564
+ objInfo: objInfo
565
+ };
566
+ }
567
+ const fxp = new _fastXmlParser.XMLParser({
568
+ numberParseOptions: {
569
+ eNotation: false,
570
+ hex: true,
571
+ leadingZeros: true
572
+ }
573
+ });
574
+
575
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
576
+ function parseXml(xml) {
577
+ const result = fxp.parse(xml);
578
+ if (result.Error) {
579
+ throw result.Error;
580
+ }
581
+ return result;
582
+ }
583
+
584
+ /**
585
+ * get content size of object content to upload
586
+ */
587
+ async function getContentLength(s) {
588
+ // use length property of string | Buffer
589
+ if (typeof s === 'string' || Buffer.isBuffer(s)) {
590
+ return s.length;
591
+ }
592
+
593
+ // property of `fs.ReadStream`
594
+ const filePath = s.path;
595
+ if (filePath && typeof filePath === 'string') {
596
+ const stat = await _async.fsp.lstat(filePath);
597
+ return stat.size;
598
+ }
599
+
600
+ // property of `fs.ReadStream`
601
+ const fd = s.fd;
602
+ if (fd && typeof fd === 'number') {
603
+ const stat = await (0, _async.fstat)(fd);
604
+ return stat.size;
605
+ }
606
+ return null;
607
+ }
608
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjcnlwdG8iLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJzdHJlYW0iLCJfZmFzdFhtbFBhcnNlciIsIl9pcGFkZHIiLCJfbG9kYXNoIiwibWltZSIsIl9hc3luYyIsIl90eXBlIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwibm9kZUludGVyb3AiLCJXZWFrTWFwIiwiY2FjaGVCYWJlbEludGVyb3AiLCJjYWNoZU5vZGVJbnRlcm9wIiwib2JqIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJjYWNoZSIsImhhcyIsImdldCIsIm5ld09iaiIsImhhc1Byb3BlcnR5RGVzY3JpcHRvciIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwia2V5IiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiZGVzYyIsInNldCIsIk1ldGFEYXRhSGVhZGVyUHJlZml4IiwiaGFzaEJpbmFyeSIsImJ1ZiIsImVuYWJsZVNIQTI1NiIsInNoYTI1NnN1bSIsImNyZWF0ZUhhc2giLCJ1cGRhdGUiLCJkaWdlc3QiLCJtZDVzdW0iLCJlbmNvZGVBc0hleCIsImMiLCJjaGFyQ29kZUF0IiwidG9TdHJpbmciLCJ0b1VwcGVyQ2FzZSIsInVyaUVzY2FwZSIsInVyaVN0ciIsImVuY29kZVVSSUNvbXBvbmVudCIsInJlcGxhY2UiLCJ1cmlSZXNvdXJjZUVzY2FwZSIsInN0cmluZyIsImdldFNjb3BlIiwicmVnaW9uIiwiZGF0ZSIsInNlcnZpY2VOYW1lIiwibWFrZURhdGVTaG9ydCIsImlzQW1hem9uRW5kcG9pbnQiLCJlbmRwb2ludCIsImlzVmlydHVhbEhvc3RTdHlsZSIsInByb3RvY29sIiwiYnVja2V0IiwicGF0aFN0eWxlIiwiaW5jbHVkZXMiLCJpc1ZhbGlkSVAiLCJpcCIsImlwYWRkciIsImlzVmFsaWQiLCJpc1ZhbGlkRW5kcG9pbnQiLCJpc1ZhbGlkRG9tYWluIiwiaG9zdCIsImlzU3RyaW5nIiwibGVuZ3RoIiwic2xpY2UiLCJub25BbHBoYU51bWVyaWNzIiwiY2hhciIsInByb2JlQ29udGVudFR5cGUiLCJwYXRoIiwiY29udGVudFR5cGUiLCJsb29rdXAiLCJpc1ZhbGlkUG9ydCIsInBvcnQiLCJwb3J0TnVtIiwicGFyc2VJbnQiLCJpc051bWJlciIsImlzTmFOIiwiaXNWYWxpZEJ1Y2tldE5hbWUiLCJ0ZXN0IiwiaXNWYWxpZE9iamVjdE5hbWUiLCJvYmplY3ROYW1lIiwiaXNWYWxpZFByZWZpeCIsInByZWZpeCIsImFyZyIsImlzRnVuY3Rpb24iLCJpc09iamVjdCIsImlzUGxhaW5PYmplY3QiLCJpc1JlYWRhYmxlU3RyZWFtIiwiX3JlYWQiLCJpc0Jvb2xlYW4iLCJpc0VtcHR5IiwibyIsIl8iLCJpc0VtcHR5T2JqZWN0IiwidmFsdWVzIiwiZmlsdGVyIiwieCIsInVuZGVmaW5lZCIsImlzRGVmaW5lZCIsImlzVmFsaWREYXRlIiwiRGF0ZSIsIm1ha2VEYXRlTG9uZyIsInMiLCJ0b0lTT1N0cmluZyIsInBpcGVzZXR1cCIsInN0cmVhbXMiLCJyZWR1Y2UiLCJzcmMiLCJkc3QiLCJvbiIsImVyciIsImVtaXQiLCJwaXBlIiwicmVhZGFibGVTdHJlYW0iLCJkYXRhIiwiUmVhZGFibGUiLCJwdXNoIiwiaW5zZXJ0Q29udGVudFR5cGUiLCJtZXRhRGF0YSIsImZpbGVQYXRoIiwidG9Mb3dlckNhc2UiLCJwcmVwZW5kWEFNWk1ldGEiLCJtYXBLZXlzIiwidmFsdWUiLCJpc0FtekhlYWRlciIsImlzU3VwcG9ydGVkSGVhZGVyIiwiaXNTdG9yYWdlQ2xhc3NIZWFkZXIiLCJ0ZW1wIiwic3RhcnRzV2l0aCIsInN1cHBvcnRlZF9oZWFkZXJzIiwiZXh0cmFjdE1ldGFkYXRhIiwiaGVhZGVycyIsInBpY2tCeSIsImxvd2VyIiwiZ2V0VmVyc2lvbklkIiwiZ2V0U291cmNlVmVyc2lvbklkIiwic2FuaXRpemVFVGFnIiwiZXRhZyIsInJlcGxhY2VDaGFycyIsIm0iLCJ0b01kNSIsInBheWxvYWQiLCJCdWZmZXIiLCJmcm9tIiwidG9TaGEyNTYiLCJ0b0FycmF5IiwicGFyYW0iLCJBcnJheSIsImlzQXJyYXkiLCJzYW5pdGl6ZU9iamVjdEtleSIsImFzU3RyTmFtZSIsImRlY29kZVVSSUNvbXBvbmVudCIsInNhbml0aXplU2l6ZSIsInNpemUiLCJOdW1iZXIiLCJQQVJUX0NPTlNUUkFJTlRTIiwiQUJTX01JTl9QQVJUX1NJWkUiLCJNSU5fUEFSVF9TSVpFIiwiTUFYX1BBUlRTX0NPVU5UIiwiTUFYX1BBUlRfU0laRSIsIk1BWF9TSU5HTEVfUFVUX09CSkVDVF9TSVpFIiwiTUFYX01VTFRJUEFSVF9QVVRfT0JKRUNUX1NJWkUiLCJleHBvcnRzIiwiR0VORVJJQ19TU0VfSEVBREVSIiwiRU5DUllQVElPTl9IRUFERVJTIiwic3NlR2VuZXJpY0hlYWRlciIsInNzZUttc0tleUlEIiwiZ2V0RW5jcnlwdGlvbkhlYWRlcnMiLCJlbmNDb25maWciLCJlbmNUeXBlIiwidHlwZSIsIkVOQ1JZUFRJT05fVFlQRVMiLCJTU0VDIiwiS01TIiwiU1NFQWxnb3JpdGhtIiwiS01TTWFzdGVyS2V5SUQiLCJwYXJ0c1JlcXVpcmVkIiwibWF4UGFydFNpemUiLCJyZXF1aXJlZFBhcnRTaXplIiwiTWF0aCIsInRydW5jIiwiY2FsY3VsYXRlRXZlblNwbGl0cyIsIm9iakluZm8iLCJyZXFQYXJ0cyIsInN0YXJ0SW5kZXhQYXJ0cyIsImVuZEluZGV4UGFydHMiLCJzdGFydCIsIlN0YXJ0IiwiZGl2aXNvclZhbHVlIiwicmVtaW5kZXJWYWx1ZSIsIm5leHRTdGFydCIsImkiLCJjdXJQYXJ0U2l6ZSIsImN1cnJlbnRTdGFydCIsImN1cnJlbnRFbmQiLCJzdGFydEluZGV4IiwiZW5kSW5kZXgiLCJmeHAiLCJYTUxQYXJzZXIiLCJudW1iZXJQYXJzZU9wdGlvbnMiLCJlTm90YXRpb24iLCJoZXgiLCJsZWFkaW5nWmVyb3MiLCJwYXJzZVhtbCIsInhtbCIsInJlc3VsdCIsInBhcnNlIiwiRXJyb3IiLCJnZXRDb250ZW50TGVuZ3RoIiwiaXNCdWZmZXIiLCJzdGF0IiwiZnNwIiwibHN0YXQiLCJmZCIsImZzdGF0Il0sInNvdXJjZXMiOlsiaGVscGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBIYW56byBTMyBKYXZhc2NyaXB0IExpYnJhcnkgZm9yIEFtYXpvbiBTMyBDb21wYXRpYmxlIENsb3VkIFN0b3JhZ2UsIChDKSAyMDE1IEhhbnpvIEFJLCBJbmMuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdub2RlOmNyeXB0bydcbmltcG9ydCAqIGFzIHN0cmVhbSBmcm9tICdub2RlOnN0cmVhbSdcblxuaW1wb3J0IHsgWE1MUGFyc2VyIH0gZnJvbSAnZmFzdC14bWwtcGFyc2VyJ1xuaW1wb3J0IGlwYWRkciBmcm9tICdpcGFkZHIuanMnXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnXG5pbXBvcnQgKiBhcyBtaW1lIGZyb20gJ21pbWUtdHlwZXMnXG5cbmltcG9ydCB7IGZzcCwgZnN0YXQgfSBmcm9tICcuL2FzeW5jLnRzJ1xuaW1wb3J0IHR5cGUgeyBCaW5hcnksIEVuY3J5cHRpb24sIE9iamVjdE1ldGFEYXRhLCBSZXF1ZXN0SGVhZGVycywgUmVzcG9uc2VIZWFkZXIgfSBmcm9tICcuL3R5cGUudHMnXG5pbXBvcnQgeyBFTkNSWVBUSU9OX1RZUEVTIH0gZnJvbSAnLi90eXBlLnRzJ1xuXG5jb25zdCBNZXRhRGF0YUhlYWRlclByZWZpeCA9ICd4LWFtei1tZXRhLSdcblxuZXhwb3J0IGZ1bmN0aW9uIGhhc2hCaW5hcnkoYnVmOiBCdWZmZXIsIGVuYWJsZVNIQTI1NjogYm9vbGVhbikge1xuICBsZXQgc2hhMjU2c3VtID0gJydcbiAgaWYgKGVuYWJsZVNIQTI1Nikge1xuICAgIHNoYTI1NnN1bSA9IGNyeXB0by5jcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoYnVmKS5kaWdlc3QoJ2hleCcpXG4gIH1cbiAgY29uc3QgbWQ1c3VtID0gY3J5cHRvLmNyZWF0ZUhhc2goJ21kNScpLnVwZGF0ZShidWYpLmRpZ2VzdCgnYmFzZTY0JylcblxuICByZXR1cm4geyBtZDVzdW0sIHNoYTI1NnN1bSB9XG59XG5cbi8vIFMzIHBlcmNlbnQtZW5jb2RlcyBzb21lIGV4dHJhIG5vbi1zdGFuZGFyZCBjaGFyYWN0ZXJzIGluIGEgVVJJIC4gU28gY29tcGx5IHdpdGggUzMuXG5jb25zdCBlbmNvZGVBc0hleCA9IChjOiBzdHJpbmcpID0+IGAlJHtjLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCl9YFxuZXhwb3J0IGZ1bmN0aW9uIHVyaUVzY2FwZSh1cmlTdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQodXJpU3RyKS5yZXBsYWNlKC9bIScoKSpdL2csIGVuY29kZUFzSGV4KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdXJpUmVzb3VyY2VFc2NhcGUoc3RyaW5nOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHVyaUVzY2FwZShzdHJpbmcpLnJlcGxhY2UoLyUyRi9nLCAnLycpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTY29wZShyZWdpb246IHN0cmluZywgZGF0ZTogRGF0ZSwgc2VydmljZU5hbWUgPSAnczMnKSB7XG4gIHJldHVybiBgJHttYWtlRGF0ZVNob3J0KGRhdGUpfS8ke3JlZ2lvbn0vJHtzZXJ2aWNlTmFtZX0vYXdzNF9yZXF1ZXN0YFxufVxuXG4vKipcbiAqIGlzQW1hem9uRW5kcG9pbnQgLSB0cnVlIGlmIGVuZHBvaW50IGlzICdzMy5hbWF6b25hd3MuY29tJyBvciAnczMuY24tbm9ydGgtMS5hbWF6b25hd3MuY29tLmNuJ1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBbWF6b25FbmRwb2ludChlbmRwb2ludDogc3RyaW5nKSB7XG4gIHJldHVybiBlbmRwb2ludCA9PT0gJ3MzLmFtYXpvbmF3cy5jb20nIHx8IGVuZHBvaW50ID09PSAnczMuY24tbm9ydGgtMS5hbWF6b25hd3MuY29tLmNuJ1xufVxuXG4vKipcbiAqIGlzVmlydHVhbEhvc3RTdHlsZSAtIHZlcmlmeSBpZiBidWNrZXQgbmFtZSBpcyBzdXBwb3J0IHdpdGggdmlydHVhbFxuICogaG9zdHMuIGJ1Y2tldE5hbWVzIHdpdGggcGVyaW9kcyBzaG91bGQgYmUgYWx3YXlzIHRyZWF0ZWQgYXMgcGF0aFxuICogc3R5bGUgaWYgdGhlIHByb3RvY29sIGlzICdodHRwczonLCB0aGlzIGlzIGR1ZSB0byBTU0wgd2lsZGNhcmRcbiAqIGxpbWl0YXRpb24uIEZvciBhbGwgb3RoZXIgYnVja2V0cyBhbmQgQW1hem9uIFMzIGVuZHBvaW50IHdlIHdpbGxcbiAqIGRlZmF1bHQgdG8gdmlydHVhbCBob3N0IHN0eWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWaXJ0dWFsSG9zdFN0eWxlKGVuZHBvaW50OiBzdHJpbmcsIHByb3RvY29sOiBzdHJpbmcsIGJ1Y2tldDogc3RyaW5nLCBwYXRoU3R5bGU6IGJvb2xlYW4pIHtcbiAgaWYgKHByb3RvY29sID09PSAnaHR0cHM6JyAmJiBidWNrZXQuaW5jbHVkZXMoJy4nKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiBpc0FtYXpvbkVuZHBvaW50KGVuZHBvaW50KSB8fCAhcGF0aFN0eWxlXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkSVAoaXA6IHN0cmluZykge1xuICByZXR1cm4gaXBhZGRyLmlzVmFsaWQoaXApXG59XG5cbi8qKlxuICogQHJldHVybnMgaWYgZW5kcG9pbnQgaXMgdmFsaWQgZG9tYWluLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEVuZHBvaW50KGVuZHBvaW50OiBzdHJpbmcpIHtcbiAgcmV0dXJuIGlzVmFsaWREb21haW4oZW5kcG9pbnQpIHx8IGlzVmFsaWRJUChlbmRwb2ludClcbn1cblxuLyoqXG4gKiBAcmV0dXJucyBpZiBpbnB1dCBob3N0IGlzIGEgdmFsaWQgZG9tYWluLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZERvbWFpbihob3N0OiBzdHJpbmcpIHtcbiAgaWYgKCFpc1N0cmluZyhob3N0KSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIC8vIFNlZSBSRkMgMTAzNSwgUkZDIDM2OTYuXG4gIGlmIChob3N0Lmxlbmd0aCA9PT0gMCB8fCBob3N0Lmxlbmd0aCA+IDI1NSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIC8vIEhvc3QgY2Fubm90IHN0YXJ0IG9yIGVuZCB3aXRoIGEgJy0nXG4gIGlmIChob3N0WzBdID09PSAnLScgfHwgaG9zdC5zbGljZSgtMSkgPT09ICctJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIC8vIEhvc3QgY2Fubm90IHN0YXJ0IG9yIGVuZCB3aXRoIGEgJ18nXG4gIGlmIChob3N0WzBdID09PSAnXycgfHwgaG9zdC5zbGljZSgtMSkgPT09ICdfJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIC8vIEhvc3QgY2Fubm90IHN0YXJ0IHdpdGggYSAnLidcbiAgaWYgKGhvc3RbMF0gPT09ICcuJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgY29uc3Qgbm9uQWxwaGFOdW1lcmljcyA9ICdgfiFAIyQlXiYqKCkrPXt9W118XFxcXFwiXFwnOzo+PD8vJ1xuICAvLyBBbGwgbm9uIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIGFyZSBpbnZhbGlkLlxuICBmb3IgKGNvbnN0IGNoYXIgb2Ygbm9uQWxwaGFOdW1lcmljcykge1xuICAgIGlmIChob3N0LmluY2x1ZGVzKGNoYXIpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cbiAgLy8gTm8gbmVlZCB0byByZWdleHAgbWF0Y2gsIHNpbmNlIHRoZSBsaXN0IGlzIG5vbi1leGhhdXN0aXZlLlxuICAvLyBXZSBsZXQgaXQgYmUgdmFsaWQgYW5kIGZhaWwgbGF0ZXIuXG4gIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogUHJvYmVzIGNvbnRlbnRUeXBlIHVzaW5nIGZpbGUgZXh0ZW5zaW9ucy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgXG4gKiAvLyByZXR1cm4gJ2ltYWdlL3BuZydcbiAqIHByb2JlQ29udGVudFR5cGUoJ2ZpbGUucG5nJylcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvYmVDb250ZW50VHlwZShwYXRoOiBzdHJpbmcpIHtcbiAgbGV0IGNvbnRlbnRUeXBlID0gbWltZS5sb29rdXAocGF0aClcbiAgaWYgKCFjb250ZW50VHlwZSkge1xuICAgIGNvbnRlbnRUeXBlID0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSdcbiAgfVxuICByZXR1cm4gY29udGVudFR5cGVcbn1cblxuLyoqXG4gKiBpcyBpbnB1dCBwb3J0IHZhbGlkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFBvcnQocG9ydDogdW5rbm93bik6IHBvcnQgaXMgbnVtYmVyIHtcbiAgLy8gQ29udmVydCBzdHJpbmcgcG9ydCB0byBudW1iZXIgaWYgbmVlZGVkXG4gIGNvbnN0IHBvcnROdW0gPSB0eXBlb2YgcG9ydCA9PT0gJ3N0cmluZycgPyBwYXJzZUludChwb3J0LCAxMCkgOiBwb3J0XG5cbiAgLy8gdmVyaWZ5IGlmIHBvcnQgaXMgYSB2YWxpZCBudW1iZXJcbiAgaWYgKCFpc051bWJlcihwb3J0TnVtKSB8fCBpc05hTihwb3J0TnVtKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gcG9ydCBgMGAgaXMgdmFsaWQgYW5kIHNwZWNpYWwgY2FzZVxuICByZXR1cm4gMCA8PSBwb3J0TnVtICYmIHBvcnROdW0gPD0gNjU1MzVcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRCdWNrZXROYW1lKGJ1Y2tldDogdW5rbm93bikge1xuICBpZiAoIWlzU3RyaW5nKGJ1Y2tldCkpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIGJ1Y2tldCBsZW5ndGggc2hvdWxkIGJlIGxlc3MgdGhhbiBhbmQgbm8gbW9yZSB0aGFuIDYzXG4gIC8vIGNoYXJhY3RlcnMgbG9uZy5cbiAgaWYgKGJ1Y2tldC5sZW5ndGggPCAzIHx8IGJ1Y2tldC5sZW5ndGggPiA2Mykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIC8vIGJ1Y2tldCB3aXRoIHN1Y2Nlc3NpdmUgcGVyaW9kcyBpcyBpbnZhbGlkLlxuICBpZiAoYnVja2V0LmluY2x1ZGVzKCcuLicpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgLy8gYnVja2V0IGNhbm5vdCBoYXZlIGlwIGFkZHJlc3Mgc3R5bGUuXG4gIGlmICgvWzAtOV0rXFwuWzAtOV0rXFwuWzAtOV0rXFwuWzAtOV0rLy50ZXN0KGJ1Y2tldCkpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICAvLyBidWNrZXQgc2hvdWxkIGJlZ2luIHdpdGggYWxwaGFiZXQvbnVtYmVyIGFuZCBlbmQgd2l0aCBhbHBoYWJldC9udW1iZXIsXG4gIC8vIHdpdGggYWxwaGFiZXQvbnVtYmVyLy4tIGluIHRoZSBtaWRkbGUuXG4gIGlmICgvXlthLXowLTldW2EtejAtOS4tXStbYS16MC05XSQvLnRlc3QoYnVja2V0KSkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qKlxuICogY2hlY2sgaWYgb2JqZWN0TmFtZSBpcyBhIHZhbGlkIG9iamVjdCBuYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkT2JqZWN0TmFtZShvYmplY3ROYW1lOiB1bmtub3duKSB7XG4gIGlmICghaXNWYWxpZFByZWZpeChvYmplY3ROYW1lKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIG9iamVjdE5hbWUubGVuZ3RoICE9PSAwXG59XG5cbi8qKlxuICogY2hlY2sgaWYgcHJlZml4IGlzIHZhbGlkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkUHJlZml4KHByZWZpeDogdW5rbm93bik6IHByZWZpeCBpcyBzdHJpbmcge1xuICBpZiAoIWlzU3RyaW5nKHByZWZpeCkpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICBpZiAocHJlZml4Lmxlbmd0aCA+IDEwMjQpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG4vKipcbiAqIGNoZWNrIGlmIHR5cGVvZiBhcmcgbnVtYmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcihhcmc6IHVua25vd24pOiBhcmcgaXMgbnVtYmVyIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInXG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5leHBvcnQgdHlwZSBBbnlGdW5jdGlvbiA9ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55XG5cbi8qKlxuICogY2hlY2sgaWYgdHlwZW9mIGFyZyBmdW5jdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNGdW5jdGlvbihhcmc6IHVua25vd24pOiBhcmcgaXMgQW55RnVuY3Rpb24ge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJ1xufVxuXG4vKipcbiAqIGNoZWNrIGlmIHR5cGVvZiBhcmcgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZyhhcmc6IHVua25vd24pOiBhcmcgaXMgc3RyaW5nIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnXG59XG5cbi8qKlxuICogY2hlY2sgaWYgdHlwZW9mIGFyZyBvYmplY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KGFyZzogdW5rbm93bik6IGFyZyBpcyBvYmplY3Qge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsXG59XG4vKipcbiAqIGNoZWNrIGlmIHR5cGVvZiBhcmcgaXMgcGxhaW4gb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1BsYWluT2JqZWN0KGFyZzogdW5rbm93bik6IGFyZyBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJnKSA9PT0gJ1tvYmplY3QgT2JqZWN0XSdcbn1cbi8qKlxuICogY2hlY2sgaWYgb2JqZWN0IGlzIHJlYWRhYmxlIHN0cmVhbVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNSZWFkYWJsZVN0cmVhbShhcmc6IHVua25vd24pOiBhcmcgaXMgc3RyZWFtLlJlYWRhYmxlIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC91bmJvdW5kLW1ldGhvZFxuICByZXR1cm4gaXNPYmplY3QoYXJnKSAmJiBpc0Z1bmN0aW9uKChhcmcgYXMgc3RyZWFtLlJlYWRhYmxlKS5fcmVhZClcbn1cblxuLyoqXG4gKiBjaGVjayBpZiBhcmcgaXMgYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCb29sZWFuKGFyZzogdW5rbm93bik6IGFyZyBpcyBib29sZWFuIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJ1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNFbXB0eShvOiB1bmtub3duKTogbyBpcyBudWxsIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIF8uaXNFbXB0eShvKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNFbXB0eU9iamVjdChvOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IGJvb2xlYW4ge1xuICByZXR1cm4gT2JqZWN0LnZhbHVlcyhvKS5maWx0ZXIoKHgpID0+IHggIT09IHVuZGVmaW5lZCkubGVuZ3RoICE9PSAwXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0RlZmluZWQ8VD4obzogVCk6IG8gaXMgRXhjbHVkZTxULCBudWxsIHwgdW5kZWZpbmVkPiB7XG4gIHJldHVybiBvICE9PSBudWxsICYmIG8gIT09IHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIGNoZWNrIGlmIGFyZyBpcyBhIHZhbGlkIGRhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWREYXRlKGFyZzogdW5rbm93bik6IGFyZyBpcyBEYXRlIHtcbiAgLy8gQHRzLWV4cGVjdC1lcnJvciBjaGVja25ldyBEYXRlKE1hdGguTmFOKVxuICByZXR1cm4gYXJnIGluc3RhbmNlb2YgRGF0ZSAmJiAhaXNOYU4oYXJnKVxufVxuXG4vKipcbiAqIENyZWF0ZSBhIERhdGUgc3RyaW5nIHdpdGggZm9ybWF0OiAnWVlZWU1NRERUSEhtbXNzJyArIFpcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VEYXRlTG9uZyhkYXRlPzogRGF0ZSk6IHN0cmluZyB7XG4gIGRhdGUgPSBkYXRlIHx8IG5ldyBEYXRlKClcblxuICAvLyBHaXZlcyBmb3JtYXQgbGlrZTogJzIwMTctMDgtMDdUMTY6Mjg6NTkuODg5WidcbiAgY29uc3QgcyA9IGRhdGUudG9JU09TdHJpbmcoKVxuXG4gIHJldHVybiBzLnNsaWNlKDAsIDQpICsgcy5zbGljZSg1LCA3KSArIHMuc2xpY2UoOCwgMTMpICsgcy5zbGljZSgxNCwgMTYpICsgcy5zbGljZSgxNywgMTkpICsgJ1onXG59XG5cbi8qKlxuICogQ3JlYXRlIGEgRGF0ZSBzdHJpbmcgd2l0aCBmb3JtYXQ6ICdZWVlZTU1ERCdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VEYXRlU2hvcnQoZGF0ZT86IERhdGUpIHtcbiAgZGF0ZSA9IGRhdGUgfHwgbmV3IERhdGUoKVxuXG4gIC8vIEdpdmVzIGZvcm1hdCBsaWtlOiAnMjAxNy0wOC0wN1QxNjoyODo1OS44ODlaJ1xuICBjb25zdCBzID0gZGF0ZS50b0lTT1N0cmluZygpXG5cbiAgcmV0dXJuIHMuc2xpY2UoMCwgNCkgKyBzLnNsaWNlKDUsIDcpICsgcy5zbGljZSg4LCAxMClcbn1cblxuLyoqXG4gKiBwaXBlc2V0dXAgc2V0cyB1cCBwaXBlKCkgZnJvbSBsZWZ0IHRvIHJpZ2h0IG9zIHN0cmVhbXMgYXJyYXlcbiAqIHBpcGVzZXR1cCB3aWxsIGFsc28gbWFrZSBzdXJlIHRoYXQgZXJyb3IgZW1pdHRlZCBhdCBhbnkgb2YgdGhlIHVwc3RyZWFtIFN0cmVhbVxuICogd2lsbCBiZSBlbWl0dGVkIGF0IHRoZSBsYXN0IHN0cmVhbS4gVGhpcyBtYWtlcyBlcnJvciBoYW5kbGluZyBzaW1wbGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBpcGVzZXR1cCguLi5zdHJlYW1zOiBbc3RyZWFtLlJlYWRhYmxlLCAuLi5zdHJlYW0uRHVwbGV4W10sIHN0cmVhbS5Xcml0YWJsZV0pIHtcbiAgLy8gQHRzLWV4cGVjdC1lcnJvciB0cyBjYW4ndCBuYXJyb3cgdGhpc1xuICByZXR1cm4gc3RyZWFtcy5yZWR1Y2UoKHNyYzogc3RyZWFtLlJlYWRhYmxlLCBkc3Q6IHN0cmVhbS5Xcml0YWJsZSkgPT4ge1xuICAgIHNyYy5vbignZXJyb3InLCAoZXJyKSA9PiBkc3QuZW1pdCgnZXJyb3InLCBlcnIpKVxuICAgIHJldHVybiBzcmMucGlwZShkc3QpXG4gIH0pXG59XG5cbi8qKlxuICogcmV0dXJuIGEgUmVhZGFibGUgc3RyZWFtIHRoYXQgZW1pdHMgZGF0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZGFibGVTdHJlYW0oZGF0YTogdW5rbm93bik6IHN0cmVhbS5SZWFkYWJsZSB7XG4gIGNvbnN0IHMgPSBuZXcgc3RyZWFtLlJlYWRhYmxlKClcbiAgcy5fcmVhZCA9ICgpID0+IHt9XG4gIHMucHVzaChkYXRhKVxuICBzLnB1c2gobnVsbClcbiAgcmV0dXJuIHNcbn1cblxuLyoqXG4gKiBQcm9jZXNzIG1ldGFkYXRhIHRvIGluc2VydCBhcHByb3ByaWF0ZSB2YWx1ZSB0byBgY29udGVudC10eXBlYCBhdHRyaWJ1dGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluc2VydENvbnRlbnRUeXBlKG1ldGFEYXRhOiBPYmplY3RNZXRhRGF0YSwgZmlsZVBhdGg6IHN0cmluZyk6IE9iamVjdE1ldGFEYXRhIHtcbiAgLy8gY2hlY2sgaWYgY29udGVudC10eXBlIGF0dHJpYnV0ZSBwcmVzZW50IGluIG1ldGFEYXRhXG4gIGZvciAoY29uc3Qga2V5IGluIG1ldGFEYXRhKSB7XG4gICAgaWYgKGtleS50b0xvd2VyQ2FzZSgpID09PSAnY29udGVudC10eXBlJykge1xuICAgICAgcmV0dXJuIG1ldGFEYXRhXG4gICAgfVxuICB9XG5cbiAgLy8gaWYgYGNvbnRlbnQtdHlwZWAgYXR0cmlidXRlIGlzIG5vdCBwcmVzZW50IGluIG1ldGFkYXRhLCB0aGVuIGluZmVyIGl0IGZyb20gdGhlIGV4dGVuc2lvbiBpbiBmaWxlUGF0aFxuICByZXR1cm4ge1xuICAgIC4uLm1ldGFEYXRhLFxuICAgICdjb250ZW50LXR5cGUnOiBwcm9iZUNvbnRlbnRUeXBlKGZpbGVQYXRoKSxcbiAgfVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uIHByZXBlbmRzIG1ldGFkYXRhIHdpdGggdGhlIGFwcHJvcHJpYXRlIHByZWZpeCBpZiBpdCBpcyBub3QgYWxyZWFkeSBvblxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlcGVuZFhBTVpNZXRhKG1ldGFEYXRhPzogT2JqZWN0TWV0YURhdGEpOiBSZXF1ZXN0SGVhZGVycyB7XG4gIGlmICghbWV0YURhdGEpIHtcbiAgICByZXR1cm4ge31cbiAgfVxuXG4gIHJldHVybiBfLm1hcEtleXMobWV0YURhdGEsICh2YWx1ZSwga2V5KSA9PiB7XG4gICAgaWYgKGlzQW16SGVhZGVyKGtleSkgfHwgaXNTdXBwb3J0ZWRIZWFkZXIoa2V5KSB8fCBpc1N0b3JhZ2VDbGFzc0hlYWRlcihrZXkpKSB7XG4gICAgICByZXR1cm4ga2V5XG4gICAgfVxuXG4gICAgcmV0dXJuIE1ldGFEYXRhSGVhZGVyUHJlZml4ICsga2V5XG4gIH0pXG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGl0IGlzIGEgdmFsaWQgaGVhZGVyIGFjY29yZGluZyB0byB0aGUgQW1hem9uUzMgQVBJXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0FtekhlYWRlcihrZXk6IHN0cmluZykge1xuICBjb25zdCB0ZW1wID0ga2V5LnRvTG93ZXJDYXNlKClcbiAgcmV0dXJuIChcbiAgICB0ZW1wLnN0YXJ0c1dpdGgoTWV0YURhdGFIZWFkZXJQcmVmaXgpIHx8XG4gICAgdGVtcCA9PT0gJ3gtYW16LWFjbCcgfHxcbiAgICB0ZW1wLnN0YXJ0c1dpdGgoJ3gtYW16LXNlcnZlci1zaWRlLWVuY3J5cHRpb24tJykgfHxcbiAgICB0ZW1wID09PSAneC1hbXotc2VydmVyLXNpZGUtZW5jcnlwdGlvbidcbiAgKVxufVxuXG4vKipcbiAqIENoZWNrcyBpZiBpdCBpcyBhIHN1cHBvcnRlZCBIZWFkZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3VwcG9ydGVkSGVhZGVyKGtleTogc3RyaW5nKSB7XG4gIGNvbnN0IHN1cHBvcnRlZF9oZWFkZXJzID0gW1xuICAgICdjb250ZW50LXR5cGUnLFxuICAgICdjYWNoZS1jb250cm9sJyxcbiAgICAnY29udGVudC1lbmNvZGluZycsXG4gICAgJ2NvbnRlbnQtZGlzcG9zaXRpb24nLFxuICAgICdjb250ZW50LWxhbmd1YWdlJyxcbiAgICAneC1hbXotd2Vic2l0ZS1yZWRpcmVjdC1sb2NhdGlvbicsXG4gICAgJ2lmLW5vbmUtbWF0Y2gnLFxuICAgICdpZi1tYXRjaCcsXG4gIF1cbiAgcmV0dXJuIHN1cHBvcnRlZF9oZWFkZXJzLmluY2x1ZGVzKGtleS50b0xvd2VyQ2FzZSgpKVxufVxuXG4vKipcbiAqIENoZWNrcyBpZiBpdCBpcyBhIHN0b3JhZ2UgaGVhZGVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N0b3JhZ2VDbGFzc0hlYWRlcihrZXk6IHN0cmluZykge1xuICByZXR1cm4ga2V5LnRvTG93ZXJDYXNlKCkgPT09ICd4LWFtei1zdG9yYWdlLWNsYXNzJ1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdE1ldGFkYXRhKGhlYWRlcnM6IFJlc3BvbnNlSGVhZGVyKSB7XG4gIHJldHVybiBfLm1hcEtleXMoXG4gICAgXy5waWNrQnkoaGVhZGVycywgKHZhbHVlLCBrZXkpID0+IGlzU3VwcG9ydGVkSGVhZGVyKGtleSkgfHwgaXNTdG9yYWdlQ2xhc3NIZWFkZXIoa2V5KSB8fCBpc0FtekhlYWRlcihrZXkpKSxcbiAgICAodmFsdWUsIGtleSkgPT4ge1xuICAgICAgY29uc3QgbG93ZXIgPSBrZXkudG9Mb3dlckNhc2UoKVxuICAgICAgaWYgKGxvd2VyLnN0YXJ0c1dpdGgoTWV0YURhdGFIZWFkZXJQcmVmaXgpKSB7XG4gICAgICAgIHJldHVybiBsb3dlci5zbGljZShNZXRhRGF0YUhlYWRlclByZWZpeC5sZW5ndGgpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBrZXlcbiAgICB9LFxuICApXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWZXJzaW9uSWQoaGVhZGVyczogUmVzcG9uc2VIZWFkZXIgPSB7fSkge1xuICByZXR1cm4gaGVhZGVyc1sneC1hbXotdmVyc2lvbi1pZCddIHx8IG51bGxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNvdXJjZVZlcnNpb25JZChoZWFkZXJzOiBSZXNwb25zZUhlYWRlciA9IHt9KSB7XG4gIHJldHVybiBoZWFkZXJzWyd4LWFtei1jb3B5LXNvdXJjZS12ZXJzaW9uLWlkJ10gfHwgbnVsbFxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2FuaXRpemVFVGFnKGV0YWcgPSAnJyk6IHN0cmluZyB7XG4gIGNvbnN0IHJlcGxhY2VDaGFyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAnXCInOiAnJyxcbiAgICAnJnF1b3Q7JzogJycsXG4gICAgJyYjMzQ7JzogJycsXG4gICAgJyZRVU9UOyc6ICcnLFxuICAgICcmI3gwMDAyMic6ICcnLFxuICB9XG4gIHJldHVybiBldGFnLnJlcGxhY2UoL14oXCJ8JnF1b3Q7fCYjMzQ7KXwoXCJ8JnF1b3Q7fCYjMzQ7KSQvZywgKG0pID0+IHJlcGxhY2VDaGFyc1ttXSBhcyBzdHJpbmcpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b01kNShwYXlsb2FkOiBCaW5hcnkpOiBzdHJpbmcge1xuICAvLyB1c2Ugc3RyaW5nIGZyb20gYnJvd3NlciBhbmQgYnVmZmVyIGZyb20gbm9kZWpzXG4gIC8vIGJyb3dzZXIgc3VwcG9ydCBpcyB0ZXN0ZWQgb25seSBhZ2FpbnN0IEhhbnpvIFMzIHNlcnZlclxuICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhhc2goJ21kNScpLnVwZGF0ZShCdWZmZXIuZnJvbShwYXlsb2FkKSkuZGlnZXN0KCkudG9TdHJpbmcoJ2Jhc2U2NCcpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b1NoYTI1NihwYXlsb2FkOiBCaW5hcnkpOiBzdHJpbmcge1xuICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShwYXlsb2FkKS5kaWdlc3QoJ2hleCcpXG59XG5cbi8qKlxuICogdG9BcnJheSByZXR1cm5zIGEgc2luZ2xlIGVsZW1lbnQgYXJyYXkgd2l0aCBwYXJhbSBiZWluZyB0aGUgZWxlbWVudCxcbiAqIGlmIHBhcmFtIGlzIGp1c3QgYSBzdHJpbmcsIGFuZCByZXR1cm5zICdwYXJhbScgYmFjayBpZiBpdCBpcyBhbiBhcnJheVxuICogU28sIGl0IG1ha2VzIHN1cmUgcGFyYW0gaXMgYWx3YXlzIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0FycmF5PFQgPSB1bmtub3duPihwYXJhbTogVCB8IFRbXSk6IEFycmF5PFQ+IHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KHBhcmFtKSkge1xuICAgIHJldHVybiBbcGFyYW1dIGFzIFRbXVxuICB9XG4gIHJldHVybiBwYXJhbVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2FuaXRpemVPYmplY3RLZXkob2JqZWN0TmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gKyBzeW1ib2wgY2hhcmFjdGVycyBhcmUgbm90IGRlY29kZWQgYXMgc3BhY2VzIGluIEpTLiBzbyByZXBsYWNlIHRoZW0gZmlyc3QgYW5kIGRlY29kZSB0byBnZXQgdGhlIGNvcnJlY3QgcmVzdWx0LlxuICBjb25zdCBhc1N0ck5hbWUgPSAob2JqZWN0TmFtZSA/IG9iamVjdE5hbWUudG9TdHJpbmcoKSA6ICcnKS5yZXBsYWNlKC9cXCsvZywgJyAnKVxuICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGFzU3RyTmFtZSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhbml0aXplU2l6ZShzaXplPzogc3RyaW5nKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHNpemUgPyBOdW1iZXIucGFyc2VJbnQoc2l6ZSkgOiB1bmRlZmluZWRcbn1cblxuZXhwb3J0IGNvbnN0IFBBUlRfQ09OU1RSQUlOVFMgPSB7XG4gIC8vIGFic01pblBhcnRTaXplIC0gYWJzb2x1dGUgbWluaW11bSBwYXJ0IHNpemUgKDUgTWlCKVxuICBBQlNfTUlOX1BBUlRfU0laRTogMTAyNCAqIDEwMjQgKiA1LFxuICAvLyBNSU5fUEFSVF9TSVpFIC0gbWluaW11bSBwYXJ0IHNpemUgMTZNaUIgcGVyIG9iamVjdCBhZnRlciB3aGljaFxuICBNSU5fUEFSVF9TSVpFOiAxMDI0ICogMTAyNCAqIDE2LFxuICAvLyBNQVhfUEFSVFNfQ09VTlQgLSBtYXhpbXVtIG51bWJlciBvZiBwYXJ0cyBmb3IgYSBzaW5nbGUgbXVsdGlwYXJ0IHNlc3Npb24uXG4gIE1BWF9QQVJUU19DT1VOVDogMTAwMDAsXG4gIC8vIE1BWF9QQVJUX1NJWkUgLSBtYXhpbXVtIHBhcnQgc2l6ZSA1R2lCIGZvciBhIHNpbmdsZSBtdWx0aXBhcnQgdXBsb2FkXG4gIC8vIG9wZXJhdGlvbi5cbiAgTUFYX1BBUlRfU0laRTogMTAyNCAqIDEwMjQgKiAxMDI0ICogNSxcbiAgLy8gTUFYX1NJTkdMRV9QVVRfT0JKRUNUX1NJWkUgLSBtYXhpbXVtIHNpemUgNUdpQiBvZiBvYmplY3QgcGVyIFBVVFxuICAvLyBvcGVyYXRpb24uXG4gIE1BWF9TSU5HTEVfUFVUX09CSkVDVF9TSVpFOiAxMDI0ICogMTAyNCAqIDEwMjQgKiA1LFxuICAvLyBNQVhfTVVMVElQQVJUX1BVVF9PQkpFQ1RfU0laRSAtIG1heGltdW0gc2l6ZSA1VGlCIG9mIG9iamVjdCBmb3JcbiAgLy8gTXVsdGlwYXJ0IG9wZXJhdGlvbi5cbiAgTUFYX01VTFRJUEFSVF9QVVRfT0JKRUNUX1NJWkU6IDEwMjQgKiAxMDI0ICogMTAyNCAqIDEwMjQgKiA1LFxufVxuXG5jb25zdCBHRU5FUklDX1NTRV9IRUFERVIgPSAnWC1BbXotU2VydmVyLVNpZGUtRW5jcnlwdGlvbidcblxuY29uc3QgRU5DUllQVElPTl9IRUFERVJTID0ge1xuICAvLyBzc2VHZW5lcmljSGVhZGVyIGlzIHRoZSBBV1MgU1NFIGhlYWRlciB1c2VkIGZvciBTU0UtUzMgYW5kIFNTRS1LTVMuXG4gIHNzZUdlbmVyaWNIZWFkZXI6IEdFTkVSSUNfU1NFX0hFQURFUixcbiAgLy8gc3NlS21zS2V5SUQgaXMgdGhlIEFXUyBTU0UtS01TIGtleSBpZC5cbiAgc3NlS21zS2V5SUQ6IEdFTkVSSUNfU1NFX0hFQURFUiArICctQXdzLUttcy1LZXktSWQnLFxufSBhcyBjb25zdFxuXG4vKipcbiAqIFJldHVybiBFbmNyeXB0aW9uIGhlYWRlcnNcbiAqIEBwYXJhbSBlbmNDb25maWdcbiAqIEByZXR1cm5zIGFuIG9iamVjdCB3aXRoIGtleSB2YWx1ZSBwYWlycyB0aGF0IGNhbiBiZSB1c2VkIGluIGhlYWRlcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbmNyeXB0aW9uSGVhZGVycyhlbmNDb25maWc6IEVuY3J5cHRpb24pOiBSZXF1ZXN0SGVhZGVycyB7XG4gIGNvbnN0IGVuY1R5cGUgPSBlbmNDb25maWcudHlwZVxuXG4gIGlmICghaXNFbXB0eShlbmNUeXBlKSkge1xuICAgIGlmIChlbmNUeXBlID09PSBFTkNSWVBUSU9OX1RZUEVTLlNTRUMpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIFtFTkNSWVBUSU9OX0hFQURFUlMuc3NlR2VuZXJpY0hlYWRlcl06ICdBRVMyNTYnLFxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZW5jVHlwZSA9PT0gRU5DUllQVElPTl9UWVBFUy5LTVMpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIFtFTkNSWVBUSU9OX0hFQURFUlMuc3NlR2VuZXJpY0hlYWRlcl06IGVuY0NvbmZpZy5TU0VBbGdvcml0aG0sXG4gICAgICAgIFtFTkNSWVBUSU9OX0hFQURFUlMuc3NlS21zS2V5SURdOiBlbmNDb25maWcuS01TTWFzdGVyS2V5SUQsXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHt9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJ0c1JlcXVpcmVkKHNpemU6IG51bWJlcik6IG51bWJlciB7XG4gIGNvbnN0IG1heFBhcnRTaXplID0gUEFSVF9DT05TVFJBSU5UUy5NQVhfTVVMVElQQVJUX1BVVF9PQkpFQ1RfU0laRSAvIChQQVJUX0NPTlNUUkFJTlRTLk1BWF9QQVJUU19DT1VOVCAtIDEpXG4gIGxldCByZXF1aXJlZFBhcnRTaXplID0gc2l6ZSAvIG1heFBhcnRTaXplXG4gIGlmIChzaXplICUgbWF4UGFydFNpemUgPiAwKSB7XG4gICAgcmVxdWlyZWRQYXJ0U2l6ZSsrXG4gIH1cbiAgcmVxdWlyZWRQYXJ0U2l6ZSA9IE1hdGgudHJ1bmMocmVxdWlyZWRQYXJ0U2l6ZSlcbiAgcmV0dXJuIHJlcXVpcmVkUGFydFNpemVcbn1cblxuLyoqXG4gKiBjYWxjdWxhdGVFdmVuU3BsaXRzIC0gY29tcHV0ZXMgc3BsaXRzIGZvciBhIHNvdXJjZSBhbmQgcmV0dXJuc1xuICogc3RhcnQgYW5kIGVuZCBpbmRleCBzbGljZXMuIFNwbGl0cyBoYXBwZW4gZXZlbmx5IHRvIGJlIHN1cmUgdGhhdCBub1xuICogcGFydCBpcyBsZXNzIHRoYW4gNU1pQiwgYXMgdGhhdCBjb3VsZCBmYWlsIHRoZSBtdWx0aXBhcnQgcmVxdWVzdCBpZlxuICogaXQgaXMgbm90IHRoZSBsYXN0IHBhcnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVFdmVuU3BsaXRzPFQgZXh0ZW5kcyB7IFN0YXJ0PzogbnVtYmVyIH0+KFxuICBzaXplOiBudW1iZXIsXG4gIG9iakluZm86IFQsXG4pOiB7XG4gIHN0YXJ0SW5kZXg6IG51bWJlcltdXG4gIG9iakluZm86IFRcbiAgZW5kSW5kZXg6IG51bWJlcltdXG59IHwgbnVsbCB7XG4gIGlmIChzaXplID09PSAwKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuICBjb25zdCByZXFQYXJ0cyA9IHBhcnRzUmVxdWlyZWQoc2l6ZSlcbiAgY29uc3Qgc3RhcnRJbmRleFBhcnRzOiBudW1iZXJbXSA9IFtdXG4gIGNvbnN0IGVuZEluZGV4UGFydHM6IG51bWJlcltdID0gW11cblxuICBsZXQgc3RhcnQgPSBvYmpJbmZvLlN0YXJ0XG4gIGlmIChpc0VtcHR5KHN0YXJ0KSB8fCBzdGFydCA9PT0gLTEpIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICBjb25zdCBkaXZpc29yVmFsdWUgPSBNYXRoLnRydW5jKHNpemUgLyByZXFQYXJ0cylcblxuICBjb25zdCByZW1pbmRlclZhbHVlID0gc2l6ZSAlIHJlcVBhcnRzXG5cbiAgbGV0IG5leHRTdGFydCA9IHN0YXJ0XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXFQYXJ0czsgaSsrKSB7XG4gICAgbGV0IGN1clBhcnRTaXplID0gZGl2aXNvclZhbHVlXG4gICAgaWYgKGkgPCByZW1pbmRlclZhbHVlKSB7XG4gICAgICBjdXJQYXJ0U2l6ZSsrXG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudFN0YXJ0ID0gbmV4dFN0YXJ0XG4gICAgY29uc3QgY3VycmVudEVuZCA9IGN1cnJlbnRTdGFydCArIGN1clBhcnRTaXplIC0gMVxuICAgIG5leHRTdGFydCA9IGN1cnJlbnRFbmQgKyAxXG5cbiAgICBzdGFydEluZGV4UGFydHMucHVzaChjdXJyZW50U3RhcnQpXG4gICAgZW5kSW5kZXhQYXJ0cy5wdXNoKGN1cnJlbnRFbmQpXG4gIH1cblxuICByZXR1cm4geyBzdGFydEluZGV4OiBzdGFydEluZGV4UGFydHMsIGVuZEluZGV4OiBlbmRJbmRleFBhcnRzLCBvYmpJbmZvOiBvYmpJbmZvIH1cbn1cbmNvbnN0IGZ4cCA9IG5ldyBYTUxQYXJzZXIoeyBudW1iZXJQYXJzZU9wdGlvbnM6IHsgZU5vdGF0aW9uOiBmYWxzZSwgaGV4OiB0cnVlLCBsZWFkaW5nWmVyb3M6IHRydWUgfSB9KVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlWG1sKHhtbDogc3RyaW5nKTogYW55IHtcbiAgY29uc3QgcmVzdWx0ID0gZnhwLnBhcnNlKHhtbClcbiAgaWYgKHJlc3VsdC5FcnJvcikge1xuICAgIHRocm93IHJlc3VsdC5FcnJvclxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vKipcbiAqIGdldCBjb250ZW50IHNpemUgb2Ygb2JqZWN0IGNvbnRlbnQgdG8gdXBsb2FkXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRDb250ZW50TGVuZ3RoKHM6IHN0cmVhbS5SZWFkYWJsZSB8IEJ1ZmZlciB8IHN0cmluZyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAvLyB1c2UgbGVuZ3RoIHByb3BlcnR5IG9mIHN0cmluZyB8IEJ1ZmZlclxuICBpZiAodHlwZW9mIHMgPT09ICdzdHJpbmcnIHx8IEJ1ZmZlci5pc0J1ZmZlcihzKSkge1xuICAgIHJldHVybiBzLmxlbmd0aFxuICB9XG5cbiAgLy8gcHJvcGVydHkgb2YgYGZzLlJlYWRTdHJlYW1gXG4gIGNvbnN0IGZpbGVQYXRoID0gKHMgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikucGF0aCBhcyBzdHJpbmcgfCB1bmRlZmluZWRcbiAgaWYgKGZpbGVQYXRoICYmIHR5cGVvZiBmaWxlUGF0aCA9PT0gJ3N0cmluZycpIHtcbiAgICBjb25zdCBzdGF0ID0gYXdhaXQgZnNwLmxzdGF0KGZpbGVQYXRoKVxuICAgIHJldHVybiBzdGF0LnNpemVcbiAgfVxuXG4gIC8vIHByb3BlcnR5IG9mIGBmcy5SZWFkU3RyZWFtYFxuICBjb25zdCBmZCA9IChzIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLmZkIGFzIG51bWJlciB8IG51bGwgfCB1bmRlZmluZWRcbiAgaWYgKGZkICYmIHR5cGVvZiBmZCA9PT0gJ251bWJlcicpIHtcbiAgICBjb25zdCBzdGF0ID0gYXdhaXQgZnN0YXQoZmQpXG4gICAgcmV0dXJuIHN0YXQuc2l6ZVxuICB9XG5cbiAgcmV0dXJuIG51bGxcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFnQkEsSUFBQUEsTUFBQSxHQUFBQyx1QkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsTUFBQSxHQUFBRix1QkFBQSxDQUFBQyxPQUFBO0FBRUEsSUFBQUUsY0FBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksT0FBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssSUFBQSxHQUFBTix1QkFBQSxDQUFBQyxPQUFBO0FBRUEsSUFBQU0sTUFBQSxHQUFBTixPQUFB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