@scion/components 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +40 -0
  2. package/_components.scss +1 -0
  3. package/_index.scss +23 -0
  4. package/dimension/dimension.directive.d.ts +43 -0
  5. package/dimension/dimension.module.d.ts +13 -0
  6. package/dimension/package.json +10 -0
  7. package/dimension/public_api.d.ts +2 -0
  8. package/dimension/scion-components-dimension.d.ts +5 -0
  9. package/esm2020/dimension/dimension.directive.mjs +83 -0
  10. package/esm2020/dimension/dimension.module.mjs +40 -0
  11. package/esm2020/dimension/public_api.mjs +17 -0
  12. package/esm2020/dimension/scion-components-dimension.mjs +5 -0
  13. package/esm2020/public-api.mjs +11 -0
  14. package/esm2020/sashbox/element-ref.directive.mjs +27 -0
  15. package/esm2020/sashbox/public_api.mjs +18 -0
  16. package/esm2020/sashbox/sash-initializer.directive.mjs +32 -0
  17. package/esm2020/sashbox/sash.directive.mjs +144 -0
  18. package/esm2020/sashbox/sashbox-accessor.mjs +6 -0
  19. package/esm2020/sashbox/sashbox.component.mjs +278 -0
  20. package/esm2020/sashbox/sashbox.module.mjs +71 -0
  21. package/esm2020/sashbox/scion-components-sashbox.mjs +5 -0
  22. package/esm2020/scion-components.mjs +5 -0
  23. package/esm2020/splitter/public_api.mjs +17 -0
  24. package/esm2020/splitter/scion-components-splitter.mjs +5 -0
  25. package/esm2020/splitter/splitter.component.mjs +227 -0
  26. package/esm2020/splitter/splitter.module.mjs +44 -0
  27. package/esm2020/throbber/ellipsis-throbber/ellipsis-throbber.component.mjs +25 -0
  28. package/esm2020/throbber/public_api.mjs +17 -0
  29. package/esm2020/throbber/ripple-throbber/ripple-throbber.component.mjs +25 -0
  30. package/esm2020/throbber/roller-throbber/roller-throbber.component.mjs +25 -0
  31. package/esm2020/throbber/scion-components-throbber.mjs +5 -0
  32. package/esm2020/throbber/spinner-throbber/spinner-throbber.component.mjs +26 -0
  33. package/esm2020/throbber/throbber.component.mjs +67 -0
  34. package/esm2020/throbber/throbber.module.mjs +50 -0
  35. package/esm2020/viewport/native-scrollbar-track-size-provider.service.mjs +114 -0
  36. package/esm2020/viewport/public_api.mjs +20 -0
  37. package/esm2020/viewport/scion-components-viewport.mjs +5 -0
  38. package/esm2020/viewport/scrollable.directive.mjs +93 -0
  39. package/esm2020/viewport/scrollbar/scrollbar.component.mjs +322 -0
  40. package/esm2020/viewport/viewport.component.mjs +265 -0
  41. package/esm2020/viewport/viewport.module.mjs +52 -0
  42. package/fesm2015/scion-components-dimension.mjs +137 -0
  43. package/fesm2015/scion-components-dimension.mjs.map +1 -0
  44. package/fesm2015/scion-components-sashbox.mjs +556 -0
  45. package/fesm2015/scion-components-sashbox.mjs.map +1 -0
  46. package/fesm2015/scion-components-splitter.mjs +286 -0
  47. package/fesm2015/scion-components-splitter.mjs.map +1 -0
  48. package/fesm2015/scion-components-throbber.mjs +216 -0
  49. package/fesm2015/scion-components-throbber.mjs.map +1 -0
  50. package/fesm2015/scion-components-viewport.mjs +846 -0
  51. package/fesm2015/scion-components-viewport.mjs.map +1 -0
  52. package/fesm2015/scion-components.mjs +4 -0
  53. package/fesm2015/scion-components.mjs.map +1 -0
  54. package/fesm2020/scion-components-dimension.mjs +137 -0
  55. package/fesm2020/scion-components-dimension.mjs.map +1 -0
  56. package/fesm2020/scion-components-sashbox.mjs +556 -0
  57. package/fesm2020/scion-components-sashbox.mjs.map +1 -0
  58. package/fesm2020/scion-components-splitter.mjs +284 -0
  59. package/fesm2020/scion-components-splitter.mjs.map +1 -0
  60. package/fesm2020/scion-components-throbber.mjs +216 -0
  61. package/fesm2020/scion-components-throbber.mjs.map +1 -0
  62. package/fesm2020/scion-components-viewport.mjs +842 -0
  63. package/fesm2020/scion-components-viewport.mjs.map +1 -0
  64. package/fesm2020/scion-components.mjs +14 -0
  65. package/fesm2020/scion-components.mjs.map +1 -0
  66. package/package.json +93 -0
  67. package/public-api.d.ts +4 -0
  68. package/sashbox/element-ref.directive.d.ts +12 -0
  69. package/sashbox/package.json +10 -0
  70. package/sashbox/public_api.d.ts +3 -0
  71. package/sashbox/sash-initializer.directive.d.ts +14 -0
  72. package/sashbox/sash.directive.d.ts +60 -0
  73. package/sashbox/sashbox-accessor.d.ts +10 -0
  74. package/sashbox/sashbox.component.d.ts +90 -0
  75. package/sashbox/sashbox.module.d.ts +33 -0
  76. package/sashbox/scion-components-sashbox.d.ts +5 -0
  77. package/scion-components.d.ts +5 -0
  78. package/splitter/package.json +10 -0
  79. package/splitter/public_api.d.ts +2 -0
  80. package/splitter/scion-components-splitter.d.ts +5 -0
  81. package/splitter/splitter.component.d.ts +104 -0
  82. package/splitter/splitter.module.d.ts +17 -0
  83. package/throbber/ellipsis-throbber/ellipsis-throbber.component.d.ts +10 -0
  84. package/throbber/package.json +10 -0
  85. package/throbber/public_api.d.ts +2 -0
  86. package/throbber/ripple-throbber/ripple-throbber.component.d.ts +10 -0
  87. package/throbber/roller-throbber/roller-throbber.component.d.ts +10 -0
  88. package/throbber/scion-components-throbber.d.ts +5 -0
  89. package/throbber/spinner-throbber/spinner-throbber.component.d.ts +11 -0
  90. package/throbber/throbber.component.d.ts +43 -0
  91. package/throbber/throbber.module.d.ts +15 -0
  92. package/viewport/_index.scss +1 -0
  93. package/viewport/_scrollbar.scss +44 -0
  94. package/viewport/native-scrollbar-track-size-provider.service.d.ts +42 -0
  95. package/viewport/package.json +10 -0
  96. package/viewport/public_api.d.ts +5 -0
  97. package/viewport/scion-components-viewport.d.ts +5 -0
  98. package/viewport/scrollable.directive.d.ts +39 -0
  99. package/viewport/scrollbar/scrollbar.component.d.ts +106 -0
  100. package/viewport/viewport.component.d.ts +160 -0
  101. package/viewport/viewport.module.d.ts +14 -0
