@pipeline-builder/pipeline-data 4.3.2 → 4.3.4

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.
Files changed (56) hide show
  1. package/lib/api/crud-service.d.ts +7 -0
  2. package/lib/api/crud-service.js +14 -3
  3. package/lib/api/ecosystem-privacy.d.ts +25 -0
  4. package/lib/api/ecosystem-privacy.js +58 -0
  5. package/lib/api/pipeline-step-resolution.d.ts +111 -0
  6. package/lib/api/pipeline-step-resolution.js +163 -0
  7. package/lib/api/plugin-consumption-policy.d.ts +8 -2
  8. package/lib/api/plugin-consumption-policy.js +20 -3
  9. package/lib/api/plugin-resolution.d.ts +26 -9
  10. package/lib/api/plugin-resolution.js +51 -33
  11. package/lib/api/public-directory.js +1 -1
  12. package/lib/api/reporting/analytics-queries.d.ts +6 -4
  13. package/lib/api/reporting/analytics-queries.js +15 -14
  14. package/lib/api/reporting/deploy-rollup.d.ts +2 -0
  15. package/lib/api/reporting/deploy-rollup.js +5 -1
  16. package/lib/api/reporting/failure-classifier.d.ts +2 -6
  17. package/lib/api/reporting/failure-classifier.js +22 -1
  18. package/lib/api/reporting/ingest.js +73 -16
  19. package/lib/api/reporting/plugin-exposure.d.ts +261 -15
  20. package/lib/api/reporting/plugin-exposure.js +423 -38
  21. package/lib/api/reporting/stakeholder/compose.d.ts +1 -1
  22. package/lib/api/reporting/stakeholder/compose.js +30 -1
  23. package/lib/api/reporting/stakeholder/store.d.ts +16 -2
  24. package/lib/api/reporting/stakeholder/store.js +17 -6
  25. package/lib/api/reporting/types.d.ts +80 -1
  26. package/lib/api/reporting/types.js +1 -1
  27. package/lib/api/reporting-service.d.ts +11 -4
  28. package/lib/api/reporting-service.js +106 -43
  29. package/lib/api/soft-delete-sweep.d.ts +8 -18
  30. package/lib/api/soft-delete-sweep.js +35 -5
  31. package/lib/api/support-cases.d.ts +380 -0
  32. package/lib/api/support-cases.js +671 -0
  33. package/lib/api/version-references.d.ts +80 -0
  34. package/lib/api/version-references.js +135 -0
  35. package/lib/core/query-filters.d.ts +3 -3
  36. package/lib/core/query-filters.js +1 -1
  37. package/lib/database/drizzle-schema.d.ts +4858 -2759
  38. package/lib/database/drizzle-schema.js +13 -3
  39. package/lib/database/index.d.ts +1 -1
  40. package/lib/database/index.js +2 -2
  41. package/lib/database/schema/ecosystem.d.ts +53 -0
  42. package/lib/database/schema/ecosystem.js +14 -3
  43. package/lib/database/schema/pipeline.d.ts +38 -0
  44. package/lib/database/schema/pipeline.js +20 -2
  45. package/lib/database/schema/plugin.d.ts +265 -0
  46. package/lib/database/schema/plugin.js +34 -3
  47. package/lib/database/schema/reporting-analytics.d.ts +786 -4
  48. package/lib/database/schema/reporting-analytics.js +111 -5
  49. package/lib/database/schema/support.d.ts +1093 -0
  50. package/lib/database/schema/support.js +323 -0
  51. package/lib/database/tenancy.d.ts +7 -5
  52. package/lib/database/tenancy.js +1 -1
  53. package/lib/index.d.ts +7 -3
  54. package/lib/index.js +11 -3
  55. package/lib/testing/exports.json +57 -0
  56. package/package.json +4 -3
