@media-quest/engine 0.0.14 → 0.0.15

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 (60) hide show
  1. package/package.json +1 -2
  2. package/src/Delement/DElement.dto.ts +5 -0
  3. package/src/Delement/DElement.ts +78 -253
  4. package/src/Delement/DImg.ts +31 -70
  5. package/src/Delement/DStyle.ts +156 -156
  6. package/src/Delement/DText.ts +9 -25
  7. package/src/Delement/Ddiv.ts +10 -23
  8. package/src/Delement/button-click-action.ts +11 -0
  9. package/src/Delement/element-factory.ts +40 -0
  10. package/src/engine/DCommand.ts +21 -0
  11. package/src/engine/SchemaDto.ts +24 -0
  12. package/src/engine/SchemaEngine.ts +48 -120
  13. package/src/{player → engine}/dplayer.spec.ts +20 -17
  14. package/src/{player → engine}/dplayer.ts +29 -16
  15. package/src/engine/history-que.spec.ts +59 -0
  16. package/src/engine/history-que.ts +39 -0
  17. package/src/{player → engine}/next-que.spec.ts +19 -8
  18. package/src/engine/next-que.ts +93 -0
  19. package/src/page/Page.ts +160 -0
  20. package/src/page/media-player.ts +117 -0
  21. package/src/page/page-component.ts +113 -0
  22. package/src/page/page-result.ts +11 -0
  23. package/src/page/task-manager.ts +203 -0
  24. package/src/page/task-state.ts +55 -0
  25. package/src/page/task.ts +87 -0
  26. package/src/public-api.ts +17 -13
  27. package/src/rules/__test__/rule-engine.spec.ts +1 -1
  28. package/src/utils/DUtil.ts +110 -103
  29. package/tsconfig.tsbuildinfo +1 -0
  30. package/dist/public-api.js +0 -2245
  31. package/dist/public-api.mjs +0 -2205
  32. package/src/Delement/AudioContainer.ts +0 -169
  33. package/src/Delement/DAuto-play.ts +0 -36
  34. package/src/Delement/VideoContainer.ts +0 -199
  35. package/src/commands/DCommand.ts +0 -63
  36. package/src/commands/DCommandBus.ts +0 -60
  37. package/src/dto/AnimationDto.ts +0 -4
  38. package/src/dto/DElement.dto.ts +0 -46
  39. package/src/dto/SchemaDto.ts +0 -65
  40. package/src/engine/DPage.ts +0 -60
  41. package/src/engine/element-factory.ts +0 -52
  42. package/src/event-handlers/DEventHandler.ts +0 -29
  43. package/src/events/DEvents.ts +0 -94
  44. package/src/events/event-bus.spec.ts +0 -21
  45. package/src/events/event-bus.ts +0 -81
  46. package/src/kladd/context-menu-manager.ts +0 -56
  47. package/src/player/history-que.spec.ts +0 -46
  48. package/src/player/history-que.ts +0 -38
  49. package/src/player/next-que.ts +0 -93
  50. package/src/services/DMedia-manager.spec.ts +0 -27
  51. package/src/services/DMedia-manager.ts +0 -179
  52. package/src/services/resource-provider.ts +0 -33
  53. package/src/services/sequence-manager.spec.ts +0 -168
  54. package/src/services/sequence-manager.ts +0 -133
  55. package/src/state/Dstate.spec.ts +0 -7
  56. package/src/state/Dstate.ts +0 -105
  57. package/src/state/boolean-property.ts +0 -69
  58. package/src/state/state-service.spec.ts +0 -307
  59. package/src/state/state-service.ts +0 -251
  60. package/src/state/state-testing-helpers.ts +0 -59
@@ -1,2245 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/public-api.ts
21
- var public_api_exports = {};
22
- __export(public_api_exports, {
23
- BooleanStateProperty: () => BooleanStateProperty,
24
- Condition: () => Condition,
25
- DCss: () => DCss,
26
- DEventHandler: () => DEventHandler,
27
- DState: () => DState,
28
- DStyle: () => DStyle,
29
- DUtil: () => DUtil,
30
- PageID: () => PageID,
31
- Rule: () => Rule,
32
- RuleEngine: () => RuleEngine,
33
- SchemaDto: () => SchemaDto,
34
- SchemaEngine: () => SchemaEngine,
35
- SchemaID: () => SchemaID,
36
- createTypedIdSingleton: () => createTypedIdSingleton
37
- });
38
- module.exports = __toCommonJS(public_api_exports);
39
-
40
- // src/dto/SchemaDto.ts
41
- var SchemaDto;
42
- ((SchemaDto2) => {
43
- SchemaDto2.getResources = (schema) => {
44
- const { pages } = schema;
45
- const videoList = pages.reduce((acc, curr) => {
46
- if (Array.isArray(curr.video)) {
47
- acc.push(...curr.video);
48
- }
49
- return acc;
50
- }, []);
51
- const audioList = pages.reduce((acc, curr) => {
52
- if (Array.isArray(curr.audio)) {
53
- acc.push(...curr.audio);
54
- }
55
- return acc;
56
- }, []);
57
- return { videoList, audioList, imageList: [] };
58
- };
59
- })(SchemaDto || (SchemaDto = {}));
60
-
61
- // src/common/DTimestamp.ts
62
- var DTimestamp;
63
- ((DTimestamp2) => {
64
- DTimestamp2.now = () => Date.now();
65
- DTimestamp2.addMills = (t, ms) => {
66
- const res = t + Math.abs(ms);
67
- return res;
68
- };
69
- DTimestamp2.diff = (t1, t2) => {
70
- const t1Abs = Math.abs(t1);
71
- const t2Abs = Math.abs(t2);
72
- return Math.abs(t1Abs - t2Abs);
73
- };
74
- DTimestamp2.diffNow = (t) => {
75
- return (0, DTimestamp2.diff)(t, (0, DTimestamp2.now)());
76
- };
77
- })(DTimestamp || (DTimestamp = {}));
78
-
79
- // src/utils/DUtil.ts
80
- var DUtil;
81
- ((DUtil2) => {
82
- DUtil2.randomString = (length) => {
83
- const letters = "abcdefghijklmnopqrstuvxyz";
84
- const uppercase = letters.toUpperCase();
85
- const all = letters + uppercase;
86
- const abs = Math.abs(length);
87
- let result = "";
88
- for (let i = 0; i < abs; i++) {
89
- const char = all.charAt(Math.floor(Math.random() * all.length));
90
- result += char;
91
- }
92
- return result;
93
- };
94
- DUtil2.randomObjectId = () => (0, DUtil2.randomString)(32);
95
- DUtil2.deleteProp = (obj, key) => {
96
- delete obj[key];
97
- return obj;
98
- };
99
- DUtil2.isInRange = (min, max) => {
100
- return (value) => value >= min && value <= max;
101
- };
102
- DUtil2.isInfinity = (number) => {
103
- return number === Number.POSITIVE_INFINITY || number === Number.NEGATIVE_INFINITY || number === Infinity;
104
- };
105
- DUtil2.isNonEmptyArray = (array) => {
106
- return array.length > 0;
107
- };
108
- DUtil2.neverCheck = (args) => {
109
- console.log("OOPS: This value slipped through the never-check", args);
110
- };
111
- DUtil2.isString = (str) => typeof str === "string";
112
- DUtil2.hasKey = (obj, key) => {
113
- if (!(0, DUtil2.isRecord)(obj)) {
114
- return false;
115
- }
116
- return Object.prototype.hasOwnProperty.call(obj, key);
117
- };
118
- DUtil2.isRecord = (obj) => {
119
- if (!obj) {
120
- return false;
121
- }
122
- if (Array.isArray(obj)) {
123
- return false;
124
- }
125
- if (typeof obj !== "object") {
126
- return false;
127
- }
128
- if (obj === null) {
129
- return false;
130
- }
131
- return true;
132
- };
133
- DUtil2.isBool = (obj) => typeof obj === "boolean";
134
- DUtil2.isTrue = (bool) => bool === true;
135
- DUtil2.isFalse = (bool) => bool === false;
136
- DUtil2.isDefined = (obj) => {
137
- const notNull = obj !== null;
138
- const notUndefined = obj !== void 0;
139
- return notNull && notUndefined;
140
- };
141
- DUtil2.hasKind = (obj) => {
142
- if (!(0, DUtil2.hasKey)(obj, "kind")) {
143
- return false;
144
- }
145
- if (typeof obj.kind !== "string") {
146
- return false;
147
- }
148
- return obj.kind.length > 0;
149
- };
150
- DUtil2.hasValue = (obj) => {
151
- return (0, DUtil2.hasKey)(obj, "value");
152
- };
153
- DUtil2.isNumber = (value) => {
154
- const isNumber2 = typeof value === "number";
155
- const notNaN = !Number.isNaN(value);
156
- return isNumber2 && notNaN;
157
- };
158
- DUtil2.maxFn = (upperLimit) => {
159
- return (value) => {
160
- return Math.min(value, upperLimit);
161
- };
162
- };
163
- DUtil2.minFn = (lowerLimit) => {
164
- return (value) => {
165
- return Math.min(value, lowerLimit);
166
- };
167
- };
168
- })(DUtil || (DUtil = {}));
169
-
170
- // src/Delement/css.ts
171
- var DCss;
172
- ((DCss2) => {
173
- DCss2.toString = (unit, scale) => {
174
- const clampedScale = Math.max(scale, 0.03);
175
- if (unit._unit === "px") {
176
- if (unit.value < 0.1) {
177
- return "0px";
178
- }
179
- const rounded = Math.round(unit.value * clampedScale);
180
- const clamped = Math.max(rounded, 1);
181
- return clamped + "px";
182
- }
183
- return unit.value + "%";
184
- };
185
- DCss2.isLengthUnit = (unit) => {
186
- if (!unit) {
187
- return false;
188
- }
189
- const unitKey = "_unit";
190
- const valueKey = "value";
191
- const hasUnitKey = DUtil.hasKey(unit, unitKey);
192
- const hasValueKey = DUtil.hasKey(unit, valueKey);
193
- return hasUnitKey && hasValueKey;
194
- };
195
- })(DCss || (DCss = {}));
196
-
197
- // src/Delement/DStyle.ts
198
- var DStyle;
199
- ((DStyle2) => {
200
- DStyle2.normalize = (el) => {
201
- el.style.padding = "0";
202
- el.style.margin = "0";
203
- el.style.position = "absolute";
204
- el.style.boxSizing = "border-box";
205
- return el;
206
- };
207
- DStyle2.applyStyles = (el, style, scale) => {
208
- const {
209
- x,
210
- y,
211
- backgroundColor,
212
- borderColor,
213
- borderWidth,
214
- borderRadius,
215
- borderStyle,
216
- w,
217
- opacity,
218
- cursor,
219
- fontSize,
220
- fontWeight,
221
- textColor,
222
- textAlign,
223
- translate,
224
- margin,
225
- padding,
226
- letterSpacing,
227
- h,
228
- transform,
229
- visibility
230
- } = style;
231
- if (backgroundColor) {
232
- el.style.backgroundColor = backgroundColor;
233
- }
234
- if (cursor) {
235
- el.style.cursor = cursor;
236
- }
237
- if (transform) {
238
- el.style.transform = transform;
239
- }
240
- if (textColor) {
241
- el.style.color = textColor;
242
- }
243
- if (textAlign) {
244
- el.style.textAlign = textAlign;
245
- }
246
- if (borderColor) {
247
- el.style.borderColor = borderColor;
248
- }
249
- if (borderWidth) {
250
- el.style.borderWidth = DCss.toString(borderWidth, scale);
251
- }
252
- if (fontWeight) {
253
- el.style.fontWeight = fontWeight + "";
254
- }
255
- if (borderStyle) {
256
- el.style.borderStyle = borderStyle;
257
- }
258
- if (fontSize) {
259
- el.style.fontSize = DCss.toString(fontSize, scale);
260
- }
261
- if (DUtil.isNumber(x)) {
262
- el.style.left = x + "%";
263
- }
264
- if (DUtil.isNumber(y)) {
265
- el.style.bottom = y + "%";
266
- }
267
- if (DUtil.isNumber(h)) {
268
- el.style.height = h + "%";
269
- }
270
- if (DUtil.isNumber(w)) {
271
- el.style.width = w + "%";
272
- }
273
- if (DCss.isLengthUnit(borderRadius)) {
274
- el.style.borderRadius = DCss.toString(borderRadius, scale);
275
- }
276
- if (letterSpacing) {
277
- el.style.letterSpacing = DCss.toString(letterSpacing, scale);
278
- }
279
- if (margin) {
280
- el.style.margin = DCss.toString(margin, scale);
281
- }
282
- if (padding) {
283
- el.style.padding = DCss.toString(padding, scale);
284
- }
285
- if (DUtil.isNumber(opacity)) {
286
- el.style.opacity = opacity + "";
287
- }
288
- if (visibility) {
289
- el.style.visibility = visibility;
290
- }
291
- return el;
292
- };
293
- })(DStyle || (DStyle = {}));
294
-
295
- // src/Delement/VideoContainer.ts
296
- var ABORT_PLAY_TO_END = "ABORT_PLAY_TO_END";
297
- var VideoContainer = class {
298
- constructor(el, eventBus, scale) {
299
- this.el = el;
300
- this.eventBus = eventBus;
301
- this.scale = scale;
302
- this.TAG = "[ D_Video ] : ";
303
- this.el.controls = false;
304
- DStyle.normalize(this.el);
305
- DStyle.applyStyles(this.el, this.defaultStyles, this.scale.scale);
306
- this.el.onended = () => {
307
- this.eventBus.emit({
308
- kind: "VIDEO_ENDED_EVENT",
309
- timestamp: DTimestamp.now(),
310
- producer: "DVideo",
311
- producerId: this.id,
312
- data: {}
313
- });
314
- };
315
- this.el.onplay = () => {
316
- };
317
- this.el.onpause = () => {
318
- };
319
- this.el.onerror = () => {
320
- };
321
- this.el.oncanplay = () => {
322
- };
323
- this.el.onloadedmetadata = () => {
324
- const duration = this.el.duration;
325
- const isInfinity = DUtil.isInfinity(duration);
326
- this.eventBus.emit({
327
- kind: "VIDEO_LOADED_METADATA_EVENT",
328
- timestamp: DTimestamp.now(),
329
- producer: "DVideo",
330
- producerId: this.id,
331
- data: { duration, isInfinity }
332
- });
333
- };
334
- this.el.ondurationchange = () => {
335
- const duration = this.el.duration;
336
- const isInfinity = DUtil.isInfinity(duration);
337
- this.eventBus.emit({
338
- kind: "VIDEO_DURATION_CHANGE_EVENT",
339
- producer: "DVideo",
340
- producerId: this.id,
341
- timestamp: DTimestamp.now(),
342
- data: { duration, isInfinity }
343
- });
344
- };
345
- }
346
- TAG;
347
- dto;
348
- defaultStyles = { h: 45, w: 100, visibility: "hidden", y: 55 };
349
- pause() {
350
- this.eventBus.emit({
351
- kind: "VIDEO_PAUSED_EVENT",
352
- data: {},
353
- producer: "DVideo",
354
- producerId: this.id,
355
- timestamp: DTimestamp.now()
356
- });
357
- this.el.pause();
358
- }
359
- play(url) {
360
- if (this.el.src !== url) {
361
- this.el.src = url;
362
- }
363
- const producerId = this.dto?.id ?? "DVideo";
364
- this.eventBus.emit({
365
- kind: "VIDEO_PLAY_EVENT",
366
- data: {},
367
- producer: "DVideo",
368
- producerId,
369
- timestamp: DTimestamp.now()
370
- });
371
- this.el.play().then((res) => {
372
- console.log(res);
373
- }).catch((e) => {
374
- console.log(e);
375
- });
376
- }
377
- async playToEnd() {
378
- this.el.volume = 1;
379
- const url = this.dto?.url;
380
- if (!url) {
381
- return false;
382
- }
383
- try {
384
- const endedOrErrored = new Promise((resolve, reject) => {
385
- this.el.addEventListener(
386
- "ended",
387
- (_) => {
388
- resolve(true);
389
- },
390
- { once: true }
391
- );
392
- this.el.addEventListener(
393
- "error",
394
- (_) => {
395
- resolve(false);
396
- },
397
- { once: true }
398
- );
399
- this.el.addEventListener(
400
- ABORT_PLAY_TO_END,
401
- () => {
402
- console.log("CATCHED ABBORT.");
403
- reject("Aborted");
404
- },
405
- { once: true }
406
- );
407
- });
408
- this.play(url);
409
- await endedOrErrored;
410
- return true;
411
- } catch (e) {
412
- console.log(e);
413
- return false;
414
- } finally {
415
- console.log(this.TAG + " finally block playToEnd() completed videoId: " + this.dto?.id);
416
- }
417
- }
418
- getStats() {
419
- const duration = this.el.duration;
420
- const currentTime = this.el.currentTime;
421
- const volume = this.el.volume;
422
- const isConnected = this.el.isConnected;
423
- const playbackQuality = this.el.getVideoPlaybackQuality();
424
- const defaultPlaybackRate = this.el.defaultPlaybackRate;
425
- const paused = this.el.paused;
426
- const played = this.el.played;
427
- return {
428
- duration,
429
- paused,
430
- played,
431
- currentTime,
432
- volume,
433
- isConnected,
434
- playbackQuality,
435
- defaultPlaybackRate
436
- };
437
- }
438
- setDto(dto) {
439
- this.dto = dto;
440
- this.el.volume = 1;
441
- this.setStyle(dto.style);
442
- this.el.src = dto.url;
443
- this.el.load();
444
- }
445
- getCurrentDto() {
446
- return this.dto ?? false;
447
- }
448
- setStyle(styles) {
449
- DStyle.applyStyles(this.el, styles, this.scale.scale);
450
- }
451
- get id() {
452
- return this.dto?.id ?? "DVideo";
453
- }
454
- destroy() {
455
- }
456
- };
457
-
458
- // src/Delement/AudioContainer.ts
459
- var AudioContainer = class {
460
- constructor(eventBus) {
461
- this.eventBus = eventBus;
462
- this.el = document.createElement("audio");
463
- this.el.style.position = "absolute";
464
- this.el.style.visibility = "hidden";
465
- this.onLoad = this.onLoad.bind(this);
466
- this.el.onload = this.onLoad;
467
- this.onLoadedMetadata = this.onLoadedMetadata.bind(this);
468
- this.el.onloadedmetadata = this.onLoadedMetadata;
469
- this.el.onplay = () => {
470
- };
471
- this.onCanPlayThrough = this.onCanPlayThrough.bind(this);
472
- this.el.oncanplaythrough = this.onCanPlayThrough;
473
- this.el.onended = (_) => {
474
- const url = this.el.src;
475
- this.eventBus.emit({
476
- kind: "AUDIO_ENDED_EVENT",
477
- data: { url },
478
- producer: "DAudio",
479
- timestamp: DTimestamp.now(),
480
- producerId: this.id
481
- });
482
- };
483
- this.el.ondurationchange = (_) => {
484
- const duration = this.el.duration;
485
- const isInfinity = duration === Number.POSITIVE_INFINITY;
486
- this.eventBus.emit({
487
- kind: "AUDIO_DURATION_CHANGE_EVENT",
488
- timestamp: DTimestamp.now(),
489
- producer: "DAudio",
490
- producerId: this.id,
491
- data: { duration: this.el.duration, isInfinity }
492
- });
493
- };
494
- }
495
- TAG = "[ DAudio ]: ";
496
- dto = null;
497
- el;
498
- setAudio(dto) {
499
- this.dto = dto;
500
- this.el.src = dto.url;
501
- this.el.load();
502
- }
503
- destroy() {
504
- try {
505
- this.el.pause();
506
- this.el.src = "";
507
- this.el.load();
508
- } catch (e) {
509
- console.log(e);
510
- }
511
- }
512
- pause() {
513
- try {
514
- this.el.pause();
515
- } catch (e) {
516
- console.log(e);
517
- }
518
- }
519
- play(url) {
520
- if (this.el.src !== url) {
521
- this.el.src = url;
522
- }
523
- this.eventBus.emit({
524
- kind: "AUDIO_PLAY_EVENT",
525
- producerId: this.id,
526
- data: {},
527
- producer: "DAudio",
528
- timestamp: DTimestamp.now()
529
- });
530
- this.el.play().then((res) => {
531
- console.log(res);
532
- }).catch((e) => {
533
- console.log(e);
534
- });
535
- }
536
- onLoadedMetadata(_) {
537
- this.eventBus.emit({
538
- kind: "AUDIO_METADATA_LOADED_EVENT",
539
- timestamp: DTimestamp.now(),
540
- producer: "DAudio",
541
- producerId: this.id,
542
- data: {}
543
- });
544
- }
545
- onLoad(_) {
546
- this.eventBus.emit({
547
- kind: "AUDIO_LOAD_EVENT",
548
- timestamp: DTimestamp.now(),
549
- producer: "DAudio",
550
- producerId: this.id,
551
- data: {}
552
- });
553
- }
554
- get id() {
555
- return this.dto?.id ?? "DAudio";
556
- }
557
- onCanPlayThrough(_) {
558
- this.eventBus.emit({
559
- kind: "AUDIO_CAN_PLAY_THROUGH_EVENT",
560
- data: {},
561
- producer: "DAudio",
562
- timestamp: DTimestamp.now(),
563
- producerId: this.id
564
- });
565
- }
566
- // private onPlay(_: Event) {}
567
- async playToEnd() {
568
- const endedOrErrored = new Promise((resolve) => {
569
- this.el.addEventListener(
570
- "ended",
571
- (_) => {
572
- resolve(true);
573
- },
574
- { once: true }
575
- );
576
- this.el.addEventListener(
577
- "error",
578
- (_) => {
579
- resolve(false);
580
- },
581
- { once: true }
582
- );
583
- });
584
- try {
585
- this.play(this.el.src);
586
- await endedOrErrored;
587
- return true;
588
- } catch (e) {
589
- console.log(e);
590
- this.eventBus.emit({
591
- kind: "AUDIO_ERROR_EVENT",
592
- timestamp: DTimestamp.now(),
593
- producer: "DAudio",
594
- producerId: this.id,
595
- data: { error: e }
596
- });
597
- return false;
598
- } finally {
599
- }
600
- return Promise.resolve(false);
601
- }
602
- };
603
-
604
- // src/services/DMedia-manager.ts
605
- var DMediaManager = class _DMediaManager {
606
- constructor(hostEl, commandBus, eventBus, resourceProvider, scale) {
607
- this.hostEl = hostEl;
608
- this.commandBus = commandBus;
609
- this.eventBus = eventBus;
610
- this.resourceProvider = resourceProvider;
611
- this.scale = scale;
612
- _DMediaManager.INSTANCE_COUNT = _DMediaManager.INSTANCE_COUNT + 1;
613
- this.instanceNumber = _DMediaManager.INSTANCE_COUNT;
614
- const videoEl = document.createElement("video");
615
- this.hostEl.append(videoEl);
616
- this.videoContainer = new VideoContainer(videoEl, eventBus, this.scale);
617
- this.audioContainer = new AudioContainer(this.eventBus);
618
- this.tick = this.tick.bind(this);
619
- this.videoContainer.setStyle({ visibility: "hidden" });
620
- const now = DTimestamp.now();
621
- this.pageEnter = now;
622
- this.sincePageEnter = DTimestamp.diff(now, now);
623
- this.unsubscribeCommands = this.commandBus.subscribe((action) => {
624
- this.commandHandler(action);
625
- }, this.TAG);
626
- this.tickerRef = window.setInterval(() => {
627
- }, 1e3);
628
- }
629
- static INSTANCE_COUNT = 0;
630
- instanceNumber;
631
- TAG = "[ MEDIA_MANAGER ] : ";
632
- videoContainer;
633
- audioContainer;
634
- pageEnter;
635
- sincePageEnter;
636
- currentPage = null;
637
- unsubscribeCommands;
638
- tickerRef;
639
- sequenceManager = false;
640
- /**
641
- * Stop all media that is playing
642
- */
643
- clearAllMedia() {
644
- this.videoContainer.pause();
645
- this.audioContainer.pause();
646
- }
647
- destroy() {
648
- console.log("TODO DESTROY ALL MEDIA");
649
- this.unsubscribeCommands();
650
- window.clearInterval(this.tickerRef);
651
- this.audioContainer.destroy();
652
- this.videoContainer.destroy();
653
- }
654
- setPage(page) {
655
- this.currentPage = page;
656
- this.videoContainer.pause();
657
- this.pageEnter = DTimestamp.now();
658
- const seq = page.autoPlaySequence;
659
- const { mainVideoId, audio } = page;
660
- const audioElements = page.audio;
661
- if (mainVideoId) {
662
- const dto = this.resourceProvider.getVideoById(mainVideoId);
663
- if (dto) {
664
- this.videoContainer.setDto(dto);
665
- this.videoContainer.setStyle({ ...dto.style, visibility: "visible" });
666
- }
667
- } else {
668
- this.videoContainer.setStyle({ visibility: "hidden" });
669
- }
670
- if (audioElements) {
671
- const first = audioElements[0];
672
- if (first) {
673
- this.audioContainer.setAudio(first);
674
- }
675
- }
676
- if (seq) {
677
- this.playSequence(seq);
678
- }
679
- }
680
- commandHandler(command) {
681
- if (command.kind === "VIDEO_PLAY_COMMAND") {
682
- const video = command.targetId;
683
- const dto = this.videoContainer.getCurrentDto();
684
- if (dto && dto.id === command.targetId) {
685
- console.log(video);
686
- this.videoContainer.play(dto.url);
687
- }
688
- }
689
- if (command.kind === "VIDEO_PAUSE_COMMAND") {
690
- this.videoContainer.pause();
691
- }
692
- if (command.kind === "AUDIO_PLAY_COMMAND") {
693
- this.audioContainer.playToEnd().then(() => {
694
- }).catch().finally(() => {
695
- });
696
- }
697
- if (command.kind === "AUDIO_PAUSE_COMMAND") {
698
- }
699
- }
700
- async playSequence(seq) {
701
- const elements = seq.items;
702
- const testClone = [...elements];
703
- const first = testClone.pop();
704
- if (!first) {
705
- return false;
706
- }
707
- const now = DTimestamp.now();
708
- seq.startCommands.forEach((c) => {
709
- console.log(c);
710
- this.commandBus.emit(c);
711
- });
712
- for (let i = 0; i < elements.length; i++) {
713
- const item = elements[i];
714
- if (item.kind === "autoplay-video") {
715
- const dto = this.resourceProvider.getVideoById(item.videoId);
716
- if (dto)
717
- this.videoContainer.setDto(dto);
718
- await this.videoContainer.playToEnd();
719
- }
720
- if (item.kind === "autoplay-audio") {
721
- console.log(item);
722
- const dto = this.resourceProvider.getAudioById(item.audioId);
723
- if (dto)
724
- this.audioContainer.setAudio(dto);
725
- await this.audioContainer.playToEnd();
726
- }
727
- }
728
- seq.endCommands.forEach((c) => {
729
- this.commandBus.emit(c);
730
- });
731
- console.log(this.TAG + "SEQUENCE ENDED");
732
- return true;
733
- }
734
- // setPage()
735
- tick() {
736
- }
737
- };
738
-
739
- // src/commands/DCommandBus.ts
740
- var DCommandBus = class {
741
- TAG = "[ COMMAND_BUS ] ";
742
- logCommands = false;
743
- commandLog = [];
744
- subscribers = /* @__PURE__ */ new Set();
745
- // readonly sub
746
- subscribe(cb, subscriberId) {
747
- const sub = {
748
- subscriberId,
749
- callback: cb
750
- };
751
- this.subscribers.add(sub);
752
- return () => {
753
- this.subscribers.delete(sub);
754
- };
755
- }
756
- emit(command) {
757
- const timestamp = DTimestamp.now();
758
- this.commandLog.push({ ...command, timestamp });
759
- if (this.logCommands) {
760
- this.logCommand(command);
761
- }
762
- this.subscribers.forEach((subscriber) => {
763
- subscriber.callback(command);
764
- });
765
- }
766
- getStats() {
767
- return {
768
- commands: [...this.commandLog],
769
- subscribers: [...this.subscribers],
770
- subscribersCount: this.subscribers.size
771
- };
772
- }
773
- logCommand(command) {
774
- console.groupCollapsed(this.TAG + " " + command.kind);
775
- console.log("TargetID : " + command.targetId);
776
- console.log(command.payload);
777
- console.groupEnd();
778
- }
779
- };
780
-
781
- // src/events/event-bus.ts
782
- var EventBus = class {
783
- TAG = "[ EVENT_BUS ] :";
784
- // private readonly subscribers = new Set<(event: DEvent) => void>();
785
- subscribers = /* @__PURE__ */ new Set();
786
- /**
787
- * Emit on module end.
788
- * @private
789
- */
790
- eventLog = [];
791
- consoleLogEvents = false;
792
- // readonly sub
793
- subscribe(cb, subscriberId) {
794
- const subscriberData = {
795
- subscriberId,
796
- cb
797
- };
798
- this.subscribers.add(subscriberData);
799
- if (this.consoleLogEvents) {
800
- console.log(this.TAG + "subscription added: " + subscriberId);
801
- console.log(this.TAG + "subscription count: " + this.subscribers.size);
802
- }
803
- return () => {
804
- if (this.consoleLogEvents) {
805
- console.log(this.TAG + "subscription removed: " + subscriberId);
806
- console.log(this.TAG + "subscription count : " + this.subscribers.size);
807
- }
808
- this.subscribers.delete(subscriberData);
809
- };
810
- }
811
- getStats() {
812
- return {
813
- subscribersCount: this.subscribers.size,
814
- eventLog: [...this.eventLog],
815
- subscribers: [...this.subscribers]
816
- };
817
- }
818
- emit(event) {
819
- if (this.consoleLogEvents) {
820
- this.logEvent(event);
821
- }
822
- this.eventLog.push(event);
823
- this.subscribers.forEach((data) => {
824
- data.cb(event);
825
- });
826
- }
827
- logEvent(event) {
828
- console.groupCollapsed(this.TAG + " " + event.kind);
829
- console.log("ProducerId: " + event.producerId);
830
- console.log(event.data);
831
- console.groupEnd();
832
- }
833
- logEvents() {
834
- console.group(this.TAG + "LOGG");
835
- console.table(this.eventLog);
836
- console.groupEnd();
837
- }
838
- };
839
-
840
- // src/player/history-que.ts
841
- var AnsweredQuestion;
842
- ((AnsweredQuestion3) => {
843
- AnsweredQuestion3.eq = (a, b) => {
844
- return a.fact === b.fact;
845
- };
846
- })(AnsweredQuestion || (AnsweredQuestion = {}));
847
- var HistoryQue = class {
848
- history = [];
849
- getFacts() {
850
- const answers = this.history.map((h) => h.answeredQuestions).flat(1);
851
- const facts = answers.map((a) => a.fact);
852
- return facts;
853
- }
854
- getAnswers() {
855
- const answers = this.history.map((h) => h.answeredQuestions).flat(1);
856
- return answers;
857
- }
858
- addToHistory(page) {
859
- this.history.push(page);
860
- }
861
- };
862
-
863
- // src/rules/condition.ts
864
- var Condition;
865
- ((Condition2) => {
866
- Condition2.evaluate = (condition, facts) => {
867
- let result = false;
868
- switch (condition.kind) {
869
- case "string-condition":
870
- result = evaluateSimple(condition, facts);
871
- break;
872
- case "numeric-condition":
873
- result = evaluateSimple(condition, facts);
874
- break;
875
- case "complex-condition":
876
- result = evaluateComplex(condition, facts);
877
- break;
878
- default:
879
- const check = condition;
880
- }
881
- return result;
882
- };
883
- const evaluateComplex = (condition, facts) => {
884
- if (condition.some.length === 0 && condition.all.length === 0) {
885
- return false;
886
- }
887
- const allSolved = condition.all.map((condition2) => {
888
- return evaluateSimple(condition2, facts);
889
- });
890
- const someEvaluated = condition.some.map((condition2) => {
891
- return evaluateSimple(condition2, facts);
892
- });
893
- const allResult = allSolved.every(DUtil.isTrue);
894
- const someResult = someEvaluated.length === 0 || someEvaluated.some(DUtil.isTrue);
895
- return someResult && allResult;
896
- };
897
- const evaluateSimple = (condition, facts) => {
898
- const fact = facts.find((f) => f.referenceId === condition.referenceId);
899
- if (!fact) {
900
- return false;
901
- }
902
- let res = false;
903
- switch (condition.kind) {
904
- case "numeric-condition":
905
- if (fact.kind === "numeric-fact") {
906
- res = evaluateNumeric(condition, fact.value);
907
- }
908
- break;
909
- case "string-condition":
910
- if (fact.kind === "string-fact") {
911
- res = evaluateString(condition, fact.value);
912
- }
913
- break;
914
- default:
915
- const check = condition;
916
- }
917
- return res;
918
- };
919
- Condition2.isEmpty = (complex) => {
920
- return complex.all.length === 0 && complex.some.length === 0;
921
- };
922
- const evaluateString = (condition, value) => {
923
- const operator = condition.operator;
924
- let result = false;
925
- switch (operator) {
926
- case "eq":
927
- result = condition.value === value;
928
- break;
929
- case "not-eq":
930
- result = condition.value !== value;
931
- break;
932
- case "shorter-then":
933
- result = condition.value !== value;
934
- break;
935
- case "longer-then":
936
- result = condition.value !== value;
937
- break;
938
- default:
939
- const check = operator;
940
- }
941
- return result;
942
- };
943
- const evaluateNumeric = (condition, value) => {
944
- const op = condition.operator;
945
- const conditionValue = condition.value;
946
- let result = false;
947
- switch (op) {
948
- case "eq":
949
- result = value === conditionValue;
950
- break;
951
- case "not-eq":
952
- result = value !== conditionValue;
953
- break;
954
- case "greater-then":
955
- result = value > conditionValue;
956
- break;
957
- case "greater-then-inclusive":
958
- result = value >= conditionValue;
959
- break;
960
- case "less-then":
961
- result = value < conditionValue;
962
- break;
963
- case "less-then-inclusive":
964
- result = value <= conditionValue;
965
- break;
966
- default:
967
- const check = op;
968
- }
969
- return result;
970
- };
971
- const _getAllSimple = (condition) => {
972
- const simple = [];
973
- switch (condition.kind) {
974
- case "complex-condition":
975
- simple.push(...condition.all);
976
- simple.push(...condition.some);
977
- break;
978
- case "numeric-condition":
979
- simple.push(condition);
980
- break;
981
- case "string-condition":
982
- simple.push(condition);
983
- break;
984
- default:
985
- DUtil.neverCheck(condition);
986
- }
987
- return simple;
988
- };
989
- Condition2.getAllSimpleConditions = (condition) => {
990
- const simple = [];
991
- if (Array.isArray(condition)) {
992
- condition.forEach((c) => {
993
- simple.push(..._getAllSimple(c));
994
- });
995
- } else {
996
- simple.push(..._getAllSimple(condition));
997
- }
998
- return simple;
999
- };
1000
- })(Condition || (Condition = {}));
1001
-
1002
- // src/rules/rule.ts
1003
- var Rule;
1004
- ((Rule2) => {
1005
- Rule2.isEmpty = (rule) => {
1006
- const emptyConditions = rule.all.length === 0 && rule.some.length === 0;
1007
- const emptyActions = rule.onSuccess.length === 0 && rule.onFailure.length === 0;
1008
- return emptyConditions || emptyActions;
1009
- };
1010
- Rule2.solve = (rule, facts) => {
1011
- if (rule.some.length === 0 && rule.all.length === 0) {
1012
- return false;
1013
- }
1014
- const someSolved = rule.some.map((condition) => Condition.evaluate(condition, facts));
1015
- const someResult = someSolved.length === 0 || someSolved.some(DUtil.isTrue);
1016
- const allSolved = rule.all.map((condition) => Condition.evaluate(condition, facts)).every(DUtil.isTrue);
1017
- return allSolved && someResult;
1018
- };
1019
- })(Rule || (Rule = {}));
1020
-
1021
- // src/rules/rule-engine.ts
1022
- var RuleEngine = class {
1023
- constructor() {
1024
- }
1025
- solveAll(rules, facts) {
1026
- const errors = [];
1027
- const matching = [];
1028
- rules.forEach((rule) => {
1029
- if (Rule.isEmpty(rule)) {
1030
- errors.push({ message: "Empty rule: " + rule.id });
1031
- } else if (Rule.solve(rule, facts)) {
1032
- const match = {
1033
- ruleDescription: rule.description,
1034
- matchingRuleId: rule.id ?? "no-id-given",
1035
- actionList: [...rule.onSuccess]
1036
- };
1037
- matching.push(match);
1038
- }
1039
- });
1040
- return { matching, errors };
1041
- }
1042
- solve(rule, facts) {
1043
- return Rule.solve(rule, facts);
1044
- }
1045
- };
1046
-
1047
- // src/player/next-que.ts
1048
- var NextQue = class {
1049
- originalOrder = [];
1050
- allPages = [];
1051
- excludedTags = /* @__PURE__ */ new Set();
1052
- excludedByPageId = /* @__PURE__ */ new Set();
1053
- remaining = [];
1054
- constructor(pages = []) {
1055
- this.resetQue(pages);
1056
- }
1057
- /**
1058
- * Will reset que with the new pages.
1059
- * @param pages
1060
- */
1061
- resetQue(pages) {
1062
- this.allPages = [...pages];
1063
- this.remaining = [...pages];
1064
- this.excludedTags = /* @__PURE__ */ new Set();
1065
- this.excludedByPageId = /* @__PURE__ */ new Set();
1066
- this.originalOrder = this.allPages.map((p) => p.id);
1067
- }
1068
- pop() {
1069
- const next = this.remaining.shift();
1070
- return next ?? false;
1071
- }
1072
- peek() {
1073
- const next = this.remaining[0];
1074
- return next ?? false;
1075
- }
1076
- jumpToPageById(pageId) {
1077
- const index = this.remaining.findIndex((p) => p.id === pageId);
1078
- if (index < 0) {
1079
- return false;
1080
- }
1081
- this.remaining = this.remaining.slice(index);
1082
- return true;
1083
- }
1084
- removeByTag(tag) {
1085
- if (Array.isArray(tag)) {
1086
- tag.forEach((tag2) => {
1087
- this.excludedTags.add(tag2);
1088
- });
1089
- } else {
1090
- this.excludedTags.add(tag);
1091
- }
1092
- this.filterRemaining();
1093
- }
1094
- /**
1095
- * Will not be included
1096
- * @param pages
1097
- */
1098
- insertAsNextByForce(pages) {
1099
- this.remaining.unshift(...pages);
1100
- }
1101
- removeByPageId(pageId) {
1102
- if (Array.isArray(pageId)) {
1103
- pageId.forEach((id) => {
1104
- this.excludedByPageId.add(id);
1105
- });
1106
- } else {
1107
- this.excludedByPageId.add(pageId);
1108
- }
1109
- this.filterRemaining();
1110
- }
1111
- filterRemaining() {
1112
- this.remaining = this.remaining.filter((p) => {
1113
- const tags = p.tags ?? [];
1114
- const isIncluededByTag = !tags.some((tag) => this.excludedTags.has(tag));
1115
- const isIncludedByPageId = !this.excludedByPageId.has(p.id);
1116
- return isIncludedByPageId && isIncluededByTag;
1117
- });
1118
- }
1119
- get isEmpty() {
1120
- return this.remaining.length === 0;
1121
- }
1122
- get size() {
1123
- return this.remaining.length;
1124
- }
1125
- get pageCount() {
1126
- return this.originalOrder.length;
1127
- }
1128
- };
1129
-
1130
- // src/player/dplayer.ts
1131
- var DPlayer = class {
1132
- history = new HistoryQue();
1133
- ruleEngine = new RuleEngine();
1134
- nextQue = new NextQue();
1135
- data;
1136
- constructor(data) {
1137
- this.data = data;
1138
- this.nextQue.resetQue(data.pages);
1139
- }
1140
- saveHistory(pageHistory) {
1141
- console.log("SAVE HISTORY", pageHistory);
1142
- this.history.addToHistory(pageHistory);
1143
- const facts = this.history.getFacts();
1144
- const result = this.ruleEngine.solveAll(this.data.rules, facts);
1145
- const matchingRules = result.matching;
1146
- const actions = matchingRules.map((r) => r.actionList).flat(1);
1147
- actions.forEach((a) => {
1148
- console.log(a.payload);
1149
- switch (a.kind) {
1150
- case "PAGE_QUE_JUMP_TO_PAGE_COMMAND":
1151
- this.nextQue.jumpToPageById(a.payload.pageId);
1152
- break;
1153
- case "PAGE_QUE_EXCLUDE_BY_PAGE_ID_COMMAND":
1154
- this.nextQue.removeByPageId(a.payload.pageIds);
1155
- break;
1156
- case "PAGE_QUE_EXCLUDE_BY_TAG_COMMAND":
1157
- this.nextQue.removeByTag(a.payload.tagIds);
1158
- break;
1159
- default:
1160
- console.log("UNKNOWN ACTION", a);
1161
- const check = a;
1162
- }
1163
- });
1164
- console.log(actions);
1165
- }
1166
- getResults() {
1167
- return this.history.getAnswers();
1168
- }
1169
- goToPageById(pageId) {
1170
- this.nextQue.jumpToPageById(pageId);
1171
- }
1172
- handleNavigationCommand(command) {
1173
- switch (command.kind) {
1174
- case "PAGE_QUE_NEXT_PAGE_COMMAND":
1175
- break;
1176
- case "PAGE_QUE_GO_TO_PAGE_COMMAND":
1177
- this.goToPageById(command.payload.pageId);
1178
- break;
1179
- case "PAGE_QUE_GO_TO_SEQUENCE_COMMAND":
1180
- this.insertSequenceById(command.payload.sequenceId);
1181
- break;
1182
- default:
1183
- DUtil.neverCheck(command);
1184
- }
1185
- }
1186
- getNextPage() {
1187
- return this.nextQue.pop();
1188
- }
1189
- insertSequenceById(id) {
1190
- const seq = this.data.pageSequences?.find((s) => s.id === id);
1191
- if (seq) {
1192
- this.nextQue.insertAsNextByForce([...seq.pages]);
1193
- } else {
1194
- }
1195
- }
1196
- /**
1197
- * Total number of pages.
1198
- */
1199
- get pageCount() {
1200
- return this.nextQue.pageCount;
1201
- }
1202
- };
1203
-
1204
- // src/event-handlers/DEventHandler.ts
1205
- var DEventHandler;
1206
- ((DEventHandler2) => {
1207
- DEventHandler2.createLookUp = (handlers) => {
1208
- const map = /* @__PURE__ */ new Map();
1209
- handlers?.forEach((h) => {
1210
- const kind = h.onEvent;
1211
- const current = map.get(kind);
1212
- const actions = current ? [...current, h] : [h];
1213
- map.set(kind, actions);
1214
- });
1215
- return map;
1216
- };
1217
- })(DEventHandler || (DEventHandler = {}));
1218
-
1219
- // src/Delement/DElement.ts
1220
- var DElement = class {
1221
- el;
1222
- clickHandlerIsEnabled = true;
1223
- id;
1224
- isAnimatingSelf = false;
1225
- currStyle = {
1226
- fontSize: { _unit: "px", value: 100 },
1227
- fontWeight: 500,
1228
- textColor: "black",
1229
- opacity: 1
1230
- };
1231
- // private readonly onQueryChangedHandlers =
1232
- eventHandlers;
1233
- commandBus;
1234
- eventBus;
1235
- scale;
1236
- baseDto;
1237
- subscriptions = /* @__PURE__ */ new Set();
1238
- constructor(el, eventBus, commandBus, dto, scale) {
1239
- this.el = el;
1240
- this.id = dto.id;
1241
- this.baseDto = dto;
1242
- this.commandBus = commandBus;
1243
- this.eventBus = eventBus;
1244
- this.eventHandlers = DEventHandler.createLookUp(dto.eventHandlers);
1245
- this.scale = scale;
1246
- this.onClickHandler = this.onClickHandler.bind(this);
1247
- this.el.onclick = this.onClickHandler;
1248
- this.onMouseOver = this.onMouseOver.bind(this);
1249
- this.el.onmouseover = this.onMouseOver;
1250
- if (dto) {
1251
- this.updateStyles(dto?.style);
1252
- }
1253
- const commandSubscription = this.commandBus.subscribe((c) => {
1254
- if (c.kind === "ELEMENT_STYLE_COMMAND" && c.targetId === this.id) {
1255
- this.setStyle(c.payload.changes);
1256
- }
1257
- if (c.kind === "ELEMENT_DISABLE_CLICK_COMMAND" && c.targetId === this.id) {
1258
- this.clickHandlerIsEnabled = false;
1259
- }
1260
- if (c.kind === "ELEMENT_ENABLE_CLICK_COMMAND" && c.targetId === this.id) {
1261
- this.clickHandlerIsEnabled = true;
1262
- }
1263
- if (c.kind === "ELEMENT_ANIMATE_COMMAND" && c.targetId === this.id) {
1264
- console.log("TODO IMPLEMENT ANIMATION_HANDLER IN DElement.");
1265
- }
1266
- }, this.id);
1267
- const eventSubscription = this.eventBus.subscribe((event) => {
1268
- const handlers = this.eventHandlers.get(event.kind) ?? [];
1269
- const commands = handlers.map((h) => h.thenExecute).flat(1);
1270
- commands.forEach((command) => {
1271
- this.commandBus.emit(command);
1272
- });
1273
- if (event.kind === "HOST_SCALE_CHANGED_EVENT") {
1274
- console.log("HANDLE THIS SCALE CHANGE!!");
1275
- this.updateStyles({});
1276
- }
1277
- if (event.kind === "STATE_QUERY_RESULT_CHANGED_EVENT") {
1278
- this.queryChangedHandler(event.data);
1279
- }
1280
- }, "ELEMENT: ");
1281
- this.normalize();
1282
- this.subscriptions.add(commandSubscription);
1283
- this.subscriptions.add(eventSubscription);
1284
- }
1285
- // abstract setScale(scale: number): void;
1286
- // /**
1287
- // * The purpose of this function is to re-emit commands from event-handlers?
1288
- // * @param command
1289
- // * @private
1290
- // */
1291
- // private handleCommandsEmittedByPrivateEventHandlers(command: DCommand) {
1292
- // console.log(command);
1293
- // switch (command.kind) {
1294
- // case "ELEMENT_STYLE_COMMAND":
1295
- // if (command.targetId === this.id) {
1296
- // this.updateStyles(command.payload.changes);
1297
- // }
1298
- // break;
1299
- // case "ELEMENT_ANIMATE_COMMAND":
1300
- // // TODO CHECK FOR TARGET ID
1301
- // this.handleAnimateSelfAction(command.payload);
1302
- // break;
1303
- // case "ELEMENT_ENABLE_CLICK_COMMAND":
1304
- // this.clickHandlerIsEnabled = true;
1305
- // // this.updateStyles(command.payload.changes);
1306
- // break;
1307
- // case "ELEMENT_DISABLE_CLICK_COMMAND":
1308
- // this.clickHandlerIsEnabled = false;
1309
- // // this.handleAnimateSelfAction(command.payload);
1310
- // break;
1311
- // case "VIDEO_PLAY_COMMAND":
1312
- // this.commandBus.emit(command);
1313
- // break;
1314
- // case "VIDEO_PAUSE_COMMAND":
1315
- // this.commandBus.emit(command);
1316
- // break;
1317
- // case "ENGINE_LEAVE_PAGE_COMMAND":
1318
- // this.commandBus.emit(command);
1319
- // break;
1320
- // case "VIDEO_JUMP_TO_COMMAND":
1321
- // this.commandBus.emit(command);
1322
- // break;
1323
- // case "VIDEO_SET_VOLUME_COMMAND":
1324
- // this.commandBus.emit(command);
1325
- // break;
1326
- // case "AUDIO_PLAY_COMMAND":
1327
- // this.commandBus.emit(command);
1328
- // break;
1329
- // case "AUDIO_PAUSE_COMMAND":
1330
- // this.commandBus.emit(command);
1331
- // break;
1332
- // case "AUDIO_SET_VOLUME_COMMAND":
1333
- // this.commandBus.emit(command);
1334
- // break;
1335
- // case "PAGE_QUE_NEXT_PAGE_COMMAND":
1336
- // this.commandBus.emit(command);
1337
- // break;
1338
- // case "PAGE_QUE_GO_TO_SEQUENCE_COMMAND":
1339
- // this.commandBus.emit(command);
1340
- // break;
1341
- // case "PAGE_QUE_GO_TO_PAGE_COMMAND":
1342
- // this.commandBus.emit(command);
1343
- // break;
1344
- // case "PAGE_QUE_EXCLUDE_BY_PAGE_ID_COMMAND":
1345
- // this.commandBus.emit(command);
1346
- // break;
1347
- // case "PAGE_QUE_JUMP_TO_PAGE_COMMAND":
1348
- // this.commandBus.emit(command);
1349
- // break;
1350
- // case "PAGE_QUE_EXCLUDE_BY_TAG_COMMAND":
1351
- // this.commandBus.emit(command);
1352
- // break;
1353
- // case "STATE_MUTATE_COMMAND":
1354
- // this.commandBus.emit(command);
1355
- // break;
1356
- // default:
1357
- // DUtil.neverCheck(command);
1358
- // }
1359
- // }
1360
- queryChangedHandler(result) {
1361
- const maybeHandlers = this.baseDto.onStateChange;
1362
- if (!maybeHandlers) {
1363
- return;
1364
- }
1365
- const queryHandlers = maybeHandlers.filter((h) => h.queryName === result.queryName);
1366
- queryHandlers.forEach((h) => {
1367
- if (result.curr) {
1368
- h.whenTrue.forEach((command) => {
1369
- this.commandBus.emit(command);
1370
- });
1371
- } else {
1372
- h.whenFalse.forEach((command) => {
1373
- this.commandBus.emit(command);
1374
- });
1375
- }
1376
- });
1377
- }
1378
- onClickHandler(_) {
1379
- if (!this.clickHandlerIsEnabled) {
1380
- console.log(this.id + "Click disabled");
1381
- return;
1382
- }
1383
- const clickAction = this.baseDto.onClick;
1384
- if (clickAction && clickAction.length > 0) {
1385
- this.eventBus.emit({
1386
- kind: "USER_CLICKED_EVENT",
1387
- producer: "DUser",
1388
- producerId: this.id,
1389
- data: { elementId: this.id },
1390
- timestamp: DTimestamp.now()
1391
- });
1392
- clickAction.forEach((command) => {
1393
- this.commandBus.emit(command);
1394
- });
1395
- }
1396
- }
1397
- onMouseOver(_) {
1398
- }
1399
- setStyle(style) {
1400
- this.updateStyles(style);
1401
- }
1402
- appendYourself(parent) {
1403
- parent.append(this.el);
1404
- }
1405
- handleAnimateSelfAction(dto) {
1406
- this.isAnimatingSelf = true;
1407
- const { keyframes, options } = dto;
1408
- const animation = this.el.animate(keyframes, options.duration);
1409
- animation.onfinish = (e) => {
1410
- console.log(e.type);
1411
- this.isAnimatingSelf = false;
1412
- };
1413
- animation.onremove = () => {
1414
- console.warn("ANIMATION REMOVED: " + animation.id);
1415
- this.isAnimatingSelf = false;
1416
- };
1417
- animation.oncancel = () => {
1418
- console.warn("ANIMATION CANCELED: " + animation.id);
1419
- this.isAnimatingSelf = false;
1420
- };
1421
- }
1422
- normalize() {
1423
- DStyle.normalize(this.el);
1424
- }
1425
- updateStyles(style) {
1426
- this.currStyle = Object.assign(this.currStyle, style);
1427
- DStyle.applyStyles(this.el, this.currStyle, this.scale.scale);
1428
- window.getComputedStyle(this.el);
1429
- }
1430
- };
1431
-
1432
- // src/Delement/Ddiv.ts
1433
- var DDiv = class extends DElement {
1434
- TAG = "[ DDiv ]: ";
1435
- defaultStyle = { x: 22, y: 4 };
1436
- children = [];
1437
- constructor(dto, eventBus, actionService, scale, children) {
1438
- const d = document.createElement("div");
1439
- super(d, eventBus, actionService, dto, scale);
1440
- this.children = children;
1441
- this.children.forEach((child) => {
1442
- child.appendYourself(this.el);
1443
- });
1444
- }
1445
- destroy() {
1446
- this.subscriptions.forEach((unsubscribe) => {
1447
- unsubscribe();
1448
- });
1449
- this.children.forEach((child) => {
1450
- child.destroy();
1451
- });
1452
- }
1453
- };
1454
-
1455
- // src/Delement/DImg.ts
1456
- var DImg = class _DImg extends DElement {
1457
- constructor(dto, actionSubject, eventBus, scaleService) {
1458
- super(document.createElement("img"), eventBus, actionSubject, dto, scaleService);
1459
- this.dto = dto;
1460
- this.actionSubject = actionSubject;
1461
- this.eventBus = eventBus;
1462
- this.scaleService = scaleService;
1463
- _DImg.IMAGE_COUNT += 1;
1464
- this.imageCount = _DImg.IMAGE_COUNT;
1465
- this.TAG = "[D_IMG " + _DImg.IMAGE_COUNT + " ]: ";
1466
- this.TIMING_TAG = "load-time (" + _DImg.IMAGE_COUNT + ") ";
1467
- this.el.loading = "eager";
1468
- this.el.style.position = "absolute";
1469
- this.setStyle(dto.style);
1470
- this.loadStart = DTimestamp.now();
1471
- this.onError = this.onError.bind(this);
1472
- this.onLoad = this.onLoad.bind(this);
1473
- this.el.onload = this.onLoad;
1474
- this.el.onerror = this.onError;
1475
- this.el.src = dto.url;
1476
- console.time(this.TIMING_TAG);
1477
- }
1478
- static IMAGE_COUNT = 0;
1479
- imageCount;
1480
- TAG;
1481
- TIMING_TAG;
1482
- loadStart;
1483
- log() {
1484
- }
1485
- setScale(scale) {
1486
- console.log(scale);
1487
- this.setStyle(this.currStyle);
1488
- }
1489
- destroy() {
1490
- this.subscriptions.forEach((unsubscribe) => {
1491
- unsubscribe();
1492
- });
1493
- }
1494
- onError(ev) {
1495
- if (ev instanceof Event) {
1496
- console.log(this.TAG + " " + ev.type);
1497
- } else {
1498
- console.log(this.TAG + ev);
1499
- }
1500
- }
1501
- onLoad(_) {
1502
- const loadTime = DTimestamp.diffNow(this.loadStart);
1503
- this.eventBus.emit({
1504
- kind: "IMAGE_LOADED_EVENT",
1505
- producer: "DImage",
1506
- producerId: this.id,
1507
- timestamp: DTimestamp.now(),
1508
- data: {
1509
- loadTime,
1510
- naturalHeight: this.el.naturalHeight,
1511
- naturalWidth: this.el.naturalWidth,
1512
- height: this.el.height,
1513
- width: this.el.width
1514
- }
1515
- });
1516
- }
1517
- };
1518
-
1519
- // src/Delement/DText.ts
1520
- var DText = class extends DElement {
1521
- TAG = "[ DParagraph ]: ";
1522
- defaultStyle = {};
1523
- constructor(dto, eventBus, actionService, scale) {
1524
- super(document.createElement("p"), eventBus, actionService, dto, scale);
1525
- this.el.style.position = "absolute";
1526
- this.el.innerText = "" + dto.text;
1527
- this.setStyle(dto.style);
1528
- }
1529
- setScale(scale) {
1530
- this.setStyle(this.currStyle);
1531
- const fontSize = this.el.style.fontSize;
1532
- console.log(this.TAG + "scale: " + scale + " Fontsize: " + fontSize);
1533
- }
1534
- destroy() {
1535
- this.subscriptions.forEach((unsubscribe) => {
1536
- unsubscribe();
1537
- });
1538
- }
1539
- };
1540
-
1541
- // src/engine/element-factory.ts
1542
- var createDElement = (dto, actionBus, eventBus, scale) => {
1543
- switch (dto._tag) {
1544
- case "div":
1545
- const childEls = createChildrenForDiv(dto, actionBus, eventBus, scale);
1546
- const newDiv = new DDiv(dto, eventBus, actionBus, scale, childEls);
1547
- return newDiv;
1548
- case "img":
1549
- return new DImg(dto, actionBus, eventBus, scale);
1550
- case "p":
1551
- return new DText(dto, eventBus, actionBus, scale);
1552
- default:
1553
- const check = dto;
1554
- throw new Error("Unknown dto given to the createDElement function.");
1555
- }
1556
- };
1557
- var createChildrenForDiv = (dto, actionSubject, eventBus, scale) => {
1558
- const childDto = dto.children;
1559
- const childEls = [];
1560
- childDto.forEach((dto2) => {
1561
- if (dto2._tag === "p") {
1562
- const newText = new DText(dto2, eventBus, actionSubject, scale);
1563
- childEls.push(newText);
1564
- }
1565
- if (dto2._tag === "img") {
1566
- const newImage = new DImg(dto2, actionSubject, eventBus, scale);
1567
- childEls.push(newImage);
1568
- }
1569
- });
1570
- return childEls;
1571
- };
1572
-
1573
- // src/engine/DPage.ts
1574
- var DPage = class {
1575
- // Todo GLOBAL EVENT_BUSS AND PAGE EVENTS:
1576
- constructor(dto, eventBus, commandBus, scale) {
1577
- this.dto = dto;
1578
- this.eventBus = eventBus;
1579
- this.commandBus = commandBus;
1580
- this.scale = scale;
1581
- this.elements = dto.elements.map((dto2) => createDElement(dto2, this.commandBus, this.eventBus, this.scale));
1582
- }
1583
- TAG = "[ DPage ]: ";
1584
- elements = [];
1585
- eventBus;
1586
- commandBus;
1587
- scale;
1588
- appendYourself(parent) {
1589
- this.elements.forEach((el) => {
1590
- el.appendYourself(parent);
1591
- });
1592
- this.eventBus.emit({
1593
- kind: "PAGE_ENTER_EVENT",
1594
- timestamp: DTimestamp.now(),
1595
- producer: "DPage",
1596
- producerId: this.id,
1597
- data: { pageId: this.id }
1598
- });
1599
- }
1600
- destroy() {
1601
- this.elements.forEach((el) => {
1602
- el.destroy();
1603
- });
1604
- }
1605
- log() {
1606
- }
1607
- get id() {
1608
- return this.dto.id;
1609
- }
1610
- };
1611
-
1612
- // src/engine/scale.ts
1613
- var ScaleService = class {
1614
- baseHeight;
1615
- baseWidth;
1616
- containerHeight = 1300;
1617
- containerWidth = 1300;
1618
- get scale() {
1619
- return this._scale;
1620
- }
1621
- get pageHeight() {
1622
- return this.baseHeight * this.scale;
1623
- }
1624
- get pageWidth() {
1625
- return this.baseWidth * this._scale;
1626
- }
1627
- _scale = 1;
1628
- subscribers = /* @__PURE__ */ new Set();
1629
- constructor(config) {
1630
- this.baseHeight = config.baseHeight;
1631
- this.baseWidth = config.baseWidth;
1632
- this.containerHeight = config.containerHeight;
1633
- this.containerWidth = config.containerWidth;
1634
- this.updateScale();
1635
- }
1636
- setContainerBounds(bounds) {
1637
- this.containerWidth = bounds.width;
1638
- this.containerHeight = bounds.height;
1639
- this.updateScale();
1640
- }
1641
- updateScale() {
1642
- const scaleFn = Scale.calc(this.baseHeight, this.baseWidth);
1643
- const scale = scaleFn({ height: this.containerHeight, width: this.containerWidth });
1644
- const hasChanged = this.scale !== scale;
1645
- this._scale = scale;
1646
- if (hasChanged) {
1647
- this.subscribers.forEach((fn) => {
1648
- fn(this._scale);
1649
- });
1650
- }
1651
- }
1652
- onChange(scaleChangeHandler, subscriberId) {
1653
- this.subscribers.add(scaleChangeHandler);
1654
- scaleChangeHandler(this._scale);
1655
- return () => {
1656
- this.subscribers.delete(scaleChangeHandler);
1657
- };
1658
- }
1659
- };
1660
- var Scale;
1661
- ((Scale2) => {
1662
- Scale2.calc = (baseHeight, baseWidth) => {
1663
- return (container) => {
1664
- const heightRatio = container.height / baseHeight;
1665
- const widthRatio = container.width / baseWidth;
1666
- return Math.min(heightRatio, widthRatio);
1667
- };
1668
- };
1669
- Scale2.scaleFunctionCreator = (scale) => {
1670
- return (value) => value * scale;
1671
- };
1672
- })(Scale || (Scale = {}));
1673
-
1674
- // src/services/resource-provider.ts
1675
- var ResourceProvider = class {
1676
- TAG = "[ RESOURCE_PROVIDER ]: ";
1677
- videoMap = /* @__PURE__ */ new Map();
1678
- audioMap = /* @__PURE__ */ new Map();
1679
- constructor(data) {
1680
- data.videos.forEach((video) => {
1681
- this.videoMap.set(video.id, video);
1682
- });
1683
- data.audio.forEach((audio) => {
1684
- this.audioMap.set(audio.id, audio);
1685
- });
1686
- }
1687
- getAudioById(id) {
1688
- const maybeAudio = this.audioMap.get(id);
1689
- if (!maybeAudio) {
1690
- console.error(this.TAG + "Audio by id " + id + " dont exist");
1691
- }
1692
- return maybeAudio ?? false;
1693
- }
1694
- getVideoById(id) {
1695
- const maybeVideo = this.videoMap.get(id);
1696
- if (!maybeVideo) {
1697
- console.error(this.TAG + "Video by id " + id + " dont exist");
1698
- }
1699
- return maybeVideo ?? false;
1700
- }
1701
- };
1702
-
1703
- // src/common/result.ts
1704
- var Ok = class _Ok {
1705
- constructor(value) {
1706
- this.value = value;
1707
- }
1708
- isOk() {
1709
- return true;
1710
- }
1711
- isFailure() {
1712
- return false;
1713
- }
1714
- map(f) {
1715
- const value = f(this.value);
1716
- return new _Ok(value);
1717
- }
1718
- };
1719
- var Failure = class _Failure {
1720
- constructor(message) {
1721
- this.message = message;
1722
- }
1723
- isFailure() {
1724
- return true;
1725
- }
1726
- isOk() {
1727
- return false;
1728
- }
1729
- map(_f) {
1730
- return new _Failure(this.message);
1731
- }
1732
- };
1733
- var Result;
1734
- ((Result2) => {
1735
- Result2.ok = (value) => new Ok(value);
1736
- Result2.failure = (message) => new Failure(message);
1737
- })(Result || (Result = {}));
1738
-
1739
- // src/state/Dstate.ts
1740
- var DState;
1741
- ((DState2) => {
1742
- DState2.isNumberMutation = (mutations) => {
1743
- if (!mutations) {
1744
- return false;
1745
- }
1746
- return mutations.kind === "set-number" || mutations.kind === "decrement-number" || mutations.kind === "increment-number";
1747
- };
1748
- DState2.isStringMutation = (mutation) => {
1749
- return mutation && mutation.kind === "set-string";
1750
- };
1751
- DState2.numericPropToFact = (prop, value) => {
1752
- const fact = {
1753
- kind: "numeric-fact",
1754
- referenceId: prop.propName,
1755
- referenceLabel: prop.propDescription ?? " [STATE_PROPERTY] : " + prop.propName,
1756
- value,
1757
- label: " [VALUE] : " + value
1758
- };
1759
- return fact;
1760
- };
1761
- DState2.stringPropToFact = (prop, value) => {
1762
- const fact = {
1763
- kind: "string-fact",
1764
- referenceId: prop.propName,
1765
- referenceLabel: " [STATE_PROPERTY] : " + prop.propName,
1766
- value,
1767
- label: " [VALUE] : " + value
1768
- };
1769
- return fact;
1770
- };
1771
- })(DState || (DState = {}));
1772
-
1773
- // src/state/state-service.ts
1774
- var StateService = class {
1775
- constructor(eventBus, commandBus, props, queryList = []) {
1776
- this.eventBus = eventBus;
1777
- this.commandBus = commandBus;
1778
- this.props = props;
1779
- this.queryList = queryList;
1780
- props.forEach((prop) => {
1781
- this.registerProperty(prop);
1782
- });
1783
- const facts = this.getAllFacts();
1784
- queryList.forEach((definition) => {
1785
- this.registerQuery(definition, facts);
1786
- });
1787
- this.evaluateQueries();
1788
- this.unsubscribeCommands = this.commandBus.subscribe((command) => {
1789
- if (command.kind === "STATE_MUTATE_COMMAND") {
1790
- this.mutation(command.payload.mutation);
1791
- }
1792
- }, this.TAG);
1793
- }
1794
- TAG = " [ STATE_SERVICE ] :";
1795
- factsString = /* @__PURE__ */ new Map();
1796
- factsNumeric = /* @__PURE__ */ new Map();
1797
- propDefinitions = /* @__PURE__ */ new Map();
1798
- queries = /* @__PURE__ */ new Map();
1799
- unsubscribeCommands;
1800
- destroy() {
1801
- this.unsubscribeCommands();
1802
- }
1803
- registerQuery(query, currentFacts) {
1804
- const result = Condition.evaluate(query.condition, currentFacts);
1805
- this.queries.set(query.name, { query, lastResult: result });
1806
- this.emitQueryChangedEvent({ queryName: query.name, prev: result, curr: result });
1807
- }
1808
- registerProperty(prop) {
1809
- if (this.propDefinitions.has(prop.propName)) {
1810
- console.warn("Prop excists already.", prop.propName);
1811
- }
1812
- this.propDefinitions.set(prop.propName, prop);
1813
- if (prop.initialValue === void 0) {
1814
- return;
1815
- }
1816
- if (prop._type === "string") {
1817
- const fact = DState.stringPropToFact(prop, prop.initialValue);
1818
- this.factsString.set(fact.referenceId, fact);
1819
- }
1820
- if (prop._type === "number") {
1821
- const fact = DState.numericPropToFact(prop, prop.initialValue);
1822
- this.factsNumeric.set(fact.referenceId, fact);
1823
- }
1824
- }
1825
- mutateString(prop, value) {
1826
- const curr = this.factsString.get(prop.propName);
1827
- if (curr) {
1828
- const updated = { ...curr, value };
1829
- this.setFact(updated);
1830
- } else {
1831
- const created = {
1832
- kind: "string-fact",
1833
- referenceId: prop.propName,
1834
- referenceLabel: "label for: " + prop.propName,
1835
- value,
1836
- label: "Value: " + value
1837
- };
1838
- this.setFact(created);
1839
- }
1840
- }
1841
- mutateNumber(prop, mutation) {
1842
- const curr = this.factsNumeric.get(prop.propName);
1843
- if (!curr) {
1844
- switch (mutation.kind) {
1845
- case "set-number":
1846
- this.setFact(DState.numericPropToFact(prop, mutation.value));
1847
- break;
1848
- case "decrement-number":
1849
- this.setFact(DState.numericPropToFact(prop, mutation.ifNotExistThenSetTo));
1850
- break;
1851
- case "increment-number":
1852
- this.setFact(DState.numericPropToFact(prop, mutation.ifNotExistThenSetTo));
1853
- break;
1854
- default:
1855
- const check = mutation;
1856
- }
1857
- }
1858
- if (curr) {
1859
- switch (mutation.kind) {
1860
- case "set-number":
1861
- this.setFact({ ...curr, value: mutation.value });
1862
- break;
1863
- case "decrement-number":
1864
- this.setFact({ ...curr, value: curr.value - mutation.stepSize });
1865
- break;
1866
- case "increment-number":
1867
- this.setFact({ ...curr, value: curr.value + mutation.stepSize });
1868
- break;
1869
- default:
1870
- const check = mutation;
1871
- }
1872
- }
1873
- }
1874
- evaluateQueries() {
1875
- const facts = this.getAllFacts();
1876
- const all = [];
1877
- this.queries.forEach((q) => {
1878
- const prev = q.lastResult;
1879
- const curr = Condition.evaluate(q.query.condition, facts);
1880
- const didChange = prev !== curr;
1881
- q.lastResult = curr;
1882
- all.push({ queryName: q.query.name, prev, curr, didChange });
1883
- });
1884
- return all;
1885
- }
1886
- mutation(mutation) {
1887
- const propDef = this.propDefinitions.get(mutation.propName);
1888
- if (!propDef) {
1889
- return { success: false };
1890
- }
1891
- if (propDef._type === "string" && DState.isStringMutation(mutation)) {
1892
- this.mutateString(propDef, mutation.value);
1893
- }
1894
- if (propDef._type === "number" && DState.isNumberMutation(mutation)) {
1895
- this.mutateNumber(propDef, mutation);
1896
- }
1897
- const queryResults = this.evaluateQueries();
1898
- const changedResult = queryResults.filter((r) => r.didChange);
1899
- changedResult.forEach((res) => {
1900
- this.emitQueryChangedEvent({ queryName: res.queryName, prev: res.prev, curr: res.curr });
1901
- });
1902
- return { success: true };
1903
- }
1904
- emitQueryChangedEvent(data) {
1905
- const queryChangedEvent = {
1906
- kind: "STATE_QUERY_RESULT_CHANGED_EVENT",
1907
- producer: "STATE-SERVICE",
1908
- producerId: "STATE-SERVICE",
1909
- timestamp: DTimestamp.now(),
1910
- data
1911
- };
1912
- const { queryName, curr, prev } = queryChangedEvent.data;
1913
- this.eventBus.emit(queryChangedEvent);
1914
- }
1915
- getPropAsFact(propName) {
1916
- const propDef = this.propDefinitions.get(propName);
1917
- if (!propDef) {
1918
- return Result.failure(
1919
- "No definition form property ny name " + propName + " is registered. (Pass in constructor.)"
1920
- );
1921
- }
1922
- const value = this.factsString.get(propName) ?? this.factsNumeric.get(propName);
1923
- return value ? Result.ok(value) : Result.failure("Property " + propName + " has no value.");
1924
- }
1925
- setFact(fact) {
1926
- switch (fact.kind) {
1927
- case "numeric-fact":
1928
- this.factsNumeric.set(fact.referenceId, fact);
1929
- break;
1930
- case "string-fact":
1931
- this.factsString.set(fact.referenceId, fact);
1932
- break;
1933
- default:
1934
- const check = fact;
1935
- }
1936
- }
1937
- getState() {
1938
- const props = {};
1939
- this.propDefinitions.forEach((def) => {
1940
- let value = null;
1941
- const maybeFact = this.getAnyFact(def.propName);
1942
- if (maybeFact) {
1943
- value = maybeFact.value;
1944
- }
1945
- props[def.propName] = value;
1946
- });
1947
- this.queries.forEach((query) => {
1948
- props[query.query.name] = query.lastResult;
1949
- });
1950
- const propNames = Object.keys(props);
1951
- const propCount = propNames.length;
1952
- const propArray = [...this.propDefinitions.values()];
1953
- return { propCount, propNames, propArray, state: props };
1954
- }
1955
- getAnyFact(propName) {
1956
- return this.factsString.get(propName) ?? this.factsNumeric.get(propName) ?? false;
1957
- }
1958
- getAllFacts() {
1959
- return [...this.factsNumeric.values(), ...this.factsString.values()];
1960
- }
1961
- /**
1962
- * Will check that all referenceIds used in Condition is registered as a valid property in state.
1963
- * @param condition
1964
- */
1965
- canBeMatched(condition) {
1966
- const simpleConditions = Condition.getAllSimpleConditions(condition);
1967
- let hasAll = true;
1968
- const allIds = simpleConditions.map((c) => c.referenceId);
1969
- const missingIds = [];
1970
- allIds.forEach((id) => {
1971
- if (!this.propDefinitions.has(id)) {
1972
- hasAll = false;
1973
- missingIds.push(id);
1974
- }
1975
- });
1976
- console.log(this.TAG, missingIds);
1977
- return hasAll;
1978
- }
1979
- isMatched(condition) {
1980
- return Condition.evaluate(condition, this.getAllFacts());
1981
- }
1982
- };
1983
-
1984
- // src/engine/SchemaEngine.ts
1985
- var SchemaEngine = class {
1986
- constructor(hostEl, height, width, schema) {
1987
- this.height = height;
1988
- this.width = width;
1989
- this.schema = schema;
1990
- this.hostElement = hostEl;
1991
- this.hostElement.appendChild(this.uiContainer);
1992
- this.hostElement.appendChild(this.mediaContainer);
1993
- const stateProps = this.schema.stateProps ?? [];
1994
- const stateQueries = this.schema.stateQueries ?? [];
1995
- this.stateService = new StateService(this.eventBus, this.commandBus, stateProps, stateQueries);
1996
- this.scale = new ScaleService({
1997
- baseHeight: schema.baseHeight,
1998
- baseWidth: schema.baseWidth,
1999
- containerWidth: width,
2000
- containerHeight: height
2001
- });
2002
- const globalEventHandlers = schema.stateFromEvent ?? [];
2003
- globalEventHandlers.forEach((h) => {
2004
- this.globalEventToStateHandlers.set(h.onEvent, h.thenExecute);
2005
- });
2006
- const resources = SchemaDto.getResources(this.schema);
2007
- this.resourceProvider = new ResourceProvider({ videos: resources.videoList, audio: resources.audioList });
2008
- this.mediaManager = new DMediaManager(
2009
- this.mediaContainer,
2010
- this.commandBus,
2011
- this.eventBus,
2012
- this.resourceProvider,
2013
- this.scale
2014
- );
2015
- this.player = new DPlayer(this.schema);
2016
- this.styleSelf();
2017
- this.nextPage();
2018
- this.hookUpListeners();
2019
- }
2020
- TAG = "[ SCHEMA_ENGINE ] :";
2021
- commandBus = new DCommandBus();
2022
- eventBus = new EventBus();
2023
- mediaManager;
2024
- scale;
2025
- hostElement;
2026
- uiContainer = document.createElement("div");
2027
- mediaContainer = document.createElement("div");
2028
- resourceProvider;
2029
- stateService;
2030
- globalEventToStateHandlers = /* @__PURE__ */ new Map();
2031
- player;
2032
- currentPage = false;
2033
- subs = [];
2034
- hookUpListeners() {
2035
- const eventSubscription = this.eventBus.subscribe((ev) => {
2036
- this.onCommandOrEvent(ev);
2037
- const globalHandlers = this.globalEventToStateHandlers.get(ev.kind) ?? [];
2038
- globalHandlers.forEach((stateCommand) => {
2039
- this.commandBus.emit(stateCommand);
2040
- });
2041
- }, this.TAG + "HOOK_UP_LISTENERS");
2042
- const commandSubscription = this.commandBus.subscribe((command) => {
2043
- this.onCommandOrEvent(command);
2044
- if (command.kind === "PAGE_QUE_NEXT_PAGE_COMMAND") {
2045
- this.nextPage();
2046
- }
2047
- if (command.kind === "ENGINE_LEAVE_PAGE_COMMAND") {
2048
- console.log(this.TAG + "SEQUENCE STARTED -- TODO EVENT FOR THIS??");
2049
- console.log(command);
2050
- const pageId = command.payload.pageId;
2051
- const facts = command.payload.factsCollected;
2052
- const timestamp = DTimestamp.now();
2053
- const ans = facts.map((f) => ({
2054
- timestamp,
2055
- fact: f
2056
- }));
2057
- this.player.saveHistory({
2058
- answeredQuestions: ans,
2059
- pageId
2060
- });
2061
- this.nextPage();
2062
- }
2063
- }, this.TAG);
2064
- this.subs.push(commandSubscription);
2065
- this.subs.push(eventSubscription);
2066
- }
2067
- styleSelf() {
2068
- this.hostElement.style.height = this.scale.pageHeight + "px";
2069
- this.hostElement.style.width = this.scale.pageWidth + "px";
2070
- this.hostElement.style.backgroundColor = this.schema.backgroundColor ?? "white";
2071
- this.hostElement.style.position = "relative";
2072
- const makeStatic = (div) => {
2073
- div.style.height = "0px";
2074
- div.style.width = "0px";
2075
- div.style.position = "static";
2076
- };
2077
- makeStatic(this.uiContainer);
2078
- makeStatic(this.mediaContainer);
2079
- }
2080
- nextPage() {
2081
- this.mediaManager.clearAllMedia();
2082
- const nextPage = this.player.getNextPage();
2083
- if (this.currentPage) {
2084
- this.currentPage.destroy();
2085
- this.uiContainer.innerHTML = "";
2086
- }
2087
- if (!nextPage) {
2088
- this.player = new DPlayer(this.schema);
2089
- if (this.schema.pages.length > 0) {
2090
- this.nextPage();
2091
- }
2092
- return false;
2093
- }
2094
- const newPage = new DPage(nextPage, this.eventBus, this.commandBus, this.scale);
2095
- this.currentPage = newPage;
2096
- newPage.appendYourself(this.uiContainer);
2097
- this.mediaManager.setPage(nextPage);
2098
- const s1 = this.stateService.getState();
2099
- return true;
2100
- }
2101
- destroy() {
2102
- if (this.currentPage) {
2103
- this.currentPage.destroy();
2104
- this.uiContainer.innerHTML = "";
2105
- }
2106
- this.mediaManager.destroy();
2107
- this.stateService.destroy();
2108
- this.subs.forEach((sub) => {
2109
- sub();
2110
- });
2111
- const evStats = this.eventBus.getStats();
2112
- const cmdStats = this.commandBus.getStats();
2113
- console.assert(evStats.subscribersCount === 0, this.TAG + " Eventbus should have no subscribers ", evStats);
2114
- console.assert(cmdStats.subscribersCount === 0, this.TAG + "Commandbus should have no subscribers", cmdStats);
2115
- }
2116
- onComplete(handler) {
2117
- console.log(handler);
2118
- }
2119
- onFatalError(handler) {
2120
- console.log(handler);
2121
- }
2122
- onCommandOrEvent(_event_or_command) {
2123
- }
2124
- setSchema(schema) {
2125
- console.log(schema);
2126
- }
2127
- };
2128
-
2129
- // src/state/boolean-property.ts
2130
- var BooleanStateProperty = class _BooleanStateProperty {
2131
- constructor(propName, initialValue, description) {
2132
- this.initialValue = initialValue;
2133
- this.propName = propName;
2134
- const initial = initialValue ? 1 : 0;
2135
- const propDescription = description ? description : "No description given";
2136
- this.propDefinition = {
2137
- propDescription,
2138
- propName,
2139
- initialValue: initial,
2140
- options: [
2141
- { value: _BooleanStateProperty.FALSE.value, valueLabel: _BooleanStateProperty.FALSE.label },
2142
- { value: _BooleanStateProperty.TRUE.value, valueLabel: _BooleanStateProperty.TRUE.label }
2143
- ],
2144
- _type: "number"
2145
- };
2146
- }
2147
- propName;
2148
- static TRUE = { value: 1, label: "TRUE" };
2149
- static FALSE = { value: 0, label: "FALSE" };
2150
- propDefinition;
2151
- getIsTrueCondition() {
2152
- return {
2153
- kind: "numeric-condition",
2154
- referenceId: this.propName,
2155
- referenceLabel: this.propName + "[ BOOLEAN ]",
2156
- valueLabel: _BooleanStateProperty.TRUE.label,
2157
- value: _BooleanStateProperty.TRUE.value,
2158
- operator: "eq"
2159
- };
2160
- }
2161
- getIsFalseCondition() {
2162
- return {
2163
- kind: "numeric-condition",
2164
- referenceId: this.propName,
2165
- referenceLabel: this.propName + "[ BOOLEAN ]",
2166
- valueLabel: _BooleanStateProperty.FALSE.label,
2167
- value: _BooleanStateProperty.FALSE.value,
2168
- operator: "eq"
2169
- };
2170
- }
2171
- getSetTrueCommand() {
2172
- return {
2173
- kind: "STATE_MUTATE_COMMAND",
2174
- target: "STATE",
2175
- targetId: "STATE",
2176
- payload: {
2177
- mutation: { propName: this.propName, kind: "set-number", value: 1 }
2178
- }
2179
- };
2180
- }
2181
- getSetFalseCommand() {
2182
- return {
2183
- kind: "STATE_MUTATE_COMMAND",
2184
- target: "STATE",
2185
- targetId: "STATE",
2186
- payload: {
2187
- mutation: { propName: this.propName, kind: "set-number", value: 0 }
2188
- }
2189
- };
2190
- }
2191
- };
2192
-
2193
- // src/utils/ID.ts
2194
- var ID_LENGTH = 32;
2195
- var MIN_LENGTH = 10;
2196
- var isID = (idName, id) => {
2197
- if (typeof id !== "string")
2198
- return false;
2199
- return id.length >= MIN_LENGTH;
2200
- };
2201
- var createIDByName = (idName) => {
2202
- const letters = "abcdefghijklmnopqrstuvyz";
2203
- const all = letters + letters.toUpperCase();
2204
- let result = "";
2205
- for (let i = 0; i < ID_LENGTH; i++) {
2206
- const char = all.charAt(Math.floor(Math.random() * all.length));
2207
- result += char;
2208
- }
2209
- return result;
2210
- };
2211
- var createTypedIdSingleton = (idName) => {
2212
- const create = () => createIDByName(idName);
2213
- const is = (id) => isID(idName, id);
2214
- const validateOrThrow = (id) => {
2215
- if (!is(id)) {
2216
- throw new Error(`Invalid id: ${id}`);
2217
- }
2218
- return id;
2219
- };
2220
- const name = idName;
2221
- const ensure = (id) => {
2222
- return is(id) ? id : create();
2223
- };
2224
- return Object.freeze({ create, is, ensure, validateOrThrow, name });
2225
- };
2226
- var SchemaID = createTypedIdSingleton("SCHEMA");
2227
- var PageID = createTypedIdSingleton("PAGE");
2228
- // Annotate the CommonJS export names for ESM import in node:
2229
- 0 && (module.exports = {
2230
- BooleanStateProperty,
2231
- Condition,
2232
- DCss,
2233
- DEventHandler,
2234
- DState,
2235
- DStyle,
2236
- DUtil,
2237
- PageID,
2238
- Rule,
2239
- RuleEngine,
2240
- SchemaDto,
2241
- SchemaEngine,
2242
- SchemaID,
2243
- createTypedIdSingleton
2244
- });
2245
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3B1YmxpYy1hcGkudHMiLCAiLi4vc3JjL2R0by9TY2hlbWFEdG8udHMiLCAiLi4vc3JjL2NvbW1vbi9EVGltZXN0YW1wLnRzIiwgIi4uL3NyYy91dGlscy9EVXRpbC50cyIsICIuLi9zcmMvRGVsZW1lbnQvY3NzLnRzIiwgIi4uL3NyYy9EZWxlbWVudC9EU3R5bGUudHMiLCAiLi4vc3JjL0RlbGVtZW50L1ZpZGVvQ29udGFpbmVyLnRzIiwgIi4uL3NyYy9EZWxlbWVudC9BdWRpb0NvbnRhaW5lci50cyIsICIuLi9zcmMvc2VydmljZXMvRE1lZGlhLW1hbmFnZXIudHMiLCAiLi4vc3JjL2NvbW1hbmRzL0RDb21tYW5kQnVzLnRzIiwgIi4uL3NyYy9ldmVudHMvZXZlbnQtYnVzLnRzIiwgIi4uL3NyYy9wbGF5ZXIvaGlzdG9yeS1xdWUudHMiLCAiLi4vc3JjL3J1bGVzL2NvbmRpdGlvbi50cyIsICIuLi9zcmMvcnVsZXMvcnVsZS50cyIsICIuLi9zcmMvcnVsZXMvcnVsZS1lbmdpbmUudHMiLCAiLi4vc3JjL3BsYXllci9uZXh0LXF1ZS50cyIsICIuLi9zcmMvcGxheWVyL2RwbGF5ZXIudHMiLCAiLi4vc3JjL2V2ZW50LWhhbmRsZXJzL0RFdmVudEhhbmRsZXIudHMiLCAiLi4vc3JjL0RlbGVtZW50L0RFbGVtZW50LnRzIiwgIi4uL3NyYy9EZWxlbWVudC9EZGl2LnRzIiwgIi4uL3NyYy9EZWxlbWVudC9ESW1nLnRzIiwgIi4uL3NyYy9EZWxlbWVudC9EVGV4dC50cyIsICIuLi9zcmMvZW5naW5lL2VsZW1lbnQtZmFjdG9yeS50cyIsICIuLi9zcmMvZW5naW5lL0RQYWdlLnRzIiwgIi4uL3NyYy9lbmdpbmUvc2NhbGUudHMiLCAiLi4vc3JjL3NlcnZpY2VzL3Jlc291cmNlLXByb3ZpZGVyLnRzIiwgIi4uL3NyYy9jb21tb24vcmVzdWx0LnRzIiwgIi4uL3NyYy9zdGF0ZS9Ec3RhdGUudHMiLCAiLi4vc3JjL3N0YXRlL3N0YXRlLXNlcnZpY2UudHMiLCAiLi4vc3JjL2VuZ2luZS9TY2hlbWFFbmdpbmUudHMiLCAiLi4vc3JjL3N0YXRlL2Jvb2xlYW4tcHJvcGVydHkudHMiLCAiLi4vc3JjL3V0aWxzL0lELnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJleHBvcnQgeyBTY2hlbWFFbmdpbmUgfSBmcm9tIFwiLi9lbmdpbmUvU2NoZW1hRW5naW5lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kdG8vU2NoZW1hRHRvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kdG8vQW5pbWF0aW9uRHRvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kdG8vREVsZW1lbnQuZHRvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9ldmVudC1oYW5kbGVycy9ERXZlbnRIYW5kbGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb21tYW5kcy9EQ29tbWFuZFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZXZlbnRzL0RFdmVudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3J1bGVzL3J1bGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3J1bGVzL2ZhY3RcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3J1bGVzL3J1bGUtZW5naW5lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9ydWxlcy9jb25kaXRpb25cIjtcbmV4cG9ydCAqIGZyb20gXCIuL3N0YXRlL2Jvb2xlYW4tcHJvcGVydHlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3N0YXRlL0RzdGF0ZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vRGVsZW1lbnQvRFN0eWxlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9EZWxlbWVudC9EQXV0by1wbGF5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9EZWxlbWVudC9jc3NcIjtcblxuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHMvRFV0aWxcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzL0lEXCI7XG4iLCAiaW1wb3J0IHsgREF1dG9QbGF5U2VxdWVuY2UgfSBmcm9tIFwiLi4vRGVsZW1lbnQvREF1dG8tcGxheVwiO1xuaW1wb3J0IHsgREF1ZGlvRHRvLCBERWxlbWVudER0bywgREltZ0R0bywgRFZpZGVvRHRvIH0gZnJvbSBcIi4vREVsZW1lbnQuZHRvXCI7XG5pbXBvcnQgeyBSdWxlIH0gZnJvbSBcIi4uL3J1bGVzL3J1bGVcIjtcbmltcG9ydCB7IEZhY3QgfSBmcm9tIFwiLi4vcnVsZXMvZmFjdFwiO1xuaW1wb3J0IHsgUGFnZVF1ZUNvbW1hbmQgfSBmcm9tIFwiLi4vY29tbWFuZHMvRENvbW1hbmRcIjtcbmltcG9ydCB7IERTdGF0ZSB9IGZyb20gXCIuLi9zdGF0ZS9Ec3RhdGVcIjtcbmltcG9ydCB7IFBhZ2VJRCwgU2NoZW1hSUQgfSBmcm9tIFwiLi4vdXRpbHMvSURcIjtcblxuZXhwb3J0IHR5cGUgUGFnZVF1ZVJ1bGVzID0gUnVsZTxQYWdlUXVlQ29tbWFuZCwgbmV2ZXI+O1xuZXhwb3J0IGludGVyZmFjZSBQYWdlRHRvIHtcbiAgcmVhZG9ubHkgaWQ6IFBhZ2VJRDtcbiAgcmVhZG9ubHkgZWxlbWVudHM6IEFycmF5PERFbGVtZW50RHRvPjtcbiAgcmVhZG9ubHkgdGFncz86IHN0cmluZ1tdO1xuICByZWFkb25seSBtYWluVmlkZW9JZD86IHN0cmluZztcbiAgcmVhZG9ubHkgYmFja2dyb3VuZENvbG9yPzogc3RyaW5nO1xuICByZWFkb25seSB2aWRlbz86IEFycmF5PERWaWRlb0R0bz47XG4gIHJlYWRvbmx5IGF1ZGlvPzogQXJyYXk8REF1ZGlvRHRvPjtcbiAgcmVhZG9ubHkgYXV0b1BsYXlTZXF1ZW5jZT86IERBdXRvUGxheVNlcXVlbmNlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBhZ2VTZXF1ZW5jZUR0byB7XG4gIHJlYWRvbmx5IGlkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJ1bGVzOiBBcnJheTxQYWdlUXVlUnVsZXM+O1xuICByZWFkb25seSBwYWdlczogQXJyYXk8UGFnZUR0bz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2NoZW1hRHRvIHtcbiAgcmVhZG9ubHkgaWQ6IFNjaGVtYUlEO1xuICByZWFkb25seSBiYXNlSGVpZ2h0OiBudW1iZXI7XG4gIHJlYWRvbmx5IGJhc2VXaWR0aDogbnVtYmVyO1xuICByZWFkb25seSBiYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcbiAgcmVhZG9ubHkgcGFnZXM6IFBhZ2VEdG9bXTtcbiAgcmVhZG9ubHkgcnVsZXM6IEFycmF5PFBhZ2VRdWVSdWxlcz47XG4gIHJlYWRvbmx5IHN0YXRlUHJvcHM/OiBSZWFkb25seUFycmF5PERTdGF0ZS5Qcm9wPjtcbiAgcmVhZG9ubHkgc3RhdGVRdWVyaWVzPzogUmVhZG9ubHlBcnJheTxEU3RhdGUuU3RhdGVRdWVyeT47XG4gIHJlYWRvbmx5IHN0YXRlRnJvbUV2ZW50OiBSZWFkb25seUFycmF5PERTdGF0ZS5mcm9tRXZlbnRIYW5kbGVyPjtcbiAgcmVhZG9ubHkgcGFnZVNlcXVlbmNlcz86IEFycmF5PFBhZ2VTZXF1ZW5jZUR0bz47XG4gIHJlYWRvbmx5IHByZWRlZmluZWRGYWN0cz86IFJlYWRvbmx5QXJyYXk8RmFjdD47XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgU2NoZW1hRHRvIHtcbiAgZXhwb3J0IGNvbnN0IGdldFJlc291cmNlcyA9IChcbiAgICBzY2hlbWE6IFNjaGVtYUR0byxcbiAgKToge1xuICAgIHZpZGVvTGlzdDogUmVhZG9ubHlBcnJheTxEVmlkZW9EdG8+O1xuICAgIGF1ZGlvTGlzdDogUmVhZG9ubHlBcnJheTxEQXVkaW9EdG8+O1xuICAgIGltYWdlTGlzdDogUmVhZG9ubHlBcnJheTxESW1nRHRvPjtcbiAgfSA9PiB7XG4gICAgY29uc3QgeyBwYWdlcyB9ID0gc2NoZW1hO1xuICAgIGNvbnN0IHZpZGVvTGlzdCA9IHBhZ2VzLnJlZHVjZTxBcnJheTxEVmlkZW9EdG8+PigoYWNjLCBjdXJyKSA9PiB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjdXJyLnZpZGVvKSkge1xuICAgICAgICBhY2MucHVzaCguLi5jdXJyLnZpZGVvKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgW10pO1xuICAgIGNvbnN0IGF1ZGlvTGlzdDogQXJyYXk8REF1ZGlvRHRvPiA9IHBhZ2VzLnJlZHVjZTxBcnJheTxEQXVkaW9EdG8+PigoYWNjLCBjdXJyKSA9PiB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjdXJyLmF1ZGlvKSkge1xuICAgICAgICBhY2MucHVzaCguLi5jdXJyLmF1ZGlvKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgW10pO1xuXG4gICAgcmV0dXJuIHsgdmlkZW9MaXN0LCBhdWRpb0xpc3QsIGltYWdlTGlzdDogW10gfTtcbiAgfTtcbn1cbiIsICJleHBvcnQgdHlwZSBEVGltZXN0YW1wID0gbnVtYmVyICYgeyBfX3RpbWVzdGFtcF9fOiB0cnVlIH07XG5leHBvcnQgbmFtZXNwYWNlIERUaW1lc3RhbXAge1xuICAgIGV4cG9ydCBjb25zdCBub3cgPSAoKSA9PiBEYXRlLm5vdygpIGFzIERUaW1lc3RhbXA7XG4gICAgZXhwb3J0IHR5cGUgRGlmZiA9IG51bWJlciAmIHsgX19kaWZmX186IHRydWUgfTtcblxuICAgIGV4cG9ydCBjb25zdCBhZGRNaWxscyA9ICh0OiBEVGltZXN0YW1wLCBtczogbnVtYmVyKTogRFRpbWVzdGFtcCA9PiB7XG4gICAgICAgIGNvbnN0IHJlcyA9IHQgKyBNYXRoLmFicyhtcyk7XG4gICAgICAgIHJldHVybiByZXMgYXMgRFRpbWVzdGFtcDtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGRpZmYgPSAodDE6IERUaW1lc3RhbXAsIHQyOiBEVGltZXN0YW1wKTogRGlmZiA9PiB7XG4gICAgICAgIGNvbnN0IHQxQWJzID0gTWF0aC5hYnModDEpO1xuICAgICAgICBjb25zdCB0MkFicyA9IE1hdGguYWJzKHQyKTtcbiAgICAgICAgcmV0dXJuIE1hdGguYWJzKHQxQWJzIC0gdDJBYnMpIGFzIERpZmY7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBkaWZmTm93ID0gKHQ6IERUaW1lc3RhbXApOiBEaWZmID0+IHtcbiAgICAgICAgcmV0dXJuIGRpZmYodCwgbm93KCkpO1xuICAgIH07XG59XG4iLCAiZXhwb3J0IHR5cGUgUmFuZG9tT2JqZWN0SWQgPSBzdHJpbmcgJiB7IHJhbmRvbU9iamVjdElkOiB0cnVlIH07XG5leHBvcnQgbmFtZXNwYWNlIERVdGlsIHtcbiAgICBleHBvcnQgY29uc3QgcmFuZG9tU3RyaW5nID0gKGxlbmd0aDogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgICAgICAgY29uc3QgbGV0dGVycyA9IFwiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnh5elwiO1xuICAgICAgICBjb25zdCB1cHBlcmNhc2UgPSBsZXR0ZXJzLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgIGNvbnN0IGFsbCA9IGxldHRlcnMgKyB1cHBlcmNhc2U7XG4gICAgICAgIGNvbnN0IGFicyA9IE1hdGguYWJzKGxlbmd0aCk7XG4gICAgICAgIGxldCByZXN1bHQgPSBcIlwiO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWJzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGNoYXIgPSBhbGwuY2hhckF0KE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGFsbC5sZW5ndGgpKTtcbiAgICAgICAgICAgIHJlc3VsdCArPSBjaGFyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCByYW5kb21PYmplY3RJZCA9ICgpID0+IHJhbmRvbVN0cmluZygzMikgYXMgUmFuZG9tT2JqZWN0SWQ7XG5cbiAgICBleHBvcnQgY29uc3QgZGVsZXRlUHJvcCA9IDxPYmosIEtleSBleHRlbmRzIGtleW9mIE9iaj4ob2JqOiBPYmosIGtleTogS2V5KTogT21pdDxPYmosIEtleT4gPT4ge1xuICAgICAgICBkZWxldGUgb2JqW2tleV07XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBpc0luUmFuZ2UgPSAobWluOiBudW1iZXIsIG1heDogbnVtYmVyKSA9PiB7XG4gICAgICAgIHJldHVybiAodmFsdWU6IG51bWJlcikgPT4gdmFsdWUgPj0gbWluICYmIHZhbHVlIDw9IG1heDtcbiAgICB9O1xuICAgIGV4cG9ydCBjb25zdCBpc0luZmluaXR5ID0gKG51bWJlcjogbnVtYmVyKSA9PiB7XG4gICAgICAgIHJldHVybiBudW1iZXIgPT09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSB8fCBudW1iZXIgPT09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSB8fCBudW1iZXIgPT09IEluZmluaXR5O1xuICAgIH07XG4gICAgZXhwb3J0IHR5cGUgTm9uRW1wdHlBcnJheTxUPiA9IFtULCAuLi5UW11dO1xuICAgIGV4cG9ydCBjb25zdCBpc05vbkVtcHR5QXJyYXkgPSA8VD4oYXJyYXk6IEFycmF5PFQ+KTogYXJyYXkgaXMgTm9uRW1wdHlBcnJheTxUPiA9PiB7XG4gICAgICAgIHJldHVybiBhcnJheS5sZW5ndGggPiAwO1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgbmV2ZXJDaGVjayA9IChhcmdzOiBuZXZlcikgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhcIk9PUFM6IFRoaXMgdmFsdWUgc2xpcHBlZCB0aHJvdWdoIHRoZSBuZXZlci1jaGVja1wiLCBhcmdzKTtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGlzU3RyaW5nID0gKHN0cjogdW5rbm93bik6IHN0ciBpcyBzdHJpbmcgPT4gdHlwZW9mIHN0ciA9PT0gXCJzdHJpbmdcIjtcblxuICAgIGV4cG9ydCBjb25zdCBoYXNLZXkgPSA8VCBleHRlbmRzIHN0cmluZz4ob2JqOiB1bmtub3duLCBrZXk6IFQpOiBvYmogaXMgUmVjb3JkPHR5cGVvZiBrZXksIHVua25vd24+ID0+IHtcbiAgICAgICAgaWYgKCFpc1JlY29yZChvYmopKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSk7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBpc1JlY29yZCA9IChvYmo6IHVua25vd24pOiBvYmogaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT4ge1xuICAgICAgICBpZiAoIW9iaikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBvYmogIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvYmogPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGlzQm9vbCA9IChvYmo6IGJvb2xlYW4pOiBvYmogaXMgYm9vbGVhbiA9PiB0eXBlb2Ygb2JqID09PSBcImJvb2xlYW5cIjtcblxuICAgIGV4cG9ydCBjb25zdCBpc1RydWUgPSAoYm9vbDogYm9vbGVhbik6IGJvb2wgaXMgdHJ1ZSA9PiBib29sID09PSB0cnVlO1xuXG4gICAgZXhwb3J0IGNvbnN0IGlzRmFsc2UgPSAoYm9vbDogYm9vbGVhbik6IGJvb2wgaXMgZmFsc2UgPT4gYm9vbCA9PT0gZmFsc2U7XG5cbiAgICBleHBvcnQgY29uc3QgaXNEZWZpbmVkID0gKG9iajogdW5rbm93bik6IGJvb2xlYW4gPT4ge1xuICAgICAgICBjb25zdCBub3ROdWxsID0gb2JqICE9PSBudWxsO1xuICAgICAgICBjb25zdCBub3RVbmRlZmluZWQgPSBvYmogIT09IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIG5vdE51bGwgJiYgbm90VW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgaGFzS2luZCA9IChvYmo6IHVua25vd24pOiBvYmogaXMgeyByZWFkb25seSBraW5kOiBzdHJpbmcgfSA9PiB7XG4gICAgICAgIGlmICghaGFzS2V5KG9iaiwgXCJraW5kXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBvYmoua2luZCAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmoua2luZC5sZW5ndGggPiAwO1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgaGFzVmFsdWUgPSAob2JqOiB1bmtub3duKTogb2JqIGlzIHsgdmFsdWU6IHVua25vd24gfSA9PiB7XG4gICAgICAgIHJldHVybiBoYXNLZXkob2JqLCBcInZhbHVlXCIpO1xuICAgIH07XG4gICAgZXhwb3J0IGNvbnN0IGlzTnVtYmVyID0gKHZhbHVlPzogbnVtYmVyKTogdmFsdWUgaXMgbnVtYmVyID0+IHtcbiAgICAgICAgY29uc3QgaXNOdW1iZXIgPSB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCI7XG4gICAgICAgIGNvbnN0IG5vdE5hTiA9ICFOdW1iZXIuaXNOYU4odmFsdWUpO1xuICAgICAgICByZXR1cm4gaXNOdW1iZXIgJiYgbm90TmFOO1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgbWF4Rm4gPSAodXBwZXJMaW1pdDogbnVtYmVyKSA9PiB7XG4gICAgICAgIHJldHVybiAodmFsdWU6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKHZhbHVlLCB1cHBlckxpbWl0KTtcbiAgICAgICAgfTtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IG1pbkZuID0gKGxvd2VyTGltaXQ6IG51bWJlcikgPT4ge1xuICAgICAgICByZXR1cm4gKHZhbHVlOiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLm1pbih2YWx1ZSwgbG93ZXJMaW1pdCk7XG4gICAgICAgIH07XG4gICAgfTtcbn1cbiIsICJpbXBvcnQgeyBEVXRpbCB9IGZyb20gXCIuLi91dGlscy9EVXRpbFwiO1xuXG5leHBvcnQgbmFtZXNwYWNlIERDc3Mge1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgUHgge1xuICAgICAgICByZWFkb25seSBfdW5pdDogXCJweFwiO1xuICAgICAgICByZWFkb25seSB2YWx1ZTogbnVtYmVyO1xuICAgIH1cblxuICAgIGV4cG9ydCB0eXBlIExlbmd0aFN0cmluZyA9IGAke251bWJlcn1weGAgfCBgJHtudW1iZXJ9JWA7XG4gICAgZXhwb3J0IGludGVyZmFjZSBQZXJjZW50IHtcbiAgICAgICAgcmVhZG9ubHkgX3VuaXQ6IFwicGVyY2VudFwiO1xuICAgICAgICByZWFkb25seSB2YWx1ZTogbnVtYmVyO1xuICAgIH1cblxuICAgIGV4cG9ydCB0eXBlIExlbmd0aFVuaXQgPSBQeCB8IFBlcmNlbnQ7XG5cbiAgICAvKipcbiAgICAgKiBXaWxsIHNjYWxlIHRvIDMlIG9mIGJhc2VTY2FsZVxuICAgICAqIEBwYXJhbSB1bml0XG4gICAgICogQHBhcmFtIHNjYWxlXG4gICAgICovXG4gICAgZXhwb3J0IGNvbnN0IHRvU3RyaW5nID0gKHVuaXQ6IFJlYWRvbmx5PExlbmd0aFVuaXQ+LCBzY2FsZTogbnVtYmVyKTogTGVuZ3RoU3RyaW5nID0+IHtcbiAgICAgICAgY29uc3QgY2xhbXBlZFNjYWxlID0gTWF0aC5tYXgoc2NhbGUsIDAuMDMpO1xuICAgICAgICBpZiAodW5pdC5fdW5pdCA9PT0gXCJweFwiKSB7XG4gICAgICAgICAgICBpZiAodW5pdC52YWx1ZSA8IDAuMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIjBweFwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCByb3VuZGVkID0gTWF0aC5yb3VuZCh1bml0LnZhbHVlICogY2xhbXBlZFNjYWxlKTtcbiAgICAgICAgICAgIGNvbnN0IGNsYW1wZWQgPSBNYXRoLm1heChyb3VuZGVkLCAxKTtcbiAgICAgICAgICAgIHJldHVybiAoY2xhbXBlZCArIFwicHhcIikgYXMgTGVuZ3RoU3RyaW5nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAodW5pdC52YWx1ZSArIFwiJVwiKSBhcyBMZW5ndGhTdHJpbmc7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBpc0xlbmd0aFVuaXQgPSAodW5pdD86IExlbmd0aFVuaXQpOiB1bml0IGlzIExlbmd0aFVuaXQgPT4ge1xuICAgICAgICBpZiAoIXVuaXQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1bml0S2V5OiBrZXlvZiBMZW5ndGhVbml0ID0gXCJfdW5pdFwiO1xuICAgICAgICBjb25zdCB2YWx1ZUtleToga2V5b2YgTGVuZ3RoVW5pdCA9IFwidmFsdWVcIjtcbiAgICAgICAgY29uc3QgaGFzVW5pdEtleSA9IERVdGlsLmhhc0tleSh1bml0LCB1bml0S2V5KTtcbiAgICAgICAgY29uc3QgaGFzVmFsdWVLZXkgPSBEVXRpbC5oYXNLZXkodW5pdCwgdmFsdWVLZXkpO1xuICAgICAgICByZXR1cm4gaGFzVW5pdEtleSAmJiBoYXNWYWx1ZUtleTtcbiAgICB9O1xufVxuIiwgImltcG9ydCB7IERDc3MgfSBmcm9tIFwiLi9jc3NcIjtcbmltcG9ydCB7IEVsZW1lbnRLZXlOYW1lcyB9IGZyb20gXCIuL0RTdHlsZS11dGlsc1wiO1xuaW1wb3J0IHsgRFV0aWwgfSBmcm9tIFwiLi4vdXRpbHMvRFV0aWxcIjtcblxudHlwZSBEU3R5bGUyID0gQ1NTU3R5bGVEZWNsYXJhdGlvbjtcbmV4cG9ydCBpbnRlcmZhY2UgRFN0eWxlIHtcbiAgICBvcGFjaXR5OiBudW1iZXI7XG4gICAgYmFja2dyb3VuZENvbG9yOiBzdHJpbmc7XG4gICAgdmlzaWJpbGl0eTogXCJ2aXNpYmxlXCIgfCBcImhpZGRlblwiO1xuICAgIGN1cnNvcjpcbiAgICAgICAgfCBcInBvaW50ZXJcIlxuICAgICAgICB8IFwiaGVscFwiXG4gICAgICAgIHwgXCJjb3B5XCJcbiAgICAgICAgfCBcIndhaXRcIlxuICAgICAgICB8IFwibm90LWFsbG93ZWRcIlxuICAgICAgICB8IFwiY29udGV4dC1tZW51XCJcbiAgICAgICAgfCBcIm1vdmVcIlxuICAgICAgICB8IFwiZ3JhYmJpbmdcIlxuICAgICAgICB8IFwiZ3JhYlwiXG4gICAgICAgIHwgXCJ6b29tLWluXCJcbiAgICAgICAgfCBcInpvb20tb3V0XCJcbiAgICAgICAgfCBcIm5vbmVcIlxuICAgICAgICB8IFwiYXV0b1wiXG4gICAgICAgIHwgXCJkZWZhdWx0XCI7XG5cbiAgICAvLyBQT1NJVElPTlxuICAgIGg6IG51bWJlcjtcbiAgICB3OiBudW1iZXI7XG4gICAgeDogbnVtYmVyO1xuICAgIHk6IG51bWJlcjtcblxuICAgIC8vIEJPUkRFUlNcbiAgICBib3JkZXJTdHlsZTogXCJzb2xpZFwiIHwgXCJub25lXCIgfCBcImRvdHRlZFwiIHwgXCJkYXNoZWRcIjtcbiAgICBib3JkZXJSYWRpdXM6IERDc3MuUHggfCBEQ3NzLlBlcmNlbnQ7XG4gICAgYm9yZGVyV2lkdGg6IERDc3MuUHg7XG4gICAgYm9yZGVyQ29sb3I6IHN0cmluZztcblxuICAgIG1hcmdpbjogRENzcy5QeCB8IERDc3MuUGVyY2VudDtcbiAgICBwYWRkaW5nOiBEQ3NzLlB4IHwgRENzcy5QZXJjZW50O1xuXG4gICAgLy8gVHJhbnNsYXRlXG4gICAgdHJhbnNmb3JtOiBzdHJpbmc7XG4gICAgdHJhbnNsYXRlOiBzdHJpbmc7XG5cbiAgICAvLyBURVhUXG4gICAgZm9udFNpemU6IERDc3MuUHg7XG4gICAgdGV4dENvbG9yOiBzdHJpbmc7XG4gICAgZm9udFdlaWdodDogMTAwIHwgMjAwIHwgMzAwIHwgNDAwIHwgNTAwIHwgNjAwIHwgNzAwIHwgODAwIHwgOTAwO1xuICAgIHRleHRBbGlnbjogXCJyaWdodFwiIHwgXCJsZWZ0XCIgfCBcImNlbnRlclwiO1xuICAgIGxldHRlclNwYWNpbmc6IERDc3MuUHg7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgRFN0eWxlIHtcbiAgICBleHBvcnQgY29uc3Qgbm9ybWFsaXplID0gPFQgZXh0ZW5kcyBIVE1MRWxlbWVudD4oZWw6IFQpOiBUID0+IHtcbiAgICAgICAgZWwuc3R5bGUucGFkZGluZyA9IFwiMFwiO1xuICAgICAgICBlbC5zdHlsZS5tYXJnaW4gPSBcIjBcIjtcbiAgICAgICAgZWwuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG4gICAgICAgIGVsLnN0eWxlLmJveFNpemluZyA9IFwiYm9yZGVyLWJveFwiO1xuICAgICAgICByZXR1cm4gZWw7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBhcHBseVN0eWxlcyA9IDxUIGV4dGVuZHMgSFRNTEVsZW1lbnQ+KGVsOiBULCBzdHlsZTogUGFydGlhbDxEU3R5bGU+LCBzY2FsZTogbnVtYmVyKTogVCA9PiB7XG4gICAgICAgIC8vIGNvbnN0IHNjYWxlUHggPSBEQ3NzLnRvU3RyaW5nQ3JlKHRoaXMuc2NhbGUpO1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICB4LFxuICAgICAgICAgICAgeSxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgIGJvcmRlckNvbG9yLFxuICAgICAgICAgICAgYm9yZGVyV2lkdGgsXG4gICAgICAgICAgICBib3JkZXJSYWRpdXMsXG4gICAgICAgICAgICBib3JkZXJTdHlsZSxcbiAgICAgICAgICAgIHcsXG4gICAgICAgICAgICBvcGFjaXR5LFxuICAgICAgICAgICAgY3Vyc29yLFxuICAgICAgICAgICAgZm9udFNpemUsXG4gICAgICAgICAgICBmb250V2VpZ2h0LFxuICAgICAgICAgICAgdGV4dENvbG9yLFxuICAgICAgICAgICAgdGV4dEFsaWduLFxuICAgICAgICAgICAgdHJhbnNsYXRlLFxuICAgICAgICAgICAgbWFyZ2luLFxuICAgICAgICAgICAgcGFkZGluZyxcbiAgICAgICAgICAgIGxldHRlclNwYWNpbmcsXG4gICAgICAgICAgICBoLFxuICAgICAgICAgICAgdHJhbnNmb3JtLFxuICAgICAgICAgICAgdmlzaWJpbGl0eSxcbiAgICAgICAgfSA9IHN0eWxlO1xuXG4gICAgICAgIC8vIHRoaXMuZWwuc3R5bGUuZm9udFdlaWdodCA9ICc5MDAnO1xuICAgICAgICBpZiAoYmFja2dyb3VuZENvbG9yKSB7XG4gICAgICAgICAgICBlbC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBiYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3Vyc29yKSB7XG4gICAgICAgICAgICBlbC5zdHlsZS5jdXJzb3IgPSBjdXJzb3I7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHJhbnNmb3JtKSB7XG4gICAgICAgICAgICBlbC5zdHlsZS50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGV4dENvbG9yKSB7XG4gICAgICAgICAgICBlbC5zdHlsZS5jb2xvciA9IHRleHRDb2xvcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGV4dEFsaWduKSB7XG4gICAgICAgICAgICBlbC5zdHlsZS50ZXh0QWxpZ24gPSB0ZXh0QWxpZ247XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYm9yZGVyQ29sb3IpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmJvcmRlckNvbG9yID0gYm9yZGVyQ29sb3I7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYm9yZGVyV2lkdGgpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmJvcmRlcldpZHRoID0gRENzcy50b1N0cmluZyhib3JkZXJXaWR0aCwgc2NhbGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmb250V2VpZ2h0KSB7XG4gICAgICAgICAgICBlbC5zdHlsZS5mb250V2VpZ2h0ID0gZm9udFdlaWdodCArIFwiXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJvcmRlclN0eWxlKSB7XG4gICAgICAgICAgICBlbC5zdHlsZS5ib3JkZXJTdHlsZSA9IGJvcmRlclN0eWxlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmb250U2l6ZSkge1xuICAgICAgICAgICAgZWwuc3R5bGUuZm9udFNpemUgPSBEQ3NzLnRvU3RyaW5nKGZvbnRTaXplLCBzY2FsZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoRFV0aWwuaXNOdW1iZXIoeCkpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmxlZnQgPSB4ICsgXCIlXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKERVdGlsLmlzTnVtYmVyKHkpKSB7XG4gICAgICAgICAgICBlbC5zdHlsZS5ib3R0b20gPSB5ICsgXCIlXCI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoRFV0aWwuaXNOdW1iZXIoaCkpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmhlaWdodCA9IGggKyBcIiVcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoRFV0aWwuaXNOdW1iZXIodykpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLndpZHRoID0gdyArIFwiJVwiO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKERDc3MuaXNMZW5ndGhVbml0KGJvcmRlclJhZGl1cykpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLmJvcmRlclJhZGl1cyA9IERDc3MudG9TdHJpbmcoYm9yZGVyUmFkaXVzLCBzY2FsZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGV0dGVyU3BhY2luZykge1xuICAgICAgICAgICAgZWwuc3R5bGUubGV0dGVyU3BhY2luZyA9IERDc3MudG9TdHJpbmcobGV0dGVyU3BhY2luZywgc2NhbGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXJnaW4pIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLm1hcmdpbiA9IERDc3MudG9TdHJpbmcobWFyZ2luLCBzY2FsZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhZGRpbmcpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLnBhZGRpbmcgPSBEQ3NzLnRvU3RyaW5nKHBhZGRpbmcsIHNjYWxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChEVXRpbC5pc051bWJlcihvcGFjaXR5KSkge1xuICAgICAgICAgICAgZWwuc3R5bGUub3BhY2l0eSA9IG9wYWNpdHkgKyBcIlwiO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZpc2liaWxpdHkpIHtcbiAgICAgICAgICAgIGVsLnN0eWxlLnZpc2liaWxpdHkgPSB2aXNpYmlsaXR5O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVsO1xuICAgIH07XG4gICAgLy8gY29uc3QgcHJvcE5hbWVzID0gbmV3IFNldCguLi5FbGVtZW50S2V5TmFtZXMpO1xuICAgIC8vIGV4cG9ydCBjb25zdCB2YWxpZEtleSA9IChrZXlOYW1lOiBzdHJpbmcpID0+IHByb3BOYW1lcy5oYXMoa2V5TmFtZSk7XG59XG4iLCAiaW1wb3J0IHsgRFZpZGVvRHRvIH0gZnJvbSBcIi4uL2R0by9ERWxlbWVudC5kdG9cIjtcbmltcG9ydCB7IERUaW1lc3RhbXAgfSBmcm9tIFwiLi4vY29tbW9uL0RUaW1lc3RhbXBcIjtcbmltcG9ydCB7IERFdmVudERpc3BhdGNoZXIgfSBmcm9tIFwiLi4vZXZlbnRzL2V2ZW50LWJ1c1wiO1xuaW1wb3J0IHsgU2NhbGVTZXJ2aWNlIH0gZnJvbSBcIi4uL2VuZ2luZS9zY2FsZVwiO1xuaW1wb3J0IHsgRFN0eWxlIH0gZnJvbSBcIi4vRFN0eWxlXCI7XG5pbXBvcnQgeyBEVXRpbCB9IGZyb20gXCIuLi91dGlscy9EVXRpbFwiO1xuXG5jb25zdCBBQk9SVF9QTEFZX1RPX0VORCA9IFwiQUJPUlRfUExBWV9UT19FTkRcIjtcbmV4cG9ydCBpbnRlcmZhY2UgQ2FuUGxheVRvRW5kIHtcbiAgICBwbGF5VG9FbmQoKTogUHJvbWlzZTxib29sZWFuPjtcbn1cblxuZXhwb3J0IGNsYXNzIFZpZGVvQ29udGFpbmVyIGltcGxlbWVudHMgQ2FuUGxheVRvRW5kIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IFRBRzogc3RyaW5nO1xuICAgIHByaXZhdGUgZHRvPzogRFZpZGVvRHRvO1xuICAgIHByaXZhdGUgZGVmYXVsdFN0eWxlczogUGFydGlhbDxEU3R5bGU+ID0geyBoOiA0NSwgdzogMTAwLCB2aXNpYmlsaXR5OiBcImhpZGRlblwiLCB5OiA1NSB9O1xuXG4gICAgcGF1c2UoKSB7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdCh7XG4gICAgICAgICAgICBraW5kOiBcIlZJREVPX1BBVVNFRF9FVkVOVFwiLFxuICAgICAgICAgICAgZGF0YToge30sXG4gICAgICAgICAgICBwcm9kdWNlcjogXCJEVmlkZW9cIixcbiAgICAgICAgICAgIHByb2R1Y2VySWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICB0aW1lc3RhbXA6IERUaW1lc3RhbXAubm93KCksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmVsLnBhdXNlKCk7XG4gICAgfVxuXG4gICAgcGxheSh1cmw6IHN0cmluZykge1xuICAgICAgICBpZiAodGhpcy5lbC5zcmMgIT09IHVybCkge1xuICAgICAgICAgICAgdGhpcy5lbC5zcmMgPSB1cmw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvZHVjZXJJZCA9IHRoaXMuZHRvPy5pZCA/PyBcIkRWaWRlb1wiO1xuICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAga2luZDogXCJWSURFT19QTEFZX0VWRU5UXCIsXG4gICAgICAgICAgICBkYXRhOiB7fSxcbiAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRWaWRlb1wiLFxuICAgICAgICAgICAgcHJvZHVjZXJJZCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZWxcbiAgICAgICAgICAgIC5wbGF5KClcbiAgICAgICAgICAgIC50aGVuKChyZXMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXMpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIC8vIGlmKHRoaXMuZWwuc3JjICE9PSB1cmwpIHtcbiAgICAgICAgLy8gICAgIHRoaXMuXG4gICAgICAgIC8vIH1cbiAgICB9XG5cbiAgICBhc3luYyBwbGF5VG9FbmQoKSB7XG4gICAgICAgIHRoaXMuZWwudm9sdW1lID0gMTtcbiAgICAgICAgY29uc3QgdXJsID0gdGhpcy5kdG8/LnVybDtcbiAgICAgICAgaWYgKCF1cmwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBlbmRlZE9yRXJyb3JlZCA9IG5ldyBQcm9taXNlPGJvb2xlYW4+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgIFwiZW5kZWRcIixcbiAgICAgICAgICAgICAgICAgICAgKF8pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHsgb25jZTogdHJ1ZSB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgIFwiZXJyb3JcIixcbiAgICAgICAgICAgICAgICAgICAgKF8pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7IG9uY2U6IHRydWUgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICAgICBBQk9SVF9QTEFZX1RPX0VORCxcbiAgICAgICAgICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJDQVRDSEVEIEFCQk9SVC5cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoXCJBYm9ydGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7IG9uY2U6IHRydWUgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiUExBWVwiKTtcbiAgICAgICAgICAgIHRoaXMucGxheSh1cmwpO1xuICAgICAgICAgICAgYXdhaXQgZW5kZWRPckVycm9yZWQ7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coZSk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLlRBRyArIFwiIGZpbmFsbHkgYmxvY2sgcGxheVRvRW5kKCkgY29tcGxldGVkIHZpZGVvSWQ6IFwiICsgdGhpcy5kdG8/LmlkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGVsOiBIVE1MVmlkZW9FbGVtZW50LFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50QnVzOiBERXZlbnREaXNwYXRjaGVyLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IHNjYWxlOiBTY2FsZVNlcnZpY2UgLy8gZHRvPzogRFZpZGVvRHRvXG4gICAgKSB7XG4gICAgICAgIHRoaXMuVEFHID0gXCJbIERfVmlkZW8gXSA6IFwiO1xuICAgICAgICB0aGlzLmVsLmNvbnRyb2xzID0gZmFsc2U7XG4gICAgICAgIERTdHlsZS5ub3JtYWxpemUodGhpcy5lbCk7XG4gICAgICAgIERTdHlsZS5hcHBseVN0eWxlcyh0aGlzLmVsLCB0aGlzLmRlZmF1bHRTdHlsZXMsIHRoaXMuc2NhbGUuc2NhbGUpO1xuXG4gICAgICAgIHRoaXMuZWwub25lbmRlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdCh7XG4gICAgICAgICAgICAgICAga2luZDogXCJWSURFT19FTkRFRF9FVkVOVFwiLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgICAgICAgICBwcm9kdWNlcjogXCJEVmlkZW9cIixcbiAgICAgICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgICAgIGRhdGE6IHt9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZWwub25wbGF5ID0gKCkgPT4ge1xuICAgICAgICAgICAgLy8gVE9ETyBMT0dHIElOVEVSTkFMIFNUQVRFX0NIQU5HRVMuXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5lbC5vbnBhdXNlID0gKCkgPT4ge307XG4gICAgICAgIHRoaXMuZWwub25lcnJvciA9ICgpID0+IHt9O1xuICAgICAgICB0aGlzLmVsLm9uY2FucGxheSA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQodGhpcy5UQUcgKyBcIlJFQURZIFRPIFBMQVlcIik7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIkR1cmF0aW9uOiBcIiArIHRoaXMuZWwuZHVyYXRpb24pO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJJZDogXCIgKyB0aGlzLmlkKTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiQ3VycmVudCBUaW1lOiBcIiArIHRoaXMuZWwuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJBdWRvUGxheTogXCIgKyB0aGlzLmVsLmF1dG9wbGF5KTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUuZ3JvdXBFbmQoKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5lbC5vbmxvYWRlZG1ldGFkYXRhID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZHVyYXRpb24gPSB0aGlzLmVsLmR1cmF0aW9uO1xuICAgICAgICAgICAgY29uc3QgaXNJbmZpbml0eSA9IERVdGlsLmlzSW5maW5pdHkoZHVyYXRpb24pO1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KHtcbiAgICAgICAgICAgICAgICBraW5kOiBcIlZJREVPX0xPQURFRF9NRVRBREFUQV9FVkVOVFwiLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgICAgICAgICBwcm9kdWNlcjogXCJEVmlkZW9cIixcbiAgICAgICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgICAgIGRhdGE6IHsgZHVyYXRpb24sIGlzSW5maW5pdHkgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICAvLyBUT0RPIFVTRSBUSElTIFNZTlRBWD9cbiAgICAgICAgdGhpcy5lbC5vbmR1cmF0aW9uY2hhbmdlID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZHVyYXRpb24gPSB0aGlzLmVsLmR1cmF0aW9uO1xuICAgICAgICAgICAgY29uc3QgaXNJbmZpbml0eSA9IERVdGlsLmlzSW5maW5pdHkoZHVyYXRpb24pO1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KHtcbiAgICAgICAgICAgICAgICBraW5kOiBcIlZJREVPX0RVUkFUSU9OX0NIQU5HRV9FVkVOVFwiLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRWaWRlb1wiLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VySWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICAgICAgICAgIGRhdGE6IHsgZHVyYXRpb24sIGlzSW5maW5pdHkgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGdldFN0YXRzKCkge1xuICAgICAgICBjb25zdCBkdXJhdGlvbiA9IHRoaXMuZWwuZHVyYXRpb247XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gdGhpcy5lbC5jdXJyZW50VGltZTtcbiAgICAgICAgY29uc3Qgdm9sdW1lID0gdGhpcy5lbC52b2x1bWU7XG4gICAgICAgIGNvbnN0IGlzQ29ubmVjdGVkID0gdGhpcy5lbC5pc0Nvbm5lY3RlZDtcbiAgICAgICAgY29uc3QgcGxheWJhY2tRdWFsaXR5ID0gdGhpcy5lbC5nZXRWaWRlb1BsYXliYWNrUXVhbGl0eSgpO1xuICAgICAgICBjb25zdCBkZWZhdWx0UGxheWJhY2tSYXRlID0gdGhpcy5lbC5kZWZhdWx0UGxheWJhY2tSYXRlO1xuICAgICAgICBjb25zdCBwYXVzZWQgPSB0aGlzLmVsLnBhdXNlZDtcbiAgICAgICAgY29uc3QgcGxheWVkID0gdGhpcy5lbC5wbGF5ZWQ7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGR1cmF0aW9uLFxuICAgICAgICAgICAgcGF1c2VkLFxuICAgICAgICAgICAgcGxheWVkLFxuICAgICAgICAgICAgY3VycmVudFRpbWUsXG4gICAgICAgICAgICB2b2x1bWUsXG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCxcbiAgICAgICAgICAgIHBsYXliYWNrUXVhbGl0eSxcbiAgICAgICAgICAgIGRlZmF1bHRQbGF5YmFja1JhdGUsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc2V0RHRvKGR0bzogRFZpZGVvRHRvKSB7XG4gICAgICAgIHRoaXMuZHRvID0gZHRvO1xuICAgICAgICB0aGlzLmVsLnZvbHVtZSA9IDE7XG4gICAgICAgIHRoaXMuc2V0U3R5bGUoZHRvLnN0eWxlKTtcbiAgICAgICAgdGhpcy5lbC5zcmMgPSBkdG8udXJsO1xuICAgICAgICB0aGlzLmVsLmxvYWQoKTtcbiAgICB9XG5cbiAgICBnZXRDdXJyZW50RHRvKCk6IERWaWRlb0R0byB8IGZhbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZHRvID8/IGZhbHNlO1xuICAgIH1cblxuICAgIHNldFN0eWxlKHN0eWxlczogUGFydGlhbDxEU3R5bGU+KSB7XG4gICAgICAgIERTdHlsZS5hcHBseVN0eWxlcyh0aGlzLmVsLCBzdHlsZXMsIHRoaXMuc2NhbGUuc2NhbGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0IGlkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kdG8/LmlkID8/IFwiRFZpZGVvXCI7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHt9XG59XG4iLCAiaW1wb3J0IHsgQ2FuUGxheVRvRW5kIH0gZnJvbSBcIi4vVmlkZW9Db250YWluZXJcIjtcbmltcG9ydCB7IERBdWRpb0R0byB9IGZyb20gXCIuLi9kdG8vREVsZW1lbnQuZHRvXCI7XG5pbXBvcnQgeyBERXZlbnREaXNwYXRjaGVyIH0gZnJvbSBcIi4uL2V2ZW50cy9ldmVudC1idXNcIjtcbmltcG9ydCB7IERUaW1lc3RhbXAgfSBmcm9tIFwiLi4vY29tbW9uL0RUaW1lc3RhbXBcIjtcblxuZXhwb3J0IGNsYXNzIEF1ZGlvQ29udGFpbmVyIGltcGxlbWVudHMgQ2FuUGxheVRvRW5kIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IFRBRyA9IFwiWyBEQXVkaW8gXTogXCI7XG4gICAgcHJvdGVjdGVkIGR0bzogREF1ZGlvRHRvIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBlbDogSFRNTEF1ZGlvRWxlbWVudDtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGV2ZW50QnVzOiBERXZlbnREaXNwYXRjaGVyKSB7XG4gICAgICAgIHRoaXMuZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYXVkaW9cIik7XG4gICAgICAgIHRoaXMuZWwuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG4gICAgICAgIHRoaXMuZWwuc3R5bGUudmlzaWJpbGl0eSA9IFwiaGlkZGVuXCI7XG4gICAgICAgIC8vIHRoaXMuZWwub25cbiAgICAgICAgdGhpcy5vbkxvYWQgPSB0aGlzLm9uTG9hZC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmVsLm9ubG9hZCA9IHRoaXMub25Mb2FkO1xuICAgICAgICB0aGlzLm9uTG9hZGVkTWV0YWRhdGEgPSB0aGlzLm9uTG9hZGVkTWV0YWRhdGEuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5lbC5vbmxvYWRlZG1ldGFkYXRhID0gdGhpcy5vbkxvYWRlZE1ldGFkYXRhO1xuICAgICAgICB0aGlzLmVsLm9ucGxheSA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vIFRPRE9cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vbkNhblBsYXlUaHJvdWdoID0gdGhpcy5vbkNhblBsYXlUaHJvdWdoLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuZWwub25jYW5wbGF5dGhyb3VnaCA9IHRoaXMub25DYW5QbGF5VGhyb3VnaDtcbiAgICAgICAgdGhpcy5lbC5vbmVuZGVkID0gKF8pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHRoaXMuZWwuc3JjO1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KHtcbiAgICAgICAgICAgICAgICBraW5kOiBcIkFVRElPX0VOREVEX0VWRU5UXCIsXG4gICAgICAgICAgICAgICAgZGF0YTogeyB1cmwgfSxcbiAgICAgICAgICAgICAgICBwcm9kdWNlcjogXCJEQXVkaW9cIixcbiAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERUaW1lc3RhbXAubm93KCksXG4gICAgICAgICAgICAgICAgcHJvZHVjZXJJZDogdGhpcy5pZCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmVsLm9uZHVyYXRpb25jaGFuZ2UgPSAoXzogRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGR1cmF0aW9uID0gdGhpcy5lbC5kdXJhdGlvbjtcbiAgICAgICAgICAgIGNvbnN0IGlzSW5maW5pdHkgPSBkdXJhdGlvbiA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KHtcbiAgICAgICAgICAgICAgICBraW5kOiBcIkFVRElPX0RVUkFUSU9OX0NIQU5HRV9FVkVOVFwiLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgICAgICAgICBwcm9kdWNlcjogXCJEQXVkaW9cIixcbiAgICAgICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgICAgIGRhdGE6IHsgZHVyYXRpb246IHRoaXMuZWwuZHVyYXRpb24sIGlzSW5maW5pdHkgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHNldEF1ZGlvKGR0bzogREF1ZGlvRHRvKSB7XG4gICAgICAgIHRoaXMuZHRvID0gZHRvO1xuICAgICAgICB0aGlzLmVsLnNyYyA9IGR0by51cmw7XG4gICAgICAgIHRoaXMuZWwubG9hZCgpO1xuICAgIH1cblxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLmVsLnBhdXNlKCk7XG4gICAgICAgICAgICB0aGlzLmVsLnNyYyA9IFwiXCI7XG4gICAgICAgICAgICB0aGlzLmVsLmxvYWQoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwYXVzZSgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuZWwucGF1c2UoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gVE9ETyBFTUlUIEVSUk9SIEVWRU5ULlxuICAgICAgICAgICAgY29uc29sZS5sb2coZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwbGF5KHVybDogc3RyaW5nKSB7XG4gICAgICAgIGlmICh0aGlzLmVsLnNyYyAhPT0gdXJsKSB7XG4gICAgICAgICAgICB0aGlzLmVsLnNyYyA9IHVybDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAga2luZDogXCJBVURJT19QTEFZX0VWRU5UXCIsXG4gICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgZGF0YToge30sXG4gICAgICAgICAgICBwcm9kdWNlcjogXCJEQXVkaW9cIixcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZWxcbiAgICAgICAgICAgIC5wbGF5KClcbiAgICAgICAgICAgIC50aGVuKChyZXMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXMpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25Mb2FkZWRNZXRhZGF0YShfOiBFdmVudCkge1xuICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAga2luZDogXCJBVURJT19NRVRBREFUQV9MT0FERURfRVZFTlRcIixcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRBdWRpb1wiLFxuICAgICAgICAgICAgcHJvZHVjZXJJZDogdGhpcy5pZCxcbiAgICAgICAgICAgIGRhdGE6IHt9LFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbkxvYWQoXzogRXZlbnQpIHtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KHtcbiAgICAgICAgICAgIGtpbmQ6IFwiQVVESU9fTE9BRF9FVkVOVFwiLFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICAgICAgcHJvZHVjZXI6IFwiREF1ZGlvXCIsXG4gICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgZGF0YToge30sXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyh0aGlzLlRBRyArIGV2ZW50LnR5cGUpO1xuICAgIH1cblxuICAgIGdldCBpZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZHRvPy5pZCA/PyBcIkRBdWRpb1wiO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25DYW5QbGF5VGhyb3VnaChfOiBFdmVudCkge1xuICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAga2luZDogXCJBVURJT19DQU5fUExBWV9USFJPVUdIX0VWRU5UXCIsXG4gICAgICAgICAgICBkYXRhOiB7fSxcbiAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRBdWRpb1wiLFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEVGltZXN0YW1wLm5vdygpLFxuICAgICAgICAgICAgcHJvZHVjZXJJZDogdGhpcy5pZCxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gcHJpdmF0ZSBvblBsYXkoXzogRXZlbnQpIHt9XG5cbiAgICBhc3luYyBwbGF5VG9FbmQoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIGNvbnN0IGVuZGVkT3JFcnJvcmVkID0gbmV3IFByb21pc2U8Ym9vbGVhbj4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICBcImVuZGVkXCIsXG4gICAgICAgICAgICAgICAgKF8pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coZSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7IG9uY2U6IHRydWUgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICBcImVycm9yXCIsXG4gICAgICAgICAgICAgICAgKF8pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coZSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgeyBvbmNlOiB0cnVlIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5wbGF5KHRoaXMuZWwuc3JjKTtcbiAgICAgICAgICAgIGF3YWl0IGVuZGVkT3JFcnJvcmVkO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIFRPRE8gTEVUIFBBUkVOVCBERUFMIFdJVEggRVJST1JTPyBUSEUgTUFOQUdFUj8/IE1BTkFHRVJTIENBTEwgQUJPUlQuXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdCh7XG4gICAgICAgICAgICAgICAga2luZDogXCJBVURJT19FUlJPUl9FVkVOVFwiLFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgICAgICAgICBwcm9kdWNlcjogXCJEQXVkaW9cIixcbiAgICAgICAgICAgICAgICBwcm9kdWNlcklkOiB0aGlzLmlkLFxuICAgICAgICAgICAgICAgIGRhdGE6IHsgZXJyb3I6IGUgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IFBhZ2VEdG8gfSBmcm9tIFwiLi4vZHRvL1NjaGVtYUR0b1wiO1xuaW1wb3J0IHsgVmlkZW9Db250YWluZXIgfSBmcm9tIFwiLi4vRGVsZW1lbnQvVmlkZW9Db250YWluZXJcIjtcbmltcG9ydCB7IEF1ZGlvQ29udGFpbmVyIH0gZnJvbSBcIi4uL0RlbGVtZW50L0F1ZGlvQ29udGFpbmVyXCI7XG5pbXBvcnQgeyBBdXRvUGxheUVsZW1lbnQsIERBdXRvUGxheVNlcXVlbmNlIH0gZnJvbSBcIi4uL0RlbGVtZW50L0RBdXRvLXBsYXlcIjtcbmltcG9ydCB7IERDb21tYW5kQnVzIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kQnVzXCI7XG5pbXBvcnQgeyBEQ29tbWFuZCB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZFwiO1xuaW1wb3J0IHsgRFRpbWVzdGFtcCB9IGZyb20gXCIuLi9jb21tb24vRFRpbWVzdGFtcFwiO1xuaW1wb3J0IHsgRXZlbnRCdXMgfSBmcm9tIFwiLi4vZXZlbnRzL2V2ZW50LWJ1c1wiO1xuaW1wb3J0IHsgU2NhbGVTZXJ2aWNlIH0gZnJvbSBcIi4uL2VuZ2luZS9zY2FsZVwiO1xuaW1wb3J0IHsgUmVzb3VyY2VQcm92aWRlciB9IGZyb20gXCIuL3Jlc291cmNlLXByb3ZpZGVyXCI7XG5pbXBvcnQgeyBBdXRvcGxheVRhc2ssIFNlcXVlbmNlTWFuYWdlciB9IGZyb20gXCIuL3NlcXVlbmNlLW1hbmFnZXJcIjtcblxuZXhwb3J0IGludGVyZmFjZSBJTWVkaWFNYW5hZ2VyIHtcbiAgc2V0UGFnZShwYWdlOiBQYWdlRHRvKTogdm9pZDtcbiAgZGVzdHJveSgpOiB2b2lkO1xufVxuXG5leHBvcnQgY2xhc3MgRE1lZGlhTWFuYWdlciBpbXBsZW1lbnRzIElNZWRpYU1hbmFnZXIge1xuICBwcml2YXRlIHN0YXRpYyBJTlNUQU5DRV9DT1VOVCA9IDA7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5zdGFuY2VOdW1iZXI6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBUQUcgPSBcIlsgTUVESUFfTUFOQUdFUiBdIDogXCI7XG4gIHByaXZhdGUgcmVhZG9ubHkgdmlkZW9Db250YWluZXI6IFZpZGVvQ29udGFpbmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGF1ZGlvQ29udGFpbmVyOiBBdWRpb0NvbnRhaW5lcjtcbiAgcHJpdmF0ZSBwYWdlRW50ZXI6IERUaW1lc3RhbXA7XG4gIHByaXZhdGUgc2luY2VQYWdlRW50ZXI6IERUaW1lc3RhbXAuRGlmZjtcbiAgcHJpdmF0ZSBjdXJyZW50UGFnZTogUGFnZUR0byB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IHVuc3Vic2NyaWJlQ29tbWFuZHM6ICgpID0+IHZvaWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgdGlja2VyUmVmOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2VxdWVuY2VNYW5hZ2VyOiBTZXF1ZW5jZU1hbmFnZXIgfCBmYWxzZSA9IGZhbHNlO1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGhvc3RFbDogSFRNTERpdkVsZW1lbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb21tYW5kQnVzOiBEQ29tbWFuZEJ1cyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50QnVzOiBFdmVudEJ1cyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlc291cmNlUHJvdmlkZXI6IFJlc291cmNlUHJvdmlkZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzY2FsZTogU2NhbGVTZXJ2aWNlLFxuICApIHtcbiAgICBETWVkaWFNYW5hZ2VyLklOU1RBTkNFX0NPVU5UID0gRE1lZGlhTWFuYWdlci5JTlNUQU5DRV9DT1VOVCArIDE7XG4gICAgdGhpcy5pbnN0YW5jZU51bWJlciA9IERNZWRpYU1hbmFnZXIuSU5TVEFOQ0VfQ09VTlQ7XG4gICAgY29uc3QgdmlkZW9FbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ2aWRlb1wiKTtcbiAgICB0aGlzLmhvc3RFbC5hcHBlbmQodmlkZW9FbCk7XG4gICAgdGhpcy52aWRlb0NvbnRhaW5lciA9IG5ldyBWaWRlb0NvbnRhaW5lcih2aWRlb0VsLCBldmVudEJ1cywgdGhpcy5zY2FsZSk7XG4gICAgdGhpcy5hdWRpb0NvbnRhaW5lciA9IG5ldyBBdWRpb0NvbnRhaW5lcih0aGlzLmV2ZW50QnVzKTtcbiAgICB0aGlzLnRpY2sgPSB0aGlzLnRpY2suYmluZCh0aGlzKTtcbiAgICB0aGlzLnZpZGVvQ29udGFpbmVyLnNldFN0eWxlKHsgdmlzaWJpbGl0eTogXCJoaWRkZW5cIiB9KTtcbiAgICBjb25zdCBub3cgPSBEVGltZXN0YW1wLm5vdygpO1xuICAgIHRoaXMucGFnZUVudGVyID0gbm93O1xuICAgIHRoaXMuc2luY2VQYWdlRW50ZXIgPSBEVGltZXN0YW1wLmRpZmYobm93LCBub3cpO1xuICAgIHRoaXMudW5zdWJzY3JpYmVDb21tYW5kcyA9IHRoaXMuY29tbWFuZEJ1cy5zdWJzY3JpYmUoKGFjdGlvbikgPT4ge1xuICAgICAgdGhpcy5jb21tYW5kSGFuZGxlcihhY3Rpb24pO1xuICAgIH0sIHRoaXMuVEFHKTtcblxuICAgIHRoaXMudGlja2VyUmVmID0gd2luZG93LnNldEludGVydmFsKCgpID0+IHt9LCAxMDAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wIGFsbCBtZWRpYSB0aGF0IGlzIHBsYXlpbmdcbiAgICovXG4gIGNsZWFyQWxsTWVkaWEoKSB7XG4gICAgdGhpcy52aWRlb0NvbnRhaW5lci5wYXVzZSgpO1xuICAgIHRoaXMuYXVkaW9Db250YWluZXIucGF1c2UoKTtcbiAgfVxuICBkZXN0cm95KCkge1xuICAgIGNvbnNvbGUubG9nKFwiVE9ETyBERVNUUk9ZIEFMTCBNRURJQVwiKTtcbiAgICB0aGlzLnVuc3Vic2NyaWJlQ29tbWFuZHMoKTtcbiAgICAvLyBjb25zb2xlLmxvZyh0aGlzLnRpY2tlclJlZik7XG4gICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy50aWNrZXJSZWYpO1xuICAgIHRoaXMuYXVkaW9Db250YWluZXIuZGVzdHJveSgpO1xuICAgIHRoaXMudmlkZW9Db250YWluZXIuZGVzdHJveSgpO1xuICB9XG5cbiAgc2V0UGFnZShwYWdlOiBQYWdlRHRvKSB7XG4gICAgLy8gVE9ETyBTVE9QIFZJREVPL0FVRElPIFRIQVQgTUlHSFQgQkUgUExBWUlORyBJTiBUSEUgRE9NPz9cbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gcGFnZTtcbiAgICB0aGlzLnZpZGVvQ29udGFpbmVyLnBhdXNlKCk7XG4gICAgdGhpcy5wYWdlRW50ZXIgPSBEVGltZXN0YW1wLm5vdygpO1xuICAgIC8vIFRPRE8gVEhpcyBtaWdodCBiZSBhIGJ1ZyBpZiBzb21lb25lXG5cbiAgICBjb25zdCBzZXEgPSBwYWdlLmF1dG9QbGF5U2VxdWVuY2U7XG4gICAgLy8gdGhpcy5zZXF1ZW5jZSA9IHNlcSA/IFsuLi5zZXEuaXRlbXNdIDogW107XG4gICAgY29uc3QgeyBtYWluVmlkZW9JZCwgYXVkaW8gfSA9IHBhZ2U7XG4gICAgY29uc3QgYXVkaW9FbGVtZW50cyA9IHBhZ2UuYXVkaW87XG5cbiAgICBpZiAobWFpblZpZGVvSWQpIHtcbiAgICAgIGNvbnN0IGR0byA9IHRoaXMucmVzb3VyY2VQcm92aWRlci5nZXRWaWRlb0J5SWQobWFpblZpZGVvSWQpO1xuICAgICAgaWYgKGR0bykge1xuICAgICAgICB0aGlzLnZpZGVvQ29udGFpbmVyLnNldER0byhkdG8pO1xuICAgICAgICB0aGlzLnZpZGVvQ29udGFpbmVyLnNldFN0eWxlKHsgLi4uZHRvLnN0eWxlLCB2aXNpYmlsaXR5OiBcInZpc2libGVcIiB9KTtcbiAgICAgIH1cbiAgICAgIC8vIHRoaXMudmlkZW9Db250YWluZXIucGxheVRvRW5kKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudmlkZW9Db250YWluZXIuc2V0U3R5bGUoeyB2aXNpYmlsaXR5OiBcImhpZGRlblwiIH0pO1xuICAgICAgLy8gSElERT9cbiAgICB9XG4gICAgaWYgKGF1ZGlvRWxlbWVudHMpIHtcbiAgICAgIGNvbnN0IGZpcnN0ID0gYXVkaW9FbGVtZW50c1swXTtcbiAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICB0aGlzLmF1ZGlvQ29udGFpbmVyLnNldEF1ZGlvKGZpcnN0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNlcSkge1xuICAgICAgdGhpcy5wbGF5U2VxdWVuY2Uoc2VxKTtcbiAgICB9XG4gICAgLy8gY29uc3QgaGFzVmlkZW8gPVxuICB9XG5cbiAgcHJpdmF0ZSBjb21tYW5kSGFuZGxlcihjb21tYW5kOiBEQ29tbWFuZCkge1xuICAgIGlmIChjb21tYW5kLmtpbmQgPT09IFwiVklERU9fUExBWV9DT01NQU5EXCIpIHtcbiAgICAgIGNvbnN0IHZpZGVvID0gY29tbWFuZC50YXJnZXRJZDtcbiAgICAgIGNvbnN0IGR0byA9IHRoaXMudmlkZW9Db250YWluZXIuZ2V0Q3VycmVudER0bygpO1xuXG4gICAgICBpZiAoZHRvICYmIGR0by5pZCA9PT0gY29tbWFuZC50YXJnZXRJZCkge1xuICAgICAgICBjb25zb2xlLmxvZyh2aWRlbyk7XG4gICAgICAgIHRoaXMudmlkZW9Db250YWluZXIucGxheShkdG8udXJsKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNvbW1hbmQua2luZCA9PT0gXCJWSURFT19QQVVTRV9DT01NQU5EXCIpIHtcbiAgICAgIHRoaXMudmlkZW9Db250YWluZXIucGF1c2UoKTtcbiAgICB9XG4gICAgaWYgKGNvbW1hbmQua2luZCA9PT0gXCJBVURJT19QTEFZX0NPTU1BTkRcIikge1xuICAgICAgdGhpcy5hdWRpb0NvbnRhaW5lclxuICAgICAgICAucGxheVRvRW5kKClcbiAgICAgICAgLnRoZW4oKCkgPT4ge30pXG4gICAgICAgIC5jYXRjaCgpXG4gICAgICAgIC5maW5hbGx5KCgpID0+IHt9KTtcbiAgICB9XG5cbiAgICBpZiAoY29tbWFuZC5raW5kID09PSBcIkFVRElPX1BBVVNFX0NPTU1BTkRcIikge1xuICAgICAgLy8gdGhpcy5hdWRpb0NvbnRhaW5lci5cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBsYXlTZXF1ZW5jZShzZXE6IERBdXRvUGxheVNlcXVlbmNlKSB7XG4gICAgLy8gY29uc29sZS5sb2codGhpcy5UQUcgKyBcIlNFUVVFTkNFIFNUQVJURUQgLS0gVE9ETyBFVkVOVCBGT1IgVEhJUz8/XCIpO1xuXG4gICAgY29uc3QgZWxlbWVudHMgPSBzZXEuaXRlbXM7XG4gICAgY29uc3QgdGVzdENsb25lID0gWy4uLmVsZW1lbnRzXTtcbiAgICBjb25zdCBmaXJzdCA9IHRlc3RDbG9uZS5wb3AoKTtcblxuICAgIGlmICghZmlyc3QpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3Qgbm93ID0gRFRpbWVzdGFtcC5ub3coKTtcbiAgICBzZXEuc3RhcnRDb21tYW5kcy5mb3JFYWNoKChjKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhjKTtcbiAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGMpO1xuICAgIH0pO1xuICAgIC8vIHRoaXMuY29tbWFuZEJ1cy5lbWl0KERTdGF0ZVByb3BzLm1lZGlhQmxvY2tlZEJ5U2VxdWVuY2Uuc2V0VHJ1ZUNvbW1hbmQpO1xuICAgIC8vIGlmIChzZXEuYmxvY2tVc2VySW5wdXQpIHtcbiAgICAvLyAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoRFN0YXRlUHJvcHMuaW5wdXRCbG9ja2luZ0J5U2VxdWVuY2UuZ2V0U2V0VHJ1ZUNvbW1hbmQoKSk7XG4gICAgLy8gfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBlbGVtZW50c1tpXTtcbiAgICAgIGlmIChpdGVtLmtpbmQgPT09IFwiYXV0b3BsYXktdmlkZW9cIikge1xuICAgICAgICBjb25zdCBkdG8gPSB0aGlzLnJlc291cmNlUHJvdmlkZXIuZ2V0VmlkZW9CeUlkKGl0ZW0udmlkZW9JZCk7XG4gICAgICAgIGlmIChkdG8pIHRoaXMudmlkZW9Db250YWluZXIuc2V0RHRvKGR0byk7XG4gICAgICAgIGF3YWl0IHRoaXMudmlkZW9Db250YWluZXIucGxheVRvRW5kKCk7XG4gICAgICB9XG4gICAgICBpZiAoaXRlbS5raW5kID09PSBcImF1dG9wbGF5LWF1ZGlvXCIpIHtcbiAgICAgICAgY29uc29sZS5sb2coaXRlbSk7XG4gICAgICAgIGNvbnN0IGR0byA9IHRoaXMucmVzb3VyY2VQcm92aWRlci5nZXRBdWRpb0J5SWQoaXRlbS5hdWRpb0lkKTtcbiAgICAgICAgaWYgKGR0bykgdGhpcy5hdWRpb0NvbnRhaW5lci5zZXRBdWRpbyhkdG8pO1xuICAgICAgICBhd2FpdCB0aGlzLmF1ZGlvQ29udGFpbmVyLnBsYXlUb0VuZCgpO1xuICAgICAgfVxuICAgIH1cbiAgICBzZXEuZW5kQ29tbWFuZHMuZm9yRWFjaCgoYykgPT4ge1xuICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoYyk7XG4gICAgfSk7XG4gICAgLy8gdGhpcy5hY3Rpb25TZXJ2aWNlLmVtaXQoRFN0YXRlUHJvcHMubWVkaWFCbG9ja2VkQnlTZXF1ZW5jZS5zZXRGYWxzZUNvbW1hbmQpO1xuICAgIC8vIHRoaXMuYWN0aW9uU2VydmljZS5lbWl0KERTdGF0ZVByb3BzLmlucHV0QmxvY2tpbmdCeVNlcXVlbmNlLnNldEZhbHNlQ29tbWFuZCk7XG4gICAgY29uc29sZS5sb2codGhpcy5UQUcgKyBcIlNFUVVFTkNFIEVOREVEXCIpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gc2V0UGFnZSgpXG5cbiAgcHJpdmF0ZSB0aWNrKCkge1xuICAgIC8vIGNvbnNvbGUubG9nKHRoaXMudmlkZW8xLmdldFN0YXRzKCkpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgRENvbW1hbmQgfSBmcm9tIFwiLi9EQ29tbWFuZFwiO1xuaW1wb3J0IHsgRFRpbWVzdGFtcCB9IGZyb20gXCIuLi9jb21tb24vRFRpbWVzdGFtcFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIERDb21tYW5kU3RvcmUge1xuICBzdWJzY3JpYmUoY2FsbGJhY2s6ICgpID0+IHZvaWQsIHN1YnNjcmliZXJJZDogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEQ29tbWFuZERpc3BhdGNoZXIge1xuICBlbWl0KGNvbW1hbmQ6IERDb21tYW5kKTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIENvbW1hbmRTdWJzY3JpYmVyRGF0YSB7XG4gIHJlYWRvbmx5IHN1YnNjcmliZXJJZDogc3RyaW5nO1xuICByZWFkb25seSBjYWxsYmFjazogKGNvbW1hbmQ6IERDb21tYW5kKSA9PiB2b2lkO1xufVxuZXhwb3J0IGNsYXNzIERDb21tYW5kQnVzIGltcGxlbWVudHMgRENvbW1hbmRTdG9yZSwgRENvbW1hbmREaXNwYXRjaGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBUQUcgPSBcIlsgQ09NTUFORF9CVVMgXSBcIjtcbiAgbG9nQ29tbWFuZHMgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBjb21tYW5kTG9nOiBBcnJheTxEQ29tbWFuZCAmIHsgdGltZXN0YW1wOiBEVGltZXN0YW1wIH0+ID0gW107XG4gIHJlYWRvbmx5IHN1YnNjcmliZXJzID0gbmV3IFNldDxDb21tYW5kU3Vic2NyaWJlckRhdGE+KCk7XG4gIC8vIHJlYWRvbmx5IHN1YlxuXG4gIHN1YnNjcmliZShjYjogKGNvbW1hbmQ6IERDb21tYW5kKSA9PiB2b2lkLCBzdWJzY3JpYmVySWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHN1YjogQ29tbWFuZFN1YnNjcmliZXJEYXRhID0ge1xuICAgICAgc3Vic2NyaWJlcklkLFxuICAgICAgY2FsbGJhY2s6IGNiLFxuICAgIH07XG5cbiAgICB0aGlzLnN1YnNjcmliZXJzLmFkZChzdWIpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB0aGlzLnN1YnNjcmliZXJzLmRlbGV0ZShzdWIpO1xuICAgIH07XG4gIH1cblxuICBlbWl0KGNvbW1hbmQ6IERDb21tYW5kKSB7XG4gICAgY29uc3QgdGltZXN0YW1wID0gRFRpbWVzdGFtcC5ub3coKTtcbiAgICB0aGlzLmNvbW1hbmRMb2cucHVzaCh7IC4uLmNvbW1hbmQsIHRpbWVzdGFtcCB9KTtcbiAgICBpZiAodGhpcy5sb2dDb21tYW5kcykge1xuICAgICAgdGhpcy5sb2dDb21tYW5kKGNvbW1hbmQpO1xuICAgIH1cbiAgICB0aGlzLnN1YnNjcmliZXJzLmZvckVhY2goKHN1YnNjcmliZXIpID0+IHtcbiAgICAgIHN1YnNjcmliZXIuY2FsbGJhY2soY29tbWFuZCk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRTdGF0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29tbWFuZHM6IFsuLi50aGlzLmNvbW1hbmRMb2ddLFxuICAgICAgc3Vic2NyaWJlcnM6IFsuLi50aGlzLnN1YnNjcmliZXJzXSxcbiAgICAgIHN1YnNjcmliZXJzQ291bnQ6IHRoaXMuc3Vic2NyaWJlcnMuc2l6ZSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBsb2dDb21tYW5kKGNvbW1hbmQ6IERDb21tYW5kKSB7XG4gICAgY29uc29sZS5ncm91cENvbGxhcHNlZCh0aGlzLlRBRyArIFwiIFwiICsgY29tbWFuZC5raW5kKTtcbiAgICBjb25zb2xlLmxvZyhcIlRhcmdldElEIDogXCIgKyBjb21tYW5kLnRhcmdldElkKTtcbiAgICBjb25zb2xlLmxvZyhjb21tYW5kLnBheWxvYWQpO1xuICAgIGNvbnNvbGUuZ3JvdXBFbmQoKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IERFdmVudCB9IGZyb20gXCIuL0RFdmVudHNcIjtcblxuaW50ZXJmYWNlIFN1YnNjcmliZXJEYXRhIHtcbiAgICByZWFkb25seSBzdWJzY3JpYmVySWQ6IHN0cmluZztcbiAgICByZWFkb25seSBjYjogKGV2ZW50OiBERXZlbnQpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgREV2ZW50U3RvcmUge1xuICAgIHN1YnNjcmliZShjYjogKGV2ZW50OiBERXZlbnQpID0+IHZvaWQsIHN1YnNjcmliZXJJZDogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBERXZlbnREaXNwYXRjaGVyIHtcbiAgICBlbWl0KGV2ZW50OiBERXZlbnQpOiB2b2lkO1xufVxuZXhwb3J0IGNsYXNzIEV2ZW50QnVzIGltcGxlbWVudHMgREV2ZW50U3RvcmUsIERFdmVudERpc3BhdGNoZXIge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgVEFHID0gXCJbICBFVkVOVF9CVVMgIF0gOlwiO1xuICAgIC8vIHByaXZhdGUgcmVhZG9ubHkgc3Vic2NyaWJlcnMgPSBuZXcgU2V0PChldmVudDogREV2ZW50KSA9PiB2b2lkPigpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgc3Vic2NyaWJlcnMgPSBuZXcgU2V0PFN1YnNjcmliZXJEYXRhPigpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdCBvbiBtb2R1bGUgZW5kLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBldmVudExvZzogREV2ZW50W10gPSBbXTtcbiAgICBjb25zb2xlTG9nRXZlbnRzID0gZmFsc2U7XG4gICAgLy8gcmVhZG9ubHkgc3ViXG5cbiAgICBzdWJzY3JpYmUoY2I6IChldmVudDogREV2ZW50KSA9PiB2b2lkLCBzdWJzY3JpYmVySWQ6IHN0cmluZykge1xuICAgICAgICAvLyB0aGlzLnN1YnNjcmliZXJzLmFkZChjYik7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXJEYXRhOiBTdWJzY3JpYmVyRGF0YSA9IHtcbiAgICAgICAgICAgIHN1YnNjcmliZXJJZCxcbiAgICAgICAgICAgIGNiLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnN1YnNjcmliZXJzLmFkZChzdWJzY3JpYmVyRGF0YSk7XG4gICAgICAgIGlmICh0aGlzLmNvbnNvbGVMb2dFdmVudHMpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCJzdWJzY3JpcHRpb24gYWRkZWQ6IFwiICsgc3Vic2NyaWJlcklkKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCJzdWJzY3JpcHRpb24gY291bnQ6IFwiICsgdGhpcy5zdWJzY3JpYmVycy5zaXplKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29uc29sZUxvZ0V2ZW50cykge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCJzdWJzY3JpcHRpb24gcmVtb3ZlZDogXCIgKyBzdWJzY3JpYmVySWQpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCJzdWJzY3JpcHRpb24gY291bnQgIDogXCIgKyB0aGlzLnN1YnNjcmliZXJzLnNpemUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdGhpcy5zdWJzY3JpYmVycy5kZWxldGUoY2IpO1xuICAgICAgICAgICAgdGhpcy5zdWJzY3JpYmVycy5kZWxldGUoc3Vic2NyaWJlckRhdGEpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGdldFN0YXRzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3Vic2NyaWJlcnNDb3VudDogdGhpcy5zdWJzY3JpYmVycy5zaXplLFxuICAgICAgICAgICAgZXZlbnRMb2c6IFsuLi50aGlzLmV2ZW50TG9nXSxcbiAgICAgICAgICAgIHN1YnNjcmliZXJzOiBbLi4udGhpcy5zdWJzY3JpYmVyc10sXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZW1pdChldmVudDogREV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnNvbGVMb2dFdmVudHMpIHtcbiAgICAgICAgICAgIHRoaXMubG9nRXZlbnQoZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZXZlbnRMb2cucHVzaChldmVudCk7XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlcnMuZm9yRWFjaCgoZGF0YSkgPT4ge1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ0NBTExJTkcgRU1JVCcpO1xuICAgICAgICAgICAgZGF0YS5jYihldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyB0aGlzLmxvZ0V2ZW50cygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgbG9nRXZlbnQoZXZlbnQ6IERFdmVudCkge1xuICAgICAgICBjb25zb2xlLmdyb3VwQ29sbGFwc2VkKHRoaXMuVEFHICsgXCIgXCIgKyBldmVudC5raW5kKTtcbiAgICAgICAgY29uc29sZS5sb2coXCJQcm9kdWNlcklkOiBcIiArIGV2ZW50LnByb2R1Y2VySWQpO1xuICAgICAgICBjb25zb2xlLmxvZyhldmVudC5kYXRhKTtcbiAgICAgICAgY29uc29sZS5ncm91cEVuZCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgbG9nRXZlbnRzKCkge1xuICAgICAgICBjb25zb2xlLmdyb3VwKHRoaXMuVEFHICsgXCJMT0dHXCIpO1xuICAgICAgICBjb25zb2xlLnRhYmxlKHRoaXMuZXZlbnRMb2cpO1xuICAgICAgICBjb25zb2xlLmdyb3VwRW5kKCk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IEZhY3QgfSBmcm9tIFwiLi4vcnVsZXMvZmFjdFwiO1xuaW1wb3J0IHsgRFRpbWVzdGFtcCB9IGZyb20gXCIuLi9jb21tb24vRFRpbWVzdGFtcFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFuc3dlcmVkUXVlc3Rpb24ge1xuICAgIHJlYWRvbmx5IHRpbWVzdGFtcDogRFRpbWVzdGFtcDtcbiAgICByZWFkb25seSBmYWN0OiBGYWN0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIEFuc3dlcmVkUXVlc3Rpb24ge1xuICAgIGV4cG9ydCBjb25zdCBlcSA9IChhOiBBbnN3ZXJlZFF1ZXN0aW9uLCBiOiBBbnN3ZXJlZFF1ZXN0aW9uKTogYm9vbGVhbiA9PiB7XG4gICAgICAgIHJldHVybiBhLmZhY3QgPT09IGIuZmFjdDtcbiAgICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBhZ2VIaXN0b3J5IHtcbiAgICByZWFkb25seSBwYWdlSWQ6IHN0cmluZztcbiAgICByZWFkb25seSBhbnN3ZXJlZFF1ZXN0aW9uczogQW5zd2VyZWRRdWVzdGlvbltdO1xufVxuXG5leHBvcnQgY2xhc3MgSGlzdG9yeVF1ZSB7XG4gICAgcHJpdmF0ZSBoaXN0b3J5OiBQYWdlSGlzdG9yeVtdID0gW107XG5cbiAgICBnZXRGYWN0cygpOiBBcnJheTxGYWN0PiB7XG4gICAgICAgIGNvbnN0IGFuc3dlcnMgPSB0aGlzLmhpc3RvcnkubWFwKChoKSA9PiBoLmFuc3dlcmVkUXVlc3Rpb25zKS5mbGF0KDEpO1xuICAgICAgICBjb25zdCBmYWN0cyA9IGFuc3dlcnMubWFwKChhKSA9PiBhLmZhY3QpO1xuICAgICAgICAvLyBUT0RPIEZJTkQgTEFURVNUIEZBQ1QgKGFuc3dlcikgaWYgaGF2ZSBtdWx0aXBsZS5cbiAgICAgICAgcmV0dXJuIGZhY3RzO1xuICAgIH1cblxuICAgIGdldEFuc3dlcnMoKTogQXJyYXk8QW5zd2VyZWRRdWVzdGlvbj4ge1xuICAgICAgICBjb25zdCBhbnN3ZXJzID0gdGhpcy5oaXN0b3J5Lm1hcCgoaCkgPT4gaC5hbnN3ZXJlZFF1ZXN0aW9ucykuZmxhdCgxKTtcbiAgICAgICAgcmV0dXJuIGFuc3dlcnM7XG4gICAgfVxuXG4gICAgYWRkVG9IaXN0b3J5KHBhZ2U6IFBhZ2VIaXN0b3J5KSB7XG4gICAgICAgIHRoaXMuaGlzdG9yeS5wdXNoKHBhZ2UpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBGYWN0IH0gZnJvbSBcIi4vZmFjdFwiO1xuaW1wb3J0IHsgRFV0aWwgfSBmcm9tIFwiLi4vdXRpbHMvRFV0aWxcIjtcbmV4cG9ydCB0eXBlIENvbmRpdGlvbiA9IENvbmRpdGlvbi5TdHJpbmcgfCBDb25kaXRpb24uTnVtZXJpYyB8IENvbmRpdGlvbi5Db21wbGV4O1xuXG5leHBvcnQgbmFtZXNwYWNlIENvbmRpdGlvbiB7XG4gICAgZXhwb3J0IHR5cGUgU3RyaW5nT3BlcmF0b3IgPSBcImVxXCIgfCBcIm5vdC1lcVwiIHwgXCJsb25nZXItdGhlblwiIHwgXCJzaG9ydGVyLXRoZW5cIjtcblxuICAgIGV4cG9ydCB0eXBlIE51bWVyaWNPcGVyYXRvciA9XG4gICAgICAgIHwgXCJlcVwiXG4gICAgICAgIHwgXCJub3QtZXFcIlxuICAgICAgICB8IFwiZ3JlYXRlci10aGVuXCJcbiAgICAgICAgfCBcImxlc3MtdGhlblwiXG4gICAgICAgIHwgXCJncmVhdGVyLXRoZW4taW5jbHVzaXZlXCJcbiAgICAgICAgfCBcImxlc3MtdGhlbi1pbmNsdXNpdmVcIjtcblxuICAgIGV4cG9ydCBpbnRlcmZhY2UgTnVtZXJpYyB7XG4gICAgICAgIHJlYWRvbmx5IHJlZmVyZW5jZUlkOiBzdHJpbmc7XG4gICAgICAgIHJlYWRvbmx5IHJlZmVyZW5jZUxhYmVsOiBzdHJpbmc7XG4gICAgICAgIHJlYWRvbmx5IHZhbHVlTGFiZWw6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkga2luZDogXCJudW1lcmljLWNvbmRpdGlvblwiO1xuICAgICAgICByZWFkb25seSBvcGVyYXRvcjogTnVtZXJpY09wZXJhdG9yO1xuICAgICAgICByZWFkb25seSB2YWx1ZTogbnVtYmVyO1xuICAgIH1cbiAgICBleHBvcnQgaW50ZXJmYWNlIFN0cmluZyB7XG4gICAgICAgIHJlYWRvbmx5IHJlZmVyZW5jZUlkOiBzdHJpbmc7XG4gICAgICAgIHJlYWRvbmx5IHJlZmVyZW5jZUxhYmVsOiBzdHJpbmc7XG4gICAgICAgIHJlYWRvbmx5IHZhbHVlTGFiZWw6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkga2luZDogXCJzdHJpbmctY29uZGl0aW9uXCI7XG4gICAgICAgIHJlYWRvbmx5IG9wZXJhdG9yOiBTdHJpbmdPcGVyYXRvcjtcbiAgICAgICAgcmVhZG9ubHkgdmFsdWU6IHN0cmluZztcbiAgICB9XG5cbiAgICBleHBvcnQgaW50ZXJmYWNlIENvbXBsZXgge1xuICAgICAgICByZWFkb25seSBraW5kOiBcImNvbXBsZXgtY29uZGl0aW9uXCI7XG4gICAgICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkgYWxsOiBSZWFkb25seUFycmF5PENvbmRpdGlvbi5TaW1wbGU+O1xuICAgICAgICByZWFkb25seSBzb21lOiBSZWFkb25seUFycmF5PENvbmRpdGlvbi5TaW1wbGU+O1xuICAgIH1cblxuICAgIGV4cG9ydCB0eXBlIFNpbXBsZSA9IENvbmRpdGlvbi5TdHJpbmcgfCBDb25kaXRpb24uTnVtZXJpYztcblxuICAgIC8qKlxuICAgICAqIEFuIGVtcHR5IGNvbmRpdGlvbiB3aWxsIGV2YWx1YXRlIHRvIGZhbHNlLFxuICAgICAqIEBwYXJhbSBjb25kaXRpb246IENvbmRpdGlvbi5BbnlcbiAgICAgKiBAcGFyYW0gZmFjdHNcbiAgICAgKi9cbiAgICBleHBvcnQgY29uc3QgZXZhbHVhdGUgPSAoY29uZGl0aW9uOiBDb25kaXRpb24sIGZhY3RzOiBSZWFkb25seUFycmF5PEZhY3Q+KSA9PiB7XG4gICAgICAgIGxldCByZXN1bHQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICAgICAgc3dpdGNoIChjb25kaXRpb24ua2luZCkge1xuICAgICAgICAgICAgY2FzZSBcInN0cmluZy1jb25kaXRpb25cIjpcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBldmFsdWF0ZVNpbXBsZShjb25kaXRpb24sIGZhY3RzKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJudW1lcmljLWNvbmRpdGlvblwiOlxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGV2YWx1YXRlU2ltcGxlKGNvbmRpdGlvbiwgZmFjdHMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImNvbXBsZXgtY29uZGl0aW9uXCI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZXZhbHVhdGVDb21wbGV4KGNvbmRpdGlvbiwgZmFjdHMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBjb25zdCBjaGVjazogbmV2ZXIgPSBjb25kaXRpb247XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgY29uc3QgZXZhbHVhdGVDb21wbGV4ID0gKGNvbmRpdGlvbjogQ29uZGl0aW9uLkNvbXBsZXgsIGZhY3RzOiBSZWFkb25seUFycmF5PEZhY3Q+KTogYm9vbGVhbiA9PiB7XG4gICAgICAgIGlmIChjb25kaXRpb24uc29tZS5sZW5ndGggPT09IDAgJiYgY29uZGl0aW9uLmFsbC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhbGxTb2x2ZWQgPSBjb25kaXRpb24uYWxsLm1hcCgoY29uZGl0aW9uKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZXZhbHVhdGVTaW1wbGUoY29uZGl0aW9uLCBmYWN0cyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHNvbWVFdmFsdWF0ZWQgPSBjb25kaXRpb24uc29tZS5tYXAoKGNvbmRpdGlvbikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGV2YWx1YXRlU2ltcGxlKGNvbmRpdGlvbiwgZmFjdHMpO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgYWxsUmVzdWx0ID0gYWxsU29sdmVkLmV2ZXJ5KERVdGlsLmlzVHJ1ZSk7XG4gICAgICAgIGNvbnN0IHNvbWVSZXN1bHQgPSBzb21lRXZhbHVhdGVkLmxlbmd0aCA9PT0gMCB8fCBzb21lRXZhbHVhdGVkLnNvbWUoRFV0aWwuaXNUcnVlKTtcbiAgICAgICAgcmV0dXJuIHNvbWVSZXN1bHQgJiYgYWxsUmVzdWx0O1xuICAgIH07XG5cbiAgICBjb25zdCBldmFsdWF0ZVNpbXBsZSA9IChjb25kaXRpb246IENvbmRpdGlvbi5TaW1wbGUsIGZhY3RzOiBSZWFkb25seUFycmF5PEZhY3Q+KTogYm9vbGVhbiA9PiB7XG4gICAgICAgIGNvbnN0IGZhY3QgPSBmYWN0cy5maW5kKChmKSA9PiBmLnJlZmVyZW5jZUlkID09PSBjb25kaXRpb24ucmVmZXJlbmNlSWQpO1xuICAgICAgICBpZiAoIWZhY3QpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzID0gZmFsc2U7XG4gICAgICAgIHN3aXRjaCAoY29uZGl0aW9uLmtpbmQpIHtcbiAgICAgICAgICAgIGNhc2UgXCJudW1lcmljLWNvbmRpdGlvblwiOlxuICAgICAgICAgICAgICAgIGlmIChmYWN0LmtpbmQgPT09IFwibnVtZXJpYy1mYWN0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzID0gZXZhbHVhdGVOdW1lcmljKGNvbmRpdGlvbiwgZmFjdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcInN0cmluZy1jb25kaXRpb25cIjpcbiAgICAgICAgICAgICAgICBpZiAoZmFjdC5raW5kID09PSBcInN0cmluZy1mYWN0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzID0gZXZhbHVhdGVTdHJpbmcoY29uZGl0aW9uLCBmYWN0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGNvbnN0IGNoZWNrOiBuZXZlciA9IGNvbmRpdGlvbjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH07XG5cbiAgICBleHBvcnQgY29uc3QgaXNFbXB0eSA9IChjb21wbGV4OiBDb21wbGV4KSA9PiB7XG4gICAgICAgIHJldHVybiBjb21wbGV4LmFsbC5sZW5ndGggPT09IDAgJiYgY29tcGxleC5zb21lLmxlbmd0aCA9PT0gMDtcbiAgICB9O1xuXG4gICAgY29uc3QgZXZhbHVhdGVTdHJpbmcgPSAoY29uZGl0aW9uOiBSZWFkb25seTxDb25kaXRpb24uU3RyaW5nPiwgdmFsdWU6IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xuICAgICAgICBjb25zdCBvcGVyYXRvciA9IGNvbmRpdGlvbi5vcGVyYXRvcjtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgICAgICBjYXNlIFwiZXFcIjpcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBjb25kaXRpb24udmFsdWUgPT09IHZhbHVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIm5vdC1lcVwiOlxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvbmRpdGlvbi52YWx1ZSAhPT0gdmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwic2hvcnRlci10aGVuXCI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gY29uZGl0aW9uLnZhbHVlICE9PSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJsb25nZXItdGhlblwiOlxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNvbmRpdGlvbi52YWx1ZSAhPT0gdmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGNvbnN0IGNoZWNrOiBuZXZlciA9IG9wZXJhdG9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIGNvbnN0IGV2YWx1YXRlTnVtZXJpYyA9IChjb25kaXRpb246IE51bWVyaWMsIHZhbHVlOiBudW1iZXIpOiBib29sZWFuID0+IHtcbiAgICAgICAgY29uc3Qgb3AgPSBjb25kaXRpb24ub3BlcmF0b3I7XG4gICAgICAgIGNvbnN0IGNvbmRpdGlvblZhbHVlID0gY29uZGl0aW9uLnZhbHVlO1xuICAgICAgICBsZXQgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIHN3aXRjaCAob3ApIHtcbiAgICAgICAgICAgIGNhc2UgXCJlcVwiOlxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHZhbHVlID09PSBjb25kaXRpb25WYWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJub3QtZXFcIjpcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB2YWx1ZSAhPT0gY29uZGl0aW9uVmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiZ3JlYXRlci10aGVuXCI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdmFsdWUgPiBjb25kaXRpb25WYWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJncmVhdGVyLXRoZW4taW5jbHVzaXZlXCI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdmFsdWUgPj0gY29uZGl0aW9uVmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwibGVzcy10aGVuXCI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdmFsdWUgPCBjb25kaXRpb25WYWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJsZXNzLXRoZW4taW5jbHVzaXZlXCI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gdmFsdWUgPD0gY29uZGl0aW9uVmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGNvbnN0IGNoZWNrOiBuZXZlciA9IG9wO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIGNvbnN0IF9nZXRBbGxTaW1wbGUgPSAoY29uZGl0aW9uOiBDb25kaXRpb24pOiBSZWFkb25seUFycmF5PENvbmRpdGlvbi5TaW1wbGU+ID0+IHtcbiAgICAgICAgY29uc3Qgc2ltcGxlOiBBcnJheTxDb25kaXRpb24uU2ltcGxlPiA9IFtdO1xuICAgICAgICBzd2l0Y2ggKGNvbmRpdGlvbi5raW5kKSB7XG4gICAgICAgICAgICBjYXNlIFwiY29tcGxleC1jb25kaXRpb25cIjpcbiAgICAgICAgICAgICAgICBzaW1wbGUucHVzaCguLi5jb25kaXRpb24uYWxsKTtcbiAgICAgICAgICAgICAgICBzaW1wbGUucHVzaCguLi5jb25kaXRpb24uc29tZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwibnVtZXJpYy1jb25kaXRpb25cIjpcbiAgICAgICAgICAgICAgICBzaW1wbGUucHVzaChjb25kaXRpb24pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcInN0cmluZy1jb25kaXRpb25cIjpcbiAgICAgICAgICAgICAgICBzaW1wbGUucHVzaChjb25kaXRpb24pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBEVXRpbC5uZXZlckNoZWNrKGNvbmRpdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNpbXBsZTtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGdldEFsbFNpbXBsZUNvbmRpdGlvbnMgPSAoXG4gICAgICAgIGNvbmRpdGlvbjogQ29uZGl0aW9uIHwgQXJyYXk8Q29uZGl0aW9uPlxuICAgICk6IFJlYWRvbmx5QXJyYXk8Q29uZGl0aW9uLlNpbXBsZT4gPT4ge1xuICAgICAgICBjb25zdCBzaW1wbGU6IEFycmF5PENvbmRpdGlvbi5TaW1wbGU+ID0gW107XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGNvbmRpdGlvbikpIHtcbiAgICAgICAgICAgIGNvbmRpdGlvbi5mb3JFYWNoKChjKSA9PiB7XG4gICAgICAgICAgICAgICAgc2ltcGxlLnB1c2goLi4uX2dldEFsbFNpbXBsZShjKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNpbXBsZS5wdXNoKC4uLl9nZXRBbGxTaW1wbGUoY29uZGl0aW9uKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNpbXBsZTtcbiAgICB9O1xufVxuIiwgImltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuL2NvbmRpdGlvblwiO1xuaW1wb3J0IHsgRmFjdCB9IGZyb20gXCIuL2ZhY3RcIjtcbmltcG9ydCB7IERVdGlsIH0gZnJvbSBcIi4uL3V0aWxzL0RVdGlsXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZTxPblN1Y2Nlc3NBY3Rpb24sIE9uRmFpbHVyZUFjdGlvbj4ge1xuICByZWFkb25seSBpZD86IHN0cmluZztcbiAgcmVhZG9ubHkgZGVzY3JpcHRpb246IHN0cmluZztcbiAgcmVhZG9ubHkgYWxsOiBSZWFkb25seUFycmF5PENvbmRpdGlvbj47XG4gIHJlYWRvbmx5IHNvbWU6IFJlYWRvbmx5QXJyYXk8Q29uZGl0aW9uPjtcbiAgcmVhZG9ubHkgb25TdWNjZXNzOiBSZWFkb25seUFycmF5PE9uU3VjY2Vzc0FjdGlvbj47XG4gIHJlYWRvbmx5IG9uRmFpbHVyZTogUmVhZG9ubHlBcnJheTxPbkZhaWx1cmVBY3Rpb24+O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIFJ1bGUge1xuICAvKipcbiAgICogVmFsaWRhdGVzIHRoYXQgdGhlIHJ1bGUgaXMgdmFsaWQuXG4gICAqIEBwYXJhbSBydWxlXG4gICAqL1xuXG4gIGV4cG9ydCBjb25zdCBpc0VtcHR5ID0gKHJ1bGU6IFJ1bGU8YW55LCBhbnk+KTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgZW1wdHlDb25kaXRpb25zID0gcnVsZS5hbGwubGVuZ3RoID09PSAwICYmIHJ1bGUuc29tZS5sZW5ndGggPT09IDA7XG4gICAgY29uc3QgZW1wdHlBY3Rpb25zID0gcnVsZS5vblN1Y2Nlc3MubGVuZ3RoID09PSAwICYmIHJ1bGUub25GYWlsdXJlLmxlbmd0aCA9PT0gMDtcbiAgICByZXR1cm4gZW1wdHlDb25kaXRpb25zIHx8IGVtcHR5QWN0aW9ucztcbiAgfTtcblxuICBleHBvcnQgY29uc3Qgc29sdmUgPSAocnVsZTogUnVsZTxhbnksIGFueT4sIGZhY3RzOiBSZWFkb25seUFycmF5PEZhY3Q+KTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKHJ1bGUuc29tZS5sZW5ndGggPT09IDAgJiYgcnVsZS5hbGwubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBUT0RPIFJFVFVSTiBXQVJOSU5HPyBPUiBMT0dHSU5HID9cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBzb21lU29sdmVkID0gcnVsZS5zb21lLm1hcCgoY29uZGl0aW9uKSA9PiBDb25kaXRpb24uZXZhbHVhdGUoY29uZGl0aW9uLCBmYWN0cykpO1xuXG4gICAgY29uc3Qgc29tZVJlc3VsdCA9IHNvbWVTb2x2ZWQubGVuZ3RoID09PSAwIHx8IHNvbWVTb2x2ZWQuc29tZShEVXRpbC5pc1RydWUpO1xuXG4gICAgY29uc3QgYWxsU29sdmVkID0gcnVsZS5hbGwubWFwKChjb25kaXRpb24pID0+IENvbmRpdGlvbi5ldmFsdWF0ZShjb25kaXRpb24sIGZhY3RzKSkuZXZlcnkoRFV0aWwuaXNUcnVlKTtcblxuICAgIHJldHVybiBhbGxTb2x2ZWQgJiYgc29tZVJlc3VsdDtcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBGYWN0IH0gZnJvbSBcIi4vZmFjdFwiO1xuaW1wb3J0IHsgUnVsZSB9IGZyb20gXCIuL3J1bGVcIjtcblxuZXhwb3J0IGludGVyZmFjZSBTb2x2ZVJlc3VsdDxTLCBGPiB7XG4gIG1hdGNoaW5nOiBSZWFkb25seUFycmF5PE1hdGNoPFMsIEY+PjtcbiAgZXJyb3JzOiBSZWFkb25seUFycmF5PFJ1bGVFbmdpbmVFcnJvcj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWF0Y2g8UywgRj4ge1xuICByZWFkb25seSBtYXRjaGluZ1J1bGVJZDogc3RyaW5nO1xuICByZWFkb25seSBydWxlRGVzY3JpcHRpb246IHN0cmluZztcbiAgcmVhZG9ubHkgYWN0aW9uTGlzdDogUmVhZG9ubHlBcnJheTxTPiB8IFJlYWRvbmx5QXJyYXk8Rj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZUVuZ2luZUVycm9yIHtcbiAgcmVhZG9ubHkga2luZD86IHN0cmluZztcbiAgcmVhZG9ubHkgbWVzc2FnZTogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgUnVsZUVuZ2luZTxTLCBGPiB7XG4gIGNvbnN0cnVjdG9yKCkge31cblxuICBzb2x2ZUFsbChydWxlczogUnVsZTxTLCBGPltdLCBmYWN0czogRmFjdFtdKTogU29sdmVSZXN1bHQ8UywgRj4ge1xuICAgIGNvbnN0IGVycm9yczogUnVsZUVuZ2luZUVycm9yW10gPSBbXTtcbiAgICBjb25zdCBtYXRjaGluZzogTWF0Y2g8UywgRj5bXSA9IFtdO1xuICAgIHJ1bGVzLmZvckVhY2goKHJ1bGUpID0+IHtcbiAgICAgIGlmIChSdWxlLmlzRW1wdHkocnVsZSkpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goeyBtZXNzYWdlOiBcIkVtcHR5IHJ1bGU6IFwiICsgcnVsZS5pZCB9KTtcbiAgICAgIH0gZWxzZSBpZiAoUnVsZS5zb2x2ZShydWxlLCBmYWN0cykpIHtcbiAgICAgICAgY29uc3QgbWF0Y2g6IE1hdGNoPFMsIEY+ID0ge1xuICAgICAgICAgIHJ1bGVEZXNjcmlwdGlvbjogcnVsZS5kZXNjcmlwdGlvbixcbiAgICAgICAgICBtYXRjaGluZ1J1bGVJZDogcnVsZS5pZCA/PyBcIm5vLWlkLWdpdmVuXCIsXG4gICAgICAgICAgYWN0aW9uTGlzdDogWy4uLnJ1bGUub25TdWNjZXNzXSxcbiAgICAgICAgfTtcbiAgICAgICAgbWF0Y2hpbmcucHVzaChtYXRjaCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHsgbWF0Y2hpbmcsIGVycm9ycyB9O1xuICB9XG5cbiAgc29sdmUocnVsZTogUnVsZTxTLCBGPiwgZmFjdHM6IEZhY3RbXSk6IGJvb2xlYW4ge1xuICAgIC8vIFRPRE8gVmFsaWRhdGUsIGFuZCBSZXR1cm4gcmVzdWx0XG4gICAgcmV0dXJuIFJ1bGUuc29sdmUocnVsZSwgZmFjdHMpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgUGFnZUR0byB9IGZyb20gXCIuLi9kdG8vU2NoZW1hRHRvXCI7XG5cbmV4cG9ydCBjbGFzcyBOZXh0UXVlIHtcbiAgICBwcml2YXRlIG9yaWdpbmFsT3JkZXI6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiA9IFtdO1xuICAgIHByaXZhdGUgYWxsUGFnZXM6IFBhZ2VEdG9bXSA9IFtdO1xuICAgIHByaXZhdGUgZXhjbHVkZWRUYWdzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgcHJpdmF0ZSBleGNsdWRlZEJ5UGFnZUlkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgcHJpdmF0ZSByZW1haW5pbmc6IFBhZ2VEdG9bXSA9IFtdO1xuICAgIGNvbnN0cnVjdG9yKHBhZ2VzOiBQYWdlRHRvW10gPSBbXSkge1xuICAgICAgICB0aGlzLnJlc2V0UXVlKHBhZ2VzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaWxsIHJlc2V0IHF1ZSB3aXRoIHRoZSBuZXcgcGFnZXMuXG4gICAgICogQHBhcmFtIHBhZ2VzXG4gICAgICovXG4gICAgcmVzZXRRdWUocGFnZXM6IFBhZ2VEdG9bXSkge1xuICAgICAgICB0aGlzLmFsbFBhZ2VzID0gWy4uLnBhZ2VzXTtcbiAgICAgICAgdGhpcy5yZW1haW5pbmcgPSBbLi4ucGFnZXNdO1xuICAgICAgICB0aGlzLmV4Y2x1ZGVkVGFncyA9IG5ldyBTZXQoKTtcbiAgICAgICAgdGhpcy5leGNsdWRlZEJ5UGFnZUlkID0gbmV3IFNldCgpO1xuICAgICAgICB0aGlzLm9yaWdpbmFsT3JkZXIgPSB0aGlzLmFsbFBhZ2VzLm1hcCgocCkgPT4gcC5pZCk7XG4gICAgfVxuXG4gICAgcG9wKCk6IFBhZ2VEdG8gfCBmYWxzZSB7XG4gICAgICAgIGNvbnN0IG5leHQgPSB0aGlzLnJlbWFpbmluZy5zaGlmdCgpO1xuICAgICAgICAvLyBUT0RPIENMT05FPz9cbiAgICAgICAgcmV0dXJuIG5leHQgPz8gZmFsc2U7XG4gICAgfVxuXG4gICAgcGVlaygpOiBQYWdlRHRvIHwgZmFsc2Uge1xuICAgICAgICBjb25zdCBuZXh0ID0gdGhpcy5yZW1haW5pbmdbMF07XG4gICAgICAgIHJldHVybiBuZXh0ID8/IGZhbHNlO1xuICAgIH1cblxuICAgIGp1bXBUb1BhZ2VCeUlkKHBhZ2VJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5yZW1haW5pbmcuZmluZEluZGV4KChwKSA9PiBwLmlkID09PSBwYWdlSWQpO1xuICAgICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1haW5pbmcgPSB0aGlzLnJlbWFpbmluZy5zbGljZShpbmRleCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJlbW92ZUJ5VGFnKHRhZzogc3RyaW5nIHwgc3RyaW5nW10pIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGFnKSkge1xuICAgICAgICAgICAgdGFnLmZvckVhY2goKHRhZykgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZXhjbHVkZWRUYWdzLmFkZCh0YWcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmV4Y2x1ZGVkVGFncy5hZGQodGFnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZpbHRlclJlbWFpbmluZygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdpbGwgbm90IGJlIGluY2x1ZGVkXG4gICAgICogQHBhcmFtIHBhZ2VzXG4gICAgICovXG4gICAgaW5zZXJ0QXNOZXh0QnlGb3JjZShwYWdlczogUGFnZUR0b1tdKSB7XG4gICAgICAgIHRoaXMucmVtYWluaW5nLnVuc2hpZnQoLi4ucGFnZXMpO1xuICAgIH1cblxuICAgIHJlbW92ZUJ5UGFnZUlkKHBhZ2VJZDogc3RyaW5nIHwgc3RyaW5nW10pIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocGFnZUlkKSkge1xuICAgICAgICAgICAgcGFnZUlkLmZvckVhY2goKGlkKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5leGNsdWRlZEJ5UGFnZUlkLmFkZChpZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZXhjbHVkZWRCeVBhZ2VJZC5hZGQocGFnZUlkKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZpbHRlclJlbWFpbmluZygpO1xuICAgICAgICAvLyB0aGlzLmV4Y2x1ZGVkQnlQYWdlSWQuYWRkKHBhZ2VJZCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmaWx0ZXJSZW1haW5pbmcoKSB7XG4gICAgICAgIHRoaXMucmVtYWluaW5nID0gdGhpcy5yZW1haW5pbmcuZmlsdGVyKChwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0YWdzID0gcC50YWdzID8/IFtdO1xuICAgICAgICAgICAgY29uc3QgaXNJbmNsdWVkZWRCeVRhZyA9ICF0YWdzLnNvbWUoKHRhZykgPT4gdGhpcy5leGNsdWRlZFRhZ3MuaGFzKHRhZykpO1xuICAgICAgICAgICAgY29uc3QgaXNJbmNsdWRlZEJ5UGFnZUlkID0gIXRoaXMuZXhjbHVkZWRCeVBhZ2VJZC5oYXMocC5pZCk7XG4gICAgICAgICAgICByZXR1cm4gaXNJbmNsdWRlZEJ5UGFnZUlkICYmIGlzSW5jbHVlZGVkQnlUYWc7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBnZXQgaXNFbXB0eSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVtYWluaW5nLmxlbmd0aCA9PT0gMDtcbiAgICB9XG4gICAgZ2V0IHNpemUoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVtYWluaW5nLmxlbmd0aDtcbiAgICB9XG4gICAgZ2V0IHBhZ2VDb3VudCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5vcmlnaW5hbE9yZGVyLmxlbmd0aDtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQW5zd2VyZWRRdWVzdGlvbiwgSGlzdG9yeVF1ZSwgUGFnZUhpc3RvcnkgfSBmcm9tIFwiLi9oaXN0b3J5LXF1ZVwiO1xuaW1wb3J0IHsgUnVsZUVuZ2luZSB9IGZyb20gXCIuLi9ydWxlcy9ydWxlLWVuZ2luZVwiO1xuaW1wb3J0IHsgTmV4dFF1ZSB9IGZyb20gXCIuL25leHQtcXVlXCI7XG5pbXBvcnQgeyBQYWdlRHRvLCBTY2hlbWFEdG8gfSBmcm9tIFwiLi4vZHRvL1NjaGVtYUR0b1wiO1xuaW1wb3J0IHsgTmF2aWdhdGlvbkNvbW1hbmQsIFBhZ2VRdWVDb21tYW5kIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kXCI7XG5pbXBvcnQgeyBEVXRpbCB9IGZyb20gXCIuLi91dGlscy9EVXRpbFwiO1xuXG5leHBvcnQgdHlwZSBEUGxheWVyRGF0YSA9IFBpY2s8U2NoZW1hRHRvLCBcInBhZ2VzXCIgfCBcInBhZ2VTZXF1ZW5jZXNcIiB8IFwicnVsZXNcIj47XG5leHBvcnQgY2xhc3MgRFBsYXllciB7XG4gIHByaXZhdGUgaGlzdG9yeSA9IG5ldyBIaXN0b3J5UXVlKCk7XG4gIHByaXZhdGUgcnVsZUVuZ2luZSA9IG5ldyBSdWxlRW5naW5lPFBhZ2VRdWVDb21tYW5kLCBQYWdlUXVlQ29tbWFuZD4oKTtcbiAgcHJpdmF0ZSBuZXh0UXVlID0gbmV3IE5leHRRdWUoKTtcbiAgcHJpdmF0ZSBkYXRhOiBEUGxheWVyRGF0YTtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBEUGxheWVyRGF0YSkge1xuICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgdGhpcy5uZXh0UXVlLnJlc2V0UXVlKGRhdGEucGFnZXMpO1xuICB9XG5cbiAgc2F2ZUhpc3RvcnkocGFnZUhpc3Rvcnk6IFBhZ2VIaXN0b3J5KSB7XG4gICAgY29uc29sZS5sb2coXCJTQVZFIEhJU1RPUllcIiwgcGFnZUhpc3RvcnkpO1xuICAgIHRoaXMuaGlzdG9yeS5hZGRUb0hpc3RvcnkocGFnZUhpc3RvcnkpO1xuICAgIGNvbnN0IGZhY3RzID0gdGhpcy5oaXN0b3J5LmdldEZhY3RzKCk7XG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5ydWxlRW5naW5lLnNvbHZlQWxsKHRoaXMuZGF0YS5ydWxlcywgZmFjdHMpO1xuICAgIGNvbnN0IG1hdGNoaW5nUnVsZXMgPSByZXN1bHQubWF0Y2hpbmc7XG4gICAgY29uc3QgYWN0aW9ucyA9IG1hdGNoaW5nUnVsZXMubWFwKChyKSA9PiByLmFjdGlvbkxpc3QpLmZsYXQoMSk7XG4gICAgYWN0aW9ucy5mb3JFYWNoKChhKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhhLnBheWxvYWQpO1xuICAgICAgc3dpdGNoIChhLmtpbmQpIHtcbiAgICAgICAgY2FzZSBcIlBBR0VfUVVFX0pVTVBfVE9fUEFHRV9DT01NQU5EXCI6XG4gICAgICAgICAgdGhpcy5uZXh0UXVlLmp1bXBUb1BhZ2VCeUlkKGEucGF5bG9hZC5wYWdlSWQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiUEFHRV9RVUVfRVhDTFVERV9CWV9QQUdFX0lEX0NPTU1BTkRcIjpcbiAgICAgICAgICB0aGlzLm5leHRRdWUucmVtb3ZlQnlQYWdlSWQoYS5wYXlsb2FkLnBhZ2VJZHMpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiUEFHRV9RVUVfRVhDTFVERV9CWV9UQUdfQ09NTUFORFwiOlxuICAgICAgICAgIHRoaXMubmV4dFF1ZS5yZW1vdmVCeVRhZyhhLnBheWxvYWQudGFnSWRzKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIlVOS05PV04gQUNUSU9OXCIsIGEpO1xuICAgICAgICAgIGNvbnN0IGNoZWNrOiBuZXZlciA9IGE7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coYWN0aW9ucyk7XG4gIH1cblxuICBnZXRSZXN1bHRzKCk6IEFuc3dlcmVkUXVlc3Rpb25bXSB7XG4gICAgcmV0dXJuIHRoaXMuaGlzdG9yeS5nZXRBbnN3ZXJzKCk7XG4gIH1cblxuICBwcml2YXRlIGdvVG9QYWdlQnlJZChwYWdlSWQ6IHN0cmluZykge1xuICAgIHRoaXMubmV4dFF1ZS5qdW1wVG9QYWdlQnlJZChwYWdlSWQpO1xuICB9XG5cbiAgaGFuZGxlTmF2aWdhdGlvbkNvbW1hbmQoY29tbWFuZDogTmF2aWdhdGlvbkNvbW1hbmQpIHtcbiAgICBzd2l0Y2ggKGNvbW1hbmQua2luZCkge1xuICAgICAgY2FzZSBcIlBBR0VfUVVFX05FWFRfUEFHRV9DT01NQU5EXCI6XG4gICAgICAgIC8vIE5PIE5FRUQgVE8gRE8gQU5ZVEhJTkdcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiUEFHRV9RVUVfR09fVE9fUEFHRV9DT01NQU5EXCI6XG4gICAgICAgIHRoaXMuZ29Ub1BhZ2VCeUlkKGNvbW1hbmQucGF5bG9hZC5wYWdlSWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJQQUdFX1FVRV9HT19UT19TRVFVRU5DRV9DT01NQU5EXCI6XG4gICAgICAgIHRoaXMuaW5zZXJ0U2VxdWVuY2VCeUlkKGNvbW1hbmQucGF5bG9hZC5zZXF1ZW5jZUlkKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIERVdGlsLm5ldmVyQ2hlY2soY29tbWFuZCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0TmV4dFBhZ2UoKTogUGFnZUR0byB8IGZhbHNlIHtcbiAgICAvLyBUT0RPIEhBTkRMRSBSVUxFUyEhXG4gICAgcmV0dXJuIHRoaXMubmV4dFF1ZS5wb3AoKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5zZXJ0U2VxdWVuY2VCeUlkKGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBzZXEgPSB0aGlzLmRhdGEucGFnZVNlcXVlbmNlcz8uZmluZCgocykgPT4gcy5pZCA9PT0gaWQpO1xuICAgIGlmIChzZXEpIHtcbiAgICAgIHRoaXMubmV4dFF1ZS5pbnNlcnRBc05leHRCeUZvcmNlKFsuLi5zZXEucGFnZXNdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSE9XIFRPIEhBTkRMRSBJTlZBTElEIElEX1JFRlM/PyBMT0dHRVI/P1xuICAgICAgLy8gTE9HIElOVkFMSUQgQ09NTUFORC5cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVG90YWwgbnVtYmVyIG9mIHBhZ2VzLlxuICAgKi9cbiAgZ2V0IHBhZ2VDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm5leHRRdWUucGFnZUNvdW50O1xuICB9XG59XG4iLCAiaW1wb3J0IHsgRENvbW1hbmQsIEVsZW1lbnRDb21tYW5kLCBTdGF0ZUNvbW1hbmQgfSBmcm9tIFwiLi4vY29tbWFuZHMvRENvbW1hbmRcIjtcbmltcG9ydCB7IERFdmVudCB9IGZyb20gXCIuLi9ldmVudHMvREV2ZW50c1wiO1xuaW1wb3J0IHsgQ29uZGl0aW9uIH0gZnJvbSBcIi4uL3J1bGVzL2NvbmRpdGlvblwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIERFdmVudEhhbmRsZXI8RSBleHRlbmRzIERFdmVudCA9IERFdmVudD4ge1xuICAgIHJlYWRvbmx5IG9uRXZlbnQ6IEVbXCJraW5kXCJdO1xuICAgIHJlYWRvbmx5IHdoZW4/OiB7IHByb2R1Y2VySWQ/OiBzdHJpbmc7IGNvbmRpdGlvbj86IENvbmRpdGlvbiB9O1xuICAgIHJlYWRvbmx5IHRoZW5FeGVjdXRlOiBSZWFkb25seUFycmF5PERDb21tYW5kPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBRdWVyeUNoYW5nZWRIYW5kbGVyIHtcbiAgICByZWFkb25seSBxdWVyeU5hbWU6IHN0cmluZztcbiAgICByZWFkb25seSB3aGVuVHJ1ZTogUmVhZG9ubHlBcnJheTxFbGVtZW50Q29tbWFuZD47XG4gICAgcmVhZG9ubHkgd2hlbkZhbHNlOiBSZWFkb25seUFycmF5PEVsZW1lbnRDb21tYW5kPjtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBERXZlbnRIYW5kbGVyIHtcbiAgICBleHBvcnQgdHlwZSBMb29rVXAgPSBNYXA8REV2ZW50SGFuZGxlcltcIm9uRXZlbnRcIl0sIEFycmF5PERFdmVudEhhbmRsZXI+PjtcbiAgICBleHBvcnQgY29uc3QgY3JlYXRlTG9va1VwID0gKGhhbmRsZXJzPzogUmVhZG9ubHlBcnJheTxERXZlbnRIYW5kbGVyPik6IExvb2tVcCA9PiB7XG4gICAgICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8REV2ZW50SGFuZGxlcltcIm9uRXZlbnRcIl0sIEFycmF5PERFdmVudEhhbmRsZXI+PigpO1xuICAgICAgICBoYW5kbGVycz8uZm9yRWFjaCgoaCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qga2luZCA9IGgub25FdmVudDtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSBtYXAuZ2V0KGtpbmQpO1xuICAgICAgICAgICAgY29uc3QgYWN0aW9ucyA9IGN1cnJlbnQgPyBbLi4uY3VycmVudCwgaF0gOiBbaF07XG4gICAgICAgICAgICBtYXAuc2V0KGtpbmQsIGFjdGlvbnMpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG1hcDtcbiAgICB9O1xufVxuIiwgImltcG9ydCB7IERTdHlsZSB9IGZyb20gXCIuL0RTdHlsZVwiO1xuaW1wb3J0IHsgREVsZW1lbnRCYXNlRHRvIH0gZnJvbSBcIi4uL2R0by9ERWxlbWVudC5kdG9cIjtcbmltcG9ydCB7IERDb21tYW5kLCBFbGVtZW50Q29tbWFuZCB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZFwiO1xuaW1wb3J0IHsgRENvbW1hbmRCdXMgfSBmcm9tIFwiLi4vY29tbWFuZHMvRENvbW1hbmRCdXNcIjtcbmltcG9ydCB7IERFdmVudEhhbmRsZXIgfSBmcm9tIFwiLi4vZXZlbnQtaGFuZGxlcnMvREV2ZW50SGFuZGxlclwiO1xuaW1wb3J0IHsgRFV0aWwgfSBmcm9tIFwiLi4vdXRpbHMvRFV0aWxcIjtcbmltcG9ydCB7IEV2ZW50QnVzIH0gZnJvbSBcIi4uL2V2ZW50cy9ldmVudC1idXNcIjtcbmltcG9ydCB7IERUaW1lc3RhbXAgfSBmcm9tIFwiLi4vY29tbW9uL0RUaW1lc3RhbXBcIjtcbmltcG9ydCB7IEFuaW1hdGlvbkR0byB9IGZyb20gXCIuLi9kdG8vQW5pbWF0aW9uRHRvXCI7XG5pbXBvcnQgeyBTY2FsZVNlcnZpY2UgfSBmcm9tIFwiLi4vZW5naW5lL3NjYWxlXCI7XG5pbXBvcnQgeyBEU3RhdGUgfSBmcm9tIFwiLi4vc3RhdGUvRHN0YXRlXCI7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBERWxlbWVudDxUIGV4dGVuZHMgSFRNTEVsZW1lbnQ+IHtcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgZWw6IFQ7XG4gICAgcHJpdmF0ZSBjbGlja0hhbmRsZXJJc0VuYWJsZWQgPSB0cnVlO1xuICAgIHJlYWRvbmx5IGlkOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBpc0FuaW1hdGluZ1NlbGYgPSBmYWxzZTtcbiAgICBwcm90ZWN0ZWQgY3VyclN0eWxlOiBQYXJ0aWFsPERTdHlsZT4gPSB7XG4gICAgICAgIGZvbnRTaXplOiB7IF91bml0OiBcInB4XCIsIHZhbHVlOiAxMDAgfSxcbiAgICAgICAgZm9udFdlaWdodDogNTAwLFxuICAgICAgICB0ZXh0Q29sb3I6IFwiYmxhY2tcIixcbiAgICAgICAgb3BhY2l0eTogMSxcbiAgICB9O1xuXG4gICAgLy8gcHJpdmF0ZSByZWFkb25seSBvblF1ZXJ5Q2hhbmdlZEhhbmRsZXJzID1cbiAgICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50SGFuZGxlcnM6IERFdmVudEhhbmRsZXIuTG9va1VwO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBjb21tYW5kQnVzOiBEQ29tbWFuZEJ1cztcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXZlbnRCdXM6IEV2ZW50QnVzO1xuICAgIHByb3RlY3RlZCBzY2FsZTogU2NhbGVTZXJ2aWNlO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgYmFzZUR0bzogREVsZW1lbnRCYXNlRHRvO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBzdWJzY3JpcHRpb25zID0gbmV3IFNldDwoKSA9PiB2b2lkPigpO1xuXG4gICAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKFxuICAgICAgICBlbDogVCxcbiAgICAgICAgZXZlbnRCdXM6IEV2ZW50QnVzLFxuICAgICAgICBjb21tYW5kQnVzOiBEQ29tbWFuZEJ1cyxcbiAgICAgICAgZHRvOiBERWxlbWVudEJhc2VEdG8sXG4gICAgICAgIHNjYWxlOiBTY2FsZVNlcnZpY2VcbiAgICApIHtcbiAgICAgICAgdGhpcy5lbCA9IGVsO1xuICAgICAgICB0aGlzLmlkID0gZHRvLmlkO1xuICAgICAgICB0aGlzLmJhc2VEdG8gPSBkdG87XG4gICAgICAgIC8vIHRoaXMuZWwuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG4gICAgICAgIHRoaXMuY29tbWFuZEJ1cyA9IGNvbW1hbmRCdXM7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgICAgICAgdGhpcy5ldmVudEhhbmRsZXJzID0gREV2ZW50SGFuZGxlci5jcmVhdGVMb29rVXAoZHRvLmV2ZW50SGFuZGxlcnMpO1xuICAgICAgICB0aGlzLnNjYWxlID0gc2NhbGU7XG4gICAgICAgIC8vIENMSUNLXG4gICAgICAgIHRoaXMub25DbGlja0hhbmRsZXIgPSB0aGlzLm9uQ2xpY2tIYW5kbGVyLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuZWwub25jbGljayA9IHRoaXMub25DbGlja0hhbmRsZXI7XG5cbiAgICAgICAgLy8gSE9WRVJcbiAgICAgICAgdGhpcy5vbk1vdXNlT3ZlciA9IHRoaXMub25Nb3VzZU92ZXIuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5lbC5vbm1vdXNlb3ZlciA9IHRoaXMub25Nb3VzZU92ZXI7XG5cbiAgICAgICAgaWYgKGR0bykge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVTdHlsZXMoZHRvPy5zdHlsZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29tbWFuZFN1YnNjcmlwdGlvbiA9IHRoaXMuY29tbWFuZEJ1cy5zdWJzY3JpYmUoKGMpID0+IHtcbiAgICAgICAgICAgIGlmIChjLmtpbmQgPT09IFwiRUxFTUVOVF9TVFlMRV9DT01NQU5EXCIgJiYgYy50YXJnZXRJZCA9PT0gdGhpcy5pZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3R5bGUoYy5wYXlsb2FkLmNoYW5nZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGMua2luZCA9PT0gXCJFTEVNRU5UX0RJU0FCTEVfQ0xJQ0tfQ09NTUFORFwiICYmIGMudGFyZ2V0SWQgPT09IHRoaXMuaWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsaWNrSGFuZGxlcklzRW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGMua2luZCA9PT0gXCJFTEVNRU5UX0VOQUJMRV9DTElDS19DT01NQU5EXCIgJiYgYy50YXJnZXRJZCA9PT0gdGhpcy5pZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xpY2tIYW5kbGVySXNFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjLmtpbmQgPT09IFwiRUxFTUVOVF9BTklNQVRFX0NPTU1BTkRcIiAmJiBjLnRhcmdldElkID09PSB0aGlzLmlkKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJUT0RPIElNUExFTUVOVCBBTklNQVRJT05fSEFORExFUiBJTiBERWxlbWVudC5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRoaXMuaWQpO1xuICAgICAgICAvLyBUT0RPIE1FTU9SWSBMRUFLXG4gICAgICAgIGNvbnN0IGV2ZW50U3Vic2NyaXB0aW9uID0gdGhpcy5ldmVudEJ1cy5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBoYW5kbGVycyA9IHRoaXMuZXZlbnRIYW5kbGVycy5nZXQoZXZlbnQua2luZCkgPz8gW107XG4gICAgICAgICAgICAvLyBUT0RPIEFwcGx5IENvbmRpdGlvbnMgaW4gV0hFTi5cbiAgICAgICAgICAgIGNvbnN0IGNvbW1hbmRzID0gaGFuZGxlcnMubWFwKChoKSA9PiBoLnRoZW5FeGVjdXRlKS5mbGF0KDEpO1xuICAgICAgICAgICAgY29tbWFuZHMuZm9yRWFjaCgoY29tbWFuZCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgICAgICAgICAgICAgIC8vIHRoaXMuZG9BY3Rpb24oY29tbWFuZCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKGV2ZW50LmtpbmQgPT09IFwiSE9TVF9TQ0FMRV9DSEFOR0VEX0VWRU5UXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkhBTkRMRSBUSElTIFNDQUxFIENIQU5HRSEhXCIpO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlU3R5bGVzKHt9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGV2ZW50LmtpbmQgPT09IFwiU1RBVEVfUVVFUllfUkVTVUxUX0NIQU5HRURfRVZFTlRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMucXVlcnlDaGFuZ2VkSGFuZGxlcihldmVudC5kYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgXCJFTEVNRU5UOiBcIik7XG4gICAgICAgIHRoaXMubm9ybWFsaXplKCk7XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoY29tbWFuZFN1YnNjcmlwdGlvbik7XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoZXZlbnRTdWJzY3JpcHRpb24pO1xuICAgIH1cblxuICAgIGFic3RyYWN0IGRlc3Ryb3koKTogdm9pZDtcblxuICAgIC8vIGFic3RyYWN0IHNldFNjYWxlKHNjYWxlOiBudW1iZXIpOiB2b2lkO1xuXG4gICAgLy8gLyoqXG4gICAgLy8gICogVGhlIHB1cnBvc2Ugb2YgdGhpcyBmdW5jdGlvbiBpcyB0byByZS1lbWl0IGNvbW1hbmRzIGZyb20gZXZlbnQtaGFuZGxlcnM/XG4gICAgLy8gICogQHBhcmFtIGNvbW1hbmRcbiAgICAvLyAgKiBAcHJpdmF0ZVxuICAgIC8vICAqL1xuICAgIC8vIHByaXZhdGUgaGFuZGxlQ29tbWFuZHNFbWl0dGVkQnlQcml2YXRlRXZlbnRIYW5kbGVycyhjb21tYW5kOiBEQ29tbWFuZCkge1xuICAgIC8vICAgICBjb25zb2xlLmxvZyhjb21tYW5kKTtcbiAgICAvLyAgICAgc3dpdGNoIChjb21tYW5kLmtpbmQpIHtcbiAgICAvLyAgICAgICAgIGNhc2UgXCJFTEVNRU5UX1NUWUxFX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICBpZiAoY29tbWFuZC50YXJnZXRJZCA9PT0gdGhpcy5pZCkge1xuICAgIC8vICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVN0eWxlcyhjb21tYW5kLnBheWxvYWQuY2hhbmdlcyk7XG4gICAgLy8gICAgICAgICAgICAgfVxuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIkVMRU1FTlRfQU5JTUFURV9DT01NQU5EXCI6XG4gICAgLy8gICAgICAgICAgICAgLy8gVE9ETyBDSEVDSyBGT1IgVEFSR0VUIElEXG4gICAgLy8gICAgICAgICAgICAgdGhpcy5oYW5kbGVBbmltYXRlU2VsZkFjdGlvbihjb21tYW5kLnBheWxvYWQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIkVMRU1FTlRfRU5BQkxFX0NMSUNLX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNsaWNrSGFuZGxlcklzRW5hYmxlZCA9IHRydWU7XG4gICAgLy8gICAgICAgICAgICAgLy8gdGhpcy51cGRhdGVTdHlsZXMoY29tbWFuZC5wYXlsb2FkLmNoYW5nZXMpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIkVMRU1FTlRfRElTQUJMRV9DTElDS19DT01NQU5EXCI6XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5jbGlja0hhbmRsZXJJc0VuYWJsZWQgPSBmYWxzZTtcbiAgICAvLyAgICAgICAgICAgICAvLyB0aGlzLmhhbmRsZUFuaW1hdGVTZWxmQWN0aW9uKGNvbW1hbmQucGF5bG9hZCk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiVklERU9fUExBWV9DT01NQU5EXCI6XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiVklERU9fUEFVU0VfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIkVOR0lORV9MRUFWRV9QQUdFX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJWSURFT19KVU1QX1RPX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJWSURFT19TRVRfVk9MVU1FX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJBVURJT19QTEFZX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJBVURJT19QQVVTRV9DT01NQU5EXCI6XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiQVVESU9fU0VUX1ZPTFVNRV9DT01NQU5EXCI6XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiUEFHRV9RVUVfTkVYVF9QQUdFX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJQQUdFX1FVRV9HT19UT19TRVFVRU5DRV9DT01NQU5EXCI6XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiUEFHRV9RVUVfR09fVE9fUEFHRV9DT01NQU5EXCI6XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgLy8gICAgICAgICAgICAgYnJlYWs7XG4gICAgLy8gICAgICAgICBjYXNlIFwiUEFHRV9RVUVfRVhDTFVERV9CWV9QQUdFX0lEX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJQQUdFX1FVRV9KVU1QX1RPX1BBR0VfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgY2FzZSBcIlBBR0VfUVVFX0VYQ0xVREVfQllfVEFHX0NPTU1BTkRcIjpcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmNvbW1hbmRCdXMuZW1pdChjb21tYW5kKTtcbiAgICAvLyAgICAgICAgICAgICBicmVhaztcbiAgICAvLyAgICAgICAgIGNhc2UgXCJTVEFURV9NVVRBVEVfQ09NTUFORFwiOlxuICAgIC8vICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgIC8vICAgICAgICAgICAgIGJyZWFrO1xuICAgIC8vICAgICAgICAgZGVmYXVsdDpcbiAgICAvLyAgICAgICAgICAgICBEVXRpbC5uZXZlckNoZWNrKGNvbW1hbmQpO1xuICAgIC8vICAgICB9XG4gICAgLy8gfVxuXG4gICAgcHJpdmF0ZSBxdWVyeUNoYW5nZWRIYW5kbGVyKHJlc3VsdDogRFN0YXRlLlN0YXRlUXVlcnlSZXN1bHQpIHtcbiAgICAgICAgY29uc3QgbWF5YmVIYW5kbGVycyA9IHRoaXMuYmFzZUR0by5vblN0YXRlQ2hhbmdlO1xuICAgICAgICBpZiAoIW1heWJlSGFuZGxlcnMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBxdWVyeUhhbmRsZXJzID0gbWF5YmVIYW5kbGVycy5maWx0ZXIoKGgpID0+IGgucXVlcnlOYW1lID09PSByZXN1bHQucXVlcnlOYW1lKTtcbiAgICAgICAgcXVlcnlIYW5kbGVycy5mb3JFYWNoKChoKSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzdWx0LmN1cnIpIHtcbiAgICAgICAgICAgICAgICBoLndoZW5UcnVlLmZvckVhY2goKGNvbW1hbmQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy5kb0FjdGlvbihjb21tYW5kKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGgud2hlbkZhbHNlLmZvckVhY2goKGNvbW1hbmQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy5kb0FjdGlvbihjb21tYW5kKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoY29tbWFuZCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhmaW5kQnlRdWVyeSwgdmFsdWUpO1xuICAgICAgICAvLyBjb25zdCBhbGwgPSB0aGlzLmJhc2VEdG8uc3RhdGVRdWVyeUNoYW5nZSA/PyBbXTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uQ2xpY2tIYW5kbGVyKF86IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coKTtcbiAgICAgICAgaWYgKCF0aGlzLmNsaWNrSGFuZGxlcklzRW5hYmxlZCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5pZCArIFwiQ2xpY2sgZGlzYWJsZWRcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2xpY2tBY3Rpb24gPSB0aGlzLmJhc2VEdG8ub25DbGljaztcbiAgICAgICAgLy8gY29uc29sZS5sb2coXCJOQVRJVkUgQ0xJQ0sgRUxFTUVOVDogSGFuZGxlcnMgXCIgKyBjbGlja0FjdGlvbj8ubGVuZ3RoKTtcbiAgICAgICAgaWYgKGNsaWNrQWN0aW9uICYmIGNsaWNrQWN0aW9uLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiVEFSR0VUSUQ6IFwiICsgY2xpY2tBY3Rpb25bMF0udGFyZ2V0SWQgKyBcIiBcIiArIHRoaXMuaWQpO1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KHtcbiAgICAgICAgICAgICAgICBraW5kOiBcIlVTRVJfQ0xJQ0tFRF9FVkVOVFwiLFxuICAgICAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRVc2VyXCIsXG4gICAgICAgICAgICAgICAgcHJvZHVjZXJJZDogdGhpcy5pZCxcbiAgICAgICAgICAgICAgICBkYXRhOiB7IGVsZW1lbnRJZDogdGhpcy5pZCB9LFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY2xpY2tBY3Rpb24uZm9yRWFjaCgoY29tbWFuZCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY29tbWFuZEJ1cy5lbWl0KGNvbW1hbmQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uTW91c2VPdmVyKF86IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coZXYpO1xuICAgIH1cblxuICAgIHNldFN0eWxlKHN0eWxlOiBQYXJ0aWFsPERTdHlsZT4pIHtcbiAgICAgICAgdGhpcy51cGRhdGVTdHlsZXMoc3R5bGUpO1xuICAgIH1cblxuICAgIGFwcGVuZFlvdXJzZWxmKHBhcmVudDogSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgcGFyZW50LmFwcGVuZCh0aGlzLmVsKTtcbiAgICAgICAgLy8gY29uc29sZS5sb2cocGFyZW50KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGhhbmRsZUFuaW1hdGVTZWxmQWN0aW9uKGR0bzogQW5pbWF0aW9uRHRvKSB7XG4gICAgICAgIHRoaXMuaXNBbmltYXRpbmdTZWxmID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgeyBrZXlmcmFtZXMsIG9wdGlvbnMgfSA9IGR0bztcblxuICAgICAgICBjb25zdCBhbmltYXRpb24gPSB0aGlzLmVsLmFuaW1hdGUoa2V5ZnJhbWVzLCBvcHRpb25zLmR1cmF0aW9uKTtcbiAgICAgICAgYW5pbWF0aW9uLm9uZmluaXNoID0gKGU6IEFuaW1hdGlvblBsYXliYWNrRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGUudHlwZSk7XG4gICAgICAgICAgICB0aGlzLmlzQW5pbWF0aW5nU2VsZiA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICBhbmltYXRpb24ub25yZW1vdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJBTklNQVRJT04gUkVNT1ZFRDogXCIgKyBhbmltYXRpb24uaWQpO1xuICAgICAgICAgICAgdGhpcy5pc0FuaW1hdGluZ1NlbGYgPSBmYWxzZTtcbiAgICAgICAgfTtcbiAgICAgICAgYW5pbWF0aW9uLm9uY2FuY2VsID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFwiQU5JTUFUSU9OIENBTkNFTEVEOiBcIiArIGFuaW1hdGlvbi5pZCk7XG4gICAgICAgICAgICB0aGlzLmlzQW5pbWF0aW5nU2VsZiA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgbm9ybWFsaXplKCkge1xuICAgICAgICBEU3R5bGUubm9ybWFsaXplKHRoaXMuZWwpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCB1cGRhdGVTdHlsZXMoc3R5bGU6IFBhcnRpYWw8RFN0eWxlPikge1xuICAgICAgICB0aGlzLmN1cnJTdHlsZSA9IE9iamVjdC5hc3NpZ24odGhpcy5jdXJyU3R5bGUsIHN0eWxlKTtcbiAgICAgICAgRFN0eWxlLmFwcGx5U3R5bGVzKHRoaXMuZWwsIHRoaXMuY3VyclN0eWxlLCB0aGlzLnNjYWxlLnNjYWxlKTtcbiAgICAgICAgd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbCk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IERFbGVtZW50IH0gZnJvbSBcIi4vREVsZW1lbnRcIjtcbmltcG9ydCB7IEREaXZEdG8gfSBmcm9tIFwiLi4vZHRvL0RFbGVtZW50LmR0b1wiO1xuaW1wb3J0IHsgRFRleHQgfSBmcm9tIFwiLi9EVGV4dFwiO1xuaW1wb3J0IHsgREltZyB9IGZyb20gXCIuL0RJbWdcIjtcbmltcG9ydCB7IERDb21tYW5kQnVzIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kQnVzXCI7XG5pbXBvcnQgeyBFdmVudEJ1cyB9IGZyb20gXCIuLi9ldmVudHMvZXZlbnQtYnVzXCI7XG5pbXBvcnQgeyBTY2FsZVNlcnZpY2UgfSBmcm9tIFwiLi4vZW5naW5lL3NjYWxlXCI7XG5cbmV4cG9ydCBjbGFzcyBERGl2IGV4dGVuZHMgREVsZW1lbnQ8SFRNTERpdkVsZW1lbnQ+IHtcbiAgcHJpdmF0ZSByZWFkb25seSBUQUcgPSBcIlsgRERpdiBdOiBcIjtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRlZmF1bHRTdHlsZSA9IHsgeDogMjIsIHk6IDQgfTtcbiAgcHJpdmF0ZSBjaGlsZHJlbjogQXJyYXk8RFRleHQgfCBESW1nPiA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGR0bzogRERpdkR0byxcbiAgICBldmVudEJ1czogRXZlbnRCdXMsXG4gICAgYWN0aW9uU2VydmljZTogRENvbW1hbmRCdXMsXG4gICAgc2NhbGU6IFNjYWxlU2VydmljZSxcbiAgICBjaGlsZHJlbjogQXJyYXk8RFRleHQgfCBESW1nPixcbiAgKSB7XG4gICAgY29uc3QgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgc3VwZXIoZCwgZXZlbnRCdXMsIGFjdGlvblNlcnZpY2UsIGR0bywgc2NhbGUpO1xuICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjtcblxuICAgIHRoaXMuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQpID0+IHtcbiAgICAgIGNoaWxkLmFwcGVuZFlvdXJzZWxmKHRoaXMuZWwpO1xuICAgIH0pO1xuICB9XG5cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaCgodW5zdWJzY3JpYmUpID0+IHtcbiAgICAgIHVuc3Vic2NyaWJlKCk7XG4gICAgfSk7XG4gICAgdGhpcy5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZCkgPT4ge1xuICAgICAgY2hpbGQuZGVzdHJveSgpO1xuICAgIH0pO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgREVsZW1lbnQgfSBmcm9tIFwiLi9ERWxlbWVudFwiO1xuaW1wb3J0IHsgREltZ0R0byB9IGZyb20gXCIuLi9kdG8vREVsZW1lbnQuZHRvXCI7XG5pbXBvcnQgeyBEQ29tbWFuZEJ1cyB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZEJ1c1wiO1xuaW1wb3J0IHsgRXZlbnRCdXMgfSBmcm9tIFwiLi4vZXZlbnRzL2V2ZW50LWJ1c1wiO1xuaW1wb3J0IHsgU2NhbGVTZXJ2aWNlIH0gZnJvbSBcIi4uL2VuZ2luZS9zY2FsZVwiO1xuaW1wb3J0IHsgRFRpbWVzdGFtcCB9IGZyb20gXCIuLi9jb21tb24vRFRpbWVzdGFtcFwiO1xuXG5leHBvcnQgY2xhc3MgREltZyBleHRlbmRzIERFbGVtZW50PEhUTUxJbWFnZUVsZW1lbnQ+IHtcbiAgICBwcml2YXRlIHN0YXRpYyBJTUFHRV9DT1VOVCA9IDA7XG4gICAgcHJpdmF0ZSByZWFkb25seSBpbWFnZUNvdW50OiBudW1iZXI7XG4gICAgcmVhZG9ubHkgVEFHOiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgVElNSU5HX1RBRzogc3RyaW5nO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9hZFN0YXJ0OiBEVGltZXN0YW1wO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgZHRvOiBESW1nRHRvLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGFjdGlvblN1YmplY3Q6IERDb21tYW5kQnVzLFxuICAgICAgICByZWFkb25seSBldmVudEJ1czogRXZlbnRCdXMsXG4gICAgICAgIHJlYWRvbmx5IHNjYWxlU2VydmljZTogU2NhbGVTZXJ2aWNlXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIiksIGV2ZW50QnVzLCBhY3Rpb25TdWJqZWN0LCBkdG8sIHNjYWxlU2VydmljZSk7XG4gICAgICAgIERJbWcuSU1BR0VfQ09VTlQgKz0gMTtcbiAgICAgICAgdGhpcy5pbWFnZUNvdW50ID0gREltZy5JTUFHRV9DT1VOVDtcbiAgICAgICAgdGhpcy5UQUcgPSBcIltEX0lNRyBcIiArIERJbWcuSU1BR0VfQ09VTlQgKyBcIiBdOiBcIjtcbiAgICAgICAgdGhpcy5USU1JTkdfVEFHID0gXCJsb2FkLXRpbWUgKFwiICsgREltZy5JTUFHRV9DT1VOVCArIFwiKSBcIjtcbiAgICAgICAgdGhpcy5lbC5sb2FkaW5nID0gXCJlYWdlclwiO1xuICAgICAgICB0aGlzLmVsLnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuICAgICAgICB0aGlzLnNldFN0eWxlKGR0by5zdHlsZSk7XG4gICAgICAgIHRoaXMubG9hZFN0YXJ0ID0gRFRpbWVzdGFtcC5ub3coKTtcbiAgICAgICAgLy8gQmluZCBIYW5kbGVyc1xuICAgICAgICB0aGlzLm9uRXJyb3IgPSB0aGlzLm9uRXJyb3IuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5vbkxvYWQgPSB0aGlzLm9uTG9hZC5iaW5kKHRoaXMpO1xuICAgICAgICAvLyB0aGlzLm9uQ2xpY2sgPSB0aGlzLm9uQ2xpY2suYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5lbC5vbmxvYWQgPSB0aGlzLm9uTG9hZDtcbiAgICAgICAgdGhpcy5lbC5vbmVycm9yID0gdGhpcy5vbkVycm9yO1xuICAgICAgICAvLyB0aGlzLmVsLm9uY2xpY2sgPSB0aGlzLm9uQ2xpY2s7XG4gICAgICAgIHRoaXMuZWwuc3JjID0gZHRvLnVybDtcbiAgICAgICAgY29uc29sZS50aW1lKHRoaXMuVElNSU5HX1RBRyk7XG4gICAgfVxuXG4gICAgbG9nKCk6IHZvaWQge31cblxuICAgIHNldFNjYWxlKHNjYWxlOiBudW1iZXIpIHtcbiAgICAgICAgY29uc29sZS5sb2coc2NhbGUpO1xuICAgICAgICB0aGlzLnNldFN0eWxlKHRoaXMuY3VyclN0eWxlKTtcbiAgICB9XG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goKHVuc3Vic2NyaWJlKSA9PiB7XG4gICAgICAgICAgICB1bnN1YnNjcmliZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uRXJyb3IoZXY6IEV2ZW50IHwgc3RyaW5nKSB7XG4gICAgICAgIGlmIChldiBpbnN0YW5jZW9mIEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLlRBRyArIFwiIFwiICsgZXYudHlwZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLlRBRyArIGV2KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgb25Mb2FkKF86IEV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGxvYWRUaW1lID0gRFRpbWVzdGFtcC5kaWZmTm93KHRoaXMubG9hZFN0YXJ0KTtcblxuICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAgICAgICAga2luZDogXCJJTUFHRV9MT0FERURfRVZFTlRcIixcbiAgICAgICAgICAgIHByb2R1Y2VyOiBcIkRJbWFnZVwiLFxuICAgICAgICAgICAgcHJvZHVjZXJJZDogdGhpcy5pZCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRFRpbWVzdGFtcC5ub3coKSxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBsb2FkVGltZSxcbiAgICAgICAgICAgICAgICBuYXR1cmFsSGVpZ2h0OiB0aGlzLmVsLm5hdHVyYWxIZWlnaHQsXG4gICAgICAgICAgICAgICAgbmF0dXJhbFdpZHRoOiB0aGlzLmVsLm5hdHVyYWxXaWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMuZWwuaGVpZ2h0LFxuICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLmVsLndpZHRoLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IERFbGVtZW50IH0gZnJvbSBcIi4vREVsZW1lbnRcIjtcbmltcG9ydCB7IERUZXh0RHRvIH0gZnJvbSBcIi4uL2R0by9ERWxlbWVudC5kdG9cIjtcbmltcG9ydCB7IERDb21tYW5kQnVzIH0gZnJvbSBcIi4uL2NvbW1hbmRzL0RDb21tYW5kQnVzXCI7XG5pbXBvcnQgeyBFdmVudEJ1cyB9IGZyb20gXCIuLi9ldmVudHMvZXZlbnQtYnVzXCI7XG5pbXBvcnQgeyBTY2FsZVNlcnZpY2UgfSBmcm9tIFwiLi4vZW5naW5lL3NjYWxlXCI7XG5cbmV4cG9ydCBjbGFzcyBEVGV4dCBleHRlbmRzIERFbGVtZW50PEhUTUxQYXJhZ3JhcGhFbGVtZW50PiB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBUQUcgPSBcIlsgRFBhcmFncmFwaCBdOiBcIjtcbiAgICBwcm90ZWN0ZWQgZGVmYXVsdFN0eWxlID0ge307XG5cbiAgICBjb25zdHJ1Y3RvcihkdG86IERUZXh0RHRvLCBldmVudEJ1czogRXZlbnRCdXMsIGFjdGlvblNlcnZpY2U6IERDb21tYW5kQnVzLCBzY2FsZTogU2NhbGVTZXJ2aWNlKSB7XG4gICAgICAgIHN1cGVyKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJwXCIpLCBldmVudEJ1cywgYWN0aW9uU2VydmljZSwgZHRvLCBzY2FsZSk7XG4gICAgICAgIHRoaXMuZWwuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG4gICAgICAgIHRoaXMuZWwuaW5uZXJUZXh0ID0gXCJcIiArIGR0by50ZXh0O1xuICAgICAgICB0aGlzLnNldFN0eWxlKGR0by5zdHlsZSk7XG4gICAgfVxuXG4gICAgc2V0U2NhbGUoc2NhbGU6IG51bWJlcikge1xuICAgICAgICB0aGlzLnNldFN0eWxlKHRoaXMuY3VyclN0eWxlKTtcbiAgICAgICAgY29uc3QgZm9udFNpemUgPSB0aGlzLmVsLnN0eWxlLmZvbnRTaXplO1xuICAgICAgICBjb25zb2xlLmxvZyh0aGlzLlRBRyArIFwic2NhbGU6IFwiICsgc2NhbGUgKyBcIiBGb250c2l6ZTogXCIgKyBmb250U2l6ZSk7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goKHVuc3Vic2NyaWJlKSA9PiB7XG4gICAgICAgICAgICB1bnN1YnNjcmliZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgREVsZW1lbnQgfSBmcm9tIFwiLi4vRGVsZW1lbnQvREVsZW1lbnRcIjtcbmltcG9ydCB7IEREaXYgfSBmcm9tIFwiLi4vRGVsZW1lbnQvRGRpdlwiO1xuaW1wb3J0IHsgREltZyB9IGZyb20gXCIuLi9EZWxlbWVudC9ESW1nXCI7XG5pbXBvcnQgeyBEVGV4dCB9IGZyb20gXCIuLi9EZWxlbWVudC9EVGV4dFwiO1xuaW1wb3J0IHsgRERpdkR0bywgREVsZW1lbnREdG8gfSBmcm9tIFwiLi4vZHRvL0RFbGVtZW50LmR0b1wiO1xuaW1wb3J0IHsgRENvbW1hbmRCdXMgfSBmcm9tIFwiLi4vY29tbWFuZHMvRENvbW1hbmRCdXNcIjtcbmltcG9ydCB7IEV2ZW50QnVzIH0gZnJvbSBcIi4uL2V2ZW50cy9ldmVudC1idXNcIjtcbmltcG9ydCB7IFNjYWxlU2VydmljZSB9IGZyb20gXCIuL3NjYWxlXCI7XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVERWxlbWVudCA9IChcbiAgICBkdG86IERFbGVtZW50RHRvLFxuICAgIGFjdGlvbkJ1czogRENvbW1hbmRCdXMsXG4gICAgZXZlbnRCdXM6IEV2ZW50QnVzLFxuICAgIHNjYWxlOiBTY2FsZVNlcnZpY2Vcbik6IERFbGVtZW50PGFueT4gPT4ge1xuICAgIHN3aXRjaCAoZHRvLl90YWcpIHtcbiAgICAgICAgY2FzZSBcImRpdlwiOlxuICAgICAgICAgICAgY29uc3QgY2hpbGRFbHMgPSBjcmVhdGVDaGlsZHJlbkZvckRpdihkdG8sIGFjdGlvbkJ1cywgZXZlbnRCdXMsIHNjYWxlKTtcbiAgICAgICAgICAgIGNvbnN0IG5ld0RpdiA9IG5ldyBERGl2KGR0bywgZXZlbnRCdXMsIGFjdGlvbkJ1cywgc2NhbGUsIGNoaWxkRWxzKTtcbiAgICAgICAgICAgIHJldHVybiBuZXdEaXY7XG4gICAgICAgIGNhc2UgXCJpbWdcIjpcbiAgICAgICAgICAgIHJldHVybiBuZXcgREltZyhkdG8sIGFjdGlvbkJ1cywgZXZlbnRCdXMsIHNjYWxlKTtcbiAgICAgICAgY2FzZSBcInBcIjpcbiAgICAgICAgICAgIHJldHVybiBuZXcgRFRleHQoZHRvLCBldmVudEJ1cywgYWN0aW9uQnVzLCBzY2FsZSk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBjb25zdCBjaGVjazogbmV2ZXIgPSBkdG87XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIGR0byBnaXZlbiB0byB0aGUgY3JlYXRlREVsZW1lbnQgZnVuY3Rpb24uXCIpO1xuICAgICAgICAvLyBUT0RPIExPR0dJTkcgb3IgY3JlYXRlIGFueSBIVE1MLUVMRU1FTlQ/P1xuICAgIH1cbn07XG5cbmNvbnN0IGNyZWF0ZUNoaWxkcmVuRm9yRGl2ID0gKFxuICAgIGR0bzogRERpdkR0byxcbiAgICBhY3Rpb25TdWJqZWN0OiBEQ29tbWFuZEJ1cyxcbiAgICBldmVudEJ1czogRXZlbnRCdXMsXG4gICAgc2NhbGU6IFNjYWxlU2VydmljZVxuKTogRERpdltcImNoaWxkcmVuXCJdID0+IHtcbiAgICBjb25zdCBjaGlsZER0byA9IGR0by5jaGlsZHJlbjtcbiAgICBjb25zdCBjaGlsZEVsczogQXJyYXk8REltZyB8IERUZXh0PiA9IFtdO1xuICAgIC8vIGNvbnNvbGUubG9nKGNoaWxkRWxlbWVudHMpO1xuICAgIGNoaWxkRHRvLmZvckVhY2goKGR0bykgPT4ge1xuICAgICAgICBpZiAoZHRvLl90YWcgPT09IFwicFwiKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdUZXh0ID0gbmV3IERUZXh0KGR0bywgZXZlbnRCdXMsIGFjdGlvblN1YmplY3QsIHNjYWxlKTtcbiAgICAgICAgICAgIGNoaWxkRWxzLnB1c2gobmV3VGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGR0by5fdGFnID09PSBcImltZ1wiKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdJbWFnZSA9IG5ldyBESW1nKGR0bywgYWN0aW9uU3ViamVjdCwgZXZlbnRCdXMsIHNjYWxlKTtcbiAgICAgICAgICAgIGNoaWxkRWxzLnB1c2gobmV3SW1hZ2UpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNoaWxkRWxzO1xufTtcbiIsICJpbXBvcnQgeyBERWxlbWVudCB9IGZyb20gXCIuLi9EZWxlbWVudC9ERWxlbWVudFwiO1xuaW1wb3J0IHsgUGFnZUR0byB9IGZyb20gXCIuLi9kdG8vU2NoZW1hRHRvXCI7XG5pbXBvcnQgeyBjcmVhdGVERWxlbWVudCB9IGZyb20gXCIuL2VsZW1lbnQtZmFjdG9yeVwiO1xuaW1wb3J0IHsgRXZlbnRCdXMgfSBmcm9tIFwiLi4vZXZlbnRzL2V2ZW50LWJ1c1wiO1xuaW1wb3J0IHsgRENvbW1hbmRCdXMgfSBmcm9tIFwiLi4vY29tbWFuZHMvRENvbW1hbmRCdXNcIjtcbmltcG9ydCB7IERUaW1lc3RhbXAgfSBmcm9tIFwiLi4vY29tbW9uL0RUaW1lc3RhbXBcIjtcbmltcG9ydCB7IFNjYWxlU2VydmljZSB9IGZyb20gXCIuL3NjYWxlXCI7XG5cbmV4cG9ydCBjbGFzcyBEUGFnZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgVEFHID0gXCJbIERQYWdlIF06IFwiO1xuICBwcml2YXRlIGVsZW1lbnRzOiBERWxlbWVudDxIVE1MRWxlbWVudD5bXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50QnVzO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbW1hbmRCdXM7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2NhbGU6IFNjYWxlU2VydmljZTtcbiAgLy8gVG9kbyBHTE9CQUwgRVZFTlRfQlVTUyBBTkQgUEFHRSBFVkVOVFM6XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBkdG86IFBhZ2VEdG8sXG4gICAgZXZlbnRCdXM6IEV2ZW50QnVzLFxuICAgIGNvbW1hbmRCdXM6IERDb21tYW5kQnVzLFxuICAgIHNjYWxlOiBTY2FsZVNlcnZpY2UsXG4gICkge1xuICAgIHRoaXMuZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgICB0aGlzLmNvbW1hbmRCdXMgPSBjb21tYW5kQnVzO1xuICAgIHRoaXMuc2NhbGUgPSBzY2FsZTtcbiAgICB0aGlzLmVsZW1lbnRzID0gZHRvLmVsZW1lbnRzLm1hcCgoZHRvKSA9PiBjcmVhdGVERWxlbWVudChkdG8sIHRoaXMuY29tbWFuZEJ1cywgdGhpcy5ldmVudEJ1cywgdGhpcy5zY2FsZSkpO1xuICB9XG5cbiAgYXBwZW5kWW91cnNlbGYocGFyZW50OiBIVE1MRWxlbWVudCkge1xuICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCIgQVBQRU5ESU5HIFRPIFBBUkVOVFwiKTtcbiAgICB0aGlzLmVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICBlbC5hcHBlbmRZb3Vyc2VsZihwYXJlbnQpO1xuICAgICAgLy8gcGFyZW50LmFwcGVuZENoaWxkKGVsLmVsKTtcbiAgICB9KTtcblxuICAgIC8vIGlmICghcHJlbG9hZE1vZGUpIHtcbiAgICB0aGlzLmV2ZW50QnVzLmVtaXQoe1xuICAgICAga2luZDogXCJQQUdFX0VOVEVSX0VWRU5UXCIsXG4gICAgICB0aW1lc3RhbXA6IERUaW1lc3RhbXAubm93KCksXG4gICAgICBwcm9kdWNlcjogXCJEUGFnZVwiLFxuICAgICAgcHJvZHVjZXJJZDogdGhpcy5pZCxcbiAgICAgIGRhdGE6IHsgcGFnZUlkOiB0aGlzLmlkIH0sXG4gICAgfSk7XG4gICAgLy8gfVxuICB9XG5cbiAgZGVzdHJveSgpIHtcbiAgICB0aGlzLmVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICBlbC5kZXN0cm95KCk7XG4gICAgfSk7XG4gIH1cblxuICBsb2coKTogdm9pZCB7XG4gICAgLy8gY29uc29sZS5sb2codGhpcy5UQUcgKyAnc2NhbGUgLSAnICsgdGhpcy5zY2FsZSk7XG4gIH1cblxuICBnZXQgaWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZHRvLmlkO1xuICB9XG59XG4iLCAiZXhwb3J0IGNsYXNzIFNjYWxlU2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYmFzZUhlaWdodDtcbiAgcHJpdmF0ZSByZWFkb25seSBiYXNlV2lkdGg7XG4gIHByaXZhdGUgY29udGFpbmVySGVpZ2h0ID0gMTMwMDtcbiAgcHJpdmF0ZSBjb250YWluZXJXaWR0aCA9IDEzMDA7XG5cbiAgZ2V0IHNjYWxlKCkge1xuICAgIHJldHVybiB0aGlzLl9zY2FsZTtcbiAgfVxuXG4gIGdldCBwYWdlSGVpZ2h0KCkge1xuICAgIHJldHVybiB0aGlzLmJhc2VIZWlnaHQgKiB0aGlzLnNjYWxlO1xuICB9XG4gIGdldCBwYWdlV2lkdGgoKSB7XG4gICAgcmV0dXJuIHRoaXMuYmFzZVdpZHRoICogdGhpcy5fc2NhbGU7XG4gIH1cblxuICBwcml2YXRlIF9zY2FsZSA9IDE7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzdWJzY3JpYmVycyA9IG5ldyBTZXQ8KHNjYWxlOiBudW1iZXIpID0+IHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiB7IGJhc2VIZWlnaHQ6IG51bWJlcjsgYmFzZVdpZHRoOiBudW1iZXI7IGNvbnRhaW5lckhlaWdodDogbnVtYmVyOyBjb250YWluZXJXaWR0aDogbnVtYmVyIH0pIHtcbiAgICB0aGlzLmJhc2VIZWlnaHQgPSBjb25maWcuYmFzZUhlaWdodDtcbiAgICB0aGlzLmJhc2VXaWR0aCA9IGNvbmZpZy5iYXNlV2lkdGg7XG4gICAgdGhpcy5jb250YWluZXJIZWlnaHQgPSBjb25maWcuY29udGFpbmVySGVpZ2h0O1xuICAgIHRoaXMuY29udGFpbmVyV2lkdGggPSBjb25maWcuY29udGFpbmVyV2lkdGg7XG4gICAgdGhpcy51cGRhdGVTY2FsZSgpO1xuICB9XG5cbiAgc2V0Q29udGFpbmVyQm91bmRzKGJvdW5kczogeyBoZWlnaHQ6IG51bWJlcjsgd2lkdGg6IG51bWJlciB9KSB7XG4gICAgdGhpcy5jb250YWluZXJXaWR0aCA9IGJvdW5kcy53aWR0aDtcbiAgICB0aGlzLmNvbnRhaW5lckhlaWdodCA9IGJvdW5kcy5oZWlnaHQ7XG4gICAgdGhpcy51cGRhdGVTY2FsZSgpO1xuICB9XG4gIHByaXZhdGUgdXBkYXRlU2NhbGUoKSB7XG4gICAgY29uc3Qgc2NhbGVGbiA9IFNjYWxlLmNhbGModGhpcy5iYXNlSGVpZ2h0LCB0aGlzLmJhc2VXaWR0aCk7XG4gICAgY29uc3Qgc2NhbGUgPSBzY2FsZUZuKHsgaGVpZ2h0OiB0aGlzLmNvbnRhaW5lckhlaWdodCwgd2lkdGg6IHRoaXMuY29udGFpbmVyV2lkdGggfSk7XG4gICAgY29uc3QgaGFzQ2hhbmdlZCA9IHRoaXMuc2NhbGUgIT09IHNjYWxlO1xuICAgIHRoaXMuX3NjYWxlID0gc2NhbGU7XG4gICAgaWYgKGhhc0NoYW5nZWQpIHtcbiAgICAgIHRoaXMuc3Vic2NyaWJlcnMuZm9yRWFjaCgoZm4pID0+IHtcbiAgICAgICAgZm4odGhpcy5fc2NhbGUpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgb25DaGFuZ2Uoc2NhbGVDaGFuZ2VIYW5kbGVyOiAoc2NhbGU6IG51bWJlcikgPT4gdm9pZCwgc3Vic2NyaWJlcklkOiBzdHJpbmcpIHtcbiAgICAvLyBjb25zb2xlLmxvZyhzdWJzY3JpYmVySWQpO1xuICAgIHRoaXMuc3Vic2NyaWJlcnMuYWRkKHNjYWxlQ2hhbmdlSGFuZGxlcik7XG4gICAgc2NhbGVDaGFuZ2VIYW5kbGVyKHRoaXMuX3NjYWxlKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgdGhpcy5zdWJzY3JpYmVycy5kZWxldGUoc2NhbGVDaGFuZ2VIYW5kbGVyKTtcbiAgICB9O1xuICB9XG59XG5leHBvcnQgbmFtZXNwYWNlIFNjYWxlIHtcbiAgZXhwb3J0IGNvbnN0IGNhbGMgPSAoYmFzZUhlaWdodDogbnVtYmVyLCBiYXNlV2lkdGg6IG51bWJlcikgPT4ge1xuICAgIHJldHVybiAoY29udGFpbmVyOiB7IGhlaWdodDogbnVtYmVyOyB3aWR0aDogbnVtYmVyIH0pID0+IHtcbiAgICAgIGNvbnN0IGhlaWdodFJhdGlvID0gY29udGFpbmVyLmhlaWdodCAvIGJhc2VIZWlnaHQ7XG4gICAgICBjb25zdCB3aWR0aFJhdGlvID0gY29udGFpbmVyLndpZHRoIC8gYmFzZVdpZHRoO1xuICAgICAgcmV0dXJuIE1hdGgubWluKGhlaWdodFJhdGlvLCB3aWR0aFJhdGlvKTtcbiAgICB9O1xuICB9O1xuXG4gIHR5cGUgU2NhbGVQb3NJbnB1dCA9IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IGg6IG51bWJlcjsgdzogbnVtYmVyIH07XG5cbiAgZXhwb3J0IGNvbnN0IHNjYWxlRnVuY3Rpb25DcmVhdG9yID0gKHNjYWxlOiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gKHZhbHVlOiBudW1iZXIpID0+IHZhbHVlICogc2NhbGU7XG4gIH07XG59XG4iLCAiaW1wb3J0IHsgREF1ZGlvRHRvLCBESW1nRHRvLCBEVmlkZW9EdG8gfSBmcm9tIFwiLi4vZHRvL0RFbGVtZW50LmR0b1wiO1xuXG5leHBvcnQgY2xhc3MgUmVzb3VyY2VQcm92aWRlciB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBUQUcgPSBcIlsgUkVTT1VSQ0VfUFJPVklERVIgXTogXCI7XG4gICAgcHJpdmF0ZSByZWFkb25seSB2aWRlb01hcCA9IG5ldyBNYXA8c3RyaW5nLCBEVmlkZW9EdG8+KCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBhdWRpb01hcCA9IG5ldyBNYXA8c3RyaW5nLCBEQXVkaW9EdG8+KCk7XG4gICAgY29uc3RydWN0b3IoZGF0YTogeyB2aWRlb3M6IFJlYWRvbmx5QXJyYXk8RFZpZGVvRHRvPjsgYXVkaW86IFJlYWRvbmx5QXJyYXk8REF1ZGlvRHRvPiB9KSB7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCJWSURFT19DT1VOVCBcIiArIGRhdGEudmlkZW9zLmxlbmd0aCk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCJBVURJT19DT1VOVCBcIiArIGRhdGEuYXVkaW8ubGVuZ3RoKTtcbiAgICAgICAgZGF0YS52aWRlb3MuZm9yRWFjaCgodmlkZW8pID0+IHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9NYXAuc2V0KHZpZGVvLmlkLCB2aWRlbyk7XG4gICAgICAgIH0pO1xuICAgICAgICBkYXRhLmF1ZGlvLmZvckVhY2goKGF1ZGlvKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmF1ZGlvTWFwLnNldChhdWRpby5pZCwgYXVkaW8pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXRBdWRpb0J5SWQoaWQ6IHN0cmluZyk6IERBdWRpb0R0byB8IGZhbHNlIHtcbiAgICAgICAgY29uc3QgbWF5YmVBdWRpbyA9IHRoaXMuYXVkaW9NYXAuZ2V0KGlkKTtcbiAgICAgICAgaWYgKCFtYXliZUF1ZGlvKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKHRoaXMuVEFHICsgXCJBdWRpbyBieSBpZCBcIiArIGlkICsgXCIgZG9udCBleGlzdFwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF5YmVBdWRpbyA/PyBmYWxzZTtcbiAgICB9XG5cbiAgICBnZXRWaWRlb0J5SWQoaWQ6IHN0cmluZyk6IERWaWRlb0R0byB8IGZhbHNlIHtcbiAgICAgICAgY29uc3QgbWF5YmVWaWRlbyA9IHRoaXMudmlkZW9NYXAuZ2V0KGlkKTtcbiAgICAgICAgaWYgKCFtYXliZVZpZGVvKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKHRoaXMuVEFHICsgXCJWaWRlbyBieSBpZCBcIiArIGlkICsgXCIgZG9udCBleGlzdFwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF5YmVWaWRlbyA/PyBmYWxzZTtcbiAgICB9XG59XG4iLCAiZXhwb3J0IGNsYXNzIE9rPFQ+IGltcGxlbWVudHMgSVJlc3VsdDxUPiB7XG4gICAgY29uc3RydWN0b3IocmVhZG9ubHkgdmFsdWU6IFQpIHt9XG4gICAgaXNPaygpOiB0aGlzIGlzIE9rPFQ+IHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlzRmFpbHVyZSgpOiB0aGlzIGlzIEZhaWx1cmU8VD4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbWFwPEE+KGY6ICh0OiBUKSA9PiBBKTogSVJlc3VsdDxBPiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gZih0aGlzLnZhbHVlKTtcbiAgICAgICAgcmV0dXJuIG5ldyBPazxBPih2YWx1ZSk7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgRmFpbHVyZTxUPiBpbXBsZW1lbnRzIElSZXN1bHQ8VD4ge1xuICAgIGNvbnN0cnVjdG9yKHJlYWRvbmx5IG1lc3NhZ2U6IHN0cmluZykge31cbiAgICBpc0ZhaWx1cmUoKTogdGhpcyBpcyBGYWlsdXJlPFQ+IHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaXNPaygpOiB0aGlzIGlzIE9rPFQ+IHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIG1hcDxBPihfZjogKHQ6IFQpID0+IEEpOiBJUmVzdWx0PEE+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBGYWlsdXJlPEE+KHRoaXMubWVzc2FnZSk7XG4gICAgfVxufVxuXG5pbnRlcmZhY2UgSVJlc3VsdDxUPiB7XG4gICAgaXNPaygpOiB0aGlzIGlzIE9rPFQ+O1xuICAgIGlzRmFpbHVyZSgpOiB0aGlzIGlzIEZhaWx1cmU8VD47XG4gICAgbWFwPEE+KGY6ICh0OiBUKSA9PiBBKTogSVJlc3VsdDxBPjtcbn1cblxuZXhwb3J0IHR5cGUgUmVzdWx0PFQ+ID0gRmFpbHVyZTxUPiB8IE9rPFQ+O1xuZXhwb3J0IG5hbWVzcGFjZSBSZXN1bHQge1xuICAgIGV4cG9ydCBjb25zdCBvayA9IDxUPih2YWx1ZTogVCkgPT4gbmV3IE9rPFQ+KHZhbHVlKTtcbiAgICBleHBvcnQgY29uc3QgZmFpbHVyZSA9IDxUPihtZXNzYWdlOiBzdHJpbmcpID0+IG5ldyBGYWlsdXJlPFQ+KG1lc3NhZ2UpO1xufVxuIiwgImltcG9ydCB7IEZhY3QgfSBmcm9tIFwiLi4vcnVsZXMvZmFjdFwiO1xuaW1wb3J0IHsgQ29uZGl0aW9uIH0gZnJvbSBcIi4uL3J1bGVzL2NvbmRpdGlvblwiO1xuaW1wb3J0IHsgREV2ZW50IH0gZnJvbSBcIi4uL2V2ZW50cy9ERXZlbnRzXCI7XG5pbXBvcnQgeyBTdGF0ZUNvbW1hbmQgfSBmcm9tIFwiLi4vY29tbWFuZHMvRENvbW1hbmRcIjtcblxuZXhwb3J0IG5hbWVzcGFjZSBEU3RhdGUge1xuICAgIGludGVyZmFjZSBQcm9wRGVmaW5pdGlvbjxUeXBlTmFtZSwgVHlwZSBleHRlbmRzIHN0cmluZyB8IG51bWJlcj4ge1xuICAgICAgICByZWFkb25seSBfdHlwZTogVHlwZU5hbWU7XG4gICAgICAgIHJlYWRvbmx5IHByb3BOYW1lOiBzdHJpbmc7XG4gICAgICAgIHJlYWRvbmx5IHByb3BEZXNjcmlwdGlvbjogc3RyaW5nO1xuICAgICAgICByZWFkb25seSBpbml0aWFsVmFsdWU/OiBUeXBlO1xuICAgICAgICByZWFkb25seSBvcHRpb25zPzogUmVhZG9ubHlBcnJheTxQcm9wVmFsdWU8VHlwZT4+O1xuICAgIH1cblxuICAgIGV4cG9ydCB0eXBlIE51bWVyaWNQcm9wID0gUHJvcERlZmluaXRpb248XCJudW1iZXJcIiwgbnVtYmVyPjtcbiAgICBleHBvcnQgdHlwZSBTdHJpbmdQcm9wID0gUHJvcERlZmluaXRpb248XCJzdHJpbmdcIiwgc3RyaW5nPjtcblxuICAgIGV4cG9ydCBpbnRlcmZhY2UgZnJvbUV2ZW50SGFuZGxlciB7XG4gICAgICAgIHJlYWRvbmx5IG9uRXZlbnQ6IERFdmVudFtcImtpbmRcIl07XG4gICAgICAgIHJlYWRvbmx5IHRoZW5FeGVjdXRlOiBSZWFkb25seUFycmF5PFN0YXRlQ29tbWFuZD47XG4gICAgfVxuXG4gICAgZXhwb3J0IGludGVyZmFjZSBQcm9wVmFsdWU8VD4ge1xuICAgICAgICByZWFkb25seSB2YWx1ZTogVDtcbiAgICAgICAgcmVhZG9ubHkgdmFsdWVMYWJlbDogc3RyaW5nO1xuICAgIH1cbiAgICBleHBvcnQgdHlwZSBQcm9wID0gTnVtZXJpY1Byb3AgfCBTdHJpbmdQcm9wO1xuXG4gICAgZXhwb3J0IGludGVyZmFjZSBTZXRTdHJpbmdNdXRhdGlvbiB7XG4gICAgICAgIHJlYWRvbmx5IGtpbmQ6IFwic2V0LXN0cmluZ1wiO1xuICAgICAgICByZWFkb25seSBwcm9wTmFtZTogc3RyaW5nO1xuICAgICAgICByZWFkb25seSB2YWx1ZTogc3RyaW5nO1xuICAgIH1cblxuICAgIGV4cG9ydCBpbnRlcmZhY2UgSW5jcmVtZW50TnVtYmVyTXV0YXRpb24ge1xuICAgICAgICByZWFkb25seSBraW5kOiBcImluY3JlbWVudC1udW1iZXJcIjtcbiAgICAgICAgcmVhZG9ubHkgcHJvcE5hbWU6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkgc3RlcFNpemU6IG51bWJlcjtcbiAgICAgICAgcmVhZG9ubHkgaWZOb3RFeGlzdFRoZW5TZXRUbzogbnVtYmVyO1xuICAgIH1cbiAgICBleHBvcnQgaW50ZXJmYWNlIERlY3JlbWVudE51bWJlck11dGF0aW9uIHtcbiAgICAgICAgcmVhZG9ubHkga2luZDogXCJkZWNyZW1lbnQtbnVtYmVyXCI7XG4gICAgICAgIHJlYWRvbmx5IHByb3BOYW1lOiBzdHJpbmc7XG4gICAgICAgIHJlYWRvbmx5IHN0ZXBTaXplOiBudW1iZXI7XG4gICAgICAgIHJlYWRvbmx5IGlmTm90RXhpc3RUaGVuU2V0VG86IG51bWJlcjtcbiAgICB9XG5cbiAgICBleHBvcnQgaW50ZXJmYWNlIFNldE51bWJlck11dGF0aW9uIHtcbiAgICAgICAgcmVhZG9ubHkga2luZDogXCJzZXQtbnVtYmVyXCI7XG4gICAgICAgIHJlYWRvbmx5IHByb3BOYW1lOiBzdHJpbmc7XG4gICAgICAgIHJlYWRvbmx5IHZhbHVlOiBudW1iZXI7XG4gICAgfVxuICAgIGV4cG9ydCB0eXBlIE51bWJlck11dGF0aW9ucyA9IEluY3JlbWVudE51bWJlck11dGF0aW9uIHwgRGVjcmVtZW50TnVtYmVyTXV0YXRpb24gfCBTZXROdW1iZXJNdXRhdGlvbjtcblxuICAgIGV4cG9ydCB0eXBlIFN0YXRlTXV0YXRpb24gPSBTZXRTdHJpbmdNdXRhdGlvbiB8IE51bWJlck11dGF0aW9ucztcblxuICAgIGV4cG9ydCBjb25zdCBpc051bWJlck11dGF0aW9uID0gKG11dGF0aW9uczogU3RhdGVNdXRhdGlvbik6IG11dGF0aW9ucyBpcyBOdW1iZXJNdXRhdGlvbnMgPT4ge1xuICAgICAgICBpZiAoIW11dGF0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIG11dGF0aW9ucy5raW5kID09PSBcInNldC1udW1iZXJcIiB8fFxuICAgICAgICAgICAgbXV0YXRpb25zLmtpbmQgPT09IFwiZGVjcmVtZW50LW51bWJlclwiIHx8XG4gICAgICAgICAgICBtdXRhdGlvbnMua2luZCA9PT0gXCJpbmNyZW1lbnQtbnVtYmVyXCJcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGNvbnN0IGlzU3RyaW5nTXV0YXRpb24gPSAobXV0YXRpb246IFN0YXRlTXV0YXRpb24pOiBtdXRhdGlvbiBpcyBTZXRTdHJpbmdNdXRhdGlvbiA9PiB7XG4gICAgICAgIHJldHVybiBtdXRhdGlvbiAmJiBtdXRhdGlvbi5raW5kID09PSBcInNldC1zdHJpbmdcIjtcbiAgICB9O1xuXG4gICAgZXhwb3J0IGludGVyZmFjZSBTdGF0ZVF1ZXJ5IHtcbiAgICAgICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICAgICAgICByZWFkb25seSBjb25kaXRpb246IENvbmRpdGlvbjtcbiAgICB9XG5cbiAgICBleHBvcnQgaW50ZXJmYWNlIFN0YXRlUXVlcnlSZXN1bHQge1xuICAgICAgICByZWFkb25seSBxdWVyeU5hbWU6IHN0cmluZztcbiAgICAgICAgcmVhZG9ubHkgcHJldjogYm9vbGVhbjtcbiAgICAgICAgcmVhZG9ubHkgY3VycjogYm9vbGVhbjtcbiAgICB9XG5cbiAgICBleHBvcnQgY29uc3QgbnVtZXJpY1Byb3BUb0ZhY3QgPSAocHJvcDogTnVtZXJpY1Byb3AsIHZhbHVlOiBudW1iZXIpID0+IHtcbiAgICAgICAgY29uc3QgZmFjdDogRmFjdC5OdW1lcmljID0ge1xuICAgICAgICAgICAga2luZDogXCJudW1lcmljLWZhY3RcIixcbiAgICAgICAgICAgIHJlZmVyZW5jZUlkOiBwcm9wLnByb3BOYW1lLFxuICAgICAgICAgICAgcmVmZXJlbmNlTGFiZWw6IHByb3AucHJvcERlc2NyaXB0aW9uID8/IFwiIFtTVEFURV9QUk9QRVJUWV0gOiBcIiArIHByb3AucHJvcE5hbWUsXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGxhYmVsOiBcIiBbVkFMVUVdIDogXCIgKyB2YWx1ZSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZhY3Q7XG4gICAgfTtcblxuICAgIGV4cG9ydCBjb25zdCBzdHJpbmdQcm9wVG9GYWN0ID0gKHByb3A6IFN0cmluZ1Byb3AsIHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgZmFjdDogRmFjdC5TdHJpbmcgPSB7XG4gICAgICAgICAgICBraW5kOiBcInN0cmluZy1mYWN0XCIsXG4gICAgICAgICAgICByZWZlcmVuY2VJZDogcHJvcC5wcm9wTmFtZSxcbiAgICAgICAgICAgIHJlZmVyZW5jZUxhYmVsOiBcIiBbU1RBVEVfUFJPUEVSVFldIDogXCIgKyBwcm9wLnByb3BOYW1lLFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBsYWJlbDogXCIgW1ZBTFVFXSA6IFwiICsgdmFsdWUsXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBmYWN0O1xuICAgIH07XG59XG4iLCAiaW1wb3J0IHsgRmFjdCB9IGZyb20gXCIuLi9ydWxlcy9mYWN0XCI7XG5pbXBvcnQgeyBSZXN1bHQgfSBmcm9tIFwiLi4vY29tbW9uL3Jlc3VsdFwiO1xuaW1wb3J0IHsgQ29uZGl0aW9uIH0gZnJvbSBcIi4uL3J1bGVzL2NvbmRpdGlvblwiO1xuaW1wb3J0IHsgRFN0YXRlIH0gZnJvbSBcIi4vRHN0YXRlXCI7XG5pbXBvcnQgeyBERXZlbnREaXNwYXRjaGVyIH0gZnJvbSBcIi4uL2V2ZW50cy9ldmVudC1idXNcIjtcbmltcG9ydCB7IERUaW1lc3RhbXAgfSBmcm9tIFwiLi4vY29tbW9uL0RUaW1lc3RhbXBcIjtcbmltcG9ydCB7IFF1ZXJ5Q2hhbmdlZEV2ZW50IH0gZnJvbSBcIi4uL2V2ZW50cy9ERXZlbnRzXCI7XG5pbXBvcnQgeyBEQ29tbWFuZEJ1cyB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZEJ1c1wiO1xuXG5leHBvcnQgY2xhc3MgU3RhdGVTZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBUQUcgPSBcIiBbIFNUQVRFX1NFUlZJQ0UgXSA6XCI7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmFjdHNTdHJpbmcgPSBuZXcgTWFwPHN0cmluZywgRmFjdC5TdHJpbmc+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmFjdHNOdW1lcmljID0gbmV3IE1hcDxzdHJpbmcsIEZhY3QuTnVtZXJpYz4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBwcm9wRGVmaW5pdGlvbnMgPSBuZXcgTWFwPHN0cmluZywgRFN0YXRlLlByb3A+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcXVlcmllcyA9IG5ldyBNYXA8c3RyaW5nLCB7IHF1ZXJ5OiBEU3RhdGUuU3RhdGVRdWVyeTsgbGFzdFJlc3VsdDogYm9vbGVhbiB9PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHVuc3Vic2NyaWJlQ29tbWFuZHM6ICgpID0+IHZvaWQ7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRCdXM6IERFdmVudERpc3BhdGNoZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb21tYW5kQnVzOiBEQ29tbWFuZEJ1cyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBSZWFkb25seUFycmF5PERTdGF0ZS5Qcm9wPixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHF1ZXJ5TGlzdDogUmVhZG9ubHlBcnJheTxEU3RhdGUuU3RhdGVRdWVyeT4gPSBbXSxcbiAgKSB7XG4gICAgcHJvcHMuZm9yRWFjaCgocHJvcCkgPT4ge1xuICAgICAgdGhpcy5yZWdpc3RlclByb3BlcnR5KHByb3ApO1xuICAgIH0pO1xuICAgIGNvbnN0IGZhY3RzID0gdGhpcy5nZXRBbGxGYWN0cygpO1xuICAgIHF1ZXJ5TGlzdC5mb3JFYWNoKChkZWZpbml0aW9uKSA9PiB7XG4gICAgICB0aGlzLnJlZ2lzdGVyUXVlcnkoZGVmaW5pdGlvbiwgZmFjdHMpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5ldmFsdWF0ZVF1ZXJpZXMoKTtcbiAgICB0aGlzLnVuc3Vic2NyaWJlQ29tbWFuZHMgPSB0aGlzLmNvbW1hbmRCdXMuc3Vic2NyaWJlKChjb21tYW5kKSA9PiB7XG4gICAgICBpZiAoY29tbWFuZC5raW5kID09PSBcIlNUQVRFX01VVEFURV9DT01NQU5EXCIpIHtcbiAgICAgICAgdGhpcy5tdXRhdGlvbihjb21tYW5kLnBheWxvYWQubXV0YXRpb24pO1xuICAgICAgfVxuICAgIH0sIHRoaXMuVEFHKTtcbiAgfVxuXG4gIGRlc3Ryb3koKSB7XG4gICAgdGhpcy51bnN1YnNjcmliZUNvbW1hbmRzKCk7XG4gIH1cblxuICBwcml2YXRlIHJlZ2lzdGVyUXVlcnkocXVlcnk6IERTdGF0ZS5TdGF0ZVF1ZXJ5LCBjdXJyZW50RmFjdHM6IFJlYWRvbmx5QXJyYXk8RmFjdD4pIHtcbiAgICBjb25zdCByZXN1bHQgPSBDb25kaXRpb24uZXZhbHVhdGUocXVlcnkuY29uZGl0aW9uLCBjdXJyZW50RmFjdHMpO1xuICAgIHRoaXMucXVlcmllcy5zZXQocXVlcnkubmFtZSwgeyBxdWVyeTogcXVlcnksIGxhc3RSZXN1bHQ6IHJlc3VsdCB9KTtcbiAgICB0aGlzLmVtaXRRdWVyeUNoYW5nZWRFdmVudCh7IHF1ZXJ5TmFtZTogcXVlcnkubmFtZSwgcHJldjogcmVzdWx0LCBjdXJyOiByZXN1bHQgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlZ2lzdGVyUHJvcGVydHkocHJvcDogRFN0YXRlLlByb3ApIHtcbiAgICBpZiAodGhpcy5wcm9wRGVmaW5pdGlvbnMuaGFzKHByb3AucHJvcE5hbWUpKSB7XG4gICAgICAvLyBMT0dHSU5HXG4gICAgICBjb25zb2xlLndhcm4oXCJQcm9wIGV4Y2lzdHMgYWxyZWFkeS5cIiwgcHJvcC5wcm9wTmFtZSk7XG4gICAgfVxuXG4gICAgdGhpcy5wcm9wRGVmaW5pdGlvbnMuc2V0KHByb3AucHJvcE5hbWUsIHByb3ApO1xuXG4gICAgaWYgKHByb3AuaW5pdGlhbFZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocHJvcC5fdHlwZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgY29uc3QgZmFjdCA9IERTdGF0ZS5zdHJpbmdQcm9wVG9GYWN0KHByb3AsIHByb3AuaW5pdGlhbFZhbHVlKTtcbiAgICAgIHRoaXMuZmFjdHNTdHJpbmcuc2V0KGZhY3QucmVmZXJlbmNlSWQsIGZhY3QpO1xuICAgIH1cbiAgICBpZiAocHJvcC5fdHlwZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgY29uc3QgZmFjdCA9IERTdGF0ZS5udW1lcmljUHJvcFRvRmFjdChwcm9wLCBwcm9wLmluaXRpYWxWYWx1ZSk7XG4gICAgICB0aGlzLmZhY3RzTnVtZXJpYy5zZXQoZmFjdC5yZWZlcmVuY2VJZCwgZmFjdCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtdXRhdGVTdHJpbmcocHJvcDogRFN0YXRlLlN0cmluZ1Byb3AsIHZhbHVlOiBzdHJpbmcpIHtcbiAgICBjb25zdCBjdXJyID0gdGhpcy5mYWN0c1N0cmluZy5nZXQocHJvcC5wcm9wTmFtZSk7XG4gICAgaWYgKGN1cnIpIHtcbiAgICAgIGNvbnN0IHVwZGF0ZWQ6IEZhY3QuU3RyaW5nID0geyAuLi5jdXJyLCB2YWx1ZSB9O1xuICAgICAgdGhpcy5zZXRGYWN0KHVwZGF0ZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjcmVhdGVkOiBGYWN0LlN0cmluZyA9IHtcbiAgICAgICAga2luZDogXCJzdHJpbmctZmFjdFwiLFxuICAgICAgICByZWZlcmVuY2VJZDogcHJvcC5wcm9wTmFtZSxcbiAgICAgICAgcmVmZXJlbmNlTGFiZWw6IFwibGFiZWwgZm9yOiBcIiArIHByb3AucHJvcE5hbWUsXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBsYWJlbDogXCJWYWx1ZTogXCIgKyB2YWx1ZSxcbiAgICAgIH07XG4gICAgICB0aGlzLnNldEZhY3QoY3JlYXRlZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtdXRhdGVOdW1iZXIocHJvcDogRFN0YXRlLk51bWVyaWNQcm9wLCBtdXRhdGlvbjogRFN0YXRlLk51bWJlck11dGF0aW9ucykge1xuICAgIGNvbnN0IGN1cnIgPSB0aGlzLmZhY3RzTnVtZXJpYy5nZXQocHJvcC5wcm9wTmFtZSk7XG4gICAgaWYgKCFjdXJyKSB7XG4gICAgICBzd2l0Y2ggKG11dGF0aW9uLmtpbmQpIHtcbiAgICAgICAgY2FzZSBcInNldC1udW1iZXJcIjpcbiAgICAgICAgICB0aGlzLnNldEZhY3QoRFN0YXRlLm51bWVyaWNQcm9wVG9GYWN0KHByb3AsIG11dGF0aW9uLnZhbHVlKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJkZWNyZW1lbnQtbnVtYmVyXCI6XG4gICAgICAgICAgdGhpcy5zZXRGYWN0KERTdGF0ZS5udW1lcmljUHJvcFRvRmFjdChwcm9wLCBtdXRhdGlvbi5pZk5vdEV4aXN0VGhlblNldFRvKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJpbmNyZW1lbnQtbnVtYmVyXCI6XG4gICAgICAgICAgdGhpcy5zZXRGYWN0KERTdGF0ZS5udW1lcmljUHJvcFRvRmFjdChwcm9wLCBtdXRhdGlvbi5pZk5vdEV4aXN0VGhlblNldFRvKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgY29uc3QgY2hlY2s6IG5ldmVyID0gbXV0YXRpb247XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChjdXJyKSB7XG4gICAgICBzd2l0Y2ggKG11dGF0aW9uLmtpbmQpIHtcbiAgICAgICAgY2FzZSBcInNldC1udW1iZXJcIjpcbiAgICAgICAgICB0aGlzLnNldEZhY3QoeyAuLi5jdXJyLCB2YWx1ZTogbXV0YXRpb24udmFsdWUgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJkZWNyZW1lbnQtbnVtYmVyXCI6XG4gICAgICAgICAgdGhpcy5zZXRGYWN0KHsgLi4uY3VyciwgdmFsdWU6IGN1cnIudmFsdWUgLSBtdXRhdGlvbi5zdGVwU2l6ZSB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImluY3JlbWVudC1udW1iZXJcIjpcbiAgICAgICAgICB0aGlzLnNldEZhY3QoeyAuLi5jdXJyLCB2YWx1ZTogY3Vyci52YWx1ZSArIG11dGF0aW9uLnN0ZXBTaXplIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGNvbnN0IGNoZWNrOiBuZXZlciA9IG11dGF0aW9uO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZXZhbHVhdGVRdWVyaWVzKCk6IFJlYWRvbmx5QXJyYXk8eyBxdWVyeU5hbWU6IHN0cmluZzsgcHJldjogYm9vbGVhbjsgY3VycjogYm9vbGVhbjsgZGlkQ2hhbmdlOiBib29sZWFuIH0+IHtcbiAgICBjb25zdCBmYWN0cyA9IHRoaXMuZ2V0QWxsRmFjdHMoKTtcbiAgICBjb25zdCBhbGw6IEFycmF5PHsgcXVlcnlOYW1lOiBzdHJpbmc7IHByZXY6IGJvb2xlYW47IGN1cnI6IGJvb2xlYW47IGRpZENoYW5nZTogYm9vbGVhbiB9PiA9IFtdO1xuICAgIHRoaXMucXVlcmllcy5mb3JFYWNoKChxKSA9PiB7XG4gICAgICBjb25zdCBwcmV2ID0gcS5sYXN0UmVzdWx0O1xuXG4gICAgICBjb25zdCBjdXJyID0gQ29uZGl0aW9uLmV2YWx1YXRlKHEucXVlcnkuY29uZGl0aW9uLCBmYWN0cyk7XG4gICAgICBjb25zdCBkaWRDaGFuZ2UgPSBwcmV2ICE9PSBjdXJyO1xuICAgICAgcS5sYXN0UmVzdWx0ID0gY3VycjtcbiAgICAgIGFsbC5wdXNoKHsgcXVlcnlOYW1lOiBxLnF1ZXJ5Lm5hbWUsIHByZXYsIGN1cnIsIGRpZENoYW5nZSB9KTtcbiAgICAgIC8vIGRlZi52YWx1ZSA9IHZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiBhbGw7XG4gIH1cblxuICBwcml2YXRlIG11dGF0aW9uKG11dGF0aW9uOiBEU3RhdGUuU3RhdGVNdXRhdGlvbik6IHsgc3VjY2VzczogYm9vbGVhbiB9IHtcbiAgICBjb25zdCBwcm9wRGVmID0gdGhpcy5wcm9wRGVmaW5pdGlvbnMuZ2V0KG11dGF0aW9uLnByb3BOYW1lKTtcbiAgICBpZiAoIXByb3BEZWYpIHtcbiAgICAgIC8vIFRPRE8gTE9HR0lOR1xuICAgICAgcmV0dXJuIHsgc3VjY2VzczogZmFsc2UgfTtcbiAgICB9XG5cbiAgICBpZiAocHJvcERlZi5fdHlwZSA9PT0gXCJzdHJpbmdcIiAmJiBEU3RhdGUuaXNTdHJpbmdNdXRhdGlvbihtdXRhdGlvbikpIHtcbiAgICAgIHRoaXMubXV0YXRlU3RyaW5nKHByb3BEZWYsIG11dGF0aW9uLnZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcERlZi5fdHlwZSA9PT0gXCJudW1iZXJcIiAmJiBEU3RhdGUuaXNOdW1iZXJNdXRhdGlvbihtdXRhdGlvbikpIHtcbiAgICAgIHRoaXMubXV0YXRlTnVtYmVyKHByb3BEZWYsIG11dGF0aW9uKTtcbiAgICB9XG4gICAgY29uc3QgcXVlcnlSZXN1bHRzID0gdGhpcy5ldmFsdWF0ZVF1ZXJpZXMoKTtcbiAgICBjb25zdCBjaGFuZ2VkUmVzdWx0ID0gcXVlcnlSZXN1bHRzLmZpbHRlcigocikgPT4gci5kaWRDaGFuZ2UpO1xuICAgIGNoYW5nZWRSZXN1bHQuZm9yRWFjaCgocmVzKSA9PiB7XG4gICAgICB0aGlzLmVtaXRRdWVyeUNoYW5nZWRFdmVudCh7IHF1ZXJ5TmFtZTogcmVzLnF1ZXJ5TmFtZSwgcHJldjogcmVzLnByZXYsIGN1cnI6IHJlcy5jdXJyIH0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0UXVlcnlDaGFuZ2VkRXZlbnQoZGF0YTogeyBxdWVyeU5hbWU6IHN0cmluZzsgcHJldjogYm9vbGVhbjsgY3VycjogYm9vbGVhbiB9KSB7XG4gICAgY29uc3QgcXVlcnlDaGFuZ2VkRXZlbnQ6IFF1ZXJ5Q2hhbmdlZEV2ZW50ID0ge1xuICAgICAga2luZDogXCJTVEFURV9RVUVSWV9SRVNVTFRfQ0hBTkdFRF9FVkVOVFwiLFxuICAgICAgcHJvZHVjZXI6IFwiU1RBVEUtU0VSVklDRVwiLFxuICAgICAgcHJvZHVjZXJJZDogXCJTVEFURS1TRVJWSUNFXCIsXG4gICAgICB0aW1lc3RhbXA6IERUaW1lc3RhbXAubm93KCksXG4gICAgICBkYXRhLFxuICAgIH07XG4gICAgY29uc3QgeyBxdWVyeU5hbWUsIGN1cnIsIHByZXYgfSA9IHF1ZXJ5Q2hhbmdlZEV2ZW50LmRhdGE7XG4gICAgLy8gY29uc29sZS5sb2coXCJbIFFVRVJZX0NIQU5HRUQgXCIgKyBxdWVyeU5hbWUgKyBcIl0gOiBcIiArIHByZXYgKyBcIiAtPiBcIiArIGN1cnIpO1xuICAgIHRoaXMuZXZlbnRCdXMuZW1pdChxdWVyeUNoYW5nZWRFdmVudCk7XG4gIH1cblxuICBnZXRQcm9wQXNGYWN0KHByb3BOYW1lOiBzdHJpbmcpOiBSZXN1bHQ8RmFjdD4ge1xuICAgIGNvbnN0IHByb3BEZWYgPSB0aGlzLnByb3BEZWZpbml0aW9ucy5nZXQocHJvcE5hbWUpO1xuICAgIGlmICghcHJvcERlZikge1xuICAgICAgcmV0dXJuIFJlc3VsdC5mYWlsdXJlKFxuICAgICAgICBcIk5vIGRlZmluaXRpb24gZm9ybSBwcm9wZXJ0eSBueSBuYW1lIFwiICsgcHJvcE5hbWUgKyBcIiBpcyByZWdpc3RlcmVkLiAoUGFzcyBpbiBjb25zdHJ1Y3Rvci4pXCIsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZmFjdHNTdHJpbmcuZ2V0KHByb3BOYW1lKSA/PyB0aGlzLmZhY3RzTnVtZXJpYy5nZXQocHJvcE5hbWUpO1xuXG4gICAgcmV0dXJuIHZhbHVlID8gUmVzdWx0Lm9rKHZhbHVlKSA6IFJlc3VsdC5mYWlsdXJlKFwiUHJvcGVydHkgXCIgKyBwcm9wTmFtZSArIFwiIGhhcyBubyB2YWx1ZS5cIik7XG4gIH1cblxuICBwcml2YXRlIHNldEZhY3QoZmFjdDogRmFjdCkge1xuICAgIHN3aXRjaCAoZmFjdC5raW5kKSB7XG4gICAgICBjYXNlIFwibnVtZXJpYy1mYWN0XCI6XG4gICAgICAgIHRoaXMuZmFjdHNOdW1lcmljLnNldChmYWN0LnJlZmVyZW5jZUlkLCBmYWN0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwic3RyaW5nLWZhY3RcIjpcbiAgICAgICAgdGhpcy5mYWN0c1N0cmluZy5zZXQoZmFjdC5yZWZlcmVuY2VJZCwgZmFjdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uc3QgY2hlY2s6IG5ldmVyID0gZmFjdDtcbiAgICB9XG4gIH1cblxuICBnZXRTdGF0ZSgpIHtcbiAgICBjb25zdCBwcm9wczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCB8IGJvb2xlYW4+ID0ge307XG4gICAgdGhpcy5wcm9wRGVmaW5pdGlvbnMuZm9yRWFjaCgoZGVmKSA9PiB7XG4gICAgICBsZXQgdmFsdWU6IHN0cmluZyB8IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAgICAgY29uc3QgbWF5YmVGYWN0ID0gdGhpcy5nZXRBbnlGYWN0KGRlZi5wcm9wTmFtZSk7XG4gICAgICBpZiAobWF5YmVGYWN0KSB7XG4gICAgICAgIHZhbHVlID0gbWF5YmVGYWN0LnZhbHVlO1xuICAgICAgfVxuICAgICAgcHJvcHNbZGVmLnByb3BOYW1lXSA9IHZhbHVlO1xuICAgIH0pO1xuICAgIHRoaXMucXVlcmllcy5mb3JFYWNoKChxdWVyeSkgPT4ge1xuICAgICAgcHJvcHNbcXVlcnkucXVlcnkubmFtZV0gPSBxdWVyeS5sYXN0UmVzdWx0O1xuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvcE5hbWVzID0gT2JqZWN0LmtleXMocHJvcHMpO1xuICAgIGNvbnN0IHByb3BDb3VudCA9IHByb3BOYW1lcy5sZW5ndGg7XG4gICAgY29uc3QgcHJvcEFycmF5ID0gWy4uLnRoaXMucHJvcERlZmluaXRpb25zLnZhbHVlcygpXTtcblxuICAgIHJldHVybiB7IHByb3BDb3VudCwgcHJvcE5hbWVzLCBwcm9wQXJyYXksIHN0YXRlOiBwcm9wcyB9O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRBbnlGYWN0KHByb3BOYW1lOiBzdHJpbmcpOiBGYWN0IHwgZmFsc2Uge1xuICAgIHJldHVybiB0aGlzLmZhY3RzU3RyaW5nLmdldChwcm9wTmFtZSkgPz8gdGhpcy5mYWN0c051bWVyaWMuZ2V0KHByb3BOYW1lKSA/PyBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QWxsRmFjdHMoKTogUmVhZG9ubHlBcnJheTxGYWN0PiB7XG4gICAgcmV0dXJuIFsuLi50aGlzLmZhY3RzTnVtZXJpYy52YWx1ZXMoKSwgLi4udGhpcy5mYWN0c1N0cmluZy52YWx1ZXMoKV07XG4gIH1cblxuICAvKipcbiAgICogV2lsbCBjaGVjayB0aGF0IGFsbCByZWZlcmVuY2VJZHMgdXNlZCBpbiBDb25kaXRpb24gaXMgcmVnaXN0ZXJlZCBhcyBhIHZhbGlkIHByb3BlcnR5IGluIHN0YXRlLlxuICAgKiBAcGFyYW0gY29uZGl0aW9uXG4gICAqL1xuICBjYW5CZU1hdGNoZWQoY29uZGl0aW9uOiBDb25kaXRpb24pOiBib29sZWFuIHtcbiAgICBjb25zdCBzaW1wbGVDb25kaXRpb25zID0gQ29uZGl0aW9uLmdldEFsbFNpbXBsZUNvbmRpdGlvbnMoY29uZGl0aW9uKTtcbiAgICBsZXQgaGFzQWxsID0gdHJ1ZTtcblxuICAgIGNvbnN0IGFsbElkcyA9IHNpbXBsZUNvbmRpdGlvbnMubWFwKChjKSA9PiBjLnJlZmVyZW5jZUlkKTtcblxuICAgIGNvbnN0IG1pc3NpbmdJZHM6IHN0cmluZ1tdID0gW107XG4gICAgYWxsSWRzLmZvckVhY2goKGlkKSA9PiB7XG4gICAgICBpZiAoIXRoaXMucHJvcERlZmluaXRpb25zLmhhcyhpZCkpIHtcbiAgICAgICAgaGFzQWxsID0gZmFsc2U7XG4gICAgICAgIG1pc3NpbmdJZHMucHVzaChpZCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2codGhpcy5UQUcsIG1pc3NpbmdJZHMpO1xuXG4gICAgcmV0dXJuIGhhc0FsbDtcbiAgfVxuICBpc01hdGNoZWQoY29uZGl0aW9uOiBDb25kaXRpb24pIHtcbiAgICByZXR1cm4gQ29uZGl0aW9uLmV2YWx1YXRlKGNvbmRpdGlvbiwgdGhpcy5nZXRBbGxGYWN0cygpKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IFNjaGVtYUR0byB9IGZyb20gXCIuLi9kdG8vU2NoZW1hRHRvXCI7XG5pbXBvcnQgeyBETWVkaWFNYW5hZ2VyIH0gZnJvbSBcIi4uL3NlcnZpY2VzL0RNZWRpYS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyBEQ29tbWFuZEJ1cyB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZEJ1c1wiO1xuaW1wb3J0IHsgRXZlbnRCdXMgfSBmcm9tIFwiLi4vZXZlbnRzL2V2ZW50LWJ1c1wiO1xuaW1wb3J0IHsgRFBsYXllciB9IGZyb20gXCIuLi9wbGF5ZXIvZHBsYXllclwiO1xuaW1wb3J0IHsgQW5zd2VyZWRRdWVzdGlvbiB9IGZyb20gXCIuLi9wbGF5ZXIvaGlzdG9yeS1xdWVcIjtcbmltcG9ydCB7IERUaW1lc3RhbXAgfSBmcm9tIFwiLi4vY29tbW9uL0RUaW1lc3RhbXBcIjtcbmltcG9ydCB7IERQYWdlIH0gZnJvbSBcIi4vRFBhZ2VcIjtcbmltcG9ydCB7IFNjYWxlU2VydmljZSB9IGZyb20gXCIuL3NjYWxlXCI7XG5pbXBvcnQgeyBSZXNvdXJjZVByb3ZpZGVyIH0gZnJvbSBcIi4uL3NlcnZpY2VzL3Jlc291cmNlLXByb3ZpZGVyXCI7XG5pbXBvcnQgeyBTdGF0ZVNlcnZpY2UgfSBmcm9tIFwiLi4vc3RhdGUvc3RhdGUtc2VydmljZVwiO1xuaW1wb3J0IHsgRENvbW1hbmQsIFN0YXRlQ29tbWFuZCB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZFwiO1xuaW1wb3J0IHsgREV2ZW50IH0gZnJvbSBcIi4uL2V2ZW50cy9ERXZlbnRzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRW5naW5lTG9nZ2VyIHtcbiAgZXJyb3IobWVzc2FnZTogc3RyaW5nKTogdm9pZDtcbiAgd2FybihtZXNzYWdlOiBzdHJpbmcpOiB2b2lkO1xuICBhcHBFdmVudChldmVudDogREV2ZW50KTogdm9pZDtcbiAgYXBwQ29tbWFuZChjb21tYW5kOiBEQ29tbWFuZCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2NoZW1hUmVzdWx0IHtcbiAgcmVhZG9ubHkgZXZlbnRMb2c6IFJlYWRvbmx5QXJyYXk8REV2ZW50PjtcbiAgcmVhZG9ubHkgY29tbWFuZExvZzogUmVhZG9ubHlBcnJheTxEQ29tbWFuZD47XG4gIHJlYWRvbmx5IGFuc3dlcnM6IFJlYWRvbmx5QXJyYXk8YW55Pjtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgSVNjaGVtYUVuZ2luZSB7XG4gIG9uQ29tcGxldGUoaGFuZGxlcjogKHJlc3VsdDogU2NoZW1hUmVzdWx0KSA9PiB2b2lkKTogdm9pZDtcbiAgb25Db21tYW5kT3JFdmVudChpdGVtOiBERXZlbnQgfCBEQ29tbWFuZCk6IHZvaWQ7XG4gIHNldFNjaGVtYShzY2hlbWE6IFNjaGVtYUR0byk6IHZvaWQ7XG4gIG9uRmF0YWxFcnJvcihoYW5kbGVyOiAoZXJyb3I6IHsgbWVzc2FnZTogc3RyaW5nIH0pID0+IHZvaWQpOiB2b2lkO1xufVxuXG5leHBvcnQgY2xhc3MgU2NoZW1hRW5naW5lIGltcGxlbWVudHMgSVNjaGVtYUVuZ2luZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgVEFHID0gXCJbIFNDSEVNQV9FTkdJTkUgXSA6XCI7XG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZEJ1cyA9IG5ldyBEQ29tbWFuZEJ1cygpO1xuICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50QnVzID0gbmV3IEV2ZW50QnVzKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWVkaWFNYW5hZ2VyOiBETWVkaWFNYW5hZ2VyO1xuICBwcml2YXRlIHJlYWRvbmx5IHNjYWxlOiBTY2FsZVNlcnZpY2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgaG9zdEVsZW1lbnQ6IEhUTUxEaXZFbGVtZW50O1xuICBwcml2YXRlIHJlYWRvbmx5IHVpQ29udGFpbmVyOiBIVE1MRGl2RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWVkaWFDb250YWluZXI6IEhUTUxEaXZFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgcHJpdmF0ZSByZWFkb25seSByZXNvdXJjZVByb3ZpZGVyOiBSZXNvdXJjZVByb3ZpZGVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YXRlU2VydmljZTogU3RhdGVTZXJ2aWNlO1xuICBwcml2YXRlIHJlYWRvbmx5IGdsb2JhbEV2ZW50VG9TdGF0ZUhhbmRsZXJzID0gbmV3IE1hcDxzdHJpbmcsIFJlYWRvbmx5QXJyYXk8U3RhdGVDb21tYW5kPj4oKTtcbiAgcHJpdmF0ZSBwbGF5ZXI6IERQbGF5ZXI7XG4gIHByaXZhdGUgY3VycmVudFBhZ2U6IERQYWdlIHwgZmFsc2UgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBzdWJzOiBBcnJheTwoKSA9PiB2b2lkPiA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGhvc3RFbDogSFRNTERpdkVsZW1lbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBoZWlnaHQ6IG51bWJlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHdpZHRoOiBudW1iZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzY2hlbWE6IFNjaGVtYUR0byxcbiAgKSB7XG4gICAgdGhpcy5ob3N0RWxlbWVudCA9IGhvc3RFbDtcbiAgICB0aGlzLmhvc3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudWlDb250YWluZXIpO1xuICAgIHRoaXMuaG9zdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5tZWRpYUNvbnRhaW5lcik7XG4gICAgY29uc3Qgc3RhdGVQcm9wcyA9IHRoaXMuc2NoZW1hLnN0YXRlUHJvcHMgPz8gW107XG4gICAgY29uc3Qgc3RhdGVRdWVyaWVzID0gdGhpcy5zY2hlbWEuc3RhdGVRdWVyaWVzID8/IFtdO1xuICAgIHRoaXMuc3RhdGVTZXJ2aWNlID0gbmV3IFN0YXRlU2VydmljZSh0aGlzLmV2ZW50QnVzLCB0aGlzLmNvbW1hbmRCdXMsIHN0YXRlUHJvcHMsIHN0YXRlUXVlcmllcyk7XG4gICAgdGhpcy5zY2FsZSA9IG5ldyBTY2FsZVNlcnZpY2Uoe1xuICAgICAgYmFzZUhlaWdodDogc2NoZW1hLmJhc2VIZWlnaHQsXG4gICAgICBiYXNlV2lkdGg6IHNjaGVtYS5iYXNlV2lkdGgsXG4gICAgICBjb250YWluZXJXaWR0aDogd2lkdGgsXG4gICAgICBjb250YWluZXJIZWlnaHQ6IGhlaWdodCxcbiAgICB9KTtcbiAgICAvLyB0aGlzLmNvbW1hbmRCdXMubG9nQ29tbWFuZHMgPSB0cnVlO1xuICAgIGNvbnN0IGdsb2JhbEV2ZW50SGFuZGxlcnMgPSBzY2hlbWEuc3RhdGVGcm9tRXZlbnQgPz8gW107XG5cbiAgICBnbG9iYWxFdmVudEhhbmRsZXJzLmZvckVhY2goKGgpID0+IHtcbiAgICAgIHRoaXMuZ2xvYmFsRXZlbnRUb1N0YXRlSGFuZGxlcnMuc2V0KGgub25FdmVudCwgaC50aGVuRXhlY3V0ZSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCByZXNvdXJjZXMgPSBTY2hlbWFEdG8uZ2V0UmVzb3VyY2VzKHRoaXMuc2NoZW1hKTtcbiAgICB0aGlzLnJlc291cmNlUHJvdmlkZXIgPSBuZXcgUmVzb3VyY2VQcm92aWRlcih7IHZpZGVvczogcmVzb3VyY2VzLnZpZGVvTGlzdCwgYXVkaW86IHJlc291cmNlcy5hdWRpb0xpc3QgfSk7XG4gICAgdGhpcy5tZWRpYU1hbmFnZXIgPSBuZXcgRE1lZGlhTWFuYWdlcihcbiAgICAgIHRoaXMubWVkaWFDb250YWluZXIsXG4gICAgICB0aGlzLmNvbW1hbmRCdXMsXG4gICAgICB0aGlzLmV2ZW50QnVzLFxuICAgICAgdGhpcy5yZXNvdXJjZVByb3ZpZGVyLFxuICAgICAgdGhpcy5zY2FsZSxcbiAgICApO1xuICAgIHRoaXMucGxheWVyID0gbmV3IERQbGF5ZXIodGhpcy5zY2hlbWEpO1xuICAgIHRoaXMuc3R5bGVTZWxmKCk7XG4gICAgdGhpcy5uZXh0UGFnZSgpO1xuICAgIHRoaXMuaG9va1VwTGlzdGVuZXJzKCk7XG4gIH1cblxuICBwcml2YXRlIGhvb2tVcExpc3RlbmVycygpIHtcbiAgICBjb25zdCBldmVudFN1YnNjcmlwdGlvbiA9IHRoaXMuZXZlbnRCdXMuc3Vic2NyaWJlKChldikgPT4ge1xuICAgICAgdGhpcy5vbkNvbW1hbmRPckV2ZW50KGV2KTtcbiAgICAgIGNvbnN0IGdsb2JhbEhhbmRsZXJzID0gdGhpcy5nbG9iYWxFdmVudFRvU3RhdGVIYW5kbGVycy5nZXQoZXYua2luZCkgPz8gW107XG4gICAgICBnbG9iYWxIYW5kbGVycy5mb3JFYWNoKChzdGF0ZUNvbW1hbmQpID0+IHtcbiAgICAgICAgdGhpcy5jb21tYW5kQnVzLmVtaXQoc3RhdGVDb21tYW5kKTtcbiAgICAgIH0pO1xuICAgIH0sIHRoaXMuVEFHICsgXCJIT09LX1VQX0xJU1RFTkVSU1wiKTtcbiAgICBjb25zdCBjb21tYW5kU3Vic2NyaXB0aW9uID0gdGhpcy5jb21tYW5kQnVzLnN1YnNjcmliZSgoY29tbWFuZCkgPT4ge1xuICAgICAgLy8gc3dpdGNoIChjb21tYW5kLmtpbmQpIHtcbiAgICAgIC8vXG4gICAgICAvLyB9XG4gICAgICB0aGlzLm9uQ29tbWFuZE9yRXZlbnQoY29tbWFuZCk7XG4gICAgICBpZiAoY29tbWFuZC5raW5kID09PSBcIlBBR0VfUVVFX05FWFRfUEFHRV9DT01NQU5EXCIpIHtcbiAgICAgICAgdGhpcy5uZXh0UGFnZSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29tbWFuZC5raW5kID09PSBcIkVOR0lORV9MRUFWRV9QQUdFX0NPTU1BTkRcIikge1xuICAgICAgICBjb25zb2xlLmxvZyh0aGlzLlRBRyArIFwiU0VRVUVOQ0UgU1RBUlRFRCAtLSBUT0RPIEVWRU5UIEZPUiBUSElTPz9cIik7XG4gICAgICAgIGNvbnNvbGUubG9nKGNvbW1hbmQpO1xuICAgICAgICBjb25zdCBwYWdlSWQgPSBjb21tYW5kLnBheWxvYWQucGFnZUlkO1xuICAgICAgICBjb25zdCBmYWN0cyA9IGNvbW1hbmQucGF5bG9hZC5mYWN0c0NvbGxlY3RlZDtcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gRFRpbWVzdGFtcC5ub3coKTtcbiAgICAgICAgY29uc3QgYW5zOiBBbnN3ZXJlZFF1ZXN0aW9uW10gPSBmYWN0cy5tYXAoKGYpID0+ICh7XG4gICAgICAgICAgdGltZXN0YW1wLFxuICAgICAgICAgIGZhY3Q6IGYsXG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy5wbGF5ZXIuc2F2ZUhpc3Rvcnkoe1xuICAgICAgICAgIGFuc3dlcmVkUXVlc3Rpb25zOiBhbnMsXG4gICAgICAgICAgcGFnZUlkLFxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLm5leHRQYWdlKCk7XG4gICAgICAgIC8vIGNvbnN0IGhpc3Rvcnk6IFBhZ2VIaXN0b3J5ID0geyBwYWdlOiB7fSwgYW5zd2VyZWRRdWVzdGlvbnM6IFtdIH07XG4gICAgICB9XG4gICAgfSwgdGhpcy5UQUcpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goY29tbWFuZFN1YnNjcmlwdGlvbik7XG4gICAgdGhpcy5zdWJzLnB1c2goZXZlbnRTdWJzY3JpcHRpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdHlsZVNlbGYoKSB7XG4gICAgdGhpcy5ob3N0RWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLnNjYWxlLnBhZ2VIZWlnaHQgKyBcInB4XCI7XG4gICAgdGhpcy5ob3N0RWxlbWVudC5zdHlsZS53aWR0aCA9IHRoaXMuc2NhbGUucGFnZVdpZHRoICsgXCJweFwiO1xuICAgIHRoaXMuaG9zdEVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5zY2hlbWEuYmFja2dyb3VuZENvbG9yID8/IFwid2hpdGVcIjtcbiAgICB0aGlzLmhvc3RFbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuICAgIC8vIHRoaXMuaG9zdEVsZW1lbnQuc3R5bGUub3ZlcmZsb3cgPSBcImhpZGRlblwiO1xuICAgIGNvbnN0IG1ha2VTdGF0aWMgPSAoZGl2OiBIVE1MRGl2RWxlbWVudCkgPT4ge1xuICAgICAgZGl2LnN0eWxlLmhlaWdodCA9IFwiMHB4XCI7XG4gICAgICBkaXYuc3R5bGUud2lkdGggPSBcIjBweFwiO1xuICAgICAgZGl2LnN0eWxlLnBvc2l0aW9uID0gXCJzdGF0aWNcIjtcbiAgICB9O1xuXG4gICAgbWFrZVN0YXRpYyh0aGlzLnVpQ29udGFpbmVyKTtcbiAgICBtYWtlU3RhdGljKHRoaXMubWVkaWFDb250YWluZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBuZXh0UGFnZSgpIHtcbiAgICAvLyBUT0RPIFNIT1VMRCBUSElTIEJFIFBBUlQgT0YgVEhFIFNDSEVNQT8/IFRISVMgSVMgQ0xFQU5VUCBMT0dJQ1xuICAgIC8vIHRoaXMuY29tbWFuZEJ1cy5lbWl0KHsga2luZDogXCJWSURFT19QQVVTRV9DT01NQU5EXCIsIHRhcmdldDogXCJWSURFT1wiLCB0YXJnZXRJZDogXCJWSURFT1wiLCBwYXlsb2FkOiB7fSB9KTtcbiAgICAvLyB0aGlzLmNvbW1hbmRCdXMuZW1pdCh7IGtpbmQ6IFwiQVVESU9fUEFVU0VfQ09NTUFORFwiLCB0YXJnZXQ6IFwiQVVESU9cIiwgdGFyZ2V0SWQ6IFwiQVVESU9cIiwgcGF5bG9hZDoge30gfSk7XG4gICAgLy8gY29uc3QgY3VyclBhZ2VJZCA9IHRoaXMuY3VycmVudFBhZ2UgPyB0aGlzLmN1cnJlbnRQYWdlLmlkIDogXCJOT19QQUdFXCI7XG4gICAgLy8gY29uc29sZS5ncm91cENvbGxhcHNlZChcIk5FWFRfUEFHRSBGUk9NOiBcIiArIGN1cnJQYWdlSWQpO1xuICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuVEFHICsgXCIgTkVYVF9QQUdFIFNUQVJURUQgQVQ6IFwiICsgY3VyclBhZ2VJZCk7XG4gICAgdGhpcy5tZWRpYU1hbmFnZXIuY2xlYXJBbGxNZWRpYSgpO1xuICAgIGNvbnN0IG5leHRQYWdlID0gdGhpcy5wbGF5ZXIuZ2V0TmV4dFBhZ2UoKTtcbiAgICAvLyBjb25zdCBzdGF0ZSA9IHRoaXMuc3RhdGVTZXJ2aWNlLmdldFN0YXRlKCk7XG4gICAgLy8gY29uc29sZS5sb2coc3RhdGUpO1xuICAgIC8vIFRPRE8gQ0xFQU4gVVAgUEFHRSBDT01QT05FTlRTIHRoaXMucGFnZS5DbGVhblVwKClcbiAgICBpZiAodGhpcy5jdXJyZW50UGFnZSkge1xuICAgICAgdGhpcy5jdXJyZW50UGFnZS5kZXN0cm95KCk7XG4gICAgICB0aGlzLnVpQ29udGFpbmVyLmlubmVySFRNTCA9IFwiXCI7XG4gICAgfVxuICAgIGlmICghbmV4dFBhZ2UpIHtcbiAgICAgIC8vIFRPRE8gRklHVVJFIE9VVCBXSEFRVCBUTyBETyBBVCBFTkQgT0YgVEVTVCEhIFN0YXJ0IG92ZXI/P1xuICAgICAgdGhpcy5wbGF5ZXIgPSBuZXcgRFBsYXllcih0aGlzLnNjaGVtYSk7XG4gICAgICBpZiAodGhpcy5zY2hlbWEucGFnZXMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLm5leHRQYWdlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IG5ld1BhZ2UgPSBuZXcgRFBhZ2UobmV4dFBhZ2UsIHRoaXMuZXZlbnRCdXMsIHRoaXMuY29tbWFuZEJ1cywgdGhpcy5zY2FsZSk7XG5cbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gbmV3UGFnZTtcbiAgICBuZXdQYWdlLmFwcGVuZFlvdXJzZWxmKHRoaXMudWlDb250YWluZXIpO1xuXG4gICAgdGhpcy5tZWRpYU1hbmFnZXIuc2V0UGFnZShuZXh0UGFnZSk7XG4gICAgY29uc3QgczEgPSB0aGlzLnN0YXRlU2VydmljZS5nZXRTdGF0ZSgpO1xuICAgIC8vIGNvbnNvbGUubG9nKHMxKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcIk5leHQtcGFnZTogXCIgKyBuZXdQYWdlLmlkKTtcbiAgICAvLyBjb25zb2xlLmdyb3VwRW5kKCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIGlmICh0aGlzLmN1cnJlbnRQYWdlKSB7XG4gICAgICB0aGlzLmN1cnJlbnRQYWdlLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMudWlDb250YWluZXIuaW5uZXJIVE1MID0gXCJcIjtcbiAgICB9XG4gICAgdGhpcy5tZWRpYU1hbmFnZXIuZGVzdHJveSgpO1xuICAgIHRoaXMuc3RhdGVTZXJ2aWNlLmRlc3Ryb3koKTtcbiAgICB0aGlzLnN1YnMuZm9yRWFjaCgoc3ViKSA9PiB7XG4gICAgICBzdWIoKTtcbiAgICB9KTtcbiAgICBjb25zdCBldlN0YXRzID0gdGhpcy5ldmVudEJ1cy5nZXRTdGF0cygpO1xuICAgIGNvbnN0IGNtZFN0YXRzID0gdGhpcy5jb21tYW5kQnVzLmdldFN0YXRzKCk7XG4gICAgY29uc29sZS5hc3NlcnQoZXZTdGF0cy5zdWJzY3JpYmVyc0NvdW50ID09PSAwLCB0aGlzLlRBRyArIFwiIEV2ZW50YnVzIHNob3VsZCBoYXZlIG5vIHN1YnNjcmliZXJzIFwiLCBldlN0YXRzKTtcbiAgICBjb25zb2xlLmFzc2VydChjbWRTdGF0cy5zdWJzY3JpYmVyc0NvdW50ID09PSAwLCB0aGlzLlRBRyArIFwiQ29tbWFuZGJ1cyBzaG91bGQgaGF2ZSBubyBzdWJzY3JpYmVyc1wiLCBjbWRTdGF0cyk7XG4gIH1cbiAgb25Db21wbGV0ZShoYW5kbGVyOiAocmVzdWx0OiBTY2hlbWFSZXN1bHQpID0+IHZvaWQpIHtcbiAgICBjb25zb2xlLmxvZyhoYW5kbGVyKTtcbiAgfVxuXG4gIG9uRmF0YWxFcnJvcihoYW5kbGVyOiAoZXJyb3I6IHsgbWVzc2FnZTogc3RyaW5nIH0pID0+IHZvaWQpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyhoYW5kbGVyKTtcbiAgfVxuXG4gIG9uQ29tbWFuZE9yRXZlbnQoX2V2ZW50X29yX2NvbW1hbmQ6IERFdmVudCB8IERDb21tYW5kKSB7fVxuXG4gIHNldFNjaGVtYShzY2hlbWE6IFNjaGVtYUR0byk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKHNjaGVtYSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBEU3RhdGUgfSBmcm9tIFwiLi9Ec3RhdGVcIjtcbmltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuLi9ydWxlcy9jb25kaXRpb25cIjtcbmltcG9ydCB7IFN0YXRlQ29tbWFuZCB9IGZyb20gXCIuLi9jb21tYW5kcy9EQ29tbWFuZFwiO1xuXG5leHBvcnQgY2xhc3MgQm9vbGVhblN0YXRlUHJvcGVydHk8UHJvcE5hbWUgZXh0ZW5kcyBzdHJpbmc+IHtcbiAgICByZWFkb25seSBwcm9wTmFtZTogUHJvcE5hbWU7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgVFJVRSA9IHsgdmFsdWU6IDEsIGxhYmVsOiBcIlRSVUVcIiB9O1xuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IEZBTFNFID0geyB2YWx1ZTogMCwgbGFiZWw6IFwiRkFMU0VcIiB9O1xuICAgIHJlYWRvbmx5IHByb3BEZWZpbml0aW9uOiBEU3RhdGUuTnVtZXJpY1Byb3A7XG5cbiAgICBnZXRJc1RydWVDb25kaXRpb24oKTogQ29uZGl0aW9uLk51bWVyaWMge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAga2luZDogXCJudW1lcmljLWNvbmRpdGlvblwiLFxuICAgICAgICAgICAgcmVmZXJlbmNlSWQ6IHRoaXMucHJvcE5hbWUsXG4gICAgICAgICAgICByZWZlcmVuY2VMYWJlbDogdGhpcy5wcm9wTmFtZSArIFwiWyBCT09MRUFOIF1cIixcbiAgICAgICAgICAgIHZhbHVlTGFiZWw6IEJvb2xlYW5TdGF0ZVByb3BlcnR5LlRSVUUubGFiZWwsXG4gICAgICAgICAgICB2YWx1ZTogQm9vbGVhblN0YXRlUHJvcGVydHkuVFJVRS52YWx1ZSxcbiAgICAgICAgICAgIG9wZXJhdG9yOiBcImVxXCIsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGdldElzRmFsc2VDb25kaXRpb24oKTogQ29uZGl0aW9uLk51bWVyaWMge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAga2luZDogXCJudW1lcmljLWNvbmRpdGlvblwiLFxuICAgICAgICAgICAgcmVmZXJlbmNlSWQ6IHRoaXMucHJvcE5hbWUsXG4gICAgICAgICAgICByZWZlcmVuY2VMYWJlbDogdGhpcy5wcm9wTmFtZSArIFwiWyBCT09MRUFOIF1cIixcbiAgICAgICAgICAgIHZhbHVlTGFiZWw6IEJvb2xlYW5TdGF0ZVByb3BlcnR5LkZBTFNFLmxhYmVsLFxuICAgICAgICAgICAgdmFsdWU6IEJvb2xlYW5TdGF0ZVByb3BlcnR5LkZBTFNFLnZhbHVlLFxuICAgICAgICAgICAgb3BlcmF0b3I6IFwiZXFcIixcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZXRTZXRUcnVlQ29tbWFuZCgpOiBTdGF0ZUNvbW1hbmQge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAga2luZDogXCJTVEFURV9NVVRBVEVfQ09NTUFORFwiLFxuICAgICAgICAgICAgdGFyZ2V0OiBcIlNUQVRFXCIsXG4gICAgICAgICAgICB0YXJnZXRJZDogXCJTVEFURVwiLFxuICAgICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgICAgIG11dGF0aW9uOiB7IHByb3BOYW1lOiB0aGlzLnByb3BOYW1lLCBraW5kOiBcInNldC1udW1iZXJcIiwgdmFsdWU6IDEgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2V0U2V0RmFsc2VDb21tYW5kKCk6IFN0YXRlQ29tbWFuZCB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBraW5kOiBcIlNUQVRFX01VVEFURV9DT01NQU5EXCIsXG4gICAgICAgICAgICB0YXJnZXQ6IFwiU1RBVEVcIixcbiAgICAgICAgICAgIHRhcmdldElkOiBcIlNUQVRFXCIsXG4gICAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICAgICAgbXV0YXRpb246IHsgcHJvcE5hbWU6IHRoaXMucHJvcE5hbWUsIGtpbmQ6IFwic2V0LW51bWJlclwiLCB2YWx1ZTogMCB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm9wTmFtZTogUHJvcE5hbWUsIHByaXZhdGUgcmVhZG9ubHkgaW5pdGlhbFZhbHVlOiBib29sZWFuLCBkZXNjcmlwdGlvbjogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMucHJvcE5hbWUgPSBwcm9wTmFtZTtcbiAgICAgICAgY29uc3QgaW5pdGlhbCA9IGluaXRpYWxWYWx1ZSA/IDEgOiAwO1xuICAgICAgICBjb25zdCBwcm9wRGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbiA/IGRlc2NyaXB0aW9uIDogXCJObyBkZXNjcmlwdGlvbiBnaXZlblwiO1xuICAgICAgICB0aGlzLnByb3BEZWZpbml0aW9uID0ge1xuICAgICAgICAgICAgcHJvcERlc2NyaXB0aW9uLFxuICAgICAgICAgICAgcHJvcE5hbWU6IHByb3BOYW1lLFxuICAgICAgICAgICAgaW5pdGlhbFZhbHVlOiBpbml0aWFsLFxuICAgICAgICAgICAgb3B0aW9uczogW1xuICAgICAgICAgICAgICAgIHsgdmFsdWU6IEJvb2xlYW5TdGF0ZVByb3BlcnR5LkZBTFNFLnZhbHVlLCB2YWx1ZUxhYmVsOiBCb29sZWFuU3RhdGVQcm9wZXJ0eS5GQUxTRS5sYWJlbCB9LFxuICAgICAgICAgICAgICAgIHsgdmFsdWU6IEJvb2xlYW5TdGF0ZVByb3BlcnR5LlRSVUUudmFsdWUsIHZhbHVlTGFiZWw6IEJvb2xlYW5TdGF0ZVByb3BlcnR5LlRSVUUubGFiZWwgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBfdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgfTtcbiAgICB9XG59XG4iLCAiLy8gVGhlIGRlZmF1bHQgbGVuZ3RoIG9mIGFuIElEXG5jb25zdCBJRF9MRU5HVEggPSAzMjtcblxuLy8gVGhlIG1pbmltdW0gbGVuZ3RoIG9mIGFuIElEXG5jb25zdCBNSU5fTEVOR1RIID0gMTA7XG5cbmV4cG9ydCB0eXBlIElEPEIgZXh0ZW5kcyBzdHJpbmc+ID0gc3RyaW5nICYgeyBfX0lEX186IEIgfTtcblxuY29uc3QgaXNJRCA9IDxjb25zdCBCIGV4dGVuZHMgc3RyaW5nPihpZE5hbWU6IEIsIGlkPzogc3RyaW5nKTogaWQgaXMgSUQ8Qj4gPT4ge1xuICBpZiAodHlwZW9mIGlkICE9PSBcInN0cmluZ1wiKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBpZC5sZW5ndGggPj0gTUlOX0xFTkdUSDtcbn07XG5cbmNvbnN0IGNyZWF0ZUlEQnlOYW1lID0gPGNvbnN0IEIgZXh0ZW5kcyBzdHJpbmc+KGlkTmFtZTogQik6IElEPEI+ID0+IHtcbiAgY29uc3QgbGV0dGVycyA9IFwiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnl6XCI7XG4gIGNvbnN0IGFsbCA9IGxldHRlcnMgKyBsZXR0ZXJzLnRvVXBwZXJDYXNlKCk7XG4gIGxldCByZXN1bHQgPSBcIlwiO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IElEX0xFTkdUSDsgaSsrKSB7XG4gICAgY29uc3QgY2hhciA9IGFsbC5jaGFyQXQoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYWxsLmxlbmd0aCkpO1xuICAgIHJlc3VsdCArPSBjaGFyO1xuICB9XG4gIHJldHVybiByZXN1bHQgYXMgSUQ8Qj47XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBvYmplY3Qgd2l0aCBoZWxwZXIgZnVuY3Rpb25zIGZvciBhIHNwZWNpZmljIElEIHR5cGVcbiAqIEBwYXJhbSBpZE5hbWVcbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVR5cGVkSWRTaW5nbGV0b24gPSA8Y29uc3QgQiBleHRlbmRzIHN0cmluZz4oaWROYW1lOiBCKSA9PiB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IElEIG9mIHRoZSBjb3JyZWN0IHR5cGVcbiAgICovXG4gIGNvbnN0IGNyZWF0ZSA9ICgpOiBJRDxCPiA9PiBjcmVhdGVJREJ5TmFtZShpZE5hbWUpO1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGlkIGlzIG9mIHRoZSBjb3JyZWN0IHR5cGVcbiAgICogQHBhcmFtIGlkXG4gICAqL1xuICBjb25zdCBpcyA9IChpZDogc3RyaW5nKTogaWQgaXMgSUQ8Qj4gPT4gaXNJRChpZE5hbWUsIGlkKTtcblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBpZCBpcyBvZiB0aGUgY29ycmVjdCB0eXBlLCBpZiBub3QgaXQgdGhyb3dzIGFuIGVycm9yXG4gICAqIEBwYXJhbSBpZFxuICAgKi9cbiAgY29uc3QgdmFsaWRhdGVPclRocm93ID0gKGlkOiBzdHJpbmcpOiBJRDxCPiA9PiB7XG4gICAgaWYgKCFpcyhpZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBpZDogJHtpZH1gKTtcbiAgICB9XG4gICAgcmV0dXJuIGlkO1xuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgbG93ZXJjYXNlIG5hbWUgb2YgdGhlIGlkIChTQ0hFTUEsIFBBR0UsIGV0YylcbiAgICovXG4gIGNvbnN0IG5hbWU6IEIgPSBpZE5hbWU7XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgdGhhdCB0aGUgaWQgaXMgb2YgdGhlIGNvcnJlY3QgdHlwZSwgaWYgbm90IGl0IGNyZWF0ZXMgYSBuZXcgb25lXG4gICAqIEBwYXJhbSBpZFxuICAgKi9cbiAgY29uc3QgZW5zdXJlID0gKGlkOiBzdHJpbmcpOiBJRDxCPiA9PiB7XG4gICAgcmV0dXJuIGlzKGlkKSA/IGlkIDogY3JlYXRlKCk7XG4gIH07XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoeyBjcmVhdGUsIGlzLCBlbnN1cmUsIHZhbGlkYXRlT3JUaHJvdywgbmFtZSB9KTtcbn07XG5cbmV4cG9ydCB0eXBlIFNjaGVtYUlEID0gSUQ8XCJTQ0hFTUFcIj47XG5leHBvcnQgY29uc3QgU2NoZW1hSUQgPSBjcmVhdGVUeXBlZElkU2luZ2xldG9uKFwiU0NIRU1BXCIpO1xuZXhwb3J0IHR5cGUgUGFnZUlEID0gSUQ8XCJQQUdFXCI+O1xuZXhwb3J0IGNvbnN0IFBhZ2VJRCA9IGNyZWF0ZVR5cGVkSWRTaW5nbGV0b24oXCJQQUdFXCIpO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7OztBQ3dDTyxJQUFVO0FBQUEsQ0FBVixDQUFVQSxlQUFWO0FBQ0UsRUFBTUEsV0FBQSxlQUFlLENBQzFCLFdBS0c7QUFDSCxVQUFNLEVBQUUsTUFBTSxJQUFJO0FBQ2xCLFVBQU0sWUFBWSxNQUFNLE9BQXlCLENBQUMsS0FBSyxTQUFTO0FBQzlELFVBQUksTUFBTSxRQUFRLEtBQUssS0FBSyxHQUFHO0FBQzdCLFlBQUksS0FBSyxHQUFHLEtBQUssS0FBSztBQUFBLE1BQ3hCO0FBQ0EsYUFBTztBQUFBLElBQ1QsR0FBRyxDQUFDLENBQUM7QUFDTCxVQUFNLFlBQThCLE1BQU0sT0FBeUIsQ0FBQyxLQUFLLFNBQVM7QUFDaEYsVUFBSSxNQUFNLFFBQVEsS0FBSyxLQUFLLEdBQUc7QUFDN0IsWUFBSSxLQUFLLEdBQUcsS0FBSyxLQUFLO0FBQUEsTUFDeEI7QUFDQSxhQUFPO0FBQUEsSUFDVCxHQUFHLENBQUMsQ0FBQztBQUVMLFdBQU8sRUFBRSxXQUFXLFdBQVcsV0FBVyxDQUFDLEVBQUU7QUFBQSxFQUMvQztBQUFBLEdBdkJlOzs7QUN2Q1YsSUFBVTtBQUFBLENBQVYsQ0FBVUMsZ0JBQVY7QUFDSSxFQUFNQSxZQUFBLE1BQU0sTUFBTSxLQUFL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VUFBVSxFQUFFLFVBQVUsS0FBSyxVQUFVLE1BQU0sY0FBYyxPQUFPLEVBQUU7QUFBQSxNQUN0RTtBQUFBLElBQ0o7QUFBQSxFQUNKO0FBQUEsRUFFQSxxQkFBbUM7QUFDL0IsV0FBTztBQUFBLE1BQ0gsTUFBTTtBQUFBLE1BQ04sUUFBUTtBQUFBLE1BQ1IsVUFBVTtBQUFBLE1BQ1YsU0FBUztBQUFBLFFBQ0wsVUFBVSxFQUFFLFVBQVUsS0FBSyxVQUFVLE1BQU0sY0FBYyxPQUFPLEVBQUU7QUFBQSxNQUN0RTtBQUFBLElBQ0o7QUFBQSxFQUNKO0FBaUJKOzs7QUNuRUEsSUFBTSxZQUFZO0FBR2xCLElBQU0sYUFBYTtBQUluQixJQUFNLE9BQU8sQ0FBeUIsUUFBVyxPQUE2QjtBQUM1RSxNQUFJLE9BQU8sT0FBTztBQUFVLFdBQU87QUFDbkMsU0FBTyxHQUFHLFVBQVU7QUFDdEI7QUFFQSxJQUFNLGlCQUFpQixDQUF5QixXQUFxQjtBQUNuRSxRQUFNLFVBQVU7QUFDaEIsUUFBTSxNQUFNLFVBQVUsUUFBUSxZQUFZO0FBQzFDLE1BQUksU0FBUztBQUNiLFdBQVMsSUFBSSxHQUFHLElBQUksV0FBVyxLQUFLO0FBQ2xDLFVBQU0sT0FBTyxJQUFJLE9BQU8sS0FBSyxNQUFNLEtBQUssT0FBTyxJQUFJLElBQUksTUFBTSxDQUFDO0FBQzlELGNBQVU7QUFBQSxFQUNaO0FBQ0EsU0FBTztBQUNUO0FBTU8sSUFBTSx5QkFBeUIsQ0FBeUIsV0FBYztBQUkzRSxRQUFNLFNBQVMsTUFBYSxlQUFlLE1BQU07QUFNakQsUUFBTSxLQUFLLENBQUMsT0FBNEIsS0FBSyxRQUFRLEVBQUU7QUFNdkQsUUFBTSxrQkFBa0IsQ0FBQyxPQUFzQjtBQUM3QyxRQUFJLENBQUMsR0FBRyxFQUFFLEdBQUc7QUFDWCxZQUFNLElBQUksTUFBTSxlQUFlLEVBQUUsRUFBRTtBQUFBLElBQ3JDO0FBQ0EsV0FBTztBQUFBLEVBQ1Q7QUFLQSxRQUFNLE9BQVU7QUFNaEIsUUFBTSxTQUFTLENBQUMsT0FBc0I7QUFDcEMsV0FBTyxHQUFHLEVBQUUsSUFBSSxLQUFLLE9BQU87QUFBQSxFQUM5QjtBQUVBLFNBQU8sT0FBTyxPQUFPLEVBQUUsUUFBUSxJQUFJLFFBQVEsaUJBQWlCLEtBQUssQ0FBQztBQUNwRTtBQUdPLElBQU0sV0FBVyx1QkFBdUIsUUFBUTtBQUVoRCxJQUFNLFNBQVMsdUJBQXVCLE1BQU07IiwKICAibmFtZXMiOiBbIlNjaGVtYUR0byIsICJEVGltZXN0YW1wIiwgIkRVdGlsIiwgImlzTnVtYmVyIiwgIkRDc3MiLCAiRFN0eWxlIiwgIkFuc3dlcmVkUXVlc3Rpb24iLCAiQ29uZGl0aW9uIiwgImNvbmRpdGlvbiIsICJSdWxlIiwgInRhZyIsICJERXZlbnRIYW5kbGVyIiwgImR0byIsICJkdG8iLCAiU2NhbGUiLCAiUmVzdWx0IiwgIkRTdGF0ZSJdCn0K