@pipeline-builder/pipeline-data 4.3.11 → 4.3.12

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.
@@ -13,6 +13,7 @@ import { invalidateOrgReports } from './caches.js';
13
13
  import { upsertDeployments } from './deploy-rollup.js';
14
14
  import { classifyFailure } from './failure-classifier.js';
15
15
  import { scrubOptional } from './sql-helpers.js';
16
+ import { deployedToolchainOf, readPlatformDefaultRelease, SELF_MUTATION_ACTION, SELF_MUTATION_STAGE, toolchainActionOf, toolchainOutcomeOf, } from './toolchain-runs.js';
16
17
  import { schema } from '../../database/drizzle-schema.js';
17
18
  import { withTenantTx } from '../../database/tenancy.js';
18
19
  const logger = createLogger('reporting-ingest');
@@ -26,14 +27,18 @@ function stepKey(pipelineId, stageName, actionName) {
26
27
  return `${pipelineId}\u0000${stageName}\u0000${actionName}`;
27
28
  }
28
29
  /**
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).
30
+ * Plugin attribution AND the deployed toolchain release: the step manifests of
31
+ * every pipeline with an attributable event, in ONE read per batch, keyed for
32
+ * an in-memory join. Names are compared post-scrub on both sides (the manifest
33
+ * stores them scrubbed the same way).
34
+ *
35
+ * The toolchain map is the PLATFORM's record of what was deployed (the
36
+ * manifest's `build-image` entry) — the only source the §7 run stamp may use.
32
37
  */