@@ -0,0 +1,323 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { SYSTEM_ORG_ID } from '@pipeline-builder/api-core';
4
+ import { sql } from 'drizzle-orm';
5
+ import { boolean, integer, varchar, pgTable, text, timestamp, uuid, index, uniqueIndex } from 'drizzle-orm/pg-core';
6
+ /**
7
+ * The WORKFLOW axis of a support case.
8
+ *
9
+ * `messages` already carries the conversation — identity, threading, priority,
10
+ * per-participant read state, attachments and soft-delete. What it has no column
11
+ * for is workflow: status, ownership, resolution and the response clock. That is
12
+ * this table, one row per case, joined to the conversation by `threadId`.
13
+ *
14
+ * Keeping them apart rather than widening `messages` is deliberate: `messages`
15
+ * also carries announcements and ordinary conversations, which have no status,
16
+ * no assignee and no response target. Six nullable columns on every announcement
17
+ * row to describe a state announcements cannot be in is how a table stops
18
+ * meaning one thing.
19
+ *
20
+ * @table support_cases
21
+ */
22
+ export const supportCase = pgTable('support_cases', {
23
+ // Internal key. NOT the case identity — see `threadId`.
24
+ id: uuid('id').primaryKey().defaultRandom(),
25
+ /**
26
+ * The root `messages.id` of the thread, and the CANONICAL case identity.
27
+ *
28
+ * The convention already exists: readers walk `threadId === root.id` and
29
+ * `update-message.ts` uses `updated.threadId ?? updated.id` for exactly this
30
+ * "the root is the identity" idea. So case identity falls out of threading the
31
+ * support path rather than being a new concept.
32
+ */
33
+ threadId: uuid('thread_id').notNull(),
34
+ // The TENANT org. Never the system org — a case is always about one tenant,
35
+ // even though the system org is the other participant in the thread.
36
+ orgId: varchar('org_id', { length: 255 }).notNull(),
37
+ /**
38
+ * Per-org, customer-quotable case number (rendered `ACME-1042`).
39
+ *
40
+ * A bare UUID is not something anyone reads out on a call or puts in an email
41
+ * subject, and a GLOBAL sequence would disclose total case volume to every
42
+ * customer. Allocated from `support_case_counters` in the same transaction as
43
+ * the insert; `support_case_org_number_uq` is the backstop that turns a
44
+ * bypassed counter into a failed insert rather than two cases sharing the one
45
+ * identifier customers quote back.
46
+ */
47
+ displayNumber: integer('display_number').notNull(),
48
+ // open | awaiting_support | awaiting_customer | resolved | closed
49
+ status: varchar('status', { length: 32 }).default('open').notNull(),
50
+ // Set by the opener; re-rankable by staff. Self-selected severity is why staff
51
+ // re-ranking is in v1: otherwise the tenant chooses the target they are owed.
52
+ severity: varchar('severity', { length: 16 }).default('normal').notNull(),
53
+ /**
54
+ * The support level held when the case was OPENED, frozen onto the case.
55
+ *
56
+ * Frozen deliberately: a customer who downgrades mid-case should still get the
57
+ * response they bought when they opened it. Resolving entitlement live would
58
+ * change an open case's promise underneath the person waiting on it.
59
+ */
60
+ level: varchar('level', { length: 32 }).notNull(),
61
+ /** True when the case was opened by spending a one-time incident rather than
62
+ * against a contact seat. Recorded so "how many incidents were actually
63
+ * used" is answerable from the cases, not only from a balance delta. */
64
+ openedWithIncident: boolean('opened_with_incident').default(false).notNull(),
65
+ // --- the two owners, which move independently. NEITHER is `createdBy`.
66
+ /** STAFF owner — a system-org actor. `null` is legitimate: it is the unowned
67
+ * pool, and how "I cannot take this" is said without a pseudo-assignee. */
68
+ assignedTo: text('assigned_to'),
69
+ /** TENANT owner — the designated contact currently responsible. Distinct from
70
+ * `createdBy`, which is the immutable audit fact of who raised the case:
71
+ * mutating that to express "someone else owns this now" would destroy the
72
+ * only record of who actually opened it. */
73
+ tenantContact: text('tenant_contact'),
74
+ // --- the response clock
75
+ /**
76
+ * When the first response is DUE, computed once at open and never recomputed.
77
+ *
78
+ * Frozen for the same reason `level` is: a change to the working week or the
79
+ * holiday list must not move a promise already made to a customer. Three
80
+ * things follow from storing it rather than deriving it per read:
81
+ * - the staff queue orders by a real deadline with no calendar arithmetic
82
+ * per row;
83
+ * - the standard/priority breach check becomes CONTRACTUAL, where a
84
+ * wall-clock quantile cannot express a business-day target at all (a
85
+ * priority case raised at 17:01 on a Friday is not late until Monday
86
+ * evening, ~79 wall-clock hours later);
87
+ * - a level with no published target, and a case opened while the calendar
88
+ * was misconfigured, are both simply NULL — no deadline rather than a
89
+ * wrong one.
90
+ */
91
+ responseDueAt: timestamp('response_due_at', { withTimezone: true }),
92
+ /** First staff reply. THE measured number — the response target is sold on it. */
93
+ firstResponseAt: timestamp('first_response_at', { withTimezone: true }),
94
+ /**
95
+ * CSAT, 1–5, set by the TENANT once the case is closed. Null = not rated,
96
+ * which is the usual state and must stay distinguishable from a bad rating.
97
+ *
98
+ * Lives here rather than in its own table because a case has exactly one
99
+ * rating — a table would buy a join and a uniqueness constraint to enforce
100
+ * what a column gets for free. First-response latency says whether we
101
+ * answered fast; this is the only thing that says whether the answer helped,
102
+ * and a desk can hit every target while being bad at support.
103
+ */
104
+ satisfaction: integer('satisfaction'),
105
+ /** Optional free text with the rating. Capped at the route. */
106
+ satisfactionComment: text('satisfaction_comment'),
107
+ satisfactionAt: timestamp('satisfaction_at', { withTimezone: true }),
108
+ /** Set when status → `awaiting_customer`; the pause anchor. */
109
+ awaitingSince: timestamp('awaiting_since', { withTimezone: true }),
110
+ /**
111
+ * Accumulated seconds spent waiting on the customer.
112
+ *
113
+ * Ageing subtracts this. Without it a case we answered in an hour, where the
114
+ * tenant replied four days later, reads as a four-day case — and the metric
115
+ * Phase 2b exists to produce reports a number no customer will accept. An
116
+ * accumulator plus the current anchor survives a case bouncing between states
117
+ * repeatedly, which replaying status history would not.
118
+ */
119
+ awaitingTotalSeconds: integer('awaiting_total_seconds').default(0).notNull(),
120
+ closedAt: timestamp('closed_at', { withTimezone: true }),
121
+ closedBy: text('closed_by'),
122
+ // Audit + soft-delete, same shape as `messages`.
123
+ createdBy: text('created_by').default(SYSTEM_ORG_ID).notNull(),
124
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
125
+ updatedBy: text('updated_by').default(SYSTEM_ORG_ID).notNull(),
126
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
127
+ isActive: boolean('is_active').default(true).notNull(),
128
+ deletedAt: timestamp('deleted_at', { withTimezone: true }),
129
+ deletedBy: text('deleted_by'),
130
+ purgeAfter: timestamp('purge_after', { withTimezone: true }),
131
+ }, (table) => ({
132
+ /**
133
+ * THE queue query: every open case across ALL tenants, oldest first.
134
+ *
135
+ * The one query shape with no org predicate to narrow it, so it is also the
136
+ * only one that scans. Partial because the queue never asks about closed
137
+ * cases — which are most of the table within a month. Mirrors
138
+ * `message_purge_idx`, which is partial for the same reason.
139
+ */
140
+ queueIdx: index('support_case_queue_idx')
141
+ .on(table.createdAt)
142
+ .where(sql `status IN ('open', 'awaiting_support') AND deleted_at IS NULL`),
143
+ /**
144
+ * The on-call sweep's only query: premium cases whose first-response target is
145
+ * approaching with nothing stamped yet.
146
+ *
147
+ * PARTIAL because the tick runs every five minutes forever and the rows it
148
+ * wants are a tiny, shrinking fraction of the table — unanswered premium
149
+ * cases. Without it every tick is a scan, and it is the one query with no org
150
+ * predicate to narrow it.
151
+ *
152
+ * `level` and NOT `is_premium`: that column lives on support_CONTACTS and
153
+ * marks an upgraded contact, while a case freezes the opening contact's
154
+ * effective level at open. The case's own promise is its `level`, so
155
+ * upgrading a contact later must not move a deadline already published to a
156
+ * customer.
157
+ */
158
+ responseDueIdx: index('support_case_response_due_idx')
159
+ .on(table.responseDueAt)
160
+ .where(sql `level = 'support_premium' AND first_response_at IS NULL AND deleted_at IS NULL`),
161
+ // A tenant listing its own cases.
162
+ orgStatusIdx: index('support_case_org_status_idx').on(table.orgId, table.status),
163
+ // The rolling-window case count behind the FAIR-USE allowance: how many cases
164
+ // this account raised in the last N days. Leading `org_id` because the count
165
+ // is always scoped to an account subtree, then `created_at` so the window is a
166
+ // range scan rather than a filter over every case the org ever raised.
167
+ orgCreatedIdx: index('support_case_org_created_idx').on(table.orgId, table.createdAt),
168
+ // "What am I on the hook for", one engineer.
169
+ assigneeIdx: index('support_case_assigned_idx')
170
+ .on(table.assignedTo, table.status)
171
+ .where(sql `assigned_to IS NOT NULL`),
172
+ // "My cases" for a contact, AND the lookup that finds a departing contact's
173
+ // open cases so they can be reassigned instead of orphaned.
174
+ tenantContactIdx: index('support_case_tenant_contact_idx')
175
+ .on(table.tenantContact, table.status)
176
+ .where(sql `tenant_contact IS NOT NULL`),
177
+ // Case identity, reached from any message in the thread.
178
+ threadUq: uniqueIndex('support_case_thread_uq').on(table.threadId),
179
+ // The customer-quotable number is unique per org, enforced not assumed.
180
+ displayUq: uniqueIndex('support_case_org_number_uq')
181
+ .on(table.orgId, table.displayNumber)
182
+ .where(sql `deleted_at IS NULL`),
183
+ }));
184
+ /**
185
+ * Per-org allocator for `support_cases.display_number`.
186
+ *
187
+ * Postgres sequences are global and cannot be per-org without one sequence per
188
+ * tenant, so the counter is a row: `UPDATE … SET next_number = next_number + 1
189
+ * RETURNING next_number` inside the case-insert transaction, where the row lock
190
+ * serialises concurrent opens within one org.
191
+ *
192
+ * @table support_case_counters
193
+ */
194
+ export const supportCaseCounter = pgTable('support_case_counters', {
195
+ orgId: varchar('org_id', { length: 255 }).primaryKey(),
196
+ nextNumber: integer('next_number').default(1).notNull(),
197
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
198
+ });
199
+ /**
200
+ * The members authorised to open support cases — what the per-contact price
201
+ * bills for.
202
+ *
203
+ * The COUNT is capped against effective `supportContacts` at designation time,
204
+ * in the same shape seats are capped at invite time. `supportContacts` has a
205
+ * tier base of 0 everywhere, so an org with no support add-on has no contacts
206
+ * and cannot open a case: the paywall is a quota check, not a feature flag.
207
+ *
208
+ * @table support_contacts
209
+ */
210
+ export const supportContact = pgTable('support_contacts', {
211
+ id: uuid('id').primaryKey().defaultRandom(),
212
+ orgId: varchar('org_id', { length: 255 }).notNull(),
213
+ userId: text('user_id').notNull(),
214
+ // Who nominated them. Audit-worthy: a contact is a paid, privileged slot.
215
+ designatedBy: text('designated_by').notNull(),
216
+ designatedAt: timestamp('designated_at', { withTimezone: true }).defaultNow().notNull(),
217
+ /**
218
+ * Whether this contact is UPGRADED to premium — 24×7 coverage, the 8-hour
219
+ * any-day target, and the only contacts who may declare `urgent` severity.
220
+ *
221
+ * A column on the contact rather than a level on the org, because that is what
222
+ * the upgrade model means: an account holds one BASELINE level covering every
223
+ * contact and upgrades a subset. Without this the `supportPremiumContacts` cap
224
+ * would grant a quota over nothing — there would be no way for any contact to
225
+ * actually be premium, and the case-open path would have nothing to read.
226
+ *
227
+ * The case freezes the OPENING CONTACT's effective level at open
228
+ * (`support_case.level`), so flipping this later never changes the promise on
229
+ * a case already raised.
230
+ */
231
+ isPremium: boolean('is_premium').default(false).notNull(),
232
+ isActive: boolean('is_active').default(true).notNull(),
233
+ revokedAt: timestamp('revoked_at', { withTimezone: true }),
234
+ revokedBy: text('revoked_by'),
235
+ }, (table) => ({
236
+ // One live designation per (org, user). Partial so a revoked row does not
237
+ // block re-designating the same person later.
238
+ orgUserUq: uniqueIndex('support_contact_org_user_uq')
239
+ .on(table.orgId, table.userId)
240
+ .where(sql `is_active = true`),
241
+ // Counting an org's live contacts against its cap, and listing them for the
242
+ // tenant-side owner picker.
243
+ orgActiveIdx: index('support_contact_org_active_idx').on(table.orgId, table.isActive),
244
+ // The premium SUBSET, counted against `supportPremiumContacts` on every
245
+ // upgrade. Partial on both flags because that is the only question asked of
246
+ // it: how many live contacts in this scope are upgraded.
247
+ orgPremiumIdx: index('support_contact_org_premium_idx')
248
+ .on(table.orgId, table.userId)
249
+ .where(sql `is_active = true AND is_premium = true`),
250
+ }));
251
+ /**
252
+ * Canned staff replies — a shared library of answers the desk reuses.
253
+ *
254
+ * SYSTEM-WIDE, not per-tenant, and deliberately so: these are the vendor's own
255
+ * wording for recurring questions, authored once and used across every
256
+ * customer. There is no `org_id` because scoping them per tenant would be the
257
+ * opposite of the point — the value is that the answer to "how do I rotate a
258
+ * service key" is written well once rather than retyped badly fifty times.
259
+ *
260
+ * That also means RLS does not apply: every row is visible to the staff who can
261
+ * reach the queue, and to nobody else. The routes are system-admin gated on
262
+ * both read and write for exactly that reason.
263
+ *
264
+ * Soft-deleted rather than removed, because a retired template is still the
265
+ * explanation of what a past reply said.
266
+ *
267
+ * @table support_canned_responses
268
+ */
269
+ export const supportCannedResponse = pgTable('support_canned_responses', {
270
+ id: uuid('id').primaryKey().defaultRandom(),
271
+ /** Short label the picker lists. */
272
+ title: varchar('title', { length: 200 }).notNull(),
273
+ body: text('body').notNull(),
274
+ createdBy: text('created_by').notNull(),
275
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
276
+ updatedBy: text('updated_by').notNull(),
277
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
278
+ isActive: boolean('is_active').default(true).notNull(),
279
+ }, (table) => ({
280
+ // The picker's only query: live templates, alphabetical.
281
+ activeTitleIdx: index('support_canned_active_idx').on(table.isActive, table.title),
282
+ }));
283
+ /**
284
+ * CSAT: the customer's verdict on a closed case.
285
+ *
286
+ * A COLUMN SET on the case rather than its own table, unlike notes. The reason
287
+ * is cardinality, not convenience: a case has many notes and exactly one
288
+ * satisfaction rating, so a table would buy an extra join and a uniqueness
289
+ * constraint to enforce what a column gets for free.
290
+ *
291
+ * Why it matters more here than in most products: the thing being SOLD is a
292
+ * response time, and first-response latency only measures whether we answered
293
+ * fast — not whether the answer was any good. A desk can hit every target and
294
+ * still be bad at support, and without this nothing in the system would notice.
295
+ *
296
+ * @table support_cases (columns)
297
+ */
298
+ /**
299
+ * Staff-only notes on a case.
300
+ *
301
+ * A SEPARATE TABLE rather than a flag on `messages`, and the reason is the
302
+ * failure mode: `messages` is read through one shared visibility predicate
303
+ * (`buildMessageConditions`), so a flag means every read path that forgets the
304
+ * extra condition leaks an internal note to the tenant. A separate table cannot
305
+ * leak by omission — it has to be joined deliberately.
306
+ *
307
+ * @table support_case_notes
308
+ */
309
+ export const supportCaseNote = pgTable('support_case_notes', {
310
+ id: uuid('id').primaryKey().defaultRandom(),
311
+ caseId: uuid('case_id').notNull(),
312
+ // Denormalised so a note can never be served without its tenant scope.
313
+ orgId: varchar('org_id', { length: 255 }).notNull(),
314
+ content: text('content').notNull(),
315
+ createdBy: text('created_by').notNull(),
316
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
317
+ isActive: boolean('is_active').default(true).notNull(),
318
+ deletedAt: timestamp('deleted_at', { withTimezone: true }),
319
+ deletedBy: text('deleted_by'),
320
+ }, (table) => ({
321
+ caseIdx: index('support_case_note_case_idx').on(table.caseId, table.isActive),
322
+ }));
323
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VwcG9ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kYXRhYmFzZS9zY2hlbWEvc3VwcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXBIOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsZUFBZSxFQUFFO0lBQ2xELHdEQUF3RDtJQUN4RCxFQUFFLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDLGFBQWEsRUFBRTtJQUUzQzs7Ozs7OztPQU9HO0lBQ0gsUUFBUSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFFckMsNEVBQTRFO0lBQzVFLHFFQUFxRTtJQUNyRSxLQUFLLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUVuRDs7Ozs7Ozs7O09BU0c7SUFDSCxhQUFhLEVBQUUsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUMsT0FBTyxFQUFFO0lBRWxELGtFQUFrRTtJQUNsRSxNQUFNLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFFbkUsK0VBQStFO0lBQy9FLDhFQUE4RTtJQUM5RSxRQUFRLEVBQUUsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFFekU7Ozs7OztPQU1HO0lBQ0gsS0FBSyxFQUFFLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFFakQ7OzZFQUV5RTtJQUN6RSxrQkFBa0IsRUFBRSxPQUFPLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFO0lBRTVFLHdFQUF3RTtJQUN4RTtnRkFDNEU7SUFDNUUsVUFBVSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDL0I7OztpREFHNkM7SUFDN0MsYUFBYSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztJQUVyQyx5QkFBeUI7SUFDekI7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0gsYUFBYSxFQUFFLFNBQVMsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUNuRSxrRkFBa0Y7SUFDbEYsZUFBZSxFQUFFLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUN2RTs7Ozs7Ozs7O09BU0c7SUFDSCxZQUFZLEVBQUUsT0FBTyxDQUFDLGNBQWMsQ0FBQztJQUNyQywrREFBK0Q7SUFDL0QsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDO0lBQ2pELGNBQWMsRUFBRSxTQUFTLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDcEUsK0RBQStEO0lBQy9ELGFBQWEsRUFBRSxTQUFTLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDbEU7Ozs7Ozs7O09BUUc7SUFDSCxvQkFBb0IsRUFBRSxPQUFPLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFO0lBRTVFLFFBQVEsRUFBRSxTQUFTLENBQUMsV0FBVyxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ3hELFFBQVEsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDO0lBRTNCLGlEQUFpRDtJQUNqRCxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFDOUQsU0FBUyxFQUFFLFNBQVMsQ0FBQyxZQUFZLEVBQUUsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxPQUFPLEVBQUU7SUFDakYsU0FBUyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQzlELFNBQVMsRUFBRSxTQUFTLENBQUMsWUFBWSxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsT0FBTyxFQUFFO0lBQ2pGLFFBQVEsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUN0RCxTQUFTLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUMxRCxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQztJQUM3QixVQUFVLEVBQUUsU0FBUyxDQUFDLGFBQWEsRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztDQUM3RCxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2I7Ozs7Ozs7T0FPRztJQUNILFFBQVEsRUFBRSxLQUFLLENBQUMsd0JBQXdCLENBQUM7U0FDdEMsRUFBRSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7U0FDbkIsS0FBSyxDQUFDLEdBQUcsQ0FBQSwrREFBK0QsQ0FBQztJQUU1RTs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNILGNBQWMsRUFBRSxLQUFLLENBQUMsK0JBQStCLENBQUM7U0FDbkQsRUFBRSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUM7U0FDdkIsS0FBSyxDQUFDLEdBQUcsQ0FBQSxnRkFBZ0YsQ0FBQztJQUU3RixrQ0FBa0M7SUFDbEMsWUFBWSxFQUFFLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDaEYsOEVBQThFO0lBQzlFLDZFQUE2RTtJQUM3RSwrRUFBK0U7SUFDL0UsdUVBQXVFO0lBQ3ZFLGFBQWEsRUFBRSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDO0lBRXJGLDZDQUE2QztJQUM3QyxXQUFXLEVBQUUsS0FBSyxDQUFDLDJCQUEyQixDQUFDO1NBQzVDLEVBQUUsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7U0FDbEMsS0FBSyxDQUFDLEdBQUcsQ0FBQSx5QkFBeUIsQ0FBQztJQUV0Qyw0RUFBNEU7SUFDNUUsNERBQTREO0lBQzVELGdCQUFnQixFQUFFLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQztTQUN2RCxFQUFFLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDO1NBQ3JDLEtBQUssQ0FBQyxHQUFHLENBQUEsNEJBQTRCLENBQUM7SUFFekMseURBQXlEO0lBQ3pELFFBQVEsRUFBRSxXQUFXLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQztJQUVsRSx3RUFBd0U7SUFDeEUsU0FBUyxFQUFFLFdBQVcsQ0FBQyw0QkFBNEIsQ0FBQztTQUNqRCxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsYUFBYSxDQUFDO1NBQ3BDLEtBQUssQ0FBQyxHQUFHLENBQUEsb0JBQW9CLENBQUM7Q0FDbEMsQ0FBQyxDQUFDLENBQUM7QUFFSjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsdUJBQXVCLEVBQUU7SUFDakUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUU7SUFDdEQsVUFBVSxFQUFFLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ3ZELFNBQVMsRUFBRSxTQUFTLENBQUMsWUFBWSxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsT0FBTyxFQUFFO0NBQ2xGLENBQUMsQ0FBQztBQUVIOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixFQUFFO0lBQ3hELEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsYUFBYSxFQUFFO0lBQzNDLEtBQUssRUFBRSxPQUFPLENBQUMsUUFBUSxFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ25ELE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ2pDLDBFQUEwRTtJQUMxRSxZQUFZLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUM3QyxZQUFZLEVBQUUsU0FBUyxDQUFDLGVBQWUsRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDLE9BQU8sRUFBRTtJQUN2Rjs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsU0FBUyxFQUFFLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ3pELFFBQVEsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUN0RCxTQUFTLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUMxRCxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQztDQUM5QixFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2IsMEVBQTBFO0lBQzFFLDhDQUE4QztJQUM5QyxTQUFTLEVBQUUsV0FBVyxDQUFDLDZCQUE2QixDQUFDO1NBQ2xELEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7U0FDN0IsS0FBSyxDQUFDLEdBQUcsQ0FBQSxrQkFBa0IsQ0FBQztJQUMvQiw0RUFBNEU7SUFDNUUsNEJBQTRCO0lBQzVCLFlBQVksRUFBRSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDO0lBQ3JGLHdFQUF3RTtJQUN4RSw0RUFBNEU7SUFDNUUseURBQXlEO0lBQ3pELGFBQWEsRUFBRSxLQUFLLENBQUMsaUNBQWlDLENBQUM7U0FDcEQsRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQztTQUM3QixLQUFLLENBQUMsR0FBRyxDQUFBLHdDQUF3QyxDQUFDO0NBQ3RELENBQUMsQ0FBQyxDQUFDO0FBRUo7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsT0FBTyxDQUFDLDBCQUEwQixFQUFFO0lBQ3ZFLEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsYUFBYSxFQUFFO0lBQzNDLG9DQUFvQztJQUNwQyxLQUFLLEVBQUUsT0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUNsRCxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUM1QixTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUN2QyxTQUFTLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDLE9BQU8sRUFBRTtJQUNqRixTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUN2QyxTQUFTLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDLE9BQU8sRUFBRTtJQUNqRixRQUFRLEVBQUUsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUU7Q0FDdkQsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNiLHlEQUF5RDtJQUN6RCxjQUFjLEVBQUUsS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQztDQUNuRixDQUFDLENBQUMsQ0FBQztBQUVKOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBRUg7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxPQUFPLENBQUMsb0JBQW9CLEVBQUU7SUFDM0QsRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxhQUFhLEVBQUU7SUFDM0MsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFDakMsdUVBQXVFO0lBQ3ZFLEtBQUssRUFBRSxPQUFPLENBQUMsUUFBUSxFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ25ELE9BQU8sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ2xDLFNBQVMsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxFQUFFO0lBQ3ZDLFNBQVMsRUFBRSxTQUFTLENBQUMsWUFBWSxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsT0FBTyxFQUFFO0lBQ2pGLFFBQVEsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUN0RCxTQUFTLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUMxRCxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQztDQUM5QixFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2IsT0FBTyxFQUFFLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUM7Q0FDOUUsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgU1lTVEVNX09SR19JRCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IGJvb2xlYW4sIGludGVnZXIsIHZhcmNoYXIsIHBnVGFibGUsIHRleHQsIHRpbWVzdGFtcCwgdXVpZCwgaW5kZXgsIHVuaXF1ZUluZGV4IH0gZnJvbSAnZHJpenpsZS1vcm0vcGctY29yZSc7XG5cbi8qKlxuICogVGhlIFdPUktGTE9XIGF4aXMgb2YgYSBzdXBwb3J0IGNhc2UuXG4gKlxuICogYG1lc3NhZ2VzYCBhbHJlYWR5IGNhcnJpZXMgdGhlIGNvbnZlcnNhdGlvbiDigJQgaWRlbnRpdHksIHRocmVhZGluZywgcHJpb3JpdHksXG4gKiBwZXItcGFydGljaXBhbnQgcmVhZCBzdGF0ZSwgYXR0YWNobWVudHMgYW5kIHNvZnQtZGVsZXRlLiBXaGF0IGl0IGhhcyBubyBjb2x1bW5cbiAqIGZvciBpcyB3b3JrZmxvdzogc3RhdHVzLCBvd25lcnNoaXAsIHJlc29sdXRpb24gYW5kIHRoZSByZXNwb25zZSBjbG9jay4gVGhhdCBpc1xuICogdGhpcyB0YWJsZSwgb25lIHJvdyBwZXIgY2FzZSwgam9pbmVkIHRvIHRoZSBjb252ZXJzYXRpb24gYnkgYHRocmVhZElkYC5cbiAqXG4gKiBLZWVwaW5nIHRoZW0gYXBhcnQgcmF0aGVyIHRoYW4gd2lkZW5pbmcgYG1lc3NhZ2VzYCBpcyBkZWxpYmVyYXRlOiBgbWVzc2FnZXNgXG4gKiBhbHNvIGNhcnJpZXMgYW5ub3VuY2VtZW50cyBhbmQgb3JkaW5hcnkgY29udmVyc2F0aW9ucywgd2hpY2ggaGF2ZSBubyBzdGF0dXMsXG4gKiBubyBhc3NpZ25lZSBhbmQgbm8gcmVzcG9uc2UgdGFyZ2V0LiBTaXggbnVsbGFibGUgY29sdW1ucyBvbiBldmVyeSBhbm5vdW5jZW1lbnRcbiAqIHJvdyB0byBkZXNjcmliZSBhIHN0YXRlIGFubm91bmNlbWVudHMgY2Fubm90IGJlIGluIGlzIGhvdyBhIHRhYmxlIHN0b3BzXG4gKiBtZWFuaW5nIG9uZSB0aGluZy5cbiAqXG4gKiBAdGFibGUgc3VwcG9ydF9jYXNlc1xuICovXG5leHBvcnQgY29uc3Qgc3VwcG9ydENhc2UgPSBwZ1RhYmxlKCdzdXBwb3J0X2Nhc2VzJywge1xuICAvLyBJbnRlcm5hbCBrZXkuIE5PVCB0aGUgY2FzZSBpZGVudGl0eSDigJQgc2VlIGB0aHJlYWRJZGAuXG4gIGlkOiB1dWlkKCdpZCcpLnByaW1hcnlLZXkoKS5kZWZhdWx0UmFuZG9tKCksXG5cbiAgLyoqXG4gICAqIFRoZSByb290IGBtZXNzYWdlcy5pZGAgb2YgdGhlIHRocmVhZCwgYW5kIHRoZSBDQU5PTklDQUwgY2FzZSBpZGVudGl0eS5cbiAgICpcbiAgICogVGhlIGNvbnZlbnRpb24gYWxyZWFkeSBleGlzdHM6IHJlYWRlcnMgd2FsayBgdGhyZWFkSWQgPT09IHJvb3QuaWRgIGFuZFxuICAgKiBgdXBkYXRlLW1lc3NhZ2UudHNgIHVzZXMgYHVwZGF0ZWQudGhyZWFkSWQgPz8gdXBkYXRlZC5pZGAgZm9yIGV4YWN0bHkgdGhpc1xuICAgKiBcInRoZSByb290IGlzIHRoZSBpZGVudGl0eVwiIGlkZWEuIFNvIGNhc2UgaWRlbnRpdHkgZmFsbHMgb3V0IG9mIHRocmVhZGluZyB0aGVcbiAgICogc3VwcG9ydCBwYXRoIHJhdGhlciB0aGFuIGJlaW5nIGEgbmV3IGNvbmNlcHQuXG4gICAqL1xuICB0aHJlYWRJZDogdXVpZCgndGhyZWFkX2lkJykubm90TnVsbCgpLFxuXG4gIC8vIFRoZSBURU5BTlQgb3JnLiBOZXZlciB0aGUgc3lzdGVtIG9yZyDigJQgYSBjYXNlIGlzIGFsd2F5cyBhYm91dCBvbmUgdGVuYW50LFxuICAvLyBldmVuIHRob3VnaCB0aGUgc3lzdGVtIG9yZyBpcyB0aGUgb3RoZXIgcGFydGljaXBhbnQgaW4gdGhlIHRocmVhZC5cbiAgb3JnSWQ6IHZhcmNoYXIoJ29yZ19pZCcsIHsgbGVuZ3RoOiAyNTUgfSkubm90TnVsbCgpLFxuXG4gIC8qKlxuICAgKiBQZXItb3JnLCBjdXN0b21lci1xdW90YWJsZSBjYXNlIG51bWJlciAocmVuZGVyZWQgYEFDTUUtMTA0MmApLlxuICAgKlxuICAgKiBBIGJhcmUgVVVJRCBpcyBub3Qgc29tZXRoaW5nIGFueW9uZSByZWFkcyBvdXQgb24gYSBjYWxsIG9yIHB1dHMgaW4gYW4gZW1haWxcbiAgICogc3ViamVjdCwgYW5kIGEgR0xPQkFMIHNlcXVlbmNlIHdvdWxkIGRpc2Nsb3NlIHRvdGFsIGNhc2Ugdm9sdW1lIHRvIGV2ZXJ5XG4gICAqIGN1c3RvbWVyLiBBbGxvY2F0ZWQgZnJvbSBgc3VwcG9ydF9jYXNlX2NvdW50ZXJzYCBpbiB0aGUgc2FtZSB0cmFuc2FjdGlvbiBhc1xuICAgKiB0aGUgaW5zZXJ0OyBgc3VwcG9ydF9jYXNlX29yZ19udW1iZXJfdXFgIGlzIHRoZSBiYWNrc3RvcCB0aGF0IHR1cm5zIGFcbiAgICogYnlwYXNzZWQgY291bnRlciBpbnRvIGEgZmFpbGVkIGluc2VydCByYXRoZXIgdGhhbiB0d28gY2FzZXMgc2hhcmluZyB0aGUgb25lXG4gICAqIGlkZW50aWZpZXIgY3VzdG9tZXJzIHF1b3RlIGJhY2suXG4gICAqL1xuICBkaXNwbGF5TnVtYmVyOiBpbnRlZ2VyKCdkaXNwbGF5X251bWJlcicpLm5vdE51bGwoKSxcblxuICAvLyBvcGVuIHwgYXdhaXRpbmdfc3VwcG9ydCB8IGF3YWl0aW5nX2N1c3RvbWVyIHwgcmVzb2x2ZWQgfCBjbG9zZWRcbiAgc3RhdHVzOiB2YXJjaGFyKCdzdGF0dXMnLCB7IGxlbmd0aDogMzIgfSkuZGVmYXVsdCgnb3BlbicpLm5vdE51bGwoKSxcblxuICAvLyBTZXQgYnkgdGhlIG9wZW5lcjsgcmUtcmFua2FibGUgYnkgc3RhZmYuIFNlbGYtc2VsZWN0ZWQgc2V2ZXJpdHkgaXMgd2h5IHN0YWZmXG4gIC8vIHJlLXJhbmtpbmcgaXMgaW4gdjE6IG90aGVyd2lzZSB0aGUgdGVuYW50IGNob29zZXMgdGhlIHRhcmdldCB0aGV5IGFyZSBvd2VkLlxuICBzZXZlcml0eTogdmFyY2hhcignc2V2ZXJpdHknLCB7IGxlbmd0aDogMTYgfSkuZGVmYXVsdCgnbm9ybWFsJykubm90TnVsbCgpLFxuXG4gIC8qKlxuICAgKiBUaGUgc3VwcG9ydCBsZXZlbCBoZWxkIHdoZW4gdGhlIGNhc2Ugd2FzIE9QRU5FRCwgZnJvemVuIG9udG8gdGhlIGNhc2UuXG4gICAqXG4gICAqIEZyb3plbiBkZWxpYmVyYXRlbHk6IGEgY3VzdG9tZXIgd2hvIGRvd25ncmFkZXMgbWlkLWNhc2Ugc2hvdWxkIHN0aWxsIGdldCB0aGVcbiAgICogcmVzcG9uc2UgdGhleSBib3VnaHQgd2hlbiB0aGV5IG9wZW5lZCBpdC4gUmVzb2x2aW5nIGVudGl0bGVtZW50IGxpdmUgd291bGRcbiAgICogY2hhbmdlIGFuIG9wZW4gY2FzZSdzIHByb21pc2UgdW5kZXJuZWF0aCB0aGUgcGVyc29uIHdhaXRpbmcgb24gaXQuXG4gICAqL1xuICBsZXZlbDogdmFyY2hhcignbGV2ZWwnLCB7IGxlbmd0aDogMzIgfSkubm90TnVsbCgpLFxuXG4gIC8qKiBUcnVlIHdoZW4gdGhlIGNhc2Ugd2FzIG9wZW5lZCBieSBzcGVuZGluZyBhIG9uZS10aW1lIGluY2lkZW50IHJhdGhlciB0aGFuXG4gICAqICBhZ2FpbnN0IGEgY29udGFjdCBzZWF0LiBSZWNvcmRlZCBzbyBcImhvdyBtYW55IGluY2lkZW50cyB3ZXJlIGFjdHVhbGx5XG4gICAqICB1c2VkXCIgaXMgYW5zd2VyYWJsZSBmcm9tIHRoZSBjYXNlcywgbm90IG9ubHkgZnJvbSBhIGJhbGFuY2UgZGVsdGEuICovXG4gIG9wZW5lZFdpdGhJbmNpZGVudDogYm9vbGVhbignb3BlbmVkX3dpdGhfaW5jaWRlbnQnKS5kZWZhdWx0KGZhbHNlKS5ub3ROdWxsKCksXG5cbiAgLy8gLS0tIHRoZSB0d28gb3duZXJzLCB3aGljaCBtb3ZlIGluZGVwZW5kZW50bHkuIE5FSVRIRVIgaXMgYGNyZWF0ZWRCeWAuXG4gIC8qKiBTVEFGRiBvd25lciDigJQgYSBzeXN0ZW0tb3JnIGFjdG9yLiBgbnVsbGAgaXMgbGVnaXRpbWF0ZTogaXQgaXMgdGhlIHVub3duZWRcbiAgICogIHBvb2wsIGFuZCBob3cgXCJJIGNhbm5vdCB0YWtlIHRoaXNcIiBpcyBzYWlkIHdpdGhvdXQgYSBwc2V1ZG8tYXNzaWduZWUuICovXG4gIGFzc2lnbmVkVG86IHRleHQoJ2Fzc2lnbmVkX3RvJyksXG4gIC8qKiBURU5BTlQgb3duZXIg4oCUIHRoZSBkZXNpZ25hdGVkIGNvbnRhY3QgY3VycmVudGx5IHJlc3BvbnNpYmxlLiBEaXN0aW5jdCBmcm9tXG4gICAqICBgY3JlYXRlZEJ5YCwgd2hpY2ggaXMgdGhlIGltbXV0YWJsZSBhdWRpdCBmYWN0IG9mIHdobyByYWlzZWQgdGhlIGNhc2U6XG4gICAqICBtdXRhdGluZyB0aGF0IHRvIGV4cHJlc3MgXCJzb21lb25lIGVsc2Ugb3ducyB0aGlzIG5vd1wiIHdvdWxkIGRlc3Ryb3kgdGhlXG4gICAqICBvbmx5IHJlY29yZCBvZiB3aG8gYWN0dWFsbHkgb3BlbmVkIGl0LiAqL1xuICB0ZW5hbnRDb250YWN0OiB0ZXh0KCd0ZW5hbnRfY29udGFjdCcpLFxuXG4gIC8vIC0tLSB0aGUgcmVzcG9uc2UgY2xvY2tcbiAgLyoqXG4gICAqIFdoZW4gdGhlIGZpcnN0IHJlc3BvbnNlIGlzIERVRSwgY29tcHV0ZWQgb25jZSBhdCBvcGVuIGFuZCBuZXZlciByZWNvbXB1dGVkLlxuICAgKlxuICAgKiBGcm96ZW4gZm9yIHRoZSBzYW1lIHJlYXNvbiBgbGV2ZWxgIGlzOiBhIGNoYW5nZSB0byB0aGUgd29ya2luZyB3ZWVrIG9yIHRoZVxuICAgKiBob2xpZGF5IGxpc3QgbXVzdCBub3QgbW92ZSBhIHByb21pc2UgYWxyZWFkeSBtYWRlIHRvIGEgY3VzdG9tZXIuIFRocmVlXG4gICAqIHRoaW5ncyBmb2xsb3cgZnJvbSBzdG9yaW5nIGl0IHJhdGhlciB0aGFuIGRlcml2aW5nIGl0IHBlciByZWFkOlxuICAgKiAgIC0gdGhlIHN0YWZmIHF1ZXVlIG9yZGVycyBieSBhIHJlYWwgZGVhZGxpbmUgd2l0aCBubyBjYWxlbmRhciBhcml0aG1ldGljXG4gICAqICAgICBwZXIgcm93O1xuICAgKiAgIC0gdGhlIHN0YW5kYXJkL3ByaW9yaXR5IGJyZWFjaCBjaGVjayBiZWNvbWVzIENPTlRSQUNUVUFMLCB3aGVyZSBhXG4gICAqICAgICB3YWxsLWNsb2NrIHF1YW50aWxlIGNhbm5vdCBleHByZXNzIGEgYnVzaW5lc3MtZGF5IHRhcmdldCBhdCBhbGwgKGFcbiAgICogICAgIHByaW9yaXR5IGNhc2UgcmFpc2VkIGF0IDE3OjAxIG9uIGEgRnJpZGF5IGlzIG5vdCBsYXRlIHVudGlsIE1vbmRheVxuICAgKiAgICAgZXZlbmluZywgfjc5IHdhbGwtY2xvY2sgaG91cnMgbGF0ZXIpO1xuICAgKiAgIC0gYSBsZXZlbCB3aXRoIG5vIHB1Ymxpc2hlZCB0YXJnZXQsIGFuZCBhIGNhc2Ugb3BlbmVkIHdoaWxlIHRoZSBjYWxlbmRhclxuICAgKiAgICAgd2FzIG1pc2NvbmZpZ3VyZWQsIGFyZSBib3RoIHNpbXBseSBOVUxMIOKAlCBubyBkZWFkbGluZSByYXRoZXIgdGhhbiBhXG4gICAqICAgICB3cm9uZyBvbmUuXG4gICAqL1xuICByZXNwb25zZUR1ZUF0OiB0aW1lc3RhbXAoJ3Jlc3BvbnNlX2R1ZV9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuICAvKiogRmlyc3Qgc3RhZmYgcmVwbHkuIFRIRSBtZWFzdXJlZCBudW1iZXIg4oCUIHRoZSByZXNwb25zZSB0YXJnZXQgaXMgc29sZCBvbiBpdC4gKi9cbiAgZmlyc3RSZXNwb25zZUF0OiB0aW1lc3RhbXAoJ2ZpcnN0X3Jlc3BvbnNlX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIC8qKlxuICAgKiBDU0FULCAx4oCTNSwgc2V0IGJ5IHRoZSBURU5BTlQgb25jZSB0aGUgY2FzZSBpcyBjbG9zZWQuIE51bGwgPSBub3QgcmF0ZWQsXG4gICAqIHdoaWNoIGlzIHRoZSB1c3VhbCBzdGF0ZSBhbmQgbXVzdCBzdGF5IGRpc3Rpbmd1aXNoYWJsZSBmcm9tIGEgYmFkIHJhdGluZy5cbiAgICpcbiAgICogTGl2ZXMgaGVyZSByYXRoZXIgdGhhbiBpbiBpdHMgb3duIHRhYmxlIGJlY2F1c2UgYSBjYXNlIGhhcyBleGFjdGx5IG9uZVxuICAgKiByYXRpbmcg4oCUIGEgdGFibGUgd291bGQgYnV5IGEgam9pbiBhbmQgYSB1bmlxdWVuZXNzIGNvbnN0cmFpbnQgdG8gZW5mb3JjZVxuICAgKiB3aGF0IGEgY29sdW1uIGdldHMgZm9yIGZyZWUuIEZpcnN0LXJlc3BvbnNlIGxhdGVuY3kgc2F5cyB3aGV0aGVyIHdlXG4gICAqIGFuc3dlcmVkIGZhc3Q7IHRoaXMgaXMgdGhlIG9ubHkgdGhpbmcgdGhhdCBzYXlzIHdoZXRoZXIgdGhlIGFuc3dlciBoZWxwZWQsXG4gICAqIGFuZCBhIGRlc2sgY2FuIGhpdCBldmVyeSB0YXJnZXQgd2hpbGUgYmVpbmcgYmFkIGF0IHN1cHBvcnQuXG4gICAqL1xuICBzYXRpc2ZhY3Rpb246IGludGVnZXIoJ3NhdGlzZmFjdGlvbicpLFxuICAvKiogT3B0aW9uYWwgZnJlZSB0ZXh0IHdpdGggdGhlIHJhdGluZy4gQ2FwcGVkIGF0IHRoZSByb3V0ZS4gKi9cbiAgc2F0aXNmYWN0aW9uQ29tbWVudDogdGV4dCgnc2F0aXNmYWN0aW9uX2NvbW1lbnQnKSxcbiAgc2F0aXNmYWN0aW9uQXQ6IHRpbWVzdGFtcCgnc2F0aXNmYWN0aW9uX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIC8qKiBTZXQgd2hlbiBzdGF0dXMg4oaSIGBhd2FpdGluZ19jdXN0b21lcmA7IHRoZSBwYXVzZSBhbmNob3IuICovXG4gIGF3YWl0aW5nU2luY2U6IHRpbWVzdGFtcCgnYXdhaXRpbmdfc2luY2UnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgLyoqXG4gICAqIEFjY3VtdWxhdGVkIHNlY29uZHMgc3BlbnQgd2FpdGluZyBvbiB0aGUgY3VzdG9tZXIuXG4gICAqXG4gICAqIEFnZWluZyBzdWJ0cmFjdHMgdGhpcy4gV2l0aG91dCBpdCBhIGNhc2Ugd2UgYW5zd2VyZWQgaW4gYW4gaG91ciwgd2hlcmUgdGhlXG4gICAqIHRlbmFudCByZXBsaWVkIGZvdXIgZGF5cyBsYXRlciwgcmVhZHMgYXMgYSBmb3VyLWRheSBjYXNlIOKAlCBhbmQgdGhlIG1ldHJpY1xuICAgKiBQaGFzZSAyYiBleGlzdHMgdG8gcHJvZHVjZSByZXBvcnRzIGEgbnVtYmVyIG5vIGN1c3RvbWVyIHdpbGwgYWNjZXB0LiBBblxuICAgKiBhY2N1bXVsYXRvciBwbHVzIHRoZSBjdXJyZW50IGFuY2hvciBzdXJ2aXZlcyBhIGNhc2UgYm91bmNpbmcgYmV0d2VlbiBzdGF0ZXNcbiAgICogcmVwZWF0ZWRseSwgd2hpY2ggcmVwbGF5aW5nIHN0YXR1cyBoaXN0b3J5IHdvdWxkIG5vdC5cbiAgICovXG4gIGF3YWl0aW5nVG90YWxTZWNvbmRzOiBpbnRlZ2VyKCdhd2FpdGluZ190b3RhbF9zZWNvbmRzJykuZGVmYXVsdCgwKS5ub3ROdWxsKCksXG5cbiAgY2xvc2VkQXQ6IHRpbWVzdGFtcCgnY2xvc2VkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIGNsb3NlZEJ5OiB0ZXh0KCdjbG9zZWRfYnknKSxcblxuICAvLyBBdWRpdCArIHNvZnQtZGVsZXRlLCBzYW1lIHNoYXBlIGFzIGBtZXNzYWdlc2AuXG4gIGNyZWF0ZWRCeTogdGV4dCgnY3JlYXRlZF9ieScpLmRlZmF1bHQoU1lTVEVNX09SR19JRCkubm90TnVsbCgpLFxuICBjcmVhdGVkQXQ6IHRpbWVzdGFtcCgnY3JlYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG4gIHVwZGF0ZWRCeTogdGV4dCgndXBkYXRlZF9ieScpLmRlZmF1bHQoU1lTVEVNX09SR19JRCkubm90TnVsbCgpLFxuICB1cGRhdGVkQXQ6IHRpbWVzdGFtcCgndXBkYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG4gIGlzQWN0aXZlOiBib29sZWFuKCdpc19hY3RpdmUnKS5kZWZhdWx0KHRydWUpLm5vdE51bGwoKSxcbiAgZGVsZXRlZEF0OiB0aW1lc3RhbXAoJ2RlbGV0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbiAgZGVsZXRlZEJ5OiB0ZXh0KCdkZWxldGVkX2J5JyksXG4gIHB1cmdlQWZ0ZXI6IHRpbWVzdGFtcCgncHVyZ2VfYWZ0ZXInLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbn0sICh0YWJsZSkgPT4gKHtcbiAgLyoqXG4gICAqIFRIRSBxdWV1ZSBxdWVyeTogZXZlcnkgb3BlbiBjYXNlIGFjcm9zcyBBTEwgdGVuYW50cywgb2xkZXN0IGZpcnN0LlxuICAgKlxuICAgKiBUaGUgb25lIHF1ZXJ5IHNoYXBlIHdpdGggbm8gb3JnIHByZWRpY2F0ZSB0byBuYXJyb3cgaXQsIHNvIGl0IGlzIGFsc28gdGhlXG4gICAqIG9ubHkgb25lIHRoYXQgc2NhbnMuIFBhcnRpYWwgYmVjYXVzZSB0aGUgcXVldWUgbmV2ZXIgYXNrcyBhYm91dCBjbG9zZWRcbiAgICogY2FzZXMg4oCUIHdoaWNoIGFyZSBtb3N0IG9mIHRoZSB0YWJsZSB3aXRoaW4gYSBtb250aC4gTWlycm9yc1xuICAgKiBgbWVzc2FnZV9wdXJnZV9pZHhgLCB3aGljaCBpcyBwYXJ0aWFsIGZvciB0aGUgc2FtZSByZWFzb24uXG4gICAqL1xuICBxdWV1ZUlkeDogaW5kZXgoJ3N1cHBvcnRfY2FzZV9xdWV1ZV9pZHgnKVxuICAgIC5vbih0YWJsZS5jcmVhdGVkQXQpXG4gICAgLndoZXJlKHNxbGBzdGF0dXMgSU4gKCdvcGVuJywgJ2F3YWl0aW5nX3N1cHBvcnQnKSBBTkQgZGVsZXRlZF9hdCBJUyBOVUxMYCksXG5cbiAgLyoqXG4gICAqIFRoZSBvbi1jYWxsIHN3ZWVwJ3Mgb25seSBxdWVyeTogcHJlbWl1bSBjYXNlcyB3aG9zZSBmaXJzdC1yZXNwb25zZSB0YXJnZXQgaXNcbiAgICogYXBwcm9hY2hpbmcgd2l0aCBub3RoaW5nIHN0YW1wZWQgeWV0LlxuICAgKlxuICAgKiBQQVJUSUFMIGJlY2F1c2UgdGhlIHRpY2sgcnVucyBldmVyeSBmaXZlIG1pbnV0ZXMgZm9yZXZlciBhbmQgdGhlIHJvd3MgaXRcbiAgICogd2FudHMgYXJlIGEgdGlueSwgc2hyaW5raW5nIGZyYWN0aW9uIG9mIHRoZSB0YWJsZSDigJQgdW5hbnN3ZXJlZCBwcmVtaXVtXG4gICAqIGNhc2VzLiBXaXRob3V0IGl0IGV2ZXJ5IHRpY2sgaXMgYSBzY2FuLCBhbmQgaXQgaXMgdGhlIG9uZSBxdWVyeSB3aXRoIG5vIG9yZ1xuICAgKiBwcmVkaWNhdGUgdG8gbmFycm93IGl0LlxuICAgKlxuICAgKiBgbGV2ZWxgIGFuZCBOT1QgYGlzX3ByZW1pdW1gOiB0aGF0IGNvbHVtbiBsaXZlcyBvbiBzdXBwb3J0X0NPTlRBQ1RTIGFuZFxuICAgKiBtYXJrcyBhbiB1cGdyYWRlZCBjb250YWN0LCB3aGlsZSBhIGNhc2UgZnJlZXplcyB0aGUgb3BlbmluZyBjb250YWN0J3NcbiAgICogZWZmZWN0aXZlIGxldmVsIGF0IG9wZW4uIFRoZSBjYXNlJ3Mgb3duIHByb21pc2UgaXMgaXRzIGBsZXZlbGAsIHNvXG4gICAqIHVwZ3JhZGluZyBhIGNvbnRhY3QgbGF0ZXIgbXVzdCBub3QgbW92ZSBhIGRlYWRsaW5lIGFscmVhZHkgcHVibGlzaGVkIHRvIGFcbiAgICogY3VzdG9tZXIuXG4gICAqL1xuICByZXNwb25zZUR1ZUlkeDogaW5kZXgoJ3N1cHBvcnRfY2FzZV9yZXNwb25zZV9kdWVfaWR4JylcbiAgICAub24odGFibGUucmVzcG9uc2VEdWVBdClcbiAgICAud2hlcmUoc3FsYGxldmVsID0gJ3N1cHBvcnRfcHJlbWl1bScgQU5EIGZpcnN0X3Jlc3BvbnNlX2F0IElTIE5VTEwgQU5EIGRlbGV0ZWRfYXQgSVMgTlVMTGApLFxuXG4gIC8vIEEgdGVuYW50IGxpc3RpbmcgaXRzIG93biBjYXNlcy5cbiAgb3JnU3RhdHVzSWR4OiBpbmRleCgnc3VwcG9ydF9jYXNlX29yZ19zdGF0dXNfaWR4Jykub24odGFibGUub3JnSWQsIHRhYmxlLnN0YXR1cyksXG4gIC8vIFRoZSByb2xsaW5nLXdpbmRvdyBjYXNlIGNvdW50IGJlaGluZCB0aGUgRkFJUi1VU0UgYWxsb3dhbmNlOiBob3cgbWFueSBjYXNlc1xuICAvLyB0aGlzIGFjY291bnQgcmFpc2VkIGluIHRoZSBsYXN0IE4gZGF5cy4gTGVhZGluZyBgb3JnX2lkYCBiZWNhdXNlIHRoZSBjb3VudFxuICAvLyBpcyBhbHdheXMgc2NvcGVkIHRvIGFuIGFjY291bnQgc3VidHJlZSwgdGhlbiBgY3JlYXRlZF9hdGAgc28gdGhlIHdpbmRvdyBpcyBhXG4gIC8vIHJhbmdlIHNjYW4gcmF0aGVyIHRoYW4gYSBmaWx0ZXIgb3ZlciBldmVyeSBjYXNlIHRoZSBvcmcgZXZlciByYWlzZWQuXG4gIG9yZ0NyZWF0ZWRJZHg6IGluZGV4KCdzdXBwb3J0X2Nhc2Vfb3JnX2NyZWF0ZWRfaWR4Jykub24odGFibGUub3JnSWQsIHRhYmxlLmNyZWF0ZWRBdCksXG5cbiAgLy8gXCJXaGF0IGFtIEkgb24gdGhlIGhvb2sgZm9yXCIsIG9uZSBlbmdpbmVlci5cbiAgYXNzaWduZWVJZHg6IGluZGV4KCdzdXBwb3J0X2Nhc2VfYXNzaWduZWRfaWR4JylcbiAgICAub24odGFibGUuYXNzaWduZWRUbywgdGFibGUuc3RhdHVzKVxuICAgIC53aGVyZShzcWxgYXNzaWduZWRfdG8gSVMgTk9UIE5VTExgKSxcblxuICAvLyBcIk15IGNhc2VzXCIgZm9yIGEgY29udGFjdCwgQU5EIHRoZSBsb29rdXAgdGhhdCBmaW5kcyBhIGRlcGFydGluZyBjb250YWN0J3NcbiAgLy8gb3BlbiBjYXNlcyBzbyB0aGV5IGNhbiBiZSByZWFzc2lnbmVkIGluc3RlYWQgb2Ygb3JwaGFuZWQuXG4gIHRlbmFudENvbnRhY3RJZHg6IGluZGV4KCdzdXBwb3J0X2Nhc2VfdGVuYW50X2NvbnRhY3RfaWR4JylcbiAgICAub24odGFibGUudGVuYW50Q29udGFjdCwgdGFibGUuc3RhdHVzKVxuICAgIC53aGVyZShzcWxgdGVuYW50X2NvbnRhY3QgSVMgTk9UIE5VTExgKSxcblxuICAvLyBDYXNlIGlkZW50aXR5LCByZWFjaGVkIGZyb20gYW55IG1lc3NhZ2UgaW4gdGhlIHRocmVhZC5cbiAgdGhyZWFkVXE6IHVuaXF1ZUluZGV4KCdzdXBwb3J0X2Nhc2VfdGhyZWFkX3VxJykub24odGFibGUudGhyZWFkSWQpLFxuXG4gIC8vIFRoZSBjdXN0b21lci1xdW90YWJsZSBudW1iZXIgaXMgdW5pcXVlIHBlciBvcmcsIGVuZm9yY2VkIG5vdCBhc3N1bWVkLlxuICBkaXNwbGF5VXE6IHVuaXF1ZUluZGV4KCdzdXBwb3J0X2Nhc2Vfb3JnX251bWJlcl91cScpXG4gICAgLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS5kaXNwbGF5TnVtYmVyKVxuICAgIC53aGVyZShzcWxgZGVsZXRlZF9hdCBJUyBOVUxMYCksXG59KSk7XG5cbi8qKlxuICogUGVyLW9yZyBhbGxvY2F0b3IgZm9yIGBzdXBwb3J0X2Nhc2VzLmRpc3BsYXlfbnVtYmVyYC5cbiAqXG4gKiBQb3N0Z3JlcyBzZXF1ZW5jZXMgYXJlIGdsb2JhbCBhbmQgY2Fubm90IGJlIHBlci1vcmcgd2l0aG91dCBvbmUgc2VxdWVuY2UgcGVyXG4gKiB0ZW5hbnQsIHNvIHRoZSBjb3VudGVyIGlzIGEgcm93OiBgVVBEQVRFIOKApiBTRVQgbmV4dF9udW1iZXIgPSBuZXh0X251bWJlciArIDFcbiAqIFJFVFVSTklORyBuZXh0X251bWJlcmAgaW5zaWRlIHRoZSBjYXNlLWluc2VydCB0cmFuc2FjdGlvbiwgd2hlcmUgdGhlIHJvdyBsb2NrXG4gKiBzZXJpYWxpc2VzIGNvbmN1cnJlbnQgb3BlbnMgd2l0aGluIG9uZSBvcmcuXG4gKlxuICogQHRhYmxlIHN1cHBvcnRfY2FzZV9jb3VudGVyc1xuICovXG5leHBvcnQgY29uc3Qgc3VwcG9ydENhc2VDb3VudGVyID0gcGdUYWJsZSgnc3VwcG9ydF9jYXNlX2NvdW50ZXJzJywge1xuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5wcmltYXJ5S2V5KCksXG4gIG5leHROdW1iZXI6IGludGVnZXIoJ25leHRfbnVtYmVyJykuZGVmYXVsdCgxKS5ub3ROdWxsKCksXG4gIHVwZGF0ZWRBdDogdGltZXN0YW1wKCd1cGRhdGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkuZGVmYXVsdE5vdygpLm5vdE51bGwoKSxcbn0pO1xuXG4vKipcbiAqIFRoZSBtZW1iZXJzIGF1dGhvcmlzZWQgdG8gb3BlbiBzdXBwb3J0IGNhc2VzIOKAlCB3aGF0IHRoZSBwZXItY29udGFjdCBwcmljZVxuICogYmlsbHMgZm9yLlxuICpcbiAqIFRoZSBDT1VOVCBpcyBjYXBwZWQgYWdhaW5zdCBlZmZlY3RpdmUgYHN1cHBvcnRDb250YWN0c2AgYXQgZGVzaWduYXRpb24gdGltZSxcbiAqIGluIHRoZSBzYW1lIHNoYXBlIHNlYXRzIGFyZSBjYXBwZWQgYXQgaW52aXRlIHRpbWUuIGBzdXBwb3J0Q29udGFjdHNgIGhhcyBhXG4gKiB0aWVyIGJhc2Ugb2YgMCBldmVyeXdoZXJlLCBzbyBhbiBvcmcgd2l0aCBubyBzdXBwb3J0IGFkZC1vbiBoYXMgbm8gY29udGFjdHNcbiAqIGFuZCBjYW5ub3Qgb3BlbiBhIGNhc2U6IHRoZSBwYXl3YWxsIGlzIGEgcXVvdGEgY2hlY2ssIG5vdCBhIGZlYXR1cmUgZmxhZy5cbiAqXG4gKiBAdGFibGUgc3VwcG9ydF9jb250YWN0c1xuICovXG5leHBvcnQgY29uc3Qgc3VwcG9ydENvbnRhY3QgPSBwZ1RhYmxlKCdzdXBwb3J0X2NvbnRhY3RzJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIHVzZXJJZDogdGV4dCgndXNlcl9pZCcpLm5vdE51bGwoKSxcbiAgLy8gV2hvIG5vbWluYXRlZCB0aGVtLiBBdWRpdC13b3J0aHk6IGEgY29udGFjdCBpcyBhIHBhaWQsIHByaXZpbGVnZWQgc2xvdC5cbiAgZGVzaWduYXRlZEJ5OiB0ZXh0KCdkZXNpZ25hdGVkX2J5Jykubm90TnVsbCgpLFxuICBkZXNpZ25hdGVkQXQ6IHRpbWVzdGFtcCgnZGVzaWduYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgY29udGFjdCBpcyBVUEdSQURFRCB0byBwcmVtaXVtIOKAlCAyNMOXNyBjb3ZlcmFnZSwgdGhlIDgtaG91clxuICAgKiBhbnktZGF5IHRhcmdldCwgYW5kIHRoZSBvbmx5IGNvbnRhY3RzIHdobyBtYXkgZGVjbGFyZSBgdXJnZW50YCBzZXZlcml0eS5cbiAgICpcbiAgICogQSBjb2x1bW4gb24gdGhlIGNvbnRhY3QgcmF0aGVyIHRoYW4gYSBsZXZlbCBvbiB0aGUgb3JnLCBiZWNhdXNlIHRoYXQgaXMgd2hhdFxuICAgKiB0aGUgdXBncmFkZSBtb2RlbCBtZWFuczogYW4gYWNjb3VudCBob2xkcyBvbmUgQkFTRUxJTkUgbGV2ZWwgY292ZXJpbmcgZXZlcnlcbiAgICogY29udGFjdCBhbmQgdXBncmFkZXMgYSBzdWJzZXQuIFdpdGhvdXQgdGhpcyB0aGUgYHN1cHBvcnRQcmVtaXVtQ29udGFjdHNgIGNhcFxuICAgKiB3b3VsZCBncmFudCBhIHF1b3RhIG92ZXIgbm90aGluZyDigJQgdGhlcmUgd291bGQgYmUgbm8gd2F5IGZvciBhbnkgY29udGFjdCB0b1xuICAgKiBhY3R1YWxseSBiZSBwcmVtaXVtLCBhbmQgdGhlIGNhc2Utb3BlbiBwYXRoIHdvdWxkIGhhdmUgbm90aGluZyB0byByZWFkLlxuICAgKlxuICAgKiBUaGUgY2FzZSBmcmVlemVzIHRoZSBPUEVOSU5HIENPTlRBQ1QncyBlZmZlY3RpdmUgbGV2ZWwgYXQgb3BlblxuICAgKiAoYHN1cHBvcnRfY2FzZS5sZXZlbGApLCBzbyBmbGlwcGluZyB0aGlzIGxhdGVyIG5ldmVyIGNoYW5nZXMgdGhlIHByb21pc2Ugb25cbiAgICogYSBjYXNlIGFscmVhZHkgcmFpc2VkLlxuICAgKi9cbiAgaXNQcmVtaXVtOiBib29sZWFuKCdpc19wcmVtaXVtJykuZGVmYXVsdChmYWxzZSkubm90TnVsbCgpLFxuICBpc0FjdGl2ZTogYm9vbGVhbignaXNfYWN0aXZlJykuZGVmYXVsdCh0cnVlKS5ub3ROdWxsKCksXG4gIHJldm9rZWRBdDogdGltZXN0YW1wKCdyZXZva2VkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIHJldm9rZWRCeTogdGV4dCgncmV2b2tlZF9ieScpLFxufSwgKHRhYmxlKSA9PiAoe1xuICAvLyBPbmUgbGl2ZSBkZXNpZ25hdGlvbiBwZXIgKG9yZywgdXNlcikuIFBhcnRpYWwgc28gYSByZXZva2VkIHJvdyBkb2VzIG5vdFxuICAvLyBibG9jayByZS1kZXNpZ25hdGluZyB0aGUgc2FtZSBwZXJzb24gbGF0ZXIuXG4gIG9yZ1VzZXJVcTogdW5pcXVlSW5kZXgoJ3N1cHBvcnRfY29udGFjdF9vcmdfdXNlcl91cScpXG4gICAgLm9uKHRhYmxlLm9yZ0lkLCB0YWJsZS51c2VySWQpXG4gICAgLndoZXJlKHNxbGBpc19hY3RpdmUgPSB0cnVlYCksXG4gIC8vIENvdW50aW5nIGFuIG9yZydzIGxpdmUgY29udGFjdHMgYWdhaW5zdCBpdHMgY2FwLCBhbmQgbGlzdGluZyB0aGVtIGZvciB0aGVcbiAgLy8gdGVuYW50LXNpZGUgb3duZXIgcGlja2VyLlxuICBvcmdBY3RpdmVJZHg6IGluZGV4KCdzdXBwb3J0X2NvbnRhY3Rfb3JnX2FjdGl2ZV9pZHgnKS5vbih0YWJsZS5vcmdJZCwgdGFibGUuaXNBY3RpdmUpLFxuICAvLyBUaGUgcHJlbWl1bSBTVUJTRVQsIGNvdW50ZWQgYWdhaW5zdCBgc3VwcG9ydFByZW1pdW1Db250YWN0c2Agb24gZXZlcnlcbiAgLy8gdXBncmFkZS4gUGFydGlhbCBvbiBib3RoIGZsYWdzIGJlY2F1c2UgdGhhdCBpcyB0aGUgb25seSBxdWVzdGlvbiBhc2tlZCBvZlxuICAvLyBpdDogaG93IG1hbnkgbGl2ZSBjb250YWN0cyBpbiB0aGlzIHNjb3BlIGFyZSB1cGdyYWRlZC5cbiAgb3JnUHJlbWl1bUlkeDogaW5kZXgoJ3N1cHBvcnRfY29udGFjdF9vcmdfcHJlbWl1bV9pZHgnKVxuICAgIC5vbih0YWJsZS5vcmdJZCwgdGFibGUudXNlcklkKVxuICAgIC53aGVyZShzcWxgaXNfYWN0aXZlID0gdHJ1ZSBBTkQgaXNfcHJlbWl1bSA9IHRydWVgKSxcbn0pKTtcblxuLyoqXG4gKiBDYW5uZWQgc3RhZmYgcmVwbGllcyDigJQgYSBzaGFyZWQgbGlicmFyeSBvZiBhbnN3ZXJzIHRoZSBkZXNrIHJldXNlcy5cbiAqXG4gKiBTWVNURU0tV0lERSwgbm90IHBlci10ZW5hbnQsIGFuZCBkZWxpYmVyYXRlbHkgc286IHRoZXNlIGFyZSB0aGUgdmVuZG9yJ3Mgb3duXG4gKiB3b3JkaW5nIGZvciByZWN1cnJpbmcgcXVlc3Rpb25zLCBhdXRob3JlZCBvbmNlIGFuZCB1c2VkIGFjcm9zcyBldmVyeVxuICogY3VzdG9tZXIuIFRoZXJlIGlzIG5vIGBvcmdfaWRgIGJlY2F1c2Ugc2NvcGluZyB0aGVtIHBlciB0ZW5hbnQgd291bGQgYmUgdGhlXG4gKiBvcHBvc2l0ZSBvZiB0aGUgcG9pbnQg4oCUIHRoZSB2YWx1ZSBpcyB0aGF0IHRoZSBhbnN3ZXIgdG8gXCJob3cgZG8gSSByb3RhdGUgYVxuICogc2VydmljZSBrZXlcIiBpcyB3cml0dGVuIHdlbGwgb25jZSByYXRoZXIgdGhhbiByZXR5cGVkIGJhZGx5IGZpZnR5IHRpbWVzLlxuICpcbiAqIFRoYXQgYWxzbyBtZWFucyBSTFMgZG9lcyBub3QgYXBwbHk6IGV2ZXJ5IHJvdyBpcyB2aXNpYmxlIHRvIHRoZSBzdGFmZiB3aG8gY2FuXG4gKiByZWFjaCB0aGUgcXVldWUsIGFuZCB0byBub2JvZHkgZWxzZS4gVGhlIHJvdXRlcyBhcmUgc3lzdGVtLWFkbWluIGdhdGVkIG9uXG4gKiBib3RoIHJlYWQgYW5kIHdyaXRlIGZvciBleGFjdGx5IHRoYXQgcmVhc29uLlxuICpcbiAqIFNvZnQtZGVsZXRlZCByYXRoZXIgdGhhbiByZW1vdmVkLCBiZWNhdXNlIGEgcmV0aXJlZCB0ZW1wbGF0ZSBpcyBzdGlsbCB0aGVcbiAqIGV4cGxhbmF0aW9uIG9mIHdoYXQgYSBwYXN0IHJlcGx5IHNhaWQuXG4gKlxuICogQHRhYmxlIHN1cHBvcnRfY2FubmVkX3Jlc3BvbnNlc1xuICovXG5leHBvcnQgY29uc3Qgc3VwcG9ydENhbm5lZFJlc3BvbnNlID0gcGdUYWJsZSgnc3VwcG9ydF9jYW5uZWRfcmVzcG9uc2VzJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICAvKiogU2hvcnQgbGFiZWwgdGhlIHBpY2tlciBsaXN0cy4gKi9cbiAgdGl0bGU6IHZhcmNoYXIoJ3RpdGxlJywgeyBsZW5ndGg6IDIwMCB9KS5ub3ROdWxsKCksXG4gIGJvZHk6IHRleHQoJ2JvZHknKS5ub3ROdWxsKCksXG4gIGNyZWF0ZWRCeTogdGV4dCgnY3JlYXRlZF9ieScpLm5vdE51bGwoKSxcbiAgY3JlYXRlZEF0OiB0aW1lc3RhbXAoJ2NyZWF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxuICB1cGRhdGVkQnk6IHRleHQoJ3VwZGF0ZWRfYnknKS5ub3ROdWxsKCksXG4gIHVwZGF0ZWRBdDogdGltZXN0YW1wKCd1cGRhdGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkuZGVmYXVsdE5vdygpLm5vdE51bGwoKSxcbiAgaXNBY3RpdmU6IGJvb2xlYW4oJ2lzX2FjdGl2ZScpLmRlZmF1bHQodHJ1ZSkubm90TnVsbCgpLFxufSwgKHRhYmxlKSA9PiAoe1xuICAvLyBUaGUgcGlja2VyJ3Mgb25seSBxdWVyeTogbGl2ZSB0ZW1wbGF0ZXMsIGFscGhhYmV0aWNhbC5cbiAgYWN0aXZlVGl0bGVJZHg6IGluZGV4KCdzdXBwb3J0X2Nhbm5lZF9hY3RpdmVfaWR4Jykub24odGFibGUuaXNBY3RpdmUsIHRhYmxlLnRpdGxlKSxcbn0pKTtcblxuLyoqXG4gKiBDU0FUOiB0aGUgY3VzdG9tZXIncyB2ZXJkaWN0IG9uIGEgY2xvc2VkIGNhc2UuXG4gKlxuICogQSBDT0xVTU4gU0VUIG9uIHRoZSBjYXNlIHJhdGhlciB0aGFuIGl0cyBvd24gdGFibGUsIHVubGlrZSBub3Rlcy4gVGhlIHJlYXNvblxuICogaXMgY2FyZGluYWxpdHksIG5vdCBjb252ZW5pZW5jZTogYSBjYXNlIGhhcyBtYW55IG5vdGVzIGFuZCBleGFjdGx5IG9uZVxuICogc2F0aXNmYWN0aW9uIHJhdGluZywgc28gYSB0YWJsZSB3b3VsZCBidXkgYW4gZXh0cmEgam9pbiBhbmQgYSB1bmlxdWVuZXNzXG4gKiBjb25zdHJhaW50IHRvIGVuZm9yY2Ugd2hhdCBhIGNvbHVtbiBnZXRzIGZvciBmcmVlLlxuICpcbiAqIFdoeSBpdCBtYXR0ZXJzIG1vcmUgaGVyZSB0aGFuIGluIG1vc3QgcHJvZHVjdHM6IHRoZSB0aGluZyBiZWluZyBTT0xEIGlzIGFcbiAqIHJlc3BvbnNlIHRpbWUsIGFuZCBmaXJzdC1yZXNwb25zZSBsYXRlbmN5IG9ubHkgbWVhc3VyZXMgd2hldGhlciB3ZSBhbnN3ZXJlZFxuICogZmFzdCDigJQgbm90IHdoZXRoZXIgdGhlIGFuc3dlciB3YXMgYW55IGdvb2QuIEEgZGVzayBjYW4gaGl0IGV2ZXJ5IHRhcmdldCBhbmRcbiAqIHN0aWxsIGJlIGJhZCBhdCBzdXBwb3J0LCBhbmQgd2l0aG91dCB0aGlzIG5vdGhpbmcgaW4gdGhlIHN5c3RlbSB3b3VsZCBub3RpY2UuXG4gKlxuICogQHRhYmxlIHN1cHBvcnRfY2FzZXMgKGNvbHVtbnMpXG4gKi9cblxuLyoqXG4gKiBTdGFmZi1vbmx5IG5vdGVzIG9uIGEgY2FzZS5cbiAqXG4gKiBBIFNFUEFSQVRFIFRBQkxFIHJhdGhlciB0aGFuIGEgZmxhZyBvbiBgbWVzc2FnZXNgLCBhbmQgdGhlIHJlYXNvbiBpcyB0aGVcbiAqIGZhaWx1cmUgbW9kZTogYG1lc3NhZ2VzYCBpcyByZWFkIHRocm91Z2ggb25lIHNoYXJlZCB2aXNpYmlsaXR5IHByZWRpY2F0ZVxuICogKGBidWlsZE1lc3NhZ2VDb25kaXRpb25zYCksIHNvIGEgZmxhZyBtZWFucyBldmVyeSByZWFkIHBhdGggdGhhdCBmb3JnZXRzIHRoZVxuICogZXh0cmEgY29uZGl0aW9uIGxlYWtzIGFuIGludGVybmFsIG5vdGUgdG8gdGhlIHRlbmFudC4gQSBzZXBhcmF0ZSB0YWJsZSBjYW5ub3RcbiAqIGxlYWsgYnkgb21pc3Npb24g4oCUIGl0IGhhcyB0byBiZSBqb2luZWQgZGVsaWJlcmF0ZWx5LlxuICpcbiAqIEB0YWJsZSBzdXBwb3J0X2Nhc2Vfbm90ZXNcbiAqL1xuZXhwb3J0IGNvbnN0IHN1cHBvcnRDYXNlTm90ZSA9IHBnVGFibGUoJ3N1cHBvcnRfY2FzZV9ub3RlcycsIHtcbiAgaWQ6IHV1aWQoJ2lkJykucHJpbWFyeUtleSgpLmRlZmF1bHRSYW5kb20oKSxcbiAgY2FzZUlkOiB1dWlkKCdjYXNlX2lkJykubm90TnVsbCgpLFxuICAvLyBEZW5vcm1hbGlzZWQgc28gYSBub3RlIGNhbiBuZXZlciBiZSBzZXJ2ZWQgd2l0aG91dCBpdHMgdGVuYW50IHNjb3BlLlxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG4gIGNvbnRlbnQ6IHRleHQoJ2NvbnRlbnQnKS5ub3ROdWxsKCksXG4gIGNyZWF0ZWRCeTogdGV4dCgnY3JlYXRlZF9ieScpLm5vdE51bGwoKSxcbiAgY3JlYXRlZEF0OiB0aW1lc3RhbXAoJ2NyZWF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KS5kZWZhdWx0Tm93KCkubm90TnVsbCgpLFxuICBpc0FjdGl2ZTogYm9vbGVhbignaXNfYWN0aXZlJykuZGVmYXVsdCh0cnVlKS5ub3ROdWxsKCksXG4gIGRlbGV0ZWRBdDogdGltZXN0YW1wKCdkZWxldGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIGRlbGV0ZWRCeTogdGV4dCgnZGVsZXRlZF9ieScpLFxufSwgKHRhYmxlKSA9PiAoe1xuICBjYXNlSWR4OiBpbmRleCgnc3VwcG9ydF9jYXNlX25vdGVfY2FzZV9pZHgnKS5vbih0YWJsZS5jYXNlSWQsIHRhYmxlLmlzQWN0aXZlKSxcbn0pKTtcblxuLyoqIFR5cGVTY3JpcHQgdHlwZXMgcmVwcmVzZW50aW5nIGRhdGFiYXNlIHJvd3MgKi9cbmV4cG9ydCB0eXBlIFN1cHBvcnRDYXNlID0gdHlwZW9mIHN1cHBvcnRDYXNlLiRpbmZlclNlbGVjdDtcbmV4cG9ydCB0eXBlIFN1cHBvcnRDYXNlSW5zZXJ0ID0gdHlwZW9mIHN1cHBvcnRDYXNlLiRpbmZlckluc2VydDtcbmV4cG9ydCB0eXBlIFN1cHBvcnRDYXNlVXBkYXRlID0gUGFydGlhbDxPbWl0PFN1cHBvcnRDYXNlSW5zZXJ0LCAnaWQnIHwgJ2NyZWF0ZWRBdCcgfCAnY3JlYXRlZEJ5JyB8ICdvcmdJZCcgfCAndGhyZWFkSWQnIHwgJ2Rpc3BsYXlOdW1iZXInPj47XG5cbmV4cG9ydCB0eXBlIFN1cHBvcnRDYXNlQ291bnRlciA9IHR5cGVvZiBzdXBwb3J0Q2FzZUNvdW50ZXIuJGluZmVyU2VsZWN0O1xuXG5leHBvcnQgdHlwZSBTdXBwb3J0Q29udGFjdCA9IHR5cGVvZiBzdXBwb3J0Q29udGFjdC4kaW5mZXJTZWxlY3Q7XG5leHBvcnQgdHlwZSBTdXBwb3J0Q29udGFjdEluc2VydCA9IHR5cGVvZiBzdXBwb3J0Q29udGFjdC4kaW5mZXJJbnNlcnQ7XG5cbmV4cG9ydCB0eXBlIFN1cHBvcnRDYXNlTm90ZSA9IHR5cGVvZiBzdXBwb3J0Q2FzZU5vdGUuJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgU3VwcG9ydENhc2VOb3RlSW5zZXJ0ID0gdHlwZW9mIHN1cHBvcnRDYXNlTm90ZS4kaW5mZXJJbnNlcnQ7XG4iXX0=
@@ -64,11 +64,13 @@ export interface TenantContext {
64
64
  * the AsyncLocalStorage store — the store is per-request, so this cannot leak
65
65
  * between requests.
66
66
  *
67
- * SCOPE: this covers reads AFTER a write IN THE SAME REQUEST. It does NOT
68
- * cover the next request (POST then a page reload issuing GET). That needs
69
- * shared state — see the cross-request section of
70
- * docs/plans/postgres-read-write-split.md — and must be settled before call
71
- * sites are migrated in bulk.
67
+ * SCOPE: this flag covers reads AFTER a write IN THE SAME REQUEST. The
68
+ * next-request case (POST, then a page reload issuing GET) needs shared state
69
+ * and is handled by api-server's `write-pin.ts`, which remembers in Redis
70
+ * that an org wrote recently and PRE-SETS this same flag on the next
71
+ * request's context — one mechanism and one code path rather than two. It
72
+ * fails closed (no Redis, or an unreachable one, routes reads to the primary)
73
+ * and short-circuits entirely when no read replica is configured.
72
74
  */
73
75
  mayHaveWritten?: boolean;
74
76
  }
