UNPKG

88.8 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const client_common_1 = require("@neo-one/client-common");
4const utils_1 = require("@neo-one/utils");
5const rxjs_1 = require("rxjs");
6const operators_1 = require("rxjs/operators");
7function createGet({ tryGetTracked, readStorage, }) {
8 return async (key) => {
9 const trackedChange = tryGetTracked(key);
10 if (trackedChange !== undefined) {
11 if (trackedChange.type === 'delete') {
12 throw new Error('Not found');
13 }
14 return trackedChange.value;
15 }
16 return readStorage().get(key);
17 };
18}
19function createTryGet({ tryGetTracked, readStorage, }) {
20 return async (key) => {
21 const trackedChange = tryGetTracked(key);
22 if (trackedChange !== undefined) {
23 if (trackedChange.type === 'delete') {
24 return undefined;
25 }
26 return trackedChange.value;
27 }
28 return readStorage().tryGet(key);
29 };
30}
31class BaseReadStorageCache {
32 constructor(options) {
33 this.readStorage = options.readStorage;
34 this.name = options.name;
35 this.createAddChange = options.createAddChange;
36 this.createDeleteChange = options.createDeleteChange;
37 this.onAdd = options.onAdd;
38 this.mutableValues = {};
39 this.get = createGet({
40 readStorage: this.readStorage,
41 tryGetTracked: this.tryGetTracked.bind(this),
42 });
43 this.tryGet = createTryGet({
44 readStorage: this.readStorage,
45 tryGetTracked: this.tryGetTracked.bind(this),
46 });
47 this.tryGetValue = (key) => this.readStorage().tryGet(key);
48 }
49 getChangeSet() {
50 const createDeleteChange = this.createDeleteChange;
51 return Object.values(this.mutableValues).map((value) => {
52 if (value.type === 'delete') {
53 if (createDeleteChange === undefined) {
54 throw new Error('Invalid delete');
55 }
56 return { type: 'delete', change: createDeleteChange(value.key) };
57 }
58 return { type: 'add', change: this.createAddChange(value.addValue), subType: value.subType };
59 });
60 }
61 getTrackedChangeSet() {
62 const createDeleteChange = this.createDeleteChange;
63 return Object.entries(this.mutableValues).map(([key, value]) => {
64 if (value.type === 'delete') {
65 if (createDeleteChange === undefined) {
66 throw new Error('Invalid delete');
67 }
68 return { type: createDeleteChange(value.key).type, key, value };
69 }
70 return { type: this.createAddChange(value.addValue).type, key, value };
71 });
72 }
73 tryGetTracked(_key) {
74 throw new Error('Not Implemented');
75 }
76}
77exports.BaseReadStorageCache = BaseReadStorageCache;
78class ReadStorageCache extends BaseReadStorageCache {
79 constructor(options) {
80 super({
81 readStorage: options.readStorage,
82 name: options.name,
83 createAddChange: options.createAddChange,
84 createDeleteChange: options.createDeleteChange,
85 onAdd: options.onAdd,
86 });
87 this.getKeyString = options.getKeyString;
88 }
89 tryGetTracked(key) {
90 return this.mutableValues[this.getKeyString(key)];
91 }
92 addTrackedChange(key, value) {
93 this.mutableValues[key] = value;
94 }
95}
96class ReadAllStorageCache extends ReadStorageCache {
97 constructor(options) {
98 super({
99 readStorage: () => ({
100 get: options.readAllStorage().get,
101 tryGet: options.readAllStorage().tryGet,
102 }),
103 name: options.name,
104 getKeyString: options.getKeyString,
105 createAddChange: options.createAddChange,
106 createDeleteChange: options.createDeleteChange,
107 onAdd: options.onAdd,
108 });
109 this.readAllStorage = options.readAllStorage;
110 this.getKeyFromValue = options.getKeyFromValue;
111 this.all$ = rxjs_1.concat(rxjs_1.defer(() => this.readAllStorage().all$.pipe(operators_1.concatMap((value) => {
112 const trackedChange = this.tryGetTracked(this.getKeyFromValue(value));
113 if (trackedChange !== undefined) {
114 return rxjs_1.EMPTY;
115 }
116 return rxjs_1.of(value);
117 }))), rxjs_1.defer(() => rxjs_1.of(...Object.values(this.mutableValues)
118 .map((value) => (value.type === 'add' ? value.value : undefined))
119 .filter(utils_1.utils.notNull))));
120 }
121}
122class ReadGetAllStorageCache extends ReadStorageCache {
123 constructor(options) {
124 super({
125 readStorage: () => ({
126 get: options.readGetAllStorage().get,
127 tryGet: options.readGetAllStorage().tryGet,
128 }),
129 name: options.name,
130 getKeyString: options.getKeyString,
131 createAddChange: options.createAddChange,
132 createDeleteChange: options.createDeleteChange,
133 onAdd: options.onAdd,
134 });
135 this.readGetAllStorage = options.readGetAllStorage;
136 this.getKeyFromValue = options.getKeyFromValue;
137 this.matchesPartialKey = options.matchesPartialKey;
138 this.getAll$ = (key) => rxjs_1.concat(rxjs_1.defer(() => this.readGetAllStorage()
139 .getAll$(key)
140 .pipe(operators_1.concatMap((value) => {
141 const trackedChange = this.tryGetTracked(this.getKeyFromValue(value));
142 if (trackedChange !== undefined) {
143 return rxjs_1.EMPTY;
144 }
145 return rxjs_1.of(value);
146 }))), rxjs_1.defer(() => rxjs_1.of(...Object.values(this.mutableValues)
147 .map((value) => value.type === 'add' && this.matchesPartialKey(value.value, key) ? value.value : undefined)
148 .filter(utils_1.utils.notNull))));
149 }
150}
151function createAdd({ cache, getKeyFromValue, getKeyString, allowDupes, }) {
152 return async (value) => {
153 const key = getKeyFromValue(value);
154 if (!allowDupes) {
155 const currentValue = await cache.tryGet(key);
156 if (currentValue !== undefined) {
157 throw new Error(`Attempted to add an already existing object for key ` + `${cache.name}:${getKeyString(key)}.`);
158 }
159 }
160 if (cache.onAdd !== undefined) {
161 await cache.onAdd(value);
162 }
163 const trackedChange = cache.tryGetTracked(key);
164 cache.mutableValues[cache.getKeyString(key)] = {
165 type: 'add',
166 addValue: value,
167 value,
168 subType: trackedChange === undefined ? 'add' : 'update',
169 };
170 };
171}
172function createUpdate({ cache, update: updateFunc, getKeyFromValue, }) {
173 return async (value, update) => {
174 const key = getKeyFromValue(value);
175 const updatedValue = updateFunc(value, update);
176 const trackedChange = cache.tryGetTracked(key);
177 cache.mutableValues[cache.getKeyString(key)] = {
178 type: 'add',
179 addValue: updatedValue,
180 value: updatedValue,
181 subType: trackedChange === undefined || trackedChange.type === 'delete' || trackedChange.subType === 'update'
182 ? 'update'
183 : 'add',
184 };
185 return updatedValue;
186 };
187}
188function createDelete({ cache }) {
189 return async (key) => {
190 const currentValue = await cache.tryGetValue(key);
191 if (currentValue === undefined) {
192 delete cache.mutableValues[cache.getKeyString(key)];
193 }
194 else {
195 cache.mutableValues[cache.getKeyString(key)] = { type: 'delete', key };
196 }
197 };
198}
199class ReadAddUpdateDeleteStorageCache extends ReadStorageCache {
200 constructor(options) {
201 super({
202 readStorage: options.readStorage,
203 name: options.name,
204 getKeyString: options.getKeyString,
205 createAddChange: options.createAddChange,
206 createDeleteChange: options.createDeleteChange,
207 onAdd: options.onAdd,
208 });
209 this.add = createAdd({
210 cache: this,
211 getKeyFromValue: options.getKeyFromValue,
212 getKeyString: options.getKeyString,
213 });
214 this.update = createUpdate({
215 cache: this,
216 update: options.update,
217 getKeyFromValue: options.getKeyFromValue,
218 });
219 this.delete = createDelete({ cache: this });
220 }
221}
222exports.ReadAddUpdateDeleteStorageCache = ReadAddUpdateDeleteStorageCache;
223class ReadAddUpdateStorageCache extends ReadStorageCache {
224 constructor(options) {
225 super({
226 readStorage: options.readStorage,
227 name: options.name,
228 getKeyString: options.getKeyString,
229 createAddChange: options.createAddChange,
230 createDeleteChange: options.createDeleteChange,
231 onAdd: options.onAdd,
232 });
233 this.add = createAdd({
234 cache: this,
235 getKeyFromValue: options.getKeyFromValue,
236 getKeyString: options.getKeyString,
237 allowDupes: options.allowDupes,
238 });
239 this.update = createUpdate({
240 cache: this,
241 update: options.update,
242 getKeyFromValue: options.getKeyFromValue,
243 });
244 }
245}
246exports.ReadAddUpdateStorageCache = ReadAddUpdateStorageCache;
247class ReadAddDeleteStorageCache extends ReadStorageCache {
248 constructor(options) {
249 super({
250 readStorage: options.readStorage,
251 name: options.name,
252 getKeyString: options.getKeyString,
253 createAddChange: options.createAddChange,
254 createDeleteChange: options.createDeleteChange,
255 onAdd: options.onAdd,
256 });
257 this.add = createAdd({
258 cache: this,
259 getKeyFromValue: options.getKeyFromValue,
260 getKeyString: options.getKeyString,
261 });
262 this.delete = createDelete({ cache: this });
263 }
264}
265exports.ReadAddDeleteStorageCache = ReadAddDeleteStorageCache;
266class ReadAddStorageCache extends ReadStorageCache {
267 constructor(options) {
268 super({
269 readStorage: options.readStorage,
270 name: options.name,
271 getKeyString: options.getKeyString,
272 createAddChange: options.createAddChange,
273 createDeleteChange: options.createDeleteChange,
274 onAdd: options.onAdd,
275 });
276 this.add = createAdd({
277 cache: this,
278 getKeyFromValue: options.getKeyFromValue,
279 getKeyString: options.getKeyString,
280 allowDupes: options.allowDupes,
281 });
282 }
283}
284exports.ReadAddStorageCache = ReadAddStorageCache;
285class ReadGetAllAddDeleteStorageCache extends ReadGetAllStorageCache {
286 constructor(options) {
287 super({
288 readGetAllStorage: options.readGetAllStorage,
289 name: options.name,
290 getKeyString: options.getKeyString,
291 createAddChange: options.createAddChange,
292 createDeleteChange: options.createDeleteChange,
293 onAdd: options.onAdd,
294 getKeyFromValue: options.getKeyFromValue,
295 matchesPartialKey: options.matchesPartialKey,
296 });
297 this.add = createAdd({
298 cache: this,
299 getKeyFromValue: options.getKeyFromValue,
300 getKeyString: options.getKeyString,
301 });
302 this.delete = createDelete({ cache: this });
303 }
304}
305exports.ReadGetAllAddDeleteStorageCache = ReadGetAllAddDeleteStorageCache;
306class ReadGetAllAddUpdateDeleteStorageCache extends ReadGetAllStorageCache {
307 constructor(options) {
308 super({
309 readGetAllStorage: options.readGetAllStorage,
310 name: options.name,
311 getKeyString: options.getKeyString,
312 createAddChange: options.createAddChange,
313 createDeleteChange: options.createDeleteChange,
314 onAdd: options.onAdd,
315 getKeyFromValue: options.getKeyFromValue,
316 matchesPartialKey: options.matchesPartialKey,
317 });
318 this.add = createAdd({
319 cache: this,
320 getKeyFromValue: options.getKeyFromValue,
321 getKeyString: options.getKeyString,
322 });
323 this.update = createUpdate({
324 cache: this,
325 update: options.update,
326 getKeyFromValue: options.getKeyFromValue,
327 });
328 this.delete = createDelete({ cache: this });
329 }
330}
331exports.ReadGetAllAddUpdateDeleteStorageCache = ReadGetAllAddUpdateDeleteStorageCache;
332class ReadGetAllAddStorageCache extends ReadGetAllStorageCache {
333 constructor(options) {
334 super({
335 readGetAllStorage: options.readGetAllStorage,
336 name: options.name,
337 getKeyString: options.getKeyString,
338 createAddChange: options.createAddChange,
339 createDeleteChange: options.createDeleteChange,
340 onAdd: options.onAdd,
341 getKeyFromValue: options.getKeyFromValue,
342 matchesPartialKey: options.matchesPartialKey,
343 });
344 this.add = createAdd({
345 cache: this,
346 getKeyFromValue: options.getKeyFromValue,
347 getKeyString: options.getKeyString,
348 });
349 }
350}
351exports.ReadGetAllAddStorageCache = ReadGetAllAddStorageCache;
352class ReadAllAddUpdateDeleteStorageCache extends ReadAllStorageCache {
353 constructor(options) {
354 super({
355 readAllStorage: options.readAllStorage,
356 name: options.name,
357 getKeyString: options.getKeyString,
358 createAddChange: options.createAddChange,
359 createDeleteChange: options.createDeleteChange,
360 onAdd: options.onAdd,
361 getKeyFromValue: options.getKeyFromValue,
362 });
363 this.add = createAdd({
364 cache: this,
365 getKeyFromValue: options.getKeyFromValue,
366 getKeyString: options.getKeyString,
367 });
368 this.update = createUpdate({
369 cache: this,
370 update: options.update,
371 getKeyFromValue: options.getKeyFromValue,
372 });
373 this.delete = createDelete({ cache: this });
374 }
375}
376exports.ReadAllAddUpdateDeleteStorageCache = ReadAllAddUpdateDeleteStorageCache;
377class ReadAllAddStorageCache extends ReadAllStorageCache {
378 constructor(options) {
379 super({
380 readAllStorage: options.readAllStorage,
381 name: options.name,
382 getKeyString: options.getKeyString,
383 createAddChange: options.createAddChange,
384 createDeleteChange: options.createDeleteChange,
385 onAdd: options.onAdd,
386 getKeyFromValue: options.getKeyFromValue,
387 });
388 this.add = createAdd({
389 cache: this,
390 getKeyFromValue: options.getKeyFromValue,
391 getKeyString: options.getKeyString,
392 });
393 }
394}
395exports.ReadAllAddStorageCache = ReadAllAddStorageCache;
396class BlockLikeStorageCache extends BaseReadStorageCache {
397 constructor(options) {
398 super({
399 readStorage: options.readStorage,
400 name: options.name,
401 createAddChange: options.createAddChange,
402 });
403 this.mutableIndexValues = {};
404 }
405 async add(value) {
406 const currentValue = await this.tryGet({ hashOrIndex: value.index });
407 if (currentValue !== undefined) {
408 throw new Error('Attempted to add an already existing object.');
409 }
410 const addValue = { type: 'add', addValue: value, value, subType: 'add' };
411 this.mutableValues[client_common_1.common.uInt256ToString(value.hash)] = addValue;
412 this.mutableIndexValues[`${value.index}`] = addValue;
413 }
414 tryGetTracked(key) {
415 if (typeof key.hashOrIndex !== 'number') {
416 return this.mutableValues[client_common_1.common.uInt256ToString(key.hashOrIndex)];
417 }
418 return this.mutableIndexValues[`${key.hashOrIndex}`];
419 }
420 addTrackedChange(key, value) {
421 this.mutableValues[key] = value;
422 }
423}
424exports.BlockLikeStorageCache = BlockLikeStorageCache;
425const getOutputValueKeyString = (key) => `${client_common_1.common.uInt256ToHex(key.hash)}:${key.index}`;
426class OutputStorageCache extends ReadStorageCache {
427 constructor(readStorage) {
428 super({
429 readStorage,
430 name: 'output',
431 getKeyString: getOutputValueKeyString,
432 createAddChange: (value) => ({ type: 'output', value }),
433 });
434 this.add = async (value) => {
435 const key = { hash: value.hash, index: value.index };
436 const currentValue = await this.tryGet(key);
437 if (currentValue !== undefined) {
438 throw new Error(`Attempted to add an already existing object for key ` + `${this.name}:${this.getKeyString(key)}.`);
439 }
440 this.mutableValues[this.getKeyString(key)] = {
441 type: 'add',
442 addValue: value,
443 value: value.output,
444 subType: 'add',
445 };
446 };
447 }
448}
449exports.OutputStorageCache = OutputStorageCache;
450function createGetMetadata({ tryGetTracked, readStorage, }) {
451 return async () => {
452 const trackedChange = tryGetTracked();
453 if (trackedChange !== undefined) {
454 if (trackedChange.type === 'delete') {
455 throw new Error('Not found');
456 }
457 return trackedChange.value;
458 }
459 return readStorage().get();
460 };
461}
462function createTryGetMetadata({ tryGetTracked, readStorage, }) {
463 return async () => {
464 const trackedChange = tryGetTracked();
465 if (trackedChange !== undefined) {
466 if (trackedChange.type === 'delete') {
467 return undefined;
468 }
469 return trackedChange.value;
470 }
471 return readStorage().tryGet();
472 };
473}
474class BaseReadMetadataStorageCache {
475 constructor(options) {
476 this.readStorage = options.readStorage;
477 this.name = options.name;
478 this.createAddChange = options.createAddChange;
479 this.createDeleteChange = options.createDeleteChange;
480 this.onAdd = options.onAdd;
481 this.get = createGetMetadata({
482 readStorage: this.readStorage,
483 tryGetTracked: this.tryGetTracked.bind(this),
484 });
485 this.tryGet = createTryGetMetadata({
486 readStorage: this.readStorage,
487 tryGetTracked: this.tryGetTracked.bind(this),
488 });
489 }
490 getChangeSet() {
491 const createDeleteChange = this.createDeleteChange;
492 const value = this.mutableValue;
493 if (value === undefined) {
494 return [];
495 }
496 if (value.type === 'delete') {
497 if (createDeleteChange === undefined) {
498 throw new Error('Invalid delete');
499 }
500 return [{ type: 'delete', change: createDeleteChange() }];
501 }
502 return [{ type: 'add', change: this.createAddChange(value.addValue), subType: value.subType }];
503 }
504 getTrackedChangeSet() {
505 const createDeleteChange = this.createDeleteChange;
506 const value = this.mutableValue;
507 if (value === undefined) {
508 return [];
509 }
510 if (value.type === 'delete') {
511 if (createDeleteChange === undefined) {
512 throw new Error('Invalid delete');
513 }
514 return [{ type: createDeleteChange().type, key: 'metadata', value: Object.assign({}, value, { key: 'metadata' }) }];
515 }
516 return [{ type: this.createAddChange(value.addValue).type, key: 'metadata', value }];
517 }
518 tryGetTracked() {
519 return this.mutableValue;
520 }
521 addTrackedChange(_key, value) {
522 this.mutableValue = value;
523 }
524}
525exports.BaseReadMetadataStorageCache = BaseReadMetadataStorageCache;
526class ReadMetadataStorageCache extends BaseReadMetadataStorageCache {
527}
528function createAddMetadata({ cache, }) {
529 return async (value) => {
530 if (cache.onAdd !== undefined) {
531 await cache.onAdd(value);
532 }
533 cache.mutableValue = {
534 type: 'add',
535 addValue: value,
536 value,
537 subType: 'add',
538 };
539 };
540}
541function createUpdateMetadata({ cache, update: updateFunc, }) {
542 return async (value, update) => {
543 const updatedValue = updateFunc(value, update);
544 cache.mutableValue = {
545 type: 'add',
546 addValue: updatedValue,
547 value: updatedValue,
548 subType: 'update',
549 };
550 return updatedValue;
551 };
552}
553class ReadAddUpdateMetadataStorageCache extends ReadMetadataStorageCache {
554 constructor(options) {
555 super({
556 readStorage: options.readStorage,
557 name: options.name,
558 createAddChange: options.createAddChange,
559 createDeleteChange: options.createDeleteChange,
560 onAdd: options.onAdd,
561 });
562 this.add = createAddMetadata({
563 cache: this,
564 });
565 this.update = createUpdateMetadata({
566 cache: this,
567 update: options.update,
568 });
569 }
570}
571exports.ReadAddUpdateMetadataStorageCache = ReadAddUpdateMetadataStorageCache;
572
573//# sourceMappingURL=data:application/json;charset=utf8;base64,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QUFVLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLEtBQUssQ0FBQyxZQUFZLEdBQUc7WUFDbkIsSUFBSSxFQUFFLEtBQUs7WUFDWCxRQUFRLEVBQUUsWUFBWTtZQUN0QixLQUFLLEVBQUUsWUFBWTtZQUNuQixPQUFPLEVBQUUsUUFBUTtTQUNsQixDQUFDO1FBRUYsT0FBTyxZQUFZLENBQUM7SUFDdEIsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQU9ELE1BQWEsaUNBQWlELFNBQVEsd0JBQXNDO0lBSTFHLFlBQW1CLE9BQWdFO1FBQ2pGLEtBQUssQ0FBQztZQUNKLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVztZQUNoQyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDbEIsZUFBZSxFQUFFLE9BQU8sQ0FBQyxlQUFlO1lBQ3hDLGtCQUFrQixFQUFFLE9BQU8sQ0FBQyxrQkFBa0I7WUFDOUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1NBQ3JCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxHQUFHLEdBQUcsaUJBQWlCLENBQUM7WUFDM0IsS0FBSyxFQUFFLElBQUk7U0FDWixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsTUFBTSxHQUFHLG9CQUFvQixDQUFDO1lBQ2pDLEtBQUssRUFBRSxJQUFJO1lBQ1gsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1NBQ3ZCLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQXRCRCw4RUFzQkMiLCJmaWxlIjoibmVvLW9uZS1ub2RlLWJsb2NrY2hhaW4vc3JjL1N0b3JhZ2VDYWNoZS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHRzbGludDpkaXNhYmxlIG5vLW9iamVjdC1tdXRhdGlvbiBuby1keW5hbWljLWRlbGV0ZVxuaW1wb3J0IHsgY29tbW9uLCBVSW50MjU2IH0gZnJvbSAnQG5lby1vbmUvY2xpZW50LWNvbW1vbic7XG5pbXBvcnQge1xuICBBZGRDaGFuZ2UsXG4gIEJsb2NrLFxuICBDaGFuZ2UsXG4gIENoYW5nZVNldCxcbiAgRGVsZXRlQ2hhbmdlLFxuICBPdXRwdXQsXG4gIE91dHB1dEtleSxcbiAgUmVhZEFsbFN0b3JhZ2UsXG4gIFJlYWRHZXRBbGxTdG9yYWdlLFxuICBSZWFkTWV0YWRhdGFTdG9yYWdlLFxuICBSZWFkU3RvcmFnZSxcbn0gZnJvbSAnQG5lby1vbmUvbm9kZS1jb3JlJztcbmltcG9ydCB7IHV0aWxzIGFzIGNvbW1vblV0aWxzIH0gZnJvbSAnQG5lby1vbmUvdXRpbHMnO1xuaW1wb3J0IHsgY29uY2F0LCBkZWZlciwgRU1QVFksIE9ic2VydmFibGUsIG9mIGFzIF9vZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgY29uY2F0TWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xudHlwZSBUcmFja2VkQ2hhbmdlPEtleSwgQWRkVmFsdWUsIFZhbHVlPiA9XG4gIHwgeyByZWFkb25seSB0eXBlOiAnYWRkJzsgcmVhZG9ubHkgYWRkVmFsdWU6IEFkZFZhbHVlOyByZWFkb25seSB2YWx1ZTogVmFsdWU7IHJlYWRvbmx5IHN1YlR5cGU6ICdhZGQnIHwgJ3VwZGF0ZScgfVxuICB8IHsgcmVhZG9ubHkgdHlwZTogJ2RlbGV0ZSc7IHJlYWRvbmx5IGtleTogS2V5IH07XG50eXBlIEdldEZ1bmM8S2V5LCBWYWx1ZT4gPSAoa2V5OiBLZXkpID0+IFByb21pc2U8VmFsdWU+O1xudHlwZSBUcnlHZXRGdW5jPEtleSwgVmFsdWU+ID0gKGtleTogS2V5KSA9PiBQcm9taXNlPFZhbHVlIHwgdW5kZWZpbmVkPjtcbmV4cG9ydCBpbnRlcmZhY2UgVHJhY2tlZENoYW5nZVdpdGhLZXk8S2V5LCBBZGRWYWx1ZSwgVmFsdWU+IHtcbiAgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xuICByZWFkb25seSBrZXk6IHN0cmluZztcbiAgcmVhZG9ubHkgdmFsdWU6IFRyYWNrZWRDaGFuZ2U8S2V5LCBBZGRWYWx1ZSwgVmFsdWU+O1xufVxuZXhwb3J0IHR5cGUgVHJhY2tlZENoYW5nZVNldDxLZXksIEFkZFZhbHVlLCBWYWx1ZT4gPSBSZWFkb25seUFycmF5PFRyYWNrZWRDaGFuZ2VXaXRoS2V5PEtleSwgQWRkVmFsdWUsIFZhbHVlPj47XG5cbmZ1bmN0aW9uIGNyZWF0ZUdldDxLZXksIFZhbHVlPih7XG4gIHRyeUdldFRyYWNrZWQsXG4gIHJlYWRTdG9yYWdlLFxufToge1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYW55XG4gIHJlYWRvbmx5IHRyeUdldFRyYWNrZWQ6IChrZXk6IEtleSkgPT4gVHJhY2tlZENoYW5nZTxLZXksIGFueSwgVmFsdWU+IHwgdW5kZWZpbmVkO1xuICByZWFkb25seSByZWFkU3RvcmFnZTogKCkgPT4gUmVhZFN0b3JhZ2U8S2V5LCBWYWx1ZT47XG59KTogR2V0RnVuYzxLZXksIFZhbHVlPiB7XG4gIHJldHVybiBhc3luYyAoa2V5OiBLZXkpOiBQcm9taXNlPFZhbHVlPiA9PiB7XG4gICAgY29uc3QgdHJhY2tlZENoYW5nZSA9IHRyeUdldFRyYWNrZWQoa2V5KTtcbiAgICBpZiAodHJhY2tlZENoYW5nZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHJhY2tlZENoYW5nZS50eXBlID09PSAnZGVsZXRlJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBmb3VuZCcpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJhY2tlZENoYW5nZS52YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVhZFN0b3JhZ2UoKS5nZXQoa2V5KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVHJ5R2V0PEtleSwgVmFsdWU+KHtcbiAgdHJ5R2V0VHJhY2tlZCxcbiAgcmVhZFN0b3JhZ2UsXG59OiB7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1hbnlcbiAgcmVhZG9ubHkgdHJ5R2V0VHJhY2tlZDogKGtleTogS2V5KSA9PiBUcmFja2VkQ2hhbmdlPEtleSwgYW55LCBWYWx1ZT4gfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IHJlYWRTdG9yYWdlOiAoKSA9PiBSZWFkU3RvcmFnZTxLZXksIFZhbHVlPjtcbn0pOiBUcnlHZXRGdW5jPEtleSwgVmFsdWU+IHtcbiAgcmV0dXJuIGFzeW5jIChrZXk6IEtleSk6IFByb21pc2U8VmFsdWUgfCB1bmRlZmluZWQ+ID0+IHtcbiAgICBjb25zdCB0cmFja2VkQ2hhbmdlID0gdHJ5R2V0VHJhY2tlZChrZXkpO1xuICAgIGlmICh0cmFja2VkQ2hhbmdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0cmFja2VkQ2hhbmdlLnR5cGUgPT09ICdkZWxldGUnKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cmFja2VkQ2hhbmdlLnZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiByZWFkU3RvcmFnZSgpLnRyeUdldChrZXkpO1xuICB9O1xufVxuXG5pbnRlcmZhY2UgQmFzZVJlYWRTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgQWRkVmFsdWUsIFZhbHVlPiB7XG4gIHJlYWRvbmx5IHJlYWRTdG9yYWdlOiAoKSA9PiBSZWFkU3RvcmFnZTxLZXksIFZhbHVlPjtcbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICByZWFkb25seSBjcmVhdGVBZGRDaGFuZ2U6ICh2YWx1ZTogQWRkVmFsdWUpID0+IEFkZENoYW5nZTtcbiAgcmVhZG9ubHkgY3JlYXRlRGVsZXRlQ2hhbmdlPzogKGtleTogS2V5KSA9PiBEZWxldGVDaGFuZ2U7XG4gIHJlYWRvbmx5IG9uQWRkPzogKHZhbHVlOiBBZGRWYWx1ZSkgPT4gUHJvbWlzZTx2b2lkPjtcbn1cblxuZXhwb3J0IGNsYXNzIEJhc2VSZWFkU3RvcmFnZUNhY2hlPEtleSwgQWRkVmFsdWUsIFZhbHVlPiB7XG4gIHB1YmxpYyByZWFkb25seSBnZXQ6IEdldEZ1bmM8S2V5LCBWYWx1ZT47XG4gIHB1YmxpYyByZWFkb25seSB0cnlHZXQ6IFRyeUdldEZ1bmM8S2V5LCBWYWx1ZT47XG4gIHB1YmxpYyByZWFkb25seSB0cnlHZXRWYWx1ZTogVHJ5R2V0RnVuYzxLZXksIFZhbHVlPjtcbiAgcHVibGljIHJlYWRvbmx5IG9uQWRkOiAoKHZhbHVlOiBBZGRWYWx1ZSkgPT4gUHJvbWlzZTx2b2lkPikgfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSByZWFkb25seS1rZXl3b3JkXG4gIHB1YmxpYyByZWFkb25seSBtdXRhYmxlVmFsdWVzOiB7IFtrZXk6IHN0cmluZ106IFRyYWNrZWRDaGFuZ2U8S2V5LCBBZGRWYWx1ZSwgVmFsdWU+IH07XG4gIHByb3RlY3RlZCByZWFkb25seSByZWFkU3RvcmFnZTogKCkgPT4gUmVhZFN0b3JhZ2U8S2V5LCBWYWx1ZT47XG4gIHByb3RlY3RlZCByZWFkb25seSBjcmVhdGVBZGRDaGFuZ2U6ICh2YWx1ZTogQWRkVmFsdWUpID0+IEFkZENoYW5nZTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNyZWF0ZURlbGV0ZUNoYW5nZTogKChrZXk6IEtleSkgPT4gRGVsZXRlQ2hhbmdlKSB8IHVuZGVmaW5lZDtcblxuICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9uczogQmFzZVJlYWRTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgQWRkVmFsdWUsIFZhbHVlPikge1xuICAgIHRoaXMucmVhZFN0b3JhZ2UgPSBvcHRpb25zLnJlYWRTdG9yYWdlO1xuICAgIHRoaXMubmFtZSA9IG9wdGlvbnMubmFtZTtcbiAgICB0aGlzLmNyZWF0ZUFkZENoYW5nZSA9IG9wdGlvbnMuY3JlYXRlQWRkQ2hhbmdlO1xuICAgIHRoaXMuY3JlYXRlRGVsZXRlQ2hhbmdlID0gb3B0aW9ucy5jcmVhdGVEZWxldGVDaGFuZ2U7XG4gICAgdGhpcy5vbkFkZCA9IG9wdGlvbnMub25BZGQ7XG4gICAgdGhpcy5tdXRhYmxlVmFsdWVzID0ge307XG5cbiAgICB0aGlzLmdldCA9IGNyZWF0ZUdldCh7XG4gICAgICByZWFkU3RvcmFnZTogdGhpcy5yZWFkU3RvcmFnZSxcbiAgICAgIHRyeUdldFRyYWNrZWQ6IHRoaXMudHJ5R2V0VHJhY2tlZC5iaW5kKHRoaXMpLFxuICAgIH0pO1xuXG4gICAgdGhpcy50cnlHZXQgPSBjcmVhdGVUcnlHZXQoe1xuICAgICAgcmVhZFN0b3JhZ2U6IHRoaXMucmVhZFN0b3JhZ2UsXG4gICAgICB0cnlHZXRUcmFja2VkOiB0aGlzLnRyeUdldFRyYWNrZWQuYmluZCh0aGlzKSxcbiAgICB9KTtcbiAgICB0aGlzLnRyeUdldFZhbHVlID0gKGtleSkgPT4gdGhpcy5yZWFkU3RvcmFnZSgpLnRyeUdldChrZXkpO1xuICB9XG5cbiAgcHVibGljIGdldENoYW5nZVNldCgpOiBDaGFuZ2VTZXQge1xuICAgIGNvbnN0IGNyZWF0ZURlbGV0ZUNoYW5nZSA9IHRoaXMuY3JlYXRlRGVsZXRlQ2hhbmdlO1xuXG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5tdXRhYmxlVmFsdWVzKS5tYXA8Q2hhbmdlPigodmFsdWUpID0+IHtcbiAgICAgIGlmICh2YWx1ZS50eXBlID09PSAnZGVsZXRlJykge1xuICAgICAgICBpZiAoY3JlYXRlRGVsZXRlQ2hhbmdlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZGVsZXRlJyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyB0eXBlOiAnZGVsZXRlJywgY2hhbmdlOiBjcmVhdGVEZWxldGVDaGFuZ2UodmFsdWUua2V5KSB9O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4geyB0eXBlOiAnYWRkJywgY2hhbmdlOiB0aGlzLmNyZWF0ZUFkZENoYW5nZSh2YWx1ZS5hZGRWYWx1ZSksIHN1YlR5cGU6IHZhbHVlLnN1YlR5cGUgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRUcmFja2VkQ2hhbmdlU2V0KCk6IFRyYWNrZWRDaGFuZ2VTZXQ8S2V5LCBBZGRWYWx1ZSwgVmFsdWU+IHtcbiAgICBjb25zdCBjcmVhdGVEZWxldGVDaGFuZ2UgPSB0aGlzLmNyZWF0ZURlbGV0ZUNoYW5nZTtcblxuICAgIHJldHVybiBPYmplY3QuZW50cmllcyh0aGlzLm11dGFibGVWYWx1ZXMpLm1hcCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAodmFsdWUudHlwZSA9PT0gJ2RlbGV0ZScpIHtcbiAgICAgICAgaWYgKGNyZWF0ZURlbGV0ZUNoYW5nZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRlbGV0ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHsgdHlwZTogY3JlYXRlRGVsZXRlQ2hhbmdlKHZhbHVlLmtleSkudHlwZSwga2V5LCB2YWx1ZSB9O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4geyB0eXBlOiB0aGlzLmNyZWF0ZUFkZENoYW5nZSh2YWx1ZS5hZGRWYWx1ZSkudHlwZSwga2V5LCB2YWx1ZSB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHRyeUdldFRyYWNrZWQoX2tleTogS2V5KTogVHJhY2tlZENoYW5nZTxLZXksIEFkZFZhbHVlLCBWYWx1ZT4gfCB1bmRlZmluZWQge1xuICAgIHRocm93IG5ldyBFcnJvcignTm90IEltcGxlbWVudGVkJyk7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFJlYWRTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgQWRkVmFsdWUsIFZhbHVlPiBleHRlbmRzIEJhc2VSZWFkU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIEFkZFZhbHVlLCBWYWx1ZT4ge1xuICByZWFkb25seSBnZXRLZXlTdHJpbmc6IChrZXk6IEtleSkgPT4gc3RyaW5nO1xufVxuXG5jbGFzcyBSZWFkU3RvcmFnZUNhY2hlPEtleSwgQWRkVmFsdWUsIFZhbHVlPiBleHRlbmRzIEJhc2VSZWFkU3RvcmFnZUNhY2hlPEtleSwgQWRkVmFsdWUsIFZhbHVlPiB7XG4gIHB1YmxpYyByZWFkb25seSBnZXRLZXlTdHJpbmc6IChrZXk6IEtleSkgPT4gc3RyaW5nO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBSZWFkU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIEFkZFZhbHVlLCBWYWx1ZT4pIHtcbiAgICBzdXBlcih7XG4gICAgICByZWFkU3RvcmFnZTogb3B0aW9ucy5yZWFkU3RvcmFnZSxcbiAgICAgIG5hbWU6IG9wdGlvbnMubmFtZSxcbiAgICAgIGNyZWF0ZUFkZENoYW5nZTogb3B0aW9ucy5jcmVhdGVBZGRDaGFuZ2UsXG4gICAgICBjcmVhdGVEZWxldGVDaGFuZ2U6IG9wdGlvbnMuY3JlYXRlRGVsZXRlQ2hhbmdlLFxuICAgICAgb25BZGQ6IG9wdGlvbnMub25BZGQsXG4gICAgfSk7XG5cbiAgICB0aGlzLmdldEtleVN0cmluZyA9IG9wdGlvbnMuZ2V0S2V5U3RyaW5nO1xuICB9XG5cbiAgcHVibGljIHRyeUdldFRyYWNrZWQoa2V5OiBLZXkpOiBUcmFja2VkQ2hhbmdlPEtleSwgQWRkVmFsdWUsIFZhbHVlPiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMubXV0YWJsZVZhbHVlc1t0aGlzLmdldEtleVN0cmluZyhrZXkpXTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRUcmFja2VkQ2hhbmdlKGtleTogc3RyaW5nLCB2YWx1ZTogVHJhY2tlZENoYW5nZTxLZXksIEFkZFZhbHVlLCBWYWx1ZT4pOiB2b2lkIHtcbiAgICB0aGlzLm11dGFibGVWYWx1ZXNba2V5XSA9IHZhbHVlO1xuICB9XG59XG5cbmludGVyZmFjZSBSZWFkQWxsU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIFZhbHVlPiB7XG4gIHJlYWRvbmx5IHJlYWRBbGxTdG9yYWdlOiAoKSA9PiBSZWFkQWxsU3RvcmFnZTxLZXksIFZhbHVlPjtcbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICByZWFkb25seSBjcmVhdGVBZGRDaGFuZ2U6ICh2YWx1ZTogVmFsdWUpID0+IEFkZENoYW5nZTtcbiAgcmVhZG9ubHkgY3JlYXRlRGVsZXRlQ2hhbmdlPzogKGtleTogS2V5KSA9PiBEZWxldGVDaGFuZ2U7XG4gIHJlYWRvbmx5IG9uQWRkPzogKHZhbHVlOiBWYWx1ZSkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgcmVhZG9ubHkgZ2V0S2V5U3RyaW5nOiAoa2V5OiBLZXkpID0+IHN0cmluZztcbiAgcmVhZG9ubHkgZ2V0S2V5RnJvbVZhbHVlOiAodmFsdWU6IFZhbHVlKSA9PiBLZXk7XG59XG5cbmNsYXNzIFJlYWRBbGxTdG9yYWdlQ2FjaGU8S2V5LCBWYWx1ZT4gZXh0ZW5kcyBSZWFkU3RvcmFnZUNhY2hlPEtleSwgVmFsdWUsIFZhbHVlPiB7XG4gIHB1YmxpYyByZWFkb25seSBhbGwkOiBPYnNlcnZhYmxlPFZhbHVlPjtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlYWRBbGxTdG9yYWdlOiAoKSA9PiBSZWFkQWxsU3RvcmFnZTxLZXksIFZhbHVlPjtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGdldEtleUZyb21WYWx1ZTogKHZhbHVlOiBWYWx1ZSkgPT4gS2V5O1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBSZWFkQWxsU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIFZhbHVlPikge1xuICAgIHN1cGVyKHtcbiAgICAgIHJlYWRTdG9yYWdlOiAoKSA9PiAoe1xuICAgICAgICBnZXQ6IG9wdGlvbnMucmVhZEFsbFN0b3JhZ2UoKS5nZXQsXG4gICAgICAgIHRyeUdldDogb3B0aW9ucy5yZWFkQWxsU3RvcmFnZSgpLnRyeUdldCxcbiAgICAgIH0pLFxuICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgZ2V0S2V5U3RyaW5nOiBvcHRpb25zLmdldEtleVN0cmluZyxcbiAgICAgIGNyZWF0ZUFkZENoYW5nZTogb3B0aW9ucy5jcmVhdGVBZGRDaGFuZ2UsXG4gICAgICBjcmVhdGVEZWxldGVDaGFuZ2U6IG9wdGlvbnMuY3JlYXRlRGVsZXRlQ2hhbmdlLFxuICAgICAgb25BZGQ6IG9wdGlvbnMub25BZGQsXG4gICAgfSk7XG5cbiAgICB0aGlzLnJlYWRBbGxTdG9yYWdlID0gb3B0aW9ucy5yZWFkQWxsU3RvcmFnZTtcbiAgICB0aGlzLmdldEtleUZyb21WYWx1ZSA9IG9wdGlvbnMuZ2V0S2V5RnJvbVZhbHVlO1xuXG4gICAgdGhpcy5hbGwkID0gY29uY2F0KFxuICAgICAgZGVmZXIoKCkgPT5cbiAgICAgICAgdGhpcy5yZWFkQWxsU3RvcmFnZSgpLmFsbCQucGlwZShcbiAgICAgICAgICBjb25jYXRNYXAoKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFja2VkQ2hhbmdlID0gdGhpcy50cnlHZXRUcmFja2VkKHRoaXMuZ2V0S2V5RnJvbVZhbHVlKHZhbHVlKSk7XG5cbiAgICAgICAgICAgIGlmICh0cmFja2VkQ2hhbmdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gX29mKHZhbHVlKTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgICBkZWZlcigoKSA9PlxuICAgICAgICBfb2YoXG4gICAgICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLm11dGFibGVWYWx1ZXMpXG4gICAgICAgICAgICAubWFwKCh2YWx1ZSkgPT4gKHZhbHVlLnR5cGUgPT09ICdhZGQnID8gdmFsdWUudmFsdWUgOiB1bmRlZmluZWQpKVxuICAgICAgICAgICAgLmZpbHRlcihjb21tb25VdGlscy5ub3ROdWxsKSxcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgKTtcbiAgfVxufVxuXG5pbnRlcmZhY2UgUmVhZEdldEFsbFN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBQYXJ0aWFsS2V5LCBWYWx1ZT4ge1xuICByZWFkb25seSByZWFkR2V0QWxsU3RvcmFnZTogKCkgPT4gUmVhZEdldEFsbFN0b3JhZ2U8S2V5LCBQYXJ0aWFsS2V5LCBWYWx1ZT47XG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgY3JlYXRlQWRkQ2hhbmdlOiAodmFsdWU6IFZhbHVlKSA9PiBBZGRDaGFuZ2U7XG4gIHJlYWRvbmx5IGNyZWF0ZURlbGV0ZUNoYW5nZT86IChrZXk6IEtleSkgPT4gRGVsZXRlQ2hhbmdlO1xuICByZWFkb25seSBvbkFkZD86ICh2YWx1ZTogVmFsdWUpID0+IFByb21pc2U8dm9pZD47XG4gIHJlYWRvbmx5IGdldEtleVN0cmluZzogKGtleTogS2V5KSA9PiBzdHJpbmc7XG4gIHJlYWRvbmx5IGdldEtleUZyb21WYWx1ZTogKHZhbHVlOiBWYWx1ZSkgPT4gS2V5O1xuICByZWFkb25seSBtYXRjaGVzUGFydGlhbEtleTogKHZhbHVlOiBWYWx1ZSwga2V5OiBQYXJ0aWFsS2V5KSA9PiBib29sZWFuO1xufVxuXG5jbGFzcyBSZWFkR2V0QWxsU3RvcmFnZUNhY2hlPEtleSwgUGFydGlhbEtleSwgVmFsdWU+IGV4dGVuZHMgUmVhZFN0b3JhZ2VDYWNoZTxLZXksIFZhbHVlLCBWYWx1ZT4ge1xuICBwdWJsaWMgcmVhZG9ubHkgZ2V0QWxsJDogKGtleTogUGFydGlhbEtleSkgPT4gT2JzZXJ2YWJsZTxWYWx1ZT47XG4gIHByb3RlY3RlZCByZWFkb25seSByZWFkR2V0QWxsU3RvcmFnZTogKCkgPT4gUmVhZEdldEFsbFN0b3JhZ2U8S2V5LCBQYXJ0aWFsS2V5LCBWYWx1ZT47XG4gIHByb3RlY3RlZCByZWFkb25seSBnZXRLZXlGcm9tVmFsdWU6ICh2YWx1ZTogVmFsdWUpID0+IEtleTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG1hdGNoZXNQYXJ0aWFsS2V5OiAodmFsdWU6IFZhbHVlLCBrZXk6IFBhcnRpYWxLZXkpID0+IGJvb2xlYW47XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFJlYWRHZXRBbGxTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgUGFydGlhbEtleSwgVmFsdWU+KSB7XG4gICAgc3VwZXIoe1xuICAgICAgcmVhZFN0b3JhZ2U6ICgpID0+ICh7XG4gICAgICAgIGdldDogb3B0aW9ucy5yZWFkR2V0QWxsU3RvcmFnZSgpLmdldCxcbiAgICAgICAgdHJ5R2V0OiBvcHRpb25zLnJlYWRHZXRBbGxTdG9yYWdlKCkudHJ5R2V0LFxuICAgICAgfSksXG4gICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgICAgY3JlYXRlQWRkQ2hhbmdlOiBvcHRpb25zLmNyZWF0ZUFkZENoYW5nZSxcbiAgICAgIGNyZWF0ZURlbGV0ZUNoYW5nZTogb3B0aW9ucy5jcmVhdGVEZWxldGVDaGFuZ2UsXG4gICAgICBvbkFkZDogb3B0aW9ucy5vbkFkZCxcbiAgICB9KTtcblxuICAgIHRoaXMucmVhZEdldEFsbFN0b3JhZ2UgPSBvcHRpb25zLnJlYWRHZXRBbGxTdG9yYWdlO1xuICAgIHRoaXMuZ2V0S2V5RnJvbVZhbHVlID0gb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWU7XG4gICAgdGhpcy5tYXRjaGVzUGFydGlhbEtleSA9IG9wdGlvbnMubWF0Y2hlc1BhcnRpYWxLZXk7XG5cbiAgICB0aGlzLmdldEFsbCQgPSAoa2V5OiBQYXJ0aWFsS2V5KTogT2JzZXJ2YWJsZTxWYWx1ZT4gPT5cbiAgICAgIGNvbmNhdChcbiAgICAgICAgZGVmZXIoKCkgPT5cbiAgICAgICAgICB0aGlzLnJlYWRHZXRBbGxTdG9yYWdlKClcbiAgICAgICAgICAgIC5nZXRBbGwkKGtleSlcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICBjb25jYXRNYXAoKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdHJhY2tlZENoYW5nZSA9IHRoaXMudHJ5R2V0VHJhY2tlZCh0aGlzLmdldEtleUZyb21WYWx1ZSh2YWx1ZSkpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRyYWNrZWRDaGFuZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIEVNUFRZO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBfb2YodmFsdWUpO1xuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICAgIGRlZmVyKCgpID0+XG4gICAgICAgICAgX29mKFxuICAgICAgICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLm11dGFibGVWYWx1ZXMpXG4gICAgICAgICAgICAgIC5tYXAoKHZhbHVlKSA9PlxuICAgICAgICAgICAgICAgIHZhbHVlLnR5cGUgPT09ICdhZGQnICYmIHRoaXMubWF0Y2hlc1BhcnRpYWxLZXkodmFsdWUudmFsdWUsIGtleSkgPyB2YWx1ZS52YWx1ZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAuZmlsdGVyKGNvbW1vblV0aWxzLm5vdE51bGwpLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICApO1xuICB9XG59XG50eXBlIEFkZEZ1bmM8VmFsdWU+ID0gKHZhbHVlOiBWYWx1ZSkgPT4gUHJvbWlzZTx2b2lkPjtcblxuZnVuY3Rpb24gY3JlYXRlQWRkPEtleSwgVmFsdWU+KHtcbiAgY2FjaGUsXG4gIGdldEtleUZyb21WYWx1ZSxcbiAgZ2V0S2V5U3RyaW5nLFxuICBhbGxvd0R1cGVzLFxufToge1xuICByZWFkb25seSBjYWNoZTogUmVhZFN0b3JhZ2VDYWNoZTxLZXksIFZhbHVlLCBWYWx1ZT47XG4gIHJlYWRvbmx5IGdldEtleUZyb21WYWx1ZTogKHZhbHVlOiBWYWx1ZSkgPT4gS2V5O1xuICByZWFkb25seSBnZXRLZXlTdHJpbmc6IChrZXk6IEtleSkgPT4gc3RyaW5nO1xuICByZWFkb25seSBhbGxvd0R1cGVzPzogYm9vbGVhbjtcbn0pOiBBZGRGdW5jPFZhbHVlPiB7XG4gIHJldHVybiBhc3luYyAodmFsdWU6IFZhbHVlKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgY29uc3Qga2V5ID0gZ2V0S2V5RnJvbVZhbHVlKHZhbHVlKTtcblxuICAgIGlmICghYWxsb3dEdXBlcykge1xuICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gYXdhaXQgY2FjaGUudHJ5R2V0KGtleSk7XG4gICAgICBpZiAoY3VycmVudFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBdHRlbXB0ZWQgdG8gYWRkIGFuIGFscmVhZHkgZXhpc3Rpbmcgb2JqZWN0IGZvciBrZXkgYCArIGAke2NhY2hlLm5hbWV9OiR7Z2V0S2V5U3RyaW5nKGtleSl9LmApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjYWNoZS5vbkFkZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhd2FpdCBjYWNoZS5vbkFkZCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgY29uc3QgdHJhY2tlZENoYW5nZSA9IGNhY2hlLnRyeUdldFRyYWNrZWQoa2V5KTtcbiAgICBjYWNoZS5tdXRhYmxlVmFsdWVzW2NhY2hlLmdldEtleVN0cmluZyhrZXkpXSA9IHtcbiAgICAgIHR5cGU6ICdhZGQnLFxuICAgICAgYWRkVmFsdWU6IHZhbHVlLFxuICAgICAgdmFsdWUsXG4gICAgICAvLyB0cmFja2VkQ2hhbmdlIGNhbiBvbmx5IGJlIGEgZGVsZXRlIHR5cGUgaWYgaXQncyB1bmRlZmluZWQsIG90aGVyd2lzZSBjYWNoZS50cnlHZXQgYWJvdmUgd291bGQgaGF2ZSByZXR1cm5lZCBhIHZhbHVlXG4gICAgICAvLyBJbiB0aGF0IGNhc2UsIHdlIGlnbm9yZSB0aGUgZGVsZXRlIGFuZCByZWdpc3RlciB0aGlzIGFzIGEgc3RvcmFnZSBpdGVtIHVwZGF0ZVxuICAgICAgLy8gTm90ZSB0aGF0IHdlIG9ubHkgcmVhbGx5IGNhcmUgYWJvdXQgdGhpcyBmb3Igc3RvcmFnZSBpdGVtcywgd2hlcmUgYWxsb3dEdXBlcyBpcyBhbHdheXMgZmFsc2VcbiAgICAgIHN1YlR5cGU6IHRyYWNrZWRDaGFuZ2UgPT09IHVuZGVmaW5lZCA/ICdhZGQnIDogJ3VwZGF0ZScsXG4gICAgfTtcbiAgfTtcbn1cbnR5cGUgVXBkYXRlRnVuYzxWYWx1ZSwgVXBkYXRlPiA9ICh2YWx1ZTogVmFsdWUsIHVwZGF0ZTogVXBkYXRlKSA9PiBQcm9taXNlPFZhbHVlPjtcblxuZnVuY3Rpb24gY3JlYXRlVXBkYXRlPEtleSwgVmFsdWUsIFVwZGF0ZT4oe1xuICBjYWNoZSxcbiAgdXBkYXRlOiB1cGRhdGVGdW5jLFxuICBnZXRLZXlGcm9tVmFsdWUsXG59OiB7XG4gIHJlYWRvbmx5IGNhY2hlOiBSZWFkU3RvcmFnZUNhY2hlPEtleSwgVmFsdWUsIFZhbHVlPjtcbiAgcmVhZG9ubHkgdXBkYXRlOiAodmFsdWU6IFZhbHVlLCB1cGRhdGU6IFVwZGF0ZSkgPT4gVmFsdWU7XG4gIHJlYWRvbmx5IGdldEtleUZyb21WYWx1ZTogKHZhbHVlOiBWYWx1ZSkgPT4gS2V5O1xufSk6IFVwZGF0ZUZ1bmM8VmFsdWUsIFVwZGF0ZT4ge1xuICByZXR1cm4gYXN5bmMgKHZhbHVlOiBWYWx1ZSwgdXBkYXRlOiBVcGRhdGUpOiBQcm9taXNlPFZhbHVlPiA9PiB7XG4gICAgY29uc3Qga2V5ID0gZ2V0S2V5RnJvbVZhbHVlKHZhbHVlKTtcbiAgICBjb25zdCB1cGRhdGVkVmFsdWUgPSB1cGRhdGVGdW5jKHZhbHVlLCB1cGRhdGUpO1xuXG4gICAgY29uc3QgdHJhY2tlZENoYW5nZSA9IGNhY2hlLnRyeUdldFRyYWNrZWQoa2V5KTtcbiAgICBjYWNoZS5tdXRhYmxlVmFsdWVzW2NhY2hlLmdldEtleVN0cmluZyhrZXkpXSA9IHtcbiAgICAgIHR5cGU6ICdhZGQnLFxuICAgICAgYWRkVmFsdWU6IHVwZGF0ZWRWYWx1ZSxcbiAgICAgIHZhbHVlOiB1cGRhdGVkVmFsdWUsXG4gICAgICBzdWJUeXBlOlxuICAgICAgICAvLyB0cmFja2VkQ2hhbmdlIHVuZGVmaW5lZCAtPiB2YWx1ZSBtdXN0IGV4aXN0IHNvIGl0J3MgYW4gdXBkYXRlXG4gICAgICAgIC8vIHRyYWNrZWRDaGFuZ2UudHlwZSA9PT0gJ2RlbGV0ZScgLT4gdmFsdWUgbXVzdCBoYXZlIHByZXZpb3VzbHkgZXhpc3RlZCwgc28gd2UgaWdub3JlIHRoZSBkZWxldGUgYW5kIGl0J3MgYW4gdXBkYXRlXG4gICAgICAgIC8vIHRyYWNrZWRDaGFuZ2Uuc3ViVHlwZSA9PT0gJ3VwZGF0ZScgLT4gdmFsdWUgbXVzdCBoYXZlIHByZXZpb3VzbHkgZXhpc3RlZFxuICAgICAgICAvLyBvdGhlcndpc2UgLT4gdmFsdWUgZGlkIG5vdCBleGlzdCwgd2UncmUganVzdCBhZGRpbmcgdHdpY2UuXG4gICAgICAgIHRyYWNrZWRDaGFuZ2UgPT09IHVuZGVmaW5lZCB8fCB0cmFja2VkQ2hhbmdlLnR5cGUgPT09ICdkZWxldGUnIHx8IHRyYWNrZWRDaGFuZ2Uuc3ViVHlwZSA9PT0gJ3VwZGF0ZSdcbiAgICAgICAgICA/ICd1cGRhdGUnXG4gICAgICAgICAgOiAnYWRkJyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHVwZGF0ZWRWYWx1ZTtcbiAgfTtcbn1cbnR5cGUgRGVsZXRlRnVuYzxLZXk+ID0gKGtleTogS2V5KSA9PiBQcm9taXNlPHZvaWQ+O1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYW55XG5mdW5jdGlvbiBjcmVhdGVEZWxldGU8S2V5Pih7IGNhY2hlIH06IHsgcmVhZG9ubHkgY2FjaGU6IFJlYWRTdG9yYWdlQ2FjaGU8S2V5LCBhbnksIGFueT4gfSk6IERlbGV0ZUZ1bmM8S2V5PiB7XG4gIHJldHVybiBhc3luYyAoa2V5OiBLZXkpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBjb25zdCBjdXJyZW50VmFsdWUgPSBhd2FpdCBjYWNoZS50cnlHZXRWYWx1ZShrZXkpO1xuICAgIGlmIChjdXJyZW50VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gV2UgZGlkIG5vdCBoYXZlIGEgdmFsdWUgYmVmb3JlLCBzbyBqdXN0IGRlbGV0ZSBhbnkgdHJhY2tlZCBjaGFuZ2VzIGFzIGlmIHRoZXkgbmV2ZXIgb2NjdXJyZWQuXG4gICAgICBkZWxldGUgY2FjaGUubXV0YWJsZVZhbHVlc1tjYWNoZS5nZXRLZXlTdHJpbmcoa2V5KV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhY2hlLm11dGFibGVWYWx1ZXNbY2FjaGUuZ2V0S2V5U3RyaW5nKGtleSldID0geyB0eXBlOiAnZGVsZXRlJywga2V5IH07XG4gICAgfVxuICB9O1xufVxuXG5pbnRlcmZhY2UgUmVhZEFkZFVwZGF0ZURlbGV0ZVN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBWYWx1ZSwgVXBkYXRlPlxuICBleHRlbmRzIFJlYWRTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgVmFsdWUsIFZhbHVlPiB7XG4gIHJlYWRvbmx5IHVwZGF0ZTogKHZhbHVlOiBWYWx1ZSwgdXBkYXRlOiBVcGRhdGUpID0+IFZhbHVlO1xuICByZWFkb25seSBnZXRLZXlGcm9tVmFsdWU6ICh2YWx1ZTogVmFsdWUpID0+IEtleTtcbn1cblxuZXhwb3J0IGNsYXNzIFJlYWRBZGRVcGRhdGVEZWxldGVTdG9yYWdlQ2FjaGU8S2V5LCBWYWx1ZSwgVXBkYXRlPiBleHRlbmRzIFJlYWRTdG9yYWdlQ2FjaGU8S2V5LCBWYWx1ZSwgVmFsdWU+IHtcbiAgcHVibGljIHJlYWRvbmx5IGFkZDogQWRkRnVuYzxWYWx1ZT47XG4gIHB1YmxpYyByZWFkb25seSB1cGRhdGU6IFVwZGF0ZUZ1bmM8VmFsdWUsIFVwZGF0ZT47XG4gIHB1YmxpYyByZWFkb25seSBkZWxldGU6IERlbGV0ZUZ1bmM8S2V5PjtcblxuICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9uczogUmVhZEFkZFVwZGF0ZURlbGV0ZVN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBWYWx1ZSwgVXBkYXRlPikge1xuICAgIHN1cGVyKHtcbiAgICAgIHJlYWRTdG9yYWdlOiBvcHRpb25zLnJlYWRTdG9yYWdlLFxuICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgZ2V0S2V5U3RyaW5nOiBvcHRpb25zLmdldEtleVN0cmluZyxcbiAgICAgIGNyZWF0ZUFkZENoYW5nZTogb3B0aW9ucy5jcmVhdGVBZGRDaGFuZ2UsXG4gICAgICBjcmVhdGVEZWxldGVDaGFuZ2U6IG9wdGlvbnMuY3JlYXRlRGVsZXRlQ2hhbmdlLFxuICAgICAgb25BZGQ6IG9wdGlvbnMub25BZGQsXG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZCA9IGNyZWF0ZUFkZCh7XG4gICAgICBjYWNoZTogdGhpcyxcbiAgICAgIGdldEtleUZyb21WYWx1ZTogb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgIH0pO1xuXG4gICAgdGhpcy51cGRhdGUgPSBjcmVhdGVVcGRhdGUoe1xuICAgICAgY2FjaGU6IHRoaXMsXG4gICAgICB1cGRhdGU6IG9wdGlvbnMudXBkYXRlLFxuICAgICAgZ2V0S2V5RnJvbVZhbHVlOiBvcHRpb25zLmdldEtleUZyb21WYWx1ZSxcbiAgICB9KTtcblxuICAgIHRoaXMuZGVsZXRlID0gY3JlYXRlRGVsZXRlKHsgY2FjaGU6IHRoaXMgfSk7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFJlYWRBZGRVcGRhdGVTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgVmFsdWUsIFVwZGF0ZT4gZXh0ZW5kcyBSZWFkU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIFZhbHVlLCBWYWx1ZT4ge1xuICByZWFkb25seSB1cGRhdGU6ICh2YWx1ZTogVmFsdWUsIHVwZGF0ZTogVXBkYXRlKSA9PiBWYWx1ZTtcbiAgcmVhZG9ubHkgZ2V0S2V5RnJvbVZhbHVlOiAodmFsdWU6IFZhbHVlKSA9PiBLZXk7XG4gIHJlYWRvbmx5IGFsbG93RHVwZXM/OiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgUmVhZEFkZFVwZGF0ZVN0b3JhZ2VDYWNoZTxLZXksIFZhbHVlLCBVcGRhdGU+IGV4dGVuZHMgUmVhZFN0b3JhZ2VDYWNoZTxLZXksIFZhbHVlLCBWYWx1ZT4ge1xuICBwdWJsaWMgcmVhZG9ubHkgYWRkOiBBZGRGdW5jPFZhbHVlPjtcbiAgcHVibGljIHJlYWRvbmx5IHVwZGF0ZTogVXBkYXRlRnVuYzxWYWx1ZSwgVXBkYXRlPjtcblxuICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9uczogUmVhZEFkZFVwZGF0ZVN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBWYWx1ZSwgVXBkYXRlPikge1xuICAgIHN1cGVyKHtcbiAgICAgIHJlYWRTdG9yYWdlOiBvcHRpb25zLnJlYWRTdG9yYWdlLFxuICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgZ2V0S2V5U3RyaW5nOiBvcHRpb25zLmdldEtleVN0cmluZyxcbiAgICAgIGNyZWF0ZUFkZENoYW5nZTogb3B0aW9ucy5jcmVhdGVBZGRDaGFuZ2UsXG4gICAgICBjcmVhdGVEZWxldGVDaGFuZ2U6IG9wdGlvbnMuY3JlYXRlRGVsZXRlQ2hhbmdlLFxuICAgICAgb25BZGQ6IG9wdGlvbnMub25BZGQsXG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZCA9IGNyZWF0ZUFkZCh7XG4gICAgICBjYWNoZTogdGhpcyxcbiAgICAgIGdldEtleUZyb21WYWx1ZTogb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgICAgYWxsb3dEdXBlczogb3B0aW9ucy5hbGxvd0R1cGVzLFxuICAgIH0pO1xuXG4gICAgdGhpcy51cGRhdGUgPSBjcmVhdGVVcGRhdGUoe1xuICAgICAgY2FjaGU6IHRoaXMsXG4gICAgICB1cGRhdGU6IG9wdGlvbnMudXBkYXRlLFxuICAgICAgZ2V0S2V5RnJvbVZhbHVlOiBvcHRpb25zLmdldEtleUZyb21WYWx1ZSxcbiAgICB9KTtcbiAgfVxufVxuXG5pbnRlcmZhY2UgUmVhZEFkZERlbGV0ZVN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBWYWx1ZT4gZXh0ZW5kcyBSZWFkU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIFZhbHVlLCBWYWx1ZT4ge1xuICByZWFkb25seSBnZXRLZXlGcm9tVmFsdWU6ICh2YWx1ZTogVmFsdWUpID0+IEtleTtcbn1cblxuZXhwb3J0IGNsYXNzIFJlYWRBZGREZWxldGVTdG9yYWdlQ2FjaGU8S2V5LCBWYWx1ZT4gZXh0ZW5kcyBSZWFkU3RvcmFnZUNhY2hlPEtleSwgVmFsdWUsIFZhbHVlPiB7XG4gIHB1YmxpYyByZWFkb25seSBhZGQ6IEFkZEZ1bmM8VmFsdWU+O1xuICBwdWJsaWMgcmVhZG9ubHkgZGVsZXRlOiBEZWxldGVGdW5jPEtleT47XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFJlYWRBZGREZWxldGVTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgVmFsdWU+KSB7XG4gICAgc3VwZXIoe1xuICAgICAgcmVhZFN0b3JhZ2U6IG9wdGlvbnMucmVhZFN0b3JhZ2UsXG4gICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgICAgY3JlYXRlQWRkQ2hhbmdlOiBvcHRpb25zLmNyZWF0ZUFkZENoYW5nZSxcbiAgICAgIGNyZWF0ZURlbGV0ZUNoYW5nZTogb3B0aW9ucy5jcmVhdGVEZWxldGVDaGFuZ2UsXG4gICAgICBvbkFkZDogb3B0aW9ucy5vbkFkZCxcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkID0gY3JlYXRlQWRkKHtcbiAgICAgIGNhY2hlOiB0aGlzLFxuICAgICAgZ2V0S2V5RnJvbVZhbHVlOiBvcHRpb25zLmdldEtleUZyb21WYWx1ZSxcbiAgICAgIGdldEtleVN0cmluZzogb3B0aW9ucy5nZXRLZXlTdHJpbmcsXG4gICAgfSk7XG5cbiAgICB0aGlzLmRlbGV0ZSA9IGNyZWF0ZURlbGV0ZSh7IGNhY2hlOiB0aGlzIH0pO1xuICB9XG59XG5cbmludGVyZmFjZSBSZWFkQWRkU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIFZhbHVlPiBleHRlbmRzIFJlYWRTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgVmFsdWUsIFZhbHVlPiB7XG4gIHJlYWRvbmx5IGdldEtleUZyb21WYWx1ZTogKHZhbHVlOiBWYWx1ZSkgPT4gS2V5O1xuICByZWFkb25seSBhbGxvd0R1cGVzPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIFJlYWRBZGRTdG9yYWdlQ2FjaGU8S2V5LCBWYWx1ZT4gZXh0ZW5kcyBSZWFkU3RvcmFnZUNhY2hlPEtleSwgVmFsdWUsIFZhbHVlPiB7XG4gIHB1YmxpYyByZWFkb25seSBhZGQ6IEFkZEZ1bmM8VmFsdWU+O1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBSZWFkQWRkU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIFZhbHVlPikge1xuICAgIHN1cGVyKHtcbiAgICAgIHJlYWRTdG9yYWdlOiBvcHRpb25zLnJlYWRTdG9yYWdlLFxuICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgZ2V0S2V5U3RyaW5nOiBvcHRpb25zLmdldEtleVN0cmluZyxcbiAgICAgIGNyZWF0ZUFkZENoYW5nZTogb3B0aW9ucy5jcmVhdGVBZGRDaGFuZ2UsXG4gICAgICBjcmVhdGVEZWxldGVDaGFuZ2U6IG9wdGlvbnMuY3JlYXRlRGVsZXRlQ2hhbmdlLFxuICAgICAgb25BZGQ6IG9wdGlvbnMub25BZGQsXG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZCA9IGNyZWF0ZUFkZCh7XG4gICAgICBjYWNoZTogdGhpcyxcbiAgICAgIGdldEtleUZyb21WYWx1ZTogb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgICAgYWxsb3dEdXBlczogb3B0aW9ucy5hbGxvd0R1cGVzLFxuICAgIH0pO1xuICB9XG59XG5cbmludGVyZmFjZSBSZWFkR2V0QWxsQWRkRGVsZXRlU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIFBhcnRpYWxLZXksIFZhbHVlPlxuICBleHRlbmRzIFJlYWRHZXRBbGxTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgUGFydGlhbEtleSwgVmFsdWU+IHtcbiAgcmVhZG9ubHkgZ2V0S2V5RnJvbVZhbHVlOiAodmFsdWU6IFZhbHVlKSA9PiBLZXk7XG59XG5cbmV4cG9ydCBjbGFzcyBSZWFkR2V0QWxsQWRkRGVsZXRlU3RvcmFnZUNhY2hlPEtleSwgUGFydGlhbEtleSwgVmFsdWU+IGV4dGVuZHMgUmVhZEdldEFsbFN0b3JhZ2VDYWNoZTxcbiAgS2V5LFxuICBQYXJ0aWFsS2V5LFxuICBWYWx1ZVxuPiB7XG4gIHB1YmxpYyByZWFkb25seSBhZGQ6IEFkZEZ1bmM8VmFsdWU+O1xuICBwdWJsaWMgcmVhZG9ubHkgZGVsZXRlOiBEZWxldGVGdW5jPEtleT47XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFJlYWRHZXRBbGxBZGREZWxldGVTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgUGFydGlhbEtleSwgVmFsdWU+KSB7XG4gICAgc3VwZXIoe1xuICAgICAgcmVhZEdldEFsbFN0b3JhZ2U6IG9wdGlvbnMucmVhZEdldEFsbFN0b3JhZ2UsXG4gICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgICAgY3JlYXRlQWRkQ2hhbmdlOiBvcHRpb25zLmNyZWF0ZUFkZENoYW5nZSxcbiAgICAgIGNyZWF0ZURlbGV0ZUNoYW5nZTogb3B0aW9ucy5jcmVhdGVEZWxldGVDaGFuZ2UsXG4gICAgICBvbkFkZDogb3B0aW9ucy5vbkFkZCxcbiAgICAgIGdldEtleUZyb21WYWx1ZTogb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWUsXG4gICAgICBtYXRjaGVzUGFydGlhbEtleTogb3B0aW9ucy5tYXRjaGVzUGFydGlhbEtleSxcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkID0gY3JlYXRlQWRkKHtcbiAgICAgIGNhY2hlOiB0aGlzLFxuICAgICAgZ2V0S2V5RnJvbVZhbHVlOiBvcHRpb25zLmdldEtleUZyb21WYWx1ZSxcbiAgICAgIGdldEtleVN0cmluZzogb3B0aW9ucy5nZXRLZXlTdHJpbmcsXG4gICAgfSk7XG5cbiAgICB0aGlzLmRlbGV0ZSA9IGNyZWF0ZURlbGV0ZSh7IGNhY2hlOiB0aGlzIH0pO1xuICB9XG59XG5cbmludGVyZmFjZSBSZWFkR2V0QWxsQWRkVXBkYXRlRGVsZXRlU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIFBhcnRpYWxLZXksIFZhbHVlLCBVcGRhdGU+XG4gIGV4dGVuZHMgUmVhZEdldEFsbFN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBQYXJ0aWFsS2V5LCBWYWx1ZT4ge1xuICByZWFkb25seSB1cGRhdGU6ICh2YWx1ZTogVmFsdWUsIHVwZGF0ZTogVXBkYXRlKSA9PiBWYWx1ZTtcbiAgcmVhZG9ubHkgZ2V0S2V5RnJvbVZhbHVlOiAodmFsdWU6IFZhbHVlKSA9PiBLZXk7XG59XG5cbmV4cG9ydCBjbGFzcyBSZWFkR2V0QWxsQWRkVXBkYXRlRGVsZXRlU3RvcmFnZUNhY2hlPEtleSwgUGFydGlhbEtleSwgVmFsdWUsIFVwZGF0ZT4gZXh0ZW5kcyBSZWFkR2V0QWxsU3RvcmFnZUNhY2hlPFxuICBLZXksXG4gIFBhcnRpYWxLZXksXG4gIFZhbHVlXG4+IHtcbiAgcHVibGljIHJlYWRvbmx5IGFkZDogQWRkRnVuYzxWYWx1ZT47XG4gIHB1YmxpYyByZWFkb25seSB1cGRhdGU6IFVwZGF0ZUZ1bmM8VmFsdWUsIFVwZGF0ZT47XG4gIHB1YmxpYyByZWFkb25seSBkZWxldGU6IERlbGV0ZUZ1bmM8S2V5PjtcblxuICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9uczogUmVhZEdldEFsbEFkZFVwZGF0ZURlbGV0ZVN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBQYXJ0aWFsS2V5LCBWYWx1ZSwgVXBkYXRlPikge1xuICAgIHN1cGVyKHtcbiAgICAgIHJlYWRHZXRBbGxTdG9yYWdlOiBvcHRpb25zLnJlYWRHZXRBbGxTdG9yYWdlLFxuICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgZ2V0S2V5U3RyaW5nOiBvcHRpb25zLmdldEtleVN0cmluZyxcbiAgICAgIGNyZWF0ZUFkZENoYW5nZTogb3B0aW9ucy5jcmVhdGVBZGRDaGFuZ2UsXG4gICAgICBjcmVhdGVEZWxldGVDaGFuZ2U6IG9wdGlvbnMuY3JlYXRlRGVsZXRlQ2hhbmdlLFxuICAgICAgb25BZGQ6IG9wdGlvbnMub25BZGQsXG4gICAgICBnZXRLZXlGcm9tVmFsdWU6IG9wdGlvbnMuZ2V0S2V5RnJvbVZhbHVlLFxuICAgICAgbWF0Y2hlc1BhcnRpYWxLZXk6IG9wdGlvbnMubWF0Y2hlc1BhcnRpYWxLZXksXG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZCA9IGNyZWF0ZUFkZCh7XG4gICAgICBjYWNoZTogdGhpcyxcbiAgICAgIGdldEtleUZyb21WYWx1ZTogb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgIH0pO1xuXG4gICAgdGhpcy51cGRhdGUgPSBjcmVhdGVVcGRhdGUoe1xuICAgICAgY2FjaGU6IHRoaXMsXG4gICAgICB1cGRhdGU6IG9wdGlvbnMudXBkYXRlLFxuICAgICAgZ2V0S2V5RnJvbVZhbHVlOiBvcHRpb25zLmdldEtleUZyb21WYWx1ZSxcbiAgICB9KTtcblxuICAgIHRoaXMuZGVsZXRlID0gY3JlYXRlRGVsZXRlKHsgY2FjaGU6IHRoaXMgfSk7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFJlYWRHZXRBbGxBZGRTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgUGFydGlhbEtleSwgVmFsdWU+XG4gIGV4dGVuZHMgUmVhZEdldEFsbFN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBQYXJ0aWFsS2V5LCBWYWx1ZT4ge1xuICByZWFkb25seSBnZXRLZXlGcm9tVmFsdWU6ICh2YWx1ZTogVmFsdWUpID0+IEtleTtcbn1cblxuZXhwb3J0IGNsYXNzIFJlYWRHZXRBbGxBZGRTdG9yYWdlQ2FjaGU8S2V5LCBQYXJ0aWFsS2V5LCBWYWx1ZT4gZXh0ZW5kcyBSZWFkR2V0QWxsU3RvcmFnZUNhY2hlPEtleSwgUGFydGlhbEtleSwgVmFsdWU+IHtcbiAgcHVibGljIHJlYWRvbmx5IGFkZDogQWRkRnVuYzxWYWx1ZT47XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFJlYWRHZXRBbGxBZGRTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgUGFydGlhbEtleSwgVmFsdWU+KSB7XG4gICAgc3VwZXIoe1xuICAgICAgcmVhZEdldEFsbFN0b3JhZ2U6IG9wdGlvbnMucmVhZEdldEFsbFN0b3JhZ2UsXG4gICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgICAgY3JlYXRlQWRkQ2hhbmdlOiBvcHRpb25zLmNyZWF0ZUFkZENoYW5nZSxcbiAgICAgIGNyZWF0ZURlbGV0ZUNoYW5nZTogb3B0aW9ucy5jcmVhdGVEZWxldGVDaGFuZ2UsXG4gICAgICBvbkFkZDogb3B0aW9ucy5vbkFkZCxcbiAgICAgIGdldEtleUZyb21WYWx1ZTogb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWUsXG4gICAgICBtYXRjaGVzUGFydGlhbEtleTogb3B0aW9ucy5tYXRjaGVzUGFydGlhbEtleSxcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkID0gY3JlYXRlQWRkKHtcbiAgICAgIGNhY2hlOiB0aGlzLFxuICAgICAgZ2V0S2V5RnJvbVZhbHVlOiBvcHRpb25zLmdldEtleUZyb21WYWx1ZSxcbiAgICAgIGdldEtleVN0cmluZzogb3B0aW9ucy5nZXRLZXlTdHJpbmcsXG4gICAgfSk7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFJlYWRBbGxBZGRVcGRhdGVEZWxldGVTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgVmFsdWUsIFVwZGF0ZT4gZXh0ZW5kcyBSZWFkQWxsU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIFZhbHVlPiB7XG4gIHJlYWRvbmx5IHVwZGF0ZTogKHZhbHVlOiBWYWx1ZSwgdXBkYXRlOiBVcGRhdGUpID0+IFZhbHVlO1xuICByZWFkb25seSBnZXRLZXlGcm9tVmFsdWU6ICh2YWx1ZTogVmFsdWUpID0+IEtleTtcbn1cblxuZXhwb3J0IGNsYXNzIFJlYWRBbGxBZGRVcGRhdGVEZWxldGVTdG9yYWdlQ2FjaGU8S2V5LCBWYWx1ZSwgVXBkYXRlPiBleHRlbmRzIFJlYWRBbGxTdG9yYWdlQ2FjaGU8S2V5LCBWYWx1ZT4ge1xuICBwdWJsaWMgcmVhZG9ubHkgYWRkOiBBZGRGdW5jPFZhbHVlPjtcbiAgcHVibGljIHJlYWRvbmx5IHVwZGF0ZTogVXBkYXRlRnVuYzxWYWx1ZSwgVXBkYXRlPjtcbiAgcHVibGljIHJlYWRvbmx5IGRlbGV0ZTogRGVsZXRlRnVuYzxLZXk+O1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBSZWFkQWxsQWRkVXBkYXRlRGVsZXRlU3RvcmFnZUNhY2hlT3B0aW9uczxLZXksIFZhbHVlLCBVcGRhdGU+KSB7XG4gICAgc3VwZXIoe1xuICAgICAgcmVhZEFsbFN0b3JhZ2U6IG9wdGlvbnMucmVhZEFsbFN0b3JhZ2UsXG4gICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgICAgY3JlYXRlQWRkQ2hhbmdlOiBvcHRpb25zLmNyZWF0ZUFkZENoYW5nZSxcbiAgICAgIGNyZWF0ZURlbGV0ZUNoYW5nZTogb3B0aW9ucy5jcmVhdGVEZWxldGVDaGFuZ2UsXG4gICAgICBvbkFkZDogb3B0aW9ucy5vbkFkZCxcbiAgICAgIGdldEtleUZyb21WYWx1ZTogb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZCA9IGNyZWF0ZUFkZCh7XG4gICAgICBjYWNoZTogdGhpcyxcbiAgICAgIGdldEtleUZyb21WYWx1ZTogb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgIH0pO1xuXG4gICAgdGhpcy51cGRhdGUgPSBjcmVhdGVVcGRhdGUoe1xuICAgICAgY2FjaGU6IHRoaXMsXG4gICAgICB1cGRhdGU6IG9wdGlvbnMudXBkYXRlLFxuICAgICAgZ2V0S2V5RnJvbVZhbHVlOiBvcHRpb25zLmdldEtleUZyb21WYWx1ZSxcbiAgICB9KTtcblxuICAgIHRoaXMuZGVsZXRlID0gY3JlYXRlRGVsZXRlKHsgY2FjaGU6IHRoaXMgfSk7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFJlYWRBbGxBZGRTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgVmFsdWU+IGV4dGVuZHMgUmVhZEFsbFN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBWYWx1ZT4ge1xuICByZWFkb25seSBnZXRLZXlGcm9tVmFsdWU6ICh2YWx1ZTogVmFsdWUpID0+IEtleTtcbn1cblxuZXhwb3J0IGNsYXNzIFJlYWRBbGxBZGRTdG9yYWdlQ2FjaGU8S2V5LCBWYWx1ZT4gZXh0ZW5kcyBSZWFkQWxsU3RvcmFnZUNhY2hlPEtleSwgVmFsdWU+IHtcbiAgcHVibGljIHJlYWRvbmx5IGFkZDogQWRkRnVuYzxWYWx1ZT47XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFJlYWRBbGxBZGRTdG9yYWdlQ2FjaGVPcHRpb25zPEtleSwgVmFsdWU+KSB7XG4gICAgc3VwZXIoe1xuICAgICAgcmVhZEFsbFN0b3JhZ2U6IG9wdGlvbnMucmVhZEFsbFN0b3JhZ2UsXG4gICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgICAgY3JlYXRlQWRkQ2hhbmdlOiBvcHRpb25zLmNyZWF0ZUFkZENoYW5nZSxcbiAgICAgIGNyZWF0ZURlbGV0ZUNoYW5nZTogb3B0aW9ucy5jcmVhdGVEZWxldGVDaGFuZ2UsXG4gICAgICBvbkFkZDogb3B0aW9ucy5vbkFkZCxcbiAgICAgIGdldEtleUZyb21WYWx1ZTogb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZCA9IGNyZWF0ZUFkZCh7XG4gICAgICBjYWNoZTogdGhpcyxcbiAgICAgIGdldEtleUZyb21WYWx1ZTogb3B0aW9ucy5nZXRLZXlGcm9tVmFsdWUsXG4gICAgICBnZXRLZXlTdHJpbmc6IG9wdGlvbnMuZ2V0S2V5U3RyaW5nLFxuICAgIH0pO1xuICB9XG59XG5cbmludGVyZmFjZSBCbG9ja0xpa2VLZXkge1xuICByZWFkb25seSBoYXNoT3JJbmRleDogQmxvY2tbJ2hhc2gnXSB8IEJsb2NrWydpbmRleCddO1xufVxuXG5pbnRlcmZhY2UgQmxvY2tMaWtlIHtcbiAgcmVhZG9ubHkgaGFzaDogQmxvY2tbJ2hhc2gnXTtcbiAgcmVhZG9ubHkgaW5kZXg6IEJsb2NrWydpbmRleCddO1xufVxuXG5pbnRlcmZhY2UgQmxvY2tMaWtlU3RvcmFnZUNhY2hlT3B0aW9uczxWYWx1ZSBleHRlbmRzIEJsb2NrTGlrZT5cbiAgZXh0ZW5kcyBCYXNlUmVhZFN0b3JhZ2VDYWNoZU9wdGlvbnM8QmxvY2tMaWtlS2V5LCBWYWx1ZSwgVmFsdWU+IHt9XG5cbmV4cG9ydCBjbGFzcyBCbG9ja0xpa2VTdG9yYWdlQ2FjaGU8VmFsdWUgZXh0ZW5kcyBCbG9ja0xpa2U+IGV4dGVuZHMgQmFzZVJlYWRTdG9yYWdlQ2FjaGU8QmxvY2tMaWtlS2V5LCBWYWx1ZSwgVmFsdWU+IHtcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIHJlYWRvbmx5LWtleXdvcmRcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG11dGFibGVJbmRleFZhbHVlczogeyBbaW5kZXg6IHN0cmluZ106IFRyYWNrZWRDaGFuZ2U8QmxvY2tMaWtlS2V5LCBWYWx1ZSwgVmFsdWU+IH07XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEJsb2NrTGlrZVN0b3JhZ2VDYWNoZU9wdGlvbnM8VmFsdWU+KSB7XG4gICAgc3VwZXIoe1xuICAgICAgcmVhZFN0b3JhZ2U6IG9wdGlvbnMucmVhZFN0b3JhZ2UsXG4gICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICBjcmVhdGVBZGRDaGFuZ2U6IG9wdGlvbnMuY3JlYXRlQWRkQ2hhbmdlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5tdXRhYmxlSW5kZXhWYWx1ZXMgPSB7fTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBhZGQodmFsdWU6IFZhbHVlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY3VycmVudFZhbHVlID0gYXdhaXQgdGhpcy50cnlHZXQoeyBoYXNoT3JJbmRleDogdmFsdWUuaW5kZXggfSk7XG4gICAgaWYgKGN1cnJlbnRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F0dGVtcHRlZCB0byBhZGQgYW4gYWxyZWFkeSBleGlzdGluZyBvYmplY3QuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgYWRkVmFsdWU6IFRyYWNrZWRDaGFuZ2U8QmxvY2tMaWtlS2V5LCBWYWx1ZSwgVmFsdWU+ID0geyB0eXBlOiAnYWRkJywgYWRkVmFsdWU6IHZhbHVlLCB2YWx1ZSwgc3ViVHlwZTogJ2FkZCcgfTtcbiAgICB0aGlzLm11dGFibGVWYWx1ZXNbY29tbW9uLnVJbnQyNTZUb1N0cmluZyh2YWx1ZS5oYXNoKV0gPSBhZGRWYWx1ZTtcbiAgICB0aGlzLm11dGFibGVJbmRleFZhbHVlc1tgJHt2YWx1ZS5pbmRleH1gXSA9IGFkZFZhbHVlO1xuICB9XG5cbiAgcHVibGljIHRyeUdldFRyYWNrZWQoa2V5OiBCbG9ja0xpa2VLZXkpOiBUcmFja2VkQ2hhbmdlPEJsb2NrTGlrZUtleSwgVmFsdWUsIFZhbHVlPiB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiBrZXkuaGFzaE9ySW5kZXggIT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gdGhpcy5tdXRhYmxlVmFsdWVzW2NvbW1vbi51SW50MjU2VG9TdHJpbmcoa2V5Lmhhc2hPckluZGV4KV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubXV0YWJsZUluZGV4VmFsdWVzW2Ake2tleS5oYXNoT3JJbmRleH1gXTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRUcmFja2VkQ2hhbmdlKGtleTogc3RyaW5nLCB2YWx1ZTogVHJhY2tlZENoYW5nZTxCbG9ja0xpa2VLZXksIFZhbHVlLCBWYWx1ZT4pOiB2b2lkIHtcbiAgICB0aGlzLm11dGFibGVWYWx1ZXNba2V5XSA9IHZhbHVlO1xuICB9XG59XG5cbmludGVyZmFjZSBPdXRwdXRWYWx1ZSB7XG4gIHJlYWRvbmx5IGhhc2g6IFVJbnQyNTY7XG4gIHJlYWRvbmx5IGluZGV4OiBudW1iZXI7XG4gIHJlYWRvbmx5IG91dHB1dDogT3V0cHV0O1xufVxuXG5jb25zdCBnZXRPdXRwdXRWYWx1ZUtleVN0cmluZyA9IChrZXk6IE91dHB1dEtleSk6IHN0cmluZyA9PiBgJHtjb21tb24udUludDI1NlRvSGV4KGtleS5oYXNoKX06JHtrZXkuaW5kZXh9YDtcblxuZXhwb3J0IGNsYXNzIE91dHB1dFN0b3JhZ2VDYWNoZSBleHRlbmRzIFJlYWRTdG9yYWdlQ2FjaGU8T3V0cHV0S2V5LCBPdXRwdXRWYWx1ZSwgT3V0cHV0PiB7XG4gIHB1YmxpYyByZWFkb25seSBhZGQ6IEFkZEZ1bmM8T3V0cHV0VmFsdWU+O1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihyZWFkU3RvcmFnZTogKCkgPT4gUmVhZFN0b3JhZ2U8T3V0cHV0S2V5LCBPdXRwdXQ+KSB7XG4gICAgc3VwZXIoe1xuICAgICAgcmVhZFN0b3JhZ2UsXG4gICAgICBuYW1lOiAnb3V0cHV0JyxcbiAgICAgIGdldEtleVN0cmluZzogZ2V0T3V0cHV0VmFsdWVLZXlTdHJpbmcsXG4gICAgICBjcmVhdGVBZGRDaGFuZ2U6ICh2YWx1ZTogT3V0cHV0VmFsdWUpID0+ICh7IHR5cGU6ICdvdXRwdXQnLCB2YWx1ZSB9KSxcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkID0gYXN5bmMgKHZhbHVlOiBPdXRwdXRWYWx1ZSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgY29uc3Qga2V5ID0geyBoYXNoOiB2YWx1ZS5oYXNoLCBpbmRleDogdmFsdWUuaW5kZXggfTtcblxuICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gYXdhaXQgdGhpcy50cnlHZXQoa2V5KTtcbiAgICAgIGlmIChjdXJyZW50VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYEF0dGVtcHRlZCB0byBhZGQgYW4gYWxyZWFkeSBleGlzdGluZyBvYmplY3QgZm9yIGtleSBgICsgYCR7dGhpcy5uYW1lfToke3RoaXMuZ2V0S2V5U3RyaW5nKGtleSl9LmAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMubXV0YWJsZVZhbHVlc1t0aGlzLmdldEtleVN0cmluZyhrZXkpXSA9IHtcbiAgICAgICAgdHlwZTogJ2FkZCcsXG4gICAgICAgIGFkZFZhbHVlOiB2YWx1ZSxcbiAgICAgICAgdmFsdWU6IHZhbHVlLm91dHB1dCxcbiAgICAgICAgc3ViVHlwZTogJ2FkZCcsXG4gICAgICB9O1xuICAgIH07XG4gIH1cbn1cbnR5cGUgVHJhY2tlZE1ldGFkYXRhQ2hhbmdlPEFkZFZhbHVlLCBWYWx1ZT4gPVxuICB8IHsgcmVhZG9ubHkgdHlwZTogJ2FkZCc7IHJlYWRvbmx5IGFkZFZhbHVlOiBBZGRWYWx1ZTsgcmVhZG9ubHkgdmFsdWU6IFZhbHVlOyByZWFkb25seSBzdWJUeXBlOiAnYWRkJyB8ICd1cGRhdGUnIH1cbiAgfCB7IHJlYWRvbmx5IHR5cGU6ICdkZWxldGUnIH07XG50eXBlIEdldE1ldGFkYXRhRnVuYzxWYWx1ZT4gPSAoa2V5PzogdW5kZWZpbmVkKSA9PiBQcm9taXNlPFZhbHVlPjtcbnR5cGUgVHJ5R2V0TWV0YWRhdGFGdW5jPFZhbHVlPiA9IChrZXk/OiB1bmRlZmluZWQpID0+IFByb21pc2U8VmFsdWUgfCB1bmRlZmluZWQ+O1xuXG5mdW5jdGlvbiBjcmVhdGVHZXRNZXRhZGF0YTxLZXksIFZhbHVlPih7XG4gIHRyeUdldFRyYWNrZWQsXG4gIHJlYWRTdG9yYWdlLFxufToge1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYW55XG4gIHJlYWRvbmx5IHRyeUdldFRyYWNrZWQ6ICgpID0+IFRyYWNrZWRNZXRhZGF0YUNoYW5nZTxhbnksIFZhbHVlPiB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgcmVhZFN0b3JhZ2U6ICgpID0+IFJlYWRNZXRhZGF0YVN0b3JhZ2U8VmFsdWU+O1xufSk6IEdldEZ1bmM8S2V5LCBWYWx1ZT4ge1xuICByZXR1cm4gYXN5bmMgKCk6IFByb21pc2U8VmFsdWU+ID0+IHtcbiAgICBjb25zdCB0cmFja2VkQ2hhbmdlID0gdHJ5R2V0VHJhY2tlZCgpO1xuICAgIGlmICh0cmFja2VkQ2hhbmdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0cmFja2VkQ2hhbmdlLnR5cGUgPT09ICdkZWxldGUnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGZvdW5kJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cmFja2VkQ2hhbmdlLnZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiByZWFkU3RvcmFnZSgpLmdldCgpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUcnlHZXRNZXRhZGF0YTxWYWx1ZT4oe1xuICB0cnlHZXRUcmFja2VkLFxuICByZWFkU3RvcmFnZSxcbn06IHtcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueVxuICByZWFkb25seSB0cnlHZXRUcmFja2VkOiAoKSA9PiBUcmFja2VkTWV0YWRhdGFDaGFuZ2U8YW55LCBWYWx1ZT4gfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IHJlYWRTdG9yYWdlOiAoKSA9PiBSZWFkTWV0YWRhdGFTdG9yYWdlPFZhbHVlPjtcbn0pOiBUcnlHZXRNZXRhZGF0YUZ1bmM8VmFsdWU+IHtcbiAgcmV0dXJuIGFzeW5jICgpOiBQcm9taXNlPFZhbHVlIHwgdW5kZWZpbmVkPiA9PiB7XG4gICAgY29uc3QgdHJhY2tlZENoYW5nZSA9IHRyeUdldFRyYWNrZWQoKTtcbiAgICBpZiAodHJhY2tlZENoYW5nZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHJhY2tlZENoYW5nZS50eXBlID09PSAnZGVsZXRlJykge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJhY2tlZENoYW5nZS52YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVhZFN0b3JhZ2UoKS50cnlHZXQoKTtcbiAgfTtcbn1cblxuaW50ZXJmYWNlIEJhc2VSZWFkTWV0YWRhdGFTdG9yYWdlQ2FjaGVPcHRpb25zPEFkZFZhbHVlLCBWYWx1ZT4ge1xuICByZWFkb25seSByZWFkU3RvcmFnZTogKCkgPT4gUmVhZE1ldGFkYXRhU3RvcmFnZTxWYWx1ZT47XG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgY3JlYXRlQWRkQ2hhbmdlOiAodmFsdWU6IEFkZFZhbHVlKSA9PiBBZGRDaGFuZ2U7XG4gIHJlYWRvbmx5IGNyZWF0ZURlbGV0ZUNoYW5nZT86ICgpID0+IERlbGV0ZUNoYW5nZTtcbiAgcmVhZG9ubHkgb25BZGQ/OiAodmFsdWU6IEFkZFZhbHVlKSA9PiBQcm9taXNlPHZvaWQ+O1xufVxuXG5leHBvcnQgY2xhc3MgQmFzZVJlYWRNZXRhZGF0YVN0b3JhZ2VDYWNoZTxBZGRWYWx1ZSwgVmFsdWU+IHtcbiAgcHVibGljIHJlYWRvbmx5IGdldDogR2V0TWV0YWRhdGFGdW5jPFZhbHVlPjtcbiAgcHVibGljIHJlYWRvbmx5IHRyeUdldDogVHJ5R2V0TWV0YWRhdGFGdW5jPFZhbHVlPjtcbiAgcHVibGljIG11dGFibGVWYWx1ZTogVHJhY2tlZE1ldGFkYXRhQ2hhbmdlPEFkZFZhbHVlLCBWYWx1ZT4gfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyByZWFkb25seSBvbkFkZDogKCh2YWx1ZTogQWRkVmFsdWUpID0+IFByb21pc2U8dm9pZD4pIHwgdW5kZWZpbmVkO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVhZFN0b3JhZ2U6ICgpID0+IFJlYWRNZXRhZGF0YVN0b3JhZ2U8VmFsdWU+O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY3JlYXRlQWRkQ2hhbmdlOiAodmFsdWU6IEFkZFZhbHVlKSA9PiBBZGRDaGFuZ2U7XG4gIHByb3RlY3RlZCByZWFkb25seSBjcmVhdGVEZWxldGVDaGFuZ2U6ICgoKSA9PiBEZWxldGVDaGFuZ2UpIHwgdW5kZWZpbmVkO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBCYXNlUmVhZE1ldGFkYXRhU3RvcmFnZUNhY2hlT3B0aW9uczxBZGRWYWx1ZSwgVmFsdWU+KSB7XG4gICAgdGhpcy5yZWFkU3RvcmFnZSA9IG9wdGlvbnMucmVhZFN0b3JhZ2U7XG4gICAgdGhpcy5uYW1lID0gb3B0aW9ucy5uYW1lO1xuICAgIHRoaXMuY3JlYXRlQWRkQ2hhbmdlID0gb3B0aW9ucy5jcmVhdGVBZGRDaGFuZ2U7XG4gICAgdGhpcy5jcmVhdGVEZWxldGVDaGFuZ2UgPSBvcHRpb25zLmNyZWF0ZURlbGV0ZUNoYW5nZTtcbiAgICB0aGlzLm9uQWRkID0gb3B0aW9ucy5vbkFkZDtcblxuICAgIHRoaXMuZ2V0ID0gY3JlYXRlR2V0TWV0YWRhdGEoe1xuICAgICAgcmVhZFN0b3JhZ2U6IHRoaXMucmVhZFN0b3JhZ2UsXG4gICAgICB0cnlHZXRUcmFja2VkOiB0aGlzLnRyeUdldFRyYWNrZWQuYmluZCh0aGlzKSxcbiAgICB9KTtcblxuICAgIHRoaXMudHJ5R2V0ID0gY3JlYXRlVHJ5R2V0TWV0YWRhdGEoe1xuICAgICAgcmVhZFN0b3JhZ2U6IHRoaXMucmVhZFN0b3JhZ2UsXG4gICAgICB0cnlHZXRUcmFja2VkOiB0aGlzLnRyeUdldFRyYWNrZWQuYmluZCh0aGlzKSxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDaGFuZ2VTZXQoKTogQ2hhbmdlU2V0IHtcbiAgICBjb25zdCBjcmVhdGVEZWxldGVDaGFuZ2UgPSB0aGlzLmNyZWF0ZURlbGV0ZUNoYW5nZTtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMubXV0YWJsZVZhbHVlO1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLnR5cGUgPT09ICdkZWxldGUnKSB7XG4gICAgICBpZiAoY3JlYXRlRGVsZXRlQ2hhbmdlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRlbGV0ZScpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gW3sgdHlwZTogJ2RlbGV0ZScsIGNoYW5nZTogY3JlYXRlRGVsZXRlQ2hhbmdlKCkgfV07XG4gICAgfVxuXG4gICAgcmV0dXJuIFt7IHR5cGU6ICdhZGQnLCBjaGFuZ2U6IHRoaXMuY3JlYXRlQWRkQ2hhbmdlKHZhbHVlLmFkZFZhbHVlKSwgc3ViVHlwZTogdmFsdWUuc3ViVHlwZSB9XTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRUcmFja2VkQ2hhbmdlU2V0KCk6IFRyYWNrZWRDaGFuZ2VTZXQ8c3RyaW5nLCBBZGRWYWx1ZSwgVmFsdWU+IHtcbiAgICBjb25zdCBjcmVhdGVEZWxldGVDaGFuZ2UgPSB0aGlzLmNyZWF0ZURlbGV0ZUNoYW5nZTtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMubXV0YWJsZVZhbHVlO1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLnR5cGUgPT09ICdkZWxldGUnKSB7XG4gICAgICBpZiAoY3JlYXRlRGVsZXRlQ2hhbmdlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRlbGV0ZScpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gW3sgdHlwZTogY3JlYXRlRGVsZXRlQ2hhbmdlKCkudHlwZSwga2V5OiAnbWV0YWRhdGEnLCB2YWx1ZTogeyAuLi52YWx1ZSwga2V5OiAnbWV0YWRhdGEnIH0gfV07XG4gICAgfVxuXG4gICAgcmV0dXJuIFt7IHR5cGU6IHRoaXMuY3JlYXRlQWRkQ2hhbmdlKHZhbHVlLmFkZFZhbHVlKS50eXBlLCBrZXk6ICdtZXRhZGF0YScsIHZhbHVlIH1dO1xuICB9XG5cbiAgcHVibGljIHRyeUdldFRyYWNrZWQoKTogVHJhY2tlZE1ldGFkYXRhQ2hhbmdlPEFkZFZhbHVlLCBWYWx1ZT4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLm11dGFibGVWYWx1ZTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRUcmFja2VkQ2hhbmdlKF9rZXk6IHN0cmluZywgdmFsdWU6IFRyYWNrZWRNZXRhZGF0YUNoYW5nZTxBZGRWYWx1ZSwgVmFsdWU+KTogdm9pZCB7XG4gICAgdGhpcy5tdXRhYmxlVmFsdWUgPSB2YWx1ZTtcbiAgfVxufVxuXG5jbGFzcyBSZWFkTWV0YWRhdGFTdG9yYWdlQ2FjaGU8QWRkVmFsdWUsIFZhbHVlPiBleHRlbmRzIEJhc2VSZWFkTWV0YWRhdGFTdG9yYWdlQ2FjaGU8QWRkVmFsdWUsIFZhbHVlPiB7fVxuXG5mdW5jdGlvbiBjcmVhdGVBZGRNZXRhZGF0YTxWYWx1ZT4oe1xuICBjYWNoZSxcbn06IHtcbiAgcmVhZG9ubHkgY2FjaGU6IFJlYWRNZXRhZGF0YVN0b3JhZ2VDYWNoZTxWYWx1ZSwgVmFsdWU+O1xufSk6IEFkZEZ1bmM8VmFsdWU+IHtcbiAgcmV0dXJuIGFzeW5jICh2YWx1ZTogVmFsdWUpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAoY2FjaGUub25BZGQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXdhaXQgY2FjaGUub25BZGQodmFsdWUpO1xuICAgIH1cblxuICAgIGNhY2hlLm11dGFibGVWYWx1ZSA9IHtcbiAgICAgIHR5cGU6ICdhZGQnLFxuICAgICAgYWRkVmFsdWU6IHZhbHVlLFxuICAgICAgdmFsdWUsXG4gICAgICBzdWJUeXBlOiAnYWRkJyxcbiAgICB9O1xuICB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVVcGRhdGVNZXRhZGF0YTxWYWx1ZSwgVXBkYXRlPih7XG4gIGNhY2hlLFxuICB1cGRhdGU6IHVwZGF0ZUZ1bmMsXG59OiB7XG4gIHJlYWRvbmx5IGNhY2hlOiBSZWFkTWV0YWRhdGFTdG9yYWdlQ2FjaGU8VmFsdWUsIFZhbHVlPjtcbiAgcmVhZG9ubHkgdXBkYXRlOiAodmFsdWU6IFZhbHVlLCB1cGRhdGU6IFVwZGF0ZSkgPT4gVmFsdWU7XG59KTogVXBkYXRlRnVuYzxWYWx1ZSwgVXBkYXRlPiB7XG4gIHJldHVybiBhc3luYyAodmFsdWU6IFZhbHVlLCB1cGRhdGU6IFVwZGF0ZSk6IFByb21pc2U8VmFsdWU+ID0+IHtcbiAgICBjb25zdCB1cGRhdGVkVmFsdWUgPSB1cGRhdGVGdW5jKHZhbHVlLCB1cGRhdGUpO1xuICAgIGNhY2hlLm11dGFibGVWYWx1ZSA9IHtcbiAgICAgIHR5cGU6ICdhZGQnLFxuICAgICAgYWRkVmFsdWU6IHVwZGF0ZWRWYWx1ZSxcbiAgICAgIHZhbHVlOiB1cGRhdGVkVmFsdWUsXG4gICAgICBzdWJUeXBlOiAndXBkYXRlJyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHVwZGF0ZWRWYWx1ZTtcbiAgfTtcbn1cblxuaW50ZXJmYWNlIFJlYWRBZGRVcGRhdGVNZXRhZGF0YVN0b3JhZ2VDYWNoZU9wdGlvbnM8VmFsdWUsIFVwZGF0ZT5cbiAgZXh0ZW5kcyBCYXNlUmVhZE1ldGFkYXRhU3RvcmFnZUNhY2hlT3B0aW9uczxWYWx1ZSwgVmFsdWU+IHtcbiAgcmVhZG9ubHkgdXBkYXRlOiAodmFsdWU6IFZhbHVlLCB1cGRhdGU6IFVwZGF0ZSkgPT4gVmFsdWU7XG59XG5cbmV4cG9ydCBjbGFzcyBSZWFkQWRkVXBkYXRlTWV0YWRhdGFTdG9yYWdlQ2FjaGU8VmFsdWUsIFVwZGF0ZT4gZXh0ZW5kcyBSZWFkTWV0YWRhdGFTdG9yYWdlQ2FjaGU8VmFsdWUsIFZhbHVlPiB7XG4gIHB1YmxpYyByZWFkb25seSBhZGQ6IEFkZEZ1bmM8VmFsdWU+O1xuICBwdWJsaWMgcmVhZG9ubHkgdXBkYXRlOiBVcGRhdGVGdW5jPFZhbHVlLCBVcGRhdGU+O1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBSZWFkQWRkVXBkYXRlTWV0YWRhdGFTdG9yYWdlQ2FjaGVPcHRpb25zPFZhbHVlLCBVcGRhdGU+KSB7XG4gICAgc3VwZXIoe1xuICAgICAgcmVhZFN0b3JhZ2U6IG9wdGlvbnMucmVhZFN0b3JhZ2UsXG4gICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICBjcmVhdGVBZGRDaGFuZ2U6IG9wdGlvbnMuY3JlYXRlQWRkQ2hhbmdlLFxuICAgICAgY3JlYXRlRGVsZXRlQ2hhbmdlOiBvcHRpb25zLmNyZWF0ZURlbGV0ZUNoYW5nZSxcbiAgICAgIG9uQWRkOiBvcHRpb25zLm9uQWRkLFxuICAgIH0pO1xuXG4gICAgdGhpcy5hZGQgPSBjcmVhdGVBZGRNZXRhZGF0YSh7XG4gICAgICBjYWNoZTogdGhpcyxcbiAgICB9KTtcblxuICAgIHRoaXMudXBkYXRlID0gY3JlYXRlVXBkYXRlTWV0YWRhdGEoe1xuICAgICAgY2FjaGU6IHRoaXMsXG4gICAgICB1cGRhdGU6IG9wdGlvbnMudXBkYXRlLFxuICAgIH0pO1xuICB9XG59XG4iXX0=