@dbx-tools/appkit-mastra 0.9.65 → 0.9.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/src/mlflow.js CHANGED
@@ -24,12 +24,86 @@
24
24
  *
25
25
  * @module
26
26
  */
27
- import { ConfigurationError } from "@databricks/appkit";
27
+ import { ConfigurationError, createWorkspaceClient } from "@databricks/appkit";
28
+ import { appkit } from "@dbx-tools/appkit";
28
29
  import { asyncUtils, errorUtils, log, object } from "@dbx-tools/shared-core";
29
30
  import { feedback } from "@dbx-tools/shared-mastra";
31
+ import { TraceLocationType, TraceMetadataKey } from "@mlflow/core";
32
+ import { TraceInfo } from "@mlflow/core/dist/core/entities/trace_info";
33
+ import { TraceState } from "@mlflow/core/dist/core/entities/trace_state";
30
34
  import { z } from "zod";
31
35
  import { databricksFetch, readResponseJson, readResponseText } from "./rest.js";
36
+ import { MLFLOW_AGENT_TAG_ATTR } from "./trace-attributes.js";
32
37
  const logger = log.logger("mastra/mlflow");
38
+ let directMlflow;
39
+ let directMlflowInitStarted = false;
40
+ let directMlflowProvider;
41
+ let directMlflowProcessor;
42
+ let appMlflowTraceInfoInitStarted = false;
43
+ let appMlflowTraceInfoClient;
44
+ let appMlflowTracePrefix;
45
+ const pendingAppMlflowTraceInfo = new Set();
46
+ const NOISY_INSTRUMENTATION_SCOPES = new Set([
47
+ "@opentelemetry/instrumentation-express",
48
+ "@opentelemetry/instrumentation-http",
49
+ "cache-manager-cache-manager",
50
+ ]);
51
+ function isAgentTraceRoot(span) {
52
+ return span.attributes[MLFLOW_AGENT_TAG_ATTR] === "true";
53
+ }
54
+ function isUsefulAgentDescendant(span) {
55
+ return !NOISY_INSTRUMENTATION_SCOPES.has(span.instrumentationScope.name);
56
+ }
57
+ /**
58
+ * Restrict the direct MLflow provider to chat roots and their descendants.
59
+ * AppKit and Mastra create other OTel roots for cache and plugin operations;
60
+ * forwarding those would recreate the one-trace-per-request noise this path is
61
+ * intended to avoid.
62
+ */
63
+ export class AgentTraceSpanProcessor {
64
+ delegate;
65
+ traceIds = new Set();
66
+ spanIds = new Set();
67
+ constructor(delegate) {
68
+ this.delegate = delegate;
69
+ }
70
+ onStart(span, parentContext) {
71
+ const traceId = span.spanContext().traceId;
72
+ const isRoot = !span.parentSpanContext?.spanId;
73
+ if (isRoot) {
74
+ if (!isAgentTraceRoot(span))
75
+ return;
76
+ this.traceIds.add(traceId);
77
+ }
78
+ else if (!this.traceIds.has(traceId) || !isUsefulAgentDescendant(span)) {
79
+ return;
80
+ }
81
+ this.spanIds.add(span.spanContext().spanId);
82
+ this.delegate.onStart(span, parentContext);
83
+ }
84
+ onEnding(span) {
85
+ if (!this.spanIds.has(span.spanContext().spanId))
86
+ return;
87
+ this.delegate.onEnding?.(span);
88
+ }
89
+ onEnd(span) {
90
+ const traceId = span.spanContext().traceId;
91
+ const spanId = span.spanContext().spanId;
92
+ if (!this.spanIds.delete(spanId))
93
+ return;
94
+ this.delegate.onEnd(span);
95
+ if (!span.parentSpanContext?.spanId)
96
+ this.traceIds.delete(traceId);
97
+ }
98
+ forceFlush() {
99
+ return this.delegate.forceFlush();
100
+ }
101
+ shutdown() {
102
+ this.traceIds.clear();
103
+ this.spanIds.clear();
104
+ return this.delegate.shutdown();
105
+ }
106
+ }
33
107
  /** Experiment tag Databricks stores as `catalog.schema.table_prefix`. */
34
108
  const TRACE_DESTINATION_PATH_TAG = "mlflow.experiment.databricksTraceDestinationPath";
35
109
  /** Experiment tag naming the OTel spans table (`catalog.schema.{prefix}_otel_spans`). */
@@ -194,20 +268,248 @@ function configuredExperiment() {
194
268
  ...(name ? { name } : {}),
195
269
  };
196
270
  }
271
+ /** Tracking URI for direct local MLflow tracing, with CLI-profile auth injected. */
272
+ export function directMlflowTrackingUri() {
273
+ if (appkit.isDatabricksAppEnv())
274
+ return undefined;
275
+ const configured = process.env.MLFLOW_TRACKING_URI?.trim();
276
+ if (configured && configured !== "databricks")
277
+ return configured;
278
+ const profile = process.env.DATABRICKS_CONFIG_PROFILE?.trim();
279
+ return profile ? `databricks://${profile}` : "databricks";
280
+ }
281
+ /** Parse the optional UC table-prefix location used by direct local tracing. */
282
+ export function directMlflowTraceLocation() {
283
+ const catalogName = process.env.MLFLOW_UC_CATALOG?.trim();
284
+ const schemaName = process.env.MLFLOW_UC_SCHEMA?.trim();
285
+ const tablePrefix = process.env.MLFLOW_UC_TABLE_PREFIX?.trim();
286
+ if (catalogName && schemaName && tablePrefix) {
287
+ return { catalogName, schemaName, tablePrefix };
288
+ }
289
+ const prefix = normalizeUcPrefix(process.env.MLFLOW_UC_TRACE_PREFIX);
290
+ if (!prefix)
291
+ return undefined;
292
+ const parts = prefix.split(".");
293
+ if (parts.length !== 3)
294
+ return undefined;
295
+ const [prefixCatalog, prefixSchema, prefixTable] = parts;
296
+ if (!prefixCatalog || !prefixSchema || !prefixTable)
297
+ return undefined;
298
+ return {
299
+ catalogName: prefixCatalog,
300
+ schemaName: prefixSchema,
301
+ tablePrefix: prefixTable,
302
+ };
303
+ }
304
+ /** Whether the local direct-to-experiment MLflow SDK has enough configuration. */
305
+ export function directMlflowTracingConfigured() {
306
+ return Boolean(!appkit.isDatabricksAppEnv() &&
307
+ process.env.MLFLOW_EXPERIMENT_ID?.trim() &&
308
+ directMlflowTrackingUri());
309
+ }
310
+ /** Whether a Databricks App can promote OTLP spans into full MLflow trace info. */
311
+ export function appMlflowTraceInfoConfigured() {
312
+ return Boolean(appkit.isDatabricksAppEnv() &&
313
+ (process.env.MLFLOW_EXPERIMENT_ID?.trim() || process.env.MLFLOW_EXPERIMENT_NAME?.trim()) &&
314
+ (process.env.OTEL_EXPORTER_OTLP_ENDPOINT?.trim() ||
315
+ process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT?.trim()));
316
+ }
317
+ /** Initialize the App service-principal client used to persist V4 trace tags and metadata. */
318
+ export async function initializeAppMlflowTraceInfo(client) {
319
+ if (appMlflowTraceInfoClient && appMlflowTracePrefix)
320
+ return true;
321
+ if (appMlflowTraceInfoInitStarted || !appMlflowTraceInfoConfigured())
322
+ return false;
323
+ appMlflowTraceInfoInitStarted = true;
324
+ try {
325
+ const resolvedClient = client ?? createWorkspaceClient();
326
+ const prefix = await resolveUcTracePrefix(resolvedClient);
327
+ if (!prefix || prefix.split(".").length !== 3) {
328
+ throw new ConfigurationError("Databricks Apps MLflow trace-info promotion requires a UC-linked experiment or MLFLOW_UC_TRACE_PREFIX.");
329
+ }
330
+ appMlflowTraceInfoClient = resolvedClient;
331
+ appMlflowTracePrefix = prefix;
332
+ logger.info("Databricks Apps MLflow trace-info promotion enabled", { prefix });
333
+ return true;
334
+ }
335
+ catch (err) {
336
+ logger.warn("Databricks Apps MLflow trace-info promotion disabled", {
337
+ error: errorUtils.errorMessage(err),
338
+ });
339
+ return false;
340
+ }
341
+ }
342
+ /** Persist MLflow V4 trace info for one Databricks Apps OTel root without re-exporting spans. */
343
+ export function persistAppMlflowTraceInfo(params) {
344
+ const client = appMlflowTraceInfoClient;
345
+ const prefix = appMlflowTracePrefix;
346
+ if (!client || !prefix)
347
+ return;
348
+ const [catalogName, schemaName, tablePrefix] = prefix.split(".");
349
+ if (!catalogName || !schemaName || !tablePrefix)
350
+ return;
351
+ const traceInfo = new TraceInfo({
352
+ traceId: `trace:/${prefix}/${params.traceId}`,
353
+ traceLocation: {
354
+ type: TraceLocationType.UC_TABLE_PREFIX,
355
+ ucTablePrefix: { catalogName, schemaName, tablePrefix },
356
+ },
357
+ requestTime: params.requestTime,
358
+ executionDuration: params.executionDuration,
359
+ state: params.error ? TraceState.ERROR : TraceState.OK,
360
+ ...(params.requestPreview ? { requestPreview: params.requestPreview } : {}),
361
+ ...(params.responsePreview ? { responsePreview: params.responsePreview } : {}),
362
+ traceMetadata: {
363
+ [TraceMetadataKey.SCHEMA_VERSION]: "4",
364
+ ...(params.user ? { [TraceMetadataKey.TRACE_USER]: params.user } : {}),
365
+ ...(params.sessionId ? { [TraceMetadataKey.TRACE_SESSION]: params.sessionId } : {}),
366
+ },
367
+ tags: params.tags,
368
+ assessments: [],
369
+ });
370
+ const path = `/api/4.0/mlflow/traces/${encodeURIComponent(prefix)}/${params.traceId}/info`;
371
+ const pending = databricksFetch(client, path, { method: "POST", body: traceInfo.toJson() })
372
+ .then(async (response) => {
373
+ if (response.ok)
374
+ return;
375
+ logger.warn("Databricks Apps MLflow trace-info promotion failed", {
376
+ traceId: params.traceId,
377
+ status: response.status,
378
+ body: await readResponseText(response),
379
+ });
380
+ })
381
+ .catch((err) => {
382
+ logger.warn("Databricks Apps MLflow trace-info promotion failed", {
383
+ traceId: params.traceId,
384
+ error: errorUtils.errorMessage(err),
385
+ });
386
+ })
387
+ .finally(() => pendingAppMlflowTraceInfo.delete(pending));
388
+ pendingAppMlflowTraceInfo.add(pending);
389
+ }
390
+ /** Reset Apps trace-info promotion state for tests. */
391
+ export function resetAppMlflowTraceInfo() {
392
+ appMlflowTraceInfoInitStarted = false;
393
+ appMlflowTraceInfoClient = undefined;
394
+ appMlflowTracePrefix = undefined;
395
+ pendingAppMlflowTraceInfo.clear();
396
+ }
397
+ async function detectedDirectMlflowTraceLocation(mlflow, trackingUri, experimentId, host) {
398
+ const explicit = directMlflowTraceLocation();
399
+ if (explicit)
400
+ return explicit;
401
+ try {
402
+ const authProvider = mlflow.createAuthProvider({
403
+ trackingUri,
404
+ ...(host ? { host } : {}),
405
+ });
406
+ const client = new mlflow.MlflowClient({ trackingUri, authProvider });
407
+ const experiment = await client.getExperiment(experimentId);
408
+ if (!experiment)
409
+ return undefined;
410
+ const { ucLocationFromExperimentTags } = await import("@mlflow/core/dist/core/destination");
411
+ const location = ucLocationFromExperimentTags(experiment.tags);
412
+ if (!location?.tablePrefix)
413
+ return undefined;
414
+ return {
415
+ catalogName: location.catalogName,
416
+ schemaName: location.schemaName,
417
+ tablePrefix: location.tablePrefix,
418
+ };
419
+ }
420
+ catch (err) {
421
+ logger.warn("direct MLflow UC trace-location detection failed", {
422
+ experimentId,
423
+ error: errorUtils.errorMessage(err),
424
+ });
425
+ return undefined;
426
+ }
427
+ }
428
+ /**
429
+ * Start the MLflow Node tracer for local development when AppKit has no OTLP
430
+ * exporter. This provider is never started in the deployed Apps path, avoiding
431
+ * a second global OTel provider racing AppKit's telemetry manager.
432
+ */
433
+ export async function initializeDirectMlflowTracing() {
434
+ if (directMlflow)
435
+ return true;
436
+ if (directMlflowInitStarted || !directMlflowTracingConfigured())
437
+ return false;
438
+ directMlflowInitStarted = true;
439
+ const experimentId = process.env.MLFLOW_EXPERIMENT_ID.trim();
440
+ const trackingUri = directMlflowTrackingUri();
441
+ try {
442
+ const mlflow = await import("@mlflow/core");
443
+ const rawHost = process.env.DATABRICKS_HOST?.trim();
444
+ const host = rawHost
445
+ ? /^https?:\/\//i.test(rawHost)
446
+ ? rawHost
447
+ : `https://${rawHost}`
448
+ : undefined;
449
+ const traceLocation = await detectedDirectMlflowTraceLocation(mlflow, trackingUri, experimentId, host);
450
+ if (!traceLocation) {
451
+ throw new ConfigurationError("Direct local MLflow tracing requires a UC-linked experiment or MLFLOW_UC_TRACE_PREFIX.");
452
+ }
453
+ const [{ DatabricksUCTableSpanExporter, DatabricksUCTableSpanProcessor }, sdk] = await Promise.all([
454
+ import("@mlflow/core/dist/exporters/uc_table"),
455
+ import("@opentelemetry/sdk-trace-node"),
456
+ ]);
457
+ const authProvider = mlflow.createAuthProvider({
458
+ trackingUri,
459
+ ...(host ? { host } : {}),
460
+ });
461
+ const client = new mlflow.MlflowClient({ trackingUri, authProvider });
462
+ const exporter = new DatabricksUCTableSpanExporter(client);
463
+ const processor = new AgentTraceSpanProcessor(new DatabricksUCTableSpanProcessor(exporter, traceLocation));
464
+ const provider = new sdk.NodeTracerProvider({ spanProcessors: [processor] });
465
+ provider.register();
466
+ directMlflow = mlflow;
467
+ directMlflowProvider = provider;
468
+ directMlflowProcessor = processor;
469
+ logger.info("direct MLflow tracing enabled", {
470
+ experimentId,
471
+ trackingUri,
472
+ traceLocation,
473
+ });
474
+ return true;
475
+ }
476
+ catch (err) {
477
+ logger.warn("direct MLflow tracing disabled", {
478
+ error: errorUtils.errorMessage(err),
479
+ });
480
+ return false;
481
+ }
482
+ }
483
+ /** Persist trace-level fields on the direct MLflow trace in the current OTel context. */
484
+ export function updateActiveMlflowTrace(options) {
485
+ directMlflow?.updateCurrentTrace(options);
486
+ }
487
+ /** Persist tags on the direct MLflow trace active in the current OTel context. */
488
+ export function updateActiveMlflowTraceTags(tags) {
489
+ updateActiveMlflowTrace({ tags });
490
+ }
491
+ /** Whether this process owns the filtered local MLflow tracer provider. */
492
+ export function directMlflowTracingActive() {
493
+ return directMlflowProcessor !== undefined;
494
+ }
495
+ /** Flush pending direct local trace exports during graceful shutdown. */
496
+ export async function flushDirectMlflowTracing() {
497
+ await Promise.all([...pendingAppMlflowTraceInfo]);
498
+ await directMlflowProcessor?.forceFlush();
499
+ await directMlflowProvider?.forceFlush();
500
+ }
197
501
  /**
198
502
  * Whether MLflow feedback logging is available for this deployment.
199
503
  *
200
- * Enabled when an OTLP exporter endpoint is configured (traces are
201
- * actually shipped somewhere) AND an MLflow experiment is named - the
202
- * two signals that the OTLP backend is MLflow and traces will
203
- * materialize there. Both are standard env vars, so no plugin config is
204
- * required; a deployment opts in simply by wiring MLflow tracing.
504
+ * Enabled when an MLflow experiment is configured and traces have an export
505
+ * path: AppKit OTLP in a Databricks App, or the direct MLflow Node SDK outside
506
+ * one. Both paths are selected from standard environment values.
205
507
  */
206
508
  export function mlflowEnabled() {
207
509
  const hasExporter = Boolean(process.env.OTEL_EXPORTER_OTLP_ENDPOINT?.trim() ||
208
510
  process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT?.trim());
209
511
  const hasExperiment = Boolean(process.env.MLFLOW_EXPERIMENT_ID?.trim() || process.env.MLFLOW_EXPERIMENT_NAME?.trim());
210
- return hasExporter && hasExperiment;
512
+ return hasExperiment && (hasExporter || directMlflowTracingConfigured());
211
513
  }