@@ -247,4 +247,4 @@ export async function withTenantTxRead(fn) {
247
247
  return fn(tx);
248
248
  });
249
249
  }
250
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW5jeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhYmFzZS90ZW5hbmN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBRUgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDckQsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDL0UsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBbUIsTUFBTSxlQUFlLENBQUM7QUFFNUUsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFlOUMsU0FBUyxjQUFjO0lBQ3JCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFDeEQsSUFBSSxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsS0FBSyxNQUFNLElBQUksR0FBRyxLQUFLLFFBQVE7UUFBRSxPQUFPLEdBQUcsQ0FBQztJQUN2RSx1RUFBdUU7SUFDdkUsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0FBQ25FLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMscUJBQXFCO0lBQzVCLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSxNQUFNLENBQUMs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QUNkLEdBQUcsQ0FBQSxtQ0FBbUMsS0FBSywwQ0FBMEMsWUFBWSw0Q0FBNEMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FDakwsQ0FBQztRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxFQUFFLENBQUMsT0FBTyxDQUNkLEdBQUcsQ0FBQSxtQ0FBbUMsS0FBSywwQ0FBMEMsWUFBWSxTQUFTLENBQzNHLENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDaEIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogVGVuYW50LWNvbnRleHQgcGx1bWJpbmcgZm9yIFBvc3RncmVzIHJvdy1sZXZlbCBzZWN1cml0eS5cbiAqXG4gKiBCYWNrZ3JvdW5kOiBwb3N0Z3Jlcy1pbml0LnNxbCBpbnN0YWxscyBSTFMgcG9saWNpZXMgb24gZXZlcnkgdXNlci1kYXRhXG4gKiB0YWJsZSB0aGF0IGNvbnN1bHQgdHdvIHNlc3Npb24gR1VDcyDigJQgYGFwcC5vcmdfaWRgIGFuZCBgYXBwLmlzX3N5c2FkbWluYC5cbiAqIEV2ZXJ5IHRlbmFudCB0YWJsZSBpcyBgRk9SQ0UgUk9XIExFVkVMIFNFQ1VSSVRZYCwgc28gdGhlIHBvbGljaWVzIGVuZm9yY2VcbiAqIGV2ZW4gZm9yIHRoZSAob3duaW5nKSBjb25uZWN0aW9uIHVzZXIg4oCUIGEgcXVlcnkgYWdhaW5zdCBvbmUgbXVzdCBydW4gaW5zaWRlIGFcbiAqIHRyYW5zYWN0aW9uIHRoYXQgaGFzIFNFVCBMT0NBTCdkIGJvdGggR1VDcyBvciBpdCByZXR1cm5zIHplcm8gcm93cyBmb3JcbiAqIG5vbi1zeXNhZG1pbnMgKGFuZCBtYXkgZmFpbCB0byB3cml0ZSBmb3IgYW55IGNhbGxlcikuIFRoZSBjcm9zcy1vcmcgcGx1Z2luXG4gKiBlY29zeXN0ZW0gY2F0YWxvZyB0YWJsZXMgY2FycnkgYSBwZXJtaXNzaXZlIGFwcC1yb2xlIHBvbGljeSBpbnN0ZWFkLlxuICpcbiAqIFRoaXMgbW9kdWxlIGlzIHRoZSBzZWFtLlxuICpcbiAqICAgMS4gYHRlbmFudENvbnRleHRgIChBc3luY0xvY2FsU3RvcmFnZSkgY2FycmllcyBge29yZ0lkLCBpc1N1cGVyQWRtaW59YFxuICogICAgICBkb3duIHRoZSBjYWxsIGNoYWluIHdpdGhvdXQgcHJvcC1kcmlsbGluZy4gU2V0IG9uY2UgYXQgdGhlIHJlcXVlc3RcbiAqICAgICAgYm91bmRhcnk7IHJlYWRhYmxlIGZyb20gYW55d2hlcmUuXG4gKlxuICogICAyLiBgd2l0aFRlbmFudFR4KGZuKWAgb3BlbnMgYSB0cmFuc2FjdGlvbiwgU0VUIExPQ0FMJ3MgYm90aCBHVUNzIGZyb21cbiAqICAgICAgdGhlIHN1cnJvdW5kaW5nIGNvbnRleHQsIHRoZW4gaW52b2tlcyBgZm4odHgpYC4gU2VydmljZXMgbWlncmF0ZSBvbmVcbiAqICAgICAgYXQgYSB0aW1lIGJ5IHdyYXBwaW5nIHRoZWlyIGV4aXN0aW5nIGRyaXp6bGUgY2FsbHMgaW4gdGhpcyBoZWxwZXIg4oCUXG4gKiAgICAgIGBkYi5zZWxlY3QoKS5mcm9tKC4uLilgIGJlY29tZXMgYHdpdGhUZW5hbnRUeCh0eCA9PiB0eC5zZWxlY3QoKS5mcm9tKC4uLikpYC5cbiAqXG4gKiAgIDMuIGBydW5XaXRoVGVuYW50Q29udGV4dChjdHgsIGZuKWAgaXMgdGhlIEV4cHJlc3MtbWlkZGxld2FyZS1zaWRlXG4gKiAgICAgIGJvb2tlbmQgdGhhdCBlc3RhYmxpc2hlcyB0aGUgQXN5bmNMb2NhbFN0b3JhZ2Ugc2NvcGUgZm9yIHRoZSByZXF1ZXN0LlxuICpcbiAqIE1pZ3JhdGlvbiBvcmRlcjpcbiAqICAgLSBGaXJzdCBhZG9wdGVyczogbmV3bHktd3JpdHRlbiBzZXJ2aWNlcyAoZGFzaGJvYXJkLCBhbGVydC1kZXN0aW5hdGlvbilcbiAqICAgICB3aGVyZSB0aGUgY2hhbmdlIGlzIG1lY2hhbmljYWwuXG4gKiAgIC0gVGhlbiBoaWdoLXdyaXRlIHNlcnZpY2VzIChwbHVnaW4sIHBpcGVsaW5lKS4gU29hayBlYWNoIG9uZSBiZWZvcmVcbiAqICAgICBmbGlwcGluZyB0aGUgdW5kZXJseWluZyB0YWJsZSB0byBGT1JDRS5cbiAqICAgLSBhZG1pbl9hdWRpdF9sb2cgdXNlcyBhIHN5c2FkbWluLW9ubHkgcG9saWN5IOKAlCBzeXNhZG1pbiBwYXRocyBtdXN0XG4gKiAgICAgYWxzbyBzZXQgYGFwcC5pc19zeXNhZG1pbiA9ICd0cnVlJ2Agb3IgdGhleSdsbCBsb3NlIGFjY2VzcyB0byBpdC5cbiAqL1xuXG5pbXBvcnQgeyBBc3luY0xvY2FsU3RvcmFnZSB9IGZyb20gJ25vZGU6YXN5bmNfaG9va3MnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCBlbWl0Q291bnRlciwgZW52SW50IH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgc3FsIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgZGIgfSBmcm9tICcuL3Bvc3RncmVzLWNvbm5lY3Rpb24uanMnO1xuaW1wb3J0IHsgZ2V0UmVhZERiLCBnZXRSZWFkUG9vbCB9IGZyb20gJy4vcmVhZC1jb25uZWN0aW9uLmpzJztcbmltcG9ydCB7IGxhZ1ZlcmRpY3QsIG1heWJlU2FtcGxlTGFnLCB0eXBlIExhZ1ZlcmRpY3QgfSBmcm9tICcuL3JlYWQtbGFnLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCd0ZW5hbnQtY29udGV4dCcpO1xuXG4vKipcbiAqIEJlaGF2aW9yIHdoZW4gYHdpdGhUZW5hbnRUeGAgaXMgaW52b2tlZCBvdXRzaWRlIGFueSBgcnVuV2l0aFRlbmFudENvbnRleHRgXG4gKiBzY29wZS4gVGhlIGVmZmVjdGl2ZSBkZWZhdWx0IGlzIGZhaWwtZmFzdCAoJ3N0cmljdCcpIGluIHByb2R1Y3Rpb24gc28gYVxuICogbWlzc2luZyB0ZW5hbnQgc2NvcGUgc3VyZmFjZXMgYXQgdGhlIGJhZCBjYWxsIHNpdGUgaW5zdGVhZCBvZiBzaWxlbnRseVxuICogcnVubmluZyB3aXRoIGVtcHR5IFJMUyBHVUNzOyBvdXRzaWRlIHByb2R1Y3Rpb24gaXQgZGVmYXVsdHMgdG8gJ3dhcm4nIHNvXG4gKiB1bi1hdWRpdGVkIGRldi90ZXN0IHBhdGhzIGtlZXAgd29ya2luZyBidXQgbG9nIGFuIGFjdGlvbmFibGUgdHJhY2UuIEFuXG4gKiBleHBsaWNpdCBSTFNfQ09OVEVYVF9NT0RFIGVudiBvdmVycmlkZSBhbHdheXMgd2lucy5cbiAqXG4gKiAnc2lsZW50JyBpcyBrZXB0IGZvciB0ZXN0cyBhbmQgc2NyaXB0cyB0aGF0IGludGVudGlvbmFsbHkgZW50ZXIgdGhlIERCXG4gKiB3aXRob3V0IGNvbnRleHQgKGUuZy4gaW50ZWdyYXRpb24gdGVzdCBzZXR1cCB0aGF0IHJ1bnMgYXMgdGhlIGNvbm5lY3Rpb25cbiAqIG93bmVyIGJlZm9yZSBhbnkgdGVuYW50IGlzIHByb3Zpc2lvbmVkKS5cbiAqL1xudHlwZSBDb250ZXh0TW9kZSA9ICdzaWxlbnQnIHwgJ3dhcm4nIHwgJ3N0cmljdCc7XG5mdW5jdGlvbiBnZXRDb250ZXh0TW9kZSgpOiBDb250ZXh0TW9kZSB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LlJMU19DT05URVhUX01PREU/LnRvTG93ZXJDYXNlKCk7XG4gIGlmIChyYXcgPT09ICdzaWxlbnQnIHx8IHJhdyA9PT0gJ3dhcm4nIHx8IHJhdyA9PT0gJ3N0cmljdCcpIHJldHVybiByYXc7XG4gIC8vIE5vIGV4cGxpY2l0IG92ZXJyaWRlOiBmYWlsLWZhc3QgaW4gcHJvZHVjdGlvbiwgd2FybiBldmVyeXdoZXJlIGVsc2UuXG4gIHJldHVybiBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nID8gJ3N0cmljdCcgOiAnd2Fybic7XG59XG5cbi8qKlxuICogUGVyLXN0YXRlbWVudCBzZXJ2ZXItc2lkZSB0aW1lb3V0IChtcykgYXBwbGllZCBJTlNJREUgZXZlcnkgYHdpdGhUZW5hbnRUeGBcbiAqIHRyYW5zYWN0aW9uLCBuZXh0IHRvIHRoZSBSTFMgR1VDcy4gYHdpdGhUZW5hbnRUeGAgaXMgdGhlIHJlYWwgcXVlcnkgcGF0aCBmb3JcbiAqIGFsbCBSTFMvQ1JVRCByZWFkcyBhbmQgd3JpdGVzLCBzbyB0aGlzIGlzIHdoZXJlIHRoZSBEQi1zaWRlIGd1YXJkIGJlbG9uZ3MgKHRoZVxuICogb2xkIGBDb25uZWN0aW9uLnRyYW5zYWN0aW9uYCB3cmFwcGVyIHRoYXQgc2V0IGl0IGlzIGRlYWQg4oCUIHNlZVxuICogcG9zdGdyZXMtY29ubmVjdGlvbi50cykuIEJvdW5kcyBhIHJ1bmF3YXkgcXVlcnkgc28gaXQgY2FuJ3QgaG9sZCBhIHBvb2xlZFxuICogY29ubmVjdGlvbiBvcGVuIGluZGVmaW5pdGVseS4gRW52LWNvbmZpZ3VyYWJsZSB2aWEgYERCX1NUQVRFTUVOVF9USU1FT1VUX01TYFxuICogKGRlZmF1bHQgMzBzKTsgc2V0IHRvIGAwYCB0byBkaXNhYmxlIHRoZSB0aW1lb3V0LlxuICovXG5mdW5jdGlvbiBnZXRTdGF0ZW1lbnRUaW1lb3V0TXMoKTogbnVtYmVyIHtcbiAgY29uc3QgbXMgPSBlbnZJbnQoJ0RCX1NUQVRFTUVOVF9USU1FT1VUX01TJywgMzBfMDAwKTtcbiAgcmV0dXJuIG1zID49IDAgPyBtcyA6IDMwXzAwMDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5hbnRDb250ZXh0IHtcbiAgLyoqIENhbGxlcidzIG9yZy4gVW5kZWZpbmVkIGZvciB1bi1hdXRoZW50aWNhdGVkIC8gc3lzdGVtIGpvYnMuICovXG4gIG9yZ0lkPzogc3RyaW5nO1xuICAvKiogQ2FsbGVyJ3MgdXNlciBpZC4gTm90IHVzZWQgZm9yIFJMUyDigJQgUG9zdGdyZXMgcG9saWNpZXMgYXJlIG9yZy1ncmFpbmVkLFxuICAgKiAgd2l0aCBubyBwZXItdXNlciBzZXNzaW9uIEdVQyDigJQgYnV0IGNhcnJpZWQgc28gYXBwLWxheWVyIHByZWRpY2F0ZXMgd2l0aCBhXG4gICAqICBQRVItVVNFUiBydW5nIChwaXBlbGluZSB0ZW1wbGF0ZXMnIGBwcml2YXRlYCB2aXNpYmlsaXR5KSBjYW4gcmVzb2x2ZSBcIndob1xuICAgKiAgaXMgYXNraW5nXCIgb24gcGF0aHMgdGhhdCBoYXZlIG5vd2hlcmUgdG8gcGFzcyBpdCwgbm90YWJseSBDcnVkU2VydmljZSdzXG4gICAqICBgd3JpdGVDb25kaXRpb25zYC4gQWJzZW50IGZvciBzeXN0ZW0gam9icywgd2hpY2ggaXMgdGhlIGZhaWwtY2xvc2VkIGNhc2U6XG4gICAqICBubyB2aWV3ZXIg4oeSIG5vIHByaXZhdGUgcm93cy4gKi9cbiAgdXNlcklkPzogc3RyaW5nO1xuICAvKiogVHJ1ZSB3aGVuIHRoZSBjYWxsZXIgaXMgYSBzeXNhZG1pbiAoc3lzdGVtLW9yZyBhZG1pbikuIEJ5cGFzc2VzIFJMU1xuICAgKiAgcG9saWNpZXMgdmlhIHRoZSBzeXNhZG1pbi1ieXBhc3MgYnJhbmNoIGluIGBjdXJyZW50X2lzX3N5c2FkbWluKClgLiAqL1xuICBpc1N1cGVyQWRtaW46IGJvb2xlYW47XG4gIC8qKiBPcmcg4oaSIHRlYW0gaGllcmFyY2h5OiB0aGUgY2FsbGVyJ3MgYWN0aXZlLW9yZyBwYXJlbnQgKHByZXNlbnQgb25seSB3aGVuIHRoZVxuICAgKiAgYWN0aXZlIG9yZyBpcyBhIHRlYW0pLiBOb3QgdXNlZCBmb3IgUkxTOyBjYXJyaWVkIHNvIGRvd25zdHJlYW0gc2lkZS1lZmZlY3RzXG4gICAqICAoZS5nLiBlbnRpdHktZXZlbnQgY29tcGxpYW5jZSBldmFsKSBjYW4gaG9ub3IgcGFyZW50IGBwcm9wYWdhdGVUb0NoaWxkcmVuYFxuICAgKiAgcnVsZXMgd2l0aG91dCBhIHJlcXVlc3QgaW4gc2NvcGUuICovXG4gIHBhcmVudE9yZ0lkPzogc3RyaW5nO1xuICAvKipcbiAgICogU2V0IG9uY2UgdGhpcyByZXF1ZXN0IGhhcyBvcGVuZWQgYSBQUklNQVJZIHRyYW5zYWN0aW9uLCBpLmUuIG1heSBoYXZlXG4gICAqIHdyaXR0ZW4uIFN1YnNlcXVlbnQgYHdpdGhUZW5hbnRUeFJlYWRgIGNhbGxzIGluIHRoZSBzYW1lIHJlcXVlc3QgdGhlbiBnbyB0b1xuICAgKiB0aGUgcHJpbWFyeSB0b28sIHNvIGEgaGFuZGxlciBjYW5ub3QgcmVhZCBpdHMgb3duIHdyaXRlIG9mZiBhIHJlcGxpY2EgdGhhdFxuICAgKiBoYXMgbm90IHJlcGxheWVkIGl0IHlldC5cbiAgICpcbiAgICogRGVsaWJlcmF0ZWx5IHNldCBieSBgd2l0aFRlbmFudFR4YCByYXRoZXIgdGhhbiBieSB3cml0ZSBjYWxsIHNpdGVzOiB0aGF0XG4gICAqIHBhdGggaXMgdGhlIG9uZSB0aGF0IGNhbiB3cml0ZSwgaXQgbmVlZHMgbm8gcGVyLWNhbGwtc2l0ZSBkaXNjaXBsaW5lLCBhbmRcbiAgICogYmVpbmcgd3JvbmcgaW4gdGhpcyBkaXJlY3Rpb24gb25seSBjb3N0cyBhIHJlcGxpY2EgaGl0LiBNdXRhdGVkIGluIHBsYWNlIG9uXG4gICAqIHRoZSBBc3luY0xvY2FsU3RvcmFnZSBzdG9yZSDigJQgdGhlIHN0b3JlIGlzIHBlci1yZXF1ZXN0LCBzbyB0aGlzIGNhbm5vdCBsZWFrXG4gICAqIGJldHdlZW4gcmVxdWVzdHMuXG4gICAqXG4gICAqIFNDT1BFOiB0aGlzIGNvdmVycyByZWFkcyBBRlRFUiBhIHdyaXRlIElOIFRIRSBTQU1FIFJFUVVFU1QuIEl0IGRvZXMgTk9UXG4gICAqIGNvdmVyIHRoZSBuZXh0IHJlcXVlc3QgKFBPU1QgdGhlbiBhIHBhZ2UgcmVsb2FkIGlzc3VpbmcgR0VUKS4gVGhhdCBuZWVkc1xuICAgKiBzaGFyZWQgc3RhdGUg4oCUIHNlZSB0aGUgY3Jvc3MtcmVxdWVzdCBzZWN0aW9uIG9mXG4gICAqIGRvY3MvcGxhbnMvcG9zdGdyZXMtcmVhZC13cml0ZS1zcGxpdC5tZCDigJQgYW5kIG11c3QgYmUgc2V0dGxlZCBiZWZvcmUgY2FsbFxuICAgKiBzaXRlcyBhcmUgbWlncmF0ZWQgaW4gYnVsay5cbiAgICovXG4gIG1heUhhdmVXcml0dGVuPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBQZXItcmVxdWVzdCB0ZW5hbnQgY29udGV4dC4gUG9wdWxhdGVkIGJ5IEV4cHJlc3MgbWlkZGxld2FyZSBvbmNlIHRoZSBKV1RcbiAqIGlzIHZhbGlkYXRlZDsgY29uc3VtZWQgYnkgYHdpdGhUZW5hbnRUeGAgYW5kIGFueSBoZWxwZXIgdGhhdCBuZWVkcyB0b1xuICoga25vdyBcIndobyBpcyB0aGUgY2FsbGVyXCIgd2l0aG91dCByZS1kZXJpdmluZyBmcm9tIHRoZSByZXF1ZXN0IG9iamVjdC5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlbmFudENvbnRleHQgPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2U8VGVuYW50Q29udGV4dD4oKTtcblxuLyoqXG4gKiBSdW4gYGZuYCBpbnNpZGUgdGhlIGdpdmVuIHRlbmFudCBzY29wZS4gVGhlIEFzeW5jTG9jYWxTdG9yYWdlIHNjb3BlXG4gKiBzdXJ2aXZlcyBhY3Jvc3MgYXN5bmMgYm91bmRhcmllcyAoUHJvbWlzZXMsIHNldFRpbWVvdXQsIGV0Yy4pLCBzbyBhbnlcbiAqIGB3aXRoVGVuYW50VHhgIGNhbGwgaW5zaWRlIGBmbmAg4oCUIGRpcmVjdGx5IG9yIHRocm91Z2ggYW55IGRlcHRoIG9mXG4gKiBhc3luYyBoZWxwZXJzIOKAlCBwaWNrcyB1cCBgY3R4YC5cbiAqXG4gKiBXcmFwIGBuZXh0KClgIGZyb20gYW4gRXhwcmVzcyBtaWRkbGV3YXJlIHRvIGVzdGFibGlzaCBwZXItcmVxdWVzdCBzY29wZTpcbiAqXG4gKiAgICAgYXBwLnVzZSgocmVxLCByZXMsIG5leHQpID0+IHtcbiAqICAgICAgIHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbiB9LCAoKSA9PiBuZXh0KCkpO1xuICogICAgIH0pO1xuICovXG5leHBvcnQgZnVuY3Rpb24gcnVuV2l0aFRlbmFudENvbnRleHQ8VD4oY3R4OiBUZW5hbnRDb250ZXh0LCBmbjogKCkgPT4gVCk6IFQge1xuICByZXR1cm4gdGVuYW50Q29udGV4dC5ydW4oY3R4LCBmbik7XG59XG5cbi8qKiBSZWFkIHRoZSBjdXJyZW50IHRlbmFudCBjb250ZXh0LiBSZXR1cm5zIHVuZGVmaW5lZCBvdXRzaWRlIGFuXG4gKiAgYHJ1bldpdGhUZW5hbnRDb250ZXh0YCBzY29wZSAoZS5nLiBiYWNrZ3JvdW5kIHdvcmtlcnMsIG1pZ3JhdGlvbnMpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRlbmFudENvbnRleHQoKTogVGVuYW50Q29udGV4dCB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB0ZW5hbnRDb250ZXh0LmdldFN0b3JlKCk7XG59XG5cbi8qKlxuICogT3BlbiBhIHRyYW5zYWN0aW9uIHdpdGggUkxTIEdVQ3MgU0VUIExPQ0FMIGZyb20gdGhlIGN1cnJlbnRcbiAqIEFzeW5jTG9jYWxTdG9yYWdlIHRlbmFudCBjb250ZXh0LCB0aGVuIGludm9rZSBgZm4odHgpYC5cbiAqXG4gKiAtIFdoZW4gY2FsbGVkIG91dHNpZGUgYSB0ZW5hbnQgc2NvcGUgKGUuZy4gZnJvbSBhIGJhY2tncm91bmQgam9iIHRoYXRcbiAqICAgZG9lc24ndCBoYXZlIGEgY2FsbGVyIGlkZW50aXR5KSwgdGhlIHRyYW5zYWN0aW9uIGlzIG9wZW5lZCB3aXRoIGJvdGhcbiAqICAgR1VDcyBjbGVhcmVkIOKAlCBSTFMgcG9saWNpZXMgd2lsbCByZXR1cm4gemVybyByb3dzIG9uIEZPUkNFJ2QgdGFibGVzLlxuICogICBDYWxsZXJzIHRoYXQgbmVlZCBhIHN5c2FkbWluLWVxdWl2YWxlbnQgc2NvcGUgc2hvdWxkIHdyYXAgdGhlbXNlbHZlcyBpblxuICogICBgcnVuV2l0aFRlbmFudENvbnRleHQoeyBpc1N1cGVyQWRtaW46IHRydWUgfSwg4oCmKWAgZXhwbGljaXRseS5cbiAqXG4gKiAtIFVzZXMgYHNldF9jb25maWcoa2V5LCB2YWx1ZSwgdHJ1ZSlgICh0aGUgYm9vbGVhbiA9IGBpc19sb2NhbGAsIGkuZS5cbiAqICAgdHJhbnNhY3Rpb24tc2NvcGVkKS4gRXF1aXZhbGVudCB0byBgU0VUIExPQ0FMYCBidXQgdGFrZXMgdGhlIHZhbHVlIGFzXG4gKiAgIGEgcGFyYW1ldGVyLCB3aGljaCBpcyB3aGF0IHdlIHdhbnQg4oCUIERyaXp6bGUncyBgc3FsYCB0ZW1wbGF0ZSBiaW5kcyB0aGVcbiAqICAgdmFsdWUgc2FmZWx5IHNvIGFuIGF0dGFja2VyLWNvbnRyb2xsZWQgYG9yZ0lkYCBjYW4ndCBlc2NhcGUgdGhlIHF1b3RpbmcuXG4gKlxuICogLSBSZXR1cm5zIHdoYXRldmVyIGBmbmAgcmV0dXJuczsgdGhyb3dzIHdoYXRldmVyIGBmbmAgdGhyb3dzIChEcml6emxlXG4gKiAgIGhhbmRsZXMgdGhlIENPTU1JVC9ST0xMQkFDSyBmb3IgdXMpLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd2l0aFRlbmFudFR4PFQ+KFxuICBmbjogKHR4OiBQYXJhbWV0ZXJzPFBhcmFtZXRlcnM8dHlwZW9mIGRiLnRyYW5zYWN0aW9uPlswXT5bMF0pID0+IFByb21pc2U8VD4sXG4gIC8qKlxuICAgKiBJTlRFUk5BTC4gV2hldGhlciB0aGlzIHRyYW5zYWN0aW9uIHNob3VsZCBtYXJrIHRoZSByZXF1ZXN0IGFzIHBvc3NpYmx5XG4gICAqIGhhdmluZyB3cml0dGVuLiBBbHdheXMgdHJ1ZSBmb3IgYSByZWFsIGNhbGxlcjsgb25seSB3aXRoVGVuYW50VHhSZWFkJ3NcbiAgICogcHJpbWFyeS1mYWxsYmFjayBwYXRoIHBhc3NlcyBmYWxzZSwgYmVjYXVzZSBhIHJlYWQgdGhhdCBsYW5kcyBvbiB0aGVcbiAgICogcHJpbWFyeSBoYXMgbm90IHdyaXR0ZW4uIFNlZSB0aGUgY29tbWVudCBhdCB0aGUgYXNzaWdubWVudCBiZWxvdy5cbiAgICovXG4gIG1hcmtXcml0dGVuID0gdHJ1ZSxcbik6IFByb21pc2U8VD4ge1xuICBjb25zdCBjdHggPSB0ZW5hbnRDb250ZXh0LmdldFN0b3JlKCk7XG5cbiAgaWYgKCFjdHgpIHtcbiAgICAvLyBTdXJmYWNlIHRoZSBidWcgaW5zdGVhZCBvZiBzaWxlbnRseSBTRVQnaW5nIGVtcHR5IEdVQ3MuIFRoZSBkZWZhdWx0XG4gICAgLy8gbW9kZSAoJ3dhcm4nKSBsb2dzIGFuIGFjdGlvbmFibGUgdHJhY2Ugc28gdGhlIGJhZCBjYWxsIHNpdGUgaXMgZWFzeVxuICAgIC8vIHRvIGZpbmQ7IHByb2R1Y3Rpb24gZGVwbG95bWVudHMgdGhhdCBoYXZlIGZpbmlzaGVkIHRoZSBhdWRpdCBjYW4gc2V0XG4gICAgLy8gUkxTX0NPTlRFWFRfTU9ERT1zdHJpY3QgdG8gZmFpbC1mYXN0IGF0IHRoZSBjYWxsIHNpdGUgKGJldHRlciBzdGFja1xuICAgIC8vIHRyYWNlIHRoYW4gdGhlIFBvc3RncmVzIFwicGVybWlzc2lvbiBkZW5pZWRcIiB0aGF0IHdvdWxkIG90aGVyd2lzZVxuICAgIC8vIHN1cmZhY2UgZnJvbSBGT1JDRSdkIFJMUykuXG4gICAgY29uc3QgbW9kZSA9IGdldENvbnRleHRNb2RlKCk7XG4gICAgaWYgKG1vZGUgPT09ICdzdHJpY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICd3aXRoVGVuYW50VHggY2FsbGVkIG91dHNpZGUgYSB0ZW5hbnQgc2NvcGUuIFdyYXAgeW91ciBoYW5kbGVyL3dvcmtlciAnXG4gICAgICAgICsgJ2luIHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgb3JnSWQsIGlzU3VwZXJBZG1pbiB9LCAuLi4pIGJlZm9yZSBpbnZva2luZyAnXG4gICAgICAgICsgJ2FueSBzZXJ2aWNlIHRoYXQgdG91Y2hlcyBSTFMtZW5mb3JjZWQgdGFibGVzLicsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAobW9kZSA9PT0gJ3dhcm4nKSB7XG4gICAgICAvLyBJbmNsdWRlIGEgc3ludGhldGljIHN0YWNrIHNvIHRoZSBvZmZlbmRpbmcgY2FsbCBzaXRlIGlzIGluIHRoZSBsb2cuXG4gICAgICBsb2dnZXIud2Fybignd2l0aFRlbmFudFR4IGNhbGxlZCBvdXRzaWRlIGEgdGVuYW50IHNjb3BlOyBSTFMgR1VDcyB3aWxsIGJlIGVtcHR5Jywge1xuICAgICAgICBzdGFjazogbmV3IEVycm9yKCd0ZW5hbnQtY29udGV4dCBtaXNzaW5nJykuc3RhY2ssXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBvcmdJZCA9IGN0eD8ub3JnSWQgPz8gJyc7XG4gIGNvbnN0IGlzU3VwZXJBZG1pbiA9IGN0eD8uaXNTdXBlckFkbWluID8gJ3RydWUnIDogJ2ZhbHNlJztcblxuICBjb25zdCBzdGF0ZW1lbnRUaW1lb3V0TXMgPSBnZXRTdGF0ZW1lbnRUaW1lb3V0TXMoKTtcblxuICAvLyBUaGlzIHRyYW5zYWN0aW9uIHJ1bnMgb24gdGhlIFBSSU1BUlkgYW5kIG1heSB3cml0ZSwgc28gYW55IGxhdGVyIHJlYWQgaW5cbiAgLy8gdGhpcyByZXF1ZXN0IG11c3Qgc3RheSBvbiB0aGUgcHJpbWFyeSB0b28uIFNldCBiZWZvcmUgdGhlIHRyYW5zYWN0aW9uIG9wZW5zXG4gIC8vIHJhdGhlciB0aGFuIGFmdGVyIGl0IGNvbW1pdHM6IGEgcmVhZCBpc3N1ZWQgY29uY3VycmVudGx5IGZyb20gdGhlIHNhbWVcbiAgLy8gaGFuZGxlciB3b3VsZCBvdGhlcndpc2UgcmFjZSB0aGUgZmxhZy5cbiAgLy9cbiAgLy8gYG1hcmtXcml0dGVuOiBmYWxzZWAgaXMgcGFzc2VkIE9OTFkgYnkgd2l0aFRlbmFudFR4UmVhZCdzIGZhbGxiYWNrIHBhdGgsXG4gIC8vIGFuZCBpdCBpcyBub3QgYW4gb3B0aW1pc2F0aW9uIOKAlCB3aXRob3V0IGl0IHRoZSBmZWF0dXJlIGRlZmVhdHMgaXRzZWxmLiBUaGF0XG4gIC8vIHBhdGggcnVucyBvbiB0aGUgcHJpbWFyeSwgc28gaXQgd291bGQgc2V0IHRoaXMgZmxhZywgd2hpY2ggYXBpLXNlcnZlcidzXG4gIC8vIG1pZGRsZXdhcmUgcmVhZHMgYWZ0ZXIgdGhlIHJlc3BvbnNlIHRvIHNldCB0aGUgUmVkaXMgd3JpdGUgcGluLiBBIHB1cmVseVxuICAvLyBSRUFELU9OTFkgcmVxdWVzdCB3b3VsZCB0aGVyZWZvcmUgcGluIGl0cyB3aG9sZSBvcmcgdG8gdGhlIHByaW1hcnkgZm9yIHRoZVxuICAvLyBwaW4gVFRMLCBldmVyeSB0aW1lLCBhbmQgc2luY2UgcmVhZHMgZmFsbCBiYWNrIHdoZW5ldmVyIG5vIHJlcGxpY2EgaXNcbiAgLy8gY29uZmlndXJlZCAodGhlIHNoaXBwaW5nIGRlZmF1bHQpIGV2ZXJ5IG9yZyB3b3VsZCBiZSBwZXJtYW5lbnRseSBwaW5uZWQuXG4gIC8vIFRoZSBmbGFnIG1lYW5zIFwidGhpcyByZXF1ZXN0IG1heSBoYXZlIFdSSVRURU5cIiwgbm90IFwidGhpcyByZXF1ZXN0IHRvdWNoZWRcbiAgLy8gdGhlIHByaW1hcnlcIiwgYW5kIHRoZSBkaWZmZXJlbmNlIGlzIHRoZSB3aG9sZSByZWFkLW9mZmxvYWQgYmVuZWZpdC5cbiAgaWYgKGN0eCAmJiBtYXJrV3JpdHRlbikgY3R4Lm1heUhhdmVXcml0dGVuID0gdHJ1ZTtcblxuICByZXR1cm4gZGIudHJhbnNhY3Rpb24oYXN5bmMgKHR4KSA9PiB7XG4gICAgLy8gU2V0IGV2ZXJ5IHRyYW5zYWN0aW9uLXNjb3BlZCBHVUMgaW4gYSBTSU5HTEUgcm91bmQtdHJpcC4gYHNldF9jb25maWcoKWBcbiAgICAvLyByZXR1cm5zIGl0cyB2YWx1ZSwgc28gbXVsdGlwbGUgY2FsbHMgY29tcG9zZSBpbiBvbmUgU0VMRUNUIHJhdGhlciB0aGFuIGFcbiAgICAvLyByb3VuZC10cmlwIHBlciBHVUMg4oCUIGVhY2ggYSBuZXR3b3JrIGhvcCB0aGF0IHRheGVzIHRoZSBzaGFyZWQgUGdCb3VuY2VyXG4gICAgLy8gcG9vbCBvbiB0aGUgaG90IHBhdGguIGB0cnVlYFxuICAgIC8vID0gaXNfbG9jYWwgKFNFVCBMT0NBTCBzZW1hbnRpY3M6IGF1dG8tcmVsZWFzZWQgb24gQ09NTUlUL1JPTExCQUNLKS4gVGhlXG4gICAgLy8gZHJpdmVyIGJpbmRzIHRoZSB2YWx1ZXMgYXMgcGFyYW1ldGVycywgc28gYSBob3N0aWxlIG9yZ19pZCBjYW4ndCBicmVhayBvdXRcbiAgICAvLyBvZiB0aGUgR1VDIHN5bnRheC5cbiAgICAvL1xuICAgIC8vIFRoZSBzdGF0ZW1lbnRfdGltZW91dCBHVUMgYm91bmRzIGEgcnVuYXdheSBxdWVyeSBzbyBpdCBjYW4ndCBob2xkIGEgcG9vbGVkXG4gICAgLy8gY29ubmVjdGlvbiBvcGVuIGluZGVmaW5pdGVseSAoYFNFVCBMT0NBTCBzdGF0ZW1lbnRfdGltZW91dCA9ICQxYCBpcyByZWplY3RlZFxuICAgIC8vIGJ5IFBvc3RncmVzLCBoZW5jZSBzZXRfY29uZmlnIHdpdGggYSBib3VuZCBtcyB2YWx1ZSkuIEluY2x1ZGVkIGluIHRoZSBzYW1lXG4gICAgLy8gc3RhdGVtZW50IHdoZW4gZW5hYmxlZCAoPjApLCBkcm9wcGVkIGVudGlyZWx5IHdoZW4gZGlzYWJsZWQgKDApLlxuICAgIGlmIChzdGF0ZW1lbnRUaW1lb3V0TXMgPiAwKSB7XG4gICAgICBhd2FpdCB0eC5leGVjdXRlKFxuICAgICAgICBzcWxgU0VMRUNUIHNldF9jb25maWcoJ2FwcC5vcmdfaWQnLCAke29yZ0lkfSwgdHJ1ZSksIHNldF9jb25maWcoJ2FwcC5pc19zeXNhZG1pbicsICR7aXNTdXBlckFkbWlufSwgdHJ1ZSksIHNldF9jb25maWcoJ3N0YXRlbWVudF90aW1lb3V0JywgJHtTdHJpbmcoc3RhdGVtZW50VGltZW91dE1zKX0sIHRydWUpYCxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHR4LmV4ZWN1dGUoXG4gICAgICAgIHNxbGBTRUxFQ1Qgc2V0X2NvbmZpZygnYXBwLm9yZ19pZCcsICR7b3JnSWR9LCB0cnVlKSwgc2V0X2NvbmZpZygnYXBwLmlzX3N5c2FkbWluJywgJHtpc1N1cGVyQWRtaW59LCB0cnVlKWAsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZm4odHgpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBXaHkgYSByZWFkIHdhcyBvciB3YXMgbm90IHNlbnQgdG8gdGhlIHJlcGxpY2EuIFJldHVybmVkIGJ5XG4gKiB7QGxpbmsgY2hvb3NlUmVhZFRhcmdldH0gc28gdGhlIGRlY2lzaW9uIGlzIGluc3BlY3RhYmxlIOKAlCBhbmQgdGVzdGFibGVcbiAqIHdpdGhvdXQgYSByZXBsaWNhLCB3aGljaCBtYXR0ZXJzIGJlY2F1c2UgdGhlIHRlc3Qgc3Vic3RyYXRlIChQR2xpdGUpIGhhcyBub1xuICogcmVwbGljYXRpb24gYXQgYWxsLlxuICovXG5leHBvcnQgdHlwZSBSZWFkVGFyZ2V0UmVhc29uID1cbiAgLyoqIE5vIHJlcGxpY2EgY29uZmlndXJlZCwgb3IgREJfUkVBRF9FTkFCTEVEPWZhbHNlLiAqL1xuICB8ICduby1yZXBsaWNhJ1xuICAvKiogVGhpcyByZXF1ZXN0IGFscmVhZHkgb3BlbmVkIGEgcHJpbWFyeSB0cmFuc2FjdGlvbiBhbmQgbWF5IGhhdmUgd3JpdHRlbi4gKi9cbiAgfCAnbWF5LWhhdmUtd3JpdHRlbidcbiAgLyoqXG4gICAqIE5vIHRlbmFudCBjb250ZXh0LiBBIGNhbGxlciBvdXRzaWRlIGBydW5XaXRoVGVuYW50Q29udGV4dGAgaGFzIG5vIG9yZyB0b1xuICAgKiBzY29wZSBSTFMgYnkgYW5kIG5vIHdhdGVybWFyayB0byBjb21wYXJlLCBzbyBpdCBnb2VzIHRvIHRoZSBwcmltYXJ5IOKAlCB3aGVyZVxuICAgKiBgd2l0aFRlbmFudFR4YCdzIFJMU19DT05URVhUX01PREUgZ3VhcmQgbG9ncyBvciB0aHJvd3MuIFJvdXRlZCB0byBhIHJlcGxpY2FcbiAgICogaW5zdGVhZCwgdGhlIHNhbWUgY2FsbCB3b3VsZCBzZXQgYGFwcC5vcmdfaWQgPSAnJ2Agd2l0aCBubyBkaWFnbm9zdGljIGF0IGFsbC5cbiAgICovXG4gIHwgJ25vLWNvbnRleHQnXG4gIC8qKlxuICAgKiBBIHJlcGxpY2EgZXhpc3RzIGJ1dCBpdHMgcmVwbGF5IGxhZyBpcyBiZXlvbmQgYERCX1JFQURfTUFYX0xBR19TRUNPTkRTYCxcbiAgICogb3IgaXMgVU5LTk9XTiAobm8gc2FtcGxlIHlldCwgdGhlIHNhbXBsZSBmYWlsZWQsIG9yIHRoZSBjYWNoZWQgc2FtcGxlIGhhc1xuICAgKiBnb25lIHN0YWxlKS4gVW5rbm93biBhbmQgbGFnZ2luZyBhcmUgdGhlIHNhbWUgZGVjaXNpb24gb24gcHVycG9zZTogdGhlXG4gICAqIGNpcmN1aXQgZmFpbHMgY2xvc2VkLlxuICAgKi9cbiAgfCAncmVwbGljYS1sYWdnaW5nJ1xuICAvKiogUm91dGVkIHRvIHRoZSByZXBsaWNhLiAqL1xuICB8ICdyZXBsaWNhJztcblxuZXhwb3J0IGludGVyZmFjZSBSZWFkVGFyZ2V0IHtcbiAgdXNlUmVwbGljYTogYm9vbGVhbjtcbiAgcmVhc29uOiBSZWFkVGFyZ2V0UmVhc29uO1xufVxuXG4vKipcbiAqIERlY2lkZSB3aGVyZSBhIHJlYWQtb25seSB0cmFuc2FjdGlvbiBzaG91bGQgcnVuLlxuICpcbiAqIFB1cmUgYW5kIHNpZGUtZWZmZWN0IGZyZWUgb24gcHVycG9zZTogdGhpcyBpcyB0aGUgd2hvbGUgb2YgdGhlIHJvdXRpbmdcbiAqIHBvbGljeSwgYW5kIGl0IGlzIHRoZSBwYXJ0IHdvcnRoIHRlc3RpbmcuIFJlcGxpY2F0aW9uIGl0c2VsZiBjYW5ub3QgYmVcbiAqIHJlcHJvZHVjZWQgbG9jYWxseSwgc28gdGhlIHRlc3RhYmxlIHVuaXQgaXMgdGhlIERFQ0lTSU9OLCBub3QgdGhlIGxhZy5cbiAqXG4gKiBUaGUgYmlhcyBpcyBkZWxpYmVyYXRlOiBhbnl0aGluZyB1bmNlcnRhaW4gcmVzb2x2ZXMgdG8gdGhlIHByaW1hcnkuIEEgcmVhZFxuICogc2VydmVkIGJ5IHRoZSBwcmltYXJ5IGlzIG1lcmVseSBsZXNzIGVmZmljaWVudDsgYSByZWFkIHNlcnZlZCBieSBhIHN0YWxlXG4gKiByZXBsaWNhIGlzIGEgdXNlci12aXNpYmxlIGJ1ZyBub2JvZHkgY2FuIHJlcHJvZHVjZS5cbiAqL1xuLyoqIEV2ZXJ5dGhpbmcgYWJvdXQgdGhlIHJlcGxpY2EgdGhhdCBpcyBub3QgcmVxdWVzdC1zcGVjaWZpYy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVhZFJlcGxpY2FIZWFsdGgge1xuICAvKiogQSByZXBsaWNhIHBvb2wgZXhpc3RzIEFORCBgREJfUkVBRF9FTkFCTEVEYCBpcyBub3QgZmFsc2UuICovXG4gIGF2YWlsYWJsZTogYm9vbGVhbjtcbiAgLyoqIFRoZSBsYWcgY2lyY3VpdCdzIHZlcmRpY3QuIGB1bmtub3duYCBpcyB0cmVhdGVkIGV4YWN0bHkgbGlrZSBgbGFnZ2luZ2AuICovXG4gIGxhZzogTGFnVmVyZGljdDtcbn1cblxuLyoqXG4gKiBXaGVyZSBhIHJlYWQgZ29lcywgYW5kIHdoeS5cbiAqXG4gKiBTWVNURU0gZ2F0ZXMgYXJlIGNoZWNrZWQgYmVmb3JlIFJFUVVFU1QgZ2F0ZXMsIHdoaWNoIG1hdHRlcnMgb25seSBmb3IgdGhlXG4gKiBleHBsYW5hdGlvbiDigJQgYnV0IHRoZSBleHBsYW5hdGlvbiBpcyB3aGF0IGFuIG9wZXJhdG9yIHJlYWRzIHdoZW4gYXNraW5nIHdoeVxuICogdGhlIHJlcGxpY2EgaXMgaWRsZSwgYW5kIFwibXkgcmVxdWVzdCB3cm90ZVwiIGlzIGEgZmFyIGxlc3MgdXNlZnVsIGFuc3dlciB0aGFuXG4gKiBcInRoZSBzdGFuZGJ5IGlzIDQwIHNlY29uZHMgYmVoaW5kXCIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaG9vc2VSZWFkVGFyZ2V0KGN0eDogVGVuYW50Q29udGV4dCB8IHVuZGVmaW5lZCwgaGVhbHRoOiBSZWFkUmVwbGljYUhlYWx0aCk6IFJlYWRUYXJnZXQge1xuICBpZiAoIWhlYWx0aC5hdmFpbGFibGUpIHJldHVybiB7IHVzZVJlcGxpY2E6IGZhbHNlLCByZWFzb246ICduby1yZXBsaWNhJyB9O1xuICBpZiAoaGVhbHRoLmxhZyAhPT0gJ29rJykgcmV0dXJuIHsgdXNlUmVwbGljYTogZmFsc2UsIHJlYXNvbjogJ3JlcGxpY2EtbGFnZ2luZycgfTtcbiAgaWYgKCFjdHgpIHJldHVybiB7IHVzZVJlcGxpY2E6IGZhbHNlLCByZWFzb246ICduby1jb250ZXh0JyB9O1xuICBpZiAoY3R4Lm1heUhhdmVXcml0dGVuKSByZXR1cm4geyB1c2VSZXBsaWNhOiBmYWxzZSwgcmVhc29uOiAnbWF5LWhhdmUtd3JpdHRlbicgfTtcbiAgcmV0dXJuIHsgdXNlUmVwbGljYTogdHJ1ZSwgcmVhc29uOiAncmVwbGljYScgfTtcbn1cblxuLyoqXG4gKiBPcGVuIGEgUkVBRC1PTkxZIHRyYW5zYWN0aW9uIHdpdGggdGhlIHNhbWUgUkxTIEdVQ3MgYHdpdGhUZW5hbnRUeGAgc2V0cyxcbiAqIHJvdXRlZCB0byB0aGUgcmVwbGljYSB3aGVuIHtAbGluayBjaG9vc2VSZWFkVGFyZ2V0fSBhbGxvd3MgaXQuXG4gKlxuICogYFNFVCBUUkFOU0FDVElPTiBSRUFEIE9OTFlgIGlzIHRoZSBndWFyZHJhaWwsIG5vdCBkZWNvcmF0aW9uLiBTZXZlcmFsIHF1ZXJpZXNcbiAqIGluIHRoaXMgY29kZWJhc2UgbG9vayBsaWtlIHJlYWRzIGF0IHRoZSBjYWxsIHNpdGUgYW5kIGFyZSBub3Qg4oCUXG4gKiBgU0VMRUNUIOKApiBGT1IgVVBEQVRFYCBpbiBjcnVkLXNlcnZpY2UncyBzZXREZWZhdWx0LCBgcGdfYWR2aXNvcnlfeGFjdF9sb2NrYFxuICogaW4gcGlwZWxpbmUtc2VydmljZSBhbmQgY29tcGxpYW5jZSdzIHN1YnNjcmlwdGlvbi1zZXJ2aWNlLiBSb3V0ZWQgdG8gYVxuICogc3RhbmRieSB0aG9zZSBmYWlsIGFueXdheTsgZGVjbGFyaW5nIHRoZSB0cmFuc2FjdGlvbiByZWFkLW9ubHkgbWFrZXMgdGhlbVxuICogZmFpbCBIRVJFLCB3aXRoIGEgY2xlYXIgbWVzc2FnZSwgaW5jbHVkaW5nIG9uIHRoZSBwcmltYXJ5IHdoZXJlIHRoZXkgd291bGRcbiAqIG90aGVyd2lzZSBzdWNjZWVkIGFuZCBxdWlldGx5IGFjcXVpcmUgYSBsb2NrIHRoZSBjYWxsZXIgZGlkIG5vdCBpbnRlbmQuXG4gKlxuICogRmFsbHMgYmFjayB0byB0aGUgcHJpbWFyeSB0cmFuc3BhcmVudGx5LCBzbyBhIGNhbGxlciBuZXZlciBoYXMgdG8gYXNrXG4gKiB3aGV0aGVyIGEgcmVwbGljYSBleGlzdHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3aXRoVGVuYW50VHhSZWFkPFQ+KFxuICBmbjogKHR4OiBQYXJhbWV0ZXJzPFBhcmFtZXRlcnM8dHlwZW9mIGRiLnRyYW5zYWN0aW9uPlswXT5bMF0pID0+IFByb21pc2U8VD4sXG4pOiBQcm9taXNlPFQ+IHtcbiAgY29uc3QgY3R4ID0gdGVuYW50Q29udGV4dC5nZXRTdG9yZSgpO1xuICBjb25zdCByZWFkRGIgPSBnZXRSZWFkRGIoKTtcbiAgY29uc3QgcmVhZFBvb2wgPSBnZXRSZWFkUG9vbCgpO1xuXG4gIC8vIEtlZXAgdGhlIGxhZyBzYW1wbGUgd2FybS4gRmlyZS1hbmQtZm9yZ2V0IGJ5IGRlc2lnbjogaXQgaXMgZGVib3VuY2VkIHRvXG4gIC8vIERCX1JFQURfTEFHX1NBTVBMRV9NUywgbmV2ZXIgdGhyb3dzLCBhbmQgbXVzdCBub3QgYWRkIGEgcm91bmQtdHJpcCB0byB0aGlzXG4gIC8vIHJlYWQuIFRoZSBmaXJzdCByZWFkIG9mIGEgcHJvY2VzcyB0aGVyZWZvcmUgcm91dGVzIHRvIHRoZSBwcmltYXJ5IChub1xuICAvLyBzYW1wbGUgeWV0KSBhbmQgd2FybXMgdGhlIGNpcmN1aXQgZm9yIHRoZSBvbmVzIGFmdGVyIGl0LlxuICBpZiAocmVhZFBvb2wpIHZvaWQgbWF5YmVTYW1wbGVMYWcocmVhZFBvb2wpO1xuXG4gIGNvbnN0IHRhcmdldCA9IGNob29zZVJlYWRUYXJnZXQoY3R4LCB7IGF2YWlsYWJsZTogcmVhZERiICE9PSBudWxsLCBsYWc6IGxhZ1ZlcmRpY3QoKSB9KTtcbiAgZW1pdENvdW50ZXIoJ3Bvc3RncmVzX3JlYWRfcm91dGVkX3RvdGFsJywgeyB0YXJnZXQ6IHRhcmdldC51c2VSZXBsaWNhID8gJ3JlcGxpY2EnIDogJ3ByaW1hcnknLCByZWFzb246IHRhcmdldC5yZWFzb24gfSk7XG5cbiAgaWYgKCF0YXJnZXQudXNlUmVwbGljYSkge1xuICAgIC8vIFByaW1hcnkgcGF0aDogaWRlbnRpY2FsIHNlbWFudGljcyB0byB3aXRoVGVuYW50VHgsIHBsdXMgdGhlIHJlYWQtb25seVxuICAgIC8vIGRlY2xhcmF0aW9uIHNvIGFuIGFjY2lkZW50YWwgd3JpdGUgaXMgY2F1Z2h0IG9uIGV2ZXJ5IHRhcmdldCDigJQgaW5jbHVkaW5nXG4gICAgLy8gdGhlIG9uZXMgdGhhdCB3aWxsIG5ldmVyIGhhdmUgYSByZXBsaWNhLlxuICAgIHJldHVybiB3aXRoVGVuYW50VHgoYXN5bmMgKHR4KSA9PiB7XG4gICAgICBhd2FpdCB0eC5leGVjdXRlKHNxbGBTRVQgVFJBTlNBQ1RJT04gUkVBRCBPTkxZYCk7XG4gICAgICByZXR1cm4gZm4odHgpO1xuICAgIH0sIC8qIG1hcmtXcml0dGVuICovIGZhbHNlKTtcbiAgfVxuXG4gIC8vIE5vbi1udWxsIGJ5IGNvbnN0cnVjdGlvbjogY2hvb3NlUmVhZFRhcmdldCBvbmx5IHJldHVybnMgdXNlUmVwbGljYSBmb3IgYVxuICAvLyBjdHggdGhhdCBleGlzdHMuIFJlYWQgdGhlIEdVQ3Mgb2ZmIGl0IGRpcmVjdGx5IHJhdGhlciB0aGFuIGRlZmF1bHRpbmcgdG9cbiAgLy8gJycg4oCUIGEgZGVmYXVsdCBoZXJlIHdvdWxkIHNpbGVudGx5IHJlLW9wZW4gdGhlIGhvbGUgdGhhdCAnbm8tY29udGV4dCdcbiAgLy8gY2xvc2VzLCBiZWNhdXNlIGFuIGVtcHR5IGFwcC5vcmdfaWQgaXMgYSBWQUxJRC1sb29raW5nIFJMUyBzY29wZS5cbiAgY29uc3QgeyBvcmdJZCB9ID0gY3R4ITtcbiAgY29uc3QgaXNTdXBlckFkbWluID0gY3R4IS5pc1N1cGVyQWRtaW4gPyAndHJ1ZScgOiAnZmFsc2UnO1xuICBjb25zdCBzdGF0ZW1lbnRUaW1lb3V0TXMgPSBnZXRTdGF0ZW1lbnRUaW1lb3V0TXMoKTtcblxuICByZXR1cm4gcmVhZERiIS50cmFuc2FjdGlvbihhc3luYyAodHgpID0+IHtcbiAgICBhd2FpdCB0eC5leGVjdXRlKHNxbGBTRVQgVFJBTlNBQ1RJT04gUkVBRCBPTkxZYCk7XG4gICAgaWYgKHN0YXRlbWVudFRpbWVvdXRNcyA+IDApIHtcbiAgICAgIGF3YWl0IHR4LmV4ZWN1dGUoXG4gICAgICAgIHNxbGBTRUxFQ1Qgc2V0X2NvbmZpZygnYXBwLm9yZ19pZCcsICR7b3JnSWR9LCB0cnVlKSwgc2V0X2NvbmZpZygnYXBwLmlzX3N5c2FkbWluJywgJHtpc1N1cGVyQWRtaW59LCB0cnVlKSwgc2V0X2NvbmZpZygnc3RhdGVtZW50X3RpbWVvdXQnLCAke1N0cmluZyhzdGF0ZW1lbnRUaW1lb3V0TXMpfSwgdHJ1ZSlgLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgdHguZXhlY3V0ZShcbiAgICAgICAgc3FsYFNFTEVDVCBzZXRfY29uZmlnKCdhcHAub3JnX2lkJywgJHtvcmdJZH0sIHRydWUpLCBzZXRfY29uZmlnKCdhcHAuaXNfc3lzYWRtaW4nLCAke2lzU3VwZXJBZG1pbn0sIHRydWUpYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBmbih0eCk7XG4gIH0pO1xufVxuIl19
250
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW5jeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhYmFzZS90ZW5hbmN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBRUgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDckQsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDL0UsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBbUIsTUFBTSxlQUFlLENBQUM7QUFFNUUsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFlOUMsU0FBUyxjQUFjO0lBQ3JCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFDeEQsSUFBSSxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsS0FBSyxNQUFNLElBQUksR0FBRyxLQUFLLFFBQVE7UUFBRSxPQUFPLEdBQUcsQ0FBQztJQUN2RSx1RUFBdUU7SUFDdkUsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0FBQ25FLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMscUJBQXFCO0lBQzVCLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSxNQUFNLENBQUMs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QUNkLEdBQUcsQ0FBQSxtQ0FBbUMsS0FBSywwQ0FBMEMsWUFBWSw0Q0FBNEMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FDakwsQ0FBQztRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxFQUFFLENBQUMsT0FBTyxDQUNkLEdBQUcsQ0FBQSxtQ0FBbUMsS0FBSywwQ0FBMEMsWUFBWSxTQUFTLENBQzNHLENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDaEIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogVGVuYW50LWNvbnRleHQgcGx1bWJpbmcgZm9yIFBvc3RncmVzIHJvdy1sZXZlbCBzZWN1cml0eS5cbiAqXG4gKiBCYWNrZ3JvdW5kOiBwb3N0Z3Jlcy1pbml0LnNxbCBpbnN0YWxscyBSTFMgcG9saWNpZXMgb24gZXZlcnkgdXNlci1kYXRhXG4gKiB0YWJsZSB0aGF0IGNvbnN1bHQgdHdvIHNlc3Npb24gR1VDcyDigJQgYGFwcC5vcmdfaWRgIGFuZCBgYXBwLmlzX3N5c2FkbWluYC5cbiAqIEV2ZXJ5IHRlbmFudCB0YWJsZSBpcyBgRk9SQ0UgUk9XIExFVkVMIFNFQ1VSSVRZYCwgc28gdGhlIHBvbGljaWVzIGVuZm9yY2VcbiAqIGV2ZW4gZm9yIHRoZSAob3duaW5nKSBjb25uZWN0aW9uIHVzZXIg4oCUIGEgcXVlcnkgYWdhaW5zdCBvbmUgbXVzdCBydW4gaW5zaWRlIGFcbiAqIHRyYW5zYWN0aW9uIHRoYXQgaGFzIFNFVCBMT0NBTCdkIGJvdGggR1VDcyBvciBpdCByZXR1cm5zIHplcm8gcm93cyBmb3JcbiAqIG5vbi1zeXNhZG1pbnMgKGFuZCBtYXkgZmFpbCB0byB3cml0ZSBmb3IgYW55IGNhbGxlcikuIFRoZSBjcm9zcy1vcmcgcGx1Z2luXG4gKiBlY29zeXN0ZW0gY2F0YWxvZyB0YWJsZXMgY2FycnkgYSBwZXJtaXNzaXZlIGFwcC1yb2xlIHBvbGljeSBpbnN0ZWFkLlxuICpcbiAqIFRoaXMgbW9kdWxlIGlzIHRoZSBzZWFtLlxuICpcbiAqICAgMS4gYHRlbmFudENvbnRleHRgIChBc3luY0xvY2FsU3RvcmFnZSkgY2FycmllcyBge29yZ0lkLCBpc1N1cGVyQWRtaW59YFxuICogICAgICBkb3duIHRoZSBjYWxsIGNoYWluIHdpdGhvdXQgcHJvcC1kcmlsbGluZy4gU2V0IG9uY2UgYXQgdGhlIHJlcXVlc3RcbiAqICAgICAgYm91bmRhcnk7IHJlYWRhYmxlIGZyb20gYW55d2hlcmUuXG4gKlxuICogICAyLiBgd2l0aFRlbmFudFR4KGZuKWAgb3BlbnMgYSB0cmFuc2FjdGlvbiwgU0VUIExPQ0FMJ3MgYm90aCBHVUNzIGZyb21cbiAqICAgICAgdGhlIHN1cnJvdW5kaW5nIGNvbnRleHQsIHRoZW4gaW52b2tlcyBgZm4odHgpYC4gU2VydmljZXMgbWlncmF0ZSBvbmVcbiAqICAgICAgYXQgYSB0aW1lIGJ5IHdyYXBwaW5nIHRoZWlyIGV4aXN0aW5nIGRyaXp6bGUgY2FsbHMgaW4gdGhpcyBoZWxwZXIg4oCUXG4gKiAgICAgIGBkYi5zZWxlY3QoKS5mcm9tKC4uLilgIGJlY29tZXMgYHdpdGhUZW5hbnRUeCh0eCA9PiB0eC5zZWxlY3QoKS5mcm9tKC4uLikpYC5cbiAqXG4gKiAgIDMuIGBydW5XaXRoVGVuYW50Q29udGV4dChjdHgsIGZuKWAgaXMgdGhlIEV4cHJlc3MtbWlkZGxld2FyZS1zaWRlXG4gKiAgICAgIGJvb2tlbmQgdGhhdCBlc3RhYmxpc2hlcyB0aGUgQXN5bmNMb2NhbFN0b3JhZ2Ugc2NvcGUgZm9yIHRoZSByZXF1ZXN0LlxuICpcbiAqIE1pZ3JhdGlvbiBvcmRlcjpcbiAqICAgLSBGaXJzdCBhZG9wdGVyczogbmV3bHktd3JpdHRlbiBzZXJ2aWNlcyAoZGFzaGJvYXJkLCBhbGVydC1kZXN0aW5hdGlvbilcbiAqICAgICB3aGVyZSB0aGUgY2hhbmdlIGlzIG1lY2hhbmljYWwuXG4gKiAgIC0gVGhlbiBoaWdoLXdyaXRlIHNlcnZpY2VzIChwbHVnaW4sIHBpcGVsaW5lKS4gU29hayBlYWNoIG9uZSBiZWZvcmVcbiAqICAgICBmbGlwcGluZyB0aGUgdW5kZXJseWluZyB0YWJsZSB0byBGT1JDRS5cbiAqICAgLSBhZG1pbl9hdWRpdF9sb2cgdXNlcyBhIHN5c2FkbWluLW9ubHkgcG9saWN5IOKAlCBzeXNhZG1pbiBwYXRocyBtdXN0XG4gKiAgICAgYWxzbyBzZXQgYGFwcC5pc19zeXNhZG1pbiA9ICd0cnVlJ2Agb3IgdGhleSdsbCBsb3NlIGFjY2VzcyB0byBpdC5cbiAqL1xuXG5pbXBvcnQgeyBBc3luY0xvY2FsU3RvcmFnZSB9IGZyb20gJ25vZGU6YXN5bmNfaG9va3MnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCBlbWl0Q291bnRlciwgZW52SW50IH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgc3FsIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgZGIgfSBmcm9tICcuL3Bvc3RncmVzLWNvbm5lY3Rpb24uanMnO1xuaW1wb3J0IHsgZ2V0UmVhZERiLCBnZXRSZWFkUG9vbCB9IGZyb20gJy4vcmVhZC1jb25uZWN0aW9uLmpzJztcbmltcG9ydCB7IGxhZ1ZlcmRpY3QsIG1heWJlU2FtcGxlTGFnLCB0eXBlIExhZ1ZlcmRpY3QgfSBmcm9tICcuL3JlYWQtbGFnLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCd0ZW5hbnQtY29udGV4dCcpO1xuXG4vKipcbiAqIEJlaGF2aW9yIHdoZW4gYHdpdGhUZW5hbnRUeGAgaXMgaW52b2tlZCBvdXRzaWRlIGFueSBgcnVuV2l0aFRlbmFudENvbnRleHRgXG4gKiBzY29wZS4gVGhlIGVmZmVjdGl2ZSBkZWZhdWx0IGlzIGZhaWwtZmFzdCAoJ3N0cmljdCcpIGluIHByb2R1Y3Rpb24gc28gYVxuICogbWlzc2luZyB0ZW5hbnQgc2NvcGUgc3VyZmFjZXMgYXQgdGhlIGJhZCBjYWxsIHNpdGUgaW5zdGVhZCBvZiBzaWxlbnRseVxuICogcnVubmluZyB3aXRoIGVtcHR5IFJMUyBHVUNzOyBvdXRzaWRlIHByb2R1Y3Rpb24gaXQgZGVmYXVsdHMgdG8gJ3dhcm4nIHNvXG4gKiB1bi1hdWRpdGVkIGRldi90ZXN0IHBhdGhzIGtlZXAgd29ya2luZyBidXQgbG9nIGFuIGFjdGlvbmFibGUgdHJhY2UuIEFuXG4gKiBleHBsaWNpdCBSTFNfQ09OVEVYVF9NT0RFIGVudiBvdmVycmlkZSBhbHdheXMgd2lucy5cbiAqXG4gKiAnc2lsZW50JyBpcyBrZXB0IGZvciB0ZXN0cyBhbmQgc2NyaXB0cyB0aGF0IGludGVudGlvbmFsbHkgZW50ZXIgdGhlIERCXG4gKiB3aXRob3V0IGNvbnRleHQgKGUuZy4gaW50ZWdyYXRpb24gdGVzdCBzZXR1cCB0aGF0IHJ1bnMgYXMgdGhlIGNvbm5lY3Rpb25cbiAqIG93bmVyIGJlZm9yZSBhbnkgdGVuYW50IGlzIHByb3Zpc2lvbmVkKS5cbiAqL1xudHlwZSBDb250ZXh0TW9kZSA9ICdzaWxlbnQnIHwgJ3dhcm4nIHwgJ3N0cmljdCc7XG5mdW5jdGlvbiBnZXRDb250ZXh0TW9kZSgpOiBDb250ZXh0TW9kZSB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LlJMU19DT05URVhUX01PREU/LnRvTG93ZXJDYXNlKCk7XG4gIGlmIChyYXcgPT09ICdzaWxlbnQnIHx8IHJhdyA9PT0gJ3dhcm4nIHx8IHJhdyA9PT0gJ3N0cmljdCcpIHJldHVybiByYXc7XG4gIC8vIE5vIGV4cGxpY2l0IG92ZXJyaWRlOiBmYWlsLWZhc3QgaW4gcHJvZHVjdGlvbiwgd2FybiBldmVyeXdoZXJlIGVsc2UuXG4gIHJldHVybiBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nID8gJ3N0cmljdCcgOiAnd2Fybic7XG59XG5cbi8qKlxuICogUGVyLXN0YXRlbWVudCBzZXJ2ZXItc2lkZSB0aW1lb3V0IChtcykgYXBwbGllZCBJTlNJREUgZXZlcnkgYHdpdGhUZW5hbnRUeGBcbiAqIHRyYW5zYWN0aW9uLCBuZXh0IHRvIHRoZSBSTFMgR1VDcy4gYHdpdGhUZW5hbnRUeGAgaXMgdGhlIHJlYWwgcXVlcnkgcGF0aCBmb3JcbiAqIGFsbCBSTFMvQ1JVRCByZWFkcyBhbmQgd3JpdGVzLCBzbyB0aGlzIGlzIHdoZXJlIHRoZSBEQi1zaWRlIGd1YXJkIGJlbG9uZ3MgKHRoZVxuICogb2xkIGBDb25uZWN0aW9uLnRyYW5zYWN0aW9uYCB3cmFwcGVyIHRoYXQgc2V0IGl0IGlzIGRlYWQg4oCUIHNlZVxuICogcG9zdGdyZXMtY29ubmVjdGlvbi50cykuIEJvdW5kcyBhIHJ1bmF3YXkgcXVlcnkgc28gaXQgY2FuJ3QgaG9sZCBhIHBvb2xlZFxuICogY29ubmVjdGlvbiBvcGVuIGluZGVmaW5pdGVseS4gRW52LWNvbmZpZ3VyYWJsZSB2aWEgYERCX1NUQVRFTUVOVF9USU1FT1VUX01TYFxuICogKGRlZmF1bHQgMzBzKTsgc2V0IHRvIGAwYCB0byBkaXNhYmxlIHRoZSB0aW1lb3V0LlxuICovXG5mdW5jdGlvbiBnZXRTdGF0ZW1lbnRUaW1lb3V0TXMoKTogbnVtYmVyIHtcbiAgY29uc3QgbXMgPSBlbnZJbnQoJ0RCX1NUQVRFTUVOVF9USU1FT1VUX01TJywgMzBfMDAwKTtcbiAgcmV0dXJuIG1zID49IDAgPyBtcyA6IDMwXzAwMDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5hbnRDb250ZXh0IHtcbiAgLyoqIENhbGxlcidzIG9yZy4gVW5kZWZpbmVkIGZvciB1bi1hdXRoZW50aWNhdGVkIC8gc3lzdGVtIGpvYnMuICovXG4gIG9yZ0lkPzogc3RyaW5nO1xuICAvKiogQ2FsbGVyJ3MgdXNlciBpZC4gTm90IHVzZWQgZm9yIFJMUyDigJQgUG9zdGdyZXMgcG9saWNpZXMgYXJlIG9yZy1ncmFpbmVkLFxuICAgKiAgd2l0aCBubyBwZXItdXNlciBzZXNzaW9uIEdVQyDigJQgYnV0IGNhcnJpZWQgc28gYXBwLWxheWVyIHByZWRpY2F0ZXMgd2l0aCBhXG4gICAqICBQRVItVVNFUiBydW5nIChwaXBlbGluZSB0ZW1wbGF0ZXMnIGBwcml2YXRlYCB2aXNpYmlsaXR5KSBjYW4gcmVzb2x2ZSBcIndob1xuICAgKiAgaXMgYXNraW5nXCIgb24gcGF0aHMgdGhhdCBoYXZlIG5vd2hlcmUgdG8gcGFzcyBpdCwgbm90YWJseSBDcnVkU2VydmljZSdzXG4gICAqICBgd3JpdGVDb25kaXRpb25zYC4gQWJzZW50IGZvciBzeXN0ZW0gam9icywgd2hpY2ggaXMgdGhlIGZhaWwtY2xvc2VkIGNhc2U6XG4gICAqICBubyB2aWV3ZXIg4oeSIG5vIHByaXZhdGUgcm93cy4gKi9cbiAgdXNlcklkPzogc3RyaW5nO1xuICAvKiogVHJ1ZSB3aGVuIHRoZSBjYWxsZXIgaXMgYSBzeXNhZG1pbiAoc3lzdGVtLW9yZyBhZG1pbikuIEJ5cGFzc2VzIFJMU1xuICAgKiAgcG9saWNpZXMgdmlhIHRoZSBzeXNhZG1pbi1ieXBhc3MgYnJhbmNoIGluIGBjdXJyZW50X2lzX3N5c2FkbWluKClgLiAqL1xuICBpc1N1cGVyQWRtaW46IGJvb2xlYW47XG4gIC8qKiBPcmcg4oaSIHRlYW0gaGllcmFyY2h5OiB0aGUgY2FsbGVyJ3MgYWN0aXZlLW9yZyBwYXJlbnQgKHByZXNlbnQgb25seSB3aGVuIHRoZVxuICAgKiAgYWN0aXZlIG9yZyBpcyBhIHRlYW0pLiBOb3QgdXNlZCBmb3IgUkxTOyBjYXJyaWVkIHNvIGRvd25zdHJlYW0gc2lkZS1lZmZlY3RzXG4gICAqICAoZS5nLiBlbnRpdHktZXZlbnQgY29tcGxpYW5jZSBldmFsKSBjYW4gaG9ub3IgcGFyZW50IGBwcm9wYWdhdGVUb0NoaWxkcmVuYFxuICAgKiAgcnVsZXMgd2l0aG91dCBhIHJlcXVlc3QgaW4gc2NvcGUuICovXG4gIHBhcmVudE9yZ0lkPzogc3RyaW5nO1xuICAvKipcbiAgICogU2V0IG9uY2UgdGhpcyByZXF1ZXN0IGhhcyBvcGVuZWQgYSBQUklNQVJZIHRyYW5zYWN0aW9uLCBpLmUuIG1heSBoYXZlXG4gICAqIHdyaXR0ZW4uIFN1YnNlcXVlbnQgYHdpdGhUZW5hbnRUeFJlYWRgIGNhbGxzIGluIHRoZSBzYW1lIHJlcXVlc3QgdGhlbiBnbyB0b1xuICAgKiB0aGUgcHJpbWFyeSB0b28sIHNvIGEgaGFuZGxlciBjYW5ub3QgcmVhZCBpdHMgb3duIHdyaXRlIG9mZiBhIHJlcGxpY2EgdGhhdFxuICAgKiBoYXMgbm90IHJlcGxheWVkIGl0IHlldC5cbiAgICpcbiAgICogRGVsaWJlcmF0ZWx5IHNldCBieSBgd2l0aFRlbmFudFR4YCByYXRoZXIgdGhhbiBieSB3cml0ZSBjYWxsIHNpdGVzOiB0aGF0XG4gICAqIHBhdGggaXMgdGhlIG9uZSB0aGF0IGNhbiB3cml0ZSwgaXQgbmVlZHMgbm8gcGVyLWNhbGwtc2l0ZSBkaXNjaXBsaW5lLCBhbmRcbiAgICogYmVpbmcgd3JvbmcgaW4gdGhpcyBkaXJlY3Rpb24gb25seSBjb3N0cyBhIHJlcGxpY2EgaGl0LiBNdXRhdGVkIGluIHBsYWNlIG9uXG4gICAqIHRoZSBBc3luY0xvY2FsU3RvcmFnZSBzdG9yZSDigJQgdGhlIHN0b3JlIGlzIHBlci1yZXF1ZXN0LCBzbyB0aGlzIGNhbm5vdCBsZWFrXG4gICAqIGJldHdlZW4gcmVxdWVzdHMuXG4gICAqXG4gICAqIFNDT1BFOiB0aGlzIGZsYWcgY292ZXJzIHJlYWRzIEFGVEVSIGEgd3JpdGUgSU4gVEhFIFNBTUUgUkVRVUVTVC4gVGhlXG4gICAqIG5leHQtcmVxdWVzdCBjYXNlIChQT1NULCB0aGVuIGEgcGFnZSByZWxvYWQgaXNzdWluZyBHRVQpIG5lZWRzIHNoYXJlZCBzdGF0ZVxuICAgKiBhbmQgaXMgaGFuZGxlZCBieSBhcGktc2VydmVyJ3MgYHdyaXRlLXBpbi50c2AsIHdoaWNoIHJlbWVtYmVycyBpbiBSZWRpc1xuICAgKiB0aGF0IGFuIG9yZyB3cm90ZSByZWNlbnRseSBhbmQgUFJFLVNFVFMgdGhpcyBzYW1lIGZsYWcgb24gdGhlIG5leHRcbiAgICogcmVxdWVzdCdzIGNvbnRleHQg4oCUIG9uZSBtZWNoYW5pc20gYW5kIG9uZSBjb2RlIHBhdGggcmF0aGVyIHRoYW4gdHdvLiBJdFxuICAgKiBmYWlscyBjbG9zZWQgKG5vIFJlZGlzLCBvciBhbiB1bnJlYWNoYWJsZSBvbmUsIHJvdXRlcyByZWFkcyB0byB0aGUgcHJpbWFyeSlcbiAgICogYW5kIHNob3J0LWNpcmN1aXRzIGVudGlyZWx5IHdoZW4gbm8gcmVhZCByZXBsaWNhIGlzIGNvbmZpZ3VyZWQuXG4gICAqL1xuICBtYXlIYXZlV3JpdHRlbj86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUGVyLXJlcXVlc3QgdGVuYW50IGNvbnRleHQuIFBvcHVsYXRlZCBieSBFeHByZXNzIG1pZGRsZXdhcmUgb25jZSB0aGUgSldUXG4gKiBpcyB2YWxpZGF0ZWQ7IGNvbnN1bWVkIGJ5IGB3aXRoVGVuYW50VHhgIGFuZCBhbnkgaGVscGVyIHRoYXQgbmVlZHMgdG9cbiAqIGtub3cgXCJ3aG8gaXMgdGhlIGNhbGxlclwiIHdpdGhvdXQgcmUtZGVyaXZpbmcgZnJvbSB0aGUgcmVxdWVzdCBvYmplY3QuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5hbnRDb250ZXh0ID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlPFRlbmFudENvbnRleHQ+KCk7XG5cbi8qKlxuICogUnVuIGBmbmAgaW5zaWRlIHRoZSBnaXZlbiB0ZW5hbnQgc2NvcGUuIFRoZSBBc3luY0xvY2FsU3RvcmFnZSBzY29wZVxuICogc3Vydml2ZXMgYWNyb3NzIGFzeW5jIGJvdW5kYXJpZXMgKFByb21pc2VzLCBzZXRUaW1lb3V0LCBldGMuKSwgc28gYW55XG4gKiBgd2l0aFRlbmFudFR4YCBjYWxsIGluc2lkZSBgZm5gIOKAlCBkaXJlY3RseSBvciB0aHJvdWdoIGFueSBkZXB0aCBvZlxuICogYXN5bmMgaGVscGVycyDigJQgcGlja3MgdXAgYGN0eGAuXG4gKlxuICogV3JhcCBgbmV4dCgpYCBmcm9tIGFuIEV4cHJlc3MgbWlkZGxld2FyZSB0byBlc3RhYmxpc2ggcGVyLXJlcXVlc3Qgc2NvcGU6XG4gKlxuICogICAgIGFwcC51c2UoKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gKiAgICAgICBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW4gfSwgKCkgPT4gbmV4dCgpKTtcbiAqICAgICB9KTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJ1bldpdGhUZW5hbnRDb250ZXh0PFQ+KGN0eDogVGVuYW50Q29udGV4dCwgZm46ICgpID0+IFQpOiBUIHtcbiAgcmV0dXJuIHRlbmFudENvbnRleHQucnVuKGN0eCwgZm4pO1xufVxuXG4vKiogUmVhZCB0aGUgY3VycmVudCB0ZW5hbnQgY29udGV4dC4gUmV0dXJucyB1bmRlZmluZWQgb3V0c2lkZSBhblxuICogIGBydW5XaXRoVGVuYW50Q29udGV4dGAgc2NvcGUgKGUuZy4gYmFja2dyb3VuZCB3b3JrZXJzLCBtaWdyYXRpb25zKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUZW5hbnRDb250ZXh0KCk6IFRlbmFudENvbnRleHQgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdGVuYW50Q29udGV4dC5nZXRTdG9yZSgpO1xufVxuXG4vKipcbiAqIE9wZW4gYSB0cmFuc2FjdGlvbiB3aXRoIFJMUyBHVUNzIFNFVCBMT0NBTCBmcm9tIHRoZSBjdXJyZW50XG4gKiBBc3luY0xvY2FsU3RvcmFnZSB0ZW5hbnQgY29udGV4dCwgdGhlbiBpbnZva2UgYGZuKHR4KWAuXG4gKlxuICogLSBXaGVuIGNhbGxlZCBvdXRzaWRlIGEgdGVuYW50IHNjb3BlIChlLmcuIGZyb20gYSBiYWNrZ3JvdW5kIGpvYiB0aGF0XG4gKiAgIGRvZXNuJ3QgaGF2ZSBhIGNhbGxlciBpZGVudGl0eSksIHRoZSB0cmFuc2FjdGlvbiBpcyBvcGVuZWQgd2l0aCBib3RoXG4gKiAgIEdVQ3MgY2xlYXJlZCDigJQgUkxTIHBvbGljaWVzIHdpbGwgcmV0dXJuIHplcm8gcm93cyBvbiBGT1JDRSdkIHRhYmxlcy5cbiAqICAgQ2FsbGVycyB0aGF0IG5lZWQgYSBzeXNhZG1pbi1lcXVpdmFsZW50IHNjb3BlIHNob3VsZCB3cmFwIHRoZW1zZWx2ZXMgaW5cbiAqICAgYHJ1bldpdGhUZW5hbnRDb250ZXh0KHsgaXNTdXBlckFkbWluOiB0cnVlIH0sIOKApilgIGV4cGxpY2l0bHkuXG4gKlxuICogLSBVc2VzIGBzZXRfY29uZmlnKGtleSwgdmFsdWUsIHRydWUpYCAodGhlIGJvb2xlYW4gPSBgaXNfbG9jYWxgLCBpLmUuXG4gKiAgIHRyYW5zYWN0aW9uLXNjb3BlZCkuIEVxdWl2YWxlbnQgdG8gYFNFVCBMT0NBTGAgYnV0IHRha2VzIHRoZSB2YWx1ZSBhc1xuICogICBhIHBhcmFtZXRlciwgd2hpY2ggaXMgd2hhdCB3ZSB3YW50IOKAlCBEcml6emxlJ3MgYHNxbGAgdGVtcGxhdGUgYmluZHMgdGhlXG4gKiAgIHZhbHVlIHNhZmVseSBzbyBhbiBhdHRhY2tlci1jb250cm9sbGVkIGBvcmdJZGAgY2FuJ3QgZXNjYXBlIHRoZSBxdW90aW5nLlxuICpcbiAqIC0gUmV0dXJucyB3aGF0ZXZlciBgZm5gIHJldHVybnM7IHRocm93cyB3aGF0ZXZlciBgZm5gIHRocm93cyAoRHJpenpsZVxuICogICBoYW5kbGVzIHRoZSBDT01NSVQvUk9MTEJBQ0sgZm9yIHVzKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhUZW5hbnRUeDxUPihcbiAgZm46ICh0eDogUGFyYW1ldGVyczxQYXJhbWV0ZXJzPHR5cGVvZiBkYi50cmFuc2FjdGlvbj5bMF0+WzBdKSA9PiBQcm9taXNlPFQ+LFxuICAvKipcbiAgICogSU5URVJOQUwuIFdoZXRoZXIgdGhpcyB0cmFuc2FjdGlvbiBzaG91bGQgbWFyayB0aGUgcmVxdWVzdCBhcyBwb3NzaWJseVxuICAgKiBoYXZpbmcgd3JpdHRlbi4gQWx3YXlzIHRydWUgZm9yIGEgcmVhbCBjYWxsZXI7IG9ubHkgd2l0aFRlbmFudFR4UmVhZCdzXG4gICAqIHByaW1hcnktZmFsbGJhY2sgcGF0aCBwYXNzZXMgZmFsc2UsIGJlY2F1c2UgYSByZWFkIHRoYXQgbGFuZHMgb24gdGhlXG4gICAqIHByaW1hcnkgaGFzIG5vdCB3cml0dGVuLiBTZWUgdGhlIGNvbW1lbnQgYXQgdGhlIGFzc2lnbm1lbnQgYmVsb3cuXG4gICAqL1xuICBtYXJrV3JpdHRlbiA9IHRydWUsXG4pOiBQcm9taXNlPFQ+IHtcbiAgY29uc3QgY3R4ID0gdGVuYW50Q29udGV4dC5nZXRTdG9yZSgpO1xuXG4gIGlmICghY3R4KSB7XG4gICAgLy8gU3VyZmFjZSB0aGUgYnVnIGluc3RlYWQgb2Ygc2lsZW50bHkgU0VUJ2luZyBlbXB0eSBHVUNzLiBUaGUgZGVmYXVsdFxuICAgIC8vIG1vZGUgKCd3YXJuJykgbG9ncyBhbiBhY3Rpb25hYmxlIHRyYWNlIHNvIHRoZSBiYWQgY2FsbCBzaXRlIGlzIGVhc3lcbiAgICAvLyB0byBmaW5kOyBwcm9kdWN0aW9uIGRlcGxveW1lbnRzIHRoYXQgaGF2ZSBmaW5pc2hlZCB0aGUgYXVkaXQgY2FuIHNldFxuICAgIC8vIFJMU19DT05URVhUX01PREU9c3RyaWN0IHRvIGZhaWwtZmFzdCBhdCB0aGUgY2FsbCBzaXRlIChiZXR0ZXIgc3RhY2tcbiAgICAvLyB0cmFjZSB0aGFuIHRoZSBQb3N0Z3JlcyBcInBlcm1pc3Npb24gZGVuaWVkXCIgdGhhdCB3b3VsZCBvdGhlcndpc2VcbiAgICAvLyBzdXJmYWNlIGZyb20gRk9SQ0UnZCBSTFMpLlxuICAgIGNvbnN0IG1vZGUgPSBnZXRDb250ZXh0TW9kZSgpO1xuICAgIGlmIChtb2RlID09PSAnc3RyaWN0Jykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnd2l0aFRlbmFudFR4IGNhbGxlZCBvdXRzaWRlIGEgdGVuYW50IHNjb3BlLiBXcmFwIHlvdXIgaGFuZGxlci93b3JrZXIgJ1xuICAgICAgICArICdpbiBydW5XaXRoVGVuYW50Q29udGV4dCh7IG9yZ0lkLCBpc1N1cGVyQWRtaW4gfSwgLi4uKSBiZWZvcmUgaW52b2tpbmcgJ1xuICAgICAgICArICdhbnkgc2VydmljZSB0aGF0IHRvdWNoZXMgUkxTLWVuZm9yY2VkIHRhYmxlcy4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKG1vZGUgPT09ICd3YXJuJykge1xuICAgICAgLy8gSW5jbHVkZSBhIHN5bnRoZXRpYyBzdGFjayBzbyB0aGUgb2ZmZW5kaW5nIGNhbGwgc2l0ZSBpcyBpbiB0aGUgbG9nLlxuICAgICAgbG9nZ2VyLndhcm4oJ3dpdGhUZW5hbnRUeCBjYWxsZWQgb3V0c2lkZSBhIHRlbmFudCBzY29wZTsgUkxTIEdVQ3Mgd2lsbCBiZSBlbXB0eScsIHtcbiAgICAgICAgc3RhY2s6IG5ldyBFcnJvcigndGVuYW50LWNvbnRleHQgbWlzc2luZycpLnN0YWNrLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgb3JnSWQgPSBjdHg/Lm9yZ0lkID8/ICcnO1xuICBjb25zdCBpc1N1cGVyQWRtaW4gPSBjdHg/LmlzU3VwZXJBZG1pbiA/ICd0cnVlJyA6ICdmYWxzZSc7XG5cbiAgY29uc3Qgc3RhdGVtZW50VGltZW91dE1zID0gZ2V0U3RhdGVtZW50VGltZW91dE1zKCk7XG5cbiAgLy8gVGhpcyB0cmFuc2FjdGlvbiBydW5zIG9uIHRoZSBQUklNQVJZIGFuZCBtYXkgd3JpdGUsIHNvIGFueSBsYXRlciByZWFkIGluXG4gIC8vIHRoaXMgcmVxdWVzdCBtdXN0IHN0YXkgb24gdGhlIHByaW1hcnkgdG9vLiBTZXQgYmVmb3JlIHRoZSB0cmFuc2FjdGlvbiBvcGVuc1xuICAvLyByYXRoZXIgdGhhbiBhZnRlciBpdCBjb21taXRzOiBhIHJlYWQgaXNzdWVkIGNvbmN1cnJlbnRseSBmcm9tIHRoZSBzYW1lXG4gIC8vIGhhbmRsZXIgd291bGQgb3RoZXJ3aXNlIHJhY2UgdGhlIGZsYWcuXG4gIC8vXG4gIC8vIGBtYXJrV3JpdHRlbjogZmFsc2VgIGlzIHBhc3NlZCBPTkxZIGJ5IHdpdGhUZW5hbnRUeFJlYWQncyBmYWxsYmFjayBwYXRoLFxuICAvLyBhbmQgaXQgaXMgbm90IGFuIG9wdGltaXNhdGlvbiDigJQgd2l0aG91dCBpdCB0aGUgZmVhdHVyZSBkZWZlYXRzIGl0c2VsZi4gVGhhdFxuICAvLyBwYXRoIHJ1bnMgb24gdGhlIHByaW1hcnksIHNvIGl0IHdvdWxkIHNldCB0aGlzIGZsYWcsIHdoaWNoIGFwaS1zZXJ2ZXInc1xuICAvLyBtaWRkbGV3YXJlIHJlYWRzIGFmdGVyIHRoZSByZXNwb25zZSB0byBzZXQgdGhlIFJlZGlzIHdyaXRlIHBpbi4gQSBwdXJlbHlcbiAgLy8gUkVBRC1PTkxZIHJlcXVlc3Qgd291bGQgdGhlcmVmb3JlIHBpbiBpdHMgd2hvbGUgb3JnIHRvIHRoZSBwcmltYXJ5IGZvciB0aGVcbiAgLy8gcGluIFRUTCwgZXZlcnkgdGltZSwgYW5kIHNpbmNlIHJlYWRzIGZhbGwgYmFjayB3aGVuZXZlciBubyByZXBsaWNhIGlzXG4gIC8vIGNvbmZpZ3VyZWQgKHRoZSBzaGlwcGluZyBkZWZhdWx0KSBldmVyeSBvcmcgd291bGQgYmUgcGVybWFuZW50bHkgcGlubmVkLlxuICAvLyBUaGUgZmxhZyBtZWFucyBcInRoaXMgcmVxdWVzdCBtYXkgaGF2ZSBXUklUVEVOXCIsIG5vdCBcInRoaXMgcmVxdWVzdCB0b3VjaGVkXG4gIC8vIHRoZSBwcmltYXJ5XCIsIGFuZCB0aGUgZGlmZmVyZW5jZSBpcyB0aGUgd2hvbGUgcmVhZC1vZmZsb2FkIGJlbmVmaXQuXG4gIGlmIChjdHggJiYgbWFya1dyaXR0ZW4pIGN0eC5tYXlIYXZlV3JpdHRlbiA9IHRydWU7XG5cbiAgcmV0dXJuIGRiLnRyYW5zYWN0aW9uKGFzeW5jICh0eCkgPT4ge1xuICAgIC8vIFNldCBldmVyeSB0cmFuc2FjdGlvbi1zY29wZWQgR1VDIGluIGEgU0lOR0xFIHJvdW5kLXRyaXAuIGBzZXRfY29uZmlnKClgXG4gICAgLy8gcmV0dXJucyBpdHMgdmFsdWUsIHNvIG11bHRpcGxlIGNhbGxzIGNvbXBvc2UgaW4gb25lIFNFTEVDVCByYXRoZXIgdGhhbiBhXG4gICAgLy8gcm91bmQtdHJpcCBwZXIgR1VDIOKAlCBlYWNoIGEgbmV0d29yayBob3AgdGhhdCB0YXhlcyB0aGUgc2hhcmVkIFBnQm91bmNlclxuICAgIC8vIHBvb2wgb24gdGhlIGhvdCBwYXRoLiBgdHJ1ZWBcbiAgICAvLyA9IGlzX2xvY2FsIChTRVQgTE9DQUwgc2VtYW50aWNzOiBhdXRvLXJlbGVhc2VkIG9uIENPTU1JVC9ST0xMQkFDSykuIFRoZVxuICAgIC8vIGRyaXZlciBiaW5kcyB0aGUgdmFsdWVzIGFzIHBhcmFtZXRlcnMsIHNvIGEgaG9zdGlsZSBvcmdfaWQgY2FuJ3QgYnJlYWsgb3V0XG4gICAgLy8gb2YgdGhlIEdVQyBzeW50YXguXG4gICAgLy9cbiAgICAvLyBUaGUgc3RhdGVtZW50X3RpbWVvdXQgR1VDIGJvdW5kcyBhIHJ1bmF3YXkgcXVlcnkgc28gaXQgY2FuJ3QgaG9sZCBhIHBvb2xlZFxuICAgIC8vIGNvbm5lY3Rpb24gb3BlbiBpbmRlZmluaXRlbHkgKGBTRVQgTE9DQUwgc3RhdGVtZW50X3RpbWVvdXQgPSAkMWAgaXMgcmVqZWN0ZWRcbiAgICAvLyBieSBQb3N0Z3JlcywgaGVuY2Ugc2V0X2NvbmZpZyB3aXRoIGEgYm91bmQgbXMgdmFsdWUpLiBJbmNsdWRlZCBpbiB0aGUgc2FtZVxuICAgIC8vIHN0YXRlbWVudCB3aGVuIGVuYWJsZWQgKD4wKSwgZHJvcHBlZCBlbnRpcmVseSB3aGVuIGRpc2FibGVkICgwKS5cbiAgICBpZiAoc3RhdGVtZW50VGltZW91dE1zID4gMCkge1xuICAgICAgYXdhaXQgdHguZXhlY3V0ZShcbiAgICAgICAgc3FsYFNFTEVDVCBzZXRfY29uZmlnKCdhcHAub3JnX2lkJywgJHtvcmdJZH0sIHRydWUpLCBzZXRfY29uZmlnKCdhcHAuaXNfc3lzYWRtaW4nLCAke2lzU3VwZXJBZG1pbn0sIHRydWUpLCBzZXRfY29uZmlnKCdzdGF0ZW1lbnRfdGltZW91dCcsICR7U3RyaW5nKHN0YXRlbWVudFRpbWVvdXRNcyl9LCB0cnVlKWAsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCB0eC5leGVjdXRlKFxuICAgICAgICBzcWxgU0VMRUNUIHNldF9jb25maWcoJ2FwcC5vcmdfaWQnLCAke29yZ0lkfSwgdHJ1ZSksIHNldF9jb25maWcoJ2FwcC5pc19zeXNhZG1pbicsICR7aXNTdXBlckFkbWlufSwgdHJ1ZSlgLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGZuKHR4KTtcbiAgfSk7XG59XG5cbi8qKlxuICogV2h5IGEgcmVhZCB3YXMgb3Igd2FzIG5vdCBzZW50IHRvIHRoZSByZXBsaWNhLiBSZXR1cm5lZCBieVxuICoge0BsaW5rIGNob29zZVJlYWRUYXJnZXR9IHNvIHRoZSBkZWNpc2lvbiBpcyBpbnNwZWN0YWJsZSDigJQgYW5kIHRlc3RhYmxlXG4gKiB3aXRob3V0IGEgcmVwbGljYSwgd2hpY2ggbWF0dGVycyBiZWNhdXNlIHRoZSB0ZXN0IHN1YnN0cmF0ZSAoUEdsaXRlKSBoYXMgbm9cbiAqIHJlcGxpY2F0aW9uIGF0IGFsbC5cbiAqL1xuZXhwb3J0IHR5cGUgUmVhZFRhcmdldFJlYXNvbiA9XG4gIC8qKiBObyByZXBsaWNhIGNvbmZpZ3VyZWQsIG9yIERCX1JFQURfRU5BQkxFRD1mYWxzZS4gKi9cbiAgfCAnbm8tcmVwbGljYSdcbiAgLyoqIFRoaXMgcmVxdWVzdCBhbHJlYWR5IG9wZW5lZCBhIHByaW1hcnkgdHJhbnNhY3Rpb24gYW5kIG1heSBoYXZlIHdyaXR0ZW4uICovXG4gIHwgJ21heS1oYXZlLXdyaXR0ZW4nXG4gIC8qKlxuICAgKiBObyB0ZW5hbnQgY29udGV4dC4gQSBjYWxsZXIgb3V0c2lkZSBgcnVuV2l0aFRlbmFudENvbnRleHRgIGhhcyBubyBvcmcgdG9cbiAgICogc2NvcGUgUkxTIGJ5IGFuZCBubyB3YXRlcm1hcmsgdG8gY29tcGFyZSwgc28gaXQgZ29lcyB0byB0aGUgcHJpbWFyeSDigJQgd2hlcmVcbiAgICogYHdpdGhUZW5hbnRUeGAncyBSTFNfQ09OVEVYVF9NT0RFIGd1YXJkIGxvZ3Mgb3IgdGhyb3dzLiBSb3V0ZWQgdG8gYSByZXBsaWNhXG4gICAqIGluc3RlYWQsIHRoZSBzYW1lIGNhbGwgd291bGQgc2V0IGBhcHAub3JnX2lkID0gJydgIHdpdGggbm8gZGlhZ25vc3RpYyBhdCBhbGwuXG4gICAqL1xuICB8ICduby1jb250ZXh0J1xuICAvKipcbiAgICogQSByZXBsaWNhIGV4aXN0cyBidXQgaXRzIHJlcGxheSBsYWcgaXMgYmV5b25kIGBEQl9SRUFEX01BWF9MQUdfU0VDT05EU2AsXG4gICAqIG9yIGlzIFVOS05PV04gKG5vIHNhbXBsZSB5ZXQsIHRoZSBzYW1wbGUgZmFpbGVkLCBvciB0aGUgY2FjaGVkIHNhbXBsZSBoYXNcbiAgICogZ29uZSBzdGFsZSkuIFVua25vd24gYW5kIGxhZ2dpbmcgYXJlIHRoZSBzYW1lIGRlY2lzaW9uIG9uIHB1cnBvc2U6IHRoZVxuICAgKiBjaXJjdWl0IGZhaWxzIGNsb3NlZC5cbiAgICovXG4gIHwgJ3JlcGxpY2EtbGFnZ2luZydcbiAgLyoqIFJvdXRlZCB0byB0aGUgcmVwbGljYS4gKi9cbiAgfCAncmVwbGljYSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVhZFRhcmdldCB7XG4gIHVzZVJlcGxpY2E6IGJvb2xlYW47XG4gIHJlYXNvbjogUmVhZFRhcmdldFJlYXNvbjtcbn1cblxuLyoqXG4gKiBEZWNpZGUgd2hlcmUgYSByZWFkLW9ubHkgdHJhbnNhY3Rpb24gc2hvdWxkIHJ1bi5cbiAqXG4gKiBQdXJlIGFuZCBzaWRlLWVmZmVjdCBmcmVlIG9uIHB1cnBvc2U6IHRoaXMgaXMgdGhlIHdob2xlIG9mIHRoZSByb3V0aW5nXG4gKiBwb2xpY3ksIGFuZCBpdCBpcyB0aGUgcGFydCB3b3J0aCB0ZXN0aW5nLiBSZXBsaWNhdGlvbiBpdHNlbGYgY2Fubm90IGJlXG4gKiByZXByb2R1Y2VkIGxvY2FsbHksIHNvIHRoZSB0ZXN0YWJsZSB1bml0IGlzIHRoZSBERUNJU0lPTiwgbm90IHRoZSBsYWcuXG4gKlxuICogVGhlIGJpYXMgaXMgZGVsaWJlcmF0ZTogYW55dGhpbmcgdW5jZXJ0YWluIHJlc29sdmVzIHRvIHRoZSBwcmltYXJ5LiBBIHJlYWRcbiAqIHNlcnZlZCBieSB0aGUgcHJpbWFyeSBpcyBtZXJlbHkgbGVzcyBlZmZpY2llbnQ7IGEgcmVhZCBzZXJ2ZWQgYnkgYSBzdGFsZVxuICogcmVwbGljYSBpcyBhIHVzZXItdmlzaWJsZSBidWcgbm9ib2R5IGNhbiByZXByb2R1Y2UuXG4gKi9cbi8qKiBFdmVyeXRoaW5nIGFib3V0IHRoZSByZXBsaWNhIHRoYXQgaXMgbm90IHJlcXVlc3Qtc3BlY2lmaWMuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlYWRSZXBsaWNhSGVhbHRoIHtcbiAgLyoqIEEgcmVwbGljYSBwb29sIGV4aXN0cyBBTkQgYERCX1JFQURfRU5BQkxFRGAgaXMgbm90IGZhbHNlLiAqL1xuICBhdmFpbGFibGU6IGJvb2xlYW47XG4gIC8qKiBUaGUgbGFnIGNpcmN1aXQncyB2ZXJkaWN0LiBgdW5rbm93bmAgaXMgdHJlYXRlZCBleGFjdGx5IGxpa2UgYGxhZ2dpbmdgLiAqL1xuICBsYWc6IExhZ1ZlcmRpY3Q7XG59XG5cbi8qKlxuICogV2hlcmUgYSByZWFkIGdvZXMsIGFuZCB3aHkuXG4gKlxuICogU1lTVEVNIGdhdGVzIGFyZSBjaGVja2VkIGJlZm9yZSBSRVFVRVNUIGdhdGVzLCB3aGljaCBtYXR0ZXJzIG9ubHkgZm9yIHRoZVxuICogZXhwbGFuYXRpb24g4oCUIGJ1dCB0aGUgZXhwbGFuYXRpb24gaXMgd2hhdCBhbiBvcGVyYXRvciByZWFkcyB3aGVuIGFza2luZyB3aHlcbiAqIHRoZSByZXBsaWNhIGlzIGlkbGUsIGFuZCBcIm15IHJlcXVlc3Qgd3JvdGVcIiBpcyBhIGZhciBsZXNzIHVzZWZ1bCBhbnN3ZXIgdGhhblxuICogXCJ0aGUgc3RhbmRieSBpcyA0MCBzZWNvbmRzIGJlaGluZFwiLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hvb3NlUmVhZFRhcmdldChjdHg6IFRlbmFudENvbnRleHQgfCB1bmRlZmluZWQsIGhlYWx0aDogUmVhZFJlcGxpY2FIZWFsdGgpOiBSZWFkVGFyZ2V0IHtcbiAgaWYgKCFoZWFsdGguYXZhaWxhYmxlKSByZXR1cm4geyB1c2VSZXBsaWNhOiBmYWxzZSwgcmVhc29uOiAnbm8tcmVwbGljYScgfTtcbiAgaWYgKGhlYWx0aC5sYWcgIT09ICdvaycpIHJldHVybiB7IHVzZVJlcGxpY2E6IGZhbHNlLCByZWFzb246ICdyZXBsaWNhLWxhZ2dpbmcnIH07XG4gIGlmICghY3R4KSByZXR1cm4geyB1c2VSZXBsaWNhOiBmYWxzZSwgcmVhc29uOiAnbm8tY29udGV4dCcgfTtcbiAgaWYgKGN0eC5tYXlIYXZlV3JpdHRlbikgcmV0dXJuIHsgdXNlUmVwbGljYTogZmFsc2UsIHJlYXNvbjogJ21heS1oYXZlLXdyaXR0ZW4nIH07XG4gIHJldHVybiB7IHVzZVJlcGxpY2E6IHRydWUsIHJlYXNvbjogJ3JlcGxpY2EnIH07XG59XG5cbi8qKlxuICogT3BlbiBhIFJFQUQtT05MWSB0cmFuc2FjdGlvbiB3aXRoIHRoZSBzYW1lIFJMUyBHVUNzIGB3aXRoVGVuYW50VHhgIHNldHMsXG4gKiByb3V0ZWQgdG8gdGhlIHJlcGxpY2Egd2hlbiB7QGxpbmsgY2hvb3NlUmVhZFRhcmdldH0gYWxsb3dzIGl0LlxuICpcbiAqIGBTRVQgVFJBTlNBQ1RJT04gUkVBRCBPTkxZYCBpcyB0aGUgZ3VhcmRyYWlsLCBub3QgZGVjb3JhdGlvbi4gU2V2ZXJhbCBxdWVyaWVzXG4gKiBpbiB0aGlzIGNvZGViYXNlIGxvb2sgbGlrZSByZWFkcyBhdCB0aGUgY2FsbCBzaXRlIGFuZCBhcmUgbm90IOKAlFxuICogYFNFTEVDVCDigKYgRk9SIFVQREFURWAgaW4gY3J1ZC1zZXJ2aWNlJ3Mgc2V0RGVmYXVsdCwgYHBnX2Fkdmlzb3J5X3hhY3RfbG9ja2BcbiAqIGluIHBpcGVsaW5lLXNlcnZpY2UgYW5kIGNvbXBsaWFuY2UncyBzdWJzY3JpcHRpb24tc2VydmljZS4gUm91dGVkIHRvIGFcbiAqIHN0YW5kYnkgdGhvc2UgZmFpbCBhbnl3YXk7IGRlY2xhcmluZyB0aGUgdHJhbnNhY3Rpb24gcmVhZC1vbmx5IG1ha2VzIHRoZW1cbiAqIGZhaWwgSEVSRSwgd2l0aCBhIGNsZWFyIG1lc3NhZ2UsIGluY2x1ZGluZyBvbiB0aGUgcHJpbWFyeSB3aGVyZSB0aGV5IHdvdWxkXG4gKiBvdGhlcndpc2Ugc3VjY2VlZCBhbmQgcXVpZXRseSBhY3F1aXJlIGEgbG9jayB0aGUgY2FsbGVyIGRpZCBub3QgaW50ZW5kLlxuICpcbiAqIEZhbGxzIGJhY2sgdG8gdGhlIHByaW1hcnkgdHJhbnNwYXJlbnRseSwgc28gYSBjYWxsZXIgbmV2ZXIgaGFzIHRvIGFza1xuICogd2hldGhlciBhIHJlcGxpY2EgZXhpc3RzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd2l0aFRlbmFudFR4UmVhZDxUPihcbiAgZm46ICh0eDogUGFyYW1ldGVyczxQYXJhbWV0ZXJzPHR5cGVvZiBkYi50cmFuc2FjdGlvbj5bMF0+WzBdKSA9PiBQcm9taXNlPFQ+LFxuKTogUHJvbWlzZTxUPiB7XG4gIGNvbnN0IGN0eCA9IHRlbmFudENvbnRleHQuZ2V0U3RvcmUoKTtcbiAgY29uc3QgcmVhZERiID0gZ2V0UmVhZERiKCk7XG4gIGNvbnN0IHJlYWRQb29sID0gZ2V0UmVhZFBvb2woKTtcblxuICAvLyBLZWVwIHRoZSBsYWcgc2FtcGxlIHdhcm0uIEZpcmUtYW5kLWZvcmdldCBieSBkZXNpZ246IGl0IGlzIGRlYm91bmNlZCB0b1xuICAvLyBEQl9SRUFEX0xBR19TQU1QTEVfTVMsIG5ldmVyIHRocm93cywgYW5kIG11c3Qgbm90IGFkZCBhIHJvdW5kLXRyaXAgdG8gdGhpc1xuICAvLyByZWFkLiBUaGUgZmlyc3QgcmVhZCBvZiBhIHByb2Nlc3MgdGhlcmVmb3JlIHJvdXRlcyB0byB0aGUgcHJpbWFyeSAobm9cbiAgLy8gc2FtcGxlIHlldCkgYW5kIHdhcm1zIHRoZSBjaXJjdWl0IGZvciB0aGUgb25lcyBhZnRlciBpdC5cbiAgaWYgKHJlYWRQb29sKSB2b2lkIG1heWJlU2FtcGxlTGFnKHJlYWRQb29sKTtcblxuICBjb25zdCB0YXJnZXQgPSBjaG9vc2VSZWFkVGFyZ2V0KGN0eCwgeyBhdmFpbGFibGU6IHJlYWREYiAhPT0gbnVsbCwgbGFnOiBsYWdWZXJkaWN0KCkgfSk7XG4gIGVtaXRDb3VudGVyKCdwb3N0Z3Jlc19yZWFkX3JvdXRlZF90b3RhbCcsIHsgdGFyZ2V0OiB0YXJnZXQudXNlUmVwbGljYSA/ICdyZXBsaWNhJyA6ICdwcmltYXJ5JywgcmVhc29uOiB0YXJnZXQucmVhc29uIH0pO1xuXG4gIGlmICghdGFyZ2V0LnVzZVJlcGxpY2EpIHtcbiAgICAvLyBQcmltYXJ5IHBhdGg6IGlkZW50aWNhbCBzZW1hbnRpY3MgdG8gd2l0aFRlbmFudFR4LCBwbHVzIHRoZSByZWFkLW9ubHlcbiAgICAvLyBkZWNsYXJhdGlvbiBzbyBhbiBhY2NpZGVudGFsIHdyaXRlIGlzIGNhdWdodCBvbiBldmVyeSB0YXJnZXQg4oCUIGluY2x1ZGluZ1xuICAgIC8vIHRoZSBvbmVzIHRoYXQgd2lsbCBuZXZlciBoYXZlIGEgcmVwbGljYS5cbiAgICByZXR1cm4gd2l0aFRlbmFudFR4KGFzeW5jICh0eCkgPT4ge1xuICAgICAgYXdhaXQgdHguZXhlY3V0ZShzcWxgU0VUIFRSQU5TQUNUSU9OIFJFQUQgT05MWWApO1xuICAgICAgcmV0dXJuIGZuKHR4KTtcbiAgICB9LCAvKiBtYXJrV3JpdHRlbiAqLyBmYWxzZSk7XG4gIH1cblxuICAvLyBOb24tbnVsbCBieSBjb25zdHJ1Y3Rpb246IGNob29zZVJlYWRUYXJnZXQgb25seSByZXR1cm5zIHVzZVJlcGxpY2EgZm9yIGFcbiAgLy8gY3R4IHRoYXQgZXhpc3RzLiBSZWFkIHRoZSBHVUNzIG9mZiBpdCBkaXJlY3RseSByYXRoZXIgdGhhbiBkZWZhdWx0aW5nIHRvXG4gIC8vICcnIOKAlCBhIGRlZmF1bHQgaGVyZSB3b3VsZCBzaWxlbnRseSByZS1vcGVuIHRoZSBob2xlIHRoYXQgJ25vLWNvbnRleHQnXG4gIC8vIGNsb3NlcywgYmVjYXVzZSBhbiBlbXB0eSBhcHAub3JnX2lkIGlzIGEgVkFMSUQtbG9va2luZyBSTFMgc2NvcGUuXG4gIGNvbnN0IHsgb3JnSWQgfSA9IGN0eCE7XG4gIGNvbnN0IGlzU3VwZXJBZG1pbiA9IGN0eCEuaXNTdXBlckFkbWluID8gJ3RydWUnIDogJ2ZhbHNlJztcbiAgY29uc3Qgc3RhdGVtZW50VGltZW91dE1zID0gZ2V0U3RhdGVtZW50VGltZW91dE1zKCk7XG5cbiAgcmV0dXJuIHJlYWREYiEudHJhbnNhY3Rpb24oYXN5bmMgKHR4KSA9PiB7XG4gICAgYXdhaXQgdHguZXhlY3V0ZShzcWxgU0VUIFRSQU5TQUNUSU9OIFJFQUQgT05MWWApO1xuICAgIGlmIChzdGF0ZW1lbnRUaW1lb3V0TXMgPiAwKSB7XG4gICAgICBhd2FpdCB0eC5leGVjdXRlKFxuICAgICAgICBzcWxgU0VMRUNUIHNldF9jb25maWcoJ2FwcC5vcmdfaWQnLCAke29yZ0lkfSwgdHJ1ZSksIHNldF9jb25maWcoJ2FwcC5pc19zeXNhZG1pbicsICR7aXNTdXBlckFkbWlufSwgdHJ1ZSksIHNldF9jb25maWcoJ3N0YXRlbWVudF90aW1lb3V0JywgJHtTdHJpbmcoc3RhdGVtZW50VGltZW91dE1zKX0sIHRydWUpYCxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHR4LmV4ZWN1dGUoXG4gICAgICAgIHNxbGBTRUxFQ1Qgc2V0X2NvbmZpZygnYXBwLm9yZ19pZCcsICR7b3JnSWR9LCB0cnVlKSwgc2V0X2NvbmZpZygnYXBwLmlzX3N5c2FkbWluJywgJHtpc1N1cGVyQWRtaW59LCB0cnVlKWAsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZm4odHgpO1xuICB9KTtcbn1cbiJdfQ==
package/lib/index.d.ts CHANGED
@@ -30,17 +30,21 @@ export * from './api/crud-service.js';
30
30
  export { parseSemver, compareSemverParts, compareSemver, isVersionRange, satisfiesVersionSpec, semverOrderBy, } from './api/semver-range.js';
