mtrl-addons 0.5.6 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,476 @@
1
+ // src/core/gestures/types.ts
2
+ var GESTURE_TYPES;
3
+ ((GESTURE_TYPES2) => {
4
+ GESTURE_TYPES2["TAP"] = "tap";
5
+ GESTURE_TYPES2["SWIPE"] = "swipe";
6
+ GESTURE_TYPES2["SWIPE_LEFT"] = "swipeleft";
7
+ GESTURE_TYPES2["SWIPE_RIGHT"] = "swiperight";
8
+ GESTURE_TYPES2["SWIPE_UP"] = "swipeup";
9
+ GESTURE_TYPES2["SWIPE_DOWN"] = "swipedown";
10
+ GESTURE_TYPES2["PINCH"] = "pinch";
11
+ GESTURE_TYPES2["ROTATE"] = "rotate";
12
+ GESTURE_TYPES2["LONG_PRESS"] = "longpress";
13
+ GESTURE_TYPES2["PAN"] = "pan";
14
+ })(GESTURE_TYPES ||= {});
15
+ var SWIPE_DIRECTIONS;
16
+ ((SWIPE_DIRECTIONS2) => {
17
+ SWIPE_DIRECTIONS2["UP"] = "up";
18
+ SWIPE_DIRECTIONS2["DOWN"] = "down";
19
+ SWIPE_DIRECTIONS2["LEFT"] = "left";
20
+ SWIPE_DIRECTIONS2["RIGHT"] = "right";
21
+ })(SWIPE_DIRECTIONS ||= {});
22
+
23
+ // src/core/gestures/utils.ts
24
+ function getDistance(x1, y1, x2, y2) {
25
+ return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
26
+ }
27
+ function getAngle(x1, y1, x2, y2) {
28
+ const angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
29
+ return angle < 0 ? angle + 360 : angle;
30
+ }
31
+ function createGestureEvent(type, originalEvent, state) {
32
+ const endTime = Date.now();
33
+ let defaultPrevented = false;
34
+ const event = {
35
+ type,
36
+ originalEvent,
37
+ target: state.target || originalEvent.target,
38
+ startTime: state.startTime,
39
+ endTime,
40
+ duration: endTime - state.startTime,
41
+ defaultPrevented,
42
+ preventDefault: () => {
43
+ defaultPrevented = true;
44
+ event.defaultPrevented = true;
45
+ if (originalEvent.cancelable) {
46
+ originalEvent.preventDefault();
47
+ }
48
+ },
49
+ stopPropagation: () => {
50
+ originalEvent.stopPropagation();
51
+ }
52
+ };
53
+ return event;
54
+ }
55
+ function hasTouchSupport() {
56
+ const maxPoints = navigator.maxTouchPoints;
57
+ return "ontouchstart" in window || typeof maxPoints === "number" && maxPoints > 0;
58
+ }
59
+ function hasPointerSupport() {
60
+ return !!window.PointerEvent;
61
+ }
62
+ function getTouchCoordinates(e) {
63
+ if ("touches" in e && Array.isArray(e.touches) && e.touches.length > 0) {
64
+ return {
65
+ clientX: e.touches[0].clientX,
66
+ clientY: e.touches[0].clientY
67
+ };
68
+ }
69
+ return {
70
+ clientX: e.clientX,
71
+ clientY: e.clientY
72
+ };
73
+ }
74
+
75
+ // src/core/gestures/tap.ts
76
+ function detectTap(context) {
77
+ const { state, options, originalEvent } = context;
78
+ const deltaX = state.currentX - state.startX;
79
+ const deltaY = state.currentY - state.startY;
80
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
81
+ if (distance < options.tapDistanceThreshold) {
82
+ const now = Date.now();
83
+ const isDoubleTap = now - state.lastTapTime < 300;
84
+ const tapCount = isDoubleTap ? state.tapCount + 1 : 1;
85
+ const tapEvent = {
86
+ ...createGestureEvent("tap", originalEvent, state),
87
+ type: "tap",
88
+ count: tapCount,
89
+ x: state.currentX,
90
+ y: state.currentY
91
+ };
92
+ return tapEvent;
93
+ }
94
+ return null;
95
+ }
96
+
97
+ // src/core/gestures/swipe.ts
98
+ function getSwipeDirection(deltaX, deltaY) {
99
+ if (Math.abs(deltaX) > Math.abs(deltaY)) {
100
+ return deltaX > 0 ? "right" /* RIGHT */ : "left" /* LEFT */;
101
+ }
102
+ return deltaY > 0 ? "down" /* DOWN */ : "up" /* UP */;
103
+ }
104
+ function detectSwipe(context) {
105
+ const { state, options, originalEvent } = context;
106
+ const deltaX = state.currentX - state.startX;
107
+ const deltaY = state.currentY - state.startY;
108
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
109
+ const endTime = Date.now();
110
+ const deltaTime = endTime - state.startTime;
111
+ const velocity = distance / deltaTime;
112
+ if (distance >= options.swipeThreshold && deltaTime <= options.swipeTimeThreshold) {
113
+ const direction = getSwipeDirection(deltaX, deltaY);
114
+ const swipeEvent = {
115
+ ...createGestureEvent("swipe", originalEvent, state),
116
+ type: "swipe",
117
+ direction,
118
+ deltaX,
119
+ deltaY,
120
+ distance,
121
+ velocity,
122
+ startX: state.startX,
123
+ startY: state.startY,
124
+ endX: state.currentX,
125
+ endY: state.currentY
126
+ };
127
+ return swipeEvent;
128
+ }
129
+ return null;
130
+ }
131
+
132
+ // src/core/gestures/longpress.ts
133
+ function detectLongPress(context, callback) {
134
+ const { state, options, originalEvent } = context;
135
+ const timer = window.setTimeout(() => {
136
+ if (state.active) {
137
+ const diffX = Math.abs(state.currentX - state.startX);
138
+ const diffY = Math.abs(state.currentY - state.startY);
139
+ if (diffX < options.tapDistanceThreshold && diffY < options.tapDistanceThreshold) {
140
+ const longPressEvent = {
141
+ ...createGestureEvent("longpress", originalEvent, state),
142
+ type: "longpress",
143
+ x: state.currentX,
144
+ y: state.currentY
145
+ };
146
+ callback(longPressEvent);
147
+ }
148
+ }
149
+ }, options.longPressTime);
150
+ return () => {
151
+ clearTimeout(timer);
152
+ };
153
+ }
154
+ function shouldCancelLongPress(context) {
155
+ const { state, options } = context;
156
+ const diffX = Math.abs(state.currentX - state.startX);
157
+ const diffY = Math.abs(state.currentY - state.startY);
158
+ return diffX > options.tapDistanceThreshold || diffY > options.tapDistanceThreshold;
159
+ }
160
+
161
+ // src/core/gestures/pan.ts
162
+ function detectPan(context) {
163
+ const { state, originalEvent } = context;
164
+ const deltaX = state.currentX - state.startX;
165
+ const deltaY = state.currentY - state.startY;
166
+ const moveDeltaX = state.currentX - state.lastX;
167
+ const moveDeltaY = state.currentY - state.lastY;
168
+ const moveDelta = Math.sqrt(moveDeltaX * moveDeltaX + moveDeltaY * moveDeltaY);
169
+ if (moveDelta > 0) {
170
+ const panEvent = {
171
+ ...createGestureEvent("pan", originalEvent, state),
172
+ type: "pan",
173
+ deltaX,
174
+ deltaY,
175
+ startX: state.startX,
176
+ startY: state.startY,
177
+ currentX: state.currentX,
178
+ currentY: state.currentY
179
+ };
180
+ return panEvent;
181
+ }
182
+ return null;
183
+ }
184
+
185
+ // src/core/gestures/pinch.ts
186
+ function detectPinch(context, touch1, touch2) {
187
+ const { state, originalEvent } = context;
188
+ const currentDistance = getDistance(touch1.clientX, touch1.clientY, touch2.clientX, touch2.clientY);
189
+ const PINCH_THRESHOLD = 10;
190
+ if (Math.abs(currentDistance - state.startDistance) > PINCH_THRESHOLD) {
191
+ const scale = currentDistance / state.startDistance;
192
+ const centerX = (touch1.clientX + touch2.clientX) / 2;
193
+ const centerY = (touch1.clientY + touch2.clientY) / 2;
194
+ const pinchEvent = {
195
+ ...createGestureEvent("pinch", originalEvent, state),
196
+ type: "pinch",
197
+ scale,
198
+ centerX,
199
+ centerY
200
+ };
201
+ return pinchEvent;
202
+ }
203
+ return null;
204
+ }
205
+
206
+ // src/core/gestures/rotate.ts
207
+ function detectRotate(context, touch1, touch2) {
208
+ const { state, originalEvent } = context;
209
+ const currentAngle = getAngle(touch1.clientX, touch1.clientY, touch2.clientX, touch2.clientY);
210
+ const ROTATION_THRESHOLD = 10;
211
+ const rotationDiff = currentAngle - state.startAngle;
212
+ if (Math.abs(rotationDiff) > ROTATION_THRESHOLD) {
213
+ const centerX = (touch1.clientX + touch2.clientX) / 2;
214
+ const centerY = (touch1.clientY + touch2.clientY) / 2;
215
+ const rotateEvent = {
216
+ ...createGestureEvent("rotate", originalEvent, state),
217
+ type: "rotate",
218
+ rotation: rotationDiff,
219
+ centerX,
220
+ centerY
221
+ };
222
+ return rotateEvent;
223
+ }
224
+ return null;
225
+ }
226
+
227
+ // src/core/gestures/manager.ts
228
+ var createGestureManager = (element, config = {}) => {
229
+ const options = {
230
+ swipeThreshold: 30,
231
+ swipeTimeThreshold: 300,
232
+ longPressTime: 500,
233
+ tapDistanceThreshold: 10,
234
+ preventDefault: true,
235
+ stopPropagation: false,
236
+ ...config
237
+ };
238
+ const handlers = new Map;
239
+ const state = {
240
+ active: false,
241
+ startTime: 0,
242
+ startX: 0,
243
+ startY: 0,
244
+ lastX: 0,
245
+ lastY: 0,
246
+ currentX: 0,
247
+ currentY: 0,
248
+ touchCount: 0,
249
+ longPressTimer: null,
250
+ startDistance: 0,
251
+ startAngle: 0,
252
+ lastTapTime: 0,
253
+ tapCount: 0,
254
+ target: null
255
+ };
256
+ const supportTouch = hasTouchSupport();
257
+ const supportPointer = hasPointerSupport();
258
+ const gestureSupport = {
259
+ tap: true,
260
+ swipe: true,
261
+ swipeleft: true,
262
+ swiperight: true,
263
+ swipeup: true,
264
+ swipedown: true,
265
+ longpress: true,
266
+ pan: true,
267
+ pinch: supportTouch || supportPointer,
268
+ rotate: supportTouch || supportPointer
269
+ };
270
+ const dispatchGesture = (event) => {
271
+ const eventHandlers = handlers.get(event.type);
272
+ if (!eventHandlers)
273
+ return;
274
+ eventHandlers.forEach((handler) => {
275
+ try {
276
+ handler(event);
277
+ } catch (error) {
278
+ console.error(`Error in gesture handler for ${event.type}:`, error);
279
+ }
280
+ });
281
+ if (event.type === "swipe" && "direction" in event) {
282
+ const directionEvent = { ...event, type: `swipe${event.direction}` };
283
+ dispatchGesture(directionEvent);
284
+ }
285
+ if (options.preventDefault && !event.defaultPrevented) {
286
+ event.preventDefault();
287
+ }
288
+ if (options.stopPropagation) {
289
+ event.stopPropagation();
290
+ }
291
+ };
292
+ let longPressCleanup = null;
293
+ const handleStart = (e) => {
294
+ const touch = getTouchCoordinates(e);
295
+ const touchCount = "touches" in e ? e.touches.length : 1;
296
+ state.active = true;
297
+ state.startTime = Date.now();
298
+ state.startX = state.lastX = state.currentX = touch.clientX;
299
+ state.startY = state.lastY = state.currentY = touch.clientY;
300
+ state.touchCount = touchCount;
301
+ state.target = e.target;
302
+ if (touchCount === 2 && "touches" in e) {
303
+ const touch1 = e.touches[0];
304
+ const touch2 = e.touches[1];
305
+ state.startDistance = Math.sqrt(Math.pow(touch2.clientX - touch1.clientX, 2) + Math.pow(touch2.clientY - touch1.clientY, 2));
306
+ state.startAngle = Math.atan2(touch2.clientY - touch1.clientY, touch2.clientX - touch1.clientX) * 180 / Math.PI;
307
+ if (state.startAngle < 0)
308
+ state.startAngle += 360;
309
+ }
310
+ const context = {
311
+ state,
312
+ options,
313
+ originalEvent: e
314
+ };
315
+ if (longPressCleanup) {
316
+ longPressCleanup();
317
+ }
318
+ longPressCleanup = detectLongPress(context, (longPressEvent) => {
319
+ dispatchGesture(longPressEvent);
320
+ });
321
+ };
322
+ const handleMove = (e) => {
323
+ if (!state.active)
324
+ return;
325
+ const touch = getTouchCoordinates(e);
326
+ const touchCount = "touches" in e ? e.touches.length : 1;
327
+ state.lastX = state.currentX;
328
+ state.lastY = state.currentY;
329
+ state.currentX = touch.clientX;
330
+ state.currentY = touch.clientY;
331
+ const context = {
332
+ state,
333
+ options,
334
+ originalEvent: e
335
+ };
336
+ if (shouldCancelLongPress(context) && longPressCleanup) {
337
+ longPressCleanup();
338
+ longPressCleanup = null;
339
+ }
340
+ const panEvent = detectPan(context);
341
+ if (panEvent) {
342
+ dispatchGesture(panEvent);
343
+ }
344
+ if (touchCount === 2 && "touches" in e) {
345
+ const touch1 = e.touches[0];
346
+ const touch2 = e.touches[1];
347
+ const pinchEvent = detectPinch(context, touch1, touch2);
348
+ if (pinchEvent) {
349
+ dispatchGesture(pinchEvent);
350
+ }
351
+ const rotateEvent = detectRotate(context, touch1, touch2);
352
+ if (rotateEvent) {
353
+ dispatchGesture(rotateEvent);
354
+ }
355
+ }
356
+ };
357
+ const handleEnd = (e) => {
358
+ if (!state.active)
359
+ return;
360
+ if (longPressCleanup) {
361
+ longPressCleanup();
362
+ longPressCleanup = null;
363
+ }
364
+ const context = {
365
+ state,
366
+ options,
367
+ originalEvent: e
368
+ };
369
+ const tapEvent = detectTap(context);
370
+ if (tapEvent) {
371
+ state.lastTapTime = Date.now();
372
+ state.tapCount = tapEvent.count;
373
+ dispatchGesture(tapEvent);
374
+ } else {
375
+ const swipeEvent = detectSwipe(context);
376
+ if (swipeEvent) {
377
+ dispatchGesture(swipeEvent);
378
+ }
379
+ }
380
+ state.active = false;
381
+ };
382
+ const handleCancel = () => {
383
+ if (longPressCleanup) {
384
+ longPressCleanup();
385
+ longPressCleanup = null;
386
+ }
387
+ state.active = false;
388
+ };
389
+ let eventListeners = {};
390
+ const setupEventListeners = () => {
391
+ if (supportPointer) {
392
+ eventListeners = {
393
+ pointerdown: handleStart,
394
+ pointermove: handleMove,
395
+ pointerup: handleEnd,
396
+ pointercancel: handleCancel
397
+ };
398
+ } else if (supportTouch) {
399
+ eventListeners = {
400
+ touchstart: handleStart,
401
+ touchmove: handleMove,
402
+ touchend: handleEnd,
403
+ touchcancel: handleCancel
404
+ };
405
+ } else {
406
+ eventListeners = {
407
+ mousedown: handleStart,
408
+ mousemove: handleMove,
409
+ mouseup: handleEnd,
410
+ mouseleave: handleCancel
411
+ };
412
+ }
413
+ Object.entries(eventListeners).forEach(([event, listener]) => {
414
+ element.addEventListener(event, listener, { passive: !options.preventDefault });
415
+ });
416
+ };
417
+ const removeEventListeners = () => {
418
+ Object.entries(eventListeners).forEach(([event, listener]) => {
419
+ element.removeEventListener(event, listener);
420
+ });
421
+ eventListeners = {};
422
+ };
423
+ setupEventListeners();
424
+ return {
425
+ on(eventType, handler) {
426
+ if (!handlers.has(eventType)) {
427
+ handlers.set(eventType, new Set);
428
+ }
429
+ handlers.get(eventType).add(handler);
430
+ return this;
431
+ },
432
+ off(eventType, handler) {
433
+ const eventHandlers = handlers.get(eventType);
434
+ if (eventHandlers) {
435
+ eventHandlers.delete(handler);
436
+ if (eventHandlers.size === 0) {
437
+ handlers.delete(eventType);
438
+ }
439
+ }
440
+ return this;
441
+ },
442
+ isSupported(gestureType) {
443
+ return gestureType in gestureSupport && gestureSupport[gestureType];
444
+ },
445
+ enable() {
446
+ setupEventListeners();
447
+ return this;
448
+ },
449
+ disable() {
450
+ removeEventListeners();
451
+ return this;
452
+ },
453
+ destroy() {
454
+ removeEventListeners();
455
+ if (longPressCleanup) {
456
+ longPressCleanup();
457
+ longPressCleanup = null;
458
+ }
459
+ handlers.clear();
460
+ }
461
+ };
462
+ };
463
+ export {
464
+ detectTap,
465
+ detectSwipe,
466
+ detectRotate,
467
+ detectPinch,
468
+ detectPan,
469
+ detectLongPress,
470
+ createGestureManager,
471
+ SWIPE_DIRECTIONS,
472
+ GESTURE_TYPES
473
+ };
474
+
475
+ //# debugId=2B40BBC2400CF95364756E2164756E21
476
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvcmUvZ2VzdHVyZXMvdHlwZXMudHMiLCAiLi4vLi4vLi4vc3JjL2NvcmUvZ2VzdHVyZXMvdXRpbHMudHMiLCAiLi4vLi4vLi4vc3JjL2NvcmUvZ2VzdHVyZXMvdGFwLnRzIiwgIi4uLy4uLy4uL3NyYy9jb3JlL2dlc3R1cmVzL3N3aXBlLnRzIiwgIi4uLy4uLy4uL3NyYy9jb3JlL2dlc3R1cmVzL2xvbmdwcmVzcy50cyIsICIuLi8uLi8uLi9zcmMvY29yZS9nZXN0dXJlcy9wYW4udHMiLCAiLi4vLi4vLi4vc3JjL2NvcmUvZ2VzdHVyZXMvcGluY2gudHMiLCAiLi4vLi4vLi4vc3JjL2NvcmUvZ2VzdHVyZXMvcm90YXRlLnRzIiwgIi4uLy4uLy4uL3NyYy9jb3JlL2dlc3R1cmVzL21hbmFnZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiLy8gc3JjL2NvcmUvZ2VzdHVyZXMvdHlwZXMudHNcbi8qKlxuICogQG1vZHVsZSBjb3JlL2dlc3R1cmVzXG4gKiBAZGVzY3JpcHRpb24gVHlwZSBkZWZpbml0aW9ucyBmb3IgdGhlIGdlc3R1cmUgc3lzdGVtXG4gKi9cblxuLyoqXG4gKiBUeXBlcyBvZiBnZXN0dXJlcyBzdXBwb3J0ZWQgYnkgdGhlIHN5c3RlbVxuICovXG5leHBvcnQgZW51bSBHRVNUVVJFX1RZUEVTIHtcbiAgVEFQID0gJ3RhcCcsXG4gIFNXSVBFID0gJ3N3aXBlJyxcbiAgU1dJUEVfTEVGVCA9ICdzd2lwZWxlZnQnLFxuICBTV0lQRV9SSUdIVCA9ICdzd2lwZXJpZ2h0JyxcbiAgU1dJUEVfVVAgPSAnc3dpcGV1cCcsXG4gIFNXSVBFX0RPV04gPSAnc3dpcGVkb3duJyxcbiAgUElOQ0ggPSAncGluY2gnLFxuICBST1RBVEUgPSAncm90YXRlJyxcbiAgTE9OR19QUkVTUyA9ICdsb25ncHJlc3MnLFxuICBQQU4gPSAncGFuJ1xufVxuXG4vKipcbiAqIERpcmVjdGlvbiBvZiBzd2lwZSBnZXN0dXJlc1xuICovXG5leHBvcnQgZW51bSBTV0lQRV9ESVJFQ1RJT05TIHtcbiAgVVAgPSAndXAnLFxuICBET1dOID0gJ2Rvd24nLFxuICBMRUZUID0gJ2xlZnQnLFxuICBSSUdIVCA9ICdyaWdodCdcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIGdlc3R1cmUgcmVjb2duaXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHZXN0dXJlQ29uZmlnIHtcbiAgLyoqXG4gICAqIE1pbmltdW0gZGlzdGFuY2UgKGluIHBpeGVscykgdG8gcmVjb2duaXplIGEgc3dpcGVcbiAgICogQGRlZmF1bHQgMzBcbiAgICovXG4gIHN3aXBlVGhyZXNob2xkPzogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIE1heGltdW0gdGltZSAoaW4gbXMpIGluIHdoaWNoIGEgc3dpcGUgbXVzdCBiZSBjb21wbGV0ZWRcbiAgICogQGRlZmF1bHQgMzAwXG4gICAqL1xuICBzd2lwZVRpbWVUaHJlc2hvbGQ/OiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogVGltZSAoaW4gbXMpIHRvIHJlY29nbml6ZSBhIGxvbmcgcHJlc3NcbiAgICogQGRlZmF1bHQgNTAwXG4gICAqL1xuICBsb25nUHJlc3NUaW1lPzogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIERpc3RhbmNlIHRocmVzaG9sZCAoaW4gcGl4ZWxzKSBmb3IgdGFwIHJlY29nbml0aW9uXG4gICAqIEBkZWZhdWx0IDEwXG4gICAqL1xuICB0YXBEaXN0YW5jZVRocmVzaG9sZD86IG51bWJlcjtcbiAgXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHByZXZlbnQgZGVmYXVsdCBiZWhhdmlvcnMgb24gdG91Y2ggZXZlbnRzXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHByZXZlbnREZWZhdWx0PzogYm9vbGVhbjtcbiAgXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHN0b3AgZXZlbnQgcHJvcGFnYXRpb25cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHN0b3BQcm9wYWdhdGlvbj86IGJvb2xlYW47XG4gIFxuICBba2V5OiBzdHJpbmddOiBhbnk7XG59XG5cbi8qKlxuICogQmFzZSBnZXN0dXJlIGV2ZW50IGRhdGFcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHZXN0dXJlRXZlbnQge1xuICAvKipcbiAgICogVHlwZSBvZiB0aGUgZ2VzdHVyZVxuICAgKi9cbiAgdHlwZTogc3RyaW5nO1xuICBcbiAgLyoqXG4gICAqIE9yaWdpbmFsIERPTSBldmVudFxuICAgKi9cbiAgb3JpZ2luYWxFdmVudDogRXZlbnQ7XG4gIFxuICAvKipcbiAgICogRWxlbWVudCB0aGUgZ2VzdHVyZSB3YXMgdHJpZ2dlcmVkIG9uXG4gICAqL1xuICB0YXJnZXQ6IEV2ZW50VGFyZ2V0O1xuICBcbiAgLyoqXG4gICAqIFRpbWVzdGFtcCB3aGVuIHRoZSBnZXN0dXJlIHN0YXJ0ZWRcbiAgICovXG4gIHN0YXJ0VGltZTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFRpbWVzdGFtcCB3aGVuIHRoZSBnZXN0dXJlIGVuZGVkXG4gICAqL1xuICBlbmRUaW1lOiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogR2VzdHVyZSBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHNcbiAgICovXG4gIGR1cmF0aW9uOiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogV2hldGhlciBkZWZhdWx0IGJlaGF2aW9yIHdhcyBwcmV2ZW50ZWRcbiAgICovXG4gIGRlZmF1bHRQcmV2ZW50ZWQ6IGJvb2xlYW47XG4gIFxuICAvKipcbiAgICogUHJldmVudCBkZWZhdWx0IGJlaGF2aW9yXG4gICAqL1xuICBwcmV2ZW50RGVmYXVsdDogKCkgPT4gdm9pZDtcbiAgXG4gIC8qKlxuICAgKiBTdG9wIGV2ZW50IHByb3BhZ2F0aW9uXG4gICAqL1xuICBzdG9wUHJvcGFnYXRpb246ICgpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogVGFwIGdlc3R1cmUgZXZlbnQgZGF0YVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRhcEV2ZW50IGV4dGVuZHMgR2VzdHVyZUV2ZW50IHtcbiAgdHlwZTogJ3RhcCc7XG4gIFxuICAvKipcbiAgICogTnVtYmVyIG9mIHRhcHMgKGZvciBkb3VibGUgdGFwIGRldGVjdGlvbilcbiAgICovXG4gIGNvdW50OiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogWCBwb3NpdGlvbiBvZiB0aGUgdGFwXG4gICAqL1xuICB4OiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogWSBwb3NpdGlvbiBvZiB0aGUgdGFwXG4gICAqL1xuICB5OiBudW1iZXI7XG59XG5cbi8qKlxuICogU3dpcGUgZ2VzdHVyZSBldmVudCBkYXRhXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3dpcGVFdmVudCBleHRlbmRzIEdlc3R1cmVFdmVudCB7XG4gIHR5cGU6ICdzd2lwZScgfCAnc3dpcGVsZWZ0JyB8ICdzd2lwZXJpZ2h0JyB8ICdzd2lwZXVwJyB8ICdzd2lwZWRvd24nO1xuICBcbiAgLyoqXG4gICAqIERpcmVjdGlvbiBvZiB0aGUgc3dpcGVcbiAgICovXG4gIGRpcmVjdGlvbjogJ3VwJyB8ICdkb3duJyB8ICdsZWZ0JyB8ICdyaWdodCc7XG4gIFxuICAvKipcbiAgICogRGlzdGFuY2Ugc3dpcGVkIGluIHRoZSBYIGRpcmVjdGlvblxuICAgKi9cbiAgZGVsdGFYOiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogRGlzdGFuY2Ugc3dpcGVkIGluIHRoZSBZIGRpcmVjdGlvblxuICAgKi9cbiAgZGVsdGFZOiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogVG90YWwgZGlzdGFuY2Ugc3dpcGVkXG4gICAqL1xuICBkaXN0YW5jZTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFZlbG9jaXR5IG9mIHRoZSBzd2lwZSBpbiBwaXhlbHMgcGVyIG1pbGxpc2Vjb25kXG4gICAqL1xuICB2ZWxvY2l0eTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFN0YXJ0IFggcG9zaXRpb25cbiAgICovXG4gIHN0YXJ0WDogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFN0YXJ0IFkgcG9zaXRpb25cbiAgICovXG4gIHN0YXJ0WTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIEVuZCBYIHBvc2l0aW9uXG4gICAqL1xuICBlbmRYOiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogRW5kIFkgcG9zaXRpb25cbiAgICovXG4gIGVuZFk6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBMb25nIHByZXNzIGdlc3R1cmUgZXZlbnQgZGF0YVxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvbmdQcmVzc0V2ZW50IGV4dGVuZHMgR2VzdHVyZUV2ZW50IHtcbiAgdHlwZTogJ2xvbmdwcmVzcyc7XG4gIFxuICAvKipcbiAgICogWCBwb3NpdGlvbiBvZiB0aGUgbG9uZyBwcmVzc1xuICAgKi9cbiAgeDogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFkgcG9zaXRpb24gb2YgdGhlIGxvbmcgcHJlc3NcbiAgICovXG4gIHk6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBQaW5jaCBnZXN0dXJlIGV2ZW50IGRhdGFcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQaW5jaEV2ZW50IGV4dGVuZHMgR2VzdHVyZUV2ZW50IHtcbiAgdHlwZTogJ3BpbmNoJztcbiAgXG4gIC8qKlxuICAgKiBTY2FsZSBmYWN0b3Igb2YgdGhlIHBpbmNoICg+MSBmb3Igem9vbSBpbiwgPDEgZm9yIHpvb20gb3V0KVxuICAgKi9cbiAgc2NhbGU6IG51bWJlcjtcbiAgXG4gIC8qKlxuICAgKiBDZW50ZXIgWCBwb3NpdGlvbiBvZiB0aGUgcGluY2hcbiAgICovXG4gIGNlbnRlclg6IG51bWJlcjtcbiAgXG4gIC8qKlxuICAgKiBDZW50ZXIgWSBwb3NpdGlvbiBvZiB0aGUgcGluY2hcbiAgICovXG4gIGNlbnRlclk6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBSb3RhdGUgZ2VzdHVyZSBldmVudCBkYXRhXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUm90YXRlRXZlbnQgZXh0ZW5kcyBHZXN0dXJlRXZlbnQge1xuICB0eXBlOiAncm90YXRlJztcbiAgXG4gIC8qKlxuICAgKiBSb3RhdGlvbiBhbmdsZSBpbiBkZWdyZWVzXG4gICAqL1xuICByb3RhdGlvbjogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIENlbnRlciBYIHBvc2l0aW9uIG9mIHRoZSByb3RhdGlvblxuICAgKi9cbiAgY2VudGVyWDogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIENlbnRlciBZIHBvc2l0aW9uIG9mIHRoZSByb3RhdGlvblxuICAgKi9cbiAgY2VudGVyWTogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBhbiBnZXN0dXJlIGV2ZW50IGRhdGFcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYW5FdmVudCBleHRlbmRzIEdlc3R1cmVFdmVudCB7XG4gIHR5cGU6ICdwYW4nO1xuICBcbiAgLyoqXG4gICAqIERpc3RhbmNlIHBhbm5lZCBpbiB0aGUgWCBkaXJlY3Rpb25cbiAgICovXG4gIGRlbHRhWDogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIERpc3RhbmNlIHBhbm5lZCBpbiB0aGUgWSBkaXJlY3Rpb25cbiAgICovXG4gIGRlbHRhWTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFN0YXJ0IFggcG9zaXRpb25cbiAgICovXG4gIHN0YXJ0WDogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFN0YXJ0IFkgcG9zaXRpb25cbiAgICovXG4gIHN0YXJ0WTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIEN1cnJlbnQgWCBwb3NpdGlvblxuICAgKi9cbiAgY3VycmVudFg6IG51bWJlcjtcbiAgXG4gIC8qKlxuICAgKiBDdXJyZW50IFkgcG9zaXRpb25cbiAgICovXG4gIGN1cnJlbnRZOiBudW1iZXI7XG59XG5cbi8qKlxuICogVW5pb24gdHlwZSBvZiBhbGwgZ2VzdHVyZSBldmVudHNcbiAqL1xuZXhwb3J0IHR5cGUgQW55R2VzdHVyZUV2ZW50ID0gXG4gIHwgVGFwRXZlbnRcbiAgfCBTd2lwZUV2ZW50IFxuICB8IExvbmdQcmVzc0V2ZW50IFxuICB8IFBpbmNoRXZlbnQgXG4gIHwgUm90YXRlRXZlbnQgXG4gIHwgUGFuRXZlbnQ7XG5cbi8qKlxuICogSGFuZGxlciBmb3IgZ2VzdHVyZSBldmVudHNcbiAqL1xuZXhwb3J0IHR5cGUgR2VzdHVyZUhhbmRsZXIgPSAoZXZlbnQ6IEFueUdlc3R1cmVFdmVudCkgPT4gdm9pZDtcblxuLyoqXG4gKiBHZXN0dXJlIHN0YXRlIGZvciB0cmFja2luZyB0b3VjaCBpbnRlcmFjdGlvbnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHZXN0dXJlU3RhdGUge1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIHN0YXJ0VGltZTogbnVtYmVyO1xuICBzdGFydFg6IG51bWJlcjtcbiAgc3RhcnRZOiBudW1iZXI7XG4gIGxhc3RYOiBudW1iZXI7XG4gIGxhc3RZOiBudW1iZXI7XG4gIGN1cnJlbnRYOiBudW1iZXI7XG4gIGN1cnJlbnRZOiBudW1iZXI7XG4gIHRvdWNoQ291bnQ6IG51bWJlcjtcbiAgbG9uZ1ByZXNzVGltZXI6IG51bWJlciB8IG51bGw7XG4gIHN0YXJ0RGlzdGFuY2U6IG51bWJlcjtcbiAgc3RhcnRBbmdsZTogbnVtYmVyO1xuICBsYXN0VGFwVGltZTogbnVtYmVyO1xuICB0YXBDb3VudDogbnVtYmVyO1xuICB0YXJnZXQ6IEV2ZW50VGFyZ2V0IHwgbnVsbDtcbn1cblxuLyoqXG4gKiBDb250ZXh0IGZvciBnZXN0dXJlIGRldGVjdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0IHtcbiAgc3RhdGU6IEdlc3R1cmVTdGF0ZTtcbiAgb3B0aW9uczogUmVxdWlyZWQ8R2VzdHVyZUNvbmZpZz47XG4gIG9yaWdpbmFsRXZlbnQ6IEV2ZW50O1xufVxuXG4vKipcbiAqIEdlc3R1cmUgbWFuYWdlciBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHZXN0dXJlTWFuYWdlciB7XG4gIC8qKlxuICAgKiBBZGQgYW4gZXZlbnQgbGlzdGVuZXIgZm9yIGEgZ2VzdHVyZVxuICAgKiBAcGFyYW0gZXZlbnRUeXBlIC0gR2VzdHVyZSB0eXBlXG4gICAqIEBwYXJhbSBoYW5kbGVyIC0gRXZlbnQgaGFuZGxlclxuICAgKiBAcmV0dXJucyBHZXN0dXJlIG1hbmFnZXIgZm9yIGNoYWluaW5nXG4gICAqL1xuICBvbjogKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiBHZXN0dXJlSGFuZGxlcikgPT4gR2VzdHVyZU1hbmFnZXI7XG4gIFxuICAvKipcbiAgICogUmVtb3ZlIGFuIGV2ZW50IGxpc3RlbmVyIGZvciBhIGdlc3R1cmVcbiAgICogQHBhcmFtIGV2ZW50VHlwZSAtIEdlc3R1cmUgdHlwZVxuICAgKiBAcGFyYW0gaGFuZGxlciAtIEV2ZW50IGhhbmRsZXJcbiAgICogQHJldHVybnMgR2VzdHVyZSBtYW5hZ2VyIGZvciBjaGFpbmluZ1xuICAgKi9cbiAgb2ZmOiAoZXZlbnRUeXBlOiBzdHJpbmcsIGhhbmRsZXI6IEdlc3R1cmVIYW5kbGVyKSA9PiBHZXN0dXJlTWFuYWdlcjtcbiAgXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIGdlc3R1cmUgaXMgc3VwcG9ydGVkIG9uIHRoZSBjdXJyZW50IGRldmljZVxuICAgKiBAcGFyYW0gZ2VzdHVyZVR5cGUgLSBUeXBlIG9mIGdlc3R1cmUgdG8gY2hlY2tcbiAgICogQHJldHVybnMgV2hldGhlciB0aGUgZ2VzdHVyZSBpcyBzdXBwb3J0ZWRcbiAgICovXG4gIGlzU3VwcG9ydGVkOiAoZ2VzdHVyZVR5cGU6IHN0cmluZykgPT4gYm9vbGVhbjtcbiAgXG4gIC8qKlxuICAgKiBFbmFibGUgZ2VzdHVyZSByZWNvZ25pdGlvblxuICAgKiBAcmV0dXJucyBHZXN0dXJlIG1hbmFnZXIgZm9yIGNoYWluaW5nXG4gICAqL1xuICBlbmFibGU6ICgpID0+IEdlc3R1cmVNYW5hZ2VyO1xuICBcbiAgLyoqXG4gICAqIERpc2FibGUgZ2VzdHVyZSByZWNvZ25pdGlvblxuICAgKiBAcmV0dXJucyBHZXN0dXJlIG1hbmFnZXIgZm9yIGNoYWluaW5nXG4gICAqL1xuICBkaXNhYmxlOiAoKSA9PiBHZXN0dXJlTWFuYWdlcjtcbiAgXG4gIC8qKlxuICAgKiBDbGVhbiB1cCBldmVudCBsaXN0ZW5lcnNcbiAgICovXG4gIGRlc3Ryb3k6ICgpID0+IHZvaWQ7XG59IiwKICAgICIvLyBzcmMvY29yZS9nZXN0dXJlcy91dGlscy50c1xuLyoqXG4gKiBAbW9kdWxlIGNvcmUvZ2VzdHVyZXNcbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGZ1bmN0aW9ucyBmb3IgZ2VzdHVyZSBkZXRlY3Rpb25cbiAqL1xuXG5pbXBvcnQgeyBHZXN0dXJlRXZlbnQsIEdlc3R1cmVTdGF0ZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQ2FsY3VsYXRlIGRpc3RhbmNlIGJldHdlZW4gdHdvIHBvaW50c1xuICpcbiAqIEBwYXJhbSB4MSAtIFggY29vcmRpbmF0ZSBvZiBmaXJzdCBwb2ludFxuICogQHBhcmFtIHkxIC0gWSBjb29yZGluYXRlIG9mIGZpcnN0IHBvaW50XG4gKiBAcGFyYW0geDIgLSBYIGNvb3JkaW5hdGUgb2Ygc2Vjb25kIHBvaW50XG4gKiBAcGFyYW0geTIgLSBZIGNvb3JkaW5hdGUgb2Ygc2Vjb25kIHBvaW50XG4gKiBAcmV0dXJucyBEaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERpc3RhbmNlKFxuICB4MTogbnVtYmVyLFxuICB5MTogbnVtYmVyLFxuICB4MjogbnVtYmVyLFxuICB5MjogbnVtYmVyXG4pOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHgyIC0geDEsIDIpICsgTWF0aC5wb3coeTIgLSB5MSwgMikpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBhbmdsZSBiZXR3ZWVuIHR3byBwb2ludHMgaW4gZGVncmVlcyAoMC0zNjApXG4gKlxuICogQHBhcmFtIHgxIC0gWCBjb29yZGluYXRlIG9mIGZpcnN0IHBvaW50XG4gKiBAcGFyYW0geTEgLSBZIGNvb3JkaW5hdGUgb2YgZmlyc3QgcG9pbnRcbiAqIEBwYXJhbSB4MiAtIFggY29vcmRpbmF0ZSBvZiBzZWNvbmQgcG9pbnRcbiAqIEBwYXJhbSB5MiAtIFkgY29vcmRpbmF0ZSBvZiBzZWNvbmQgcG9pbnRcbiAqIEByZXR1cm5zIEFuZ2xlIGluIGRlZ3JlZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFuZ2xlKFxuICB4MTogbnVtYmVyLFxuICB5MTogbnVtYmVyLFxuICB4MjogbnVtYmVyLFxuICB5MjogbnVtYmVyXG4pOiBudW1iZXIge1xuICBjb25zdCBhbmdsZSA9IChNYXRoLmF0YW4yKHkyIC0geTEsIHgyIC0geDEpICogMTgwKSAvIE1hdGguUEk7XG4gIHJldHVybiBhbmdsZSA8IDAgPyBhbmdsZSArIDM2MCA6IGFuZ2xlO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIGJhc2UgZ2VzdHVyZSBldmVudFxuICpcbiAqIEBwYXJhbSB0eXBlIC0gVHlwZSBvZiBnZXN0dXJlXG4gKiBAcGFyYW0gb3JpZ2luYWxFdmVudCAtIE9yaWdpbmFsIERPTSBldmVudFxuICogQHBhcmFtIHN0YXRlIC0gQ3VycmVudCBnZXN0dXJlIHN0YXRlXG4gKiBAcmV0dXJucyBCYXNlIGdlc3R1cmUgZXZlbnQgb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVHZXN0dXJlRXZlbnQoXG4gIHR5cGU6IHN0cmluZyxcbiAgb3JpZ2luYWxFdmVudDogRXZlbnQsXG4gIHN0YXRlOiBHZXN0dXJlU3RhdGVcbik6IEdlc3R1cmVFdmVudCB7XG4gIGNvbnN0IGVuZFRpbWUgPSBEYXRlLm5vdygpO1xuICBsZXQgZGVmYXVsdFByZXZlbnRlZCA9IGZhbHNlO1xuXG4gIGNvbnN0IGV2ZW50OiBHZXN0dXJlRXZlbnQgPSB7XG4gICAgdHlwZSxcbiAgICBvcmlnaW5hbEV2ZW50LFxuICAgIHRhcmdldDpcbiAgICAgIChzdGF0ZS50YXJnZXQgYXMgRXZlbnRUYXJnZXQpIHx8IChvcmlnaW5hbEV2ZW50LnRhcmdldCBhcyBFdmVudFRhcmdldCksXG4gICAgc3RhcnRUaW1lOiBzdGF0ZS5zdGFydFRpbWUsXG4gICAgZW5kVGltZSxcbiAgICBkdXJhdGlvbjogZW5kVGltZSAtIHN0YXRlLnN0YXJ0VGltZSxcbiAgICBkZWZhdWx0UHJldmVudGVkLFxuICAgIHByZXZlbnREZWZhdWx0OiAoKSA9PiB7XG4gICAgICBkZWZhdWx0UHJldmVudGVkID0gdHJ1ZTtcbiAgICAgIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xuICAgICAgaWYgKG9yaWdpbmFsRXZlbnQuY2FuY2VsYWJsZSkge1xuICAgICAgICBvcmlnaW5hbEV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBzdG9wUHJvcGFnYXRpb246ICgpID0+IHtcbiAgICAgIG9yaWdpbmFsRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSxcbiAgfTtcblxuICByZXR1cm4gZXZlbnQ7XG59XG5cbi8qKlxuICogRGV0ZWN0IGlmIHRoZSBkZXZpY2Ugc3VwcG9ydHMgdG91Y2ggZXZlbnRzXG4gKlxuICogQHJldHVybnMgV2hldGhlciB0b3VjaCBpcyBzdXBwb3J0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1RvdWNoU3VwcG9ydCgpOiBib29sZWFuIHtcbiAgY29uc3QgbWF4UG9pbnRzID0gKG5hdmlnYXRvciBhcyBhbnkpLm1heFRvdWNoUG9pbnRzO1xuICByZXR1cm4gKFxuICAgIFwib250b3VjaHN0YXJ0XCIgaW4gd2luZG93IHx8ICh0eXBlb2YgbWF4UG9pbnRzID09PSBcIm51bWJlclwiICYmIG1heFBvaW50cyA+IDApXG4gICk7XG59XG5cbi8qKlxuICogRGV0ZWN0IGlmIHRoZSBkZXZpY2Ugc3VwcG9ydHMgcG9pbnRlciBldmVudHNcbiAqXG4gKiBAcmV0dXJucyBXaGV0aGVyIHBvaW50ZXIgZXZlbnRzIGFyZSBzdXBwb3J0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1BvaW50ZXJTdXBwb3J0KCk6IGJvb2xlYW4ge1xuICByZXR1cm4gISF3aW5kb3cuUG9pbnRlckV2ZW50O1xufVxuXG4vKipcbiAqIEV4dHJhY3Qgbm9ybWFsaXplZCB0b3VjaCBjb29yZGluYXRlcyBmcm9tIGFuIGV2ZW50XG4gKiBXb3JrcyB3aXRoIG1vdXNlIGV2ZW50cywgdG91Y2ggZXZlbnRzIGFuZCBwb2ludGVyIGV2ZW50c1xuICpcbiAqIEBwYXJhbSBlIC0gRE9NIGV2ZW50XG4gKiBAcmV0dXJucyBPYmplY3Qgd2l0aCBjbGllbnRYIGFuZCBjbGllbnRZIGNvb3JkaW5hdGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUb3VjaENvb3JkaW5hdGVzKFxuICBlOiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCB8IFBvaW50ZXJFdmVudFxuKTogeyBjbGllbnRYOiBudW1iZXI7IGNsaWVudFk6IG51bWJlciB9IHtcbiAgaWYgKFwidG91Y2hlc1wiIGluIGUgJiYgQXJyYXkuaXNBcnJheShlLnRvdWNoZXMpICYmIGUudG91Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNsaWVudFg6IGUudG91Y2hlc1swXS5jbGllbnRYLFxuICAgICAgY2xpZW50WTogZS50b3VjaGVzWzBdLmNsaWVudFksXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY2xpZW50WDogKGUgYXMgTW91c2VFdmVudCB8IFBvaW50ZXJFdmVudCkuY2xpZW50WCxcbiAgICBjbGllbnRZOiAoZSBhcyBNb3VzZUV2ZW50IHwgUG9pbnRlckV2ZW50KS5jbGllbnRZLFxuICB9O1xufVxuIiwKICAgICIvLyBzcmMvY29yZS9nZXN0dXJlcy90YXAudHNcbi8qKlxuICogQG1vZHVsZSBjb3JlL2dlc3R1cmVzXG4gKiBAZGVzY3JpcHRpb24gVGFwIGdlc3R1cmUgZGV0ZWN0aW9uXG4gKi9cblxuaW1wb3J0IHsgVGFwRXZlbnQsIEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0IH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBjcmVhdGVHZXN0dXJlRXZlbnQgfSBmcm9tICcuL3V0aWxzJztcblxuLyoqXG4gKiBEZXRlY3QgdGFwIGdlc3R1cmVcbiAqIFxuICogQHBhcmFtIGNvbnRleHQgLSBHZXN0dXJlIGRldGVjdGlvbiBjb250ZXh0XG4gKiBAcmV0dXJucyBUYXAgZXZlbnQgb3IgbnVsbCBpZiBubyB0YXAgZGV0ZWN0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdFRhcChjb250ZXh0OiBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCk6IFRhcEV2ZW50IHwgbnVsbCB7XG4gIGNvbnN0IHsgc3RhdGUsIG9wdGlvbnMsIG9yaWdpbmFsRXZlbnQgfSA9IGNvbnRleHQ7XG4gIFxuICAvLyBDYWxjdWxhdGUgZGlzdGFuY2UgYmV0d2VlbiBzdGFydCBhbmQgY3VycmVudCBwb3NpdGlvblxuICBjb25zdCBkZWx0YVggPSBzdGF0ZS5jdXJyZW50WCAtIHN0YXRlLnN0YXJ0WDtcbiAgY29uc3QgZGVsdGFZID0gc3RhdGUuY3VycmVudFkgLSBzdGF0ZS5zdGFydFk7XG4gIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5zcXJ0KGRlbHRhWCAqIGRlbHRhWCArIGRlbHRhWSAqIGRlbHRhWSk7XG4gIFxuICAvLyBDaGVjayBpZiBtb3ZlbWVudCBpcyB3aXRoaW4gdGhyZXNob2xkXG4gIGlmIChkaXN0YW5jZSA8IG9wdGlvbnMudGFwRGlzdGFuY2VUaHJlc2hvbGQpIHtcbiAgICAvLyBDaGVjayBmb3IgZG91YmxlIHRhcFxuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3QgaXNEb3VibGVUYXAgPSBub3cgLSBzdGF0ZS5sYXN0VGFwVGltZSA8IDMwMDtcbiAgICBcbiAgICBjb25zdCB0YXBDb3VudCA9IGlzRG91YmxlVGFwID8gc3RhdGUudGFwQ291bnQgKyAxIDogMTtcbiAgICBcbiAgICAvLyBDcmVhdGUgdGFwIGV2ZW50XG4gICAgY29uc3QgdGFwRXZlbnQ6IFRhcEV2ZW50ID0ge1xuICAgICAgLi4uY3JlYXRlR2VzdHVyZUV2ZW50KCd0YXAnLCBvcmlnaW5hbEV2ZW50LCBzdGF0ZSksXG4gICAgICB0eXBlOiAndGFwJyxcbiAgICAgIGNvdW50OiB0YXBDb3VudCxcbiAgICAgIHg6IHN0YXRlLmN1cnJlbnRYLFxuICAgICAgeTogc3RhdGUuY3VycmVudFlcbiAgICB9O1xuICAgIFxuICAgIHJldHVybiB0YXBFdmVudDtcbiAgfVxuICBcbiAgcmV0dXJuIG51bGw7XG59IiwKICAgICIvLyBzcmMvY29yZS9nZXN0dXJlcy9zd2lwZS50c1xuLyoqXG4gKiBAbW9kdWxlIGNvcmUvZ2VzdHVyZXNcbiAqIEBkZXNjcmlwdGlvbiBTd2lwZSBnZXN0dXJlIGRldGVjdGlvblxuICovXG5cbmltcG9ydCB7IFN3aXBlRXZlbnQsIEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0LCBTV0lQRV9ESVJFQ1RJT05TIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBjcmVhdGVHZXN0dXJlRXZlbnQgfSBmcm9tICcuL3V0aWxzJztcblxuLyoqXG4gKiBEZXRlcm1pbmUgc3dpcGUgZGlyZWN0aW9uIGJhc2VkIG9uIGRlbHRhIFggYW5kIFlcbiAqIFxuICogQHBhcmFtIGRlbHRhWCAtIERpc3RhbmNlIG1vdmVkIGluIFggZGlyZWN0aW9uXG4gKiBAcGFyYW0gZGVsdGFZIC0gRGlzdGFuY2UgbW92ZWQgaW4gWSBkaXJlY3Rpb25cbiAqIEByZXR1cm5zIERpcmVjdGlvbiBvZiB0aGUgc3dpcGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN3aXBlRGlyZWN0aW9uKGRlbHRhWDogbnVtYmVyLCBkZWx0YVk6IG51bWJlcik6IFNXSVBFX0RJUkVDVElPTlMge1xuICBpZiAoTWF0aC5hYnMoZGVsdGFYKSA+IE1hdGguYWJzKGRlbHRhWSkpIHtcbiAgICByZXR1cm4gZGVsdGFYID4gMCA/IFNXSVBFX0RJUkVDVElPTlMuUklHSFQgOiBTV0lQRV9ESVJFQ1RJT05TLkxFRlQ7XG4gIH1cbiAgcmV0dXJuIGRlbHRhWSA+IDAgPyBTV0lQRV9ESVJFQ1RJT05TLkRPV04gOiBTV0lQRV9ESVJFQ1RJT05TLlVQO1xufVxuXG4vKipcbiAqIERldGVjdCBzd2lwZSBnZXN0dXJlXG4gKiBcbiAqIEBwYXJhbSBjb250ZXh0IC0gR2VzdHVyZSBkZXRlY3Rpb24gY29udGV4dFxuICogQHJldHVybnMgU3dpcGUgZXZlbnQgb3IgbnVsbCBpZiBubyBzd2lwZSBkZXRlY3RlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0U3dpcGUoY29udGV4dDogR2VzdHVyZURldGVjdGlvbkNvbnRleHQpOiBTd2lwZUV2ZW50IHwgbnVsbCB7XG4gIGNvbnN0IHsgc3RhdGUsIG9wdGlvbnMsIG9yaWdpbmFsRXZlbnQgfSA9IGNvbnRleHQ7XG4gIFxuICAvLyBDYWxjdWxhdGUgZGVsdGFzIGFuZCBkaXN0YW5jZVxuICBjb25zdCBkZWx0YVggPSBzdGF0ZS5jdXJyZW50WCAtIHN0YXRlLnN0YXJ0WDtcbiAgY29uc3QgZGVsdGFZID0gc3RhdGUuY3VycmVudFkgLSBzdGF0ZS5zdGFydFk7XG4gIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5zcXJ0KGRlbHRhWCAqIGRlbHRhWCArIGRlbHRhWSAqIGRlbHRhWSk7XG4gIFxuICAvLyBDYWxjdWxhdGUgdGltZSBhbmQgdmVsb2NpdHlcbiAgY29uc3QgZW5kVGltZSA9IERhdGUubm93KCk7XG4gIGNvbnN0IGRlbHRhVGltZSA9IGVuZFRpbWUgLSBzdGF0ZS5zdGFydFRpbWU7XG4gIGNvbnN0IHZlbG9jaXR5ID0gZGlzdGFuY2UgLyBkZWx0YVRpbWU7XG4gIFxuICAvLyBDaGVjayBpZiBpdCdzIGEgc3dpcGVcbiAgaWYgKGRpc3RhbmNlID49IG9wdGlvbnMuc3dpcGVUaHJlc2hvbGQgJiYgZGVsdGFUaW1lIDw9IG9wdGlvbnMuc3dpcGVUaW1lVGhyZXNob2xkKSB7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gZ2V0U3dpcGVEaXJlY3Rpb24oZGVsdGFYLCBkZWx0YVkpO1xuICAgIFxuICAgIC8vIENyZWF0ZSBzd2lwZSBldmVudFxuICAgIGNvbnN0IHN3aXBlRXZlbnQ6IFN3aXBlRXZlbnQgPSB7XG4gICAgICAuLi5jcmVhdGVHZXN0dXJlRXZlbnQoJ3N3aXBlJywgb3JpZ2luYWxFdmVudCwgc3RhdGUpLFxuICAgICAgdHlwZTogJ3N3aXBlJyxcbiAgICAgIGRpcmVjdGlvbixcbiAgICAgIGRlbHRhWCxcbiAgICAgIGRlbHRhWSxcbiAgICAgIGRpc3RhbmNlLFxuICAgICAgdmVsb2NpdHksXG4gICAgICBzdGFydFg6IHN0YXRlLnN0YXJ0WCxcbiAgICAgIHN0YXJ0WTogc3RhdGUuc3RhcnRZLFxuICAgICAgZW5kWDogc3RhdGUuY3VycmVudFgsXG4gICAgICBlbmRZOiBzdGF0ZS5jdXJyZW50WVxuICAgIH07XG4gICAgXG4gICAgcmV0dXJuIHN3aXBlRXZlbnQ7XG4gIH1cbiAgXG4gIHJldHVybiBudWxsO1xufSIsCiAgICAiLy8gc3JjL2NvcmUvZ2VzdHVyZXMvbG9uZ3ByZXNzLnRzXG4vKipcbiAqIEBtb2R1bGUgY29yZS9nZXN0dXJlc1xuICogQGRlc2NyaXB0aW9uIExvbmcgcHJlc3MgZ2VzdHVyZSBkZXRlY3Rpb25cbiAqL1xuXG5pbXBvcnQgeyBMb25nUHJlc3NFdmVudCwgR2VzdHVyZURldGVjdGlvbkNvbnRleHQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGNyZWF0ZUdlc3R1cmVFdmVudCB9IGZyb20gJy4vdXRpbHMnO1xuXG4vKipcbiAqIERldGVjdCBsb25nIHByZXNzIGdlc3R1cmVcbiAqIFxuICogVGhpcyBpcyBzbGlnaHRseSBkaWZmZXJlbnQgZnJvbSBvdGhlciBnZXN0dXJlIGRldGVjdG9ycyBhcyBpdCBzZXRzIHVwIGEgdGltZXJcbiAqIGFuZCByZXR1cm5zIGEgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIHRyaWdnZXJlZCB3aGVuIHRoZSB0aW1lciBjb21wbGV0ZXMuXG4gKiBcbiAqIEBwYXJhbSBjb250ZXh0IC0gR2VzdHVyZSBkZXRlY3Rpb24gY29udGV4dFxuICogQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIGxvbmcgcHJlc3MgaXMgZGV0ZWN0ZWRcbiAqIEByZXR1cm5zIENsZWFudXAgZnVuY3Rpb24gdG8gY2FuY2VsIHRoZSBsb25nIHByZXNzIGRldGVjdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0TG9uZ1ByZXNzKFxuICBjb250ZXh0OiBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCxcbiAgY2FsbGJhY2s6IChldmVudDogTG9uZ1ByZXNzRXZlbnQpID0+IHZvaWRcbik6ICgpID0+IHZvaWQge1xuICBjb25zdCB7IHN0YXRlLCBvcHRpb25zLCBvcmlnaW5hbEV2ZW50IH0gPSBjb250ZXh0O1xuICBcbiAgLy8gU2V0IGEgdGltZXIgZm9yIGxvbmcgcHJlc3MgZGV0ZWN0aW9uXG4gIGNvbnN0IHRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgIC8vIE9ubHkgdHJpZ2dlciBpZiBnZXN0dXJlIGlzIHN0aWxsIGFjdGl2ZVxuICAgIGlmIChzdGF0ZS5hY3RpdmUpIHtcbiAgICAgIC8vIENoZWNrIGlmIG1vdmVtZW50IGlzIHdpdGhpbiB0aHJlc2hvbGRcbiAgICAgIGNvbnN0IGRpZmZYID0gTWF0aC5hYnMoc3RhdGUuY3VycmVudFggLSBzdGF0ZS5zdGFydFgpO1xuICAgICAgY29uc3QgZGlmZlkgPSBNYXRoLmFicyhzdGF0ZS5jdXJyZW50WSAtIHN0YXRlLnN0YXJ0WSk7XG4gICAgICBcbiAgICAgIGlmIChkaWZmWCA8IG9wdGlvbnMudGFwRGlzdGFuY2VUaHJlc2hvbGQgJiYgZGlmZlkgPCBvcHRpb25zLnRhcERpc3RhbmNlVGhyZXNob2xkKSB7XG4gICAgICAgIC8vIENyZWF0ZSBsb25nIHByZXNzIGV2ZW50XG4gICAgICAgIGNvbnN0IGxvbmdQcmVzc0V2ZW50OiBMb25nUHJlc3NFdmVudCA9IHtcbiAgICAgICAgICAuLi5jcmVhdGVHZXN0dXJlRXZlbnQoJ2xvbmdwcmVzcycsIG9yaWdpbmFsRXZlbnQsIHN0YXRlKSxcbiAgICAgICAgICB0eXBlOiAnbG9uZ3ByZXNzJyxcbiAgICAgICAgICB4OiBzdGF0ZS5jdXJyZW50WCxcbiAgICAgICAgICB5OiBzdGF0ZS5jdXJyZW50WVxuICAgICAgICB9O1xuICAgICAgICBcbiAgICAgICAgLy8gVHJpZ2dlciBjYWxsYmFja1xuICAgICAgICBjYWxsYmFjayhsb25nUHJlc3NFdmVudCk7XG4gICAgICB9XG4gICAgfVxuICB9LCBvcHRpb25zLmxvbmdQcmVzc1RpbWUpO1xuICBcbiAgLy8gUmV0dXJuIGNsZWFudXAgZnVuY3Rpb25cbiAgcmV0dXJuICgpID0+IHtcbiAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICB9O1xufVxuXG4vKipcbiAqIENoZWNrIGlmIG1vdmVtZW50IHdvdWxkIGNhbmNlbCBhIGxvbmcgcHJlc3NcbiAqIFxuICogQHBhcmFtIGNvbnRleHQgLSBHZXN0dXJlIGRldGVjdGlvbiBjb250ZXh0XG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBsb25nIHByZXNzIHNob3VsZCBiZSBjYW5jZWxlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2hvdWxkQ2FuY2VsTG9uZ1ByZXNzKGNvbnRleHQ6IEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0KTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgc3RhdGUsIG9wdGlvbnMgfSA9IGNvbnRleHQ7XG4gIFxuICBjb25zdCBkaWZmWCA9IE1hdGguYWJzKHN0YXRlLmN1cnJlbnRYIC0gc3RhdGUuc3RhcnRYKTtcbiAgY29uc3QgZGlmZlkgPSBNYXRoLmFicyhzdGF0ZS5jdXJyZW50WSAtIHN0YXRlLnN0YXJ0WSk7XG4gIFxuICByZXR1cm4gZGlmZlggPiBvcHRpb25zLnRhcERpc3RhbmNlVGhyZXNob2xkIHx8IGRpZmZZID4gb3B0aW9ucy50YXBEaXN0YW5jZVRocmVzaG9sZDtcbn0iLAogICAgIi8vIHNyYy9jb3JlL2dlc3R1cmVzL3Bhbi50c1xuLyoqXG4gKiBAbW9kdWxlIGNvcmUvZ2VzdHVyZXNcbiAqIEBkZXNjcmlwdGlvbiBQYW4gZ2VzdHVyZSBkZXRlY3Rpb25cbiAqL1xuXG5pbXBvcnQgeyBQYW5FdmVudCwgR2VzdHVyZURldGVjdGlvbkNvbnRleHQgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgY3JlYXRlR2VzdHVyZUV2ZW50IH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBEZXRlY3QgcGFuIGdlc3R1cmVcbiAqXG4gKiBAcGFyYW0gY29udGV4dCAtIEdlc3R1cmUgZGV0ZWN0aW9uIGNvbnRleHRcbiAqIEByZXR1cm5zIFBhbiBldmVudCBvciBudWxsIGlmIG5vIHNpZ25pZmljYW50IG1vdmVtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXRlY3RQYW4oY29udGV4dDogR2VzdHVyZURldGVjdGlvbkNvbnRleHQpOiBQYW5FdmVudCB8IG51bGwge1xuICBjb25zdCB7IHN0YXRlLCBvcmlnaW5hbEV2ZW50IH0gPSBjb250ZXh0O1xuXG4gIC8vIENhbGN1bGF0ZSBkZWx0YSBmcm9tIHN0YXJ0IHBvc2l0aW9uXG4gIGNvbnN0IGRlbHRhWCA9IHN0YXRlLmN1cnJlbnRYIC0gc3RhdGUuc3RhcnRYO1xuICBjb25zdCBkZWx0YVkgPSBzdGF0ZS5jdXJyZW50WSAtIHN0YXRlLnN0YXJ0WTtcblxuICAvLyBDYWxjdWxhdGUgZGVsdGEgZnJvbSBsYXN0IHBvc2l0aW9uIHRvIGRldGVybWluZSBpZiB0aGVyZSdzIHNpZ25pZmljYW50IG1vdmVtZW50XG4gIGNvbnN0IG1vdmVEZWx0YVggPSBzdGF0ZS5jdXJyZW50WCAtIHN0YXRlLmxhc3RYO1xuICBjb25zdCBtb3ZlRGVsdGFZID0gc3RhdGUuY3VycmVudFkgLSBzdGF0ZS5sYXN0WTtcbiAgY29uc3QgbW92ZURlbHRhID0gTWF0aC5zcXJ0KFxuICAgIG1vdmVEZWx0YVggKiBtb3ZlRGVsdGFYICsgbW92ZURlbHRhWSAqIG1vdmVEZWx0YVlcbiAgKTtcblxuICAvLyBDaGVjayBpZiBtb3ZlbWVudCBpcyBzaWduaWZpY2FudFxuICBpZiAobW92ZURlbHRhID4gMCkge1xuICAgIC8vIENyZWF0ZSBwYW4gZXZlbnRcbiAgICBjb25zdCBwYW5FdmVudDogUGFuRXZlbnQgPSB7XG4gICAgICAuLi5jcmVhdGVHZXN0dXJlRXZlbnQoXCJwYW5cIiwgb3JpZ2luYWxFdmVudCwgc3RhdGUpLFxuICAgICAgdHlwZTogXCJwYW5cIixcbiAgICAgIGRlbHRhWCxcbiAgICAgIGRlbHRhWSxcbiAgICAgIHN0YXJ0WDogc3RhdGUuc3RhcnRYLFxuICAgICAgc3RhcnRZOiBzdGF0ZS5zdGFydFksXG4gICAgICBjdXJyZW50WDogc3RhdGUuY3VycmVudFgsXG4gICAgICBjdXJyZW50WTogc3RhdGUuY3VycmVudFksXG4gICAgfTtcblxuICAgIHJldHVybiBwYW5FdmVudDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuIiwKICAgICIvLyBzcmMvY29yZS9nZXN0dXJlcy9waW5jaC50c1xuLyoqXG4gKiBAbW9kdWxlIGNvcmUvZ2VzdHVyZXNcbiAqIEBkZXNjcmlwdGlvbiBQaW5jaCBnZXN0dXJlIGRldGVjdGlvblxuICovXG5cbmltcG9ydCB7IFBpbmNoRXZlbnQsIEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0IH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IGNyZWF0ZUdlc3R1cmVFdmVudCwgZ2V0RGlzdGFuY2UgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG4vKipcbiAqIERldGVjdCBwaW5jaCBnZXN0dXJlXG4gKlxuICogQHBhcmFtIGNvbnRleHQgLSBHZXN0dXJlIGRldGVjdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0gdG91Y2gxIC0gRmlyc3QgdG91Y2ggcG9pbnRcbiAqIEBwYXJhbSB0b3VjaDIgLSBTZWNvbmQgdG91Y2ggcG9pbnRcbiAqIEByZXR1cm5zIFBpbmNoIGV2ZW50IG9yIG51bGwgaWYgbm8gcGluY2ggZGV0ZWN0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdFBpbmNoKFxuICBjb250ZXh0OiBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCxcbiAgdG91Y2gxOiBUb3VjaCxcbiAgdG91Y2gyOiBUb3VjaFxuKTogUGluY2hFdmVudCB8IG51bGwge1xuICBjb25zdCB7IHN0YXRlLCBvcmlnaW5hbEV2ZW50IH0gPSBjb250ZXh0O1xuXG4gIC8vIENhbGN1bGF0ZSBjdXJyZW50IGRpc3RhbmNlIGJldHdlZW4gdG91Y2ggcG9pbnRzXG4gIGNvbnN0IGN1cnJlbnREaXN0YW5jZSA9IGdldERpc3RhbmNlKFxuICAgIHRvdWNoMS5jbGllbnRYLFxuICAgIHRvdWNoMS5jbGllbnRZLFxuICAgIHRvdWNoMi5jbGllbnRYLFxuICAgIHRvdWNoMi5jbGllbnRZXG4gICk7XG5cbiAgLy8gTWluaW11bSBtb3ZlbWVudCB0aHJlc2hvbGQgZm9yIHBpbmNoIGRldGVjdGlvblxuICBjb25zdCBQSU5DSF9USFJFU0hPTEQgPSAxMDtcblxuICAvLyBDaGVjayBpZiB0aGUgZGlzdGFuY2UgY2hhbmdlIGlzIHNpZ25pZmljYW50XG4gIGlmIChNYXRoLmFicyhjdXJyZW50RGlzdGFuY2UgLSBzdGF0ZS5zdGFydERpc3RhbmNlKSA+IFBJTkNIX1RIUkVTSE9MRCkge1xuICAgIC8vIENhbGN1bGF0ZSBzY2FsZSBmYWN0b3JcbiAgICBjb25zdCBzY2FsZSA9IGN1cnJlbnREaXN0YW5jZSAvIHN0YXRlLnN0YXJ0RGlzdGFuY2U7XG5cbiAgICAvLyBDYWxjdWxhdGUgY2VudGVyIHBvaW50XG4gICAgY29uc3QgY2VudGVyWCA9ICh0b3VjaDEuY2xpZW50WCArIHRvdWNoMi5jbGllbnRYKSAvIDI7XG4gICAgY29uc3QgY2VudGVyWSA9ICh0b3VjaDEuY2xpZW50WSArIHRvdWNoMi5jbGllbnRZKSAvIDI7XG5cbiAgICAvLyBDcmVhdGUgcGluY2ggZXZlbnRcbiAgICBjb25zdCBwaW5jaEV2ZW50OiBQaW5jaEV2ZW50ID0ge1xuICAgICAgLi4uY3JlYXRlR2VzdHVyZUV2ZW50KFwicGluY2hcIiwgb3JpZ2luYWxFdmVudCwgc3RhdGUpLFxuICAgICAgdHlwZTogXCJwaW5jaFwiLFxuICAgICAgc2NhbGUsXG4gICAgICBjZW50ZXJYLFxuICAgICAgY2VudGVyWSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHBpbmNoRXZlbnQ7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbiIsCiAgICAiLy8gc3JjL2NvcmUvZ2VzdHVyZXMvcm90YXRlLnRzXG4vKipcbiAqIEBtb2R1bGUgY29yZS9nZXN0dXJlc1xuICogQGRlc2NyaXB0aW9uIFJvdGF0ZSBnZXN0dXJlIGRldGVjdGlvblxuICovXG5cbmltcG9ydCB7IFJvdGF0ZUV2ZW50LCBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBjcmVhdGVHZXN0dXJlRXZlbnQsIGdldEFuZ2xlIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBEZXRlY3Qgcm90YXRlIGdlc3R1cmVcbiAqXG4gKiBAcGFyYW0gY29udGV4dCAtIEdlc3R1cmUgZGV0ZWN0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSB0b3VjaDEgLSBGaXJzdCB0b3VjaCBwb2ludFxuICogQHBhcmFtIHRvdWNoMiAtIFNlY29uZCB0b3VjaCBwb2ludFxuICogQHJldHVybnMgUm90YXRlIGV2ZW50IG9yIG51bGwgaWYgbm8gcm90YXRpb24gZGV0ZWN0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdFJvdGF0ZShcbiAgY29udGV4dDogR2VzdHVyZURldGVjdGlvbkNvbnRleHQsXG4gIHRvdWNoMTogVG91Y2gsXG4gIHRvdWNoMjogVG91Y2hcbik6IFJvdGF0ZUV2ZW50IHwgbnVsbCB7XG4gIGNvbnN0IHsgc3RhdGUsIG9yaWdpbmFsRXZlbnQgfSA9IGNvbnRleHQ7XG5cbiAgLy8gQ2FsY3VsYXRlIGN1cnJlbnQgYW5nbGUgYmV0d2VlbiB0b3VjaCBwb2ludHNcbiAgY29uc3QgY3VycmVudEFuZ2xlID0gZ2V0QW5nbGUoXG4gICAgdG91Y2gxLmNsaWVudFgsXG4gICAgdG91Y2gxLmNsaWVudFksXG4gICAgdG91Y2gyLmNsaWVudFgsXG4gICAgdG91Y2gyLmNsaWVudFlcbiAgKTtcblxuICAvLyBNaW5pbXVtIHJvdGF0aW9uIHRocmVzaG9sZCBmb3IgZGV0ZWN0aW9uXG4gIGNvbnN0IFJPVEFUSU9OX1RIUkVTSE9MRCA9IDEwO1xuXG4gIC8vIENhbGN1bGF0ZSByb3RhdGlvbiBkaWZmZXJlbmNlXG4gIGNvbnN0IHJvdGF0aW9uRGlmZiA9IGN1cnJlbnRBbmdsZSAtIHN0YXRlLnN0YXJ0QW5nbGU7XG5cbiAgLy8gQ2hlY2sgaWYgcm90YXRpb24gaXMgc2lnbmlmaWNhbnRcbiAgaWYgKE1hdGguYWJzKHJvdGF0aW9uRGlmZikgPiBST1RBVElPTl9USFJFU0hPTEQpIHtcbiAgICAvLyBDYWxjdWxhdGUgY2VudGVyIHBvaW50XG4gICAgY29uc3QgY2VudGVyWCA9ICh0b3VjaDEuY2xpZW50WCArIHRvdWNoMi5jbGllbnRYKSAvIDI7XG4gICAgY29uc3QgY2VudGVyWSA9ICh0b3VjaDEuY2xpZW50WSArIHRvdWNoMi5jbGllbnRZKSAvIDI7XG5cbiAgICAvLyBDcmVhdGUgcm90YXRlIGV2ZW50XG4gICAgY29uc3Qgcm90YXRlRXZlbnQ6IFJvdGF0ZUV2ZW50ID0ge1xuICAgICAgLi4uY3JlYXRlR2VzdHVyZUV2ZW50KFwicm90YXRlXCIsIG9yaWdpbmFsRXZlbnQsIHN0YXRlKSxcbiAgICAgIHR5cGU6IFwicm90YXRlXCIsXG4gICAgICByb3RhdGlvbjogcm90YXRpb25EaWZmLFxuICAgICAgY2VudGVyWCxcbiAgICAgIGNlbnRlclksXG4gICAgfTtcblxuICAgIHJldHVybiByb3RhdGVFdmVudDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuIiwKICAgICIvLyBzcmMvY29yZS9nZXN0dXJlcy9tYW5hZ2VyLnRzXG4vKipcbiAqIEBtb2R1bGUgY29yZS9nZXN0dXJlc1xuICogQGRlc2NyaXB0aW9uIEdlc3R1cmUgbWFuYWdlbWVudCBzeXN0ZW0gZm9yIGhhbmRsaW5nIHRvdWNoIGFuZCBtb3VzZSBpbnRlcmFjdGlvbnNcbiAqL1xuXG5pbXBvcnQgeyBcbiAgR2VzdHVyZUNvbmZpZyxcbiAgR2VzdHVyZU1hbmFnZXIsXG4gIEdlc3R1cmVTdGF0ZSxcbiAgR2VzdHVyZUhhbmRsZXIsXG4gIEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0LFxuICBBbnlHZXN0dXJlRXZlbnQsXG4gIEdFU1RVUkVfVFlQRVMsXG4gIFNXSVBFX0RJUkVDVElPTlNcbn0gZnJvbSAnLi90eXBlcyc7XG5cbmltcG9ydCB7IGRldGVjdFRhcCB9IGZyb20gJy4vdGFwJztcbmltcG9ydCB7IGRldGVjdFN3aXBlIH0gZnJvbSAnLi9zd2lwZSc7XG5pbXBvcnQgeyBkZXRlY3RMb25nUHJlc3MsIHNob3VsZENhbmNlbExvbmdQcmVzcyB9IGZyb20gJy4vbG9uZ3ByZXNzJztcbmltcG9ydCB7IGRldGVjdFBhbiB9IGZyb20gJy4vcGFuJztcbmltcG9ydCB7IGRldGVjdFBpbmNoIH0gZnJvbSAnLi9waW5jaCc7XG5pbXBvcnQgeyBkZXRlY3RSb3RhdGUgfSBmcm9tICcuL3JvdGF0ZSc7XG5pbXBvcnQgeyBoYXNUb3VjaFN1cHBvcnQsIGhhc1BvaW50ZXJTdXBwb3J0LCBnZXRUb3VjaENvb3JkaW5hdGVzIH0gZnJvbSAnLi91dGlscyc7XG5cbi8vIFJlLWV4cG9ydCB0eXBlcyBhbmQgY29uc3RhbnRzXG5leHBvcnQgeyBHRVNUVVJFX1RZUEVTLCBTV0lQRV9ESVJFQ1RJT05TIH07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGdlc3R1cmUgbWFuYWdlciBmb3IgaGFuZGxpbmcgdG91Y2ggYW5kIG1vdXNlIGludGVyYWN0aW9uc1xuICogXG4gKiBAcGFyYW0gZWxlbWVudCAtIERPTSBlbGVtZW50IHRvIGF0dGFjaCBnZXN0dXJlIHJlY29nbml0aW9uIHRvXG4gKiBAcGFyYW0gY29uZmlnIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zXG4gKiBAcmV0dXJucyBHZXN0dXJlIG1hbmFnZXIgaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUdlc3R1cmVNYW5hZ2VyID0gKFxuICBlbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgY29uZmlnOiBHZXN0dXJlQ29uZmlnID0ge31cbik6IEdlc3R1cmVNYW5hZ2VyID0+IHtcbiAgLy8gRGVmYXVsdCBjb25maWd1cmF0aW9uXG4gIGNvbnN0IG9wdGlvbnM6IFJlcXVpcmVkPEdlc3R1cmVDb25maWc+ID0ge1xuICAgIHN3aXBlVGhyZXNob2xkOiAzMCxcbiAgICBzd2lwZVRpbWVUaHJlc2hvbGQ6IDMwMCxcbiAgICBsb25nUHJlc3NUaW1lOiA1MDAsXG4gICAgdGFwRGlzdGFuY2VUaHJlc2hvbGQ6IDEwLFxuICAgIHByZXZlbnREZWZhdWx0OiB0cnVlLFxuICAgIHN0b3BQcm9wYWdhdGlvbjogZmFsc2UsXG4gICAgLi4uY29uZmlnXG4gIH07XG4gIFxuICAvLyBFdmVudCBoYW5kbGVycyBzdG9yYWdlXG4gIGNvbnN0IGhhbmRsZXJzOiBNYXA8c3RyaW5nLCBTZXQ8R2VzdHVyZUhhbmRsZXI+PiA9IG5ldyBNYXAoKTtcbiAgXG4gIC8vIEdlc3R1cmUgc3RhdGVcbiAgY29uc3Qgc3RhdGU6IEdlc3R1cmVTdGF0ZSA9IHtcbiAgICBhY3RpdmU6IGZhbHNlLFxuICAgIHN0YXJ0VGltZTogMCxcbiAgICBzdGFydFg6IDAsXG4gICAgc3RhcnRZOiAwLFxuICAgIGxhc3RYOiAwLFxuICAgIGxhc3RZOiAwLFxuICAgIGN1cnJlbnRYOiAwLFxuICAgIGN1cnJlbnRZOiAwLFxuICAgIHRvdWNoQ291bnQ6IDAsXG4gICAgbG9uZ1ByZXNzVGltZXI6IG51bGwsXG4gICAgc3RhcnREaXN0YW5jZTogMCxcbiAgICBzdGFydEFuZ2xlOiAwLFxuICAgIGxhc3RUYXBUaW1lOiAwLFxuICAgIHRhcENvdW50OiAwLFxuICAgIHRhcmdldDogbnVsbFxuICB9O1xuICBcbiAgLy8gRGV0ZWN0IGZlYXR1cmUgc3VwcG9ydFxuICBjb25zdCBzdXBwb3J0VG91Y2ggPSBoYXNUb3VjaFN1cHBvcnQoKTtcbiAgY29uc3Qgc3VwcG9ydFBvaW50ZXIgPSBoYXNQb2ludGVyU3VwcG9ydCgpO1xuICAgIFxuICBjb25zdCBnZXN0dXJlU3VwcG9ydCA9IHtcbiAgICB0YXA6IHRydWUsXG4gICAgc3dpcGU6IHRydWUsXG4gICAgc3dpcGVsZWZ0OiB0cnVlLFxuICAgIHN3aXBlcmlnaHQ6IHRydWUsXG4gICAgc3dpcGV1cDogdHJ1ZSxcbiAgICBzd2lwZWRvd246IHRydWUsXG4gICAgbG9uZ3ByZXNzOiB0cnVlLFxuICAgIHBhbjogdHJ1ZSxcbiAgICBwaW5jaDogc3VwcG9ydFRvdWNoIHx8IHN1cHBvcnRQb2ludGVyLFxuICAgIHJvdGF0ZTogc3VwcG9ydFRvdWNoIHx8IHN1cHBvcnRQb2ludGVyXG4gIH07XG4gIFxuICAvKipcbiAgICogRGlzcGF0Y2ggYSBnZXN0dXJlIGV2ZW50XG4gICAqL1xuICBjb25zdCBkaXNwYXRjaEdlc3R1cmUgPSAoZXZlbnQ6IEFueUdlc3R1cmVFdmVudCk6IHZvaWQgPT4ge1xuICAgIC8vIEdldCBoYW5kbGVycyBmb3IgdGhpcyBldmVudCB0eXBlXG4gICAgY29uc3QgZXZlbnRIYW5kbGVycyA9IGhhbmRsZXJzLmdldChldmVudC50eXBlKTtcbiAgICBpZiAoIWV2ZW50SGFuZGxlcnMpIHJldHVybjtcbiAgICBcbiAgICAvLyBDYWxsIGVhY2ggaGFuZGxlclxuICAgIGV2ZW50SGFuZGxlcnMuZm9yRWFjaChoYW5kbGVyID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgaW4gZ2VzdHVyZSBoYW5kbGVyIGZvciAke2V2ZW50LnR5cGV9OmAsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICAvLyBGb3Igc3dpcGUsIGFsc28gZGlzcGF0Y2ggZGlyZWN0aW9uLXNwZWNpZmljIGV2ZW50c1xuICAgIGlmIChldmVudC50eXBlID09PSAnc3dpcGUnICYmICdkaXJlY3Rpb24nIGluIGV2ZW50KSB7XG4gICAgICBjb25zdCBkaXJlY3Rpb25FdmVudCA9IHsgLi4uZXZlbnQsIHR5cGU6IGBzd2lwZSR7ZXZlbnQuZGlyZWN0aW9ufWAgYXMgYW55IH07XG4gICAgICBkaXNwYXRjaEdlc3R1cmUoZGlyZWN0aW9uRXZlbnQgYXMgYW55KTtcbiAgICB9XG4gICAgXG4gICAgLy8gQXBwbHkgZGVmYXVsdCBjb25maWd1cmF0aW9uIGZvciBwcmV2ZW50RGVmYXVsdCBhbmQgc3RvcFByb3BhZ2F0aW9uXG4gICAgaWYgKG9wdGlvbnMucHJldmVudERlZmF1bHQgJiYgIWV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIFxuICAgIGlmIChvcHRpb25zLnN0b3BQcm9wYWdhdGlvbikge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuICB9O1xuICBcbiAgLy8gUmVmZXJlbmNlIHRvIHRoZSBsb25ncHJlc3MgY2xlYW51cCBmdW5jdGlvblxuICBsZXQgbG9uZ1ByZXNzQ2xlYW51cDogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gIFxuICAvKipcbiAgICogSGFuZGxlIHRvdWNoL21vdXNlIHN0YXJ0XG4gICAqL1xuICBjb25zdCBoYW5kbGVTdGFydCA9IChlOiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCB8IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHRvdWNoID0gZ2V0VG91Y2hDb29yZGluYXRlcyhlKTtcbiAgICBjb25zdCB0b3VjaENvdW50ID0gJ3RvdWNoZXMnIGluIGUgPyBlLnRvdWNoZXMubGVuZ3RoIDogMTtcbiAgICBcbiAgICAvLyBTdG9yZSBnZXN0dXJlIHN0YXRlXG4gICAgc3RhdGUuYWN0aXZlID0gdHJ1ZTtcbiAgICBzdGF0ZS5zdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHN0YXRlLnN0YXJ0WCA9IHN0YXRlLmxhc3RYID0gc3RhdGUuY3VycmVudFggPSB0b3VjaC5jbGllbnRYO1xuICAgIHN0YXRlLnN0YXJ0WSA9IHN0YXRlLmxhc3RZID0gc3RhdGUuY3VycmVudFkgPSB0b3VjaC5jbGllbnRZO1xuICAgIHN0YXRlLnRvdWNoQ291bnQgPSB0b3VjaENvdW50O1xuICAgIHN0YXRlLnRhcmdldCA9IGUudGFyZ2V0O1xuICAgIFxuICAgIC8vIEhhbmRsZSBtdWx0aS10b3VjaCBnZXN0dXJlc1xuICAgIGlmICh0b3VjaENvdW50ID09PSAyICYmICd0b3VjaGVzJyBpbiBlKSB7XG4gICAgICBjb25zdCB0b3VjaDEgPSBlLnRvdWNoZXNbMF07XG4gICAgICBjb25zdCB0b3VjaDIgPSBlLnRvdWNoZXNbMV07XG4gICAgICBcbiAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlcyBmb3IgcGluY2ggYW5kIHJvdGF0ZVxuICAgICAgc3RhdGUuc3RhcnREaXN0YW5jZSA9IE1hdGguc3FydChcbiAgICAgICAgTWF0aC5wb3codG91Y2gyLmNsaWVudFggLSB0b3VjaDEuY2xpZW50WCwgMikgKyBcbiAgICAgICAgTWF0aC5wb3codG91Y2gyLmNsaWVudFkgLSB0b3VjaDEuY2xpZW50WSwgMilcbiAgICAgICk7XG4gICAgICBcbiAgICAgIHN0YXRlLnN0YXJ0QW5nbGUgPSBNYXRoLmF0YW4yKFxuICAgICAgICB0b3VjaDIuY2xpZW50WSAtIHRvdWNoMS5jbGllbnRZLFxuICAgICAgICB0b3VjaDIuY2xpZW50WCAtIHRvdWNoMS5jbGllbnRYXG4gICAgICApICogMTgwIC8gTWF0aC5QSTtcbiAgICAgIFxuICAgICAgaWYgKHN0YXRlLnN0YXJ0QW5nbGUgPCAwKSBzdGF0ZS5zdGFydEFuZ2xlICs9IDM2MDtcbiAgICB9XG4gICAgXG4gICAgLy8gU2V0dXAgY29udGV4dCBmb3IgZ2VzdHVyZSBkZXRlY3Rpb25cbiAgICBjb25zdCBjb250ZXh0OiBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCA9IHtcbiAgICAgIHN0YXRlLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIG9yaWdpbmFsRXZlbnQ6IGVcbiAgICB9O1xuICAgIFxuICAgIC8vIFN0YXJ0IGxvbmcgcHJlc3MgZGV0ZWN0aW9uXG4gICAgaWYgKGxvbmdQcmVzc0NsZWFudXApIHtcbiAgICAgIGxvbmdQcmVzc0NsZWFudXAoKTtcbiAgICB9XG4gICAgXG4gICAgbG9uZ1ByZXNzQ2xlYW51cCA9IGRldGVjdExvbmdQcmVzcyhjb250ZXh0LCAobG9uZ1ByZXNzRXZlbnQpID0+IHtcbiAgICAgIGRpc3BhdGNoR2VzdHVyZShsb25nUHJlc3NFdmVudCk7XG4gICAgfSk7XG4gIH07XG4gIFxuICAvKipcbiAgICogSGFuZGxlIHRvdWNoL21vdXNlIG1vdmVcbiAgICovXG4gIGNvbnN0IGhhbmRsZU1vdmUgPSAoZTogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQgfCBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAoIXN0YXRlLmFjdGl2ZSkgcmV0dXJuO1xuICAgIFxuICAgIGNvbnN0IHRvdWNoID0gZ2V0VG91Y2hDb29yZGluYXRlcyhlKTtcbiAgICBjb25zdCB0b3VjaENvdW50ID0gJ3RvdWNoZXMnIGluIGUgPyBlLnRvdWNoZXMubGVuZ3RoIDogMTtcbiAgICBcbiAgICAvLyBVcGRhdGUgcG9zaXRpb25zXG4gICAgc3RhdGUubGFzdFggPSBzdGF0ZS5jdXJyZW50WDtcbiAgICBzdGF0ZS5sYXN0WSA9IHN0YXRlLmN1cnJlbnRZO1xuICAgIHN0YXRlLmN1cnJlbnRYID0gdG91Y2guY2xpZW50WDtcbiAgICBzdGF0ZS5jdXJyZW50WSA9IHRvdWNoLmNsaWVudFk7XG4gICAgXG4gICAgLy8gU2V0dXAgY29udGV4dCBmb3IgZ2VzdHVyZSBkZXRlY3Rpb25cbiAgICBjb25zdCBjb250ZXh0OiBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCA9IHtcbiAgICAgIHN0YXRlLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIG9yaWdpbmFsRXZlbnQ6IGVcbiAgICB9O1xuICAgIFxuICAgIC8vIENoZWNrIGlmIHdlIHNob3VsZCBjYW5jZWwgbG9uZ3ByZXNzXG4gICAgaWYgKHNob3VsZENhbmNlbExvbmdQcmVzcyhjb250ZXh0KSAmJiBsb25nUHJlc3NDbGVhbnVwKSB7XG4gICAgICBsb25nUHJlc3NDbGVhbnVwKCk7XG4gICAgICBsb25nUHJlc3NDbGVhbnVwID0gbnVsbDtcbiAgICB9XG4gICAgXG4gICAgLy8gRGV0ZWN0IHBhbiBnZXN0dXJlXG4gICAgY29uc3QgcGFuRXZlbnQgPSBkZXRlY3RQYW4oY29udGV4dCk7XG4gICAgaWYgKHBhbkV2ZW50KSB7XG4gICAgICBkaXNwYXRjaEdlc3R1cmUocGFuRXZlbnQpO1xuICAgIH1cbiAgICBcbiAgICAvLyBNdWx0aS10b3VjaCBnZXN0dXJlc1xuICAgIGlmICh0b3VjaENvdW50ID09PSAyICYmICd0b3VjaGVzJyBpbiBlKSB7XG4gICAgICBjb25zdCB0b3VjaDEgPSBlLnRvdWNoZXNbMF07XG4gICAgICBjb25zdCB0b3VjaDIgPSBlLnRvdWNoZXNbMV07XG4gICAgICBcbiAgICAgIC8vIERldGVjdCBwaW5jaFxuICAgICAgY29uc3QgcGluY2hFdmVudCA9IGRldGVjdFBpbmNoKGNvbnRleHQsIHRvdWNoMSwgdG91Y2gyKTtcbiAgICAgIGlmIChwaW5jaEV2ZW50KSB7XG4gICAgICAgIGRpc3BhdGNoR2VzdHVyZShwaW5jaEV2ZW50KTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gRGV0ZWN0IHJvdGF0ZVxuICAgICAgY29uc3Qgcm90YXRlRXZlbnQgPSBkZXRlY3RSb3RhdGUoY29udGV4dCwgdG91Y2gxLCB0b3VjaDIpO1xuICAgICAgaWYgKHJvdGF0ZUV2ZW50KSB7XG4gICAgICAgIGRpc3BhdGNoR2VzdHVyZShyb3RhdGVFdmVudCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICBcbiAgLyoqXG4gICAqIEhhbmRsZSB0b3VjaC9tb3VzZSBlbmRcbiAgICovXG4gIGNvbnN0IGhhbmRsZUVuZCA9IChlOiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCB8IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGlmICghc3RhdGUuYWN0aXZlKSByZXR1cm47XG4gICAgXG4gICAgLy8gQ2FuY2VsIGFueSBvbmdvaW5nIGxvbmcgcHJlc3MgZGV0ZWN0aW9uXG4gICAgaWYgKGxvbmdQcmVzc0NsZWFudXApIHtcbiAgICAgIGxvbmdQcmVzc0NsZWFudXAoKTtcbiAgICAgIGxvbmdQcmVzc0NsZWFudXAgPSBudWxsO1xuICAgIH1cbiAgICBcbiAgICAvLyBTZXR1cCBjb250ZXh0IGZvciBnZXN0dXJlIGRldGVjdGlvblxuICAgIGNvbnN0IGNvbnRleHQ6IEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0ID0ge1xuICAgICAgc3RhdGUsXG4gICAgICBvcHRpb25zLFxuICAgICAgb3JpZ2luYWxFdmVudDogZVxuICAgIH07XG4gICAgXG4gICAgLy8gRGV0ZWN0IHRhcFxuICAgIGNvbnN0IHRhcEV2ZW50ID0gZGV0ZWN0VGFwKGNvbnRleHQpO1xuICAgIGlmICh0YXBFdmVudCkge1xuICAgICAgLy8gVXBkYXRlIHRhcCBjb3VudCBmb3IgbmV4dCB0YXBcbiAgICAgIHN0YXRlLmxhc3RUYXBUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgIHN0YXRlLnRhcENvdW50ID0gdGFwRXZlbnQuY291bnQ7XG4gICAgICBcbiAgICAgIGRpc3BhdGNoR2VzdHVyZSh0YXBFdmVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERldGVjdCBzd2lwZVxuICAgICAgY29uc3Qgc3dpcGVFdmVudCA9IGRldGVjdFN3aXBlKGNvbnRleHQpO1xuICAgICAgaWYgKHN3aXBlRXZlbnQpIHtcbiAgICAgICAgZGlzcGF0Y2hHZXN0dXJlKHN3aXBlRXZlbnQpO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBSZXNldCBzdGF0ZVxuICAgIHN0YXRlLmFjdGl2ZSA9IGZhbHNlO1xuICB9O1xuICBcbiAgLyoqXG4gICAqIEhhbmRsZSB0b3VjaC9tb3VzZSBjYW5jZWxcbiAgICovXG4gIGNvbnN0IGhhbmRsZUNhbmNlbCA9ICgpOiB2b2lkID0+IHtcbiAgICAvLyBDYW5jZWwgbG9uZyBwcmVzcyBkZXRlY3Rpb25cbiAgICBpZiAobG9uZ1ByZXNzQ2xlYW51cCkge1xuICAgICAgbG9uZ1ByZXNzQ2xlYW51cCgpO1xuICAgICAgbG9uZ1ByZXNzQ2xlYW51cCA9IG51bGw7XG4gICAgfVxuICAgIFxuICAgIC8vIFJlc2V0IHN0YXRlXG4gICAgc3RhdGUuYWN0aXZlID0gZmFsc2U7XG4gIH07XG4gIFxuICAvLyBFdmVudCBsaXN0ZW5lciByZWZlcmVuY2VzXG4gIGxldCBldmVudExpc3RlbmVyczogeyBcbiAgICBbZXZlbnQ6IHN0cmluZ106IEV2ZW50TGlzdGVuZXIgXG4gIH0gPSB7fTtcbiAgXG4gIC8qKlxuICAgKiBTZXQgdXAgZXZlbnQgbGlzdGVuZXJzIGJhc2VkIG9uIGF2YWlsYWJsZSBBUElzXG4gICAqL1xuICBjb25zdCBzZXR1cEV2ZW50TGlzdGVuZXJzID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmIChzdXBwb3J0UG9pbnRlcikge1xuICAgICAgLy8gVXNlIFBvaW50ZXIgRXZlbnRzIEFQSVxuICAgICAgZXZlbnRMaXN0ZW5lcnMgPSB7XG4gICAgICAgIHBvaW50ZXJkb3duOiBoYW5kbGVTdGFydCBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICBwb2ludGVybW92ZTogaGFuZGxlTW92ZSBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICBwb2ludGVydXA6IGhhbmRsZUVuZCBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICBwb2ludGVyY2FuY2VsOiBoYW5kbGVDYW5jZWwgYXMgRXZlbnRMaXN0ZW5lclxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHN1cHBvcnRUb3VjaCkge1xuICAgICAgLy8gVXNlIFRvdWNoIEV2ZW50cyBBUElcbiAgICAgIGV2ZW50TGlzdGVuZXJzID0ge1xuICAgICAgICB0b3VjaHN0YXJ0OiBoYW5kbGVTdGFydCBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICB0b3VjaG1vdmU6IGhhbmRsZU1vdmUgYXMgRXZlbnRMaXN0ZW5lcixcbiAgICAgICAgdG91Y2hlbmQ6IGhhbmRsZUVuZCBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICB0b3VjaGNhbmNlbDogaGFuZGxlQ2FuY2VsIGFzIEV2ZW50TGlzdGVuZXJcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZhbGwgYmFjayB0byBNb3VzZSBFdmVudHMgQVBJXG4gICAgICBldmVudExpc3RlbmVycyA9IHtcbiAgICAgICAgbW91c2Vkb3duOiBoYW5kbGVTdGFydCBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICBtb3VzZW1vdmU6IGhhbmRsZU1vdmUgYXMgRXZlbnRMaXN0ZW5lcixcbiAgICAgICAgbW91c2V1cDogaGFuZGxlRW5kIGFzIEV2ZW50TGlzdGVuZXIsXG4gICAgICAgIG1vdXNlbGVhdmU6IGhhbmRsZUNhbmNlbCBhcyBFdmVudExpc3RlbmVyXG4gICAgICB9O1xuICAgIH1cbiAgICBcbiAgICAvLyBBZGQgbGlzdGVuZXJzIHRvIGVsZW1lbnRcbiAgICBPYmplY3QuZW50cmllcyhldmVudExpc3RlbmVycykuZm9yRWFjaCgoW2V2ZW50LCBsaXN0ZW5lcl0pID0+IHtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIHsgcGFzc2l2ZTogIW9wdGlvbnMucHJldmVudERlZmF1bHQgfSk7XG4gICAgfSk7XG4gIH07XG4gIFxuICAvKipcbiAgICogUmVtb3ZlIGFsbCBldmVudCBsaXN0ZW5lcnNcbiAgICovXG4gIGNvbnN0IHJlbW92ZUV2ZW50TGlzdGVuZXJzID0gKCk6IHZvaWQgPT4ge1xuICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGZyb20gZWxlbWVudFxuICAgIE9iamVjdC5lbnRyaWVzKGV2ZW50TGlzdGVuZXJzKS5mb3JFYWNoKChbZXZlbnQsIGxpc3RlbmVyXSkgPT4ge1xuICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7XG4gICAgfSk7XG4gICAgXG4gICAgLy8gQ2xlYXIgZXZlbnRMaXN0ZW5lcnMgb2JqZWN0XG4gICAgZXZlbnRMaXN0ZW5lcnMgPSB7fTtcbiAgfTtcbiAgXG4gIC8vIEluaXRpYWxpemUgZXZlbnQgbGlzdGVuZXJzXG4gIHNldHVwRXZlbnRMaXN0ZW5lcnMoKTtcbiAgXG4gIHJldHVybiB7XG4gICAgLyoqXG4gICAgICogQWRkIGEgZ2VzdHVyZSBldmVudCBsaXN0ZW5lclxuICAgICAqIEBwYXJhbSBldmVudFR5cGUgLSBUeXBlIG9mIGdlc3R1cmUgdG8gbGlzdGVuIGZvclxuICAgICAqIEBwYXJhbSBoYW5kbGVyIC0gRXZlbnQgaGFuZGxlciBmdW5jdGlvblxuICAgICAqIEByZXR1cm5zIEdlc3R1cmUgbWFuYWdlciBmb3IgY2hhaW5pbmdcbiAgICAgKi9cbiAgICBvbihldmVudFR5cGU6IHN0cmluZywgaGFuZGxlcjogR2VzdHVyZUhhbmRsZXIpOiBHZXN0dXJlTWFuYWdlciB7XG4gICAgICBpZiAoIWhhbmRsZXJzLmhhcyhldmVudFR5cGUpKSB7XG4gICAgICAgIGhhbmRsZXJzLnNldChldmVudFR5cGUsIG5ldyBTZXQoKSk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGhhbmRsZXJzLmdldChldmVudFR5cGUpIS5hZGQoaGFuZGxlcik7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIFxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIGdlc3R1cmUgZXZlbnQgbGlzdGVuZXJcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIC0gVHlwZSBvZiBnZXN0dXJlXG4gICAgICogQHBhcmFtIGhhbmRsZXIgLSBFdmVudCBoYW5kbGVyIHRvIHJlbW92ZVxuICAgICAqIEByZXR1cm5zIEdlc3R1cmUgbWFuYWdlciBmb3IgY2hhaW5pbmdcbiAgICAgKi9cbiAgICBvZmYoZXZlbnRUeXBlOiBzdHJpbmcsIGhhbmRsZXI6IEdlc3R1cmVIYW5kbGVyKTogR2VzdHVyZU1hbmFnZXIge1xuICAgICAgY29uc3QgZXZlbnRIYW5kbGVycyA9IGhhbmRsZXJzLmdldChldmVudFR5cGUpO1xuICAgICAgaWYgKGV2ZW50SGFuZGxlcnMpIHtcbiAgICAgICAgZXZlbnRIYW5kbGVycy5kZWxldGUoaGFuZGxlcik7XG4gICAgICAgIFxuICAgICAgICBpZiAoZXZlbnRIYW5kbGVycy5zaXplID09PSAwKSB7XG4gICAgICAgICAgaGFuZGxlcnMuZGVsZXRlKGV2ZW50VHlwZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgYSBnZXN0dXJlIGlzIHN1cHBvcnRlZCBvbiB0aGUgY3VycmVudCBkZXZpY2VcbiAgICAgKiBAcGFyYW0gZ2VzdHVyZVR5cGUgLSBUeXBlIG9mIGdlc3R1cmUgdG8gY2hlY2tcbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBnZXN0dXJlIGlzIHN1cHBvcnRlZFxuICAgICAqL1xuICAgIGlzU3VwcG9ydGVkKGdlc3R1cmVUeXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiBnZXN0dXJlVHlwZSBpbiBnZXN0dXJlU3VwcG9ydCAmJiBnZXN0dXJlU3VwcG9ydFtnZXN0dXJlVHlwZSBhcyBrZXlvZiB0eXBlb2YgZ2VzdHVyZVN1cHBvcnRdO1xuICAgIH0sXG4gICAgXG4gICAgLyoqXG4gICAgICogRW5hYmxlIGdlc3R1cmUgcmVjb2duaXRpb24gYnkgYWRkaW5nIGV2ZW50IGxpc3RlbmVyc1xuICAgICAqIEByZXR1cm5zIEdlc3R1cmUgbWFuYWdlciBmb3IgY2hhaW5pbmdcbiAgICAgKi9cbiAgICBlbmFibGUoKTogR2VzdHVyZU1hbmFnZXIge1xuICAgICAgc2V0dXBFdmVudExpc3RlbmVycygpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBcbiAgICAvKipcbiAgICAgKiBEaXNhYmxlIGdlc3R1cmUgcmVjb2duaXRpb24gYnkgcmVtb3ZpbmcgZXZlbnQgbGlzdGVuZXJzXG4gICAgICogQHJldHVybnMgR2VzdHVyZSBtYW5hZ2VyIGZvciBjaGFpbmluZ1xuICAgICAqL1xuICAgIGRpc2FibGUoKTogR2VzdHVyZU1hbmFnZXIge1xuICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgXG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAgZXZlbnQgbGlzdGVuZXJzIGFuZCB0aW1lcnNcbiAgICAgKi9cbiAgICBkZXN0cm95KCk6IHZvaWQge1xuICAgICAgLy8gQ2xlYW4gdXAgbGlzdGVuZXJzXG4gICAgICByZW1vdmVFdmVudExpc3RlbmVycygpO1xuICAgICAgXG4gICAgICAvLyBDbGVhciBsb25nIHByZXNzIHRpbWVyXG4gICAgICBpZiAobG9uZ1ByZXNzQ2xlYW51cCkge1xuICAgICAgICBsb25nUHJlc3NDbGVhbnVwKCk7XG4gICAgICAgIGxvbmdQcmVzc0NsZWFudXAgPSBudWxsO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBDbGVhciBoYW5kbGVyIHJlZmVyZW5jZXNcbiAgICAgIGhhbmRsZXJzLmNsZWFyKCk7XG4gICAgfVxuICB9O1xufTsiCiAgXSwKICAibWFwcGluZ3MiOiAiO0FBU08sSUFBSztBQUFBLENBQUwsQ0FBSyxtQkFBTDtBQUFBLEVBQ0wsd0JBQU07QUFBQSxFQUNOLDBCQUFRO0FBQUEsRUFDUiwrQkFBYTtBQUFBLEVBQ2IsZ0NBQWM7QUFBQSxFQUNkLDZCQUFXO0FBQUEsRUFDWCwrQkFBYTtBQUFBLEVBQ2IsMEJBQVE7QUFBQSxFQUNSLDJCQUFTO0FBQUEsRUFDVCwrQkFBYTtBQUFBLEVBQ2Isd0JBQU07QUFBQSxHQVZJO0FBZ0JMLElBQUs7QUFBQSxDQUFMLENBQUssc0JBQUw7QUFBQSxFQUNMLDBCQUFLO0FBQUEsRUFDTCw0QkFBTztBQUFBLEVBQ1AsNEJBQU87QUFBQSxFQUNQLDZCQUFRO0FBQUEsR0FKRTs7O0FDUkwsU0FBUyxXQUFXLENBQ3pCLElBQ0EsSUFDQSxJQUNBLElBQ1E7QUFBQSxFQUNSLE9BQU8sS0FBSyxLQUFLLEtBQUssSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxLQUFLLElBQUksQ0FBQyxDQUFDO0FBQUE7QUFZdkQsU0FBUyxRQUFRLENBQ3RCLElBQ0EsSUFDQSxJQUNBLElBQ1E7QUFBQSxFQUNSLE1BQU0sUUFB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QUNGLEVBQU8sU0FBSSxjQUFjO0FBQUEsTUFFdkIsaUJBQWlCO0FBQUEsUUFDZixZQUFZO0FBQUEsUUFDWixXQUFXO0FBQUEsUUFDWCxVQUFVO0FBQUEsUUFDVixhQUFhO0FBQUEsTUFDZjtBQUFBLElBQ0YsRUFBTztBQUFBLE1BRUwsaUJBQWlCO0FBQUEsUUFDZixXQUFXO0FBQUEsUUFDWCxXQUFXO0FBQUEsUUFDWCxTQUFTO0FBQUEsUUFDVCxZQUFZO0FBQUEsTUFDZDtBQUFBO0FBQUEsSUFJRixPQUFPLFFBQVEsY0FBYyxFQUFFLFFBQVEsRUFBRSxPQUFPLGNBQWM7QUFBQSxNQUM1RCxRQUFRLGlCQUFpQixPQUFPLFVBQVUsRUFBRSxTQUFTLENBQUMsUUFBUSxlQUFlLENBQUM7QUFBQSxLQUMvRTtBQUFBO0FBQUEsRUFNSCxNQUFNLHVCQUF1QixNQUFZO0FBQUEsSUFFdkMsT0FBTyxRQUFRLGNBQWMsRUFBRSxRQUFRLEVBQUUsT0FBTyxjQUFjO0FBQUEsTUFDNUQsUUFBUSxvQkFBb0IsT0FBTyxRQUFRO0FBQUEsS0FDNUM7QUFBQSxJQUdELGlCQUFpQixDQUFDO0FBQUE7QUFBQSxFQUlwQixvQkFBb0I7QUFBQSxFQUVwQixPQUFPO0FBQUEsSUFPTCxFQUFFLENBQUMsV0FBbUIsU0FBeUM7QUFBQSxNQUM3RCxJQUFJLENBQUMsU0FBUyxJQUFJLFNBQVMsR0FBRztBQUFBLFFBQzVCLFNBQVMsSUFBSSxXQUFXLElBQUksR0FBSztBQUFBLE1BQ25DO0FBQUEsTUFFQSxTQUFTLElBQUksU0FBUyxFQUFHLElBQUksT0FBTztBQUFBLE1BQ3BDLE9BQU87QUFBQTtBQUFBLElBU1QsR0FBRyxDQUFDLFdBQW1CLFNBQXlDO0FBQUEsTUFDOUQsTUFBTSxnQkFBZ0IsU0FBUyxJQUFJLFNBQVM7QUFBQSxNQUM1QyxJQUFJLGVBQWU7QUFBQSxRQUNqQixjQUFjLE9BQU8sT0FBTztBQUFBLFFBRTVCLElBQUksY0FBYyxTQUFTLEdBQUc7QUFBQSxVQUM1QixTQUFTLE9BQU8sU0FBUztBQUFBLFFBQzNCO0FBQUEsTUFDRjtBQUFBLE1BQ0EsT0FBTztBQUFBO0FBQUEsSUFRVCxXQUFXLENBQUMsYUFBOEI7QUFBQSxNQUN4QyxPQUFPLGVBQWUsa0JBQWtCLGVBQWU7QUFBQTtBQUFBLElBT3pELE1BQU0sR0FBbUI7QUFBQSxNQUN2QixvQkFBb0I7QUFBQSxNQUNwQixPQUFPO0FBQUE7QUFBQSxJQU9ULE9BQU8sR0FBbUI7QUFBQSxNQUN4QixxQkFBcUI7QUFBQSxNQUNyQixPQUFPO0FBQUE7QUFBQSxJQU1ULE9BQU8sR0FBUztBQUFBLE1BRWQscUJBQXFCO0FBQUEsTUFHckIsSUFBSSxrQkFBa0I7QUFBQSxRQUNwQixpQkFBaUI7QUFBQSxRQUNqQixtQkFBbUI7QUFBQSxNQUNyQjtBQUFBLE1BR0EsU0FBUyxNQUFNO0FBQUE7QUFBQSxFQUVuQjtBQUFBOyIsCiAgImRlYnVnSWQiOiAiMkI0MEJCQzI0MDBDRjk1MzY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=