@pepperi-addons/ngx-composite-lib 0.4.2-beta.194 → 0.4.2-beta.197
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/esm2020/color-settings/color-settings.component.mjs +1 -1
- package/esm2020/icon-picker/icon-picker.component.mjs +1 -1
- package/esm2020/layout-builder/main-editor/main-editor.component.mjs +1 -1
- package/esm2020/layout-builder/section-editor/section-editor.component.mjs +1 -1
- package/esm2020/layout-builder2/hide-in/hide-in.component.mjs +54 -0
- package/esm2020/layout-builder2/hide-in/hide-in.module.mjs +81 -0
- package/esm2020/layout-builder2/layout/layout.component.mjs +266 -0
- package/esm2020/layout-builder2/layout/layout.module.mjs +55 -0
- package/esm2020/layout-builder2/layout-builder-editor/layout-builder-editor.component.mjs +25 -0
- package/esm2020/layout-builder2/layout-builder-editor/layout-builder-editor.module.mjs +45 -0
- package/esm2020/layout-builder2/layout-builder-internal.service.mjs +639 -0
- package/esm2020/layout-builder2/layout-builder.component.mjs +357 -0
- package/esm2020/layout-builder2/layout-builder.model.mjs +2 -0
- package/esm2020/layout-builder2/layout-builder.module.mjs +145 -0
- package/esm2020/layout-builder2/layout-builder.service.mjs +49 -0
- package/esm2020/layout-builder2/layout-content.directive.mjs +13 -0
- package/esm2020/layout-builder2/main-editor/main-editor.component.mjs +170 -0
- package/esm2020/layout-builder2/main-editor/main-editor.module.mjs +99 -0
- package/esm2020/layout-builder2/pepperi-addons-ngx-composite-lib-layout-builder2.mjs +5 -0
- package/esm2020/layout-builder2/public-api.mjs +13 -0
- package/esm2020/layout-builder2/section/section.component.mjs +382 -0
- package/esm2020/layout-builder2/section/section.module.mjs +44 -0
- package/esm2020/layout-builder2/section-block/section-block.component.mjs +172 -0
- package/esm2020/layout-builder2/section-block/section-block.module.mjs +34 -0
- package/esm2020/layout-builder2/section-editor/section-editor.component.mjs +204 -0
- package/esm2020/layout-builder2/section-editor/section-editor.module.mjs +48 -0
- package/esm2020/padding-settings/padding-settings.component.mjs +1 -1
- package/esm2020/shadow-settings/shadow-settings.component.mjs +1 -1
- package/fesm2015/pepperi-addons-ngx-composite-lib-color-settings.mjs +1 -1
- package/fesm2015/pepperi-addons-ngx-composite-lib-color-settings.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-composite-lib-icon-picker.mjs +1 -1
- package/fesm2015/pepperi-addons-ngx-composite-lib-icon-picker.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-composite-lib-layout-builder.mjs +2 -2
- package/fesm2015/pepperi-addons-ngx-composite-lib-layout-builder.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-composite-lib-layout-builder2.mjs +2755 -0
- package/fesm2015/pepperi-addons-ngx-composite-lib-layout-builder2.mjs.map +1 -0
- package/fesm2015/pepperi-addons-ngx-composite-lib-padding-settings.mjs +1 -1
- package/fesm2015/pepperi-addons-ngx-composite-lib-padding-settings.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-composite-lib-shadow-settings.mjs +1 -1
- package/fesm2015/pepperi-addons-ngx-composite-lib-shadow-settings.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-composite-lib-color-settings.mjs +1 -1
- package/fesm2020/pepperi-addons-ngx-composite-lib-color-settings.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-composite-lib-icon-picker.mjs +1 -1
- package/fesm2020/pepperi-addons-ngx-composite-lib-icon-picker.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-composite-lib-layout-builder.mjs +2 -2
- package/fesm2020/pepperi-addons-ngx-composite-lib-layout-builder.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-composite-lib-layout-builder2.mjs +2717 -0
- package/fesm2020/pepperi-addons-ngx-composite-lib-layout-builder2.mjs.map +1 -0
- package/fesm2020/pepperi-addons-ngx-composite-lib-padding-settings.mjs +1 -1
- package/fesm2020/pepperi-addons-ngx-composite-lib-padding-settings.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-composite-lib-shadow-settings.mjs +1 -1
- package/fesm2020/pepperi-addons-ngx-composite-lib-shadow-settings.mjs.map +1 -1
- package/layout-builder2/hide-in/hide-in.component.d.ts +25 -0
- package/layout-builder2/hide-in/hide-in.component.theme.scss +9 -0
- package/layout-builder2/hide-in/hide-in.module.d.ts +20 -0
- package/layout-builder2/index.d.ts +5 -0
- package/layout-builder2/layout/layout.component.d.ts +58 -0
- package/layout-builder2/layout/layout.module.d.ts +16 -0
- package/layout-builder2/layout-builder-editor/layout-builder-editor.component.d.ts +12 -0
- package/layout-builder2/layout-builder-editor/layout-builder-editor.module.d.ts +14 -0
- package/layout-builder2/layout-builder-internal.service.d.ts +118 -0
- package/layout-builder2/layout-builder.component.d.ts +87 -0
- package/layout-builder2/layout-builder.component.theme.scss +57 -0
- package/layout-builder2/layout-builder.model.d.ts +43 -0
- package/layout-builder2/layout-builder.module.d.ts +33 -0
- package/layout-builder2/layout-builder.service.d.ts +24 -0
- package/layout-builder2/layout-content.directive.d.ts +5 -0
- package/layout-builder2/main-editor/main-editor.component.d.ts +52 -0
- package/layout-builder2/main-editor/main-editor.module.d.ts +27 -0
- package/layout-builder2/public-api.d.ts +9 -0
- package/layout-builder2/section/section.component.d.ts +86 -0
- package/layout-builder2/section/section.component.theme.scss +115 -0
- package/layout-builder2/section/section.module.d.ts +14 -0
- package/layout-builder2/section-block/section-block.component.d.ts +48 -0
- package/layout-builder2/section-block/section-block.component.theme.scss +13 -0
- package/layout-builder2/section-block/section-block.module.d.ts +11 -0
- package/layout-builder2/section-editor/section-editor.component.d.ts +56 -0
- package/layout-builder2/section-editor/section-editor.module.d.ts +15 -0
- package/package.json +10 -2
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
import { Injectable } from "@angular/core";
|
|
2
|
+
import { coerceNumberProperty } from "@angular/cdk/coercion";
|
|
3
|
+
import { moveItemInArray } from "@angular/cdk/drag-drop";
|
|
4
|
+
import { PepGuid, PepScreenSizeType } from "@pepperi-addons/ngx-lib";
|
|
5
|
+
import { BehaviorSubject } from 'rxjs';
|
|
6
|
+
import { distinctUntilChanged, filter } from 'rxjs/operators';
|
|
7
|
+
import { PepDialogData } from "@pepperi-addons/ngx-lib/dialog";
|
|
8
|
+
import { PepPaddingSettings } from "@pepperi-addons/ngx-composite-lib/padding-settings";
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
import * as i1 from "@ngx-translate/core";
|
|
11
|
+
import * as i2 from "@pepperi-addons/ngx-lib/dialog";
|
|
12
|
+
import * as i3 from "@pepperi-addons/ngx-lib";
|
|
13
|
+
export class LayoutBuilderInternalService {
|
|
14
|
+
// // This subject is for skeleton.
|
|
15
|
+
// private _showSkeletonSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
|
16
|
+
// get showSkeletonChange$(): Observable<boolean> {
|
|
17
|
+
// return this._showSkeletonSubject.asObservable().pipe(distinctUntilChanged());
|
|
18
|
+
// }
|
|
19
|
+
constructor(translate, dialogService, layoutService) {
|
|
20
|
+
this.translate = translate;
|
|
21
|
+
this.dialogService = dialogService;
|
|
22
|
+
this.layoutService = layoutService;
|
|
23
|
+
this._manageGlobalCursor = true;
|
|
24
|
+
this._defaultSectionTitle = '';
|
|
25
|
+
// This configuration is for blocks behavior.
|
|
26
|
+
this._blocksLimitNumber = 0;
|
|
27
|
+
this._navigateToEditorAfterBlockAdded = false;
|
|
28
|
+
this._getBlockTitle = (blockKey) => { return blockKey; };
|
|
29
|
+
this._editorsBreadCrumb = Array();
|
|
30
|
+
this._editorMode = false;
|
|
31
|
+
this._editableState = false;
|
|
32
|
+
// This subject is for the screen size change events.
|
|
33
|
+
this._screenSizeSubject = new BehaviorSubject(undefined);
|
|
34
|
+
// This subject is for demostrate the container size (Usage only in edit mode).
|
|
35
|
+
this._screenWidthSubject = new BehaviorSubject('100%');
|
|
36
|
+
// This subject is for load the current editor (Usage only in edit mode).
|
|
37
|
+
this._editorSubject = new BehaviorSubject(null);
|
|
38
|
+
// This is the sections columns drop list subject.
|
|
39
|
+
this._sectionsColumnsDropListSubject = new BehaviorSubject([]);
|
|
40
|
+
// This is the sections subject (a pare from the layout view object)
|
|
41
|
+
this._sectionsViewSubject = new BehaviorSubject([]);
|
|
42
|
+
// This subject is for layout view change.
|
|
43
|
+
this._layoutViewSubject = new BehaviorSubject(null);
|
|
44
|
+
// This subject is for edit mode when block is dragging now or not.
|
|
45
|
+
this._draggingBlockKey = new BehaviorSubject('');
|
|
46
|
+
// This subject is for edit mode when section is dragging now or not.
|
|
47
|
+
this._draggingSectionKey = new BehaviorSubject('');
|
|
48
|
+
// // This subject is for lock or unlock the screen (Usage only in edit mode).
|
|
49
|
+
// private _lockScreenSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
|
50
|
+
// get lockScreenChange$(): Observable<boolean> {
|
|
51
|
+
// return this._lockScreenSubject.asObservable().pipe(distinctUntilChanged());
|
|
52
|
+
// }
|
|
53
|
+
// This is for control the preview mode (for load the blocks with the CPI events)
|
|
54
|
+
this._previewModeSubject = new BehaviorSubject(false);
|
|
55
|
+
// This is for editor mode for block added.
|
|
56
|
+
this._blockAddedEventSubject = new BehaviorSubject(null);
|
|
57
|
+
// This is for editor mode for blocks removed.
|
|
58
|
+
this._blocksRemovedEventSubject = new BehaviorSubject([]);
|
|
59
|
+
//
|
|
60
|
+
this.translate.get('LAYOUT_BUILDER.SECTION').subscribe((res) => {
|
|
61
|
+
// Set the default section name.
|
|
62
|
+
this._defaultSectionTitle = res;
|
|
63
|
+
});
|
|
64
|
+
this.layoutService.onResize$.subscribe((size) => {
|
|
65
|
+
this.notifyScreenSizeChange(size);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
setBlocksConfig(value) {
|
|
69
|
+
this._blocksLimitNumber = value.blocksLimitNumber || 0;
|
|
70
|
+
this._navigateToEditorAfterBlockAdded = value.navigateToEditorAfterBlockAdded ?? false;
|
|
71
|
+
this._getBlockTitle = value.getBlockTitle ? value.getBlockTitle : (blockKey) => { return blockKey; };
|
|
72
|
+
}
|
|
73
|
+
get editorMode() {
|
|
74
|
+
return this._editorMode;
|
|
75
|
+
}
|
|
76
|
+
setEditorMode(value) {
|
|
77
|
+
this._editorMode = value;
|
|
78
|
+
this.setEditableState();
|
|
79
|
+
}
|
|
80
|
+
get editableState() {
|
|
81
|
+
return this._editableState;
|
|
82
|
+
}
|
|
83
|
+
get screenSizeChange$() {
|
|
84
|
+
return this._screenSizeSubject.asObservable().pipe(distinctUntilChanged());
|
|
85
|
+
}
|
|
86
|
+
get screenWidthChange$() {
|
|
87
|
+
return this._screenWidthSubject.asObservable().pipe(distinctUntilChanged());
|
|
88
|
+
}
|
|
89
|
+
get editorChange$() {
|
|
90
|
+
return this._editorSubject.asObservable().pipe(distinctUntilChanged());
|
|
91
|
+
}
|
|
92
|
+
get sectionsColumnsDropListChange$() {
|
|
93
|
+
return this._sectionsColumnsDropListSubject.asObservable();
|
|
94
|
+
}
|
|
95
|
+
get sectionsChange$() {
|
|
96
|
+
return this._sectionsViewSubject.asObservable();
|
|
97
|
+
// (prevSections, nextSections) => JSON.stringify(prevSections) === JSON.stringify(nextSections)));
|
|
98
|
+
}
|
|
99
|
+
get layoutViewChange$() {
|
|
100
|
+
return this._layoutViewSubject.asObservable().pipe(filter(layout => !!layout));
|
|
101
|
+
}
|
|
102
|
+
get draggingBlockKey() {
|
|
103
|
+
return this._draggingBlockKey.asObservable().pipe(distinctUntilChanged());
|
|
104
|
+
}
|
|
105
|
+
get draggingSectionKey() {
|
|
106
|
+
return this._draggingSectionKey.asObservable().pipe(distinctUntilChanged());
|
|
107
|
+
}
|
|
108
|
+
get previewModeChange$() {
|
|
109
|
+
return this._previewModeSubject.asObservable().pipe(distinctUntilChanged());
|
|
110
|
+
}
|
|
111
|
+
get blockAddedEventSubject$() {
|
|
112
|
+
return this._blockAddedEventSubject.asObservable();
|
|
113
|
+
}
|
|
114
|
+
get blocksRemovedEventSubject$() {
|
|
115
|
+
return this._blocksRemovedEventSubject.asObservable();
|
|
116
|
+
}
|
|
117
|
+
setEditableState() {
|
|
118
|
+
this._editableState = this.editorMode && !this._previewModeSubject.getValue();
|
|
119
|
+
}
|
|
120
|
+
notifyLayoutViewChange(layoutViewToUpdate) {
|
|
121
|
+
if (layoutViewToUpdate) {
|
|
122
|
+
if (this.editorMode) {
|
|
123
|
+
this.updateLayoutEditorProperties(layoutViewToUpdate);
|
|
124
|
+
}
|
|
125
|
+
// Update the layout for the view.
|
|
126
|
+
this._layoutViewSubject.next(layoutViewToUpdate);
|
|
127
|
+
// Update the sections for the view.
|
|
128
|
+
this._sectionsViewSubject.next(layoutViewToUpdate?.Layout.Sections || []);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
notifyBlockAdded(blockAddedEventData) {
|
|
132
|
+
// Notify that the block is added (to raise the event for the client).
|
|
133
|
+
this._blockAddedEventSubject.next(blockAddedEventData);
|
|
134
|
+
}
|
|
135
|
+
notifyBlocksRemoved(keys) {
|
|
136
|
+
if (keys) {
|
|
137
|
+
// Notify that the blocks are removed (to raise the event for the client).
|
|
138
|
+
this._blocksRemovedEventSubject.next(keys);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
notifyEditorChange(editor) {
|
|
142
|
+
this._editorSubject.next(editor);
|
|
143
|
+
}
|
|
144
|
+
notifyPreviewModeChange(value) {
|
|
145
|
+
this._previewModeSubject.next(value);
|
|
146
|
+
this.setEditableState();
|
|
147
|
+
}
|
|
148
|
+
// private notifyLockScreen(value: boolean) {
|
|
149
|
+
// this._lockScreenSubject.next(value);
|
|
150
|
+
// }
|
|
151
|
+
notifySectionsColumnsDropListChange(sectionsColumnsDropList) {
|
|
152
|
+
this._sectionsColumnsDropListSubject.next(sectionsColumnsDropList);
|
|
153
|
+
}
|
|
154
|
+
notifyScreenSizeChange(size) {
|
|
155
|
+
this._screenSizeSubject.next(size);
|
|
156
|
+
}
|
|
157
|
+
updateLayoutEditorProperties(layoutView) {
|
|
158
|
+
if (this._editorsBreadCrumb[0]) {
|
|
159
|
+
const layoutEditor = {
|
|
160
|
+
maxWidth: layoutView?.Layout.MaxWidth || 0,
|
|
161
|
+
verticalSpacing: layoutView?.Layout.VerticalSpacing,
|
|
162
|
+
horizontalSpacing: layoutView?.Layout.HorizontalSpacing,
|
|
163
|
+
sectionsGap: layoutView?.Layout.SectionsGap,
|
|
164
|
+
columnsGap: layoutView?.Layout.ColumnsGap,
|
|
165
|
+
// roundedCorners: layoutView?.Layout.RoundedCorners
|
|
166
|
+
};
|
|
167
|
+
this._editorsBreadCrumb[0].hostObject = layoutEditor;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
loadDefaultEditor(layoutView) {
|
|
171
|
+
this._editorsBreadCrumb = new Array();
|
|
172
|
+
if (layoutView) {
|
|
173
|
+
this.translate.get('LAYOUT_BUILDER.DEFAULT_TITLE').subscribe((title) => {
|
|
174
|
+
this._editorsBreadCrumb.push({
|
|
175
|
+
id: LayoutBuilderInternalService.MAIN_EDITOR_ID,
|
|
176
|
+
type: 'layout-builder',
|
|
177
|
+
title: title,
|
|
178
|
+
// hostObject: {} // Updates in updateLayoutEditorProperties function above.
|
|
179
|
+
});
|
|
180
|
+
this.updateLayoutEditorProperties(layoutView);
|
|
181
|
+
this.notifyEditorChange(this._editorsBreadCrumb[0]);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
this.notifyEditorChange(null);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
changeCurrentEditor() {
|
|
189
|
+
if (this._editorsBreadCrumb.length > 0) {
|
|
190
|
+
this.notifyEditorChange(this._editorsBreadCrumb[this._editorsBreadCrumb.length - 1]);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
getEditorByType(editorType, id, title = '') {
|
|
194
|
+
// Build editor object.
|
|
195
|
+
let editor = null;
|
|
196
|
+
if (editorType === 'section') {
|
|
197
|
+
editor = this.getSectionEditor(id, title);
|
|
198
|
+
}
|
|
199
|
+
else if (editorType === 'block') {
|
|
200
|
+
editor = this.getBlockEditor(id, title);
|
|
201
|
+
}
|
|
202
|
+
return editor;
|
|
203
|
+
}
|
|
204
|
+
getBlockEditor(blockKey, title) {
|
|
205
|
+
// Get block editor title.
|
|
206
|
+
const blockTitle = title || this.getBlockTitle(blockKey);
|
|
207
|
+
return {
|
|
208
|
+
id: blockKey,
|
|
209
|
+
type: 'block',
|
|
210
|
+
title: blockTitle
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
getSectionEditorTitle(section, sectionIndex) {
|
|
214
|
+
return section.Name || `${this._defaultSectionTitle} ${sectionIndex + 1}`;
|
|
215
|
+
}
|
|
216
|
+
getSectionEditor(sectionId, title) {
|
|
217
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
218
|
+
const sections = layoutView?.Layout.Sections || [];
|
|
219
|
+
const sectionIndex = sections.findIndex(section => section.Key === sectionId);
|
|
220
|
+
if (sectionIndex >= 0) {
|
|
221
|
+
const section = sections[sectionIndex];
|
|
222
|
+
const sectionEditor = {
|
|
223
|
+
id: section.Key,
|
|
224
|
+
sectionName: section.Name || '',
|
|
225
|
+
split: section.Split || undefined,
|
|
226
|
+
height: section.Height || 0,
|
|
227
|
+
collapseOnTablet: section.CollapseOnTablet ?? false,
|
|
228
|
+
fillHeight: section.FillHeight ?? false,
|
|
229
|
+
padding: section.Padding || new PepPaddingSettings(true, '0')
|
|
230
|
+
};
|
|
231
|
+
return {
|
|
232
|
+
id: sectionId,
|
|
233
|
+
type: 'section',
|
|
234
|
+
title: title || this.getSectionEditorTitle(section, sectionIndex),
|
|
235
|
+
hostObject: sectionEditor
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
getSectionColumnByIdForEditor(sectionColumnId) {
|
|
243
|
+
let currentColumn = null;
|
|
244
|
+
// Get the section and column array by the pattern of the section column key.
|
|
245
|
+
const sectionColumnPatternSeparator = this.getSectionColumnKey();
|
|
246
|
+
const sectionColumnArr = sectionColumnId.split(sectionColumnPatternSeparator);
|
|
247
|
+
if (sectionColumnArr.length === 2) {
|
|
248
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
249
|
+
const sections = layoutView?.Layout.Sections || [];
|
|
250
|
+
// Get the section id to get the section index.
|
|
251
|
+
const sectionId = sectionColumnArr[0];
|
|
252
|
+
const sectionIndex = sections.findIndex(section => section.Key === sectionId);
|
|
253
|
+
// Get the column index.
|
|
254
|
+
const columnIndex = coerceNumberProperty(sectionColumnArr[1], -1);
|
|
255
|
+
if (sectionIndex >= 0 && columnIndex >= 0) {
|
|
256
|
+
currentColumn = sections[sectionIndex].Columns[columnIndex];
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return currentColumn;
|
|
260
|
+
}
|
|
261
|
+
getCssScreenWidh(screenType) {
|
|
262
|
+
let widthToSet = '100%';
|
|
263
|
+
if (screenType === 'Tablet') {
|
|
264
|
+
widthToSet = '720';
|
|
265
|
+
}
|
|
266
|
+
else if (screenType === 'Phablet') {
|
|
267
|
+
widthToSet = '360';
|
|
268
|
+
}
|
|
269
|
+
return widthToSet;
|
|
270
|
+
}
|
|
271
|
+
getBlocksNumber() {
|
|
272
|
+
let blocksNumber = 0;
|
|
273
|
+
const sections = this._layoutViewSubject.getValue()?.Layout.Sections || [];
|
|
274
|
+
for (let index = 0; index < sections.length; index++) {
|
|
275
|
+
const section = sections[index];
|
|
276
|
+
for (let columnIndex = 0; columnIndex < section.Columns.length; columnIndex++) {
|
|
277
|
+
const column = section.Columns[columnIndex];
|
|
278
|
+
if (column.BlockContainer && column.BlockContainer.BlockKey?.length > 0) {
|
|
279
|
+
blocksNumber++;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return blocksNumber;
|
|
284
|
+
}
|
|
285
|
+
changeCursorOnDragStart() {
|
|
286
|
+
if (this._manageGlobalCursor) {
|
|
287
|
+
document.body.classList.add('inheritCursors');
|
|
288
|
+
document.body.style.cursor = 'grabbing';
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
changeCursorOnDragEnd() {
|
|
292
|
+
if (this._manageGlobalCursor) {
|
|
293
|
+
document.body.classList.remove('inheritCursors');
|
|
294
|
+
document.body.style.cursor = 'unset';
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/***********************************************************************************************/
|
|
298
|
+
/* Public functions
|
|
299
|
+
/***********************************************************************************************/
|
|
300
|
+
getCurrentLayoutView() {
|
|
301
|
+
return this._layoutViewSubject.getValue();
|
|
302
|
+
}
|
|
303
|
+
getBlockTitle(blockKey) {
|
|
304
|
+
return this._getBlockTitle(blockKey) || blockKey;
|
|
305
|
+
}
|
|
306
|
+
setManageGlobalCursor(value) {
|
|
307
|
+
this._manageGlobalCursor = value;
|
|
308
|
+
}
|
|
309
|
+
setSectionsColumnsDropListChange(sectionsColumnsDropList) {
|
|
310
|
+
this.notifySectionsColumnsDropListChange(sectionsColumnsDropList);
|
|
311
|
+
}
|
|
312
|
+
changePreviewMode(value) {
|
|
313
|
+
this.notifyPreviewModeChange(value);
|
|
314
|
+
}
|
|
315
|
+
getCurrentScreenType() {
|
|
316
|
+
return this.getScreenType(this._screenSizeSubject?.getValue() || PepScreenSizeType.LG);
|
|
317
|
+
}
|
|
318
|
+
getScreenType(size) {
|
|
319
|
+
const screenType = size < PepScreenSizeType.MD ? 'Landscape' :
|
|
320
|
+
(size === PepScreenSizeType.MD || size === PepScreenSizeType.SM ? 'Tablet' : 'Phablet');
|
|
321
|
+
return screenType;
|
|
322
|
+
}
|
|
323
|
+
getSectionColumnKey(sectionKey = '', index = '') {
|
|
324
|
+
return `${sectionKey}_column_${index}`;
|
|
325
|
+
}
|
|
326
|
+
getIsHidden(hideIn, currentScreenType) {
|
|
327
|
+
return (hideIn && hideIn?.length > 0) ? hideIn.some(hi => hi === currentScreenType) : false;
|
|
328
|
+
}
|
|
329
|
+
navigateToEditor(editorType, id, title = '') {
|
|
330
|
+
let success = false;
|
|
331
|
+
// Cannot navigate into 'layout-builder' because this is first and const in the editorsBreadCrumbs.
|
|
332
|
+
if (editorType !== 'layout-builder' && id?.length > 0) {
|
|
333
|
+
// Check which editor we have now
|
|
334
|
+
const currentEditor = this._editorsBreadCrumb[this._editorsBreadCrumb.length - 1];
|
|
335
|
+
// Only if it's another editor.
|
|
336
|
+
if (currentEditor.id !== id) {
|
|
337
|
+
if (currentEditor.type !== 'layout-builder') {
|
|
338
|
+
// Always pop the last and insert the current.
|
|
339
|
+
this._editorsBreadCrumb.pop();
|
|
340
|
+
}
|
|
341
|
+
const editor = this.getEditorByType(editorType, id, title);
|
|
342
|
+
if (editor) {
|
|
343
|
+
this._editorsBreadCrumb.push(editor);
|
|
344
|
+
this.changeCurrentEditor();
|
|
345
|
+
success = true;
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
success = false;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return success;
|
|
353
|
+
}
|
|
354
|
+
navigateBackFromEditor() {
|
|
355
|
+
// Keep the layout builder editor.
|
|
356
|
+
if (this._editorsBreadCrumb.length > 1) {
|
|
357
|
+
// Maybe we want to compare the last editor for validation ?
|
|
358
|
+
const lastEditor = this._editorsBreadCrumb.pop();
|
|
359
|
+
this.changeCurrentEditor();
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
updateLayoutFromEditor(editorData) {
|
|
363
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
364
|
+
if (layoutView) {
|
|
365
|
+
layoutView.Layout.MaxWidth = editorData.maxWidth;
|
|
366
|
+
layoutView.Layout.HorizontalSpacing = editorData.horizontalSpacing;
|
|
367
|
+
layoutView.Layout.VerticalSpacing = editorData.verticalSpacing;
|
|
368
|
+
layoutView.Layout.SectionsGap = editorData.sectionsGap;
|
|
369
|
+
layoutView.Layout.ColumnsGap = editorData.columnsGap;
|
|
370
|
+
// layoutView.Layout.RoundedCorners = editorData.roundedCorners;
|
|
371
|
+
this.notifyLayoutViewChange(layoutView);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
updateSectionFromEditor(sectionData) {
|
|
375
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
376
|
+
const sections = layoutView?.Layout.Sections || [];
|
|
377
|
+
const sectionIndex = sections.findIndex(section => section.Key === sectionData.id);
|
|
378
|
+
// Update section details.
|
|
379
|
+
if (sectionIndex >= 0) {
|
|
380
|
+
const blocksIdsToRemove = [];
|
|
381
|
+
const currentSection = sections[sectionIndex];
|
|
382
|
+
currentSection.Name = sectionData.sectionName;
|
|
383
|
+
currentSection.Split = sectionData.split;
|
|
384
|
+
currentSection.Height = sectionData.height;
|
|
385
|
+
currentSection.CollapseOnTablet = sectionData.collapseOnTablet;
|
|
386
|
+
currentSection.FillHeight = sectionData.fillHeight;
|
|
387
|
+
currentSection.Padding = sectionData.padding;
|
|
388
|
+
// Get the new columns number from currentSection.Split, if its undefined put a default 1.
|
|
389
|
+
const newColumnsLength = currentSection.Split?.split(' ').length || 1;
|
|
390
|
+
if (newColumnsLength > currentSection.Columns.length) {
|
|
391
|
+
while (newColumnsLength > currentSection.Columns.length) {
|
|
392
|
+
currentSection.Columns.push({});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
else if (newColumnsLength < currentSection.Columns.length) {
|
|
396
|
+
while (newColumnsLength < currentSection.Columns.length) {
|
|
397
|
+
const colunm = currentSection.Columns.pop();
|
|
398
|
+
// If there is block in this column delete it.
|
|
399
|
+
if (colunm && colunm.BlockContainer) {
|
|
400
|
+
blocksIdsToRemove.push(colunm.BlockContainer.BlockKey);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
// Update editor title
|
|
405
|
+
const currentEditor = this._editorSubject.getValue();
|
|
406
|
+
if (currentEditor && currentEditor.type === 'section' && currentEditor.id === currentSection.Key) {
|
|
407
|
+
const title = this.getSectionEditorTitle(currentSection, sectionIndex);
|
|
408
|
+
currentEditor.title = title;
|
|
409
|
+
this.notifyEditorChange(currentEditor);
|
|
410
|
+
}
|
|
411
|
+
// Update sections change.
|
|
412
|
+
this.notifyLayoutViewChange(layoutView);
|
|
413
|
+
// If there are blocks to remove, notify the blocks removed.
|
|
414
|
+
if (blocksIdsToRemove.length > 0) {
|
|
415
|
+
this.notifyBlocksRemoved(blocksIdsToRemove);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
addSection(section = null) {
|
|
420
|
+
// Create new section
|
|
421
|
+
if (!section) {
|
|
422
|
+
section = {
|
|
423
|
+
Key: PepGuid.newGuid(),
|
|
424
|
+
Columns: [{}],
|
|
425
|
+
Hide: []
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
// Add the new section to layout view.
|
|
429
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
430
|
+
const sections = layoutView?.Layout.Sections || [];
|
|
431
|
+
sections.push(section);
|
|
432
|
+
this.notifyLayoutViewChange(layoutView);
|
|
433
|
+
}
|
|
434
|
+
removeSection(sectionId) {
|
|
435
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
436
|
+
const sections = layoutView?.Layout.Sections || [];
|
|
437
|
+
const index = sections.findIndex(section => section.Key === sectionId);
|
|
438
|
+
if (index > -1) {
|
|
439
|
+
// Get the blocks id's to remove.
|
|
440
|
+
const blocksIdsToRemove = sections[index].Columns.map(column => column?.BlockContainer?.BlockKey);
|
|
441
|
+
// Remove section.
|
|
442
|
+
sections.splice(index, 1);
|
|
443
|
+
this.notifyLayoutViewChange(layoutView);
|
|
444
|
+
// If there are blocks to remove, notify the blocks removed.
|
|
445
|
+
if (blocksIdsToRemove.length > 0) {
|
|
446
|
+
this.notifyBlocksRemoved(blocksIdsToRemove);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
hideSection(sectionId, hideIn) {
|
|
451
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
452
|
+
const sections = layoutView?.Layout.Sections || [];
|
|
453
|
+
const index = sections.findIndex(section => section.Key === sectionId);
|
|
454
|
+
if (index > -1) {
|
|
455
|
+
sections[index].Hide = hideIn;
|
|
456
|
+
this.notifyLayoutViewChange(layoutView);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
onSectionDropped(event) {
|
|
460
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
461
|
+
const sections = layoutView?.Layout.Sections || [];
|
|
462
|
+
moveItemInArray(sections, event.previousIndex, event.currentIndex);
|
|
463
|
+
this.notifyLayoutViewChange(layoutView);
|
|
464
|
+
}
|
|
465
|
+
onSectionDragStart(event) {
|
|
466
|
+
this.changeCursorOnDragStart();
|
|
467
|
+
this._draggingSectionKey.next(event.source.data);
|
|
468
|
+
}
|
|
469
|
+
onSectionDragEnd(event) {
|
|
470
|
+
this.changeCursorOnDragEnd();
|
|
471
|
+
this._draggingSectionKey.next('');
|
|
472
|
+
}
|
|
473
|
+
removeBlockFromSection(blockId) {
|
|
474
|
+
let blockRemoved = false;
|
|
475
|
+
// Remove the block from section column.
|
|
476
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
477
|
+
const sections = layoutView?.Layout.Sections || [];
|
|
478
|
+
for (let sectionIndex = 0; sectionIndex < sections.length; sectionIndex++) {
|
|
479
|
+
const section = sections[sectionIndex];
|
|
480
|
+
// Remove the block container.
|
|
481
|
+
const columnIndex = section.Columns.findIndex(column => column.BlockContainer?.BlockKey === blockId);
|
|
482
|
+
if (columnIndex > -1) {
|
|
483
|
+
delete section.Columns[columnIndex].BlockContainer;
|
|
484
|
+
this.notifyLayoutViewChange(layoutView);
|
|
485
|
+
blockRemoved = true;
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
// If the block was removed, notify the block removed.
|
|
490
|
+
if (blockRemoved) {
|
|
491
|
+
this.notifyBlocksRemoved([blockId]);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
hideBlock(sectionId, blockId, hideIn) {
|
|
495
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
496
|
+
const sections = layoutView?.Layout.Sections || [];
|
|
497
|
+
const index = sections.findIndex(section => section.Key === sectionId);
|
|
498
|
+
if (index > -1) {
|
|
499
|
+
const columnIndex = sections[index].Columns.findIndex(column => column.BlockContainer?.BlockKey === blockId);
|
|
500
|
+
if (columnIndex > -1) {
|
|
501
|
+
const blockContainer = sections[index].Columns[columnIndex].BlockContainer;
|
|
502
|
+
if (blockContainer) {
|
|
503
|
+
blockContainer.Hide = hideIn;
|
|
504
|
+
this.notifyLayoutViewChange(layoutView);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
onBlockDropped(event, sectionId) {
|
|
510
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
511
|
+
if (event.previousContainer.id === LayoutBuilderInternalService.AVAILABLE_BLOCKS_CONTAINER_ID) {
|
|
512
|
+
// Validate if blocks number allow.
|
|
513
|
+
if (this._blocksLimitNumber > 0 && this.getBlocksNumber() >= this._blocksLimitNumber) {
|
|
514
|
+
const data = new PepDialogData({
|
|
515
|
+
title: this.translate.instant('MESSAGES.DIALOG_NOTICE_TITLE'),
|
|
516
|
+
content: this.translate.instant('LAYOUT_BUILDER.BLOCKS_COUNT_LIMIT_MESSAGE'),
|
|
517
|
+
});
|
|
518
|
+
this.dialogService.openDefaultDialog(data);
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
// Get the block relation (previousContainer.data is IPepDraggableItem and inside we have AvailableBlock object).
|
|
522
|
+
const draggableItem = event.previousContainer.data[event.previousIndex];
|
|
523
|
+
if (draggableItem) {
|
|
524
|
+
// lock the screen untill the editor will be loaded.
|
|
525
|
+
// this._lockScreenSubject.next(true);
|
|
526
|
+
// Get the column.
|
|
527
|
+
const currentColumn = this.getSectionColumnByIdForEditor(event.container.id);
|
|
528
|
+
// Set the block key in the section block only if there is a blank column.
|
|
529
|
+
if (currentColumn && !currentColumn.BlockContainer) {
|
|
530
|
+
// Generate the block uuid.
|
|
531
|
+
const blockKey = PepGuid.newGuid();
|
|
532
|
+
currentColumn.BlockContainer = {
|
|
533
|
+
BlockKey: blockKey,
|
|
534
|
+
};
|
|
535
|
+
// Here we update the layout view cause the layout is updated.
|
|
536
|
+
this.notifyLayoutViewChange(layoutView);
|
|
537
|
+
// Raise block added event.
|
|
538
|
+
const blockAddedEventData = {
|
|
539
|
+
BlockKey: blockKey,
|
|
540
|
+
DraggableItem: draggableItem,
|
|
541
|
+
};
|
|
542
|
+
this.notifyBlockAdded(blockAddedEventData);
|
|
543
|
+
if (this._navigateToEditorAfterBlockAdded) {
|
|
544
|
+
// Navigate to the block editor.
|
|
545
|
+
this.navigateToEditor('block', blockKey);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
console.log("draggableItem is not a IPepDraggableItem type");
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
// If the block moved between columns in the same section or between different sections but not in the same column.
|
|
556
|
+
if (event.container.id !== event.previousContainer.id) {
|
|
557
|
+
// Get the column.
|
|
558
|
+
const currentColumn = this.getSectionColumnByIdForEditor(event.container.id);
|
|
559
|
+
// Get the previous column.
|
|
560
|
+
const previuosColumn = this.getSectionColumnByIdForEditor(event.previousContainer.id);
|
|
561
|
+
if (currentColumn && previuosColumn) {
|
|
562
|
+
currentColumn.BlockContainer = previuosColumn.BlockContainer;
|
|
563
|
+
delete previuosColumn.BlockContainer;
|
|
564
|
+
this.notifyLayoutViewChange(layoutView);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
onBlockDragStart(event) {
|
|
570
|
+
this.changeCursorOnDragStart();
|
|
571
|
+
// Take the block key if exist, else take the available block key (relation key).
|
|
572
|
+
const blockKey = event.source.data?.BlockKey || event.source.data?.Key;
|
|
573
|
+
this._draggingBlockKey.next(blockKey);
|
|
574
|
+
}
|
|
575
|
+
onBlockDragEnd(event) {
|
|
576
|
+
this.changeCursorOnDragEnd();
|
|
577
|
+
this._draggingBlockKey.next('');
|
|
578
|
+
}
|
|
579
|
+
doesColumnContainBlock(sectionId, columnIndex) {
|
|
580
|
+
let res = false;
|
|
581
|
+
const layoutView = this._layoutViewSubject.getValue();
|
|
582
|
+
const section = layoutView?.Layout.Sections.find(section => section.Key === sectionId);
|
|
583
|
+
if (section && columnIndex >= 0 && section.Columns.length > columnIndex) {
|
|
584
|
+
res = !!section.Columns[columnIndex].BlockContainer;
|
|
585
|
+
}
|
|
586
|
+
return res;
|
|
587
|
+
}
|
|
588
|
+
setScreenWidth(screenType) {
|
|
589
|
+
const value = this.getCssScreenWidh(screenType);
|
|
590
|
+
const width = coerceNumberProperty(value, 0);
|
|
591
|
+
if (width === 0) {
|
|
592
|
+
this._screenWidthSubject.next('100%');
|
|
593
|
+
this.notifyScreenSizeChange(PepScreenSizeType.XL);
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
this._screenWidthSubject.next(`${width}px`);
|
|
597
|
+
// Change the size according the width.
|
|
598
|
+
if (width >= 1920) {
|
|
599
|
+
this.notifyScreenSizeChange(PepScreenSizeType.XL);
|
|
600
|
+
}
|
|
601
|
+
else if (width >= 1280 && width < 1920) {
|
|
602
|
+
this.notifyScreenSizeChange(PepScreenSizeType.LG);
|
|
603
|
+
}
|
|
604
|
+
else if (width >= 960 && width < 1280) {
|
|
605
|
+
this.notifyScreenSizeChange(PepScreenSizeType.MD);
|
|
606
|
+
}
|
|
607
|
+
else if (width >= 600 && width < 960) {
|
|
608
|
+
this.notifyScreenSizeChange(PepScreenSizeType.SM);
|
|
609
|
+
}
|
|
610
|
+
else if (width < 600) {
|
|
611
|
+
this.notifyScreenSizeChange(PepScreenSizeType.XS);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
// showSkeleton(show: boolean): void {
|
|
616
|
+
// this._showSkeletonSubject.next(show);
|
|
617
|
+
// }
|
|
618
|
+
// lockScreen(value: boolean): void {
|
|
619
|
+
// this.notifyLockScreen(value);
|
|
620
|
+
// }
|
|
621
|
+
loadLayoutBuilder(layoutView) {
|
|
622
|
+
if (this.editorMode) {
|
|
623
|
+
if (this._editorsBreadCrumb.length === 0) {
|
|
624
|
+
// Load the layout editor.
|
|
625
|
+
this.loadDefaultEditor(layoutView);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
// Load only the layout view.
|
|
629
|
+
this.notifyLayoutViewChange(layoutView);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
LayoutBuilderInternalService.AVAILABLE_BLOCKS_CONTAINER_ID = 'availableBlocks';
|
|
633
|
+
LayoutBuilderInternalService.MAIN_EDITOR_ID = 'main';
|
|
634
|
+
LayoutBuilderInternalService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: LayoutBuilderInternalService, deps: [{ token: i1.TranslateService }, { token: i2.PepDialogService }, { token: i3.PepLayoutService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
635
|
+
LayoutBuilderInternalService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: LayoutBuilderInternalService });
|
|
636
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: LayoutBuilderInternalService, decorators: [{
|
|
637
|
+
type: Injectable
|
|
638
|
+
}], ctorParameters: function () { return [{ type: i1.TranslateService }, { type: i2.PepDialogService }, { type: i3.PepLayoutService }]; } });
|
|
639
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5b3V0LWJ1aWxkZXItaW50ZXJuYWwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1jb21wb3NpdGUtbGliL2xheW91dC1idWlsZGVyMi9sYXlvdXQtYnVpbGRlci1pbnRlcm5hbC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDN0QsT0FBTyxFQUF3RCxlQUFlLEVBQXFCLE1BQU0sd0JBQXdCLENBQUM7QUFFbEksT0FBTyxFQUFtQixPQUFPLEVBQW9DLGlCQUFpQixFQUEwQyxNQUFNLHlCQUF5QixDQUFDO0FBR2hLLE9BQU8sRUFBYyxlQUFlLEVBQVcsTUFBTSxNQUFNLENBQUM7QUFDNUQsT0FBTyxFQUFnQixvQkFBb0IsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU1RSxPQUFPLEVBQUUsYUFBYSxFQUFvQixNQUFNLGdDQUFnQyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9EQUFvRCxDQUFDOzs7OztBQTBCeEYsTUFBTSxPQUFPLDRCQUE0QjtJQTBHckMsbUNBQW1DO0lBQ25DLCtGQUErRjtJQUMvRixtREFBbUQ7SUFDbkQsb0ZBQW9GO0lBQ3BGLElBQUk7SUFFSixZQUNjLFNBQTJCLEVBQzNCLGFBQStCLEVBQ2pDLGFBQStCO1FBRjdCLGNBQVMsR0FBVCxTQUFTLENBQWtCO1FBQzNCLGtCQUFhLEdBQWIsYUFBYSxDQUFrQjtRQUNqQyxrQkFBYSxHQUFiLGFBQWEsQ0FBa0I7UUEvR25DLHdCQUFtQixHQUFHLElBQUksQ0FBQztRQUUzQix5QkFBb0IsR0FBRyxFQUFFLENBQUM7UUFFbEMsNkNBQTZDO1FBQ3JDLHVCQUFrQixHQUFHLENBQUMsQ0FBQztRQUN2QixxQ0FBZ0Ms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SEFGL0IsNEJBQTRCOzZIQUE1Qiw0QkFBNEI7MkZBQTVCLDRCQUE0QjtrQkFMeEMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgY29lcmNlTnVtYmVyUHJvcGVydHkgfSBmcm9tIFwiQGFuZ3VsYXIvY2RrL2NvZXJjaW9uXCI7XG5pbXBvcnQgeyBDZGtEcmFnRHJvcCwgQ2RrRHJhZ0VuZCwgQ2RrRHJhZ1N0YXJ0LCBjb3B5QXJyYXlJdGVtLCBtb3ZlSXRlbUluQXJyYXksIHRyYW5zZmVyQXJyYXlJdGVtIH0gZnJvbSBcIkBhbmd1bGFyL2Nkay9kcmFnLWRyb3BcIjtcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tIFwiQG5neC10cmFuc2xhdGUvY29yZVwiO1xuaW1wb3J0IHsgUGVwQWRkb25TZXJ2aWNlLCBQZXBHdWlkLCBQZXBIdHRwU2VydmljZSwgUGVwTGF5b3V0U2VydmljZSwgUGVwU2NyZWVuU2l6ZVR5cGUsIFBlcFNlc3Npb25TZXJ2aWNlLCBQZXBVdGlsaXRpZXNTZXJ2aWNlIH0gZnJvbSBcIkBwZXBwZXJpLWFkZG9ucy9uZ3gtbGliXCI7XG5pbXBvcnQgeyBJUGVwRHJhZ2dhYmxlSXRlbSB9IGZyb20gXCJAcGVwcGVyaS1hZGRvbnMvbmd4LWxpYi9kcmFnZ2FibGUtaXRlbXNcIjtcbmltcG9ydCB7IERhdGFWaWV3U2NyZWVuU2l6ZSwgU3BsaXRUeXBlIH0gZnJvbSBcIkBwZXBwZXJpLWFkZG9ucy9wYXBpLXNka1wiO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgQmVoYXZpb3JTdWJqZWN0LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBQZXBMYXlvdXRFZGl0b3JUeXBlLCBJUGVwTGF5b3V0QmxvY2tBZGRlZEV2ZW50LCBJUGVwTGF5b3V0U2VjdGlvbiwgSVBlcExheW91dFNlY3Rpb25Db2x1bW4sIElQZXBMYXlvdXRWaWV3LCBJUGVwTGF5b3V0QmxvY2tDb25maWcsIFBlcExheW91dFNpemVUeXBlLCBJRWRpdG9yIH0gZnJvbSBcIi4vbGF5b3V0LWJ1aWxkZXIubW9kZWxcIjtcbmltcG9ydCB7IFBlcERpYWxvZ0RhdGEsIFBlcERpYWxvZ1NlcnZpY2UgfSBmcm9tIFwiQHBlcHBlcmktYWRkb25zL25neC1saWIvZGlhbG9nXCI7XG5pbXBvcnQgeyBQZXBQYWRkaW5nU2V0dGluZ3MgfSBmcm9tIFwiQHBlcHBlcmktYWRkb25zL25neC1jb21wb3NpdGUtbGliL3BhZGRpbmctc2V0dGluZ3NcIjtcblxuZXhwb3J0IGludGVyZmFjZSBJTGF5b3V0RWRpdG9yIHtcbiAgICBtYXhXaWR0aDogbnVtYmVyLFxuICAgIGhvcml6b250YWxTcGFjaW5nPzogUGVwTGF5b3V0U2l6ZVR5cGUsXG4gICAgdmVydGljYWxTcGFjaW5nPzogUGVwTGF5b3V0U2l6ZVR5cGUsXG4gICAgc2VjdGlvbnNHYXA/OiBQZXBMYXlvdXRTaXplVHlwZSxcbiAgICBjb2x1bW5zR2FwPzogUGVwTGF5b3V0U2l6ZVR5cGUsXG4gICAgcm91bmRlZENvcm5lcnM/OiBQZXBMYXlvdXRTaXplVHlwZSxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJTGF5b3V0U2VjdGlvbkVkaXRvciB7XG4gICAgaWQ6IHN0cmluZyxcbiAgICBzZWN0aW9uTmFtZTogc3RyaW5nLFxuICAgIHNwbGl0OiBTcGxpdFR5cGUgfCB1bmRlZmluZWQsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICAgY29sbGFwc2VPblRhYmxldDogYm9vbGVhbixcbiAgICBmaWxsSGVpZ2h0OiBib29sZWFuXG4gICAgcGFkZGluZzogUGVwUGFkZGluZ1NldHRpbmdzO1xufVxuXG5ASW5qZWN0YWJsZShcbi8vICAgICB7XG4vLyAgICAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxuLy8gfVxuKVxuZXhwb3J0IGNsYXNzIExheW91dEJ1aWxkZXJJbnRlcm5hbFNlcnZpY2Uge1xuICAgIHN0YXRpYyByZWFkb25seSBBVkFJTEFCTEVfQkxPQ0tTX0NPTlRBSU5FUl9JRCA9ICdhdmFpbGFibGVCbG9ja3MnO1xuICAgIHN0YXRpYyByZWFkb25seSBNQUlOX0VESVRPUl9JRCA9ICdtYWluJztcblxuICAgIHByaXZhdGUgX21hbmFnZUdsb2JhbEN1cnNvciA9IHRydWU7XG5cbiAgICBwcml2YXRlIF9kZWZhdWx0U2VjdGlvblRpdGxlID0gJyc7XG4gICAgXG4gICAgLy8gVGhpcyBjb25maWd1cmF0aW9uIGlzIGZvciBibG9ja3MgYmVoYXZpb3IuXG4gICAgcHJpdmF0ZSBfYmxvY2tzTGltaXROdW1iZXIgPSAwO1xuICAgIHByaXZhdGUgX25hdmlnYXRlVG9FZGl0b3JBZnRlckJsb2NrQWRkZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIF9nZXRCbG9ja1RpdGxlOiAoYmxvY2tLZXk6IHN0cmluZykgPT4gc3RyaW5nID0gKGJsb2NrS2V5KSA9PiB7IHJldHVybiBibG9ja0tleSB9O1xuICAgIHNldEJsb2Nrc0NvbmZpZyh2YWx1ZTogSVBlcExheW91dEJsb2NrQ29uZmlnKSB7XG4gICAgICAgIHRoaXMuX2Jsb2Nrc0xpbWl0TnVtYmVyID0gdmFsdWUuYmxvY2tzTGltaXROdW1iZXIgfHwgMDtcbiAgICAgICAgdGhpcy5fbmF2aWdhdGVUb0VkaXRvckFmdGVyQmxvY2tBZGRlZCA9IHZhbHVlLm5hdmlnYXRlVG9FZGl0b3JBZnRlckJsb2NrQWRkZWQgPz8gZmFsc2U7XG4gICAgICAgIHRoaXMuX2dldEJsb2NrVGl0bGUgPSB2YWx1ZS5nZXRCbG9ja1RpdGxlID8gdmFsdWUuZ2V0QmxvY2tUaXRsZSA6IChibG9ja0tleSkgPT4geyByZXR1cm4gYmxvY2tLZXkgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9lZGl0b3JzQnJlYWRDcnVtYiA9IEFycmF5PElFZGl0b3I+KCk7XG5cbiAgICBwcml2YXRlIF9lZGl0b3JNb2RlID0gZmFsc2U7XG4gICAgZ2V0IGVkaXRvck1vZGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lZGl0b3JNb2RlO1xuICAgIH1cbiAgICBzZXRFZGl0b3JNb2RlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuX2VkaXRvck1vZGUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5zZXRFZGl0YWJsZVN0YXRlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZWRpdGFibGVTdGF0ZSA9IGZhbHNlO1xuICAgIGdldCBlZGl0YWJsZVN0YXRlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZWRpdGFibGVTdGF0ZTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIHN1YmplY3QgaXMgZm9yIHRoZSBzY3JlZW4gc2l6ZSBjaGFuZ2UgZXZlbnRzLlxuICAgIHByaXZhdGUgX3NjcmVlblNpemVTdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8UGVwU2NyZWVuU2l6ZVR5cGUgfCB1bmRlZmluZWQ+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxQZXBTY3JlZW5TaXplVHlwZSB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgICBnZXQgc2NyZWVuU2l6ZUNoYW5nZSQoKTogT2JzZXJ2YWJsZTxQZXBTY3JlZW5TaXplVHlwZSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2NyZWVuU2l6ZVN1YmplY3QuYXNPYnNlcnZhYmxlKCkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKTtcbiAgICB9XG4gICAgXG4gICAgLy8gVGhpcyBzdWJqZWN0IGlzIGZvciBkZW1vc3RyYXRlIHRoZSBjb250YWluZXIgc2l6ZSAoVXNhZ2Ugb25seSBpbiBlZGl0IG1vZGUpLlxuICAgIHByaXZhdGUgX3NjcmVlbldpZHRoU3ViamVjdDogQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oJzEwMCUnKTtcbiAgICBnZXQgc2NyZWVuV2lkdGhDaGFuZ2UkKCk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zY3JlZW5XaWR0aFN1YmplY3QuYXNPYnNlcnZhYmxlKCkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIHN1YmplY3QgaXMgZm9yIGxvYWQgdGhlIGN1cnJlbnQgZWRpdG9yIChVc2FnZSBvbmx5IGluIGVkaXQgbW9kZSkuXG4gICAgcHJpdmF0ZSBfZWRpdG9yU3ViamVjdDogQmVoYXZpb3JTdWJqZWN0PElFZGl0b3IgfCBudWxsPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SUVkaXRvciB8IG51bGw+KG51bGwpO1xuICAgIGdldCBlZGl0b3JDaGFuZ2UkKCk6IE9ic2VydmFibGU8SUVkaXRvciB8IG51bGw+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VkaXRvclN1YmplY3QuYXNPYnNlcnZhYmxlKCkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGlzIHRoZSBzZWN0aW9ucyBjb2x1bW5zIGRyb3AgbGlzdCBzdWJqZWN0LlxuICAgIHByaXZhdGUgX3NlY3Rpb25zQ29sdW1uc0Ryb3BMaXN0U3ViamVjdDogQmVoYXZpb3JTdWJqZWN0PGFueVtdPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55W10+KFtdKTtcbiAgICBnZXQgc2VjdGlvbnNDb2x1bW5zRHJvcExpc3RDaGFuZ2UkKCk6IE9ic2VydmFibGU8YW55W10+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlY3Rpb25zQ29sdW1uc0Ryb3BMaXN0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGlzIHRoZSBzZWN0aW9ucyBzdWJqZWN0IChhIHBhcmUgZnJvbSB0aGUgbGF5b3V0IHZpZXcgb2JqZWN0KVxuICAgIHByaXZhdGUgX3NlY3Rpb25zVmlld1N1YmplY3Q6IEJlaGF2aW9yU3ViamVjdDxJUGVwTGF5b3V0U2VjdGlvbltdPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SVBlcExheW91dFNlY3Rpb25bXT4oW10pO1xuICAgIGdldCBzZWN0aW9uc0NoYW5nZSQoKTogT2JzZXJ2YWJsZTxJUGVwTGF5b3V0U2VjdGlvbltdPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZWN0aW9uc1ZpZXdTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICAgICAgICAvLyAocHJldlNlY3Rpb25zLCBuZXh0U2VjdGlvbnMpID0+IEpTT04uc3RyaW5naWZ5KHByZXZTZWN0aW9ucykgPT09IEpTT04uc3RyaW5naWZ5KG5leHRTZWN0aW9ucykpKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIHN1YmplY3QgaXMgZm9yIGxheW91dCB2aWV3IGNoYW5nZS5cbiAgICBwcml2YXRlIF9sYXlvdXRWaWV3U3ViamVjdDogQmVoYXZpb3JTdWJqZWN0PElQZXBMYXlvdXRWaWV3IHwgbnVsbD4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PElQZXBMYXlvdXRWaWV3IHwgbnVsbD4obnVsbCk7XG4gICAgZ2V0IGxheW91dFZpZXdDaGFuZ2UkKCk6IE9ic2VydmFibGU8SVBlcExheW91dFZpZXcgfCBudWxsPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sYXlvdXRWaWV3U3ViamVjdC5hc09ic2VydmFibGUoKS5waXBlKGZpbHRlcihsYXlvdXQgPT4gISFsYXlvdXQpKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIHN1YmplY3QgaXMgZm9yIGVkaXQgbW9kZSB3aGVuIGJsb2NrIGlzIGRyYWdnaW5nIG5vdyBvciBub3QuXG4gICAgcHJpdmF0ZSBfZHJhZ2dpbmdCbG9ja0tleTogQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KCcnKTtcbiAgICBnZXQgZHJhZ2dpbmdCbG9ja0tleSgpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZHJhZ2dpbmdCbG9ja0tleS5hc09ic2VydmFibGUoKS5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xuICAgIH1cblxuICAgIC8vIFRoaXMgc3ViamVjdCBpcyBmb3IgZWRpdCBtb2RlIHdoZW4gc2VjdGlvbiBpcyBkcmFnZ2luZyBub3cgb3Igbm90LlxuICAgIHByaXZhdGUgX2RyYWdnaW5nU2VjdGlvbktleTogQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KCcnKTtcbiAgICBnZXQgZHJhZ2dpbmdTZWN0aW9uS2V5KCk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kcmFnZ2luZ1NlY3Rpb25LZXkuYXNPYnNlcnZhYmxlKCkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKTtcbiAgICB9XG5cbiAgICAvLyAvLyBUaGlzIHN1YmplY3QgaXMgZm9yIGxvY2sgb3IgdW5sb2NrIHRoZSBzY3JlZW4gKFVzYWdlIG9ubHkgaW4gZWRpdCBtb2RlKS5cbiAgICAvLyBwcml2YXRlIF9sb2NrU2NyZWVuU3ViamVjdDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gICAgLy8gZ2V0IGxvY2tTY3JlZW5DaGFuZ2UkKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIC8vICAgICByZXR1cm4gdGhpcy5fbG9ja1NjcmVlblN1YmplY3QuYXNPYnNlcnZhYmxlKCkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKTtcbiAgICAvLyB9XG5cbiAgICAvLyBUaGlzIGlzIGZvciBjb250cm9sIHRoZSBwcmV2aWV3IG1vZGUgKGZvciBsb2FkIHRoZSBibG9ja3Mgd2l0aCB0aGUgQ1BJIGV2ZW50cykgXG4gICAgcHJpdmF0ZSBfcHJldmlld01vZGVTdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgICBnZXQgcHJldmlld01vZGVDaGFuZ2UkKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJldmlld01vZGVTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBpcyBmb3IgZWRpdG9yIG1vZGUgZm9yIGJsb2NrIGFkZGVkLlxuICAgIHByaXZhdGUgX2Jsb2NrQWRkZWRFdmVudFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PElQZXBMYXlvdXRCbG9ja0FkZGVkRXZlbnQgfCBudWxsPihudWxsKTtcbiAgICBnZXQgYmxvY2tBZGRlZEV2ZW50U3ViamVjdCQoKTogT2JzZXJ2YWJsZTxJUGVwTGF5b3V0QmxvY2tBZGRlZEV2ZW50IHwgbnVsbD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmxvY2tBZGRlZEV2ZW50U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgICB9XG4gICAgLy8gVGhpcyBpcyBmb3IgZWRpdG9yIG1vZGUgZm9yIGJsb2NrcyByZW1vdmVkLlxuICAgIHByaXZhdGUgX2Jsb2Nrc1JlbW92ZWRFdmVudFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZ1tdPihbXSk7XG4gICAgZ2V0IGJsb2Nrc1JlbW92ZWRFdmVudFN1YmplY3QkKCk6IE9ic2VydmFibGU8c3RyaW5nW10+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Jsb2Nrc1JlbW92ZWRFdmVudFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgLy8gLy8gVGhpcyBzdWJqZWN0IGlzIGZvciBza2VsZXRvbi5cbiAgICAvLyBwcml2YXRlIF9zaG93U2tlbGV0b25TdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KHRydWUpO1xuICAgIC8vIGdldCBzaG93U2tlbGV0b25DaGFuZ2UkKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIC8vICAgICByZXR1cm4gdGhpcy5fc2hvd1NrZWxldG9uU3ViamVjdC5hc09ic2VydmFibGUoKS5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xuICAgIC8vIH1cbiAgICBcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJvdGVjdGVkIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICAgICAgcHJvdGVjdGVkIGRpYWxvZ1NlcnZpY2U6IFBlcERpYWxvZ1NlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbGF5b3V0U2VydmljZTogUGVwTGF5b3V0U2VydmljZSxcbiAgICApIHtcbiAgICAgICAgLy9cbiAgICAgICAgdGhpcy50cmFuc2xhdGUuZ2V0KCdMQVlPVVRfQlVJTERFUi5TRUNUSU9OJykuc3Vic2NyaWJlKChyZXM6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgLy8gU2V0IHRoZSBkZWZhdWx0IHNlY3Rpb24gbmFtZS5cbiAgICAgICAgICAgIHRoaXMuX2RlZmF1bHRTZWN0aW9uVGl0bGUgPSByZXM7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMubGF5b3V0U2VydmljZS5vblJlc2l6ZSQuc3Vic2NyaWJlKChzaXplOiBQZXBTY3JlZW5TaXplVHlwZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5ub3RpZnlTY3JlZW5TaXplQ2hhbmdlKHNpemUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgXG4gICAgcHJpdmF0ZSBzZXRFZGl0YWJsZVN0YXRlKCkge1xuICAgICAgICB0aGlzLl9lZGl0YWJsZVN0YXRlID0gdGhpcy5lZGl0b3JNb2RlICYmICF0aGlzLl9wcmV2aWV3TW9kZVN1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlld1RvVXBkYXRlOiBJUGVwTGF5b3V0VmlldyB8IG51bGwpIHtcbiAgICAgICAgaWYgKGxheW91dFZpZXdUb1VwZGF0ZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuZWRpdG9yTW9kZSkge1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlTGF5b3V0RWRpdG9yUHJvcGVydGllcyhsYXlvdXRWaWV3VG9VcGRhdGUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBVcGRhdGUgdGhlIGxheW91dCBmb3IgdGhlIHZpZXcuXG4gICAgICAgICAgICB0aGlzLl9sYXlvdXRWaWV3U3ViamVjdC5uZXh0KGxheW91dFZpZXdUb1VwZGF0ZSk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgc2VjdGlvbnMgZm9yIHRoZSB2aWV3LlxuICAgICAgICAgICAgdGhpcy5fc2VjdGlvbnNWaWV3U3ViamVjdC5uZXh0KGxheW91dFZpZXdUb1VwZGF0ZT8uTGF5b3V0LlNlY3Rpb25zIHx8IFtdKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbm90aWZ5QmxvY2tBZGRlZChibG9ja0FkZGVkRXZlbnREYXRhOiBJUGVwTGF5b3V0QmxvY2tBZGRlZEV2ZW50KSB7XG4gICAgICAgIC8vIE5vdGlmeSB0aGF0IHRoZSBibG9jayBpcyBhZGRlZCAodG8gcmFpc2UgdGhlIGV2ZW50IGZvciB0aGUgY2xpZW50KS5cbiAgICAgICAgdGhpcy5fYmxvY2tBZGRlZEV2ZW50U3ViamVjdC5uZXh0KGJsb2NrQWRkZWRFdmVudERhdGEpO1xuICAgIH1cblxuICAgIHByaXZhdGUgbm90aWZ5QmxvY2tzUmVtb3ZlZChrZXlzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoa2V5cykge1xuICAgICAgICAgICAgLy8gTm90aWZ5IHRoYXQgdGhlIGJsb2NrcyBhcmUgcmVtb3ZlZCAodG8gcmFpc2UgdGhlIGV2ZW50IGZvciB0aGUgY2xpZW50KS5cbiAgICAgICAgICAgIHRoaXMuX2Jsb2Nrc1JlbW92ZWRFdmVudFN1YmplY3QubmV4dChrZXlzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbm90aWZ5RWRpdG9yQ2hhbmdlKGVkaXRvcjogSUVkaXRvciB8IG51bGwpIHtcbiAgICAgICAgdGhpcy5fZWRpdG9yU3ViamVjdC5uZXh0KGVkaXRvcik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBub3RpZnlQcmV2aWV3TW9kZUNoYW5nZSh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl9wcmV2aWV3TW9kZVN1YmplY3QubmV4dCh2YWx1ZSk7XG4gICAgICAgIHRoaXMuc2V0RWRpdGFibGVTdGF0ZSgpO1xuICAgIH1cblxuICAgIC8vIHByaXZhdGUgbm90aWZ5TG9ja1NjcmVlbih2YWx1ZTogYm9vbGVhbikge1xuICAgIC8vICAgICB0aGlzLl9sb2NrU2NyZWVuU3ViamVjdC5uZXh0KHZhbHVlKTtcbiAgICAvLyB9XG5cbiAgICBwcml2YXRlIG5vdGlmeVNlY3Rpb25zQ29sdW1uc0Ryb3BMaXN0Q2hhbmdlKHNlY3Rpb25zQ29sdW1uc0Ryb3BMaXN0OiBhbnlbXSkge1xuICAgICAgICB0aGlzLl9zZWN0aW9uc0NvbHVtbnNEcm9wTGlzdFN1YmplY3QubmV4dChzZWN0aW9uc0NvbHVtbnNEcm9wTGlzdCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBub3RpZnlTY3JlZW5TaXplQ2hhbmdlKHNpemU6IFBlcFNjcmVlblNpemVUeXBlKSB7XG4gICAgICAgIHRoaXMuX3NjcmVlblNpemVTdWJqZWN0Lm5leHQoc2l6ZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVMYXlvdXRFZGl0b3JQcm9wZXJ0aWVzKGxheW91dFZpZXc6IElQZXBMYXlvdXRWaWV3KSB7XG4gICAgICAgIGlmICh0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYlswXSkge1xuICAgICAgICAgICAgY29uc3QgbGF5b3V0RWRpdG9yOiBJTGF5b3V0RWRpdG9yID0ge1xuICAgICAgICAgICAgICAgIG1heFdpZHRoOiBsYXlvdXRWaWV3Py5MYXlvdXQuTWF4V2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICB2ZXJ0aWNhbFNwYWNpbmc6IGxheW91dFZpZXc/LkxheW91dC5WZXJ0aWNhbFNwYWNpbmcsXG4gICAgICAgICAgICAgICAgaG9yaXpvbnRhbFNwYWNpbmc6IGxheW91dFZpZXc/LkxheW91dC5Ib3Jpem9udGFsU3BhY2luZyxcbiAgICAgICAgICAgICAgICBzZWN0aW9uc0dhcDogbGF5b3V0Vmlldz8uTGF5b3V0LlNlY3Rpb25zR2FwLFxuICAgICAgICAgICAgICAgIGNvbHVtbnNHYXA6IGxheW91dFZpZXc/LkxheW91dC5Db2x1bW5zR2FwLFxuICAgICAgICAgICAgICAgIC8vIHJvdW5kZWRDb3JuZXJzOiBsYXlvdXRWaWV3Py5MYXlvdXQuUm91bmRlZENvcm5lcnNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHRoaXMuX2VkaXRvcnNCcmVhZENydW1iWzBdLmhvc3RPYmplY3QgPSBsYXlvdXRFZGl0b3I7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGxvYWREZWZhdWx0RWRpdG9yKGxheW91dFZpZXc6IElQZXBMYXlvdXRWaWV3KSB7XG4gICAgICAgIHRoaXMuX2VkaXRvcnNCcmVhZENydW1iID0gbmV3IEFycmF5PElFZGl0b3I+KCk7XG5cbiAgICAgICAgaWYgKGxheW91dFZpZXcpIHtcbiAgICAgICAgICAgIHRoaXMudHJhbnNsYXRlLmdldCgnTEFZT1VUX0JVSUxERVIuREVGQVVMVF9USVRMRScpLnN1YnNjcmliZSgodGl0bGU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX2VkaXRvcnNCcmVhZENydW1iLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBpZDogTGF5b3V0QnVpbGRlckludGVybmFsU2VydmljZS5NQUlOX0VESVRPUl9JRCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZSA6ICdsYXlvdXQtYnVpbGRlcicsXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICAgICAgICAgICAgLy8gaG9zdE9iamVjdDoge30gLy8gVXBkYXRlcyBpbiB1cGRhdGVMYXlvdXRFZGl0b3JQcm9wZXJ0aWVzIGZ1bmN0aW9uIGFib3ZlLlxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVMYXlvdXRFZGl0b3JQcm9wZXJ0aWVzKGxheW91dFZpZXcpO1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5RWRpdG9yQ2hhbmdlKHRoaXMuX2VkaXRvcnNCcmVhZENydW1iWzBdKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5ub3RpZnlFZGl0b3JDaGFuZ2UobnVsbCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNoYW5nZUN1cnJlbnRFZGl0b3IoKSB7XG4gICAgICAgIGlmICh0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLm5vdGlmeUVkaXRvckNoYW5nZSh0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYlt0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYi5sZW5ndGggLSAxXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEVkaXRvckJ5VHlwZShlZGl0b3JUeXBlOiBQZXBMYXlvdXRFZGl0b3JUeXBlLCBpZDogc3RyaW5nLCB0aXRsZSA9ICcnKTogSUVkaXRvciB8IG51bGwge1xuICAgICAgICAvLyBCdWlsZCBlZGl0b3Igb2JqZWN0LlxuICAgICAgICBsZXQgZWRpdG9yOiBJRWRpdG9yIHwgbnVsbCA9IG51bGw7XG5cbiAgICAgICAgaWYgKGVkaXRvclR5cGUgPT09ICdzZWN0aW9uJykge1xuICAgICAgICAgICAgZWRpdG9yID0gdGhpcy5nZXRTZWN0aW9uRWRpdG9yKGlkLCB0aXRsZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZWRpdG9yVHlwZSA9PT0gJ2Jsb2NrJykge1xuICAgICAgICAgICAgZWRpdG9yID0gdGhpcy5nZXRCbG9ja0VkaXRvcihpZCwgdGl0bGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVkaXRvcjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEJsb2NrRWRpdG9yKGJsb2NrS2V5OiBzdHJpbmcsIHRpdGxlOiBzdHJpbmcpOiBJRWRpdG9yIHtcbiAgICAgICAgLy8gR2V0IGJsb2NrIGVkaXRvciB0aXRsZS5cbiAgICAgICAgY29uc3QgYmxvY2tUaXRsZSA9IHRpdGxlIHx8IHRoaXMuZ2V0QmxvY2tUaXRsZShibG9ja0tleSk7IFxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpZDogYmxvY2tLZXksXG4gICAgICAgICAgICB0eXBlOiAnYmxvY2snLFxuICAgICAgICAgICAgdGl0bGU6IGJsb2NrVGl0bGVcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0U2VjdGlvbkVkaXRvclRpdGxlKHNlY3Rpb246IElQZXBMYXlvdXRTZWN0aW9uLCBzZWN0aW9uSW5kZXg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBzZWN0aW9uLk5hbWUgfHwgYCR7dGhpcy5fZGVmYXVsdFNlY3Rpb25UaXRsZX0gJHtzZWN0aW9uSW5kZXggKyAxfWA7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTZWN0aW9uRWRpdG9yKHNlY3Rpb25JZDogc3RyaW5nLCB0aXRsZTogc3RyaW5nKTogSUVkaXRvciB8IG51bGwge1xuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBsYXlvdXRWaWV3Py5MYXlvdXQuU2VjdGlvbnMgfHwgW107XG4gICAgICAgIGNvbnN0IHNlY3Rpb25JbmRleCA9IHNlY3Rpb25zLmZpbmRJbmRleChzZWN0aW9uID0+IHNlY3Rpb24uS2V5ID09PSBzZWN0aW9uSWQpO1xuXG4gICAgICAgIGlmIChzZWN0aW9uSW5kZXggPj0gMCkge1xuICAgICAgICAgICAgY29uc3Qgc2VjdGlvbiA9IHNlY3Rpb25zW3NlY3Rpb25JbmRleF07XG4gICAgICAgICAgICBjb25zdCBzZWN0aW9uRWRpdG9yOiBJTGF5b3V0U2VjdGlvbkVkaXRvciA9IHtcbiAgICAgICAgICAgICAgICBpZDogc2VjdGlvbi5LZXksXG4gICAgICAgICAgICAgICAgc2VjdGlvbk5hbWU6IHNlY3Rpb24uTmFtZSB8fCAnJyxcbiAgICAgICAgICAgICAgICBzcGxpdDogc2VjdGlvbi5TcGxpdCB8fCB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBzZWN0aW9uLkhlaWdodCB8fCAwLFxuICAgICAgICAgICAgICAgIGNvbGxhcHNlT25UYWJsZXQ6IHNlY3Rpb24uQ29sbGFwc2VPblRhYmxldCA/PyBmYWxzZSxcbiAgICAgICAgICAgICAgICBmaWxsSGVpZ2h0OiBzZWN0aW9uLkZpbGxIZWlnaHQgPz8gZmFsc2UsXG4gICAgICAgICAgICAgICAgcGFkZGluZzogc2VjdGlvbi5QYWRkaW5nIHx8IG5ldyBQZXBQYWRkaW5nU2V0dGluZ3ModHJ1ZSwgJzAnKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGlkOiBzZWN0aW9uSWQsXG4gICAgICAgICAgICAgICAgdHlwZTogJ3NlY3Rpb24nLFxuICAgICAgICAgICAgICAgIHRpdGxlOiB0aXRsZSB8fCB0aGlzLmdldFNlY3Rpb25FZGl0b3JUaXRsZShzZWN0aW9uLCBzZWN0aW9uSW5kZXgpLFxuICAgICAgICAgICAgICAgIGhvc3RPYmplY3Q6IHNlY3Rpb25FZGl0b3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTZWN0aW9uQ29sdW1uQnlJZEZvckVkaXRvcihzZWN0aW9uQ29sdW1uSWQ6IHN0cmluZyk6IElQZXBMYXlvdXRTZWN0aW9uQ29sdW1uIHwgbnVsbCB7XG4gICAgICAgIGxldCBjdXJyZW50Q29sdW1uID0gbnVsbDtcblxuICAgICAgICAvLyBHZXQgdGhlIHNlY3Rpb24gYW5kIGNvbHVtbiBhcnJheSBieSB0aGUgcGF0dGVybiBvZiB0aGUgc2VjdGlvbiBjb2x1bW4ga2V5LlxuICAgICAgICBjb25zdCBzZWN0aW9uQ29sdW1uUGF0dGVyblNlcGFyYXRvciA9IHRoaXMuZ2V0U2VjdGlvbkNvbHVtbktleSgpO1xuICAgICAgICBjb25zdCBzZWN0aW9uQ29sdW1uQXJyID0gc2VjdGlvbkNvbHVtbklkLnNwbGl0KHNlY3Rpb25Db2x1bW5QYXR0ZXJuU2VwYXJhdG9yKTtcblxuICAgICAgICBpZiAoc2VjdGlvbkNvbHVtbkFyci5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgIGNvbnN0IGxheW91dFZpZXcgPSB0aGlzLl9sYXlvdXRWaWV3U3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgICAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBsYXlvdXRWaWV3Py5MYXlvdXQuU2VjdGlvbnMgfHwgW107XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIEdldCB0aGUgc2VjdGlvbiBpZCB0byBnZXQgdGhlIHNlY3Rpb24gaW5kZXguXG4gICAgICAgICAgICBjb25zdCBzZWN0aW9uSWQgPSBzZWN0aW9uQ29sdW1uQXJyWzBdO1xuICAgICAgICAgICAgY29uc3Qgc2VjdGlvbkluZGV4ID0gc2VjdGlvbnMuZmluZEluZGV4KHNlY3Rpb24gPT4gc2VjdGlvbi5LZXkgPT09IHNlY3Rpb25JZCk7XG4gICAgICAgICAgICAvLyBHZXQgdGhlIGNvbHVtbiBpbmRleC5cbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbkluZGV4ID0gY29lcmNlTnVtYmVyUHJvcGVydHkoc2VjdGlvbkNvbHVtbkFyclsxXSwgLTEpO1xuICAgICAgICAgICAgaWYgKHNlY3Rpb25JbmRleCA+PSAwICYmIGNvbHVtbkluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50Q29sdW1uID0gc2VjdGlvbnNbc2VjdGlvbkluZGV4XS5Db2x1bW5zW2NvbHVtbkluZGV4XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjdXJyZW50Q29sdW1uO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q3NzU2NyZWVuV2lkaChzY3JlZW5UeXBlOiBEYXRhVmlld1NjcmVlblNpemUpOiBzdHJpbmcge1xuICAgICAgICBsZXQgd2lkdGhUb1NldCA9ICcxMDAlJztcblxuICAgICAgICBpZiAoc2NyZWVuVHlwZSA9PT0gJ1RhYmxldCcpIHtcbiAgICAgICAgICAgIHdpZHRoVG9TZXQgPSAnNzIwJztcbiAgICAgICAgfSBlbHNlIGlmIChzY3JlZW5UeXBlID09PSAnUGhhYmxldCcpIHtcbiAgICAgICAgICAgIHdpZHRoVG9TZXQgPSAnMzYwJztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB3aWR0aFRvU2V0O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0QmxvY2tzTnVtYmVyKCk6IG51bWJlciB7XG4gICAgICAgIGxldCBibG9ja3NOdW1iZXIgPSAwO1xuICAgICAgICBjb25zdCBzZWN0aW9ucyA9IHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmdldFZhbHVlKCk/LkxheW91dC5TZWN0aW9ucyB8fCBbXTtcblxuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgc2VjdGlvbnMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICBjb25zdCBzZWN0aW9uID0gc2VjdGlvbnNbaW5kZXhdO1xuICAgICAgICBcbiAgICAgICAgICAgIGZvciAobGV0IGNvbHVtbkluZGV4ID0gMDsgY29sdW1uSW5kZXggPCBzZWN0aW9uLkNvbHVtbnMubGVuZ3RoOyBjb2x1bW5JbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29sdW1uID0gc2VjdGlvbi5Db2x1bW5zW2NvbHVtbkluZGV4XTtcbiAgICAgICAgICAgICAgICBpZiAoY29sdW1uLkJsb2NrQ29udGFpbmVyICYmIGNvbHVtbi5CbG9ja0NvbnRhaW5lci5CbG9ja0tleT8ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBibG9ja3NOdW1iZXIrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYmxvY2tzTnVtYmVyO1xuICAgIH1cblxuICAgIHByaXZhdGUgY2hhbmdlQ3Vyc29yT25EcmFnU3RhcnQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9tYW5hZ2VHbG9iYWxDdXJzb3IpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnaW5oZXJpdEN1cnNvcnMnKTtcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUuY3Vyc29yID0gJ2dyYWJiaW5nJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY2hhbmdlQ3Vyc29yT25EcmFnRW5kKCkge1xuICAgICAgICBpZiAodGhpcy5fbWFuYWdlR2xvYmFsQ3Vyc29yKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2luaGVyaXRDdXJzb3JzJyk7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLmN1cnNvciA9ICd1bnNldCc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4gICAgLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHVibGljIGZ1bmN0aW9uc1xuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAgIGdldEN1cnJlbnRMYXlvdXRWaWV3KCk6IElQZXBMYXlvdXRWaWV3IHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sYXlvdXRWaWV3U3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgIH1cblxuICAgIGdldEJsb2NrVGl0bGUoYmxvY2tLZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRCbG9ja1RpdGxlKGJsb2NrS2V5KSB8fCBibG9ja0tleTtcbiAgICB9XG5cbiAgICBzZXRNYW5hZ2VHbG9iYWxDdXJzb3IodmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fbWFuYWdlR2xvYmFsQ3Vyc29yID0gdmFsdWU7XG4gICAgfVxuXG4gICAgc2V0U2VjdGlvbnNDb2x1bW5zRHJvcExpc3RDaGFuZ2Uoc2VjdGlvbnNDb2x1bW5zRHJvcExpc3Q6IGFueVtdKSB7XG4gICAgICAgIHRoaXMubm90aWZ5U2VjdGlvbnNDb2x1bW5zRHJvcExpc3RDaGFuZ2Uoc2VjdGlvbnNDb2x1bW5zRHJvcExpc3QpO1xuICAgIH1cblxuICAgIGNoYW5nZVByZXZpZXdNb2RlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMubm90aWZ5UHJldmlld01vZGVDaGFuZ2UodmFsdWUpO1xuICAgIH1cblxuICAgIGdldEN1cnJlbnRTY3JlZW5UeXBlKCk6IERhdGFWaWV3U2NyZWVuU2l6ZSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFNjcmVlblR5cGUodGhpcy5fc2NyZWVuU2l6ZVN1YmplY3Q/LmdldFZhbHVlKCkgfHwgUGVwU2NyZWVuU2l6ZVR5cGUuTEcpO1xuICAgIH1cblxuICAgIGdldFNjcmVlblR5cGUoc2l6ZTogUGVwU2NyZWVuU2l6ZVR5cGUpOiBEYXRhVmlld1NjcmVlblNpemUge1xuICAgICAgICBjb25zdCBzY3JlZW5UeXBlOiBEYXRhVmlld1NjcmVlblNpemUgPVxuICAgICAgICAgICAgc2l6ZSA8IFBlcFNjcmVlblNpemVUeXBlLk1EID8gJ0xhbmRzY2FwZScgOlxuICAgICAgICAgICAgKHNpemUgPT09IFBlcFNjcmVlblNpemVUeXBlLk1EIHx8IHNpemUgPT09IFBlcFNjcmVlblNpemVUeXBlLlNNID8gJ1RhYmxldCcgOiAnUGhhYmxldCcpO1xuXG4gICAgICAgIHJldHVybiBzY3JlZW5UeXBlO1xuICAgIH1cblxuICAgIGdldFNlY3Rpb25Db2x1bW5LZXkoc2VjdGlvbktleSA9ICcnLCBpbmRleCA9ICcnKSB7XG4gICAgICAgIHJldHVybiBgJHtzZWN0aW9uS2V5fV9jb2x1bW5fJHtpbmRleH1gO1xuICAgIH1cblxuICAgIGdldElzSGlkZGVuKGhpZGVJbjogRGF0YVZpZXdTY3JlZW5TaXplW10gfCB1bmRlZmluZWQsIGN1cnJlbnRTY3JlZW5UeXBlOiBEYXRhVmlld1NjcmVlblNpemUpIHtcbiAgICAgICAgcmV0dXJuIChoaWRlSW4gJiYgaGlkZUluPy5sZW5ndGggPiAwKSA/IGhpZGVJbi5zb21lKGhpID0+IGhpID09PSBjdXJyZW50U2NyZWVuVHlwZSkgOiBmYWxzZTtcbiAgICB9XG5cbiAgICBuYXZpZ2F0ZVRvRWRpdG9yKGVkaXRvclR5cGU6IFBlcExheW91dEVkaXRvclR5cGUsIGlkOiBzdHJpbmcsIHRpdGxlID0gJycpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IHN1Y2Nlc3MgPSBmYWxzZTtcblxuICAgICAgICAvLyBDYW5ub3QgbmF2aWdhdGUgaW50byAnbGF5b3V0LWJ1aWxkZXInIGJlY2F1c2UgdGhpcyBpcyBmaXJzdCBhbmQgY29uc3QgaW4gdGhlIGVkaXRvcnNCcmVhZENydW1icy5cbiAgICAgICAgaWYgKGVkaXRvclR5cGUgIT09ICdsYXlvdXQtYnVpbGRlcicgJiYgaWQ/Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIENoZWNrIHdoaWNoIGVkaXRvciB3ZSBoYXZlIG5vd1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEVkaXRvciA9IHRoaXMuX2VkaXRvcnNCcmVhZENydW1iW3RoaXMuX2VkaXRvcnNCcmVhZENydW1iLmxlbmd0aCAtIDFdO1xuXG4gICAgICAgICAgICAvLyBPbmx5IGlmIGl0J3MgYW5vdGhlciBlZGl0b3IuXG4gICAgICAgICAgICBpZihjdXJyZW50RWRpdG9yLmlkICE9PSBpZCkge1xuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50RWRpdG9yLnR5cGUgIT09ICdsYXlvdXQtYnVpbGRlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQWx3YXlzIHBvcCB0aGUgbGFzdCBhbmQgaW5zZXJ0IHRoZSBjdXJyZW50LlxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYi5wb3AoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBlZGl0b3IgPSB0aGlzLmdldEVkaXRvckJ5VHlwZShlZGl0b3JUeXBlLCBpZCwgdGl0bGUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGVkaXRvcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYi5wdXNoKGVkaXRvcik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlQ3VycmVudEVkaXRvcigpO1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3M7XG4gICAgfVxuXG4gICAgbmF2aWdhdGVCYWNrRnJvbUVkaXRvcigpIHtcbiAgICAgICAgLy8gS2VlcCB0aGUgbGF5b3V0IGJ1aWxkZXIgZWRpdG9yLlxuICAgICAgICBpZiAodGhpcy5fZWRpdG9yc0JyZWFkQ3J1bWIubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgLy8gTWF5YmUgd2Ugd2FudCB0byBjb21wYXJlIHRoZSBsYXN0IGVkaXRvciBmb3IgdmFsaWRhdGlvbiA/XG4gICAgICAgICAgICBjb25zdCBsYXN0RWRpdG9yID0gdGhpcy5fZWRpdG9yc0JyZWFkQ3J1bWIucG9wKCk7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZUN1cnJlbnRFZGl0b3IoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZUxheW91dEZyb21FZGl0b3IoZWRpdG9yRGF0YTogSUxheW91dEVkaXRvcikge1xuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcblxuICAgICAgICBpZiAobGF5b3V0Vmlldykge1xuICAgICAgICAgICAgbGF5b3V0Vmlldy5MYXlvdXQuTWF4V2lkdGggPSBlZGl0b3JEYXRhLm1heFdpZHRoO1xuICAgICAgICAgICAgbGF5b3V0Vmlldy5MYXlvdXQuSG9yaXpvbnRhbFNwYWNpbmcgPSBlZGl0b3JEYXRhLmhvcml6b250YWxTcGFjaW5nO1xuICAgICAgICAgICAgbGF5b3V0Vmlldy5MYXlvdXQuVmVydGljYWxTcGFjaW5nID0gZWRpdG9yRGF0YS52ZXJ0aWNhbFNwYWNpbmc7XG4gICAgICAgICAgICBsYXlvdXRWaWV3LkxheW91dC5TZWN0aW9uc0dhcCA9IGVkaXRvckRhdGEuc2VjdGlvbnNHYXA7XG4gICAgICAgICAgICBsYXlvdXRWaWV3LkxheW91dC5Db2x1bW5zR2FwID0gZWRpdG9yRGF0YS5jb2x1bW5zR2FwO1xuICAgICAgICAgICAgLy8gbGF5b3V0Vmlldy5MYXlvdXQuUm91bmRlZENvcm5lcnMgPSBlZGl0b3JEYXRhLnJvdW5kZWRDb3JuZXJzO1xuXG4gICAgICAgICAgICB0aGlzLm5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlldyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgdXBkYXRlU2VjdGlvbkZyb21FZGl0b3Ioc2VjdGlvbkRhdGE6IElMYXlvdXRTZWN0aW9uRWRpdG9yKSB7XG4gICAgICAgIGNvbnN0IGxheW91dFZpZXcgPSB0aGlzLl9sYXlvdXRWaWV3U3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgICAgICBjb25zdCBzZWN0aW9ucyA9IGxheW91dFZpZXc/LkxheW91dC5TZWN0aW9ucyB8fCBbXTtcbiAgICAgICAgY29uc3Qgc2VjdGlvbkluZGV4ID0gc2VjdGlvbnMuZmluZEluZGV4KHNlY3Rpb24gPT4gc2VjdGlvbi5LZXkgPT09IHNlY3Rpb25EYXRhLmlkKTtcblxuICAgICAgICAvLyBVcGRhdGUgc2VjdGlvbiBkZXRhaWxzLlxuICAgICAgICBpZiAoc2VjdGlvbkluZGV4ID49IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGJsb2Nrc0lkc1RvUmVtb3ZlID0gW107XG5cbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRTZWN0aW9uID0gc2VjdGlvbnNbc2VjdGlvbkluZGV4XTtcbiAgICAgICAgICAgIGN1cnJlbnRTZWN0aW9uLk5hbWUgPSBzZWN0aW9uRGF0YS5zZWN0aW9uTmFtZTtcbiAgICAgICAgICAgIGN1cnJlbnRTZWN0aW9uLlNwbGl0ID0gc2VjdGlvbkRhdGEuc3BsaXQ7XG4gICAgICAgICAgICBjdXJyZW50U2VjdGlvbi5IZWlnaHQgPSBzZWN0aW9uRGF0YS5oZWlnaHQ7XG4gICAgICAgICAgICBjdXJyZW50U2VjdGlvbi5Db2xsYXBzZU9uVGFibGV0ID0gc2VjdGlvbkRhdGEuY29sbGFwc2VPblRhYmxldDtcbiAgICAgICAgICAgIGN1cnJlbnRTZWN0aW9uLkZpbGxIZWlnaHQgPSBzZWN0aW9uRGF0YS5maWxsSGVpZ2h0O1xuICAgICAgICAgICAgY3VycmVudFNlY3Rpb24uUGFkZGluZyA9IHNlY3Rpb25EYXRhLnBhZGRpbmc7XG5cbiAgICAgICAgICAgIC8vIEdldCB0aGUgbmV3IGNvbHVtbnMgbnVtYmVyIGZyb20gY3VycmVudFNlY3Rpb24uU3BsaXQsIGlmIGl0cyB1bmRlZmluZWQgcHV0IGEgZGVmYXVsdCAxLlxuICAgICAgICAgICAgY29uc3QgbmV3Q29sdW1uc0xlbmd0aCA9IGN1cnJlbnRTZWN0aW9uLlNwbGl0Py5zcGxpdCgnICcpLmxlbmd0aCB8fCAxO1xuICAgICAgICAgICAgaWYgKG5ld0NvbHVtbnNMZW5ndGggPiBjdXJyZW50U2VjdGlvbi5Db2x1bW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdoaWxlIChuZXdDb2x1bW5zTGVuZ3RoID4gY3VycmVudFNlY3Rpb24uQ29sdW1ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFNlY3Rpb24uQ29sdW1ucy5wdXNoKHt9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5ld0NvbHVtbnNMZW5ndGggPCBjdXJyZW50U2VjdGlvbi5Db2x1bW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdoaWxlIChuZXdDb2x1bW5zTGVuZ3RoIDwgY3VycmVudFNlY3Rpb24uQ29sdW1ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29sdW5tID0gY3VycmVudFNlY3Rpb24uQ29sdW1ucy5wb3AoKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgYmxvY2sgaW4gdGhpcyBjb2x1bW4gZGVsZXRlIGl0LlxuICAgICAgICAgICAgICAgICAgICBpZiAoY29sdW5tICYmIGNvbHVubS5CbG9ja0NvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tzSWRzVG9SZW1vdmUucHVzaChjb2x1bm0uQmxvY2tDb250YWluZXIuQmxvY2tLZXkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBVcGRhdGUgZWRpdG9yIHRpdGxlXG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RWRpdG9yID0gdGhpcy5fZWRpdG9yU3ViamVjdC5nZXRWYWx1ZSgpO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRFZGl0b3IgJiYgY3VycmVudEVkaXRvci50eXBlID09PSAnc2VjdGlvbicgJiYgY3VycmVudEVkaXRvci5pZCA9PT0gY3VycmVudFNlY3Rpb24uS2V5KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGl0bGUgPSB0aGlzLmdldFNlY3Rpb25FZGl0b3JUaXRsZShjdXJyZW50U2VjdGlvbiwgc2VjdGlvbkluZGV4KTtcbiAgICAgICAgICAgICAgICBjdXJyZW50RWRpdG9yLnRpdGxlID0gdGl0bGU7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlFZGl0b3JDaGFuZ2UoY3VycmVudEVkaXRvcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFVwZGF0ZSBzZWN0aW9ucyBjaGFuZ2UuXG4gICAgICAgICAgICB0aGlzLm5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlldyk7XG5cbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBibG9ja3MgdG8gcmVtb3ZlLCBub3RpZnkgdGhlIGJsb2NrcyByZW1vdmVkLlxuICAgICAgICAgICAgaWYgKGJsb2Nrc0lkc1RvUmVtb3ZlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeUJsb2Nrc1JlbW92ZWQoYmxvY2tzSWRzVG9SZW1vdmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYWRkU2VjdGlvbihzZWN0aW9uOiBJUGVwTGF5b3V0U2VjdGlvbiB8IG51bGwgPSBudWxsKSB7XG4gICAgICAgIC8vIENyZWF0ZSBuZXcgc2VjdGlvblxuICAgICAgICBpZiAoIXNlY3Rpb24pIHtcbiAgICAgICAgICAgIHNlY3Rpb24gPSB7XG4gICAgICAgICAgICAgICAgS2V5OiBQZXBHdWlkLm5ld0d1aWQoKSxcbiAgICAgICAgICAgICAgICBDb2x1bW5zOiBbe31dLCAvLyBBZGQgZW1wdHkgc2VjdGlvbiBjb2x1bW5cbiAgICAgICAgICAgICAgICBIaWRlOiBbXVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIHRoZSBuZXcgc2VjdGlvbiB0byBsYXlvdXQgdmlldy5cbiAgICAgICAgY29uc3QgbGF5b3V0VmlldyA9IHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IHNlY3Rpb25zID0gbGF5b3V0Vmlldz8uTGF5b3V0LlNlY3Rpb25zIHx8IFtdO1xuICAgICAgICBzZWN0aW9ucy5wdXNoKHNlY3Rpb24pO1xuICAgICAgICB0aGlzLm5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlldyk7XG4gICAgfVxuXG4gICAgcmVtb3ZlU2VjdGlvbihzZWN0aW9uSWQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBsYXlvdXRWaWV3Py5MYXlvdXQuU2VjdGlvbnMgfHwgW107XG4gICAgICAgIGNvbnN0IGluZGV4ID0gc2VjdGlvbnMuZmluZEluZGV4KHNlY3Rpb24gPT4gc2VjdGlvbi5LZXkgPT09IHNlY3Rpb25JZCk7XG4gICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAvLyBHZXQgdGhlIGJsb2NrcyBpZCdzIHRvIHJlbW92ZS5cbiAgICAgICAgICAgIGNvbnN0IGJsb2Nrc0lkc1RvUmVtb3ZlOiBhbnkgPSBzZWN0aW9uc1tpbmRleF0uQ29sdW1ucy5tYXAoY29sdW1uID0+IGNvbHVtbj8uQmxvY2tDb250YWluZXI/LkJsb2NrS2V5KTtcblxuICAgICAgICAgICAgLy8gUmVtb3ZlIHNlY3Rpb24uXG4gICAgICAgICAgICBzZWN0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5ub3RpZnlMYXlvdXRWaWV3Q2hhbmdlKGxheW91dFZpZXcpO1xuXG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYmxvY2tzIHRvIHJlbW92ZSwgbm90aWZ5IHRoZSBibG9ja3MgcmVtb3ZlZC5cbiAgICAgICAgICAgIGlmIChibG9ja3NJZHNUb1JlbW92ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlCbG9ja3NSZW1vdmVkKGJsb2Nrc0lkc1RvUmVtb3ZlKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGlkZVNlY3Rpb24oc2VjdGlvbklkOiBzdHJpbmcsIGhpZGVJbjogRGF0YVZpZXdTY3JlZW5TaXplW10pIHtcbiAgICAgICAgY29uc3QgbGF5b3V0VmlldyA9IHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IHNlY3Rpb25zID0gbGF5b3V0Vmlldz8uTGF5b3V0LlNlY3Rpb25zIHx8IFtdO1xuICAgICAgICBjb25zdCBpbmRleCA9IHNlY3Rpb25zLmZpbmRJbmRleChzZWN0aW9uID0+IHNlY3Rpb24uS2V5ID09PSBzZWN0aW9uSWQpO1xuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAgc2VjdGlvbnNbaW5kZXhdLkhpZGUgPSBoaWRlSW47XG4gICAgICAgICAgICB0aGlzLm5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlldyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblNlY3Rpb25Ecm9wcGVkKGV2ZW50OiBDZGtEcmFnRHJvcDxhbnlbXT4pIHtcbiAgICAgICAgY29uc3QgbGF5b3V0VmlldyA9IHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IHNlY3Rpb25zID0gbGF5b3V0Vmlldz8uTGF5b3V0LlNlY3Rpb25zIHx8IFtdO1xuICAgICAgICBtb3ZlSXRlbUluQXJyYXkoc2VjdGlvbnMsIGV2ZW50LnByZXZpb3VzSW5kZXgsIGV2ZW50LmN1cnJlbnRJbmRleCk7XG4gICAgICAgIHRoaXMubm90aWZ5TGF5b3V0Vmlld0NoYW5nZShsYXlvdXRWaWV3KTtcbiAgICB9XG5cbiAgICBvblNlY3Rpb25EcmFnU3RhcnQoZXZlbnQ6IENka0RyYWdTdGFydCkge1xuICAgICAgICB0aGlzLmNoYW5nZUN1cnNvck9uRHJhZ1N0YXJ0KCk7XG4gICAgICAgIHRoaXMuX2RyYWdnaW5nU2VjdGlvbktleS5uZXh0KGV2ZW50LnNvdXJjZS5kYXRhKTtcbiAgICB9XG5cbiAgICBvblNlY3Rpb25EcmFnRW5kKGV2ZW50OiBDZGtEcmFnRW5kKSB7XG4gICAgICAgIHRoaXMuY2hhbmdlQ3Vyc29yT25EcmFnRW5kKCk7XG4gICAgICAgIHRoaXMuX2RyYWdnaW5nU2VjdGlvbktleS5uZXh0KCcnKTtcbiAgICB9XG5cbiAgICByZW1vdmVCbG9ja0Zyb21TZWN0aW9uKGJsb2NrSWQ6IHN0cmluZykge1xuICAgICAgICBsZXQgYmxvY2tSZW1vdmVkID0gZmFsc2U7XG5cbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBibG9jayBmcm9tIHNlY3Rpb24gY29sdW1uLlxuICAgICAgICBjb25zdCBsYXlvdXRWaWV3ID0gdGhpcy5fbGF5b3V0Vmlld1N1YmplY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBsYXlvdXRWaWV3Py5MYXlvdXQuU2VjdGlvbnMgfHwgW107XG4gICAgICAgIFxuICAgICAgICBmb3IgKGxldCBzZWN0aW9uSW5kZXggPSAwOyBzZWN0aW9uSW5kZXggPCBzZWN0aW9ucy5sZW5ndGg7IHNlY3Rpb25JbmRleCsrKSB7XG4gICAgICAgICAgICBjb25zdCBzZWN0aW9uID0gc2VjdGlvbnNbc2VjdGlvbkluZGV4XTtcblxuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBibG9jayBjb250YWluZXIuXG4gICAgICAgICAgICBjb25zdCBjb2x1bW5JbmRleCA9IHNlY3Rpb24uQ29sdW1ucy5maW5kSW5kZXgoY29sdW1uID0+IGNvbHVtbi5CbG9ja0NvbnRhaW5lcj8uQmxvY2tLZXkgPT09IGJsb2NrSWQpO1xuICAgICAgICAgICAgaWYgKGNvbHVtbkluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgc2VjdGlvbi5Db2x1bW5zW2NvbHVtbkluZGV4XS5CbG9ja0NvbnRhaW5lcjtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlldyk7XG4gICAgICAgICAgICAgICAgYmxvY2tSZW1vdmVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIGJsb2NrIHdhcyByZW1vdmVkLCBub3RpZnkgdGhlIGJsb2NrIHJlbW92ZWQuXG4gICAgICAgIGlmIChibG9ja1JlbW92ZWQpIHtcbiAgICAgICAgICAgIHRoaXMubm90aWZ5QmxvY2tzUmVtb3ZlZChbYmxvY2tJZF0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGlkZUJsb2NrKHNlY3Rpb25JZDogc3RyaW5nLCBibG9ja0lkOiBzdHJpbmcsIGhpZGVJbjogRGF0YVZpZXdTY3JlZW5TaXplW10pIHtcbiAgICAgICAgY29uc3QgbGF5b3V0VmlldyA9IHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IHNlY3Rpb25zID0gbGF5b3V0Vmlldz8uTGF5b3V0LlNlY3Rpb25zIHx8IFtdO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgaW5kZXggPSBzZWN0aW9ucy5maW5kSW5kZXgoc2VjdGlvbiA9PiBzZWN0aW9uLktleSA9PT0gc2VjdGlvbklkKTtcbiAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbkluZGV4ID0gc2VjdGlvbnNbaW5kZXhdLkNvbHVtbnMuZmluZEluZGV4KGNvbHVtbiA9PiBjb2x1bW4uQmxvY2tDb250YWluZXI/LkJsb2NrS2V5ID09PSBibG9ja0lkKTtcbiAgICAgICAgICAgIGlmIChjb2x1bW5JbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYmxvY2tDb250YWluZXIgPSBzZWN0aW9uc1tpbmRleF0uQ29sdW1uc1tjb2x1bW5JbmRleF0uQmxvY2tDb250YWluZXI7XG4gICAgICAgICAgICAgICAgaWYgKGJsb2NrQ29udGFpbmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGJsb2NrQ29udGFpbmVyLkhpZGUgPSBoaWRlSW47XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5TGF5b3V0Vmlld0NoYW5nZShsYXlvdXRWaWV3KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkJsb2NrRHJvcHBlZChldmVudDogQ2RrRHJhZ0Ryb3A8SVBlcExheW91dFNlY3Rpb25Db2x1bW4sIGFueSwgYW55Piwgc2VjdGlvbklkOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgbGF5b3V0VmlldyA9IHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmdldFZhbHVlKCk7XG5cbiAgICAgICAgaWYgKGV2ZW50LnByZXZpb3VzQ29udGFpbmVyLmlkID09PSBMYXlvdXRCdWlsZGVySW50ZXJuYWxTZXJ2aWNlLkFWQUlMQUJMRV9CTE9DS1NfQ09OVEFJTkVSX0lEKSB7XG4gICAgICAgICAgICAvLyBWYWxpZGF0ZSBpZiBibG9ja3MgbnVtYmVyIGFsbG93LlxuICAgICAgICAgICAgaWYgKHRoaXMuX2Jsb2Nrc0xpbWl0TnVtYmVyID4gMCAmJiB0aGlzLmdldEJsb2Nrc051bWJlcigpID49IHRoaXMuX2Jsb2Nrc0xpbWl0TnVtYmVyKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IG5ldyBQZXBEaWFsb2dEYXRhKHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ01FU1NBR0VTLkRJQUxPR19OT1RJQ0VfVElUTEUnKSxcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogdGhpcy50cmFuc2xhdGUuaW5zdGFudCgnTEFZT1VUX0JVSUxERVIuQkxPQ0tTX0NPVU5UX0xJTUlUX01FU1NBR0UnKSxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHRoaXMuZGlhbG9nU2VydmljZS5vcGVuRGVmYXVsdERpYWxvZyhkYXRhKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBibG9jayByZWxhdGlvbiAocHJldmlvdXNDb250YWluZXIuZGF0YSBpcyBJUGVwRHJhZ2dhYmxlSXRlbSBhbmQgaW5zaWRlIHdlIGhhdmUgQXZhaWxhYmxlQmxvY2sgb2JqZWN0KS5cbiAgICAgICAgICAgICAgICBjb25zdCBkcmFnZ2FibGVJdGVtOiBJUGVwRHJhZ2dhYmxlSXRlbSA9IGV2ZW50LnByZXZpb3VzQ29udGFpbmVyLmRhdGFbZXZlbnQucHJldmlvdXNJbmRleF0gYXMgSVBlcERyYWdnYWJsZUl0ZW07XG5cbiAgICAgICAgICAgICAgICBpZiAoZHJhZ2dhYmxlSXRlbSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBsb2NrIHRoZSBzY3JlZW4gdW50aWxsIHRoZSBlZGl0b3Igd2lsbCBiZSBsb2FkZWQuXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMuX2xvY2tTY3JlZW5TdWJqZWN0Lm5leHQodHJ1ZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBjb2x1bW4uXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRDb2x1bW4gPSB0aGlzLmdldFNlY3Rpb25Db2x1bW5CeUlkRm9yRWRpdG9yKGV2ZW50LmNvbnRhaW5lci5pZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gU2V0IHRoZSBibG9jayBrZXkgaW4gdGhlIHNlY3Rpb24gYmxvY2sgb25seSBpZiB0aGVyZSBpcyBhIGJsYW5rIGNvbHVtbi5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRDb2x1bW4gJiYgIWN1cnJlbnRDb2x1bW4uQmxvY2tDb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdlbmVyYXRlIHRoZSBibG9jayB1dWlkLlxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYmxvY2tLZXkgPSBQZXBHdWlkLm5ld0d1aWQoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudENvbHVtbi5CbG9ja0NvbnRhaW5lciA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBCbG9ja0tleTogYmxvY2tLZXksXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBIZXJlIHdlIHVwZGF0ZSB0aGUgbGF5b3V0IHZpZXcgY2F1c2UgdGhlIGxheW91dCBpcyB1cGRhdGVkLlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlMYXlvdXRWaWV3Q2hhbmdlKGxheW91dFZpZXcpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSYWlzZSBibG9jayBhZGRlZCBldmVudC5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJsb2NrQWRkZWRFdmVudERhdGE6IElQZXBMYXlvdXRCbG9ja0FkZGVkRXZlbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQmxvY2tLZXk6IGJsb2NrS2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIERyYWdnYWJsZUl0ZW06IGRyYWdnYWJsZUl0ZW0sXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5QmxvY2tBZGRlZChibG9ja0FkZGVkRXZlbnREYXRhKTsgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmF2aWdhdGVUb0VkaXRvckFmdGVyQmxvY2tBZGRlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5hdmlnYXRlIHRvIHRoZSBibG9jayBlZGl0b3IuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXZpZ2F0ZVRvRWRpdG9yKCdibG9jaycsIGJsb2NrS2V5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiZHJhZ2dhYmxlSXRlbSBpcyBub3QgYSBJUGVwRHJhZ2dhYmxlSXRlbSB0eXBlXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBibG9jayBtb3ZlZCBiZXR3ZWVuIGNvbHVtbnMgaW4gdGhlIHNhbWUgc2VjdGlvbiBvciBiZXR3ZWVuIGRpZmZlcmVudCBzZWN0aW9ucyBidXQgbm90IGluIHRoZSBzYW1lIGNvbHVtbi5cbiAgICAgICAgICAgIGlmIChldmVudC5jb250YWluZXIuaWQgIT09IGV2ZW50LnByZXZpb3VzQ29udGFpbmVyLmlkKSB7XG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBjb2x1bW4uXG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudENvbHVtbiA9IHRoaXMuZ2V0U2VjdGlvbkNvbHVtbkJ5SWRGb3JFZGl0b3IoZXZlbnQuY29udGFpbmVyLmlkKTtcbiAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIHByZXZpb3VzIGNvbHVtbi5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmV2aXVvc0NvbHVtbiA9IHRoaXMuZ2V0U2VjdGlvbkNvbHVtbkJ5SWRGb3JFZGl0b3IoZXZlbnQucHJldmlvdXNDb250YWluZXIuaWQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRDb2x1bW4gJiYgcHJldml1b3NDb2x1bW4pIHtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudENvbHVtbi5CbG9ja0NvbnRhaW5lciA9IHByZXZpdW9zQ29sdW1uLkJsb2NrQ29udGFpbmVyO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcHJldml1b3NDb2x1bW4uQmxvY2tDb250YWluZXI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5TGF5b3V0Vmlld0NoYW5nZShsYXlvdXRWaWV3KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkJsb2NrRHJhZ1N0YXJ0KGV2ZW50OiBDZGtEcmFnU3RhcnQpIHtcbiAgICAgICAgdGhpcy5jaGFuZ2VDdXJzb3JPbkRyYWdTdGFydCgpO1xuICAgICAgICAvLyBUYWtlIHRoZSBibG9jayBrZXkgaWYgZXhpc3QsIGVsc2UgdGFrZSB0aGUgYXZhaWxhYmxlIGJsb2NrIGtleSAocmVsYXRpb24ga2V5KS5cbiAgICAgICAgY29uc3QgYmxvY2tLZXkgPSBldmVudC5zb3VyY2UuZGF0YT8uQmxvY2tLZXkgfHwgZXZlbnQuc291cmNlLmRhdGE/LktleTtcbiAgICAgICAgdGhpcy5fZHJhZ2dpbmdCbG9ja0tleS5uZXh0KGJsb2NrS2V5KTtcbiAgICB9XG5cbiAgICBvbkJsb2NrRHJhZ0VuZChldmVudDogQ2RrRHJhZ0VuZCkge1xuICAgICAgICB0aGlzLmNoYW5nZUN1cnNvck9uRHJhZ0VuZCgpO1xuICAgICAgICB0aGlzLl9kcmFnZ2luZ0Jsb2NrS2V5Lm5leHQoJycpO1xuICAgIH1cbiAgICBcbiAgICBkb2VzQ29sdW1uQ29udGFpbkJsb2NrKHNlY3Rpb25JZDogc3RyaW5nLCBjb2x1bW5JbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCByZXMgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgbGF5b3V0VmlldyA9IHRoaXMuX2xheW91dFZpZXdTdWJqZWN0LmdldFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IHNlY3Rpb24gPSBsYXlvdXRWaWV3Py5MYXlvdXQuU2VjdGlvbnMuZmluZChzZWN0aW9uID0+IHNlY3Rpb24uS2V5ID09PSBzZWN0aW9uSWQpO1xuXG4gICAgICAgIGlmIChzZWN0aW9uICYmIGNvbHVtbkluZGV4ID49IDAgJiYgc2VjdGlvbi5Db2x1bW5zLmxlbmd0aCA+IGNvbHVtbkluZGV4KSB7XG4gICAgICAgICAgICByZXMgPSAhIXNlY3Rpb24uQ29sdW1uc1tjb2x1bW5JbmRleF0uQmxvY2tDb250YWluZXI7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIHNldFNjcmVlbldpZHRoKHNjcmVlblR5cGU6IERhdGFWaWV3U2NyZWVuU2l6ZSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0Q3NzU2NyZWVuV2lkaChzY3JlZW5UeXBlKVxuXG4gICAgICAgIGNvbnN0IHdpZHRoID0gY29lcmNlTnVtYmVyUHJvcGVydHkodmFsdWUsIDApO1xuICAgICAgICBpZiAod2lkdGggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuX3NjcmVlbldpZHRoU3ViamVjdC5uZXh0KCcxMDAlJyk7XG4gICAgICAgICAgICB0aGlzLm5vdGlmeVNjcmVlblNpemVDaGFuZ2UoUGVwU2NyZWVuU2l6ZVR5cGUuWEwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2NyZWVuV2lkdGhTdWJqZWN0Lm5leHQoYCR7d2lkdGh9cHhgKTtcblxuICAgICAgICAgICAgLy8gQ2hhbmdlIHRoZSBzaXplIGFjY29yZGluZyB0aGUgd2lkdGguXG4gICAgICAgICAgICBpZiAod2lkdGggPj0gMTkyMCkge1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5U2NyZWVuU2l6ZUNoYW5nZShQZXBTY3JlZW5TaXplVHlwZS5YTCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHdpZHRoID49IDEyODAgJiYgd2lkdGggPCAxOTIwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlTY3JlZW5TaXplQ2hhbmdlKFBlcFNjcmVlblNpemVUeXBlLkxHKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAod2lkdGggPj0gOTYwICYmIHdpZHRoIDwgMTI4MCkge1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5U2NyZWVuU2l6ZUNoYW5nZShQZXBTY3JlZW5TaXplVHlwZS5NRCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHdpZHRoID49IDYwMCAmJiB3aWR0aCA8IDk2MCkge1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5U2NyZWVuU2l6ZUNoYW5nZShQZXBTY3JlZW5TaXplVHlwZS5TTSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHdpZHRoIDwgNjAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZnlTY3JlZW5TaXplQ2hhbmdlKFBlcFNjcmVlblNpemVUeXBlLlhTKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNob3dTa2VsZXRvbihzaG93OiBib29sZWFuKTogdm9pZCB7XG4gICAgLy8gICAgIHRoaXMuX3Nob3dTa2VsZXRvblN1YmplY3QubmV4dChzaG93KTtcbiAgICAvLyB9XG4gICAgXG4gICAgLy8gbG9ja1NjcmVlbih2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIC8vICAgICB0aGlzLm5vdGlmeUxvY2tTY3JlZW4odmFsdWUpO1xuICAgIC8vIH1cblxuICAgIGxvYWRMYXlvdXRCdWlsZGVyKGxheW91dFZpZXc6IElQZXBMYXlvdXRWaWV3KTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmVkaXRvck1vZGUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9lZGl0b3JzQnJlYWRDcnVtYi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAvLyBMb2FkIHRoZSBsYXlvdXQgZWRpdG9yLlxuICAgICAgICAgICAgICAgIHRoaXMubG9hZERlZmF1bHRFZGl0b3IobGF5b3V0Vmlldyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb2FkIG9ubHkgdGhlIGxheW91dCB2aWV3LlxuICAgICAgICB0aGlzLm5vdGlmeUxheW91dFZpZXdDaGFuZ2UobGF5b3V0Vmlldyk7XG4gICAgfVxufVxuIl19
|