212
514
  /**
213
515
  * Resolve whether user feedback is enabled from the plugin's optional
@@ -360,4 +662,4 @@ export async function logFeedback(client, params) {
360
662
  }
361
663
  return undefined;
362
664
  }
363
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWxmbG93LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21sZmxvdy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUVILE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRXhELE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM3RSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDcEQsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUN4QixPQUFPLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWhGLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7QUFLM0MseUVBQXlFO0FBQ3pFLE1BQU0sMEJBQTBCLEdBQUcsa0RBQWtELENBQUM7QUFDdEYseUZBQXlGO0FBQ3pGLE1BQU0sNEJBQTRCLEdBQUcsbURBQW1ELENBQUM7QUFFekY7Ozs7R0FJRztBQUNILElBQUksY0FBMEQsQ0FBQztBQUUvRCw2RUFBNkU7QUFDN0UsU0FBUyxpQkFBaUIsQ0FBQyxHQUF1QjtJQUNoRCxNQUFNLEtBQUssR0FBRyxHQUFHO1FBQ2YsRUFBRSxJQUFJLEVBQUU7U0FDUCxPQUFPLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztTQUN4QixPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZCLE9BQU8sS0FBSyxJQUFJLFNBQVMsQ0FBQztBQUM1QixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FBQyxLQUF5QjtJQUNwRCxNQUFNLElBQUksR0FBRyxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDM0IsSUFBSSxDQUFD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QWlCO2dCQUNqQixLQUFLLEVBQUUsVUFBVSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUM7YUFDcEMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUNELElBQUksR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ1gsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzQyxNQUFNLFlBQVksR0FDZixNQUF1RCxFQUFFLFVBQVUsRUFBRSxhQUFhO2dCQUNsRixNQUFzQyxFQUFFLGFBQWEsQ0FBQztZQUN6RCxPQUFPLE9BQU8sWUFBWSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDOUQsQ0FBQztRQUNELGtFQUFrRTtRQUNsRSwwREFBMEQ7UUFDMUQsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxPQUFPLEdBQUcsaUJBQWlCLEVBQUUsQ0FBQztZQUN0RCxNQUFNLFVBQVUsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEdBQUcsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3RCxTQUFTO1FBQ1gsQ0FBQztRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsdUJBQXVCLEVBQUU7WUFDbkMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO1lBQ3ZCLGlCQUFpQjtZQUNqQixNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU07WUFDbEIsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUMsR0FBRyxDQUFDO1NBQ2xDLENBQUMsQ0FBQztRQUNILE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFDRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNTGZsb3cgdXNlci1mZWVkYmFjayBsb2dnaW5nOiBkZXRlY3Qgd2hldGhlciBNTGZsb3cgdHJhY2luZyBpcyB3aXJlZFxuICogZm9yIHRoaXMgZGVwbG95bWVudCwgYW5kIGxvZyBhIHRodW1icyAvIGNvbW1lbnQgYXMgYSB0cmFjZVxuICogKmFzc2Vzc21lbnQqIHZpYSB0aGUgRGF0YWJyaWNrcyBNTGZsb3cgUkVTVCBBUEkuXG4gKlxuICogRmVlZGJhY2sgYXR0YWNoZXMgdG8gYSB0cmFjZSwgYW5kIHRoZSBwbHVnaW4ncyBzcGFucyByZWFjaCBNTGZsb3dcbiAqIHRocm91Z2ggdGhlIHNhbWUgT1RlbCBwaXBlbGluZSBhcyBldmVyeSBvdGhlciBBcHBLaXQgc3BhbiAoc2VlXG4gKiBgb2JzZXJ2YWJpbGl0eS50c2ApLiBPbiBEYXRhYnJpY2tzIEFwcHMgdGhhdCBwaXBlbGluZSBpcyB0aGUgVUNcbiAqIHNpZGVjYXIgaW5qZWN0ZWQgYnkgYHRlbGVtZXRyeV9leHBvcnRfZGVzdGluYXRpb25zYCwgbm90IGEgZGlyZWN0XG4gKiB3b3Jrc3BhY2UgT1RMUCBVUkwuIE1MZmxvdyBkZXJpdmVzIGl0cyB0cmFjZSBpZCBmcm9tIHRoZSBPcGVuVGVsZW1ldHJ5XG4gKiB0cmFjZSBpZCAoYHRyLTxoZXgob3RlbFRyYWNlSWQpPmApLCBzbyB0aGUgc2VydmVyIHN0YW1wcyB0aGUgYWN0aXZlXG4gKiB0cmFjZSBpZCBvbiBlYWNoIHR1cm4ncyByZXNwb25zZSBhbmQgdGhlIGNsaWVudCBzZW5kcyBpdCBiYWNrIGhlcmUuXG4gKlxuICogVGhlcmUgaXMgbm8gTUxmbG93IEpTIFNESywgc28gdGhpcyBwb3N0cyB0byB0aGUgYXNzZXNzbWVudHMgUkVTVFxuICogZW5kcG9pbnQgZGlyZWN0bHkgdXNpbmcgdGhlIE9CTy1zY29wZWQgd29ya3NwYWNlIGNsaWVudCAodGhlIGZlZWRiYWNrXG4gKiBpcyB0aHVzIGF0dHJpYnV0ZWQgdG8gdGhlIHNpZ25lZC1pbiB1c2VyKS4gVUMtYmFja2VkIEFwcHMgdHJhY2VzIG5lZWRcbiAqIHRoZSBleHBlcmltZW50J3MgdGFibGUtcHJlZml4IFVSSSAoYHRyYWNlOi97Y2F0YWxvZ30ue3NjaGVtYX0ue3ByZWZpeH0ve3RyLWhleH1gKVxuICogcmF0aGVyIHRoYW4gdGhlIGV4cGVyaW1lbnQtc3RvcmUgaWQgdGhlIFVJIGRvZXMgbm90IHN0b3JlLiBUaGF0IHByZWZpeCBpc1xuICogcmVhZCBmcm9tIHRoZSBleHBlcmltZW50J3MgYG1sZmxvdy5leHBlcmltZW50LmRhdGFicmlja3NUcmFjZURlc3RpbmF0aW9uUGF0aGBcbiAqIHRhZyAob3IgdGhlIHNwYW5zLXRhYmxlIHRhZyk7IGBNTEZMT1dfVUNfVFJBQ0VfUFJFRklYYCByZW1haW5zIGFuIG9wdGlvbmFsXG4gKiBvdmVycmlkZS4gVHJhY2UgZXhwb3J0IGlzIGFzeW5jaHJvbm91cywgc28gdGhlIGp1c3QtZmluaXNoZWQgdHJhY2UgbWF5IG5vdFxuICogZXhpc3QgaW4gTUxmbG93IHlldCB3aGVuIHRoZSB1c2VyIHJlYWN0czsgdGhlIGxvZyBjYWxsIHJldHJpZXMgYnJpZWZseSBvblxuICogXCJub3QgZm91bmRcIiBiZWZvcmUgZ2l2aW5nIHVwIHNvZnRseS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgQ29uZmlndXJhdGlvbkVycm9yIH0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdFwiO1xuaW1wb3J0IHsgYXBwa2l0IH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG5pbXBvcnQgeyBhc3luY1V0aWxzLCBlcnJvclV0aWxzLCBsb2csIG9iamVjdCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBmZWVkYmFjayB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1tYXN0cmFcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyBkYXRhYnJpY2tzRmV0Y2gsIHJlYWRSZXNwb25zZUpzb24sIHJlYWRSZXNwb25zZVRleHQgfSBmcm9tIFwiLi9yZXN0LnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtYXN0cmEvbWxmbG93XCIpO1xuXG4vKiogV29ya3NwYWNlIGNsaWVudCBjYXJyaWVkIG9uIGFuIEFwcEtpdCBleGVjdXRpb24gY29udGV4dC4gKi9cbnR5cGUgV29ya3NwYWNlQ2xpZW50ID0gYXBwa2l0LldvcmtzcGFjZUNsaWVudExpa2U7XG5cbi8qKiBFeHBlcmltZW50IHRhZyBEYXRhYnJpY2tzIHN0b3JlcyBhcyBgY2F0YWxvZy5zY2hlbWEudGFibGVfcHJlZml4YC4gKi9cbmNvbnN0IFRSQUNFX0RFU1RJTkFUSU9OX1BBVEhfVEFHID0gXCJtbGZsb3cuZXhwZXJpbWVudC5kYXRhYnJpY2tzVHJhY2VEZXN0aW5hdGlvblBhdGhcIjtcbi8qKiBFeHBlcmltZW50IHRhZyBuYW1pbmcgdGhlIE9UZWwgc3BhbnMgdGFibGUgKGBjYXRhbG9nLnNjaGVtYS57cHJlZml4fV9vdGVsX3NwYW5zYCkuICovXG5jb25zdCBUUkFDRV9TUEFOX1NUT1JBR0VfVEFCTEVfVEFHID0gXCJtbGZsb3cuZXhwZXJpbWVudC5kYXRhYnJpY2tzVHJhY2VTcGFuU3RvcmFnZVRhYmxlXCI7XG5cbi8qKlxuICogQ2FjaGVkIFVDIHRhYmxlIHByZWZpeCByZXNvbHZlZCBmcm9tIHRoZSBleHBlcmltZW50LiBgbG9hZGVkYCBkaXN0aW5ndWlzaGVzXG4gKiBcIm5vdCBmZXRjaGVkIHlldFwiIGZyb20gXCJmZXRjaGVkLCBleHBlcmltZW50IGhhcyBubyBVQyBsb2NhdGlvblwiLiBOZXR3b3JrXG4gKiBmYWlsdXJlcyBhcmUgbm90IGNhY2hlZCBzbyBhIGxhdGVyIHRodW1icyBjbGljayBjYW4gcmV0cnkuXG4gKi9cbmxldCBsb2FkZWRVY1ByZWZpeDogeyBwcmVmaXg6IHN0cmluZyB8IHVuZGVmaW5lZCB9IHwgdW5kZWZpbmVkO1xuXG4vKiogU3RyaXAgdGhlIGB0cmFjZTovYCBVUkkgd3JhcHBlciBhbmQgdHJhaWxpbmcgc2xhc2hlcyBmcm9tIGEgVUMgcHJlZml4LiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplVWNQcmVmaXgocmF3OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCB2YWx1ZSA9IHJhd1xuICAgID8udHJpbSgpXG4gICAgLnJlcGxhY2UoL150cmFjZTpcXC8vLCBcIlwiKVxuICAgIC5yZXBsYWNlKC9cXC8rJC8sIFwiXCIpO1xuICByZXR1cm4gdmFsdWUgfHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIERlcml2ZSBgY2F0YWxvZy5zY2hlbWEudGFibGVfcHJlZml4YCBmcm9tIGEgc3BhbnMgdGFibGUgbmFtZS5cbiAqIERhdGFicmlja3MgbmFtZXMgdGhlIHRhYmxlIGB7cHJlZml4fV9vdGVsX3NwYW5zYC5cbiAqL1xuZnVuY3Rpb24gcHJlZml4RnJvbVNwYW5UYWJsZSh0YWJsZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgbmFtZSA9IHRhYmxlPy50cmltKCk7XG4gIGlmICghbmFtZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKG5hbWUuZW5kc1dpdGgoXCJfb3RlbF9zcGFuc1wiKSkgcmV0dXJuIG5hbWUuc2xpY2UoMCwgLVwiX290ZWxfc3BhbnNcIi5sZW5ndGgpO1xuICBpZiAobmFtZS5lbmRzV2l0aChcIl9zcGFuc1wiKSkgcmV0dXJuIG5hbWUuc2xpY2UoMCwgLVwiX3NwYW5zXCIubGVuZ3RoKTtcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gZXhwZXJpbWVudFRhZ01hcChyYXc6IHVua25vd24pOiBNYXA8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgdGFncyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIGlmIChBcnJheS5pc0FycmF5KHJhdykpIHtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiByYXcpIHtcbiAgICAgIGlmICghb2JqZWN0LmlzUmVjb3JkKHRhZykgfHwgdHlwZW9mIHRhZy5rZXkgIT09IFwic3RyaW5nXCIgfHwgdHlwZW9mIHRhZy52YWx1ZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRhZ3Muc2V0KHRhZy5rZXksIHRhZy52YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiB0YWdzO1xuICB9XG4gIGlmICghb2JqZWN0LmlzUmVjb3JkKHJhdykpIHJldHVybiB0YWdzO1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhyYXcpKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikgdGFncy5zZXQoa2V5LCB2YWx1ZSk7XG4gIH1cbiAgcmV0dXJuIHRhZ3M7XG59XG5cbi8qKlxuICogVUMgdGFibGUgcHJlZml4IHRoZSBhc3Nlc3NtZW50cyBBUEkgbmVlZHMsIHJlYWQgZnJvbSBleHBlcmltZW50IHRhZ3MuXG4gKlxuICogUHJlZmVycyB0aGUgdGhyZWUtcGFydCBkZXN0aW5hdGlvbiBwYXRoIERhdGFicmlja3Mgd3JpdGVzIHdoZW4gdGhlXG4gKiBleHBlcmltZW50IGlzIGxpbmtlZCB0byBhIHRhYmxlLXByZWZpeCBsb2NhdGlvbi4gRmFsbHMgYmFjayB0byBzdHJpcHBpbmdcbiAqIGBfb3RlbF9zcGFuc2AgZnJvbSB0aGUgc3BhbnMtdGFibGUgdGFnLiBUd28tcGFydCBzY2hlbWEtbGlua2VkIGRlc3RpbmF0aW9uc1xuICogYXJlIGlnbm9yZWQgKHRoZXkgYXJlIG5vdCBhIHRhYmxlIHByZWZpeCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1Y1RyYWNlUHJlZml4RnJvbUV4cGVyaW1lbnRUYWdzKHJhd1RhZ3M6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCB0YWdzID0gZXhwZXJpbWVudFRhZ01hcChyYXdUYWdzKTtcbiAgY29uc3QgZGVzdGluYXRpb24gPSBub3JtYWxpemVVY1ByZWZpeCh0YWdzLmdldChUUkFDRV9ERVNUSU5BVElPTl9QQVRIX1RBRykpO1xuICBpZiAoZGVzdGluYXRpb24gJiYgZGVzdGluYXRpb24uc3BsaXQoXCIuXCIpLmxlbmd0aCA+PSAzKSByZXR1cm4gZGVzdGluYXRpb247XG4gIHJldHVybiBwcmVmaXhGcm9tU3BhblRhYmxlKHRhZ3MuZ2V0KFRSQUNFX1NQQU5fU1RPUkFHRV9UQUJMRV9UQUcpKTtcbn1cblxuLyoqIERyb3AgdGhlIGluLXByb2Nlc3MgVUMgcHJlZml4IGNhY2hlICh0ZXN0cykuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRVY1RyYWNlUHJlZml4Q2FjaGUoKTogdm9pZCB7XG4gIGxvYWRlZFVjUHJlZml4ID0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFRyYWNlIGlkIHRoZSBhc3Nlc3NtZW50cyBSRVNUIEFQSSBhY2NlcHRzIGZvciB0aGlzIGRlcGxveW1lbnQuXG4gKlxuICogRGF0YWJyaWNrcyBBcHBzIHBlcnNpc3QgdHJhY2VzIGluIFVuaXR5IENhdGFsb2cuIFRoZSBleHBlcmltZW50IFVJIGxpc3RzXG4gKiB0aG9zZSByb3dzLCBidXQgYFBPU1QgL2FwaS8zLjAvbWxmbG93L3RyYWNlcy97aWR9L2Fzc2Vzc21lbnRzYCBsb29rcyB1cCB0aGVcbiAqIGV4cGVyaW1lbnQgc3RvcmUgdW5sZXNzIGB7aWR9YCBpcyB0aGUgVUMgVVJJIGB0cmFjZTove2NhdGFsb2d9LntzY2hlbWF9LntwcmVmaXh9L3t0ci1oZXh9YC5cbiAqIEEgYmFyZSBgdHItPGhleD5gIDQwNHMgYW5kIHRoZSBhc3Nlc3NtZW50IG5ldmVyIGFwcGVhcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtbGZsb3dBc3Nlc3NtZW50VHJhY2VJZCh0cmFjZUlkOiBzdHJpbmcsIHByZWZpeD86IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHJlc29sdmVkID0gbm9ybWFsaXplVWNQcmVmaXgocHJlZml4KTtcbiAgcmV0dXJuIHJlc29sdmVkID8gYHRyYWNlOi8ke3Jlc29sdmVkfS8ke3RyYWNlSWR9YCA6IHRyYWNlSWQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVVY1RyYWNlUHJlZml4KGNsaWVudDogV29ya3NwYWNlQ2xpZW50KTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgZnJvbUVudiA9IG5vcm1hbGl6ZVVjUHJlZml4KHByb2Nlc3MuZW52Lk1MRkxPV19VQ19UUkFDRV9QUkVGSVgpO1xuICBpZiAoZnJvbUVudikgcmV0dXJuIGZyb21FbnY7XG4gIGlmIChsb2FkZWRVY1ByZWZpeCkgcmV0dXJuIGxvYWRlZFVjUHJlZml4LnByZWZpeDtcbiAgY29uc3QgZXhwZXJpbWVudCA9IGF3YWl0IGZldGNoRXhwZXJpbWVudChjbGllbnQpO1xuICBpZiAoIWV4cGVyaW1lbnQpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IHByZWZpeCA9IHVjVHJhY2VQcmVmaXhGcm9tRXhwZXJpbWVudFRhZ3MoZXhwZXJpbWVudC50YWdzKTtcbiAgbG9hZGVkVWNQcmVmaXggPSB7IHByZWZpeCB9O1xuICByZXR1cm4gcHJlZml4O1xufVxuXG4vKiogQXNzZXNzbWVudHMgUkVTVCBwYXRoIGZvciBhIHRyYWNlLiBgMy4wYCBpcyB0aGUgY3VycmVudCBNTGZsb3cgQVBJIHZlcnNpb24uICovXG5jb25zdCBhc3Nlc3NtZW50c1BhdGggPSAodHJhY2VJZDogc3RyaW5nKTogc3RyaW5nID0+XG4gIGAvYXBpLzMuMC9tbGZsb3cvdHJhY2VzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KHRyYWNlSWQpfS9hc3Nlc3NtZW50c2A7XG5cbi8qKiBOdW1iZXIgb2YgdGltZXMgdG8gcmV0cnkgYSBcInRyYWNlIG5vdCBmb3VuZFwiIHJlc3BvbnNlIGJlZm9yZSBnaXZpbmcgdXAuICovXG5jb25zdCBOT1RfRk9VTkRfUkVUUklFUyA9IDM7XG4vKiogQmFzZSBiYWNrb2ZmIGJldHdlZW4gXCJ0cmFjZSBub3QgZm91bmRcIiByZXRyaWVzLCBpbiBtcyAoZ3Jvd3MgbGluZWFybHkpLiAqL1xuY29uc3QgTk9UX0ZPVU5EX0JBQ0tPRkZfTVMgPSAxMjAwO1xuXG5jb25zdCBNbGZsb3dFeHBlcmltZW50UmVzcG9uc2VTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGV4cGVyaW1lbnQ6IHpcbiAgICAgIC5vYmplY3Qoe1xuICAgICAgICBleHBlcmltZW50X2lkOiB6LnN0cmluZygpLm1pbigxKS5kZXNjcmliZShcIldvcmtzcGFjZSBNTGZsb3cgZXhwZXJpbWVudCBpZGVudGlmaWVyLlwiKSxcbiAgICAgICAgdGFnczogei51bmtub3duKCkub3B0aW9uYWwoKS5kZXNjcmliZShcIkV4cGVyaW1lbnQgdGFncywgaW5jbHVkaW5nIHRoZSBVQyB0cmFjZSBsb2NhdGlvbi5cIiksXG4gICAgICB9KVxuICAgICAgLnBhc3N0aHJvdWdoKClcbiAgICAgIC5kZXNjcmliZShcIkNvbmZpZ3VyZWQgTUxmbG93IGV4cGVyaW1lbnQuXCIpLFxuICB9KVxuICAucGFzc3Rocm91Z2goKVxuICAuZGVzY3JpYmUoXCJNTGZsb3cgZ2V0LWV4cGVyaW1lbnQgcmVzcG9uc2UuXCIpO1xuXG5jb25zdCBDdXJyZW50VXNlclJlc3BvbnNlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICB1c2VyTmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiQ3VycmVudCB3b3Jrc3BhY2UgdXNlciBuYW1lLlwiKSxcbiAgICBhcHBsaWNhdGlvbklkOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJDdXJyZW50IHNlcnZpY2UgcHJpbmNpcGFsIGFwcGxpY2F0aW9uIGlkLlwiKSxcbiAgICBkaXNwbGF5TmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiQ3VycmVudCBwcmluY2lwYWwgZGlzcGxheSBuYW1lLlwiKSxcbiAgICBncm91cHM6IHpcbiAgICAgIC5hcnJheShcbiAgICAgICAgelxuICAgICAgICAgIC5vYmplY3Qoe1xuICAgICAgICAgICAgdmFsdWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZShcIldvcmtzcGFjZSBncm91cCBpZGVudGlmaWVyLlwiKSxcbiAgICAgICAgICAgIGRpc3BsYXk6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZShcIldvcmtzcGFjZSBncm91cCBkaXNwbGF5IG5hbWUuXCIpLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnBhc3N0aHJvdWdoKCksXG4gICAgICApXG4gICAgICAub3B0aW9uYWwoKVxuICAgICAgLmRlc2NyaWJlKFwiR3JvdXBzIGFzc2lnbmVkIHRvIHRoZSBjdXJyZW50IHByaW5jaXBhbC5cIiksXG4gIH0pXG4gIC5wYXNzdGhyb3VnaCgpXG4gIC5kZXNjcmliZShcIkRhdGFicmlja3MgQ3VycmVudCBVc2VyIEFQSSByZXNwb25zZS5cIik7XG5cbmNvbnN0IEV4cGVyaW1lbnRQZXJtaXNzaW9uc1Jlc3BvbnNlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBhY2Nlc3NfY29udHJvbF9saXN0OiB6XG4gICAgICAuYXJyYXkoXG4gICAgICAgIHpcbiAgICAgICAgICAub2JqZWN0KHtcbiAgICAgICAgICAgIHVzZXJfbmFtZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiVXNlciBwcmluY2lwYWwgbmFtZS5cIiksXG4gICAgICAgICAgICBncm91cF9uYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJHcm91cCBwcmluY2lwYWwgbmFtZS5cIiksXG4gICAgICAgICAgICBzZXJ2aWNlX3ByaW5jaXBhbF9uYW1lOiB6XG4gICAgICAgICAgICAgIC5zdHJpbmcoKVxuICAgICAgICAgICAgICAub3B0aW9uYWwoKVxuICAgICAgICAgICAgICAuZGVzY3JpYmUoXCJTZXJ2aWNlIHByaW5jaXBhbCBhcHBsaWNhdGlvbiBpZC5cIiksXG4gICAgICAgICAgICBhbGxfcGVybWlzc2lvbnM6IHpcbiAgICAgICAgICAgICAgLmFycmF5KFxuICAgICAgICAgICAgICAgIHpcbiAgICAgICAgICAgICAgICAgIC5vYmplY3Qoe1xuICAgICAgICAgICAgICAgICAgICBwZXJtaXNzaW9uX2xldmVsOiB6LnN0cmluZygpLmRlc2NyaWJlKFwiRWZmZWN0aXZlIGV4cGVyaW1lbnQgcGVybWlzc2lvbiBsZXZlbC5cIiksXG4gICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgLnBhc3N0aHJvdWdoKCksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgLm9wdGlvbmFsKClcbiAgICAgICAgICAgICAgLmRlc2NyaWJlKFwiRGlyZWN0IGFuZCBpbmhlcml0ZWQgcGVybWlzc2lvbnMgZm9yIHRoaXMgcHJpbmNpcGFsLlwiKSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5wYXNzdGhyb3VnaCgpLFxuICAgICAgKVxuICAgICAgLm9wdGlvbmFsKClcbiAgICAgIC5kZXNjcmliZShcIkV4cGVyaW1lbnQgYWNjZXNzIGNvbnRyb2wgZW50cmllcy5cIiksXG4gIH0pXG4gIC5wYXNzdGhyb3VnaCgpXG4gIC5kZXNjcmliZShcIkRhdGFicmlja3MgZXhwZXJpbWVudCBwZXJtaXNzaW9ucyByZXNwb25zZS5cIik7XG5cbmZ1bmN0aW9uIGNvbmZpZ3VyZWRFeHBlcmltZW50KCk6IHsgaWQ/OiBzdHJpbmc7IG5hbWU/OiBzdHJpbmcgfSB7XG4gIGNvbnN0IGlkID0gcHJvY2Vzcy5lbnYuTUxGTE9XX0VYUEVSSU1FTlRfSUQ/LnRyaW0oKTtcbiAgY29uc3QgbmFtZSA9IHByb2Nlc3MuZW52Lk1MRkxPV19FWFBFUklNRU5UX05BTUU/LnRyaW0oKTtcbiAgcmV0dXJuIHtcbiAgICAuLi4oaWQgPyB7IGlkIH0gOiB7fSksXG4gICAgLi4uKG5hbWUgPyB7IG5hbWUgfSA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIE1MZmxvdyBmZWVkYmFjayBsb2dnaW5nIGlzIGF2YWlsYWJsZSBmb3IgdGhpcyBkZXBsb3ltZW50LlxuICpcbiAqIEVuYWJsZWQgd2hlbiBhbiBPVExQIGV4cG9ydGVyIGVuZHBvaW50IGlzIGNvbmZpZ3VyZWQgKHRyYWNlcyBhcmVcbiAqIGFjdHVhbGx5IHNoaXBwZWQgc29tZXdoZXJlKSBBTkQgYW4gTUxmbG93IGV4cGVyaW1lbnQgaXMgbmFtZWQgLSB0aGVcbiAqIHR3byBzaWduYWxzIHRoYXQgdGhlIE9UTFAgYmFja2VuZCBpcyBNTGZsb3cgYW5kIHRyYWNlcyB3aWxsXG4gKiBtYXRlcmlhbGl6ZSB0aGVyZS4gQm90aCBhcmUgc3RhbmRhcmQgZW52IHZhcnMsIHNvIG5vIHBsdWdpbiBjb25maWcgaXNcbiAqIHJlcXVpcmVkOyBhIGRlcGxveW1lbnQgb3B0cyBpbiBzaW1wbHkgYnkgd2lyaW5nIE1MZmxvdyB0cmFjaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWxmbG93RW5hYmxlZCgpOiBib29sZWFuIHtcbiAgY29uc3QgaGFzRXhwb3J0ZXIgPSBCb29sZWFuKFxuICAgIHByb2Nlc3MuZW52Lk9URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVD8udHJpbSgpIHx8XG4gICAgcHJvY2Vzcy5lbnYuT1RFTF9FWFBPUlRFUl9PVExQX1RSQUNFU19FTkRQT0lOVD8udHJpbSgpLFxuICApO1xuICBjb25zdCBoYXNFeHBlcmltZW50ID0gQm9vbGVhbihcbiAgICBwcm9jZXNzLmVudi5NTEZMT1dfRVhQRVJJTUVOVF9JRD8udHJpbSgpIHx8IHByb2Nlc3MuZW52Lk1MRkxPV19FWFBFUklNRU5UX05BTUU/LnRyaW0oKSxcbiAgKTtcbiAgcmV0dXJuIGhhc0V4cG9ydGVyICYmIGhhc0V4cGVyaW1lbnQ7XG59XG5cbi8qKlxuICogUmVzb2x2ZSB3aGV0aGVyIHVzZXIgZmVlZGJhY2sgaXMgZW5hYmxlZCBmcm9tIHRoZSBwbHVnaW4ncyBvcHRpb25hbFxuICogYGNvbmZpZy5mZWVkYmFja2Agb3ZlcnJpZGU6IHRoZSBleHBsaWNpdCBib29sZWFuIHdpbnMsIG90aGVyd2lzZSBmYWxsXG4gKiBiYWNrIHRvIGF1dG8tZGV0ZWN0aW5nIE1MZmxvdyB0cmFjaW5nICh7QGxpbmsgbWxmbG93RW5hYmxlZH0pLiBTaGFyZWRcbiAqIGJ5IHRoZSBwbHVnaW4ncyBjbGllbnQtY29uZmlnIGdhdGUgYW5kIHRoZSBzZXJ2ZXIncyB0cmFjZS1pZCBoZWFkZXIgc29cbiAqIHRoZSB0d28gbmV2ZXIgZGlzYWdyZWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRmVlZGJhY2tFbmFibGVkKGV4cGxpY2l0OiBib29sZWFuIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIHJldHVybiBleHBsaWNpdCA/PyBtbGZsb3dFbmFibGVkKCk7XG59XG5cbi8qKlxuICogUmVqZWN0IGFuIGV4cGxpY2l0bHkgZW5hYmxlZCBmZWVkYmFjayBzdXJmYWNlIHdoZW4gbm8gTUxmbG93IGV4cGVyaW1lbnQgaXNcbiAqIGNvbmZpZ3VyZWQuIEF1dG8gbW9kZSByZW1haW5zIG5vbi1mYXRhbCBhbmQgc2ltcGx5IGRpc2FibGVzIGZlZWRiYWNrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVGZWVkYmFja0NvbmZpZyhleHBsaWNpdDogYm9vbGVhbiB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICBpZiAoZXhwbGljaXQgIT09IHRydWUpIHJldHVybjtcbiAgY29uc3QgZXhwZXJpbWVudCA9IGNvbmZpZ3VyZWRFeHBlcmltZW50KCk7XG4gIGlmIChleHBlcmltZW50LmlkIHx8IGV4cGVyaW1lbnQubmFtZSkgcmV0dXJuO1xuICB0aHJvdyBuZXcgQ29uZmlndXJhdGlvbkVycm9yKFxuICAgIFwibWFzdHJhOiBmZWVkYmFjayBpcyBlbmFibGVkIGJ1dCBubyBNTGZsb3cgZXhwZXJpbWVudCBpcyBjb25maWd1cmVkLiBcIiArXG4gICAgICBcIlNldCBNTEZMT1dfRVhQRVJJTUVOVF9JRCBvciBNTEZMT1dfRVhQRVJJTUVOVF9OQU1FLCB1c2UgZmVlZGJhY2s6IGZhbHNlLCBcIiArXG4gICAgICBcIm9yIG9taXQgZmVlZGJhY2sgdG8gdXNlIGF1dG9tYXRpYyBkZXRlY3Rpb24uXCIsXG4gICk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBjb25maWd1cmVkIGV4cGVyaW1lbnQgVVJMIG9ubHkgd2hlbiB0aGUgYWN0aXZlIERhdGFicmlja3NcbiAqIHByaW5jaXBhbCBoYXMgZWZmZWN0aXZlIGBDQU5fTUFOQUdFYCBwZXJtaXNzaW9uLiBQZXJtaXNzaW9uIGxvb2t1cCBpc1xuICogaW50ZW50aW9uYWxseSBiZXN0LWVmZm9ydCBzbyBBcHBzIGVudmlyb25tZW50cyB0aGF0IGRvIG5vdCBleHBvc2UgdGhlXG4gKiByZXF1aXJlZCBBUElzIHNpbXBseSBvbWl0IHRoZSBkZWJ1ZyBhZmZvcmRhbmNlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWxmbG93RXhwZXJpbWVudE1hbmFnZXJVcmwoXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50LFxuKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgcmVzb2x2ZU1sZmxvd0V4cGVyaW1lbnRNYW5hZ2VyVXJsKGNsaWVudCk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZU1sZmxvd0V4cGVyaW1lbnRNYW5hZ2VyVXJsKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCxcbik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGV4cGVyaW1lbnRJZCA9IGF3YWl0IHJlc29sdmVFeHBlcmltZW50SWQoY2xpZW50KTtcbiAgaWYgKCFleHBlcmltZW50SWQpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgW2N1cnJlbnRSZXNwb25zZSwgcGVybWlzc2lvbnNSZXNwb25zZV0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgZGF0YWJyaWNrc0ZldGNoKGNsaWVudCwgXCIvYXBpLzIuMC9wcmV2aWV3L3NjaW0vdjIvTWVcIiwgeyBtZXRob2Q6IFwiR0VUXCIgfSksXG4gICAgZGF0YWJyaWNrc0ZldGNoKFxuICAgICAgY2xpZW50LFxuICAgICAgYC9hcGkvMi4wL3Blcm1pc3Npb25zL2V4cGVyaW1lbnRzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGV4cGVyaW1lbnRJZCl9YCxcbiAgICAgIHsgbWV0aG9kOiBcIkdFVFwiIH0sXG4gICAgKSxcbiAgXSk7XG4gIGlmICghY3VycmVudFJlc3BvbnNlLm9rIHx8ICFwZXJtaXNzaW9uc1Jlc3BvbnNlLm9rKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGN1cnJlbnQgPSBDdXJyZW50VXNlclJlc3BvbnNlU2NoZW1hLnNhZmVQYXJzZShhd2FpdCByZWFkUmVzcG9uc2VKc29uKGN1cnJlbnRSZXNwb25zZSkpO1xuICBjb25zdCBwZXJtaXNzaW9ucyA9IEV4cGVyaW1lbnRQZXJtaXNzaW9uc1Jlc3BvbnNlU2NoZW1hLnNhZmVQYXJzZShcbiAgICBhd2FpdCByZWFkUmVzcG9uc2VKc29uKHBlcm1pc3Npb25zUmVzcG9uc2UpLFxuICApO1xuICBpZiAoIWN1cnJlbnQuc3VjY2VzcyB8fCAhcGVybWlzc2lvbnMuc3VjY2VzcykgcmV0dXJuIHVuZGVmaW5lZDtcblxuICBjb25zdCB1c2VyTmFtZXMgPSBuZXcgU2V0KFxuICAgIFtjdXJyZW50LmRhdGEudXNlck5hbWUsIGN1cnJlbnQuZGF0YS5hcHBsaWNhdGlvbklkLCBjdXJyZW50LmRhdGEuZGlzcGxheU5hbWVdLmZpbHRlcihcbiAgICAgICh2YWx1ZSk6IHZhbHVlIGlzIHN0cmluZyA9PiBCb29sZWFuKHZhbHVlKSxcbiAgICApLFxuICApO1xuICBjb25zdCBncm91cE5hbWVzID0gbmV3IFNldChcbiAgICAoY3VycmVudC5kYXRhLmdyb3VwcyA/PyBbXSkuZmxhdE1hcCgoeyB2YWx1ZSwgZGlzcGxheSB9KSA9PlxuICAgICAgW3ZhbHVlLCBkaXNwbGF5XS5maWx0ZXIoKGVudHJ5KTogZW50cnkgaXMgc3RyaW5nID0+IEJvb2xlYW4oZW50cnkpKSxcbiAgICApLFxuICApO1xuICBjb25zdCBjYW5NYW5hZ2UgPSAocGVybWlzc2lvbnMuZGF0YS5hY2Nlc3NfY29udHJvbF9saXN0ID8/IFtdKS5zb21lKChlbnRyeSkgPT4ge1xuICAgIGNvbnN0IG1hdGNoZXMgPVxuICAgICAgKGVudHJ5LnVzZXJfbmFtZSAhPT0gdW5kZWZpbmVkICYmIHVzZXJOYW1lcy5oYXMoZW50cnkudXNlcl9uYW1lKSkgfHxcbiAgICAgIChlbnRyeS5zZXJ2aWNlX3ByaW5jaXBhbF9uYW1lICE9PSB1bmRlZmluZWQgJiYgdXNlck5hbWVzLmhhcyhlbnRyeS5zZXJ2aWNlX3ByaW5jaXBhbF9uYW1lKSkgfHxcbiAgICAgIChlbnRyeS5ncm91cF9uYW1lICE9PSB1bmRlZmluZWQgJiYgZ3JvdXBOYW1lcy5oYXMoZW50cnkuZ3JvdXBfbmFtZSkpO1xuICAgIHJldHVybiAoXG4gICAgICBtYXRjaGVzICYmXG4gICAgICAoZW50cnkuYWxsX3Blcm1pc3Npb25zID8/IFtdKS5zb21lKFxuICAgICAgICAocGVybWlzc2lvbikgPT4gcGVybWlzc2lvbi5wZXJtaXNzaW9uX2xldmVsID09PSBcIkNBTl9NQU5BR0VcIixcbiAgICAgIClcbiAgICApO1xuICB9KTtcbiAgaWYgKCFjYW5NYW5hZ2UpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgaG9zdCA9IChhd2FpdCBjbGllbnQuY29uZmlnLmdldEhvc3QoKSkudG9TdHJpbmcoKTtcbiAgcmV0dXJuIG5ldyBVUkwoYC9tbC9leHBlcmltZW50cy8ke2VuY29kZVVSSUNvbXBvbmVudChleHBlcmltZW50SWQpfWAsIGhvc3QpLnRvU3RyaW5nKCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoRXhwZXJpbWVudChcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQsXG4pOiBQcm9taXNlPHsgZXhwZXJpbWVudF9pZDogc3RyaW5nOyB0YWdzPzogdW5rbm93biB9IHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGV4cGVyaW1lbnQgPSBjb25maWd1cmVkRXhwZXJpbWVudCgpO1xuICBjb25zdCBwYXRoID0gZXhwZXJpbWVudC5pZFxuICAgID8gYC9hcGkvMi4wL21sZmxvdy9leHBlcmltZW50cy9nZXQ/ZXhwZXJpbWVudF9pZD0ke2VuY29kZVVSSUNvbXBvbmVudChleHBlcmltZW50LmlkKX1gXG4gICAgOiBleHBlcmltZW50Lm5hbWVcbiAgICAgID8gYC9hcGkvMi4wL21sZmxvdy9leHBlcmltZW50cy9nZXQtYnktbmFtZT9leHBlcmltZW50X25hbWU9JHtlbmNvZGVVUklDb21wb25lbnQoXG4gICAgICAgICAgZXhwZXJpbWVudC5uYW1lLFxuICAgICAgICApfWBcbiAgICAgIDogdW5kZWZpbmVkO1xuICBpZiAoIXBhdGgpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZGF0YWJyaWNrc0ZldGNoKGNsaWVudCwgcGF0aCwgeyBtZXRob2Q6IFwiR0VUXCIgfSk7XG4gIGlmICghcmVzcG9uc2Uub2spIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IHBhcnNlZCA9IE1sZmxvd0V4cGVyaW1lbnRSZXNwb25zZVNjaGVtYS5zYWZlUGFyc2UoYXdhaXQgcmVhZFJlc3BvbnNlSnNvbihyZXNwb25zZSkpO1xuICByZXR1cm4gcGFyc2VkLnN1Y2Nlc3MgPyBwYXJzZWQuZGF0YS5leHBlcmltZW50IDogdW5kZWZpbmVkO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlRXhwZXJpbWVudElkKGNsaWVudDogV29ya3NwYWNlQ2xpZW50KTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgY29uZmlndXJlZCA9IGNvbmZpZ3VyZWRFeHBlcmltZW50KCk7XG4gIGlmIChjb25maWd1cmVkLmlkKSByZXR1cm4gY29uZmlndXJlZC5pZDtcbiAgcmV0dXJuIChhd2FpdCBmZXRjaEV4cGVyaW1lbnQoY2xpZW50KSk/LmV4cGVyaW1lbnRfaWQ7XG59XG5cbi8qKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgbG9nRmVlZGJhY2t9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBMb2dGZWVkYmFja1BhcmFtcyB7XG4gIC8qKiBNTGZsb3cgdHJhY2UgaWQgdGhlIGFzc2Vzc21lbnQgYXR0YWNoZXMgdG8gKGB0ci08aGV4PmApLiAqL1xuICB0cmFjZUlkOiBzdHJpbmc7XG4gIC8qKiBBc3Nlc3NtZW50IG5hbWU7IGRlZmF1bHRzIHBlciB3aGV0aGVyIGEgdmFsdWUgb3IgYSBjb21tZW50IGlzIHNlbnQuICovXG4gIG5hbWU/OiBzdHJpbmc7XG4gIC8qKiBUaHVtYnMgLyByYXRpbmcgLyBsYWJlbCB2YWx1ZS4gT21pdCBmb3IgYSBjb21tZW50LW9ubHkgc3VibWlzc2lvbi4gKi9cbiAgdmFsdWU/OiBib29sZWFuIHwgbnVtYmVyIHwgc3RyaW5nO1xuICAvKiogRnJlZWZvcm0gY29tbWVudDogdGhlIHJhdGlvbmFsZSBhbG9uZ3NpZGUgYSB2YWx1ZSwgb3IgdGhlIHZhbHVlIGl0c2VsZiB3aGVuIG5vbmUuICovXG4gIGNvbW1lbnQ/OiBzdHJpbmc7XG4gIC8qKiBJZGVudGl0eSB0aGUgZmVlZGJhY2sgaXMgYXR0cmlidXRlZCB0byAodXNlciBlbWFpbCAvIGlkKS4gKi9cbiAgc291cmNlSWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogTG9nIGEgSFVNQU4gZmVlZGJhY2sgYXNzZXNzbWVudCB0byBhIHRyYWNlLiBSZXR1cm5zIHRoZSBjcmVhdGVkXG4gKiBhc3Nlc3NtZW50IGlkIG9uIHN1Y2Nlc3MsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlIHRyYWNlIGNhbid0IGJlXG4gKiBmb3VuZCAoZXZlbiBhZnRlciByZXRyeWluZyBmb3IgZXhwb3J0IGxhZykgb3IgdGhlIHJlcXVlc3Qgb3RoZXJ3aXNlXG4gKiBmYWlscyAtIGNhbGxlcnMgc3VyZmFjZSB0aGF0IGFzIGEgc29mdCBcIm5vdCByZWNvcmRlZFwiIHJhdGhlciB0aGFuIGFuXG4gKiBlcnJvciwga2VlcGluZyB0aGUgY2hhdCB1c2FibGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2dGZWVkYmFjayhcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQsXG4gIHBhcmFtczogTG9nRmVlZGJhY2tQYXJhbXMsXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICAvLyBBIGNvbW1lbnQgd2l0aCBubyB0aHVtYnMgdmFsdWUgaXMgbG9nZ2VkIGFzIHRleHQgZmVlZGJhY2s7IGEgdmFsdWVcbiAgLy8gKHdpdGggYW4gb3B0aW9uYWwgY29tbWVudCBhcyB0aGUgcmF0aW9uYWxlKSBpcyB0aGUgdGh1bWJzIHBhdGguXG4gIGNvbnN0IGhhc1ZhbHVlID0gcGFyYW1zLnZhbHVlICE9PSB1bmRlZmluZWQ7XG4gIGNvbnN0IG5hbWUgPVxuICAgIHBhcmFtcy5uYW1lPy50cmltKCkgfHxcbiAgICAoaGFzVmFsdWUgPyBmZWVkYmFjay5ERUZBVUxUX0ZFRURCQUNLX05BTUUgOiBmZWVkYmFjay5ERUZBVUxUX0NPTU1FTlRfTkFNRSk7XG4gIGNvbnN0IHZhbHVlID0gaGFzVmFsdWUgPyBwYXJhbXMudmFsdWUgOiBwYXJhbXMuY29tbWVudDtcbiAgY29uc3QgYXNzZXNzbWVudFRyYWNlSWQgPSBtbGZsb3dBc3Nlc3NtZW50VHJhY2VJZChcbiAgICBwYXJhbXMudHJhY2VJZCxcbiAgICBhd2FpdCByZXNvbHZlVWNUcmFjZVByZWZpeChjbGllbnQpLFxuICApO1xuICBjb25zdCBhc3Nlc3NtZW50OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHtcbiAgICB0cmFjZV9pZDogYXNzZXNzbWVudFRyYWNlSWQsXG4gICAgYXNzZXNzbWVudF9uYW1lOiBuYW1lLFxuICAgIHNvdXJjZToge1xuICAgICAgc291cmNlX3R5cGU6IFwiSFVNQU5cIixcbiAgICAgIHNvdXJjZV9pZDogcGFyYW1zLnNvdXJjZUlkPy50cmltKCkgfHwgXCJ1c2VyXCIsXG4gICAgfSxcbiAgICBmZWVkYmFjazogeyB2YWx1ZSB9LFxuICAgIC4uLihoYXNWYWx1ZSAmJiBwYXJhbXMuY29tbWVudD8udHJpbSgpID8geyByYXRpb25hbGU6IHBhcmFtcy5jb21tZW50IH0gOiB7fSksXG4gIH07XG4gIGNvbnN0IGJvZHkgPSB7IGFzc2Vzc21lbnQgfTtcblxuICBmb3IgKGxldCBhdHRlbXB0ID0gMDsgYXR0ZW1wdCA8PSBOT1RfRk9VTkRfUkVUUklFUzsgYXR0ZW1wdCsrKSB7XG4gICAgbGV0IHJlczogUmVzcG9uc2U7XG4gICAgdHJ5IHtcbiAgICAgIHJlcyA9IGF3YWl0IGRhdGFicmlja3NGZXRjaChjbGllbnQsIGFzc2Vzc21lbnRzUGF0aChhc3Nlc3NtZW50VHJhY2VJZCksIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgYm9keSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgbG9nZ2VyLndhcm4oXCJmZWVkYmFjayByZXF1ZXN0IGZhaWxlZFwiLCB7XG4gICAgICAgIHRyYWNlSWQ6IHBhcmFtcy50cmFjZUlkLFxuICAgICAgICBhc3Nlc3NtZW50VHJhY2VJZCxcbiAgICAgICAgZXJyb3I6IGVycm9yVXRpbHMuZXJyb3JNZXNzYWdlKGVyciksXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmIChyZXMub2spIHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IGF3YWl0IHJlYWRSZXNwb25zZUpzb24ocmVzKTtcbiAgICAgIGNvbnN0IGFzc2Vzc21lbnRJZCA9XG4gICAgICAgIChwYXJzZWQgYXMgeyBhc3Nlc3NtZW50PzogeyBhc3Nlc3NtZW50X2lkPzogdW5rbm93biB9IH0pPy5hc3Nlc3NtZW50Py5hc3Nlc3NtZW50X2lkID8/XG4gICAgICAgIChwYXJzZWQgYXMgeyBhc3Nlc3NtZW50X2lkPzogdW5rbm93biB9KT8uYXNzZXNzbWVudF9pZDtcbiAgICAgIHJldHVybiB0eXBlb2YgYXNzZXNzbWVudElkID09PSBcInN0cmluZ1wiID8gYXNzZXNzbWVudElkIDogXCJcIjtcbiAgICB9XG4gICAgLy8gVHJhY2UgZXhwb3J0IGlzIGFzeW5jOyBhIGZyZXNoIHRyYWNlIG1heSBub3QgZXhpc3QgeWV0LiBSZXRyeSBhXG4gICAgLy8gZmV3IHRpbWVzIHdpdGggYSBzaG9ydCBiYWNrb2ZmIGJlZm9yZSBnaXZpbmcgdXAgc29mdGx5LlxuICAgIGlmIChyZXMuc3RhdHVzID09PSA0MDQgJiYgYXR0ZW1wdCA8IE5PVF9GT1VORF9SRVRSSUVTKSB7XG4gICAgICBhd2FpdCBhc3luY1V0aWxzLnNsZWVwKE5PVF9GT1VORF9CQUNLT0ZGX01TICogKGF0dGVtcHQgKyAxKSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgbG9nZ2VyLndhcm4oXCJmZWVkYmFjayBub3QgcmVjb3JkZWRcIiwge1xuICAgICAgdHJhY2VJZDogcGFyYW1zLnRyYWNlSWQsXG4gICAgICBhc3Nlc3NtZW50VHJhY2VJZCxcbiAgICAgIHN0YXR1czogcmVzLnN0YXR1cyxcbiAgICAgIGJvZHk6IGF3YWl0IHJlYWRSZXNwb25zZVRleHQocmVzKSxcbiAgICB9KTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG4iXX0=
665
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWxmbG93LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21sZmxvdy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUVILE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0UsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDdkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDZDQUE2QyxDQUFDO0FBUXpFLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDeEIsT0FBTyxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNoRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUU5RCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBSzNDLElBQUksWUFBc0MsQ0FBQztBQUMzQyxJQUFJLHVCQUF1QixHQUFHLEtBQUssQ0FBQztBQUNwQyxJQUFJLG9CQUFvRCxDQUFDO0FBQ3pELElBQUkscUJBQWdELENBQUM7QUFDckQsSUFBSSw2QkFBNkIsR0FBRyxLQUFLLENBQUM7QUFDMUMsSUFBSSx3QkFBcUQsQ0FBQztBQUMxRCxJQUFJLG9CQUF3QyxDQUFDO0FBQzdDLE1BQU0seUJBQXlC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TGZsb3cgdXNlci1mZWVkYmFjayBsb2dnaW5nOiBkZXRlY3Qgd2hldGhlciBNTGZsb3cgdHJhY2luZyBpcyB3aXJlZFxuICogZm9yIHRoaXMgZGVwbG95bWVudCwgYW5kIGxvZyBhIHRodW1icyAvIGNvbW1lbnQgYXMgYSB0cmFjZVxuICogKmFzc2Vzc21lbnQqIHZpYSB0aGUgRGF0YWJyaWNrcyBNTGZsb3cgUkVTVCBBUEkuXG4gKlxuICogRmVlZGJhY2sgYXR0YWNoZXMgdG8gYSB0cmFjZSwgYW5kIHRoZSBwbHVnaW4ncyBzcGFucyByZWFjaCBNTGZsb3dcbiAqIHRocm91Z2ggdGhlIHNhbWUgT1RlbCBwaXBlbGluZSBhcyBldmVyeSBvdGhlciBBcHBLaXQgc3BhbiAoc2VlXG4gKiBgb2JzZXJ2YWJpbGl0eS50c2ApLiBPbiBEYXRhYnJpY2tzIEFwcHMgdGhhdCBwaXBlbGluZSBpcyB0aGUgVUNcbiAqIHNpZGVjYXIgaW5qZWN0ZWQgYnkgYHRlbGVtZXRyeV9leHBvcnRfZGVzdGluYXRpb25zYCwgbm90IGEgZGlyZWN0XG4gKiB3b3Jrc3BhY2UgT1RMUCBVUkwuIE1MZmxvdyBkZXJpdmVzIGl0cyB0cmFjZSBpZCBmcm9tIHRoZSBPcGVuVGVsZW1ldHJ5XG4gKiB0cmFjZSBpZCAoYHRyLTxoZXgob3RlbFRyYWNlSWQpPmApLCBzbyB0aGUgc2VydmVyIHN0YW1wcyB0aGUgYWN0aXZlXG4gKiB0cmFjZSBpZCBvbiBlYWNoIHR1cm4ncyByZXNwb25zZSBhbmQgdGhlIGNsaWVudCBzZW5kcyBpdCBiYWNrIGhlcmUuXG4gKlxuICogVGhlcmUgaXMgbm8gTUxmbG93IEpTIFNESywgc28gdGhpcyBwb3N0cyB0byB0aGUgYXNzZXNzbWVudHMgUkVTVFxuICogZW5kcG9pbnQgZGlyZWN0bHkgdXNpbmcgdGhlIE9CTy1zY29wZWQgd29ya3NwYWNlIGNsaWVudCAodGhlIGZlZWRiYWNrXG4gKiBpcyB0aHVzIGF0dHJpYnV0ZWQgdG8gdGhlIHNpZ25lZC1pbiB1c2VyKS4gVUMtYmFja2VkIEFwcHMgdHJhY2VzIG5lZWRcbiAqIHRoZSBleHBlcmltZW50J3MgdGFibGUtcHJlZml4IFVSSSAoYHRyYWNlOi97Y2F0YWxvZ30ue3NjaGVtYX0ue3ByZWZpeH0ve3RyLWhleH1gKVxuICogcmF0aGVyIHRoYW4gdGhlIGV4cGVyaW1lbnQtc3RvcmUgaWQgdGhlIFVJIGRvZXMgbm90IHN0b3JlLiBUaGF0IHByZWZpeCBpc1xuICogcmVhZCBmcm9tIHRoZSBleHBlcmltZW50J3MgYG1sZmxvdy5leHBlcmltZW50LmRhdGFicmlja3NUcmFjZURlc3RpbmF0aW9uUGF0aGBcbiAqIHRhZyAob3IgdGhlIHNwYW5zLXRhYmxlIHRhZyk7IGBNTEZMT1dfVUNfVFJBQ0VfUFJFRklYYCByZW1haW5zIGFuIG9wdGlvbmFsXG4gKiBvdmVycmlkZS4gVHJhY2UgZXhwb3J0IGlzIGFzeW5jaHJvbm91cywgc28gdGhlIGp1c3QtZmluaXNoZWQgdHJhY2UgbWF5IG5vdFxuICogZXhpc3QgaW4gTUxmbG93IHlldCB3aGVuIHRoZSB1c2VyIHJlYWN0czsgdGhlIGxvZyBjYWxsIHJldHJpZXMgYnJpZWZseSBvblxuICogXCJub3QgZm91bmRcIiBiZWZvcmUgZ2l2aW5nIHVwIHNvZnRseS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgQ29uZmlndXJhdGlvbkVycm9yLCBjcmVhdGVXb3Jrc3BhY2VDbGllbnQgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBhcHBraXQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGFzeW5jVXRpbHMsIGVycm9yVXRpbHMsIGxvZywgb2JqZWN0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGZlZWRiYWNrIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1hc3RyYVwiO1xuaW1wb3J0IHsgVHJhY2VMb2NhdGlvblR5cGUsIFRyYWNlTWV0YWRhdGFLZXkgfSBmcm9tIFwiQG1sZmxvdy9jb3JlXCI7XG5pbXBvcnQgeyBUcmFjZUluZm8gfSBmcm9tIFwiQG1sZmxvdy9jb3JlL2Rpc3QvY29yZS9lbnRpdGllcy90cmFjZV9pbmZvXCI7XG5pbXBvcnQgeyBUcmFjZVN0YXRlIH0gZnJvbSBcIkBtbGZsb3cvY29yZS9kaXN0L2NvcmUvZW50aXRpZXMvdHJhY2Vfc3RhdGVcIjtcbmltcG9ydCB0eXBlIHsgQ29udGV4dCB9IGZyb20gXCJAb3BlbnRlbGVtZXRyeS9hcGlcIjtcbmltcG9ydCB0eXBlIHtcbiAgUmVhZGFibGVTcGFuLFxuICBTcGFuIGFzIFNka1NwYW4sXG4gIFNwYW5Qcm9jZXNzb3IsXG59IGZyb20gXCJAb3BlbnRlbGVtZXRyeS9zZGstdHJhY2UtYmFzZVwiO1xuaW1wb3J0IHR5cGUgeyBOb2RlVHJhY2VyUHJvdmlkZXIgfSBmcm9tIFwiQG9wZW50ZWxlbWV0cnkvc2RrLXRyYWNlLW5vZGVcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyBkYXRhYnJpY2tzRmV0Y2gsIHJlYWRSZXNwb25zZUpzb24sIHJlYWRSZXNwb25zZVRleHQgfSBmcm9tIFwiLi9yZXN0LnRzXCI7XG5pbXBvcnQgeyBNTEZMT1dfQUdFTlRfVEFHX0FUVFIgfSBmcm9tIFwiLi90cmFjZS1hdHRyaWJ1dGVzLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtYXN0cmEvbWxmbG93XCIpO1xuXG50eXBlIE1sZmxvd01vZHVsZSA9IHR5cGVvZiBpbXBvcnQoXCJAbWxmbG93L2NvcmVcIik7XG50eXBlIFVwZGF0ZUN1cnJlbnRUcmFjZU9wdGlvbnMgPSBQYXJhbWV0ZXJzPE1sZmxvd01vZHVsZVtcInVwZGF0ZUN1cnJlbnRUcmFjZVwiXT5bMF07XG5cbmxldCBkaXJlY3RNbGZsb3c6IE1sZmxvd01vZHVsZSB8IHVuZGVmaW5lZDtcbmxldCBkaXJlY3RNbGZsb3dJbml0U3RhcnRlZCA9IGZhbHNlO1xubGV0IGRpcmVjdE1sZmxvd1Byb3ZpZGVyOiBOb2RlVHJhY2VyUHJvdmlkZXIgfCB1bmRlZmluZWQ7XG5sZXQgZGlyZWN0TWxmbG93UHJvY2Vzc29yOiBTcGFuUHJvY2Vzc29yIHwgdW5kZWZpbmVkO1xubGV0IGFwcE1sZmxvd1RyYWNlSW5mb0luaXRTdGFydGVkID0gZmFsc2U7XG5sZXQgYXBwTWxmbG93VHJhY2VJbmZvQ2xpZW50OiBXb3Jrc3BhY2VDbGllbnQgfCB1bmRlZmluZWQ7XG5sZXQgYXBwTWxmbG93VHJhY2VQcmVmaXg6IHN0cmluZyB8IHVuZGVmaW5lZDtcbmNvbnN0IHBlbmRpbmdBcHBNbGZsb3dUcmFjZUluZm8gPSBuZXcgU2V0PFByb21pc2U8dm9pZD4+KCk7XG5cbmNvbnN0IE5PSVNZX0lOU1RSVU1FTlRBVElPTl9TQ09QRVMgPSBuZXcgU2V0KFtcbiAgXCJAb3BlbnRlbGVtZXRyeS9pbnN0cnVtZW50YXRpb24tZXhwcmVzc1wiLFxuICBcIkBvcGVudGVsZW1ldHJ5L2luc3RydW1lbnRhdGlvbi1odHRwXCIsXG4gIFwiY2FjaGUtbWFuYWdlci1jYWNoZS1tYW5hZ2VyXCIsXG5dKTtcblxuZnVuY3Rpb24gaXNBZ2VudFRyYWNlUm9vdChzcGFuOiBTZGtTcGFuKTogYm9vbGVhbiB7XG4gIHJldHVybiBzcGFuLmF0dHJpYnV0ZXNbTUxGTE9XX0FHRU5UX1RBR19BVFRSXSA9PT0gXCJ0cnVlXCI7XG59XG5cbmZ1bmN0aW9uIGlzVXNlZnVsQWdlbnREZXNjZW5kYW50KHNwYW46IFNka1NwYW4pOiBib29sZWFuIHtcbiAgcmV0dXJuICFOT0lTWV9JTlNUUlVNRU5UQVRJT05fU0NPUEVTLmhhcyhzcGFuLmluc3RydW1lbnRhdGlvblNjb3BlLm5hbWUpO1xufVxuXG4vKipcbiAqIFJlc3RyaWN0IHRoZSBkaXJlY3QgTUxmbG93IHByb3ZpZGVyIHRvIGNoYXQgcm9vdHMgYW5kIHRoZWlyIGRlc2NlbmRhbnRzLlxuICogQXBwS2l0IGFuZCBNYXN0cmEgY3JlYXRlIG90aGVyIE9UZWwgcm9vdHMgZm9yIGNhY2hlIGFuZCBwbHVnaW4gb3BlcmF0aW9ucztcbiAqIGZvcndhcmRpbmcgdGhvc2Ugd291bGQgcmVjcmVhdGUgdGhlIG9uZS10cmFjZS1wZXItcmVxdWVzdCBub2lzZSB0aGlzIHBhdGggaXNcbiAqIGludGVuZGVkIHRvIGF2b2lkLlxuICovXG5leHBvcnQgY2xhc3MgQWdlbnRUcmFjZVNwYW5Qcm9jZXNzb3IgaW1wbGVtZW50cyBTcGFuUHJvY2Vzc29yIHtcbiAgcHJpdmF0ZSByZWFkb25seSB0cmFjZUlkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHNwYW5JZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGRlbGVnYXRlOiBTcGFuUHJvY2Vzc29yKSB7fVxuXG4gIG9uU3RhcnQoc3BhbjogU2RrU3BhbiwgcGFyZW50Q29udGV4dDogQ29udGV4dCk6IHZvaWQge1xuICAgIGNvbnN0IHRyYWNlSWQgPSBzcGFuLnNwYW5Db250ZXh0KCkudHJhY2VJZDtcbiAgICBjb25zdCBpc1Jvb3QgPSAhc3Bhbi5wYXJlbnRTcGFuQ29udGV4dD8uc3BhbklkO1xuICAgIGlmIChpc1Jvb3QpIHtcbiAgICAgIGlmICghaXNBZ2VudFRyYWNlUm9vdChzcGFuKSkgcmV0dXJuO1xuICAgICAgdGhpcy50cmFjZUlkcy5hZGQodHJhY2VJZCk7XG4gICAgfSBlbHNlIGlmICghdGhpcy50cmFjZUlkcy5oYXModHJhY2VJZCkgfHwgIWlzVXNlZnVsQWdlbnREZXNjZW5kYW50KHNwYW4pKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc3Bhbklkcy5hZGQoc3Bhbi5zcGFuQ29udGV4dCgpLnNwYW5JZCk7XG4gICAgdGhpcy5kZWxlZ2F0ZS5vblN0YXJ0KHNwYW4sIHBhcmVudENvbnRleHQpO1xuICB9XG5cbiAgb25FbmRpbmcoc3BhbjogU2RrU3Bhbik6IHZvaWQge1xuICAgIGlmICghdGhpcy5zcGFuSWRzLmhhcyhzcGFuLnNwYW5Db250ZXh0KCkuc3BhbklkKSkgcmV0dXJuO1xuICAgIHRoaXMuZGVsZWdhdGUub25FbmRpbmc/LihzcGFuKTtcbiAgfVxuXG4gIG9uRW5kKHNwYW46IFJlYWRhYmxlU3Bhbik6IHZvaWQge1xuICAgIGNvbnN0IHRyYWNlSWQgPSBzcGFuLnNwYW5Db250ZXh0KCkudHJhY2VJZDtcbiAgICBjb25zdCBzcGFuSWQgPSBzcGFuLnNwYW5Db250ZXh0KCkuc3BhbklkO1xuICAgIGlmICghdGhpcy5zcGFuSWRzLmRlbGV0ZShzcGFuSWQpKSByZXR1cm47XG4gICAgdGhpcy5kZWxlZ2F0ZS5vbkVuZChzcGFuKTtcbiAgICBpZiAoIXNwYW4ucGFyZW50U3BhbkNvbnRleHQ/LnNwYW5JZCkgdGhpcy50cmFjZUlkcy5kZWxldGUodHJhY2VJZCk7XG4gIH1cblxuICBmb3JjZUZsdXNoKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmRlbGVnYXRlLmZvcmNlRmx1c2goKTtcbiAgfVxuXG4gIHNodXRkb3duKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMudHJhY2VJZHMuY2xlYXIoKTtcbiAgICB0aGlzLnNwYW5JZHMuY2xlYXIoKTtcbiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZS5zaHV0ZG93bigpO1xuICB9XG59XG5cbi8qKiBXb3Jrc3BhY2UgY2xpZW50IGNhcnJpZWQgb24gYW4gQXBwS2l0IGV4ZWN1dGlvbiBjb250ZXh0LiAqL1xudHlwZSBXb3Jrc3BhY2VDbGllbnQgPSBhcHBraXQuV29ya3NwYWNlQ2xpZW50TGlrZTtcblxuLyoqIEV4cGVyaW1lbnQgdGFnIERhdGFicmlja3Mgc3RvcmVzIGFzIGBjYXRhbG9nLnNjaGVtYS50YWJsZV9wcmVmaXhgLiAqL1xuY29uc3QgVFJBQ0VfREVTVElOQVRJT05fUEFUSF9UQUcgPSBcIm1sZmxvdy5leHBlcmltZW50LmRhdGFicmlja3NUcmFjZURlc3RpbmF0aW9uUGF0aFwiO1xuLyoqIEV4cGVyaW1lbnQgdGFnIG5hbWluZyB0aGUgT1RlbCBzcGFucyB0YWJsZSAoYGNhdGFsb2cuc2NoZW1hLntwcmVmaXh9X290ZWxfc3BhbnNgKS4gKi9cbmNvbnN0IFRSQUNFX1NQQU5fU1RPUkFHRV9UQUJMRV9UQUcgPSBcIm1sZmxvdy5leHBlcmltZW50LmRhdGFicmlja3NUcmFjZVNwYW5TdG9yYWdlVGFibGVcIjtcblxuLyoqXG4gKiBDYWNoZWQgVUMgdGFibGUgcHJlZml4IHJlc29sdmVkIGZyb20gdGhlIGV4cGVyaW1lbnQuIGBsb2FkZWRgIGRpc3Rpbmd1aXNoZXNcbiAqIFwibm90IGZldGNoZWQgeWV0XCIgZnJvbSBcImZldGNoZWQsIGV4cGVyaW1lbnQgaGFzIG5vIFVDIGxvY2F0aW9uXCIuIE5ldHdvcmtcbiAqIGZhaWx1cmVzIGFyZSBub3QgY2FjaGVkIHNvIGEgbGF0ZXIgdGh1bWJzIGNsaWNrIGNhbiByZXRyeS5cbiAqL1xubGV0IGxvYWRlZFVjUHJlZml4OiB7IHByZWZpeDogc3RyaW5nIHwgdW5kZWZpbmVkIH0gfCB1bmRlZmluZWQ7XG5cbi8qKiBTdHJpcCB0aGUgYHRyYWNlOi9gIFVSSSB3cmFwcGVyIGFuZCB0cmFpbGluZyBzbGFzaGVzIGZyb20gYSBVQyBwcmVmaXguICovXG5mdW5jdGlvbiBub3JtYWxpemVVY1ByZWZpeChyYXc6IHN0cmluZyB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHZhbHVlID0gcmF3XG4gICAgPy50cmltKClcbiAgICAucmVwbGFjZSgvXnRyYWNlOlxcLy8sIFwiXCIpXG4gICAgLnJlcGxhY2UoL1xcLyskLywgXCJcIik7XG4gIHJldHVybiB2YWx1ZSB8fCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRGVyaXZlIGBjYXRhbG9nLnNjaGVtYS50YWJsZV9wcmVmaXhgIGZyb20gYSBzcGFucyB0YWJsZSBuYW1lLlxuICogRGF0YWJyaWNrcyBuYW1lcyB0aGUgdGFibGUgYHtwcmVmaXh9X290ZWxfc3BhbnNgLlxuICovXG5mdW5jdGlvbiBwcmVmaXhGcm9tU3BhblRhYmxlKHRhYmxlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBuYW1lID0gdGFibGU/LnRyaW0oKTtcbiAgaWYgKCFuYW1lKSByZXR1cm4gdW5kZWZpbmVkO1xuICBpZiAobmFtZS5lbmRzV2l0aChcIl9vdGVsX3NwYW5zXCIpKSByZXR1cm4gbmFtZS5zbGljZSgwLCAtXCJfb3RlbF9zcGFuc1wiLmxlbmd0aCk7XG4gIGlmIChuYW1lLmVuZHNXaXRoKFwiX3NwYW5zXCIpKSByZXR1cm4gbmFtZS5zbGljZSgwLCAtXCJfc3BhbnNcIi5sZW5ndGgpO1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBleHBlcmltZW50VGFnTWFwKHJhdzogdW5rbm93bik6IE1hcDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCB0YWdzID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgaWYgKEFycmF5LmlzQXJyYXkocmF3KSkge1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHJhdykge1xuICAgICAgaWYgKCFvYmplY3QuaXNSZWNvcmQodGFnKSB8fCB0eXBlb2YgdGFnLmtleSAhPT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgdGFnLnZhbHVlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdGFncy5zZXQodGFnLmtleSwgdGFnLnZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHRhZ3M7XG4gIH1cbiAgaWYgKCFvYmplY3QuaXNSZWNvcmQocmF3KSkgcmV0dXJuIHRhZ3M7XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHJhdykpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB0YWdzLnNldChrZXksIHZhbHVlKTtcbiAgfVxuICByZXR1cm4gdGFncztcbn1cblxuLyoqXG4gKiBVQyB0YWJsZSBwcmVmaXggdGhlIGFzc2Vzc21lbnRzIEFQSSBuZWVkcywgcmVhZCBmcm9tIGV4cGVyaW1lbnQgdGFncy5cbiAqXG4gKiBQcmVmZXJzIHRoZSB0aHJlZS1wYXJ0IGRlc3RpbmF0aW9uIHBhdGggRGF0YWJyaWNrcyB3cml0ZXMgd2hlbiB0aGVcbiAqIGV4cGVyaW1lbnQgaXMgbGlua2VkIHRvIGEgdGFibGUtcHJlZml4IGxvY2F0aW9uLiBGYWxscyBiYWNrIHRvIHN0cmlwcGluZ1xuICogYF9vdGVsX3NwYW5zYCBmcm9tIHRoZSBzcGFucy10YWJsZSB0YWcuIFR3by1wYXJ0IHNjaGVtYS1saW5rZWQgZGVzdGluYXRpb25zXG4gKiBhcmUgaWdub3JlZCAodGhleSBhcmUgbm90IGEgdGFibGUgcHJlZml4KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVjVHJhY2VQcmVmaXhGcm9tRXhwZXJpbWVudFRhZ3MocmF3VGFnczogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHRhZ3MgPSBleHBlcmltZW50VGFnTWFwKHJhd1RhZ3MpO1xuICBjb25zdCBkZXN0aW5hdGlvbiA9IG5vcm1hbGl6ZVVjUHJlZml4KHRhZ3MuZ2V0KFRSQUNFX0RFU1RJTkFUSU9OX1BBVEhfVEFHKSk7XG4gIGlmIChkZXN0aW5hdGlvbiAmJiBkZXN0aW5hdGlvbi5zcGxpdChcIi5cIikubGVuZ3RoID49IDMpIHJldHVybiBkZXN0aW5hdGlvbjtcbiAgcmV0dXJuIHByZWZpeEZyb21TcGFuVGFibGUodGFncy5nZXQoVFJBQ0VfU1BBTl9TVE9SQUdFX1RBQkxFX1RBRykpO1xufVxuXG4vKiogRHJvcCB0aGUgaW4tcHJvY2VzcyBVQyBwcmVmaXggY2FjaGUgKHRlc3RzKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldFVjVHJhY2VQcmVmaXhDYWNoZSgpOiB2b2lkIHtcbiAgbG9hZGVkVWNQcmVmaXggPSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogVHJhY2UgaWQgdGhlIGFzc2Vzc21lbnRzIFJFU1QgQVBJIGFjY2VwdHMgZm9yIHRoaXMgZGVwbG95bWVudC5cbiAqXG4gKiBEYXRhYnJpY2tzIEFwcHMgcGVyc2lzdCB0cmFjZXMgaW4gVW5pdHkgQ2F0YWxvZy4gVGhlIGV4cGVyaW1lbnQgVUkgbGlzdHNcbiAqIHRob3NlIHJvd3MsIGJ1dCBgUE9TVCAvYXBpLzMuMC9tbGZsb3cvdHJhY2VzL3tpZH0vYXNzZXNzbWVudHNgIGxvb2tzIHVwIHRoZVxuICogZXhwZXJpbWVudCBzdG9yZSB1bmxlc3MgYHtpZH1gIGlzIHRoZSBVQyBVUkkgYHRyYWNlOi97Y2F0YWxvZ30ue3NjaGVtYX0ue3ByZWZpeH0ve3RyLWhleH1gLlxuICogQSBiYXJlIGB0ci08aGV4PmAgNDA0cyBhbmQgdGhlIGFzc2Vzc21lbnQgbmV2ZXIgYXBwZWFycy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1sZmxvd0Fzc2Vzc21lbnRUcmFjZUlkKHRyYWNlSWQ6IHN0cmluZywgcHJlZml4Pzogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcmVzb2x2ZWQgPSBub3JtYWxpemVVY1ByZWZpeChwcmVmaXgpO1xuICByZXR1cm4gcmVzb2x2ZWQgPyBgdHJhY2U6LyR7cmVzb2x2ZWR9LyR7dHJhY2VJZH1gIDogdHJhY2VJZDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVVjVHJhY2VQcmVmaXgoY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBmcm9tRW52ID0gbm9ybWFsaXplVWNQcmVmaXgocHJvY2Vzcy5lbnYuTUxGTE9XX1VDX1RSQUNFX1BSRUZJWCk7XG4gIGlmIChmcm9tRW52KSByZXR1cm4gZnJvbUVudjtcbiAgaWYgKGxvYWRlZFVjUHJlZml4KSByZXR1cm4gbG9hZGVkVWNQcmVmaXgucHJlZml4O1xuICBjb25zdCBleHBlcmltZW50ID0gYXdhaXQgZmV0Y2hFeHBlcmltZW50KGNsaWVudCk7XG4gIGlmICghZXhwZXJpbWVudCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgcHJlZml4ID0gdWNUcmFjZVByZWZpeEZyb21FeHBlcmltZW50VGFncyhleHBlcmltZW50LnRhZ3MpO1xuICBsb2FkZWRVY1ByZWZpeCA9IHsgcHJlZml4IH07XG4gIHJldHVybiBwcmVmaXg7XG59XG5cbi8qKiBBc3Nlc3NtZW50cyBSRVNUIHBhdGggZm9yIGEgdHJhY2UuIGAzLjBgIGlzIHRoZSBjdXJyZW50IE1MZmxvdyBBUEkgdmVyc2lvbi4gKi9cbmNvbnN0IGFzc2Vzc21lbnRzUGF0aCA9ICh0cmFjZUlkOiBzdHJpbmcpOiBzdHJpbmcgPT5cbiAgYC9hcGkvMy4wL21sZmxvdy90cmFjZXMvJHtlbmNvZGVVUklDb21wb25lbnQodHJhY2VJZCl9L2Fzc2Vzc21lbnRzYDtcblxuLyoqIE51bWJlciBvZiB0aW1lcyB0byByZXRyeSBhIFwidHJhY2Ugbm90IGZvdW5kXCIgcmVzcG9uc2UgYmVmb3JlIGdpdmluZyB1cC4gKi9cbmNvbnN0IE5PVF9GT1VORF9SRVRSSUVTID0gMztcbi8qKiBCYXNlIGJhY2tvZmYgYmV0d2VlbiBcInRyYWNlIG5vdCBmb3VuZFwiIHJldHJpZXMsIGluIG1zIChncm93cyBsaW5lYXJseSkuICovXG5jb25zdCBOT1RfRk9VTkRfQkFDS09GRl9NUyA9IDEyMDA7XG5cbmNvbnN0IE1sZmxvd0V4cGVyaW1lbnRSZXNwb25zZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZXhwZXJpbWVudDogelxuICAgICAgLm9iamVjdCh7XG4gICAgICAgIGV4cGVyaW1lbnRfaWQ6IHouc3RyaW5nKCkubWluKDEpLmRlc2NyaWJlKFwiV29ya3NwYWNlIE1MZmxvdyBleHBlcmltZW50IGlkZW50aWZpZXIuXCIpLFxuICAgICAgICB0YWdzOiB6LnVua25vd24oKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiRXhwZXJpbWVudCB0YWdzLCBpbmNsdWRpbmcgdGhlIFVDIHRyYWNlIGxvY2F0aW9uLlwiKSxcbiAgICAgIH0pXG4gICAgICAucGFzc3Rocm91Z2goKVxuICAgICAgLmRlc2NyaWJlKFwiQ29uZmlndXJlZCBNTGZsb3cgZXhwZXJpbWVudC5cIiksXG4gIH0pXG4gIC5wYXNzdGhyb3VnaCgpXG4gIC5kZXNjcmliZShcIk1MZmxvdyBnZXQtZXhwZXJpbWVudCByZXNwb25zZS5cIik7XG5cbmNvbnN0IEN1cnJlbnRVc2VyUmVzcG9uc2VTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHVzZXJOYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJDdXJyZW50IHdvcmtzcGFjZSB1c2VyIG5hbWUuXCIpLFxuICAgIGFwcGxpY2F0aW9uSWQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZShcIkN1cnJlbnQgc2VydmljZSBwcmluY2lwYWwgYXBwbGljYXRpb24gaWQuXCIpLFxuICAgIGRpc3BsYXlOYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJDdXJyZW50IHByaW5jaXBhbCBkaXNwbGF5IG5hbWUuXCIpLFxuICAgIGdyb3VwczogelxuICAgICAgLmFycmF5KFxuICAgICAgICB6XG4gICAgICAgICAgLm9iamVjdCh7XG4gICAgICAgICAgICB2YWx1ZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiV29ya3NwYWNlIGdyb3VwIGlkZW50aWZpZXIuXCIpLFxuICAgICAgICAgICAgZGlzcGxheTogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiV29ya3NwYWNlIGdyb3VwIGRpc3BsYXkgbmFtZS5cIiksXG4gICAgICAgICAgfSlcbiAgICAgICAgICAucGFzc3Rocm91Z2goKSxcbiAgICAgIClcbiAgICAgIC5vcHRpb25hbCgpXG4gICAgICAuZGVzY3JpYmUoXCJHcm91cHMgYXNzaWduZWQgdG8gdGhlIGN1cnJlbnQgcHJpbmNpcGFsLlwiKSxcbiAgfSlcbiAgLnBhc3N0aHJvdWdoKClcbiAgLmRlc2NyaWJlKFwiRGF0YWJyaWNrcyBDdXJyZW50IFVzZXIgQVBJIHJlc3BvbnNlLlwiKTtcblxuY29uc3QgRXhwZXJpbWVudFBlcm1pc3Npb25zUmVzcG9uc2VTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGFjY2Vzc19jb250cm9sX2xpc3Q6IHpcbiAgICAgIC5hcnJheShcbiAgICAgICAgelxuICAgICAgICAgIC5vYmplY3Qoe1xuICAgICAgICAgICAgdXNlcl9uYW1lOiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJVc2VyIHByaW5jaXBhbCBuYW1lLlwiKSxcbiAgICAgICAgICAgIGdyb3VwX25hbWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZShcIkdyb3VwIHByaW5jaXBhbCBuYW1lLlwiKSxcbiAgICAgICAgICAgIHNlcnZpY2VfcHJpbmNpcGFsX25hbWU6IHpcbiAgICAgICAgICAgICAgLnN0cmluZygpXG4gICAgICAgICAgICAgIC5vcHRpb25hbCgpXG4gICAgICAgICAgICAgIC5kZXNjcmliZShcIlNlcnZpY2UgcHJpbmNpcGFsIGFwcGxpY2F0aW9uIGlkLlwiKSxcbiAgICAgICAgICAgIGFsbF9wZXJtaXNzaW9uczogelxuICAgICAgICAgICAgICAuYXJyYXkoXG4gICAgICAgICAgICAgICAgelxuICAgICAgICAgICAgICAgICAgLm9iamVjdCh7XG4gICAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25fbGV2ZWw6IHouc3RyaW5nKCkuZGVzY3JpYmUoXCJFZmZlY3RpdmUgZXhwZXJpbWVudCBwZXJtaXNzaW9uIGxldmVsLlwiKSxcbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAucGFzc3Rocm91Z2goKSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAub3B0aW9uYWwoKVxuICAgICAgICAgICAgICAuZGVzY3JpYmUoXCJEaXJlY3QgYW5kIGluaGVyaXRlZCBwZXJtaXNzaW9ucyBmb3IgdGhpcyBwcmluY2lwYWwuXCIpLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnBhc3N0aHJvdWdoKCksXG4gICAgICApXG4gICAgICAub3B0aW9uYWwoKVxuICAgICAgLmRlc2NyaWJlKFwiRXhwZXJpbWVudCBhY2Nlc3MgY29udHJvbCBlbnRyaWVzLlwiKSxcbiAgfSlcbiAgLnBhc3N0aHJvdWdoKClcbiAgLmRlc2NyaWJlKFwiRGF0YWJyaWNrcyBleHBlcmltZW50IHBlcm1pc3Npb25zIHJlc3BvbnNlLlwiKTtcblxuZnVuY3Rpb24gY29uZmlndXJlZEV4cGVyaW1lbnQoKTogeyBpZD86IHN0cmluZzsgbmFtZT86IHN0cmluZyB9IHtcbiAgY29uc3QgaWQgPSBwcm9jZXNzLmVudi5NTEZMT1dfRVhQRVJJTUVOVF9JRD8udHJpbSgpO1xuICBjb25zdCBuYW1lID0gcHJvY2Vzcy5lbnYuTUxGTE9XX0VYUEVSSU1FTlRfTkFNRT8udHJpbSgpO1xuICByZXR1cm4ge1xuICAgIC4uLihpZCA/IHsgaWQgfSA6IHt9KSxcbiAgICAuLi4obmFtZSA/IHsgbmFtZSB9IDoge30pLFxuICB9O1xufVxuXG4vKiogVHJhY2tpbmcgVVJJIGZvciBkaXJlY3QgbG9jYWwgTUxmbG93IHRyYWNpbmcsIHdpdGggQ0xJLXByb2ZpbGUgYXV0aCBpbmplY3RlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXJlY3RNbGZsb3dUcmFja2luZ1VyaSgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoYXBwa2l0LmlzRGF0YWJyaWNrc0FwcEVudigpKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBjb25maWd1cmVkID0gcHJvY2Vzcy5lbnYuTUxGTE9XX1RSQUNLSU5HX1VSST8udHJpbSgpO1xuICBpZiAoY29uZmlndXJlZCAmJiBjb25maWd1cmVkICE9PSBcImRhdGFicmlja3NcIikgcmV0dXJuIGNvbmZpZ3VyZWQ7XG4gIGNvbnN0IHByb2ZpbGUgPSBwcm9jZXNzLmVudi5EQVRBQlJJQ0tTX0NPTkZJR19QUk9GSUxFPy50cmltKCk7XG4gIHJldHVybiBwcm9maWxlID8gYGRhdGFicmlja3M6Ly8ke3Byb2ZpbGV9YCA6IFwiZGF0YWJyaWNrc1wiO1xufVxuXG4vKiogUGFyc2UgdGhlIG9wdGlvbmFsIFVDIHRhYmxlLXByZWZpeCBsb2NhdGlvbiB1c2VkIGJ5IGRpcmVjdCBsb2NhbCB0cmFjaW5nLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpcmVjdE1sZmxvd1RyYWNlTG9jYXRpb24oKTpcbiAgfCB7IGNhdGFsb2dOYW1lOiBzdHJpbmc7IHNjaGVtYU5hbWU6IHN0cmluZzsgdGFibGVQcmVmaXg6IHN0cmluZyB9XG4gIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgY2F0YWxvZ05hbWUgPSBwcm9jZXNzLmVudi5NTEZMT1dfVUNfQ0FUQUxPRz8udHJpbSgpO1xuICBjb25zdCBzY2hlbWFOYW1lID0gcHJvY2Vzcy5lbnYuTUxGTE9XX1VDX1NDSEVNQT8udHJpbSgpO1xuICBjb25zdCB0YWJsZVByZWZpeCA9IHByb2Nlc3MuZW52Lk1MRkxPV19VQ19UQUJMRV9QUkVGSVg/LnRyaW0oKTtcbiAgaWYgKGNhdGFsb2dOYW1lICYmIHNjaGVtYU5hbWUgJiYgdGFibGVQcmVmaXgpIHtcbiAgICByZXR1cm4geyBjYXRhbG9nTmFtZSwgc2NoZW1hTmFtZSwgdGFibGVQcmVmaXggfTtcbiAgfVxuXG4gIGNvbnN0IHByZWZpeCA9IG5vcm1hbGl6ZVVjUHJlZml4KHByb2Nlc3MuZW52Lk1MRkxPV19VQ19UUkFDRV9QUkVGSVgpO1xuICBpZiAoIXByZWZpeCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgcGFydHMgPSBwcmVmaXguc3BsaXQoXCIuXCIpO1xuICBpZiAocGFydHMubGVuZ3RoICE9PSAzKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBbcHJlZml4Q2F0YWxvZywgcHJlZml4U2NoZW1hLCBwcmVmaXhUYWJsZV0gPSBwYXJ0cztcbiAgaWYgKCFwcmVmaXhDYXRhbG9nIHx8ICFwcmVmaXhTY2hlbWEgfHwgIXByZWZpeFRhYmxlKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4ge1xuICAgIGNhdGFsb2dOYW1lOiBwcmVmaXhDYXRhbG9nLFxuICAgIHNjaGVtYU5hbWU6IHByZWZpeFNjaGVtYSxcbiAgICB0YWJsZVByZWZpeDogcHJlZml4VGFibGUsXG4gIH07XG59XG5cbi8qKiBXaGV0aGVyIHRoZSBsb2NhbCBkaXJlY3QtdG8tZXhwZXJpbWVudCBNTGZsb3cgU0RLIGhhcyBlbm91Z2ggY29uZmlndXJhdGlvbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXJlY3RNbGZsb3dUcmFjaW5nQ29uZmlndXJlZCgpOiBib29sZWFuIHtcbiAgcmV0dXJuIEJvb2xlYW4oXG4gICAgIWFwcGtpdC5pc0RhdGFicmlja3NBcHBFbnYoKSAmJlxuICAgICAgcHJvY2Vzcy5lbnYuTUxGTE9XX0VYUEVSSU1FTlRfSUQ/LnRyaW0oKSAmJlxuICAgICAgZGlyZWN0TWxmbG93VHJhY2tpbmdVcmkoKSxcbiAgKTtcbn1cblxuLyoqIFdoZXRoZXIgYSBEYXRhYnJpY2tzIEFwcCBjYW4gcHJvbW90ZSBPVExQIHNwYW5zIGludG8gZnVsbCBNTGZsb3cgdHJhY2UgaW5mby4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBNbGZsb3dUcmFjZUluZm9Db25maWd1cmVkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gQm9vbGVhbihcbiAgICBhcHBraXQuaXNEYXRhYnJpY2tzQXBwRW52KCkgJiZcbiAgICAgIChwcm9jZXNzLmVudi5NTEZMT1dfRVhQRVJJTUVOVF9JRD8udHJpbSgpIHx8IHByb2Nlc3MuZW52Lk1MRkxPV19FWFBFUklNRU5UX05BTUU/LnRyaW0oKSkgJiZcbiAgICAgIChwcm9jZXNzLmVudi5PVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ/LnRyaW0oKSB8fFxuICAgICAgICBwcm9jZXNzLmVudi5PVEVMX0VYUE9SVEVSX09UTFBfVFJBQ0VTX0VORFBPSU5UPy50cmltKCkpLFxuICApO1xufVxuXG4vKiogSW5pdGlhbGl6ZSB0aGUgQXBwIHNlcnZpY2UtcHJpbmNpcGFsIGNsaWVudCB1c2VkIHRvIHBlcnNpc3QgVjQgdHJhY2UgdGFncyBhbmQgbWV0YWRhdGEuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5pdGlhbGl6ZUFwcE1sZmxvd1RyYWNlSW5mbyhcbiAgY2xpZW50PzogV29ya3NwYWNlQ2xpZW50LFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGlmIChhcHBNbGZsb3dUcmFjZUluZm9DbGllbnQgJiYgYXBwTWxmbG93VHJhY2VQcmVmaXgpIHJldHVybiB0cnVlO1xuICBpZiAoYXBwTWxmbG93VHJhY2VJbmZvSW5pdFN0YXJ0ZWQgfHwgIWFwcE1sZmxvd1RyYWNlSW5mb0NvbmZpZ3VyZWQoKSkgcmV0dXJuIGZhbHNlO1xuICBhcHBNbGZsb3dUcmFjZUluZm9Jbml0U3RhcnRlZCA9IHRydWU7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzb2x2ZWRDbGllbnQgPSBjbGllbnQgPz8gKGNyZWF0ZVdvcmtzcGFjZUNsaWVudCgpIGFzIFdvcmtzcGFjZUNsaWVudCk7XG4gICAgY29uc3QgcHJlZml4ID0gYXdhaXQgcmVzb2x2ZVVjVHJhY2VQcmVmaXgocmVzb2x2ZWRDbGllbnQpO1xuICAgIGlmICghcHJlZml4IHx8IHByZWZpeC5zcGxpdChcIi5cIikubGVuZ3RoICE9PSAzKSB7XG4gICAgICB0aHJvdyBuZXcgQ29uZmlndXJhdGlvbkVycm9yKFxuICAgICAgICBcIkRhdGFicmlja3MgQXBwcyBNTGZsb3cgdHJhY2UtaW5mbyBwcm9tb3Rpb24gcmVxdWlyZXMgYSBVQy1saW5rZWQgZXhwZXJpbWVudCBvciBNTEZMT1dfVUNfVFJBQ0VfUFJFRklYLlwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgYXBwTWxmbG93VHJhY2VJbmZvQ2xpZW50ID0gcmVzb2x2ZWRDbGllbnQ7XG4gICAgYXBwTWxmbG93VHJhY2VQcmVmaXggPSBwcmVmaXg7XG4gICAgbG9nZ2VyLmluZm8oXCJEYXRhYnJpY2tzIEFwcHMgTUxmbG93IHRyYWNlLWluZm8gcHJvbW90aW9uIGVuYWJsZWRcIiwgeyBwcmVmaXggfSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKFwiRGF0YWJyaWNrcyBBcHBzIE1MZmxvdyB0cmFjZS1pbmZvIHByb21vdGlvbiBkaXNhYmxlZFwiLCB7XG4gICAgICBlcnJvcjogZXJyb3JVdGlscy5lcnJvck1lc3NhZ2UoZXJyKSxcbiAgICB9KTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqIFRyYWNlLWxldmVsIHZhbHVlcyBwZXJzaXN0ZWQgYmVzaWRlIHNwYW5zIGFscmVhZHkgZXhwb3J0ZWQgYnkgdGhlIEFwcHMgT1RMUCBzaWRlY2FyLiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBNbGZsb3dUcmFjZUluZm8ge1xuICB0cmFjZUlkOiBzdHJpbmc7XG4gIHJlcXVlc3RUaW1lOiBudW1iZXI7XG4gIGV4ZWN1dGlvbkR1cmF0aW9uOiBudW1iZXI7XG4gIGVycm9yOiBib29sZWFuO1xuICB0YWdzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICB1c2VyPzogc3RyaW5nO1xuICBzZXNzaW9uSWQ/OiBzdHJpbmc7XG4gIHJlcXVlc3RQcmV2aWV3Pzogc3RyaW5nO1xuICByZXNwb25zZVByZXZpZXc/OiBzdHJpbmc7XG59XG5cbi8qKiBQZXJzaXN0IE1MZmxvdyBWNCB0cmFjZSBpbmZvIGZvciBvbmUgRGF0YWJyaWNrcyBBcHBzIE9UZWwgcm9vdCB3aXRob3V0IHJlLWV4cG9ydGluZyBzcGFucy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwZXJzaXN0QXBwTWxmbG93VHJhY2VJbmZvKHBhcmFtczogQXBwTWxmbG93VHJhY2VJbmZvKTogdm9pZCB7XG4gIGNvbnN0IGNsaWVudCA9IGFwcE1sZmxvd1RyYWNlSW5mb0NsaWVudDtcbiAgY29uc3QgcHJlZml4ID0gYXBwTWxmbG93VHJhY2VQcmVmaXg7XG4gIGlmICghY2xpZW50IHx8ICFwcmVmaXgpIHJldHVybjtcbiAgY29uc3QgW2NhdGFsb2dOYW1lLCBzY2hlbWFOYW1lLCB0YWJsZVByZWZpeF0gPSBwcmVmaXguc3BsaXQoXCIuXCIpO1xuICBpZiAoIWNhdGFsb2dOYW1lIHx8ICFzY2hlbWFOYW1lIHx8ICF0YWJsZVByZWZpeCkgcmV0dXJuO1xuICBjb25zdCB0cmFjZUluZm8gPSBuZXcgVHJhY2VJbmZvKHtcbiAgICB0cmFjZUlkOiBgdHJhY2U6LyR7cHJlZml4fS8ke3BhcmFtcy50cmFjZUlkfWAsXG4gICAgdHJhY2VMb2NhdGlvbjoge1xuICAgICAgdHlwZTogVHJhY2VMb2NhdGlvblR5cGUuVUNfVEFCTEVfUFJFRklYLFxuICAgICAgdWNUYWJsZVByZWZpeDogeyBjYXRhbG9nTmFtZSwgc2NoZW1hTmFtZSwgdGFibGVQcmVmaXggfSxcbiAgICB9LFxuICAgIHJlcXVlc3RUaW1lOiBwYXJhbXMucmVxdWVzdFRpbWUsXG4gICAgZXhlY3V0aW9uRHVyYXRpb246IHBhcmFtcy5leGVjdXRpb25EdXJhdGlvbixcbiAgICBzdGF0ZTogcGFyYW1zLmVycm9yID8gVHJhY2VTdGF0ZS5FUlJPUiA6IFRyYWNlU3RhdGUuT0ssXG4gICAgLi4uKHBhcmFtcy5yZXF1ZXN0UHJldmlldyA/IHsgcmVxdWVzdFByZXZpZXc6IHBhcmFtcy5yZXF1ZXN0UHJldmlldyB9IDoge30pLFxuICAgIC4uLihwYXJhbXMucmVzcG9uc2VQcmV2aWV3ID8geyByZXNwb25zZVByZXZpZXc6IHBhcmFtcy5yZXNwb25zZVByZXZpZXcgfSA6IHt9KSxcbiAgICB0cmFjZU1ldGFkYXRhOiB7XG4gICAgICBbVHJhY2VNZXRhZGF0YUtleS5TQ0hFTUFfVkVSU0lPTl06IFwiNFwiLFxuICAgICAgLi4uKHBhcmFtcy51c2VyID8geyBbVHJhY2VNZXRhZGF0YUtleS5UUkFDRV9VU0VSXTogcGFyYW1zLnVzZXIgfSA6IHt9KSxcbiAgICAgIC4uLihwYXJhbXMuc2Vzc2lvbklkID8geyBbVHJhY2VNZXRhZGF0YUtleS5UUkFDRV9TRVNTSU9OXTogcGFyYW1zLnNlc3Npb25JZCB9IDoge30pLFxuICAgIH0sXG4gICAgdGFnczogcGFyYW1zLnRhZ3MsXG4gICAgYXNzZXNzbWVudHM6IFtdLFxuICB9KTtcbiAgY29uc3QgcGF0aCA9IGAvYXBpLzQuMC9tbGZsb3cvdHJhY2VzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KHByZWZpeCl9LyR7cGFyYW1zLnRyYWNlSWR9L2luZm9gO1xuICBjb25zdCBwZW5kaW5nID0gZGF0YWJyaWNrc0ZldGNoKGNsaWVudCwgcGF0aCwgeyBtZXRob2Q6IFwiUE9TVFwiLCBib2R5OiB0cmFjZUluZm8udG9Kc29uKCkgfSlcbiAgICAudGhlbihhc3luYyAocmVzcG9uc2UpID0+IHtcbiAgICAgIGlmIChyZXNwb25zZS5vaykgcmV0dXJuO1xuICAgICAgbG9nZ2VyLndhcm4oXCJEYXRhYnJpY2tzIEFwcHMgTUxmbG93IHRyYWNlLWluZm8gcHJvbW90aW9uIGZhaWxlZFwiLCB7XG4gICAgICAgIHRyYWNlSWQ6IHBhcmFtcy50cmFjZUlkLFxuICAgICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgYm9keTogYXdhaXQgcmVhZFJlc3BvbnNlVGV4dChyZXNwb25zZSksXG4gICAgICB9KTtcbiAgICB9KVxuICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICBsb2dnZXIud2FybihcIkRhdGFicmlja3MgQXBwcyBNTGZsb3cgdHJhY2UtaW5mbyBwcm9tb3Rpb24gZmFpbGVkXCIsIHtcbiAgICAgICAgdHJhY2VJZDogcGFyYW1zLnRyYWNlSWQsXG4gICAgICAgIGVycm9yOiBlcnJvclV0aWxzLmVycm9yTWVzc2FnZShlcnIpLFxuICAgICAgfSk7XG4gICAgfSlcbiAgICAuZmluYWxseSgoKSA9PiBwZW5kaW5nQXBwTWxmbG93VHJhY2VJbmZvLmRlbGV0ZShwZW5kaW5nKSk7XG4gIHBlbmRpbmdBcHBNbGZsb3dUcmFjZUluZm8uYWRkKHBlbmRpbmcpO1xufVxuXG4vKiogUmVzZXQgQXBwcyB0cmFjZS1pbmZvIHByb21vdGlvbiBzdGF0ZSBmb3IgdGVzdHMuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRBcHBNbGZsb3dUcmFjZUluZm8oKTogdm9pZCB7XG4gIGFwcE1sZmxvd1RyYWNlSW5mb0luaXRTdGFydGVkID0gZmFsc2U7XG4gIGFwcE1sZmxvd1RyYWNlSW5mb0NsaWVudCA9IHVuZGVmaW5lZDtcbiAgYXBwTWxmbG93VHJhY2VQcmVmaXggPSB1bmRlZmluZWQ7XG4gIHBlbmRpbmdBcHBNbGZsb3dUcmFjZUluZm8uY2xlYXIoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGV0ZWN0ZWREaXJlY3RNbGZsb3dUcmFjZUxvY2F0aW9uKFxuICBtbGZsb3c6IE1sZmxvd01vZHVsZSxcbiAgdHJhY2tpbmdVcmk6IHN0cmluZyxcbiAgZXhwZXJpbWVudElkOiBzdHJpbmcsXG4gIGhvc3Q6IHN0cmluZyB8IHVuZGVmaW5lZCxcbik6IFByb21pc2U8eyBjYXRhbG9nTmFtZTogc3RyaW5nOyBzY2hlbWFOYW1lOiBzdHJpbmc7IHRhYmxlUHJlZml4OiBzdHJpbmcgfSB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBleHBsaWNpdCA9IGRpcmVjdE1sZmxvd1RyYWNlTG9jYXRpb24oKTtcbiAgaWYgKGV4cGxpY2l0KSByZXR1cm4gZXhwbGljaXQ7XG4gIHRyeSB7XG4gICAgY29uc3QgYXV0aFByb3ZpZGVyID0gbWxmbG93LmNyZWF0ZUF1dGhQcm92aWRlcih7XG4gICAgICB0cmFja2luZ1VyaSxcbiAgICAgIC4uLihob3N0ID8geyBob3N0IH0gOiB7fSksXG4gICAgfSk7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IG1sZmxvdy5NbGZsb3dDbGllbnQoeyB0cmFja2luZ1VyaSwgYXV0aFByb3ZpZGVyIH0pO1xuICAgIGNvbnN0IGV4cGVyaW1lbnQgPSBhd2FpdCBjbGllbnQuZ2V0RXhwZXJpbWVudChleHBlcmltZW50SWQpO1xuICAgIGlmICghZXhwZXJpbWVudCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjb25zdCB7IHVjTG9jYXRpb25Gcm9tRXhwZXJpbWVudFRhZ3MgfSA9IGF3YWl0IGltcG9ydChcIkBtbGZsb3cvY29yZS9kaXN0L2NvcmUvZGVzdGluYXRpb25cIik7XG4gICAgY29uc3QgbG9jYXRpb24gPSB1Y0xvY2F0aW9uRnJvbUV4cGVyaW1lbnRUYWdzKGV4cGVyaW1lbnQudGFncyk7XG4gICAgaWYgKCFsb2NhdGlvbj8udGFibGVQcmVmaXgpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNhdGFsb2dOYW1lOiBsb2NhdGlvbi5jYXRhbG9nTmFtZSxcbiAgICAgIHNjaGVtYU5hbWU6IGxvY2F0aW9uLnNjaGVtYU5hbWUsXG4gICAgICB0YWJsZVByZWZpeDogbG9jYXRpb24udGFibGVQcmVmaXgsXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLndhcm4oXCJkaXJlY3QgTUxmbG93IFVDIHRyYWNlLWxvY2F0aW9uIGRldGVjdGlvbiBmYWlsZWRcIiwge1xuICAgICAgZXhwZXJpbWVudElkLFxuICAgICAgZXJyb3I6IGVycm9yVXRpbHMuZXJyb3JNZXNzYWdlKGVyciksXG4gICAgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIFN0YXJ0IHRoZSBNTGZsb3cgTm9kZSB0cmFjZXIgZm9yIGxvY2FsIGRldmVsb3BtZW50IHdoZW4gQXBwS2l0IGhhcyBubyBPVExQXG4gKiBleHBvcnRlci4gVGhpcyBwcm92aWRlciBpcyBuZXZlciBzdGFydGVkIGluIHRoZSBkZXBsb3llZCBBcHBzIHBhdGgsIGF2b2lkaW5nXG4gKiBhIHNlY29uZCBnbG9iYWwgT1RlbCBwcm92aWRlciByYWNpbmcgQXBwS2l0J3MgdGVsZW1ldHJ5IG1hbmFnZXIuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbml0aWFsaXplRGlyZWN0TWxmbG93VHJhY2luZygpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgaWYgKGRpcmVjdE1sZmxvdykgcmV0dXJuIHRydWU7XG4gIGlmIChkaXJlY3RNbGZsb3dJbml0U3RhcnRlZCB8fCAhZGlyZWN0TWxmbG93VHJhY2luZ0NvbmZpZ3VyZWQoKSkgcmV0dXJuIGZhbHNlO1xuICBkaXJlY3RNbGZsb3dJbml0U3RhcnRlZCA9IHRydWU7XG5cbiAgY29uc3QgZXhwZXJpbWVudElkID0gcHJvY2Vzcy5lbnYuTUxGTE9XX0VYUEVSSU1FTlRfSUQhLnRyaW0oKTtcbiAgY29uc3QgdHJhY2tpbmdVcmkgPSBkaXJlY3RNbGZsb3dUcmFja2luZ1VyaSgpITtcbiAgdHJ5IHtcbiAgICBjb25zdCBtbGZsb3cgPSBhd2FpdCBpbXBvcnQoXCJAbWxmbG93L2NvcmVcIik7XG4gICAgY29uc3QgcmF3SG9zdCA9IHByb2Nlc3MuZW52LkRBVEFCUklDS1NfSE9TVD8udHJpbSgpO1xuICAgIGNvbnN0IGhvc3QgPSByYXdIb3N0XG4gICAgICA/IC9eaHR0cHM/OlxcL1xcLy9pLnRlc3QocmF3SG9zdClcbiAgICAgICAgPyByYXdIb3N0XG4gICAgICAgIDogYGh0dHBzOi8vJHtyYXdIb3N0fWBcbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IHRyYWNlTG9jYXRpb24gPSBhd2FpdCBkZXRlY3RlZERpcmVjdE1sZmxvd1RyYWNlTG9jYXRpb24oXG4gICAgICBtbGZsb3csXG4gICAgICB0cmFja2luZ1VyaSxcbiAgICAgIGV4cGVyaW1lbnRJZCxcbiAgICAgIGhvc3QsXG4gICAgKTtcbiAgICBpZiAoIXRyYWNlTG9jYXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBDb25maWd1cmF0aW9uRXJyb3IoXG4gICAgICAgIFwiRGlyZWN0IGxvY2FsIE1MZmxvdyB0cmFjaW5nIHJlcXVpcmVzIGEgVUMtbGlua2VkIGV4cGVyaW1lbnQgb3IgTUxGTE9XX1VDX1RSQUNFX1BSRUZJWC5cIixcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IFt7IERhdGFicmlja3NVQ1RhYmxlU3BhbkV4cG9ydGVyLCBEYXRhYnJpY2tzVUNUYWJsZVNwYW5Qcm9jZXNzb3IgfSwgc2RrXSA9XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIGltcG9ydChcIkBtbGZsb3cvY29yZS9kaXN0L2V4cG9ydGVycy91Y190YWJsZVwiKSxcbiAgICAgICAgaW1wb3J0KFwiQG9wZW50ZWxlbWV0cnkvc2RrLXRyYWNlLW5vZGVcIiksXG4gICAgICBdKTtcbiAgICBjb25zdCBhdXRoUHJvdmlkZXIgPSBtbGZsb3cuY3JlYXRlQXV0aFByb3ZpZGVyKHtcbiAgICAgIHRyYWNraW5nVXJpLFxuICAgICAgLi4uKGhvc3QgPyB7IGhvc3QgfSA6IHt9KSxcbiAgICB9KTtcbiAgICBjb25zdCBjbGllbnQgPSBuZXcgbWxmbG93Lk1sZmxvd0NsaWVudCh7IHRyYWNraW5nVXJpLCBhdXRoUHJvdmlkZXIgfSk7XG4gICAgY29uc3QgZXhwb3J0ZXIgPSBuZXcgRGF0YWJyaWNrc1VDVGFibGVTcGFuRXhwb3J0ZXIoY2xpZW50KTtcbiAgICBjb25zdCBwcm9jZXNzb3IgPSBuZXcgQWdlbnRUcmFjZVNwYW5Qcm9jZXNzb3IoXG4gICAgICBuZXcgRGF0YWJyaWNrc1VDVGFibGVTcGFuUHJvY2Vzc29yKGV4cG9ydGVyLCB0cmFjZUxvY2F0aW9uKSxcbiAgICApO1xuICAgIGNvbnN0IHByb3ZpZGVyID0gbmV3IHNkay5Ob2RlVHJhY2VyUHJvdmlkZXIoeyBzcGFuUHJvY2Vzc29yczogW3Byb2Nlc3Nvcl0gfSk7XG4gICAgcHJvdmlkZXIucmVnaXN0ZXIoKTtcbiAgICBkaXJlY3RNbGZsb3cgPSBtbGZsb3c7XG4gICAgZGlyZWN0TWxmbG93UHJvdmlkZXIgPSBwcm92aWRlcjtcbiAgICBkaXJlY3RNbGZsb3dQcm9jZXNzb3IgPSBwcm9jZXNzb3I7XG4gICAgbG9nZ2VyLmluZm8oXCJkaXJlY3QgTUxmbG93IHRyYWNpbmcgZW5hYmxlZFwiLCB7XG4gICAgICBleHBlcmltZW50SWQsXG4gICAgICB0cmFja2luZ1VyaSxcbiAgICAgIHRyYWNlTG9jYXRpb24sXG4gICAgfSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKFwiZGlyZWN0IE1MZmxvdyB0cmFjaW5nIGRpc2FibGVkXCIsIHtcbiAgICAgIGVycm9yOiBlcnJvclV0aWxzLmVycm9yTWVzc2FnZShlcnIpLFxuICAgIH0pO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKiogUGVyc2lzdCB0cmFjZS1sZXZlbCBmaWVsZHMgb24gdGhlIGRpcmVjdCBNTGZsb3cgdHJhY2UgaW4gdGhlIGN1cnJlbnQgT1RlbCBjb250ZXh0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUFjdGl2ZU1sZmxvd1RyYWNlKG9wdGlvbnM6IFVwZGF0ZUN1cnJlbnRUcmFjZU9wdGlvbnMpOiB2b2lkIHtcbiAgZGlyZWN0TWxmbG93Py51cGRhdGVDdXJyZW50VHJhY2Uob3B0aW9ucyk7XG59XG5cbi8qKiBQZXJzaXN0IHRhZ3Mgb24gdGhlIGRpcmVjdCBNTGZsb3cgdHJhY2UgYWN0aXZlIGluIHRoZSBjdXJyZW50IE9UZWwgY29udGV4dC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVBY3RpdmVNbGZsb3dUcmFjZVRhZ3ModGFnczogUmVjb3JkPHN0cmluZywgc3RyaW5nPik6IHZvaWQge1xuICB1cGRhdGVBY3RpdmVNbGZsb3dUcmFjZSh7IHRhZ3MgfSk7XG59XG5cbi8qKiBXaGV0aGVyIHRoaXMgcHJvY2VzcyBvd25zIHRoZSBmaWx0ZXJlZCBsb2NhbCBNTGZsb3cgdHJhY2VyIHByb3ZpZGVyLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpcmVjdE1sZmxvd1RyYWNpbmdBY3RpdmUoKTogYm9vbGVhbiB7XG4gIHJldHVybiBkaXJlY3RNbGZsb3dQcm9jZXNzb3IgIT09IHVuZGVmaW5lZDtcbn1cblxuLyoqIEZsdXNoIHBlbmRpbmcgZGlyZWN0IGxvY2FsIHRyYWNlIGV4cG9ydHMgZHVyaW5nIGdyYWNlZnVsIHNodXRkb3duLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZsdXNoRGlyZWN0TWxmbG93VHJhY2luZygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgUHJvbWlzZS5hbGwoWy4uLnBlbmRpbmdBcHBNbGZsb3dUcmFjZUluZm9dKTtcbiAgYXdhaXQgZGlyZWN0TWxmbG93UHJvY2Vzc29yPy5mb3JjZUZsdXNoKCk7XG4gIGF3YWl0IGRpcmVjdE1sZmxvd1Byb3ZpZGVyPy5mb3JjZUZsdXNoKCk7XG59XG5cbi8qKlxuICogV2hldGhlciBNTGZsb3cgZmVlZGJhY2sgbG9nZ2luZyBpcyBhdmFpbGFibGUgZm9yIHRoaXMgZGVwbG95bWVudC5cbiAqXG4gKiBFbmFibGVkIHdoZW4gYW4gTUxmbG93IGV4cGVyaW1lbnQgaXMgY29uZmlndXJlZCBhbmQgdHJhY2VzIGhhdmUgYW4gZXhwb3J0XG4gKiBwYXRoOiBBcHBLaXQgT1RMUCBpbiBhIERhdGFicmlja3MgQXBwLCBvciB0aGUgZGlyZWN0IE1MZmxvdyBOb2RlIFNESyBvdXRzaWRlXG4gKiBvbmUuIEJvdGggcGF0aHMgYXJlIHNlbGVjdGVkIGZyb20gc3RhbmRhcmQgZW52aXJvbm1lbnQgdmFsdWVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWxmbG93RW5hYmxlZCgpOiBib29sZWFuIHtcbiAgY29uc3QgaGFzRXhwb3J0ZXIgPSBCb29sZWFuKFxuICAgIHByb2Nlc3MuZW52Lk9URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVD8udHJpbSgpIHx8XG4gICAgcHJvY2Vzcy5lbnYuT1RFTF9FWFBPUlRFUl9PVExQX1RSQUNFU19FTkRQT0lOVD8udHJpbSgpLFxuICApO1xuICBjb25zdCBoYXNFeHBlcmltZW50ID0gQm9vbGVhbihcbiAgICBwcm9jZXNzLmVudi5NTEZMT1dfRVhQRVJJTUVOVF9JRD8udHJpbSgpIHx8IHByb2Nlc3MuZW52Lk1MRkxPV19FWFBFUklNRU5UX05BTUU/LnRyaW0oKSxcbiAgKTtcbiAgcmV0dXJuIGhhc0V4cGVyaW1lbnQgJiYgKGhhc0V4cG9ydGVyIHx8IGRpcmVjdE1sZmxvd1RyYWNpbmdDb25maWd1cmVkKCkpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgd2hldGhlciB1c2VyIGZlZWRiYWNrIGlzIGVuYWJsZWQgZnJvbSB0aGUgcGx1Z2luJ3Mgb3B0aW9uYWxcbiAqIGBjb25maWcuZmVlZGJhY2tgIG92ZXJyaWRlOiB0aGUgZXhwbGljaXQgYm9vbGVhbiB3aW5zLCBvdGhlcndpc2UgZmFsbFxuICogYmFjayB0byBhdXRvLWRldGVjdGluZyBNTGZsb3cgdHJhY2luZyAoe0BsaW5rIG1sZmxvd0VuYWJsZWR9KS4gU2hhcmVkXG4gKiBieSB0aGUgcGx1Z2luJ3MgY2xpZW50LWNvbmZpZyBnYXRlIGFuZCB0aGUgc2VydmVyJ3MgdHJhY2UtaWQgaGVhZGVyIHNvXG4gKiB0aGUgdHdvIG5ldmVyIGRpc2FncmVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUZlZWRiYWNrRW5hYmxlZChleHBsaWNpdDogYm9vbGVhbiB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICByZXR1cm4gZXhwbGljaXQgPz8gbWxmbG93RW5hYmxlZCgpO1xufVxuXG4vKipcbiAqIFJlamVjdCBhbiBleHBsaWNpdGx5IGVuYWJsZWQgZmVlZGJhY2sgc3VyZmFjZSB3aGVuIG5vIE1MZmxvdyBleHBlcmltZW50IGlzXG4gKiBjb25maWd1cmVkLiBBdXRvIG1vZGUgcmVtYWlucyBub24tZmF0YWwgYW5kIHNpbXBseSBkaXNhYmxlcyBmZWVkYmFjay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlRmVlZGJhY2tDb25maWcoZXhwbGljaXQ6IGJvb2xlYW4gfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgaWYgKGV4cGxpY2l0ICE9PSB0cnVlKSByZXR1cm47XG4gIGNvbnN0IGV4cGVyaW1lbnQgPSBjb25maWd1cmVkRXhwZXJpbWVudCgpO1xuICBpZiAoZXhwZXJpbWVudC5pZCB8fCBleHBlcmltZW50Lm5hbWUpIHJldHVybjtcbiAgdGhyb3cgbmV3IENvbmZpZ3VyYXRpb25FcnJvcihcbiAgICBcIm1hc3RyYTogZmVlZGJhY2sgaXMgZW5hYmxlZCBidXQgbm8gTUxmbG93IGV4cGVyaW1lbnQgaXMgY29uZmlndXJlZC4gXCIgK1xuICAgICAgXCJTZXQgTUxGTE9XX0VYUEVSSU1FTlRfSUQgb3IgTUxGTE9XX0VYUEVSSU1FTlRfTkFNRSwgdXNlIGZlZWRiYWNrOiBmYWxzZSwgXCIgK1xuICAgICAgXCJvciBvbWl0IGZlZWRiYWNrIHRvIHVzZSBhdXRvbWF0aWMgZGV0ZWN0aW9uLlwiLFxuICApO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgY29uZmlndXJlZCBleHBlcmltZW50IFVSTCBvbmx5IHdoZW4gdGhlIGFjdGl2ZSBEYXRhYnJpY2tzXG4gKiBwcmluY2lwYWwgaGFzIGVmZmVjdGl2ZSBgQ0FOX01BTkFHRWAgcGVybWlzc2lvbi4gUGVybWlzc2lvbiBsb29rdXAgaXNcbiAqIGludGVudGlvbmFsbHkgYmVzdC1lZmZvcnQgc28gQXBwcyBlbnZpcm9ubWVudHMgdGhhdCBkbyBub3QgZXhwb3NlIHRoZVxuICogcmVxdWlyZWQgQVBJcyBzaW1wbHkgb21pdCB0aGUgZGVidWcgYWZmb3JkYW5jZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1sZmxvd0V4cGVyaW1lbnRNYW5hZ2VyVXJsKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCxcbik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHJlc29sdmVNbGZsb3dFeHBlcmltZW50TWFuYWdlclVybChjbGllbnQpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVNbGZsb3dFeHBlcmltZW50TWFuYWdlclVybChcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQsXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBleHBlcmltZW50SWQgPSBhd2FpdCByZXNvbHZlRXhwZXJpbWVudElkKGNsaWVudCk7XG4gIGlmICghZXhwZXJpbWVudElkKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IFtjdXJyZW50UmVzcG9uc2UsIHBlcm1pc3Npb25zUmVzcG9uc2VdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgIGRhdGFicmlja3NGZXRjaChjbGllbnQsIFwiL2FwaS8yLjAvcHJldmlldy9zY2ltL3YyL01lXCIsIHsgbWV0aG9kOiBcIkdFVFwiIH0pLFxuICAgIGRhdGFicmlja3NGZXRjaChcbiAgICAgIGNsaWVudCxcbiAgICAgIGAvYXBpLzIuMC9wZXJtaXNzaW9ucy9leHBlcmltZW50cy8ke2VuY29kZVVSSUNvbXBvbmVudChleHBlcmltZW50SWQpfWAsXG4gICAgICB7IG1ldGhvZDogXCJHRVRcIiB9LFxuICAgICksXG4gIF0pO1xuICBpZiAoIWN1cnJlbnRSZXNwb25zZS5vayB8fCAhcGVybWlzc2lvbnNSZXNwb25zZS5vaykgcmV0dXJuIHVuZGVmaW5lZDtcblxuICBjb25zdCBjdXJyZW50ID0gQ3VycmVudFVzZXJSZXNwb25zZVNjaGVtYS5zYWZlUGFyc2UoYXdhaXQgcmVhZFJlc3BvbnNlSnNvbihjdXJyZW50UmVzcG9uc2UpKTtcbiAgY29uc3QgcGVybWlzc2lvbnMgPSBFeHBlcmltZW50UGVybWlzc2lvbnNSZXNwb25zZVNjaGVtYS5zYWZlUGFyc2UoXG4gICAgYXdhaXQgcmVhZFJlc3BvbnNlSnNvbihwZXJtaXNzaW9uc1Jlc3BvbnNlKSxcbiAgKTtcbiAgaWYgKCFjdXJyZW50LnN1Y2Nlc3MgfHwgIXBlcm1pc3Npb25zLnN1Y2Nlc3MpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgdXNlck5hbWVzID0gbmV3IFNldChcbiAgICBbY3VycmVudC5kYXRhLnVzZXJOYW1lLCBjdXJyZW50LmRhdGEuYXBwbGljYXRpb25JZCwgY3VycmVudC5kYXRhLmRpc3BsYXlOYW1lXS5maWx0ZXIoXG4gICAgICAodmFsdWUpOiB2YWx1ZSBpcyBzdHJpbmcgPT4gQm9vbGVhbih2YWx1ZSksXG4gICAgKSxcbiAgKTtcbiAgY29uc3QgZ3JvdXBOYW1lcyA9IG5ldyBTZXQoXG4gICAgKGN1cnJlbnQuZGF0YS5ncm91cHMgPz8gW10pLmZsYXRNYXAoKHsgdmFsdWUsIGRpc3BsYXkgfSkgPT5cbiAgICAgIFt2YWx1ZSwgZGlzcGxheV0uZmlsdGVyKChlbnRyeSk6IGVudHJ5IGlzIHN0cmluZyA9PiBCb29sZWFuKGVudHJ5KSksXG4gICAgKSxcbiAgKTtcbiAgY29uc3QgY2FuTWFuYWdlID0gKHBlcm1pc3Npb25zLmRhdGEuYWNjZXNzX2NvbnRyb2xfbGlzdCA/PyBbXSkuc29tZSgoZW50cnkpID0+IHtcbiAgICBjb25zdCBtYXRjaGVzID1cbiAgICAgIChlbnRyeS51c2VyX25hbWUgIT09IHVuZGVmaW5lZCAmJiB1c2VyTmFtZXMuaGFzKGVudHJ5LnVzZXJfbmFtZSkpIHx8XG4gICAgICAoZW50cnkuc2VydmljZV9wcmluY2lwYWxfbmFtZSAhPT0gdW5kZWZpbmVkICYmIHVzZXJOYW1lcy5oYXMoZW50cnkuc2VydmljZV9wcmluY2lwYWxfbmFtZSkpIHx8XG4gICAgICAoZW50cnkuZ3JvdXBfbmFtZSAhPT0gdW5kZWZpbmVkICYmIGdyb3VwTmFtZXMuaGFzKGVudHJ5Lmdyb3VwX25hbWUpKTtcbiAgICByZXR1cm4gKFxuICAgICAgbWF0Y2hlcyAmJlxuICAgICAgKGVudHJ5LmFsbF9wZXJtaXNzaW9ucyA/PyBbXSkuc29tZShcbiAgICAgICAgKHBlcm1pc3Npb24pID0+IHBlcm1pc3Npb24ucGVybWlzc2lvbl9sZXZlbCA9PT0gXCJDQU5fTUFOQUdFXCIsXG4gICAgICApXG4gICAgKTtcbiAgfSk7XG4gIGlmICghY2FuTWFuYWdlKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGhvc3QgPSAoYXdhaXQgY2xpZW50LmNvbmZpZy5nZXRIb3N0KCkpLnRvU3RyaW5nKCk7XG4gIHJldHVybiBuZXcgVVJMKGAvbWwvZXhwZXJpbWVudHMvJHtlbmNvZGVVUklDb21wb25lbnQoZXhwZXJpbWVudElkKX1gLCBob3N0KS50b1N0cmluZygpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmZXRjaEV4cGVyaW1lbnQoXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50LFxuKTogUHJvbWlzZTx7IGV4cGVyaW1lbnRfaWQ6IHN0cmluZzsgdGFncz86IHVua25vd24gfSB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBleHBlcmltZW50ID0gY29uZmlndXJlZEV4cGVyaW1lbnQoKTtcbiAgY29uc3QgcGF0aCA9IGV4cGVyaW1lbnQuaWRcbiAgICA/IGAvYXBpLzIuMC9tbGZsb3cvZXhwZXJpbWVudHMvZ2V0P2V4cGVyaW1lbnRfaWQ9JHtlbmNvZGVVUklDb21wb25lbnQoZXhwZXJpbWVudC5pZCl9YFxuICAgIDogZXhwZXJpbWVudC5uYW1lXG4gICAgICA/IGAvYXBpLzIuMC9tbGZsb3cvZXhwZXJpbWVudHMvZ2V0LWJ5LW5hbWU/ZXhwZXJpbWVudF9uYW1lPSR7ZW5jb2RlVVJJQ29tcG9uZW50KFxuICAgICAgICAgIGV4cGVyaW1lbnQubmFtZSxcbiAgICAgICAgKX1gXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKCFwYXRoKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGRhdGFicmlja3NGZXRjaChjbGllbnQsIHBhdGgsIHsgbWV0aG9kOiBcIkdFVFwiIH0pO1xuICBpZiAoIXJlc3BvbnNlLm9rKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBwYXJzZWQgPSBNbGZsb3dFeHBlcmltZW50UmVzcG9uc2VTY2hlbWEuc2FmZVBhcnNlKGF3YWl0IHJlYWRSZXNwb25zZUpzb24ocmVzcG9uc2UpKTtcbiAgcmV0dXJuIHBhcnNlZC5zdWNjZXNzID8gcGFyc2VkLmRhdGEuZXhwZXJpbWVudCA6IHVuZGVmaW5lZDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUV4cGVyaW1lbnRJZChjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGNvbmZpZ3VyZWQgPSBjb25maWd1cmVkRXhwZXJpbWVudCgpO1xuICBpZiAoY29uZmlndXJlZC5pZCkgcmV0dXJuIGNvbmZpZ3VyZWQuaWQ7XG4gIHJldHVybiAoYXdhaXQgZmV0Y2hFeHBlcmltZW50KGNsaWVudCkpPy5leHBlcmltZW50X2lkO1xufVxuXG4vKiogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGxvZ0ZlZWRiYWNrfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTG9nRmVlZGJhY2tQYXJhbXMge1xuICAvKiogTUxmbG93IHRyYWNlIGlkIHRoZSBhc3Nlc3NtZW50IGF0dGFjaGVzIHRvIChgdHItPGhleD5gKS4gKi9cbiAgdHJhY2VJZDogc3RyaW5nO1xuICAvKiogQXNzZXNzbWVudCBuYW1lOyBkZWZhdWx0cyBwZXIgd2hldGhlciBhIHZhbHVlIG9yIGEgY29tbWVudCBpcyBzZW50LiAqL1xuICBuYW1lPzogc3RyaW5nO1xuICAvKiogVGh1bWJzIC8gcmF0aW5nIC8gbGFiZWwgdmFsdWUuIE9taXQgZm9yIGEgY29tbWVudC1vbmx5IHN1Ym1pc3Npb24uICovXG4gIHZhbHVlPzogYm9vbGVhbiB8IG51bWJlciB8IHN0cmluZztcbiAgLyoqIEZyZWVmb3JtIGNvbW1lbnQ6IHRoZSByYXRpb25hbGUgYWxvbmdzaWRlIGEgdmFsdWUsIG9yIHRoZSB2YWx1ZSBpdHNlbGYgd2hlbiBub25lLiAqL1xuICBjb21tZW50Pzogc3RyaW5nO1xuICAvKiogSWRlbnRpdHkgdGhlIGZlZWRiYWNrIGlzIGF0dHJpYnV0ZWQgdG8gKHVzZXIgZW1haWwgLyBpZCkuICovXG4gIHNvdXJjZUlkPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIExvZyBhIEhVTUFOIGZlZWRiYWNrIGFzc2Vzc21lbnQgdG8gYSB0cmFjZS4gUmV0dXJucyB0aGUgY3JlYXRlZFxuICogYXNzZXNzbWVudCBpZCBvbiBzdWNjZXNzLCBvciBgdW5kZWZpbmVkYCB3aGVuIHRoZSB0cmFjZSBjYW4ndCBiZVxuICogZm91bmQgKGV2ZW4gYWZ0ZXIgcmV0cnlpbmcgZm9yIGV4cG9ydCBsYWcpIG9yIHRoZSByZXF1ZXN0IG90aGVyd2lzZVxuICogZmFpbHMgLSBjYWxsZXJzIHN1cmZhY2UgdGhhdCBhcyBhIHNvZnQgXCJub3QgcmVjb3JkZWRcIiByYXRoZXIgdGhhbiBhblxuICogZXJyb3IsIGtlZXBpbmcgdGhlIGNoYXQgdXNhYmxlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9nRmVlZGJhY2soXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50LFxuICBwYXJhbXM6IExvZ0ZlZWRiYWNrUGFyYW1zLFxuKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgLy8gQSBjb21tZW50IHdpdGggbm8gdGh1bWJzIHZhbHVlIGlzIGxvZ2dlZCBhcyB0ZXh0IGZlZWRiYWNrOyBhIHZhbHVlXG4gIC8vICh3aXRoIGFuIG9wdGlvbmFsIGNvbW1lbnQgYXMgdGhlIHJhdGlvbmFsZSkgaXMgdGhlIHRodW1icyBwYXRoLlxuICBjb25zdCBoYXNWYWx1ZSA9IHBhcmFtcy52YWx1ZSAhPT0gdW5kZWZpbmVkO1xuICBjb25zdCBuYW1lID1cbiAgICBwYXJhbXMubmFtZT8udHJpbSgpIHx8XG4gICAgKGhhc1ZhbHVlID8gZmVlZGJhY2suREVGQVVMVF9GRUVEQkFDS19OQU1FIDogZmVlZGJhY2suREVGQVVMVF9DT01NRU5UX05BTUUpO1xuICBjb25zdCB2YWx1ZSA9IGhhc1ZhbHVlID8gcGFyYW1zLnZhbHVlIDogcGFyYW1zLmNvbW1lbnQ7XG4gIGNvbnN0IGFzc2Vzc21lbnRUcmFjZUlkID0gbWxmbG93QXNzZXNzbWVudFRyYWNlSWQoXG4gICAgcGFyYW1zLnRyYWNlSWQsXG4gICAgYXdhaXQgcmVzb2x2ZVVjVHJhY2VQcmVmaXgoY2xpZW50KSxcbiAgKTtcbiAgY29uc3QgYXNzZXNzbWVudDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7XG4gICAgdHJhY2VfaWQ6IGFzc2Vzc21lbnRUcmFjZUlkLFxuICAgIGFzc2Vzc21lbnRfbmFtZTogbmFtZSxcbiAgICBzb3VyY2U6IHtcbiAgICAgIHNvdXJjZV90eXBlOiBcIkhVTUFOXCIsXG4gICAgICBzb3VyY2VfaWQ6IHBhcmFtcy5zb3VyY2VJZD8udHJpbSgpIHx8IFwidXNlclwiLFxuICAgIH0sXG4gICAgZmVlZGJhY2s6IHsgdmFsdWUgfSxcbiAgICAuLi4oaGFzVmFsdWUgJiYgcGFyYW1zLmNvbW1lbnQ/LnRyaW0oKSA/IHsgcmF0aW9uYWxlOiBwYXJhbXMuY29tbWVudCB9IDoge30pLFxuICB9O1xuICBjb25zdCBib2R5ID0geyBhc3Nlc3NtZW50IH07XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPD0gTk9UX0ZPVU5EX1JFVFJJRVM7IGF0dGVtcHQrKykge1xuICAgIGxldCByZXM6IFJlc3BvbnNlO1xuICAgIHRyeSB7XG4gICAgICByZXMgPSBhd2FpdCBkYXRhYnJpY2tzRmV0Y2goY2xpZW50LCBhc3Nlc3NtZW50c1BhdGgoYXNzZXNzbWVudFRyYWNlSWQpLCB7XG4gICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICAgIGJvZHksXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwiZmVlZGJhY2sgcmVxdWVzdCBmYWlsZWRcIiwge1xuICAgICAgICB0cmFjZUlkOiBwYXJhbXMudHJhY2VJZCxcbiAgICAgICAgYXNzZXNzbWVudFRyYWNlSWQsXG4gICAgICAgIGVycm9yOiBlcnJvclV0aWxzLmVycm9yTWVzc2FnZShlcnIpLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBpZiAocmVzLm9rKSB7XG4gICAgICBjb25zdCBwYXJzZWQgPSBhd2FpdCByZWFkUmVzcG9uc2VKc29uKHJlcyk7XG4gICAgICBjb25zdCBhc3Nlc3NtZW50SWQgPVxuICAgICAgICAocGFyc2VkIGFzIHsgYXNzZXNzbWVudD86IHsgYXNzZXNzbWVudF9pZD86IHVua25vd24gfSB9KT8uYXNzZXNzbWVudD8uYXNzZXNzbWVudF9pZCA/P1xuICAgICAgICAocGFyc2VkIGFzIHsgYXNzZXNzbWVudF9pZD86IHVua25vd24gfSk/LmFzc2Vzc21lbnRfaWQ7XG4gICAgICByZXR1cm4gdHlwZW9mIGFzc2Vzc21lbnRJZCA9PT0gXCJzdHJpbmdcIiA/IGFzc2Vzc21lbnRJZCA6IFwiXCI7XG4gICAgfVxuICAgIC8vIFRyYWNlIGV4cG9ydCBpcyBhc3luYzsgYSBmcmVzaCB0cmFjZSBtYXkgbm90IGV4aXN0IHlldC4gUmV0cnkgYVxuICAgIC8vIGZldyB0aW1lcyB3aXRoIGEgc2hvcnQgYmFja29mZiBiZWZvcmUgZ2l2aW5nIHVwIHNvZnRseS5cbiAgICBpZiAocmVzLnN0YXR1cyA9PT0gNDA0ICYmIGF0dGVtcHQgPCBOT1RfRk9VTkRfUkVUUklFUykge1xuICAgICAgYXdhaXQgYXN5bmNVdGlscy5zbGVlcChOT1RfRk9VTkRfQkFDS09GRl9NUyAqIChhdHRlbXB0ICsgMSkpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGxvZ2dlci53YXJuKFwiZmVlZGJhY2sgbm90IHJlY29yZGVkXCIsIHtcbiAgICAgIHRyYWNlSWQ6IHBhcmFtcy50cmFjZUlkLFxuICAgICAgYXNzZXNzbWVudFRyYWNlSWQsXG4gICAgICBzdGF0dXM6IHJlcy5zdGF0dXMsXG4gICAgICBib2R5OiBhd2FpdCByZWFkUmVzcG9uc2VUZXh0KHJlcyksXG4gICAgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuIl19