@pipeline-builder/pipeline-data 3.4.35 → 3.4.37

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.
@@ -7,7 +7,7 @@ const api_core_1 = require("@pipeline-builder/api-core");
7
7
  const drizzle_orm_1 = require("drizzle-orm");
8
8
  const crud_service_1 = require("./crud-service");
9
9
  const drizzle_schema_1 = require("../database/drizzle-schema");
10
- const postgres_connection_1 = require("../database/postgres-connection");
10
+ const tenancy_1 = require("../database/tenancy");
11
11
  const logger = (0, api_core_1.createLogger)('reporting-service');
12
12
  /**
13
13
  * Cache for reporting aggregations. Two tiers:
@@ -43,60 +43,69 @@ class ReportingService {
43
43
  * Returns counts + a sample of unregistered ARNs for observability.
44
44
  */
45
45
  async ingestEvents(events) {
46
- // Batch-resolve all unique ARNs in one query
47
- const uniqueArns = [...new Set(events.map(e => e.pipelineArn))];
48
- const registryRows = await postgres_connection_1.db
49
- .select({
50
- pipelineId: drizzle_schema_1.schema.pipelineRegistry.pipelineId,
51
- orgId: drizzle_schema_1.schema.pipelineRegistry.orgId,
52
- pipelineArn: drizzle_schema_1.schema.pipelineRegistry.pipelineArn,
53
- })
54
- .from(drizzle_schema_1.schema.pipelineRegistry)
55
- .where((0, drizzle_orm_1.inArray)(drizzle_schema_1.schema.pipelineRegistry.pipelineArn, uniqueArns));
56
- const arnMap = new Map(registryRows.map(r => [r.pipelineArn, r]));
57
- // Build insert batch (skip unregistered ARNs)
58
- const rows = [];
59
- let skipped = 0;
60
- const unregisteredArns = [];
61
- for (const event of events) {
62
- const registry = arnMap.get(event.pipelineArn);
63
- if (!registry) {
64
- skipped++;
65
- unregisteredArns.push(event.pipelineArn);
66
- continue;
46
+ // Multi-org batch insert: the caller resolves to multiple orgs via the
47
+ // pipeline-registry lookup below, so the route layer MUST establish a
48
+ // `runWithTenantContext({ isSuperAdmin: true }, ...)` scope before calling
49
+ // this method. Under FORCE'd RLS, a single tx with `app.org_id = <one
50
+ // org>` could only write events for that org; bypass via sysadmin is
51
+ // the right gate for this server-internal cross-tenant endpoint. See
52
+ // api/reporting/src/routes/event-ingest.ts for the wrapper.
53
+ return (0, tenancy_1.withTenantTx)(async (tx) => {
54
+ // Batch-resolve all unique ARNs in one query
55
+ const uniqueArns = [...new Set(events.map(e => e.pipelineArn))];
56
+ const registryRows = await tx
57
+ .select({
58
+ pipelineId: drizzle_schema_1.schema.pipelineRegistry.pipelineId,
59
+ orgId: drizzle_schema_1.schema.pipelineRegistry.orgId,
60
+ pipelineArn: drizzle_schema_1.schema.pipelineRegistry.pipelineArn,
61
+ })
62
+ .from(drizzle_schema_1.schema.pipelineRegistry)
63
+ .where((0, drizzle_orm_1.inArray)(drizzle_schema_1.schema.pipelineRegistry.pipelineArn, uniqueArns));
64
+ const arnMap = new Map(registryRows.map(r => [r.pipelineArn, r]));
65
+ // Build insert batch (skip unregistered ARNs)
66
+ const rows = [];
67
+ let skipped = 0;
68
+ const unregisteredArns = [];
69
+ for (const event of events) {
70
+ const registry = arnMap.get(event.pipelineArn);
71
+ if (!registry) {
72
+ skipped++;
73
+ unregisteredArns.push(event.pipelineArn);
74
+ continue;
75
+ }
76
+ rows.push({
77
+ pipelineId: registry.pipelineId,
78
+ orgId: registry.orgId,
79
+ eventSource: event.eventSource,
80
+ eventType: event.eventType,
81
+ status: event.status,
82
+ pipelineArn: (0, api_core_1.hashAccountInArn)(event.pipelineArn),
83
+ executionId: event.executionId,
84
+ stageName: event.stageName,
85
+ actionName: event.actionName,
86
+ startedAt: event.startedAt ? new Date(event.startedAt) : undefined,
87
+ completedAt: event.completedAt ? new Date(event.completedAt) : undefined,
88
+ durationMs: event.durationMs,
89
+ detail: event.detail,
90
+ });
67
91
  }
68
- rows.push({
69
- pipelineId: registry.pipelineId,
70
- orgId: registry.orgId,
71
- eventSource: event.eventSource,
72
- eventType: event.eventType,
73
- status: event.status,
74
- pipelineArn: (0, api_core_1.hashAccountInArn)(event.pipelineArn),
75
- executionId: event.executionId,
76
- stageName: event.stageName,
77
- actionName: event.actionName,
78
- startedAt: event.startedAt ? new Date(event.startedAt) : undefined,
79
- completedAt: event.completedAt ? new Date(event.completedAt) : undefined,
80
- durationMs: event.durationMs,
81
- detail: event.detail,
82
- });
83
- }
84
- if (rows.length > 0) {
85
- await postgres_connection_1.db.insert(drizzle_schema_1.schema.pipelineEvent).values(rows);
86
- // Per-org failures are logged but don't fail the batch — `Promise.all`
87
- // so the caller doesn't return before invalidation completes,
88
- // otherwise dashboards can serve stale data right after ingest.
89
- const affectedOrgs = [...new Set(rows.map(r => r.orgId))];
90
- await Promise.all(affectedOrgs.map((org) => this.invalidateOrg(org).catch((err) => {
91
- logger.warn('Reporting cache invalidation failed', { orgId: org, error: (0, api_core_1.errorMessage)(err) });
92
- })));
93
- }
94
- return { inserted: rows.length, skipped, unregisteredArns };
92
+ if (rows.length > 0) {
93
+ await tx.insert(drizzle_schema_1.schema.pipelineEvent).values(rows);
94
+ // Per-org cache invalidation runs outside the tx (Redis, not Postgres).
95
+ // `Promise.all` so the caller doesn't return before invalidation
96
+ // completes, otherwise dashboards can serve stale data right after ingest.
97
+ const affectedOrgs = [...new Set(rows.map(r => r.orgId))];
98
+ await Promise.all(affectedOrgs.map((org) => this.invalidateOrg(org).catch((err) => {
99
+ logger.warn('Reporting cache invalidation failed', { orgId: org, error: (0, api_core_1.errorMessage)(err) });
100
+ })));
101
+ }
102
+ return { inserted: rows.length, skipped, unregisteredArns };
103
+ });
95
104
  }
96
105
  // ── Category 1: Pipeline Execution & Performance ──
97
106
  /** 1.1 Execution count per pipeline with status breakdown. */
98
107
  async getExecutionCount(orgId) {
99
- return timeseriesCache.getOrSet(`${orgId}:exec-count`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
108
+ return timeseriesCache.getOrSet(`${orgId}:exec-count`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
100
109
  SELECT
101
110
  p.id, p.project, p.organization, p.pipeline_name,
102
111
  COUNT(*)::int AS total,
@@ -111,11 +120,11 @@ class ReportingService {
111
120
  WHERE p.org_id = ${orgId} AND p.is_active = true
112
121
  GROUP BY p.id
113
122
  ORDER BY total DESC
114
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
123
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
115
124
  }
116
125
  /** 1.2 Success rate over time for an org. */
117
126
  async getSuccessRate(orgId, interval, from, to) {
118
- return timeseriesCache.getOrSet(`${orgId}:success-rate:${interval}:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
127
+ return timeseriesCache.getOrSet(`${orgId}:success-rate:${interval}:${from}:${to}`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
119
128
  SELECT
120
129
  DATE_TRUNC(${interval}, e.started_at)::text AS period,
121
130
  COUNT(*) FILTER (WHERE e.status = 'SUCCEEDED')::int AS succeeded,
@@ -129,11 +138,11 @@ class ReportingService {
129
138
  AND e.status IN ('SUCCEEDED', 'FAILED', 'CANCELED')
130
139
  AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
131
140
  GROUP BY period ORDER BY period
132
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
141
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
133
142
  }
134
143
  /** 1.3 Average duration per pipeline. */
135
144
  async getAverageDuration(orgId, from, to) {
136
- return timeseriesCache.getOrSet(`${orgId}:avg-duration:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
145
+ return timeseriesCache.getOrSet(`${orgId}:avg-duration:${from}:${to}`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
137
146
  SELECT
138
147
  p.id, p.project, p.pipeline_name,
139
148
  AVG(e.duration_ms)::int AS avg_ms,
@@ -146,11 +155,11 @@ class ReportingService {
146
155
  WHERE p.org_id = ${orgId} AND e.event_type = 'PIPELINE' AND e.duration_ms IS NOT NULL
147
156
  AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
148
157
  GROUP BY p.id ORDER BY avg_ms DESC
149
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
158
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
150
159
  }
151
160
  /** 1.5 Stage failure heatmap — which stages fail most. */
152
161
  async getStageFailures(orgId, from, to) {
153
- return timeseriesCache.getOrSet(`${orgId}:stage-failures:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
162
+ return timeseriesCache.getOrSet(`${orgId}:stage-failures:${from}:${to}`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
154
163
  SELECT
155
164
  e.stage_name,
156
165
  COUNT(*) FILTER (WHERE e.status = 'FAILED')::int AS failures,
@@ -162,11 +171,11 @@ class ReportingService {
162
171
  WHERE p.org_id = ${orgId} AND e.event_type = 'STAGE' AND e.stage_name IS NOT NULL
163
172
  AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
164
173
  GROUP BY e.stage_name ORDER BY failures DESC
165
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
174
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
166
175
  }
167
176
  /** 1.6 Stage bottlenecks — slowest stages per pipeline. */
168
177
  async getStageBottlenecks(orgId, from, to) {
169
- return timeseriesCache.getOrSet(`${orgId}:stage-bottlenecks:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
178
+ return timeseriesCache.getOrSet(`${orgId}:stage-bottlenecks:${from}:${to}`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
170
179
  SELECT
171
180
  p.id, p.pipeline_name, e.stage_name,
172
181
  AVG(e.duration_ms)::int AS avg_ms,
@@ -176,11 +185,11 @@ class ReportingService {
176
185
  WHERE p.org_id = ${orgId} AND e.event_type = 'STAGE' AND e.duration_ms IS NOT NULL
177
186
  AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
178
187
  GROUP BY p.id, e.stage_name ORDER BY avg_ms DESC
179
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
188
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
180
189
  }
181
190
  /** 1.7 Action failure rate — which plugin steps fail most. */
182
191
  async getActionFailures(orgId, from, to) {
183
- return timeseriesCache.getOrSet(`${orgId}:action-failures:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
192
+ return timeseriesCache.getOrSet(`${orgId}:action-failures:${from}:${to}`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
184
193
  SELECT
185
194
  e.action_name,
186
195
  COUNT(*) FILTER (WHERE e.status = 'FAILED')::int AS failures,
@@ -192,11 +201,11 @@ class ReportingService {
192
201
  WHERE p.org_id = ${orgId} AND e.event_type = 'ACTION' AND e.action_name IS NOT NULL
193
202
  AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
194
203
  GROUP BY e.action_name ORDER BY failures DESC
195
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
204
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
196
205
  }
197
206
  /** 1.8 Error categorization — group failure messages. */
198
207
  async getErrors(orgId, from, to, limit = 20) {
199
- return timeseriesCache.getOrSet(`${orgId}:errors:${from}:${to}:${limit}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
208
+ return timeseriesCache.getOrSet(`${orgId}:errors:${from}:${to}:${limit}`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
200
209
  SELECT
201
210
  SUBSTRING(e.error_message FROM 1 FOR 200) AS error_pattern,
202
211
  COUNT(*)::int AS occurrences,
@@ -208,13 +217,13 @@ class ReportingService {
208
217
  AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
209
218
  GROUP BY error_pattern ORDER BY occurrences DESC
210
219
  LIMIT ${limit}
211
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
220
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
212
221
  }
213
222
  // ── Category 2: Plugin Inventory & Builds ──
214
223
  /** 2.1 Plugin summary — counts and breakdowns. */
215
224
  async getPluginSummary(orgId) {
216
225
  return inventoryCache.getOrSet(`${orgId}:plugin-summary`, async () => {
217
- const rows = await postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
226
+ const rows = await (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
218
227
  SELECT
219
228
  COUNT(*)::int AS total,
220
229
  COUNT(*) FILTER (WHERE ${drizzle_schema_1.schema.plugin.isActive})::int AS active,
@@ -224,13 +233,13 @@ class ReportingService {
224
233
  COUNT(DISTINCT ${drizzle_schema_1.schema.plugin.name})::int AS unique_names
225
234
  FROM ${drizzle_schema_1.schema.plugin}
226
235
  WHERE ${drizzle_schema_1.schema.plugin.orgId} = ${orgId}
227
- `);
236
+ `));
228
237
  return ((0, crud_service_1.drizzleRows)(rows.rows)[0] || { total: 0, active: 0, inactive: 0, public: 0, private: 0, uniqueNames: 0 });
229
238
  });
230
239
  }
231
240
  /** 2.2 Type & compute distribution. */
232
241
  async getPluginDistribution(orgId) {
233
- return inventoryCache.getOrSet(`${orgId}:plugin-distribution`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
242
+ return inventoryCache.getOrSet(`${orgId}:plugin-distribution`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
234
243
  SELECT
235
244
  ${drizzle_schema_1.schema.plugin.pluginType} AS plugin_type,
236
245
  ${drizzle_schema_1.schema.plugin.computeType} AS compute_type,
@@ -239,11 +248,11 @@ class ReportingService {
239
248
  WHERE ${drizzle_schema_1.schema.plugin.orgId} = ${orgId} AND ${drizzle_schema_1.schema.plugin.isActive} = true
240
249
  GROUP BY ${drizzle_schema_1.schema.plugin.pluginType}, ${drizzle_schema_1.schema.plugin.computeType}
241
250
  ORDER BY count DESC
242
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
251
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
243
252
  }
244
253
  /** 2.3 Version counts per plugin name. */
245
254
  async getPluginVersions(orgId) {
246
- return inventoryCache.getOrSet(`${orgId}:plugin-versions`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
255
+ return inventoryCache.getOrSet(`${orgId}:plugin-versions`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
247
256
  SELECT
248
257
  ${drizzle_schema_1.schema.plugin.name},
249
258
  COUNT(*)::int AS version_count,
@@ -253,11 +262,11 @@ class ReportingService {
253
262
  WHERE ${drizzle_schema_1.schema.plugin.orgId} = ${orgId} AND ${drizzle_schema_1.schema.plugin.isActive} = true
254
263
  GROUP BY ${drizzle_schema_1.schema.plugin.name}
255
264
  ORDER BY version_count DESC
256
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
265
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
257
266
  }
258
267
  /** 2.4 Build success rate over time. */
259
268
  async getBuildSuccessRate(orgId, interval, from, to) {
260
- return timeseriesCache.getOrSet(`${orgId}:build-success:${interval}:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
269
+ return timeseriesCache.getOrSet(`${orgId}:build-success:${interval}:${from}:${to}`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
261
270
  SELECT
262
271
  DATE_TRUNC(${interval}, e.started_at)::text AS period,
263
272
  COUNT(*) FILTER (WHERE e.status = 'completed')::int AS succeeded,
@@ -269,11 +278,11 @@ class ReportingService {
269
278
  AND e.status IN ('completed', 'failed')
270
279
  AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
271
280
  GROUP BY period ORDER BY period
272
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
281
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
273
282
  }
274
283
  /** 2.5 Build duration per plugin. */
275
284
  async getBuildDuration(orgId, from, to) {
276
- return timeseriesCache.getOrSet(`${orgId}:build-duration:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
285
+ return timeseriesCache.getOrSet(`${orgId}:build-duration:${from}:${to}`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
277
286
  SELECT
278
287
  e.detail->>'pluginName' AS plugin_name,
279
288
  AVG(e.duration_ms)::int AS avg_ms,
@@ -283,11 +292,11 @@ class ReportingService {
283
292
  WHERE e.org_id = ${orgId} AND e.event_source = 'plugin-build' AND e.duration_ms IS NOT NULL
284
293
  AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
285
294
  GROUP BY plugin_name ORDER BY avg_ms DESC
286
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
295
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
287
296
  }
288
297
  /** 2.6 Build failures — top error messages. */
289
298
  async getBuildFailures(orgId, from, to, limit = 20) {
290
- return timeseriesCache.getOrSet(`${orgId}:build-failures:${from}:${to}:${limit}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
299
+ return timeseriesCache.getOrSet(`${orgId}:build-failures:${from}:${to}:${limit}`, () => (0, tenancy_1.withTenantTx)((tx) => tx.execute((0, drizzle_orm_1.sql) `
291
300
  SELECT
292
301
  e.detail->>'pluginName' AS plugin_name,
293
302
  e.error_message,
@@ -299,9 +308,9 @@ class ReportingService {
299
308
  GROUP BY plugin_name, e.error_message
300
309
  ORDER BY occurrences DESC
301
310
  LIMIT ${limit}
302
- `).then(r => (0, crud_service_1.drizzleRows)(r.rows)));
311
+ `).then(r => (0, crud_service_1.drizzleRows)(r.rows))));
303
312
  }
304
313
  }
305
314
  exports.ReportingService = ReportingService;
306
315
  exports.reportingService = new ReportingService();
307
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0aW5nLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JlcG9ydGluZy1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDOzs7QUFFdEMseURBQThHO0FBQzlHLDZDQUEyQztBQUMzQyxpREFBNkM7QUFDN0MsK0RBQW9EO0FBQ3BELHlFQUFxRDtBQUVyRCxNQUFNLE1BQU0sR0FBRyxJQUFBLHVCQUFZLEVBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUVqRDs7OztHQUlHO0FBQ0gsTUFBTSxjQUFjLEdBQUcsSUFBQSw2QkFBa0IsRUFBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsMEJBQTBCLElBQUksS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDeEgsTUFBTSxlQUFlLEdBQUcsSUFBQSw2QkFBa0IsRUFBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLElBQUksS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFrSXpILDJEQUEyRDtBQUUzRDs7Ozs7OztHQU9HO0FBQ0gsTUFBYSxnQkFBZ0I7SUFFM0IsMEVBQTBFO0lBQzFFLEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBYTtRQUMvQixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDaEIsY0FBYyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUM7WUFDOUMsZUFBZSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUM7U0FDaEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFxQjtRQUN0Qyw2Q0FBNkM7UUFDN0MsTUFBTSxVQUFVLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENB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LElBQUksQ0FBQyxDQUFDLENBQ2pELENBQUM7SUFDSixDQUFDO0lBRUQsK0NBQStDO0lBQy9DLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFhLEVBQUUsSUFBWSxFQUFFLEVBQVUsRUFBRSxRQUFnQixFQUFFO1FBQ2hGLE9BQU8sZUFBZSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEtBQUssbUJBQW1CLElBQUksSUFBSSxFQUFFLElBQUksS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQ3JGLHdCQUFFLENBQUMsT0FBTyxDQUFDLElBQUEsaUJBQUcsRUFBQTs7Ozs7O2VBTUwsdUJBQU0sQ0FBQyxhQUFhOzJCQUNSLEtBQUs7Z0NBQ0EsSUFBSSxxQ0FBcUMsRUFBRTs7O2dCQUczRCxLQUFLO09BQ2QsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUEsMEJBQVcsRUFBZSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FDaEQsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQXRVRCw0Q0FzVUM7QUFFWSxRQUFBLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBjcmVhdGVDYWNoZVNlcnZpY2UsIGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlLCBoYXNoQWNjb3VudEluQXJuIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgaW5BcnJheSwgc3FsIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgZHJpenpsZVJvd3MgfSBmcm9tICcuL2NydWQtc2VydmljZSc7XG5pbXBvcnQgeyBzY2hlbWEgfSBmcm9tICcuLi9kYXRhYmFzZS9kcml6emxlLXNjaGVtYSc7XG5pbXBvcnQgeyBkYiB9IGZyb20gJy4uL2RhdGFiYXNlL3Bvc3RncmVzLWNvbm5lY3Rpb24nO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3JlcG9ydGluZy1zZXJ2aWNlJyk7XG5cbi8qKlxuICogQ2FjaGUgZm9yIHJlcG9ydGluZyBhZ2dyZWdhdGlvbnMuIFR3byB0aWVyczpcbiAqIC0gSW52ZW50b3J5IHF1ZXJpZXMgKHBsdWdpbiBzdW1tYXJ5L2Rpc3RyaWJ1dGlvbi92ZXJzaW9ucyk6IDUgbWluIFRUTCDigJQgY2hhbmdlcyBvbiBwbHVnaW4gQ1JVRFxuICogLSBFeGVjdXRpb24vYnVpbGQgcXVlcmllcyB3aXRoIGRhdGUgcmFuZ2VzOiAyIG1pbiBUVEwg4oCUIG5ldyBldmVudHMgYXJyaXZlIGNvbnRpbnVvdXNseVxuICovXG5jb25zdCBpbnZlbnRvcnlDYWNoZSA9IGNyZWF0ZUNhY2hlU2VydmljZSgncmVwb3J0OmludjonLCBwYXJzZUludChwcm9jZXNzLmVudi5DQUNIRV9UVExfUkVQT1JUX0lOVkVOVE9SWSB8fCAnMzAwJywgMTApKTtcbmNvbnN0IHRpbWVzZXJpZXNDYWNoZSA9IGNyZWF0ZUNhY2hlU2VydmljZSgncmVwb3J0OnRzOicsIHBhcnNlSW50KHByb2Nlc3MuZW52LkNBQ0hFX1RUTF9SRVBPUlRfVElNRVNFUklFUyB8fCAnMTIwJywgMTApKTtcblxuLy8g4pSA4pSA4pSAIFR5cGVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5pbnRlcmZhY2UgRXhlY3V0aW9uQ291bnQge1xuICBpZDogc3RyaW5nO1xuICBwcm9qZWN0OiBzdHJpbmc7XG4gIG9yZ2FuaXphdGlvbjogc3RyaW5nO1xuICBwaXBlbGluZU5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHRvdGFsOiBudW1iZXI7XG4gIHN1Y2NlZWRlZDogbnVtYmVyO1xuICBmYWlsZWQ6IG51bWJlcjtcbiAgY2FuY2VsZWQ6IG51bWJlcjtcbiAgZmlyc3RFeGVjdXRpb246IHN0cmluZyB8IG51bGw7XG4gIGxhc3RFeGVjdXRpb246IHN0cmluZyB8IG51bGw7XG59XG5cbmludGVyZmFjZSBUaW1lU2VyaWVzRW50cnkge1xuICBwZXJpb2Q6IHN0cmluZztcbiAgc3VjY2VlZGVkOiBudW1iZXI7XG4gIGZhaWxlZDogbnVtYmVyO1xuICBjYW5jZWxlZDogbnVtYmVyO1xuICBzdWNjZXNzUGN0OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBEdXJhdGlvblN0YXRzIHtcbiAgaWQ6IHN0cmluZztcbiAgcHJvamVjdDogc3RyaW5nO1xuICBwaXBlbGluZU5hbWU6IHN0cmluZyB8IG51bGw7XG4gIGF2Z01zOiBudW1iZXI7XG4gIG1pbk1zOiBudW1iZXI7XG4gIG1heE1zOiBudW1iZXI7XG4gIHA5NU1zOiBudW1iZXI7XG4gIGV4ZWN1dGlvbnM6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFN0YWdlRmFpbHVyZSB7XG4gIHN0YWdlTmFtZTogc3RyaW5nO1xuICBmYWlsdXJlczogbnVtYmVyO1xuICB0b3RhbDogbnVtYmVyO1xuICBmYWlsdXJlUGN0OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBTdGFnZUJvdHRsZW5lY2sge1xuICBpZDogc3RyaW5nO1xuICBwaXBlbGluZU5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHN0YWdlTmFtZTogc3RyaW5nO1xuICBhdmdNczogbnVtYmVyO1xuICBtYXhNczogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQWN0aW9uRmFpbHVyZSB7XG4gIGFjdGlvbk5hbWU6IHN0cmluZztcbiAgZmFpbHVyZXM6IG51bWJlcjtcbiAgdG90YWw6IG51bWJlcjtcbiAgZmFpbHVyZVBjdDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgRXJyb3JFbnRyeSB7XG4gIGVycm9yUGF0dGVybjogc3RyaW5nO1xuICBvY2N1cnJlbmNlczogbnVtYmVyO1xuICBhZmZlY3RlZFBpcGVsaW5lczogbnVtYmVyO1xuICBsYXN0U2Vlbjogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUGx1Z2luU3VtbWFyeSB7XG4gIHRvdGFsOiBudW1iZXI7XG4gIGFjdGl2ZTogbnVtYmVyO1xuICBpbmFjdGl2ZTogbnVtYmVyO1xuICBwdWJsaWM6IG51bWJlcjtcbiAgcHJpdmF0ZTogbnVtYmVyO1xuICB1bmlxdWVOYW1lczogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgVHlwZUNvbXB1dGVEaXN0cmlidXRpb24ge1xuICBwbHVnaW5UeXBlOiBzdHJpbmc7XG4gIGNvbXB1dGVUeXBlOiBzdHJpbmc7XG4gIGNvdW50OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBWZXJzaW9uQ291bnQge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZlcnNpb25Db3VudDogbnVtYmVyO1xuICBsYXRlc3RWZXJzaW9uOiBzdHJpbmc7XG4gIGhhc0RlZmF1bHQ6IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBCdWlsZFRpbWVTZXJpZXNFbnRyeSB7XG4gIHBlcmlvZDogc3RyaW5nO1xuICBzdWNjZWVkZWQ6IG51bWJlcjtcbiAgZmFpbGVkOiBudW1iZXI7XG4gIHN1Y2Nlc3NQY3Q6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIEJ1aWxkRHVyYXRpb24ge1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIGF2Z01zOiBudW1iZXI7XG4gIG1heE1zOiBudW1iZXI7XG4gIGJ1aWxkczogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQnVpbGRGYWlsdXJlIHtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBlcnJvck1lc3NhZ2U6IHN0cmluZztcbiAgb2NjdXJyZW5jZXM6IG51bWJlcjtcbiAgbGFzdFNlZW46IHN0cmluZztcbn1cblxuLyoqIEV2ZW50IHBheWxvYWQgYWNjZXB0ZWQgYnkgYFJlcG9ydGluZ1NlcnZpY2UuaW5nZXN0RXZlbnRzYC4gTWlycm9ycyB0aGUgcm91dGUncyBab2Qgc2hhcGUuICovXG5leHBvcnQgaW50ZXJmYWNlIEluZ2VzdEV2ZW50IHtcbiAgcGlwZWxpbmVBcm46IHN0cmluZztcbiAgZXZlbnRTb3VyY2U6ICdjb2RlcGlwZWxpbmUnIHwgJ2NvZGVidWlsZCcgfCAncGx1Z2luLWJ1aWxkJztcbiAgZXZlbnRUeXBlOiAnUElQRUxJTkUnIHwgJ1NUQUdFJyB8ICdBQ1RJT04nIHwgJ0JVSUxEJztcbiAgc3RhdHVzOiBzdHJpbmc7XG4gIGV4ZWN1dGlvbklkPzogc3RyaW5nO1xuICBzdGFnZU5hbWU/OiBzdHJpbmc7XG4gIGFjdGlvbk5hbWU/OiBzdHJpbmc7XG4gIHN0YXJ0ZWRBdD86IHN0cmluZztcbiAgY29tcGxldGVkQXQ/OiBzdHJpbmc7XG4gIGR1cmF0aW9uTXM/OiBudW1iZXI7XG4gIGRldGFpbD86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG4vKiogQ291bnRzICsgdGhlIChwb3NzaWJseSB0cnVuY2F0ZWQpIGxpc3Qgb2YgdW5yZWdpc3RlcmVkIEFSTnMgdGhlIGNhbGxlciBjYW4gbG9nLiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmdlc3RSZXN1bHQge1xuICBpbnNlcnRlZDogbnVtYmVyO1xuICBza2lwcGVkOiBudW1iZXI7XG4gIHVucmVnaXN0ZXJlZEFybnM6IHN0cmluZ1tdO1xufVxuXG4vLyDilIDilIDilIAgU2VydmljZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLyoqXG4gKiBSZWFkLW9ubHkgcmVwb3J0aW5nIHNlcnZpY2UgZm9yIHBpcGVsaW5lIGV4ZWN1dGlvbiBhbmQgcGx1Z2luIGludmVudG9yeSBhZ2dyZWdhdGlvbnMuXG4gKiBEb2VzIG5vdCBleHRlbmQgQ3J1ZFNlcnZpY2Ug4oCUIHJlcG9ydHMgYXJlIGFnZ3JlZ2F0ZSBxdWVyaWVzLCBub3QgZW50aXR5IENSVUQuXG4gKlxuICogQWxsIHF1ZXJpZXMgYXJlIGNhY2hlZCBpbi1tZW1vcnkgdG8gYXZvaWQgcmVwZWF0ZWQgZXhwZW5zaXZlIFNRTCBhZ2dyZWdhdGlvbnM6XG4gKiAtIEludmVudG9yeSBxdWVyaWVzIChwbHVnaW4gc3VtbWFyeS9kaXN0cmlidXRpb24vdmVyc2lvbnMpOiA1IG1pbiBUVExcbiAqIC0gVGltZXNlcmllcyBxdWVyaWVzIChleGVjdXRpb24vYnVpbGQgbWV0cmljcyB3aXRoIGRhdGUgcmFuZ2VzKTogMiBtaW4gVFRMXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXBvcnRpbmdTZXJ2aWNlIHtcblxuICAvKiogSW52YWxpZGF0ZSBhbGwgY2FjaGVkIHJlcG9ydHMgZm9yIGFuIG9yZyAoY2FsbCBhZnRlciBldmVudCBpbmdlc3QpLiAqL1xuICBhc3luYyBpbnZhbGlkYXRlT3JnKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICBpbnZlbnRvcnlDYWNoZS5pbnZhbGlkYXRlUGF0dGVybihgJHtvcmdJZH06KmApLFxuICAgICAgdGltZXNlcmllc0NhY2hlLmludmFsaWRhdGVQYXR0ZXJuKGAke29yZ0lkfToqYCksXG4gICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSBpbmNvbWluZyBldmVudHMgYWdhaW5zdCB0aGUgcGlwZWxpbmUgcmVnaXN0cnksIGJhdGNoLWluc2VydCB0aGVcbiAgICogbWF0Y2hlZCBvbmVzLCBhbmQgaW52YWxpZGF0ZSByZXBvcnRpbmcgY2FjaGVzIGZvciBhZmZlY3RlZCBvcmdzLlxuICAgKiBFdmVudHMgZm9yIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBBUk5zIGFyZSBkcm9wcGVkIChhbmQgbG9nZ2VkIGF0IFdBUk5cbiAgICogd2l0aCBzYW1wbGUgQVJOcyBzbyBhbiBvcGVyYXRvciBjYW4gc2VlIHdoZW4gRXZlbnRCcmlkZ2UgaXMgZGVsaXZlcmluZ1xuICAgKiBldmVudHMgZm9yIHBpcGVsaW5lcyB0aGF0IGhhdmVuJ3QgY2FsbGVkIFBPU1QgL3BpcGVsaW5lcy9yZWdpc3RyeSB5ZXQpLlxuICAgKlxuICAgKiBSZXR1cm5zIGNvdW50cyArIGEgc2FtcGxlIG9mIHVucmVnaXN0ZXJlZCBBUk5zIGZvciBvYnNlcnZhYmlsaXR5LlxuICAgKi9cbiAgYXN5bmMgaW5nZXN0RXZlbnRzKGV2ZW50czogSW5nZXN0RXZlbnRbXSk6IFByb21pc2U8SW5nZXN0UmVzdWx0PiB7XG4gICAgLy8gQmF0Y2gtcmVzb2x2ZSBhbGwgdW5pcXVlIEFSTnMgaW4gb25lIHF1ZXJ5XG4gICAgY29uc3QgdW5pcXVlQXJucyA9IFsuLi5uZXcgU2V0KGV2ZW50cy5tYXAoZSA9PiBlLnBpcGVsaW5lQXJuKSldO1xuICAgIGNvbnN0IHJlZ2lzdHJ5Um93cyA9IGF3YWl0IGRiXG4gICAgICAuc2VsZWN0KHtcbiAgICAgICAgcGlwZWxpbmVJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkucGlwZWxpbmVJZCxcbiAgICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5Lm9yZ0lkLFxuICAgICAgICBwaXBlbGluZUFybjogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkucGlwZWxpbmVBcm4sXG4gICAgICB9KVxuICAgICAgLmZyb20oc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkpXG4gICAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUFybiwgdW5pcXVlQXJucykpO1xuXG4gICAgY29uc3QgYXJuTWFwID0gbmV3IE1hcChyZWdpc3RyeVJvd3MubWFwKHIgPT4gW3IucGlwZWxpbmVBcm4sIHJdKSk7XG5cbiAgICAvLyBCdWlsZCBpbnNlcnQgYmF0Y2ggKHNraXAgdW5yZWdpc3RlcmVkIEFSTnMpXG4gICAgY29uc3Qgcm93czogQXJyYXk8dHlwZW9mIHNjaGVtYS5waXBlbGluZUV2ZW50LiRpbmZlckluc2VydD4gPSBbXTtcbiAgICBsZXQgc2tpcHBlZCA9IDA7XG4gICAgY29uc3QgdW5yZWdpc3RlcmVkQXJuczogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICBjb25zdCByZWdpc3RyeSA9IGFybk1hcC5nZXQoZXZlbnQucGlwZWxpbmVBcm4pO1xuICAgICAgaWYgKCFyZWdpc3RyeSkge1xuICAgICAgICBza2lwcGVkKys7XG4gICAgICAgIHVucmVnaXN0ZXJlZEFybnMucHVzaChldmVudC5waXBlbGluZUFybik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICByb3dzLnB1c2goe1xuICAgICAgICBwaXBlbGluZUlkOiByZWdpc3RyeS5waXBlbGluZUlkLFxuICAgICAgICBvcmdJZDogcmVnaXN0cnkub3JnSWQsXG4gICAgICAgIGV2ZW50U291cmNlOiBldmVudC5ldmVudFNvdXJjZSxcbiAgICAgICAgZXZlbnRUeXBlOiBldmVudC5ldmVudFR5cGUsXG4gICAgICAgIHN0YXR1czogZXZlbnQuc3RhdHVzLFxuICAgICAgICBwaXBlbGluZUFybjogaGFzaEFjY291bnRJbkFybihldmVudC5waXBlbGluZUFybiksXG4gICAgICAgIGV4ZWN1dGlvbklkOiBldmVudC5leGVjdXRpb25JZCxcbiAgICAgICAgc3RhZ2VOYW1lOiBldmVudC5zdGFnZU5hbWUsXG4gICAgICAgIGFjdGlvbk5hbWU6IGV2ZW50LmFjdGlvbk5hbWUsXG4gICAgICAgIHN0YXJ0ZWRBdDogZXZlbnQuc3RhcnRlZEF0ID8gbmV3IERhdGUoZXZlbnQuc3RhcnRlZEF0KSA6IHVuZGVmaW5lZCxcbiAgICAgICAgY29tcGxldGVkQXQ6IGV2ZW50LmNvbXBsZXRlZEF0ID8gbmV3IERhdGUoZXZlbnQuY29tcGxldGVkQXQpIDogdW5kZWZpbmVkLFxuICAgICAgICBkdXJhdGlvbk1zOiBldmVudC5kdXJhdGlvbk1zLFxuICAgICAgICBkZXRhaWw6IGV2ZW50LmRldGFpbCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChyb3dzLmxlbmd0aCA+IDApIHtcbiAgICAgIGF3YWl0IGRiLmluc2VydChzY2hlbWEucGlwZWxpbmVFdmVudCkudmFsdWVzKHJvd3MpO1xuXG4gICAgICAvLyBQZXItb3JnIGZhaWx1cmVzIGFyZSBsb2dnZWQgYnV0IGRvbid0IGZhaWwgdGhlIGJhdGNoIOKAlCBgUHJvbWlzZS5hbGxgXG4gICAgICAvLyBzbyB0aGUgY2FsbGVyIGRvZXNuJ3QgcmV0dXJuIGJlZm9yZSBpbnZhbGlkYXRpb24gY29tcGxldGVzLFxuICAgICAgLy8gb3RoZXJ3aXNlIGRhc2hib2FyZHMgY2FuIHNlcnZlIHN0YWxlIGRhdGEgcmlnaHQgYWZ0ZXIgaW5nZXN0LlxuICAgICAgY29uc3QgYWZmZWN0ZWRPcmdzID0gWy4uLm5ldyBTZXQocm93cy5tYXAociA9PiByLm9yZ0lkKSldO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoYWZmZWN0ZWRPcmdzLm1hcCgob3JnKSA9PlxuICAgICAgICB0aGlzLmludmFsaWRhdGVPcmcob3JnKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyBjYWNoZSBpbnZhbGlkYXRpb24gZmFpbGVkJywgeyBvcmdJZDogb3JnLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgaW5zZXJ0ZWQ6IHJvd3MubGVuZ3RoLCBza2lwcGVkLCB1bnJlZ2lzdGVyZWRBcm5zIH07XG4gIH1cblxuICAvLyDilIDilIAgQ2F0ZWdvcnkgMTogUGlwZWxpbmUgRXhlY3V0aW9uICYgUGVyZm9ybWFuY2Ug4pSA4pSAXG5cbiAgLyoqIDEuMSBFeGVjdXRpb24gY291bnQgcGVyIHBpcGVsaW5lIHdpdGggc3RhdHVzIGJyZWFrZG93bi4gKi9cbiAgYXN5bmMgZ2V0RXhlY3V0aW9uQ291bnQob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8RXhlY3V0aW9uQ291bnRbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmV4ZWMtY291bnRgLCAoKSA9PlxuICAgICAgZGIuZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIHAuaWQsIHAucHJvamVjdCwgcC5vcmdhbml6YXRpb24sIHAucGlwZWxpbmVfbmFtZSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHRvdGFsLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJyk6OmludCBBUyBzdWNjZWVkZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWxlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0NBTkNFTEVEJyk6OmludCBBUyBjYW5jZWxlZCxcbiAgICAgICAgICBNSU4oZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBmaXJzdF9leGVjdXRpb24sXG4gICAgICAgICAgTUFYKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgbGFzdF9leGVjdXRpb25cbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZX0gcFxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGUgT04gZS5waXBlbGluZV9pZCA9IHAuaWRcbiAgICAgICAgICBBTkQgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyBBTkQgZS5zdGF0dXMgIT0gJ1NUQVJURUQnXG4gICAgICAgIFdIRVJFIHAub3JnX2lkID0gJHtvcmdJZH0gQU5EIHAuaXNfYWN0aXZlID0gdHJ1ZVxuICAgICAgICBHUk9VUCBCWSBwLmlkXG4gICAgICAgIE9SREVSIEJZIHRvdGFsIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxFeGVjdXRpb25Db3VudD4oci5yb3dzKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAxLjIgU3VjY2VzcyByYXRlIG92ZXIgdGltZSBmb3IgYW4gb3JnLiAqL1xuICBhc3luYyBnZXRTdWNjZXNzUmF0ZShvcmdJZDogc3RyaW5nLCBpbnRlcnZhbDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPFRpbWVTZXJpZXNFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06c3VjY2Vzcy1yYXRlOiR7aW50ZXJ2YWx9OiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgZGIuZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIERBVEVfVFJVTkMoJHtpbnRlcnZhbH0sIGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgcGVyaW9kLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJyk6OmludCBBUyBzdWNjZWVkZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWxlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0NBTkNFTEVEJyk6OmludCBBUyBjYW5jZWxlZCxcbiAgICAgICAgICBST1VORChDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCcpOjpudW1lcmljXG4gICAgICAgICAgICAvIE5VTExJRihDT1VOVCgqKSwgMCkgKiAxMDAsIDEpOjpmbG9hdCBBUyBzdWNjZXNzX3BjdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnXG4gICAgICAgICAgQU5EIGUuc3RhdHVzIElOICgnU1VDQ0VFREVEJywgJ0ZBSUxFRCcsICdDQU5DRUxFRCcpXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwZXJpb2QgT1JERVIgQlkgcGVyaW9kXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VGltZVNlcmllc0VudHJ5PihyLnJvd3MpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDEuMyBBdmVyYWdlIGR1cmF0aW9uIHBlciBwaXBlbGluZS4gKi9cbiAgYXN5bmMgZ2V0QXZlcmFnZUR1cmF0aW9uKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IFByb21pc2U8RHVyYXRpb25TdGF0c1tdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06YXZnLWR1cmF0aW9uOiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgZGIuZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIHAuaWQsIHAucHJvamVjdCwgcC5waXBlbGluZV9uYW1lLFxuICAgICAgICAgIEFWRyhlLmR1cmF0aW9uX21zKTo6aW50IEFTIGF2Z19tcyxcbiAgICAgICAgICBNSU4oZS5kdXJhdGlvbl9tcyk6OmludCBBUyBtaW5fbXMsXG4gICAgICAgICAgTUFYKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWF4X21zLFxuICAgICAgICAgIFBFUkNFTlRJTEVfQ09OVCgwLjk1KSBXSVRISU4gR1JPVVAgKE9SREVSIEJZIGUuZHVyYXRpb25fbXMpOjppbnQgQVMgcDk1X21zLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgZXhlY3V0aW9uc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLmR1cmF0aW9uX21zIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwLmlkIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8RHVyYXRpb25TdGF0cz4oci5yb3dzKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAxLjUgU3RhZ2UgZmFpbHVyZSBoZWF0bWFwIOKAlCB3aGljaCBzdGFnZXMgZmFpbCBtb3N0LiAqL1xuICBhc3luYyBnZXRTdGFnZUZhaWx1cmVzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IFByb21pc2U8U3RhZ2VGYWlsdXJlW10+IHtcbiAgICByZXR1cm4gdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpzdGFnZS1mYWlsdXJlczoke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIGRiLmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLnN0YWdlX25hbWUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWx1cmVzLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgZmFpbHVyZV9wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF90eXBlID0gJ1NUQUdFJyBBTkQgZS5zdGFnZV9uYW1lIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBlLnN0YWdlX25hbWUgT1JERVIgQlkgZmFpbHVyZXMgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFN0YWdlRmFpbHVyZT4oci5yb3dzKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAxLjYgU3RhZ2UgYm90dGxlbmVja3Mg4oCUIHNsb3dlc3Qgc3RhZ2VzIHBlciBwaXBlbGluZS4gKi9cbiAgYXN5bmMgZ2V0U3RhZ2VCb3R0bGVuZWNrcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPFN0YWdlQm90dGxlbmVja1tdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06c3RhZ2UtYm90dGxlbmVja3M6JHtmcm9tfToke3RvfWAsICgpID0+XG4gICAgICBkYi5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5waXBlbGluZV9uYW1lLCBlLnN0YWdlX25hbWUsXG4gICAgICAgICAgQVZHKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgYXZnX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLmR1cmF0aW9uX21zIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwLmlkLCBlLnN0YWdlX25hbWUgT1JERVIgQlkgYXZnX21zIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxTdGFnZUJvdHRsZW5lY2s+KHIucm93cykpLFxuICAgICk7XG4gIH1cblxuICAvKiogMS43IEFjdGlvbiBmYWlsdXJlIHJhdGUg4oCUIHdoaWNoIHBsdWdpbiBzdGVwcyBmYWlsIG1vc3QuICovXG4gIGFzeW5jIGdldEFjdGlvbkZhaWx1cmVzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IFByb21pc2U8QWN0aW9uRmFpbHVyZVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06YWN0aW9uLWZhaWx1cmVzOiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgZGIuZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuYWN0aW9uX25hbWUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWx1cmVzLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgZmFpbHVyZV9wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF90eXBlID0gJ0FDVElPTicgQU5EIGUuYWN0aW9uX25hbWUgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIGUuYWN0aW9uX25hbWUgT1JERVIgQlkgZmFpbHVyZXMgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPEFjdGlvbkZhaWx1cmU+KHIucm93cykpLFxuICAgICk7XG4gIH1cblxuICAvKiogMS44IEVycm9yIGNhdGVnb3JpemF0aW9uIOKAlCBncm91cCBmYWlsdXJlIG1lc3NhZ2VzLiAqL1xuICBhc3luYyBnZXRFcnJvcnMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBsaW1pdDogbnVtYmVyID0gMjApOiBQcm9taXNlPEVycm9yRW50cnlbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmVycm9yczoke2Zyb219OiR7dG99OiR7bGltaXR9YCwgKCkgPT5cbiAgICAgIGRiLmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBTVUJTVFJJTkcoZS5lcnJvcl9tZXNzYWdlIEZST00gMSBGT1IgMjAwKSBBUyBlcnJvcl9wYXR0ZXJuLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgb2NjdXJyZW5jZXMsXG4gICAgICAgICAgQ09VTlQoRElTVElOQ1QgZS5waXBlbGluZV9pZCk6OmludCBBUyBhZmZlY3RlZF9waXBlbGluZXMsXG4gICAgICAgICAgTUFYKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgbGFzdF9zZWVuXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuc3RhdHVzID0gJ0ZBSUxFRCcgQU5EIGUuZXJyb3JfbWVzc2FnZSBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgZXJyb3JfcGF0dGVybiBPUkRFUiBCWSBvY2N1cnJlbmNlcyBERVNDXG4gICAgICAgIExJTUlUICR7bGltaXR9XG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8RXJyb3JFbnRyeT4oci5yb3dzKSksXG4gICAgKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBDYXRlZ29yeSAyOiBQbHVnaW4gSW52ZW50b3J5ICYgQnVpbGRzIOKUgOKUgFxuXG4gIC8qKiAyLjEgUGx1Z2luIHN1bW1hcnkg4oCUIGNvdW50cyBhbmQgYnJlYWtkb3ducy4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luU3VtbWFyeShvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxQbHVnaW5TdW1tYXJ5PiB7XG4gICAgcmV0dXJuIGludmVudG9yeUNhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpwbHVnaW4tc3VtbWFyeWAsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBkYi5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0pOjppbnQgQVMgYWN0aXZlLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgTk9UICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0pOjppbnQgQVMgaW5hY3RpdmUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSAke3NjaGVtYS5wbHVnaW4uYWNjZXNzTW9kaWZpZXJ9ID0gJ3B1YmxpYycpOjppbnQgQVMgcHVibGljLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLmFjY2Vzc01vZGlmaWVyfSA9ICdwcml2YXRlJyk6OmludCBBUyBwcml2YXRlLFxuICAgICAgICAgIENPVU5UKERJU1RJTkNUICR7c2NoZW1hLnBsdWdpbi5uYW1lfSk6OmludCBBUyB1bmlxdWVfbmFtZXNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfVxuICAgICAgYCk7XG4gICAgICByZXR1cm4gKGRyaXp6bGVSb3dzPFBsdWdpblN1bW1hcnk+KHJvd3Mucm93cylbMF0gfHwgeyB0b3RhbDogMCwgYWN0aXZlOiAwLCBpbmFjdGl2ZTogMCwgcHVibGljOiAwLCBwcml2YXRlOiAwLCB1bmlxdWVOYW1lczogMCB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiAyLjIgVHlwZSAmIGNvbXB1dGUgZGlzdHJpYnV0aW9uLiAqL1xuICBhc3luYyBnZXRQbHVnaW5EaXN0cmlidXRpb24ob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8VHlwZUNvbXB1dGVEaXN0cmlidXRpb25bXT4ge1xuICAgIHJldHVybiBpbnZlbnRvcnlDYWNoZS5nZXRPclNldChgJHtvcmdJZH06cGx1Z2luLWRpc3RyaWJ1dGlvbmAsICgpID0+XG4gICAgICBkYi5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgJHtzY2hlbWEucGx1Z2luLnBsdWdpblR5cGV9IEFTIHBsdWdpbl90eXBlLFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5jb21wdXRlVHlwZX0gQVMgY29tcHV0ZV90eXBlLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgY291bnRcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfSBBTkQgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgJHtzY2hlbWEucGx1Z2luLnBsdWdpblR5cGV9LCAke3NjaGVtYS5wbHVnaW4uY29tcHV0ZVR5cGV9XG4gICAgICAgIE9SREVSIEJZIGNvdW50IERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxUeXBlQ29tcHV0ZURpc3RyaWJ1dGlvbj4oci5yb3dzKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAyLjMgVmVyc2lvbiBjb3VudHMgcGVyIHBsdWdpbiBuYW1lLiAqL1xuICBhc3luYyBnZXRQbHVnaW5WZXJzaW9ucyhvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxWZXJzaW9uQ291bnRbXT4ge1xuICAgIHJldHVybiBpbnZlbnRvcnlDYWNoZS5nZXRPclNldChgJHtvcmdJZH06cGx1Z2luLXZlcnNpb25zYCwgKCkgPT5cbiAgICAgIGRiLmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICAke3NjaGVtYS5wbHVnaW4ubmFtZX0sXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB2ZXJzaW9uX2NvdW50LFxuICAgICAgICAgIE1BWCgke3NjaGVtYS5wbHVnaW4udmVyc2lvbn0pIEFTIGxhdGVzdF92ZXJzaW9uLFxuICAgICAgICAgIGJvb2xfb3IoJHtzY2hlbWEucGx1Z2luLmlzRGVmYXVsdH0pIEFTIGhhc19kZWZhdWx0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGx1Z2lufVxuICAgICAgICBXSEVSRSAke3NjaGVtYS5wbHVnaW4ub3JnSWR9ID0gJHtvcmdJZH0gQU5EICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0gPSB0cnVlXG4gICAgICAgIEdST1VQIEJZICR7c2NoZW1hLnBsdWdpbi5uYW1lfVxuICAgICAgICBPUkRFUiBCWSB2ZXJzaW9uX2NvdW50IERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxWZXJzaW9uQ291bnQ+KHIucm93cykpLFxuICAgICk7XG4gIH1cblxuICAvKiogMi40IEJ1aWxkIHN1Y2Nlc3MgcmF0ZSBvdmVyIHRpbWUuICovXG4gIGFzeW5jIGdldEJ1aWxkU3VjY2Vzc1JhdGUob3JnSWQ6IHN0cmluZywgaW50ZXJ2YWw6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogUHJvbWlzZTxCdWlsZFRpbWVTZXJpZXNFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06YnVpbGQtc3VjY2Vzczoke2ludGVydmFsfToke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIGRiLmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBEQVRFX1RSVU5DKCR7aW50ZXJ2YWx9LCBlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIHBlcmlvZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ2NvbXBsZXRlZCcpOjppbnQgQVMgc3VjY2VlZGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnZmFpbGVkJyk6OmludCBBUyBmYWlsZWQsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdjb21wbGV0ZWQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgc3VjY2Vzc19wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIFdIRVJFIGUub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfc291cmNlID0gJ3BsdWdpbi1idWlsZCdcbiAgICAgICAgICBBTkQgZS5zdGF0dXMgSU4gKCdjb21wbGV0ZWQnLCAnZmFpbGVkJylcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIHBlcmlvZCBPUkRFUiBCWSBwZXJpb2RcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxCdWlsZFRpbWVTZXJpZXNFbnRyeT4oci5yb3dzKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAyLjUgQnVpbGQgZHVyYXRpb24gcGVyIHBsdWdpbi4gKi9cbiAgYXN5bmMgZ2V0QnVpbGREdXJhdGlvbihvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPEJ1aWxkRHVyYXRpb25bXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmJ1aWxkLWR1cmF0aW9uOiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgZGIuZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuZGV0YWlsLT4+J3BsdWdpbk5hbWUnIEFTIHBsdWdpbl9uYW1lLFxuICAgICAgICAgIEFWRyhlLmR1cmF0aW9uX21zKTo6aW50IEFTIGF2Z19tcyxcbiAgICAgICAgICBNQVgoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBtYXhfbXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBidWlsZHNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIFdIRVJFIGUub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfc291cmNlID0gJ3BsdWdpbi1idWlsZCcgQU5EIGUuZHVyYXRpb25fbXMgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIHBsdWdpbl9uYW1lIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8QnVpbGREdXJhdGlvbj4oci5yb3dzKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAyLjYgQnVpbGQgZmFpbHVyZXMg4oCUIHRvcCBlcnJvciBtZXNzYWdlcy4gKi9cbiAgYXN5bmMgZ2V0QnVpbGRGYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIGxpbWl0OiBudW1iZXIgPSAyMCk6IFByb21pc2U8QnVpbGRGYWlsdXJlW10+IHtcbiAgICByZXR1cm4gdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpidWlsZC1mYWlsdXJlczoke2Zyb219OiR7dG99OiR7bGltaXR9YCwgKCkgPT5cbiAgICAgIGRiLmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLmRldGFpbC0+PidwbHVnaW5OYW1lJyBBUyBwbHVnaW5fbmFtZSxcbiAgICAgICAgICBlLmVycm9yX21lc3NhZ2UsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBvY2N1cnJlbmNlcyxcbiAgICAgICAgICBNQVgoZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBsYXN0X3NlZW5cbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIFdIRVJFIGUub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfc291cmNlID0gJ3BsdWdpbi1idWlsZCcgQU5EIGUuc3RhdHVzID0gJ2ZhaWxlZCdcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIHBsdWdpbl9uYW1lLCBlLmVycm9yX21lc3NhZ2VcbiAgICAgICAgT1JERVIgQlkgb2NjdXJyZW5jZXMgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPEJ1aWxkRmFpbHVyZT4oci5yb3dzKSksXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgcmVwb3J0aW5nU2VydmljZSA9IG5ldyBSZXBvcnRpbmdTZXJ2aWNlKCk7XG4iXX0=
316
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0aW5nLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JlcG9ydGluZy1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDOzs7QUFFdEMseURBQThHO0FBQzlHLDZDQUEyQztBQUMzQyxpREFBNkM7QUFDN0MsK0RBQW9EO0FBQ3BELGlEQUFtRDtBQUVuRCxNQUFNLE1BQU0sR0FBRyxJQUFBLHVCQUFZLEVBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUVqRDs7OztHQUlHO0FBQ0gsTUFBTSxjQUFjLEdBQUcsSUFBQSw2QkFBa0IsRUFBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsMEJBQTBCLElBQUksS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDeEgsTUFBTSxlQUFlLEdBQUcsSUFBQSw2QkFBa0IsRUFBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLElBQUksS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFrSXpILDJEQUEyRDtBQUUzRDs7Ozs7OztHQU9HO0FBQ0gsTUFBYSxnQkFBZ0I7SUFFM0IsMEVBQTBFO0lBQzFFLEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBYTtRQUMvQixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDaEIsY0FBYyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUM7WUFDOUMsZUFBZSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUM7U0FDaEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFxQjtRQUN0Qyx1RUFBdUU7UUFDdkUsc0VBQXNFO1FBQ3RFLDJFQUEyRTtRQUMzRSxzRUFBc0U7UUFDdEUscUVBQXFFO1FBQ3JFLHFFQUFx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SSxJQUFJLEVBQUUsSUFBSSxLQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FDckYsSUFBQSxzQkFBWSxFQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUEsaUJBQUcsRUFBQTs7Ozs7O2VBTTFCLHVCQUFNLENBQUMsYUFBYTsyQkFDUixLQUFLO2dDQUNBLElBQUkscUNBQXFDLEVBQUU7OztnQkFHM0QsS0FBSztPQUNkLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFBLDBCQUFXLEVBQWUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FDakQsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQS9VRCw0Q0ErVUM7QUFFWSxRQUFBLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBjcmVhdGVDYWNoZVNlcnZpY2UsIGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlLCBoYXNoQWNjb3VudEluQXJuIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgaW5BcnJheSwgc3FsIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgZHJpenpsZVJvd3MgfSBmcm9tICcuL2NydWQtc2VydmljZSc7XG5pbXBvcnQgeyBzY2hlbWEgfSBmcm9tICcuLi9kYXRhYmFzZS9kcml6emxlLXNjaGVtYSc7XG5pbXBvcnQgeyB3aXRoVGVuYW50VHggfSBmcm9tICcuLi9kYXRhYmFzZS90ZW5hbmN5JztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdyZXBvcnRpbmctc2VydmljZScpO1xuXG4vKipcbiAqIENhY2hlIGZvciByZXBvcnRpbmcgYWdncmVnYXRpb25zLiBUd28gdGllcnM6XG4gKiAtIEludmVudG9yeSBxdWVyaWVzIChwbHVnaW4gc3VtbWFyeS9kaXN0cmlidXRpb24vdmVyc2lvbnMpOiA1IG1pbiBUVEwg4oCUIGNoYW5nZXMgb24gcGx1Z2luIENSVURcbiAqIC0gRXhlY3V0aW9uL2J1aWxkIHF1ZXJpZXMgd2l0aCBkYXRlIHJhbmdlczogMiBtaW4gVFRMIOKAlCBuZXcgZXZlbnRzIGFycml2ZSBjb250aW51b3VzbHlcbiAqL1xuY29uc3QgaW52ZW50b3J5Q2FjaGUgPSBjcmVhdGVDYWNoZVNlcnZpY2UoJ3JlcG9ydDppbnY6JywgcGFyc2VJbnQocHJvY2Vzcy5lbnYuQ0FDSEVfVFRMX1JFUE9SVF9JTlZFTlRPUlkgfHwgJzMwMCcsIDEwKSk7XG5jb25zdCB0aW1lc2VyaWVzQ2FjaGUgPSBjcmVhdGVDYWNoZVNlcnZpY2UoJ3JlcG9ydDp0czonLCBwYXJzZUludChwcm9jZXNzLmVudi5DQUNIRV9UVExfUkVQT1JUX1RJTUVTRVJJRVMgfHwgJzEyMCcsIDEwKSk7XG5cbi8vIOKUgOKUgOKUgCBUeXBlcyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuaW50ZXJmYWNlIEV4ZWN1dGlvbkNvdW50IHtcbiAgaWQ6IHN0cmluZztcbiAgcHJvamVjdDogc3RyaW5nO1xuICBvcmdhbml6YXRpb246IHN0cmluZztcbiAgcGlwZWxpbmVOYW1lOiBzdHJpbmcgfCBudWxsO1xuICB0b3RhbDogbnVtYmVyO1xuICBzdWNjZWVkZWQ6IG51bWJlcjtcbiAgZmFpbGVkOiBudW1iZXI7XG4gIGNhbmNlbGVkOiBudW1iZXI7XG4gIGZpcnN0RXhlY3V0aW9uOiBzdHJpbmcgfCBudWxsO1xuICBsYXN0RXhlY3V0aW9uOiBzdHJpbmcgfCBudWxsO1xufVxuXG5pbnRlcmZhY2UgVGltZVNlcmllc0VudHJ5IHtcbiAgcGVyaW9kOiBzdHJpbmc7XG4gIHN1Y2NlZWRlZDogbnVtYmVyO1xuICBmYWlsZWQ6IG51bWJlcjtcbiAgY2FuY2VsZWQ6IG51bWJlcjtcbiAgc3VjY2Vzc1BjdDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgRHVyYXRpb25TdGF0cyB7XG4gIGlkOiBzdHJpbmc7XG4gIHByb2plY3Q6IHN0cmluZztcbiAgcGlwZWxpbmVOYW1lOiBzdHJpbmcgfCBudWxsO1xuICBhdmdNczogbnVtYmVyO1xuICBtaW5NczogbnVtYmVyO1xuICBtYXhNczogbnVtYmVyO1xuICBwOTVNczogbnVtYmVyO1xuICBleGVjdXRpb25zOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBTdGFnZUZhaWx1cmUge1xuICBzdGFnZU5hbWU6IHN0cmluZztcbiAgZmFpbHVyZXM6IG51bWJlcjtcbiAgdG90YWw6IG51bWJlcjtcbiAgZmFpbHVyZVBjdDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgU3RhZ2VCb3R0bGVuZWNrIHtcbiAgaWQ6IHN0cmluZztcbiAgcGlwZWxpbmVOYW1lOiBzdHJpbmcgfCBudWxsO1xuICBzdGFnZU5hbWU6IHN0cmluZztcbiAgYXZnTXM6IG51bWJlcjtcbiAgbWF4TXM6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIEFjdGlvbkZhaWx1cmUge1xuICBhY3Rpb25OYW1lOiBzdHJpbmc7XG4gIGZhaWx1cmVzOiBudW1iZXI7XG4gIHRvdGFsOiBudW1iZXI7XG4gIGZhaWx1cmVQY3Q6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIEVycm9yRW50cnkge1xuICBlcnJvclBhdHRlcm46IHN0cmluZztcbiAgb2NjdXJyZW5jZXM6IG51bWJlcjtcbiAgYWZmZWN0ZWRQaXBlbGluZXM6IG51bWJlcjtcbiAgbGFzdFNlZW46IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFBsdWdpblN1bW1hcnkge1xuICB0b3RhbDogbnVtYmVyO1xuICBhY3RpdmU6IG51bWJlcjtcbiAgaW5hY3RpdmU6IG51bWJlcjtcbiAgcHVibGljOiBudW1iZXI7XG4gIHByaXZhdGU6IG51bWJlcjtcbiAgdW5pcXVlTmFtZXM6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFR5cGVDb21wdXRlRGlzdHJpYnV0aW9uIHtcbiAgcGx1Z2luVHlwZTogc3RyaW5nO1xuICBjb21wdXRlVHlwZTogc3RyaW5nO1xuICBjb3VudDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgVmVyc2lvbkNvdW50IHtcbiAgbmFtZTogc3RyaW5nO1xuICB2ZXJzaW9uQ291bnQ6IG51bWJlcjtcbiAgbGF0ZXN0VmVyc2lvbjogc3RyaW5nO1xuICBoYXNEZWZhdWx0OiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgQnVpbGRUaW1lU2VyaWVzRW50cnkge1xuICBwZXJpb2Q6IHN0cmluZztcbiAgc3VjY2VlZGVkOiBudW1iZXI7XG4gIGZhaWxlZDogbnVtYmVyO1xuICBzdWNjZXNzUGN0OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBCdWlsZER1cmF0aW9uIHtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBhdmdNczogbnVtYmVyO1xuICBtYXhNczogbnVtYmVyO1xuICBidWlsZHM6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIEJ1aWxkRmFpbHVyZSB7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgZXJyb3JNZXNzYWdlOiBzdHJpbmc7XG4gIG9jY3VycmVuY2VzOiBudW1iZXI7XG4gIGxhc3RTZWVuOiBzdHJpbmc7XG59XG5cbi8qKiBFdmVudCBwYXlsb2FkIGFjY2VwdGVkIGJ5IGBSZXBvcnRpbmdTZXJ2aWNlLmluZ2VzdEV2ZW50c2AuIE1pcnJvcnMgdGhlIHJvdXRlJ3MgWm9kIHNoYXBlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmdlc3RFdmVudCB7XG4gIHBpcGVsaW5lQXJuOiBzdHJpbmc7XG4gIGV2ZW50U291cmNlOiAnY29kZXBpcGVsaW5lJyB8ICdjb2RlYnVpbGQnIHwgJ3BsdWdpbi1idWlsZCc7XG4gIGV2ZW50VHlwZTogJ1BJUEVMSU5FJyB8ICdTVEFHRScgfCAnQUNUSU9OJyB8ICdCVUlMRCc7XG4gIHN0YXR1czogc3RyaW5nO1xuICBleGVjdXRpb25JZD86IHN0cmluZztcbiAgc3RhZ2VOYW1lPzogc3RyaW5nO1xuICBhY3Rpb25OYW1lPzogc3RyaW5nO1xuICBzdGFydGVkQXQ/OiBzdHJpbmc7XG4gIGNvbXBsZXRlZEF0Pzogc3RyaW5nO1xuICBkdXJhdGlvbk1zPzogbnVtYmVyO1xuICBkZXRhaWw/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuLyoqIENvdW50cyArIHRoZSAocG9zc2libHkgdHJ1bmNhdGVkKSBsaXN0IG9mIHVucmVnaXN0ZXJlZCBBUk5zIHRoZSBjYWxsZXIgY2FuIGxvZy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5nZXN0UmVzdWx0IHtcbiAgaW5zZXJ0ZWQ6IG51bWJlcjtcbiAgc2tpcHBlZDogbnVtYmVyO1xuICB1bnJlZ2lzdGVyZWRBcm5zOiBzdHJpbmdbXTtcbn1cblxuLy8g4pSA4pSA4pSAIFNlcnZpY2Ug4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8qKlxuICogUmVhZC1vbmx5IHJlcG9ydGluZyBzZXJ2aWNlIGZvciBwaXBlbGluZSBleGVjdXRpb24gYW5kIHBsdWdpbiBpbnZlbnRvcnkgYWdncmVnYXRpb25zLlxuICogRG9lcyBub3QgZXh0ZW5kIENydWRTZXJ2aWNlIOKAlCByZXBvcnRzIGFyZSBhZ2dyZWdhdGUgcXVlcmllcywgbm90IGVudGl0eSBDUlVELlxuICpcbiAqIEFsbCBxdWVyaWVzIGFyZSBjYWNoZWQgaW4tbWVtb3J5IHRvIGF2b2lkIHJlcGVhdGVkIGV4cGVuc2l2ZSBTUUwgYWdncmVnYXRpb25zOlxuICogLSBJbnZlbnRvcnkgcXVlcmllcyAocGx1Z2luIHN1bW1hcnkvZGlzdHJpYnV0aW9uL3ZlcnNpb25zKTogNSBtaW4gVFRMXG4gKiAtIFRpbWVzZXJpZXMgcXVlcmllcyAoZXhlY3V0aW9uL2J1aWxkIG1ldHJpY3Mgd2l0aCBkYXRlIHJhbmdlcyk6IDIgbWluIFRUTFxuICovXG5leHBvcnQgY2xhc3MgUmVwb3J0aW5nU2VydmljZSB7XG5cbiAgLyoqIEludmFsaWRhdGUgYWxsIGNhY2hlZCByZXBvcnRzIGZvciBhbiBvcmcgKGNhbGwgYWZ0ZXIgZXZlbnQgaW5nZXN0KS4gKi9cbiAgYXN5bmMgaW52YWxpZGF0ZU9yZyhvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgaW52ZW50b3J5Q2FjaGUuaW52YWxpZGF0ZVBhdHRlcm4oYCR7b3JnSWR9OipgKSxcbiAgICAgIHRpbWVzZXJpZXNDYWNoZS5pbnZhbGlkYXRlUGF0dGVybihgJHtvcmdJZH06KmApLFxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgaW5jb21pbmcgZXZlbnRzIGFnYWluc3QgdGhlIHBpcGVsaW5lIHJlZ2lzdHJ5LCBiYXRjaC1pbnNlcnQgdGhlXG4gICAqIG1hdGNoZWQgb25lcywgYW5kIGludmFsaWRhdGUgcmVwb3J0aW5nIGNhY2hlcyBmb3IgYWZmZWN0ZWQgb3Jncy5cbiAgICogRXZlbnRzIGZvciB1bnJlZ2lzdGVyZWQgcGlwZWxpbmUgQVJOcyBhcmUgZHJvcHBlZCAoYW5kIGxvZ2dlZCBhdCBXQVJOXG4gICAqIHdpdGggc2FtcGxlIEFSTnMgc28gYW4gb3BlcmF0b3IgY2FuIHNlZSB3aGVuIEV2ZW50QnJpZGdlIGlzIGRlbGl2ZXJpbmdcbiAgICogZXZlbnRzIGZvciBwaXBlbGluZXMgdGhhdCBoYXZlbid0IGNhbGxlZCBQT1NUIC9waXBlbGluZXMvcmVnaXN0cnkgeWV0KS5cbiAgICpcbiAgICogUmV0dXJucyBjb3VudHMgKyBhIHNhbXBsZSBvZiB1bnJlZ2lzdGVyZWQgQVJOcyBmb3Igb2JzZXJ2YWJpbGl0eS5cbiAgICovXG4gIGFzeW5jIGluZ2VzdEV2ZW50cyhldmVudHM6IEluZ2VzdEV2ZW50W10pOiBQcm9taXNlPEluZ2VzdFJlc3VsdD4ge1xuICAgIC8vIE11bHRpLW9yZyBiYXRjaCBpbnNlcnQ6IHRoZSBjYWxsZXIgcmVzb2x2ZXMgdG8gbXVsdGlwbGUgb3JncyB2aWEgdGhlXG4gICAgLy8gcGlwZWxpbmUtcmVnaXN0cnkgbG9va3VwIGJlbG93LCBzbyB0aGUgcm91dGUgbGF5ZXIgTVVTVCBlc3RhYmxpc2ggYVxuICAgIC8vIGBydW5XaXRoVGVuYW50Q29udGV4dCh7IGlzU3VwZXJBZG1pbjogdHJ1ZSB9LCAuLi4pYCBzY29wZSBiZWZvcmUgY2FsbGluZ1xuICAgIC8vIHRoaXMgbWV0aG9kLiBVbmRlciBGT1JDRSdkIFJMUywgYSBzaW5nbGUgdHggd2l0aCBgYXBwLm9yZ19pZCA9IDxvbmVcbiAgICAvLyBvcmc+YCBjb3VsZCBvbmx5IHdyaXRlIGV2ZW50cyBmb3IgdGhhdCBvcmc7IGJ5cGFzcyB2aWEgc3lzYWRtaW4gaXNcbiAgICAvLyB0aGUgcmlnaHQgZ2F0ZSBmb3IgdGhpcyBzZXJ2ZXItaW50ZXJuYWwgY3Jvc3MtdGVuYW50IGVuZHBvaW50LiBTZWVcbiAgICAvLyBhcGkvcmVwb3J0aW5nL3NyYy9yb3V0ZXMvZXZlbnQtaW5nZXN0LnRzIGZvciB0aGUgd3JhcHBlci5cbiAgICByZXR1cm4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4ge1xuICAgICAgLy8gQmF0Y2gtcmVzb2x2ZSBhbGwgdW5pcXVlIEFSTnMgaW4gb25lIHF1ZXJ5XG4gICAgICBjb25zdCB1bmlxdWVBcm5zID0gWy4uLm5ldyBTZXQoZXZlbnRzLm1hcChlID0+IGUucGlwZWxpbmVBcm4pKV07XG4gICAgICBjb25zdCByZWdpc3RyeVJvd3MgPSBhd2FpdCB0eFxuICAgICAgICAuc2VsZWN0KHtcbiAgICAgICAgICBwaXBlbGluZUlkOiBzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLFxuICAgICAgICAgIG9yZ0lkOiBzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5vcmdJZCxcbiAgICAgICAgICBwaXBlbGluZUFybjogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkucGlwZWxpbmVBcm4sXG4gICAgICAgIH0pXG4gICAgICAgIC5mcm9tKHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5KVxuICAgICAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUFybiwgdW5pcXVlQXJucykpO1xuXG4gICAgICBjb25zdCBhcm5NYXAgPSBuZXcgTWFwKHJlZ2lzdHJ5Um93cy5tYXAociA9PiBbci5waXBlbGluZUFybiwgcl0pKTtcblxuICAgICAgLy8gQnVpbGQgaW5zZXJ0IGJhdGNoIChza2lwIHVucmVnaXN0ZXJlZCBBUk5zKVxuICAgICAgY29uc3Qgcm93czogQXJyYXk8dHlwZW9mIHNjaGVtYS5waXBlbGluZUV2ZW50LiRpbmZlckluc2VydD4gPSBbXTtcbiAgICAgIGxldCBza2lwcGVkID0gMDtcbiAgICAgIGNvbnN0IHVucmVnaXN0ZXJlZEFybnM6IHN0cmluZ1tdID0gW107XG5cbiAgICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICAgIGNvbnN0IHJlZ2lzdHJ5ID0gYXJuTWFwLmdldChldmVudC5waXBlbGluZUFybik7XG4gICAgICAgIGlmICghcmVnaXN0cnkpIHtcbiAgICAgICAgICBza2lwcGVkKys7XG4gICAgICAgICAgdW5yZWdpc3RlcmVkQXJucy5wdXNoKGV2ZW50LnBpcGVsaW5lQXJuKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJvd3MucHVzaCh7XG4gICAgICAgICAgcGlwZWxpbmVJZDogcmVnaXN0cnkucGlwZWxpbmVJZCxcbiAgICAgICAgICBvcmdJZDogcmVnaXN0cnkub3JnSWQsXG4gICAgICAgICAgZXZlbnRTb3VyY2U6IGV2ZW50LmV2ZW50U291cmNlLFxuICAgICAgICAgIGV2ZW50VHlwZTogZXZlbnQuZXZlbnRUeXBlLFxuICAgICAgICAgIHN0YXR1czogZXZlbnQuc3RhdHVzLFxuICAgICAgICAgIHBpcGVsaW5lQXJuOiBoYXNoQWNjb3VudEluQXJuKGV2ZW50LnBpcGVsaW5lQXJuKSxcbiAgICAgICAgICBleGVjdXRpb25JZDogZXZlbnQuZXhlY3V0aW9uSWQsXG4gICAgICAgICAgc3RhZ2VOYW1lOiBldmVudC5zdGFnZU5hbWUsXG4gICAgICAgICAgYWN0aW9uTmFtZTogZXZlbnQuYWN0aW9uTmFtZSxcbiAgICAgICAgICBzdGFydGVkQXQ6IGV2ZW50LnN0YXJ0ZWRBdCA/IG5ldyBEYXRlKGV2ZW50LnN0YXJ0ZWRBdCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgY29tcGxldGVkQXQ6IGV2ZW50LmNvbXBsZXRlZEF0ID8gbmV3IERhdGUoZXZlbnQuY29tcGxldGVkQXQpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGR1cmF0aW9uTXM6IGV2ZW50LmR1cmF0aW9uTXMsXG4gICAgICAgICAgZGV0YWlsOiBldmVudC5kZXRhaWwsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAocm93cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHR4Lmluc2VydChzY2hlbWEucGlwZWxpbmVFdmVudCkudmFsdWVzKHJvd3MpO1xuXG4gICAgICAgIC8vIFBlci1vcmcgY2FjaGUgaW52YWxpZGF0aW9uIHJ1bnMgb3V0c2lkZSB0aGUgdHggKFJlZGlzLCBub3QgUG9zdGdyZXMpLlxuICAgICAgICAvLyBgUHJvbWlzZS5hbGxgIHNvIHRoZSBjYWxsZXIgZG9lc24ndCByZXR1cm4gYmVmb3JlIGludmFsaWRhdGlvblxuICAgICAgICAvLyBjb21wbGV0ZXMsIG90aGVyd2lzZSBkYXNoYm9hcmRzIGNhbiBzZXJ2ZSBzdGFsZSBkYXRhIHJpZ2h0IGFmdGVyIGluZ2VzdC5cbiAgICAgICAgY29uc3QgYWZmZWN0ZWRPcmdzID0gWy4uLm5ldyBTZXQocm93cy5tYXAociA9PiByLm9yZ0lkKSldO1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChhZmZlY3RlZE9yZ3MubWFwKChvcmcpID0+XG4gICAgICAgICAgdGhpcy5pbnZhbGlkYXRlT3JnKG9yZykuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyBjYWNoZSBpbnZhbGlkYXRpb24gZmFpbGVkJywgeyBvcmdJZDogb3JnLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICAgICAgfSksXG4gICAgICAgICkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4geyBpbnNlcnRlZDogcm93cy5sZW5ndGgsIHNraXBwZWQsIHVucmVnaXN0ZXJlZEFybnMgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBDYXRlZ29yeSAxOiBQaXBlbGluZSBFeGVjdXRpb24gJiBQZXJmb3JtYW5jZSDilIDilIBcblxuICAvKiogMS4xIEV4ZWN1dGlvbiBjb3VudCBwZXIgcGlwZWxpbmUgd2l0aCBzdGF0dXMgYnJlYWtkb3duLiAqL1xuICBhc3luYyBnZXRFeGVjdXRpb25Db3VudChvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxFeGVjdXRpb25Db3VudFtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06ZXhlYy1jb3VudGAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5wcm9qZWN0LCBwLm9yZ2FuaXphdGlvbiwgcC5waXBlbGluZV9uYW1lLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnQ0FOQ0VMRUQnKTo6aW50IEFTIGNhbmNlbGVkLFxuICAgICAgICAgIE1JTihlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGZpcnN0X2V4ZWN1dGlvbixcbiAgICAgICAgICBNQVgoZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBsYXN0X2V4ZWN1dGlvblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lfSBwXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZSBPTiBlLnBpcGVsaW5lX2lkID0gcC5pZFxuICAgICAgICAgIEFORCBlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLnN0YXR1cyAhPSAnU1RBUlRFRCdcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgcC5pc19hY3RpdmUgPSB0cnVlXG4gICAgICAgIEdST1VQIEJZIHAuaWRcbiAgICAgICAgT1JERVIgQlkgdG90YWwgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPEV4ZWN1dGlvbkNvdW50PihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAxLjIgU3VjY2VzcyByYXRlIG92ZXIgdGltZSBmb3IgYW4gb3JnLiAqL1xuICBhc3luYyBnZXRTdWNjZXNzUmF0ZShvcmdJZDogc3RyaW5nLCBpbnRlcnZhbDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPFRpbWVTZXJpZXNFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06c3VjY2Vzcy1yYXRlOiR7aW50ZXJ2YWx9OiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIERBVEVfVFJVTkMoJHtpbnRlcnZhbH0sIGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgcGVyaW9kLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJyk6OmludCBBUyBzdWNjZWVkZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWxlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0NBTkNFTEVEJyk6OmludCBBUyBjYW5jZWxlZCxcbiAgICAgICAgICBST1VORChDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCcpOjpudW1lcmljXG4gICAgICAgICAgICAvIE5VTExJRihDT1VOVCgqKSwgMCkgKiAxMDAsIDEpOjpmbG9hdCBBUyBzdWNjZXNzX3BjdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnXG4gICAgICAgICAgQU5EIGUuc3RhdHVzIElOICgnU1VDQ0VFREVEJywgJ0ZBSUxFRCcsICdDQU5DRUxFRCcpXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwZXJpb2QgT1JERVIgQlkgcGVyaW9kXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VGltZVNlcmllc0VudHJ5PihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAxLjMgQXZlcmFnZSBkdXJhdGlvbiBwZXIgcGlwZWxpbmUuICovXG4gIGFzeW5jIGdldEF2ZXJhZ2VEdXJhdGlvbihvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPER1cmF0aW9uU3RhdHNbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmF2Zy1kdXJhdGlvbjoke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBwLmlkLCBwLnByb2plY3QsIHAucGlwZWxpbmVfbmFtZSxcbiAgICAgICAgICBBVkcoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBhdmdfbXMsXG4gICAgICAgICAgTUlOKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWluX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tcyxcbiAgICAgICAgICBQRVJDRU5USUxFX0NPTlQoMC45NSkgV0lUSElOIEdST1VQIChPUkRFUiBCWSBlLmR1cmF0aW9uX21zKTo6aW50IEFTIHA5NV9tcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIGV4ZWN1dGlvbnNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyBBTkQgZS5kdXJhdGlvbl9tcyBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgcC5pZCBPUkRFUiBCWSBhdmdfbXMgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPER1cmF0aW9uU3RhdHM+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDEuNSBTdGFnZSBmYWlsdXJlIGhlYXRtYXAg4oCUIHdoaWNoIHN0YWdlcyBmYWlsIG1vc3QuICovXG4gIGFzeW5jIGdldFN0YWdlRmFpbHVyZXMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogUHJvbWlzZTxTdGFnZUZhaWx1cmVbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnN0YWdlLWZhaWx1cmVzOiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuc3RhZ2VfbmFtZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbHVyZXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBST1VORChDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjpudW1lcmljXG4gICAgICAgICAgICAvIE5VTExJRihDT1VOVCgqKSwgMCkgKiAxMDAsIDEpOjpmbG9hdCBBUyBmYWlsdXJlX3BjdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLnN0YWdlX25hbWUgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIGUuc3RhZ2VfbmFtZSBPUkRFUiBCWSBmYWlsdXJlcyBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8U3RhZ2VGYWlsdXJlPihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAxLjYgU3RhZ2UgYm90dGxlbmVja3Mg4oCUIHNsb3dlc3Qgc3RhZ2VzIHBlciBwaXBlbGluZS4gKi9cbiAgYXN5bmMgZ2V0U3RhZ2VCb3R0bGVuZWNrcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPFN0YWdlQm90dGxlbmVja1tdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06c3RhZ2UtYm90dGxlbmVja3M6JHtmcm9tfToke3RvfWAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5waXBlbGluZV9uYW1lLCBlLnN0YWdlX25hbWUsXG4gICAgICAgICAgQVZHKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgYXZnX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLmR1cmF0aW9uX21zIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwLmlkLCBlLnN0YWdlX25hbWUgT1JERVIgQlkgYXZnX21zIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxTdGFnZUJvdHRsZW5lY2s+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDEuNyBBY3Rpb24gZmFpbHVyZSByYXRlIOKAlCB3aGljaCBwbHVnaW4gc3RlcHMgZmFpbCBtb3N0LiAqL1xuICBhc3luYyBnZXRBY3Rpb25GYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPEFjdGlvbkZhaWx1cmVbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmFjdGlvbi1mYWlsdXJlczoke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLmFjdGlvbl9uYW1lLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsdXJlcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHRvdGFsLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIGZhaWx1cmVfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdBQ1RJT04nIEFORCBlLmFjdGlvbl9uYW1lIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBlLmFjdGlvbl9uYW1lIE9SREVSIEJZIGZhaWx1cmVzIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxBY3Rpb25GYWlsdXJlPihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAxLjggRXJyb3IgY2F0ZWdvcml6YXRpb24g4oCUIGdyb3VwIGZhaWx1cmUgbWVzc2FnZXMuICovXG4gIGFzeW5jIGdldEVycm9ycyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIGxpbWl0OiBudW1iZXIgPSAyMCk6IFByb21pc2U8RXJyb3JFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06ZXJyb3JzOiR7ZnJvbX06JHt0b306JHtsaW1pdH1gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIFNVQlNUUklORyhlLmVycm9yX21lc3NhZ2UgRlJPTSAxIEZPUiAyMDApIEFTIGVycm9yX3BhdHRlcm4sXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBvY2N1cnJlbmNlcyxcbiAgICAgICAgICBDT1VOVChESVNUSU5DVCBlLnBpcGVsaW5lX2lkKTo6aW50IEFTIGFmZmVjdGVkX3BpcGVsaW5lcyxcbiAgICAgICAgICBNQVgoZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBsYXN0X3NlZW5cbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5zdGF0dXMgPSAnRkFJTEVEJyBBTkQgZS5lcnJvcl9tZXNzYWdlIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBlcnJvcl9wYXR0ZXJuIE9SREVSIEJZIG9jY3VycmVuY2VzIERFU0NcbiAgICAgICAgTElNSVQgJHtsaW1pdH1cbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxFcnJvckVudHJ5PihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBDYXRlZ29yeSAyOiBQbHVnaW4gSW52ZW50b3J5ICYgQnVpbGRzIOKUgOKUgFxuXG4gIC8qKiAyLjEgUGx1Z2luIHN1bW1hcnkg4oCUIGNvdW50cyBhbmQgYnJlYWtkb3ducy4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luU3VtbWFyeShvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxQbHVnaW5TdW1tYXJ5PiB7XG4gICAgcmV0dXJuIGludmVudG9yeUNhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpwbHVnaW4tc3VtbWFyeWAsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0pOjppbnQgQVMgYWN0aXZlLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgTk9UICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0pOjppbnQgQVMgaW5hY3RpdmUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSAke3NjaGVtYS5wbHVnaW4uYWNjZXNzTW9kaWZpZXJ9ID0gJ3B1YmxpYycpOjppbnQgQVMgcHVibGljLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLmFjY2Vzc01vZGlmaWVyfSA9ICdwcml2YXRlJyk6OmludCBBUyBwcml2YXRlLFxuICAgICAgICAgIENPVU5UKERJU1RJTkNUICR7c2NoZW1hLnBsdWdpbi5uYW1lfSk6OmludCBBUyB1bmlxdWVfbmFtZXNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfVxuICAgICAgYCkpO1xuICAgICAgcmV0dXJuIChkcml6emxlUm93czxQbHVnaW5TdW1tYXJ5Pihyb3dzLnJvd3MpWzBdIHx8IHsgdG90YWw6IDAsIGFjdGl2ZTogMCwgaW5hY3RpdmU6IDAsIHB1YmxpYzogMCwgcHJpdmF0ZTogMCwgdW5pcXVlTmFtZXM6IDAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKiogMi4yIFR5cGUgJiBjb21wdXRlIGRpc3RyaWJ1dGlvbi4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luRGlzdHJpYnV0aW9uKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFR5cGVDb21wdXRlRGlzdHJpYnV0aW9uW10+IHtcbiAgICByZXR1cm4gaW52ZW50b3J5Q2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnBsdWdpbi1kaXN0cmlidXRpb25gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5wbHVnaW5UeXBlfSBBUyBwbHVnaW5fdHlwZSxcbiAgICAgICAgICAke3NjaGVtYS5wbHVnaW4uY29tcHV0ZVR5cGV9IEFTIGNvbXB1dGVfdHlwZSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIGNvdW50XG4gICAgICAgIEZST00gJHtzY2hlbWEucGx1Z2lufVxuICAgICAgICBXSEVSRSAke3NjaGVtYS5wbHVnaW4ub3JnSWR9ID0gJHtvcmdJZH0gQU5EICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0gPSB0cnVlXG4gICAgICAgIEdST1VQIEJZICR7c2NoZW1hLnBsdWdpbi5wbHVnaW5UeXBlfSwgJHtzY2hlbWEucGx1Z2luLmNvbXB1dGVUeXBlfVxuICAgICAgICBPUkRFUiBCWSBjb3VudCBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VHlwZUNvbXB1dGVEaXN0cmlidXRpb24+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDIuMyBWZXJzaW9uIGNvdW50cyBwZXIgcGx1Z2luIG5hbWUuICovXG4gIGFzeW5jIGdldFBsdWdpblZlcnNpb25zKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFZlcnNpb25Db3VudFtdPiB7XG4gICAgcmV0dXJuIGludmVudG9yeUNhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpwbHVnaW4tdmVyc2lvbnNgLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5uYW1lfSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHZlcnNpb25fY291bnQsXG4gICAgICAgICAgTUFYKCR7c2NoZW1hLnBsdWdpbi52ZXJzaW9ufSkgQVMgbGF0ZXN0X3ZlcnNpb24sXG4gICAgICAgICAgYm9vbF9vcigke3NjaGVtYS5wbHVnaW4uaXNEZWZhdWx0fSkgQVMgaGFzX2RlZmF1bHRcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfSBBTkQgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgJHtzY2hlbWEucGx1Z2luLm5hbWV9XG4gICAgICAgIE9SREVSIEJZIHZlcnNpb25fY291bnQgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFZlcnNpb25Db3VudD4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cblxuICAvKiogMi40IEJ1aWxkIHN1Y2Nlc3MgcmF0ZSBvdmVyIHRpbWUuICovXG4gIGFzeW5jIGdldEJ1aWxkU3VjY2Vzc1JhdGUob3JnSWQ6IHN0cmluZywgaW50ZXJ2YWw6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogUHJvbWlzZTxCdWlsZFRpbWVTZXJpZXNFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06YnVpbGQtc3VjY2Vzczoke2ludGVydmFsfToke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBEQVRFX1RSVU5DKCR7aW50ZXJ2YWx9LCBlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIHBlcmlvZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ2NvbXBsZXRlZCcpOjppbnQgQVMgc3VjY2VlZGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnZmFpbGVkJyk6OmludCBBUyBmYWlsZWQsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdjb21wbGV0ZWQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgc3VjY2Vzc19wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIFdIRVJFIGUub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfc291cmNlID0gJ3BsdWdpbi1idWlsZCdcbiAgICAgICAgICBBTkQgZS5zdGF0dXMgSU4gKCdjb21wbGV0ZWQnLCAnZmFpbGVkJylcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIHBlcmlvZCBPUkRFUiBCWSBwZXJpb2RcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxCdWlsZFRpbWVTZXJpZXNFbnRyeT4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cblxuICAvKiogMi41IEJ1aWxkIGR1cmF0aW9uIHBlciBwbHVnaW4uICovXG4gIGFzeW5jIGdldEJ1aWxkRHVyYXRpb24ob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogUHJvbWlzZTxCdWlsZER1cmF0aW9uW10+IHtcbiAgICByZXR1cm4gdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpidWlsZC1kdXJhdGlvbjoke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLmRldGFpbC0+PidwbHVnaW5OYW1lJyBBUyBwbHVnaW5fbmFtZSxcbiAgICAgICAgICBBVkcoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBhdmdfbXMsXG4gICAgICAgICAgTUFYKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWF4X21zLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgYnVpbGRzXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnIEFORCBlLmR1cmF0aW9uX21zIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwbHVnaW5fbmFtZSBPUkRFUiBCWSBhdmdfbXMgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPEJ1aWxkRHVyYXRpb24+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDIuNiBCdWlsZCBmYWlsdXJlcyDigJQgdG9wIGVycm9yIG1lc3NhZ2VzLiAqL1xuICBhc3luYyBnZXRCdWlsZEZhaWx1cmVzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgbGltaXQ6IG51bWJlciA9IDIwKTogUHJvbWlzZTxCdWlsZEZhaWx1cmVbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmJ1aWxkLWZhaWx1cmVzOiR7ZnJvbX06JHt0b306JHtsaW1pdH1gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuZGV0YWlsLT4+J3BsdWdpbk5hbWUnIEFTIHBsdWdpbl9uYW1lLFxuICAgICAgICAgIGUuZXJyb3JfbWVzc2FnZSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIG9jY3VycmVuY2VzLFxuICAgICAgICAgIE1BWChlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGxhc3Rfc2VlblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgV0hFUkUgZS5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF9zb3VyY2UgPSAncGx1Z2luLWJ1aWxkJyBBTkQgZS5zdGF0dXMgPSAnZmFpbGVkJ1xuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgcGx1Z2luX25hbWUsIGUuZXJyb3JfbWVzc2FnZVxuICAgICAgICBPUkRFUiBCWSBvY2N1cnJlbmNlcyBERVNDXG4gICAgICAgIExJTUlUICR7bGltaXR9XG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8QnVpbGRGYWlsdXJlPihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgcmVwb3J0aW5nU2VydmljZSA9IG5ldyBSZXBvcnRpbmdTZXJ2aWNlKCk7XG4iXX0=