@ethlete/core 4.23.8 → 4.24.1

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 (143) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/fesm2022/ethlete-core.mjs +131 -139
  3. package/fesm2022/ethlete-core.mjs.map +1 -1
  4. package/lib/types/angular.types.d.ts +0 -1
  5. package/lib/utils/signal.utils.d.ts +5 -0
  6. package/package.json +7 -9
  7. package/esm2022/ethlete-core.mjs +0 -5
  8. package/esm2022/index.mjs +0 -38
  9. package/esm2022/lib/components/structured-data/index.mjs +0 -2
  10. package/esm2022/lib/components/structured-data/structured-data.component.mjs +0 -37
  11. package/esm2022/lib/constants/index.mjs +0 -2
  12. package/esm2022/lib/constants/viewport.constants.mjs +0 -17
  13. package/esm2022/lib/decorators/memo/index.mjs +0 -2
  14. package/esm2022/lib/decorators/memo/memo.decorator.mjs +0 -25
  15. package/esm2022/lib/directives/animatable/animatable.directive.mjs +0 -121
  16. package/esm2022/lib/directives/animatable/index.mjs +0 -2
  17. package/esm2022/lib/directives/animated-if/animated-if.directive.mjs +0 -54
  18. package/esm2022/lib/directives/animated-if/index.mjs +0 -2
  19. package/esm2022/lib/directives/animated-lifecycle/animated-lifecycle.directive.mjs +0 -136
  20. package/esm2022/lib/directives/animated-lifecycle/index.mjs +0 -2
  21. package/esm2022/lib/directives/animated-overlay/animated-overlay.directive.mjs +0 -344
  22. package/esm2022/lib/directives/animated-overlay/index.mjs +0 -2
  23. package/esm2022/lib/directives/click-outside/click-outside.directive.mjs +0 -37
  24. package/esm2022/lib/directives/click-outside/index.mjs +0 -2
  25. package/esm2022/lib/directives/cursor-drag-scroll/cursor-drag-scroll.constants.mjs +0 -3
  26. package/esm2022/lib/directives/cursor-drag-scroll/cursor-drag-scroll.directive.mjs +0 -170
  27. package/esm2022/lib/directives/cursor-drag-scroll/index.mjs +0 -3
  28. package/esm2022/lib/directives/debug/debug.directive.mjs +0 -44
  29. package/esm2022/lib/directives/debug/index.mjs +0 -2
  30. package/esm2022/lib/directives/delayable/delayable.directive.mjs +0 -55
  31. package/esm2022/lib/directives/delayable/index.mjs +0 -2
  32. package/esm2022/lib/directives/is-active-element/index.mjs +0 -2
  33. package/esm2022/lib/directives/is-active-element/is-active-element.directive.mjs +0 -33
  34. package/esm2022/lib/directives/is-element/index.mjs +0 -2
  35. package/esm2022/lib/directives/is-element/is-element.directive.mjs +0 -33
  36. package/esm2022/lib/directives/let/index.mjs +0 -3
  37. package/esm2022/lib/directives/let/let.directive.mjs +0 -40
  38. package/esm2022/lib/directives/let/let.types.mjs +0 -9
  39. package/esm2022/lib/directives/observe-content/index.mjs +0 -2
  40. package/esm2022/lib/directives/observe-content/observe-content.directive.mjs +0 -72
  41. package/esm2022/lib/directives/observe-resize/index.mjs +0 -2
  42. package/esm2022/lib/directives/observe-resize/observe-resize.directive.mjs +0 -72
  43. package/esm2022/lib/directives/observe-scroll-state/index.mjs +0 -4
  44. package/esm2022/lib/directives/observe-scroll-state/observe-scroll-state.constants.mjs +0 -3
  45. package/esm2022/lib/directives/observe-scroll-state/observe-scroll-state.directive.mjs +0 -180
  46. package/esm2022/lib/directives/observe-scroll-state/observe-scroll-state.types.mjs +0 -2
  47. package/esm2022/lib/directives/observe-visibility/index.mjs +0 -2
  48. package/esm2022/lib/directives/observe-visibility/observe-visibility.directive.mjs +0 -80
  49. package/esm2022/lib/directives/repeat/index.mjs +0 -2
  50. package/esm2022/lib/directives/repeat/repeat.directive.mjs +0 -35
  51. package/esm2022/lib/directives/root-boundary/index.mjs +0 -2
  52. package/esm2022/lib/directives/root-boundary/root-boundary.directive.mjs +0 -36
  53. package/esm2022/lib/directives/scroll-observer-first-element/index.mjs +0 -2
  54. package/esm2022/lib/directives/scroll-observer-first-element/scroll-observer-first-element.directive.mjs +0 -24
  55. package/esm2022/lib/directives/scroll-observer-ignore-target/index.mjs +0 -2
  56. package/esm2022/lib/directives/scroll-observer-ignore-target/scroll-observer-ignore-target.directive.mjs +0 -18
  57. package/esm2022/lib/directives/scroll-observer-last-element/index.mjs +0 -2
  58. package/esm2022/lib/directives/scroll-observer-last-element/scroll-observer-last-element.directive.mjs +0 -27
  59. package/esm2022/lib/directives/seo/index.mjs +0 -5
  60. package/esm2022/lib/directives/seo/seo.directive.constants.mjs +0 -3
  61. package/esm2022/lib/directives/seo/seo.directive.mjs +0 -166
  62. package/esm2022/lib/directives/seo/seo.directive.types.mjs +0 -2
  63. package/esm2022/lib/directives/seo/seo.directive.utils.mjs +0 -7
  64. package/esm2022/lib/pipes/infer-mime-type/index.mjs +0 -3
  65. package/esm2022/lib/pipes/infer-mime-type/infer-mime-type.pipe.mjs +0 -18
  66. package/esm2022/lib/pipes/infer-mime-type/infer-mime-type.util.mjs +0 -196
  67. package/esm2022/lib/pipes/normalize-game-result-type/index.mjs +0 -4
  68. package/esm2022/lib/pipes/normalize-game-result-type/normalize-game-result-type.pipe.mjs +0 -15
  69. package/esm2022/lib/pipes/normalize-game-result-type/normalize-game-result-type.types.mjs +0 -2
  70. package/esm2022/lib/pipes/normalize-game-result-type/normalize-game-result-type.util.mjs +0 -34
  71. package/esm2022/lib/pipes/normalize-match-participants/index.mjs +0 -4
  72. package/esm2022/lib/pipes/normalize-match-participants/normalize-match-participants.pipe.mjs +0 -15
  73. package/esm2022/lib/pipes/normalize-match-participants/normalize-match-participants.types.mjs +0 -2
  74. package/esm2022/lib/pipes/normalize-match-participants/normalize-match-participants.util.mjs +0 -47
  75. package/esm2022/lib/pipes/normalize-match-score/index.mjs +0 -4
  76. package/esm2022/lib/pipes/normalize-match-score/normalize-match-score.pipe.mjs +0 -15
  77. package/esm2022/lib/pipes/normalize-match-score/normalize-match-score.types.mjs +0 -2
  78. package/esm2022/lib/pipes/normalize-match-score/normalize-match-score.util.mjs +0 -126
  79. package/esm2022/lib/pipes/normalize-match-state/index.mjs +0 -4
  80. package/esm2022/lib/pipes/normalize-match-state/normalize-match-state.constants.mjs +0 -2
  81. package/esm2022/lib/pipes/normalize-match-state/normalize-match-state.pipe.mjs +0 -15
  82. package/esm2022/lib/pipes/normalize-match-state/normalize-match-state.util.mjs +0 -19
  83. package/esm2022/lib/pipes/normalize-match-type/index.mjs +0 -3
  84. package/esm2022/lib/pipes/normalize-match-type/normalize-match-type.pipe.mjs +0 -15
  85. package/esm2022/lib/pipes/normalize-match-type/normalize-match-type.util.mjs +0 -38
  86. package/esm2022/lib/pipes/to-array/index.mjs +0 -3
  87. package/esm2022/lib/pipes/to-array/to-array.pipe.mjs +0 -15
  88. package/esm2022/lib/pipes/to-array/to-array.util.mjs +0 -5
  89. package/esm2022/lib/props/create-prop-handlers.mjs +0 -17
  90. package/esm2022/lib/props/create-props.mjs +0 -53
  91. package/esm2022/lib/props/create-setup.mjs +0 -19
  92. package/esm2022/lib/props/dependency-stash.mjs +0 -20
  93. package/esm2022/lib/props/element-dictionary.mjs +0 -44
  94. package/esm2022/lib/props/index.mjs +0 -9
  95. package/esm2022/lib/props/props-binding.mjs +0 -53
  96. package/esm2022/lib/props/props.directive.mjs +0 -35
  97. package/esm2022/lib/props/template-input.mjs +0 -41
  98. package/esm2022/lib/services/click-observer.service.mjs +0 -73
  99. package/esm2022/lib/services/content-observer.service.mjs +0 -79
  100. package/esm2022/lib/services/focus-visible.service.mjs +0 -34
  101. package/esm2022/lib/services/index.mjs +0 -9
  102. package/esm2022/lib/services/intersection-observer.service.mjs +0 -75
  103. package/esm2022/lib/services/resize-observer.service.mjs +0 -75
  104. package/esm2022/lib/services/router-state.service.mjs +0 -205
  105. package/esm2022/lib/services/viewport.service.mjs +0 -244
  106. package/esm2022/lib/services/viewport.types.mjs +0 -2
  107. package/esm2022/lib/types/angular.types.mjs +0 -15
  108. package/esm2022/lib/types/i18n.types.mjs +0 -2
  109. package/esm2022/lib/types/index.mjs +0 -5
  110. package/esm2022/lib/types/value.types.mjs +0 -2
  111. package/esm2022/lib/types/viewport.types.mjs +0 -2
  112. package/esm2022/lib/utils/active-selection-model.utils.mjs +0 -91
  113. package/esm2022/lib/utils/angular.utils.mjs +0 -7
  114. package/esm2022/lib/utils/animation.utils.mjs +0 -113
  115. package/esm2022/lib/utils/clamp.util.mjs +0 -4
  116. package/esm2022/lib/utils/clone.util.mjs +0 -78
  117. package/esm2022/lib/utils/component-id.utils.mjs +0 -7
  118. package/esm2022/lib/utils/cookie.util.mjs +0 -53
  119. package/esm2022/lib/utils/destroy.utils.mjs +0 -13
  120. package/esm2022/lib/utils/equal.util.mjs +0 -118
  121. package/esm2022/lib/utils/form.utils.mjs +0 -63
  122. package/esm2022/lib/utils/index.mjs +0 -27
  123. package/esm2022/lib/utils/inject.utils.mjs +0 -4
  124. package/esm2022/lib/utils/intersection-observer.utils.mjs +0 -65
  125. package/esm2022/lib/utils/key-press-manager.utils.mjs +0 -30
  126. package/esm2022/lib/utils/media-query-observable.util.mjs +0 -18
  127. package/esm2022/lib/utils/mutation-observable.util.mjs +0 -42
  128. package/esm2022/lib/utils/object.utils.mjs +0 -30
  129. package/esm2022/lib/utils/reactive-binding.util.mjs +0 -124
  130. package/esm2022/lib/utils/resize-observable.util.mjs +0 -12
  131. package/esm2022/lib/utils/round.utils.mjs +0 -5
  132. package/esm2022/lib/utils/runtime-error.utils.mjs +0 -31
  133. package/esm2022/lib/utils/scrollable.utils.mjs +0 -157
  134. package/esm2022/lib/utils/selection-model.utils.mjs +0 -376
  135. package/esm2022/lib/utils/signal.utils.mjs +0 -1004
  136. package/esm2022/lib/utils/smart-block-scroll-strategy.utils.mjs +0 -96
  137. package/esm2022/lib/utils/value.utils.mjs +0 -22
  138. package/esm2022/lib/utils/viewport.util.mjs +0 -5
  139. package/esm2022/lib/validators/at-least-one-required.validator.mjs +0 -20
  140. package/esm2022/lib/validators/index.mjs +0 -15
  141. package/esm2022/lib/validators/is-array-not-empty.validator.mjs +0 -9
  142. package/esm2022/lib/validators/is-email.validator.mjs +0 -10
  143. package/esm2022/lib/validators/must-match.validator.mjs +0 -19
