@okeyamy/lua 5.0.4
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/README.md +552 -0
- package/build/es5/__tests__/ai-personalize.test.js +811 -0
- package/build/es5/__tests__/lua.js +134 -0
- package/build/es5/__tests__/original-roughly.js +197 -0
- package/build/es5/__tests__/original.js +174 -0
- package/build/es5/__tests__/unit.js +72 -0
- package/build/es5/__tests__/weighted-history.test.js +376 -0
- package/build/es5/ai-personalize.js +641 -0
- package/build/es5/index.js +30 -0
- package/build/es5/lua.js +366 -0
- package/build/es5/personalization.js +811 -0
- package/build/es5/prompts/personalization-prompts.js +260 -0
- package/build/es5/storage/weighted-history.js +384 -0
- package/build/es5/stores/browser-cookie.js +25 -0
- package/build/es5/stores/local.js +29 -0
- package/build/es5/stores/memory.js +22 -0
- package/build/es5/utils.js +54 -0
- package/build/es5/utm-personalize.js +817 -0
- package/build/es5/utm.js +304 -0
- package/build/lua.dev.js +1574 -0
- package/build/lua.es.js +1566 -0
- package/build/lua.js +1574 -0
- package/build/lua.min.js +8 -0
- package/package.json +68 -0
|
@@ -0,0 +1,811 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
5
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
6
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
7
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
8
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
9
|
+
/**
|
|
10
|
+
* Tests for AI Personalization Engine
|
|
11
|
+
* Tests config validation, API communication, response validation, and caching
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Mock localStorage
|
|
15
|
+
var localStorageMock = function () {
|
|
16
|
+
var store = {};
|
|
17
|
+
return {
|
|
18
|
+
getItem: jest.fn(function (key) {
|
|
19
|
+
return store[key] || null;
|
|
20
|
+
}),
|
|
21
|
+
setItem: jest.fn(function (key, val) {
|
|
22
|
+
store[key] = String(val);
|
|
23
|
+
}),
|
|
24
|
+
removeItem: jest.fn(function (key) {
|
|
25
|
+
delete store[key];
|
|
26
|
+
}),
|
|
27
|
+
clear: jest.fn(function () {
|
|
28
|
+
store = {};
|
|
29
|
+
}),
|
|
30
|
+
get length() {
|
|
31
|
+
return Object.keys(store).length;
|
|
32
|
+
},
|
|
33
|
+
key: jest.fn(function (i) {
|
|
34
|
+
return Object.keys(store)[i] || null;
|
|
35
|
+
})
|
|
36
|
+
};
|
|
37
|
+
}();
|
|
38
|
+
Object.defineProperty(global, 'localStorage', {
|
|
39
|
+
value: localStorageMock
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Mock crypto
|
|
43
|
+
Object.defineProperty(global, 'crypto', {
|
|
44
|
+
value: {
|
|
45
|
+
getRandomValues: function getRandomValues(buf) {
|
|
46
|
+
for (var i = 0; i < buf.length; i++) buf[i] = Math.floor(Math.random() * 256);
|
|
47
|
+
return buf;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Mock fetch
|
|
53
|
+
global.fetch = jest.fn();
|
|
54
|
+
global.AbortController = /*#__PURE__*/function () {
|
|
55
|
+
function _class() {
|
|
56
|
+
(0, _classCallCheck2.default)(this, _class);
|
|
57
|
+
this.signal = {};
|
|
58
|
+
}
|
|
59
|
+
return (0, _createClass2.default)(_class, [{
|
|
60
|
+
key: "abort",
|
|
61
|
+
value: function abort() {}
|
|
62
|
+
}]);
|
|
63
|
+
}();
|
|
64
|
+
|
|
65
|
+
// Load modules in order (dependencies first)
|
|
66
|
+
require('../storage/weighted-history');
|
|
67
|
+
require('../prompts/personalization-prompts');
|
|
68
|
+
require('../ai-personalize');
|
|
69
|
+
var LuaAIPersonalize = global.LuaAIPersonalize;
|
|
70
|
+
var LuaPrompts = global.LuaPrompts;
|
|
71
|
+
var LuaWeightedHistory = global.LuaWeightedHistory;
|
|
72
|
+
var mockTemplates = {
|
|
73
|
+
'gaming': {
|
|
74
|
+
headline: 'Level Up Your Setup',
|
|
75
|
+
subheadline: 'Pro gear for serious gamers.',
|
|
76
|
+
ctaLabel: 'Explore Gaming',
|
|
77
|
+
ctaLink: '/gaming',
|
|
78
|
+
image: 'gaming.jpg'
|
|
79
|
+
},
|
|
80
|
+
'professional': {
|
|
81
|
+
headline: 'Work Smarter',
|
|
82
|
+
subheadline: 'Premium productivity tools.',
|
|
83
|
+
ctaLabel: 'View Collection',
|
|
84
|
+
ctaLink: '/professional',
|
|
85
|
+
image: 'pro.jpg'
|
|
86
|
+
},
|
|
87
|
+
'default': {
|
|
88
|
+
headline: 'Welcome',
|
|
89
|
+
subheadline: 'Discover products.',
|
|
90
|
+
ctaLabel: 'Shop Now',
|
|
91
|
+
ctaLink: '/shop',
|
|
92
|
+
image: 'default.jpg'
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
var mockContext = {
|
|
96
|
+
utm: {
|
|
97
|
+
utm_source: 'reddit',
|
|
98
|
+
utm_campaign: 'gaming_console'
|
|
99
|
+
},
|
|
100
|
+
referrer: {
|
|
101
|
+
source: 'reddit',
|
|
102
|
+
category: 'social',
|
|
103
|
+
url: 'https://reddit.com'
|
|
104
|
+
},
|
|
105
|
+
userAgent: {
|
|
106
|
+
isMobile: false,
|
|
107
|
+
isTablet: false,
|
|
108
|
+
isDesktop: true,
|
|
109
|
+
raw: ''
|
|
110
|
+
},
|
|
111
|
+
timestamp: Date.now(),
|
|
112
|
+
hasUTM: true,
|
|
113
|
+
primaryIntent: 'gaming'
|
|
114
|
+
};
|
|
115
|
+
beforeEach(function () {
|
|
116
|
+
localStorageMock.clear();
|
|
117
|
+
jest.clearAllMocks();
|
|
118
|
+
global.fetch.mockReset();
|
|
119
|
+
});
|
|
120
|
+
describe('LuaAIPersonalize', function () {
|
|
121
|
+
it('should be registered on global', function () {
|
|
122
|
+
expect(LuaAIPersonalize).toBeDefined();
|
|
123
|
+
expect((0, _typeof2.default)(LuaAIPersonalize.decide)).toBe('function');
|
|
124
|
+
expect((0, _typeof2.default)(LuaAIPersonalize.normalizeConfig)).toBe('function');
|
|
125
|
+
});
|
|
126
|
+
describe('normalizeConfig', function () {
|
|
127
|
+
it('should reject null config', function () {
|
|
128
|
+
var result = LuaAIPersonalize.normalizeConfig(null);
|
|
129
|
+
expect(result.valid).toBe(false);
|
|
130
|
+
});
|
|
131
|
+
it('should reject config without apiKey or apiUrl', function () {
|
|
132
|
+
var result = LuaAIPersonalize.normalizeConfig({});
|
|
133
|
+
expect(result.valid).toBe(false);
|
|
134
|
+
expect(result.error).toContain('apiKey');
|
|
135
|
+
});
|
|
136
|
+
it('should accept config with apiKey', function () {
|
|
137
|
+
var result = LuaAIPersonalize.normalizeConfig({
|
|
138
|
+
apiKey: 'sk-test123'
|
|
139
|
+
});
|
|
140
|
+
expect(result.valid).toBe(true);
|
|
141
|
+
expect(result.useDirectApi).toBe(true);
|
|
142
|
+
expect(result.apiKey).toBe('sk-test123');
|
|
143
|
+
});
|
|
144
|
+
it('should accept config with apiUrl', function () {
|
|
145
|
+
var result = LuaAIPersonalize.normalizeConfig({
|
|
146
|
+
apiUrl: 'https://proxy.example.com/api'
|
|
147
|
+
});
|
|
148
|
+
expect(result.valid).toBe(true);
|
|
149
|
+
expect(result.useDirectApi).toBe(false);
|
|
150
|
+
expect(result.apiUrl).toBe('https://proxy.example.com/api');
|
|
151
|
+
});
|
|
152
|
+
it('should apply defaults for missing fields', function () {
|
|
153
|
+
var result = LuaAIPersonalize.normalizeConfig({
|
|
154
|
+
apiKey: 'sk-test'
|
|
155
|
+
});
|
|
156
|
+
expect(result.model).toBe('gpt-4o-mini');
|
|
157
|
+
expect(result.mode).toBe('select');
|
|
158
|
+
expect(result.timeout).toBe(5000);
|
|
159
|
+
expect(result.maxRetries).toBe(1);
|
|
160
|
+
expect(result.fallbackToStandard).toBe(true);
|
|
161
|
+
expect(result.cacheDecisions).toBe(true);
|
|
162
|
+
expect(result.historyEnabled).toBe(true);
|
|
163
|
+
expect(result.historyDecayRate).toBe(0.9);
|
|
164
|
+
});
|
|
165
|
+
it('should use custom values when provided', function () {
|
|
166
|
+
var result = LuaAIPersonalize.normalizeConfig({
|
|
167
|
+
apiKey: 'sk-test',
|
|
168
|
+
model: 'gpt-4o',
|
|
169
|
+
mode: 'generate',
|
|
170
|
+
timeout: 10000,
|
|
171
|
+
temperature: 0.5,
|
|
172
|
+
maxTokens: 1000
|
|
173
|
+
});
|
|
174
|
+
expect(result.model).toBe('gpt-4o');
|
|
175
|
+
expect(result.mode).toBe('generate');
|
|
176
|
+
expect(result.timeout).toBe(10000);
|
|
177
|
+
expect(result.temperature).toBe(0.5);
|
|
178
|
+
expect(result.maxTokens).toBe(1000);
|
|
179
|
+
});
|
|
180
|
+
it('should prefer apiUrl over direct when both provided', function () {
|
|
181
|
+
var result = LuaAIPersonalize.normalizeConfig({
|
|
182
|
+
apiKey: 'sk-test',
|
|
183
|
+
apiUrl: 'https://proxy.com/api'
|
|
184
|
+
});
|
|
185
|
+
expect(result.useDirectApi).toBe(false);
|
|
186
|
+
expect(result.apiUrl).toBe('https://proxy.com/api');
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
describe('validateSelectResponse', function () {
|
|
190
|
+
it('should accept valid selection response', function () {
|
|
191
|
+
var result = LuaAIPersonalize.validateSelectResponse({
|
|
192
|
+
selectedVariant: 'gaming',
|
|
193
|
+
confidence: 0.9,
|
|
194
|
+
reasoning: 'test'
|
|
195
|
+
}, mockTemplates);
|
|
196
|
+
expect(result.valid).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
it('should reject missing selectedVariant', function () {
|
|
199
|
+
var result = LuaAIPersonalize.validateSelectResponse({
|
|
200
|
+
confidence: 0.9
|
|
201
|
+
}, mockTemplates);
|
|
202
|
+
expect(result.valid).toBe(false);
|
|
203
|
+
});
|
|
204
|
+
it('should reject non-existent variant', function () {
|
|
205
|
+
var result = LuaAIPersonalize.validateSelectResponse({
|
|
206
|
+
selectedVariant: 'nonexistent'
|
|
207
|
+
}, mockTemplates);
|
|
208
|
+
expect(result.valid).toBe(false);
|
|
209
|
+
expect(result.error).toContain('nonexistent');
|
|
210
|
+
});
|
|
211
|
+
it('should reject null response', function () {
|
|
212
|
+
var result = LuaAIPersonalize.validateSelectResponse(null, mockTemplates);
|
|
213
|
+
expect(result.valid).toBe(false);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
describe('validateGenerateResponse', function () {
|
|
217
|
+
it('should accept valid generation response', function () {
|
|
218
|
+
var result = LuaAIPersonalize.validateGenerateResponse({
|
|
219
|
+
headline: 'Test Headline',
|
|
220
|
+
subheadline: 'Test subheadline here',
|
|
221
|
+
ctaLabel: 'Click Me'
|
|
222
|
+
});
|
|
223
|
+
expect(result.valid).toBe(true);
|
|
224
|
+
});
|
|
225
|
+
it('should reject missing headline', function () {
|
|
226
|
+
var result = LuaAIPersonalize.validateGenerateResponse({
|
|
227
|
+
subheadline: 'Test',
|
|
228
|
+
ctaLabel: 'Click'
|
|
229
|
+
});
|
|
230
|
+
expect(result.valid).toBe(false);
|
|
231
|
+
expect(result.error).toContain('headline');
|
|
232
|
+
});
|
|
233
|
+
it('should reject missing subheadline', function () {
|
|
234
|
+
var result = LuaAIPersonalize.validateGenerateResponse({
|
|
235
|
+
headline: 'Test',
|
|
236
|
+
ctaLabel: 'Click'
|
|
237
|
+
});
|
|
238
|
+
expect(result.valid).toBe(false);
|
|
239
|
+
});
|
|
240
|
+
it('should reject missing ctaLabel', function () {
|
|
241
|
+
var result = LuaAIPersonalize.validateGenerateResponse({
|
|
242
|
+
headline: 'Test',
|
|
243
|
+
subheadline: 'Sub'
|
|
244
|
+
});
|
|
245
|
+
expect(result.valid).toBe(false);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe('decide (select mode)', function () {
|
|
249
|
+
it('should call OpenAI and return a valid decision', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
250
|
+
var decision;
|
|
251
|
+
return _regenerator.default.wrap(function (_context) {
|
|
252
|
+
while (1) switch (_context.prev = _context.next) {
|
|
253
|
+
case 0:
|
|
254
|
+
global.fetch.mockResolvedValueOnce({
|
|
255
|
+
ok: true,
|
|
256
|
+
json: function json() {
|
|
257
|
+
return Promise.resolve({
|
|
258
|
+
choices: [{
|
|
259
|
+
message: {
|
|
260
|
+
content: JSON.stringify({
|
|
261
|
+
selectedVariant: 'gaming',
|
|
262
|
+
confidence: 0.92,
|
|
263
|
+
reasoning: 'User came from Reddit with gaming console campaign'
|
|
264
|
+
})
|
|
265
|
+
}
|
|
266
|
+
}]
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
_context.next = 1;
|
|
271
|
+
return LuaAIPersonalize.decide(mockContext, {
|
|
272
|
+
templates: mockTemplates,
|
|
273
|
+
aiConfig: {
|
|
274
|
+
apiKey: 'sk-test',
|
|
275
|
+
mode: 'select',
|
|
276
|
+
cacheDecisions: false,
|
|
277
|
+
historyEnabled: false
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
case 1:
|
|
281
|
+
decision = _context.sent;
|
|
282
|
+
expect(decision.intent).toBe('gaming');
|
|
283
|
+
expect(decision.source).toBe('ai');
|
|
284
|
+
expect(decision.template).toBe(mockTemplates['gaming']);
|
|
285
|
+
expect(decision.aiResponse.confidence).toBe(0.92);
|
|
286
|
+
expect(decision.aiResponse.model).toBe('gpt-4o-mini');
|
|
287
|
+
expect(decision.aiResponse.mode).toBe('select');
|
|
288
|
+
case 2:
|
|
289
|
+
case "end":
|
|
290
|
+
return _context.stop();
|
|
291
|
+
}
|
|
292
|
+
}, _callee);
|
|
293
|
+
})));
|
|
294
|
+
it('should include Authorization header for direct API', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
295
|
+
return _regenerator.default.wrap(function (_context2) {
|
|
296
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
297
|
+
case 0:
|
|
298
|
+
global.fetch.mockResolvedValueOnce({
|
|
299
|
+
ok: true,
|
|
300
|
+
json: function json() {
|
|
301
|
+
return Promise.resolve({
|
|
302
|
+
choices: [{
|
|
303
|
+
message: {
|
|
304
|
+
content: JSON.stringify({
|
|
305
|
+
selectedVariant: 'gaming',
|
|
306
|
+
confidence: 0.8,
|
|
307
|
+
reasoning: 'test'
|
|
308
|
+
})
|
|
309
|
+
}
|
|
310
|
+
}]
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
_context2.next = 1;
|
|
315
|
+
return LuaAIPersonalize.decide(mockContext, {
|
|
316
|
+
templates: mockTemplates,
|
|
317
|
+
aiConfig: {
|
|
318
|
+
apiKey: 'sk-mykey123',
|
|
319
|
+
mode: 'select',
|
|
320
|
+
cacheDecisions: false,
|
|
321
|
+
historyEnabled: false
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
case 1:
|
|
325
|
+
expect(global.fetch).toHaveBeenCalledWith('https://api.openai.com/v1/chat/completions', expect.objectContaining({
|
|
326
|
+
method: 'POST',
|
|
327
|
+
headers: expect.objectContaining({
|
|
328
|
+
'Authorization': 'Bearer sk-mykey123'
|
|
329
|
+
})
|
|
330
|
+
}));
|
|
331
|
+
case 2:
|
|
332
|
+
case "end":
|
|
333
|
+
return _context2.stop();
|
|
334
|
+
}
|
|
335
|
+
}, _callee2);
|
|
336
|
+
})));
|
|
337
|
+
it('should use proxy URL when apiUrl is provided', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
338
|
+
return _regenerator.default.wrap(function (_context3) {
|
|
339
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
340
|
+
case 0:
|
|
341
|
+
global.fetch.mockResolvedValueOnce({
|
|
342
|
+
ok: true,
|
|
343
|
+
json: function json() {
|
|
344
|
+
return Promise.resolve({
|
|
345
|
+
choices: [{
|
|
346
|
+
message: {
|
|
347
|
+
content: JSON.stringify({
|
|
348
|
+
selectedVariant: 'gaming',
|
|
349
|
+
confidence: 0.8,
|
|
350
|
+
reasoning: 'test'
|
|
351
|
+
})
|
|
352
|
+
}
|
|
353
|
+
}]
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
_context3.next = 1;
|
|
358
|
+
return LuaAIPersonalize.decide(mockContext, {
|
|
359
|
+
templates: mockTemplates,
|
|
360
|
+
aiConfig: {
|
|
361
|
+
apiUrl: 'https://myproxy.com/openai',
|
|
362
|
+
mode: 'select',
|
|
363
|
+
cacheDecisions: false,
|
|
364
|
+
historyEnabled: false
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
case 1:
|
|
368
|
+
expect(global.fetch).toHaveBeenCalledWith('https://myproxy.com/openai', expect.any(Object));
|
|
369
|
+
case 2:
|
|
370
|
+
case "end":
|
|
371
|
+
return _context3.stop();
|
|
372
|
+
}
|
|
373
|
+
}, _callee3);
|
|
374
|
+
})));
|
|
375
|
+
});
|
|
376
|
+
describe('decide (generate mode)', function () {
|
|
377
|
+
it('should call OpenAI and return generated content', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
|
|
378
|
+
var decision;
|
|
379
|
+
return _regenerator.default.wrap(function (_context4) {
|
|
380
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
381
|
+
case 0:
|
|
382
|
+
global.fetch.mockResolvedValueOnce({
|
|
383
|
+
ok: true,
|
|
384
|
+
json: function json() {
|
|
385
|
+
return Promise.resolve({
|
|
386
|
+
choices: [{
|
|
387
|
+
message: {
|
|
388
|
+
content: JSON.stringify({
|
|
389
|
+
headline: 'Game On, Gear Up',
|
|
390
|
+
subheadline: 'The ultimate gaming setup awaits you.',
|
|
391
|
+
ctaLabel: 'Level Up',
|
|
392
|
+
confidence: 0.88,
|
|
393
|
+
reasoning: 'Gamer from Reddit'
|
|
394
|
+
})
|
|
395
|
+
}
|
|
396
|
+
}]
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
_context4.next = 1;
|
|
401
|
+
return LuaAIPersonalize.decide(mockContext, {
|
|
402
|
+
templates: mockTemplates,
|
|
403
|
+
aiConfig: {
|
|
404
|
+
apiKey: 'sk-test',
|
|
405
|
+
mode: 'generate',
|
|
406
|
+
cacheDecisions: false,
|
|
407
|
+
historyEnabled: false
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
case 1:
|
|
411
|
+
decision = _context4.sent;
|
|
412
|
+
expect(decision.intent).toBe('ai-generated');
|
|
413
|
+
expect(decision.source).toBe('ai');
|
|
414
|
+
expect(decision.template.headline).toBe('Game On, Gear Up');
|
|
415
|
+
expect(decision.template.subheadline).toBe('The ultimate gaming setup awaits you.');
|
|
416
|
+
expect(decision.template.ctaLabel).toBe('Level Up');
|
|
417
|
+
expect(decision.aiResponse.mode).toBe('generate');
|
|
418
|
+
case 2:
|
|
419
|
+
case "end":
|
|
420
|
+
return _context4.stop();
|
|
421
|
+
}
|
|
422
|
+
}, _callee4);
|
|
423
|
+
})));
|
|
424
|
+
});
|
|
425
|
+
describe('error handling', function () {
|
|
426
|
+
it('should reject with error for invalid config', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5() {
|
|
427
|
+
return _regenerator.default.wrap(function (_context5) {
|
|
428
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
429
|
+
case 0:
|
|
430
|
+
_context5.next = 1;
|
|
431
|
+
return expect(LuaAIPersonalize.decide(mockContext, {
|
|
432
|
+
templates: mockTemplates,
|
|
433
|
+
aiConfig: {}
|
|
434
|
+
})).rejects.toThrow('apiKey');
|
|
435
|
+
case 1:
|
|
436
|
+
case "end":
|
|
437
|
+
return _context5.stop();
|
|
438
|
+
}
|
|
439
|
+
}, _callee5);
|
|
440
|
+
})));
|
|
441
|
+
it('should reject on API error', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee6() {
|
|
442
|
+
return _regenerator.default.wrap(function (_context6) {
|
|
443
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
444
|
+
case 0:
|
|
445
|
+
global.fetch.mockResolvedValueOnce({
|
|
446
|
+
ok: false,
|
|
447
|
+
status: 401,
|
|
448
|
+
text: function text() {
|
|
449
|
+
return Promise.resolve('Unauthorized');
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
_context6.next = 1;
|
|
453
|
+
return expect(LuaAIPersonalize.decide(mockContext, {
|
|
454
|
+
templates: mockTemplates,
|
|
455
|
+
aiConfig: {
|
|
456
|
+
apiKey: 'sk-bad',
|
|
457
|
+
cacheDecisions: false,
|
|
458
|
+
historyEnabled: false,
|
|
459
|
+
maxRetries: 0
|
|
460
|
+
}
|
|
461
|
+
})).rejects.toThrow('401');
|
|
462
|
+
case 1:
|
|
463
|
+
case "end":
|
|
464
|
+
return _context6.stop();
|
|
465
|
+
}
|
|
466
|
+
}, _callee6);
|
|
467
|
+
})));
|
|
468
|
+
it('should reject on invalid JSON response', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee7() {
|
|
469
|
+
return _regenerator.default.wrap(function (_context7) {
|
|
470
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
471
|
+
case 0:
|
|
472
|
+
global.fetch.mockResolvedValueOnce({
|
|
473
|
+
ok: true,
|
|
474
|
+
json: function json() {
|
|
475
|
+
return Promise.resolve({
|
|
476
|
+
choices: [{
|
|
477
|
+
message: {
|
|
478
|
+
content: 'this is not json'
|
|
479
|
+
}
|
|
480
|
+
}]
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
_context7.next = 1;
|
|
485
|
+
return expect(LuaAIPersonalize.decide(mockContext, {
|
|
486
|
+
templates: mockTemplates,
|
|
487
|
+
aiConfig: {
|
|
488
|
+
apiKey: 'sk-test',
|
|
489
|
+
cacheDecisions: false,
|
|
490
|
+
historyEnabled: false,
|
|
491
|
+
maxRetries: 0
|
|
492
|
+
}
|
|
493
|
+
})).rejects.toThrow();
|
|
494
|
+
case 1:
|
|
495
|
+
case "end":
|
|
496
|
+
return _context7.stop();
|
|
497
|
+
}
|
|
498
|
+
}, _callee7);
|
|
499
|
+
})));
|
|
500
|
+
it('should reject on invalid selection (nonexistent variant)', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee8() {
|
|
501
|
+
return _regenerator.default.wrap(function (_context8) {
|
|
502
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
503
|
+
case 0:
|
|
504
|
+
global.fetch.mockResolvedValueOnce({
|
|
505
|
+
ok: true,
|
|
506
|
+
json: function json() {
|
|
507
|
+
return Promise.resolve({
|
|
508
|
+
choices: [{
|
|
509
|
+
message: {
|
|
510
|
+
content: JSON.stringify({
|
|
511
|
+
selectedVariant: 'fake',
|
|
512
|
+
confidence: 0.5,
|
|
513
|
+
reasoning: 'oops'
|
|
514
|
+
})
|
|
515
|
+
}
|
|
516
|
+
}]
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
_context8.next = 1;
|
|
521
|
+
return expect(LuaAIPersonalize.decide(mockContext, {
|
|
522
|
+
templates: mockTemplates,
|
|
523
|
+
aiConfig: {
|
|
524
|
+
apiKey: 'sk-test',
|
|
525
|
+
cacheDecisions: false,
|
|
526
|
+
historyEnabled: false,
|
|
527
|
+
maxRetries: 0
|
|
528
|
+
}
|
|
529
|
+
})).rejects.toThrow('does not exist');
|
|
530
|
+
case 1:
|
|
531
|
+
case "end":
|
|
532
|
+
return _context8.stop();
|
|
533
|
+
}
|
|
534
|
+
}, _callee8);
|
|
535
|
+
})));
|
|
536
|
+
});
|
|
537
|
+
describe('caching', function () {
|
|
538
|
+
it('should cache a decision and return it on subsequent calls', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee9() {
|
|
539
|
+
var first, second;
|
|
540
|
+
return _regenerator.default.wrap(function (_context9) {
|
|
541
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
542
|
+
case 0:
|
|
543
|
+
global.fetch.mockResolvedValueOnce({
|
|
544
|
+
ok: true,
|
|
545
|
+
json: function json() {
|
|
546
|
+
return Promise.resolve({
|
|
547
|
+
choices: [{
|
|
548
|
+
message: {
|
|
549
|
+
content: JSON.stringify({
|
|
550
|
+
selectedVariant: 'gaming',
|
|
551
|
+
confidence: 0.9,
|
|
552
|
+
reasoning: 'test'
|
|
553
|
+
})
|
|
554
|
+
}
|
|
555
|
+
}]
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
// First call - hits API
|
|
561
|
+
_context9.next = 1;
|
|
562
|
+
return LuaAIPersonalize.decide(mockContext, {
|
|
563
|
+
templates: mockTemplates,
|
|
564
|
+
aiConfig: {
|
|
565
|
+
apiKey: 'sk-test',
|
|
566
|
+
cacheDecisions: true,
|
|
567
|
+
historyEnabled: false
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
case 1:
|
|
571
|
+
first = _context9.sent;
|
|
572
|
+
expect(first.source).toBe('ai');
|
|
573
|
+
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
574
|
+
|
|
575
|
+
// Second call - should use cache
|
|
576
|
+
_context9.next = 2;
|
|
577
|
+
return LuaAIPersonalize.decide(mockContext, {
|
|
578
|
+
templates: mockTemplates,
|
|
579
|
+
aiConfig: {
|
|
580
|
+
apiKey: 'sk-test',
|
|
581
|
+
cacheDecisions: true,
|
|
582
|
+
historyEnabled: false
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
case 2:
|
|
586
|
+
second = _context9.sent;
|
|
587
|
+
expect(second.source).toBe('ai-cached');
|
|
588
|
+
expect(global.fetch).toHaveBeenCalledTimes(1); // No new fetch call
|
|
589
|
+
case 3:
|
|
590
|
+
case "end":
|
|
591
|
+
return _context9.stop();
|
|
592
|
+
}
|
|
593
|
+
}, _callee9);
|
|
594
|
+
})));
|
|
595
|
+
it('clearCache should remove all cached decisions', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee0() {
|
|
596
|
+
var result;
|
|
597
|
+
return _regenerator.default.wrap(function (_context0) {
|
|
598
|
+
while (1) switch (_context0.prev = _context0.next) {
|
|
599
|
+
case 0:
|
|
600
|
+
// Store something in cache
|
|
601
|
+
global.fetch.mockResolvedValueOnce({
|
|
602
|
+
ok: true,
|
|
603
|
+
json: function json() {
|
|
604
|
+
return Promise.resolve({
|
|
605
|
+
choices: [{
|
|
606
|
+
message: {
|
|
607
|
+
content: JSON.stringify({
|
|
608
|
+
selectedVariant: 'gaming',
|
|
609
|
+
confidence: 0.9,
|
|
610
|
+
reasoning: 'test'
|
|
611
|
+
})
|
|
612
|
+
}
|
|
613
|
+
}]
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
_context0.next = 1;
|
|
618
|
+
return LuaAIPersonalize.decide(mockContext, {
|
|
619
|
+
templates: mockTemplates,
|
|
620
|
+
aiConfig: {
|
|
621
|
+
apiKey: 'sk-test',
|
|
622
|
+
cacheDecisions: true,
|
|
623
|
+
historyEnabled: false
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
case 1:
|
|
627
|
+
LuaAIPersonalize.clearCache();
|
|
628
|
+
|
|
629
|
+
// Next call should hit API again
|
|
630
|
+
global.fetch.mockResolvedValueOnce({
|
|
631
|
+
ok: true,
|
|
632
|
+
json: function json() {
|
|
633
|
+
return Promise.resolve({
|
|
634
|
+
choices: [{
|
|
635
|
+
message: {
|
|
636
|
+
content: JSON.stringify({
|
|
637
|
+
selectedVariant: 'professional',
|
|
638
|
+
confidence: 0.8,
|
|
639
|
+
reasoning: 'cleared'
|
|
640
|
+
})
|
|
641
|
+
}
|
|
642
|
+
}]
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
_context0.next = 2;
|
|
647
|
+
return LuaAIPersonalize.decide(mockContext, {
|
|
648
|
+
templates: mockTemplates,
|
|
649
|
+
aiConfig: {
|
|
650
|
+
apiKey: 'sk-test',
|
|
651
|
+
cacheDecisions: true,
|
|
652
|
+
historyEnabled: false
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
case 2:
|
|
656
|
+
result = _context0.sent;
|
|
657
|
+
expect(result.source).toBe('ai');
|
|
658
|
+
expect(global.fetch).toHaveBeenCalledTimes(2);
|
|
659
|
+
case 3:
|
|
660
|
+
case "end":
|
|
661
|
+
return _context0.stop();
|
|
662
|
+
}
|
|
663
|
+
}, _callee0);
|
|
664
|
+
})));
|
|
665
|
+
});
|
|
666
|
+
describe('isReady', function () {
|
|
667
|
+
it('should return ready for valid config with modules loaded', function () {
|
|
668
|
+
var result = LuaAIPersonalize.isReady({
|
|
669
|
+
apiKey: 'sk-test'
|
|
670
|
+
});
|
|
671
|
+
expect(result.ready).toBe(true);
|
|
672
|
+
});
|
|
673
|
+
it('should return not ready for invalid config', function () {
|
|
674
|
+
var result = LuaAIPersonalize.isReady({});
|
|
675
|
+
expect(result.ready).toBe(false);
|
|
676
|
+
expect(result.error).toBeDefined();
|
|
677
|
+
});
|
|
678
|
+
});
|
|
679
|
+
});
|
|
680
|
+
describe('LuaPrompts', function () {
|
|
681
|
+
it('should be registered on global', function () {
|
|
682
|
+
expect(LuaPrompts).toBeDefined();
|
|
683
|
+
expect((0, _typeof2.default)(LuaPrompts.buildSelectPrompt)).toBe('function');
|
|
684
|
+
expect((0, _typeof2.default)(LuaPrompts.buildGeneratePrompt)).toBe('function');
|
|
685
|
+
expect((0, _typeof2.default)(LuaPrompts.buildMessages)).toBe('function');
|
|
686
|
+
});
|
|
687
|
+
describe('buildMessages', function () {
|
|
688
|
+
it('should build select mode messages', function () {
|
|
689
|
+
var messages = LuaPrompts.buildMessages('select', {
|
|
690
|
+
context: mockContext,
|
|
691
|
+
weightedHistory: 'No history',
|
|
692
|
+
variants: mockTemplates
|
|
693
|
+
});
|
|
694
|
+
expect(messages.length).toBe(2);
|
|
695
|
+
expect(messages[0].role).toBe('system');
|
|
696
|
+
expect(messages[1].role).toBe('user');
|
|
697
|
+
expect(messages[0].content).toContain('personalization');
|
|
698
|
+
expect(messages[1].content).toContain('reddit');
|
|
699
|
+
expect(messages[1].content).toContain('gaming');
|
|
700
|
+
expect(messages[1].content).toContain('AVAILABLE VARIANTS');
|
|
701
|
+
});
|
|
702
|
+
it('should build generate mode messages', function () {
|
|
703
|
+
var messages = LuaPrompts.buildMessages('generate', {
|
|
704
|
+
context: mockContext,
|
|
705
|
+
weightedHistory: 'No history',
|
|
706
|
+
brandContext: {
|
|
707
|
+
brandVoice: 'bold and energetic',
|
|
708
|
+
targetAudience: 'gamers'
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
expect(messages.length).toBe(2);
|
|
712
|
+
expect(messages[0].content).toContain('copywriter');
|
|
713
|
+
expect(messages[1].content).toContain('bold and energetic');
|
|
714
|
+
expect(messages[1].content).toContain('gamers');
|
|
715
|
+
});
|
|
716
|
+
it('should use custom system prompt when provided', function () {
|
|
717
|
+
var messages = LuaPrompts.buildMessages('select', {
|
|
718
|
+
context: mockContext,
|
|
719
|
+
variants: mockTemplates
|
|
720
|
+
}, {
|
|
721
|
+
system: 'You are a custom AI.'
|
|
722
|
+
});
|
|
723
|
+
expect(messages[0].content).toBe('You are a custom AI.');
|
|
724
|
+
});
|
|
725
|
+
});
|
|
726
|
+
describe('buildSelectPrompt', function () {
|
|
727
|
+
it('should include all UTM parameters', function () {
|
|
728
|
+
var prompt = LuaPrompts.buildSelectPrompt({
|
|
729
|
+
context: {
|
|
730
|
+
utm: {
|
|
731
|
+
utm_source: 'google',
|
|
732
|
+
utm_medium: 'cpc',
|
|
733
|
+
utm_campaign: 'sale'
|
|
734
|
+
},
|
|
735
|
+
referrer: {
|
|
736
|
+
source: 'google',
|
|
737
|
+
category: 'search'
|
|
738
|
+
},
|
|
739
|
+
userAgent: {
|
|
740
|
+
isMobile: true,
|
|
741
|
+
isTablet: false,
|
|
742
|
+
isDesktop: false
|
|
743
|
+
},
|
|
744
|
+
hasUTM: true,
|
|
745
|
+
primaryIntent: 'price-focused'
|
|
746
|
+
},
|
|
747
|
+
weightedHistory: 'New visitor',
|
|
748
|
+
variants: mockTemplates
|
|
749
|
+
});
|
|
750
|
+
expect(prompt).toContain('google');
|
|
751
|
+
expect(prompt).toContain('cpc');
|
|
752
|
+
expect(prompt).toContain('sale');
|
|
753
|
+
expect(prompt).toContain('mobile');
|
|
754
|
+
expect(prompt).toContain('price-focused');
|
|
755
|
+
});
|
|
756
|
+
it('should list all variant keys', function () {
|
|
757
|
+
var prompt = LuaPrompts.buildSelectPrompt({
|
|
758
|
+
context: mockContext,
|
|
759
|
+
variants: mockTemplates
|
|
760
|
+
});
|
|
761
|
+
expect(prompt).toContain('"gaming"');
|
|
762
|
+
expect(prompt).toContain('"professional"');
|
|
763
|
+
expect(prompt).toContain('"default"');
|
|
764
|
+
});
|
|
765
|
+
it('should include preference scores when provided', function () {
|
|
766
|
+
var prompt = LuaPrompts.buildSelectPrompt({
|
|
767
|
+
context: mockContext,
|
|
768
|
+
variants: mockTemplates,
|
|
769
|
+
preferences: {
|
|
770
|
+
gaming: 1.5,
|
|
771
|
+
professional: 0.7
|
|
772
|
+
}
|
|
773
|
+
});
|
|
774
|
+
expect(prompt).toContain('PREFERENCE SCORES');
|
|
775
|
+
expect(prompt).toContain('gaming');
|
|
776
|
+
expect(prompt).toContain('1.500');
|
|
777
|
+
});
|
|
778
|
+
});
|
|
779
|
+
describe('buildGeneratePrompt', function () {
|
|
780
|
+
it('should include brand context fields', function () {
|
|
781
|
+
var prompt = LuaPrompts.buildGeneratePrompt({
|
|
782
|
+
context: mockContext,
|
|
783
|
+
brandContext: {
|
|
784
|
+
brandVoice: 'friendly and modern',
|
|
785
|
+
targetAudience: 'young professionals',
|
|
786
|
+
productType: 'tech accessories',
|
|
787
|
+
industry: 'e-commerce',
|
|
788
|
+
customField: 'custom value'
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
expect(prompt).toContain('friendly and modern');
|
|
792
|
+
expect(prompt).toContain('young professionals');
|
|
793
|
+
expect(prompt).toContain('tech accessories');
|
|
794
|
+
expect(prompt).toContain('e-commerce');
|
|
795
|
+
expect(prompt).toContain('custom value');
|
|
796
|
+
});
|
|
797
|
+
it('should include reference template when provided', function () {
|
|
798
|
+
var prompt = LuaPrompts.buildGeneratePrompt({
|
|
799
|
+
context: mockContext,
|
|
800
|
+
fallbackTemplate: {
|
|
801
|
+
headline: 'Default Headline',
|
|
802
|
+
subheadline: 'Default sub',
|
|
803
|
+
ctaLabel: 'Default CTA'
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
expect(prompt).toContain('Default Headline');
|
|
807
|
+
expect(prompt).toContain('REFERENCE TEMPLATE');
|
|
808
|
+
});
|
|
809
|
+
});
|
|
810
|
+
});
|
|
811
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJsb2NhbFN0b3JhZ2VNb2NrIiwic3RvcmUiLCJnZXRJdGVtIiwiamVzdCIsImZuIiwia2V5Iiwic2V0SXRlbSIsInZhbCIsIlN0cmluZyIsInJlbW92ZUl0ZW0iLCJjbGVhciIsImxlbmd0aCIsIk9iamVjdCIsImtleXMiLCJpIiwiZGVmaW5lUHJvcGVydHkiLCJnbG9iYWwiLCJ2YWx1ZSIsImdldFJhbmRvbVZhbHVlcyIsImJ1ZiIsIk1hdGgiLCJmbG9vciIsInJhbmRvbSIsImZldGNoIiwiQWJvcnRDb250cm9sbGVyIiwiX2NsYXNzIiwiX2NsYXNzQ2FsbENoZWNrMiIsImRlZmF1bHQiLCJzaWduYWwiLCJfY3JlYXRlQ2xhc3MyIiwiYWJvcnQiLCJyZXF1aXJlIiwiTHVhQUlQZXJzb25hbGl6ZSIsIkx1YVByb21wdHMiLCJMdWFXZWlnaHRlZEhpc3RvcnkiLCJtb2NrVGVtcGxhdGVzIiwiaGVhZGxpbmUiLCJzdWJoZWFkbGluZSIsImN0YUxhYmVsIiwiY3RhTGluayIsImltYWdlIiwibW9ja0NvbnRleHQiLCJ1dG0iLCJ1dG1fc291cmNlIiwidXRtX2NhbXBhaWduIiwicmVmZXJyZXIiLCJzb3VyY2UiLCJjYXRlZ29yeSIsInVybCIsInVzZXJBZ2VudCIsImlzTW9iaWxlIiwiaXNUYWJsZXQiLCJpc0Rlc2t0b3AiLCJyYXciLCJ0aW1lc3RhbXAiLCJEYXRlIiwibm93IiwiaGFzVVRNIiwicHJpbWFyeUludGVudCIsImJlZm9yZUVhY2giLCJjbGVhckFsbE1vY2tzIiwibW9ja1Jlc2V0IiwiZGVzY3JpYmUiLCJpdCIsImV4cGVjdCIsInRvQmVEZWZpbmVkIiwiX3R5cGVvZjIiLCJkZWNpZGUiLCJ0b0JlIiwibm9ybWFsaXplQ29uZmlnIiwicmVzdWx0IiwidmFsaWQiLCJlcnJvciIsInRvQ29udGFpbiIsImFwaUtleSIsInVzZURpcmVjdEFwaSIsImFwaVVybCIsIm1vZGVsIiwibW9kZSIsInRpbWVvdXQiLCJtYXhSZXRyaWVzIiwiZmFsbGJhY2tUb1N0YW5kYXJkIiwiY2FjaGVEZWNpc2lvbnMiLCJoaXN0b3J5RW5hYmxlZCIsImhpc3RvcnlEZWNheVJhdGUiLCJ0ZW1wZXJhdHVyZSIsIm1heFRva2VucyIsInZhbGlkYXRlU2VsZWN0UmVzcG9uc2UiLCJzZWxlY3RlZFZhcmlhbnQiLCJjb25maWRlbmNlIiwicmVhc29uaW5nIiwidmFsaWRhdGVHZW5lcmF0ZVJlc3BvbnNlIiwiX2FzeW5jVG9HZW5lcmF0b3IyIiwiX3JlZ2VuZXJhdG9yIiwibWFyayIsIl9jYWxsZWUiLCJkZWNpc2lvbiIsIndyYXAiLCJfY29udGV4dCIsInByZXYiLCJuZXh0IiwibW9ja1Jlc29sdmVkVmFsdWVPbmNlIiwib2siLCJqc29uIiwiUHJvbWlzZSIsInJlc29sdmUiLCJjaG9pY2VzIiwibWVzc2FnZSIsImNvbnRlbnQiLCJKU09OIiwic3RyaW5naWZ5IiwidGVtcGxhdGVzIiwiYWlDb25maWciLCJzZW50IiwiaW50ZW50IiwidGVtcGxhdGUiLCJhaVJlc3BvbnNlIiwic3RvcCIsIl9jYWxsZWUyIiwiX2NvbnRleHQyIiwidG9IYXZlQmVlbkNhbGxlZFdpdGgiLCJvYmplY3RDb250YWluaW5nIiwibWV0aG9kIiwiaGVhZGVycyIsIl9jYWxsZWUzIiwiX2NvbnRleHQzIiwiYW55IiwiX2NhbGxlZTQiLCJfY29udGV4dDQiLCJfY2FsbGVlNSIsIl9jb250ZXh0NSIsInJlamVjdHMiLCJ0b1Rocm93IiwiX2NhbGxlZTYiLCJfY29udGV4dDYiLCJzdGF0dXMiLCJ0ZXh0IiwiX2NhbGxlZTciLCJfY29udGV4dDciLCJfY2FsbGVlOCIsIl9jb250ZXh0OCIsIl9jYWxsZWU5IiwiZmlyc3QiLCJzZWNvbmQiLCJfY29udGV4dDkiLCJ0b0hhdmVCZWVuQ2FsbGVkVGltZXMiLCJfY2FsbGVlMCIsIl9jb250ZXh0MCIsImNsZWFyQ2FjaGUiLCJpc1JlYWR5IiwicmVhZHkiLCJidWlsZFNlbGVjdFByb21wdCIsImJ1aWxkR2VuZXJhdGVQcm9tcHQiLCJidWlsZE1lc3NhZ2VzIiwibWVzc2FnZXMiLCJjb250ZXh0Iiwid2VpZ2h0ZWRIaXN0b3J5IiwidmFyaWFudHMiLCJyb2xlIiwiYnJhbmRDb250ZXh0IiwiYnJhbmRWb2ljZSIsInRhcmdldEF1ZGllbmNlIiwic3lzdGVtIiwicHJvbXB0IiwidXRtX21lZGl1bSIsInByZWZlcmVuY2VzIiwiZ2FtaW5nIiwicHJvZmVzc2lvbmFsIiwicHJvZHVjdFR5cGUiLCJpbmR1c3RyeSIsImN1c3RvbUZpZWxkIiwiZmFsbGJhY2tUZW1wbGF0ZSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9fX3Rlc3RzX18vYWktcGVyc29uYWxpemUudGVzdC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogVGVzdHMgZm9yIEFJIFBlcnNvbmFsaXphdGlvbiBFbmdpbmVcbiAqIFRlc3RzIGNvbmZpZyB2YWxpZGF0aW9uLCBBUEkgY29tbXVuaWNhdGlvbiwgcmVzcG9uc2UgdmFsaWRhdGlvbiwgYW5kIGNhY2hpbmdcbiAqL1xuXG4vLyBNb2NrIGxvY2FsU3RvcmFnZVxuY29uc3QgbG9jYWxTdG9yYWdlTW9jayA9IChmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHN0b3JlID0ge31cbiAgICByZXR1cm4ge1xuICAgICAgICBnZXRJdGVtOiBqZXN0LmZuKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIHN0b3JlW2tleV0gfHwgbnVsbCB9KSxcbiAgICAgICAgc2V0SXRlbTogamVzdC5mbihmdW5jdGlvbiAoa2V5LCB2YWwpIHsgc3RvcmVba2V5XSA9IFN0cmluZyh2YWwpIH0pLFxuICAgICAgICByZW1vdmVJdGVtOiBqZXN0LmZuKGZ1bmN0aW9uIChrZXkpIHsgZGVsZXRlIHN0b3JlW2tleV0gfSksXG4gICAgICAgIGNsZWFyOiBqZXN0LmZuKGZ1bmN0aW9uICgpIHsgc3RvcmUgPSB7fSB9KSxcbiAgICAgICAgZ2V0IGxlbmd0aCgpIHsgcmV0dXJuIE9iamVjdC5rZXlzKHN0b3JlKS5sZW5ndGggfSxcbiAgICAgICAga2V5OiBqZXN0LmZuKGZ1bmN0aW9uIChpKSB7IHJldHVybiBPYmplY3Qua2V5cyhzdG9yZSlbaV0gfHwgbnVsbCB9KVxuICAgIH1cbn0pKClcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbCwgJ2xvY2FsU3RvcmFnZScsIHsgdmFsdWU6IGxvY2FsU3RvcmFnZU1vY2sgfSlcblxuLy8gTW9jayBjcnlwdG9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWwsICdjcnlwdG8nLCB7XG4gICAgdmFsdWU6IHtcbiAgICAgICAgZ2V0UmFuZG9tVmFsdWVzOiBmdW5jdGlvbiAoYnVmKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zi5sZW5ndGg7IGkrKykgYnVmW2ldID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjU2KVxuICAgICAgICAgICAgcmV0dXJuIGJ1ZlxuICAgICAgICB9XG4gICAgfVxufSlcblxuLy8gTW9jayBmZXRjaFxuZ2xvYmFsLmZldGNoID0gamVzdC5mbigpXG5nbG9iYWwuQWJvcnRDb250cm9sbGVyID0gY2xhc3Mge1xuICAgIGNvbnN0cnVjdG9yKCkgeyB0aGlzLnNpZ25hbCA9IHt9IH1cbiAgICBhYm9ydCgpIHt9XG59XG5cbi8vIExvYWQgbW9kdWxlcyBpbiBvcmRlciAoZGVwZW5kZW5jaWVzIGZpcnN0KVxucmVxdWlyZSgnLi4vc3RvcmFnZS93ZWlnaHRlZC1oaXN0b3J5JylcbnJlcXVpcmUoJy4uL3Byb21wdHMvcGVyc29uYWxpemF0aW9uLXByb21wdHMnKVxucmVxdWlyZSgnLi4vYWktcGVyc29uYWxpemUnKVxuXG5jb25zdCBMdWFBSVBlcnNvbmFsaXplID0gZ2xvYmFsLkx1YUFJUGVyc29uYWxpemVcbmNvbnN0IEx1YVByb21wdHMgPSBnbG9iYWwuTHVhUHJvbXB0c1xuY29uc3QgTHVhV2VpZ2h0ZWRIaXN0b3J5ID0gZ2xvYmFsLkx1YVdlaWdodGVkSGlzdG9yeVxuXG5jb25zdCBtb2NrVGVtcGxhdGVzID0ge1xuICAgICdnYW1pbmcnOiB7XG4gICAgICAgIGhlYWRsaW5lOiAnTGV2ZWwgVXAgWW91ciBTZXR1cCcsXG4gICAgICAgIHN1YmhlYWRsaW5lOiAnUHJvIGdlYXIgZm9yIHNlcmlvdXMgZ2FtZXJzLicsXG4gICAgICAgIGN0YUxhYmVsOiAnRXhwbG9yZSBHYW1pbmcnLFxuICAgICAgICBjdGFMaW5rOiAnL2dhbWluZycsXG4gICAgICAgIGltYWdlOiAnZ2FtaW5nLmpwZydcbiAgICB9LFxuICAgICdwcm9mZXNzaW9uYWwnOiB7XG4gICAgICAgIGhlYWRsaW5lOiAnV29yayBTbWFydGVyJyxcbiAgICAgICAgc3ViaGVhZGxpbmU6ICdQcmVtaXVtIHByb2R1Y3Rpdml0eSB0b29scy4nLFxuICAgICAgICBjdGFMYWJlbDogJ1ZpZXcgQ29sbGVjdGlvbicsXG4gICAgICAgIGN0YUxpbms6ICcvcHJvZmVzc2lvbmFsJyxcbiAgICAgICAgaW1hZ2U6ICdwcm8uanBnJ1xuICAgIH0sXG4gICAgJ2RlZmF1bHQnOiB7XG4gICAgICAgIGhlYWRsaW5lOiAnV2VsY29tZScsXG4gICAgICAgIHN1YmhlYWRsaW5lOiAnRGlzY292ZXIgcHJvZHVjdHMuJyxcbiAgICAgICAgY3RhTGFiZWw6ICdTaG9wIE5vdycsXG4gICAgICAgIGN0YUxpbms6ICcvc2hvcCcsXG4gICAgICAgIGltYWdlOiAnZGVmYXVsdC5qcGcnXG4gICAgfVxufVxuXG5jb25zdCBtb2NrQ29udGV4dCA9IHtcbiAgICB1dG06IHsgdXRtX3NvdXJjZTogJ3JlZGRpdCcsIHV0bV9jYW1wYWlnbjogJ2dhbWluZ19jb25zb2xlJyB9LFxuICAgIHJlZmVycmVyOiB7IHNvdXJjZTogJ3JlZGRpdCcsIGNhdGVnb3J5OiAnc29jaWFsJywgdXJsOiAnaHR0cHM6Ly9yZWRkaXQuY29tJyB9LFxuICAgIHVzZXJBZ2VudDogeyBpc01vYmlsZTogZmFsc2UsIGlzVGFibGV0OiBmYWxzZSwgaXNEZXNrdG9wOiB0cnVlLCByYXc6ICcnIH0sXG4gICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgIGhhc1VUTTogdHJ1ZSxcbiAgICBwcmltYXJ5SW50ZW50OiAnZ2FtaW5nJ1xufVxuXG5iZWZvcmVFYWNoKCgpID0+IHtcbiAgICBsb2NhbFN0b3JhZ2VNb2NrLmNsZWFyKClcbiAgICBqZXN0LmNsZWFyQWxsTW9ja3MoKVxuICAgIGdsb2JhbC5mZXRjaC5tb2NrUmVzZXQoKVxufSlcblxuZGVzY3JpYmUoJ0x1YUFJUGVyc29uYWxpemUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBiZSByZWdpc3RlcmVkIG9uIGdsb2JhbCcsICgpID0+IHtcbiAgICAgICAgZXhwZWN0KEx1YUFJUGVyc29uYWxpemUpLnRvQmVEZWZpbmVkKClcbiAgICAgICAgZXhwZWN0KHR5cGVvZiBMdWFBSVBlcnNvbmFsaXplLmRlY2lkZSkudG9CZSgnZnVuY3Rpb24nKVxuICAgICAgICBleHBlY3QodHlwZW9mIEx1YUFJUGVyc29uYWxpemUubm9ybWFsaXplQ29uZmlnKS50b0JlKCdmdW5jdGlvbicpXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdub3JtYWxpemVDb25maWcnLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IG51bGwgY29uZmlnJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhQUlQZXJzb25hbGl6ZS5ub3JtYWxpemVDb25maWcobnVsbClcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgY29uZmlnIHdpdGhvdXQgYXBpS2V5IG9yIGFwaVVybCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IEx1YUFJUGVyc29uYWxpemUubm9ybWFsaXplQ29uZmlnKHt9KVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZShmYWxzZSlcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQuZXJyb3IpLnRvQ29udGFpbignYXBpS2V5JylcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIGFjY2VwdCBjb25maWcgd2l0aCBhcGlLZXknLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBMdWFBSVBlcnNvbmFsaXplLm5vcm1hbGl6ZUNvbmZpZyh7IGFwaUtleTogJ3NrLXRlc3QxMjMnIH0pXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKHRydWUpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0LnVzZURpcmVjdEFwaSkudG9CZSh0cnVlKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC5hcGlLZXkpLnRvQmUoJ3NrLXRlc3QxMjMnKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgYWNjZXB0IGNvbmZpZyB3aXRoIGFwaVVybCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IEx1YUFJUGVyc29uYWxpemUubm9ybWFsaXplQ29uZmlnKHsgYXBpVXJsOiAnaHR0cHM6Ly9wcm94eS5leGFtcGxlLmNvbS9hcGknIH0pXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKHRydWUpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0LnVzZURpcmVjdEFwaSkudG9CZShmYWxzZSlcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQuYXBpVXJsKS50b0JlKCdodHRwczovL3Byb3h5LmV4YW1wbGUuY29tL2FwaScpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCBhcHBseSBkZWZhdWx0cyBmb3IgbWlzc2luZyBmaWVsZHMnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBMdWFBSVBlcnNvbmFsaXplLm5vcm1hbGl6ZUNvbmZpZyh7IGFwaUtleTogJ3NrLXRlc3QnIH0pXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0Lm1vZGVsKS50b0JlKCdncHQtNG8tbWluaScpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0Lm1vZGUpLnRvQmUoJ3NlbGVjdCcpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0LnRpbWVvdXQpLnRvQmUoNTAwMClcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQubWF4UmV0cmllcykudG9CZSgxKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC5mYWxsYmFja1RvU3RhbmRhcmQpLnRvQmUodHJ1ZSlcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQuY2FjaGVEZWNpc2lvbnMpLnRvQmUodHJ1ZSlcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQuaGlzdG9yeUVuYWJsZWQpLnRvQmUodHJ1ZSlcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQuaGlzdG9yeURlY2F5UmF0ZSkudG9CZSgwLjkpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCB1c2UgY3VzdG9tIHZhbHVlcyB3aGVuIHByb3ZpZGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhQUlQZXJzb25hbGl6ZS5ub3JtYWxpemVDb25maWcoe1xuICAgICAgICAgICAgICAgIGFwaUtleTogJ3NrLXRlc3QnLFxuICAgICAgICAgICAgICAgIG1vZGVsOiAnZ3B0LTRvJyxcbiAgICAgICAgICAgICAgICBtb2RlOiAnZ2VuZXJhdGUnLFxuICAgICAgICAgICAgICAgIHRpbWVvdXQ6IDEwMDAwLFxuICAgICAgICAgICAgICAgIHRlbXBlcmF0dXJlOiAwLjUsXG4gICAgICAgICAgICAgICAgbWF4VG9rZW5zOiAxMDAwXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC5tb2RlbCkudG9CZSgnZ3B0LTRvJylcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQubW9kZSkudG9CZSgnZ2VuZXJhdGUnKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC50aW1lb3V0KS50b0JlKDEwMDAwKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC50ZW1wZXJhdHVyZSkudG9CZSgwLjUpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0Lm1heFRva2VucykudG9CZSgxMDAwKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgcHJlZmVyIGFwaVVybCBvdmVyIGRpcmVjdCB3aGVuIGJvdGggcHJvdmlkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBMdWFBSVBlcnNvbmFsaXplLm5vcm1hbGl6ZUNvbmZpZyh7XG4gICAgICAgICAgICAgICAgYXBpS2V5OiAnc2stdGVzdCcsXG4gICAgICAgICAgICAgICAgYXBpVXJsOiAnaHR0cHM6Ly9wcm94eS5jb20vYXBpJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQudXNlRGlyZWN0QXBpKS50b0JlKGZhbHNlKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC5hcGlVcmwpLnRvQmUoJ2h0dHBzOi8vcHJveHkuY29tL2FwaScpXG4gICAgICAgIH0pXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCd2YWxpZGF0ZVNlbGVjdFJlc3BvbnNlJywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIGFjY2VwdCB2YWxpZCBzZWxlY3Rpb24gcmVzcG9uc2UnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBMdWFBSVBlcnNvbmFsaXplLnZhbGlkYXRlU2VsZWN0UmVzcG9uc2UoXG4gICAgICAgICAgICAgICAgeyBzZWxlY3RlZFZhcmlhbnQ6ICdnYW1pbmcnLCBjb25maWRlbmNlOiAwLjksIHJlYXNvbmluZzogJ3Rlc3QnIH0sXG4gICAgICAgICAgICAgICAgbW9ja1RlbXBsYXRlc1xuICAgICAgICAgICAgKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IG1pc3Npbmcgc2VsZWN0ZWRWYXJpYW50JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhQUlQZXJzb25hbGl6ZS52YWxpZGF0ZVNlbGVjdFJlc3BvbnNlKFxuICAgICAgICAgICAgICAgIHsgY29uZmlkZW5jZTogMC45IH0sXG4gICAgICAgICAgICAgICAgbW9ja1RlbXBsYXRlc1xuICAgICAgICAgICAgKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZShmYWxzZSlcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBub24tZXhpc3RlbnQgdmFyaWFudCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IEx1YUFJUGVyc29uYWxpemUudmFsaWRhdGVTZWxlY3RSZXNwb25zZShcbiAgICAgICAgICAgICAgICB7IHNlbGVjdGVkVmFyaWFudDogJ25vbmV4aXN0ZW50JyB9LFxuICAgICAgICAgICAgICAgIG1vY2tUZW1wbGF0ZXNcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0LmVycm9yKS50b0NvbnRhaW4oJ25vbmV4aXN0ZW50JylcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBudWxsIHJlc3BvbnNlJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhQUlQZXJzb25hbGl6ZS52YWxpZGF0ZVNlbGVjdFJlc3BvbnNlKG51bGwsIG1vY2tUZW1wbGF0ZXMpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKGZhbHNlKVxuICAgICAgICB9KVxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgndmFsaWRhdGVHZW5lcmF0ZVJlc3BvbnNlJywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIGFjY2VwdCB2YWxpZCBnZW5lcmF0aW9uIHJlc3BvbnNlJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhQUlQZXJzb25hbGl6ZS52YWxpZGF0ZUdlbmVyYXRlUmVzcG9uc2Uoe1xuICAgICAgICAgICAgICAgIGhlYWRsaW5lOiAnVGVzdCBIZWFkbGluZScsXG4gICAgICAgICAgICAgICAgc3ViaGVhZGxpbmU6ICdUZXN0IHN1YmhlYWRsaW5lIGhlcmUnLFxuICAgICAgICAgICAgICAgIGN0YUxhYmVsOiAnQ2xpY2sgTWUnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IG1pc3NpbmcgaGVhZGxpbmUnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBMdWFBSVBlcnNvbmFsaXplLnZhbGlkYXRlR2VuZXJhdGVSZXNwb25zZSh7XG4gICAgICAgICAgICAgICAgc3ViaGVhZGxpbmU6ICdUZXN0JyxcbiAgICAgICAgICAgICAgICBjdGFMYWJlbDogJ0NsaWNrJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0LmVycm9yKS50b0NvbnRhaW4oJ2hlYWRsaW5lJylcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBtaXNzaW5nIHN1YmhlYWRsaW5lJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhQUlQZXJzb25hbGl6ZS52YWxpZGF0ZUdlbmVyYXRlUmVzcG9uc2Uoe1xuICAgICAgICAgICAgICAgIGhlYWRsaW5lOiAnVGVzdCcsXG4gICAgICAgICAgICAgICAgY3RhTGFiZWw6ICdDbGljaydcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKGZhbHNlKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IG1pc3NpbmcgY3RhTGFiZWwnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBMdWFBSVBlcnNvbmFsaXplLnZhbGlkYXRlR2VuZXJhdGVSZXNwb25zZSh7XG4gICAgICAgICAgICAgICAgaGVhZGxpbmU6ICdUZXN0JyxcbiAgICAgICAgICAgICAgICBzdWJoZWFkbGluZTogJ1N1YidcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKGZhbHNlKVxuICAgICAgICB9KVxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnZGVjaWRlIChzZWxlY3QgbW9kZSknLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgY2FsbCBPcGVuQUkgYW5kIHJldHVybiBhIHZhbGlkIGRlY2lzaW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgZ2xvYmFsLmZldGNoLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICAgICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgICAgICAganNvbjogKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgY2hvaWNlczogW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkVmFyaWFudDogJ2dhbWluZycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZGVuY2U6IDAuOTIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbmluZzogJ1VzZXIgY2FtZSBmcm9tIFJlZGRpdCB3aXRoIGdhbWluZyBjb25zb2xlIGNhbXBhaWduJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1dXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGNvbnN0IGRlY2lzaW9uID0gYXdhaXQgTHVhQUlQZXJzb25hbGl6ZS5kZWNpZGUobW9ja0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZXM6IG1vY2tUZW1wbGF0ZXMsXG4gICAgICAgICAgICAgICAgYWlDb25maWc6IHsgYXBpS2V5OiAnc2stdGVzdCcsIG1vZGU6ICdzZWxlY3QnLCBjYWNoZURlY2lzaW9uczogZmFsc2UsIGhpc3RvcnlFbmFibGVkOiBmYWxzZSB9XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBleHBlY3QoZGVjaXNpb24uaW50ZW50KS50b0JlKCdnYW1pbmcnKVxuICAgICAgICAgICAgZXhwZWN0KGRlY2lzaW9uLnNvdXJjZSkudG9CZSgnYWknKVxuICAgICAgICAgICAgZXhwZWN0KGRlY2lzaW9uLnRlbXBsYXRlKS50b0JlKG1vY2tUZW1wbGF0ZXNbJ2dhbWluZyddKVxuICAgICAgICAgICAgZXhwZWN0KGRlY2lzaW9uLmFpUmVzcG9uc2UuY29uZmlkZW5jZSkudG9CZSgwLjkyKVxuICAgICAgICAgICAgZXhwZWN0KGRlY2lzaW9uLmFpUmVzcG9uc2UubW9kZWwpLnRvQmUoJ2dwdC00by1taW5pJylcbiAgICAgICAgICAgIGV4cGVjdChkZWNpc2lvbi5haVJlc3BvbnNlLm1vZGUpLnRvQmUoJ3NlbGVjdCcpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCBpbmNsdWRlIEF1dGhvcml6YXRpb24gaGVhZGVyIGZvciBkaXJlY3QgQVBJJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgZ2xvYmFsLmZldGNoLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICAgICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgICAgICAganNvbjogKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgY2hvaWNlczogW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IHsgY29udGVudDogSlNPTi5zdHJpbmdpZnkoeyBzZWxlY3RlZFZhcmlhbnQ6ICdnYW1pbmcnLCBjb25maWRlbmNlOiAwLjgsIHJlYXNvbmluZzogJ3Rlc3QnIH0pIH1cbiAgICAgICAgICAgICAgICAgICAgfV1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgYXdhaXQgTHVhQUlQZXJzb25hbGl6ZS5kZWNpZGUobW9ja0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZXM6IG1vY2tUZW1wbGF0ZXMsXG4gICAgICAgICAgICAgICAgYWlDb25maWc6IHsgYXBpS2V5OiAnc2stbXlrZXkxMjMnLCBtb2RlOiAnc2VsZWN0JywgY2FjaGVEZWNpc2lvbnM6IGZhbHNlLCBoaXN0b3J5RW5hYmxlZDogZmFsc2UgfVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZXhwZWN0KGdsb2JhbC5mZXRjaCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICAgICAgICAgICAgJ2h0dHBzOi8vYXBpLm9wZW5haS5jb20vdjEvY2hhdC9jb21wbGV0aW9ucycsXG4gICAgICAgICAgICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICAgICAgICAgICAgICAgICAgJ0F1dGhvcml6YXRpb24nOiAnQmVhcmVyIHNrLW15a2V5MTIzJ1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCB1c2UgcHJveHkgVVJMIHdoZW4gYXBpVXJsIGlzIHByb3ZpZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgZ2xvYmFsLmZldGNoLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICAgICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgICAgICAganNvbjogKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgY2hvaWNlczogW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IHsgY29udGVudDogSlNPTi5zdHJpbmdpZnkoeyBzZWxlY3RlZFZhcmlhbnQ6ICdnYW1pbmcnLCBjb25maWRlbmNlOiAwLjgsIHJlYXNvbmluZzogJ3Rlc3QnIH0pIH1cbiAgICAgICAgICAgICAgICAgICAgfV1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgYXdhaXQgTHVhQUlQZXJzb25hbGl6ZS5kZWNpZGUobW9ja0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZXM6IG1vY2tUZW1wbGF0ZXMsXG4gICAgICAgICAgICAgICAgYWlDb25maWc6IHsgYXBpVXJsOiAnaHR0cHM6Ly9teXByb3h5LmNvbS9vcGVuYWknLCBtb2RlOiAnc2VsZWN0JywgY2FjaGVEZWNpc2lvbnM6IGZhbHNlLCBoaXN0b3J5RW5hYmxlZDogZmFsc2UgfVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZXhwZWN0KGdsb2JhbC5mZXRjaCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICAgICAgICAgICAgJ2h0dHBzOi8vbXlwcm94eS5jb20vb3BlbmFpJyxcbiAgICAgICAgICAgICAgICBleHBlY3QuYW55KE9iamVjdClcbiAgICAgICAgICAgIClcbiAgICAgICAgfSlcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2RlY2lkZSAoZ2VuZXJhdGUgbW9kZSknLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgY2FsbCBPcGVuQUkgYW5kIHJldHVybiBnZW5lcmF0ZWQgY29udGVudCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGdsb2JhbC5mZXRjaC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgICAgICAgICAgIG9rOiB0cnVlLFxuICAgICAgICAgICAgICAgIGpzb246ICgpID0+IFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIGNob2ljZXM6IFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkbGluZTogJ0dhbWUgT24sIEdlYXIgVXAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJoZWFkbGluZTogJ1RoZSB1bHRpbWF0ZSBnYW1pbmcgc2V0dXAgYXdhaXRzIHlvdS4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdGFMYWJlbDogJ0xldmVsIFVwJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlkZW5jZTogMC44OCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhc29uaW5nOiAnR2FtZXIgZnJvbSBSZWRkaXQnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfV1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgY29uc3QgZGVjaXNpb24gPSBhd2FpdCBMdWFBSVBlcnNvbmFsaXplLmRlY2lkZShtb2NrQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlczogbW9ja1RlbXBsYXRlcyxcbiAgICAgICAgICAgICAgICBhaUNvbmZpZzoge1xuICAgICAgICAgICAgICAgICAgICBhcGlLZXk6ICdzay10ZXN0JyxcbiAgICAgICAgICAgICAgICAgICAgbW9kZTogJ2dlbmVyYXRlJyxcbiAgICAgICAgICAgICAgICAgICAgY2FjaGVEZWNpc2lvbnM6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBoaXN0b3J5RW5hYmxlZDogZmFsc2VcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBleHBlY3QoZGVjaXNpb24uaW50ZW50KS50b0JlKCdhaS1nZW5lcmF0ZWQnKVxuICAgICAgICAgICAgZXhwZWN0KGRlY2lzaW9uLnNvdXJjZSkudG9CZSgnYWknKVxuICAgICAgICAgICAgZXhwZWN0KGRlY2lzaW9uLnRlbXBsYXRlLmhlYWRsaW5lKS50b0JlKCdHYW1lIE9uLCBHZWFyIFVwJylcbiAgICAgICAgICAgIGV4cGVjdChkZWNpc2lvbi50ZW1wbGF0ZS5zdWJoZWFkbGluZSkudG9CZSgnVGhlIHVsdGltYXRlIGdhbWluZyBzZXR1cCBhd2FpdHMgeW91LicpXG4gICAgICAgICAgICBleHBlY3QoZGVjaXNpb24udGVtcGxhdGUuY3RhTGFiZWwpLnRvQmUoJ0xldmVsIFVwJylcbiAgICAgICAgICAgIGV4cGVjdChkZWNpc2lvbi5haVJlc3BvbnNlLm1vZGUpLnRvQmUoJ2dlbmVyYXRlJylcbiAgICAgICAgfSlcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2Vycm9yIGhhbmRsaW5nJywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCB3aXRoIGVycm9yIGZvciBpbnZhbGlkIGNvbmZpZycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGV4cGVjdChMdWFBSVBlcnNvbmFsaXplLmRlY2lkZShtb2NrQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlczogbW9ja1RlbXBsYXRlcyxcbiAgICAgICAgICAgICAgICBhaUNvbmZpZzoge31cbiAgICAgICAgICAgIH0pKS5yZWplY3RzLnRvVGhyb3coJ2FwaUtleScpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3Qgb24gQVBJIGVycm9yJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgZ2xvYmFsLmZldGNoLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICAgICAgICAgICAgb2s6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHN0YXR1czogNDAxLFxuICAgICAgICAgICAgICAgIHRleHQ6ICgpID0+IFByb21pc2UucmVzb2x2ZSgnVW5hdXRob3JpemVkJylcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGF3YWl0IGV4cGVjdChMdWFBSVBlcnNvbmFsaXplLmRlY2lkZShtb2NrQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlczogbW9ja1RlbXBsYXRlcyxcbiAgICAgICAgICAgICAgICBhaUNvbmZpZzogeyBhcGlLZXk6ICdzay1iYWQnLCBjYWNoZURlY2lzaW9uczogZmFsc2UsIGhpc3RvcnlFbmFibGVkOiBmYWxzZSwgbWF4UmV0cmllczogMCB9XG4gICAgICAgICAgICB9KSkucmVqZWN0cy50b1Rocm93KCc0MDEnKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IG9uIGludmFsaWQgSlNPTiByZXNwb25zZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGdsb2JhbC5mZXRjaC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgICAgICAgICAgIG9rOiB0cnVlLFxuICAgICAgICAgICAgICAgIGpzb246ICgpID0+IFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIGNob2ljZXM6IFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiB7IGNvbnRlbnQ6ICd0aGlzIGlzIG5vdCBqc29uJyB9XG4gICAgICAgICAgICAgICAgICAgIH1dXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGF3YWl0IGV4cGVjdChMdWFBSVBlcnNvbmFsaXplLmRlY2lkZShtb2NrQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlczogbW9ja1RlbXBsYXRlcyxcbiAgICAgICAgICAgICAgICBhaUNvbmZpZzogeyBhcGlLZXk6ICdzay10ZXN0JywgY2FjaGVEZWNpc2lvbnM6IGZhbHNlLCBoaXN0b3J5RW5hYmxlZDogZmFsc2UsIG1heFJldHJpZXM6IDAgfVxuICAgICAgICAgICAgfSkpLnJlamVjdHMudG9UaHJvdygpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3Qgb24gaW52YWxpZCBzZWxlY3Rpb24gKG5vbmV4aXN0ZW50IHZhcmlhbnQpJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgZ2xvYmFsLmZldGNoLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICAgICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgICAgICAganNvbjogKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgY2hvaWNlczogW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IHsgY29udGVudDogSlNPTi5zdHJpbmdpZnkoeyBzZWxlY3RlZFZhcmlhbnQ6ICdmYWtlJywgY29uZmlkZW5jZTogMC41LCByZWFzb25pbmc6ICdvb3BzJyB9KSB9XG4gICAgICAgICAgICAgICAgICAgIH1dXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGF3YWl0IGV4cGVjdChMdWFBSVBlcnNvbmFsaXplLmRlY2lkZShtb2NrQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlczogbW9ja1RlbXBsYXRlcyxcbiAgICAgICAgICAgICAgICBhaUNvbmZpZzogeyBhcGlLZXk6ICdzay10ZXN0JywgY2FjaGVEZWNpc2lvbnM6IGZhbHNlLCBoaXN0b3J5RW5hYmxlZDogZmFsc2UsIG1heFJldHJpZXM6IDAgfVxuICAgICAgICAgICAgfSkpLnJlamVjdHMudG9UaHJvdygnZG9lcyBub3QgZXhpc3QnKVxuICAgICAgICB9KVxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnY2FjaGluZycsICgpID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCBjYWNoZSBhIGRlY2lzaW9uIGFuZCByZXR1cm4gaXQgb24gc3Vic2VxdWVudCBjYWxscycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGdsb2JhbC5mZXRjaC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2Uoe1xuICAgICAgICAgICAgICAgIG9rOiB0cnVlLFxuICAgICAgICAgICAgICAgIGpzb246ICgpID0+IFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIGNob2ljZXM6IFt7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiB7IGNvbnRlbnQ6IEpTT04uc3RyaW5naWZ5KHsgc2VsZWN0ZWRWYXJpYW50OiAnZ2FtaW5nJywgY29uZmlkZW5jZTogMC45LCByZWFzb25pbmc6ICd0ZXN0JyB9KSB9XG4gICAgICAgICAgICAgICAgICAgIH1dXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIC8vIEZpcnN0IGNhbGwgLSBoaXRzIEFQSVxuICAgICAgICAgICAgY29uc3QgZmlyc3QgPSBhd2FpdCBMdWFBSVBlcnNvbmFsaXplLmRlY2lkZShtb2NrQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlczogbW9ja1RlbXBsYXRlcyxcbiAgICAgICAgICAgICAgICBhaUNvbmZpZzogeyBhcGlLZXk6ICdzay10ZXN0JywgY2FjaGVEZWNpc2lvbnM6IHRydWUsIGhpc3RvcnlFbmFibGVkOiBmYWxzZSB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgZXhwZWN0KGZpcnN0LnNvdXJjZSkudG9CZSgnYWknKVxuICAgICAgICAgICAgZXhwZWN0KGdsb2JhbC5mZXRjaCkudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpXG5cbiAgICAgICAgICAgIC8vIFNlY29uZCBjYWxsIC0gc2hvdWxkIHVzZSBjYWNoZVxuICAgICAgICAgICAgY29uc3Qgc2Vjb25kID0gYXdhaXQgTHVhQUlQZXJzb25hbGl6ZS5kZWNpZGUobW9ja0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZXM6IG1vY2tUZW1wbGF0ZXMsXG4gICAgICAgICAgICAgICAgYWlDb25maWc6IHsgYXBpS2V5OiAnc2stdGVzdCcsIGNhY2hlRGVjaXNpb25zOiB0cnVlLCBoaXN0b3J5RW5hYmxlZDogZmFsc2UgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGV4cGVjdChzZWNvbmQuc291cmNlKS50b0JlKCdhaS1jYWNoZWQnKVxuICAgICAgICAgICAgZXhwZWN0KGdsb2JhbC5mZXRjaCkudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpIC8vIE5vIG5ldyBmZXRjaCBjYWxsXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ2NsZWFyQ2FjaGUgc2hvdWxkIHJlbW92ZSBhbGwgY2FjaGVkIGRlY2lzaW9ucycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIC8vIFN0b3JlIHNvbWV0aGluZyBpbiBjYWNoZVxuICAgICAgICAgICAgZ2xvYmFsLmZldGNoLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7XG4gICAgICAgICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgICAgICAganNvbjogKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgY2hvaWNlczogW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IHsgY29udGVudDogSlNPTi5zdHJpbmdpZnkoeyBzZWxlY3RlZFZhcmlhbnQ6ICdnYW1pbmcnLCBjb25maWRlbmNlOiAwLjksIHJlYXNvbmluZzogJ3Rlc3QnIH0pIH1cbiAgICAgICAgICAgICAgICAgICAgfV1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgYXdhaXQgTHVhQUlQZXJzb25hbGl6ZS5kZWNpZGUobW9ja0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZXM6IG1vY2tUZW1wbGF0ZXMsXG4gICAgICAgICAgICAgICAgYWlDb25maWc6IHsgYXBpS2V5OiAnc2stdGVzdCcsIGNhY2hlRGVjaXNpb25zOiB0cnVlLCBoaXN0b3J5RW5hYmxlZDogZmFsc2UgfVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgTHVhQUlQZXJzb25hbGl6ZS5jbGVhckNhY2hlKClcblxuICAgICAgICAgICAgLy8gTmV4dCBjYWxsIHNob3VsZCBoaXQgQVBJIGFnYWluXG4gICAgICAgICAgICBnbG9iYWwuZmV0Y2gubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHtcbiAgICAgICAgICAgICAgICBvazogdHJ1ZSxcbiAgICAgICAgICAgICAgICBqc29uOiAoKSA9PiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICBjaG9pY2VzOiBbe1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogeyBjb250ZW50OiBKU09OLnN0cmluZ2lmeSh7IHNlbGVjdGVkVmFyaWFudDogJ3Byb2Zlc3Npb25hbCcsIGNvbmZpZGVuY2U6IDAuOCwgcmVhc29uaW5nOiAnY2xlYXJlZCcgfSkgfVxuICAgICAgICAgICAgICAgICAgICB9XVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBMdWFBSVBlcnNvbmFsaXplLmRlY2lkZShtb2NrQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlczogbW9ja1RlbXBsYXRlcyxcbiAgICAgICAgICAgICAgICBhaUNvbmZpZzogeyBhcGlLZXk6ICdzay10ZXN0JywgY2FjaGVEZWNpc2lvbnM6IHRydWUsIGhpc3RvcnlFbmFibGVkOiBmYWxzZSB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC5zb3VyY2UpLnRvQmUoJ2FpJylcbiAgICAgICAgICAgIGV4cGVjdChnbG9iYWwuZmV0Y2gpLnRvSGF2ZUJlZW5DYWxsZWRUaW1lcygyKVxuICAgICAgICB9KVxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnaXNSZWFkeScsICgpID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gcmVhZHkgZm9yIHZhbGlkIGNvbmZpZyB3aXRoIG1vZHVsZXMgbG9hZGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhQUlQZXJzb25hbGl6ZS5pc1JlYWR5KHsgYXBpS2V5OiAnc2stdGVzdCcgfSlcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQucmVhZHkpLnRvQmUodHJ1ZSlcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBub3QgcmVhZHkgZm9yIGludmFsaWQgY29uZmlnJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhQUlQZXJzb25hbGl6ZS5pc1JlYWR5KHt9KVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC5yZWFkeSkudG9CZShmYWxzZSlcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQuZXJyb3IpLnRvQmVEZWZpbmVkKClcbiAgICAgICAgfSlcbiAgICB9KVxufSlcblxuZGVzY3JpYmUoJ0x1YVByb21wdHMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBiZSByZWdpc3RlcmVkIG9uIGdsb2JhbCcsICgpID0+IHtcbiAgICAgICAgZXhwZWN0KEx1YVByb21wdHMpLnRvQmVEZWZpbmVkKClcbiAgICAgICAgZXhwZWN0KHR5cGVvZiBMdWFQcm9tcHRzLmJ1aWxkU2VsZWN0UHJvbXB0KS50b0JlKCdmdW5jdGlvbicpXG4gICAgICAgIGV4cGVjdCh0eXBlb2YgTHVhUHJvbXB0cy5idWlsZEdlbmVyYXRlUHJvbXB0KS50b0JlKCdmdW5jdGlvbicpXG4gICAgICAgIGV4cGVjdCh0eXBlb2YgTHVhUHJvbXB0cy5idWlsZE1lc3NhZ2VzKS50b0JlKCdmdW5jdGlvbicpXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdidWlsZE1lc3NhZ2VzJywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIGJ1aWxkIHNlbGVjdCBtb2RlIG1lc3NhZ2VzJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZXMgPSBMdWFQcm9tcHRzLmJ1aWxkTWVzc2FnZXMoJ3NlbGVjdCcsIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiBtb2NrQ29udGV4dCxcbiAgICAgICAgICAgICAgICB3ZWlnaHRlZEhpc3Rvcnk6ICdObyBoaXN0b3J5JyxcbiAgICAgICAgICAgICAgICB2YXJpYW50czogbW9ja1RlbXBsYXRlc1xuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZXhwZWN0KG1lc3NhZ2VzLmxlbmd0aCkudG9CZSgyKVxuICAgICAgICAgICAgZXhwZWN0KG1lc3NhZ2VzWzBdLnJvbGUpLnRvQmUoJ3N5c3RlbScpXG4gICAgICAgICAgICBleHBlY3QobWVzc2FnZXNbMV0ucm9sZSkudG9CZSgndXNlcicpXG4gICAgICAgICAgICBleHBlY3QobWVzc2FnZXNbMF0uY29udGVudCkudG9Db250YWluKCdwZXJzb25hbGl6YXRpb24nKVxuICAgICAgICAgICAgZXhwZWN0KG1lc3NhZ2VzWzFdLmNvbnRlbnQpLnRvQ29udGFpbigncmVkZGl0JylcbiAgICAgICAgICAgIGV4cGVjdChtZXNzYWdlc1sxXS5jb250ZW50KS50b0NvbnRhaW4oJ2dhbWluZycpXG4gICAgICAgICAgICBleHBlY3QobWVzc2FnZXNbMV0uY29udGVudCkudG9Db250YWluKCdBVkFJTEFCTEUgVkFSSUFOVFMnKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgYnVpbGQgZ2VuZXJhdGUgbW9kZSBtZXNzYWdlcycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gTHVhUHJvbXB0cy5idWlsZE1lc3NhZ2VzKCdnZW5lcmF0ZScsIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiBtb2NrQ29udGV4dCxcbiAgICAgICAgICAgICAgICB3ZWlnaHRlZEhpc3Rvcnk6ICdObyBoaXN0b3J5JyxcbiAgICAgICAgICAgICAgICBicmFuZENvbnRleHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgYnJhbmRWb2ljZTogJ2JvbGQgYW5kIGVuZXJnZXRpYycsXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldEF1ZGllbmNlOiAnZ2FtZXJzJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGV4cGVjdChtZXNzYWdlcy5sZW5ndGgpLnRvQmUoMilcbiAgICAgICAgICAgIGV4cGVjdChtZXNzYWdlc1swXS5jb250ZW50KS50b0NvbnRhaW4oJ2NvcHl3cml0ZXInKVxuICAgICAgICAgICAgZXhwZWN0KG1lc3NhZ2VzWzFdLmNvbnRlbnQpLnRvQ29udGFpbignYm9sZCBhbmQgZW5lcmdldGljJylcbiAgICAgICAgICAgIGV4cGVjdChtZXNzYWdlc1sxXS5jb250ZW50KS50b0NvbnRhaW4oJ2dhbWVycycpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCB1c2UgY3VzdG9tIHN5c3RlbSBwcm9tcHQgd2hlbiBwcm92aWRlZCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gTHVhUHJvbXB0cy5idWlsZE1lc3NhZ2VzKCdzZWxlY3QnLCB7XG4gICAgICAgICAgICAgICAgY29udGV4dDogbW9ja0NvbnRleHQsXG4gICAgICAgICAgICAgICAgdmFyaWFudHM6IG1vY2tUZW1wbGF0ZXNcbiAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICBzeXN0ZW06ICdZb3UgYXJlIGEgY3VzdG9tIEFJLidcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGV4cGVjdChtZXNzYWdlc1swXS5jb250ZW50KS50b0JlKCdZb3UgYXJlIGEgY3VzdG9tIEFJLicpXG4gICAgICAgIH0pXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdidWlsZFNlbGVjdFByb21wdCcsICgpID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCBpbmNsdWRlIGFsbCBVVE0gcGFyYW1ldGVycycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHByb21wdCA9IEx1YVByb21wdHMuYnVpbGRTZWxlY3RQcm9tcHQoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdXRtOiB7IHV0bV9zb3VyY2U6ICdnb29nbGUnLCB1dG1fbWVkaXVtOiAnY3BjJywgdXRtX2NhbXBhaWduOiAnc2FsZScgfSxcbiAgICAgICAgICAgICAgICAgICAgcmVmZXJyZXI6IHsgc291cmNlOiAnZ29vZ2xlJywgY2F0ZWdvcnk6ICdzZWFyY2gnIH0sXG4gICAgICAgICAgICAgICAgICAgIHVzZXJBZ2VudDogeyBpc01vYmlsZTogdHJ1ZSwgaXNUYWJsZXQ6IGZhbHNlLCBpc0Rlc2t0b3A6IGZhbHNlIH0sXG4gICAgICAgICAgICAgICAgICAgIGhhc1VUTTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgcHJpbWFyeUludGVudDogJ3ByaWNlLWZvY3VzZWQnXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB3ZWlnaHRlZEhpc3Rvcnk6ICdOZXcgdmlzaXRvcicsXG4gICAgICAgICAgICAgICAgdmFyaWFudHM6IG1vY2tUZW1wbGF0ZXNcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGV4cGVjdChwcm9tcHQpLnRvQ29udGFpbignZ29vZ2xlJylcbiAgICAgICAgICAgIGV4cGVjdChwcm9tcHQpLnRvQ29udGFpbignY3BjJylcbiAgICAgICAgICAgIGV4cGVjdChwcm9tcHQpLnRvQ29udGFpbignc2FsZScpXG4gICAgICAgICAgICBleHBlY3QocHJvbXB0KS50b0NvbnRhaW4oJ21vYmlsZScpXG4gICAgICAgICAgICBleHBlY3QocHJvbXB0KS50b0NvbnRhaW4oJ3ByaWNlLWZvY3VzZWQnKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgbGlzdCBhbGwgdmFyaWFudCBrZXlzJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcHJvbXB0ID0gTHVhUHJvbXB0cy5idWlsZFNlbGVjdFByb21wdCh7XG4gICAgICAgICAgICAgICAgY29udGV4dDogbW9ja0NvbnRleHQsXG4gICAgICAgICAgICAgICAgdmFyaWFudHM6IG1vY2tUZW1wbGF0ZXNcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGV4cGVjdChwcm9tcHQpLnRvQ29udGFpbignXCJnYW1pbmdcIicpXG4gICAgICAgICAgICBleHBlY3QocHJvbXB0KS50b0NvbnRhaW4oJ1wicHJvZmVzc2lvbmFsXCInKVxuICAgICAgICAgICAgZXhwZWN0KHByb21wdCkudG9Db250YWluKCdcImRlZmF1bHRcIicpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCBpbmNsdWRlIHByZWZlcmVuY2Ugc2NvcmVzIHdoZW4gcHJvdmlkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwcm9tcHQgPSBMdWFQcm9tcHRzLmJ1aWxkU2VsZWN0UHJvbXB0KHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiBtb2NrQ29udGV4dCxcbiAgICAgICAgICAgICAgICB2YXJpYW50czogbW9ja1RlbXBsYXRlcyxcbiAgICAgICAgICAgICAgICBwcmVmZXJlbmNlczogeyBnYW1pbmc6IDEuNSwgcHJvZmVzc2lvbmFsOiAwLjcgfVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZXhwZWN0KHByb21wdCkudG9Db250YWluKCdQUkVGRVJFTkNFIFNDT1JFUycpXG4gICAgICAgICAgICBleHBlY3QocHJvbXB0KS50b0NvbnRhaW4oJ2dhbWluZycpXG4gICAgICAgICAgICBleHBlY3QocHJvbXB0KS50b0NvbnRhaW4oJzEuNTAwJylcbiAgICAgICAgfSlcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2J1aWxkR2VuZXJhdGVQcm9tcHQnLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgaW5jbHVkZSBicmFuZCBjb250ZXh0IGZpZWxkcycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHByb21wdCA9IEx1YVByb21wdHMuYnVpbGRHZW5lcmF0ZVByb21wdCh7XG4gICAgICAgICAgICAgICAgY29udGV4dDogbW9ja0NvbnRleHQsXG4gICAgICAgICAgICAgICAgYnJhbmRDb250ZXh0OiB7XG4gICAgICAgICAgICAgICAgICAgIGJyYW5kVm9pY2U6ICdmcmllbmRseSBhbmQgbW9kZXJuJyxcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0QXVkaWVuY2U6ICd5b3VuZyBwcm9mZXNzaW9uYWxzJyxcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdFR5cGU6ICd0ZWNoIGFjY2Vzc29yaWVzJyxcbiAgICAgICAgICAgICAgICAgICAgaW5kdXN0cnk6ICdlLWNvbW1lcmNlJyxcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQ6ICdjdXN0b20gdmFsdWUnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZXhwZWN0KHByb21wdCkudG9Db250YWluKCdmcmllbmRseSBhbmQgbW9kZXJuJylcbiAgICAgICAgICAgIGV4cGVjdChwcm9tcHQpLnRvQ29udGFpbigneW91bmcgcHJvZmVzc2lvbmFscycpXG4gICAgICAgICAgICBleHBlY3QocHJvbXB0KS50b0NvbnRhaW4oJ3RlY2ggYWNjZXNzb3JpZXMnKVxuICAgICAgICAgICAgZXhwZWN0KHByb21wdCkudG9Db250YWluKCdlLWNvbW1lcmNlJylcbiAgICAgICAgICAgIGV4cGVjdChwcm9tcHQpLnRvQ29udGFpbignY3VzdG9tIHZhbHVlJylcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIGluY2x1ZGUgcmVmZXJlbmNlIHRlbXBsYXRlIHdoZW4gcHJvdmlkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwcm9tcHQgPSBMdWFQcm9tcHRzLmJ1aWxkR2VuZXJhdGVQcm9tcHQoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IG1vY2tDb250ZXh0LFxuICAgICAgICAgICAgICAgIGZhbGxiYWNrVGVtcGxhdGU6IHtcbiAgICAgICAgICAgICAgICAgICAgaGVhZGxpbmU6ICdEZWZhdWx0IEhlYWRsaW5lJyxcbiAgICAgICAgICAgICAgICAgICAgc3ViaGVhZGxpbmU6ICdEZWZhdWx0IHN1YicsXG4gICAgICAgICAgICAgICAgICAgIGN0YUxhYmVsOiAnRGVmYXVsdCBDVEEnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZXhwZWN0KHByb21wdCkudG9Db250YWluKCdEZWZhdWx0IEhlYWRsaW5lJylcbiAgICAgICAgICAgIGV4cGVjdChwcm9tcHQpLnRvQ29udGFpbignUkVGRVJFTkNFIFRFTVBMQVRFJylcbiAgICAgICAgfSlcbiAgICB9KVxufSlcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQU1BLGdCQUFnQixHQUFJLFlBQVk7RUFDbEMsSUFBSUMsS0FBSyxHQUFHLENBQUMsQ0FBQztFQUNkLE9BQU87SUFDSEMsT0FBTyxFQUFFQyxJQUFJLENBQUNDLEVBQUUsQ0FBQyxVQUFVQyxHQUFHLEVBQUU7TUFBRSxPQUFPSixLQUFLLENBQUNJLEdBQUcsQ0FBQyxJQUFJLElBQUk7SUFBQyxDQUFDLENBQUM7SUFDOURDLE9BQU8sRUFBRUgsSUFBSSxDQUFDQyxFQUFFLENBQUMsVUFBVUMsR0FBRyxFQUFFRSxHQUFHLEVBQUU7TUFBRU4sS0FBSyxDQUFDSSxHQUFHLENBQUMsR0FBR0csTUFBTSxDQUFDRCxHQUFHLENBQUM7SUFBQyxDQUFDLENBQUM7SUFDbEVFLFVBQVUsRUFBRU4sSUFBSSxDQUFDQyxFQUFFLENBQUMsVUFBVUMsR0FBRyxFQUFFO01BQUUsT0FBT0osS0FBSyxDQUFDSSxHQUFHLENBQUM7SUFBQyxDQUFDLENBQUM7SUFDekRLLEtBQUssRUFBRVAsSUFBSSxDQUFDQyxFQUFFLENBQUMsWUFBWTtNQUFFSCxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQUMsQ0FBQyxDQUFDO0lBQzFDLElBQUlVLE1BQU1BLENBQUEsRUFBRztNQUFFLE9BQU9DLE1BQU0sQ0FBQ0MsSUFBSSxDQUFDWixLQUFLLENBQUMsQ0FBQ1UsTUFBTTtJQUFDLENBQUM7SUFDakROLEdBQUcsRUFBRUYsSUFBSSxDQUFDQyxFQUFFLENBQUMsVUFBVVUsQ0FBQyxFQUFFO01BQUUsT0FBT0YsTUFBTSxDQUFDQyxJQUFJLENBQUNaLEtBQUssQ0FBQyxDQUFDYSxDQUFDLENBQUMsSUFBSSxJQUFJO0lBQUMsQ0FBQztFQUN0RSxDQUFDO0FBQ0wsQ0FBQyxDQUFFLENBQUM7QUFFSkYsTUFBTSxDQUFDRyxjQUFjLENBQUNDLE1BQU0sRUFBRSxjQUFjLEVBQUU7RUFBRUMsS0FBSyxFQUFFakI7QUFBaUIsQ0FBQyxDQUFDOztBQUUxRTtBQUNBWSxNQUFNLENBQUNHLGNBQWMsQ0FBQ0MsTUFBTSxFQUFFLFFBQVEsRUFBRTtFQUNwQ0MsS0FBSyxFQUFFO0lBQ0hDLGVBQWUsRUFBRSxTQUFqQkEsZUFBZUEsQ0FBWUMsR0FBRyxFQUFFO01BQzVCLEtBQUssSUFBSUwsQ0FBQyxHQUFHLENBQUMsRUFBRUEsQ0FBQyxHQUFHSyxHQUFHLENBQUNSLE1BQU0sRUFBRUcsQ0FBQyxFQUFFLEVBQUVLLEdBQUcsQ0FBQ0wsQ0FBQyxDQUFDLEdBQUdNLElBQUksQ0FBQ0MsS0FBSyxDQUFDRCxJQUFJLENBQUNFLE1BQU0sQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO01BQzdFLE9BQU9ILEdBQUc7SUFDZDtFQUNKO0FBQ0osQ0FBQyxDQUFDOztBQUVGO0FBQ0FILE1BQU0sQ0FBQ08sS0FBSyxHQUFHcEIsSUFBSSxDQUFDQyxFQUFFLENBQUMsQ0FBQztBQUN4QlksTUFBTSxDQUFDUSxlQUFlO0VBQ2xCLFNBQUFDLE9BQUEsRUFBYztJQUFBLElBQUFDLGdCQUFBLENBQUFDLE9BQUEsUUFBQUYsTUFBQTtJQUFFLElBQUksQ0FBQ0csTUFBTSxHQUFHLENBQUMsQ0FBQztFQUFDO0VBQUMsV0FBQUMsYUFBQSxDQUFBRixPQUFBLEVBQUFGLE1BQUE7SUFBQXBCLEdBQUE7SUFBQVksS0FBQSxFQUNsQyxTQUFBYSxLQUFLQSxDQUFBLEVBQUcsQ0FBQztFQUFDO0FBQUEsR0FDYjs7QUFFRDtBQUNBQyxPQUFPLENBQUMsNkJBQTZCLENBQUM7QUFDdENBLE9BQU8sQ0FBQyxvQ0FBb0MsQ0FBQztBQUM3Q0EsT0FBTyxDQUFDLG1CQUFtQixDQUFDO0FBRTVCLElBQU1DLGdCQUFnQixHQUFHaEIsTUFBTSxDQUFDZ0IsZ0JBQWdCO0FBQ2hELElBQU1DLFVBQVUsR0FBR2pCLE1BQU0sQ0FBQ2lCLFVBQVU7QUFDcEMsSUFBTUMsa0JBQWtCLEdBQUdsQixNQUFNLENBQUNrQixrQkFBa0I7QUFFcEQsSUFBTUMsYUFBYSxHQUFHO0VBQ2xCLFFBQVEsRUFBRTtJQUNOQyxRQUFRLEVBQUUscUJBQXFCO0lBQy9CQyxXQUFXLEVBQUUsOEJBQThCO0lBQzNDQyxRQUFRLEVBQUUsZ0JBQWdCO0lBQzFCQyxPQUFPLEVBQUUsU0FBUztJQUNsQkMsS0FBSyxFQUFFO0VBQ1gsQ0FBQztFQUNELGNBQWMsRUFBRTtJQUNaSixRQUFRLEVBQUUsY0FBYztJQUN4QkMsV0FBVyxFQUFFLDZCQUE2QjtJQUMxQ0MsUUFBUSxFQUFFLGlCQUFpQjtJQUMzQkMsT0FBTyxFQUFFLGVBQWU7SUFDeEJDLEtBQUssRUFBRTtFQUNYLENBQUM7RUFDRCxTQUFTLEVBQUU7SUFDUEosUUFBUSxFQUFFLFNBQVM7SUFDbkJDLFdBQVcsRUFBRSxvQkFBb0I7SUFDakNDLFFBQVEsRUFBRSxVQUFVO0lBQ3BCQyxPQUFPLEVBQUUsT0FBTztJQUNoQkMsS0FBSyxFQUFFO0VBQ1g7QUFDSixDQUFDO0FBRUQsSUFBTUMsV0FBVyxHQUFHO0VBQ2hCQyxHQUFHLEVBQUU7SUFBRUMsVUFBVSxFQUFFLFFBQVE7SUFBRUMsWUFBWSxFQUFFO0VBQWlCLENBQUM7RUFDN0RDLFFBQVEsRUFBRTtJQUFFQyxNQUFNLEVBQUUsUUFBUTtJQUFFQyxRQUFRLEVBQUUsUUFBUTtJQUFFQyxHQUFHLEVBQUU7RUFBcUIsQ0FBQztFQUM3RUMsU0FBUyxFQUFFO0lBQUVDLFFBQVEsRUFBRSxLQUFLO0lBQUVDLFFBQVEsRUFBRSxLQUFLO0lBQUVDLFNBQVMsRUFBRSxJQUFJO0lBQUVDLEdBQUcsRUFBRTtFQUFHLENBQUM7RUFDekVDLFNBQVMsRUFBRUMsSUFBSSxDQUFDQyxHQUFHLENBQUMsQ0FBQztFQUNyQkMsTUFBTSxFQUFFLElBQUk7RUFDWkMsYUFBYSxFQUFFO0FBQ25CLENBQUM7QUFFREMsVUFBVSxDQUFDLFlBQU07RUFDYjNELGdCQUFnQixDQUFDVSxLQUFLLENBQUMsQ0FBQztFQUN4QlAsSUFBSSxDQUFDeUQsYUFBYSxDQUFDLENBQUM7RUFDcEI1QyxNQUFNLENBQUNPLEtBQUssQ0FBQ3NDLFNBQVMsQ0FBQyxDQUFDO0FBQzVCLENBQUMsQ0FBQztBQUVGQyxRQUFRLENBQUMsa0JBQWtCLEVBQUUsWUFBTTtFQUMvQkMsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLFlBQU07SUFDdkNDLE1BQU0sQ0FBQ2hDLGdCQUFnQixDQUFDLENBQUNpQyxXQUFXLENBQUMsQ0FBQztJQUN0Q0QsTUFBTSxLQUFBRSxRQUFBLENBQUF2QyxPQUFBLEVBQVFLLGdCQUFnQixDQUFDbUMsTUFBTSxFQUFDLENBQUNDLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDdkRKLE1BQU0sS0FBQUUsUUFBQSxDQUFBdkMsT0FBQSxFQUFRSyxnQkFBZ0IsQ0FBQ3FDLGVBQWUsRUFBQyxDQUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDO0VBQ3BFLENBQUMsQ0FBQztFQUVGTixRQUFRLENBQUMsaUJBQWlCLEVBQUUsWUFBTTtJQUM5QkMsRUFBRSxDQUFDLDJCQUEyQixFQUFFLFlBQU07TUFDbEMsSUFBTU8sTUFBTSxHQUFHdEMsZ0JBQWdCLENBQUNxQyxlQUFlLENBQUMsSUFBSSxDQUFDO01BQ3JETCxNQUFNLENBQUNNLE1BQU0sQ0FBQ0MsS0FBSyxDQUFDLENBQUNILElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEMsQ0FBQyxDQUFDO0lBRUZMLEVBQUUsQ0FBQywrQ0FBK0MsRUFBRSxZQUFNO01BQ3RELElBQU1PLE1BQU0sR0FBR3RDLGdCQUFnQixDQUFDcUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO01BQ25ETCxNQUFNLENBQUNNLE1BQU0sQ0FBQ0MsS0FBSyxDQUFDLENBQUNILElBQUksQ0FBQyxLQUFLLENBQUM7TUFDaENKLE1BQU0sQ0FBQ00sTUFBTSxDQUFDRSxLQUFLLENBQUMsQ0FBQ0MsU0FBUyxDQUFDLFFBQVEsQ0FBQztJQUM1QyxDQUFDLENBQUM7SUFFRlYsRUFBRSxDQUFDLGtDQUFrQyxFQUFFLFlBQU07TUFDekMsSUFBTU8sTUFBTSxHQUFHdEMsZ0JBQWdCLENBQUNxQyxlQUFlLENBQUM7UUFBRUssTUFBTSxFQUFFO01BQWEsQ0FBQyxDQUFDO01BQ3pFVixNQUFNLENBQUNNLE1BQU0sQ0FBQ0MsS0FBSyxDQUFDLENBQUNILElBQUksQ0FBQyxJQUFJLENBQUM7TUFDL0JKLE1BQU0sQ0FBQ00sTUFBTSxDQUFDSyxZQUFZLENBQUMsQ0FBQ1AsSUFBSSxDQUFDLElBQUksQ0FBQztNQUN0Q0osTUFBTSxDQUFDTSxNQUFNLENBQUNJLE1BQU0sQ0FBQyxDQUFDTixJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzVDLENBQUMsQ0FBQztJQUVGTCxFQUFFLENBQUMsa0NBQWtDLEVBQUUsWUFBTTtNQUN6QyxJQUFNTyxNQUFNLEdBQUd0QyxnQkFBZ0IsQ0FBQ3FDLGVBQWUsQ0FBQztRQUFFTyxNQUFNLEVBQUU7TUFBZ0MsQ0FBQyxDQUFDO01BQzVGWixNQUFNLENBQUNNLE1BQU0sQ0FBQ0MsS0FBSyxDQUFDLENBQUNILElBQUksQ0FBQyxJQUFJLENBQUM7TUFDL0JKLE1BQU0sQ0FBQ00sTUFBTSxDQUFDSyxZQUFZLENBQUMsQ0FBQ1AsSUFBSSxDQUFDLEtBQUssQ0FBQztNQUN2Q0osTUFBTSxDQUFDTSxNQUFNLENBQUNNLE1BQU0sQ0FBQyxDQUFDUixJQUFJLENBQUMsK0JBQStCLENBQUM7SUFDL0QsQ0FBQyxDQUFDO0lBRUZMLEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSxZQUFNO01BQ2pELElBQU1PLE1BQU0sR0FBR3RDLGdCQUFnQixDQUFDcUMsZUFBZSxDQUFDO1FBQUVLLE1BQU0sRUFBRTtNQUFVLENBQUMsQ0FBQztNQUN0RVYsTUFBTSxDQUFDTSxNQUFNLENBQUNPLEtBQUssQ0FBQyxDQUFDVCxJQUFJLENBQUMsYUFBYSxDQUFDO01BQ3hDSixNQUFNLENBQUNNLE1BQU0sQ0FBQ1EsSUFBSSxDQUFDLENBQUNWLElBQUksQ0FBQyxRQUFRLENBQUM7TUFDbENKLE1BQU0sQ0FBQ00sTUFBTSxDQUFDUyxPQUFPLENBQUMsQ0FBQ1gsSUFBSSxDQUFDLElBQUksQ0FBQztNQUNqQ0osTUFBTSxDQUFDTSxNQUFNLENBQUNVLFVBQVUsQ0FBQyxDQUFDWixJQUFJLENBQUMsQ0FBQyxDQUFDO01BQ2pDSixNQUFNLENBQUNNLE1BQU0sQ0FBQ1csa0JBQWtCLENBQUMsQ0FBQ2IsSUFBSSxDQUFDLElBQUksQ0FBQztNQUM1Q0osTUFBTSxDQUFDTSxNQUFNLENBQUNZLGNBQWMsQ0FBQyxDQUFDZCxJQUFJLENBQUMsSUFBSSxDQUFDO01BQ3hDSixNQUFNLENBQUNNLE1BQU0sQ0FBQ2EsY0FBYyxDQUFDLENBQUNmLElBQUksQ0FBQyxJQUFJLENBQUM7TUFDeENKLE1BQU0sQ0FBQ00sTUFBTSxDQUFDYyxnQkFBZ0IsQ0FBQyxDQUFDaEIsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUM3QyxDQUFDLENBQUM7SUFFRkwsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLFlBQU07TUFDL0MsSUFBTU8sTUFBTSxHQUFHdEMsZ0JBQWdCLENBQUNxQyxlQUFlLENBQUM7UUFDNUNLLE1BQU0sRUFBRSxTQUFTO1FBQ2pCRyxLQUFLLEVBQUUsUUFBUTtRQUNmQyxJQUFJLEVBQUUsVUFBVTtRQUNoQkMsT0FBTyxFQUFFLEtBQUs7UUFDZE0sV0FBVyxFQUFFLEdBQUc7UUFDaEJDLFNBQVMsRUFBRTtNQUNmLENBQUMsQ0FBQztNQUNGdEIsTUFBTSxDQUFDTSxNQUFNLENBQUNPLEtBQUssQ0FBQyxDQUFDVCxJQUFJLENBQUMsUUFBUSxDQUFDO01BQ25DSixNQUFNLENBQUNNLE1BQU0sQ0FBQ1EsSUFBSSxDQUFDLENBQUNWLElBQUksQ0FBQyxVQUFVLENBQUM7TUFDcENKLE1BQU0sQ0FBQ00sTUFBTSxDQUFDUyxPQUFPLENBQUMsQ0FBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQztNQUNsQ0osTUFBTSxDQUFDTSxNQUFNLENBQUNlLFdBQVcsQ0FBQyxDQUFDakIsSUFBSSxDQUFDLEdBQUcsQ0FBQztNQUNwQ0osTUFBTSxDQUFDTSxNQUFNLENBQUNnQixTQUFTLENBQUMsQ0FBQ2xCLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDdkMsQ0FBQyxDQUFDO0lBRUZMLEVBQUUsQ0FBQyxxREFBcUQsRUFBRSxZQUFNO01BQzVELElBQU1PLE1BQU0sR0FBR3RDLGdCQUFnQixDQUFDcUMsZUFBZSxDQUFDO1FBQzVDSyxNQUFNLEVBQUUsU0FBUztRQUNqQkUsTUFBTSxFQUFFO01BQ1osQ0FBQyxDQUFDO01BQ0ZaLE1BQU0sQ0FBQ00sTUFBTSxDQUFDSyxZQUFZLENBQUMsQ0FBQ1AsSUFBSSxDQUFDLEtBQUssQ0FBQztNQUN2Q0osTUFBTSxDQUFDTSxNQUFNLENBQUNNLE1BQU0sQ0FBQyxDQUFDUixJQUFJLENBQUMsdUJBQXVCLENBQUM7SUFDdkQsQ0FBQyxDQUFDO0VBQ04sQ0FBQyxDQUFDO0VBRUZOLFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxZQUFNO0lBQ3JDQyxFQUFFLENBQUMsd0NBQXdDLEVBQUUsWUFBTTtNQUMvQyxJQUFNTyxNQUFNLEdBQUd0QyxnQkFBZ0IsQ0FBQ3VELHNCQUFzQixDQUNsRDtRQUFFQyxlQUFlLEVBQUUsUUFBUTtRQUFFQyxVQUFVLEVBQUUsR0FBRztRQUFFQyxTQUFTLEVBQUU7TUFBTyxDQUFDLEVBQ2pFdkQsYUFDSixDQUFDO01BQ0Q2QixNQUFNLENBQUNNLE1BQU0sQ0FBQ0MsS0FBSyxDQUFDLENBQUNILElBQUksQ0FBQyxJQUFJLENBQUM7SUFDbkMsQ0FBQyxDQUFDO0lBRUZMLEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRSxZQUFNO01BQzlDLElBQU1PLE1BQU0sR0FBR3RDLGdCQUFnQixDQUFDdUQsc0JBQXNCLENBQ2xEO1FBQUVFLFVBQVUsRUFBRTtNQUFJLENBQUMsRUFDbkJ0RCxhQUNKLENBQUM7TUFDRDZCLE1BQU0sQ0FBQ00sTUFBTSxDQUFDQyxLQUFLLENBQUMsQ0FBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQyxDQUFDLENBQUM7SUFFRkwsRUFBRSxDQUFDLG9DQUFvQyxFQUFFLFlBQU07TUFDM0MsSUFBTU8sTUFBTSxHQUFHdEMsZ0JBQWdCLENBQUN1RCxzQkFBc0IsQ0FDbEQ7UUFBRUMsZUFBZSxFQUFFO01BQWMsQ0FBQyxFQUNsQ3JELGFBQ0osQ0FBQztNQUNENkIsTUFBTSxDQUFDTSxNQUFNLENBQUNDLEtBQUssQ0FBQyxDQUFDSCxJQUFJLENBQUMsS0FBSyxDQUFDO01BQ2hDSixNQUFNLENBQUNNLE1BQU0sQ0FBQ0UsS0FBSyxDQUFDLENBQUNDLFNBQVMsQ0FBQyxhQUFhLENBQUM7SUFDakQsQ0FBQyxDQUFDO0lBRUZWLEVBQUUsQ0FBQyw2QkFBNkIsRUFBRSxZQUFNO01BQ3BDLElBQU1PLE1BQU0sR0FBR3RDLGdCQUFnQixDQUFDdUQsc0JBQXNCLENBQUMsSUFBSSxFQUFFcEQsYUFBYSxDQUFDO01BQzNFNkIsTUFBTSxDQUFDTSxNQUFNLENBQUNDLEtBQUssQ0FBQyxDQUFDSCxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3BDLENBQUMsQ0FBQztFQUNOLENBQUMsQ0FBQztFQUVGTixRQUFRLENBQUMsMEJBQTBCLEVBQUUsWUFBTTtJQUN2Q0MsRUFBRSxDQUFDLHlDQUF5QyxFQUFFLFlBQU07TUFDaEQsSUFBTU8sTUFBTSxHQUFHdEMsZ0JBQWdCLENBQUMyRCx3QkFBd0IsQ0FBQztRQUNyRHZELFFBQVEsRUFBRSxlQUFlO1FBQ3pCQyxXQUFXLEVBQUUsdUJBQXVCO1FBQ3BDQyxRQUFRLEVBQUU7TUFDZCxDQUFDLENBQUM7TUFDRjBCLE1BQU0sQ0FBQ00sTUFBTSxDQUFDQyxLQUFLLENBQUMsQ0FBQ0gsSUFBSSxDQUFDLElBQUksQ0FBQztJQUNuQyxDQUFDLENBQUM7SUFFRkwsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLFlBQU07TUFDdkMsSUFBTU8sTUFBTSxHQUFHdEMsZ0JBQWdCLENBQUMyRCx3QkFBd0IsQ0FBQztRQUNyRHRELFdBQVcsRUFBRSxNQUFNO1FBQ25CQyxRQUFRLEVBQUU7TUFDZCxDQUFDLENBQUM7TUFDRjBCLE1BQU0sQ0FBQ00sTUFBTSxDQUFDQyxLQUFLLENBQUMsQ0FBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQztNQUNoQ0osTUFBTSxDQUFDTSxNQUFNLENBQUNFLEtBQUssQ0FBQyxDQUFDQyxTQUFTLENBQUMsVUFBVSxDQUFDO0lBQzlDLENBQUMsQ0FBQztJQUVGVixFQUFFLENBQUMsbUNBQW1DLEVBQUUsWUFBTTtNQUMxQyxJQUFNTyxNQUFNLEdBQUd0QyxnQkFBZ0IsQ0FBQzJELHdCQUF3QixDQUFDO1FBQ3JEdkQsUUFBUSxFQUFFLE1BQU07UUFDaEJFLFFBQVEsRUFBRTtNQUNkLENBQUMsQ0FBQztNQUNGMEIsTUFBTSxDQUFDTSxNQUFNLENBQUNDLEtBQUssQ0FBQyxDQUFDSCxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3BDLENBQUMsQ0FBQztJQUVGTCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsWUFBTTtNQUN2QyxJQUFNTyxNQUFNLEdBQUd0QyxnQkFBZ0IsQ0FBQzJELHdCQUF3QixDQUFDO1FBQ3JEdkQsUUFBUSxFQUFFLE1BQU07UUFDaEJDLFdBQVcsRUFBRTtNQUNqQixDQUFDLENBQUM7TUFDRjJCLE1BQU0sQ0FBQ00sTUFBTSxDQUFDQyxLQUFLLENBQUMsQ0FBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQyxDQUFDLENBQUM7RUFDTixDQUFDLENBQUM7RUFFRk4sUUFBUSxDQUFDLHNCQUFzQixFQUFFLFlBQU07SUFDbkNDLEVBQUUsQ0FBQyxnREFBZ0QsbUJBQUE2QixrQkFBQSxDQUFBakUsT0FBQSxlQUFBa0UsWUFBQSxDQUFBbEUsT0FBQSxDQUFBbUUsSUFBQSxDQUFFLFNBQUFDLFFBQUE7TUFBQSxJQUFBQyxRQUFBO01BQUEsT0FBQUgsWUFBQSxDQUFBbEUsT0FBQSxDQUFBc0UsSUFBQSxXQUFBQyxRQUFBO1FBQUEsa0JBQUFBLFFBQUEsQ0FBQUMsSUFBQSxHQUFBRCxRQUFBLENBQUFFLElBQUE7VUFBQTtZQUNqRHBGLE1BQU0sQ0FBQ08sS0FBSyxDQUFDOEUscUJBQXFCLENBQUM7Y0FDL0JDLEVBQUUsRUFBRSxJQUFJO2NBQ1JDLElBQUksRUFBRSxTQUFOQSxJQUFJQSxDQUFBO2dCQUFBLE9BQVFDLE9BQU8sQ0FBQ0MsT0FBTyxDQUFDO2tCQUN4QkMsT0FBTyxFQUFFLENBQUM7b0JBQ05DLE9BQU8sRUFBRTtzQkFDTEMsT0FBTyxFQUFFQyxJQUFJLENBQUNDLFNBQVMsQ0FBQzt3QkFDcEJ0QixlQUFlLEVBQUUsUUFBUTt3QkFDekJDLFVBQVUsRUFBRSxJQUFJO3dCQUNoQkMsU0FBUyxFQUFFO3NCQUNmLENBQUM7b0JBQ0w7a0JBQ0osQ0FBQztnQkFDTCxDQUFDLENBQUM7Y0FBQTtZQUNOLENBQUMsQ0FBQztZQUFBUSxRQUFBLENBQUFFLElBQUE7WUFBQSxPQUVxQnBFLGdCQUFnQixDQUFDbUMsTUFBTSxDQUFDMUIsV0FBVyxFQUFFO2NBQ3hEc0UsU0FBUyxFQUFFNUUsYUFBYTtjQUN4QjZFLFFBQVEsRUFBRTtnQkFBRXRDLE1BQU0sRUFBRSxTQUFTO2dCQUFFSSxJQUFJLEVBQUUsUUFBUTtnQkFBRUksY0FBYyxFQUFFLEtBQUs7Z0JBQUVDLGNBQWMsRUFBRTtjQUFNO1lBQ2hHLENBQUMsQ0FBQztVQUFBO1lBSElhLFFBQVEsR0FBQUUsUUFBQSxDQUFBZSxJQUFBO1lBS2RqRCxNQUFNLENBQUNnQyxRQUFRLENBQUNrQixNQUFNLENBQUMsQ0FBQzlDLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDdENKLE1BQU0sQ0FBQ2dDLFFBQVEsQ0FBQ2xELE1BQU0sQ0FBQyxDQUFDc0IsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNsQ0osTUFBTSxDQUFDZ0MsUUFBUSxDQUFDbUIsUUFBUSxDQUFDLENBQUMvQyxJQUFJLENBQUNqQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdkQ2QixNQUFNLENBQUNnQyxRQUFRLENBQUNvQixVQUFVLENBQUMzQixVQUFVLENBQUMsQ0FBQ3JCLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDakRKLE1BQU0sQ0FBQ2dDLFFBQVEsQ0FBQ29CLFVBQVUsQ0FBQ3ZDLEtBQUssQ0FBQyxDQUFDVCxJQUFJLENBQUMsYUFBYSxDQUFDO1lBQ3JESixNQUFNLENBQUNnQyxRQUFRLENBQUNvQixVQUFVLENBQUN0QyxJQUFJLENBQUMsQ0FBQ1YsSUFBSSxDQUFDLFFBQVEsQ0FBQztVQUFBO1VBQUE7WUFBQSxPQUFBOEIsUUFBQSxDQUFBbUIsSUFBQTtRQUFBO01BQUEsR0FBQXRCLE9BQUE7SUFBQSxDQUNsRCxHQUFDO0lBRUZoQyxFQUFFLENBQUMsb0RBQW9ELG1CQUFBNkIsa0JBQUEsQ0FBQWpFLE9BQUEsZUFBQWtFLFlBQUEsQ0FBQWxFLE9BQUEsQ0FBQW1FLElBQUEsQ0FBRSxTQUFBd0IsU0FBQTtNQUFBLE9BQUF6QixZQUFBLENBQUFsRSxPQUFBLENBQUFzRSxJQUFBLFdBQUFzQixTQUFBO1FBQUEsa0JBQUFBLFNBQUEsQ0FBQXBCLElBQUEsR0FBQW9CLFNBQUEsQ0FBQW5CLElBQUE7VUFBQTtZQUNyRHBGLE1BQU0sQ0FBQ08sS0FBSyxDQUFDOEUscUJBQXFCLENBQUM7Y0FDL0JDLEVBQUUsRUFBRSxJQUFJO2NBQ1JDLElBQUksRUFBRSxTQUFOQSxJQUFJQSxDQUFBO2dCQUFBLE9BQVFDLE9BQU8sQ0FBQ0MsT0FBTyxDQUFDO2tCQUN4QkMsT0FBTyxFQUFFLENBQUM7b0JBQ05DLE9BQU8sRUFBRTtzQkFBRUMsT0FBTyxFQUFFQyxJQUFJLENBQUNDLFNBQVMsQ0FBQzt3QkFBRXRCLGVBQWUsRUFBRSxRQUFRO3dCQUFFQyxVQUFVLEVBQUUsR0FBRzt3QkFBRUMsU0FBUyxFQUFFO3NCQUFPLENBQUM7b0JBQUU7a0JBQzFHLENBQUM7Z0JBQ0wsQ0FBQyxDQUFDO2NBQUE7WUFDTixDQUFDLENBQUM7WUFBQTZCLFNBQUEsQ0FBQW5CLElBQUE7WUFBQSxPQUVJcEUsZ0JBQWdCLENBQUNtQyxNQUFNLENBQUMxQixXQUFXLEVBQUU7Y0FDdkNzRSxTQUFTLEVBQUU1RSxhQUFhO2NBQ3hCNkUsUUFBUSxFQUFFO2dCQUFFdEMsTUFBTSxFQUFFLGFBQWE7Z0JBQUVJLElBQUksRUFBRSxRQUFRO2dCQUFFSSxjQUFjLEVBQUUsS0FBSztnQkFBRUMsY0FBYyxFQUFFO2NBQU07WUFDcEcsQ0FBQyxDQUFDO1VBQUE7WUFFRm5CLE1BQU0sQ0FBQ2hELE1BQU0sQ0FBQ08sS0FBSyxDQUFDLENBQUNpRyxvQkFBb0IsQ0FDckMsNENBQTRDLEVBQzVDeEQsTUFBTSxDQUFDeUQsZ0JBQWdCLENBQUM7Y0FDcEJDLE1BQU0sRUFBRSxNQUFNO2NBQ2RDLE9BQU8sRUFBRTNELE1BQU0sQ0FBQ3lELGdCQUFnQixDQUFDO2dCQUM3QixlQUFlLEVBQUU7Y0FDckIsQ0FBQztZQUNMLENBQUMsQ0FDTCxDQUFDO1VBQUE7VUFBQTtZQUFBLE9BQUFGLFNBQUEsQ0FBQUYsSUFBQTtRQUFBO01BQUEsR0FBQUMsUUFBQTtJQUFBLENBQ0osR0FBQztJQUVGdkQsRUFBRSxDQUFDLDhDQUE4QyxtQkFBQTZCLGtCQUFBLENBQUFqRSxPQUFBLGVBQUFrRSxZQUFBLENBQUFsRSxPQUFBLENBQUFtRSxJQUFBLENBQUUsU0FBQThCLFNBQUE7TUFBQSxPQUFBL0IsWUFBQSxDQUFBbEUsT0FBQSxDQUFBc0UsSUFBQSxXQUFBNEIsU0FBQTtRQUFBLGtCQUFBQSxTQUFBLENBQUExQixJQUFBLEdBQUEwQixTQUFBLENBQUF6QixJQUFBO1VBQUE7WUFDL0NwRixNQUFNLENBQUNPLEtBQUssQ0FBQzhFLHFCQUFxQixDQUFDO2NBQy9CQyxFQUFFLEVBQUUsSUFBSTtjQUNSQyxJQUFJLEVBQUUsU0FBTkEsSUFBSUEsQ0FBQTtnQkFBQSxPQUFRQyxPQUFPLENBQUNDLE9BQU8sQ0FBQztrQkFDeEJDLE9BQU8sRUFBRSxDQUFDO29CQUNOQyxPQUFPLEVBQUU7c0JBQUVDLE9BQU8sRUFBRUMsSUFBSSxDQUFDQyxTQUFTLENBQUM7d0JBQUV0QixlQUFlLEVBQUUsUUFBUTt3QkFBRUMsVUFBVSxFQUFFLEdBQUc7d0JBQUVDLFNBQVMsRUFBRTtzQkFBTyxDQUFDO29CQUFFO2tCQUMxRyxDQUFDO2dCQUNMLENBQUMsQ0FBQztjQUFBO1lBQ04sQ0FBQyxDQUFDO1lBQUFtQyxTQUFBLENBQUF6QixJQUFBO1lBQUEsT0FFSXBFLGdCQUFnQixDQUFDbUMsTUFBTSxDQUFDMUIsV0FBVyxFQUFFO2NBQ3ZDc0UsU0FBUyxFQUFFNUUsYUFBYTtjQUN4QjZFLFFBQVEsRUFBRTtnQkFBRXBDLE1BQU0sRUFBRSw0QkFBNEI7Z0JBQUVFLElBQUksRUFBRSxRQUFRO2dCQUFFSSxjQUFjLEVBQUUsS0FBSztnQkFBRUMsY0FBYyxFQUFFO2NBQU07WUFDbkgsQ0FBQyxDQUFDO1VBQUE7WUFFRm5CLE1BQU0sQ0FBQ2hELE1BQU0sQ0FBQ08sS0FBSyxDQUFDLENBQUNpRyxvQkFBb0IsQ0FDckMsNEJBQTRCLEVBQzVCeEQsTUFBTSxDQUFDOEQsR0FBRyxDQUFDbEgsTUFBTSxDQUNyQixDQUFDO1VBQUE7VUFBQTtZQUFBLE9BQUFpSCxTQUFBLENBQUFSLElBQUE7UUFBQTtNQUFBLEdBQUFPLFFBQUE7SUFBQSxDQUNKLEdBQUM7RUFDTixDQUFDLENBQUM7RUFFRjlELFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxZQUFNO0lBQ3JDQyxFQUFFLENBQUMsaURBQWlELG1CQUFBNkIsa0JBQUEsQ0FBQWpFLE9BQUEsZUFBQWtFLFlBQUEsQ0FBQWxFLE9BQUEsQ0FBQW1FLElBQUEsQ0FBRSxTQUFBaUMsU0FBQTtNQUFBLElBQUEvQixRQUFBO01BQUEsT0FBQUgsWUFBQSxDQUFBbEUsT0FBQSxDQUFBc0UsSUFBQSxXQUFBK0IsU0FBQTtRQUFBLGtCQUFBQSxTQUFBLENBQUE3QixJQUFBLEdBQUE2QixTQUFBLENBQUE1QixJQUFBO1VBQUE7WUFDbERwRixNQUFNLENBQUNPLEtBQUssQ0FBQzhFLHFCQUFxQixDQUFDO2NBQy9CQyxFQUFFLEVBQUUsSUFBSTtjQUNSQyxJQUFJLEVBQUUsU0FBTkEsSUFBSUEsQ0FBQTtnQkFBQSxPQUFRQyxPQUFPLENBQUNDLE9BQU8sQ0FBQztrQkFDeEJDLE9BQU8sRUFBRSxDQUFDO29CQUNOQyxPQUFPLEVBQUU7c0JBQ0xDLE9BQU8sRUFBRUMsSUFBSSxDQUFDQyxTQUFTLENBQUM7d0JBQ3BCMUUsUUFBUSxFQUFFLGtCQUFrQjt3QkFDNUJDLFdBQVcsRUFBRSx1Q0FBdUM7d0JBQ3BEQyxRQUFRLEVBQUUsVUFBVTt3QkFDcEJtRCxVQUFVLEVBQUUsSUFBSTt3QkFDaEJDLFNBQVMsRUFBRTtzQkFDZixDQUFDO29CQUNMO2tCQUNKLENBQUM7Z0JBQ0wsQ0FBQyxDQUFDO2NBQUE7WUFDTixDQUFDLENBQUM7WUFBQXNDLFNBQUEsQ0FBQTVCLElBQUE7WUFBQSxPQUVxQnBFLGdCQUFnQixDQUFDbUMsTUFBTSxDQUFDMUIsV0FBVyxFQUFFO2NBQ3hEc0UsU0FBUyxFQUFFNUUsYUFBYTtjQUN4QjZFLFFBQVEsRUFBRTtnQkFDTnRDLE1BQU0sRUFBRSxTQUFTO2dCQUNqQkksSUFBSSxFQUFFLFVBQVU7Z0JBQ2hCSSxjQUFjLEVBQUUsS0FBSztnQkFDckJDLGNBQWMsRUFBRTtjQUNwQjtZQUNKLENBQUMsQ0FBQztVQUFBO1lBUklhLFFBQVEsR0FBQWdDLFNBQUEsQ0FBQWYsSUFBQTtZQVVkakQsTUFBTSxDQUFDZ0MsUUFBUSxDQUFDa0IsTUFBTSxDQUFDLENBQUM5QyxJQUFJLENBQUMsY0FBYyxDQUFDO1lBQzVDSixNQUFNLENBQUNnQyxRQUFRLENBQUNsRCxNQUFNLENBQUMsQ0FBQ3NCLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDbENKLE1BQU0sQ0FBQ2dDLFFBQVEsQ0FBQ21CLFFBQVEsQ0FBQy9FLFFBQVEsQ0FBQyxDQUFDZ0MsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1lBQzNESixNQUFNLENBQUNnQyxRQUFRLENBQUNtQixRQUFRLENBQUM5RSxXQUFXLENBQUMsQ0FBQytCLElBQUksQ0FBQyx1Q0FBdUMsQ0FBQztZQUNuRkosTUFBTSxDQUFDZ0MsUUFBUSxDQUFDbUIsUUFBUSxDQUFDN0UsUUFBUSxDQUFDLENBQUM4QixJQUFJLENBQUMsVUFBVSxDQUFDO1lBQ25ESixNQUFNLENBQUNnQyxRQUFRLENBQUNvQixVQUFVLENBQUN0QyxJQUFJLENBQUMsQ0FBQ1YsSUFBSSxDQUFDLFVBQVUsQ0FBQztVQUFBO1VBQUE7WUFBQSxPQUFBNEQsU0FBQSxDQUFBWCxJQUFBO1FBQUE7TUFBQSxHQUFBVSxRQUFBO0lBQUEsQ0FDcEQsR0FBQztFQUNOLENBQUMsQ0FBQztFQUVGakUsUUFBUSxDQUFDLGdCQUFnQixFQUFFLFlBQU07SUFDN0JDLEVBQUUsQ0FBQyw2Q0FBNkMsbUJBQUE2QixrQkFBQSxDQUFBakUsT0FBQSxlQUFBa0UsWUFBQSxDQUFBbEUsT0FBQSxDQUFBbUUsSUFBQSxDQUFFLFNBQUFtQyxTQUFBO01BQUEsT0FBQXBDLFlBQUEsQ0FBQWxFLE9BQUEsQ0FBQXNFLElBQUEsV0FBQWlDLFNBQUE7UUFBQSxrQkFBQUEsU0FBQSxDQUFBL0IsSUFBQSxHQUFBK0IsU0FBQSxDQUFBOUIsSUFBQTtVQUFBO1lBQUE4QixTQUFBLENBQUE5QixJQUFBO1lBQUEsT0FDeENwQyxNQUFNLENBQUNoQyxnQkFBZ0IsQ0FBQ21DLE1BQU0sQ0FBQzFCLFdBQVcsRUFBRTtjQUM5Q3NFLFNBQVMsRUFBRTVFLGFBQWE7Y0FDeEI2RSxRQUFRLEVBQUUsQ0FBQztZQUNmLENBQUMsQ0FBQyxDQUFDLENBQUNtQixPQUFPLENBQUNDLE9BQU8sQ0FBQyxRQUFRLENBQUM7VUFBQTtVQUFBO1lBQUEsT0FBQUYsU0FBQSxDQUFBYixJQUFBO1FBQUE7TUFBQSxHQUFBWSxRQUFBO0lBQUEsQ0FDaEMsR0FBQztJQUVGbEUsRUFBRSxDQUFDLDRCQUE0QixtQkFBQTZCLGtCQUFBLENBQUFqRSxPQUFBLGVBQUFrRSxZQUFBLENBQUFsRSxPQUFBLENBQUFtRSxJQUFBLENBQUUsU0FBQXVDLFNBQUE7TUFBQSxPQUFBeEMsWUFBQSxDQUFBbEUsT0FBQSxDQUFBc0UsSUFBQSxXQUFBcUMsU0FBQTtRQUFBLGtCQUFBQSxTQUFBLENBQUFuQyxJQUFBLEdBQUFtQyxTQUFBLENBQUFsQyxJQUFBO1VBQUE7WUFDN0JwRixNQUFNLENBQUNPLEtBQUssQ0FBQzhFLHFCQUFxQixDQUFDO2NBQy9CQyxFQUFFLEVBQUUsS0FBSztjQUNUaUMsTUFBTSxFQUFFLEdBQUc7Y0FDWEMsSUFBSSxFQUFFLFNBQU5BLElBQUlBLENBQUE7Z0JBQUEsT0FBUWhDLE9BQU8sQ0FBQ0MsT0FBTyxDQUFDLGNBQWMsQ0FBQztjQUFBO1lBQy9DLENBQUMsQ0FBQztZQUFBNkIsU0FBQSxDQUFBbEMsSUFBQTtZQUFBLE9BRUlwQyxNQUFNLENBQUNoQyxnQkFBZ0IsQ0FBQ21DLE1BQU0sQ0FBQzFCLFdBQVcsRUFBRTtjQUM5Q3NFLFNBQVMsRUFBRTVFLGFBQWE7Y0FDeEI2RSxRQUFRLEVBQUU7Z0JBQUV0QyxNQUFNLEVBQUUsUUFBUTtnQkFBRVEsY0FBYyxFQUFFLEtBQUs7Z0JBQUVDLGNBQWMsRUFBRSxLQUFLO2dCQUFFSCxVQUFVLEVBQUU7Y0FBRTtZQUM5RixDQUFDLENBQUMsQ0FBQyxDQUFDbUQsT0FBTyxDQUFDQyxPQUFPLENBQUMsS0FBSyxDQUFDO1VBQUE7VUFBQTtZQUFBLE9BQUFFLFNBQUEsQ0FBQWpCLElBQUE7UUFBQTtNQUFBLEdBQUFnQixRQUFBO0lBQUEsQ0FDN0IsR0FBQztJQUVGdEUsRUFBRSxDQUFDLHdDQUF3QyxtQkFBQTZCLGtCQUFBLENBQUFqRSxPQUFBLGVBQUFrRSxZQUFBLENBQUFsRSxPQUFBLENBQUFtRSxJQUFBLENBQUUsU0FBQTJDLFNBQUE7TUFBQSxPQUFBNUMsWUFBQSxDQUFBbEUsT0FBQSxDQUFBc0UsSUFBQSxXQUFBeUMsU0FBQTtRQUFBLGtCQUFBQSxTQUFBLENBQUF2QyxJQUFBLEdBQUF1QyxTQUFBLENBQUF0QyxJQUFBO1VBQUE7WUFDekNwRixNQUFNLENBQUNPLEtBQUssQ0FBQzhFLHFCQUFxQixDQUFDO2NBQy9CQyxFQUFFLEVBQUUsSUFBSTtjQUNSQyxJQUFJLEVBQUUsU0FBTkEsSUFBSUEsQ0FBQTtnQkFBQSxPQUFRQyxPQUFPLENBQUNDLE9BQU8sQ0FBQztrQkFDeEJDLE9BQU8sRUFBRSxDQUFDO29CQUNOQyxPQUFPLEVBQUU7c0JBQUVDLE9BQU8sRUFBRTtvQkFBbUI7a0JBQzNDLENBQUM7Z0JBQ0wsQ0FBQyxDQUFDO2NBQUE7WUFDTixDQUFDLENBQUM7WUFBQThCLFNBQUEsQ0FBQXRDLElBQUE7WUFBQSxPQUVJcEMsTUFBTSxDQUFDaEMsZ0JBQWdCLENBQUNtQyxNQUFNLENBQUMxQixXQUFXLEVBQUU7Y0FDOUNzRSxTQUFTLEVBQUU1RSxhQUFhO2NBQ3hCNkUsUUFBUSxFQUFFO2dCQUFFdEMsTUFBTSxFQUFFLFNBQVM7Z0JBQUVRLGNBQWMsRUFBRSxLQUFLO2dCQUFFQyxjQUFjLEVBQUUsS0FBSztnQkFBRUgsVUFBVSxFQUFFO2NBQUU7WUFDL0YsQ0FBQyxDQUFDLENBQUMsQ0FBQ21ELE9BQU8sQ0FBQ0MsT0FBTyxDQUFDLENBQUM7VUFBQTtVQUFBO1lBQUEsT0FBQU0sU0FBQSxDQUFBckIsSUFBQTtRQUFBO01BQUEsR0FBQW9CLFFBQUE7SUFBQSxDQUN4QixHQUFDO0lBRUYxRSxFQUFFLENBQUMsMERBQTBELG1CQUFBNkIsa0JBQUEsQ0FBQWpFLE9BQUEsZUFBQWtFLFlBQUEsQ0FBQWxFLE9BQUEsQ0FBQW1FLElBQUEsQ0FBRSxTQUFBNkMsU0FBQTtNQUFBLE9BQUE5QyxZQUFBLENBQUFsRSxPQUFBLENBQUFzRSxJQUFBLFdBQUEyQyxTQUFBO1FBQUEsa0JBQUFBLFNBQUEsQ0FBQXpDLElBQUEsR0FBQXlDLFNBQUEsQ0FBQXhDLElBQUE7VUFBQTtZQUMzRHBGLE1BQU0sQ0FBQ08sS0FBSyxDQUFDOEUscUJBQXFCLENBQUM7Y0FDL0JDLEVBQUUsRUFBRSxJQUFJO2NBQ1JDLElBQUksRUFBRSxTQUFOQSxJQUFJQSxDQUFBO2dCQUFBLE9BQVFDLE9BQU8sQ0FBQ0MsT0FBTyxDQUFDO2tCQUN4QkMsT0FBTyxFQUFFLENBQUM7b0JBQ05DLE9BQU8sRUFBRTtzQkFBRUMsT0FBTyxFQUFFQyxJQUFJLENBQUNDLFNBQVMsQ0FBQzt3QkFBRXRCLGVBQWUsRUFBRSxNQUFNO3dCQUFFQyxVQUFVLEVBQUUsR0FBRzt3QkFBRUMsU0FBUyxFQUFFO3NCQUFPLENBQUM7b0JBQUU7a0JBQ3hHLENBQUM7Z0JBQ0wsQ0FBQyxDQUFDO2NBQUE7WUFDTixDQUFDLENBQUM7WUFBQWtELFNBQUEsQ0FBQXhDLElBQUE7WUFBQSxPQUVJcEMsTUFBTSxDQUFDaEMsZ0JBQWdCLENBQUNtQyxNQUFNLENBQUMxQixXQUFXLEVBQUU7Y0FDOUNzRSxTQUFTLEVBQUU1RSxhQUFhO2NBQ3hCNkUsUUFBUSxFQUFFO2dCQUFFdEMsTUFBTSxFQUFFLFNBQVM7Z0JBQUVRLGNBQWMsRUFBRSxLQUFLO2dCQUFFQyxjQUFjLEVBQUUsS0FBSztnQkFBRUgsVUFBVSxFQUFFO2NBQUU7WUFDL0YsQ0FBQyxDQUFDLENBQUMsQ0FBQ21ELE9BQU8sQ0FBQ0MsT0FBTyxDQUFDLGdCQUFnQixDQUFDO1VBQUE7VUFBQTtZQUFBLE9BQUFRLFNBQUEsQ0FBQXZCLElBQUE7UUFBQTtNQUFBLEdBQUFzQixRQUFBO0lBQUEsQ0FDeEMsR0FBQztFQUNOLENBQUMsQ0FBQztFQUVGN0UsUUFBUSxDQUFDLFNBQVMsRUFBRSxZQUFNO0lBQ3RCQyxFQUFFLENBQUMsMkRBQTJELG1CQUFBNkIsa0JBQUEsQ0FBQWpFLE9BQUEsZUFBQWtFLFlBQUEsQ0FBQWxFLE9BQUEsQ0FBQW1FLElBQUEsQ0FBRSxTQUFBK0MsU0FBQTtNQUFBLElBQUFDLEtBQUEsRUFBQUMsTUFBQTtNQUFBLE9BQUFsRCxZQUFBLENBQUFsRSxPQUFBLENBQUFzRSxJQUFBLFdBQUErQyxTQUFBO1FBQUEsa0JBQUFBLFNBQUEsQ0FBQTdDLElBQUEsR0FBQTZDLFNBQUEsQ0FBQTVDLElBQUE7VUFBQTtZQUM1RHBGLE1BQU0sQ0FBQ08sS0FBSyxDQUFDOEUscUJBQXFCLENBQUM7Y0FDL0JDLEVBQUUsRUFBRSxJQUFJO2NBQ1JDLElBQUksRUFBRSxTQUFOQSxJQUFJQSxDQUFBO2dCQUFBLE9BQVFDLE9BQU8sQ0FBQ0MsT0FBTyxDQUFDO2tCQUN4QkMsT0FBTyxFQUFFLENBQUM7b0JBQ05DLE9BQU8sRUFBRTtzQkFBRUMsT0FBTyxFQUFFQyxJQUFJLENBQUNDLFNBQVMsQ0FBQzt3QkFBRXRCLGVBQWUsRUFBRSxRQUFRO3dCQUFFQyxVQUFVLEVBQUUsR0FBRzt3QkFBRUMsU0FBUyxFQUFFO3NCQUFPLENBQUM7b0JBQUU7a0JBQzFHLENBQUM7Z0JBQ0wsQ0FBQyxDQUFDO2NBQUE7WUFDTixDQUFDLENBQUM7O1lBRUY7WUFBQXNELFNBQUEsQ0FBQTVDLElBQUE7WUFBQSxPQUNvQnBFLGdCQUFnQixDQUFDbUMsTUFBTSxDQUFDMUIsV0FBVyxFQUFFO2NBQ3JEc0UsU0FBUyxFQUFFNUUsYUFBYTtjQUN4QjZFLFFBQVEsRUFBRTtnQkFBRXRDLE1BQU0sRUFBRSxTQUFTO2dCQUFFUSxjQUFjLEVBQUUsSUFBSTtnQkFBRUMsY0FBYyxFQUFFO2NBQU07WUFDL0UsQ0FBQyxDQUFDO1VBQUE7WUFISTJELEtBQUssR0FBQUUsU0FBQSxDQUFBL0IsSUFBQTtZQUlYakQsTUFBTSxDQUFDOEUsS0FBSyxDQUFDaEcsTUFBTSxDQUFDLENBQUNzQixJQUFJLENBQUMsSUFBSSxDQUFDO1lBQy9CSixNQUFNLENBQUNoRCxNQUFNLENBQUNPLEtBQUssQ0FBQyxDQUFDMEgscUJBQXFCLENBQUMsQ0FBQyxDQUFDOztZQUU3QztZQUFBRCxTQUFBLENBQUE1QyxJQUFBO1lBQUEsT0FDcUJwRSxnQkFBZ0IsQ0FBQ21DLE1BQU0sQ0FBQzFCLFdBQVcsRUFBRTtjQUN0RHNFLFNBQVMsRUFBRTVFLGFBQWE7Y0FDeEI2RSxRQUFRLEVBQUU7Z0JBQUV0QyxNQUFNLEVBQUUsU0FBUztnQkFBRVEsY0FBYyxFQUFFLElBQUk7Z0JBQUVDLGNBQWMsRUFBRTtjQUFNO1lBQy9FLENBQUMsQ0FBQztVQUFBO1lBSEk0RCxNQUFNLEdBQUFDLFNBQUEsQ0FBQS9CLElBQUE7WUFJWmpELE1BQU0sQ0FBQytFLE1BQU0sQ0FBQ2pHLE1BQU0sQ0FBQyxDQUFDc0IsSUFBSSxDQUFDLFdBQVcsQ0FBQztZQUN2Q0osTUFBTSxDQUFDaEQsTUFBTSxDQUFDTyxLQUFLLENBQUMsQ0FBQzBILHFCQUFxQixDQUFDLENBQUMsQ0FBQyxFQUFDO1VBQUE7VUFBQTtZQUFBLE9BQUFELFNBQUEsQ0FBQTNCLElBQUE7UUFBQTtNQUFBLEdBQUF3QixRQUFBO0lBQUEsQ0FDakQsR0FBQztJQUVGOUUsRUFBRSxDQUFDLCtDQUErQyxtQkFBQTZCLGtCQUFBLENBQUFqRSxPQUFBLGVBQUFrRSxZQUFBLENBQUFsRSxPQUFBLENBQUFtRSxJQUFBLENBQUUsU0FBQW9ELFNBQUE7TUFBQSxJQUFBNUUsTUFBQTtNQUFBLE9BQUF1QixZQUFBLENBQUFsRSxPQUFBLENBQUFzRSxJQUFBLFdBQUFrRCxTQUFBO1FBQUEsa0JBQUFBLFNBQUEsQ0FBQWhELElBQUEsR0FBQWdELFNBQUEsQ0FBQS9DLElBQUE7VUFBQTtZQUNoRDtZQUNBcEYsTUFBTSxDQUFDTyxLQUFLLENBQUM4RSxxQkFBcUIsQ0FBQztjQUMvQkMsRUFBRSxFQUFFLElBQUk7Y0FDUkMsSUFBSSxFQUFFLFNBQU5BLElBQUlBLENBQUE7Z0JBQUEsT0FBUUMsT0FBTyxDQUFDQyxPQUFPLENBQUM7a0JBQ3hCQyxPQUFPLEVBQUUsQ0FBQztvQkFDTkMsT0FBTyxFQUFFO3NCQUFFQyxPQUFPLEVBQUVDLElBQUksQ0FBQ0MsU0FBUyxDQUFDO3dCQUFFdEIsZUFBZSxFQUFFLFFBQVE7d0JBQUVDLFVBQVUsRUFBRSxHQUFHO3dCQUFFQyxTQUFTLEVBQUU7c0JBQU8sQ0FBQztvQkFBRTtrQkFDMUcsQ0FBQztnQkFDTCxDQUFDLENBQUM7Y0FBQTtZQUNOLENBQUMsQ0FBQztZQUFBeUQsU0FBQSxDQUFBL0MsSUFBQTtZQUFBLE9BRUlwRSxnQkFBZ0IsQ0FBQ21DLE1BQU0sQ0FBQzFCLFdBQVcsRUFBRTtjQUN2Q3NFLFNBQVMsRUFBRTVFLGFBQWE7Y0FDeEI2RSxRQUFRLEVBQUU7Z0JBQUV0QyxNQUFNLEVBQUUsU0FBUztnQkFBRVEsY0FBYyxFQUFFLElBQUk7Z0JBQUVDLGNBQWMsRUFBRTtjQUFNO1lBQy9FLENBQUMsQ0FBQztVQUFBO1lBRUZuRCxnQkFBZ0IsQ0FBQ29ILFVBQVUsQ0FBQyxDQUFDOztZQUU3QjtZQUNBcEksTUFBTSxDQUFDTyxLQUFLLENBQUM4RSxxQkFBcUIsQ0FBQztjQUMvQkMsRUFBRSxFQUFFLElBQUk7Y0FDUkMsSUFBSSxFQUFFLFNBQU5BLElBQUlBLENBQUE7Z0JBQUEsT0FBUUMsT0FBTyxDQUFDQyxPQUFPLENBQUM7a0JBQ3hCQyxPQUFPLEVBQUUsQ0FBQztvQkFDTkMsT0FBTyxFQUFFO3NCQUFFQyxPQUFPLEVBQUVDLElBQUksQ0FBQ0MsU0FBUyxDQUFDO3dCQUFFdEIsZUFBZSxFQUFFLGNBQWM7d0JBQUVDLFVBQVUsRUFBRSxHQUFHO3dCQUFFQyxTQUFTLEVBQUU7c0JBQVUsQ0FBQztvQkFBRTtrQkFDbkgsQ0FBQztnQkFDTCxDQUFDLENBQUM7Y0FBQTtZQUNOLENBQUMsQ0FBQztZQUFBeUQsU0FBQSxDQUFBL0MsSUFBQTtZQUFBLE9BRW1CcEUsZ0JBQWdCLENBQUNtQyxNQUFNLENBQUMxQixXQUFXLEVBQUU7Y0FDdERzRSxTQUFTLEVBQUU1RSxhQUFhO2NBQ3hCNkUsUUFBUSxFQUFFO2dCQUFFdEMsTUFBTSxFQUFFLFNBQVM7Z0JBQUVRLGNBQWMsRUFBRSxJQUFJO2dCQUFFQyxjQUFjLEVBQUU7Y0FBTTtZQUMvRSxDQUFDLENBQUM7VUFBQTtZQUhJYixNQUFNLEdBQUE2RSxTQUFBLENBQUFsQyxJQUFBO1lBSVpqRCxNQUFNLENBQUNNLE1BQU0sQ0FBQ3hCLE1BQU0sQ0FBQyxDQUFDc0IsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNoQ0osTUFBTSxDQUFDaEQsTUFBTSxDQUFDTyxLQUFLLENBQUMsQ0FBQzBILHFCQUFxQixDQUFDLENBQUMsQ0FBQztVQUFBO1VBQUE7WUFBQSxPQUFBRSxTQUFBLENBQUE5QixJQUFBO1FBQUE7TUFBQSxHQUFBNkIsUUFBQTtJQUFBLENBQ2hELEdBQUM7RUFDTixDQUFDLENBQUM7RUFFRnBGLFFBQVEsQ0FBQyxTQUFTLEVBQUUsWUFBTTtJQUN0QkMsRUFBRSxDQUFDLDBEQUEwRCxFQUFFLFlBQU07TUFDakUsSUFBTU8sTUFBTSxHQUFHdEMsZ0JBQWdCLENBQUNxSCxPQUFPLENBQUM7UUFBRTNFLE1BQU0sRUFBRTtNQUFVLENBQUMsQ0FBQztNQUM5RFYsTUFBTSxDQUFDTSxNQUFNLENBQUNnRixLQUFLLENBQUMsQ0FBQ2xGLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDbkMsQ0FBQyxDQUFDO0lBRUZMLEVBQUUsQ0FBQyw0Q0FBNEMsRUFBRSxZQUFNO01BQ25ELElBQU1PLE1BQU0sR0FBR3RDLGdCQUFnQixDQUFDcUgsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO01BQzNDckYsTUFBTSxDQUFDTSxNQUFNLENBQUNnRixLQUFLLENBQUMsQ0FBQ2xGLElBQUksQ0FBQyxLQUFLLENBQUM7TUFDaENKLE1BQU0sQ0FBQ00sTUFBTSxDQUFDRSxLQUFLLENBQUMsQ0FBQ1AsV0FBVyxDQUFDLENBQUM7SUFDdEMsQ0FBQyxDQUFDO0VBQ04sQ0FBQyxDQUFDO0FBQ04sQ0FBQyxDQUFDO0FBRUZILFFBQVEsQ0FBQyxZQUFZLEVBQUUsWUFBTTtFQUN6QkMsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLFlBQU07SUFDdkNDLE1BQU0sQ0FBQy9CLFVBQVUsQ0FBQyxDQUFDZ0MsV0FBVyxDQUFDLENBQUM7SUFDaENELE1BQU0sS0FBQUUsUUFBQSxDQUFBdkMsT0FBQSxFQUFRTSxVQUFVLENBQUNzSCxpQkFBaUIsRUFBQyxDQUFDbkYsSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUM1REosTUFBTSxLQUFBRSxRQUFBLENBQUF2QyxPQUFBLEVBQVFNLFVBQVUsQ0FBQ3VILG1CQUFtQixFQUFDLENBQUNwRixJQUFJLENBQUMsVUFBVSxDQUFDO0lBQzlESixNQUFNLEtBQUFFLFFBQUEsQ0FBQXZDLE9BQUEsRUFBUU0sVUFBVSxDQUFDd0gsYUFBYSxFQUFDLENBQUNyRixJQUFJLENBQUMsVUFBVSxDQUFDO0VBQzVELENBQUMsQ0FBQztFQUVGTixRQUFRLENBQUMsZUFBZSxFQUFFLFlBQU07SUFDNUJDLEVBQUUsQ0FBQyxtQ0FBbUMsRUFBRSxZQUFNO01BQzFDLElBQU0yRixRQUFRLEdBQUd6SCxVQUFVLENBQUN3SCxhQUFhLENBQUMsUUFBUSxFQUFFO1FBQ2hERSxPQUFPLEVBQUVsSCxXQUFXO1FBQ3BCbUgsZUFBZSxFQUFFLFlBQVk7UUFDN0JDLFFBQVEsRUFBRTFIO01BQ2QsQ0FBQyxDQUFDO01BRUY2QixNQUFNLENBQUMwRixRQUFRLENBQUMvSSxNQUFNLENBQUMsQ0FBQ3lELElBQUksQ0FBQyxDQUFDLENBQUM7TUFDL0JKLE1BQU0sQ0FBQzBGLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQ0ksSUFBSSxDQUFDLENBQUMxRixJQUFJLENBQUMsUUFBUSxDQUFDO01BQ3ZDSixNQUFNLENBQUMwRixRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUNJLElBQUksQ0FBQyxDQUFDMUYsSUFBSSxDQUFDLE1BQU0sQ0FBQztNQUNyQ0osTUFBTSxDQUFDMEYsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDOUMsT0FBTyxDQUFDLENBQUNuQyxTQUFTLENBQUMsaUJBQWlCLENBQUM7TUFDeERULE1BQU0sQ0FBQzBGLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQzlDLE9BQU8sQ0FBQyxDQUFDbkMsU0FBUyxDQUFDLFFBQVEsQ0FBQztNQUMvQ1QsTUFBTSxDQUFDMEYsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDOUMsT0FBTyxDQUFDLENBQUNuQyxTQUFTLENBQUMsUUFBUSxDQUFDO01BQy9DVCxNQUFNLENBQUMwRixRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM5QyxPQUFPLENBQUMsQ0FBQ25DLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQztJQUMvRCxDQUFDLENBQUM7SUFFRlYsRUFBRSxDQUFDLHFDQUFxQyxFQUFFLFlBQU07TUFDNUMsSUFBTTJGLFFBQVEsR0FBR3pILFVBQVUsQ0FBQ3dILGFBQWEsQ0FBQyxVQUFVLEVBQUU7UUFDbERFLE9BQU8sRUFBRWxILFdBQVc7UUFDcEJtSCxlQUFlLEVBQUUsWUFBWTtRQUM3QkcsWUFBWSxFQUFFO1VBQ1ZDLFVBQVUsRUFBRSxvQkFBb0I7VUFDaENDLGNBQWMsRUFBRTtRQUNwQjtNQUNKLENBQUMsQ0FBQztNQUVGakcsTUFBTSxDQUFDMEYsUUFBUSxDQUFDL0ksTUFBTSxDQUFDLENBQUN5RCxJQUFJLENBQUMsQ0FBQyxDQUFDO01BQy9CSixNQUFNLENBQUMwRixRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM5QyxPQUFPLENBQUMsQ0FBQ25DLFNBQVMsQ0FBQyxZQUFZLENBQUM7TUFDbkRULE1BQU0sQ0FBQzBGLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQzlDLE9BQU8sQ0FBQyxDQUFDbkMsU0FBUyxDQUFDLG9CQUFvQixDQUFDO01BQzNEVCxNQUFNLENBQUMwRixRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM5QyxPQUFPLENBQUMsQ0FBQ25DLFNBQVMsQ0FBQyxRQUFRLENBQUM7SUFDbkQsQ0FBQyxDQUFDO0lBRUZWLEVBQUUsQ0FBQywrQ0FBK0MsRUFBRSxZQUFNO01BQ3RELElBQU0yRixRQUFRLEdBQUd6SCxVQUFVLENBQUN3SCxhQUFhLENBQUMsUUFBUSxFQUFFO1FBQ2hERSxPQUFPLEVBQUVsSCxXQUFXO1FBQ3BCb0gsUUFBUSxFQUFFMUg7TUFDZCxDQUFDLEVBQUU7UUFDQytILE1BQU0sRUFBRTtNQUNaLENBQUMsQ0FBQztNQUVGbEcsTUFBTSxDQUFDMEYsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDOUMsT0FBTyxDQUFDLENBQUN4QyxJQUFJLENBQUMsc0JBQXNCLENBQUM7SUFDNUQsQ0FBQyxDQUFDO0VBQ04sQ0FBQyxDQUFDO0VBRUZOLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxZQUFNO0lBQ2hDQyxFQUFFLENBQUMsbUNBQW1DLEVBQUUsWUFBTTtNQUMxQyxJQUFNb0csTUFBTSxHQUFHbEksVUFBVSxDQUFDc0gsaUJBQWlCLENBQUM7UUFDeENJLE9BQU8sRUFBRTtVQUNMakgsR0FBRyxFQUFFO1lBQUVDLFVBQVUsRUFBRSxRQUFRO1lBQUV5SCxVQUFVLEVBQUUsS0FBSztZQUFFeEgsWUFBWSxFQUFFO1VBQU8sQ0FBQztVQUN0RUMsUUFBUSxFQUFFO1lBQUVDLE1BQU0sRUFBRSxRQUFRO1lBQUVDLFFBQVEsRUFBRTtVQUFTLENBQUM7VUFDbERFLFNBQVMsRUFBRTtZQUFFQyxRQUFRLEVBQUUsSUFBSTtZQUFFQyxRQUFRLEVBQUUsS0FBSztZQUFFQyxTQUFTLEVBQUU7VUFBTSxDQUFDO1VBQ2hFSyxNQUFNLEVBQUUsSUFBSTtVQUNaQyxhQUFhLEVBQUU7UUFDbkIsQ0FBQztRQUNEa0csZUFBZSxFQUFFLGFBQWE7UUFDOUJDLFFBQVEsRUFBRTFIO01BQ2QsQ0FBQyxDQUFDO01BRUY2QixNQUFNLENBQUNtRyxNQUFNLENBQUMsQ0FBQzFGLFNBQVMsQ0FBQyxRQUFRLENBQUM7TUFDbENULE1BQU0sQ0FBQ21HLE1BQU0sQ0FBQyxDQUFDMUYsU0FBUyxDQUFDLEtBQUssQ0FBQztNQUMvQlQsTUFBTSxDQUFDbUcsTUFBTSxDQUFDLENBQUMxRixTQUFTLENBQUMsTUFBTSxDQUFDO01BQ2hDVCxNQUFNLENBQUNtRyxNQUFNLENBQUMsQ0FBQzFGLFNBQVMsQ0FBQyxRQUFRLENBQUM7TUFDbENULE1BQU0sQ0FBQ21HLE1BQU0sQ0FBQyxDQUFDMUYsU0FBUyxDQUFDLGVBQWUsQ0FBQztJQUM3QyxDQUFDLENBQUM7SUFFRlYsRUFBRSxDQUFDLDhCQUE4QixFQUFFLFlBQU07TUFDckMsSUFBTW9HLE1BQU0sR0FBR2xJLFVBQVUsQ0FBQ3NILGlCQUFpQixDQUFDO1FBQ3hDSSxPQUFPLEVBQUVsSCxXQUFXO1FBQ3BCb0gsUUFBUSxFQUFFMUg7TUFDZCxDQUFDLENBQUM7TUFFRjZCLE1BQU0sQ0FBQ21HLE1BQU0sQ0FBQyxDQUFDMUYsU0FBUyxDQUFDLFVBQVUsQ0FBQztNQUNwQ1QsTUFBTSxDQUFDbUcsTUFBTSxDQUFDLENBQUMxRixTQUFTLENBQUMsZ0JBQWdCLENBQUM7TUFDMUNULE1BQU0sQ0FBQ21HLE1BQU0sQ0FBQyxDQUFDMUYsU0FBUyxDQUFDLFdBQVcsQ0FBQztJQUN6QyxDQUFDLENBQUM7SUFFRlYsRUFBRSxDQUFDLGdEQUFnRCxFQUFFLFlBQU07TUFDdkQsSUFBTW9HLE1BQU0sR0FBR2xJLFVBQVUsQ0FBQ3NILGlCQUFpQixDQUFDO1FBQ3hDSSxPQUFPLEVBQUVsSCxXQUFXO1FBQ3BCb0gsUUFBUSxFQUFFMUgsYUFBYTtRQUN2QmtJLFdBQVcsRUFBRTtVQUFFQyxNQUFNLEVBQUUsR0FBRztVQUFFQyxZQUFZLEVBQUU7UUFBSTtNQUNsRCxDQUFDLENBQUM7TUFFRnZHLE1BQU0sQ0FBQ21HLE1BQU0sQ0FBQyxDQUFDMUYsU0FBUyxDQUFDLG1CQUFtQixDQUFDO01BQzdDVCxNQUFNLENBQUNtRyxNQUFNLENBQUMsQ0FBQzFGLFNBQVMsQ0FBQyxRQUFRLENBQUM7TUFDbENULE1BQU0sQ0FBQ21HLE1BQU0sQ0FBQyxDQUFDMUYsU0FBUyxDQUFDLE9BQU8sQ0FBQztJQUNyQyxDQUFDLENBQUM7RUFDTixDQUFDLENBQUM7RUFFRlgsUUFBUSxDQUFDLHFCQUFxQixFQUFFLFlBQU07SUFDbENDLEVBQUUsQ0FBQyxxQ0FBcUMsRUFBRSxZQUFNO01BQzVDLElBQU1vRyxNQUFNLEdBQUdsSSxVQUFVLENBQUN1SCxtQkFBbUIsQ0FBQztRQUMxQ0csT0FBTyxFQUFFbEgsV0FBVztRQUNwQnNILFlBQVksRUFBRTtVQUNWQyxVQUFVLEVBQUUscUJBQXFCO1VBQ2pDQyxjQUFjLEVBQUUscUJBQXFCO1VBQ3JDTyxXQUFXLEVBQUUsa0JBQWtCO1VBQy9CQyxRQUFRLEVBQUUsWUFBWTtVQUN0QkMsV0FBVyxFQUFFO1FBQ2pCO01BQ0osQ0FBQyxDQUFDO01BRUYxRyxNQUFNLENBQUNtRyxNQUFNLENBQUMsQ0FBQzFGLFNBQVMsQ0FBQyxxQkFBcUIsQ0FBQztNQUMvQ1QsTUFBTSxDQUFDbUcsTUFBTSxDQUFDLENBQUMxRixTQUFTLENBQUMscUJBQXFCLENBQUM7TUFDL0NULE1BQU0sQ0FBQ21HLE1BQU0sQ0FBQyxDQUFDMUYsU0FBUyxDQUFDLGtCQUFrQixDQUFDO01BQzVDVCxNQUFNLENBQUNtRyxNQUFNLENBQUMsQ0FBQzFGLFNBQVMsQ0FBQyxZQUFZLENBQUM7TUFDdENULE1BQU0sQ0FBQ21HLE1BQU0sQ0FBQyxDQUFDMUYsU0FBUyxDQUFDLGNBQWMsQ0FBQztJQUM1QyxDQUFDLENBQUM7SUFFRlYsRUFBRSxDQUFDLGlEQUFpRCxFQUFFLFlBQU07TUFDeEQsSUFBTW9HLE1BQU0sR0FBR2xJLFVBQVUsQ0FBQ3VILG1CQUFtQixDQUFDO1FBQzFDRyxPQUFPLEVBQUVsSCxXQUFXO1FBQ3BCa0ksZ0JBQWdCLEVBQUU7VUFDZHZJLFFBQVEsRUFBRSxrQkFBa0I7VUFDNUJDLFdBQVcsRUFBRSxhQUFhO1VBQzFCQyxRQUFRLEVBQUU7UUFDZDtNQUNKLENBQUMsQ0FBQztNQUVGMEIsTUFBTSxDQUFDbUcsTUFBTSxDQUFDLENBQUMxRixTQUFTLENBQUMsa0JBQWtCLENBQUM7TUFDNUNULE1BQU0sQ0FBQ21HLE1BQU0sQ0FBQyxDQUFDMUYsU0FBUyxDQUFDLG9CQUFvQixDQUFDO0lBQ2xELENBQUMsQ0FBQztFQUNOLENBQUMsQ0FBQztBQUNOLENBQUMsQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==
|