31
31
  export { normalizeQuery, searchPublicListings, listPublicCategories, getPublicListing, getPublicListedVersion, listPublicReviews, listPublicListingsForSitemap, type DirectoryTrustTier, type DirectorySort, DIRECTORY_SORTS, DIRECTORY_TIERS, type DirectorySearchParams, type ReviewSort, REVIEW_SORTS, type PublicListingRow, } from './api/public-directory.js';
32
32
  export { listEnabledAlertDestinations, type NotificationDestination, } from './api/alert-destinations.js';
33
+ export { anonymizeReviewsByAuthor } from './api/ecosystem-privacy.js';
34
+ export { openSupportCase, findCaseByThread, listQueue, listOrgCases, stampFirstResponse, setCaseStatus, setCaseSeverity, assignCase, assignCases, closeCases, transferCaseToContact, openCasesForContact, SUPPORT_CASE_STATUSES, QUEUE_STATUSES, type SupportCaseStatus, type OpenCaseInput, countActiveSupportContacts, listActiveSupportContacts, isSupportContact, designateSupportContact, revokeSupportContact, countPremiumSupportContacts, isPremiumSupportContact, setSupportContactPremium, countCasesInWindow, rateCase, addCaseNote, listCaseNotes, deleteCaseNote, type SupportCaseNote, listCannedResponses, createCannedResponse, updateCannedResponse, deleteCannedResponse, type CannedResponse, listCasesDueForPage, } from './api/support-cases.js';
33
35
  export { policyOf, effectiveConsumptionPolicy, applyPolicyUpdate, type ConsumptionPolicy, DEFAULT_CONSUMPTION_POLICY, } from './api/plugin-consumption-policy.js';
