@pipeline-builder/pipeline-data 3.4.63 → 3.4.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -21
- package/lib/api/access-control-builder.js +24 -32
- package/lib/api/crud-service.js +44 -50
- package/lib/api/query-builders.d.ts +1 -1
- package/lib/api/query-builders.js +86 -98
- package/lib/api/reporting-service.js +83 -87
- package/lib/core/query-filters.js +3 -5
- package/lib/database/drizzle-schema.d.ts +1 -1
- package/lib/database/drizzle-schema.js +449 -451
- package/lib/database/index.d.ts +5 -5
- package/lib/database/index.js +6 -24
- package/lib/database/migrator.js +10 -46
- package/lib/database/postgres-connection.d.ts +1 -1
- package/lib/database/postgres-connection.js +22 -31
- package/lib/database/retry-strategy.js +4 -8
- package/lib/database/tenancy.d.ts +1 -1
- package/lib/database/tenancy.js +18 -25
- package/lib/index.d.ts +6 -6
- package/lib/index.js +7 -23
- package/package.json +18 -11
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// Copyright 2026 Pipeline Builder Contributors
|
|
3
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const tenancy_1 = require("../database/tenancy");
|
|
11
|
-
const logger = (0, api_core_1.createLogger)('reporting-service');
|
|
3
|
+
import { createCacheService, createLogger, errorMessage } from '@pipeline-builder/api-core';
|
|
4
|
+
import { inArray, sql } from 'drizzle-orm';
|
|
5
|
+
import { drizzleRows } from './crud-service.js';
|
|
6
|
+
import { schema } from '../database/drizzle-schema.js';
|
|
7
|
+
import { withTenantTx, runWithTenantContext } from '../database/tenancy.js';
|
|
8
|
+
const logger = createLogger('reporting-service');
|
|
12
9
|
/**
|
|
13
10
|
* Cache for reporting aggregations. Two tiers:
|
|
14
11
|
* - Inventory queries (plugin summary/distribution/versions): 5 min TTL — changes on plugin CRUD
|
|
15
12
|
* - Execution/build queries with date ranges: 2 min TTL — new events arrive continuously
|
|
16
13
|
*/
|
|
17
|
-
const inventoryCache =
|
|
18
|
-
const timeseriesCache =
|
|
14
|
+
const inventoryCache = createCacheService('report:inv:', parseInt(process.env.CACHE_TTL_REPORT_INVENTORY || '300', 10));
|
|
15
|
+
const timeseriesCache = createCacheService('report:ts:', parseInt(process.env.CACHE_TTL_REPORT_TIMESERIES || '120', 10));
|
|
19
16
|
// ─── Service ────────────────────────────────────────────
|
|
20
17
|
/**
|
|
21
18
|
* Read-only reporting service for pipeline execution and plugin inventory aggregations.
|
|
@@ -25,7 +22,7 @@ const timeseriesCache = (0, api_core_1.createCacheService)('report:ts:', parseIn
|
|
|
25
22
|
* - Inventory queries (plugin summary/distribution/versions): 5 min TTL
|
|
26
23
|
* - Timeseries queries (execution/build metrics with date ranges): 2 min TTL
|
|
27
24
|
*/
|
|
28
|
-
class ReportingService {
|
|
25
|
+
export class ReportingService {
|
|
29
26
|
/** Invalidate all cached reports for an org (call after event ingest). */
|
|
30
27
|
async invalidateOrg(orgId) {
|
|
31
28
|
await Promise.all([
|
|
@@ -56,16 +53,16 @@ class ReportingService {
|
|
|
56
53
|
// in-memory invalidations are unrelated to the tx but still serialized
|
|
57
54
|
// its commit). Cache TTL is 2-5 min so fire-and-forget post-commit is
|
|
58
55
|
// an acceptable trade for tighter lock windows.
|
|
59
|
-
const { inserted, skipped, unregisteredPipelineIds, affectedOrgs } = await
|
|
56
|
+
const { inserted, skipped, unregisteredPipelineIds, affectedOrgs } = await withTenantTx(async (tx) => {
|
|
60
57
|
// Batch-resolve all unique pipeline ids in one query
|
|
61
58
|
const uniqueIds = [...new Set(events.map(e => e.pipelineId))];
|
|
62
59
|
const registryRows = await tx
|
|
63
60
|
.select({
|
|
64
|
-
pipelineId:
|
|
65
|
-
orgId:
|
|
61
|
+
pipelineId: schema.pipelineRegistry.pipelineId,
|
|
62
|
+
orgId: schema.pipelineRegistry.orgId,
|
|
66
63
|
})
|
|
67
|
-
.from(
|
|
68
|
-
.where(
|
|
64
|
+
.from(schema.pipelineRegistry)
|
|
65
|
+
.where(inArray(schema.pipelineRegistry.pipelineId, uniqueIds));
|
|
69
66
|
const idMap = new Map(registryRows.map(r => [r.pipelineId, r]));
|
|
70
67
|
// Build insert batch (skip events whose pipeline isn't registered)
|
|
71
68
|
const rows = [];
|
|
@@ -103,9 +100,9 @@ class ReportingService {
|
|
|
103
100
|
// makes re-delivery idempotent. `returning` gives the REAL inserted set so
|
|
104
101
|
// counts + cache invalidation ignore duplicates.
|
|
105
102
|
const insertedRows = rows.length > 0
|
|
106
|
-
? await tx.insert(
|
|
103
|
+
? await tx.insert(schema.pipelineEvent).values(rows)
|
|
107
104
|
.onConflictDoNothing()
|
|
108
|
-
.returning({ orgId:
|
|
105
|
+
.returning({ orgId: schema.pipelineEvent.orgId })
|
|
109
106
|
: [];
|
|
110
107
|
return {
|
|
111
108
|
inserted: insertedRows.length,
|
|
@@ -128,7 +125,7 @@ class ReportingService {
|
|
|
128
125
|
// short enough that a missed invalidation self-heals.
|
|
129
126
|
if (affectedOrgs.length > 0) {
|
|
130
127
|
void Promise.all(affectedOrgs.map((org) => this.invalidateOrg(org).catch((err) => {
|
|
131
|
-
logger.warn('Reporting cache invalidation failed', { orgId: org, error:
|
|
128
|
+
logger.warn('Reporting cache invalidation failed', { orgId: org, error: errorMessage(err) });
|
|
132
129
|
})));
|
|
133
130
|
}
|
|
134
131
|
return { inserted, skipped, unregisteredPipelineIds };
|
|
@@ -146,8 +143,8 @@ class ReportingService {
|
|
|
146
143
|
const ids = orgIds && orgIds.length > 0 ? orgIds : [orgId];
|
|
147
144
|
const multi = ids.length > 1;
|
|
148
145
|
const pred = multi
|
|
149
|
-
?
|
|
150
|
-
:
|
|
146
|
+
? sql `IN (${sql.join(ids.map((id) => sql `${id}`), sql `, `)})`
|
|
147
|
+
: sql `= ${ids[0]}`;
|
|
151
148
|
return { pred, multi };
|
|
152
149
|
}
|
|
153
150
|
/**
|
|
@@ -159,13 +156,13 @@ class ReportingService {
|
|
|
159
156
|
*/
|
|
160
157
|
runReport(cacheKey, multi, exec) {
|
|
161
158
|
return multi
|
|
162
|
-
?
|
|
159
|
+
? runWithTenantContext({ isSuperAdmin: true }, exec)
|
|
163
160
|
: timeseriesCache.getOrSet(cacheKey, exec);
|
|
164
161
|
}
|
|
165
162
|
/** 1.1 Execution count per pipeline with status breakdown. */
|
|
166
163
|
async getExecutionCount(orgId, orgIds) {
|
|
167
164
|
const { pred, multi } = this.orgScope(orgId, orgIds);
|
|
168
|
-
const exec = () =>
|
|
165
|
+
const exec = () => withTenantTx((tx) => tx.execute(sql `
|
|
169
166
|
SELECT
|
|
170
167
|
p.id, p.project, p.organization, p.pipeline_name,
|
|
171
168
|
COUNT(*)::int AS total,
|
|
@@ -174,19 +171,19 @@ class ReportingService {
|
|
|
174
171
|
COUNT(*) FILTER (WHERE e.status = 'CANCELED')::int AS canceled,
|
|
175
172
|
MIN(e.started_at)::text AS first_execution,
|
|
176
173
|
MAX(e.started_at)::text AS last_execution
|
|
177
|
-
FROM ${
|
|
178
|
-
JOIN ${
|
|
174
|
+
FROM ${schema.pipeline} p
|
|
175
|
+
JOIN ${schema.pipelineEvent} e ON e.pipeline_id = p.id
|
|
179
176
|
AND e.event_type = 'PIPELINE' AND e.status != 'STARTED'
|
|
180
177
|
WHERE p.org_id ${pred} AND p.is_active = true
|
|
181
178
|
GROUP BY p.id
|
|
182
179
|
ORDER BY total DESC
|
|
183
|
-
`).then(r =>
|
|
180
|
+
`).then(r => drizzleRows(r.rows)));
|
|
184
181
|
return this.runReport(`${orgId}:exec-count`, multi, exec);
|
|
185
182
|
}
|
|
186
183
|
/** 1.2 Success rate over time for an org. */
|
|
187
184
|
async getSuccessRate(orgId, interval, from, to, orgIds) {
|
|
188
185
|
const { pred, multi } = this.orgScope(orgId, orgIds);
|
|
189
|
-
const exec = () =>
|
|
186
|
+
const exec = () => withTenantTx((tx) => tx.execute(sql `
|
|
190
187
|
SELECT
|
|
191
188
|
DATE_TRUNC(${interval}, e.started_at)::text AS period,
|
|
192
189
|
COUNT(*) FILTER (WHERE e.status = 'SUCCEEDED')::int AS succeeded,
|
|
@@ -194,19 +191,19 @@ class ReportingService {
|
|
|
194
191
|
COUNT(*) FILTER (WHERE e.status = 'CANCELED')::int AS canceled,
|
|
195
192
|
ROUND(COUNT(*) FILTER (WHERE e.status = 'SUCCEEDED')::numeric
|
|
196
193
|
/ NULLIF(COUNT(*), 0) * 100, 1)::float AS success_pct
|
|
197
|
-
FROM ${
|
|
198
|
-
JOIN ${
|
|
194
|
+
FROM ${schema.pipelineEvent} e
|
|
195
|
+
JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
|
|
199
196
|
WHERE p.org_id ${pred} AND e.event_type = 'PIPELINE'
|
|
200
197
|
AND e.status IN ('SUCCEEDED', 'FAILED', 'CANCELED')
|
|
201
198
|
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
202
199
|
GROUP BY period ORDER BY period
|
|
203
|
-
`).then(r =>
|
|
200
|
+
`).then(r => drizzleRows(r.rows)));
|
|
204
201
|
return this.runReport(`${orgId}:success-rate:${interval}:${from}:${to}`, multi, exec);
|
|
205
202
|
}
|
|
206
203
|
/** 1.3 Average duration per pipeline. */
|
|
207
204
|
async getAverageDuration(orgId, from, to, orgIds) {
|
|
208
205
|
const { pred, multi } = this.orgScope(orgId, orgIds);
|
|
209
|
-
const exec = () =>
|
|
206
|
+
const exec = () => withTenantTx((tx) => tx.execute(sql `
|
|
210
207
|
SELECT
|
|
211
208
|
p.id, p.project, p.pipeline_name,
|
|
212
209
|
AVG(e.duration_ms)::int AS avg_ms,
|
|
@@ -214,120 +211,120 @@ class ReportingService {
|
|
|
214
211
|
MAX(e.duration_ms)::int AS max_ms,
|
|
215
212
|
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY e.duration_ms)::int AS p95_ms,
|
|
216
213
|
COUNT(*)::int AS executions
|
|
217
|
-
FROM ${
|
|
218
|
-
JOIN ${
|
|
214
|
+
FROM ${schema.pipelineEvent} e
|
|
215
|
+
JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
|
|
219
216
|
WHERE p.org_id ${pred} AND e.event_type = 'PIPELINE' AND e.duration_ms IS NOT NULL
|
|
220
217
|
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
221
218
|
GROUP BY p.id ORDER BY avg_ms DESC
|
|
222
|
-
`).then(r =>
|
|
219
|
+
`).then(r => drizzleRows(r.rows)));
|
|
223
220
|
return this.runReport(`${orgId}:avg-duration:${from}:${to}`, multi, exec);
|
|
224
221
|
}
|
|
225
222
|
/** 1.5 Stage failure heatmap — which stages fail most. */
|
|
226
223
|
async getStageFailures(orgId, from, to) {
|
|
227
|
-
return timeseriesCache.getOrSet(`${orgId}:stage-failures:${from}:${to}`, () =>
|
|
224
|
+
return timeseriesCache.getOrSet(`${orgId}:stage-failures:${from}:${to}`, () => withTenantTx((tx) => tx.execute(sql `
|
|
228
225
|
SELECT
|
|
229
226
|
e.stage_name,
|
|
230
227
|
COUNT(*) FILTER (WHERE e.status = 'FAILED')::int AS failures,
|
|
231
228
|
COUNT(*)::int AS total,
|
|
232
229
|
ROUND(COUNT(*) FILTER (WHERE e.status = 'FAILED')::numeric
|
|
233
230
|
/ NULLIF(COUNT(*), 0) * 100, 1)::float AS failure_pct
|
|
234
|
-
FROM ${
|
|
235
|
-
JOIN ${
|
|
231
|
+
FROM ${schema.pipelineEvent} e
|
|
232
|
+
JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
|
|
236
233
|
WHERE p.org_id = ${orgId} AND e.event_type = 'STAGE' AND e.stage_name IS NOT NULL
|
|
237
234
|
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
238
235
|
GROUP BY e.stage_name ORDER BY failures DESC
|
|
239
|
-
`).then(r =>
|
|
236
|
+
`).then(r => drizzleRows(r.rows))));
|
|
240
237
|
}
|
|
241
238
|
/** 1.6 Stage bottlenecks — slowest stages per pipeline. */
|
|
242
239
|
async getStageBottlenecks(orgId, from, to) {
|
|
243
|
-
return timeseriesCache.getOrSet(`${orgId}:stage-bottlenecks:${from}:${to}`, () =>
|
|
240
|
+
return timeseriesCache.getOrSet(`${orgId}:stage-bottlenecks:${from}:${to}`, () => withTenantTx((tx) => tx.execute(sql `
|
|
244
241
|
SELECT
|
|
245
242
|
p.id, p.pipeline_name, e.stage_name,
|
|
246
243
|
AVG(e.duration_ms)::int AS avg_ms,
|
|
247
244
|
MAX(e.duration_ms)::int AS max_ms
|
|
248
|
-
FROM ${
|
|
249
|
-
JOIN ${
|
|
245
|
+
FROM ${schema.pipelineEvent} e
|
|
246
|
+
JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
|
|
250
247
|
WHERE p.org_id = ${orgId} AND e.event_type = 'STAGE' AND e.duration_ms IS NOT NULL
|
|
251
248
|
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
252
249
|
GROUP BY p.id, e.stage_name ORDER BY avg_ms DESC
|
|
253
|
-
`).then(r =>
|
|
250
|
+
`).then(r => drizzleRows(r.rows))));
|
|
254
251
|
}
|
|
255
252
|
/** 1.7 Action failure rate — which plugin steps fail most. */
|
|
256
253
|
async getActionFailures(orgId, from, to) {
|
|
257
|
-
return timeseriesCache.getOrSet(`${orgId}:action-failures:${from}:${to}`, () =>
|
|
254
|
+
return timeseriesCache.getOrSet(`${orgId}:action-failures:${from}:${to}`, () => withTenantTx((tx) => tx.execute(sql `
|
|
258
255
|
SELECT
|
|
259
256
|
e.action_name,
|
|
260
257
|
COUNT(*) FILTER (WHERE e.status = 'FAILED')::int AS failures,
|
|
261
258
|
COUNT(*)::int AS total,
|
|
262
259
|
ROUND(COUNT(*) FILTER (WHERE e.status = 'FAILED')::numeric
|
|
263
260
|
/ NULLIF(COUNT(*), 0) * 100, 1)::float AS failure_pct
|
|
264
|
-
FROM ${
|
|
265
|
-
JOIN ${
|
|
261
|
+
FROM ${schema.pipelineEvent} e
|
|
262
|
+
JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
|
|
266
263
|
WHERE p.org_id = ${orgId} AND e.event_type = 'ACTION' AND e.action_name IS NOT NULL
|
|
267
264
|
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
268
265
|
GROUP BY e.action_name ORDER BY failures DESC
|
|
269
|
-
`).then(r =>
|
|
266
|
+
`).then(r => drizzleRows(r.rows))));
|
|
270
267
|
}
|
|
271
268
|
/** 1.8 Error categorization — group failure messages. */
|
|
272
269
|
async getErrors(orgId, from, to, limit = 20) {
|
|
273
|
-
return timeseriesCache.getOrSet(`${orgId}:errors:${from}:${to}:${limit}`, () =>
|
|
270
|
+
return timeseriesCache.getOrSet(`${orgId}:errors:${from}:${to}:${limit}`, () => withTenantTx((tx) => tx.execute(sql `
|
|
274
271
|
SELECT
|
|
275
272
|
SUBSTRING(e.error_message FROM 1 FOR 200) AS error_pattern,
|
|
276
273
|
COUNT(*)::int AS occurrences,
|
|
277
274
|
COUNT(DISTINCT e.pipeline_id)::int AS affected_pipelines,
|
|
278
275
|
MAX(e.started_at)::text AS last_seen
|
|
279
|
-
FROM ${
|
|
280
|
-
JOIN ${
|
|
276
|
+
FROM ${schema.pipelineEvent} e
|
|
277
|
+
JOIN ${schema.pipeline} p ON p.id = e.pipeline_id
|
|
281
278
|
WHERE p.org_id = ${orgId} AND e.status = 'FAILED' AND e.error_message IS NOT NULL
|
|
282
279
|
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
283
280
|
GROUP BY error_pattern ORDER BY occurrences DESC
|
|
284
281
|
LIMIT ${limit}
|
|
285
|
-
`).then(r =>
|
|
282
|
+
`).then(r => drizzleRows(r.rows))));
|
|
286
283
|
}
|
|
287
284
|
// ── Category 2: Plugin Inventory & Builds ──
|
|
288
285
|
/** 2.1 Plugin summary — counts and breakdowns. */
|
|
289
286
|
async getPluginSummary(orgId) {
|
|
290
287
|
return inventoryCache.getOrSet(`${orgId}:plugin-summary`, async () => {
|
|
291
|
-
const rows = await
|
|
288
|
+
const rows = await withTenantTx((tx) => tx.execute(sql `
|
|
292
289
|
SELECT
|
|
293
290
|
COUNT(*)::int AS total,
|
|
294
|
-
COUNT(*) FILTER (WHERE ${
|
|
295
|
-
COUNT(*) FILTER (WHERE NOT ${
|
|
296
|
-
COUNT(*) FILTER (WHERE ${
|
|
297
|
-
COUNT(*) FILTER (WHERE ${
|
|
298
|
-
COUNT(DISTINCT ${
|
|
299
|
-
FROM ${
|
|
300
|
-
WHERE ${
|
|
291
|
+
COUNT(*) FILTER (WHERE ${schema.plugin.isActive})::int AS active,
|
|
292
|
+
COUNT(*) FILTER (WHERE NOT ${schema.plugin.isActive})::int AS inactive,
|
|
293
|
+
COUNT(*) FILTER (WHERE ${schema.plugin.accessModifier} = 'public')::int AS public,
|
|
294
|
+
COUNT(*) FILTER (WHERE ${schema.plugin.accessModifier} = 'private')::int AS private,
|
|
295
|
+
COUNT(DISTINCT ${schema.plugin.name})::int AS unique_names
|
|
296
|
+
FROM ${schema.plugin}
|
|
297
|
+
WHERE ${schema.plugin.orgId} = ${orgId}
|
|
301
298
|
`));
|
|
302
|
-
return (
|
|
299
|
+
return (drizzleRows(rows.rows)[0] || { total: 0, active: 0, inactive: 0, public: 0, private: 0, uniqueNames: 0 });
|
|
303
300
|
});
|
|
304
301
|
}
|
|
305
302
|
/** 2.2 Type & compute distribution. */
|
|
306
303
|
async getPluginDistribution(orgId) {
|
|
307
|
-
return inventoryCache.getOrSet(`${orgId}:plugin-distribution`, () =>
|
|
304
|
+
return inventoryCache.getOrSet(`${orgId}:plugin-distribution`, () => withTenantTx((tx) => tx.execute(sql `
|
|
308
305
|
SELECT
|
|
309
|
-
${
|
|
310
|
-
${
|
|
306
|
+
${schema.plugin.pluginType} AS plugin_type,
|
|
307
|
+
${schema.plugin.computeType} AS compute_type,
|
|
311
308
|
COUNT(*)::int AS count
|
|
312
|
-
FROM ${
|
|
313
|
-
WHERE ${
|
|
314
|
-
GROUP BY ${
|
|
309
|
+
FROM ${schema.plugin}
|
|
310
|
+
WHERE ${schema.plugin.orgId} = ${orgId} AND ${schema.plugin.isActive} = true
|
|
311
|
+
GROUP BY ${schema.plugin.pluginType}, ${schema.plugin.computeType}
|
|
315
312
|
ORDER BY count DESC
|
|
316
|
-
`).then(r =>
|
|
313
|
+
`).then(r => drizzleRows(r.rows))));
|
|
317
314
|
}
|
|
318
315
|
/** 2.3 Version counts per plugin name. */
|
|
319
316
|
async getPluginVersions(orgId) {
|
|
320
|
-
return inventoryCache.getOrSet(`${orgId}:plugin-versions`, () =>
|
|
317
|
+
return inventoryCache.getOrSet(`${orgId}:plugin-versions`, () => withTenantTx((tx) => tx.execute(sql `
|
|
321
318
|
SELECT
|
|
322
|
-
${
|
|
319
|
+
${schema.plugin.name},
|
|
323
320
|
COUNT(*)::int AS version_count,
|
|
324
|
-
MAX(${
|
|
325
|
-
bool_or(${
|
|
326
|
-
FROM ${
|
|
327
|
-
WHERE ${
|
|
328
|
-
GROUP BY ${
|
|
321
|
+
MAX(${schema.plugin.version}) AS latest_version,
|
|
322
|
+
bool_or(${schema.plugin.isDefault}) AS has_default
|
|
323
|
+
FROM ${schema.plugin}
|
|
324
|
+
WHERE ${schema.plugin.orgId} = ${orgId} AND ${schema.plugin.isActive} = true
|
|
325
|
+
GROUP BY ${schema.plugin.name}
|
|
329
326
|
ORDER BY version_count DESC
|
|
330
|
-
`).then(r =>
|
|
327
|
+
`).then(r => drizzleRows(r.rows))));
|
|
331
328
|
}
|
|
332
329
|
/**
|
|
333
330
|
* 2.4 Build success rate over time.
|
|
@@ -344,51 +341,50 @@ class ReportingService {
|
|
|
344
341
|
* than silently producing zero rows here. See findings N71.
|
|
345
342
|
*/
|
|
346
343
|
async getBuildSuccessRate(orgId, interval, from, to) {
|
|
347
|
-
return timeseriesCache.getOrSet(`${orgId}:build-success:${interval}:${from}:${to}`, () =>
|
|
344
|
+
return timeseriesCache.getOrSet(`${orgId}:build-success:${interval}:${from}:${to}`, () => withTenantTx((tx) => tx.execute(sql `
|
|
348
345
|
SELECT
|
|
349
346
|
DATE_TRUNC(${interval}, e.started_at)::text AS period,
|
|
350
347
|
COUNT(*) FILTER (WHERE e.status = 'completed')::int AS succeeded,
|
|
351
348
|
COUNT(*) FILTER (WHERE e.status = 'failed')::int AS failed,
|
|
352
349
|
ROUND(COUNT(*) FILTER (WHERE e.status = 'completed')::numeric
|
|
353
350
|
/ NULLIF(COUNT(*), 0) * 100, 1)::float AS success_pct
|
|
354
|
-
FROM ${
|
|
351
|
+
FROM ${schema.pipelineEvent} e
|
|
355
352
|
WHERE e.org_id = ${orgId} AND e.event_source = 'plugin-build'
|
|
356
353
|
AND e.status IN ('completed', 'failed')
|
|
357
354
|
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
358
355
|
GROUP BY period ORDER BY period
|
|
359
|
-
`).then(r =>
|
|
356
|
+
`).then(r => drizzleRows(r.rows))));
|
|
360
357
|
}
|
|
361
358
|
/** 2.5 Build duration per plugin. */
|
|
362
359
|
async getBuildDuration(orgId, from, to) {
|
|
363
|
-
return timeseriesCache.getOrSet(`${orgId}:build-duration:${from}:${to}`, () =>
|
|
360
|
+
return timeseriesCache.getOrSet(`${orgId}:build-duration:${from}:${to}`, () => withTenantTx((tx) => tx.execute(sql `
|
|
364
361
|
SELECT
|
|
365
362
|
e.detail->>'pluginName' AS plugin_name,
|
|
366
363
|
AVG(e.duration_ms)::int AS avg_ms,
|
|
367
364
|
MAX(e.duration_ms)::int AS max_ms,
|
|
368
365
|
COUNT(*)::int AS builds
|
|
369
|
-
FROM ${
|
|
366
|
+
FROM ${schema.pipelineEvent} e
|
|
370
367
|
WHERE e.org_id = ${orgId} AND e.event_source = 'plugin-build' AND e.duration_ms IS NOT NULL
|
|
371
368
|
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
372
369
|
GROUP BY plugin_name ORDER BY avg_ms DESC
|
|
373
|
-
`).then(r =>
|
|
370
|
+
`).then(r => drizzleRows(r.rows))));
|
|
374
371
|
}
|
|
375
372
|
/** 2.6 Build failures — top error messages. */
|
|
376
373
|
async getBuildFailures(orgId, from, to, limit = 20) {
|
|
377
|
-
return timeseriesCache.getOrSet(`${orgId}:build-failures:${from}:${to}:${limit}`, () =>
|
|
374
|
+
return timeseriesCache.getOrSet(`${orgId}:build-failures:${from}:${to}:${limit}`, () => withTenantTx((tx) => tx.execute(sql `
|
|
378
375
|
SELECT
|
|
379
376
|
e.detail->>'pluginName' AS plugin_name,
|
|
380
377
|
e.error_message,
|
|
381
378
|
COUNT(*)::int AS occurrences,
|
|
382
379
|
MAX(e.started_at)::text AS last_seen
|
|
383
|
-
FROM ${
|
|
380
|
+
FROM ${schema.pipelineEvent} e
|
|
384
381
|
WHERE e.org_id = ${orgId} AND e.event_source = 'plugin-build' AND e.status = 'failed'
|
|
385
382
|
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
386
383
|
GROUP BY plugin_name, e.error_message
|
|
387
384
|
ORDER BY occurrences DESC
|
|
388
385
|
LIMIT ${limit}
|
|
389
|
-
`).then(r =>
|
|
386
|
+
`).then(r => drizzleRows(r.rows))));
|
|
390
387
|
}
|
|
391
388
|
}
|
|
392
|
-
|
|
393
|
-
exports.reportingService = new ReportingService();
|
|
394
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0aW5nLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JlcG9ydGluZy1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDOzs7QUFFdEMseURBQTRGO0FBQzVGLDZDQUEyQztBQUMzQyxpREFBNkM7QUFDN0MsK0RBQW9EO0FBQ3BELGlEQUF5RTtBQUV6RSxNQUFNLE1BQU0sR0FBRyxJQUFBLHVCQUFZLEVBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUVqRDs7OztHQUlHO0FBQ0gsTUFBTSxjQUFjLEdBQUcsSUFBQSw2QkFBa0IsRUFBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsMEJBQTBCLElBQUksS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDeEgsTUFBTSxlQUFlLEdBQUcsSUFBQSw2QkFBa0IsRUFBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLElBQUksS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFzSXpILDJEQUEyRDtBQUUzRDs7Ozs7OztHQU9HO0FBQ0gsTUFBYSxnQkFBZ0I7SUFFM0IsMEVBQTBFO0lBQzFFLEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBYTtRQUMvQixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDaEIsY0FBYyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUM7WUFDOUMsZUFBZSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUM7U0FDaEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFxQjtRQUN0Qyx1RUFBdUU7UUFDdkUsc0VBQXNFO1FBQ3RFLDJFQUEyRTtRQUMzRSxzRUFBc0U7UUFDdEUscUVBQXFFO1FBQ3JFLHFFQUFx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QUssbUJBQW1CLElBQUksSUFBSSxFQUFFLElBQUksS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQ3JGLElBQUEsc0JBQVksRUFBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFBLGlCQUFHLEVBQUE7Ozs7OztlQU0xQix1QkFBTSxDQUFDLGFBQWE7MkJBQ1IsS0FBSztnQ0FDQSxJQUFJLHFDQUFxQyxFQUFFOzs7Z0JBRzNELEtBQUs7T0FDZCxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBQSwwQkFBVyxFQUFlLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQ2pELENBQUM7SUFDSixDQUFDO0NBQ0Y7QUEzWkQsNENBMlpDO0FBRVksUUFBQSxnQkFBZ0IsR0FBRyxJQUFJLGdCQUFnQixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgY3JlYXRlQ2FjaGVTZXJ2aWNlLCBjcmVhdGVMb2dnZXIsIGVycm9yTWVzc2FnZSB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGluQXJyYXksIHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IGRyaXp6bGVSb3dzIH0gZnJvbSAnLi9jcnVkLXNlcnZpY2UnO1xuaW1wb3J0IHsgc2NoZW1hIH0gZnJvbSAnLi4vZGF0YWJhc2UvZHJpenpsZS1zY2hlbWEnO1xuaW1wb3J0IHsgd2l0aFRlbmFudFR4LCBydW5XaXRoVGVuYW50Q29udGV4dCB9IGZyb20gJy4uL2RhdGFiYXNlL3RlbmFuY3knO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3JlcG9ydGluZy1zZXJ2aWNlJyk7XG5cbi8qKlxuICogQ2FjaGUgZm9yIHJlcG9ydGluZyBhZ2dyZWdhdGlvbnMuIFR3byB0aWVyczpcbiAqIC0gSW52ZW50b3J5IHF1ZXJpZXMgKHBsdWdpbiBzdW1tYXJ5L2Rpc3RyaWJ1dGlvbi92ZXJzaW9ucyk6IDUgbWluIFRUTCDigJQgY2hhbmdlcyBvbiBwbHVnaW4gQ1JVRFxuICogLSBFeGVjdXRpb24vYnVpbGQgcXVlcmllcyB3aXRoIGRhdGUgcmFuZ2VzOiAyIG1pbiBUVEwg4oCUIG5ldyBldmVudHMgYXJyaXZlIGNvbnRpbnVvdXNseVxuICovXG5jb25zdCBpbnZlbnRvcnlDYWNoZSA9IGNyZWF0ZUNhY2hlU2VydmljZSgncmVwb3J0OmludjonLCBwYXJzZUludChwcm9jZXNzLmVudi5DQUNIRV9UVExfUkVQT1JUX0lOVkVOVE9SWSB8fCAnMzAwJywgMTApKTtcbmNvbnN0IHRpbWVzZXJpZXNDYWNoZSA9IGNyZWF0ZUNhY2hlU2VydmljZSgncmVwb3J0OnRzOicsIHBhcnNlSW50KHByb2Nlc3MuZW52LkNBQ0hFX1RUTF9SRVBPUlRfVElNRVNFUklFUyB8fCAnMTIwJywgMTApKTtcblxuLy8g4pSA4pSA4pSAIFR5cGVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5pbnRlcmZhY2UgRXhlY3V0aW9uQ291bnQge1xuICBpZDogc3RyaW5nO1xuICBwcm9qZWN0OiBzdHJpbmc7XG4gIG9yZ2FuaXphdGlvbjogc3RyaW5nO1xuICBwaXBlbGluZU5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHRvdGFsOiBudW1iZXI7XG4gIHN1Y2NlZWRlZDogbnVtYmVyO1xuICBmYWlsZWQ6IG51bWJlcjtcbiAgY2FuY2VsZWQ6IG51bWJlcjtcbiAgZmlyc3RFeGVjdXRpb246IHN0cmluZyB8IG51bGw7XG4gIGxhc3RFeGVjdXRpb246IHN0cmluZyB8IG51bGw7XG59XG5cbmludGVyZmFjZSBUaW1lU2VyaWVzRW50cnkge1xuICBwZXJpb2Q6IHN0cmluZztcbiAgc3VjY2VlZGVkOiBudW1iZXI7XG4gIGZhaWxlZDogbnVtYmVyO1xuICBjYW5jZWxlZDogbnVtYmVyO1xuICBzdWNjZXNzUGN0OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBEdXJhdGlvblN0YXRzIHtcbiAgaWQ6IHN0cmluZztcbiAgcHJvamVjdDogc3RyaW5nO1xuICBwaXBlbGluZU5hbWU6IHN0cmluZyB8IG51bGw7XG4gIGF2Z01zOiBudW1iZXI7XG4gIG1pbk1zOiBudW1iZXI7XG4gIG1heE1zOiBudW1iZXI7XG4gIHA5NU1zOiBudW1iZXI7XG4gIGV4ZWN1dGlvbnM6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFN0YWdlRmFpbHVyZSB7XG4gIHN0YWdlTmFtZTogc3RyaW5nO1xuICBmYWlsdXJlczogbnVtYmVyO1xuICB0b3RhbDogbnVtYmVyO1xuICBmYWlsdXJlUGN0OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBTdGFnZUJvdHRsZW5lY2sge1xuICBpZDogc3RyaW5nO1xuICBwaXBlbGluZU5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHN0YWdlTmFtZTogc3RyaW5nO1xuICBhdmdNczogbnVtYmVyO1xuICBtYXhNczogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQWN0aW9uRmFpbHVyZSB7XG4gIGFjdGlvbk5hbWU6IHN0cmluZztcbiAgZmFpbHVyZXM6IG51bWJlcjtcbiAgdG90YWw6IG51bWJlcjtcbiAgZmFpbHVyZVBjdDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgRXJyb3JFbnRyeSB7XG4gIGVycm9yUGF0dGVybjogc3RyaW5nO1xuICBvY2N1cnJlbmNlczogbnVtYmVyO1xuICBhZmZlY3RlZFBpcGVsaW5lczogbnVtYmVyO1xuICBsYXN0U2Vlbjogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUGx1Z2luU3VtbWFyeSB7XG4gIHRvdGFsOiBudW1iZXI7XG4gIGFjdGl2ZTogbnVtYmVyO1xuICBpbmFjdGl2ZTogbnVtYmVyO1xuICBwdWJsaWM6IG51bWJlcjtcbiAgcHJpdmF0ZTogbnVtYmVyO1xuICB1bmlxdWVOYW1lczogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgVHlwZUNvbXB1dGVEaXN0cmlidXRpb24ge1xuICBwbHVnaW5UeXBlOiBzdHJpbmc7XG4gIGNvbXB1dGVUeXBlOiBzdHJpbmc7XG4gIGNvdW50OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBWZXJzaW9uQ291bnQge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZlcnNpb25Db3VudDogbnVtYmVyO1xuICBsYXRlc3RWZXJzaW9uOiBzdHJpbmc7XG4gIGhhc0RlZmF1bHQ6IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBCdWlsZFRpbWVTZXJpZXNFbnRyeSB7XG4gIHBlcmlvZDogc3RyaW5nO1xuICBzdWNjZWVkZWQ6IG51bWJlcjtcbiAgZmFpbGVkOiBudW1iZXI7XG4gIHN1Y2Nlc3NQY3Q6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIEJ1aWxkRHVyYXRpb24ge1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIGF2Z01zOiBudW1iZXI7XG4gIG1heE1zOiBudW1iZXI7XG4gIGJ1aWxkczogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQnVpbGRGYWlsdXJlIHtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBlcnJvck1lc3NhZ2U6IHN0cmluZztcbiAgb2NjdXJyZW5jZXM6IG51bWJlcjtcbiAgbGFzdFNlZW46IHN0cmluZztcbn1cblxuLyoqIEV2ZW50IHBheWxvYWQgYWNjZXB0ZWQgYnkgYFJlcG9ydGluZ1NlcnZpY2UuaW5nZXN0RXZlbnRzYC4gTWlycm9ycyB0aGUgcm91dGUncyBab2Qgc2hhcGUuICovXG5leHBvcnQgaW50ZXJmYWNlIEluZ2VzdEV2ZW50IHtcbiAgLyoqIFN0YWJsZSBwaXBlbGluZSBpZCB0aGUgZXZlbnRzIExhbWJkYSByZWFkIGZyb20gdGhlIGBQSVBFTElORV9FVkVOVF9JRGBcbiAgICogIHRhZyAoPSB0aGUgcGxhdGZvcm0gcGlwZWxpbmVJZCkuIFRoZSByZWdpc3RyeSBqb2luIGtleS4gKi9cbiAgcGlwZWxpbmVJZDogc3RyaW5nO1xuICBldmVudFNvdXJjZTogJ2NvZGVwaXBlbGluZScgfCAnY29kZWJ1aWxkJyB8ICdwbHVnaW4tYnVpbGQnO1xuICBldmVudFR5cGU6ICdQSVBFTElORScgfCAnU1RBR0UnIHwgJ0FDVElPTicgfCAnQlVJTEQnO1xuICBzdGF0dXM6IHN0cmluZztcbiAgZXhlY3V0aW9uSWQ/OiBzdHJpbmc7XG4gIHN0YWdlTmFtZT86IHN0cmluZztcbiAgYWN0aW9uTmFtZT86IHN0cmluZztcbiAgLyoqIEh1bWFuLXJlYWRhYmxlIGZhaWx1cmUgcmVhc29uIChBY3Rpb24gZXZlbnRzKS4gKi9cbiAgZXJyb3JNZXNzYWdlPzogc3RyaW5nO1xuICBzdGFydGVkQXQ/OiBzdHJpbmc7XG4gIGNvbXBsZXRlZEF0Pzogc3RyaW5nO1xuICBkdXJhdGlvbk1zPzogbnVtYmVyO1xuICBkZXRhaWw/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuLyoqIENvdW50cyArIHRoZSAocG9zc2libHkgdHJ1bmNhdGVkKSBsaXN0IG9mIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZHMgdGhlIGNhbGxlciBjYW4gbG9nLiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmdlc3RSZXN1bHQge1xuICBpbnNlcnRlZDogbnVtYmVyO1xuICBza2lwcGVkOiBudW1iZXI7XG4gIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzOiBzdHJpbmdbXTtcbn1cblxuLy8g4pSA4pSA4pSAIFNlcnZpY2Ug4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8qKlxuICogUmVhZC1vbmx5IHJlcG9ydGluZyBzZXJ2aWNlIGZvciBwaXBlbGluZSBleGVjdXRpb24gYW5kIHBsdWdpbiBpbnZlbnRvcnkgYWdncmVnYXRpb25zLlxuICogRG9lcyBub3QgZXh0ZW5kIENydWRTZXJ2aWNlIOKAlCByZXBvcnRzIGFyZSBhZ2dyZWdhdGUgcXVlcmllcywgbm90IGVudGl0eSBDUlVELlxuICpcbiAqIEFsbCBxdWVyaWVzIGFyZSBjYWNoZWQgaW4tbWVtb3J5IHRvIGF2b2lkIHJlcGVhdGVkIGV4cGVuc2l2ZSBTUUwgYWdncmVnYXRpb25zOlxuICogLSBJbnZlbnRvcnkgcXVlcmllcyAocGx1Z2luIHN1bW1hcnkvZGlzdHJpYnV0aW9uL3ZlcnNpb25zKTogNSBtaW4gVFRMXG4gKiAtIFRpbWVzZXJpZXMgcXVlcmllcyAoZXhlY3V0aW9uL2J1aWxkIG1ldHJpY3Mgd2l0aCBkYXRlIHJhbmdlcyk6IDIgbWluIFRUTFxuICovXG5leHBvcnQgY2xhc3MgUmVwb3J0aW5nU2VydmljZSB7XG5cbiAgLyoqIEludmFsaWRhdGUgYWxsIGNhY2hlZCByZXBvcnRzIGZvciBhbiBvcmcgKGNhbGwgYWZ0ZXIgZXZlbnQgaW5nZXN0KS4gKi9cbiAgYXN5bmMgaW52YWxpZGF0ZU9yZyhvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgaW52ZW50b3J5Q2FjaGUuaW52YWxpZGF0ZVBhdHRlcm4oYCR7b3JnSWR9OipgKSxcbiAgICAgIHRpbWVzZXJpZXNDYWNoZS5pbnZhbGlkYXRlUGF0dGVybihgJHtvcmdJZH06KmApLFxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgaW5jb21pbmcgZXZlbnRzIGFnYWluc3QgdGhlIHBpcGVsaW5lIHJlZ2lzdHJ5LCBiYXRjaC1pbnNlcnQgdGhlXG4gICAqIG1hdGNoZWQgb25lcywgYW5kIGludmFsaWRhdGUgcmVwb3J0aW5nIGNhY2hlcyBmb3IgYWZmZWN0ZWQgb3Jncy5cbiAgICogRXZlbnRzIGZvciB1bnJlZ2lzdGVyZWQgcGlwZWxpbmUgQVJOcyBhcmUgZHJvcHBlZCAoYW5kIGxvZ2dlZCBhdCBXQVJOXG4gICAqIHdpdGggc2FtcGxlIEFSTnMgc28gYW4gb3BlcmF0b3IgY2FuIHNlZSB3aGVuIEV2ZW50QnJpZGdlIGlzIGRlbGl2ZXJpbmdcbiAgICogZXZlbnRzIGZvciBwaXBlbGluZXMgdGhhdCBoYXZlbid0IGNhbGxlZCBQT1NUIC9waXBlbGluZXMvcmVnaXN0cnkgeWV0KS5cbiAgICpcbiAgICogUmV0dXJucyBjb3VudHMgKyBhIHNhbXBsZSBvZiB1bnJlZ2lzdGVyZWQgQVJOcyBmb3Igb2JzZXJ2YWJpbGl0eS5cbiAgICovXG4gIGFzeW5jIGluZ2VzdEV2ZW50cyhldmVudHM6IEluZ2VzdEV2ZW50W10pOiBQcm9taXNlPEluZ2VzdFJlc3VsdD4ge1xuICAgIC8vIE11bHRpLW9yZyBiYXRjaCBpbnNlcnQ6IHRoZSBjYWxsZXIgcmVzb2x2ZXMgdG8gbXVsdGlwbGUgb3JncyB2aWEgdGhlXG4gICAgLy8gcGlwZWxpbmUtcmVnaXN0cnkgbG9va3VwIGJlbG93LCBzbyB0aGUgcm91dGUgbGF5ZXIgTVVTVCBlc3RhYmxpc2ggYVxuICAgIC8vIGBydW5XaXRoVGVuYW50Q29udGV4dCh7IGlzU3VwZXJBZG1pbjogdHJ1ZSB9LCAuLi4pYCBzY29wZSBiZWZvcmUgY2FsbGluZ1xuICAgIC8vIHRoaXMgbWV0aG9kLiBVbmRlciBGT1JDRSdkIFJMUywgYSBzaW5nbGUgdHggd2l0aCBgYXBwLm9yZ19pZCA9IDxvbmVcbiAgICAvLyBvcmc+YCBjb3VsZCBvbmx5IHdyaXRlIGV2ZW50cyBmb3IgdGhhdCBvcmc7IGJ5cGFzcyB2aWEgc3lzYWRtaW4gaXNcbiAgICAvLyB0aGUgcmlnaHQgZ2F0ZSBmb3IgdGhpcyBzZXJ2ZXItaW50ZXJuYWwgY3Jvc3MtdGVuYW50IGVuZHBvaW50LiBTZWVcbiAgICAvLyBhcGkvcmVwb3J0aW5nL3NyYy9yb3V0ZXMvZXZlbnQtaW5nZXN0LnRzIGZvciB0aGUgd3JhcHBlci5cbiAgICAvLyBSdW4gaW5zZXJ0IGluc2lkZSB0aGUgdHgsIGJ1dCBDT0xMRUNUIGFmZmVjdGVkIG9yZ3MgYW5kIGludmFsaWRhdGVcbiAgICAvLyBjYWNoZXMgQUZURVIgdGhlIHR4IHJlc29sdmVzLiBLZWVwaW5nIGludmFsaWRhdGlvbiBpbnNpZGUgdGhlIHR4IGhlbGRcbiAgICAvLyB0aGUgcGcgbG9ja3Mgb3BlbiBmb3IgdGhlIGR1cmF0aW9uIG9mIHRoZSBjYWNoZSByb3VuZC10cmlwcyAoUmVkaXMgb3JcbiAgICAvLyBpbi1tZW1vcnkgaW52YWxpZGF0aW9ucyBhcmUgdW5yZWxhdGVkIHRvIHRoZSB0eCBidXQgc3RpbGwgc2VyaWFsaXplZFxuICAgIC8vIGl0cyBjb21taXQpLiBDYWNoZSBUVEwgaXMgMi01IG1pbiBzbyBmaXJlLWFuZC1mb3JnZXQgcG9zdC1jb21taXQgaXNcbiAgICAvLyBhbiBhY2NlcHRhYmxlIHRyYWRlIGZvciB0aWdodGVyIGxvY2sgd2luZG93cy5cbiAgICBjb25zdCB7IGluc2VydGVkLCBza2lwcGVkLCB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcywgYWZmZWN0ZWRPcmdzIH0gPSBhd2FpdCB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB7XG4gICAgICAvLyBCYXRjaC1yZXNvbHZlIGFsbCB1bmlxdWUgcGlwZWxpbmUgaWRzIGluIG9uZSBxdWVyeVxuICAgICAgY29uc3QgdW5pcXVlSWRzID0gWy4uLm5ldyBTZXQoZXZlbnRzLm1hcChlID0+IGUucGlwZWxpbmVJZCkpXTtcbiAgICAgIGNvbnN0IHJlZ2lzdHJ5Um93cyA9IGF3YWl0IHR4XG4gICAgICAgIC5zZWxlY3Qoe1xuICAgICAgICAgIHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5LnBpcGVsaW5lSWQsXG4gICAgICAgICAgb3JnSWQ6IHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5Lm9yZ0lkLFxuICAgICAgICB9KVxuICAgICAgICAuZnJvbShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeSlcbiAgICAgICAgLndoZXJlKGluQXJyYXkoc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkucGlwZWxpbmVJZCwgdW5pcXVlSWRzKSk7XG5cbiAgICAgIGNvbnN0IGlkTWFwID0gbmV3IE1hcChyZWdpc3RyeVJvd3MubWFwKHIgPT4gW3IucGlwZWxpbmVJZCwgcl0pKTtcblxuICAgICAgLy8gQnVpbGQgaW5zZXJ0IGJhdGNoIChza2lwIGV2ZW50cyB3aG9zZSBwaXBlbGluZSBpc24ndCByZWdpc3RlcmVkKVxuICAgICAgY29uc3Qgcm93czogQXJyYXk8dHlwZW9mIHNjaGVtYS5waXBlbGluZUV2ZW50LiRpbmZlckluc2VydD4gPSBbXTtcbiAgICAgIGxldCBza2lwcGVkTG9jYWwgPSAwO1xuICAgICAgY29uc3QgdW5yZWdpc3RlcmVkTG9jYWw6IHN0cmluZ1tdID0gW107XG5cbiAgICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICAgIGNvbnN0IHJlZ2lzdHJ5ID0gaWRNYXAuZ2V0KGV2ZW50LnBpcGVsaW5lSWQpO1xuICAgICAgICBpZiAoIXJlZ2lzdHJ5KSB7XG4gICAgICAgICAgc2tpcHBlZExvY2FsKys7XG4gICAgICAgICAgdW5yZWdpc3RlcmVkTG9jYWwucHVzaChldmVudC5waXBlbGluZUlkKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJvd3MucHVzaCh7XG4gICAgICAgICAgLy8gcmVnaXN0cnkucGlwZWxpbmVJZCA9PT0gZXZlbnQucGlwZWxpbmVJZDsgdXNlIHRoZSByZWdpc3RyeSdzIHNvIHRoZVxuICAgICAgICAgIC8vIEZLIGlzIGFsd2F5cyBhIHJvdyB0aGF0IGV4aXN0cywgYW5kIHB1bGwgb3JnSWQgZnJvbSB0aGUgcmVnaXN0cnkgZm9yXG4gICAgICAgICAgLy8gdGVuYW5jeSAobmV2ZXIgdHJ1c3QgdGhlIGNhbGxlcidzIGNsYWltZWQgb3JnKS5cbiAgICAgICAgICBwaXBlbGluZUlkOiByZWdpc3RyeS5waXBlbGluZUlkLFxuICAgICAgICAgIG9yZ0lkOiByZWdpc3RyeS5vcmdJZCxcbiAgICAgICAgICBldmVudFNvdXJjZTogZXZlbnQuZXZlbnRTb3VyY2UsXG4gICAgICAgICAgZXZlbnRUeXBlOiBldmVudC5ldmVudFR5cGUsXG4gICAgICAgICAgc3RhdHVzOiBldmVudC5zdGF0dXMsXG4gICAgICAgICAgZXhlY3V0aW9uSWQ6IGV2ZW50LmV4ZWN1dGlvbklkLFxuICAgICAgICAgIHN0YWdlTmFtZTogZXZlbnQuc3RhZ2VOYW1lLFxuICAgICAgICAgIGFjdGlvbk5hbWU6IGV2ZW50LmFjdGlvbk5hbWUsXG4gICAgICAgICAgZXJyb3JNZXNzYWdlOiBldmVudC5lcnJvck1lc3NhZ2UsXG4gICAgICAgICAgc3RhcnRlZEF0OiBldmVudC5zdGFydGVkQXQgPyBuZXcgRGF0ZShldmVudC5zdGFydGVkQXQpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGNvbXBsZXRlZEF0OiBldmVudC5jb21wbGV0ZWRBdCA/IG5ldyBEYXRlKGV2ZW50LmNvbXBsZXRlZEF0KSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICBkdXJhdGlvbk1zOiBldmVudC5kdXJhdGlvbk1zLFxuICAgICAgICAgIGRldGFpbDogZXZlbnQuZGV0YWlsLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gU1FTIGlzIGF0LWxlYXN0LW9uY2UsIHNvIEV2ZW50QnJpZGdlIGNhbiBkZWxpdmVyIHRoZSBzYW1lIHN0YXRlLWNoYW5nZVxuICAgICAgLy8gdHdpY2UuIGBvbkNvbmZsaWN0RG9Ob3RoaW5nYCArIHRoZSBwYXJ0aWFsIHVuaXF1ZSBpbmRleCBvblxuICAgICAgLy8gKHBpcGVsaW5lX2lkLCBleGVjdXRpb25faWQsIGV2ZW50X3R5cGUsIHN0YXR1cywgc3RhZ2VfbmFtZSwgYWN0aW9uX25hbWUpXG4gICAgICAvLyBtYWtlcyByZS1kZWxpdmVyeSBpZGVtcG90ZW50LiBgcmV0dXJuaW5nYCBnaXZlcyB0aGUgUkVBTCBpbnNlcnRlZCBzZXQgc29cbiAgICAgIC8vIGNvdW50cyArIGNhY2hlIGludmFsaWRhdGlvbiBpZ25vcmUgZHVwbGljYXRlcy5cbiAgICAgIGNvbnN0IGluc2VydGVkUm93cyA9IHJvd3MubGVuZ3RoID4gMFxuICAgICAgICA/IGF3YWl0IHR4Lmluc2VydChzY2hlbWEucGlwZWxpbmVFdmVudCkudmFsdWVzKHJvd3MpXG4gICAgICAgICAgLm9uQ29uZmxpY3REb05vdGhpbmcoKVxuICAgICAgICAgIC5yZXR1cm5pbmcoeyBvcmdJZDogc2NoZW1hLnBpcGVsaW5lRXZlbnQub3JnSWQgfSlcbiAgICAgICAgOiBbXTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaW5zZXJ0ZWQ6IGluc2VydGVkUm93cy5sZW5ndGgsXG4gICAgICAgIHNraXBwZWQ6IHNraXBwZWRMb2NhbCxcbiAgICAgICAgdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHM6IHVucmVnaXN0ZXJlZExvY2FsLFxuICAgICAgICBhZmZlY3RlZE9yZ3M6IFsuLi5uZXcgU2V0KGluc2VydGVkUm93cy5tYXAociA9PiByLm9yZ0lkKSldLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIFN1cmZhY2UgdGhlIHNpbGVudCBza2lwOiBhbiB1bnJlZ2lzdGVyZWQgcGlwZWxpbmUgaWQgdXN1YWxseSBtZWFucyB0aGVcbiAgICAvLyBwaXBlbGluZSBoYXNuJ3QgY2FsbGVkIFBPU1QgL3BpcGVsaW5lcy9yZWdpc3RyeSB5ZXQgKG9yIGl0c1xuICAgIC8vIFBJUEVMSU5FX0VWRU5UX0lEIHRhZyBpcyBtaXNzaW5nL3VucmVhZGFibGUgYnkgdGhlIExhbWJkYSkuIExvZ2dpbmcgaXRcbiAgICAvLyBtYWtlcyBhIGJyb2tlbiBqb2luIHZpc2libGUgaW5zdGVhZCBvZiBsb29raW5nIGxpa2UgXCJubyBhY3Rpdml0eVwiLlxuICAgIGlmICh1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcy5sZW5ndGggPiAwKSB7XG4gICAgICBsb2dnZXIud2FybignUGlwZWxpbmUgZXZlbnRzIHNraXBwZWQ6IHBpcGVsaW5lIGlkIG5vdCBmb3VuZCBpbiByZWdpc3RyeScsIHtcbiAgICAgICAgY291bnQ6IHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLmxlbmd0aCxcbiAgICAgICAgc2FtcGxlOiB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcy5zbGljZSgwLCAzKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIFBvc3QtY29tbWl0IGNhY2hlIGludmFsaWRhdGlvbi4gRmlyZS1hbmQtZm9yZ2V0IHdpdGggbG9nZ2luZyDigJQgVFRMIGlzXG4gICAgLy8gc2hvcnQgZW5vdWdoIHRoYXQgYSBtaXNzZWQgaW52YWxpZGF0aW9uIHNlbGYtaGVhbHMuXG4gICAgaWYgKGFmZmVjdGVkT3Jncy5sZW5ndGggPiAwKSB7XG4gICAgICB2b2lkIFByb21pc2UuYWxsKGFmZmVjdGVkT3Jncy5tYXAoKG9yZykgPT5cbiAgICAgICAgdGhpcy5pbnZhbGlkYXRlT3JnKG9yZykuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgIGxvZ2dlci53YXJuKCdSZXBvcnRpbmcgY2FjaGUgaW52YWxpZGF0aW9uIGZhaWxlZCcsIHsgb3JnSWQ6IG9yZywgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgICAgICB9KSxcbiAgICAgICkpO1xuICAgIH1cblxuICAgIHJldHVybiB7IGluc2VydGVkLCBza2lwcGVkLCB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkcyB9O1xuICB9XG5cbiAgLy8g4pSA4pSAIENhdGVnb3J5IDE6IFBpcGVsaW5lIEV4ZWN1dGlvbiAmIFBlcmZvcm1hbmNlIOKUgOKUgFxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgb3JnLXNjb3BlIHByZWRpY2F0ZSBmb3IgYSByZXBvcnQgcXVlcnkuIFdpdGggYG9yZ0lkc2AgKHRoZVxuICAgKiBvcmcg4oaSIHRlYW0gcm9sbHVwIOKAlCBhIHBhcmVudCdzIGBbc2VsZiwgLi4uZGVzY2VuZGFudHNdYCkgaXQgYmVjb21lcyBhblxuICAgKiBgSU4gKC4uLilgIG92ZXIgdGhlIHN1YnRyZWU7IG90aGVyd2lzZSB0aGUgc2luZ2xlLW9yZyBgPSAkb3JnYC4gUmV0dXJucyBhXG4gICAqIGBtdWx0aWAgZmxhZyBzbyBjYWxsZXJzIGNhbiBydW4gbXVsdGktb3JnIHJlYWRzIHVuZGVyIHN5c2FkbWluIGNvbnRleHRcbiAgICogKHRoZSBzdWJ0cmVlIHNwYW5zIG9yZ3Mgb3V0c2lkZSB0aGUgcmVxdWVzdCdzIFJMUyBzY29wZSkgYW5kIHNhbHQgdGhlXG4gICAqIGNhY2hlIGtleS5cbiAgICovXG4gIHByaXZhdGUgb3JnU2NvcGUob3JnSWQ6IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pIHtcbiAgICBjb25zdCBpZHMgPSBvcmdJZHMgJiYgb3JnSWRzLmxlbmd0aCA+IDAgPyBvcmdJZHMgOiBbb3JnSWRdO1xuICAgIGNvbnN0IG11bHRpID0gaWRzLmxlbmd0aCA+IDE7XG4gICAgY29uc3QgcHJlZCA9IG11bHRpXG4gICAgICA/IHNxbGBJTiAoJHtzcWwuam9pbihpZHMubWFwKChpZCkgPT4gc3FsYCR7aWR9YCksIHNxbGAsIGApfSlgXG4gICAgICA6IHNxbGA9ICR7aWRzWzBdfWA7XG4gICAgcmV0dXJuIHsgcHJlZCwgbXVsdGkgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYSByZXBvcnQgcmVhZC4gU2luZ2xlLW9yZyByZWFkcyB1c2UgdGhlIHBlci1vcmcgY2FjaGUgKGludmFsaWRhdGVkIG9uXG4gICAqIHRoYXQgb3JnJ3MgZXZlbnQgaW5nZXN0KS4gUm9sbHVwIChtdWx0aS1vcmcpIHJlYWRzICoqYnlwYXNzIHRoZSBjYWNoZSoqIGFuZFxuICAgKiBydW4gdW5kZXIgc3lzYWRtaW4gY29udGV4dDogdGhleSdyZSBhZG1pbi1vbmx5IGFuZCBsb3dlci1mcmVxdWVuY3ksIGFuZCBhXG4gICAqIGNoaWxkIG9yZydzIGV2ZW50IGluZ2VzdCBjYW4ndCBpbnZhbGlkYXRlIGEgcGFyZW50J3Mgcm9sbHVwIGVudHJ5IChyZXBvcnRpbmdcbiAgICogaGFzIG5vIG9yZyB0cmVlKSwgc28gY2FjaGluZyB0aGVtIHdvdWxkIHNlcnZlIHN0YWxlIGFnZ3JlZ2F0ZXMuIEFsd2F5cyBmcmVzaC5cbiAgICovXG4gIHByaXZhdGUgcnVuUmVwb3J0PFQ+KGNhY2hlS2V5OiBzdHJpbmcsIG11bHRpOiBib29sZWFuLCBleGVjOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgcmV0dXJuIG11bHRpXG4gICAgICA/IHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIGV4ZWMpXG4gICAgICA6IHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChjYWNoZUtleSwgZXhlYyk7XG4gIH1cblxuICAvKiogMS4xIEV4ZWN1dGlvbiBjb3VudCBwZXIgcGlwZWxpbmUgd2l0aCBzdGF0dXMgYnJlYWtkb3duLiAqL1xuICBhc3luYyBnZXRFeGVjdXRpb25Db3VudChvcmdJZDogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8RXhlY3V0aW9uQ291bnRbXT4ge1xuICAgIGNvbnN0IHsgcHJlZCwgbXVsdGkgfSA9IHRoaXMub3JnU2NvcGUob3JnSWQsIG9yZ0lkcyk7XG4gICAgY29uc3QgZXhlYyA9ICgpID0+IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBwLmlkLCBwLnByb2plY3QsIHAub3JnYW5pemF0aW9uLCBwLnBpcGVsaW5lX25hbWUsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCcpOjppbnQgQVMgc3VjY2VlZGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdDQU5DRUxFRCcpOjppbnQgQVMgY2FuY2VsZWQsXG4gICAgICAgICAgTUlOKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgZmlyc3RfZXhlY3V0aW9uLFxuICAgICAgICAgIE1BWChlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGxhc3RfZXhlY3V0aW9uXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmV9IHBcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlIE9OIGUucGlwZWxpbmVfaWQgPSBwLmlkXG4gICAgICAgICAgQU5EIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScgQU5EIGUuc3RhdHVzICE9ICdTVEFSVEVEJ1xuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBwLmlzX2FjdGl2ZSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgcC5pZFxuICAgICAgICBPUkRFUiBCWSB0b3RhbCBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8RXhlY3V0aW9uQ291bnQ+KHIucm93cykpKTtcbiAgICByZXR1cm4gdGhpcy5ydW5SZXBvcnQoYCR7b3JnSWR9OmV4ZWMtY291bnRgLCBtdWx0aSwgZXhlYyk7XG4gIH1cblxuICAvKiogMS4yIFN1Y2Nlc3MgcmF0ZSBvdmVyIHRpbWUgZm9yIGFuIG9yZy4gKi9cbiAgYXN5bmMgZ2V0U3VjY2Vzc1JhdGUob3JnSWQ6IHN0cmluZywgaW50ZXJ2YWw6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8VGltZVNlcmllc0VudHJ5W10+IHtcbiAgICBjb25zdCB7IHByZWQsIG11bHRpIH0gPSB0aGlzLm9yZ1Njb3BlKG9yZ0lkLCBvcmdJZHMpO1xuICAgIGNvbnN0IGV4ZWMgPSAoKSA9PiB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgREFURV9UUlVOQygke2ludGVydmFsfSwgZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBwZXJpb2QsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnQ0FOQ0VMRUQnKTo6aW50IEFTIGNhbmNlbGVkLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIHN1Y2Nlc3NfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORSdcbiAgICAgICAgICBBTkQgZS5zdGF0dXMgSU4gKCdTVUNDRUVERUQnLCAnRkFJTEVEJywgJ0NBTkNFTEVEJylcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIHBlcmlvZCBPUkRFUiBCWSBwZXJpb2RcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxUaW1lU2VyaWVzRW50cnk+KHIucm93cykpKTtcbiAgICByZXR1cm4gdGhpcy5ydW5SZXBvcnQoYCR7b3JnSWR9OnN1Y2Nlc3MtcmF0ZToke2ludGVydmFsfToke2Zyb219OiR7dG99YCwgbXVsdGksIGV4ZWMpO1xuICB9XG5cbiAgLyoqIDEuMyBBdmVyYWdlIGR1cmF0aW9uIHBlciBwaXBlbGluZS4gKi9cbiAgYXN5bmMgZ2V0QXZlcmFnZUR1cmF0aW9uKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgb3JnSWRzPzogc3RyaW5nW10pOiBQcm9taXNlPER1cmF0aW9uU3RhdHNbXT4ge1xuICAgIGNvbnN0IHsgcHJlZCwgbXVsdGkgfSA9IHRoaXMub3JnU2NvcGUob3JnSWQsIG9yZ0lkcyk7XG4gICAgY29uc3QgZXhlYyA9ICgpID0+IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBwLmlkLCBwLnByb2plY3QsIHAucGlwZWxpbmVfbmFtZSxcbiAgICAgICAgICBBVkcoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBhdmdfbXMsXG4gICAgICAgICAgTUlOKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWluX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tcyxcbiAgICAgICAgICBQRVJDRU5USUxFX0NPTlQoMC45NSkgV0lUSElOIEdST1VQIChPUkRFUiBCWSBlLmR1cmF0aW9uX21zKTo6aW50IEFTIHA5NV9tcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIGV4ZWN1dGlvbnNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyBBTkQgZS5kdXJhdGlvbl9tcyBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgcC5pZCBPUkRFUiBCWSBhdmdfbXMgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPER1cmF0aW9uU3RhdHM+KHIucm93cykpKTtcbiAgICByZXR1cm4gdGhpcy5ydW5SZXBvcnQoYCR7b3JnSWR9OmF2Zy1kdXJhdGlvbjoke2Zyb219OiR7dG99YCwgbXVsdGksIGV4ZWMpO1xuICB9XG5cbiAgLyoqIDEuNSBTdGFnZSBmYWlsdXJlIGhlYXRtYXAg4oCUIHdoaWNoIHN0YWdlcyBmYWlsIG1vc3QuICovXG4gIGFzeW5jIGdldFN0YWdlRmFpbHVyZXMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogUHJvbWlzZTxTdGFnZUZhaWx1cmVbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnN0YWdlLWZhaWx1cmVzOiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuc3RhZ2VfbmFtZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjppbnQgQVMgZmFpbHVyZXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBST1VORChDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0ZBSUxFRCcpOjpudW1lcmljXG4gICAgICAgICAgICAvIE5VTExJRihDT1VOVCgqKSwgMCkgKiAxMDAsIDEpOjpmbG9hdCBBUyBmYWlsdXJlX3BjdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLnN0YWdlX25hbWUgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIGUuc3RhZ2VfbmFtZSBPUkRFUiBCWSBmYWlsdXJlcyBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8U3RhZ2VGYWlsdXJlPihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAxLjYgU3RhZ2UgYm90dGxlbmVja3Mg4oCUIHNsb3dlc3Qgc3RhZ2VzIHBlciBwaXBlbGluZS4gKi9cbiAgYXN5bmMgZ2V0U3RhZ2VCb3R0bGVuZWNrcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPFN0YWdlQm90dGxlbmVja1tdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06c3RhZ2UtYm90dGxlbmVja3M6JHtmcm9tfToke3RvfWAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgcC5pZCwgcC5waXBlbGluZV9uYW1lLCBlLnN0YWdlX25hbWUsXG4gICAgICAgICAgQVZHKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgYXZnX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnU1RBR0UnIEFORCBlLmR1cmF0aW9uX21zIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwLmlkLCBlLnN0YWdlX25hbWUgT1JERVIgQlkgYXZnX21zIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxTdGFnZUJvdHRsZW5lY2s+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDEuNyBBY3Rpb24gZmFpbHVyZSByYXRlIOKAlCB3aGljaCBwbHVnaW4gc3RlcHMgZmFpbCBtb3N0LiAqL1xuICBhc3luYyBnZXRBY3Rpb25GYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPEFjdGlvbkZhaWx1cmVbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmFjdGlvbi1mYWlsdXJlczoke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLmFjdGlvbl9uYW1lLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsdXJlcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHRvdGFsLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIGZhaWx1cmVfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdBQ1RJT04nIEFORCBlLmFjdGlvbl9uYW1lIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBlLmFjdGlvbl9uYW1lIE9SREVSIEJZIGZhaWx1cmVzIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxBY3Rpb25GYWlsdXJlPihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAxLjggRXJyb3IgY2F0ZWdvcml6YXRpb24g4oCUIGdyb3VwIGZhaWx1cmUgbWVzc2FnZXMuICovXG4gIGFzeW5jIGdldEVycm9ycyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIGxpbWl0OiBudW1iZXIgPSAyMCk6IFByb21pc2U8RXJyb3JFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06ZXJyb3JzOiR7ZnJvbX06JHt0b306JHtsaW1pdH1gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIFNVQlNUUklORyhlLmVycm9yX21lc3NhZ2UgRlJPTSAxIEZPUiAyMDApIEFTIGVycm9yX3BhdHRlcm4sXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBvY2N1cnJlbmNlcyxcbiAgICAgICAgICBDT1VOVChESVNUSU5DVCBlLnBpcGVsaW5lX2lkKTo6aW50IEFTIGFmZmVjdGVkX3BpcGVsaW5lcyxcbiAgICAgICAgICBNQVgoZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBsYXN0X3NlZW5cbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5zdGF0dXMgPSAnRkFJTEVEJyBBTkQgZS5lcnJvcl9tZXNzYWdlIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBlcnJvcl9wYXR0ZXJuIE9SREVSIEJZIG9jY3VycmVuY2VzIERFU0NcbiAgICAgICAgTElNSVQgJHtsaW1pdH1cbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxFcnJvckVudHJ5PihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBDYXRlZ29yeSAyOiBQbHVnaW4gSW52ZW50b3J5ICYgQnVpbGRzIOKUgOKUgFxuXG4gIC8qKiAyLjEgUGx1Z2luIHN1bW1hcnkg4oCUIGNvdW50cyBhbmQgYnJlYWtkb3ducy4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luU3VtbWFyeShvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxQbHVnaW5TdW1tYXJ5PiB7XG4gICAgcmV0dXJuIGludmVudG9yeUNhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpwbHVnaW4tc3VtbWFyeWAsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0pOjppbnQgQVMgYWN0aXZlLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgTk9UICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0pOjppbnQgQVMgaW5hY3RpdmUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSAke3NjaGVtYS5wbHVnaW4uYWNjZXNzTW9kaWZpZXJ9ID0gJ3B1YmxpYycpOjppbnQgQVMgcHVibGljLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLmFjY2Vzc01vZGlmaWVyfSA9ICdwcml2YXRlJyk6OmludCBBUyBwcml2YXRlLFxuICAgICAgICAgIENPVU5UKERJU1RJTkNUICR7c2NoZW1hLnBsdWdpbi5uYW1lfSk6OmludCBBUyB1bmlxdWVfbmFtZXNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfVxuICAgICAgYCkpO1xuICAgICAgcmV0dXJuIChkcml6emxlUm93czxQbHVnaW5TdW1tYXJ5Pihyb3dzLnJvd3MpWzBdIHx8IHsgdG90YWw6IDAsIGFjdGl2ZTogMCwgaW5hY3RpdmU6IDAsIHB1YmxpYzogMCwgcHJpdmF0ZTogMCwgdW5pcXVlTmFtZXM6IDAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKiogMi4yIFR5cGUgJiBjb21wdXRlIGRpc3RyaWJ1dGlvbi4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luRGlzdHJpYnV0aW9uKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFR5cGVDb21wdXRlRGlzdHJpYnV0aW9uW10+IHtcbiAgICByZXR1cm4gaW52ZW50b3J5Q2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnBsdWdpbi1kaXN0cmlidXRpb25gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5wbHVnaW5UeXBlfSBBUyBwbHVnaW5fdHlwZSxcbiAgICAgICAgICAke3NjaGVtYS5wbHVnaW4uY29tcHV0ZVR5cGV9IEFTIGNvbXB1dGVfdHlwZSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIGNvdW50XG4gICAgICAgIEZST00gJHtzY2hlbWEucGx1Z2lufVxuICAgICAgICBXSEVSRSAke3NjaGVtYS5wbHVnaW4ub3JnSWR9ID0gJHtvcmdJZH0gQU5EICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0gPSB0cnVlXG4gICAgICAgIEdST1VQIEJZICR7c2NoZW1hLnBsdWdpbi5wbHVnaW5UeXBlfSwgJHtzY2hlbWEucGx1Z2luLmNvbXB1dGVUeXBlfVxuICAgICAgICBPUkRFUiBCWSBjb3VudCBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VHlwZUNvbXB1dGVEaXN0cmlidXRpb24+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDIuMyBWZXJzaW9uIGNvdW50cyBwZXIgcGx1Z2luIG5hbWUuICovXG4gIGFzeW5jIGdldFBsdWdpblZlcnNpb25zKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFZlcnNpb25Db3VudFtdPiB7XG4gICAgcmV0dXJuIGludmVudG9yeUNhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpwbHVnaW4tdmVyc2lvbnNgLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5uYW1lfSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHZlcnNpb25fY291bnQsXG4gICAgICAgICAgTUFYKCR7c2NoZW1hLnBsdWdpbi52ZXJzaW9ufSkgQVMgbGF0ZXN0X3ZlcnNpb24sXG4gICAgICAgICAgYm9vbF9vcigke3NjaGVtYS5wbHVnaW4uaXNEZWZhdWx0fSkgQVMgaGFzX2RlZmF1bHRcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfSBBTkQgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgJHtzY2hlbWEucGx1Z2luLm5hbWV9XG4gICAgICAgIE9SREVSIEJZIHZlcnNpb25fY291bnQgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFZlcnNpb25Db3VudD4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogMi40IEJ1aWxkIHN1Y2Nlc3MgcmF0ZSBvdmVyIHRpbWUuXG4gICAqXG4gICAqIFNUQVRVUyBDQVNJTkcgTk9URTogVGhpcyBxdWVyeSBmaWx0ZXJzIGJ5IGBldmVudF9zb3VyY2UgPSAncGx1Z2luLWJ1aWxkJ2BcbiAgICogYW5kIHVzZXMgbG93ZXJjYXNlIHN0YXR1cyB2YWx1ZXMgKGAnY29tcGxldGVkJ2AsIGAnZmFpbGVkJ2ApLCB3aGlsZVxuICAgKiBgZ2V0U3VjY2Vzc1JhdGVgICgxLjIpIGZpbHRlcnMgYnkgYGV2ZW50X3R5cGUgPSAnUElQRUxJTkUnYCB3aXRoXG4gICAqIHVwcGVyY2FzZSBBV1Mtc3R5bGUgc3RhdHVzZXMgKGAnU1VDQ0VFREVEJ2AsIGAnRkFJTEVEJ2AsIGAnQ0FOQ0VMRUQnYCkuXG4gICAqIFRoZSBjYXNpbmcgZHJpZnQgaXMgaW50ZW50aW9uYWwgYW5kIHRyYWNrcyB0aGUgcHJvZHVjZXI6XG4gICAqICAgLSBgcGx1Z2luLWJ1aWxkYCBldmVudHMgY29tZSBmcm9tIG91ciBvd24gYnVpbGQgcGlwZWxpbmUgKGxvd2VyY2FzZSlcbiAgICogICAtIGBQSVBFTElORWAgZXZlbnRzIGNvbWUgZnJvbSBBV1MgQ29kZVBpcGVsaW5lICh1cHBlcmNhc2UpXG4gICAqIFRoZSBpbmdlc3QgWm9kIHNjaGVtYSBhdCBhcGkvcmVwb3J0aW5nL3NyYy9yb3V0ZXMvZXZlbnQtaW5nZXN0LnRzXG4gICAqIFNIT1VMRCBlbnVtIHRoZXNlIHBlci1ldmVudFNvdXJjZSBzbyB3ZSBjYXRjaCBkcmlmdCBhdCBpbmdlc3QgcmF0aGVyXG4gICAqIHRoYW4gc2lsZW50bHkgcHJvZHVjaW5nIHplcm8gcm93cyBoZXJlLiBTZWUgZmluZGluZ3MgTjcxLlxuICAgKi9cbiAgYXN5bmMgZ2V0QnVpbGRTdWNjZXNzUmF0ZShvcmdJZDogc3RyaW5nLCBpbnRlcnZhbDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPEJ1aWxkVGltZVNlcmllc0VudHJ5W10+IHtcbiAgICByZXR1cm4gdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpidWlsZC1zdWNjZXNzOiR7aW50ZXJ2YWx9OiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIERBVEVfVFJVTkMoJHtpbnRlcnZhbH0sIGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgcGVyaW9kLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnY29tcGxldGVkJyk6OmludCBBUyBzdWNjZWVkZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdmYWlsZWQnKTo6aW50IEFTIGZhaWxlZCxcbiAgICAgICAgICBST1VORChDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ2NvbXBsZXRlZCcpOjpudW1lcmljXG4gICAgICAgICAgICAvIE5VTExJRihDT1VOVCgqKSwgMCkgKiAxMDAsIDEpOjpmbG9hdCBBUyBzdWNjZXNzX3BjdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgV0hFUkUgZS5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF9zb3VyY2UgPSAncGx1Z2luLWJ1aWxkJ1xuICAgICAgICAgIEFORCBlLnN0YXR1cyBJTiAoJ2NvbXBsZXRlZCcsICdmYWlsZWQnKVxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgcGVyaW9kIE9SREVSIEJZIHBlcmlvZFxuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPEJ1aWxkVGltZVNlcmllc0VudHJ5PihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAyLjUgQnVpbGQgZHVyYXRpb24gcGVyIHBsdWdpbi4gKi9cbiAgYXN5bmMgZ2V0QnVpbGREdXJhdGlvbihvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPEJ1aWxkRHVyYXRpb25bXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmJ1aWxkLWR1cmF0aW9uOiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuZGV0YWlsLT4+J3BsdWdpbk5hbWUnIEFTIHBsdWdpbl9uYW1lLFxuICAgICAgICAgIEFWRyhlLmR1cmF0aW9uX21zKTo6aW50IEFTIGF2Z19tcyxcbiAgICAgICAgICBNQVgoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBtYXhfbXMsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBidWlsZHNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIFdIRVJFIGUub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfc291cmNlID0gJ3BsdWdpbi1idWlsZCcgQU5EIGUuZHVyYXRpb25fbXMgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIHBsdWdpbl9uYW1lIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8QnVpbGREdXJhdGlvbj4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cblxuICAvKiogMi42IEJ1aWxkIGZhaWx1cmVzIOKAlCB0b3AgZXJyb3IgbWVzc2FnZXMuICovXG4gIGFzeW5jIGdldEJ1aWxkRmFpbHVyZXMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBsaW1pdDogbnVtYmVyID0gMjApOiBQcm9taXNlPEJ1aWxkRmFpbHVyZVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06YnVpbGQtZmFpbHVyZXM6JHtmcm9tfToke3RvfToke2xpbWl0fWAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5kZXRhaWwtPj4ncGx1Z2luTmFtZScgQVMgcGx1Z2luX25hbWUsXG4gICAgICAgICAgZS5lcnJvcl9tZXNzYWdlLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgb2NjdXJyZW5jZXMsXG4gICAgICAgICAgTUFYKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgbGFzdF9zZWVuXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnIEFORCBlLnN0YXR1cyA9ICdmYWlsZWQnXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwbHVnaW5fbmFtZSwgZS5lcnJvcl9tZXNzYWdlXG4gICAgICAgIE9SREVSIEJZIG9jY3VycmVuY2VzIERFU0NcbiAgICAgICAgTElNSVQgJHtsaW1pdH1cbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxCdWlsZEZhaWx1cmU+KHIucm93cykpKSxcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCByZXBvcnRpbmdTZXJ2aWNlID0gbmV3IFJlcG9ydGluZ1NlcnZpY2UoKTtcbiJdfQ==
|
|
389
|
+
export const reportingService = new ReportingService();
|
|
390
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0aW5nLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JlcG9ydGluZy1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM1RixPQUFPLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMzQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUU1RSxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUVqRDs7OztHQUlHO0FBQ0gsTUFBTSxjQUFjLEdBQUcsa0JBQWtCLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixJQUFJLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hILE1BQU0sZUFBZSxHQUFHLGtCQUFrQixDQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsSUFBSSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQXNJekgsMkRBQTJEO0FBRTNEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLE9BQU8sZ0JBQWdCO0lBRTNCLDBFQUEwRTtJQUMxRSxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQWE7UUFDL0IsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDO1lBQ2hCLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEtBQUssSUFBSSxDQUFDO1lBQzlDLGVBQWUsQ0FBQyxpQkFB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OztlQU0xQixNQUFNLENBQUMsYUFBYTsyQkFDUixLQUFLO2dDQUNBLElBQUkscUNBQXFDLEVBQUU7OztnQkFHM0QsS0FBSztPQUNkLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQWUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FDakQsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQUVELE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBjcmVhdGVDYWNoZVNlcnZpY2UsIGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgaW5BcnJheSwgc3FsIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgZHJpenpsZVJvd3MgfSBmcm9tICcuL2NydWQtc2VydmljZS5qcyc7XG5pbXBvcnQgeyBzY2hlbWEgfSBmcm9tICcuLi9kYXRhYmFzZS9kcml6emxlLXNjaGVtYS5qcyc7XG5pbXBvcnQgeyB3aXRoVGVuYW50VHgsIHJ1bldpdGhUZW5hbnRDb250ZXh0IH0gZnJvbSAnLi4vZGF0YWJhc2UvdGVuYW5jeS5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigncmVwb3J0aW5nLXNlcnZpY2UnKTtcblxuLyoqXG4gKiBDYWNoZSBmb3IgcmVwb3J0aW5nIGFnZ3JlZ2F0aW9ucy4gVHdvIHRpZXJzOlxuICogLSBJbnZlbnRvcnkgcXVlcmllcyAocGx1Z2luIHN1bW1hcnkvZGlzdHJpYnV0aW9uL3ZlcnNpb25zKTogNSBtaW4gVFRMIOKAlCBjaGFuZ2VzIG9uIHBsdWdpbiBDUlVEXG4gKiAtIEV4ZWN1dGlvbi9idWlsZCBxdWVyaWVzIHdpdGggZGF0ZSByYW5nZXM6IDIgbWluIFRUTCDigJQgbmV3IGV2ZW50cyBhcnJpdmUgY29udGludW91c2x5XG4gKi9cbmNvbnN0IGludmVudG9yeUNhY2hlID0gY3JlYXRlQ2FjaGVTZXJ2aWNlKCdyZXBvcnQ6aW52OicsIHBhcnNlSW50KHByb2Nlc3MuZW52LkNBQ0hFX1RUTF9SRVBPUlRfSU5WRU5UT1JZIHx8ICczMDAnLCAxMCkpO1xuY29uc3QgdGltZXNlcmllc0NhY2hlID0gY3JlYXRlQ2FjaGVTZXJ2aWNlKCdyZXBvcnQ6dHM6JywgcGFyc2VJbnQocHJvY2Vzcy5lbnYuQ0FDSEVfVFRMX1JFUE9SVF9USU1FU0VSSUVTIHx8ICcxMjAnLCAxMCkpO1xuXG4vLyDilIDilIDilIAgVHlwZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmludGVyZmFjZSBFeGVjdXRpb25Db3VudCB7XG4gIGlkOiBzdHJpbmc7XG4gIHByb2plY3Q6IHN0cmluZztcbiAgb3JnYW5pemF0aW9uOiBzdHJpbmc7XG4gIHBpcGVsaW5lTmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgdG90YWw6IG51bWJlcjtcbiAgc3VjY2VlZGVkOiBudW1iZXI7XG4gIGZhaWxlZDogbnVtYmVyO1xuICBjYW5jZWxlZDogbnVtYmVyO1xuICBmaXJzdEV4ZWN1dGlvbjogc3RyaW5nIHwgbnVsbDtcbiAgbGFzdEV4ZWN1dGlvbjogc3RyaW5nIHwgbnVsbDtcbn1cblxuaW50ZXJmYWNlIFRpbWVTZXJpZXNFbnRyeSB7XG4gIHBlcmlvZDogc3RyaW5nO1xuICBzdWNjZWVkZWQ6IG51bWJlcjtcbiAgZmFpbGVkOiBudW1iZXI7XG4gIGNhbmNlbGVkOiBudW1iZXI7XG4gIHN1Y2Nlc3NQY3Q6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIER1cmF0aW9uU3RhdHMge1xuICBpZDogc3RyaW5nO1xuICBwcm9qZWN0OiBzdHJpbmc7XG4gIHBpcGVsaW5lTmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgYXZnTXM6IG51bWJlcjtcbiAgbWluTXM6IG51bWJlcjtcbiAgbWF4TXM6IG51bWJlcjtcbiAgcDk1TXM6IG51bWJlcjtcbiAgZXhlY3V0aW9uczogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgU3RhZ2VGYWlsdXJlIHtcbiAgc3RhZ2VOYW1lOiBzdHJpbmc7XG4gIGZhaWx1cmVzOiBudW1iZXI7XG4gIHRvdGFsOiBudW1iZXI7XG4gIGZhaWx1cmVQY3Q6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFN0YWdlQm90dGxlbmVjayB7XG4gIGlkOiBzdHJpbmc7XG4gIHBpcGVsaW5lTmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgc3RhZ2VOYW1lOiBzdHJpbmc7XG4gIGF2Z01zOiBudW1iZXI7XG4gIG1heE1zOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBBY3Rpb25GYWlsdXJlIHtcbiAgYWN0aW9uTmFtZTogc3RyaW5nO1xuICBmYWlsdXJlczogbnVtYmVyO1xuICB0b3RhbDogbnVtYmVyO1xuICBmYWlsdXJlUGN0OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBFcnJvckVudHJ5IHtcbiAgZXJyb3JQYXR0ZXJuOiBzdHJpbmc7XG4gIG9jY3VycmVuY2VzOiBudW1iZXI7XG4gIGFmZmVjdGVkUGlwZWxpbmVzOiBudW1iZXI7XG4gIGxhc3RTZWVuOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBQbHVnaW5TdW1tYXJ5IHtcbiAgdG90YWw6IG51bWJlcjtcbiAgYWN0aXZlOiBudW1iZXI7XG4gIGluYWN0aXZlOiBudW1iZXI7XG4gIHB1YmxpYzogbnVtYmVyO1xuICBwcml2YXRlOiBudW1iZXI7XG4gIHVuaXF1ZU5hbWVzOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBUeXBlQ29tcHV0ZURpc3RyaWJ1dGlvbiB7XG4gIHBsdWdpblR5cGU6IHN0cmluZztcbiAgY29tcHV0ZVR5cGU6IHN0cmluZztcbiAgY291bnQ6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFZlcnNpb25Db3VudCB7XG4gIG5hbWU6IHN0cmluZztcbiAgdmVyc2lvbkNvdW50OiBudW1iZXI7XG4gIGxhdGVzdFZlcnNpb246IHN0cmluZztcbiAgaGFzRGVmYXVsdDogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIEJ1aWxkVGltZVNlcmllc0VudHJ5IHtcbiAgcGVyaW9kOiBzdHJpbmc7XG4gIHN1Y2NlZWRlZDogbnVtYmVyO1xuICBmYWlsZWQ6IG51bWJlcjtcbiAgc3VjY2Vzc1BjdDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQnVpbGREdXJhdGlvbiB7XG4gIHBsdWdpbk5hbWU6IHN0cmluZztcbiAgYXZnTXM6IG51bWJlcjtcbiAgbWF4TXM6IG51bWJlcjtcbiAgYnVpbGRzOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBCdWlsZEZhaWx1cmUge1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIGVycm9yTWVzc2FnZTogc3RyaW5nO1xuICBvY2N1cnJlbmNlczogbnVtYmVyO1xuICBsYXN0U2Vlbjogc3RyaW5nO1xufVxuXG4vKiogRXZlbnQgcGF5bG9hZCBhY2NlcHRlZCBieSBgUmVwb3J0aW5nU2VydmljZS5pbmdlc3RFdmVudHNgLiBNaXJyb3JzIHRoZSByb3V0ZSdzIFpvZCBzaGFwZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5nZXN0RXZlbnQge1xuICAvKiogU3RhYmxlIHBpcGVsaW5lIGlkIHRoZSBldmVudHMgTGFtYmRhIHJlYWQgZnJvbSB0aGUgYFBJUEVMSU5FX0VWRU5UX0lEYFxuICAgKiAgdGFnICg9IHRoZSBwbGF0Zm9ybSBwaXBlbGluZUlkKS4gVGhlIHJlZ2lzdHJ5IGpvaW4ga2V5LiAqL1xuICBwaXBlbGluZUlkOiBzdHJpbmc7XG4gIGV2ZW50U291cmNlOiAnY29kZXBpcGVsaW5lJyB8ICdjb2RlYnVpbGQnIHwgJ3BsdWdpbi1idWlsZCc7XG4gIGV2ZW50VHlwZTogJ1BJUEVMSU5FJyB8ICdTVEFHRScgfCAnQUNUSU9OJyB8ICdCVUlMRCc7XG4gIHN0YXR1czogc3RyaW5nO1xuICBleGVjdXRpb25JZD86IHN0cmluZztcbiAgc3RhZ2VOYW1lPzogc3RyaW5nO1xuICBhY3Rpb25OYW1lPzogc3RyaW5nO1xuICAvKiogSHVtYW4tcmVhZGFibGUgZmFpbHVyZSByZWFzb24gKEFjdGlvbiBldmVudHMpLiAqL1xuICBlcnJvck1lc3NhZ2U/OiBzdHJpbmc7XG4gIHN0YXJ0ZWRBdD86IHN0cmluZztcbiAgY29tcGxldGVkQXQ/OiBzdHJpbmc7XG4gIGR1cmF0aW9uTXM/OiBudW1iZXI7XG4gIGRldGFpbD86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG4vKiogQ291bnRzICsgdGhlIChwb3NzaWJseSB0cnVuY2F0ZWQpIGxpc3Qgb2YgdW5yZWdpc3RlcmVkIHBpcGVsaW5lIGlkcyB0aGUgY2FsbGVyIGNhbiBsb2cuICovXG5leHBvcnQgaW50ZXJmYWNlIEluZ2VzdFJlc3VsdCB7XG4gIGluc2VydGVkOiBudW1iZXI7XG4gIHNraXBwZWQ6IG51bWJlcjtcbiAgdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHM6IHN0cmluZ1tdO1xufVxuXG4vLyDilIDilIDilIAgU2VydmljZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLyoqXG4gKiBSZWFkLW9ubHkgcmVwb3J0aW5nIHNlcnZpY2UgZm9yIHBpcGVsaW5lIGV4ZWN1dGlvbiBhbmQgcGx1Z2luIGludmVudG9yeSBhZ2dyZWdhdGlvbnMuXG4gKiBEb2VzIG5vdCBleHRlbmQgQ3J1ZFNlcnZpY2Ug4oCUIHJlcG9ydHMgYXJlIGFnZ3JlZ2F0ZSBxdWVyaWVzLCBub3QgZW50aXR5IENSVUQuXG4gKlxuICogQWxsIHF1ZXJpZXMgYXJlIGNhY2hlZCBpbi1tZW1vcnkgdG8gYXZvaWQgcmVwZWF0ZWQgZXhwZW5zaXZlIFNRTCBhZ2dyZWdhdGlvbnM6XG4gKiAtIEludmVudG9yeSBxdWVyaWVzIChwbHVnaW4gc3VtbWFyeS9kaXN0cmlidXRpb24vdmVyc2lvbnMpOiA1IG1pbiBUVExcbiAqIC0gVGltZXNlcmllcyBxdWVyaWVzIChleGVjdXRpb24vYnVpbGQgbWV0cmljcyB3aXRoIGRhdGUgcmFuZ2VzKTogMiBtaW4gVFRMXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXBvcnRpbmdTZXJ2aWNlIHtcblxuICAvKiogSW52YWxpZGF0ZSBhbGwgY2FjaGVkIHJlcG9ydHMgZm9yIGFuIG9yZyAoY2FsbCBhZnRlciBldmVudCBpbmdlc3QpLiAqL1xuICBhc3luYyBpbnZhbGlkYXRlT3JnKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICBpbnZlbnRvcnlDYWNoZS5pbnZhbGlkYXRlUGF0dGVybihgJHtvcmdJZH06KmApLFxuICAgICAgdGltZXNlcmllc0NhY2hlLmludmFsaWRhdGVQYXR0ZXJuKGAke29yZ0lkfToqYCksXG4gICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSBpbmNvbWluZyBldmVudHMgYWdhaW5zdCB0aGUgcGlwZWxpbmUgcmVnaXN0cnksIGJhdGNoLWluc2VydCB0aGVcbiAgICogbWF0Y2hlZCBvbmVzLCBhbmQgaW52YWxpZGF0ZSByZXBvcnRpbmcgY2FjaGVzIGZvciBhZmZlY3RlZCBvcmdzLlxuICAgKiBFdmVudHMgZm9yIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBBUk5zIGFyZSBkcm9wcGVkIChhbmQgbG9nZ2VkIGF0IFdBUk5cbiAgICogd2l0aCBzYW1wbGUgQVJOcyBzbyBhbiBvcGVyYXRvciBjYW4gc2VlIHdoZW4gRXZlbnRCcmlkZ2UgaXMgZGVsaXZlcmluZ1xuICAgKiBldmVudHMgZm9yIHBpcGVsaW5lcyB0aGF0IGhhdmVuJ3QgY2FsbGVkIFBPU1QgL3BpcGVsaW5lcy9yZWdpc3RyeSB5ZXQpLlxuICAgKlxuICAgKiBSZXR1cm5zIGNvdW50cyArIGEgc2FtcGxlIG9mIHVucmVnaXN0ZXJlZCBBUk5zIGZvciBvYnNlcnZhYmlsaXR5LlxuICAgKi9cbiAgYXN5bmMgaW5nZXN0RXZlbnRzKGV2ZW50czogSW5nZXN0RXZlbnRbXSk6IFByb21pc2U8SW5nZXN0UmVzdWx0PiB7XG4gICAgLy8gTXVsdGktb3JnIGJhdGNoIGluc2VydDogdGhlIGNhbGxlciByZXNvbHZlcyB0byBtdWx0aXBsZSBvcmdzIHZpYSB0aGVcbiAgICAvLyBwaXBlbGluZS1yZWdpc3RyeSBsb29rdXAgYmVsb3csIHNvIHRoZSByb3V0ZSBsYXllciBNVVNUIGVzdGFibGlzaCBhXG4gICAgLy8gYHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIC4uLilgIHNjb3BlIGJlZm9yZSBjYWxsaW5nXG4gICAgLy8gdGhpcyBtZXRob2QuIFVuZGVyIEZPUkNFJ2QgUkxTLCBhIHNpbmdsZSB0eCB3aXRoIGBhcHAub3JnX2lkID0gPG9uZVxuICAgIC8vIG9yZz5gIGNvdWxkIG9ubHkgd3JpdGUgZXZlbnRzIGZvciB0aGF0IG9yZzsgYnlwYXNzIHZpYSBzeXNhZG1pbiBpc1xuICAgIC8vIHRoZSByaWdodCBnYXRlIGZvciB0aGlzIHNlcnZlci1pbnRlcm5hbCBjcm9zcy10ZW5hbnQgZW5kcG9pbnQuIFNlZVxuICAgIC8vIGFwaS9yZXBvcnRpbmcvc3JjL3JvdXRlcy9ldmVudC1pbmdlc3QudHMgZm9yIHRoZSB3cmFwcGVyLlxuICAgIC8vIFJ1biBpbnNlcnQgaW5zaWRlIHRoZSB0eCwgYnV0IENPTExFQ1QgYWZmZWN0ZWQgb3JncyBhbmQgaW52YWxpZGF0ZVxuICAgIC8vIGNhY2hlcyBBRlRFUiB0aGUgdHggcmVzb2x2ZXMuIEtlZXBpbmcgaW52YWxpZGF0aW9uIGluc2lkZSB0aGUgdHggaGVsZFxuICAgIC8vIHRoZSBwZyBsb2NrcyBvcGVuIGZvciB0aGUgZHVyYXRpb24gb2YgdGhlIGNhY2hlIHJvdW5kLXRyaXBzIChSZWRpcyBvclxuICAgIC8vIGluLW1lbW9yeSBpbnZhbGlkYXRpb25zIGFyZSB1bnJlbGF0ZWQgdG8gdGhlIHR4IGJ1dCBzdGlsbCBzZXJpYWxpemVkXG4gICAgLy8gaXRzIGNvbW1pdCkuIENhY2hlIFRUTCBpcyAyLTUgbWluIHNvIGZpcmUtYW5kLWZvcmdldCBwb3N0LWNvbW1pdCBpc1xuICAgIC8vIGFuIGFjY2VwdGFibGUgdHJhZGUgZm9yIHRpZ2h0ZXIgbG9jayB3aW5kb3dzLlxuICAgIGNvbnN0IHsgaW5zZXJ0ZWQsIHNraXBwZWQsIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLCBhZmZlY3RlZE9yZ3MgfSA9IGF3YWl0IHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICAgIC8vIEJhdGNoLXJlc29sdmUgYWxsIHVuaXF1ZSBwaXBlbGluZSBpZHMgaW4gb25lIHF1ZXJ5XG4gICAgICBjb25zdCB1bmlxdWVJZHMgPSBbLi4ubmV3IFNldChldmVudHMubWFwKGUgPT4gZS5waXBlbGluZUlkKSldO1xuICAgICAgY29uc3QgcmVnaXN0cnlSb3dzID0gYXdhaXQgdHhcbiAgICAgICAgLnNlbGVjdCh7XG4gICAgICAgICAgcGlwZWxpbmVJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkucGlwZWxpbmVJZCxcbiAgICAgICAgICBvcmdJZDogc2NoZW1hLnBpcGVsaW5lUmVnaXN0cnkub3JnSWQsXG4gICAgICAgIH0pXG4gICAgICAgIC5mcm9tKHNjaGVtYS5waXBlbGluZVJlZ2lzdHJ5KVxuICAgICAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGlwZWxpbmVSZWdpc3RyeS5waXBlbGluZUlkLCB1bmlxdWVJZHMpKTtcblxuICAgICAgY29uc3QgaWRNYXAgPSBuZXcgTWFwKHJlZ2lzdHJ5Um93cy5tYXAociA9PiBbci5waXBlbGluZUlkLCByXSkpO1xuXG4gICAgICAvLyBCdWlsZCBpbnNlcnQgYmF0Y2ggKHNraXAgZXZlbnRzIHdob3NlIHBpcGVsaW5lIGlzbid0IHJlZ2lzdGVyZWQpXG4gICAgICBjb25zdCByb3dzOiBBcnJheTx0eXBlb2Ygc2NoZW1hLnBpcGVsaW5lRXZlbnQuJGluZmVySW5zZXJ0PiA9IFtdO1xuICAgICAgbGV0IHNraXBwZWRMb2NhbCA9IDA7XG4gICAgICBjb25zdCB1bnJlZ2lzdGVyZWRMb2NhbDogc3RyaW5nW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMpIHtcbiAgICAgICAgY29uc3QgcmVnaXN0cnkgPSBpZE1hcC5nZXQoZXZlbnQucGlwZWxpbmVJZCk7XG4gICAgICAgIGlmICghcmVnaXN0cnkpIHtcbiAgICAgICAgICBza2lwcGVkTG9jYWwrKztcbiAgICAgICAgICB1bnJlZ2lzdGVyZWRMb2NhbC5wdXNoKGV2ZW50LnBpcGVsaW5lSWQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgICAvLyByZWdpc3RyeS5waXBlbGluZUlkID09PSBldmVudC5waXBlbGluZUlkOyB1c2UgdGhlIHJlZ2lzdHJ5J3Mgc28gdGhlXG4gICAgICAgICAgLy8gRksgaXMgYWx3YXlzIGEgcm93IHRoYXQgZXhpc3RzLCBhbmQgcHVsbCBvcmdJZCBmcm9tIHRoZSByZWdpc3RyeSBmb3JcbiAgICAgICAgICAvLyB0ZW5hbmN5IChuZXZlciB0cnVzdCB0aGUgY2FsbGVyJ3MgY2xhaW1lZCBvcmcpLlxuICAgICAgICAgIHBpcGVsaW5lSWQ6IHJlZ2lzdHJ5LnBpcGVsaW5lSWQsXG4gICAgICAgICAgb3JnSWQ6IHJlZ2lzdHJ5Lm9yZ0lkLFxuICAgICAgICAgIGV2ZW50U291cmNlOiBldmVudC5ldmVudFNvdXJjZSxcbiAgICAgICAgICBldmVudFR5cGU6IGV2ZW50LmV2ZW50VHlwZSxcbiAgICAgICAgICBzdGF0dXM6IGV2ZW50LnN0YXR1cyxcbiAgICAgICAgICBleGVjdXRpb25JZDogZXZlbnQuZXhlY3V0aW9uSWQsXG4gICAgICAgICAgc3RhZ2VOYW1lOiBldmVudC5zdGFnZU5hbWUsXG4gICAgICAgICAgYWN0aW9uTmFtZTogZXZlbnQuYWN0aW9uTmFtZSxcbiAgICAgICAgICBlcnJvck1lc3NhZ2U6IGV2ZW50LmVycm9yTWVzc2FnZSxcbiAgICAgICAgICBzdGFydGVkQXQ6IGV2ZW50LnN0YXJ0ZWRBdCA/IG5ldyBEYXRlKGV2ZW50LnN0YXJ0ZWRBdCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgY29tcGxldGVkQXQ6IGV2ZW50LmNvbXBsZXRlZEF0ID8gbmV3IERhdGUoZXZlbnQuY29tcGxldGVkQXQpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGR1cmF0aW9uTXM6IGV2ZW50LmR1cmF0aW9uTXMsXG4gICAgICAgICAgZGV0YWlsOiBldmVudC5kZXRhaWwsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBTUVMgaXMgYXQtbGVhc3Qtb25jZSwgc28gRXZlbnRCcmlkZ2UgY2FuIGRlbGl2ZXIgdGhlIHNhbWUgc3RhdGUtY2hhbmdlXG4gICAgICAvLyB0d2ljZS4gYG9uQ29uZmxpY3REb05vdGhpbmdgICsgdGhlIHBhcnRpYWwgdW5pcXVlIGluZGV4IG9uXG4gICAgICAvLyAocGlwZWxpbmVfaWQsIGV4ZWN1dGlvbl9pZCwgZXZlbnRfdHlwZSwgc3RhdHVzLCBzdGFnZV9uYW1lLCBhY3Rpb25fbmFtZSlcbiAgICAgIC8vIG1ha2VzIHJlLWRlbGl2ZXJ5IGlkZW1wb3RlbnQuIGByZXR1cm5pbmdgIGdpdmVzIHRoZSBSRUFMIGluc2VydGVkIHNldCBzb1xuICAgICAgLy8gY291bnRzICsgY2FjaGUgaW52YWxpZGF0aW9uIGlnbm9yZSBkdXBsaWNhdGVzLlxuICAgICAgY29uc3QgaW5zZXJ0ZWRSb3dzID0gcm93cy5sZW5ndGggPiAwXG4gICAgICAgID8gYXdhaXQgdHguaW5zZXJ0KHNjaGVtYS5waXBlbGluZUV2ZW50KS52YWx1ZXMocm93cylcbiAgICAgICAgICAub25Db25mbGljdERvTm90aGluZygpXG4gICAgICAgICAgLnJldHVybmluZyh7IG9yZ0lkOiBzY2hlbWEucGlwZWxpbmVFdmVudC5vcmdJZCB9KVxuICAgICAgICA6IFtdO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBpbnNlcnRlZDogaW5zZXJ0ZWRSb3dzLmxlbmd0aCxcbiAgICAgICAgc2tpcHBlZDogc2tpcHBlZExvY2FsLFxuICAgICAgICB1bnJlZ2lzdGVyZWRQaXBlbGluZUlkczogdW5yZWdpc3RlcmVkTG9jYWwsXG4gICAgICAgIGFmZmVjdGVkT3JnczogWy4uLm5ldyBTZXQoaW5zZXJ0ZWRSb3dzLm1hcChyID0+IHIub3JnSWQpKV0sXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gU3VyZmFjZSB0aGUgc2lsZW50IHNraXA6IGFuIHVucmVnaXN0ZXJlZCBwaXBlbGluZSBpZCB1c3VhbGx5IG1lYW5zIHRoZVxuICAgIC8vIHBpcGVsaW5lIGhhc24ndCBjYWxsZWQgUE9TVCAvcGlwZWxpbmVzL3JlZ2lzdHJ5IHlldCAob3IgaXRzXG4gICAgLy8gUElQRUxJTkVfRVZFTlRfSUQgdGFnIGlzIG1pc3NpbmcvdW5yZWFkYWJsZSBieSB0aGUgTGFtYmRhKS4gTG9nZ2luZyBpdFxuICAgIC8vIG1ha2VzIGEgYnJva2VuIGpvaW4gdmlzaWJsZSBpbnN0ZWFkIG9mIGxvb2tpbmcgbGlrZSBcIm5vIGFjdGl2aXR5XCIuXG4gICAgaWYgKHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGxvZ2dlci53YXJuKCdQaXBlbGluZSBldmVudHMgc2tpcHBlZDogcGlwZWxpbmUgaWQgbm90IGZvdW5kIGluIHJlZ2lzdHJ5Jywge1xuICAgICAgICBjb3VudDogdW5yZWdpc3RlcmVkUGlwZWxpbmVJZHMubGVuZ3RoLFxuICAgICAgICBzYW1wbGU6IHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzLnNsaWNlKDAsIDMpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gUG9zdC1jb21taXQgY2FjaGUgaW52YWxpZGF0aW9uLiBGaXJlLWFuZC1mb3JnZXQgd2l0aCBsb2dnaW5nIOKAlCBUVEwgaXNcbiAgICAvLyBzaG9ydCBlbm91Z2ggdGhhdCBhIG1pc3NlZCBpbnZhbGlkYXRpb24gc2VsZi1oZWFscy5cbiAgICBpZiAoYWZmZWN0ZWRPcmdzLmxlbmd0aCA+IDApIHtcbiAgICAgIHZvaWQgUHJvbWlzZS5hbGwoYWZmZWN0ZWRPcmdzLm1hcCgob3JnKSA9PlxuICAgICAgICB0aGlzLmludmFsaWRhdGVPcmcob3JnKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyBjYWNoZSBpbnZhbGlkYXRpb24gZmFpbGVkJywgeyBvcmdJZDogb3JnLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgaW5zZXJ0ZWQsIHNraXBwZWQsIHVucmVnaXN0ZXJlZFBpcGVsaW5lSWRzIH07XG4gIH1cblxuICAvLyDilIDilIAgQ2F0ZWdvcnkgMTogUGlwZWxpbmUgRXhlY3V0aW9uICYgUGVyZm9ybWFuY2Ug4pSA4pSAXG5cbiAgLyoqXG4gICAqIEJ1aWxkIHRoZSBvcmctc2NvcGUgcHJlZGljYXRlIGZvciBhIHJlcG9ydCBxdWVyeS4gV2l0aCBgb3JnSWRzYCAodGhlXG4gICAqIG9yZyDihpIgdGVhbSByb2xsdXAg4oCUIGEgcGFyZW50J3MgYFtzZWxmLCAuLi5kZXNjZW5kYW50c11gKSBpdCBiZWNvbWVzIGFuXG4gICAqIGBJTiAoLi4uKWAgb3ZlciB0aGUgc3VidHJlZTsgb3RoZXJ3aXNlIHRoZSBzaW5nbGUtb3JnIGA9ICRvcmdgLiBSZXR1cm5zIGFcbiAgICogYG11bHRpYCBmbGFnIHNvIGNhbGxlcnMgY2FuIHJ1biBtdWx0aS1vcmcgcmVhZHMgdW5kZXIgc3lzYWRtaW4gY29udGV4dFxuICAgKiAodGhlIHN1YnRyZWUgc3BhbnMgb3JncyBvdXRzaWRlIHRoZSByZXF1ZXN0J3MgUkxTIHNjb3BlKSBhbmQgc2FsdCB0aGVcbiAgICogY2FjaGUga2V5LlxuICAgKi9cbiAgcHJpdmF0ZSBvcmdTY29wZShvcmdJZDogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSkge1xuICAgIGNvbnN0IGlkcyA9IG9yZ0lkcyAmJiBvcmdJZHMubGVuZ3RoID4gMCA/IG9yZ0lkcyA6IFtvcmdJZF07XG4gICAgY29uc3QgbXVsdGkgPSBpZHMubGVuZ3RoID4gMTtcbiAgICBjb25zdCBwcmVkID0gbXVsdGlcbiAgICAgID8gc3FsYElOICgke3NxbC5qb2luKGlkcy5tYXAoKGlkKSA9PiBzcWxgJHtpZH1gKSwgc3FsYCwgYCl9KWBcbiAgICAgIDogc3FsYD0gJHtpZHNbMF19YDtcbiAgICByZXR1cm4geyBwcmVkLCBtdWx0aSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1biBhIHJlcG9ydCByZWFkLiBTaW5nbGUtb3JnIHJlYWRzIHVzZSB0aGUgcGVyLW9yZyBjYWNoZSAoaW52YWxpZGF0ZWQgb25cbiAgICogdGhhdCBvcmcncyBldmVudCBpbmdlc3QpLiBSb2xsdXAgKG11bHRpLW9yZykgcmVhZHMgKipieXBhc3MgdGhlIGNhY2hlKiogYW5kXG4gICAqIHJ1biB1bmRlciBzeXNhZG1pbiBjb250ZXh0OiB0aGV5J3JlIGFkbWluLW9ubHkgYW5kIGxvd2VyLWZyZXF1ZW5jeSwgYW5kIGFcbiAgICogY2hpbGQgb3JnJ3MgZXZlbnQgaW5nZXN0IGNhbid0IGludmFsaWRhdGUgYSBwYXJlbnQncyByb2xsdXAgZW50cnkgKHJlcG9ydGluZ1xuICAgKiBoYXMgbm8gb3JnIHRyZWUpLCBzbyBjYWNoaW5nIHRoZW0gd291bGQgc2VydmUgc3RhbGUgYWdncmVnYXRlcy4gQWx3YXlzIGZyZXNoLlxuICAgKi9cbiAgcHJpdmF0ZSBydW5SZXBvcnQ8VD4oY2FjaGVLZXk6IHN0cmluZywgbXVsdGk6IGJvb2xlYW4sIGV4ZWM6ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICByZXR1cm4gbXVsdGlcbiAgICAgID8gcnVuV2l0aFRlbmFudENvbnRleHQoeyBpc1N1cGVyQWRtaW46IHRydWUgfSwgZXhlYylcbiAgICAgIDogdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGNhY2hlS2V5LCBleGVjKTtcbiAgfVxuXG4gIC8qKiAxLjEgRXhlY3V0aW9uIGNvdW50IHBlciBwaXBlbGluZSB3aXRoIHN0YXR1cyBicmVha2Rvd24uICovXG4gIGFzeW5jIGdldEV4ZWN1dGlvbkNvdW50KG9yZ0lkOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxFeGVjdXRpb25Db3VudFtdPiB7XG4gICAgY29uc3QgeyBwcmVkLCBtdWx0aSB9ID0gdGhpcy5vcmdTY29wZShvcmdJZCwgb3JnSWRzKTtcbiAgICBjb25zdCBleGVjID0gKCkgPT4gd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIHAuaWQsIHAucHJvamVjdCwgcC5vcmdhbml6YXRpb24sIHAucGlwZWxpbmVfbmFtZSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHRvdGFsLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnU1VDQ0VFREVEJyk6OmludCBBUyBzdWNjZWVkZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWxlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ0NBTkNFTEVEJyk6OmludCBBUyBjYW5jZWxlZCxcbiAgICAgICAgICBNSU4oZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBmaXJzdF9leGVjdXRpb24sXG4gICAgICAgICAgTUFYKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgbGFzdF9leGVjdXRpb25cbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZX0gcFxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGUgT04gZS5waXBlbGluZV9pZCA9IHAuaWRcbiAgICAgICAgICBBTkQgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyBBTkQgZS5zdGF0dXMgIT0gJ1NUQVJURUQnXG4gICAgICAgIFdIRVJFIHAub3JnX2lkICR7cHJlZH0gQU5EIHAuaXNfYWN0aXZlID0gdHJ1ZVxuICAgICAgICBHUk9VUCBCWSBwLmlkXG4gICAgICAgIE9SREVSIEJZIHRvdGFsIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxFeGVjdXRpb25Db3VudD4oci5yb3dzKSkpO1xuICAgIHJldHVybiB0aGlzLnJ1blJlcG9ydChgJHtvcmdJZH06ZXhlYy1jb3VudGAsIG11bHRpLCBleGVjKTtcbiAgfVxuXG4gIC8qKiAxLjIgU3VjY2VzcyByYXRlIG92ZXIgdGltZSBmb3IgYW4gb3JnLiAqL1xuICBhc3luYyBnZXRTdWNjZXNzUmF0ZShvcmdJZDogc3RyaW5nLCBpbnRlcnZhbDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIG9yZ0lkcz86IHN0cmluZ1tdKTogUHJvbWlzZTxUaW1lU2VyaWVzRW50cnlbXT4ge1xuICAgIGNvbnN0IHsgcHJlZCwgbXVsdGkgfSA9IHRoaXMub3JnU2NvcGUob3JnSWQsIG9yZ0lkcyk7XG4gICAgY29uc3QgZXhlYyA9ICgpID0+IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBEQVRFX1RSVU5DKCR7aW50ZXJ2YWx9LCBlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIHBlcmlvZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCcpOjppbnQgQVMgc3VjY2VlZGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdDQU5DRUxFRCcpOjppbnQgQVMgY2FuY2VsZWQsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgc3VjY2Vzc19wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgJHtwcmVkfSBBTkQgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJ1xuICAgICAgICAgIEFORCBlLnN0YXR1cyBJTiAoJ1NVQ0NFRURFRCcsICdGQUlMRUQnLCAnQ0FOQ0VMRUQnKVxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgcGVyaW9kIE9SREVSIEJZIHBlcmlvZFxuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFRpbWVTZXJpZXNFbnRyeT4oci5yb3dzKSkpO1xuICAgIHJldHVybiB0aGlzLnJ1blJlcG9ydChgJHtvcmdJZH06c3VjY2Vzcy1yYXRlOiR7aW50ZXJ2YWx9OiR7ZnJvbX06JHt0b31gLCBtdWx0aSwgZXhlYyk7XG4gIH1cblxuICAvKiogMS4zIEF2ZXJhZ2UgZHVyYXRpb24gcGVyIHBpcGVsaW5lLiAqL1xuICBhc3luYyBnZXRBdmVyYWdlRHVyYXRpb24ob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBvcmdJZHM/OiBzdHJpbmdbXSk6IFByb21pc2U8RHVyYXRpb25TdGF0c1tdPiB7XG4gICAgY29uc3QgeyBwcmVkLCBtdWx0aSB9ID0gdGhpcy5vcmdTY29wZShvcmdJZCwgb3JnSWRzKTtcbiAgICBjb25zdCBleGVjID0gKCkgPT4gd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIHAuaWQsIHAucHJvamVjdCwgcC5waXBlbGluZV9uYW1lLFxuICAgICAgICAgIEFWRyhlLmR1cmF0aW9uX21zKTo6aW50IEFTIGF2Z19tcyxcbiAgICAgICAgICBNSU4oZS5kdXJhdGlvbl9tcyk6OmludCBBUyBtaW5fbXMsXG4gICAgICAgICAgTUFYKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWF4X21zLFxuICAgICAgICAgIFBFUkNFTlRJTEVfQ09OVCgwLjk1KSBXSVRISU4gR1JPVVAgKE9SREVSIEJZIGUuZHVyYXRpb25fbXMpOjppbnQgQVMgcDk1X21zLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgZXhlY3V0aW9uc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCAke3ByZWR9IEFORCBlLmV2ZW50X3R5cGUgPSAnUElQRUxJTkUnIEFORCBlLmR1cmF0aW9uX21zIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwLmlkIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8RHVyYXRpb25TdGF0cz4oci5yb3dzKSkpO1xuICAgIHJldHVybiB0aGlzLnJ1blJlcG9ydChgJHtvcmdJZH06YXZnLWR1cmF0aW9uOiR7ZnJvbX06JHt0b31gLCBtdWx0aSwgZXhlYyk7XG4gIH1cblxuICAvKiogMS41IFN0YWdlIGZhaWx1cmUgaGVhdG1hcCDigJQgd2hpY2ggc3RhZ2VzIGZhaWwgbW9zdC4gKi9cbiAgYXN5bmMgZ2V0U3RhZ2VGYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPFN0YWdlRmFpbHVyZVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06c3RhZ2UtZmFpbHVyZXM6JHtmcm9tfToke3RvfWAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5zdGFnZV9uYW1lLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsdXJlcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHRvdGFsLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIGZhaWx1cmVfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdTVEFHRScgQU5EIGUuc3RhZ2VfbmFtZSBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgZS5zdGFnZV9uYW1lIE9SREVSIEJZIGZhaWx1cmVzIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxTdGFnZUZhaWx1cmU+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDEuNiBTdGFnZSBib3R0bGVuZWNrcyDigJQgc2xvd2VzdCBzdGFnZXMgcGVyIHBpcGVsaW5lLiAqL1xuICBhc3luYyBnZXRTdGFnZUJvdHRsZW5lY2tzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IFByb21pc2U8U3RhZ2VCb3R0bGVuZWNrW10+IHtcbiAgICByZXR1cm4gdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpzdGFnZS1ib3R0bGVuZWNrczoke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBwLmlkLCBwLnBpcGVsaW5lX25hbWUsIGUuc3RhZ2VfbmFtZSxcbiAgICAgICAgICBBVkcoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBhdmdfbXMsXG4gICAgICAgICAgTUFYKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWF4X21zXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdTVEFHRScgQU5EIGUuZHVyYXRpb25fbXMgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIHAuaWQsIGUuc3RhZ2VfbmFtZSBPUkRFUiBCWSBhdmdfbXMgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPFN0YWdlQm90dGxlbmVjaz4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cblxuICAvKiogMS43IEFjdGlvbiBmYWlsdXJlIHJhdGUg4oCUIHdoaWNoIHBsdWdpbiBzdGVwcyBmYWlsIG1vc3QuICovXG4gIGFzeW5jIGdldEFjdGlvbkZhaWx1cmVzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IFByb21pc2U8QWN0aW9uRmFpbHVyZVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06YWN0aW9uLWZhaWx1cmVzOiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIGUuYWN0aW9uX25hbWUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6aW50IEFTIGZhaWx1cmVzLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdGQUlMRUQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgZmFpbHVyZV9wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF90eXBlID0gJ0FDVElPTicgQU5EIGUuYWN0aW9uX25hbWUgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIGUuYWN0aW9uX25hbWUgT1JERVIgQlkgZmFpbHVyZXMgREVTQ1xuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPEFjdGlvbkZhaWx1cmU+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDEuOCBFcnJvciBjYXRlZ29yaXphdGlvbiDigJQgZ3JvdXAgZmFpbHVyZSBtZXNzYWdlcy4gKi9cbiAgYXN5bmMgZ2V0RXJyb3JzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgbGltaXQ6IG51bWJlciA9IDIwKTogUHJvbWlzZTxFcnJvckVudHJ5W10+IHtcbiAgICByZXR1cm4gdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGAke29yZ0lkfTplcnJvcnM6JHtmcm9tfToke3RvfToke2xpbWl0fWAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgU1VCU1RSSU5HKGUuZXJyb3JfbWVzc2FnZSBGUk9NIDEgRk9SIDIwMCkgQVMgZXJyb3JfcGF0dGVybixcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIG9jY3VycmVuY2VzLFxuICAgICAgICAgIENPVU5UKERJU1RJTkNUIGUucGlwZWxpbmVfaWQpOjppbnQgQVMgYWZmZWN0ZWRfcGlwZWxpbmVzLFxuICAgICAgICAgIE1BWChlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGxhc3Rfc2VlblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLnN0YXR1cyA9ICdGQUlMRUQnIEFORCBlLmVycm9yX21lc3NhZ2UgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIGVycm9yX3BhdHRlcm4gT1JERVIgQlkgb2NjdXJyZW5jZXMgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPEVycm9yRW50cnk+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLy8g4pSA4pSAIENhdGVnb3J5IDI6IFBsdWdpbiBJbnZlbnRvcnkgJiBCdWlsZHMg4pSA4pSAXG5cbiAgLyoqIDIuMSBQbHVnaW4gc3VtbWFyeSDigJQgY291bnRzIGFuZCBicmVha2Rvd25zLiAqL1xuICBhc3luYyBnZXRQbHVnaW5TdW1tYXJ5KG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFBsdWdpblN1bW1hcnk+IHtcbiAgICByZXR1cm4gaW52ZW50b3J5Q2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnBsdWdpbi1zdW1tYXJ5YCwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHRvdGFsLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSk6OmludCBBUyBhY3RpdmUsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBOT1QgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSk6OmludCBBUyBpbmFjdGl2ZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi5hY2Nlc3NNb2RpZmllcn0gPSAncHVibGljJyk6OmludCBBUyBwdWJsaWMsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSAke3NjaGVtYS5wbHVnaW4uYWNjZXNzTW9kaWZpZXJ9ID0gJ3ByaXZhdGUnKTo6aW50IEFTIHByaXZhdGUsXG4gICAgICAgICAgQ09VTlQoRElTVElOQ1QgJHtzY2hlbWEucGx1Z2luLm5hbWV9KTo6aW50IEFTIHVuaXF1ZV9uYW1lc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBsdWdpbn1cbiAgICAgICAgV0hFUkUgJHtzY2hlbWEucGx1Z2luLm9yZ0lkfSA9ICR7b3JnSWR9XG4gICAgICBgKSk7XG4gICAgICByZXR1cm4gKGRyaXp6bGVSb3dzPFBsdWdpblN1bW1hcnk+KHJvd3Mucm93cylbMF0gfHwgeyB0b3RhbDogMCwgYWN0aXZlOiAwLCBpbmFjdGl2ZTogMCwgcHVibGljOiAwLCBwcml2YXRlOiAwLCB1bmlxdWVOYW1lczogMCB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiAyLjIgVHlwZSAmIGNvbXB1dGUgZGlzdHJpYnV0aW9uLiAqL1xuICBhc3luYyBnZXRQbHVnaW5EaXN0cmlidXRpb24ob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8VHlwZUNvbXB1dGVEaXN0cmlidXRpb25bXT4ge1xuICAgIHJldHVybiBpbnZlbnRvcnlDYWNoZS5nZXRPclNldChgJHtvcmdJZH06cGx1Z2luLWRpc3RyaWJ1dGlvbmAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgJHtzY2hlbWEucGx1Z2luLnBsdWdpblR5cGV9IEFTIHBsdWdpbl90eXBlLFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5jb21wdXRlVHlwZX0gQVMgY29tcHV0ZV90eXBlLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgY291bnRcbiAgICAgICAgRlJPTSAke3NjaGVtYS5wbHVnaW59XG4gICAgICAgIFdIRVJFICR7c2NoZW1hLnBsdWdpbi5vcmdJZH0gPSAke29yZ0lkfSBBTkQgJHtzY2hlbWEucGx1Z2luLmlzQWN0aXZlfSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgJHtzY2hlbWEucGx1Z2luLnBsdWdpblR5cGV9LCAke3NjaGVtYS5wbHVnaW4uY29tcHV0ZVR5cGV9XG4gICAgICAgIE9SREVSIEJZIGNvdW50IERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxUeXBlQ29tcHV0ZURpc3RyaWJ1dGlvbj4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cblxuICAvKiogMi4zIFZlcnNpb24gY291bnRzIHBlciBwbHVnaW4gbmFtZS4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luVmVyc2lvbnMob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8VmVyc2lvbkNvdW50W10+IHtcbiAgICByZXR1cm4gaW52ZW50b3J5Q2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnBsdWdpbi12ZXJzaW9uc2AsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgJHtzY2hlbWEucGx1Z2luLm5hbWV9LFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdmVyc2lvbl9jb3VudCxcbiAgICAgICAgICBNQVgoJHtzY2hlbWEucGx1Z2luLnZlcnNpb259KSBBUyBsYXRlc3RfdmVyc2lvbixcbiAgICAgICAgICBib29sX29yKCR7c2NoZW1hLnBsdWdpbi5pc0RlZmF1bHR9KSBBUyBoYXNfZGVmYXVsdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBsdWdpbn1cbiAgICAgICAgV0hFUkUgJHtzY2hlbWEucGx1Z2luLm9yZ0lkfSA9ICR7b3JnSWR9IEFORCAke3NjaGVtYS5wbHVnaW4uaXNBY3RpdmV9ID0gdHJ1ZVxuICAgICAgICBHUk9VUCBCWSAke3NjaGVtYS5wbHVnaW4ubmFtZX1cbiAgICAgICAgT1JERVIgQlkgdmVyc2lvbl9jb3VudCBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8VmVyc2lvbkNvdW50PihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAyLjQgQnVpbGQgc3VjY2VzcyByYXRlIG92ZXIgdGltZS5cbiAgICpcbiAgICogU1RBVFVTIENBU0lORyBOT1RFOiBUaGlzIHF1ZXJ5IGZpbHRlcnMgYnkgYGV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnYFxuICAgKiBhbmQgdXNlcyBsb3dlcmNhc2Ugc3RhdHVzIHZhbHVlcyAoYCdjb21wbGV0ZWQnYCwgYCdmYWlsZWQnYCksIHdoaWxlXG4gICAqIGBnZXRTdWNjZXNzUmF0ZWAgKDEuMikgZmlsdGVycyBieSBgZXZlbnRfdHlwZSA9ICdQSVBFTElORSdgIHdpdGhcbiAgICogdXBwZXJjYXNlIEFXUy1zdHlsZSBzdGF0dXNlcyAoYCdTVUNDRUVERUQnYCwgYCdGQUlMRUQnYCwgYCdDQU5DRUxFRCdgKS5cbiAgICogVGhlIGNhc2luZyBkcmlmdCBpcyBpbnRlbnRpb25hbCBhbmQgdHJhY2tzIHRoZSBwcm9kdWNlcjpcbiAgICogICAtIGBwbHVnaW4tYnVpbGRgIGV2ZW50cyBjb21lIGZyb20gb3VyIG93biBidWlsZCBwaXBlbGluZSAobG93ZXJjYXNlKVxuICAgKiAgIC0gYFBJUEVMSU5FYCBldmVudHMgY29tZSBmcm9tIEFXUyBDb2RlUGlwZWxpbmUgKHVwcGVyY2FzZSlcbiAgICogVGhlIGluZ2VzdCBab2Qgc2NoZW1hIGF0IGFwaS9yZXBvcnRpbmcvc3JjL3JvdXRlcy9ldmVudC1pbmdlc3QudHNcbiAgICogU0hPVUxEIGVudW0gdGhlc2UgcGVyLWV2ZW50U291cmNlIHNvIHdlIGNhdGNoIGRyaWZ0IGF0IGluZ2VzdCByYXRoZXJcbiAgICogdGhhbiBzaWxlbnRseSBwcm9kdWNpbmcgemVybyByb3dzIGhlcmUuIFNlZSBmaW5kaW5ncyBONzEuXG4gICAqL1xuICBhc3luYyBnZXRCdWlsZFN1Y2Nlc3NSYXRlKG9yZ0lkOiBzdHJpbmcsIGludGVydmFsOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IFByb21pc2U8QnVpbGRUaW1lU2VyaWVzRW50cnlbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmJ1aWxkLXN1Y2Nlc3M6JHtpbnRlcnZhbH06JHtmcm9tfToke3RvfWAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgREFURV9UUlVOQygke2ludGVydmFsfSwgZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBwZXJpb2QsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdjb21wbGV0ZWQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ2ZhaWxlZCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnY29tcGxldGVkJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIHN1Y2Nlc3NfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnXG4gICAgICAgICAgQU5EIGUuc3RhdHVzIElOICgnY29tcGxldGVkJywgJ2ZhaWxlZCcpXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwZXJpb2QgT1JERVIgQlkgcGVyaW9kXG4gICAgICBgKS50aGVuKHIgPT4gZHJpenpsZVJvd3M8QnVpbGRUaW1lU2VyaWVzRW50cnk+KHIucm93cykpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDIuNSBCdWlsZCBkdXJhdGlvbiBwZXIgcGx1Z2luLiAqL1xuICBhc3luYyBnZXRCdWlsZER1cmF0aW9uKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IFByb21pc2U8QnVpbGREdXJhdGlvbltdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06YnVpbGQtZHVyYXRpb246JHtmcm9tfToke3RvfWAsICgpID0+XG4gICAgICB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5kZXRhaWwtPj4ncGx1Z2luTmFtZScgQVMgcGx1Z2luX25hbWUsXG4gICAgICAgICAgQVZHKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgYXZnX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIGJ1aWxkc1xuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgV0hFUkUgZS5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF9zb3VyY2UgPSAncGx1Z2luLWJ1aWxkJyBBTkQgZS5kdXJhdGlvbl9tcyBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgcGx1Z2luX25hbWUgT1JERVIgQlkgYXZnX21zIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBkcml6emxlUm93czxCdWlsZER1cmF0aW9uPihyLnJvd3MpKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAyLjYgQnVpbGQgZmFpbHVyZXMg4oCUIHRvcCBlcnJvciBtZXNzYWdlcy4gKi9cbiAgYXN5bmMgZ2V0QnVpbGRGYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcsIGxpbWl0OiBudW1iZXIgPSAyMCk6IFByb21pc2U8QnVpbGRGYWlsdXJlW10+IHtcbiAgICByZXR1cm4gdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpidWlsZC1mYWlsdXJlczoke2Zyb219OiR7dG99OiR7bGltaXR9YCwgKCkgPT5cbiAgICAgIHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLmRldGFpbC0+PidwbHVnaW5OYW1lJyBBUyBwbHVnaW5fbmFtZSxcbiAgICAgICAgICBlLmVycm9yX21lc3NhZ2UsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyBvY2N1cnJlbmNlcyxcbiAgICAgICAgICBNQVgoZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBsYXN0X3NlZW5cbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIFdIRVJFIGUub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfc291cmNlID0gJ3BsdWdpbi1idWlsZCcgQU5EIGUuc3RhdHVzID0gJ2ZhaWxlZCdcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIHBsdWdpbl9uYW1lLCBlLmVycm9yX21lc3NhZ2VcbiAgICAgICAgT1JERVIgQlkgb2NjdXJyZW5jZXMgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCkudGhlbihyID0+IGRyaXp6bGVSb3dzPEJ1aWxkRmFpbHVyZT4oci5yb3dzKSkpLFxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHJlcG9ydGluZ1NlcnZpY2UgPSBuZXcgUmVwb3J0aW5nU2VydmljZSgpO1xuIl19
|