ng2-file-upload 4.0.0 → 6.0.0

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.
@@ -0,0 +1,404 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { FileLikeObject } from './file-like-object.class';
3
+ import { FileItem } from './file-item.class';
4
+ import { FileType } from './file-type.class';
5
+ function isFile(value) {
6
+ return (File && value instanceof File);
7
+ }
8
+ export class FileUploader {
9
+ constructor(options) {
10
+ this.isUploading = false;
11
+ this.queue = [];
12
+ this.progress = 0;
13
+ this._nextIndex = 0;
14
+ this.options = {
15
+ autoUpload: false,
16
+ isHTML5: true,
17
+ filters: [],
18
+ removeAfterUpload: false,
19
+ disableMultipart: false,
20
+ formatDataFunction: (item) => item._file,
21
+ formatDataFunctionIsAsync: false,
22
+ url: ''
23
+ };
24
+ this.setOptions(options);
25
+ this.response = new EventEmitter();
26
+ }
27
+ setOptions(options) {
28
+ this.options = Object.assign(this.options, options);
29
+ this.authToken = this.options.authToken;
30
+ this.authTokenHeader = this.options.authTokenHeader || 'Authorization';
31
+ this.autoUpload = this.options.autoUpload;
32
+ this.options.filters?.unshift({ name: 'queueLimit', fn: this._queueLimitFilter });
33
+ if (this.options.maxFileSize) {
34
+ this.options.filters?.unshift({ name: 'fileSize', fn: this._fileSizeFilter });
35
+ }
36
+ if (this.options.allowedFileType) {
37
+ this.options.filters?.unshift({ name: 'fileType', fn: this._fileTypeFilter });
38
+ }
39
+ if (this.options.allowedMimeType) {
40
+ this.options.filters?.unshift({ name: 'mimeType', fn: this._mimeTypeFilter });
41
+ }
42
+ for (let i = 0; i < this.queue.length; i++) {
43
+ this.queue[i].url = this.options.url;
44
+ }
45
+ }
46
+ addToQueue(files, _options, filters) {
47
+ let options = _options;
48
+ const list = [];
49
+ for (const file of files) {
50
+ list.push(file);
51
+ }
52
+ const arrayOfFilters = this._getFilters(filters);
53
+ const count = this.queue.length;
54
+ const addedFileItems = [];
55
+ list.map((some) => {
56
+ if (!options) {
57
+ options = this.options;
58
+ }
59
+ const temp = new FileLikeObject(some);
60
+ if (this._isValidFile(temp, arrayOfFilters, options)) {
61
+ const fileItem = new FileItem(this, some, options);
62
+ addedFileItems.push(fileItem);
63
+ this.queue.push(fileItem);
64
+ this._onAfterAddingFile(fileItem);
65
+ }
66
+ else {
67
+ if (typeof this._failFilterIndex === 'number' && this._failFilterIndex >= 0) {
68
+ const filter = arrayOfFilters[this._failFilterIndex];
69
+ this._onWhenAddingFileFailed(temp, filter, options);
70
+ }
71
+ }
72
+ });
73
+ if (this.queue.length !== count) {
74
+ this._onAfterAddingAll(addedFileItems);
75
+ this.progress = this._getTotalProgress();
76
+ }
77
+ this._render();
78
+ if (this.options.autoUpload) {
79
+ this.uploadAll();
80
+ }
81
+ }
82
+ removeFromQueue(value) {
83
+ const index = this.getIndexOfItem(value);
84
+ const item = this.queue[index];
85
+ if (item.isUploading) {
86
+ item.cancel();
87
+ }
88
+ this.queue.splice(index, 1);
89
+ this.progress = this._getTotalProgress();
90
+ }
91
+ clearQueue() {
92
+ while (this.queue.length) {
93
+ this.queue[0].remove();
94
+ }
95
+ this.progress = 0;
96
+ }
97
+ uploadItem(value) {
98
+ const index = this.getIndexOfItem(value);
99
+ const item = this.queue[index];
100
+ const transport = this.options.isHTML5 ? '_xhrTransport' : '_iframeTransport';
101
+ item._prepareToUploading();
102
+ if (this.isUploading) {
103
+ return;
104
+ }
105
+ this.isUploading = true;
106
+ this[transport](item);
107
+ }
108
+ cancelItem(value) {
109
+ const index = this.getIndexOfItem(value);
110
+ const item = this.queue[index];
111
+ const prop = this.options.isHTML5 ? item._xhr : item._form;
112
+ if (item && item.isUploading) {
113
+ prop.abort();
114
+ }
115
+ }
116
+ uploadAll() {
117
+ const items = this.getNotUploadedItems().filter((item) => !item.isUploading);
118
+ if (!items.length) {
119
+ return;
120
+ }
121
+ items.map((item) => item._prepareToUploading());
122
+ items[0].upload();
123
+ }
124
+ cancelAll() {
125
+ const items = this.getNotUploadedItems();
126
+ items.map((item) => item.cancel());
127
+ }
128
+ isFile(value) {
129
+ return isFile(value);
130
+ }
131
+ isFileLikeObject(value) {
132
+ return value instanceof FileLikeObject;
133
+ }
134
+ getIndexOfItem(value) {
135
+ return typeof value === 'number' ? value : this.queue.indexOf(value);
136
+ }
137
+ getNotUploadedItems() {
138
+ return this.queue.filter((item) => !item.isUploaded);
139
+ }
140
+ getReadyItems() {
141
+ return this.queue
142
+ .filter((item) => (item.isReady && !item.isUploading))
143
+ .sort((item1, item2) => item1.index - item2.index);
144
+ }
145
+ onAfterAddingAll(fileItems) {
146
+ return { fileItems };
147
+ }
148
+ onBuildItemForm(fileItem, form) {
149
+ return { fileItem, form };
150
+ }
151
+ onAfterAddingFile(fileItem) {
152
+ return { fileItem };
153
+ }
154
+ onWhenAddingFileFailed(item, filter, options) {
155
+ return { item, filter, options };
156
+ }
157
+ onBeforeUploadItem(fileItem) {
158
+ return { fileItem };
159
+ }
160
+ onProgressItem(fileItem, progress) {
161
+ return { fileItem, progress };
162
+ }
163
+ onProgressAll(progress) {
164
+ return { progress };
165
+ }
166
+ onSuccessItem(item, response, status, headers) {
167
+ return { item, response, status, headers };
168
+ }
169
+ onErrorItem(item, response, status, headers) {
170
+ return { item, response, status, headers };
171
+ }
172
+ onCancelItem(item, response, status, headers) {
173
+ return { item, response, status, headers };
174
+ }
175
+ onCompleteItem(item, response, status, headers) {
176
+ return { item, response, status, headers };
177
+ }
178
+ onCompleteAll() {
179
+ return void 0;
180
+ }
181
+ _mimeTypeFilter(item) {
182
+ return !(item?.type && this.options.allowedMimeType && this.options.allowedMimeType?.indexOf(item.type) === -1);
183
+ }
184
+ _fileSizeFilter(item) {
185
+ return !(this.options.maxFileSize && item.size > this.options.maxFileSize);
186
+ }
187
+ _fileTypeFilter(item) {
188
+ return !(this.options.allowedFileType &&
189
+ this.options.allowedFileType.indexOf(FileType.getMimeClass(item)) === -1);
190
+ }
191
+ _onErrorItem(item, response, status, headers) {
192
+ item._onError(response, status, headers);
193
+ this.onErrorItem(item, response, status, headers);
194
+ }
195
+ _onCompleteItem(item, response, status, headers) {
196
+ item._onComplete(response, status, headers);
197
+ this.onCompleteItem(item, response, status, headers);
198
+ const nextItem = this.getReadyItems()[0];
199
+ this.isUploading = false;
200
+ if (nextItem) {
201
+ nextItem.upload();
202
+ return;
203
+ }
204
+ this.onCompleteAll();
205
+ this.progress = this._getTotalProgress();
206
+ this._render();
207
+ }
208
+ _headersGetter(parsedHeaders) {
209
+ return (name) => {
210
+ if (name) {
211
+ return parsedHeaders[name.toLowerCase()] || undefined;
212
+ }
213
+ return parsedHeaders;
214
+ };
215
+ }
216
+ _xhrTransport(item) {
217
+ // tslint:disable-next-line:no-this-assignment
218
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
219
+ const that = this;
220
+ const xhr = item._xhr = new XMLHttpRequest();
221
+ let sendable;
222
+ this._onBeforeUploadItem(item);
223
+ if (typeof item._file.size !== 'number') {
224
+ throw new TypeError('The file specified is no longer valid');
225
+ }
226
+ if (!this.options.disableMultipart) {
227
+ sendable = new FormData();
228
+ this._onBuildItemForm(item, sendable);
229
+ const appendFile = () => sendable.append(item.alias, item._file, item.file.name);
230
+ if (!this.options.parametersBeforeFiles) {
231
+ appendFile();
232
+ }
233
+ // For AWS, Additional Parameters must come BEFORE Files
234
+ if (this.options.additionalParameter !== undefined) {
235
+ Object.keys(this.options.additionalParameter).forEach((key) => {
236
+ let paramVal = this.options.additionalParameter?.[key];
237
+ // Allow an additional parameter to include the filename
238
+ if (typeof paramVal === 'string' && paramVal.indexOf('{{file_name}}') >= 0 && item.file?.name) {
239
+ paramVal = paramVal.replace('{{file_name}}', item.file.name);
240
+ }
241
+ sendable.append(key, paramVal);
242
+ });
243
+ }
244
+ if (appendFile && this.options.parametersBeforeFiles) {
245
+ appendFile();
246
+ }
247
+ }
248
+ else {
249
+ if (this.options.formatDataFunction) {
250
+ sendable = this.options.formatDataFunction(item);
251
+ }
252
+ }
253
+ xhr.upload.onprogress = (event) => {
254
+ const progress = Math.round(event.lengthComputable ? event.loaded * 100 / event.total : 0);
255
+ this._onProgressItem(item, progress);
256
+ };
257
+ xhr.onload = () => {
258
+ const headers = this._parseHeaders(xhr.getAllResponseHeaders());
259
+ const response = this._transformResponse(xhr.response);
260
+ const gist = this._isSuccessCode(xhr.status) ? 'Success' : 'Error';
261
+ const method = `_on${gist}Item`;
262
+ this[method](item, response, xhr.status, headers);
263
+ this._onCompleteItem(item, response, xhr.status, headers);
264
+ };
265
+ xhr.onerror = () => {
266
+ const headers = this._parseHeaders(xhr.getAllResponseHeaders());
267
+ const response = this._transformResponse(xhr.response);
268
+ this._onErrorItem(item, response, xhr.status, headers);
269
+ this._onCompleteItem(item, response, xhr.status, headers);
270
+ };
271
+ xhr.onabort = () => {
272
+ const headers = this._parseHeaders(xhr.getAllResponseHeaders());
273
+ const response = this._transformResponse(xhr.response);
274
+ this._onCancelItem(item, response, xhr.status, headers);
275
+ this._onCompleteItem(item, response, xhr.status, headers);
276
+ };
277
+ if (item.method && item.url) {
278
+ xhr.open(item.method, item.url, true);
279
+ }
280
+ xhr.withCredentials = item.withCredentials;
281
+ if (this.options.headers) {
282
+ for (const header of this.options.headers) {
283
+ xhr.setRequestHeader(header.name, header.value);
284
+ }
285
+ }
286
+ if (item.headers.length) {
287
+ for (const header of item.headers) {
288
+ xhr.setRequestHeader(header.name, header.value);
289
+ }
290
+ }
291
+ if (this.authToken && this.authTokenHeader) {
292
+ xhr.setRequestHeader(this.authTokenHeader, this.authToken);
293
+ }
294
+ xhr.onreadystatechange = function () {
295
+ if (xhr.readyState == XMLHttpRequest.DONE) {
296
+ that.response.emit(xhr.responseText);
297
+ }
298
+ };
299
+ if (this.options.formatDataFunctionIsAsync) {
300
+ sendable.then((result) => xhr.send(JSON.stringify(result)));
301
+ }
302
+ else {
303
+ xhr.send(sendable);
304
+ }
305
+ this._render();
306
+ }
307
+ _getTotalProgress(value = 0) {
308
+ if (this.options.removeAfterUpload) {
309
+ return value;
310
+ }
311
+ const notUploaded = this.getNotUploadedItems().length;
312
+ const uploaded = notUploaded ? this.queue.length - notUploaded : this.queue.length;
313
+ const ratio = 100 / this.queue.length;
314
+ const current = value * ratio / 100;
315
+ return Math.round(uploaded * ratio + current);
316
+ }
317
+ _getFilters(filters) {
318
+ if (!filters) {
319
+ return this.options?.filters || [];
320
+ }
321
+ if (Array.isArray(filters)) {
322
+ return filters;
323
+ }
324
+ if (typeof filters === 'string') {
325
+ const names = filters.match(/[^\s,]+/g);
326
+ return this.options?.filters || []
327
+ .filter((filter) => names?.indexOf(filter.name) !== -1);
328
+ }
329
+ return this.options?.filters || [];
330
+ }
331
+ _render() {
332
+ return void 0;
333
+ }
334
+ _queueLimitFilter() {
335
+ return this.options.queueLimit === undefined || this.queue.length < this.options.queueLimit;
336
+ }
337
+ _isValidFile(file, filters, options) {
338
+ this._failFilterIndex = -1;
339
+ return !filters.length ? true : filters.every((filter) => {
340
+ if (typeof this._failFilterIndex === 'number') {
341
+ this._failFilterIndex++;
342
+ }
343
+ return filter.fn.call(this, file, options);
344
+ });
345
+ }
346
+ _isSuccessCode(status) {
347
+ return (status >= 200 && status < 300) || status === 304;
348
+ }
349
+ _transformResponse(response) {
350
+ return response;
351
+ }
352
+ _parseHeaders(headers) {
353
+ const parsed = {};
354
+ let key;
355
+ let val;
356
+ let i;
357
+ if (!headers) {
358
+ return parsed;
359
+ }
360
+ headers.split('\n').map((line) => {
361
+ i = line.indexOf(':');
362
+ key = line.slice(0, i).trim().toLowerCase();
363
+ val = line.slice(i + 1).trim();
364
+ if (key) {
365
+ parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
366
+ }
367
+ });
368
+ return parsed;
369
+ }
370
+ _onWhenAddingFileFailed(item, filter, options) {
371
+ this.onWhenAddingFileFailed(item, filter, options);
372
+ }
373
+ _onAfterAddingFile(item) {
374
+ this.onAfterAddingFile(item);
375
+ }
376
+ _onAfterAddingAll(items) {
377
+ this.onAfterAddingAll(items);
378
+ }
379
+ _onBeforeUploadItem(item) {
380
+ item._onBeforeUpload();
381
+ this.onBeforeUploadItem(item);
382
+ }
383
+ _onBuildItemForm(item, form) {
384
+ item._onBuildForm(form);
385
+ this.onBuildItemForm(item, form);
386
+ }
387
+ _onProgressItem(item, progress) {
388
+ const total = this._getTotalProgress(progress);
389
+ this.progress = total;
390
+ item._onProgress(progress);
391
+ this.onProgressItem(item, progress);
392
+ this.onProgressAll(total);
393
+ this._render();
394
+ }
395
+ _onSuccessItem(item, response, status, headers) {
396
+ item._onSuccess(response, status, headers);
397
+ this.onSuccessItem(item, response, status, headers);
398
+ }
399
+ _onCancelItem(item, response, status, headers) {
400
+ item._onCancel(response, status, headers);
401
+ this.onCancelItem(item, response, status, headers);
402
+ }
403
+ }
404
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWRlci5jbGFzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvbmcyLWZpbGUtdXBsb2FkL2ZpbGUtdXBsb2FkL2ZpbGUtdXBsb2FkZXIuY2xhc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUU3QyxTQUFTLE1BQU0sQ0FBQyxLQUFVO0lBQ3hCLE9BQU8sQ0FBQyxJQUFJLElBQUksS0FBSyxZQUFZLElBQUksQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFxQ0QsTUFBTSxPQUFPLFlBQVk7SUF3QnZCLFlBQVksT0FBNEI7UUFyQnhDLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLFVBQUssR0FBZSxFQUFFLENBQUM7UUFDdkIsYUFBUSxHQUFHLENBQUMsQ0FBQztRQUNiLGVBQVUsR0FBRyxDQUFDLENBQUM7UUFLZixZQUFPLEdBQXdCO1lBQzdCLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLE9BQU8sRUFBRSxJQUFJO1lBQ2IsT0FBTyxFQUFFLEVBQUU7WUFDWCxpQkFBaUIsRUFBRSxLQUFLO1lBQ3hCLGdCQUFnQixFQUFFLEtBQUs7WUFDdkIsa0JBQWtCLEVBQUUsQ0FBQyxJQUFjLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLO1lBQ2xELHlCQUF5QixFQUFFLEtBQUs7WUFDaEMsR0FBRyxFQUFFLEVBQUU7U0FDUixDQUFDO1FBS0EsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7SUFDN0MsQ0FB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QUFjLEVBQUUsT0FBOEI7UUFDdEcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDckQsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGaWxlTGlrZU9iamVjdCB9IGZyb20gJy4vZmlsZS1saWtlLW9iamVjdC5jbGFzcyc7XG5pbXBvcnQgeyBGaWxlSXRlbSB9IGZyb20gJy4vZmlsZS1pdGVtLmNsYXNzJztcbmltcG9ydCB7IEZpbGVUeXBlIH0gZnJvbSAnLi9maWxlLXR5cGUuY2xhc3MnO1xuXG5mdW5jdGlvbiBpc0ZpbGUodmFsdWU6IGFueSk6IGJvb2xlYW4ge1xuICByZXR1cm4gKEZpbGUgJiYgdmFsdWUgaW5zdGFuY2VvZiBGaWxlKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIZWFkZXJzIHtcbiAgbmFtZTogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlZFJlc3BvbnNlSGVhZGVycyB7IFsgaGVhZGVyRmllbGROYW1lOiBzdHJpbmcgXTogc3RyaW5nIH1cblxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJGdW5jdGlvbiB7XG4gIG5hbWU6IHN0cmluZztcbiAgZm4oaXRlbTogRmlsZUxpa2VPYmplY3QsIG9wdGlvbnM/OiBGaWxlVXBsb2FkZXJPcHRpb25zKTogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGaWxlVXBsb2FkZXJPcHRpb25zIHtcbiAgYWxsb3dlZE1pbWVUeXBlPzogc3RyaW5nW107XG4gIGFsbG93ZWRGaWxlVHlwZT86IHN0cmluZ1tdO1xuICBhdXRvVXBsb2FkPzogYm9vbGVhbjtcbiAgaXNIVE1MNT86IGJvb2xlYW47XG4gIGZpbHRlcnM/OiBGaWx0ZXJGdW5jdGlvbltdO1xuICBoZWFkZXJzPzogSGVhZGVyc1tdO1xuICBtZXRob2Q/OiBzdHJpbmc7XG4gIGF1dGhUb2tlbj86IHN0cmluZztcbiAgbWF4RmlsZVNpemU/OiBudW1iZXI7XG4gIHF1ZXVlTGltaXQ/OiBudW1iZXI7XG4gIHJlbW92ZUFmdGVyVXBsb2FkPzogYm9vbGVhbjtcbiAgdXJsOiBzdHJpbmc7XG4gIGRpc2FibGVNdWx0aXBhcnQ/OiBib29sZWFuO1xuICBpdGVtQWxpYXM/OiBzdHJpbmc7XG4gIGF1dGhUb2tlbkhlYWRlcj86IHN0cmluZztcbiAgYWRkaXRpb25hbFBhcmFtZXRlcj86IHsgWyBrZXk6IHN0cmluZyBdOiBhbnkgfTtcbiAgcGFyYW1ldGVyc0JlZm9yZUZpbGVzPzogYm9vbGVhbjtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHlwZXNcbiAgZm9ybWF0RGF0YUZ1bmN0aW9uPzogRnVuY3Rpb247XG4gIGZvcm1hdERhdGFGdW5jdGlvbklzQXN5bmM/OiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgRmlsZVVwbG9hZGVyIHtcblxuICBhdXRoVG9rZW4/OiBzdHJpbmc7XG4gIGlzVXBsb2FkaW5nID0gZmFsc2U7XG4gIHF1ZXVlOiBGaWxlSXRlbVtdID0gW107XG4gIHByb2dyZXNzID0gMDtcbiAgX25leHRJbmRleCA9IDA7XG4gIGF1dG9VcGxvYWQ6IGFueTtcbiAgYXV0aFRva2VuSGVhZGVyPzogc3RyaW5nO1xuICByZXNwb25zZTogRXZlbnRFbWl0dGVyPGFueT47XG5cbiAgb3B0aW9uczogRmlsZVVwbG9hZGVyT3B0aW9ucyA9IHtcbiAgICBhdXRvVXBsb2FkOiBmYWxzZSxcbiAgICBpc0hUTUw1OiB0cnVlLFxuICAgIGZpbHRlcnM6IFtdLFxuICAgIHJlbW92ZUFmdGVyVXBsb2FkOiBmYWxzZSxcbiAgICBkaXNhYmxlTXVsdGlwYXJ0OiBmYWxzZSxcbiAgICBmb3JtYXREYXRhRnVuY3Rpb246IChpdGVtOiBGaWxlSXRlbSkgPT4gaXRlbS5fZmlsZSxcbiAgICBmb3JtYXREYXRhRnVuY3Rpb25Jc0FzeW5jOiBmYWxzZSxcbiAgICB1cmw6ICcnXG4gIH07XG5cbiAgcHJvdGVjdGVkIF9mYWlsRmlsdGVySW5kZXg/OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogRmlsZVVwbG9hZGVyT3B0aW9ucykge1xuICAgIHRoaXMuc2V0T3B0aW9ucyhvcHRpb25zKTtcbiAgICB0aGlzLnJlc3BvbnNlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIH1cblxuICBzZXRPcHRpb25zKG9wdGlvbnM6IEZpbGVVcGxvYWRlck9wdGlvbnMpOiB2b2lkIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHRoaXMub3B0aW9ucywgb3B0aW9ucyk7XG5cbiAgICB0aGlzLmF1dGhUb2tlbiA9IHRoaXMub3B0aW9ucy5hdXRoVG9rZW47XG4gICAgdGhpcy5hdXRoVG9rZW5IZWFkZXIgPSB0aGlzLm9wdGlvbnMuYXV0aFRva2VuSGVhZGVyIHx8ICdBdXRob3JpemF0aW9uJztcbiAgICB0aGlzLmF1dG9VcGxvYWQgPSB0aGlzLm9wdGlvbnMuYXV0b1VwbG9hZDtcbiAgICB0aGlzLm9wdGlvbnMuZmlsdGVycz8udW5zaGlmdCh7IG5hbWU6ICdxdWV1ZUxpbWl0JywgZm46IHRoaXMuX3F1ZXVlTGltaXRGaWx0ZXIgfSk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLm1heEZpbGVTaXplKSB7XG4gICAgICB0aGlzLm9wdGlvbnMuZmlsdGVycz8udW5zaGlmdCh7IG5hbWU6ICdmaWxlU2l6ZScsIGZuOiB0aGlzLl9maWxlU2l6ZUZpbHRlciB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmFsbG93ZWRGaWxlVHlwZSkge1xuICAgICAgdGhpcy5vcHRpb25zLmZpbHRlcnM/LnVuc2hpZnQoeyBuYW1lOiAnZmlsZVR5cGUnLCBmbjogdGhpcy5fZmlsZVR5cGVGaWx0ZXIgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hbGxvd2VkTWltZVR5cGUpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5maWx0ZXJzPy51bnNoaWZ0KHsgbmFtZTogJ21pbWVUeXBlJywgZm46IHRoaXMuX21pbWVUeXBlRmlsdGVyIH0pO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5xdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5xdWV1ZVsgaSBdLnVybCA9IHRoaXMub3B0aW9ucy51cmw7XG4gICAgfVxuICB9XG5cbiAgYWRkVG9RdWV1ZShmaWxlczogRmlsZVtdLCBfb3B0aW9ucz86IEZpbGVVcGxvYWRlck9wdGlvbnMsIGZpbHRlcnM/OiBbXSB8IHN0cmluZyk6IHZvaWQge1xuICAgIGxldCBvcHRpb25zID0gX29wdGlvbnM7XG4gICAgY29uc3QgbGlzdDogRmlsZVtdID0gW107XG4gICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICBsaXN0LnB1c2goZmlsZSk7XG4gICAgfVxuICAgIGNvbnN0IGFycmF5T2ZGaWx0ZXJzID0gdGhpcy5fZ2V0RmlsdGVycyhmaWx0ZXJzKTtcbiAgICBjb25zdCBjb3VudCA9IHRoaXMucXVldWUubGVuZ3RoO1xuICAgIGNvbnN0IGFkZGVkRmlsZUl0ZW1zOiBGaWxlSXRlbVtdID0gW107XG4gICAgbGlzdC5tYXAoKHNvbWU6IEZpbGUpID0+IHtcbiAgICAgIGlmICghb3B0aW9ucykge1xuICAgICAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0ZW1wID0gbmV3IEZpbGVMaWtlT2JqZWN0KHNvbWUpO1xuICAgICAgaWYgKHRoaXMuX2lzVmFsaWRGaWxlKHRlbXAsIGFycmF5T2ZGaWx0ZXJzLCBvcHRpb25zKSkge1xuICAgICAgICBjb25zdCBmaWxlSXRlbSA9IG5ldyBGaWxlSXRlbSh0aGlzLCBzb21lLCBvcHRpb25zKTtcbiAgICAgICAgYWRkZWRGaWxlSXRlbXMucHVzaChmaWxlSXRlbSk7XG4gICAgICAgIHRoaXMucXVldWUucHVzaChmaWxlSXRlbSk7XG4gICAgICAgIHRoaXMuX29uQWZ0ZXJBZGRpbmdGaWxlKGZpbGVJdGVtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5fZmFpbEZpbHRlckluZGV4ID09PSAnbnVtYmVyJyAmJiB0aGlzLl9mYWlsRmlsdGVySW5kZXggPj0gMCkge1xuICAgICAgICAgIGNvbnN0IGZpbHRlciA9IGFycmF5T2ZGaWx0ZXJzWyB0aGlzLl9mYWlsRmlsdGVySW5kZXggXTtcbiAgICAgICAgICB0aGlzLl9vbldoZW5BZGRpbmdGaWxlRmFpbGVkKHRlbXAsIGZpbHRlciwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAodGhpcy5xdWV1ZS5sZW5ndGggIT09IGNvdW50KSB7XG4gICAgICB0aGlzLl9vbkFmdGVyQWRkaW5nQWxsKGFkZGVkRmlsZUl0ZW1zKTtcbiAgICAgIHRoaXMucHJvZ3Jlc3MgPSB0aGlzLl9nZXRUb3RhbFByb2dyZXNzKCk7XG4gICAgfVxuICAgIHRoaXMuX3JlbmRlcigpO1xuICAgIGlmICh0aGlzLm9wdGlvbnMuYXV0b1VwbG9hZCkge1xuICAgICAgdGhpcy51cGxvYWRBbGwoKTtcbiAgICB9XG4gIH1cblxuICByZW1vdmVGcm9tUXVldWUodmFsdWU6IEZpbGVJdGVtKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmdldEluZGV4T2ZJdGVtKHZhbHVlKTtcbiAgICBjb25zdCBpdGVtID0gdGhpcy5xdWV1ZVsgaW5kZXggXTtcbiAgICBpZiAoaXRlbS5pc1VwbG9hZGluZykge1xuICAgICAgaXRlbS5jYW5jZWwoKTtcbiAgICB9XG4gICAgdGhpcy5xdWV1ZS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHRoaXMucHJvZ3Jlc3MgPSB0aGlzLl9nZXRUb3RhbFByb2dyZXNzKCk7XG4gIH1cblxuICBjbGVhclF1ZXVlKCk6IHZvaWQge1xuICAgIHdoaWxlICh0aGlzLnF1ZXVlLmxlbmd0aCkge1xuICAgICAgdGhpcy5xdWV1ZVsgMCBdLnJlbW92ZSgpO1xuICAgIH1cbiAgICB0aGlzLnByb2dyZXNzID0gMDtcbiAgfVxuXG4gIHVwbG9hZEl0ZW0odmFsdWU6IEZpbGVJdGVtKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmdldEluZGV4T2ZJdGVtKHZhbHVlKTtcbiAgICBjb25zdCBpdGVtID0gdGhpcy5xdWV1ZVsgaW5kZXggXTtcbiAgICBjb25zdCB0cmFuc3BvcnQgPSB0aGlzLm9wdGlvbnMuaXNIVE1MNSA/ICdfeGhyVHJhbnNwb3J0JyA6ICdfaWZyYW1lVHJhbnNwb3J0JztcbiAgICBpdGVtLl9wcmVwYXJlVG9VcGxvYWRpbmcoKTtcbiAgICBpZiAodGhpcy5pc1VwbG9hZGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmlzVXBsb2FkaW5nID0gdHJ1ZTtcbiAgICAodGhpcyBhcyBhbnkpWyB0cmFuc3BvcnQgXShpdGVtKTtcbiAgfVxuXG4gIGNhbmNlbEl0ZW0odmFsdWU6IEZpbGVJdGVtKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmdldEluZGV4T2ZJdGVtKHZhbHVlKTtcbiAgICBjb25zdCBpdGVtID0gdGhpcy5xdWV1ZVsgaW5kZXggXTtcbiAgICBjb25zdCBwcm9wID0gdGhpcy5vcHRpb25zLmlzSFRNTDUgPyBpdGVtLl94aHIgOiBpdGVtLl9mb3JtO1xuICAgIGlmIChpdGVtICYmIGl0ZW0uaXNVcGxvYWRpbmcpIHtcbiAgICAgIHByb3AuYWJvcnQoKTtcbiAgICB9XG4gIH1cblxuICB1cGxvYWRBbGwoKTogdm9pZCB7XG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLmdldE5vdFVwbG9hZGVkSXRlbXMoKS5maWx0ZXIoKGl0ZW06IEZpbGVJdGVtKSA9PiAhaXRlbS5pc1VwbG9hZGluZyk7XG4gICAgaWYgKCFpdGVtcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaXRlbXMubWFwKChpdGVtOiBGaWxlSXRlbSkgPT4gaXRlbS5fcHJlcGFyZVRvVXBsb2FkaW5nKCkpO1xuICAgIGl0ZW1zWyAwIF0udXBsb2FkKCk7XG4gIH1cblxuICBjYW5jZWxBbGwoKTogdm9pZCB7XG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLmdldE5vdFVwbG9hZGVkSXRlbXMoKTtcbiAgICBpdGVtcy5tYXAoKGl0ZW06IEZpbGVJdGVtKSA9PiBpdGVtLmNhbmNlbCgpKTtcbiAgfVxuXG4gIGlzRmlsZSh2YWx1ZTogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzRmlsZSh2YWx1ZSk7XG4gIH1cblxuICBpc0ZpbGVMaWtlT2JqZWN0KHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBGaWxlTGlrZU9iamVjdDtcbiAgfVxuXG4gIGdldEluZGV4T2ZJdGVtKHZhbHVlOiBhbnkpOiBudW1iZXIge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInID8gdmFsdWUgOiB0aGlzLnF1ZXVlLmluZGV4T2YodmFsdWUpO1xuICB9XG5cbiAgZ2V0Tm90VXBsb2FkZWRJdGVtcygpOiBhbnlbXSB7XG4gICAgcmV0dXJuIHRoaXMucXVldWUuZmlsdGVyKChpdGVtOiBGaWxlSXRlbSkgPT4gIWl0ZW0uaXNVcGxvYWRlZCk7XG4gIH1cblxuICBnZXRSZWFkeUl0ZW1zKCk6IGFueVtdIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZVxuICAgICAgLmZpbHRlcigoaXRlbTogRmlsZUl0ZW0pID0+IChpdGVtLmlzUmVhZHkgJiYgIWl0ZW0uaXNVcGxvYWRpbmcpKVxuICAgICAgLnNvcnQoKGl0ZW0xOiBhbnksIGl0ZW0yOiBhbnkpID0+IGl0ZW0xLmluZGV4IC0gaXRlbTIuaW5kZXgpO1xuICB9XG5cbiAgb25BZnRlckFkZGluZ0FsbChmaWxlSXRlbXM6IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIHsgZmlsZUl0ZW1zIH07XG4gIH1cblxuICBvbkJ1aWxkSXRlbUZvcm0oZmlsZUl0ZW06IEZpbGVJdGVtLCBmb3JtOiBhbnkpOiBhbnkge1xuICAgIHJldHVybiB7IGZpbGVJdGVtLCBmb3JtIH07XG4gIH1cblxuICBvbkFmdGVyQWRkaW5nRmlsZShmaWxlSXRlbTogRmlsZUl0ZW0pOiBhbnkge1xuICAgIHJldHVybiB7IGZpbGVJdGVtIH07XG4gIH1cblxuICBvbldoZW5BZGRpbmdGaWxlRmFpbGVkKGl0ZW06IEZpbGVMaWtlT2JqZWN0LCBmaWx0ZXI6IGFueSwgb3B0aW9uczogYW55KTogYW55IHtcbiAgICByZXR1cm4geyBpdGVtLCBmaWx0ZXIsIG9wdGlvbnMgfTtcbiAgfVxuXG4gIG9uQmVmb3JlVXBsb2FkSXRlbShmaWxlSXRlbTogRmlsZUl0ZW0pOiBhbnkge1xuICAgIHJldHVybiB7IGZpbGVJdGVtIH07XG4gIH1cblxuICBvblByb2dyZXNzSXRlbShmaWxlSXRlbTogRmlsZUl0ZW0sIHByb2dyZXNzOiBhbnkpOiBhbnkge1xuICAgIHJldHVybiB7IGZpbGVJdGVtLCBwcm9ncmVzcyB9O1xuICB9XG5cbiAgb25Qcm9ncmVzc0FsbChwcm9ncmVzczogYW55KTogYW55IHtcbiAgICByZXR1cm4geyBwcm9ncmVzcyB9O1xuICB9XG5cbiAgb25TdWNjZXNzSXRlbShpdGVtOiBGaWxlSXRlbSwgcmVzcG9uc2U6IHN0cmluZywgc3RhdHVzOiBudW1iZXIsIGhlYWRlcnM6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyk6IGFueSB7XG4gICAgcmV0dXJuIHsgaXRlbSwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyB9O1xuICB9XG5cbiAgb25FcnJvckl0ZW0oaXRlbTogRmlsZUl0ZW0sIHJlc3BvbnNlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiBhbnkge1xuICAgIHJldHVybiB7IGl0ZW0sIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMgfTtcbiAgfVxuXG4gIG9uQ2FuY2VsSXRlbShpdGVtOiBGaWxlSXRlbSwgcmVzcG9uc2U6IHN0cmluZywgc3RhdHVzOiBudW1iZXIsIGhlYWRlcnM6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyk6IGFueSB7XG4gICAgcmV0dXJuIHsgaXRlbSwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyB9O1xuICB9XG5cbiAgb25Db21wbGV0ZUl0ZW0oaXRlbTogRmlsZUl0ZW0sIHJlc3BvbnNlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiBhbnkge1xuICAgIHJldHVybiB7IGl0ZW0sIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMgfTtcbiAgfVxuXG4gIG9uQ29tcGxldGVBbGwoKTogYW55IHtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9XG5cbiAgX21pbWVUeXBlRmlsdGVyKGl0ZW06IEZpbGVMaWtlT2JqZWN0KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEoaXRlbT8udHlwZSAmJiB0aGlzLm9wdGlvbnMuYWxsb3dlZE1pbWVUeXBlICYmIHRoaXMub3B0aW9ucy5hbGxvd2VkTWltZVR5cGU/LmluZGV4T2YoaXRlbS50eXBlKSA9PT0gLTEpO1xuICB9XG5cbiAgX2ZpbGVTaXplRmlsdGVyKGl0ZW06IEZpbGVMaWtlT2JqZWN0KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEodGhpcy5vcHRpb25zLm1heEZpbGVTaXplICYmIGl0ZW0uc2l6ZSA+IHRoaXMub3B0aW9ucy5tYXhGaWxlU2l6ZSk7XG4gIH1cblxuICBfZmlsZVR5cGVGaWx0ZXIoaXRlbTogRmlsZUxpa2VPYmplY3QpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISh0aGlzLm9wdGlvbnMuYWxsb3dlZEZpbGVUeXBlICYmXG4gICAgICB0aGlzLm9wdGlvbnMuYWxsb3dlZEZpbGVUeXBlLmluZGV4T2YoRmlsZVR5cGUuZ2V0TWltZUNsYXNzKGl0ZW0pKSA9PT0gLTEpO1xuICB9XG5cbiAgX29uRXJyb3JJdGVtKGl0ZW06IEZpbGVJdGVtLCByZXNwb25zZTogc3RyaW5nLCBzdGF0dXM6IG51bWJlciwgaGVhZGVyczogUGFyc2VkUmVzcG9uc2VIZWFkZXJzKTogdm9pZCB7XG4gICAgaXRlbS5fb25FcnJvcihyZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzKTtcbiAgICB0aGlzLm9uRXJyb3JJdGVtKGl0ZW0sIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMpO1xuICB9XG5cbiAgX29uQ29tcGxldGVJdGVtKGl0ZW06IEZpbGVJdGVtLCByZXNwb25zZTogc3RyaW5nLCBzdGF0dXM6IG51bWJlciwgaGVhZGVyczogUGFyc2VkUmVzcG9uc2VIZWFkZXJzKTogdm9pZCB7XG4gICAgaXRlbS5fb25Db21wbGV0ZShyZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzKTtcbiAgICB0aGlzLm9uQ29tcGxldGVJdGVtKGl0ZW0sIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMpO1xuICAgIGNvbnN0IG5leHRJdGVtID0gdGhpcy5nZXRSZWFkeUl0ZW1zKClbIDAgXTtcbiAgICB0aGlzLmlzVXBsb2FkaW5nID0gZmFsc2U7XG4gICAgaWYgKG5leHRJdGVtKSB7XG4gICAgICBuZXh0SXRlbS51cGxvYWQoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm9uQ29tcGxldGVBbGwoKTtcbiAgICB0aGlzLnByb2dyZXNzID0gdGhpcy5fZ2V0VG90YWxQcm9ncmVzcygpO1xuICAgIHRoaXMuX3JlbmRlcigpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9oZWFkZXJzR2V0dGVyKHBhcnNlZEhlYWRlcnM6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyk6IGFueSB7XG4gICAgcmV0dXJuIChuYW1lOiBhbnkpOiBhbnkgPT4ge1xuICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlZEhlYWRlcnNbIG5hbWUudG9Mb3dlckNhc2UoKSBdIHx8IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBhcnNlZEhlYWRlcnM7XG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfeGhyVHJhbnNwb3J0KGl0ZW06IEZpbGVJdGVtKTogYW55IHtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tdGhpcy1hc3NpZ25tZW50XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgY29uc3QgeGhyID0gaXRlbS5feGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgbGV0IHNlbmRhYmxlOiBhbnk7XG4gICAgdGhpcy5fb25CZWZvcmVVcGxvYWRJdGVtKGl0ZW0pO1xuXG4gICAgaWYgKHR5cGVvZiBpdGVtLl9maWxlLnNpemUgIT09ICdudW1iZXInKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgZmlsZSBzcGVjaWZpZWQgaXMgbm8gbG9uZ2VyIHZhbGlkJyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5vcHRpb25zLmRpc2FibGVNdWx0aXBhcnQpIHtcbiAgICAgIHNlbmRhYmxlID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICB0aGlzLl9vbkJ1aWxkSXRlbUZvcm0oaXRlbSwgc2VuZGFibGUpO1xuICAgICAgY29uc3QgYXBwZW5kRmlsZSA9ICgpID0+IHNlbmRhYmxlLmFwcGVuZChpdGVtLmFsaWFzLCBpdGVtLl9maWxlLCBpdGVtLmZpbGUubmFtZSk7XG4gICAgICBpZiAoIXRoaXMub3B0aW9ucy5wYXJhbWV0ZXJzQmVmb3JlRmlsZXMpIHtcbiAgICAgICAgYXBwZW5kRmlsZSgpO1xuICAgICAgfVxuXG4gICAgICAvLyBGb3IgQVdTLCBBZGRpdGlvbmFsIFBhcmFtZXRlcnMgbXVzdCBjb21lIEJFRk9SRSBGaWxlc1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5hZGRpdGlvbmFsUGFyYW1ldGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5vcHRpb25zLmFkZGl0aW9uYWxQYXJhbWV0ZXIpLmZvckVhY2goKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgbGV0IHBhcmFtVmFsID0gdGhpcy5vcHRpb25zLmFkZGl0aW9uYWxQYXJhbWV0ZXI/Llsga2V5IF07XG4gICAgICAgICAgLy8gQWxsb3cgYW4gYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gaW5jbHVkZSB0aGUgZmlsZW5hbWVcbiAgICAgICAgICBpZiAodHlwZW9mIHBhcmFtVmFsID09PSAnc3RyaW5nJyAmJiBwYXJhbVZhbC5pbmRleE9mKCd7e2ZpbGVfbmFtZX19JykgPj0gMCAmJiBpdGVtLmZpbGU/Lm5hbWUpIHtcbiAgICAgICAgICAgIHBhcmFtVmFsID0gcGFyYW1WYWwucmVwbGFjZSgne3tmaWxlX25hbWV9fScsIGl0ZW0uZmlsZS5uYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VuZGFibGUuYXBwZW5kKGtleSwgcGFyYW1WYWwpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFwcGVuZEZpbGUgJiYgdGhpcy5vcHRpb25zLnBhcmFtZXRlcnNCZWZvcmVGaWxlcykge1xuICAgICAgICBhcHBlbmRGaWxlKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuZm9ybWF0RGF0YUZ1bmN0aW9uKSB7XG4gICAgICAgIHNlbmRhYmxlID0gdGhpcy5vcHRpb25zLmZvcm1hdERhdGFGdW5jdGlvbihpdGVtKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB4aHIudXBsb2FkLm9ucHJvZ3Jlc3MgPSAoZXZlbnQ6IGFueSkgPT4ge1xuICAgICAgY29uc3QgcHJvZ3Jlc3MgPSBNYXRoLnJvdW5kKGV2ZW50Lmxlbmd0aENvbXB1dGFibGUgPyBldmVudC5sb2FkZWQgKiAxMDAgLyBldmVudC50b3RhbCA6IDApO1xuICAgICAgdGhpcy5fb25Qcm9ncmVzc0l0ZW0oaXRlbSwgcHJvZ3Jlc3MpO1xuICAgIH07XG4gICAgeGhyLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGhlYWRlcnMgPSB0aGlzLl9wYXJzZUhlYWRlcnMoeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gdGhpcy5fdHJhbnNmb3JtUmVzcG9uc2UoeGhyLnJlc3BvbnNlKTtcbiAgICAgIGNvbnN0IGdpc3QgPSB0aGlzLl9pc1N1Y2Nlc3NDb2RlKHhoci5zdGF0dXMpID8gJ1N1Y2Nlc3MnIDogJ0Vycm9yJztcbiAgICAgIGNvbnN0IG1ldGhvZCA9IGBfb24ke2dpc3R9SXRlbWA7XG4gICAgICAodGhpcyBhcyBhbnkpWyBtZXRob2QgXShpdGVtLCByZXNwb25zZSwgeGhyLnN0YXR1cywgaGVhZGVycyk7XG4gICAgICB0aGlzLl9vbkNvbXBsZXRlSXRlbShpdGVtLCByZXNwb25zZSwgeGhyLnN0YXR1cywgaGVhZGVycyk7XG4gICAgfTtcbiAgICB4aHIub25lcnJvciA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGhlYWRlcnMgPSB0aGlzLl9wYXJzZUhlYWRlcnMoeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gdGhpcy5fdHJhbnNmb3JtUmVzcG9uc2UoeGhyLnJlc3BvbnNlKTtcbiAgICAgIHRoaXMuX29uRXJyb3JJdGVtKGl0ZW0sIHJlc3BvbnNlLCB4aHIuc3RhdHVzLCBoZWFkZXJzKTtcbiAgICAgIHRoaXMuX29uQ29tcGxldGVJdGVtKGl0ZW0sIHJlc3BvbnNlLCB4aHIuc3RhdHVzLCBoZWFkZXJzKTtcbiAgICB9O1xuICAgIHhoci5vbmFib3J0ID0gKCkgPT4ge1xuICAgICAgY29uc3QgaGVhZGVycyA9IHRoaXMuX3BhcnNlSGVhZGVycyh4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLl90cmFuc2Zvcm1SZXNwb25zZSh4aHIucmVzcG9uc2UpO1xuICAgICAgdGhpcy5fb25DYW5jZWxJdGVtKGl0ZW0sIHJlc3BvbnNlLCB4aHIuc3RhdHVzLCBoZWFkZXJzKTtcbiAgICAgIHRoaXMuX29uQ29tcGxldGVJdGVtKGl0ZW0sIHJlc3BvbnNlLCB4aHIuc3RhdHVzLCBoZWFkZXJzKTtcbiAgICB9O1xuICAgIGlmIChpdGVtLm1ldGhvZCAmJiBpdGVtLnVybCkge1xuICAgICAgeGhyLm9wZW4oaXRlbS5tZXRob2QsIGl0ZW0udXJsLCB0cnVlKTtcbiAgICB9XG4gICAgeGhyLndpdGhDcmVkZW50aWFscyA9IGl0ZW0ud2l0aENyZWRlbnRpYWxzO1xuICAgIGlmICh0aGlzLm9wdGlvbnMuaGVhZGVycykge1xuICAgICAgZm9yIChjb25zdCBoZWFkZXIgb2YgdGhpcy5vcHRpb25zLmhlYWRlcnMpIHtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoaGVhZGVyLm5hbWUsIGhlYWRlci52YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpdGVtLmhlYWRlcnMubGVuZ3RoKSB7XG4gICAgICBmb3IgKGNvbnN0IGhlYWRlciBvZiBpdGVtLmhlYWRlcnMpIHtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoaGVhZGVyLm5hbWUsIGhlYWRlci52YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0aGlzLmF1dGhUb2tlbiAmJiB0aGlzLmF1dGhUb2tlbkhlYWRlcikge1xuICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIodGhpcy5hdXRoVG9rZW5IZWFkZXIsIHRoaXMuYXV0aFRva2VuKTtcbiAgICB9XG4gICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PSBYTUxIdHRwUmVxdWVzdC5ET05FKSB7XG4gICAgICAgIHRoYXQucmVzcG9uc2UuZW1pdCh4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGlmICh0aGlzLm9wdGlvbnMuZm9ybWF0RGF0YUZ1bmN0aW9uSXNBc3luYykge1xuICAgICAgc2VuZGFibGUudGhlbihcbiAgICAgICAgKHJlc3VsdDogYW55KSA9PiB4aHIuc2VuZChKU09OLnN0cmluZ2lmeShyZXN1bHQpKVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgeGhyLnNlbmQoc2VuZGFibGUpO1xuICAgIH1cbiAgICB0aGlzLl9yZW5kZXIoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfZ2V0VG90YWxQcm9ncmVzcyh2YWx1ZSA9IDApOiBudW1iZXIge1xuICAgIGlmICh0aGlzLm9wdGlvbnMucmVtb3ZlQWZ0ZXJVcGxvYWQpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgY29uc3Qgbm90VXBsb2FkZWQgPSB0aGlzLmdldE5vdFVwbG9hZGVkSXRlbXMoKS5sZW5ndGg7XG4gICAgY29uc3QgdXBsb2FkZWQgPSBub3RVcGxvYWRlZCA/IHRoaXMucXVldWUubGVuZ3RoIC0gbm90VXBsb2FkZWQgOiB0aGlzLnF1ZXVlLmxlbmd0aDtcbiAgICBjb25zdCByYXRpbyA9IDEwMCAvIHRoaXMucXVldWUubGVuZ3RoO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB2YWx1ZSAqIHJhdGlvIC8gMTAwO1xuICAgIHJldHVybiBNYXRoLnJvdW5kKHVwbG9hZGVkICogcmF0aW8gKyBjdXJyZW50KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfZ2V0RmlsdGVycyhmaWx0ZXJzPzogRmlsdGVyRnVuY3Rpb25bXSB8IHN0cmluZyk6IEZpbHRlckZ1bmN0aW9uW10gfCBbXSB7XG4gICAgaWYgKCFmaWx0ZXJzKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zPy5maWx0ZXJzIHx8IFtdO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheShmaWx0ZXJzKSkge1xuICAgICAgcmV0dXJuIGZpbHRlcnM7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZmlsdGVycyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IG5hbWVzID0gZmlsdGVycy5tYXRjaCgvW15cXHMsXSsvZyk7XG5cbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnM/LmZpbHRlcnMgfHwgW11cbiAgICAgICAgLmZpbHRlcigoZmlsdGVyOiBhbnkpID0+IG5hbWVzPy5pbmRleE9mKGZpbHRlci5uYW1lKSAhPT0gLTEpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm9wdGlvbnM/LmZpbHRlcnMgfHwgW107XG4gIH1cblxuICBwcm90ZWN0ZWQgX3JlbmRlcigpOiBhbnkge1xuICAgIHJldHVybiB2b2lkIDA7XG4gIH1cblxuICBwcm90ZWN0ZWQgX3F1ZXVlTGltaXRGaWx0ZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5xdWV1ZUxpbWl0ID09PSB1bmRlZmluZWQgfHwgdGhpcy5xdWV1ZS5sZW5ndGggPCB0aGlzLm9wdGlvbnMucXVldWVMaW1pdDtcbiAgfVxuXG4gIHByb3RlY3RlZCBfaXNWYWxpZEZpbGUoZmlsZTogRmlsZUxpa2VPYmplY3QsIGZpbHRlcnM6IEZpbHRlckZ1bmN0aW9uW10sIG9wdGlvbnM6IEZpbGVVcGxvYWRlck9wdGlvbnMpOiBib29sZWFuIHtcbiAgICB0aGlzLl9mYWlsRmlsdGVySW5kZXggPSAtMTtcblxuICAgIHJldHVybiAhZmlsdGVycy5sZW5ndGggPyB0cnVlIDogZmlsdGVycy5ldmVyeSgoZmlsdGVyOiBGaWx0ZXJGdW5jdGlvbikgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLl9mYWlsRmlsdGVySW5kZXggPT09ICdudW1iZXInKSB7XG4gICAgICAgIHRoaXMuX2ZhaWxGaWx0ZXJJbmRleCsrO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmlsdGVyLmZuLmNhbGwodGhpcywgZmlsZSwgb3B0aW9ucyk7XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2lzU3VjY2Vzc0NvZGUoc3RhdHVzOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwKSB8fCBzdGF0dXMgPT09IDMwNDtcbiAgfVxuXG4gIHByb3RlY3RlZCBfdHJhbnNmb3JtUmVzcG9uc2UocmVzcG9uc2U6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHJlc3BvbnNlO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9wYXJzZUhlYWRlcnMoaGVhZGVyczogc3RyaW5nKTogUGFyc2VkUmVzcG9uc2VIZWFkZXJzIHtcbiAgICBjb25zdCBwYXJzZWQ6IGFueSA9IHt9O1xuICAgIGxldCBrZXk6IGFueTtcbiAgICBsZXQgdmFsOiBhbnk7XG4gICAgbGV0IGk6IGFueTtcbiAgICBpZiAoIWhlYWRlcnMpIHtcbiAgICAgIHJldHVybiBwYXJzZWQ7XG4gICAgfVxuICAgIGhlYWRlcnMuc3BsaXQoJ1xcbicpLm1hcCgobGluZTogYW55KSA9PiB7XG4gICAgICBpID0gbGluZS5pbmRleE9mKCc6Jyk7XG4gICAgICBrZXkgPSBsaW5lLnNsaWNlKDAsIGkpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgdmFsID0gbGluZS5zbGljZShpICsgMSkudHJpbSgpO1xuICAgICAgaWYgKGtleSkge1xuICAgICAgICBwYXJzZWRbIGtleSBdID0gcGFyc2VkWyBrZXkgXSA/IHBhcnNlZFsga2V5IF0gKyAnLCAnICsgdmFsIDogdmFsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHBhcnNlZDtcbiAgfVxuXG4gIHByb3RlY3RlZCBfb25XaGVuQWRkaW5nRmlsZUZhaWxlZChpdGVtOiBGaWxlTGlrZU9iamVjdCwgZmlsdGVyOiBhbnksIG9wdGlvbnM6IGFueSk6IHZvaWQge1xuICAgIHRoaXMub25XaGVuQWRkaW5nRmlsZUZhaWxlZChpdGVtLCBmaWx0ZXIsIG9wdGlvbnMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vbkFmdGVyQWRkaW5nRmlsZShpdGVtOiBGaWxlSXRlbSk6IHZvaWQge1xuICAgIHRoaXMub25BZnRlckFkZGluZ0ZpbGUoaXRlbSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uQWZ0ZXJBZGRpbmdBbGwoaXRlbXM6IGFueSk6IHZvaWQge1xuICAgIHRoaXMub25BZnRlckFkZGluZ0FsbChpdGVtcyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uQmVmb3JlVXBsb2FkSXRlbShpdGVtOiBGaWxlSXRlbSk6IHZvaWQge1xuICAgIGl0ZW0uX29uQmVmb3JlVXBsb2FkKCk7XG4gICAgdGhpcy5vbkJlZm9yZVVwbG9hZEl0ZW0oaXRlbSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uQnVpbGRJdGVtRm9ybShpdGVtOiBGaWxlSXRlbSwgZm9ybTogYW55KTogdm9pZCB7XG4gICAgaXRlbS5fb25CdWlsZEZvcm0oZm9ybSk7XG4gICAgdGhpcy5vbkJ1aWxkSXRlbUZvcm0oaXRlbSwgZm9ybSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uUHJvZ3Jlc3NJdGVtKGl0ZW06IEZpbGVJdGVtLCBwcm9ncmVzczogYW55KTogdm9pZCB7XG4gICAgY29uc3QgdG90YWwgPSB0aGlzLl9nZXRUb3RhbFByb2dyZXNzKHByb2dyZXNzKTtcbiAgICB0aGlzLnByb2dyZXNzID0gdG90YWw7XG4gICAgaXRlbS5fb25Qcm9ncmVzcyhwcm9ncmVzcyk7XG4gICAgdGhpcy5vblByb2dyZXNzSXRlbShpdGVtLCBwcm9ncmVzcyk7XG4gICAgdGhpcy5vblByb2dyZXNzQWxsKHRvdGFsKTtcbiAgICB0aGlzLl9yZW5kZXIoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfb25TdWNjZXNzSXRlbShpdGVtOiBGaWxlSXRlbSwgcmVzcG9uc2U6IHN0cmluZywgc3RhdHVzOiBudW1iZXIsIGhlYWRlcnM6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyk6IHZvaWQge1xuICAgIGl0ZW0uX29uU3VjY2VzcyhyZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzKTtcbiAgICB0aGlzLm9uU3VjY2Vzc0l0ZW0oaXRlbSwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uQ2FuY2VsSXRlbShpdGVtOiBGaWxlSXRlbSwgcmVzcG9uc2U6IHN0cmluZywgc3RhdHVzOiBudW1iZXIsIGhlYWRlcnM6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyk6IHZvaWQge1xuICAgIGl0ZW0uX29uQ2FuY2VsKHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMpO1xuICAgIHRoaXMub25DYW5jZWxJdGVtKGl0ZW0sIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMpO1xuICB9XG59XG4iXX0=