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