@pipeline-builder/pipeline-data 4.1.15 → 4.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/lib/api/access-control-builder.d.ts +18 -1
  2. package/lib/api/access-control-builder.js +19 -6
  3. package/lib/api/crud-service.d.ts +94 -36
  4. package/lib/api/crud-service.js +188 -166
  5. package/lib/api/plugin-resolution.d.ts +253 -0
  6. package/lib/api/plugin-resolution.js +649 -0
  7. package/lib/api/public-directory.d.ts +281 -0
  8. package/lib/api/public-directory.js +457 -0
  9. package/lib/api/query-builders.d.ts +13 -0
  10. package/lib/api/query-builders.js +74 -9
  11. package/lib/api/reporting/caches.js +4 -4
  12. package/lib/api/reporting/dora-scoring.d.ts +3 -3
  13. package/lib/api/reporting/dora-scoring.js +4 -4
  14. package/lib/api/reporting/dora.d.ts +6 -6
  15. package/lib/api/reporting/dora.js +97 -73
  16. package/lib/api/reporting/plugin-runtime.d.ts +25 -0
  17. package/lib/api/reporting/plugin-runtime.js +106 -0
  18. package/lib/api/reporting/query-scope.d.ts +8 -2
  19. package/lib/api/reporting/query-scope.js +16 -7
  20. package/lib/api/reporting/retention.d.ts +4 -10
  21. package/lib/api/reporting/retention.js +8 -11
  22. package/lib/api/reporting/sql-helpers.d.ts +4 -7
  23. package/lib/api/reporting/sql-helpers.js +8 -9
  24. package/lib/api/reporting/types.d.ts +55 -17
  25. package/lib/api/reporting/types.js +1 -1
  26. package/lib/api/reporting-service.d.ts +35 -26
  27. package/lib/api/reporting-service.js +245 -161
  28. package/lib/api/semver-range.d.ts +73 -0
  29. package/lib/api/semver-range.js +227 -0
  30. package/lib/api/soft-delete-sweep.js +8 -20
  31. package/lib/core/query-filters.d.ts +18 -3
  32. package/lib/core/query-filters.js +1 -1
  33. package/lib/database/drizzle-schema.d.ts +7790 -2461
  34. package/lib/database/drizzle-schema.js +29 -1
  35. package/lib/database/index.d.ts +4 -2
  36. package/lib/database/index.js +5 -3
  37. package/lib/database/pg-result.d.ts +19 -0
  38. package/lib/database/pg-result.js +32 -0
  39. package/lib/database/postgres-connection.js +14 -24
  40. package/lib/database/public-reader.d.ts +14 -0
  41. package/lib/database/public-reader.js +68 -0
  42. package/lib/database/retry-strategy.d.ts +3 -5
  43. package/lib/database/retry-strategy.js +4 -6
  44. package/lib/database/schema/compliance.d.ts +16 -34
  45. package/lib/database/schema/compliance.js +4 -4
  46. package/lib/database/schema/dashboard.js +4 -2
  47. package/lib/database/schema/ecosystem.d.ts +6586 -0
  48. package/lib/database/schema/ecosystem.js +709 -0
  49. package/lib/database/schema/message.d.ts +6 -12
  50. package/lib/database/schema/message.js +3 -1
  51. package/lib/database/schema/pipeline.d.ts +79 -5
  52. package/lib/database/schema/pipeline.js +46 -25
  53. package/lib/database/schema/plugin.d.ts +587 -3
  54. package/lib/database/schema/plugin.js +86 -14
  55. package/lib/database/tenancy.d.ts +6 -7
  56. package/lib/database/tenancy.js +13 -14
  57. package/lib/index.d.ts +7 -4
  58. package/lib/index.js +7 -4
  59. package/lib/testing/exports.json +146 -0
  60. package/package.json +44 -7
@@ -10,12 +10,107 @@ import { withTenantTx, runWithTenantContext } from '../database/tenancy.js';
10
10
  import { inventoryCache, timeseriesCache } from './reporting/caches.js';
11
11
  import { DORA_INCIDENT_WINDOW_HOURS, resolveIncidentWindowHours } from './reporting/dora-scoring.js';
12
12
  import { getDoraMetrics as doraMetrics, getDoraTrend as doraTrend, getBuildHealth as buildHealth, } from './reporting/dora.js';
13
- import { orgScope, runReport } from './reporting/query-scope.js';
13
+ import { getPluginRuntime as pluginRuntime, getPluginRuntimeAggregate as pluginRuntimeAggregate, hasVerifiedPluginUse as verifiedPluginUse, } from './reporting/plugin-runtime.js';
14
+ import { report } from './reporting/query-scope.js';
14
15
  // Aliased: the module functions and the delegating methods below share names.
15
16
  import { REPORTING_EVENT_RETENTION_DAYS, REPORTING_DORA_RETENTION_DAYS, resolveEventRetentionDays, resolveDoraRetentionDays, retentionCutoff, } from './reporting/retention.js';
16
- import { assertReportInterval, scrubOptional, optionalStartedAtRange } from './reporting/sql-helpers.js';
17
- export { resolveDoraRetentionDays, resolveEventRetentionDays, retentionCutoff } from './reporting/retention.js';
17
+ import { assertReportInterval, scrubOptional, optionalStartedAtRange, startedAtWindow } from './reporting/sql-helpers.js';
18
18
  const logger = createLogger('reporting-service');