@@ -1,1004 +0,0 @@
1
- import { coerceElement } from '@angular/cdk/coercion';
2
- import { DOCUMENT } from '@angular/common';
3
- import { DestroyRef, ElementRef, Injector, NgZone, QueryList, Renderer2, RendererStyleFlags2, afterNextRender, computed, effect, inject, isDevMode, isSignal, runInInjectionContext, signal, untracked, } from '@angular/core';
4
- import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
5
- import { NavigationEnd, Router } from '@angular/router';
6
- import { Observable, debounceTime, distinctUntilChanged, filter, fromEvent, map, merge, of, pairwise, startWith, switchMap, take, takeUntil, tap, } from 'rxjs';
7
- import { ET_PROPERTY_REMOVED, ViewportService } from '../services';
8
- import { nextFrame } from './animation.utils';
9
- import { equal } from './equal.util';
10
- import { isElementVisible } from './scrollable.utils';
11
- function isElementSignal(el) {
12
- if (isSignal(el)) {
13
- const val = el();
14
- return typeof val === 'object' && val !== null && 'currentElement' in val && 'previousElement' in val;
15
- }
16
- return false;
17
- }
18
- const documentElementSignal = () => signal({
19
- currentElement: document.documentElement,
20
- previousElement: null,
21
- currentElements: [document.documentElement],
22
- previousElements: [],
23
- });
24
- const buildElementSignal = (el) => {
25
- if (el === null || el === undefined) {
26
- return signal({ currentElement: null, previousElement: null, currentElements: [], previousElements: [] });
27
- }
28
- if (isElementSignal(el)) {
29
- return el;
30
- }
31
- let mElSignal = null;
32
- const switchElement = () => switchMap((elOrRef) => {
33
- if (elOrRef instanceof QueryList) {
34
- return elOrRef.changes.pipe(startWith(elOrRef), map(() => elOrRef.toArray().map((r) => coerceElement(r))));
35
- }
36
- else if (Array.isArray(elOrRef)) {
37
- return of(elOrRef.map((r) => coerceElement(r)));
38
- }
39
- else {
40
- const coercedEl = coerceElement(elOrRef);
41
- return of(coercedEl ? [coercedEl] : null);
42
- }
43
- });
44
- if (el instanceof Observable) {
45
- mElSignal = toSignal(el.pipe(switchElement()), { initialValue: null });
46
- }
47
- else if (isSignal(el)) {
48
- mElSignal = toSignal(toObservable(el).pipe(switchElement()), { initialValue: null });
49
- }
50
- else if (el instanceof QueryList) {
51
- mElSignal = toSignal(el.changes.pipe(startWith(el), map(() => el.toArray().map((r) => coerceElement(r)))), { initialValue: null });
52
- }
53
- else {
54
- mElSignal = signal([coerceElement(el)]);
55
- }
56
- const elSig = toSignal(toObservable(mElSignal).pipe(startWith(null), pairwise(), map(([previousElements, currentElements]) => ({
57
- previousElements: previousElements ?? [],
58
- currentElements: currentElements ?? [],
59
- currentElement: currentElements?.[0] ?? null,
60
- previousElement: previousElements?.[0] ?? null,
61
- }))), { initialValue: { currentElement: null, previousElement: null, previousElements: [], currentElements: [] } });
62
- return computed(() => elSig(), {
63
- equal: (a, b) => a.currentElement === b.currentElement &&
64
- a.previousElement === b.previousElement &&
65
- a.currentElements.length === b.currentElements.length &&
66
- a.currentElements.every((v, i) => v === b.currentElements[i]) &&
67
- a.previousElements.length === b.previousElements.length &&
68
- a.previousElements.every((v, i) => v === b.previousElements[i]),
69
- });
70
- };
71
- const firstElementSignal = (el) => {
72
- return computed(() => {
73
- const current = el();
74
- if (current.currentElements.length > 1) {
75
- console.warn('More than one element is bound to the signal. Only the first element will be used.', current.currentElements);
76
- }
77
- const curr = current.currentElements[0] ?? null;
78
- const prev = current.previousElements[0] ?? null;
79
- return { currentElement: curr, previousElement: prev };
80
- }, { equal: (a, b) => a.currentElement === b.currentElement && a.previousElement === b.previousElement });
81
- };
82
- export const buildSignalEffects = (el, config) => {
83
- const elements = buildElementSignal(el);
84
- const injector = inject(Injector);
85
- effect(() => {
86
- const { currentElements, previousElements } = elements();
87
- for (const previousEl of previousElements) {
88
- if (currentElements.includes(previousEl))
89
- continue;
90
- const tokens = Object.keys(config.tokenMap)
91
- .map((key) => key.split(' '))
92
- .flat();
93
- if (!tokens.length)
94
- continue;
95
- config.cleanupFn(previousEl, tokens);
96
- }
97
- for (const currentEl of currentElements) {
98
- if (previousElements.includes(currentEl))
99
- continue;
100
- for (const [tokens, condition] of Object.entries(config.tokenMap)) {
101
- untracked(() => {
102
- const tokenArray = tokens.split(' ');
103
- if (!tokenArray.length)
104
- return;
105
- config.updateFn(currentEl, tokenArray, condition());
106
- });
107
- }
108
- }
109
- });
110
- const effects = {};
111
- const has = (tokens) => tokens in effects;
112
- const push = (tokens, signal) => {
113
- if (has(tokens))
114
- return;
115
- runInInjectionContext(injector, () => {
116
- effects[tokens] = effect(() => {
117
- const { currentElements } = untracked(() => elements());
118
- const value = signal();
119
- for (const el of currentElements) {
120
- const tokenArray = tokens.split(' ');
121
- if (!tokenArray.length)
122
- continue;
123
- config.updateFn(el, tokenArray, value);
124
- }
125
- });
126
- });
127
- };
128
- const pushMany = (map) => {
129
- for (const [tokens, signal] of Object.entries(map)) {
130
- push(tokens, signal);
131
- }
132
- };
133
- const remove = (tokens) => {
134
- effects[tokens]?.destroy();
135
- delete effects[tokens];
136
- for (const el of elements().currentElements) {
137
- const tokenArray = tokens.split(' ');
138
- if (!tokenArray.length)
139
- continue;
140
- config.cleanupFn(el, tokenArray);
141
- }
142
- };
143
- const removeMany = (tokens) => {
144
- for (const token of tokens) {
145
- remove(token);
146
- }
147
- };
148
- pushMany(config.tokenMap);
149
- return { remove, removeMany, has, push, pushMany };
150
- };
151
- export const signalIsRendered = () => {
152
- const isRendered = signal(false);
153
- afterNextRender(() => isRendered.set(true));
154
- return isRendered.asReadonly();
155
- };
156
- export const signalClasses = (el, classMap) => {
157
- const renderer = inject(Renderer2);
158
- return buildSignalEffects(el, {
159
- tokenMap: classMap,
160
- cleanupFn: (el, tokens) => tokens.forEach((token) => renderer.removeClass(el, token)),
161
- updateFn: (el, tokens, condition) => {
162
- if (!condition) {
163
- tokens.forEach((token) => renderer.removeClass(el, token));
164
- }
165
- else {
166
- tokens.forEach((token) => renderer.addClass(el, token));
167
- }
168
- },
169
- });
170
- };
171
- export const signalHostClasses = (classMap) => signalClasses(inject(ElementRef), classMap);
172
- const ALWAYS_TRUE_ATTRIBUTE_KEYS = ['disabled', 'readonly', 'required', 'checked', 'selected', 'hidden', 'inert'];
173
- export const signalAttributes = (el, attributeMap) => {
174
- const renderer = inject(Renderer2);
175
- return buildSignalEffects(el, {
176
- tokenMap: attributeMap,
177
- cleanupFn: (el, tokens) => tokens.forEach((token) => el.removeAttribute(token)),
178
- updateFn: (el, tokens, condition) => {
179
- for (const token of tokens) {
180
- if (ALWAYS_TRUE_ATTRIBUTE_KEYS.includes(token)) {
181
- if (condition) {
182
- renderer.setAttribute(el, token, '');
183
- }
184
- else {
185
- renderer.removeAttribute(el, token);
186
- }
187
- continue;
188
- }
189
- if (condition === null || condition === undefined) {
190
- renderer.removeAttribute(el, token);
191
- }
192
- else {
193
- renderer.setAttribute(el, token, `${condition}`);
194
- }
195
- }
196
- },
197
- });
198
- };
199
- export const signalHostAttributes = (attributeMap) => signalAttributes(inject(ElementRef), attributeMap);
200
- export const signalStyles = (el, styleMap) => {
201
- const renderer = inject(Renderer2);
202
- return buildSignalEffects(el, {
203
- tokenMap: styleMap,
204
- cleanupFn: (el, tokens) => tokens.forEach((token) => renderer.removeStyle(el, token, RendererStyleFlags2.DashCase)),
205
- updateFn: (el, tokens, condition) => {
206
- for (const token of tokens) {
207
- if (condition === null || condition === undefined) {
208
- renderer.removeStyle(el, token, RendererStyleFlags2.DashCase);
209
- }
210
- else {
211
- renderer.setStyle(el, token, `${condition}`, RendererStyleFlags2.DashCase);
212
- }
213
- }
214
- },
215
- });
216
- };
217
- export const signalHostStyles = (styleMap) => signalStyles(inject(ElementRef), styleMap);
218
- export const boundingClientRectToElementRect = (rect) => ({
219
- bottom: rect.bottom,
220
- height: rect.height,
221
- left: rect.left,
222
- right: rect.right,
223
- top: rect.top,
224
- width: rect.width,
225
- x: rect.x,
226
- y: rect.y,
227
- });
228
- export const createElementDimensions = (el, rect) => {
229
- if (!el) {
230
- return {
231
- rect: null,
232
- client: null,
233
- scroll: null,
234
- offset: null,
235
- };
236
- }
237
- const cachedNormalizedRect = rect ? boundingClientRectToElementRect(rect) : null;
238
- const rectFn = () => cachedNormalizedRect ? cachedNormalizedRect : boundingClientRectToElementRect(el.getBoundingClientRect());
239
- return {
240
- rect: rectFn,
241
- client: { width: el.clientWidth, height: el.clientHeight },
242
- scroll: { width: el.scrollWidth, height: el.scrollHeight },
243
- offset: { width: el.offsetWidth, height: el.offsetHeight },
244
- };
245
- };
246
- export const signalElementDimensions = (el) => {
247
- const destroyRef = inject(DestroyRef);
248
- const elements = buildElementSignal(el);
249
- const zone = inject(NgZone);
250
- const isRendered = signalIsRendered();
251
- const initialValue = () => createElementDimensions(elements().currentElement);
252
- const elementDimensionsSignal = signal(initialValue());
253
- const observer = new ResizeObserver((e) => {
254
- if (!isRendered())
255
- return;
256
- const entry = e[0];
257
- if (entry) {
258
- const target = entry.target;
259
- const newDimensions = createElementDimensions(target);
260
- zone.run(() => elementDimensionsSignal.set(newDimensions));
261
- }
262
- });
263
- effect(() => {
264
- const els = elements();
265
- untracked(() => {
266
- elementDimensionsSignal.set(initialValue());
267
- if (els.previousElement) {
268
- observer.disconnect();
269
- }
270
- if (els.currentElement) {
271
- const computedDisplay = getComputedStyle(els.currentElement).display;
272
- const currentElIsAngularComponent = els.currentElement?.tagName.toLowerCase().includes('-');
273
- if (computedDisplay === 'inline' && isDevMode() && currentElIsAngularComponent) {
274
- console.error(`Element <${els.currentElement?.tagName.toLowerCase()}> is an Angular component and has a display of 'inline'. Inline elements cannot be observed for dimensions. Please change it to 'block' or something else.`);
275
- }
276
- observer.observe(els.currentElement);
277
- }
278
- });
279
- }, { allowSignalWrites: true });
280
- destroyRef.onDestroy(() => observer.disconnect());
281
- return computed(() => elementDimensionsSignal(), {
282
- equal: (a, b) => equal(a, b),
283
- });
284
- };
285
- export const signalHostElementDimensions = () => signalElementDimensions(inject(ElementRef));
286
- export const signalElementMutations = (el, options) => {
287
- const destroyRef = inject(DestroyRef);
288
- const elements = buildElementSignal(el);
289
- const zone = inject(NgZone);
290
- const isRendered = signalIsRendered();
291
- const elementMutationsSignal = signal(null);
292
- const observer = new MutationObserver((e) => {
293
- if (!isRendered())
294
- return;
295
- const entry = e[0];
296
- if (entry) {
297
- zone.run(() => elementMutationsSignal.set(entry));
298
- }
299
- });
300
- effect(() => {
301
- const els = elements();
302
- elementMutationsSignal.set(null);
303
- if (els.previousElement) {
304
- observer.disconnect();
305
- }
306
- if (els.currentElement) {
307
- observer.observe(els.currentElement, options);
308
- }
309
- }, { allowSignalWrites: true });
310
- destroyRef.onDestroy(() => observer.disconnect());
311
- return elementMutationsSignal.asReadonly();
312
- };
313
- export const signalHostElementMutations = (options) => signalElementMutations(inject(ElementRef), options);
314
- export const areScrollStatesEqual = (a, b) => {
315
- return (a.canScroll === b.canScroll &&
316
- a.canScrollHorizontally === b.canScrollHorizontally &&
317
- a.canScrollVertically === b.canScrollVertically &&
318
- equal(a.elementDimensions, b.elementDimensions));
319
- };
320
- export const signalElementScrollState = (el, options) => {
321
- const elements = buildElementSignal(el);
322
- const observedEl = firstElementSignal(elements);
323
- const elementDimensions = signalElementDimensions(elements);
324
- const elementMutations = signalElementMutations(elements, { childList: true, subtree: true, attributes: true });
325
- const isRendered = signalIsRendered();
326
- const initialScrollPosition = options?.initialScrollPosition;
327
- if (initialScrollPosition) {
328
- const ref = effect(() => {
329
- if (!isRendered())
330
- return;
331
- const scrollPosition = initialScrollPosition();
332
- const element = observedEl().currentElement;
333
- if (scrollPosition && element) {
334
- if (scrollPosition.left !== undefined)
335
- element.scrollLeft = scrollPosition.left;
336
- if (scrollPosition.top !== undefined)
337
- element.scrollTop = scrollPosition.top;
338
- ref.destroy();
339
- }
340
- });
341
- }
342
- const notScrollable = (dimensions) => ({
343
- canScroll: false,
344
- canScrollHorizontally: false,
345
- canScrollVertically: false,
346
- elementDimensions: dimensions,
347
- });
348
- return computed(() => {
349
- const element = observedEl().currentElement;
350
- const dimensions = elementDimensions();
351
- // We are not interested what the mutation is, just that there is one.
352
- // Changes to the DOM can affect the scroll state of the element.
353
- elementMutations();
354
- if (!element || !isRendered())
355
- return notScrollable(dimensions);
356
- const { scrollWidth, scrollHeight, clientHeight, clientWidth } = element;
357
- const canScrollHorizontally = scrollWidth > clientWidth;
358
- const canScrollVertically = scrollHeight > clientHeight;
359
- return {
360
- canScroll: canScrollHorizontally || canScrollVertically,
361
- canScrollHorizontally,
362
- canScrollVertically,
363
- elementDimensions: dimensions,
364
- };
365
- }, { equal: (a, b) => areScrollStatesEqual(a, b) });
366
- };
367
- export const signalHostElementScrollState = () => signalElementScrollState(inject(ElementRef));
368
- export const signalElementIntersection = (el, options) => {
369
- const destroyRef = inject(DestroyRef);
370
- const elements = buildElementSignal(el);
371
- const root = firstElementSignal(options?.root ? buildElementSignal(options?.root) : documentElementSignal());
372
- const zone = inject(NgZone);
373
- const isRendered = signalIsRendered();
374
- const isEnabled = options?.enabled ?? signal(true);
375
- const elementIntersectionSignal = signal([]);
376
- const observer = signal(null);
377
- const currentlyObservedElements = new Set();
378
- const updateIntersections = (entries) => {
379
- let currentValues = [...elementIntersectionSignal()];
380
- for (const entry of entries) {
381
- const existingEntryIndex = currentValues.findIndex((v) => v.target === entry.target);
382
- // Round the intersection ratio to the nearest 0.01 to avoid floating point errors and system scaling issues.
383
- const roundedIntersectionRatio = Math.round(entry.intersectionRatio * 100) / 100;
384
- const intersectionEntry = {
385
- boundingClientRect: entry.boundingClientRect,
386
- intersectionRatio: roundedIntersectionRatio,
387
- intersectionRect: entry.intersectionRect,
388
- isIntersecting: entry.isIntersecting,
389
- rootBounds: entry.rootBounds,
390
- target: entry.target,
391
- time: entry.time,
392
- };
393
- if (existingEntryIndex !== -1) {
394
- currentValues = [
395
- ...currentValues.slice(0, existingEntryIndex),
396
- intersectionEntry,
397
- ...currentValues.slice(existingEntryIndex + 1),
398
- ];
399
- }
400
- else {
401
- currentValues = [...currentValues, intersectionEntry];
402
- }
403
- }
404
- zone.run(() => elementIntersectionSignal.set(currentValues));
405
- };
406
- const updateIntersectionObserver = (rendered, enabled, rootEl) => {
407
- observer()?.disconnect();
408
- currentlyObservedElements.clear();
409
- if (!rendered || !enabled || !rootEl) {
410
- observer.set(null);
411
- return;
412
- }
413
- const newObserver = new IntersectionObserver((entries) => updateIntersections(entries), {
414
- ...options,
415
- root: rootEl,
416
- });
417
- observer.set(newObserver);
418
- };
419
- const updateObservedElements = (observer, elements) => {
420
- const rootEl = root().currentElement;
421
- if (!observer || !rootEl)
422
- return;
423
- const rootBounds = rootEl.getBoundingClientRect();
424
- const currIntersectionValue = elementIntersectionSignal();
425
- const newIntersectionValue = [];
426
- for (const el of elements.currentElements) {
427
- if (currentlyObservedElements.has(el)) {
428
- const existingEntryIndex = currIntersectionValue.findIndex((v) => v.target === el);
429
- const existingEntry = currIntersectionValue[existingEntryIndex];
430
- if (!existingEntry) {
431
- console.warn('Could not find existing entry for element. The intersection observer might be broken now.', el);
432
- continue;
433
- }
434
- newIntersectionValue.push(existingEntry);
435
- continue;
436
- }
437
- const elBounds = el.getBoundingClientRect();
438
- const initialElementVisibility = isElementVisible({
439
- container: rootEl,
440
- element: el,
441
- containerRect: rootBounds,
442
- elementRect: elBounds,
443
- });
444
- if (!initialElementVisibility) {
445
- console.error('No visibility data found for element.', {
446
- element: el,
447
- container: rootEl,
448
- });
449
- continue;
450
- }
451
- const intersectionEntry = {
452
- boundingClientRect: elBounds,
453
- intersectionRatio: initialElementVisibility.intersectionRatio,
454
- intersectionRect: elBounds,
455
- isIntersecting: initialElementVisibility.isIntersecting,
456
- rootBounds: rootBounds,
457
- target: el,
458
- time: performance.now(),
459
- };
460
- newIntersectionValue.push(intersectionEntry);
461
- currentlyObservedElements.add(el);
462
- observer.observe(el);
463
- }
464
- for (const el of elements.previousElements) {
465
- if (elements.currentElements.includes(el))
466
- continue;
467
- observer.unobserve(el);
468
- currentlyObservedElements.delete(el);
469
- }
470
- elementIntersectionSignal.set(newIntersectionValue);
471
- };
472
- effect(() => {
473
- const rootEl = root().currentElement;
474
- const rendered = isRendered();
475
- const enabled = isEnabled();
476
- untracked(() => updateIntersectionObserver(rendered, enabled, rootEl));
477
- }, { allowSignalWrites: true });
478
- effect(() => {
479
- const els = elements();
480
- const obs = observer();
481
- untracked(() => updateObservedElements(obs, els));
482
- });
483
- destroyRef.onDestroy(() => observer()?.disconnect());
484
- return elementIntersectionSignal.asReadonly();
485
- };
486
- export const signalHostElementIntersection = (options) => signalElementIntersection(inject(ElementRef), options);
487
- export const signalElementChildren = (el) => {
488
- const elements = buildElementSignal(el);
489
- const isRendered = signalIsRendered();
490
- const elementMutations = signalElementMutations(elements, { childList: true, subtree: true, attributes: true });
491
- return computed(() => {
492
- if (!isRendered())
493
- return [];
494
- const els = elements();
495
- // We are not interested what the mutation is, just that there is one.
496
- // Changes to the DOM may affect the children of the element.
497
- elementMutations();
498
- if (!els.currentElement)
499
- return [];
500
- const children = [];
501
- for (let index = 0; index < els.currentElement.children.length; index++) {
502
- const element = els.currentElement.children[index];
503
- if (element instanceof HTMLElement) {
504
- children.push(element);
505
- }
506
- }
507
- return children;
508
- }, { equal: (a, b) => a.length === b.length && a.every((v, i) => v === b[i]) });
509
- };
510
- export const previousSignalValue = (signal) => {
511
- const obs = toObservable(signal).pipe(pairwise(), map(([prev]) => prev));
512
- return toSignal(obs);
513
- };
514
- export const syncSignal = (from, to, options) => {
515
- let isFirstRun = options?.skipSyncRead ? false : true;
516
- if (!options?.skipSyncRead) {
517
- try {
518
- // this might throw if the signal is not yet initialized (eg. a required signal input inside the constructor)
519
- // in that case we just skip the initial sync
520
- to.set(from());
521
- }
522
- catch {
523
- isFirstRun = false;
524
- if (isDevMode()) {
525
- console.warn('Failed to sync signals. The target signal is not yet initialized.', { from, to });
526
- }
527
- }
528
- }
529
- const ref = effect(() => {
530
- const formVal = from();
531
- if (isFirstRun) {
532
- isFirstRun = false;
533
- return;
534
- }
535
- untracked(() => {
536
- to.set(formVal);
537
- });
538
- });
539
- return ref;
540
- };
541
- export const controlValueSignal = (control, options) => {
542
- const initialValue = deferredSignal(() => (isSignal(control) ? control() : control));
543
- const controlStream = isSignal(control)
544
- ? toObservable(control)
545
- : of(control);
546
- const controlObs = controlStream.pipe(switchMap((control) => {
547
- if (!control)
548
- return of(null);
549
- const vcsObs = options?.debounceTime
550
- ? control.valueChanges.pipe(debounceTime(options.debounceTime))
551
- : control.valueChanges;
552
- return vcsObs.pipe(map(() => control.getRawValue()));
553
- }));
554
- const isRendered = toObservable(signalIsRendered()).pipe(filter((v) => v));
555
- const obs = !options?.debounceFirst
556
- ? isRendered.pipe(switchMap(() => merge(of(initialValue()?.getRawValue()), controlObs)))
557
- : isRendered.pipe(switchMap(() => controlObs));
558
- return toSignal(obs.pipe(distinctUntilChanged((a, b) => equal(a, b))), {
559
- initialValue: null,
560
- });
561
- };
562
- /**
563
- * The first item in the pair is the previous value and the second item is the current value.
564
- */
565
- export const controlValueSignalWithPrevious = (control, options) => {
566
- const obs = toObservable(controlValueSignal(control, options)).pipe(pairwise(), startWith([null, control.getRawValue()]));
567
- return toSignal(obs, { requireSync: true });
568
- };
569
- /**
570
- * @deprecated Use `controlValueSignal` instead with `debounceTime` set to `300` and `debounceFirst` set to `true`.
571
- */
572
- export const debouncedControlValueSignal = (control, options) => controlValueSignal(control, options ?? { debounceTime: 300, debounceFirst: true });
573
- export const transformOrReturn = (src, config) => {
574
- const transformer = config?.transform;
575
- if (transformer) {
576
- return computed(() => transformer(src()));
577
- }
578
- return src;
579
- };
580
- /** Inject the current router event */
581
- export const injectRouterEvent = () => {
582
- const router = inject(Router);
583
- return toSignal(router.events, { initialValue: null });
584
- };
585
- /**
586
- * Inject the current url.
587
- * The url includes query params as well as the fragment. Use `injectRoute` instead if you are not intrusted in those.
588
- * @example "/my-page?query=1&param=true#fragment"
589
- */
590
- export const injectUrl = () => {
591
- const event = injectRouterEvent();
592
- const router = inject(Router);
593
- const url = signal(router.url);
594
- effect(() => {
595
- const currentEvent = event();
596
- untracked(() => {
597
- if (currentEvent instanceof NavigationEnd) {
598
- url.set(currentEvent.urlAfterRedirects);
599
- }
600
- });
601
- });
602
- return url.asReadonly();
603
- };
604
- /**
605
- * Inject the current route
606
- * @example "/my-page"
607
- */
608
- export const injectRoute = () => {
609
- const url = injectUrl();
610
- return computed(() => {
611
- const fullUrl = url();
612
- const urlWithoutQueryParams = fullUrl.split('?')[0] ?? '';
613
- const withoutFragment = urlWithoutQueryParams.split('#')[0] ?? '';
614
- return withoutFragment;
615
- });
616
- };
617
- const createRouterState = (router) => {
618
- let route = router.routerState.snapshot.root;
619
- while (route.firstChild) {
620
- route = route.firstChild;
621
- }
622
- const { data, params, queryParams, title, fragment } = route;
623
- return {
624
- data,
625
- pathParams: params,
626
- queryParams,
627
- title: title ?? null,
628
- fragment,
629
- };
630
- };
631
- /**
632
- * Inject the complete router state. This includes the current route data, path params, query params, title and fragment.
633
- */
634
- export const injectRouterState = () => {
635
- const url = injectUrl();
636
- const router = inject(Router);
637
- const routerState = signal(createRouterState(router));
638
- effect(() => {
639
- url();
640
- untracked(() => routerState.set(createRouterState(router)));
641
- });
642
- return routerState.asReadonly();
643
- };
644
- /** Inject a signal containing the current route fragment (the part after the # inside the url if present) */
645
- export const injectFragment = (config) => {
646
- const routerState = injectRouterState();
647
- const fragment = computed(() => routerState().fragment);
648
- return transformOrReturn(fragment, config);
649
- };
650
- /** Inject all currently available query parameters as a signal */
651
- export const injectQueryParams = () => {
652
- const routerState = injectRouterState();
653
- const queryParams = computed(() => routerState().queryParams);
654
- return queryParams;
655
- };
656
- /** Inject all currently available route data as a signal */
657
- export const injectRouteData = () => {
658
- const routerState = injectRouterState();
659
- const data = computed(() => routerState().data);
660
- return data;
661
- };
662
- /** Inject the current route title as a signal */
663
- export const injectRouteTitle = (config) => {
664
- const routerState = injectRouterState();
665
- const title = computed(() => routerState().title);
666
- return transformOrReturn(title, config);
667
- };
668
- /** Inject all currently available path parameters as a signal */
669
- export const injectPathParams = () => {
670
- const routerState = injectRouterState();
671
- const pathParams = computed(() => routerState().pathParams);
672
- return pathParams;
673
- };
674
- /** Inject a specific query parameter as a signal */
675
- export const injectQueryParam = (key, config) => {
676
- const queryParams = injectQueryParams();
677
- const src = computed(() => queryParams()[key] ?? null);
678
- return transformOrReturn(src, config);
679
- };
680
- /** Inject a specific route data item as a signal */
681
- export const injectRouteDataItem = (key, config) => {
682
- const data = injectRouteData();
683
- const src = computed(() => data()[key] ?? null);
684
- return transformOrReturn(src, config);
685
- };
686
- /** Inject a specific path parameter as a signal */
687
- export const injectPathParam = (key, config) => {
688
- const pathParams = injectPathParams();
689
- const src = computed(() => pathParams()[key] ?? null);
690
- return transformOrReturn(src, config);
691
- };
692
- /**
693
- * Inject query params that changed during navigation. Unchanged query params will be ignored.
694
- * Removed query params will be represented by the symbol `ET_PROPERTY_REMOVED`.
695
- */
696
- export const injectQueryParamChanges = () => {
697
- const queryParams = injectQueryParams();
698
- const prevQueryParams = previousSignalValue(queryParams);
699
- return computed(() => {
700
- const current = queryParams();
701
- const previous = prevQueryParams() ?? {};
702
- const changes = {};
703
- const allKeys = new Set([
704
- ...Object.keys(previous),
705
- ...Object.keys(current),
706
- ]);
707
- for (const key of allKeys) {
708
- if (!equal(previous[key], current[key])) {
709
- const val = current[key] === undefined ? ET_PROPERTY_REMOVED : current[key];
710
- changes[key] = val;
711
- }
712
- }
713
- return changes;
714
- });
715
- };
716
- /**
717
- * Inject path params that changed during navigation. Unchanged path params will be ignored.
718
- * Removed path params will be represented by the symbol `ET_PROPERTY_REMOVED`.
719
- */
720
- export const injectPathParamChanges = () => {
721
- const pathParams = injectPathParams();
722
- const prevPathParams = previousSignalValue(pathParams);
723
- return computed(() => {
724
- const current = pathParams();
725
- const previous = prevPathParams() ?? {};
726
- const changes = {};
727
- const allKeys = new Set([
728
- ...Object.keys(previous),
729
- ...Object.keys(current),
730
- ]);
731
- for (const key of allKeys) {
732
- if (!equal(previous[key], current[key])) {
733
- const val = current[key] === undefined ? ET_PROPERTY_REMOVED : current[key];
734
- changes[key] = val;
735
- }
736
- }
737
- return changes;
738
- });
739
- };
740
- export const createIsRenderedSignal = () => {
741
- const value = signal(false);
742
- nextFrame(() => {
743
- if (!value()) {
744
- console.error('Render signal was not set to true. This can cause unexpected behavior. Make sure to .bind() the render signal at the end of the constructor.');
745
- }
746
- });
747
- return {
748
- state: value,
749
- bind: () => effect(() => value.set(true), { allowSignalWrites: true }),
750
- };
751
- };
752
- export const createCanAnimateSignal = () => {
753
- const value = signal(false);
754
- nextFrame(() => {
755
- value.set(true);
756
- });
757
- return {
758
- state: value.asReadonly(),
759
- };
760
- };
761
- export const maybeSignalValue = (value) => {
762
- if (isSignal(value)) {
763
- return value();
764
- }
765
- return value;
766
- };
767
- /** The deadzone in pixels after which the cursor drag scroll will take effect. */
768
- const CURSOR_DRAG_SCROLL_DEADZONE = 5;
769
- /** The class that is added to the element when the cursor is being dragged. */
770
- const CURSOR_DRAG_SCROLLING_CLASS = 'et-cursor-drag-scroll--scrolling';
771
- const CURSOR_DRAG_INIT_CLASS = 'et-cursor-drag-scroll--init';
772
- /** A function to apply cursor drag scroll behavior to an element. */
773
- export const useCursorDragScroll = (el, options) => {
774
- const elements = buildElementSignal(el);
775
- const element = firstElementSignal(elements);
776
- const destroyRef = inject(DestroyRef);
777
- const { enabled = signal(true), allowedDirection = 'both' } = options ?? {};
778
- const scrollState = signalElementScrollState(elements);
779
- const renderer = inject(Renderer2);
780
- const isDragging = signal(false);
781
- const isInitDragging = signal(false);
782
- const initialDragPosition = signal({ x: 0, y: 0 });
783
- const initialScrollPosition = signal({ x: 0, y: 0 });
784
- const dragAmount = signal({ x: 0, y: 0 });
785
- const document = inject(DOCUMENT);
786
- const canScroll = computed(() => {
787
- const currentScrollState = scrollState();
788
- const direction = maybeSignalValue(allowedDirection);
789
- switch (direction) {
790
- case 'both':
791
- return currentScrollState.canScrollHorizontally || currentScrollState.canScrollVertically;
792
- case 'horizontal':
793
- return currentScrollState.canScrollHorizontally;
794
- case 'vertical':
795
- return currentScrollState.canScrollVertically;
796
- }
797
- });
798
- // Cleanup if the element the cursor drag scroll is bound to gets changed
799
- effect(() => {
800
- const { previousElement } = element();
801
- if (previousElement) {
802
- renderer.removeStyle(previousElement, 'cursor');
803
- }
804
- });
805
- // Conditionally apply styles/classes to the element and the document
806
- effect(() => {
807
- const currCanScroll = canScroll();
808
- const isEnabled = enabled();
809
- const currIsDragging = isDragging();
810
- const currIsInitDragging = isInitDragging();
811
- untracked(() => {
812
- const el = element().currentElement;
813
- if (!el)
814
- return;
815
- if (!currCanScroll || !isEnabled) {
816
- renderer.removeStyle(el, 'cursor');
817
- renderer.removeStyle(el, 'scrollSnapType');
818
- renderer.removeStyle(el, 'scrollBehavior');
819
- renderer.removeClass(el, CURSOR_DRAG_SCROLLING_CLASS);
820
- renderer.removeClass(el, CURSOR_DRAG_INIT_CLASS);
821
- renderer.removeStyle(document.documentElement, 'cursor');
822
- return;
823
- }
824
- if (currIsInitDragging) {
825
- renderer.addClass(el, CURSOR_DRAG_INIT_CLASS);
826
- }
827
- if (currIsDragging) {
828
- renderer.addClass(el, CURSOR_DRAG_SCROLLING_CLASS);
829
- renderer.setStyle(el, 'scrollSnapType', 'none');
830
- renderer.setStyle(el, 'scrollBehavior', 'unset');
831
- renderer.setStyle(el, 'cursor', 'grabbing');
832
- renderer.setStyle(document.documentElement, 'cursor', 'grabbing');
833
- }
834
- if (!currIsInitDragging && !currIsDragging) {
835
- renderer.setStyle(el, 'cursor', 'grab');
836
- renderer.removeStyle(el, 'scrollSnapType');
837
- renderer.removeStyle(el, 'scrollBehavior');
838
- renderer.removeClass(el, CURSOR_DRAG_SCROLLING_CLASS);
839
- renderer.removeClass(el, CURSOR_DRAG_INIT_CLASS);
840
- renderer.removeStyle(document.documentElement, 'cursor');
841
- }
842
- });
843
- });
844
- // Update the element's scroll position when the user drags
845
- effect(() => {
846
- const currDragAmount = dragAmount();
847
- untracked(() => {
848
- const currIsDragging = isDragging();
849
- const el = element().currentElement;
850
- const { x: dragX, y: dragY } = currDragAmount;
851
- const { x: scrollX, y: scrollY } = initialScrollPosition();
852
- const currAllowedDirection = maybeSignalValue(allowedDirection);
853
- if (!el || !currIsDragging)
854
- return;
855
- switch (currAllowedDirection) {
856
- case 'both':
857
- el.scroll({
858
- top: dragY + scrollY,
859
- left: dragX + scrollX,
860
- behavior: 'instant',
861
- });
862
- break;
863
- case 'horizontal':
864
- el.scroll({
865
- left: dragX + scrollX,
866
- behavior: 'instant',
867
- });
868
- break;
869
- case 'vertical':
870
- el.scroll({
871
- top: dragY + scrollY,
872
- behavior: 'instant',
873
- });
874
- break;
875
- }
876
- });
877
- });
878
- const updateDragging = (e) => {
879
- const el = element().currentElement;
880
- if (!el)
881
- return;
882
- const dx = (e.clientX - initialDragPosition().x) * -1;
883
- const dy = (e.clientY - initialDragPosition().y) * -1;
884
- dragAmount.set({ x: dx, y: dy });
885
- if (Math.abs(dx) > CURSOR_DRAG_SCROLL_DEADZONE || Math.abs(dy) > CURSOR_DRAG_SCROLL_DEADZONE) {
886
- isDragging.set(true);
887
- }
888
- };
889
- const updateDraggingEnd = () => {
890
- isDragging.set(false);
891
- isInitDragging.set(false);
892
- initialDragPosition.set({ x: 0, y: 0 });
893
- initialScrollPosition.set({ x: 0, y: 0 });
894
- dragAmount.set({ x: 0, y: 0 });
895
- };
896
- const setupDragging = (e) => {
897
- const mouseUp = fromEvent(document, 'mouseup');
898
- const mouseMove = fromEvent(document, 'mousemove');
899
- const el = element().currentElement;
900
- if (!el)
901
- return;
902
- mouseMove
903
- .pipe(takeUntilDestroyed(destroyRef), takeUntil(mouseUp), tap((e) => updateDragging(e)))
904
- .subscribe();
905
- mouseUp
906
- .pipe(take(1), takeUntilDestroyed(destroyRef), tap(() => updateDraggingEnd()))
907
- .subscribe();
908
- initialDragPosition.set({ x: e.clientX, y: e.clientY });
909
- initialScrollPosition.set({ x: el.scrollLeft, y: el.scrollTop });
910
- isInitDragging.set(true);
911
- };
912
- toObservable(element)
913
- .pipe(map((e) => e?.currentElement), switchMap((el) => (el ? fromEvent(el, 'mousedown') : of(null))), filter((e) => !!e), filter(() => enabled()), tap((e) => setupDragging(e)), takeUntilDestroyed())
914
- .subscribe();
915
- return {
916
- isDragging: isDragging.asReadonly(),
917
- currentDragAmount: dragAmount.asReadonly(),
918
- };
919
- };
920
- /**
921
- * A computed that will only be reactive until the source signal contains a truthy value.
922
- * All subsequent changes inside the computation will be ignored.
923
- */
924
- export const computedTillTruthy = (source) => {
925
- const value = signal(null);
926
- const ref = effect(() => {
927
- const val = source();
928
- if (val) {
929
- value.set(val);
930
- ref.destroy();
931
- }
932
- }, { allowSignalWrites: true });
933
- return value.asReadonly();
934
- };
935
- /**
936
- * A computed that will only be reactive until the source signal contains a falsy value.
937
- * All subsequent changes inside the computation will be ignored.
938
- */
939
- export const computedTillFalsy = (source) => {
940
- const value = signal(null);
941
- const ref = effect(() => {
942
- const val = source();
943
- if (!val) {
944
- value.set(val);
945
- ref.destroy();
946
- }
947
- }, { allowSignalWrites: true });
948
- return value.asReadonly();
949
- };
950
- /**
951
- * A writeable signal that will be set to the provided value once all inputs are set.
952
- * During that time, the signal will be set to `null`.
953
- */
954
- export const deferredSignal = (valueFn) => {
955
- const valueSignal = signal(null);
956
- afterNextRender(() => {
957
- valueSignal.set(valueFn());
958
- });
959
- return valueSignal;
960
- };
961
- /** Inject a signal containing a boolean value indicating if the viewport is xs */
962
- export const injectIsXs = () => {
963
- return toSignal(inject(ViewportService).isXs$, { requireSync: true });
964
- };
965
- /** Inject a signal containing a boolean value indicating if the viewport is sm */
966
- export const injectIsSm = () => {
967
- return toSignal(inject(ViewportService).isSm$, { requireSync: true });
968
- };
969
- /** Inject a signal containing a boolean value indicating if the viewport is md */
970
- export const injectIsMd = () => {
971
- return toSignal(inject(ViewportService).isMd$, { requireSync: true });
972
- };
973
- /** Inject a signal containing a boolean value indicating if the viewport is lg */
974
- export const injectIsLg = () => {
975
- return toSignal(inject(ViewportService).isLg$, { requireSync: true });
976
- };
977
- /** Inject a signal containing a boolean value indicating if the viewport is xl */
978
- export const injectIsXl = () => {
979
- return toSignal(inject(ViewportService).isXl$, { requireSync: true });
980
- };
981
- /** Inject a signal containing a boolean value indicating if the viewport is 2xl */
982
- export const injectIs2Xl = () => {
983
- return toSignal(inject(ViewportService).is2Xl$, { requireSync: true });
984
- };
985
- /**
986
- * Inject a boolean value indicating if the viewport is matching the provided options.
987
- * This value is not reactive. If you want to react to changes, use the {@link injectObserveBreakpoint} function instead.
988
- */
989
- export const injectBreakpointIsMatched = (options) => {
990
- return inject(ViewportService).isMatched(options);
991
- };
992
- /**
993
- * Inject a signal containing a boolean value indicating if the viewport is matching the provided options.
994
- */
995
- export const injectObserveBreakpoint = (options) => {
996
- return toSignal(inject(ViewportService).observe(options), { initialValue: injectBreakpointIsMatched(options) });
997
- };
998
- /** Inject a signal containing the current breakpoint. */
999
- export const injectCurrentBreakpoint = () => {
1000
- return toSignal(inject(ViewportService).currentViewport$, {
1001
- initialValue: inject(ViewportService).currentViewport,
1002
- });
1003
- };
1004
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsLnV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9jb3JlL3NyYy9saWIvdXRpbHMvc2lnbmFsLnV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUNMLFVBQVUsRUFFVixVQUFVLEVBQ1YsUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUNULG1CQUFtQixFQUduQixlQUFlLEVBQ2YsUUFBUSxFQUNSLE1BQU0sRUFDTixNQUFNLEVBQ04sU0FBUyxFQUNULFFBQVEsRUFDUixxQkFBcUIsRUFDckIsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXhGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEQsT0FBTyxFQUNMLFVBQVUsRUFDVixZQUFZLEVBQ1osb0JBQW9CLEVBQ3BCLE1BQU0sRUFDTixTQUFTLEVBQ1QsR0FBRyxFQUNILEtBQUssRUFDTCxFQUFFLEVBQ0YsUUFBUSxFQUNSLFNBQVMsRUFDVCxTQUFTLEVBQ1QsSUFBSSxFQUNKLFNBQVMsRUFDVCxHQUFHLEdBQ0osTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQUUsbUJBQW1CLEVBQWUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRWhGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixD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QixPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDeEUsQ0FBQyxDQUFDO0FBRUYsbUZBQW1GO0FBQ25GLE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxHQUFHLEVBQUU7SUFDOUIsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQ3pFLENBQUMsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLENBQUMsT0FBaUUsRUFBRSxFQUFFO0lBQzdHLE9BQU8sTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNwRCxDQUFDLENBQUM7QUFFRjs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQUMsT0FBaUUsRUFBRSxFQUFFO0lBQzNHLE9BQU8sUUFBUSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxZQUFZLEVBQUUseUJBQXlCLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xILENBQUMsQ0FBQztBQUVGLHlEQUF5RDtBQUN6RCxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLEVBQUU7SUFDMUMsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDLGdCQUFnQixFQUFFO1FBQ3hELFlBQVksRUFBRSxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsZUFBZTtLQUN0RCxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb2VyY2VFbGVtZW50IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIERlc3Ryb3lSZWYsXG4gIEVmZmVjdFJlZixcbiAgRWxlbWVudFJlZixcbiAgSW5qZWN0b3IsXG4gIE5nWm9uZSxcbiAgUXVlcnlMaXN0LFxuICBSZW5kZXJlcjIsXG4gIFJlbmRlcmVyU3R5bGVGbGFnczIsXG4gIFNpZ25hbCxcbiAgV3JpdGFibGVTaWduYWwsXG4gIGFmdGVyTmV4dFJlbmRlcixcbiAgY29tcHV0ZWQsXG4gIGVmZmVjdCxcbiAgaW5qZWN0LFxuICBpc0Rldk1vZGUsXG4gIGlzU2lnbmFsLFxuICBydW5JbkluamVjdGlvbkNvbnRleHQsXG4gIHNpZ25hbCxcbiAgdW50cmFja2VkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCwgdG9PYnNlcnZhYmxlLCB0b1NpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgRm9ybUNvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uRW5kLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtcbiAgT2JzZXJ2YWJsZSxcbiAgZGVib3VuY2VUaW1lLFxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgZmlsdGVyLFxuICBmcm9tRXZlbnQsXG4gIG1hcCxcbiAgbWVyZ2UsXG4gIG9mLFxuICBwYWlyd2lzZSxcbiAgc3RhcnRXaXRoLFxuICBzd2l0Y2hNYXAsXG4gIHRha2UsXG4gIHRha2VVbnRpbCxcbiAgdGFwLFxufSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEVUX1BST1BFUlRZX1JFTU9WRUQsIFJvdXRlclN0YXRlLCBWaWV3cG9ydFNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBCcmVha3BvaW50IH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgbmV4dEZyYW1lIH0gZnJvbSAnLi9hbmltYXRpb24udXRpbHMnO1xuaW1wb3J0IHsgZXF1YWwgfSBmcm9tICcuL2VxdWFsLnV0aWwnO1xuaW1wb3J0IHsgaXNFbGVtZW50VmlzaWJsZSB9IGZyb20gJy4vc2Nyb2xsYWJsZS51dGlscyc7XG5cbnR5cGUgU2lnbmFsRWxlbWVudEJpbmRpbmdDb21wbGV4VHlwZSA9XG4gIHwgSFRNTEVsZW1lbnRcbiAgfCBFbGVtZW50UmVmPEhUTUxFbGVtZW50PlxuICB8IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPEhUTUxFbGVtZW50PiB8IEhUTUxFbGVtZW50PlxuICB8IEFycmF5PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgSFRNTEVsZW1lbnQ+XG4gIHwgbnVsbFxuICB8IHVuZGVmaW5lZDtcblxudHlwZSBTaWduYWxFbGVtZW50QmluZGluZ1R5cGUgPVxuICB8IEhUTUxFbGVtZW50XG4gIHwgRWxlbWVudFJlZjxIVE1MRWxlbWVudD5cbiAgfCBPYnNlcnZhYmxlPFNpZ25hbEVsZW1lbnRCaW5kaW5nQ29tcGxleFR5cGU+XG4gIHwgU2lnbmFsPFNpZ25hbEVsZW1lbnRCaW5kaW5nQ29tcGxleFR5cGU+XG4gIHwgUXVlcnlMaXN0PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgSFRNTEVsZW1lbnQ+XG4gIHwgRWxlbWVudFNpZ25hbDtcblxudHlwZSBFbGVtZW50U2lnbmFsID0gU2lnbmFsPHtcbiAgLyoqIEBkZXByZWNhdGVkIEFsd2F5cyB1c2UgY3VycmVudEVsZW1lbnRzICAqL1xuICBjdXJyZW50RWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsO1xuXG4gIC8qKiBAZGVwcmVjYXRlZCBBbHdheXMgdXNlIHByZXZpb3VzRWxlbWVudHMgICovXG4gIHByZXZpb3VzRWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsO1xuICBjdXJyZW50RWxlbWVudHM6IEhUTUxFbGVtZW50W107XG4gIHByZXZpb3VzRWxlbWVudHM6IEhUTUxFbGVtZW50W107XG59PjtcblxudHlwZSBFbGVtZW50U2lnbmFsVmFsdWUgPSBSZXR1cm5UeXBlPEVsZW1lbnRTaWduYWw+O1xuXG5mdW5jdGlvbiBpc0VsZW1lbnRTaWduYWwoZWw6IHVua25vd24pOiBlbCBpcyBFbGVtZW50U2lnbmFsIHtcbiAgaWYgKGlzU2lnbmFsKGVsKSkge1xuICAgIGNvbnN0IHZhbCA9IGVsKCk7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbCAhPT0gbnVsbCAmJiAnY3VycmVudEVsZW1lbnQnIGluIHZhbCAmJiAncHJldmlvdXNFbGVtZW50JyBpbiB2YWw7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmNvbnN0IGRvY3VtZW50RWxlbWVudFNpZ25hbCA9ICgpOiBFbGVtZW50U2lnbmFsID0+XG4gIHNpZ25hbCh7XG4gICAgY3VycmVudEVsZW1lbnQ6IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxcbiAgICBwcmV2aW91c0VsZW1lbnQ6IG51bGwsXG4gICAgY3VycmVudEVsZW1lbnRzOiBbZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50XSxcbiAgICBwcmV2aW91c0VsZW1lbnRzOiBbXSxcbiAgfSk7XG5cbmNvbnN0IGJ1aWxkRWxlbWVudFNpZ25hbCA9IChlbDogU2lnbmFsRWxlbWVudEJpbmRpbmdUeXBlIHwgbnVsbCB8IHVuZGVmaW5lZCk6IEVsZW1lbnRTaWduYWwgPT4ge1xuICBpZiAoZWwgPT09IG51bGwgfHwgZWwgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBzaWduYWwoeyBjdXJyZW50RWxlbWVudDogbnVsbCwgcHJldmlvdXNFbGVtZW50OiBudWxsLCBjdXJyZW50RWxlbWVudHM6IFtdLCBwcmV2aW91c0VsZW1lbnRzOiBbXSB9KTtcbiAgfVxuXG4gIGlmIChpc0VsZW1lbnRTaWduYWwoZWwpKSB7XG4gICAgcmV0dXJuIGVsO1xuICB9XG5cbiAgbGV0IG1FbFNpZ25hbDogU2lnbmFsPEhUTUxFbGVtZW50W10gfCBudWxsPiB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0IHN3aXRjaEVsZW1lbnQgPSAoKSA9PlxuICAgIHN3aXRjaE1hcCgoZWxPclJlZjogU2lnbmFsRWxlbWVudEJpbmRpbmdDb21wbGV4VHlwZSkgPT4ge1xuICAgICAgaWYgKGVsT3JSZWYgaW5zdGFuY2VvZiBRdWVyeUxpc3QpIHtcbiAgICAgICAgcmV0dXJuIGVsT3JSZWYuY2hhbmdlcy5waXBlKFxuICAgICAgICAgIHN0YXJ0V2l0aChlbE9yUmVmKSxcbiAgICAgICAgICBtYXAoKCkgPT4gZWxPclJlZi50b0FycmF5KCkubWFwKChyKSA9PiBjb2VyY2VFbGVtZW50KHIpKSksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoZWxPclJlZikpIHtcbiAgICAgICAgcmV0dXJuIG9mKGVsT3JSZWYubWFwKChyKSA9PiBjb2VyY2VFbGVtZW50KHIpKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBjb2VyY2VkRWwgPSBjb2VyY2VFbGVtZW50KGVsT3JSZWYpO1xuICAgICAgICByZXR1cm4gb2YoY29lcmNlZEVsID8gW2NvZXJjZWRFbF0gOiBudWxsKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICBpZiAoZWwgaW5zdGFuY2VvZiBPYnNlcnZhYmxlKSB7XG4gICAgbUVsU2lnbmFsID0gdG9TaWduYWwoZWwucGlwZShzd2l0Y2hFbGVtZW50KCkpLCB7IGluaXRpYWxWYWx1ZTogbnVsbCB9KTtcbiAgfSBlbHNlIGlmIChpc1NpZ25hbChlbCkpIHtcbiAgICBtRWxTaWduYWwgPSB0b1NpZ25hbCh0b09ic2VydmFibGUoZWwpLnBpcGUoc3dpdGNoRWxlbWVudCgpKSwgeyBpbml0aWFsVmFsdWU6IG51bGwgfSk7XG4gIH0gZWxzZSBpZiAoZWwgaW5zdGFuY2VvZiBRdWVyeUxpc3QpIHtcbiAgICBtRWxTaWduYWwgPSB0b1NpZ25hbChcbiAgICAgIGVsLmNoYW5nZXMucGlwZShcbiAgICAgICAgc3RhcnRXaXRoKGVsKSxcbiAgICAgICAgbWFwKCgpID0+IGVsLnRvQXJyYXkoKS5tYXAoKHIpID0+IGNvZXJjZUVsZW1lbnQocikpKSxcbiAgICAgICksXG4gICAgICB7IGluaXRpYWxWYWx1ZTogbnVsbCB9LFxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgbUVsU2lnbmFsID0gc2lnbmFsKFtjb2VyY2VFbGVtZW50KGVsKV0pO1xuICB9XG5cbiAgY29uc3QgZWxTaWcgPSB0b1NpZ25hbChcbiAgICB0b09ic2VydmFibGUobUVsU2lnbmFsKS5waXBlKFxuICAgICAgc3RhcnRXaXRoKG51bGwpLFxuICAgICAgcGFpcndpc2UoKSxcbiAgICAgIG1hcCgoW3ByZXZpb3VzRWxlbWVudHMsIGN1cnJlbnRFbGVtZW50c10pID0+ICh7XG4gICAgICAgIHByZXZpb3VzRWxlbWVudHM6IHByZXZpb3VzRWxlbWVudHMgPz8gW10sXG4gICAgICAgIGN1cnJlbnRFbGVtZW50czogY3VycmVudEVsZW1lbnRzID8/IFtdLFxuICAgICAgICBjdXJyZW50RWxlbWVudDogY3VycmVudEVsZW1lbnRzPy5bMF0gPz8gbnVsbCxcbiAgICAgICAgcHJldmlvdXNFbGVtZW50OiBwcmV2aW91c0VsZW1lbnRzPy5bMF0gPz8gbnVsbCxcbiAgICAgIH0pKSxcbiAgICApLFxuICAgIHsgaW5pdGlhbFZhbHVlOiB7IGN1cnJlbnRFbGVtZW50OiBudWxsLCBwcmV2aW91c0VsZW1lbnQ6IG51bGwsIHByZXZpb3VzRWxlbWVudHM6IFtdLCBjdXJyZW50RWxlbWVudHM6IFtdIH0gfSxcbiAgKTtcblxuICByZXR1cm4gY29tcHV0ZWQoKCkgPT4gZWxTaWcoKSwge1xuICAgIGVxdWFsOiAoYSwgYikgPT5cbiAgICAgIGEuY3VycmVudEVsZW1lbnQgPT09IGIuY3VycmVudEVsZW1lbnQgJiZcbiAgICAgIGEucHJldmlvdXNFbGVtZW50ID09PSBiLnByZXZpb3VzRWxlbWVudCAmJlxuICAgICAgYS5jdXJyZW50RWxlbWVudHMubGVuZ3RoID09PSBiLmN1cnJlbnRFbGVtZW50cy5sZW5ndGggJiZcbiAgICAgIGEuY3VycmVudEVsZW1lbnRzLmV2ZXJ5KCh2LCBpKSA9PiB2ID09PSBiLmN1cnJlbnRFbGVtZW50c1tpXSkgJiZcbiAgICAgIGEucHJldmlvdXNFbGVtZW50cy5sZW5ndGggPT09IGIucHJldmlvdXNFbGVtZW50cy5sZW5ndGggJiZcbiAgICAgIGEucHJldmlvdXNFbGVtZW50cy5ldmVyeSgodiwgaSkgPT4gdiA9PT0gYi5wcmV2aW91c0VsZW1lbnRzW2ldKSxcbiAgfSk7XG59O1xuXG5jb25zdCBmaXJzdEVsZW1lbnRTaWduYWwgPSAoZWw6IEVsZW1lbnRTaWduYWwpID0+IHtcbiAgcmV0dXJuIGNvbXB1dGVkKFxuICAgICgpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBlbCgpO1xuXG4gICAgICBpZiAoY3VycmVudC5jdXJyZW50RWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgJ01vcmUgdGhhbiBvbmUgZWxlbWVudCBpcyBib3VuZCB0byB0aGUgc2lnbmFsLiBPbmx5IHRoZSBmaXJzdCBlbGVtZW50IHdpbGwgYmUgdXNlZC4nLFxuICAgICAgICAgIGN1cnJlbnQuY3VycmVudEVsZW1lbnRzLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjdXJyID0gY3VycmVudC5jdXJyZW50RWxlbWVudHNbMF0gPz8gbnVsbDtcbiAgICAgIGNvbnN0IHByZXYgPSBjdXJyZW50LnByZXZpb3VzRWxlbWVudHNbMF0gPz8gbnVsbDtcblxuICAgICAgcmV0dXJuIHsgY3VycmVudEVsZW1lbnQ6IGN1cnIsIHByZXZpb3VzRWxlbWVudDogcHJldiB9O1xuICAgIH0sXG4gICAgeyBlcXVhbDogKGEsIGIpID0+IGEuY3VycmVudEVsZW1lbnQgPT09IGIuY3VycmVudEVsZW1lbnQgJiYgYS5wcmV2aW91c0VsZW1lbnQgPT09IGIucHJldmlvdXNFbGVtZW50IH0sXG4gICk7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkU2lnbmFsRWZmZWN0c0NvbmZpZzxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgU2lnbmFsPHVua25vd24+Pj4ge1xuICAvKiogVGhlIHRva2VucyB0byBhcHBseSBhbmQgdGhlaXIgc2lnbmFsIHZhbHVlICAqL1xuICB0b2tlbk1hcDogVDtcblxuICAvKiogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGludm9rZWQgZm9yIGVsZW1lbnRzIHRoYXQgd2VyZSByZW1vdmVkIGZyb20gdGhlIHNpZ25hbCBlZmZlY3RzICovXG4gIGNsZWFudXBGbjogKGVsOiBIVE1MRWxlbWVudCwgdG9rZW5zOiBzdHJpbmdbXSkgPT4gdm9pZDtcblxuICAvKiogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGludm9rZWQgZm9yIGVsZW1lbnRzIHRoYXQgd2VyZSBhZGRlZCB0byB0aGUgc2lnbmFsIGVmZmVjdHMgb3Igd2hlbiB0aGVpciBzaWduYWwgdmFsdWUgY2hhbmdlcyAqL1xuICB1cGRhdGVGbjogKGVsOiBIVE1MRWxlbWVudCwgdG9rZW5zOiBzdHJpbmdbXSwgY29uZGl0aW9uUmVzdWx0OiB1bmtub3duKSA9PiB2b2lkO1xufVxuXG5leHBvcnQgY29uc3QgYnVpbGRTaWduYWxFZmZlY3RzID0gPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBTaWduYWw8dW5rbm93bj4+PihcbiAgZWw6IFNpZ25hbEVsZW1lbnRCaW5kaW5nVHlwZSxcbiAgY29uZmlnOiBCdWlsZFNpZ25hbEVmZmVjdHNDb25maWc8VD4sXG4pID0+IHtcbiAgY29uc3QgZWxlbWVudHMgPSBidWlsZEVsZW1lbnRTaWduYWwoZWwpO1xuICBjb25zdCBpbmplY3RvciA9IGluamVjdChJbmplY3Rvcik7XG5cbiAgZWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCB7IGN1cnJlbnRFbGVtZW50cywgcHJldmlvdXNFbGVtZW50cyB9ID0gZWxlbWVudHMoKTtcblxuICAgIGZvciAoY29uc3QgcHJldmlvdXNFbCBvZiBwcmV2aW91c0VsZW1lbnRzKSB7XG4gICAgICBpZiAoY3VycmVudEVsZW1lbnRzLmluY2x1ZGVzKHByZXZpb3VzRWwpKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgdG9rZW5zID0gT2JqZWN0LmtleXMoY29uZmlnLnRva2VuTWFwKVxuICAgICAgICAubWFwKChrZXkpID0+IGtleS5zcGxpdCgnICcpKVxuICAgICAgICAuZmxhdCgpO1xuXG4gICAgICBpZiAoIXRva2Vucy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgICBjb25maWcuY2xlYW51cEZuKHByZXZpb3VzRWwsIHRva2Vucyk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBjdXJyZW50RWwgb2YgY3VycmVudEVsZW1lbnRzKSB7XG4gICAgICBpZiAocHJldmlvdXNFbGVtZW50cy5pbmNsdWRlcyhjdXJyZW50RWwpKSBjb250aW51ZTtcblxuICAgICAgZm9yIChjb25zdCBbdG9rZW5zLCBjb25kaXRpb25dIG9mIE9iamVjdC5lbnRyaWVzKGNvbmZpZy50b2tlbk1hcCkpIHtcbiAgICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgICBjb25zdCB0b2tlbkFycmF5ID0gdG9rZW5zLnNwbGl0KCcgJyk7XG4gICAgICAgICAgaWYgKCF0b2tlbkFycmF5Lmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgICAgICAgY29uZmlnLnVwZGF0ZUZuKGN1cnJlbnRFbCwgdG9rZW5BcnJheSwgY29uZGl0aW9uKCkpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGVmZmVjdHM6IFJlY29yZDxzdHJpbmcsIEVmZmVjdFJlZj4gPSB7fTtcblxuICBjb25zdCBoYXMgPSAodG9rZW5zOiBzdHJpbmcpID0+IHRva2VucyBpbiBlZmZlY3RzO1xuXG4gIGNvbnN0IHB1c2ggPSAodG9rZW5zOiBzdHJpbmcsIHNpZ25hbDogU2lnbmFsPHVua25vd24+KSA9PiB7XG4gICAgaWYgKGhhcyh0b2tlbnMpKSByZXR1cm47XG5cbiAgICBydW5JbkluamVjdGlvbkNvbnRleHQoaW5qZWN0b3IsICgpID0+IHtcbiAgICAgIGVmZmVjdHNbdG9rZW5zXSA9IGVmZmVjdCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY3VycmVudEVsZW1lbnRzIH0gPSB1bnRyYWNrZWQoKCkgPT4gZWxlbWVudHMoKSk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gc2lnbmFsKCk7XG5cbiAgICAgICAgZm9yIChjb25zdCBlbCBvZiBjdXJyZW50RWxlbWVudHMpIHtcbiAgICAgICAgICBjb25zdCB0b2tlbkFycmF5ID0gdG9rZW5zLnNwbGl0KCcgJyk7XG4gICAgICAgICAgaWYgKCF0b2tlbkFycmF5Lmxlbmd0aCkgY29udGludWU7XG5cbiAgICAgICAgICBjb25maWcudXBkYXRlRm4oZWwsIHRva2VuQXJyYXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgcHVzaE1hbnkgPSAobWFwOiBSZWNvcmQ8c3RyaW5nLCBTaWduYWw8dW5rbm93bj4+KSA9PiB7XG4gICAgZm9yIChjb25zdCBbdG9rZW5zLCBzaWduYWxdIG9mIE9iamVjdC5lbnRyaWVzKG1hcCkpIHtcbiAgICAgIHB1c2godG9rZW5zLCBzaWduYWwpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCByZW1vdmUgPSAodG9rZW5zOiBzdHJpbmcpID0+IHtcbiAgICBlZmZlY3RzW3Rva2Vuc10/LmRlc3Ryb3koKTtcblxuICAgIGRlbGV0ZSBlZmZlY3RzW3Rva2Vuc107XG5cbiAgICBmb3IgKGNvbnN0IGVsIG9mIGVsZW1lbnRzKCkuY3VycmVudEVsZW1lbnRzKSB7XG4gICAgICBjb25zdCB0b2tlbkFycmF5ID0gdG9rZW5zLnNwbGl0KCcgJyk7XG4gICAgICBpZiAoIXRva2VuQXJyYXkubGVuZ3RoKSBjb250aW51ZTtcblxuICAgICAgY29uZmlnLmNsZWFudXBGbihlbCwgdG9rZW5BcnJheSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHJlbW92ZU1hbnkgPSAodG9rZW5zOiBzdHJpbmdbXSkgPT4ge1xuICAgIGZvciAoY29uc3QgdG9rZW4gb2YgdG9rZW5zKSB7XG4gICAgICByZW1vdmUodG9rZW4pO1xuICAgIH1cbiAgfTtcblxuICBwdXNoTWFueShjb25maWcudG9rZW5NYXApO1xuXG4gIHJldHVybiB7IHJlbW92ZSwgcmVtb3ZlTWFueSwgaGFzLCBwdXNoLCBwdXNoTWFueSB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHNpZ25hbElzUmVuZGVyZWQgPSAoKSA9PiB7XG4gIGNvbnN0IGlzUmVuZGVyZWQgPSBzaWduYWwoZmFsc2UpO1xuXG4gIGFmdGVyTmV4dFJlbmRlcigoKSA9PiBpc1JlbmRlcmVkLnNldCh0cnVlKSk7XG5cbiAgcmV0dXJuIGlzUmVuZGVyZWQuYXNSZWFkb25seSgpO1xufTtcblxuZXhwb3J0IGNvbnN0IHNpZ25hbENsYXNzZXMgPSA8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIFNpZ25hbDx1bmtub3duPj4+KGVsOiBTaWduYWxFbGVtZW50QmluZGluZ1R5cGUsIGNsYXNzTWFwOiBUKSA9PiB7XG4gIGNvbnN0IHJlbmRlcmVyID0gaW5qZWN0KFJlbmRlcmVyMik7XG5cbiAgcmV0dXJuIGJ1aWxkU2lnbmFsRWZmZWN0cyhlbCwge1xuICAgIHRva2VuTWFwOiBjbGFzc01hcCxcbiAgICBjbGVhbnVwRm46IChlbCwgdG9rZW5zKSA9PiB0b2tlbnMuZm9yRWFjaCgodG9rZW4pID0+IHJlbmRlcmVyLnJlbW92ZUNsYXNzKGVsLCB0b2tlbikpLFxuICAgIHVwZGF0ZUZuOiAoZWwsIHRva2VucywgY29uZGl0aW9uKSA9PiB7XG4gICAgICBpZiAoIWNvbmRpdGlvbikge1xuICAgICAgICB0b2tlbnMuZm9yRWFjaCgodG9rZW4pID0+IHJlbmRlcmVyLnJlbW92ZUNsYXNzKGVsLCB0b2tlbikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdG9rZW5zLmZvckVhY2goKHRva2VuKSA9PiByZW5kZXJlci5hZGRDbGFzcyhlbCwgdG9rZW4pKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaWduYWxIb3N0Q2xhc3NlcyA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgU2lnbmFsPHVua25vd24+Pj4oY2xhc3NNYXA6IFQpID0+XG4gIHNpZ25hbENsYXNzZXMoaW5qZWN0KEVsZW1lbnRSZWYpLCBjbGFzc01hcCk7XG5cbmNvbnN0IEFMV0FZU19UUlVFX0FUVFJJQlVURV9LRVlTID0gWydkaXNhYmxlZCcsICdyZWFkb25seScsICdyZXF1aXJlZCcsICdjaGVja2VkJywgJ3NlbGVjdGVkJywgJ2hpZGRlbicsICdpbmVydCddO1xuXG5leHBvcnQgY29uc3Qgc2lnbmFsQXR0cmlidXRlcyA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgU2lnbmFsPHVua25vd24+Pj4oXG4gIGVsOiBTaWduYWxFbGVtZW50QmluZGluZ1R5cGUsXG4gIGF0dHJpYnV0ZU1hcDogVCxcbikgPT4ge1xuICBjb25zdCByZW5kZXJlciA9IGluamVjdChSZW5kZXJlcjIpO1xuXG4gIHJldHVybiBidWlsZFNpZ25hbEVmZmVjdHMoZWwsIHtcbiAgICB0b2tlbk1hcDogYXR0cmlidXRlTWFwLFxuICAgIGNsZWFudXBGbjogKGVsLCB0b2tlbnMpID0+IHRva2Vucy5mb3JFYWNoKCh0b2tlbikgPT4gZWwucmVtb3ZlQXR0cmlidXRlKHRva2VuKSksXG4gICAgdXBkYXRlRm46IChlbCwgdG9rZW5zLCBjb25kaXRpb24pID0+IHtcbiAgICAgIGZvciAoY29uc3QgdG9rZW4gb2YgdG9rZW5zKSB7XG4gICAgICAgIGlmIChBTFdBWVNfVFJVRV9BVFRSSUJVVEVfS0VZUy5pbmNsdWRlcyh0b2tlbikpIHtcbiAgICAgICAgICBpZiAoY29uZGl0aW9uKSB7XG4gICAgICAgICAgICByZW5kZXJlci5zZXRBdHRyaWJ1dGUoZWwsIHRva2VuLCAnJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlbmRlcmVyLnJlbW92ZUF0dHJpYnV0ZShlbCwgdG9rZW4pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb25kaXRpb24gPT09IG51bGwgfHwgY29uZGl0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZW5kZXJlci5yZW1vdmVBdHRyaWJ1dGUoZWwsIHRva2VuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZW5kZXJlci5zZXRBdHRyaWJ1dGUoZWwsIHRva2VuLCBgJHtjb25kaXRpb259YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaWduYWxIb3N0QXR0cmlidXRlcyA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgU2lnbmFsPHVua25vd24+Pj4oYXR0cmlidXRlTWFwOiBUKSA9PlxuICBzaWduYWxBdHRyaWJ1dGVzKGluamVjdChFbGVtZW50UmVmKSwgYXR0cmlidXRlTWFwKTtcblxuZXhwb3J0IGNvbnN0IHNpZ25hbFN0eWxlcyA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgU2lnbmFsPHVua25vd24+Pj4oZWw6IFNpZ25hbEVsZW1lbnRCaW5kaW5nVHlwZSwgc3R5bGVNYXA6IFQpID0+IHtcbiAgY29uc3QgcmVuZGVyZXIgPSBpbmplY3QoUmVuZGVyZXIyKTtcblxuICByZXR1cm4gYnVpbGRTaWduYWxFZmZlY3RzKGVsLCB7XG4gICAgdG9rZW5NYXA6IHN0eWxlTWFwLFxuICAgIGNsZWFudXBGbjogKGVsLCB0b2tlbnMpID0+IHRva2Vucy5mb3JFYWNoKCh0b2tlbikgPT4gcmVuZGVyZXIucmVtb3ZlU3R5bGUoZWwsIHRva2VuLCBSZW5kZXJlclN0eWxlRmxhZ3MyLkRhc2hDYXNlKSksXG4gICAgdXBkYXRlRm46IChlbCwgdG9rZW5zLCBjb25kaXRpb24pID0+IHtcbiAgICAgIGZvciAoY29uc3QgdG9rZW4gb2YgdG9rZW5zKSB7XG4gICAgICAgIGlmIChjb25kaXRpb24gPT09IG51bGwgfHwgY29uZGl0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZW5kZXJlci5yZW1vdmVTdHlsZShlbCwgdG9rZW4sIFJlbmRlcmVyU3R5bGVGbGFnczIuRGFzaENhc2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlbmRlcmVyLnNldFN0eWxlKGVsLCB0b2tlbiwgYCR7Y29uZGl0aW9ufWAsIFJlbmRlcmVyU3R5bGVGbGFnczIuRGFzaENhc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbmFsSG9zdFN0eWxlcyA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgU2lnbmFsPHVua25vd24+Pj4oc3R5bGVNYXA6IFQpID0+XG4gIHNpZ25hbFN0eWxlcyhpbmplY3QoRWxlbWVudFJlZiksIHN0eWxlTWFwKTtcblxuZXhwb3J0IGludGVyZmFjZSBMb2dpY2FsU2l6ZSB7XG4gIGlubGluZVNpemU6IG51bWJlcjtcbiAgYmxvY2tTaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIEVsZW1lbnRSZWN0ID0ge1xuICBib3R0b206IG51bWJlcjtcbiAgaGVpZ2h0OiBudW1iZXI7XG4gIGxlZnQ6IG51bWJlcjtcbiAgcmlnaHQ6IG51bWJlcjtcbiAgdG9wOiBudW1iZXI7XG4gIHdpZHRoOiBudW1iZXI7XG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgRWxlbWVudFNpemUgPSB7XG4gIHdpZHRoOiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xufTtcblxuZXhwb3J0IGNvbnN0IGJvdW5kaW5nQ2xpZW50UmVjdFRvRWxlbWVudFJlY3QgPSAocmVjdDogRE9NUmVjdFJlYWRPbmx5KTogRWxlbWVudFJlY3QgPT4gKHtcbiAgYm90dG9tOiByZWN0LmJvdHRvbSxcbiAgaGVpZ2h0OiByZWN0LmhlaWdodCxcbiAgbGVmdDogcmVjdC5sZWZ0LFxuICByaWdodDogcmVjdC5yaWdodCxcbiAgdG9wOiByZWN0LnRvcCxcbiAgd2lkdGg6IHJlY3Qud2lkdGgsXG4gIHg6IHJlY3QueCxcbiAgeTogcmVjdC55LFxufSk7XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVFbGVtZW50RGltZW5zaW9ucyA9IChlbDogSFRNTEVsZW1lbnQgfCBudWxsLCByZWN0PzogRE9NUmVjdCk6IE51bGxhYmxlRWxlbWVudERpbWVuc2lvbnMgPT4ge1xuICBpZiAoIWVsKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHJlY3Q6IG51bGwsXG4gICAgICBjbGllbnQ6IG51bGwsXG4gICAgICBzY3JvbGw6IG51bGwsXG4gICAgICBvZmZzZXQ6IG51bGwsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IGNhY2hlZE5vcm1hbGl6ZWRSZWN0ID0gcmVjdCA/IGJvdW5kaW5nQ2xpZW50UmVjdFRvRWxlbWVudFJlY3QocmVjdCkgOiBudWxsO1xuICBjb25zdCByZWN0Rm4gPSAoKSA9PlxuICAgIGNhY2hlZE5vcm1hbGl6ZWRSZWN0ID8gY2FjaGVkTm9ybWFsaXplZFJlY3QgOiBib3VuZGluZ0NsaWVudFJlY3RUb0VsZW1lbnRSZWN0KGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcblxuICByZXR1cm4ge1xuICAgIHJlY3Q6IHJlY3RGbixcbiAgICBjbGllbnQ6IHsgd2lkdGg6IGVsLmNsaWVudFdpZHRoLCBoZWlnaHQ6IGVsLmNsaWVudEhlaWdodCB9LFxuICAgIHNjcm9sbDogeyB3aWR0aDogZWwuc2Nyb2xsV2lkdGgsIGhlaWdodDogZWwuc2Nyb2xsSGVpZ2h0IH0sXG4gICAgb2Zmc2V0OiB7IHdpZHRoOiBlbC5vZmZzZXRXaWR0aCwgaGVpZ2h0OiBlbC5vZmZzZXRIZWlnaHQgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCB0eXBlIEVsZW1lbnREaW1lbnNpb25zID0ge1xuICByZWN0OiAoKSA9PiBFbGVtZW50UmVjdDtcbiAgY2xpZW50OiBFbGVtZW50U2l6ZTtcbiAgc2Nyb2xsOiBFbGVtZW50U2l6ZTtcbiAgb2Zmc2V0OiBFbGVtZW50U2l6ZTtcbn07XG5cbmV4cG9ydCB0eXBlIE51bGxhYmxlRWxlbWVudERpbWVuc2lvbnMgPSB7XG4gIFtLIGluIGtleW9mIEVsZW1lbnREaW1lbnNpb25zXTogRWxlbWVudERpbWVuc2lvbnNbS10gfCBudWxsO1xufTtcblxuZXhwb3J0IGNvbnN0IHNpZ25hbEVsZW1lbnREaW1lbnNpb25zID0gKGVsOiBTaWduYWxFbGVtZW50QmluZGluZ1R5cGUpID0+IHtcbiAgY29uc3QgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgY29uc3QgZWxlbWVudHMgPSBidWlsZEVsZW1lbnRTaWduYWwoZWwpO1xuICBjb25zdCB6b25lID0gaW5qZWN0KE5nWm9uZSk7XG4gIGNvbnN0IGlzUmVuZGVyZWQgPSBzaWduYWxJc1JlbmRlcmVkKCk7XG5cbiAgY29uc3QgaW5pdGlhbFZhbHVlID0gKCkgPT4gY3JlYXRlRWxlbWVudERpbWVuc2lvbnMoZWxlbWVudHMoKS5jdXJyZW50RWxlbWVudCk7XG5cbiAgY29uc3QgZWxlbWVudERpbWVuc2lvbnNTaWduYWwgPSBzaWduYWw8TnVsbGFibGVFbGVtZW50RGltZW5zaW9ucz4oaW5pdGlhbFZhbHVlKCkpO1xuXG4gIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKChlKSA9PiB7XG4gICAgaWYgKCFpc1JlbmRlcmVkKCkpIHJldHVybjtcblxuICAgIGNvbnN0IGVudHJ5ID0gZVswXTtcblxuICAgIGlmIChlbnRyeSkge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZW50cnkudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgICAgY29uc3QgbmV3RGltZW5zaW9ucyA9IGNyZWF0ZUVsZW1lbnREaW1lbnNpb25zKHRhcmdldCk7XG5cbiAgICAgIHpvbmUucnVuKCgpID0+IGVsZW1lbnREaW1lbnNpb25zU2lnbmFsLnNldChuZXdEaW1lbnNpb25zKSk7XG4gICAgfVxuICB9KTtcblxuICBlZmZlY3QoXG4gICAgKCkgPT4ge1xuICAgICAgY29uc3QgZWxzID0gZWxlbWVudHMoKTtcblxuICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgZWxlbWVudERpbWVuc2lvbnNTaWduYWwuc2V0KGluaXRpYWxWYWx1ZSgpKTtcblxuICAgICAgICBpZiAoZWxzLnByZXZpb3VzRWxlbWVudCkge1xuICAgICAgICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbHMuY3VycmVudEVsZW1lbnQpIHtcbiAgICAgICAgICBjb25zdCBjb21wdXRlZERpc3BsYXkgPSBnZXRDb21wdXRlZFN0eWxlKGVscy5jdXJyZW50RWxlbWVudCkuZGlzcGxheTtcbiAgICAgICAgICBjb25zdCBjdXJyZW50RWxJc0FuZ3VsYXJDb21wb25lbnQgPSBlbHMuY3VycmVudEVsZW1lbnQ/LnRhZ05hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnLScpO1xuXG4gICAgICAgICAgaWYgKGNvbXB1dGVkRGlzcGxheSA9PT0gJ2lubGluZScgJiYgaXNEZXZNb2RlKCkgJiYgY3VycmVudEVsSXNBbmd1bGFyQ29tcG9uZW50KSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICBgRWxlbWVudCA8JHtlbHMuY3VycmVudEVsZW1lbnQ/LnRhZ05hbWUudG9Mb3dlckNhc2UoKX0+IGlzIGFuIEFuZ3VsYXIgY29tcG9uZW50IGFuZCBoYXMgYSBkaXNwbGF5IG9mICdpbmxpbmUnLiBJbmxpbmUgZWxlbWVudHMgY2Fubm90IGJlIG9ic2VydmVkIGZvciBkaW1lbnNpb25zLiBQbGVhc2UgY2hhbmdlIGl0IHRvICdibG9jaycgb3Igc29tZXRoaW5nIGVsc2UuYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZShlbHMuY3VycmVudEVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9LFxuICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfSxcbiAgKTtcblxuICBkZXN0cm95UmVmLm9uRGVzdHJveSgoKSA9PiBvYnNlcnZlci5kaXNjb25uZWN0KCkpO1xuXG4gIHJldHVybiBjb21wdXRlZCgoKSA9PiBlbGVtZW50RGltZW5zaW9uc1NpZ25hbCgpLCB7XG4gICAgZXF1YWw6IChhLCBiKSA9PiBlcXVhbChhLCBiKSxcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbmFsSG9zdEVsZW1lbnREaW1lbnNpb25zID0gKCkgPT4gc2lnbmFsRWxlbWVudERpbWVuc2lvbnMoaW5qZWN0KEVsZW1lbnRSZWYpKTtcblxuZXhwb3J0IGNvbnN0IHNpZ25hbEVsZW1lbnRNdXRhdGlvbnMgPSAoZWw6IFNpZ25hbEVsZW1lbnRCaW5kaW5nVHlwZSwgb3B0aW9ucz86IE11dGF0aW9uT2JzZXJ2ZXJJbml0KSA9PiB7XG4gIGNvbnN0IGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIGNvbnN0IGVsZW1lbnRzID0gYnVpbGRFbGVtZW50U2lnbmFsKGVsKTtcbiAgY29uc3Qgem9uZSA9IGluamVjdChOZ1pvbmUpO1xuICBjb25zdCBpc1JlbmRlcmVkID0gc2lnbmFsSXNSZW5kZXJlZCgpO1xuXG4gIGNvbnN0IGVsZW1lbnRNdXRhdGlvbnNTaWduYWwgPSBzaWduYWw8TXV0YXRpb25SZWNvcmQgfCBudWxsPihudWxsKTtcblxuICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChlKSA9PiB7XG4gICAgaWYgKCFpc1JlbmRlcmVkKCkpIHJldHVybjtcblxuICAgIGNvbnN0IGVudHJ5ID0gZVswXTtcblxuICAgIGlmIChlbnRyeSkge1xuICAgICAgem9uZS5ydW4oKCkgPT4gZWxlbWVudE11dGF0aW9uc1NpZ25hbC5zZXQoZW50cnkpKTtcbiAgICB9XG4gIH0pO1xuXG4gIGVmZmVjdChcbiAgICAoKSA9PiB7XG4gICAgICBjb25zdCBlbHMgPSBlbGVtZW50cygpO1xuXG4gICAgICBlbGVtZW50TXV0YXRpb25zU2lnbmFsLnNldChudWxsKTtcblxuICAgICAgaWYgKGVscy5wcmV2aW91c0VsZW1lbnQpIHtcbiAgICAgICAgb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZWxzLmN1cnJlbnRFbGVtZW50KSB7XG4gICAgICAgIG9ic2VydmVyLm9ic2VydmUoZWxzLmN1cnJlbnRFbGVtZW50LCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfSxcbiAgKTtcblxuICBkZXN0cm95UmVmLm9uRGVzdHJveSgoKSA9PiBvYnNlcnZlci5kaXNjb25uZWN0KCkpO1xuXG4gIHJldHVybiBlbGVtZW50TXV0YXRpb25zU2lnbmFsLmFzUmVhZG9ubHkoKTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaWduYWxIb3N0RWxlbWVudE11dGF0aW9ucyA9IChvcHRpb25zPzogTXV0YXRpb25PYnNlcnZlckluaXQpID0+XG4gIHNpZ25hbEVsZW1lbnRNdXRhdGlvbnMoaW5qZWN0KEVsZW1lbnRSZWYpLCBvcHRpb25zKTtcblxuZXhwb3J0IHR5cGUgU2lnbmFsRWxlbWVudFNjcm9sbFN0YXRlT3B0aW9ucyA9IHtcbiAgLyoqIFRoZSBpbml0aWFsIHNjcm9sbCBwb3NpdGlvbiB0byBzY3JvbGwgdG8uIE9uY2UgYSB0cnV0aHkgdmFsdWUgZ2V0J3MgZW1pdHRlZCwgYWxsIGZ1cnRoZXIgdmFsdWVzIHdpbGwgYmUgaWdub3JlZC4gKi9cbiAgaW5pdGlhbFNjcm9sbFBvc2l0aW9uPzogU2lnbmFsPFNjcm9sbFRvT3B0aW9ucyB8IG51bGw+O1xufTtcblxuZXhwb3J0IHR5cGUgRWxlbWVudFNjcm9sbFN0YXRlID0ge1xuICBjYW5TY3JvbGw6IGJvb2xlYW47XG4gIGNhblNjcm9sbEhvcml6b250YWxseTogYm9vbGVhbjtcbiAgY2FuU2Nyb2xsVmVydGljYWxseTogYm9vbGVhbjtcbiAgZWxlbWVudERpbWVuc2lvbnM6IE51bGxhYmxlRWxlbWVudERpbWVuc2lvbnM7XG59O1xuXG5leHBvcnQgY29uc3QgYXJlU2Nyb2xsU3RhdGVzRXF1YWwgPSAoYTogRWxlbWVudFNjcm9sbFN0YXRlLCBiOiBFbGVtZW50U2Nyb2xsU3RhdGUpID0+IHtcbiAgcmV0dXJuIChcbiAgICBhLmNhblNjcm9sbCA9PT0gYi5jYW5TY3JvbGwgJiZcbiAgICBhLmNhblNjcm9sbEhvcml6b250YWxseSA9PT0gYi5jYW5TY3JvbGxIb3Jpem9udGFsbHkgJiZcbiAgICBhLmNhblNjcm9sbFZlcnRpY2FsbHkgPT09IGIuY2FuU2Nyb2xsVmVydGljYWxseSAmJlxuICAgIGVxdWFsKGEuZWxlbWVudERpbWVuc2lvbnMsIGIuZWxlbWVudERpbWVuc2lvbnMpXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbmFsRWxlbWVudFNjcm9sbFN0YXRlID0gKGVsOiBTaWduYWxFbGVtZW50QmluZGluZ1R5cGUsIG9wdGlvbnM/OiBTaWduYWxFbGVtZW50U2Nyb2xsU3RhdGVPcHRpb25zKSA9PiB7XG4gIGNvbnN0IGVsZW1lbnRzID0gYnVpbGRFbGVtZW50U2lnbmFsKGVsKTtcbiAgY29uc3Qgb2JzZXJ2ZWRFbCA9IGZpcnN0RWxlbWVudFNpZ25hbChlbGVtZW50cyk7XG4gIGNvbnN0IGVsZW1lbnREaW1lbnNpb25zID0gc2lnbmFsRWxlbWVudERpbWVuc2lvbnMoZWxlbWVudHMpO1xuICBjb25zdCBlbGVtZW50TXV0YXRpb25zID0gc2lnbmFsRWxlbWVudE11dGF0aW9ucyhlbGVtZW50cywgeyBjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IHRydWUsIGF0dHJpYnV0ZXM6IHRydWUgfSk7XG4gIGNvbnN0IGlzUmVuZGVyZWQgPSBzaWduYWxJc1JlbmRlcmVkKCk7XG5cbiAgY29uc3QgaW5pdGlhbFNjcm9sbFBvc2l0aW9uID0gb3B0aW9ucz8uaW5pdGlhbFNjcm9sbFBvc2l0aW9uO1xuXG4gIGlmIChpbml0aWFsU2Nyb2xsUG9zaXRpb24pIHtcbiAgICBjb25zdCByZWYgPSBlZmZlY3QoKCkgPT4ge1xuICAgICAgaWYgKCFpc1JlbmRlcmVkKCkpIHJldHVybjtcblxuICAgICAgY29uc3Qgc2Nyb2xsUG9zaXRpb24gPSBpbml0aWFsU2Nyb2xsUG9zaXRpb24oKTtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBvYnNlcnZlZEVsKCkuY3VycmVudEVsZW1lbnQ7XG5cbiAgICAgIGlmIChzY3JvbGxQb3NpdGlvbiAmJiBlbGVtZW50KSB7XG4gICAgICAgIGlmIChzY3JvbGxQb3NpdGlvbi5sZWZ0ICE9PSB1bmRlZmluZWQpIGVsZW1lbnQuc2Nyb2xsTGVmdCA9IHNjcm9sbFBvc2l0aW9uLmxlZnQ7XG4gICAgICAgIGlmIChzY3JvbGxQb3NpdGlvbi50b3AgIT09IHVuZGVmaW5lZCkgZWxlbWVudC5zY3JvbGxUb3AgPSBzY3JvbGxQb3NpdGlvbi50b3A7XG4gICAgICAgIHJlZi5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBub3RTY3JvbGxhYmxlID0gKGRpbWVuc2lvbnM6IE51bGxhYmxlRWxlbWVudERpbWVuc2lvbnMpID0+ICh7XG4gICAgY2FuU2Nyb2xsOiBmYWxzZSxcbiAgICBjYW5TY3JvbGxIb3Jpem9udGFsbHk6IGZhbHNlLFxuICAgIGNhblNjcm9sbFZlcnRpY2FsbHk6IGZhbHNlLFxuICAgIGVsZW1lbnREaW1lbnNpb25zOiBkaW1lbnNpb25zLFxuICB9KTtcblxuICByZXR1cm4gY29tcHV0ZWQ8RWxlbWVudFNjcm9sbFN0YXRlPihcbiAgICAoKSA9PiB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gb2JzZXJ2ZWRFbCgpLmN1cnJlbnRFbGVtZW50O1xuICAgICAgY29uc3QgZGltZW5zaW9ucyA9IGVsZW1lbnREaW1lbnNpb25zKCk7XG5cbiAgICAgIC8vIFdlIGFyZSBub3QgaW50ZXJlc3RlZCB3aGF0IHRoZSBtdXRhdGlvbiBpcywganVzdCB0aGF0IHRoZXJlIGlzIG9uZS5cbiAgICAgIC8vIENoYW5nZXMgdG8gdGhlIERPTSBjYW4gYWZmZWN0IHRoZSBzY3JvbGwgc3RhdGUgb2YgdGhlIGVsZW1lbnQuXG4gICAgICBlbGVtZW50TXV0YXRpb25zKCk7XG5cbiAgICAgIGlmICghZWxlbWVudCB8fCAhaXNSZW5kZXJlZCgpKSByZXR1cm4gbm90U2Nyb2xsYWJsZShkaW1lbnNpb25zKTtcblxuICAgICAgY29uc3QgeyBzY3JvbGxXaWR0aCwgc2Nyb2xsSGVpZ2h0LCBjbGllbnRIZWlnaHQsIGNsaWVudFdpZHRoIH0gPSBlbGVtZW50O1xuXG4gICAgICBjb25zdCBjYW5TY3JvbGxIb3Jpem9udGFsbHkgPSBzY3JvbGxXaWR0aCA+IGNsaWVudFdpZHRoO1xuICAgICAgY29uc3QgY2FuU2Nyb2xsVmVydGljYWxseSA9IHNjcm9sbEhlaWdodCA+IGNsaWVudEhlaWdodDtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY2FuU2Nyb2xsOiBjYW5TY3JvbGxIb3Jpem9udGFsbHkgfHwgY2FuU2Nyb2xsVmVydGljYWxseSxcbiAgICAgICAgY2FuU2Nyb2xsSG9yaXpvbnRhbGx5LFxuICAgICAgICBjYW5TY3JvbGxWZXJ0aWNhbGx5LFxuICAgICAgICBlbGVtZW50RGltZW5zaW9uczogZGltZW5zaW9ucyxcbiAgICAgIH07XG4gICAgfSxcbiAgICB7IGVxdWFsOiAoYSwgYikgPT4gYXJlU2Nyb2xsU3RhdGVzRXF1YWwoYSwgYikgfSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaWduYWxIb3N0RWxlbWVudFNjcm9sbFN0YXRlID0gKCkgPT4gc2lnbmFsRWxlbWVudFNjcm9sbFN0YXRlKGluamVjdChFbGVtZW50UmVmKSk7XG5cbmV4cG9ydCB0eXBlIFNpZ25hbEVsZW1lbnRJbnRlcnNlY3Rpb25PcHRpb25zID0gT21pdDxJbnRlcnNlY3Rpb25PYnNlcnZlckluaXQsICdyb290Jz4gJiB7XG4gIHJvb3Q/OiBTaWduYWxFbGVtZW50QmluZGluZ1R5cGU7XG4gIGVuYWJsZWQ/OiBTaWduYWw8Ym9vbGVhbj47XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbmFsRWxlbWVudEludGVyc2VjdGlvbiA9IChlbDogU2lnbmFsRWxlbWVudEJpbmRpbmdUeXBlLCBvcHRpb25zPzogU2lnbmFsRWxlbWVudEludGVyc2VjdGlvbk9wdGlvbnMpID0+IHtcbiAgY29uc3QgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgY29uc3QgZWxlbWVudHMgPSBidWlsZEVsZW1lbnRTaWduYWwoZWwpO1xuICBjb25zdCByb290ID0gZmlyc3RFbGVtZW50U2lnbmFsKG9wdGlvbnM/LnJvb3QgPyBidWlsZEVsZW1lbnRTaWduYWwob3B0aW9ucz8ucm9vdCkgOiBkb2N1bWVudEVsZW1lbnRTaWduYWwoKSk7XG4gIGNvbnN0IHpvbmUgPSBpbmplY3QoTmdab25lKTtcbiAgY29uc3QgaXNSZW5kZXJlZCA9IHNpZ25hbElzUmVuZGVyZWQoKTtcbiAgY29uc3QgaXNFbmFibGVkID0gb3B0aW9ucz8uZW5hYmxlZCA/PyBzaWduYWwodHJ1ZSk7XG5cbiAgY29uc3QgZWxlbWVudEludGVyc2VjdGlvblNpZ25hbCA9IHNpZ25hbDxJbnRlcnNlY3Rpb25PYnNlcnZlckVudHJ5W10+KFtdKTtcbiAgY29uc3Qgb2JzZXJ2ZXIgPSBzaWduYWw8SW50ZXJzZWN0aW9uT2JzZXJ2ZXIgfCBudWxsPihudWxsKTtcblxuICBjb25zdCBjdXJyZW50bHlPYnNlcnZlZEVsZW1lbnRzID0gbmV3IFNldDxIVE1MRWxlbWVudD4oKTtcblxuICBjb25zdCB1cGRhdGVJbnRlcnNlY3Rpb25zID0gKGVudHJpZXM6IEludGVyc2VjdGlvbk9ic2VydmVyRW50cnlbXSkgPT4ge1xuICAgIGxldCBjdXJyZW50VmFsdWVzID0gWy4uLmVsZW1lbnRJbnRlcnNlY3Rpb25TaWduYWwoKV07XG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nRW50cnlJbmRleCA9IGN1cnJlbnRWYWx1ZXMuZmluZEluZGV4KCh2KSA9PiB2LnRhcmdldCA9PT0gZW50cnkudGFyZ2V0KTtcblxuICAgICAgLy8gUm91bmQgdGhlIGludGVyc2VjdGlvbiByYXRpbyB0byB0aGUgbmVhcmVzdCAwLjAxIHRvIGF2b2lkIGZsb2F0aW5nIHBvaW50IGVycm9ycyBhbmQgc3lzdGVtIHNjYWxpbmcgaXNzdWVzLlxuICAgICAgY29uc3Qgcm91bmRlZEludGVyc2VjdGlvblJhdGlvID0gTWF0aC5yb3VuZChlbnRyeS5pbnRlcnNlY3Rpb25SYXRpbyAqIDEwMCkgLyAxMDA7XG5cbiAgICAgIGNvbnN0IGludGVyc2VjdGlvbkVudHJ5OiBJbnRlcnNlY3Rpb25PYnNlcnZlckVudHJ5ID0ge1xuICAgICAgICBib3VuZGluZ0NsaWVudFJlY3Q6IGVudHJ5LmJvdW5kaW5nQ2xpZW50UmVjdCxcbiAgICAgICAgaW50ZXJzZWN0aW9uUmF0aW86IHJvdW5kZWRJbnRlcnNlY3Rpb25SYXRpbyxcbiAgICAgICAgaW50ZXJzZWN0aW9uUmVjdDogZW50cnkuaW50ZXJzZWN0aW9uUmVjdCxcbiAgICAgICAgaXNJbnRlcnNlY3Rpbmc6IGVudHJ5LmlzSW50ZXJzZWN0aW5nLFxuICAgICAgICByb290Qm91bmRzOiBlbnRyeS5yb290Qm91bmRzLFxuICAgICAgICB0YXJnZXQ6IGVudHJ5LnRhcmdldCxcbiAgICAgICAgdGltZTogZW50cnkudGltZSxcbiAgICAgIH07XG5cbiAgICAgIGlmIChleGlzdGluZ0VudHJ5SW5kZXggIT09IC0xKSB7XG4gICAgICAgIGN1cnJlbnRWYWx1ZXMgPSBbXG4gICAgICAgICAgLi4uY3VycmVudFZhbHVlcy5zbGljZSgwLCBleGlzdGluZ0VudHJ5SW5kZXgpLFxuICAgICAgICAgIGludGVyc2VjdGlvbkVudHJ5LFxuICAgICAgICAgIC4uLmN1cnJlbnRWYWx1ZXMuc2xpY2UoZXhpc3RpbmdFbnRyeUluZGV4ICsgMSksXG4gICAgICAgIF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdXJyZW50VmFsdWVzID0gWy4uLmN1cnJlbnRWYWx1ZXMsIGludGVyc2VjdGlvbkVudHJ5XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB6b25lLnJ1bigoKSA9PiBlbGVtZW50SW50ZXJzZWN0aW9uU2lnbmFsLnNldChjdXJyZW50VmFsdWVzKSk7XG4gIH07XG5cbiAgY29uc3QgdXBkYXRlSW50ZXJzZWN0aW9uT2JzZXJ2ZXIgPSAocmVuZGVyZWQ6IGJvb2xlYW4sIGVuYWJsZWQ6IGJvb2xlYW4sIHJvb3RFbDogSFRNTEVsZW1lbnQgfCBudWxsKSA9PiB7XG4gICAgb2JzZXJ2ZXIoKT8uZGlzY29ubmVjdCgpO1xuICAgIGN1cnJlbnRseU9ic2VydmVkRWxlbWVudHMuY2xlYXIoKTtcblxuICAgIGlmICghcmVuZGVyZWQgfHwgIWVuYWJsZWQgfHwgIXJvb3RFbCkge1xuICAgICAgb2JzZXJ2ZXIuc2V0KG51bGwpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5ld09ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbnRyaWVzKSA9PiB1cGRhdGVJbnRlcnNlY3Rpb25zKGVudHJpZXMpLCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgcm9vdDogcm9vdEVsLFxuICAgIH0pO1xuXG4gICAgb2JzZXJ2ZXIuc2V0KG5ld09ic2VydmVyKTtcbiAgfTtcblxuICBjb25zdCB1cGRhdGVPYnNlcnZlZEVsZW1lbnRzID0gKG9ic2VydmVyOiBJbnRlcnNlY3Rpb25PYnNlcnZlciB8IG51bGwsIGVsZW1lbnRzOiBFbGVtZW50U2lnbmFsVmFsdWUpID0+IHtcbiAgICBjb25zdCByb290RWwgPSByb290KCkuY3VycmVudEVsZW1lbnQ7XG5cbiAgICBpZiAoIW9ic2VydmVyIHx8ICFyb290RWwpIHJldHVybjtcblxuICAgIGNvbnN0IHJvb3RCb3VuZHMgPSByb290RWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBjb25zdCBjdXJySW50ZXJzZWN0aW9uVmFsdWUgPSBlbGVtZW50SW50ZXJzZWN0aW9uU2lnbmFsKCk7XG4gICAgY29uc3QgbmV3SW50ZXJzZWN0aW9uVmFsdWU6IEludGVyc2VjdGlvbk9ic2VydmVyRW50cnlbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBlbCBvZiBlbGVtZW50cy5jdXJyZW50RWxlbWVudHMpIHtcbiAgICAgIGlmIChjdXJyZW50bHlPYnNlcnZlZEVsZW1lbnRzLmhhcyhlbCkpIHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdFbnRyeUluZGV4ID0gY3VyckludGVyc2VjdGlvblZhbHVlLmZpbmRJbmRleCgodikgPT4gdi50YXJnZXQgPT09IGVsKTtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdFbnRyeSA9IGN1cnJJbnRlcnNlY3Rpb25WYWx1ZVtleGlzdGluZ0VudHJ5SW5kZXhdO1xuXG4gICAgICAgIGlmICghZXhpc3RpbmdFbnRyeSkge1xuICAgICAgICAgIGNvbnNvbGUud2FybignQ291bGQgbm90IGZpbmQgZXhpc3RpbmcgZW50cnkgZm9yIGVsZW1lbnQuIFRoZSBpbnRlcnNlY3Rpb24gb2JzZXJ2ZXIgbWlnaHQgYmUgYnJva2VuIG5vdy4nLCBlbCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBuZXdJbnRlcnNlY3Rpb25WYWx1ZS5wdXNoKGV4aXN0aW5nRW50cnkpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZWxCb3VuZHMgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgY29uc3QgaW5pdGlhbEVsZW1lbnRWaXNpYmlsaXR5ID0gaXNFbGVtZW50VmlzaWJsZSh7XG4gICAgICAgIGNvbnRhaW5lcjogcm9vdEVsLFxuICAgICAgICBlbGVtZW50OiBlbCxcbiAgICAgICAgY29udGFpbmVyUmVjdDogcm9vdEJvdW5kcyxcbiAgICAgICAgZWxlbWVudFJlY3Q6IGVsQm91bmRzLFxuICAgICAgfSk7XG5cbiAgICAgIGlmICghaW5pdGlhbEVsZW1lbnRWaXNpYmlsaXR5KSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ05vIHZpc2liaWxpdHkgZGF0YSBmb3VuZCBmb3IgZWxlbWVudC4nLCB7XG4gICAgICAgICAgZWxlbWVudDogZWwsXG4gICAgICAgICAgY29udGFpbmVyOiByb290RWwsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpbnRlcnNlY3Rpb25FbnRyeTogSW50ZXJzZWN0aW9uT2JzZXJ2ZXJFbnRyeSA9IHtcbiAgICAgICAgYm91bmRpbmdDbGllbnRSZWN0OiBlbEJvdW5kcyxcbiAgICAgICAgaW50ZXJzZWN0aW9uUmF0aW86IGluaXRpYWxFbGVtZW50VmlzaWJpbGl0eS5pbnRlcnNlY3Rpb25SYXRpbyxcbiAgICAgICAgaW50ZXJzZWN0aW9uUmVjdDogZWxCb3VuZHMsXG4gICAgICAgIGlzSW50ZXJzZWN0aW5nOiBpbml0aWFsRWxlbWVudFZpc2liaWxpdHkuaXNJbnRlcnNlY3RpbmcsXG4gICAgICAgIHJvb3RCb3VuZHM6IHJvb3RCb3VuZHMsXG4gICAgICAgIHRhcmdldDogZWwsXG4gICAgICAgIHRpbWU6IHBlcmZvcm1hbmNlLm5vdygpLFxuICAgICAgfTtcblxuICAgICAgbmV3SW50ZXJzZWN0aW9uVmFsdWUucHVzaChpbnRlcnNlY3Rpb25FbnRyeSk7XG5cbiAgICAgIGN1cnJlbnRseU9ic2VydmVkRWxlbWVudHMuYWRkKGVsKTtcbiAgICAgIG9ic2VydmVyLm9ic2VydmUoZWwpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZWwgb2YgZWxlbWVudHMucHJldmlvdXNFbGVtZW50cykge1xuICAgICAgaWYgKGVsZW1lbnRzLmN1cnJlbnRFbGVtZW50cy5pbmNsdWRlcyhlbCkpIGNvbnRpbnVlO1xuXG4gICAgICBvYnNlcnZlci51bm9ic2VydmUoZWwpO1xuICAgICAgY3VycmVudGx5T2JzZXJ2ZWRFbGVtZW50cy5kZWxldGUoZWwpO1xuICAgIH1cblxuICAgIGVsZW1lbnRJbnRlcnNlY3Rpb25TaWduYWwuc2V0KG5ld0ludGVyc2VjdGlvblZhbHVlKTtcbiAgfTtcblxuICBlZmZlY3QoXG4gICAgKCkgPT4ge1xuICAgICAgY29uc3Qgcm9vdEVsID0gcm9vdCgpLmN1cnJlbnRFbGVtZW50O1xuICAgICAgY29uc3QgcmVuZGVyZWQgPSBpc1JlbmRlcmVkKCk7XG4gICAgICBjb25zdCBlbmFibGVkID0gaXNFbmFibGVkKCk7XG5cbiAgICAgIHVudHJhY2tlZCgoKSA9PiB1cGRhdGVJbnRlcnNlY3Rpb25PYnNlcnZlcihyZW5kZXJlZCwgZW5hYmxlZCwgcm9vdEVsKSk7XG4gICAgfSxcbiAgICB7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH0sXG4gICk7XG5cbiAgZWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBlbHMgPSBlbGVtZW50cygpO1xuICAgIGNvbnN0IG9icyA9IG9ic2VydmVyKCk7XG5cbiAgICB1bnRyYWNrZWQoKCkgPT4gdXBkYXRlT2JzZXJ2ZWRFbGVtZW50cyhvYnMsIGVscykpO1xuICB9KTtcblxuICBkZXN0cm95UmVmLm9uRGVzdHJveSgoKSA9PiBvYnNlcnZlcigpPy5kaXNjb25uZWN0KCkpO1xuXG4gIHJldHVybiBlbGVtZW50SW50ZXJzZWN0aW9uU2lnbmFsLmFzUmVhZG9ubHkoKTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaWduYWxIb3N0RWxlbWVudEludGVyc2VjdGlvbiA9IChvcHRpb25zPzogU2lnbmFsRWxlbWVudEludGVyc2VjdGlvbk9wdGlvbnMpID0+XG4gIHNpZ25hbEVsZW1lbnRJbnRlcnNlY3Rpb24oaW5qZWN0KEVsZW1lbnRSZWYpLCBvcHRpb25zKTtcblxuZXhwb3J0IGNvbnN0IHNpZ25hbEVsZW1lbnRDaGlsZHJlbiA9IChlbDogU2lnbmFsRWxlbWVudEJpbmRpbmdUeXBlKSA9PiB7XG4gIGNvbnN0IGVsZW1lbnRzID0gYnVpbGRFbGVtZW50U2lnbmFsKGVsKTtcbiAgY29uc3QgaXNSZW5kZXJlZCA9IHNpZ25hbElzUmVuZGVyZWQoKTtcbiAgY29uc3QgZWxlbWVudE11dGF0aW9ucyA9IHNpZ25hbEVsZW1lbnRNdXRhdGlvbnMoZWxlbWVudHMsIHsgY2hpbGRMaXN0OiB0cnVlLCBzdWJ0cmVlOiB0cnVlLCBhdHRyaWJ1dGVzOiB0cnVlIH0pO1xuXG4gIHJldHVybiBjb21wdXRlZChcbiAgICAoKSA9PiB7XG4gICAgICBpZiAoIWlzUmVuZGVyZWQoKSkgcmV0dXJuIFtdO1xuXG4gICAgICBjb25zdCBlbHMgPSBlbGVtZW50cygpO1xuXG4gICAgICAvLyBXZSBhcmUgbm90IGludGVyZXN0ZWQgd2hhdCB0aGUgbXV0YXRpb24gaXMsIGp1c3QgdGhhdCB0aGVyZSBpcyBvbmUuXG4gICAgICAvLyBDaGFuZ2VzIHRvIHRoZSBET00gbWF5IGFmZmVjdCB0aGUgY2hpbGRyZW4gb2YgdGhlIGVsZW1lbnQuXG4gICAgICBlbGVtZW50TXV0YXRpb25zKCk7XG5cbiAgICAgIGlmICghZWxzLmN1cnJlbnRFbGVtZW50KSByZXR1cm4gW107XG5cbiAgICAgIGNvbnN0IGNoaWxkcmVuOiBIVE1MRWxlbWVudFtdID0gW107XG5cbiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBlbHMuY3VycmVudEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBlbHMuY3VycmVudEVsZW1lbnQuY2hpbGRyZW5baW5kZXhdO1xuXG4gICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICBjaGlsZHJlbi5wdXNoKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjaGlsZHJlbjtcbiAgICB9LFxuICAgIHsgZXF1YWw6IChhLCBiKSA9PiBhLmxlbmd0aCA9PT0gYi5sZW5ndGggJiYgYS5ldmVyeSgodiwgaSkgPT4gdiA9PT0gYltpXSkgfSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwcmV2aW91c1NpZ25hbFZhbHVlID0gPFQ+KHNpZ25hbDogU2lnbmFsPFQ+KSA9PiB7XG4gIGNvbnN0IG9icyA9IHRvT2JzZXJ2YWJsZShzaWduYWwpLnBpcGUoXG4gICAgcGFpcndpc2UoKSxcbiAgICBtYXAoKFtwcmV2XSkgPT4gcHJldiksXG4gICk7XG5cbiAgcmV0dXJuIHRvU2lnbmFsKG9icyk7XG59O1xuXG5leHBvcnQgdHlwZSBTeW5jU2lnbmFsT3B0aW9ucyA9IHtcbiAgLyoqXG4gICAqIElmIHRydWUsIHRoZSB0YXJnZXQgc2lnbmFsIHdpbGwgbm90IGJlIHVwZGF0ZWQgd2l0aCB0aGUgc291cmNlIHNpZ25hbCdzIHZhbHVlIGluIGEgc3luYyBvcGVyYXRpb24uXG4gICAqIFRoaXMgc2hvdWxkIGJlIHNldCB0byB0cnVlIGZvciBzaWduYWxzIHRoYXQgbmVlZCB0byBiZSBpbml0aWFsaXplZCBmaXJzdCBiZWZvcmUgc3luY2luZyAoZWcuIHJlcXVpcmVkIGlucHV0cylcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHNraXBTeW5jUmVhZD86IGJvb2xlYW47XG59O1xuXG5leHBvcnQgY29uc3Qgc3luY1NpZ25hbCA9IDxUPihmcm9tOiBTaWduYWw8VD4sIHRvOiBXcml0YWJsZVNpZ25hbDxUPiwgb3B0aW9ucz86IFN5bmNTaWduYWxPcHRpb25zKSA9PiB7XG4gIGxldCBpc0ZpcnN0UnVuID0gb3B0aW9ucz8uc2tpcFN5bmNSZWFkID8gZmFsc2UgOiB0cnVlO1xuXG4gIGlmICghb3B0aW9ucz8uc2tpcFN5bmNSZWFkKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIHRoaXMgbWlnaHQgdGhyb3cgaWYgdGhlIHNpZ25hbCBpcyBub3QgeWV0IGluaXRpYWxpemVkIChlZy4gYSByZXF1aXJlZCBzaWduYWwgaW5wdXQgaW5zaWRlIHRoZSBjb25zdHJ1Y3RvcilcbiAgICAgIC8vIGluIHRoYXQgY2FzZSB3ZSBqdXN0IHNraXAgdGhlIGluaXRpYWwgc3luY1xuICAgICAgdG8uc2V0KGZyb20oKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBpc0ZpcnN0UnVuID0gZmFsc2U7XG5cbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBzeW5jIHNpZ25hbHMuIFRoZSB0YXJnZXQgc2lnbmFsIGlzIG5vdCB5ZXQgaW5pdGlhbGl6ZWQuJywgeyBmcm9tLCB0byB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCByZWYgPSBlZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGZvcm1WYWwgPSBmcm9tKCk7XG5cbiAgICBpZiAoaXNGaXJzdFJ1bikge1xuICAgICAgaXNGaXJzdFJ1biA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHVudHJhY2tlZCgoKSA9PiB7XG4gICAgICB0by5zZXQoZm9ybVZhbCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiByZWY7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbnRyb2xWYWx1ZVNpZ25hbE9wdGlvbnMge1xuICBkZWJvdW5jZVRpbWU/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBkZWJvdW5jZUZpcnN0PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNvbnN0IGNvbnRyb2xWYWx1ZVNpZ25hbCA9IDxcbiAgVCBleHRlbmRzIFNpZ25hbDxBYnN0cmFjdENvbnRyb2wgfCBudWxsPiB8IEFic3RyYWN0Q29udHJvbCxcbiAgSiBleHRlbmRzIFQgZXh0ZW5kcyBTaWduYWw8aW5mZXIgST4gPyBJIDogVCxcbj4oXG4gIGNvbnRyb2w6IFQsXG4gIG9wdGlvbnM/OiBDb250cm9sVmFsdWVTaWduYWxPcHRpb25zLFxuKSA9PiB7XG4gIGNvbnN0IGluaXRpYWxWYWx1ZSA9IGRlZmVycmVkU2lnbmFsKCgpID0+IChpc1NpZ25hbChjb250cm9sKSA/IGNvbnRyb2woKSA6IChjb250cm9sIGFzIEFic3RyYWN0Q29udHJvbCkpKTtcblxuICBjb25zdCBjb250cm9sU3RyZWFtID0gaXNTaWduYWwoY29udHJvbClcbiAgICA/IHRvT2JzZXJ2YWJsZTxBYnN0cmFjdENvbnRyb2wgfCBudWxsPihjb250cm9sKVxuICAgIDogb2Y8QWJzdHJhY3RDb250cm9sIHwgbnVsbD4oY29udHJvbCk7XG5cbiAgY29uc3QgY29udHJvbE9icyA9IGNvbnRyb2xTdHJlYW0ucGlwZShcbiAgICBzd2l0Y2hNYXAoKGNvbnRyb2wpID0+IHtcbiAgICAgIGlmICghY29udHJvbCkgcmV0dXJuIG9mKG51bGwpO1xuXG4gICAgICBjb25zdCB2Y3NPYnMgPSBvcHRpb25zPy5kZWJvdW5jZVRpbWVcbiAgICAgICAgPyBjb250cm9sLnZhbHVlQ2hhbmdlcy5waXBlKGRlYm91bmNlVGltZShvcHRpb25zLmRlYm91bmNlVGltZSkpXG4gICAgICAgIDogY29udHJvbC52YWx1ZUNoYW5nZXM7XG5cbiAgICAgIHJldHVybiB2Y3NPYnMucGlwZShtYXAoKCkgPT4gY29udHJvbC5nZXRSYXdWYWx1ZSgpKSk7XG4gICAgfSksXG4gICk7XG5cbiAgY29uc3QgaXNSZW5kZXJlZCA9IHRvT2JzZXJ2YWJsZShzaWduYWxJc1JlbmRlcmVkKCkpLnBpcGUoZmlsdGVyKCh2KSA9PiB2KSk7XG4gIGNvbnN0IG9iczogT2JzZXJ2YWJsZTxSZXR1cm5UeXBlPE5vbk51bGxhYmxlPEo+WydnZXRSYXdWYWx1ZSddPj4gPSAhb3B0aW9ucz8uZGVib3VuY2VGaXJzdFxuICAgID8gaXNSZW5kZXJlZC5waXBlKHN3aXRjaE1hcCgoKSA9PiBtZXJnZShvZihpbml0aWFsVmFsdWUoKT8uZ2V0UmF3VmFsdWUoKSksIGNvbnRyb2xPYnMpKSlcbiAgICA6IGlzUmVuZGVyZWQucGlwZShzd2l0Y2hNYXAoKCkgPT4gY29udHJvbE9icykpO1xuXG4gIHJldHVybiB0b1NpZ25hbChvYnMucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgoYSwgYikgPT4gZXF1YWwoYSwgYikpKSwge1xuICAgIGluaXRpYWxWYWx1ZTogbnVsbCxcbiAgfSk7XG59O1xuXG4vKipcbiAqIFRoZSBmaXJzdCBpdGVtIGluIHRoZSBwYWlyIGlzIHRoZSBwcmV2aW91cyB2YWx1ZSBhbmQgdGhlIHNlY29uZCBpdGVtIGlzIHRoZSBjdXJyZW50IHZhbHVlLlxuICovXG5leHBvcnQgY29uc3QgY29udHJvbFZhbHVlU2lnbmFsV2l0aFByZXZpb3VzID0gPFQgZXh0ZW5kcyBBYnN0cmFjdENvbnRyb2w+KFxuICBjb250cm9sOiBULFxuICBvcHRpb25zPzogQ29udHJvbFZhbHVlU2lnbmFsT3B0aW9ucyxcbikgPT4ge1xuICBjb25zdCBvYnMgPSB0b09ic2VydmFibGUoY29udHJvbFZhbHVlU2lnbmFsKGNvbnRyb2wsIG9wdGlvbnMpKS5waXBlKFxuICAgIHBhaXJ3aXNlKCksXG4gICAgc3RhcnRXaXRoKFtudWxsLCBjb250cm9sLmdldFJhd1ZhbHVlKCldKSxcbiAgKTtcblxuICByZXR1cm4gdG9TaWduYWwob2JzLCB7IHJlcXVpcmVTeW5jOiB0cnVlIH0pO1xufTtcblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgYGNvbnRyb2xWYWx1ZVNpZ25hbGAgaW5zdGVhZCB3aXRoIGBkZWJvdW5jZVRpbWVgIG9wdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZWJvdW5jZWRDb250cm9sVmFsdWVTaWduYWxPcHRpb25zIHtcbiAgLyoqXG4gICAqIEBkZWZhdWx0IDMwMFxuICAgKi9cbiAgZGVib3VuY2VUaW1lPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEBkZXByZWNhdGVkIFVzZSBgY29udHJvbFZhbHVlU2lnbmFsYCBpbnN0ZWFkIHdpdGggYGRlYm91bmNlVGltZWAgc2V0IHRvIGAzMDBgIGFuZCBgZGVib3VuY2VGaXJzdGAgc2V0IHRvIGB0cnVlYC5cbiAqL1xuZXhwb3J0IGNvbnN0IGRlYm91bmNlZENvbnRyb2xWYWx1ZVNpZ25hbCA9IDxUIGV4dGVuZHMgRm9ybUNvbnRyb2w+KFxuICBjb250cm9sOiBULFxuICBvcHRpb25zPzogRGVib3VuY2VkQ29udHJvbFZhbHVlU2lnbmFsT3B0aW9ucyxcbikgPT4gY29udHJvbFZhbHVlU2lnbmFsKGNvbnRyb2wsIG9wdGlvbnMgPz8geyBkZWJvdW5jZVRpbWU6IDMwMCwgZGVib3VuY2VGaXJzdDogdHJ1ZSB9KTtcblxuZXhwb3J0IHR5cGUgSW5qZWN0VXRpbENvbmZpZyA9IHtcbiAgLyoqIFRoZSBpbmplY3RvciB0byB1c2UgZm9yIHRoZSBpbmplY3Rpb24uIE11c3QgYmUgcHJvdmlkZWQgaWYgdGhlIGZ1bmN0aW9uIGlzIG5vdCBjYWxsZWQgZnJvbSB3aXRoaW4gYSBpbmplY3Rpb24gY29udGV4dC4gKi9cbiAgaW5qZWN0b3I/OiBJbmplY3Rvcjtcbn07XG5cbmV4cG9ydCB0eXBlIEluamVjdFV0aWxUcmFuc2Zvcm1Db25maWc8SW4sIE91dD4gPSB7XG4gIC8qKlxuICAgKiBBIHRyYW5zZm9ybSBmdW5jdGlvbiBzaW1pbGFyIHRvIHRoZSBgdHJhbnNmb3JtYCBmdW5jdGlvbiBpbiBBbmd1bGFyIGlucHV0IGJpbmRpbmdzLlxuICAgKiBDYW4gYmUgdXNlZCB0byB0cmFuc2Zvcm0gdGhlIHZhbHVlIGJlZm9yZSBpdCBpcyByZXR1cm5lZC5cbiAgICogRS5nLiB0cmFuc2Zvcm1pbmcgYFwidHJ1ZVwiYCB0byBgdHJ1ZWAgZm9yIGEgYm9vbGVhbiBhdHRyaWJ1dGUuXG4gICAqL1xuICB0cmFuc2Zvcm0/OiAodmFsdWU6IEluKSA9PiBPdXQ7XG59O1xuXG5leHBvcnQgY29uc3QgdHJhbnNmb3JtT3JSZXR1cm4gPSA8SW4sIE91dD4oc3JjOiBTaWduYWw8SW4+LCBjb25maWc/OiBJbmplY3RVdGlsVHJhbnNmb3JtQ29uZmlnPEluLCBPdXQ+KSA9PiB7XG4gIGNvbnN0IHRyYW5zZm9ybWVyID0gY29uZmlnPy50cmFuc2Zvcm07XG5cbiAgaWYgKHRyYW5zZm9ybWVyKSB7XG4gICAgcmV0dXJuIGNvbXB1dGVkKCgpID0+IHRyYW5zZm9ybWVyKHNyYygpKSk7XG4gIH1cblxuICByZXR1cm4gc3JjIGFzIHVua25vd24gYXMgU2lnbmFsPE91dD47XG59O1xuXG4vKiogSW5qZWN0IHRoZSBjdXJyZW50IHJvdXRlciBldmVudCAqL1xuZXhwb3J0IGNvbnN0IGluamVjdFJvdXRlckV2ZW50ID0gKCkgPT4ge1xuICBjb25zdCByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcblxuICByZXR1cm4gdG9TaWduYWwocm91dGVyLmV2ZW50cywgeyBpbml0aWFsVmFsdWU6IG51bGwgfSk7XG59O1xuXG4vKipcbiAqIEluamVjdCB0aGUgY3VycmVudCB1cmwuXG4gKiBUaGUgdXJsIGluY2x1ZGVzIHF1ZXJ5IHBhcmFtcyBhcyB3ZWxsIGFzIHRoZSBmcmFnbWVudC4gVXNlIGBpbmplY3RSb3V0ZWAgaW5zdGVhZCBpZiB5b3UgYXJlIG5vdCBpbnRydXN0ZWQgaW4gdGhvc2UuXG4gKiBAZXhhbXBsZSBcIi9teS1wYWdlP3F1ZXJ5PTEmcGFyYW09dHJ1ZSNmcmFnbWVudFwiXG4gKi9cbmV4cG9ydCBjb25zdCBpbmplY3RVcmwgPSAoKSA9PiB7XG4gIGNvbnN0IGV2ZW50ID0gaW5qZWN0Um91dGVyRXZlbnQoKTtcbiAgY29uc3Qgcm91dGVyID0gaW5qZWN0KFJvdXRlcik7XG5cbiAgY29uc3QgdXJsID0gc2lnbmFsKHJvdXRlci51cmwpO1xuXG4gIGVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgY3VycmVudEV2ZW50ID0gZXZlbnQoKTtcblxuICAgIHVudHJhY2tlZCgoKSA9PiB7XG4gICAgICBpZiAoY3VycmVudEV2ZW50IGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCkge1xuICAgICAgICB1cmwuc2V0KGN1cnJlbnRFdmVudC51cmxBZnRlclJlZGlyZWN0cyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiB1cmwuYXNSZWFkb25seSgpO1xufTtcblxuLyoqXG4gKiBJbmplY3QgdGhlIGN1cnJlbnQgcm91dGVcbiAqIEBleGFtcGxlIFwiL215LXBhZ2VcIlxuICovXG5leHBvcnQgY29uc3QgaW5qZWN0Um91dGUgPSAoKSA9PiB7XG4gIGNvbnN0IHVybCA9IGluamVjdFVybCgpO1xuXG4gIHJldHVybiBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgZnVsbFVybCA9IHVybCgpO1xuICAgIGNvbnN0IHVybFdpdGhvdXRRdWVyeVBhcmFtcyA9IGZ1bGxVcmwuc3BsaXQoJz8nKVswXSA/PyAnJztcbiAgICBjb25zdCB3aXRob3V0RnJhZ21lbnQgPSB1cmxXaXRob3V0UXVlcnlQYXJhbXMuc3BsaXQoJyMnKVswXSA/PyAnJztcblxuICAgIHJldHVybiB3aXRob3V0RnJhZ21lbnQ7XG4gIH0pO1xufTtcblxuY29uc3QgY3JlYXRlUm91dGVyU3RhdGUgPSAocm91dGVyOiBSb3V0ZXIpID0+IHtcbiAgbGV0IHJvdXRlID0gcm91dGVyLnJvdXRlclN0YXRlLnNuYXBzaG90LnJvb3Q7XG5cbiAgd2hpbGUgKHJvdXRlLmZpcnN0Q2hpbGQpIHtcbiAgICByb3V0ZSA9IHJvdXRlLmZpcnN0Q2hpbGQ7XG4gIH1cblxuICBjb25zdCB7IGRhdGEsIHBhcmFtcywgcXVlcnlQYXJhbXMsIHRpdGxlLCBmcmFnbWVudCB9ID0gcm91dGU7XG5cbiAgcmV0dXJuIHtcbiAgICBkYXRhLFxuICAgIHBhdGhQYXJhbXM6IHBhcmFtcyxcbiAgICBxdWVyeVBhcmFtcyxcbiAgICB0aXRsZTogdGl0bGUgPz8gbnVsbCxcbiAgICBmcmFnbWVudCxcbiAgfTtcbn07XG5cbi8qKlxuICogSW5qZWN0IHRoZSBjb21wbGV0ZSByb3V0ZXIgc3RhdGUuIFRoaXMgaW5jbHVkZXMgdGhlIGN1cnJlbnQgcm91dGUgZGF0YSwgcGF0aCBwYXJhbXMsIHF1ZXJ5IHBhcmFtcywgdGl0bGUgYW5kIGZyYWdtZW50LlxuICovXG5leHBvcnQgY29uc3QgaW5qZWN0Um91dGVyU3RhdGUgPSAoKSA9PiB7XG4gIGNvbnN0IHVybCA9IGluamVjdFVybCgpO1xuICBjb25zdCByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcblxuICBjb25zdCByb3V0ZXJTdGF0ZSA9IHNpZ25hbDxSb3V0ZXJTdGF0ZT4oY3JlYXRlUm91dGVyU3RhdGUocm91dGVyKSk7XG5cbiAgZWZmZWN0KCgpID0+IHtcbiAgICB1cmwoKTtcblxuICAgIHVudHJhY2tlZCgoKSA9PiByb3V0ZXJTdGF0ZS5zZXQoY3JlYXRlUm91dGVyU3RhdGUocm91dGVyKSkpO1xuICB9KTtcblxuICByZXR1cm4gcm91dGVyU3RhdGUuYXNSZWFkb25seSgpO1xufTtcblxuLyoqIEluamVjdCBhIHNpZ25hbCBjb250YWluaW5nIHRoZSBjdXJyZW50IHJvdXRlIGZyYWdtZW50ICh0aGUgcGFydCBhZnRlciB0aGUgIyBpbnNpZGUgdGhlIHVybCBpZiBwcmVzZW50KSAqL1xuZXhwb3J0IGNvbnN0IGluamVjdEZyYWdtZW50ID0gPFQgPSBzdHJpbmcgfCBudWxsPihcbiAgY29uZmlnPzogSW5qZWN0VXRpbENvbmZpZyAmIEluamVjdFV0aWxUcmFuc2Zvcm1Db25maWc8c3RyaW5nIHwgbnVsbCwgVD4sXG4pID0+IHtcbiAgY29uc3Qgcm91dGVyU3RhdGUgPSBpbmplY3RSb3V0ZXJTdGF0ZSgpO1xuICBjb25zdCBmcmFnbWVudCA9IGNvbXB1dGVkKCgpID0+IHJvdXRlclN0YXRlKCkuZnJhZ21lbnQpO1xuXG4gIHJldHVybiB0cmFuc2Zvcm1PclJldHVybihmcmFnbWVudCwgY29uZmlnKTtcbn07XG5cbi8qKiBJbmplY3QgYWxsIGN1cnJlbnRseSBhdmFpbGFibGUgcXVlcnkgcGFyYW1ldGVycyBhcyBhIHNpZ25hbCAqL1xuZXhwb3J0IGNvbnN0IGluamVjdFF1ZXJ5UGFyYW1zID0gKCkgPT4ge1xuICBjb25zdCByb3V0ZXJTdGF0ZSA9IGluamVjdFJvdXRlclN0YXRlKCk7XG5cbiAgY29uc3QgcXVlcnlQYXJhbXMgPSBjb21wdXRlZCgoKSA9PiByb3V0ZXJTdGF0ZSgpLnF1ZXJ5UGFyYW1zKTtcblxuICByZXR1cm4gcXVlcnlQYXJhbXM7XG59O1xuXG4vKiogSW5qZWN0IGFsbCBjdXJyZW50bHkgYXZhaWxhYmxlIHJvdXRlIGRhdGEgYXMgYSBzaWduYWwgKi9cbmV4cG9ydCBjb25zdCBpbmplY3RSb3V0ZURhdGEgPSAoKSA9PiB7XG4gIGNvbnN0IHJvdXRlclN0YXRlID0gaW5qZWN0Um91dGVyU3RhdGUoKTtcblxuICBjb25zdCBkYXRhID0gY29tcHV0ZWQoKCkgPT4gcm91dGVyU3RhdGUoKS5kYXRhKTtcblxuICByZXR1cm4gZGF0YTtcbn07XG5cbi8qKiBJbmplY3QgdGhlIGN1cnJlbnQgcm91dGUgdGl0bGUgYXMgYSBzaWduYWwgKi9cbmV4cG9ydCBjb25zdCBpbmplY3RSb3V0ZVRpdGxlID0gPFQgPSBzdHJpbmcgfCBudWxsPihjb25maWc/OiBJbmplY3RVdGlsVHJhbnNmb3JtQ29uZmlnPHN0cmluZyB8IG51bGwsIFQ+KSA9PiB7XG4gIGNvbnN0IHJvdXRlclN0YXRlID0gaW5qZWN0Um91dGVyU3RhdGUoKTtcbiAgY29uc3QgdGl0bGUgPSBjb21wdXRlZCgoKSA9PiByb3V0ZXJTdGF0ZSgpLnRpdGxlKTtcblxuICByZXR1cm4gdHJhbnNmb3JtT3JSZXR1cm4odGl0bGUsIGNvbmZpZyk7XG59O1xuXG4vKiogSW5qZWN0IGFsbCBjdXJyZW50bHkgYXZhaWxhYmxlIHBhdGggcGFyYW1ldGVycyBhcyBhIHNpZ25hbCAqL1xuZXhwb3J0IGNvbnN0IGluamVjdFBhdGhQYXJhbXMgPSAoKSA9PiB7XG4gIGNvbnN0IHJvdXRlclN0YXRlID0gaW5qZWN0Um91dGVyU3RhdGUoKTtcblxuICBjb25zdCBwYXRoUGFyYW1zID0gY29tcHV0ZWQoKCkgPT4gcm91dGVyU3RhdGUoKS5wYXRoUGFyYW1zKTtcblxuICByZXR1cm4gcGF0aFBhcmFtcztcbn07XG5cbi8qKiBJbmplY3QgYSBzcGVjaWZpYyBxdWVyeSBwYXJhbWV0ZXIgYXMgYSBzaWduYWwgKi9cbmV4cG9ydCBjb25zdCBpbmplY3RRdWVyeVBhcmFtID0gPFQgPSBzdHJpbmcgfCBudWxsPihcbiAga2V5OiBzdHJpbmcsXG4gIGNvbmZpZz86IEluamVjdFV0aWxUcmFuc2Zvcm1Db25maWc8c3RyaW5nIHwgbnVsbCwgVD4sXG4pID0+IHtcbiAgY29uc3QgcXVlcnlQYXJhbXMgPSBpbmplY3RRdWVyeVBhcmFtcygpO1xuICBjb25zdCBzcmMgPSBjb21wdXRlZCgoKSA9PiBxdWVyeVBhcmFtcygpW2tleV0gPz8gbnVsbCkgYXMgU2lnbmFsPHN0cmluZyB8IG51bGw+O1xuXG4gIHJldHVybiB0cmFuc2Zvcm1PclJldHVybihzcmMsIGNvbmZpZyk7XG59O1xuXG4vKiogSW5qZWN0IGEgc3BlY2lmaWMgcm91dGUgZGF0YSBpdGVtIGFzIGEgc2lnbmFsICovXG5leHBvcnQgY29uc3QgaW5qZWN0Um91dGVEYXRhSXRlbSA9IDxUID0gdW5rbm93bj4oa2V5OiBzdHJpbmcsIGNvbmZpZz86IEluamVjdFV0aWxUcmFuc2Zvcm1Db25maWc8dW5rbm93biwgVD4pID0+IHtcbiAgY29uc3QgZGF0YSA9IGluamVjdFJvdXRlRGF0YSgpO1xuICBjb25zdCBzcmMgPSBjb21wdXRlZCgoKSA9PiBkYXRhKClba2V5XSA/PyBudWxsKSBhcyBTaWduYWw8VD47XG5cbiAgcmV0dXJuIHRyYW5zZm9ybU9yUmV0dXJuKHNyYywgY29uZmlnKTtcbn07XG5cbi8qKiBJbmplY3QgYSBzcGVjaWZpYyBwYXRoIHBhcmFtZXRlciBhcyBhIHNpZ25hbCAqL1xuZXhwb3J0IGNvbnN0IGluamVjdFBhdGhQYXJhbSA9IDxUID0gc3RyaW5nIHwgbnVsbD4oXG4gIGtleTogc3RyaW5nLFxuICBjb25maWc/OiBJbmplY3RVdGlsVHJhbnNmb3JtQ29uZmlnPHN0cmluZyB8IG51bGwsIFQ+LFxuKSA9PiB7XG4gIGNvbnN0IHBhdGhQYXJhbXMgPSBpbmplY3RQYXRoUGFyYW1zKCk7XG4gIGNvbnN0IHNyYyA9IGNvbXB1dGVkKCgpID0+IHBhdGhQYXJhbXMoKVtrZXldID8/IG51bGwpIGFzIFNpZ25hbDxzdHJpbmcgfCBudWxsPjtcblxuICByZXR1cm4gdHJhbnNmb3JtT3JSZXR1cm4oc3JjLCBjb25maWcpO1xufTtcblxuLyoqXG4gKiBJbmplY3QgcXVlcnkgcGFyYW1zIHRoYXQgY2hhbmdlZCBkdXJpbmcgbmF2aWdhdGlvbi4gVW5jaGFuZ2VkIHF1ZXJ5IHBhcmFtcyB3aWxsIGJlIGlnbm9yZWQuXG4gKiBSZW1vdmVkIHF1ZXJ5IHBhcmFtcyB3aWxsIGJlIHJlcHJlc2VudGVkIGJ5IHRoZSBzeW1ib2wgYEVUX1BST1BFUlRZX1JFTU9WRURgLlxuICovXG5leHBvcnQgY29uc3QgaW5qZWN0UXVlcnlQYXJhbUNoYW5nZXMgPSAoKSA9PiB7XG4gIGNvbnN0IHF1ZXJ5UGFyYW1zID0gaW5qZWN0UXVlcnlQYXJhbXMoKTtcbiAgY29uc3QgcHJldlF1ZXJ5UGFyYW1zID0gcHJldmlvdXNTaWduYWxWYWx1ZShxdWVyeVBhcmFtcyk7XG5cbiAgcmV0dXJuIGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBjdXJyZW50ID0gcXVlcnlQYXJhbXMoKTtcbiAgICBjb25zdCBwcmV2aW91cyA9IHByZXZRdWVyeVBhcmFtcygpID8/IHt9O1xuXG4gICAgY29uc3QgY2hhbmdlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIGNvbnN0IGFsbEtleXMgPSBuZXcgU2V0PGtleW9mIHR5cGVvZiBwcmV2aW91cyAmIGtleW9mIHR5cGVvZiBjdXJyZW50PihbXG4gICAgICAuLi5PYmplY3Qua2V5cyhwcmV2aW91cyksXG4gICAgICAuLi5PYmplY3Qua2V5cyhjdXJyZW50KSxcbiAgICBdKTtcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIGFsbEtleXMpIHtcbiAgICAgIGlmICghZXF1YWwocHJldmlvdXNba2V5XSwgY3VycmVudFtrZXldKSkge1xuICAgICAgICBjb25zdCB2YWwgPSBjdXJyZW50W2tleV0gPT09IHVuZGVmaW5lZCA/IEVUX1BST1BFUlRZX1JFTU9WRUQgOiBjdXJyZW50W2tleV07XG5cbiAgICAgICAgY2hhbmdlc1trZXldID0gdmFsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjaGFuZ2VzO1xuICB9KTtcbn07XG5cbi8qKlxuICogSW5qZWN0IHBhdGggcGFyYW1zIHRoYXQgY2hhbmdlZCBkdXJpbmcgbmF2aWdhdGlvbi4gVW5jaGFuZ2VkIHBhdGggcGFyYW1zIHdpbGwgYmUgaWdub3JlZC5cbiAqIFJlbW92ZWQgcGF0aCBwYXJhbXMgd2lsbCBiZSByZXByZXNlbnRlZCBieSB0aGUgc3ltYm9sIGBFVF9QUk9QRVJUWV9SRU1PVkVEYC5cbiAqL1xuZXhwb3J0IGNvbnN0IGluamVjdFBhdGhQYXJhbUNoYW5nZXMgPSAoKSA9PiB7XG4gIGNvbnN0IHBhdGhQYXJhbXMgPSBpbmplY3RQYXRoUGFyYW1zKCk7XG4gIGNvbnN0IHByZXZQYXRoUGFyYW1zID0gcHJldmlvdXNTaWduYWxWYWx1ZShwYXRoUGFyYW1zKTtcblxuICByZXR1cm4gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBwYXRoUGFyYW1zKCk7XG4gICAgY29uc3QgcHJldmlvdXMgPSBwcmV2UGF0aFBhcmFtcygpID8/IHt9O1xuXG4gICAgY29uc3QgY2hhbmdlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIGNvbnN0IGFsbEtleXMgPSBuZXcgU2V0PGtleW9mIHR5cGVvZiBwcmV2aW91cyAmIGtleW9mIHR5cGVvZiBjdXJyZW50PihbXG4gICAgICAuLi5PYmplY3Qua2V5cyhwcmV2aW91cyksXG4gICAgICAuLi5PYmplY3Qua2V5cyhjdXJyZW50KSxcbiAgICBdKTtcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIGFsbEtleXMpIHtcbiAgICAgIGlmICghZXF1YWwocHJldmlvdXNba2V5XSwgY3VycmVudFtrZXldKSkge1xuICAgICAgICBjb25zdCB2YWwgPSBjdXJyZW50W2tleV0gPT09IHVuZGVmaW5lZCA/IEVUX1BST1BFUlRZX1JFTU9WRUQgOiBjdXJyZW50W2tleV07XG5cbiAgICAgICAgY2hhbmdlc1trZXldID0gdmFsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjaGFuZ2VzO1xuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVJc1JlbmRlcmVkU2lnbmFsID0gKCkgPT4ge1xuICBjb25zdCB2YWx1ZSA9IHNpZ25hbChmYWxzZSk7XG5cbiAgbmV4dEZyYW1lKCgpID0+IHtcbiAgICBpZiAoIXZhbHVlKCkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICdSZW5kZXIgc2lnbmFsIHdhcyBub3Qgc2V0IHRvIHRydWUuIFRoaXMgY2FuIGNhdXNlIHVuZXhwZWN0ZWQgYmVoYXZpb3IuIE1ha2Ugc3VyZSB0byAuYmluZCgpIHRoZSByZW5kZXIgc2lnbmFsIGF0IHRoZSBlbmQgb2YgdGhlIGNvbnN0cnVjdG9yLicsXG4gICAgICApO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBzdGF0ZTogdmFsdWUsXG4gICAgYmluZDogKCkgPT4gZWZmZWN0KCgpID0+IHZhbHVlLnNldCh0cnVlKSwgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9KSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVDYW5BbmltYXRlU2lnbmFsID0gKCkgPT4ge1xuICBjb25zdCB2YWx1ZSA9IHNpZ25hbChmYWxzZSk7XG5cbiAgbmV4dEZyYW1lKCgpID0+IHtcbiAgICB2YWx1ZS5zZXQodHJ1ZSk7XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgc3RhdGU6IHZhbHVlLmFzUmVhZG9ubHkoKSxcbiAgfTtcbn07XG5cbmV4cG9ydCB0eXBlIEN1cnNvckRyYWdTY3JvbGxEaXJlY3Rpb24gPSAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnIHwgJ2JvdGgnO1xuXG5leHBvcnQgdHlwZSBNYXliZVNpZ25hbDxUPiA9IFQgfCBTaWduYWw8VD47XG5cbmV4cG9ydCBjb25zdCBtYXliZVNpZ25hbFZhbHVlID0gPFQ+KHZhbHVlOiBNYXliZVNpZ25hbDxUPikgPT4ge1xuICBpZiAoaXNTaWduYWwodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlKCk7XG4gIH1cblxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5leHBvcnQgdHlwZSBDdXJzb3JEcmFnU2Nyb2xsT3B0aW9ucyA9IHtcbiAgLyoqIElmIHRydWUsIGN1cnNvciBkcmFnIHNjcm9sbGluZyB3aWxsIGJlIGVuYWJsZWQuICovXG4gIGVuYWJsZWQ/OiBTaWduYWw8Ym9vbGVhbj47XG5cbiAgLyoqIFRoZSBhbGxvd2VkIHNjcm9sbCBkaXJlY3Rpb24uICovXG4gIGFsbG93ZWREaXJlY3Rpb24/OiBNYXliZVNpZ25hbDxDdXJzb3JEcmFnU2Nyb2xsRGlyZWN0aW9uPjtcbn07XG5cbi8qKiBUaGUgZGVhZHpvbmUgaW4gcGl4ZWxzIGFmdGVyIHdoaWNoIHRoZSBjdXJzb3IgZHJhZyBzY3JvbGwgd2lsbCB0YWtlIGVmZmVjdC4gKi9cbmNvbnN0IENVUlNPUl9EUkFHX1NDUk9MTF9ERUFEWk9ORSA9IDU7XG5cbi8qKiBUaGUgY2xhc3MgdGhhdCBpcyBhZGRlZCB0byB0aGUgZWxlbWVudCB3aGVuIHRoZSBjdXJzb3IgaXMgYmVpbmcgZHJhZ2dlZC4gKi9cbmNvbnN0IENVUlNPUl9EUkFHX1NDUk9MTElOR19DTEFTUyA9ICdldC1jdXJzb3ItZHJhZy1zY3JvbGwtLXNjcm9sbGluZyc7XG5jb25zdCBDVVJTT1JfRFJBR19JTklUX0NMQVNTID0gJ2V0LWN1cnNvci1kcmFnLXNjcm9sbC0taW5pdCc7XG5cbi8qKiBBIGZ1bmN0aW9uIHRvIGFwcGx5IGN1cnNvciBkcmFnIHNjcm9sbCBiZWhhdmlvciB0byBhbiBlbGVtZW50LiAqL1xuZXhwb3J0IGNvbnN0IHVzZUN1cnNvckRyYWdTY3JvbGwgPSAoZWw6IFNpZ25hbEVsZW1lbnRCaW5kaW5nVHlwZSwgb3B0aW9ucz86IEN1cnNvckRyYWdTY3JvbGxPcHRpb25zKSA9PiB7XG4gIGNvbnN0IGVsZW1lbnRzID0gYnVpbGRFbGVtZW50U2lnbmFsKGVsKTtcbiAgY29uc3QgZWxlbWVudCA9IGZpcnN0RWxlbWVudFNpZ25hbChlbGVtZW50cyk7XG4gIGNvbnN0IGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIGNvbnN0IHsgZW5hYmxlZCA9IHNpZ25hbCh0cnVlKSwgYWxsb3dlZERpcmVjdGlvbiA9ICdib3RoJyB9ID0gb3B0aW9ucyA/PyB7fTtcbiAgY29uc3Qgc2Nyb2xsU3RhdGUgPSBzaWduYWxFbGVtZW50U2Nyb2xsU3RhdGUoZWxlbWVudHMpO1xuICBjb25zdCByZW5kZXJlciA9IGluamVjdChSZW5kZXJlcjIpO1xuICBjb25zdCBpc0RyYWdnaW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgY29uc3QgaXNJbml0RHJhZ2dpbmcgPSBzaWduYWwoZmFsc2UpO1xuICBjb25zdCBpbml0aWFsRHJhZ1Bvc2l0aW9uID0gc2lnbmFsKHsgeDogMCwgeTogMCB9KTtcbiAgY29uc3QgaW5pdGlhbFNjcm9sbFBvc2l0aW9uID0gc2lnbmFsKHsgeDogMCwgeTogMCB9KTtcbiAgY29uc3QgZHJhZ0Ftb3VudCA9IHNpZ25hbCh7IHg6IDAsIHk6IDAgfSk7XG4gIGNvbnN0IGRvY3VtZW50ID0gaW5qZWN0KERPQ1VNRU5UKTtcblxuICBjb25zdCBjYW5TY3JvbGwgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgY3VycmVudFNjcm9sbFN0YXRlID0gc2Nyb2xsU3RhdGUoKTtcbiAgICBjb25zdCBkaXJlY3Rpb24gPSBtYXliZVNpZ25hbFZhbHVlKGFsbG93ZWREaXJlY3Rpb24pO1xuXG4gICAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICAgIGNhc2UgJ2JvdGgnOlxuICAgICAgICByZXR1cm4gY3VycmVudFNjcm9sbFN0YXRlLmNhblNjcm9sbEhvcml6b250YWxseSB8fCBjdXJyZW50U2Nyb2xsU3RhdGUuY2FuU2Nyb2xsVmVydGljYWxseTtcbiAgICAgIGNhc2UgJ2hvcml6b250YWwnOlxuICAgICAgICByZXR1cm4gY3VycmVudFNjcm9sbFN0YXRlLmNhblNjcm9sbEhvcml6b250YWxseTtcbiAgICAgIGNhc2UgJ3ZlcnRpY2FsJzpcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRTY3JvbGxTdGF0ZS5jYW5TY3JvbGxWZXJ0aWNhbGx5O1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gQ2xlYW51cCBpZiB0aGUgZWxlbWVudCB0aGUgY3Vyc29yIGRyYWcgc2Nyb2xsIGlzIGJvdW5kIHRvIGdldHMgY2hhbmdlZFxuICBlZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHsgcHJldmlvdXNFbGVtZW50IH0gPSBlbGVtZW50KCk7XG5cbiAgICBpZiAocHJldmlvdXNFbGVtZW50KSB7XG4gICAgICByZW5kZXJlci5yZW1vdmVTdHlsZShwcmV2aW91c0VsZW1lbnQsICdjdXJzb3InKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIENvbmRpdGlvbmFsbHkgYXBwbHkgc3R5bGVzL2NsYXNzZXMgdG8gdGhlIGVsZW1lbnQgYW5kIHRoZSBkb2N1bWVudFxuICBlZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGN1cnJDYW5TY3JvbGwgPSBjYW5TY3JvbGwoKTtcbiAgICBjb25zdCBpc0VuYWJsZWQgPSBlbmFibGVkKCk7XG4gICAgY29uc3QgY3VycklzRHJhZ2dpbmcgPSBpc0RyYWdnaW5nKCk7XG4gICAgY29uc3QgY3VycklzSW5pdERyYWdnaW5nID0gaXNJbml0RHJhZ2dpbmcoKTtcblxuICAgIHVudHJhY2tlZCgoKSA9PiB7XG4gICAgICBjb25zdCBlbCA9IGVsZW1lbnQoKS5jdXJyZW50RWxlbWVudDtcblxuICAgICAgaWYgKCFlbCkgcmV0dXJuO1xuXG4gICAgICBpZiAoIWN1cnJDYW5TY3JvbGwgfHwgIWlzRW5hYmxlZCkge1xuICAgICAgICByZW5kZXJlci5yZW1vdmVTdHlsZShlbCwgJ2N1cnNvcicpO1xuICAgICAgICByZW5kZXJlci5yZW1vdmVTdHlsZShlbCwgJ3Njcm9sbFNuYXBUeXBlJyk7XG4gICAgICAgIHJlbmRlcmVyLnJlbW92ZVN0eWxlKGVsLCAnc2Nyb2xsQmVoYXZpb3InKTtcbiAgICAgICAgcmVuZGVyZXIucmVtb3ZlQ2xhc3MoZWwsIENVUlNPUl9EUkFHX1NDUk9MTElOR19DTEFTUyk7XG4gICAgICAgIHJlbmRlcmVyLnJlbW92ZUNsYXNzKGVsLCBDVVJTT1JfRFJBR19JTklUX0NMQVNTKTtcbiAgICAgICAgcmVuZGVyZXIucmVtb3ZlU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCAnY3Vyc29yJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGN1cnJJc0luaXREcmFnZ2luZykge1xuICAgICAgICByZW5kZXJlci5hZGRDbGFzcyhlbCwgQ1VSU09SX0RSQUdfSU5JVF9DTEFTUyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJySXNEcmFnZ2luZykge1xuICAgICAgICByZW5kZXJlci5hZGRDbGFzcyhlbCwgQ1VSU09SX0RSQUdfU0NST0xMSU5HX0NMQVNTKTtcbiAgICAgICAgcmVuZGVyZXIuc2V0U3R5bGUoZWwsICdzY3JvbGxTbmFwVHlwZScsICdub25lJyk7XG4gICAgICAgIHJlbmRlcmVyLnNldFN0eWxlKGVsLCAnc2Nyb2xsQmVoYXZpb3InLCAndW5zZXQnKTtcbiAgICAgICAgcmVuZGVyZXIuc2V0U3R5bGUoZWwsICdjdXJzb3InLCAnZ3JhYmJpbmcnKTtcbiAgICAgICAgcmVuZGVyZXIuc2V0U3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCAnY3Vyc29yJywgJ2dyYWJiaW5nJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghY3VycklzSW5pdERyYWdnaW5nICYmICFjdXJySXNEcmFnZ2luZykge1xuICAgICAgICByZW5kZXJlci5zZXRTdHlsZShlbCwgJ2N1cnNvcicsICdncmFiJyk7XG4gICAgICAgIHJlbmRlcmVyLnJlbW92ZVN0eWxlKGVsLCAnc2Nyb2xsU25hcFR5cGUnKTtcbiAgICAgICAgcmVuZGVyZXIucmVtb3ZlU3R5bGUoZWwsICdzY3JvbGxCZWhhdmlvcicpO1xuICAgICAgICByZW5kZXJlci5yZW1vdmVDbGFzcyhlbCwgQ1VSU09SX0RSQUdfU0NST0xMSU5HX0NMQVNTKTtcbiAgICAgICAgcmVuZGVyZXIucmVtb3ZlQ2xhc3MoZWwsIENVUlNPUl9EUkFHX0lOSVRfQ0xBU1MpO1xuICAgICAgICByZW5kZXJlci5yZW1vdmVTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdjdXJzb3InKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gVXBkYXRlIHRoZSBlbGVtZW50J3Mgc2Nyb2xsIHBvc2l0aW9uIHdoZW4gdGhlIHVzZXIgZHJhZ3NcbiAgZWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBjdXJyRHJhZ0Ftb3VudCA9IGRyYWdBbW91bnQoKTtcblxuICAgIHVudHJhY2tlZCgoKSA9PiB7XG4gICAgICBjb25zdCBjdXJySXNEcmFnZ2luZyA9IGlzRHJhZ2dpbmcoKTtcbiAgICAgIGNvbnN0IGVsID0gZWxlbWVudCgpLmN1cnJlbnRFbGVtZW50O1xuICAgICAgY29uc3QgeyB4OiBkcmFnWCwgeTogZHJhZ1kgfSA9IGN1cnJEcmFnQW1vdW50O1xuICAgICAgY29uc3QgeyB4OiBzY3JvbGxYLCB5OiBzY3JvbGxZIH0gPSBpbml0aWFsU2Nyb2xsUG9zaXRpb24oKTtcbiAgICAgIGNvbnN0IGN1cnJBbGxvd2VkRGlyZWN0aW9uID0gbWF5YmVTaWduYWxWYWx1ZShhbGxvd2VkRGlyZWN0aW9uKTtcblxuICAgICAgaWYgKCFlbCB8fCAhY3VycklzRHJhZ2dpbmcpIHJldHVybjtcblxuICAgICAgc3dpdGNoIChjdXJyQWxsb3dlZERpcmVjdGlvbikge1xuICAgICAgICBjYXNlICdib3RoJzpcbiAgICAgICAgICBlbC5zY3JvbGwoe1xuICAgICAgICAgICAgdG9wOiBkcmFnWSArIHNjcm9sbFksXG4gICAgICAgICAgICBsZWZ0OiBkcmFnWCArIHNjcm9sbFgsXG4gICAgICAgICAgICBiZWhhdmlvcjogJ2luc3RhbnQnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdob3Jpem9udGFsJzpcbiAgICAgICAgICBlbC5zY3JvbGwoe1xuICAgICAgICAgICAgbGVmdDogZHJhZ1ggKyBzY3JvbGxYLFxuICAgICAgICAgICAgYmVoYXZpb3I6ICdpbnN0YW50JyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndmVydGljYWwnOlxuICAgICAgICAgIGVsLnNjcm9sbCh7XG4gICAgICAgICAgICB0b3A6IGRyYWdZICsgc2Nyb2xsWSxcbiAgICAgICAgICAgIGJlaGF2aW9yOiAnaW5zdGFudCcsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGNvbnN0IHVwZGF0ZURyYWdnaW5nID0gKGU6IE1vdXNlRXZlbnQpID0+IHtcbiAgICBjb25zdCBlbCA9IGVsZW1lbnQoKS5jdXJyZW50RWxlbWVudDtcblxuICAgIGlmICghZWwpIHJldHVybjtcblxuICAgIGNvbnN0IGR4ID0gKGUuY2xpZW50WCAtIGluaXRpYWxEcmFnUG9zaXRpb24oKS54KSAqIC0xO1xuICAgIGNvbnN0IGR5ID0gKGUuY2xpZW50WSAtIGluaXRpYWxEcmFnUG9zaXRpb24oKS55KSAqIC0xO1xuXG4gICAgZHJhZ0Ftb3VudC5zZXQoeyB4OiBkeCwgeTogZHkgfSk7XG5cbiAgICBpZiAoTWF0aC5hYnMoZHgpID4gQ1VSU09SX0RSQUdfU0NST0xMX0RFQURaT05FIHx8IE1hdGguYWJzKGR5KSA+IENVUlNPUl9EUkFHX1NDUk9MTF9ERUFEWk9ORSkge1xuICAgICAgaXNEcmFnZ2luZy5zZXQodHJ1ZSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHVwZGF0ZURyYWdnaW5nRW5kID0gKCkgPT4ge1xuICAgIGlzRHJhZ2dpbmcuc2V0KGZhbHNlKTtcbiAgICBpc0luaXREcmFnZ2luZy5zZXQoZmFsc2UpO1xuICAgIGluaXRpYWxEcmFnUG9zaXRpb24uc2V0KHsgeDogMCwgeTogMCB9KTtcbiAgICBpbml0aWFsU2Nyb2xsUG9zaXRpb24uc2V0KHsgeDogMCwgeTogMCB9KTtcbiAgICBkcmFnQW1vdW50LnNldCh7IHg6IDAsIHk6IDAgfSk7XG4gIH07XG5cbiAgY29uc3Qgc2V0dXBEcmFnZ2luZyA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgY29uc3QgbW91c2VVcCA9IGZyb21FdmVudDxNb3VzZUV2ZW50Pihkb2N1bWVudCwgJ21vdXNldXAnKTtcbiAgICBjb25zdCBtb3VzZU1vdmUgPSBmcm9tRXZlbnQ8TW91c2VFdmVudD4oZG9jdW1lbnQsICdtb3VzZW1vdmUnKTtcbiAgICBjb25zdCBlbCA9IGVsZW1lbnQoKS5jdXJyZW50RWxlbWVudDtcblxuICAgIGlmICghZWwpIHJldHVybjtcblxuICAgIG1vdXNlTW92ZVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZChkZXN0cm95UmVmKSxcbiAgICAgICAgdGFrZVVudGlsKG1vdXNlVXApLFxuICAgICAgICB0YXAoKGUpID0+IHVwZGF0ZURyYWdnaW5nKGUpKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcblxuICAgIG1vdXNlVXBcbiAgICAgIC5waXBlKFxuICAgICAgICB0YWtlKDEpLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQoZGVzdHJveVJlZiksXG4gICAgICAgIHRhcCgoKSA9PiB1cGRhdGVEcmFnZ2luZ0VuZCgpKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcblxuICAgIGluaXRpYWxEcmFnUG9zaXRpb24uc2V0KHsgeDogZS5jbGllbnRYLCB5OiBlLmNsaWVudFkgfSk7XG4gICAgaW5pdGlhbFNjcm9sbFBvc2l0aW9uLnNldCh7IHg6IGVsLnNjcm9sbExlZnQsIHk6IGVsLnNjcm9sbFRvcCB9KTtcbiAgICBpc0luaXREcmFnZ2luZy5zZXQodHJ1ZSk7XG4gIH07XG5cbiAgdG9PYnNlcnZhYmxlKGVsZW1lbnQpXG4gICAgLnBpcGUoXG4gICAgICBtYXAoKGUpID0+IGU/LmN1cnJlbnRFbGVtZW50KSxcbiAgICAgIHN3aXRjaE1hcCgoZWwpID0+IChlbCA/IGZyb21FdmVudDxNb3VzZUV2ZW50PihlbCwgJ21vdXNlZG93bicpIDogb2YobnVsbCkpKSxcbiAgICAgIGZpbHRlcigoZSk6IGUgaXMgTW91c2VFdmVudCA9PiAhIWUpLFxuICAgICAgZmlsdGVyKCgpID0+IGVuYWJsZWQoKSksXG4gICAgICB0YXAoKGUpID0+IHNldHVwRHJhZ2dpbmcoZSkpLFxuICAgICAgdGFrZVVudGlsRGVzdHJveWVkKCksXG4gICAgKVxuICAgIC5zdWJzY3JpYmUoKTtcblxuICByZXR1cm4ge1xuICAgIGlzRHJhZ2dpbmc6IGlzRHJhZ2dpbmcuYXNSZWFkb25seSgpLFxuICAgIGN1cnJlbnREcmFnQW1vdW50OiBkcmFnQW1vdW50LmFzUmVhZG9ubHkoKSxcbiAgfTtcbn07XG5cbi8qKlxuICogQSBjb21wdXRlZCB0aGF0IHdpbGwgb25seSBiZSByZWFjdGl2ZSB1bnRpbCB0aGUgc291cmNlIHNpZ25hbCBjb250YWlucyBhIHRydXRoeSB2YWx1ZS5cbiAqIEFsbCBzdWJzZXF1ZW50IGNoYW5nZXMgaW5zaWRlIHRoZSBjb21wdXRhdGlvbiB3aWxsIGJlIGlnbm9yZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBjb21wdXRlZFRpbGxUcnV0aHkgPSA8VD4oc291cmNlOiBTaWduYWw8VD4pID0+IHtcbiAgY29uc3QgdmFsdWUgPSBzaWduYWw8VCB8IG51bGw+KG51bGwpO1xuXG4gIGNvbnN0IHJlZiA9IGVmZmVjdChcbiAgICAoKSA9PiB7XG4gICAgICBjb25zdCB2YWwgPSBzb3VyY2UoKTtcblxuICAgICAgaWYgKHZhbCkge1xuICAgICAgICB2YWx1ZS5zZXQodmFsKTtcbiAgICAgICAgcmVmLmRlc3Ryb3koKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfSxcbiAgKTtcblxuICByZXR1cm4gdmFsdWUuYXNSZWFkb25seSgpO1xufTtcblxuLyoqXG4gKiBBIGNvbXB1dGVkIHRoYXQgd2lsbCBvbmx5IGJlIHJlYWN0aXZlIHVudGlsIHRoZSBzb3VyY2Ugc2lnbmFsIGNvbnRhaW5zIGEgZmFsc3kgdmFsdWUuXG4gKiBBbGwgc3Vic2VxdWVudCBjaGFuZ2VzIGluc2lkZSB0aGUgY29tcHV0YXRpb24gd2lsbCBiZSBpZ25vcmVkLlxuICovXG5leHBvcnQgY29uc3QgY29tcHV0ZWRUaWxsRmFsc3kgPSA8VD4oc291cmNlOiBTaWduYWw8VD4pID0+IHtcbiAgY29uc3QgdmFsdWUgPSBzaWduYWw8VCB8IG51bGw+KG51bGwpO1xuXG4gIGNvbnN0IHJlZiA9IGVmZmVjdChcbiAgICAoKSA9PiB7XG4gICAgICBjb25zdCB2YWwgPSBzb3VyY2UoKTtcblxuICAgICAgaWYgKCF2YWwpIHtcbiAgICAgICAgdmFsdWUuc2V0KHZhbCk7XG4gICAgICAgIHJlZi5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgfSxcbiAgICB7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH0sXG4gICk7XG5cbiAgcmV0dXJuIHZhbHVlLmFzUmVhZG9ubHkoKTtcbn07XG5cbi8qKlxuICogQSB3cml0ZWFibGUgc2lnbmFsIHRoYXQgd2lsbCBiZSBzZXQgdG8gdGhlIHByb3ZpZGVkIHZhbHVlIG9uY2UgYWxsIGlucHV0cyBhcmUgc2V0LlxuICogRHVyaW5nIHRoYXQgdGltZSwgdGhlIHNpZ25hbCB3aWxsIGJlIHNldCB0byBgbnVsbGAuXG4gKi9cbmV4cG9ydCBjb25zdCBkZWZlcnJlZFNpZ25hbCA9IDxUIGV4dGVuZHMgKCkgPT4gdW5rbm93bj4odmFsdWVGbjogVCkgPT4ge1xuICBjb25zdCB2YWx1ZVNpZ25hbCA9IHNpZ25hbDxSZXR1cm5UeXBlPFQ+IHwgbnVsbD4obnVsbCk7XG5cbiAgYWZ0ZXJOZXh0UmVuZGVyKCgpID0+IHtcbiAgICB2YWx1ZVNpZ25hbC5zZXQodmFsdWVGbigpIGFzIFJldHVyblR5cGU8VD4pO1xuICB9KTtcblxuICByZXR1cm4gdmFsdWVTaWduYWw7XG59O1xuXG4vKiogSW5qZWN0IGEgc2lnbmFsIGNvbnRhaW5pbmcgYSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgaWYgdGhlIHZpZXdwb3J0IGlzIHhzICovXG5leHBvcnQgY29uc3QgaW5qZWN0SXNYcyA9ICgpID0+IHtcbiAgcmV0dXJuIHRvU2lnbmFsKGluamVjdChWaWV3cG9ydFNlcnZpY2UpLmlzWHMkLCB7IHJlcXVpcmVTeW5jOiB0cnVlIH0pO1xufTtcblxuLyoqIEluamVjdCBhIHNpZ25hbCBjb250YWluaW5nIGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIGlmIHRoZSB2aWV3cG9ydCBpcyBzbSAqL1xuZXhwb3J0IGNvbnN0IGluamVjdElzU20gPSAoKSA9PiB7XG4gIHJldHVybiB0b1NpZ25hbChpbmplY3QoVmlld3BvcnRTZXJ2aWNlKS5pc1NtJCwgeyByZXF1aXJlU3luYzogdHJ1ZSB9KTtcbn07XG5cbi8qKiBJbmplY3QgYSBzaWduYWwgY29udGFpbmluZyBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyBpZiB0aGUgdmlld3BvcnQgaXMgbWQgKi9cbmV4cG9ydCBjb25zdCBpbmplY3RJc01kID0gKCkgPT4ge1xuICByZXR1cm4gdG9TaWduYWwoaW5qZWN0KFZpZXdwb3J0U2VydmljZSkuaXNNZCQsIHsgcmVxdWlyZVN5bmM6IHRydWUgfSk7XG59O1xuXG4vKiogSW5qZWN0IGEgc2lnbmFsIGNvbnRhaW5pbmcgYSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgaWYgdGhlIHZpZXdwb3J0IGlzIGxnICovXG5leHBvcnQgY29uc3QgaW5qZWN0SXNMZyA9ICgpID0+IHtcbiAgcmV0dXJuIHRvU2lnbmFsKGluamVjdChWaWV3cG9ydFNlcnZpY2UpLmlzTGckLCB7IHJlcXVpcmVTeW5jOiB0cnVlIH0pO1xufTtcblxuLyoqIEluamVjdCBhIHNpZ25hbCBjb250YWluaW5nIGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIGlmIHRoZSB2aWV3cG9ydCBpcyB4bCAqL1xuZXhwb3J0IGNvbnN0IGluamVjdElzWGwgPSAoKSA9PiB7XG4gIHJldHVybiB0b1NpZ25hbChpbmplY3QoVmlld3BvcnRTZXJ2aWNlKS5pc1hsJCwgeyByZXF1aXJlU3luYzogdHJ1ZSB9KTtcbn07XG5cbi8qKiBJbmplY3QgYSBzaWduYWwgY29udGFpbmluZyBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyBpZiB0aGUgdmlld3BvcnQgaXMgMnhsICovXG5leHBvcnQgY29uc3QgaW5qZWN0SXMyWGwgPSAoKSA9PiB7XG4gIHJldHVybiB0b1NpZ25hbChpbmplY3QoVmlld3BvcnRTZXJ2aWNlKS5pczJYbCQsIHsgcmVxdWlyZVN5bmM6IHRydWUgfSk7XG59O1xuXG4vKipcbiAqIEluamVjdCBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyBpZiB0aGUgdmlld3BvcnQgaXMgbWF0Y2hpbmcgdGhlIHByb3ZpZGVkIG9wdGlvbnMuXG4gKiBUaGlzIHZhbHVlIGlzIG5vdCByZWFjdGl2ZS4gSWYgeW91IHdhbnQgdG8gcmVhY3QgdG8gY2hhbmdlcywgdXNlIHRoZSB7QGxpbmsgaW5qZWN0T2JzZXJ2ZUJyZWFrcG9pbnR9IGZ1bmN0aW9uIGluc3RlYWQuXG4gKi9cbmV4cG9ydCBjb25zdCBpbmplY3RCcmVha3BvaW50SXNNYXRjaGVkID0gKG9wdGlvbnM6IHsgbWluPzogbnVtYmVyIHwgQnJlYWtwb2ludDsgbWF4PzogbnVtYmVyIHwgQnJlYWtwb2ludCB9KSA9PiB7XG4gIHJldHVybiBpbmplY3QoVmlld3BvcnRTZXJ2aWNlKS5pc01hdGNoZWQob3B0aW9ucyk7XG59O1xuXG4vKipcbiAqIEluamVjdCBhIHNpZ25hbCBjb250YWluaW5nIGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIGlmIHRoZSB2aWV3cG9ydCBpcyBtYXRjaGluZyB0aGUgcHJvdmlkZWQgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGNvbnN0IGluamVjdE9ic2VydmVCcmVha3BvaW50ID0gKG9wdGlvbnM6IHsgbWluPzogbnVtYmVyIHwgQnJlYWtwb2ludDsgbWF4PzogbnVtYmVyIHwgQnJlYWtwb2ludCB9KSA9PiB7XG4gIHJldHVybiB0b1NpZ25hbChpbmplY3QoVmlld3BvcnRTZXJ2aWNlKS5vYnNlcnZlKG9wdGlvbnMpLCB7IGluaXRpYWxWYWx1ZTogaW5qZWN0QnJlYWtwb2ludElzTWF0Y2hlZChvcHRpb25zKSB9KTtcbn07XG5cbi8qKiBJbmplY3QgYSBzaWduYWwgY29udGFpbmluZyB0aGUgY3VycmVudCBicmVha3BvaW50LiAqL1xuZXhwb3J0IGNvbnN0IGluamVjdEN1cnJlbnRCcmVha3BvaW50ID0gKCkgPT4ge1xuICByZXR1cm4gdG9TaWduYWwoaW5qZWN0KFZpZXdwb3J0U2VydmljZSkuY3VycmVudFZpZXdwb3J0JCwge1xuICAgIGluaXRpYWxWYWx1ZTogaW5qZWN0KFZpZXdwb3J0U2VydmljZSkuY3VycmVudFZpZXdwb3J0LFxuICB9KTtcbn07XG4iXX0=