@@ -0,0 +1,322 @@
1
+ /*
2
+ * Copyright (c) 2018-2019 Swiss Federal Railways
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ */
10
+ import { DOCUMENT } from '@angular/common';
11
+ import { ChangeDetectionStrategy, Component, HostBinding, Inject, Input, NgZone, ViewChild } from '@angular/core';
12
+ import { fromEvent, merge, of, Subject, timer } from 'rxjs';
13
+ import { debounceTime, first, map, startWith, switchMap, takeUntil, takeWhile, withLatestFrom } from 'rxjs/operators';
14
+ import { fromDimension$, fromMutation$ } from '@scion/toolkit/observable';
15
+ import { filterArray, subscribeInside } from '@scion/toolkit/operators';
16
+ import * as i0 from "@angular/core";
17
+ /**
18
+ * Renders a vertical or horizontal scrollbar.
19
+ *
20
+ * The scrollbar features the following functionality:
21
+ * - allows to move the thumb by mouse or touch
22
+ * - enlarges the thumb if the mouse pointer is near the thumb
23
+ * - allows paging on mousedown on the scroll track
24
+ *
25
+ * ### CSS styling:
26
+ *
27
+ * You can override the following CSS variables:
28
+ *
29
+ * - sci-scrollbar-color: Sets the color of the scrollbar (by default, uses `rgb(78, 78, 78)`).
30
+ *
31
+ * Example:
32
+ *
33
+ * ```css
34
+ *
35
+ * sci-scrollbar {
36
+ * --sci-scrollbar-color: blue;
37
+ * }
38
+ * ```
39
+ */
40
+ export class SciScrollbarComponent {
41
+ constructor(_host, _document, _zone) {
42
+ this._host = _host;
43
+ this._document = _document;
44
+ this._zone = _zone;
45
+ this._destroy$ = new Subject();
46
+ this._viewportChange$ = new Subject();
47
+ this._lastDragPosition = null;
48
+ this._overflow = false;
49
+ this._thumbSizeFr = 0;
50
+ this._thumbPositionFr = 0;
51
+ /**
52
+ * Specifies the direction of the scrollbar.
53
+ *
54
+ * By default, if not specified, renders a vertical scrollbar.
55
+ */
56
+ this.direction = 'vscroll';
57
+ this._viewportChange$
58
+ .pipe(switchMap(() => {
59
+ if (!this._viewport) {
60
+ return of(undefined);
61
+ }
62
+ return merge(this.viewportScrollChange$(), this.viewportDimensionChange$({ debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME }), this.viewportClientDimensionChange$({ debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME }));
63
+ }), subscribeInside(continueFn => this._zone.runOutsideAngular(continueFn)), takeUntil(this._destroy$))
64
+ .subscribe(() => {
65
+ if (this._viewport) {
66
+ this.renderScrollPosition();
67
+ }
68
+ else {
69
+ this.unsetScrollPosition();
70
+ }
71
+ });
72
+ }
73
+ get vertical() {
74
+ return this.direction === 'vscroll';
75
+ }
76
+ get horizontal() {
77
+ return this.direction === 'hscroll';
78
+ }
79
+ get scrolling() {
80
+ return this._lastDragPosition !== null;
81
+ }
82
+ /**
83
+ * The viewport to provide scrollbars for.
84
+ */
85
+ set setViewport(viewport) {
86
+ this._viewport = viewport;
87
+ this._viewportChange$.next();
88
+ }
89
+ /**
90
+ * Computes the scroll position and updates CSS variables to render the scroll position in the UI.
91
+ */
92
+ renderScrollPosition() {
93
+ NgZone.assertNotInAngularZone();
94
+ const viewportSize = this.viewportSize;
95
+ const viewportClientSize = this.viewportClientSize;
96
+ const thumbPositionFr = this.scrollPosition / viewportClientSize;
97
+ const thumbSizeFr = viewportSize / viewportClientSize;
98
+ const overflow = viewportClientSize > viewportSize;
99
+ if (thumbPositionFr !== this._thumbPositionFr || thumbSizeFr !== this._thumbSizeFr) {
100
+ this._thumbPositionFr = thumbPositionFr;
101
+ this._thumbSizeFr = thumbSizeFr;
102
+ this.setCssVariable('--ɵsci-scrollbar-thumb-position-fr', thumbPositionFr);
103
+ this.setCssVariable('--ɵsci-scrollbar-thumb-size-fr', thumbSizeFr);
104
+ }
105
+ if (overflow !== this._overflow) {
106
+ this._overflow = overflow;
107
+ overflow ? this._host.nativeElement.classList.add('overflow') : this._host.nativeElement.classList.remove('overflow');
108
+ }
109
+ }
110
+ /**
111
+ * Clears CSS variables used for rendering the scroll position in the UI.
112
+ */
113
+ unsetScrollPosition() {
114
+ NgZone.assertNotInAngularZone();
115
+ this._thumbPositionFr = 0;
116
+ this._thumbSizeFr = 0;
117
+ this._overflow = false;
118
+ this.setCssVariable('--ɵsci-scrollbar-thumb-position-fr', 0);
119
+ this.setCssVariable('--ɵsci-scrollbar-thumb-size-fr', 0);
120
+ this._host.nativeElement.classList.remove('overflow');
121
+ }
122
+ /* @docs-private */
123
+ onTouchStart(event) {
124
+ event.preventDefault();
125
+ this._lastDragPosition = this.vertical ? event.touches[0].screenY : event.touches[0].screenX;
126
+ }
127
+ /* @docs-private */
128
+ onTouchMove(event) {
129
+ event.preventDefault();
130
+ const newDragPositionPx = this.vertical ? event.touches[0].screenY : event.touches[0].screenX;
131
+ const scrollbarPanPx = newDragPositionPx - this._lastDragPosition;
132
+ const viewportPanPx = this.toViewportPanPx(scrollbarPanPx);
133
+ this._lastDragPosition = newDragPositionPx;
134
+ this.moveViewportClient(viewportPanPx);
135
+ }
136
+ /* @docs-private */
137
+ onTouchEnd(event) {
138
+ event.preventDefault();
139
+ this._lastDragPosition = null;
140
+ }
141
+ /* @docs-private */
142
+ onMouseDown(mousedownEvent) {
143
+ if (mousedownEvent.button !== 0) {
144
+ return;
145
+ }
146
+ mousedownEvent.preventDefault();
147
+ this._lastDragPosition = this.vertical ? mousedownEvent.screenY : mousedownEvent.screenX;
148
+ // Listen for 'mousemove' events
149
+ this._zone.runOutsideAngular(() => {
150
+ const mousemoveListener = merge(fromEvent(this._document, 'mousemove'), fromEvent(this._document, 'sci-mousemove'))
151
+ .pipe(takeUntil(this._destroy$))
152
+ .subscribe(mousemoveEvent => {
153
+ mousemoveEvent.preventDefault();
154
+ const newDragPositionPx = this.vertical ? mousemoveEvent.screenY : mousemoveEvent.screenX;
155
+ const scrollbarPanPx = newDragPositionPx - this._lastDragPosition;
156
+ const viewportPanPx = this.toViewportPanPx(scrollbarPanPx);
157
+ this._lastDragPosition = newDragPositionPx;
158
+ this.moveViewportClient(viewportPanPx);
159
+ });
160
+ // Listen for 'mouseup' events; use 'capture phase' and 'stop propagation' to not close overlays
161
+ merge(fromEvent(this._document, 'mouseup', { capture: true }), fromEvent(this._document, 'sci-mouseup'))
162
+ .pipe(first(), takeUntil(this._destroy$))
163
+ .subscribe(mouseupEvent => {
164
+ mouseupEvent.stopPropagation();
165
+ mousemoveListener.unsubscribe();
166
+ this._lastDragPosition = null;
167
+ });
168
+ });
169
+ }
170
+ /* @docs-private */
171
+ onScrollTrackMouseDown(event, direction) {
172
+ const signum = (direction === 'up' ? -1 : +1);
173
+ this.scrollWhileMouseDown(this.toViewportPanPx(signum * this.thumbSize), event);
174
+ }
175
+ /**
176
+ * Projects the given scrollbar scroll pixels into viewport scroll pixels.
177
+ */
178
+ toViewportPanPx(scrollbarPanPx) {
179
+ const scrollRangePx = this.trackSize - this.thumbSize;
180
+ const scrollRatio = scrollbarPanPx / scrollRangePx;
181
+ return scrollRatio * (this.viewportClientSize - this.viewportSize);
182
+ }
183
+ /**
184
+ * Moves the viewport client by the specified numbers of pixels.
185
+ */
186
+ moveViewportClient(viewportPanPx) {
187
+ if (this.vertical) {
188
+ this._viewport.scrollTop += viewportPanPx;
189
+ }
190
+ else {
191
+ this._viewport.scrollLeft += viewportPanPx;
192
+ }
193
+ }
194
+ /**
195
+ * Indicates if the content overflows.
196
+ */
197
+ get overflow() {
198
+ return this._overflow;
199
+ }
200
+ /**
201
+ * Scrolls continuously while holding the mouse pressed, or until the mouse leaves the scrolltrack.
202
+ */
203
+ scrollWhileMouseDown(viewportScrollPx, mousedownEvent) {
204
+ // The `EventTarget` type of `Event.target` is not yet compatible with `FromEventTarget` used in `fromEvent`.
205
+ // This will be fixed in rxjs version 7.0.0. Refer to https://github.com/ReactiveX/rxjs/commit/5f022d784570684632e6fd5ae247fc259ee34c4b
206
+ // for more details.
207
+ const scrollTrackElement = mousedownEvent.target;
208
+ // scroll continuously every 50ms after an initial delay of 250ms
209
+ timer(250, 50)
210
+ .pipe(
211
+ // continue chain with latest mouse event
212
+ withLatestFrom(merge(of(mousedownEvent), fromEvent(scrollTrackElement, 'mousemove')), (tick, event) => event),
213
+ // start immediately
214
+ startWith(mousedownEvent),
215
+ // stop scrolling if the thumb hits the mouse pointer position
216
+ takeWhile((event) => scrollTrackElement === this._document.elementFromPoint(event.clientX, event.clientY)), debounceTime(10),
217
+ // stop scrolling on mouseout or mouseup
218
+ takeUntil(merge(fromEvent(scrollTrackElement, 'mouseout'), fromEvent(scrollTrackElement, 'mouseup'))))
219
+ .subscribe(() => {
220
+ this.moveViewportClient(viewportScrollPx);
221
+ });
222
+ }
223
+ /**
224
+ * Emits whenever the viewport scrolls.
225
+ */
226
+ viewportScrollChange$() {
227
+ return fromEvent(this._viewport, 'scroll', { passive: true }).pipe(map(() => undefined));
228
+ }
229
+ /**
230
+ * Emits on subscription, and then each time the size of the viewport changes.
231
+ */
232
+ viewportDimensionChange$(options) {
233
+ return fromDimension$(this._viewport)
234
+ .pipe(
235
+ // Debouncing is particularly important in the context of Angular animations, since they continuously
236
+ // trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
237
+ // expands a panel that contains a viewport.
238
+ debounceTime(options.debounceTime), map(() => undefined));
239
+ }
240
+ /**
241
+ * Emits on subscription, and then each time the size or style property of the viewport client changes.
242
+ */
243
+ viewportClientDimensionChange$(options) {
244
+ return this.children$(this._viewport)
245
+ .pipe(switchMap(children => merge(...children.map(child => merge(fromDimension$(child),
246
+ // Observe style mutations since some transformations change the scroll position without necessarily triggering a dimension change,
247
+ // e.g., `scale` or `translate` used by some virtual scroll implementations
248
+ fromMutation$(child, { subtree: false, childList: false, attributeFilter: ['style'] }))))),
249
+ // Debouncing is particularly important in the context of Angular animations, since they continuously
250
+ // trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
251
+ // expands a panel that contains a viewport.
252
+ debounceTime(options.debounceTime), map(() => undefined));
253
+ }
254
+ /**
255
+ * Emits the children of the passed element, and then each time child elements are added or removed.
256
+ */
257
+ children$(element) {
258
+ return fromMutation$(element, { subtree: false, childList: true })
259
+ .pipe(startWith(undefined), map(() => Array.from(element.children)), filterArray((child) => child instanceof HTMLElement));
260
+ }
261
+ setCssVariable(key, value) {
262
+ this._host.nativeElement.style.setProperty(key, value);
263
+ }
264
+ get viewportSize() {
265
+ return this._viewport ? (this.vertical ? this._viewport.clientHeight : this._viewport.clientWidth) : 0;
266
+ }
267
+ get viewportClientSize() {
268
+ return this._viewport ? (this.vertical ? this._viewport.scrollHeight : this._viewport.scrollWidth) : 0;
269
+ }
270
+ get scrollPosition() {
271
+ return this._viewport ? (this.vertical ? this._viewport.scrollTop : this._viewport.scrollLeft) : 0;
272
+ }
273
+ get thumbSize() {
274
+ const thumbElement = this.thumbElement.nativeElement;
275
+ return this.vertical ? thumbElement.clientHeight : thumbElement.clientWidth;
276
+ }
277
+ get trackSize() {
278
+ const trackElement = this._host.nativeElement;
279
+ return this.vertical ? trackElement.clientHeight : trackElement.clientWidth;
280
+ }
281
+ /* @docs-private */
282
+ ngOnDestroy() {
283
+ this._destroy$.next();
284
+ }
285
+ }
286
+ /**
287
+ * Timeout for debouncing viewport resize events that trigger the scroll position computation.
288
+ *
289
+ * Debouncing is particularly important in the context of Angular animations, since they continuously
290
+ * trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
291
+ * expands a panel that contains a viewport.
292
+ *
293
+ * @internal
294
+ */
295
+ SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME = 50;
296
+ SciScrollbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: SciScrollbarComponent, deps: [{ token: i0.ElementRef }, { token: DOCUMENT }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
297
+ SciScrollbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.3", type: SciScrollbarComponent, selector: "sci-scrollbar", inputs: { direction: "direction", setViewport: ["viewport", "setViewport"] }, host: { properties: { "class.vertical": "this.vertical", "class.horizontal": "this.horizontal", "class.scrolling": "this.scrolling" } }, viewQueries: [{ propertyName: "thumbElement", first: true, predicate: ["thumb_handle"], descendants: true, static: true }], ngImport: i0, template: "<!-- scrolltrack to move the viewport client upwards (paging) -->\n<div class=\"scrolltrack-start\" (mousedown)=\"onScrollTrackMouseDown($event, 'up')\"></div>\n\n<!-- scrollthumb -->\n<div #thumb_handle\n class=\"thumb-handle\"\n [class.vertical]=\"vertical\"\n [class.horizontal]=\"horizontal\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd($event)\"\n (touchcancel)=\"onTouchEnd($event)\">\n <div class=\"thumb\"\n [class.vertical]=\"vertical\"\n [class.horizontal]=\"horizontal\">\n </div>\n</div>\n\n<!-- scrolltrack to move the viewport client downwards (paging) -->\n<div class=\"scrolltrack-end\" (mousedown)=\"onScrollTrackMouseDown($event, 'down')\"></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;border:2px solid transparent;box-sizing:border-box;--sci-scrollbar-color: rgb(78, 78, 78);--\\275sci-scrollbar-thumb-position-fr: 0;--\\275sci-scrollbar-thumb-size-fr: 0}:host.vertical{flex-direction:column}:host.horizontal{flex-direction:row}:host>div.scrolltrack-start{flex-grow:var(--\\275sci-scrollbar-thumb-position-fr)}:host>div.thumb-handle{flex-basis:20px;display:flex;flex-grow:var(--\\275sci-scrollbar-thumb-size-fr);align-items:center}:host>div.thumb-handle.vertical{flex-direction:column}:host>div.thumb-handle.horizontal{flex-direction:row}:host>div.thumb-handle>div.thumb{flex:auto;border-radius:4px;background-color:var(--sci-scrollbar-color);opacity:.4;transition-duration:125ms;transition-property:width,height;transition-timing-function:ease-out}:host>div.thumb-handle>div.thumb.vertical{width:60%}:host>div.thumb-handle>div.thumb.horizontal{height:60%}:host>div.scrolltrack-end{flex-grow:calc(1 - (var(--\\275sci-scrollbar-thumb-position-fr) + var(--\\275sci-scrollbar-thumb-size-fr)))}:host-context:not(.overflow){display:none}:host-context:hover>div.thumb-handle>div.thumb,:host-context(.scrolling)>div.thumb-handle>div.thumb{background-color:var(--sci-scrollbar-color);opacity:.75}:host-context:hover>div.thumb-handle>div.thumb.vertical,:host-context(.scrolling)>div.thumb-handle>div.thumb.vertical{width:100%}:host-context:hover>div.thumb-handle>div.thumb.horizontal,:host-context(.scrolling)>div.thumb-handle>div.thumb.horizontal{height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
298
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: SciScrollbarComponent, decorators: [{
299
+ type: Component,
300
+ args: [{ selector: 'sci-scrollbar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- scrolltrack to move the viewport client upwards (paging) -->\n<div class=\"scrolltrack-start\" (mousedown)=\"onScrollTrackMouseDown($event, 'up')\"></div>\n\n<!-- scrollthumb -->\n<div #thumb_handle\n class=\"thumb-handle\"\n [class.vertical]=\"vertical\"\n [class.horizontal]=\"horizontal\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd($event)\"\n (touchcancel)=\"onTouchEnd($event)\">\n <div class=\"thumb\"\n [class.vertical]=\"vertical\"\n [class.horizontal]=\"horizontal\">\n </div>\n</div>\n\n<!-- scrolltrack to move the viewport client downwards (paging) -->\n<div class=\"scrolltrack-end\" (mousedown)=\"onScrollTrackMouseDown($event, 'down')\"></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;border:2px solid transparent;box-sizing:border-box;--sci-scrollbar-color: rgb(78, 78, 78);--\\275sci-scrollbar-thumb-position-fr: 0;--\\275sci-scrollbar-thumb-size-fr: 0}:host.vertical{flex-direction:column}:host.horizontal{flex-direction:row}:host>div.scrolltrack-start{flex-grow:var(--\\275sci-scrollbar-thumb-position-fr)}:host>div.thumb-handle{flex-basis:20px;display:flex;flex-grow:var(--\\275sci-scrollbar-thumb-size-fr);align-items:center}:host>div.thumb-handle.vertical{flex-direction:column}:host>div.thumb-handle.horizontal{flex-direction:row}:host>div.thumb-handle>div.thumb{flex:auto;border-radius:4px;background-color:var(--sci-scrollbar-color);opacity:.4;transition-duration:125ms;transition-property:width,height;transition-timing-function:ease-out}:host>div.thumb-handle>div.thumb.vertical{width:60%}:host>div.thumb-handle>div.thumb.horizontal{height:60%}:host>div.scrolltrack-end{flex-grow:calc(1 - (var(--\\275sci-scrollbar-thumb-position-fr) + var(--\\275sci-scrollbar-thumb-size-fr)))}:host-context:not(.overflow){display:none}:host-context:hover>div.thumb-handle>div.thumb,:host-context(.scrolling)>div.thumb-handle>div.thumb{background-color:var(--sci-scrollbar-color);opacity:.75}:host-context:hover>div.thumb-handle>div.thumb.vertical,:host-context(.scrolling)>div.thumb-handle>div.thumb.vertical{width:100%}:host-context:hover>div.thumb-handle>div.thumb.horizontal,:host-context(.scrolling)>div.thumb-handle>div.thumb.horizontal{height:100%}\n"] }]
301
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: undefined, decorators: [{
302
+ type: Inject,
303
+ args: [DOCUMENT]
304
+ }] }, { type: i0.NgZone }]; }, propDecorators: { thumbElement: [{
305
+ type: ViewChild,
306
+ args: ['thumb_handle', { static: true }]
307
+ }], vertical: [{
308
+ type: HostBinding,
309
+ args: ['class.vertical']
310
+ }], horizontal: [{
311
+ type: HostBinding,
312
+ args: ['class.horizontal']
313
+ }], scrolling: [{
314
+ type: HostBinding,
315
+ args: ['class.scrolling']
316
+ }], direction: [{
317
+ type: Input
318
+ }], setViewport: [{
319
+ type: Input,
320
+ args: ['viewport']
321
+ }] } });
322
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NjaW9uL2NvbXBvbmVudHMvdmlld3BvcnQvc3JjL3Njcm9sbGJhci9zY3JvbGxiYXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2Npb24vY29tcG9uZW50cy92aWV3cG9ydC9zcmMvc2Nyb2xsYmFyL3Njcm9sbGJhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRztBQUVILE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsU0FBUyxFQUFjLFdBQVcsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBYSxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDdkksT0FBTyxFQUFDLFNBQVMsRUFBRSxLQUFLLEVBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDdEUsT0FBTyxFQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwSCxPQUFPLEVBQUMsY0FBYyxFQUFFLGFBQWEsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBQ3hFLE9BQU8sRUFBQyxXQUFXLEVBQUUsZUFBZSxFQUFDLE1BQU0sMEJBQTBCLENBQUM7O0FBRXRFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBT0gsTUFBTSxPQUFPLHFCQUFxQjtJQTBEaEMsWUFBb0IsS0FBOEIsRUFDWixTQUFjLEVBQ2hDLEtBQWE7UUFGYixVQUFLLEdBQUwsS0FBSyxDQUF5QjtRQUNaLGNBQVMsR0FBVCxTQUFTLENBQUs7UUFDaEMsVUFB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WUFBWSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDO0lBQzlFLENBQUM7SUFFRCxtQkFBbUI7SUFDWixXQUFXO1FBQ2hCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDeEIsQ0FBQzs7QUFqVUQ7Ozs7Ozs7O0dBUUc7QUFDb0IsbURBQTZCLEdBQUcsRUFBRyxDQUFBO2tIQVgvQyxxQkFBcUIsNENBMkRaLFFBQVE7c0dBM0RqQixxQkFBcUIsd1lDOUNsQyw0eUJBcUJBOzJGRHlCYSxxQkFBcUI7a0JBTmpDLFNBQVM7K0JBQ0UsZUFBZSxtQkFHUix1QkFBdUIsQ0FBQyxNQUFNOzswQkE2RGxDLE1BQU07MkJBQUMsUUFBUTtpRUFuQ3JCLFlBQVk7c0JBRGxCLFNBQVM7dUJBQUMsY0FBYyxFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQztnQkFJOUIsUUFBUTtzQkFEbEIsV0FBVzt1QkFBQyxnQkFBZ0I7Z0JBTWxCLFVBQVU7c0JBRHBCLFdBQVc7dUJBQUMsa0JBQWtCO2dCQU1wQixTQUFTO3NCQURuQixXQUFXO3VCQUFDLGlCQUFpQjtnQkFXdkIsU0FBUztzQkFEZixLQUFLO2dCQU9LLFdBQVc7c0JBRHJCLEtBQUs7dUJBQUMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtMjAxOSBTd2lzcyBGZWRlcmFsIFJhaWx3YXlzXG4gKlxuICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZVxuICogYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSAyLjBcbiAqIHdoaWNoIGlzIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wL1xuICpcbiAqICBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMFxuICovXG5cbmltcG9ydCB7RE9DVU1FTlR9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge0NoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RCaW5kaW5nLCBJbmplY3QsIElucHV0LCBOZ1pvbmUsIE9uRGVzdHJveSwgVmlld0NoaWxkfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7ZnJvbUV2ZW50LCBtZXJnZSwgT2JzZXJ2YWJsZSwgb2YsIFN1YmplY3QsIHRpbWVyfSBmcm9tICdyeGpzJztcbmltcG9ydCB7ZGVib3VuY2VUaW1lLCBmaXJzdCwgbWFwLCBzdGFydFdpdGgsIHN3aXRjaE1hcCwgdGFrZVVudGlsLCB0YWtlV2hpbGUsIHdpdGhMYXRlc3RGcm9tfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge2Zyb21EaW1lbnNpb24kLCBmcm9tTXV0YXRpb24kfSBmcm9tICdAc2Npb24vdG9vbGtpdC9vYnNlcnZhYmxlJztcbmltcG9ydCB7ZmlsdGVyQXJyYXksIHN1YnNjcmliZUluc2lkZX0gZnJvbSAnQHNjaW9uL3Rvb2xraXQvb3BlcmF0b3JzJztcblxuLyoqXG4gKiBSZW5kZXJzIGEgdmVydGljYWwgb3IgaG9yaXpvbnRhbCBzY3JvbGxiYXIuXG4gKlxuICogVGhlIHNjcm9sbGJhciBmZWF0dXJlcyB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uYWxpdHk6XG4gKiAtIGFsbG93cyB0byBtb3ZlIHRoZSB0aHVtYiBieSBtb3VzZSBvciB0b3VjaFxuICogLSBlbmxhcmdlcyB0aGUgdGh1bWIgaWYgdGhlIG1vdXNlIHBvaW50ZXIgaXMgbmVhciB0aGUgdGh1bWJcbiAqIC0gYWxsb3dzIHBhZ2luZyBvbiBtb3VzZWRvd24gb24gdGhlIHNjcm9sbCB0cmFja1xuICpcbiAqICMjIyBDU1Mgc3R5bGluZzpcbiAqXG4gKiBZb3UgY2FuIG92ZXJyaWRlIHRoZSBmb2xsb3dpbmcgQ1NTIHZhcmlhYmxlczpcbiAqXG4gKiAtIHNjaS1zY3JvbGxiYXItY29sb3I6ICAgIFNldHMgdGhlIGNvbG9yIG9mIHRoZSBzY3JvbGxiYXIgKGJ5IGRlZmF1bHQsIHVzZXMgYHJnYig3OCwgNzgsIDc4KWApLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogYGBgY3NzXG4gKlxuICogc2NpLXNjcm9sbGJhciB7XG4gKiAgIC0tc2NpLXNjcm9sbGJhci1jb2xvcjogYmx1ZTtcbiAqIH1cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzY2ktc2Nyb2xsYmFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3Njcm9sbGJhci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3Njcm9sbGJhci5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU2NpU2Nyb2xsYmFyQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcblxuICAvKipcbiAgICogVGltZW91dCBmb3IgZGVib3VuY2luZyB2aWV3cG9ydCByZXNpemUgZXZlbnRzIHRoYXQgdHJpZ2dlciB0aGUgc2Nyb2xsIHBvc2l0aW9uIGNvbXB1dGF0aW9uLlxuICAgKlxuICAgKiBEZWJvdW5jaW5nIGlzIHBhcnRpY3VsYXJseSBpbXBvcnRhbnQgaW4gdGhlIGNvbnRleHQgb2YgQW5ndWxhciBhbmltYXRpb25zLCBzaW5jZSB0aGV5IGNvbnRpbnVvdXNseVxuICAgKiB0cmlnZ2VyIHJlc2l6ZSBldmVudHMuIERlYm91bmNpbmcgcHJldmVudHMgdGhlIHNjcm9sbGJhciBmcm9tIGZsaWNrZXJpbmcsIGZvciBleGFtcGxlLCB3aGVuIHRoZSB1c2VyXG4gICAqIGV4cGFuZHMgYSBwYW5lbCB0aGF0IGNvbnRhaW5zIGEgdmlld3BvcnQuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBWSUVXUE9SVF9SRVNJWkVfREVCT1VOQ0VfVElNRSA9IDUwO1xuXG4gIHByaXZhdGUgX2Rlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBfdmlld3BvcnQhOiBIVE1MRWxlbWVudDtcbiAgcHJpdmF0ZSBfdmlld3BvcnRDaGFuZ2UkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBfbGFzdERyYWdQb3NpdGlvbjogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBfb3ZlcmZsb3cgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfdGh1bWJTaXplRnIgPSAwO1xuICBwcml2YXRlIF90aHVtYlBvc2l0aW9uRnIgPSAwO1xuXG4gIC8qIEBkb2NzLXByaXZhdGUgKi9cbiAgQFZpZXdDaGlsZCgndGh1bWJfaGFuZGxlJywge3N0YXRpYzogdHJ1ZX0pXG4gIHB1YmxpYyB0aHVtYkVsZW1lbnQhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLnZlcnRpY2FsJylcbiAgcHVibGljIGdldCB2ZXJ0aWNhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kaXJlY3Rpb24gPT09ICd2c2Nyb2xsJztcbiAgfVxuXG4gIEBIb3N0QmluZGluZygnY2xhc3MuaG9yaXpvbnRhbCcpXG4gIHB1YmxpYyBnZXQgaG9yaXpvbnRhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kaXJlY3Rpb24gPT09ICdoc2Nyb2xsJztcbiAgfVxuXG4gIEBIb3N0QmluZGluZygnY2xhc3Muc2Nyb2xsaW5nJylcbiAgcHVibGljIGdldCBzY3JvbGxpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2xhc3REcmFnUG9zaXRpb24gIT09IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogU3BlY2lmaWVzIHRoZSBkaXJlY3Rpb24gb2YgdGhlIHNjcm9sbGJhci5cbiAgICpcbiAgICogQnkgZGVmYXVsdCwgaWYgbm90IHNwZWNpZmllZCwgcmVuZGVycyBhIHZlcnRpY2FsIHNjcm9sbGJhci5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBkaXJlY3Rpb246ICd2c2Nyb2xsJyB8ICdoc2Nyb2xsJyA9ICd2c2Nyb2xsJztcblxuICAvKipcbiAgICogVGhlIHZpZXdwb3J0IHRvIHByb3ZpZGUgc2Nyb2xsYmFycyBmb3IuXG4gICAqL1xuICBASW5wdXQoJ3ZpZXdwb3J0JykgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAYW5ndWxhci1lc2xpbnQvbm8taW5wdXQtcmVuYW1lXG4gIHB1YmxpYyBzZXQgc2V0Vmlld3BvcnQodmlld3BvcnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgdGhpcy5fdmlld3BvcnQgPSB2aWV3cG9ydDtcbiAgICB0aGlzLl92aWV3cG9ydENoYW5nZSQubmV4dCgpO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfaG9zdDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgICAgICAgICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgX2RvY3VtZW50OiBhbnksXG4gICAgICAgICAgICAgIHByaXZhdGUgX3pvbmU6IE5nWm9uZSkge1xuICAgIHRoaXMuX3ZpZXdwb3J0Q2hhbmdlJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XG4gICAgICAgICAgaWYgKCF0aGlzLl92aWV3cG9ydCkge1xuICAgICAgICAgICAgcmV0dXJuIG9mKHVuZGVmaW5lZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBtZXJnZShcbiAgICAgICAgICAgIHRoaXMudmlld3BvcnRTY3JvbGxDaGFuZ2UkKCksXG4gICAgICAgICAgICB0aGlzLnZpZXdwb3J0RGltZW5zaW9uQ2hhbmdlJCh7ZGVib3VuY2VUaW1lOiBTY2lTY3JvbGxiYXJDb21wb25lbnQuVklFV1BPUlRfUkVTSVpFX0RFQk9VTkNFX1RJTUV9KSxcbiAgICAgICAgICAgIHRoaXMudmlld3BvcnRDbGllbnREaW1lbnNpb25DaGFuZ2UkKHtkZWJvdW5jZVRpbWU6IFNjaVNjcm9sbGJhckNvbXBvbmVudC5WSUVXUE9SVF9SRVNJWkVfREVCT1VOQ0VfVElNRX0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH0pLFxuICAgICAgICBzdWJzY3JpYmVJbnNpZGUoY29udGludWVGbiA9PiB0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKGNvbnRpbnVlRm4pKSxcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5fdmlld3BvcnQpIHtcbiAgICAgICAgICB0aGlzLnJlbmRlclNjcm9sbFBvc2l0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhpcy51bnNldFNjcm9sbFBvc2l0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGVzIHRoZSBzY3JvbGwgcG9zaXRpb24gYW5kIHVwZGF0ZXMgQ1NTIHZhcmlhYmxlcyB0byByZW5kZXIgdGhlIHNjcm9sbCBwb3NpdGlvbiBpbiB0aGUgVUkuXG4gICAqL1xuICBwcml2YXRlIHJlbmRlclNjcm9sbFBvc2l0aW9uKCk6IHZvaWQge1xuICAgIE5nWm9uZS5hc3NlcnROb3RJbkFuZ3VsYXJab25lKCk7XG4gICAgY29uc3Qgdmlld3BvcnRTaXplID0gdGhpcy52aWV3cG9ydFNpemU7XG4gICAgY29uc3Qgdmlld3BvcnRDbGllbnRTaXplID0gdGhpcy52aWV3cG9ydENsaWVudFNpemU7XG4gICAgY29uc3QgdGh1bWJQb3NpdGlvbkZyID0gdGhpcy5zY3JvbGxQb3NpdGlvbiAvIHZpZXdwb3J0Q2xpZW50U2l6ZTtcbiAgICBjb25zdCB0aHVtYlNpemVGciA9IHZpZXdwb3J0U2l6ZSAvIHZpZXdwb3J0Q2xpZW50U2l6ZTtcbiAgICBjb25zdCBvdmVyZmxvdyA9IHZpZXdwb3J0Q2xpZW50U2l6ZSA+IHZpZXdwb3J0U2l6ZTtcblxuICAgIGlmICh0aHVtYlBvc2l0aW9uRnIgIT09IHRoaXMuX3RodW1iUG9zaXRpb25GciB8fCB0aHVtYlNpemVGciAhPT0gdGhpcy5fdGh1bWJTaXplRnIpIHtcbiAgICAgIHRoaXMuX3RodW1iUG9zaXRpb25GciA9IHRodW1iUG9zaXRpb25GcjtcbiAgICAgIHRoaXMuX3RodW1iU2l6ZUZyID0gdGh1bWJTaXplRnI7XG4gICAgICB0aGlzLnNldENzc1ZhcmlhYmxlKCctLcm1c2NpLXNjcm9sbGJhci10aHVtYi1wb3NpdGlvbi1mcicsIHRodW1iUG9zaXRpb25Gcik7XG4gICAgICB0aGlzLnNldENzc1ZhcmlhYmxlKCctLcm1c2NpLXNjcm9sbGJhci10aHVtYi1zaXplLWZyJywgdGh1bWJTaXplRnIpO1xuICAgIH1cblxuICAgIGlmIChvdmVyZmxvdyAhPT0gdGhpcy5fb3ZlcmZsb3cpIHtcbiAgICAgIHRoaXMuX292ZXJmbG93ID0gb3ZlcmZsb3c7XG4gICAgICBvdmVyZmxvdyA/IHRoaXMuX2hvc3QubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdvdmVyZmxvdycpIDogdGhpcy5faG9zdC5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ292ZXJmbG93Jyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyBDU1MgdmFyaWFibGVzIHVzZWQgZm9yIHJlbmRlcmluZyB0aGUgc2Nyb2xsIHBvc2l0aW9uIGluIHRoZSBVSS5cbiAgICovXG4gIHByaXZhdGUgdW5zZXRTY3JvbGxQb3NpdGlvbigpOiB2b2lkIHtcbiAgICBOZ1pvbmUuYXNzZXJ0Tm90SW5Bbmd1bGFyWm9uZSgpO1xuICAgIHRoaXMuX3RodW1iUG9zaXRpb25GciA9IDA7XG4gICAgdGhpcy5fdGh1bWJTaXplRnIgPSAwO1xuICAgIHRoaXMuX292ZXJmbG93ID0gZmFsc2U7XG4gICAgdGhpcy5zZXRDc3NWYXJpYWJsZSgnLS3JtXNjaS1zY3JvbGxiYXItdGh1bWItcG9zaXRpb24tZnInLCAwKTtcbiAgICB0aGlzLnNldENzc1ZhcmlhYmxlKCctLcm1c2NpLXNjcm9sbGJhci10aHVtYi1zaXplLWZyJywgMCk7XG4gICAgdGhpcy5faG9zdC5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ292ZXJmbG93Jyk7XG4gIH1cblxuICAvKiBAZG9jcy1wcml2YXRlICovXG4gIHB1YmxpYyBvblRvdWNoU3RhcnQoZXZlbnQ6IFRvdWNoRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuX2xhc3REcmFnUG9zaXRpb24gPSB0aGlzLnZlcnRpY2FsID8gZXZlbnQudG91Y2hlc1swXS5zY3JlZW5ZIDogZXZlbnQudG91Y2hlc1swXS5zY3JlZW5YO1xuICB9XG5cbiAgLyogQGRvY3MtcHJpdmF0ZSAqL1xuICBwdWJsaWMgb25Ub3VjaE1vdmUoZXZlbnQ6IFRvdWNoRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgbmV3RHJhZ1Bvc2l0aW9uUHggPSB0aGlzLnZlcnRpY2FsID8gZXZlbnQudG91Y2hlc1swXS5zY3JlZW5ZIDogZXZlbnQudG91Y2hlc1swXS5zY3JlZW5YO1xuICAgIGNvbnN0IHNjcm9sbGJhclBhblB4ID0gbmV3RHJhZ1Bvc2l0aW9uUHggLSB0aGlzLl9sYXN0RHJhZ1Bvc2l0aW9uITtcbiAgICBjb25zdCB2aWV3cG9ydFBhblB4ID0gdGhpcy50b1ZpZXdwb3J0UGFuUHgoc2Nyb2xsYmFyUGFuUHgpO1xuICAgIHRoaXMuX2xhc3REcmFnUG9zaXRpb24gPSBuZXdEcmFnUG9zaXRpb25QeDtcbiAgICB0aGlzLm1vdmVWaWV3cG9ydENsaWVudCh2aWV3cG9ydFBhblB4KTtcbiAgfVxuXG4gIC8qIEBkb2NzLXByaXZhdGUgKi9cbiAgcHVibGljIG9uVG91Y2hFbmQoZXZlbnQ6IFRvdWNoRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuX2xhc3REcmFnUG9zaXRpb24gPSBudWxsO1xuICB9XG5cbiAgLyogQGRvY3MtcHJpdmF0ZSAqL1xuICBwdWJsaWMgb25Nb3VzZURvd24obW91c2Vkb3duRXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAobW91c2Vkb3duRXZlbnQuYnV0dG9uICE9PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbW91c2Vkb3duRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLl9sYXN0RHJhZ1Bvc2l0aW9uID0gdGhpcy52ZXJ0aWNhbCA/IG1vdXNlZG93bkV2ZW50LnNjcmVlblkgOiBtb3VzZWRvd25FdmVudC5zY3JlZW5YO1xuXG4gICAgLy8gTGlzdGVuIGZvciAnbW91c2Vtb3ZlJyBldmVudHNcbiAgICB0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGNvbnN0IG1vdXNlbW92ZUxpc3RlbmVyID0gbWVyZ2UoZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KHRoaXMuX2RvY3VtZW50LCAnbW91c2Vtb3ZlJyksIGZyb21FdmVudDxNb3VzZUV2ZW50Pih0aGlzLl9kb2N1bWVudCwgJ3NjaS1tb3VzZW1vdmUnKSlcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZShtb3VzZW1vdmVFdmVudCA9PiB7XG4gICAgICAgICAgbW91c2Vtb3ZlRXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgIGNvbnN0IG5ld0RyYWdQb3NpdGlvblB4ID0gdGhpcy52ZXJ0aWNhbCA/IG1vdXNlbW92ZUV2ZW50LnNjcmVlblkgOiBtb3VzZW1vdmVFdmVudC5zY3JlZW5YO1xuICAgICAgICAgIGNvbnN0IHNjcm9sbGJhclBhblB4ID0gbmV3RHJhZ1Bvc2l0aW9uUHggLSB0aGlzLl9sYXN0RHJhZ1Bvc2l0aW9uITtcbiAgICAgICAgICBjb25zdCB2aWV3cG9ydFBhblB4ID0gdGhpcy50b1ZpZXdwb3J0UGFuUHgoc2Nyb2xsYmFyUGFuUHgpO1xuICAgICAgICAgIHRoaXMuX2xhc3REcmFnUG9zaXRpb24gPSBuZXdEcmFnUG9zaXRpb25QeDtcbiAgICAgICAgICB0aGlzLm1vdmVWaWV3cG9ydENsaWVudCh2aWV3cG9ydFBhblB4KTtcbiAgICAgICAgfSk7XG5cbiAgICAgIC8vIExpc3RlbiBmb3IgJ21vdXNldXAnIGV2ZW50czsgdXNlICdjYXB0dXJlIHBoYXNlJyBhbmQgJ3N0b3AgcHJvcGFnYXRpb24nIHRvIG5vdCBjbG9zZSBvdmVybGF5c1xuICAgICAgbWVyZ2UoZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KHRoaXMuX2RvY3VtZW50LCAnbW91c2V1cCcsIHtjYXB0dXJlOiB0cnVlfSksIGZyb21FdmVudDxNb3VzZUV2ZW50Pih0aGlzLl9kb2N1bWVudCwgJ3NjaS1tb3VzZXVwJykpXG4gICAgICAgIC5waXBlKGZpcnN0KCksIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUobW91c2V1cEV2ZW50ID0+IHtcbiAgICAgICAgICBtb3VzZXVwRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgbW91c2Vtb3ZlTGlzdGVuZXIudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICB0aGlzLl9sYXN0RHJhZ1Bvc2l0aW9uID0gbnVsbDtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKiBAZG9jcy1wcml2YXRlICovXG4gIHB1YmxpYyBvblNjcm9sbFRyYWNrTW91c2VEb3duKGV2ZW50OiBNb3VzZUV2ZW50LCBkaXJlY3Rpb246ICd1cCcgfCAnZG93bicpOiB2b2lkIHtcbiAgICBjb25zdCBzaWdudW0gPSAoZGlyZWN0aW9uID09PSAndXAnID8gLTEgOiArMSk7XG4gICAgdGhpcy5zY3JvbGxXaGlsZU1vdXNlRG93bih0aGlzLnRvVmlld3BvcnRQYW5QeChzaWdudW0gKiB0aGlzLnRodW1iU2l6ZSksIGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9qZWN0cyB0aGUgZ2l2ZW4gc2Nyb2xsYmFyIHNjcm9sbCBwaXhlbHMgaW50byB2aWV3cG9ydCBzY3JvbGwgcGl4ZWxzLlxuICAgKi9cbiAgcHJpdmF0ZSB0b1ZpZXdwb3J0UGFuUHgoc2Nyb2xsYmFyUGFuUHg6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3Qgc2Nyb2xsUmFuZ2VQeCA9IHRoaXMudHJhY2tTaXplIC0gdGhpcy50aHVtYlNpemU7XG4gICAgY29uc3Qgc2Nyb2xsUmF0aW8gPSBzY3JvbGxiYXJQYW5QeCAvIHNjcm9sbFJhbmdlUHg7XG4gICAgcmV0dXJuIHNjcm9sbFJhdGlvICogKHRoaXMudmlld3BvcnRDbGllbnRTaXplIC0gdGhpcy52aWV3cG9ydFNpemUpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmVzIHRoZSB2aWV3cG9ydCBjbGllbnQgYnkgdGhlIHNwZWNpZmllZCBudW1iZXJzIG9mIHBpeGVscy5cbiAgICovXG4gIHByaXZhdGUgbW92ZVZpZXdwb3J0Q2xpZW50KHZpZXdwb3J0UGFuUHg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLnZlcnRpY2FsKSB7XG4gICAgICB0aGlzLl92aWV3cG9ydC5zY3JvbGxUb3AgKz0gdmlld3BvcnRQYW5QeDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLl92aWV3cG9ydC5zY3JvbGxMZWZ0ICs9IHZpZXdwb3J0UGFuUHg7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyBpZiB0aGUgY29udGVudCBvdmVyZmxvd3MuXG4gICAqL1xuICBwdWJsaWMgZ2V0IG92ZXJmbG93KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9vdmVyZmxvdztcbiAgfVxuXG4gIC8qKlxuICAgKiBTY3JvbGxzIGNvbnRpbnVvdXNseSB3aGlsZSBob2xkaW5nIHRoZSBtb3VzZSBwcmVzc2VkLCBvciB1bnRpbCB0aGUgbW91c2UgbGVhdmVzIHRoZSBzY3JvbGx0cmFjay5cbiAgICovXG4gIHByaXZhdGUgc2Nyb2xsV2hpbGVNb3VzZURvd24odmlld3BvcnRTY3JvbGxQeDogbnVtYmVyLCBtb3VzZWRvd25FdmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIC8vIFRoZSBgRXZlbnRUYXJnZXRgIHR5cGUgb2YgYEV2ZW50LnRhcmdldGAgaXMgbm90IHlldCBjb21wYXRpYmxlIHdpdGggYEZyb21FdmVudFRhcmdldGAgdXNlZCBpbiBgZnJvbUV2ZW50YC5cbiAgICAvLyBUaGlzIHdpbGwgYmUgZml4ZWQgaW4gcnhqcyB2ZXJzaW9uIDcuMC4wLiBSZWZlciB0byBodHRwczovL2dpdGh1Yi5jb20vUmVhY3RpdmVYL3J4anMvY29tbWl0LzVmMDIyZDc4NDU3MDY4NDYzMmU2ZmQ1YWUyNDdmYzI1OWVlMzRjNGJcbiAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIGNvbnN0IHNjcm9sbFRyYWNrRWxlbWVudCA9IG1vdXNlZG93bkV2ZW50LnRhcmdldCBhcyBFbGVtZW50O1xuXG4gICAgLy8gc2Nyb2xsIGNvbnRpbnVvdXNseSBldmVyeSA1MG1zIGFmdGVyIGFuIGluaXRpYWwgZGVsYXkgb2YgMjUwbXNcbiAgICB0aW1lcigyNTAsIDUwKVxuICAgICAgLnBpcGUoXG4gICAgICAgIC8vIGNvbnRpbnVlIGNoYWluIHdpdGggbGF0ZXN0IG1vdXNlIGV2ZW50XG4gICAgICAgIHdpdGhMYXRlc3RGcm9tKG1lcmdlKG9mKG1vdXNlZG93bkV2ZW50KSwgZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KHNjcm9sbFRyYWNrRWxlbWVudCwgJ21vdXNlbW92ZScpKSwgKHRpY2ssIGV2ZW50KSA9PiBldmVudCksXG4gICAgICAgIC8vIHN0YXJ0IGltbWVkaWF0ZWx5XG4gICAgICAgIHN0YXJ0V2l0aChtb3VzZWRvd25FdmVudCksXG4gICAgICAgIC8vIHN0b3Agc2Nyb2xsaW5nIGlmIHRoZSB0aHVtYiBoaXRzIHRoZSBtb3VzZSBwb2ludGVyIHBvc2l0aW9uXG4gICAgICAgIHRha2VXaGlsZSgoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHNjcm9sbFRyYWNrRWxlbWVudCA9PT0gdGhpcy5fZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZKSksXG4gICAgICAgIGRlYm91bmNlVGltZSgxMCksXG4gICAgICAgIC8vIHN0b3Agc2Nyb2xsaW5nIG9uIG1vdXNlb3V0IG9yIG1vdXNldXBcbiAgICAgICAgdGFrZVVudGlsKG1lcmdlKGZyb21FdmVudChzY3JvbGxUcmFja0VsZW1lbnQsICdtb3VzZW91dCcpLCBmcm9tRXZlbnQoc2Nyb2xsVHJhY2tFbGVtZW50LCAnbW91c2V1cCcpKSksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5tb3ZlVmlld3BvcnRDbGllbnQodmlld3BvcnRTY3JvbGxQeCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyB3aGVuZXZlciB0aGUgdmlld3BvcnQgc2Nyb2xscy5cbiAgICovXG4gIHByaXZhdGUgdmlld3BvcnRTY3JvbGxDaGFuZ2UkKCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiBmcm9tRXZlbnQodGhpcy5fdmlld3BvcnQsICdzY3JvbGwnLCB7cGFzc2l2ZTogdHJ1ZX0pLnBpcGUobWFwKCgpID0+IHVuZGVmaW5lZCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIG9uIHN1YnNjcmlwdGlvbiwgYW5kIHRoZW4gZWFjaCB0aW1lIHRoZSBzaXplIG9mIHRoZSB2aWV3cG9ydCBjaGFuZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSB2aWV3cG9ydERpbWVuc2lvbkNoYW5nZSQob3B0aW9uczoge2RlYm91bmNlVGltZTogbnVtYmVyfSk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiBmcm9tRGltZW5zaW9uJCh0aGlzLl92aWV3cG9ydClcbiAgICAgIC5waXBlKFxuICAgICAgICAvLyBEZWJvdW5jaW5nIGlzIHBhcnRpY3VsYXJseSBpbXBvcnRhbnQgaW4gdGhlIGNvbnRleHQgb2YgQW5ndWxhciBhbmltYXRpb25zLCBzaW5jZSB0aGV5IGNvbnRpbnVvdXNseVxuICAgICAgICAvLyB0cmlnZ2VyIHJlc2l6ZSBldmVudHMuIERlYm91bmNpbmcgcHJldmVudHMgdGhlIHNjcm9sbGJhciBmcm9tIGZsaWNrZXJpbmcsIGZvciBleGFtcGxlLCB3aGVuIHRoZSB1c2VyXG4gICAgICAgIC8vIGV4cGFuZHMgYSBwYW5lbCB0aGF0IGNvbnRhaW5zIGEgdmlld3BvcnQuXG4gICAgICAgIGRlYm91bmNlVGltZShvcHRpb25zLmRlYm91bmNlVGltZSksXG4gICAgICAgIG1hcCgoKSA9PiB1bmRlZmluZWQpLFxuICAgICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyBvbiBzdWJzY3JpcHRpb24sIGFuZCB0aGVuIGVhY2ggdGltZSB0aGUgc2l6ZSBvciBzdHlsZSBwcm9wZXJ0eSBvZiB0aGUgdmlld3BvcnQgY2xpZW50IGNoYW5nZXMuXG4gICAqL1xuICBwcml2YXRlIHZpZXdwb3J0Q2xpZW50RGltZW5zaW9uQ2hhbmdlJChvcHRpb25zOiB7ZGVib3VuY2VUaW1lOiBudW1iZXJ9KTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW4kKHRoaXMuX3ZpZXdwb3J0KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcChjaGlsZHJlbiA9PiBtZXJnZSguLi5jaGlsZHJlbi5tYXAoY2hpbGQgPT4gbWVyZ2UoXG4gICAgICAgICAgZnJvbURpbWVuc2lvbiQoY2hpbGQpLFxuICAgICAgICAgIC8vIE9ic2VydmUgc3R5bGUgbXV0YXRpb25zIHNpbmNlIHNvbWUgdHJhbnNmb3JtYXRpb25zIGNoYW5nZSB0aGUgc2Nyb2xsIHBvc2l0aW9uIHdpdGhvdXQgbmVjZXNzYXJpbHkgdHJpZ2dlcmluZyBhIGRpbWVuc2lvbiBjaGFuZ2UsXG4gICAgICAgICAgLy8gZS5nLiwgYHNjYWxlYCBvciBgdHJhbnNsYXRlYCB1c2VkIGJ5IHNvbWUgdmlydHVhbCBzY3JvbGwgaW1wbGVtZW50YXRpb25zXG4gICAgICAgICAgZnJvbU11dGF0aW9uJChjaGlsZCwge3N1YnRyZWU6IGZhbHNlLCBjaGlsZExpc3Q6IGZhbHNlLCBhdHRyaWJ1dGVGaWx0ZXI6IFsnc3R5bGUnXX0pKSxcbiAgICAgICAgKSkpLFxuICAgICAgICAvLyBEZWJvdW5jaW5nIGlzIHBhcnRpY3VsYXJseSBpbXBvcnRhbnQgaW4gdGhlIGNvbnRleHQgb2YgQW5ndWxhciBhbmltYXRpb25zLCBzaW5jZSB0aGV5IGNvbnRpbnVvdXNseVxuICAgICAgICAvLyB0cmlnZ2VyIHJlc2l6ZSBldmVudHMuIERlYm91bmNpbmcgcHJldmVudHMgdGhlIHNjcm9sbGJhciBmcm9tIGZsaWNrZXJpbmcsIGZvciBleGFtcGxlLCB3aGVuIHRoZSB1c2VyXG4gICAgICAgIC8vIGV4cGFuZHMgYSBwYW5lbCB0aGF0IGNvbnRhaW5zIGEgdmlld3BvcnQuXG4gICAgICAgIGRlYm91bmNlVGltZShvcHRpb25zLmRlYm91bmNlVGltZSksXG4gICAgICAgIG1hcCgoKSA9PiB1bmRlZmluZWQpLFxuICAgICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgY2hpbGRyZW4gb2YgdGhlIHBhc3NlZCBlbGVtZW50LCBhbmQgdGhlbiBlYWNoIHRpbWUgY2hpbGQgZWxlbWVudHMgYXJlIGFkZGVkIG9yIHJlbW92ZWQuXG4gICAqL1xuICBwcml2YXRlIGNoaWxkcmVuJChlbGVtZW50OiBIVE1MRWxlbWVudCk6IE9ic2VydmFibGU8SFRNTEVsZW1lbnRbXT4ge1xuICAgIHJldHVybiBmcm9tTXV0YXRpb24kKGVsZW1lbnQsIHtzdWJ0cmVlOiBmYWxzZSwgY2hpbGRMaXN0OiB0cnVlfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBzdGFydFdpdGgodW5kZWZpbmVkIGFzIHZvaWQpLFxuICAgICAgICBtYXAoKCkgPT4gQXJyYXkuZnJvbShlbGVtZW50LmNoaWxkcmVuKSksXG4gICAgICAgIGZpbHRlckFycmF5KChjaGlsZDogRWxlbWVudCk6IGNoaWxkIGlzIEhUTUxFbGVtZW50ID0+IGNoaWxkIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpLFxuICAgICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0Q3NzVmFyaWFibGUoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLl9ob3N0Lm5hdGl2ZUVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIGdldCB2aWV3cG9ydFNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fdmlld3BvcnQgPyAodGhpcy52ZXJ0aWNhbCA/IHRoaXMuX3ZpZXdwb3J0LmNsaWVudEhlaWdodCA6IHRoaXMuX3ZpZXdwb3J0LmNsaWVudFdpZHRoKSA6IDA7XG4gIH1cblxuICBwcml2YXRlIGdldCB2aWV3cG9ydENsaWVudFNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fdmlld3BvcnQgPyAodGhpcy52ZXJ0aWNhbCA/IHRoaXMuX3ZpZXdwb3J0LnNjcm9sbEhlaWdodCA6IHRoaXMuX3ZpZXdwb3J0LnNjcm9sbFdpZHRoKSA6IDA7XG4gIH1cblxuICBwcml2YXRlIGdldCBzY3JvbGxQb3NpdGlvbigpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl92aWV3cG9ydCA/ICh0aGlzLnZlcnRpY2FsID8gdGhpcy5fdmlld3BvcnQuc2Nyb2xsVG9wIDogdGhpcy5fdmlld3BvcnQuc2Nyb2xsTGVmdCkgOiAwO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgdGh1bWJTaXplKCk6IG51bWJlciB7XG4gICAgY29uc3QgdGh1bWJFbGVtZW50ID0gdGhpcy50aHVtYkVsZW1lbnQubmF0aXZlRWxlbWVudDtcbiAgICByZXR1cm4gdGhpcy52ZXJ0aWNhbCA/IHRodW1iRWxlbWVudC5jbGllbnRIZWlnaHQgOiB0aHVtYkVsZW1lbnQuY2xpZW50V2lkdGg7XG4gIH1cblxuICBwcml2YXRlIGdldCB0cmFja1NpemUoKTogbnVtYmVyIHtcbiAgICBjb25zdCB0cmFja0VsZW1lbnQgPSB0aGlzLl9ob3N0Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgcmV0dXJuIHRoaXMudmVydGljYWwgPyB0cmFja0VsZW1lbnQuY2xpZW50SGVpZ2h0IDogdHJhY2tFbGVtZW50LmNsaWVudFdpZHRoO1xuICB9XG5cbiAgLyogQGRvY3MtcHJpdmF0ZSAqL1xuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5fZGVzdHJveSQubmV4dCgpO1xuICB9XG59XG4iLCI8IS0tIHNjcm9sbHRyYWNrIHRvIG1vdmUgdGhlIHZpZXdwb3J0IGNsaWVudCB1cHdhcmRzIChwYWdpbmcpIC0tPlxuPGRpdiBjbGFzcz1cInNjcm9sbHRyYWNrLXN0YXJ0XCIgKG1vdXNlZG93bik9XCJvblNjcm9sbFRyYWNrTW91c2VEb3duKCRldmVudCwgJ3VwJylcIj48L2Rpdj5cblxuPCEtLSBzY3JvbGx0aHVtYiAtLT5cbjxkaXYgI3RodW1iX2hhbmRsZVxuICAgICBjbGFzcz1cInRodW1iLWhhbmRsZVwiXG4gICAgIFtjbGFzcy52ZXJ0aWNhbF09XCJ2ZXJ0aWNhbFwiXG4gICAgIFtjbGFzcy5ob3Jpem9udGFsXT1cImhvcml6b250YWxcIlxuICAgICAobW91c2Vkb3duKT1cIm9uTW91c2VEb3duKCRldmVudClcIlxuICAgICAodG91Y2hzdGFydCk9XCJvblRvdWNoU3RhcnQoJGV2ZW50KVwiXG4gICAgICh0b3VjaG1vdmUpPVwib25Ub3VjaE1vdmUoJGV2ZW50KVwiXG4gICAgICh0b3VjaGVuZCk9XCJvblRvdWNoRW5kKCRldmVudClcIlxuICAgICAodG91Y2hjYW5jZWwpPVwib25Ub3VjaEVuZCgkZXZlbnQpXCI+XG4gIDxkaXYgY2xhc3M9XCJ0aHVtYlwiXG4gICAgICAgW2NsYXNzLnZlcnRpY2FsXT1cInZlcnRpY2FsXCJcbiAgICAgICBbY2xhc3MuaG9yaXpvbnRhbF09XCJob3Jpem9udGFsXCI+XG4gIDwvZGl2PlxuPC9kaXY+XG5cbjwhLS0gc2Nyb2xsdHJhY2sgdG8gbW92ZSB0aGUgdmlld3BvcnQgY2xpZW50IGRvd253YXJkcyAocGFnaW5nKSAtLT5cbjxkaXYgY2xhc3M9XCJzY3JvbGx0cmFjay1lbmRcIiAobW91c2Vkb3duKT1cIm9uU2Nyb2xsVHJhY2tNb3VzZURvd24oJGV2ZW50LCAnZG93bicpXCI+PC9kaXY+XG4iXX0=