@decaf-ts/for-couchdb 0.1.28 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE.md +0 -0
  2. package/README.md +38 -242
  3. package/dist/for-couchdb.cjs +872 -0
  4. package/dist/for-couchdb.esm.cjs +858 -0
  5. package/docker/.dockerignore +0 -0
  6. package/docker/.env +0 -0
  7. package/docker/Dockerfile-booter +0 -0
  8. package/docker/Dockerfile-couchdb +0 -0
  9. package/docker/couchdb.ini +0 -0
  10. package/docker/docker-compose.yml +0 -0
  11. package/lib/adapter.cjs +1 -0
  12. package/lib/adapter.d.ts +0 -0
  13. package/lib/constants.cjs +1 -0
  14. package/lib/constants.d.ts +0 -0
  15. package/lib/errors.cjs +1 -0
  16. package/lib/errors.d.ts +0 -0
  17. package/lib/esm/adapter.d.ts +0 -0
  18. package/lib/esm/adapter.js +1 -2
  19. package/lib/esm/constants.d.ts +0 -0
  20. package/lib/esm/constants.js +1 -2
  21. package/lib/esm/errors.d.ts +0 -0
  22. package/lib/esm/errors.js +1 -2
  23. package/lib/esm/index.d.ts +1 -1
  24. package/lib/esm/index.js +2 -3
  25. package/lib/esm/indexes/generator.d.ts +0 -0
  26. package/lib/esm/indexes/generator.js +1 -2
  27. package/lib/esm/indexes/index.d.ts +0 -0
  28. package/lib/esm/indexes/index.js +1 -2
  29. package/lib/esm/interfaces/CouchDBRepository.d.ts +0 -0
  30. package/lib/esm/interfaces/CouchDBRepository.js +1 -2
  31. package/lib/esm/interfaces/index.d.ts +0 -0
  32. package/lib/esm/interfaces/index.js +1 -2
  33. package/lib/esm/model/CouchDBSequence.d.ts +3 -3
  34. package/lib/esm/model/CouchDBSequence.js +1 -17
  35. package/lib/esm/model/index.d.ts +0 -0
  36. package/lib/esm/model/index.js +1 -2
  37. package/lib/esm/query/FromClause.d.ts +0 -0
  38. package/lib/esm/query/FromClause.js +1 -2
  39. package/lib/esm/query/InsertClause.d.ts +0 -0
  40. package/lib/esm/query/InsertClause.js +1 -2
  41. package/lib/esm/query/Paginator.d.ts +0 -0
  42. package/lib/esm/query/Paginator.js +1 -2
  43. package/lib/esm/query/SelectClause.d.ts +0 -0
  44. package/lib/esm/query/SelectClause.js +1 -2
  45. package/lib/esm/query/Statement.d.ts +0 -0
  46. package/lib/esm/query/Statement.js +1 -2
  47. package/lib/esm/query/ValuesClause.d.ts +0 -0
  48. package/lib/esm/query/ValuesClause.js +1 -2
  49. package/lib/esm/query/WhereClause.d.ts +0 -0
  50. package/lib/esm/query/WhereClause.js +1 -2
  51. package/lib/esm/query/constants.d.ts +0 -0
  52. package/lib/esm/query/constants.js +1 -2
  53. package/lib/esm/query/factory.d.ts +0 -0
  54. package/lib/esm/query/factory.js +1 -2
  55. package/lib/esm/query/index.d.ts +0 -0
  56. package/lib/esm/query/index.js +1 -2
  57. package/lib/esm/query/translate.d.ts +0 -0
  58. package/lib/esm/query/translate.js +1 -2
  59. package/lib/esm/sequences/Sequence.d.ts +0 -0
  60. package/lib/esm/sequences/Sequence.js +1 -2
  61. package/lib/esm/sequences/index.d.ts +0 -0
  62. package/lib/esm/sequences/index.js +1 -2
  63. package/lib/esm/sequences/utils.d.ts +0 -0
  64. package/lib/esm/sequences/utils.js +1 -2
  65. package/lib/esm/types.d.ts +0 -0
  66. package/lib/esm/types.js +1 -2
  67. package/lib/esm/utils.d.ts +0 -0
  68. package/lib/esm/utils.js +1 -2
  69. package/lib/index.cjs +2 -1
  70. package/lib/index.d.ts +1 -1
  71. package/lib/indexes/generator.cjs +1 -0
  72. package/lib/indexes/generator.d.ts +0 -0
  73. package/lib/indexes/index.cjs +1 -0
  74. package/lib/indexes/index.d.ts +0 -0
  75. package/lib/interfaces/CouchDBRepository.cjs +1 -0
  76. package/lib/interfaces/CouchDBRepository.d.ts +0 -0
  77. package/lib/interfaces/index.cjs +1 -0
  78. package/lib/interfaces/index.d.ts +0 -0
  79. package/lib/model/CouchDBSequence.cjs +1 -15
  80. package/lib/model/CouchDBSequence.d.ts +3 -3
  81. package/lib/model/index.cjs +1 -0
  82. package/lib/model/index.d.ts +0 -0
  83. package/lib/query/FromClause.cjs +1 -0
  84. package/lib/query/FromClause.d.ts +0 -0
  85. package/lib/query/InsertClause.cjs +1 -0
  86. package/lib/query/InsertClause.d.ts +0 -0
  87. package/lib/query/Paginator.cjs +1 -0
  88. package/lib/query/Paginator.d.ts +0 -0
  89. package/lib/query/SelectClause.cjs +1 -0
  90. package/lib/query/SelectClause.d.ts +0 -0
  91. package/lib/query/Statement.cjs +1 -0
  92. package/lib/query/Statement.d.ts +0 -0
  93. package/lib/query/ValuesClause.cjs +1 -0
  94. package/lib/query/ValuesClause.d.ts +0 -0
  95. package/lib/query/WhereClause.cjs +1 -0
  96. package/lib/query/WhereClause.d.ts +0 -0
  97. package/lib/query/constants.cjs +1 -0
  98. package/lib/query/constants.d.ts +0 -0
  99. package/lib/query/factory.cjs +1 -0
  100. package/lib/query/factory.d.ts +0 -0
  101. package/lib/query/index.cjs +1 -0
  102. package/lib/query/index.d.ts +0 -0
  103. package/lib/query/translate.cjs +1 -0
  104. package/lib/query/translate.d.ts +0 -0
  105. package/lib/sequences/Sequence.cjs +1 -0
  106. package/lib/sequences/Sequence.d.ts +0 -0
  107. package/lib/sequences/index.cjs +1 -0
  108. package/lib/sequences/index.d.ts +0 -0
  109. package/lib/sequences/utils.cjs +1 -0
  110. package/lib/sequences/utils.d.ts +0 -0
  111. package/lib/types.cjs +1 -0
  112. package/lib/types.d.ts +0 -0
  113. package/lib/utils.cjs +1 -0
  114. package/lib/utils.d.ts +0 -0
  115. package/package.json +38 -40
  116. package/dist/esm/for-couchdb.bundle.min.esm.js +0 -2
  117. package/dist/esm/for-couchdb.bundle.min.esm.js.LICENSE.txt +0 -14
  118. package/dist/for-couchdb.bundle.min.js +0 -2
  119. package/dist/for-couchdb.bundle.min.js.LICENSE.txt +0 -14
