@archont561/qgis-sdk 0.4.0 → 0.5.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.
@@ -0,0 +1,895 @@
1
+ import {
2
+ STREAM_EVENT_KINDS,
3
+ isPlainRecord,
4
+ QgisSdkBridgeAbortedError2
5
+ } from "./chunk-8gawbn19.js";
6
+ import {
7
+ QgisSdkError2
8
+ } from "./chunk-2hwva3a3.js";
9
+
10
+ // src/declarations.ts
11
+ var MAX_SAFE_INTEGER2 = 9007199254740991;
12
+ var MIN_SAFE_INTEGER2 = -9007199254740991;
13
+ var PLUGIN_DESCRIPTION_SCHEMA_VERSION2 = 1;
14
+ function isSafeJsonInteger2(value) {
15
+ return typeof value === "number" && Number.isSafeInteger(value);
16
+ }
17
+
18
+ class QgisSdkDeclarationError2 extends QgisSdkError2 {
19
+ constructor(message) {
20
+ super(message, "invalid_declaration");
21
+ }
22
+ }
23
+
24
+ class QgisSdkValidationIssue2 {
25
+ path;
26
+ code;
27
+ constructor(path, code) {
28
+ this.path = Object.freeze([...path]);
29
+ this.code = code;
30
+ }
31
+ toJSON() {
32
+ return {
33
+ path: [...this.path],
34
+ code: this.code
35
+ };
36
+ }
37
+ }
38
+
39
+ class QgisSdkContractValidationError2 extends QgisSdkError2 {
40
+ direction;
41
+ issues;
42
+ constructor(direction, issues) {
43
+ const prefix = direction === "request" ? "Request" : "Result";
44
+ super(`${prefix} contract validation failed`, "contract_validation_failed");
45
+ this.direction = direction;
46
+ this.issues = Object.freeze([...issues]);
47
+ }
48
+ toJSON() {
49
+ return {
50
+ code: this.code,
51
+ direction: this.direction,
52
+ issues: this.issues.map((issue) => issue.toJSON())
53
+ };
54
+ }
55
+ }
56
+ var DECLARATION_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9_.-]*$/;
57
+ var PYTHON_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
58
+ function validateDeclarationId(value, label) {
59
+ if (typeof value !== "string" || !DECLARATION_ID_PATTERN.test(value)) {
60
+ throw new QgisSdkDeclarationError2(`Invalid ${label} id: expected [a-zA-Z][a-zA-Z0-9_.-]*`);
61
+ }
62
+ return value;
63
+ }
64
+ function validateNonBlankTitle(value, id) {
65
+ if (typeof value !== "string" || value.trim().length === 0) {
66
+ throw new QgisSdkDeclarationError2(`${id}: title must be a nonempty string`);
67
+ }
68
+ return value;
69
+ }
70
+ function parseOperationHead(raw, label) {
71
+ if (!isPlainRecord(raw)) {
72
+ throw new QgisSdkDeclarationError2(`${label[0]?.toUpperCase()}${label.slice(1)} description must be an object`);
73
+ }
74
+ const id = validateDeclarationId(raw.id, label);
75
+ const title = validateNonBlankTitle(raw.title, id);
76
+ if (typeof raw.handler !== "string" || !PYTHON_IDENTIFIER_PATTERN.test(raw.handler)) {
77
+ throw new QgisSdkDeclarationError2(`${id}: handler must be a valid Python identifier`);
78
+ }
79
+ if (!isPlainRecord(raw.request)) {
80
+ throw new QgisSdkDeclarationError2(`${id}: request schema must be an object`);
81
+ }
82
+ return {
83
+ raw,
84
+ id,
85
+ title,
86
+ handler: raw.handler,
87
+ request: Object.freeze({ ...raw.request })
88
+ };
89
+ }
90
+ function parseActionDescription(raw) {
91
+ const head = parseOperationHead(raw, "action");
92
+ if (!isPlainRecord(head.raw.result)) {
93
+ throw new QgisSdkDeclarationError2(`${head.id}: result schema must be an object`);
94
+ }
95
+ return Object.freeze({
96
+ id: head.id,
97
+ title: head.title,
98
+ handler: head.handler,
99
+ request: head.request,
100
+ result: Object.freeze({ ...head.raw.result })
101
+ });
102
+ }
103
+ function parseStreamDescription(raw) {
104
+ const head = parseOperationHead(raw, "stream");
105
+ const declared = head.raw.events;
106
+ if (!isPlainRecord(declared) || Object.keys(declared).length === 0) {
107
+ throw new QgisSdkDeclarationError2(`${head.id}: events must map at least one event kind to a schema`);
108
+ }
109
+ const events = {};
110
+ for (const [kind, schema] of Object.entries(declared)) {
111
+ if (!STREAM_EVENT_KINDS.includes(kind)) {
112
+ throw new QgisSdkDeclarationError2(`${head.id}: ${kind} is not a stream event kind`);
113
+ }
114
+ if (!isPlainRecord(schema)) {
115
+ throw new QgisSdkDeclarationError2(`${head.id}: events.${kind} schema must be an object`);
116
+ }
117
+ events[kind] = Object.freeze({ ...schema });
118
+ }
119
+ return Object.freeze({
120
+ id: head.id,
121
+ title: head.title,
122
+ handler: head.handler,
123
+ request: head.request,
124
+ events: Object.freeze(events)
125
+ });
126
+ }
127
+ function parsePluginDescription2(input) {
128
+ let parsed = input;
129
+ if (typeof input === "string") {
130
+ try {
131
+ parsed = JSON.parse(input);
132
+ } catch {
133
+ throw new QgisSdkDeclarationError2("Plugin description is not valid JSON");
134
+ }
135
+ }
136
+ if (!isPlainRecord(parsed)) {
137
+ throw new QgisSdkDeclarationError2("Plugin description must be an object");
138
+ }
139
+ if (parsed.schema_version !== PLUGIN_DESCRIPTION_SCHEMA_VERSION2) {
140
+ throw new QgisSdkDeclarationError2(`Unsupported plugin description schema_version: ${String(parsed.schema_version)}`);
141
+ }
142
+ const id = validateDeclarationId(parsed.id, "plugin");
143
+ const title = validateNonBlankTitle(parsed.title, id);
144
+ if (!Array.isArray(parsed.actions)) {
145
+ throw new QgisSdkDeclarationError2(`${id}: actions must be an array`);
146
+ }
147
+ const declaredStreams = parsed.streams ?? [];
148
+ if (!Array.isArray(declaredStreams)) {
149
+ throw new QgisSdkDeclarationError2(`${id}: streams must be an array`);
150
+ }
151
+ const seenIds = new Set;
152
+ const claim = (operationId, label) => {
153
+ if (seenIds.has(operationId)) {
154
+ throw new QgisSdkDeclarationError2(`${id}: duplicate ${label} id ${operationId}`);
155
+ }
156
+ seenIds.add(operationId);
157
+ };
158
+ const actions = [];
159
+ for (const item of parsed.actions) {
160
+ const action = parseActionDescription(item);
161
+ claim(action.id, "action");
162
+ actions.push(action);
163
+ }
164
+ const streams = [];
165
+ for (const item of declaredStreams) {
166
+ const stream = parseStreamDescription(item);
167
+ claim(stream.id, "stream");
168
+ streams.push(stream);
169
+ }
170
+ const byId = (left, right) => left.id < right.id ? -1 : 1;
171
+ actions.sort(byId);
172
+ streams.sort(byId);
173
+ return Object.freeze({
174
+ schema_version: PLUGIN_DESCRIPTION_SCHEMA_VERSION2,
175
+ id,
176
+ title,
177
+ actions: Object.freeze(actions),
178
+ streams: Object.freeze(streams)
179
+ });
180
+ }
181
+
182
+ // src/validate.ts
183
+ class QgisSdkContractError2 extends QgisSdkError2 {
184
+ operation;
185
+ direction;
186
+ issues;
187
+ constructor(operation, direction, issues) {
188
+ const detail = issues[0] === undefined ? "" : `: ${describe(issues[0])}`;
189
+ super(`${operation}: the ${direction} does not match the declared contract${detail}`, "contract_validation_failed");
190
+ this.operation = operation;
191
+ this.direction = direction;
192
+ this.issues = Object.freeze([...issues]);
193
+ }
194
+ toJSON() {
195
+ return {
196
+ code: this.code,
197
+ operation: this.operation,
198
+ direction: this.direction,
199
+ issues: this.issues.map((issue) => issue.toJSON())
200
+ };
201
+ }
202
+ }
203
+ function describe(issue) {
204
+ const where = issue.path.length === 0 ? "value" : issue.path.join(".");
205
+ return `${where} ${issue.code}`;
206
+ }
207
+ var PRIMITIVES = new Set([
208
+ "string",
209
+ "boolean",
210
+ "integer",
211
+ "number",
212
+ "null",
213
+ "array",
214
+ "object"
215
+ ]);
216
+ var KNOWN_KEYWORDS = new Set([
217
+ "type",
218
+ "properties",
219
+ "required",
220
+ "additionalProperties",
221
+ "items",
222
+ "anyOf",
223
+ "enum",
224
+ "minimum",
225
+ "maximum",
226
+ "pattern",
227
+ "title",
228
+ "description",
229
+ "x-qgis-sdk"
230
+ ]);
231
+ function validateAgainstSchema2(value, schema, options = {}) {
232
+ const issues = [];
233
+ check(value, schema, options.path ?? [], options.allowUnknown === true, issues);
234
+ return issues;
235
+ }
236
+ function check(value, schema, path, allowUnknown, issues) {
237
+ if (!isPlainRecord(schema)) {
238
+ throw new QgisSdkDeclarationError2(`${where(path)}: a schema must be an object`);
239
+ }
240
+ const unknown = Object.keys(schema).filter((key) => !KNOWN_KEYWORDS.has(key));
241
+ if (unknown.length > 0) {
242
+ throw new QgisSdkDeclarationError2(`${where(path)}: unsupported schema keyword(s) ${unknown.sort().join(", ")}`);
243
+ }
244
+ if ("anyOf" in schema) {
245
+ const branches = schema.anyOf;
246
+ if (!Array.isArray(branches) || branches.length === 0) {
247
+ throw new QgisSdkDeclarationError2(`${where(path)}: anyOf must be a nonempty list`);
248
+ }
249
+ for (const branch of branches) {
250
+ const attempt = [];
251
+ check(value, branch, path, allowUnknown, attempt);
252
+ if (attempt.length === 0) {
253
+ return;
254
+ }
255
+ }
256
+ issues.push(new QgisSdkValidationIssue2([...path], "any_of"));
257
+ return;
258
+ }
259
+ if ("enum" in schema) {
260
+ const choices = schema.enum;
261
+ if (!Array.isArray(choices)) {
262
+ throw new QgisSdkDeclarationError2(`${where(path)}: enum must be a list`);
263
+ }
264
+ if (!choices.some((choice) => sameJson(choice, value))) {
265
+ issues.push(new QgisSdkValidationIssue2([...path], "enum"));
266
+ }
267
+ return;
268
+ }
269
+ const declared = schema.type;
270
+ if (declared === undefined) {
271
+ throw new QgisSdkDeclarationError2(`${where(path)}: a schema needs a type, anyOf or enum`);
272
+ }
273
+ if (typeof declared !== "string" || !PRIMITIVES.has(declared)) {
274
+ throw new QgisSdkDeclarationError2(`${where(path)}: unsupported type ${JSON.stringify(declared)}`);
275
+ }
276
+ switch (declared) {
277
+ case "string":
278
+ checkString(value, schema, path, issues);
279
+ return;
280
+ case "boolean":
281
+ if (typeof value !== "boolean") {
282
+ issues.push(new QgisSdkValidationIssue2([...path], "type"));
283
+ }
284
+ return;
285
+ case "integer":
286
+ if (typeof value !== "number" || !Number.isInteger(value)) {
287
+ issues.push(new QgisSdkValidationIssue2([...path], "type"));
288
+ return;
289
+ }
290
+ checkBounds(value, schema, path, issues);
291
+ return;
292
+ case "number":
293
+ if (typeof value !== "number") {
294
+ issues.push(new QgisSdkValidationIssue2([...path], "type"));
295
+ return;
296
+ }
297
+ if (!Number.isFinite(value)) {
298
+ issues.push(new QgisSdkValidationIssue2([...path], "not_finite"));
299
+ return;
300
+ }
301
+ checkBounds(value, schema, path, issues);
302
+ return;
303
+ case "null":
304
+ if (value !== null) {
305
+ issues.push(new QgisSdkValidationIssue2([...path], "type"));
306
+ }
307
+ return;
308
+ case "array":
309
+ checkArray(value, schema, path, allowUnknown, issues);
310
+ return;
311
+ default:
312
+ checkObject(value, schema, path, allowUnknown, issues);
313
+ }
314
+ }
315
+ function checkString(value, schema, path, issues) {
316
+ if (typeof value !== "string") {
317
+ issues.push(new QgisSdkValidationIssue2([...path], "type"));
318
+ return;
319
+ }
320
+ const pattern = schema.pattern;
321
+ if (pattern === undefined || pattern === null) {
322
+ return;
323
+ }
324
+ if (typeof pattern !== "string") {
325
+ throw new QgisSdkDeclarationError2(`${where(path)}: pattern must be a string`);
326
+ }
327
+ let expression;
328
+ try {
329
+ expression = new RegExp(`^(?:${pattern})$`, "u");
330
+ } catch (error) {
331
+ throw new QgisSdkDeclarationError2(`${where(path)}: pattern ${JSON.stringify(pattern)} is unusable: ${String(error)}`);
332
+ }
333
+ if (!expression.test(value)) {
334
+ issues.push(new QgisSdkValidationIssue2([...path], "pattern"));
335
+ }
336
+ }
337
+ function checkBounds(value, schema, path, issues) {
338
+ const minimum = schema.minimum;
339
+ if (typeof minimum === "number" && value < minimum) {
340
+ issues.push(new QgisSdkValidationIssue2([...path], "minimum"));
341
+ }
342
+ const maximum = schema.maximum;
343
+ if (typeof maximum === "number" && value > maximum) {
344
+ issues.push(new QgisSdkValidationIssue2([...path], "maximum"));
345
+ }
346
+ }
347
+ function checkArray(value, schema, path, allowUnknown, issues) {
348
+ if (!Array.isArray(value)) {
349
+ issues.push(new QgisSdkValidationIssue2([...path], "type"));
350
+ return;
351
+ }
352
+ const items = schema.items;
353
+ if (items === undefined || items === null) {
354
+ return;
355
+ }
356
+ value.forEach((item, index) => {
357
+ check(item, items, [...path, index], allowUnknown, issues);
358
+ });
359
+ }
360
+ function checkObject(value, schema, path, allowUnknown, issues) {
361
+ if (!isPlainRecord(value)) {
362
+ issues.push(new QgisSdkValidationIssue2([...path], "type"));
363
+ return;
364
+ }
365
+ const properties = schema.properties ?? {};
366
+ if (!isPlainRecord(properties)) {
367
+ throw new QgisSdkDeclarationError2(`${where(path)}: properties must be an object`);
368
+ }
369
+ const required = schema.required ?? [];
370
+ if (!Array.isArray(required)) {
371
+ throw new QgisSdkDeclarationError2(`${where(path)}: required must be a list`);
372
+ }
373
+ for (const key of required) {
374
+ if (typeof key === "string" && !(key in value)) {
375
+ issues.push(new QgisSdkValidationIssue2([...path, key], "required"));
376
+ }
377
+ }
378
+ const strict = schema.additionalProperties === false && !allowUnknown;
379
+ for (const [key, item] of Object.entries(value)) {
380
+ if (Object.hasOwn(properties, key)) {
381
+ check(item, properties[key], [...path, key], allowUnknown, issues);
382
+ } else if (strict) {
383
+ issues.push(new QgisSdkValidationIssue2([...path, key], "unknown_property"));
384
+ }
385
+ }
386
+ }
387
+ function sameJson(a, b) {
388
+ if (a === b) {
389
+ return true;
390
+ }
391
+ if (typeof a !== typeof b || a === null || b === null) {
392
+ return false;
393
+ }
394
+ if (Array.isArray(a)) {
395
+ return Array.isArray(b) && a.length === b.length && a.every((item, index) => sameJson(item, b[index]));
396
+ }
397
+ if (isPlainRecord(a) && isPlainRecord(b)) {
398
+ const keys = Object.keys(a);
399
+ return keys.length === Object.keys(b).length && keys.every((key) => Object.hasOwn(b, key) && sameJson(a[key], b[key]));
400
+ }
401
+ return false;
402
+ }
403
+ function where(path) {
404
+ return path.length === 0 ? "value" : path.join(".");
405
+ }
406
+
407
+ // src/stores.ts
408
+ class QgisSdkStoreError2 extends QgisSdkError2 {
409
+ constructor(message) {
410
+ super(message, "store_binding");
411
+ }
412
+ }
413
+
414
+ class BaseStore {
415
+ snapshot;
416
+ listeners = new Set;
417
+ constructor(initial) {
418
+ this.snapshot = initial;
419
+ }
420
+ getSnapshot = () => this.snapshot;
421
+ subscribe = (listener) => {
422
+ this.listeners.add(listener);
423
+ listener(this.snapshot);
424
+ return () => {
425
+ this.listeners.delete(listener);
426
+ };
427
+ };
428
+ publish(next) {
429
+ if (Object.is(next, this.snapshot)) {
430
+ return;
431
+ }
432
+ this.snapshot = next;
433
+ for (const listener of [...this.listeners]) {
434
+ listener(next);
435
+ }
436
+ }
437
+ }
438
+ function asError(error) {
439
+ return error instanceof Error ? error : new Error(String(error));
440
+ }
441
+ var IDLE = Object.freeze({ status: "idle" });
442
+ var PENDING = Object.freeze({ status: "pending" });
443
+
444
+ class OperationStore2 extends BaseStore {
445
+ operation;
446
+ generation = 0;
447
+ controller = null;
448
+ constructor(operation) {
449
+ super(IDLE);
450
+ this.operation = operation;
451
+ }
452
+ abort = () => {
453
+ this.generation += 1;
454
+ this.controller?.abort();
455
+ this.controller = null;
456
+ };
457
+ reset = () => {
458
+ this.abort();
459
+ this.publish(IDLE);
460
+ };
461
+ run = async (input) => {
462
+ this.abort();
463
+ const mine = this.generation;
464
+ const controller = new AbortController;
465
+ this.controller = controller;
466
+ this.publish(PENDING);
467
+ try {
468
+ const value = await this.operation(input, { signal: controller.signal });
469
+ if (this.generation !== mine) {
470
+ return;
471
+ }
472
+ this.publish({ status: "ok", value });
473
+ return value;
474
+ } catch (error) {
475
+ if (this.generation !== mine || error instanceof QgisSdkBridgeAbortedError2) {
476
+ return;
477
+ }
478
+ this.publish({ status: "error", error: asError(error) });
479
+ return;
480
+ } finally {
481
+ if (this.controller === controller) {
482
+ this.controller = null;
483
+ }
484
+ }
485
+ };
486
+ }
487
+ var IDLE_STREAM = Object.freeze({
488
+ status: "idle",
489
+ lastEvent: null,
490
+ terminal: null,
491
+ error: null
492
+ });
493
+ function stableKey2(value) {
494
+ return JSON.stringify(value, (_key, item) => isPlainRecord(item) ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) : item);
495
+ }
496
+
497
+ class StreamStore2 extends BaseStore {
498
+ open;
499
+ handlers;
500
+ key = null;
501
+ cancel = null;
502
+ constructor(open, handlers = {}) {
503
+ super(IDLE_STREAM);
504
+ this.open = open;
505
+ this.handlers = handlers;
506
+ }
507
+ setHandlers(handlers) {
508
+ this.handlers = handlers;
509
+ }
510
+ setInput = (input) => {
511
+ const key = input === null ? null : stableKey2(input);
512
+ if (key === this.key) {
513
+ return;
514
+ }
515
+ this.cancel?.();
516
+ this.cancel = null;
517
+ this.key = key;
518
+ if (input === null || key === null) {
519
+ this.publish(IDLE_STREAM);
520
+ return;
521
+ }
522
+ this.cancel = this.start(input);
523
+ };
524
+ close = () => {
525
+ this.setInput(null);
526
+ };
527
+ start(input) {
528
+ let cancelled = false;
529
+ let handle = null;
530
+ const update = (change) => {
531
+ if (!cancelled) {
532
+ this.publish(change(this.getSnapshot()));
533
+ }
534
+ };
535
+ this.publish({
536
+ status: "opening",
537
+ lastEvent: null,
538
+ terminal: null,
539
+ error: null
540
+ });
541
+ this.open(input, {
542
+ onEvent: (event) => {
543
+ if (cancelled) {
544
+ return;
545
+ }
546
+ this.handlers.onEvent?.(event);
547
+ update((previous) => ({ ...previous, lastEvent: event }));
548
+ },
549
+ onTerminal: (terminal) => {
550
+ if (cancelled) {
551
+ return;
552
+ }
553
+ this.handlers.onTerminal?.(terminal);
554
+ update((previous) => ({ ...previous, status: "ended", terminal }));
555
+ }
556
+ }).then((opened) => {
557
+ if (cancelled) {
558
+ opened.close();
559
+ return;
560
+ }
561
+ handle = opened;
562
+ update((previous) => previous.status === "ended" ? previous : { ...previous, status: "open" });
563
+ }, (error) => {
564
+ update(() => ({
565
+ status: "failed",
566
+ lastEvent: null,
567
+ terminal: null,
568
+ error: asError(error)
569
+ }));
570
+ });
571
+ return () => {
572
+ cancelled = true;
573
+ handle?.close();
574
+ };
575
+ }
576
+ }
577
+ var FIELD_KINDS = new Set([
578
+ "text",
579
+ "integer",
580
+ "number",
581
+ "boolean",
582
+ "choice",
583
+ "layer",
584
+ "crs",
585
+ "metres",
586
+ "file",
587
+ "directory",
588
+ "field",
589
+ "range",
590
+ "colour"
591
+ ]);
592
+ var PRIMITIVE_KINDS = {
593
+ string: "text",
594
+ integer: "integer",
595
+ number: "number",
596
+ boolean: "boolean"
597
+ };
598
+ var NUMERIC_KINDS = new Set([
599
+ "integer",
600
+ "number",
601
+ "metres",
602
+ "range"
603
+ ]);
604
+ var DETAIL_KEYS = ["minimum", "maximum", "step", "of", "filters", "alpha"];
605
+ function labelFor2(name) {
606
+ const spaced = name.replace(/_/g, " ").trim();
607
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
608
+ }
609
+ function concrete(schema) {
610
+ const branches = schema.anyOf;
611
+ if (!Array.isArray(branches)) {
612
+ return [schema, false];
613
+ }
614
+ const nonNull = branches.filter((branch) => isPlainRecord(branch) && branch.type !== "null");
615
+ if (nonNull.length === 1 && nonNull.length !== branches.length) {
616
+ return [nonNull[0], true];
617
+ }
618
+ throw new QgisSdkStoreError2("a union field must be one type or that type plus null to be rendered");
619
+ }
620
+ function kindFor(owner, name, schema) {
621
+ const intent = schema["x-qgis-sdk"];
622
+ const marked = isPlainRecord(intent) ? intent.kind : undefined;
623
+ if (typeof marked === "string") {
624
+ if (!FIELD_KINDS.has(marked)) {
625
+ throw new QgisSdkStoreError2(`${owner}: field ${name} has unknown kind ${JSON.stringify(marked)}`);
626
+ }
627
+ return marked;
628
+ }
629
+ if ("enum" in schema) {
630
+ return "choice";
631
+ }
632
+ const kind = PRIMITIVE_KINDS[String(schema.type)];
633
+ if (kind === undefined) {
634
+ throw new QgisSdkStoreError2(`${owner}: field ${name} has no input for its schema; declare a primitive, an enum or a kind`);
635
+ }
636
+ return kind;
637
+ }
638
+ function schemaFields2(schema, owner = "form") {
639
+ const properties = schema.properties;
640
+ if (!isPlainRecord(properties)) {
641
+ return Object.freeze([]);
642
+ }
643
+ const required = new Set(Array.isArray(schema.required) ? schema.required : []);
644
+ return Object.freeze(Object.entries(properties).map(([name, property]) => {
645
+ if (!isPlainRecord(property)) {
646
+ throw new QgisSdkStoreError2(`${owner}: field ${name} is not a schema`);
647
+ }
648
+ const [shape, nullable] = concrete(property);
649
+ const kind = kindFor(owner, name, shape);
650
+ const intent = isPlainRecord(shape["x-qgis-sdk"]) ? shape["x-qgis-sdk"] : {};
651
+ const merged = { ...shape, ...intent };
652
+ const details = kind === "integer" ? {} : Object.fromEntries(DETAIL_KEYS.filter((key) => (key in merged)).map((key) => [
653
+ key,
654
+ merged[key]
655
+ ]));
656
+ return Object.freeze({
657
+ name,
658
+ label: labelFor2(name),
659
+ kind,
660
+ required: required.has(name) && !nullable,
661
+ nullable,
662
+ choices: Object.freeze(kind === "choice" && Array.isArray(shape.enum) ? [...shape.enum] : []),
663
+ details: Object.freeze(details),
664
+ schema: property
665
+ });
666
+ }));
667
+ }
668
+ function operationOf(qgis, id) {
669
+ let node = qgis;
670
+ for (const segment of id.split(".")) {
671
+ node = isPlainRecord(node) || typeof node === "function" ? node[segment] : undefined;
672
+ }
673
+ if (typeof node !== "function") {
674
+ throw new QgisSdkStoreError2(`${id} is not an operation of this QgisSdk`);
675
+ }
676
+ return node;
677
+ }
678
+ function coerce(field, value) {
679
+ if (value === "" && field.kind !== "text") {
680
+ return;
681
+ }
682
+ if (NUMERIC_KINDS.has(field.kind) && typeof value === "string") {
683
+ const trimmed = value.trim();
684
+ if (trimmed !== "" && /^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$/.test(trimmed)) {
685
+ const number = Number(trimmed);
686
+ if (field.kind !== "integer" || Number.isInteger(number)) {
687
+ return number;
688
+ }
689
+ }
690
+ }
691
+ return value;
692
+ }
693
+
694
+ class FormStore2 extends BaseStore {
695
+ id;
696
+ title;
697
+ fields;
698
+ byName;
699
+ request;
700
+ initial;
701
+ operation;
702
+ unsubscribe;
703
+ constructor(qgis, id, options = {}) {
704
+ const action = qgis.schema.actions.find((candidate) => candidate.id === id);
705
+ if (action === undefined) {
706
+ throw new QgisSdkStoreError2(`${id} is not a declared action of this schema`);
707
+ }
708
+ const fields = schemaFields2(action.request, `form ${id}`);
709
+ const initial = FormStore2.defaults(options.initial ?? {});
710
+ super(FormStore2.evaluate(initial, action.request, false, false, IDLE));
711
+ this.id = id;
712
+ this.title = action.title;
713
+ this.fields = fields;
714
+ this.byName = new Map(fields.map((field) => [field.name, field]));
715
+ this.request = action.request;
716
+ this.initial = initial;
717
+ this.operation = new OperationStore2(operationOf(qgis, id));
718
+ let first = true;
719
+ this.unsubscribe = this.operation.subscribe((submission) => {
720
+ if (first) {
721
+ first = false;
722
+ return;
723
+ }
724
+ const current = this.getSnapshot();
725
+ this.publish({ ...current, submission });
726
+ });
727
+ }
728
+ static describe(qgis, id) {
729
+ return qgis.schema.actions.find((candidate) => candidate.id === id);
730
+ }
731
+ static defaults(initial) {
732
+ return Object.freeze(Object.fromEntries(Object.entries(initial).filter(([, value]) => value !== undefined)));
733
+ }
734
+ static evaluate(values, request, dirty, submitted, submission) {
735
+ const issues = validateAgainstSchema2(values, request);
736
+ const errors = {};
737
+ for (const issue of issues) {
738
+ const [head] = issue.path;
739
+ const name = typeof head === "string" ? head : "";
740
+ if (!(name in errors)) {
741
+ errors[name] = issue.code;
742
+ }
743
+ }
744
+ return Object.freeze({
745
+ values,
746
+ issues: Object.freeze(issues),
747
+ errors: Object.freeze(errors),
748
+ valid: issues.length === 0,
749
+ dirty,
750
+ submitted,
751
+ submission
752
+ });
753
+ }
754
+ set = (name, value) => {
755
+ this.setValues({ [name]: value });
756
+ };
757
+ setValues = (changes) => {
758
+ const current = this.getSnapshot();
759
+ const values = { ...current.values };
760
+ for (const [name, raw] of Object.entries(changes)) {
761
+ const field = this.byName.get(name);
762
+ if (field === undefined) {
763
+ throw new QgisSdkStoreError2(`${this.id} has no field ${name}`);
764
+ }
765
+ const value = coerce(field, raw);
766
+ if (value === undefined) {
767
+ delete values[name];
768
+ } else {
769
+ values[name] = value;
770
+ }
771
+ }
772
+ this.publish(FormStore2.evaluate(Object.freeze(values), this.request, true, current.submitted, current.submission));
773
+ };
774
+ field(name) {
775
+ const field = this.byName.get(name);
776
+ if (field === undefined) {
777
+ throw new QgisSdkStoreError2(`${this.id} has no field ${name}`);
778
+ }
779
+ return field;
780
+ }
781
+ reset = () => {
782
+ this.operation.reset();
783
+ this.publish(FormStore2.evaluate(this.initial, this.request, false, false, IDLE));
784
+ };
785
+ abort = () => {
786
+ this.operation.abort();
787
+ };
788
+ submit = async () => {
789
+ const current = this.getSnapshot();
790
+ if (!current.valid) {
791
+ this.publish({ ...current, submitted: true });
792
+ return;
793
+ }
794
+ if (!current.submitted) {
795
+ this.publish({ ...current, submitted: true });
796
+ }
797
+ return this.operation.run(current.values);
798
+ };
799
+ dispose() {
800
+ this.operation.abort();
801
+ this.unsubscribe();
802
+ }
803
+ }
804
+ function formStore2(qgis, id, options) {
805
+ return new FormStore2(qgis, id, options);
806
+ }
807
+ var IDLE_QUERY = Object.freeze({ status: "idle" });
808
+
809
+ class HostQueryStore2 extends BaseStore {
810
+ qgis;
811
+ operation;
812
+ loader;
813
+ generation = 0;
814
+ controller = null;
815
+ constructor(qgis, operation, loader) {
816
+ super(IDLE_QUERY);
817
+ this.qgis = qgis;
818
+ this.operation = operation;
819
+ this.loader = loader;
820
+ }
821
+ abort = () => {
822
+ this.generation += 1;
823
+ this.controller?.abort();
824
+ this.controller = null;
825
+ };
826
+ reset = () => {
827
+ this.abort();
828
+ this.publish(IDLE_QUERY);
829
+ };
830
+ refresh = async () => {
831
+ this.abort();
832
+ const mine = this.generation;
833
+ const controller = new AbortController;
834
+ this.controller = controller;
835
+ this.publish({ status: "loading" });
836
+ try {
837
+ await this.qgis.ready;
838
+ if (this.generation !== mine) {
839
+ return;
840
+ }
841
+ if (!this.qgis.host.granted.includes(this.operation)) {
842
+ this.publish({
843
+ status: "refused",
844
+ operation: this.operation,
845
+ message: `this view was not granted ${this.operation}`
846
+ });
847
+ return;
848
+ }
849
+ const value = await this.loader(this.qgis.host, {
850
+ signal: controller.signal
851
+ });
852
+ if (this.generation !== mine) {
853
+ return;
854
+ }
855
+ this.publish({ status: "ok", value });
856
+ return value;
857
+ } catch (error) {
858
+ if (this.generation !== mine || error instanceof QgisSdkBridgeAbortedError2) {
859
+ return;
860
+ }
861
+ this.publish({ status: "error", error: asError(error) });
862
+ return;
863
+ } finally {
864
+ if (this.controller === controller) {
865
+ this.controller = null;
866
+ }
867
+ }
868
+ };
869
+ }
870
+ function layersQuery2(qgis, options = {}) {
871
+ return new HostQueryStore2(qgis, "layers.list", async (host, { signal }) => {
872
+ const items = [];
873
+ let cursor;
874
+ do {
875
+ const page = await host.layers.list({
876
+ ...cursor === undefined ? {} : { cursor },
877
+ ...options.pageSize === undefined ? {} : { limit: options.pageSize }
878
+ }, { signal });
879
+ items.push(...page.items);
880
+ cursor = page.next_cursor;
881
+ } while (cursor !== undefined);
882
+ return Object.freeze(items);
883
+ });
884
+ }
885
+ function layerFieldsQuery2(qgis, layerId) {
886
+ return new HostQueryStore2(qgis, "layers.get", async (host, { signal }) => {
887
+ const layer = await host.layers.get({ layer_id: layerId }, { signal });
888
+ return Object.freeze([...layer.field_names]);
889
+ });
890
+ }
891
+
892
+ export { MAX_SAFE_INTEGER2, MIN_SAFE_INTEGER2, PLUGIN_DESCRIPTION_SCHEMA_VERSION2, isSafeJsonInteger2, QgisSdkDeclarationError2, QgisSdkValidationIssue2, QgisSdkContractValidationError2, parsePluginDescription2, QgisSdkContractError2, validateAgainstSchema2, QgisSdkStoreError2, OperationStore2, stableKey2, StreamStore2, labelFor2, schemaFields2, FormStore2, formStore2, HostQueryStore2, layersQuery2, layerFieldsQuery2 };
893
+
894
+ //# debugId=E60C228E310DFC3564756E2164756E21
895
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL2RlY2xhcmF0aW9ucy50cyIsICJzcmMvdmFsaWRhdGUudHMiLCAic3JjL3N0b3Jlcy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICAgICIvKipcbiAqIFRoZSB2ZXJzaW9uIDEgcGx1Z2luLWRlc2NyaXB0aW9uIGNvbnRyYWN0IGFuZCBpdHMgd2lyZSBsaW1pdHMuXG4gKlxuICogTWlycm9ycyB0aGUgUUdJUy1mcmVlIGBxZ2lzX3Nkay5tb2RlbHNgIGFuZCBgcWdpc19zZGsuZGVjbGFyYXRpb25zYFxuICogKGBzY2hlbWFfdmVyc2lvbiA9IDFgKSBjb250cmFjdHMgd2l0aG91dCBpbXBvcnRpbmcgYnJvd3NlciBvciBRdCBnbG9iYWxzLlxuICogYHBhcnNlUGx1Z2luRGVzY3JpcHRpb25gIGlzIHRoZSBicm93c2VyLXNpZGUgcmVhZGVyIG9mIHdoYXRcbiAqIGBkZXNjcmliZV9wbHVnaW4oY2xzKS50b19qc29uKClgIGVtaXRzOyBgcWdpcy1zZGsgYnJpZGdlIGdlbmVyYXRlYCBpcyB0aGVcbiAqIGJ1aWxkLXRpbWUgb25lLlxuICovXG5cbmltcG9ydCB7IFFnaXNTZGtFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuaW1wb3J0IHsgaXNQbGFpblJlY29yZCwgU1RSRUFNX0VWRU5UX0tJTkRTIH0gZnJvbSBcIi4vaW50ZXJuYWxcIjtcblxuZXhwb3J0IGNvbnN0IE1BWF9TQUZFX0lOVEVHRVI6IG51bWJlciA9IDlfMDA3XzE5OV8yNTRfNzQwXzk5MTtcbmV4cG9ydCBjb25zdCBNSU5fU0FGRV9JTlRFR0VSOiBudW1iZXIgPSAtOV8wMDdfMTk5XzI1NF83NDBfOTkxO1xuZXhwb3J0IGNvbnN0IFBMVUdJTl9ERVNDUklQVElPTl9TQ0hFTUFfVkVSU0lPTjogMSA9IDE7XG5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25EaXJlY3Rpb24gPSBcInJlcXVlc3RcIiB8IFwicmVzdWx0XCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VyaWFsaXplZFZhbGlkYXRpb25Jc3N1ZSB7XG5cdHJlYWRvbmx5IHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW107XG5cdHJlYWRvbmx5IGNvZGU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXJpYWxpemVkQ29udHJhY3RWYWxpZGF0aW9uRXJyb3Ige1xuXHRyZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGRpcmVjdGlvbjogVmFsaWRhdGlvbkRpcmVjdGlvbjtcblx0cmVhZG9ubHkgaXNzdWVzOiBTZXJpYWxpemVkVmFsaWRhdGlvbklzc3VlW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uRGVzY3JpcHRpb24ge1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBoYW5kbGVyOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHJlcXVlc3Q6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcblx0cmVhZG9ubHkgcmVzdWx0OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG59XG5cbi8qKiBUaGUgZXZlbnQga2luZHMgYSBzdHJlYW0gbWF5IGRlY2xhcmU7IHRoZSBmcmFtZSBjYXJyaWVzIHRoZSBzYW1lIHRocmVlLiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtRXZlbnRLaW5kID0gXCJkYXRhXCIgfCBcInByb2dyZXNzXCIgfCBcInN0YXRlXCI7XG5cbi8qKlxuICogQSBkZWNsYXJlZCBzdHJlYW0gKGRlY2lzaW9uLTI4KTogYSByZXF1ZXN0IGluLCBvbmUgcGF5bG9hZCBzY2hlbWEgcGVyXG4gKiBkZWNsYXJlZCBldmVudCBraW5kIG91dC4gVGhlcmUgaXMgbm8gYHJlc3VsdGA6IHRoZSByZXBseSB0byBhIHN1YnNjcmlwdGlvbiBpc1xuICogdGhlIHByb3RvY29sJ3MgYWNrbm93bGVkZ2VtZW50LCBub3Qgc29tZXRoaW5nIGFuIGF1dGhvciBkZWNsYXJlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJlYW1EZXNjcmlwdGlvbiB7XG5cdHJlYWRvbmx5IGlkOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGhhbmRsZXI6IHN0cmluZztcblx0cmVhZG9ubHkgcmVxdWVzdDogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuXHRyZWFkb25seSBldmVudHM6IFJlYWRvbmx5PFxuXHRcdFBhcnRpYWw8UmVjb3JkPFN0cmVhbUV2ZW50S2luZCwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+Pj5cblx0Pjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQbHVnaW5EZXNjcmlwdGlvbiB7XG5cdHJlYWRvbmx5IHNjaGVtYV92ZXJzaW9uOiAxO1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBhY3Rpb25zOiByZWFkb25seSBBY3Rpb25EZXNjcmlwdGlvbltdO1xuXHQvKiogRGVjbGFyZWQgc3RyZWFtczsgYSBkZXNjcmlwdGlvbiBmcm9tIGEgaG9zdCB0aGF0IHByZWRhdGVzIHRoZW0gaXMgZW1wdHkuICovXG5cdHJlYWRvbmx5IHN0cmVhbXM6IHJlYWRvbmx5IFN0cmVhbURlc2NyaXB0aW9uW107XG59XG5cbi8qKlxuICogUmV0dXJuIHdoZXRoZXIgYHZhbHVlYCBpcyBhIGZpbml0ZSBpbnRlZ2VyIHdpdGhpbiB0aGUgSmF2YVNjcmlwdC1zYWZlIHdpcmUgcmFuZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NhZmVKc29uSW50ZWdlcih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlciB7XG5cdHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzU2FmZUludGVnZXIodmFsdWUpO1xufVxuXG4vKipcbiAqIEEgZGVjbGFyYXRpb24gY2Fubm90IGJlIHJlcHJlc2VudGVkIG9yIHBhcnNlZCBpbiB0aGUgdmVyc2lvbmVkIGNvbnRyYWN0LlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IgZXh0ZW5kcyBRZ2lzU2RrRXJyb3Ige1xuXHRwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG5cdFx0c3VwZXIobWVzc2FnZSwgXCJpbnZhbGlkX2RlY2xhcmF0aW9uXCIpO1xuXHR9XG59XG5cbi8qKlxuICogU2FmZSwgc3RydWN0dXJlZCBsb2NhdGlvbiBhbmQgY2F0ZWdvcnkgZm9yIGEgcmVqZWN0ZWQgY29udHJhY3QgdmFsdWUuXG4gKi9cbmV4cG9ydCBjbGFzcyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlIHtcblx0cHVibGljIHJlYWRvbmx5IHBhdGg6IHJlYWRvbmx5IChzdHJpbmcgfCBudW1iZXIpW107XG5cdHB1YmxpYyByZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKHBhdGg6IHJlYWRvbmx5IChzdHJpbmcgfCBudW1iZXIpW10sIGNvZGU6IHN0cmluZykge1xuXHRcdHRoaXMucGF0aCA9IE9iamVjdC5mcmVlemUoWy4uLnBhdGhdKTtcblx0XHR0aGlzLmNvZGUgPSBjb2RlO1xuXHR9XG5cblx0cHVibGljIHRvSlNPTigpOiBTZXJpYWxpemVkVmFsaWRhdGlvbklzc3VlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0cGF0aDogWy4uLnRoaXMucGF0aF0sXG5cdFx0XHRjb2RlOiB0aGlzLmNvZGUsXG5cdFx0fTtcblx0fVxufVxuXG4vKipcbiAqIEEgcmVxdWVzdCBvciByZXN1bHQgZGlkIG5vdCBzYXRpc2Z5IGl0cyBkZWNsYXJlZCB3aXJlIGNvbnRyYWN0LlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka0NvbnRyYWN0VmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgUWdpc1Nka0Vycm9yIHtcblx0cHVibGljIHJlYWRvbmx5IGRpcmVjdGlvbjogVmFsaWRhdGlvbkRpcmVjdGlvbjtcblx0cHVibGljIHJlYWRvbmx5IGlzc3VlczogcmVhZG9ubHkgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRkaXJlY3Rpb246IFZhbGlkYXRpb25EaXJlY3Rpb24sXG5cdFx0aXNzdWVzOiByZWFkb25seSBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10sXG5cdCkge1xuXHRcdGNvbnN0IHByZWZpeCA9IGRpcmVjdGlvbiA9PT0gXCJyZXF1ZXN0XCIgPyBcIlJlcXVlc3RcIiA6IFwiUmVzdWx0XCI7XG5cdFx0c3VwZXIoYCR7cHJlZml4fSBjb250cmFjdCB2YWxpZGF0aW9uIGZhaWxlZGAsIFwiY29udHJhY3RfdmFsaWRhdGlvbl9mYWlsZWRcIik7XG5cdFx0dGhpcy5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG5cdFx0dGhpcy5pc3N1ZXMgPSBPYmplY3QuZnJlZXplKFsuLi5pc3N1ZXNdKTtcblx0fVxuXG5cdHB1YmxpYyB0b0pTT04oKTogU2VyaWFsaXplZENvbnRyYWN0VmFsaWRhdGlvbkVycm9yIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0Y29kZTogdGhpcy5jb2RlLFxuXHRcdFx0ZGlyZWN0aW9uOiB0aGlzLmRpcmVjdGlvbixcblx0XHRcdGlzc3VlczogdGhpcy5pc3N1ZXMubWFwKChpc3N1ZSkgPT4gaXNzdWUudG9KU09OKCkpLFxuXHRcdH07XG5cdH1cbn1cblxuY29uc3QgREVDTEFSQVRJT05fSURfUEFUVEVSTiA9IC9eW2EtekEtWl1bYS16QS1aMC05Xy4tXSokLztcbmNvbnN0IFBZVEhPTl9JREVOVElGSUVSX1BBVFRFUk4gPSAvXlthLXpBLVpfXVthLXpBLVowLTlfXSokLztcblxuZnVuY3Rpb24gdmFsaWRhdGVEZWNsYXJhdGlvbklkKHZhbHVlOiB1bmtub3duLCBsYWJlbDogc3RyaW5nKTogc3RyaW5nIHtcblx0aWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIiB8fCAhREVDTEFSQVRJT05fSURfUEFUVEVSTi50ZXN0KHZhbHVlKSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGBJbnZhbGlkICR7bGFiZWx9IGlkOiBleHBlY3RlZCBbYS16QS1aXVthLXpBLVowLTlfLi1dKmAsXG5cdFx0KTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlTm9uQmxhbmtUaXRsZSh2YWx1ZTogdW5rbm93biwgaWQ6IHN0cmluZyk6IHN0cmluZyB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIgfHwgdmFsdWUudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihgJHtpZH06IHRpdGxlIG11c3QgYmUgYSBub25lbXB0eSBzdHJpbmdgKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHBhcnNlT3BlcmF0aW9uSGVhZChcblx0cmF3OiB1bmtub3duLFxuXHRsYWJlbDogc3RyaW5nLFxuKToge1xuXHRyZWFkb25seSByYXc6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBoYW5kbGVyOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHJlcXVlc3Q6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcbn0ge1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQocmF3KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2xhYmVsWzBdPy50b1VwcGVyQ2FzZSgpfSR7bGFiZWwuc2xpY2UoMSl9IGRlc2NyaXB0aW9uIG11c3QgYmUgYW4gb2JqZWN0YCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IGlkID0gdmFsaWRhdGVEZWNsYXJhdGlvbklkKHJhdy5pZCwgbGFiZWwpO1xuXHRjb25zdCB0aXRsZSA9IHZhbGlkYXRlTm9uQmxhbmtUaXRsZShyYXcudGl0bGUsIGlkKTtcblx0aWYgKFxuXHRcdHR5cGVvZiByYXcuaGFuZGxlciAhPT0gXCJzdHJpbmdcIiB8fFxuXHRcdCFQWVRIT05fSURFTlRJRklFUl9QQVRURVJOLnRlc3QocmF3LmhhbmRsZXIpXG5cdCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2lkfTogaGFuZGxlciBtdXN0IGJlIGEgdmFsaWQgUHl0aG9uIGlkZW50aWZpZXJgLFxuXHRcdCk7XG5cdH1cblx0aWYgKCFpc1BsYWluUmVjb3JkKHJhdy5yZXF1ZXN0KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2lkfTogcmVxdWVzdCBzY2hlbWEgbXVzdCBiZSBhbiBvYmplY3RgLFxuXHRcdCk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRyYXcsXG5cdFx0aWQsXG5cdFx0dGl0bGUsXG5cdFx0aGFuZGxlcjogcmF3LmhhbmRsZXIsXG5cdFx0cmVxdWVzdDogT2JqZWN0LmZyZWV6ZSh7IC4uLnJhdy5yZXF1ZXN0IH0pLFxuXHR9O1xufVxuXG5mdW5jdGlvbiBwYXJzZUFjdGlvbkRlc2NyaXB0aW9uKHJhdzogdW5rbm93bik6IEFjdGlvbkRlc2NyaXB0aW9uIHtcblx0Y29uc3QgaGVhZCA9IHBhcnNlT3BlcmF0aW9uSGVhZChyYXcsIFwiYWN0aW9uXCIpO1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQoaGVhZC5yYXcucmVzdWx0KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2hlYWQuaWR9OiByZXN1bHQgc2NoZW1hIG11c3QgYmUgYW4gb2JqZWN0YCxcblx0XHQpO1xuXHR9XG5cdHJldHVybiBPYmplY3QuZnJlZXplKHtcblx0XHRpZDogaGVhZC5pZCxcblx0XHR0aXRsZTogaGVhZC50aXRsZSxcblx0XHRoYW5kbGVyOiBoZWFkLmhhbmRsZXIsXG5cdFx0cmVxdWVzdDogaGVhZC5yZXF1ZXN0LFxuXHRcdHJlc3VsdDogT2JqZWN0LmZyZWV6ZSh7IC4uLmhlYWQucmF3LnJlc3VsdCB9KSxcblx0fSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU3RyZWFtRGVzY3JpcHRpb24ocmF3OiB1bmtub3duKTogU3RyZWFtRGVzY3JpcHRpb24ge1xuXHRjb25zdCBoZWFkID0gcGFyc2VPcGVyYXRpb25IZWFkKHJhdywgXCJzdHJlYW1cIik7XG5cdGNvbnN0IGRlY2xhcmVkID0gaGVhZC5yYXcuZXZlbnRzO1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQoZGVjbGFyZWQpIHx8IE9iamVjdC5rZXlzKGRlY2xhcmVkKS5sZW5ndGggPT09IDApIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHtoZWFkLmlkfTogZXZlbnRzIG11c3QgbWFwIGF0IGxlYXN0IG9uZSBldmVudCBraW5kIHRvIGEgc2NoZW1hYCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IGV2ZW50czogUGFydGlhbDxcblx0XHRSZWNvcmQ8U3RyZWFtRXZlbnRLaW5kLCBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4+XG5cdD4gPSB7fTtcblx0Zm9yIChjb25zdCBba2luZCwgc2NoZW1hXSBvZiBPYmplY3QuZW50cmllcyhkZWNsYXJlZCkpIHtcblx0XHRpZiAoIVNUUkVBTV9FVkVOVF9LSU5EUy5pbmNsdWRlcyhraW5kIGFzIFN0cmVhbUV2ZW50S2luZCkpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aGVhZC5pZH06ICR7a2luZH0gaXMgbm90IGEgc3RyZWFtIGV2ZW50IGtpbmRgLFxuXHRcdFx0KTtcblx0XHR9XG5cdFx0aWYgKCFpc1BsYWluUmVjb3JkKHNjaGVtYSkpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aGVhZC5pZH06IGV2ZW50cy4ke2tpbmR9IHNjaGVtYSBtdXN0IGJlIGFuIG9iamVjdGAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRldmVudHNba2luZCBhcyBTdHJlYW1FdmVudEtpbmRdID0gT2JqZWN0LmZyZWV6ZSh7IC4uLnNjaGVtYSB9KTtcblx0fVxuXHRyZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG5cdFx0aWQ6IGhlYWQuaWQsXG5cdFx0dGl0bGU6IGhlYWQudGl0bGUsXG5cdFx0aGFuZGxlcjogaGVhZC5oYW5kbGVyLFxuXHRcdHJlcXVlc3Q6IGhlYWQucmVxdWVzdCxcblx0XHRldmVudHM6IE9iamVjdC5mcmVlemUoZXZlbnRzKSxcblx0fSk7XG59XG5cbi8qKlxuICogUGFyc2UgYW5kIHZhbGlkYXRlIGEgdmVyc2lvbiAxIGBQbHVnaW5EZXNjcmlwdGlvbmAgZW1pdHRlZCBieSBgZGVzY3JpYmVfcGx1Z2luYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGx1Z2luRGVzY3JpcHRpb24oXG5cdGlucHV0OiBzdHJpbmcgfCBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sXG4pOiBQbHVnaW5EZXNjcmlwdGlvbiB7XG5cdGxldCBwYXJzZWQ6IHVua25vd24gPSBpbnB1dDtcblx0aWYgKHR5cGVvZiBpbnB1dCA9PT0gXCJzdHJpbmdcIikge1xuXHRcdHRyeSB7XG5cdFx0XHRwYXJzZWQgPSBKU09OLnBhcnNlKGlucHV0KTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcIlBsdWdpbiBkZXNjcmlwdGlvbiBpcyBub3QgdmFsaWQgSlNPTlwiKTtcblx0XHR9XG5cdH1cblx0aWYgKCFpc1BsYWluUmVjb3JkKHBhcnNlZCkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXCJQbHVnaW4gZGVzY3JpcHRpb24gbXVzdCBiZSBhbiBvYmplY3RcIik7XG5cdH1cblx0aWYgKHBhcnNlZC5zY2hlbWFfdmVyc2lvbiAhPT0gUExVR0lOX0RFU0NSSVBUSU9OX1NDSEVNQV9WRVJTSU9OKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YFVuc3VwcG9ydGVkIHBsdWdpbiBkZXNjcmlwdGlvbiBzY2hlbWFfdmVyc2lvbjogJHtTdHJpbmcocGFyc2VkLnNjaGVtYV92ZXJzaW9uKX1gLFxuXHRcdCk7XG5cdH1cblx0Y29uc3QgaWQgPSB2YWxpZGF0ZURlY2xhcmF0aW9uSWQocGFyc2VkLmlkLCBcInBsdWdpblwiKTtcblx0Y29uc3QgdGl0bGUgPSB2YWxpZGF0ZU5vbkJsYW5rVGl0bGUocGFyc2VkLnRpdGxlLCBpZCk7XG5cdGlmICghQXJyYXkuaXNBcnJheShwYXJzZWQuYWN0aW9ucykpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoYCR7aWR9OiBhY3Rpb25zIG11c3QgYmUgYW4gYXJyYXlgKTtcblx0fVxuXHRjb25zdCBkZWNsYXJlZFN0cmVhbXMgPSBwYXJzZWQuc3RyZWFtcyA/PyBbXTtcblx0aWYgKCFBcnJheS5pc0FycmF5KGRlY2xhcmVkU3RyZWFtcykpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoYCR7aWR9OiBzdHJlYW1zIG11c3QgYmUgYW4gYXJyYXlgKTtcblx0fVxuXHQvLyBBY3Rpb25zIGFuZCBzdHJlYW1zIHNoYXJlIG9uZSBpZCBuYW1lc3BhY2UgKGRlY2lzaW9uLTI4KS5cblx0Y29uc3Qgc2VlbklkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXHRjb25zdCBjbGFpbSA9IChvcGVyYXRpb25JZDogc3RyaW5nLCBsYWJlbDogc3RyaW5nKTogdm9pZCA9PiB7XG5cdFx0aWYgKHNlZW5JZHMuaGFzKG9wZXJhdGlvbklkKSkge1xuXHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0XHRgJHtpZH06IGR1cGxpY2F0ZSAke2xhYmVsfSBpZCAke29wZXJhdGlvbklkfWAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRzZWVuSWRzLmFkZChvcGVyYXRpb25JZCk7XG5cdH07XG5cdGNvbnN0IGFjdGlvbnM6IEFjdGlvbkRlc2NyaXB0aW9uW10gPSBbXTtcblx0Zm9yIChjb25zdCBpdGVtIG9mIHBhcnNlZC5hY3Rpb25zKSB7XG5cdFx0Y29uc3QgYWN0aW9uID0gcGFyc2VBY3Rpb25EZXNjcmlwdGlvbihpdGVtKTtcblx0XHRjbGFpbShhY3Rpb24uaWQsIFwiYWN0aW9uXCIpO1xuXHRcdGFjdGlvbnMucHVzaChhY3Rpb24pO1xuXHR9XG5cdGNvbnN0IHN0cmVhbXM6IFN0cmVhbURlc2NyaXB0aW9uW10gPSBbXTtcblx0Zm9yIChjb25zdCBpdGVtIG9mIGRlY2xhcmVkU3RyZWFtcykge1xuXHRcdGNvbnN0IHN0cmVhbSA9IHBhcnNlU3RyZWFtRGVzY3JpcHRpb24oaXRlbSk7XG5cdFx0Y2xhaW0oc3RyZWFtLmlkLCBcInN0cmVhbVwiKTtcblx0XHRzdHJlYW1zLnB1c2goc3RyZWFtKTtcblx0fVxuXHRjb25zdCBieUlkID0gKFxuXHRcdGxlZnQ6IHsgcmVhZG9ubHkgaWQ6IHN0cmluZyB9LFxuXHRcdHJpZ2h0OiB7IHJlYWRvbmx5IGlkOiBzdHJpbmcgfSxcblx0KTogbnVtYmVyID0+IChsZWZ0LmlkIDwgcmlnaHQuaWQgPyAtMSA6IDEpO1xuXHRhY3Rpb25zLnNvcnQoYnlJZCk7XG5cdHN0cmVhbXMuc29ydChieUlkKTtcblx0cmV0dXJuIE9iamVjdC5mcmVlemUoe1xuXHRcdHNjaGVtYV92ZXJzaW9uOiBQTFVHSU5fREVTQ1JJUFRJT05fU0NIRU1BX1ZFUlNJT04sXG5cdFx0aWQsXG5cdFx0dGl0bGUsXG5cdFx0YWN0aW9uczogT2JqZWN0LmZyZWV6ZShhY3Rpb25zKSxcblx0XHRzdHJlYW1zOiBPYmplY3QuZnJlZXplKHN0cmVhbXMpLFxuXHR9KTtcbn1cbiIsCiAgICAiLyoqXG4gKiBWYWxpZGF0ZSBhIHZhbHVlIGFnYWluc3QgdGhlIHNjaGVtYSBzdWJzZXQgYGRlc2NyaWJlX3BsdWdpbmAgZW1pdHMuXG4gKlxuICogVGhpcyBpcyB0aGUgVHlwZVNjcmlwdCBzaWRlIG9mIGBxZ2lzX3Nkay5icmlkZ2Uuc2NoZW1hYDogdGhlIHNhbWUgY2xvc2VkXG4gKiBkaWFsZWN0IChvYmplY3RzIHdpdGggYHByb3BlcnRpZXNgL2ByZXF1aXJlZGAvYGFkZGl0aW9uYWxQcm9wZXJ0aWVzYCwgYXJyYXlzXG4gKiB3aXRoIGBpdGVtc2AsIHRoZSBmaXZlIEpTT04gcHJpbWl0aXZlcywgYGFueU9mYCBhbmQgYGVudW1gLCB0aGUgaW50ZWdlclxuICogYm91bmRzIGFuZCBgcGF0dGVybmApIGNoZWNrZWQgdGhlIHNhbWUgd2F5LCBzbyBgUWdpc1Nka2AgcmVmdXNlcyBvbiB0aGUgcGFnZVxuICogZXhhY3RseSB3aGF0IHRoZSBob3N0IHdvdWxkIHJlZnVzZSBhIG1lc3NhZ2UgbGF0ZXIuIEFueXRoaW5nIG91dHNpZGUgdGhlXG4gKiBkaWFsZWN0IGlzIGEgZGVjbGFyYXRpb24gZmF1bHQgYW5kIHRocm93czsgYSB2YWx1ZSB0aGF0IGRvZXMgbm90IGZpdCBpcyBhblxuICogaXNzdWUgdGhlIGNhbGxlciByZXBvcnRzLlxuICpcbiAqIFRoZSB0d28gYXN5bW1ldHJpZXMgb2YgZGVjaXNpb24tMjIgaG9sZCBoZXJlIHRvbzogYSByZXF1ZXN0IGlzIGNoZWNrZWRcbiAqIHN0cmljdGx5IChhbiB1bmtub3duIHByb3BlcnR5IGlzIGFuIGlzc3VlIHdoZW4gdGhlIHNjaGVtYSBjbG9zZXMgdGhlXG4gKiBvYmplY3QpLCBhIHJlc3VsdCBvciBhbiBldmVudCBsZW5pZW50bHkgKGBhbGxvd1Vua25vd25gKSwgc28gYSBob3N0IG1heSBhZGRcbiAqIGEgZmllbGQgd2l0aG91dCBicmVha2luZyBhbiBvbGRlciBwYWdlIHdoaWxlIGEgbWlzc2luZyBvciBtaXN0eXBlZCBmaWVsZCBpc1xuICogc3RpbGwgY2F1Z2h0LlxuICovXG5cbmltcG9ydCB7XG5cdFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yLFxuXHRRZ2lzU2RrVmFsaWRhdGlvbklzc3VlLFxuXHR0eXBlIFNlcmlhbGl6ZWRWYWxpZGF0aW9uSXNzdWUsXG59IGZyb20gXCIuL2RlY2xhcmF0aW9uc1wiO1xuaW1wb3J0IHsgUWdpc1Nka0Vycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBpc1BsYWluUmVjb3JkIH0gZnJvbSBcIi4vaW50ZXJuYWxcIjtcblxuLyoqIE9uZSBzY2hlbWEgb2YgdGhlIGRlY2xhcmVkIGRpYWxlY3QsIGFzIHRoZSBkZXNjcmlwdGlvbiBjYXJyaWVzIGl0LiAqL1xuZXhwb3J0IHR5cGUgRGVjbGFyZWRTY2hlbWEgPSBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgdmFsaWRhdGVBZ2FpbnN0U2NoZW1hfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmFsaWRhdGVPcHRpb25zIHtcblx0LyoqIElnbm9yZSBwcm9wZXJ0aWVzIHRoZSBzY2hlbWEgZG9lcyBub3QgbmFtZSAocmVzdWx0cyBhbmQgZXZlbnRzKS4gKi9cblx0cmVhZG9ubHkgYWxsb3dVbmtub3duPzogYm9vbGVhbjtcblx0LyoqIFdoZXJlIHRoZSB2YWx1ZSBzaXRzLCBwcmVmaXhlZCB0byBldmVyeSBpc3N1ZSdzIHBhdGguICovXG5cdHJlYWRvbmx5IHBhdGg/OiByZWFkb25seSAoc3RyaW5nIHwgbnVtYmVyKVtdO1xufVxuXG4vKiogV2hpY2ggc2lkZSBvZiBhIGNhbGwgYSBjb250cmFjdCBpc3N1ZSBiZWxvbmdzIHRvLiAqL1xuZXhwb3J0IHR5cGUgQ29udHJhY3REaXJlY3Rpb24gPSBcInJlcXVlc3RcIiB8IFwicmVzdWx0XCIgfCBcImV2ZW50XCI7XG5cbi8qKiBUaGUgSlNPTiBmb3JtIG9mIHtAbGluayBRZ2lzU2RrQ29udHJhY3RFcnJvcn0uICovXG5leHBvcnQgaW50ZXJmYWNlIFNlcmlhbGl6ZWRDb250cmFjdEVycm9yIHtcblx0cmVhZG9ubHkgY29kZTogc3RyaW5nO1xuXHRyZWFkb25seSBvcGVyYXRpb246IHN0cmluZztcblx0cmVhZG9ubHkgZGlyZWN0aW9uOiBDb250cmFjdERpcmVjdGlvbjtcblx0cmVhZG9ubHkgaXNzdWVzOiBTZXJpYWxpemVkVmFsaWRhdGlvbklzc3VlW107XG59XG5cbi8qKlxuICogQW4gYXJndW1lbnQsIGEgcmVwbHkgb3IgYW4gZXZlbnQgZG9lcyBub3QgbWF0Y2ggdGhlIGRlY2xhcmVkIGNvbnRyYWN0LlxuICpcbiAqIFRoZSBjb2RlIGlzIHRoZSBvbmUgYm90aCBsYW5ndWFnZXMgdXNlIGZvciB0aGlzIGNhdGVnb3J5LCBzbyBhIHBhZ2UgdGhhdFxuICogYWxyZWFkeSBtYXRjaGVzIGBjb250cmFjdF92YWxpZGF0aW9uX2ZhaWxlZGAgbmVlZHMgbm8gc2Vjb25kIGJyYW5jaC5cbiAqL1xuZXhwb3J0IGNsYXNzIFFnaXNTZGtDb250cmFjdEVycm9yIGV4dGVuZHMgUWdpc1Nka0Vycm9yIHtcblx0cHVibGljIHJlYWRvbmx5IG9wZXJhdGlvbjogc3RyaW5nO1xuXHRwdWJsaWMgcmVhZG9ubHkgZGlyZWN0aW9uOiBDb250cmFjdERpcmVjdGlvbjtcblx0cHVibGljIHJlYWRvbmx5IGlzc3VlczogcmVhZG9ubHkgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRvcGVyYXRpb246IHN0cmluZyxcblx0XHRkaXJlY3Rpb246IENvbnRyYWN0RGlyZWN0aW9uLFxuXHRcdGlzc3VlczogcmVhZG9ubHkgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdLFxuXHQpIHtcblx0XHRjb25zdCBkZXRhaWwgPSBpc3N1ZXNbMF0gPT09IHVuZGVmaW5lZCA/IFwiXCIgOiBgOiAke2Rlc2NyaWJlKGlzc3Vlc1swXSl9YDtcblx0XHRzdXBlcihcblx0XHRcdGAke29wZXJhdGlvbn06IHRoZSAke2RpcmVjdGlvbn0gZG9lcyBub3QgbWF0Y2ggdGhlIGRlY2xhcmVkIGNvbnRyYWN0JHtkZXRhaWx9YCxcblx0XHRcdFwiY29udHJhY3RfdmFsaWRhdGlvbl9mYWlsZWRcIixcblx0XHQpO1xuXHRcdHRoaXMub3BlcmF0aW9uID0gb3BlcmF0aW9uO1xuXHRcdHRoaXMuZGlyZWN0aW9uID0gZGlyZWN0aW9uO1xuXHRcdHRoaXMuaXNzdWVzID0gT2JqZWN0LmZyZWV6ZShbLi4uaXNzdWVzXSk7XG5cdH1cblxuXHRwdWJsaWMgdG9KU09OKCk6IFNlcmlhbGl6ZWRDb250cmFjdEVycm9yIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0Y29kZTogdGhpcy5jb2RlLFxuXHRcdFx0b3BlcmF0aW9uOiB0aGlzLm9wZXJhdGlvbixcblx0XHRcdGRpcmVjdGlvbjogdGhpcy5kaXJlY3Rpb24sXG5cdFx0XHRpc3N1ZXM6IHRoaXMuaXNzdWVzLm1hcCgoaXNzdWUpID0+IGlzc3VlLnRvSlNPTigpKSxcblx0XHR9O1xuXHR9XG59XG5cbmZ1bmN0aW9uIGRlc2NyaWJlKGlzc3VlOiBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlKTogc3RyaW5nIHtcblx0Y29uc3Qgd2hlcmUgPSBpc3N1ZS5wYXRoLmxlbmd0aCA9PT0gMCA/IFwidmFsdWVcIiA6IGlzc3VlLnBhdGguam9pbihcIi5cIik7XG5cdHJldHVybiBgJHt3aGVyZX0gJHtpc3N1ZS5jb2RlfWA7XG59XG5cbmNvbnN0IFBSSU1JVElWRVM6IFJlYWRvbmx5U2V0PHN0cmluZz4gPSBuZXcgU2V0KFtcblx0XCJzdHJpbmdcIixcblx0XCJib29sZWFuXCIsXG5cdFwiaW50ZWdlclwiLFxuXHRcIm51bWJlclwiLFxuXHRcIm51bGxcIixcblx0XCJhcnJheVwiLFxuXHRcIm9iamVjdFwiLFxuXSk7XG5cbmNvbnN0IEtOT1dOX0tFWVdPUkRTOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldChbXG5cdFwidHlwZVwiLFxuXHRcInByb3BlcnRpZXNcIixcblx0XCJyZXF1aXJlZFwiLFxuXHRcImFkZGl0aW9uYWxQcm9wZXJ0aWVzXCIsXG5cdFwiaXRlbXNcIixcblx0XCJhbnlPZlwiLFxuXHRcImVudW1cIixcblx0XCJtaW5pbXVtXCIsXG5cdFwibWF4aW11bVwiLFxuXHRcInBhdHRlcm5cIixcblx0XCJ0aXRsZVwiLFxuXHRcImRlc2NyaXB0aW9uXCIsXG5cdC8vIFRoZSBpbnB1dCBraW5kIGEgZGVzY3JpYmVyIGFubm90YXRlZCAoYHsga2luZDogXCJsYXllclwiIH1gKTsgZm9ybXMgYW5kXG5cdC8vIHBhZ2VzIHJlYWQgaXQsIHZhbGlkYXRpb24gcmVhZHMgcGFzdCBpdC5cblx0XCJ4LXFnaXMtc2RrXCIsXG5dKTtcblxudHlwZSBQYXRoID0gcmVhZG9ubHkgKHN0cmluZyB8IG51bWJlcilbXTtcblxuLyoqXG4gKiBSZXR1cm4gZXZlcnkgaXNzdWUgYHZhbHVlYCBoYXMgYWdhaW5zdCBgc2NoZW1hYDsgYW4gZW1wdHkgYXJyYXkgaXMgYSBtYXRjaC5cbiAqXG4gKiBUaHJvd3Mge0BsaW5rIFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yfSB3aGVuIGBzY2hlbWFgIGxlYXZlcyB0aGUgZGVjbGFyZWRcbiAqIGRpYWxlY3QsIGJlY2F1c2UgdGhhdCBpcyBhIGZhdWx0IGluIHRoZSBkZWNsYXJhdGlvbiwgbmV2ZXIgaW4gdGhlIHZhbHVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVBZ2FpbnN0U2NoZW1hKFxuXHR2YWx1ZTogdW5rbm93bixcblx0c2NoZW1hOiBEZWNsYXJlZFNjaGVtYSxcblx0b3B0aW9uczogVmFsaWRhdGVPcHRpb25zID0ge30sXG4pOiBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10ge1xuXHRjb25zdCBpc3N1ZXM6IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWVbXSA9IFtdO1xuXHRjaGVjayhcblx0XHR2YWx1ZSxcblx0XHRzY2hlbWEsXG5cdFx0b3B0aW9ucy5wYXRoID8/IFtdLFxuXHRcdG9wdGlvbnMuYWxsb3dVbmtub3duID09PSB0cnVlLFxuXHRcdGlzc3Vlcyxcblx0KTtcblx0cmV0dXJuIGlzc3Vlcztcbn1cblxuZnVuY3Rpb24gY2hlY2soXG5cdHZhbHVlOiB1bmtub3duLFxuXHRzY2hlbWE6IHVua25vd24sXG5cdHBhdGg6IFBhdGgsXG5cdGFsbG93VW5rbm93bjogYm9vbGVhbixcblx0aXNzdWVzOiBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10sXG4pOiB2b2lkIHtcblx0aWYgKCFpc1BsYWluUmVjb3JkKHNjaGVtYSkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHt3aGVyZShwYXRoKX06IGEgc2NoZW1hIG11c3QgYmUgYW4gb2JqZWN0YCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IHVua25vd24gPSBPYmplY3Qua2V5cyhzY2hlbWEpLmZpbHRlcigoa2V5KSA9PiAhS05PV05fS0VZV09SRFMuaGFzKGtleSkpO1xuXHRpZiAodW5rbm93bi5sZW5ndGggPiAwKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YCR7d2hlcmUocGF0aCl9OiB1bnN1cHBvcnRlZCBzY2hlbWEga2V5d29yZChzKSAke3Vua25vd24uc29ydCgpLmpvaW4oXCIsIFwiKX1gLFxuXHRcdCk7XG5cdH1cblx0aWYgKFwiYW55T2ZcIiBpbiBzY2hlbWEpIHtcblx0XHRjb25zdCBicmFuY2hlcyA9IHNjaGVtYS5hbnlPZjtcblx0XHRpZiAoIUFycmF5LmlzQXJyYXkoYnJhbmNoZXMpIHx8IGJyYW5jaGVzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0XHRgJHt3aGVyZShwYXRoKX06IGFueU9mIG11c3QgYmUgYSBub25lbXB0eSBsaXN0YCxcblx0XHRcdCk7XG5cdFx0fVxuXHRcdGZvciAoY29uc3QgYnJhbmNoIG9mIGJyYW5jaGVzKSB7XG5cdFx0XHRjb25zdCBhdHRlbXB0OiBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10gPSBbXTtcblx0XHRcdGNoZWNrKHZhbHVlLCBicmFuY2gsIHBhdGgsIGFsbG93VW5rbm93biwgYXR0ZW1wdCk7XG5cdFx0XHRpZiAoYXR0ZW1wdC5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aF0sIFwiYW55X29mXCIpKTtcblx0XHRyZXR1cm47XG5cdH1cblx0aWYgKFwiZW51bVwiIGluIHNjaGVtYSkge1xuXHRcdGNvbnN0IGNob2ljZXMgPSBzY2hlbWEuZW51bTtcblx0XHRpZiAoIUFycmF5LmlzQXJyYXkoY2hvaWNlcykpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihgJHt3aGVyZShwYXRoKX06IGVudW0gbXVzdCBiZSBhIGxpc3RgKTtcblx0XHR9XG5cdFx0aWYgKCFjaG9pY2VzLnNvbWUoKGNob2ljZSkgPT4gc2FtZUpzb24oY2hvaWNlLCB2YWx1ZSkpKSB7XG5cdFx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aF0sIFwiZW51bVwiKSk7XG5cdFx0fVxuXHRcdHJldHVybjtcblx0fVxuXHRjb25zdCBkZWNsYXJlZCA9IHNjaGVtYS50eXBlO1xuXHRpZiAoZGVjbGFyZWQgPT09IHVuZGVmaW5lZCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke3doZXJlKHBhdGgpfTogYSBzY2hlbWEgbmVlZHMgYSB0eXBlLCBhbnlPZiBvciBlbnVtYCxcblx0XHQpO1xuXHR9XG5cdGlmICh0eXBlb2YgZGVjbGFyZWQgIT09IFwic3RyaW5nXCIgfHwgIVBSSU1JVElWRVMuaGFzKGRlY2xhcmVkKSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke3doZXJlKHBhdGgpfTogdW5zdXBwb3J0ZWQgdHlwZSAke0pTT04uc3RyaW5naWZ5KGRlY2xhcmVkKX1gLFxuXHRcdCk7XG5cdH1cblx0c3dpdGNoIChkZWNsYXJlZCkge1xuXHRcdGNhc2UgXCJzdHJpbmdcIjpcblx0XHRcdGNoZWNrU3RyaW5nKHZhbHVlLCBzY2hlbWEsIHBhdGgsIGlzc3Vlcyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0Y2FzZSBcImJvb2xlYW5cIjpcblx0XHRcdGlmICh0eXBlb2YgdmFsdWUgIT09IFwiYm9vbGVhblwiKSB7XG5cdFx0XHRcdGlzc3Vlcy5wdXNoKG5ldyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlKFsuLi5wYXRoXSwgXCJ0eXBlXCIpKTtcblx0XHRcdH1cblx0XHRcdHJldHVybjtcblx0XHRjYXNlIFwiaW50ZWdlclwiOlxuXHRcdFx0aWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJudW1iZXJcIiB8fCAhTnVtYmVyLmlzSW50ZWdlcih2YWx1ZSkpIHtcblx0XHRcdFx0aXNzdWVzLnB1c2gobmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGhdLCBcInR5cGVcIikpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRjaGVja0JvdW5kcyh2YWx1ZSwgc2NoZW1hLCBwYXRoLCBpc3N1ZXMpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdGNhc2UgXCJudW1iZXJcIjpcblx0XHRcdGlmICh0eXBlb2YgdmFsdWUgIT09IFwibnVtYmVyXCIpIHtcblx0XHRcdFx0aXNzdWVzLnB1c2gobmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGhdLCBcInR5cGVcIikpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRpZiAoIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHtcblx0XHRcdFx0aXNzdWVzLnB1c2gobmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGhdLCBcIm5vdF9maW5pdGVcIikpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRjaGVja0JvdW5kcyh2YWx1ZSwgc2NoZW1hLCBwYXRoLCBpc3N1ZXMpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdGNhc2UgXCJudWxsXCI6XG5cdFx0XHRpZiAodmFsdWUgIT09IG51bGwpIHtcblx0XHRcdFx0aXNzdWVzLnB1c2gobmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGhdLCBcInR5cGVcIikpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuO1xuXHRcdGNhc2UgXCJhcnJheVwiOlxuXHRcdFx0Y2hlY2tBcnJheSh2YWx1ZSwgc2NoZW1hLCBwYXRoLCBhbGxvd1Vua25vd24sIGlzc3Vlcyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0ZGVmYXVsdDpcblx0XHRcdGNoZWNrT2JqZWN0KHZhbHVlLCBzY2hlbWEsIHBhdGgsIGFsbG93VW5rbm93biwgaXNzdWVzKTtcblx0fVxufVxuXG5mdW5jdGlvbiBjaGVja1N0cmluZyhcblx0dmFsdWU6IHVua25vd24sXG5cdHNjaGVtYTogRGVjbGFyZWRTY2hlbWEsXG5cdHBhdGg6IFBhdGgsXG5cdGlzc3VlczogUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdLFxuKTogdm9pZCB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIpIHtcblx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aF0sIFwidHlwZVwiKSk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGNvbnN0IHBhdHRlcm4gPSBzY2hlbWEucGF0dGVybjtcblx0aWYgKHBhdHRlcm4gPT09IHVuZGVmaW5lZCB8fCBwYXR0ZXJuID09PSBudWxsKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGlmICh0eXBlb2YgcGF0dGVybiAhPT0gXCJzdHJpbmdcIikge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke3doZXJlKHBhdGgpfTogcGF0dGVybiBtdXN0IGJlIGEgc3RyaW5nYCxcblx0XHQpO1xuXHR9XG5cdGxldCBleHByZXNzaW9uOiBSZWdFeHA7XG5cdHRyeSB7XG5cdFx0Ly8gUHl0aG9uJ3MgcmUuZnVsbG1hdGNoOiB0aGUgd2hvbGUgc3RyaW5nLCB3aXRoIHRoZSB1bmljb2RlIGZsYWcgdGhlXG5cdFx0Ly8gZGVjbGFyYXRpb24gc2lkZSBhbHJlYWR5IGFzc3VtZXMuXG5cdFx0ZXhwcmVzc2lvbiA9IG5ldyBSZWdFeHAoYF4oPzoke3BhdHRlcm59KSRgLCBcInVcIik7XG5cdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YCR7d2hlcmUocGF0aCl9OiBwYXR0ZXJuICR7SlNPTi5zdHJpbmdpZnkocGF0dGVybil9IGlzIHVudXNhYmxlOiAke1N0cmluZyhlcnJvcil9YCxcblx0XHQpO1xuXHR9XG5cdGlmICghZXhwcmVzc2lvbi50ZXN0KHZhbHVlKSkge1xuXHRcdGlzc3Vlcy5wdXNoKG5ldyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlKFsuLi5wYXRoXSwgXCJwYXR0ZXJuXCIpKTtcblx0fVxufVxuXG5mdW5jdGlvbiBjaGVja0JvdW5kcyhcblx0dmFsdWU6IG51bWJlcixcblx0c2NoZW1hOiBEZWNsYXJlZFNjaGVtYSxcblx0cGF0aDogUGF0aCxcblx0aXNzdWVzOiBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10sXG4pOiB2b2lkIHtcblx0Y29uc3QgbWluaW11bSA9IHNjaGVtYS5taW5pbXVtO1xuXHRpZiAodHlwZW9mIG1pbmltdW0gPT09IFwibnVtYmVyXCIgJiYgdmFsdWUgPCBtaW5pbXVtKSB7XG5cdFx0aXNzdWVzLnB1c2gobmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGhdLCBcIm1pbmltdW1cIikpO1xuXHR9XG5cdGNvbnN0IG1heGltdW0gPSBzY2hlbWEubWF4aW11bTtcblx0aWYgKHR5cGVvZiBtYXhpbXVtID09PSBcIm51bWJlclwiICYmIHZhbHVlID4gbWF4aW11bSkge1xuXHRcdGlzc3Vlcy5wdXNoKG5ldyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlKFsuLi5wYXRoXSwgXCJtYXhpbXVtXCIpKTtcblx0fVxufVxuXG5mdW5jdGlvbiBjaGVja0FycmF5KFxuXHR2YWx1ZTogdW5rbm93bixcblx0c2NoZW1hOiBEZWNsYXJlZFNjaGVtYSxcblx0cGF0aDogUGF0aCxcblx0YWxsb3dVbmtub3duOiBib29sZWFuLFxuXHRpc3N1ZXM6IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWVbXSxcbik6IHZvaWQge1xuXHRpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG5cdFx0aXNzdWVzLnB1c2gobmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGhdLCBcInR5cGVcIikpO1xuXHRcdHJldHVybjtcblx0fVxuXHRjb25zdCBpdGVtcyA9IHNjaGVtYS5pdGVtcztcblx0aWYgKGl0ZW1zID09PSB1bmRlZmluZWQgfHwgaXRlbXMgPT09IG51bGwpIHtcblx0XHRyZXR1cm47XG5cdH1cblx0dmFsdWUuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcblx0XHRjaGVjayhpdGVtLCBpdGVtcywgWy4uLnBhdGgsIGluZGV4XSwgYWxsb3dVbmtub3duLCBpc3N1ZXMpO1xuXHR9KTtcbn1cblxuZnVuY3Rpb24gY2hlY2tPYmplY3QoXG5cdHZhbHVlOiB1bmtub3duLFxuXHRzY2hlbWE6IERlY2xhcmVkU2NoZW1hLFxuXHRwYXRoOiBQYXRoLFxuXHRhbGxvd1Vua25vd246IGJvb2xlYW4sXG5cdGlzc3VlczogUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdLFxuKTogdm9pZCB7XG5cdGlmICghaXNQbGFpblJlY29yZCh2YWx1ZSkpIHtcblx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aF0sIFwidHlwZVwiKSk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGNvbnN0IHByb3BlcnRpZXMgPSBzY2hlbWEucHJvcGVydGllcyA/PyB7fTtcblx0aWYgKCFpc1BsYWluUmVjb3JkKHByb3BlcnRpZXMpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YCR7d2hlcmUocGF0aCl9OiBwcm9wZXJ0aWVzIG11c3QgYmUgYW4gb2JqZWN0YCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IHJlcXVpcmVkID0gc2NoZW1hLnJlcXVpcmVkID8/IFtdO1xuXHRpZiAoIUFycmF5LmlzQXJyYXkocmVxdWlyZWQpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YCR7d2hlcmUocGF0aCl9OiByZXF1aXJlZCBtdXN0IGJlIGEgbGlzdGAsXG5cdFx0KTtcblx0fVxuXHRmb3IgKGNvbnN0IGtleSBvZiByZXF1aXJlZCkge1xuXHRcdGlmICh0eXBlb2Yga2V5ID09PSBcInN0cmluZ1wiICYmICEoa2V5IGluIHZhbHVlKSkge1xuXHRcdFx0aXNzdWVzLnB1c2gobmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGgsIGtleV0sIFwicmVxdWlyZWRcIikpO1xuXHRcdH1cblx0fVxuXHRjb25zdCBzdHJpY3QgPSBzY2hlbWEuYWRkaXRpb25hbFByb3BlcnRpZXMgPT09IGZhbHNlICYmICFhbGxvd1Vua25vd247XG5cdGZvciAoY29uc3QgW2tleSwgaXRlbV0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG5cdFx0aWYgKE9iamVjdC5oYXNPd24ocHJvcGVydGllcywga2V5KSkge1xuXHRcdFx0Y2hlY2soaXRlbSwgcHJvcGVydGllc1trZXldLCBbLi4ucGF0aCwga2V5XSwgYWxsb3dVbmtub3duLCBpc3N1ZXMpO1xuXHRcdH0gZWxzZSBpZiAoc3RyaWN0KSB7XG5cdFx0XHRpc3N1ZXMucHVzaChcblx0XHRcdFx0bmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGgsIGtleV0sIFwidW5rbm93bl9wcm9wZXJ0eVwiKSxcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG59XG5cbi8qKiBKU09OIGVxdWFsaXR5OiBgdHJ1ZWAgaXMgbm90IGAxYCwgYW5kIGAxYCBpcyBgMS4wYC4gKi9cbmZ1bmN0aW9uIHNhbWVKc29uKGE6IHVua25vd24sIGI6IHVua25vd24pOiBib29sZWFuIHtcblx0aWYgKGEgPT09IGIpIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXHRpZiAodHlwZW9mIGEgIT09IHR5cGVvZiBiIHx8IGEgPT09IG51bGwgfHwgYiA9PT0gbnVsbCkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuXHRcdHJldHVybiAoXG5cdFx0XHRBcnJheS5pc0FycmF5KGIpICYmXG5cdFx0XHRhLmxlbmd0aCA9PT0gYi5sZW5ndGggJiZcblx0XHRcdGEuZXZlcnkoKGl0ZW0sIGluZGV4KSA9PiBzYW1lSnNvbihpdGVtLCBiW2luZGV4XSkpXG5cdFx0KTtcblx0fVxuXHRpZiAoaXNQbGFpblJlY29yZChhKSAmJiBpc1BsYWluUmVjb3JkKGIpKSB7XG5cdFx0Y29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGEpO1xuXHRcdHJldHVybiAoXG5cdFx0XHRrZXlzLmxlbmd0aCA9PT0gT2JqZWN0LmtleXMoYikubGVuZ3RoICYmXG5cdFx0XHRrZXlzLmV2ZXJ5KChrZXkpID0+IE9iamVjdC5oYXNPd24oYiwga2V5KSAmJiBzYW1lSnNvbihhW2tleV0sIGJba2V5XSkpXG5cdFx0KTtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHdoZXJlKHBhdGg6IFBhdGgpOiBzdHJpbmcge1xuXHRyZXR1cm4gcGF0aC5sZW5ndGggPT09IDAgPyBcInZhbHVlXCIgOiBwYXRoLmpvaW4oXCIuXCIpO1xufVxuIiwKICAgICIvKipcbiAqIFRoZSBmcmFtZXdvcmstZnJlZSBzdG9yZSBjb3JlIChkZWNpc2lvbi00NykuXG4gKlxuICogRXZlcnkgYWRhcHRlciAtIGAuL3JlYWN0YCwgYC4vdnVlYCwgYC4vc3ZlbHRlYCwgb3IgYSB2YW5pbGxhIHBhZ2Ugd2l0aCBub1xuICogYWRhcHRlciBhdCBhbGwgLSBkcml2ZXMgdGhlIHNhbWUgZm91ciBzdG9yZXMuIEEgc3RvcmUgaXMgYSB2YWx1ZSBwbHVzIHRoZVxuICogU3ZlbHRlIHN0b3JlIGNvbnRyYWN0OiBgc3Vic2NyaWJlKGxpc3RlbmVyKWAgY2FsbHMgdGhlIGxpc3RlbmVyIGF0IG9uY2Ugd2l0aFxuICogdGhlIGN1cnJlbnQgc25hcHNob3QgYW5kIGFnYWluIGFmdGVyIGV2ZXJ5IGNoYW5nZSwgYW5kIHJldHVybnMgdGhlXG4gKiB1bnN1YnNjcmliZSBmdW5jdGlvbjsgYGdldFNuYXBzaG90KClgIGlzIHRoZSBzYW1lIHZhbHVlIHdpdGhvdXQgYVxuICogc3Vic2NyaXB0aW9uLCBrZXB0IHJlZmVyZW50aWFsbHkgc3RhYmxlIGJldHdlZW4gY2hhbmdlcyBzbyBSZWFjdCdzXG4gKiBgdXNlU3luY0V4dGVybmFsU3RvcmVgIGNhbiBjb21wYXJlIGl0LiBOb3RoaW5nIGluIHRoaXMgbW9kdWxlIGltcG9ydHMgYVxuICogZnJhbWV3b3JrLCB0b3VjaGVzIHRoZSBET00gb3IgcnVucyBhdCBpbXBvcnQgdGltZS5cbiAqXG4gKiAtIHtAbGluayBPcGVyYXRpb25TdG9yZX0gcnVucyBvbmUgZ2VuZXJhdGVkIG9wZXJhdGlvbjogdGhlIGxhdGVzdCBydW4gd2lucyxcbiAqICAgYW4gYWJvcnRlZCBjYWxsIGlzIHN3YWxsb3dlZCwgYW5kIGBydW5gIG5ldmVyIHJlamVjdHMgaW50byBhIGhhbmRsZXIuXG4gKiAtIHtAbGluayBTdHJlYW1TdG9yZX0gaG9sZHMgb25lIGdlbmVyYXRlZCBzdHJlYW0gb3BlbiB3aGlsZSBpdHMgaW5wdXQgaXNcbiAqICAgbm9uLW51bGwsIHJlb3BlbmluZyBvbmx5IHdoZW4gdGhlIGlucHV0J3MgKmNvbnRlbnQqIGNoYW5nZXMuXG4gKiAtIHtAbGluayBGb3JtU3RvcmV9IGJpbmRzIHRoZSB2YWx1ZXMgb2Ygb25lIGRlY2xhcmVkIGFjdGlvbidzIHJlcXVlc3QgdG8gaXRzXG4gKiAgIHNjaGVtYTogZmllbGRzIGZyb20gdGhlIGRlY2xhcmF0aW9uLCBpc3N1ZXMgZnJvbSB0aGUgdmFsaWRhdG9yLCBzdWJtaXNzaW9uXG4gKiAgIHRocm91Z2ggYW4gb3BlcmF0aW9uIHN0b3JlLlxuICogLSB7QGxpbmsgSG9zdFF1ZXJ5U3RvcmV9IHJlYWRzIHRoZSBjdXJhdGVkIGhvc3Qgc3VyZmFjZSBhbmQgc2F5cyBgcmVmdXNlZGBcbiAqICAgLSBiZWZvcmUgYW55IGNhbGwgbGVhdmVzIHRoZSBwYWdlIC0gd2hlbiB0aGUgdmlldyB3YXMgbm90IGdyYW50ZWQgdGhlXG4gKiAgIG9wZXJhdGlvbiBpdCBuZWVkcy5cbiAqL1xuXG5pbXBvcnQgeyBRZ2lzU2RrQnJpZGdlQWJvcnRlZEVycm9yIH0gZnJvbSBcIi4vYnJpZGdlXCI7XG5pbXBvcnQgdHlwZSB7IEFjdGlvbkRlc2NyaXB0aW9uLCBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlIH0gZnJvbSBcIi4vZGVjbGFyYXRpb25zXCI7XG5pbXBvcnQgeyBRZ2lzU2RrRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB0eXBlIHtcblx0SG9zdE9wZXJhdGlvbklkLFxuXHRMYXllclBhZ2UsXG5cdFZlY3RvckxheWVySW5mbyxcbn0gZnJvbSBcIi4vZ2VuZXJhdGVkL2hvc3RcIjtcbmltcG9ydCB7IGlzUGxhaW5SZWNvcmQgfSBmcm9tIFwiLi9pbnRlcm5hbFwiO1xuaW1wb3J0IHR5cGUgeyBRZ2lzU2RrQ29yZSwgUWdpc1Nka0hvc3QgfSBmcm9tIFwiLi9xZ2lzLXNka1wiO1xuaW1wb3J0IHR5cGUgeyBPcGVyYXRpb25TaGFwZSB9IGZyb20gXCIuL3NjaGVtYVwiO1xuaW1wb3J0IHsgdHlwZSBEZWNsYXJlZFNjaGVtYSwgdmFsaWRhdGVBZ2FpbnN0U2NoZW1hIH0gZnJvbSBcIi4vdmFsaWRhdGVcIjtcblxuLyoqIEEgc3RvcmUgd2FzIGJ1aWx0IG9yIGRyaXZlbiBvdXRzaWRlIHRoZSBzaGFwZSBpdCBuZWVkcy4gKi9cbmV4cG9ydCBjbGFzcyBRZ2lzU2RrU3RvcmVFcnJvciBleHRlbmRzIFFnaXNTZGtFcnJvciB7XG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcblx0XHRzdXBlcihtZXNzYWdlLCBcInN0b3JlX2JpbmRpbmdcIik7XG5cdH1cbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUaGUgY29udHJhY3Rcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKiogV2hhdCBhIGxpc3RlbmVyIHJlY2VpdmVzOiB0aGUgd2hvbGUgc25hcHNob3QsIG5ldmVyIGEgZGlmZi4gKi9cbmV4cG9ydCB0eXBlIFN0b3JlTGlzdGVuZXI8VD4gPSAoc25hcHNob3Q6IFQpID0+IHZvaWQ7XG5cbi8qKlxuICogVGhlIGNvbnRyYWN0IGV2ZXJ5IHN0b3JlIGhvbm91cnMsIGFuZCB0aGUgb25lIGB1c2VTeW5jRXh0ZXJuYWxTdG9yZWAsXG4gKiBWdWUncyBgc2hhbGxvd1JlZmAgd2lyaW5nIGFuZCBTdmVsdGUncyBgJHN0b3JlYCBhbGwgcmVhZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdG9yZTxUPiB7XG5cdC8qKiBUaGUgY3VycmVudCB2YWx1ZTsgdGhlIHNhbWUgb2JqZWN0IHVudGlsIHRoZSBuZXh0IGNoYW5nZS4gQm91bmQuICovXG5cdHJlYWRvbmx5IGdldFNuYXBzaG90OiAoKSA9PiBUO1xuXHQvKipcblx0ICogQ2FsbCBgbGlzdGVuZXJgIG5vdyBhbmQgYWZ0ZXIgZXZlcnkgY2hhbmdlOyB0aGUgcmV0dXJuZWQgZnVuY3Rpb25cblx0ICogc3RvcHMgdGhlIGNhbGxzLiBCb3VuZC4gU3ZlbHRlIHBhc3NlcyBhIHNlY29uZCBgaW52YWxpZGF0ZWAgYXJndW1lbnQsXG5cdCAqIHdoaWNoIGlzIGlnbm9yZWQuXG5cdCAqL1xuXHRyZWFkb25seSBzdWJzY3JpYmU6IChsaXN0ZW5lcjogU3RvcmVMaXN0ZW5lcjxUPikgPT4gKCkgPT4gdm9pZDtcbn1cblxuYWJzdHJhY3QgY2xhc3MgQmFzZVN0b3JlPFQ+IGltcGxlbWVudHMgU3RvcmU8VD4ge1xuXHRwcml2YXRlIHNuYXBzaG90OiBUO1xuXHRwcml2YXRlIHJlYWRvbmx5IGxpc3RlbmVycyA9IG5ldyBTZXQ8U3RvcmVMaXN0ZW5lcjxUPj4oKTtcblxuXHRwcm90ZWN0ZWQgY29uc3RydWN0b3IoaW5pdGlhbDogVCkge1xuXHRcdHRoaXMuc25hcHNob3QgPSBpbml0aWFsO1xuXHR9XG5cblx0Ly8gQm91bmQsIHNvIGB1c2VTeW5jRXh0ZXJuYWxTdG9yZShzdG9yZS5zdWJzY3JpYmUsIHN0b3JlLmdldFNuYXBzaG90KWBcblx0Ly8gbmVlZHMgbm8gd3JhcHBlci5cblx0cHVibGljIHJlYWRvbmx5IGdldFNuYXBzaG90ID0gKCk6IFQgPT4gdGhpcy5zbmFwc2hvdDtcblxuXHRwdWJsaWMgcmVhZG9ubHkgc3Vic2NyaWJlID0gKGxpc3RlbmVyOiBTdG9yZUxpc3RlbmVyPFQ+KTogKCgpID0+IHZvaWQpID0+IHtcblx0XHR0aGlzLmxpc3RlbmVycy5hZGQobGlzdGVuZXIpO1xuXHRcdGxpc3RlbmVyKHRoaXMuc25hcHNob3QpO1xuXHRcdHJldHVybiAoKSA9PiB7XG5cdFx0XHR0aGlzLmxpc3RlbmVycy5kZWxldGUobGlzdGVuZXIpO1xuXHRcdH07XG5cdH07XG5cblx0cHJvdGVjdGVkIHB1Ymxpc2gobmV4dDogVCk6IHZvaWQge1xuXHRcdGlmIChPYmplY3QuaXMobmV4dCwgdGhpcy5zbmFwc2hvdCkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5zbmFwc2hvdCA9IG5leHQ7XG5cdFx0Zm9yIChjb25zdCBsaXN0ZW5lciBvZiBbLi4udGhpcy5saXN0ZW5lcnNdKSB7XG5cdFx0XHRsaXN0ZW5lcihuZXh0KTtcblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gYXNFcnJvcihlcnJvcjogdW5rbm93bik6IEVycm9yIHtcblx0cmV0dXJuIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBPcGVyYXRpb25TdG9yZVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBXaGVyZSBvbmUgaW52b2NhdGlvbiBzdGFuZHMuICovXG5leHBvcnQgdHlwZSBPcGVyYXRpb25TdGF0ZTxSPiA9XG5cdHwgeyByZWFkb25seSBzdGF0dXM6IFwiaWRsZVwiIH1cblx0fCB7IHJlYWRvbmx5IHN0YXR1czogXCJwZW5kaW5nXCIgfVxuXHR8IHsgcmVhZG9ubHkgc3RhdHVzOiBcIm9rXCI7IHJlYWRvbmx5IHZhbHVlOiBSIH1cblx0fCB7IHJlYWRvbmx5IHN0YXR1czogXCJlcnJvclwiOyByZWFkb25seSBlcnJvcjogRXJyb3IgfTtcblxuLyoqIEFuIG9wZXJhdGlvbiBtZW1iZXIgb2YgYSBnZW5lcmF0ZWQgbWFwOiBpbnB1dCwgb3B0aW9uYWwgc2lnbmFsLCBwcm9taXNlLiAqL1xuZXhwb3J0IHR5cGUgT3BlcmF0aW9uPEksIFI+ID0gKFxuXHRpbnB1dDogSSxcblx0b3B0aW9ucz86IHsgcmVhZG9ubHkgc2lnbmFsPzogQWJvcnRTaWduYWwgfSxcbikgPT4gUHJvbWlzZTxSPjtcblxuY29uc3QgSURMRTogT3BlcmF0aW9uU3RhdGU8bmV2ZXI+ID0gT2JqZWN0LmZyZWV6ZSh7IHN0YXR1czogXCJpZGxlXCIgfSk7XG5jb25zdCBQRU5ESU5HOiBPcGVyYXRpb25TdGF0ZTxuZXZlcj4gPSBPYmplY3QuZnJlZXplKHsgc3RhdHVzOiBcInBlbmRpbmdcIiB9KTtcblxuLyoqXG4gKiBSdW4gb25lIGdlbmVyYXRlZCBvcGVyYXRpb24uXG4gKlxuICogYHJ1bmAgcmVzb2x2ZXMgd2l0aCB0aGUgdmFsdWUsIG9yIHdpdGggYHVuZGVmaW5lZGAgd2hlbiB0aGUgY2FsbCBmYWlsZWQsXG4gKiB3YXMgYWJvcnRlZCBvciB3YXMgc3VwZXJzZWRlZCBieSBhIGxhdGVyIHJ1biAtIHRoZSBzdGF0ZSBjYXJyaWVzIHRoZSBlcnJvcixcbiAqIHNvIHRoZSBwcm9taXNlIG5ldmVyIHJlamVjdHMgaW50byBhbiBldmVudCBoYW5kbGVyLiBPbmx5IHRoZSBsYXRlc3QgcnVuIGNhblxuICogY2hhbmdlIHRoZSBzdGF0ZS4gYGFib3J0YCBlbmRzIHRoZSBpbi1mbGlnaHQgY2FsbCBsb2NhbGx5ICh0aGUgaG9zdCBtYXlcbiAqIHN0aWxsIHJ1biBpdCk7IGByZXNldGAgYWJvcnRzIGFuZCByZXR1cm5zIHRvIGBpZGxlYC4gVGhlIG1ldGhvZHMgYXJlIGJvdW5kLFxuICogc28gdGhleSBjYW4gYmUgcGFzc2VkIGFyb3VuZCB3aXRob3V0IHRoZSBzdG9yZS5cbiAqL1xuZXhwb3J0IGNsYXNzIE9wZXJhdGlvblN0b3JlPEksIFI+IGV4dGVuZHMgQmFzZVN0b3JlPE9wZXJhdGlvblN0YXRlPFI+PiB7XG5cdHByaXZhdGUgZ2VuZXJhdGlvbiA9IDA7XG5cdHByaXZhdGUgY29udHJvbGxlcjogQWJvcnRDb250cm9sbGVyIHwgbnVsbCA9IG51bGw7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgb3BlcmF0aW9uOiBPcGVyYXRpb248SSwgUj4pIHtcblx0XHRzdXBlcihJRExFKTtcblx0fVxuXG5cdHB1YmxpYyByZWFkb25seSBhYm9ydCA9ICgpOiB2b2lkID0+IHtcblx0XHR0aGlzLmdlbmVyYXRpb24gKz0gMTtcblx0XHR0aGlzLmNvbnRyb2xsZXI/LmFib3J0KCk7XG5cdFx0dGhpcy5jb250cm9sbGVyID0gbnVsbDtcblx0fTtcblxuXHRwdWJsaWMgcmVhZG9ubHkgcmVzZXQgPSAoKTogdm9pZCA9PiB7XG5cdFx0dGhpcy5hYm9ydCgpO1xuXHRcdHRoaXMucHVibGlzaChJRExFKTtcblx0fTtcblxuXHRwdWJsaWMgcmVhZG9ubHkgcnVuID0gYXN5bmMgKGlucHV0OiBJKTogUHJvbWlzZTxSIHwgdW5kZWZpbmVkPiA9PiB7XG5cdFx0dGhpcy5hYm9ydCgpO1xuXHRcdGNvbnN0IG1pbmUgPSB0aGlzLmdlbmVyYXRpb247XG5cdFx0Y29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblx0XHR0aGlzLmNvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuXHRcdHRoaXMucHVibGlzaChQRU5ESU5HKTtcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgdmFsdWUgPSBhd2FpdCB0aGlzLm9wZXJhdGlvbihpbnB1dCwgeyBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsIH0pO1xuXHRcdFx0aWYgKHRoaXMuZ2VuZXJhdGlvbiAhPT0gbWluZSkge1xuXHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5wdWJsaXNoKHsgc3RhdHVzOiBcIm9rXCIsIHZhbHVlIH0pO1xuXHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdHRoaXMuZ2VuZXJhdGlvbiAhPT0gbWluZSB8fFxuXHRcdFx0XHRlcnJvciBpbnN0YW5jZW9mIFFnaXNTZGtCcmlkZ2VBYm9ydGVkRXJyb3Jcblx0XHRcdCkge1xuXHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5wdWJsaXNoKHsgc3RhdHVzOiBcImVycm9yXCIsIGVycm9yOiBhc0Vycm9yKGVycm9yKSB9KTtcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fSBmaW5hbGx5IHtcblx0XHRcdGlmICh0aGlzLmNvbnRyb2xsZXIgPT09IGNvbnRyb2xsZXIpIHtcblx0XHRcdFx0dGhpcy5jb250cm9sbGVyID0gbnVsbDtcblx0XHRcdH1cblx0XHR9XG5cdH07XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU3RyZWFtU3RvcmVcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKiogSG93IGEgc3RyZWFtIGVuZGVkLCBhcyB0aGUgZ2VuZXJhdGVkIG1vZHVsZSByZXBvcnRzIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJlYW1UZXJtaW5hbExpa2Uge1xuXHRyZWFkb25seSBraW5kOiBzdHJpbmc7XG5cdHJlYWRvbmx5IG1lc3NhZ2U/OiBzdHJpbmc7XG5cdHJlYWRvbmx5IGRyb3BwZWQ/OiBudW1iZXI7XG59XG5cbi8qKiBUaGUgaGFuZGxlIGEgZ2VuZXJhdGVkIHN0cmVhbSBtZW1iZXIgcmVzb2x2ZXMgd2l0aC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtSGFuZGxlTGlrZSB7XG5cdHJlYWRvbmx5IGlkOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGNsb3NlZDogYm9vbGVhbjtcblx0Y2xvc2UoKTogdm9pZDtcbn1cblxuLyoqIEhhbmRsZXJzIGZvciBhIHN0cmVhbSwgYXMgYSBnZW5lcmF0ZWQgbW9kdWxlIHR5cGVzIHRoZW0uICovXG5leHBvcnQgaW50ZXJmYWNlIFN0cmVhbUhhbmRsZXJzTGlrZTxFPiB7XG5cdHJlYWRvbmx5IG9uRXZlbnQ/OiAoZXZlbnQ6IEUpID0+IHZvaWQ7XG5cdHJlYWRvbmx5IG9uVGVybWluYWw/OiAodGVybWluYWw6IFN0cmVhbVRlcm1pbmFsTGlrZSkgPT4gdm9pZDtcbn1cblxuLyoqIEEgc3RyZWFtIG1lbWJlciBvZiBhIGdlbmVyYXRlZCBtYXAuICovXG5leHBvcnQgdHlwZSBTdHJlYW08SSwgRT4gPSAoXG5cdGlucHV0OiBJLFxuXHRoYW5kbGVyczogU3RyZWFtSGFuZGxlcnNMaWtlPEU+LFxuXHRvcHRpb25zPzogeyByZWFkb25seSBzaWduYWw/OiBBYm9ydFNpZ25hbCB9LFxuKSA9PiBQcm9taXNlPFN0cmVhbUhhbmRsZUxpa2U+O1xuXG4vKiogV2hlcmUgb25lIHN1YnNjcmlwdGlvbiBzdGFuZHMuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0cmVhbVN0YXRlPEU+IHtcblx0LyoqIGBpZGxlYCB3aXRoIGEgbnVsbCBpbnB1dCwgYGZhaWxlZGAgd2hlbiB0aGUgaG9zdCByZWZ1c2VkIHRvIG9wZW4gaXQuICovXG5cdHJlYWRvbmx5IHN0YXR1czogXCJpZGxlXCIgfCBcIm9wZW5pbmdcIiB8IFwib3BlblwiIHwgXCJlbmRlZFwiIHwgXCJmYWlsZWRcIjtcblx0cmVhZG9ubHkgbGFzdEV2ZW50OiBFIHwgbnVsbDtcblx0cmVhZG9ubHkgdGVybWluYWw6IFN0cmVhbVRlcm1pbmFsTGlrZSB8IG51bGw7XG5cdHJlYWRvbmx5IGVycm9yOiBFcnJvciB8IG51bGw7XG59XG5cbmNvbnN0IElETEVfU1RSRUFNOiBTdHJlYW1TdGF0ZTxuZXZlcj4gPSBPYmplY3QuZnJlZXplKHtcblx0c3RhdHVzOiBcImlkbGVcIixcblx0bGFzdEV2ZW50OiBudWxsLFxuXHR0ZXJtaW5hbDogbnVsbCxcblx0ZXJyb3I6IG51bGwsXG59KTtcblxuLyoqXG4gKiBSZXR1cm4gYSBrZXkgdGhhdCBpcyBlcXVhbCBmb3IgdHdvIGlucHV0cyB3aXRoIHRoZSBzYW1lIGNvbnRlbnQsIHdoYXRldmVyXG4gKiB0aGUgb3JkZXIgdGhlaXIgZmllbGRzIHdlcmUgd3JpdHRlbiBpbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YWJsZUtleSh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XG5cdHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgKF9rZXksIGl0ZW06IHVua25vd24pID0+XG5cdFx0aXNQbGFpblJlY29yZChpdGVtKVxuXHRcdFx0PyBPYmplY3QuZnJvbUVudHJpZXMoXG5cdFx0XHRcdFx0T2JqZWN0LmVudHJpZXMoaXRlbSkuc29ydCgoW2FdLCBbYl0pID0+IChhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogMCkpLFxuXHRcdFx0XHQpXG5cdFx0XHQ6IGl0ZW0sXG5cdCk7XG59XG5cbi8qKlxuICogSG9sZCBvbmUgZ2VuZXJhdGVkIHN0cmVhbSBvcGVuIHdoaWxlIGl0cyBpbnB1dCBpcyBub24tbnVsbC5cbiAqXG4gKiBgc2V0SW5wdXRgIGZvbGxvd3MgdGhlICpjb250ZW50KiBvZiB0aGUgaW5wdXQ6IGEgbmV3IG9iamVjdCB3aXRoIHRoZSBzYW1lXG4gKiBmaWVsZHMgY2hhbmdlcyBub3RoaW5nLCBhIGRpZmZlcmVudCBvbmUgY2xvc2VzIHRoZSBvbGQgc3RyZWFtIGFuZCBvcGVucyBhXG4gKiBuZXcgb25lLCBgbnVsbGAgY2xvc2VzIGl0LiBIYW5kbGVycyBhcmUgcmVhZCBmcmVzaCBvbiBldmVyeSBmcmFtZSwgc29cbiAqIGBzZXRIYW5kbGVyc2Agd2l0aCBhIG5ldyBjbG9zdXJlIHJlb3BlbnMgbm90aGluZy4gYGNsb3NlYCBpcyBzYWZlIGJlZm9yZSB0aGVcbiAqIGhvc3QgaGFzIGFja25vd2xlZGdlZCB0aGUgc3RyZWFtOiB0aGUgaGFuZGxlIGlzIGNsb3NlZCB0aGUgbW9tZW50IGl0XG4gKiBhcnJpdmVzLlxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtU3RvcmU8SSwgRT4gZXh0ZW5kcyBCYXNlU3RvcmU8U3RyZWFtU3RhdGU8RT4+IHtcblx0cHJpdmF0ZSBrZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXHRwcml2YXRlIGNhbmNlbDogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKFxuXHRcdHByaXZhdGUgcmVhZG9ubHkgb3BlbjogU3RyZWFtPEksIEU+LFxuXHRcdHByaXZhdGUgaGFuZGxlcnM6IFN0cmVhbUhhbmRsZXJzTGlrZTxFPiA9IHt9LFxuXHQpIHtcblx0XHRzdXBlcihJRExFX1NUUkVBTSk7XG5cdH1cblxuXHQvKiogUmVwbGFjZSB0aGUgaGFuZGxlcnMgdGhlIG5leHQgZnJhbWVzIHJlYWNoOyBub3RoaW5nIHJlb3BlbnMuICovXG5cdHB1YmxpYyBzZXRIYW5kbGVycyhoYW5kbGVyczogU3RyZWFtSGFuZGxlcnNMaWtlPEU+KTogdm9pZCB7XG5cdFx0dGhpcy5oYW5kbGVycyA9IGhhbmRsZXJzO1xuXHR9XG5cblx0cHVibGljIHJlYWRvbmx5IHNldElucHV0ID0gKGlucHV0OiBJIHwgbnVsbCk6IHZvaWQgPT4ge1xuXHRcdGNvbnN0IGtleSA9IGlucHV0ID09PSBudWxsID8gbnVsbCA6IHN0YWJsZUtleShpbnB1dCk7XG5cdFx0aWYgKGtleSA9PT0gdGhpcy5rZXkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5jYW5jZWw/LigpO1xuXHRcdHRoaXMuY2FuY2VsID0gbnVsbDtcblx0XHR0aGlzLmtleSA9IGtleTtcblx0XHRpZiAoaW5wdXQgPT09IG51bGwgfHwga2V5ID09PSBudWxsKSB7XG5cdFx0XHR0aGlzLnB1Ymxpc2goSURMRV9TVFJFQU0pO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR0aGlzLmNhbmNlbCA9IHRoaXMuc3RhcnQoaW5wdXQpO1xuXHR9O1xuXG5cdHB1YmxpYyByZWFkb25seSBjbG9zZSA9ICgpOiB2b2lkID0+IHtcblx0XHR0aGlzLnNldElucHV0KG51bGwpO1xuXHR9O1xuXG5cdHByaXZhdGUgc3RhcnQoaW5wdXQ6IEkpOiAoKSA9PiB2b2lkIHtcblx0XHRsZXQgY2FuY2VsbGVkID0gZmFsc2U7XG5cdFx0bGV0IGhhbmRsZTogU3RyZWFtSGFuZGxlTGlrZSB8IG51bGwgPSBudWxsO1xuXHRcdGNvbnN0IHVwZGF0ZSA9IChjaGFuZ2U6IChwcmV2aW91czogU3RyZWFtU3RhdGU8RT4pID0+IFN0cmVhbVN0YXRlPEU+KSA9PiB7XG5cdFx0XHRpZiAoIWNhbmNlbGxlZCkge1xuXHRcdFx0XHR0aGlzLnB1Ymxpc2goY2hhbmdlKHRoaXMuZ2V0U25hcHNob3QoKSkpO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0dGhpcy5wdWJsaXNoKHtcblx0XHRcdHN0YXR1czogXCJvcGVuaW5nXCIsXG5cdFx0XHRsYXN0RXZlbnQ6IG51bGwsXG5cdFx0XHR0ZXJtaW5hbDogbnVsbCxcblx0XHRcdGVycm9yOiBudWxsLFxuXHRcdH0pO1xuXHRcdHRoaXMub3BlbihpbnB1dCwge1xuXHRcdFx0b25FdmVudDogKGV2ZW50KSA9PiB7XG5cdFx0XHRcdGlmIChjYW5jZWxsZWQpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5oYW5kbGVycy5vbkV2ZW50Py4oZXZlbnQpO1xuXHRcdFx0XHR1cGRhdGUoKHByZXZpb3VzKSA9PiAoeyAuLi5wcmV2aW91cywgbGFzdEV2ZW50OiBldmVudCB9KSk7XG5cdFx0XHR9LFxuXHRcdFx0b25UZXJtaW5hbDogKHRlcm1pbmFsKSA9PiB7XG5cdFx0XHRcdGlmIChjYW5jZWxsZWQpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5oYW5kbGVycy5vblRlcm1pbmFsPy4odGVybWluYWwpO1xuXHRcdFx0XHR1cGRhdGUoKHByZXZpb3VzKSA9PiAoeyAuLi5wcmV2aW91cywgc3RhdHVzOiBcImVuZGVkXCIsIHRlcm1pbmFsIH0pKTtcblx0XHRcdH0sXG5cdFx0fSkudGhlbihcblx0XHRcdChvcGVuZWQpID0+IHtcblx0XHRcdFx0aWYgKGNhbmNlbGxlZCkge1xuXHRcdFx0XHRcdG9wZW5lZC5jbG9zZSgpO1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0XHRoYW5kbGUgPSBvcGVuZWQ7XG5cdFx0XHRcdHVwZGF0ZSgocHJldmlvdXMpID0+XG5cdFx0XHRcdFx0cHJldmlvdXMuc3RhdHVzID09PSBcImVuZGVkXCJcblx0XHRcdFx0XHRcdD8gcHJldmlvdXNcblx0XHRcdFx0XHRcdDogeyAuLi5wcmV2aW91cywgc3RhdHVzOiBcIm9wZW5cIiB9LFxuXHRcdFx0XHQpO1xuXHRcdFx0fSxcblx0XHRcdChlcnJvcjogdW5rbm93bikgPT4ge1xuXHRcdFx0XHR1cGRhdGUoKCkgPT4gKHtcblx0XHRcdFx0XHRzdGF0dXM6IFwiZmFpbGVkXCIsXG5cdFx0XHRcdFx0bGFzdEV2ZW50OiBudWxsLFxuXHRcdFx0XHRcdHRlcm1pbmFsOiBudWxsLFxuXHRcdFx0XHRcdGVycm9yOiBhc0Vycm9yKGVycm9yKSxcblx0XHRcdFx0fSkpO1xuXHRcdFx0fSxcblx0XHQpO1xuXHRcdHJldHVybiAoKSA9PiB7XG5cdFx0XHRjYW5jZWxsZWQgPSB0cnVlO1xuXHRcdFx0aGFuZGxlPy5jbG9zZSgpO1xuXHRcdH07XG5cdH1cbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBGb3JtU3RvcmVcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKipcbiAqIFRoZSBpbnB1dCBmYW1pbGllcyBhIGRlY2xhcmVkIHJlcXVlc3QgY2FuIGFzayBmb3I6IHRoZSBzYW1lIG5hbWVzIHRoZVxuICogUHl0aG9uIGBxZ2lzX3Nkay51aWAgY2F0YWxvZ3VlIGRyYXdzLCBzbyBhIGZvcm0gb24gZWl0aGVyIHNpZGUgb2YgdGhlXG4gKiBicmlkZ2UgcmVuZGVycyBvbmUgZGVjbGFyYXRpb24gdGhlIHNhbWUgd2F5LlxuICovXG5leHBvcnQgdHlwZSBGb3JtRmllbGRLaW5kID1cblx0fCBcInRleHRcIlxuXHR8IFwiaW50ZWdlclwiXG5cdHwgXCJudW1iZXJcIlxuXHR8IFwiYm9vbGVhblwiXG5cdHwgXCJjaG9pY2VcIlxuXHR8IFwibGF5ZXJcIlxuXHR8IFwiY3JzXCJcblx0fCBcIm1ldHJlc1wiXG5cdHwgXCJmaWxlXCJcblx0fCBcImRpcmVjdG9yeVwiXG5cdHwgXCJmaWVsZFwiXG5cdHwgXCJyYW5nZVwiXG5cdHwgXCJjb2xvdXJcIjtcblxuY29uc3QgRklFTERfS0lORFM6IFJlYWRvbmx5U2V0PHN0cmluZz4gPSBuZXcgU2V0PEZvcm1GaWVsZEtpbmQ+KFtcblx0XCJ0ZXh0XCIsXG5cdFwiaW50ZWdlclwiLFxuXHRcIm51bWJlclwiLFxuXHRcImJvb2xlYW5cIixcblx0XCJjaG9pY2VcIixcblx0XCJsYXllclwiLFxuXHRcImNyc1wiLFxuXHRcIm1ldHJlc1wiLFxuXHRcImZpbGVcIixcblx0XCJkaXJlY3RvcnlcIixcblx0XCJmaWVsZFwiLFxuXHRcInJhbmdlXCIsXG5cdFwiY29sb3VyXCIsXG5dKTtcbmNvbnN0IFBSSU1JVElWRV9LSU5EUzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgRm9ybUZpZWxkS2luZD4+ID0ge1xuXHRzdHJpbmc6IFwidGV4dFwiLFxuXHRpbnRlZ2VyOiBcImludGVnZXJcIixcblx0bnVtYmVyOiBcIm51bWJlclwiLFxuXHRib29sZWFuOiBcImJvb2xlYW5cIixcbn07XG5jb25zdCBOVU1FUklDX0tJTkRTOiBSZWFkb25seVNldDxGb3JtRmllbGRLaW5kPiA9IG5ldyBTZXQ8Rm9ybUZpZWxkS2luZD4oW1xuXHRcImludGVnZXJcIixcblx0XCJudW1iZXJcIixcblx0XCJtZXRyZXNcIixcblx0XCJyYW5nZVwiLFxuXSk7XG5jb25zdCBERVRBSUxfS0VZUyA9IFtcIm1pbmltdW1cIiwgXCJtYXhpbXVtXCIsIFwic3RlcFwiLCBcIm9mXCIsIFwiZmlsdGVyc1wiLCBcImFscGhhXCJdO1xuXG4vKiogT25lIGlucHV0IG9mIGEgZGVjbGFyZWQgYWN0aW9uLCBhcyBhIHBhZ2Ugc2hvdWxkIHJlbmRlciBpdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRm9ybUZpZWxkIHtcblx0cmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXHQvKiogYGJ1ZmZlcl9kaXN0YW5jZWAgLT4gYEJ1ZmZlciBkaXN0YW5jZWAuICovXG5cdHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGtpbmQ6IEZvcm1GaWVsZEtpbmQ7XG5cdHJlYWRvbmx5IHJlcXVpcmVkOiBib29sZWFuO1xuXHRyZWFkb25seSBudWxsYWJsZTogYm9vbGVhbjtcblx0LyoqIFRoZSBgZW51bWAgb2YgYSBgY2hvaWNlYCBmaWVsZDsgZW1wdHkgb3RoZXJ3aXNlLiAqL1xuXHRyZWFkb25seSBjaG9pY2VzOiByZWFkb25seSB1bmtub3duW107XG5cdC8qKiBCb3VuZHMsIGEgcGFyZW50IGlucHV0LCBwaWNrZXIgZmlsdGVyczogd2hhdCB0aGUga2luZCBuZWVkcyBiZXlvbmQgYSBuYW1lLiAqL1xuXHRyZWFkb25seSBkZXRhaWxzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG5cdC8qKiBUaGUgcHJvcGVydHkgc2NoZW1hIHRoZSB2YWx1ZSBpcyB2YWxpZGF0ZWQgYWdhaW5zdC4gKi9cblx0cmVhZG9ubHkgc2NoZW1hOiBEZWNsYXJlZFNjaGVtYTtcbn1cblxuLyoqIFJlbmRlciBhIGZpZWxkIG5hbWUgYXMgYSBsYWJlbC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYWJlbEZvcihuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRjb25zdCBzcGFjZWQgPSBuYW1lLnJlcGxhY2UoL18vZywgXCIgXCIpLnRyaW0oKTtcblx0cmV0dXJuIHNwYWNlZC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHNwYWNlZC5zbGljZSgxKS50b0xvd2VyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBjb25jcmV0ZShzY2hlbWE6IERlY2xhcmVkU2NoZW1hKTogW0RlY2xhcmVkU2NoZW1hLCBib29sZWFuXSB7XG5cdGNvbnN0IGJyYW5jaGVzID0gc2NoZW1hLmFueU9mO1xuXHRpZiAoIUFycmF5LmlzQXJyYXkoYnJhbmNoZXMpKSB7XG5cdFx0cmV0dXJuIFtzY2hlbWEsIGZhbHNlXTtcblx0fVxuXHRjb25zdCBub25OdWxsID0gYnJhbmNoZXMuZmlsdGVyKFxuXHRcdChicmFuY2gpOiBicmFuY2ggaXMgRGVjbGFyZWRTY2hlbWEgPT5cblx0XHRcdGlzUGxhaW5SZWNvcmQoYnJhbmNoKSAmJiBicmFuY2gudHlwZSAhPT0gXCJudWxsXCIsXG5cdCk7XG5cdGlmIChub25OdWxsLmxlbmd0aCA9PT0gMSAmJiBub25OdWxsLmxlbmd0aCAhPT0gYnJhbmNoZXMubGVuZ3RoKSB7XG5cdFx0cmV0dXJuIFtub25OdWxsWzBdIGFzIERlY2xhcmVkU2NoZW1hLCB0cnVlXTtcblx0fVxuXHR0aHJvdyBuZXcgUWdpc1Nka1N0b3JlRXJyb3IoXG5cdFx0XCJhIHVuaW9uIGZpZWxkIG11c3QgYmUgb25lIHR5cGUgb3IgdGhhdCB0eXBlIHBsdXMgbnVsbCB0byBiZSByZW5kZXJlZFwiLFxuXHQpO1xufVxuXG5mdW5jdGlvbiBraW5kRm9yKFxuXHRvd25lcjogc3RyaW5nLFxuXHRuYW1lOiBzdHJpbmcsXG5cdHNjaGVtYTogRGVjbGFyZWRTY2hlbWEsXG4pOiBGb3JtRmllbGRLaW5kIHtcblx0Y29uc3QgaW50ZW50ID0gc2NoZW1hW1wieC1xZ2lzLXNka1wiXTtcblx0Y29uc3QgbWFya2VkID0gaXNQbGFpblJlY29yZChpbnRlbnQpID8gaW50ZW50LmtpbmQgOiB1bmRlZmluZWQ7XG5cdGlmICh0eXBlb2YgbWFya2VkID09PSBcInN0cmluZ1wiKSB7XG5cdFx0aWYgKCFGSUVMRF9LSU5EUy5oYXMobWFya2VkKSkge1xuXHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtTdG9yZUVycm9yKFxuXHRcdFx0XHRgJHtvd25lcn06IGZpZWxkICR7bmFtZX0gaGFzIHVua25vd24ga2luZCAke0pTT04uc3RyaW5naWZ5KG1hcmtlZCl9YCxcblx0XHRcdCk7XG5cdFx0fVxuXHRcdHJldHVybiBtYXJrZWQgYXMgRm9ybUZpZWxkS2luZDtcblx0fVxuXHRpZiAoXCJlbnVtXCIgaW4gc2NoZW1hKSB7XG5cdFx0cmV0dXJuIFwiY2hvaWNlXCI7XG5cdH1cblx0Y29uc3Qga2luZCA9IFBSSU1JVElWRV9LSU5EU1tTdHJpbmcoc2NoZW1hLnR5cGUpXTtcblx0aWYgKGtpbmQgPT09IHVuZGVmaW5lZCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrU3RvcmVFcnJvcihcblx0XHRcdGAke293bmVyfTogZmllbGQgJHtuYW1lfSBoYXMgbm8gaW5wdXQgZm9yIGl0cyBzY2hlbWE7IGRlY2xhcmUgYSBwcmltaXRpdmUsIGFuIGVudW0gb3IgYSBraW5kYCxcblx0XHQpO1xuXHR9XG5cdHJldHVybiBraW5kO1xufVxuXG4vKipcbiAqIFRoZSBmaWVsZHMgb2YgYSBkZWNsYXJlZCByZXF1ZXN0IHNjaGVtYSwgaW4gZGVjbGFyYXRpb24gb3JkZXI6IHRoZVxuICogVHlwZVNjcmlwdCB0d2luIG9mIGBxZ2lzX3Nkay51aS5zY2hlbWFfZmllbGRzYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjaGVtYUZpZWxkcyhcblx0c2NoZW1hOiBEZWNsYXJlZFNjaGVtYSxcblx0b3duZXIgPSBcImZvcm1cIixcbik6IHJlYWRvbmx5IEZvcm1GaWVsZFtdIHtcblx0Y29uc3QgcHJvcGVydGllcyA9IHNjaGVtYS5wcm9wZXJ0aWVzO1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQocHJvcGVydGllcykpIHtcblx0XHRyZXR1cm4gT2JqZWN0LmZyZWV6ZShbXSk7XG5cdH1cblx0Y29uc3QgcmVxdWlyZWQgPSBuZXcgU2V0KFxuXHRcdEFycmF5LmlzQXJyYXkoc2NoZW1hLnJlcXVpcmVkKSA/IChzY2hlbWEucmVxdWlyZWQgYXMgc3RyaW5nW10pIDogW10sXG5cdCk7XG5cdHJldHVybiBPYmplY3QuZnJlZXplKFxuXHRcdE9iamVjdC5lbnRyaWVzKHByb3BlcnRpZXMpLm1hcCgoW25hbWUsIHByb3BlcnR5XSkgPT4ge1xuXHRcdFx0aWYgKCFpc1BsYWluUmVjb3JkKHByb3BlcnR5KSkge1xuXHRcdFx0XHR0aHJvdyBuZXcgUWdpc1Nka1N0b3JlRXJyb3IoYCR7b3duZXJ9OiBmaWVsZCAke25hbWV9IGlzIG5vdCBhIHNjaGVtYWApO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgW3NoYXBlLCBudWxsYWJsZV0gPSBjb25jcmV0ZShwcm9wZXJ0eSk7XG5cdFx0XHRjb25zdCBraW5kID0ga2luZEZvcihvd25lciwgbmFtZSwgc2hhcGUpO1xuXHRcdFx0Y29uc3QgaW50ZW50ID0gaXNQbGFpblJlY29yZChzaGFwZVtcIngtcWdpcy1zZGtcIl0pXG5cdFx0XHRcdD8gc2hhcGVbXCJ4LXFnaXMtc2RrXCJdXG5cdFx0XHRcdDoge307XG5cdFx0XHRjb25zdCBtZXJnZWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0geyAuLi5zaGFwZSwgLi4uaW50ZW50IH07XG5cdFx0XHRjb25zdCBkZXRhaWxzID1cblx0XHRcdFx0a2luZCA9PT0gXCJpbnRlZ2VyXCJcblx0XHRcdFx0XHQ/IHt9XG5cdFx0XHRcdFx0OiBPYmplY3QuZnJvbUVudHJpZXMoXG5cdFx0XHRcdFx0XHRcdERFVEFJTF9LRVlTLmZpbHRlcigoa2V5KSA9PiBrZXkgaW4gbWVyZ2VkKS5tYXAoKGtleSkgPT4gW1xuXHRcdFx0XHRcdFx0XHRcdGtleSxcblx0XHRcdFx0XHRcdFx0XHRtZXJnZWRba2V5XSxcblx0XHRcdFx0XHRcdFx0XSksXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0cmV0dXJuIE9iamVjdC5mcmVlemUoe1xuXHRcdFx0XHRuYW1lLFxuXHRcdFx0XHRsYWJlbDogbGFiZWxGb3IobmFtZSksXG5cdFx0XHRcdGtpbmQsXG5cdFx0XHRcdHJlcXVpcmVkOiByZXF1aXJlZC5oYXMobmFtZSkgJiYgIW51bGxhYmxlLFxuXHRcdFx0XHRudWxsYWJsZSxcblx0XHRcdFx0Y2hvaWNlczogT2JqZWN0LmZyZWV6ZShcblx0XHRcdFx0XHRraW5kID09PSBcImNob2ljZVwiICYmIEFycmF5LmlzQXJyYXkoc2hhcGUuZW51bSkgPyBbLi4uc2hhcGUuZW51bV0gOiBbXSxcblx0XHRcdFx0KSxcblx0XHRcdFx0ZGV0YWlsczogT2JqZWN0LmZyZWV6ZShkZXRhaWxzKSxcblx0XHRcdFx0c2NoZW1hOiBwcm9wZXJ0eSxcblx0XHRcdH0pO1xuXHRcdH0pLFxuXHQpO1xufVxuXG4vKiogVGhlIHZhbHVlcyBhIGZvcm0gaG9sZHM6IG9uZSBlbnRyeSBwZXIgZmllbGQgdGhlIHVzZXIgb3IgdGhlIHNjaGVtYSBzZXQuICovXG5leHBvcnQgdHlwZSBGb3JtVmFsdWVzID0gUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuXG4vKiogV2hlcmUgb25lIGZvcm0gc3RhbmRzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBGb3JtU3RhdGU8Uj4ge1xuXHRyZWFkb25seSB2YWx1ZXM6IEZvcm1WYWx1ZXM7XG5cdC8qKiBFdmVyeSBpc3N1ZSB0aGUgY3VycmVudCB2YWx1ZXMgaGF2ZSBhZ2FpbnN0IHRoZSByZXF1ZXN0IHNjaGVtYS4gKi9cblx0cmVhZG9ubHkgaXNzdWVzOiByZWFkb25seSBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW107XG5cdC8qKiBUaGUgZmlyc3QgaXNzdWUgY29kZSBwZXIgZmllbGQgbmFtZSwgZm9yIGEgbGFiZWwgdG8gc2hvdy4gKi9cblx0cmVhZG9ubHkgZXJyb3JzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+Pjtcblx0cmVhZG9ubHkgdmFsaWQ6IGJvb2xlYW47XG5cdC8qKiBBIHZhbHVlIGNoYW5nZWQgc2luY2UgY29uc3RydWN0aW9uIG9yIHRoZSBsYXN0IGByZXNldGAuICovXG5cdHJlYWRvbmx5IGRpcnR5OiBib29sZWFuO1xuXHQvKiogYHN1Ym1pdGAgd2FzIGF0dGVtcHRlZCBzaW5jZSBjb25zdHJ1Y3Rpb24gb3IgdGhlIGxhc3QgYHJlc2V0YC4gKi9cblx0cmVhZG9ubHkgc3VibWl0dGVkOiBib29sZWFuO1xuXHQvKiogVGhlIGxhdGVzdCBzdWJtaXNzaW9uLCBhcyBhbiBvcGVyYXRpb24gc3RvcmUgcmVwb3J0cyBpdC4gKi9cblx0cmVhZG9ubHkgc3VibWlzc2lvbjogT3BlcmF0aW9uU3RhdGU8Uj47XG59XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgRm9ybVN0b3JlfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRm9ybU9wdGlvbnMge1xuXHQvKiogVmFsdWVzIHRvIHN0YXJ0IGZyb207IHRoZSBkZWNsYXJlZCBkaWFsZWN0IGhhcyBubyBkZWZhdWx0cyBvZiBpdHMgb3duLiAqL1xuXHRyZWFkb25seSBpbml0aWFsPzogRm9ybVZhbHVlcztcbn1cblxudHlwZSBSZXF1ZXN0T2Y8TywgSyBleHRlbmRzIGtleW9mIE8+ID0gT1tLXSBleHRlbmRzIE9wZXJhdGlvblNoYXBlXG5cdD8gT1tLXVtcInJlcXVlc3RcIl1cblx0OiBuZXZlcjtcbnR5cGUgUmVzdWx0T2Y8TywgSyBleHRlbmRzIGtleW9mIE8+ID0gT1tLXSBleHRlbmRzIE9wZXJhdGlvblNoYXBlXG5cdD8gT1tLXVtcInJlc3VsdFwiXVxuXHQ6IG5ldmVyO1xuXG4vKipcbiAqIFdhbGsgYHFnaXNgIGJ5IHRoZSBkb3R0ZWQgaWQgdG8gdGhlIG1ldGhvZCBhIGRlY2xhcmVkIGFjdGlvbiBiZWNhbWUuXG4gKi9cbmZ1bmN0aW9uIG9wZXJhdGlvbk9mPEksIFI+KFxuXHRxZ2lzOiBRZ2lzU2RrQ29yZTx1bmtub3duLCB1bmtub3duPixcblx0aWQ6IHN0cmluZyxcbik6IE9wZXJhdGlvbjxJLCBSPiB7XG5cdGxldCBub2RlOiB1bmtub3duID0gcWdpcztcblx0Zm9yIChjb25zdCBzZWdtZW50IG9mIGlkLnNwbGl0KFwiLlwiKSkge1xuXHRcdG5vZGUgPVxuXHRcdFx0aXNQbGFpblJlY29yZChub2RlKSB8fCB0eXBlb2Ygbm9kZSA9PT0gXCJmdW5jdGlvblwiXG5cdFx0XHRcdD8gKG5vZGUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW3NlZ21lbnRdXG5cdFx0XHRcdDogdW5kZWZpbmVkO1xuXHR9XG5cdGlmICh0eXBlb2Ygbm9kZSAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtTdG9yZUVycm9yKGAke2lkfSBpcyBub3QgYW4gb3BlcmF0aW9uIG9mIHRoaXMgUWdpc1Nka2ApO1xuXHR9XG5cdHJldHVybiBub2RlIGFzIE9wZXJhdGlvbjxJLCBSPjtcbn1cblxuZnVuY3Rpb24gY29lcmNlKGZpZWxkOiBGb3JtRmllbGQsIHZhbHVlOiB1bmtub3duKTogdW5rbm93biB7XG5cdGlmICh2YWx1ZSA9PT0gXCJcIiAmJiBmaWVsZC5raW5kICE9PSBcInRleHRcIikge1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0aWYgKE5VTUVSSUNfS0lORFMuaGFzKGZpZWxkLmtpbmQpICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikge1xuXHRcdGNvbnN0IHRyaW1tZWQgPSB2YWx1ZS50cmltKCk7XG5cdFx0aWYgKFxuXHRcdFx0dHJpbW1lZCAhPT0gXCJcIiAmJlxuXHRcdFx0L15bLStdPyhcXGQrXFwuP1xcZCp8XFwuXFxkKykoW2VFXVstK10/XFxkKyk/JC8udGVzdCh0cmltbWVkKVxuXHRcdCkge1xuXHRcdFx0Y29uc3QgbnVtYmVyID0gTnVtYmVyKHRyaW1tZWQpO1xuXHRcdFx0aWYgKGZpZWxkLmtpbmQgIT09IFwiaW50ZWdlclwiIHx8IE51bWJlci5pc0ludGVnZXIobnVtYmVyKSkge1xuXHRcdFx0XHRyZXR1cm4gbnVtYmVyO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogQmluZCB0aGUgcmVxdWVzdCBvZiBvbmUgZGVjbGFyZWQgYWN0aW9uIHRvIGl0cyBzY2hlbWEuXG4gKlxuICogVGhlIGZpZWxkcyBjb21lIGZyb20gdGhlIGRlY2xhcmF0aW9uLCBzbyBhIHBhZ2UgcmVuZGVycyBgZm9ybS5maWVsZHNgXG4gKiBpbnN0ZWFkIG9mIGd1ZXNzaW5nOyBgc2V0YCBjb2VyY2VzIHdoYXQgYW4gYDxpbnB1dD5gIHlpZWxkcyAoYFwiM1wiYCBmb3IgYVxuICogbnVtZXJpYyBmaWVsZCwgYFwiXCJgIGZvciBhbiB1bnNldCBvbmUpIGFuZCByZS12YWxpZGF0ZXM7IGBzdWJtaXRgIHJlZnVzZXNcbiAqIGludmFsaWQgdmFsdWVzIHdpdGhvdXQgYSBjYWxsIGFuZCBvdGhlcndpc2UgcnVucyB0aGUgb3BlcmF0aW9uIHRocm91Z2ggYW5cbiAqIHtAbGluayBPcGVyYXRpb25TdG9yZX0sIHdob3NlIHN0YXRlIGlzIGBzdWJtaXNzaW9uYC5cbiAqL1xuZXhwb3J0IGNsYXNzIEZvcm1TdG9yZTxSZXEgZXh0ZW5kcyBvYmplY3QsIFI+IGV4dGVuZHMgQmFzZVN0b3JlPEZvcm1TdGF0ZTxSPj4ge1xuXHRwdWJsaWMgcmVhZG9ubHkgaWQ6IHN0cmluZztcblx0cHVibGljIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG5cdHB1YmxpYyByZWFkb25seSBmaWVsZHM6IHJlYWRvbmx5IEZvcm1GaWVsZFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IGJ5TmFtZTogUmVhZG9ubHlNYXA8c3RyaW5nLCBGb3JtRmllbGQ+O1xuXHRwcml2YXRlIHJlYWRvbmx5IHJlcXVlc3Q6IERlY2xhcmVkU2NoZW1hO1xuXHRwcml2YXRlIHJlYWRvbmx5IGluaXRpYWw6IEZvcm1WYWx1ZXM7XG5cdHByaXZhdGUgcmVhZG9ubHkgb3BlcmF0aW9uOiBPcGVyYXRpb25TdG9yZTxSZXEsIFI+O1xuXHRwcml2YXRlIHJlYWRvbmx5IHVuc3Vic2NyaWJlOiAoKSA9PiB2b2lkO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRxZ2lzOiBRZ2lzU2RrQ29yZTx1bmtub3duLCB1bmtub3duPixcblx0XHRpZDogc3RyaW5nLFxuXHRcdG9wdGlvbnM6IEZvcm1PcHRpb25zID0ge30sXG5cdCkge1xuXHRcdGNvbnN0IGFjdGlvbiA9IHFnaXMuc2NoZW1hLmFjdGlvbnMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUuaWQgPT09IGlkKTtcblx0XHRpZiAoYWN0aW9uID09PSB1bmRlZmluZWQpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrU3RvcmVFcnJvcihcblx0XHRcdFx0YCR7aWR9IGlzIG5vdCBhIGRlY2xhcmVkIGFjdGlvbiBvZiB0aGlzIHNjaGVtYWAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRjb25zdCBmaWVsZHMgPSBzY2hlbWFGaWVsZHMoYWN0aW9uLnJlcXVlc3QsIGBmb3JtICR7aWR9YCk7XG5cdFx0Y29uc3QgaW5pdGlhbCA9IEZvcm1TdG9yZS5kZWZhdWx0cyhvcHRpb25zLmluaXRpYWwgPz8ge30pO1xuXHRcdHN1cGVyKEZvcm1TdG9yZS5ldmFsdWF0ZShpbml0aWFsLCBhY3Rpb24ucmVxdWVzdCwgZmFsc2UsIGZhbHNlLCBJRExFKSk7XG5cdFx0dGhpcy5pZCA9IGlkO1xuXHRcdHRoaXMudGl0bGUgPSBhY3Rpb24udGl0bGU7XG5cdFx0dGhpcy5maWVsZHMgPSBmaWVsZHM7XG5cdFx0dGhpcy5ieU5hbWUgPSBuZXcgTWFwKGZpZWxkcy5tYXAoKGZpZWxkKSA9PiBbZmllbGQubmFtZSwgZmllbGRdKSk7XG5cdFx0dGhpcy5yZXF1ZXN0ID0gYWN0aW9uLnJlcXVlc3Q7XG5cdFx0dGhpcy5pbml0aWFsID0gaW5pdGlhbDtcblx0XHR0aGlzLm9wZXJhdGlvbiA9IG5ldyBPcGVyYXRpb25TdG9yZShvcGVyYXRpb25PZjxSZXEsIFI+KHFnaXMsIGlkKSk7XG5cdFx0bGV0IGZpcnN0ID0gdHJ1ZTtcblx0XHR0aGlzLnVuc3Vic2NyaWJlID0gdGhpcy5vcGVyYXRpb24uc3Vic2NyaWJlKChzdWJtaXNzaW9uKSA9PiB7XG5cdFx0XHRpZiAoZmlyc3QpIHtcblx0XHRcdFx0Zmlyc3QgPSBmYWxzZTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgY3VycmVudCA9IHRoaXMuZ2V0U25hcHNob3QoKTtcblx0XHRcdHRoaXMucHVibGlzaCh7IC4uLmN1cnJlbnQsIHN1Ym1pc3Npb24gfSk7XG5cdFx0fSk7XG5cdH1cblxuXHQvKiogVGhlIGRlY2xhcmF0aW9uIHRoZSBmb3JtIHdhcyBidWlsdCBmcm9tLCBmb3IgYSBwYWdlIHRoYXQgcmVuZGVycyBtb3JlLiAqL1xuXHRwdWJsaWMgc3RhdGljIGRlc2NyaWJlKFxuXHRcdHFnaXM6IFFnaXNTZGtDb3JlPHVua25vd24sIHVua25vd24+LFxuXHRcdGlkOiBzdHJpbmcsXG5cdCk6IEFjdGlvbkRlc2NyaXB0aW9uIHwgdW5kZWZpbmVkIHtcblx0XHRyZXR1cm4gcWdpcy5zY2hlbWEuYWN0aW9ucy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PT0gaWQpO1xuXHR9XG5cblx0cHJpdmF0ZSBzdGF0aWMgZGVmYXVsdHMoaW5pdGlhbDogRm9ybVZhbHVlcyk6IEZvcm1WYWx1ZXMge1xuXHRcdC8vIFRoZSBkZWNsYXJlZCBkaWFsZWN0IGNhcnJpZXMgbm8gYGRlZmF1bHRgIGtleXdvcmQ6IHdoYXQgYSBmb3JtIHN0YXJ0c1xuXHRcdC8vIGZyb20gaXMgdGhlIHBhZ2UncyBjaG9pY2UsIGFuZCBhbiB1bnNldCByZXF1aXJlZCBmaWVsZCBpcyBhbiBpc3N1ZVxuXHRcdC8vIHRoZSBwYWdlIHNob3dzIG9uY2UgYHN1Ym1pdHRlZGAgaXMgdHJ1ZS5cblx0XHRyZXR1cm4gT2JqZWN0LmZyZWV6ZShcblx0XHRcdE9iamVjdC5mcm9tRW50cmllcyhcblx0XHRcdFx0T2JqZWN0LmVudHJpZXMoaW5pdGlhbCkuZmlsdGVyKChbLCB2YWx1ZV0pID0+IHZhbHVlICE9PSB1bmRlZmluZWQpLFxuXHRcdFx0KSxcblx0XHQpO1xuXHR9XG5cblx0cHJpdmF0ZSBzdGF0aWMgZXZhbHVhdGU8Uj4oXG5cdFx0dmFsdWVzOiBGb3JtVmFsdWVzLFxuXHRcdHJlcXVlc3Q6IERlY2xhcmVkU2NoZW1hLFxuXHRcdGRpcnR5OiBib29sZWFuLFxuXHRcdHN1Ym1pdHRlZDogYm9vbGVhbixcblx0XHRzdWJtaXNzaW9uOiBPcGVyYXRpb25TdGF0ZTxSPixcblx0KTogRm9ybVN0YXRlPFI+IHtcblx0XHRjb25zdCBpc3N1ZXMgPSB2YWxpZGF0ZUFnYWluc3RTY2hlbWEodmFsdWVzLCByZXF1ZXN0KTtcblx0XHRjb25zdCBlcnJvcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblx0XHRmb3IgKGNvbnN0IGlzc3VlIG9mIGlzc3Vlcykge1xuXHRcdFx0Y29uc3QgW2hlYWRdID0gaXNzdWUucGF0aDtcblx0XHRcdGNvbnN0IG5hbWUgPSB0eXBlb2YgaGVhZCA9PT0gXCJzdHJpbmdcIiA/IGhlYWQgOiBcIlwiO1xuXHRcdFx0aWYgKCEobmFtZSBpbiBlcnJvcnMpKSB7XG5cdFx0XHRcdGVycm9yc1tuYW1lXSA9IGlzc3VlLmNvZGU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBPYmplY3QuZnJlZXplKHtcblx0XHRcdHZhbHVlcyxcblx0XHRcdGlzc3VlczogT2JqZWN0LmZyZWV6ZShpc3N1ZXMpLFxuXHRcdFx0ZXJyb3JzOiBPYmplY3QuZnJlZXplKGVycm9ycyksXG5cdFx0XHR2YWxpZDogaXNzdWVzLmxlbmd0aCA9PT0gMCxcblx0XHRcdGRpcnR5LFxuXHRcdFx0c3VibWl0dGVkLFxuXHRcdFx0c3VibWlzc2lvbixcblx0XHR9KTtcblx0fVxuXG5cdC8qKiBTZXQgb25lIGZpZWxkOyBgdW5kZWZpbmVkYCB1bnNldHMgaXQuICovXG5cdHB1YmxpYyByZWFkb25seSBzZXQgPSAobmFtZTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bik6IHZvaWQgPT4ge1xuXHRcdHRoaXMuc2V0VmFsdWVzKHsgW25hbWVdOiB2YWx1ZSB9KTtcblx0fTtcblxuXHQvKiogU2V0IHNldmVyYWwgZmllbGRzIGF0IG9uY2UuICovXG5cdHB1YmxpYyByZWFkb25seSBzZXRWYWx1ZXMgPSAoY2hhbmdlczogRm9ybVZhbHVlcyk6IHZvaWQgPT4ge1xuXHRcdGNvbnN0IGN1cnJlbnQgPSB0aGlzLmdldFNuYXBzaG90KCk7XG5cdFx0Y29uc3QgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHsgLi4uY3VycmVudC52YWx1ZXMgfTtcblx0XHRmb3IgKGNvbnN0IFtuYW1lLCByYXddIG9mIE9iamVjdC5lbnRyaWVzKGNoYW5nZXMpKSB7XG5cdFx0XHRjb25zdCBmaWVsZCA9IHRoaXMuYnlOYW1lLmdldChuYW1lKTtcblx0XHRcdGlmIChmaWVsZCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHRocm93IG5ldyBRZ2lzU2RrU3RvcmVFcnJvcihgJHt0aGlzLmlkfSBoYXMgbm8gZmllbGQgJHtuYW1lfWApO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgdmFsdWUgPSBjb2VyY2UoZmllbGQsIHJhdyk7XG5cdFx0XHRpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRkZWxldGUgdmFsdWVzW25hbWVdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dmFsdWVzW25hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMucHVibGlzaChcblx0XHRcdEZvcm1TdG9yZS5ldmFsdWF0ZShcblx0XHRcdFx0T2JqZWN0LmZyZWV6ZSh2YWx1ZXMpLFxuXHRcdFx0XHR0aGlzLnJlcXVlc3QsXG5cdFx0XHRcdHRydWUsXG5cdFx0XHRcdGN1cnJlbnQuc3VibWl0dGVkLFxuXHRcdFx0XHRjdXJyZW50LnN1Ym1pc3Npb24sXG5cdFx0XHQpLFxuXHRcdCk7XG5cdH07XG5cblx0LyoqIFRoZSBkZWNsYXJlZCBmaWVsZCwgZm9yIGEgcmVuZGVyZXIgd29ya2luZyBmcm9tIGEgbmFtZS4gKi9cblx0cHVibGljIGZpZWxkKG5hbWU6IHN0cmluZyk6IEZvcm1GaWVsZCB7XG5cdFx0Y29uc3QgZmllbGQgPSB0aGlzLmJ5TmFtZS5nZXQobmFtZSk7XG5cdFx0aWYgKGZpZWxkID09PSB1bmRlZmluZWQpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrU3RvcmVFcnJvcihgJHt0aGlzLmlkfSBoYXMgbm8gZmllbGQgJHtuYW1lfWApO1xuXHRcdH1cblx0XHRyZXR1cm4gZmllbGQ7XG5cdH1cblxuXHQvKiogQmFjayB0byB0aGUgaW5pdGlhbCB2YWx1ZXMgYW5kIGFuIGlkbGUgc3VibWlzc2lvbjsgYWJvcnRzIGEgY2FsbCBpbiBmbGlnaHQuICovXG5cdHB1YmxpYyByZWFkb25seSByZXNldCA9ICgpOiB2b2lkID0+IHtcblx0XHR0aGlzLm9wZXJhdGlvbi5yZXNldCgpO1xuXHRcdHRoaXMucHVibGlzaChcblx0XHRcdEZvcm1TdG9yZS5ldmFsdWF0ZSh0aGlzLmluaXRpYWwsIHRoaXMucmVxdWVzdCwgZmFsc2UsIGZhbHNlLCBJRExFKSxcblx0XHQpO1xuXHR9O1xuXG5cdC8qKiBBYm9ydCBhIHN1Ym1pc3Npb24gaW4gZmxpZ2h0OyB0aGUgdmFsdWVzIHN0YXkuICovXG5cdHB1YmxpYyByZWFkb25seSBhYm9ydCA9ICgpOiB2b2lkID0+IHtcblx0XHR0aGlzLm9wZXJhdGlvbi5hYm9ydCgpO1xuXHR9O1xuXG5cdC8qKlxuXHQgKiBWYWxpZGF0ZSwgdGhlbiBydW4gdGhlIGFjdGlvbiB3aXRoIHRoZSBjdXJyZW50IHZhbHVlcy4gUmVzb2x2ZXMgd2l0aCB0aGVcblx0ICogcmVzdWx0LCBvciBgdW5kZWZpbmVkYCB3aGVuIHRoZSB2YWx1ZXMgYXJlIGludmFsaWQgKG5vIGNhbGwgaXMgbWFkZSkgb3Jcblx0ICogdGhlIGNhbGwgZmFpbGVkLCB3YXMgYWJvcnRlZCBvciBzdXBlcnNlZGVkIC0gYHN1Ym1pc3Npb25gIHNheXMgd2hpY2guXG5cdCAqL1xuXHRwdWJsaWMgcmVhZG9ubHkgc3VibWl0ID0gYXN5bmMgKCk6IFByb21pc2U8UiB8IHVuZGVmaW5lZD4gPT4ge1xuXHRcdGNvbnN0IGN1cnJlbnQgPSB0aGlzLmdldFNuYXBzaG90KCk7XG5cdFx0aWYgKCFjdXJyZW50LnZhbGlkKSB7XG5cdFx0XHR0aGlzLnB1Ymxpc2goeyAuLi5jdXJyZW50LCBzdWJtaXR0ZWQ6IHRydWUgfSk7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRpZiAoIWN1cnJlbnQuc3VibWl0dGVkKSB7XG5cdFx0XHR0aGlzLnB1Ymxpc2goeyAuLi5jdXJyZW50LCBzdWJtaXR0ZWQ6IHRydWUgfSk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLm9wZXJhdGlvbi5ydW4oY3VycmVudC52YWx1ZXMgYXMgUmVxKTtcblx0fTtcblxuXHQvKiogU3RvcCBmb2xsb3dpbmcgdGhlIHN1Ym1pc3Npb247IGZvciBhbiBhZGFwdGVyIHRlYXJpbmcgdGhlIGZvcm0gZG93bi4gKi9cblx0cHVibGljIGRpc3Bvc2UoKTogdm9pZCB7XG5cdFx0dGhpcy5vcGVyYXRpb24uYWJvcnQoKTtcblx0XHR0aGlzLnVuc3Vic2NyaWJlKCk7XG5cdH1cbn1cblxuLyoqXG4gKiBUaGUgZm9ybSBmb3IgYHFnaXMuPGlkPmAsIHR5cGVkIGZyb20gdGhlIHNjaGVtYTogdGhlIHJlcXVlc3QgbmFtZXMgdGhlXG4gKiBmaWVsZHMsIHRoZSByZXN1bHQgdHlwZXMgdGhlIHN1Ym1pc3Npb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtU3RvcmU8TywgSyBleHRlbmRzIGtleW9mIE8gJiBzdHJpbmc+KFxuXHRxZ2lzOiBRZ2lzU2RrQ29yZTxPLCB1bmtub3duPixcblx0aWQ6IEssXG5cdG9wdGlvbnM/OiBGb3JtT3B0aW9ucyxcbik6IEZvcm1TdG9yZTxSZXF1ZXN0T2Y8TywgSz4gJiBvYmplY3QsIFJlc3VsdE9mPE8sIEs+PiB7XG5cdHJldHVybiBuZXcgRm9ybVN0b3JlKHFnaXMgYXMgUWdpc1Nka0NvcmU8dW5rbm93biwgdW5rbm93bj4sIGlkLCBvcHRpb25zKTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBIb3N0UXVlcnlTdG9yZVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBXaGVyZSBvbmUgaG9zdCBxdWVyeSBzdGFuZHMuICovXG5leHBvcnQgdHlwZSBIb3N0UXVlcnlTdGF0ZTxUPiA9XG5cdHwgeyByZWFkb25seSBzdGF0dXM6IFwiaWRsZVwiIH1cblx0fCB7IHJlYWRvbmx5IHN0YXR1czogXCJsb2FkaW5nXCIgfVxuXHR8IHsgcmVhZG9ubHkgc3RhdHVzOiBcIm9rXCI7IHJlYWRvbmx5IHZhbHVlOiBUIH1cblx0fCB7IHJlYWRvbmx5IHN0YXR1czogXCJlcnJvclwiOyByZWFkb25seSBlcnJvcjogRXJyb3IgfVxuXHR8IHtcblx0XHRcdC8qKiBUaGUgaGFuZHNoYWtlIGRpZCBub3QgZ3JhbnQgYG9wZXJhdGlvbmA7IG5vIGNhbGwgd2FzIG1hZGUuICovXG5cdFx0XHRyZWFkb25seSBzdGF0dXM6IFwicmVmdXNlZFwiO1xuXHRcdFx0cmVhZG9ubHkgb3BlcmF0aW9uOiBIb3N0T3BlcmF0aW9uSWQ7XG5cdFx0XHRyZWFkb25seSBtZXNzYWdlOiBzdHJpbmc7XG5cdCAgfTtcblxuY29uc3QgSURMRV9RVUVSWTogSG9zdFF1ZXJ5U3RhdGU8bmV2ZXI+ID0gT2JqZWN0LmZyZWV6ZSh7IHN0YXR1czogXCJpZGxlXCIgfSk7XG5cbi8qKiBXaGF0IGEgaG9zdCBxdWVyeSBydW5zIG9uY2UgdGhlIGdyYW50IGlzIGNvbmZpcm1lZC4gKi9cbmV4cG9ydCB0eXBlIEhvc3RRdWVyeUxvYWRlcjxUPiA9IChcblx0aG9zdDogUWdpc1Nka0hvc3QsXG5cdG9wdGlvbnM6IHsgcmVhZG9ubHkgc2lnbmFsOiBBYm9ydFNpZ25hbCB9LFxuKSA9PiBQcm9taXNlPFQ+O1xuXG4vKipcbiAqIFJlYWQgdGhlIGN1cmF0ZWQgaG9zdCBzdXJmYWNlLCBncmFudCBmaXJzdC5cbiAqXG4gKiBgcmVmcmVzaGAgd2FpdHMgZm9yIHRoZSBoYW5kc2hha2UsIHRoZW4gLSB3aGVuIGBxZ2lzLmhvc3QuZ3JhbnRlZGAgbGFja3NcbiAqIHRoZSBvcGVyYXRpb24gdGhlIHF1ZXJ5IG5lZWRzIC0gc2V0dGxlcyBvbiBgcmVmdXNlZGAgd2l0aG91dCBhIGNhbGwsIHNvIGFcbiAqIHBhZ2UgY2FuIHNob3cgXCJhc2sgdGhlIHBsdWdpbiBhdXRob3IgZm9yIGBsYXllcnMucmVhZGBcIiBpbnN0ZWFkIG9mIGFcbiAqIGBub3RfYXV0aG9yaXplZGAgZmF1bHQuIE90aGVyd2lzZSB0aGUgbG9hZGVyIHJ1bnMgd2l0aCBsYXRlc3Qtd2luc1xuICogc2VtYW50aWNzIGxpa2UgYW4gb3BlcmF0aW9uIHN0b3JlLlxuICovXG5leHBvcnQgY2xhc3MgSG9zdFF1ZXJ5U3RvcmU8VD4gZXh0ZW5kcyBCYXNlU3RvcmU8SG9zdFF1ZXJ5U3RhdGU8VD4+IHtcblx0cHJpdmF0ZSBnZW5lcmF0aW9uID0gMDtcblx0cHJpdmF0ZSBjb250cm9sbGVyOiBBYm9ydENvbnRyb2xsZXIgfCBudWxsID0gbnVsbDtcblxuXHRwdWJsaWMgY29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSByZWFkb25seSBxZ2lzOiBRZ2lzU2RrQ29yZTx1bmtub3duLCB1bmtub3duPixcblx0XHRwdWJsaWMgcmVhZG9ubHkgb3BlcmF0aW9uOiBIb3N0T3BlcmF0aW9uSWQsXG5cdFx0cHJpdmF0ZSByZWFkb25seSBsb2FkZXI6IEhvc3RRdWVyeUxvYWRlcjxUPixcblx0KSB7XG5cdFx0c3VwZXIoSURMRV9RVUVSWSk7XG5cdH1cblxuXHRwdWJsaWMgcmVhZG9ubHkgYWJvcnQgPSAoKTogdm9pZCA9PiB7XG5cdFx0dGhpcy5nZW5lcmF0aW9uICs9IDE7XG5cdFx0dGhpcy5jb250cm9sbGVyPy5hYm9ydCgpO1xuXHRcdHRoaXMuY29udHJvbGxlciA9IG51bGw7XG5cdH07XG5cblx0cHVibGljIHJlYWRvbmx5IHJlc2V0ID0gKCk6IHZvaWQgPT4ge1xuXHRcdHRoaXMuYWJvcnQoKTtcblx0XHR0aGlzLnB1Ymxpc2goSURMRV9RVUVSWSk7XG5cdH07XG5cblx0cHVibGljIHJlYWRvbmx5IHJlZnJlc2ggPSBhc3luYyAoKTogUHJvbWlzZTxUIHwgdW5kZWZpbmVkPiA9PiB7XG5cdFx0dGhpcy5hYm9ydCgpO1xuXHRcdGNvbnN0IG1pbmUgPSB0aGlzLmdlbmVyYXRpb247XG5cdFx0Y29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblx0XHR0aGlzLmNvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuXHRcdHRoaXMucHVibGlzaCh7IHN0YXR1czogXCJsb2FkaW5nXCIgfSk7XG5cdFx0dHJ5IHtcblx0XHRcdGF3YWl0IHRoaXMucWdpcy5yZWFkeTtcblx0XHRcdGlmICh0aGlzLmdlbmVyYXRpb24gIT09IG1pbmUpIHtcblx0XHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGlmICghdGhpcy5xZ2lzLmhvc3QuZ3JhbnRlZC5pbmNsdWRlcyh0aGlzLm9wZXJhdGlvbikpIHtcblx0XHRcdFx0dGhpcy5wdWJsaXNoKHtcblx0XHRcdFx0XHRzdGF0dXM6IFwicmVmdXNlZFwiLFxuXHRcdFx0XHRcdG9wZXJhdGlvbjogdGhpcy5vcGVyYXRpb24sXG5cdFx0XHRcdFx0bWVzc2FnZTogYHRoaXMgdmlldyB3YXMgbm90IGdyYW50ZWQgJHt0aGlzLm9wZXJhdGlvbn1gLFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdGNvbnN0IHZhbHVlID0gYXdhaXQgdGhpcy5sb2FkZXIodGhpcy5xZ2lzLmhvc3QsIHtcblx0XHRcdFx0c2lnbmFsOiBjb250cm9sbGVyLnNpZ25hbCxcblx0XHRcdH0pO1xuXHRcdFx0aWYgKHRoaXMuZ2VuZXJhdGlvbiAhPT0gbWluZSkge1xuXHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5wdWJsaXNoKHsgc3RhdHVzOiBcIm9rXCIsIHZhbHVlIH0pO1xuXHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdHRoaXMuZ2VuZXJhdGlvbiAhPT0gbWluZSB8fFxuXHRcdFx0XHRlcnJvciBpbnN0YW5jZW9mIFFnaXNTZGtCcmlkZ2VBYm9ydGVkRXJyb3Jcblx0XHRcdCkge1xuXHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5wdWJsaXNoKHsgc3RhdHVzOiBcImVycm9yXCIsIGVycm9yOiBhc0Vycm9yKGVycm9yKSB9KTtcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fSBmaW5hbGx5IHtcblx0XHRcdGlmICh0aGlzLmNvbnRyb2xsZXIgPT09IGNvbnRyb2xsZXIpIHtcblx0XHRcdFx0dGhpcy5jb250cm9sbGVyID0gbnVsbDtcblx0XHRcdH1cblx0XHR9XG5cdH07XG59XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgbGF5ZXJzUXVlcnl9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYXllcnNRdWVyeU9wdGlvbnMge1xuXHQvKiogSXRlbXMgcGVyIHBhZ2Ugd2hpbGUgZm9sbG93aW5nIGBuZXh0X2N1cnNvcmA7IHRoZSBob3N0J3MgZGVmYXVsdCBvdGhlcndpc2UuICovXG5cdHJlYWRvbmx5IHBhZ2VTaXplPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEV2ZXJ5IHZlY3RvciBsYXllciBvZiB0aGUgcHJvamVjdCwgZm9sbG93aW5nIGBsYXllcnMubGlzdGAgcGFnZXMgdG8gdGhlXG4gKiBlbmQ6IHdoYXQgYSBsYXllciBwaWNrZXIgYmluZHMgdG8uIE5lZWRzIHRoZSBgbGF5ZXJzLnJlYWRgIGdyYW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJzUXVlcnkoXG5cdHFnaXM6IFFnaXNTZGtDb3JlPHVua25vd24sIHVua25vd24+LFxuXHRvcHRpb25zOiBMYXllcnNRdWVyeU9wdGlvbnMgPSB7fSxcbik6IEhvc3RRdWVyeVN0b3JlPHJlYWRvbmx5IFZlY3RvckxheWVySW5mb1tdPiB7XG5cdHJldHVybiBuZXcgSG9zdFF1ZXJ5U3RvcmUocWdpcywgXCJsYXllcnMubGlzdFwiLCBhc3luYyAoaG9zdCwgeyBzaWduYWwgfSkgPT4ge1xuXHRcdGNvbnN0IGl0ZW1zOiBWZWN0b3JMYXllckluZm9bXSA9IFtdO1xuXHRcdGxldCBjdXJzb3I6IHN0cmluZyB8IHVuZGVmaW5lZDtcblx0XHRkbyB7XG5cdFx0XHRjb25zdCBwYWdlOiBMYXllclBhZ2UgPSBhd2FpdCBob3N0LmxheWVycy5saXN0KFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0Li4uKGN1cnNvciA9PT0gdW5kZWZpbmVkID8ge30gOiB7IGN1cnNvciB9KSxcblx0XHRcdFx0XHQuLi4ob3B0aW9ucy5wYWdlU2l6ZSA9PT0gdW5kZWZpbmVkXG5cdFx0XHRcdFx0XHQ/IHt9XG5cdFx0XHRcdFx0XHQ6IHsgbGltaXQ6IG9wdGlvbnMucGFnZVNpemUgfSksXG5cdFx0XHRcdH0sXG5cdFx0XHRcdHsgc2lnbmFsIH0sXG5cdFx0XHQpO1xuXHRcdFx0aXRlbXMucHVzaCguLi5wYWdlLml0ZW1zKTtcblx0XHRcdGN1cnNvciA9IHBhZ2UubmV4dF9jdXJzb3I7XG5cdFx0fSB3aGlsZSAoY3Vyc29yICE9PSB1bmRlZmluZWQpO1xuXHRcdHJldHVybiBPYmplY3QuZnJlZXplKGl0ZW1zKTtcblx0fSk7XG59XG5cbi8qKlxuICogVGhlIGZpZWxkIG5hbWVzIG9mIG9uZSB2ZWN0b3IgbGF5ZXIsIGZvciBhIGBmaWVsZGAgaW5wdXQgd2hvc2UgYG9mYCBuYW1lc1xuICogYSBsYXllciBpbnB1dDogYGxheWVycy5nZXRgIHVuZGVyIHRoZSBgbGF5ZXJzLnJlYWRgIGdyYW50LiBBIGxheWVyJ3MgQ1JTIGlzXG4gKiBvbiB0aGUgc2FtZSByZXBseTsgYSBwcm9qZWN0IENSUyBxdWVyeSBpcyBub3Qgb24gdGhlIHdpcmUgeWV0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGF5ZXJGaWVsZHNRdWVyeShcblx0cWdpczogUWdpc1Nka0NvcmU8dW5rbm93biwgdW5rbm93bj4sXG5cdGxheWVySWQ6IHN0cmluZyxcbik6IEhvc3RRdWVyeVN0b3JlPHJlYWRvbmx5IHN0cmluZ1tdPiB7XG5cdHJldHVybiBuZXcgSG9zdFF1ZXJ5U3RvcmUocWdpcywgXCJsYXllcnMuZ2V0XCIsIGFzeW5jIChob3N0LCB7IHNpZ25hbCB9KSA9PiB7XG5cdFx0Y29uc3QgbGF5ZXIgPSBhd2FpdCBob3N0LmxheWVycy5nZXQoeyBsYXllcl9pZDogbGF5ZXJJZCB9LCB7IHNpZ25hbCB9KTtcblx0XHRyZXR1cm4gT2JqZWN0LmZyZWV6ZShbLi4ubGF5ZXIuZmllbGRfbmFtZXNdKTtcblx0fSk7XG59XG4iCiAgXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7O0FBYU8sSUFBTSxvQkFBMkI7QUFDakMsSUFBTSxvQkFBMkI7QUFDakMsSUFBTSxxQ0FBdUM7QUFxRDdDLFNBQVMsa0JBQWlCLENBQUMsT0FBaUM7QUFBQSxFQUNsRSxPQUFPLE9BQU8sVUFBVSxZQUFZLE9BQU8sY0FBYyxLQUFLO0FBQUE7QUFBQTtBQU14RCxNQUFNLGlDQUFnQyxjQUFhO0FBQUEsRUFDbEQsV0FBVyxDQUFDLFNBQWlCO0FBQUEsSUFDbkMsTUFBTSxTQUFTLHFC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