33
38
  async function loadStepPlugins(tx, attributable) {
34
39
  const pipelineIds = [...new Set(attributable.map((e) => e.pipelineId))];
35
40
  if (pipelineIds.length === 0)
36
- return new Map();
41
+ return { steps: new Map(), toolchain: new Map() };
37
42
  const rows = await tx
38
43
  .select({
39
44
  pipelineId: schema.pipelineStepManifest.pipelineId,
@@ -44,10 +49,14 @@ async function loadStepPlugins(tx, attributable) {
44
49
  pluginPublisherId: schema.pipelineStepManifest.pluginPublisherId,
45
50
  pluginName: schema.pipelineStepManifest.pluginName,
46
51
  pluginVersion: schema.pipelineStepManifest.pluginVersion,
52
+ stepKey: schema.pipelineStepManifest.stepKey,
47
53
  })
48
54
  .from(schema.pipelineStepManifest)
49
55
  .where(inArray(schema.pipelineStepManifest.pipelineId, pipelineIds));
50
- return new Map(rows.map((m) => [stepKey(m.pipelineId, m.stageName, m.actionName), m]));
56
+ return {
57
+ steps: new Map(rows.map((m) => [stepKey(m.pipelineId, m.stageName, m.actionName), m])),
58
+ toolchain: deployedToolchainOf(rows),
59
+ };
51
60
  }
52
61
  /**
53
62
  * Allowance for clock skew between an AWS event's source clock and ours. A real
@@ -104,7 +113,7 @@ function pbFailureCode(detail) {
104
113
  const code = failure && typeof failure === 'object' ? failure.code : undefined;
105
114
  return typeof code === 'string' && /^[A-Z][A-Z0-9_]{0,63}$/.test(code) ? code : null;
106
115
  }
107
- function toEventRow(event, registry, plugin, keyId) {
116
+ function toEventRow(event, registry, plugin, keyId, toolchainRelease) {
108
117
  const detail = event.sourceMessageId !== undefined
109
118
  ? { ...(event.detail ?? {}), sourceMessageId: event.sourceMessageId }
110
119
  : event.detail;
@@ -142,6 +151,9 @@ function toEventRow(event, registry, plugin, keyId) {
142
151
  pluginPublisherId: plugin?.pluginPublisherId ?? null,
143
152
  pluginName: plugin?.pluginName ?? null,
144
153
  pluginVersion: plugin?.pluginVersion ?? null,
154
+ // The managed toolchain release a synth / self-mutation action ran on, from
155
+ // the platform's deployed manifest (never the payload). NULL otherwise.
156
+ toolchainRelease,
145
157
  // WHAT KIND of thing broke, classified here rather than at read time: the
146
158
  // error text is scrubbed above and eventually swept by retention, so a
147
159
  // category derived later would have nothing left to read. NULL for anything
@@ -174,10 +186,23 @@ function toEventRow(event, registry, plugin, keyId) {
174
186
  *
175
187
  * A non-null environment marks a deploy.
176
188
  */
177
- function emitIngestMetrics(rows, onMetric) {
189
+ function emitIngestMetrics(rows, onMetric, platformDefaultRelease) {
178
190
  for (const r of rows) {
179
191
  if (!r.pipelineId)
180
192
  continue;
193
+ // Toolchain runs (§7, alerting only): a terminal outcome on a stamped row.
194
+ // Not exclusive — the same action is also a compute measurement below.
195
+ const outcome = r.toolchainRelease ? toolchainOutcomeOf(r.status) : null;
196
+ if (r.toolchainRelease && outcome) {
197
+ onMetric({
198
+ kind: 'toolchain',
199
+ toolchainRelease: r.toolchainRelease,
200
+ // Stamped rows are only ever synth or self-mutation.
201
+ action: r.stageName === SELF_MUTATION_STAGE && r.actionName === SELF_MUTATION_ACTION ? 'self-mutation' : 'synth',
202
+ outcome,
203
+ platformDefaultRelease,
204
+ });
205
+ }
181
206
  // Compute consumption: every TERMINAL action, measurable or not. The
182
207
  // unmeasurable ones are the point — they are what the coverage ratio counts.
183
208
  if (r.eventType === 'ACTION' && TERMINAL_ACTION_STATES.includes(r.status)) {
@@ -239,7 +264,7 @@ export async function ingestEvents(events, onMetric, caller) {
239
264
  // Caches are invalidated AFTER the tx resolves: doing it inside held the pg
240
265
  // locks open across unrelated cache round-trips. The TTL is 2-5 min, so a
241
266
  // fire-and-forget post-commit invalidation is an acceptable trade.
242
- const { inserted, skipped, unregisteredPipelineIds, affectedOrgs, droppedForeignOrg, droppedInvalidTime, foreignPipelineIds, insertedRows } = await withTenantTx(async (tx) => {
267
+ const { inserted, skipped, unregisteredPipelineIds, affectedOrgs, droppedForeignOrg, droppedInvalidTime, foreignPipelineIds, insertedRows, platformDefaultRelease } = await withTenantTx(async (tx) => {
243
268
  // Batch-resolve all unique pipeline ids in one query
244
269
  const uniqueIds = [...new Set(events.map(e => e.pipelineId))];
245
270
  const registryRows = await tx
@@ -250,7 +275,7 @@ export async function ingestEvents(events, onMetric, caller) {
250
275
  .from(schema.pipelineRegistry)
251
276
  .where(inArray(schema.pipelineRegistry.pipelineId, uniqueIds));
252
277
  const idMap = new Map(registryRows.map(r => [r.pipelineId, r]));
253
- const stepPlugins = await loadStepPlugins(tx, events.filter((e) => isAttributable(e) && idMap.has(e.pipelineId)));
278
+ const { steps: stepPlugins, toolchain } = await loadStepPlugins(tx, events.filter((e) => isAttributable(e) && idMap.has(e.pipelineId)));
254
279
  // Build insert batch (skip events whose pipeline isn't registered)
255
280
  const rows = [];
256
281
  let skippedLocal = 0;
@@ -292,9 +317,16 @@ export async function ingestEvents(events, onMetric, caller) {
292
317
  const step = isAttributable(event) && stageName && actionName
293
318
  ? stepPlugins.get(stepKey(registry.pipelineId, stageName, actionName))
294
319
  : undefined;
320
+ // The toolchain stamp: is this the pipeline's synth / self-mutation
321
+ // action, and which release did the platform deploy it with?
322
+ const deployed = toolchain.get(registry.pipelineId);
323
+ const sameOrgDeployed = deployed && deployed.orgId === registry.orgId ? deployed : undefined;
324
+ const toolchainRelease = toolchainActionOf({ eventType: event.eventType, stageName, actionName }, sameOrgDeployed)
325
+ ? sameOrgDeployed.releaseVersion
326
+ : null;
295
327
  // Same-org guard: a manifest row is only ever written by the org that
296
328
  // owns the pipeline, but the ingest runs cross-tenant, so don't lean on it.
297
- rows.push(toEventRow(event, registry, step && step.orgId === registry.orgId ? step : undefined, caller?.keyId));
329
+ rows.push(toEventRow(event, registry, step && step.orgId === registry.orgId ? step : undefined, caller?.keyId, toolchainRelease));
298
330
  }
299
331
  // SQS is at-least-once, so EventBridge can deliver the same state-change
300
332
  // twice. `onConflictDoNothing` + the partial unique indexes on
@@ -311,7 +343,9 @@ export async function ingestEvents(events, onMetric, caller) {
311
343
  eventType: schema.pipelineEvent.eventType,
312
344
  status: schema.pipelineEvent.status,
313
345
  stageName: schema.pipelineEvent.stageName,
346
+ actionName: schema.pipelineEvent.actionName,
314
347
  environment: schema.pipelineEvent.environment,
348
+ toolchainRelease: schema.pipelineEvent.toolchainRelease,
315
349
  // For the per-deploy rollup below: everything `dora_deployments` needs,
316
350
  // taken from the rows that ACTUALLY landed so a re-delivery cannot
317
351
  // produce a second deploy.
@@ -342,7 +376,13 @@ export async function ingestEvents(events, onMetric, caller) {
342
376
  reasons: [...invalidTimeReasons],
343
377
  });
344
378
  }
379
+ // The platform default, for the alert's baseline gauge — read only when a
380
+ // toolchain run landed, so ordinary batches pay nothing.
381
+ const defaultRelease = landed.some((r) => r.toolchainRelease)
382
+ ? await readPlatformDefaultRelease(tx)
383
+ : null;
345
384
  return {
385
+ platformDefaultRelease: defaultRelease,
346
386
  inserted: landed.length,
347
387
  skipped: skippedLocal,
348
388
  unregisteredPipelineIds: unregisteredLocal,
@@ -354,7 +394,7 @@ export async function ingestEvents(events, onMetric, caller) {
354
394
  };
355
395
  });
356
396
  if (onMetric)
357
- emitIngestMetrics(insertedRows, onMetric);
397
+ emitIngestMetrics(insertedRows, onMetric, platformDefaultRelease);
358
398
  // Per-deploy rollup. AFTER the events commit and outside their transaction: the
359
399
  // events are the durable record and `dora_deployments` is derived from them, so
360
400
  // a rollup failure must not roll back an ingest that succeeded. Rebuildable
@@ -389,4 +429,4 @@ export async function ingestEvents(events, onMetric, caller) {
389
429
  insertedPipelineIds: [...new Set(insertedRows.map((r) => r.pipelineId).filter((id) => !!id))],
390
430
  };
391
431
  }
392
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5nZXN0LmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBpL3JlcG9ydGluZy9pbmdlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3RJLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFakQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQzFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUd6RCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQWNoRCxxRUFBcUU7QUFDckUsU0FBUyxjQUFjLENBQUMsQ0FBYztJQUNwQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsS0FBSyxRQUFRLElBQUksQ0FBQyxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUM7V0FDdkQsQ0FBQyxDQUFDLENBQUMsV0FBVyxLQUFLLGNBQWMsSUFBSSxDQUFDLENBQUMsV0FBVyxLQUFLLFdBQVcsQ0FBQztXQUNuRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztBQUN2QyxDQUFDO0FBRUQsU0FBUyxPQUFPLENBQUMsVUFBa0IsRUFBRSxTQUFpQixFQUFFLFVBQWtCO0lBQ3hF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LEdBQUcsRUFBRSxLQUFLLEVBQUUsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMvRixDQUFDLENBQUMsQ0FDSCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBTztRQUNMLFFBQVE7UUFDUixPQUFPO1FBQ1AsdUJBQXVCO1FBQ3ZCLFlBQVk7UUFDWixpQkFBaUI7UUFDakIsa0JBQWtCO1FBQ2xCLGtCQUFrQjtRQUNsQixvQkFBb0IsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzdHLG1CQUFtQixFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFnQixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7S0FDNUcsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBFdmVudCBpbmdlc3Q6IHRoZSBXUklURSBoYWxmIG9mIHJlcG9ydGluZy4gUmVzb2x2ZXMgaW5jb21pbmcgcGlwZWxpbmUgZXZlbnRzXG4gKiBhZ2FpbnN0IHRoZSBwaXBlbGluZSByZWdpc3RyeSwgc2NydWJzIGV2ZXJ5IGZyZWUtZm9ybSBzdHJpbmcsIGJhdGNoLWluc2VydHNcbiAqIHRoZSBtYXRjaGVkIHJvd3MgaWRlbXBvdGVudGx5LCBhbmQgaW52YWxpZGF0ZXMgdGhlIGFmZmVjdGVkIG9yZ3MnIHJlcG9ydFxuICogY2FjaGVzLiBTZXBhcmF0ZSBmcm9tIHRoZSByZXBvcnQgcXVlcmllcyBiZWNhdXNlIHRoaXMgaXMgcmVwb3J0aW5nJ3Mgb25seVxuICogZHVyYWJsZSBwZXJzaXN0ZW5jZSBib3VuZGFyeSDigJQgZXZlcnl0aGluZyBlbHNlIGluIHRoZSBzZXJ2aWNlIG9ubHkgcmVhZHMuXG4gKi9cblxuaW1wb3J0IHsgY29tcHV0ZUNyZWRpdHNGb3IsIGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlLCBub3JtYWxpemVDb21wdXRlVHlwZSwgc2NydWJBd3NJZGVudGlmaWVycyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGluQXJyYXkgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgeyBpbnZhbGlkYXRlT3JnUmVwb3J0cyB9IGZyb20gJy4vY2FjaGVzLmpzJztcbmltcG9ydCB7IHVwc2VydERlcGxveW1lbnRzIH0gZnJvbSAnLi9kZXBsb3ktcm9sbHVwLmpzJztcbmltcG9ydCB7IGNsYXNzaWZ5RmFpbHVyZSB9IGZyb20gJy4vZmFpbHVyZS1jbGFzc2lmaWVyLmpzJztcbmltcG9ydCB7IHNjcnViT3B0aW9uYWwgfSBmcm9tICcuL3NxbC1oZWxwZXJzLmpzJztcbmltcG9ydCB0eXBlIHsgSW5nZXN0Q2FsbGVyLCBJbmdlc3RFdmVudCwgSW5nZXN0TWV0cmljLCBJbmdlc3RSZXN1bHQgfSBmcm9tICcuL3R5cGVzLmpzJztcbmltcG9ydCB7IHNjaGVtYSB9IGZyb20gJy4uLy4uL2RhdGFiYXNlL2RyaXp6bGUtc2NoZW1hLmpzJztcbmltcG9ydCB7IHdpdGhUZW5hbnRUeCB9IGZyb20gJy4uLy4uL2RhdGFiYXNlL3RlbmFuY3kuanMnO1xuaW1wb3J0IHR5cGUgeyBDcnVkVHggfSBmcm9tICcuLi9jcnVkLXNlcnZpY2UuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3JlcG9ydGluZy1pbmdlc3QnKTtcblxudHlwZSBQaXBlbGluZUV2ZW50SW5zZXJ0ID0gdHlwZW9mIHNjaGVtYS5waXBlbGluZUV2ZW50LiRpbmZlckluc2VydDtcblxuXG4vKiogVGhlIHBsdWdpbiBhIHBpcGVsaW5lIHN0ZXAgcnVucywgZnJvbSB0aGUgc3RlcCBtYW5pZmVzdCBpdHMgbGFzdCBkZXBsb3kgcmVnaXN0ZXJlZC4gKi9cbmludGVyZmFjZSBTdGVwUGx1Z2luIHtcbiAgb3JnSWQ6IHN0cmluZztcbiAgcGx1Z2luUHVibGlzaGVyOiBzdHJpbmcgfCBudWxsO1xuICBwbHVnaW5QdWJsaXNoZXJJZDogc3RyaW5nIHwgbnVsbDtcbiAgcGx1Z2luTmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgcGx1Z2luVmVyc2lvbjogc3RyaW5nIHwgbnVsbDtcbn1cblxuLyoqIEFuIGFjdGlvbi9idWlsZCBldmVudCB0aGF0IGNhbiBiZSBhdHRyaWJ1dGVkIHRvIGEgcGx1Z2luIHN0ZXAuICovXG5mdW5jdGlvbiBpc0F0dHJpYnV0YWJsZShlOiBJbmdlc3RFdmVudCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKGUuZXZlbnRUeXBlID09PSAnQUNUSU9OJyB8fCBlLmV2ZW50VHlwZSA9PT0gJ0JVSUxEJylcbiAgICAmJiAoZS5ldmVudFNvdXJjZSA9PT0gJ2NvZGVwaXBlbGluZScgfHwgZS5ldmVudFNvdXJjZSA9PT0gJ2NvZGVidWlsZCcpXG4gICAgJiYgISFlLnN0YWdlTmFtZSAmJiAhIWUuYWN0aW9uTmFtZTtcbn1cblxuZnVuY3Rpb24gc3RlcEtleShwaXBlbGluZUlkOiBzdHJpbmcsIHN0YWdlTmFtZTogc3RyaW5nLCBhY3Rpb25OYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7cGlwZWxpbmVJZH1cXHUwMDAwJHtzdGFnZU5hbWV9XFx1MDAwMCR7YWN0aW9uTmFtZX1gO1xufVxuXG4vKipcbiAqIFBsdWdpbiBhdHRyaWJ1dGlvbjogdGhlIHN0ZXAgbWFuaWZlc3RzIG9mIGV2ZXJ5IHBpcGVsaW5lIHdpdGggYW4gYXR0cmlidXRhYmxlXG4gKiBldmVudCwgaW4gT05FIHJlYWQgcGVyIGJhdGNoLCBrZXllZCBmb3IgYW4gaW4tbWVtb3J5IGpvaW4uIE5hbWVzIGFyZSBjb21wYXJlZFxuICogcG9zdC1zY3J1YiBvbiBib3RoIHNpZGVzICh0aGUgbWFuaWZlc3Qgc3RvcmVzIHRoZW0gc2NydWJiZWQgdGhlIHNhbWUgd2F5KS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gbG9hZFN0ZXBQbHVnaW5zKHR4OiBDcnVkVHgsIGF0dHJpYnV0YWJsZTogSW5nZXN0RXZlbnRbXSk6IFByb21pc2U8TWFwPHN0cmluZywgU3RlcFBsdWdpbj4+IHtcbiAgY29uc3QgcGlwZWxpbmVJZHMgPSBbLi4ubmV3IFNldChhdHRyaWJ1dGFibGUubWFwKChlKSA9PiBlLnBpcGVsaW5lSWQpKV07XG4gIGlmIChwaXBlbGluZUlkcy5sZW5ndGggPT09IDApIHJldHVybiBuZXcgTWFwKCk7XG4gIGNvbnN0IHJvd3MgPSBhd2FpdCB0eFxuICAgIC5zZWxlY3Qoe1xuICAgICAgcGlwZWxpbmVJZDogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBpcGVsaW5lSWQsXG4gICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0Lm9yZ0lkLFxuICAgICAgc3RhZ2VOYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3Quc3RhZ2VOYW1lLFxuICAgICAgYWN0aW9uTmFtZTogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LmFjdGlvbk5hbWUsXG4gICAgICBwbHVnaW5QdWJsaXNoZXI6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5wbHVnaW5QdWJsaXNoZXIsXG4gICAgICBwbHVnaW5QdWJsaXNoZXJJZDogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBsdWdpblB1Ymxpc2hlcklkLFxuICAgICAgcGx1Z2luTmFtZTogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBsdWdpbk5hbWUsXG4gICAgICBwbHVnaW5WZXJzaW9uOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luVmVyc2lvbixcbiAgICB9KVxuICAgIC5mcm9tKHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdClcbiAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGlwZWxpbmVJZCwgcGlwZWxpbmVJZHMpKTtcbiAgcmV0dXJuIG5ldyBNYXAocm93cy5tYXAoKG0pID0+IFtzdGVwS2V5KG0ucGlwZWxpbmVJZCwgbS5zdGFnZU5hbWUsIG0uYWN0aW9uTmFtZSksIG1dKSk7XG59XG5cbi8qKlxuICogQWxsb3dhbmNlIGZvciBjbG9jayBza2V3IGJldHdlZW4gYW4gQVdTIGV2ZW50J3Mgc291cmNlIGNsb2NrIGFuZCBvdXJzLiBBIHJlYWxcbiAqIENvZGVQaXBlbGluZSBldmVudCBjYW4gY2FycnkgYSB0aW1lc3RhbXAgYSBsaXR0bGUgYWhlYWQgb2Ygb3VyIGBub3dgOyB3aXRob3V0XG4gKiBzb21lIHRvbGVyYW5jZSB0aGUgdmFsaWRhdGlvbiBiZWxvdyB3b3VsZCBkcm9wIGhlYWx0aHkgZXZlbnRzIGR1cmluZyBub3JtYWxcbiAqIE5UUCBkcmlmdCwgd2hpY2ggaXMgZmFyIHdvcnNlIHRoYW4gYWRtaXR0aW5nIGEgZmV3IHNlY29uZHMgb2Ygc2tldy5cbiAqL1xuY29uc3QgQ0xPQ0tfU0tFV19UT0xFUkFOQ0VfTVMgPSA1ICogNjAgKiAxMDAwO1xuXG4vKipcbiAqIFdoeSB0aGlzIGV2ZW50J3MgdGltZXN0YW1wcyBhcmUgaW1wb3NzaWJsZSwgb3IgbnVsbCB3aGVuIHRoZXkgYXJlIHVzYWJsZS5cbiAqXG4gKiBDaGVja2VkIGF0IElOR0VTVCDigJQgdGhlIGR1cmFibGUgYm91bmRhcnkg4oCUIHJhdGhlciB0aGFuIGNsYW1wZWQgd2hlbiB0aGUgbWV0cmljc1xuICogYXJlIGNvbXB1dGVkLiBBIG5lZ2F0aXZlIGR1cmF0aW9uIG9yIGEgZnV0dXJlIGRlcGxveSB1c2VkIHRvIGJlIGNsYW1wZWQgdG8gMFxuICogZG93bnN0cmVhbSwgd2hpY2ggcmVwb3J0ZWQgYSBicm9rZW4gY2xvY2sgYXMgYW4gaW5zdGFudCBkZXBsb3kgYW5kIHF1aWV0bHlcbiAqIG1vdmVkIGRlcGxveW1lbnQgZnJlcXVlbmN5LCBjaGFuZ2UtZmFpbHVyZSByYXRlIGFuZCBsZWFkIHRpbWUgZm9yIHRoZSBvcmcuXG4gKlxuICogTk9UIGNoZWNrZWQgaGVyZTogY29tbWl0IHRpbWUgdnMgZGVwbG95IGNvbXBsZXRpb24uIGBjb21taXRfdGltZXN0YW1wYCByaWRlcyB0aGVcbiAqIFBJUEVMSU5FL3NvdXJjZSBldmVudCB3aGlsZSB0aGUgZGVwbG95J3MgYGNvbXBsZXRlZF9hdGAgaXMgb24gYSBzZXBhcmF0ZSBTVEFHRVxuICogcm93LCBqb2luZWQgYnkgYGV4ZWN1dGlvbl9pZGAgb25seSB3aGVuIERPUkEgaXMgcXVlcmllZCDigJQgc28gbm8gc2luZ2xlIGV2ZW50XG4gKiBjYXJyaWVzIGJvdGgsIGFuZCB0aGF0IG9yZGVyaW5nIGNhbiBvbmx5IGJlIGd1YXJkZWQgd2hlcmUgdGhlIHR3byBtZWV0LlxuICovXG5mdW5jdGlvbiBpbnZhbGlkRXZlbnRUaW1lcyhldmVudDogSW5nZXN0RXZlbnQsIG5vd01zOiBudW1iZXIpOiBzdHJpbmcgfCBudWxsIHtcbiAgY29uc3QgY2VpbGluZyA9IG5vd01zICsgQ0xPQ0tfU0tFV19UT0xFUkFOQ0VfTVM7XG4gIGNvbnN0IHBhcnNlZDogQXJyYXk8W3N0cmluZywgbnVtYmVyXT4gPSBbXTtcbiAgZm9yIChjb25zdCBmaWVsZCBvZiBbJ3N0YXJ0ZWRBdCcsICdjb21wbGV0ZWRBdCcsICdjb21taXRUaW1lc3RhbXAnXSBhcyBjb25zdCkge1xuICAgIGNvbnN0IHJhdyA9IGV2ZW50W2ZpZWxkXTtcbiAgICBpZiAocmF3ID09PSB1bmRlZmluZWQgfHwgcmF3ID09PSBudWxsKSBjb250aW51ZTtcbiAgICBjb25zdCBtcyA9IERhdGUucGFyc2UoU3RyaW5nKHJhdykpO1xuICAgIGlmICghTnVtYmVyLmlzRmluaXRlKG1zKSkgcmV0dXJuIGAke2ZpZWxkfSBpcyBub3QgYSBwYXJzZWFibGUgdGltZXN0YW1wYDtcbiAgICBpZiAobXMgPiBjZWlsaW5nKSByZXR1cm4gYCR7ZmllbGR9IGlzIGluIHRoZSBmdXR1cmVgO1xuICAgIHBhcnNlZC5wdXNoKFtmaWVsZCwgbXNdKTtcbiAgfVxuICBjb25zdCBzdGFydGVkID0gcGFyc2VkLmZpbmQoKFtmXSkgPT4gZiA9PT0gJ3N0YXJ0ZWRBdCcpPy5bMV07XG4gIGNvbnN0IGNvbXBsZXRlZCA9IHBhcnNlZC5maW5kKChbZl0pID0+IGYgPT09ICdjb21wbGV0ZWRBdCcpPy5bMV07XG4gIGlmIChzdGFydGVkICE9PSB1bmRlZmluZWQgJiYgY29tcGxldGVkICE9PSB1bmRlZmluZWQgJiYgY29tcGxldGVkIDwgc3RhcnRlZCkge1xuICAgIHJldHVybiAnY29tcGxldGVkQXQgaXMgYmVmb3JlIHN0YXJ0ZWRBdCc7XG4gIH1cbiAgaWYgKGV2ZW50LmR1cmF0aW9uTXMgIT09IHVuZGVmaW5lZCAmJiBldmVudC5kdXJhdGlvbk1zICE9PSBudWxsICYmIGV2ZW50LmR1cmF0aW9uTXMgPCAwKSB7XG4gICAgcmV0dXJuICdkdXJhdGlvbk1zIGlzIG5lZ2F0aXZlJztcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBUaGUgcGVyc2lzdGVkIHJvdyBmb3Igb25lIGluZ2VzdGVkIGV2ZW50LiBUaGlzIGlzIHRoZSBEVVJBQkxFIHBlcnNpc3RlbmNlXG4gKiBib3VuZGFyeTogZXZlcnkgdXNlci9BV1MtZGVyaXZlZCBmcmVlLWZvcm0gc3RyaW5nIGlzIHNjcnViYmVkIGhlcmUsIGFuZFxuICogdGVuYW5jeSBjb21lcyBmcm9tIHRoZSBwaXBlbGluZSByZWdpc3RyeSwgbmV2ZXIgdGhlIGNhbGxlcidzIGNsYWltZWQgb3JnLlxuICovXG4vKiogVGhlIHN5bnRoIHJlZnVzYWwgY29kZSB0aGUgZXZlbnRzIExhbWJkYSBhdHRhY2hlZCAoYGRldGFpbC5wYkZhaWx1cmUuY29kZWApLCBpZiBhbnkuICovXG5mdW5jdGlvbiBwYkZhaWx1cmVDb2RlKGRldGFpbDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQpOiBzdHJpbmcgfCBudWxsIHtcbiAgY29uc3QgZmFpbHVyZSA9IGRldGFpbD8ucGJGYWlsdXJlO1xuICBjb25zdCBjb2RlID0gZmFpbHVyZSAmJiB0eXBlb2YgZmFpbHVyZSA9PT0gJ29iamVjdCcgPyAoZmFpbHVyZSBhcyB7IGNvZGU/OiB1bmtub3duIH0pLmNvZGUgOiB1bmRlZmluZWQ7XG4gIHJldHVybiB0eXBlb2YgY29kZSA9PT0gJ3N0cmluZycgJiYgL15bQS1aXVtBLVowLTlfXXswLDYzfSQvLnRlc3QoY29kZSkgPyBjb2RlIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gdG9FdmVudFJvdyhldmVudDogSW5nZXN0RXZlbnQsIHJlZ2lzdHJ5OiB7IHBpcGVsaW5lSWQ6IHN0cmluZzsgb3JnSWQ6IHN0cmluZyB9LCBwbHVnaW46IFN0ZXBQbHVnaW4gfCB1bmRlZmluZWQsIGtleUlkOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQaXBlbGluZUV2ZW50SW5zZXJ0IHtcbiAgY29uc3QgZGV0YWlsID0gZXZlbnQuc291cmNlTWVzc2FnZUlkICE9PSB1bmRlZmluZWRcbiAgICA/IHsgLi4uKGV2ZW50LmRldGFpbCA/PyB7fSksIHNvdXJjZU1lc3NhZ2VJZDogZXZlbnQuc291cmNlTWVzc2FnZUlkIH1cbiAgICA6IGV2ZW50LmRldGFpbDtcbiAgcmV0dXJuIHtcbiAgICAvLyByZWdpc3RyeS5waXBlbGluZUlkID09PSBldmVudC5waXBlbGluZUlkOyB0aGUgcmVnaXN0cnkncyBpcyBhbHdheXMgYSByb3dcbiAgICAvLyB0aGF0IGV4aXN0cyAoRkspIGFuZCBpdHMgb3JnSWQgaXMgdGhlIHRydXN0ZWQgdGVuYW50LlxuICAgIHBpcGVsaW5lSWQ6IHJlZ2lzdHJ5LnBpcGVsaW5lSWQsXG4gICAgb3JnSWQ6IHJlZ2lzdHJ5Lm9yZ0lkLFxuICAgIGV2ZW50U291cmNlOiBldmVudC5ldmVudFNvdXJjZSxcbiAgICBldmVudFR5cGU6IGV2ZW50LmV2ZW50VHlwZSxcbiAgICBzdGF0dXM6IGV2ZW50LnN0YXR1cyxcbiAgICAvLyBBbiBBV1MtQVNTSUdORUQgVVVJRCwgbm90IGZyZWUtZm9ybSB0ZXh0OiBpdCBjYW4ndCBjYXJyeSBhbiBhY2NvdW50IGlkLFxuICAgIC8vIGFuZCBzY3J1YmJpbmcgYSAxMi1kaWdpdCBydW4gaW5zaWRlIGl0IHdvdWxkIGNvcnJ1cHQgdGhlIGNvcnJlbGF0aW9uIGtleS5cbiAgICBleGVjdXRpb25JZDogZXZlbnQuZXhlY3V0aW9uSWQsXG4gICAgLy8gVVNFUi1BVVRIT1JFRCBwaXBlbGluZS1zdHJ1Y3R1cmUgbmFtZXMg4oCUIHNhbWUgdW50cnVzdGVkIG9yaWdpbiBhc1xuICAgIC8vIGVycm9yTWVzc2FnZSwgc28gc2NydWJiZWQgKGEgc3RhZ2UgbmFtZWQgd2l0aCBhbiBBUk4gbXVzdCBub3QgcGVyc2lzdCkuXG4gICAgc3RhZ2VOYW1lOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LnN0YWdlTmFtZSksXG4gICAgYWN0aW9uTmFtZTogc2NydWJPcHRpb25hbChldmVudC5hY3Rpb25OYW1lKSxcbiAgICAvLyBIQVJEIENPTlNUUkFJTlQ6IGFuIEFXUyBhY2NvdW50IGlkIG11c3QgTkVWRVIgYmUgcGVyc2lzdGVkLiBGYWlsdXJlIGRldGFpbFxuICAgIC8vIGFuZCBtZXNzYWdlcyByb3V0aW5lbHkgY2FycnkgQVJOcyBhbmQgYmFyZSAxMi1kaWdpdCBhY2NvdW50IGlkcy5cbiAgICBlcnJvck1lc3NhZ2U6IHNjcnViT3B0aW9uYWwoZXZlbnQuZXJyb3JNZXNzYWdlKSxcbiAgICBzdGFydGVkQXQ6IGV2ZW50LnN0YXJ0ZWRBdCA/IG5ldyBEYXRlKGV2ZW50LnN0YXJ0ZWRBdCkgOiB1bmRlZmluZWQsXG4gICAgY29tcGxldGVkQXQ6IGV2ZW50LmNvbXBsZXRlZEF0ID8gbmV3IERhdGUoZXZlbnQuY29tcGxldGVkQXQpIDogdW5kZWZpbmVkLFxuICAgIGR1cmF0aW9uTXM6IGV2ZW50LmR1cmF0aW9uTXMsXG4gICAgLy8gRGVwbG95IGF0dHJpYnV0aW9uIOKAlCBzY3J1YmJlZCBsaWtlIHRoZSBvdGhlciBmcmVlLWZvcm0gc3RyaW5ncy5cbiAgICBjb21taXRTaGE6IHNjcnViT3B0aW9uYWwoZXZlbnQuY29tbWl0U2hhKSxcbiAgICBjb21taXRSZWY6IHNjcnViT3B0aW9uYWwoZXZlbnQuY29tbWl0UmVmKSxcbiAgICBlbnZpcm9ubWVudDogc2NydWJPcHRpb25hbChldmVudC5lbnZpcm9ubWVudCksXG4gICAgLy8gTWVhc3VyZWQgbGVhZCB0aW1lOiB0aGUgb2xkZXN0IHVuc2hpcHBlZCBjb21taXQncyB0aW1lICsgdGhlIGNvdW50LiBBblxuICAgIC8vIFNDTS1kZXJpdmVkIGluc3RhbnQgYW5kIGEgcGxhaW4gaW50ZWdlciDigJQgbm90aGluZyB0byBzY3J1Yi5cbiAgICBjb21taXRUaW1lc3RhbXA6IGV2ZW50LmNvbW1pdFRpbWVzdGFtcCA/IG5ldyBEYXRlKGV2ZW50LmNvbW1pdFRpbWVzdGFtcCkgOiB1bmRlZmluZWQsXG4gICAgY29tbWl0Q291bnQ6IGV2ZW50LmNvbW1pdENvdW50LFxuICAgIC8vIE5VTEwgZm9yIG5vbi1wbHVnaW4gYWN0aW9ucyBhbmQgZm9yIHBpcGVsaW5lcyBkZXBsb3llZCB3aXRob3V0IGEgbWFuaWZlc3QuXG4gICAgcGx1Z2luUHVibGlzaGVyOiBwbHVnaW4/LnBsdWdpblB1Ymxpc2hlciA/PyBudWxsLFxuICAgIHBsdWdpblB1Ymxpc2hlcklkOiBwbHVnaW4/LnBsdWdpblB1Ymxpc2hlcklkID8/IG51bGwsXG4gICAgcGx1Z2luTmFtZTogcGx1Z2luPy5wbHVnaW5OYW1lID8/IG51bGwsXG4gICAgcGx1Z2luVmVyc2lvbjogcGx1Z2luPy5wbHVnaW5WZXJzaW9uID8/IG51bGwsXG4gICAgLy8gV0hBVCBLSU5EIG9mIHRoaW5nIGJyb2tlLCBjbGFzc2lmaWVkIGhlcmUgcmF0aGVyIHRoYW4gYXQgcmVhZCB0aW1lOiB0aGVcbiAgICAvLyBlcnJvciB0ZXh0IGlzIHNjcnViYmVkIGFib3ZlIGFuZCBldmVudHVhbGx5IHN3ZXB0IGJ5IHJldGVudGlvbiwgc28gYVxuICAgIC8vIGNhdGVnb3J5IGRlcml2ZWQgbGF0ZXIgd291bGQgaGF2ZSBub3RoaW5nIGxlZnQgdG8gcmVhZC4gTlVMTCBmb3IgYW55dGhpbmdcbiAgICAvLyB0aGF0IGlzIG5vdCBhIGZhaWx1cmUsIHNvIGl0cyBwcmVzZW5jZSBhbHdheXMgbWVhbnMgXCJ0aGlzIGJyb2tlXCIuXG4gICAgZmFpbHVyZUNhdGVnb3J5OiBjbGFzc2lmeUZhaWx1cmUoe1xuICAgICAgc3RhdHVzOiBldmVudC5zdGF0dXMsXG4gICAgICBlcnJvck1lc3NhZ2U6IHNjcnViT3B0aW9uYWwoZXZlbnQuZXJyb3JNZXNzYWdlKSxcbiAgICAgIGFjdGlvbk5hbWU6IHNjcnViT3B0aW9uYWwoZXZlbnQuYWN0aW9uTmFtZSksXG4gICAgICBzdGFnZU5hbWU6IHNjcnViT3B0aW9uYWwoZXZlbnQuc3RhZ2VOYW1lKSxcbiAgICAgIGZhaWx1cmVDb2RlOiBwYkZhaWx1cmVDb2RlKGV2ZW50LmRldGFpbCksXG4gICAgfSksXG4gICAgLy8gUHJvdmVuYW5jZS4gQm90aCBhcmUgb3BhcXVlIGlkcyDigJQgYW4gQVdTLWFzc2lnbmVkIGV2ZW50IFVVSUQgYW5kIG91ciBvd25cbiAgICAvLyBrZXkgaWQg4oCUIHNvIG5laXRoZXIgY2FuIGNhcnJ5IGFuIGFjY291bnQgaWQgYW5kIG5laXRoZXIgaXMgc2NydWJiZWRcbiAgICAvLyAoc2NydWJiaW5nIGEgZGlnaXQgcnVuIGluc2lkZSBvbmUgd291bGQgY29ycnVwdCB0aGUgY29ycmVsYXRpb24ga2V5KS5cbiAgICBzb3VyY2VFdmVudElkOiBldmVudC5zb3VyY2VFdmVudElkLFxuICAgIGluZ2VzdEtleUlkOiBrZXlJZCxcbiAgICBkZXRhaWw6IGRldGFpbCAhPT0gdW5kZWZpbmVkID8gc2NydWJBd3NJZGVudGlmaWVycyhkZXRhaWwpIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vKipcbiAqIEZhbiB0ZXJtaW5hbCBTVEFHRSBvdXRjb21lcyBhbmQgcGVyLUFDVElPTiBjb21wdXRlIGNvbnN1bXB0aW9uIGludG8gdGhlXG4gKiByb3V0ZSdzIG1ldHJpYyBob29rIChwaXBlbGluZS1kYXRhIGNhbid0IGltcG9ydCBhcGktc2VydmVyJ3MgcmVnaXN0cnkpIGFmdGVyXG4gKiB0aGUgaW5zZXJ0IGNvbW1pdHMuXG4gKlxuICogRHJpdmVuIG9mZiB0aGUgSU5TRVJURUQgcm93cywgc28gYSByZS1kZWxpdmVyZWQgZXZlbnQgdGhlIGRlZHVwIGluZGV4XG4gKiBzd2FsbG93ZWQgaXMgbmV2ZXIgY291bnRlZCB0d2ljZS4gVGhhdCBwcm9wZXJ0eSBpcyBsb2FkLWJlYXJpbmcgZm9yIHRoZVxuICogY29tcHV0ZSBzZXJpZXMgaW4gYSB3YXkgaXQgd2FzIG5vdCBmb3IgdGhlIHN0YWdlIG9uZTogYSBkdXBsaWNhdGVkIHN0YWdlXG4gKiBvdXRjb21lIGRpc3RvcnRzIGEgcmF0ZSwgd2hlcmVhcyBhIGR1cGxpY2F0ZWQgdkNQVS1taW51dGUgZmlndXJlIGlzIGFcbiAqIGRvdWJsZS1jaGFyZ2Ugd2FpdGluZyBmb3IgdGhlIGRheSB0aGUgY2hhcmdlIGlzIHN3aXRjaGVkIG9uLlxuICpcbiAqIEEgbm9uLW51bGwgZW52aXJvbm1lbnQgbWFya3MgYSBkZXBsb3kuXG4gKi9cbmZ1bmN0aW9uIGVtaXRJbmdlc3RNZXRyaWNzKFxuICByb3dzOiBSZWFkb25seUFycmF5PHtcbiAgICBvcmdJZDogc3RyaW5nO1xuICAgIHBpcGVsaW5lSWQ6IHN0cmluZyB8IG51bGw7XG4gICAgZXZlbnRUeXBlOiBzdHJpbmc7XG4gICAgc3RhdHVzOiBzdHJpbmc7XG4gICAgc3RhZ2VOYW1lOiBzdHJpbmcgfCBudWxsO1xuICAgIGVudmlyb25tZW50OiBzdHJpbmcgfCBudWxsO1xuICAgIGR1cmF0aW9uTXM/OiBudW1iZXIgfCBudWxsO1xuICAgIGRldGFpbD86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgbnVsbDtcbiAgfT4sXG4gIG9uTWV0cmljOiAobTogSW5nZXN0TWV0cmljKSA9PiB2b2lkLFxuKTogdm9pZCB7XG4gIGZvciAoY29uc3QgciBvZiByb3dzKSB7XG4gICAgaWYgKCFyLnBpcGVsaW5lSWQpIGNvbnRpbnVlO1xuXG4gICAgLy8gQ29tcHV0ZSBjb25zdW1wdGlvbjogZXZlcnkgVEVSTUlOQUwgYWN0aW9uLCBtZWFzdXJhYmxlIG9yIG5vdC4gVGhlXG4gICAgLy8gdW5tZWFzdXJhYmxlIG9uZXMgYXJlIHRoZSBwb2ludCDigJQgdGhleSBhcmUgd2hhdCB0aGUgY292ZXJhZ2UgcmF0aW8gY291bnRzLlxuICAgIGlmIChyLmV2ZW50VHlwZSA9PT0gJ0FDVElPTicgJiYgVEVSTUlOQUxfQUNUSU9OX1NUQVRFUy5pbmNsdWRlcyhyLnN0YXR1cykpIHtcbiAgICAgIGNvbnN0IGNvbXB1dGVUeXBlID0gbm9ybWFsaXplQ29tcHV0ZVR5cGUoXG4gICAgICAgIHR5cGVvZiByLmRldGFpbD8uY29tcHV0ZVR5cGUgPT09ICdzdHJpbmcnID8gci5kZXRhaWwuY29tcHV0ZVR5cGUgOiBudWxsLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGR1cmF0aW9uTXMgPSByLmR1cmF0aW9uTXMgPz8gbnVsbDtcbiAgICAgIG9uTWV0cmljKHtcbiAgICAgICAga2luZDogJ2NvbXB1dGUnLFxuICAgICAgICBwaXBlbGluZUlkOiByLnBpcGVsaW5lSWQsXG4gICAgICAgIG9yZ0lkOiByLm9yZ0lkLFxuICAgICAgICBjb21wdXRlVHlwZSxcbiAgICAgICAgZHVyYXRpb25NcyxcbiAgICAgICAgY3JlZGl0czogY29tcHV0ZUNyZWRpdHNGb3IoZHVyYXRpb25NcywgY29tcHV0ZVR5cGUpLFxuICAgICAgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoci5ldmVudFR5cGUgIT09ICdTVEFHRScgfHwgKHIuc3RhdHVzICE9PSAnU1VDQ0VFREVEJyAmJiByLnN0YXR1cyAhPT0gJ0ZBSUxFRCcpKSBjb250aW51ZTtcbiAgICBvbk1ldHJpYyh7XG4gICAgICBraW5kOiAnc3RhZ2UnLFxuICAgICAgcGlwZWxpbmVJZDogci5waXBlbGluZUlkLFxuICAgICAgb3JnSWQ6IHIub3JnSWQsXG4gICAgICBzdGFnZTogci5zdGFnZU5hbWUgPz8gJycsXG4gICAgICBlbnZpcm9ubWVudDogci5lbnZpcm9ubWVudCA/PyBudWxsLFxuICAgICAgcmVzdWx0OiByLnN0YXR1cyA9PT0gJ1NVQ0NFRURFRCcgPyAnc3VjY2VlZGVkJyA6ICdmYWlsZWQnLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKiBBY3Rpb24gc3RhdGVzIHRoYXQgbWVhbiB0aGUgYWN0aW9uIGlzIG92ZXIgYW5kIGl0cyBjb25zdW1wdGlvbiBpcyBmaW5hbC4gKi9cbmNvbnN0IFRFUk1JTkFMX0FDVElPTl9TVEFURVM6IHJlYWRvbmx5IHN0cmluZ1tdID0gWydTVUNDRUVERUQnLCAnRkFJTEVEJywgJ1NUT1BQRUQnXTtcblxuLyoqXG4gKiBSZXNvbHZlIGluY29taW5nIGV2ZW50cyBhZ2FpbnN0IHRoZSBwaXBlbGluZSByZWdpc3RyeSwgYmF0Y2gtaW5zZXJ0IHRoZVxuICogbWF0Y2hlZCBvbmVzLCBhbmQgaW52YWxpZGF0ZSByZXBvcnRpbmcgY2FjaGVzIGZvciBhZmZlY3RlZCBvcmdzLlxuICogRXZlbnRzIGZvciB1bnJlZ2lzdGVyZWQgcGlwZWxpbmUgaWRzIGFyZSBkcm9wcGVkIChhbmQgbG9nZ2VkIGF0IFdBUk5cbiAqIHdpdGggc2FtcGxlIGlkcyBzbyBhbiBvcGVyYXRvciBjYW4gc2VlIHdoZW4gRXZlbnRCcmlkZ2UgaXMgZGVsaXZlcmluZ1xuICogZXZlbnRzIGZvciBwaXBlbGluZXMgdGhhdCBoYXZlbid0IGNhbGxlZCBQT1NUIC9waXBlbGluZXMvcmVnaXN0cnkgeWV0KS5cbiAqXG4gKiBSZXR1cm5zIGNvdW50cyArIGEgc2FtcGxlIG9mIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZHMgZm9yIG9ic2VydmFiaWxpdHkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbmdlc3RFdmVudHMoXG4gIGV2ZW50czogSW5nZXN0RXZlbnRbXSxcbiAgb25NZXRyaWM/OiAobTogSW5nZXN0TWV0cmljKSA9PiB2b2lkLFxuICBjYWxsZXI/OiBJbmdlc3RDYWxsZXIsXG4pOiBQcm9taXNlPEluZ2VzdFJlc3VsdD4ge1xuICAvLyBURU5BTkNZLiBBbiBldmVudCdzIG9yZyBjb21lcyBmcm9tIHRoZSBwaXBlbGluZSBSRUdJU1RSWSwgbm90IHRoZSB0b2tlbiwgc29cbiAgLy8gdGhlIHNjb3BlIGNoZWNrIGFsb25lIGxldCBhbnkgYHJlcG9ydGluZzppbmdlc3RgIGhvbGRlciBwb3N0IGV2ZW50cyBmb3JcbiAgLy8gYW5vdGhlciBvcmcncyBwaXBlbGluZSBpZCBhbmQgaGF2ZSB0aGVtIGF0dHJpYnV0ZWQgdGhlcmUuIGBjYWxsZXJgIGNhcnJpZXNcbiAgLy8gdGhlIG9yZyBpZHMgdGhpcyB0b2tlbiBtYXkgd3JpdGUgZm9yOyBhbnl0aGluZyBlbHNlIGlzIGRyb3BwZWQgYmVsb3cuXG4gIC8vXG4gIC8vIGBjYWxsZXJgIGlzIG9wdGlvbmFsIG9ubHkgc28gaW4tcHJvY2VzcyBjYWxsZXJzIHRoYXQgYWxyZWFkeSBydW5cbiAgLy8gY3Jvc3MtdGVuYW50ICh0ZXN0cywgYmFja2ZpbGxzKSBrZWVwIHdvcmtpbmcg4oCUIGFuIEFCU0VOVCBjYWxsZXIgbWVhbnMgXCJub1xuICAvLyByZXN0cmljdGlvblwiLCBhbmQgdGhlIHJvdXRlIGFsd2F5cyBzdXBwbGllcyBvbmUuIEEgY2FsbGVyIHdpdGggYW4gRU1QVFlcbiAgLy8gYWxsb3ctbGlzdCBhbmQgbm8gY3Jvc3NUZW5hbnQgZmxhZyB0aGVyZWZvcmUgZHJvcHMgZXZlcnl0aGluZywgd2hpY2ggaXMgdGhlXG4gIC8vIHJpZ2h0IGFuc3dlciB3aGVuIHRoZSByb3V0ZSBjb3VsZCBub3QgZXN0YWJsaXNoIHdobyBpcyB3cml0aW5nLlxuICBjb25zdCB1bnJlc3RyaWN0ZWQgPSBjYWxsZXIgPT09IHVuZGVmaW5lZCB8fCBjYWxsZXIuY3Jvc3NUZW5hbnQgPT09IHRydWU7XG4gIGNvbnN0IGFsbG93ZWQgPSBuZXcgU2V0KGNhbGxlcj8uYWxsb3dlZE9yZ0lkcyA/PyBbXSk7XG4gIC8vIE11bHRpLW9yZyBiYXRjaCBpbnNlcnQ6IHRoZSBjYWxsZXIgcmVzb2x2ZXMgdG8gbXVsdGlwbGUgb3JncyB2aWEgdGhlXG4gIC8vIHBpcGVsaW5lLXJlZ2lzdHJ5IGxvb2t1cCBiZWxvdywgc28gdGhlIHJvdXRlIGxheWVyIE1VU1QgZXN0YWJsaXNoIGFcbiAgLy8gYHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIC4uLilgIHNjb3BlIGJlZm9yZSBjYWxsaW5nXG4gIC8vIHRoaXMgZnVuY3Rpb24uIFVuZGVyIEZPUkNFJ2QgUkxTLCBhIHNpbmdsZSB0eCB3aXRoIGBhcHAub3JnX2lkID0gPG9uZVxuICAvLyBvcmc+YCBjb3VsZCBvbmx5IHdyaXRlIGV2ZW50cyBmb3IgdGhhdCBvcmc7IGJ5cGFzcyB2aWEgc3lzYWRtaW4gaXNcbiAgLy8gdGhlIHJpZ2h0IGdhdGUgZm9yIHRoaXMgc2VydmVyLWludGVybmFsIGNyb3NzLXRlbmFudCBlbmRwb2ludC4gU2VlXG4gIC8vIGFwaS9yZXBvcnRpbmcvc3JjL3JvdXRlcy9ldmVudC1pbmdlc3QudHMgZm9yIHRoZSB3cmFwcGVyLlxuICAvLyBDYWNoZXMgYXJlIGludmFsaWRhdGVkIEFGVEVSIHRoZSB0eCByZXNvbHZlczogZG9pbmcgaXQgaW5zaWRlIGhlbGQgdGhlIHBnXG4gIC8vIGxvY2tzIG9wZW4gYWNyb3NzIHVucmVsYXRlZCBjYWNoZSByb3VuZC10cmlwcy4gVGhlIFRUTCBpcyAyLTUgbWluLCBzbyBhXG4gIC8vIGZpcmUtYW5kLWZvcmdldCBwb3N0LWNvbW1pdCBpbnZhbGlkYXRpb24gaXMgYW4gYWNjZXB0YWJsZSB0cmFkZS5cbiAgY29uc3QgeyBpbnNlcnRlZCwgc2tpcHBlZCwgdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMsIGFmZmVjdGVkT3JncywgZHJvcHBlZEZvcmVpZ25PcmcsIGRyb3BwZWRJbnZhbGlkVGltZSwgZm9yZWlnblBpcGVsaW5lSWRzLCBpbnNlcnRlZFJvd3MgfSA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAvLyBCYXRjaC1yZXNvbHZlIGFsbCB1bmlxdWUgcGlwZWxpbmUgaWRzIGluIG9uZSBxdWVyeVxuICAgIGNvbnN0IHVuaXF1ZUlkcyA9IFsuLi5uZXcgU2V0KGV2ZW50cy5tYXAoZSA9PiBlLnBpcGVsaW5lSWQpKV07XG4gICAgY29uc3QgcmVnaXN0cnlSb3dzID0gYXdhaXQgdHhcbiAgICAgIC5zZWxlY3Qoe1xuICAgICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLFxuICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkub3JnSWQsXG4gICAgICB9KVxuICAgICAgLmZyb20oc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkpXG4gICAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLCB1bmlxdWVJZHMpKTtcblxuICAgIGNvbnN0IGlkTWFwID0gbmV3IE1hcChyZWdpc3RyeVJvd3MubWFwKHIgPT4gW3IucGlwZWxpbmVJZCwgcl0pKTtcbiAgICBjb25zdCBzdGVwUGx1Z2lucyA9IGF3YWl0IGxvYWRTdGVwUGx1Z2lucyh0eCwgZXZlbnRzLmZpbHRlcigoZSkgPT4gaXNBdHRyaWJ1dGFibGUoZSkgJiYgaWRNYXAuaGFzKGUucGlwZWxpbmVJZCkpKTtcblxuICAgIC8vIEJ1aWxkIGluc2VydCBiYXRjaCAoc2tpcCBldmVudHMgd2hvc2UgcGlwZWxpbmUgaXNuJ3QgcmVnaXN0ZXJlZClcbiAgICBjb25zdCByb3dzOiBQaXBlbGluZUV2ZW50SW5zZXJ0W10gPSBbXTtcbiAgICBsZXQgc2tpcHBlZExvY2FsID0gMDtcbiAgICBsZXQgZm9yZWlnbkxvY2FsID0gMDtcbiAgICBsZXQgaW52YWxpZFRpbWVMb2NhbCA9IDA7XG4gICAgY29uc3QgaW52YWxpZFRpbWVSZWFzb25zID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgZm9yZWlnbk9yZ0lkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IGZvcmVpZ25QaXBlbGluZUlkc0xvY2FsID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgdW5yZWdpc3RlcmVkTG9jYWw6IHN0cmluZ1tdID0gW107XG4gICAgLy8gT25lIGBub3dgIGZvciB0aGUgd2hvbGUgYmF0Y2g6IHBlci1ldmVudCBjbG9ja3Mgd291bGQgbGV0IGFuIGV2ZW50IHBhc3Mgb3JcbiAgICAvLyBmYWlsIGRlcGVuZGluZyBvbiB3aGVyZSBpdCBzYXQgaW4gdGhlIGxvb3AuXG4gICAgY29uc3Qgbm93TXMgPSBEYXRlLm5vdygpO1xuXG4gICAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMpIHtcbiAgICAgIGNvbnN0IHJlZ2lzdHJ5ID0gaWRNYXAuZ2V0KGV2ZW50LnBpcGVsaW5lSWQpO1xuICAgICAgaWYgKCFyZWdpc3RyeSkge1xuICAgICAgICBza2lwcGVkTG9jYWwrKztcbiAgICAgICAgdW5yZWdpc3RlcmVkTG9jYWwucHVzaChldmVudC5waXBlbGluZUlkKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICAvLyBUaGUgcGlwZWxpbmUgcmVzb2x2ZXMgdG8gYW4gb3JnIHRoaXMgY2FsbGVyIG1heSBub3Qgd3JpdGUgZm9yLiBDb3VudGVkXG4gICAgICAvLyBzZXBhcmF0ZWx5IGZyb20gYHNraXBwZWRgIChhbiB1bnJlZ2lzdGVyZWQgaWQgaXMgYSBwcm9kdWNlciBydW5uaW5nXG4gICAgICAvLyBhaGVhZCBvZiByZWdpc3RyYXRpb247IHRoaXMgaXMgYSB0ZW5hbmN5IHJlZnVzYWwpIGFuZCBuZXZlciBpbnNlcnRlZC5cbiAgICAgIGlmICghdW5yZXN0cmljdGVkICYmICFhbGxvd2VkLmhhcyhyZWdpc3RyeS5vcmdJZCkpIHtcbiAgICAgICAgZm9yZWlnbkxvY2FsKys7XG4gICAgICAgIGZvcmVpZ25PcmdJZHMuYWRkKHJlZ2lzdHJ5Lm9yZ0lkKTtcbiAgICAgICAgZm9yZWlnblBpcGVsaW5lSWRzTG9jYWwuYWRkKGV2ZW50LnBpcGVsaW5lSWQpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIC8vIEltcG9zc2libGUgdGltZXN0YW1wcyBhcmUgcmVmdXNlZCBhdCB0aGUgYm91bmRhcnksIHNvIG5vIGRvd25zdHJlYW1cbiAgICAgIC8vIG1ldHJpYyBoYXMgdG8gY2xhbXAgYSBuZWdhdGl2ZSBnYXAgYW5kIGNhbGwgaXQgemVyby5cbiAgICAgIGNvbnN0IGJhZFRpbWUgPSBpbnZhbGlkRXZlbnRUaW1lcyhldmVudCwgbm93TXMpO1xuICAgICAgaWYgKGJhZFRpbWUpIHtcbiAgICAgICAgaW52YWxpZFRpbWVMb2NhbCsrO1xuICAgICAgICBpbnZhbGlkVGltZVJlYXNvbnMuYWRkKGJhZFRpbWUpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YWdlTmFtZSA9IHNjcnViT3B0aW9uYWwoZXZlbnQuc3RhZ2VOYW1lKTtcbiAgICAgIGNvbnN0IGFjdGlvbk5hbWUgPSBzY3J1Yk9wdGlvbmFsKGV2ZW50LmFjdGlvbk5hbWUpO1xuICAgICAgY29uc3Qgc3RlcCA9IGlzQXR0cmlidXRhYmxlKGV2ZW50KSAmJiBzdGFnZU5hbWUgJiYgYWN0aW9uTmFtZVxuICAgICAgICA/IHN0ZXBQbHVnaW5zLmdldChzdGVwS2V5KHJlZ2lzdHJ5LnBpcGVsaW5lSWQsIHN0YWdlTmFtZSwgYWN0aW9uTmFtZSkpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgLy8gU2FtZS1vcmcgZ3VhcmQ6IGEgbWFuaWZlc3Qgcm93IGlzIG9ubHkgZXZlciB3cml0dGVuIGJ5IHRoZSBvcmcgdGhhdFxuICAgICAgLy8gb3ducyB0aGUgcGlwZWxpbmUsIGJ1dCB0aGUgaW5nZXN0IHJ1bnMgY3Jvc3MtdGVuYW50LCBzbyBkb24ndCBsZWFuIG9uIGl0LlxuICAgICAgcm93cy5wdXNoKHRvRXZlbnRSb3coZXZlbnQsIHJlZ2lzdHJ5LCBzdGVwICYmIHN0ZXAub3JnSWQgPT09IHJlZ2lzdHJ5Lm9yZ0lkID8gc3RlcCA6IHVuZGVmaW5lZCwgY2FsbGVyPy5rZXlJZCkpO1xuICAgIH1cblxuICAgIC8vIFNRUyBpcyBhdC1sZWFzdC1vbmNlLCBzbyBFdmVudEJyaWRnZSBjYW4gZGVsaXZlciB0aGUgc2FtZSBzdGF0ZS1jaGFuZ2VcbiAgICAvLyB0d2ljZS4gYG9uQ29uZmxpY3REb05vdGhpbmdgICsgdGhlIHBhcnRpYWwgdW5pcXVlIGluZGV4ZXMgb25cbiAgICAvLyAocGlwZWxpbmVfaWQsIGV4ZWN1dGlvbl9pZCwgZXZlbnRfdHlwZSwgc3RhdHVzLCBzdGFnZV9uYW1lLCBhY3Rpb25fbmFtZSlcbiAgICAvLyBhbmQgb24gc291cmNlX2V2ZW50X2lkICh0aGUgRXZlbnRCcmlkZ2UgaWQsIHdoZW4gcHJlc2VudCkgbWFrZVxuICAgIC8vIHJlLWRlbGl2ZXJ5IGlkZW1wb3RlbnQuIGByZXR1cm5pbmdgIGdpdmVzIHRoZSBSRUFMIGluc2VydGVkIHNldCBzb1xuICAgIC8vIGNvdW50cywgbWV0cmljcyBhbmQgY2FjaGUgaW52YWxpZGF0aW9uIGFsbCBpZ25vcmUgZHVwbGljYXRlcy5cbiAgICBjb25zdCBsYW5kZWQgPSByb3dzLmxlbmd0aCA+IDBcbiAgICAgID8gYXdhaXQgdHguaW5zZXJ0KHNjaGVtYS5waXBlbGluZUV2ZW50KS52YWx1ZXMocm93cylcbiAgICAgICAgLm9uQ29uZmxpY3REb05vdGhpbmcoKVxuICAgICAgICAucmV0dXJuaW5nKHtcbiAgICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lRXZlbnQub3JnSWQsXG4gICAgICAgICAgcGlwZWxpbmVJZDogc2NoZW1hLnBpcGVsaW5lRXZlbnQucGlwZWxpbmVJZCxcbiAgICAgICAgICBldmVudFR5cGU6IHNjaGVtYS5waXBlbGluZUV2ZW50LmV2ZW50VHlwZSxcbiAgICAgICAgICBzdGF0dXM6IHNjaGVtYS5waXBlbGluZUV2ZW50LnN0YXR1cyxcbiAgICAgICAgICBzdGFnZU5hbWU6IHNjaGVtYS5waXBlbGluZUV2ZW50LnN0YWdlTmFtZSxcbiAgICAgICAgICBlbnZpcm9ubWVudDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuZW52aXJvbm1lbnQsXG4gICAgICAgICAgLy8gRm9yIHRoZSBwZXItZGVwbG95IHJvbGx1cCBiZWxvdzogZXZlcnl0aGluZyBgZG9yYV9kZXBsb3ltZW50c2AgbmVlZHMsXG4gICAgICAgICAgLy8gdGFrZW4gZnJvbSB0aGUgcm93cyB0aGF0IEFDVFVBTExZIGxhbmRlZCBzbyBhIHJlLWRlbGl2ZXJ5IGNhbm5vdFxuICAgICAgICAgIC8vIHByb2R1Y2UgYSBzZWNvbmQgZGVwbG95LlxuICAgICAgICAgIGV4ZWN1dGlvbklkOiBzY2hlbWEucGlwZWxpbmVFdmVudC5leGVjdXRpb25JZCxcbiAgICAgICAgICBjb21taXRTaGE6IHNjaGVtYS5waXBlbGluZUV2ZW50LmNvbW1pdFNoYSxcbiAgICAgICAgICBjb21taXRUaW1lc3RhbXA6IHNjaGVtYS5waXBlbGluZUV2ZW50LmNvbW1pdFRpbWVzdGFtcCxcbiAgICAgICAgICBjb21taXRDb3VudDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuY29tbWl0Q291bnQsXG4gICAgICAgICAgY29tcGxldGVkQXQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmNvbXBsZXRlZEF0LFxuICAgICAgICAgIHN0YXJ0ZWRBdDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuc3RhcnRlZEF0LFxuICAgICAgICAgIGNyZWF0ZWRBdDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuY3JlYXRlZEF0LFxuICAgICAgICAgIGRldGFpbDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuZGV0YWlsLFxuICAgICAgICAgIHNvdXJjZUV2ZW50SWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LnNvdXJjZUV2ZW50SWQsXG4gICAgICAgIH0pXG4gICAgICA6IFtdO1xuXG4gICAgLy8gTG9nIGluc2lkZSB0aGUgdHggc2NvcGUgd2hpbGUgdGhlIG9yZyBzZXQgaXMgaW4gaGFuZC4gV0FSTiwgbm90IGVycm9yOlxuICAgIC8vIGEgbWlzcm91dGVkIHByb2R1Y2VyIGlzIHRoZSBjb21tb24gY2F1c2UsIGJ1dCB0aGUgc2FtZSBsaW5lIGlzIHRoZSBvbmx5XG4gICAgLy8gc2lnbmFsIG9mIGFuIGluamVjdGlvbiBhdHRlbXB0LCBzbyBpdCBuYW1lcyB0aGUgb3JncyBpdCByZWZ1c2VkLlxuICAgIGlmIChmb3JlaWduTG9jYWwgPiAwKSB7XG4gICAgICBsb2dnZXIud2FybignRHJvcHBlZCBpbmdlc3QgZXZlbnRzIGZvciBvcmdzIHRoZSBjYWxsZXIgbWF5IG5vdCB3cml0ZSBmb3InLCB7XG4gICAgICAgIGRyb3BwZWQ6IGZvcmVpZ25Mb2NhbCxcbiAgICAgICAgZm9yZWlnbk9yZ0lkczogWy4uLmZvcmVpZ25PcmdJZHNdLFxuICAgICAgICBhbGxvd2VkT3JnSWRzOiBbLi4uYWxsb3dlZF0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoaW52YWxpZFRpbWVMb2NhbCA+IDApIHtcbiAgICAgIGxvZ2dlci53YXJuKCdEcm9wcGVkIGluZ2VzdCBldmVudHMgd2l0aCBpbXBvc3NpYmxlIHRpbWVzdGFtcHMnLCB7XG4gICAgICAgIGRyb3BwZWQ6IGludmFsaWRUaW1lTG9jYWwsXG4gICAgICAgIHJlYXNvbnM6IFsuLi5pbnZhbGlkVGltZVJlYXNvbnNdLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGluc2VydGVkOiBsYW5kZWQubGVuZ3RoLFxuICAgICAgc2tpcHBlZDogc2tpcHBlZExvY2FsLFxuICAgICAgdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHM6IHVucmVnaXN0ZXJlZExvY2FsLFxuICAgICAgYWZmZWN0ZWRPcmdzOiBbLi4ubmV3IFNldChsYW5kZWQubWFwKHIgPT4gci5vcmdJZCkpXSxcbiAgICAgIGRyb3BwZWRGb3JlaWduT3JnOiBmb3JlaWduTG9jYWwsXG4gICAgICBkcm9wcGVkSW52YWxpZFRpbWU6IGludmFsaWRUaW1lTG9jYWwsXG4gICAgICBmb3JlaWduUGlwZWxpbmVJZHM6IFsuLi5mb3JlaWduUGlwZWxpbmVJZHNMb2NhbF0sXG4gICAgICBpbnNlcnRlZFJvd3M6IGxhbmRlZCxcbiAgICB9O1xuICB9KTtcblxuICBpZiAob25NZXRyaWMpIGVtaXRJbmdlc3RNZXRyaWNzKGluc2VydGVkUm93cywgb25NZXRyaWMpO1xuXG4gIC8vIFBlci1kZXBsb3kgcm9sbHVwLiBBRlRFUiB0aGUgZXZlbnRzIGNvbW1pdCBhbmQgb3V0c2lkZSB0aGVpciB0cmFuc2FjdGlvbjogdGhlXG4gIC8vIGV2ZW50cyBhcmUgdGhlIGR1cmFibGUgcmVjb3JkIGFuZCBgZG9yYV9kZXBsb3ltZW50c2AgaXMgZGVyaXZlZCBmcm9tIHRoZW0sIHNvXG4gIC8vIGEgcm9sbHVwIGZhaWx1cmUgbXVzdCBub3Qgcm9sbCBiYWNrIGFuIGluZ2VzdCB0aGF0IHN1Y2NlZWRlZC4gUmVidWlsZGFibGVcbiAgLy8gZWl0aGVyIHdheS4gYHVwc2VydERlcGxveW1lbnRzYCBuZXZlciB0aHJvd3MgZm9yIHRoYXQgcmVhc29uLlxuICBhd2FpdCB1cHNlcnREZXBsb3ltZW50cyhpbnNlcnRlZFJvd3MpO1xuXG4gIC8vIFN1cmZhY2UgdGhlIHNpbGVudCBza2lwOiBhbiB1bnJlZ2lzdGVyZWQgcGlwZWxpbmUgaWQgdXN1YWxseSBtZWFucyB0aGVcbiAgLy8gcGlwZWxpbmUgaGFzbid0IGNhbGxlZCBQT1NUIC9waXBlbGluZXMvcmVnaXN0cnkgeWV0IChvciBpdHNcbiAgLy8gcGIucGlwZWxpbmUtaWQgdGFnIGlzIG1pc3NpbmcvdW5yZWFkYWJsZSBieSB0aGUgTGFtYmRhKS4gTG9nZ2luZyBpdFxuICAvLyBtYWtlcyBhIGJyb2tlbiBqb2luIHZpc2libGUgaW5zdGVhZCBvZiBsb29raW5nIGxpa2UgXCJubyBhY3Rpdml0eVwiLlxuICBpZiAodW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMubGVuZ3RoID4gMCkge1xuICAgIGxvZ2dlci53YXJuKCdQaXBlbGluZSBldmVudHMgc2tpcHBlZDogcGlwZWxpbmUgaWQgbm90IGZvdW5kIGluIHJlZ2lzdHJ5Jywge1xuICAgICAgY291bnQ6IHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLmxlbmd0aCxcbiAgICAgIHNhbXBsZTogdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMuc2xpY2UoMCwgMyksXG4gICAgfSk7XG4gIH1cblxuICAvLyBQb3N0LWNvbW1pdCBjYWNoZSBpbnZhbGlkYXRpb24uIEZpcmUtYW5kLWZvcmdldCB3aXRoIGxvZ2dpbmcg4oCUIFRUTCBpc1xuICAvLyBzaG9ydCBlbm91Z2ggdGhhdCBhIG1pc3NlZCBpbnZhbGlkYXRpb24gc2VsZi1oZWFscy5cbiAgaWYgKGFmZmVjdGVkT3Jncy5sZW5ndGggPiAwKSB7XG4gICAgdm9pZCBQcm9taXNlLmFsbChhZmZlY3RlZE9yZ3MubWFwKChvcmcpID0+XG4gICAgICBpbnZhbGlkYXRlT3JnUmVwb3J0cyhvcmcpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyBjYWNoZSBpbnZhbGlkYXRpb24gZmFpbGVkJywgeyBvcmdJZDogb3JnLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICB9KSxcbiAgICApKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgaW5zZXJ0ZWQsXG4gICAgc2tpcHBlZCxcbiAgICB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcyxcbiAgICBhZmZlY3RlZE9yZ3MsXG4gICAgZHJvcHBlZEZvcmVpZ25PcmcsXG4gICAgZHJvcHBlZEludmFsaWRUaW1lLFxuICAgIGZvcmVpZ25QaXBlbGluZUlkcyxcbiAgICBpbnNlcnRlZEV4ZWN1dGlvbklkczogWy4uLm5ldyBTZXQoaW5zZXJ0ZWRSb3dzLm1hcCgocikgPT4gci5leGVjdXRpb25JZCkuZmlsdGVyKChpZCk6IGlkIGlzIHN0cmluZyA9PiAhIWlkKSldLFxuICAgIGluc2VydGVkUGlwZWxpbmVJZHM6IFsuLi5uZXcgU2V0KGluc2VydGVkUm93cy5tYXAoKHIpID0+IHIucGlwZWxpbmVJZCkuZmlsdGVyKChpZCk6IGlkIGlzIHN0cmluZyA9PiAhIWlkKSldLFxuICB9O1xufVxuIl19
432
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5nZXN0LmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBpL3JlcG9ydGluZy9pbmdlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3RJLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakQsT0FBTyxFQUNMLG1CQUFtQixFQUFFLDBCQUEwQixFQUFFLG9CQUFvQixFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUM3RyxrQkFBa0IsR0FDbkIsTUFBTSxxQkFBcUIsQ0FBQztBQUU3QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDMUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBR3pELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBY2hELHFFQUFxRTtBQUNyRSxTQUFTLGNBQWMsQ0FBQyxDQUFjO0lBQ3BDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxLQUFLLFFBQVEsSUFBSSxDQUFDLENBQUMsU0FBUyxLQUFLLE9BQU8sQ0FBQztXQUN2RCxDQUFDLENBQUMsQ0FBQyxXQUFXLEtBQUssY0FBYyxJQUFJLENBQUMsQ0FBQyxXQUFXLEtBQUssV0FBVyxDQUFDO1dBQ25FLENBQUMsQ0FBQyxDQUFDLENB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Q0FBQyxDQUFDLEVBQUUsRUFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzdHLG1CQUFtQixFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFnQixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7S0FDNUcsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBFdmVudCBpbmdlc3Q6IHRoZSBXUklURSBoYWxmIG9mIHJlcG9ydGluZy4gUmVzb2x2ZXMgaW5jb21pbmcgcGlwZWxpbmUgZXZlbnRzXG4gKiBhZ2FpbnN0IHRoZSBwaXBlbGluZSByZWdpc3RyeSwgc2NydWJzIGV2ZXJ5IGZyZWUtZm9ybSBzdHJpbmcsIGJhdGNoLWluc2VydHNcbiAqIHRoZSBtYXRjaGVkIHJvd3MgaWRlbXBvdGVudGx5LCBhbmQgaW52YWxpZGF0ZXMgdGhlIGFmZmVjdGVkIG9yZ3MnIHJlcG9ydFxuICogY2FjaGVzLiBTZXBhcmF0ZSBmcm9tIHRoZSByZXBvcnQgcXVlcmllcyBiZWNhdXNlIHRoaXMgaXMgcmVwb3J0aW5nJ3Mgb25seVxuICogZHVyYWJsZSBwZXJzaXN0ZW5jZSBib3VuZGFyeSDigJQgZXZlcnl0aGluZyBlbHNlIGluIHRoZSBzZXJ2aWNlIG9ubHkgcmVhZHMuXG4gKi9cblxuaW1wb3J0IHsgY29tcHV0ZUNyZWRpdHNGb3IsIGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlLCBub3JtYWxpemVDb21wdXRlVHlwZSwgc2NydWJBd3NJZGVudGlmaWVycyB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGluQXJyYXkgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgeyBpbnZhbGlkYXRlT3JnUmVwb3J0cyB9IGZyb20gJy4vY2FjaGVzLmpzJztcbmltcG9ydCB7IHVwc2VydERlcGxveW1lbnRzIH0gZnJvbSAnLi9kZXBsb3ktcm9sbHVwLmpzJztcbmltcG9ydCB7IGNsYXNzaWZ5RmFpbHVyZSB9IGZyb20gJy4vZmFpbHVyZS1jbGFzc2lmaWVyLmpzJztcbmltcG9ydCB7IHNjcnViT3B0aW9uYWwgfSBmcm9tICcuL3NxbC1oZWxwZXJzLmpzJztcbmltcG9ydCB7XG4gIGRlcGxveWVkVG9vbGNoYWluT2YsIHJlYWRQbGF0Zm9ybURlZmF1bHRSZWxlYXNlLCBTRUxGX01VVEFUSU9OX0FDVElPTiwgU0VMRl9NVVRBVElPTl9TVEFHRSwgdG9vbGNoYWluQWN0aW9uT2YsXG4gIHRvb2xjaGFpbk91dGNvbWVPZiwgdHlwZSBEZXBsb3llZFRvb2xjaGFpbixcbn0gZnJvbSAnLi90b29sY2hhaW4tcnVucy5qcyc7XG5pbXBvcnQgdHlwZSB7IEluZ2VzdENhbGxlciwgSW5nZXN0RXZlbnQsIEluZ2VzdE1ldHJpYywgSW5nZXN0UmVzdWx0IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5pbXBvcnQgeyBzY2hlbWEgfSBmcm9tICcuLi8uLi9kYXRhYmFzZS9kcml6emxlLXNjaGVtYS5qcyc7XG5pbXBvcnQgeyB3aXRoVGVuYW50VHggfSBmcm9tICcuLi8uLi9kYXRhYmFzZS90ZW5hbmN5LmpzJztcbmltcG9ydCB0eXBlIHsgQ3J1ZFR4IH0gZnJvbSAnLi4vY3J1ZC1zZXJ2aWNlLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdyZXBvcnRpbmctaW5nZXN0Jyk7XG5cbnR5cGUgUGlwZWxpbmVFdmVudEluc2VydCA9IHR5cGVvZiBzY2hlbWEucGlwZWxpbmVFdmVudC4kaW5mZXJJbnNlcnQ7XG5cblxuLyoqIFRoZSBwbHVnaW4gYSBwaXBlbGluZSBzdGVwIHJ1bnMsIGZyb20gdGhlIHN0ZXAgbWFuaWZlc3QgaXRzIGxhc3QgZGVwbG95IHJlZ2lzdGVyZWQuICovXG5pbnRlcmZhY2UgU3RlcFBsdWdpbiB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIHBsdWdpblB1Ymxpc2hlcjogc3RyaW5nIHwgbnVsbDtcbiAgcGx1Z2luUHVibGlzaGVySWQ6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpbk5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHBsdWdpblZlcnNpb246IHN0cmluZyB8IG51bGw7XG59XG5cbi8qKiBBbiBhY3Rpb24vYnVpbGQgZXZlbnQgdGhhdCBjYW4gYmUgYXR0cmlidXRlZCB0byBhIHBsdWdpbiBzdGVwLiAqL1xuZnVuY3Rpb24gaXNBdHRyaWJ1dGFibGUoZTogSW5nZXN0RXZlbnQpOiBib29sZWFuIHtcbiAgcmV0dXJuIChlLmV2ZW50VHlwZSA9PT0gJ0FDVElPTicgfHwgZS5ldmVudFR5cGUgPT09ICdCVUlMRCcpXG4gICAgJiYgKGUuZXZlbnRTb3VyY2UgPT09ICdjb2RlcGlwZWxpbmUnIHx8IGUuZXZlbnRTb3VyY2UgPT09ICdjb2RlYnVpbGQnKVxuICAgICYmICEhZS5zdGFnZU5hbWUgJiYgISFlLmFjdGlvbk5hbWU7XG59XG5cbmZ1bmN0aW9uIHN0ZXBLZXkocGlwZWxpbmVJZDogc3RyaW5nLCBzdGFnZU5hbWU6IHN0cmluZywgYWN0aW9uTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke3BpcGVsaW5lSWR9XFx1MDAwMCR7c3RhZ2VOYW1lfVxcdTAwMDAke2FjdGlvbk5hbWV9YDtcbn1cblxuLyoqXG4gKiBQbHVnaW4gYXR0cmlidXRpb24gQU5EIHRoZSBkZXBsb3llZCB0b29sY2hhaW4gcmVsZWFzZTogdGhlIHN0ZXAgbWFuaWZlc3RzIG9mXG4gKiBldmVyeSBwaXBlbGluZSB3aXRoIGFuIGF0dHJpYnV0YWJsZSBldmVudCwgaW4gT05FIHJlYWQgcGVyIGJhdGNoLCBrZXllZCBmb3JcbiAqIGFuIGluLW1lbW9yeSBqb2luLiBOYW1lcyBhcmUgY29tcGFyZWQgcG9zdC1zY3J1YiBvbiBib3RoIHNpZGVzICh0aGUgbWFuaWZlc3RcbiAqIHN0b3JlcyB0aGVtIHNjcnViYmVkIHRoZSBzYW1lIHdheSkuXG4gKlxuICogVGhlIHRvb2xjaGFpbiBtYXAgaXMgdGhlIFBMQVRGT1JNJ3MgcmVjb3JkIG9mIHdoYXQgd2FzIGRlcGxveWVkICh0aGVcbiAqIG1hbmlmZXN0J3MgYGJ1aWxkLWltYWdlYCBlbnRyeSkg4oCUIHRoZSBvbmx5IHNvdXJjZSB0aGUgwqc3IHJ1biBzdGFtcCBtYXkgdXNlLlxuICovXG5hc3luYyBmdW5jdGlvbiBsb2FkU3RlcFBsdWdpbnModHg6IENydWRUeCwgYXR0cmlidXRhYmxlOiBJbmdlc3RFdmVudFtdKTogUHJvbWlzZTx7IHN0ZXBzOiBNYXA8c3RyaW5nLCBTdGVwUGx1Z2luPjsgdG9vbGNoYWluOiBNYXA8c3RyaW5nLCBEZXBsb3llZFRvb2xjaGFpbj4gfT4ge1xuICBjb25zdCBwaXBlbGluZUlkcyA9IFsuLi5uZXcgU2V0KGF0dHJpYnV0YWJsZS5tYXAoKGUpID0+IGUucGlwZWxpbmVJZCkpXTtcbiAgaWYgKHBpcGVsaW5lSWRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHsgc3RlcHM6IG5ldyBNYXAoKSwgdG9vbGNoYWluOiBuZXcgTWFwKCkgfTtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHR4XG4gICAgLnNlbGVjdCh7XG4gICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGlwZWxpbmVJZCxcbiAgICAgIG9yZ0lkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3Qub3JnSWQsXG4gICAgICBzdGFnZU5hbWU6IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5zdGFnZU5hbWUsXG4gICAgICBhY3Rpb25OYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QuYWN0aW9uTmFtZSxcbiAgICAgIHBsdWdpblB1Ymxpc2hlcjogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBsdWdpblB1Ymxpc2hlcixcbiAgICAgIHBsdWdpblB1Ymxpc2hlcklkOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luUHVibGlzaGVySWQsXG4gICAgICBwbHVnaW5OYW1lOiBzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QucGx1Z2luTmFtZSxcbiAgICAgIHBsdWdpblZlcnNpb246IHNjaGVtYS5waXBlbGluZVN0ZXBNYW5pZmVzdC5wbHVnaW5WZXJzaW9uLFxuICAgICAgc3RlcEtleTogc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnN0ZXBLZXksXG4gICAgfSlcbiAgICAuZnJvbShzY2hlbWEucGlwZWxpbmVTdGVwTWFuaWZlc3QpXG4gICAgLndoZXJlKGluQXJyYXkoc2NoZW1hLnBpcGVsaW5lU3RlcE1hbmlmZXN0LnBpcGVsaW5lSWQsIHBpcGVsaW5lSWRzKSk7XG4gIHJldHVybiB7XG4gICAgc3RlcHM6IG5ldyBNYXAocm93cy5tYXAoKG0pID0+IFtzdGVwS2V5KG0ucGlwZWxpbmVJZCwgbS5zdGFnZU5hbWUsIG0uYWN0aW9uTmFtZSksIG1dKSksXG4gICAgdG9vbGNoYWluOiBkZXBsb3llZFRvb2xjaGFpbk9mKHJvd3MpLFxuICB9O1xufVxuXG4vKipcbiAqIEFsbG93YW5jZSBmb3IgY2xvY2sgc2tldyBiZXR3ZWVuIGFuIEFXUyBldmVudCdzIHNvdXJjZSBjbG9jayBhbmQgb3Vycy4gQSByZWFsXG4gKiBDb2RlUGlwZWxpbmUgZXZlbnQgY2FuIGNhcnJ5IGEgdGltZXN0YW1wIGEgbGl0dGxlIGFoZWFkIG9mIG91ciBgbm93YDsgd2l0aG91dFxuICogc29tZSB0b2xlcmFuY2UgdGhlIHZhbGlkYXRpb24gYmVsb3cgd291bGQgZHJvcCBoZWFsdGh5IGV2ZW50cyBkdXJpbmcgbm9ybWFsXG4gKiBOVFAgZHJpZnQsIHdoaWNoIGlzIGZhciB3b3JzZSB0aGFuIGFkbWl0dGluZyBhIGZldyBzZWNvbmRzIG9mIHNrZXcuXG4gKi9cbmNvbnN0IENMT0NLX1NLRVdfVE9MRVJBTkNFX01TID0gNSAqIDYwICogMTAwMDtcblxuLyoqXG4gKiBXaHkgdGhpcyBldmVudCdzIHRpbWVzdGFtcHMgYXJlIGltcG9zc2libGUsIG9yIG51bGwgd2hlbiB0aGV5IGFyZSB1c2FibGUuXG4gKlxuICogQ2hlY2tlZCBhdCBJTkdFU1Qg4oCUIHRoZSBkdXJhYmxlIGJvdW5kYXJ5IOKAlCByYXRoZXIgdGhhbiBjbGFtcGVkIHdoZW4gdGhlIG1ldHJpY3NcbiAqIGFyZSBjb21wdXRlZC4gQSBuZWdhdGl2ZSBkdXJhdGlvbiBvciBhIGZ1dHVyZSBkZXBsb3kgdXNlZCB0byBiZSBjbGFtcGVkIHRvIDBcbiAqIGRvd25zdHJlYW0sIHdoaWNoIHJlcG9ydGVkIGEgYnJva2VuIGNsb2NrIGFzIGFuIGluc3RhbnQgZGVwbG95IGFuZCBxdWlldGx5XG4gKiBtb3ZlZCBkZXBsb3ltZW50IGZyZXF1ZW5jeSwgY2hhbmdlLWZhaWx1cmUgcmF0ZSBhbmQgbGVhZCB0aW1lIGZvciB0aGUgb3JnLlxuICpcbiAqIE5PVCBjaGVja2VkIGhlcmU6IGNvbW1pdCB0aW1lIHZzIGRlcGxveSBjb21wbGV0aW9uLiBgY29tbWl0X3RpbWVzdGFtcGAgcmlkZXMgdGhlXG4gKiBQSVBFTElORS9zb3VyY2UgZXZlbnQgd2hpbGUgdGhlIGRlcGxveSdzIGBjb21wbGV0ZWRfYXRgIGlzIG9uIGEgc2VwYXJhdGUgU1RBR0VcbiAqIHJvdywgam9pbmVkIGJ5IGBleGVjdXRpb25faWRgIG9ubHkgd2hlbiBET1JBIGlzIHF1ZXJpZWQg4oCUIHNvIG5vIHNpbmdsZSBldmVudFxuICogY2FycmllcyBib3RoLCBhbmQgdGhhdCBvcmRlcmluZyBjYW4gb25seSBiZSBndWFyZGVkIHdoZXJlIHRoZSB0d28gbWVldC5cbiAqL1xuZnVuY3Rpb24gaW52YWxpZEV2ZW50VGltZXMoZXZlbnQ6IEluZ2VzdEV2ZW50LCBub3dNczogbnVtYmVyKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IGNlaWxpbmcgPSBub3dNcyArIENMT0NLX1NLRVdfVE9MRVJBTkNFX01TO1xuICBjb25zdCBwYXJzZWQ6IEFycmF5PFtzdHJpbmcsIG51bWJlcl0+ID0gW107XG4gIGZvciAoY29uc3QgZmllbGQgb2YgWydzdGFydGVkQXQnLCAnY29tcGxldGVkQXQnLCAnY29tbWl0VGltZXN0YW1wJ10gYXMgY29uc3QpIHtcbiAgICBjb25zdCByYXcgPSBldmVudFtmaWVsZF07XG4gICAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gbnVsbCkgY29udGludWU7XG4gICAgY29uc3QgbXMgPSBEYXRlLnBhcnNlKFN0cmluZyhyYXcpKTtcbiAgICBpZiAoIU51bWJlci5pc0Zpbml0ZShtcykpIHJldHVybiBgJHtmaWVsZH0gaXMgbm90IGEgcGFyc2VhYmxlIHRpbWVzdGFtcGA7XG4gICAgaWYgKG1zID4gY2VpbGluZykgcmV0dXJuIGAke2ZpZWxkfSBpcyBpbiB0aGUgZnV0dXJlYDtcbiAgICBwYXJzZWQucHVzaChbZmllbGQsIG1zXSk7XG4gIH1cbiAgY29uc3Qgc3RhcnRlZCA9IHBhcnNlZC5maW5kKChbZl0pID0+IGYgPT09ICdzdGFydGVkQXQnKT8uWzFdO1xuICBjb25zdCBjb21wbGV0ZWQgPSBwYXJzZWQuZmluZCgoW2ZdKSA9PiBmID09PSAnY29tcGxldGVkQXQnKT8uWzFdO1xuICBpZiAoc3RhcnRlZCAhPT0gdW5kZWZpbmVkICYmIGNvbXBsZXRlZCAhPT0gdW5kZWZpbmVkICYmIGNvbXBsZXRlZCA8IHN0YXJ0ZWQpIHtcbiAgICByZXR1cm4gJ2NvbXBsZXRlZEF0IGlzIGJlZm9yZSBzdGFydGVkQXQnO1xuICB9XG4gIGlmIChldmVudC5kdXJhdGlvbk1zICE9PSB1bmRlZmluZWQgJiYgZXZlbnQuZHVyYXRpb25NcyAhPT0gbnVsbCAmJiBldmVudC5kdXJhdGlvbk1zIDwgMCkge1xuICAgIHJldHVybiAnZHVyYXRpb25NcyBpcyBuZWdhdGl2ZSc7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogVGhlIHBlcnNpc3RlZCByb3cgZm9yIG9uZSBpbmdlc3RlZCBldmVudC4gVGhpcyBpcyB0aGUgRFVSQUJMRSBwZXJzaXN0ZW5jZVxuICogYm91bmRhcnk6IGV2ZXJ5IHVzZXIvQVdTLWRlcml2ZWQgZnJlZS1mb3JtIHN0cmluZyBpcyBzY3J1YmJlZCBoZXJlLCBhbmRcbiAqIHRlbmFuY3kgY29tZXMgZnJvbSB0aGUgcGlwZWxpbmUgcmVnaXN0cnksIG5ldmVyIHRoZSBjYWxsZXIncyBjbGFpbWVkIG9yZy5cbiAqL1xuLyoqIFRoZSBzeW50aCByZWZ1c2FsIGNvZGUgdGhlIGV2ZW50cyBMYW1iZGEgYXR0YWNoZWQgKGBkZXRhaWwucGJGYWlsdXJlLmNvZGVgKSwgaWYgYW55LiAqL1xuZnVuY3Rpb24gcGJGYWlsdXJlQ29kZShkZXRhaWw6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IGZhaWx1cmUgPSBkZXRhaWw/LnBiRmFpbHVyZTtcbiAgY29uc3QgY29kZSA9IGZhaWx1cmUgJiYgdHlwZW9mIGZhaWx1cmUgPT09ICdvYmplY3QnID8gKGZhaWx1cmUgYXMgeyBjb2RlPzogdW5rbm93biB9KS5jb2RlIDogdW5kZWZpbmVkO1xuICByZXR1cm4gdHlwZW9mIGNvZGUgPT09ICdzdHJpbmcnICYmIC9eW0EtWl1bQS1aMC05X117MCw2M30kLy50ZXN0KGNvZGUpID8gY29kZSA6IG51bGw7XG59XG5cbmZ1bmN0aW9uIHRvRXZlbnRSb3coXG4gIGV2ZW50OiBJbmdlc3RFdmVudCxcbiAgcmVnaXN0cnk6IHsgcGlwZWxpbmVJZDogc3RyaW5nOyBvcmdJZDogc3RyaW5nIH0sXG4gIHBsdWdpbjogU3RlcFBsdWdpbiB8IHVuZGVmaW5lZCxcbiAga2V5SWQ6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgdG9vbGNoYWluUmVsZWFzZTogc3RyaW5nIHwgbnVsbCxcbik6IFBpcGVsaW5lRXZlbnRJbnNlcnQge1xuICBjb25zdCBkZXRhaWwgPSBldmVudC5zb3VyY2VNZXNzYWdlSWQgIT09IHVuZGVmaW5lZFxuICAgID8geyAuLi4oZXZlbnQuZGV0YWlsID8/IHt9KSwgc291cmNlTWVzc2FnZUlkOiBldmVudC5zb3VyY2VNZXNzYWdlSWQgfVxuICAgIDogZXZlbnQuZGV0YWlsO1xuICByZXR1cm4ge1xuICAgIC8vIHJlZ2lzdHJ5LnBpcGVsaW5lSWQgPT09IGV2ZW50LnBpcGVsaW5lSWQ7IHRoZSByZWdpc3RyeSdzIGlzIGFsd2F5cyBhIHJvd1xuICAgIC8vIHRoYXQgZXhpc3RzIChGSykgYW5kIGl0cyBvcmdJZCBpcyB0aGUgdHJ1c3RlZCB0ZW5hbnQuXG4gICAgcGlwZWxpbmVJZDogcmVnaXN0cnkucGlwZWxpbmVJZCxcbiAgICBvcmdJZDogcmVnaXN0cnkub3JnSWQsXG4gICAgZXZlbnRTb3VyY2U6IGV2ZW50LmV2ZW50U291cmNlLFxuICAgIGV2ZW50VHlwZTogZXZlbnQuZXZlbnRUeXBlLFxuICAgIHN0YXR1czogZXZlbnQuc3RhdHVzLFxuICAgIC8vIEFuIEFXUy1BU1NJR05FRCBVVUlELCBub3QgZnJlZS1mb3JtIHRleHQ6IGl0IGNhbid0IGNhcnJ5IGFuIGFjY291bnQgaWQsXG4gICAgLy8gYW5kIHNjcnViYmluZyBhIDEyLWRpZ2l0IHJ1biBpbnNpZGUgaXQgd291bGQgY29ycnVwdCB0aGUgY29ycmVsYXRpb24ga2V5LlxuICAgIGV4ZWN1dGlvbklkOiBldmVudC5leGVjdXRpb25JZCxcbiAgICAvLyBVU0VSLUFVVEhPUkVEIHBpcGVsaW5lLXN0cnVjdHVyZSBuYW1lcyDigJQgc2FtZSB1bnRydXN0ZWQgb3JpZ2luIGFzXG4gICAgLy8gZXJyb3JNZXNzYWdlLCBzbyBzY3J1YmJlZCAoYSBzdGFnZSBuYW1lZCB3aXRoIGFuIEFSTiBtdXN0IG5vdCBwZXJzaXN0KS5cbiAgICBzdGFnZU5hbWU6IHNjcnViT3B0aW9uYWwoZXZlbnQuc3RhZ2VOYW1lKSxcbiAgICBhY3Rpb25OYW1lOiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmFjdGlvbk5hbWUpLFxuICAgIC8vIEhBUkQgQ09OU1RSQUlOVDogYW4gQVdTIGFjY291bnQgaWQgbXVzdCBORVZFUiBiZSBwZXJzaXN0ZWQuIEZhaWx1cmUgZGV0YWlsXG4gICAgLy8gYW5kIG1lc3NhZ2VzIHJvdXRpbmVseSBjYXJyeSBBUk5zIGFuZCBiYXJlIDEyLWRpZ2l0IGFjY291bnQgaWRzLlxuICAgIGVycm9yTWVzc2FnZTogc2NydWJPcHRpb25hbChldmVudC5lcnJvck1lc3NhZ2UpLFxuICAgIHN0YXJ0ZWRBdDogZXZlbnQuc3RhcnRlZEF0ID8gbmV3IERhdGUoZXZlbnQuc3RhcnRlZEF0KSA6IHVuZGVmaW5lZCxcbiAgICBjb21wbGV0ZWRBdDogZXZlbnQuY29tcGxldGVkQXQgPyBuZXcgRGF0ZShldmVudC5jb21wbGV0ZWRBdCkgOiB1bmRlZmluZWQsXG4gICAgZHVyYXRpb25NczogZXZlbnQuZHVyYXRpb25NcyxcbiAgICAvLyBEZXBsb3kgYXR0cmlidXRpb24g4oCUIHNjcnViYmVkIGxpa2UgdGhlIG90aGVyIGZyZWUtZm9ybSBzdHJpbmdzLlxuICAgIGNvbW1pdFNoYTogc2NydWJPcHRpb25hbChldmVudC5jb21taXRTaGEpLFxuICAgIGNvbW1pdFJlZjogc2NydWJPcHRpb25hbChldmVudC5jb21taXRSZWYpLFxuICAgIGVudmlyb25tZW50OiBzY3J1Yk9wdGlvbmFsKGV2ZW50LmVudmlyb25tZW50KSxcbiAgICAvLyBNZWFzdXJlZCBsZWFkIHRpbWU6IHRoZSBvbGRlc3QgdW5zaGlwcGVkIGNvbW1pdCdzIHRpbWUgKyB0aGUgY291bnQuIEFuXG4gICAgLy8gU0NNLWRlcml2ZWQgaW5zdGFudCBhbmQgYSBwbGFpbiBpbnRlZ2VyIOKAlCBub3RoaW5nIHRvIHNjcnViLlxuICAgIGNvbW1pdFRpbWVzdGFtcDogZXZlbnQuY29tbWl0VGltZXN0YW1wID8gbmV3IERhdGUoZXZlbnQuY29tbWl0VGltZXN0YW1wKSA6IHVuZGVmaW5lZCxcbiAgICBjb21taXRDb3VudDogZXZlbnQuY29tbWl0Q291bnQsXG4gICAgLy8gTlVMTCBmb3Igbm9uLXBsdWdpbiBhY3Rpb25zIGFuZCBmb3IgcGlwZWxpbmVzIGRlcGxveWVkIHdpdGhvdXQgYSBtYW5pZmVzdC5cbiAgICBwbHVnaW5QdWJsaXNoZXI6IHBsdWdpbj8ucGx1Z2luUHVibGlzaGVyID8/IG51bGwsXG4gICAgcGx1Z2luUHVibGlzaGVySWQ6IHBsdWdpbj8ucGx1Z2luUHVibGlzaGVySWQgPz8gbnVsbCxcbiAgICBwbHVnaW5OYW1lOiBwbHVnaW4/LnBsdWdpbk5hbWUgPz8gbnVsbCxcbiAgICBwbHVnaW5WZXJzaW9uOiBwbHVnaW4/LnBsdWdpblZlcnNpb24gPz8gbnVsbCxcbiAgICAvLyBUaGUgbWFuYWdlZCB0b29sY2hhaW4gcmVsZWFzZSBhIHN5bnRoIC8gc2VsZi1tdXRhdGlvbiBhY3Rpb24gcmFuIG9uLCBmcm9tXG4gICAgLy8gdGhlIHBsYXRmb3JtJ3MgZGVwbG95ZWQgbWFuaWZlc3QgKG5ldmVyIHRoZSBwYXlsb2FkKS4gTlVMTCBvdGhlcndpc2UuXG4gICAgdG9vbGNoYWluUmVsZWFzZSxcbiAgICAvLyBXSEFUIEtJTkQgb2YgdGhpbmcgYnJva2UsIGNsYXNzaWZpZWQgaGVyZSByYXRoZXIgdGhhbiBhdCByZWFkIHRpbWU6IHRoZVxuICAgIC8vIGVycm9yIHRleHQgaXMgc2NydWJiZWQgYWJvdmUgYW5kIGV2ZW50dWFsbHkgc3dlcHQgYnkgcmV0ZW50aW9uLCBzbyBhXG4gICAgLy8gY2F0ZWdvcnkgZGVyaXZlZCBsYXRlciB3b3VsZCBoYXZlIG5vdGhpbmcgbGVmdCB0byByZWFkLiBOVUxMIGZvciBhbnl0aGluZ1xuICAgIC8vIHRoYXQgaXMgbm90IGEgZmFpbHVyZSwgc28gaXRzIHByZXNlbmNlIGFsd2F5cyBtZWFucyBcInRoaXMgYnJva2VcIi5cbiAgICBmYWlsdXJlQ2F0ZWdvcnk6IGNsYXNzaWZ5RmFpbHVyZSh7XG4gICAgICBzdGF0dXM6IGV2ZW50LnN0YXR1cyxcbiAgICAgIGVycm9yTWVzc2FnZTogc2NydWJPcHRpb25hbChldmVudC5lcnJvck1lc3NhZ2UpLFxuICAgICAgYWN0aW9uTmFtZTogc2NydWJPcHRpb25hbChldmVudC5hY3Rpb25OYW1lKSxcbiAgICAgIHN0YWdlTmFtZTogc2NydWJPcHRpb25hbChldmVudC5zdGFnZU5hbWUpLFxuICAgICAgZmFpbHVyZUNvZGU6IHBiRmFpbHVyZUNvZGUoZXZlbnQuZGV0YWlsKSxcbiAgICB9KSxcbiAgICAvLyBQcm92ZW5hbmNlLiBCb3RoIGFyZSBvcGFxdWUgaWRzIOKAlCBhbiBBV1MtYXNzaWduZWQgZXZlbnQgVVVJRCBhbmQgb3VyIG93blxuICAgIC8vIGtleSBpZCDigJQgc28gbmVpdGhlciBjYW4gY2FycnkgYW4gYWNjb3VudCBpZCBhbmQgbmVpdGhlciBpcyBzY3J1YmJlZFxuICAgIC8vIChzY3J1YmJpbmcgYSBkaWdpdCBydW4gaW5zaWRlIG9uZSB3b3VsZCBjb3JydXB0IHRoZSBjb3JyZWxhdGlvbiBrZXkpLlxuICAgIHNvdXJjZUV2ZW50SWQ6IGV2ZW50LnNvdXJjZUV2ZW50SWQsXG4gICAgaW5nZXN0S2V5SWQ6IGtleUlkLFxuICAgIGRldGFpbDogZGV0YWlsICE9PSB1bmRlZmluZWQgPyBzY3J1YkF3c0lkZW50aWZpZXJzKGRldGFpbCkgOiB1bmRlZmluZWQsXG4gIH07XG59XG5cbi8qKlxuICogRmFuIHRlcm1pbmFsIFNUQUdFIG91dGNvbWVzIGFuZCBwZXItQUNUSU9OIGNvbXB1dGUgY29uc3VtcHRpb24gaW50byB0aGVcbiAqIHJvdXRlJ3MgbWV0cmljIGhvb2sgKHBpcGVsaW5lLWRhdGEgY2FuJ3QgaW1wb3J0IGFwaS1zZXJ2ZXIncyByZWdpc3RyeSkgYWZ0ZXJcbiAqIHRoZSBpbnNlcnQgY29tbWl0cy5cbiAqXG4gKiBEcml2ZW4gb2ZmIHRoZSBJTlNFUlRFRCByb3dzLCBzbyBhIHJlLWRlbGl2ZXJlZCBldmVudCB0aGUgZGVkdXAgaW5kZXhcbiAqIHN3YWxsb3dlZCBpcyBuZXZlciBjb3VudGVkIHR3aWNlLiBUaGF0IHByb3BlcnR5IGlzIGxvYWQtYmVhcmluZyBmb3IgdGhlXG4gKiBjb21wdXRlIHNlcmllcyBpbiBhIHdheSBpdCB3YXMgbm90IGZvciB0aGUgc3RhZ2Ugb25lOiBhIGR1cGxpY2F0ZWQgc3RhZ2VcbiAqIG91dGNvbWUgZGlzdG9ydHMgYSByYXRlLCB3aGVyZWFzIGEgZHVwbGljYXRlZCB2Q1BVLW1pbnV0ZSBmaWd1cmUgaXMgYVxuICogZG91YmxlLWNoYXJnZSB3YWl0aW5nIGZvciB0aGUgZGF5IHRoZSBjaGFyZ2UgaXMgc3dpdGNoZWQgb24uXG4gKlxuICogQSBub24tbnVsbCBlbnZpcm9ubWVudCBtYXJrcyBhIGRlcGxveS5cbiAqL1xuZnVuY3Rpb24gZW1pdEluZ2VzdE1ldHJpY3MoXG4gIHJvd3M6IFJlYWRvbmx5QXJyYXk8e1xuICAgIG9yZ0lkOiBzdHJpbmc7XG4gICAgcGlwZWxpbmVJZDogc3RyaW5nIHwgbnVsbDtcbiAgICBldmVudFR5cGU6IHN0cmluZztcbiAgICBzdGF0dXM6IHN0cmluZztcbiAgICBzdGFnZU5hbWU6IHN0cmluZyB8IG51bGw7XG4gICAgYWN0aW9uTmFtZT86IHN0cmluZyB8IG51bGw7XG4gICAgZW52aXJvbm1lbnQ6IHN0cmluZyB8IG51bGw7XG4gICAgZHVyYXRpb25Ncz86IG51bWJlciB8IG51bGw7XG4gICAgZGV0YWlsPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBudWxsO1xuICAgIHRvb2xjaGFpblJlbGVhc2U/OiBzdHJpbmcgfCBudWxsO1xuICB9PixcbiAgb25NZXRyaWM6IChtOiBJbmdlc3RNZXRyaWMpID0+IHZvaWQsXG4gIHBsYXRmb3JtRGVmYXVsdFJlbGVhc2U6IHN0cmluZyB8IG51bGwsXG4pOiB2b2lkIHtcbiAgZm9yIChjb25zdCByIG9mIHJvd3MpIHtcbiAgICBpZiAoIXIucGlwZWxpbmVJZCkgY29udGludWU7XG5cbiAgICAvLyBUb29sY2hhaW4gcnVucyAowqc3LCBhbGVydGluZyBvbmx5KTogYSB0ZXJtaW5hbCBvdXRjb21lIG9uIGEgc3RhbXBlZCByb3cuXG4gICAgLy8gTm90IGV4Y2x1c2l2ZSDigJQgdGhlIHNhbWUgYWN0aW9uIGlzIGFsc28gYSBjb21wdXRlIG1lYXN1cmVtZW50IGJlbG93LlxuICAgIGNvbnN0IG91dGNvbWUgPSByLnRvb2xjaGFpblJlbGVhc2UgPyB0b29sY2hhaW5PdXRjb21lT2Yoci5zdGF0dXMpIDogbnVsbDtcbiAgICBpZiAoci50b29sY2hhaW5SZWxlYXNlICYmIG91dGNvbWUpIHtcbiAgICAgIG9uTWV0cmljKHtcbiAgICAgICAga2luZDogJ3Rvb2xjaGFpbicsXG4gICAgICAgIHRvb2xjaGFpblJlbGVhc2U6IHIudG9vbGNoYWluUmVsZWFzZSxcbiAgICAgICAgLy8gU3RhbXBlZCByb3dzIGFyZSBvbmx5IGV2ZXIgc3ludGggb3Igc2VsZi1tdXRhdGlvbi5cbiAgICAgICAgYWN0aW9uOiByLnN0YWdlTmFtZSA9PT0gU0VMRl9NVVRBVElPTl9TVEFHRSAmJiByLmFjdGlvbk5hbWUgPT09IFNFTEZfTVVUQVRJT05fQUNUSU9OID8gJ3NlbGYtbXV0YXRpb24nIDogJ3N5bnRoJyxcbiAgICAgICAgb3V0Y29tZSxcbiAgICAgICAgcGxhdGZvcm1EZWZhdWx0UmVsZWFzZSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENvbXB1dGUgY29uc3VtcHRpb246IGV2ZXJ5IFRFUk1JTkFMIGFjdGlvbiwgbWVhc3VyYWJsZSBvciBub3QuIFRoZVxuICAgIC8vIHVubWVhc3VyYWJsZSBvbmVzIGFyZSB0aGUgcG9pbnQg4oCUIHRoZXkgYXJlIHdoYXQgdGhlIGNvdmVyYWdlIHJhdGlvIGNvdW50cy5cbiAgICBpZiAoci5ldmVudFR5cGUgPT09ICdBQ1RJT04nICYmIFRFUk1JTkFMX0FDVElPTl9TVEFURVMuaW5jbHVkZXMoci5zdGF0dXMpKSB7XG4gICAgICBjb25zdCBjb21wdXRlVHlwZSA9IG5vcm1hbGl6ZUNvbXB1dGVUeXBlKFxuICAgICAgICB0eXBlb2Ygci5kZXRhaWw/LmNvbXB1dGVUeXBlID09PSAnc3RyaW5nJyA/IHIuZGV0YWlsLmNvbXB1dGVUeXBlIDogbnVsbCxcbiAgICAgICk7XG4gICAgICBjb25zdCBkdXJhdGlvbk1zID0gci5kdXJhdGlvbk1zID8/IG51bGw7XG4gICAgICBvbk1ldHJpYyh7XG4gICAgICAgIGtpbmQ6ICdjb21wdXRlJyxcbiAgICAgICAgcGlwZWxpbmVJZDogci5waXBlbGluZUlkLFxuICAgICAgICBvcmdJZDogci5vcmdJZCxcbiAgICAgICAgY29tcHV0ZVR5cGUsXG4gICAgICAgIGR1cmF0aW9uTXMsXG4gICAgICAgIGNyZWRpdHM6IGNvbXB1dGVDcmVkaXRzRm9yKGR1cmF0aW9uTXMsIGNvbXB1dGVUeXBlKSxcbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHIuZXZlbnRUeXBlICE9PSAnU1RBR0UnIHx8IChyLnN0YXR1cyAhPT0gJ1NVQ0NFRURFRCcgJiYgci5zdGF0dXMgIT09ICdGQUlMRUQnKSkgY29udGludWU7XG4gICAgb25NZXRyaWMoe1xuICAgICAga2luZDogJ3N0YWdlJyxcbiAgICAgIHBpcGVsaW5lSWQ6IHIucGlwZWxpbmVJZCxcbiAgICAgIG9yZ0lkOiByLm9yZ0lkLFxuICAgICAgc3RhZ2U6IHIuc3RhZ2VOYW1lID8/ICcnLFxuICAgICAgZW52aXJvbm1lbnQ6IHIuZW52aXJvbm1lbnQgPz8gbnVsbCxcbiAgICAgIHJlc3VsdDogci5zdGF0dXMgPT09ICdTVUNDRUVERUQnID8gJ3N1Y2NlZWRlZCcgOiAnZmFpbGVkJyxcbiAgICB9KTtcbiAgfVxufVxuXG4vKiogQWN0aW9uIHN0YXRlcyB0aGF0IG1lYW4gdGhlIGFjdGlvbiBpcyBvdmVyIGFuZCBpdHMgY29uc3VtcHRpb24gaXMgZmluYWwuICovXG5jb25zdCBURVJNSU5BTF9BQ1RJT05fU1RBVEVTOiByZWFkb25seSBzdHJpbmdbXSA9IFsnU1VDQ0VFREVEJywgJ0ZBSUxFRCcsICdTVE9QUEVEJ107XG5cbi8qKlxuICogUmVzb2x2ZSBpbmNvbWluZyBldmVudHMgYWdhaW5zdCB0aGUgcGlwZWxpbmUgcmVnaXN0cnksIGJhdGNoLWluc2VydCB0aGVcbiAqIG1hdGNoZWQgb25lcywgYW5kIGludmFsaWRhdGUgcmVwb3J0aW5nIGNhY2hlcyBmb3IgYWZmZWN0ZWQgb3Jncy5cbiAqIEV2ZW50cyBmb3IgdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkcyBhcmUgZHJvcHBlZCAoYW5kIGxvZ2dlZCBhdCBXQVJOXG4gKiB3aXRoIHNhbXBsZSBpZHMgc28gYW4gb3BlcmF0b3IgY2FuIHNlZSB3aGVuIEV2ZW50QnJpZGdlIGlzIGRlbGl2ZXJpbmdcbiAqIGV2ZW50cyBmb3IgcGlwZWxpbmVzIHRoYXQgaGF2ZW4ndCBjYWxsZWQgUE9TVCAvcGlwZWxpbmVzL3JlZ2lzdHJ5IHlldCkuXG4gKlxuICogUmV0dXJucyBjb3VudHMgKyBhIHNhbXBsZSBvZiB1bnJlZ2lzdGVyZWQgcGlwZWxpbmUgaWRzIGZvciBvYnNlcnZhYmlsaXR5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5nZXN0RXZlbnRzKFxuICBldmVudHM6IEluZ2VzdEV2ZW50W10sXG4gIG9uTWV0cmljPzogKG06IEluZ2VzdE1ldHJpYykgPT4gdm9pZCxcbiAgY2FsbGVyPzogSW5nZXN0Q2FsbGVyLFxuKTogUHJvbWlzZTxJbmdlc3RSZXN1bHQ+IHtcbiAgLy8gVEVOQU5DWS4gQW4gZXZlbnQncyBvcmcgY29tZXMgZnJvbSB0aGUgcGlwZWxpbmUgUkVHSVNUUlksIG5vdCB0aGUgdG9rZW4sIHNvXG4gIC8vIHRoZSBzY29wZSBjaGVjayBhbG9uZSBsZXQgYW55IGByZXBvcnRpbmc6aW5nZXN0YCBob2xkZXIgcG9zdCBldmVudHMgZm9yXG4gIC8vIGFub3RoZXIgb3JnJ3MgcGlwZWxpbmUgaWQgYW5kIGhhdmUgdGhlbSBhdHRyaWJ1dGVkIHRoZXJlLiBgY2FsbGVyYCBjYXJyaWVzXG4gIC8vIHRoZSBvcmcgaWRzIHRoaXMgdG9rZW4gbWF5IHdyaXRlIGZvcjsgYW55dGhpbmcgZWxzZSBpcyBkcm9wcGVkIGJlbG93LlxuICAvL1xuICAvLyBgY2FsbGVyYCBpcyBvcHRpb25hbCBvbmx5IHNvIGluLXByb2Nlc3MgY2FsbGVycyB0aGF0IGFscmVhZHkgcnVuXG4gIC8vIGNyb3NzLXRlbmFudCAodGVzdHMsIGJhY2tmaWxscykga2VlcCB3b3JraW5nIOKAlCBhbiBBQlNFTlQgY2FsbGVyIG1lYW5zIFwibm9cbiAgLy8gcmVzdHJpY3Rpb25cIiwgYW5kIHRoZSByb3V0ZSBhbHdheXMgc3VwcGxpZXMgb25lLiBBIGNhbGxlciB3aXRoIGFuIEVNUFRZXG4gIC8vIGFsbG93LWxpc3QgYW5kIG5vIGNyb3NzVGVuYW50IGZsYWcgdGhlcmVmb3JlIGRyb3BzIGV2ZXJ5dGhpbmcsIHdoaWNoIGlzIHRoZVxuICAvLyByaWdodCBhbnN3ZXIgd2hlbiB0aGUgcm91dGUgY291bGQgbm90IGVzdGFibGlzaCB3aG8gaXMgd3JpdGluZy5cbiAgY29uc3QgdW5yZXN0cmljdGVkID0gY2FsbGVyID09PSB1bmRlZmluZWQgfHwgY2FsbGVyLmNyb3NzVGVuYW50ID09PSB0cnVlO1xuICBjb25zdCBhbGxvd2VkID0gbmV3IFNldChjYWxsZXI/LmFsbG93ZWRPcmdJZHMgPz8gW10pO1xuICAvLyBNdWx0aS1vcmcgYmF0Y2ggaW5zZXJ0OiB0aGUgY2FsbGVyIHJlc29sdmVzIHRvIG11bHRpcGxlIG9yZ3MgdmlhIHRoZVxuICAvLyBwaXBlbGluZS1yZWdpc3RyeSBsb29rdXAgYmVsb3csIHNvIHRoZSByb3V0ZSBsYXllciBNVVNUIGVzdGFibGlzaCBhXG4gIC8vIGBydW5XaXRoVGVuYW50Q29udGV4dCh7IGlzU3VwZXJBZG1pbjogdHJ1ZSB9LCAuLi4pYCBzY29wZSBiZWZvcmUgY2FsbGluZ1xuICAvLyB0aGlzIGZ1bmN0aW9uLiBVbmRlciBGT1JDRSdkIFJMUywgYSBzaW5nbGUgdHggd2l0aCBgYXBwLm9yZ19pZCA9IDxvbmVcbiAgLy8gb3JnPmAgY291bGQgb25seSB3cml0ZSBldmVudHMgZm9yIHRoYXQgb3JnOyBieXBhc3MgdmlhIHN5c2FkbWluIGlzXG4gIC8vIHRoZSByaWdodCBnYXRlIGZvciB0aGlzIHNlcnZlci1pbnRlcm5hbCBjcm9zcy10ZW5hbnQgZW5kcG9pbnQuIFNlZVxuICAvLyBhcGkvcmVwb3J0aW5nL3NyYy9yb3V0ZXMvZXZlbnQtaW5nZXN0LnRzIGZvciB0aGUgd3JhcHBlci5cbiAgLy8gQ2FjaGVzIGFyZSBpbnZhbGlkYXRlZCBBRlRFUiB0aGUgdHggcmVzb2x2ZXM6IGRvaW5nIGl0IGluc2lkZSBoZWxkIHRoZSBwZ1xuICAvLyBsb2NrcyBvcGVuIGFjcm9zcyB1bnJlbGF0ZWQgY2FjaGUgcm91bmQtdHJpcHMuIFRoZSBUVEwgaXMgMi01IG1pbiwgc28gYVxuICAvLyBmaXJlLWFuZC1mb3JnZXQgcG9zdC1jb21taXQgaW52YWxpZGF0aW9uIGlzIGFuIGFjY2VwdGFibGUgdHJhZGUuXG4gIGNvbnN0IHsgaW5zZXJ0ZWQsIHNraXBwZWQsIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLCBhZmZlY3RlZE9yZ3MsIGRyb3BwZWRGb3JlaWduT3JnLCBkcm9wcGVkSW52YWxpZFRpbWUsIGZvcmVpZ25QaXBlbGluZUlkcywgaW5zZXJ0ZWRSb3dzLCBwbGF0Zm9ybURlZmF1bHRSZWxlYXNlIH0gPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB7XG4gICAgLy8gQmF0Y2gtcmVzb2x2ZSBhbGwgdW5pcXVlIHBpcGVsaW5lIGlkcyBpbiBvbmUgcXVlcnlcbiAgICBjb25zdCB1bmlxdWVJZHMgPSBbLi4ubmV3IFNldChldmVudHMubWFwKGUgPT4gZS5waXBlbGluZUlkKSldO1xuICAgIGNvbnN0IHJlZ2lzdHJ5Um93cyA9IGF3YWl0IHR4XG4gICAgICAuc2VsZWN0KHtcbiAgICAgICAgcGlwZWxpbmVJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkucGlwZWxpbmVJZCxcbiAgICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5Lm9yZ0lkLFxuICAgICAgfSlcbiAgICAgIC5mcm9tKHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5KVxuICAgICAgLndoZXJlKGluQXJyYXkoc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkucGlwZWxpbmVJZCwgdW5pcXVlSWRzKSk7XG5cbiAgICBjb25zdCBpZE1hcCA9IG5ldyBNYXAocmVnaXN0cnlSb3dzLm1hcChyID0+IFtyLnBpcGVsaW5lSWQsIHJdKSk7XG4gICAgY29uc3QgeyBzdGVwczogc3RlcFBsdWdpbnMsIHRvb2xjaGFpbiB9ID0gYXdhaXQgbG9hZFN0ZXBQbHVnaW5zKHR4LCBldmVudHMuZmlsdGVyKChlKSA9PiBpc0F0dHJpYnV0YWJsZShlKSAmJiBpZE1hcC5oYXMoZS5waXBlbGluZUlkKSkpO1xuXG4gICAgLy8gQnVpbGQgaW5zZXJ0IGJhdGNoIChza2lwIGV2ZW50cyB3aG9zZSBwaXBlbGluZSBpc24ndCByZWdpc3RlcmVkKVxuICAgIGNvbnN0IHJvd3M6IFBpcGVsaW5lRXZlbnRJbnNlcnRbXSA9IFtdO1xuICAgIGxldCBza2lwcGVkTG9jYWwgPSAwO1xuICAgIGxldCBmb3JlaWduTG9jYWwgPSAwO1xuICAgIGxldCBpbnZhbGlkVGltZUxvY2FsID0gMDtcbiAgICBjb25zdCBpbnZhbGlkVGltZVJlYXNvbnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCBmb3JlaWduT3JnSWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgZm9yZWlnblBpcGVsaW5lSWRzTG9jYWwgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCB1bnJlZ2lzdGVyZWRMb2NhbDogc3RyaW5nW10gPSBbXTtcbiAgICAvLyBPbmUgYG5vd2AgZm9yIHRoZSB3aG9sZSBiYXRjaDogcGVyLWV2ZW50IGNsb2NrcyB3b3VsZCBsZXQgYW4gZXZlbnQgcGFzcyBvclxuICAgIC8vIGZhaWwgZGVwZW5kaW5nIG9uIHdoZXJlIGl0IHNhdCBpbiB0aGUgbG9vcC5cbiAgICBjb25zdCBub3dNcyA9IERhdGUubm93KCk7XG5cbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIGV2ZW50cykge1xuICAgICAgY29uc3QgcmVnaXN0cnkgPSBpZE1hcC5nZXQoZXZlbnQucGlwZWxpbmVJZCk7XG4gICAgICBpZiAoIXJlZ2lzdHJ5KSB7XG4gICAgICAgIHNraXBwZWRMb2NhbCsrO1xuICAgICAgICB1bnJlZ2lzdGVyZWRMb2NhbC5wdXNoKGV2ZW50LnBpcGVsaW5lSWQpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIC8vIFRoZSBwaXBlbGluZSByZXNvbHZlcyB0byBhbiBvcmcgdGhpcyBjYWxsZXIgbWF5IG5vdCB3cml0ZSBmb3IuIENvdW50ZWRcbiAgICAgIC8vIHNlcGFyYXRlbHkgZnJvbSBgc2tpcHBlZGAgKGFuIHVucmVnaXN0ZXJlZCBpZCBpcyBhIHByb2R1Y2VyIHJ1bm5pbmdcbiAgICAgIC8vIGFoZWFkIG9mIHJlZ2lzdHJhdGlvbjsgdGhpcyBpcyBhIHRlbmFuY3kgcmVmdXNhbCkgYW5kIG5ldmVyIGluc2VydGVkLlxuICAgICAgaWYgKCF1bnJlc3RyaWN0ZWQgJiYgIWFsbG93ZWQuaGFzKHJlZ2lzdHJ5Lm9yZ0lkKSkge1xuICAgICAgICBmb3JlaWduTG9jYWwrKztcbiAgICAgICAgZm9yZWlnbk9yZ0lkcy5hZGQocmVnaXN0cnkub3JnSWQpO1xuICAgICAgICBmb3JlaWduUGlwZWxpbmVJZHNMb2NhbC5hZGQoZXZlbnQucGlwZWxpbmVJZCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gSW1wb3NzaWJsZSB0aW1lc3RhbXBzIGFyZSByZWZ1c2VkIGF0IHRoZSBib3VuZGFyeSwgc28gbm8gZG93bnN0cmVhbVxuICAgICAgLy8gbWV0cmljIGhhcyB0byBjbGFtcCBhIG5lZ2F0aXZlIGdhcCBhbmQgY2FsbCBpdCB6ZXJvLlxuICAgICAgY29uc3QgYmFkVGltZSA9IGludmFsaWRFdmVudFRpbWVzKGV2ZW50LCBub3dNcyk7XG4gICAgICBpZiAoYmFkVGltZSkge1xuICAgICAgICBpbnZhbGlkVGltZUxvY2FsKys7XG4gICAgICAgIGludmFsaWRUaW1lUmVhc29ucy5hZGQoYmFkVGltZSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhZ2VOYW1lID0gc2NydWJPcHRpb25hbChldmVudC5zdGFnZU5hbWUpO1xuICAgICAgY29uc3QgYWN0aW9uTmFtZSA9IHNjcnViT3B0aW9uYWwoZXZlbnQuYWN0aW9uTmFtZSk7XG4gICAgICBjb25zdCBzdGVwID0gaXNBdHRyaWJ1dGFibGUoZXZlbnQpICYmIHN0YWdlTmFtZSAmJiBhY3Rpb25OYW1lXG4gICAgICAgID8gc3RlcFBsdWdpbnMuZ2V0KHN0ZXBLZXkocmVnaXN0cnkucGlwZWxpbmVJZCwgc3RhZ2VOYW1lLCBhY3Rpb25OYW1lKSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAvLyBUaGUgdG9vbGNoYWluIHN0YW1wOiBpcyB0aGlzIHRoZSBwaXBlbGluZSdzIHN5bnRoIC8gc2VsZi1tdXRhdGlvblxuICAgICAgLy8gYWN0aW9uLCBhbmQgd2hpY2ggcmVsZWFzZSBkaWQgdGhlIHBsYXRmb3JtIGRlcGxveSBpdCB3aXRoP1xuICAgICAgY29uc3QgZGVwbG95ZWQgPSB0b29sY2hhaW4uZ2V0KHJlZ2lzdHJ5LnBpcGVsaW5lSWQpO1xuICAgICAgY29uc3Qgc2FtZU9yZ0RlcGxveWVkID0gZGVwbG95ZWQgJiYgZGVwbG95ZWQub3JnSWQgPT09IHJlZ2lzdHJ5Lm9yZ0lkID8gZGVwbG95ZWQgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCB0b29sY2hhaW5SZWxlYXNlID0gdG9vbGNoYWluQWN0aW9uT2YoeyBldmVudFR5cGU6IGV2ZW50LmV2ZW50VHlwZSwgc3RhZ2VOYW1lLCBhY3Rpb25OYW1lIH0sIHNhbWVPcmdEZXBsb3llZClcbiAgICAgICAgPyBzYW1lT3JnRGVwbG95ZWQhLnJlbGVhc2VWZXJzaW9uXG4gICAgICAgIDogbnVsbDtcbiAgICAgIC8vIFNhbWUtb3JnIGd1YXJkOiBhIG1hbmlmZXN0IHJvdyBpcyBvbmx5IGV2ZXIgd3JpdHRlbiBieSB0aGUgb3JnIHRoYXRcbiAgICAgIC8vIG93bnMgdGhlIHBpcGVsaW5lLCBidXQgdGhlIGluZ2VzdCBydW5zIGNyb3NzLXRlbmFudCwgc28gZG9uJ3QgbGVhbiBvbiBpdC5cbiAgICAgIHJvd3MucHVzaCh0b0V2ZW50Um93KGV2ZW50LCByZWdpc3RyeSwgc3RlcCAmJiBzdGVwLm9yZ0lkID09PSByZWdpc3RyeS5vcmdJZCA/IHN0ZXAgOiB1bmRlZmluZWQsIGNhbGxlcj8ua2V5SWQsIHRvb2xjaGFpblJlbGVhc2UpKTtcbiAgICB9XG5cbiAgICAvLyBTUVMgaXMgYXQtbGVhc3Qtb25jZSwgc28gRXZlbnRCcmlkZ2UgY2FuIGRlbGl2ZXIgdGhlIHNhbWUgc3RhdGUtY2hhbmdlXG4gICAgLy8gdHdpY2UuIGBvbkNvbmZsaWN0RG9Ob3RoaW5nYCArIHRoZSBwYXJ0aWFsIHVuaXF1ZSBpbmRleGVzIG9uXG4gICAgLy8gKHBpcGVsaW5lX2lkLCBleGVjdXRpb25faWQsIGV2ZW50X3R5cGUsIHN0YXR1cywgc3RhZ2VfbmFtZSwgYWN0aW9uX25hbWUpXG4gICAgLy8gYW5kIG9uIHNvdXJjZV9ldmVudF9pZCAodGhlIEV2ZW50QnJpZGdlIGlkLCB3aGVuIHByZXNlbnQpIG1ha2VcbiAgICAvLyByZS1kZWxpdmVyeSBpZGVtcG90ZW50LiBgcmV0dXJuaW5nYCBnaXZlcyB0aGUgUkVBTCBpbnNlcnRlZCBzZXQgc29cbiAgICAvLyBjb3VudHMsIG1ldHJpY3MgYW5kIGNhY2hlIGludmFsaWRhdGlvbiBhbGwgaWdub3JlIGR1cGxpY2F0ZXMuXG4gICAgY29uc3QgbGFuZGVkID0gcm93cy5sZW5ndGggPiAwXG4gICAgICA/IGF3YWl0IHR4Lmluc2VydChzY2hlbWEucGlwZWxpbmVFdmVudCkudmFsdWVzKHJvd3MpXG4gICAgICAgIC5vbkNvbmZsaWN0RG9Ob3RoaW5nKClcbiAgICAgICAgLnJldHVybmluZyh7XG4gICAgICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50Lm9yZ0lkLFxuICAgICAgICAgIHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LnBpcGVsaW5lSWQsXG4gICAgICAgICAgZXZlbnRUeXBlOiBzY2hlbWEucGlwZWxpbmVFdmVudC5ldmVudFR5cGUsXG4gICAgICAgICAgc3RhdHVzOiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGF0dXMsXG4gICAgICAgICAgc3RhZ2VOYW1lOiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGFnZU5hbWUsXG4gICAgICAgICAgYWN0aW9uTmFtZTogc2NoZW1hLnBpcGVsaW5lRXZlbnQuYWN0aW9uTmFtZSxcbiAgICAgICAgICBlbnZpcm9ubWVudDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuZW52aXJvbm1lbnQsXG4gICAgICAgICAgdG9vbGNoYWluUmVsZWFzZTogc2NoZW1hLnBpcGVsaW5lRXZlbnQudG9vbGNoYWluUmVsZWFzZSxcbiAgICAgICAgICAvLyBGb3IgdGhlIHBlci1kZXBsb3kgcm9sbHVwIGJlbG93OiBldmVyeXRoaW5nIGBkb3JhX2RlcGxveW1lbnRzYCBuZWVkcyxcbiAgICAgICAgICAvLyB0YWtlbiBmcm9tIHRoZSByb3dzIHRoYXQgQUNUVUFMTFkgbGFuZGVkIHNvIGEgcmUtZGVsaXZlcnkgY2Fubm90XG4gICAgICAgICAgLy8gcHJvZHVjZSBhIHNlY29uZCBkZXBsb3kuXG4gICAgICAgICAgZXhlY3V0aW9uSWQ6IHNjaGVtYS5waXBlbGluZUV2ZW50LmV4ZWN1dGlvbklkLFxuICAgICAgICAgIGNvbW1pdFNoYTogc2NoZW1hLnBpcGVsaW5lRXZlbnQuY29tbWl0U2hhLFxuICAgICAgICAgIGNvbW1pdFRpbWVzdGFtcDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuY29tbWl0VGltZXN0YW1wLFxuICAgICAgICAgIGNvbW1pdENvdW50OiBzY2hlbWEucGlwZWxpbmVFdmVudC5jb21taXRDb3VudCxcbiAgICAgICAgICBjb21wbGV0ZWRBdDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuY29tcGxldGVkQXQsXG4gICAgICAgICAgc3RhcnRlZEF0OiBzY2hlbWEucGlwZWxpbmVFdmVudC5zdGFydGVkQXQsXG4gICAgICAgICAgY3JlYXRlZEF0OiBzY2hlbWEucGlwZWxpbmVFdmVudC5jcmVhdGVkQXQsXG4gICAgICAgICAgZGV0YWlsOiBzY2hlbWEucGlwZWxpbmVFdmVudC5kZXRhaWwsXG4gICAgICAgICAgc291cmNlRXZlbnRJZDogc2NoZW1hLnBpcGVsaW5lRXZlbnQuc291cmNlRXZlbnRJZCxcbiAgICAgICAgfSlcbiAgICAgIDogW107XG5cbiAgICAvLyBMb2cgaW5zaWRlIHRoZSB0eCBzY29wZSB3aGlsZSB0aGUgb3JnIHNldCBpcyBpbiBoYW5kLiBXQVJOLCBub3QgZXJyb3I6XG4gICAgLy8gYSBtaXNyb3V0ZWQgcHJvZHVjZXIgaXMgdGhlIGNvbW1vbiBjYXVzZSwgYnV0IHRoZSBzYW1lIGxpbmUgaXMgdGhlIG9ubHlcbiAgICAvLyBzaWduYWwgb2YgYW4gaW5qZWN0aW9uIGF0dGVtcHQsIHNvIGl0IG5hbWVzIHRoZSBvcmdzIGl0IHJlZnVzZWQuXG4gICAgaWYgKGZvcmVpZ25Mb2NhbCA+IDApIHtcbiAgICAgIGxvZ2dlci53YXJuKCdEcm9wcGVkIGluZ2VzdCBldmVudHMgZm9yIG9yZ3MgdGhlIGNhbGxlciBtYXkgbm90IHdyaXRlIGZvcicsIHtcbiAgICAgICAgZHJvcHBlZDogZm9yZWlnbkxvY2FsLFxuICAgICAgICBmb3JlaWduT3JnSWRzOiBbLi4uZm9yZWlnbk9yZ0lkc10sXG4gICAgICAgIGFsbG93ZWRPcmdJZHM6IFsuLi5hbGxvd2VkXSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChpbnZhbGlkVGltZUxvY2FsID4gMCkge1xuICAgICAgbG9nZ2VyLndhcm4oJ0Ryb3BwZWQgaW5nZXN0IGV2ZW50cyB3aXRoIGltcG9zc2libGUgdGltZXN0YW1wcycsIHtcbiAgICAgICAgZHJvcHBlZDogaW52YWxpZFRpbWVMb2NhbCxcbiAgICAgICAgcmVhc29uczogWy4uLmludmFsaWRUaW1lUmVhc29uc10sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBUaGUgcGxhdGZvcm0gZGVmYXVsdCwgZm9yIHRoZSBhbGVydCdzIGJhc2VsaW5lIGdhdWdlIOKAlCByZWFkIG9ubHkgd2hlbiBhXG4gICAgLy8gdG9vbGNoYWluIHJ1biBsYW5kZWQsIHNvIG9yZGluYXJ5IGJhdGNoZXMgcGF5IG5vdGhpbmcuXG4gICAgY29uc3QgZGVmYXVsdFJlbGVhc2UgPSBsYW5kZWQuc29tZSgocikgPT4gci50b29sY2hhaW5SZWxlYXNlKVxuICAgICAgPyBhd2FpdCByZWFkUGxhdGZvcm1EZWZhdWx0UmVsZWFzZSh0eClcbiAgICAgIDogbnVsbDtcblxuICAgIHJldHVybiB7XG4gICAgICBwbGF0Zm9ybURlZmF1bHRSZWxlYXNlOiBkZWZhdWx0UmVsZWFzZSxcbiAgICAgIGluc2VydGVkOiBsYW5kZWQubGVuZ3RoLFxuICAgICAgc2tpcHBlZDogc2tpcHBlZExvY2FsLFxuICAgICAgdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHM6IHVucmVnaXN0ZXJlZExvY2FsLFxuICAgICAgYWZmZWN0ZWRPcmdzOiBbLi4ubmV3IFNldChsYW5kZWQubWFwKHIgPT4gci5vcmdJZCkpXSxcbiAgICAgIGRyb3BwZWRGb3JlaWduT3JnOiBmb3JlaWduTG9jYWwsXG4gICAgICBkcm9wcGVkSW52YWxpZFRpbWU6IGludmFsaWRUaW1lTG9jYWwsXG4gICAgICBmb3JlaWduUGlwZWxpbmVJZHM6IFsuLi5mb3JlaWduUGlwZWxpbmVJZHNMb2NhbF0sXG4gICAgICBpbnNlcnRlZFJvd3M6IGxhbmRlZCxcbiAgICB9O1xuICB9KTtcblxuICBpZiAob25NZXRyaWMpIGVtaXRJbmdlc3RNZXRyaWNzKGluc2VydGVkUm93cywgb25NZXRyaWMsIHBsYXRmb3JtRGVmYXVsdFJlbGVhc2UpO1xuXG4gIC8vIFBlci1kZXBsb3kgcm9sbHVwLiBBRlRFUiB0aGUgZXZlbnRzIGNvbW1pdCBhbmQgb3V0c2lkZSB0aGVpciB0cmFuc2FjdGlvbjogdGhlXG4gIC8vIGV2ZW50cyBhcmUgdGhlIGR1cmFibGUgcmVjb3JkIGFuZCBgZG9yYV9kZXBsb3ltZW50c2AgaXMgZGVyaXZlZCBmcm9tIHRoZW0sIHNvXG4gIC8vIGEgcm9sbHVwIGZhaWx1cmUgbXVzdCBub3Qgcm9sbCBiYWNrIGFuIGluZ2VzdCB0aGF0IHN1Y2NlZWRlZC4gUmVidWlsZGFibGVcbiAgLy8gZWl0aGVyIHdheS4gYHVwc2VydERlcGxveW1lbnRzYCBuZXZlciB0aHJvd3MgZm9yIHRoYXQgcmVhc29uLlxuICBhd2FpdCB1cHNlcnREZXBsb3ltZW50cyhpbnNlcnRlZFJvd3MpO1xuXG4gIC8vIFN1cmZhY2UgdGhlIHNpbGVudCBza2lwOiBhbiB1bnJlZ2lzdGVyZWQgcGlwZWxpbmUgaWQgdXN1YWxseSBtZWFucyB0aGVcbiAgLy8gcGlwZWxpbmUgaGFzbid0IGNhbGxlZCBQT1NUIC9waXBlbGluZXMvcmVnaXN0cnkgeWV0IChvciBpdHNcbiAgLy8gcGIucGlwZWxpbmUtaWQgdGFnIGlzIG1pc3NpbmcvdW5yZWFkYWJsZSBieSB0aGUgTGFtYmRhKS4gTG9nZ2luZyBpdFxuICAvLyBtYWtlcyBhIGJyb2tlbiBqb2luIHZpc2libGUgaW5zdGVhZCBvZiBsb29raW5nIGxpa2UgXCJubyBhY3Rpdml0eVwiLlxuICBpZiAodW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMubGVuZ3RoID4gMCkge1xuICAgIGxvZ2dlci53YXJuKCdQaXBlbGluZSBldmVudHMgc2tpcHBlZDogcGlwZWxpbmUgaWQgbm90IGZvdW5kIGluIHJlZ2lzdHJ5Jywge1xuICAgICAgY291bnQ6IHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLmxlbmd0aCxcbiAgICAgIHNhbXBsZTogdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMuc2xpY2UoMCwgMyksXG4gICAgfSk7XG4gIH1cblxuICAvLyBQb3N0LWNvbW1pdCBjYWNoZSBpbnZhbGlkYXRpb24uIEZpcmUtYW5kLWZvcmdldCB3aXRoIGxvZ2dpbmcg4oCUIFRUTCBpc1xuICAvLyBzaG9ydCBlbm91Z2ggdGhhdCBhIG1pc3NlZCBpbnZhbGlkYXRpb24gc2VsZi1oZWFscy5cbiAgaWYgKGFmZmVjdGVkT3Jncy5sZW5ndGggPiAwKSB7XG4gICAgdm9pZCBQcm9taXNlLmFsbChhZmZlY3RlZE9yZ3MubWFwKChvcmcpID0+XG4gICAgICBpbnZhbGlkYXRlT3JnUmVwb3J0cyhvcmcpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyBjYWNoZSBpbnZhbGlkYXRpb24gZmFpbGVkJywgeyBvcmdJZDogb3JnLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICB9KSxcbiAgICApKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgaW5zZXJ0ZWQsXG4gICAgc2tpcHBlZCxcbiAgICB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcyxcbiAgICBhZmZlY3RlZE9yZ3MsXG4gICAgZHJvcHBlZEZvcmVpZ25PcmcsXG4gICAgZHJvcHBlZEludmFsaWRUaW1lLFxuICAgIGZvcmVpZ25QaXBlbGluZUlkcyxcbiAgICBpbnNlcnRlZEV4ZWN1dGlvbklkczogWy4uLm5ldyBTZXQoaW5zZXJ0ZWRSb3dzLm1hcCgocikgPT4gci5leGVjdXRpb25JZCkuZmlsdGVyKChpZCk6IGlkIGlzIHN0cmluZyA9PiAhIWlkKSldLFxuICAgIGluc2VydGVkUGlwZWxpbmVJZHM6IFsuLi5uZXcgU2V0KGluc2VydGVkUm93cy5tYXAoKHIpID0+IHIucGlwZWxpbmVJZCkuZmlsdGVyKChpZCk6IGlkIGlzIHN0cmluZyA9PiAhIWlkKSldLFxuICB9O1xufVxuIl19
@@ -0,0 +1,162 @@
1
+ import { type SqlExecutor } from '../../database/pg-result.js';
2
+ /** The two toolchain actions a release is judged on. */
3
+ export type ToolchainAction = 'synth' | 'self-mutation';
4
+ /** Terminal toolchain outcomes; anything else (STARTED, CANCELED, ABANDONED…) says nothing about the toolchain. */
5
+ export type ToolchainOutcome = 'succeeded' | 'failed';
6
+ /**
7
+ * CDK Pipelines' self-mutation action: a fixed stage and action name
8
+ * (`aws-cdk-lib/pipelines/lib/codepipeline/codepipeline.js`).
9
+ */
10
+ export declare const SELF_MUTATION_STAGE = "UpdatePipeline";
11
+ export declare const SELF_MUTATION_ACTION = "SelfMutate";
12
+ /**
13
+ * The synth step's `stepKey` in the step manifest (`pluginStepLabel(null, …)`).
14
+ * The synth ACTION's name is a generated id, so it is identified by the
15
+ * manifest row carrying this key — the names the built pipeline really used.
16
+ */
17
+ export declare const SYNTH_STEP_KEY = "synth";
18
+ /**
19
+ * The `build-image` entry's plugin: the release's bootstrap half. The entry is
20
+ * the manifest's non-step row under `step_key` {@link BUILD_IMAGE_STEP_KEY}
21
+ * (api-core `BUILD_IMAGE_MANIFEST_*`), and its `plugin_version` IS the release.
22
+ */
23
+ export declare const BUILD_IMAGE_PLUGIN = "pipeline-bootstrap";
24
+ /** A manifest row, as {@link deployedToolchainOf} reads it. */
25
+ export interface ToolchainManifestRow {
26
+ pipelineId: string;
27
+ orgId: string;
28
+ stageName: string;
29
+ actionName: string;
30
+ pluginPublisher: string | null;
31
+ pluginName: string | null;
32
+ pluginVersion: string | null;
33
+ stepKey?: string | null;
34
+ }
35
+ /** One pipeline's deployed toolchain, from its manifest. */
36
+ export interface DeployedToolchain {
37
+ orgId: string;
38
+ /** The release its `build-image` entry records. */
39
+ releaseVersion: string;
40
+ /** The synth action as the built pipeline names it; null when the manifest has no synth row. */
41
+ synth: {
42
+ stageName: string;
43
+ actionName: string;
44
+ } | null;
45
+ }
46
+ /**
47
+ * Each pipeline's deployed toolchain, from its manifest rows. A pipeline
48
+ * whose manifest records no `build-image` entry (deployed before releases, or
49
+ * a placeholder bootstrap) has none, and its actions are not stamped. Only an
50
+ * OWN-ORG row (no publisher) counts: a managed name can never be a listing.
51
+ */
52
+ export declare function deployedToolchainOf(rows: readonly ToolchainManifestRow[]): Map<string, DeployedToolchain>;
53
+ /**
54
+ * Which toolchain action (if any) an ACTION event is, given its pipeline's
55
+ * deployed toolchain. Names are compared post-scrub, as the manifest stores them.
56
+ */
57
+ export declare function toolchainActionOf(event: {
58
+ eventType: string;
59
+ stageName?: string | null;
60
+ actionName?: string | null;
61
+ }, deployed: DeployedToolchain | undefined): ToolchainAction | null;
62
+ /** The terminal outcome of a status, or null for a non-terminal / non-judging one. */
63
+ export declare function toolchainOutcomeOf(status: string): ToolchainOutcome | null;
64
+ /** The gate's thresholds (set on the console, Phase 5). */
65
+ export interface CanaryGateParams {
66
+ /** N: counted synth runs required. */
67
+ minRuns: number;
68
+ /** M: distinct orgs required. */
69
+ minOrgs: number;
70
+ /** T: the release's failure rate may exceed the default's by at most this many percentage points. */
71
+ maxFailurePointsAboveDefault: number;
72
+ }
73
+ export declare const DEFAULT_CANARY_GATE: Readonly<CanaryGateParams>;
74
+ /** One org's terminal synth outcomes on the candidate, NEWEST first. */
75
+ export interface OrgRuns {
76
+ orgId: string;
77
+ outcomes: readonly ToolchainOutcome[];
78
+ }
79
+ export interface CanaryGateInput {
80
+ releaseVersion: string;
81
+ candidate: readonly OrgRuns[];
82
+ /** The current platform default's synth runs over the same window (uncapped). */
83
+ baseline: {
84
+ releaseVersion: string | null;
85
+ runs: number;
86
+ failures: number;
87
+ };
88
+ params?: Partial<CanaryGateParams>;
89
+ }
90
+ export type CanaryGateShortfall = 'runs' | 'orgs' | 'failure-rate';
91
+ /** The gate's verdict and every number behind it — what the console shows. */
92
+ export interface CanaryGateResult {
93
+ passed: boolean;
94
+ releaseVersion: string;
95
+ params: CanaryGateParams;
96
+ /** ceil(N / M): the most runs any one org contributes. */
97
+ perOrgCap: number;
98
+ /** Runs counted toward N, after the per-org cap. */
99
+ countedRuns: number;
100
+ /** Every terminal synth run on the release, before the cap. */
101
+ totalRuns: number;
102
+ /** Distinct orgs with at least one counted run. */
103
+ orgs: number;
104
+ /** Failures among the counted runs. */
105
+ failures: number;
106
+ /** Percent (0–100) over the counted runs; null with none. */
107
+ failureRate: number | null;
108
+ baselineReleaseVersion: string | null;
109
+ baselineRuns: number;
110
+ /** Percent (0–100); 0 when the default has no runs in the window (the strict reading). */
111
+ baselineFailureRate: number;
112
+ /** failureRate − baselineFailureRate, in points; null with no counted runs. */
113
+ pointsAboveDefault: number | null;
114
+ /** Which thresholds were not met (empty when passed). */
115
+ shortfalls: CanaryGateShortfall[];
116
+ }
117
+ /** The per-org contribution cap: ceil(N / M). */
118
+ export declare function canaryPerOrgCap(params: Pick<CanaryGateParams, 'minRuns' | 'minOrgs'>): number;
119
+ /**
120
+ * The canary gate: at least N counted synth runs across at least M orgs, and a
121
+ * failure rate within T points of the current default's. Each org counts its
122
+ * most recent `ceil(N / M)` runs only — toward N AND toward the failure rate,
123
+ * so one org can neither satisfy N alone nor dominate the rate. Being BETTER
124
+ * than the default never fails the gate.
125
+ */
126
+ export declare function evaluateCanaryGate(input: CanaryGateInput): CanaryGateResult;
127
+ /**
128
+ * Evaluate the canary gate for `releaseVersion` against `baselineReleaseVersion`
129
+ * (the current platform default; null when none) from the stamped rows.
130
+ *
131
+ * Window: since the release was registered (`toolchain_release.created_at`),
132
+ * for both the candidate and the default, so the two rates are contemporaneous.
133
+ * Only terminal (SUCCEEDED / FAILED) SYNTH runs count; self-mutation is not
134
+ * part of the gate (§6 counts synth runs).
135
+ *
136
+ * Reads every org's rows: run it ELEVATED (the plugin service's toolchain tx
137
+ * is). The candidate read is bounded at `ceil(N/M)` rows per org.
138
+ */
139
+ export declare function readCanaryGate(db: SqlExecutor, releaseVersion: string, baselineReleaseVersion: string | null, params?: Partial<CanaryGateParams>): Promise<CanaryGateResult>;
140
+ export interface AffectedOrg {
141
+ orgId: string;
142
+ /** Pipelines in this org on the release whose latest synth failed. */
143
+ pipelines: number;
144
+ pipelineIds: string[];
145
+ }
146
+ export interface AffectedPipelines {
147
+ releaseVersion: string;
148
+ totalPipelines: number;
149
+ orgs: AffectedOrg[];
150
+ }
151
+ /**
152
+ * Pipelines whose DEPLOYED release is `releaseVersion` (their manifest's
153
+ * `build-image` entry) and whose LATEST terminal synth run failed, grouped by
154
+ * org — the console's Affected view and the "Notify affected owners" target
155
+ * set. A pipeline whose latest synth succeeded has healed and is not listed.
156
+ *
157
+ * Elevated read: it spans every org. Callers show the system-org operator
158
+ * counts, and notify each org about its own pipelines only.
159
+ */
160
+ export declare function readAffectedPipelines(db: SqlExecutor, releaseVersion: string): Promise<AffectedPipelines>;
161
+ /** The current platform default (elevated read), or null. */
162
+ export declare function readPlatformDefaultRelease(db: SqlExecutor): Promise<string | null>;