@@ -0,0 +1,872 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@decaf-ts/core'), require('@decaf-ts/db-decorators'), require('@decaf-ts/decorator-validation'), require('reflect-metadata')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', '@decaf-ts/core', '@decaf-ts/db-decorators', '@decaf-ts/decorator-validation', 'reflect-metadata'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["for-couchdb"] = {}, global.core, global.dbDecorators, global.decoratorValidation));
5
+ })(this, (function (exports, core, dbDecorators, decoratorValidation) { 'use strict';
6
+
7
+ const reservedAttributes = /^_.*$/g;
8
+ const CouchDBKeys = {
9
+ SEPARATOR: "_",
10
+ ID: "_id",
11
+ REV: "_rev",
12
+ DELETED: "_deleted",
13
+ TABLE: "??table",
14
+ SEQUENCE: "??sequence",
15
+ DDOC: "ddoc",
16
+ NATIVE: "__native",
17
+ INDEX: "index",
18
+ };
19
+
20
+ const CouchDBOperator = {
21
+ EQUAL: "$eq",
22
+ DIFFERENT: "$ne",
23
+ BIGGER: "$gt",
24
+ BIGGER_EQ: "$gte",
25
+ SMALLER: "$lt",
26
+ SMALLER_EQ: "$lte",
27
+ // BETWEEN = "BETWEEN",
28
+ NOT: "$not",
29
+ IN: "$in",
30
+ // IS = "IS",
31
+ REGEXP: "$regex",
32
+ };
33
+ const CouchDBGroupOperator = {
34
+ AND: "$and",
35
+ OR: "$or",
36
+ };
37
+
38
+ function generateIndexName$1(name, direction, compositions, separator = dbDecorators.DefaultSeparator) {
39
+ return [
40
+ ...name.map((n) => (n === CouchDBKeys.TABLE ? "table" : n)),
41
+ ...([]),
42
+ ...([]),
43
+ CouchDBKeys.INDEX,
44
+ ].join(separator);
45
+ }
46
+ function generateIndexes(models) {
47
+ const tableName = generateIndexName$1([CouchDBKeys.TABLE]);
48
+ const indexes = {};
49
+ indexes[tableName] = {
50
+ index: {
51
+ fields: [CouchDBKeys.TABLE],
52
+ },
53
+ name: tableName,
54
+ ddoc: tableName,
55
+ type: "json",
56
+ };
57
+ models.forEach((m) => {
58
+ const ind = core.Repository.indexes(m);
59
+ Object.entries(ind).forEach(([key, value]) => {
60
+ const k = Object.keys(value)[0];
61
+ // eslint-disable-next-line prefer-const
62
+ let { directions, compositions } = value[k];
63
+ const tableName = core.Repository.table(m);
64
+ compositions = compositions || [];
65
+ function generate(sort) {
66
+ const name = [
67
+ tableName,
68
+ key,
69
+ ...compositions,
70
+ core.PersistenceKeys.INDEX,
71
+ ].join(dbDecorators.DefaultSeparator);
72
+ indexes[name] = {
73
+ index: {
74
+ fields: [key, ...compositions, CouchDBKeys.TABLE].reduce((accum, el) => {
75
+ if (sort) {
76
+ const res = {};
77
+ res[el] = sort;
78
+ accum.push(res);
79
+ }
80
+ else {
81
+ accum.push(el);
82
+ }
83
+ return accum;
84
+ }, []),
85
+ },
86
+ name: name,
87
+ ddoc: name,
88
+ type: "json",
89
+ };
90
+ if (!sort) {
91
+ const tableFilter = {};
92
+ tableFilter[CouchDBKeys.TABLE] = {};
93
+ tableFilter[CouchDBKeys.TABLE][CouchDBOperator.EQUAL] = tableName;
94
+ indexes[name].index.partial_filter_selector = tableFilter;
95
+ }
96
+ }
97
+ generate();
98
+ if (directions)
99
+ directions.forEach((d) => generate(d));
100
+ });
101
+ });
102
+ return Object.values(indexes);
103
+ }
104
+
105
+ /******************************************************************************
106
+ Copyright (c) Microsoft Corporation.
107
+
108
+ Permission to use, copy, modify, and/or distribute this software for any
109
+ purpose with or without fee is hereby granted.
110
+
111
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
112
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
113
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
114
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
115
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
116
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
117
+ PERFORMANCE OF THIS SOFTWARE.
118
+ ***************************************************************************** */
119
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
120
+
121
+
122
+ function __decorate(decorators, target, key, desc) {
123
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
124
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
125
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
126
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
127
+ }
128
+
129
+ function __metadata(metadataKey, metadataValue) {
130
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
131
+ }
132
+
133
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
134
+ var e = new Error(message);
135
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
136
+ };
137
+
138
+ exports.Sequence = class Sequence extends core.BaseModel {
139
+ constructor(seq) {
140
+ super(seq);
141
+ }
142
+ };
143
+ __decorate([
144
+ core.pk(),
145
+ __metadata("design:type", String)
146
+ ], exports.Sequence.prototype, "id", void 0);
147
+ __decorate([
148
+ decoratorValidation.required(),
149
+ core.index(),
150
+ __metadata("design:type", Object)
151
+ ], exports.Sequence.prototype, "current", void 0);
152
+ exports.Sequence = __decorate([
153
+ core.table(CouchDBKeys.SEQUENCE),
154
+ decoratorValidation.model(),
155
+ __metadata("design:paramtypes", [Object])
156
+ ], exports.Sequence);
157
+
158
+ function parseSequenceValue(type, value) {
159
+ switch (type) {
160
+ case "Number":
161
+ return typeof value === "string"
162
+ ? parseInt(value)
163
+ : typeof value === "number"
164
+ ? value
165
+ : BigInt(value);
166
+ case "BigInt":
167
+ return BigInt(value);
168
+ default:
169
+ throw new dbDecorators.InternalError("Should never happen");
170
+ }
171
+ }
172
+
173
+ /**
174
+ * @summary Abstract implementation of a Sequence
175
+ * @description provides the basic functionality for {@link Sequence}s
176
+ *
177
+ * @param {SequenceOptions} options
178
+ *
179
+ * @class CouchDBSequence
180
+ * @implements Sequence
181
+ *
182
+ * @category Sequences
183
+ */
184
+ class CouchDBSequence extends core.Sequence {
185
+ constructor(options, adapter) {
186
+ super(options);
187
+ this.repo = core.Repository.forModel(exports.Sequence, adapter.flavour);
188
+ }
189
+ /**
190
+ * @summary Retrieves the current value for the sequence
191
+ * @protected
192
+ */
193
+ async current() {
194
+ const { name, startWith } = this.options;
195
+ try {
196
+ const sequence = await this.repo.read(name);
197
+ return this.parse(sequence.current);
198
+ }
199
+ catch (e) {
200
+ if (e instanceof dbDecorators.NotFoundError) {
201
+ if (typeof startWith === "undefined")
202
+ throw new dbDecorators.InternalError("Starting value is not defined for a non existing sequence");
203
+ try {
204
+ return this.parse(startWith);
205
+ }
206
+ catch (e) {
207
+ throw new dbDecorators.InternalError(decoratorValidation.sf("Failed to parse initial value for sequence {0}: {1}", startWith.toString(), e));
208
+ }
209
+ }
210
+ throw new dbDecorators.InternalError(decoratorValidation.sf("Failed to retrieve current value for sequence {0}: {1}", name, e));
211
+ }
212
+ }
213
+ /**
214
+ * @summary Parses the {@link Sequence} value
215
+ *
216
+ * @protected
217
+ * @param value
218
+ */
219
+ parse(value) {
220
+ return parseSequenceValue(this.options.type, value);
221
+ }
222
+ /**
223
+ * @summary increments the sequence
224
+ * @description Sequence specific implementation
225
+ *
226
+ * @param {string | number | bigint} current
227
+ * @param count
228
+ * @protected
229
+ */
230
+ async increment(current, count) {
231
+ const { type, incrementBy, name } = this.options;
232
+ let next;
233
+ const toIncrementBy = count || incrementBy;
234
+ if (toIncrementBy % incrementBy !== 0)
235
+ throw new dbDecorators.InternalError(`Value to increment does not consider the incrementBy setting: ${incrementBy}`);
236
+ switch (type) {
237
+ case "Number":
238
+ next = this.parse(current) + toIncrementBy;
239
+ break;
240
+ case "BigInt":
241
+ next = this.parse(current) + BigInt(toIncrementBy);
242
+ break;
243
+ default:
244
+ throw new dbDecorators.InternalError("Should never happen");
245
+ }
246
+ let seq;
247
+ try {
248
+ seq = await this.repo.update(new exports.Sequence({ id: name, current: next }));
249
+ }
250
+ catch (e) {
251
+ if (!(e instanceof dbDecorators.NotFoundError))
252
+ throw e;
253
+ seq = await this.repo.create(new exports.Sequence({ id: name, current: next }));
254
+ }
255
+ return seq.current;
256
+ }
257
+ /**
258
+ * @summary Generates the next value in th sequence
259
+ * @description calls {@link Sequence#parse} on the current value
260
+ * followed by {@link Sequence#increment}
261
+ *
262
+ */
263
+ async next() {
264
+ const current = await this.current();
265
+ return this.increment(current);
266
+ }
267
+ async range(count) {
268
+ const current = (await this.current());
269
+ const incrementBy = this.parse(this.options.incrementBy);
270
+ const next = await this.increment(current, this.parse(count) * incrementBy);
271
+ const range = [];
272
+ for (let i = 1; i <= count; i++) {
273
+ range.push(current + incrementBy * this.parse(i));
274
+ }
275
+ if (range[range.length - 1] !== next)
276
+ throw new dbDecorators.InternalError("Miscalculation of range");
277
+ return range;
278
+ }
279
+ }
280
+
281
+ class CouchDBPaginator extends core.Paginator {
282
+ get total() {
283
+ throw new dbDecorators.InternalError(`The total pages api is not available for couchdb`);
284
+ }
285
+ get count() {
286
+ throw new dbDecorators.InternalError(`The record count api is not available for couchdb`);
287
+ }
288
+ constructor(statement, size, rawStatement) {
289
+ super(statement, size, rawStatement);
290
+ }
291
+ prepare(rawStatement) {
292
+ const query = Object.assign({}, rawStatement);
293
+ if (query.limit)
294
+ this.limit = query.limit;
295
+ query.limit = this.size;
296
+ return query;
297
+ }
298
+ async page(page = 1, ...args) {
299
+ const statement = Object.assign({}, this.statement);
300
+ const target = this.stat.getTarget();
301
+ // if (!this._recordCount || !this._totalPages) {
302
+ // // this._recordCount = await this.adapter
303
+ // // .Query()
304
+ // // .count()
305
+ // // .from(target)
306
+ // // .execute<number>();
307
+ // }
308
+ if (page !== 1) {
309
+ if (!this.bookMark)
310
+ throw new core.PagingError("No bookmark. Did you start in the first page?");
311
+ statement["bookmark"] = this.bookMark;
312
+ }
313
+ const rawResult = await this.adapter.raw(statement, false, ...args);
314
+ const { docs, bookmark, warning } = rawResult;
315
+ if (warning)
316
+ console.warn(warning);
317
+ const results = statement.fields && statement.fields.length
318
+ ? docs // has fields means its not full model
319
+ : docs.map((d) => {
320
+ //no fields means we need to revert to saving process
321
+ if (!target)
322
+ throw new core.PagingError("No statement target defined");
323
+ const pkDef = dbDecorators.findPrimaryKey(new target());
324
+ const pk = pkDef.id;
325
+ const originalId = d._id.split(dbDecorators.DefaultSeparator);
326
+ originalId.splice(0, 1); // remove the table name
327
+ return this.adapter.revert(d, target, pk, parseSequenceValue(pkDef.props.type, originalId.join(dbDecorators.DefaultSeparator)));
328
+ });
329
+ this.bookMark = bookmark;
330
+ this._currentPage = page;
331
+ return results;
332
+ }
333
+ }
334
+
335
+ class CouchDBStatement extends core.Statement {
336
+ constructor(adapter) {
337
+ super(adapter);
338
+ }
339
+ /**
340
+ * @inheritDoc
341
+ */
342
+ async execute() {
343
+ try {
344
+ const query = this.build();
345
+ if (!query.limit)
346
+ query.limit = Number.MAX_SAFE_INTEGER;
347
+ return this.raw(query);
348
+ }
349
+ catch (e) {
350
+ throw new dbDecorators.InternalError(e);
351
+ }
352
+ }
353
+ async paginate(size) {
354
+ try {
355
+ const query = this.build();
356
+ return new CouchDBPaginator(this, size, query);
357
+ }
358
+ catch (e) {
359
+ throw new dbDecorators.InternalError(e);
360
+ }
361
+ }
362
+ processRecord(r, pkAttr, sequenceType) {
363
+ if (!r[CouchDBKeys.ID])
364
+ throw new dbDecorators.InternalError(`No CouchDB Id definition found. Should not be possible`);
365
+ const [, ...keyArgs] = r[CouchDBKeys.ID].split("_");
366
+ const id = keyArgs.join("_");
367
+ return this.adapter.revert(r, this.target, pkAttr, parseSequenceValue(sequenceType, id));
368
+ }
369
+ async raw(rawInput, ...args) {
370
+ const results = await this.adapter.raw(rawInput, true, ...args);
371
+ if (!this.fullRecord)
372
+ return results;
373
+ if (!this.target)
374
+ throw new dbDecorators.InternalError("No target defined in statement. should never happen");
375
+ const pkDef = dbDecorators.findPrimaryKey(new this.target());
376
+ const pkAttr = pkDef.id;
377
+ const type = pkDef.props.type;
378
+ if (Array.isArray(results))
379
+ return results.map((r) => this.processRecord(r, pkAttr, type));
380
+ return this.processRecord(results, pkAttr, type);
381
+ }
382
+ }
383
+
384
+ // noinspection JSAnnotator
385
+ class CouchDBFromClause extends core.FromClause {
386
+ constructor(clause) {
387
+ super(clause);
388
+ }
389
+ build(previous) {
390
+ const selectors = {};
391
+ selectors[CouchDBKeys.TABLE] = {};
392
+ selectors[CouchDBKeys.TABLE] =
393
+ typeof this.selector === "string"
394
+ ? this.selector
395
+ : core.Repository.table(this.selector);
396
+ previous.selector = selectors;
397
+ return previous;
398
+ }
399
+ }
400
+
401
+ // noinspection JSAnnotator
402
+ class CouchDBInsertClause extends core.InsertClause {
403
+ constructor(clause) {
404
+ super(clause);
405
+ }
406
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
407
+ build(query) {
408
+ throw new dbDecorators.InternalError("Not supported");
409
+ }
410
+ }
411
+
412
+ class CouchDBWhereClause extends core.WhereClause {
413
+ constructor(clause) {
414
+ super(clause);
415
+ }
416
+ build(query) {
417
+ const condition = this.adapter.parseCondition(core.Condition.and(this.condition, core.Condition.attribute(CouchDBKeys.TABLE).eq(query.selector[CouchDBKeys.TABLE]))).selector;
418
+ const selectorKeys = Object.keys(condition);
419
+ if (selectorKeys.length === 1 &&
420
+ Object.values(CouchDBGroupOperator).indexOf(selectorKeys[0]) !== -1)
421
+ switch (selectorKeys[0]) {
422
+ case CouchDBGroupOperator.AND:
423
+ condition[CouchDBGroupOperator.AND] = [
424
+ ...Object.values(condition[CouchDBGroupOperator.AND]).reduce((accum, val) => {
425
+ const keys = Object.keys(val);
426
+ if (keys.length !== 1)
427
+ throw new Error("Too many keys in query selector. should be one");
428
+ const k = keys[0];
429
+ if (k === CouchDBGroupOperator.AND)
430
+ accum.push(...val[k]);
431
+ else
432
+ accum.push(val);
433
+ return accum;
434
+ }, []),
435
+ ];
436
+ query.selector = condition;
437
+ break;
438
+ case CouchDBGroupOperator.OR: {
439
+ const s = {};
440
+ s[CouchDBGroupOperator.AND] = [
441
+ condition,
442
+ ...Object.entries(query.selector).map(([key, val]) => {
443
+ const result = {};
444
+ result[key] = val;
445
+ return result;
446
+ }),
447
+ ];
448
+ query.selector = s;
449
+ break;
450
+ }
451
+ default:
452
+ throw new Error("This should be impossible");
453
+ }
454
+ else {
455
+ Object.entries(condition).forEach(([key, val]) => {
456
+ if (query.selector[key])
457
+ console.warn(decoratorValidation.sf("A {0} query param is about to be overridden: {1} by {2}", key, query.selector[key], val));
458
+ query.selector[key] = val;
459
+ });
460
+ }
461
+ return query;
462
+ }
463
+ }
464
+
465
+ class CouchDBSelectClause extends core.SelectClause {
466
+ constructor(clause) {
467
+ super(clause);
468
+ }
469
+ build(query) {
470
+ if (!this.selector || this.selector === core.Const.FULL_RECORD)
471
+ return query;
472
+ query.fields =
473
+ typeof this.selector === "string"
474
+ ? [this.selector]
475
+ : this.selector;
476
+ return query;
477
+ }
478
+ }
479
+
480
+ class CouchDBValuesClause extends core.ValuesClause {
481
+ constructor(clause) {
482
+ super(clause);
483
+ }
484
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
485
+ build(previous) {
486
+ throw new dbDecorators.InternalError("Not implemented");
487
+ }
488
+ }
489
+
490
+ class Factory extends core.ClauseFactory {
491
+ constructor(adapter) {
492
+ super(adapter);
493
+ }
494
+ from(statement, selector) {
495
+ return new CouchDBFromClause({ statement: statement, selector: selector });
496
+ }
497
+ groupBy(statement, selector) {
498
+ return new (class extends core.GroupByClause {
499
+ constructor(clause) {
500
+ super(clause);
501
+ }
502
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
503
+ build(query) {
504
+ throw new dbDecorators.InternalError("Not implemented");
505
+ }
506
+ })({
507
+ statement: statement,
508
+ selector: selector,
509
+ });
510
+ }
511
+ insert() {
512
+ return new CouchDBInsertClause({
513
+ statement: new CouchDBStatement(this.adapter),
514
+ });
515
+ }
516
+ limit(statement, selector) {
517
+ return new (class extends core.LimitClause {
518
+ constructor(clause) {
519
+ super(clause);
520
+ }
521
+ build(query) {
522
+ query.limit = this.selector;
523
+ return query;
524
+ }
525
+ })({
526
+ statement: statement,
527
+ selector: selector,
528
+ });
529
+ }
530
+ offset(statement, selector) {
531
+ return new (class extends core.OffsetClause {
532
+ constructor(clause) {
533
+ super(clause);
534
+ }
535
+ build(query) {
536
+ const skip = parseInt(this.selector);
537
+ if (isNaN(skip))
538
+ throw new core.QueryError("Failed to parse offset");
539
+ query.skip = skip;
540
+ return query;
541
+ }
542
+ })({
543
+ statement: statement,
544
+ selector: selector,
545
+ });
546
+ }
547
+ orderBy(statement, selector) {
548
+ return new (class extends core.OrderByClause {
549
+ constructor(clause) {
550
+ super(clause);
551
+ }
552
+ build(query) {
553
+ query.sort = query.sort || [];
554
+ query.selector = query.selector || {};
555
+ this.selector.forEach((s) => {
556
+ const [selector, value] = s;
557
+ const rec = {};
558
+ rec[selector] = value;
559
+ query.sort.push(rec);
560
+ if (!query.selector[selector]) {
561
+ query.selector[selector] = {};
562
+ query.selector[selector][CouchDBOperator.BIGGER] = null;
563
+ }
564
+ // query.fields = query.fields || [];
565
+ // query.fields = [...new Set([...query.fields, selector]).keys()]
566
+ });
567
+ return query;
568
+ }
569
+ })({
570
+ statement: statement,
571
+ selector: selector,
572
+ });
573
+ }
574
+ select(selector) {
575
+ return new CouchDBSelectClause({
576
+ statement: new CouchDBStatement(this.adapter),
577
+ selector: selector,
578
+ });
579
+ }
580
+ values(statement, values) {
581
+ return new CouchDBValuesClause({
582
+ statement: statement,
583
+ values: values,
584
+ });
585
+ }
586
+ where(statement, condition) {
587
+ return new CouchDBWhereClause({
588
+ statement: statement,
589
+ condition: condition,
590
+ });
591
+ }
592
+ }
593
+
594
+ function translateOperators(operator) {
595
+ for (const operators of [CouchDBOperator, CouchDBGroupOperator]) {
596
+ const el = Object.keys(operators).find((k) => k === operator);
597
+ if (el)
598
+ return operators[el];
599
+ }
600
+ throw new core.QueryError(`Could not find adapter translation for operator ${operator}`);
601
+ }
602
+
603
+ class IndexError extends dbDecorators.BaseError {
604
+ constructor(msg) {
605
+ super(IndexError.name, msg);
606
+ }
607
+ }
608
+
609
+ class CouchDBAdapter extends core.Adapter {
610
+ constructor(scope, flavour) {
611
+ super(scope, flavour);
612
+ [this.create, this.createAll, this.update, this.updateAll].forEach((m) => {
613
+ const name = m.name;
614
+ dbDecorators.prefixMethod(this, m, this[name + "Prefix"]);
615
+ });
616
+ }
617
+ get Clauses() {
618
+ if (!this.factory)
619
+ this.factory = new Factory(this);
620
+ return this.factory;
621
+ }
622
+ Query() {
623
+ return super.Query();
624
+ }
625
+ get Statement() {
626
+ return new CouchDBStatement(this);
627
+ }
628
+ parseCondition(condition) {
629
+ function merge(op, obj1, obj2) {
630
+ const result = { selector: {} };
631
+ result.selector[op] = [obj1, obj2];
632
+ return result;
633
+ }
634
+ const { attr1, operator, comparison } = condition;
635
+ let op = {};
636
+ if ([core.GroupOperator.AND, core.GroupOperator.OR, core.Operator.NOT].indexOf(operator) === -1) {
637
+ op[attr1] = {};
638
+ op[attr1][translateOperators(operator)] =
639
+ comparison;
640
+ }
641
+ else if (operator === core.Operator.NOT) {
642
+ op = this.parseCondition(attr1).selector;
643
+ op[translateOperators(core.Operator.NOT)] = {};
644
+ op[translateOperators(core.Operator.NOT)][attr1.attr1] = comparison;
645
+ }
646
+ else {
647
+ const op1 = this.parseCondition(attr1).selector;
648
+ const op2 = this.parseCondition(comparison).selector;
649
+ op = merge(translateOperators(operator), op1, op2).selector;
650
+ }
651
+ return { selector: op };
652
+ }
653
+ async Sequence(options) {
654
+ return new CouchDBSequence(options, this);
655
+ }
656
+ async initialize() {
657
+ const managedModels = core.Adapter.models(this.flavour);
658
+ return this.index(...managedModels);
659
+ }
660
+ assignMetadata(model, rev) {
661
+ Object.defineProperty(model, core.PersistenceKeys.METADATA, {
662
+ enumerable: false,
663
+ configurable: false,
664
+ writable: false,
665
+ value: rev,
666
+ });
667
+ return model;
668
+ }
669
+ assignMultipleMetadata(models, revs) {
670
+ models.forEach((m, i) => {
671
+ core.Repository.setMetadata(m, revs[i]);
672
+ return m;
673
+ });
674
+ return models;
675
+ }
676
+ createPrefix(tableName, id, model) {
677
+ const record = {};
678
+ record[CouchDBKeys.TABLE] = tableName;
679
+ record[CouchDBKeys.ID] = this.generateId(tableName, id);
680
+ Object.assign(record, model);
681
+ return [tableName, id, record];
682
+ }
683
+ createAllPrefix(tableName, ids, models) {
684
+ if (ids.length !== models.length)
685
+ throw new dbDecorators.InternalError("Ids and models must have the same length");
686
+ const records = ids.map((id, count) => {
687
+ const record = {};
688
+ record[CouchDBKeys.TABLE] = tableName;
689
+ record[CouchDBKeys.ID] = this.generateId(tableName, id);
690
+ Object.assign(record, models[count]);
691
+ return record;
692
+ });
693
+ return [tableName, ids, records];
694
+ }
695
+ updatePrefix(tableName, id, model) {
696
+ const record = {};
697
+ record[CouchDBKeys.TABLE] = tableName;
698
+ record[CouchDBKeys.ID] = this.generateId(tableName, id);
699
+ const rev = model[core.PersistenceKeys.METADATA];
700
+ if (!rev)
701
+ throw new dbDecorators.InternalError(`No revision number found for record with id ${id}`);
702
+ Object.assign(record, model);
703
+ record[CouchDBKeys.REV] = rev;
704
+ return [tableName, id, record];
705
+ }
706
+ updateAllPrefix(tableName, ids, models) {
707
+ if (ids.length !== models.length)
708
+ throw new dbDecorators.InternalError("Ids and models must have the same length");
709
+ const records = ids.map((id, count) => {
710
+ const record = {};
711
+ record[CouchDBKeys.TABLE] = tableName;
712
+ record[CouchDBKeys.ID] = this.generateId(tableName, id);
713
+ const rev = models[count][core.PersistenceKeys.METADATA];
714
+ if (!rev)
715
+ throw new dbDecorators.InternalError(`No revision number found for record with id ${id}`);
716
+ Object.assign(record, models[count]);
717
+ record[CouchDBKeys.REV] = rev;
718
+ return record;
719
+ });
720
+ return [tableName, ids, records];
721
+ }
722
+ generateId(tableName, id) {
723
+ return [tableName, id].join(CouchDBKeys.SEPARATOR);
724
+ }
725
+ parseError(err, reason) {
726
+ return CouchDBAdapter.parseError(err, reason);
727
+ }
728
+ isReserved(attr) {
729
+ return !!attr.match(reservedAttributes);
730
+ }
731
+ static parseError(err, reason) {
732
+ if (err instanceof dbDecorators.BaseError)
733
+ return err;
734
+ let code = "";
735
+ if (typeof err === "string") {
736
+ code = err;
737
+ if (code.match(/already exist|update conflict/g))
738
+ return new dbDecorators.ConflictError(code);
739
+ if (code.match(/missing|deleted/g))
740
+ return new dbDecorators.NotFoundError(code);
741
+ }
742
+ else if (err.code) {
743
+ code = err.code;
744
+ reason = reason || err.message;
745
+ }
746
+ else if (err.statusCode) {
747
+ code = err.statusCode;
748
+ reason = reason || err.message;
749
+ }
750
+ else {
751
+ code = err.message;
752
+ }
753
+ switch (code.toString()) {
754
+ case "401":
755
+ case "412":
756
+ case "409":
757
+ return new dbDecorators.ConflictError(reason);
758
+ case "404":
759
+ return new dbDecorators.NotFoundError(reason);
760
+ case "400":
761
+ if (code.toString().match(/No\sindex\sexists/g))
762
+ return new IndexError(err);
763
+ return new dbDecorators.InternalError(err);
764
+ default:
765
+ if (code.toString().match(/ECONNREFUSED/g))
766
+ return new core.ConnectionError(err);
767
+ return new dbDecorators.InternalError(err);
768
+ }
769
+ }
770
+ }
771
+
772
+ async function reAuth(con, user, pass) {
773
+ return con.auth(user, pass);
774
+ }
775
+ function wrapDocumentScope(con, dbName, user, pass) {
776
+ const db = con.use(dbName);
777
+ ["insert", "get", "put", "destroy", "find"].forEach((k) => {
778
+ const original = db[k];
779
+ Object.defineProperty(db, k, {
780
+ enumerable: false,
781
+ configurable: true,
782
+ value: async (...args) => {
783
+ await reAuth(con, user, pass);
784
+ return original.call(db, ...args);
785
+ },
786
+ });
787
+ });
788
+ Object.defineProperty(db, CouchDBKeys.NATIVE, {
789
+ enumerable: false,
790
+ configurable: false,
791
+ writable: false,
792
+ value: con,
793
+ });
794
+ return db;
795
+ }
796
+ function testReservedAttributes(attr) {
797
+ const regexp = /^_.*$/g;
798
+ return attr.match(regexp);
799
+ }
800
+ function generateIndexName(attribute, tableName, compositions, order, separator = dbDecorators.DefaultSeparator) {
801
+ const attr = [core.PersistenceKeys.INDEX, tableName, attribute];
802
+ if (compositions)
803
+ attr.push(...compositions);
804
+ if (order)
805
+ attr.push(order);
806
+ return attr.join(separator);
807
+ }
808
+ function generateIndexDoc(attribute, tableName, compositions, order, separator = dbDecorators.DefaultSeparator) {
809
+ const partialFilterSelector = {};
810
+ partialFilterSelector[CouchDBKeys.TABLE] = {};
811
+ partialFilterSelector[CouchDBKeys.TABLE][CouchDBOperator.EQUAL] = tableName;
812
+ let fields;
813
+ if (order) {
814
+ const orderProp = {};
815
+ orderProp[attribute] = order;
816
+ const sortedCompositions = (compositions || []).map((c) => {
817
+ const r = {};
818
+ r[c] = order;
819
+ return r;
820
+ });
821
+ const sortedTable = {};
822
+ sortedTable[CouchDBKeys.TABLE] = order;
823
+ fields = [orderProp, ...sortedCompositions, sortedTable];
824
+ }
825
+ else {
826
+ fields = [attribute, ...(compositions || []), CouchDBKeys.TABLE];
827
+ }
828
+ const name = generateIndexName(attribute, tableName, compositions, order, separator);
829
+ return {
830
+ index: {
831
+ fields: fields,
832
+ // partial_filter_selector: partialFilterSelector,
833
+ },
834
+ ddoc: [name, CouchDBKeys.DDOC].join(separator),
835
+ name: name,
836
+ };
837
+ }
838
+
839
+ /**
840
+ * @summary Module summary
841
+ * @description Module description
842
+ * @module ts-workspace
843
+ */
844
+ /**
845
+ * @summary Namespace summary
846
+ * @description Namespace description
847
+ * @namespace Namespace
848
+ * @memberOf module:ts-workspace
849
+ */
850
+ /**
851
+ * @summary stores the current package version
852
+ * @description this is how you should document a constant
853
+ * @const VERSION
854
+ * @memberOf module:ts-workspace
855
+ */
856
+ const VERSION = "0.2.0";
857
+
858
+ exports.CouchDBAdapter = CouchDBAdapter;
859
+ exports.CouchDBKeys = CouchDBKeys;
860
+ exports.CouchDBSequence = CouchDBSequence;
861
+ exports.IndexError = IndexError;
862
+ exports.VERSION = VERSION;
863
+ exports.generateIndexDoc = generateIndexDoc;
864
+ exports.generateIndexName = generateIndexName;
865
+ exports.generateIndexes = generateIndexes;
866
+ exports.reAuth = reAuth;
867
+ exports.reservedAttributes = reservedAttributes;
868
+ exports.testReservedAttributes = testReservedAttributes;
869
+ exports.wrapDocumentScope = wrapDocumentScope;
870
+
871
+ }));
872
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yLWNvdWNoZGIuY2pzIiwic291cmNlcyI6WyIuLi9zcmMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3F1ZXJ5L2NvbnN0YW50cy50cyIsIi4uL3NyYy9pbmRleGVzL2dlbmVyYXRvci50cyIsIi4uL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYuanMiLCIuLi9zcmMvbW9kZWwvQ291Y2hEQlNlcXVlbmNlLnRzIiwiLi4vc3JjL3NlcXVlbmNlcy91dGlscy50cyIsIi4uL3NyYy9zZXF1ZW5jZXMvU2VxdWVuY2UudHMiLCIuLi9zcmMvcXVlcnkvUGFnaW5hdG9yLnRzIiwiLi4vc3JjL3F1ZXJ5L1N0YXRlbWVudC50cyIsIi4uL3NyYy9xdWVyeS9Gcm9tQ2xhdXNlLnRzIiwiLi4vc3JjL3F1ZXJ5L0luc2VydENsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9XaGVyZUNsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9TZWxlY3RDbGF1c2UudHMiLCIuLi9zcmMvcXVlcnkvVmFsdWVzQ2xhdXNlLnRzIiwiLi4vc3JjL3F1ZXJ5L2ZhY3RvcnkudHMiLCIuLi9zcmMvcXVlcnkvdHJhbnNsYXRlLnRzIiwiLi4vc3JjL2Vycm9ycy50cyIsIi4uL3NyYy9hZGFwdGVyLnRzIiwiLi4vc3JjL3V0aWxzLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCByZXNlcnZlZEF0dHJpYnV0ZXMgPSAvXl8uKiQvZztcblxuZXhwb3J0IGNvbnN0IENvdWNoREJLZXlzID0ge1xuICBTRVBBUkFUT1I6IFwiX1wiLFxuICBJRDogXCJfaWRcIixcbiAgUkVWOiBcIl9yZXZcIixcbiAgREVMRVRFRDogXCJfZGVsZXRlZFwiLFxuICBUQUJMRTogXCI/P3RhYmxlXCIsXG4gIFNFUVVFTkNFOiBcIj8/c2VxdWVuY2VcIixcbiAgRERPQzogXCJkZG9jXCIsXG4gIE5BVElWRTogXCJfX25hdGl2ZVwiLFxuICBJTkRFWDogXCJpbmRleFwiLFxufTtcbiIsImltcG9ydCB7IE1hbmdvT3BlcmF0b3IgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZXhwb3J0IGNvbnN0IENvdWNoREJPcGVyYXRvcjogUmVjb3JkPHN0cmluZywgTWFuZ29PcGVyYXRvcj4gPSB7XG4gIEVRVUFMOiBcIiRlcVwiLFxuICBESUZGRVJFTlQ6IFwiJG5lXCIsXG4gIEJJR0dFUjogXCIkZ3RcIixcbiAgQklHR0VSX0VROiBcIiRndGVcIixcbiAgU01BTExFUjogXCIkbHRcIixcbiAgU01BTExFUl9FUTogXCIkbHRlXCIsXG4gIC8vIEJFVFdFRU4gPSBcIkJFVFdFRU5cIixcbiAgTk9UOiBcIiRub3RcIixcbiAgSU46IFwiJGluXCIsXG4gIC8vIElTID0gXCJJU1wiLFxuICBSRUdFWFA6IFwiJHJlZ2V4XCIsXG59O1xuXG5leHBvcnQgY29uc3QgQ291Y2hEQkdyb3VwT3BlcmF0b3I6IFJlY29yZDxzdHJpbmcsIE1hbmdvT3BlcmF0b3I+ID0ge1xuICBBTkQ6IFwiJGFuZFwiLFxuICBPUjogXCIkb3JcIixcbn07XG5cbmV4cG9ydCBjb25zdCBDb3VjaERCQ29uc3Q6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gIE5VTEw6IFwibnVsbFwiLFxufTtcbiIsImltcG9ydCB7XG4gIEluZGV4TWV0YWRhdGEsXG4gIE9yZGVyRGlyZWN0aW9uLFxuICBQZXJzaXN0ZW5jZUtleXMsXG4gIFJlcG9zaXRvcnksXG59IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgQ291Y2hEQktleXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBEZWZhdWx0U2VwYXJhdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBDb3VjaERCT3BlcmF0b3IgfSBmcm9tIFwiLi4vcXVlcnkvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDcmVhdGVJbmRleFJlcXVlc3QgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZnVuY3Rpb24gZ2VuZXJhdGVJbmRleE5hbWUoXG4gIG5hbWU6IHN0cmluZ1tdLFxuICBkaXJlY3Rpb24/OiBPcmRlckRpcmVjdGlvbixcbiAgY29tcG9zaXRpb25zPzogc3RyaW5nW10sXG4gIHNlcGFyYXRvciA9IERlZmF1bHRTZXBhcmF0b3Jcbikge1xuICByZXR1cm4gW1xuICAgIC4uLm5hbWUubWFwKChuKSA9PiAobiA9PT0gQ291Y2hEQktleXMuVEFCTEUgPyBcInRhYmxlXCIgOiBuKSksXG4gICAgLi4uKGNvbXBvc2l0aW9ucyB8fCBbXSksXG4gICAgLi4uKGRpcmVjdGlvbiA/IFtkaXJlY3Rpb25dIDogW10pLFxuICAgIENvdWNoREJLZXlzLklOREVYLFxuICBdLmpvaW4oc2VwYXJhdG9yKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlSW5kZXhlczxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbHM6IENvbnN0cnVjdG9yPE0+W11cbik6IENyZWF0ZUluZGV4UmVxdWVzdFtdIHtcbiAgY29uc3QgdGFibGVOYW1lID0gZ2VuZXJhdGVJbmRleE5hbWUoW0NvdWNoREJLZXlzLlRBQkxFXSk7XG4gIGNvbnN0IGluZGV4ZXM6IFJlY29yZDxzdHJpbmcsIENyZWF0ZUluZGV4UmVxdWVzdD4gPSB7fTtcbiAgaW5kZXhlc1t0YWJsZU5hbWVdID0ge1xuICAgIGluZGV4OiB7XG4gICAgICBmaWVsZHM6IFtDb3VjaERCS2V5cy5UQUJMRV0sXG4gICAgfSxcbiAgICBuYW1lOiB0YWJsZU5hbWUsXG4gICAgZGRvYzogdGFibGVOYW1lLFxuICAgIHR5cGU6IFwianNvblwiLFxuICB9O1xuXG4gIG1vZGVscy5mb3JFYWNoKChtKSA9PiB7XG4gICAgY29uc3QgaW5kOiBSZWNvcmQ8c3RyaW5nLCBJbmRleE1ldGFkYXRhPiA9IFJlcG9zaXRvcnkuaW5kZXhlcyhtKTtcbiAgICBPYmplY3QuZW50cmllcyhpbmQpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgY29uc3QgayA9IE9iamVjdC5rZXlzKHZhbHVlKVswXTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItY29uc3RcbiAgICAgIGxldCB7IGRpcmVjdGlvbnMsIGNvbXBvc2l0aW9ucyB9ID0gKHZhbHVlIGFzIGFueSlba107XG4gICAgICBjb25zdCB0YWJsZU5hbWUgPSBSZXBvc2l0b3J5LnRhYmxlKG0pO1xuICAgICAgY29tcG9zaXRpb25zID0gY29tcG9zaXRpb25zIHx8IFtdO1xuXG4gICAgICBmdW5jdGlvbiBnZW5lcmF0ZShzb3J0PzogT3JkZXJEaXJlY3Rpb24pIHtcbiAgICAgICAgY29uc3QgbmFtZSA9IFtcbiAgICAgICAgICB0YWJsZU5hbWUsXG4gICAgICAgICAga2V5LFxuICAgICAgICAgIC4uLihjb21wb3NpdGlvbnMgYXMgW10pLFxuICAgICAgICAgIFBlcnNpc3RlbmNlS2V5cy5JTkRFWCxcbiAgICAgICAgXS5qb2luKERlZmF1bHRTZXBhcmF0b3IpO1xuXG4gICAgICAgIGluZGV4ZXNbbmFtZV0gPSB7XG4gICAgICAgICAgaW5kZXg6IHtcbiAgICAgICAgICAgIGZpZWxkczogW2tleSwgLi4uKGNvbXBvc2l0aW9ucyBhcyBbXSksIENvdWNoREJLZXlzLlRBQkxFXS5yZWR1Y2UoXG4gICAgICAgICAgICAgIChhY2N1bTogYW55W10sIGVsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHNvcnQpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlczogYW55ID0ge307XG4gICAgICAgICAgICAgICAgICByZXNbZWxdID0gc29ydDtcbiAgICAgICAgICAgICAgICAgIGFjY3VtLnB1c2gocmVzKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgYWNjdW0ucHVzaChlbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgW11cbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgIGRkb2M6IG5hbWUsXG4gICAgICAgICAgdHlwZTogXCJqc29uXCIsXG4gICAgICAgIH07XG4gICAgICAgIGlmICghc29ydCkge1xuICAgICAgICAgIGNvbnN0IHRhYmxlRmlsdGVyOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgICAgICAgdGFibGVGaWx0ZXJbQ291Y2hEQktleXMuVEFCTEVdID0ge307XG4gICAgICAgICAgdGFibGVGaWx0ZXJbQ291Y2hEQktleXMuVEFCTEVdW0NvdWNoREJPcGVyYXRvci5FUVVBTF0gPSB0YWJsZU5hbWU7XG4gICAgICAgICAgaW5kZXhlc1tuYW1lXS5pbmRleC5wYXJ0aWFsX2ZpbHRlcl9zZWxlY3RvciA9IHRhYmxlRmlsdGVyO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGdlbmVyYXRlKCk7XG4gICAgICBpZiAoZGlyZWN0aW9ucylcbiAgICAgICAgKGRpcmVjdGlvbnMgYXMgdW5rbm93biBhcyBPcmRlckRpcmVjdGlvbltdKS5mb3JFYWNoKChkKSA9PiBnZW5lcmF0ZShkKSk7XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gT2JqZWN0LnZhbHVlcyhpbmRleGVzKTtcbn1cbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSwgU3VwcHJlc3NlZEVycm9yLCBTeW1ib2wsIEl0ZXJhdG9yICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2VzRGVjb3JhdGUoY3RvciwgZGVzY3JpcHRvckluLCBkZWNvcmF0b3JzLCBjb250ZXh0SW4sIGluaXRpYWxpemVycywgZXh0cmFJbml0aWFsaXplcnMpIHtcclxuICAgIGZ1bmN0aW9uIGFjY2VwdChmKSB7IGlmIChmICE9PSB2b2lkIDAgJiYgdHlwZW9mIGYgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZ1bmN0aW9uIGV4cGVjdGVkXCIpOyByZXR1cm4gZjsgfVxyXG4gICAgdmFyIGtpbmQgPSBjb250ZXh0SW4ua2luZCwga2V5ID0ga2luZCA9PT0gXCJnZXR0ZXJcIiA/IFwiZ2V0XCIgOiBraW5kID09PSBcInNldHRlclwiID8gXCJzZXRcIiA6IFwidmFsdWVcIjtcclxuICAgIHZhciB0YXJnZXQgPSAhZGVzY3JpcHRvckluICYmIGN0b3IgPyBjb250ZXh0SW5bXCJzdGF0aWNcIl0gPyBjdG9yIDogY3Rvci5wcm90b3R5cGUgOiBudWxsO1xyXG4gICAgdmFyIGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9ySW4gfHwgKHRhcmdldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSkgOiB7fSk7XHJcbiAgICB2YXIgXywgZG9uZSA9IGZhbHNlO1xyXG4gICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgY29udGV4dCA9IHt9O1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluKSBjb250ZXh0W3BdID0gcCA9PT0gXCJhY2Nlc3NcIiA/IHt9IDogY29udGV4dEluW3BdO1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluLmFjY2VzcykgY29udGV4dC5hY2Nlc3NbcF0gPSBjb250ZXh0SW4uYWNjZXNzW3BdO1xyXG4gICAgICAgIGNvbnRleHQuYWRkSW5pdGlhbGl6ZXIgPSBmdW5jdGlvbiAoZikgeyBpZiAoZG9uZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBhZGQgaW5pdGlhbGl6ZXJzIGFmdGVyIGRlY29yYXRpb24gaGFzIGNvbXBsZXRlZFwiKTsgZXh0cmFJbml0aWFsaXplcnMucHVzaChhY2NlcHQoZiB8fCBudWxsKSk7IH07XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9ICgwLCBkZWNvcmF0b3JzW2ldKShraW5kID09PSBcImFjY2Vzc29yXCIgPyB7IGdldDogZGVzY3JpcHRvci5nZXQsIHNldDogZGVzY3JpcHRvci5zZXQgfSA6IGRlc2NyaXB0b3Jba2V5XSwgY29udGV4dCk7XHJcbiAgICAgICAgaWYgKGtpbmQgPT09IFwiYWNjZXNzb3JcIikge1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsIHx8IHR5cGVvZiByZXN1bHQgIT09IFwib2JqZWN0XCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QgZXhwZWN0ZWRcIik7XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5nZXQpKSBkZXNjcmlwdG9yLmdldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5zZXQpKSBkZXNjcmlwdG9yLnNldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5pbml0KSkgaW5pdGlhbGl6ZXJzLnVuc2hpZnQoXyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKF8gPSBhY2NlcHQocmVzdWx0KSkge1xyXG4gICAgICAgICAgICBpZiAoa2luZCA9PT0gXCJmaWVsZFwiKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcclxuICAgICAgICAgICAgZWxzZSBkZXNjcmlwdG9yW2tleV0gPSBfO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0YXJnZXQpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGNvbnRleHRJbi5uYW1lLCBkZXNjcmlwdG9yKTtcclxuICAgIGRvbmUgPSB0cnVlO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcnVuSW5pdGlhbGl6ZXJzKHRoaXNBcmcsIGluaXRpYWxpemVycywgdmFsdWUpIHtcclxuICAgIHZhciB1c2VWYWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbml0aWFsaXplcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB2YWx1ZSA9IHVzZVZhbHVlID8gaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZywgdmFsdWUpIDogaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdXNlVmFsdWUgPyB2YWx1ZSA6IHZvaWQgMDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Byb3BLZXkoeCkge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiID8geCA6IFwiXCIuY29uY2F0KHgpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc2V0RnVuY3Rpb25OYW1lKGYsIG5hbWUsIHByZWZpeCkge1xyXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSBcInN5bWJvbFwiKSBuYW1lID0gbmFtZS5kZXNjcmlwdGlvbiA/IFwiW1wiLmNvbmNhdChuYW1lLmRlc2NyaXB0aW9uLCBcIl1cIikgOiBcIlwiO1xyXG4gICAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmLCBcIm5hbWVcIiwgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBwcmVmaXggPyBcIlwiLmNvbmNhdChwcmVmaXgsIFwiIFwiLCBuYW1lKSA6IG5hbWUgfSk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnID0gT2JqZWN0LmNyZWF0ZSgodHlwZW9mIEl0ZXJhdG9yID09PSBcImZ1bmN0aW9uXCIgPyBJdGVyYXRvciA6IE9iamVjdCkucHJvdG90eXBlKTtcclxuICAgIHJldHVybiBnLm5leHQgPSB2ZXJiKDApLCBnW1widGhyb3dcIl0gPSB2ZXJiKDEpLCBnW1wicmV0dXJuXCJdID0gdmVyYigyKSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChnICYmIChnID0gMCwgb3BbMF0gJiYgKF8gPSAwKSksIF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xyXG4gICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcclxuICAgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xyXG4gICAgfVxyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcclxuICAgIGlmIChwYWNrIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIGZvciAodmFyIGkgPSAwLCBsID0gZnJvbS5sZW5ndGgsIGFyOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xyXG4gICAgICAgICAgICBhcltpXSA9IGZyb21baV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvLmNvbmNhdChhciB8fCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSBPYmplY3QuY3JlYXRlKCh0eXBlb2YgQXN5bmNJdGVyYXRvciA9PT0gXCJmdW5jdGlvblwiID8gQXN5bmNJdGVyYXRvciA6IE9iamVjdCkucHJvdG90eXBlKSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiLCBhd2FpdFJldHVybiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIGF3YWl0UmV0dXJuKGYpIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUodikudGhlbihmLCByZWplY3QpOyB9OyB9XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaWYgKGdbbl0pIHsgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgaWYgKGYpIGlbbl0gPSBmKGlbbl0pOyB9IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBmYWxzZSB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcclxufSkgOiBmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBvW1wiZGVmYXVsdFwiXSA9IHY7XHJcbn07XHJcblxyXG52YXIgb3duS2V5cyA9IGZ1bmN0aW9uKG8pIHtcclxuICAgIG93bktleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB8fCBmdW5jdGlvbiAobykge1xyXG4gICAgICAgIHZhciBhciA9IFtdO1xyXG4gICAgICAgIGZvciAodmFyIGsgaW4gbykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBrKSkgYXJbYXIubGVuZ3RoXSA9IGs7XHJcbiAgICAgICAgcmV0dXJuIGFyO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBvd25LZXlzKG8pO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgPSBvd25LZXlzKG1vZCksIGkgPSAwOyBpIDwgay5sZW5ndGg7IGkrKykgaWYgKGtbaV0gIT09IFwiZGVmYXVsdFwiKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGtbaV0pO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEluKHN0YXRlLCByZWNlaXZlcikge1xyXG4gICAgaWYgKHJlY2VpdmVyID09PSBudWxsIHx8ICh0eXBlb2YgcmVjZWl2ZXIgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlY2VpdmVyICE9PSBcImZ1bmN0aW9uXCIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHVzZSAnaW4nIG9wZXJhdG9yIG9uIG5vbi1vYmplY3RcIik7XHJcbiAgICByZXR1cm4gdHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciA9PT0gc3RhdGUgOiBzdGF0ZS5oYXMocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hZGREaXNwb3NhYmxlUmVzb3VyY2UoZW52LCB2YWx1ZSwgYXN5bmMpIHtcclxuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdm9pZCAwKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZC5cIik7XHJcbiAgICAgICAgdmFyIGRpc3Bvc2UsIGlubmVyO1xyXG4gICAgICAgIGlmIChhc3luYykge1xyXG4gICAgICAgICAgICBpZiAoIVN5bWJvbC5hc3luY0Rpc3Bvc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNEaXNwb3NlIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5hc3luY0Rpc3Bvc2VdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZGlzcG9zZSA9PT0gdm9pZCAwKSB7XHJcbiAgICAgICAgICAgIGlmICghU3ltYm9sLmRpc3Bvc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuZGlzcG9zZSBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICAgICAgICAgIGRpc3Bvc2UgPSB2YWx1ZVtTeW1ib2wuZGlzcG9zZV07XHJcbiAgICAgICAgICAgIGlmIChhc3luYykgaW5uZXIgPSBkaXNwb3NlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodHlwZW9mIGRpc3Bvc2UgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBub3QgZGlzcG9zYWJsZS5cIik7XHJcbiAgICAgICAgaWYgKGlubmVyKSBkaXNwb3NlID0gZnVuY3Rpb24oKSB7IHRyeSB7IGlubmVyLmNhbGwodGhpcyk7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIFByb21pc2UucmVqZWN0KGUpOyB9IH07XHJcbiAgICAgICAgZW52LnN0YWNrLnB1c2goeyB2YWx1ZTogdmFsdWUsIGRpc3Bvc2U6IGRpc3Bvc2UsIGFzeW5jOiBhc3luYyB9KTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGFzeW5jKSB7XHJcbiAgICAgICAgZW52LnN0YWNrLnB1c2goeyBhc3luYzogdHJ1ZSB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB2YWx1ZTtcclxuXHJcbn1cclxuXHJcbnZhciBfU3VwcHJlc3NlZEVycm9yID0gdHlwZW9mIFN1cHByZXNzZWRFcnJvciA9PT0gXCJmdW5jdGlvblwiID8gU3VwcHJlc3NlZEVycm9yIDogZnVuY3Rpb24gKGVycm9yLCBzdXBwcmVzc2VkLCBtZXNzYWdlKSB7XHJcbiAgICB2YXIgZSA9IG5ldyBFcnJvcihtZXNzYWdlKTtcclxuICAgIHJldHVybiBlLm5hbWUgPSBcIlN1cHByZXNzZWRFcnJvclwiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kaXNwb3NlUmVzb3VyY2VzKGVudikge1xyXG4gICAgZnVuY3Rpb24gZmFpbChlKSB7XHJcbiAgICAgICAgZW52LmVycm9yID0gZW52Lmhhc0Vycm9yID8gbmV3IF9TdXBwcmVzc2VkRXJyb3IoZSwgZW52LmVycm9yLCBcIkFuIGVycm9yIHdhcyBzdXBwcmVzc2VkIGR1cmluZyBkaXNwb3NhbC5cIikgOiBlO1xyXG4gICAgICAgIGVudi5oYXNFcnJvciA9IHRydWU7XHJcbiAgICB9XHJcbiAgICB2YXIgciwgcyA9IDA7XHJcbiAgICBmdW5jdGlvbiBuZXh0KCkge1xyXG4gICAgICAgIHdoaWxlIChyID0gZW52LnN0YWNrLnBvcCgpKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXIuYXN5bmMgJiYgcyA9PT0gMSkgcmV0dXJuIHMgPSAwLCBlbnYuc3RhY2sucHVzaChyKSwgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihuZXh0KTtcclxuICAgICAgICAgICAgICAgIGlmIChyLmRpc3Bvc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gci5kaXNwb3NlLmNhbGwoci52YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHIuYXN5bmMpIHJldHVybiBzIHw9IDIsIFByb21pc2UucmVzb2x2ZShyZXN1bHQpLnRoZW4obmV4dCwgZnVuY3Rpb24oZSkgeyBmYWlsKGUpOyByZXR1cm4gbmV4dCgpOyB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgcyB8PSAxO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBmYWlsKGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzID09PSAxKSByZXR1cm4gZW52Lmhhc0Vycm9yID8gUHJvbWlzZS5yZWplY3QoZW52LmVycm9yKSA6IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIGlmIChlbnYuaGFzRXJyb3IpIHRocm93IGVudi5lcnJvcjtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXh0KCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jld3JpdGVSZWxhdGl2ZUltcG9ydEV4dGVuc2lvbihwYXRoLCBwcmVzZXJ2ZUpzeCkge1xyXG4gICAgaWYgKHR5cGVvZiBwYXRoID09PSBcInN0cmluZ1wiICYmIC9eXFwuXFwuP1xcLy8udGVzdChwYXRoKSkge1xyXG4gICAgICAgIHJldHVybiBwYXRoLnJlcGxhY2UoL1xcLih0c3gpJHwoKD86XFwuZCk/KSgoPzpcXC5bXi4vXSs/KT8pXFwuKFtjbV0/KXRzJC9pLCBmdW5jdGlvbiAobSwgdHN4LCBkLCBleHQsIGNtKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0c3ggPyBwcmVzZXJ2ZUpzeCA/IFwiLmpzeFwiIDogXCIuanNcIiA6IGQgJiYgKCFleHQgfHwgIWNtKSA/IG0gOiAoZCArIGV4dCArIFwiLlwiICsgY20udG9Mb3dlckNhc2UoKSArIFwianNcIik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcGF0aDtcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgX19leHRlbmRzOiBfX2V4dGVuZHMsXHJcbiAgICBfX2Fzc2lnbjogX19hc3NpZ24sXHJcbiAgICBfX3Jlc3Q6IF9fcmVzdCxcclxuICAgIF9fZGVjb3JhdGU6IF9fZGVjb3JhdGUsXHJcbiAgICBfX3BhcmFtOiBfX3BhcmFtLFxyXG4gICAgX19lc0RlY29yYXRlOiBfX2VzRGVjb3JhdGUsXHJcbiAgICBfX3J1bkluaXRpYWxpemVyczogX19ydW5Jbml0aWFsaXplcnMsXHJcbiAgICBfX3Byb3BLZXk6IF9fcHJvcEtleSxcclxuICAgIF9fc2V0RnVuY3Rpb25OYW1lOiBfX3NldEZ1bmN0aW9uTmFtZSxcclxuICAgIF9fbWV0YWRhdGE6IF9fbWV0YWRhdGEsXHJcbiAgICBfX2F3YWl0ZXI6IF9fYXdhaXRlcixcclxuICAgIF9fZ2VuZXJhdG9yOiBfX2dlbmVyYXRvcixcclxuICAgIF9fY3JlYXRlQmluZGluZzogX19jcmVhdGVCaW5kaW5nLFxyXG4gICAgX19leHBvcnRTdGFyOiBfX2V4cG9ydFN0YXIsXHJcbiAgICBfX3ZhbHVlczogX192YWx1ZXMsXHJcbiAgICBfX3JlYWQ6IF9fcmVhZCxcclxuICAgIF9fc3ByZWFkOiBfX3NwcmVhZCxcclxuICAgIF9fc3ByZWFkQXJyYXlzOiBfX3NwcmVhZEFycmF5cyxcclxuICAgIF9fc3ByZWFkQXJyYXk6IF9fc3ByZWFkQXJyYXksXHJcbiAgICBfX2F3YWl0OiBfX2F3YWl0LFxyXG4gICAgX19hc3luY0dlbmVyYXRvcjogX19hc3luY0dlbmVyYXRvcixcclxuICAgIF9fYXN5bmNEZWxlZ2F0b3I6IF9fYXN5bmNEZWxlZ2F0b3IsXHJcbiAgICBfX2FzeW5jVmFsdWVzOiBfX2FzeW5jVmFsdWVzLFxyXG4gICAgX19tYWtlVGVtcGxhdGVPYmplY3Q6IF9fbWFrZVRlbXBsYXRlT2JqZWN0LFxyXG4gICAgX19pbXBvcnRTdGFyOiBfX2ltcG9ydFN0YXIsXHJcbiAgICBfX2ltcG9ydERlZmF1bHQ6IF9faW1wb3J0RGVmYXVsdCxcclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQ6IF9fY2xhc3NQcml2YXRlRmllbGRHZXQsXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0OiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0LFxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEluOiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4sXHJcbiAgICBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZTogX19hZGREaXNwb3NhYmxlUmVzb3VyY2UsXHJcbiAgICBfX2Rpc3Bvc2VSZXNvdXJjZXM6IF9fZGlzcG9zZVJlc291cmNlcyxcclxuICAgIF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uOiBfX3Jld3JpdGVSZWxhdGl2ZUltcG9ydEV4dGVuc2lvbixcclxufTtcclxuIiwiaW1wb3J0IHR5cGUgeyBNb2RlbEFyZyB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IG1vZGVsLCByZXF1aXJlZCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEJhc2VNb2RlbCwgcGssIGluZGV4LCB0YWJsZSB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgQ291Y2hEQktleXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5cbkB0YWJsZShDb3VjaERCS2V5cy5TRVFVRU5DRSlcbkBtb2RlbCgpXG5leHBvcnQgY2xhc3MgU2VxdWVuY2UgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogQHN1bW1hcnkgdGhlIFByaW1hcnkga2V5IGZvciB0aGUgREJTZXF1ZW5jZVxuICAgKiBAcHJvcCBuYW1lXG4gICAqXG4gICAqIEBzZWUgcGtcbiAgICovXG4gIEBwaygpXG4gIGlkITogc3RyaW5nO1xuICAvKipcbiAgICogQHN1bW1hcnkgdGhlIGN1cnJlbnQgdmFsdWUgZm9yIHRoZSBEQlNlcXVlbmNlXG4gICAqIEBwcm9wIGN1cnJlbnRcbiAgICpcbiAgICogQHNlZSByZXF1aXJlZFxuICAgKiBAc2VlIGluZGV4XG4gICAqL1xuICBAcmVxdWlyZWQoKVxuICBAaW5kZXgoKVxuICBjdXJyZW50ITogc3RyaW5nIHwgbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHNlcT86IE1vZGVsQXJnPFNlcXVlbmNlPikge1xuICAgIHN1cGVyKHNlcSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU2VxdWVuY2VWYWx1ZShcbiAgdHlwZTogXCJOdW1iZXJcIiB8IFwiQmlnSW50XCIgfCB1bmRlZmluZWQsXG4gIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnRcbik6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgXCJOdW1iZXJcIjpcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCJcbiAgICAgICAgPyBwYXJzZUludCh2YWx1ZSlcbiAgICAgICAgOiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCJcbiAgICAgICAgICA/IHZhbHVlXG4gICAgICAgICAgOiBCaWdJbnQodmFsdWUpO1xuICAgIGNhc2UgXCJCaWdJbnRcIjpcbiAgICAgIHJldHVybiBCaWdJbnQodmFsdWUpO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIlNob3VsZCBuZXZlciBoYXBwZW5cIik7XG4gIH1cbn1cbiIsImltcG9ydCB7IHNmIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgU2VxdWVuY2UgYXMgU2VxIH0gZnJvbSBcIi4uL21vZGVsL0NvdWNoREJTZXF1ZW5jZVwiO1xuaW1wb3J0IHsgSW50ZXJuYWxFcnJvciwgTm90Rm91bmRFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgQWRhcHRlciwgUmVwb3NpdG9yeSwgU2VxdWVuY2VPcHRpb25zIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBTZXF1ZW5jZSB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgcGFyc2VTZXF1ZW5jZVZhbHVlIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IE1hbmdvUXVlcnkgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IENvdWNoREJSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL2ludGVyZmFjZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBBYnN0cmFjdCBpbXBsZW1lbnRhdGlvbiBvZiBhIFNlcXVlbmNlXG4gKiBAZGVzY3JpcHRpb24gcHJvdmlkZXMgdGhlIGJhc2ljIGZ1bmN0aW9uYWxpdHkgZm9yIHtAbGluayBTZXF1ZW5jZX1zXG4gKlxuICogQHBhcmFtIHtTZXF1ZW5jZU9wdGlvbnN9IG9wdGlvbnNcbiAqXG4gKiBAY2xhc3MgQ291Y2hEQlNlcXVlbmNlXG4gKiBAaW1wbGVtZW50cyBTZXF1ZW5jZVxuICpcbiAqIEBjYXRlZ29yeSBTZXF1ZW5jZXNcbiAqL1xuZXhwb3J0IGNsYXNzIENvdWNoREJTZXF1ZW5jZSBleHRlbmRzIFNlcXVlbmNlIHtcbiAgcHJvdGVjdGVkIHJlcG86IENvdWNoREJSZXBvc2l0b3J5PFNlcSwgYW55PjtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBTZXF1ZW5jZU9wdGlvbnMsIGFkYXB0ZXI6IEFkYXB0ZXI8YW55LCBNYW5nb1F1ZXJ5Pikge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMucmVwbyA9IFJlcG9zaXRvcnkuZm9yTW9kZWwoU2VxLCBhZGFwdGVyLmZsYXZvdXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgY3VycmVudCB2YWx1ZSBmb3IgdGhlIHNlcXVlbmNlXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIGFzeW5jIGN1cnJlbnQoKTogUHJvbWlzZTxzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ+IHtcbiAgICBjb25zdCB7IG5hbWUsIHN0YXJ0V2l0aCB9ID0gdGhpcy5vcHRpb25zO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzZXF1ZW5jZTogU2VxID0gYXdhaXQgdGhpcy5yZXBvLnJlYWQobmFtZSBhcyBzdHJpbmcpO1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2Uoc2VxdWVuY2UuY3VycmVudCBhcyBzdHJpbmcgfCBudW1iZXIpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBOb3RGb3VuZEVycm9yKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc3RhcnRXaXRoID09PSBcInVuZGVmaW5lZFwiKVxuICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgICAgXCJTdGFydGluZyB2YWx1ZSBpcyBub3QgZGVmaW5lZCBmb3IgYSBub24gZXhpc3Rpbmcgc2VxdWVuY2VcIlxuICAgICAgICAgICk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2Uoc3RhcnRXaXRoKTtcbiAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgICBzZihcbiAgICAgICAgICAgICAgXCJGYWlsZWQgdG8gcGFyc2UgaW5pdGlhbCB2YWx1ZSBmb3Igc2VxdWVuY2UgezB9OiB7MX1cIixcbiAgICAgICAgICAgICAgc3RhcnRXaXRoLnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgIGVcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgc2YoXG4gICAgICAgICAgXCJGYWlsZWQgdG8gcmV0cmlldmUgY3VycmVudCB2YWx1ZSBmb3Igc2VxdWVuY2UgezB9OiB7MX1cIixcbiAgICAgICAgICBuYW1lIGFzIHN0cmluZyxcbiAgICAgICAgICBlXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFBhcnNlcyB0aGUge0BsaW5rIFNlcXVlbmNlfSB2YWx1ZVxuICAgKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBwYXJhbSB2YWx1ZVxuICAgKi9cbiAgcHJpdmF0ZSBwYXJzZSh2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHtcbiAgICByZXR1cm4gcGFyc2VTZXF1ZW5jZVZhbHVlKHRoaXMub3B0aW9ucy50eXBlLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgaW5jcmVtZW50cyB0aGUgc2VxdWVuY2VcbiAgICogQGRlc2NyaXB0aW9uIFNlcXVlbmNlIHNwZWNpZmljIGltcGxlbWVudGF0aW9uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50fSBjdXJyZW50XG4gICAqIEBwYXJhbSBjb3VudFxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGluY3JlbWVudChcbiAgICBjdXJyZW50OiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQsXG4gICAgY291bnQ/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ+IHtcbiAgICBjb25zdCB7IHR5cGUsIGluY3JlbWVudEJ5LCBuYW1lIH0gPSB0aGlzLm9wdGlvbnM7XG4gICAgbGV0IG5leHQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludDtcbiAgICBjb25zdCB0b0luY3JlbWVudEJ5ID0gY291bnQgfHwgaW5jcmVtZW50Qnk7XG4gICAgaWYgKHRvSW5jcmVtZW50QnkgJSBpbmNyZW1lbnRCeSAhPT0gMClcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgVmFsdWUgdG8gaW5jcmVtZW50IGRvZXMgbm90IGNvbnNpZGVyIHRoZSBpbmNyZW1lbnRCeSBzZXR0aW5nOiAke2luY3JlbWVudEJ5fWBcbiAgICAgICk7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIFwiTnVtYmVyXCI6XG4gICAgICAgIG5leHQgPSAodGhpcy5wYXJzZShjdXJyZW50KSBhcyBudW1iZXIpICsgdG9JbmNyZW1lbnRCeTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiQmlnSW50XCI6XG4gICAgICAgIG5leHQgPSAodGhpcy5wYXJzZShjdXJyZW50KSBhcyBiaWdpbnQpICsgQmlnSW50KHRvSW5jcmVtZW50QnkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiU2hvdWxkIG5ldmVyIGhhcHBlblwiKTtcbiAgICB9XG4gICAgbGV0IHNlcTogU2VxO1xuICAgIHRyeSB7XG4gICAgICBzZXEgPSBhd2FpdCB0aGlzLnJlcG8udXBkYXRlKG5ldyBTZXEoeyBpZDogbmFtZSwgY3VycmVudDogbmV4dCB9KSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoIShlIGluc3RhbmNlb2YgTm90Rm91bmRFcnJvcikpIHRocm93IGU7XG4gICAgICBzZXEgPSBhd2FpdCB0aGlzLnJlcG8uY3JlYXRlKG5ldyBTZXEoeyBpZDogbmFtZSwgY3VycmVudDogbmV4dCB9KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlcS5jdXJyZW50IGFzIHN0cmluZyB8IG51bWJlciB8IGJpZ2ludDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBHZW5lcmF0ZXMgdGhlIG5leHQgdmFsdWUgaW4gdGggc2VxdWVuY2VcbiAgICogQGRlc2NyaXB0aW9uIGNhbGxzIHtAbGluayBTZXF1ZW5jZSNwYXJzZX0gb24gdGhlIGN1cnJlbnQgdmFsdWVcbiAgICogZm9sbG93ZWQgYnkge0BsaW5rIFNlcXVlbmNlI2luY3JlbWVudH1cbiAgICpcbiAgICovXG4gIGFzeW5jIG5leHQoKTogUHJvbWlzZTxudW1iZXIgfCBzdHJpbmcgfCBiaWdpbnQ+IHtcbiAgICBjb25zdCBjdXJyZW50ID0gYXdhaXQgdGhpcy5jdXJyZW50KCk7XG4gICAgcmV0dXJuIHRoaXMuaW5jcmVtZW50KGN1cnJlbnQpO1xuICB9XG5cbiAgYXN5bmMgcmFuZ2UoY291bnQ6IG51bWJlcik6IFByb21pc2U8KG51bWJlciB8IHN0cmluZyB8IGJpZ2ludClbXT4ge1xuICAgIGNvbnN0IGN1cnJlbnQgPSAoYXdhaXQgdGhpcy5jdXJyZW50KCkpIGFzIG51bWJlcjtcbiAgICBjb25zdCBpbmNyZW1lbnRCeSA9IHRoaXMucGFyc2UodGhpcy5vcHRpb25zLmluY3JlbWVudEJ5KSBhcyBudW1iZXI7XG4gICAgY29uc3QgbmV4dDogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50ID0gYXdhaXQgdGhpcy5pbmNyZW1lbnQoXG4gICAgICBjdXJyZW50LFxuICAgICAgKHRoaXMucGFyc2UoY291bnQpIGFzIG51bWJlcikgKiBpbmNyZW1lbnRCeVxuICAgICk7XG4gICAgY29uc3QgcmFuZ2U6IChudW1iZXIgfCBzdHJpbmcgfCBiaWdpbnQpW10gPSBbXTtcbiAgICBmb3IgKGxldCBpOiBudW1iZXIgPSAxOyBpIDw9IGNvdW50OyBpKyspIHtcbiAgICAgIHJhbmdlLnB1c2goY3VycmVudCArIGluY3JlbWVudEJ5ICogKHRoaXMucGFyc2UoaSkgYXMgbnVtYmVyKSk7XG4gICAgfVxuICAgIGlmIChyYW5nZVtyYW5nZS5sZW5ndGggLSAxXSAhPT0gbmV4dClcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTWlzY2FsY3VsYXRpb24gb2YgcmFuZ2VcIik7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBQYWdpbmF0b3IsXG4gIFBhZ2luZ0Vycm9yLFxuICBTZXF1ZW5jZU9wdGlvbnMsXG4gIFN0YXRlbWVudCxcbn0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQge1xuICBEZWZhdWx0U2VwYXJhdG9yLFxuICBmaW5kUHJpbWFyeUtleSxcbiAgSW50ZXJuYWxFcnJvcixcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBwYXJzZVNlcXVlbmNlVmFsdWUgfSBmcm9tIFwiLi4vc2VxdWVuY2VzL3V0aWxzXCI7XG5pbXBvcnQgeyBNYW5nb1F1ZXJ5LCBNYW5nb1Jlc3BvbnNlIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBDb3VjaERCUGFnaW5hdG9yPFY+IGV4dGVuZHMgUGFnaW5hdG9yPFYsIE1hbmdvUXVlcnk+IHtcbiAgcHJpdmF0ZSBib29rTWFyaz86IHN0cmluZztcblxuICBnZXQgdG90YWwoKTogbnVtYmVyIHtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgVGhlIHRvdGFsIHBhZ2VzIGFwaSBpcyBub3QgYXZhaWxhYmxlIGZvciBjb3VjaGRiYCk7XG4gIH1cblxuICBnZXQgY291bnQoKTogbnVtYmVyIHtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBUaGUgcmVjb3JkIGNvdW50IGFwaSBpcyBub3QgYXZhaWxhYmxlIGZvciBjb3VjaGRiYFxuICAgICk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxNYW5nb1F1ZXJ5PixcbiAgICBzaXplOiBudW1iZXIsXG4gICAgcmF3U3RhdGVtZW50OiBNYW5nb1F1ZXJ5XG4gICkge1xuICAgIHN1cGVyKHN0YXRlbWVudCwgc2l6ZSwgcmF3U3RhdGVtZW50KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwcmVwYXJlKHJhd1N0YXRlbWVudDogTWFuZ29RdWVyeSk6IE1hbmdvUXVlcnkge1xuICAgIGNvbnN0IHF1ZXJ5OiBNYW5nb1F1ZXJ5ID0gT2JqZWN0LmFzc2lnbih7fSwgcmF3U3RhdGVtZW50KTtcbiAgICBpZiAocXVlcnkubGltaXQpIHRoaXMubGltaXQgPSBxdWVyeS5saW1pdDtcblxuICAgIHF1ZXJ5LmxpbWl0ID0gdGhpcy5zaXplO1xuXG4gICAgcmV0dXJuIHF1ZXJ5O1xuICB9XG5cbiAgYXN5bmMgcGFnZShwYWdlOiBudW1iZXIgPSAxLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8VltdPiB7XG4gICAgY29uc3Qgc3RhdGVtZW50ID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5zdGF0ZW1lbnQpO1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuc3RhdC5nZXRUYXJnZXQoKTtcbiAgICAvLyBpZiAoIXRoaXMuX3JlY29yZENvdW50IHx8ICF0aGlzLl90b3RhbFBhZ2VzKSB7XG4gICAgLy8gICAvLyB0aGlzLl9yZWNvcmRDb3VudCA9IGF3YWl0IHRoaXMuYWRhcHRlclxuICAgIC8vICAgLy8gICAuUXVlcnkoKVxuICAgIC8vICAgLy8gICAuY291bnQoKVxuICAgIC8vICAgLy8gICAuZnJvbSh0YXJnZXQpXG4gICAgLy8gICAvLyAgIC5leGVjdXRlPG51bWJlcj4oKTtcbiAgICAvLyB9XG5cbiAgICBpZiAocGFnZSAhPT0gMSkge1xuICAgICAgaWYgKCF0aGlzLmJvb2tNYXJrKVxuICAgICAgICB0aHJvdyBuZXcgUGFnaW5nRXJyb3IoXCJObyBib29rbWFyay4gRGlkIHlvdSBzdGFydCBpbiB0aGUgZmlyc3QgcGFnZT9cIik7XG4gICAgICBzdGF0ZW1lbnRbXCJib29rbWFya1wiXSA9IHRoaXMuYm9va01hcms7XG4gICAgfVxuICAgIGNvbnN0IHJhd1Jlc3VsdDogTWFuZ29SZXNwb25zZTxhbnk+ID0gYXdhaXQgdGhpcy5hZGFwdGVyLnJhdyhcbiAgICAgIHN0YXRlbWVudCxcbiAgICAgIGZhbHNlLFxuICAgICAgLi4uYXJnc1xuICAgICk7XG5cbiAgICBjb25zdCB7IGRvY3MsIGJvb2ttYXJrLCB3YXJuaW5nIH0gPSByYXdSZXN1bHQ7XG4gICAgaWYgKHdhcm5pbmcpIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbiAgICBjb25zdCByZXN1bHRzID1cbiAgICAgIHN0YXRlbWVudC5maWVsZHMgJiYgc3RhdGVtZW50LmZpZWxkcy5sZW5ndGhcbiAgICAgICAgPyBkb2NzIC8vIGhhcyBmaWVsZHMgbWVhbnMgaXRzIG5vdCBmdWxsIG1vZGVsXG4gICAgICAgIDogZG9jcy5tYXAoKGQ6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy9ubyBmaWVsZHMgbWVhbnMgd2UgbmVlZCB0byByZXZlcnQgdG8gc2F2aW5nIHByb2Nlc3NcbiAgICAgICAgICAgIGlmICghdGFyZ2V0KSB0aHJvdyBuZXcgUGFnaW5nRXJyb3IoXCJObyBzdGF0ZW1lbnQgdGFyZ2V0IGRlZmluZWRcIik7XG4gICAgICAgICAgICBjb25zdCBwa0RlZiA9IGZpbmRQcmltYXJ5S2V5KG5ldyB0YXJnZXQoKSkgYXMge1xuICAgICAgICAgICAgICBpZDogc3RyaW5nO1xuICAgICAgICAgICAgICBwcm9wczogU2VxdWVuY2VPcHRpb25zO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHBrID0gcGtEZWYuaWQ7XG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbElkID0gZC5faWQuc3BsaXQoRGVmYXVsdFNlcGFyYXRvcik7XG4gICAgICAgICAgICBvcmlnaW5hbElkLnNwbGljZSgwLCAxKTsgLy8gcmVtb3ZlIHRoZSB0YWJsZSBuYW1lXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydChcbiAgICAgICAgICAgICAgZCxcbiAgICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgICBwayxcbiAgICAgICAgICAgICAgcGFyc2VTZXF1ZW5jZVZhbHVlKFxuICAgICAgICAgICAgICAgIHBrRGVmLnByb3BzLnR5cGUsXG4gICAgICAgICAgICAgICAgb3JpZ2luYWxJZC5qb2luKERlZmF1bHRTZXBhcmF0b3IpXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgdGhpcy5ib29rTWFyayA9IGJvb2ttYXJrO1xuICAgIHRoaXMuX2N1cnJlbnRQYWdlID0gcGFnZTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxufVxuIiwiaW1wb3J0IHsgQWRhcHRlciwgU3RhdGVtZW50IH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBmaW5kUHJpbWFyeUtleSwgSW50ZXJuYWxFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBDb3VjaERCS2V5cyB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHBhcnNlU2VxdWVuY2VWYWx1ZSB9IGZyb20gXCIuLi9zZXF1ZW5jZXMvdXRpbHNcIjtcbmltcG9ydCB7IFBhZ2luYXRvciB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgQ291Y2hEQlBhZ2luYXRvciB9IGZyb20gXCIuL1BhZ2luYXRvclwiO1xuaW1wb3J0IHsgTWFuZ29RdWVyeSB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG5leHBvcnQgY2xhc3MgQ291Y2hEQlN0YXRlbWVudDxZPiBleHRlbmRzIFN0YXRlbWVudDxNYW5nb1F1ZXJ5PiB7XG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXI6IEFkYXB0ZXI8WSwgTWFuZ29RdWVyeT4pIHtcbiAgICBzdXBlcihhZGFwdGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZTxZPigpOiBQcm9taXNlPFk+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcXVlcnk6IE1hbmdvUXVlcnkgPSB0aGlzLmJ1aWxkKCk7XG4gICAgICBpZiAoIXF1ZXJ5LmxpbWl0KSBxdWVyeS5saW1pdCA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSO1xuICAgICAgcmV0dXJuIHRoaXMucmF3KHF1ZXJ5KTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGUpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHBhZ2luYXRlPFI+KHNpemU6IG51bWJlcik6IFByb21pc2U8UGFnaW5hdG9yPFIsIE1hbmdvUXVlcnk+PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHF1ZXJ5OiBNYW5nb1F1ZXJ5ID0gdGhpcy5idWlsZCgpO1xuICAgICAgcmV0dXJuIG5ldyBDb3VjaERCUGFnaW5hdG9yKHRoaXMsIHNpemUsIHF1ZXJ5KTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc1JlY29yZChcbiAgICByOiBhbnksXG4gICAgcGtBdHRyOiBzdHJpbmcsXG4gICAgc2VxdWVuY2VUeXBlOiBcIk51bWJlclwiIHwgXCJCaWdJbnRcIiB8IHVuZGVmaW5lZFxuICApIHtcbiAgICBpZiAoIXJbQ291Y2hEQktleXMuSURdKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBObyBDb3VjaERCIElkIGRlZmluaXRpb24gZm91bmQuIFNob3VsZCBub3QgYmUgcG9zc2libGVgXG4gICAgICApO1xuICAgIGNvbnN0IFssIC4uLmtleUFyZ3NdID0gcltDb3VjaERCS2V5cy5JRF0uc3BsaXQoXCJfXCIpO1xuXG4gICAgY29uc3QgaWQgPSBrZXlBcmdzLmpvaW4oXCJfXCIpO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIucmV2ZXJ0KFxuICAgICAgcixcbiAgICAgIHRoaXMudGFyZ2V0IGFzIENvbnN0cnVjdG9yPGFueT4sXG4gICAgICBwa0F0dHIsXG4gICAgICBwYXJzZVNlcXVlbmNlVmFsdWUoc2VxdWVuY2VUeXBlLCBpZClcbiAgICApIGFzIGFueTtcbiAgfVxuXG4gIGFzeW5jIHJhdzxSPihyYXdJbnB1dDogTWFuZ29RdWVyeSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFI+IHtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5hZGFwdGVyLnJhdzxSPihyYXdJbnB1dCwgdHJ1ZSwgLi4uYXJncyk7XG4gICAgaWYgKCF0aGlzLmZ1bGxSZWNvcmQpIHJldHVybiByZXN1bHRzO1xuICAgIGlmICghdGhpcy50YXJnZXQpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgXCJObyB0YXJnZXQgZGVmaW5lZCBpbiBzdGF0ZW1lbnQuIHNob3VsZCBuZXZlciBoYXBwZW5cIlxuICAgICAgKTtcblxuICAgIGNvbnN0IHBrRGVmID0gZmluZFByaW1hcnlLZXkobmV3IHRoaXMudGFyZ2V0KCkgYXMgYW55KTtcbiAgICBjb25zdCBwa0F0dHIgPSBwa0RlZi5pZDtcbiAgICBjb25zdCB0eXBlID0gcGtEZWYucHJvcHMudHlwZTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRzKSlcbiAgICAgIHJldHVybiByZXN1bHRzLm1hcCgocikgPT4gdGhpcy5wcm9jZXNzUmVjb3JkKHIsIHBrQXR0ciwgdHlwZSkpIGFzIFI7XG4gICAgcmV0dXJuIHRoaXMucHJvY2Vzc1JlY29yZChyZXN1bHRzLCBwa0F0dHIsIHR5cGUpIGFzIFI7XG4gIH1cbn1cbiIsImltcG9ydCB7IEZyb21DbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE1vZGVsQXJnLCBNb2RlbCwgQ29uc3RydWN0b3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBDb3VjaERCS2V5cyB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE1hbmdvUXVlcnkgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLy8gbm9pbnNwZWN0aW9uIEpTQW5ub3RhdG9yXG5leHBvcnQgY2xhc3MgQ291Y2hEQkZyb21DbGF1c2U8TSBleHRlbmRzIE1vZGVsPiBleHRlbmRzIEZyb21DbGF1c2U8XG4gIE1hbmdvUXVlcnksXG4gIE1cbj4ge1xuICBjb25zdHJ1Y3RvcihjbGF1c2U6IE1vZGVsQXJnPEZyb21DbGF1c2U8TWFuZ29RdWVyeSwgTT4+KSB7XG4gICAgc3VwZXIoY2xhdXNlKTtcbiAgfVxuXG4gIGJ1aWxkKHByZXZpb3VzOiBNYW5nb1F1ZXJ5KTogTWFuZ29RdWVyeSB7XG4gICAgY29uc3Qgc2VsZWN0b3JzOiBhbnkgPSB7fTtcbiAgICBzZWxlY3RvcnNbQ291Y2hEQktleXMuVEFCTEVdID0ge307XG4gICAgc2VsZWN0b3JzW0NvdWNoREJLZXlzLlRBQkxFXSA9XG4gICAgICB0eXBlb2YgdGhpcy5zZWxlY3RvciA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IHRoaXMuc2VsZWN0b3JcbiAgICAgICAgOiBSZXBvc2l0b3J5LnRhYmxlKHRoaXMuc2VsZWN0b3IgYXMgQ29uc3RydWN0b3I8TT4pO1xuICAgIHByZXZpb3VzLnNlbGVjdG9yID0gc2VsZWN0b3JzO1xuICAgIHJldHVybiBwcmV2aW91cztcbiAgfVxufVxuIiwiaW1wb3J0IHsgSW5zZXJ0Q2xhdXNlIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBNb2RlbEFyZywgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNYW5nb1F1ZXJ5IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8vIG5vaW5zcGVjdGlvbiBKU0Fubm90YXRvclxuZXhwb3J0IGNsYXNzIENvdWNoREJJbnNlcnRDbGF1c2U8TSBleHRlbmRzIE1vZGVsPiBleHRlbmRzIEluc2VydENsYXVzZTxcbiAgTWFuZ29RdWVyeSxcbiAgTVxuPiB7XG4gIGNvbnN0cnVjdG9yKGNsYXVzZTogTW9kZWxBcmc8SW5zZXJ0Q2xhdXNlPE1hbmdvUXVlcnksIE0+Pikge1xuICAgIHN1cGVyKGNsYXVzZSk7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGJ1aWxkKHF1ZXJ5OiBNYW5nb1F1ZXJ5KTogTWFuZ29RdWVyeSB7XG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJOb3Qgc3VwcG9ydGVkXCIpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBDb25kaXRpb24sIFdoZXJlQ2xhdXNlIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBNb2RlbEFyZyB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IENvdWNoREJHcm91cE9wZXJhdG9yIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBzZiB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IENvdWNoREJLZXlzIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgTWFuZ29PcGVyYXRvciwgTWFuZ29RdWVyeSwgTWFuZ29TZWxlY3RvciB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG5leHBvcnQgY2xhc3MgQ291Y2hEQldoZXJlQ2xhdXNlIGV4dGVuZHMgV2hlcmVDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICBjb25zdHJ1Y3RvcihjbGF1c2U6IE1vZGVsQXJnPFdoZXJlQ2xhdXNlPE1hbmdvUXVlcnk+Pikge1xuICAgIHN1cGVyKGNsYXVzZSk7XG4gIH1cblxuICBidWlsZChxdWVyeTogTWFuZ29RdWVyeSk6IE1hbmdvUXVlcnkge1xuICAgIGNvbnN0IGNvbmRpdGlvbjogTWFuZ29TZWxlY3RvciA9IHRoaXMuYWRhcHRlci5wYXJzZUNvbmRpdGlvbihcbiAgICAgIENvbmRpdGlvbi5hbmQoXG4gICAgICAgIHRoaXMuY29uZGl0aW9uIGFzIENvbmRpdGlvbixcbiAgICAgICAgQ29uZGl0aW9uLmF0dHJpYnV0ZShDb3VjaERCS2V5cy5UQUJMRSkuZXEoXG4gICAgICAgICAgcXVlcnkuc2VsZWN0b3JbQ291Y2hEQktleXMuVEFCTEVdXG4gICAgICAgIClcbiAgICAgIClcbiAgICApLnNlbGVjdG9yO1xuXG4gICAgY29uc3Qgc2VsZWN0b3JLZXlzID0gT2JqZWN0LmtleXMoY29uZGl0aW9uKSBhcyBNYW5nb09wZXJhdG9yW107XG4gICAgaWYgKFxuICAgICAgc2VsZWN0b3JLZXlzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgT2JqZWN0LnZhbHVlcyhDb3VjaERCR3JvdXBPcGVyYXRvcikuaW5kZXhPZihzZWxlY3RvcktleXNbMF0pICE9PSAtMVxuICAgIClcbiAgICAgIHN3aXRjaCAoc2VsZWN0b3JLZXlzWzBdKSB7XG4gICAgICAgIGNhc2UgQ291Y2hEQkdyb3VwT3BlcmF0b3IuQU5EOlxuICAgICAgICAgIGNvbmRpdGlvbltDb3VjaERCR3JvdXBPcGVyYXRvci5BTkRdID0gW1xuICAgICAgICAgICAgLi4uT2JqZWN0LnZhbHVlcyhcbiAgICAgICAgICAgICAgY29uZGl0aW9uW0NvdWNoREJHcm91cE9wZXJhdG9yLkFORF0gYXMgTWFuZ29TZWxlY3RvclxuICAgICAgICAgICAgKS5yZWR1Y2UoKGFjY3VtOiBNYW5nb1NlbGVjdG9yW10sIHZhbDogYW55KSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyh2YWwpO1xuICAgICAgICAgICAgICBpZiAoa2V5cy5sZW5ndGggIT09IDEpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgXCJUb28gbWFueSBrZXlzIGluIHF1ZXJ5IHNlbGVjdG9yLiBzaG91bGQgYmUgb25lXCJcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBjb25zdCBrID0ga2V5c1swXTtcbiAgICAgICAgICAgICAgaWYgKGsgPT09IENvdWNoREJHcm91cE9wZXJhdG9yLkFORClcbiAgICAgICAgICAgICAgICBhY2N1bS5wdXNoKC4uLih2YWxba10gYXMgYW55W10pKTtcbiAgICAgICAgICAgICAgZWxzZSBhY2N1bS5wdXNoKHZhbCk7XG4gICAgICAgICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgICAgICAgIH0sIFtdKSxcbiAgICAgICAgICBdO1xuICAgICAgICAgIHF1ZXJ5LnNlbGVjdG9yID0gY29uZGl0aW9uO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIENvdWNoREJHcm91cE9wZXJhdG9yLk9SOiB7XG4gICAgICAgICAgY29uc3QgczogUmVjb3JkPGFueSwgYW55PiA9IHt9O1xuICAgICAgICAgIHNbQ291Y2hEQkdyb3VwT3BlcmF0b3IuQU5EXSA9IFtcbiAgICAgICAgICAgIGNvbmRpdGlvbixcbiAgICAgICAgICAgIC4uLk9iamVjdC5lbnRyaWVzKHF1ZXJ5LnNlbGVjdG9yKS5tYXAoKFtrZXksIHZhbF0pID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVzdWx0OiBSZWNvcmQ8YW55LCBhbnk+ID0ge307XG4gICAgICAgICAgICAgIHJlc3VsdFtrZXldID0gdmFsO1xuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgXTtcbiAgICAgICAgICBxdWVyeS5zZWxlY3RvciA9IHM7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIHNob3VsZCBiZSBpbXBvc3NpYmxlXCIpO1xuICAgICAgfVxuICAgIGVsc2Uge1xuICAgICAgT2JqZWN0LmVudHJpZXMoY29uZGl0aW9uKS5mb3JFYWNoKChba2V5LCB2YWxdKSA9PiB7XG4gICAgICAgIGlmIChxdWVyeS5zZWxlY3RvcltrZXldKVxuICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgIHNmKFxuICAgICAgICAgICAgICBcIkEgezB9IHF1ZXJ5IHBhcmFtIGlzIGFib3V0IHRvIGJlIG92ZXJyaWRkZW46IHsxfSBieSB7Mn1cIixcbiAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICBxdWVyeS5zZWxlY3RvcltrZXldIGFzIHVua25vd24gYXMgc3RyaW5nLFxuICAgICAgICAgICAgICB2YWwgYXMgdW5rbm93biBhcyBzdHJpbmdcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICBxdWVyeS5zZWxlY3RvcltrZXldID0gdmFsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHF1ZXJ5O1xuICB9XG59XG4iLCJpbXBvcnQgeyBDb25zdCwgU2VsZWN0Q2xhdXNlIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBNb2RlbEFyZywgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBNYW5nb1F1ZXJ5IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBDb3VjaERCU2VsZWN0Q2xhdXNlPE0gZXh0ZW5kcyBNb2RlbD4gZXh0ZW5kcyBTZWxlY3RDbGF1c2U8XG4gIE1hbmdvUXVlcnksXG4gIE1cbj4ge1xuICBjb25zdHJ1Y3RvcihjbGF1c2U6IE1vZGVsQXJnPFNlbGVjdENsYXVzZTxNYW5nb1F1ZXJ5LCBNPj4pIHtcbiAgICBzdXBlcihjbGF1c2UpO1xuICB9XG5cbiAgYnVpbGQocXVlcnk6IE1hbmdvUXVlcnkpOiBNYW5nb1F1ZXJ5IHtcbiAgICBpZiAoIXRoaXMuc2VsZWN0b3IgfHwgdGhpcy5zZWxlY3RvciA9PT0gQ29uc3QuRlVMTF9SRUNPUkQpIHJldHVybiBxdWVyeTtcbiAgICBxdWVyeS5maWVsZHMgPVxuICAgICAgdHlwZW9mIHRoaXMuc2VsZWN0b3IgPT09IFwic3RyaW5nXCJcbiAgICAgICAgPyBbdGhpcy5zZWxlY3RvciBhcyBzdHJpbmddXG4gICAgICAgIDogKHRoaXMuc2VsZWN0b3IgYXMgc3RyaW5nW10pO1xuICAgIHJldHVybiBxdWVyeTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVmFsdWVzQ2xhdXNlIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBNb2RlbEFyZywgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNYW5nb1F1ZXJ5IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBDb3VjaERCVmFsdWVzQ2xhdXNlPE0gZXh0ZW5kcyBNb2RlbD4gZXh0ZW5kcyBWYWx1ZXNDbGF1c2U8XG4gIE1hbmdvUXVlcnksXG4gIE1cbj4ge1xuICBjb25zdHJ1Y3RvcihjbGF1c2U6IE1vZGVsQXJnPFZhbHVlc0NsYXVzZTxNYW5nb1F1ZXJ5LCBNPj4pIHtcbiAgICBzdXBlcihjbGF1c2UpO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBidWlsZChwcmV2aW91czogTWFuZ29RdWVyeSk6IE1hbmdvUXVlcnkge1xuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTm90IGltcGxlbWVudGVkXCIpO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBDbGF1c2VGYWN0b3J5LFxuICBDb25kaXRpb24sXG4gIEZyb21DbGF1c2UsXG4gIEZyb21TZWxlY3RvcixcbiAgR3JvdXBCeVNlbGVjdG9yLFxuICBMaW1pdFNlbGVjdG9yLFxuICBPZmZzZXRTZWxlY3RvcixcbiAgT3JkZXJCeVNlbGVjdG9yLFxuICBRdWVyeUVycm9yLFxuICBTZWxlY3RTZWxlY3RvcixcbiAgU3RhdGVtZW50LFxufSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IExpbWl0Q2xhdXNlIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBTZWxlY3RDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IFdoZXJlQ2xhdXNlIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBPZmZzZXRDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE9yZGVyQnlDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IEdyb3VwQnlDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IFZhbHVlc0NsYXVzZSB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgSW5zZXJ0Q2xhdXNlIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBDb3VjaERCRnJvbUNsYXVzZSB9IGZyb20gXCIuL0Zyb21DbGF1c2VcIjtcbmltcG9ydCB7IE1vZGVsQXJnLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IENvdWNoREJJbnNlcnRDbGF1c2UgfSBmcm9tIFwiLi9JbnNlcnRDbGF1c2VcIjtcbmltcG9ydCB7IENvdWNoREJTdGF0ZW1lbnQgfSBmcm9tIFwiLi9TdGF0ZW1lbnRcIjtcbmltcG9ydCB7IENvdWNoREJXaGVyZUNsYXVzZSB9IGZyb20gXCIuL1doZXJlQ2xhdXNlXCI7XG5pbXBvcnQgeyBDb3VjaERCU2VsZWN0Q2xhdXNlIH0gZnJvbSBcIi4vU2VsZWN0Q2xhdXNlXCI7XG5pbXBvcnQgeyBDb3VjaERCVmFsdWVzQ2xhdXNlIH0gZnJvbSBcIi4vVmFsdWVzQ2xhdXNlXCI7XG5pbXBvcnQgeyBDb3VjaERCT3BlcmF0b3IgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IENvdWNoREJBZGFwdGVyIH0gZnJvbSBcIi4uL2FkYXB0ZXJcIjtcbmltcG9ydCB7IE1hbmdvUXVlcnksIE1hbmdvU2VsZWN0b3IgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZXhwb3J0IGNsYXNzIEZhY3Rvcnk8Uz4gZXh0ZW5kcyBDbGF1c2VGYWN0b3J5PFMsIE1hbmdvUXVlcnk+IHtcbiAgY29uc3RydWN0b3IoYWRhcHRlcjogQ291Y2hEQkFkYXB0ZXI8Uz4pIHtcbiAgICBzdXBlcihhZGFwdGVyKTtcbiAgfVxuXG4gIGZyb208TSBleHRlbmRzIE1vZGVsPihcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxNYW5nb1F1ZXJ5PixcbiAgICBzZWxlY3RvcjogRnJvbVNlbGVjdG9yPE0+XG4gICk6IEZyb21DbGF1c2U8TWFuZ29RdWVyeSwgTT4ge1xuICAgIHJldHVybiBuZXcgQ291Y2hEQkZyb21DbGF1c2UoeyBzdGF0ZW1lbnQ6IHN0YXRlbWVudCwgc2VsZWN0b3I6IHNlbGVjdG9yIH0pO1xuICB9XG5cbiAgZ3JvdXBCeShcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxNYW5nb1F1ZXJ5PixcbiAgICBzZWxlY3RvcjogR3JvdXBCeVNlbGVjdG9yXG4gICk6IEdyb3VwQnlDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICAgIHJldHVybiBuZXcgKGNsYXNzIGV4dGVuZHMgR3JvdXBCeUNsYXVzZTxNYW5nb1F1ZXJ5PiB7XG4gICAgICBjb25zdHJ1Y3RvcihjbGF1c2U6IE1vZGVsQXJnPEdyb3VwQnlDbGF1c2U8TWFuZ29RdWVyeT4+KSB7XG4gICAgICAgIHN1cGVyKGNsYXVzZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIGJ1aWxkKHF1ZXJ5OiBNYW5nb1F1ZXJ5KTogTWFuZ29RdWVyeSB7XG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTm90IGltcGxlbWVudGVkXCIpO1xuICAgICAgfVxuICAgIH0pKHtcbiAgICAgIHN0YXRlbWVudDogc3RhdGVtZW50LFxuICAgICAgc2VsZWN0b3I6IHNlbGVjdG9yLFxuICAgIH0pO1xuICB9XG5cbiAgaW5zZXJ0PE0gZXh0ZW5kcyBNb2RlbD4oKTogSW5zZXJ0Q2xhdXNlPE1hbmdvUXVlcnksIE0+IHtcbiAgICByZXR1cm4gbmV3IENvdWNoREJJbnNlcnRDbGF1c2Uoe1xuICAgICAgc3RhdGVtZW50OiBuZXcgQ291Y2hEQlN0YXRlbWVudCh0aGlzLmFkYXB0ZXIpLFxuICAgIH0pO1xuICB9XG5cbiAgbGltaXQoXG4gICAgc3RhdGVtZW50OiBTdGF0ZW1lbnQ8TWFuZ29RdWVyeT4sXG4gICAgc2VsZWN0b3I6IExpbWl0U2VsZWN0b3JcbiAgKTogTGltaXRDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICAgIHJldHVybiBuZXcgKGNsYXNzIGV4dGVuZHMgTGltaXRDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICAgICAgY29uc3RydWN0b3IoY2xhdXNlOiBNb2RlbEFyZzxMaW1pdENsYXVzZTxNYW5nb1F1ZXJ5Pj4pIHtcbiAgICAgICAgc3VwZXIoY2xhdXNlKTtcbiAgICAgIH1cblxuICAgICAgYnVpbGQocXVlcnk6IE1hbmdvUXVlcnkpOiBNYW5nb1F1ZXJ5IHtcbiAgICAgICAgcXVlcnkubGltaXQgPSB0aGlzLnNlbGVjdG9yIGFzIG51bWJlcjtcbiAgICAgICAgcmV0dXJuIHF1ZXJ5O1xuICAgICAgfVxuICAgIH0pKHtcbiAgICAgIHN0YXRlbWVudDogc3RhdGVtZW50LFxuICAgICAgc2VsZWN0b3I6IHNlbGVjdG9yLFxuICAgIH0pO1xuICB9XG5cbiAgb2Zmc2V0KFxuICAgIHN0YXRlbWVudDogU3RhdGVtZW50PE1hbmdvUXVlcnk+LFxuICAgIHNlbGVjdG9yOiBPZmZzZXRTZWxlY3RvclxuICApOiBPZmZzZXRDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICAgIHJldHVybiBuZXcgKGNsYXNzIGV4dGVuZHMgT2Zmc2V0Q2xhdXNlPE1hbmdvUXVlcnk+IHtcbiAgICAgIGNvbnN0cnVjdG9yKGNsYXVzZTogTW9kZWxBcmc8T2Zmc2V0Q2xhdXNlPE1hbmdvUXVlcnk+Pikge1xuICAgICAgICBzdXBlcihjbGF1c2UpO1xuICAgICAgfVxuXG4gICAgICBidWlsZChxdWVyeTogTWFuZ29RdWVyeSk6IE1hbmdvUXVlcnkge1xuICAgICAgICBjb25zdCBza2lwOiBudW1iZXIgPSBwYXJzZUludCh0aGlzLnNlbGVjdG9yIGFzIHVua25vd24gYXMgc3RyaW5nKTtcbiAgICAgICAgaWYgKGlzTmFOKHNraXApKSB0aHJvdyBuZXcgUXVlcnlFcnJvcihcIkZhaWxlZCB0byBwYXJzZSBvZmZzZXRcIik7XG4gICAgICAgIHF1ZXJ5LnNraXAgPSBza2lwO1xuICAgICAgICByZXR1cm4gcXVlcnk7XG4gICAgICB9XG4gICAgfSkoe1xuICAgICAgc3RhdGVtZW50OiBzdGF0ZW1lbnQsXG4gICAgICBzZWxlY3Rvcjogc2VsZWN0b3IsXG4gICAgfSk7XG4gIH1cblxuICBvcmRlckJ5KFxuICAgIHN0YXRlbWVudDogU3RhdGVtZW50PE1hbmdvUXVlcnk+LFxuICAgIHNlbGVjdG9yOiBPcmRlckJ5U2VsZWN0b3JbXVxuICApOiBPcmRlckJ5Q2xhdXNlPE1hbmdvUXVlcnk+IHtcbiAgICByZXR1cm4gbmV3IChjbGFzcyBleHRlbmRzIE9yZGVyQnlDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICAgICAgY29uc3RydWN0b3IoY2xhdXNlOiBNb2RlbEFyZzxPcmRlckJ5Q2xhdXNlPE1hbmdvUXVlcnk+Pikge1xuICAgICAgICBzdXBlcihjbGF1c2UpO1xuICAgICAgfVxuXG4gICAgICBidWlsZChxdWVyeTogTWFuZ29RdWVyeSk6IE1hbmdvUXVlcnkge1xuICAgICAgICBxdWVyeS5zb3J0ID0gcXVlcnkuc29ydCB8fCBbXTtcbiAgICAgICAgcXVlcnkuc2VsZWN0b3IgPSBxdWVyeS5zZWxlY3RvciB8fCAoe30gYXMgTWFuZ29TZWxlY3Rvcik7XG4gICAgICAgIHRoaXMuc2VsZWN0b3IhLmZvckVhY2goKHMpID0+IHtcbiAgICAgICAgICBjb25zdCBbc2VsZWN0b3IsIHZhbHVlXSA9IHM7XG4gICAgICAgICAgY29uc3QgcmVjOiBhbnkgPSB7fTtcbiAgICAgICAgICByZWNbc2VsZWN0b3JdID0gdmFsdWU7XG4gICAgICAgICAgKHF1ZXJ5LnNvcnQgYXMgYW55W10pLnB1c2gocmVjIGFzIGFueSk7XG4gICAgICAgICAgaWYgKCFxdWVyeS5zZWxlY3RvcltzZWxlY3Rvcl0pIHtcbiAgICAgICAgICAgIHF1ZXJ5LnNlbGVjdG9yW3NlbGVjdG9yXSA9IHt9IGFzIE1hbmdvU2VsZWN0b3I7XG4gICAgICAgICAgICAocXVlcnkuc2VsZWN0b3Jbc2VsZWN0b3JdIGFzIE1hbmdvU2VsZWN0b3IpW1xuICAgICAgICAgICAgICBDb3VjaERCT3BlcmF0b3IuQklHR0VSXG4gICAgICAgICAgICBdID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gcXVlcnkuZmllbGRzID0gcXVlcnkuZmllbGRzIHx8IFtdO1xuICAgICAgICAgIC8vIHF1ZXJ5LmZpZWxkcyA9IFsuLi5uZXcgU2V0KFsuLi5xdWVyeS5maWVsZHMsIHNlbGVjdG9yXSkua2V5cygpXVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHF1ZXJ5O1xuICAgICAgfVxuICAgIH0pKHtcbiAgICAgIHN0YXRlbWVudDogc3RhdGVtZW50LFxuICAgICAgc2VsZWN0b3I6IHNlbGVjdG9yLFxuICAgIH0pO1xuICB9XG5cbiAgc2VsZWN0PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgc2VsZWN0b3I6IFNlbGVjdFNlbGVjdG9yIHwgdW5kZWZpbmVkXG4gICk6IFNlbGVjdENsYXVzZTxNYW5nb1F1ZXJ5LCBNPiB7XG4gICAgcmV0dXJuIG5ldyBDb3VjaERCU2VsZWN0Q2xhdXNlKHtcbiAgICAgIHN0YXRlbWVudDogbmV3IENvdWNoREJTdGF0ZW1lbnQodGhpcy5hZGFwdGVyKSxcbiAgICAgIHNlbGVjdG9yOiBzZWxlY3RvcixcbiAgICB9KTtcbiAgfVxuXG4gIHZhbHVlczxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIHN0YXRlbWVudDogU3RhdGVtZW50PE1hbmdvUXVlcnk+LFxuICAgIHZhbHVlczogTVtdXG4gICk6IFZhbHVlc0NsYXVzZTxNYW5nb1F1ZXJ5LCBNPiB7XG4gICAgcmV0dXJuIG5ldyBDb3VjaERCVmFsdWVzQ2xhdXNlPE0+KHtcbiAgICAgIHN0YXRlbWVudDogc3RhdGVtZW50LFxuICAgICAgdmFsdWVzOiB2YWx1ZXMsXG4gICAgfSk7XG4gIH1cblxuICB3aGVyZShcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxNYW5nb1F1ZXJ5PixcbiAgICBjb25kaXRpb246IENvbmRpdGlvblxuICApOiBXaGVyZUNsYXVzZTxNYW5nb1F1ZXJ5PiB7XG4gICAgcmV0dXJuIG5ldyBDb3VjaERCV2hlcmVDbGF1c2Uoe1xuICAgICAgc3RhdGVtZW50OiBzdGF0ZW1lbnQsXG4gICAgICBjb25kaXRpb246IGNvbmRpdGlvbixcbiAgICB9KTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgR3JvdXBPcGVyYXRvciwgT3BlcmF0b3IgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IENvdWNoREJHcm91cE9wZXJhdG9yLCBDb3VjaERCT3BlcmF0b3IgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFF1ZXJ5RXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE1hbmdvT3BlcmF0b3IgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zbGF0ZU9wZXJhdG9ycyhcbiAgb3BlcmF0b3I6IEdyb3VwT3BlcmF0b3IgfCBPcGVyYXRvclxuKTogTWFuZ29PcGVyYXRvciB7XG4gIGZvciAoY29uc3Qgb3BlcmF0b3JzIG9mIFtDb3VjaERCT3BlcmF0b3IsIENvdWNoREJHcm91cE9wZXJhdG9yXSkge1xuICAgIGNvbnN0IGVsID0gT2JqZWN0LmtleXMob3BlcmF0b3JzKS5maW5kKChrKSA9PiBrID09PSBvcGVyYXRvcik7XG4gICAgaWYgKGVsKSByZXR1cm4gb3BlcmF0b3JzW2VsXTtcbiAgfVxuICB0aHJvdyBuZXcgUXVlcnlFcnJvcihcbiAgICBgQ291bGQgbm90IGZpbmQgYWRhcHRlciB0cmFuc2xhdGlvbiBmb3Igb3BlcmF0b3IgJHtvcGVyYXRvcn1gXG4gICk7XG59XG4iLCJpbXBvcnQgeyBCYXNlRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGNsYXNzIEluZGV4RXJyb3IgZXh0ZW5kcyBCYXNlRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoSW5kZXhFcnJvci5uYW1lLCBtc2cpO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBBZGFwdGVyLFxuICBTZXF1ZW5jZSxcbiAgU2VxdWVuY2VPcHRpb25zLFxuICBQZXJzaXN0ZW5jZUtleXMsXG4gIE9wZXJhdG9yLFxuICBHcm91cE9wZXJhdG9yLFxuICBTdGF0ZW1lbnQsXG4gIFF1ZXJ5LFxuICBDbGF1c2VGYWN0b3J5LFxuICBDb25kaXRpb24sXG4gIENvbm5lY3Rpb25FcnJvcixcbiAgUmVwb3NpdG9yeSxcbiAgVXNlcixcbn0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBDb3VjaERCS2V5cywgcmVzZXJ2ZWRBdHRyaWJ1dGVzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBCYXNlRXJyb3IsXG4gIENvbmZsaWN0RXJyb3IsXG4gIEludGVybmFsRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIHByZWZpeE1ldGhvZCxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgXCJyZWZsZWN0LW1ldGFkYXRhXCI7XG5pbXBvcnQgeyBDb3VjaERCU3RhdGVtZW50IH0gZnJvbSBcIi4vcXVlcnkvU3RhdGVtZW50XCI7XG5pbXBvcnQgeyBGYWN0b3J5IH0gZnJvbSBcIi4vcXVlcnlcIjtcbmltcG9ydCB7IHRyYW5zbGF0ZU9wZXJhdG9ycyB9IGZyb20gXCIuL3F1ZXJ5L3RyYW5zbGF0ZVwiO1xuaW1wb3J0IHsgQ291Y2hEQlNlcXVlbmNlIH0gZnJvbSBcIi4vc2VxdWVuY2VzL1NlcXVlbmNlXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBJbmRleEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBNYW5nb09wZXJhdG9yLCBNYW5nb1F1ZXJ5LCBNYW5nb1NlbGVjdG9yIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIENvdWNoREJBZGFwdGVyPFM+IGV4dGVuZHMgQWRhcHRlcjxTLCBNYW5nb1F1ZXJ5PiB7XG4gIHByb3RlY3RlZCBmYWN0b3J5PzogRmFjdG9yeTxTPjtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3Ioc2NvcGU6IFMsIGZsYXZvdXI6IHN0cmluZykge1xuICAgIHN1cGVyKHNjb3BlLCBmbGF2b3VyKTtcbiAgICBbdGhpcy5jcmVhdGUsIHRoaXMuY3JlYXRlQWxsLCB0aGlzLnVwZGF0ZSwgdGhpcy51cGRhdGVBbGxdLmZvckVhY2goKG0pID0+IHtcbiAgICAgIGNvbnN0IG5hbWUgPSBtLm5hbWU7XG4gICAgICBwcmVmaXhNZXRob2QodGhpcywgbSwgKHRoaXMgYXMgYW55KVtuYW1lICsgXCJQcmVmaXhcIl0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0IENsYXVzZXMoKTogQ2xhdXNlRmFjdG9yeTxTLCBNYW5nb1F1ZXJ5PiB7XG4gICAgaWYgKCF0aGlzLmZhY3RvcnkpIHRoaXMuZmFjdG9yeSA9IG5ldyBGYWN0b3J5KHRoaXMpO1xuICAgIHJldHVybiB0aGlzLmZhY3Rvcnk7XG4gIH1cblxuICBRdWVyeTxNIGV4dGVuZHMgTW9kZWw+KCk6IFF1ZXJ5PE1hbmdvUXVlcnksIE0+IHtcbiAgICByZXR1cm4gc3VwZXIuUXVlcnkoKTtcbiAgfVxuXG4gIGdldCBTdGF0ZW1lbnQoKTogU3RhdGVtZW50PE1hbmdvUXVlcnk+IHtcbiAgICByZXR1cm4gbmV3IENvdWNoREJTdGF0ZW1lbnQodGhpcyk7XG4gIH1cblxuICBwYXJzZUNvbmRpdGlvbihjb25kaXRpb246IENvbmRpdGlvbik6IE1hbmdvUXVlcnkge1xuICAgIGZ1bmN0aW9uIG1lcmdlKFxuICAgICAgb3A6IE1hbmdvT3BlcmF0b3IsXG4gICAgICBvYmoxOiBNYW5nb1NlbGVjdG9yLFxuICAgICAgb2JqMjogTWFuZ29TZWxlY3RvclxuICAgICk6IE1hbmdvUXVlcnkge1xuICAgICAgY29uc3QgcmVzdWx0OiBNYW5nb1F1ZXJ5ID0geyBzZWxlY3Rvcjoge30gYXMgTWFuZ29TZWxlY3RvciB9O1xuICAgICAgcmVzdWx0LnNlbGVjdG9yW29wXSA9IFtvYmoxLCBvYmoyXTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgY29uc3QgeyBhdHRyMSwgb3BlcmF0b3IsIGNvbXBhcmlzb24gfSA9IGNvbmRpdGlvbiBhcyB1bmtub3duIGFzIHtcbiAgICAgIGF0dHIxOiBzdHJpbmcgfCBDb25kaXRpb247XG4gICAgICBvcGVyYXRvcjogT3BlcmF0b3IgfCBHcm91cE9wZXJhdG9yO1xuICAgICAgY29tcGFyaXNvbjogYW55O1xuICAgIH07XG5cbiAgICBsZXQgb3A6IE1hbmdvU2VsZWN0b3IgPSB7fSBhcyBNYW5nb1NlbGVjdG9yO1xuICAgIGlmIChcbiAgICAgIFtHcm91cE9wZXJhdG9yLkFORCwgR3JvdXBPcGVyYXRvci5PUiwgT3BlcmF0b3IuTk9UXS5pbmRleE9mKFxuICAgICAgICBvcGVyYXRvciBhcyBHcm91cE9wZXJhdG9yXG4gICAgICApID09PSAtMVxuICAgICkge1xuICAgICAgb3BbYXR0cjEgYXMgc3RyaW5nXSA9IHt9IGFzIE1hbmdvU2VsZWN0b3I7XG4gICAgICAob3BbYXR0cjEgYXMgc3RyaW5nXSBhcyBNYW5nb1NlbGVjdG9yKVt0cmFuc2xhdGVPcGVyYXRvcnMob3BlcmF0b3IpXSA9XG4gICAgICAgIGNvbXBhcmlzb247XG4gICAgfSBlbHNlIGlmIChvcGVyYXRvciA9PT0gT3BlcmF0b3IuTk9UKSB7XG4gICAgICBvcCA9IHRoaXMucGFyc2VDb25kaXRpb24oYXR0cjEgYXMgQ29uZGl0aW9uKS5zZWxlY3RvciBhcyBNYW5nb1NlbGVjdG9yO1xuICAgICAgb3BbdHJhbnNsYXRlT3BlcmF0b3JzKE9wZXJhdG9yLk5PVCldID0ge30gYXMgTWFuZ29TZWxlY3RvcjtcbiAgICAgIChvcFt0cmFuc2xhdGVPcGVyYXRvcnMoT3BlcmF0b3IuTk9UKV0gYXMgTWFuZ29TZWxlY3RvcilbXG4gICAgICAgIChhdHRyMSBhcyB1bmtub3duIGFzIHsgYXR0cjE6IHN0cmluZyB9KS5hdHRyMVxuICAgICAgXSA9IGNvbXBhcmlzb247XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG9wMTogYW55ID0gdGhpcy5wYXJzZUNvbmRpdGlvbihhdHRyMSBhcyBDb25kaXRpb24pLnNlbGVjdG9yO1xuICAgICAgY29uc3Qgb3AyOiBhbnkgPSB0aGlzLnBhcnNlQ29uZGl0aW9uKGNvbXBhcmlzb24gYXMgQ29uZGl0aW9uKS5zZWxlY3RvcjtcbiAgICAgIG9wID0gbWVyZ2UodHJhbnNsYXRlT3BlcmF0b3JzKG9wZXJhdG9yKSwgb3AxLCBvcDIpLnNlbGVjdG9yO1xuICAgIH1cblxuICAgIHJldHVybiB7IHNlbGVjdG9yOiBvcCB9O1xuICB9XG5cbiAgYXN5bmMgU2VxdWVuY2Uob3B0aW9uczogU2VxdWVuY2VPcHRpb25zKTogUHJvbWlzZTxTZXF1ZW5jZT4ge1xuICAgIHJldHVybiBuZXcgQ291Y2hEQlNlcXVlbmNlKG9wdGlvbnMsIHRoaXMpO1xuICB9XG5cbiAgYXN5bmMgaW5pdGlhbGl6ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtYW5hZ2VkTW9kZWxzID0gQWRhcHRlci5tb2RlbHModGhpcy5mbGF2b3VyKTtcbiAgICByZXR1cm4gdGhpcy5pbmRleCguLi5tYW5hZ2VkTW9kZWxzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBpbmRleDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIC4uLm1vZGVsczogQ29uc3RydWN0b3I8TT5bXVxuICApOiBQcm9taXNlPHZvaWQ+O1xuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCB1c2VyKCk6IFByb21pc2U8VXNlcj47XG5cbiAgYWJzdHJhY3QgcmF3PFY+KHJhd0lucHV0OiBNYW5nb1F1ZXJ5LCBwcm9jZXNzOiBib29sZWFuKTogUHJvbWlzZTxWPjtcblxuICBwcm90ZWN0ZWQgYXNzaWduTWV0YWRhdGEoXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgcmV2OiBzdHJpbmdcbiAgKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZGVsLCBQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEEsIHtcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIHZhbHVlOiByZXYsXG4gICAgfSk7XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzc2lnbk11bHRpcGxlTWV0YWRhdGEoXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10sXG4gICAgcmV2czogc3RyaW5nW11cbiAgKTogUmVjb3JkPHN0cmluZywgYW55PltdIHtcbiAgICBtb2RlbHMuZm9yRWFjaCgobSwgaSkgPT4ge1xuICAgICAgUmVwb3NpdG9yeS5zZXRNZXRhZGF0YShtIGFzIGFueSwgcmV2c1tpXSk7XG4gICAgICByZXR1cm4gbTtcbiAgICB9KTtcbiAgICByZXR1cm4gbW9kZWxzO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVByZWZpeChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICkge1xuICAgIGNvbnN0IHJlY29yZDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgIHJlY29yZFtDb3VjaERCS2V5cy5UQUJMRV0gPSB0YWJsZU5hbWU7XG4gICAgcmVjb3JkW0NvdWNoREJLZXlzLklEXSA9IHRoaXMuZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkKTtcbiAgICBPYmplY3QuYXNzaWduKHJlY29yZCwgbW9kZWwpO1xuICAgIHJldHVybiBbdGFibGVOYW1lLCBpZCwgcmVjb3JkXTtcbiAgfVxuXG4gIGFic3RyYWN0IGNyZWF0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj47XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUFsbFByZWZpeChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W11cbiAgKSB7XG4gICAgaWYgKGlkcy5sZW5ndGggIT09IG1vZGVscy5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIklkcyBhbmQgbW9kZWxzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGhcIik7XG5cbiAgICBjb25zdCByZWNvcmRzID0gaWRzLm1hcCgoaWQsIGNvdW50KSA9PiB7XG4gICAgICBjb25zdCByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICAgIHJlY29yZFtDb3VjaERCS2V5cy5UQUJMRV0gPSB0YWJsZU5hbWU7XG4gICAgICByZWNvcmRbQ291Y2hEQktleXMuSURdID0gdGhpcy5nZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpO1xuICAgICAgT2JqZWN0LmFzc2lnbihyZWNvcmQsIG1vZGVsc1tjb3VudF0pO1xuICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICB9KTtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWRzLCByZWNvcmRzXTtcbiAgfVxuXG4gIGFic3RyYWN0IGNyZWF0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+O1xuXG4gIGFic3RyYWN0IHJlYWQoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlclxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG4gIGFic3RyYWN0IHJlYWRBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPjtcblxuICB1cGRhdGVQcmVmaXgoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PlxuICApIHtcbiAgICBjb25zdCByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICByZWNvcmRbQ291Y2hEQktleXMuVEFCTEVdID0gdGFibGVOYW1lO1xuICAgIHJlY29yZFtDb3VjaERCS2V5cy5JRF0gPSB0aGlzLmdlbmVyYXRlSWQodGFibGVOYW1lLCBpZCk7XG4gICAgY29uc3QgcmV2ID0gbW9kZWxbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXTtcbiAgICBpZiAoIXJldilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgTm8gcmV2aXNpb24gbnVtYmVyIGZvdW5kIGZvciByZWNvcmQgd2l0aCBpZCAke2lkfWBcbiAgICAgICk7XG4gICAgT2JqZWN0LmFzc2lnbihyZWNvcmQsIG1vZGVsKTtcbiAgICByZWNvcmRbQ291Y2hEQktleXMuUkVWXSA9IHJldjtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWQsIHJlY29yZF07XG4gIH1cblxuICBhYnN0cmFjdCB1cGRhdGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG4gIHByb3RlY3RlZCB1cGRhdGVBbGxQcmVmaXgoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIG1vZGVsczogUmVjb3JkPHN0cmluZywgYW55PltdXG4gICkge1xuICAgIGlmIChpZHMubGVuZ3RoICE9PSBtb2RlbHMubGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJJZHMgYW5kIG1vZGVscyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoXCIpO1xuXG4gICAgY29uc3QgcmVjb3JkcyA9IGlkcy5tYXAoKGlkLCBjb3VudCkgPT4ge1xuICAgICAgY29uc3QgcmVjb3JkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgICByZWNvcmRbQ291Y2hEQktleXMuVEFCTEVdID0gdGFibGVOYW1lO1xuICAgICAgcmVjb3JkW0NvdWNoREJLZXlzLklEXSA9IHRoaXMuZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkKTtcbiAgICAgIGNvbnN0IHJldiA9IG1vZGVsc1tjb3VudF1bUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXTtcbiAgICAgIGlmICghcmV2KVxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICBgTm8gcmV2aXNpb24gbnVtYmVyIGZvdW5kIGZvciByZWNvcmQgd2l0aCBpZCAke2lkfWBcbiAgICAgICAgKTtcbiAgICAgIE9iamVjdC5hc3NpZ24ocmVjb3JkLCBtb2RlbHNbY291bnRdKTtcbiAgICAgIHJlY29yZFtDb3VjaERCS2V5cy5SRVZdID0gcmV2O1xuICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICB9KTtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWRzLCByZWNvcmRzXTtcbiAgfVxuXG4gIGFic3RyYWN0IHVwZGF0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+O1xuXG4gIGFic3RyYWN0IGRlbGV0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj47XG5cbiAgYWJzdHJhY3QgZGVsZXRlQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkczogKHN0cmluZyB8IG51bWJlciB8IGJpZ2ludClbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT5bXT47XG5cbiAgcHJvdGVjdGVkIGdlbmVyYXRlSWQodGFibGVOYW1lOiBzdHJpbmcsIGlkOiBzdHJpbmcgfCBudW1iZXIpIHtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWRdLmpvaW4oQ291Y2hEQktleXMuU0VQQVJBVE9SKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUVycm9yKGVycjogRXJyb3IgfCBzdHJpbmcsIHJlYXNvbj86IHN0cmluZyk6IEJhc2VFcnJvciB7XG4gICAgcmV0dXJuIENvdWNoREJBZGFwdGVyLnBhcnNlRXJyb3IoZXJyLCByZWFzb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGlzUmVzZXJ2ZWQoYXR0cjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhYXR0ci5tYXRjaChyZXNlcnZlZEF0dHJpYnV0ZXMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHN0YXRpYyBwYXJzZUVycm9yKGVycjogRXJyb3IgfCBzdHJpbmcsIHJlYXNvbj86IHN0cmluZyk6IEJhc2VFcnJvciB7XG4gICAgaWYgKGVyciBpbnN0YW5jZW9mIEJhc2VFcnJvcikgcmV0dXJuIGVyciBhcyBhbnk7XG4gICAgbGV0IGNvZGU6IHN0cmluZyA9IFwiXCI7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGNvZGUgPSBlcnI7XG4gICAgICBpZiAoY29kZS5tYXRjaCgvYWxyZWFkeSBleGlzdHx1cGRhdGUgY29uZmxpY3QvZykpXG4gICAgICAgIHJldHVybiBuZXcgQ29uZmxpY3RFcnJvcihjb2RlKTtcbiAgICAgIGlmIChjb2RlLm1hdGNoKC9taXNzaW5nfGRlbGV0ZWQvZykpIHJldHVybiBuZXcgTm90Rm91bmRFcnJvcihjb2RlKTtcbiAgICB9IGVsc2UgaWYgKChlcnIgYXMgYW55KS5jb2RlKSB7XG4gICAgICBjb2RlID0gKGVyciBhcyBhbnkpLmNvZGU7XG4gICAgICByZWFzb24gPSByZWFzb24gfHwgZXJyLm1lc3NhZ2U7XG4gICAgfSBlbHNlIGlmICgoZXJyIGFzIGFueSkuc3RhdHVzQ29kZSkge1xuICAgICAgY29kZSA9IChlcnIgYXMgYW55KS5zdGF0dXNDb2RlO1xuICAgICAgcmVhc29uID0gcmVhc29uIHx8IGVyci5tZXNzYWdlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlID0gZXJyLm1lc3NhZ2U7XG4gICAgfVxuXG4gICAgc3dpdGNoIChjb2RlLnRvU3RyaW5nKCkpIHtcbiAgICAgIGNhc2UgXCI0MDFcIjpcbiAgICAgIGNhc2UgXCI0MTJcIjpcbiAgICAgIGNhc2UgXCI0MDlcIjpcbiAgICAgICAgcmV0dXJuIG5ldyBDb25mbGljdEVycm9yKHJlYXNvbiBhcyBzdHJpbmcpO1xuICAgICAgY2FzZSBcIjQwNFwiOlxuICAgICAgICByZXR1cm4gbmV3IE5vdEZvdW5kRXJyb3IocmVhc29uIGFzIHN0cmluZyk7XG4gICAgICBjYXNlIFwiNDAwXCI6XG4gICAgICAgIGlmIChjb2RlLnRvU3RyaW5nKCkubWF0Y2goL05vXFxzaW5kZXhcXHNleGlzdHMvZykpXG4gICAgICAgICAgcmV0dXJuIG5ldyBJbmRleEVycm9yKGVycik7XG4gICAgICAgIHJldHVybiBuZXcgSW50ZXJuYWxFcnJvcihlcnIpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGNvZGUudG9TdHJpbmcoKS5tYXRjaCgvRUNPTk5SRUZVU0VEL2cpKVxuICAgICAgICAgIHJldHVybiBuZXcgQ29ubmVjdGlvbkVycm9yKGVycik7XG4gICAgICAgIHJldHVybiBuZXcgSW50ZXJuYWxFcnJvcihlcnIpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgT3JkZXJEaXJlY3Rpb24sIFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgQ291Y2hEQktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IERlZmF1bHRTZXBhcmF0b3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IENvdWNoREJPcGVyYXRvciB9IGZyb20gXCIuL3F1ZXJ5L2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ3JlYXRlSW5kZXhSZXF1ZXN0LCBNYW5nb1NlbGVjdG9yLCBTb3J0T3JkZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVBdXRoKGNvbjogYW55LCB1c2VyOiBzdHJpbmcsIHBhc3M6IHN0cmluZykge1xuICByZXR1cm4gY29uLmF1dGgodXNlciwgcGFzcyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3cmFwRG9jdW1lbnRTY29wZShcbiAgY29uOiBhbnksXG4gIGRiTmFtZTogc3RyaW5nLFxuICB1c2VyOiBzdHJpbmcsXG4gIHBhc3M6IHN0cmluZ1xuKTogYW55IHtcbiAgY29uc3QgZGIgPSBjb24udXNlKGRiTmFtZSk7XG4gIFtcImluc2VydFwiLCBcImdldFwiLCBcInB1dFwiLCBcImRlc3Ryb3lcIiwgXCJmaW5kXCJdLmZvckVhY2goKGspID0+IHtcbiAgICBjb25zdCBvcmlnaW5hbCA9IChkYiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrXTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGIsIGssIHtcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IGFzeW5jICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgICAgICBhd2FpdCByZUF1dGgoY29uLCB1c2VyLCBwYXNzKTtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsLmNhbGwoZGIsIC4uLmFyZ3MpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkYiwgQ291Y2hEQktleXMuTkFUSVZFLCB7XG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IGNvbixcbiAgfSk7XG4gIHJldHVybiBkYjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRlc3RSZXNlcnZlZEF0dHJpYnV0ZXMoYXR0cjogc3RyaW5nKSB7XG4gIGNvbnN0IHJlZ2V4cCA9IC9eXy4qJC9nO1xuICByZXR1cm4gYXR0ci5tYXRjaChyZWdleHApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVJbmRleE5hbWUoXG4gIGF0dHJpYnV0ZTogc3RyaW5nLFxuICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgY29tcG9zaXRpb25zPzogc3RyaW5nW10sXG4gIG9yZGVyPzogT3JkZXJEaXJlY3Rpb24sXG4gIHNlcGFyYXRvciA9IERlZmF1bHRTZXBhcmF0b3Jcbik6IHN0cmluZyB7XG4gIGNvbnN0IGF0dHIgPSBbUGVyc2lzdGVuY2VLZXlzLklOREVYLCB0YWJsZU5hbWUsIGF0dHJpYnV0ZV07XG4gIGlmIChjb21wb3NpdGlvbnMpIGF0dHIucHVzaCguLi5jb21wb3NpdGlvbnMpO1xuICBpZiAob3JkZXIpIGF0dHIucHVzaChvcmRlcik7XG4gIHJldHVybiBhdHRyLmpvaW4oc2VwYXJhdG9yKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlSW5kZXhEb2MoXG4gIGF0dHJpYnV0ZTogc3RyaW5nLFxuICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgY29tcG9zaXRpb25zPzogc3RyaW5nW10sXG4gIG9yZGVyPzogT3JkZXJEaXJlY3Rpb24sXG4gIHNlcGFyYXRvciA9IERlZmF1bHRTZXBhcmF0b3Jcbik6IENyZWF0ZUluZGV4UmVxdWVzdCB7XG4gIGNvbnN0IHBhcnRpYWxGaWx0ZXJTZWxlY3RvcjogTWFuZ29TZWxlY3RvciA9IHt9O1xuICBwYXJ0aWFsRmlsdGVyU2VsZWN0b3JbQ291Y2hEQktleXMuVEFCTEVdID0ge30gYXMgTWFuZ29TZWxlY3RvcjtcbiAgKHBhcnRpYWxGaWx0ZXJTZWxlY3RvcltDb3VjaERCS2V5cy5UQUJMRV0gYXMgTWFuZ29TZWxlY3RvcilbXG4gICAgQ291Y2hEQk9wZXJhdG9yLkVRVUFMXG4gIF0gPSB0YWJsZU5hbWU7XG4gIGxldCBmaWVsZHM6IFNvcnRPcmRlcltdO1xuICBpZiAob3JkZXIpIHtcbiAgICBjb25zdCBvcmRlclByb3A6IFNvcnRPcmRlciA9IHt9O1xuICAgIG9yZGVyUHJvcFthdHRyaWJ1dGVdID0gb3JkZXIgYXMgXCJhc2NcIiB8IFwiZGVzY1wiO1xuICAgIGNvbnN0IHNvcnRlZENvbXBvc2l0aW9uczogU29ydE9yZGVyW10gPSAoY29tcG9zaXRpb25zIHx8IFtdKS5tYXAoKGMpID0+IHtcbiAgICAgIGNvbnN0IHI6IFNvcnRPcmRlciA9IHt9O1xuICAgICAgcltjXSA9IG9yZGVyIGFzIFwiYXNjXCIgfCBcImRlc2NcIjtcbiAgICAgIHJldHVybiByO1xuICAgIH0pO1xuICAgIGNvbnN0IHNvcnRlZFRhYmxlOiBTb3J0T3JkZXIgPSB7fTtcbiAgICBzb3J0ZWRUYWJsZVtDb3VjaERCS2V5cy5UQUJMRV0gPSBvcmRlciBhcyBcImFzY1wiIHwgXCJkZXNjXCI7XG4gICAgZmllbGRzID0gW29yZGVyUHJvcCwgLi4uc29ydGVkQ29tcG9zaXRpb25zLCBzb3J0ZWRUYWJsZV07XG4gIH0gZWxzZSB7XG4gICAgZmllbGRzID0gW2F0dHJpYnV0ZSwgLi4uKGNvbXBvc2l0aW9ucyB8fCBbXSksIENvdWNoREJLZXlzLlRBQkxFXTtcbiAgfVxuICBjb25zdCBuYW1lID0gZ2VuZXJhdGVJbmRleE5hbWUoXG4gICAgYXR0cmlidXRlLFxuICAgIHRhYmxlTmFtZSxcbiAgICBjb21wb3NpdGlvbnMsXG4gICAgb3JkZXIsXG4gICAgc2VwYXJhdG9yXG4gICk7XG4gIHJldHVybiB7XG4gICAgaW5kZXg6IHtcbiAgICAgIGZpZWxkczogZmllbGRzLFxuICAgICAgLy8gcGFydGlhbF9maWx0ZXJfc2VsZWN0b3I6IHBhcnRpYWxGaWx0ZXJTZWxlY3RvcixcbiAgICB9LFxuICAgIGRkb2M6IFtuYW1lLCBDb3VjaERCS2V5cy5ERE9DXS5qb2luKHNlcGFyYXRvciksXG4gICAgbmFtZTogbmFtZSxcbiAgfTtcbn1cbiIsImV4cG9ydCAqIGZyb20gXCIuL2luZGV4ZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ludGVyZmFjZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL21vZGVsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9zZXF1ZW5jZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FkYXB0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZXJyb3JzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBNb2R1bGUgc3VtbWFyeVxuICogQGRlc2NyaXB0aW9uIE1vZHVsZSBkZXNjcmlwdGlvblxuICogQG1vZHVsZSB0cy13b3Jrc3BhY2VcbiAqL1xuXG4vKipcbiAqIEBzdW1tYXJ5IE5hbWVzcGFjZSBzdW1tYXJ5XG4gKiBAZGVzY3JpcHRpb24gTmFtZXNwYWNlIGRlc2NyaXB0aW9uXG4gKiBAbmFtZXNwYWNlIE5hbWVzcGFjZVxuICogQG1lbWJlck9mIG1vZHVsZTp0cy13b3Jrc3BhY2VcbiAqL1xuXG4vKipcbiAqIEBzdW1tYXJ5IHN0b3JlcyB0aGUgY3VycmVudCBwYWNrYWdlIHZlcnNpb25cbiAqIEBkZXNjcmlwdGlvbiB0aGlzIGlzIGhvdyB5b3Ugc2hvdWxkIGRvY3VtZW50IGEgY29uc3RhbnRcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnRzLXdvcmtzcGFjZVxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6WyJnZW5lcmF0ZUluZGV4TmFtZSIsIkRlZmF1bHRTZXBhcmF0b3IiLCJSZXBvc2l0b3J5IiwiUGVyc2lzdGVuY2VLZXlzIiwiU2VxdWVuY2UiLCJCYXNlTW9kZWwiLCJwayIsInJlcXVpcmVkIiwiaW5kZXgiLCJ0YWJsZSIsIm1vZGVsIiwiSW50ZXJuYWxFcnJvciIsIlNlcSIsIk5vdEZvdW5kRXJyb3IiLCJzZiIsIlBhZ2luYXRvciIsIlBhZ2luZ0Vycm9yIiwiZmluZFByaW1hcnlLZXkiLCJTdGF0ZW1lbnQiLCJGcm9tQ2xhdXNlIiwiSW5zZXJ0Q2xhdXNlIiwiV2hlcmVDbGF1c2UiLCJDb25kaXRpb24iLCJTZWxlY3RDbGF1c2UiLCJDb25zdCIsIlZhbHVlc0NsYXVzZSIsIkNsYXVzZUZhY3RvcnkiLCJHcm91cEJ5Q2xhdXNlIiwiTGltaXRDbGF1c2UiLCJPZmZzZXRDbGF1c2UiLCJRdWVyeUVycm9yIiwiT3JkZXJCeUNsYXVzZSIsIkJhc2VFcnJvciIsIkFkYXB0ZXIiLCJwcmVmaXhNZXRob2QiLCJHcm91cE9wZXJhdG9yIiwiT3BlcmF0b3IiLCJDb25mbGljdEVycm9yIiwiQ29ubmVjdGlvbkVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBTyxVQUFNLGtCQUFrQixHQUFHO0FBRXJCLFVBQUEsV0FBVyxHQUFHO0lBQ3pCLElBQUEsU0FBUyxFQUFFLEdBQUc7SUFDZCxJQUFBLEVBQUUsRUFBRSxLQUFLO0lBQ1QsSUFBQSxHQUFHLEVBQUUsTUFBTTtJQUNYLElBQUEsT0FBTyxFQUFFLFVBQVU7SUFDbkIsSUFBQSxLQUFLLEVBQUUsU0FBUztJQUNoQixJQUFBLFFBQVEsRUFBRSxZQUFZO0lBQ3RCLElBQUEsSUFBSSxFQUFFLE1BQU07SUFDWixJQUFBLE1BQU0sRUFBRSxVQUFVO0lBQ2xCLElBQUEsS0FBSyxFQUFFLE9BQU87OztJQ1RULE1BQU0sZUFBZSxHQUFrQztJQUM1RCxJQUFBLEtBQUssRUFBRSxLQUFLO0lBQ1osSUFBQSxTQUFT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