19
+ /** An action/build event that can be attributed to a plugin step. */
20
+ function isAttributable(e) {
21
+ return (e.eventType === 'ACTION' || e.eventType === 'BUILD')
22
+ && (e.eventSource === 'codepipeline' || e.eventSource === 'codebuild')
23
+ && !!e.stageName && !!e.actionName;
24
+ }
25
+ function stepKey(pipelineId, stageName, actionName) {
26
+ return `${pipelineId}\u0000${stageName}\u0000${actionName}`;
27
+ }
28
+ /**
29
+ * Plugin attribution: the step manifests of every pipeline with an attributable
30
+ * event, in ONE read per batch, keyed for an in-memory join. Names are compared
31
+ * post-scrub on both sides (the manifest stores them scrubbed the same way).
32
+ */
33
+ async function loadStepPlugins(tx, attributable) {
34
+ const pipelineIds = [...new Set(attributable.map((e) => e.pipelineId))];
35
+ if (pipelineIds.length === 0)
36
+ return new Map();
37
+ const rows = await tx
38
+ .select({
39
+ pipelineId: schema.pipelineStepManifest.pipelineId,
40
+ orgId: schema.pipelineStepManifest.orgId,
41
+ stageName: schema.pipelineStepManifest.stageName,
42
+ actionName: schema.pipelineStepManifest.actionName,
43
+ pluginPublisher: schema.pipelineStepManifest.pluginPublisher,
44
+ pluginPublisherId: schema.pipelineStepManifest.pluginPublisherId,
45
+ pluginName: schema.pipelineStepManifest.pluginName,
46
+ pluginVersion: schema.pipelineStepManifest.pluginVersion,
47
+ })
48
+ .from(schema.pipelineStepManifest)
49
+ .where(inArray(schema.pipelineStepManifest.pipelineId, pipelineIds));
50
+ return new Map(rows.map((m) => [stepKey(m.pipelineId, m.stageName, m.actionName), m]));
51
+ }
52
+ /**
53
+ * The persisted row for one ingested event. This is the DURABLE persistence
54
+ * boundary: every user/AWS-derived free-form string is scrubbed here, and
55
+ * tenancy comes from the pipeline registry, never the caller's claimed org.
56
+ */
57
+ function toEventRow(event, registry, plugin) {
58
+ return {
59
+ // registry.pipelineId === event.pipelineId; the registry's is always a row
60
+ // that exists (FK) and its orgId is the trusted tenant.
61
+ pipelineId: registry.pipelineId,
62
+ orgId: registry.orgId,
63
+ eventSource: event.eventSource,
64
+ eventType: event.eventType,
65
+ status: event.status,
66
+ // An AWS-ASSIGNED UUID, not free-form text: it can't carry an account id,
67
+ // and scrubbing a 12-digit run inside it would corrupt the correlation key.
68
+ executionId: event.executionId,
69
+ // USER-AUTHORED pipeline-structure names — same untrusted origin as
70
+ // errorMessage, so scrubbed (a stage named with an ARN must not persist).
71
+ stageName: scrubOptional(event.stageName),
72
+ actionName: scrubOptional(event.actionName),
73
+ // HARD CONSTRAINT: an AWS account id must NEVER be persisted. Failure detail
74
+ // and messages routinely carry ARNs and bare 12-digit account ids.
75
+ errorMessage: scrubOptional(event.errorMessage),
76
+ startedAt: event.startedAt ? new Date(event.startedAt) : undefined,
77
+ completedAt: event.completedAt ? new Date(event.completedAt) : undefined,
78
+ durationMs: event.durationMs,
79
+ // Deploy attribution — scrubbed like the other free-form strings.
80
+ commitSha: scrubOptional(event.commitSha),
81
+ commitRef: scrubOptional(event.commitRef),
82
+ environment: scrubOptional(event.environment),
83
+ // Measured lead time: the oldest unshipped commit's time + the count. An
84
+ // SCM-derived instant and a plain integer — nothing to scrub.
85
+ commitTimestamp: event.commitTimestamp ? new Date(event.commitTimestamp) : undefined,
86
+ commitCount: event.commitCount,
87
+ // NULL for non-plugin actions and for pipelines deployed without a manifest.
88
+ pluginPublisher: plugin?.pluginPublisher ?? null,
89
+ pluginPublisherId: plugin?.pluginPublisherId ?? null,
90
+ pluginName: plugin?.pluginName ?? null,
91
+ pluginVersion: plugin?.pluginVersion ?? null,
92
+ detail: event.detail !== undefined ? scrubAwsIdentifiers(event.detail) : undefined,
93
+ };
94
+ }
95
+ /**
96
+ * Fan terminal STAGE outcomes into the route's metric hook (pipeline-data can't
97
+ * import api-server's registry) after the insert commits. Driven off the
98
+ * INSERTED rows, so a re-delivered event the dedup index swallowed is never
99
+ * counted twice. A non-null environment marks a deploy.
100
+ */
101
+ function emitStageMetrics(rows, onMetric) {
102
+ for (const r of rows) {
103
+ if (r.eventType !== 'STAGE' || (r.status !== 'SUCCEEDED' && r.status !== 'FAILED') || !r.pipelineId)
104
+ continue;
105
+ onMetric({
106
+ pipelineId: r.pipelineId,
107
+ orgId: r.orgId,
108
+ stage: r.stageName ?? '',
109
+ environment: r.environment ?? null,
110
+ result: r.status === 'SUCCEEDED' ? 'succeeded' : 'failed',
111
+ });
112
+ }
113
+ }
19
114
  export class ReportingService {
20
115
  /** Invalidate all cached reports for an org (call after event ingest). */
21
116
  async invalidateOrg(orgId) {
@@ -41,12 +136,9 @@ export class ReportingService {
41
136
  // org>` could only write events for that org; bypass via sysadmin is
42
137
  // the right gate for this server-internal cross-tenant endpoint. See
43
138
  // api/reporting/src/routes/event-ingest.ts for the wrapper.
44
- // Run insert inside the tx, but COLLECT affected orgs and invalidate
45
- // caches AFTER the tx resolves. Keeping invalidation inside the tx held
46
- // the pg locks open for the duration of the cache round-trips (Redis or
47
- // in-memory invalidations are unrelated to the tx but still serialized
48
- // its commit). Cache TTL is 2-5 min so fire-and-forget post-commit is
49
- // an acceptable trade for tighter lock windows.
139
+ // Caches are invalidated AFTER the tx resolves: doing it inside held the pg
140
+ // locks open across unrelated cache round-trips. The TTL is 2-5 min, so a
141
+ // fire-and-forget post-commit invalidation is an acceptable trade.
50
142
  const { inserted, skipped, unregisteredPipelineIds, affectedOrgs, insertedRows } = await withTenantTx(async (tx) => {
51
143
  // Batch-resolve all unique pipeline ids in one query
52
144
  const uniqueIds = [...new Set(events.map(e => e.pipelineId))];
@@ -58,6 +150,7 @@ export class ReportingService {
58
150
  .from(schema.pipelineRegistry)
59
151
  .where(inArray(schema.pipelineRegistry.pipelineId, uniqueIds));
60
152
  const idMap = new Map(registryRows.map(r => [r.pipelineId, r]));
153
+ const stepPlugins = await loadStepPlugins(tx, events.filter((e) => isAttributable(e) && idMap.has(e.pipelineId)));
61
154
  // Build insert batch (skip events whose pipeline isn't registered)
62
155
  const rows = [];
63
156
  let skippedLocal = 0;
@@ -69,49 +162,14 @@ export class ReportingService {
69
162
  unregisteredLocal.push(event.pipelineId);
70
163
  continue;
71
164
  }
72
- rows.push({
73
- // registry.pipelineId === event.pipelineId; use the registry's so the
74
- // FK is always a row that exists, and pull orgId from the registry for
75
- // tenancy (never trust the caller's claimed org).
76
- pipelineId: registry.pipelineId,
77
- orgId: registry.orgId,
78
- eventSource: event.eventSource,
79
- eventType: event.eventType,
80
- status: event.status,
81
- // executionId is an AWS-ASSIGNED identifier (a UUID), not free-form
82
- // user text, so it can't carry an account id — and scrubbing a UUID
83
- // that happens to contain a 12-digit run would corrupt the correlation
84
- // key. Left intact by design.
85
- executionId: event.executionId,
86
- // stageName/actionName are USER-AUTHORED pipeline-structure names
87
- // promoted from the CodePipeline detail — same untrusted-AWS-derived
88
- // origin as errorMessage below, so scrub them at this persistence
89
- // boundary too (a stage named with an ARN/12-digit id must not persist).
90
- stageName: scrubOptional(event.stageName),
91
- actionName: scrubOptional(event.actionName),
92
- // HARD CONSTRAINT: an AWS account id must NEVER be persisted. This is
93
- // the DURABLE persistence boundary and must not trust upstream:
94
- // CodePipeline/CodeBuild failure detail & messages routinely carry
95
- // ARNs (arn:aws:…:<account-id>:…) and bare 12-digit account ids. Scrub
96
- // both free-form fields here before insert (per-event, non-mutating).
97
- errorMessage: scrubOptional(event.errorMessage),
98
- startedAt: event.startedAt ? new Date(event.startedAt) : undefined,
99
- completedAt: event.completedAt ? new Date(event.completedAt) : undefined,
100
- durationMs: event.durationMs,
101
- // Deploy-attribution fields — scrubbed like the other free-form strings
102
- // so an ARN/account id can never enter via a ref or environment name.
103
- commitSha: scrubOptional(event.commitSha),
104
- commitRef: scrubOptional(event.commitRef),
105
- environment: scrubOptional(event.environment),
106
- // Measured lead time (Phase 4): oldest unshipped commit time + count.
107
- // commitTimestamp is an AWS/SCM-derived instant (never account-id
108
- // shaped); commitCount is a plain integer. Neither needs scrubbing.
109
- commitTimestamp: event.commitTimestamp ? new Date(event.commitTimestamp) : undefined,
110
- commitCount: event.commitCount,
111
- detail: event.detail !== undefined
112
- ? scrubAwsIdentifiers(event.detail)
113
- : undefined,
114
- });
165
+ const stageName = scrubOptional(event.stageName);
166
+ const actionName = scrubOptional(event.actionName);
167
+ const step = isAttributable(event) && stageName && actionName
168
+ ? stepPlugins.get(stepKey(registry.pipelineId, stageName, actionName))
169
+ : undefined;
170
+ // Same-org guard: a manifest row is only ever written by the org that
171
+ // owns the pipeline, but the ingest runs cross-tenant, so don't lean on it.
172
+ rows.push(toEventRow(event, registry, step && step.orgId === registry.orgId ? step : undefined));
115
173
  }
116
174
  // SQS is at-least-once, so EventBridge can deliver the same state-change
117
175
  // twice. `onConflictDoNothing` + the partial unique index on
@@ -138,25 +196,8 @@ export class ReportingService {
138
196
  insertedRows: landed,
139
197
  };
140
198
  });
141
- // Phase 3b: fan terminal STAGE outcomes into Prometheus counters via the
142
- // route's hook (pipeline-data can't import api-server's registry), after the
143
- // insert COMMITS. Driven off the INSERTED rows — not the request batch — so a re-delivered event
144
- // the dedup index swallowed is never counted twice (counters, unlike the
145
- // table, have no idempotency of their own). Values are the persisted,
146
- // already-scrubbed columns. A non-null environment also marks a deploy.
147
- if (onMetric) {
148
- for (const r of insertedRows) {
149
- if (r.eventType !== 'STAGE' || (r.status !== 'SUCCEEDED' && r.status !== 'FAILED') || !r.pipelineId)
150
- continue;
151
- onMetric({
152
- pipelineId: r.pipelineId,
153
- orgId: r.orgId,
154
- stage: r.stageName ?? '',
155
- environment: r.environment ?? null,
156
- result: r.status === 'SUCCEEDED' ? 'succeeded' : 'failed',
157
- });
158
- }
159
- }
199
+ if (onMetric)
200
+ emitStageMetrics(insertedRows, onMetric);
160
201
  // Surface the silent skip: an unregistered pipeline id usually means the
161
202
  // pipeline hasn't called POST /pipelines/registry yet (or its
162
203
  // pb.pipeline-id tag is missing/unreadable by the Lambda). Logging it
@@ -177,9 +218,8 @@ export class ReportingService {
177
218
  return { inserted, skipped, unregisteredPipelineIds, affectedOrgs };
178
219
  }
179
220
  // ── Category 1: Pipeline Execution & Performance ──
180
- /** 1.1 Execution count per pipeline with status breakdown. */
221
+ /** Execution count per pipeline with status breakdown. */
181
222
  async getExecutionCount(orgId, orgIds, range) {
182
- const { pred, multi } = orgScope(orgId, orgIds);
183
223
  // Optional [from,to] window on the execution's started_at, mirroring the
184
224
  // sibling timeseries reports so the dashboard date-range picker narrows the
185
225
  // count too (an empty range = all-time, preserving the prior behavior). The
@@ -187,7 +227,7 @@ export class ReportingService {
187
227
  // (LEFT semantics preserved via the inner-join filter — a pipeline with zero
188
228
  // matching events drops from the count, same as before for its window).
189
229
  const rangeClause = optionalStartedAtRange(range);
190
- const exec = () => withTenantTx((tx) => tx.execute(sql `
230
+ return report(`exec-count:${range?.from ?? ''}:${range?.to ?? ''}`, orgId, orgIds, (pred) => sql `
191
231
  SELECT
192
232
  p.id, p.project, p.organization, p.pipeline_name,
193
233
  COUNT(*)::int AS total,
@@ -203,11 +243,10 @@ export class ReportingService {
203
243
  WHERE p.org_id ${pred} AND p.is_active = true
204
244
  GROUP BY p.id
205
245
  ORDER BY total DESC
206
- `).then(r => drizzleRows(r.rows)));
207
- return runReport(`${orgId}:exec-count:${range?.from ?? ''}:${range?.to ?? ''}`, multi, exec);
246
+ `);
208
247
  }
209
248
  /**
210
- * 1.1b Per-pipeline execution history — DISTINCT executions for one pipeline,
249
+ * Per-pipeline execution history — DISTINCT executions for one pipeline,
211
250
  * newest first. Groups all events by `execution_id` in a single scan and
212
251
  * rolls each execution up to one row:
213
252
  * - status: derived from the PIPELINE-type events. FAILED wins, then
@@ -223,9 +262,8 @@ export class ReportingService {
223
262
  * subtree. A pipelineId belonging to another org yields zero rows.
224
263
  */
225
264
  async listPipelineExecutions(orgId, pipelineId, orgIds, range, limit = 50) {
226
- const { pred, multi } = orgScope(orgId, orgIds);
227
265
  const rangeClause = optionalStartedAtRange(range);
228
- const exec = () => withTenantTx((tx) => tx.execute(sql `
266
+ return report(`pipeline-executions:${pipelineId}:${range?.from ?? ''}:${range?.to ?? ''}:${limit}`, orgId, orgIds, (pred) => sql `
229
267
  SELECT
230
268
  e.execution_id,
231
269
  CASE
@@ -246,14 +284,12 @@ export class ReportingService {
246
284
  GROUP BY e.execution_id
247
285
  ORDER BY MAX(e.created_at) DESC
248
286
  LIMIT ${limit}
249
- `).then(r => drizzleRows(r.rows)));
250
- return runReport(`${orgId}:pipeline-executions:${pipelineId}:${range?.from ?? ''}:${range?.to ?? ''}:${limit}`, multi, exec);
287
+ `);
251
288
  }
252
- /** 1.2 Success rate over time for an org. */
289
+ /** Success rate over time for an org. */
253
290
  async getSuccessRate(orgId, interval, from, to, orgIds) {
254
291
  assertReportInterval(interval);
255
- const { pred, multi } = orgScope(orgId, orgIds);
256
- const exec = () => withTenantTx((tx) => tx.execute(sql `
292
+ return report(`success-rate:${interval}:${from}:${to}`, orgId, orgIds, (pred) => sql `
257
293
  SELECT
258
294
  DATE_TRUNC(${interval}, e.started_at)::text AS period,
259
295
  COUNT(*) FILTER (WHERE e.status = 'SUCCEEDED')::int AS succeeded,
@@ -265,15 +301,13 @@ export class ReportingService {
265
301
  JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
266
302
  WHERE p.org_id ${pred} AND e.event_type = 'PIPELINE'
267
303
  AND e.status IN ('SUCCEEDED', 'FAILED', 'CANCELED')
268
- AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
304
+ AND ${startedAtWindow(from, to)}
269
305
  GROUP BY period ORDER BY period
270
- `).then(r => drizzleRows(r.rows)));
271
- return runReport(`${orgId}:success-rate:${interval}:${from}:${to}`, multi, exec);
306
+ `);
272
307
  }
273
- /** 1.3 Average duration per pipeline. */
308
+ /** Average duration per pipeline. */
274
309
  async getAverageDuration(orgId, from, to, orgIds) {
275
- const { pred, multi } = orgScope(orgId, orgIds);
276
- const exec = () => withTenantTx((tx) => tx.execute(sql `
310
+ return report(`avg-duration:${from}:${to}`, orgId, orgIds, (pred) => sql `
277
311
  SELECT
278
312
  p.id, p.project, p.pipeline_name,
279
313
  AVG(e.duration_ms)::int AS avg_ms,
@@ -284,15 +318,13 @@ export class ReportingService {
284
318
  FROM ${schema.pipelineEvent} e
285
319
  JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
286
320
  WHERE p.org_id ${pred} AND e.event_type = 'PIPELINE' AND e.duration_ms IS NOT NULL
287
- AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
321
+ AND ${startedAtWindow(from, to)}
288
322
  GROUP BY p.id ORDER BY avg_ms DESC
289
- `).then(r => drizzleRows(r.rows)));
290
- return runReport(`${orgId}:avg-duration:${from}:${to}`, multi, exec);
323
+ `);
291
324
  }
292
- /** 1.5 Stage failure heatmap — which stages fail most. */
325
+ /** Stage failure heatmap — which stages fail most. */
293
326
  async getStageFailures(orgId, from, to, orgIds) {
294
- const { pred, multi } = orgScope(orgId, orgIds);
295
- const exec = () => withTenantTx((tx) => tx.execute(sql `
327
+ return report(`stage-failures:${from}:${to}`, orgId, orgIds, (pred) => sql `
296
328
  SELECT
297
329
  e.stage_name,
298
330
  COUNT(*) FILTER (WHERE e.status = 'FAILED')::int AS failures,
@@ -302,10 +334,9 @@ export class ReportingService {
302
334
  FROM ${schema.pipelineEvent} e
303
335
  JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
304
336
  WHERE p.org_id ${pred} AND e.event_type = 'STAGE' AND e.stage_name IS NOT NULL
305
- AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
337
+ AND ${startedAtWindow(from, to)}
306
338
  GROUP BY e.stage_name ORDER BY failures DESC
307
- `).then(r => drizzleRows(r.rows)));
308
- return runReport(`${orgId}:stage-failures:${from}:${to}`, multi, exec);
339
+ `);
309
340
  }
310
341
  /**
311
342
  * Distinct deploy `environment` values observed in the window — powers the
@@ -313,21 +344,19 @@ export class ReportingService {
313
344
  * reports; only non-null environments (i.e. deploy-attributed executions).
314
345
  */
315
346
  async getReportEnvironments(orgId, from, to, orgIds) {
316
- const { pred, multi } = orgScope(orgId, orgIds);
317
- const exec = () => withTenantTx((tx) => tx.execute(sql `
347
+ const rows = await report(`report-envs:${from}:${to}`, orgId, orgIds, (pred) => sql `
318
348
  SELECT DISTINCT e.environment AS environment
319
349
  FROM ${schema.pipelineEvent} e
320
350
  JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
321
351
  WHERE p.org_id ${pred} AND e.environment IS NOT NULL
322
- AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
352
+ AND ${startedAtWindow(from, to)}
323
353
  ORDER BY environment
324
- `).then(r => drizzleRows(r.rows).map((row) => row.environment)));
325
- return runReport(`${orgId}:report-envs:${from}:${to}`, multi, exec);
354
+ `);
355
+ return rows.map((row) => row.environment);
326
356
  }
327
- /** 1.6 Stage bottlenecks — slowest stages per pipeline. */
357
+ /** Stage bottlenecks — slowest stages per pipeline. */
328
358
  async getStageBottlenecks(orgId, from, to, orgIds) {
329
- const { pred, multi } = orgScope(orgId, orgIds);
330
- const exec = () => withTenantTx((tx) => tx.execute(sql `
359
+ return report(`stage-bottlenecks:${from}:${to}`, orgId, orgIds, (pred) => sql `
331
360
  SELECT
332
361
  p.id, p.pipeline_name, e.stage_name,
333
362
  AVG(e.duration_ms)::int AS avg_ms,
@@ -335,15 +364,13 @@ export class ReportingService {
335
364
  FROM ${schema.pipelineEvent} e
336
365
  JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
337
366
  WHERE p.org_id ${pred} AND e.event_type = 'STAGE' AND e.duration_ms IS NOT NULL
338
- AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
367
+ AND ${startedAtWindow(from, to)}
339
368
  GROUP BY p.id, e.stage_name ORDER BY avg_ms DESC
340
- `).then(r => drizzleRows(r.rows)));
341
- return runReport(`${orgId}:stage-bottlenecks:${from}:${to}`, multi, exec);
369
+ `);
342
370
  }
343
- /** 1.7 Action failure rate — which plugin steps fail most. */
371
+ /** Action failure rate — which plugin steps fail most. */
344
372
  async getActionFailures(orgId, from, to, orgIds) {
345
- const { pred, multi } = orgScope(orgId, orgIds);
346
- const exec = () => withTenantTx((tx) => tx.execute(sql `
373
+ return report(`action-failures:${from}:${to}`, orgId, orgIds, (pred) => sql `
347
374
  SELECT
348
375
  e.action_name,
349
376
  COUNT(*) FILTER (WHERE e.status = 'FAILED')::int AS failures,
@@ -353,20 +380,18 @@ export class ReportingService {
353
380
  FROM ${schema.pipelineEvent} e
354
381
  JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
355
382
  WHERE p.org_id ${pred} AND e.event_type = 'ACTION' AND e.action_name IS NOT NULL
356
- AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
383
+ AND ${startedAtWindow(from, to)}
357
384
  GROUP BY e.action_name ORDER BY failures DESC
358
- `).then(r => drizzleRows(r.rows)));
359
- return runReport(`${orgId}:action-failures:${from}:${to}`, multi, exec);
385
+ `);
360
386
  }
361
387
  /**
362
- * 1.8 Error categorization — group failure messages. Execution report, so
388
+ * Error categorization — group failure messages. Execution report, so
363
389
  * rollup-aware exactly like the sibling execution reports: with `orgIds`
364
390
  * (the org→team subtree) the org gate becomes an `IN (...)` and the read runs
365
391
  * fresh under sysadmin via `runReport`; single-org reads keep the per-org cache.
366
392
  */
367
393
  async getErrors(orgId, from, to, limit = 20, orgIds) {
368
- const { pred, multi } = orgScope(orgId, orgIds);
369
- const exec = () => withTenantTx((tx) => tx.execute(sql `
394
+ return report(`errors:${from}:${to}:${limit}`, orgId, orgIds, (pred) => sql `
370
395
  SELECT
371
396
  SUBSTRING(e.error_message FROM 1 FOR 200) AS error_pattern,
372
397
  COUNT(*)::int AS occurrences,
@@ -375,11 +400,10 @@ export class ReportingService {
375
400
  FROM ${schema.pipelineEvent} e
376
401
  JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
377
402
  WHERE p.org_id ${pred} AND e.status = 'FAILED' AND e.error_message IS NOT NULL
378
- AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
403
+ AND ${startedAtWindow(from, to)}
379
404
  GROUP BY error_pattern ORDER BY occurrences DESC
380
405
  LIMIT ${limit}
381
- `).then(r => drizzleRows(r.rows)));
382
- return runReport(`${orgId}:errors:${from}:${to}:${limit}`, multi, exec);
406
+ `);
383
407
  }
384
408
  /**
385
409
  * The four DORA measures plus their per-environment breakdown.
@@ -413,7 +437,7 @@ export class ReportingService {
413
437
  return (drizzleRows(rows.rows)[0] || { total: 0, active: 0, inactive: 0, public: 0, org: 0, private: 0, uniqueNames: 0 });
414
438
  });
415
439
  }
416
- /** 2.2 Type & compute distribution.
440
+ /** Type & compute distribution.
417
441
  * INTENTIONALLY SINGLE-ORG (no rollup): plugin inventory is per-org (see
418
442
  * getPluginSummary). Single `= $org` scope. */
419
443
  async getPluginDistribution(orgId) {
@@ -428,7 +452,7 @@ export class ReportingService {
428
452
  ORDER BY count DESC
429
453
  `).then(r => drizzleRows(r.rows))));
430
454
  }
431
- /** 2.3 Version counts per plugin name.
455
+ /** Version counts per plugin name.
432
456
  * INTENTIONALLY SINGLE-ORG (no rollup): plugin inventory is per-org (see
433
457
  * getPluginSummary). Single `= $org` scope. */
434
458
  async getPluginVersions(orgId) {
@@ -458,7 +482,7 @@ export class ReportingService {
458
482
  `).then(r => drizzleRows(r.rows))));
459
483
  }
460
484
  /**
461
- * 2.4 Build success rate over time.
485
+ * Build success rate over time.
462
486
  *
463
487
  * STATUS CASING NOTE: This query filters by `event_source = 'plugin-build'`
464
488
  * and uses lowercase status values (`'completed'`, `'failed'`), while
@@ -476,8 +500,7 @@ export class ReportingService {
476
500
  // Build activity report — rollup-aware like the execution reports. These
477
501
  // rows are gated on the pipeline_event `org_id` directly (no pipeline join),
478
502
  // so `pred` applies to `e.org_id`.
479
- const { pred, multi } = orgScope(orgId, orgIds);
480
- const exec = () => withTenantTx((tx) => tx.execute(sql `
503
+ return report(`build-success:${interval}:${from}:${to}`, orgId, orgIds, (pred) => sql `
481
504
  SELECT
482
505
  DATE_TRUNC(${interval}, e.started_at)::text AS period,
483
506
  COUNT(*) FILTER (WHERE e.status = 'completed')::int AS succeeded,
@@ -487,15 +510,13 @@ export class ReportingService {
487
510
  FROM ${schema.pipelineEvent} e
488
511
  WHERE e.org_id ${pred} AND e.event_source = 'plugin-build'
489
512
  AND e.status IN ('completed', 'failed')
490
- AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
513
+ AND ${startedAtWindow(from, to)}
491
514
  GROUP BY period ORDER BY period
492
- `).then(r => drizzleRows(r.rows)));
493
- return runReport(`${orgId}:build-success:${interval}:${from}:${to}`, multi, exec);
515
+ `);
494
516
  }
495
- /** 2.5 Build duration per plugin. Build activity report — rollup-aware. */
517
+ /** Build duration per plugin. Build activity report — rollup-aware. */
496
518
  async getBuildDuration(orgId, from, to, orgIds) {
497
- const { pred, multi } = orgScope(orgId, orgIds);
498
- const exec = () => withTenantTx((tx) => tx.execute(sql `
519
+ return report(`build-duration:${from}:${to}`, orgId, orgIds, (pred) => sql `
499
520
  SELECT
500
521
  e.detail->>'pluginName' AS plugin_name,
501
522
  AVG(e.duration_ms)::int AS avg_ms,
@@ -503,15 +524,13 @@ export class ReportingService {
503
524
  COUNT(*)::int AS builds
504
525
  FROM ${schema.pipelineEvent} e
505
526
  WHERE e.org_id ${pred} AND e.event_source = 'plugin-build' AND e.duration_ms IS NOT NULL
506
- AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
527
+ AND ${startedAtWindow(from, to)}
507
528
  GROUP BY plugin_name ORDER BY avg_ms DESC
508
- `).then(r => drizzleRows(r.rows)));
509
- return runReport(`${orgId}:build-duration:${from}:${to}`, multi, exec);
529
+ `);
510
530
  }
511
- /** 2.6 Build failures — top error messages. Build activity report — rollup-aware. */
531
+ /** Build failures — top error messages. Build activity report — rollup-aware. */
512
532
  async getBuildFailures(orgId, from, to, limit = 20, orgIds) {
513
- const { pred, multi } = orgScope(orgId, orgIds);
514
- const exec = () => withTenantTx((tx) => tx.execute(sql `
533
+ return report(`build-failures:${from}:${to}:${limit}`, orgId, orgIds, (pred) => sql `
515
534
  SELECT
516
535
  e.detail->>'pluginName' AS plugin_name,
517
536
  e.error_message,
@@ -519,16 +538,32 @@ export class ReportingService {
519
538
  MAX(e.started_at)::text AS last_seen
520
539
  FROM ${schema.pipelineEvent} e
521
540
  WHERE e.org_id ${pred} AND e.event_source = 'plugin-build' AND e.status = 'failed'
522
- AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
541
+ AND ${startedAtWindow(from, to)}
523
542
  GROUP BY plugin_name, e.error_message
524
543
  ORDER BY occurrences DESC
525
544
  LIMIT ${limit}
526
- `).then(r => drizzleRows(r.rows)));
527
- return runReport(`${orgId}:build-failures:${from}:${to}:${limit}`, multi, exec);
545
+ `);
546
+ }
547
+ // ── Plugin runtime telemetry — see ./reporting/plugin-runtime.ts ──
548
+ /**
549
+ * Plugin runtime: per plugin version runs, success rate and p50/p95
550
+ * duration over `[from, to]`, from the manifest-attributed ACTION events.
551
+ * Rollup-aware.
552
+ */
553
+ async getPluginRuntime(orgId, from, to, filter, orgIds) {
554
+ return pluginRuntime(orgId, from, to, filter, orgIds);
555
+ }
556
+ /** Cross-org 30-day runtime aggregate for a `(publisher, name)` listing (plugin_stats input). Service callers only. */
557
+ async getPluginRuntimeAggregate(publisher, name) {
558
+ return pluginRuntimeAggregate(publisher, name);
559
+ }
560
+ /** Review "verified use": `orgId` ran `(publisher, name)` successfully within 90 days. Service callers only. */
561
+ async hasVerifiedPluginUse(orgId, publisher, name) {
562
+ return verifiedPluginUse(orgId, publisher, name);
528
563
  }
529
564
  // ── Category 3: DORA write paths (post-deploy outcomes + ingest health) ──
530
565
  /**
531
- * Record a manual post-deploy outcome marker (Phase 2): a user marks a
566
+ * Record a manual post-deploy outcome marker: a user marks a
532
567
  * deployment `failed` (a production incident linked to the deploy) or
533
568
  * `restored` (recovered). Idempotent — keyed on (execution_id, outcome) so a
534
569
  * duplicate POST refreshes `at` rather than double-counting, while a
@@ -555,7 +590,7 @@ export class ReportingService {
555
590
  });
556
591
  }
557
592
  /**
558
- * Ingest a production incident (Phase 5) from the org's incident tooling
593
+ * Ingest a production incident from the org's incident tooling
559
594
  * (PagerDuty / Datadog / Alertmanager webhook). Idempotent — keyed on
560
595
  * (org_id, incident_id) so a later resolve re-post upserts `resolved_at`
561
596
  * (and refreshes the other mutable fields) instead of inserting a duplicate.
@@ -579,7 +614,19 @@ export class ReportingService {
579
614
  severity,
580
615
  }).onConflictDoUpdate({
581
616
  target: [schema.incident.orgId, schema.incident.incidentId],
582
- set: { environment, openedAt, resolvedAt, severity },
617
+ // A redelivered FIRING post (no resolvedAt) must not wipe a recorded
618
+ // resolve — senders re-post firing alerts on every repeat interval, and
619
+ // delivery order isn't guaranteed. Keep the stored resolve unless the
620
+ // post carries its own, or the incident was RE-OPENED (a different
621
+ // openedAt means a new occurrence, whose resolve state is the post's).
622
+ set: {
623
+ environment,
624
+ openedAt,
625
+ resolvedAt: sql `CASE WHEN ${schema.incident.openedAt} = excluded.opened_at
626
+ THEN COALESCE(excluded.resolved_at, ${schema.incident.resolvedAt})
627
+ ELSE excluded.resolved_at END`,
628
+ severity,
629
+ },
583
630
  })));
584
631
  // A new/updated incident changes the DORA aggregate — drop cached reports.
585
632
  await this.invalidateOrg(orgId).catch((err) => {
@@ -587,12 +634,12 @@ export class ReportingService {
587
634
  });
588
635
  }
589
636
  /**
590
- * Read the per-org DORA settings (Phase 5b). Returns the stored
637
+ * Read the per-org DORA settings. Returns the stored
591
638
  * `incidentWindowHours` override (or `null` when unset) plus the global env
592
639
  * default, so the settings UI can show both. Runs under the caller's tenant
593
640
  * context (RLS-scoped); a single-org read.
594
641
  */
595
- async getIncidentSettings(orgId) {
642
+ async getReportingSettings(orgId, retentionOrgId = orgId) {
596
643
  const rows = drizzleRows((await withTenantTx((tx) => tx.execute(sql `
597
644
  SELECT ${schema.doraSettings.incidentWindowHours} AS incident_window_hours,
598
645
  ${schema.doraSettings.eventRetentionDays} AS event_retention_days,
@@ -602,17 +649,38 @@ export class ReportingService {
602
649
  LIMIT 1
603
650
  `))).rows);
604
651
  const row = rows[0];
652
+ // Retention is a billing entitlement synced onto the account ROOT only; a
653
+ // team reads its root's window (the incident window stays the team's own).
654
+ const retention = retentionOrgId === orgId
655
+ ? row
656
+ : await this.#readRetentionOverride(retentionOrgId);
605
657
  return {
606
658
  incidentWindowHours: row?.incident_window_hours != null ? Number(row.incident_window_hours) : null,
607
659
  defaultWindowHours: DORA_INCIDENT_WINDOW_HOURS,
608
- eventRetentionDays: row?.event_retention_days != null ? Number(row.event_retention_days) : null,
609
- doraRetentionDays: row?.dora_retention_days != null ? Number(row.dora_retention_days) : null,
660
+ eventRetentionDays: retention?.event_retention_days != null ? Number(retention.event_retention_days) : null,
661
+ doraRetentionDays: retention?.dora_retention_days != null ? Number(retention.dora_retention_days) : null,
610
662
  defaultEventRetentionDays: REPORTING_EVENT_RETENTION_DAYS,
611
663
  defaultDoraRetentionDays: REPORTING_DORA_RETENTION_DAYS,
612
664
  };
613
665
  }
614
666
  /**
615
- * Upsert per-org reporting settings (Phase 5b incident window + Phase 7
667
+ * The ROOT org's stored retention override. The caller (a team) can't see the
668
+ * root's `dora_settings` row under its own RLS scope, so this narrow read of
669
+ * two integer columns — keyed by the explicit, JWT-derived root id — runs in a
670
+ * sysadmin scope.
671
+ */
672
+ async #readRetentionOverride(orgId) {
673
+ const rows = await runWithTenantContext({ isSuperAdmin: true }, async () => drizzleRows((await withTenantTx((tx) => tx.execute(sql `
674
+ SELECT ${schema.doraSettings.eventRetentionDays} AS event_retention_days,
675
+ ${schema.doraSettings.doraRetentionDays} AS dora_retention_days
676
+ FROM ${schema.doraSettings}
677
+ WHERE ${schema.doraSettings.orgId} = ${orgId}
678
+ LIMIT 1
679
+ `))).rows));
680
+ return rows[0];
681
+ }
682
+ /**
683
+ * Upsert per-org reporting settings (incident window +
616
684
  * retention overrides), idempotent on `org_id`. A partial write — only the
617
685
  * fields present in `patch` are set (so updating retention never clears the
618
686
  * incident window, and vice-versa). Set self-serve by an org admin via
@@ -643,7 +711,7 @@ export class ReportingService {
643
711
  });
644
712
  }
645
713
  /**
646
- * List recent incidents for an org (Phase 5b org-admin surface), newest first,
714
+ * List recent incidents for an org (org-admin surface), newest first,
647
715
  * paginated. Each row carries its resolved state and its deploy correlation —
648
716
  * the most recent SUCCESSFUL deploy to the incident's `environment` whose
649
717
  * `completed_at` falls within the effective per-org correlation window before
@@ -652,7 +720,7 @@ export class ReportingService {
652
720
  * the `p.org_id`/`i.org_id` predicates + the tenant context.
653
721
  */
654
722
  async listIncidents(orgId, opts) {
655
- const { incidentWindowHours } = await this.getIncidentSettings(orgId);
723
+ const { incidentWindowHours } = await this.getReportingSettings(orgId);
656
724
  const windowHours = resolveIncidentWindowHours(incidentWindowHours);
657
725
  const limit = Math.max(1, Math.min(opts.limit, 200));
658
726
  const offset = Math.max(0, opts.offset);
@@ -695,7 +763,7 @@ export class ReportingService {
695
763
  }))));
696
764
  }
697
765
  /**
698
- * Wiring-test dry-run (Phase 5b): would a synthetic incident opening NOW for
766
+ * Wiring-test dry-run: would a synthetic incident opening NOW for
699
767
  * `environment` correlate to a recent successful deploy under the org's
700
768
  * effective window? This is a NON-persisting correlation check — it verifies
701
769
  * the admin's environment naming + window line up with real deploy events
@@ -704,7 +772,7 @@ export class ReportingService {
704
772
  async testIncidentCorrelation(orgId, environment) {
705
773
  const env = scrubAwsIdentifiersFromString(environment);
706
774
  const openedAt = new Date().toISOString();
707
- const { incidentWindowHours } = await this.getIncidentSettings(orgId);
775
+ const { incidentWindowHours } = await this.getReportingSettings(orgId);
708
776
  const windowHours = resolveIncidentWindowHours(incidentWindowHours);
709
777
  const rows = drizzleRows((await withTenantTx((tx) => tx.execute(sql `
710
778
  SELECT e.execution_id AS execution_id, e.completed_at::text AS completed_at
@@ -728,7 +796,7 @@ export class ReportingService {
728
796
  };
729
797
  }
730
798
  /**
731
- * Upsert per-org ingestion health (Phase 3): the AWS events Lambda periodically
799
+ * Upsert per-org ingestion health: the AWS events Lambda periodically
732
800
  * reports forwarded/dropped counters + the last event timestamp so the Reports
733
801
  * UI can show flowing / stale / dropping. One row per org (upsert on org_id).
734
802
  */
@@ -751,7 +819,7 @@ export class ReportingService {
751
819
  })));
752
820
  }
753
821
  /**
754
- * Read back one org's ingestion health (Phase 3) for the Reports UI freshness
822
+ * Read back one org's ingestion health for the Reports UI freshness
755
823
  * indicator. Returns `null` when the org has NO row — i.e. the deployment has
756
824
  * never ingested anything — which the UI must render as "no ingest reported
757
825
  * yet", never as "stale". RLS-scoped to the org like every other read.
@@ -774,7 +842,7 @@ export class ReportingService {
774
842
  }
775
843
  /**
776
844
  * Batched hard-DELETE of one reporting table's rows expired past a `created_at`
777
- * cutoff, scoped to an org and an optional row predicate (Phase 7). Uses a
845
+ * cutoff, scoped to an org and an optional row predicate. Uses a
778
846
  * `ctid`-in-subquery LIMIT so each statement touches at most `batchSize` rows
779
847
  * (short lock windows, no long table scan under lock); `RETURNING 1` lets us
780
848
  * count via `.rows.length` without depending on the driver's `rowCount`. Loops
@@ -807,7 +875,7 @@ export class ReportingService {
807
875
  return total;
808
876
  }
809
877
  /**
810
- * Reporting retention sweep (Phase 7). Hard-deletes rows older than their
878
+ * Reporting retention sweep. Hard-deletes rows older than their
811
879
  * retention window, by `created_at`, across every org that has reporting data —
812
880
  * a **split** policy so high-volume standard events expire faster than the
813
881
  * low-volume DORA source:
@@ -825,6 +893,7 @@ export class ReportingService {
825
893
  const batchSize = Math.max(1, opts.batchSize ?? 1000);
826
894
  const maxBatches = Math.max(1, opts.maxBatchesPerTable ?? 50);
827
895
  const now = opts.now ?? new Date();
896
+ const resolveRetentionOrgId = opts.resolveRetentionOrgId ?? (async (orgId) => orgId);
828
897
  const counts = {
829
898
  orgs: 0, standardEvents: 0, doraEvents: 0, deploymentOutcomes: 0, incidents: 0,
830
899
  };
@@ -853,10 +922,25 @@ export class ReportingService {
853
922
  const outcomesTable = sql `${schema.deploymentOutcome}`;
854
923
  const incidentsTable = sql `${schema.incident}`;
855
924
  for (const { org_id: orgId } of orgRows) {
856
- const ov = overrides.get(orgId);
925
+ // Retention follows the account ROOT's entitlement (billing syncs it onto
926
+ // the root only). An unresolvable root ⇒ skip this org this tick rather
927
+ // than purge a team's rows on the (shorter) env default.
928
+ let retentionOrgId;
929
+ try {
930
+ retentionOrgId = await resolveRetentionOrgId(orgId);
931
+ }
932
+ catch (err) {
933
+ logger.warn('Reporting retention: root resolution threw; skipping org this tick', { orgId, error: errorMessage(err) });
934
+ retentionOrgId = null;
935
+ }
936
+ if (retentionOrgId === null) {
937
+ logger.warn('Reporting retention: could not resolve the retention root; org skipped this tick', { orgId });
938
+ continue;
939
+ }
940
+ const ov = overrides.get(retentionOrgId);
857
941
  const eventDays = resolveEventRetentionDays(ov?.event_retention_days);
858
942
  const doraDays = resolveDoraRetentionDays(ov?.dora_retention_days);
859
- // `-1` = unlimited (Phase 8): keep forever, skip that window's deletes for
943
+ // `-1` = unlimited: keep forever, skip that window's deletes for
860
944
  // this org. Standard-event and DORA-source windows are independent; an org
861
945
  // with both `-1` is fully skipped. Log the skip so it's observable.
862
946
  const skipEvents = eventDays === -1;
@@ -897,4 +981,4 @@ export class ReportingService {
897
981
  }
898
982
  }
899
983
  export const reportingService = new ReportingService();
900
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0aW5nLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JlcG9ydGluZy1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM1SCxPQUFPLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFNUUsZ0ZBQWdGO0FBQ2hGLDRFQUE0RTtBQUM1RSxPQUFPLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3JHLE9BQU8sRUFDTCxjQUFjLElBQUksV0FBVyxFQUM3QixZQUFZLElBQUksU0FBUyxFQUN6QixjQUFjLElBQUksV0FBVyxHQUM5QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDakUsOEVBQThFO0FBQzlFLE9BQU8sRUFDTCw4QkFBOEIsRUFBRSw2QkFBNkIsRUFDN0QseUJBQXlCLEVBQUUsd0JBQXdCLEVBQUUsZUFBZSxHQUNyRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2xDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxhQUFhLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQXdCekcs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Q0FDekQsV0FBVyxFQUNYLEdBQUcsQ0FBQSxZQUFZLEtBQUssbUZBQW1GLFVBQVUsRUFBRSxFQUNuSCxTQUFTLEVBQUUsVUFBVSxDQUN0QixDQUFDO29CQUNGLE1BQU0sQ0FBQyxrQkFBa0IsSUFBSSxNQUFNLElBQUksQ0FBQywyQkFBMkIsQ0FDakUsYUFBYSxFQUNiLEdBQUcsQ0FBQSxZQUFZLEtBQUsscUJBQXFCLFVBQVUsRUFBRSxFQUNyRCxTQUFTLEVBQUUsVUFBVSxDQUN0QixDQUFDO29CQUNGLE1BQU0sQ0FBQyxTQUFTLElBQUksTUFBTSxJQUFJLENBQUMsMkJBQTJCLENBQ3hELGNBQWMsRUFDZCxHQUFHLENBQUEsWUFBWSxLQUFLLHFCQUFxQixVQUFVLEVBQUUsRUFDckQsU0FBUyxFQUFFLFVBQVUsQ0FDdEIsQ0FBQztnQkFDSixDQUFDO2dCQUNELE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDO1lBQ25CLENBQUM7WUFFRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsY0FBYyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDM0csSUFBSSxTQUFTLEdBQUcsQ0FBQztnQkFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLCtDQUErQyxFQUFFLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQy9GLE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBRUQsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlLCBzY3J1YkF3c0lkZW50aWZpZXJzLCBzY3J1YkF3c0lkZW50aWZpZXJzRnJvbVN0cmluZyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGVxLCBpbkFycmF5LCBzcWwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgeyBkcml6emxlUm93cyB9IGZyb20gJy4vY3J1ZC1zZXJ2aWNlLmpzJztcbmltcG9ydCB7IHNjaGVtYSB9IGZyb20gJy4uL2RhdGFiYXNlL2RyaXp6bGUtc2NoZW1hLmpzJztcbmltcG9ydCB7IHdpdGhUZW5hbnRUeCwgcnVuV2l0aFRlbmFudENvbnRleHQgfSBmcm9tICcuLi9kYXRhYmFzZS90ZW5hbmN5LmpzJztcblxuLy8gRXh0cmFjdGVkIGZvciBzaXplIOKAlCBzZWUgLi9yZXBvcnRpbmcvLiBFdmVyeXRoaW5nIHB1YmxpYyBpcyByZS1leHBvcnRlZCBiZWxvd1xuLy8gc28gYEBwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWRhdGFgJ3Mgc3VyZmFjZSBpcyB1bmNoYW5nZWQgYnkgdGhlIHNwbGl0LlxuaW1wb3J0IHsgaW52ZW50b3J5Q2FjaGUsIHRpbWVzZXJpZXNDYWNoZSB9IGZyb20gJy4vcmVwb3J0aW5nL2NhY2hlcy5qcyc7XG5pbXBvcnQgeyBET1JBX0lOQ0lERU5UX1dJTkRPV19IT1VSUywgcmVzb2x2ZUluY2lkZW50V2luZG93SG91cnMgfSBmcm9tICcuL3JlcG9ydGluZy9kb3JhLXNjb3JpbmcuanMnO1xuaW1wb3J0IHtcbiAgZ2V0RG9yYU1ldHJpY3MgYXMgZG9yYU1ldHJpY3MsXG4gIGdldERvcmFUcmVuZCBhcyBkb3JhVHJlbmQsXG4gIGdldEJ1aWxkSGVhbHRoIGFzIGJ1aWxkSGVhbHRoLFxufSBmcm9tICcuL3JlcG9ydGluZy9kb3JhLmpzJztcbmltcG9ydCB7IG9yZ1Njb3BlLCBydW5SZXBvcnQgfSBmcm9tICcuL3JlcG9ydGluZy9xdWVyeS1zY29wZS5qcyc7XG4vLyBBbGlhc2VkOiB0aGUgbW9kdWxlIGZ1bmN0aW9ucyBhbmQgdGhlIGRlbGVnYXRpbmcgbWV0aG9kcyBiZWxvdyBzaGFyZSBuYW1lcy5cbmltcG9ydCB7XG4gIFJFUE9SVElOR19FVkVOVF9SRVRFTlRJT05fREFZUywgUkVQT1JUSU5HX0RPUkFfUkVURU5USU9OX0RBWVMsXG4gIHJlc29sdmVFdmVudFJldGVudGlvbkRheXMsIHJlc29sdmVEb3JhUmV0ZW50aW9uRGF5cywgcmV0ZW50aW9uQ3V0b2ZmLFxufSBmcm9tICcuL3JlcG9ydGluZy9yZXRlbnRpb24uanMnO1xuaW1wb3J0IHsgYXNzZXJ0UmVwb3J0SW50ZXJ2YWwsIHNjcnViT3B0aW9uYWwsIG9wdGlvbmFsU3RhcnRlZEF0UmFuZ2UgfSBmcm9tICcuL3JlcG9ydGluZy9zcWwtaGVscGVycy5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIEV4ZWN1dGlvbkNvdW50LCBUaW1lU2VyaWVzRW50cnksIER1cmF0aW9uU3RhdHMsIFBpcGVsaW5lRXhlY3V0aW9uLCBTdGFnZUZhaWx1cmUsIFN0YWdlQm90dGxlbmVjayxcbiAgQWN0aW9uRmFpbHVyZSwgRXJyb3JFbnRyeSwgUGx1Z2luU3VtbWFyeSwgVHlwZUNvbXB1dGVEaXN0cmlidXRpb24sIFZlcnNpb25Db3VudCxcbiAgQnVpbGRUaW1lU2VyaWVzRW50cnksIEJ1aWxkRHVyYXRpb24sIEJ1aWxkRmFpbHVyZSxcbiAgUmVwb3J0aW5nUmV0ZW50aW9uT3B0aW9ucywgUmVwb3J0aW5nUmV0ZW50aW9uQ291bnRzLFxuICBEb3JhT3B0aW9ucywgSW5jaWRlbnRTZXR0aW5ncywgUmVwb3J0aW5nU2V0dGluZ3NQYXRjaCwgSW5jaWRlbnRMaXN0SXRlbSwgSW5jaWRlbnRUZXN0UmVzdWx0LFxuICBEb3JhTWV0cmljcywgRG9yYVRyZW5kUG9pbnQsIEJ1aWxkSGVhbHRoLCBJbmNpZGVudElucHV0LFxuICBJbmdlc3RFdmVudCwgSW5nZXN0TWV0cmljLCBJbmdlc3RSZXN1bHQsIEluZ2VzdEhlYWx0aFN0YXR1cyxcbn0gZnJvbSAnLi9yZXBvcnRpbmcvdHlwZXMuanMnO1xuXG4vLyBSZS1leHBvcnQgRVhBQ1RMWSB0aGUgc3VyZmFjZSB0aGlzIG1vZHVsZSBoYWQgYmVmb3JlIHRoZSBzcGxpdCDigJQgbm8gbW9yZS5cbi8vIGBzcmMvaW5kZXgudHNgIGRvZXMgYGV4cG9ydCAqIGZyb20gJy4vYXBpL3JlcG9ydGluZy1zZXJ2aWNlLmpzJ2AsIHNvIGFueXRoaW5nXG4vLyByZS1leHBvcnRlZCBoZXJlIGJlY29tZXMgcGFydCBvZiB0aGUgcGFja2FnZSdzIHB1YmxpYyBBUEkuIEVudW1lcmF0ZWQgcmF0aGVyXG4vLyB0aGFuIGBleHBvcnQgKmAgZm9yIHRoYXQgcmVhc29uOiB0aGUgZXh0cmFjdGVkIG1vZHVsZXMgYWxzbyBleHBvcnQgaW50ZXJuYWxzXG4vLyAob3JnU2NvcGUsIHJ1blJlcG9ydCwgdGhlIGNhY2hlcywgdGhlIERPUkEgcm93IHNoYXBlcykgdGhhdCB3ZXJlIHByaXZhdGVcbi8vIGJlZm9yZSBhbmQgbXVzdCBzdGF5IHRoYXQgd2F5LlxuZXhwb3J0IHR5cGUge1xuICBCdWlsZEhlYWx0aCwgQnVpbGRIZWFsdGhTdGFnZSwgRG9yYUVudk1ldHJpY3MsIERvcmFMZXZlbCwgRG9yYU1ldHJpY3MsIERvcmFPcHRpb25zLCBEb3JhVHJlbmRQb2ludCxcbiAgSW5jaWRlbnRJbnB1dCwgSW5jaWRlbnRMaXN0SXRlbSwgSW5jaWRlbnRTZXR0aW5ncywgSW5jaWRlbnRUZXN0UmVzdWx0LFxuICBJbmdlc3RFdmVudCwgSW5nZXN0SGVhbHRoU3RhdHVzLCBJbmdlc3RNZXRyaWMsIEluZ2VzdFJlc3VsdCxcbiAgUmVwb3J0aW5nUmV0ZW50aW9uQ291bnRzLCBSZXBvcnRpbmdSZXRlbnRpb25PcHRpb25zLCBSZXBvcnRpbmdSZXRlbnRpb25TZXR0aW5ncyxcbiAgUmVwb3J0aW5nU2V0dGluZ3NQYXRjaCxcbn0gZnJvbSAnLi9yZXBvcnRpbmcvdHlwZXMuanMnO1xuZXhwb3J0IHsgcmVzb2x2ZURvcmFSZXRlbnRpb25EYXlzLCByZXNvbHZlRXZlbnRSZXRlbnRpb25EYXlzLCByZXRlbnRpb25DdXRvZmYgfSBmcm9tICcuL3JlcG9ydGluZy9yZXRlbnRpb24uanMnO1xuXG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigncmVwb3J0aW5nLXNlcnZpY2UnKTtcblxuZXhwb3J0IGNsYXNzIFJlcG9ydGluZ1NlcnZpY2Uge1xuXG4gIC8qKiBJbnZhbGlkYXRlIGFsbCBjYWNoZWQgcmVwb3J0cyBmb3IgYW4gb3JnIChjYWxsIGFmdGVyIGV2ZW50IGluZ2VzdCkuICovXG4gIGFzeW5jIGludmFsaWRhdGVPcmcob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIGludmVudG9yeUNhY2hlLmludmFsaWRhdGVQYXR0ZXJuKGAke29yZ0lkfToqYCksXG4gICAgICB0aW1lc2VyaWVzQ2FjaGUuaW52YWxpZGF0ZVBhdHRlcm4oYCR7b3JnSWR9OipgKSxcbiAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIGluY29taW5nIGV2ZW50cyBhZ2FpbnN0IHRoZSBwaXBlbGluZSByZWdpc3RyeSwgYmF0Y2gtaW5zZXJ0IHRoZVxuICAgKiBtYXRjaGVkIG9uZXMsIGFuZCBpbnZhbGlkYXRlIHJlcG9ydGluZyBjYWNoZXMgZm9yIGFmZmVjdGVkIG9yZ3MuXG4gICAqIEV2ZW50cyBmb3IgdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkcyBhcmUgZHJvcHBlZCAoYW5kIGxvZ2dlZCBhdCBXQVJOXG4gICAqIHdpdGggc2FtcGxlIGlkcyBzbyBhbiBvcGVyYXRvciBjYW4gc2VlIHdoZW4gRXZlbnRCcmlkZ2UgaXMgZGVsaXZlcmluZ1xuICAgKiBldmVudHMgZm9yIHBpcGVsaW5lcyB0aGF0IGhhdmVuJ3QgY2FsbGVkIFBPU1QgL3BpcGVsaW5lcy9yZWdpc3RyeSB5ZXQpLlxuICAgKlxuICAgKiBSZXR1cm5zIGNvdW50cyArIGEgc2FtcGxlIG9mIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZHMgZm9yIG9ic2VydmFiaWxpdHkuXG4gICAqL1xuICBhc3luYyBpbmdlc3RFdmVudHMoZXZlbnRzOiBJbmdlc3RFdmVudFtdLCBvbk1ldHJpYz86IChtOiBJbmdlc3RNZXRyaWMpID0+IHZvaWQpOiBQcm9taXNlPEluZ2VzdFJlc3VsdD4ge1xuICAgIC8vIE11bHRpLW9yZyBiYXRjaCBpbnNlcnQ6IHRoZSBjYWxsZXIgcmVzb2x2ZXMgdG8gbXVsdGlwbGUgb3JncyB2aWEgdGhlXG4gICAgLy8gcGlwZWxpbmUtcmVnaXN0cnkgbG9va3VwIGJlbG93LCBzbyB0aGUgcm91dGUgbGF5ZXIgTVVTVCBlc3RhYmxpc2ggYVxuICAgIC8vIGBydW5XaXRoVGVuYW50Q29udGV4dCh7IGlzU3VwZXJBZG1pbjogdHJ1ZSB9LCAuLi4pYCBzY29wZSBiZWZvcmUgY2FsbGluZ1xuICAgIC8vIHRoaXMgbWV0aG9kLiBVbmRlciBGT1JDRSdkIFJMUywgYSBzaW5nbGUgdHggd2l0aCBgYXBwLm9yZ19pZCA9IDxvbmVcbiAgICAvLyBvcmc+YCBjb3VsZCBvbmx5IHdyaXRlIGV2ZW50cyBmb3IgdGhhdCBvcmc7IGJ5cGFzcyB2aWEgc3lzYWRtaW4gaXNcbiAgICAvLyB0aGUgcmlnaHQgZ2F0ZSBmb3IgdGhpcyBzZXJ2ZXItaW50ZXJuYWwgY3Jvc3MtdGVuYW50IGVuZHBvaW50LiBTZWVcbiAgICAvLyBhcGkvcmVwb3J0aW5nL3NyYy9yb3V0ZXMvZXZlbnQtaW5nZXN0LnRzIGZvciB0aGUgd3JhcHBlci5cbiAgICAvLyBSdW4gaW5zZXJ0IGluc2lkZSB0aGUgdHgsIGJ1dCBDT0xMRUNUIGFmZmVjdGVkIG9yZ3MgYW5kIGludmFsaWRhdGVcbiAgICAvLyBjYWNoZXMgQUZURVIgdGhlIHR4IHJlc29sdmVzLiBLZWVwaW5nIGludmFsaWRhdGlvbiBpbnNpZGUgdGhlIHR4IGhlbGRcbiAgICAvLyB0aGUgcGcgbG9ja3Mgb3BlbiBmb3IgdGhlIGR1cmF0aW9uIG9mIHRoZSBjYWNoZSByb3VuZC10cmlwcyAoUmVkaXMgb3JcbiAgICAvLyBpbi1tZW1vcnkgaW52YWxpZGF0aW9ucyBhcmUgdW5yZWxhdGVkIHRvIHRoZSB0eCBidXQgc3RpbGwgc2VyaWFsaXplZFxuICAgIC8vIGl0cyBjb21taXQpLiBDYWNoZSBUVEwgaXMgMi01IG1pbiBzbyBmaXJlLWFuZC1mb3JnZXQgcG9zdC1jb21taXQgaXNcbiAgICAvLyBhbiBhY2NlcHRhYmxlIHRyYWRlIGZvciB0aWdodGVyIGxvY2sgd2luZG93cy5cbiAgICBjb25zdCB7IGluc2VydGVkLCBza2lwcGVkLCB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcywgYWZmZWN0ZWRPcmdzLCBpbnNlcnRlZFJvd3MgfSA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAgIC8vIEJhdGNoLXJlc29sdmUgYWxsIHVuaXF1ZSBwaXBlbGluZSBpZHMgaW4gb25lIHF1ZXJ5XG4gICAgICBjb25zdCB1bmlxdWVJZHMgPSBbLi4ubmV3IFNldChldmVudHMubWFwKGUgPT4gZS5waXBlbGluZUlkKSldO1xuICAgICAgY29uc3QgcmVnaXN0cnlSb3dzID0gYXdhaXQgdHhcbiAgICAgICAgLnNlbGVjdCh7XG4gICAgICAgICAgcGlwZWxpbmVJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkucGlwZWxpbmVJZCxcbiAgICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkub3JnSWQsXG4gICAgICAgIH0pXG4gICAgICAgIC5mcm9tKHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5KVxuICAgICAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLCB1bmlxdWVJZHMpKTtcblxuICAgICAgY29uc3QgaWRNYXAgPSBuZXcgTWFwKHJlZ2lzdHJ5Um93cy5tYXAociA9PiBbci5waXBlbGluZUlkLCByXSkpO1xuXG4gICAgICAvLyBCdWlsZCBpbnNlcnQgYmF0Y2ggKHNraXAgZXZlbnRzIHdob3NlIHBpcGVsaW5lIGlzbid0IHJlZ2lzdGVyZWQpXG4gICAgICBjb25zdCByb3dzOiBBcnJheTx0eXBlb2Ygc2NoZW1hLnBpcGVsaW5lRXZlbnQuJGluZmVySW5zZXJ0PiA9IFtdO1xuICAgICAgbGV0IHNraXBwZWRMb2NhbCA9IDA7XG4gICAgICBjb25zdCB1bnJlZ2lzdGVyZWRMb2NhbDogc3RyaW5nW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMpIHtcbiAgICAgICAgY29uc3QgcmVnaXN0cnkgPSBpZE1hcC5nZXQoZXZlbnQucGlwZWxpbmVJZCk7XG4gICAgICAgIGlmICghcmVnaXN0cnkpIHtcbiAgICAgICAgICBza2lwcGVkTG9jYWwrKztcbiAgICAgICAgICB1bnJlZ2lzdGVyZWRMb2NhbC5wdXNoKGV2ZW50LnBpcGVsaW5lSWQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgICAvLyByZWdpc3RyeS5waXBlbGluZUlkID09PSBldmVudC5waXBlbGluZUlkOyB1c2UgdGhlIHJlZ2lzdHJ5J3Mgc28gdGhlXG4gICAgICAgICAgLy8gRksgaXMgYWx3YXlzIGEgcm93IHRoYXQgZXhpc3RzLCBhbmQgcHVsbCBvcmdJZCBmcm9tIHRoZSByZWdpc3RyeSBmb3JcbiAgICAgICAgICAvLyB0ZW5hbmN5IChuZXZlciB0cnVzdCB0aGUgY2FsbGVyJ3MgY2xhaW1lZCBvcmcpLlxuICAgICAgICAgIHBpcGVsaW5lSWQ6IHJlZ2lzdHJ5LnBpcGVsaW5lSWQsXG4gICAgICAgICAgb3JnSWQ6IHJlZ2lzdHJ5Lm9yZ0lkLFxuICAgICAgICAgIGV2ZW50U291cmNlOiBldmVudC5ldmVudFNvdXJjZSxcbiAgICAgICAgICBldmVudFR5cGU6IGV2ZW50LmV2ZW50VHlwZSxcbiAgICAgICAgICBzdGF0dXM6IGV2ZW50LnN0YXR1cyxcbiAgICAgICAgICAvLyBleGVjdXRpb25JZCBpcyBhbiBBV1MtQVNTSUdORUQgaWRlbnRpZmllciAoYSBVVUlEKSwgbm90IGZyZWUtZm9ybVxuICAgICAgICAgIC8vIHVzZXIgdGV4dCwgc28gaXQgY2FuJ3QgY2FycnkgYW4gYWNjb3VudCBpZCDigJQgYW5kIHNjcnViYmluZyBhIFVVSURcbiAgICAgICAgICAvLyB0aGF0IGhhcHBlbnMgdG8gY29udGFpbiBhIDEyLWRpZ2l0IHJ1biB3b3VsZCBjb3JydXB0IHRoZSBjb3JyZWxhdGlvblxuICAgICAgICAgIC8vIGtleS4gTGVmdCBpbnRhY3QgYnkgZGVzaWduLlxuICAgICAgICAgIGV4ZWN1dGlvbklkOiBldmVudC5leGVjdXRpb25JZCxcbiAgICAgICAgICAvLyBzdGFnZU5hbWUvYWN0aW9uTmFtZSBhcmUgVVNFUi1BVVRIT1JFRCBwaXBlbGluZS1zdHJ1Y3R1cmUgbmFtZXNcbiAgICAgICAgICAvLyBwcm9tb3RlZCBmcm9tIHRoZSBDb2RlUGlwZWxpbmUgZGV0YWlsIOKAlCBzYW1lIHVudHJ1c3RlZC1BV1MtZGVyaXZlZFxuICAgICAgICAgIC8vIG9yaWdpbiBhcyBlcnJvck1lc3NhZ2UgYmVsb3csIHNvIHNjcnViIHRoZW0gYXQgdGhpcyBwZXJzaXN0ZW5jZVxuICAgICAgICAgIC8vIGJvdW5kYXJ5IHRvbyAoYSBzdGFnZSBuYW1lZCB3aXRoIGFuIEFSTi8xMi1kaWdpdCBpZCBtdXN0IG5vdCBwZXJzaXN0KS5cbiAgICAgICAgICBzdGFnZU5hbWU6IHNjcnViT3B0aW9uYWwoZXZlbnQuc3RhZ2VOYW1lKSxcbiAgICAgICAgICBhY3Rpb25OYW1lOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmFjdGlvbk5hbWUpLFxuICAgICAgICAgIC8vIEhBUkQgQ09OU1RSQUlOVDogYW4gQVdTIGFjY291bnQgaWQgbXVzdCBORVZFUiBiZSBwZXJzaXN0ZWQuIFRoaXMgaXNcbiAgICAgICAgICAvLyB0aGUgRFVSQUJMRSBwZXJzaXN0ZW5jZSBib3VuZGFyeSBhbmQgbXVzdCBub3QgdHJ1c3QgdXBzdHJlYW06XG4gICAgICAgICAgLy8gQ29kZVBpcGVsaW5lL0NvZGVCdWlsZCBmYWlsdXJlIGRldGFpbCAmIG1lc3NhZ2VzIHJvdXRpbmVseSBjYXJyeVxuICAgICAgICAgIC8vIEFSTnMgKGFybjphd3M64oCmOjxhY2NvdW50LWlkPjrigKYpIGFuZCBiYXJlIDEyLWRpZ2l0IGFjY291bnQgaWRzLiBTY3J1YlxuICAgICAgICAgIC8vIGJvdGggZnJlZS1mb3JtIGZpZWxkcyBoZXJlIGJlZm9yZSBpbnNlcnQgKHBlci1ldmVudCwgbm9uLW11dGF0aW5nKS5cbiAgICAgICAgICBlcnJvck1lc3NhZ2U6IHNjcnViT3B0aW9uYWwoZXZlbnQuZXJyb3JNZXNzYWdlKSxcbiAgICAgICAgICBzdGFydGVkQXQ6IGV2ZW50LnN0YXJ0ZWRBdCA/IG5ldyBEYXRlKGV2ZW50LnN0YXJ0ZWRBdCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgY29tcGxldGVkQXQ6IGV2ZW50LmNvbXBsZXRlZEF0ID8gbmV3IERhdGUoZXZlbnQuY29tcGxldGVkQXQpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGR1cmF0aW9uTXM6IGV2ZW50LmR1cmF0aW9uTXMsXG4gICAgICAgICAgLy8gRGVwbG95LWF0dHJpYnV0aW9uIGZpZWxkcyDigJQgc2NydWJiZWQgbGlrZSB0aGUgb3RoZXIgZnJlZS1mb3JtIHN0cmluZ3NcbiAgICAgICAgICAvLyBzbyBhbiBBUk4vYWNjb3VudCBpZCBjYW4gbmV2ZXIgZW50ZXIgdmlhIGEgcmVmIG9yIGVudmlyb25tZW50IG5hbWUuXG4gICAgICAgICAgY29tbWl0U2hhOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmNvbW1pdFNoYSksXG4gICAgICAgICAgY29tbWl0UmVmOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmNvbW1pdFJlZiksXG4gICAgICAgICAgZW52aXJvbm1lbnQ6IHNjcnViT3B0aW9uYWwoZXZlbnQuZW52aXJvbm1lbnQpLFxuICAgICAgICAgIC8vIE1lYXN1cmVkIGxlYWQgdGltZSAoUGhhc2UgNCk6IG9sZGVzdCB1bnNoaXBwZWQgY29tbWl0IHRpbWUgKyBjb3VudC5cbiAgICAgICAgICAvLyBjb21taXRUaW1lc3RhbXAgaXMgYW4gQVdTL1NDTS1kZXJpdmVkIGluc3RhbnQgKG5ldmVyIGFjY291bnQtaWRcbiAgICAgICAgICAvLyBzaGFwZWQpOyBjb21taXRDb3VudCBpcyBhIHBsYWluIGludGVnZXIuIE5laXRoZXIgbmVlZHMgc2NydWJiaW5nLlxuICAgICAgICAgIGNvbW1pdFRpbWVzdGFtcDogZXZlbnQuY29tbWl0VGltZXN0YW1wID8gbmV3IERhdGUoZXZlbnQuY29tbWl0VGltZXN0YW1wKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICBjb21taXRDb3VudDogZXZlbnQuY29tbWl0Q291bnQsXG4gICAgICAgICAgZGV0YWlsOiBldmVudC5kZXRhaWwgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBzY3J1YkF3c0lkZW50aWZpZXJzKGV2ZW50LmRldGFpbClcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcblxuICAgICAgfVxuXG4gICAgICAvLyBTUVMgaXMgYXQtbGVhc3Qtb25jZSwgc28gRXZlbnRCcmlkZ2UgY2FuIGRlbGl2ZXIgdGhlIHNhbWUgc3RhdGUtY2hhbmdlXG4gICAgICAvLyB0d2ljZS4gYG9uQ29uZmxpY3REb05vdGhpbmdgICsgdGhlIHBhcnRpYWwgdW5pcXVlIGluZGV4IG9uXG4gICAgICAvLyAocGlwZWxpbmVfaWQsIGV4ZWN1dGlvbl9pZCwgZXZlbnRfdHlwZSwgc3RhdHVzLCBzdGFnZV9uYW1lLCBhY3Rpb25fbmFtZSlcbiAgICAgIC8vIG1ha2VzIHJlLWRlbGl2ZXJ5IGlkZW1wb3RlbnQuIGByZXR1cm5pbmdgIGdpdmVzIHRoZSBSRUFMIGluc2VydGVkIHNldCBzb1xuICAgICAgLy8gY291bnRzLCBtZXRyaWNzIGFuZCBjYWNoZSBpbnZhbGlkYXRpb24gYWxsIGlnbm9yZSBkdXBsaWNhdGVzLlxuICAgICAgY29uc3QgbGFuZGVkID0gcm93cy5sZW5ndGggPiAwXG4gICAgICAgID8gYXdhaXQgdHguaW5zZXJ0KHNjaGVtYS5waXBlbGluZUV2ZW50KS52YWx1ZXMocm93cylcbiAgICAgICAgICAub25Db25mbGljdERvTm90aGluZygpXG4gICAgICAgICAgLnJldHVybmluZyh7XG4gICAgICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lRXZlbnQub3JnSWQsXG4gICAgICAgICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVFdmVudC5waXBlbGluZUlkLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBzY2hlbWEucGlwZWxpbmVFdmVudC5ldmVudFR5cGUsXG4gICAgICAgICAgICBzdGF0dXM6IHNjaGVtYS5waXBlbGluZUV2ZW50LnN0YXR1cyxcbiAgICAgICAgICAgIHN0YWdlTmFtZTogc2NoZW1hLnBpcGVsaW5lRXZlbnQuc3RhZ2VOYW1lLFxuICAgICAgICAgICAgZW52aXJvbm1lbnQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmVudmlyb25tZW50LFxuICAgICAgICAgIH0pXG4gICAgICAgIDogW107XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGluc2VydGVkOiBsYW5kZWQubGVuZ3RoLFxuICAgICAgICBza2lwcGVkOiBza2lwcGVkTG9jYWwsXG4gICAgICAgIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzOiB1bnJlZ2lzdGVyZWRMb2NhbCxcbiAgICAgICAgYWZmZWN0ZWRPcmdzOiBbLi4ubmV3IFNldChsYW5kZWQubWFwKHIgPT4gci5vcmdJZCkpXSxcbiAgICAgICAgaW5zZXJ0ZWRSb3dzOiBsYW5kZWQsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gUGhhc2UgM2I6IGZhbiB0ZXJtaW5hbCBTVEFHRSBvdXRjb21lcyBpbnRvIFByb21ldGhldXMgY291bnRlcnMgdmlhIHRoZVxuICAgIC8vIHJvdXRlJ3MgaG9vayAocGlwZWxpbmUtZGF0YSBjYW4ndCBpbXBvcnQgYXBpLXNlcnZlcidzIHJlZ2lzdHJ5KSwgYWZ0ZXIgdGhlXG4gICAgLy8gaW5zZXJ0IENPTU1JVFMuIERyaXZlbiBvZmYgdGhlIElOU0VSVEVEIHJvd3Mg4oCUIG5vdCB0aGUgcmVxdWVzdCBiYXRjaCDigJQgc28gYSByZS1kZWxpdmVyZWQgZXZlbnRcbiAgICAvLyB0aGUgZGVkdXAgaW5kZXggc3dhbGxvd2VkIGlzIG5ldmVyIGNvdW50ZWQgdHdpY2UgKGNvdW50ZXJzLCB1bmxpa2UgdGhlXG4gICAgLy8gdGFibGUsIGhhdmUgbm8gaWRlbXBvdGVuY3kgb2YgdGhlaXIgb3duKS4gVmFsdWVzIGFyZSB0aGUgcGVyc2lzdGVkLFxuICAgIC8vIGFscmVhZHktc2NydWJiZWQgY29sdW1ucy4gQSBub24tbnVsbCBlbnZpcm9ubWVudCBhbHNvIG1hcmtzIGEgZGVwbG95LlxuICAgIGlmIChvbk1ldHJpYykge1xuICAgICAgZm9yIChjb25zdCByIG9mIGluc2VydGVkUm93cykge1xuICAgICAgICBpZiAoci5ldmVudFR5cGUgIT09ICdTVEFHRScgfHwgKHIuc3RhdHVzICE9PSAnU1VDQ0VFREVEJyAmJiByLnN0YXR1cyAhPT0gJ0ZBSUxFRCcpIHx8ICFyLnBpcGVsaW5lSWQpIGNvbnRpbnVlO1xuICAgICAgICBvbk1ldHJpYyh7XG4gICAgICAgICAgcGlwZWxpbmVJZDogci5waXBlbGluZUlkLFxuICAgICAgICAgIG9yZ0lkOiByLm9yZ0lkLFxuICAgICAgICAgIHN0YWdlOiByLnN0YWdlTmFtZSA/PyAnJyxcbiAgICAgICAgICBlbnZpcm9ubWVudDogci5lbnZpcm9ubWVudCA/PyBudWxsLFxuICAgICAgICAgIHJlc3VsdDogci5zdGF0dXMgPT09ICdTVUNDRUVERUQnID8gJ3N1Y2NlZWRlZCcgOiAnZmFpbGVkJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gU3VyZmFjZSB0aGUgc2lsZW50IHNraXA6IGFuIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZCB1c3VhbGx5IG1lYW5zIHRoZVxuICAgIC8vIHBpcGVsaW5lIGhhc24ndCBjYWxsZWQgUE9TVCAvcGlwZWxpbmVzL3JlZ2lzdHJ5IHlldCAob3IgaXRzXG4gICAgLy8gcGIucGlwZWxpbmUtaWQgdGFnIGlzIG1pc3NpbmcvdW5yZWFkYWJsZSBieSB0aGUgTGFtYmRhKS4gTG9nZ2luZyBpdFxuICAgIC8vIG1ha2VzIGEgYnJva2VuIGpvaW4gdmlzaWJsZSBpbnN0ZWFkIG9mIGxvb2tpbmcgbGlrZSBcIm5vIGFjdGl2aXR5XCIuXG4gICAgaWYgKHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGxvZ2dlci53YXJuKCdQaXBlbGluZSBldmVudHMgc2tpcHBlZDogcGlwZWxpbmUgaWQgbm90IGZvdW5kIGluIHJlZ2lzdHJ5Jywge1xuICAgICAgICBjb3VudDogdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMubGVuZ3RoLFxuICAgICAgICBzYW1wbGU6IHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLnNsaWNlKDAsIDMpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gUG9zdC1jb21taXQgY2FjaGUgaW52YWxpZGF0aW9uLiBGaXJlLWFuZC1mb3JnZXQgd2l0aCBsb2dnaW5nIOKAlCBUVEwgaXNcbiAgICAvLyBzaG9ydCBlbm91Z2ggdGhhdCBhIG1pc3NlZCBpbnZhbGlkYXRpb24gc2VsZi1oZWFscy5cbiAgICBpZiAoYWZmZWN0ZWRPcmdzLmxlbmd0aCA+IDApIHtcbiAgICAgIHZvaWQgUHJvbWlzZS5hbGwoYWZmZWN0ZWRPcmdzLm1hcCgob3JnKSA9PlxuICAgICAgICB0aGlzLmludmFsaWRhdGVPcmcob3JnKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyBjYWNoZSBpbnZhbGlkYXRpb24gZmFpbGVkJywgeyBvcmdJZDogb3JnLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgaW5zZXJ0ZWQsIHNraXBwZWQsIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLCBhZmZlY3RlZE9yZ3MgfTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBDYXRlZ29yeSAxOiBQaXBlbGluZSBFeGVjdXRpb24gJiBQZXJmb3JtYW5jZSDilIDilIBcblxuXG4gIC8qKiAxLjEgRXhlY3V0aW9uIGNvdW50IHBlciBwaXBlbGluZSB3aXRoIHN0YXR1cyBicmVha2Rvd24uICovXG4gIGFzeW5jIGdldEV4ZWN1dGlvbkNvdW50KG9yZ0lkOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdLCByYW5nZT86IHsgZnJvbT86IHN0cmluZzsgdG8/OiBzdHJpbmcgfSk6IFByb21pc2U8RXhlY3V0aW9uQ291bnRbXT4ge1xuICAgIGNvbnN0IHsgcHJlZCwgbXVsdGkgfSA9IG9yZ1Njb3BlKG9yZ0lkLCBvcmdJZHMpO1xuICAgIC8vIE9wdGlvbmFsIFtmcm9tLHRvXSB3aW5kb3cgb24gdGhlIGV4ZWN1dGlvbidzIHN0YXJ0ZWRfYXQsIG1pcnJvcmluZyB0aGVcbiAgICAvLyBzaWJsaW5nIHRpbWVzZXJpZXMgcmVwb3J0cyBzbyB0aGUgZGFzaGJvYXJkIGRhdGUtcmFuZ2UgcGlja2VyIG5hcnJvd3MgdGhlXG4gICAgLy8gY291bnQgdG9vIChhbiBlbXB0eSByYW5nZSA9IGFsbC10aW1lLCBwcmVzZXJ2aW5nIHRoZSBwcmlvciBiZWhhdmlvcikuIFRoZVxuICAgIC8vIHJhbmdlIHJpZGVzIHRoZSBKT0lOIHNvIHBpcGVsaW5lcyB3aXRoIG5vIGluLXdpbmRvdyBldmVudHMgc3RpbGwgbGlzdFxuICAgIC8vIChMRUZUIHNlbWFudGljcyBwcmVzZXJ2ZWQgdmlhIHRoZSBpbm5lci1qb2luIGZpbHRlciDigJQgYSBwaXBlbGluZSB3aXRoIHplcm9cbiAgICAvLyBtYXRjaGluZyBldmVudHMgZHJvcHMgZnJvbSB0aGUgY291bnQsIHNhbWUgYXMgYmVmb3JlIGZvciBpdHMgd2luZG93KS5cbiAgICBjb25zdCByYW5nZUNsYXVzZSA9IG9wdGlvbmFsU3RhcnRlZEF0UmFuZ2UocmFuZ2UpO1xuICAgIGNvbnN0IGV4ZWMgPSAoKSA9PiB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5wcm9qZWN0LCBwLm9yZ2FuaXphdGlvbiwgcC5waXBlbGluZV9uYW1lLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnQ0FOQ0VMRUQnKTo6aW50IEFTIGNhbmNlbGVkLFxuICAgICAgICAgIE1JTihlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGZpcnN0X2V4ZWN1dGlvbixcbiAgICAgICAgICBNQVgoZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBsYXN0X2V4ZWN1dGlvblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lfSBwXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZSBPTiBlLnBpcGVsaW5lX2lkID0gcC5pZFxuICAgICAgICAgIEFORCBlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLnN0YXR1cyAhPSAnU1RBUlRFRCdcbiAgICAgICAgICAke3JhbmdlQ2xhdXNlfVxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBwLmlzX2FjdGl2ZSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgcC5pZFxuICAgICAgICBPUkRFUiBCWSB0b3RhbCBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8RXhlY3V0aW9uQ291bnQ+KHIucm93cykpKTtcbiAgICByZXR1cm4gcnVuUmVwb3J0KGAke29yZ0lkfTpleGVjLWNvdW50OiR7cmFuZ2U/LmZyb20gPz8gJyd9OiR7cmFuZ2U/LnRvID8/ICcnfWAsIG11bHRpLCBleGVjKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAxLjFiIFBlci1waXBlbGluZSBleGVjdXRpb24gaGlzdG9yeSDigJQgRElTVElOQ1QgZXhlY3V0aW9ucyBmb3Igb25lIHBpcGVsaW5lLFxuICAgKiBuZXdlc3QgZmlyc3QuIEdyb3VwcyBhbGwgZXZlbnRzIGJ5IGBleGVjdXRpb25faWRgIGluIGEgc2luZ2xlIHNjYW4gYW5kXG4gICAqIHJvbGxzIGVhY2ggZXhlY3V0aW9uIHVwIHRvIG9uZSByb3c6XG4gICAqICAgLSBzdGF0dXM6IGRlcml2ZWQgZnJvbSB0aGUgUElQRUxJTkUtdHlwZSBldmVudHMuIEZBSUxFRCB3aW5zLCB0aGVuXG4gICAqICAgICBTVUNDRUVERUQsIHRoZW4gQ0FOQ0VMRUQ7IGFuIGV4ZWN1dGlvbiB3aXRoIG5vIHRlcm1pbmFsIFBJUEVMSU5FIGV2ZW50XG4gICAqICAgICBpcyBzdGlsbCBgaW4tcHJvZ3Jlc3NgLlxuICAgKiAgIC0gc3RhcnRlZEF0L2VuZGVkQXQvZHVyYXRpb25NczogZnJvbSB0aGUgUElQRUxJTkUgbGlmZWN5Y2xlIGV2ZW50cy5cbiAgICogICAtIGZhaWxpbmdTdGFnZS9mYWlsaW5nQWN0aW9uOiB0aGUgZmlyc3QgRkFJTEVEIFNUQUdFL0FDVElPTiBldmVudCAoY2hlYXAg4oCUXG4gICAqICAgICBzYW1lIHNjYW4sIG5vIGV4dHJhIHF1ZXJ5KS5cbiAgICpcbiAgICogT1JHLVNDT1BJTkc6IGlkZW50aWNhbCB0byB0aGUgc2libGluZyBleGVjdXRpb24gcmVwb3J0cyDigJQgam9pbnMgdGhlIHBpcGVsaW5lXG4gICAqIHJlZ2lzdHJ5IHRhYmxlIChgcGlwZWxpbmVgKSBhbmQgZ2F0ZXMgb24gYHAub3JnX2lkICR7cHJlZH1gLCB3aGVyZSBgcHJlZGAgaXNcbiAgICogdGhlIHNpbmdsZS1vcmcgYD0gJG9yZ2Agb3IgKHdpdGggYSByb2xsdXApIGFuIGBJTiAoLi4uKWAgb3ZlciB0aGUgb3Jn4oaSdGVhbVxuICAgKiBzdWJ0cmVlLiBBIHBpcGVsaW5lSWQgYmVsb25naW5nIHRvIGFub3RoZXIgb3JnIHlpZWxkcyB6ZXJvIHJvd3MuXG4gICAqL1xuICBhc3luYyBsaXN0UGlwZWxpbmVFeGVjdXRpb25zKFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgcGlwZWxpbmVJZDogc3RyaW5nLFxuICAgIG9yZ0lkcz86IHN0cmluZ1tdLFxuICAgIHJhbmdlPzogeyBmcm9tPzogc3RyaW5nOyB0bz86IHN0cmluZyB9LFxuICAgIGxpbWl0OiBudW1iZXIgPSA1MCxcbiAgKTogUHJvbWlzZTxQaXBlbGluZUV4ZWN1dGlvbltdPiB7XG4gICAgY29uc3QgeyBwcmVkLCBtdWx0aSB9ID0gb3JnU2NvcGUob3JnSWQsIG9yZ0lkcyk7XG4gICAgY29uc3QgcmFuZ2VDbGF1c2UgPSBvcHRpb25hbFN0YXJ0ZWRBdFJhbmdlKHJhbmdlKTtcbiAgICBjb25zdCBleGVjID0gKCkgPT4gd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuZXhlY3V0aW9uX2lkLFxuICAgICAgICAgIENBU0VcbiAgICAgICAgICAgIFdIRU4gYm9vbF9vcihlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLnN0YXR1cyA9ICdGQUlMRUQnKSBUSEVOICdmYWlsZWQnXG4gICAgICAgICAgICBXSEVOIGJvb2xfb3IoZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyBBTkQgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJykgVEhFTiAnc3VjY2VlZGVkJ1xuICAgICAgICAgICAgV0hFTiBib29sX29yKGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScgQU5EIGUuc3RhdHVzID0gJ0NBTkNFTEVEJykgVEhFTiAnY2FuY2VsZWQnXG4gICAgICAgICAgICBFTFNFICdpbi1wcm9ncmVzcydcbiAgICAgICAgICBFTkQgQVMgc3RhdHVzLFxuICAgICAgICAgIE1JTihlLnN0YXJ0ZWRfYXQpIEZJTFRFUiAoV0hFUkUgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyk6OnRleHQgQVMgc3RhcnRlZF9hdCxcbiAgICAgICAgICBNQVgoZS5jb21wbGV0ZWRfYXQpIEZJTFRFUiAoV0hFUkUgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyk6OnRleHQgQVMgZW5kZWRfYXQsXG4gICAgICAgICAgTUFYKGUuZHVyYXRpb25fbXMpIEZJTFRFUiAoV0hFUkUgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyk6OmludCBBUyBkdXJhdGlvbl9tcyxcbiAgICAgICAgICAoQVJSQVlfQUdHKGUuc3RhZ2VfbmFtZSkgRklMVEVSIChXSEVSRSBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLnN0YXR1cyA9ICdGQUlMRUQnKSlbMV0gQVMgZmFpbGluZ19zdGFnZSxcbiAgICAgICAgICAoQVJSQVlfQUdHKGUuYWN0aW9uX25hbWUpIEZJTFRFUiAoV0hFUkUgZS5ldmVudF90eXBlID0gJ0FDVElPTicgQU5EIGUuc3RhdHVzID0gJ0ZBSUxFRCcpKVsxXSBBUyBmYWlsaW5nX2FjdGlvblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLnBpcGVsaW5lX2lkID0gJHtwaXBlbGluZUlkfSBBTkQgZS5leGVjdXRpb25faWQgSVMgTk9UIE5VTExcbiAgICAgICAgICAke3JhbmdlQ2xhdXNlfVxuICAgICAgICBHUk9VUCBCWSBlLmV4ZWN1dGlvbl9pZFxuICAgICAgICBPUkRFUiBCWSBNQVgoZS5jcmVhdGVkX2F0KSBERVNDXG4gICAgICAgIExJTUlUICR7bGltaXR9XG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8UGlwZWxpbmVFeGVjdXRpb24+KHIucm93cykpKTtcbiAgICByZXR1cm4gcnVuUmVwb3J0KGAke29yZ0lkfTpwaXBlbGluZS1leGVjdXRpb25zOiR7cGlwZWxpbmVJZH06JHtyYW5nZT8uZnJvbSA/PyAnJ306JHtyYW5nZT8udG8gPz8gJyd9OiR7bGltaXR9YCwgbXVsdGksIGV4ZWMpO1xuICB9XG5cbiAgLyoqIDEuMiBTdWNjZXNzIHJhdGUgb3ZlciB0aW1lIGZvciBhbiBvcmcuICovXG4gIGFzeW5jIGdldFN1Y2Nlc3NSYXRlKG9yZ0lkOiBzdHJpbmcsIGludGVydmFsOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPFRpbWVTZXJpZXNFbnRyeVtdPiB7XG4gICAgYXNzZXJ0UmVwb3J0SW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgIGNvbnN0IHsgcHJlZCwgbXVsdGkgfSA9IG9yZ1Njb3BlKG9yZ0lkLCBvcmdJZHMpO1xuICAgIGNvbnN0IGV4ZWMgPSAoKSA9PiB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgREFURV9UUlVOQygke2ludGVydmFsfSwgZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBwZXJpb2QsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnQ0FOQ0VMRUQnKTo6aW50IEFTIGNhbmNlbGVkLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIHN1Y2Nlc3NfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORSdcbiAgICAgICAgICBBTkQgZS5zdGF0dXMgSU4gKCdTVUNDRUVERUQnLCAnRkFJTEVEJywgJ0NBTkNFTEVEJylcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIHBlcmlvZCBPUkRFUiBCWSBwZXJpb2RcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxUaW1lU2VyaWVzRW50cnk+KHIucm93cykpKTtcbiAgICByZXR1cm4gcnVuUmVwb3J0KGAke29yZ0lkfTpzdWNjZXNzLXJhdGU6JHtpbnRlcnZhbH06JHtmcm9tfToke3RvfWAsIG11bHRpLCBleGVjKTtcbiAgfVxuXG4gIC8qKiAxLjMgQXZlcmFnZSBkdXJhdGlvbiBwZXIgcGlwZWxpbmUuICovXG4gIGFzeW5jIGdldEF2ZXJhZ2VEdXJhdGlvbihvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxEdXJhdGlvblN0YXRzW10+IHtcbiAgICBjb25zdCB7IHByZWQsIG11bHRpIH0gPSBvcmdTY29wZShvcmdJZCwgb3JnSWRzKTtcbiAgICBjb25zdCBleGVjID0gKCkgPT4gd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIHAuaWQsIHAucHJvamVjdCwgcC5waXBlbGluZV9uYW1lLFxuICAgICAgICAgIEFWRyhlLmR1cmF0aW9uX21zKTo6aW50IEFTIGF2Z19tcyxcbiAgICAgICAgICBNSU4oZS5kdXJhdGlvbl9tcyk6OmludCBBUyBtaW5fbXMsXG4gICAgICAgICAgTUFYKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWF4X21zLFxuICAgICAgICAgIFBFUkNFTlRJTEVfQ09OVCgwLjk1KSBXSVRISU4gR1JPVVAgKE9SREVSIEJZIGUuZHVyYXRpb25fbXMpOjppbnQgQVMgcDk1X21zLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgZXhlY3V0aW9uc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLmR1cmF0aW9uX21zIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwLmlkIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8RHVyYXRpb25TdGF0cz4oci5yb3dzKSkpO1xuICAgIHJldHVybiBydW5SZXBvcnQoYCR7b3JnSWR9OmF2Zy1kdXJhdGlvbjoke2Zyb219OiR7dG99YCwgbXVsdGksIGV4ZWMpO1xuICB9XG5cbiAgLyoqIDEuNSBTdGFnZSBmYWlsdXJlIGhlYXRtYXAg4oCUIHdoaWNoIHN0YWdlcyBmYWlsIG1vc3QuICovXG4gIGFzeW5jIGdldFN0YWdlRmFpbHVyZXMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8U3RhZ2VGYWlsdXJlW10+IHtcbiAgICBjb25zdCB7IHByZWQsIG11bHRpIH0gPSBvcmdTY29wZShvcmdJZCwgb3JnSWRzKTtcbiAgICBjb25zdCBleGVjID0gKCkgPT4gd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuc3RhZ2VfbmFtZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbHVyZXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBST1VORChDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjpudW1lcmljXG4gICAgICAgICAgICAvIE5VTExJRihDT1VOVCgqKSwgMCkgKiAxMDAsIDEpOjpmbG9hdCBBUyBmYWlsdXJlX3BjdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLnN0YWdlX25hbWUgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIGUuc3RhZ2VfbmFtZSBPUkRFUiBCWSBmYWlsdXJlcyBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8U3RhZ2VGYWlsdXJlPihyLnJvd3MpKSk7XG4gICAgcmV0dXJuIHJ1blJlcG9ydChgJHtvcmdJZH06c3RhZ2UtZmFpbHVyZXM6JHtmcm9tfToke3RvfWAsIG11bHRpLCBleGVjKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXN0aW5jdCBkZXBsb3kgYGVudmlyb25tZW50YCB2YWx1ZXMgb2JzZXJ2ZWQgaW4gdGhlIHdpbmRvdyDigJQgcG93ZXJzIHRoZVxuICAgKiBET1JBIGVudmlyb25tZW50LXNjb3BlIGRhdGFsaXN0LiBPcmctc2NvcGVkICsgcm9sbHVwLWF3YXJlIGxpa2UgdGhlIHNpYmxpbmdcbiAgICogcmVwb3J0czsgb25seSBub24tbnVsbCBlbnZpcm9ubWVudHMgKGkuZS4gZGVwbG95LWF0dHJpYnV0ZWQgZXhlY3V0aW9ucykuXG4gICAqL1xuICBhc3luYyBnZXRSZXBvcnRFbnZpcm9ubWVudHMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBjb25zdCB7IHByZWQsIG11bHRpIH0gPSBvcmdTY29wZShvcmdJZCwgb3JnSWRzKTtcbiAgICBjb25zdCBleGVjID0gKCkgPT4gd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVCBESVNUSU5DVCBlLmVudmlyb25tZW50IEFTIGVudmlyb25tZW50XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuZW52aXJvbm1lbnQgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIE9SREVSIEJZIGVudmlyb25tZW50XG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8eyBlbnZpcm9ubWVudDogc3RyaW5nIH0+KHIucm93cykubWFwKChyb3cpID0+IHJvdy5lbnZpcm9ubWVudCkpKTtcbiAgICByZXR1cm4gcnVuUmVwb3J0KGAke29yZ0lkfTpyZXBvcnQtZW52czoke2Zyb219OiR7dG99YCwgbXVsdGksIGV4ZWMpO1xuICB9XG5cbiAgLyoqIDEuNiBTdGFnZSBib3R0bGVuZWNrcyDigJQgc2xvd2VzdCBzdGFnZXMgcGVyIHBpcGVsaW5lLiAqL1xuICBhc3luYyBnZXRTdGFnZUJvdHRsZW5lY2tzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPFN0YWdlQm90dGxlbmVja1tdPiB7XG4gICAgY29uc3QgeyBwcmVkLCBtdWx0aSB9ID0gb3JnU2NvcGUob3JnSWQsIG9yZ0lkcyk7XG4gICAgY29uc3QgZXhlYyA9ICgpID0+IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBwLmlkLCBwLnBpcGVsaW5lX25hbWUsIGUuc3RhZ2VfbmFtZSxcbiAgICAgICAgICBBVkcoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBhdmdfbXMsXG4gICAgICAgICAgTUFYKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWF4X21zXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdTVEFHRScgQU5EIGUuZHVyYXRpb25fbXMgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIHAuaWQsIGUuc3RhZ2VfbmFtZSBPUkRFUiBCWSBhdmdfbXMgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFN0YWdlQm90dGxlbmVjaz4oci5yb3dzKSkpO1xuICAgIHJldHVybiBydW5SZXBvcnQoYCR7b3JnSWR9OnN0YWdlLWJvdHRsZW5lY2tzOiR7ZnJvbX06JHt0b31gLCBtdWx0aSwgZXhlYyk7XG4gIH1cblxuICAvKiogMS43IEFjdGlvbiBmYWlsdXJlIHJhdGUg4oCUIHdoaWNoIHBsdWdpbiBzdGVwcyBmYWlsIG1vc3QuICovXG4gIGFzeW5jIGdldEFjdGlvbkZhaWx1cmVzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPEFjdGlvbkZhaWx1cmVbXT4ge1xuICAgIGNvbnN0IHsgcHJlZCwgbXVsdGkgfSA9IG9yZ1Njb3BlKG9yZ0lkLCBvcmdJZHMpO1xuICAgIGNvbnN0IGV4ZWMgPSAoKSA9PiB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5hY3Rpb25fbmFtZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbHVyZXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBST1VORChDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjpudW1lcmljXG4gICAgICAgICAgICAvIE5VTExJRihDT1VOVCgqKSwgMCkgKiAxMDAsIDEpOjpmbG9hdCBBUyBmYWlsdXJlX3BjdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnQUNUSU9OJyBBTkQgZS5hY3Rpb25fbmFtZSBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgZS5hY3Rpb25fbmFtZSBPUkRFUiBCWSBmYWlsdXJlcyBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8QWN0aW9uRmFpbHVyZT4oci5yb3dzKSkpO1xuICAgIHJldHVybiBydW5SZXBvcnQoYCR7b3JnSWR9OmFjdGlvbi1mYWlsdXJlczoke2Zyb219OiR7dG99YCwgbXVsdGksIGV4ZWMpO1xuICB9XG5cbiAgLyoqXG4gICAqIDEuOCBFcnJvciBjYXRlZ29yaXphdGlvbiDigJQgZ3JvdXAgZmFpbHVyZSBtZXNzYWdlcy4gRXhlY3V0aW9uIHJlcG9ydCwgc29cbiAgICogcm9sbHVwLWF3YXJlIGV4YWN0bHkgbGlrZSB0aGUgc2libGluZyBleGVjdXRpb24gcmVwb3J0czogd2l0aCBgb3JnSWRzYFxuICAgKiAodGhlIG9yZ+KGknRlYW0gc3VidHJlZSkgdGhlIG9yZyBnYXRlIGJlY29tZXMgYW4gYElOICguLi4pYCBhbmQgdGhlIHJlYWQgcnVuc1xuICAgKiBmcmVzaCB1bmRlciBzeXNhZG1pbiB2aWEgYHJ1blJlcG9ydGA7IHNpbmdsZS1vcmcgcmVhZHMga2VlcCB0aGUgcGVyLW9yZyBjYWNoZS5cbiAgICovXG4gIGFzeW5jIGdldEVycm9ycyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIGxpbWl0OiBudW1iZXIgPSAyMCwgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPEVycm9yRW50cnlbXT4ge1xuICAgIGNvbnN0IHsgcHJlZCwgbXVsdGkgfSA9IG9yZ1Njb3BlKG9yZ0lkLCBvcmdJZHMpO1xuICAgIGNvbnN0IGV4ZWMgPSAoKSA9PiB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgU1VCU1RSSU5HKGUuZXJyb3JfbWVzc2FnZSBGUk9NIDEgRk9SIDIwMCkgQVMgZXJyb3JfcGF0dGVybixcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIG9jY3VycmVuY2VzLFxuICAgICAgICAgIENPVU5UKERJU1RJTkNUIGUucGlwZWxpbmVfaWQpOjppbnQgQVMgYWZmZWN0ZWRfcGlwZWxpbmVzLFxuICAgICAgICAgIE1BWChlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGxhc3Rfc2VlblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLnN0YXR1cyA9ICdGQUlMRUQnIEFORCBlLmVycm9yX21lc3NhZ2UgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIGVycm9yX3BhdHRlcm4gT1JERVIgQlkgb2NjdXJyZW5jZXMgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPEVycm9yRW50cnk+KHIucm93cykpKTtcbiAgICByZXR1cm4gcnVuUmVwb3J0KGAke29yZ0lkfTplcnJvcnM6JHtmcm9tfToke3RvfToke2xpbWl0fWAsIG11bHRpLCBleGVjKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgZm91ciBET1JBIG1lYXN1cmVzIHBsdXMgdGhlaXIgcGVyLWVudmlyb25tZW50IGJyZWFrZG93bi5cbiAgICogSW1wbGVtZW50YXRpb24gaW4gLi9yZXBvcnRpbmcvZG9yYS50cyDigJQgc2VlIHRoYXQgZmlsZSdzIGhlYWRlciBmb3Igd2h5LlxuICAgKi9cbiAgZ2V0RG9yYU1ldHJpY3MoXG4gICAgb3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSwgb3B0czogRG9yYU9wdGlvbnMgPSB7fSxcbiAgKTogUHJvbWlzZTxEb3JhTWV0cmljcz4ge1xuICAgIHJldHVybiBkb3JhTWV0cmljcyhvcmdJZCwgZnJvbSwgdG8sIG9yZ0lkcywgb3B0cyk7XG4gIH1cblxuICAvKiogRE9SQSBtZWFzdXJlcyBidWNrZXRlZCBvdmVyIHRpbWUuICovXG4gIGdldERvcmFUcmVuZChcbiAgICBvcmdJZDogc3RyaW5nLCBpbnRlcnZhbDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdLCBvcHRzOiBEb3JhT3B0aW9ucyA9IHt9LFxuICApOiBQcm9taXNlPERvcmFUcmVuZFBvaW50W10+IHtcbiAgICByZXR1cm4gZG9yYVRyZW5kKG9yZ0lkLCBpbnRlcnZhbCwgZnJvbSwgdG8sIG9yZ0lkcywgb3B0cyk7XG4gIH1cblxuICAvKiogUGVyLXBpcGVsaW5lIGJ1aWxkIGhlYWx0aCAoc3RhZ2UgcGFzcyByYXRlcyBvdmVyIGEgd2luZG93KS4gKi9cbiAgZ2V0QnVpbGRIZWFsdGgoXG4gICAgb3JnSWQ6IHN0cmluZywgcGlwZWxpbmVJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdLFxuICApOiBQcm9taXNlPEJ1aWxkSGVhbHRoPiB7XG4gICAgcmV0dXJuIGJ1aWxkSGVhbHRoKG9yZ0lkLCBwaXBlbGluZUlkLCBmcm9tLCB0bywgb3JnSWRzKTtcbiAgfVxuXG4gIGFzeW5jIGdldFBsdWdpblN1bW1hcnkob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8UGx1Z2luU3VtbWFyeT4ge1xuICAgIHJldHVybiBpbnZlbnRvcnlDYWNoZS5nZXRPclNldChgJHtvcmdJZH06cGx1Z2luLXN1bW1hcnlgLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSAke3NjaGVtYS5wbHVnaW4uaXNBY3RpdmV9KTo6aW50IEFTIGFjdGl2ZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIE5PVCAke3NjaGVtYS5wbHVnaW4uaXNBY3RpdmV9KTo6aW50IEFTIGluYWN0aXZlLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLnZpc2liaWxpdHl9ID0gJ3B1YmxpYycpOjppbnQgQVMgcHVibGljLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLnZpc2liaWxpdHl9ID0gJ29yZycpOjppbnQgQVMgb3JnLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLnZpc2liaWxpdHl9ID0gJ3ByaXZhdGUnKTo6aW50IEFTIHByaXZhdGUsXG4gICAgICAgICAgQ09VTlQoRElTVElOQ1QgJHtzY2hlbWEucGx1Z2luLm5hbWV9KTo6aW50IEFTIHVuaXF1ZV9uYW1lc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBsdWdpbn1cbiAgICAgICAgV0hFUkUgJHtzY2hlbWEucGx1Z2luLm9yZ0lkfSA9ICR7b3JnSWR9XG4gICAgICBgKSk7XG4gICAgICByZXR1cm4gKGRyaXp6bGVSb3dzPFBsdWdpblN1bW1hcnk+KHJvd3Mucm93cylbMF0gfHwgeyB0b3RhbDogMCwgYWN0aXZlOiAwLCBpbmFjdGl2ZTogMCwgcHVibGljOiAwLCBvcmc6IDAsIHByaXZhdGU6IDAsIHVuaXF1ZU5hbWVzOiAwIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIDIuMiBUeXBlICYgY29tcHV0ZSBkaXN0cmlidXRpb24uXG4gICAqICBJTlRFTlRJT05BTExZIFNJTkdMRS1PUkcgKG5vIHJvbGx1cCk6IHBsdWdpbiBpbnZlbnRvcnkgaXMgcGVyLW9yZyAoc2VlXG4gICAqICBnZXRQbHVnaW5TdW1tYXJ5KS4gU2luZ2xlIGA9ICRvcmdgIHNjb3BlLiAqL1xuICBhc3luYyBnZXRQbHVnaW5EaXN0cmlidXRpb24ob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8VHlwZUNvbXB1dGVEaXN0cmlidXRpb25bXT4ge1xuICAgIHJldHVybiBpbnZlbnRvcnlDYWNoZS5nZXRPclNldChgJHtvcmdJZH06cGx1Z2luLWRpc3RyaWJ1dGlvbmAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgJHtzY2hlbWEucGx1Z2luLnBsdWdpblR5cGV9IEFTIHBsdWdpbl90eXBlLFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5jb21wdXRlVHlwZX0gQVMgY29tcHV0ZV90eXBlLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgY291bnRcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfSBBTkQgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgJHtzY2hlbWEucGx1Z2luLnBsdWdpblR5cGV9LCAke3NjaGVtYS5wbHVnaW4uY29tcHV0ZVR5cGV9XG4gICAgICAgIE9SREVSIEJZIGNvdW50IERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxUeXBlQ29tcHV0ZURpc3RyaWJ1dGlvbj4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cblxuICAvKiogMi4zIFZlcnNpb24gY291bnRzIHBlciBwbHVnaW4gbmFtZS5cbiAgICogIElOVEVOVElPTkFMTFkgU0lOR0xFLU9SRyAobm8gcm9sbHVwKTogcGx1Z2luIGludmVudG9yeSBpcyBwZXItb3JnIChzZWVcbiAgICogIGdldFBsdWdpblN1bW1hcnkpLiBTaW5nbGUgYD0gJG9yZ2Agc2NvcGUuICovXG4gIGFzeW5jIGdldFBsdWdpblZlcnNpb25zKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFZlcnNpb25Db3VudFtdPiB7XG4gICAgcmV0dXJuIGludmVudG9yeUNhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpwbHVnaW4tdmVyc2lvbnNgLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5uYW1lfSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHZlcnNpb25fY291bnQsXG4gICAgICAgICAgLS0gSGlnaGVzdCB2ZXJzaW9uIGJ5IE5VTUVSSUMgc2VtdmVyIGNvcmUgKG5vdCBsZXhpY2FsOiAnMTAuMC4wJyA+ICc5LjAuMCcpLlxuICAgICAgICAgIC0tIFN0cmlwIGFueSAtcHJlcmVsZWFzZS8rYnVpbGQgc3VmZml4IGJlZm9yZSB0aGUgaW50W10gY2FzdCBzbyBpdCBjYW4ndFxuICAgICAgICAgIC0tIGVycm9yIG9uIHZhbGlkIHNlbXZlcjsga2VlcCB0aGUgb3JpZ2luYWwgc3RyaW5nIGZvciBkaXNwbGF5LlxuICAgICAgICAgIC0tIEdVQVJEOiBhIG5vbi1udW1lcmljLWRvdHRlZCB2ZXJzaW9uICgnbGF0ZXN0JywgJycsICd2MScpIHdvdWxkIG1ha2UgdGhlXG4gICAgICAgICAgLS0gOjppbnRbXSBjYXN0IHRocm93IGFuZCBibG93IHVwIHRoZSBXSE9MRSBvcmcgc3VtbWFyeS4gT25seSBjYXN0IHJvd3NcbiAgICAgICAgICAtLSB3aG9zZSBzdHJpcHBlZCBjb3JlIG1hdGNoZXMgYSBudW1lcmljLWRvdHRlZCBzaGFwZTsgc29ydCBldmVyeXRoaW5nXG4gICAgICAgICAgLS0gZWxzZSB0byB0aGUgYm90dG9tIHZpYSBhIHNlbnRpbmVsIEFSUkFZWy0xXSBzbyB0aGUgcm93IHN0aWxsIGNvdW50cy5cbiAgICAgICAgICAoYXJyYXlfYWdnKCR7c2NoZW1hLnBsdWdpbi52ZXJzaW9ufVxuICAgICAgICAgICAgIE9SREVSIEJZIENBU0VcbiAgICAgICAgICAgICAgIFdIRU4gcmVnZXhwX3JlcGxhY2UoJHtzY2hlbWEucGx1Z2luLnZlcnNpb259LCAnWy0rXS4qJCcsICcnKSB+ICdeWzAtOV0rKFsuXVswLTldKykqJCdcbiAgICAgICAgICAgICAgICAgVEhFTiBzdHJpbmdfdG9fYXJyYXkocmVnZXhwX3JlcGxhY2UoJHtzY2hlbWEucGx1Z2luLnZlcnNpb259LCAnWy0rXS4qJCcsICcnKSwgJy4nKTo6aW50W11cbiAgICAgICAgICAgICAgIEVMU0UgQVJSQVlbLTFdXG4gICAgICAgICAgICAgRU5EIERFU0NcbiAgICAgICAgICApKVsxXSBBUyBsYXRlc3RfdmVyc2lvbixcbiAgICAgICAgICBib29sX29yKCR7c2NoZW1hLnBsdWdpbi5pc0RlZmF1bHR9KSBBUyBoYXNfZGVmYXVsdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBsdWdpbn1cbiAgICAgICAgV0hFUkUgJHtzY2hlbWEucGx1Z2luLm9yZ0lkfSA9ICR7b3JnSWR9IEFORCAke3NjaGVtYS5wbHVnaW4uaXNBY3RpdmV9ID0gdHJ1ZVxuICAgICAgICBHUk9VUCBCWSAke3NjaGVtYS5wbHVnaW4ubmFtZX1cbiAgICAgICAgT1JERVIgQlkgdmVyc2lvbl9jb3VudCBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VmVyc2lvbkNvdW50PihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAyLjQgQnVpbGQgc3VjY2VzcyByYXRlIG92ZXIgdGltZS5cbiAgICpcbiAgICogU1RBVFVTIENBU0lORyBOT1RFOiBUaGlzIHF1ZXJ5IGZpbHRlcnMgYnkgYGV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnYFxuICAgKiBhbmQgdXNlcyBsb3dlcmNhc2Ugc3RhdHVzIHZhbHVlcyAoYCdjb21wbGV0ZWQnYCwgYCdmYWlsZWQnYCksIHdoaWxlXG4gICAqIGBnZXRTdWNjZXNzUmF0ZWAgKDEuMikgZmlsdGVycyBieSBgZXZlbnRfdHlwZSA9ICdQSVBFTElORSdgIHdpdGhcbiAgICogdXBwZXJjYXNlIEFXUy1zdHlsZSBzdGF0dXNlcyAoYCdTVUNDRUVERUQnYCwgYCdGQUlMRUQnYCwgYCdDQU5DRUxFRCdgKS5cbiAgICogVGhlIGNhc2luZyBkcmlmdCBpcyBpbnRlbnRpb25hbCBhbmQgdHJhY2tzIHRoZSBwcm9kdWNlcjpcbiAgICogICAtIGBwbHVnaW4tYnVpbGRgIGV2ZW50cyBjb21lIGZyb20gb3VyIG93biBidWlsZCBwaXBlbGluZSAobG93ZXJjYXNlKVxuICAgKiAgIC0gYFBJUEVMSU5FYCBldmVudHMgY29tZSBmcm9tIEFXUyBDb2RlUGlwZWxpbmUgKHVwcGVyY2FzZSlcbiAgICogVGhlIGluZ2VzdCBab2Qgc2NoZW1hIGF0IGFwaS9yZXBvcnRpbmcvc3JjL3JvdXRlcy9ldmVudC1pbmdlc3QudHNcbiAgICogU0hPVUxEIGVudW0gdGhlc2UgcGVyLWV2ZW50U291cmNlIHNvIHdlIGNhdGNoIGRyaWZ0IGF0IGluZ2VzdCByYXRoZXJcbiAgICogdGhhbiBzaWxlbnRseSBwcm9kdWNpbmcgemVybyByb3dzIGhlcmUuIFNlZSBmaW5kaW5ncyBONzEuXG4gICAqL1xuICBhc3luYyBnZXRCdWlsZFN1Y2Nlc3NSYXRlKG9yZ0lkOiBzdHJpbmcsIGludGVydmFsOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPEJ1aWxkVGltZVNlcmllc0VudHJ5W10+IHtcbiAgICBhc3NlcnRSZXBvcnRJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgLy8gQnVpbGQgYWN0aXZpdHkgcmVwb3J0IOKAlCByb2xsdXAtYXdhcmUgbGlrZSB0aGUgZXhlY3V0aW9uIHJlcG9ydHMuIFRoZXNlXG4gICAgLy8gcm93cyBhcmUgZ2F0ZWQgb24gdGhlIHBpcGVsaW5lX2V2ZW50IGBvcmdfaWRgIGRpcmVjdGx5IChubyBwaXBlbGluZSBqb2luKSxcbiAgICAvLyBzbyBgcHJlZGAgYXBwbGllcyB0byBgZS5vcmdfaWRgLlxuICAgIGNvbnN0IHsgcHJlZCwgbXVsdGkgfSA9IG9yZ1Njb3BlKG9yZ0lkLCBvcmdJZHMpO1xuICAgIGNvbnN0IGV4ZWMgPSAoKSA9PiB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgREFURV9UUlVOQygke2ludGVydmFsfSwgZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBwZXJpb2QsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdjb21wbGV0ZWQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ2ZhaWxlZCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnY29tcGxldGVkJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIHN1Y2Nlc3NfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnXG4gICAgICAgICAgQU5EIGUuc3RhdHVzIElOICgnY29tcGxldGVkJywgJ2ZhaWxlZCcpXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwZXJpb2QgT1JERVIgQlkgcGVyaW9kXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8QnVpbGRUaW1lU2VyaWVzRW50cnk+KHIucm93cykpKTtcbiAgICByZXR1cm4gcnVuUmVwb3J0KGAke29yZ0lkfTpidWlsZC1zdWNjZXNzOiR7aW50ZXJ2YWx9OiR7ZnJvbX06JHt0b31gLCBtdWx0aSwgZXhlYyk7XG4gIH1cblxuICAvKiogMi41IEJ1aWxkIGR1cmF0aW9uIHBlciBwbHVnaW4uIEJ1aWxkIGFjdGl2aXR5IHJlcG9ydCDigJQgcm9sbHVwLWF3YXJlLiAqL1xuICBhc3luYyBnZXRCdWlsZER1cmF0aW9uKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPEJ1aWxkRHVyYXRpb25bXT4ge1xuICAgIGNvbnN0IHsgcHJlZCwgbXVsdGkgfSA9IG9yZ1Njb3BlKG9yZ0lkLCBvcmdJZHMpO1xuICAgIGNvbnN0IGV4ZWMgPSAoKSA9PiB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5kZXRhaWwtPj4ncGx1Z2luTmFtZScgQVMgcGx1Z2luX25hbWUsXG4gICAgICAgICAgQVZHKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgYXZnX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIGJ1aWxkc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgV0hFUkUgZS5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF9zb3VyY2UgPSAncGx1Z2luLWJ1aWxkJyBBTkQgZS5kdXJhdGlvbl9tcyBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgcGx1Z2luX25hbWUgT1JERVIgQlkgYXZnX21zIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxCdWlsZER1cmF0aW9uPihyLnJvd3MpKSk7XG4gICAgcmV0dXJuIHJ1blJlcG9ydChgJHtvcmdJZH06YnVpbGQtZHVyYXRpb246JHtmcm9tfToke3RvfWAsIG11bHRpLCBleGVjKTtcbiAgfVxuXG4gIC8qKiAyLjYgQnVpbGQgZmFpbHVyZXMg4oCUIHRvcCBlcnJvciBtZXNzYWdlcy4gQnVpbGQgYWN0aXZpdHkgcmVwb3J0IOKAlCByb2xsdXAtYXdhcmUuICovXG4gIGFzeW5jIGdldEJ1aWxkRmFpbHVyZXMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBsaW1pdDogbnVtYmVyID0gMjAsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxCdWlsZEZhaWx1cmVbXT4ge1xuICAgIGNvbnN0IHsgcHJlZCwgbXVsdGkgfSA9IG9yZ1Njb3BlKG9yZ0lkLCBvcmdJZHMpO1xuICAgIGNvbnN0IGV4ZWMgPSAoKSA9PiB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5kZXRhaWwtPj4ncGx1Z2luTmFtZScgQVMgcGx1Z2luX25hbWUsXG4gICAgICAgICAgZS5lcnJvcl9tZXNzYWdlLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgb2NjdXJyZW5jZXMsXG4gICAgICAgICAgTUFYKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgbGFzdF9zZWVuXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnIEFORCBlLnN0YXR1cyA9ICdmYWlsZWQnXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwbHVnaW5fbmFtZSwgZS5lcnJvcl9tZXNzYWdlXG4gICAgICAgIE9SREVSIEJZIG9jY3VycmVuY2VzIERFU0NcbiAgICAgICAgTElNSVQgJHtsaW1pdH1cbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxCdWlsZEZhaWx1cmU+KHIucm93cykpKTtcbiAgICByZXR1cm4gcnVuUmVwb3J0KGAke29yZ0lkfTpidWlsZC1mYWlsdXJlczoke2Zyb219OiR7dG99OiR7bGltaXR9YCwgbXVsdGksIGV4ZWMpO1xuICB9XG5cbiAgLy8g4pSA4pSAIENhdGVnb3J5IDM6IERPUkEgd3JpdGUgcGF0aHMgKHBvc3QtZGVwbG95IG91dGNvbWVzICsgaW5nZXN0IGhlYWx0aCkg4pSA4pSAXG5cbiAgLyoqXG4gICAqIFJlY29yZCBhIG1hbnVhbCBwb3N0LWRlcGxveSBvdXRjb21lIG1hcmtlciAoUGhhc2UgMik6IGEgdXNlciBtYXJrcyBhXG4gICAqIGRlcGxveW1lbnQgYGZhaWxlZGAgKGEgcHJvZHVjdGlvbiBpbmNpZGVudCBsaW5rZWQgdG8gdGhlIGRlcGxveSkgb3JcbiAgICogYHJlc3RvcmVkYCAocmVjb3ZlcmVkKS4gSWRlbXBvdGVudCDigJQga2V5ZWQgb24gKGV4ZWN1dGlvbl9pZCwgb3V0Y29tZSkgc28gYVxuICAgKiBkdXBsaWNhdGUgUE9TVCByZWZyZXNoZXMgYGF0YCByYXRoZXIgdGhhbiBkb3VibGUtY291bnRpbmcsIHdoaWxlIGFcbiAgICogZmFpbGVk4oaScmVzdG9yZWQgcGFpciBzdGF5cyB0d28gcm93cy4gRmVlZHMgdGhlIHBvc3QtZGVwbG95IENGUiBjb21wb25lbnQgYW5kXG4gICAqIHRoZSByZWFsIE1UVFIuIFJ1bnMgdW5kZXIgdGhlIGNhbGxlcidzIG9yZyBjb250ZXh0IChSTFMgV0lUSCBDSEVDSykuXG4gICAqL1xuICBhc3luYyByZWNvcmREZXBsb3ltZW50T3V0Y29tZShcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIGV4ZWN1dGlvbklkOiBzdHJpbmcsXG4gICAgaW5wdXQ6IHsgb3V0Y29tZTogJ2ZhaWxlZCcgfCAncmVzdG9yZWQnOyBhdDogc3RyaW5nOyBlbnZpcm9ubWVudD86IHN0cmluZyB9LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW46IGZhbHNlIH0sICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5pbnNlcnQoc2NoZW1hLmRlcGxveW1lbnRPdXRjb21lKS52YWx1ZXMoe1xuICAgICAgICBleGVjdXRpb25JZCxcbiAgICAgICAgb3JnSWQsXG4gICAgICAgIGVudmlyb25tZW50OiBzY3J1Yk9wdGlvbmFsKGlucHV0LmVudmlyb25tZW50KSxcbiAgICAgICAgb3V0Y29tZTogaW5wdXQub3V0Y29tZSxcbiAgICAgICAgYXQ6IG5ldyBEYXRlKGlucHV0LmF0KSxcbiAgICAgIH0pLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogW3NjaGVtYS5kZXBsb3ltZW50T3V0Y29tZS5leGVjdXRpb25JZCwgc2NoZW1hLmRlcGxveW1lbnRPdXRjb21lLm91dGNvbWVdLFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICBhdDogbmV3IERhdGUoaW5wdXQuYXQpLFxuICAgICAgICAgIGVudmlyb25tZW50OiBzY3J1Yk9wdGlvbmFsKGlucHV0LmVudmlyb25tZW50KSA/PyBudWxsLFxuICAgICAgICB9LFxuICAgICAgfSkpLFxuICAgICk7XG4gICAgLy8gT3V0Y29tZSBjaGFuZ2VzIHRoZSBET1JBIGFnZ3JlZ2F0ZSDigJQgZHJvcCB0aGUgb3JnJ3MgY2FjaGVkIHJlcG9ydHMuXG4gICAgYXdhaXQgdGhpcy5pbnZhbGlkYXRlT3JnKG9yZ0lkKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIGNhY2hlIGludmFsaWRhdGlvbiBmYWlsZWQnLCB7IG9yZ0lkLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW5nZXN0IGEgcHJvZHVjdGlvbiBpbmNpZGVudCAoUGhhc2UgNSkgZnJvbSB0aGUgb3JnJ3MgaW5jaWRlbnQgdG9vbGluZ1xuICAgKiAoUGFnZXJEdXR5IC8gRGF0YWRvZyAvIEFsZXJ0bWFuYWdlciB3ZWJob29rKS4gSWRlbXBvdGVudCDigJQga2V5ZWQgb25cbiAgICogKG9yZ19pZCwgaW5jaWRlbnRfaWQpIHNvIGEgbGF0ZXIgcmVzb2x2ZSByZS1wb3N0IHVwc2VydHMgYHJlc29sdmVkX2F0YFxuICAgKiAoYW5kIHJlZnJlc2hlcyB0aGUgb3RoZXIgbXV0YWJsZSBmaWVsZHMpIGluc3RlYWQgb2YgaW5zZXJ0aW5nIGEgZHVwbGljYXRlLlxuICAgKiBET1JBIGNvcnJlbGF0ZXMgZWFjaCBpbmNpZGVudCB0byB0aGUgbW9zdCByZWNlbnQgc3VjY2Vzc2Z1bCBkZXBsb3kgdG8gaXRzXG4gICAqIGBlbnZpcm9ubWVudGAsIHByb2R1Y2luZyBhbiBhdXRvbWF0ZWQgcG9zdC1kZXBsb3kgZmFpbHVyZSArIGEgcmVhbCBNVFRSLlxuICAgKiBSdW5zIHVuZGVyIHRoZSBjYWxsZXIncyBvcmcgY29udGV4dCAoUkxTIFdJVEggQ0hFQ0spOyBmcmVlLWZvcm0gZmllbGRzIGFyZVxuICAgKiBBV1MtaWQgc2NydWJiZWQgYXQgdGhpcyBwZXJzaXN0ZW5jZSBib3VuZGFyeSBsaWtlIHRoZSBvdGhlciBpbmdlc3QgcGF0aHMuXG4gICAqL1xuICBhc3luYyByZWNvcmRJbmNpZGVudChvcmdJZDogc3RyaW5nLCBpbnB1dDogSW5jaWRlbnRJbnB1dCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGluY2lkZW50SWQgPSBzY3J1YkF3c0lkZW50aWZpZXJzRnJvbVN0cmluZyhpbnB1dC5pbmNpZGVudElkKTtcbiAgICBjb25zdCBlbnZpcm9ubWVudCA9IHNjcnViQXdzSWRlbnRpZmllcnNGcm9tU3RyaW5nKGlucHV0LmVudmlyb25tZW50KTtcbiAgICBjb25zdCBzZXZlcml0eSA9IHNjcnViQXdzSWRlbnRpZmllcnNGcm9tU3RyaW5nKGlucHV0LnNldmVyaXR5KTtcbiAgICBjb25zdCBvcGVuZWRBdCA9IG5ldyBEYXRlKGlucHV0Lm9wZW5lZEF0KTtcbiAgICBjb25zdCByZXNvbHZlZEF0ID0gaW5wdXQucmVzb2x2ZWRBdCA/IG5ldyBEYXRlKGlucHV0LnJlc29sdmVkQXQpIDogbnVsbDtcbiAgICBhd2FpdCBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW46IGZhbHNlIH0sICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5pbnNlcnQoc2NoZW1hLmluY2lkZW50KS52YWx1ZXMoe1xuICAgICAgICBpbmNpZGVudElkLFxuICAgICAgICBvcmdJZCxcbiAgICAgICAgZW52aXJvbm1lbnQsXG4gICAgICAgIG9wZW5lZEF0LFxuICAgICAgICByZXNvbHZlZEF0LFxuICAgICAgICBzZXZlcml0eSxcbiAgICAgIH0pLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogW3NjaGVtYS5pbmNpZGVudC5vcmdJZCwgc2NoZW1hLmluY2lkZW50LmluY2lkZW50SWRdLFxuICAgICAgICBzZXQ6IHsgZW52aXJvbm1lbnQsIG9wZW5lZEF0LCByZXNvbHZlZEF0LCBzZXZlcml0eSB9LFxuICAgICAgfSkpLFxuICAgICk7XG4gICAgLy8gQSBuZXcvdXBkYXRlZCBpbmNpZGVudCBjaGFuZ2VzIHRoZSBET1JBIGFnZ3JlZ2F0ZSDigJQgZHJvcCBjYWNoZWQgcmVwb3J0cy5cbiAgICBhd2FpdCB0aGlzLmludmFsaWRhdGVPcmcob3JnSWQpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgIGxvZ2dlci53YXJuKCdSZXBvcnRpbmcgY2FjaGUgaW52YWxpZGF0aW9uIGZhaWxlZCcsIHsgb3JnSWQsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkIHRoZSBwZXItb3JnIERPUkEgc2V0dGluZ3MgKFBoYXNlIDViKS4gUmV0dXJucyB0aGUgc3RvcmVkXG4gICAqIGBpbmNpZGVudFdpbmRvd0hvdXJzYCBvdmVycmlkZSAob3IgYG51bGxgIHdoZW4gdW5zZXQpIHBsdXMgdGhlIGdsb2JhbCBlbnZcbiAgICogZGVmYXVsdCwgc28gdGhlIHNldHRpbmdzIFVJIGNhbiBzaG93IGJvdGguIFJ1bnMgdW5kZXIgdGhlIGNhbGxlcidzIHRlbmFudFxuICAgKiBjb250ZXh0IChSTFMtc2NvcGVkKTsgYSBzaW5nbGUtb3JnIHJlYWQuXG4gICAqL1xuICBhc3luYyBnZXRJbmNpZGVudFNldHRpbmdzKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPEluY2lkZW50U2V0dGluZ3M+IHtcbiAgICBjb25zdCByb3dzID0gZHJpenpsZVJvd3M8e1xuICAgICAgaW5jaWRlbnRfd2luZG93X2hvdXJzOiBudW1iZXIgfCBudWxsO1xuICAgICAgZXZlbnRfcmV0ZW50aW9uX2RheXM6IG51bWJlciB8IG51bGw7XG4gICAgICBkb3JhX3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgIH0+KChhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5pbmNpZGVudFdpbmRvd0hvdXJzfSBBUyBpbmNpZGVudF93aW5kb3dfaG91cnMsXG4gICAgICAgICAgICAgICAke3NjaGVtYS5kb3JhU2V0dGluZ3MuZXZlbnRSZXRlbnRpb25EYXlzfSBBUyBldmVudF9yZXRlbnRpb25fZGF5cyxcbiAgICAgICAgICAgICAgICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5kb3JhUmV0ZW50aW9uRGF5c30gQVMgZG9yYV9yZXRlbnRpb25fZGF5c1xuICAgICAgICBGUk9NICR7c2NoZW1hLmRvcmFTZXR0aW5nc31cbiAgICAgICAgV0hFUkUgJHtzY2hlbWEuZG9yYVNldHRpbmdzLm9yZ0lkfSA9ICR7b3JnSWR9XG4gICAgICAgIExJTUlUIDFcbiAgICAgIGApKSkucm93cyk7XG4gICAgY29uc3Qgcm93ID0gcm93c1swXTtcbiAgICByZXR1cm4ge1xuICAgICAgaW5jaWRlbnRXaW5kb3dIb3Vyczogcm93Py5pbmNpZGVudF93aW5kb3dfaG91cnMgIT0gbnVsbCA/IE51bWJlcihyb3cuaW5jaWRlbnRfd2luZG93X2hvdXJzKSA6IG51bGwsXG4gICAgICBkZWZhdWx0V2luZG93SG91cnM6IERPUkFfSU5DSURFTlRfV0lORE9XX0hPVVJTLFxuICAgICAgZXZlbnRSZXRlbnRpb25EYXlzOiByb3c/LmV2ZW50X3JldGVudGlvbl9kYXlzICE9IG51bGwgPyBOdW1iZXIocm93LmV2ZW50X3JldGVudGlvbl9kYXlzKSA6IG51bGwsXG4gICAgICBkb3JhUmV0ZW50aW9uRGF5czogcm93Py5kb3JhX3JldGVudGlvbl9kYXlzICE9IG51bGwgPyBOdW1iZXIocm93LmRvcmFfcmV0ZW50aW9uX2RheXMpIDogbnVsbCxcbiAgICAgIGRlZmF1bHRFdmVudFJldGVudGlvbkRheXM6IFJFUE9SVElOR19FVkVOVF9SRVRFTlRJT05fREFZUyxcbiAgICAgIGRlZmF1bHREb3JhUmV0ZW50aW9uRGF5czogUkVQT1JUSU5HX0RPUkFfUkVURU5USU9OX0RBWVMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcHNlcnQgcGVyLW9yZyByZXBvcnRpbmcgc2V0dGluZ3MgKFBoYXNlIDViIGluY2lkZW50IHdpbmRvdyArIFBoYXNlIDdcbiAgICogcmV0ZW50aW9uIG92ZXJyaWRlcyksIGlkZW1wb3RlbnQgb24gYG9yZ19pZGAuIEEgcGFydGlhbCB3cml0ZSDigJQgb25seSB0aGVcbiAgICogZmllbGRzIHByZXNlbnQgaW4gYHBhdGNoYCBhcmUgc2V0IChzbyB1cGRhdGluZyByZXRlbnRpb24gbmV2ZXIgY2xlYXJzIHRoZVxuICAgKiBpbmNpZGVudCB3aW5kb3csIGFuZCB2aWNlLXZlcnNhKS4gU2V0IHNlbGYtc2VydmUgYnkgYW4gb3JnIGFkbWluIHZpYVxuICAgKiBgUFVUIC9hcGkvcmVwb3J0cy9zZXR0aW5ncy9pbmNpZGVudHNgLiBSdW5zIHVuZGVyIHRoZSBjYWxsZXIncyBvcmcgY29udGV4dFxuICAgKiAoUkxTIFdJVEggQ0hFQ0spOyBhIGNoYW5nZWQgdmFsdWUgYWZmZWN0cyBET1JBIGFnZ3JlZ2F0ZXMgc28gdGhlIG9yZydzXG4gICAqIGNhY2hlZCByZXBvcnRzIGFyZSBkcm9wcGVkLlxuICAgKi9cbiAgYXN5bmMgc2V0UmVwb3J0aW5nU2V0dGluZ3Mob3JnSWQ6IHN0cmluZywgcGF0Y2g6IFJlcG9ydGluZ1NldHRpbmdzUGF0Y2gpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzZXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0geyB1cGRhdGVkQXQ6IG5ldyBEYXRlKCkgfTtcbiAgICBpZiAocGF0Y2guaW5jaWRlbnRXaW5kb3dIb3VycyAhPT0gdW5kZWZpbmVkKSBzZXQuaW5jaWRlbnRXaW5kb3dIb3VycyA9IHBhdGNoLmluY2lkZW50V2luZG93SG91cnM7XG4gICAgaWYgKHBhdGNoLmV2ZW50UmV0ZW50aW9uRGF5cyAhPT0gdW5kZWZpbmVkKSBzZXQuZXZlbnRSZXRlbnRpb25EYXlzID0gcGF0Y2guZXZlbnRSZXRlbnRpb25EYXlzO1xuICAgIGlmIChwYXRjaC5kb3JhUmV0ZW50aW9uRGF5cyAhPT0gdW5kZWZpbmVkKSBzZXQuZG9yYVJldGVudGlvbkRheXMgPSBwYXRjaC5kb3JhUmV0ZW50aW9uRGF5cztcbiAgICBhd2FpdCBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW46IGZhbHNlIH0sICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5pbnNlcnQoc2NoZW1hLmRvcmFTZXR0aW5ncykudmFsdWVzKHtcbiAgICAgICAgb3JnSWQsXG4gICAgICAgIGluY2lkZW50V2luZG93SG91cnM6IHBhdGNoLmluY2lkZW50V2luZG93SG91cnMsXG4gICAgICAgIGV2ZW50UmV0ZW50aW9uRGF5czogcGF0Y2guZXZlbnRSZXRlbnRpb25EYXlzLFxuICAgICAgICBkb3JhUmV0ZW50aW9uRGF5czogcGF0Y2guZG9yYVJldGVudGlvbkRheXMsXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgIH0pLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogc2NoZW1hLmRvcmFTZXR0aW5ncy5vcmdJZCxcbiAgICAgICAgc2V0LFxuICAgICAgfSkpLFxuICAgICk7XG4gICAgYXdhaXQgdGhpcy5pbnZhbGlkYXRlT3JnKG9yZ0lkKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIGNhY2hlIGludmFsaWRhdGlvbiBmYWlsZWQnLCB7IG9yZ0lkLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdCByZWNlbnQgaW5jaWRlbnRzIGZvciBhbiBvcmcgKFBoYXNlIDViIG9yZy1hZG1pbiBzdXJmYWNlKSwgbmV3ZXN0IGZpcnN0LFxuICAgKiBwYWdpbmF0ZWQuIEVhY2ggcm93IGNhcnJpZXMgaXRzIHJlc29sdmVkIHN0YXRlIGFuZCBpdHMgZGVwbG95IGNvcnJlbGF0aW9uIOKAlFxuICAgKiB0aGUgbW9zdCByZWNlbnQgU1VDQ0VTU0ZVTCBkZXBsb3kgdG8gdGhlIGluY2lkZW50J3MgYGVudmlyb25tZW50YCB3aG9zZVxuICAgKiBgY29tcGxldGVkX2F0YCBmYWxscyB3aXRoaW4gdGhlIGVmZmVjdGl2ZSBwZXItb3JnIGNvcnJlbGF0aW9uIHdpbmRvdyBiZWZvcmVcbiAgICogYG9wZW5lZF9hdGAgKHRoZSBzYW1lIHJ1bGUgRE9SQSdzIENGUi9NVFRSIGNvcnJlbGF0aW9uIGFwcGxpZXMpLiBTaW5nbGUtb3JnXG4gICAqIChubyByb2xsdXApIOKAlCBhbiBvcmcgYWRtaW4gdmlld3MgdGhlaXIgb3duIG9yZydzIGluY2lkZW50cy4gUkxTLXNjb3BlZCB2aWFcbiAgICogdGhlIGBwLm9yZ19pZGAvYGkub3JnX2lkYCBwcmVkaWNhdGVzICsgdGhlIHRlbmFudCBjb250ZXh0LlxuICAgKi9cbiAgYXN5bmMgbGlzdEluY2lkZW50cyhvcmdJZDogc3RyaW5nLCBvcHRzOiB7IGxpbWl0OiBudW1iZXI7IG9mZnNldDogbnVtYmVyIH0pOiBQcm9taXNlPEluY2lkZW50TGlzdEl0ZW1bXT4ge1xuICAgIGNvbnN0IHsgaW5jaWRlbnRXaW5kb3dIb3VycyB9ID0gYXdhaXQgdGhpcy5nZXRJbmNpZGVudFNldHRpbmdzKG9yZ0lkKTtcbiAgICBjb25zdCB3aW5kb3dIb3VycyA9IHJlc29sdmVJbmNpZGVudFdpbmRvd0hvdXJzKGluY2lkZW50V2luZG93SG91cnMpO1xuICAgIGNvbnN0IGxpbWl0ID0gTWF0aC5tYXgoMSwgTWF0aC5taW4ob3B0cy5saW1pdCwgMjAwKSk7XG4gICAgY29uc3Qgb2Zmc2V0ID0gTWF0aC5tYXgoMCwgb3B0cy5vZmZzZXQpO1xuICAgIC8vIFRoZSBjb3JyZWxhdGlvbiB3aW5kb3cgaXMgZXhwcmVzc2VkIGluIFNFQ09ORFMgYXMgYSBkb3VibGUsIG5vdCBhc1xuICAgIC8vIGBtYWtlX2ludGVydmFsKGhvdXJzID0+IE46OmludClgLiBUaGUgd2luZG93IGlzIHZhbGlkYXRlZCBhcyBhbnkgcG9zaXRpdmVcbiAgICAvLyBudW1iZXIgKDAuNWggaXMgbGVnYWwpIGFuZCB0aGUgaW4tbWVtb3J5IERPUkEgY29ycmVsYXRpb24gdXNlcyBpdCBleGFjdGx5O1xuICAgIC8vIHRoZSBpbnQgY2FzdCBtYWRlIFBvc3RncmVzIHJlamVjdCBhIGZyYWN0aW9uYWwgdmFsdWUsIHNvIGEgMC41aCB3aW5kb3dcbiAgICAvLyByZXR1cm5lZCA1MDAgZnJvbSB0aGlzIGVuZHBvaW50IGFuZCBmcm9tIHRoZSBjb3JyZWxhdGlvbiBsb29rdXAgYmVsb3cuXG4gICAgcmV0dXJuIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBpLmluY2lkZW50X2lkIEFTIFwiaW5jaWRlbnRJZFwiLFxuICAgICAgICAgIGkuZW52aXJvbm1lbnQgQVMgZW52aXJvbm1lbnQsXG4gICAgICAgICAgaS5zZXZlcml0eSBBUyBzZXZlcml0eSxcbiAgICAgICAgICBpLm9wZW5lZF9hdDo6dGV4dCBBUyBcIm9wZW5lZEF0XCIsXG4gICAgICAgICAgaS5yZXNvbHZlZF9hdDo6dGV4dCBBUyBcInJlc29sdmVkQXRcIixcbiAgICAgICAgICBpLmNyZWF0ZWRfYXQ6OnRleHQgQVMgXCJjcmVhdGVkQXRcIixcbiAgICAgICAgICAoaS5yZXNvbHZlZF9hdCBJUyBOT1QgTlVMTCkgQVMgcmVzb2x2ZWQsXG4gICAgICAgICAgY29yci5leGVjdXRpb25faWQgQVMgXCJjb3JyZWxhdGVkRXhlY3V0aW9uSWRcIixcbiAgICAgICAgICBjb3JyLmNvbXBsZXRlZF9hdDo6dGV4dCBBUyBcImRlcGxveUNvbXBsZXRlZEF0XCJcbiAgICAgICAgRlJPTSAke3NjaGVtYS5pbmNpZGVudH0gaVxuICAgICAgICBMRUZUIEpPSU4gTEFURVJBTCAoXG4gICAgICAgICAgU0VMRUNUIGUuZXhlY3V0aW9uX2lkLCBlLmNvbXBsZXRlZF9hdFxuICAgICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnXG4gICAgICAgICAgICBBTkQgZS5lbnZpcm9ubWVudCA9IGkuZW52aXJvbm1lbnQgQU5EIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCdcbiAgICAgICAgICAgIEFORCBlLmNvbXBsZXRlZF9hdCA8PSBpLm9wZW5lZF9hdFxuICAgICAgICAgICAgQU5EIGUuY29tcGxldGVkX2F0ID49IGkub3BlbmVkX2F0IC0gbWFrZV9pbnRlcnZhbChzZWNzID0+ICR7d2luZG93SG91cnMgKiAzNjAwfTo6ZG91YmxlIHByZWNpc2lvbilcbiAgICAgICAgICBPUkRFUiBCWSBlLmNvbXBsZXRlZF9hdCBERVNDXG4gICAgICAgICAgTElNSVQgMVxuICAgICAgICApIGNvcnIgT04gdHJ1ZVxuICAgICAgICBXSEVSRSBpLm9yZ19pZCA9ICR7b3JnSWR9XG4gICAgICAgIE9SREVSIEJZIGkub3BlbmVkX2F0IERFU0NcbiAgICAgICAgTElNSVQgJHtsaW1pdH0gT0ZGU0VUICR7b2Zmc2V0fVxuICAgICAgYCkudGhlbigocikgPT4gZHJpenpsZVJvd3M8SW5jaWRlbnRMaXN0SXRlbT4oci5yb3dzKS5tYXAoKHJvdykgPT4gKHtcbiAgICAgIC4uLnJvdyxcbiAgICAgIHJlc29sdmVkOiByb3cucmVzb2x2ZWQgPT09IHRydWUgfHwgKHJvdy5yZXNvbHZlZCBhcyB1bmtub3duKSA9PT0gJ3QnLFxuICAgICAgY29ycmVsYXRlZEV4ZWN1dGlvbklkOiByb3cuY29ycmVsYXRlZEV4ZWN1dGlvbklkID8/IG51bGwsXG4gICAgICBkZXBsb3lDb21wbGV0ZWRBdDogcm93LmRlcGxveUNvbXBsZXRlZEF0ID8/IG51bGwsXG4gICAgfSkpKSk7XG4gIH1cblxuICAvKipcbiAgICogV2lyaW5nLXRlc3QgZHJ5LXJ1biAoUGhhc2UgNWIpOiB3b3VsZCBhIHN5bnRoZXRpYyBpbmNpZGVudCBvcGVuaW5nIE5PVyBmb3JcbiAgICogYGVudmlyb25tZW50YCBjb3JyZWxhdGUgdG8gYSByZWNlbnQgc3VjY2Vzc2Z1bCBkZXBsb3kgdW5kZXIgdGhlIG9yZydzXG4gICAqIGVmZmVjdGl2ZSB3aW5kb3c/IFRoaXMgaXMgYSBOT04tcGVyc2lzdGluZyBjb3JyZWxhdGlvbiBjaGVjayDigJQgaXQgdmVyaWZpZXNcbiAgICogdGhlIGFkbWluJ3MgZW52aXJvbm1lbnQgbmFtaW5nICsgd2luZG93IGxpbmUgdXAgd2l0aCByZWFsIGRlcGxveSBldmVudHNcbiAgICogV0lUSE9VVCB3cml0aW5nIGFuIGluY2lkZW50IChzbyBhIFwidGVzdFwiIG5ldmVyIHBvbGx1dGVzIENGUi9NVFRSKS4gUkxTLXNjb3BlZC5cbiAgICovXG4gIGFzeW5jIHRlc3RJbmNpZGVudENvcnJlbGF0aW9uKG9yZ0lkOiBzdHJpbmcsIGVudmlyb25tZW50OiBzdHJpbmcpOiBQcm9taXNlPEluY2lkZW50VGVzdFJlc3VsdD4ge1xuICAgIGNvbnN0IGVudiA9IHNjcnViQXdzSWRlbnRpZmllcnNGcm9tU3RyaW5nKGVudmlyb25tZW50KTtcbiAgICBjb25zdCBvcGVuZWRBdCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICBjb25zdCB7IGluY2lkZW50V2luZG93SG91cnMgfSA9IGF3YWl0IHRoaXMuZ2V0SW5jaWRlbnRTZXR0aW5ncyhvcmdJZCk7XG4gICAgY29uc3Qgd2luZG93SG91cnMgPSByZXNvbHZlSW5jaWRlbnRXaW5kb3dIb3VycyhpbmNpZGVudFdpbmRvd0hvdXJzKTtcbiAgICBjb25zdCByb3dzID0gZHJpenpsZVJvd3M8eyBleGVjdXRpb25faWQ6IHN0cmluZyB8IG51bGw7IGNvbXBsZXRlZF9hdDogc3RyaW5nIHwgbnVsbCB9PigoYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVCBlLmV4ZWN1dGlvbl9pZCBBUyBleGVjdXRpb25faWQsIGUuY29tcGxldGVkX2F0Ojp0ZXh0IEFTIGNvbXBsZXRlZF9hdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnXG4gICAgICAgICAgQU5EIGUuZW52aXJvbm1lbnQgPSAke2Vudn0gQU5EIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCdcbiAgICAgICAgICBBTkQgZS5jb21wbGV0ZWRfYXQgPD0gJHtvcGVuZWRBdH06OnRpbWVzdGFtcHR6XG4gICAgICAgICAgQU5EIGUuY29tcGxldGVkX2F0ID49ICR7b3BlbmVkQXR9Ojp0aW1lc3RhbXB0eiAtIG1ha2VfaW50ZXJ2YWwoc2VjcyA9PiAke3dpbmRvd0hvdXJzICogMzYwMH06OmRvdWJsZSBwcmVjaXNpb24pXG4gICAgICAgIE9SREVSIEJZIGUuY29tcGxldGVkX2F0IERFU0NcbiAgICAgICAgTElNSVQgMVxuICAgICAgYCkpKS5yb3dzKTtcbiAgICBjb25zdCBoaXQgPSByb3dzWzBdO1xuICAgIHJldHVybiB7XG4gICAgICBlbnZpcm9ubWVudDogZW52LFxuICAgICAgb3BlbmVkQXQsXG4gICAgICB3aW5kb3dIb3VycyxcbiAgICAgIGNvcnJlbGF0ZWQ6IGhpdD8uZXhlY3V0aW9uX2lkICE9IG51bGwsXG4gICAgICBleGVjdXRpb25JZDogaGl0Py5leGVjdXRpb25faWQgPz8gbnVsbCxcbiAgICAgIGRlcGxveUNvbXBsZXRlZEF0OiBoaXQ/LmNvbXBsZXRlZF9hdCA/PyBudWxsLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVXBzZXJ0IHBlci1vcmcgaW5nZXN0aW9uIGhlYWx0aCAoUGhhc2UgMyk6IHRoZSBBV1MgZXZlbnRzIExhbWJkYSBwZXJpb2RpY2FsbHlcbiAgICogcmVwb3J0cyBmb3J3YXJkZWQvZHJvcHBlZCBjb3VudGVycyArIHRoZSBsYXN0IGV2ZW50IHRpbWVzdGFtcCBzbyB0aGUgUmVwb3J0c1xuICAgKiBVSSBjYW4gc2hvdyBmbG93aW5nIC8gc3RhbGUgLyBkcm9wcGluZy4gT25lIHJvdyBwZXIgb3JnICh1cHNlcnQgb24gb3JnX2lkKS5cbiAgICovXG4gIGFzeW5jIHJlY29yZEluZ2VzdEhlYWx0aChcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIGlucHV0OiB7IGZvcndhcmRlZD86IG51bWJlcjsgZHJvcHBlZD86IG51bWJlcjsgbGFzdEV2ZW50QXQ/OiBzdHJpbmcgfSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbGFzdEV2ZW50QXQgPSBpbnB1dC5sYXN0RXZlbnRBdCA/IG5ldyBEYXRlKGlucHV0Lmxhc3RFdmVudEF0KSA6IHVuZGVmaW5lZDtcbiAgICBhd2FpdCBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW46IGZhbHNlIH0sICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5pbnNlcnQoc2NoZW1hLmluZ2VzdEhlYWx0aCkudmFsdWVzKHtcbiAgICAgICAgb3JnSWQsXG4gICAgICAgIGZvcndhcmRlZDogaW5wdXQuZm9yd2FyZGVkLFxuICAgICAgICBkcm9wcGVkOiBpbnB1dC5kcm9wcGVkLFxuICAgICAgICBsYXN0RXZlbnRBdCxcbiAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgfSkub25Db25mbGljdERvVXBkYXRlKHtcbiAgICAgICAgdGFyZ2V0OiBzY2hlbWEuaW5nZXN0SGVhbHRoLm9yZ0lkLFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICBmb3J3YXJkZWQ6IGlucHV0LmZvcndhcmRlZCxcbiAgICAgICAgICBkcm9wcGVkOiBpbnB1dC5kcm9wcGVkLFxuICAgICAgICAgIGxhc3RFdmVudEF0LFxuICAgICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgfSxcbiAgICAgIH0pKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgYmFjayBvbmUgb3JnJ3MgaW5nZXN0aW9uIGhlYWx0aCAoUGhhc2UgMykgZm9yIHRoZSBSZXBvcnRzIFVJIGZyZXNobmVzc1xuICAgKiBpbmRpY2F0b3IuIFJldHVybnMgYG51bGxgIHdoZW4gdGhlIG9yZyBoYXMgTk8gcm93IOKAlCBpLmUuIHRoZSBkZXBsb3ltZW50IGhhc1xuICAgKiBuZXZlciBpbmdlc3RlZCBhbnl0aGluZyDigJQgd2hpY2ggdGhlIFVJIG11c3QgcmVuZGVyIGFzIFwibm8gaW5nZXN0IHJlcG9ydGVkXG4gICAqIHlldFwiLCBuZXZlciBhcyBcInN0YWxlXCIuIFJMUy1zY29wZWQgdG8gdGhlIG9yZyBsaWtlIGV2ZXJ5IG90aGVyIHJlYWQuXG4gICAqL1xuICBhc3luYyBnZXRJbmdlc3RIZWFsdGgob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8SW5nZXN0SGVhbHRoU3RhdHVzIHwgbnVsbD4ge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW46IGZhbHNlIH0sICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eFxuICAgICAgICAuc2VsZWN0KClcbiAgICAgICAgLmZyb20oc2NoZW1hLmluZ2VzdEhlYWx0aClcbiAgICAgICAgLndoZXJlKGVxKHNjaGVtYS5pbmdlc3RIZWFsdGgub3JnSWQsIG9yZ0lkKSlcbiAgICAgICAgLmxpbWl0KDEpKSxcbiAgICApO1xuICAgIGNvbnN0IHJvdyA9IHJvd3NbMF07XG4gICAgaWYgKCFyb3cpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB7XG4gICAgICB1cGRhdGVkQXQ6IHJvdy51cGRhdGVkQXQudG9JU09TdHJpbmcoKSxcbiAgICAgIGxhc3RFdmVudEF0OiByb3cubGFzdEV2ZW50QXQgPyByb3cubGFzdEV2ZW50QXQudG9JU09TdHJpbmcoKSA6IG51bGwsXG4gICAgICBmb3J3YXJkZWQ6IHJvdy5mb3J3YXJkZWQgPz8gbnVsbCxcbiAgICAgIGRyb3BwZWQ6IHJvdy5kcm9wcGVkID8/IG51bGwsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCYXRjaGVkIGhhcmQtREVMRVRFIG9mIG9uZSByZXBvcnRpbmcgdGFibGUncyByb3dzIGV4cGlyZWQgcGFzdCBhIGBjcmVhdGVkX2F0YFxuICAgKiBjdXRvZmYsIHNjb3BlZCB0byBhbiBvcmcgYW5kIGFuIG9wdGlvbmFsIHJvdyBwcmVkaWNhdGUgKFBoYXNlIDcpLiBVc2VzIGFcbiAgICogYGN0aWRgLWluLXN1YnF1ZXJ5IExJTUlUIHNvIGVhY2ggc3RhdGVtZW50IHRvdWNoZXMgYXQgbW9zdCBgYmF0Y2hTaXplYCByb3dzXG4gICAqIChzaG9ydCBsb2NrIHdpbmRvd3MsIG5vIGxvbmcgdGFibGUgc2NhbiB1bmRlciBsb2NrKTsgYFJFVFVSTklORyAxYCBsZXRzIHVzXG4gICAqIGNvdW50IHZpYSBgLnJvd3MubGVuZ3RoYCB3aXRob3V0IGRlcGVuZGluZyBvbiB0aGUgZHJpdmVyJ3MgYHJvd0NvdW50YC4gTG9vcHNcbiAgICogdW50aWwgYSBzaG9ydCBiYXRjaCAoZHJhaW5lZCkgb3IgdGhlIHBlci10aWNrIGNhcCwgdGhlbiBkZWZlcnMgdGhlIHJlc3QuXG4gICAqIE1VU1QgcnVuIGluc2lkZSBhIHN5c2FkbWluIHRlbmFudCBzY29wZSAoc2VlIHB1cmdlRXhwaXJlZFJlcG9ydGluZ0RhdGEpIHNvIGl0XG4gICAqIGJ5cGFzc2VzIFJMUyBhbmQgY2FuIGRlbGV0ZSBhY3Jvc3MgdGhlIG9yZydzIHJvd3MuXG4gICAqL1xuICBhc3luYyAjcHVyZ2VSZXBvcnRpbmdUYWJsZUJhdGNoZWQoXG4gICAgdGFibGVTcWw6IFJldHVyblR5cGU8dHlwZW9mIHNxbD4sXG4gICAgcHJlZGljYXRlOiBSZXR1cm5UeXBlPHR5cGVvZiBzcWw+LFxuICAgIGJhdGNoU2l6ZTogbnVtYmVyLFxuICAgIG1heEJhdGNoZXM6IG51bWJlcixcbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBsZXQgdG90YWwgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF4QmF0Y2hlczsgaSsrKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgREVMRVRFIEZST00gJHt0YWJsZVNxbH1cbiAgICAgICAgV0hFUkUgY3RpZCBJTiAoXG4gICAgICAgICAgU0VMRUNUIGN0aWQgRlJPTSAke3RhYmxlU3FsfVxuICAgICAgICAgIFdIRVJFICR7cHJlZGljYXRlfVxuICAgICAgICAgIExJTUlUICR7YmF0Y2hTaXplfVxuICAgICAgICApXG4gICAgICAgIFJFVFVSTklORyAxXG4gICAgICBgKSk7XG4gICAgICBjb25zdCBwdXJnZWQgPSBkcml6emxlUm93czx1bmtub3duPihyZXMucm93cykubGVuZ3RoO1xuICAgICAgdG90YWwgKz0gcHVyZ2VkO1xuICAgICAgaWYgKHB1cmdlZCA8IGJhdGNoU2l6ZSkgYnJlYWs7IC8vIGRyYWluZWRcbiAgICAgIGlmIChpID09PSBtYXhCYXRjaGVzIC0gMSkge1xuICAgICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIHJldGVudGlvbiBoaXQgcGVyLXRpY2sgY2FwOyByZW1haW5pbmcgcm93cyBkZWZlcnJlZCcsIHtcbiAgICAgICAgICBwdXJnZWRUaGlzVGljazogdG90YWwsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdG90YWw7XG4gIH1cblxuICAvKipcbiAgICogUmVwb3J0aW5nIHJldGVudGlvbiBzd2VlcCAoUGhhc2UgNykuIEhhcmQtZGVsZXRlcyByb3dzIG9sZGVyIHRoYW4gdGhlaXJcbiAgICogcmV0ZW50aW9uIHdpbmRvdywgYnkgYGNyZWF0ZWRfYXRgLCBhY3Jvc3MgZXZlcnkgb3JnIHRoYXQgaGFzIHJlcG9ydGluZyBkYXRhIOKAlFxuICAgKiBhICoqc3BsaXQqKiBwb2xpY3kgc28gaGlnaC12b2x1bWUgc3RhbmRhcmQgZXZlbnRzIGV4cGlyZSBmYXN0ZXIgdGhhbiB0aGVcbiAgICogbG93LXZvbHVtZSBET1JBIHNvdXJjZTpcbiAgICogIC0gYHBpcGVsaW5lX2V2ZW50cyBXSEVSRSBlbnZpcm9ubWVudCBJUyBOVUxMYCDihpIgc3RhbmRhcmQtZXZlbnQgd2luZG93LlxuICAgKiAgLSBgcGlwZWxpbmVfZXZlbnRzIFdIRVJFIGVudmlyb25tZW50IElTIE5PVCBOVUxMYCAoZGVwbG95IHN0YWdlcyksXG4gICAqICAgIGBkZXBsb3ltZW50X291dGNvbWVzYCwgYW5kIGBpbmNpZGVudHNgIOKGkiBET1JBLXNvdXJjZSB3aW5kb3cuXG4gICAqIEVhY2ggb3JnJ3Mgd2luZG93cyBjb21lIGZyb20gaXRzIGBkb3JhX3NldHRpbmdzYCBvdmVycmlkZSwgZWxzZSB0aGUgZ2xvYmFsXG4gICAqIGVudiBkZWZhdWx0cyAoc2VlIHtAbGluayByZXNvbHZlRXZlbnRSZXRlbnRpb25EYXlzfSAvIHtAbGluayByZXNvbHZlRG9yYVJldGVudGlvbkRheXN9KS5cbiAgICogYGluZ2VzdF9oZWFsdGhgIGFuZCBgZG9yYV9zZXR0aW5nc2AgYXJlIG5ldmVyIHB1cmdlZC4gT25lIGBub3dgIGZvciB0aGUgd2hvbGVcbiAgICogdGljayAocm93cyBjcm9zc2luZyB0aGUgYm91bmRhcnkgbWlkLXN3ZWVwIHdhaXQgZm9yIHRoZSBuZXh0KS4gRXN0YWJsaXNoZXMgYVxuICAgKiBzeXNhZG1pbiB0ZW5hbnQgc2NvcGUgc28gdGhlIGRlbGV0ZXMgc3BhbiBhbGwgb3JncyAvIGJ5cGFzcyBSTFMg4oCUIHRoaXMgaXMgYVxuICAgKiBjcm9zcy10ZW5hbnQgaG91c2VrZWVwaW5nIGpvYi4gUmV0dXJucyAoYW5kIGxvZ3MpIHBlci13aW5kb3cgcHVyZ2UgdGFsbGllcy5cbiAgICovXG4gIGFzeW5jIHB1cmdlRXhwaXJlZFJlcG9ydGluZ0RhdGEob3B0czogUmVwb3J0aW5nUmV0ZW50aW9uT3B0aW9ucyA9IHt9KTogUHJvbWlzZTxSZXBvcnRpbmdSZXRlbnRpb25Db3VudHM+IHtcbiAgICBjb25zdCBiYXRjaFNpemUgPSBNYXRoLm1heCgxLCBvcHRzLmJhdGNoU2l6ZSA/PyAxMDAwKTtcbiAgICBjb25zdCBtYXhCYXRjaGVzID0gTWF0aC5tYXgoMSwgb3B0cy5tYXhCYXRjaGVzUGVyVGFibGUgPz8gNTApO1xuICAgIGNvbnN0IG5vdyA9IG9wdHMubm93ID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgY291bnRzOiBSZXBvcnRpbmdSZXRlbnRpb25Db3VudHMgPSB7XG4gICAgICBvcmdzOiAwLCBzdGFuZGFyZEV2ZW50czogMCwgZG9yYUV2ZW50czogMCwgZGVwbG95bWVudE91dGNvbWVzOiAwLCBpbmNpZGVudHM6IDAsXG4gICAgfTtcblxuICAgIHJldHVybiBydW5XaXRoVGVuYW50Q29udGV4dCh7IGlzU3VwZXJBZG1pbjogdHJ1ZSB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBFbnVtZXJhdGUgZXZlcnkgb3JnIHdpdGggcmVwb3J0aW5nIGRhdGEgKHVuaW9uIGFjcm9zcyB0aGUgdGhyZWUgdGFibGVzKS5cbiAgICAgIGNvbnN0IG9yZ1Jvd3MgPSBkcml6emxlUm93czx7IG9yZ19pZDogc3RyaW5nIH0+KChhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUIERJU1RJTkNUIG9yZ19pZCBGUk9NIChcbiAgICAgICAgICBTRUxFQ1QgJHtzY2hlbWEucGlwZWxpbmVFdmVudC5vcmdJZH0gQVMgb3JnX2lkIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH1cbiAgICAgICAgICBVTklPTlxuICAgICAgICAgIFNFTEVDVCAke3NjaGVtYS5kZXBsb3ltZW50T3V0Y29tZS5vcmdJZH0gQVMgb3JnX2lkIEZST00gJHtzY2hlbWEuZGVwbG95bWVudE91dGNvbWV9XG4gICAgICAgICAgVU5JT05cbiAgICAgICAgICBTRUxFQ1QgJHtzY2hlbWEuaW5jaWRlbnQub3JnSWR9IEFTIG9yZ19pZCBGUk9NICR7c2NoZW1hLmluY2lkZW50fVxuICAgICAgICApIEFTIG9yZ3NcbiAgICAgIGApKSkucm93cyk7XG4gICAgICBpZiAob3JnUm93cy5sZW5ndGggPT09IDApIHJldHVybiBjb3VudHM7XG5cbiAgICAgIC8vIFBlci1vcmcgcmV0ZW50aW9uIG92ZXJyaWRlcyAoYSBzaW5nbGUgcmVhZDsgb3JncyB3aXRob3V0IGEgcm93IHVzZSBkZWZhdWx0cykuXG4gICAgICBjb25zdCBvdmVycmlkZVJvd3MgPSBkcml6emxlUm93czx7XG4gICAgICAgIG9yZ19pZDogc3RyaW5nO1xuICAgICAgICBldmVudF9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbDtcbiAgICAgICAgZG9yYV9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbDtcbiAgICAgIH0+KChhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5vcmdJZH0gQVMgb3JnX2lkLFxuICAgICAgICAgICAgICAgJHtzY2hlbWEuZG9yYVNldHRpbmdzLmV2ZW50UmV0ZW50aW9uRGF5c30gQVMgZXZlbnRfcmV0ZW50aW9uX2RheXMsXG4gICAgICAgICAgICAgICAke3NjaGVtYS5kb3JhU2V0dGluZ3MuZG9yYVJldGVudGlvbkRheXN9IEFTIGRvcmFfcmV0ZW50aW9uX2RheXNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5kb3JhU2V0dGluZ3N9XG4gICAgICBgKSkpLnJvd3MpO1xuICAgICAgY29uc3Qgb3ZlcnJpZGVzID0gbmV3IE1hcChvdmVycmlkZVJvd3MubWFwKChyKSA9PiBbci5vcmdfaWQsIHJdKSk7XG5cbiAgICAgIGNvbnN0IGV2ZW50c1RhYmxlID0gc3FsYCR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9YDtcbiAgICAgIGNvbnN0IG91dGNvbWVzVGFibGUgPSBzcWxgJHtzY2hlbWEuZGVwbG95bWVudE91dGNvbWV9YDtcbiAgICAgIGNvbnN0IGluY2lkZW50c1RhYmxlID0gc3FsYCR7c2NoZW1hLmluY2lkZW50fWA7XG5cbiAgICAgIGZvciAoY29uc3QgeyBvcmdfaWQ6IG9yZ0lkIH0gb2Ygb3JnUm93cykge1xuICAgICAgICBjb25zdCBvdiA9IG92ZXJyaWRlcy5nZXQob3JnSWQpO1xuICAgICAgICBjb25zdCBldmVudERheXMgPSByZXNvbHZlRXZlbnRSZXRlbnRpb25EYXlzKG92Py5ldmVudF9yZXRlbnRpb25fZGF5cyk7XG4gICAgICAgIGNvbnN0IGRvcmFEYXlzID0gcmVzb2x2ZURvcmFSZXRlbnRpb25EYXlzKG92Py5kb3JhX3JldGVudGlvbl9kYXlzKTtcbiAgICAgICAgLy8gYC0xYCA9IHVubGltaXRlZCAoUGhhc2UgOCk6IGtlZXAgZm9yZXZlciwgc2tpcCB0aGF0IHdpbmRvdydzIGRlbGV0ZXMgZm9yXG4gICAgICAgIC8vIHRoaXMgb3JnLiBTdGFuZGFyZC1ldmVudCBhbmQgRE9SQS1zb3VyY2Ugd2luZG93cyBhcmUgaW5kZXBlbmRlbnQ7IGFuIG9yZ1xuICAgICAgICAvLyB3aXRoIGJvdGggYC0xYCBpcyBmdWxseSBza2lwcGVkLiBMb2cgdGhlIHNraXAgc28gaXQncyBvYnNlcnZhYmxlLlxuICAgICAgICBjb25zdCBza2lwRXZlbnRzID0gZXZlbnREYXlzID09PSAtMTtcbiAgICAgICAgY29uc3Qgc2tpcERvcmEgPSBkb3JhRGF5cyA9PT0gLTE7XG4gICAgICAgIGlmIChza2lwRXZlbnRzIHx8IHNraXBEb3JhKSB7XG4gICAgICAgICAgbG9nZ2VyLmluZm8oJ1JlcG9ydGluZyByZXRlbnRpb24gc3dlZXAgc2tpcHBpbmcgdW5saW1pdGVkIHdpbmRvdyhzKScsIHtcbiAgICAgICAgICAgIG9yZ0lkLFxuICAgICAgICAgICAgc3RhbmRhcmRFdmVudHM6IHNraXBFdmVudHMgPyAndW5saW1pdGVkJyA6IGV2ZW50RGF5cyxcbiAgICAgICAgICAgIGRvcmFTb3VyY2U6IHNraXBEb3JhID8gJ3VubGltaXRlZCcgOiBkb3JhRGF5cyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc2tpcEV2ZW50cykge1xuICAgICAgICAgIGNvbnN0IGV2ZW50Q3V0b2ZmID0gcmV0ZW50aW9uQ3V0b2ZmKG5vdywgZXZlbnREYXlzKTtcbiAgICAgICAgICBjb3VudHMuc3RhbmRhcmRFdmVudHMgKz0gYXdhaXQgdGhpcy4jcHVyZ2VSZXBvcnRpbmdUYWJsZUJhdGNoZWQoXG4gICAgICAgICAgICBldmVudHNUYWJsZSxcbiAgICAgICAgICAgIC8vIFNwYXJlIHJvd3MgY2FycnlpbmcgYSBjb21taXQgdGltZXN0YW1wOiB0aGV5IGFyZSBET1JBIFNPVVJDRSBkYXRhLlxuICAgICAgICAgICAgLy8gTGVhZCB0aW1lIGpvaW5zIGRlcGxveXMgdG8gdGhlIGV4ZWN1dGlvbidzIGVhcmxpZXN0XG4gICAgICAgICAgICAvLyBgY29tbWl0X3RpbWVzdGFtcGAsIGFuZCB0aGF0IGVucmljaG1lbnQgcmlkZXMgdGhlIFBJUEVMSU5FL3NvdXJjZVxuICAgICAgICAgICAgLy8gZXZlbnQgKGVudmlyb25tZW50IElTIE5VTEwpLCBuZXZlciB0aGUgZGVwbG95IFNUQUdFIHJvdy4gUHVyZ2luZ1xuICAgICAgICAgICAgLy8gdGhlbSBvbiB0aGlzIHNob3J0IHdpbmRvdyB3aGlsZSB0aGUgZGVwbG95cyB0aGV5IGV4cGxhaW4gbGl2ZSBvblxuICAgICAgICAgICAgLy8gdGhlIERPUkEgd2luZG93IG1hZGUgbGVhZCB0aW1lIHJlYWQgXCJ1bmtub3duXCIgZm9yIGV2ZXJ5IHJhbmdlXG4gICAgICAgICAgICAvLyBvbGRlciB0aGFuIHRoZSBzdGFuZGFyZCByZXRlbnRpb24g4oCUIHNpbGVudGx5LCB3aXRoIHRoZSBkZXBsb3lzXG4gICAgICAgICAgICAvLyBzdGlsbCBjb3VudGVkLiBUaGV5IGZvbGxvdyB0aGUgRE9SQSB3aW5kb3cgYmVsb3cgaW5zdGVhZC5cbiAgICAgICAgICAgIHNxbGBvcmdfaWQgPSAke29yZ0lkfSBBTkQgZW52aXJvbm1lbnQgSVMgTlVMTCBBTkQgY29tbWl0X3RpbWVzdGFtcCBJUyBOVUxMIEFORCBjcmVhdGVkX2F0IDwgJHtldmVudEN1dG9mZn1gLFxuICAgICAgICAgICAgYmF0Y2hTaXplLCBtYXhCYXRjaGVzLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXNraXBEb3JhKSB7XG4gICAgICAgICAgY29uc3QgZG9yYUN1dG9mZiA9IHJldGVudGlvbkN1dG9mZihub3csIGRvcmFEYXlzKTtcbiAgICAgICAgICBjb3VudHMuZG9yYUV2ZW50cyArPSBhd2FpdCB0aGlzLiNwdXJnZVJlcG9ydGluZ1RhYmxlQmF0Y2hlZChcbiAgICAgICAgICAgIGV2ZW50c1RhYmxlLFxuICAgICAgICAgICAgc3FsYG9yZ19pZCA9ICR7b3JnSWR9IEFORCAoZW52aXJvbm1lbnQgSVMgTk9UIE5VTEwgT1IgY29tbWl0X3RpbWVzdGFtcCBJUyBOT1QgTlVMTCkgQU5EIGNyZWF0ZWRfYXQgPCAke2RvcmFDdXRvZmZ9YCxcbiAgICAgICAgICAgIGJhdGNoU2l6ZSwgbWF4QmF0Y2hlcyxcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvdW50cy5kZXBsb3ltZW50T3V0Y29tZXMgKz0gYXdhaXQgdGhpcy4jcHVyZ2VSZXBvcnRpbmdUYWJsZUJhdGNoZWQoXG4gICAgICAgICAgICBvdXRjb21lc1RhYmxlLFxuICAgICAgICAgICAgc3FsYG9yZ19pZCA9ICR7b3JnSWR9IEFORCBjcmVhdGVkX2F0IDwgJHtkb3JhQ3V0b2ZmfWAsXG4gICAgICAgICAgICBiYXRjaFNpemUsIG1heEJhdGNoZXMsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb3VudHMuaW5jaWRlbnRzICs9IGF3YWl0IHRoaXMuI3B1cmdlUmVwb3J0aW5nVGFibGVCYXRjaGVkKFxuICAgICAgICAgICAgaW5jaWRlbnRzVGFibGUsXG4gICAgICAgICAgICBzcWxgb3JnX2lkID0gJHtvcmdJZH0gQU5EIGNyZWF0ZWRfYXQgPCAke2RvcmFDdXRvZmZ9YCxcbiAgICAgICAgICAgIGJhdGNoU2l6ZSwgbWF4QmF0Y2hlcyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGNvdW50cy5vcmdzICs9IDE7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHB1cmdlZEFueSA9IGNvdW50cy5zdGFuZGFyZEV2ZW50cyArIGNvdW50cy5kb3JhRXZlbnRzICsgY291bnRzLmRlcGxveW1lbnRPdXRjb21lcyArIGNvdW50cy5pbmNpZGVudHM7XG4gICAgICBpZiAocHVyZ2VkQW55ID4gMCkgbG9nZ2VyLmluZm8oJ1JlcG9ydGluZyByZXRlbnRpb24gc3dlZXAgcHVyZ2VkIGV4cGlyZWQgcm93cycsIHsgLi4uY291bnRzIH0pO1xuICAgICAgcmV0dXJuIGNvdW50cztcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgcmVwb3J0aW5nU2VydmljZSA9IG5ldyBSZXBvcnRpbmdTZXJ2aWNlKCk7XG4iXX0=
984
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0aW5nLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JlcG9ydGluZy1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM1SCxPQUFPLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBZSxNQUFNLG1CQUFtQixDQUFDO0FBQzdELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFNUUsZ0ZBQWdGO0FBQ2hGLDRFQUE0RTtBQUM1RSxPQUFPLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3JHLE9BQU8sRUFDTCxjQUFjLElBQUksV0FBVyxFQUM3QixZQUFZLElBQUksU0FBUyxFQUN6QixjQUFjLElBQUksV0FBVyxHQUM5QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFDTCxnQkFBZ0IsSUFBSSxhQUFhLEVBQ2pDLHlCQUF5QixJQUFJLHNCQUFzQixFQUNuRCxvQkFBb0IsSUFBSSxpQkFBaUIsR0FDMUMsTUFBTSwrQkFBK0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDcEQsOEVBQThFO0FBQzlFLE9BQU8sRUFDTCw4QkFBOEIsRUFBRSw2QkFBNkIsRUFDN0QseUJBQXlCLEVBQUUsd0JBQXdCLEVBQUUsZUFBZSxH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QU0sZ0JBQWdCLEdBQUcsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlLCBzY3J1YkF3c0lkZW50aWZpZXJzLCBzY3J1YkF3c0lkZW50aWZpZXJzRnJvbVN0cmluZyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGVxLCBpbkFycmF5LCBzcWwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgeyBkcml6emxlUm93cywgdHlwZSBDcnVkVHggfSBmcm9tICcuL2NydWQtc2VydmljZS5qcyc7XG5pbXBvcnQgeyBzY2hlbWEgfSBmcm9tICcuLi9kYXRhYmFzZS9kcml6emxlLXNjaGVtYS5qcyc7XG5pbXBvcnQgeyB3aXRoVGVuYW50VHgsIHJ1bldpdGhUZW5hbnRDb250ZXh0IH0gZnJvbSAnLi4vZGF0YWJhc2UvdGVuYW5jeS5qcyc7XG5cbi8vIEV4dHJhY3RlZCBmb3Igc2l6ZSDigJQgc2VlIC4vcmVwb3J0aW5nLy4gRXZlcnl0aGluZyBwdWJsaWMgaXMgcmUtZXhwb3J0ZWQgYmVsb3dcbi8vIHNvIGBAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1kYXRhYCdzIHN1cmZhY2UgaXMgdW5jaGFuZ2VkIGJ5IHRoZSBzcGxpdC5cbmltcG9ydCB7IGludmVudG9yeUNhY2hlLCB0aW1lc2VyaWVzQ2FjaGUgfSBmcm9tICcuL3JlcG9ydGluZy9jYWNoZXMuanMnO1xuaW1wb3J0IHsgRE9SQV9JTkNJREVOVF9XSU5ET1dfSE9VUlMsIHJlc29sdmVJbmNpZGVudFdpbmRvd0hvdXJzIH0gZnJvbSAnLi9yZXBvcnRpbmcvZG9yYS1zY29yaW5nLmpzJztcbmltcG9ydCB7XG4gIGdldERvcmFNZXRyaWNzIGFzIGRvcmFNZXRyaWNzLFxuICBnZXREb3JhVHJlbmQgYXMgZG9yYVRyZW5kLFxuICBnZXRCdWlsZEhlYWx0aCBhcyBidWlsZEhlYWx0aCxcbn0gZnJvbSAnLi9yZXBvcnRpbmcvZG9yYS5qcyc7XG5pbXBvcnQge1xuICBnZXRQbHVnaW5SdW50aW1lIGFzIHBsdWdpblJ1bnRpbWUsXG4gIGdldFBsdWdpblJ1bnRpbWVBZ2dyZWdhdGUgYXMgcGx1Z2luUnVudGltZUFnZ3JlZ2F0ZSxcbiAgaGFzVmVyaWZpZWRQbHVnaW5Vc2UgYXMgdmVyaWZpZWRQbHVnaW5Vc2UsXG59IGZyb20gJy4vcmVwb3J0aW5nL3BsdWdpbi1ydW50aW1lLmpzJztcbmltcG9ydCB7IHJlcG9ydCB9IGZyb20gJy4vcmVwb3J0aW5nL3F1ZXJ5LXNjb3BlLmpzJztcbi8vIEFsaWFzZWQ6IHRoZSBtb2R1bGUgZnVuY3Rpb25zIGFuZCB0aGUgZGVsZWdhdGluZyBtZXRob2RzIGJlbG93IHNoYXJlIG5hbWVzLlxuaW1wb3J0IHtcbiAgUkVQT1JUSU5HX0VWRU5UX1JFVEVOVElPTl9EQVlTLCBSRVBPUlRJTkdfRE9SQV9SRVRFTlRJT05fREFZUyxcbiAgcmVzb2x2ZUV2ZW50UmV0ZW50aW9uRGF5cywgcmVzb2x2ZURvcmFSZXRlbnRpb25EYXlzLCByZXRlbnRpb25DdXRvZmYsXG59IGZyb20gJy4vcmVwb3J0aW5nL3JldGVudGlvbi5qcyc7XG5pbXBvcnQgeyBhc3NlcnRSZXBvcnRJbnRlcnZhbCwgc2NydWJPcHRpb25hbCwgb3B0aW9uYWxTdGFydGVkQXRSYW5nZSwgc3RhcnRlZEF0V2luZG93IH0gZnJvbSAnLi9yZXBvcnRpbmcvc3FsLWhlbHBlcnMuanMnO1xuaW1wb3J0IHR5cGUge1xuICBFeGVjdXRpb25Db3VudCwgVGltZVNlcmllc0VudHJ5LCBEdXJhdGlvblN0YXRzLCBQaXBlbGluZUV4ZWN1dGlvbiwgU3RhZ2VGYWlsdXJlLCBTdGFnZUJvdHRsZW5lY2ssXG4gIEFjdGlvbkZhaWx1cmUsIEVycm9yRW50cnksIFBsdWdpblN1bW1hcnksIFR5cGVDb21wdXRlRGlzdHJpYnV0aW9uLCBWZXJzaW9uQ291bnQsXG4gIEJ1aWxkVGltZVNlcmllc0VudHJ5LCBCdWlsZER1cmF0aW9uLCBCdWlsZEZhaWx1cmUsXG4gIFBsdWdpblJ1bnRpbWVBZ2dyZWdhdGUsIFBsdWdpblJ1bnRpbWVGaWx0ZXIsIFBsdWdpblJ1bnRpbWVTdGF0cyxcbiAgUmVwb3J0aW5nUmV0ZW50aW9uT3B0aW9ucywgUmVwb3J0aW5nUmV0ZW50aW9uQ291bnRzLFxuICBEb3JhT3B0aW9ucywgUmVwb3J0aW5nU2V0dGluZ3MsIFJlcG9ydGluZ1NldHRpbmdzUGF0Y2gsIEluY2lkZW50TGlzdEl0ZW0sIEluY2lkZW50VGVzdFJlc3VsdCxcbiAgRG9yYU1ldHJpY3MsIERvcmFUcmVuZFBvaW50LCBCdWlsZEhlYWx0aCwgSW5jaWRlbnRJbnB1dCxcbiAgSW5nZXN0RXZlbnQsIEluZ2VzdE1ldHJpYywgSW5nZXN0UmVzdWx0LCBJbmdlc3RIZWFsdGhTdGF0dXMsXG59IGZyb20gJy4vcmVwb3J0aW5nL3R5cGVzLmpzJztcblxuLy8gVGhlIHJlcG9ydGluZyB0eXBlcyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBwYWNrYWdlIEFQSS4gRW51bWVyYXRlZCByYXRoZXIgdGhhblxuLy8gYGV4cG9ydCAqYCBiZWNhdXNlIHRoZSByZXBvcnRpbmcgbW9kdWxlcyBhbHNvIGV4cG9ydCBpbnRlcm5hbHMgKG9yZ1Njb3BlLFxuLy8gcnVuUmVwb3J0LCB0aGUgY2FjaGVzLCB0aGUgRE9SQSByb3cgc2hhcGVzKSB0aGF0IG11c3Qgc3RheSBwcml2YXRlLlxuZXhwb3J0IHR5cGUge1xuICBCdWlsZEhlYWx0aCwgQnVpbGRIZWFsdGhTdGFnZSwgRG9yYUVudk1ldHJpY3MsIERvcmFMZXZlbCwgRG9yYU1ldHJpY3MsIERvcmFPcHRpb25zLCBEb3JhVHJlbmRQb2ludCxcbiAgSW5jaWRlbnRJbnB1dCwgSW5jaWRlbnRMaXN0SXRlbSwgUmVwb3J0aW5nU2V0dGluZ3MsIEluY2lkZW50VGVzdFJlc3VsdCxcbiAgSW5nZXN0RXZlbnQsIEluZ2VzdEhlYWx0aFN0YXR1cywgSW5nZXN0TWV0cmljLCBJbmdlc3RSZXN1bHQsXG4gIFBsdWdpblJ1bnRpbWVBZ2dyZWdhdGUsIFBsdWdpblJ1bnRpbWVGaWx0ZXIsIFBsdWdpblJ1bnRpbWVTdGF0cyxcbiAgUmVwb3J0aW5nUmV0ZW50aW9uQ291bnRzLCBSZXBvcnRpbmdSZXRlbnRpb25PcHRpb25zLCBSZXBvcnRpbmdSZXRlbnRpb25TZXR0aW5ncyxcbiAgUmVwb3J0aW5nU2V0dGluZ3NQYXRjaCxcbn0gZnJvbSAnLi9yZXBvcnRpbmcvdHlwZXMuanMnO1xuXG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigncmVwb3J0aW5nLXNlcnZpY2UnKTtcblxudHlwZSBQaXBlbGluZUV2ZW50SW5zZXJ0ID0gdHlwZW9mIHNjaGVtYS5waXBlbGluZUV2ZW50LiRpbmZlckluc2VydDtcblxuLyoqIFRoZSBwbHVnaW4gYSBwaXBlbGluZSBzdGVwIHJ1bnMsIGZyb20gdGhlIHN0ZXAgbWFuaWZlc3QgaXRzIGxhc3QgZGVwbG95IHJlZ2lzdGVyZWQuICovXG5pbnRlcmZhY2UgU3RlcFBsdWdpbiB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIHBsdWdpblB1Ymxpc2hlcjogc3RyaW5nIHwgbnVsbDtcbiAgcGx1Z2luUHVibGlzaGVySWQ6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpbk5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpblZlcnNpb246IHN0cmluZyB8IG51bGw7XG59XG5cbi8qKiBBbiBhY3Rpb24vYnVpbGQgZXZlbnQgdGhhdCBjYW4gYmUgYXR0cmlidXRlZCB0byBhIHBsdWdpbiBzdGVwLiAqL1xuZnVuY3Rpb24gaXNBdHRyaWJ1dGFibGUoZTogSW5nZXN0RXZlbnQpOiBib29sZWFuIHtcbiAgcmV0dXJuIChlLmV2ZW50VHlwZSA9PT0gJ0FDVElPTicgfHwgZS5ldmVudFR5cGUgPT09ICdCVUlMRCcpXG4gICAgJiYgKGUuZXZlbnRTb3VyY2UgPT09ICdjb2RlcGlwZWxpbmUnIHx8IGUuZXZlbnRTb3VyY2UgPT09ICdjb2RlYnVpbGQnKVxuICAgICYmICEhZS5zdGFnZU5hbWUgJiYgISFlLmFjdGlvbk5hbWU7XG59XG5cbmZ1bmN0aW9uIHN0ZXBLZXkocGlwZWxpbmVJZDogc3RyaW5nLCBzdGFnZU5hbWU6IHN0cmluZywgYWN0aW9uTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke3BpcGVsaW5lSWR9XFx1MDAwMCR7c3RhZ2VOYW1lfVxcdTAwMDAke2FjdGlvbk5hbWV9YDtcbn1cblxuLyoqXG4gKiBQbHVnaW4gYXR0cmlidXRpb246IHRoZSBzdGVwIG1hbmlmZXN0cyBvZiBldmVyeSBwaXBlbGluZSB3aXRoIGFuIGF0dHJpYnV0YWJsZVxuICogZXZlbnQsIGluIE9ORSByZWFkIHBlciBiYXRjaCwga2V5ZWQgZm9yIGFuIGluLW1lbW9yeSBqb2luLiBOYW1lcyBhcmUgY29tcGFyZWRcbiAqIHBvc3Qtc2NydWIgb24gYm90aCBzaWRlcyAodGhlIG1hbmlmZXN0IHN0b3JlcyB0aGVtIHNjcnViYmVkIHRoZSBzYW1lIHdheSkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGxvYWRTdGVwUGx1Z2lucyh0eDogQ3J1ZFR4LCBhdHRyaWJ1dGFibGU6IEluZ2VzdEV2ZW50W10pOiBQcm9taXNlPE1hcDxzdHJpbmcsIFN0ZXBQbHVnaW4+PiB7XG4gIGNvbnN0IHBpcGVsaW5lSWRzID0gWy4uLm5ldyBTZXQoYXR0cmlidXRhYmxlLm1hcCgoZSkgPT4gZS5waXBlbGluZUlkKSldO1xuICBpZiAocGlwZWxpbmVJZHMubGVuZ3RoID09PSAwKSByZXR1cm4gbmV3IE1hcCgpO1xuICBjb25zdCByb3dzID0gYXdhaXQgdHhcbiAgICAuc2VsZWN0KHtcbiAgICAgIHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5waXBlbGluZUlkLFxuICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5vcmdJZCxcbiAgICAgIHN0YWdlTmFtZTogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnN0YWdlTmFtZSxcbiAgICAgIGFjdGlvbk5hbWU6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5hY3Rpb25OYW1lLFxuICAgICAgcGx1Z2luUHVibGlzaGVyOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luUHVibGlzaGVyLFxuICAgICAgcGx1Z2luUHVibGlzaGVySWQ6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5wbHVnaW5QdWJsaXNoZXJJZCxcbiAgICAgIHBsdWdpbk5hbWU6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5wbHVnaW5OYW1lLFxuICAgICAgcGx1Z2luVmVyc2lvbjogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBsdWdpblZlcnNpb24sXG4gICAgfSlcbiAgICAuZnJvbShzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QpXG4gICAgLndoZXJlKGluQXJyYXkoc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBpcGVsaW5lSWQsIHBpcGVsaW5lSWRzKSk7XG4gIHJldHVybiBuZXcgTWFwKHJvd3MubWFwKChtKSA9PiBbc3RlcEtleShtLnBpcGVsaW5lSWQsIG0uc3RhZ2VOYW1lLCBtLmFjdGlvbk5hbWUpLCBtXSkpO1xufVxuXG4vKipcbiAqIFRoZSBwZXJzaXN0ZWQgcm93IGZvciBvbmUgaW5nZXN0ZWQgZXZlbnQuIFRoaXMgaXMgdGhlIERVUkFCTEUgcGVyc2lzdGVuY2VcbiAqIGJvdW5kYXJ5OiBldmVyeSB1c2VyL0FXUy1kZXJpdmVkIGZyZWUtZm9ybSBzdHJpbmcgaXMgc2NydWJiZWQgaGVyZSwgYW5kXG4gKiB0ZW5hbmN5IGNvbWVzIGZyb20gdGhlIHBpcGVsaW5lIHJlZ2lzdHJ5LCBuZXZlciB0aGUgY2FsbGVyJ3MgY2xhaW1lZCBvcmcuXG4gKi9cbmZ1bmN0aW9uIHRvRXZlbnRSb3coZXZlbnQ6IEluZ2VzdEV2ZW50LCByZWdpc3RyeTogeyBwaXBlbGluZUlkOiBzdHJpbmc7IG9yZ0lkOiBzdHJpbmcgfSwgcGx1Z2luOiBTdGVwUGx1Z2luIHwgdW5kZWZpbmVkKTogUGlwZWxpbmVFdmVudEluc2VydCB7XG4gIHJldHVybiB7XG4gICAgLy8gcmVnaXN0cnkucGlwZWxpbmVJZCA9PT0gZXZlbnQucGlwZWxpbmVJZDsgdGhlIHJlZ2lzdHJ5J3MgaXMgYWx3YXlzIGEgcm93XG4gICAgLy8gdGhhdCBleGlzdHMgKEZLKSBhbmQgaXRzIG9yZ0lkIGlzIHRoZSB0cnVzdGVkIHRlbmFudC5cbiAgICBwaXBlbGluZUlkOiByZWdpc3RyeS5waXBlbGluZUlkLFxuICAgIG9yZ0lkOiByZWdpc3RyeS5vcmdJZCxcbiAgICBldmVudFNvdXJjZTogZXZlbnQuZXZlbnRTb3VyY2UsXG4gICAgZXZlbnRUeXBlOiBldmVudC5ldmVudFR5cGUsXG4gICAgc3RhdHVzOiBldmVudC5zdGF0dXMsXG4gICAgLy8gQW4gQVdTLUFTU0lHTkVEIFVVSUQsIG5vdCBmcmVlLWZvcm0gdGV4dDogaXQgY2FuJ3QgY2FycnkgYW4gYWNjb3VudCBpZCxcbiAgICAvLyBhbmQgc2NydWJiaW5nIGEgMTItZGlnaXQgcnVuIGluc2lkZSBpdCB3b3VsZCBjb3JydXB0IHRoZSBjb3JyZWxhdGlvbiBrZXkuXG4gICAgZXhlY3V0aW9uSWQ6IGV2ZW50LmV4ZWN1dGlvbklkLFxuICAgIC8vIFVTRVItQVVUSE9SRUQgcGlwZWxpbmUtc3RydWN0dXJlIG5hbWVzIOKAlCBzYW1lIHVudHJ1c3RlZCBvcmlnaW4gYXNcbiAgICAvLyBlcnJvck1lc3NhZ2UsIHNvIHNjcnViYmVkIChhIHN0YWdlIG5hbWVkIHdpdGggYW4gQVJOIG11c3Qgbm90IHBlcnNpc3QpLlxuICAgIHN0YWdlTmFtZTogc2NydWJPcHRpb25hbChldmVudC5zdGFnZU5hbWUpLFxuICAgIGFjdGlvbk5hbWU6IHNjcnViT3B0aW9uYWwoZXZlbnQuYWN0aW9uTmFtZSksXG4gICAgLy8gSEFSRCBDT05TVFJBSU5UOiBhbiBBV1MgYWNjb3VudCBpZCBtdXN0IE5FVkVSIGJlIHBlcnNpc3RlZC4gRmFpbHVyZSBkZXRhaWxcbiAgICAvLyBhbmQgbWVzc2FnZXMgcm91dGluZWx5IGNhcnJ5IEFSTnMgYW5kIGJhcmUgMTItZGlnaXQgYWNjb3VudCBpZHMuXG4gICAgZXJyb3JNZXNzYWdlOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmVycm9yTWVzc2FnZSksXG4gICAgc3RhcnRlZEF0OiBldmVudC5zdGFydGVkQXQgPyBuZXcgRGF0ZShldmVudC5zdGFydGVkQXQpIDogdW5kZWZpbmVkLFxuICAgIGNvbXBsZXRlZEF0OiBldmVudC5jb21wbGV0ZWRBdCA/IG5ldyBEYXRlKGV2ZW50LmNvbXBsZXRlZEF0KSA6IHVuZGVmaW5lZCxcbiAgICBkdXJhdGlvbk1zOiBldmVudC5kdXJhdGlvbk1zLFxuICAgIC8vIERlcGxveSBhdHRyaWJ1dGlvbiDigJQgc2NydWJiZWQgbGlrZSB0aGUgb3RoZXIgZnJlZS1mb3JtIHN0cmluZ3MuXG4gICAgY29tbWl0U2hhOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmNvbW1pdFNoYSksXG4gICAgY29tbWl0UmVmOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmNvbW1pdFJlZiksXG4gICAgZW52aXJvbm1lbnQ6IHNjcnViT3B0aW9uYWwoZXZlbnQuZW52aXJvbm1lbnQpLFxuICAgIC8vIE1lYXN1cmVkIGxlYWQgdGltZTogdGhlIG9sZGVzdCB1bnNoaXBwZWQgY29tbWl0J3MgdGltZSArIHRoZSBjb3VudC4gQW5cbiAgICAvLyBTQ00tZGVyaXZlZCBpbnN0YW50IGFuZCBhIHBsYWluIGludGVnZXIg4oCUIG5vdGhpbmcgdG8gc2NydWIuXG4gICAgY29tbWl0VGltZXN0YW1wOiBldmVudC5jb21taXRUaW1lc3RhbXAgPyBuZXcgRGF0ZShldmVudC5jb21taXRUaW1lc3RhbXApIDogdW5kZWZpbmVkLFxuICAgIGNvbW1pdENvdW50OiBldmVudC5jb21taXRDb3VudCxcbiAgICAvLyBOVUxMIGZvciBub24tcGx1Z2luIGFjdGlvbnMgYW5kIGZvciBwaXBlbGluZXMgZGVwbG95ZWQgd2l0aG91dCBhIG1hbmlmZXN0LlxuICAgIHBsdWdpblB1Ymxpc2hlcjogcGx1Z2luPy5wbHVnaW5QdWJsaXNoZXIgPz8gbnVsbCxcbiAgICBwbHVnaW5QdWJsaXNoZXJJZDogcGx1Z2luPy5wbHVnaW5QdWJsaXNoZXJJZCA/PyBudWxsLFxuICAgIHBsdWdpbk5hbWU6IHBsdWdpbj8ucGx1Z2luTmFtZSA/PyBudWxsLFxuICAgIHBsdWdpblZlcnNpb246IHBsdWdpbj8ucGx1Z2luVmVyc2lvbiA/PyBudWxsLFxuICAgIGRldGFpbDogZXZlbnQuZGV0YWlsICE9PSB1bmRlZmluZWQgPyBzY3J1YkF3c0lkZW50aWZpZXJzKGV2ZW50LmRldGFpbCkgOiB1bmRlZmluZWQsXG4gIH07XG59XG5cbi8qKlxuICogRmFuIHRlcm1pbmFsIFNUQUdFIG91dGNvbWVzIGludG8gdGhlIHJvdXRlJ3MgbWV0cmljIGhvb2sgKHBpcGVsaW5lLWRhdGEgY2FuJ3RcbiAqIGltcG9ydCBhcGktc2VydmVyJ3MgcmVnaXN0cnkpIGFmdGVyIHRoZSBpbnNlcnQgY29tbWl0cy4gRHJpdmVuIG9mZiB0aGVcbiAqIElOU0VSVEVEIHJvd3MsIHNvIGEgcmUtZGVsaXZlcmVkIGV2ZW50IHRoZSBkZWR1cCBpbmRleCBzd2FsbG93ZWQgaXMgbmV2ZXJcbiAqIGNvdW50ZWQgdHdpY2UuIEEgbm9uLW51bGwgZW52aXJvbm1lbnQgbWFya3MgYSBkZXBsb3kuXG4gKi9cbmZ1bmN0aW9uIGVtaXRTdGFnZU1ldHJpY3MoXG4gIHJvd3M6IFJlYWRvbmx5QXJyYXk8eyBvcmdJZDogc3RyaW5nOyBwaXBlbGluZUlkOiBzdHJpbmcgfCBudWxsOyBldmVudFR5cGU6IHN0cmluZzsgc3RhdHVzOiBzdHJpbmc7IHN0YWdlTmFtZTogc3RyaW5nIHwgbnVsbDsgZW52aXJvbm1lbnQ6IHN0cmluZyB8IG51bGwgfT4sXG4gIG9uTWV0cmljOiAobTogSW5nZXN0TWV0cmljKSA9PiB2b2lkLFxuKTogdm9pZCB7XG4gIGZvciAoY29uc3QgciBvZiByb3dzKSB7XG4gICAgaWYgKHIuZXZlbnRUeXBlICE9PSAnU1RBR0UnIHx8IChyLnN0YXR1cyAhPT0gJ1NVQ0NFRURFRCcgJiYgci5zdGF0dXMgIT09ICdGQUlMRUQnKSB8fCAhci5waXBlbGluZUlkKSBjb250aW51ZTtcbiAgICBvbk1ldHJpYyh7XG4gICAgICBwaXBlbGluZUlkOiByLnBpcGVsaW5lSWQsXG4gICAgICBvcmdJZDogci5vcmdJZCxcbiAgICAgIHN0YWdlOiByLnN0YWdlTmFtZSA/PyAnJyxcbiAgICAgIGVudmlyb25tZW50OiByLmVudmlyb25tZW50ID8/IG51bGwsXG4gICAgICByZXN1bHQ6IHIuc3RhdHVzID09PSAnU1VDQ0VFREVEJyA/ICdzdWNjZWVkZWQnIDogJ2ZhaWxlZCcsXG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFJlcG9ydGluZ1NlcnZpY2Uge1xuXG4gIC8qKiBJbnZhbGlkYXRlIGFsbCBjYWNoZWQgcmVwb3J0cyBmb3IgYW4gb3JnIChjYWxsIGFmdGVyIGV2ZW50IGluZ2VzdCkuICovXG4gIGFzeW5jIGludmFsaWRhdGVPcmcob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIGludmVudG9yeUNhY2hlLmludmFsaWRhdGVQYXR0ZXJuKGAke29yZ0lkfToqYCksXG4gICAgICB0aW1lc2VyaWVzQ2FjaGUuaW52YWxpZGF0ZVBhdHRlcm4oYCR7b3JnSWR9OipgKSxcbiAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIGluY29taW5nIGV2ZW50cyBhZ2FpbnN0IHRoZSBwaXBlbGluZSByZWdpc3RyeSwgYmF0Y2gtaW5zZXJ0IHRoZVxuICAgKiBtYXRjaGVkIG9uZXMsIGFuZCBpbnZhbGlkYXRlIHJlcG9ydGluZyBjYWNoZXMgZm9yIGFmZmVjdGVkIG9yZ3MuXG4gICAqIEV2ZW50cyBmb3IgdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkcyBhcmUgZHJvcHBlZCAoYW5kIGxvZ2dlZCBhdCBXQVJOXG4gICAqIHdpdGggc2FtcGxlIGlkcyBzbyBhbiBvcGVyYXRvciBjYW4gc2VlIHdoZW4gRXZlbnRCcmlkZ2UgaXMgZGVsaXZlcmluZ1xuICAgKiBldmVudHMgZm9yIHBpcGVsaW5lcyB0aGF0IGhhdmVuJ3QgY2FsbGVkIFBPU1QgL3BpcGVsaW5lcy9yZWdpc3RyeSB5ZXQpLlxuICAgKlxuICAgKiBSZXR1cm5zIGNvdW50cyArIGEgc2FtcGxlIG9mIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZHMgZm9yIG9ic2VydmFiaWxpdHkuXG4gICAqL1xuICBhc3luYyBpbmdlc3RFdmVudHMoZXZlbnRzOiBJbmdlc3RFdmVudFtdLCBvbk1ldHJpYz86IChtOiBJbmdlc3RNZXRyaWMpID0+IHZvaWQpOiBQcm9taXNlPEluZ2VzdFJlc3VsdD4ge1xuICAgIC8vIE11bHRpLW9yZyBiYXRjaCBpbnNlcnQ6IHRoZSBjYWxsZXIgcmVzb2x2ZXMgdG8gbXVsdGlwbGUgb3JncyB2aWEgdGhlXG4gICAgLy8gcGlwZWxpbmUtcmVnaXN0cnkgbG9va3VwIGJlbG93LCBzbyB0aGUgcm91dGUgbGF5ZXIgTVVTVCBlc3RhYmxpc2ggYVxuICAgIC8vIGBydW5XaXRoVGVuYW50Q29udGV4dCh7IGlzU3VwZXJBZG1pbjogdHJ1ZSB9LCAuLi4pYCBzY29wZSBiZWZvcmUgY2FsbGluZ1xuICAgIC8vIHRoaXMgbWV0aG9kLiBVbmRlciBGT1JDRSdkIFJMUywgYSBzaW5nbGUgdHggd2l0aCBgYXBwLm9yZ19pZCA9IDxvbmVcbiAgICAvLyBvcmc+YCBjb3VsZCBvbmx5IHdyaXRlIGV2ZW50cyBmb3IgdGhhdCBvcmc7IGJ5cGFzcyB2aWEgc3lzYWRtaW4gaXNcbiAgICAvLyB0aGUgcmlnaHQgZ2F0ZSBmb3IgdGhpcyBzZXJ2ZXItaW50ZXJuYWwgY3Jvc3MtdGVuYW50IGVuZHBvaW50LiBTZWVcbiAgICAvLyBhcGkvcmVwb3J0aW5nL3NyYy9yb3V0ZXMvZXZlbnQtaW5nZXN0LnRzIGZvciB0aGUgd3JhcHBlci5cbiAgICAvLyBDYWNoZXMgYXJlIGludmFsaWRhdGVkIEFGVEVSIHRoZSB0eCByZXNvbHZlczogZG9pbmcgaXQgaW5zaWRlIGhlbGQgdGhlIHBnXG4gICAgLy8gbG9ja3Mgb3BlbiBhY3Jvc3MgdW5yZWxhdGVkIGNhY2hlIHJvdW5kLXRyaXBzLiBUaGUgVFRMIGlzIDItNSBtaW4sIHNvIGFcbiAgICAvLyBmaXJlLWFuZC1mb3JnZXQgcG9zdC1jb21taXQgaW52YWxpZGF0aW9uIGlzIGFuIGFjY2VwdGFibGUgdHJhZGUuXG4gICAgY29uc3QgeyBpbnNlcnRlZCwgc2tpcHBlZCwgdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMsIGFmZmVjdGVkT3JncywgaW5zZXJ0ZWRSb3dzIH0gPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB7XG4gICAgICAvLyBCYXRjaC1yZXNvbHZlIGFsbCB1bmlxdWUgcGlwZWxpbmUgaWRzIGluIG9uZSBxdWVyeVxuICAgICAgY29uc3QgdW5pcXVlSWRzID0gWy4uLm5ldyBTZXQoZXZlbnRzLm1hcChlID0+IGUucGlwZWxpbmVJZCkpXTtcbiAgICAgIGNvbnN0IHJlZ2lzdHJ5Um93cyA9IGF3YWl0IHR4XG4gICAgICAgIC5zZWxlY3Qoe1xuICAgICAgICAgIHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5LnBpcGVsaW5lSWQsXG4gICAgICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5Lm9yZ0lkLFxuICAgICAgICB9KVxuICAgICAgICAuZnJvbShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeSlcbiAgICAgICAgLndoZXJlKGluQXJyYXkoc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkucGlwZWxpbmVJZCwgdW5pcXVlSWRzKSk7XG5cbiAgICAgIGNvbnN0IGlkTWFwID0gbmV3IE1hcChyZWdpc3RyeVJvd3MubWFwKHIgPT4gW3IucGlwZWxpbmVJZCwgcl0pKTtcbiAgICAgIGNvbnN0IHN0ZXBQbHVnaW5zID0gYXdhaXQgbG9hZFN0ZXBQbHVnaW5zKHR4LCBldmVudHMuZmlsdGVyKChlKSA9PiBpc0F0dHJpYnV0YWJsZShlKSAmJiBpZE1hcC5oYXMoZS5waXBlbGluZUlkKSkpO1xuXG4gICAgICAvLyBCdWlsZCBpbnNlcnQgYmF0Y2ggKHNraXAgZXZlbnRzIHdob3NlIHBpcGVsaW5lIGlzbid0IHJlZ2lzdGVyZWQpXG4gICAgICBjb25zdCByb3dzOiBQaXBlbGluZUV2ZW50SW5zZXJ0W10gPSBbXTtcbiAgICAgIGxldCBza2lwcGVkTG9jYWwgPSAwO1xuICAgICAgY29uc3QgdW5yZWdpc3RlcmVkTG9jYWw6IHN0cmluZ1tdID0gW107XG5cbiAgICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICAgIGNvbnN0IHJlZ2lzdHJ5ID0gaWRNYXAuZ2V0KGV2ZW50LnBpcGVsaW5lSWQpO1xuICAgICAgICBpZiAoIXJlZ2lzdHJ5KSB7XG4gICAgICAgICAgc2tpcHBlZExvY2FsKys7XG4gICAgICAgICAgdW5yZWdpc3RlcmVkTG9jYWwucHVzaChldmVudC5waXBlbGluZUlkKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdGFnZU5hbWUgPSBzY3J1Yk9wdGlvbmFsKGV2ZW50LnN0YWdlTmFtZSk7XG4gICAgICAgIGNvbnN0IGFjdGlvbk5hbWUgPSBzY3J1Yk9wdGlvbmFsKGV2ZW50LmFjdGlvbk5hbWUpO1xuICAgICAgICBjb25zdCBzdGVwID0gaXNBdHRyaWJ1dGFibGUoZXZlbnQpICYmIHN0YWdlTmFtZSAmJiBhY3Rpb25OYW1lXG4gICAgICAgICAgPyBzdGVwUGx1Z2lucy5nZXQoc3RlcEtleShyZWdpc3RyeS5waXBlbGluZUlkLCBzdGFnZU5hbWUsIGFjdGlvbk5hbWUpKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICAvLyBTYW1lLW9yZyBndWFyZDogYSBtYW5pZmVzdCByb3cgaXMgb25seSBldmVyIHdyaXR0ZW4gYnkgdGhlIG9yZyB0aGF0XG4gICAgICAgIC8vIG93bnMgdGhlIHBpcGVsaW5lLCBidXQgdGhlIGluZ2VzdCBydW5zIGNyb3NzLXRlbmFudCwgc28gZG9uJ3QgbGVhbiBvbiBpdC5cbiAgICAgICAgcm93cy5wdXNoKHRvRXZlbnRSb3coZXZlbnQsIHJlZ2lzdHJ5LCBzdGVwICYmIHN0ZXAub3JnSWQgPT09IHJlZ2lzdHJ5Lm9yZ0lkID8gc3RlcCA6IHVuZGVmaW5lZCkpO1xuICAgICAgfVxuXG4gICAgICAvLyBTUVMgaXMgYXQtbGVhc3Qtb25jZSwgc28gRXZlbnRCcmlkZ2UgY2FuIGRlbGl2ZXIgdGhlIHNhbWUgc3RhdGUtY2hhbmdlXG4gICAgICAvLyB0d2ljZS4gYG9uQ29uZmxpY3REb05vdGhpbmdgICsgdGhlIHBhcnRpYWwgdW5pcXVlIGluZGV4IG9uXG4gICAgICAvLyAocGlwZWxpbmVfaWQsIGV4ZWN1dGlvbl9pZCwgZXZlbnRfdHlwZSwgc3RhdHVzLCBzdGFnZV9uYW1lLCBhY3Rpb25fbmFtZSlcbiAgICAgIC8vIG1ha2VzIHJlLWRlbGl2ZXJ5IGlkZW1wb3RlbnQuIGByZXR1cm5pbmdgIGdpdmVzIHRoZSBSRUFMIGluc2VydGVkIHNldCBzb1xuICAgICAgLy8gY291bnRzLCBtZXRyaWNzIGFuZCBjYWNoZSBpbnZhbGlkYXRpb24gYWxsIGlnbm9yZSBkdXBsaWNhdGVzLlxuICAgICAgY29uc3QgbGFuZGVkID0gcm93cy5sZW5ndGggPiAwXG4gICAgICAgID8gYXdhaXQgdHguaW5zZXJ0KHNjaGVtYS5waXBlbGluZUV2ZW50KS52YWx1ZXMocm93cylcbiAgICAgICAgICAub25Db25mbGljdERvTm90aGluZygpXG4gICAgICAgICAgLnJldHVybmluZyh7XG4gICAgICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lRXZlbnQub3JnSWQsXG4gICAgICAgICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVFdmVudC5waXBlbGluZUlkLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBzY2hlbWEucGlwZWxpbmVFdmVudC5ldmVudFR5cGUsXG4gICAgICAgICAgICBzdGF0dXM6IHNjaGVtYS5waXBlbGluZUV2ZW50LnN0YXR1cyxcbiAgICAgICAgICAgIHN0YWdlTmFtZTogc2NoZW1hLnBpcGVsaW5lRXZlbnQuc3RhZ2VOYW1lLFxuICAgICAgICAgICAgZW52aXJvbm1lbnQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmVudmlyb25tZW50LFxuICAgICAgICAgIH0pXG4gICAgICAgIDogW107XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGluc2VydGVkOiBsYW5kZWQubGVuZ3RoLFxuICAgICAgICBza2lwcGVkOiBza2lwcGVkTG9jYWwsXG4gICAgICAgIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzOiB1bnJlZ2lzdGVyZWRMb2NhbCxcbiAgICAgICAgYWZmZWN0ZWRPcmdzOiBbLi4ubmV3IFNldChsYW5kZWQubWFwKHIgPT4gci5vcmdJZCkpXSxcbiAgICAgICAgaW5zZXJ0ZWRSb3dzOiBsYW5kZWQsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgaWYgKG9uTWV0cmljKSBlbWl0U3RhZ2VNZXRyaWNzKGluc2VydGVkUm93cywgb25NZXRyaWMpO1xuXG4gICAgLy8gU3VyZmFjZSB0aGUgc2lsZW50IHNraXA6IGFuIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZCB1c3VhbGx5IG1lYW5zIHRoZVxuICAgIC8vIHBpcGVsaW5lIGhhc24ndCBjYWxsZWQgUE9TVCAvcGlwZWxpbmVzL3JlZ2lzdHJ5IHlldCAob3IgaXRzXG4gICAgLy8gcGIucGlwZWxpbmUtaWQgdGFnIGlzIG1pc3NpbmcvdW5yZWFkYWJsZSBieSB0aGUgTGFtYmRhKS4gTG9nZ2luZyBpdFxuICAgIC8vIG1ha2VzIGEgYnJva2VuIGpvaW4gdmlzaWJsZSBpbnN0ZWFkIG9mIGxvb2tpbmcgbGlrZSBcIm5vIGFjdGl2aXR5XCIuXG4gICAgaWYgKHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGxvZ2dlci53YXJuKCdQaXBlbGluZSBldmVudHMgc2tpcHBlZDogcGlwZWxpbmUgaWQgbm90IGZvdW5kIGluIHJlZ2lzdHJ5Jywge1xuICAgICAgICBjb3VudDogdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMubGVuZ3RoLFxuICAgICAgICBzYW1wbGU6IHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLnNsaWNlKDAsIDMpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gUG9zdC1jb21taXQgY2FjaGUgaW52YWxpZGF0aW9uLiBGaXJlLWFuZC1mb3JnZXQgd2l0aCBsb2dnaW5nIOKAlCBUVEwgaXNcbiAgICAvLyBzaG9ydCBlbm91Z2ggdGhhdCBhIG1pc3NlZCBpbnZhbGlkYXRpb24gc2VsZi1oZWFscy5cbiAgICBpZiAoYWZmZWN0ZWRPcmdzLmxlbmd0aCA+IDApIHtcbiAgICAgIHZvaWQgUHJvbWlzZS5hbGwoYWZmZWN0ZWRPcmdzLm1hcCgob3JnKSA9PlxuICAgICAgICB0aGlzLmludmFsaWRhdGVPcmcob3JnKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyBjYWNoZSBpbnZhbGlkYXRpb24gZmFpbGVkJywgeyBvcmdJZDogb3JnLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgaW5zZXJ0ZWQsIHNraXBwZWQsIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLCBhZmZlY3RlZE9yZ3MgfTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBDYXRlZ29yeSAxOiBQaXBlbGluZSBFeGVjdXRpb24gJiBQZXJmb3JtYW5jZSDilIDilIBcblxuXG4gIC8qKiBFeGVjdXRpb24gY291bnQgcGVyIHBpcGVsaW5lIHdpdGggc3RhdHVzIGJyZWFrZG93bi4gKi9cbiAgYXN5bmMgZ2V0RXhlY3V0aW9uQ291bnQob3JnSWQ6IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10sIHJhbmdlPzogeyBmcm9tPzogc3RyaW5nOyB0bz86IHN0cmluZyB9KTogUHJvbWlzZTxFeGVjdXRpb25Db3VudFtdPiB7XG4gICAgLy8gT3B0aW9uYWwgW2Zyb20sdG9dIHdpbmRvdyBvbiB0aGUgZXhlY3V0aW9uJ3Mgc3RhcnRlZF9hdCwgbWlycm9yaW5nIHRoZVxuICAgIC8vIHNpYmxpbmcgdGltZXNlcmllcyByZXBvcnRzIHNvIHRoZSBkYXNoYm9hcmQgZGF0ZS1yYW5nZSBwaWNrZXIgbmFycm93cyB0aGVcbiAgICAvLyBjb3VudCB0b28gKGFuIGVtcHR5IHJhbmdlID0gYWxsLXRpbWUsIHByZXNlcnZpbmcgdGhlIHByaW9yIGJlaGF2aW9yKS4gVGhlXG4gICAgLy8gcmFuZ2UgcmlkZXMgdGhlIEpPSU4gc28gcGlwZWxpbmVzIHdpdGggbm8gaW4td2luZG93IGV2ZW50cyBzdGlsbCBsaXN0XG4gICAgLy8gKExFRlQgc2VtYW50aWNzIHByZXNlcnZlZCB2aWEgdGhlIGlubmVyLWpvaW4gZmlsdGVyIOKAlCBhIHBpcGVsaW5lIHdpdGggemVyb1xuICAgIC8vIG1hdGNoaW5nIGV2ZW50cyBkcm9wcyBmcm9tIHRoZSBjb3VudCwgc2FtZSBhcyBiZWZvcmUgZm9yIGl0cyB3aW5kb3cpLlxuICAgIGNvbnN0IHJhbmdlQ2xhdXNlID0gb3B0aW9uYWxTdGFydGVkQXRSYW5nZShyYW5nZSk7XG4gICAgcmV0dXJuIHJlcG9ydDxFeGVjdXRpb25Db3VudD4oYGV4ZWMtY291bnQ6JHtyYW5nZT8uZnJvbSA/PyAnJ306JHtyYW5nZT8udG8gPz8gJyd9YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5wcm9qZWN0LCBwLm9yZ2FuaXphdGlvbiwgcC5waXBlbGluZV9uYW1lLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnQ0FOQ0VMRUQnKTo6aW50IEFTIGNhbmNlbGVkLFxuICAgICAgICAgIE1JTihlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGZpcnN0X2V4ZWN1dGlvbixcbiAgICAgICAgICBNQVgoZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBsYXN0X2V4ZWN1dGlvblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lfSBwXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZSBPTiBlLnBpcGVsaW5lX2lkID0gcC5pZFxuICAgICAgICAgIEFORCBlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLnN0YXR1cyAhPSAnU1RBUlRFRCdcbiAgICAgICAgICAke3JhbmdlQ2xhdXNlfVxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBwLmlzX2FjdGl2ZSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgcC5pZFxuICAgICAgICBPUkRFUiBCWSB0b3RhbCBERVNDXG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXItcGlwZWxpbmUgZXhlY3V0aW9uIGhpc3Rvcnkg4oCUIERJU1RJTkNUIGV4ZWN1dGlvbnMgZm9yIG9uZSBwaXBlbGluZSxcbiAgICogbmV3ZXN0IGZpcnN0LiBHcm91cHMgYWxsIGV2ZW50cyBieSBgZXhlY3V0aW9uX2lkYCBpbiBhIHNpbmdsZSBzY2FuIGFuZFxuICAgKiByb2xscyBlYWNoIGV4ZWN1dGlvbiB1cCB0byBvbmUgcm93OlxuICAgKiAgIC0gc3RhdHVzOiBkZXJpdmVkIGZyb20gdGhlIFBJUEVMSU5FLXR5cGUgZXZlbnRzLiBGQUlMRUQgd2lucywgdGhlblxuICAgKiAgICAgU1VDQ0VFREVELCB0aGVuIENBTkNFTEVEOyBhbiBleGVjdXRpb24gd2l0aCBubyB0ZXJtaW5hbCBQSVBFTElORSBldmVudFxuICAgKiAgICAgaXMgc3RpbGwgYGluLXByb2dyZXNzYC5cbiAgICogICAtIHN0YXJ0ZWRBdC9lbmRlZEF0L2R1cmF0aW9uTXM6IGZyb20gdGhlIFBJUEVMSU5FIGxpZmVjeWNsZSBldmVudHMuXG4gICAqICAgLSBmYWlsaW5nU3RhZ2UvZmFpbGluZ0FjdGlvbjogdGhlIGZpcnN0IEZBSUxFRCBTVEFHRS9BQ1RJT04gZXZlbnQgKGNoZWFwIOKAlFxuICAgKiAgICAgc2FtZSBzY2FuLCBubyBleHRyYSBxdWVyeSkuXG4gICAqXG4gICAqIE9SRy1TQ09QSU5HOiBpZGVudGljYWwgdG8gdGhlIHNpYmxpbmcgZXhlY3V0aW9uIHJlcG9ydHMg4oCUIGpvaW5zIHRoZSBwaXBlbGluZVxuICAgKiByZWdpc3RyeSB0YWJsZSAoYHBpcGVsaW5lYCkgYW5kIGdhdGVzIG9uIGBwLm9yZ19pZCAke3ByZWR9YCwgd2hlcmUgYHByZWRgIGlzXG4gICAqIHRoZSBzaW5nbGUtb3JnIGA9ICRvcmdgIG9yICh3aXRoIGEgcm9sbHVwKSBhbiBgSU4gKC4uLilgIG92ZXIgdGhlIG9yZ+KGknRlYW1cbiAgICogc3VidHJlZS4gQSBwaXBlbGluZUlkIGJlbG9uZ2luZyB0byBhbm90aGVyIG9yZyB5aWVsZHMgemVybyByb3dzLlxuICAgKi9cbiAgYXN5bmMgbGlzdFBpcGVsaW5lRXhlY3V0aW9ucyhcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIHBpcGVsaW5lSWQ6IHN0cmluZyxcbiAgICBvcmdJZHM/OiBzdHJpbmdbXSxcbiAgICByYW5nZT86IHsgZnJvbT86IHN0cmluZzsgdG8/OiBzdHJpbmcgfSxcbiAgICBsaW1pdDogbnVtYmVyID0gNTAsXG4gICk6IFByb21pc2U8UGlwZWxpbmVFeGVjdXRpb25bXT4ge1xuICAgIGNvbnN0IHJhbmdlQ2xhdXNlID0gb3B0aW9uYWxTdGFydGVkQXRSYW5nZShyYW5nZSk7XG4gICAgcmV0dXJuIHJlcG9ydDxQaXBlbGluZUV4ZWN1dGlvbj4oYHBpcGVsaW5lLWV4ZWN1dGlvbnM6JHtwaXBlbGluZUlkfToke3JhbmdlPy5mcm9tID8/ICcnfToke3JhbmdlPy50byA/PyAnJ306JHtsaW1pdH1gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLmV4ZWN1dGlvbl9pZCxcbiAgICAgICAgICBDQVNFXG4gICAgICAgICAgICBXSEVOIGJvb2xfb3IoZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyBBTkQgZS5zdGF0dXMgPSAnRkFJTEVEJykgVEhFTiAnZmFpbGVkJ1xuICAgICAgICAgICAgV0hFTiBib29sX29yKGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScgQU5EIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCcpIFRIRU4gJ3N1Y2NlZWRlZCdcbiAgICAgICAgICAgIFdIRU4gYm9vbF9vcihlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLnN0YXR1cyA9ICdDQU5DRUxFRCcpIFRIRU4gJ2NhbmNlbGVkJ1xuICAgICAgICAgICAgRUxTRSAnaW4tcHJvZ3Jlc3MnXG4gICAgICAgICAgRU5EIEFTIHN0YXR1cyxcbiAgICAgICAgICBNSU4oZS5zdGFydGVkX2F0KSBGSUxURVIgKFdIRVJFIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScpOjp0ZXh0IEFTIHN0YXJ0ZWRfYXQsXG4gICAgICAgICAgTUFYKGUuY29tcGxldGVkX2F0KSBGSUxURVIgKFdIRVJFIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScpOjp0ZXh0IEFTIGVuZGVkX2F0LFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKSBGSUxURVIgKFdIRVJFIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScpOjppbnQgQVMgZHVyYXRpb25fbXMsXG4gICAgICAgICAgKEFSUkFZX0FHRyhlLnN0YWdlX25hbWUpIEZJTFRFUiAoV0hFUkUgZS5ldmVudF90eXBlID0gJ1NUQUdFJyBBTkQgZS5zdGF0dXMgPSAnRkFJTEVEJykpWzFdIEFTIGZhaWxpbmdfc3RhZ2UsXG4gICAgICAgICAgKEFSUkFZX0FHRyhlLmFjdGlvbl9uYW1lKSBGSUxURVIgKFdIRVJFIGUuZXZlbnRfdHlwZSA9ICdBQ1RJT04nIEFORCBlLnN0YXR1cyA9ICdGQUlMRUQnKSlbMV0gQVMgZmFpbGluZ19hY3Rpb25cbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5waXBlbGluZV9pZCA9ICR7cGlwZWxpbmVJZH0gQU5EIGUuZXhlY3V0aW9uX2lkIElTIE5PVCBOVUxMXG4gICAgICAgICAgJHtyYW5nZUNsYXVzZX1cbiAgICAgICAgR1JPVVAgQlkgZS5leGVjdXRpb25faWRcbiAgICAgICAgT1JERVIgQlkgTUFYKGUuY3JlYXRlZF9hdCkgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCk7XG4gIH1cblxuICAvKiogU3VjY2VzcyByYXRlIG92ZXIgdGltZSBmb3IgYW4gb3JnLiAqL1xuICBhc3luYyBnZXRTdWNjZXNzUmF0ZShvcmdJZDogc3RyaW5nLCBpbnRlcnZhbDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxUaW1lU2VyaWVzRW50cnlbXT4ge1xuICAgIGFzc2VydFJlcG9ydEludGVydmFsKGludGVydmFsKTtcbiAgICByZXR1cm4gcmVwb3J0PFRpbWVTZXJpZXNFbnRyeT4oYHN1Y2Nlc3MtcmF0ZToke2ludGVydmFsfToke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgREFURV9UUlVOQygke2ludGVydmFsfSwgZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBwZXJpb2QsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnQ0FOQ0VMRUQnKTo6aW50IEFTIGNhbmNlbGVkLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIHN1Y2Nlc3NfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORSdcbiAgICAgICAgICBBTkQgZS5zdGF0dXMgSU4gKCdTVUNDRUVERUQnLCAnRkFJTEVEJywgJ0NBTkNFTEVEJylcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBwZXJpb2QgT1JERVIgQlkgcGVyaW9kXG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKiBBdmVyYWdlIGR1cmF0aW9uIHBlciBwaXBlbGluZS4gKi9cbiAgYXN5bmMgZ2V0QXZlcmFnZUR1cmF0aW9uKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPER1cmF0aW9uU3RhdHNbXT4ge1xuICAgIHJldHVybiByZXBvcnQ8RHVyYXRpb25TdGF0cz4oYGF2Zy1kdXJhdGlvbjoke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5wcm9qZWN0LCBwLnBpcGVsaW5lX25hbWUsXG4gICAgICAgICAgQVZHKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgYXZnX21zLFxuICAgICAgICAgIE1JTihlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1pbl9tcyxcbiAgICAgICAgICBNQVgoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBtYXhfbXMsXG4gICAgICAgICAgUEVSQ0VOVElMRV9DT05UKDAuOTUpIFdJVEhJTiBHUk9VUCAoT1JERVIgQlkgZS5kdXJhdGlvbl9tcyk6OmludCBBUyBwOTVfbXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBleGVjdXRpb25zXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScgQU5EIGUuZHVyYXRpb25fbXMgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBwLmlkIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKiBTdGFnZSBmYWlsdXJlIGhlYXRtYXAg4oCUIHdoaWNoIHN0YWdlcyBmYWlsIG1vc3QuICovXG4gIGFzeW5jIGdldFN0YWdlRmFpbHVyZXMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8U3RhZ2VGYWlsdXJlW10+IHtcbiAgICByZXR1cm4gcmVwb3J0PFN0YWdlRmFpbHVyZT4oYHN0YWdlLWZhaWx1cmVzOiR7ZnJvbX06JHt0b31gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLnN0YWdlX25hbWUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWx1cmVzLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgZmFpbHVyZV9wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF90eXBlID0gJ1NUQUdFJyBBTkQgZS5zdGFnZV9uYW1lIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EICR7c3RhcnRlZEF0V2luZG93KGZyb20sIHRvKX1cbiAgICAgICAgR1JPVVAgQlkgZS5zdGFnZV9uYW1lIE9SREVSIEJZIGZhaWx1cmVzIERFU0NcbiAgICAgIGApO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3RpbmN0IGRlcGxveSBgZW52aXJvbm1lbnRgIHZhbHVlcyBvYnNlcnZlZCBpbiB0aGUgd2luZG93IOKAlCBwb3dlcnMgdGhlXG4gICAqIERPUkEgZW52aXJvbm1lbnQtc2NvcGUgZGF0YWxpc3QuIE9yZy1zY29wZWQgKyByb2xsdXAtYXdhcmUgbGlrZSB0aGUgc2libGluZ1xuICAgKiByZXBvcnRzOyBvbmx5IG5vbi1udWxsIGVudmlyb25tZW50cyAoaS5lLiBkZXBsb3ktYXR0cmlidXRlZCBleGVjdXRpb25zKS5cbiAgICovXG4gIGFzeW5jIGdldFJlcG9ydEVudmlyb25tZW50cyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCByZXBvcnQ8eyBlbnZpcm9ubWVudDogc3RyaW5nIH0+KGByZXBvcnQtZW52czoke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUIERJU1RJTkNUIGUuZW52aXJvbm1lbnQgQVMgZW52aXJvbm1lbnRcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5lbnZpcm9ubWVudCBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCAke3N0YXJ0ZWRBdFdpbmRvdyhmcm9tLCB0byl9XG4gICAgICAgIE9SREVSIEJZIGVudmlyb25tZW50XG4gICAgICBgKTtcbiAgICByZXR1cm4gcm93cy5tYXAoKHJvdykgPT4gcm93LmVudmlyb25tZW50KTtcbiAgfVxuXG4gIC8qKiBTdGFnZSBib3R0bGVuZWNrcyDigJQgc2xvd2VzdCBzdGFnZXMgcGVyIHBpcGVsaW5lLiAqL1xuICBhc3luYyBnZXRTdGFnZUJvdHRsZW5lY2tzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPFN0YWdlQm90dGxlbmVja1tdPiB7XG4gICAgcmV0dXJuIHJlcG9ydDxTdGFnZUJvdHRsZW5lY2s+KGBzdGFnZS1ib3R0bGVuZWNrczoke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5waXBlbGluZV9uYW1lLCBlLnN0YWdlX25hbWUsXG4gICAgICAgICAgQVZHKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgYXZnX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLmR1cmF0aW9uX21zIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EICR7c3RhcnRlZEF0V2luZG93KGZyb20sIHRvKX1cbiAgICAgICAgR1JPVVAgQlkgcC5pZCwgZS5zdGFnZV9uYW1lIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKTtcbiAgfVxuXG4gIC8qKiBBY3Rpb24gZmFpbHVyZSByYXRlIOKAlCB3aGljaCBwbHVnaW4gc3RlcHMgZmFpbCBtb3N0LiAqL1xuICBhc3luYyBnZXRBY3Rpb25GYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxBY3Rpb25GYWlsdXJlW10+IHtcbiAgICByZXR1cm4gcmVwb3J0PEFjdGlvbkZhaWx1cmU+KGBhY3Rpb24tZmFpbHVyZXM6JHtmcm9tfToke3RvfWAsIG9yZ0lkLCBvcmdJZHMsIChwcmVkKSA9PiBzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuYWN0aW9uX25hbWUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWx1cmVzLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgZmFpbHVyZV9wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF90eXBlID0gJ0FDVElPTicgQU5EIGUuYWN0aW9uX25hbWUgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBlLmFjdGlvbl9uYW1lIE9SREVSIEJZIGZhaWx1cmVzIERFU0NcbiAgICAgIGApO1xuICB9XG5cbiAgLyoqXG4gICAqIEVycm9yIGNhdGVnb3JpemF0aW9uIOKAlCBncm91cCBmYWlsdXJlIG1lc3NhZ2VzLiBFeGVjdXRpb24gcmVwb3J0LCBzb1xuICAgKiByb2xsdXAtYXdhcmUgZXhhY3RseSBsaWtlIHRoZSBzaWJsaW5nIGV4ZWN1dGlvbiByZXBvcnRzOiB3aXRoIGBvcmdJZHNgXG4gICAqICh0aGUgb3Jn4oaSdGVhbSBzdWJ0cmVlKSB0aGUgb3JnIGdhdGUgYmVjb21lcyBhbiBgSU4gKC4uLilgIGFuZCB0aGUgcmVhZCBydW5zXG4gICAqIGZyZXNoIHVuZGVyIHN5c2FkbWluIHZpYSBgcnVuUmVwb3J0YDsgc2luZ2xlLW9yZyByZWFkcyBrZWVwIHRoZSBwZXItb3JnIGNhY2hlLlxuICAgKi9cbiAgYXN5bmMgZ2V0RXJyb3JzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgbGltaXQ6IG51bWJlciA9IDIwLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8RXJyb3JFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHJlcG9ydDxFcnJvckVudHJ5PihgZXJyb3JzOiR7ZnJvbX06JHt0b306JHtsaW1pdH1gLCBvcmdJZCwgb3JnSWRzLCAocHJlZCkgPT4gc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBTVUJTVFJJTkcoZS5lcnJvcl9tZXNzYWdlIEZST00gMSBGT1IgMjAwKSBBUyBlcnJvcl9wYXR0ZXJuLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgb2NjdXJyZW5jZXMsXG4gICAgICAgICAgQ09VTlQoRElTVElOQ1QgZS5waXBlbGluZV9pZCk6OmludCBBUyBhZmZlY3RlZF9waXBlbGluZXMsXG4gICAgICAgICAgTUFYKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgbGFzdF9zZWVuXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuc3RhdHVzID0gJ0ZBSUxFRCcgQU5EIGUuZXJyb3JfbWVzc2FnZSBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCAke3N0YXJ0ZWRBdFdpbmRvdyhmcm9tLCB0byl9XG4gICAgICAgIEdST1VQIEJZIGVycm9yX3BhdHRlcm4gT1JERVIgQlkgb2NjdXJyZW5jZXMgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGZvdXIgRE9SQSBtZWFzdXJlcyBwbHVzIHRoZWlyIHBlci1lbnZpcm9ubWVudCBicmVha2Rvd24uXG4gICAqIEltcGxlbWVudGF0aW9uIGluIC4vcmVwb3J0aW5nL2RvcmEudHMg4oCUIHNlZSB0aGF0IGZpbGUncyBoZWFkZXIgZm9yIHdoeS5cbiAgICovXG4gIGdldERvcmFNZXRyaWNzKFxuICAgIG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10sIG9wdHM6IERvcmFPcHRpb25zID0ge30sXG4gICk6IFByb21pc2U8RG9yYU1ldHJpY3M+IHtcbiAgICByZXR1cm4gZG9yYU1ldHJpY3Mob3JnSWQsIGZyb20sIHRvLCBvcmdJZHMsIG9wdHMpO1xuICB9XG5cbiAgLyoqIERPUkEgbWVhc3VyZXMgYnVja2V0ZWQgb3ZlciB0aW1lLiAqL1xuICBnZXREb3JhVHJlbmQoXG4gICAgb3JnSWQ6IHN0cmluZywgaW50ZXJ2YWw6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSwgb3B0czogRG9yYU9wdGlvbnMgPSB7fSxcbiAgKTogUHJvbWlzZTxEb3JhVHJlbmRQb2ludFtdPiB7XG4gICAgcmV0dXJuIGRvcmFUcmVuZChvcmdJZCwgaW50ZXJ2YWwsIGZyb20sIHRvLCBvcmdJZHMsIG9wdHMpO1xuICB9XG5cbiAgLyoqIFBlci1waXBlbGluZSBidWlsZCBoZWFsdGggKHN0YWdlIHBhc3MgcmF0ZXMgb3ZlciBhIHdpbmRvdykuICovXG4gIGdldEJ1aWxkSGVhbHRoKFxuICAgIG9yZ0lkOiBzdHJpbmcsIHBpcGVsaW5lSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSxcbiAgKTogUHJvbWlzZTxCdWlsZEhlYWx0aD4ge1xuICAgIHJldHVybiBidWlsZEhlYWx0aChvcmdJZCwgcGlwZWxpbmVJZCwgZnJvbSwgdG8sIG9yZ0lkcyk7XG4gIH1cblxuICBhc3luYyBnZXRQbHVnaW5TdW1tYXJ5KG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFBsdWdpblN1bW1hcnk+IHtcbiAgICByZXR1cm4gaW52ZW50b3J5Q2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnBsdWdpbi1zdW1tYXJ5YCwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHRvdGFsLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSk6OmludCBBUyBhY3RpdmUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBOT1QgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSk6OmludCBBUyBpbmFjdGl2ZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi52aXNpYmlsaXR5fSA9ICdwdWJsaWMnKTo6aW50IEFTIHB1YmxpYyxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi52aXNpYmlsaXR5fSA9ICdvcmcnKTo6aW50IEFTIG9yZyxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi52aXNpYmlsaXR5fSA9ICdwcml2YXRlJyk6OmludCBBUyBwcml2YXRlLFxuICAgICAgICAgIENPVU5UKERJU1RJTkNUICR7c2NoZW1hLnBsdWdpbi5uYW1lfSk6OmludCBBUyB1bmlxdWVfbmFtZXNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfVxuICAgICAgYCkpO1xuICAgICAgcmV0dXJuIChkcml6emxlUm93czxQbHVnaW5TdW1tYXJ5Pihyb3dzLnJvd3MpWzBdIHx8IHsgdG90YWw6IDAsIGFjdGl2ZTogMCwgaW5hY3RpdmU6IDAsIHB1YmxpYzogMCwgb3JnOiAwLCBwcml2YXRlOiAwLCB1bmlxdWVOYW1lczogMCB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBUeXBlICYgY29tcHV0ZSBkaXN0cmlidXRpb24uXG4gICAqICBJTlRFTlRJT05BTExZIFNJTkdMRS1PUkcgKG5vIHJvbGx1cCk6IHBsdWdpbiBpbnZlbnRvcnkgaXMgcGVyLW9yZyAoc2VlXG4gICAqICBnZXRQbHVnaW5TdW1tYXJ5KS4gU2luZ2xlIGA9ICRvcmdgIHNjb3BlLiAqL1xuICBhc3luYyBnZXRQbHVnaW5EaXN0cmlidXRpb24ob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8VHlwZUNvbXB1dGVEaXN0cmlidXRpb25bXT4ge1xuICAgIHJldHVybiBpbnZlbnRvcnlDYWNoZS5nZXRPclNldChgJHtvcmdJZH06cGx1Z2luLWRpc3RyaWJ1dGlvbmAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgJHtzY2hlbWEucGx1Z2luLnBsdWdpblR5cGV9IEFTIHBsdWdpbl90eXBlLFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5jb21wdXRlVHlwZX0gQVMgY29tcHV0ZV90eXBlLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgY291bnRcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfSBBTkQgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgJHtzY2hlbWEucGx1Z2luLnBsdWdpblR5cGV9LCAke3NjaGVtYS5wbHVnaW4uY29tcHV0ZVR5cGV9XG4gICAgICAgIE9SREVSIEJZIGNvdW50IERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxUeXBlQ29tcHV0ZURpc3RyaWJ1dGlvbj4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cblxuICAvKiogVmVyc2lvbiBjb3VudHMgcGVyIHBsdWdpbiBuYW1lLlxuICAgKiAgSU5URU5USU9OQUxMWSBTSU5HTEUtT1JHIChubyByb2xsdXApOiBwbHVnaW4gaW52ZW50b3J5IGlzIHBlci1vcmcgKHNlZVxuICAgKiAgZ2V0UGx1Z2luU3VtbWFyeSkuIFNpbmdsZSBgPSAkb3JnYCBzY29wZS4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luVmVyc2lvbnMob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8VmVyc2lvbkNvdW50W10+IHtcbiAgICByZXR1cm4gaW52ZW50b3J5Q2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnBsdWdpbi12ZXJzaW9uc2AsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgJHtzY2hlbWEucGx1Z2luLm5hbWV9LFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdmVyc2lvbl9jb3VudCxcbiAgICAgICAgICAtLSBIaWdoZXN0IHZlcnNpb24gYnkgTlVNRVJJQyBzZW12ZXIgY29yZSAobm90IGxleGljYWw6ICcxMC4wLjAnID4gJzkuMC4wJykuXG4gICAgICAgICAgLS0gU3RyaXAgYW55IC1wcmVyZWxlYXNlLytidWlsZCBzdWZmaXggYmVmb3JlIHRoZSBpbnRbXSBjYXN0IHNvIGl0IGNhbid0XG4gICAgICAgICAgLS0gZXJyb3Igb24gdmFsaWQgc2VtdmVyOyBrZWVwIHRoZSBvcmlnaW5hbCBzdHJpbmcgZm9yIGRpc3BsYXkuXG4gICAgICAgICAgLS0gR1VBUkQ6IGEgbm9uLW51bWVyaWMtZG90dGVkIHZlcnNpb24gKCdsYXRlc3QnLCAnJywgJ3YxJykgd291bGQgbWFrZSB0aGVcbiAgICAgICAgICAtLSA6OmludFtdIGNhc3QgdGhyb3cgYW5kIGJsb3cgdXAgdGhlIFdIT0xFIG9yZyBzdW1tYXJ5LiBPbmx5IGNhc3Qgcm93c1xuICAgICAgICAgIC0tIHdob3NlIHN0cmlwcGVkIGNvcmUgbWF0Y2hlcyBhIG51bWVyaWMtZG90dGVkIHNoYXBlOyBzb3J0IGV2ZXJ5dGhpbmdcbiAgICAgICAgICAtLSBlbHNlIHRvIHRoZSBib3R0b20gdmlhIGEgc2VudGluZWwgQVJSQVlbLTFdIHNvIHRoZSByb3cgc3RpbGwgY291bnRzLlxuICAgICAgICAgIChhcnJheV9hZ2coJHtzY2hlbWEucGx1Z2luLnZlcnNpb259XG4gICAgICAgICAgICAgT1JERVIgQlkgQ0FTRVxuICAgICAgICAgICAgICAgV0hFTiByZWdleHBfcmVwbGFjZSgke3NjaGVtYS5wbHVnaW4udmVyc2lvbn0sICdbLStdLiokJywgJycpIH4gJ15bMC05XSsoWy5dWzAtOV0rKSokJ1xuICAgICAgICAgICAgICAgICBUSEVOIHN0cmluZ190b19hcnJheShyZWdleHBfcmVwbGFjZSgke3NjaGVtYS5wbHVnaW4udmVyc2lvbn0sICdbLStdLiokJywgJycpLCAnLicpOjppbnRbXVxuICAgICAgICAgICAgICAgRUxTRSBBUlJBWVstMV1cbiAgICAgICAgICAgICBFTkQgREVTQ1xuICAgICAgICAgICkpWzFdIEFTIGxhdGVzdF92ZXJzaW9uLFxuICAgICAgICAgIGJvb2xfb3IoJHtzY2hlbWEucGx1Z2luLmlzRGVmYXVsdH0pIEFTIGhhc19kZWZhdWx0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGx1Z2lufVxuICAgICAgICBXSEVSRSAke3NjaGVtYS5wbHVnaW4ub3JnSWR9ID0gJHtvcmdJZH0gQU5EICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0gPSB0cnVlXG4gICAgICAgIEdST1VQIEJZICR7c2NoZW1hLnBsdWdpbi5uYW1lfVxuICAgICAgICBPUkRFUiBCWSB2ZXJzaW9uX2NvdW50IERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxWZXJzaW9uQ291bnQ+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIHN1Y2Nlc3MgcmF0ZSBvdmVyIHRpbWUuXG4gICAqXG4gICAqIFNUQVRVUyBDQVNJTkcgTk9URTogVGhpcyBxdWVyeSBmaWx0ZXJzIGJ5IGBldmVudF9zb3VyY2UgPSAncGx1Z2luLWJ1aWxkJ2BcbiAgICogYW5kIHVzZXMgbG93ZXJjYXNlIHN0YXR1cyB2YWx1ZXMgKGAnY29tcGxldGVkJ2AsIGAnZmFpbGVkJ2ApLCB3aGlsZVxuICAgKiBgZ2V0U3VjY2Vzc1JhdGVgICgxLjIpIGZpbHRlcnMgYnkgYGV2ZW50X3R5cGUgPSAnUElQRUxJTkUnYCB3aXRoXG4gICAqIHVwcGVyY2FzZSBBV1Mtc3R5bGUgc3RhdHVzZXMgKGAnU1VDQ0VFREVEJ2AsIGAnRkFJTEVEJ2AsIGAnQ0FOQ0VMRUQnYCkuXG4gICAqIFRoZSBjYXNpbmcgZHJpZnQgaXMgaW50ZW50aW9uYWwgYW5kIHRyYWNrcyB0aGUgcHJvZHVjZXI6XG4gICAqICAgLSBgcGx1Z2luLWJ1aWxkYCBldmVudHMgY29tZSBmcm9tIG91ciBvd24gYnVpbGQgcGlwZWxpbmUgKGxvd2VyY2FzZSlcbiAgICogICAtIGBQSVBFTElORWAgZXZlbnRzIGNvbWUgZnJvbSBBV1MgQ29kZVBpcGVsaW5lICh1cHBlcmNhc2UpXG4gICAqIFRoZSBpbmdlc3QgWm9kIHNjaGVtYSBhdCBhcGkvcmVwb3J0aW5nL3NyYy9yb3V0ZXMvZXZlbnQtaW5nZXN0LnRzXG4gICAqIFNIT1VMRCBlbnVtIHRoZXNlIHBlci1ldmVudFNvdXJjZSBzbyB3ZSBjYXRjaCBkcmlmdCBhdCBpbmdlc3QgcmF0aGVyXG4gICAqIHRoYW4gc2lsZW50bHkgcHJvZHVjaW5nIHplcm8gcm93cyBoZXJlLiBTZWUgZmluZGluZ3MgTjcxLlxuICAgKi9cbiAgYXN5bmMgZ2V0QnVpbGRTdWNjZXNzUmF0ZShvcmdJZDogc3RyaW5nLCBpbnRlcnZhbDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxCdWlsZFRpbWVTZXJpZXNFbnRyeVtdPiB7XG4gICAgYXNzZXJ0UmVwb3J0SW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgIC8vIEJ1aWxkIGFjdGl2aXR5IHJlcG9ydCDigJQgcm9sbHVwLWF3YXJlIGxpa2UgdGhlIGV4ZWN1dGlvbiByZXBvcnRzLiBUaGVzZVxuICAgIC8vIHJvd3MgYXJlIGdhdGVkIG9uIHRoZSBwaXBlbGluZV9ldmVudCBgb3JnX2lkYCBkaXJlY3RseSAobm8gcGlwZWxpbmUgam9pbiksXG4gICAgLy8gc28gYHByZWRgIGFwcGxpZXMgdG8gYGUub3JnX2lkYC5cbiAgICByZXR1cm4gcmVwb3J0PEJ1aWxkVGltZVNlcmllc0VudHJ5PihgYnVpbGQtc3VjY2Vzczoke2ludGVydmFsfToke2Zyb219OiR7dG99YCwgb3JnSWQsIG9yZ0lkcywgKHByZWQpID0+IHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgREFURV9UUlVOQygke2ludGVydmFsfSwgZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBwZXJpb2QsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdjb21wbGV0ZWQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ2ZhaWxlZCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnY29tcGxldGVkJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIHN1Y2Nlc3NfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnXG4gICAgICAgICAgQU5EIGUuc3RhdHVzIElOICgnY29tcGxldGVkJywgJ2ZhaWxlZCcpXG4gICAgICAgICAgQU5EICR7c3RhcnRlZEF0V2luZG93KGZyb20sIHRvKX1cbiAgICAgICAgR1JPVVAgQlkgcGVyaW9kIE9SREVSIEJZIHBlcmlvZFxuICAgICAgYCk7XG4gIH1cblxuICAvKiogQnVpbGQgZHVyYXRpb24gcGVyIHBsdWdpbi4gQnVpbGQgYWN0aXZpdHkgcmVwb3J0IOKAlCByb2xsdXAtYXdhcmUuICovXG4gIGFzeW5jIGdldEJ1aWxkRHVyYXRpb24ob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8QnVpbGREdXJhdGlvbltdPiB7XG4gICAgcmV0dXJuIHJlcG9ydDxCdWlsZER1cmF0aW9uPihgYnVpbGQtZHVyYXRpb246JHtmcm9tfToke3RvfWAsIG9yZ0lkLCBvcmdJZHMsIChwcmVkKSA9PiBzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuZGV0YWlsLT4+J3BsdWdpbk5hbWUnIEFTIHBsdWdpbl9uYW1lLFxuICAgICAgICAgIEFWRyhlLmR1cmF0aW9uX21zKTo6aW50IEFTIGF2Z19tcyxcbiAgICAgICAgICBNQVgoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBtYXhfbXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBidWlsZHNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIFdIRVJFIGUub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfc291cmNlID0gJ3BsdWdpbi1idWlsZCcgQU5EIGUuZHVyYXRpb25fbXMgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgJHtzdGFydGVkQXRXaW5kb3coZnJvbSwgdG8pfVxuICAgICAgICBHUk9VUCBCWSBwbHVnaW5fbmFtZSBPUkRFUiBCWSBhdmdfbXMgREVTQ1xuICAgICAgYCk7XG4gIH1cblxuICAvKiogQnVpbGQgZmFpbHVyZXMg4oCUIHRvcCBlcnJvciBtZXNzYWdlcy4gQnVpbGQgYWN0aXZpdHkgcmVwb3J0IOKAlCByb2xsdXAtYXdhcmUuICovXG4gIGFzeW5jIGdldEJ1aWxkRmFpbHVyZXMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBsaW1pdDogbnVtYmVyID0gMjAsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxCdWlsZEZhaWx1cmVbXT4ge1xuICAgIHJldHVybiByZXBvcnQ8QnVpbGRGYWlsdXJlPihgYnVpbGQtZmFpbHVyZXM6JHtmcm9tfToke3RvfToke2xpbWl0fWAsIG9yZ0lkLCBvcmdJZHMsIChwcmVkKSA9PiBzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuZGV0YWlsLT4+J3BsdWdpbk5hbWUnIEFTIHBsdWdpbl9uYW1lLFxuICAgICAgICAgIGUuZXJyb3JfbWVzc2FnZSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIG9jY3VycmVuY2VzLFxuICAgICAgICAgIE1BWChlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGxhc3Rfc2VlblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgV0hFUkUgZS5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF9zb3VyY2UgPSAncGx1Z2luLWJ1aWxkJyBBTkQgZS5zdGF0dXMgPSAnZmFpbGVkJ1xuICAgICAgICAgIEFORCAke3N0YXJ0ZWRBdFdpbmRvdyhmcm9tLCB0byl9XG4gICAgICAgIEdST1VQIEJZIHBsdWdpbl9uYW1lLCBlLmVycm9yX21lc3NhZ2VcbiAgICAgICAgT1JERVIgQlkgb2NjdXJyZW5jZXMgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCk7XG4gIH1cblxuICAvLyDilIDilIAgUGx1Z2luIHJ1bnRpbWUgdGVsZW1ldHJ5IOKAlCBzZWUgLi9yZXBvcnRpbmcvcGx1Z2luLXJ1bnRpbWUudHMg4pSA4pSAXG5cbiAgLyoqXG4gICAqIFBsdWdpbiBydW50aW1lOiBwZXIgcGx1Z2luIHZlcnNpb24gcnVucywgc3VjY2VzcyByYXRlIGFuZCBwNTAvcDk1XG4gICAqIGR1cmF0aW9uIG92ZXIgYFtmcm9tLCB0b11gLCBmcm9tIHRoZSBtYW5pZmVzdC1hdHRyaWJ1dGVkIEFDVElPTiBldmVudHMuXG4gICAqIFJvbGx1cC1hd2FyZS5cbiAgICovXG4gIGFzeW5jIGdldFBsdWdpblJ1bnRpbWUob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBmaWx0ZXI/OiBQbHVnaW5SdW50aW1lRmlsdGVyLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8UGx1Z2luUnVudGltZVN0YXRzW10+IHtcbiAgICByZXR1cm4gcGx1Z2luUnVudGltZShvcmdJZCwgZnJvbSwgdG8sIGZpbHRlciwgb3JnSWRzKTtcbiAgfVxuXG4gIC8qKiBDcm9zcy1vcmcgMzAtZGF5IHJ1bnRpbWUgYWdncmVnYXRlIGZvciBhIGAocHVibGlzaGVyLCBuYW1lKWAgbGlzdGluZyAocGx1Z2luX3N0YXRzIGlucHV0KS4gU2VydmljZSBjYWxsZXJzIG9ubHkuICovXG4gIGFzeW5jIGdldFBsdWdpblJ1bnRpbWVBZ2dyZWdhdGUocHVibGlzaGVyOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IFByb21pc2U8UGx1Z2luUnVudGltZUFnZ3JlZ2F0ZT4ge1xuICAgIHJldHVybiBwbHVnaW5SdW50aW1lQWdncmVnYXRlKHB1Ymxpc2hlciwgbmFtZSk7XG4gIH1cblxuICAvKiogUmV2aWV3IFwidmVyaWZpZWQgdXNlXCI6IGBvcmdJZGAgcmFuIGAocHVibGlzaGVyLCBuYW1lKWAgc3VjY2Vzc2Z1bGx5IHdpdGhpbiA5MCBkYXlzLiBTZXJ2aWNlIGNhbGxlcnMgb25seS4gKi9cbiAgYXN5bmMgaGFzVmVyaWZpZWRQbHVnaW5Vc2Uob3JnSWQ6IHN0cmluZywgcHVibGlzaGVyOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB2ZXJpZmllZFBsdWdpblVzZShvcmdJZCwgcHVibGlzaGVyLCBuYW1lKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBDYXRlZ29yeSAzOiBET1JBIHdyaXRlIHBhdGhzIChwb3N0LWRlcGxveSBvdXRjb21lcyArIGluZ2VzdCBoZWFsdGgpIOKUgOKUgFxuXG4gIC8qKlxuICAgKiBSZWNvcmQgYSBtYW51YWwgcG9zdC1kZXBsb3kgb3V0Y29tZSBtYXJrZXI6IGEgdXNlciBtYXJrcyBhXG4gICAqIGRlcGxveW1lbnQgYGZhaWxlZGAgKGEgcHJvZHVjdGlvbiBpbmNpZGVudCBsaW5rZWQgdG8gdGhlIGRlcGxveSkgb3JcbiAgICogYHJlc3RvcmVkYCAocmVjb3ZlcmVkKS4gSWRlbXBvdGVudCDigJQga2V5ZWQgb24gKGV4ZWN1dGlvbl9pZCwgb3V0Y29tZSkgc28gYVxuICAgKiBkdXBsaWNhdGUgUE9TVCByZWZyZXNoZXMgYGF0YCByYXRoZXIgdGhhbiBkb3VibGUtY291bnRpbmcsIHdoaWxlIGFcbiAgICogZmFpbGVk4oaScmVzdG9yZWQgcGFpciBzdGF5cyB0d28gcm93cy4gRmVlZHMgdGhlIHBvc3QtZGVwbG95IENGUiBjb21wb25lbnQgYW5kXG4gICAqIHRoZSByZWFsIE1UVFIuIFJ1bnMgdW5kZXIgdGhlIGNhbGxlcidzIG9yZyBjb250ZXh0IChSTFMgV0lUSCBDSEVDSykuXG4gICAqL1xuICBhc3luYyByZWNvcmREZXBsb3ltZW50T3V0Y29tZShcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIGV4ZWN1dGlvbklkOiBzdHJpbmcsXG4gICAgaW5wdXQ6IHsgb3V0Y29tZTogJ2ZhaWxlZCcgfCAncmVzdG9yZWQnOyBhdDogc3RyaW5nOyBlbnZpcm9ubWVudD86IHN0cmluZyB9LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW46IGZhbHNlIH0sICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5pbnNlcnQoc2NoZW1hLmRlcGxveW1lbnRPdXRjb21lKS52YWx1ZXMoe1xuICAgICAgICBleGVjdXRpb25JZCxcbiAgICAgICAgb3JnSWQsXG4gICAgICAgIGVudmlyb25tZW50OiBzY3J1Yk9wdGlvbmFsKGlucHV0LmVudmlyb25tZW50KSxcbiAgICAgICAgb3V0Y29tZTogaW5wdXQub3V0Y29tZSxcbiAgICAgICAgYXQ6IG5ldyBEYXRlKGlucHV0LmF0KSxcbiAgICAgIH0pLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogW3NjaGVtYS5kZXBsb3ltZW50T3V0Y29tZS5leGVjdXRpb25JZCwgc2NoZW1hLmRlcGxveW1lbnRPdXRjb21lLm91dGNvbWVdLFxuICAgICAgICBzZXQ6IHtcbiAgICAgICAgICBhdDogbmV3IERhdGUoaW5wdXQuYXQpLFxuICAgICAgICAgIGVudmlyb25tZW50OiBzY3J1Yk9wdGlvbmFsKGlucHV0LmVudmlyb25tZW50KSA/PyBudWxsLFxuICAgICAgICB9LFxuICAgICAgfSkpLFxuICAgICk7XG4gICAgLy8gT3V0Y29tZSBjaGFuZ2VzIHRoZSBET1JBIGFnZ3JlZ2F0ZSDigJQgZHJvcCB0aGUgb3JnJ3MgY2FjaGVkIHJlcG9ydHMuXG4gICAgYXdhaXQgdGhpcy5pbnZhbGlkYXRlT3JnKG9yZ0lkKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIGNhY2hlIGludmFsaWRhdGlvbiBmYWlsZWQnLCB7IG9yZ0lkLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW5nZXN0IGEgcHJvZHVjdGlvbiBpbmNpZGVudCBmcm9tIHRoZSBvcmcncyBpbmNpZGVudCB0b29saW5nXG4gICAqIChQYWdlckR1dHkgLyBEYXRhZG9nIC8gQWxlcnRtYW5hZ2VyIHdlYmhvb2spLiBJZGVtcG90ZW50IOKAlCBrZXllZCBvblxuICAgKiAob3JnX2lkLCBpbmNpZGVudF9pZCkgc28gYSBsYXRlciByZXNvbHZlIHJlLXBvc3QgdXBzZXJ0cyBgcmVzb2x2ZWRfYXRgXG4gICAqIChhbmQgcmVmcmVzaGVzIHRoZSBvdGhlciBtdXRhYmxlIGZpZWxkcykgaW5zdGVhZCBvZiBpbnNlcnRpbmcgYSBkdXBsaWNhdGUuXG4gICAqIERPUkEgY29ycmVsYXRlcyBlYWNoIGluY2lkZW50IHRvIHRoZSBtb3N0IHJlY2VudCBzdWNjZXNzZnVsIGRlcGxveSB0byBpdHNcbiAgICogYGVudmlyb25tZW50YCwgcHJvZHVjaW5nIGFuIGF1dG9tYXRlZCBwb3N0LWRlcGxveSBmYWlsdXJlICsgYSByZWFsIE1UVFIuXG4gICAqIFJ1bnMgdW5kZXIgdGhlIGNhbGxlcidzIG9yZyBjb250ZXh0IChSTFMgV0lUSCBDSEVDSyk7IGZyZWUtZm9ybSBmaWVsZHMgYXJlXG4gICAqIEFXUy1pZCBzY3J1YmJlZCBhdCB0aGlzIHBlcnNpc3RlbmNlIGJvdW5kYXJ5IGxpa2UgdGhlIG90aGVyIGluZ2VzdCBwYXRocy5cbiAgICovXG4gIGFzeW5jIHJlY29yZEluY2lkZW50KG9yZ0lkOiBzdHJpbmcsIGlucHV0OiBJbmNpZGVudElucHV0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaW5jaWRlbnRJZCA9IHNjcnViQXdzSWRlbnRpZmllcnNGcm9tU3RyaW5nKGlucHV0LmluY2lkZW50SWQpO1xuICAgIGNvbnN0IGVudmlyb25tZW50ID0gc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmcoaW5wdXQuZW52aXJvbm1lbnQpO1xuICAgIGNvbnN0IHNldmVyaXR5ID0gc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmcoaW5wdXQuc2V2ZXJpdHkpO1xuICAgIGNvbnN0IG9wZW5lZEF0ID0gbmV3IERhdGUoaW5wdXQub3BlbmVkQXQpO1xuICAgIGNvbnN0IHJlc29sdmVkQXQgPSBpbnB1dC5yZXNvbHZlZEF0ID8gbmV3IERhdGUoaW5wdXQucmVzb2x2ZWRBdCkgOiBudWxsO1xuICAgIGF3YWl0IHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbjogZmFsc2UgfSwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4Lmluc2VydChzY2hlbWEuaW5jaWRlbnQpLnZhbHVlcyh7XG4gICAgICAgIGluY2lkZW50SWQsXG4gICAgICAgIG9yZ0lkLFxuICAgICAgICBlbnZpcm9ubWVudCxcbiAgICAgICAgb3BlbmVkQXQsXG4gICAgICAgIHJlc29sdmVkQXQsXG4gICAgICAgIHNldmVyaXR5LFxuICAgICAgfSkub25Db25mbGljdERvVXBkYXRlKHtcbiAgICAgICAgdGFyZ2V0OiBbc2NoZW1hLmluY2lkZW50Lm9yZ0lkLCBzY2hlbWEuaW5jaWRlbnQuaW5jaWRlbnRJZF0sXG4gICAgICAgIC8vIEEgcmVkZWxpdmVyZWQgRklSSU5HIHBvc3QgKG5vIHJlc29sdmVkQXQpIG11c3Qgbm90IHdpcGUgYSByZWNvcmRlZFxuICAgICAgICAvLyByZXNvbHZlIOKAlCBzZW5kZXJzIHJlLXBvc3QgZmlyaW5nIGFsZXJ0cyBvbiBldmVyeSByZXBlYXQgaW50ZXJ2YWwsIGFuZFxuICAgICAgICAvLyBkZWxpdmVyeSBvcmRlciBpc24ndCBndWFyYW50ZWVkLiBLZWVwIHRoZSBzdG9yZWQgcmVzb2x2ZSB1bmxlc3MgdGhlXG4gICAgICAgIC8vIHBvc3QgY2FycmllcyBpdHMgb3duLCBvciB0aGUgaW5jaWRlbnQgd2FzIFJFLU9QRU5FRCAoYSBkaWZmZXJlbnRcbiAgICAgICAgLy8gb3BlbmVkQXQgbWVhbnMgYSBuZXcgb2NjdXJyZW5jZSwgd2hvc2UgcmVzb2x2ZSBzdGF0ZSBpcyB0aGUgcG9zdCdzKS5cbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgZW52aXJvbm1lbnQsXG4gICAgICAgICAgb3BlbmVkQXQsXG4gICAgICAgICAgcmVzb2x2ZWRBdDogc3FsYENBU0UgV0hFTiAke3NjaGVtYS5pbmNpZGVudC5vcGVuZWRBdH0gPSBleGNsdWRlZC5vcGVuZWRfYXRcbiAgICAgICAgICAgIFRIRU4gQ09BTEVTQ0UoZXhjbHVkZWQucmVzb2x2ZWRfYXQsICR7c2NoZW1hLmluY2lkZW50LnJlc29sdmVkQXR9KVxuICAgICAgICAgICAgRUxTRSBleGNsdWRlZC5yZXNvbHZlZF9hdCBFTkRgLFxuICAgICAgICAgIHNldmVyaXR5LFxuICAgICAgICB9LFxuICAgICAgfSkpLFxuICAgICk7XG4gICAgLy8gQSBuZXcvdXBkYXRlZCBpbmNpZGVudCBjaGFuZ2VzIHRoZSBET1JBIGFnZ3JlZ2F0ZSDigJQgZHJvcCBjYWNoZWQgcmVwb3J0cy5cbiAgICBhd2FpdCB0aGlzLmludmFsaWRhdGVPcmcob3JnSWQpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgIGxvZ2dlci53YXJuKCdSZXBvcnRpbmcgY2FjaGUgaW52YWxpZGF0aW9uIGZhaWxlZCcsIHsgb3JnSWQsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkIHRoZSBwZXItb3JnIERPUkEgc2V0dGluZ3MuIFJldHVybnMgdGhlIHN0b3JlZFxuICAgKiBgaW5jaWRlbnRXaW5kb3dIb3Vyc2Agb3ZlcnJpZGUgKG9yIGBudWxsYCB3aGVuIHVuc2V0KSBwbHVzIHRoZSBnbG9iYWwgZW52XG4gICAqIGRlZmF1bHQsIHNvIHRoZSBzZXR0aW5ncyBVSSBjYW4gc2hvdyBib3RoLiBSdW5zIHVuZGVyIHRoZSBjYWxsZXIncyB0ZW5hbnRcbiAgICogY29udGV4dCAoUkxTLXNjb3BlZCk7IGEgc2luZ2xlLW9yZyByZWFkLlxuICAgKi9cbiAgYXN5bmMgZ2V0UmVwb3J0aW5nU2V0dGluZ3Mob3JnSWQ6IHN0cmluZywgcmV0ZW50aW9uT3JnSWQ6IHN0cmluZyA9IG9yZ0lkKTogUHJvbWlzZTxSZXBvcnRpbmdTZXR0aW5ncz4ge1xuICAgIGNvbnN0IHJvd3MgPSBkcml6emxlUm93czx7XG4gICAgICBpbmNpZGVudF93aW5kb3dfaG91cnM6IG51bWJlciB8IG51bGw7XG4gICAgICBldmVudF9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbDtcbiAgICAgIGRvcmFfcmV0ZW50aW9uX2RheXM6IG51bWJlciB8IG51bGw7XG4gICAgfT4oKGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1QgJHtzY2hlbWEuZG9yYVNldHRpbmdzLmluY2lkZW50V2luZG93SG91cnN9IEFTIGluY2lkZW50X3dpbmRvd19ob3VycyxcbiAgICAgICAgICAgICAgICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5ldmVudFJldGVudGlvbkRheXN9IEFTIGV2ZW50X3JldGVudGlvbl9kYXlzLFxuICAgICAgICAgICAgICAgJHtzY2hlbWEuZG9yYVNldHRpbmdzLmRvcmFSZXRlbnRpb25EYXlzfSBBUyBkb3JhX3JldGVudGlvbl9kYXlzXG4gICAgICAgIEZST00gJHtzY2hlbWEuZG9yYVNldHRpbmdzfVxuICAgICAgICBXSEVSRSAke3NjaGVtYS5kb3JhU2V0dGluZ3Mub3JnSWR9ID0gJHtvcmdJZH1cbiAgICAgICAgTElNSVQgMVxuICAgICAgYCkpKS5yb3dzKTtcbiAgICBjb25zdCByb3cgPSByb3dzWzBdO1xuICAgIC8vIFJldGVudGlvbiBpcyBhIGJpbGxpbmcgZW50aXRsZW1lbnQgc3luY2VkIG9udG8gdGhlIGFjY291bnQgUk9PVCBvbmx5OyBhXG4gICAgLy8gdGVhbSByZWFkcyBpdHMgcm9vdCdzIHdpbmRvdyAodGhlIGluY2lkZW50IHdpbmRvdyBzdGF5cyB0aGUgdGVhbSdzIG93bikuXG4gICAgY29uc3QgcmV0ZW50aW9uID0gcmV0ZW50aW9uT3JnSWQgPT09IG9yZ0lkXG4gICAgICA/IHJvd1xuICAgICAgOiBhd2FpdCB0aGlzLiNyZWFkUmV0ZW50aW9uT3ZlcnJpZGUocmV0ZW50aW9uT3JnSWQpO1xuICAgIHJldHVybiB7XG4gICAgICBpbmNpZGVudFdpbmRvd0hvdXJzOiByb3c/LmluY2lkZW50X3dpbmRvd19ob3VycyAhPSBudWxsID8gTnVtYmVyKHJvdy5pbmNpZGVudF93aW5kb3dfaG91cnMpIDogbnVsbCxcbiAgICAgIGRlZmF1bHRXaW5kb3dIb3VyczogRE9SQV9JTkNJREVOVF9XSU5ET1dfSE9VUlMsXG4gICAgICBldmVudFJldGVudGlvbkRheXM6IHJldGVudGlvbj8uZXZlbnRfcmV0ZW50aW9uX2RheXMgIT0gbnVsbCA/IE51bWJlcihyZXRlbnRpb24uZXZlbnRfcmV0ZW50aW9uX2RheXMpIDogbnVsbCxcbiAgICAgIGRvcmFSZXRlbnRpb25EYXlzOiByZXRlbnRpb24/LmRvcmFfcmV0ZW50aW9uX2RheXMgIT0gbnVsbCA/IE51bWJlcihyZXRlbnRpb24uZG9yYV9yZXRlbnRpb25fZGF5cykgOiBudWxsLFxuICAgICAgZGVmYXVsdEV2ZW50UmV0ZW50aW9uRGF5czogUkVQT1JUSU5HX0VWRU5UX1JFVEVOVElPTl9EQVlTLFxuICAgICAgZGVmYXVsdERvcmFSZXRlbnRpb25EYXlzOiBSRVBPUlRJTkdfRE9SQV9SRVRFTlRJT05fREFZUyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBST09UIG9yZydzIHN0b3JlZCByZXRlbnRpb24gb3ZlcnJpZGUuIFRoZSBjYWxsZXIgKGEgdGVhbSkgY2FuJ3Qgc2VlIHRoZVxuICAgKiByb290J3MgYGRvcmFfc2V0dGluZ3NgIHJvdyB1bmRlciBpdHMgb3duIFJMUyBzY29wZSwgc28gdGhpcyBuYXJyb3cgcmVhZCBvZlxuICAgKiB0d28gaW50ZWdlciBjb2x1bW5zIOKAlCBrZXllZCBieSB0aGUgZXhwbGljaXQsIEpXVC1kZXJpdmVkIHJvb3QgaWQg4oCUIHJ1bnMgaW4gYVxuICAgKiBzeXNhZG1pbiBzY29wZS5cbiAgICovXG4gIGFzeW5jICNyZWFkUmV0ZW50aW9uT3ZlcnJpZGUob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8eyBldmVudF9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbDsgZG9yYV9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbCB9IHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3Qgcm93cyA9IGF3YWl0IHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIGFzeW5jICgpID0+IGRyaXp6bGVSb3dzPHtcbiAgICAgIGV2ZW50X3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgICAgZG9yYV9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbDtcbiAgICB9PigoYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVCAke3NjaGVtYS5kb3JhU2V0dGluZ3MuZXZlbnRSZXRlbnRpb25EYXlzfSBBUyBldmVudF9yZXRlbnRpb25fZGF5cyxcbiAgICAgICAgICAgICAgICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5kb3JhUmV0ZW50aW9uRGF5c30gQVMgZG9yYV9yZXRlbnRpb25fZGF5c1xuICAgICAgICBGUk9NICR7c2NoZW1hLmRvcmFTZXR0aW5nc31cbiAgICAgICAgV0hFUkUgJHtzY2hlbWEuZG9yYVNldHRpbmdzLm9yZ0lkfSA9ICR7b3JnSWR9XG4gICAgICAgIExJTUlUIDFcbiAgICAgIGApKSkucm93cykpO1xuICAgIHJldHVybiByb3dzWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwc2VydCBwZXItb3JnIHJlcG9ydGluZyBzZXR0aW5ncyAoaW5jaWRlbnQgd2luZG93ICtcbiAgICogcmV0ZW50aW9uIG92ZXJyaWRlcyksIGlkZW1wb3RlbnQgb24gYG9yZ19pZGAuIEEgcGFydGlhbCB3cml0ZSDigJQgb25seSB0aGVcbiAgICogZmllbGRzIHByZXNlbnQgaW4gYHBhdGNoYCBhcmUgc2V0IChzbyB1cGRhdGluZyByZXRlbnRpb24gbmV2ZXIgY2xlYXJzIHRoZVxuICAgKiBpbmNpZGVudCB3aW5kb3csIGFuZCB2aWNlLXZlcnNhKS4gU2V0IHNlbGYtc2VydmUgYnkgYW4gb3JnIGFkbWluIHZpYVxuICAgKiBgUFVUIC9hcGkvcmVwb3J0cy9zZXR0aW5ncy9pbmNpZGVudHNgLiBSdW5zIHVuZGVyIHRoZSBjYWxsZXIncyBvcmcgY29udGV4dFxuICAgKiAoUkxTIFdJVEggQ0hFQ0spOyBhIGNoYW5nZWQgdmFsdWUgYWZmZWN0cyBET1JBIGFnZ3JlZ2F0ZXMgc28gdGhlIG9yZydzXG4gICAqIGNhY2hlZCByZXBvcnRzIGFyZSBkcm9wcGVkLlxuICAgKi9cbiAgYXN5bmMgc2V0UmVwb3J0aW5nU2V0dGluZ3Mob3JnSWQ6IHN0cmluZywgcGF0Y2g6IFJlcG9ydGluZ1NldHRpbmdzUGF0Y2gpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzZXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0geyB1cGRhdGVkQXQ6IG5ldyBEYXRlKCkgfTtcbiAgICBpZiAocGF0Y2guaW5jaWRlbnRXaW5kb3dIb3VycyAhPT0gdW5kZWZpbmVkKSBzZXQuaW5jaWRlbnRXaW5kb3dIb3VycyA9IHBhdGNoLmluY2lkZW50V2luZG93SG91cnM7XG4gICAgaWYgKHBhdGNoLmV2ZW50UmV0ZW50aW9uRGF5cyAhPT0gdW5kZWZpbmVkKSBzZXQuZXZlbnRSZXRlbnRpb25EYXlzID0gcGF0Y2guZXZlbnRSZXRlbnRpb25EYXlzO1xuICAgIGlmIChwYXRjaC5kb3JhUmV0ZW50aW9uRGF5cyAhPT0gdW5kZWZpbmVkKSBzZXQuZG9yYVJldGVudGlvbkRheXMgPSBwYXRjaC5kb3JhUmV0ZW50aW9uRGF5cztcbiAgICBhd2FpdCBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW46IGZhbHNlIH0sICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5pbnNlcnQoc2NoZW1hLmRvcmFTZXR0aW5ncykudmFsdWVzKHtcbiAgICAgICAgb3JnSWQsXG4gICAgICAgIGluY2lkZW50V2luZG93SG91cnM6IHBhdGNoLmluY2lkZW50V2luZG93SG91cnMsXG4gICAgICAgIGV2ZW50UmV0ZW50aW9uRGF5czogcGF0Y2guZXZlbnRSZXRlbnRpb25EYXlzLFxuICAgICAgICBkb3JhUmV0ZW50aW9uRGF5czogcGF0Y2guZG9yYVJldGVudGlvbkRheXMsXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgIH0pLm9uQ29uZmxpY3REb1VwZGF0ZSh7XG4gICAgICAgIHRhcmdldDogc2NoZW1hLmRvcmFTZXR0aW5ncy5vcmdJZCxcbiAgICAgICAgc2V0LFxuICAgICAgfSkpLFxuICAgICk7XG4gICAgYXdhaXQgdGhpcy5pbnZhbGlkYXRlT3JnKG9yZ0lkKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIGNhY2hlIGludmFsaWRhdGlvbiBmYWlsZWQnLCB7IG9yZ0lkLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdCByZWNlbnQgaW5jaWRlbnRzIGZvciBhbiBvcmcgKG9yZy1hZG1pbiBzdXJmYWNlKSwgbmV3ZXN0IGZpcnN0LFxuICAgKiBwYWdpbmF0ZWQuIEVhY2ggcm93IGNhcnJpZXMgaXRzIHJlc29sdmVkIHN0YXRlIGFuZCBpdHMgZGVwbG95IGNvcnJlbGF0aW9uIOKAlFxuICAgKiB0aGUgbW9zdCByZWNlbnQgU1VDQ0VTU0ZVTCBkZXBsb3kgdG8gdGhlIGluY2lkZW50J3MgYGVudmlyb25tZW50YCB3aG9zZVxuICAgKiBgY29tcGxldGVkX2F0YCBmYWxscyB3aXRoaW4gdGhlIGVmZmVjdGl2ZSBwZXItb3JnIGNvcnJlbGF0aW9uIHdpbmRvdyBiZWZvcmVcbiAgICogYG9wZW5lZF9hdGAgKHRoZSBzYW1lIHJ1bGUgRE9SQSdzIENGUi9NVFRSIGNvcnJlbGF0aW9uIGFwcGxpZXMpLiBTaW5nbGUtb3JnXG4gICAqIChubyByb2xsdXApIOKAlCBhbiBvcmcgYWRtaW4gdmlld3MgdGhlaXIgb3duIG9yZydzIGluY2lkZW50cy4gUkxTLXNjb3BlZCB2aWFcbiAgICogdGhlIGBwLm9yZ19pZGAvYGkub3JnX2lkYCBwcmVkaWNhdGVzICsgdGhlIHRlbmFudCBjb250ZXh0LlxuICAgKi9cbiAgYXN5bmMgbGlzdEluY2lkZW50cyhvcmdJZDogc3RyaW5nLCBvcHRzOiB7IGxpbWl0OiBudW1iZXI7IG9mZnNldDogbnVtYmVyIH0pOiBQcm9taXNlPEluY2lkZW50TGlzdEl0ZW1bXT4ge1xuICAgIGNvbnN0IHsgaW5jaWRlbnRXaW5kb3dIb3VycyB9ID0gYXdhaXQgdGhpcy5nZXRSZXBvcnRpbmdTZXR0aW5ncyhvcmdJZCk7XG4gICAgY29uc3Qgd2luZG93SG91cnMgPSByZXNvbHZlSW5jaWRlbnRXaW5kb3dIb3VycyhpbmNpZGVudFdpbmRvd0hvdXJzKTtcbiAgICBjb25zdCBsaW1pdCA9IE1hdGgubWF4KDEsIE1hdGgubWluKG9wdHMubGltaXQsIDIwMCkpO1xuICAgIGNvbnN0IG9mZnNldCA9IE1hdGgubWF4KDAsIG9wdHMub2Zmc2V0KTtcbiAgICAvLyBUaGUgY29ycmVsYXRpb24gd2luZG93IGlzIGV4cHJlc3NlZCBpbiBTRUNPTkRTIGFzIGEgZG91YmxlLCBub3QgYXNcbiAgICAvLyBgbWFrZV9pbnRlcnZhbChob3VycyA9PiBOOjppbnQpYC4gVGhlIHdpbmRvdyBpcyB2YWxpZGF0ZWQgYXMgYW55IHBvc2l0aXZlXG4gICAgLy8gbnVtYmVyICgwLjVoIGlzIGxlZ2FsKSBhbmQgdGhlIGluLW1lbW9yeSBET1JBIGNvcnJlbGF0aW9uIHVzZXMgaXQgZXhhY3RseTtcbiAgICAvLyB0aGUgaW50IGNhc3QgbWFkZSBQb3N0Z3JlcyByZWplY3QgYSBmcmFjdGlvbmFsIHZhbHVlLCBzbyBhIDAuNWggd2luZG93XG4gICAgLy8gcmV0dXJuZWQgNTAwIGZyb20gdGhpcyBlbmRwb2ludCBhbmQgZnJvbSB0aGUgY29ycmVsYXRpb24gbG9va3VwIGJlbG93LlxuICAgIHJldHVybiB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgaS5pbmNpZGVudF9pZCBBUyBcImluY2lkZW50SWRcIixcbiAgICAgICAgICBpLmVudmlyb25tZW50IEFTIGVudmlyb25tZW50LFxuICAgICAgICAgIGkuc2V2ZXJpdHkgQVMgc2V2ZXJpdHksXG4gICAgICAgICAgaS5vcGVuZWRfYXQ6OnRleHQgQVMgXCJvcGVuZWRBdFwiLFxuICAgICAgICAgIGkucmVzb2x2ZWRfYXQ6OnRleHQgQVMgXCJyZXNvbHZlZEF0XCIsXG4gICAgICAgICAgaS5jcmVhdGVkX2F0Ojp0ZXh0IEFTIFwiY3JlYXRlZEF0XCIsXG4gICAgICAgICAgKGkucmVzb2x2ZWRfYXQgSVMgTk9UIE5VTEwpIEFTIHJlc29sdmVkLFxuICAgICAgICAgIGNvcnIuZXhlY3V0aW9uX2lkIEFTIFwiY29ycmVsYXRlZEV4ZWN1dGlvbklkXCIsXG4gICAgICAgICAgY29yci5jb21wbGV0ZWRfYXQ6OnRleHQgQVMgXCJkZXBsb3lDb21wbGV0ZWRBdFwiXG4gICAgICAgIEZST00gJHtzY2hlbWEuaW5jaWRlbnR9IGlcbiAgICAgICAgTEVGVCBKT0lOIExBVEVSQUwgKFxuICAgICAgICAgIFNFTEVDVCBlLmV4ZWN1dGlvbl9pZCwgZS5jb21wbGV0ZWRfYXRcbiAgICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF90eXBlID0gJ1NUQUdFJ1xuICAgICAgICAgICAgQU5EIGUuZW52aXJvbm1lbnQgPSBpLmVudmlyb25tZW50IEFORCBlLnN0YXR1cyA9ICdTVUNDRUVERUQnXG4gICAgICAgICAgICBBTkQgZS5jb21wbGV0ZWRfYXQgPD0gaS5vcGVuZWRfYXRcbiAgICAgICAgICAgIEFORCBlLmNvbXBsZXRlZF9hdCA+PSBpLm9wZW5lZF9hdCAtIG1ha2VfaW50ZXJ2YWwoc2VjcyA9PiAke3dpbmRvd0hvdXJzICogMzYwMH06OmRvdWJsZSBwcmVjaXNpb24pXG4gICAgICAgICAgT1JERVIgQlkgZS5jb21wbGV0ZWRfYXQgREVTQ1xuICAgICAgICAgIExJTUlUIDFcbiAgICAgICAgKSBjb3JyIE9OIHRydWVcbiAgICAgICAgV0hFUkUgaS5vcmdfaWQgPSAke29yZ0lkfVxuICAgICAgICBPUkRFUiBCWSBpLm9wZW5lZF9hdCBERVNDXG4gICAgICAgIExJTUlUICR7bGltaXR9IE9GRlNFVCAke29mZnNldH1cbiAgICAgIGApLnRoZW4oKHIpID0+IGRyaXp6bGVSb3dzPEluY2lkZW50TGlzdEl0ZW0+KHIucm93cykubWFwKChyb3cpID0+ICh7XG4gICAgICAuLi5yb3csXG4gICAgICByZXNvbHZlZDogcm93LnJlc29sdmVkID09PSB0cnVlIHx8IChyb3cucmVzb2x2ZWQgYXMgdW5rbm93bikgPT09ICd0JyxcbiAgICAgIGNvcnJlbGF0ZWRFeGVjdXRpb25JZDogcm93LmNvcnJlbGF0ZWRFeGVjdXRpb25JZCA/PyBudWxsLFxuICAgICAgZGVwbG95Q29tcGxldGVkQXQ6IHJvdy5kZXBsb3lDb21wbGV0ZWRBdCA/PyBudWxsLFxuICAgIH0pKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdpcmluZy10ZXN0IGRyeS1ydW46IHdvdWxkIGEgc3ludGhldGljIGluY2lkZW50IG9wZW5pbmcgTk9XIGZvclxuICAgKiBgZW52aXJvbm1lbnRgIGNvcnJlbGF0ZSB0byBhIHJlY2VudCBzdWNjZXNzZnVsIGRlcGxveSB1bmRlciB0aGUgb3JnJ3NcbiAgICogZWZmZWN0aXZlIHdpbmRvdz8gVGhpcyBpcyBhIE5PTi1wZXJzaXN0aW5nIGNvcnJlbGF0aW9uIGNoZWNrIOKAlCBpdCB2ZXJpZmllc1xuICAgKiB0aGUgYWRtaW4ncyBlbnZpcm9ubWVudCBuYW1pbmcgKyB3aW5kb3cgbGluZSB1cCB3aXRoIHJlYWwgZGVwbG95IGV2ZW50c1xuICAgKiBXSVRIT1VUIHdyaXRpbmcgYW4gaW5jaWRlbnQgKHNvIGEgXCJ0ZXN0XCIgbmV2ZXIgcG9sbHV0ZXMgQ0ZSL01UVFIpLiBSTFMtc2NvcGVkLlxuICAgKi9cbiAgYXN5bmMgdGVzdEluY2lkZW50Q29ycmVsYXRpb24ob3JnSWQ6IHN0cmluZywgZW52aXJvbm1lbnQ6IHN0cmluZyk6IFByb21pc2U8SW5jaWRlbnRUZXN0UmVzdWx0PiB7XG4gICAgY29uc3QgZW52ID0gc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmcoZW52aXJvbm1lbnQpO1xuICAgIGNvbnN0IG9wZW5lZEF0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgIGNvbnN0IHsgaW5jaWRlbnRXaW5kb3dIb3VycyB9ID0gYXdhaXQgdGhpcy5nZXRSZXBvcnRpbmdTZXR0aW5ncyhvcmdJZCk7XG4gICAgY29uc3Qgd2luZG93SG91cnMgPSByZXNvbHZlSW5jaWRlbnRXaW5kb3dIb3VycyhpbmNpZGVudFdpbmRvd0hvdXJzKTtcbiAgICBjb25zdCByb3dzID0gZHJpenpsZVJvd3M8eyBleGVjdXRpb25faWQ6IHN0cmluZyB8IG51bGw7IGNvbXBsZXRlZF9hdDogc3RyaW5nIHwgbnVsbCB9PigoYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVCBlLmV4ZWN1dGlvbl9pZCBBUyBleGVjdXRpb25faWQsIGUuY29tcGxldGVkX2F0Ojp0ZXh0IEFTIGNvbXBsZXRlZF9hdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnXG4gICAgICAgICAgQU5EIGUuZW52aXJvbm1lbnQgPSAke2Vudn0gQU5EIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCdcbiAgICAgICAgICBBTkQgZS5jb21wbGV0ZWRfYXQgPD0gJHtvcGVuZWRBdH06OnRpbWVzdGFtcHR6XG4gICAgICAgICAgQU5EIGUuY29tcGxldGVkX2F0ID49ICR7b3BlbmVkQXR9Ojp0aW1lc3RhbXB0eiAtIG1ha2VfaW50ZXJ2YWwoc2VjcyA9PiAke3dpbmRvd0hvdXJzICogMzYwMH06OmRvdWJsZSBwcmVjaXNpb24pXG4gICAgICAgIE9SREVSIEJZIGUuY29tcGxldGVkX2F0IERFU0NcbiAgICAgICAgTElNSVQgMVxuICAgICAgYCkpKS5yb3dzKTtcbiAgICBjb25zdCBoaXQgPSByb3dzWzBdO1xuICAgIHJldHVybiB7XG4gICAgICBlbnZpcm9ubWVudDogZW52LFxuICAgICAgb3BlbmVkQXQsXG4gICAgICB3aW5kb3dIb3VycyxcbiAgICAgIGNvcnJlbGF0ZWQ6IGhpdD8uZXhlY3V0aW9uX2lkICE9IG51bGwsXG4gICAgICBleGVjdXRpb25JZDogaGl0Py5leGVjdXRpb25faWQgPz8gbnVsbCxcbiAgICAgIGRlcGxveUNvbXBsZXRlZEF0OiBoaXQ/LmNvbXBsZXRlZF9hdCA/PyBudWxsLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVXBzZXJ0IHBlci1vcmcgaW5nZXN0aW9uIGhlYWx0aDogdGhlIEFXUyBldmVudHMgTGFtYmRhIHBlcmlvZGljYWxseVxuICAgKiByZXBvcnRzIGZvcndhcmRlZC9kcm9wcGVkIGNvdW50ZXJzICsgdGhlIGxhc3QgZXZlbnQgdGltZXN0YW1wIHNvIHRoZSBSZXBvcnRzXG4gICAqIFVJIGNhbiBzaG93IGZsb3dpbmcgLyBzdGFsZSAvIGRyb3BwaW5nLiBPbmUgcm93IHBlciBvcmcgKHVwc2VydCBvbiBvcmdfaWQpLlxuICAgKi9cbiAgYXN5bmMgcmVjb3JkSW5nZXN0SGVhbHRoKFxuICAgIG9yZ0lkOiBzdHJpbmcsXG4gICAgaW5wdXQ6IHsgZm9yd2FyZGVkPzogbnVtYmVyOyBkcm9wcGVkPzogbnVtYmVyOyBsYXN0RXZlbnRBdD86IHN0cmluZyB9LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsYXN0RXZlbnRBdCA9IGlucHV0Lmxhc3RFdmVudEF0ID8gbmV3IERhdGUoaW5wdXQubGFzdEV2ZW50QXQpIDogdW5kZWZpbmVkO1xuICAgIGF3YWl0IHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbjogZmFsc2UgfSwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4Lmluc2VydChzY2hlbWEuaW5nZXN0SGVhbHRoKS52YWx1ZXMoe1xuICAgICAgICBvcmdJZCxcbiAgICAgICAgZm9yd2FyZGVkOiBpbnB1dC5mb3J3YXJkZWQsXG4gICAgICAgIGRyb3BwZWQ6IGlucHV0LmRyb3BwZWQsXG4gICAgICAgIGxhc3RFdmVudEF0LFxuICAgICAgICB1cGRhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICB9KS5vbkNvbmZsaWN0RG9VcGRhdGUoe1xuICAgICAgICB0YXJnZXQ6IHNjaGVtYS5pbmdlc3RIZWFsdGgub3JnSWQsXG4gICAgICAgIHNldDoge1xuICAgICAgICAgIGZvcndhcmRlZDogaW5wdXQuZm9yd2FyZGVkLFxuICAgICAgICAgIGRyb3BwZWQ6IGlucHV0LmRyb3BwZWQsXG4gICAgICAgICAgbGFzdEV2ZW50QXQsXG4gICAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICB9LFxuICAgICAgfSkpLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZCBiYWNrIG9uZSBvcmcncyBpbmdlc3Rpb24gaGVhbHRoIGZvciB0aGUgUmVwb3J0cyBVSSBmcmVzaG5lc3NcbiAgICogaW5kaWNhdG9yLiBSZXR1cm5zIGBudWxsYCB3aGVuIHRoZSBvcmcgaGFzIE5PIHJvdyDigJQgaS5lLiB0aGUgZGVwbG95bWVudCBoYXNcbiAgICogbmV2ZXIgaW5nZXN0ZWQgYW55dGhpbmcg4oCUIHdoaWNoIHRoZSBVSSBtdXN0IHJlbmRlciBhcyBcIm5vIGluZ2VzdCByZXBvcnRlZFxuICAgKiB5ZXRcIiwgbmV2ZXIgYXMgXCJzdGFsZVwiLiBSTFMtc2NvcGVkIHRvIHRoZSBvcmcgbGlrZSBldmVyeSBvdGhlciByZWFkLlxuICAgKi9cbiAgYXN5bmMgZ2V0SW5nZXN0SGVhbHRoKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPEluZ2VzdEhlYWx0aFN0YXR1cyB8IG51bGw+IHtcbiAgICBjb25zdCByb3dzID0gYXdhaXQgcnVuV2l0aFRlbmFudENvbnRleHQoeyBvcmdJZCwgaXNTdXBlckFkbWluOiBmYWxzZSB9LCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHhcbiAgICAgICAgLnNlbGVjdCgpXG4gICAgICAgIC5mcm9tKHNjaGVtYS5pbmdlc3RIZWFsdGgpXG4gICAgICAgIC53aGVyZShlcShzY2hlbWEuaW5nZXN0SGVhbHRoLm9yZ0lkLCBvcmdJZCkpXG4gICAgICAgIC5saW1pdCgxKSksXG4gICAgKTtcbiAgICBjb25zdCByb3cgPSByb3dzWzBdO1xuICAgIGlmICghcm93KSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4ge1xuICAgICAgdXBkYXRlZEF0OiByb3cudXBkYXRlZEF0LnRvSVNPU3RyaW5nKCksXG4gICAgICBsYXN0RXZlbnRBdDogcm93Lmxhc3RFdmVudEF0ID8gcm93Lmxhc3RFdmVudEF0LnRvSVNPU3RyaW5nKCkgOiBudWxsLFxuICAgICAgZm9yd2FyZGVkOiByb3cuZm9yd2FyZGVkID8/IG51bGwsXG4gICAgICBkcm9wcGVkOiByb3cuZHJvcHBlZCA/PyBudWxsLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQmF0Y2hlZCBoYXJkLURFTEVURSBvZiBvbmUgcmVwb3J0aW5nIHRhYmxlJ3Mgcm93cyBleHBpcmVkIHBhc3QgYSBgY3JlYXRlZF9hdGBcbiAgICogY3V0b2ZmLCBzY29wZWQgdG8gYW4gb3JnIGFuZCBhbiBvcHRpb25hbCByb3cgcHJlZGljYXRlLiBVc2VzIGFcbiAgICogYGN0aWRgLWluLXN1YnF1ZXJ5IExJTUlUIHNvIGVhY2ggc3RhdGVtZW50IHRvdWNoZXMgYXQgbW9zdCBgYmF0Y2hTaXplYCByb3dzXG4gICAqIChzaG9ydCBsb2NrIHdpbmRvd3MsIG5vIGxvbmcgdGFibGUgc2NhbiB1bmRlciBsb2NrKTsgYFJFVFVSTklORyAxYCBsZXRzIHVzXG4gICAqIGNvdW50IHZpYSBgLnJvd3MubGVuZ3RoYCB3aXRob3V0IGRlcGVuZGluZyBvbiB0aGUgZHJpdmVyJ3MgYHJvd0NvdW50YC4gTG9vcHNcbiAgICogdW50aWwgYSBzaG9ydCBiYXRjaCAoZHJhaW5lZCkgb3IgdGhlIHBlci10aWNrIGNhcCwgdGhlbiBkZWZlcnMgdGhlIHJlc3QuXG4gICAqIE1VU1QgcnVuIGluc2lkZSBhIHN5c2FkbWluIHRlbmFudCBzY29wZSAoc2VlIHB1cmdlRXhwaXJlZFJlcG9ydGluZ0RhdGEpIHNvIGl0XG4gICAqIGJ5cGFzc2VzIFJMUyBhbmQgY2FuIGRlbGV0ZSBhY3Jvc3MgdGhlIG9yZydzIHJvd3MuXG4gICAqL1xuICBhc3luYyAjcHVyZ2VSZXBvcnRpbmdUYWJsZUJhdGNoZWQoXG4gICAgdGFibGVTcWw6IFJldHVyblR5cGU8dHlwZW9mIHNxbD4sXG4gICAgcHJlZGljYXRlOiBSZXR1cm5UeXBlPHR5cGVvZiBzcWw+LFxuICAgIGJhdGNoU2l6ZTogbnVtYmVyLFxuICAgIG1heEJhdGNoZXM6IG51bWJlcixcbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBsZXQgdG90YWwgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF4QmF0Y2hlczsgaSsrKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgREVMRVRFIEZST00gJHt0YWJsZVNxbH1cbiAgICAgICAgV0hFUkUgY3RpZCBJTiAoXG4gICAgICAgICAgU0VMRUNUIGN0aWQgRlJPTSAke3RhYmxlU3FsfVxuICAgICAgICAgIFdIRVJFICR7cHJlZGljYXRlfVxuICAgICAgICAgIExJTUlUICR7YmF0Y2hTaXplfVxuICAgICAgICApXG4gICAgICAgIFJFVFVSTklORyAxXG4gICAgICBgKSk7XG4gICAgICBjb25zdCBwdXJnZWQgPSBkcml6emxlUm93czx1bmtub3duPihyZXMucm93cykubGVuZ3RoO1xuICAgICAgdG90YWwgKz0gcHVyZ2VkO1xuICAgICAgaWYgKHB1cmdlZCA8IGJhdGNoU2l6ZSkgYnJlYWs7IC8vIGRyYWluZWRcbiAgICAgIGlmIChpID09PSBtYXhCYXRjaGVzIC0gMSkge1xuICAgICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIHJldGVudGlvbiBoaXQgcGVyLXRpY2sgY2FwOyByZW1haW5pbmcgcm93cyBkZWZlcnJlZCcsIHtcbiAgICAgICAgICBwdXJnZWRUaGlzVGljazogdG90YWwsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdG90YWw7XG4gIH1cblxuICAvKipcbiAgICogUmVwb3J0aW5nIHJldGVudGlvbiBzd2VlcC4gSGFyZC1kZWxldGVzIHJvd3Mgb2xkZXIgdGhhbiB0aGVpclxuICAgKiByZXRlbnRpb24gd2luZG93LCBieSBgY3JlYXRlZF9hdGAsIGFjcm9zcyBldmVyeSBvcmcgdGhhdCBoYXMgcmVwb3J0aW5nIGRhdGEg4oCUXG4gICAqIGEgKipzcGxpdCoqIHBvbGljeSBzbyBoaWdoLXZvbHVtZSBzdGFuZGFyZCBldmVudHMgZXhwaXJlIGZhc3RlciB0aGFuIHRoZVxuICAgKiBsb3ctdm9sdW1lIERPUkEgc291cmNlOlxuICAgKiAgLSBgcGlwZWxpbmVfZXZlbnRzIFdIRVJFIGVudmlyb25tZW50IElTIE5VTExgIOKGkiBzdGFuZGFyZC1ldmVudCB3aW5kb3cuXG4gICAqICAtIGBwaXBlbGluZV9ldmVudHMgV0hFUkUgZW52aXJvbm1lbnQgSVMgTk9UIE5VTExgIChkZXBsb3kgc3RhZ2VzKSxcbiAgICogICAgYGRlcGxveW1lbnRfb3V0Y29tZXNgLCBhbmQgYGluY2lkZW50c2Ag4oaSIERPUkEtc291cmNlIHdpbmRvdy5cbiAgICogRWFjaCBvcmcncyB3aW5kb3dzIGNvbWUgZnJvbSBpdHMgYGRvcmFfc2V0dGluZ3NgIG92ZXJyaWRlLCBlbHNlIHRoZSBnbG9iYWxcbiAgICogZW52IGRlZmF1bHRzIChzZWUge0BsaW5rIHJlc29sdmVFdmVudFJldGVudGlvbkRheXN9IC8ge0BsaW5rIHJlc29sdmVEb3JhUmV0ZW50aW9uRGF5c30pLlxuICAgKiBgaW5nZXN0X2hlYWx0aGAgYW5kIGBkb3JhX3NldHRpbmdzYCBhcmUgbmV2ZXIgcHVyZ2VkLiBPbmUgYG5vd2AgZm9yIHRoZSB3aG9sZVxuICAgKiB0aWNrIChyb3dzIGNyb3NzaW5nIHRoZSBib3VuZGFyeSBtaWQtc3dlZXAgd2FpdCBmb3IgdGhlIG5leHQpLiBFc3RhYmxpc2hlcyBhXG4gICAqIHN5c2FkbWluIHRlbmFudCBzY29wZSBzbyB0aGUgZGVsZXRlcyBzcGFuIGFsbCBvcmdzIC8gYnlwYXNzIFJMUyDigJQgdGhpcyBpcyBhXG4gICAqIGNyb3NzLXRlbmFudCBob3VzZWtlZXBpbmcgam9iLiBSZXR1cm5zIChhbmQgbG9ncykgcGVyLXdpbmRvdyBwdXJnZSB0YWxsaWVzLlxuICAgKi9cbiAgYXN5bmMgcHVyZ2VFeHBpcmVkUmVwb3J0aW5nRGF0YShvcHRzOiBSZXBvcnRpbmdSZXRlbnRpb25PcHRpb25zID0ge30pOiBQcm9taXNlPFJlcG9ydGluZ1JldGVudGlvbkNvdW50cz4ge1xuICAgIGNvbnN0IGJhdGNoU2l6ZSA9IE1hdGgubWF4KDEsIG9wdHMuYmF0Y2hTaXplID8/IDEwMDApO1xuICAgIGNvbnN0IG1heEJhdGNoZXMgPSBNYXRoLm1heCgxLCBvcHRzLm1heEJhdGNoZXNQZXJUYWJsZSA/PyA1MCk7XG4gICAgY29uc3Qgbm93ID0gb3B0cy5ub3cgPz8gbmV3IERhdGUoKTtcbiAgICBjb25zdCByZXNvbHZlUmV0ZW50aW9uT3JnSWQgPSBvcHRzLnJlc29sdmVSZXRlbnRpb25PcmdJZCA/PyAoYXN5bmMgKG9yZ0lkOiBzdHJpbmcpID0+IG9yZ0lkKTtcbiAgICBjb25zdCBjb3VudHM6IFJlcG9ydGluZ1JldGVudGlvbkNvdW50cyA9IHtcbiAgICAgIG9yZ3M6IDAsIHN0YW5kYXJkRXZlbnRzOiAwLCBkb3JhRXZlbnRzOiAwLCBkZXBsb3ltZW50T3V0Y29tZXM6IDAsIGluY2lkZW50czogMCxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIEVudW1lcmF0ZSBldmVyeSBvcmcgd2l0aCByZXBvcnRpbmcgZGF0YSAodW5pb24gYWNyb3NzIHRoZSB0aHJlZSB0YWJsZXMpLlxuICAgICAgY29uc3Qgb3JnUm93cyA9IGRyaXp6bGVSb3dzPHsgb3JnX2lkOiBzdHJpbmcgfT4oKGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1QgRElTVElOQ1Qgb3JnX2lkIEZST00gKFxuICAgICAgICAgIFNFTEVDVCAke3NjaGVtYS5waXBlbGluZUV2ZW50Lm9yZ0lkfSBBUyBvcmdfaWQgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fVxuICAgICAgICAgIFVOSU9OXG4gICAgICAgICAgU0VMRUNUICR7c2NoZW1hLmRlcGxveW1lbnRPdXRjb21lLm9yZ0lkfSBBUyBvcmdfaWQgRlJPTSAke3NjaGVtYS5kZXBsb3ltZW50T3V0Y29tZX1cbiAgICAgICAgICBVTklPTlxuICAgICAgICAgIFNFTEVDVCAke3NjaGVtYS5pbmNpZGVudC5vcmdJZH0gQVMgb3JnX2lkIEZST00gJHtzY2hlbWEuaW5jaWRlbnR9XG4gICAgICAgICkgQVMgb3Jnc1xuICAgICAgYCkpKS5yb3dzKTtcbiAgICAgIGlmIChvcmdSb3dzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGNvdW50cztcblxuICAgICAgLy8gUGVyLW9yZyByZXRlbnRpb24gb3ZlcnJpZGVzIChhIHNpbmdsZSByZWFkOyBvcmdzIHdpdGhvdXQgYSByb3cgdXNlIGRlZmF1bHRzKS5cbiAgICAgIGNvbnN0IG92ZXJyaWRlUm93cyA9IGRyaXp6bGVSb3dzPHtcbiAgICAgICAgb3JnX2lkOiBzdHJpbmc7XG4gICAgICAgIGV2ZW50X3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgICAgICBkb3JhX3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgICAgfT4oKGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1QgJHtzY2hlbWEuZG9yYVNldHRpbmdzLm9yZ0lkfSBBUyBvcmdfaWQsXG4gICAgICAgICAgICAgICAke3NjaGVtYS5kb3JhU2V0dGluZ3MuZXZlbnRSZXRlbnRpb25EYXlzfSBBUyBldmVudF9yZXRlbnRpb25fZGF5cyxcbiAgICAgICAgICAgICAgICR7c2NoZW1hLmRvcmFTZXR0aW5ncy5kb3JhUmV0ZW50aW9uRGF5c30gQVMgZG9yYV9yZXRlbnRpb25fZGF5c1xuICAgICAgICBGUk9NICR7c2NoZW1hLmRvcmFTZXR0aW5nc31cbiAgICAgIGApKSkucm93cyk7XG4gICAgICBjb25zdCBvdmVycmlkZXMgPSBuZXcgTWFwKG92ZXJyaWRlUm93cy5tYXAoKHIpID0+IFtyLm9yZ19pZCwgcl0pKTtcblxuICAgICAgY29uc3QgZXZlbnRzVGFibGUgPSBzcWxgJHtzY2hlbWEucGlwZWxpbmVFdmVudH1gO1xuICAgICAgY29uc3Qgb3V0Y29tZXNUYWJsZSA9IHNxbGAke3NjaGVtYS5kZXBsb3ltZW50T3V0Y29tZX1gO1xuICAgICAgY29uc3QgaW5jaWRlbnRzVGFibGUgPSBzcWxgJHtzY2hlbWEuaW5jaWRlbnR9YDtcblxuICAgICAgZm9yIChjb25zdCB7IG9yZ19pZDogb3JnSWQgfSBvZiBvcmdSb3dzKSB7XG4gICAgICAgIC8vIFJldGVudGlvbiBmb2xsb3dzIHRoZSBhY2NvdW50IFJPT1QncyBlbnRpdGxlbWVudCAoYmlsbGluZyBzeW5jcyBpdCBvbnRvXG4gICAgICAgIC8vIHRoZSByb290IG9ubHkpLiBBbiB1bnJlc29sdmFibGUgcm9vdCDih5Igc2tpcCB0aGlzIG9yZyB0aGlzIHRpY2sgcmF0aGVyXG4gICAgICAgIC8vIHRoYW4gcHVyZ2UgYSB0ZWFtJ3Mgcm93cyBvbiB0aGUgKHNob3J0ZXIpIGVudiBkZWZhdWx0LlxuICAgICAgICBsZXQgcmV0ZW50aW9uT3JnSWQ6IHN0cmluZyB8IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0ZW50aW9uT3JnSWQgPSBhd2FpdCByZXNvbHZlUmV0ZW50aW9uT3JnSWQob3JnSWQpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIHJldGVudGlvbjogcm9vdCByZXNvbHV0aW9uIHRocmV3OyBza2lwcGluZyBvcmcgdGhpcyB0aWNrJywgeyBvcmdJZCwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgICAgICAgIHJldGVudGlvbk9yZ0lkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmV0ZW50aW9uT3JnSWQgPT09IG51bGwpIHtcbiAgICAgICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIHJldGVudGlvbjogY291bGQgbm90IHJlc29sdmUgdGhlIHJldGVudGlvbiByb290OyBvcmcgc2tpcHBlZCB0aGlzIHRpY2snLCB7IG9yZ0lkIH0pO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG92ID0gb3ZlcnJpZGVzLmdldChyZXRlbnRpb25PcmdJZCk7XG4gICAgICAgIGNvbnN0IGV2ZW50RGF5cyA9IHJlc29sdmVFdmVudFJldGVudGlvbkRheXMob3Y/LmV2ZW50X3JldGVudGlvbl9kYXlzKTtcbiAgICAgICAgY29uc3QgZG9yYURheXMgPSByZXNvbHZlRG9yYVJldGVudGlvbkRheXMob3Y/LmRvcmFfcmV0ZW50aW9uX2RheXMpO1xuICAgICAgICAvLyBgLTFgID0gdW5saW1pdGVkOiBrZWVwIGZvcmV2ZXIsIHNraXAgdGhhdCB3aW5kb3cncyBkZWxldGVzIGZvclxuICAgICAgICAvLyB0aGlzIG9yZy4gU3RhbmRhcmQtZXZlbnQgYW5kIERPUkEtc291cmNlIHdpbmRvd3MgYXJlIGluZGVwZW5kZW50OyBhbiBvcmdcbiAgICAgICAgLy8gd2l0aCBib3RoIGAtMWAgaXMgZnVsbHkgc2tpcHBlZC4gTG9nIHRoZSBza2lwIHNvIGl0J3Mgb2JzZXJ2YWJsZS5cbiAgICAgICAgY29uc3Qgc2tpcEV2ZW50cyA9IGV2ZW50RGF5cyA9PT0gLTE7XG4gICAgICAgIGNvbnN0IHNraXBEb3JhID0gZG9yYURheXMgPT09IC0xO1xuICAgICAgICBpZiAoc2tpcEV2ZW50cyB8fCBza2lwRG9yYSkge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKCdSZXBvcnRpbmcgcmV0ZW50aW9uIHN3ZWVwIHNraXBwaW5nIHVubGltaXRlZCB3aW5kb3cocyknLCB7XG4gICAgICAgICAgICBvcmdJZCxcbiAgICAgICAgICAgIHN0YW5kYXJkRXZlbnRzOiBza2lwRXZlbnRzID8gJ3VubGltaXRlZCcgOiBldmVudERheXMsXG4gICAgICAgICAgICBkb3JhU291cmNlOiBza2lwRG9yYSA/ICd1bmxpbWl0ZWQnIDogZG9yYURheXMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXNraXBFdmVudHMpIHtcbiAgICAgICAgICBjb25zdCBldmVudEN1dG9mZiA9IHJldGVudGlvbkN1dG9mZihub3csIGV2ZW50RGF5cyk7XG4gICAgICAgICAgY291bnRzLnN0YW5kYXJkRXZlbnRzICs9IGF3YWl0IHRoaXMuI3B1cmdlUmVwb3J0aW5nVGFibGVCYXRjaGVkKFxuICAgICAgICAgICAgZXZlbnRzVGFibGUsXG4gICAgICAgICAgICAvLyBTcGFyZSByb3dzIGNhcnJ5aW5nIGEgY29tbWl0IHRpbWVzdGFtcDogdGhleSBhcmUgRE9SQSBTT1VSQ0UgZGF0YS5cbiAgICAgICAgICAgIC8vIExlYWQgdGltZSBqb2lucyBkZXBsb3lzIHRvIHRoZSBleGVjdXRpb24ncyBlYXJsaWVzdFxuICAgICAgICAgICAgLy8gYGNvbW1pdF90aW1lc3RhbXBgLCBhbmQgdGhhdCBlbnJpY2htZW50IHJpZGVzIHRoZSBQSVBFTElORS9zb3VyY2VcbiAgICAgICAgICAgIC8vIGV2ZW50IChlbnZpcm9ubWVudCBJUyBOVUxMKSwgbmV2ZXIgdGhlIGRlcGxveSBTVEFHRSByb3cuIFB1cmdpbmdcbiAgICAgICAgICAgIC8vIHRoZW0gb24gdGhpcyBzaG9ydCB3aW5kb3cgd2hpbGUgdGhlIGRlcGxveXMgdGhleSBleHBsYWluIGxpdmUgb25cbiAgICAgICAgICAgIC8vIHRoZSBET1JBIHdpbmRvdyBtYWRlIGxlYWQgdGltZSByZWFkIFwidW5rbm93blwiIGZvciBldmVyeSByYW5nZVxuICAgICAgICAgICAgLy8gb2xkZXIgdGhhbiB0aGUgc3RhbmRhcmQgcmV0ZW50aW9uIOKAlCBzaWxlbnRseSwgd2l0aCB0aGUgZGVwbG95c1xuICAgICAgICAgICAgLy8gc3RpbGwgY291bnRlZC4gVGhleSBmb2xsb3cgdGhlIERPUkEgd2luZG93IGJlbG93IGluc3RlYWQuXG4gICAgICAgICAgICBzcWxgb3JnX2lkID0gJHtvcmdJZH0gQU5EIGVudmlyb25tZW50IElTIE5VTEwgQU5EIGNvbW1pdF90aW1lc3RhbXAgSVMgTlVMTCBBTkQgY3JlYXRlZF9hdCA8ICR7ZXZlbnRDdXRvZmZ9YCxcbiAgICAgICAgICAgIGJhdGNoU2l6ZSwgbWF4QmF0Y2hlcyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFza2lwRG9yYSkge1xuICAgICAgICAgIGNvbnN0IGRvcmFDdXRvZmYgPSByZXRlbnRpb25DdXRvZmYobm93LCBkb3JhRGF5cyk7XG4gICAgICAgICAgY291bnRzLmRvcmFFdmVudHMgKz0gYXdhaXQgdGhpcy4jcHVyZ2VSZXBvcnRpbmdUYWJsZUJhdGNoZWQoXG4gICAgICAgICAgICBldmVudHNUYWJsZSxcbiAgICAgICAgICAgIHNxbGBvcmdfaWQgPSAke29yZ0lkfSBBTkQgKGVudmlyb25tZW50IElTIE5PVCBOVUxMIE9SIGNvbW1pdF90aW1lc3RhbXAgSVMgTk9UIE5VTEwpIEFORCBjcmVhdGVkX2F0IDwgJHtkb3JhQ3V0b2ZmfWAsXG4gICAgICAgICAgICBiYXRjaFNpemUsIG1heEJhdGNoZXMsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb3VudHMuZGVwbG95bWVudE91dGNvbWVzICs9IGF3YWl0IHRoaXMuI3B1cmdlUmVwb3J0aW5nVGFibGVCYXRjaGVkKFxuICAgICAgICAgICAgb3V0Y29tZXNUYWJsZSxcbiAgICAgICAgICAgIHNxbGBvcmdfaWQgPSAke29yZ0lkfSBBTkQgY3JlYXRlZF9hdCA8ICR7ZG9yYUN1dG9mZn1gLFxuICAgICAgICAgICAgYmF0Y2hTaXplLCBtYXhCYXRjaGVzLFxuICAgICAgICAgICk7XG4gICAgICAgICAgY291bnRzLmluY2lkZW50cyArPSBhd2FpdCB0aGlzLiNwdXJnZVJlcG9ydGluZ1RhYmxlQmF0Y2hlZChcbiAgICAgICAgICAgIGluY2lkZW50c1RhYmxlLFxuICAgICAgICAgICAgc3FsYG9yZ19pZCA9ICR7b3JnSWR9IEFORCBjcmVhdGVkX2F0IDwgJHtkb3JhQ3V0b2ZmfWAsXG4gICAgICAgICAgICBiYXRjaFNpemUsIG1heEJhdGNoZXMsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBjb3VudHMub3JncyArPSAxO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwdXJnZWRBbnkgPSBjb3VudHMuc3RhbmRhcmRFdmVudHMgKyBjb3VudHMuZG9yYUV2ZW50cyArIGNvdW50cy5kZXBsb3ltZW50T3V0Y29tZXMgKyBjb3VudHMuaW5jaWRlbnRzO1xuICAgICAgaWYgKHB1cmdlZEFueSA+IDApIGxvZ2dlci5pbmZvKCdSZXBvcnRpbmcgcmV0ZW50aW9uIHN3ZWVwIHB1cmdlZCBleHBpcmVkIHJvd3MnLCB7IC4uLmNvdW50cyB9KTtcbiAgICAgIHJldHVybiBjb3VudHM7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHJlcG9ydGluZ1NlcnZpY2UgPSBuZXcgUmVwb3J0aW5nU2VydmljZSgpO1xuIl19