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