@pipeline-builder/pipeline-data 3.1.0
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/LICENSE +202 -0
- package/README.md +34 -0
- package/drizzle.config.ts +17 -0
- package/lib/api/access-control-builder.d.ts +109 -0
- package/lib/api/access-control-builder.js +181 -0
- package/lib/api/crud-service.d.ts +170 -0
- package/lib/api/crud-service.js +387 -0
- package/lib/api/query-builders.d.ts +74 -0
- package/lib/api/query-builders.js +336 -0
- package/lib/api/reporting-service.d.ts +131 -0
- package/lib/api/reporting-service.js +248 -0
- package/lib/core/query-filters.d.ts +235 -0
- package/lib/core/query-filters.js +23 -0
- package/lib/database/drizzle-schema.d.ts +10043 -0
- package/lib/database/drizzle-schema.js +715 -0
- package/lib/database/index.d.ts +3 -0
- package/lib/database/index.js +22 -0
- package/lib/database/postgres-connection.d.ts +232 -0
- package/lib/database/postgres-connection.js +456 -0
- package/lib/database/retry-strategy.d.ts +68 -0
- package/lib/database/retry-strategy.js +126 -0
- package/lib/index.d.ts +30 -0
- package/lib/index.js +52 -0
- package/package.json +125 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.reportingService = exports.ReportingService = void 0;
|
|
6
|
+
const api_core_1 = require("@pipeline-builder/api-core");
|
|
7
|
+
const drizzle_orm_1 = require("drizzle-orm");
|
|
8
|
+
const crud_service_1 = require("./crud-service");
|
|
9
|
+
const drizzle_schema_1 = require("../database/drizzle-schema");
|
|
10
|
+
const postgres_connection_1 = require("../database/postgres-connection");
|
|
11
|
+
/** Cast raw SQL result rows to a typed array. Alias for drizzleRows. */
|
|
12
|
+
const sqlRows = (result) => (0, crud_service_1.drizzleRows)(result.rows);
|
|
13
|
+
/**
|
|
14
|
+
* Cache for reporting aggregations. Two tiers:
|
|
15
|
+
* - Inventory queries (plugin summary/distribution/versions): 5 min TTL — changes on plugin CRUD
|
|
16
|
+
* - Execution/build queries with date ranges: 2 min TTL — new events arrive continuously
|
|
17
|
+
*/
|
|
18
|
+
const inventoryCache = (0, api_core_1.createCacheService)('report:inv:', parseInt(process.env.CACHE_TTL_REPORT_INVENTORY || '300', 10));
|
|
19
|
+
const timeseriesCache = (0, api_core_1.createCacheService)('report:ts:', parseInt(process.env.CACHE_TTL_REPORT_TIMESERIES || '120', 10));
|
|
20
|
+
// ─── Service ────────────────────────────────────────────
|
|
21
|
+
/**
|
|
22
|
+
* Read-only reporting service for pipeline execution and plugin inventory aggregations.
|
|
23
|
+
* Does not extend CrudService — reports are aggregate queries, not entity CRUD.
|
|
24
|
+
*
|
|
25
|
+
* All queries are cached in-memory to avoid repeated expensive SQL aggregations:
|
|
26
|
+
* - Inventory queries (plugin summary/distribution/versions): 5 min TTL
|
|
27
|
+
* - Timeseries queries (execution/build metrics with date ranges): 2 min TTL
|
|
28
|
+
*/
|
|
29
|
+
class ReportingService {
|
|
30
|
+
/** Invalidate all cached reports for an org (call after event ingest). */
|
|
31
|
+
async invalidateOrg(orgId) {
|
|
32
|
+
await Promise.all([
|
|
33
|
+
inventoryCache.invalidatePattern(`${orgId}:*`),
|
|
34
|
+
timeseriesCache.invalidatePattern(`${orgId}:*`),
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
// ── Category 1: Pipeline Execution & Performance ──
|
|
38
|
+
/** 1.1 Execution count per pipeline with status breakdown. */
|
|
39
|
+
async getExecutionCount(orgId) {
|
|
40
|
+
return timeseriesCache.getOrSet(`${orgId}:exec-count`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
41
|
+
SELECT
|
|
42
|
+
p.id, p.project, p.organization, p.pipeline_name,
|
|
43
|
+
COUNT(*)::int AS total,
|
|
44
|
+
COUNT(*) FILTER (WHERE e.status = 'SUCCEEDED')::int AS succeeded,
|
|
45
|
+
COUNT(*) FILTER (WHERE e.status = 'FAILED')::int AS failed,
|
|
46
|
+
COUNT(*) FILTER (WHERE e.status = 'CANCELED')::int AS canceled,
|
|
47
|
+
MIN(e.started_at)::text AS first_execution,
|
|
48
|
+
MAX(e.started_at)::text AS last_execution
|
|
49
|
+
FROM ${drizzle_schema_1.schema.pipeline} p
|
|
50
|
+
JOIN ${drizzle_schema_1.schema.pipelineEvent} e ON e.pipeline_id = p.id
|
|
51
|
+
AND e.event_type = 'PIPELINE' AND e.status != 'STARTED'
|
|
52
|
+
WHERE p.org_id = ${orgId} AND p.is_active = true
|
|
53
|
+
GROUP BY p.id
|
|
54
|
+
ORDER BY total DESC
|
|
55
|
+
`).then(r => sqlRows(r)));
|
|
56
|
+
}
|
|
57
|
+
/** 1.2 Success rate over time for an org. */
|
|
58
|
+
async getSuccessRate(orgId, interval, from, to) {
|
|
59
|
+
return timeseriesCache.getOrSet(`${orgId}:success-rate:${interval}:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
60
|
+
SELECT
|
|
61
|
+
DATE_TRUNC(${interval}, e.started_at)::text AS period,
|
|
62
|
+
COUNT(*) FILTER (WHERE e.status = 'SUCCEEDED')::int AS succeeded,
|
|
63
|
+
COUNT(*) FILTER (WHERE e.status = 'FAILED')::int AS failed,
|
|
64
|
+
COUNT(*) FILTER (WHERE e.status = 'CANCELED')::int AS canceled,
|
|
65
|
+
ROUND(COUNT(*) FILTER (WHERE e.status = 'SUCCEEDED')::numeric
|
|
66
|
+
/ NULLIF(COUNT(*), 0) * 100, 1)::float AS success_pct
|
|
67
|
+
FROM ${drizzle_schema_1.schema.pipelineEvent} e
|
|
68
|
+
JOIN ${drizzle_schema_1.schema.pipeline} p ON p.id = e.pipeline_id
|
|
69
|
+
WHERE p.org_id = ${orgId} AND e.event_type = 'PIPELINE'
|
|
70
|
+
AND e.status IN ('SUCCEEDED', 'FAILED', 'CANCELED')
|
|
71
|
+
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
72
|
+
GROUP BY period ORDER BY period
|
|
73
|
+
`).then(r => sqlRows(r)));
|
|
74
|
+
}
|
|
75
|
+
/** 1.3 Average duration per pipeline. */
|
|
76
|
+
async getAverageDuration(orgId, from, to) {
|
|
77
|
+
return timeseriesCache.getOrSet(`${orgId}:avg-duration:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
78
|
+
SELECT
|
|
79
|
+
p.id, p.project, p.pipeline_name,
|
|
80
|
+
AVG(e.duration_ms)::int AS avg_ms,
|
|
81
|
+
MIN(e.duration_ms)::int AS min_ms,
|
|
82
|
+
MAX(e.duration_ms)::int AS max_ms,
|
|
83
|
+
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY e.duration_ms)::int AS p95_ms,
|
|
84
|
+
COUNT(*)::int AS executions
|
|
85
|
+
FROM ${drizzle_schema_1.schema.pipelineEvent} e
|
|
86
|
+
JOIN ${drizzle_schema_1.schema.pipeline} p ON p.id = e.pipeline_id
|
|
87
|
+
WHERE p.org_id = ${orgId} AND e.event_type = 'PIPELINE' AND e.duration_ms IS NOT NULL
|
|
88
|
+
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
89
|
+
GROUP BY p.id ORDER BY avg_ms DESC
|
|
90
|
+
`).then(r => sqlRows(r)));
|
|
91
|
+
}
|
|
92
|
+
/** 1.5 Stage failure heatmap — which stages fail most. */
|
|
93
|
+
async getStageFailures(orgId, from, to) {
|
|
94
|
+
return timeseriesCache.getOrSet(`${orgId}:stage-failures:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
95
|
+
SELECT
|
|
96
|
+
e.stage_name,
|
|
97
|
+
COUNT(*) FILTER (WHERE e.status = 'FAILED')::int AS failures,
|
|
98
|
+
COUNT(*)::int AS total,
|
|
99
|
+
ROUND(COUNT(*) FILTER (WHERE e.status = 'FAILED')::numeric
|
|
100
|
+
/ NULLIF(COUNT(*), 0) * 100, 1)::float AS failure_pct
|
|
101
|
+
FROM ${drizzle_schema_1.schema.pipelineEvent} e
|
|
102
|
+
JOIN ${drizzle_schema_1.schema.pipeline} p ON p.id = e.pipeline_id
|
|
103
|
+
WHERE p.org_id = ${orgId} AND e.event_type = 'STAGE' AND e.stage_name IS NOT NULL
|
|
104
|
+
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
105
|
+
GROUP BY e.stage_name ORDER BY failures DESC
|
|
106
|
+
`).then(r => sqlRows(r)));
|
|
107
|
+
}
|
|
108
|
+
/** 1.6 Stage bottlenecks — slowest stages per pipeline. */
|
|
109
|
+
async getStageBottlenecks(orgId, from, to) {
|
|
110
|
+
return timeseriesCache.getOrSet(`${orgId}:stage-bottlenecks:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
111
|
+
SELECT
|
|
112
|
+
p.id, p.pipeline_name, e.stage_name,
|
|
113
|
+
AVG(e.duration_ms)::int AS avg_ms,
|
|
114
|
+
MAX(e.duration_ms)::int AS max_ms
|
|
115
|
+
FROM ${drizzle_schema_1.schema.pipelineEvent} e
|
|
116
|
+
JOIN ${drizzle_schema_1.schema.pipeline} p ON p.id = e.pipeline_id
|
|
117
|
+
WHERE p.org_id = ${orgId} AND e.event_type = 'STAGE' AND e.duration_ms IS NOT NULL
|
|
118
|
+
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
119
|
+
GROUP BY p.id, e.stage_name ORDER BY avg_ms DESC
|
|
120
|
+
`).then(r => sqlRows(r)));
|
|
121
|
+
}
|
|
122
|
+
/** 1.7 Action failure rate — which plugin steps fail most. */
|
|
123
|
+
async getActionFailures(orgId, from, to) {
|
|
124
|
+
return timeseriesCache.getOrSet(`${orgId}:action-failures:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
125
|
+
SELECT
|
|
126
|
+
e.action_name,
|
|
127
|
+
COUNT(*) FILTER (WHERE e.status = 'FAILED')::int AS failures,
|
|
128
|
+
COUNT(*)::int AS total,
|
|
129
|
+
ROUND(COUNT(*) FILTER (WHERE e.status = 'FAILED')::numeric
|
|
130
|
+
/ NULLIF(COUNT(*), 0) * 100, 1)::float AS failure_pct
|
|
131
|
+
FROM ${drizzle_schema_1.schema.pipelineEvent} e
|
|
132
|
+
JOIN ${drizzle_schema_1.schema.pipeline} p ON p.id = e.pipeline_id
|
|
133
|
+
WHERE p.org_id = ${orgId} AND e.event_type = 'ACTION' AND e.action_name IS NOT NULL
|
|
134
|
+
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
135
|
+
GROUP BY e.action_name ORDER BY failures DESC
|
|
136
|
+
`).then(r => sqlRows(r)));
|
|
137
|
+
}
|
|
138
|
+
/** 1.8 Error categorization — group failure messages. */
|
|
139
|
+
async getErrors(orgId, from, to, limit = 20) {
|
|
140
|
+
return timeseriesCache.getOrSet(`${orgId}:errors:${from}:${to}:${limit}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
141
|
+
SELECT
|
|
142
|
+
SUBSTRING(e.error_message FROM 1 FOR 200) AS error_pattern,
|
|
143
|
+
COUNT(*)::int AS occurrences,
|
|
144
|
+
COUNT(DISTINCT e.pipeline_id)::int AS affected_pipelines,
|
|
145
|
+
MAX(e.started_at)::text AS last_seen
|
|
146
|
+
FROM ${drizzle_schema_1.schema.pipelineEvent} e
|
|
147
|
+
JOIN ${drizzle_schema_1.schema.pipeline} p ON p.id = e.pipeline_id
|
|
148
|
+
WHERE p.org_id = ${orgId} AND e.status = 'FAILED' AND e.error_message IS NOT NULL
|
|
149
|
+
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
150
|
+
GROUP BY error_pattern ORDER BY occurrences DESC
|
|
151
|
+
LIMIT ${limit}
|
|
152
|
+
`).then(r => sqlRows(r)));
|
|
153
|
+
}
|
|
154
|
+
// ── Category 2: Plugin Inventory & Builds ──
|
|
155
|
+
/** 2.1 Plugin summary — counts and breakdowns. */
|
|
156
|
+
async getPluginSummary(orgId) {
|
|
157
|
+
return inventoryCache.getOrSet(`${orgId}:plugin-summary`, async () => {
|
|
158
|
+
const rows = await postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
159
|
+
SELECT
|
|
160
|
+
COUNT(*)::int AS total,
|
|
161
|
+
COUNT(*) FILTER (WHERE ${drizzle_schema_1.schema.plugin.isActive})::int AS active,
|
|
162
|
+
COUNT(*) FILTER (WHERE NOT ${drizzle_schema_1.schema.plugin.isActive})::int AS inactive,
|
|
163
|
+
COUNT(*) FILTER (WHERE ${drizzle_schema_1.schema.plugin.accessModifier} = 'public')::int AS public,
|
|
164
|
+
COUNT(*) FILTER (WHERE ${drizzle_schema_1.schema.plugin.accessModifier} = 'private')::int AS private,
|
|
165
|
+
COUNT(DISTINCT ${drizzle_schema_1.schema.plugin.name})::int AS unique_names
|
|
166
|
+
FROM ${drizzle_schema_1.schema.plugin}
|
|
167
|
+
WHERE ${drizzle_schema_1.schema.plugin.orgId} = ${orgId}
|
|
168
|
+
`);
|
|
169
|
+
return (sqlRows(rows)[0] || { total: 0, active: 0, inactive: 0, public: 0, private: 0, uniqueNames: 0 });
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/** 2.2 Type & compute distribution. */
|
|
173
|
+
async getPluginDistribution(orgId) {
|
|
174
|
+
return inventoryCache.getOrSet(`${orgId}:plugin-distribution`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
175
|
+
SELECT
|
|
176
|
+
${drizzle_schema_1.schema.plugin.pluginType} AS plugin_type,
|
|
177
|
+
${drizzle_schema_1.schema.plugin.computeType} AS compute_type,
|
|
178
|
+
COUNT(*)::int AS count
|
|
179
|
+
FROM ${drizzle_schema_1.schema.plugin}
|
|
180
|
+
WHERE ${drizzle_schema_1.schema.plugin.orgId} = ${orgId} AND ${drizzle_schema_1.schema.plugin.isActive} = true
|
|
181
|
+
GROUP BY ${drizzle_schema_1.schema.plugin.pluginType}, ${drizzle_schema_1.schema.plugin.computeType}
|
|
182
|
+
ORDER BY count DESC
|
|
183
|
+
`).then(r => sqlRows(r)));
|
|
184
|
+
}
|
|
185
|
+
/** 2.3 Version counts per plugin name. */
|
|
186
|
+
async getPluginVersions(orgId) {
|
|
187
|
+
return inventoryCache.getOrSet(`${orgId}:plugin-versions`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
188
|
+
SELECT
|
|
189
|
+
${drizzle_schema_1.schema.plugin.name},
|
|
190
|
+
COUNT(*)::int AS version_count,
|
|
191
|
+
MAX(${drizzle_schema_1.schema.plugin.version}) AS latest_version,
|
|
192
|
+
bool_or(${drizzle_schema_1.schema.plugin.isDefault}) AS has_default
|
|
193
|
+
FROM ${drizzle_schema_1.schema.plugin}
|
|
194
|
+
WHERE ${drizzle_schema_1.schema.plugin.orgId} = ${orgId} AND ${drizzle_schema_1.schema.plugin.isActive} = true
|
|
195
|
+
GROUP BY ${drizzle_schema_1.schema.plugin.name}
|
|
196
|
+
ORDER BY version_count DESC
|
|
197
|
+
`).then(r => sqlRows(r)));
|
|
198
|
+
}
|
|
199
|
+
/** 2.4 Build success rate over time. */
|
|
200
|
+
async getBuildSuccessRate(orgId, interval, from, to) {
|
|
201
|
+
return timeseriesCache.getOrSet(`${orgId}:build-success:${interval}:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
202
|
+
SELECT
|
|
203
|
+
DATE_TRUNC(${interval}, e.started_at)::text AS period,
|
|
204
|
+
COUNT(*) FILTER (WHERE e.status = 'completed')::int AS succeeded,
|
|
205
|
+
COUNT(*) FILTER (WHERE e.status = 'failed')::int AS failed,
|
|
206
|
+
ROUND(COUNT(*) FILTER (WHERE e.status = 'completed')::numeric
|
|
207
|
+
/ NULLIF(COUNT(*), 0) * 100, 1)::float AS success_pct
|
|
208
|
+
FROM ${drizzle_schema_1.schema.pipelineEvent} e
|
|
209
|
+
WHERE e.org_id = ${orgId} AND e.event_source = 'plugin-build'
|
|
210
|
+
AND e.status IN ('completed', 'failed')
|
|
211
|
+
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
212
|
+
GROUP BY period ORDER BY period
|
|
213
|
+
`).then(r => sqlRows(r)));
|
|
214
|
+
}
|
|
215
|
+
/** 2.5 Build duration per plugin. */
|
|
216
|
+
async getBuildDuration(orgId, from, to) {
|
|
217
|
+
return timeseriesCache.getOrSet(`${orgId}:build-duration:${from}:${to}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
218
|
+
SELECT
|
|
219
|
+
e.detail->>'pluginName' AS plugin_name,
|
|
220
|
+
AVG(e.duration_ms)::int AS avg_ms,
|
|
221
|
+
MAX(e.duration_ms)::int AS max_ms,
|
|
222
|
+
COUNT(*)::int AS builds
|
|
223
|
+
FROM ${drizzle_schema_1.schema.pipelineEvent} e
|
|
224
|
+
WHERE e.org_id = ${orgId} AND e.event_source = 'plugin-build' AND e.duration_ms IS NOT NULL
|
|
225
|
+
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
226
|
+
GROUP BY plugin_name ORDER BY avg_ms DESC
|
|
227
|
+
`).then(r => sqlRows(r)));
|
|
228
|
+
}
|
|
229
|
+
/** 2.6 Build failures — top error messages. */
|
|
230
|
+
async getBuildFailures(orgId, from, to, limit = 20) {
|
|
231
|
+
return timeseriesCache.getOrSet(`${orgId}:build-failures:${from}:${to}:${limit}`, () => postgres_connection_1.db.execute((0, drizzle_orm_1.sql) `
|
|
232
|
+
SELECT
|
|
233
|
+
e.detail->>'pluginName' AS plugin_name,
|
|
234
|
+
e.error_message,
|
|
235
|
+
COUNT(*)::int AS occurrences,
|
|
236
|
+
MAX(e.started_at)::text AS last_seen
|
|
237
|
+
FROM ${drizzle_schema_1.schema.pipelineEvent} e
|
|
238
|
+
WHERE e.org_id = ${orgId} AND e.event_source = 'plugin-build' AND e.status = 'failed'
|
|
239
|
+
AND e.started_at >= ${from}::timestamptz AND e.started_at <= ${to}::timestamptz
|
|
240
|
+
GROUP BY plugin_name, e.error_message
|
|
241
|
+
ORDER BY occurrences DESC
|
|
242
|
+
LIMIT ${limit}
|
|
243
|
+
`).then(r => sqlRows(r)));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
exports.ReportingService = ReportingService;
|
|
247
|
+
exports.reportingService = new ReportingService();
|
|
248
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0aW5nLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JlcG9ydGluZy1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDOzs7QUFFdEMseURBQWdFO0FBQ2hFLDZDQUFrQztBQUNsQyxpREFBNkM7QUFDN0MsK0RBQW9EO0FBQ3BELHlFQUFxRDtBQUVyRCx3RUFBd0U7QUFDeEUsTUFBTSxPQUFPLEdBQUcsQ0FBSSxNQUEyQixFQUFPLEVBQUUsQ0FBQyxJQUFBLDBCQUFXLEVBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBRXJGOzs7O0dBSUc7QUFDSCxNQUFNLGNBQWMsR0FBRyxJQUFBLDZCQUFrQixFQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsSUFBSSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN4SCxNQUFNLGVBQWUsR0FBRyxJQUFBLDZCQUFrQixFQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsSUFBSSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQTRHekgsMkRBQTJEO0FBRTNEOzs7Ozs7O0dBT0c7QUFDSCxNQUFhLGdCQUFnQjtJQUUzQiwwRUFBMEU7SUFDMUUsS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFhO1FBQy9CLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztZQUNoQixjQUFjLENBQUMsaUJBQWlCLENBQUMsR0FBRyxLQUFLLElBQUksQ0FBQztZQUM5QyxlQUFlLENBQUMsaUJBQWlCLENBQUMsR0FBRyxLQUFLLElBQUksQ0FBQztTQUNoRCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQscURBQXFEO0lBRXJELDhEQUE4RDtJQUM5RCxLQUFLLENBQUMsaUJBQWlCLENBQUMsS0FBYTtRQUNuQyxPQUFPLGVBQWUsQ0FB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Q3JDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFhLEVBQUUsSUFBWSxFQUFFLEVBQVU7UUFDNUQsT0FBTyxlQUFlLENBQUMsUUFBUSxDQUFDLEdBQUcsS0FBSyxtQkFBbUIsSUFBSSxJQUFJLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUM1RSx3QkFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFBLGlCQUFHLEVBQUE7Ozs7OztlQU1MLHVCQUFNLENBQUMsYUFBYTsyQkFDUixLQUFLO2dDQUNBLElBQUkscUNBQXFDLEVBQUU7O09BRXBFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQWdCLENBQUMsQ0FBQyxDQUFDLENBQ3hDLENBQUM7SUFDSixDQUFDO0lBRUQsK0NBQStDO0lBQy9DLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFhLEVBQUUsSUFBWSxFQUFFLEVBQVUsRUFBRSxRQUFnQixFQUFFO1FBQ2hGLE9BQU8sZUFBZSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEtBQUssbUJBQW1CLElBQUksSUFBSSxFQUFFLElBQUksS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQ3JGLHdCQUFFLENBQUMsT0FBTyxDQUFDLElBQUEsaUJBQUcsRUFBQTs7Ozs7O2VBTUwsdUJBQU0sQ0FBQyxhQUFhOzJCQUNSLEtBQUs7Z0NBQ0EsSUFBSSxxQ0FBcUMsRUFBRTs7O2dCQUczRCxLQUFLO09BQ2QsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBZSxDQUFDLENBQUMsQ0FBQyxDQUN2QyxDQUFDO0lBQ0osQ0FBQztDQUNGO0FBaFFELDRDQWdRQztBQUVZLFFBQUEsZ0JBQWdCLEdBQUcsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IGNyZWF0ZUNhY2hlU2VydmljZSB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IGRyaXp6bGVSb3dzIH0gZnJvbSAnLi9jcnVkLXNlcnZpY2UnO1xuaW1wb3J0IHsgc2NoZW1hIH0gZnJvbSAnLi4vZGF0YWJhc2UvZHJpenpsZS1zY2hlbWEnO1xuaW1wb3J0IHsgZGIgfSBmcm9tICcuLi9kYXRhYmFzZS9wb3N0Z3Jlcy1jb25uZWN0aW9uJztcblxuLyoqIENhc3QgcmF3IFNRTCByZXN1bHQgcm93cyB0byBhIHR5cGVkIGFycmF5LiBBbGlhcyBmb3IgZHJpenpsZVJvd3MuICovXG5jb25zdCBzcWxSb3dzID0gPFQ+KHJlc3VsdDogeyByb3dzOiB1bmtub3duW10gfSk6IFRbXSA9PiBkcml6emxlUm93czxUPihyZXN1bHQucm93cyk7XG5cbi8qKlxuICogQ2FjaGUgZm9yIHJlcG9ydGluZyBhZ2dyZWdhdGlvbnMuIFR3byB0aWVyczpcbiAqIC0gSW52ZW50b3J5IHF1ZXJpZXMgKHBsdWdpbiBzdW1tYXJ5L2Rpc3RyaWJ1dGlvbi92ZXJzaW9ucyk6IDUgbWluIFRUTCDigJQgY2hhbmdlcyBvbiBwbHVnaW4gQ1JVRFxuICogLSBFeGVjdXRpb24vYnVpbGQgcXVlcmllcyB3aXRoIGRhdGUgcmFuZ2VzOiAyIG1pbiBUVEwg4oCUIG5ldyBldmVudHMgYXJyaXZlIGNvbnRpbnVvdXNseVxuICovXG5jb25zdCBpbnZlbnRvcnlDYWNoZSA9IGNyZWF0ZUNhY2hlU2VydmljZSgncmVwb3J0OmludjonLCBwYXJzZUludChwcm9jZXNzLmVudi5DQUNIRV9UVExfUkVQT1JUX0lOVkVOVE9SWSB8fCAnMzAwJywgMTApKTtcbmNvbnN0IHRpbWVzZXJpZXNDYWNoZSA9IGNyZWF0ZUNhY2hlU2VydmljZSgncmVwb3J0OnRzOicsIHBhcnNlSW50KHByb2Nlc3MuZW52LkNBQ0hFX1RUTF9SRVBPUlRfVElNRVNFUklFUyB8fCAnMTIwJywgMTApKTtcblxuLy8g4pSA4pSA4pSAIFR5cGVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5pbnRlcmZhY2UgRXhlY3V0aW9uQ291bnQge1xuICBpZDogc3RyaW5nO1xuICBwcm9qZWN0OiBzdHJpbmc7XG4gIG9yZ2FuaXphdGlvbjogc3RyaW5nO1xuICBwaXBlbGluZU5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHRvdGFsOiBudW1iZXI7XG4gIHN1Y2NlZWRlZDogbnVtYmVyO1xuICBmYWlsZWQ6IG51bWJlcjtcbiAgY2FuY2VsZWQ6IG51bWJlcjtcbiAgZmlyc3RFeGVjdXRpb246IHN0cmluZyB8IG51bGw7XG4gIGxhc3RFeGVjdXRpb246IHN0cmluZyB8IG51bGw7XG59XG5cbmludGVyZmFjZSBUaW1lU2VyaWVzRW50cnkge1xuICBwZXJpb2Q6IHN0cmluZztcbiAgc3VjY2VlZGVkOiBudW1iZXI7XG4gIGZhaWxlZDogbnVtYmVyO1xuICBjYW5jZWxlZDogbnVtYmVyO1xuICBzdWNjZXNzUGN0OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBEdXJhdGlvblN0YXRzIHtcbiAgaWQ6IHN0cmluZztcbiAgcHJvamVjdDogc3RyaW5nO1xuICBwaXBlbGluZU5hbWU6IHN0cmluZyB8IG51bGw7XG4gIGF2Z01zOiBudW1iZXI7XG4gIG1pbk1zOiBudW1iZXI7XG4gIG1heE1zOiBudW1iZXI7XG4gIHA5NU1zOiBudW1iZXI7XG4gIGV4ZWN1dGlvbnM6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFN0YWdlRmFpbHVyZSB7XG4gIHN0YWdlTmFtZTogc3RyaW5nO1xuICBmYWlsdXJlczogbnVtYmVyO1xuICB0b3RhbDogbnVtYmVyO1xuICBmYWlsdXJlUGN0OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBTdGFnZUJvdHRsZW5lY2sge1xuICBpZDogc3RyaW5nO1xuICBwaXBlbGluZU5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHN0YWdlTmFtZTogc3RyaW5nO1xuICBhdmdNczogbnVtYmVyO1xuICBtYXhNczogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQWN0aW9uRmFpbHVyZSB7XG4gIGFjdGlvbk5hbWU6IHN0cmluZztcbiAgZmFpbHVyZXM6IG51bWJlcjtcbiAgdG90YWw6IG51bWJlcjtcbiAgZmFpbHVyZVBjdDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgRXJyb3JFbnRyeSB7XG4gIGVycm9yUGF0dGVybjogc3RyaW5nO1xuICBvY2N1cnJlbmNlczogbnVtYmVyO1xuICBhZmZlY3RlZFBpcGVsaW5lczogbnVtYmVyO1xuICBsYXN0U2Vlbjogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUGx1Z2luU3VtbWFyeSB7XG4gIHRvdGFsOiBudW1iZXI7XG4gIGFjdGl2ZTogbnVtYmVyO1xuICBpbmFjdGl2ZTogbnVtYmVyO1xuICBwdWJsaWM6IG51bWJlcjtcbiAgcHJpdmF0ZTogbnVtYmVyO1xuICB1bmlxdWVOYW1lczogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgVHlwZUNvbXB1dGVEaXN0cmlidXRpb24ge1xuICBwbHVnaW5UeXBlOiBzdHJpbmc7XG4gIGNvbXB1dGVUeXBlOiBzdHJpbmc7XG4gIGNvdW50OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBWZXJzaW9uQ291bnQge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZlcnNpb25Db3VudDogbnVtYmVyO1xuICBsYXRlc3RWZXJzaW9uOiBzdHJpbmc7XG4gIGhhc0RlZmF1bHQ6IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBCdWlsZFRpbWVTZXJpZXNFbnRyeSB7XG4gIHBlcmlvZDogc3RyaW5nO1xuICBzdWNjZWVkZWQ6IG51bWJlcjtcbiAgZmFpbGVkOiBudW1iZXI7XG4gIHN1Y2Nlc3NQY3Q6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIEJ1aWxkRHVyYXRpb24ge1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIGF2Z01zOiBudW1iZXI7XG4gIG1heE1zOiBudW1iZXI7XG4gIGJ1aWxkczogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQnVpbGRGYWlsdXJlIHtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBlcnJvck1lc3NhZ2U6IHN0cmluZztcbiAgb2NjdXJyZW5jZXM6IG51bWJlcjtcbiAgbGFzdFNlZW46IHN0cmluZztcbn1cblxuLy8g4pSA4pSA4pSAIFNlcnZpY2Ug4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8qKlxuICogUmVhZC1vbmx5IHJlcG9ydGluZyBzZXJ2aWNlIGZvciBwaXBlbGluZSBleGVjdXRpb24gYW5kIHBsdWdpbiBpbnZlbnRvcnkgYWdncmVnYXRpb25zLlxuICogRG9lcyBub3QgZXh0ZW5kIENydWRTZXJ2aWNlIOKAlCByZXBvcnRzIGFyZSBhZ2dyZWdhdGUgcXVlcmllcywgbm90IGVudGl0eSBDUlVELlxuICpcbiAqIEFsbCBxdWVyaWVzIGFyZSBjYWNoZWQgaW4tbWVtb3J5IHRvIGF2b2lkIHJlcGVhdGVkIGV4cGVuc2l2ZSBTUUwgYWdncmVnYXRpb25zOlxuICogLSBJbnZlbnRvcnkgcXVlcmllcyAocGx1Z2luIHN1bW1hcnkvZGlzdHJpYnV0aW9uL3ZlcnNpb25zKTogNSBtaW4gVFRMXG4gKiAtIFRpbWVzZXJpZXMgcXVlcmllcyAoZXhlY3V0aW9uL2J1aWxkIG1ldHJpY3Mgd2l0aCBkYXRlIHJhbmdlcyk6IDIgbWluIFRUTFxuICovXG5leHBvcnQgY2xhc3MgUmVwb3J0aW5nU2VydmljZSB7XG5cbiAgLyoqIEludmFsaWRhdGUgYWxsIGNhY2hlZCByZXBvcnRzIGZvciBhbiBvcmcgKGNhbGwgYWZ0ZXIgZXZlbnQgaW5nZXN0KS4gKi9cbiAgYXN5bmMgaW52YWxpZGF0ZU9yZyhvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgaW52ZW50b3J5Q2FjaGUuaW52YWxpZGF0ZVBhdHRlcm4oYCR7b3JnSWR9OipgKSxcbiAgICAgIHRpbWVzZXJpZXNDYWNoZS5pbnZhbGlkYXRlUGF0dGVybihgJHtvcmdJZH06KmApLFxuICAgIF0pO1xuICB9XG5cbiAgLy8g4pSA4pSAIENhdGVnb3J5IDE6IFBpcGVsaW5lIEV4ZWN1dGlvbiAmIFBlcmZvcm1hbmNlIOKUgOKUgFxuXG4gIC8qKiAxLjEgRXhlY3V0aW9uIGNvdW50IHBlciBwaXBlbGluZSB3aXRoIHN0YXR1cyBicmVha2Rvd24uICovXG4gIGFzeW5jIGdldEV4ZWN1dGlvbkNvdW50KG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPEV4ZWN1dGlvbkNvdW50W10+IHtcbiAgICByZXR1cm4gdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpleGVjLWNvdW50YCwgKCkgPT5cbiAgICAgIGRiLmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBwLmlkLCBwLnByb2plY3QsIHAub3JnYW5pemF0aW9uLCBwLnBpcGVsaW5lX25hbWUsXG4gICAgICAgICAgQ09VTlQoKik6OmludCBBUyB0b3RhbCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCcpOjppbnQgQVMgc3VjY2VlZGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdDQU5DRUxFRCcpOjppbnQgQVMgY2FuY2VsZWQsXG4gICAgICAgICAgTUlOKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgZmlyc3RfZXhlY3V0aW9uLFxuICAgICAgICAgIE1BWChlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGxhc3RfZXhlY3V0aW9uXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmV9IHBcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlIE9OIGUucGlwZWxpbmVfaWQgPSBwLmlkXG4gICAgICAgICAgQU5EIGUuZXZlbnRfdHlwZSA9ICdQSVBFTElORScgQU5EIGUuc3RhdHVzICE9ICdTVEFSVEVEJ1xuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBwLmlzX2FjdGl2ZSA9IHRydWVcbiAgICAgICAgR1JPVVAgQlkgcC5pZFxuICAgICAgICBPUkRFUiBCWSB0b3RhbCBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gc3FsUm93czxFeGVjdXRpb25Db3VudD4ocikpLFxuICAgICk7XG4gIH1cblxuICAvKiogMS4yIFN1Y2Nlc3MgcmF0ZSBvdmVyIHRpbWUgZm9yIGFuIG9yZy4gKi9cbiAgYXN5bmMgZ2V0U3VjY2Vzc1JhdGUob3JnSWQ6IHN0cmluZywgaW50ZXJ2YWw6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogUHJvbWlzZTxUaW1lU2VyaWVzRW50cnlbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnN1Y2Nlc3MtcmF0ZToke2ludGVydmFsfToke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIGRiLmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBEQVRFX1RSVU5DKCR7aW50ZXJ2YWx9LCBlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIHBlcmlvZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ1NVQ0NFRURFRCcpOjppbnQgQVMgc3VjY2VlZGVkLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsZWQsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdDQU5DRUxFRCcpOjppbnQgQVMgY2FuY2VsZWQsXG4gICAgICAgICAgUk9VTkQoQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdTVUNDRUVERUQnKTo6bnVtZXJpY1xuICAgICAgICAgICAgLyBOVUxMSUYoQ09VTlQoKiksIDApICogMTAwLCAxKTo6ZmxvYXQgQVMgc3VjY2Vzc19wY3RcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJ1xuICAgICAgICAgIEFORCBlLnN0YXR1cyBJTiAoJ1NVQ0NFRURFRCcsICdGQUlMRUQnLCAnQ0FOQ0VMRUQnKVxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgcGVyaW9kIE9SREVSIEJZIHBlcmlvZFxuICAgICAgYCkudGhlbihyID0+IHNxbFJvd3M8VGltZVNlcmllc0VudHJ5PihyKSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKiAxLjMgQXZlcmFnZSBkdXJhdGlvbiBwZXIgcGlwZWxpbmUuICovXG4gIGFzeW5jIGdldEF2ZXJhZ2VEdXJhdGlvbihvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPER1cmF0aW9uU3RhdHNbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmF2Zy1kdXJhdGlvbjoke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIGRiLmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBwLmlkLCBwLnByb2plY3QsIHAucGlwZWxpbmVfbmFtZSxcbiAgICAgICAgICBBVkcoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBhdmdfbXMsXG4gICAgICAgICAgTUlOKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWluX21zLFxuICAgICAgICAgIE1BWChlLmR1cmF0aW9uX21zKTo6aW50IEFTIG1heF9tcyxcbiAgICAgICAgICBQRVJDRU5USUxFX0NPTlQoMC45NSkgV0lUSElOIEdST1VQIChPUkRFUiBCWSBlLmR1cmF0aW9uX21zKTo6aW50IEFTIHA5NV9tcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIGV4ZWN1dGlvbnNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF90eXBlID0gJ1BJUEVMSU5FJyBBTkQgZS5kdXJhdGlvbl9tcyBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgcC5pZCBPUkRFUiBCWSBhdmdfbXMgREVTQ1xuICAgICAgYCkudGhlbihyID0+IHNxbFJvd3M8RHVyYXRpb25TdGF0cz4ocikpLFxuICAgICk7XG4gIH1cblxuICAvKiogMS41IFN0YWdlIGZhaWx1cmUgaGVhdG1hcCDigJQgd2hpY2ggc3RhZ2VzIGZhaWwgbW9zdC4gKi9cbiAgYXN5bmMgZ2V0U3RhZ2VGYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPFN0YWdlRmFpbHVyZVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06c3RhZ2UtZmFpbHVyZXM6JHtmcm9tfToke3RvfWAsICgpID0+XG4gICAgICBkYi5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5zdGFnZV9uYW1lLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsdXJlcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHRvdGFsLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIGZhaWx1cmVfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdTVEFHRScgQU5EIGUuc3RhZ2VfbmFtZSBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgZS5zdGFnZV9uYW1lIE9SREVSIEJZIGZhaWx1cmVzIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBzcWxSb3dzPFN0YWdlRmFpbHVyZT4ocikpLFxuICAgICk7XG4gIH1cblxuICAvKiogMS42IFN0YWdlIGJvdHRsZW5lY2tzIOKAlCBzbG93ZXN0IHN0YWdlcyBwZXIgcGlwZWxpbmUuICovXG4gIGFzeW5jIGdldFN0YWdlQm90dGxlbmVja3Mob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogUHJvbWlzZTxTdGFnZUJvdHRsZW5lY2tbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnN0YWdlLWJvdHRsZW5lY2tzOiR7ZnJvbX06JHt0b31gLCAoKSA9PlxuICAgICAgZGIuZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIHAuaWQsIHAucGlwZWxpbmVfbmFtZSwgZS5zdGFnZV9uYW1lLFxuICAgICAgICAgIEFWRyhlLmR1cmF0aW9uX21zKTo6aW50IEFTIGF2Z19tcyxcbiAgICAgICAgICBNQVgoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBtYXhfbXNcbiAgICAgICAgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fSBlXG4gICAgICAgIEpPSU4gJHtzY2hlbWEucGlwZWxpbmV9IHAgT04gcC5pZCA9IGUucGlwZWxpbmVfaWRcbiAgICAgICAgV0hFUkUgcC5vcmdfaWQgPSAke29yZ0lkfSBBTkQgZS5ldmVudF90eXBlID0gJ1NUQUdFJyBBTkQgZS5kdXJhdGlvbl9tcyBJUyBOT1QgTlVMTFxuICAgICAgICAgIEFORCBlLnN0YXJ0ZWRfYXQgPj0gJHtmcm9tfTo6dGltZXN0YW1wdHogQU5EIGUuc3RhcnRlZF9hdCA8PSAke3RvfTo6dGltZXN0YW1wdHpcbiAgICAgICAgR1JPVVAgQlkgcC5pZCwgZS5zdGFnZV9uYW1lIE9SREVSIEJZIGF2Z19tcyBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gc3FsUm93czxTdGFnZUJvdHRsZW5lY2s+KHIpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDEuNyBBY3Rpb24gZmFpbHVyZSByYXRlIOKAlCB3aGljaCBwbHVnaW4gc3RlcHMgZmFpbCBtb3N0LiAqL1xuICBhc3luYyBnZXRBY3Rpb25GYWlsdXJlcyhvcmdJZDogc3RyaW5nLCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmcpOiBQcm9taXNlPEFjdGlvbkZhaWx1cmVbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmFjdGlvbi1mYWlsdXJlczoke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIGRiLmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLmFjdGlvbl9uYW1lLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6OmludCBBUyBmYWlsdXJlcyxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIHRvdGFsLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnRkFJTEVEJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIGZhaWx1cmVfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBKT0lOICR7c2NoZW1hLnBpcGVsaW5lfSBwIE9OIHAuaWQgPSBlLnBpcGVsaW5lX2lkXG4gICAgICAgIFdIRVJFIHAub3JnX2lkID0gJHtvcmdJZH0gQU5EIGUuZXZlbnRfdHlwZSA9ICdBQ1RJT04nIEFORCBlLmFjdGlvbl9uYW1lIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBlLmFjdGlvbl9uYW1lIE9SREVSIEJZIGZhaWx1cmVzIERFU0NcbiAgICAgIGApLnRoZW4ociA9PiBzcWxSb3dzPEFjdGlvbkZhaWx1cmU+KHIpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDEuOCBFcnJvciBjYXRlZ29yaXphdGlvbiDigJQgZ3JvdXAgZmFpbHVyZSBtZXNzYWdlcy4gKi9cbiAgYXN5bmMgZ2V0RXJyb3JzKG9yZ0lkOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZywgbGltaXQ6IG51bWJlciA9IDIwKTogUHJvbWlzZTxFcnJvckVudHJ5W10+IHtcbiAgICByZXR1cm4gdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGAke29yZ0lkfTplcnJvcnM6JHtmcm9tfToke3RvfToke2xpbWl0fWAsICgpID0+XG4gICAgICBkYi5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgU1VCU1RSSU5HKGUuZXJyb3JfbWVzc2FnZSBGUk9NIDEgRk9SIDIwMCkgQVMgZXJyb3JfcGF0dGVybixcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIG9jY3VycmVuY2VzLFxuICAgICAgICAgIENPVU5UKERJU1RJTkNUIGUucGlwZWxpbmVfaWQpOjppbnQgQVMgYWZmZWN0ZWRfcGlwZWxpbmVzLFxuICAgICAgICAgIE1BWChlLnN0YXJ0ZWRfYXQpOjp0ZXh0IEFTIGxhc3Rfc2VlblxuICAgICAgICBGUk9NICR7c2NoZW1hLnBpcGVsaW5lRXZlbnR9IGVcbiAgICAgICAgSk9JTiAke3NjaGVtYS5waXBlbGluZX0gcCBPTiBwLmlkID0gZS5waXBlbGluZV9pZFxuICAgICAgICBXSEVSRSBwLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLnN0YXR1cyA9ICdGQUlMRUQnIEFORCBlLmVycm9yX21lc3NhZ2UgSVMgTk9UIE5VTExcbiAgICAgICAgICBBTkQgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6XG4gICAgICAgIEdST1VQIEJZIGVycm9yX3BhdHRlcm4gT1JERVIgQlkgb2NjdXJyZW5jZXMgREVTQ1xuICAgICAgICBMSU1JVCAke2xpbWl0fVxuICAgICAgYCkudGhlbihyID0+IHNxbFJvd3M8RXJyb3JFbnRyeT4ocikpLFxuICAgICk7XG4gIH1cblxuICAvLyDilIDilIAgQ2F0ZWdvcnkgMjogUGx1Z2luIEludmVudG9yeSAmIEJ1aWxkcyDilIDilIBcblxuICAvKiogMi4xIFBsdWdpbiBzdW1tYXJ5IOKAlCBjb3VudHMgYW5kIGJyZWFrZG93bnMuICovXG4gIGFzeW5jIGdldFBsdWdpblN1bW1hcnkob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8UGx1Z2luU3VtbWFyeT4ge1xuICAgIHJldHVybiBpbnZlbnRvcnlDYWNoZS5nZXRPclNldChgJHtvcmdJZH06cGx1Z2luLXN1bW1hcnlgLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByb3dzID0gYXdhaXQgZGIuZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdG90YWwsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSAke3NjaGVtYS5wbHVnaW4uaXNBY3RpdmV9KTo6aW50IEFTIGFjdGl2ZSxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIE5PVCAke3NjaGVtYS5wbHVnaW4uaXNBY3RpdmV9KTo6aW50IEFTIGluYWN0aXZlLFxuICAgICAgICAgIENPVU5UKCopIEZJTFRFUiAoV0hFUkUgJHtzY2hlbWEucGx1Z2luLmFjY2Vzc01vZGlmaWVyfSA9ICdwdWJsaWMnKTo6aW50IEFTIHB1YmxpYyxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFICR7c2NoZW1hLnBsdWdpbi5hY2Nlc3NNb2RpZmllcn0gPSAncHJpdmF0ZScpOjppbnQgQVMgcHJpdmF0ZSxcbiAgICAgICAgICBDT1VOVChESVNUSU5DVCAke3NjaGVtYS5wbHVnaW4ubmFtZX0pOjppbnQgQVMgdW5pcXVlX25hbWVzXG4gICAgICAgIEZST00gJHtzY2hlbWEucGx1Z2lufVxuICAgICAgICBXSEVSRSAke3NjaGVtYS5wbHVnaW4ub3JnSWR9ID0gJHtvcmdJZH1cbiAgICAgIGApO1xuICAgICAgcmV0dXJuIChzcWxSb3dzPFBsdWdpblN1bW1hcnk+KHJvd3MpWzBdIHx8IHsgdG90YWw6IDAsIGFjdGl2ZTogMCwgaW5hY3RpdmU6IDAsIHB1YmxpYzogMCwgcHJpdmF0ZTogMCwgdW5pcXVlTmFtZXM6IDAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKiogMi4yIFR5cGUgJiBjb21wdXRlIGRpc3RyaWJ1dGlvbi4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luRGlzdHJpYnV0aW9uKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFR5cGVDb21wdXRlRGlzdHJpYnV0aW9uW10+IHtcbiAgICByZXR1cm4gaW52ZW50b3J5Q2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnBsdWdpbi1kaXN0cmlidXRpb25gLCAoKSA9PlxuICAgICAgZGIuZXhlY3V0ZShzcWxgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgICR7c2NoZW1hLnBsdWdpbi5wbHVnaW5UeXBlfSBBUyBwbHVnaW5fdHlwZSxcbiAgICAgICAgICAke3NjaGVtYS5wbHVnaW4uY29tcHV0ZVR5cGV9IEFTIGNvbXB1dGVfdHlwZSxcbiAgICAgICAgICBDT1VOVCgqKTo6aW50IEFTIGNvdW50XG4gICAgICAgIEZST00gJHtzY2hlbWEucGx1Z2lufVxuICAgICAgICBXSEVSRSAke3NjaGVtYS5wbHVnaW4ub3JnSWR9ID0gJHtvcmdJZH0gQU5EICR7c2NoZW1hLnBsdWdpbi5pc0FjdGl2ZX0gPSB0cnVlXG4gICAgICAgIEdST1VQIEJZICR7c2NoZW1hLnBsdWdpbi5wbHVnaW5UeXBlfSwgJHtzY2hlbWEucGx1Z2luLmNvbXB1dGVUeXBlfVxuICAgICAgICBPUkRFUiBCWSBjb3VudCBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gc3FsUm93czxUeXBlQ29tcHV0ZURpc3RyaWJ1dGlvbj4ocikpLFxuICAgICk7XG4gIH1cblxuICAvKiogMi4zIFZlcnNpb24gY291bnRzIHBlciBwbHVnaW4gbmFtZS4gKi9cbiAgYXN5bmMgZ2V0UGx1Z2luVmVyc2lvbnMob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8VmVyc2lvbkNvdW50W10+IHtcbiAgICByZXR1cm4gaW52ZW50b3J5Q2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OnBsdWdpbi12ZXJzaW9uc2AsICgpID0+XG4gICAgICBkYi5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgJHtzY2hlbWEucGx1Z2luLm5hbWV9LFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgdmVyc2lvbl9jb3VudCxcbiAgICAgICAgICBNQVgoJHtzY2hlbWEucGx1Z2luLnZlcnNpb259KSBBUyBsYXRlc3RfdmVyc2lvbixcbiAgICAgICAgICBib29sX29yKCR7c2NoZW1hLnBsdWdpbi5pc0RlZmF1bHR9KSBBUyBoYXNfZGVmYXVsdFxuICAgICAgICBGUk9NICR7c2NoZW1hLnBsdWdpbn1cbiAgICAgICAgV0hFUkUgJHtzY2hlbWEucGx1Z2luLm9yZ0lkfSA9ICR7b3JnSWR9IEFORCAke3NjaGVtYS5wbHVnaW4uaXNBY3RpdmV9ID0gdHJ1ZVxuICAgICAgICBHUk9VUCBCWSAke3NjaGVtYS5wbHVnaW4ubmFtZX1cbiAgICAgICAgT1JERVIgQlkgdmVyc2lvbl9jb3VudCBERVNDXG4gICAgICBgKS50aGVuKHIgPT4gc3FsUm93czxWZXJzaW9uQ291bnQ+KHIpKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIDIuNCBCdWlsZCBzdWNjZXNzIHJhdGUgb3ZlciB0aW1lLiAqL1xuICBhc3luYyBnZXRCdWlsZFN1Y2Nlc3NSYXRlKG9yZ0lkOiBzdHJpbmcsIGludGVydmFsOiBzdHJpbmcsIGZyb206IHN0cmluZywgdG86IHN0cmluZyk6IFByb21pc2U8QnVpbGRUaW1lU2VyaWVzRW50cnlbXT4ge1xuICAgIHJldHVybiB0aW1lc2VyaWVzQ2FjaGUuZ2V0T3JTZXQoYCR7b3JnSWR9OmJ1aWxkLXN1Y2Nlc3M6JHtpbnRlcnZhbH06JHtmcm9tfToke3RvfWAsICgpID0+XG4gICAgICBkYi5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgREFURV9UUlVOQygke2ludGVydmFsfSwgZS5zdGFydGVkX2F0KTo6dGV4dCBBUyBwZXJpb2QsXG4gICAgICAgICAgQ09VTlQoKikgRklMVEVSIChXSEVSRSBlLnN0YXR1cyA9ICdjb21wbGV0ZWQnKTo6aW50IEFTIHN1Y2NlZWRlZCxcbiAgICAgICAgICBDT1VOVCgqKSBGSUxURVIgKFdIRVJFIGUuc3RhdHVzID0gJ2ZhaWxlZCcpOjppbnQgQVMgZmFpbGVkLFxuICAgICAgICAgIFJPVU5EKENPVU5UKCopIEZJTFRFUiAoV0hFUkUgZS5zdGF0dXMgPSAnY29tcGxldGVkJyk6Om51bWVyaWNcbiAgICAgICAgICAgIC8gTlVMTElGKENPVU5UKCopLCAwKSAqIDEwMCwgMSk6OmZsb2F0IEFTIHN1Y2Nlc3NfcGN0XG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnXG4gICAgICAgICAgQU5EIGUuc3RhdHVzIElOICgnY29tcGxldGVkJywgJ2ZhaWxlZCcpXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwZXJpb2QgT1JERVIgQlkgcGVyaW9kXG4gICAgICBgKS50aGVuKHIgPT4gc3FsUm93czxCdWlsZFRpbWVTZXJpZXNFbnRyeT4ocikpLFxuICAgICk7XG4gIH1cblxuICAvKiogMi41IEJ1aWxkIGR1cmF0aW9uIHBlciBwbHVnaW4uICovXG4gIGFzeW5jIGdldEJ1aWxkRHVyYXRpb24ob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogUHJvbWlzZTxCdWlsZER1cmF0aW9uW10+IHtcbiAgICByZXR1cm4gdGltZXNlcmllc0NhY2hlLmdldE9yU2V0KGAke29yZ0lkfTpidWlsZC1kdXJhdGlvbjoke2Zyb219OiR7dG99YCwgKCkgPT5cbiAgICAgIGRiLmV4ZWN1dGUoc3FsYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICBlLmRldGFpbC0+PidwbHVnaW5OYW1lJyBBUyBwbHVnaW5fbmFtZSxcbiAgICAgICAgICBBVkcoZS5kdXJhdGlvbl9tcyk6OmludCBBUyBhdmdfbXMsXG4gICAgICAgICAgTUFYKGUuZHVyYXRpb25fbXMpOjppbnQgQVMgbWF4X21zLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgYnVpbGRzXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnIEFORCBlLmR1cmF0aW9uX21zIElTIE5PVCBOVUxMXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwbHVnaW5fbmFtZSBPUkRFUiBCWSBhdmdfbXMgREVTQ1xuICAgICAgYCkudGhlbihyID0+IHNxbFJvd3M8QnVpbGREdXJhdGlvbj4ocikpLFxuICAgICk7XG4gIH1cblxuICAvKiogMi42IEJ1aWxkIGZhaWx1cmVzIOKAlCB0b3AgZXJyb3IgbWVzc2FnZXMuICovXG4gIGFzeW5jIGdldEJ1aWxkRmFpbHVyZXMob3JnSWQ6IHN0cmluZywgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nLCBsaW1pdDogbnVtYmVyID0gMjApOiBQcm9taXNlPEJ1aWxkRmFpbHVyZVtdPiB7XG4gICAgcmV0dXJuIHRpbWVzZXJpZXNDYWNoZS5nZXRPclNldChgJHtvcmdJZH06YnVpbGQtZmFpbHVyZXM6JHtmcm9tfToke3RvfToke2xpbWl0fWAsICgpID0+XG4gICAgICBkYi5leGVjdXRlKHNxbGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgZS5kZXRhaWwtPj4ncGx1Z2luTmFtZScgQVMgcGx1Z2luX25hbWUsXG4gICAgICAgICAgZS5lcnJvcl9tZXNzYWdlLFxuICAgICAgICAgIENPVU5UKCopOjppbnQgQVMgb2NjdXJyZW5jZXMsXG4gICAgICAgICAgTUFYKGUuc3RhcnRlZF9hdCk6OnRleHQgQVMgbGFzdF9zZWVuXG4gICAgICAgIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH0gZVxuICAgICAgICBXSEVSRSBlLm9yZ19pZCA9ICR7b3JnSWR9IEFORCBlLmV2ZW50X3NvdXJjZSA9ICdwbHVnaW4tYnVpbGQnIEFORCBlLnN0YXR1cyA9ICdmYWlsZWQnXG4gICAgICAgICAgQU5EIGUuc3RhcnRlZF9hdCA+PSAke2Zyb219Ojp0aW1lc3RhbXB0eiBBTkQgZS5zdGFydGVkX2F0IDw9ICR7dG99Ojp0aW1lc3RhbXB0elxuICAgICAgICBHUk9VUCBCWSBwbHVnaW5fbmFtZSwgZS5lcnJvcl9tZXNzYWdlXG4gICAgICAgIE9SREVSIEJZIG9jY3VycmVuY2VzIERFU0NcbiAgICAgICAgTElNSVQgJHtsaW1pdH1cbiAgICAgIGApLnRoZW4ociA9PiBzcWxSb3dzPEJ1aWxkRmFpbHVyZT4ocikpLFxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHJlcG9ydGluZ1NlcnZpY2UgPSBuZXcgUmVwb3J0aW5nU2VydmljZSgpO1xuIl19
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { AccessModifier } from '@pipeline-builder/api-core';
|
|
2
|
+
/**
|
|
3
|
+
* Base filter interface containing common filter properties shared across all entity types.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* const filter: CommonFilter = {
|
|
8
|
+
* id: '123',
|
|
9
|
+
* orgId: 'my-org',
|
|
10
|
+
* accessModifier: AccessModifier.PUBLIC,
|
|
11
|
+
* isDefault: true,
|
|
12
|
+
* isActive: true
|
|
13
|
+
* };
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export interface CommonFilter {
|
|
17
|
+
/**
|
|
18
|
+
* Unique identifier for the entity
|
|
19
|
+
* Can be a single ID or array of IDs for batch filtering
|
|
20
|
+
*/
|
|
21
|
+
readonly id?: string | string[];
|
|
22
|
+
/**
|
|
23
|
+
* Organization identifier to filter entities by organization
|
|
24
|
+
* Can be a single org ID or array for multi-org filtering
|
|
25
|
+
*/
|
|
26
|
+
readonly orgId?: string | string[];
|
|
27
|
+
/**
|
|
28
|
+
* Access modifier to filter by visibility/permissions
|
|
29
|
+
* Use AccessModifier enum for type safety
|
|
30
|
+
* @see AccessModifier
|
|
31
|
+
*/
|
|
32
|
+
readonly accessModifier?: AccessModifier | string;
|
|
33
|
+
/**
|
|
34
|
+
* Filter by default status
|
|
35
|
+
* - true: Only default entities
|
|
36
|
+
* - false: Only non-default entities
|
|
37
|
+
* - undefined: All entities
|
|
38
|
+
*/
|
|
39
|
+
readonly isDefault?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Filter by active/inactive status
|
|
42
|
+
* - true: Only active entities
|
|
43
|
+
* - false: Only inactive entities
|
|
44
|
+
* - undefined: All entities
|
|
45
|
+
*/
|
|
46
|
+
readonly isActive?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Number of results to return
|
|
49
|
+
* @minimum 1
|
|
50
|
+
* @maximum 1000
|
|
51
|
+
*/
|
|
52
|
+
readonly limit?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Number of results to skip (for pagination)
|
|
55
|
+
* @minimum 0
|
|
56
|
+
*/
|
|
57
|
+
readonly offset?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Sort field and direction
|
|
60
|
+
* @example "name:asc", "createdAt:desc"
|
|
61
|
+
*/
|
|
62
|
+
readonly sort?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Filter interface for plugin-specific properties.
|
|
66
|
+
* Extends CommonFilter to include plugin-related filter options.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const filter: PluginFilter = {
|
|
71
|
+
* name: 'nodejs-build',
|
|
72
|
+
* version: '1.0.0',
|
|
73
|
+
* isActive: true
|
|
74
|
+
* };
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export interface PluginFilter extends CommonFilter {
|
|
78
|
+
/**
|
|
79
|
+
* Plugin name to filter by
|
|
80
|
+
*/
|
|
81
|
+
readonly name?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Plugin version to filter by
|
|
84
|
+
* Supports semantic versioning
|
|
85
|
+
* @example "1.0.0", "^2.0.0", "~1.2.3"
|
|
86
|
+
*/
|
|
87
|
+
readonly version?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Docker image tag associated with the plugin
|
|
90
|
+
*/
|
|
91
|
+
readonly imageTag?: string;
|
|
92
|
+
/**
|
|
93
|
+
* Keyword to search within the keywords JSONB array (case-insensitive contains)
|
|
94
|
+
*/
|
|
95
|
+
readonly keyword?: string;
|
|
96
|
+
/**
|
|
97
|
+
* Plugin category to filter by
|
|
98
|
+
* @example "language", "security", "testing"
|
|
99
|
+
*/
|
|
100
|
+
readonly category?: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Filter interface for pipeline-specific properties.
|
|
104
|
+
* Extends CommonFilter to include pipeline-related filter options.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const filter: PipelineFilter = {
|
|
109
|
+
* project: 'my-app',
|
|
110
|
+
* organization: 'my-org',
|
|
111
|
+
* pipelineName: 'my-pipeline',
|
|
112
|
+
* isActive: true
|
|
113
|
+
* };
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export interface PipelineFilter extends CommonFilter {
|
|
117
|
+
/**
|
|
118
|
+
* Project name associated with the pipeline
|
|
119
|
+
*/
|
|
120
|
+
readonly project?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Organization name associated with the pipeline
|
|
123
|
+
*/
|
|
124
|
+
readonly organization?: string;
|
|
125
|
+
/**
|
|
126
|
+
* Pipeline name to filter by
|
|
127
|
+
*/
|
|
128
|
+
readonly pipelineName?: string;
|
|
129
|
+
/**
|
|
130
|
+
* Keyword to search within the keywords JSONB array (case-insensitive contains)
|
|
131
|
+
*/
|
|
132
|
+
readonly keyword?: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Filter interface for message-specific properties.
|
|
136
|
+
* Extends CommonFilter to include message-related filter options.
|
|
137
|
+
*/
|
|
138
|
+
export interface MessageFilter extends CommonFilter {
|
|
139
|
+
/**
|
|
140
|
+
* Thread ID to filter by (for fetching thread replies).
|
|
141
|
+
* Pass `null` to filter for root messages only (threadId IS NULL).
|
|
142
|
+
*/
|
|
143
|
+
readonly threadId?: string | null;
|
|
144
|
+
/**
|
|
145
|
+
* Recipient organization ID to filter by
|
|
146
|
+
* Use '*' for broadcast announcements
|
|
147
|
+
*/
|
|
148
|
+
readonly recipientOrgId?: string;
|
|
149
|
+
/**
|
|
150
|
+
* Message type filter
|
|
151
|
+
*/
|
|
152
|
+
readonly messageType?: 'announcement' | 'conversation';
|
|
153
|
+
/**
|
|
154
|
+
* Filter by read status
|
|
155
|
+
*/
|
|
156
|
+
readonly isRead?: boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Filter by priority level
|
|
159
|
+
*/
|
|
160
|
+
readonly priority?: 'normal' | 'high' | 'urgent';
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Filter for compliance policies.
|
|
164
|
+
*/
|
|
165
|
+
export interface CompliancePolicyFilter extends CommonFilter {
|
|
166
|
+
readonly name?: string;
|
|
167
|
+
readonly isTemplate?: boolean;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Filter for compliance rules.
|
|
171
|
+
*/
|
|
172
|
+
export interface ComplianceRuleFilter extends CommonFilter {
|
|
173
|
+
readonly name?: string;
|
|
174
|
+
readonly policyId?: string;
|
|
175
|
+
readonly target?: 'plugin' | 'pipeline';
|
|
176
|
+
readonly field?: string;
|
|
177
|
+
readonly severity?: 'warning' | 'error' | 'critical';
|
|
178
|
+
readonly scope?: 'org' | 'published';
|
|
179
|
+
readonly tag?: string;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Filter for compliance rule subscriptions.
|
|
183
|
+
*/
|
|
184
|
+
export interface ComplianceRuleSubscriptionFilter {
|
|
185
|
+
readonly orgId?: string;
|
|
186
|
+
readonly ruleId?: string;
|
|
187
|
+
readonly isActive?: boolean;
|
|
188
|
+
readonly limit?: number;
|
|
189
|
+
readonly offset?: number;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Filter for compliance exemptions.
|
|
193
|
+
*/
|
|
194
|
+
export interface ComplianceExemptionFilter {
|
|
195
|
+
readonly orgId?: string;
|
|
196
|
+
readonly ruleId?: string;
|
|
197
|
+
readonly entityType?: 'plugin' | 'pipeline';
|
|
198
|
+
readonly entityId?: string;
|
|
199
|
+
readonly status?: 'pending' | 'approved' | 'rejected' | 'expired';
|
|
200
|
+
readonly limit?: number;
|
|
201
|
+
readonly offset?: number;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Filter for compliance audit log entries.
|
|
205
|
+
*/
|
|
206
|
+
export interface ComplianceAuditFilter {
|
|
207
|
+
readonly orgId?: string;
|
|
208
|
+
readonly target?: 'plugin' | 'pipeline';
|
|
209
|
+
readonly action?: string;
|
|
210
|
+
readonly result?: 'pass' | 'warn' | 'block';
|
|
211
|
+
readonly scanId?: string;
|
|
212
|
+
readonly dateFrom?: string;
|
|
213
|
+
readonly dateTo?: string;
|
|
214
|
+
readonly limit?: number;
|
|
215
|
+
readonly offset?: number;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Filter for compliance scans.
|
|
219
|
+
*/
|
|
220
|
+
export interface ComplianceScanFilter {
|
|
221
|
+
readonly orgId?: string;
|
|
222
|
+
readonly target?: 'plugin' | 'pipeline' | 'all';
|
|
223
|
+
readonly status?: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
224
|
+
readonly triggeredBy?: 'manual' | 'scheduled' | 'rule-change' | 'rule-dry-run';
|
|
225
|
+
readonly limit?: number;
|
|
226
|
+
readonly offset?: number;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Validates message filter properties.
|
|
230
|
+
* Returns a result object with `valid` flag and `errors` array.
|
|
231
|
+
*/
|
|
232
|
+
export declare function validateMessageFilter(filter: Partial<MessageFilter>): {
|
|
233
|
+
valid: boolean;
|
|
234
|
+
errors: string[];
|
|
235
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.validateMessageFilter = validateMessageFilter;
|
|
6
|
+
/**
|
|
7
|
+
* Validates message filter properties.
|
|
8
|
+
* Returns a result object with `valid` flag and `errors` array.
|
|
9
|
+
*/
|
|
10
|
+
function validateMessageFilter(filter) {
|
|
11
|
+
const errors = [];
|
|
12
|
+
if (filter.messageType && !['announcement', 'conversation'].includes(filter.messageType)) {
|
|
13
|
+
errors.push(`Invalid messageType: "${filter.messageType}". Must be "announcement" or "conversation"`);
|
|
14
|
+
}
|
|
15
|
+
if (filter.priority && !['normal', 'high', 'urgent'].includes(filter.priority)) {
|
|
16
|
+
errors.push(`Invalid priority: "${filter.priority}". Must be "normal", "high", or "urgent"`);
|
|
17
|
+
}
|
|
18
|
+
if (filter.threadId !== undefined && filter.threadId !== null && typeof filter.threadId !== 'string') {
|
|
19
|
+
errors.push('threadId must be a string UUID or null');
|
|
20
|
+
}
|
|
21
|
+
return { valid: errors.length === 0, errors };
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktZmlsdGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL3F1ZXJ5LWZpbHRlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7O0FBMFF0QyxzREFpQkM7QUFyQkQ7OztHQUdHO0FBQ0gsU0FBZ0IscUJBQXFCLENBQUMsTUFBOEI7SUFJbEUsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFDO0lBRTVCLElBQUksTUFBTSxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztRQUN6RixNQUFNLENBQUMsSUFBSSxDQUFDLHlCQUF5QixNQUFNLENBQUMsV0FBVyw2Q0FBNkMsQ0FBQyxDQUFDO0lBQ3hHLENBQUM7SUFDRCxJQUFJLE1BQU0sQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQy9FLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0JBQXNCLE1BQU0sQ0FBQyxRQUFRLDBDQUEwQyxDQUFDLENBQUM7SUFDL0YsQ0FBQztJQUNELElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxTQUFTLElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxJQUFJLElBQUksT0FBTyxNQUFNLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ3JHLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQztBQUNoRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IEFjY2Vzc01vZGlmaWVyIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuXG4vKipcbiAqIEJhc2UgZmlsdGVyIGludGVyZmFjZSBjb250YWluaW5nIGNvbW1vbiBmaWx0ZXIgcHJvcGVydGllcyBzaGFyZWQgYWNyb3NzIGFsbCBlbnRpdHkgdHlwZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGZpbHRlcjogQ29tbW9uRmlsdGVyID0ge1xuICogICBpZDogJzEyMycsXG4gKiAgIG9yZ0lkOiAnbXktb3JnJyxcbiAqICAgYWNjZXNzTW9kaWZpZXI6IEFjY2Vzc01vZGlmaWVyLlBVQkxJQyxcbiAqICAgaXNEZWZhdWx0OiB0cnVlLFxuICogICBpc0FjdGl2ZTogdHJ1ZVxuICogfTtcbiAqIGBgYFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbW1vbkZpbHRlciB7XG4gIC8qKlxuICAgKiBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGVudGl0eVxuICAgKiBDYW4gYmUgYSBzaW5nbGUgSUQgb3IgYXJyYXkgb2YgSURzIGZvciBiYXRjaCBmaWx0ZXJpbmdcbiAgICovXG4gIHJlYWRvbmx5IGlkPzogc3RyaW5nIHwgc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIE9yZ2FuaXphdGlvbiBpZGVudGlmaWVyIHRvIGZpbHRlciBlbnRpdGllcyBieSBvcmdhbml6YXRpb25cbiAgICogQ2FuIGJlIGEgc2luZ2xlIG9yZyBJRCBvciBhcnJheSBmb3IgbXVsdGktb3JnIGZpbHRlcmluZ1xuICAgKi9cbiAgcmVhZG9ubHkgb3JnSWQ/OiBzdHJpbmcgfCBzdHJpbmdbXTtcblxuICAvKipcbiAgICogQWNjZXNzIG1vZGlmaWVyIHRvIGZpbHRlciBieSB2aXNpYmlsaXR5L3Blcm1pc3Npb25zXG4gICAqIFVzZSBBY2Nlc3NNb2RpZmllciBlbnVtIGZvciB0eXBlIHNhZmV0eVxuICAgKiBAc2VlIEFjY2Vzc01vZGlmaWVyXG4gICAqL1xuICByZWFkb25seSBhY2Nlc3NNb2RpZmllcj86IEFjY2Vzc01vZGlmaWVyIHwgc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBGaWx0ZXIgYnkgZGVmYXVsdCBzdGF0dXNcbiAgICogLSB0cnVlOiBPbmx5IGRlZmF1bHQgZW50aXRpZXNcbiAgICogLSBmYWxzZTogT25seSBub24tZGVmYXVsdCBlbnRpdGllc1xuICAgKiAtIHVuZGVmaW5lZDogQWxsIGVudGl0aWVzXG4gICAqL1xuICByZWFkb25seSBpc0RlZmF1bHQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBGaWx0ZXIgYnkgYWN0aXZlL2luYWN0aXZlIHN0YXR1c1xuICAgKiAtIHRydWU6IE9ubHkgYWN0aXZlIGVudGl0aWVzXG4gICAqIC0gZmFsc2U6IE9ubHkgaW5hY3RpdmUgZW50aXRpZXNcbiAgICogLSB1bmRlZmluZWQ6IEFsbCBlbnRpdGllc1xuICAgKi9cbiAgcmVhZG9ubHkgaXNBY3RpdmU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgcmVzdWx0cyB0byByZXR1cm5cbiAgICogQG1pbmltdW0gMVxuICAgKiBAbWF4aW11bSAxMDAwXG4gICAqL1xuICByZWFkb25seSBsaW1pdD86IG51bWJlcjtcblxuICAvKipcbiAgICogTnVtYmVyIG9mIHJlc3VsdHMgdG8gc2tpcCAoZm9yIHBhZ2luYXRpb24pXG4gICAqIEBtaW5pbXVtIDBcbiAgICovXG4gIHJlYWRvbmx5IG9mZnNldD86IG51bWJlcjtcblxuICAvKipcbiAgICogU29ydCBmaWVsZCBhbmQgZGlyZWN0aW9uXG4gICAqIEBleGFtcGxlIFwibmFtZTphc2NcIiwgXCJjcmVhdGVkQXQ6ZGVzY1wiXG4gICAqL1xuICByZWFkb25seSBzb3J0Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEZpbHRlciBpbnRlcmZhY2UgZm9yIHBsdWdpbi1zcGVjaWZpYyBwcm9wZXJ0aWVzLlxuICogRXh0ZW5kcyBDb21tb25GaWx0ZXIgdG8gaW5jbHVkZSBwbHVnaW4tcmVsYXRlZCBmaWx0ZXIgb3B0aW9ucy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZmlsdGVyOiBQbHVnaW5GaWx0ZXIgPSB7XG4gKiAgIG5hbWU6ICdub2RlanMtYnVpbGQnLFxuICogICB2ZXJzaW9uOiAnMS4wLjAnLFxuICogICBpc0FjdGl2ZTogdHJ1ZVxuICogfTtcbiAqIGBgYFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBsdWdpbkZpbHRlciBleHRlbmRzIENvbW1vbkZpbHRlciB7XG4gIC8qKlxuICAgKiBQbHVnaW4gbmFtZSB0byBmaWx0ZXIgYnlcbiAgICovXG4gIHJlYWRvbmx5IG5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFBsdWdpbiB2ZXJzaW9uIHRvIGZpbHRlciBieVxuICAgKiBTdXBwb3J0cyBzZW1hbnRpYyB2ZXJzaW9uaW5nXG4gICAqIEBleGFtcGxlIFwiMS4wLjBcIiwgXCJeMi4wLjBcIiwgXCJ+MS4yLjNcIlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZztcblxuICAvKipcbiAgICogRG9ja2VyIGltYWdlIHRhZyBhc3NvY2lhdGVkIHdpdGggdGhlIHBsdWdpblxuICAgKi9cbiAgcmVhZG9ubHkgaW1hZ2VUYWc/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEtleXdvcmQgdG8gc2VhcmNoIHdpdGhpbiB0aGUga2V5d29yZHMgSlNPTkIgYXJyYXkgKGNhc2UtaW5zZW5zaXRpdmUgY29udGFpbnMpXG4gICAqL1xuICByZWFkb25seSBrZXl3b3JkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQbHVnaW4gY2F0ZWdvcnkgdG8gZmlsdGVyIGJ5XG4gICAqIEBleGFtcGxlIFwibGFuZ3VhZ2VcIiwgXCJzZWN1cml0eVwiLCBcInRlc3RpbmdcIlxuICAgKi9cbiAgcmVhZG9ubHkgY2F0ZWdvcnk/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogRmlsdGVyIGludGVyZmFjZSBmb3IgcGlwZWxpbmUtc3BlY2lmaWMgcHJvcGVydGllcy5cbiAqIEV4dGVuZHMgQ29tbW9uRmlsdGVyIHRvIGluY2x1ZGUgcGlwZWxpbmUtcmVsYXRlZCBmaWx0ZXIgb3B0aW9ucy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZmlsdGVyOiBQaXBlbGluZUZpbHRlciA9IHtcbiAqICAgcHJvamVjdDogJ215LWFwcCcsXG4gKiAgIG9yZ2FuaXphdGlvbjogJ215LW9yZycsXG4gKiAgIHBpcGVsaW5lTmFtZTogJ215LXBpcGVsaW5lJyxcbiAqICAgaXNBY3RpdmU6IHRydWVcbiAqIH07XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQaXBlbGluZUZpbHRlciBleHRlbmRzIENvbW1vbkZpbHRlciB7XG4gIC8qKlxuICAgKiBQcm9qZWN0IG5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBwaXBlbGluZVxuICAgKi9cbiAgcmVhZG9ubHkgcHJvamVjdD86IHN0cmluZztcblxuICAvKipcbiAgICogT3JnYW5pemF0aW9uIG5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBwaXBlbGluZVxuICAgKi9cbiAgcmVhZG9ubHkgb3JnYW5pemF0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQaXBlbGluZSBuYW1lIHRvIGZpbHRlciBieVxuICAgKi9cbiAgcmVhZG9ubHkgcGlwZWxpbmVOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBLZXl3b3JkIHRvIHNlYXJjaCB3aXRoaW4gdGhlIGtleXdvcmRzIEpTT05CIGFycmF5IChjYXNlLWluc2Vuc2l0aXZlIGNvbnRhaW5zKVxuICAgKi9cbiAgcmVhZG9ubHkga2V5d29yZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBGaWx0ZXIgaW50ZXJmYWNlIGZvciBtZXNzYWdlLXNwZWNpZmljIHByb3BlcnRpZXMuXG4gKiBFeHRlbmRzIENvbW1vbkZpbHRlciB0byBpbmNsdWRlIG1lc3NhZ2UtcmVsYXRlZCBmaWx0ZXIgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZXNzYWdlRmlsdGVyIGV4dGVuZHMgQ29tbW9uRmlsdGVyIHtcbiAgLyoqXG4gICAqIFRocmVhZCBJRCB0byBmaWx0ZXIgYnkgKGZvciBmZXRjaGluZyB0aHJlYWQgcmVwbGllcykuXG4gICAqIFBhc3MgYG51bGxgIHRvIGZpbHRlciBmb3Igcm9vdCBtZXNzYWdlcyBvbmx5ICh0aHJlYWRJZCBJUyBOVUxMKS5cbiAgICovXG4gIHJlYWRvbmx5IHRocmVhZElkPzogc3RyaW5nIHwgbnVsbDtcblxuICAvKipcbiAgICogUmVjaXBpZW50IG9yZ2FuaXphdGlvbiBJRCB0byBmaWx0ZXIgYnlcbiAgICogVXNlICcqJyBmb3IgYnJvYWRjYXN0IGFubm91bmNlbWVudHNcbiAgICovXG4gIHJlYWRvbmx5IHJlY2lwaWVudE9yZ0lkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNZXNzYWdlIHR5cGUgZmlsdGVyXG4gICAqL1xuICByZWFkb25seSBtZXNzYWdlVHlwZT86ICdhbm5vdW5jZW1lbnQnIHwgJ2NvbnZlcnNhdGlvbic7XG5cbiAgLyoqXG4gICAqIEZpbHRlciBieSByZWFkIHN0YXR1c1xuICAgKi9cbiAgcmVhZG9ubHkgaXNSZWFkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRmlsdGVyIGJ5IHByaW9yaXR5IGxldmVsXG4gICAqL1xuICByZWFkb25seSBwcmlvcml0eT86ICdub3JtYWwnIHwgJ2hpZ2gnIHwgJ3VyZ2VudCc7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENvbXBsaWFuY2UgRmlsdGVyc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIEZpbHRlciBmb3IgY29tcGxpYW5jZSBwb2xpY2llcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb21wbGlhbmNlUG9saWN5RmlsdGVyIGV4dGVuZHMgQ29tbW9uRmlsdGVyIHtcbiAgcmVhZG9ubHkgbmFtZT86IHN0cmluZztcbiAgcmVhZG9ubHkgaXNUZW1wbGF0ZT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogRmlsdGVyIGZvciBjb21wbGlhbmNlIHJ1bGVzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXBsaWFuY2VSdWxlRmlsdGVyIGV4dGVuZHMgQ29tbW9uRmlsdGVyIHtcbiAgcmVhZG9ubHkgbmFtZT86IHN0cmluZztcbiAgcmVhZG9ubHkgcG9saWN5SWQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRhcmdldD86ICdwbHVnaW4nIHwgJ3BpcGVsaW5lJztcbiAgcmVhZG9ubHkgZmllbGQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNldmVyaXR5PzogJ3dhcm5pbmcnIHwgJ2Vycm9yJyB8ICdjcml0aWNhbCc7XG4gIHJlYWRvbmx5IHNjb3BlPzogJ29yZycgfCAncHVibGlzaGVkJztcbiAgcmVhZG9ubHkgdGFnPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEZpbHRlciBmb3IgY29tcGxpYW5jZSBydWxlIHN1YnNjcmlwdGlvbnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcGxpYW5jZVJ1bGVTdWJzY3JpcHRpb25GaWx0ZXIge1xuICByZWFkb25seSBvcmdJZD86IHN0cmluZztcbiAgcmVhZG9ubHkgcnVsZUlkPzogc3RyaW5nO1xuICByZWFkb25seSBpc0FjdGl2ZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGxpbWl0PzogbnVtYmVyO1xuICByZWFkb25seSBvZmZzZXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogRmlsdGVyIGZvciBjb21wbGlhbmNlIGV4ZW1wdGlvbnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcGxpYW5jZUV4ZW1wdGlvbkZpbHRlciB7XG4gIHJlYWRvbmx5IG9yZ0lkPzogc3RyaW5nO1xuICByZWFkb25seSBydWxlSWQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGVudGl0eVR5cGU/OiAncGx1Z2luJyB8ICdwaXBlbGluZSc7XG4gIHJlYWRvbmx5IGVudGl0eUlkPzogc3RyaW5nO1xuICByZWFkb25seSBzdGF0dXM/OiAncGVuZGluZycgfCAnYXBwcm92ZWQnIHwgJ3JlamVjdGVkJyB8ICdleHBpcmVkJztcbiAgcmVhZG9ubHkgbGltaXQ/OiBudW1iZXI7XG4gIHJlYWRvbmx5IG9mZnNldD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBGaWx0ZXIgZm9yIGNvbXBsaWFuY2UgYXVkaXQgbG9nIGVudHJpZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcGxpYW5jZUF1ZGl0RmlsdGVyIHtcbiAgcmVhZG9ubHkgb3JnSWQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRhcmdldD86ICdwbHVnaW4nIHwgJ3BpcGVsaW5lJztcbiAgcmVhZG9ubHkgYWN0aW9uPzogc3RyaW5nO1xuICByZWFkb25seSByZXN1bHQ/OiAncGFzcycgfCAnd2FybicgfCAnYmxvY2snO1xuICByZWFkb25seSBzY2FuSWQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRhdGVGcm9tPzogc3RyaW5nO1xuICByZWFkb25seSBkYXRlVG8/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGxpbWl0PzogbnVtYmVyO1xuICByZWFkb25seSBvZmZzZXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogRmlsdGVyIGZvciBjb21wbGlhbmNlIHNjYW5zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXBsaWFuY2VTY2FuRmlsdGVyIHtcbiAgcmVhZG9ubHkgb3JnSWQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRhcmdldD86ICdwbHVnaW4nIHwgJ3BpcGVsaW5lJyB8ICdhbGwnO1xuICByZWFkb25seSBzdGF0dXM/OiAncGVuZGluZycgfCAncnVubmluZycgfCAnY29tcGxldGVkJyB8ICdmYWlsZWQnIHwgJ2NhbmNlbGxlZCc7XG4gIHJlYWRvbmx5IHRyaWdnZXJlZEJ5PzogJ21hbnVhbCcgfCAnc2NoZWR1bGVkJyB8ICdydWxlLWNoYW5nZScgfCAncnVsZS1kcnktcnVuJztcbiAgcmVhZG9ubHkgbGltaXQ/OiBudW1iZXI7XG4gIHJlYWRvbmx5IG9mZnNldD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgbWVzc2FnZSBmaWx0ZXIgcHJvcGVydGllcy5cbiAqIFJldHVybnMgYSByZXN1bHQgb2JqZWN0IHdpdGggYHZhbGlkYCBmbGFnIGFuZCBgZXJyb3JzYCBhcnJheS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlTWVzc2FnZUZpbHRlcihmaWx0ZXI6IFBhcnRpYWw8TWVzc2FnZUZpbHRlcj4pOiB7XG4gIHZhbGlkOiBib29sZWFuO1xuICBlcnJvcnM6IHN0cmluZ1tdO1xufSB7XG4gIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICBpZiAoZmlsdGVyLm1lc3NhZ2VUeXBlICYmICFbJ2Fubm91bmNlbWVudCcsICdjb252ZXJzYXRpb24nXS5pbmNsdWRlcyhmaWx0ZXIubWVzc2FnZVR5cGUpKSB7XG4gICAgZXJyb3JzLnB1c2goYEludmFsaWQgbWVzc2FnZVR5cGU6IFwiJHtmaWx0ZXIubWVzc2FnZVR5cGV9XCIuIE11c3QgYmUgXCJhbm5vdW5jZW1lbnRcIiBvciBcImNvbnZlcnNhdGlvblwiYCk7XG4gIH1cbiAgaWYgKGZpbHRlci5wcmlvcml0eSAmJiAhWydub3JtYWwnLCAnaGlnaCcsICd1cmdlbnQnXS5pbmNsdWRlcyhmaWx0ZXIucHJpb3JpdHkpKSB7XG4gICAgZXJyb3JzLnB1c2goYEludmFsaWQgcHJpb3JpdHk6IFwiJHtmaWx0ZXIucHJpb3JpdHl9XCIuIE11c3QgYmUgXCJub3JtYWxcIiwgXCJoaWdoXCIsIG9yIFwidXJnZW50XCJgKTtcbiAgfVxuICBpZiAoZmlsdGVyLnRocmVhZElkICE9PSB1bmRlZmluZWQgJiYgZmlsdGVyLnRocmVhZElkICE9PSBudWxsICYmIHR5cGVvZiBmaWx0ZXIudGhyZWFkSWQgIT09ICdzdHJpbmcnKSB7XG4gICAgZXJyb3JzLnB1c2goJ3RocmVhZElkIG11c3QgYmUgYSBzdHJpbmcgVVVJRCBvciBudWxsJyk7XG4gIH1cblxuICByZXR1cm4geyB2YWxpZDogZXJyb3JzLmxlbmd0aCA9PT0gMCwgZXJyb3JzIH07XG59XG4iXX0=
|