@ceriousdevtech/ngx-cerious-scroll 1.0.0 → 1.0.2
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/README.md +287 -13
- package/esm2022/lib/cerious-scroll.directive.mjs +231 -18
- package/fesm2022/ceriousdevtech-ngx-cerious-scroll.mjs +230 -17
- package/fesm2022/ceriousdevtech-ngx-cerious-scroll.mjs.map +1 -1
- package/lib/cerious-scroll.directive.d.ts +37 -0
- package/package.json +9 -5
- package/LICENSE-COMMERCIAL +0 -71
|
@@ -35,7 +35,13 @@ export class CeriousScrollDirective {
|
|
|
35
35
|
this.ceriousScrollReady = new EventEmitter();
|
|
36
36
|
this.hostRef = null;
|
|
37
37
|
this.viewportSub = null;
|
|
38
|
+
this.scheduledRenderFrame = null;
|
|
38
39
|
this.viewByContainer = new Map();
|
|
40
|
+
// Pool of views detached because their container left the viewport. Reusing
|
|
41
|
+
// them on subsequent renders avoids destroying + recreating the entire row
|
|
42
|
+
// component tree on fast scrolls (where the engine's element pool wipes
|
|
43
|
+
// textContent on reused containers, so view rootNodes get orphaned).
|
|
44
|
+
this.freeViews = [];
|
|
39
45
|
}
|
|
40
46
|
ngAfterViewInit() {
|
|
41
47
|
this.ensureInitialized();
|
|
@@ -45,10 +51,33 @@ export class CeriousScrollDirective {
|
|
|
45
51
|
return;
|
|
46
52
|
if (changes['ceriousScrollItems'] || changes['ceriousScrollTotalElements']) {
|
|
47
53
|
const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
|
|
48
|
-
this.hostRef.scroller.totalElements
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
const countChanged = this.hostRef.scroller.totalElements !== total;
|
|
55
|
+
if (countChanged) {
|
|
56
|
+
// The dataset size changed: the ViewportRenderer stores its own copy of
|
|
57
|
+
// totalElements (set by value at construction) so patching the engine's
|
|
58
|
+
// public property alone leaves the renderer's internal bound stale. The
|
|
59
|
+
// renderer would then use the old count for its viewport-fill loop and
|
|
60
|
+
// bottom-boundary scan, producing phantom renders at out-of-bounds
|
|
61
|
+
// indices (undefined items → 0-height rows → the fill loop never
|
|
62
|
+
// satisfies its height condition → hundreds of renderer callbacks).
|
|
63
|
+
// Recreating the engine gives both the engine and the renderer a fresh,
|
|
64
|
+
// consistent count. ensureInitialized() schedules the first render via
|
|
65
|
+
// queueMicrotask, which runs after the current CD cycle completes.
|
|
66
|
+
this.recreate();
|
|
67
|
+
}
|
|
68
|
+
else if (this.ceriousScrollAutoRender) {
|
|
69
|
+
// Same count, new data reference (e.g. an immutable edit or a sort that
|
|
70
|
+
// happens to keep the same length). The engine reuses the DOM element it
|
|
71
|
+
// already rendered for each overlapping index without re-invoking the
|
|
72
|
+
// renderer, so update the content of every currently-visible row IN
|
|
73
|
+
// PLACE before calling render(). This preserves each row's embedded
|
|
74
|
+
// view (so a focused textbox keeps focus/caret) and does NOT discard
|
|
75
|
+
// cached heights. If a row's height actually changes the engine's
|
|
76
|
+
// ResizeObserver keeps the cache correct on its own; for a wholesale
|
|
77
|
+
// height change across all rows, call recalculate() instead.
|
|
78
|
+
this.refreshRenderedContent();
|
|
51
79
|
this.render();
|
|
80
|
+
}
|
|
52
81
|
}
|
|
53
82
|
if (changes['ceriousScrollOptions'] && !changes['ceriousScrollOptions'].firstChange) {
|
|
54
83
|
// Options are consumed primarily at construction time.
|
|
@@ -56,6 +85,10 @@ export class CeriousScrollDirective {
|
|
|
56
85
|
}
|
|
57
86
|
}
|
|
58
87
|
ngOnDestroy() {
|
|
88
|
+
if (this.scheduledRenderFrame != null) {
|
|
89
|
+
cancelAnimationFrame(this.scheduledRenderFrame);
|
|
90
|
+
this.scheduledRenderFrame = null;
|
|
91
|
+
}
|
|
59
92
|
this.viewportSub?.unsubscribe();
|
|
60
93
|
this.viewportSub = null;
|
|
61
94
|
this.destroyAllViews();
|
|
@@ -72,16 +105,122 @@ export class CeriousScrollDirective {
|
|
|
72
105
|
const hostContainer = this.host.nativeElement;
|
|
73
106
|
const height = hostContainer.clientHeight || hostContainer.offsetHeight;
|
|
74
107
|
const contentContainer = this.hostRef.contentElement;
|
|
108
|
+
// Track whether the engine asked us to bind any row this pass. Pure scroll
|
|
109
|
+
// frames where the visible row set doesn't change still drive render() via
|
|
110
|
+
// the rAF coalescer — there's no point in walking the prune map or
|
|
111
|
+
// emitting the viewport range when nothing was touched.
|
|
112
|
+
let rendererInvocations = 0;
|
|
75
113
|
const renderer = (index, elementContainer) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
114
|
+
rendererInvocations++;
|
|
115
|
+
// Render each row's embedded view with LOCAL change detection
|
|
116
|
+
// (`view.detectChanges()` inside `renderTemplateIntoContainer`) so the
|
|
117
|
+
// engine can measure its height during this pass. Do NOT wrap each row in
|
|
118
|
+
// its own `ngZone.run` — that fires a full `ApplicationRef` tick *per row*
|
|
119
|
+
// (O(newRows × visibleRows) work, janky drags). The single coalesced tick
|
|
120
|
+
// for the whole pass is handled by the caller (`scheduleRender`).
|
|
121
|
+
this.renderTemplateIntoContainer(template, index, elementContainer);
|
|
80
122
|
};
|
|
81
123
|
const range = this.hostRef.scroller.renderViewport(height, contentContainer, renderer);
|
|
82
|
-
|
|
124
|
+
if (rendererInvocations === 0) {
|
|
125
|
+
// Viewport didn't change — skip the prune walk and the (potentially
|
|
126
|
+
// zone-entering) emit.
|
|
127
|
+
return range;
|
|
128
|
+
}
|
|
129
|
+
// Destroy views whose container the engine no longer renders. Without this,
|
|
130
|
+
// every container the engine recycles into its element pool leaves its
|
|
131
|
+
// embedded view attached to ApplicationRef forever — so the attached-view
|
|
132
|
+
// list (and every O(n) `detachView`) grows without bound and scrolling gets
|
|
133
|
+
// progressively slower. Mirrors the React/Vue wrappers, which drop rows that
|
|
134
|
+
// fall out of `getRenderedIndices()`.
|
|
135
|
+
this.pruneDetachedViews();
|
|
136
|
+
// Only re-enter the zone (a global tick) if someone is actually listening.
|
|
137
|
+
if (this.ceriousScrollMeasuredViewport.observed) {
|
|
138
|
+
this.ngZone.run(() => this.ceriousScrollMeasuredViewport.emit(range));
|
|
139
|
+
}
|
|
83
140
|
return range;
|
|
84
141
|
}
|
|
142
|
+
/** Tear down embedded views whose container is no longer part of the viewport. */
|
|
143
|
+
pruneDetachedViews() {
|
|
144
|
+
if (!this.hostRef || this.viewByContainer.size === 0)
|
|
145
|
+
return;
|
|
146
|
+
const scroller = this.hostRef.scroller;
|
|
147
|
+
const active = new Set();
|
|
148
|
+
for (const index of scroller.getRenderedIndices()) {
|
|
149
|
+
const el = scroller.getRenderedElement(index);
|
|
150
|
+
if (el)
|
|
151
|
+
active.add(el);
|
|
152
|
+
}
|
|
153
|
+
for (const [container, view] of this.viewByContainer) {
|
|
154
|
+
if (!active.has(container)) {
|
|
155
|
+
// Detach DOM but keep the view alive in the pool for future reuse.
|
|
156
|
+
// Destroying + recreating views per scroll step dominates frame time.
|
|
157
|
+
for (const node of view.rootNodes) {
|
|
158
|
+
if (node.parentNode)
|
|
159
|
+
node.parentNode.removeChild(node);
|
|
160
|
+
}
|
|
161
|
+
this.viewByContainer.delete(container);
|
|
162
|
+
this.freeViews.push(view);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/** Auto-render coalesced to at most once per animation frame. */
|
|
167
|
+
scheduleRender() {
|
|
168
|
+
if (this.scheduledRenderFrame != null)
|
|
169
|
+
return;
|
|
170
|
+
this.scheduledRenderFrame = requestAnimationFrame(() => {
|
|
171
|
+
this.scheduledRenderFrame = null;
|
|
172
|
+
// Run render() OUTSIDE Angular's zone. A full ApplicationRef.tick() on
|
|
173
|
+
// every scroll frame is the primary FPS bottleneck: even when no rows
|
|
174
|
+
// change (pure translation), ngZone.run() causes Angular to walk the
|
|
175
|
+
// entire component tree. Instead we call view.detectChanges() locally
|
|
176
|
+
// inside renderTemplateIntoContainer for each affected row. Zone entry is
|
|
177
|
+
// only needed when creating a brand-new embedded view (to zone-patch its
|
|
178
|
+
// event listeners) — recycled and pooled views were already created inside
|
|
179
|
+
// zone and their listeners remain zone-aware.
|
|
180
|
+
this.render();
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Discard all cached row heights and re-measure the viewport.
|
|
185
|
+
*
|
|
186
|
+
* Call this only when the heights of rows you've *already rendered* may have
|
|
187
|
+
* changed without their indices changing — e.g. a global font/density change,
|
|
188
|
+
* or swapping every row to a different layout. This forces a synchronous
|
|
189
|
+
* re-measure (one `offsetHeight` read per visible row), so do NOT call it on
|
|
190
|
+
* routine edits: a single cell edit keeps its row's size, and the engine's
|
|
191
|
+
* ResizeObserver picks up any incidental resize on its own.
|
|
192
|
+
*/
|
|
193
|
+
recalculate() {
|
|
194
|
+
if (!this.hostRef)
|
|
195
|
+
return null;
|
|
196
|
+
// Discard the cached heights, then re-render. The engine re-measures and
|
|
197
|
+
// re-caches the rendered rows during the pass and refreshes the scroll
|
|
198
|
+
// percentage, so an in-place height change (e.g. expand/collapse) is
|
|
199
|
+
// reflected in the total content height and scrollbar immediately.
|
|
200
|
+
this.hostRef.scroller.clearAllCaches();
|
|
201
|
+
return this.render();
|
|
202
|
+
}
|
|
203
|
+
/** Jump directly to an element index, then render. */
|
|
204
|
+
jumpToElement(index) {
|
|
205
|
+
if (!this.hostRef)
|
|
206
|
+
return null;
|
|
207
|
+
this.hostRef.scroller.jumpToElement(index);
|
|
208
|
+
return this.render();
|
|
209
|
+
}
|
|
210
|
+
/** Scroll to a percentage (0..100), then render. */
|
|
211
|
+
scrollToPercentage(percentage) {
|
|
212
|
+
if (!this.hostRef)
|
|
213
|
+
return null;
|
|
214
|
+
this.hostRef.scroller.handleScrollPercentage(percentage);
|
|
215
|
+
return this.render();
|
|
216
|
+
}
|
|
217
|
+
/** Reset to the top, then render. */
|
|
218
|
+
reset() {
|
|
219
|
+
if (!this.hostRef)
|
|
220
|
+
return null;
|
|
221
|
+
this.hostRef.scroller.reset();
|
|
222
|
+
return this.render();
|
|
223
|
+
}
|
|
85
224
|
recreate() {
|
|
86
225
|
this.viewportSub?.unsubscribe();
|
|
87
226
|
this.viewportSub = null;
|
|
@@ -96,11 +235,16 @@ export class CeriousScrollDirective {
|
|
|
96
235
|
const container = this.host.nativeElement;
|
|
97
236
|
const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
|
|
98
237
|
this.hostRef = this.cerious.createHost(container, total, this.ceriousScrollOptions, this.ngZone, () => {
|
|
238
|
+
// Coalesce scroll-driven renders to one per frame (the native scrollbar
|
|
239
|
+
// can fire many scroll events between paints).
|
|
99
240
|
if (this.ceriousScrollAutoRender)
|
|
100
|
-
this.
|
|
241
|
+
this.scheduleRender();
|
|
101
242
|
});
|
|
102
243
|
this.viewportSub = this.hostRef.viewportChanges$.subscribe((detail) => {
|
|
103
|
-
|
|
244
|
+
// Skip the global tick when nobody is bound to the output.
|
|
245
|
+
if (this.ceriousScrollViewportChange.observed) {
|
|
246
|
+
this.ngZone.run(() => this.ceriousScrollViewportChange.emit(detail));
|
|
247
|
+
}
|
|
104
248
|
});
|
|
105
249
|
this.ceriousScrollReady.emit(this.hostRef.scroller);
|
|
106
250
|
if (this.ceriousScrollAutoRender) {
|
|
@@ -119,27 +263,96 @@ export class CeriousScrollDirective {
|
|
|
119
263
|
renderTemplateIntoContainer(template, index, elementContainer) {
|
|
120
264
|
const previous = this.viewByContainer.get(elementContainer);
|
|
121
265
|
if (previous) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
this.
|
|
266
|
+
// Recycle: update the bound context and run local CD instead of
|
|
267
|
+
// destroying the embedded view and rebuilding the entire row tree.
|
|
268
|
+
const item = this.getItemForIndex(index);
|
|
269
|
+
previous.context.$implicit = item;
|
|
270
|
+
previous.context.item = item;
|
|
271
|
+
previous.context.index = index;
|
|
272
|
+
// The core engine wipes elementContainer.textContent when reusing it from
|
|
273
|
+
// its pool, orphaning the view's root nodes. Re-append them defensively.
|
|
274
|
+
if (previous.rootNodes.length && previous.rootNodes[0].parentNode !== elementContainer) {
|
|
275
|
+
for (const node of previous.rootNodes) {
|
|
276
|
+
elementContainer.appendChild(node);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
previous.detectChanges();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
// Try to reuse a pooled view from a container that scrolled out of viewport.
|
|
283
|
+
const pooled = this.freeViews.pop();
|
|
284
|
+
if (pooled) {
|
|
285
|
+
const item = this.getItemForIndex(index);
|
|
286
|
+
pooled.context.$implicit = item;
|
|
287
|
+
pooled.context.item = item;
|
|
288
|
+
pooled.context.index = index;
|
|
289
|
+
elementContainer.textContent = '';
|
|
290
|
+
for (const node of pooled.rootNodes) {
|
|
291
|
+
elementContainer.appendChild(node);
|
|
292
|
+
}
|
|
293
|
+
pooled.detectChanges();
|
|
294
|
+
this.viewByContainer.set(elementContainer, pooled);
|
|
295
|
+
return;
|
|
125
296
|
}
|
|
126
|
-
//
|
|
297
|
+
// No prior view for this container: create one.
|
|
298
|
+
// Enter the Angular zone so the new view's template event listeners
|
|
299
|
+
// ((click), (input), etc.) are zone-patched. This path runs at most
|
|
300
|
+
// once per visible row (after that, the view is recycled from the pool).
|
|
127
301
|
elementContainer.textContent = '';
|
|
128
302
|
const item = this.getItemForIndex(index);
|
|
129
|
-
const view =
|
|
130
|
-
|
|
131
|
-
|
|
303
|
+
const view = this.ngZone.run(() => {
|
|
304
|
+
const v = template.createEmbeddedView({ $implicit: item, item, index });
|
|
305
|
+
this.appRef.attachView(v);
|
|
306
|
+
v.detectChanges();
|
|
307
|
+
return v;
|
|
308
|
+
});
|
|
132
309
|
for (const node of view.rootNodes) {
|
|
133
310
|
elementContainer.appendChild(node);
|
|
134
311
|
}
|
|
135
312
|
this.viewByContainer.set(elementContainer, view);
|
|
136
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* Update the bound item/index on every currently-rendered row's embedded view
|
|
316
|
+
* and run change detection, without recreating the views. Used when the data
|
|
317
|
+
* reference changes but the visible indices (and their heights) do not, so row
|
|
318
|
+
* state (focus, selection, open dropdowns) survives the update.
|
|
319
|
+
*/
|
|
320
|
+
/**
|
|
321
|
+
* Re-bind each currently rendered row's context (from the current items/getter)
|
|
322
|
+
* and run change detection on its embedded view. Use this after mutating row
|
|
323
|
+
* state in place (e.g. selection flags) or column-level state read by the row
|
|
324
|
+
* template, when row identity and visible indices have not changed. Cheap
|
|
325
|
+
* relative to `render()` — does not invoke the engine's measurement pass.
|
|
326
|
+
*/
|
|
327
|
+
refreshRenderedContent() {
|
|
328
|
+
if (!this.hostRef)
|
|
329
|
+
return;
|
|
330
|
+
const scroller = this.hostRef.scroller;
|
|
331
|
+
for (const index of scroller.getRenderedIndices()) {
|
|
332
|
+
const container = scroller.getRenderedElement(index);
|
|
333
|
+
if (!container)
|
|
334
|
+
continue;
|
|
335
|
+
const view = this.viewByContainer.get(container);
|
|
336
|
+
if (!view)
|
|
337
|
+
continue;
|
|
338
|
+
const item = this.getItemForIndex(index);
|
|
339
|
+
view.context.$implicit = item;
|
|
340
|
+
view.context.item = item;
|
|
341
|
+
view.context.index = index;
|
|
342
|
+
view.detectChanges();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
137
345
|
destroyAllViews() {
|
|
138
346
|
for (const view of this.viewByContainer.values()) {
|
|
139
347
|
this.appRef.detachView(view);
|
|
140
348
|
view.destroy();
|
|
141
349
|
}
|
|
142
350
|
this.viewByContainer.clear();
|
|
351
|
+
for (const view of this.freeViews) {
|
|
352
|
+
this.appRef.detachView(view);
|
|
353
|
+
view.destroy();
|
|
354
|
+
}
|
|
355
|
+
this.freeViews.length = 0;
|
|
143
356
|
}
|
|
144
357
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollDirective, deps: [{ token: i0.ElementRef }, { token: i0.ApplicationRef }, { token: i0.NgZone }, { token: i1.CeriousScrollService }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
145
358
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: CeriousScrollDirective, isStandalone: true, selector: "[ceriousScroll]", inputs: { ceriousScrollTotalElements: "ceriousScrollTotalElements", ceriousScrollItems: "ceriousScrollItems", ceriousScrollGetItem: "ceriousScrollGetItem", ceriousScrollItemTemplate: "ceriousScrollItemTemplate", ceriousScrollOptions: "ceriousScrollOptions", ceriousScrollAutoRender: "ceriousScrollAutoRender" }, outputs: { ceriousScrollViewportChange: "ceriousScrollViewportChange", ceriousScrollMeasuredViewport: "ceriousScrollMeasuredViewport", ceriousScrollReady: "ceriousScrollReady" }, usesOnChanges: true, ngImport: i0 }); }
|
|
@@ -169,4 +382,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
169
382
|
}], ceriousScrollReady: [{
|
|
170
383
|
type: Output
|
|
171
384
|
}] } });
|
|
172
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNlcmlvdXMtc2Nyb2xsL3NyYy9saWIvY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFHTCxTQUFTLEVBR1QsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEdBR1AsTUFBTSxlQUFlLENBQUM7OztBQWF2QixTQUFTLG1CQUFtQixDQUFDLGFBQXdDLEVBQUUsUUFBbUM7SUFDeEcsTUFBTSxTQUFTLEdBQUcsT0FBTyxhQUFhLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDMUgsSUFBSSxTQUFTLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUN2RCxNQUFNLElBQUksS0FBSyxDQUFDLHVGQUF1RixDQUFDLENBQUM7SUFDM0csQ0FBQztJQUNELHdDQUF3QztJQUN4QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFNRCxNQUFNLE9BQU8sc0JBQXNCO0lBaUNqQyxZQUNtQixJQUE2QixFQUM3QixNQUFzQixFQUN0QixNQUFjLEVBQ2QsT0FBNkI7UUFIN0IsU0FBSSxHQUFKLElBQUksQ0FBeUI7UUFDN0IsV0FBTSxHQUFOLE1BQU0sQ0FBZ0I7UUFDdEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQXNCO1FBcENoRCxtRkFBbUY7UUFDMUUsK0JBQTBCLEdBQWtCLElBQUksQ0FBQztRQUUxRCxpREFBaUQ7UUFDeEMsdUJBQWtCLEdBQTRCLElBQUksQ0FB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LG9CQUFvQjtzQkFBNUIsS0FBSztnQkFHRyx1QkFBdUI7c0JBQS9CLEtBQUs7Z0JBR0ksMkJBQTJCO3NCQUFwQyxNQUFNO2dCQUdHLDZCQUE2QjtzQkFBdEMsTUFBTTtnQkFHRyxrQkFBa0I7c0JBQTNCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBBcHBsaWNhdGlvblJlZixcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFbWJlZGRlZFZpZXdSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQge1xuICB0eXBlIENlcmlvdXNTY3JvbGxPcHRpb25zLFxuICB0eXBlIEVsZW1lbnRSZW5kZXJlcixcbiAgdHlwZSBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UsXG59IGZyb20gJ0BjZXJpb3VzZGV2dGVjaC9jZXJpb3VzLXNjcm9sbCc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHR5cGUgeyBDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWwgfSBmcm9tICcuL2NlcmlvdXMtc2Nyb2xsLnR5cGVzJztcbmltcG9ydCB0eXBlIHsgQ2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQgfSBmcm9tICcuL2NlcmlvdXMtc2Nyb2xsLWl0ZW0tdGVtcGxhdGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IHR5cGUgQ2VyaW91c1Njcm9sbEhvc3RSZWYsIENlcmlvdXNTY3JvbGxTZXJ2aWNlIH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC5zZXJ2aWNlJztcblxuZnVuY3Rpb24gY29lcmNlVG90YWxFbGVtZW50cyhleHBsaWNpdFRvdGFsOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkLCBpdGVtc0xlbjogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCk6IG51bWJlciB7XG4gIGNvbnN0IGNhbmRpZGF0ZSA9IHR5cGVvZiBleHBsaWNpdFRvdGFsID09PSAnbnVtYmVyJyA/IGV4cGxpY2l0VG90YWwgOiB0eXBlb2YgaXRlbXNMZW4gPT09ICdudW1iZXInID8gaXRlbXNMZW4gOiB1bmRlZmluZWQ7XG4gIGlmIChjYW5kaWRhdGUgPT09IHVuZGVmaW5lZCB8fCBOdW1iZXIuaXNOYU4oY2FuZGlkYXRlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2VyaW91c1Njcm9sbERpcmVjdGl2ZTogcHJvdmlkZSBgY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHNgIG9yIGBjZXJpb3VzU2Nyb2xsSXRlbXNgLicpO1xuICB9XG4gIC8vIENlcmlvdXNTY3JvbGwgY3VycmVudGx5IHJlcXVpcmVzID49IDFcbiAgcmV0dXJuIE1hdGgubWF4KDEsIGNhbmRpZGF0ZSk7XG59XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tjZXJpb3VzU2Nyb2xsXScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIENlcmlvdXNTY3JvbGxEaXJlY3RpdmU8VEl0ZW0gPSB1bmtub3duPiBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgLyoqIFRvdGFsIG51bWJlciBvZiBpdGVtcy4gSWYgb21pdHRlZCwgZGVyaXZlZCBmcm9tIGBjZXJpb3VzU2Nyb2xsSXRlbXMubGVuZ3RoYC4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHM6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBPcHRpb25hbCBpdGVtcyBhcnJheSAoZW5hYmxlcyBgbGV0LWl0ZW1gKS4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEl0ZW1zOiByZWFkb25seSBUSXRlbVtdIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIE9wdGlvbmFsIGdldHRlciBmb3IgbGFyZ2UgZGF0YXNldHMgKGFsdGVybmF0aXZlIHRvIHBhc3NpbmcgZnVsbCBgaXRlbXNgKS4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEdldEl0ZW06ICgoaW5kZXg6IG51bWJlcikgPT4gVEl0ZW0pIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIFRlbXBsYXRlIHVzZWQgdG8gcmVuZGVyIGVhY2ggcm93LiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dDxUSXRlbT4+IHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIE9wdGlvbnMgcGFzc2VkIHRvIGBuZXcgQ2VyaW91c1Njcm9sbCguLi4pYC4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbE9wdGlvbnM6IENlcmlvdXNTY3JvbGxPcHRpb25zID0ge307XG5cbiAgLyoqIEF1dG9tYXRpY2FsbHkgY2FsbCByZW5kZXIgYWZ0ZXIgZWFjaCBzY3JvbGwgZXZlbnQuIERlZmF1bHQ6IHRydWUgKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEF1dG9SZW5kZXIgPSB0cnVlO1xuXG4gIC8qKiBFbWl0cyBgY2VyaW91cy12aWV3cG9ydC1jaGFuZ2VgIGRldGFpbC4gKi9cbiAgQE91dHB1dCgpIGNlcmlvdXNTY3JvbGxWaWV3cG9ydENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2VyaW91c1ZpZXdwb3J0Q2hhbmdlRGV0YWlsPigpO1xuXG4gIC8qKiBFbWl0cyB0aGUgbGFzdCBtZWFzdXJlZCB2aWV3cG9ydCBhZnRlciBlYWNoIHJlbmRlciBwYXNzLiAqL1xuICBAT3V0cHV0KCkgY2VyaW91c1Njcm9sbE1lYXN1cmVkVmlld3BvcnQgPSBuZXcgRXZlbnRFbWl0dGVyPE1lYXN1cmVkVmlld3BvcnRSYW5nZT4oKTtcblxuICAvKiogRW1pdHMgb25jZSB0aGUgdW5kZXJseWluZyBgQ2VyaW91c1Njcm9sbGAgaW5zdGFuY2UgaXMgcmVhZHkuICovXG4gIEBPdXRwdXQoKSBjZXJpb3VzU2Nyb2xsUmVhZHkgPSBuZXcgRXZlbnRFbWl0dGVyPENlcmlvdXNTY3JvbGxIb3N0UmVmWydzY3JvbGxlciddPigpO1xuXG4gIHByaXZhdGUgaG9zdFJlZjogQ2VyaW91c1Njcm9sbEhvc3RSZWYgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB2aWV3cG9ydFN1YjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB2aWV3QnlDb250YWluZXIgPSBuZXcgTWFwPEhUTUxFbGVtZW50LCBFbWJlZGRlZFZpZXdSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+Pj4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhvc3Q6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXBwUmVmOiBBcHBsaWNhdGlvblJlZixcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2VyaW91czogQ2VyaW91c1Njcm9sbFNlcnZpY2VcbiAgKSB7fVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybjtcblxuICAgIGlmIChjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsSXRlbXMnXSB8fCBjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50cyddKSB7XG4gICAgICBjb25zdCB0b3RhbCA9IGNvZXJjZVRvdGFsRWxlbWVudHModGhpcy5jZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50cywgdGhpcy5jZXJpb3VzU2Nyb2xsSXRlbXM/Lmxlbmd0aCA/PyBudWxsKTtcbiAgICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci50b3RhbEVsZW1lbnRzID0gdG90YWw7XG4gICAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuY2xlYXJBbGxDYWNoZXMoKTtcbiAgICAgIGlmICh0aGlzLmNlcmlvdXNTY3JvbGxBdXRvUmVuZGVyKSB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddICYmICFjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddLmZpcnN0Q2hhbmdlKSB7XG4gICAgICAvLyBPcHRpb25zIGFyZSBjb25zdW1lZCBwcmltYXJpbHkgYXQgY29uc3RydWN0aW9uIHRpbWUuXG4gICAgICB0aGlzLnJlY3JlYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy52aWV3cG9ydFN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLnZpZXdwb3J0U3ViID0gbnVsbDtcblxuICAgIHRoaXMuZGVzdHJveUFsbFZpZXdzKCk7XG5cbiAgICB0aGlzLmhvc3RSZWY/LmRlc3Ryb3koKTtcbiAgICB0aGlzLmhvc3RSZWYgPSBudWxsO1xuICB9XG5cbiAgLyoqIEltcGVyYXRpdmVseSB0cmlnZ2VyIGEgcmVuZGVyIHBhc3MgKHVzZXMgYGNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVgKS4gKi9cbiAgcmVuZGVyKCk6IE1lYXN1cmVkVmlld3BvcnRSYW5nZSB8IG51bGwge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZTtcbiAgICBpZiAoIXRlbXBsYXRlKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IGhvc3RDb250YWluZXIgPSB0aGlzLmhvc3QubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBoZWlnaHQgPSBob3N0Q29udGFpbmVyLmNsaWVudEhlaWdodCB8fCBob3N0Q29udGFpbmVyLm9mZnNldEhlaWdodDtcbiAgICBjb25zdCBjb250ZW50Q29udGFpbmVyID0gdGhpcy5ob3N0UmVmLmNvbnRlbnRFbGVtZW50O1xuXG4gICAgY29uc3QgcmVuZGVyZXI6IEVsZW1lbnRSZW5kZXJlciA9IChpbmRleCwgZWxlbWVudENvbnRhaW5lcikgPT4ge1xuICAgICAgLy8gUmVuZGVyaW5nIG11c3QgY3JlYXRlIEFuZ3VsYXIgdmlld3MgaW5zaWRlIHRoZSBBbmd1bGFyIHpvbmUuXG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlclRlbXBsYXRlSW50b0NvbnRhaW5lcih0ZW1wbGF0ZSwgaW5kZXgsIGVsZW1lbnRDb250YWluZXIpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGNvbnN0IHJhbmdlID0gdGhpcy5ob3N0UmVmLnNjcm9sbGVyLnJlbmRlclZpZXdwb3J0KGhlaWdodCwgY29udGVudENvbnRhaW5lciwgcmVuZGVyZXIpO1xuICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLmNlcmlvdXNTY3JvbGxNZWFzdXJlZFZpZXdwb3J0LmVtaXQocmFuZ2UpKTtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cblxuICBwcml2YXRlIHJlY3JlYXRlKCk6IHZvaWQge1xuICAgIHRoaXMudmlld3BvcnRTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy52aWV3cG9ydFN1YiA9IG51bGw7XG5cbiAgICB0aGlzLmRlc3Ryb3lBbGxWaWV3cygpO1xuXG4gICAgdGhpcy5ob3N0UmVmPy5kZXN0cm95KCk7XG4gICAgdGhpcy5ob3N0UmVmID0gbnVsbDtcblxuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgZW5zdXJlSW5pdGlhbGl6ZWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaG9zdFJlZikgcmV0dXJuO1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgdG90YWwgPSBjb2VyY2VUb3RhbEVsZW1lbnRzKHRoaXMuY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHMsIHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1zPy5sZW5ndGggPz8gbnVsbCk7XG5cbiAgICB0aGlzLmhvc3RSZWYgPSB0aGlzLmNlcmlvdXMuY3JlYXRlSG9zdChjb250YWluZXIsIHRvdGFsLCB0aGlzLmNlcmlvdXNTY3JvbGxPcHRpb25zLCB0aGlzLm5nWm9uZSwgKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuY2VyaW91c1Njcm9sbEF1dG9SZW5kZXIpIHRoaXMucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnZpZXdwb3J0U3ViID0gdGhpcy5ob3N0UmVmLnZpZXdwb3J0Q2hhbmdlcyQuc3Vic2NyaWJlKChkZXRhaWw6IENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbCkgPT4ge1xuICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlLmVtaXQoZGV0YWlsKSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNlcmlvdXNTY3JvbGxSZWFkeS5lbWl0KHRoaXMuaG9zdFJlZi5zY3JvbGxlcik7XG5cbiAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5yZW5kZXIoKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRJdGVtRm9ySW5kZXgoaW5kZXg6IG51bWJlcik6IFRJdGVtIHtcbiAgICBjb25zdCBnZXR0ZXIgPSB0aGlzLmNlcmlvdXNTY3JvbGxHZXRJdGVtO1xuICAgIGlmIChnZXR0ZXIpIHJldHVybiBnZXR0ZXIoaW5kZXgpO1xuXG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtcztcbiAgICBpZiAoIWl0ZW1zKSByZXR1cm4gdW5kZWZpbmVkIGFzIFRJdGVtO1xuXG4gICAgcmV0dXJuIGl0ZW1zW2luZGV4XTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyKFxuICAgIHRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dDxUSXRlbT4+LFxuICAgIGluZGV4OiBudW1iZXIsXG4gICAgZWxlbWVudENvbnRhaW5lcjogSFRNTEVsZW1lbnRcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgcHJldmlvdXMgPSB0aGlzLnZpZXdCeUNvbnRhaW5lci5nZXQoZWxlbWVudENvbnRhaW5lcik7XG4gICAgaWYgKHByZXZpb3VzKSB7XG4gICAgICB0aGlzLmFwcFJlZi5kZXRhY2hWaWV3KHByZXZpb3VzKTtcbiAgICAgIHByZXZpb3VzLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMudmlld0J5Q29udGFpbmVyLmRlbGV0ZShlbGVtZW50Q29udGFpbmVyKTtcbiAgICB9XG5cbiAgICAvLyBDbGVhciBwcmlvciBET00gKENlcmlvdXNTY3JvbGwgbWF5IHJlY3ljbGUgY29udGFpbmVycykuXG4gICAgZWxlbWVudENvbnRhaW5lci50ZXh0Q29udGVudCA9ICcnO1xuXG4gICAgY29uc3QgaXRlbSA9IHRoaXMuZ2V0SXRlbUZvckluZGV4KGluZGV4KTtcbiAgICBjb25zdCB2aWV3ID0gdGVtcGxhdGUuY3JlYXRlRW1iZWRkZWRWaWV3KHsgJGltcGxpY2l0OiBpdGVtLCBpdGVtLCBpbmRleCB9KTtcbiAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHZpZXcpO1xuICAgIHZpZXcuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIHZpZXcucm9vdE5vZGVzKSB7XG4gICAgICBlbGVtZW50Q29udGFpbmVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIH1cblxuICAgIHRoaXMudmlld0J5Q29udGFpbmVyLnNldChlbGVtZW50Q29udGFpbmVyLCB2aWV3KTtcbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveUFsbFZpZXdzKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgdmlldyBvZiB0aGlzLnZpZXdCeUNvbnRhaW5lci52YWx1ZXMoKSkge1xuICAgICAgdGhpcy5hcHBSZWYuZGV0YWNoVmlldyh2aWV3KTtcbiAgICAgIHZpZXcuZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5jbGVhcigpO1xuICB9XG59XG4iXX0=
|
|
385
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNlcmlvdXMtc2Nyb2xsL3NyYy9saWIvY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFHTCxTQUFTLEVBR1QsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEdBR1AsTUFBTSxlQUFlLENBQUM7OztBQWF2QixTQUFTLG1CQUFtQixDQUFDLGFBQXdDLEVBQUUsUUFBbUM7SUFDeEcsTUFBTSxTQUFTLEdBQUcsT0FBTyxhQUFhLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDMUgsSUFBSSxTQUFTLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUN2RCxNQUFNLElBQUksS0FBSyxDQUFDLHVGQUF1RixDQUFDLENBQUM7SUFDM0csQ0FBQztJQUNELHdDQUF3QztJQUN4QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFNRCxNQUFNLE9BQU8sc0JBQXNCO0lBdUNqQyxZQUNtQixJQUE2QixFQUM3QixNQUFzQixFQUN0QixNQUFjLEVBQ2QsT0FBNkI7UUFIN0IsU0FBSSxHQUFKLElBQUksQ0FBeUI7UUFDN0IsV0FBTSxHQUFOLE1BQU0sQ0FBZ0I7UUFDdEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQXNCO1FBMUNoRCxtRkFBbUY7UUFDMUUsK0JBQTBCLEdBQWtCLElBQUksQ0FBQztRQUUxRCxpREFBaUQ7UUFDeEMsdUJBQWtCLEdBQTRCLElBQUksQ0FB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UyxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDN0IsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUM7UUFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDNUIsQ0FBQzsrR0FsWVUsc0JBQXNCO21HQUF0QixzQkFBc0I7OzRGQUF0QixzQkFBc0I7a0JBSmxDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGlCQUFpQjtvQkFDM0IsVUFBVSxFQUFFLElBQUk7aUJBQ2pCO29LQUdVLDBCQUEwQjtzQkFBbEMsS0FBSztnQkFHRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBR0csb0JBQW9CO3NCQUE1QixLQUFLO2dCQUdHLHlCQUF5QjtzQkFBakMsS0FBSztnQkFHRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBR0csdUJBQXVCO3NCQUEvQixLQUFLO2dCQUdJLDJCQUEyQjtzQkFBcEMsTUFBTTtnQkFHRyw2QkFBNkI7c0JBQXRDLE1BQU07Z0JBR0csa0JBQWtCO3NCQUEzQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQXBwbGljYXRpb25SZWYsXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRW1iZWRkZWRWaWV3UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtcbiAgdHlwZSBDZXJpb3VzU2Nyb2xsT3B0aW9ucyxcbiAgdHlwZSBFbGVtZW50UmVuZGVyZXIsXG4gIHR5cGUgTWVhc3VyZWRWaWV3cG9ydFJhbmdlLFxufSBmcm9tICdAY2VyaW91c2RldnRlY2gvY2VyaW91cy1zY3JvbGwnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB0eXBlIHsgQ2VyaW91c1ZpZXdwb3J0Q2hhbmdlRGV0YWlsIH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC50eXBlcyc7XG5pbXBvcnQgdHlwZSB7IENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0IH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC1pdGVtLXRlbXBsYXRlLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyB0eXBlIENlcmlvdXNTY3JvbGxIb3N0UmVmLCBDZXJpb3VzU2Nyb2xsU2VydmljZSB9IGZyb20gJy4vY2VyaW91cy1zY3JvbGwuc2VydmljZSc7XG5cbmZ1bmN0aW9uIGNvZXJjZVRvdGFsRWxlbWVudHMoZXhwbGljaXRUb3RhbDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCwgaXRlbXNMZW46IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQpOiBudW1iZXIge1xuICBjb25zdCBjYW5kaWRhdGUgPSB0eXBlb2YgZXhwbGljaXRUb3RhbCA9PT0gJ251bWJlcicgPyBleHBsaWNpdFRvdGFsIDogdHlwZW9mIGl0ZW1zTGVuID09PSAnbnVtYmVyJyA/IGl0ZW1zTGVuIDogdW5kZWZpbmVkO1xuICBpZiAoY2FuZGlkYXRlID09PSB1bmRlZmluZWQgfHwgTnVtYmVyLmlzTmFOKGNhbmRpZGF0ZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NlcmlvdXNTY3JvbGxEaXJlY3RpdmU6IHByb3ZpZGUgYGNlcmlvdXNTY3JvbGxUb3RhbEVsZW1lbnRzYCBvciBgY2VyaW91c1Njcm9sbEl0ZW1zYC4nKTtcbiAgfVxuICAvLyBDZXJpb3VzU2Nyb2xsIGN1cnJlbnRseSByZXF1aXJlcyA+PSAxXG4gIHJldHVybiBNYXRoLm1heCgxLCBjYW5kaWRhdGUpO1xufVxuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbY2VyaW91c1Njcm9sbF0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBDZXJpb3VzU2Nyb2xsRGlyZWN0aXZlPFRJdGVtID0gdW5rbm93bj4gaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIC8qKiBUb3RhbCBudW1iZXIgb2YgaXRlbXMuIElmIG9taXR0ZWQsIGRlcml2ZWQgZnJvbSBgY2VyaW91c1Njcm9sbEl0ZW1zLmxlbmd0aGAuICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxUb3RhbEVsZW1lbnRzOiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICAvKiogT3B0aW9uYWwgaXRlbXMgYXJyYXkgKGVuYWJsZXMgYGxldC1pdGVtYCkuICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxJdGVtczogcmVhZG9ubHkgVEl0ZW1bXSB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBPcHRpb25hbCBnZXR0ZXIgZm9yIGxhcmdlIGRhdGFzZXRzIChhbHRlcm5hdGl2ZSB0byBwYXNzaW5nIGZ1bGwgYGl0ZW1zYCkuICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxHZXRJdGVtOiAoKGluZGV4OiBudW1iZXIpID0+IFRJdGVtKSB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBUZW1wbGF0ZSB1c2VkIHRvIHJlbmRlciBlYWNoIHJvdy4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZTogVGVtcGxhdGVSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+PiB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBPcHRpb25zIHBhc3NlZCB0byBgbmV3IENlcmlvdXNTY3JvbGwoLi4uKWAuICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxPcHRpb25zOiBDZXJpb3VzU2Nyb2xsT3B0aW9ucyA9IHt9O1xuXG4gIC8qKiBBdXRvbWF0aWNhbGx5IGNhbGwgcmVuZGVyIGFmdGVyIGVhY2ggc2Nyb2xsIGV2ZW50LiBEZWZhdWx0OiB0cnVlICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxBdXRvUmVuZGVyID0gdHJ1ZTtcblxuICAvKiogRW1pdHMgYGNlcmlvdXMtdmlld3BvcnQtY2hhbmdlYCBkZXRhaWwuICovXG4gIEBPdXRwdXQoKSBjZXJpb3VzU2Nyb2xsVmlld3BvcnRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbD4oKTtcblxuICAvKiogRW1pdHMgdGhlIGxhc3QgbWVhc3VyZWQgdmlld3BvcnQgYWZ0ZXIgZWFjaCByZW5kZXIgcGFzcy4gKi9cbiAgQE91dHB1dCgpIGNlcmlvdXNTY3JvbGxNZWFzdXJlZFZpZXdwb3J0ID0gbmV3IEV2ZW50RW1pdHRlcjxNZWFzdXJlZFZpZXdwb3J0UmFuZ2U+KCk7XG5cbiAgLyoqIEVtaXRzIG9uY2UgdGhlIHVuZGVybHlpbmcgYENlcmlvdXNTY3JvbGxgIGluc3RhbmNlIGlzIHJlYWR5LiAqL1xuICBAT3V0cHV0KCkgY2VyaW91c1Njcm9sbFJlYWR5ID0gbmV3IEV2ZW50RW1pdHRlcjxDZXJpb3VzU2Nyb2xsSG9zdFJlZlsnc2Nyb2xsZXInXT4oKTtcblxuICBwcml2YXRlIGhvc3RSZWY6IENlcmlvdXNTY3JvbGxIb3N0UmVmIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdmlld3BvcnRTdWI6IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHNjaGVkdWxlZFJlbmRlckZyYW1lOiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHJlYWRvbmx5IHZpZXdCeUNvbnRhaW5lciA9IG5ldyBNYXA8SFRNTEVsZW1lbnQsIEVtYmVkZGVkVmlld1JlZjxDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dDxUSXRlbT4+PigpO1xuICAvLyBQb29sIG9mIHZpZXdzIGRldGFjaGVkIGJlY2F1c2UgdGhlaXIgY29udGFpbmVyIGxlZnQgdGhlIHZpZXdwb3J0LiBSZXVzaW5nXG4gIC8vIHRoZW0gb24gc3Vic2VxdWVudCByZW5kZXJzIGF2b2lkcyBkZXN0cm95aW5nICsgcmVjcmVhdGluZyB0aGUgZW50aXJlIHJvd1xuICAvLyBjb21wb25lbnQgdHJlZSBvbiBmYXN0IHNjcm9sbHMgKHdoZXJlIHRoZSBlbmdpbmUncyBlbGVtZW50IHBvb2wgd2lwZXNcbiAgLy8gdGV4dENvbnRlbnQgb24gcmV1c2VkIGNvbnRhaW5lcnMsIHNvIHZpZXcgcm9vdE5vZGVzIGdldCBvcnBoYW5lZCkuXG4gIHByaXZhdGUgcmVhZG9ubHkgZnJlZVZpZXdzOiBFbWJlZGRlZFZpZXdSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+PltdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGFwcFJlZjogQXBwbGljYXRpb25SZWYsXG4gICAgcHJpdmF0ZSByZWFkb25seSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNlcmlvdXM6IENlcmlvdXNTY3JvbGxTZXJ2aWNlXG4gICkge31cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm47XG5cbiAgICBpZiAoY2hhbmdlc1snY2VyaW91c1Njcm9sbEl0ZW1zJ10gfHwgY2hhbmdlc1snY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHMnXSkge1xuICAgICAgY29uc3QgdG90YWwgPSBjb2VyY2VUb3RhbEVsZW1lbnRzKHRoaXMuY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHMsIHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1zPy5sZW5ndGggPz8gbnVsbCk7XG4gICAgICBjb25zdCBjb3VudENoYW5nZWQgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIudG90YWxFbGVtZW50cyAhPT0gdG90YWw7XG5cbiAgICAgIGlmIChjb3VudENoYW5nZWQpIHtcbiAgICAgICAgLy8gVGhlIGRhdGFzZXQgc2l6ZSBjaGFuZ2VkOiB0aGUgVmlld3BvcnRSZW5kZXJlciBzdG9yZXMgaXRzIG93biBjb3B5IG9mXG4gICAgICAgIC8vIHRvdGFsRWxlbWVudHMgKHNldCBieSB2YWx1ZSBhdCBjb25zdHJ1Y3Rpb24pIHNvIHBhdGNoaW5nIHRoZSBlbmdpbmUnc1xuICAgICAgICAvLyBwdWJsaWMgcHJvcGVydHkgYWxvbmUgbGVhdmVzIHRoZSByZW5kZXJlcidzIGludGVybmFsIGJvdW5kIHN0YWxlLiAgVGhlXG4gICAgICAgIC8vIHJlbmRlcmVyIHdvdWxkIHRoZW4gdXNlIHRoZSBvbGQgY291bnQgZm9yIGl0cyB2aWV3cG9ydC1maWxsIGxvb3AgYW5kXG4gICAgICAgIC8vIGJvdHRvbS1ib3VuZGFyeSBzY2FuLCBwcm9kdWNpbmcgcGhhbnRvbSByZW5kZXJzIGF0IG91dC1vZi1ib3VuZHNcbiAgICAgICAgLy8gaW5kaWNlcyAodW5kZWZpbmVkIGl0ZW1zIOKGkiAwLWhlaWdodCByb3dzIOKGkiB0aGUgZmlsbCBsb29wIG5ldmVyXG4gICAgICAgIC8vIHNhdGlzZmllcyBpdHMgaGVpZ2h0IGNvbmRpdGlvbiDihpIgaHVuZHJlZHMgb2YgcmVuZGVyZXIgY2FsbGJhY2tzKS5cbiAgICAgICAgLy8gUmVjcmVhdGluZyB0aGUgZW5naW5lIGdpdmVzIGJvdGggdGhlIGVuZ2luZSBhbmQgdGhlIHJlbmRlcmVyIGEgZnJlc2gsXG4gICAgICAgIC8vIGNvbnNpc3RlbnQgY291bnQuICBlbnN1cmVJbml0aWFsaXplZCgpIHNjaGVkdWxlcyB0aGUgZmlyc3QgcmVuZGVyIHZpYVxuICAgICAgICAvLyBxdWV1ZU1pY3JvdGFzaywgd2hpY2ggcnVucyBhZnRlciB0aGUgY3VycmVudCBDRCBjeWNsZSBjb21wbGV0ZXMuXG4gICAgICAgIHRoaXMucmVjcmVhdGUoKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgICAvLyBTYW1lIGNvdW50LCBuZXcgZGF0YSByZWZlcmVuY2UgKGUuZy4gYW4gaW1tdXRhYmxlIGVkaXQgb3IgYSBzb3J0IHRoYXRcbiAgICAgICAgLy8gaGFwcGVucyB0byBrZWVwIHRoZSBzYW1lIGxlbmd0aCkuIFRoZSBlbmdpbmUgcmV1c2VzIHRoZSBET00gZWxlbWVudCBpdFxuICAgICAgICAvLyBhbHJlYWR5IHJlbmRlcmVkIGZvciBlYWNoIG92ZXJsYXBwaW5nIGluZGV4IHdpdGhvdXQgcmUtaW52b2tpbmcgdGhlXG4gICAgICAgIC8vIHJlbmRlcmVyLCBzbyB1cGRhdGUgdGhlIGNvbnRlbnQgb2YgZXZlcnkgY3VycmVudGx5LXZpc2libGUgcm93IElOXG4gICAgICAgIC8vIFBMQUNFIGJlZm9yZSBjYWxsaW5nIHJlbmRlcigpLiAgVGhpcyBwcmVzZXJ2ZXMgZWFjaCByb3cncyBlbWJlZGRlZFxuICAgICAgICAvLyB2aWV3IChzbyBhIGZvY3VzZWQgdGV4dGJveCBrZWVwcyBmb2N1cy9jYXJldCkgYW5kIGRvZXMgTk9UIGRpc2NhcmRcbiAgICAgICAgLy8gY2FjaGVkIGhlaWdodHMuIElmIGEgcm93J3MgaGVpZ2h0IGFjdHVhbGx5IGNoYW5nZXMgdGhlIGVuZ2luZSdzXG4gICAgICAgIC8vIFJlc2l6ZU9ic2VydmVyIGtlZXBzIHRoZSBjYWNoZSBjb3JyZWN0IG9uIGl0cyBvd247IGZvciBhIHdob2xlc2FsZVxuICAgICAgICAvLyBoZWlnaHQgY2hhbmdlIGFjcm9zcyBhbGwgcm93cywgY2FsbCByZWNhbGN1bGF0ZSgpIGluc3RlYWQuXG4gICAgICAgIHRoaXMucmVmcmVzaFJlbmRlcmVkQ29udGVudCgpO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddICYmICFjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddLmZpcnN0Q2hhbmdlKSB7XG4gICAgICAvLyBPcHRpb25zIGFyZSBjb25zdW1lZCBwcmltYXJpbHkgYXQgY29uc3RydWN0aW9uIHRpbWUuXG4gICAgICB0aGlzLnJlY3JlYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgIT0gbnVsbCkge1xuICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5zY2hlZHVsZWRSZW5kZXJGcmFtZSk7XG4gICAgICB0aGlzLnNjaGVkdWxlZFJlbmRlckZyYW1lID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLnZpZXdwb3J0U3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMudmlld3BvcnRTdWIgPSBudWxsO1xuXG4gICAgdGhpcy5kZXN0cm95QWxsVmlld3MoKTtcblxuICAgIHRoaXMuaG9zdFJlZj8uZGVzdHJveSgpO1xuICAgIHRoaXMuaG9zdFJlZiA9IG51bGw7XG4gIH1cblxuICAvKiogSW1wZXJhdGl2ZWx5IHRyaWdnZXIgYSByZW5kZXIgcGFzcyAodXNlcyBgY2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZWApLiAqL1xuICByZW5kZXIoKTogTWVhc3VyZWRWaWV3cG9ydFJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHRlbXBsYXRlID0gdGhpcy5jZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlO1xuICAgIGlmICghdGVtcGxhdGUpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgaG9zdENvbnRhaW5lciA9IHRoaXMuaG9zdC5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IGhlaWdodCA9IGhvc3RDb250YWluZXIuY2xpZW50SGVpZ2h0IHx8IGhvc3RDb250YWluZXIub2Zmc2V0SGVpZ2h0O1xuICAgIGNvbnN0IGNvbnRlbnRDb250YWluZXIgPSB0aGlzLmhvc3RSZWYuY29udGVudEVsZW1lbnQ7XG5cbiAgICAvLyBUcmFjayB3aGV0aGVyIHRoZSBlbmdpbmUgYXNrZWQgdXMgdG8gYmluZCBhbnkgcm93IHRoaXMgcGFzcy4gUHVyZSBzY3JvbGxcbiAgICAvLyBmcmFtZXMgd2hlcmUgdGhlIHZpc2libGUgcm93IHNldCBkb2Vzbid0IGNoYW5nZSBzdGlsbCBkcml2ZSByZW5kZXIoKSB2aWFcbiAgICAvLyB0aGUgckFGIGNvYWxlc2NlciDigJQgdGhlcmUncyBubyBwb2ludCBpbiB3YWxraW5nIHRoZSBwcnVuZSBtYXAgb3JcbiAgICAvLyBlbWl0dGluZyB0aGUgdmlld3BvcnQgcmFuZ2Ugd2hlbiBub3RoaW5nIHdhcyB0b3VjaGVkLlxuICAgIGxldCByZW5kZXJlckludm9jYXRpb25zID0gMDtcbiAgICBjb25zdCByZW5kZXJlcjogRWxlbWVudFJlbmRlcmVyID0gKGluZGV4LCBlbGVtZW50Q29udGFpbmVyKSA9PiB7XG4gICAgICByZW5kZXJlckludm9jYXRpb25zKys7XG4gICAgICAvLyBSZW5kZXIgZWFjaCByb3cncyBlbWJlZGRlZCB2aWV3IHdpdGggTE9DQUwgY2hhbmdlIGRldGVjdGlvblxuICAgICAgLy8gKGB2aWV3LmRldGVjdENoYW5nZXMoKWAgaW5zaWRlIGByZW5kZXJUZW1wbGF0ZUludG9Db250YWluZXJgKSBzbyB0aGVcbiAgICAgIC8vIGVuZ2luZSBjYW4gbWVhc3VyZSBpdHMgaGVpZ2h0IGR1cmluZyB0aGlzIHBhc3MuIERvIE5PVCB3cmFwIGVhY2ggcm93IGluXG4gICAgICAvLyBpdHMgb3duIGBuZ1pvbmUucnVuYCDigJQgdGhhdCBmaXJlcyBhIGZ1bGwgYEFwcGxpY2F0aW9uUmVmYCB0aWNrICpwZXIgcm93KlxuICAgICAgLy8gKE8obmV3Um93cyDDlyB2aXNpYmxlUm93cykgd29yaywgamFua3kgZHJhZ3MpLiBUaGUgc2luZ2xlIGNvYWxlc2NlZCB0aWNrXG4gICAgICAvLyBmb3IgdGhlIHdob2xlIHBhc3MgaXMgaGFuZGxlZCBieSB0aGUgY2FsbGVyIChgc2NoZWR1bGVSZW5kZXJgKS5cbiAgICAgIHRoaXMucmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyKHRlbXBsYXRlLCBpbmRleCwgZWxlbWVudENvbnRhaW5lcik7XG4gICAgfTtcblxuICAgIGNvbnN0IHJhbmdlID0gdGhpcy5ob3N0UmVmLnNjcm9sbGVyLnJlbmRlclZpZXdwb3J0KGhlaWdodCwgY29udGVudENvbnRhaW5lciwgcmVuZGVyZXIpO1xuXG4gICAgaWYgKHJlbmRlcmVySW52b2NhdGlvbnMgPT09IDApIHtcbiAgICAgIC8vIFZpZXdwb3J0IGRpZG4ndCBjaGFuZ2Ug4oCUIHNraXAgdGhlIHBydW5lIHdhbGsgYW5kIHRoZSAocG90ZW50aWFsbHlcbiAgICAgIC8vIHpvbmUtZW50ZXJpbmcpIGVtaXQuXG4gICAgICByZXR1cm4gcmFuZ2U7XG4gICAgfVxuXG4gICAgLy8gRGVzdHJveSB2aWV3cyB3aG9zZSBjb250YWluZXIgdGhlIGVuZ2luZSBubyBsb25nZXIgcmVuZGVycy4gV2l0aG91dCB0aGlzLFxuICAgIC8vIGV2ZXJ5IGNvbnRhaW5lciB0aGUgZW5naW5lIHJlY3ljbGVzIGludG8gaXRzIGVsZW1lbnQgcG9vbCBsZWF2ZXMgaXRzXG4gICAgLy8gZW1iZWRkZWQgdmlldyBhdHRhY2hlZCB0byBBcHBsaWNhdGlvblJlZiBmb3JldmVyIOKAlCBzbyB0aGUgYXR0YWNoZWQtdmlld1xuICAgIC8vIGxpc3QgKGFuZCBldmVyeSBPKG4pIGBkZXRhY2hWaWV3YCkgZ3Jvd3Mgd2l0aG91dCBib3VuZCBhbmQgc2Nyb2xsaW5nIGdldHNcbiAgICAvLyBwcm9ncmVzc2l2ZWx5IHNsb3dlci4gTWlycm9ycyB0aGUgUmVhY3QvVnVlIHdyYXBwZXJzLCB3aGljaCBkcm9wIHJvd3MgdGhhdFxuICAgIC8vIGZhbGwgb3V0IG9mIGBnZXRSZW5kZXJlZEluZGljZXMoKWAuXG4gICAgdGhpcy5wcnVuZURldGFjaGVkVmlld3MoKTtcblxuICAgIC8vIE9ubHkgcmUtZW50ZXIgdGhlIHpvbmUgKGEgZ2xvYmFsIHRpY2spIGlmIHNvbWVvbmUgaXMgYWN0dWFsbHkgbGlzdGVuaW5nLlxuICAgIGlmICh0aGlzLmNlcmlvdXNTY3JvbGxNZWFzdXJlZFZpZXdwb3J0Lm9ic2VydmVkKSB7XG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5jZXJpb3VzU2Nyb2xsTWVhc3VyZWRWaWV3cG9ydC5lbWl0KHJhbmdlKSk7XG4gICAgfVxuICAgIHJldHVybiByYW5nZTtcbiAgfVxuXG4gIC8qKiBUZWFyIGRvd24gZW1iZWRkZWQgdmlld3Mgd2hvc2UgY29udGFpbmVyIGlzIG5vIGxvbmdlciBwYXJ0IG9mIHRoZSB2aWV3cG9ydC4gKi9cbiAgcHJpdmF0ZSBwcnVuZURldGFjaGVkVmlld3MoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYgfHwgdGhpcy52aWV3QnlDb250YWluZXIuc2l6ZSA9PT0gMCkgcmV0dXJuO1xuICAgIGNvbnN0IHNjcm9sbGVyID0gdGhpcy5ob3N0UmVmLnNjcm9sbGVyO1xuICAgIGNvbnN0IGFjdGl2ZSA9IG5ldyBTZXQ8SFRNTEVsZW1lbnQ+KCk7XG4gICAgZm9yIChjb25zdCBpbmRleCBvZiBzY3JvbGxlci5nZXRSZW5kZXJlZEluZGljZXMoKSkge1xuICAgICAgY29uc3QgZWwgPSBzY3JvbGxlci5nZXRSZW5kZXJlZEVsZW1lbnQoaW5kZXgpO1xuICAgICAgaWYgKGVsKSBhY3RpdmUuYWRkKGVsKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBbY29udGFpbmVyLCB2aWV3XSBvZiB0aGlzLnZpZXdCeUNvbnRhaW5lcikge1xuICAgICAgaWYgKCFhY3RpdmUuaGFzKGNvbnRhaW5lcikpIHtcbiAgICAgICAgLy8gRGV0YWNoIERPTSBidXQga2VlcCB0aGUgdmlldyBhbGl2ZSBpbiB0aGUgcG9vbCBmb3IgZnV0dXJlIHJldXNlLlxuICAgICAgICAvLyBEZXN0cm95aW5nICsgcmVjcmVhdGluZyB2aWV3cyBwZXIgc2Nyb2xsIHN0ZXAgZG9taW5hdGVzIGZyYW1lIHRpbWUuXG4gICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiB2aWV3LnJvb3ROb2Rlcykge1xuICAgICAgICAgIGlmIChub2RlLnBhcmVudE5vZGUpIG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5kZWxldGUoY29udGFpbmVyKTtcbiAgICAgICAgdGhpcy5mcmVlVmlld3MucHVzaCh2aWV3KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiogQXV0by1yZW5kZXIgY29hbGVzY2VkIHRvIGF0IG1vc3Qgb25jZSBwZXIgYW5pbWF0aW9uIGZyYW1lLiAqL1xuICBwcml2YXRlIHNjaGVkdWxlUmVuZGVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNjaGVkdWxlZFJlbmRlckZyYW1lICE9IG51bGwpIHJldHVybjtcbiAgICB0aGlzLnNjaGVkdWxlZFJlbmRlckZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgPSBudWxsO1xuICAgICAgLy8gUnVuIHJlbmRlcigpIE9VVFNJREUgQW5ndWxhcidzIHpvbmUuIEEgZnVsbCBBcHBsaWNhdGlvblJlZi50aWNrKCkgb25cbiAgICAgIC8vIGV2ZXJ5IHNjcm9sbCBmcmFtZSBpcyB0aGUgcHJpbWFyeSBGUFMgYm90dGxlbmVjazogZXZlbiB3aGVuIG5vIHJvd3NcbiAgICAgIC8vIGNoYW5nZSAocHVyZSB0cmFuc2xhdGlvbiksIG5nWm9uZS5ydW4oKSBjYXVzZXMgQW5ndWxhciB0byB3YWxrIHRoZVxuICAgICAgLy8gZW50aXJlIGNvbXBvbmVudCB0cmVlLiBJbnN0ZWFkIHdlIGNhbGwgdmlldy5kZXRlY3RDaGFuZ2VzKCkgbG9jYWxseVxuICAgICAgLy8gaW5zaWRlIHJlbmRlclRlbXBsYXRlSW50b0NvbnRhaW5lciBmb3IgZWFjaCBhZmZlY3RlZCByb3cuIFpvbmUgZW50cnkgaXNcbiAgICAgIC8vIG9ubHkgbmVlZGVkIHdoZW4gY3JlYXRpbmcgYSBicmFuZC1uZXcgZW1iZWRkZWQgdmlldyAodG8gem9uZS1wYXRjaCBpdHNcbiAgICAgIC8vIGV2ZW50IGxpc3RlbmVycykg4oCUIHJlY3ljbGVkIGFuZCBwb29sZWQgdmlld3Mgd2VyZSBhbHJlYWR5IGNyZWF0ZWQgaW5zaWRlXG4gICAgICAvLyB6b25lIGFuZCB0aGVpciBsaXN0ZW5lcnMgcmVtYWluIHpvbmUtYXdhcmUuXG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc2NhcmQgYWxsIGNhY2hlZCByb3cgaGVpZ2h0cyBhbmQgcmUtbWVhc3VyZSB0aGUgdmlld3BvcnQuXG4gICAqXG4gICAqIENhbGwgdGhpcyBvbmx5IHdoZW4gdGhlIGhlaWdodHMgb2Ygcm93cyB5b3UndmUgKmFscmVhZHkgcmVuZGVyZWQqIG1heSBoYXZlXG4gICAqIGNoYW5nZWQgd2l0aG91dCB0aGVpciBpbmRpY2VzIGNoYW5naW5nIOKAlCBlLmcuIGEgZ2xvYmFsIGZvbnQvZGVuc2l0eSBjaGFuZ2UsXG4gICAqIG9yIHN3YXBwaW5nIGV2ZXJ5IHJvdyB0byBhIGRpZmZlcmVudCBsYXlvdXQuIFRoaXMgZm9yY2VzIGEgc3luY2hyb25vdXNcbiAgICogcmUtbWVhc3VyZSAob25lIGBvZmZzZXRIZWlnaHRgIHJlYWQgcGVyIHZpc2libGUgcm93KSwgc28gZG8gTk9UIGNhbGwgaXQgb25cbiAgICogcm91dGluZSBlZGl0czogYSBzaW5nbGUgY2VsbCBlZGl0IGtlZXBzIGl0cyByb3cncyBzaXplLCBhbmQgdGhlIGVuZ2luZSdzXG4gICAqIFJlc2l6ZU9ic2VydmVyIHBpY2tzIHVwIGFueSBpbmNpZGVudGFsIHJlc2l6ZSBvbiBpdHMgb3duLlxuICAgKi9cbiAgcmVjYWxjdWxhdGUoKTogTWVhc3VyZWRWaWV3cG9ydFJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybiBudWxsO1xuICAgIC8vIERpc2NhcmQgdGhlIGNhY2hlZCBoZWlnaHRzLCB0aGVuIHJlLXJlbmRlci4gVGhlIGVuZ2luZSByZS1tZWFzdXJlcyBhbmRcbiAgICAvLyByZS1jYWNoZXMgdGhlIHJlbmRlcmVkIHJvd3MgZHVyaW5nIHRoZSBwYXNzIGFuZCByZWZyZXNoZXMgdGhlIHNjcm9sbFxuICAgIC8vIHBlcmNlbnRhZ2UsIHNvIGFuIGluLXBsYWNlIGhlaWdodCBjaGFuZ2UgKGUuZy4gZXhwYW5kL2NvbGxhcHNlKSBpc1xuICAgIC8vIHJlZmxlY3RlZCBpbiB0aGUgdG90YWwgY29udGVudCBoZWlnaHQgYW5kIHNjcm9sbGJhciBpbW1lZGlhdGVseS5cbiAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuY2xlYXJBbGxDYWNoZXMoKTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBKdW1wIGRpcmVjdGx5IHRvIGFuIGVsZW1lbnQgaW5kZXgsIHRoZW4gcmVuZGVyLiAqL1xuICBqdW1wVG9FbGVtZW50KGluZGV4OiBudW1iZXIpOiBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZikgcmV0dXJuIG51bGw7XG4gICAgdGhpcy5ob3N0UmVmLnNjcm9sbGVyLmp1bXBUb0VsZW1lbnQoaW5kZXgpO1xuICAgIHJldHVybiB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqIFNjcm9sbCB0byBhIHBlcmNlbnRhZ2UgKDAuLjEwMCksIHRoZW4gcmVuZGVyLiAqL1xuICBzY3JvbGxUb1BlcmNlbnRhZ2UocGVyY2VudGFnZTogbnVtYmVyKTogTWVhc3VyZWRWaWV3cG9ydFJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybiBudWxsO1xuICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci5oYW5kbGVTY3JvbGxQZXJjZW50YWdlKHBlcmNlbnRhZ2UpO1xuICAgIHJldHVybiB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqIFJlc2V0IHRvIHRoZSB0b3AsIHRoZW4gcmVuZGVyLiAqL1xuICByZXNldCgpOiBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZikgcmV0dXJuIG51bGw7XG4gICAgdGhpcy5ob3N0UmVmLnNjcm9sbGVyLnJlc2V0KCk7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBwcml2YXRlIHJlY3JlYXRlKCk6IHZvaWQge1xuICAgIHRoaXMudmlld3BvcnRTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy52aWV3cG9ydFN1YiA9IG51bGw7XG5cbiAgICB0aGlzLmRlc3Ryb3lBbGxWaWV3cygpO1xuXG4gICAgdGhpcy5ob3N0UmVmPy5kZXN0cm95KCk7XG4gICAgdGhpcy5ob3N0UmVmID0gbnVsbDtcblxuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgZW5zdXJlSW5pdGlhbGl6ZWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaG9zdFJlZikgcmV0dXJuO1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgdG90YWwgPSBjb2VyY2VUb3RhbEVsZW1lbnRzKHRoaXMuY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHMsIHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1zPy5sZW5ndGggPz8gbnVsbCk7XG5cbiAgICB0aGlzLmhvc3RSZWYgPSB0aGlzLmNlcmlvdXMuY3JlYXRlSG9zdChjb250YWluZXIsIHRvdGFsLCB0aGlzLmNlcmlvdXNTY3JvbGxPcHRpb25zLCB0aGlzLm5nWm9uZSwgKCkgPT4ge1xuICAgICAgLy8gQ29hbGVzY2Ugc2Nyb2xsLWRyaXZlbiByZW5kZXJzIHRvIG9uZSBwZXIgZnJhbWUgKHRoZSBuYXRpdmUgc2Nyb2xsYmFyXG4gICAgICAvLyBjYW4gZmlyZSBtYW55IHNjcm9sbCBldmVudHMgYmV0d2VlbiBwYWludHMpLlxuICAgICAgaWYgKHRoaXMuY2VyaW91c1Njcm9sbEF1dG9SZW5kZXIpIHRoaXMuc2NoZWR1bGVSZW5kZXIoKTtcbiAgICB9KTtcblxuICAgIHRoaXMudmlld3BvcnRTdWIgPSB0aGlzLmhvc3RSZWYudmlld3BvcnRDaGFuZ2VzJC5zdWJzY3JpYmUoKGRldGFpbDogQ2VyaW91c1ZpZXdwb3J0Q2hhbmdlRGV0YWlsKSA9PiB7XG4gICAgICAvLyBTa2lwIHRoZSBnbG9iYWwgdGljayB3aGVuIG5vYm9keSBpcyBib3VuZCB0byB0aGUgb3V0cHV0LlxuICAgICAgaWYgKHRoaXMuY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlLm9ic2VydmVkKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLmNlcmlvdXNTY3JvbGxWaWV3cG9ydENoYW5nZS5lbWl0KGRldGFpbCkpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5jZXJpb3VzU2Nyb2xsUmVhZHkuZW1pdCh0aGlzLmhvc3RSZWYuc2Nyb2xsZXIpO1xuXG4gICAgaWYgKHRoaXMuY2VyaW91c1Njcm9sbEF1dG9SZW5kZXIpIHtcbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHRoaXMucmVuZGVyKCkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0SXRlbUZvckluZGV4KGluZGV4OiBudW1iZXIpOiBUSXRlbSB7XG4gICAgY29uc3QgZ2V0dGVyID0gdGhpcy5jZXJpb3VzU2Nyb2xsR2V0SXRlbTtcbiAgICBpZiAoZ2V0dGVyKSByZXR1cm4gZ2V0dGVyKGluZGV4KTtcblxuICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5jZXJpb3VzU2Nyb2xsSXRlbXM7XG4gICAgaWYgKCFpdGVtcykgcmV0dXJuIHVuZGVmaW5lZCBhcyBUSXRlbTtcblxuICAgIHJldHVybiBpdGVtc1tpbmRleF07XG4gIH1cblxuICBwcml2YXRlIHJlbmRlclRlbXBsYXRlSW50b0NvbnRhaW5lcihcbiAgICB0ZW1wbGF0ZTogVGVtcGxhdGVSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+PixcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIGVsZW1lbnRDb250YWluZXI6IEhUTUxFbGVtZW50XG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHByZXZpb3VzID0gdGhpcy52aWV3QnlDb250YWluZXIuZ2V0KGVsZW1lbnRDb250YWluZXIpO1xuICAgIGlmIChwcmV2aW91cykge1xuICAgICAgLy8gUmVjeWNsZTogdXBkYXRlIHRoZSBib3VuZCBjb250ZXh0IGFuZCBydW4gbG9jYWwgQ0QgaW5zdGVhZCBvZlxuICAgICAgLy8gZGVzdHJveWluZyB0aGUgZW1iZWRkZWQgdmlldyBhbmQgcmVidWlsZGluZyB0aGUgZW50aXJlIHJvdyB0cmVlLlxuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuZ2V0SXRlbUZvckluZGV4KGluZGV4KTtcbiAgICAgIHByZXZpb3VzLmNvbnRleHQuJGltcGxpY2l0ID0gaXRlbTtcbiAgICAgIHByZXZpb3VzLmNvbnRleHQuaXRlbSA9IGl0ZW07XG4gICAgICBwcmV2aW91cy5jb250ZXh0LmluZGV4ID0gaW5kZXg7XG4gICAgICAvLyBUaGUgY29yZSBlbmdpbmUgd2lwZXMgZWxlbWVudENvbnRhaW5lci50ZXh0Q29udGVudCB3aGVuIHJldXNpbmcgaXQgZnJvbVxuICAgICAgLy8gaXRzIHBvb2wsIG9ycGhhbmluZyB0aGUgdmlldydzIHJvb3Qgbm9kZXMuIFJlLWFwcGVuZCB0aGVtIGRlZmVuc2l2ZWx5LlxuICAgICAgaWYgKHByZXZpb3VzLnJvb3ROb2Rlcy5sZW5ndGggJiYgcHJldmlvdXMucm9vdE5vZGVzWzBdLnBhcmVudE5vZGUgIT09IGVsZW1lbnRDb250YWluZXIpIHtcbiAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIHByZXZpb3VzLnJvb3ROb2Rlcykge1xuICAgICAgICAgIGVsZW1lbnRDb250YWluZXIuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHByZXZpb3VzLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUcnkgdG8gcmV1c2UgYSBwb29sZWQgdmlldyBmcm9tIGEgY29udGFpbmVyIHRoYXQgc2Nyb2xsZWQgb3V0IG9mIHZpZXdwb3J0LlxuICAgIGNvbnN0IHBvb2xlZCA9IHRoaXMuZnJlZVZpZXdzLnBvcCgpO1xuICAgIGlmIChwb29sZWQpIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmdldEl0ZW1Gb3JJbmRleChpbmRleCk7XG4gICAgICBwb29sZWQuY29udGV4dC4kaW1wbGljaXQgPSBpdGVtO1xuICAgICAgcG9vbGVkLmNvbnRleHQuaXRlbSA9IGl0ZW07XG4gICAgICBwb29sZWQuY29udGV4dC5pbmRleCA9IGluZGV4O1xuICAgICAgZWxlbWVudENvbnRhaW5lci50ZXh0Q29udGVudCA9ICcnO1xuICAgICAgZm9yIChjb25zdCBub2RlIG9mIHBvb2xlZC5yb290Tm9kZXMpIHtcbiAgICAgICAgZWxlbWVudENvbnRhaW5lci5hcHBlbmRDaGlsZChub2RlKTtcbiAgICAgIH1cbiAgICAgIHBvb2xlZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5zZXQoZWxlbWVudENvbnRhaW5lciwgcG9vbGVkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBObyBwcmlvciB2aWV3IGZvciB0aGlzIGNvbnRhaW5lcjogY3JlYXRlIG9uZS5cbiAgICAvLyBFbnRlciB0aGUgQW5ndWxhciB6b25lIHNvIHRoZSBuZXcgdmlldydzIHRlbXBsYXRlIGV2ZW50IGxpc3RlbmVyc1xuICAgIC8vICgoY2xpY2spLCAoaW5wdXQpLCBldGMuKSBhcmUgem9uZS1wYXRjaGVkLiBUaGlzIHBhdGggcnVucyBhdCBtb3N0XG4gICAgLy8gb25jZSBwZXIgdmlzaWJsZSByb3cgKGFmdGVyIHRoYXQsIHRoZSB2aWV3IGlzIHJlY3ljbGVkIGZyb20gdGhlIHBvb2wpLlxuICAgIGVsZW1lbnRDb250YWluZXIudGV4dENvbnRlbnQgPSAnJztcblxuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmdldEl0ZW1Gb3JJbmRleChpbmRleCk7XG4gICAgY29uc3QgdmlldyA9IHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICBjb25zdCB2ID0gdGVtcGxhdGUuY3JlYXRlRW1iZWRkZWRWaWV3KHsgJGltcGxpY2l0OiBpdGVtLCBpdGVtLCBpbmRleCB9KTtcbiAgICAgIHRoaXMuYXBwUmVmLmF0dGFjaFZpZXcodik7XG4gICAgICB2LmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHJldHVybiB2O1xuICAgIH0pO1xuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIHZpZXcucm9vdE5vZGVzKSB7XG4gICAgICBlbGVtZW50Q29udGFpbmVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIH1cblxuICAgIHRoaXMudmlld0J5Q29udGFpbmVyLnNldChlbGVtZW50Q29udGFpbmVyLCB2aWV3KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIGJvdW5kIGl0ZW0vaW5kZXggb24gZXZlcnkgY3VycmVudGx5LXJlbmRlcmVkIHJvdydzIGVtYmVkZGVkIHZpZXdcbiAgICogYW5kIHJ1biBjaGFuZ2UgZGV0ZWN0aW9uLCB3aXRob3V0IHJlY3JlYXRpbmcgdGhlIHZpZXdzLiBVc2VkIHdoZW4gdGhlIGRhdGFcbiAgICogcmVmZXJlbmNlIGNoYW5nZXMgYnV0IHRoZSB2aXNpYmxlIGluZGljZXMgKGFuZCB0aGVpciBoZWlnaHRzKSBkbyBub3QsIHNvIHJvd1xuICAgKiBzdGF0ZSAoZm9jdXMsIHNlbGVjdGlvbiwgb3BlbiBkcm9wZG93bnMpIHN1cnZpdmVzIHRoZSB1cGRhdGUuXG4gICAqL1xuICAvKipcbiAgICogUmUtYmluZCBlYWNoIGN1cnJlbnRseSByZW5kZXJlZCByb3cncyBjb250ZXh0IChmcm9tIHRoZSBjdXJyZW50IGl0ZW1zL2dldHRlcilcbiAgICogYW5kIHJ1biBjaGFuZ2UgZGV0ZWN0aW9uIG9uIGl0cyBlbWJlZGRlZCB2aWV3LiBVc2UgdGhpcyBhZnRlciBtdXRhdGluZyByb3dcbiAgICogc3RhdGUgaW4gcGxhY2UgKGUuZy4gc2VsZWN0aW9uIGZsYWdzKSBvciBjb2x1bW4tbGV2ZWwgc3RhdGUgcmVhZCBieSB0aGUgcm93XG4gICAqIHRlbXBsYXRlLCB3aGVuIHJvdyBpZGVudGl0eSBhbmQgdmlzaWJsZSBpbmRpY2VzIGhhdmUgbm90IGNoYW5nZWQuIENoZWFwXG4gICAqIHJlbGF0aXZlIHRvIGByZW5kZXIoKWAg4oCUIGRvZXMgbm90IGludm9rZSB0aGUgZW5naW5lJ3MgbWVhc3VyZW1lbnQgcGFzcy5cbiAgICovXG4gIHJlZnJlc2hSZW5kZXJlZENvbnRlbnQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybjtcbiAgICBjb25zdCBzY3JvbGxlciA9IHRoaXMuaG9zdFJlZi5zY3JvbGxlcjtcblxuICAgIGZvciAoY29uc3QgaW5kZXggb2Ygc2Nyb2xsZXIuZ2V0UmVuZGVyZWRJbmRpY2VzKCkpIHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHNjcm9sbGVyLmdldFJlbmRlcmVkRWxlbWVudChpbmRleCk7XG4gICAgICBpZiAoIWNvbnRhaW5lcikgY29udGludWU7XG5cbiAgICAgIGNvbnN0IHZpZXcgPSB0aGlzLnZpZXdCeUNvbnRhaW5lci5nZXQoY29udGFpbmVyKTtcbiAgICAgIGlmICghdmlldykgY29udGludWU7XG5cbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmdldEl0ZW1Gb3JJbmRleChpbmRleCk7XG4gICAgICB2aWV3LmNvbnRleHQuJGltcGxpY2l0ID0gaXRlbTtcbiAgICAgIHZpZXcuY29udGV4dC5pdGVtID0gaXRlbTtcbiAgICAgIHZpZXcuY29udGV4dC5pbmRleCA9IGluZGV4O1xuICAgICAgdmlldy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZXN0cm95QWxsVmlld3MoKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCB2aWV3IG9mIHRoaXMudmlld0J5Q29udGFpbmVyLnZhbHVlcygpKSB7XG4gICAgICB0aGlzLmFwcFJlZi5kZXRhY2hWaWV3KHZpZXcpO1xuICAgICAgdmlldy5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMudmlld0J5Q29udGFpbmVyLmNsZWFyKCk7XG4gICAgZm9yIChjb25zdCB2aWV3IG9mIHRoaXMuZnJlZVZpZXdzKSB7XG4gICAgICB0aGlzLmFwcFJlZi5kZXRhY2hWaWV3KHZpZXcpO1xuICAgICAgdmlldy5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMuZnJlZVZpZXdzLmxlbmd0aCA9IDA7XG4gIH1cbn1cbiJdfQ==
|