34
36
  export { advisoryRangeCovers, advisoryRangeProblem, advisoriesCovering, blockingAdvisories, } from './api/plugin-advisories.js';
35
- export { listingBlock, implicitInstallRange, installAdmits, scopeOrgIds, installModeFor, drizzleListingSource, resolveListingReference, listedVersionWarnings, listedPluginRecord, loadOrgInstallContext, orgListingStates, resolvableListings, type ResolutionRefusal, type ResolutionScope, type ListingDataSource, type ListingResolved, type OrgListingState, } from './api/plugin-resolution.js';
37
+ export { listingBlock, implicitInstallRange, installAdmits, scopeOrgIds, installModeFor, drizzleListingSource, resolveListingReference, listedVersionWarnings, listedPluginRecord, loadOrgInstallContext, orgListingStates, resolvableListings, type ResolutionRefusal, type ResolutionScope, type ListingDataSource, type ListingResolved, type OrgListingState, vulnUpgradeAvailableWarning, type VulnUpgradeAvailableWarning, } from './api/plugin-resolution.js';
38
+ export { findVersionReferences, distinctPipelines, versionReferencedPredicate, orgImageDigestsInUse, type VersionReferenceTarget, type VersionReference, } from './api/version-references.js';
39
+ export { declaredResolution, recordStepLookup, pipelineStepLookups, declaredPipelinesForPlugin, stageAndStep, stepLabelOf, type DeclaredStepInput, type DeclaredStepPlugin, type DeclaredStepResolution, type StepLookupRecord, type DeclaredPipelineRef, } from './api/pipeline-step-resolution.js';
36
40
  export { runSoftDeletePurge, createSoftDeletePurgeScheduler, type PurgeableEntity, } from './api/soft-delete-sweep.js';
