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