@dotglitch/ngx-common 1.0.21 → 1.0.22
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/assets/mat-icons.d.ts +5705 -0
- package/components/filemanager/file-grid/file-grid.component.d.ts +97 -0
- package/components/filemanager/filemanager.component.d.ts +206 -0
- package/components/filemanager/folder-rename/folder-rename.component.d.ts +18 -0
- package/components/filemanager/helpers.d.ts +5 -0
- package/components/filemanager/icon-resolver.d.ts +13 -0
- package/components/filemanager/textextensions.d.ts +3 -0
- package/components/filemanager/toolbar/breadcrumb/breadcrumb.component.d.ts +16 -0
- package/components/filemanager/toolbar/icon-button/icon-button.component.d.ts +11 -0
- package/components/filemanager/toolbar/toolbar.component.d.ts +30 -0
- package/components/filemanager/tree-view/tree-view.component.d.ts +21 -0
- package/components/tabulator/tabulator.component.d.ts +30 -0
- package/components/types.d.ts +16 -0
- package/components/vscode/ts-type-resolver/dependency-parser.d.ts +6 -0
- package/components/vscode/ts-type-resolver/dummy-source-cache.d.ts +7 -0
- package/components/vscode/ts-type-resolver/import-resolver.d.ts +28 -0
- package/components/vscode/ts-type-resolver/main.d.ts +22 -0
- package/components/vscode/ts-type-resolver/recursion-depth.d.ts +11 -0
- package/components/vscode/ts-type-resolver/types.d.ts +179 -0
- package/components/vscode/ts-type-resolver/unpkg-source-resolver.d.ts +5 -0
- package/components/vscode/ts-type-resolver/update-emitter.d.ts +2 -0
- package/components/vscode/vscode.component.d.ts +57 -0
- package/esm2020/assets/mat-icons.mjs +5705 -0
- package/esm2020/components/filemanager/file-grid/file-grid.component.mjs +672 -0
- package/esm2020/components/filemanager/filemanager.component.mjs +301 -0
- package/esm2020/components/filemanager/folder-rename/folder-rename.component.mjs +57 -0
- package/esm2020/components/filemanager/helpers.mjs +26 -0
- package/esm2020/components/filemanager/icon-resolver.mjs +155 -0
- package/esm2020/components/filemanager/textextensions.mjs +294 -0
- package/esm2020/components/filemanager/toolbar/breadcrumb/breadcrumb.component.mjs +26 -0
- package/esm2020/components/filemanager/toolbar/icon-button/icon-button.component.mjs +34 -0
- package/esm2020/components/filemanager/toolbar/toolbar.component.mjs +163 -0
- package/esm2020/components/filemanager/tree-view/tree-view.component.mjs +53 -0
- package/esm2020/components/lazy-loader/lazy-loader.module.mjs +3 -3
- package/esm2020/components/lazy-loader/lazy-loader.service.mjs +1 -1
- package/esm2020/components/menu/menu.component.mjs +1 -2
- package/esm2020/components/tabulator/tabulator.component.mjs +92 -0
- package/esm2020/components/types.mjs +3 -0
- package/esm2020/components/vscode/ts-type-resolver/dependency-parser.mjs +91 -0
- package/esm2020/components/vscode/ts-type-resolver/dummy-source-cache.mjs +15 -0
- package/esm2020/components/vscode/ts-type-resolver/import-resolver.mjs +311 -0
- package/esm2020/components/vscode/ts-type-resolver/main.mjs +112 -0
- package/esm2020/components/vscode/ts-type-resolver/recursion-depth.mjs +21 -0
- package/esm2020/components/vscode/ts-type-resolver/types.mjs +14 -0
- package/esm2020/components/vscode/ts-type-resolver/unpkg-source-resolver.mjs +21 -0
- package/esm2020/components/vscode/ts-type-resolver/update-emitter.mjs +37 -0
- package/esm2020/components/vscode/vscode.component.mjs +230 -0
- package/esm2020/directives/menu.directive.mjs +19 -18
- package/esm2020/public-api.mjs +6 -1
- package/fesm2015/dotglitch-ngx-common-folder-rename.component-d039534b.mjs +79 -0
- package/fesm2015/dotglitch-ngx-common-folder-rename.component-d039534b.mjs.map +1 -0
- package/fesm2015/dotglitch-ngx-common.mjs +8360 -27
- package/fesm2015/dotglitch-ngx-common.mjs.map +1 -1
- package/fesm2020/dotglitch-ngx-common-folder-rename.component-ba3ebd0a.mjs +78 -0
- package/fesm2020/dotglitch-ngx-common-folder-rename.component-ba3ebd0a.mjs.map +1 -0
- package/fesm2020/dotglitch-ngx-common.mjs +8329 -26
- package/fesm2020/dotglitch-ngx-common.mjs.map +1 -1
- package/package.json +6 -2
- package/public-api.d.ts +4 -0
|
@@ -0,0 +1,672 @@
|
|
|
1
|
+
import { Component, EventEmitter, Output, Input, ViewChild, TemplateRef, SecurityContext } from '@angular/core';
|
|
2
|
+
import { MatTabsModule } from '@angular/material/tabs';
|
|
3
|
+
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
4
|
+
import { MatInputModule } from '@angular/material/input';
|
|
5
|
+
import { DatePipe, NgForOf, NgIf } from '@angular/common';
|
|
6
|
+
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
7
|
+
import { NgScrollbarModule } from 'ngx-scrollbar';
|
|
8
|
+
import { IconResolver } from '../icon-resolver';
|
|
9
|
+
import { TabulatorComponent } from '../../tabulator/tabulator.component';
|
|
10
|
+
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
11
|
+
import { uploadFile } from '../helpers';
|
|
12
|
+
import { MenuDirective, openMenu } from '../../../public-api';
|
|
13
|
+
import * as i0 from "@angular/core";
|
|
14
|
+
import * as i1 from "../../../public-api";
|
|
15
|
+
import * as i2 from "@angular/material/dialog";
|
|
16
|
+
import * as i3 from "../filemanager.component";
|
|
17
|
+
import * as i4 from "@angular/platform-browser";
|
|
18
|
+
import * as i5 from "ngx-scrollbar";
|
|
19
|
+
import * as i6 from "@angular/material/checkbox";
|
|
20
|
+
import * as i7 from "@angular/material/progress-bar";
|
|
21
|
+
import * as i8 from "@angular/cdk/scrolling";
|
|
22
|
+
const itemWidth = (80 + 20);
|
|
23
|
+
export class FileGridComponent {
|
|
24
|
+
set path(value) {
|
|
25
|
+
if (!value)
|
|
26
|
+
return;
|
|
27
|
+
if (this._path && this.config.navigateOnlyToDescendants) {
|
|
28
|
+
if (!value.startsWith('/'))
|
|
29
|
+
value = '/' + value;
|
|
30
|
+
if (!value.startsWith(this.config.path))
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
let prev = this._path;
|
|
34
|
+
this._path = value;
|
|
35
|
+
if (prev != value) {
|
|
36
|
+
this.pathChange.next(this.path);
|
|
37
|
+
if (this.config.apiSettings)
|
|
38
|
+
this.loadFolder();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
get path() { return this._path; }
|
|
42
|
+
performChecksum(path, digest) {
|
|
43
|
+
// this.windowManager.openWindow({
|
|
44
|
+
// appId: "checksum",
|
|
45
|
+
// data: { digest, path },
|
|
46
|
+
// workspace: this.windowRef.workspace,
|
|
47
|
+
// width: 600,
|
|
48
|
+
// height: 250
|
|
49
|
+
// });
|
|
50
|
+
}
|
|
51
|
+
get libConfig() { return this.fileManager.libConfig; }
|
|
52
|
+
constructor(fetch, keyboard, dialog, matDialog, fileManager, changeDetector, sanitizer) {
|
|
53
|
+
this.fetch = fetch;
|
|
54
|
+
this.keyboard = keyboard;
|
|
55
|
+
this.dialog = dialog;
|
|
56
|
+
this.matDialog = matDialog;
|
|
57
|
+
this.fileManager = fileManager;
|
|
58
|
+
this.changeDetector = changeDetector;
|
|
59
|
+
this.sanitizer = sanitizer;
|
|
60
|
+
this.pathChange = new EventEmitter();
|
|
61
|
+
this.config = {};
|
|
62
|
+
this.showHiddenFiles = false;
|
|
63
|
+
this.viewMode = "grid";
|
|
64
|
+
this.gridSize = "normal";
|
|
65
|
+
this.fileSelect = new EventEmitter();
|
|
66
|
+
this.fileDblClick = new EventEmitter();
|
|
67
|
+
this.folderSelect = new EventEmitter();
|
|
68
|
+
this.folderDblClick = new EventEmitter();
|
|
69
|
+
this.newTab = new EventEmitter();
|
|
70
|
+
this.loadFiles = new EventEmitter();
|
|
71
|
+
this.directoryContents = [];
|
|
72
|
+
this.selection = [];
|
|
73
|
+
this.selectionChange = new EventEmitter();
|
|
74
|
+
this.value = [];
|
|
75
|
+
this.valueChange = new EventEmitter();
|
|
76
|
+
this.sortedFolders = [];
|
|
77
|
+
this.sorters = {
|
|
78
|
+
"a-z": (a, b) => a.name > b.name ? 1 : -1,
|
|
79
|
+
"z-a": (a, b) => b.name > a.name ? 1 : -1,
|
|
80
|
+
"lastmod": (a, b) => b.stats.mtimeMs - a.stats.mtimeMs,
|
|
81
|
+
"firstmod": (a, b) => a.stats.mtimeMs - b.stats.mtimeMs,
|
|
82
|
+
"size": (a, b) => b.stats.size - a.stats.size,
|
|
83
|
+
"type": (a, b) => a.path.split('.').splice(-1, 1)[0] > b.path.split('.').splice(-1, 1)[0] ? 1 : -1
|
|
84
|
+
};
|
|
85
|
+
this.sortOrder = "a-z";
|
|
86
|
+
this.itemsPerRow = 6;
|
|
87
|
+
// If the current directory is inside of an archive
|
|
88
|
+
this.isArchive = true;
|
|
89
|
+
this.userIsDraggingFile = false;
|
|
90
|
+
this.draggingOver = false;
|
|
91
|
+
this.showLoader = false;
|
|
92
|
+
this.hideLoader = false;
|
|
93
|
+
this.columns = [
|
|
94
|
+
{ id: "name", label: "Name" },
|
|
95
|
+
{ id: "size", label: "Size" },
|
|
96
|
+
{ id: "type", label: "Type" },
|
|
97
|
+
{ id: "owner", label: "Owner" },
|
|
98
|
+
{ id: "group", label: "Group" },
|
|
99
|
+
{ id: "permissions", label: "Permissions" },
|
|
100
|
+
{ id: "location", label: "Location" },
|
|
101
|
+
{ id: "modified", label: "Modified" },
|
|
102
|
+
{ id: "modified--time", label: "Modified - Time" },
|
|
103
|
+
{ id: "accessed", label: "Accessed" },
|
|
104
|
+
{ id: "created", label: "Created" },
|
|
105
|
+
{ id: "recency", label: "Recency" },
|
|
106
|
+
{ id: "star", label: "Star" },
|
|
107
|
+
{ id: "detailed-type", label: "Detailed Type" },
|
|
108
|
+
];
|
|
109
|
+
this.cols = [
|
|
110
|
+
{ id: "name", label: "Name" },
|
|
111
|
+
{ id: "size", label: "Size" },
|
|
112
|
+
{ id: "modified", label: "Modified" },
|
|
113
|
+
{ id: "star", label: "Star" }
|
|
114
|
+
];
|
|
115
|
+
this.folderContextMenu = [
|
|
116
|
+
{
|
|
117
|
+
label: "New Folder",
|
|
118
|
+
// shortcutLabel: "Shift+Ctrl+N",
|
|
119
|
+
icon: "create_new_folder",
|
|
120
|
+
action: (data) => {
|
|
121
|
+
// console.log("New folder goodness");
|
|
122
|
+
// console.log(data);
|
|
123
|
+
this.dialog.open("folder-rename", "@dotglitch/ngx-web-components", {
|
|
124
|
+
inputs: { path: data?.path || this.path, name: data?.name || '', config: this.config }
|
|
125
|
+
}).then(r => this.loadFolder());
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
label: "Upload file",
|
|
130
|
+
// shortcutLabel: "Ctrl+D",
|
|
131
|
+
icon: "file_upload",
|
|
132
|
+
action: (evt) => uploadFile(this.fetch, this.config, this._path, evt ? (evt.path + evt.name) : null, this.fileManager.contextTags).then(res => {
|
|
133
|
+
this.loadFolder();
|
|
134
|
+
})
|
|
135
|
+
},
|
|
136
|
+
"separator",
|
|
137
|
+
// {
|
|
138
|
+
// isDisabled: (data) => true,
|
|
139
|
+
// label: "_P_aste",
|
|
140
|
+
// icon: "content_paste",
|
|
141
|
+
// action: (evt) => {
|
|
142
|
+
// }
|
|
143
|
+
// },
|
|
144
|
+
{
|
|
145
|
+
label: "Select _A_ll",
|
|
146
|
+
shortcutLabel: "Ctrl+A",
|
|
147
|
+
icon: "select_all",
|
|
148
|
+
action: (evt) => {
|
|
149
|
+
this.selection = this._sortFilter();
|
|
150
|
+
this.selectionText = this.getSelectionText();
|
|
151
|
+
this.selectionChange.next(this.selection);
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
// "separator",
|
|
155
|
+
// {
|
|
156
|
+
// label: "P_r_operties",
|
|
157
|
+
// icon: "find_in_page",
|
|
158
|
+
// action: (evt) => {
|
|
159
|
+
// }
|
|
160
|
+
// }
|
|
161
|
+
];
|
|
162
|
+
this.fileContextMenu = [];
|
|
163
|
+
this.nameCellFormatter = ((cell, formatterParams, onRendered) => {
|
|
164
|
+
// TODO: Sanitize?
|
|
165
|
+
const item = cell.getData();
|
|
166
|
+
return `
|
|
167
|
+
<span style="display: flex; align-items: center">
|
|
168
|
+
<img style="height: 24px; margin-right: 6px" src="${item['_icon'].path}"/>
|
|
169
|
+
<p style="margin: 0">${this.sanitizer.sanitize(SecurityContext.HTML, item['vanityName'] || item.name)}</p>
|
|
170
|
+
</span>
|
|
171
|
+
`;
|
|
172
|
+
}).bind(this);
|
|
173
|
+
this.iconResolver = new IconResolver(this.libConfig.assetPath);
|
|
174
|
+
// ctrl + a => select all
|
|
175
|
+
keyboard.onKeyCommand({
|
|
176
|
+
key: "a",
|
|
177
|
+
ctrl: true,
|
|
178
|
+
}).subscribe(evt => {
|
|
179
|
+
this.selection = this._sortFilter();
|
|
180
|
+
this.selectionText = this.getSelectionText();
|
|
181
|
+
this.selectionChange.next(this.selection);
|
|
182
|
+
});
|
|
183
|
+
// ctrl + c => copy file names to clipboard
|
|
184
|
+
keyboard.onKeyCommand({
|
|
185
|
+
key: "c",
|
|
186
|
+
ctrl: true,
|
|
187
|
+
}).subscribe(evt => {
|
|
188
|
+
});
|
|
189
|
+
// ctrl + h => toggle hidden files
|
|
190
|
+
keyboard.onKeyCommand({
|
|
191
|
+
key: "h",
|
|
192
|
+
ctrl: true,
|
|
193
|
+
interrupt: true
|
|
194
|
+
}).subscribe(evt => {
|
|
195
|
+
this.showHiddenFiles = !this.showHiddenFiles;
|
|
196
|
+
});
|
|
197
|
+
// F2 => Rename selected files
|
|
198
|
+
keyboard.onKeyCommand({
|
|
199
|
+
key: "f2",
|
|
200
|
+
}).subscribe(evt => {
|
|
201
|
+
// Rename selected file(s)
|
|
202
|
+
});
|
|
203
|
+
// Enter => Open selected files
|
|
204
|
+
keyboard.onKeyCommand({
|
|
205
|
+
key: "Enter",
|
|
206
|
+
}).subscribe(evt => {
|
|
207
|
+
const files = this.directoryContents.filter(dc => this.selection.find(i => i.name == dc.name));
|
|
208
|
+
// this.windowManager.openFiles(files as any);
|
|
209
|
+
});
|
|
210
|
+
// Delete => delete selected files
|
|
211
|
+
keyboard.onKeyCommand({
|
|
212
|
+
key: "delete",
|
|
213
|
+
}).subscribe(evt => {
|
|
214
|
+
const files = this.directoryContents.filter(dc => this.selection.find(i => i.name == dc.name));
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
async ngOnInit() {
|
|
218
|
+
// this.loadFolder();
|
|
219
|
+
}
|
|
220
|
+
ngAfterViewInit() {
|
|
221
|
+
this.fileContextMenu = [
|
|
222
|
+
{
|
|
223
|
+
label: "Download",
|
|
224
|
+
icon: "download",
|
|
225
|
+
action: (file) => {
|
|
226
|
+
let target = `${window.origin}${this.config.apiSettings.downloadEntryUrl}`;
|
|
227
|
+
let path = file.path + file.name;
|
|
228
|
+
if (file.kind == "directory" && !path.endsWith('/'))
|
|
229
|
+
path += "/";
|
|
230
|
+
target += `${target.includes('?') ? '&' : '?'}path=${path}&ngsw-bypass=true`;
|
|
231
|
+
console.log(target);
|
|
232
|
+
// window.open(target);
|
|
233
|
+
var link = document.createElement("a");
|
|
234
|
+
link.download = file.name;
|
|
235
|
+
link.href = target;
|
|
236
|
+
link.click();
|
|
237
|
+
link.remove();
|
|
238
|
+
this.fileManager.fileDownload.next(file);
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
label: "Open in new Tab",
|
|
243
|
+
icon: "open_in_new",
|
|
244
|
+
isVisible: (data) => data.kind == "directory",
|
|
245
|
+
action: (data) => {
|
|
246
|
+
this.fileManager.initTab(data.path + data.name);
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
// {
|
|
250
|
+
// label: "Open with Application...",
|
|
251
|
+
// isVisible: (data) => data.kind == "file",
|
|
252
|
+
// shortcutLabel: "Ctrl+D",
|
|
253
|
+
// action: (evt) => {
|
|
254
|
+
// },
|
|
255
|
+
// },
|
|
256
|
+
"separator",
|
|
257
|
+
// {
|
|
258
|
+
// label: "Cut",
|
|
259
|
+
// icon: "content_cut",
|
|
260
|
+
// isDisabled: data => true,
|
|
261
|
+
// action: (evt) => {
|
|
262
|
+
// },
|
|
263
|
+
// },
|
|
264
|
+
// {
|
|
265
|
+
// label: "Copy",
|
|
266
|
+
// icon: "file_copy",
|
|
267
|
+
// isDisabled: data => true,
|
|
268
|
+
// childrenResolver: () => new Promise(r => setTimeout(r, 500000))
|
|
269
|
+
// },
|
|
270
|
+
// {
|
|
271
|
+
// label: "Move To...",
|
|
272
|
+
// icon: "drive_file_move",
|
|
273
|
+
// shortcutLabel: "Ctrl+A",
|
|
274
|
+
// action: (evt) => {
|
|
275
|
+
// },
|
|
276
|
+
// },
|
|
277
|
+
// {
|
|
278
|
+
// label: "Copy To...",
|
|
279
|
+
// icon: "folder_copy",
|
|
280
|
+
// shortcutLabel: "Ctrl+A",
|
|
281
|
+
// action: (evt) => {
|
|
282
|
+
// },
|
|
283
|
+
// },
|
|
284
|
+
{
|
|
285
|
+
label: "Delete",
|
|
286
|
+
icon: "delete",
|
|
287
|
+
// shortcutLabel: "Del",
|
|
288
|
+
isVisible: data => !data.path.includes("#/"),
|
|
289
|
+
action: (evt) => {
|
|
290
|
+
const path = evt.path + evt.name;
|
|
291
|
+
const url = this.config.apiSettings.deleteEntryUrlTemplate
|
|
292
|
+
? this.config.apiSettings.deleteEntryUrlTemplate(path)
|
|
293
|
+
: this.config.apiSettings.deleteEntryUrl;
|
|
294
|
+
this.fetch.delete(url)
|
|
295
|
+
.then(() => this.loadFolder());
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
// {
|
|
299
|
+
// label: "Shred file",
|
|
300
|
+
// icon: "delete_forever",
|
|
301
|
+
// isVisible: data => !data.path.includes("#/"), // omit files in compressed dirs
|
|
302
|
+
// action: (evt) => {
|
|
303
|
+
// this.fetch.post(`/api/filesystem/delete?wipe=true`, { files: [evt.path + evt.name]})
|
|
304
|
+
// .then(() => this.loadFolder())
|
|
305
|
+
// },
|
|
306
|
+
// },
|
|
307
|
+
{
|
|
308
|
+
label: "Rename",
|
|
309
|
+
icon: "drive_file_rename_outline",
|
|
310
|
+
isVisible: data => !data.path.includes("#/"),
|
|
311
|
+
// shortcutLabel: "F2",
|
|
312
|
+
action: (data) => {
|
|
313
|
+
this.dialog.open("folder-rename", "@dotglitch/ngx-web-components", {
|
|
314
|
+
inputs: { path: data?.path || this.path, name: data?.name || '', config: this.config }
|
|
315
|
+
}).then(r => this.loadFolder());
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
// Extract Here
|
|
319
|
+
// Extract To...
|
|
320
|
+
// {
|
|
321
|
+
// label: "Extract Here",
|
|
322
|
+
// icon: "folder_zip",
|
|
323
|
+
// shortcutLabel: "Ctrl+A",
|
|
324
|
+
// isDisabled: (data) => !(data.kind == "file" && data.ext != ".zip" && isArchive(data)),
|
|
325
|
+
// action: (evt) => {
|
|
326
|
+
// // TODO
|
|
327
|
+
// },
|
|
328
|
+
// },
|
|
329
|
+
// {
|
|
330
|
+
// label: "Extract to...",
|
|
331
|
+
// icon: "folder_zip",
|
|
332
|
+
// shortcutLabel: "Ctrl+A",
|
|
333
|
+
// isDisabled: (data) => !(data.kind == "file" && data.ext != ".zip" && isArchive(data)),
|
|
334
|
+
// action: (evt) => {
|
|
335
|
+
// // TODO
|
|
336
|
+
// },
|
|
337
|
+
// },
|
|
338
|
+
// {
|
|
339
|
+
// label: "Compress...",
|
|
340
|
+
// icon: "folder_zip",
|
|
341
|
+
// shortcutLabel: "Ctrl+A",
|
|
342
|
+
// isDisabled: (data) => data.kind == "file",
|
|
343
|
+
// action: (evt) => {
|
|
344
|
+
// // TODO
|
|
345
|
+
// },
|
|
346
|
+
// },
|
|
347
|
+
{
|
|
348
|
+
label: "Checksum",
|
|
349
|
+
icon: "manage_search",
|
|
350
|
+
isDisabled: (data) => data.kind != "file",
|
|
351
|
+
children: [
|
|
352
|
+
{
|
|
353
|
+
label: "MD5",
|
|
354
|
+
action: (evt) => this.performChecksum(evt.path + evt.name, "md5"),
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
label: "SHA1",
|
|
358
|
+
action: (evt) => this.performChecksum(evt.path + evt.name, "sha1"),
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
label: "SHA256",
|
|
362
|
+
action: (evt) => this.performChecksum(evt.path + evt.name, "sha256"),
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
label: "SHA512",
|
|
366
|
+
action: (evt) => this.performChecksum(evt.path + evt.name, "sha512"),
|
|
367
|
+
},
|
|
368
|
+
],
|
|
369
|
+
isVisible: (data) => {
|
|
370
|
+
return false;
|
|
371
|
+
return !this.isArchive || data.kind == "file";
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
// {
|
|
375
|
+
// label: "Star",
|
|
376
|
+
// icon: "star",
|
|
377
|
+
// shortcutLabel: "Ctrl+A",
|
|
378
|
+
// action: (evt) => {
|
|
379
|
+
// },
|
|
380
|
+
// },
|
|
381
|
+
// "separator",
|
|
382
|
+
// {
|
|
383
|
+
// label: "P_r_operties",
|
|
384
|
+
// icon: "find_in_page",
|
|
385
|
+
// action: (evt) => {
|
|
386
|
+
// },
|
|
387
|
+
// }
|
|
388
|
+
];
|
|
389
|
+
}
|
|
390
|
+
async loadFolder() {
|
|
391
|
+
this.showLoader = true;
|
|
392
|
+
this.hideLoader = false;
|
|
393
|
+
const url = this.config.apiSettings.listEntriesUrlTemplate
|
|
394
|
+
? this.config.apiSettings.listEntriesUrlTemplate(this.path)
|
|
395
|
+
: this.config.apiSettings.listEntriesUrl;
|
|
396
|
+
this.fetch.post(url, { path: this.path, showHidden: this.showHiddenFiles })
|
|
397
|
+
.then((data) => {
|
|
398
|
+
const files = data?.files || [];
|
|
399
|
+
const dirs = data?.dirs || [];
|
|
400
|
+
const descriptors = files.concat(dirs);
|
|
401
|
+
descriptors.forEach(f => {
|
|
402
|
+
f['_icon'] = this.iconResolver.resolveIcon(f);
|
|
403
|
+
if (f.kind == "file") {
|
|
404
|
+
f['_ctime'] = new Date(f.stats?.ctimeMs)?.toLocaleString();
|
|
405
|
+
f['_mtime'] = new Date(f.stats?.mtimeMs)?.toLocaleString();
|
|
406
|
+
f['_size'] = this.bytesToString(f.stats?.size);
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
this.directoryContents = descriptors;
|
|
410
|
+
this._sortFilter();
|
|
411
|
+
this.resize();
|
|
412
|
+
this.loadFiles.next(descriptors);
|
|
413
|
+
if (this.sortedFolders.length > 0)
|
|
414
|
+
this.flowRows();
|
|
415
|
+
setTimeout(() => this.resize(), 250);
|
|
416
|
+
setTimeout(() => this.resize(), 500);
|
|
417
|
+
setTimeout(() => this.resize(), 1000);
|
|
418
|
+
setTimeout(() => this.resize(), 2500);
|
|
419
|
+
setTimeout(() => this.resize(), 5000);
|
|
420
|
+
})
|
|
421
|
+
.catch(e => console.error(e))
|
|
422
|
+
.finally(() => {
|
|
423
|
+
this.hideLoader = true;
|
|
424
|
+
setTimeout(() => {
|
|
425
|
+
this.showLoader = false;
|
|
426
|
+
}, 200);
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
flowRows() {
|
|
430
|
+
let filtered = this._sortFilter();
|
|
431
|
+
this.sortedFolders = [];
|
|
432
|
+
const num = Math.ceil(filtered.length / this.itemsPerRow);
|
|
433
|
+
const iterations = Math.min(num, 100);
|
|
434
|
+
for (let row = 0; row < iterations; row++) {
|
|
435
|
+
if (!this.sortedFolders[row])
|
|
436
|
+
this.sortedFolders[row] = [];
|
|
437
|
+
for (let i = row * this.itemsPerRow; i < (row + 1) * this.itemsPerRow && i < filtered.length; i++) {
|
|
438
|
+
this.sortedFolders[row].push(filtered[i]);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
onSelect(item, evt) {
|
|
443
|
+
evt.stopPropagation();
|
|
444
|
+
if (this.keyboard.isShiftPressed) {
|
|
445
|
+
let start = this.directoryContents.findIndex(i => i.name == this.selection.slice(-1, 1)[0].name);
|
|
446
|
+
let end = this.directoryContents.indexOf(item);
|
|
447
|
+
if (start == -1)
|
|
448
|
+
start = end;
|
|
449
|
+
let items = start > end
|
|
450
|
+
? this.directoryContents.slice(end, start + 1)
|
|
451
|
+
: this.directoryContents.slice(start, end + 1);
|
|
452
|
+
this.selection = items;
|
|
453
|
+
}
|
|
454
|
+
else if (this.keyboard.isCtrlPressed) {
|
|
455
|
+
if (!this.selection.includes(item))
|
|
456
|
+
this.selection.push(item);
|
|
457
|
+
else // Case that we selected the same item twice
|
|
458
|
+
this.selection.splice(this.selection.indexOf(item), 1);
|
|
459
|
+
}
|
|
460
|
+
else
|
|
461
|
+
this.selection = [item];
|
|
462
|
+
if (this.selection.length == 1) {
|
|
463
|
+
if (this.selection[0].kind == "directory")
|
|
464
|
+
this.folderSelect.next(this.selection[0]);
|
|
465
|
+
else
|
|
466
|
+
this.fileSelect.next(this.selection[0]);
|
|
467
|
+
}
|
|
468
|
+
this.selectionChange.next(this.selection);
|
|
469
|
+
this.selectionText = this.getSelectionText();
|
|
470
|
+
}
|
|
471
|
+
onItemClick(file) {
|
|
472
|
+
console.log(file, this);
|
|
473
|
+
if (file.kind == "directory") {
|
|
474
|
+
this.folderDblClick.next(file);
|
|
475
|
+
this.path = file.path + file.name;
|
|
476
|
+
}
|
|
477
|
+
// else if (file.ext == "zip") {
|
|
478
|
+
// this.fileDblClick.next(file);
|
|
479
|
+
// this.path = file.path + file.name;
|
|
480
|
+
// }
|
|
481
|
+
else {
|
|
482
|
+
this.fileDblClick.next(file);
|
|
483
|
+
this.fileSelect.next(file);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
onToggle(item, state) {
|
|
487
|
+
item['_value'] = state.checked;
|
|
488
|
+
// TODO: What causes this to be null when initialized with an array?
|
|
489
|
+
if (!this.value) {
|
|
490
|
+
this.value = [];
|
|
491
|
+
}
|
|
492
|
+
if (state.checked) {
|
|
493
|
+
this.value.push(item);
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
const i = this.value.findIndex(v => v == item);
|
|
497
|
+
if (i >= 0)
|
|
498
|
+
this.value.splice(i, 1);
|
|
499
|
+
}
|
|
500
|
+
this.valueChange.next(this.value);
|
|
501
|
+
}
|
|
502
|
+
async clearSelection() {
|
|
503
|
+
this.value = [];
|
|
504
|
+
this.valueChange.next(this.value);
|
|
505
|
+
this.tabulator?.table?.getRows().forEach(r => r.getElement().classList.remove('selected'));
|
|
506
|
+
}
|
|
507
|
+
_sortFilter() {
|
|
508
|
+
return this.directoryContents = this.directoryContents?.filter(d => d.kind == 'directory')
|
|
509
|
+
.concat(this.directoryContents?.filter(d => d.kind == 'file')
|
|
510
|
+
.sort(this.sorters[this.sortOrder]));
|
|
511
|
+
}
|
|
512
|
+
getSelectionText() {
|
|
513
|
+
const dirCount = this.selection.filter(s => s.kind == "directory").length;
|
|
514
|
+
const fileCount = this.selection.filter(s => s.kind == "file").length;
|
|
515
|
+
if (dirCount + fileCount == 0)
|
|
516
|
+
return "";
|
|
517
|
+
const totalSize = this.directoryContents
|
|
518
|
+
.filter(d => d.kind == "file")
|
|
519
|
+
.filter(d => this.selection?.find(i => i.name == d.name))
|
|
520
|
+
.map(d => d['stats'].size).reduce((a, b) => a + b, 0);
|
|
521
|
+
if (dirCount + fileCount == 1)
|
|
522
|
+
return `"${this.selection[0].name}" selected (${this.bytesToString(totalSize)})`;
|
|
523
|
+
if (dirCount > 0 && fileCount == 0)
|
|
524
|
+
return `"${dirCount}" folders selected`;
|
|
525
|
+
if (fileCount > 0 && dirCount == 0)
|
|
526
|
+
return `${fileCount} items selected (${this.bytesToString(totalSize)})`;
|
|
527
|
+
return `${dirCount} folder${dirCount == 1 ? "" : "s"} selected, ${fileCount} other item${fileCount == 1 ? "" : "s"} selected (${this.bytesToString(totalSize)})`;
|
|
528
|
+
}
|
|
529
|
+
bytesToString(bytes, decimals = 2) {
|
|
530
|
+
if (!+bytes)
|
|
531
|
+
return '0 Bytes';
|
|
532
|
+
const k = 1024;
|
|
533
|
+
const dm = decimals < 0 ? 0 : decimals;
|
|
534
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
535
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
536
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
537
|
+
}
|
|
538
|
+
resize() {
|
|
539
|
+
if (!this.filesRef) {
|
|
540
|
+
setTimeout(() => this.resize(), 25);
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
;
|
|
544
|
+
const bounds = this.filesRef.nativeElement.getBoundingClientRect();
|
|
545
|
+
const newColCount = Math.floor(bounds.width / itemWidth);
|
|
546
|
+
if (newColCount != this.itemsPerRow) {
|
|
547
|
+
this.itemsPerRow = Math.floor(bounds.width / itemWidth);
|
|
548
|
+
if (this.itemsPerRow > 100)
|
|
549
|
+
this.itemsPerRow = 1;
|
|
550
|
+
this.flowRows();
|
|
551
|
+
}
|
|
552
|
+
if (this.sortedFolders?.length == 0)
|
|
553
|
+
this.flowRows();
|
|
554
|
+
}
|
|
555
|
+
onDragStart(evt, item) {
|
|
556
|
+
const target = `${window.origin}/api/filesystem/download?dir=${item.path}&file=${item.name}`;
|
|
557
|
+
evt.dataTransfer.clearData();
|
|
558
|
+
// evt.dataTransfer.setData('text/uri-list', target);
|
|
559
|
+
// evt.dataTransfer.setData('DownloadURL', `text/uri-list:${target}`);
|
|
560
|
+
evt.dataTransfer.setData('text/plain', item.name);
|
|
561
|
+
}
|
|
562
|
+
onDrop(ev) {
|
|
563
|
+
ev.preventDefault();
|
|
564
|
+
if (ev.dataTransfer.items) {
|
|
565
|
+
// Use DataTransferItemList interface to access the file(s)
|
|
566
|
+
[...ev.dataTransfer.items].forEach((item, i) => {
|
|
567
|
+
// If dropped items aren't files, reject them
|
|
568
|
+
if (item.kind === "file") {
|
|
569
|
+
const file = item.getAsFile();
|
|
570
|
+
console.log(`… file[${i}].name = ${file.name}`);
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
// Use DataTransfer interface to access the file(s)
|
|
576
|
+
[...ev.dataTransfer.files].forEach((file, i) => {
|
|
577
|
+
console.log(`… file[${i}].name = ${file.name}`);
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
onRowCtx({ event, row }) {
|
|
582
|
+
openMenu(this.matDialog, this.fileContextMenu, row.getData(), event);
|
|
583
|
+
}
|
|
584
|
+
onRowClick({ event, row, data }) {
|
|
585
|
+
// $event.data['_value'] = $event.data['_value'] == true ? false : true
|
|
586
|
+
// console.log(event, row, data, this.value);
|
|
587
|
+
const rowEl = row.getElement();
|
|
588
|
+
let state = rowEl.classList.contains('selected');
|
|
589
|
+
data['_value'] = !state;
|
|
590
|
+
if (!this.value) {
|
|
591
|
+
this.value = [];
|
|
592
|
+
}
|
|
593
|
+
if (!state) {
|
|
594
|
+
rowEl.classList.add('selected');
|
|
595
|
+
this.value.push(data);
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
rowEl.classList.remove('selected');
|
|
599
|
+
const i = this.value.findIndex(v => v == data);
|
|
600
|
+
if (i >= 0)
|
|
601
|
+
this.value.splice(i, 1);
|
|
602
|
+
}
|
|
603
|
+
this.valueChange.next(this.value);
|
|
604
|
+
}
|
|
605
|
+
sort() {
|
|
606
|
+
this._sortFilter();
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
FileGridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileGridComponent, deps: [{ token: i1.Fetch }, { token: i1.KeyboardService }, { token: i1.DialogService }, { token: i2.MatDialog }, { token: i3.FilemanagerComponent }, { token: i0.ChangeDetectorRef }, { token: i4.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
|
|
610
|
+
FileGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: FileGridComponent, isStandalone: true, selector: "app-file-grid", inputs: { path: "path", config: "config", showHiddenFiles: "showHiddenFiles", viewMode: "viewMode", gridSize: "gridSize", tab: "tab", selection: "selection", value: "value", sortOrder: "sortOrder" }, outputs: { pathChange: "pathChange", fileSelect: "fileSelect", fileDblClick: "fileDblClick", folderSelect: "folderSelect", folderDblClick: "folderDblClick", newTab: "newTab", loadFiles: "loadFiles", selectionChange: "selectionChange", valueChange: "valueChange" }, viewQueries: [{ propertyName: "filesRef", first: true, predicate: ["fileViewport"], descendants: true }, { propertyName: "tabulator", first: true, predicate: TabulatorComponent, descendants: true }, { propertyName: "renameTemplate", first: true, predicate: ["renameTemplate"], descendants: true, read: TemplateRef }], ngImport: i0, template: "<ng-container *ngIf=\"showLoader\">\n <mat-progress-bar [class.hide]=\"hideLoader\" mode=\"query\"/>\n</ng-container>\n\n<div\n style=\"display: contents\"\n [style.--filemanager-fileicon-backdrop]=\"'url(' + iconResolver.path + '/pop/generic.svg)'\"\n (dragstart)=\"userIsDraggingFile = true\"\n (dragend)=\"userIsDraggingFile = false\"\n (dragover)=\"draggingOver = true\"\n (dragleave)=\"draggingOver = false\"\n (ondrop)=\"onDrop($event)\"\n>\n <!-- <ng-container *ngIf=\"draggingOver\"></ng-container> -->\n <!-- Grid mode -->\n <ng-scrollbar\n *ngIf=\"viewMode == 'grid'\"\n class=\"grid {{gridSize}} {{config.imageSize || 'normal'}}\"\n [class.selectionMode]=\"config.mode == 'focusFiles'\"\n [class.showDropArea]=\"draggingOver\"\n style=\"height: 100%; width: 100%\"\n track=\"vertical\"\n pointerEventsMethod=\"scrollbar\"\n [ngx-contextmenu]=\"folderContextMenu\"\n >\n <div class=\"resize-observer\" #fileViewport></div>\n <cdk-virtual-scroll-viewport\n itemSize=\"134\"\n scrollViewport\n (click)=\"selection = []; selectionText = ''\"\n >\n <div class=\"row\" *cdkVirtualFor=\"let row of sortedFolders\">\n <div class=\"file\"\n *ngFor=\"let item of row\"\n [class.selected]=\"selection.includes(item)\"\n [class.generic]=\"item['_icon'].needsBackdrop\"\n [ngx-contextmenu]=\"fileContextMenu\"\n [ngx-menu-context]=\"item\"\n >\n <mat-checkbox\n #checkbox\n *ngIf=\"config.mode == 'focusFiles' && item.kind == 'file'\"\n [checked]=\"item['_value']\"\n (change)=\"onToggle(item, $event)\"\n />\n <div\n style=\"display: contents\"\n (click)=\"onSelect(item, $event)\"\n (dblclick)=\"onItemClick(item)\"\n (dragstart)=\"onDragStart($event, item)\"\n >\n <img [src]=\"item['_icon'].path\"/>\n <p>{{item['vanityName'] || item.name}}</p>\n </div>\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-scrollbar>\n\n <!-- List mode -->\n <div\n *ngIf=\"viewMode == 'list'\"\n style=\"width: 100%; height: 100%\"\n [class.showDropArea]=\"draggingOver\"\n [ngx-contextmenu]=\"folderContextMenu\"\n >\n <app-tabulator\n [dataSource]=\"directoryContents\"\n [columns]=\"[\n { field: 'name', title: 'Name', formatter: nameCellFormatter },\n { field: '_size', title: 'Size' },\n { field: '_ctime', title: 'Created' },\n { field: '_mtime', title: 'Modified' },\n ]\"\n [options]=\"{\n rowHeight: 32\n }\"\n (rowClick)=\"onRowClick($event)\"\n (rowDblClick)=\"onItemClick($event.data)\"\n (rowContext)=\"onRowCtx($event)\"\n />\n </div>\n</div>\n\n<div class=\"select-hint\" *ngIf=\"selectionText\">\n {{selectionText}}\n</div>\n\n", styles: [":host{display:block;height:100%;width:100%;overflow:hidden}.resize-observer{position:absolute;inset:0}.grid .row{flex:1;display:grid;grid-template-columns:repeat(auto-fill,80px);justify-content:space-between;grid-gap:20px;grid-auto-rows:min-content;padding:10px;margin-right:10px}.grid .file{width:80px;z-index:1;position:relative;transition:opacity 50ms ease-in-out;display:flex;flex-direction:column;align-items:center;text-align:center}.grid .file.selected p{background-color:#8ad9d9;color:#000}.grid .file.generic:before{content:\" \";position:absolute;background:var(--filemanager-fileicon-backdrop);background-repeat:no-repeat;width:100%;height:100%;z-index:-1;left:0}.grid .file.generic img{height:44px;width:44px;margin-top:28px;margin-bottom:8px}.grid .file img{-webkit-user-select:none;user-select:none}.grid .file p{height:50px;width:100%;margin:0;padding:2px;font-size:14px;line-height:16px;border-radius:4px;overflow:hidden;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;text-overflow:ellipsis;overflow-wrap:break-word;transition:background-color 50ms ease-in-out,color 50ms ease-in-out}.grid .file mat-checkbox{position:absolute;left:-32px;top:-16px}:host ::ng-deep .small .file{width:46px}:host ::ng-deep .grid.selectionMode .row{padding-left:30px}:host ::ng-deep .grid.selectionMode .cdk-virtual-scroll-content-wrapper{padding-top:10px}:host ::ng-deep .tabulator .tabulator-row .tabulator-cell:not(:first-of-type){padding-top:9px}.list .row{flex:1;display:flex;align-items:center;padding:5px 10px;height:42px}.list .row p{margin:0}.list .row:hover{background-color:var(--filemanager-row-hover-background-color, #343434)}.list .row.selected p{background-color:#8ad9d9;color:#000;border-radius:5px;padding:0 4px}.list .row.odd{background-color:var(--filemanager-row-alt-background-color, #323232)}.select-hint{position:absolute;font-size:14px;bottom:0;right:0;background-color:#000a;padding:2px 10px;border:1px solid black;border-top-right-radius:5px;border-bottom:none;border-right:none;z-index:9999}.select-hint:hover{display:none}.showDropArea{border:4px dashed rgba(18,18,18,.8);transition:border-color .25s ease}:host ::ng-deep ng-scrollbar.ng-scrollbar{box-sizing:border-box!important;--scrollbar-thumb-color: #666;min-height:200px;min-width:200px}mat-progress-bar{--mdc-linear-progress-track-height: 2px;position:absolute;top:0;left:0;width:100%;animation:dropIn .2s ease;transition:position .2s ease;z-index:100}mat-progress-bar.hide{top:-2px}@keyframes dropIn{0%{top:-2px}to{top:0}}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "ngmodule", type: NgScrollbarModule }, { kind: "component", type: i5.NgScrollbar, selector: "ng-scrollbar", inputs: ["disabled", "sensorDisabled", "pointerEventsDisabled", "viewportPropagateMouseMove", "autoHeightDisabled", "autoWidthDisabled", "viewClass", "trackClass", "thumbClass", "minThumbSize", "trackClickScrollDuration", "pointerEventsMethod", "track", "visibility", "appearance", "position", "sensorDebounce", "scrollAuditTime"], outputs: ["updated"], exportAs: ["ngScrollbar"] }, { kind: "directive", type: i5.ScrollViewport, selector: "[scrollViewport]" }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i6.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i7.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: TabulatorComponent, selector: "app-tabulator", inputs: ["dataSource", "columns", "key", "options"], outputs: ["cellClick", "cellDblClick", "rowClick", "rowContext", "rowDblClick"] }, { kind: "directive", type: MenuDirective, selector: "[ngx-contextmenu],[ngx-menu],[ngxContextmenu],[ngxMenu]", inputs: ["ngx-menu-context", "ngx-contextmenu", "ngx-menu", "ngx-menu-config"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i8.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i8.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i8.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }] });
|
|
611
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileGridComponent, decorators: [{
|
|
612
|
+
type: Component,
|
|
613
|
+
args: [{ selector: 'app-file-grid', imports: [
|
|
614
|
+
NgIf,
|
|
615
|
+
NgForOf,
|
|
616
|
+
DatePipe,
|
|
617
|
+
MatTabsModule,
|
|
618
|
+
NgScrollbarModule,
|
|
619
|
+
MatInputModule,
|
|
620
|
+
MatCheckboxModule,
|
|
621
|
+
MatProgressBarModule,
|
|
622
|
+
TabulatorComponent,
|
|
623
|
+
MenuDirective,
|
|
624
|
+
ScrollingModule
|
|
625
|
+
], standalone: true, template: "<ng-container *ngIf=\"showLoader\">\n <mat-progress-bar [class.hide]=\"hideLoader\" mode=\"query\"/>\n</ng-container>\n\n<div\n style=\"display: contents\"\n [style.--filemanager-fileicon-backdrop]=\"'url(' + iconResolver.path + '/pop/generic.svg)'\"\n (dragstart)=\"userIsDraggingFile = true\"\n (dragend)=\"userIsDraggingFile = false\"\n (dragover)=\"draggingOver = true\"\n (dragleave)=\"draggingOver = false\"\n (ondrop)=\"onDrop($event)\"\n>\n <!-- <ng-container *ngIf=\"draggingOver\"></ng-container> -->\n <!-- Grid mode -->\n <ng-scrollbar\n *ngIf=\"viewMode == 'grid'\"\n class=\"grid {{gridSize}} {{config.imageSize || 'normal'}}\"\n [class.selectionMode]=\"config.mode == 'focusFiles'\"\n [class.showDropArea]=\"draggingOver\"\n style=\"height: 100%; width: 100%\"\n track=\"vertical\"\n pointerEventsMethod=\"scrollbar\"\n [ngx-contextmenu]=\"folderContextMenu\"\n >\n <div class=\"resize-observer\" #fileViewport></div>\n <cdk-virtual-scroll-viewport\n itemSize=\"134\"\n scrollViewport\n (click)=\"selection = []; selectionText = ''\"\n >\n <div class=\"row\" *cdkVirtualFor=\"let row of sortedFolders\">\n <div class=\"file\"\n *ngFor=\"let item of row\"\n [class.selected]=\"selection.includes(item)\"\n [class.generic]=\"item['_icon'].needsBackdrop\"\n [ngx-contextmenu]=\"fileContextMenu\"\n [ngx-menu-context]=\"item\"\n >\n <mat-checkbox\n #checkbox\n *ngIf=\"config.mode == 'focusFiles' && item.kind == 'file'\"\n [checked]=\"item['_value']\"\n (change)=\"onToggle(item, $event)\"\n />\n <div\n style=\"display: contents\"\n (click)=\"onSelect(item, $event)\"\n (dblclick)=\"onItemClick(item)\"\n (dragstart)=\"onDragStart($event, item)\"\n >\n <img [src]=\"item['_icon'].path\"/>\n <p>{{item['vanityName'] || item.name}}</p>\n </div>\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-scrollbar>\n\n <!-- List mode -->\n <div\n *ngIf=\"viewMode == 'list'\"\n style=\"width: 100%; height: 100%\"\n [class.showDropArea]=\"draggingOver\"\n [ngx-contextmenu]=\"folderContextMenu\"\n >\n <app-tabulator\n [dataSource]=\"directoryContents\"\n [columns]=\"[\n { field: 'name', title: 'Name', formatter: nameCellFormatter },\n { field: '_size', title: 'Size' },\n { field: '_ctime', title: 'Created' },\n { field: '_mtime', title: 'Modified' },\n ]\"\n [options]=\"{\n rowHeight: 32\n }\"\n (rowClick)=\"onRowClick($event)\"\n (rowDblClick)=\"onItemClick($event.data)\"\n (rowContext)=\"onRowCtx($event)\"\n />\n </div>\n</div>\n\n<div class=\"select-hint\" *ngIf=\"selectionText\">\n {{selectionText}}\n</div>\n\n", styles: [":host{display:block;height:100%;width:100%;overflow:hidden}.resize-observer{position:absolute;inset:0}.grid .row{flex:1;display:grid;grid-template-columns:repeat(auto-fill,80px);justify-content:space-between;grid-gap:20px;grid-auto-rows:min-content;padding:10px;margin-right:10px}.grid .file{width:80px;z-index:1;position:relative;transition:opacity 50ms ease-in-out;display:flex;flex-direction:column;align-items:center;text-align:center}.grid .file.selected p{background-color:#8ad9d9;color:#000}.grid .file.generic:before{content:\" \";position:absolute;background:var(--filemanager-fileicon-backdrop);background-repeat:no-repeat;width:100%;height:100%;z-index:-1;left:0}.grid .file.generic img{height:44px;width:44px;margin-top:28px;margin-bottom:8px}.grid .file img{-webkit-user-select:none;user-select:none}.grid .file p{height:50px;width:100%;margin:0;padding:2px;font-size:14px;line-height:16px;border-radius:4px;overflow:hidden;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;text-overflow:ellipsis;overflow-wrap:break-word;transition:background-color 50ms ease-in-out,color 50ms ease-in-out}.grid .file mat-checkbox{position:absolute;left:-32px;top:-16px}:host ::ng-deep .small .file{width:46px}:host ::ng-deep .grid.selectionMode .row{padding-left:30px}:host ::ng-deep .grid.selectionMode .cdk-virtual-scroll-content-wrapper{padding-top:10px}:host ::ng-deep .tabulator .tabulator-row .tabulator-cell:not(:first-of-type){padding-top:9px}.list .row{flex:1;display:flex;align-items:center;padding:5px 10px;height:42px}.list .row p{margin:0}.list .row:hover{background-color:var(--filemanager-row-hover-background-color, #343434)}.list .row.selected p{background-color:#8ad9d9;color:#000;border-radius:5px;padding:0 4px}.list .row.odd{background-color:var(--filemanager-row-alt-background-color, #323232)}.select-hint{position:absolute;font-size:14px;bottom:0;right:0;background-color:#000a;padding:2px 10px;border:1px solid black;border-top-right-radius:5px;border-bottom:none;border-right:none;z-index:9999}.select-hint:hover{display:none}.showDropArea{border:4px dashed rgba(18,18,18,.8);transition:border-color .25s ease}:host ::ng-deep ng-scrollbar.ng-scrollbar{box-sizing:border-box!important;--scrollbar-thumb-color: #666;min-height:200px;min-width:200px}mat-progress-bar{--mdc-linear-progress-track-height: 2px;position:absolute;top:0;left:0;width:100%;animation:dropIn .2s ease;transition:position .2s ease;z-index:100}mat-progress-bar.hide{top:-2px}@keyframes dropIn{0%{top:-2px}to{top:0}}\n"] }]
|
|
626
|
+
}], ctorParameters: function () { return [{ type: i1.Fetch }, { type: i1.KeyboardService }, { type: i1.DialogService }, { type: i2.MatDialog }, { type: i3.FilemanagerComponent }, { type: i0.ChangeDetectorRef }, { type: i4.DomSanitizer }]; }, propDecorators: { filesRef: [{
|
|
627
|
+
type: ViewChild,
|
|
628
|
+
args: ["fileViewport"]
|
|
629
|
+
}], tabulator: [{
|
|
630
|
+
type: ViewChild,
|
|
631
|
+
args: [TabulatorComponent]
|
|
632
|
+
}], renameTemplate: [{
|
|
633
|
+
type: ViewChild,
|
|
634
|
+
args: ['renameTemplate', { read: TemplateRef }]
|
|
635
|
+
}], path: [{
|
|
636
|
+
type: Input
|
|
637
|
+
}], pathChange: [{
|
|
638
|
+
type: Output
|
|
639
|
+
}], config: [{
|
|
640
|
+
type: Input
|
|
641
|
+
}], showHiddenFiles: [{
|
|
642
|
+
type: Input
|
|
643
|
+
}], viewMode: [{
|
|
644
|
+
type: Input
|
|
645
|
+
}], gridSize: [{
|
|
646
|
+
type: Input
|
|
647
|
+
}], tab: [{
|
|
648
|
+
type: Input
|
|
649
|
+
}], fileSelect: [{
|
|
650
|
+
type: Output
|
|
651
|
+
}], fileDblClick: [{
|
|
652
|
+
type: Output
|
|
653
|
+
}], folderSelect: [{
|
|
654
|
+
type: Output
|
|
655
|
+
}], folderDblClick: [{
|
|
656
|
+
type: Output
|
|
657
|
+
}], newTab: [{
|
|
658
|
+
type: Output
|
|
659
|
+
}], loadFiles: [{
|
|
660
|
+
type: Output
|
|
661
|
+
}], selection: [{
|
|
662
|
+
type: Input
|
|
663
|
+
}], selectionChange: [{
|
|
664
|
+
type: Output
|
|
665
|
+
}], value: [{
|
|
666
|
+
type: Input
|
|
667
|
+
}], valueChange: [{
|
|
668
|
+
type: Output
|
|
669
|
+
}], sortOrder: [{
|
|
670
|
+
type: Input
|
|
671
|
+
}] } });
|
|
672
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1ncmlkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbW1vbi9zcmMvY29tcG9uZW50cy9maWxlbWFuYWdlci9maWxlLWdyaWQvZmlsZS1ncmlkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbW1vbi9zcmMvY29tcG9uZW50cy9maWxlbWFuYWdlci9maWxlLWdyaWQvZmlsZS1ncmlkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFnQyxXQUFXLEVBQXFCLGVBQWUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6SyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxFQUFxQixpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHekQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR2xELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN6RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN0RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3hDLE9BQU8sRUFBeUMsYUFBYSxFQUFZLFFBQVEsRUFBRSxNQUFNLHFCQUFxQixDQUFD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SSxXQUFXO3NCQUFwQixNQUFNO2dCQWNFLFNBQVM7c0JBQWpCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgRXZlbnRFbWl0dGVyLCBPdXRwdXQsIElucHV0LCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIE9wdGlvbmFsLCBJbmplY3QsIFRlbXBsYXRlUmVmLCBDaGFuZ2VEZXRlY3RvclJlZiwgU2VjdXJpdHlDb250ZXh0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNYXRUYWJzTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFicyc7XG5pbXBvcnQgeyBNYXRDaGVja2JveENoYW5nZSwgTWF0Q2hlY2tib3hNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jaGVja2JveCc7XG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IERhdGVQaXBlLCBOZ0Zvck9mLCBOZ0lmIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFNjcm9sbGluZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9zY3JvbGxpbmcnO1xuaW1wb3J0IHsgTWF0RGlhbG9nLCBNYXREaWFsb2dSZWYgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgQ2VsbENvbXBvbmVudCwgRW1wdHlDYWxsYmFjayB9IGZyb20gJ3RhYnVsYXRvci10YWJsZXMnO1xuaW1wb3J0IHsgTmdTY3JvbGxiYXJNb2R1bGUgfSBmcm9tICduZ3gtc2Nyb2xsYmFyJztcbmltcG9ydCB7IERpcmVjdG9yeURlc2NyaXB0b3IsIEZpbGVEZXNjcmlwdG9yLCBGaWxlbWFuYWdlckNvbXBvbmVudCwgRmlsZVZpZXdUYWIsIEZTRGVzY3JpcHRvciwgTmd4RmlsZU1hbmFnZXJDb25maWd1cmF0aW9uIH0gZnJvbSAnLi4vZmlsZW1hbmFnZXIuY29tcG9uZW50JztcbmltcG9ydCB7IEZpbGVTb3J0aW5nIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgSWNvblJlc29sdmVyIH0gZnJvbSAnLi4vaWNvbi1yZXNvbHZlcic7XG5pbXBvcnQgeyBUYWJ1bGF0b3JDb21wb25lbnQgfSBmcm9tICcuLi8uLi90YWJ1bGF0b3IvdGFidWxhdG9yLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBNYXRQcm9ncmVzc0Jhck1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3Byb2dyZXNzLWJhcic7XG5pbXBvcnQgeyB1cGxvYWRGaWxlIH0gZnJvbSAnLi4vaGVscGVycyc7XG5pbXBvcnQgeyBEaWFsb2dTZXJ2aWNlLCBGZXRjaCwgS2V5Ym9hcmRTZXJ2aWNlLCBNZW51RGlyZWN0aXZlLCBNZW51SXRlbSwgb3Blbk1lbnUgfSBmcm9tICcuLi8uLi8uLi9wdWJsaWMtYXBpJztcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuXG5jb25zdCBpdGVtV2lkdGggPSAoODAgKyAyMCk7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnYXBwLWZpbGUtZ3JpZCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2ZpbGUtZ3JpZC5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vZmlsZS1ncmlkLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgaW1wb3J0czogW1xuICAgICAgICBOZ0lmLFxuICAgICAgICBOZ0Zvck9mLFxuICAgICAgICBEYXRlUGlwZSxcbiAgICAgICAgTWF0VGFic01vZHVsZSxcbiAgICAgICAgTmdTY3JvbGxiYXJNb2R1bGUsXG4gICAgICAgIE1hdElucHV0TW9kdWxlLFxuICAgICAgICBNYXRDaGVja2JveE1vZHVsZSxcbiAgICAgICAgTWF0UHJvZ3Jlc3NCYXJNb2R1bGUsXG4gICAgICAgIFRhYnVsYXRvckNvbXBvbmVudCxcbiAgICAgICAgTWVudURpcmVjdGl2ZSxcbiAgICAgICAgU2Nyb2xsaW5nTW9kdWxlXG4gICAgXSxcbiAgICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIEZpbGVHcmlkQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgICBAVmlld0NoaWxkKFwiZmlsZVZpZXdwb3J0XCIpIGZpbGVzUmVmOiBFbGVtZW50UmVmO1xuICAgIEBWaWV3Q2hpbGQoVGFidWxhdG9yQ29tcG9uZW50KSB0YWJ1bGF0b3I6IFRhYnVsYXRvckNvbXBvbmVudDtcblxuICAgIEBWaWV3Q2hpbGQoJ3JlbmFtZVRlbXBsYXRlJywgeyByZWFkOiBUZW1wbGF0ZVJlZiB9KSByZW5hbWVUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuXG4gICAgcHJpdmF0ZSBfcGF0aDogc3RyaW5nO1xuICAgIEBJbnB1dCgpIHNldCBwYXRoKHZhbHVlOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKCF2YWx1ZSkgcmV0dXJuO1xuXG4gICAgICAgIGlmICh0aGlzLl9wYXRoICYmIHRoaXMuY29uZmlnLm5hdmlnYXRlT25seVRvRGVzY2VuZGFudHMpIHtcbiAgICAgICAgICAgIGlmICghdmFsdWUuc3RhcnRzV2l0aCgnLycpKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gJy8nICsgdmFsdWU7XG4gICAgICAgICAgICBpZiAoIXZhbHVlLnN0YXJ0c1dpdGgodGhpcy5jb25maWcucGF0aCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHByZXYgPSB0aGlzLl9wYXRoO1xuXG4gICAgICAgIHRoaXMuX3BhdGggPSB2YWx1ZTtcblxuICAgICAgICBpZiAocHJldiAhPSB2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5wYXRoQ2hhbmdlLm5leHQodGhpcy5wYXRoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5hcGlTZXR0aW5ncylcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRGb2xkZXIoKVxuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwYXRoKCkge3JldHVybiB0aGlzLl9wYXRofVxuICAgIEBPdXRwdXQoKSBwYXRoQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgICBASW5wdXQoKSBjb25maWc6IE5neEZpbGVNYW5hZ2VyQ29uZmlndXJhdGlvbiA9IHt9O1xuICAgIEBJbnB1dCgpIHNob3dIaWRkZW5GaWxlcyA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIHZpZXdNb2RlOiBcImxpc3RcIiB8IFwiZ3JpZFwiID0gXCJncmlkXCI7XG4gICAgQElucHV0KCkgZ3JpZFNpemU6IFwic21hbGxcIiB8IFwibm9ybWFsXCIgfCBcImxhcmdlXCIgPSBcIm5vcm1hbFwiO1xuICAgIEBJbnB1dCgpIHRhYjogRmlsZVZpZXdUYWI7XG5cbiAgICBAT3V0cHV0KCkgZmlsZVNlbGVjdCA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZURlc2NyaXB0b3I+KCk7XG4gICAgQE91dHB1dCgpIGZpbGVEYmxDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZURlc2NyaXB0b3I+KCk7XG4gICAgQE91dHB1dCgpIGZvbGRlclNlbGVjdCA9IG5ldyBFdmVudEVtaXR0ZXI8RGlyZWN0b3J5RGVzY3JpcHRvcj4oKTtcbiAgICBAT3V0cHV0KCkgZm9sZGVyRGJsQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPERpcmVjdG9yeURlc2NyaXB0b3I+KCk7XG4gICAgQE91dHB1dCgpIG5ld1RhYiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBwYXRoOiBzdHJpbmc7IH0+KCk7XG4gICAgQE91dHB1dCgpIGxvYWRGaWxlcyA9IG5ldyBFdmVudEVtaXR0ZXI8RlNEZXNjcmlwdG9yW10+KCk7XG5cbiAgICBkaXJlY3RvcnlDb250ZW50czogRlNEZXNjcmlwdG9yW10gPSBbXTtcbiAgICBASW5wdXQoKSBzZWxlY3Rpb246IEZTRGVzY3JpcHRvcltdID0gW107XG4gICAgQE91dHB1dCgpIHNlbGVjdGlvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8RlNEZXNjcmlwdG9yW10+KCk7XG5cbiAgICBASW5wdXQoKSB2YWx1ZTogRlNEZXNjcmlwdG9yW10gPSBbXTtcbiAgICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPEZTRGVzY3JpcHRvcltdPigpO1xuXG4gICAgc2VsZWN0aW9uVGV4dDogc3RyaW5nO1xuXG4gICAgc29ydGVkRm9sZGVyczogYW55W11bXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBzb3J0ZXJzID0ge1xuICAgICAgICBcImEtelwiOiAoYTogRmlsZURlc2NyaXB0b3IsIGI6IEZpbGVEZXNjcmlwdG9yKSA9PiBhLm5hbWUgPiBiLm5hbWUgPyAxIDogLTEsXG4gICAgICAgIFwiei1hXCI6IChhOiBGaWxlRGVzY3JpcHRvciwgYjogRmlsZURlc2NyaXB0b3IpID0+IGIubmFtZSA+IGEubmFtZSA/IDEgOiAtMSxcbiAgICAgICAgXCJsYXN0bW9kXCI6IChhOiBGaWxlRGVzY3JpcHRvciwgYjogRmlsZURlc2NyaXB0b3IpID0+IGIuc3RhdHMubXRpbWVNcyAtIGEuc3RhdHMubXRpbWVNcyxcbiAgICAgICAgXCJmaXJzdG1vZFwiOiAoYTogRmlsZURlc2NyaXB0b3IsIGI6IEZpbGVEZXNjcmlwdG9yKSA9PiBhLnN0YXRzLm10aW1lTXMgLSBiLnN0YXRzLm10aW1lTXMsXG4gICAgICAgIFwic2l6ZVwiOiAoYTogRmlsZURlc2NyaXB0b3IsIGI6IEZpbGVEZXNjcmlwdG9yKSA9PiBiLnN0YXRzLnNpemUgLSBhLnN0YXRzLnNpemUsXG4gICAgICAgIFwidHlwZVwiOiAoYTogRmlsZURlc2NyaXB0b3IsIGI6IEZpbGVEZXNjcmlwdG9yKSA9PiBhLnBhdGguc3BsaXQoJy4nKS5zcGxpY2UoLTEsIDEpWzBdID4gYi5wYXRoLnNwbGl0KCcuJykuc3BsaWNlKC0xLCAxKVswXSA/IDEgOiAtMVxuICAgIH07XG4gICAgQElucHV0KCkgc29ydE9yZGVyOiBGaWxlU29ydGluZyA9IFwiYS16XCI7XG5cbiAgICBpdGVtc1BlclJvdyA9IDY7XG5cbiAgICAvLyBJZiB0aGUgY3VycmVudCBkaXJlY3RvcnkgaXMgaW5zaWRlIG9mIGFuIGFyY2hpdmVcbiAgICBpc0FyY2hpdmUgPSB0cnVlO1xuXG4gICAgdXNlcklzRHJhZ2dpbmdGaWxlID0gZmFsc2U7XG4gICAgZHJhZ2dpbmdPdmVyID0gZmFsc2U7XG5cbiAgICBzaG93TG9hZGVyID0gZmFsc2U7XG4gICAgaGlkZUxvYWRlciA9IGZhbHNlO1xuXG4gICAgcmVhZG9ubHkgY29sdW1ucyA9IFtcbiAgICAgICAgeyBpZDogXCJuYW1lXCIsIGxhYmVsOiBcIk5hbWVcIiB9LFxuICAgICAgICB7IGlkOiBcInNpemVcIiwgbGFiZWw6IFwiU2l6ZVwifSxcbiAgICAgICAgeyBpZDogXCJ0eXBlXCIsIGxhYmVsOiBcIlR5cGVcIn0sXG4gICAgICAgIHsgaWQ6IFwib3duZXJcIiwgbGFiZWw6IFwiT3duZXJcIn0sXG4gICAgICAgIHsgaWQ6IFwiZ3JvdXBcIiwgbGFiZWw6IFwiR3JvdXBcIn0sXG4gICAgICAgIHsgaWQ6IFwicGVybWlzc2lvbnNcIiwgbGFiZWw6IFwiUGVybWlzc2lvbnNcIn0sXG4gICAgICAgIHsgaWQ6IFwibG9jYXRpb25cIiwgbGFiZWw6IFwiTG9jYXRpb25cIn0sXG4gICAgICAgIHsgaWQ6IFwibW9kaWZpZWRcIiwgbGFiZWw6IFwiTW9kaWZpZWRcIn0sXG4gICAgICAgIHsgaWQ6IFwibW9kaWZpZWQtLXRpbWVcIiwgbGFiZWw6IFwiTW9kaWZpZWQgLSBUaW1lXCJ9LFxuICAgICAgICB7IGlkOiBcImFjY2Vzc2VkXCIsIGxhYmVsOiBcIkFjY2Vzc2VkXCJ9LFxuICAgICAgICB7IGlkOiBcImNyZWF0ZWRcIiwgbGFiZWw6IFwiQ3JlYXRlZFwifSxcbiAgICAgICAgeyBpZDogXCJyZWNlbmN5XCIsIGxhYmVsOiBcIlJlY2VuY3lcIn0sXG4gICAgICAgIHsgaWQ6IFwic3RhclwiLCBsYWJlbDogXCJTdGFyXCJ9LFxuICAgICAgICB7IGlkOiBcImRldGFpbGVkLXR5cGVcIiwgbGFiZWw6IFwiRGV0YWlsZWQgVHlwZVwifSxcbiAgICBdO1xuXG4gICAgY29scyA9IFtcbiAgICAgICAgeyBpZDogXCJuYW1lXCIsIGxhYmVsOiBcIk5hbWVcIiB9LFxuICAgICAgICB7IGlkOiBcInNpemVcIiwgbGFiZWw6IFwiU2l6ZVwiIH0sXG4gICAgICAgIHsgaWQ6IFwibW9kaWZpZWRcIiwgbGFiZWw6IFwiTW9kaWZpZWRcIiB9LFxuICAgICAgICB7IGlkOiBcInN0YXJcIiwgbGFiZWw6IFwiU3RhclwiIH1cbiAgICBdO1xuXG4gICAgZm9sZGVyQ29udGV4dE1lbnU6IE1lbnVJdGVtPEZTRGVzY3JpcHRvcj5bXSA9IFtcbiAgICAgICAge1xuICAgICAgICAgICAgbGFiZWw6IFwiTmV3IEZvbGRlclwiLFxuICAgICAgICAgICAgLy8gc2hvcnRjdXRMYWJlbDogXCJTaGlmdCtDdHJsK05cIixcbiAgICAgICAgICAgIGljb246IFwiY3JlYXRlX25ld19mb2xkZXJcIixcbiAgICAgICAgICAgIGFjdGlvbjogKGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIk5ldyBmb2xkZXIgZ29vZG5lc3NcIik7XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coZGF0YSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kaWFsb2cub3BlbihcImZvbGRlci1yZW5hbWVcIiwgXCJAZG90Z2xpdGNoL25neC13ZWItY29tcG9uZW50c1wiLCB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0czogeyBwYXRoOiBkYXRhPy5wYXRoIHx8IHRoaXMucGF0aCwgbmFtZTogZGF0YT8ubmFtZSB8fCAnJywgY29uZmlnOiB0aGlzLmNvbmZpZyB9XG4gICAgICAgICAgICAgICAgfSkudGhlbihyID0+IHRoaXMubG9hZEZvbGRlcigpKVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBsYWJlbDogXCJVcGxvYWQgZmlsZVwiLFxuICAgICAgICAgICAgLy8gc2hvcnRjdXRMYWJlbDogXCJDdHJsK0RcIixcbiAgICAgICAgICAgIGljb246IFwiZmlsZV91cGxvYWRcIixcbiAgICAgICAgICAgIGFjdGlvbjogKGV2dCkgPT4gdXBsb2FkRmlsZSh0aGlzLmZldGNoLCB0aGlzLmNvbmZpZywgdGhpcy5fcGF0aCwgZXZ0ID8gKGV2dC5wYXRoICsgZXZ0Lm5hbWUpIDogbnVsbCwgdGhpcy5maWxlTWFuYWdlci5jb250ZXh0VGFncykudGhlbihyZXMgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZEZvbGRlcigpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfSxcbiAgICAgICAgXCJzZXBhcmF0b3JcIixcbiAgICAgICAgLy8ge1xuICAgICAgICAvLyAgICAgaXNEaXNhYmxlZDogKGRhdGEpID0+IHRydWUsXG4gICAgICAgIC8vICAgICBsYWJlbDogXCJfUF9hc3RlXCIsXG4gICAgICAgIC8vICAgICBpY29uOiBcImNvbnRlbnRfcGFzdGVcIixcbiAgICAgICAgLy8gICAgIGFjdGlvbjogKGV2dCkgPT4ge1xuICAgICAgICAvLyAgICAgfVxuICAgICAgICAvLyB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBsYWJlbDogXCJTZWxlY3QgX0FfbGxcIixcbiAgICAgICAgICAgIHNob3J0Y3V0TGFiZWw6IFwiQ3RybCtBXCIsXG4gICAgICAgICAgICBpY29uOiBcInNlbGVjdF9hbGxcIixcbiAgICAgICAgICAgIGFjdGlvbjogKGV2dCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gdGhpcy5fc29ydEZpbHRlcigpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uVGV4dCA9IHRoaXMuZ2V0U2VsZWN0aW9uVGV4dCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLm5leHQodGhpcy5zZWxlY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICAvLyBcInNlcGFyYXRvclwiLFxuICAgICAgICAvLyB7XG4gICAgICAgIC8vICAgICBsYWJlbDogXCJQX3Jfb3BlcnRpZXNcIixcbiAgICAgICAgLy8gICAgIGljb246IFwiZmluZF9pbl9wYWdlXCIsXG4gICAgICAgIC8vICAgICBhY3Rpb246IChldnQpID0+IHtcblxuICAgICAgICAvLyAgICAgfVxuICAgICAgICAvLyB9XG4gICAgXTtcblxuICAgIGZpbGVDb250ZXh0TWVudTogTWVudUl0ZW08RlNEZXNjcmlwdG9yPltdID0gW107XG5cbiAgICBwZXJmb3JtQ2hlY2tzdW0ocGF0aCwgZGlnZXN0KSB7XG4gICAgICAgIC8vIHRoaXMud2luZG93TWFuYWdlci5vcGVuV2luZG93KHtcbiAgICAgICAgLy8gICAgIGFwcElkOiBcImNoZWNrc3VtXCIsXG4gICAgICAgIC8vICAgICBkYXRhOiB7IGRpZ2VzdCwgcGF0aCB9LFxuICAgICAgICAvLyAgICAgd29ya3NwYWNlOiB0aGlzLndpbmRvd1JlZi53b3Jrc3BhY2UsXG4gICAgICAgIC8vICAgICB3aWR0aDogNjAwLFxuICAgICAgICAvLyAgICAgaGVpZ2h0OiAyNTBcbiAgICAgICAgLy8gfSk7XG4gICAgfVxuXG4gICAgaWNvblJlc29sdmVyOiBJY29uUmVzb2x2ZXI7XG5cbiAgICBnZXQgbGliQ29uZmlnKCkgeyByZXR1cm4gdGhpcy5maWxlTWFuYWdlci5saWJDb25maWcgfVxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGZldGNoOiBGZXRjaCxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBrZXlib2FyZDogS2V5Ym9hcmRTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGRpYWxvZzogRGlhbG9nU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBtYXREaWFsb2c6IE1hdERpYWxvZyxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBmaWxlTWFuYWdlcjogRmlsZW1hbmFnZXJDb21wb25lbnQsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IHNhbml0aXplcjogRG9tU2FuaXRpemVyXG4gICAgKSB7XG5cblxuICAgICAgICB0aGlzLmljb25SZXNvbHZlciA9IG5ldyBJY29uUmVzb2x2ZXIodGhpcy5saWJDb25maWcuYXNzZXRQYXRoKTtcblxuICAgICAgICAvLyBjdHJsICsgYSA9PiBzZWxlY3QgYWxsXG4gICAgICAgIGtleWJvYXJkLm9uS2V5Q29tbWFuZCh7XG4gICAgICAgICAgICBrZXk6IFwiYVwiLFxuICAgICAgICAgICAgY3RybDogdHJ1ZSxcbiAgICAgICAgfSkuc3Vic2NyaWJlKGV2dCA9PiB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGlvbiA9IHRoaXMuX3NvcnRGaWx0ZXIoKTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uVGV4dCA9IHRoaXMuZ2V0U2VsZWN0aW9uVGV4dCgpO1xuICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2UubmV4dCh0aGlzLnNlbGVjdGlvbik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGN0cmwgKyBjID0+IGNvcHkgZmlsZSBuYW1lcyB0byBjbGlwYm9hcmRcbiAgICAgICAga2V5Ym9hcmQub25LZXlDb21tYW5kKHtcbiAgICAgICAgICAgIGtleTogXCJjXCIsXG4gICAgICAgICAgICBjdHJsOiB0cnVlLFxuICAgICAgICB9KS5zdWJzY3JpYmUoZXZ0ID0+IHtcblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBjdHJsICsgaCA9PiB0b2dnbGUgaGlkZGVuIGZpbGVzXG4gICAgICAgIGtleWJvYXJkLm9uS2V5Q29tbWFuZCh7XG4gICAgICAgICAgICBrZXk6IFwiaFwiLFxuICAgICAgICAgICAgY3RybDogdHJ1ZSxcbiAgICAgICAgICAgIGludGVycnVwdDogdHJ1ZVxuICAgICAgICB9KS5zdWJzY3JpYmUoZXZ0ID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2hvd0hpZGRlbkZpbGVzID0gIXRoaXMuc2hvd0hpZGRlbkZpbGVzO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBGMiA9PiBSZW5hbWUgc2VsZWN0ZWQgZmlsZXNcbiAgICAgICAga2V5Ym9hcmQub25LZXlDb21tYW5kKHtcbiAgICAgICAgICAgIGtleTogXCJmMlwiLFxuICAgICAgICB9KS5zdWJzY3JpYmUoZXZ0ID0+IHtcbiAgICAgICAgICAgIC8vIFJlbmFtZSBzZWxlY3RlZCBmaWxlKHMpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEVudGVyID0+IE9wZW4gc2VsZWN0ZWQgZmlsZXNcbiAgICAgICAga2V5Ym9hcmQub25LZXlDb21tYW5kKHtcbiAgICAgICAgICAgIGtleTogXCJFbnRlclwiLFxuICAgICAgICB9KS5zdWJzY3JpYmUoZXZ0ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVzID0gdGhpcy5kaXJlY3RvcnlDb250ZW50cy5maWx0ZXIoZGMgPT4gdGhpcy5zZWxlY3Rpb24uZmluZChpID0+IGkubmFtZSA9PSBkYy5uYW1lKSk7XG4gICAgICAgICAgICAvLyB0aGlzLndpbmRvd01hbmFnZXIub3BlbkZpbGVzKGZpbGVzIGFzIGFueSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIERlbGV0ZSA9PiBkZWxldGUgc2VsZWN0ZWQgZmlsZXNcbiAgICAgICAga2V5Ym9hcmQub25LZXlDb21tYW5kKHtcbiAgICAgICAgICAgIGtleTogXCJkZWxldGVcIixcbiAgICAgICAgfSkuc3Vic2NyaWJlKGV2dCA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaWxlcyA9IHRoaXMuZGlyZWN0b3J5Q29udGVudHMuZmlsdGVyKGRjID0+IHRoaXMuc2VsZWN0aW9uLmZpbmQoaSA9PiBpLm5hbWUgPT0gZGMubmFtZSkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICAgICAgLy8gdGhpcy5sb2FkRm9sZGVyKCk7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgICAgICB0aGlzLmZpbGVDb250ZXh0TWVudSA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogXCJEb3dubG9hZFwiLFxuICAgICAgICAgICAgICAgIGljb246IFwiZG93bmxvYWRcIixcbiAgICAgICAgICAgICAgICBhY3Rpb246IChmaWxlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB0YXJnZXQgPSBgJHt3aW5kb3cub3JpZ2lufSR7dGhpcy5jb25maWcuYXBpU2V0dGluZ3MuZG93bmxvYWRFbnRyeVVybH1gO1xuICAgICAgICAgICAgICAgICAgICBsZXQgcGF0aCA9IGZpbGUucGF0aCArIGZpbGUubmFtZTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZS5raW5kID09IFwiZGlyZWN0b3J5XCIgJiYgIXBhdGguZW5kc1dpdGgoJy8nKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggKz0gXCIvXCI7XG5cbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ICs9IGAke3RhcmdldC5pbmNsdWRlcygnPycpID8gJyYnIDogJz8nfXBhdGg9JHtwYXRofSZuZ3N3LWJ5cGFzcz10cnVlYDtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2codGFyZ2V0KTtcbiAgICAgICAgICAgICAgICAgICAgLy8gd2luZG93Lm9wZW4odGFyZ2V0KTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcbiAgICAgICAgICAgICAgICAgICAgbGluay5kb3dubG9hZCA9IGZpbGUubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgbGluay5ocmVmID0gdGFyZ2V0O1xuICAgICAgICAgICAgICAgICAgICBsaW5rLmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgICAgIGxpbmsucmVtb3ZlKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsZU1hbmFnZXIuZmlsZURvd25sb2FkLm5leHQoZmlsZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogXCJPcGVuIGluIG5ldyBUYWJcIixcbiAgICAgICAgICAgICAgICBpY29uOiBcIm9wZW5faW5fbmV3XCIsXG4gICAgICAgICAgICAgICAgaXNWaXNpYmxlOiAoZGF0YSkgPT4gZGF0YS5raW5kID09IFwiZGlyZWN0b3J5XCIsXG4gICAgICAgICAgICAgICAgYWN0aW9uOiAoZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbGVNYW5hZ2VyLmluaXRUYWIoZGF0YS5wYXRoICsgZGF0YS5uYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgLy8ge1xuICAgICAgICAgICAgLy8gICAgIGxhYmVsOiBcIk9wZW4gd2l0aCBBcHBsaWNhdGlvbi4uLlwiLFxuICAgICAgICAgICAgLy8gICAgIGlzVmlzaWJsZTogKGRhdGEpID0+IGRhdGEua2luZCA9PSBcImZpbGVcIixcbiAgICAgICAgICAgIC8vICAgICBzaG9ydGN1dExhYmVsOiBcIkN0cmwrRFwiLFxuICAgICAgICAgICAgLy8gICAgIGFjdGlvbjogKGV2dCkgPT4ge1xuXG4gICAgICAgICAgICAvLyAgICAgfSxcbiAgICAgICAgICAgIC8vIH0sXG4gICAgICAgICAgICBcInNlcGFyYXRvclwiLFxuICAgICAgICAgICAgLy8ge1xuICAgICAgICAgICAgLy8gICAgIGxhYmVsOiBcIkN1dFwiLFxuICAgICAgICAgICAgLy8gICAgIGljb246IFwiY29udGVudF9jdXRcIixcbiAgICAgICAgICAgIC8vICAgICBpc0Rpc2FibGVkOiBkYXRhID0+IHRydWUsXG4gICAgICAgICAgICAvLyAgICAgYWN0aW9uOiAoZXZ0KSA9PiB7XG4gICAgICAgICAgICAvLyAgICAgfSxcbiAgICAgICAgICAgIC8vIH0sXG4gICAgICAgICAgICAvLyB7XG4gICAgICAgICAgICAvLyAgICAgbGFiZWw6IFwiQ29weVwiLFxuICAgICAgICAgICAgLy8gICAgIGljb246IFwiZmlsZV9jb3B5XCIsXG4gICAgICAgICAgICAvLyAgICAgaXNEaXNhYmxlZDogZGF0YSA9PiB0cnVlLFxuICAgICAgICAgICAgLy8gICAgIGNoaWxkcmVuUmVzb2x2ZXI6ICgpID0+IG5ldyBQcm9taXNlKHIgPT4gc2V0VGltZW91dChyLCA1MDAwMDApKVxuICAgICAgICAgICAgLy8gfSxcbiAgICAgICAgICAgIC8vIHtcbiAgICAgICAgICAgIC8vICAgICBsYWJlbDogXCJNb3ZlIFRvLi4uXCIsXG4gICAgICAgICAgICAvLyAgICAgaWNvbjogXCJkcml2ZV9maWxlX21vdmVcIixcbiAgICAgICAgICAgIC8vICAgICBzaG9ydGN1dExhYmVsOiBcIkN0cmwrQVwiLFxuICAgICAgICAgICAgLy8gICAgIGFjdGlvbjogKGV2dCkgPT4ge1xuXG4gICAgICAgICAgICAvLyAgICAgfSxcbiAgICAgICAgICAgIC8vIH0sXG4gICAgICAgICAgICAvLyB7XG4gICAgICAgICAgICAvLyAgICAgbGFiZWw6IFwiQ29weSBUby4uLlwiLFxuICAgICAgICAgICAgLy8gICAgIGljb246IFwiZm9sZGVyX2NvcHlcIixcbiAgICAgICAgICAgIC8vICAgICBzaG9ydGN1dExhYmVsOiBcIkN0cmwrQVwiLFxuICAgICAgICAgICAgLy8gICAgIGFjdGlvbjogKGV2dCkgPT4ge1xuXG4gICAgICAgICAgICAvLyAgICAgfSxcbiAgICAgICAgICAgIC8vIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6IFwiRGVsZXRlXCIsXG4gICAgICAgICAgICAgICAgaWNvbjogXCJkZWxldGVcIixcbiAgICAgICAgICAgICAgICAvLyBzaG9ydGN1dExhYmVsOiBcIkRlbFwiLFxuICAgICAgICAgICAgICAgIGlzVmlzaWJsZTogZGF0YSA9PiAhZGF0YS5wYXRoLmluY2x1ZGVzKFwiIy9cIiksIC8vIG9taXQgZmlsZXMgaW4gY29tcHJlc3NlZCBkaXJzXG4gICAgICAgICAgICAgICAgYWN0aW9uOiAoZXZ0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhdGggPSBldnQucGF0aCArIGV2dC5uYW1lO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHVybCA9IHRoaXMuY29uZmlnLmFwaVNldHRpbmdzLmRlbGV0ZUVudHJ5VXJsVGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gdGhpcy5jb25maWcuYXBpU2V0dGluZ3MuZGVsZXRlRW50cnlVcmxUZW1wbGF0ZShwYXRoKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmNvbmZpZy5hcGlTZXR0aW5ncy5kZWxldGVFbnRyeVVybFxuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmV0Y2guZGVsZXRlKHVybClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMubG9hZEZvbGRlcigpKVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgLy8ge1xuICAgICAgICAgICAgLy8gICAgIGxhYmVsOiBcIlNocmVkIGZpbGVcIixcbiAgICAgICAgICAgIC8vICAgICBpY29uOiBcImRlbGV0ZV9mb3JldmVyXCIsXG4gICAgICAgICAgICAvLyAgICAgaXNWaXNpYmxlOiBkYXRhID0+ICFkYXRhLnBhdGguaW5jbHVkZXMoXCIjL1wiKSwgLy8gb21pdCBmaWxlcyBpbiBjb21wcmVzc2VkIGRpcnNcbiAgICAgICAgICAgIC8vICAgICBhY3Rpb246IChldnQpID0+IHtcbiAgICAgICAgICAgIC8vICAgICAgICAgdGhpcy5mZXRjaC5wb3N0KGAvYXBpL2ZpbGVzeXN0ZW0vZGVsZXRlP3dpcGU9dHJ1ZWAsIHsgZmlsZXM6IFtldnQucGF0aCArIGV2dC5uYW1lXX0pXG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLmxvYWRGb2xkZXIoKSlcbiAgICAgICAgICAgIC8vICAgICB9LFxuICAgICAgICAgICAgLy8gfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogXCJSZW5hbWVcIixcbiAgICAgICAgICAgICAgICBpY29uOiBcImRyaXZlX2ZpbGVfcmVuYW1lX291dGxpbmVcIixcbiAgICAgICAgICAgICAgICBpc1Zpc2libGU6IGRhdGEgPT4gIWRhdGEucGF0aC5pbmNsdWRlcyhcIiMvXCIpLCAvLyBvbWl0IGZpbGVzIGluIGNvbXByZXNzZWQgZGlyc1xuICAgICAgICAgICAgICAgIC8vIHNob3J0Y3V0TGFiZWw6IFwiRjJcIixcbiAgICAgICAgICAgICAgICBhY3Rpb246IChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGlhbG9nLm9wZW4oXCJmb2xkZXItcmVuYW1lXCIsIFwiQGRvdGdsaXRjaC9uZ3gtd2ViLWNvbXBvbmVudHNcIiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRzOiB7IHBhdGg6IGRhdGE/LnBhdGggfHwgdGhpcy5wYXRoLCBuYW1lOiBkYXRhPy5uYW1lIHx8ICcnLCBjb25maWc6IHRoaXMuY29uZmlnIH1cbiAgICAgICAgICAgICAgICAgICAgfSkudGhlbihyID0+IHRoaXMubG9hZEZvbGRlcigpKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8vIEV4dHJhY3QgSGVyZVxuICAgICAgICAgICAgLy8gRXh0cmFjdCBUby4uLlxuICAgICAgICAgICAgLy8ge1xuICAgICAgICAgICAgLy8gICAgIGxhYmVsOiBcIkV4dHJhY3QgSGVyZVwiLFxuICAgICAgICAgICAgLy8gICAgIGljb246IFwiZm9sZGVyX3ppcFwiLFxuICAgICAgICAgICAgLy8gICAgIHNob3J0Y3V0TGFiZWw6IFwiQ3RybCtBXCIsXG4gICAgICAgICAgICAvLyAgICAgaXNEaXNhYmxlZDogKGRhdGEpID0+ICEoZGF0YS5raW5kID09IFwiZmlsZVwiICYmIGRhdGEuZXh0ICE9IFwiLnppcFwiICYmIGlzQXJjaGl2ZShkYXRhKSksXG4gICAgICAgICAgICAvLyAgICAgYWN0aW9uOiAoZXZ0KSA9PiB7XG4gICAgICAgICAgICAvLyAgICAgICAgIC8vIFRPRE9cbiAgICAgICAgICAgIC8vICAgICB9LFxuICAgICAgICAgICAgLy8gfSxcbiAgICAgICAgICAgIC8vIHtcbiAgICAgICAgICAgIC8vICAgICBsYWJlbDogXCJFeHRyYWN0IHRvLi4uXCIsXG4gICAgICAgICAgICAvLyAgICAgaWNvbjogXCJmb2xkZXJfemlwXCIsXG4gICAgICAgICAgICAvLyAgICAgc2hvcnRjdXRMYWJlbDogXCJDdHJsK0FcIixcbiAgICAgICAgICAgIC8vICAgICBpc0Rpc2FibGVkOiAoZGF0YSkgPT4gIShkYXRhLmtpbmQgPT0gXCJmaWxlXCIgJiYgZGF0YS5leHQgIT0gXCIuemlwXCIgJiYgaXNBcmNoaXZlKGRhdGEpKSxcbiAgICAgICAgICAgIC8vICAgICBhY3Rpb246IChldnQpID0+IHtcbiAgICAgICAgICAgIC8vICAgICAgICAgLy8gVE9ET1xuICAgICAgICAgICAgLy8gICAgIH0sXG4gICAgICAgICAgICAvLyB9LFxuICAgICAgICAgICAgLy8ge1xuICAgICAgICAgICAgLy8gICAgIGxhYmVsOiBcIkNvbXByZXNzLi4uXCIsXG4gICAgICAgICAgICAvLyAgICAgaWNvbjogXCJmb2xkZXJfemlwXCIsXG4gICAgICAgICAgICAvLyAgICAgc2hvcnRjdXRMYWJlbDogXCJDdHJsK0FcIixcbiAgICAgICAgICAgIC8vICAgICBpc0Rpc2FibGVkOiAoZGF0YSkgPT4gZGF0YS5raW5kID09IFwiZmlsZVwiLFxuICAgICAgICAgICAgLy8gICAgIGFjdGlvbjogKGV2dCkgPT4ge1xuICAgICAgICAgICAgLy8gICAgICAgICAvLyBUT0RPXG4gICAgICAgICAgICAvLyAgICAgfSxcbiAgICAgICAgICAgIC8vIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6IFwiQ2hlY2tzdW1cIixcbiAgICAgICAgICAgICAgICBpY29uOiBcIm1hbmFnZV9zZWFyY2hcIixcbiAgICAgICAgICAgICAgICBpc0Rpc2FibGVkOiAoZGF0YSkgPT4gZGF0YS5raW5kICE9IFwiZmlsZVwiLFxuICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBcIk1ENVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAoZXZ0KSA9PiB0aGlzLnBlcmZvcm1DaGVja3N1bShldnQucGF0aCArIGV2dC5uYW1lLCBcIm1kNVwiKSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IFwiU0hBMVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAoZXZ0KSA9PiB0aGlzLnBlcmZvcm1DaGVja3N1bShldnQucGF0aCArIGV2dC5uYW1lLCBcInNoYTFcIiksXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBcIlNIQTI1NlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAoZXZ0KSA9PiB0aGlzLnBlcmZvcm1DaGVja3N1bShldnQucGF0aCArIGV2dC5uYW1lLCBcInNoYTI1NlwiKSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IFwiU0hBNTEyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IChldnQpID0+IHRoaXMucGVyZm9ybUNoZWNrc3VtKGV2dC5wYXRoICsgZXZ0Lm5hbWUsIFwic2hhNTEyXCIpLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgaXNWaXNpYmxlOiAoZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAhdGhpcy5pc0FyY2hpdmUgfHwgZGF0YS5raW5kID09IFwiZmlsZVwiO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgLy8ge1xuICAgICAgICAgICAgLy8gICAgIGxhYmVsOiBcIlN0YXJcIixcbiAgICAgICAgICAgIC8vICAgICBpY29uOiBcInN0YXJcIixcbiAgICAgICAgICAgIC8vICAgICBzaG9ydGN1dExhYmVsOiBcIkN0cmwrQVwiLFxuICAgICAgICAgICAgLy8gICAgIGFjdGlvbjogKGV2dCkgPT4ge1xuXG4gICAgICAgICAgICAvLyAgICAgfSxcbiAgICAgICAgICAgIC8vIH0sXG4gICAgICAgICAgICAvLyBcInNlcGFyYXRvclwiLFxuICAgICAgICAgICAgLy8ge1xuICAgICAgICAgICAgLy8gICAgIGxhYmVsOiBcIlBfcl9vcGVydGllc1wiLFxuICAgICAgICAgICAgLy8gICAgIGljb246IFwiZmluZF9pbl9wYWdlXCIsXG4gICAgICAgICAgICAvLyAgICAgYWN0aW9uOiAoZXZ0KSA9PiB7XG5cbiAgICAgICAgICAgIC8vICAgICB9LFxuICAgICAgICAgICAgLy8gfVxuICAgICAgICBdO1xuICAgIH1cblxuICAgIGFzeW5jIGxvYWRGb2xkZXIoKSB7XG4gICAgICAgIHRoaXMuc2hvd0xvYWRlciA9IHRydWU7XG4gICAgICAgIHRoaXMuaGlkZUxvYWRlciA9IGZhbHNlO1xuXG4gICAgICAgIGNvbnN0IHVybCA9IHRoaXMuY29uZmlnLmFwaVNldHRpbmdzLmxpc3RFbnRyaWVzVXJsVGVtcGxhdGVcbiAgICAgICAgICAgID8gdGhpcy5jb25maWcuYXBpU2V0dGluZ3MubGlzdEVudHJpZXNVcmxUZW1wbGF0ZSh0aGlzLnBhdGgpXG4gICAgICAgICAgICA6IHRoaXMuY29uZmlnLmFwaVNldHRpbmdzLmxpc3RFbnRyaWVzVXJsXG5cbiAgICAgICAgdGhpcy5mZXRjaC5wb3N0KHVybCwgeyBwYXRoOiB0aGlzLnBhdGgsIHNob3dIaWRkZW46IHRoaXMuc2hvd0hpZGRlbkZpbGVzIH0pXG4gICAgICAgICAgICAudGhlbigoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZXM6IEZpbGVEZXNjcmlwdG9yW10gPSBkYXRhPy5maWxlcyB8fCBbXTtcbiAgICAgICAgICAgICAgICBjb25zdCBkaXJzOiBEaXJlY3RvcnlEZXNjcmlwdG9yW10gPSBkYXRhPy5kaXJzIHx8IFtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRlc2NyaXB0b3JzID0gZmlsZXMuY29uY2F0KGRpcnMgYXMgYW55KSBhcyBGU0Rlc2NyaXB0b3JbXTtcblxuICAgICAgICAgICAgICAgIGRlc2NyaXB0b3JzLmZvckVhY2goZiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGZbJ19pY29uJ10gPSB0aGlzLmljb25SZXNvbHZlci5yZXNvbHZlSWNvbihmKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGYua2luZCA9PSBcImZpbGVcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZlsnX2N0aW1lJ10gPSBuZXcgRGF0ZShmLnN0YXRzPy5jdGltZU1zKT8udG9Mb2NhbGVTdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZbJ19tdGltZSddID0gbmV3IERhdGUoZi5zdGF0cz8ubXRpbWVNcyk/LnRvTG9jYWxlU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmWydfc2l6ZSddID0gdGhpcy5ieXRlc1RvU3RyaW5nKGYuc3RhdHM/LnNpemUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmRpcmVjdG9yeUNvbnRlbnRzID0gZGVzY3JpcHRvcnM7XG5cbiAgICAgICAgICAgICAgICB0aGlzLl9zb3J0RmlsdGVyKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRGaWxlcy5uZXh0KGRlc2NyaXB0b3JzKTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNvcnRlZEZvbGRlcnMubGVuZ3RoID4gMClcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mbG93Um93cygpO1xuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnJlc2l6ZSgpLCAyNTApO1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5yZXNpemUoKSwgNTAwKTtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMucmVzaXplKCksIDEwMDApO1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5yZXNpemUoKSwgMjUwMCk7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnJlc2l6ZSgpLCA1MDAwKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZSA9PiBjb25zb2xlLmVycm9yKGUpKVxuICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUxvYWRlciA9IHRydWU7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0xvYWRlciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH0sIDIwMCk7XG4gICAgICAgICAgICB9KVxuICAgIH1cblxuICAgIGZsb3dSb3dzKCkge1xuICAgICAgICBsZXQgZmlsdGVyZWQgPSB0aGlzLl9zb3J0RmlsdGVyKCk7XG5cbiAgICAgICAgdGhpcy5zb3J0ZWRGb2xkZXJzID0gW107XG4gICAgICAgIGNvbnN0IG51bSA9IE1hdGguY2VpbChmaWx0ZXJlZC5sZW5ndGggLyB0aGlzLml0ZW1zUGVyUm93KTtcbiAgICAgICAgY29uc3QgaXRlcmF0aW9ucyA9IE1hdGgubWluKG51bSwgMTAwKTtcblxuICAgICAgICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCBpdGVyYXRpb25zOyByb3crKykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNvcnRlZEZvbGRlcnNbcm93XSlcbiAgICAgICAgICAgICAgICB0aGlzLnNvcnRlZEZvbGRlcnNbcm93XSA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gcm93ICogdGhpcy5pdGVtc1BlclJvdzsgaSA8IChyb3cgKyAxKSAqIHRoaXMuaXRlbXNQZXJSb3cgJiYgaSA8IGZpbHRlcmVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zb3J0ZWRGb2xkZXJzW3Jvd10ucHVzaChmaWx0ZXJlZFtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblNlbGVjdChpdGVtOiBGU0Rlc2NyaXB0b3IsIGV2dCkge1xuICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgaWYgKHRoaXMua2V5Ym9hcmQuaXNTaGlmdFByZXNzZWQpIHtcbiAgICAgICAgICAgIGxldCBzdGFydCA9IHRoaXMuZGlyZWN0b3J5Q29udGVudHMuZmluZEluZGV4KGkgPT4gaS5uYW1lID09IHRoaXMuc2VsZWN0aW9uLnNsaWNlKC0xLCAxKVswXS5uYW1lKTtcbiAgICAgICAgICAgIGxldCBlbmQgPSB0aGlzLmRpcmVjdG9yeUNvbnRlbnRzLmluZGV4T2YoaXRlbSk7XG5cbiAgICAgICAgICAgIGlmIChzdGFydCA9PSAtMSlcbiAgICAgICAgICAgICAgICBzdGFydCA9IGVuZDtcblxuICAgICAgICAgICAgbGV0IGl0ZW1zID0gc3RhcnQgPiBlbmRcbiAgICAgICAgICAgICAgICA/IHRoaXMuZGlyZWN0b3J5Q29udGVudHMuc2xpY2UoZW5kLCBzdGFydCArIDEpXG4gICAgICAgICAgICAgICAgOiB0aGlzLmRpcmVjdG9yeUNvbnRlbnRzLnNsaWNlKHN0YXJ0LCBlbmQgKyAxKTtcblxuICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb24gPSBpdGVtcztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLmtleWJvYXJkLmlzQ3RybFByZXNzZWQpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZWxlY3Rpb24uaW5jbHVkZXMoaXRlbSkpXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb24ucHVzaChpdGVtKTtcbiAgICAgICAgICAgIGVsc2UgLy8gQ2FzZSB0aGF0IHdlIHNlbGVjdGVkIHRoZSBzYW1lIGl0ZW0gdHdpY2VcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvbi5zcGxpY2UodGhpcy5zZWxlY3Rpb24uaW5kZXhPZihpdGVtKSwgMSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb24gPSBbaXRlbV07XG5cbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0aW9uLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zZWxlY3Rpb25bMF0ua2luZCA9PSBcImRpcmVjdG9yeVwiKVxuICAgICAgICAgICAgICAgIHRoaXMuZm9sZGVyU2VsZWN0Lm5leHQodGhpcy5zZWxlY3Rpb25bMF0pO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHRoaXMuZmlsZVNlbGVjdC5uZXh0KHRoaXMuc2VsZWN0aW9uWzBdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLm5leHQodGhpcy5zZWxlY3Rpb24pO1xuICAgICAgICB0aGlzLnNlbGVjdGlvblRleHQgPSB0aGlzLmdldFNlbGVjdGlvblRleHQoKTtcbiAgICB9XG5cbiAgICBvbkl0ZW1DbGljayhmaWxlOiBGU0Rlc2NyaXB0b3IpIHtcbiAgICAgICAgY29uc29sZS5sb2coZmlsZSwgdGhpcyk7XG4gICAgICAgIGlmIChmaWxlLmtpbmQgPT0gXCJkaXJlY3RvcnlcIikge1xuICAgICAgICAgICAgdGhpcy5mb2xkZXJEYmxDbGljay5uZXh0KGZpbGUpO1xuICAgICAgICAgICAgdGhpcy5wYXRoID0gZmlsZS5wYXRoICsgZmlsZS5uYW1lO1xuICAgICAgICB9XG4gICAgICAgIC8vIGVsc2UgaWYgKGZpbGUuZXh0ID09IFwiemlwXCIpIHtcbiAgICAgICAgLy8gICAgIHRoaXMuZmlsZURibENsaWNrLm5leHQoZmlsZSk7XG4gICAgICAgIC8vICAgICB0aGlzLnBhdGggPSBmaWxlLnBhdGggKyBmaWxlLm5hbWU7XG4gICAgICAgIC8vIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmZpbGVEYmxDbGljay5uZXh0KGZpbGUpO1xuICAgICAgICAgICAgdGhpcy5maWxlU2VsZWN0Lm5leHQoZmlsZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblRvZ2dsZShpdGVtLCBzdGF0ZTogTWF0Q2hlY2tib3hDaGFuZ2UpIHtcbiAgICAgICAgaXRlbVsnX3ZhbHVlJ10gPSBzdGF0ZS5jaGVja2VkO1xuXG4gICAgICAgIC8vIFRPRE86IFdoYXQgY2F1c2VzIHRoaXMgdG8gYmUgbnVsbCB3aGVuIGluaXRpYWxpemVkIHdpdGggYW4gYXJyYXk/XG4gICAgICAgIGlmICghdGhpcy52YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN0YXRlLmNoZWNrZWQpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUucHVzaChpdGVtKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGkgPSB0aGlzLnZhbHVlLmZpbmRJbmRleCh2ID0+IHYgPT0gaXRlbSk7XG4gICAgICAgICAgICBpZiAoaSA+PSAwKVxuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUuc3BsaWNlKGksIDEpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmFsdWVDaGFuZ2UubmV4dCh0aGlzLnZhbHVlKTtcbiAgICB9XG5cbiAgICBhc3luYyBjbGVhclNlbGVjdGlvbigpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IFtdO1xuICAgICAgICB0aGlzLnZhbHVlQ2hhbmdlLm5leHQodGhpcy52YWx1ZSk7XG5cbiAgICAgICAgdGhpcy50YWJ1bGF0b3I/LnRhYmxlPy5nZXRSb3dzKCkuZm9yRWFjaChyID0+IHIuZ2V0RWxlbWVudCgpLmNsYXNzTGlzdC5yZW1vdmUoJ3NlbGVjdGVkJykpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3NvcnRGaWx0ZXIoKTogRmlsZURlc2NyaXB0b3JbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpcmVjdG9yeUNvbnRlbnRzID0gdGhpcy5kaXJlY3RvcnlDb250ZW50cz8uZmlsdGVyKGQgPT4gZC5raW5kID09ICdkaXJlY3RvcnknKVxuICAgICAgICAgICAgLmNvbmNhdCh0aGlzLmRpcmVjdG9yeUNvbnRlbnRzPy5maWx0ZXIoZCA9PiBkLmtpbmQgPT0gJ2ZpbGUnKVxuICAgICAgICAgICAgICAgIC5zb3J0KHRoaXMuc29ydGVyc1t0aGlzLnNvcnRPcmRlcl0pXG4gICAgICAgICAgICApIGFzIEZpbGVEZXNjcmlwdG9yW107XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTZWxlY3Rpb25UZXh0KCkge1xuICAgICAgICBjb25zdCBkaXJDb3VudCA9IHRoaXMuc2VsZWN0aW9uLmZpbHRlcihzID0+IHMua2luZCA9PSBcImRpcmVjdG9yeVwiKS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGZpbGVDb3VudCA9IHRoaXMuc2VsZWN0aW9uLmZpbHRlcihzID0+IHMua2luZCA9PSBcImZpbGVcIikubGVuZ3RoO1xuXG4gICAgICAgIGlmIChkaXJDb3VudCArIGZpbGVDb3VudCA9PSAwKSByZXR1cm4gXCJcIjtcblxuICAgICAgICBjb25zdCB0b3RhbFNpemUgPVxuICAgICAgICAgICAgdGhpcy5kaXJlY3RvcnlDb250ZW50c1xuICAgICAgICAgICAgICAgIC5maWx0ZXIoZCA9PiBkLmtpbmQgPT0gXCJmaWxlXCIpXG4gICAgICAgICAgICAgICAgLmZpbHRlcihkID0+IHRoaXMuc2VsZWN0aW9uPy5maW5kKGkgPT4gaS5uYW1lID09IGQubmFtZSkpXG4gICAgICAgICAgICAgICAgLm1hcChkID0+IGRbJ3N0YXRzJ10uc2l6ZSkucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCk7XG5cbiAgICAgICAgaWYgKGRpckNvdW50ICsgZmlsZUNvdW50ID09IDEpXG4gICAgICAgICAgICByZXR1cm4gYFwiJHt0aGlzLnNlbGVjdGlvblswXS5uYW1lfVwiIHNlbGVjdGVkICgke3RoaXMuYnl0ZXNUb1N0cmluZyh0b3RhbFNpemUpfSlgO1xuXG4gICAgICAgIGlmIChkaXJDb3VudCA+IDAgJiYgZmlsZUNvdW50ID09IDApXG4gICAgICAgICAgICByZXR1cm4gYFwiJHtkaXJDb3VudH1cIiBmb2xkZXJzIHNlbGVjdGVkYDtcbiAgICAgICAgaWYgKGZpbGVDb3VudCA+IDAgJiYgZGlyQ291bnQgPT0gMClcbiAgICAgICAgICAgIHJldHVybiBgJHtmaWxlQ291bnR9IGl0ZW1zIHNlbGVjdGVkICgke3RoaXMuYnl0ZXNUb1N0cmluZyh0b3RhbFNpemUpfSlgO1xuXG4gICAgICAgIHJldHVybiBgJHtkaXJDb3VudH0gZm9sZGVyJHtkaXJDb3VudCA9PSAxID8gXCJcIiA6IFwic1wifSBzZWxlY3RlZCwgJHtmaWxlQ291bnR9IG90aGVyIGl0ZW0ke2ZpbGVDb3VudCA9PSAxID8gXCJcIiA6IFwic1wifSBzZWxlY3RlZCAoJHt0aGlzLmJ5dGVzVG9TdHJpbmcodG90YWxTaXplKX0pYDtcbiAgICB9XG5cbiAgICBieXRlc1RvU3RyaW5nKGJ5dGVzOiBudW1iZXIsIGRlY2ltYWxzID0gMikge1xuICAgICAgICBpZiAoIStieXRlcykgcmV0dXJuICcwIEJ5dGVzJztcblxuICAgICAgICBjb25zdCBrID0gMTAyNDtcbiAgICAgICAgY29uc3QgZG0gPSBkZWNpbWFscyA8IDAgPyAwIDogZGVjaW1hbHM7XG4gICAgICAgIGNvbnN0IHNpemVzID0gWydCeXRlcycsICdLQicsICdNQicsICdHQicsICdUQicsICdQQicsICdFQicsICdaQicsICdZQiddO1xuXG4gICAgICAgIGNvbnN0IGkgPSBNYXRoLmZsb29yKE1hdGgubG9nKGJ5dGVzKSAvIE1hdGgubG9nKGspKTtcblxuICAgICAgICByZXR1cm4gYCR7cGFyc2VGbG9hdCgoYnl0ZXMgLyBNYXRoLnBvdyhrLCBpKSkudG9GaXhlZChkbSkpfSAke3NpemVzW2ldfWA7XG4gICAgfVxuXG4gICAgcHVibGljIHJlc2l6ZSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmZpbGVzUmVmKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMucmVzaXplKCksIDI1KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBib3VuZHMgPSAodGhpcy5maWxlc1JlZi5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50KS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgICBjb25zdCBuZXdDb2xDb3VudCA9IE1hdGguZmxvb3IoYm91bmRzLndpZHRoIC8gaXRlbVdpZHRoKTtcbiAgICAgICAgaWYgKG5ld0NvbENvdW50ICE9IHRoaXMuaXRlbXNQZXJSb3cpIHtcbiAgICAgICAgICAgIHRoaXMuaXRlbXNQZXJSb3cgPSBNYXRoLmZsb29yKGJvdW5kcy53aWR0aCAvIGl0ZW1XaWR0aCk7XG4gICAgICAgICAgICBpZiAodGhpcy5pdGVtc1BlclJvdyA+IDEwMClcbiAgICAgICAgICAgICAgICB0aGlzLml0ZW1zUGVyUm93ID0gMTtcblxuICAgICAgICAgICAgdGhpcy5mbG93Um93cygpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc29ydGVkRm9sZGVycz8ubGVuZ3RoID09IDApXG4gICAgICAgICAgICB0aGlzLmZsb3dSb3dzKCk7XG4gICAgfVxuXG4gICAgb25EcmFnU3RhcnQoZXZ0OiBEcmFnRXZlbnQsIGl0ZW06IEZTRGVzY3JpcHRvcikge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBgJHt3aW5kb3cub3JpZ2lufS9hcGkvZmlsZXN5c3RlbS9kb3dubG9hZD9kaXI9JHtpdGVtLnBhdGh9JmZpbGU9JHtpdGVtLm5hbWV9YDtcblxuICAgICAgICBldnQuZGF0YVRyYW5zZmVyLmNsZWFyRGF0YSgpO1xuICAgICAgICAvLyBldnQuZGF0YVRyYW5zZmVyLnNldERhdGEoJ3RleHQvdXJpLWxpc3QnLCB0YXJnZXQpO1xuICAgICAgICAvLyBldnQuZGF0YVRyYW5zZmVyLnNldERhdGEoJ0Rvd25sb2FkVVJMJywgYHRleHQvdXJpLWxpc3Q6JHt0YXJnZXR9YCk7XG4gICAgICAgIGV2dC5kYXRhVHJhbnNmZXIuc2V0RGF0YSgndGV4dC9wbGFpbicsIGl0ZW0ubmFtZSk7XG4gICAgfVxuXG4gICAgb25Ecm9wKGV2KSB7XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgaWYgKGV2LmRhdGFUcmFuc2Zlci5pdGVtcykge1xuICAgICAgICAgICAgLy8gVXNlIERhdGFUcmFuc2Zlckl0ZW1MaXN0IGludGVyZmFjZSB0byBhY2Nlc3MgdGhlIGZpbGUocylcbiAgICAgICAgICAgIFsuLi5ldi5kYXRhVHJhbnNmZXIuaXRlbXNdLmZvckVhY2goKGl0ZW0sIGkpID0+IHtcbiAgICAgICAgICAgIC8vIElmIGRyb3BwZWQgaXRlbXMgYXJlbid0IGZpbGVzLCByZWplY3QgdGhlbVxuICAgICAgICAgICAgaWYgKGl0ZW0ua2luZCA9PT0gXCJmaWxlXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlID0gaXRlbS5nZXRBc0ZpbGUoKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhg4oCmIGZpbGVbJHtpfV0ubmFtZSA9ICR7ZmlsZS5uYW1lfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBVc2UgRGF0YVRyYW5zZmVyIGludGVyZmFjZSB0byBhY2Nlc3MgdGhlIGZpbGUocylcbiAgICAgICAgICAgIFsuLi5ldi5kYXRhVHJhbnNmZXIuZmlsZXNdLmZvckVhY2goKGZpbGUsIGkpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGDigKYgZmlsZVske2l9XS5uYW1lID0gJHtmaWxlLm5hbWV9YCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5hbWVDZWxsRm9ybWF0dGVyID0gKChjZWxsOiBDZWxsQ29tcG9uZW50LCBmb3JtYXR0ZXJQYXJhbXM6IHt9LCBvblJlbmRlcmVkOiBFbXB0eUNhbGxiYWNrKSA9PiB7XG4gICAgICAgIC8vIFRPRE86IFNhbml0aXplP1xuICAgICAgICBjb25zdCBpdGVtID0gY2VsbC5nZXREYXRhKCkgYXMgRlNEZXNjcmlwdG9yO1xuICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgPGltZyBzdHlsZT1cImhlaWdodDogMjRweDsgbWFyZ2luLXJpZ2h0OiA2cHhcIiBzcmM9XCIke2l0ZW1bJ19pY29uJ10ucGF0aH1cIi8+XG4gICAgICAgICAgICAgICAgPHAgc3R5bGU9XCJtYXJnaW46IDBcIj4ke3RoaXMuc2FuaXRpemVyLnNhbml0aXplKFNlY3VyaXR5Q29udGV4dC5IVE1MLCBpdGVtWyd2YW5pdHlOYW1lJ10gfHwgaXRlbS5uYW1lKX08L3A+XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIGA7XG4gICAgfSkuYmluZCh0aGlzKVxuXG4gICAgb25Sb3dDdHgoe2V2ZW50LCByb3d9KSB7XG4gICAgICAgIG9wZW5NZW51KHRoaXMubWF0RGlhbG9nLCB0aGlzLmZpbGVDb250ZXh0TWVudSwgcm93LmdldERhdGEoKSwgZXZlbnQpO1xuICAgIH1cblxuICAgIG9uUm93Q2xpY2soe2V2ZW50LCByb3csIGRhdGF9KSB7XG4gICAgICAgIC8vICRldmVudC5kYXRhWydfdmFsdWUnXSA9ICRldmVudC5kYXRhWydfdmFsdWUnXSA9PSB0cnVlID8gZmFsc2UgOiB0cnVlXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGV2ZW50LCByb3csIGRhdGEsIHRoaXMudmFsdWUpO1xuXG4gICAgICAgIGNvbnN0IHJvd0VsID0gcm93LmdldEVsZW1lbnQoKTtcbiAgICAgICAgbGV0IHN0YXRlID0gcm93RWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdzZWxlY3RlZCcpO1xuICAgICAgICBkYXRhWydfdmFsdWUnXSA9ICFzdGF0ZTtcblxuICAgICAgICBpZiAoIXRoaXMudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc3RhdGUpIHtcbiAgICAgICAgICAgIHJvd0VsLmNsYXNzTGlzdC5hZGQoJ3NlbGVjdGVkJyk7XG4gICAgICAgICAgICB0aGlzLnZhbHVlLnB1c2goZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByb3dFbC5jbGFzc0xpc3QucmVtb3ZlKCdzZWxlY3RlZCcpO1xuICAgICAgICAgICAgY29uc3QgaSA9IHRoaXMudmFsdWUuZmluZEluZGV4KHYgPT4gdiA9PSBkYXRhKTtcbiAgICAgICAgICAgIGlmIChpID49IDApXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZS5zcGxpY2UoaSwgMSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZhbHVlQ2hhbmdlLm5leHQodGhpcy52YWx1ZSk7XG4gICAgfVxuXG4gICAgc29ydCgpIHtcbiAgICAgICAgdGhpcy5fc29ydEZpbHRlcigpO1xuICAgIH1cbn1cblxuXG5cblxuXG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwic2hvd0xvYWRlclwiPlxuICAgIDxtYXQtcHJvZ3Jlc3MtYmFyIFtjbGFzcy5oaWRlXT1cImhpZGVMb2FkZXJcIiBtb2RlPVwicXVlcnlcIi8+XG48L25nLWNvbnRhaW5lcj5cblxuPGRpdlxuICAgIHN0eWxlPVwiZGlzcGxheTogY29udGVudHNcIlxuICAgIFtzdHlsZS4tLWZpbGVtYW5hZ2VyLWZpbGVpY29uLWJhY2tkcm9wXT1cIid1cmwoJyArIGljb25SZXNvbHZlci5wYXRoICsgJy9wb3AvZ2VuZXJpYy5zdmcpJ1wiXG4gICAgKGRyYWdzdGFydCk9XCJ1c2VySXNEcmFnZ2luZ0ZpbGUgPSB0cnVlXCJcbiAgICAoZHJhZ2VuZCk9XCJ1c2VySXNEcmFnZ2luZ0ZpbGUgPSBmYWxzZVwiXG4gICAgKGRyYWdvdmVyKT1cImRyYWdnaW5nT3ZlciA9IHRydWVcIlxuICAgIChkcmFnbGVhdmUpPVwiZHJhZ2dpbmdPdmVyID0gZmFsc2VcIlxuICAgIChvbmRyb3ApPVwib25Ecm9wKCRldmVudClcIlxuPlxuICAgIDwhLS0gPG5nLWNvbnRhaW5lciAqbmdJZj1cImRyYWdnaW5nT3ZlclwiPjwvbmctY29udGFpbmVyPiAtLT5cbiAgICA8IS0tIEdyaWQgbW9kZSAtLT5cbiAgICA8bmctc2Nyb2xsYmFyXG4gICAgICAgICpuZ0lmPVwidmlld01vZGUgPT0gJ2dyaWQnXCJcbiAgICAgICAgY2xhc3M9XCJncmlkIHt7Z3JpZFNpemV9fSB7e2NvbmZpZy5pbWFnZVNpemUgfHwgJ25vcm1hbCd9fVwiXG4gICAgICAgIFtjbGFzcy5zZWxlY3Rpb25Nb2RlXT1cImNvbmZpZy5tb2RlID09ICdmb2N1c0ZpbGVzJ1wiXG4gICAgICAgIFtjbGFzcy5zaG93RHJvcEFyZWFdPVwiZHJhZ2dpbmdPdmVyXCJcbiAgICAgICAgc3R5bGU9XCJoZWlnaHQ6IDEwMCU7IHdpZHRoOiAxMDAlXCJcbiAgICAgICAgdHJhY2s9XCJ2ZXJ0aWNhbFwiXG4gICAgICAgIHBvaW50ZXJFdmVudHNNZXRob2Q9XCJzY3JvbGxiYXJcIlxuICAgICAgICBbbmd4LWNvbnRleHRtZW51XT1cImZvbGRlckNvbnRleHRNZW51XCJcbiAgICA+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpemUtb2JzZXJ2ZXJcIiAjZmlsZVZpZXdwb3J0PjwvZGl2PlxuICAgICAgICA8Y2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0XG4gICAgICAgICAgICBpdGVtU2l6ZT1cIjEzNFwiXG4gICAgICAgICAgICBzY3JvbGxWaWV3cG9ydFxuICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdGlvbiA9IFtdOyBzZWxlY3Rpb25UZXh0ID0gJydcIlxuICAgICAgICA+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKmNka1ZpcnR1YWxGb3I9XCJsZXQgcm93IG9mIHNvcnRlZEZvbGRlcnNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmlsZVwiXG4gICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJvd1wiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJzZWxlY3Rpb24uaW5jbHVkZXMoaXRlbSlcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuZ2VuZXJpY109XCJpdGVtWydfaWNvbiddLm5lZWRzQmFja2Ryb3BcIlxuICAgICAgICAgICAgICAgICAgICBbbmd4LWNvbnRleHRtZW51XT1cImZpbGVDb250ZXh0TWVudVwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ3gtbWVudS1jb250ZXh0XT1cIml0ZW1cIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgICAgI2NoZWNrYm94XG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbmZpZy5tb2RlID09ICdmb2N1c0ZpbGVzJyAmJiBpdGVtLmtpbmQgPT0gJ2ZpbGUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cIml0ZW1bJ192YWx1ZSddXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25Ub2dnbGUoaXRlbSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwiZGlzcGxheTogY29udGVudHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uU2VsZWN0KGl0ZW0sICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGRibGNsaWNrKT1cIm9uSXRlbUNsaWNrKGl0ZW0pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChkcmFnc3RhcnQpPVwib25EcmFnU3RhcnQoJGV2ZW50LCBpdGVtKVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgW3NyY109XCJpdGVtWydfaWNvbiddLnBhdGhcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cD57e2l0ZW1bJ3Zhbml0eU5hbWUnXSB8fCBpdGVtLm5hbWV9fTwvcD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9jZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnQ+XG4gICAgPC9uZy1zY3JvbGxiYXI+XG5cbiAgICA8IS0tIExpc3QgbW9kZSAtLT5cbiAgICA8ZGl2XG4gICAgICAgICpuZ0lmPVwidmlld01vZGUgPT0gJ2xpc3QnXCJcbiAgICAgICAgc3R5bGU9XCJ3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlXCJcbiAgICAgICAgW2NsYXNzLnNob3dEcm9wQXJlYV09XCJkcmFnZ2luZ092ZXJcIlxuICAgICAgICBbbmd4LWNvbnRleHRtZW51XT1cImZvbGRlckNvbnRleHRNZW51XCJcbiAgICA+XG4gICAgICAgIDxhcHAtdGFidWxhdG9yXG4gICAgICAgICAgICBbZGF0YVNvdXJjZV09XCJkaXJlY3RvcnlDb250ZW50c1wiXG4gICAgICAgICAgICBbY29sdW1uc109XCJbXG4gICAgICAgICAgICAgICAgeyBmaWVsZDogJ25hbWUnLCB0aXRsZTogJ05hbWUnLCBmb3JtYXR0ZXI6IG5hbWVDZWxsRm9ybWF0dGVyIH0sXG4gICAgICAgICAgICAgICAgeyBmaWVsZDogJ19zaXplJywgdGl0bGU6ICdTaXplJyB9LFxuICAgICAgICAgICAgICAgIHsgZmllbGQ6ICdfY3RpbWUnLCB0aXRsZTogJ0NyZWF0ZWQnIH0sXG4gICAgICAgICAgICAgICAgeyBmaWVsZDogJ19tdGltZScsIHRpdGxlOiAnTW9kaWZpZWQnIH0sXG4gICAgICAgICAgICBdXCJcbiAgICAgICAgICAgIFtvcHRpb25zXT1cIntcbiAgICAgICAgICAgICAgICByb3dIZWlnaHQ6IDMyXG4gICAgICAgICAgICB9XCJcbiAgICAgICAgICAgIChyb3dDbGljayk9XCJvblJvd0NsaWNrKCRldmVudClcIlxuICAgICAgICAgICAgKHJvd0RibENsaWNrKT1cIm9uSXRlbUNsaWNrKCRldmVudC5kYXRhKVwiXG4gICAgICAgICAgICAocm93Q29udGV4dCk9XCJvblJvd0N0eCgkZXZlbnQpXCJcbiAgICAgICAgLz5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuXG48ZGl2IGNsYXNzPVwic2VsZWN0LWhpbnRcIiAqbmdJZj1cInNlbGVjdGlvblRleHRcIj5cbiAgICB7e3NlbGVjdGlvblRleHR9fVxuPC9kaXY+XG5cbiJdfQ==
|