37
- export { type BuildHealth, type DoraLevel, type DoraMetrics, type DoraOptions, type DoraTrendPoint, type IncidentListItem, type ReportingSettings, type IncidentTestResult, type IngestCaller, type IngestMetric, type LastDeployedCommit, } from './api/reporting-service.js';
41
+ export { type BuildHealth, type DoraLevel, type DoraMetrics, type DoraOptions, type DoraTrendPoint, type DeploymentOutcomeWrite, type IncidentListItem, type IncidentState, type IncidentWrite, type ReportingSettings, type IncidentTestResult, type IngestCaller, type IngestMetric, type LastDeployedCommit, } from './api/reporting-service.js';
38
42
  export { upsertDeployments, applyDeployOutcome, correlateIncident, isDeployEvent, leadTimeGapOf, type DeployCandidate, } from './api/reporting/deploy-rollup.js';
39
43
  export { rebuildDay, runRollupPass, rollupSettleHours, rollupBatchDays, utcDayStart, } from './api/reporting/daily-rollup.js';
40
44
  export { classifyFailure, isTeamActionable, FAILURE_CATEGORY_LABELS, } from './api/reporting/failure-classifier.js';
41
45
  export { getPipelineBreakdown, getFailureAnalysis, getStagePerformance, getResourceConsumption, getPromotionView, getOutdatedPlugins, getPluginVulnerabilities, getAdoption, type AnalyticsScope, type PipelineBreakdownRow, type FailureCategoryRow, type StagePerformanceRow, type ResourceRow, type PromotionRow, type OutdatedPluginRow, type VulnerabilityRow, type AdoptionSummary, } from './api/reporting/analytics-queries.js';
