@pipeline-builder/pipeline-data 4.1.23 → 4.1.25
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/lib/api/alert-destinations.d.ts +17 -0
- package/lib/api/alert-destinations.js +36 -0
- package/lib/api/reporting/analytics-queries.d.ts +274 -0
- package/lib/api/reporting/analytics-queries.js +598 -0
- package/lib/api/reporting/daily-rollup.d.ts +41 -0
- package/lib/api/reporting/daily-rollup.js +173 -0
- package/lib/api/reporting/deploy-rollup.d.ts +78 -0
- package/lib/api/reporting/deploy-rollup.js +203 -0
- package/lib/api/reporting/dora-scoring.d.ts +14 -0
- package/lib/api/reporting/dora-scoring.js +25 -1
- package/lib/api/reporting/dora.js +30 -6
- package/lib/api/reporting/failure-classifier.d.ts +54 -0
- package/lib/api/reporting/failure-classifier.js +179 -0
- package/lib/api/reporting/ingest.d.ts +2 -2
- package/lib/api/reporting/ingest.js +129 -4
- package/lib/api/reporting/last-deploy.d.ts +31 -0
- package/lib/api/reporting/last-deploy.js +93 -0
- package/lib/api/reporting/needs-attention.d.ts +93 -0
- package/lib/api/reporting/needs-attention.js +152 -0
- package/lib/api/reporting/plugin-exposure.d.ts +129 -0
- package/lib/api/reporting/plugin-exposure.js +312 -0
- package/lib/api/reporting/retention-sweep.js +9 -1
- package/lib/api/reporting/sql-helpers.d.ts +35 -2
- package/lib/api/reporting/sql-helpers.js +39 -1
- package/lib/api/reporting/stakeholder/compose.d.ts +115 -0
- package/lib/api/reporting/stakeholder/compose.js +234 -0
- package/lib/api/reporting/stakeholder/index.d.ts +14 -0
- package/lib/api/reporting/stakeholder/index.js +17 -0
- package/lib/api/reporting/stakeholder/period.d.ts +102 -0
- package/lib/api/reporting/stakeholder/period.js +273 -0
- package/lib/api/reporting/stakeholder/report-html.d.ts +93 -0
- package/lib/api/reporting/stakeholder/report-html.js +208 -0
- package/lib/api/reporting/stakeholder/sections.d.ts +117 -0
- package/lib/api/reporting/stakeholder/sections.js +249 -0
- package/lib/api/reporting/stakeholder/store.d.ts +450 -0
- package/lib/api/reporting/stakeholder/store.js +981 -0
- package/lib/api/reporting/stakeholder/templates.d.ts +21 -0
- package/lib/api/reporting/stakeholder/templates.js +104 -0
- package/lib/api/reporting/types.d.ts +73 -0
- package/lib/api/reporting/types.js +1 -1
- package/lib/api/reporting-service.d.ts +94 -5
- package/lib/api/reporting-service.js +169 -10
- package/lib/api/soft-delete-sweep.d.ts +11 -2
- package/lib/api/soft-delete-sweep.js +17 -6
- package/lib/database/drizzle-schema.d.ts +2263 -385
- package/lib/database/drizzle-schema.js +18 -7
- package/lib/database/index.d.ts +1 -1
- package/lib/database/index.js +4 -2
- package/lib/database/schema/compliance.d.ts +0 -682
- package/lib/database/schema/compliance.js +6 -66
- package/lib/database/schema/ecosystem.d.ts +20 -157
- package/lib/database/schema/ecosystem.js +23 -16
- package/lib/database/schema/pipeline.d.ts +200 -0
- package/lib/database/schema/pipeline.js +100 -1
- package/lib/database/schema/plugin.d.ts +20 -1
- package/lib/database/schema/plugin.js +13 -1
- package/lib/database/schema/reporting-analytics.d.ts +1212 -0
- package/lib/database/schema/reporting-analytics.js +250 -0
- package/lib/database/schema/reporting-stakeholder.d.ts +1405 -0
- package/lib/database/schema/reporting-stakeholder.js +251 -0
- package/lib/index.d.ts +10 -1
- package/lib/index.js +15 -1
- package/lib/testing/exports.json +67 -4
- package/package.json +4 -3
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* What plugin versions an org's pipelines are actually on, and which of those are
|
|
5
|
+
* known-vulnerable.
|
|
6
|
+
*
|
|
7
|
+
* Two tables, written here, read by the outdated-plugin and vulnerability report
|
|
8
|
+
* sections:
|
|
9
|
+
*
|
|
10
|
+
* - `pipeline_plugin_resolution` — the DECLARED side. Recomputed on pipeline
|
|
11
|
+
* write and on plugin publish, because the alternative is resolving every step
|
|
12
|
+
* of every pipeline against the catalog on every read, and that is not a query
|
|
13
|
+
* anyone can afford to put in a report.
|
|
14
|
+
* - `plugin_vuln_exposure` — the VULNERABLE side, per PIPELINE. A version-level
|
|
15
|
+
* table would force every reader to re-derive "which of our pipelines is
|
|
16
|
+
* exposed", which is the only form of the question anybody asks.
|
|
17
|
+
*
|
|
18
|
+
* DECLARED IS NOT DEPLOYED, and the report says which it is showing. A pipeline's
|
|
19
|
+
* config declares `^2.0.0`; what ran at its last deploy is whatever the step
|
|
20
|
+
* manifest recorded, pinned to a digest. Those disagree whenever a pipeline has not
|
|
21
|
+
* re-synthed since a publish — which is most of the time, and exactly the gap a
|
|
22
|
+
* vulnerability report is for. Conflating them would let a report say "fixed"
|
|
23
|
+
* about a pipeline still running the old image.
|
|
24
|
+
*/
|
|
25
|
+
import { randomUUID } from 'node:crypto';
|
|
26
|
+
import { createLogger, errorMessage } from '@pipeline-builder/api-core';
|
|
27
|
+
import { and, eq, inArray, isNull, lte, sql } from 'drizzle-orm';
|
|
28
|
+
import { schema } from '../../database/drizzle-schema.js';
|
|
29
|
+
import { withTenantTx } from '../../database/tenancy.js';
|
|
30
|
+
const logger = createLogger('plugin-exposure');
|
|
31
|
+
/** `1.2.3` → `[1, 2, 3]`; anything unparseable → null. */
|
|
32
|
+
function semver(v) {
|
|
33
|
+
const m = /^v?(\d+)\.(\d+)\.(\d+)/.exec(v ?? '');
|
|
34
|
+
return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* How far `resolved` is behind `latest`.
|
|
38
|
+
*
|
|
39
|
+
* `null` when either side is unparseable, NOT `'none'`. "We could not tell" and
|
|
40
|
+
* "it is up to date" are opposite answers, and reporting the second for the first
|
|
41
|
+
* is how a pipeline on an ancient pre-release version gets a clean bill of health.
|
|
42
|
+
*/
|
|
43
|
+
export function versionGap(resolved, latest) {
|
|
44
|
+
const a = semver(resolved);
|
|
45
|
+
const b = semver(latest);
|
|
46
|
+
if (!a || !b)
|
|
47
|
+
return null;
|
|
48
|
+
if (b[0] > a[0])
|
|
49
|
+
return 'major';
|
|
50
|
+
if (b[0] < a[0])
|
|
51
|
+
return 'none'; // resolved is ahead of "latest" — not behind
|
|
52
|
+
if (b[1] > a[1])
|
|
53
|
+
return 'minor';
|
|
54
|
+
if (b[1] < a[1])
|
|
55
|
+
return 'none';
|
|
56
|
+
if (b[2] > a[2])
|
|
57
|
+
return 'patch';
|
|
58
|
+
return 'none';
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Replace a pipeline's resolution rows.
|
|
62
|
+
*
|
|
63
|
+
* DELETE-then-INSERT for the pipeline, in one transaction, because a step can be
|
|
64
|
+
* REMOVED from a config: an upsert-only writer would leave the deleted step's row
|
|
65
|
+
* behind forever, and the outdated-plugin section would keep reporting a step the
|
|
66
|
+
* pipeline no longer has.
|
|
67
|
+
*/
|
|
68
|
+
export async function replacePipelineResolution(pipelineId, steps) {
|
|
69
|
+
const values = steps.map((s) => ({
|
|
70
|
+
orgId: s.orgId,
|
|
71
|
+
pipelineId: s.pipelineId,
|
|
72
|
+
stageName: s.stageName,
|
|
73
|
+
stepName: s.stepName,
|
|
74
|
+
pluginPublisher: s.pluginPublisher ?? null,
|
|
75
|
+
pluginName: s.pluginName,
|
|
76
|
+
declaredVersion: s.declaredVersion ?? null,
|
|
77
|
+
resolvedVersion: s.resolvedVersion ?? null,
|
|
78
|
+
latestVersion: s.latestVersion ?? null,
|
|
79
|
+
versionGap: versionGap(s.resolvedVersion, s.latestVersion),
|
|
80
|
+
withinPolicy: s.withinPolicy ?? true,
|
|
81
|
+
computedAt: new Date(),
|
|
82
|
+
}));
|
|
83
|
+
return withTenantTx(async (tx) => {
|
|
84
|
+
await tx.delete(schema.pipelinePluginResolution)
|
|
85
|
+
.where(eq(schema.pipelinePluginResolution.pipelineId, pipelineId));
|
|
86
|
+
if (values.length === 0)
|
|
87
|
+
return 0;
|
|
88
|
+
const landed = await tx.insert(schema.pipelinePluginResolution).values(values)
|
|
89
|
+
.returning({ pipelineId: schema.pipelinePluginResolution.pipelineId });
|
|
90
|
+
return landed.length;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Refresh the `latest`/gap columns for one plugin across every pipeline that uses
|
|
95
|
+
* it, without re-resolving anything else.
|
|
96
|
+
*
|
|
97
|
+
* Called on publish. A publish changes what "latest" means for every pipeline in
|
|
98
|
+
* the instance that declares the plugin, and re-resolving each of those pipelines
|
|
99
|
+
* from scratch would make publishing cost O(pipelines) work — so only the two
|
|
100
|
+
* columns a publish can change are touched.
|
|
101
|
+
*/
|
|
102
|
+
export async function refreshLatestForPlugin(pluginName, pluginPublisher, latestVersion) {
|
|
103
|
+
const rows = await withTenantTx((tx) => tx.update(schema.pipelinePluginResolution)
|
|
104
|
+
.set({
|
|
105
|
+
latestVersion,
|
|
106
|
+
// Recomputed in SQL from the row's own resolved version, so one statement
|
|
107
|
+
// covers every pipeline rather than a round trip each.
|
|
108
|
+
// `::text` on every bind of the version: Postgres otherwise deduces
|
|
109
|
+
// inconsistent types for the same parameter (varchar for the assignment,
|
|
110
|
+
// text for `split_part`) and refuses to plan the statement.
|
|
111
|
+
versionGap: sql `CASE
|
|
112
|
+
WHEN ${schema.pipelinePluginResolution.resolvedVersion} IS NULL THEN NULL
|
|
113
|
+
WHEN split_part(${latestVersion}::text, '.', 1)::int > split_part(${schema.pipelinePluginResolution.resolvedVersion}, '.', 1)::int THEN 'major'
|
|
114
|
+
WHEN split_part(${latestVersion}::text, '.', 1)::int < split_part(${schema.pipelinePluginResolution.resolvedVersion}, '.', 1)::int THEN 'none'
|
|
115
|
+
WHEN split_part(${latestVersion}::text, '.', 2)::int > split_part(${schema.pipelinePluginResolution.resolvedVersion}, '.', 2)::int THEN 'minor'
|
|
116
|
+
WHEN split_part(${latestVersion}::text, '.', 2)::int < split_part(${schema.pipelinePluginResolution.resolvedVersion}, '.', 2)::int THEN 'none'
|
|
117
|
+
WHEN split_part(${latestVersion}::text, '.', 3)::int > split_part(${schema.pipelinePluginResolution.resolvedVersion}, '.', 3)::int THEN 'patch'
|
|
118
|
+
ELSE 'none' END`,
|
|
119
|
+
computedAt: new Date(),
|
|
120
|
+
})
|
|
121
|
+
.where(and(eq(schema.pipelinePluginResolution.pluginName, pluginName), pluginPublisher === null
|
|
122
|
+
? isNull(schema.pipelinePluginResolution.pluginPublisher)
|
|
123
|
+
: eq(schema.pipelinePluginResolution.pluginPublisher, pluginPublisher),
|
|
124
|
+
// Only rows whose resolved version parses as semver; anything else has no
|
|
125
|
+
// gap to compute and the CASE would throw on the cast.
|
|
126
|
+
sql `${schema.pipelinePluginResolution.resolvedVersion} ~ '^[0-9]+\\.[0-9]+\\.[0-9]+'`))
|
|
127
|
+
.returning({ pipelineId: schema.pipelinePluginResolution.pipelineId }));
|
|
128
|
+
return rows.length;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Open or refresh exposures.
|
|
132
|
+
*
|
|
133
|
+
* Upserts on (pipeline, plugin, version, source) so a nightly rescan REFRESHES the
|
|
134
|
+
* counts rather than opening a new row every night — otherwise the report would
|
|
135
|
+
* show one exposure per night of the same problem, which reads as an escalating
|
|
136
|
+
* situation when nothing changed.
|
|
137
|
+
*
|
|
138
|
+
* A refresh deliberately does NOT reset `triage_state`: an org that accepted a
|
|
139
|
+
* finding with a reason and a deadline has made a decision, and re-raising it every
|
|
140
|
+
* night is how a team learns to ignore the report. It DOES clear a stale
|
|
141
|
+
* acceptance, because that is what the deadline was for.
|
|
142
|
+
*/
|
|
143
|
+
export async function upsertExposures(inputs, now = new Date()) {
|
|
144
|
+
if (inputs.length === 0)
|
|
145
|
+
return 0;
|
|
146
|
+
const values = inputs.map((e) => ({
|
|
147
|
+
id: randomUUID(),
|
|
148
|
+
orgId: e.orgId,
|
|
149
|
+
pipelineId: e.pipelineId,
|
|
150
|
+
pluginPublisher: e.pluginPublisher ?? null,
|
|
151
|
+
pluginName: e.pluginName,
|
|
152
|
+
pluginVersion: e.pluginVersion,
|
|
153
|
+
imageDigest: e.imageDigest ?? null,
|
|
154
|
+
source: e.source,
|
|
155
|
+
criticalCount: e.criticalCount,
|
|
156
|
+
highCount: e.highCount,
|
|
157
|
+
topFindings: e.topFindings ?? [],
|
|
158
|
+
flaggedAt: now,
|
|
159
|
+
updatedAt: now,
|
|
160
|
+
}));
|
|
161
|
+
try {
|
|
162
|
+
const landed = await withTenantTx((tx) => tx.insert(schema.pluginVulnExposure).values(values)
|
|
163
|
+
.onConflictDoUpdate({
|
|
164
|
+
target: [
|
|
165
|
+
schema.pluginVulnExposure.pipelineId,
|
|
166
|
+
schema.pluginVulnExposure.pluginName,
|
|
167
|
+
schema.pluginVulnExposure.pluginVersion,
|
|
168
|
+
schema.pluginVulnExposure.source,
|
|
169
|
+
],
|
|
170
|
+
set: {
|
|
171
|
+
criticalCount: sql `excluded.critical_count`,
|
|
172
|
+
highCount: sql `excluded.high_count`,
|
|
173
|
+
topFindings: sql `excluded.top_findings`,
|
|
174
|
+
imageDigest: sql `COALESCE(excluded.image_digest, ${schema.pluginVulnExposure.imageDigest})`,
|
|
175
|
+
// Still exposed, so the fix marker is cleared: a row that was closed by a
|
|
176
|
+
// deploy and is flagged again is a regression, and leaving `fixed_at` set
|
|
177
|
+
// would hide it.
|
|
178
|
+
fixedAt: null,
|
|
179
|
+
// An acceptance past its deadline stops being an acceptance. That is the
|
|
180
|
+
// entire point of time-boxing it, and it is enforced HERE rather than at
|
|
181
|
+
// read time so the stored state is the truth.
|
|
182
|
+
triageState: sql `CASE
|
|
183
|
+
WHEN ${schema.pluginVulnExposure.triageState} = 'accepted'
|
|
184
|
+
AND ${schema.pluginVulnExposure.acceptedUntil} IS NOT NULL
|
|
185
|
+
AND ${schema.pluginVulnExposure.acceptedUntil} <= ${now}
|
|
186
|
+
THEN 'open'
|
|
187
|
+
WHEN ${schema.pluginVulnExposure.triageState} = 'fixed' THEN 'open'
|
|
188
|
+
ELSE ${schema.pluginVulnExposure.triageState} END`,
|
|
189
|
+
updatedAt: now,
|
|
190
|
+
},
|
|
191
|
+
})
|
|
192
|
+
.returning({ id: schema.pluginVulnExposure.id }));
|
|
193
|
+
return landed.length;
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
logger.warn('Plugin exposure upsert failed', { count: values.length, error: errorMessage(err) });
|
|
197
|
+
return 0;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Close the exposures a pipeline has moved off.
|
|
202
|
+
*
|
|
203
|
+
* Called when a deploy records a new step manifest: anything flagged for that
|
|
204
|
+
* pipeline whose version is NOT in the set it now runs is fixed. Closing by
|
|
205
|
+
* absence rather than waiting for a rescan to notice is what makes "we fixed it"
|
|
206
|
+
* show up in the report on the next deploy instead of the next night.
|
|
207
|
+
*/
|
|
208
|
+
export async function closeFixedExposures(pipelineId, liveVersions, now = new Date()) {
|
|
209
|
+
const live = new Set(liveVersions.map((v) => `${v.pluginName}@${v.pluginVersion}`));
|
|
210
|
+
const open = await withTenantTx((tx) => tx.select({
|
|
211
|
+
id: schema.pluginVulnExposure.id,
|
|
212
|
+
pluginName: schema.pluginVulnExposure.pluginName,
|
|
213
|
+
pluginVersion: schema.pluginVulnExposure.pluginVersion,
|
|
214
|
+
}).from(schema.pluginVulnExposure)
|
|
215
|
+
.where(and(eq(schema.pluginVulnExposure.pipelineId, pipelineId), isNull(schema.pluginVulnExposure.fixedAt))));
|
|
216
|
+
const stale = open
|
|
217
|
+
.filter((r) => !live.has(`${r.pluginName}@${r.pluginVersion}`))
|
|
218
|
+
.map((r) => r.id);
|
|
219
|
+
if (stale.length === 0)
|
|
220
|
+
return 0;
|
|
221
|
+
const closed = await withTenantTx((tx) => tx.update(schema.pluginVulnExposure)
|
|
222
|
+
.set({ fixedAt: now, triageState: 'fixed', updatedAt: now })
|
|
223
|
+
.where(inArray(schema.pluginVulnExposure.id, stale))
|
|
224
|
+
.returning({ id: schema.pluginVulnExposure.id }));
|
|
225
|
+
return closed.length;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* The org's live exposures, for the report section.
|
|
229
|
+
*
|
|
230
|
+
* `accepted` rows whose deadline has passed come back as OPEN even if no rescan
|
|
231
|
+
* has refreshed them yet: a read must not present an expired acceptance as a
|
|
232
|
+
* current one, and the report is read far more often than the rescan runs.
|
|
233
|
+
*/
|
|
234
|
+
export async function openExposures(orgId) {
|
|
235
|
+
const now = new Date();
|
|
236
|
+
const rows = await withTenantTx((tx) => tx.select({
|
|
237
|
+
pipelineId: schema.pluginVulnExposure.pipelineId,
|
|
238
|
+
pluginName: schema.pluginVulnExposure.pluginName,
|
|
239
|
+
pluginVersion: schema.pluginVulnExposure.pluginVersion,
|
|
240
|
+
pluginPublisher: schema.pluginVulnExposure.pluginPublisher,
|
|
241
|
+
source: schema.pluginVulnExposure.source,
|
|
242
|
+
criticalCount: schema.pluginVulnExposure.criticalCount,
|
|
243
|
+
highCount: schema.pluginVulnExposure.highCount,
|
|
244
|
+
topFindings: schema.pluginVulnExposure.topFindings,
|
|
245
|
+
triageState: schema.pluginVulnExposure.triageState,
|
|
246
|
+
acceptedUntil: schema.pluginVulnExposure.acceptedUntil,
|
|
247
|
+
flaggedAt: schema.pluginVulnExposure.flaggedAt,
|
|
248
|
+
}).from(schema.pluginVulnExposure)
|
|
249
|
+
.where(and(eq(schema.pluginVulnExposure.orgId, orgId), isNull(schema.pluginVulnExposure.fixedAt),
|
|
250
|
+
// An acceptance that has run out is not an acceptance.
|
|
251
|
+
sql `(${schema.pluginVulnExposure.triageState} <> 'accepted'
|
|
252
|
+
OR ${schema.pluginVulnExposure.acceptedUntil} IS NULL
|
|
253
|
+
OR ${schema.pluginVulnExposure.acceptedUntil} <= ${now})`))
|
|
254
|
+
.orderBy(sql `${schema.pluginVulnExposure.criticalCount} DESC, ${schema.pluginVulnExposure.highCount} DESC`));
|
|
255
|
+
return rows.map((r) => ({
|
|
256
|
+
pipelineId: r.pipelineId,
|
|
257
|
+
pluginName: r.pluginName,
|
|
258
|
+
pluginVersion: r.pluginVersion,
|
|
259
|
+
pluginPublisher: r.pluginPublisher ?? null,
|
|
260
|
+
source: r.source,
|
|
261
|
+
criticalCount: r.criticalCount,
|
|
262
|
+
highCount: r.highCount,
|
|
263
|
+
topFindings: r.topFindings ?? [],
|
|
264
|
+
// An expired acceptance reads as open, which is what it is.
|
|
265
|
+
triageState: r.triageState === 'accepted' && r.acceptedUntil ? 'open' : r.triageState,
|
|
266
|
+
flaggedAt: r.flaggedAt,
|
|
267
|
+
}));
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Record a triage decision.
|
|
271
|
+
*
|
|
272
|
+
* `accepted` REQUIRES a deadline and a reason. A permanent, unexplained mute is
|
|
273
|
+
* how a finding stops being anybody's problem, and there is no good reason to
|
|
274
|
+
* support it — the caller gets an error rather than a silently unbounded
|
|
275
|
+
* acceptance.
|
|
276
|
+
*/
|
|
277
|
+
export async function triageExposure(orgId, id, decision) {
|
|
278
|
+
if (decision.state === 'accepted' && (!decision.acceptedUntil || !decision.reason?.trim())) {
|
|
279
|
+
throw new Error('Accepting a vulnerability exposure needs a reason and an expiry date');
|
|
280
|
+
}
|
|
281
|
+
const rows = await withTenantTx((tx) => tx.update(schema.pluginVulnExposure)
|
|
282
|
+
.set({
|
|
283
|
+
triageState: decision.state,
|
|
284
|
+
acceptedUntil: decision.state === 'accepted' ? (decision.acceptedUntil ?? null) : null,
|
|
285
|
+
triageReason: decision.reason ?? null,
|
|
286
|
+
triagedBy: decision.actor,
|
|
287
|
+
triagedAt: new Date(),
|
|
288
|
+
updatedAt: new Date(),
|
|
289
|
+
})
|
|
290
|
+
.where(and(eq(schema.pluginVulnExposure.id, id), eq(schema.pluginVulnExposure.orgId, orgId)))
|
|
291
|
+
.returning({ id: schema.pluginVulnExposure.id }));
|
|
292
|
+
return rows.length > 0;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Exposures whose acceptance has lapsed, for the org's security notifications.
|
|
296
|
+
*
|
|
297
|
+
* Surfaced rather than silently reopened: somebody decided to accept this until a
|
|
298
|
+
* date, that date has passed, and the person who decided is the one who should
|
|
299
|
+
* hear about it.
|
|
300
|
+
*/
|
|
301
|
+
export async function lapsedAcceptances(orgId, now = new Date()) {
|
|
302
|
+
const rows = await withTenantTx((tx) => tx.select({
|
|
303
|
+
id: schema.pluginVulnExposure.id,
|
|
304
|
+
pluginName: schema.pluginVulnExposure.pluginName,
|
|
305
|
+
pluginVersion: schema.pluginVulnExposure.pluginVersion,
|
|
306
|
+
triagedBy: schema.pluginVulnExposure.triagedBy,
|
|
307
|
+
acceptedUntil: schema.pluginVulnExposure.acceptedUntil,
|
|
308
|
+
}).from(schema.pluginVulnExposure)
|
|
309
|
+
.where(and(eq(schema.pluginVulnExposure.orgId, orgId), eq(schema.pluginVulnExposure.triageState, 'accepted'), isNull(schema.pluginVulnExposure.fixedAt), lte(schema.pluginVulnExposure.acceptedUntil, now))));
|
|
310
|
+
return rows;
|
|
311
|
+
}
|
|
312
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWV4cG9zdXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvcGx1Z2luLWV4cG9zdXJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDekMsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDakUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRTFELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV6RCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQW1CL0MsMERBQTBEO0FBQzFELFNBQVMsTUFBTSxDQUFDLENBQTRCO0lBQzFDLE1BQU0sQ0FBQyxHQUFHLHdCQUF3QixDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDakQsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQy9ELENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUFDLFFBQW1DLEVBQUUsTUFBaUM7SUFDL0YsTUFBTSxDQUFDLEdBQUcsTUFBTSxD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Q0FDbEQsQ0FBQyxDQUFDLENBQUM7SUFDTixPQUFPLElBQThILENBQUM7QUFDeEksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIFdoYXQgcGx1Z2luIHZlcnNpb25zIGFuIG9yZydzIHBpcGVsaW5lcyBhcmUgYWN0dWFsbHkgb24sIGFuZCB3aGljaCBvZiB0aG9zZSBhcmVcbiAqIGtub3duLXZ1bG5lcmFibGUuXG4gKlxuICogVHdvIHRhYmxlcywgd3JpdHRlbiBoZXJlLCByZWFkIGJ5IHRoZSBvdXRkYXRlZC1wbHVnaW4gYW5kIHZ1bG5lcmFiaWxpdHkgcmVwb3J0XG4gKiBzZWN0aW9uczpcbiAqXG4gKiAgLSBgcGlwZWxpbmVfcGx1Z2luX3Jlc29sdXRpb25gIOKAlCB0aGUgREVDTEFSRUQgc2lkZS4gUmVjb21wdXRlZCBvbiBwaXBlbGluZVxuICogICAgd3JpdGUgYW5kIG9uIHBsdWdpbiBwdWJsaXNoLCBiZWNhdXNlIHRoZSBhbHRlcm5hdGl2ZSBpcyByZXNvbHZpbmcgZXZlcnkgc3RlcFxuICogICAgb2YgZXZlcnkgcGlwZWxpbmUgYWdhaW5zdCB0aGUgY2F0YWxvZyBvbiBldmVyeSByZWFkLCBhbmQgdGhhdCBpcyBub3QgYSBxdWVyeVxuICogICAgYW55b25lIGNhbiBhZmZvcmQgdG8gcHV0IGluIGEgcmVwb3J0LlxuICogIC0gYHBsdWdpbl92dWxuX2V4cG9zdXJlYCDigJQgdGhlIFZVTE5FUkFCTEUgc2lkZSwgcGVyIFBJUEVMSU5FLiBBIHZlcnNpb24tbGV2ZWxcbiAqICAgIHRhYmxlIHdvdWxkIGZvcmNlIGV2ZXJ5IHJlYWRlciB0byByZS1kZXJpdmUgXCJ3aGljaCBvZiBvdXIgcGlwZWxpbmVzIGlzXG4gKiAgICBleHBvc2VkXCIsIHdoaWNoIGlzIHRoZSBvbmx5IGZvcm0gb2YgdGhlIHF1ZXN0aW9uIGFueWJvZHkgYXNrcy5cbiAqXG4gKiBERUNMQVJFRCBJUyBOT1QgREVQTE9ZRUQsIGFuZCB0aGUgcmVwb3J0IHNheXMgd2hpY2ggaXQgaXMgc2hvd2luZy4gQSBwaXBlbGluZSdzXG4gKiBjb25maWcgZGVjbGFyZXMgYF4yLjAuMGA7IHdoYXQgcmFuIGF0IGl0cyBsYXN0IGRlcGxveSBpcyB3aGF0ZXZlciB0aGUgc3RlcFxuICogbWFuaWZlc3QgcmVjb3JkZWQsIHBpbm5lZCB0byBhIGRpZ2VzdC4gVGhvc2UgZGlzYWdyZWUgd2hlbmV2ZXIgYSBwaXBlbGluZSBoYXMgbm90XG4gKiByZS1zeW50aGVkIHNpbmNlIGEgcHVibGlzaCDigJQgd2hpY2ggaXMgbW9zdCBvZiB0aGUgdGltZSwgYW5kIGV4YWN0bHkgdGhlIGdhcCBhXG4gKiB2dWxuZXJhYmlsaXR5IHJlcG9ydCBpcyBmb3IuIENvbmZsYXRpbmcgdGhlbSB3b3VsZCBsZXQgYSByZXBvcnQgc2F5IFwiZml4ZWRcIlxuICogYWJvdXQgYSBwaXBlbGluZSBzdGlsbCBydW5uaW5nIHRoZSBvbGQgaW1hZ2UuXG4gKi9cblxuaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gJ25vZGU6Y3J5cHRvJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgYW5kLCBlcSwgaW5BcnJheSwgaXNOdWxsLCBsdGUsIHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IHNjaGVtYSB9IGZyb20gJy4uLy4uL2RhdGFiYXNlL2RyaXp6bGUtc2NoZW1hLmpzJztcbmltcG9ydCB0eXBlIHsgRXhwb3N1cmVTb3VyY2UgfSBmcm9tICcuLi8uLi9kYXRhYmFzZS9zY2hlbWEvcmVwb3J0aW5nLWFuYWx5dGljcy5qcyc7XG5pbXBvcnQgeyB3aXRoVGVuYW50VHggfSBmcm9tICcuLi8uLi9kYXRhYmFzZS90ZW5hbmN5LmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdwbHVnaW4tZXhwb3N1cmUnKTtcblxuLyoqIEhvdyBmYXIgYmVoaW5kIGEgcmVzb2x2ZWQgdmVyc2lvbiBpcyBmcm9tIHRoZSBuZXdlc3Qgb25lIGF2YWlsYWJsZS4gKi9cbmV4cG9ydCB0eXBlIFZlcnNpb25HYXAgPSAnbWFqb3InIHwgJ21pbm9yJyB8ICdwYXRjaCcgfCAnbm9uZSc7XG5cbi8qKiBPbmUgcmVzb2x2ZWQgc3RlcCwgYXMgdGhlIHdyaXRlciB0YWtlcyBpdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRTdGVwIHtcbiAgb3JnSWQ6IHN0cmluZztcbiAgcGlwZWxpbmVJZDogc3RyaW5nO1xuICBzdGFnZU5hbWU6IHN0cmluZztcbiAgc3RlcE5hbWU6IHN0cmluZztcbiAgcGx1Z2luUHVibGlzaGVyPzogc3RyaW5nIHwgbnVsbDtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBkZWNsYXJlZFZlcnNpb24/OiBzdHJpbmcgfCBudWxsO1xuICByZXNvbHZlZFZlcnNpb24/OiBzdHJpbmcgfCBudWxsO1xuICBsYXRlc3RWZXJzaW9uPzogc3RyaW5nIHwgbnVsbDtcbiAgd2l0aGluUG9saWN5PzogYm9vbGVhbjtcbn1cblxuLyoqIGAxLjIuM2Ag4oaSIGBbMSwgMiwgM11gOyBhbnl0aGluZyB1bnBhcnNlYWJsZSDihpIgbnVsbC4gKi9cbmZ1bmN0aW9uIHNlbXZlcih2OiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgbnVsbCB7XG4gIGNvbnN0IG0gPSAvXnY/KFxcZCspXFwuKFxcZCspXFwuKFxcZCspLy5leGVjKHYgPz8gJycpO1xuICByZXR1cm4gbSA/IFtOdW1iZXIobVsxXSksIE51bWJlcihtWzJdKSwgTnVtYmVyKG1bM10pXSA6IG51bGw7XG59XG5cbi8qKlxuICogSG93IGZhciBgcmVzb2x2ZWRgIGlzIGJlaGluZCBgbGF0ZXN0YC5cbiAqXG4gKiBgbnVsbGAgd2hlbiBlaXRoZXIgc2lkZSBpcyB1bnBhcnNlYWJsZSwgTk9UIGAnbm9uZSdgLiBcIldlIGNvdWxkIG5vdCB0ZWxsXCIgYW5kXG4gKiBcIml0IGlzIHVwIHRvIGRhdGVcIiBhcmUgb3Bwb3NpdGUgYW5zd2VycywgYW5kIHJlcG9ydGluZyB0aGUgc2Vjb25kIGZvciB0aGUgZmlyc3RcbiAqIGlzIGhvdyBhIHBpcGVsaW5lIG9uIGFuIGFuY2llbnQgcHJlLXJlbGVhc2UgdmVyc2lvbiBnZXRzIGEgY2xlYW4gYmlsbCBvZiBoZWFsdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJzaW9uR2FwKHJlc29sdmVkOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkLCBsYXRlc3Q6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQpOiBWZXJzaW9uR2FwIHwgbnVsbCB7XG4gIGNvbnN0IGEgPSBzZW12ZXIocmVzb2x2ZWQpO1xuICBjb25zdCBiID0gc2VtdmVyKGxhdGVzdCk7XG4gIGlmICghYSB8fCAhYikgcmV0dXJuIG51bGw7XG4gIGlmIChiWzBdID4gYVswXSkgcmV0dXJuICdtYWpvcic7XG4gIGlmIChiWzBdIDwgYVswXSkgcmV0dXJuICdub25lJzsgLy8gcmVzb2x2ZWQgaXMgYWhlYWQgb2YgXCJsYXRlc3RcIiDigJQgbm90IGJlaGluZFxuICBpZiAoYlsxXSA+IGFbMV0pIHJldHVybiAnbWlub3InO1xuICBpZiAoYlsxXSA8IGFbMV0pIHJldHVybiAnbm9uZSc7XG4gIGlmIChiWzJdID4gYVsyXSkgcmV0dXJuICdwYXRjaCc7XG4gIHJldHVybiAnbm9uZSc7XG59XG5cbi8qKlxuICogUmVwbGFjZSBhIHBpcGVsaW5lJ3MgcmVzb2x1dGlvbiByb3dzLlxuICpcbiAqIERFTEVURS10aGVuLUlOU0VSVCBmb3IgdGhlIHBpcGVsaW5lLCBpbiBvbmUgdHJhbnNhY3Rpb24sIGJlY2F1c2UgYSBzdGVwIGNhbiBiZVxuICogUkVNT1ZFRCBmcm9tIGEgY29uZmlnOiBhbiB1cHNlcnQtb25seSB3cml0ZXIgd291bGQgbGVhdmUgdGhlIGRlbGV0ZWQgc3RlcCdzIHJvd1xuICogYmVoaW5kIGZvcmV2ZXIsIGFuZCB0aGUgb3V0ZGF0ZWQtcGx1Z2luIHNlY3Rpb24gd291bGQga2VlcCByZXBvcnRpbmcgYSBzdGVwIHRoZVxuICogcGlwZWxpbmUgbm8gbG9uZ2VyIGhhcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcGxhY2VQaXBlbGluZVJlc29sdXRpb24oXG4gIHBpcGVsaW5lSWQ6IHN0cmluZyxcbiAgc3RlcHM6IHJlYWRvbmx5IFJlc29sdmVkU3RlcFtdLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgY29uc3QgdmFsdWVzID0gc3RlcHMubWFwKChzKSA9PiAoe1xuICAgIG9yZ0lkOiBzLm9yZ0lkLFxuICAgIHBpcGVsaW5lSWQ6IHMucGlwZWxpbmVJZCxcbiAgICBzdGFnZU5hbWU6IHMuc3RhZ2VOYW1lLFxuICAgIHN0ZXBOYW1lOiBzLnN0ZXBOYW1lLFxuICAgIHBsdWdpblB1Ymxpc2hlcjogcy5wbHVnaW5QdWJsaXNoZXIgPz8gbnVsbCxcbiAgICBwbHVnaW5OYW1lOiBzLnBsdWdpbk5hbWUsXG4gICAgZGVjbGFyZWRWZXJzaW9uOiBzLmRlY2xhcmVkVmVyc2lvbiA/PyBudWxsLFxuICAgIHJlc29sdmVkVmVyc2lvbjogcy5yZXNvbHZlZFZlcnNpb24gPz8gbnVsbCxcbiAgICBsYXRlc3RWZXJzaW9uOiBzLmxhdGVzdFZlcnNpb24gPz8gbnVsbCxcbiAgICB2ZXJzaW9uR2FwOiB2ZXJzaW9uR2FwKHMucmVzb2x2ZWRWZXJzaW9uLCBzLmxhdGVzdFZlcnNpb24pLFxuICAgIHdpdGhpblBvbGljeTogcy53aXRoaW5Qb2xpY3kgPz8gdHJ1ZSxcbiAgICBjb21wdXRlZEF0OiBuZXcgRGF0ZSgpLFxuICB9KSk7XG5cbiAgcmV0dXJuIHdpdGhUZW5hbnRUeChhc3luYyAodHgpID0+IHtcbiAgICBhd2FpdCB0eC5kZWxldGUoc2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbilcbiAgICAgIC53aGVyZShlcShzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnBpcGVsaW5lSWQsIHBpcGVsaW5lSWQpKTtcbiAgICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDA7XG4gICAgY29uc3QgbGFuZGVkID0gYXdhaXQgdHguaW5zZXJ0KHNjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24pLnZhbHVlcyh2YWx1ZXMpXG4gICAgICAucmV0dXJuaW5nKHsgcGlwZWxpbmVJZDogc2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5waXBlbGluZUlkIH0pO1xuICAgIHJldHVybiAobGFuZGVkIGFzIHVua25vd25bXSkubGVuZ3RoO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZWZyZXNoIHRoZSBgbGF0ZXN0YC9nYXAgY29sdW1ucyBmb3Igb25lIHBsdWdpbiBhY3Jvc3MgZXZlcnkgcGlwZWxpbmUgdGhhdCB1c2VzXG4gKiBpdCwgd2l0aG91dCByZS1yZXNvbHZpbmcgYW55dGhpbmcgZWxzZS5cbiAqXG4gKiBDYWxsZWQgb24gcHVibGlzaC4gQSBwdWJsaXNoIGNoYW5nZXMgd2hhdCBcImxhdGVzdFwiIG1lYW5zIGZvciBldmVyeSBwaXBlbGluZSBpblxuICogdGhlIGluc3RhbmNlIHRoYXQgZGVjbGFyZXMgdGhlIHBsdWdpbiwgYW5kIHJlLXJlc29sdmluZyBlYWNoIG9mIHRob3NlIHBpcGVsaW5lc1xuICogZnJvbSBzY3JhdGNoIHdvdWxkIG1ha2UgcHVibGlzaGluZyBjb3N0IE8ocGlwZWxpbmVzKSB3b3JrIOKAlCBzbyBvbmx5IHRoZSB0d29cbiAqIGNvbHVtbnMgYSBwdWJsaXNoIGNhbiBjaGFuZ2UgYXJlIHRvdWNoZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWZyZXNoTGF0ZXN0Rm9yUGx1Z2luKFxuICBwbHVnaW5OYW1lOiBzdHJpbmcsXG4gIHBsdWdpblB1Ymxpc2hlcjogc3RyaW5nIHwgbnVsbCxcbiAgbGF0ZXN0VmVyc2lvbjogc3RyaW5nLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LnVwZGF0ZShzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uKVxuICAgIC5zZXQoe1xuICAgICAgbGF0ZXN0VmVyc2lvbixcbiAgICAgIC8vIFJlY29tcHV0ZWQgaW4gU1FMIGZyb20gdGhlIHJvdydzIG93biByZXNvbHZlZCB2ZXJzaW9uLCBzbyBvbmUgc3RhdGVtZW50XG4gICAgICAvLyBjb3ZlcnMgZXZlcnkgcGlwZWxpbmUgcmF0aGVyIHRoYW4gYSByb3VuZCB0cmlwIGVhY2guXG4gICAgICAvLyBgOjp0ZXh0YCBvbiBldmVyeSBiaW5kIG9mIHRoZSB2ZXJzaW9uOiBQb3N0Z3JlcyBvdGhlcndpc2UgZGVkdWNlc1xuICAgICAgLy8gaW5jb25zaXN0ZW50IHR5cGVzIGZvciB0aGUgc2FtZSBwYXJhbWV0ZXIgKHZhcmNoYXIgZm9yIHRoZSBhc3NpZ25tZW50LFxuICAgICAgLy8gdGV4dCBmb3IgYHNwbGl0X3BhcnRgKSBhbmQgcmVmdXNlcyB0byBwbGFuIHRoZSBzdGF0ZW1lbnQuXG4gICAgICB2ZXJzaW9uR2FwOiBzcWxgQ0FTRVxuICAgICAgICBXSEVOICR7c2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5yZXNvbHZlZFZlcnNpb259IElTIE5VTEwgVEhFTiBOVUxMXG4gICAgICAgIFdIRU4gc3BsaXRfcGFydCgke2xhdGVzdFZlcnNpb259Ojp0ZXh0LCAnLicsIDEpOjppbnQgPiBzcGxpdF9wYXJ0KCR7c2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5yZXNvbHZlZFZlcnNpb259LCAnLicsIDEpOjppbnQgVEhFTiAnbWFqb3InXG4gICAgICAgIFdIRU4gc3BsaXRfcGFydCgke2xhdGVzdFZlcnNpb259Ojp0ZXh0LCAnLicsIDEpOjppbnQgPCBzcGxpdF9wYXJ0KCR7c2NoZW1hLnBpcGVsaW5lUGx1Z2luUmVzb2x1dGlvbi5yZXNvbHZlZFZlcnNpb259LCAnLicsIDEpOjppbnQgVEhFTiAnbm9uZSdcbiAgICAgICAgV0hFTiBzcGxpdF9wYXJ0KCR7bGF0ZXN0VmVyc2lvbn06OnRleHQsICcuJywgMik6OmludCA+IHNwbGl0X3BhcnQoJHtzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnJlc29sdmVkVmVyc2lvbn0sICcuJywgMik6OmludCBUSEVOICdtaW5vcidcbiAgICAgICAgV0hFTiBzcGxpdF9wYXJ0KCR7bGF0ZXN0VmVyc2lvbn06OnRleHQsICcuJywgMik6OmludCA8IHNwbGl0X3BhcnQoJHtzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnJlc29sdmVkVmVyc2lvbn0sICcuJywgMik6OmludCBUSEVOICdub25lJ1xuICAgICAgICBXSEVOIHNwbGl0X3BhcnQoJHtsYXRlc3RWZXJzaW9ufTo6dGV4dCwgJy4nLCAzKTo6aW50ID4gc3BsaXRfcGFydCgke3NjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucmVzb2x2ZWRWZXJzaW9ufSwgJy4nLCAzKTo6aW50IFRIRU4gJ3BhdGNoJ1xuICAgICAgICBFTFNFICdub25lJyBFTkRgLFxuICAgICAgY29tcHV0ZWRBdDogbmV3IERhdGUoKSxcbiAgICB9KVxuICAgIC53aGVyZShhbmQoXG4gICAgICBlcShzY2hlbWEucGlwZWxpbmVQbHVnaW5SZXNvbHV0aW9uLnBsdWdpbk5hbWUsIHBsdWdpbk5hbWUpLFxuICAgICAgcGx1Z2luUHVibGlzaGVyID09PSBudWxsXG4gICAgICAgID8gaXNOdWxsKHNjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucGx1Z2luUHVibGlzaGVyKVxuICAgICAgICA6IGVxKHNjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucGx1Z2luUHVibGlzaGVyLCBwbHVnaW5QdWJsaXNoZXIpLFxuICAgICAgLy8gT25seSByb3dzIHdob3NlIHJlc29sdmVkIHZlcnNpb24gcGFyc2VzIGFzIHNlbXZlcjsgYW55dGhpbmcgZWxzZSBoYXMgbm9cbiAgICAgIC8vIGdhcCB0byBjb21wdXRlIGFuZCB0aGUgQ0FTRSB3b3VsZCB0aHJvdyBvbiB0aGUgY2FzdC5cbiAgICAgIHNxbGAke3NjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucmVzb2x2ZWRWZXJzaW9ufSB+ICdeWzAtOV0rXFxcXC5bMC05XStcXFxcLlswLTldKydgLFxuICAgICkpXG4gICAgLnJldHVybmluZyh7IHBpcGVsaW5lSWQ6IHNjaGVtYS5waXBlbGluZVBsdWdpblJlc29sdXRpb24ucGlwZWxpbmVJZCB9KSk7XG4gIHJldHVybiAocm93cyBhcyB1bmtub3duW10pLmxlbmd0aDtcbn1cblxuLyoqIE9uZSBmbGFnZ2VkIHZlcnNpb24sIGFzIHRoZSByZXNjYW4gcmVwb3J0cyBpdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXhwb3N1cmVJbnB1dCB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIHBpcGVsaW5lSWQ6IHN0cmluZztcbiAgcGx1Z2luUHVibGlzaGVyPzogc3RyaW5nIHwgbnVsbDtcbiAgcGx1Z2luTmFtZTogc3RyaW5nO1xuICBwbHVnaW5WZXJzaW9uOiBzdHJpbmc7XG4gIGltYWdlRGlnZXN0Pzogc3RyaW5nIHwgbnVsbDtcbiAgc291cmNlOiBFeHBvc3VyZVNvdXJjZTtcbiAgY3JpdGljYWxDb3VudDogbnVtYmVyO1xuICBoaWdoQ291bnQ6IG51bWJlcjtcbiAgdG9wRmluZGluZ3M/OiBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG59XG5cbi8qKlxuICogT3BlbiBvciByZWZyZXNoIGV4cG9zdXJlcy5cbiAqXG4gKiBVcHNlcnRzIG9uIChwaXBlbGluZSwgcGx1Z2luLCB2ZXJzaW9uLCBzb3VyY2UpIHNvIGEgbmlnaHRseSByZXNjYW4gUkVGUkVTSEVTIHRoZVxuICogY291bnRzIHJhdGhlciB0aGFuIG9wZW5pbmcgYSBuZXcgcm93IGV2ZXJ5IG5pZ2h0IOKAlCBvdGhlcndpc2UgdGhlIHJlcG9ydCB3b3VsZFxuICogc2hvdyBvbmUgZXhwb3N1cmUgcGVyIG5pZ2h0IG9mIHRoZSBzYW1lIHByb2JsZW0sIHdoaWNoIHJlYWRzIGFzIGFuIGVzY2FsYXRpbmdcbiAqIHNpdHVhdGlvbiB3aGVuIG5vdGhpbmcgY2hhbmdlZC5cbiAqXG4gKiBBIHJlZnJlc2ggZGVsaWJlcmF0ZWx5IGRvZXMgTk9UIHJlc2V0IGB0cmlhZ2Vfc3RhdGVgOiBhbiBvcmcgdGhhdCBhY2NlcHRlZCBhXG4gKiBmaW5kaW5nIHdpdGggYSByZWFzb24gYW5kIGEgZGVhZGxpbmUgaGFzIG1hZGUgYSBkZWNpc2lvbiwgYW5kIHJlLXJhaXNpbmcgaXQgZXZlcnlcbiAqIG5pZ2h0IGlzIGhvdyBhIHRlYW0gbGVhcm5zIHRvIGlnbm9yZSB0aGUgcmVwb3J0LiBJdCBET0VTIGNsZWFyIGEgc3RhbGVcbiAqIGFjY2VwdGFuY2UsIGJlY2F1c2UgdGhhdCBpcyB3aGF0IHRoZSBkZWFkbGluZSB3YXMgZm9yLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdXBzZXJ0RXhwb3N1cmVzKGlucHV0czogcmVhZG9ubHkgRXhwb3N1cmVJbnB1dFtdLCBub3cgPSBuZXcgRGF0ZSgpKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDApIHJldHVybiAwO1xuICBjb25zdCB2YWx1ZXMgPSBpbnB1dHMubWFwKChlKSA9PiAoe1xuICAgIGlkOiByYW5kb21VVUlEKCksXG4gICAgb3JnSWQ6IGUub3JnSWQsXG4gICAgcGlwZWxpbmVJZDogZS5waXBlbGluZUlkLFxuICAgIHBsdWdpblB1Ymxpc2hlcjogZS5wbHVnaW5QdWJsaXNoZXIgPz8gbnVsbCxcbiAgICBwbHVnaW5OYW1lOiBlLnBsdWdpbk5hbWUsXG4gICAgcGx1Z2luVmVyc2lvbjogZS5wbHVnaW5WZXJzaW9uLFxuICAgIGltYWdlRGlnZXN0OiBlLmltYWdlRGlnZXN0ID8/IG51bGwsXG4gICAgc291cmNlOiBlLnNvdXJjZSxcbiAgICBjcml0aWNhbENvdW50OiBlLmNyaXRpY2FsQ291bnQsXG4gICAgaGlnaENvdW50OiBlLmhpZ2hDb3VudCxcbiAgICB0b3BGaW5kaW5nczogZS50b3BGaW5kaW5ncyA/PyBbXSxcbiAgICBmbGFnZ2VkQXQ6IG5vdyxcbiAgICB1cGRhdGVkQXQ6IG5vdyxcbiAgfSkpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgbGFuZGVkID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguaW5zZXJ0KHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUpLnZhbHVlcyh2YWx1ZXMpXG4gICAgICAub25Db25mbGljdERvVXBkYXRlKHtcbiAgICAgICAgdGFyZ2V0OiBbXG4gICAgICAgICAgc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5waXBlbGluZUlkLFxuICAgICAgICAgIHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luTmFtZSxcbiAgICAgICAgICBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBsdWdpblZlcnNpb24sXG4gICAgICAgICAgc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5zb3VyY2UsXG4gICAgICAgIF0sXG4gICAgICAgIHNldDoge1xuICAgICAgICAgIGNyaXRpY2FsQ291bnQ6IHNxbGBleGNsdWRlZC5jcml0aWNhbF9jb3VudGAsXG4gICAgICAgICAgaGlnaENvdW50OiBzcWxgZXhjbHVkZWQuaGlnaF9jb3VudGAsXG4gICAgICAgICAgdG9wRmluZGluZ3M6IHNxbGBleGNsdWRlZC50b3BfZmluZGluZ3NgLFxuICAgICAgICAgIGltYWdlRGlnZXN0OiBzcWxgQ09BTEVTQ0UoZXhjbHVkZWQuaW1hZ2VfZGlnZXN0LCAke3NjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuaW1hZ2VEaWdlc3R9KWAsXG4gICAgICAgICAgLy8gU3RpbGwgZXhwb3NlZCwgc28gdGhlIGZpeCBtYXJrZXIgaXMgY2xlYXJlZDogYSByb3cgdGhhdCB3YXMgY2xvc2VkIGJ5IGFcbiAgICAgICAgICAvLyBkZXBsb3kgYW5kIGlzIGZsYWdnZWQgYWdhaW4gaXMgYSByZWdyZXNzaW9uLCBhbmQgbGVhdmluZyBgZml4ZWRfYXRgIHNldFxuICAgICAgICAgIC8vIHdvdWxkIGhpZGUgaXQuXG4gICAgICAgICAgZml4ZWRBdDogbnVsbCxcbiAgICAgICAgICAvLyBBbiBhY2NlcHRhbmNlIHBhc3QgaXRzIGRlYWRsaW5lIHN0b3BzIGJlaW5nIGFuIGFjY2VwdGFuY2UuIFRoYXQgaXMgdGhlXG4gICAgICAgICAgLy8gZW50aXJlIHBvaW50IG9mIHRpbWUtYm94aW5nIGl0LCBhbmQgaXQgaXMgZW5mb3JjZWQgSEVSRSByYXRoZXIgdGhhbiBhdFxuICAgICAgICAgIC8vIHJlYWQgdGltZSBzbyB0aGUgc3RvcmVkIHN0YXRlIGlzIHRoZSB0cnV0aC5cbiAgICAgICAgICB0cmlhZ2VTdGF0ZTogc3FsYENBU0VcbiAgICAgICAgICAgIFdIRU4gJHtzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnRyaWFnZVN0YXRlfSA9ICdhY2NlcHRlZCdcbiAgICAgICAgICAgICBBTkQgJHtzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmFjY2VwdGVkVW50aWx9IElTIE5PVCBOVUxMXG4gICAgICAgICAgICAgQU5EICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5hY2NlcHRlZFVudGlsfSA8PSAke25vd31cbiAgICAgICAgICAgIFRIRU4gJ29wZW4nXG4gICAgICAgICAgICBXSEVOICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZX0gPSAnZml4ZWQnIFRIRU4gJ29wZW4nXG4gICAgICAgICAgICBFTFNFICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZX0gRU5EYCxcbiAgICAgICAgICB1cGRhdGVkQXQ6IG5vdyxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgICAucmV0dXJuaW5nKHsgaWQ6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuaWQgfSkpO1xuICAgIHJldHVybiAobGFuZGVkIGFzIHVua25vd25bXSkubGVuZ3RoO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybignUGx1Z2luIGV4cG9zdXJlIHVwc2VydCBmYWlsZWQnLCB7IGNvdW50OiB2YWx1ZXMubGVuZ3RoLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgcmV0dXJuIDA7XG4gIH1cbn1cblxuLyoqXG4gKiBDbG9zZSB0aGUgZXhwb3N1cmVzIGEgcGlwZWxpbmUgaGFzIG1vdmVkIG9mZi5cbiAqXG4gKiBDYWxsZWQgd2hlbiBhIGRlcGxveSByZWNvcmRzIGEgbmV3IHN0ZXAgbWFuaWZlc3Q6IGFueXRoaW5nIGZsYWdnZWQgZm9yIHRoYXRcbiAqIHBpcGVsaW5lIHdob3NlIHZlcnNpb24gaXMgTk9UIGluIHRoZSBzZXQgaXQgbm93IHJ1bnMgaXMgZml4ZWQuIENsb3NpbmcgYnlcbiAqIGFic2VuY2UgcmF0aGVyIHRoYW4gd2FpdGluZyBmb3IgYSByZXNjYW4gdG8gbm90aWNlIGlzIHdoYXQgbWFrZXMgXCJ3ZSBmaXhlZCBpdFwiXG4gKiBzaG93IHVwIGluIHRoZSByZXBvcnQgb24gdGhlIG5leHQgZGVwbG95IGluc3RlYWQgb2YgdGhlIG5leHQgbmlnaHQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbG9zZUZpeGVkRXhwb3N1cmVzKFxuICBwaXBlbGluZUlkOiBzdHJpbmcsXG4gIGxpdmVWZXJzaW9uczogUmVhZG9ubHlBcnJheTx7IHBsdWdpbk5hbWU6IHN0cmluZzsgcGx1Z2luVmVyc2lvbjogc3RyaW5nIH0+LFxuICBub3cgPSBuZXcgRGF0ZSgpLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgY29uc3QgbGl2ZSA9IG5ldyBTZXQobGl2ZVZlcnNpb25zLm1hcCgodikgPT4gYCR7di5wbHVnaW5OYW1lfUAke3YucGx1Z2luVmVyc2lvbn1gKSk7XG4gIGNvbnN0IG9wZW4gPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5zZWxlY3Qoe1xuICAgIGlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkLFxuICAgIHBsdWdpbk5hbWU6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luTmFtZSxcbiAgICBwbHVnaW5WZXJzaW9uOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBsdWdpblZlcnNpb24sXG4gIH0pLmZyb20oc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAud2hlcmUoYW5kKFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5waXBlbGluZUlkLCBwaXBlbGluZUlkKSxcbiAgICAgIGlzTnVsbChzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmZpeGVkQXQpLFxuICAgICkpKTtcbiAgY29uc3Qgc3RhbGUgPSAob3BlbiBhcyBBcnJheTx7IGlkOiBzdHJpbmc7IHBsdWdpbk5hbWU6IHN0cmluZzsgcGx1Z2luVmVyc2lvbjogc3RyaW5nIH0+KVxuICAgIC5maWx0ZXIoKHIpID0+ICFsaXZlLmhhcyhgJHtyLnBsdWdpbk5hbWV9QCR7ci5wbHVnaW5WZXJzaW9ufWApKVxuICAgIC5tYXAoKHIpID0+IHIuaWQpO1xuICBpZiAoc3RhbGUubGVuZ3RoID09PSAwKSByZXR1cm4gMDtcblxuICBjb25zdCBjbG9zZWQgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC51cGRhdGUoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAuc2V0KHsgZml4ZWRBdDogbm93LCB0cmlhZ2VTdGF0ZTogJ2ZpeGVkJywgdXBkYXRlZEF0OiBub3cgfSlcbiAgICAud2hlcmUoaW5BcnJheShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkLCBzdGFsZSkpXG4gICAgLnJldHVybmluZyh7IGlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkIH0pKTtcbiAgcmV0dXJuIChjbG9zZWQgYXMgdW5rbm93bltdKS5sZW5ndGg7XG59XG5cbi8qKlxuICogVGhlIG9yZydzIGxpdmUgZXhwb3N1cmVzLCBmb3IgdGhlIHJlcG9ydCBzZWN0aW9uLlxuICpcbiAqIGBhY2NlcHRlZGAgcm93cyB3aG9zZSBkZWFkbGluZSBoYXMgcGFzc2VkIGNvbWUgYmFjayBhcyBPUEVOIGV2ZW4gaWYgbm8gcmVzY2FuXG4gKiBoYXMgcmVmcmVzaGVkIHRoZW0geWV0OiBhIHJlYWQgbXVzdCBub3QgcHJlc2VudCBhbiBleHBpcmVkIGFjY2VwdGFuY2UgYXMgYVxuICogY3VycmVudCBvbmUsIGFuZCB0aGUgcmVwb3J0IGlzIHJlYWQgZmFyIG1vcmUgb2Z0ZW4gdGhhbiB0aGUgcmVzY2FuIHJ1bnMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuRXhwb3N1cmVzKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPEFycmF5PHtcbiAgcGlwZWxpbmVJZDogc3RyaW5nO1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIHBsdWdpblZlcnNpb246IHN0cmluZztcbiAgcGx1Z2luUHVibGlzaGVyOiBzdHJpbmcgfCBudWxsO1xuICBzb3VyY2U6IEV4cG9zdXJlU291cmNlO1xuICBjcml0aWNhbENvdW50OiBudW1iZXI7XG4gIGhpZ2hDb3VudDogbnVtYmVyO1xuICB0b3BGaW5kaW5nczogQXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICB0cmlhZ2VTdGF0ZTogc3RyaW5nO1xuICBmbGFnZ2VkQXQ6IERhdGU7XG59Pj4ge1xuICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICBjb25zdCByb3dzID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguc2VsZWN0KHtcbiAgICBwaXBlbGluZUlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBpcGVsaW5lSWQsXG4gICAgcGx1Z2luTmFtZTogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5wbHVnaW5OYW1lLFxuICAgIHBsdWdpblZlcnNpb246IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luVmVyc2lvbixcbiAgICBwbHVnaW5QdWJsaXNoZXI6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luUHVibGlzaGVyLFxuICAgIHNvdXJjZTogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5zb3VyY2UsXG4gICAgY3JpdGljYWxDb3VudDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5jcml0aWNhbENvdW50LFxuICAgIGhpZ2hDb3VudDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5oaWdoQ291bnQsXG4gICAgdG9wRmluZGluZ3M6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUudG9wRmluZGluZ3MsXG4gICAgdHJpYWdlU3RhdGU6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUudHJpYWdlU3RhdGUsXG4gICAgYWNjZXB0ZWRVbnRpbDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5hY2NlcHRlZFVudGlsLFxuICAgIGZsYWdnZWRBdDogc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5mbGFnZ2VkQXQsXG4gIH0pLmZyb20oc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAud2hlcmUoYW5kKFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5vcmdJZCwgb3JnSWQpLFxuICAgICAgaXNOdWxsKHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuZml4ZWRBdCksXG4gICAgICAvLyBBbiBhY2NlcHRhbmNlIHRoYXQgaGFzIHJ1biBvdXQgaXMgbm90IGFuIGFjY2VwdGFuY2UuXG4gICAgICBzcWxgKCR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZX0gPD4gJ2FjY2VwdGVkJ1xuICAgICAgICAgICBPUiAke3NjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuYWNjZXB0ZWRVbnRpbH0gSVMgTlVMTFxuICAgICAgICAgICBPUiAke3NjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuYWNjZXB0ZWRVbnRpbH0gPD0gJHtub3d9KWAsXG4gICAgKSlcbiAgICAub3JkZXJCeShzcWxgJHtzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmNyaXRpY2FsQ291bnR9IERFU0MsICR7c2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5oaWdoQ291bnR9IERFU0NgKSk7XG5cbiAgcmV0dXJuIChyb3dzIGFzIEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PikubWFwKChyKSA9PiAoe1xuICAgIHBpcGVsaW5lSWQ6IHIucGlwZWxpbmVJZCBhcyBzdHJpbmcsXG4gICAgcGx1Z2luTmFtZTogci5wbHVnaW5OYW1lIGFzIHN0cmluZyxcbiAgICBwbHVnaW5WZXJzaW9uOiByLnBsdWdpblZlcnNpb24gYXMgc3RyaW5nLFxuICAgIHBsdWdpblB1Ymxpc2hlcjogKHIucGx1Z2luUHVibGlzaGVyIGFzIHN0cmluZyB8IG51bGwpID8/IG51bGwsXG4gICAgc291cmNlOiByLnNvdXJjZSBhcyBFeHBvc3VyZVNvdXJjZSxcbiAgICBjcml0aWNhbENvdW50OiByLmNyaXRpY2FsQ291bnQgYXMgbnVtYmVyLFxuICAgIGhpZ2hDb3VudDogci5oaWdoQ291bnQgYXMgbnVtYmVyLFxuICAgIHRvcEZpbmRpbmdzOiAoci50b3BGaW5kaW5ncyBhcyBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4pID8/IFtdLFxuICAgIC8vIEFuIGV4cGlyZWQgYWNjZXB0YW5jZSByZWFkcyBhcyBvcGVuLCB3aGljaCBpcyB3aGF0IGl0IGlzLlxuICAgIHRyaWFnZVN0YXRlOiByLnRyaWFnZVN0YXRlID09PSAnYWNjZXB0ZWQnICYmIHIuYWNjZXB0ZWRVbnRpbCA/ICdvcGVuJyA6IChyLnRyaWFnZVN0YXRlIGFzIHN0cmluZyksXG4gICAgZmxhZ2dlZEF0OiByLmZsYWdnZWRBdCBhcyBEYXRlLFxuICB9KSk7XG59XG5cbi8qKlxuICogUmVjb3JkIGEgdHJpYWdlIGRlY2lzaW9uLlxuICpcbiAqIGBhY2NlcHRlZGAgUkVRVUlSRVMgYSBkZWFkbGluZSBhbmQgYSByZWFzb24uIEEgcGVybWFuZW50LCB1bmV4cGxhaW5lZCBtdXRlIGlzXG4gKiBob3cgYSBmaW5kaW5nIHN0b3BzIGJlaW5nIGFueWJvZHkncyBwcm9ibGVtLCBhbmQgdGhlcmUgaXMgbm8gZ29vZCByZWFzb24gdG9cbiAqIHN1cHBvcnQgaXQg4oCUIHRoZSBjYWxsZXIgZ2V0cyBhbiBlcnJvciByYXRoZXIgdGhhbiBhIHNpbGVudGx5IHVuYm91bmRlZFxuICogYWNjZXB0YW5jZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRyaWFnZUV4cG9zdXJlKFxuICBvcmdJZDogc3RyaW5nLFxuICBpZDogc3RyaW5nLFxuICBkZWNpc2lvbjogeyBzdGF0ZTogJ29wZW4nIHwgJ2FjY2VwdGVkJyB8ICdmYWxzZV9wb3NpdGl2ZSc7IHJlYXNvbj86IHN0cmluZzsgYWNjZXB0ZWRVbnRpbD86IERhdGU7IGFjdG9yOiBzdHJpbmcgfSxcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBpZiAoZGVjaXNpb24uc3RhdGUgPT09ICdhY2NlcHRlZCcgJiYgKCFkZWNpc2lvbi5hY2NlcHRlZFVudGlsIHx8ICFkZWNpc2lvbi5yZWFzb24/LnRyaW0oKSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0FjY2VwdGluZyBhIHZ1bG5lcmFiaWxpdHkgZXhwb3N1cmUgbmVlZHMgYSByZWFzb24gYW5kIGFuIGV4cGlyeSBkYXRlJyk7XG4gIH1cbiAgY29uc3Qgcm93cyA9IGF3YWl0IHdpdGhUZW5hbnRUeCgodHgpID0+IHR4LnVwZGF0ZShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlKVxuICAgIC5zZXQoe1xuICAgICAgdHJpYWdlU3RhdGU6IGRlY2lzaW9uLnN0YXRlLFxuICAgICAgYWNjZXB0ZWRVbnRpbDogZGVjaXNpb24uc3RhdGUgPT09ICdhY2NlcHRlZCcgPyAoZGVjaXNpb24uYWNjZXB0ZWRVbnRpbCA/PyBudWxsKSA6IG51bGwsXG4gICAgICB0cmlhZ2VSZWFzb246IGRlY2lzaW9uLnJlYXNvbiA/PyBudWxsLFxuICAgICAgdHJpYWdlZEJ5OiBkZWNpc2lvbi5hY3RvcixcbiAgICAgIHRyaWFnZWRBdDogbmV3IERhdGUoKSxcbiAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICB9KVxuICAgIC53aGVyZShhbmQoXG4gICAgICBlcShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkLCBpZCksXG4gICAgICBlcShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLm9yZ0lkLCBvcmdJZCksXG4gICAgKSlcbiAgICAucmV0dXJuaW5nKHsgaWQ6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUuaWQgfSkpO1xuICByZXR1cm4gKHJvd3MgYXMgdW5rbm93bltdKS5sZW5ndGggPiAwO1xufVxuXG4vKipcbiAqIEV4cG9zdXJlcyB3aG9zZSBhY2NlcHRhbmNlIGhhcyBsYXBzZWQsIGZvciB0aGUgb3JnJ3Mgc2VjdXJpdHkgbm90aWZpY2F0aW9ucy5cbiAqXG4gKiBTdXJmYWNlZCByYXRoZXIgdGhhbiBzaWxlbnRseSByZW9wZW5lZDogc29tZWJvZHkgZGVjaWRlZCB0byBhY2NlcHQgdGhpcyB1bnRpbCBhXG4gKiBkYXRlLCB0aGF0IGRhdGUgaGFzIHBhc3NlZCwgYW5kIHRoZSBwZXJzb24gd2hvIGRlY2lkZWQgaXMgdGhlIG9uZSB3aG8gc2hvdWxkXG4gKiBoZWFyIGFib3V0IGl0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbGFwc2VkQWNjZXB0YW5jZXMob3JnSWQ6IHN0cmluZywgbm93ID0gbmV3IERhdGUoKSk6IFByb21pc2U8QXJyYXk8e1xuICBpZDogc3RyaW5nO1xuICBwbHVnaW5OYW1lOiBzdHJpbmc7XG4gIHBsdWdpblZlcnNpb246IHN0cmluZztcbiAgdHJpYWdlZEJ5OiBzdHJpbmcgfCBudWxsO1xuICBhY2NlcHRlZFVudGlsOiBEYXRlIHwgbnVsbDtcbn0+PiB7XG4gIGNvbnN0IHJvd3MgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5zZWxlY3Qoe1xuICAgIGlkOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmlkLFxuICAgIHBsdWdpbk5hbWU6IHNjaGVtYS5wbHVnaW5WdWxuRXhwb3N1cmUucGx1Z2luTmFtZSxcbiAgICBwbHVnaW5WZXJzaW9uOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnBsdWdpblZlcnNpb24sXG4gICAgdHJpYWdlZEJ5OiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLnRyaWFnZWRCeSxcbiAgICBhY2NlcHRlZFVudGlsOiBzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmFjY2VwdGVkVW50aWwsXG4gIH0pLmZyb20oc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZSlcbiAgICAud2hlcmUoYW5kKFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5vcmdJZCwgb3JnSWQpLFxuICAgICAgZXEoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS50cmlhZ2VTdGF0ZSwgJ2FjY2VwdGVkJyksXG4gICAgICBpc051bGwoc2NoZW1hLnBsdWdpblZ1bG5FeHBvc3VyZS5maXhlZEF0KSxcbiAgICAgIGx0ZShzY2hlbWEucGx1Z2luVnVsbkV4cG9zdXJlLmFjY2VwdGVkVW50aWwsIG5vdyksXG4gICAgKSkpO1xuICByZXR1cm4gcm93cyBhcyBBcnJheTx7IGlkOiBzdHJpbmc7IHBsdWdpbk5hbWU6IHN0cmluZzsgcGx1Z2luVmVyc2lvbjogc3RyaW5nOyB0cmlhZ2VkQnk6IHN0cmluZyB8IG51bGw7IGFjY2VwdGVkVW50aWw6IERhdGUgfCBudWxsIH0+O1xufVxuIl19
|
|
@@ -95,6 +95,14 @@ export async function purgeExpiredReportingData(opts = {}) {
|
|
|
95
95
|
const outcomesTable = sql `${schema.deploymentOutcome}`;
|
|
96
96
|
const incidentsTable = sql `${schema.incident}`;
|
|
97
97
|
for (const { org_id: orgId } of orgRows) {
|
|
98
|
+
// Lock lost, or shutting down: stop between orgs. Every remaining org still
|
|
99
|
+
// has expired rows, so the next tick resumes exactly where this left off.
|
|
100
|
+
if (opts.run?.signal.aborted) {
|
|
101
|
+
logger.info('Reporting retention sweep stopping early', {
|
|
102
|
+
reason: String(opts.run.signal.reason ?? 'aborted'), orgsDone: counts.orgs,
|
|
103
|
+
});
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
98
106
|
// Retention follows the account ROOT's entitlement (billing syncs it onto
|
|
99
107
|
// the root only). An unresolvable root ⇒ skip this org this tick rather
|
|
100
108
|
// than purge a team's rows on the (shorter) env default.
|
|
@@ -152,4 +160,4 @@ export async function purgeExpiredReportingData(opts = {}) {
|
|
|
152
160
|
return counts;
|
|
153
161
|
});
|
|
154
162
|
}
|
|
155
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV0ZW50aW9uLXN3ZWVwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvcmV0ZW50aW9uLXN3ZWVwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7O0dBS0c7QUFFSCxPQUFPLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLHdCQUF3QixFQUFFLGVBQWUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRHLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMxRCxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDL0UsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRWpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0FBRW5EOzs7Ozs7Ozs7R0FTRztBQUNILEtBQUssVUFBVSwwQkFBMEIsQ0FDdkMsUUFBZ0MsRUFDaEMsU0FBaUMsRUFDakMsU0FBaUIsRUFDakIsVUFBa0I7SUFFbEIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sR0FBRyxHQUFHLE1BQU0sWUFBWSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQTtvQkFDckMsUUFBUTs7MkJBRUQsUUFBUTtnQkFDbkIsU0FBUztnQkFDVCxTQUFTOzs7S0FHcEIsQ0FBQyxDQUFDLENBQUM7UUFDSixNQUFNLE1BQU0sR0FBRyxXQUFXLENBQVUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUNyRCxLQUFLLElBQUksTUFBTSxDQUFDO1FBQ2hCLElBQUksTUFBTSxHQUFHLFNBQVM7WUFBRSxNQUFNLENBQUMsVUFBVTtRQUN6QyxJQUFJLENBQUMsS0FBSyxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekIsTUFBTSxDQUFDLElBQUksQ0FBQywrREFBK0QsRUFBRTtnQkFDM0UsY0FBYyxFQUFFLEtBQUs7YUFDdEIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUseUJBQXlCLENBQUMsSUFBSSxHQUE4QixFQUFFO0lBQ2xGLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLENBQUM7SUFDdEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzlELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLElBQUksSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUNuQyxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxxQkFBcUIsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFhLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdGLE1BQU0sTUFBTSxHQUE2QjtRQUN2QyxJQUFJLEVBQUUsQ0FBQyxFQUFFLGNBQWMsRUFBRSxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUM7S0FDL0UsQ0FBQztJQUVGLE9BQU8sb0JBQW9CLENBQUMsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDN0QsMkVBQTJFO1FBQzNFLE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBcUIsQ0FBQyxNQUFNLFlBQVksQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUE7O2lCQUU3RSxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssbUJBQW1CLE1BQU0sQ0FBQyxhQUFhOztpQkFFakUsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEtBQUssbUJBQW1CLE1BQU0sQ0FBQyxpQkFBaUI7O2lCQUV6RSxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssbUJBQW1CLE1BQU0sQ0FBQyxRQUFROztLQUVuRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ1gsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLE1BQU0sQ0FBQztRQUV4QyxnRkFBZ0Y7UUFDaEYsTUFBTSxZQUFZLEdBQUcsV0FBVyxDQUk3QixDQUFDLE1BQU0sWUFBWSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQTtlQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUs7ZUFDekIsTUFBTSxDQUFDLFlBQVksQ0FBQyxrQkFBa0I7ZUFDdEMsTUFBTSxDQUFDLFlBQVksQ0FBQyxpQkFBaUI7YUFDdkMsTUFBTSxDQUFDLFlBQVk7S0FDM0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNYLE1BQU0sU0FBUyxHQUFHLElBQUksR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFbEUsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFBLEdBQUcsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2pELE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQSxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3ZELE1BQU0sY0FBYyxHQUFHLEdBQUcsQ0FBQSxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUUvQyxLQUFLLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksT0FBTyxFQUFFLENBQUM7WUFDeEMsMEVBQTBFO1lBQzFFLHdFQUF3RTtZQUN4RSx5REFBeUQ7WUFDekQsSUFBSSxjQUE2QixDQUFDO1lBQ2xDLElBQUksQ0FBQztnQkFDSCxjQUFjLEdBQUcsTUFBTSxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0RCxDQUFDO1lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztnQkFDYixNQUFNLENBQUMsSUFBSSxDQUFDLG9FQUFvRSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUN2SCxjQUFjLEdBQUcsSUFBSSxDQUFDO1lBQ3hCLENBQUM7WUFDRCxJQUFJLGNBQWMsS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDNUIsTUFBTSxDQUFDLElBQUksQ0FBQyxrRkFBa0YsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7Z0JBQzNHLFNBQVM7WUFDWCxDQUFDO1lBQ0QsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUN6QyxNQUFNLFNBQVMsR0FBRyx5QkFBeUIsQ0FBQyxFQUFFLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztZQUN0RSxNQUFNLFFBQVEsR0FBRyx3QkFBd0IsQ0FBQyxFQUFFLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztZQUNuRSxpRUFBaUU7WUFDakUsMkVBQTJFO1lBQzNFLG9FQUFvRTtZQUNwRSxNQUFNLFVBQVUsR0FBRyxTQUFTLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDcEMsTUFBTSxRQUFRLEdBQUcsUUFBUSxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ2pDLElBQUksVUFBVSxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUMzQixNQUFNLENBQUMsSUFBSSxDQUFDLHdEQUF3RCxFQUFFO29CQUNwRSxLQUFLO29CQUNMLGNBQWMsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsU0FBUztvQkFDcEQsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxRQUFRO2lCQUM5QyxDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNoQixNQUFNLFdBQVcsR0FBRyxlQUFlLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUNwRCxNQUFNLENBQUMsY0FBYyxJQUFJLE1BQU0sMEJBQTBCLENBQ3ZELFdBQVc7Z0JBQ1gscUVBQXFFO2dCQUNyRSxzREFBc0Q7Z0JBQ3RELG9FQUFvRTtnQkFDcEUsbUVBQW1FO2dCQUNuRSxtRUFBbUU7Z0JBQ25FLGdFQUFnRTtnQkFDaEUsaUVBQWlFO2dCQUNqRSw0REFBNEQ7Z0JBQzVELEdBQUcsQ0FBQSxZQUFZLEtBQUssMEVBQTBFLFdBQVcsRUFBRSxFQUMzRyxTQUFTLEVBQUUsVUFBVSxDQUN0QixDQUFDO1lBQ0osQ0FBQztZQUVELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDZCxNQUFNLFVBQVUsR0FBRyxlQUFlLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUNsRCxNQUFNLENBQUMsVUFBVSxJQUFJLE1BQU0sMEJBQTBCLENBQ25ELFdBQVcsRUFDWCxHQUFHLENBQUEsWUFBWSxLQUFLLG1GQUFtRixVQUFVLEVBQUUsRUFDbkgsU0FBUyxFQUFFLFVBQVUsQ0FDdEIsQ0FBQztnQkFDRixNQUFNLENBQUMsa0JBQWtCLElBQUksTUFBTSwwQkFBMEIsQ0FDM0QsYUFBYSxFQUNiLEdBQUcsQ0FBQSxZQUFZLEtBQUsscUJBQXFCLFVBQVUsRUFBRSxFQUNyRCxTQUFTLEVBQUUsVUFBVSxDQUN0QixDQUFDO2dCQUNGLE1BQU0sQ0FBQyxTQUFTLElBQUksTUFBTSwwQkFBMEIsQ0FDbEQsY0FBYyxFQUNkLEdBQUcsQ0FBQSxZQUFZLEtBQUsscUJBQXFCLFVBQVUsRUFBRSxFQUNyRCxTQUFTLEVBQUUsVUFBVSxDQUN0QixDQUFDO1lBQ0osQ0FBQztZQUNELE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQ25CLENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsY0FBYyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7UUFDM0csSUFBSSxTQUFTLEdBQUcsQ0FBQztZQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsK0NBQStDLEVBQUUsRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDL0YsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogVGhlIHJlcG9ydGluZyByZXRlbnRpb24gU1dFRVA6IHRoZSBiYXRjaGVkIGhhcmQtZGVsZXRlIHRoYXQgZW5mb3JjZXMgdGhlXG4gKiB3aW5kb3dzIGAuL3JldGVudGlvbi50c2AgcmVzb2x2ZXMuIFNwbGl0IGZyb20gdGhlIHdpbmRvd3MgbW9kdWxlIHNvIHRoZSBwdXJlLFxuICogZW52LW9ubHkgcG9saWN5IHN0YXlzIGZyZWUgb2YgZGF0YWJhc2UgY29kZSwgYW5kIGZyb20gdGhlIHJlcG9ydGluZyBzZXJ2aWNlXG4gKiBiZWNhdXNlIHRoaXMgaXMgY3Jvc3MtdGVuYW50IGhvdXNla2VlcGluZywgbm90IGEgcmVwb3J0LlxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciwgZXJyb3JNZXNzYWdlIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgc3FsIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgcmVzb2x2ZUV2ZW50UmV0ZW50aW9uRGF5cywgcmVzb2x2ZURvcmFSZXRlbnRpb25EYXlzLCByZXRlbnRpb25DdXRvZmYgfSBmcm9tICcuL3JldGVudGlvbi5qcyc7XG5pbXBvcnQgdHlwZSB7IFJlcG9ydGluZ1JldGVudGlvbkNvdW50cywgUmVwb3J0aW5nUmV0ZW50aW9uT3B0aW9ucyB9IGZyb20gJy4vdHlwZXMuanMnO1xuaW1wb3J0IHsgc2NoZW1hIH0gZnJvbSAnLi4vLi4vZGF0YWJhc2UvZHJpenpsZS1zY2hlbWEuanMnO1xuaW1wb3J0IHsgd2l0aFRlbmFudFR4LCBydW5XaXRoVGVuYW50Q29udGV4dCB9IGZyb20gJy4uLy4uL2RhdGFiYXNlL3RlbmFuY3kuanMnO1xuaW1wb3J0IHsgZHJpenpsZVJvd3MgfSBmcm9tICcuLi9jcnVkLXNlcnZpY2UuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3JlcG9ydGluZy1yZXRlbnRpb24nKTtcblxuLyoqXG4gKiBCYXRjaGVkIGhhcmQtREVMRVRFIG9mIG9uZSByZXBvcnRpbmcgdGFibGUncyByb3dzIGV4cGlyZWQgcGFzdCBhIGBjcmVhdGVkX2F0YFxuICogY3V0b2ZmLCBzY29wZWQgdG8gYW4gb3JnIGFuZCBhbiBvcHRpb25hbCByb3cgcHJlZGljYXRlLiBVc2VzIGFcbiAqIGBjdGlkYC1pbi1zdWJxdWVyeSBMSU1JVCBzbyBlYWNoIHN0YXRlbWVudCB0b3VjaGVzIGF0IG1vc3QgYGJhdGNoU2l6ZWAgcm93c1xuICogKHNob3J0IGxvY2sgd2luZG93cywgbm8gbG9uZyB0YWJsZSBzY2FuIHVuZGVyIGxvY2spOyBgUkVUVVJOSU5HIDFgIGxldHMgdXNcbiAqIGNvdW50IHZpYSBgLnJvd3MubGVuZ3RoYCB3aXRob3V0IGRlcGVuZGluZyBvbiB0aGUgZHJpdmVyJ3MgYHJvd0NvdW50YC4gTG9vcHNcbiAqIHVudGlsIGEgc2hvcnQgYmF0Y2ggKGRyYWluZWQpIG9yIHRoZSBwZXItdGljayBjYXAsIHRoZW4gZGVmZXJzIHRoZSByZXN0LlxuICogTVVTVCBydW4gaW5zaWRlIGEgc3lzYWRtaW4gdGVuYW50IHNjb3BlIChzZWUgcHVyZ2VFeHBpcmVkUmVwb3J0aW5nRGF0YSkgc28gaXRcbiAqIGJ5cGFzc2VzIFJMUyBhbmQgY2FuIGRlbGV0ZSBhY3Jvc3MgdGhlIG9yZydzIHJvd3MuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHB1cmdlUmVwb3J0aW5nVGFibGVCYXRjaGVkKFxuICB0YWJsZVNxbDogUmV0dXJuVHlwZTx0eXBlb2Ygc3FsPixcbiAgcHJlZGljYXRlOiBSZXR1cm5UeXBlPHR5cGVvZiBzcWw+LFxuICBiYXRjaFNpemU6IG51bWJlcixcbiAgbWF4QmF0Y2hlczogbnVtYmVyLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgbGV0IHRvdGFsID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXhCYXRjaGVzOyBpKyspIHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgIERFTEVURSBGUk9NICR7dGFibGVTcWx9XG4gICAgICBXSEVSRSBjdGlkIElOIChcbiAgICAgICAgU0VMRUNUIGN0aWQgRlJPTSAke3RhYmxlU3FsfVxuICAgICAgICBXSEVSRSAke3ByZWRpY2F0ZX1cbiAgICAgICAgTElNSVQgJHtiYXRjaFNpemV9XG4gICAgICApXG4gICAgICBSRVRVUk5JTkcgMVxuICAgIGApKTtcbiAgICBjb25zdCBwdXJnZWQgPSBkcml6emxlUm93czx1bmtub3duPihyZXMucm93cykubGVuZ3RoO1xuICAgIHRvdGFsICs9IHB1cmdlZDtcbiAgICBpZiAocHVyZ2VkIDwgYmF0Y2hTaXplKSBicmVhazsgLy8gZHJhaW5lZFxuICAgIGlmIChpID09PSBtYXhCYXRjaGVzIC0gMSkge1xuICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyByZXRlbnRpb24gaGl0IHBlci10aWNrIGNhcDsgcmVtYWluaW5nIHJvd3MgZGVmZXJyZWQnLCB7XG4gICAgICAgIHB1cmdlZFRoaXNUaWNrOiB0b3RhbCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdG90YWw7XG59XG5cbi8qKlxuICogUmVwb3J0aW5nIHJldGVudGlvbiBzd2VlcC4gSGFyZC1kZWxldGVzIHJvd3Mgb2xkZXIgdGhhbiB0aGVpclxuICogcmV0ZW50aW9uIHdpbmRvdywgYnkgYGNyZWF0ZWRfYXRgLCBhY3Jvc3MgZXZlcnkgb3JnIHRoYXQgaGFzIHJlcG9ydGluZyBkYXRhIOKAlFxuICogYSAqKnNwbGl0KiogcG9saWN5IHNvIGhpZ2gtdm9sdW1lIHN0YW5kYXJkIGV2ZW50cyBleHBpcmUgZmFzdGVyIHRoYW4gdGhlXG4gKiBsb3ctdm9sdW1lIERPUkEgc291cmNlOlxuICogIC0gYHBpcGVsaW5lX2V2ZW50cyBXSEVSRSBlbnZpcm9ubWVudCBJUyBOVUxMYCDihpIgc3RhbmRhcmQtZXZlbnQgd2luZG93LlxuICogIC0gYHBpcGVsaW5lX2V2ZW50cyBXSEVSRSBlbnZpcm9ubWVudCBJUyBOT1QgTlVMTGAgKGRlcGxveSBzdGFnZXMpLFxuICogICAgYGRlcGxveW1lbnRfb3V0Y29tZXNgLCBhbmQgYGluY2lkZW50c2Ag4oaSIERPUkEtc291cmNlIHdpbmRvdy5cbiAqIEVhY2ggb3JnJ3Mgd2luZG93cyBjb21lIGZyb20gaXRzIGBkb3JhX3NldHRpbmdzYCBvdmVycmlkZSwgZWxzZSB0aGUgZ2xvYmFsXG4gKiBlbnYgZGVmYXVsdHMgKHNlZSB7QGxpbmsgcmVzb2x2ZUV2ZW50UmV0ZW50aW9uRGF5c30gLyB7QGxpbmsgcmVzb2x2ZURvcmFSZXRlbnRpb25EYXlzfSkuXG4gKiBgaW5nZXN0X2hlYWx0aGAgYW5kIGBkb3JhX3NldHRpbmdzYCBhcmUgbmV2ZXIgcHVyZ2VkLiBPbmUgYG5vd2AgZm9yIHRoZSB3aG9sZVxuICogdGljayAocm93cyBjcm9zc2luZyB0aGUgYm91bmRhcnkgbWlkLXN3ZWVwIHdhaXQgZm9yIHRoZSBuZXh0KS4gRXN0YWJsaXNoZXMgYVxuICogc3lzYWRtaW4gdGVuYW50IHNjb3BlIHNvIHRoZSBkZWxldGVzIHNwYW4gYWxsIG9yZ3MgLyBieXBhc3MgUkxTIOKAlCB0aGlzIGlzIGFcbiAqIGNyb3NzLXRlbmFudCBob3VzZWtlZXBpbmcgam9iLiBSZXR1cm5zIChhbmQgbG9ncykgcGVyLXdpbmRvdyBwdXJnZSB0YWxsaWVzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHVyZ2VFeHBpcmVkUmVwb3J0aW5nRGF0YShvcHRzOiBSZXBvcnRpbmdSZXRlbnRpb25PcHRpb25zID0ge30pOiBQcm9taXNlPFJlcG9ydGluZ1JldGVudGlvbkNvdW50cz4ge1xuICBjb25zdCBiYXRjaFNpemUgPSBNYXRoLm1heCgxLCBvcHRzLmJhdGNoU2l6ZSA/PyAxMDAwKTtcbiAgY29uc3QgbWF4QmF0Y2hlcyA9IE1hdGgubWF4KDEsIG9wdHMubWF4QmF0Y2hlc1BlclRhYmxlID8/IDUwKTtcbiAgY29uc3Qgbm93ID0gb3B0cy5ub3cgPz8gbmV3IERhdGUoKTtcbiAgY29uc3QgcmVzb2x2ZVJldGVudGlvbk9yZ0lkID0gb3B0cy5yZXNvbHZlUmV0ZW50aW9uT3JnSWQgPz8gKGFzeW5jIChvcmdJZDogc3RyaW5nKSA9PiBvcmdJZCk7XG4gIGNvbnN0IGNvdW50czogUmVwb3J0aW5nUmV0ZW50aW9uQ291bnRzID0ge1xuICAgIG9yZ3M6IDAsIHN0YW5kYXJkRXZlbnRzOiAwLCBkb3JhRXZlbnRzOiAwLCBkZXBsb3ltZW50T3V0Y29tZXM6IDAsIGluY2lkZW50czogMCxcbiAgfTtcblxuICByZXR1cm4gcnVuV2l0aFRlbmFudENvbnRleHQoeyBpc1N1cGVyQWRtaW46IHRydWUgfSwgYXN5bmMgKCkgPT4ge1xuICAgIC8vIEVudW1lcmF0ZSBldmVyeSBvcmcgd2l0aCByZXBvcnRpbmcgZGF0YSAodW5pb24gYWNyb3NzIHRoZSB0aHJlZSB0YWJsZXMpLlxuICAgIGNvbnN0IG9yZ1Jvd3MgPSBkcml6emxlUm93czx7IG9yZ19pZDogc3RyaW5nIH0+KChhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgIFNFTEVDVCBESVNUSU5DVCBvcmdfaWQgRlJPTSAoXG4gICAgICAgIFNFTEVDVCAke3NjaGVtYS5waXBlbGluZUV2ZW50Lm9yZ0lkfSBBUyBvcmdfaWQgRlJPTSAke3NjaGVtYS5waXBlbGluZUV2ZW50fVxuICAgICAgICBVTklPTlxuICAgICAgICBTRUxFQ1QgJHtzY2hlbWEuZGVwbG95bWVudE91dGNvbWUub3JnSWR9IEFTIG9yZ19pZCBGUk9NICR7c2NoZW1hLmRlcGxveW1lbnRPdXRjb21lfVxuICAgICAgICBVTklPTlxuICAgICAgICBTRUxFQ1QgJHtzY2hlbWEuaW5jaWRlbnQub3JnSWR9IEFTIG9yZ19pZCBGUk9NICR7c2NoZW1hLmluY2lkZW50fVxuICAgICAgKSBBUyBvcmdzXG4gICAgYCkpKS5yb3dzKTtcbiAgICBpZiAob3JnUm93cy5sZW5ndGggPT09IDApIHJldHVybiBjb3VudHM7XG5cbiAgICAvLyBQZXItb3JnIHJldGVudGlvbiBvdmVycmlkZXMgKGEgc2luZ2xlIHJlYWQ7IG9yZ3Mgd2l0aG91dCBhIHJvdyB1c2UgZGVmYXVsdHMpLlxuICAgIGNvbnN0IG92ZXJyaWRlUm93cyA9IGRyaXp6bGVSb3dzPHtcbiAgICAgIG9yZ19pZDogc3RyaW5nO1xuICAgICAgZXZlbnRfcmV0ZW50aW9uX2RheXM6IG51bWJlciB8IG51bGw7XG4gICAgICBkb3JhX3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgIH0+KChhd2FpdCB3aXRoVGVuYW50VHgoKHR4KSA9PiB0eC5leGVjdXRlKHNxbGBcbiAgICAgIFNFTEVDVCAke3NjaGVtYS5kb3JhU2V0dGluZ3Mub3JnSWR9IEFTIG9yZ19pZCxcbiAgICAgICAgICAgICAke3NjaGVtYS5kb3JhU2V0dGluZ3MuZXZlbnRSZXRlbnRpb25EYXlzfSBBUyBldmVudF9yZXRlbnRpb25fZGF5cyxcbiAgICAgICAgICAgICAke3NjaGVtYS5kb3JhU2V0dGluZ3MuZG9yYVJldGVudGlvbkRheXN9IEFTIGRvcmFfcmV0ZW50aW9uX2RheXNcbiAgICAgIEZST00gJHtzY2hlbWEuZG9yYVNldHRpbmdzfVxuICAgIGApKSkucm93cyk7XG4gICAgY29uc3Qgb3ZlcnJpZGVzID0gbmV3IE1hcChvdmVycmlkZVJvd3MubWFwKChyKSA9PiBbci5vcmdfaWQsIHJdKSk7XG5cbiAgICBjb25zdCBldmVudHNUYWJsZSA9IHNxbGAke3NjaGVtYS5waXBlbGluZUV2ZW50fWA7XG4gICAgY29uc3Qgb3V0Y29tZXNUYWJsZSA9IHNxbGAke3NjaGVtYS5kZXBsb3ltZW50T3V0Y29tZX1gO1xuICAgIGNvbnN0IGluY2lkZW50c1RhYmxlID0gc3FsYCR7c2NoZW1hLmluY2lkZW50fWA7XG5cbiAgICBmb3IgKGNvbnN0IHsgb3JnX2lkOiBvcmdJZCB9IG9mIG9yZ1Jvd3MpIHtcbiAgICAgIC8vIFJldGVudGlvbiBmb2xsb3dzIHRoZSBhY2NvdW50IFJPT1QncyBlbnRpdGxlbWVudCAoYmlsbGluZyBzeW5jcyBpdCBvbnRvXG4gICAgICAvLyB0aGUgcm9vdCBvbmx5KS4gQW4gdW5yZXNvbHZhYmxlIHJvb3Qg4oeSIHNraXAgdGhpcyBvcmcgdGhpcyB0aWNrIHJhdGhlclxuICAgICAgLy8gdGhhbiBwdXJnZSBhIHRlYW0ncyByb3dzIG9uIHRoZSAoc2hvcnRlcikgZW52IGRlZmF1bHQuXG4gICAgICBsZXQgcmV0ZW50aW9uT3JnSWQ6IHN0cmluZyB8IG51bGw7XG4gICAgICB0cnkge1xuICAgICAgICByZXRlbnRpb25PcmdJZCA9IGF3YWl0IHJlc29sdmVSZXRlbnRpb25PcmdJZChvcmdJZCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyByZXRlbnRpb246IHJvb3QgcmVzb2x1dGlvbiB0aHJldzsgc2tpcHBpbmcgb3JnIHRoaXMgdGljaycsIHsgb3JnSWQsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICAgICAgcmV0ZW50aW9uT3JnSWQgPSBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKHJldGVudGlvbk9yZ0lkID09PSBudWxsKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdSZXBvcnRpbmcgcmV0ZW50aW9uOiBjb3VsZCBub3QgcmVzb2x2ZSB0aGUgcmV0ZW50aW9uIHJvb3Q7IG9yZyBza2lwcGVkIHRoaXMgdGljaycsIHsgb3JnSWQgfSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3YgPSBvdmVycmlkZXMuZ2V0KHJldGVudGlvbk9yZ0lkKTtcbiAgICAgIGNvbnN0IGV2ZW50RGF5cyA9IHJlc29sdmVFdmVudFJldGVudGlvbkRheXMob3Y/LmV2ZW50X3JldGVudGlvbl9kYXlzKTtcbiAgICAgIGNvbnN0IGRvcmFEYXlzID0gcmVzb2x2ZURvcmFSZXRlbnRpb25EYXlzKG92Py5kb3JhX3JldGVudGlvbl9kYXlzKTtcbiAgICAgIC8vIGAtMWAgPSB1bmxpbWl0ZWQ6IGtlZXAgZm9yZXZlciwgc2tpcCB0aGF0IHdpbmRvdydzIGRlbGV0ZXMgZm9yXG4gICAgICAvLyB0aGlzIG9yZy4gU3RhbmRhcmQtZXZlbnQgYW5kIERPUkEtc291cmNlIHdpbmRvd3MgYXJlIGluZGVwZW5kZW50OyBhbiBvcmdcbiAgICAgIC8vIHdpdGggYm90aCBgLTFgIGlzIGZ1bGx5IHNraXBwZWQuIExvZyB0aGUgc2tpcCBzbyBpdCdzIG9ic2VydmFibGUuXG4gICAgICBjb25zdCBza2lwRXZlbnRzID0gZXZlbnREYXlzID09PSAtMTtcbiAgICAgIGNvbnN0IHNraXBEb3JhID0gZG9yYURheXMgPT09IC0xO1xuICAgICAgaWYgKHNraXBFdmVudHMgfHwgc2tpcERvcmEpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ1JlcG9ydGluZyByZXRlbnRpb24gc3dlZXAgc2tpcHBpbmcgdW5saW1pdGVkIHdpbmRvdyhzKScsIHtcbiAgICAgICAgICBvcmdJZCxcbiAgICAgICAgICBzdGFuZGFyZEV2ZW50czogc2tpcEV2ZW50cyA/ICd1bmxpbWl0ZWQnIDogZXZlbnREYXlzLFxuICAgICAgICAgIGRvcmFTb3VyY2U6IHNraXBEb3JhID8gJ3VubGltaXRlZCcgOiBkb3JhRGF5cyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghc2tpcEV2ZW50cykge1xuICAgICAgICBjb25zdCBldmVudEN1dG9mZiA9IHJldGVudGlvbkN1dG9mZihub3csIGV2ZW50RGF5cyk7XG4gICAgICAgIGNvdW50cy5zdGFuZGFyZEV2ZW50cyArPSBhd2FpdCBwdXJnZVJlcG9ydGluZ1RhYmxlQmF0Y2hlZChcbiAgICAgICAgICBldmVudHNUYWJsZSxcbiAgICAgICAgICAvLyBTcGFyZSByb3dzIGNhcnJ5aW5nIGEgY29tbWl0IHRpbWVzdGFtcDogdGhleSBhcmUgRE9SQSBTT1VSQ0UgZGF0YS5cbiAgICAgICAgICAvLyBMZWFkIHRpbWUgam9pbnMgZGVwbG95cyB0byB0aGUgZXhlY3V0aW9uJ3MgZWFybGllc3RcbiAgICAgICAgICAvLyBgY29tbWl0X3RpbWVzdGFtcGAsIGFuZCB0aGF0IGVucmljaG1lbnQgcmlkZXMgdGhlIFBJUEVMSU5FL3NvdXJjZVxuICAgICAgICAgIC8vIGV2ZW50IChlbnZpcm9ubWVudCBJUyBOVUxMKSwgbmV2ZXIgdGhlIGRlcGxveSBTVEFHRSByb3cuIFB1cmdpbmdcbiAgICAgICAgICAvLyB0aGVtIG9uIHRoaXMgc2hvcnQgd2luZG93IHdoaWxlIHRoZSBkZXBsb3lzIHRoZXkgZXhwbGFpbiBsaXZlIG9uXG4gICAgICAgICAgLy8gdGhlIERPUkEgd2luZG93IG1hZGUgbGVhZCB0aW1lIHJlYWQgXCJ1bmtub3duXCIgZm9yIGV2ZXJ5IHJhbmdlXG4gICAgICAgICAgLy8gb2xkZXIgdGhhbiB0aGUgc3RhbmRhcmQgcmV0ZW50aW9uIOKAlCBzaWxlbnRseSwgd2l0aCB0aGUgZGVwbG95c1xuICAgICAgICAgIC8vIHN0aWxsIGNvdW50ZWQuIFRoZXkgZm9sbG93IHRoZSBET1JBIHdpbmRvdyBiZWxvdyBpbnN0ZWFkLlxuICAgICAgICAgIHNxbGBvcmdfaWQgPSAke29yZ0lkfSBBTkQgZW52aXJvbm1lbnQgSVMgTlVMTCBBTkQgY29tbWl0X3RpbWVzdGFtcCBJUyBOVUxMIEFORCBjcmVhdGVkX2F0IDwgJHtldmVudEN1dG9mZn1gLFxuICAgICAgICAgIGJhdGNoU2l6ZSwgbWF4QmF0Y2hlcyxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFza2lwRG9yYSkge1xuICAgICAgICBjb25zdCBkb3JhQ3V0b2ZmID0gcmV0ZW50aW9uQ3V0b2ZmKG5vdywgZG9yYURheXMpO1xuICAgICAgICBjb3VudHMuZG9yYUV2ZW50cyArPSBhd2FpdCBwdXJnZVJlcG9ydGluZ1RhYmxlQmF0Y2hlZChcbiAgICAgICAgICBldmVudHNUYWJsZSxcbiAgICAgICAgICBzcWxgb3JnX2lkID0gJHtvcmdJZH0gQU5EIChlbnZpcm9ubWVudCBJUyBOT1QgTlVMTCBPUiBjb21taXRfdGltZXN0YW1wIElTIE5PVCBOVUxMKSBBTkQgY3JlYXRlZF9hdCA8ICR7ZG9yYUN1dG9mZn1gLFxuICAgICAgICAgIGJhdGNoU2l6ZSwgbWF4QmF0Y2hlcyxcbiAgICAgICAgKTtcbiAgICAgICAgY291bnRzLmRlcGxveW1lbnRPdXRjb21lcyArPSBhd2FpdCBwdXJnZVJlcG9ydGluZ1RhYmxlQmF0Y2hlZChcbiAgICAgICAgICBvdXRjb21lc1RhYmxlLFxuICAgICAgICAgIHNxbGBvcmdfaWQgPSAke29yZ0lkfSBBTkQgY3JlYXRlZF9hdCA8ICR7ZG9yYUN1dG9mZn1gLFxuICAgICAgICAgIGJhdGNoU2l6ZSwgbWF4QmF0Y2hlcyxcbiAgICAgICAgKTtcbiAgICAgICAgY291bnRzLmluY2lkZW50cyArPSBhd2FpdCBwdXJnZVJlcG9ydGluZ1RhYmxlQmF0Y2hlZChcbiAgICAgICAgICBpbmNpZGVudHNUYWJsZSxcbiAgICAgICAgICBzcWxgb3JnX2lkID0gJHtvcmdJZH0gQU5EIGNyZWF0ZWRfYXQgPCAke2RvcmFDdXRvZmZ9YCxcbiAgICAgICAgICBiYXRjaFNpemUsIG1heEJhdGNoZXMsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjb3VudHMub3JncyArPSAxO1xuICAgIH1cblxuICAgIGNvbnN0IHB1cmdlZEFueSA9IGNvdW50cy5zdGFuZGFyZEV2ZW50cyArIGNvdW50cy5kb3JhRXZlbnRzICsgY291bnRzLmRlcGxveW1lbnRPdXRjb21lcyArIGNvdW50cy5pbmNpZGVudHM7XG4gICAgaWYgKHB1cmdlZEFueSA+IDApIGxvZ2dlci5pbmZvKCdSZXBvcnRpbmcgcmV0ZW50aW9uIHN3ZWVwIHB1cmdlZCBleHBpcmVkIHJvd3MnLCB7IC4uLmNvdW50cyB9KTtcbiAgICByZXR1cm4gY291bnRzO1xuICB9KTtcbn1cbiJdfQ==
|
|
163
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV0ZW50aW9uLXN3ZWVwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9yZXBvcnRpbmcvcmV0ZW50aW9uLXN3ZWVwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7O0dBS0c7QUFFSCxPQUFPLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLHdCQUF3QixFQUFFLGVBQWUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRHLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMxRCxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDL0UsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRWpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0FBRW5EOzs7Ozs7Ozs7R0FTRztBQUNILEtBQUssVUFBVSwwQkFBMEIsQ0FDdkMsUUFBZ0MsRUFDaEMsU0FBaUMsRUFDakMsU0FBaUIsRUFDakIsVUFBa0I7SUFFbEIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sR0FBRyxHQUFHLE1BQU0sWUFBWSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQTtvQkFDckMsUUFBUTs7MkJBRUQsUUFBUTtnQkFDbkIsU0FBUztnQkFDVCxTQUFTOzs7S0FHcEIsQ0FBQyxDQUFDLENBQUM7UUFDSixNQUFNLE1BQU0s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TSxDQUFDLFVBQVUsSUFBSSxNQUFNLDBCQUEwQixDQUNuRCxXQUFXLEVBQ1gsR0FBRyxDQUFBLFlBQVksS0FBSyxtRkFBbUYsVUFBVSxFQUFFLEVBQ25ILFNBQVMsRUFBRSxVQUFVLENBQ3RCLENBQUM7Z0JBQ0YsTUFBTSxDQUFDLGtCQUFrQixJQUFJLE1BQU0sMEJBQTBCLENBQzNELGFBQWEsRUFDYixHQUFHLENBQUEsWUFBWSxLQUFLLHFCQUFxQixVQUFVLEVBQUUsRUFDckQsU0FBUyxFQUFFLFVBQVUsQ0FDdEIsQ0FBQztnQkFDRixNQUFNLENBQUMsU0FBUyxJQUFJLE1BQU0sMEJBQTBCLENBQ2xELGNBQWMsRUFDZCxHQUFHLENBQUEsWUFBWSxLQUFLLHFCQUFxQixVQUFVLEVBQUUsRUFDckQsU0FBUyxFQUFFLFVBQVUsQ0FDdEIsQ0FBQztZQUNKLENBQUM7WUFDRCxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQztRQUNuQixDQUFDO1FBRUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDO1FBQzNHLElBQUksU0FBUyxHQUFHLENBQUM7WUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLCtDQUErQyxFQUFFLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQy9GLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIFRoZSByZXBvcnRpbmcgcmV0ZW50aW9uIFNXRUVQOiB0aGUgYmF0Y2hlZCBoYXJkLWRlbGV0ZSB0aGF0IGVuZm9yY2VzIHRoZVxuICogd2luZG93cyBgLi9yZXRlbnRpb24udHNgIHJlc29sdmVzLiBTcGxpdCBmcm9tIHRoZSB3aW5kb3dzIG1vZHVsZSBzbyB0aGUgcHVyZSxcbiAqIGVudi1vbmx5IHBvbGljeSBzdGF5cyBmcmVlIG9mIGRhdGFiYXNlIGNvZGUsIGFuZCBmcm9tIHRoZSByZXBvcnRpbmcgc2VydmljZVxuICogYmVjYXVzZSB0aGlzIGlzIGNyb3NzLXRlbmFudCBob3VzZWtlZXBpbmcsIG5vdCBhIHJlcG9ydC5cbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIsIGVycm9yTWVzc2FnZSB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IHJlc29sdmVFdmVudFJldGVudGlvbkRheXMsIHJlc29sdmVEb3JhUmV0ZW50aW9uRGF5cywgcmV0ZW50aW9uQ3V0b2ZmIH0gZnJvbSAnLi9yZXRlbnRpb24uanMnO1xuaW1wb3J0IHR5cGUgeyBSZXBvcnRpbmdSZXRlbnRpb25Db3VudHMsIFJlcG9ydGluZ1JldGVudGlvbk9wdGlvbnMgfSBmcm9tICcuL3R5cGVzLmpzJztcbmltcG9ydCB7IHNjaGVtYSB9IGZyb20gJy4uLy4uL2RhdGFiYXNlL2RyaXp6bGUtc2NoZW1hLmpzJztcbmltcG9ydCB7IHdpdGhUZW5hbnRUeCwgcnVuV2l0aFRlbmFudENvbnRleHQgfSBmcm9tICcuLi8uLi9kYXRhYmFzZS90ZW5hbmN5LmpzJztcbmltcG9ydCB7IGRyaXp6bGVSb3dzIH0gZnJvbSAnLi4vY3J1ZC1zZXJ2aWNlLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdyZXBvcnRpbmctcmV0ZW50aW9uJyk7XG5cbi8qKlxuICogQmF0Y2hlZCBoYXJkLURFTEVURSBvZiBvbmUgcmVwb3J0aW5nIHRhYmxlJ3Mgcm93cyBleHBpcmVkIHBhc3QgYSBgY3JlYXRlZF9hdGBcbiAqIGN1dG9mZiwgc2NvcGVkIHRvIGFuIG9yZyBhbmQgYW4gb3B0aW9uYWwgcm93IHByZWRpY2F0ZS4gVXNlcyBhXG4gKiBgY3RpZGAtaW4tc3VicXVlcnkgTElNSVQgc28gZWFjaCBzdGF0ZW1lbnQgdG91Y2hlcyBhdCBtb3N0IGBiYXRjaFNpemVgIHJvd3NcbiAqIChzaG9ydCBsb2NrIHdpbmRvd3MsIG5vIGxvbmcgdGFibGUgc2NhbiB1bmRlciBsb2NrKTsgYFJFVFVSTklORyAxYCBsZXRzIHVzXG4gKiBjb3VudCB2aWEgYC5yb3dzLmxlbmd0aGAgd2l0aG91dCBkZXBlbmRpbmcgb24gdGhlIGRyaXZlcidzIGByb3dDb3VudGAuIExvb3BzXG4gKiB1bnRpbCBhIHNob3J0IGJhdGNoIChkcmFpbmVkKSBvciB0aGUgcGVyLXRpY2sgY2FwLCB0aGVuIGRlZmVycyB0aGUgcmVzdC5cbiAqIE1VU1QgcnVuIGluc2lkZSBhIHN5c2FkbWluIHRlbmFudCBzY29wZSAoc2VlIHB1cmdlRXhwaXJlZFJlcG9ydGluZ0RhdGEpIHNvIGl0XG4gKiBieXBhc3NlcyBSTFMgYW5kIGNhbiBkZWxldGUgYWNyb3NzIHRoZSBvcmcncyByb3dzLlxuICovXG5hc3luYyBmdW5jdGlvbiBwdXJnZVJlcG9ydGluZ1RhYmxlQmF0Y2hlZChcbiAgdGFibGVTcWw6IFJldHVyblR5cGU8dHlwZW9mIHNxbD4sXG4gIHByZWRpY2F0ZTogUmV0dXJuVHlwZTx0eXBlb2Ygc3FsPixcbiAgYmF0Y2hTaXplOiBudW1iZXIsXG4gIG1heEJhdGNoZXM6IG51bWJlcixcbik6IFByb21pc2U8bnVtYmVyPiB7XG4gIGxldCB0b3RhbCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbWF4QmF0Y2hlczsgaSsrKSB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICBERUxFVEUgRlJPTSAke3RhYmxlU3FsfVxuICAgICAgV0hFUkUgY3RpZCBJTiAoXG4gICAgICAgIFNFTEVDVCBjdGlkIEZST00gJHt0YWJsZVNxbH1cbiAgICAgICAgV0hFUkUgJHtwcmVkaWNhdGV9XG4gICAgICAgIExJTUlUICR7YmF0Y2hTaXplfVxuICAgICAgKVxuICAgICAgUkVUVVJOSU5HIDFcbiAgICBgKSk7XG4gICAgY29uc3QgcHVyZ2VkID0gZHJpenpsZVJvd3M8dW5rbm93bj4ocmVzLnJvd3MpLmxlbmd0aDtcbiAgICB0b3RhbCArPSBwdXJnZWQ7XG4gICAgaWYgKHB1cmdlZCA8IGJhdGNoU2l6ZSkgYnJlYWs7IC8vIGRyYWluZWRcbiAgICBpZiAoaSA9PT0gbWF4QmF0Y2hlcyAtIDEpIHtcbiAgICAgIGxvZ2dlci53YXJuKCdSZXBvcnRpbmcgcmV0ZW50aW9uIGhpdCBwZXItdGljayBjYXA7IHJlbWFpbmluZyByb3dzIGRlZmVycmVkJywge1xuICAgICAgICBwdXJnZWRUaGlzVGljazogdG90YWwsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRvdGFsO1xufVxuXG4vKipcbiAqIFJlcG9ydGluZyByZXRlbnRpb24gc3dlZXAuIEhhcmQtZGVsZXRlcyByb3dzIG9sZGVyIHRoYW4gdGhlaXJcbiAqIHJldGVudGlvbiB3aW5kb3csIGJ5IGBjcmVhdGVkX2F0YCwgYWNyb3NzIGV2ZXJ5IG9yZyB0aGF0IGhhcyByZXBvcnRpbmcgZGF0YSDigJRcbiAqIGEgKipzcGxpdCoqIHBvbGljeSBzbyBoaWdoLXZvbHVtZSBzdGFuZGFyZCBldmVudHMgZXhwaXJlIGZhc3RlciB0aGFuIHRoZVxuICogbG93LXZvbHVtZSBET1JBIHNvdXJjZTpcbiAqICAtIGBwaXBlbGluZV9ldmVudHMgV0hFUkUgZW52aXJvbm1lbnQgSVMgTlVMTGAg4oaSIHN0YW5kYXJkLWV2ZW50IHdpbmRvdy5cbiAqICAtIGBwaXBlbGluZV9ldmVudHMgV0hFUkUgZW52aXJvbm1lbnQgSVMgTk9UIE5VTExgIChkZXBsb3kgc3RhZ2VzKSxcbiAqICAgIGBkZXBsb3ltZW50X291dGNvbWVzYCwgYW5kIGBpbmNpZGVudHNgIOKGkiBET1JBLXNvdXJjZSB3aW5kb3cuXG4gKiBFYWNoIG9yZydzIHdpbmRvd3MgY29tZSBmcm9tIGl0cyBgZG9yYV9zZXR0aW5nc2Agb3ZlcnJpZGUsIGVsc2UgdGhlIGdsb2JhbFxuICogZW52IGRlZmF1bHRzIChzZWUge0BsaW5rIHJlc29sdmVFdmVudFJldGVudGlvbkRheXN9IC8ge0BsaW5rIHJlc29sdmVEb3JhUmV0ZW50aW9uRGF5c30pLlxuICogYGluZ2VzdF9oZWFsdGhgIGFuZCBgZG9yYV9zZXR0aW5nc2AgYXJlIG5ldmVyIHB1cmdlZC4gT25lIGBub3dgIGZvciB0aGUgd2hvbGVcbiAqIHRpY2sgKHJvd3MgY3Jvc3NpbmcgdGhlIGJvdW5kYXJ5IG1pZC1zd2VlcCB3YWl0IGZvciB0aGUgbmV4dCkuIEVzdGFibGlzaGVzIGFcbiAqIHN5c2FkbWluIHRlbmFudCBzY29wZSBzbyB0aGUgZGVsZXRlcyBzcGFuIGFsbCBvcmdzIC8gYnlwYXNzIFJMUyDigJQgdGhpcyBpcyBhXG4gKiBjcm9zcy10ZW5hbnQgaG91c2VrZWVwaW5nIGpvYi4gUmV0dXJucyAoYW5kIGxvZ3MpIHBlci13aW5kb3cgcHVyZ2UgdGFsbGllcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHB1cmdlRXhwaXJlZFJlcG9ydGluZ0RhdGEob3B0czogUmVwb3J0aW5nUmV0ZW50aW9uT3B0aW9ucyA9IHt9KTogUHJvbWlzZTxSZXBvcnRpbmdSZXRlbnRpb25Db3VudHM+IHtcbiAgY29uc3QgYmF0Y2hTaXplID0gTWF0aC5tYXgoMSwgb3B0cy5iYXRjaFNpemUgPz8gMTAwMCk7XG4gIGNvbnN0IG1heEJhdGNoZXMgPSBNYXRoLm1heCgxLCBvcHRzLm1heEJhdGNoZXNQZXJUYWJsZSA/PyA1MCk7XG4gIGNvbnN0IG5vdyA9IG9wdHMubm93ID8/IG5ldyBEYXRlKCk7XG4gIGNvbnN0IHJlc29sdmVSZXRlbnRpb25PcmdJZCA9IG9wdHMucmVzb2x2ZVJldGVudGlvbk9yZ0lkID8/IChhc3luYyAob3JnSWQ6IHN0cmluZykgPT4gb3JnSWQpO1xuICBjb25zdCBjb3VudHM6IFJlcG9ydGluZ1JldGVudGlvbkNvdW50cyA9IHtcbiAgICBvcmdzOiAwLCBzdGFuZGFyZEV2ZW50czogMCwgZG9yYUV2ZW50czogMCwgZGVwbG95bWVudE91dGNvbWVzOiAwLCBpbmNpZGVudHM6IDAsXG4gIH07XG5cbiAgcmV0dXJuIHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIGFzeW5jICgpID0+IHtcbiAgICAvLyBFbnVtZXJhdGUgZXZlcnkgb3JnIHdpdGggcmVwb3J0aW5nIGRhdGEgKHVuaW9uIGFjcm9zcyB0aGUgdGhyZWUgdGFibGVzKS5cbiAgICBjb25zdCBvcmdSb3dzID0gZHJpenpsZVJvd3M8eyBvcmdfaWQ6IHN0cmluZyB9PigoYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICBTRUxFQ1QgRElTVElOQ1Qgb3JnX2lkIEZST00gKFxuICAgICAgICBTRUxFQ1QgJHtzY2hlbWEucGlwZWxpbmVFdmVudC5vcmdJZH0gQVMgb3JnX2lkIEZST00gJHtzY2hlbWEucGlwZWxpbmVFdmVudH1cbiAgICAgICAgVU5JT05cbiAgICAgICAgU0VMRUNUICR7c2NoZW1hLmRlcGxveW1lbnRPdXRjb21lLm9yZ0lkfSBBUyBvcmdfaWQgRlJPTSAke3NjaGVtYS5kZXBsb3ltZW50T3V0Y29tZX1cbiAgICAgICAgVU5JT05cbiAgICAgICAgU0VMRUNUICR7c2NoZW1hLmluY2lkZW50Lm9yZ0lkfSBBUyBvcmdfaWQgRlJPTSAke3NjaGVtYS5pbmNpZGVudH1cbiAgICAgICkgQVMgb3Jnc1xuICAgIGApKSkucm93cyk7XG4gICAgaWYgKG9yZ1Jvd3MubGVuZ3RoID09PSAwKSByZXR1cm4gY291bnRzO1xuXG4gICAgLy8gUGVyLW9yZyByZXRlbnRpb24gb3ZlcnJpZGVzIChhIHNpbmdsZSByZWFkOyBvcmdzIHdpdGhvdXQgYSByb3cgdXNlIGRlZmF1bHRzKS5cbiAgICBjb25zdCBvdmVycmlkZVJvd3MgPSBkcml6emxlUm93czx7XG4gICAgICBvcmdfaWQ6IHN0cmluZztcbiAgICAgIGV2ZW50X3JldGVudGlvbl9kYXlzOiBudW1iZXIgfCBudWxsO1xuICAgICAgZG9yYV9yZXRlbnRpb25fZGF5czogbnVtYmVyIHwgbnVsbDtcbiAgICB9PigoYXdhaXQgd2l0aFRlbmFudFR4KCh0eCkgPT4gdHguZXhlY3V0ZShzcWxgXG4gICAgICBTRUxFQ1QgJHtzY2hlbWEuZG9yYVNldHRpbmdzLm9yZ0lkfSBBUyBvcmdfaWQsXG4gICAgICAgICAgICAgJHtzY2hlbWEuZG9yYVNldHRpbmdzLmV2ZW50UmV0ZW50aW9uRGF5c30gQVMgZXZlbnRfcmV0ZW50aW9uX2RheXMsXG4gICAgICAgICAgICAgJHtzY2hlbWEuZG9yYVNldHRpbmdzLmRvcmFSZXRlbnRpb25EYXlzfSBBUyBkb3JhX3JldGVudGlvbl9kYXlzXG4gICAgICBGUk9NICR7c2NoZW1hLmRvcmFTZXR0aW5nc31cbiAgICBgKSkpLnJvd3MpO1xuICAgIGNvbnN0IG92ZXJyaWRlcyA9IG5ldyBNYXAob3ZlcnJpZGVSb3dzLm1hcCgocikgPT4gW3Iub3JnX2lkLCByXSkpO1xuXG4gICAgY29uc3QgZXZlbnRzVGFibGUgPSBzcWxgJHtzY2hlbWEucGlwZWxpbmVFdmVudH1gO1xuICAgIGNvbnN0IG91dGNvbWVzVGFibGUgPSBzcWxgJHtzY2hlbWEuZGVwbG95bWVudE91dGNvbWV9YDtcbiAgICBjb25zdCBpbmNpZGVudHNUYWJsZSA9IHNxbGAke3NjaGVtYS5pbmNpZGVudH1gO1xuXG4gICAgZm9yIChjb25zdCB7IG9yZ19pZDogb3JnSWQgfSBvZiBvcmdSb3dzKSB7XG4gICAgICAvLyBMb2NrIGxvc3QsIG9yIHNodXR0aW5nIGRvd246IHN0b3AgYmV0d2VlbiBvcmdzLiBFdmVyeSByZW1haW5pbmcgb3JnIHN0aWxsXG4gICAgICAvLyBoYXMgZXhwaXJlZCByb3dzLCBzbyB0aGUgbmV4dCB0aWNrIHJlc3VtZXMgZXhhY3RseSB3aGVyZSB0aGlzIGxlZnQgb2ZmLlxuICAgICAgaWYgKG9wdHMucnVuPy5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgICBsb2dnZXIuaW5mbygnUmVwb3J0aW5nIHJldGVudGlvbiBzd2VlcCBzdG9wcGluZyBlYXJseScsIHtcbiAgICAgICAgICByZWFzb246IFN0cmluZyhvcHRzLnJ1bi5zaWduYWwucmVhc29uID8/ICdhYm9ydGVkJyksIG9yZ3NEb25lOiBjb3VudHMub3JncyxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgLy8gUmV0ZW50aW9uIGZvbGxvd3MgdGhlIGFjY291bnQgUk9PVCdzIGVudGl0bGVtZW50IChiaWxsaW5nIHN5bmNzIGl0IG9udG9cbiAgICAgIC8vIHRoZSByb290IG9ubHkpLiBBbiB1bnJlc29sdmFibGUgcm9vdCDih5Igc2tpcCB0aGlzIG9yZyB0aGlzIHRpY2sgcmF0aGVyXG4gICAgICAvLyB0aGFuIHB1cmdlIGEgdGVhbSdzIHJvd3Mgb24gdGhlIChzaG9ydGVyKSBlbnYgZGVmYXVsdC5cbiAgICAgIGxldCByZXRlbnRpb25PcmdJZDogc3RyaW5nIHwgbnVsbDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldGVudGlvbk9yZ0lkID0gYXdhaXQgcmVzb2x2ZVJldGVudGlvbk9yZ0lkKG9yZ0lkKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIud2FybignUmVwb3J0aW5nIHJldGVudGlvbjogcm9vdCByZXNvbHV0aW9uIHRocmV3OyBza2lwcGluZyBvcmcgdGhpcyB0aWNrJywgeyBvcmdJZCwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgICAgICByZXRlbnRpb25PcmdJZCA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAocmV0ZW50aW9uT3JnSWQgPT09IG51bGwpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1JlcG9ydGluZyByZXRlbnRpb246IGNvdWxkIG5vdCByZXNvbHZlIHRoZSByZXRlbnRpb24gcm9vdDsgb3JnIHNraXBwZWQgdGhpcyB0aWNrJywgeyBvcmdJZCB9KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBvdiA9IG92ZXJyaWRlcy5nZXQocmV0ZW50aW9uT3JnSWQpO1xuICAgICAgY29uc3QgZXZlbnREYXlzID0gcmVzb2x2ZUV2ZW50UmV0ZW50aW9uRGF5cyhvdj8uZXZlbnRfcmV0ZW50aW9uX2RheXMpO1xuICAgICAgY29uc3QgZG9yYURheXMgPSByZXNvbHZlRG9yYVJldGVudGlvbkRheXMob3Y/LmRvcmFfcmV0ZW50aW9uX2RheXMpO1xuICAgICAgLy8gYC0xYCA9IHVubGltaXRlZDoga2VlcCBmb3JldmVyLCBza2lwIHRoYXQgd2luZG93J3MgZGVsZXRlcyBmb3JcbiAgICAgIC8vIHRoaXMgb3JnLiBTdGFuZGFyZC1ldmVudCBhbmQgRE9SQS1zb3VyY2Ugd2luZG93cyBhcmUgaW5kZXBlbmRlbnQ7IGFuIG9yZ1xuICAgICAgLy8gd2l0aCBib3RoIGAtMWAgaXMgZnVsbHkgc2tpcHBlZC4gTG9nIHRoZSBza2lwIHNvIGl0J3Mgb2JzZXJ2YWJsZS5cbiAgICAgIGNvbnN0IHNraXBFdmVudHMgPSBldmVudERheXMgPT09IC0xO1xuICAgICAgY29uc3Qgc2tpcERvcmEgPSBkb3JhRGF5cyA9PT0gLTE7XG4gICAgICBpZiAoc2tpcEV2ZW50cyB8fCBza2lwRG9yYSkge1xuICAgICAgICBsb2dnZXIuaW5mbygnUmVwb3J0aW5nIHJldGVudGlvbiBzd2VlcCBza2lwcGluZyB1bmxpbWl0ZWQgd2luZG93KHMpJywge1xuICAgICAgICAgIG9yZ0lkLFxuICAgICAgICAgIHN0YW5kYXJkRXZlbnRzOiBza2lwRXZlbnRzID8gJ3VubGltaXRlZCcgOiBldmVudERheXMsXG4gICAgICAgICAgZG9yYVNvdXJjZTogc2tpcERvcmEgPyAndW5saW1pdGVkJyA6IGRvcmFEYXlzLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFza2lwRXZlbnRzKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50Q3V0b2ZmID0gcmV0ZW50aW9uQ3V0b2ZmKG5vdywgZXZlbnREYXlzKTtcbiAgICAgICAgY291bnRzLnN0YW5kYXJkRXZlbnRzICs9IGF3YWl0IHB1cmdlUmVwb3J0aW5nVGFibGVCYXRjaGVkKFxuICAgICAgICAgIGV2ZW50c1RhYmxlLFxuICAgICAgICAgIC8vIFNwYXJlIHJvd3MgY2FycnlpbmcgYSBjb21taXQgdGltZXN0YW1wOiB0aGV5IGFyZSBET1JBIFNPVVJDRSBkYXRhLlxuICAgICAgICAgIC8vIExlYWQgdGltZSBqb2lucyBkZXBsb3lzIHRvIHRoZSBleGVjdXRpb24ncyBlYXJsaWVzdFxuICAgICAgICAgIC8vIGBjb21taXRfdGltZXN0YW1wYCwgYW5kIHRoYXQgZW5yaWNobWVudCByaWRlcyB0aGUgUElQRUxJTkUvc291cmNlXG4gICAgICAgICAgLy8gZXZlbnQgKGVudmlyb25tZW50IElTIE5VTEwpLCBuZXZlciB0aGUgZGVwbG95IFNUQUdFIHJvdy4gUHVyZ2luZ1xuICAgICAgICAgIC8vIHRoZW0gb24gdGhpcyBzaG9ydCB3aW5kb3cgd2hpbGUgdGhlIGRlcGxveXMgdGhleSBleHBsYWluIGxpdmUgb25cbiAgICAgICAgICAvLyB0aGUgRE9SQSB3aW5kb3cgbWFkZSBsZWFkIHRpbWUgcmVhZCBcInVua25vd25cIiBmb3IgZXZlcnkgcmFuZ2VcbiAgICAgICAgICAvLyBvbGRlciB0aGFuIHRoZSBzdGFuZGFyZCByZXRlbnRpb24g4oCUIHNpbGVudGx5LCB3aXRoIHRoZSBkZXBsb3lzXG4gICAgICAgICAgLy8gc3RpbGwgY291bnRlZC4gVGhleSBmb2xsb3cgdGhlIERPUkEgd2luZG93IGJlbG93IGluc3RlYWQuXG4gICAgICAgICAgc3FsYG9yZ19pZCA9ICR7b3JnSWR9IEFORCBlbnZpcm9ubWVudCBJUyBOVUxMIEFORCBjb21taXRfdGltZXN0YW1wIElTIE5VTEwgQU5EIGNyZWF0ZWRfYXQgPCAke2V2ZW50Q3V0b2ZmfWAsXG4gICAgICAgICAgYmF0Y2hTaXplLCBtYXhCYXRjaGVzLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXNraXBEb3JhKSB7XG4gICAgICAgIGNvbnN0IGRvcmFDdXRvZmYgPSByZXRlbnRpb25DdXRvZmYobm93LCBkb3JhRGF5cyk7XG4gICAgICAgIGNvdW50cy5kb3JhRXZlbnRzICs9IGF3YWl0IHB1cmdlUmVwb3J0aW5nVGFibGVCYXRjaGVkKFxuICAgICAgICAgIGV2ZW50c1RhYmxlLFxuICAgICAgICAgIHNxbGBvcmdfaWQgPSAke29yZ0lkfSBBTkQgKGVudmlyb25tZW50IElTIE5PVCBOVUxMIE9SIGNvbW1pdF90aW1lc3RhbXAgSVMgTk9UIE5VTEwpIEFORCBjcmVhdGVkX2F0IDwgJHtkb3JhQ3V0b2ZmfWAsXG4gICAgICAgICAgYmF0Y2hTaXplLCBtYXhCYXRjaGVzLFxuICAgICAgICApO1xuICAgICAgICBjb3VudHMuZGVwbG95bWVudE91dGNvbWVzICs9IGF3YWl0IHB1cmdlUmVwb3J0aW5nVGFibGVCYXRjaGVkKFxuICAgICAgICAgIG91dGNvbWVzVGFibGUsXG4gICAgICAgICAgc3FsYG9yZ19pZCA9ICR7b3JnSWR9IEFORCBjcmVhdGVkX2F0IDwgJHtkb3JhQ3V0b2ZmfWAsXG4gICAgICAgICAgYmF0Y2hTaXplLCBtYXhCYXRjaGVzLFxuICAgICAgICApO1xuICAgICAgICBjb3VudHMuaW5jaWRlbnRzICs9IGF3YWl0IHB1cmdlUmVwb3J0aW5nVGFibGVCYXRjaGVkKFxuICAgICAgICAgIGluY2lkZW50c1RhYmxlLFxuICAgICAgICAgIHNxbGBvcmdfaWQgPSAke29yZ0lkfSBBTkQgY3JlYXRlZF9hdCA8ICR7ZG9yYUN1dG9mZn1gLFxuICAgICAgICAgIGJhdGNoU2l6ZSwgbWF4QmF0Y2hlcyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvdW50cy5vcmdzICs9IDE7XG4gICAgfVxuXG4gICAgY29uc3QgcHVyZ2VkQW55ID0gY291bnRzLnN0YW5kYXJkRXZlbnRzICsgY291bnRzLmRvcmFFdmVudHMgKyBjb3VudHMuZGVwbG95bWVudE91dGNvbWVzICsgY291bnRzLmluY2lkZW50cztcbiAgICBpZiAocHVyZ2VkQW55ID4gMCkgbG9nZ2VyLmluZm8oJ1JlcG9ydGluZyByZXRlbnRpb24gc3dlZXAgcHVyZ2VkIGV4cGlyZWQgcm93cycsIHsgLi4uY291bnRzIH0pO1xuICAgIHJldHVybiBjb3VudHM7XG4gIH0pO1xufVxuIl19
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Small SQL fragments and input guards shared across the reporting queries.
|
|
3
|
+
*/
|
|
4
|
+
import { type WeekStart } from '@pipeline-builder/api-core';
|
|
5
|
+
import { sql, type SQL } from 'drizzle-orm';
|
|
2
6
|
/**
|
|
3
7
|
* Defense-in-depth guard for the `DATE_TRUNC(${interval}, …)` bucket argument.
|
|
4
8
|
* The route layer (`parseReportInterval`) is the security boundary and already
|
|
@@ -8,6 +12,35 @@ import { sql } from 'drizzle-orm';
|
|
|
8
12
|
* REPORT_INTERVALS allow-list so the two can't drift.
|
|
9
13
|
*/
|
|
10
14
|
export declare function assertReportInterval(interval: string): void;
|
|
15
|
+
/**
|
|
16
|
+
* The time-bucket expression for a report series: `DATE_TRUNC` in the REPORT'S
|
|
17
|
+
* timezone, honouring the org's week start.
|
|
18
|
+
*
|
|
19
|
+
* Two things this fixes, both of which made a manager's report cover the wrong
|
|
20
|
+
* days:
|
|
21
|
+
*
|
|
22
|
+
* - Bucketing ran in the database session's timezone, which is UTC in every
|
|
23
|
+
* deploy. A Chicago team's "week" therefore began 18:00 Sunday local, so their
|
|
24
|
+
* Monday report cut off Sunday evening's work and attributed it to the previous
|
|
25
|
+
* week. `AT TIME ZONE` converts to local wall time BEFORE truncating.
|
|
26
|
+
* - Postgres `DATE_TRUNC('week', …)` is ISO-8601 and always starts Monday, with
|
|
27
|
+
* no setting. A Sunday-week org gets the boundary shifted a day either side of
|
|
28
|
+
* the truncation, which is the only way to move it.
|
|
29
|
+
*
|
|
30
|
+
* `interval` is asserted against the allow-list by {@link assertReportInterval};
|
|
31
|
+
* `tz` rides as a BOUND parameter, never interpolated.
|
|
32
|
+
*
|
|
33
|
+
* Returns a `timestamp without time zone` in local wall time — which is what a
|
|
34
|
+
* period label ("2026-W38", "2026-08") should read as.
|
|
35
|
+
*/
|
|
36
|
+
export declare function periodBucket(interval: string, column: SQL, tz: string, weekStart?: WeekStart): SQL;
|
|
37
|
+
/**
|
|
38
|
+
* Cache-key suffix for the bucketing settings. Report cache keys carried the
|
|
39
|
+
* interval and the date range but NOT the timezone or week start, so once
|
|
40
|
+
* bucketing became timezone-aware one org's Chicago buckets would have been
|
|
41
|
+
* served to a request asking for UTC. Every keyed report must include this.
|
|
42
|
+
*/
|
|
43
|
+
export declare function bucketKey(tz: string, weekStart?: WeekStart): string;
|
|
11
44
|
/**
|
|
12
45
|
* Scrub AWS identifiers from an optional free-form string, preserving `undefined`
|
|
13
46
|
* (so an absent field stays absent rather than becoming an empty scrubbed string).
|
|
@@ -22,7 +55,7 @@ export declare function scrubOptional(value: string | undefined): string | undef
|
|
|
22
55
|
* trend, and build health — so the precedence can't drift between them. Assumes the
|
|
23
56
|
* grouped event alias is `e`.
|
|
24
57
|
*/
|
|
25
|
-
export declare const terminalStatusRollup:
|
|
58
|
+
export declare const terminalStatusRollup: SQL<unknown>;
|
|
26
59
|
/** The report window on `e.started_at` (inclusive `[from, to]`). */
|
|
27
60
|
export declare function startedAtWindow(from: string, to: string): ReturnType<typeof sql>;
|
|
28
61
|
/** Optional `[from,to]` window on `e.started_at` for the execution reports —
|
|
@@ -18,6 +18,44 @@ export function assertReportInterval(interval) {
|
|
|
18
18
|
throw new Error(`Invalid report interval: ${interval}. Expected one of: ${REPORT_INTERVALS.join(', ')}`);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* The time-bucket expression for a report series: `DATE_TRUNC` in the REPORT'S
|
|
23
|
+
* timezone, honouring the org's week start.
|
|
24
|
+
*
|
|
25
|
+
* Two things this fixes, both of which made a manager's report cover the wrong
|
|
26
|
+
* days:
|
|
27
|
+
*
|
|
28
|
+
* - Bucketing ran in the database session's timezone, which is UTC in every
|
|
29
|
+
* deploy. A Chicago team's "week" therefore began 18:00 Sunday local, so their
|
|
30
|
+
* Monday report cut off Sunday evening's work and attributed it to the previous
|
|
31
|
+
* week. `AT TIME ZONE` converts to local wall time BEFORE truncating.
|
|
32
|
+
* - Postgres `DATE_TRUNC('week', …)` is ISO-8601 and always starts Monday, with
|
|
33
|
+
* no setting. A Sunday-week org gets the boundary shifted a day either side of
|
|
34
|
+
* the truncation, which is the only way to move it.
|
|
35
|
+
*
|
|
36
|
+
* `interval` is asserted against the allow-list by {@link assertReportInterval};
|
|
37
|
+
* `tz` rides as a BOUND parameter, never interpolated.
|
|
38
|
+
*
|
|
39
|
+
* Returns a `timestamp without time zone` in local wall time — which is what a
|
|
40
|
+
* period label ("2026-W38", "2026-08") should read as.
|
|
41
|
+
*/
|
|
42
|
+
export function periodBucket(interval, column, tz, weekStart = 'monday') {
|
|
43
|
+
assertReportInterval(interval);
|
|
44
|
+
const local = sql `(${column} AT TIME ZONE ${tz})`;
|
|
45
|
+
if (interval === 'week' && weekStart === 'sunday') {
|
|
46
|
+
return sql `(DATE_TRUNC('week', ${local} + INTERVAL '1 day') - INTERVAL '1 day')`;
|
|
47
|
+
}
|
|
48
|
+
return sql `DATE_TRUNC(${interval}, ${local})`;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Cache-key suffix for the bucketing settings. Report cache keys carried the
|
|
52
|
+
* interval and the date range but NOT the timezone or week start, so once
|
|
53
|
+
* bucketing became timezone-aware one org's Chicago buckets would have been
|
|
54
|
+
* served to a request asking for UTC. Every keyed report must include this.
|
|
55
|
+
*/
|
|
56
|
+
export function bucketKey(tz, weekStart = 'monday') {
|
|
57
|
+
return `${tz}:${weekStart}`;
|
|
58
|
+
}
|
|
21
59
|
/**
|
|
22
60
|
* Scrub AWS identifiers from an optional free-form string, preserving `undefined`
|
|
23
61
|
* (so an absent field stays absent rather than becoming an empty scrubbed string).
|
|
@@ -61,4 +99,4 @@ export function optionalStartedAtRange(range) {
|
|
|
61
99
|
* `in_window` is false for a look-back-only row kept solely so incidents opened
|
|
62
100
|
* near `from` can correlate to a deploy that completed just before the window.
|
|
63
101
|
*/
|
|
64
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
102
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3FsLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBpL3JlcG9ydGluZy9zcWwtaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDOztHQUVHO0FBRUgsT0FBTyxFQUFFLGdCQUFnQixFQUFFLDZCQUE2QixFQUFrQixNQUFNLDRCQUE0QixDQUFDO0FBQzdHLE9BQU8sRUFBRSxHQUFHLEVBQVksTUFBTSxhQUFhLENBQUM7QUFFNUM7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxRQUFnQjtJQUNuRCxJQUFJLENBQUUsZ0JBQXNDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDaEUsTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsUUFBUSxzQkFBc0IsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMzRyxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsUUFBZ0IsRUFBRSxNQUFXLEVBQUUsRUFBVSxFQUFFLFNBQVMsR0FBYyxRQUFRO0lBQ3JHLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQy9CLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQSxJQUFJLE1BQU0saUJBQWlCLEVBQUUsR0FBRyxDQUFDO0lBQ2xELElBQUksUUFBUSxLQUFLLE1BQU0sSUFBSSxTQUFTLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDbEQsT0FBTyxHQUFHLENBQUEsdUJBQXVCLEtBQUssMENBQTBDLENBQUM7SUFDbkYsQ0FBQztJQUNELE9BQU8sR0FBRyxDQUFBLGNBQWMsUUFBUSxLQUFLLEtBQUssR0FBRyxDQUFDO0FBQ2hELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsRUFBVSxFQUFFLFNBQVMsR0FBYyxRQUFRO0lBQ25FLE9BQU8sR0FBRyxFQUFFLElBQUksU0FBUyxFQUFFLENBQUM7QUFDOUIsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxLQUF5QjtJQUNyRCxPQUFPLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLDZCQUE2QixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDaEYsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEdBQUcsQ0FBQTs7OztnQkFJdkIsQ0FBQztBQUVqQixvRUFBb0U7QUFDcEUsTUFBTSxVQUFVLGVBQWUsQ0FBQyxJQUFZLEVBQUUsRUFBVTtJQUN0RCxPQUFPLEdBQUcsQ0FBQSxtQkFBbUIsSUFBSSxxQ0FBcUMsRUFBRSxlQUFlLENBQUM7QUFDMUYsQ0FBQztBQUVEOztxRkFFcUY7QUFDckYsTUFBTSxVQUFVLHNCQUFzQixDQUFDLEtBQXNDO0lBQzNFLE9BQU8sS0FBSyxFQUFFLElBQUksSUFBSSxLQUFLLEVBQUUsRUFBRTtRQUM3QixDQUFDLENBQUMsR0FBRyxDQUFBLE9BQU8sZUFBZSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1FBQ25ELENBQUMsQ0FBQyxHQUFHLENBQUEsRUFBRSxDQUFDO0FBQ1osQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIFNtYWxsIFNRTCBmcmFnbWVudHMgYW5kIGlucHV0IGd1YXJkcyBzaGFyZWQgYWNyb3NzIHRoZSByZXBvcnRpbmcgcXVlcmllcy5cbiAqL1xuXG5pbXBvcnQgeyBSRVBPUlRfSU5URVJWQUxTLCBzY3J1YkF3c0lkZW50aWZpZXJzRnJvbVN0cmluZywgdHlwZSBXZWVrU3RhcnQgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBzcWwsIHR5cGUgU1FMIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuXG4vKipcbiAqIERlZmVuc2UtaW4tZGVwdGggZ3VhcmQgZm9yIHRoZSBgREFURV9UUlVOQygke2ludGVydmFsfSwg4oCmKWAgYnVja2V0IGFyZ3VtZW50LlxuICogVGhlIHJvdXRlIGxheWVyIChgcGFyc2VSZXBvcnRJbnRlcnZhbGApIGlzIHRoZSBzZWN1cml0eSBib3VuZGFyeSBhbmQgYWxyZWFkeVxuICogcmVqZWN0cyB1bmtub3duIGludGVydmFsczsgdGhpcyBhc3NlcnQgbWFrZXMgYW4gaW52YWxpZCB2YWx1ZSBmYWlsIGZhc3QgYXQgdGhlXG4gKiBzZXJ2aWNlIGJvdW5kYXJ5IHdpdGggYSBjbGVhciBlcnJvciBpbnN0ZWFkIG9mIHN1cmZhY2luZyBhIHJhdyBQb3N0Z3JlcyBlcnJvclxuICogaWYgYSBjYWxsZXIgZXZlciBieXBhc3NlcyB0aGUgcm91dGUgdmFsaWRhdGlvbi4gU2hhcmVzIGFwaS1jb3JlJ3NcbiAqIFJFUE9SVF9JTlRFUlZBTFMgYWxsb3ctbGlzdCBzbyB0aGUgdHdvIGNhbid0IGRyaWZ0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UmVwb3J0SW50ZXJ2YWwoaW50ZXJ2YWw6IHN0cmluZyk6IHZvaWQge1xuICBpZiAoIShSRVBPUlRfSU5URVJWQUxTIGFzIHJlYWRvbmx5IHN0cmluZ1tdKS5pbmNsdWRlcyhpbnRlcnZhbCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcmVwb3J0IGludGVydmFsOiAke2ludGVydmFsfS4gRXhwZWN0ZWQgb25lIG9mOiAke1JFUE9SVF9JTlRFUlZBTFMuam9pbignLCAnKX1gKTtcbiAgfVxufVxuXG4vKipcbiAqIFRoZSB0aW1lLWJ1Y2tldCBleHByZXNzaW9uIGZvciBhIHJlcG9ydCBzZXJpZXM6IGBEQVRFX1RSVU5DYCBpbiB0aGUgUkVQT1JUJ1NcbiAqIHRpbWV6b25lLCBob25vdXJpbmcgdGhlIG9yZydzIHdlZWsgc3RhcnQuXG4gKlxuICogVHdvIHRoaW5ncyB0aGlzIGZpeGVzLCBib3RoIG9mIHdoaWNoIG1hZGUgYSBtYW5hZ2VyJ3MgcmVwb3J0IGNvdmVyIHRoZSB3cm9uZ1xuICogZGF5czpcbiAqXG4gKiAgLSBCdWNrZXRpbmcgcmFuIGluIHRoZSBkYXRhYmFzZSBzZXNzaW9uJ3MgdGltZXpvbmUsIHdoaWNoIGlzIFVUQyBpbiBldmVyeVxuICogICAgZGVwbG95LiBBIENoaWNhZ28gdGVhbSdzIFwid2Vla1wiIHRoZXJlZm9yZSBiZWdhbiAxODowMCBTdW5kYXkgbG9jYWwsIHNvIHRoZWlyXG4gKiAgICBNb25kYXkgcmVwb3J0IGN1dCBvZmYgU3VuZGF5IGV2ZW5pbmcncyB3b3JrIGFuZCBhdHRyaWJ1dGVkIGl0IHRvIHRoZSBwcmV2aW91c1xuICogICAgd2Vlay4gYEFUIFRJTUUgWk9ORWAgY29udmVydHMgdG8gbG9jYWwgd2FsbCB0aW1lIEJFRk9SRSB0cnVuY2F0aW5nLlxuICogIC0gUG9zdGdyZXMgYERBVEVfVFJVTkMoJ3dlZWsnLCDigKYpYCBpcyBJU08tODYwMSBhbmQgYWx3YXlzIHN0YXJ0cyBNb25kYXksIHdpdGhcbiAqICAgIG5vIHNldHRpbmcuIEEgU3VuZGF5LXdlZWsgb3JnIGdldHMgdGhlIGJvdW5kYXJ5IHNoaWZ0ZWQgYSBkYXkgZWl0aGVyIHNpZGUgb2ZcbiAqICAgIHRoZSB0cnVuY2F0aW9uLCB3aGljaCBpcyB0aGUgb25seSB3YXkgdG8gbW92ZSBpdC5cbiAqXG4gKiBgaW50ZXJ2YWxgIGlzIGFzc2VydGVkIGFnYWluc3QgdGhlIGFsbG93LWxpc3QgYnkge0BsaW5rIGFzc2VydFJlcG9ydEludGVydmFsfTtcbiAqIGB0emAgcmlkZXMgYXMgYSBCT1VORCBwYXJhbWV0ZXIsIG5ldmVyIGludGVycG9sYXRlZC5cbiAqXG4gKiBSZXR1cm5zIGEgYHRpbWVzdGFtcCB3aXRob3V0IHRpbWUgem9uZWAgaW4gbG9jYWwgd2FsbCB0aW1lIOKAlCB3aGljaCBpcyB3aGF0IGFcbiAqIHBlcmlvZCBsYWJlbCAoXCIyMDI2LVczOFwiLCBcIjIwMjYtMDhcIikgc2hvdWxkIHJlYWQgYXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwZXJpb2RCdWNrZXQoaW50ZXJ2YWw6IHN0cmluZywgY29sdW1uOiBTUUwsIHR6OiBzdHJpbmcsIHdlZWtTdGFydDogV2Vla1N0YXJ0ID0gJ21vbmRheScpOiBTUUwge1xuICBhc3NlcnRSZXBvcnRJbnRlcnZhbChpbnRlcnZhbCk7XG4gIGNvbnN0IGxvY2FsID0gc3FsYCgke2NvbHVtbn0gQVQgVElNRSBaT05FICR7dHp9KWA7XG4gIGlmIChpbnRlcnZhbCA9PT0gJ3dlZWsnICYmIHdlZWtTdGFydCA9PT0gJ3N1bmRheScpIHtcbiAgICByZXR1cm4gc3FsYChEQVRFX1RSVU5DKCd3ZWVrJywgJHtsb2NhbH0gKyBJTlRFUlZBTCAnMSBkYXknKSAtIElOVEVSVkFMICcxIGRheScpYDtcbiAgfVxuICByZXR1cm4gc3FsYERBVEVfVFJVTkMoJHtpbnRlcnZhbH0sICR7bG9jYWx9KWA7XG59XG5cbi8qKlxuICogQ2FjaGUta2V5IHN1ZmZpeCBmb3IgdGhlIGJ1Y2tldGluZyBzZXR0aW5ncy4gUmVwb3J0IGNhY2hlIGtleXMgY2FycmllZCB0aGVcbiAqIGludGVydmFsIGFuZCB0aGUgZGF0ZSByYW5nZSBidXQgTk9UIHRoZSB0aW1lem9uZSBvciB3ZWVrIHN0YXJ0LCBzbyBvbmNlXG4gKiBidWNrZXRpbmcgYmVjYW1lIHRpbWV6b25lLWF3YXJlIG9uZSBvcmcncyBDaGljYWdvIGJ1Y2tldHMgd291bGQgaGF2ZSBiZWVuXG4gKiBzZXJ2ZWQgdG8gYSByZXF1ZXN0IGFza2luZyBmb3IgVVRDLiBFdmVyeSBrZXllZCByZXBvcnQgbXVzdCBpbmNsdWRlIHRoaXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWNrZXRLZXkodHo6IHN0cmluZywgd2Vla1N0YXJ0OiBXZWVrU3RhcnQgPSAnbW9uZGF5Jyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHt0en06JHt3ZWVrU3RhcnR9YDtcbn1cblxuLyoqXG4gKiBTY3J1YiBBV1MgaWRlbnRpZmllcnMgZnJvbSBhbiBvcHRpb25hbCBmcmVlLWZvcm0gc3RyaW5nLCBwcmVzZXJ2aW5nIGB1bmRlZmluZWRgXG4gKiAoc28gYW4gYWJzZW50IGZpZWxkIHN0YXlzIGFic2VudCByYXRoZXIgdGhhbiBiZWNvbWluZyBhbiBlbXB0eSBzY3J1YmJlZCBzdHJpbmcpLlxuICogVGhlIERVUkFCTEUgcGVyc2lzdGVuY2UgYm91bmRhcnkgZm9yIHRoZSBpbmdlc3QgcGF0aHMg4oCUIGV2ZXJ5IHVzZXIvQVdTLWRlcml2ZWRcbiAqIHN0cmluZyBmaWVsZCBpcyBmdW5uZWxlZCB0aHJvdWdoIHRoaXMgYmVmb3JlIGluc2VydC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjcnViT3B0aW9uYWwodmFsdWU6IHN0cmluZyB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmcodmFsdWUpIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJvbGwgYSBncm91cCBvZiBkZXBsb3kvc3RhZ2UgZXZlbnRzIChncm91cGVkIHBlciBleGVjdXRpb24pIHVwIHRvIG9uZSB0ZXJtaW5hbFxuICogc3RhdHVzOiBGQUlMRUQgd2lucywgdGhlbiBTVUNDRUVERUQsIGVsc2UgT1RIRVIgKHN0aWxsLXJ1bm5pbmcgLyBub24tdGVybWluYWwpLlxuICogU2hhcmVkIGJ5IHRoZSB0aHJlZSBwZXItKGVudnxzdGFnZSwgZXhlY3V0aW9uKSByb2xsdXAgQ1RFcyDigJQgRE9SQSBtZXRyaWNzLCBET1JBXG4gKiB0cmVuZCwgYW5kIGJ1aWxkIGhlYWx0aCDigJQgc28gdGhlIHByZWNlZGVuY2UgY2FuJ3QgZHJpZnQgYmV0d2VlbiB0aGVtLiBBc3N1bWVzIHRoZVxuICogZ3JvdXBlZCBldmVudCBhbGlhcyBpcyBgZWAuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZXJtaW5hbFN0YXR1c1JvbGx1cCA9IHNxbGBDQVNFXG4gICAgICAgICAgICAgIFdIRU4gYm9vbF9vcihlLnN0YXR1cyA9ICdGQUlMRUQnKSBUSEVOICdGQUlMRUQnXG4gICAgICAgICAgICAgIFdIRU4gYm9vbF9vcihlLnN0YXR1cyA9ICdTVUNDRUVERUQnKSBUSEVOICdTVUNDRUVERUQnXG4gICAgICAgICAgICAgIEVMU0UgJ09USEVSJ1xuICAgICAgICAgICAgRU5EYDtcblxuLyoqIFRoZSByZXBvcnQgd2luZG93IG9uIGBlLnN0YXJ0ZWRfYXRgIChpbmNsdXNpdmUgYFtmcm9tLCB0b11gKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFydGVkQXRXaW5kb3coZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nKTogUmV0dXJuVHlwZTx0eXBlb2Ygc3FsPiB7XG4gIHJldHVybiBzcWxgZS5zdGFydGVkX2F0ID49ICR7ZnJvbX06OnRpbWVzdGFtcHR6IEFORCBlLnN0YXJ0ZWRfYXQgPD0gJHt0b306OnRpbWVzdGFtcHR6YDtcbn1cblxuLyoqIE9wdGlvbmFsIGBbZnJvbSx0b11gIHdpbmRvdyBvbiBgZS5zdGFydGVkX2F0YCBmb3IgdGhlIGV4ZWN1dGlvbiByZXBvcnRzIOKAlFxuICogIGEgbm8tb3AgYHNxbGAgZnJhZ21lbnQgd2hlbiBlaXRoZXIgYm91bmQgaXMgYWJzZW50IChhbGwtdGltZSkuIFNoYXJlZCBieSB0aGVcbiAqICBleGVjdXRpb24tY291bnQgYW5kIHBlci1waXBlbGluZS1leGVjdXRpb24gcmVwb3J0cyBzbyB0aGV5IG5hcnJvdyBpZGVudGljYWxseS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvcHRpb25hbFN0YXJ0ZWRBdFJhbmdlKHJhbmdlPzogeyBmcm9tPzogc3RyaW5nOyB0bz86IHN0cmluZyB9KTogUmV0dXJuVHlwZTx0eXBlb2Ygc3FsPiB7XG4gIHJldHVybiByYW5nZT8uZnJvbSAmJiByYW5nZT8udG9cbiAgICA/IHNxbGBBTkQgJHtzdGFydGVkQXRXaW5kb3cocmFuZ2UuZnJvbSwgcmFuZ2UudG8pfWBcbiAgICA6IHNxbGBgO1xufVxuXG4vKipcbiAqIFBlci1leGVjdXRpb24gdGVybWluYWwgZGVwbG95IHJvdyAob25lIHJvdyBwZXIgKGVudmlyb25tZW50LCBleGVjdXRpb24pLFxuICogTk9UIHBlciBzdGFnZSkuIFRoZSBTUUwgcm9sbHMgZXZlcnkgZGVwbG95IFNUQUdFIHRhcmdldGluZyBhbiBlbnYgd2l0aGluIGFuXG4gKiBleGVjdXRpb24gdXAgdG8gYSBzaW5nbGUgdGVybWluYWwgc3RhdHVzOyB0aGUgSlMgc2hhcGluZyBidWNrZXRzIHRoZXNlIGJ5XG4gKiBlbnZpcm9ubWVudC4gYGNvbW1pdF90c2AgaXMgdGhlIGV4ZWN1dGlvbidzIEVBUkxJRVNUIGNvbW1pdCB0aW1lIGFjcm9zc1xuICogYWxsIGl0cyBldmVudHMg4oCUIGNvbW1pdCBlbnJpY2htZW50IHJpZGVzIHRoZSBQSVBFTElORS9zb3VyY2UgZXZlbnQsIG5vdCB0aGVcbiAqIGRlcGxveSBTVEFHRSDigJQgam9pbmVkIGJ5IGV4ZWN1dGlvbl9pZCAobnVsbCB3aGVuIHVucmVzb2x2ZWQg4oaSIGxlYWQgYHVua25vd25gKS5cbiAqIGBpbl93aW5kb3dgIGlzIGZhbHNlIGZvciBhIGxvb2stYmFjay1vbmx5IHJvdyBrZXB0IHNvbGVseSBzbyBpbmNpZGVudHMgb3BlbmVkXG4gKiBuZWFyIGBmcm9tYCBjYW4gY29ycmVsYXRlIHRvIGEgZGVwbG95IHRoYXQgY29tcGxldGVkIGp1c3QgYmVmb3JlIHRoZSB3aW5kb3cuXG4gKi9cbiJdfQ==
|