42
46
  export { evaluateNeedsAttention, thresholdsFrom, DEFAULT_THRESHOLDS, type NeedsAttentionThresholds, type AttentionFinding, type AttentionItem, type AttentionInput, type AttentionRuleId, } from './api/reporting/needs-attention.js';
43
- export { replacePipelineResolution, refreshLatestForPlugin, upsertExposures, closeFixedExposures, openExposures, triageExposure, lapsedAcceptances, versionGap, type ResolvedStep, type ExposureInput, type VersionGap, } from './api/reporting/plugin-exposure.js';
47
+ export { replacePipelineResolution, refreshLatestForPlugin, upsertExposures, closeFixedExposures, closePipelineExposures, closeVersionExposures, reconcilePipelineExposures, syncVersionExposures, pipelinesOnVersion, exposureFromScan, liveExposurePredicate, openExposures, triageExposure, lapsedAcceptances, pipelineExposures, exposureById, activeAcceptances, acceptanceKey, reopenLapsedAcceptances, versionGap, type PipelineExposure, type TriageDecision, type PipelineAcceptances, type LapsedAcceptance, type ResolvedStep, type ExposureInput, type ExposureStep, type ExposureCounts, type LiveVersion, type PipelineOnVersion, type PluginVersionRef, type ScanState, type VersionGap, } from './api/reporting/plugin-exposure.js';
44
48
  export { resolvePeriod, resolvePeriodByLabel, rejectUnreportablePeriod, nextPeriodBoundary, completePeriodsSince, registerSection, getSection, allSections, sectionIds, REPORT_TEMPLATE_SPECS, getTemplate, composeSnapshot, LOW_SAMPLE_THRESHOLD, REPORT_FEATURE_SUBSTITUTES, renderReportHtml, reportFileName, trendSentence, type ReportHtmlInput, type ResolvedPeriod, type PeriodRejection, type SectionSpec, type SectionContext, type SectionDataSource, type TemplateSpec, type ReportSnapshot, type ComposedSection, type DataQualityNote, type ComposeOptions, type TrendDirection, StakeholderReportStore, stakeholderReportStore, hashToken, mintToken, DEFAULT_SHARE_LINK_TTL_DAYS, MAX_SHARE_LINK_TTL_DAYS, MAX_BOUNCES, VERIFICATION_TTL_MS, type CreateDefinitionInput, type UpdateDefinitionInput, type MintedShareLink, type ResolvedShareLink, } from './api/reporting/stakeholder/index.js';
45
49
  export { type PluginRuntimeFilter, type PluginRuntimeStats, ReportingService, reportingService, } from './api/reporting-service.js';
46
50
  export { type PluginFilter, type PipelineFilter, type PipelineTemplateFilter, type MessageFilter, type CompliancePolicyFilter, type ComplianceRuleFilter, type ComplianceExemptionFilter, type ComplianceAuditFilter, type ComplianceScanFilter, } from './core/query-filters.js';