@pipeline-builder/api-core 4.1.13 → 4.1.15

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 (187) hide show
  1. package/README.md +3 -2
  2. package/lib/constants/index.d.ts +0 -1
  3. package/lib/constants/index.js +1 -2
  4. package/lib/errors/app-errors.d.ts +8 -3
  5. package/lib/errors/app-errors.js +10 -5
  6. package/lib/helpers/access-helpers.d.ts +4 -6
  7. package/lib/helpers/access-helpers.js +6 -8
  8. package/lib/helpers/index.d.ts +3 -3
  9. package/lib/helpers/index.js +4 -4
  10. package/lib/helpers/org-hierarchy-http.d.ts +11 -10
  11. package/lib/helpers/org-hierarchy-http.js +24 -35
  12. package/lib/helpers/org-hierarchy.d.ts +37 -3
  13. package/lib/helpers/org-hierarchy.js +45 -4
  14. package/lib/helpers/restore-helpers.d.ts +44 -24
  15. package/lib/helpers/restore-helpers.js +41 -52
  16. package/lib/helpers/sse-helpers.d.ts +29 -7
  17. package/lib/helpers/sse-helpers.js +36 -9
  18. package/lib/index.d.ts +16 -14
  19. package/lib/index.js +17 -15
  20. package/lib/middleware/assurance.d.ts +116 -0
  21. package/lib/middleware/assurance.js +176 -0
  22. package/lib/middleware/auth.d.ts +5 -427
  23. package/lib/middleware/auth.js +36 -789
  24. package/lib/middleware/ecosystem-guard.d.ts +47 -0
  25. package/lib/middleware/ecosystem-guard.js +60 -0
  26. package/lib/middleware/index.d.ts +11 -4
  27. package/lib/middleware/index.js +12 -5
  28. package/lib/middleware/jwt-verify.d.ts +52 -0
  29. package/lib/middleware/jwt-verify.js +105 -0
  30. package/lib/middleware/permission-gates.d.ts +133 -0
  31. package/lib/middleware/permission-gates.js +260 -0
  32. package/lib/middleware/revocation.d.ts +96 -0
  33. package/lib/middleware/revocation.js +162 -0
  34. package/lib/middleware/route-table.d.ts +11 -0
  35. package/lib/middleware/route-table.js +4 -1
  36. package/lib/middleware/service-tokens.d.ts +83 -0
  37. package/lib/middleware/service-tokens.js +158 -0
  38. package/lib/middleware/step-up.d.ts +2 -2
  39. package/lib/middleware/step-up.js +8 -7
  40. package/lib/middleware/system-org.d.ts +20 -0
  41. package/lib/middleware/system-org.js +25 -0
  42. package/lib/openapi/routes/plugin-routes.js +133 -10
  43. package/lib/openapi/schema-registry.js +2 -5
  44. package/lib/routes/index.d.ts +1 -1
  45. package/lib/routes/index.js +2 -2
  46. package/lib/services/api-key-exchange.js +7 -5
  47. package/lib/services/audit-spool.d.ts +34 -10
  48. package/lib/services/audit-spool.js +75 -34
  49. package/lib/services/cache-service.d.ts +7 -0
  50. package/lib/services/cache-service.js +1 -1
  51. package/lib/services/circuit-breaker.d.ts +14 -1
  52. package/lib/services/circuit-breaker.js +36 -10
  53. package/lib/services/compliance-client.d.ts +10 -2
  54. package/lib/services/compliance-client.js +17 -10
  55. package/lib/services/compliance-event-subscriber.js +6 -6
  56. package/lib/services/durable-event-bus.js +8 -11
  57. package/lib/services/ecosystem-notify-client.d.ts +32 -0
  58. package/lib/services/ecosystem-notify-client.js +71 -0
  59. package/lib/services/env-redis.d.ts +4 -1
  60. package/lib/services/env-redis.js +32 -3
  61. package/lib/services/http-client.d.ts +19 -0
  62. package/lib/services/http-client.js +98 -19
  63. package/lib/services/index.d.ts +25 -24
  64. package/lib/services/index.js +25 -22
  65. package/lib/services/jwks-cache.js +5 -4
  66. package/lib/services/leader-lock.d.ts +22 -5
  67. package/lib/services/leader-lock.js +61 -6
  68. package/lib/services/quota.d.ts +9 -4
  69. package/lib/services/quota.js +34 -40
  70. package/lib/services/remote-audit-client.d.ts +28 -32
  71. package/lib/services/remote-audit-client.js +166 -49
  72. package/lib/services/retry-forever.js +5 -11
  73. package/lib/services/retry-strategy.d.ts +1 -1
  74. package/lib/services/retry-strategy.js +5 -4
  75. package/lib/services/scheduler.d.ts +8 -3
  76. package/lib/services/scheduler.js +17 -5
  77. package/lib/services/service-boot.d.ts +14 -13
  78. package/lib/services/service-boot.js +18 -15
  79. package/lib/services/service-keys.d.ts +1 -1
  80. package/lib/services/service-keys.js +12 -18
  81. package/lib/services/sse-ticket-store.d.ts +9 -1
  82. package/lib/services/sse-ticket-store.js +24 -9
  83. package/lib/services/system-notification.d.ts +27 -0
  84. package/lib/services/system-notification.js +50 -0
  85. package/lib/services/token-revocation.d.ts +50 -1
  86. package/lib/services/token-revocation.js +103 -3
  87. package/lib/types/audit-events.d.ts +6 -6
  88. package/lib/types/audit-events.js +1 -1
  89. package/lib/types/common.d.ts +32 -13
  90. package/lib/types/common.js +2 -1
  91. package/lib/types/ecosystem-notifications.d.ts +142 -0
  92. package/lib/types/ecosystem-notifications.js +210 -0
  93. package/lib/types/ecosystem.d.ts +77 -0
  94. package/lib/types/ecosystem.js +119 -0
  95. package/lib/types/error-codes.d.ts +81 -0
  96. package/lib/types/error-codes.js +108 -1
  97. package/lib/types/feature-flags.d.ts +21 -1
  98. package/lib/types/feature-flags.js +36 -2
  99. package/lib/types/index.d.ts +14 -9
  100. package/lib/types/index.js +15 -10
  101. package/lib/types/permissions.d.ts +46 -8
  102. package/lib/types/permissions.js +75 -12
  103. package/lib/types/plugin-catalog.d.ts +35 -0
  104. package/lib/types/plugin-catalog.js +39 -0
  105. package/lib/types/plugin-health.d.ts +102 -0
  106. package/lib/types/plugin-health.js +184 -0
  107. package/lib/types/quota-tiers.d.ts +15 -0
  108. package/lib/types/quota-tiers.js +23 -3
  109. package/lib/types/wire-vocabulary.d.ts +102 -0
  110. package/lib/types/wire-vocabulary.js +94 -0
  111. package/lib/utils/alias-resolver.js +2 -2
  112. package/lib/utils/audit.d.ts +5 -2
  113. package/lib/utils/audit.js +6 -3
  114. package/lib/utils/compliance-attributes.js +3 -4
  115. package/lib/utils/concurrency.d.ts +7 -0
  116. package/lib/utils/concurrency.js +13 -1
  117. package/lib/utils/env.d.ts +3 -4
  118. package/lib/utils/env.js +4 -5
  119. package/lib/utils/identity.d.ts +13 -4
  120. package/lib/utils/identity.js +18 -10
  121. package/lib/utils/index.d.ts +13 -10
  122. package/lib/utils/index.js +13 -10
  123. package/lib/utils/jwk.d.ts +4 -0
  124. package/lib/utils/jwk.js +13 -1
  125. package/lib/utils/logger.d.ts +1 -1
  126. package/lib/utils/logger.js +1 -1
  127. package/lib/utils/object.d.ts +11 -0
  128. package/lib/utils/object.js +24 -1
  129. package/lib/utils/params.d.ts +8 -22
  130. package/lib/utils/params.js +15 -43
  131. package/lib/utils/plugin-compliance.d.ts +98 -0
  132. package/lib/utils/plugin-compliance.js +78 -0
  133. package/lib/utils/proof-of-work.d.ts +69 -0
  134. package/lib/utils/proof-of-work.js +139 -0
  135. package/lib/utils/response.d.ts +16 -6
  136. package/lib/utils/response.js +18 -15
  137. package/lib/utils/retention.d.ts +17 -0
  138. package/lib/utils/retention.js +30 -0
  139. package/lib/utils/secret-encryption.d.ts +7 -7
  140. package/lib/utils/secret-encryption.js +9 -10
  141. package/lib/utils/secret-rotation.js +2 -2
  142. package/lib/utils/sensitive-patterns.js +4 -5
  143. package/lib/utils/service-registry.d.ts +15 -0
  144. package/lib/utils/service-registry.js +24 -0
  145. package/lib/utils/ssrf.d.ts +11 -2
  146. package/lib/utils/ssrf.js +112 -33
  147. package/lib/validation/ai-schemas.js +3 -2
  148. package/lib/validation/common-schemas.d.ts +0 -9
  149. package/lib/validation/common-schemas.js +1 -7
  150. package/lib/validation/dockerfile-static.d.ts +26 -0
  151. package/lib/validation/dockerfile-static.js +210 -0
  152. package/lib/validation/index.d.ts +13 -4
  153. package/lib/validation/index.js +14 -5
  154. package/lib/validation/message-schemas.js +6 -4
  155. package/lib/validation/pipeline-schemas.d.ts +8 -2
  156. package/lib/validation/pipeline-schemas.js +30 -4
  157. package/lib/validation/plugin-base-images.d.ts +20 -0
  158. package/lib/validation/plugin-base-images.js +17 -0
  159. package/lib/validation/plugin-catalog-detect.d.ts +86 -0
  160. package/lib/validation/plugin-catalog-detect.js +237 -0
  161. package/lib/validation/plugin-catalog-metadata.d.ts +141 -0
  162. package/lib/validation/plugin-catalog-metadata.js +162 -0
  163. package/lib/validation/plugin-heuristics.d.ts +41 -0
  164. package/lib/validation/plugin-heuristics.js +211 -0
  165. package/lib/validation/plugin-lint.d.ts +18 -0
  166. package/lib/validation/plugin-lint.js +136 -0
  167. package/lib/validation/plugin-name-confusable.d.ts +15 -0
  168. package/lib/validation/plugin-name-confusable.js +81 -0
  169. package/lib/validation/plugin-schemas.d.ts +40 -26
  170. package/lib/validation/plugin-schemas.js +26 -23
  171. package/lib/validation/plugin-spec-schema.d.ts +112 -0
  172. package/lib/validation/plugin-spec-schema.js +163 -0
  173. package/lib/validation/plugin-template-contract.d.ts +64 -0
  174. package/lib/validation/plugin-template-contract.js +113 -0
  175. package/package.json +69 -4
  176. package/lib/testing/mock-api-core.d.ts +0 -150
  177. package/lib/testing/mock-api-core.js +0 -246
  178. package/lib/testing/mock-drizzle.d.ts +0 -6
  179. package/lib/testing/mock-drizzle.js +0 -57
  180. package/lib/testing/route-coverage.d.ts +0 -64
  181. package/lib/testing/route-coverage.js +0 -183
  182. package/lib/testing/service-tokens.d.ts +0 -66
  183. package/lib/testing/service-tokens.js +0 -137
  184. package/lib/testing/tier-mock.d.ts +0 -44
  185. package/lib/testing/tier-mock.js +0 -65
  186. package/lib/testing/user-tokens.d.ts +0 -75
  187. package/lib/testing/user-tokens.js +0 -115
@@ -5,6 +5,8 @@ export const ALL_PERMISSIONS = [
5
5
  'pipelines:read', 'pipelines:write', 'pipelines:publish',
6
6
  'templates:read', 'templates:write', 'templates:publish',
7
7
  'plugins:read', 'plugins:write', 'plugins:publish',
8
+ 'plugins:install', 'plugin_installs:manage', 'publishers:manage',
9
+ 'plugins:moderate', 'publishers:verify',
8
10
  'compliance:read', 'compliance:write',
9
11
  'members:manage', 'roles:manage', 'invitations:manage', 'service_accounts:manage',
10
12
  'dashboards:read', 'dashboards:write',
@@ -20,12 +22,12 @@ export const ALL_PERMISSIONS = [
20
22
  /**
21
23
  * The CLOSED set of functions that take a {@link Permission} and decide access.
22
24
  *
23
- * "Is permission X enforced anywhere?" has to be answerable statically, and it
24
- * used to not be: four different call shapes consumed a permission id
25
+ * "Is permission X enforced anywhere?" has to be answerable statically, which
26
+ * a grep can't do: four different call shapes consume a permission id
25
27
  * (`requirePermission('x')` at a route, `userHasPermission(req, 'x')` inside a
26
28
  * controller, and `resolveVisibility(req, v, 'x')` /
27
29
  * `requireVisibilityWriteAccess(…, 'x')` in the visibility helpers), so a naive
28
- * grep for a route-level gate reported `templates:publish` as UNENFORCED when it
30
+ * grep for a route-level gate reports `templates:publish` as UNENFORCED when it
29
31
  * is in fact enforced on every template publish.
30
32
  *
31
33
  * They all bottom out in `userHasPermission`, so the RUNTIME primitive was
@@ -40,6 +42,8 @@ export const PERMISSION_GATES = [
40
42
  'requirePermission',
41
43
  'requireAllPermissions',
42
44
  'requirePermissionOrService',
45
+ // The plugin-ecosystem governance chain (system org + permission + aal2).
46
+ 'requireEcosystemPermission',
43
47
  // The single runtime primitive every gate above delegates to; also called
44
48
  // directly where a controller branches on a capability rather than rejecting.
45
49
  'userHasPermission',
@@ -68,6 +72,11 @@ export const PERMISSION_CATALOG = [
68
72
  { id: 'plugins:read', label: 'View plugins', description: 'View plugins and builds', category: 'Plugins' },
69
73
  { id: 'plugins:write', label: 'Manage plugins', description: 'Create, upload, edit, and delete plugins', category: 'Plugins' },
70
74
  { id: 'plugins:publish', label: 'Publish plugins', description: 'Make plugins public (org-wide/catalog visibility)', category: 'Plugins' },
75
+ { id: 'plugins:install', label: 'Install plugins', description: 'Install, upgrade, and uninstall ecosystem plugins (or request an install when your org requires approval)', category: 'Plugin Ecosystem' },
76
+ { id: 'plugin_installs:manage', label: 'Manage plugin installs', description: "Set your org's plugin consumption policy and approve or deny install requests within the org", category: 'Plugin Ecosystem' },
77
+ { id: 'publishers:manage', label: 'Manage publisher profile', description: "Manage your org's publisher profile and submit publish, verification, transfer, and advisory requests", category: 'Plugin Ecosystem' },
78
+ { id: 'plugins:moderate', label: 'Moderate the plugin ecosystem', description: 'Decide publish requests, moderate submissions and reviews, yank versions, and publish advisories (system org only)', category: 'Plugin Ecosystem' },
79
+ { id: 'publishers:verify', label: 'Verify publishers', description: 'Approve Verified applications, publisher tier and profile changes, and ownership transfers (system org only)', category: 'Plugin Ecosystem' },
71
80
  { id: 'compliance:read', label: 'View compliance', description: 'View compliance rules, policies, and scans', category: 'Compliance' },
72
81
  { id: 'compliance:write', label: 'Manage compliance', description: 'Create and edit rules, policies, and exemptions', category: 'Compliance' },
73
82
  { id: 'members:manage', label: 'Manage members', description: 'Add, remove, and change roles of org members', category: 'Members & Access' },
@@ -129,19 +138,38 @@ export const SUPERADMIN_ONLY_PERMISSIONS = [
129
138
  'registry:read',
130
139
  'registry:write',
131
140
  ];
141
+ /**
142
+ * Permissions that govern the PLUGIN ECOSYSTEM and may be held only inside the
143
+ * system org (docs/plugin-publishing.md). Like
144
+ * {@link SUPERADMIN_ONLY_PERMISSIONS} they are in no member/admin/owner bundle
145
+ * and are never grantable through a custom Role in ANY org (platform
146
+ * `sanitizePermissions` refuses them). The only holders are superadmins
147
+ * (implicit-all) and members of the built-in "Ecosystem Manager" Role, which is
148
+ * seeded in the system org alone from {@link ECOSYSTEM_MANAGER_PERMISSIONS} and
149
+ * assignable only by a superadmin.
150
+ */
151
+ export const SYSTEM_ORG_ONLY_PERMISSIONS = [
152
+ 'plugins:moderate',
153
+ 'publishers:verify',
154
+ ];
155
+ /** Whether `permission` may be held only inside the system org. */
156
+ export function isSystemOrgOnlyPermission(permission) {
157
+ return SYSTEM_ORG_ONLY_PERMISSIONS.includes(permission);
158
+ }
132
159
  /**
133
160
  * Permissions an org may assign via a CUSTOM Role — every permission except the
134
- * {@link SUPERADMIN_ONLY_PERMISSIONS}. Custom-Role create/update validates the
135
- * requested permission set against this (see platform roles-service).
161
+ * {@link SUPERADMIN_ONLY_PERMISSIONS} and {@link SYSTEM_ORG_ONLY_PERMISSIONS}.
162
+ * Custom-Role create/update validates the requested permission set against this
163
+ * (see platform roles-service).
136
164
  */
137
- export const ORG_ASSIGNABLE_PERMISSIONS = ALL_PERMISSIONS.filter((p) => !SUPERADMIN_ONLY_PERMISSIONS.includes(p));
165
+ export const ORG_ASSIGNABLE_PERMISSIONS = ALL_PERMISSIONS.filter((p) => isOrgAssignablePermission(p));
138
166
  /** Whether `permission` may be granted through a user-authored custom Role. */
139
167
  export function isOrgAssignablePermission(permission) {
140
- return !SUPERADMIN_ONLY_PERMISSIONS.includes(permission);
168
+ return !SUPERADMIN_ONLY_PERMISSIONS.includes(permission) && !isSystemOrgOnlyPermission(permission);
141
169
  }
142
170
  /**
143
171
  * Category → permissions for the custom-Role AUTHORING picker: the catalog minus
144
- * the {@link SUPERADMIN_ONLY_PERMISSIONS}, with any now-empty category dropped
172
+ * the non-assignable permissions, with any now-empty category dropped
145
173
  * (so "Registry" disappears). The grouped view of
146
174
  * {@link ORG_ASSIGNABLE_PERMISSIONS}.
147
175
  */
@@ -200,8 +228,10 @@ export function intersectPermissions(effective, subset) {
200
228
  * read elsewhere. No member/role/billing management, no compliance/alert
201
229
  * authoring, and no `:publish` on any catalog.
202
230
  * - `admin` — full org administration: every ORG-ASSIGNABLE permission (i.e.
203
- * ALL_PERMISSIONS minus the {@link SUPERADMIN_ONLY_PERMISSIONS}, so `registry:*`
204
- * stay superadmin-implicit-only and are NOT granted to org admins).
231
+ * ALL_PERMISSIONS minus the {@link SUPERADMIN_ONLY_PERMISSIONS} and the
232
+ * {@link SYSTEM_ORG_ONLY_PERMISSIONS}, so `registry:*` stay
233
+ * superadmin-implicit-only and ecosystem moderation stays with the system
234
+ * org's Ecosystem Managers — neither is granted to org admins).
205
235
  * - `owner` — same as admin (ownership itself — transfer/delete — is gated
206
236
  * separately, not via a permission).
207
237
  */
@@ -209,6 +239,7 @@ const MEMBER_PERMISSIONS = [
209
239
  'pipelines:read', 'pipelines:write',
210
240
  'templates:read', 'templates:write',
211
241
  'plugins:read', 'plugins:write',
242
+ 'plugins:install',
212
243
  'compliance:read',
213
244
  'dashboards:read',
214
245
  'observability:read',
@@ -229,6 +260,21 @@ export const ROLE_PERMISSIONS = {
229
260
  admin: ADMIN_PERMISSIONS,
230
261
  owner: ADMIN_PERMISSIONS,
231
262
  };
263
+ /**
264
+ * Seed bundle for the built-in "Ecosystem Manager" Role — seeded ONLY in the
265
+ * system org (docs/plugin-publishing.md). It carries the
266
+ * {@link SYSTEM_ORG_ONLY_PERMISSIONS} plus the reads a moderator needs (the
267
+ * in-app catalog, in-app notices, the moderation-SLA dashboard) and nothing
268
+ * tenant-facing: no `registry:*`, no `members:manage`. The Role grants the
269
+ * coarse `member` label and never sets `isSuperAdmin`.
270
+ */
271
+ export const ECOSYSTEM_MANAGER_PERMISSIONS = [
272
+ 'plugins:read',
273
+ 'plugins:moderate',
274
+ 'publishers:verify',
275
+ 'messages:read',
276
+ 'observability:read',
277
+ ];
232
278
  // =============================================================================
233
279
  // Resolution
234
280
  // =============================================================================
@@ -239,7 +285,7 @@ export const ROLE_PERMISSIONS = {
239
285
  * permissions carried by the Roles they hold (a Role = a named permission set;
240
286
  * built-in Roles carry their bundle explicitly, seeded from
241
287
  * {@link ROLE_PERMISSIONS}). There is no separate role-derived baseline — the
242
- * coarse `role` label no longer grants anything on its own.
288
+ * coarse `role` label grants nothing on its own.
243
289
  *
244
290
  * 1. Platform superadmins (`isSuperAdmin`) always get ALL permissions.
245
291
  * 2. Otherwise, union every permission granted by the user's assigned Roles.
@@ -261,10 +307,27 @@ export function resolveUserPermissions(assignedPermissions, isSuperAdmin) {
261
307
  }
262
308
  return ALL_PERMISSIONS.filter(p => perms.has(p));
263
309
  }
310
+ /**
311
+ * Confine a resolved permission list to what may be held in the token's ACTIVE
312
+ * org: outside the system org every {@link SYSTEM_ORG_ONLY_PERMISSIONS} entry is
313
+ * dropped (docs/plugin-publishing.md). Applied at token issue on
314
+ * top of {@link resolveUserPermissions} — including a superadmin's implicit-all —
315
+ * so a token minted in a tenant org never CLAIMS `plugins:moderate` /
316
+ * `publishers:verify`, even if a hand-written Role document somehow carried
317
+ * them there. (Superadmins still pass `hasPermission` via the flag; the
318
+ * ecosystem route gate additionally requires the system org, so that bypass
319
+ * never reaches a governance route from a tenant org either.)
320
+ *
321
+ * Takes a boolean rather than an org id so this module stays dependency-free
322
+ * (the frontend imports it); callers decide with api-core `isSystemOrgId`.
323
+ */
324
+ export function confinePermissionsToOrg(permissions, activeOrgIsSystemOrg) {
325
+ return activeOrgIsSystemOrg ? [...permissions] : permissions.filter((p) => !isSystemOrgOnlyPermission(p));
326
+ }
264
327
  /** Whether a resolved permission list grants `permission` (superadmin ⇒ always). */
265
328
  export function hasPermission(granted, permission, isSuperAdmin) {
266
329
  if (isSuperAdmin)
267
330
  return true;
268
331
  return !!granted && granted.includes(permission);
269
332
  }
270
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvcGVybWlzc2lvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQTBGdEMsNEVBQTRFO0FBQzVFLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBMEI7SUFDcEQsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CO0lBQ3hELGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLG1CQUFtQjtJQUN4RCxjQUFjLEVBQUUsZUFBZSxFQUFFLGlCQUFpQjtJQUNsRCxpQkFBaUIsRUFBRSxrQkFBa0I7SUFDckMsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLG9CQUFvQixFQUFFLHlCQUF5QjtJQUNqRixpQkFBaUIsRUFBRSxrQkFBa0I7SUFDckMsb0JBQW9CLEVBQUUscUJBQXFCO0lBQzNDLGFBQWE7SUFDYixjQUFjLEVBQUUsZ0JBQWdCO0lBQ2hDLGVBQWUsRUFBRSxnQkFBZ0I7SUFDakMsY0FBYyxFQUFFLGdCQUFnQjtJQUNoQyxhQUFhO0lBQ2IsZUFBZSxFQUFFLGdCQUFnQjtJQUNqQyxjQUFjLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxtQkFBbUI7Q0FDMUQsQ0FBQztBQUVGOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFzQjtJQUNqRCw0RUFBNEU7SUFDNUUsbUJBQW1CO0lBQ25CLHVCQUF1QjtJQUN2Qiw0QkFBNEI7SUFDNUIsMEVBQTBFO0lBQzFFLDhFQUE4RTtJQUM5RSxtQkFBbUI7SUFDbkIsZUFBZTtJQUNmLGtFQUFrRTtJQUNsRSw4QkFBOEI7SUFDOUIsNEJBQTRCO0lBQzVCLG1CQUFtQjtDQUNwQixDQUFDO0FBYUY7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBOEI7SUFDM0QsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxF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QUMsQ0FBQztBQUNuRCxDQUFDO0FBRUQsb0ZBQW9GO0FBQ3BGLE1BQU0sVUFBVSxhQUFhLENBQzNCLE9BQTZDLEVBQzdDLFVBQXNCLEVBQ3RCLFlBQXNCO0lBRXRCLElBQUksWUFBWTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzlCLE9BQU8sQ0FBQyxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ25ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBPcmdSb2xlIH0gZnJvbSAnLi9jb21tb24uanMnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gUGVybWlzc2lvbiBpZGVudGlmaWVyc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDYW5vbmljYWwgZmluZS1ncmFpbmVkIHBlcm1pc3Npb24gaWRlbnRpZmllcnMsIGluIGByZXNvdXJjZTphY3Rpb25gIGZvcm0uXG4gKlxuICogVGhlc2UgYXJlIHRoZSBPUkctU0NPUEVEIGNhcGFiaWxpdGllcyBhIFJvbGUgY2FuIGdyYW50IChSQkFDKS4gQ29hcnNlIGJ5XG4gKiBkZXNpZ24g4oCUIGA6d3JpdGVgIGNvdmVycyBjcmVhdGUvdXBkYXRlL2RlbGV0ZSBmb3IgYSByZXNvdXJjZSDigJQgc28gdGhlIGNhdGFsb2dcbiAqIGFuZCBwZXJtaXNzaW9uLXBpY2tlciBVSSBzdGF5IHNtYWxsOyBzcGxpdCBhIGA6d3JpdGVgIGludG8gYDpjcmVhdGVgL2A6ZGVsZXRlYFxuICogbGF0ZXIgaWYgYSByZXNvdXJjZSBuZWVkcyBpdC5cbiAqXG4gKiBOT1QgbW9kZWxlZCBoZXJlIChpbnRlbnRpb25hbGx5KTogcGxhdGZvcm0tb3BlcmF0b3IgYWN0aW9ucyAob3JnIGRlbGV0ZSwgdGllci9cbiAqIHF1b3RhIG92ZXJyaWRlLCB1c2VyIGFkbWluLCBpbXBlcnNvbmF0aW9uLCBwbGF0Zm9ybSBzZXR0aW5ncykgc3RheSBiZWhpbmQgdGhlXG4gKiBnbG9iYWwgYGlzU3VwZXJBZG1pbmAgZmxhZywgbm90IGEgcGVyLW9yZyBwZXJtaXNzaW9uOyBhbmQgYHJlcXVpcmVTdGVwVXBgXG4gKiAoTUZBKSAvIGByZXF1aXJlRmVhdHVyZWAgKHBsYW4gZW50aXRsZW1lbnRzKSByZW1haW4gb3J0aG9nb25hbCBnYXRlcy5cbiAqL1xuZXhwb3J0IHR5cGUgUGVybWlzc2lvbiA9XG4gIC8vIFBpcGVsaW5lc1xuICB8ICdwaXBlbGluZXM6cmVhZCdcbiAgfCAncGlwZWxpbmVzOndyaXRlJ1xuICB8ICdwaXBlbGluZXM6cHVibGlzaCdcbiAgLy8gR29sZGVuLXBhdGggcGlwZWxpbmUgdGVtcGxhdGVzLiBTcGxpdCBvdXQgb2YgYHBpcGVsaW5lczoqYCBzbyBhIHBsYXRmb3JtXG4gIC8vIHRlYW0gY2FuIGN1cmF0ZSB0aGUgc3RhcnRlciBjYXRhbG9nIFdJVEhPVVQgd3JpdGUgYWNjZXNzIHRvIGV2ZXJ5IHBpcGVsaW5lXG4gIC8vIChhbmQgdmljZSB2ZXJzYSkg4oCUIHRoZSB0d28gdXNlZCB0byBzaGFyZSBvbmUgZ2F0ZS4gYDpwdWJsaXNoYCBtYXBzIHRvIHRoZVxuICAvLyB0ZW1wbGF0ZSBsYWRkZXIncyBgcHVibGljYCBydW5nOyBgb3JnYCBhbmQgYHByaXZhdGVgIG5lZWQgb25seSBgOndyaXRlYC5cbiAgfCAndGVtcGxhdGVzOnJlYWQnXG4gIHwgJ3RlbXBsYXRlczp3cml0ZSdcbiAgfCAndGVtcGxhdGVzOnB1Ymxpc2gnXG4gIC8vIFBsdWdpbnNcbiAgfCAncGx1Z2luczpyZWFkJ1xuICB8ICdwbHVnaW5zOndyaXRlJ1xuICB8ICdwbHVnaW5zOnB1Ymxpc2gnXG4gIC8vIENvbXBsaWFuY2VcbiAgfCAnY29tcGxpYW5jZTpyZWFkJ1xuICB8ICdjb21wbGlhbmNlOndyaXRlJ1xuICAvLyBNZW1iZXJzICYgYWNjZXNzXG4gIHwgJ21lbWJlcnM6bWFuYWdlJ1xuICB8ICdyb2xlczptYW5hZ2UnXG4gIHwgJ2ludml0YXRpb25zOm1hbmFnZSdcbiAgLy8gT3JnLXNjb3BlZCBzZXJ2aWNlIGFjY291bnRzIChub24taHVtYW4gcHJpbmNpcGFscykgYW5kIHRoZWlyIGFjY2VzcyBrZXlzLlxuICAvLyBTcGxpdCBvdXQgb2YgYG1lbWJlcnM6bWFuYWdlYCBiZWNhdXNlIGEgc2VydmljZSBhY2NvdW50IGlzIGEgQ1JFREVOVElBTFxuICAvLyBob2xkZXIsIG5vdCBhIHBlcnNvbjogZ3JhbnRpbmcgc29tZW9uZSB0aGUgYWJpbGl0eSB0byBtaW50IGxvbmctbGl2ZWRcbiAgLy8gbWFjaGluZSBrZXlzIGlzIGEgZGlmZmVyZW50IGRlY2lzaW9uIGZyb20gbGV0dGluZyB0aGVtIG1hbmFnZSB0aGUgcm9zdGVyLlxuICB8ICdzZXJ2aWNlX2FjY291bnRzOm1hbmFnZSdcbiAgLy8gT2JzZXJ2YWJpbGl0eVxuICB8ICdkYXNoYm9hcmRzOnJlYWQnXG4gIHwgJ2Rhc2hib2FyZHM6d3JpdGUnXG4gIHwgJ29ic2VydmFiaWxpdHk6cmVhZCdcbiAgfCAnb2JzZXJ2YWJpbGl0eTp3cml0ZSdcbiAgLy8gYGxvZ3M6ZXhwb3J0YCBpcyBzcGxpdCBPVVQgb2YgYG9ic2VydmFiaWxpdHk6cmVhZGAgZGVsaWJlcmF0ZWx5LiBSZWFkaW5nXG4gIC8vIGxvZ3MgaW4gdGhlIFVJIGlzIHBhZ2VkIGFuZCBlcGhlbWVyYWw7IEVYUE9SVElORyB0aGVtIGlzIGJ1bGsgZWdyZXNzIHRoYXRcbiAgLy8gbGVhdmVzIHRoZSBidWlsZGluZyBhbmQgb3V0bGl2ZXMgYSByZXZva2VkIHNlc3Npb24sIHNvIGFuIG9yZyBhZG1pbiBtdXN0IGJlXG4gIC8vIGFibGUgdG8gZ3JhbnQgbG9nIHZpZXdpbmcgd2l0aG91dCBncmFudGluZyBkb3dubG9hZHMuXG4gIHwgJ2xvZ3M6ZXhwb3J0J1xuICAvLyBJbnNpZ2h0c1xuICB8ICdyZXBvcnRzOnJlYWQnXG4gIHwgJ3JlcG9ydHM6cm9sbHVwJ1xuICAvLyBNZXNzYWdpbmdcbiAgfCAnbWVzc2FnZXM6cmVhZCdcbiAgfCAnbWVzc2FnZXM6d3JpdGUnXG4gIC8vIEJpbGxpbmcgJiBxdW90YXNcbiAgfCAnYmlsbGluZzpyZWFkJ1xuICB8ICdiaWxsaW5nOm1hbmFnZSdcbiAgfCAncXVvdGFzOnJlYWQnXG4gIC8vIFJlZ2lzdHJ5XG4gIHwgJ3JlZ2lzdHJ5OnJlYWQnXG4gIHwgJ3JlZ2lzdHJ5OndyaXRlJ1xuICAvLyBPcmdhbml6YXRpb24gc2V0dGluZ3MuXG4gIC8vICAtIGBvcmc6c2V0dGluZ3NgIOKAlCBnZW5lcmFsIG9yZyBzZXR0aW5ncyArIEFJIGNvbmZpZy5cbiAgLy8gIC0gYG9yZzppZHBgICAgICAg4oCUIFNTTyAvIElkUCBjb25maWd1cmF0aW9uIChzZW5zaXRpdmU6IGNvbnRyb2xzIGxvZ2luKS5cbiAgLy8gIC0gYG9yZzprbXNgICAgICAg4oCUIGN1c3RvbWVyLW1hbmFnZWQgS01TIGtleSBjb25maWd1cmF0aW9uIChzZW5zaXRpdmU6XG4gIC8vICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgZW5jcnlwdGlvbiBvZiBvcmcgZGF0YSkuXG4gIC8vICAtIGBvcmc6aW1wZXJzb25hdGlvbmAg4oCUIHRoZSBpbXBlcnNvbmF0aW9uIHBvbGljeSAoc2Vuc2l0aXZlOiBjb250cm9scyB3aG9cbiAgLy8gICAgICAgICAgICAgICAgICAgICBtYXkgVklFVyB0aGUgb3JnJ3MgZGF0YSBhcyBvbmUgb2YgaXRzIG1lbWJlcnMpLlxuICAvLyBgb3JnOmlkcGAvYG9yZzprbXNgL2Bvcmc6aW1wZXJzb25hdGlvbmAgd2VyZSBzcGxpdCBPVVQgb2YgYG9yZzpzZXR0aW5nc2Agc28gYVxuICAvLyBjdXN0b20gcm9sZSBjYW4gZ3JhbnQgZ2VuZXJhbCBzZXR0aW5ncyBXSVRIT1VUIHRoZSBzZW5zaXRpdmUgc3VyZmFjZXMg4oCUIGFcbiAgLy8gXCJzZXR0aW5ncyBtYW5hZ2VyXCIgcm9sZSBmb3Igb3JnIG5hbWUgb3IgQUkgcHJvdmlkZXIgbXVzdCBub3QgYWxzbyBiZSBhYmxlIHRvXG4gIC8vIHN3aXRjaCB0aGUgb3JnIHRvIGBvcGVuYC4gQWxsIHJlbWFpbiBvcmctYXNzaWduYWJsZSBhbmQgYXJlIHNlZWRlZCBpbnRvIHRoZVxuICAvLyBhZG1pbi9vd25lciBidW5kbGVzICh2aWEgT1JHX0FTU0lHTkFCTEVfUEVSTUlTU0lPTlMpIHNvIGV4aXN0aW5nIGFkbWlucyBrZWVwXG4gIC8vIGZ1bGwgYWNjZXNzLlxuICB8ICdvcmc6c2V0dGluZ3MnXG4gIHwgJ29yZzppZHAnXG4gIHwgJ29yZzprbXMnXG4gIHwgJ29yZzppbXBlcnNvbmF0aW9uJztcblxuLyoqIEFsbCB2YWxpZCBwZXJtaXNzaW9ucyAob3JkZXIgZGV0ZXJtaW5lcyBkaXNwbGF5IG9yZGVyIGluIHRoZSBwaWNrZXIpLiAqL1xuZXhwb3J0IGNvbnN0IEFMTF9QRVJNSVNTSU9OUzogcmVhZG9ubHkgUGVybWlzc2lvbltdID0gW1xuICAncGlwZWxpbmVzOnJlYWQnLCAncGlwZWxpbmVzOndyaXRlJywgJ3BpcGVsaW5lczpwdWJsaXNoJyxcbiAgJ3RlbXBsYXRlczpyZWFkJywgJ3RlbXBsYXRlczp3cml0ZScsICd0ZW1wbGF0ZXM6cHVibGlzaCcsXG4gICdwbHVnaW5zOnJlYWQnLCAncGx1Z2luczp3cml0ZScsICdwbHVnaW5zOnB1Ymxpc2gnLFxuICAnY29tcGxpYW5jZTpyZWFkJywgJ2NvbXBsaWFuY2U6d3JpdGUnLFxuICAnbWVtYmVyczptYW5hZ2UnLCAncm9sZXM6bWFuYWdlJywgJ2ludml0YXRpb25zOm1hbmFnZScsICdzZXJ2aWNlX2FjY291bnRzOm1hbmFnZScsXG4gICdkYXNoYm9hcmRzOnJlYWQnLCAnZGFzaGJvYXJkczp3cml0ZScsXG4gICdvYnNlcnZhYmlsaXR5OnJlYWQnLCAnb2JzZXJ2YWJpbGl0eTp3cml0ZScsXG4gICdsb2dzOmV4cG9ydCcsXG4gICdyZXBvcnRzOnJlYWQnLCAncmVwb3J0czpyb2xsdXAnLFxuICAnbWVzc2FnZXM6cmVhZCcsICdtZXNzYWdlczp3cml0ZScsXG4gICdiaWxsaW5nOnJlYWQnLCAnYmlsbGluZzptYW5hZ2UnLFxuICAncXVvdGFzOnJlYWQnLFxuICAncmVnaXN0cnk6cmVhZCcsICdyZWdpc3RyeTp3cml0ZScsXG4gICdvcmc6c2V0dGluZ3MnLCAnb3JnOmlkcCcsICdvcmc6a21zJywgJ29yZzppbXBlcnNvbmF0aW9uJyxcbl07XG5cbi8qKlxuICogVGhlIENMT1NFRCBzZXQgb2YgZnVuY3Rpb25zIHRoYXQgdGFrZSBhIHtAbGluayBQZXJtaXNzaW9ufSBhbmQgZGVjaWRlIGFjY2Vzcy5cbiAqXG4gKiBcIklzIHBlcm1pc3Npb24gWCBlbmZvcmNlZCBhbnl3aGVyZT9cIiBoYXMgdG8gYmUgYW5zd2VyYWJsZSBzdGF0aWNhbGx5LCBhbmQgaXRcbiAqIHVzZWQgdG8gbm90IGJlOiBmb3VyIGRpZmZlcmVudCBjYWxsIHNoYXBlcyBjb25zdW1lZCBhIHBlcm1pc3Npb24gaWRcbiAqIChgcmVxdWlyZVBlcm1pc3Npb24oJ3gnKWAgYXQgYSByb3V0ZSwgYHVzZXJIYXNQZXJtaXNzaW9uKHJlcSwgJ3gnKWAgaW5zaWRlIGFcbiAqIGNvbnRyb2xsZXIsIGFuZCBgcmVzb2x2ZVZpc2liaWxpdHkocmVxLCB2LCAneCcpYCAvXG4gKiBgcmVxdWlyZVZpc2liaWxpdHlXcml0ZUFjY2VzcyjigKYsICd4JylgIGluIHRoZSB2aXNpYmlsaXR5IGhlbHBlcnMpLCBzbyBhIG5haXZlXG4gKiBncmVwIGZvciBhIHJvdXRlLWxldmVsIGdhdGUgcmVwb3J0ZWQgYHRlbXBsYXRlczpwdWJsaXNoYCBhcyBVTkVORk9SQ0VEIHdoZW4gaXRcbiAqIGlzIGluIGZhY3QgZW5mb3JjZWQgb24gZXZlcnkgdGVtcGxhdGUgcHVibGlzaC5cbiAqXG4gKiBUaGV5IGFsbCBib3R0b20gb3V0IGluIGB1c2VySGFzUGVybWlzc2lvbmAsIHNvIHRoZSBSVU5USU1FIHByaW1pdGl2ZSB3YXNcbiAqIGFscmVhZHkgb25lLiBUaGlzIGNvbnN0YW50IG1ha2VzIHRoZSBTVEFUSUMgc3VyZmFjZSBvbmUgYXMgd2VsbDogaXQgbmFtZXNcbiAqIGV2ZXJ5IGVudHJ5IHBvaW50LCBzbyBgcGVybWlzc2lvbi1jb3ZlcmFnZS50ZXN0LnRzYCBjYW4gZW51bWVyYXRlIHRoZSBjYXRhbG9nXG4gKiBhbmQgcmVwb3J0IGVhY2ggcGVybWlzc2lvbidzIGVuZm9yY2VtZW50IHNpdGVzIHdpdGhvdXQgZ3Vlc3NpbmcuIEEgbmV3IGdhdGVcbiAqIHRoYXQgdGFrZXMgYSBgUGVybWlzc2lvbmAgbXVzdCBiZSBsaXN0ZWQgaGVyZSwgb3IgdGhlIGNvdmVyYWdlIHJlcG9ydCBzdGFydHNcbiAqIGx5aW5nIGFib3V0IHRoZSBwZXJtaXNzaW9ucyBvbmx5IHRoYXQgZ2F0ZSBlbmZvcmNlcy5cbiAqL1xuZXhwb3J0IGNvbnN0IFBFUk1JU1NJT05fR0FURVM6IHJlYWRvbmx5IHN0cmluZ1tdID0gW1xuICAvLyBNaWRkbGV3YXJlIGdhdGVzIChyb3V0ZSBsZXZlbCkg4oCUIGFsbCBhbnktb2YgZXhjZXB0IHJlcXVpcmVBbGxQZXJtaXNzaW9ucy5cbiAgJ3JlcXVpcmVQZXJtaXNzaW9uJyxcbiAgJ3JlcXVpcmVBbGxQZXJtaXNzaW9ucycsXG4gICdyZXF1aXJlUGVybWlzc2lvbk9yU2VydmljZScsXG4gIC8vIFRoZSBzaW5nbGUgcnVudGltZSBwcmltaXRpdmUgZXZlcnkgZ2F0ZSBhYm92ZSBkZWxlZ2F0ZXMgdG87IGFsc28gY2FsbGVkXG4gIC8vIGRpcmVjdGx5IHdoZXJlIGEgY29udHJvbGxlciBicmFuY2hlcyBvbiBhIGNhcGFiaWxpdHkgcmF0aGVyIHRoYW4gcmVqZWN0aW5nLlxuICAndXNlckhhc1Blcm1pc3Npb24nLFxuICAnaGFzUGVybWlzc2lvbicsXG4gIC8vIFZpc2liaWxpdHkgaGVscGVycyDigJQgdGhleSB0YWtlIHRoZSBlbnRpdHkncyBQVUJMSVNIIHBlcm1pc3Npb24uXG4gICdyZXF1aXJlVmlzaWJpbGl0eVdyaXRlQWNjZXNzJyxcbiAgJ2NoZWNrVmlzaWJpbGl0eVdyaXRlQWNjZXNzJyxcbiAgJ3Jlc29sdmVWaXNpYmlsaXR5Jyxcbl07XG5cbi8qKlxuICogRGlzcGxheSBtZXRhZGF0YSBmb3Igb25lIHBlcm1pc3Npb246IHRoZSBsYWJlbCArIGRlc2NyaXB0aW9uIHRoZVxuICogcGVybWlzc2lvbi1waWNrZXIgVUkgc2hvd3MsIGFuZCB0aGUgY2F0ZWdvcnkgaXQgZ3JvdXBzIHVuZGVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBlcm1pc3Npb25NZXRhIHtcbiAgaWQ6IFBlcm1pc3Npb247XG4gIGxhYmVsOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGNhdGVnb3J5OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIHBlcm1pc3Npb24gY2F0YWxvZyB3aXRoIGRpc3BsYXkgbWV0YWRhdGEsIGluIHBpY2tlciBvcmRlci5cbiAqXG4gKiBUaGlzIG1vZHVsZSBpcyB0aGUgU0lOR0xFIGNhdGFsb2cgZm9yIGJhY2tlbmQgYW5kIGJyb3dzZXIgYWxpa2U6IGl0IGhhcyBub1xuICogcnVudGltZSBkZXBlbmRlbmNpZXMgKHRoZSBvbmx5IGltcG9ydCBpcyBhIHR5cGUpLCBzbyB0aGUgZnJvbnRlbmQgaW1wb3J0cyBpdFxuICogdGhyb3VnaCB0aGUgYEBwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlL3Blcm1pc3Npb25zYCBzdWJwYXRoIGluc3RlYWQgb2Yga2VlcGluZ1xuICogYSBoYW5kLW1haW50YWluZWQgbWlycm9yLiBFdmVyeSBpZCBpbiB7QGxpbmsgQUxMX1BFUk1JU1NJT05TfSBtdXN0IGFwcGVhciBoZXJlXG4gKiBleGFjdGx5IG9uY2UgKGFzc2VydGVkIGJ5IGBwZXJtaXNzaW9ucy50ZXN0LnRzYCkuXG4gKi9cbmV4cG9ydCBjb25zdCBQRVJNSVNTSU9OX0NBVEFMT0c6IHJlYWRvbmx5IFBlcm1pc3Npb25NZXRhW10gPSBbXG4gIHsgaWQ6ICdwaXBlbGluZXM6cmVhZCcsIGxhYmVsOiAnVmlldyBwaXBlbGluZXMnLCBkZXNjcmlwdGlvbjogJ1ZpZXcgcGlwZWxpbmVzIGFuZCB0aGVpciBleGVjdXRpb25zJywgY2F0ZWdvcnk6ICdQaXBlbGluZXMnIH0sXG4gIHsgaWQ6ICdwaXBlbGluZXM6d3JpdGUnLCBsYWJlbDogJ01hbmFnZSBwaXBlbGluZXMnLCBkZXNjcmlwdGlvbjogJ0NyZWF0ZSwgZWRpdCwgYW5kIGRlbGV0ZSBwaXBlbGluZXMnLCBjYXRlZ29yeTogJ1BpcGVsaW5lcycgfSxcbiAgeyBpZDogJ3BpcGVsaW5lczpwdWJsaXNoJywgbGFiZWw6ICdQdWJsaXNoIHBpcGVsaW5lcycsIGRlc2NyaXB0aW9uOiAnTWFrZSBwaXBlbGluZXMgcHVibGljIChvcmctd2lkZS9jYXRhbG9nIHZpc2liaWxpdHkpJywgY2F0ZWdvcnk6ICdQaXBlbGluZXMnIH0sXG4gIHsgaWQ6ICd0ZW1wbGF0ZXM6cmVhZCcsIGxhYmVsOiAnVmlldyB0ZW1wbGF0ZXMnLCBkZXNjcmlwdGlvbjogJ1ZpZXcgdGhlIGdvbGRlbi1wYXRoIHRlbXBsYXRlIGNhdGFsb2cnLCBjYXRlZ29yeTogJ1RlbXBsYXRlcycgfSxcbiAgeyBpZDogJ3RlbXBsYXRlczp3cml0ZScsIGxhYmVsOiAnTWFuYWdlIHRlbXBsYXRlcycsIGRlc2NyaXB0aW9uOiAnQXV0aG9yLCBlZGl0LCBhbmQgZGVsZXRlIHBpcGVsaW5lIHRlbXBsYXRlcycsIGNhdGVnb3J5OiAnVGVtcGxhdGVzJyB9LFxuICB7IGlkOiAndGVtcGxhdGVzOnB1Ymxpc2gnLCBsYWJlbDogJ1B1Ymxpc2ggdGVtcGxhdGVzJywgZGVzY3JpcHRpb246ICdTaGFyZSBhIHRlbXBsYXRlIGJleW9uZCB5b3VyIG9yZyAocHVibGljIHZpc2liaWxpdHkpJywgY2F0ZWdvcnk6ICdUZW1wbGF0ZXMnIH0sXG4gIHsgaWQ6ICdwbHVnaW5zOnJlYWQnLCBsYWJlbDogJ1ZpZXcgcGx1Z2lucycsIGRlc2NyaXB0aW9uOiAnVmlldyBwbHVnaW5zIGFuZCBidWlsZHMnLCBjYXRlZ29yeTogJ1BsdWdpbnMnIH0sXG4gIHsgaWQ6ICdwbHVnaW5zOndyaXRlJywgbGFiZWw6ICdNYW5hZ2UgcGx1Z2lucycsIGRlc2NyaXB0aW9uOiAnQ3JlYXRlLCB1cGxvYWQsIGVkaXQsIGFuZCBkZWxldGUgcGx1Z2lucycsIGNhdGVnb3J5OiAnUGx1Z2lucycgfSxcbiAgeyBpZDogJ3BsdWdpbnM6cHVibGlzaCcsIGxhYmVsOiAnUHVibGlzaCBwbHVnaW5zJywgZGVzY3JpcHRpb246ICdNYWtlIHBsdWdpbnMgcHVibGljIChvcmctd2lkZS9jYXRhbG9nIHZpc2liaWxpdHkpJywgY2F0ZWdvcnk6ICdQbHVnaW5zJyB9LFxuICB7IGlkOiAnY29tcGxpYW5jZTpyZWFkJywgbGFiZWw6ICdWaWV3IGNvbXBsaWFuY2UnLCBkZXNjcmlwdGlvbjogJ1ZpZXcgY29tcGxpYW5jZSBydWxlcywgcG9saWNpZXMsIGFuZCBzY2FucycsIGNhdGVnb3J5OiAnQ29tcGxpYW5jZScgfSxcbiAgeyBpZDogJ2NvbXBsaWFuY2U6d3JpdGUnLCBsYWJlbDogJ01hbmFnZSBjb21wbGlhbmNlJywgZGVzY3JpcHRpb246ICdDcmVhdGUgYW5kIGVkaXQgcnVsZXMsIHBvbGljaWVzLCBhbmQgZXhlbXB0aW9ucycsIGNhdGVnb3J5OiAnQ29tcGxpYW5jZScgfSxcbiAgeyBpZDogJ21lbWJlcnM6bWFuYWdlJywgbGFiZWw6ICdNYW5hZ2UgbWVtYmVycycsIGRlc2NyaXB0aW9uOiAnQWRkLCByZW1vdmUsIGFuZCBjaGFuZ2Ugcm9sZXMgb2Ygb3JnIG1lbWJlcnMnLCBjYXRlZ29yeTogJ01lbWJlcnMgJiBBY2Nlc3MnIH0sXG4gIHsgaWQ6ICdyb2xlczptYW5hZ2UnLCBsYWJlbDogJ01hbmFnZSByb2xlcycsIGRlc2NyaXB0aW9uOiAnQ3JlYXRlLCBlZGl0LCBhbmQgZGVsZXRlIHJvbGVzJywgY2F0ZWdvcnk6ICdNZW1iZXJzICYgQWNjZXNzJyB9LFxuICB7IGlkOiAnaW52aXRhdGlvbnM6bWFuYWdlJywgbGFiZWw6ICdNYW5hZ2UgaW52aXRhdGlvbnMnLCBkZXNjcmlwdGlvbjogJ1NlbmQsIHJlc2VuZCwgYW5kIHJldm9rZSBpbnZpdGF0aW9ucycsIGNhdGVnb3J5OiAnTWVtYmVycyAmIEFjY2VzcycgfSxcbiAgeyBpZDogJ3NlcnZpY2VfYWNjb3VudHM6bWFuYWdlJywgbGFiZWw6ICdNYW5hZ2Ugc2VydmljZSBhY2NvdW50cycsIGRlc2NyaXB0aW9uOiAnQ3JlYXRlIG9yZyBzZXJ2aWNlIGFjY291bnRzLCBhc3NpZ24gdGhlaXIgcm9sZXMsIGFuZCBpc3N1ZSBvciByZXZva2UgdGhlaXIga2V5cycsIGNhdGVnb3J5OiAnTWVtYmVycyAmIEFjY2VzcycgfSxcbiAgeyBpZDogJ2Rhc2hib2FyZHM6cmVhZCcsIGxhYmVsOiAnVmlldyBkYXNoYm9hcmRzJywgZGVzY3JpcHRpb246ICdWaWV3IGN1c3RvbSBkYXNoYm9hcmRzJywgY2F0ZWdvcnk6ICdPYnNlcnZhYmlsaXR5JyB9LFxuICB7IGlkOiAnZGFzaGJvYXJkczp3cml0ZScsIGxhYmVsOiAnTWFuYWdlIGRhc2hib2FyZHMnLCBkZXNjcmlwdGlvbjogJ0NyZWF0ZSBhbmQgZWRpdCBjdXN0b20gZGFzaGJvYXJkcycsIGNhdGVnb3J5OiAnT2JzZXJ2YWJpbGl0eScgfSxcbiAgeyBpZDogJ29ic2VydmFiaWxpdHk6cmVhZCcsIGxhYmVsOiAnVmlldyBhbGVydGluZycsIGRlc2NyaXB0aW9uOiAnVmlldyBhbGVydCBydWxlcyBhbmQgZGVzdGluYXRpb25zJywgY2F0ZWdvcnk6ICdPYnNlcnZhYmlsaXR5JyB9LFxuICB7IGlkOiAnb2JzZXJ2YWJpbGl0eTp3cml0ZScsIGxhYmVsOiAnTWFuYWdlIGFsZXJ0aW5nJywgZGVzY3JpcHRpb246ICdDcmVhdGUgYW5kIGVkaXQgYWxlcnQgcnVsZXMgYW5kIGRlc3RpbmF0aW9ucycsIGNhdGVnb3J5OiAnT2JzZXJ2YWJpbGl0eScgfSxcbiAgeyBpZDogJ2xvZ3M6ZXhwb3J0JywgbGFiZWw6ICdEb3dubG9hZCBsb2dzJywgZGVzY3JpcHRpb246IFwiRG93bmxvYWQgeW91ciBvcmdhbml6YXRpb24ncyBsb2cgZW50cmllcyBhcyBhIGZpbGUgKHZpZXdpbmcgbG9ncyBvbmx5IG5lZWRzICdWaWV3IGFsZXJ0aW5nJylcIiwgY2F0ZWdvcnk6ICdPYnNlcnZhYmlsaXR5JyB9LFxuICB7IGlkOiAncmVwb3J0czpyZWFkJywgbGFiZWw6ICdWaWV3IHJlcG9ydHMnLCBkZXNjcmlwdGlvbjogJ1ZpZXcgYW5hbHl0aWNzIGFuZCByZXBvcnRzJywgY2F0ZWdvcnk6ICdJbnNpZ2h0cycgfSxcbiAgeyBpZDogJ3JlcG9ydHM6cm9sbHVwJywgbGFiZWw6ICdSb2xsIHVwIHRlYW0gcmVwb3J0cycsIGRlc2NyaXB0aW9uOiAnSW5jbHVkZSBkZXNjZW5kYW50IHRlYW1zIHdoZW4gdmlld2luZyByZXBvcnRzJywgY2F0ZWdvcnk6ICdJbnNpZ2h0cycgfSxcbiAgeyBpZDogJ21lc3NhZ2VzOnJlYWQnLCBsYWJlbDogJ1ZpZXcgbWVzc2FnZXMnLCBkZXNjcmlwdGlvbjogJ1ZpZXcgbWVzc2FnZXMgYW5kIGFubm91bmNlbWVudHMnLCBjYXRlZ29yeTogJ01lc3NhZ2luZycgfSxcbiAgeyBpZDogJ21lc3NhZ2VzOndyaXRlJywgbGFiZWw6ICdTZW5kIG1lc3NhZ2VzJywgZGVzY3JpcHRpb246ICdTZW5kIG1lc3NhZ2VzIGFuZCBhbm5vdW5jZW1lbnRzJywgY2F0ZWdvcnk6ICdNZXNzYWdpbmcnIH0sXG4gIHsgaWQ6ICdiaWxsaW5nOnJlYWQnLCBsYWJlbDogJ1ZpZXcgYmlsbGluZycsIGRlc2NyaXB0aW9uOiAnVmlldyBzdWJzY3JpcHRpb25zIGFuZCB1c2FnZScsIGNhdGVnb3J5OiAnQmlsbGluZyAmIFF1b3RhcycgfSxcbiAgeyBpZDogJ2JpbGxpbmc6bWFuYWdlJywgbGFiZWw6ICdNYW5hZ2UgYmlsbGluZycsIGRlc2NyaXB0aW9uOiAnTWFuYWdlIHN1YnNjcmlwdGlvbnMsIGFkZC1vbnMsIGFuZCB0aGUgYmlsbGluZyBwb3J0YWwnLCBjYXRlZ29yeTogJ0JpbGxpbmcgJiBRdW90YXMnIH0sXG4gIHsgaWQ6ICdxdW90YXM6cmVhZCcsIGxhYmVsOiAnVmlldyBxdW90YXMnLCBkZXNjcmlwdGlvbjogJ1ZpZXcgb3JnYW5pemF0aW9uIHF1b3RhcyBhbmQgdXNhZ2UnLCBjYXRlZ29yeTogJ0JpbGxpbmcgJiBRdW90YXMnIH0sXG4gIHsgaWQ6ICdyZWdpc3RyeTpyZWFkJywgbGFiZWw6ICdWaWV3IHJlZ2lzdHJ5JywgZGVzY3JpcHRpb246ICdWaWV3IHRoZSBjb250YWluZXIgaW1hZ2UgcmVnaXN0cnknLCBjYXRlZ29yeTogJ1JlZ2lzdHJ5JyB9LFxuICB7IGlkOiAncmVnaXN0cnk6d3JpdGUnLCBsYWJlbDogJ01hbmFnZSByZWdpc3RyeScsIGRlc2NyaXB0aW9uOiAnRGVsZXRlIGFuZCBjb3B5IGNvbnRhaW5lciBpbWFnZXMnLCBjYXRlZ29yeTogJ1JlZ2lzdHJ5JyB9LFxuICB7IGlkOiAnb3JnOnNldHRpbmdzJywgbGFiZWw6ICdPcmdhbml6YXRpb24gc2V0dGluZ3MnLCBkZXNjcmlwdGlvbjogJ01hbmFnZSBnZW5lcmFsIG9yZyBzZXR0aW5ncyBhbmQgQUkgY29uZmlnJywgY2F0ZWdvcnk6ICdPcmdhbml6YXRpb24nIH0sXG4gIHsgaWQ6ICdvcmc6aWRwJywgbGFiZWw6ICdNYW5hZ2UgU1NPL0lkUCcsIGRlc2NyaXB0aW9uOiAnQ29uZmlndXJlIHNpbmdsZSBzaWduLW9uIGFuZCBpZGVudGl0eSBwcm92aWRlcnMnLCBjYXRlZ29yeTogJ09yZ2FuaXphdGlvbicgfSxcbiAgeyBpZDogJ29yZzprbXMnLCBsYWJlbDogJ01hbmFnZSBlbmNyeXB0aW9uIGtleXMnLCBkZXNjcmlwdGlvbjogJ0NvbmZpZ3VyZSBjdXN0b21lci1tYW5hZ2VkIEtNUyBlbmNyeXB0aW9uIGtleXMnLCBjYXRlZ29yeTogJ09yZ2FuaXphdGlvbicgfSxcbiAgeyBpZDogJ29yZzppbXBlcnNvbmF0aW9uJywgbGFiZWw6ICdNYW5hZ2UgaW1wZXJzb25hdGlvbiBwb2xpY3knLCBkZXNjcmlwdGlvbjogJ0NvbnRyb2wgd2hldGhlciBwbGF0Zm9ybSBvcGVyYXRvcnMgbWF5IHZpZXcgdGhlIG9yZ2FuaXphdGlvbiBhcyBvbmUgb2YgaXRzIG1lbWJlcnMnLCBjYXRlZ29yeTogJ09yZ2FuaXphdGlvbicgfSxcbl07XG5cbmNvbnN0IFBFUk1JU1NJT05fTEFCRUxTID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oUEVSTUlTU0lPTl9DQVRBTE9HLm1hcCgocCkgPT4gW3AuaWQsIHAubGFiZWxdKSk7XG5cbi8qKiBIdW1hbiBsYWJlbCBmb3IgYSBwZXJtaXNzaW9uIGlkIChmYWxscyBiYWNrIHRvIHRoZSByYXcgaWQgZm9yIGFuIHVua25vd24gb25lKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwZXJtaXNzaW9uTGFiZWwoaWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBQRVJNSVNTSU9OX0xBQkVMUy5nZXQoaWQpID8/IGlkO1xufVxuXG4vKiogT25lIHBpY2tlciBzZWN0aW9uOiBhIGNhdGVnb3J5IGFuZCB0aGUgcGVybWlzc2lvbnMgaXQgY29udGFpbnMsIGluIGNhdGFsb2cgb3JkZXIuICovXG5leHBvcnQgaW50ZXJmYWNlIFBlcm1pc3Npb25DYXRlZ29yeSB7XG4gIGNhdGVnb3J5OiBzdHJpbmc7XG4gIHBlcm1pc3Npb25zOiBQZXJtaXNzaW9uTWV0YVtdO1xufVxuXG4vKiogR3JvdXAgYSBwZXJtaXNzaW9uIGxpc3QgaW50byBjYXRlZ29yaWVzLCBwcmVzZXJ2aW5nIGNhdGFsb2cgb3JkZXIuICovXG5mdW5jdGlvbiBncm91cEJ5Q2F0ZWdvcnkocGVybXM6IHJlYWRvbmx5IFBlcm1pc3Npb25NZXRhW10pOiBQZXJtaXNzaW9uQ2F0ZWdvcnlbXSB7XG4gIGNvbnN0IG9yZGVyOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBieUNhdGVnb3J5ID0gbmV3IE1hcDxzdHJpbmcsIFBlcm1pc3Npb25NZXRhW10+KCk7XG4gIGZvciAoY29uc3QgcCBvZiBwZXJtcykge1xuICAgIGlmICghYnlDYXRlZ29yeS5oYXMocC5jYXRlZ29yeSkpIHsgYnlDYXRlZ29yeS5zZXQocC5jYXRlZ29yeSwgW10pOyBvcmRlci5wdXNoKHAuY2F0ZWdvcnkpOyB9XG4gICAgYnlDYXRlZ29yeS5nZXQocC5jYXRlZ29yeSkhLnB1c2gocCk7XG4gIH1cbiAgcmV0dXJuIG9yZGVyLm1hcCgoY2F0ZWdvcnkpID0+ICh7IGNhdGVnb3J5LCBwZXJtaXNzaW9uczogYnlDYXRlZ29yeS5nZXQoY2F0ZWdvcnkpISB9KSk7XG59XG5cbi8qKiBDaGVjayB3aGV0aGVyIGEgc3RyaW5nIGlzIGEgdmFsaWQgUGVybWlzc2lvbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkUGVybWlzc2lvbih2YWx1ZTogc3RyaW5nKTogdmFsdWUgaXMgUGVybWlzc2lvbiB7XG4gIHJldHVybiAoQUxMX1BFUk1JU1NJT05TIGFzIHJlYWRvbmx5IHN0cmluZ1tdKS5pbmNsdWRlcyh2YWx1ZSk7XG59XG5cbi8qKlxuICogUGVybWlzc2lvbnMgdGhhdCBtdXN0IE5FVkVSIGJlIGdyYW50YWJsZSB0aHJvdWdoIGEgdXNlci1hdXRob3JlZCBDVVNUT00gUm9sZSDigJRcbiAqIHRoZXkgZ2F0ZSBwbGF0Zm9ybS1vcGVyYXRvciBzdXJmYWNlcyAodGhlIHNoYXJlZCBpbWFnZSByZWdpc3RyeSksIHNvIGFsbG93aW5nXG4gKiBhbiBvcmcgYWRtaW4gdG8gbWludCBhIFJvbGUgY2FycnlpbmcgdGhlbSB3b3VsZCBiZSBhIGxhdGVudCBwcml2aWxlZ2VcbiAqIGVzY2FsYXRpb24uIFRoZXkgYXJlIE5PVCBzZWVkZWQgaW50byBBTlkgYnVpbHQtaW4gUm9sZSBidW5kbGUgKG5laXRoZXJcbiAqIGBtZW1iZXJgIG5vciBgYWRtaW5gKSwgc28gdGhlIG9ubHkgaG9sZGVyIGlzIGEgc3VwZXJhZG1pbiAoaW1wbGljaXQtYWxsKSDigJRcbiAqIHdoaWNoIGlzIHdoYXQgbWFrZXMgdGhlIGltYWdlLXJlZ2lzdHJ5IGdhdGVzIHRoYXQgcmVxdWlyZSB0aGVtIGVmZmVjdGl2ZWx5XG4gKiBzdXBlcmFkbWluLW9ubHkuIFRoaXMgbGlzdCBBTFNPIGJsb2NrcyBjdXN0b20tUm9sZSBhdXRob3JpbmcgZnJvbSByZXF1ZXN0aW5nXG4gKiB0aGVtIChzZWUgcGxhdGZvcm0gYHNhbml0aXplUGVybWlzc2lvbnNgKS5cbiAqL1xuZXhwb3J0IGNvbnN0IFNVUEVSQURNSU5fT05MWV9QRVJNSVNTSU9OUzogcmVhZG9ubHkgUGVybWlzc2lvbltdID0gW1xuICAncmVnaXN0cnk6cmVhZCcsXG4gICdyZWdpc3RyeTp3cml0ZScsXG5dO1xuXG4vKipcbiAqIFBlcm1pc3Npb25zIGFuIG9yZyBtYXkgYXNzaWduIHZpYSBhIENVU1RPTSBSb2xlIOKAlCBldmVyeSBwZXJtaXNzaW9uIGV4Y2VwdCB0aGVcbiAqIHtAbGluayBTVVBFUkFETUlOX09OTFlfUEVSTUlTU0lPTlN9LiBDdXN0b20tUm9sZSBjcmVhdGUvdXBkYXRlIHZhbGlkYXRlcyB0aGVcbiAqIHJlcXVlc3RlZCBwZXJtaXNzaW9uIHNldCBhZ2FpbnN0IHRoaXMgKHNlZSBwbGF0Zm9ybSByb2xlcy1zZXJ2aWNlKS5cbiAqL1xuZXhwb3J0IGNvbnN0IE9SR19BU1NJR05BQkxFX1BFUk1JU1NJT05TOiByZWFkb25seSBQZXJtaXNzaW9uW10gPVxuICBBTExfUEVSTUlTU0lPTlMuZmlsdGVyKChwKSA9PiAhU1VQRVJBRE1JTl9PTkxZX1BFUk1JU1NJT05TLmluY2x1ZGVzKHApKTtcblxuLyoqIFdoZXRoZXIgYHBlcm1pc3Npb25gIG1heSBiZSBncmFudGVkIHRocm91Z2ggYSB1c2VyLWF1dGhvcmVkIGN1c3RvbSBSb2xlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT3JnQXNzaWduYWJsZVBlcm1pc3Npb24ocGVybWlzc2lvbjogUGVybWlzc2lvbik6IGJvb2xlYW4ge1xuICByZXR1cm4gIVNVUEVSQURNSU5fT05MWV9QRVJNSVNTSU9OUy5pbmNsdWRlcyhwZXJtaXNzaW9uKTtcbn1cblxuLyoqXG4gKiBDYXRlZ29yeSDihpIgcGVybWlzc2lvbnMgZm9yIHRoZSBjdXN0b20tUm9sZSBBVVRIT1JJTkcgcGlja2VyOiB0aGUgY2F0YWxvZyBtaW51c1xuICogdGhlIHtAbGluayBTVVBFUkFETUlOX09OTFlfUEVSTUlTU0lPTlN9LCB3aXRoIGFueSBub3ctZW1wdHkgY2F0ZWdvcnkgZHJvcHBlZFxuICogKHNvIFwiUmVnaXN0cnlcIiBkaXNhcHBlYXJzKS4gVGhlIGdyb3VwZWQgdmlldyBvZlxuICoge0BsaW5rIE9SR19BU1NJR05BQkxFX1BFUk1JU1NJT05TfS5cbiAqL1xuZXhwb3J0IGNvbnN0IE9SR19BU1NJR05BQkxFX0NBVEVHT1JJRVM6IHJlYWRvbmx5IFBlcm1pc3Npb25DYXRlZ29yeVtdID1cbiAgZ3JvdXBCeUNhdGVnb3J5KFBFUk1JU1NJT05fQ0FUQUxPRy5maWx0ZXIoKHApID0+IGlzT3JnQXNzaWduYWJsZVBlcm1pc3Npb24ocC5pZCkpKTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFBlcm1pc3Npb24tc2NvcGVkIGNyZWRlbnRpYWxzIChwZXJzb25hbCBhY2Nlc3Mga2V5cyAvIG1hY2hpbmUgdG9rZW5zKVxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBFdmVyeSBgOnJlYWRgIHBlcm1pc3Npb24g4oCUIHRoZSBcInJlYWQtb25seVwiIHByZXNldCBhIG5ldyBwZXJzb25hbCBhY2Nlc3Mga2V5XG4gKiBzdGFydHMgZnJvbS4gRGVyaXZlZCBmcm9tIHRoZSBjYXRhbG9nIHNvIGEgbmV3IHJlc291cmNlJ3MgcmVhZCBwZXJtaXNzaW9uXG4gKiBqb2lucyB0aGUgcHJlc2V0IHdpdGhvdXQgYSBzZWNvbmQgZWRpdC5cbiAqL1xuZXhwb3J0IGNvbnN0IFJFQURfT05MWV9QRVJNSVNTSU9OUzogcmVhZG9ubHkgUGVybWlzc2lvbltdID1cbiAgQUxMX1BFUk1JU1NJT05TLmZpbHRlcigocCkgPT4gcC5lbmRzV2l0aCgnOnJlYWQnKSk7XG5cbi8qKlxuICogTm9ybWFsaXplIGEgcmVxdWVzdGVkIHBlcm1pc3Npb24gc3Vic2V0OiBldmVyeSBlbnRyeSBtdXN0IGJlIGEgY2F0YWxvZyBpZFxuICogKGFueXRoaW5nIGVsc2Ug4oaSIGBudWxsYCwgdGhlIGNhbGxlcidzIDQwMCksIGR1cGxpY2F0ZXMgY29sbGFwc2UsIGFuZCB0aGVcbiAqIHJlc3VsdCBpcyBpbiBjYW5vbmljYWwgY2F0YWxvZyBvcmRlciBzbyBhIHN0b3JlZCBzdWJzZXQgY29tcGFyZXMgc3RhYmx5LlxuICogQW4gRU1QVFkgYXJyYXkgaXMgdmFsaWQg4oCUIGEga2V5IHRoYXQgY2FuIGF1dGhlbnRpY2F0ZSBidXQgZG8gbm90aGluZyDigJQgYW5kXG4gKiBpcyBkaXN0aW5jdCBmcm9tIFwibm8gc3Vic2V0XCIgKGB1bmRlZmluZWRgKSwgd2hpY2ggbWVhbnMgZnVsbCBhY2Nlc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVQZXJtaXNzaW9uU3Vic2V0KHJlcXVlc3RlZDogcmVhZG9ubHkgdW5rbm93bltdKTogUGVybWlzc2lvbltdIHwgbnVsbCB7XG4gIGNvbnN0IHdhbnRlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IHAgb2YgcmVxdWVzdGVkKSB7XG4gICAgaWYgKHR5cGVvZiBwICE9PSAnc3RyaW5nJyB8fCAhaXNWYWxpZFBlcm1pc3Npb24ocCkpIHJldHVybiBudWxsO1xuICAgIHdhbnRlZC5hZGQocCk7XG4gIH1cbiAgcmV0dXJuIEFMTF9QRVJNSVNTSU9OUy5maWx0ZXIoKHApID0+IHdhbnRlZC5oYXMocCkpO1xufVxuXG4vKipcbiAqIFRoZSBwZXJtaXNzaW9ucyBhIHBlcm1pc3Npb24tc2NvcGVkIGNyZWRlbnRpYWwgYWN0dWFsbHkgY2FycmllczogdGhlXG4gKiBJTlRFUlNFQ1RJT04gb2YgdGhlIHN1YnNldCBpdCB3YXMgY3JlYXRlZCB3aXRoIGFuZCB0aGUgaG9sZGVyJ3MgQ1VSUkVOVFxuICogZWZmZWN0aXZlIHBlcm1pc3Npb25zLCBpbiBjYXRhbG9nIG9yZGVyLiBSZS1ldmFsdWF0ZWQgYXQgZXZlcnkgaXNzdWUsIHNvXG4gKiBsb3NpbmcgYSBSb2xlIHNocmlua3MgdGhlIGNyZWRlbnRpYWwgYW5kIG5vdGhpbmcgY2FuIGV2ZXIgZ3JvdyBpdCBwYXN0IHRoZVxuICogc3Vic2V0IGl0IHdhcyBjcmVhdGVkIHdpdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnNlY3RQZXJtaXNzaW9ucyhcbiAgZWZmZWN0aXZlOiByZWFkb25seSBzdHJpbmdbXSxcbiAgc3Vic2V0OiByZWFkb25seSBzdHJpbmdbXSxcbik6IFBlcm1pc3Npb25bXSB7XG4gIGNvbnN0IGFsbG93ZWQgPSBuZXcgU2V0KHN1YnNldCk7XG4gIGNvbnN0IGhlbGQgPSBuZXcgU2V0KGVmZmVjdGl2ZSk7XG4gIHJldHVybiBBTExfUEVSTUlTU0lPTlMuZmlsdGVyKChwKSA9PiBhbGxvd2VkLmhhcyhwKSAmJiBoZWxkLmhhcyhwKSk7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBCdWlsdC1pbiBSb2xlIHNlZWQgYnVuZGxlc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBQZXJtaXNzaW9uIGJ1bmRsZXMgdXNlZCB0byBTRUVEIHRoZSBidWlsdC1pbiBSb2xlcyAoXCJBZG1pblwiLCBcIk1lbWJlclwiKS5cbiAqXG4gKiBUaGlzIGlzIHRoZSBzaW5nbGUgZGVmaW5pdGlvbiBvZiB3aGF0IHRob3NlIGJ1aWx0LWluIFJvbGVzIGdyYW50IOKAlCBpdCBpcyB1c2VkXG4gKiB3aGVuIGEgUm9sZSByZWNvcmQgaXMgY3JlYXRlZCAoYW5kIGJ5IHRoZSBzdGFydHVwIGJhY2tmaWxsKSB0byBwb3B1bGF0ZSB0aGF0XG4gKiBSb2xlJ3Mgb3duIGBwZXJtaXNzaW9uc1tdYC4gSXQgaXMgTk9UIGEgcnVudGltZSBwZXJtaXNzaW9uIHNvdXJjZTogYSB1c2VyJ3NcbiAqIGVmZmVjdGl2ZSBwZXJtaXNzaW9ucyBjb21lIE9OTFkgZnJvbSB0aGUgUm9sZXMgYXNzaWduZWQgdG8gdGhlbSAoc2VlXG4gKiB7QGxpbmsgcmVzb2x2ZVVzZXJQZXJtaXNzaW9uc30pLiBUaGUgY29hcnNlIGByb2xlYCBsYWJlbCAob3duZXIvYWRtaW4vbWVtYmVyKVxuICogc3Vydml2ZXMgb25seSBmb3IgYGlzQWRtaW5gL293bmVyc2hpcC9kaXNwbGF5LCBuZXZlciB0byBncmFudCBwZXJtaXNzaW9ucy5cbiAqXG4gKiAtIGBtZW1iZXJgICDigJQgZGF5LXRvLWRheSBidWlsZGVyOiByZWFkICsgd3JpdGUgb24gcGlwZWxpbmVzL3RlbXBsYXRlcy9wbHVnaW5zLFxuICogICByZWFkIGVsc2V3aGVyZS4gTm8gbWVtYmVyL3JvbGUvYmlsbGluZyBtYW5hZ2VtZW50LCBubyBjb21wbGlhbmNlL2FsZXJ0XG4gKiAgIGF1dGhvcmluZywgYW5kIG5vIGA6cHVibGlzaGAgb24gYW55IGNhdGFsb2cuXG4gKiAtIGBhZG1pbmAgICDigJQgZnVsbCBvcmcgYWRtaW5pc3RyYXRpb246IGV2ZXJ5IE9SRy1BU1NJR05BQkxFIHBlcm1pc3Npb24gKGkuZS5cbiAqICAgQUxMX1BFUk1JU1NJT05TIG1pbnVzIHRoZSB7QGxpbmsgU1VQRVJBRE1JTl9PTkxZX1BFUk1JU1NJT05TfSwgc28gYHJlZ2lzdHJ5OipgXG4gKiAgIHN0YXkgc3VwZXJhZG1pbi1pbXBsaWNpdC1vbmx5IGFuZCBhcmUgTk9UIGdyYW50ZWQgdG8gb3JnIGFkbWlucykuXG4gKiAtIGBvd25lcmAgICDigJQgc2FtZSBhcyBhZG1pbiAob3duZXJzaGlwIGl0c2VsZiDigJQgdHJhbnNmZXIvZGVsZXRlIOKAlCBpcyBnYXRlZFxuICogICBzZXBhcmF0ZWx5LCBub3QgdmlhIGEgcGVybWlzc2lvbikuXG4gKi9cbmNvbnN0IE1FTUJFUl9QRVJNSVNTSU9OUzogcmVhZG9ubHkgUGVybWlzc2lvbltdID0gW1xuICAncGlwZWxpbmVzOnJlYWQnLCAncGlwZWxpbmVzOndyaXRlJyxcbiAgJ3RlbXBsYXRlczpyZWFkJywgJ3RlbXBsYXRlczp3cml0ZScsXG4gICdwbHVnaW5zOnJlYWQnLCAncGx1Z2luczp3cml0ZScsXG4gICdjb21wbGlhbmNlOnJlYWQnLFxuICAnZGFzaGJvYXJkczpyZWFkJyxcbiAgJ29ic2VydmFiaWxpdHk6cmVhZCcsXG4gICdyZXBvcnRzOnJlYWQnLFxuICAnbWVzc2FnZXM6cmVhZCcsICdtZXNzYWdlczp3cml0ZScsXG4gICdiaWxsaW5nOnJlYWQnLFxuICAncXVvdGFzOnJlYWQnLFxuXTtcblxuY29uc3QgQURNSU5fUEVSTUlTU0lPTlM6IHJlYWRvbmx5IFBlcm1pc3Npb25bXSA9IFsuLi5PUkdfQVNTSUdOQUJMRV9QRVJNSVNTSU9OU107XG5cbi8qKlxuICogU2VlZCBidW5kbGUgZm9yIGVhY2ggYnVpbHQtaW4gUm9sZSwga2V5ZWQgYnkgdGhlIGNvYXJzZSByb2xlIGl0IGdyYW50cy5cbiAqIENvbnN1bWVkIGJ5IHRoZSBSb2xlIHNlZWRlciArIHRoZSBzdGFydHVwIGJhY2tmaWxsIHRvIHBvcHVsYXRlIGEgYnVpbHQtaW5cbiAqIFJvbGUncyBgcGVybWlzc2lvbnNbXWAuIE5PVCBjb25zdWx0ZWQgYXQgcmVxdWVzdCB0aW1lIOKAlCBzZWVcbiAqIHtAbGluayByZXNvbHZlVXNlclBlcm1pc3Npb25zfS5cbiAqL1xuZXhwb3J0IGNvbnN0IFJPTEVfUEVSTUlTU0lPTlM6IFJlY29yZDxPcmdSb2xlLCByZWFkb25seSBQZXJtaXNzaW9uW10+ID0ge1xuICBtZW1iZXI6IE1FTUJFUl9QRVJNSVNTSU9OUyxcbiAgYWRtaW46IEFETUlOX1BFUk1JU1NJT05TLFxuICBvd25lcjogQURNSU5fUEVSTUlTU0lPTlMsXG59O1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gUmVzb2x1dGlvblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBSZXNvbHZlIGEgdXNlcidzIGVmZmVjdGl2ZSBvcmcgcGVybWlzc2lvbnMgZnJvbSB0aGUgUm9sZXMgYXNzaWduZWQgdG8gdGhlbS5cbiAqXG4gKiBTaW5nbGUtc291cmNlIG1vZGVsOiBhIHVzZXIncyBhYmlsaXRpZXMgYXJlIEVYQUNUTFkgdGhlIHVuaW9uIG9mIHRoZVxuICogcGVybWlzc2lvbnMgY2FycmllZCBieSB0aGUgUm9sZXMgdGhleSBob2xkIChhIFJvbGUgPSBhIG5hbWVkIHBlcm1pc3Npb24gc2V0O1xuICogYnVpbHQtaW4gUm9sZXMgY2FycnkgdGhlaXIgYnVuZGxlIGV4cGxpY2l0bHksIHNlZWRlZCBmcm9tXG4gKiB7QGxpbmsgUk9MRV9QRVJNSVNTSU9OU30pLiBUaGVyZSBpcyBubyBzZXBhcmF0ZSByb2xlLWRlcml2ZWQgYmFzZWxpbmUg4oCUIHRoZVxuICogY29hcnNlIGByb2xlYCBsYWJlbCBubyBsb25nZXIgZ3JhbnRzIGFueXRoaW5nIG9uIGl0cyBvd24uXG4gKlxuICogMS4gUGxhdGZvcm0gc3VwZXJhZG1pbnMgKGBpc1N1cGVyQWRtaW5gKSBhbHdheXMgZ2V0IEFMTCBwZXJtaXNzaW9ucy5cbiAqIDIuIE90aGVyd2lzZSwgdW5pb24gZXZlcnkgcGVybWlzc2lvbiBncmFudGVkIGJ5IHRoZSB1c2VyJ3MgYXNzaWduZWQgUm9sZXMuXG4gKiAzLiBJbnZhbGlkL3Vua25vd24gcGVybWlzc2lvbiBzdHJpbmdzIGFyZSBzaWxlbnRseSBpZ25vcmVkLlxuICpcbiAqIEBwYXJhbSBhc3NpZ25lZFBlcm1pc3Npb25zIC0gRmxhdHRlbmVkIHBlcm1pc3Npb25zIGZyb20gZXZlcnkgUm9sZSB0aGUgdXNlciBob2xkc1xuICogQHBhcmFtIGlzU3VwZXJBZG1pbiAtIFdoZXRoZXIgdGhlIHVzZXIgaGFzIHRoZSBnbG9iYWwgc3VwZXItYWRtaW4gZmxhZ1xuICogQHJldHVybnMgRWZmZWN0aXZlIHBlcm1pc3Npb25zIGluIGNhbm9uaWNhbCBvcmRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVVzZXJQZXJtaXNzaW9ucyhcbiAgYXNzaWduZWRQZXJtaXNzaW9ucz86IHJlYWRvbmx5IHN0cmluZ1tdIHwgbnVsbCxcbiAgaXNTdXBlckFkbWluPzogYm9vbGVhbixcbik6IFBlcm1pc3Npb25bXSB7XG4gIGlmIChpc1N1cGVyQWRtaW4pIHJldHVybiBbLi4uQUxMX1BFUk1JU1NJT05TXTtcblxuICBjb25zdCBwZXJtcyA9IG5ldyBTZXQ8UGVybWlzc2lvbj4oKTtcbiAgaWYgKGFzc2lnbmVkUGVybWlzc2lvbnMpIHtcbiAgICBmb3IgKGNvbnN0IHAgb2YgYXNzaWduZWRQZXJtaXNzaW9ucykge1xuICAgICAgaWYgKGlzVmFsaWRQZXJtaXNzaW9uKHApKSBwZXJtcy5hZGQocCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBBTExfUEVSTUlTU0lPTlMuZmlsdGVyKHAgPT4gcGVybXMuaGFzKHApKTtcbn1cblxuLyoqIFdoZXRoZXIgYSByZXNvbHZlZCBwZXJtaXNzaW9uIGxpc3QgZ3JhbnRzIGBwZXJtaXNzaW9uYCAoc3VwZXJhZG1pbiDih5IgYWx3YXlzKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNQZXJtaXNzaW9uKFxuICBncmFudGVkOiByZWFkb25seSBzdHJpbmdbXSB8IG51bGwgfCB1bmRlZmluZWQsXG4gIHBlcm1pc3Npb246IFBlcm1pc3Npb24sXG4gIGlzU3VwZXJBZG1pbj86IGJvb2xlYW4sXG4pOiBib29sZWFuIHtcbiAgaWYgKGlzU3VwZXJBZG1pbikgcmV0dXJuIHRydWU7XG4gIHJldHVybiAhIWdyYW50ZWQgJiYgZ3JhbnRlZC5pbmNsdWRlcyhwZXJtaXNzaW9uKTtcbn1cbiJdfQ==
333
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvcGVybWlzc2lvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQXlHdEMsNEVBQTRFO0FBQzVFLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBMEI7SUFDcEQsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CO0lBQ3hELGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLG1CQUFtQjtJQUN4RCxjQUFjLEVBQUUsZUFBZSxFQUFFLGlCQUFpQjtJQUNsRCxpQkFBaUIsRUFBRSx3QkFBd0IsRUFBRSxtQkFBbUI7SUFDaEUsa0JBQWtCLEVBQUUsbUJBQW1CO0lBQ3ZDLGlCQUFpQixFQUFFLGtCQUFrQjtJQUNyQyxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsb0JBQW9CLEVBQUUseUJBQXlCO0lBQ2pGLGlCQUFpQixFQUFFLGtCQUFrQjtJQUNyQyxvQkFBb0IsRUFBRSxxQkFBcUI7SUFDM0MsYUFBYTtJQUNiLGNBQWMsRUFBRSxnQkFBZ0I7SUFDaEMsZUFBZSxFQUFFLGdCQUFnQjtJQUNqQyxjQUFjLEVBQUUsZ0JBQWdCO0lBQ2hDLGFBQWE7SUFDYixlQUFlLEVBQUUsZ0JBQWdCO0lBQ2pDLGNBQWMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLG1CQUFtQjtDQUMxRCxDQUFDO0FBRUY7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQXNCO0lBQ2pELDRFQUE0RTtJQUM1RSxtQkFBbUI7SUFDbkIsdUJBQXVCO0lBQ3ZCLDRCQUE0QjtJQUM1QiwwRUFBMEU7SUFDMUUsNEJBQTRCO0lBQzVCLDBFQUEwRTtJQUMxRSw4RUFBOEU7SUFDOUUsbUJBQW1CO0lBQ25CLGVBQWU7SUFDZixrRUFBa0U7SUFDbEUsOEJBQThCO0lBQzlCLDRCQUE0QjtJQUM1QixtQkFBbUI7Q0FDcEIsQ0FBQztB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LENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkQsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxNQUFNLFVBQVUsdUJBQXVCLENBQ3JDLFdBQXlCLEVBQ3pCLG9CQUE2QjtJQUU3QixPQUFPLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMseUJBQXlCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1RyxDQUFDO0FBRUQsb0ZBQW9GO0FBQ3BGLE1BQU0sVUFBVSxhQUFhLENBQzNCLE9BQTZDLEVBQzdDLFVBQXNCLEVBQ3RCLFlBQXNCO0lBRXRCLElBQUksWUFBWTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzlCLE9BQU8sQ0FBQyxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ25ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBPcmdSb2xlIH0gZnJvbSAnLi9jb21tb24uanMnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gUGVybWlzc2lvbiBpZGVudGlmaWVyc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDYW5vbmljYWwgZmluZS1ncmFpbmVkIHBlcm1pc3Npb24gaWRlbnRpZmllcnMsIGluIGByZXNvdXJjZTphY3Rpb25gIGZvcm0uXG4gKlxuICogVGhlc2UgYXJlIHRoZSBPUkctU0NPUEVEIGNhcGFiaWxpdGllcyBhIFJvbGUgY2FuIGdyYW50IChSQkFDKS4gQ29hcnNlIGJ5XG4gKiBkZXNpZ24g4oCUIGA6d3JpdGVgIGNvdmVycyBjcmVhdGUvdXBkYXRlL2RlbGV0ZSBmb3IgYSByZXNvdXJjZSDigJQgc28gdGhlIGNhdGFsb2dcbiAqIGFuZCBwZXJtaXNzaW9uLXBpY2tlciBVSSBzdGF5IHNtYWxsOyBzcGxpdCBhIGA6d3JpdGVgIGludG8gYDpjcmVhdGVgL2A6ZGVsZXRlYFxuICogbGF0ZXIgaWYgYSByZXNvdXJjZSBuZWVkcyBpdC5cbiAqXG4gKiBOT1QgbW9kZWxlZCBoZXJlIChpbnRlbnRpb25hbGx5KTogcGxhdGZvcm0tb3BlcmF0b3IgYWN0aW9ucyAob3JnIGRlbGV0ZSwgdGllci9cbiAqIHF1b3RhIG92ZXJyaWRlLCB1c2VyIGFkbWluLCBpbXBlcnNvbmF0aW9uLCBwbGF0Zm9ybSBzZXR0aW5ncykgc3RheSBiZWhpbmQgdGhlXG4gKiBnbG9iYWwgYGlzU3VwZXJBZG1pbmAgZmxhZywgbm90IGEgcGVyLW9yZyBwZXJtaXNzaW9uOyBhbmQgYHJlcXVpcmVTdGVwVXBgXG4gKiAoTUZBKSAvIGByZXF1aXJlRmVhdHVyZWAgKHBsYW4gZW50aXRsZW1lbnRzKSByZW1haW4gb3J0aG9nb25hbCBnYXRlcy5cbiAqL1xuZXhwb3J0IHR5cGUgUGVybWlzc2lvbiA9XG4gIC8vIFBpcGVsaW5lc1xuICB8ICdwaXBlbGluZXM6cmVhZCdcbiAgfCAncGlwZWxpbmVzOndyaXRlJ1xuICB8ICdwaXBlbGluZXM6cHVibGlzaCdcbiAgLy8gR29sZGVuLXBhdGggcGlwZWxpbmUgdGVtcGxhdGVzLiBTcGxpdCBvdXQgb2YgYHBpcGVsaW5lczoqYCBzbyBhIHBsYXRmb3JtXG4gIC8vIHRlYW0gY2FuIGN1cmF0ZSB0aGUgc3RhcnRlciBjYXRhbG9nIFdJVEhPVVQgd3JpdGUgYWNjZXNzIHRvIGV2ZXJ5IHBpcGVsaW5lXG4gIC8vIChhbmQgdmljZSB2ZXJzYSkuIGA6cHVibGlzaGAgbWFwcyB0byB0aGVcbiAgLy8gdGVtcGxhdGUgbGFkZGVyJ3MgYHB1YmxpY2AgcnVuZzsgYG9yZ2AgYW5kIGBwcml2YXRlYCBuZWVkIG9ubHkgYDp3cml0ZWAuXG4gIHwgJ3RlbXBsYXRlczpyZWFkJ1xuICB8ICd0ZW1wbGF0ZXM6d3JpdGUnXG4gIHwgJ3RlbXBsYXRlczpwdWJsaXNoJ1xuICAvLyBQbHVnaW5zXG4gIHwgJ3BsdWdpbnM6cmVhZCdcbiAgfCAncGx1Z2luczp3cml0ZSdcbiAgfCAncGx1Z2luczpwdWJsaXNoJ1xuICAvLyBQbHVnaW4gZWNvc3lzdGVtIChkb2NzL3BsdWdpbi1wdWJsaXNoaW5nLm1kKS4gT3JnLWFzc2lnbmFibGU6XG4gIC8vICAtIGBwbHVnaW5zOmluc3RhbGxgICAgICAgICDigJQgaW5zdGFsbC91cGdyYWRlL3VuaW5zdGFsbCBsaXN0aW5ncyAob3IgUkVRVUVTVFxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbiBpbnN0YWxsIHdoZW4gdGhlIG9yZydzIHBvbGljeSBuZWVkcyBhcHByb3ZhbCkuXG4gIC8vICAtIGBwbHVnaW5faW5zdGFsbHM6bWFuYWdlYCDigJQgdGhlIG9yZydzIGNvbnN1bXB0aW9uIHBvbGljeSArIGRlY2lkaW5nIGluc3RhbGxcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMgV0lUSElOIHRoZSBvcmcgKG9yZy1sb2NhbCBvbmx5KS5cbiAgLy8gIC0gYHB1Ymxpc2hlcnM6bWFuYWdlYCAgICAgIOKAlCB0aGUgb3JnJ3MgcHVibGlzaGVyIHByb2ZpbGUgKyBzdWJtaXR0aW5nXG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjb3N5c3RlbSByZXF1ZXN0cyAoZXZlcnkgZGVjaXNpb24gaXMgc3lzdGVtLW9yZykuXG4gIC8vIFN5c3RlbS1vcmctb25seSAoc2VlIFNZU1RFTV9PUkdfT05MWV9QRVJNSVNTSU9OUyk6XG4gIC8vICAtIGBwbHVnaW5zOm1vZGVyYXRlYCAgICAgICDigJQgZGVjaWRlIHB1Ymxpc2ggcmVxdWVzdHMsIG1vZGVyYXRlLCB5YW5rLCBhZHZpc29yaWVzLlxuICAvLyAgLSBgcHVibGlzaGVyczp2ZXJpZnlgICAgICAg4oCUIHB1Ymxpc2hlciB0aWVycywgcHJvZmlsZSBjaGFuZ2VzLCB0cmFuc2ZlcnMuXG4gIHwgJ3BsdWdpbnM6aW5zdGFsbCdcbiAgfCAncGx1Z2luX2luc3RhbGxzOm1hbmFnZSdcbiAgfCAncHVibGlzaGVyczptYW5hZ2UnXG4gIHwgJ3BsdWdpbnM6bW9kZXJhdGUnXG4gIHwgJ3B1Ymxpc2hlcnM6dmVyaWZ5J1xuICAvLyBDb21wbGlhbmNlXG4gIHwgJ2NvbXBsaWFuY2U6cmVhZCdcbiAgfCAnY29tcGxpYW5jZTp3cml0ZSdcbiAgLy8gTWVtYmVycyAmIGFjY2Vzc1xuICB8ICdtZW1iZXJzOm1hbmFnZSdcbiAgfCAncm9sZXM6bWFuYWdlJ1xuICB8ICdpbnZpdGF0aW9uczptYW5hZ2UnXG4gIC8vIE9yZy1zY29wZWQgc2VydmljZSBhY2NvdW50cyAobm9uLWh1bWFuIHByaW5jaXBhbHMpIGFuZCB0aGVpciBhY2Nlc3Mga2V5cy5cbiAgLy8gU3BsaXQgb3V0IG9mIGBtZW1iZXJzOm1hbmFnZWAgYmVjYXVzZSBhIHNlcnZpY2UgYWNjb3VudCBpcyBhIENSRURFTlRJQUxcbiAgLy8gaG9sZGVyLCBub3QgYSBwZXJzb246IGdyYW50aW5nIHNvbWVvbmUgdGhlIGFiaWxpdHkgdG8gbWludCBsb25nLWxpdmVkXG4gIC8vIG1hY2hpbmUga2V5cyBpcyBhIGRpZmZlcmVudCBkZWNpc2lvbiBmcm9tIGxldHRpbmcgdGhlbSBtYW5hZ2UgdGhlIHJvc3Rlci5cbiAgfCAnc2VydmljZV9hY2NvdW50czptYW5hZ2UnXG4gIC8vIE9ic2VydmFiaWxpdHlcbiAgfCAnZGFzaGJvYXJkczpyZWFkJ1xuICB8ICdkYXNoYm9hcmRzOndyaXRlJ1xuICB8ICdvYnNlcnZhYmlsaXR5OnJlYWQnXG4gIHwgJ29ic2VydmFiaWxpdHk6d3JpdGUnXG4gIC8vIGBsb2dzOmV4cG9ydGAgaXMgc3BsaXQgT1VUIG9mIGBvYnNlcnZhYmlsaXR5OnJlYWRgIGRlbGliZXJhdGVseS4gUmVhZGluZ1xuICAvLyBsb2dzIGluIHRoZSBVSSBpcyBwYWdlZCBhbmQgZXBoZW1lcmFsOyBFWFBPUlRJTkcgdGhlbSBpcyBidWxrIGVncmVzcyB0aGF0XG4gIC8vIGxlYXZlcyB0aGUgYnVpbGRpbmcgYW5kIG91dGxpdmVzIGEgcmV2b2tlZCBzZXNzaW9uLCBzbyBhbiBvcmcgYWRtaW4gbXVzdCBiZVxuICAvLyBhYmxlIHRvIGdyYW50IGxvZyB2aWV3aW5nIHdpdGhvdXQgZ3JhbnRpbmcgZG93bmxvYWRzLlxuICB8ICdsb2dzOmV4cG9ydCdcbiAgLy8gSW5zaWdodHNcbiAgfCAncmVwb3J0czpyZWFkJ1xuICB8ICdyZXBvcnRzOnJvbGx1cCdcbiAgLy8gTWVzc2FnaW5nXG4gIHwgJ21lc3NhZ2VzOnJlYWQnXG4gIHwgJ21lc3NhZ2VzOndyaXRlJ1xuICAvLyBCaWxsaW5nICYgcXVvdGFzXG4gIHwgJ2JpbGxpbmc6cmVhZCdcbiAgfCAnYmlsbGluZzptYW5hZ2UnXG4gIHwgJ3F1b3RhczpyZWFkJ1xuICAvLyBSZWdpc3RyeVxuICB8ICdyZWdpc3RyeTpyZWFkJ1xuICB8ICdyZWdpc3RyeTp3cml0ZSdcbiAgLy8gT3JnYW5pemF0aW9uIHNldHRpbmdzLlxuICAvLyAgLSBgb3JnOnNldHRpbmdzYCDigJQgZ2VuZXJhbCBvcmcgc2V0dGluZ3MgKyBBSSBjb25maWcuXG4gIC8vICAtIGBvcmc6aWRwYCAgICAgIOKAlCBTU08gLyBJZFAgY29uZmlndXJhdGlvbiAoc2Vuc2l0aXZlOiBjb250cm9scyBsb2dpbikuXG4gIC8vICAtIGBvcmc6a21zYCAgICAgIOKAlCBjdXN0b21lci1tYW5hZ2VkIEtNUyBrZXkgY29uZmlndXJhdGlvbiAoc2Vuc2l0aXZlOlxuICAvLyAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzIGVuY3J5cHRpb24gb2Ygb3JnIGRhdGEpLlxuICAvLyAgLSBgb3JnOmltcGVyc29uYXRpb25gIOKAlCB0aGUgaW1wZXJzb25hdGlvbiBwb2xpY3kgKHNlbnNpdGl2ZTogY29udHJvbHMgd2hvXG4gIC8vICAgICAgICAgICAgICAgICAgICAgbWF5IFZJRVcgdGhlIG9yZydzIGRhdGEgYXMgb25lIG9mIGl0cyBtZW1iZXJzKS5cbiAgLy8gYG9yZzppZHBgL2Bvcmc6a21zYC9gb3JnOmltcGVyc29uYXRpb25gIHdlcmUgc3BsaXQgT1VUIG9mIGBvcmc6c2V0dGluZ3NgIHNvIGFcbiAgLy8gY3VzdG9tIHJvbGUgY2FuIGdyYW50IGdlbmVyYWwgc2V0dGluZ3MgV0lUSE9VVCB0aGUgc2Vuc2l0aXZlIHN1cmZhY2VzIOKAlCBhXG4gIC8vIFwic2V0dGluZ3MgbWFuYWdlclwiIHJvbGUgZm9yIG9yZyBuYW1lIG9yIEFJIHByb3ZpZGVyIG11c3Qgbm90IGFsc28gYmUgYWJsZSB0b1xuICAvLyBzd2l0Y2ggdGhlIG9yZyB0byBgb3BlbmAuIEFsbCByZW1haW4gb3JnLWFzc2lnbmFibGUgYW5kIGFyZSBzZWVkZWQgaW50byB0aGVcbiAgLy8gYWRtaW4vb3duZXIgYnVuZGxlcyAodmlhIE9SR19BU1NJR05BQkxFX1BFUk1JU1NJT05TKSBzbyBleGlzdGluZyBhZG1pbnMga2VlcFxuICAvLyBmdWxsIGFjY2Vzcy5cbiAgfCAnb3JnOnNldHRpbmdzJ1xuICB8ICdvcmc6aWRwJ1xuICB8ICdvcmc6a21zJ1xuICB8ICdvcmc6aW1wZXJzb25hdGlvbic7XG5cbi8qKiBBbGwgdmFsaWQgcGVybWlzc2lvbnMgKG9yZGVyIGRldGVybWluZXMgZGlzcGxheSBvcmRlciBpbiB0aGUgcGlja2VyKS4gKi9cbmV4cG9ydCBjb25zdCBBTExfUEVSTUlTU0lPTlM6IHJlYWRvbmx5IFBlcm1pc3Npb25bXSA9IFtcbiAgJ3BpcGVsaW5lczpyZWFkJywgJ3BpcGVsaW5lczp3cml0ZScsICdwaXBlbGluZXM6cHVibGlzaCcsXG4gICd0ZW1wbGF0ZXM6cmVhZCcsICd0ZW1wbGF0ZXM6d3JpdGUnLCAndGVtcGxhdGVzOnB1Ymxpc2gnLFxuICAncGx1Z2luczpyZWFkJywgJ3BsdWdpbnM6d3JpdGUnLCAncGx1Z2luczpwdWJsaXNoJyxcbiAgJ3BsdWdpbnM6aW5zdGFsbCcsICdwbHVnaW5faW5zdGFsbHM6bWFuYWdlJywgJ3B1Ymxpc2hlcnM6bWFuYWdlJyxcbiAgJ3BsdWdpbnM6bW9kZXJhdGUnLCAncHVibGlzaGVyczp2ZXJpZnknLFxuICAnY29tcGxpYW5jZTpyZWFkJywgJ2NvbXBsaWFuY2U6d3JpdGUnLFxuICAnbWVtYmVyczptYW5hZ2UnLCAncm9sZXM6bWFuYWdlJywgJ2ludml0YXRpb25zOm1hbmFnZScsICdzZXJ2aWNlX2FjY291bnRzOm1hbmFnZScsXG4gICdkYXNoYm9hcmRzOnJlYWQnLCAnZGFzaGJvYXJkczp3cml0ZScsXG4gICdvYnNlcnZhYmlsaXR5OnJlYWQnLCAnb2JzZXJ2YWJpbGl0eTp3cml0ZScsXG4gICdsb2dzOmV4cG9ydCcsXG4gICdyZXBvcnRzOnJlYWQnLCAncmVwb3J0czpyb2xsdXAnLFxuICAnbWVzc2FnZXM6cmVhZCcsICdtZXNzYWdlczp3cml0ZScsXG4gICdiaWxsaW5nOnJlYWQnLCAnYmlsbGluZzptYW5hZ2UnLFxuICAncXVvdGFzOnJlYWQnLFxuICAncmVnaXN0cnk6cmVhZCcsICdyZWdpc3RyeTp3cml0ZScsXG4gICdvcmc6c2V0dGluZ3MnLCAnb3JnOmlkcCcsICdvcmc6a21zJywgJ29yZzppbXBlcnNvbmF0aW9uJyxcbl07XG5cbi8qKlxuICogVGhlIENMT1NFRCBzZXQgb2YgZnVuY3Rpb25zIHRoYXQgdGFrZSBhIHtAbGluayBQZXJtaXNzaW9ufSBhbmQgZGVjaWRlIGFjY2Vzcy5cbiAqXG4gKiBcIklzIHBlcm1pc3Npb24gWCBlbmZvcmNlZCBhbnl3aGVyZT9cIiBoYXMgdG8gYmUgYW5zd2VyYWJsZSBzdGF0aWNhbGx5LCB3aGljaFxuICogYSBncmVwIGNhbid0IGRvOiBmb3VyIGRpZmZlcmVudCBjYWxsIHNoYXBlcyBjb25zdW1lIGEgcGVybWlzc2lvbiBpZFxuICogKGByZXF1aXJlUGVybWlzc2lvbigneCcpYCBhdCBhIHJvdXRlLCBgdXNlckhhc1Blcm1pc3Npb24ocmVxLCAneCcpYCBpbnNpZGUgYVxuICogY29udHJvbGxlciwgYW5kIGByZXNvbHZlVmlzaWJpbGl0eShyZXEsIHYsICd4JylgIC9cbiAqIGByZXF1aXJlVmlzaWJpbGl0eVdyaXRlQWNjZXNzKOKApiwgJ3gnKWAgaW4gdGhlIHZpc2liaWxpdHkgaGVscGVycyksIHNvIGEgbmFpdmVcbiAqIGdyZXAgZm9yIGEgcm91dGUtbGV2ZWwgZ2F0ZSByZXBvcnRzIGB0ZW1wbGF0ZXM6cHVibGlzaGAgYXMgVU5FTkZPUkNFRCB3aGVuIGl0XG4gKiBpcyBpbiBmYWN0IGVuZm9yY2VkIG9uIGV2ZXJ5IHRlbXBsYXRlIHB1Ymxpc2guXG4gKlxuICogVGhleSBhbGwgYm90dG9tIG91dCBpbiBgdXNlckhhc1Blcm1pc3Npb25gLCBzbyB0aGUgUlVOVElNRSBwcmltaXRpdmUgd2FzXG4gKiBhbHJlYWR5IG9uZS4gVGhpcyBjb25zdGFudCBtYWtlcyB0aGUgU1RBVElDIHN1cmZhY2Ugb25lIGFzIHdlbGw6IGl0IG5hbWVzXG4gKiBldmVyeSBlbnRyeSBwb2ludCwgc28gYHBlcm1pc3Npb24tY292ZXJhZ2UudGVzdC50c2AgY2FuIGVudW1lcmF0ZSB0aGUgY2F0YWxvZ1xuICogYW5kIHJlcG9ydCBlYWNoIHBlcm1pc3Npb24ncyBlbmZvcmNlbWVudCBzaXRlcyB3aXRob3V0IGd1ZXNzaW5nLiBBIG5ldyBnYXRlXG4gKiB0aGF0IHRha2VzIGEgYFBlcm1pc3Npb25gIG11c3QgYmUgbGlzdGVkIGhlcmUsIG9yIHRoZSBjb3ZlcmFnZSByZXBvcnQgc3RhcnRzXG4gKiBseWluZyBhYm91dCB0aGUgcGVybWlzc2lvbnMgb25seSB0aGF0IGdhdGUgZW5mb3JjZXMuXG4gKi9cbmV4cG9ydCBjb25zdCBQRVJNSVNTSU9OX0dBVEVTOiByZWFkb25seSBzdHJpbmdbXSA9IFtcbiAgLy8gTWlkZGxld2FyZSBnYXRlcyAocm91dGUgbGV2ZWwpIOKAlCBhbGwgYW55LW9mIGV4Y2VwdCByZXF1aXJlQWxsUGVybWlzc2lvbnMuXG4gICdyZXF1aXJlUGVybWlzc2lvbicsXG4gICdyZXF1aXJlQWxsUGVybWlzc2lvbnMnLFxuICAncmVxdWlyZVBlcm1pc3Npb25PclNlcnZpY2UnLFxuICAvLyBUaGUgcGx1Z2luLWVjb3N5c3RlbSBnb3Zlcm5hbmNlIGNoYWluIChzeXN0ZW0gb3JnICsgcGVybWlzc2lvbiArIGFhbDIpLlxuICAncmVxdWlyZUVjb3N5c3RlbVBlcm1pc3Npb24nLFxuICAvLyBUaGUgc2luZ2xlIHJ1bnRpbWUgcHJpbWl0aXZlIGV2ZXJ5IGdhdGUgYWJvdmUgZGVsZWdhdGVzIHRvOyBhbHNvIGNhbGxlZFxuICAvLyBkaXJlY3RseSB3aGVyZSBhIGNvbnRyb2xsZXIgYnJhbmNoZXMgb24gYSBjYXBhYmlsaXR5IHJhdGhlciB0aGFuIHJlamVjdGluZy5cbiAgJ3VzZXJIYXNQZXJtaXNzaW9uJyxcbiAgJ2hhc1Blcm1pc3Npb24nLFxuICAvLyBWaXNpYmlsaXR5IGhlbHBlcnMg4oCUIHRoZXkgdGFrZSB0aGUgZW50aXR5J3MgUFVCTElTSCBwZXJtaXNzaW9uLlxuICAncmVxdWlyZVZpc2liaWxpdHlXcml0ZUFjY2VzcycsXG4gICdjaGVja1Zpc2liaWxpdHlXcml0ZUFjY2VzcycsXG4gICdyZXNvbHZlVmlzaWJpbGl0eScsXG5dO1xuXG4vKipcbiAqIERpc3BsYXkgbWV0YWRhdGEgZm9yIG9uZSBwZXJtaXNzaW9uOiB0aGUgbGFiZWwgKyBkZXNjcmlwdGlvbiB0aGVcbiAqIHBlcm1pc3Npb24tcGlja2VyIFVJIHNob3dzLCBhbmQgdGhlIGNhdGVnb3J5IGl0IGdyb3VwcyB1bmRlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQZXJtaXNzaW9uTWV0YSB7XG4gIGlkOiBQZXJtaXNzaW9uO1xuICBsYWJlbDogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBjYXRlZ29yeTogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSBwZXJtaXNzaW9uIGNhdGFsb2cgd2l0aCBkaXNwbGF5IG1ldGFkYXRhLCBpbiBwaWNrZXIgb3JkZXIuXG4gKlxuICogVGhpcyBtb2R1bGUgaXMgdGhlIFNJTkdMRSBjYXRhbG9nIGZvciBiYWNrZW5kIGFuZCBicm93c2VyIGFsaWtlOiBpdCBoYXMgbm9cbiAqIHJ1bnRpbWUgZGVwZW5kZW5jaWVzICh0aGUgb25seSBpbXBvcnQgaXMgYSB0eXBlKSwgc28gdGhlIGZyb250ZW5kIGltcG9ydHMgaXRcbiAqIHRocm91Z2ggdGhlIGBAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZS9wZXJtaXNzaW9uc2Agc3VicGF0aCBpbnN0ZWFkIG9mIGtlZXBpbmdcbiAqIGEgaGFuZC1tYWludGFpbmVkIG1pcnJvci4gRXZlcnkgaWQgaW4ge0BsaW5rIEFMTF9QRVJNSVNTSU9OU30gbXVzdCBhcHBlYXIgaGVyZVxuICogZXhhY3RseSBvbmNlIChhc3NlcnRlZCBieSBgcGVybWlzc2lvbnMudGVzdC50c2ApLlxuICovXG5leHBvcnQgY29uc3QgUEVSTUlTU0lPTl9DQVRBTE9HOiByZWFkb25seSBQZXJtaXNzaW9uTWV0YVtdID0gW1xuICB7IGlkOiAncGlwZWxpbmVzOnJlYWQnLCBsYWJlbDogJ1ZpZXcgcGlwZWxpbmVzJywgZGVzY3JpcHRpb246ICdWaWV3IHBpcGVsaW5lcyBhbmQgdGhlaXIgZXhlY3V0aW9ucycsIGNhdGVnb3J5OiAnUGlwZWxpbmVzJyB9LFxuICB7IGlkOiAncGlwZWxpbmVzOndyaXRlJywgbGFiZWw6ICdNYW5hZ2UgcGlwZWxpbmVzJywgZGVzY3JpcHRpb246ICdDcmVhdGUsIGVkaXQsIGFuZCBkZWxldGUgcGlwZWxpbmVzJywgY2F0ZWdvcnk6ICdQaXBlbGluZXMnIH0sXG4gIHsgaWQ6ICdwaXBlbGluZXM6cHVibGlzaCcsIGxhYmVsOiAnUHVibGlzaCBwaXBlbGluZXMnLCBkZXNjcmlwdGlvbjogJ01ha2UgcGlwZWxpbmVzIHB1YmxpYyAob3JnLXdpZGUvY2F0YWxvZyB2aXNpYmlsaXR5KScsIGNhdGVnb3J5OiAnUGlwZWxpbmVzJyB9LFxuICB7IGlkOiAndGVtcGxhdGVzOnJlYWQnLCBsYWJlbDogJ1ZpZXcgdGVtcGxhdGVzJywgZGVzY3JpcHRpb246ICdWaWV3IHRoZSBnb2xkZW4tcGF0aCB0ZW1wbGF0ZSBjYXRhbG9nJywgY2F0ZWdvcnk6ICdUZW1wbGF0ZXMnIH0sXG4gIHsgaWQ6ICd0ZW1wbGF0ZXM6d3JpdGUnLCBsYWJlbDogJ01hbmFnZSB0ZW1wbGF0ZXMnLCBkZXNjcmlwdGlvbjogJ0F1dGhvciwgZWRpdCwgYW5kIGRlbGV0ZSBwaXBlbGluZSB0ZW1wbGF0ZXMnLCBjYXRlZ29yeTogJ1RlbXBsYXRlcycgfSxcbiAgeyBpZDogJ3RlbXBsYXRlczpwdWJsaXNoJywgbGFiZWw6ICdQdWJsaXNoIHRlbXBsYXRlcycsIGRlc2NyaXB0aW9uOiAnU2hhcmUgYSB0ZW1wbGF0ZSBiZXlvbmQgeW91ciBvcmcgKHB1YmxpYyB2aXNpYmlsaXR5KScsIGNhdGVnb3J5OiAnVGVtcGxhdGVzJyB9LFxuICB7IGlkOiAncGx1Z2luczpyZWFkJywgbGFiZWw6ICdWaWV3IHBsdWdpbnMnLCBkZXNjcmlwdGlvbjogJ1ZpZXcgcGx1Z2lucyBhbmQgYnVpbGRzJywgY2F0ZWdvcnk6ICdQbHVnaW5zJyB9LFxuICB7IGlkOiAncGx1Z2luczp3cml0ZScsIGxhYmVsOiAnTWFuYWdlIHBsdWdpbnMnLCBkZXNjcmlwdGlvbjogJ0NyZWF0ZSwgdXBsb2FkLCBlZGl0LCBhbmQgZGVsZXRlIHBsdWdpbnMnLCBjYXRlZ29yeTogJ1BsdWdpbnMnIH0sXG4gIHsgaWQ6ICdwbHVnaW5zOnB1Ymxpc2gnLCBsYWJlbDogJ1B1Ymxpc2ggcGx1Z2lucycsIGRlc2NyaXB0aW9uOiAnTWFrZSBwbHVnaW5zIHB1YmxpYyAob3JnLXdpZGUvY2F0YWxvZyB2aXNpYmlsaXR5KScsIGNhdGVnb3J5OiAnUGx1Z2lucycgfSxcbiAgeyBpZDogJ3BsdWdpbnM6aW5zdGFsbCcsIGxhYmVsOiAnSW5zdGFsbCBwbHVnaW5zJywgZGVzY3JpcHRpb246ICdJbnN0YWxsLCB1cGdyYWRlLCBhbmQgdW5pbnN0YWxsIGVjb3N5c3RlbSBwbHVnaW5zIChvciByZXF1ZXN0IGFuIGluc3RhbGwgd2hlbiB5b3VyIG9yZyByZXF1aXJlcyBhcHByb3ZhbCknLCBjYXRlZ29yeTogJ1BsdWdpbiBFY29zeXN0ZW0nIH0sXG4gIHsgaWQ6ICdwbHVnaW5faW5zdGFsbHM6bWFuYWdlJywgbGFiZWw6ICdNYW5hZ2UgcGx1Z2luIGluc3RhbGxzJywgZGVzY3JpcHRpb246IFwiU2V0IHlvdXIgb3JnJ3MgcGx1Z2luIGNvbnN1bXB0aW9uIHBvbGljeSBhbmQgYXBwcm92ZSBvciBkZW55IGluc3RhbGwgcmVxdWVzdHMgd2l0aGluIHRoZSBvcmdcIiwgY2F0ZWdvcnk6ICdQbHVnaW4gRWNvc3lzdGVtJyB9LFxuICB7IGlkOiAncHVibGlzaGVyczptYW5hZ2UnLCBsYWJlbDogJ01hbmFnZSBwdWJsaXNoZXIgcHJvZmlsZScsIGRlc2NyaXB0aW9uOiBcIk1hbmFnZSB5b3VyIG9yZydzIHB1Ymxpc2hlciBwcm9maWxlIGFuZCBzdWJtaXQgcHVibGlzaCwgdmVyaWZpY2F0aW9uLCB0cmFuc2ZlciwgYW5kIGFkdmlzb3J5IHJlcXVlc3RzXCIsIGNhdGVnb3J5OiAnUGx1Z2luIEVjb3N5c3RlbScgfSxcbiAgeyBpZDogJ3BsdWdpbnM6bW9kZXJhdGUnLCBsYWJlbDogJ01vZGVyYXRlIHRoZSBwbHVnaW4gZWNvc3lzdGVtJywgZGVzY3JpcHRpb246ICdEZWNpZGUgcHVibGlzaCByZXF1ZXN0cywgbW9kZXJhdGUgc3VibWlzc2lvbnMgYW5kIHJldmlld3MsIHlhbmsgdmVyc2lvbnMsIGFuZCBwdWJsaXNoIGFkdmlzb3JpZXMgKHN5c3RlbSBvcmcgb25seSknLCBjYXRlZ29yeTogJ1BsdWdpbiBFY29zeXN0ZW0nIH0sXG4gIHsgaWQ6ICdwdWJsaXNoZXJzOnZlcmlmeScsIGxhYmVsOiAnVmVyaWZ5IHB1Ymxpc2hlcnMnLCBkZXNjcmlwdGlvbjogJ0FwcHJvdmUgVmVyaWZpZWQgYXBwbGljYXRpb25zLCBwdWJsaXNoZXIgdGllciBhbmQgcHJvZmlsZSBjaGFuZ2VzLCBhbmQgb3duZXJzaGlwIHRyYW5zZmVycyAoc3lzdGVtIG9yZyBvbmx5KScsIGNhdGVnb3J5OiAnUGx1Z2luIEVjb3N5c3RlbScgfSxcbiAgeyBpZDogJ2NvbXBsaWFuY2U6cmVhZCcsIGxhYmVsOiAnVmlldyBjb21wbGlhbmNlJywgZGVzY3JpcHRpb246ICdWaWV3IGNvbXBsaWFuY2UgcnVsZXMsIHBvbGljaWVzLCBhbmQgc2NhbnMnLCBjYXRlZ29yeTogJ0NvbXBsaWFuY2UnIH0sXG4gIHsgaWQ6ICdjb21wbGlhbmNlOndyaXRlJywgbGFiZWw6ICdNYW5hZ2UgY29tcGxpYW5jZScsIGRlc2NyaXB0aW9uOiAnQ3JlYXRlIGFuZCBlZGl0IHJ1bGVzLCBwb2xpY2llcywgYW5kIGV4ZW1wdGlvbnMnLCBjYXRlZ29yeTogJ0NvbXBsaWFuY2UnIH0sXG4gIHsgaWQ6ICdtZW1iZXJzOm1hbmFnZScsIGxhYmVsOiAnTWFuYWdlIG1lbWJlcnMnLCBkZXNjcmlwdGlvbjogJ0FkZCwgcmVtb3ZlLCBhbmQgY2hhbmdlIHJvbGVzIG9mIG9yZyBtZW1iZXJzJywgY2F0ZWdvcnk6ICdNZW1iZXJzICYgQWNjZXNzJyB9LFxuICB7IGlkOiAncm9sZXM6bWFuYWdlJywgbGFiZWw6ICdNYW5hZ2Ugcm9sZXMnLCBkZXNjcmlwdGlvbjogJ0NyZWF0ZSwgZWRpdCwgYW5kIGRlbGV0ZSByb2xlcycsIGNhdGVnb3J5OiAnTWVtYmVycyAmIEFjY2VzcycgfSxcbiAgeyBpZDogJ2ludml0YXRpb25zOm1hbmFnZScsIGxhYmVsOiAnTWFuYWdlIGludml0YXRpb25zJywgZGVzY3JpcHRpb246ICdTZW5kLCByZXNlbmQsIGFuZCByZXZva2UgaW52aXRhdGlvbnMnLCBjYXRlZ29yeTogJ01lbWJlcnMgJiBBY2Nlc3MnIH0sXG4gIHsgaWQ6ICdzZXJ2aWNlX2FjY291bnRzOm1hbmFnZScsIGxhYmVsOiAnTWFuYWdlIHNlcnZpY2UgYWNjb3VudHMnLCBkZXNjcmlwdGlvbjogJ0NyZWF0ZSBvcmcgc2VydmljZSBhY2NvdW50cywgYXNzaWduIHRoZWlyIHJvbGVzLCBhbmQgaXNzdWUgb3IgcmV2b2tlIHRoZWlyIGtleXMnLCBjYXRlZ29yeTogJ01lbWJlcnMgJiBBY2Nlc3MnIH0sXG4gIHsgaWQ6ICdkYXNoYm9hcmRzOnJlYWQnLCBsYWJlbDogJ1ZpZXcgZGFzaGJvYXJkcycsIGRlc2NyaXB0aW9uOiAnVmlldyBjdXN0b20gZGFzaGJvYXJkcycsIGNhdGVnb3J5OiAnT2JzZXJ2YWJpbGl0eScgfSxcbiAgeyBpZDogJ2Rhc2hib2FyZHM6d3JpdGUnLCBsYWJlbDogJ01hbmFnZSBkYXNoYm9hcmRzJywgZGVzY3JpcHRpb246ICdDcmVhdGUgYW5kIGVkaXQgY3VzdG9tIGRhc2hib2FyZHMnLCBjYXRlZ29yeTogJ09ic2VydmFiaWxpdHknIH0sXG4gIHsgaWQ6ICdvYnNlcnZhYmlsaXR5OnJlYWQnLCBsYWJlbDogJ1ZpZXcgYWxlcnRpbmcnLCBkZXNjcmlwdGlvbjogJ1ZpZXcgYWxlcnQgcnVsZXMgYW5kIGRlc3RpbmF0aW9ucycsIGNhdGVnb3J5OiAnT2JzZXJ2YWJpbGl0eScgfSxcbiAgeyBpZDogJ29ic2VydmFiaWxpdHk6d3JpdGUnLCBsYWJlbDogJ01hbmFnZSBhbGVydGluZycsIGRlc2NyaXB0aW9uOiAnQ3JlYXRlIGFuZCBlZGl0IGFsZXJ0IHJ1bGVzIGFuZCBkZXN0aW5hdGlvbnMnLCBjYXRlZ29yeTogJ09ic2VydmFiaWxpdHknIH0sXG4gIHsgaWQ6ICdsb2dzOmV4cG9ydCcsIGxhYmVsOiAnRG93bmxvYWQgbG9ncycsIGRlc2NyaXB0aW9uOiBcIkRvd25sb2FkIHlvdXIgb3JnYW5pemF0aW9uJ3MgbG9nIGVudHJpZXMgYXMgYSBmaWxlICh2aWV3aW5nIGxvZ3Mgb25seSBuZWVkcyAnVmlldyBhbGVydGluZycpXCIsIGNhdGVnb3J5OiAnT2JzZXJ2YWJpbGl0eScgfSxcbiAgeyBpZDogJ3JlcG9ydHM6cmVhZCcsIGxhYmVsOiAnVmlldyByZXBvcnRzJywgZGVzY3JpcHRpb246ICdWaWV3IGFuYWx5dGljcyBhbmQgcmVwb3J0cycsIGNhdGVnb3J5OiAnSW5zaWdodHMnIH0sXG4gIHsgaWQ6ICdyZXBvcnRzOnJvbGx1cCcsIGxhYmVsOiAnUm9sbCB1cCB0ZWFtIHJlcG9ydHMnLCBkZXNjcmlwdGlvbjogJ0luY2x1ZGUgZGVzY2VuZGFudCB0ZWFtcyB3aGVuIHZpZXdpbmcgcmVwb3J0cycsIGNhdGVnb3J5OiAnSW5zaWdodHMnIH0sXG4gIHsgaWQ6ICdtZXNzYWdlczpyZWFkJywgbGFiZWw6ICdWaWV3IG1lc3NhZ2VzJywgZGVzY3JpcHRpb246ICdWaWV3IG1lc3NhZ2VzIGFuZCBhbm5vdW5jZW1lbnRzJywgY2F0ZWdvcnk6ICdNZXNzYWdpbmcnIH0sXG4gIHsgaWQ6ICdtZXNzYWdlczp3cml0ZScsIGxhYmVsOiAnU2VuZCBtZXNzYWdlcycsIGRlc2NyaXB0aW9uOiAnU2VuZCBtZXNzYWdlcyBhbmQgYW5ub3VuY2VtZW50cycsIGNhdGVnb3J5OiAnTWVzc2FnaW5nJyB9LFxuICB7IGlkOiAnYmlsbGluZzpyZWFkJywgbGFiZWw6ICdWaWV3IGJpbGxpbmcnLCBkZXNjcmlwdGlvbjogJ1ZpZXcgc3Vic2NyaXB0aW9ucyBhbmQgdXNhZ2UnLCBjYXRlZ29yeTogJ0JpbGxpbmcgJiBRdW90YXMnIH0sXG4gIHsgaWQ6ICdiaWxsaW5nOm1hbmFnZScsIGxhYmVsOiAnTWFuYWdlIGJpbGxpbmcnLCBkZXNjcmlwdGlvbjogJ01hbmFnZSBzdWJzY3JpcHRpb25zLCBhZGQtb25zLCBhbmQgdGhlIGJpbGxpbmcgcG9ydGFsJywgY2F0ZWdvcnk6ICdCaWxsaW5nICYgUXVvdGFzJyB9LFxuICB7IGlkOiAncXVvdGFzOnJlYWQnLCBsYWJlbDogJ1ZpZXcgcXVvdGFzJywgZGVzY3JpcHRpb246ICdWaWV3IG9yZ2FuaXphdGlvbiBxdW90YXMgYW5kIHVzYWdlJywgY2F0ZWdvcnk6ICdCaWxsaW5nICYgUXVvdGFzJyB9LFxuICB7IGlkOiAncmVnaXN0cnk6cmVhZCcsIGxhYmVsOiAnVmlldyByZWdpc3RyeScsIGRlc2NyaXB0aW9uOiAnVmlldyB0aGUgY29udGFpbmVyIGltYWdlIHJlZ2lzdHJ5JywgY2F0ZWdvcnk6ICdSZWdpc3RyeScgfSxcbiAgeyBpZDogJ3JlZ2lzdHJ5OndyaXRlJywgbGFiZWw6ICdNYW5hZ2UgcmVnaXN0cnknLCBkZXNjcmlwdGlvbjogJ0RlbGV0ZSBhbmQgY29weSBjb250YWluZXIgaW1hZ2VzJywgY2F0ZWdvcnk6ICdSZWdpc3RyeScgfSxcbiAgeyBpZDogJ29yZzpzZXR0aW5ncycsIGxhYmVsOiAnT3JnYW5pemF0aW9uIHNldHRpbmdzJywgZGVzY3JpcHRpb246ICdNYW5hZ2UgZ2VuZXJhbCBvcmcgc2V0dGluZ3MgYW5kIEFJIGNvbmZpZycsIGNhdGVnb3J5OiAnT3JnYW5pemF0aW9uJyB9LFxuICB7IGlkOiAnb3JnOmlkcCcsIGxhYmVsOiAnTWFuYWdlIFNTTy9JZFAnLCBkZXNjcmlwdGlvbjogJ0NvbmZpZ3VyZSBzaW5nbGUgc2lnbi1vbiBhbmQgaWRlbnRpdHkgcHJvdmlkZXJzJywgY2F0ZWdvcnk6ICdPcmdhbml6YXRpb24nIH0sXG4gIHsgaWQ6ICdvcmc6a21zJywgbGFiZWw6ICdNYW5hZ2UgZW5jcnlwdGlvbiBrZXlzJywgZGVzY3JpcHRpb246ICdDb25maWd1cmUgY3VzdG9tZXItbWFuYWdlZCBLTVMgZW5jcnlwdGlvbiBrZXlzJywgY2F0ZWdvcnk6ICdPcmdhbml6YXRpb24nIH0sXG4gIHsgaWQ6ICdvcmc6aW1wZXJzb25hdGlvbicsIGxhYmVsOiAnTWFuYWdlIGltcGVyc29uYXRpb24gcG9saWN5JywgZGVzY3JpcHRpb246ICdDb250cm9sIHdoZXRoZXIgcGxhdGZvcm0gb3BlcmF0b3JzIG1heSB2aWV3IHRoZSBvcmdhbml6YXRpb24gYXMgb25lIG9mIGl0cyBtZW1iZXJzJywgY2F0ZWdvcnk6ICdPcmdhbml6YXRpb24nIH0sXG5dO1xuXG5jb25zdCBQRVJNSVNTSU9OX0xBQkVMUyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KFBFUk1JU1NJT05fQ0FUQUxPRy5tYXAoKHApID0+IFtwLmlkLCBwLmxhYmVsXSkpO1xuXG4vKiogSHVtYW4gbGFiZWwgZm9yIGEgcGVybWlzc2lvbiBpZCAoZmFsbHMgYmFjayB0byB0aGUgcmF3IGlkIGZvciBhbiB1bmtub3duIG9uZSkuICovXG5leHBvcnQgZnVuY3Rpb24gcGVybWlzc2lvbkxhYmVsKGlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gUEVSTUlTU0lPTl9MQUJFTFMuZ2V0KGlkKSA/PyBpZDtcbn1cblxuLyoqIE9uZSBwaWNrZXIgc2VjdGlvbjogYSBjYXRlZ29yeSBhbmQgdGhlIHBlcm1pc3Npb25zIGl0IGNvbnRhaW5zLCBpbiBjYXRhbG9nIG9yZGVyLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQZXJtaXNzaW9uQ2F0ZWdvcnkge1xuICBjYXRlZ29yeTogc3RyaW5nO1xuICBwZXJtaXNzaW9uczogUGVybWlzc2lvbk1ldGFbXTtcbn1cblxuLyoqIEdyb3VwIGEgcGVybWlzc2lvbiBsaXN0IGludG8gY2F0ZWdvcmllcywgcHJlc2VydmluZyBjYXRhbG9nIG9yZGVyLiAqL1xuZnVuY3Rpb24gZ3JvdXBCeUNhdGVnb3J5KHBlcm1zOiByZWFkb25seSBQZXJtaXNzaW9uTWV0YVtdKTogUGVybWlzc2lvbkNhdGVnb3J5W10ge1xuICBjb25zdCBvcmRlcjogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgYnlDYXRlZ29yeSA9IG5ldyBNYXA8c3RyaW5nLCBQZXJtaXNzaW9uTWV0YVtdPigpO1xuICBmb3IgKGNvbnN0IHAgb2YgcGVybXMpIHtcbiAgICBpZiAoIWJ5Q2F0ZWdvcnkuaGFzKHAuY2F0ZWdvcnkpKSB7IGJ5Q2F0ZWdvcnkuc2V0KHAuY2F0ZWdvcnksIFtdKTsgb3JkZXIucHVzaChwLmNhdGVnb3J5KTsgfVxuICAgIGJ5Q2F0ZWdvcnkuZ2V0KHAuY2F0ZWdvcnkpIS5wdXNoKHApO1xuICB9XG4gIHJldHVybiBvcmRlci5tYXAoKGNhdGVnb3J5KSA9PiAoeyBjYXRlZ29yeSwgcGVybWlzc2lvbnM6IGJ5Q2F0ZWdvcnkuZ2V0KGNhdGVnb3J5KSEgfSkpO1xufVxuXG4vKiogQ2hlY2sgd2hldGhlciBhIHN0cmluZyBpcyBhIHZhbGlkIFBlcm1pc3Npb24uICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFBlcm1pc3Npb24odmFsdWU6IHN0cmluZyk6IHZhbHVlIGlzIFBlcm1pc3Npb24ge1xuICByZXR1cm4gKEFMTF9QRVJNSVNTSU9OUyBhcyByZWFkb25seSBzdHJpbmdbXSkuaW5jbHVkZXModmFsdWUpO1xufVxuXG4vKipcbiAqIFBlcm1pc3Npb25zIHRoYXQgbXVzdCBORVZFUiBiZSBncmFudGFibGUgdGhyb3VnaCBhIHVzZXItYXV0aG9yZWQgQ1VTVE9NIFJvbGUg4oCUXG4gKiB0aGV5IGdhdGUgcGxhdGZvcm0tb3BlcmF0b3Igc3VyZmFjZXMgKHRoZSBzaGFyZWQgaW1hZ2UgcmVnaXN0cnkpLCBzbyBhbGxvd2luZ1xuICogYW4gb3JnIGFkbWluIHRvIG1pbnQgYSBSb2xlIGNhcnJ5aW5nIHRoZW0gd291bGQgYmUgYSBsYXRlbnQgcHJpdmlsZWdlXG4gKiBlc2NhbGF0aW9uLiBUaGV5IGFyZSBOT1Qgc2VlZGVkIGludG8gQU5ZIGJ1aWx0LWluIFJvbGUgYnVuZGxlIChuZWl0aGVyXG4gKiBgbWVtYmVyYCBub3IgYGFkbWluYCksIHNvIHRoZSBvbmx5IGhvbGRlciBpcyBhIHN1cGVyYWRtaW4gKGltcGxpY2l0LWFsbCkg4oCUXG4gKiB3aGljaCBpcyB3aGF0IG1ha2VzIHRoZSBpbWFnZS1yZWdpc3RyeSBnYXRlcyB0aGF0IHJlcXVpcmUgdGhlbSBlZmZlY3RpdmVseVxuICogc3VwZXJhZG1pbi1vbmx5LiBUaGlzIGxpc3QgQUxTTyBibG9ja3MgY3VzdG9tLVJvbGUgYXV0aG9yaW5nIGZyb20gcmVxdWVzdGluZ1xuICogdGhlbSAoc2VlIHBsYXRmb3JtIGBzYW5pdGl6ZVBlcm1pc3Npb25zYCkuXG4gKi9cbmV4cG9ydCBjb25zdCBTVVBFUkFETUlOX09OTFlfUEVSTUlTU0lPTlM6IHJlYWRvbmx5IFBlcm1pc3Npb25bXSA9IFtcbiAgJ3JlZ2lzdHJ5OnJlYWQnLFxuICAncmVnaXN0cnk6d3JpdGUnLFxuXTtcblxuLyoqXG4gKiBQZXJtaXNzaW9ucyB0aGF0IGdvdmVybiB0aGUgUExVR0lOIEVDT1NZU1RFTSBhbmQgbWF5IGJlIGhlbGQgb25seSBpbnNpZGUgdGhlXG4gKiBzeXN0ZW0gb3JnIChkb2NzL3BsdWdpbi1wdWJsaXNoaW5nLm1kKS4gTGlrZVxuICoge0BsaW5rIFNVUEVSQURNSU5fT05MWV9QRVJNSVNTSU9OU30gdGhleSBhcmUgaW4gbm8gbWVtYmVyL2FkbWluL293bmVyIGJ1bmRsZVxuICogYW5kIGFyZSBuZXZlciBncmFudGFibGUgdGhyb3VnaCBhIGN1c3RvbSBSb2xlIGluIEFOWSBvcmcgKHBsYXRmb3JtXG4gKiBgc2FuaXRpemVQZXJtaXNzaW9uc2AgcmVmdXNlcyB0aGVtKS4gVGhlIG9ubHkgaG9sZGVycyBhcmUgc3VwZXJhZG1pbnNcbiAqIChpbXBsaWNpdC1hbGwpIGFuZCBtZW1iZXJzIG9mIHRoZSBidWlsdC1pbiBcIkVjb3N5c3RlbSBNYW5hZ2VyXCIgUm9sZSwgd2hpY2ggaXNcbiAqIHNlZWRlZCBpbiB0aGUgc3lzdGVtIG9yZyBhbG9uZSBmcm9tIHtAbGluayBFQ09TWVNURU1fTUFOQUdFUl9QRVJNSVNTSU9OU30gYW5kXG4gKiBhc3NpZ25hYmxlIG9ubHkgYnkgYSBzdXBlcmFkbWluLlxuICovXG5leHBvcnQgY29uc3QgU1lTVEVNX09SR19PTkxZX1BFUk1JU1NJT05TOiByZWFkb25seSBQZXJtaXNzaW9uW10gPSBbXG4gICdwbHVnaW5zOm1vZGVyYXRlJyxcbiAgJ3B1Ymxpc2hlcnM6dmVyaWZ5Jyxcbl07XG5cbi8qKiBXaGV0aGVyIGBwZXJtaXNzaW9uYCBtYXkgYmUgaGVsZCBvbmx5IGluc2lkZSB0aGUgc3lzdGVtIG9yZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N5c3RlbU9yZ09ubHlQZXJtaXNzaW9uKHBlcm1pc3Npb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFNZU1RFTV9PUkdfT05MWV9QRVJNSVNTSU9OUyBhcyByZWFkb25seSBzdHJpbmdbXSkuaW5jbHVkZXMocGVybWlzc2lvbik7XG59XG5cbi8qKlxuICogUGVybWlzc2lvbnMgYW4gb3JnIG1heSBhc3NpZ24gdmlhIGEgQ1VTVE9NIFJvbGUg4oCUIGV2ZXJ5IHBlcm1pc3Npb24gZXhjZXB0IHRoZVxuICoge0BsaW5rIFNVUEVSQURNSU5fT05MWV9QRVJNSVNTSU9OU30gYW5kIHtAbGluayBTWVNURU1fT1JHX09OTFlfUEVSTUlTU0lPTlN9LlxuICogQ3VzdG9tLVJvbGUgY3JlYXRlL3VwZGF0ZSB2YWxpZGF0ZXMgdGhlIHJlcXVlc3RlZCBwZXJtaXNzaW9uIHNldCBhZ2FpbnN0IHRoaXNcbiAqIChzZWUgcGxhdGZvcm0gcm9sZXMtc2VydmljZSkuXG4gKi9cbmV4cG9ydCBjb25zdCBPUkdfQVNTSUdOQUJMRV9QRVJNSVNTSU9OUzogcmVhZG9ubHkgUGVybWlzc2lvbltdID1cbiAgQUxMX1BFUk1JU1NJT05TLmZpbHRlcigocCkgPT4gaXNPcmdBc3NpZ25hYmxlUGVybWlzc2lvbihwKSk7XG5cbi8qKiBXaGV0aGVyIGBwZXJtaXNzaW9uYCBtYXkgYmUgZ3JhbnRlZCB0aHJvdWdoIGEgdXNlci1hdXRob3JlZCBjdXN0b20gUm9sZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc09yZ0Fzc2lnbmFibGVQZXJtaXNzaW9uKHBlcm1pc3Npb246IFBlcm1pc3Npb24pOiBib29sZWFuIHtcbiAgcmV0dXJuICFTVVBFUkFETUlOX09OTFlfUEVSTUlTU0lPTlMuaW5jbHVkZXMocGVybWlzc2lvbikgJiYgIWlzU3lzdGVtT3JnT25seVBlcm1pc3Npb24ocGVybWlzc2lvbik7XG59XG5cbi8qKlxuICogQ2F0ZWdvcnkg4oaSIHBlcm1pc3Npb25zIGZvciB0aGUgY3VzdG9tLVJvbGUgQVVUSE9SSU5HIHBpY2tlcjogdGhlIGNhdGFsb2cgbWludXNcbiAqIHRoZSBub24tYXNzaWduYWJsZSBwZXJtaXNzaW9ucywgd2l0aCBhbnkgbm93LWVtcHR5IGNhdGVnb3J5IGRyb3BwZWRcbiAqIChzbyBcIlJlZ2lzdHJ5XCIgZGlzYXBwZWFycykuIFRoZSBncm91cGVkIHZpZXcgb2ZcbiAqIHtAbGluayBPUkdfQVNTSUdOQUJMRV9QRVJNSVNTSU9OU30uXG4gKi9cbmV4cG9ydCBjb25zdCBPUkdfQVNTSUdOQUJMRV9DQVRFR09SSUVTOiByZWFkb25seSBQZXJtaXNzaW9uQ2F0ZWdvcnlbXSA9XG4gIGdyb3VwQnlDYXRlZ29yeShQRVJNSVNTSU9OX0NBVEFMT0cuZmlsdGVyKChwKSA9PiBpc09yZ0Fzc2lnbmFibGVQZXJtaXNzaW9uKHAuaWQpKSk7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBQZXJtaXNzaW9uLXNjb3BlZCBjcmVkZW50aWFscyAocGVyc29uYWwgYWNjZXNzIGtleXMgLyBtYWNoaW5lIHRva2Vucylcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogRXZlcnkgYDpyZWFkYCBwZXJtaXNzaW9uIOKAlCB0aGUgXCJyZWFkLW9ubHlcIiBwcmVzZXQgYSBuZXcgcGVyc29uYWwgYWNjZXNzIGtleVxuICogc3RhcnRzIGZyb20uIERlcml2ZWQgZnJvbSB0aGUgY2F0YWxvZyBzbyBhIG5ldyByZXNvdXJjZSdzIHJlYWQgcGVybWlzc2lvblxuICogam9pbnMgdGhlIHByZXNldCB3aXRob3V0IGEgc2Vjb25kIGVkaXQuXG4gKi9cbmV4cG9ydCBjb25zdCBSRUFEX09OTFlfUEVSTUlTU0lPTlM6IHJlYWRvbmx5IFBlcm1pc3Npb25bXSA9XG4gIEFMTF9QRVJNSVNTSU9OUy5maWx0ZXIoKHApID0+IHAuZW5kc1dpdGgoJzpyZWFkJykpO1xuXG4vKipcbiAqIE5vcm1hbGl6ZSBhIHJlcXVlc3RlZCBwZXJtaXNzaW9uIHN1YnNldDogZXZlcnkgZW50cnkgbXVzdCBiZSBhIGNhdGFsb2cgaWRcbiAqIChhbnl0aGluZyBlbHNlIOKGkiBgbnVsbGAsIHRoZSBjYWxsZXIncyA0MDApLCBkdXBsaWNhdGVzIGNvbGxhcHNlLCBhbmQgdGhlXG4gKiByZXN1bHQgaXMgaW4gY2Fub25pY2FsIGNhdGFsb2cgb3JkZXIgc28gYSBzdG9yZWQgc3Vic2V0IGNvbXBhcmVzIHN0YWJseS5cbiAqIEFuIEVNUFRZIGFycmF5IGlzIHZhbGlkIOKAlCBhIGtleSB0aGF0IGNhbiBhdXRoZW50aWNhdGUgYnV0IGRvIG5vdGhpbmcg4oCUIGFuZFxuICogaXMgZGlzdGluY3QgZnJvbSBcIm5vIHN1YnNldFwiIChgdW5kZWZpbmVkYCksIHdoaWNoIG1lYW5zIGZ1bGwgYWNjZXNzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplUGVybWlzc2lvblN1YnNldChyZXF1ZXN0ZWQ6IHJlYWRvbmx5IHVua25vd25bXSk6IFBlcm1pc3Npb25bXSB8IG51bGwge1xuICBjb25zdCB3YW50ZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgZm9yIChjb25zdCBwIG9mIHJlcXVlc3RlZCkge1xuICAgIGlmICh0eXBlb2YgcCAhPT0gJ3N0cmluZycgfHwgIWlzVmFsaWRQZXJtaXNzaW9uKHApKSByZXR1cm4gbnVsbDtcbiAgICB3YW50ZWQuYWRkKHApO1xuICB9XG4gIHJldHVybiBBTExfUEVSTUlTU0lPTlMuZmlsdGVyKChwKSA9PiB3YW50ZWQuaGFzKHApKTtcbn1cblxuLyoqXG4gKiBUaGUgcGVybWlzc2lvbnMgYSBwZXJtaXNzaW9uLXNjb3BlZCBjcmVkZW50aWFsIGFjdHVhbGx5IGNhcnJpZXM6IHRoZVxuICogSU5URVJTRUNUSU9OIG9mIHRoZSBzdWJzZXQgaXQgd2FzIGNyZWF0ZWQgd2l0aCBhbmQgdGhlIGhvbGRlcidzIENVUlJFTlRcbiAqIGVmZmVjdGl2ZSBwZXJtaXNzaW9ucywgaW4gY2F0YWxvZyBvcmRlci4gUmUtZXZhbHVhdGVkIGF0IGV2ZXJ5IGlzc3VlLCBzb1xuICogbG9zaW5nIGEgUm9sZSBzaHJpbmtzIHRoZSBjcmVkZW50aWFsIGFuZCBub3RoaW5nIGNhbiBldmVyIGdyb3cgaXQgcGFzdCB0aGVcbiAqIHN1YnNldCBpdCB3YXMgY3JlYXRlZCB3aXRoLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJzZWN0UGVybWlzc2lvbnMoXG4gIGVmZmVjdGl2ZTogcmVhZG9ubHkgc3RyaW5nW10sXG4gIHN1YnNldDogcmVhZG9ubHkgc3RyaW5nW10sXG4pOiBQZXJtaXNzaW9uW10ge1xuICBjb25zdCBhbGxvd2VkID0gbmV3IFNldChzdWJzZXQpO1xuICBjb25zdCBoZWxkID0gbmV3IFNldChlZmZlY3RpdmUpO1xuICByZXR1cm4gQUxMX1BFUk1JU1NJT05TLmZpbHRlcigocCkgPT4gYWxsb3dlZC5oYXMocCkgJiYgaGVsZC5oYXMocCkpO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQnVpbHQtaW4gUm9sZSBzZWVkIGJ1bmRsZXNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogUGVybWlzc2lvbiBidW5kbGVzIHVzZWQgdG8gU0VFRCB0aGUgYnVpbHQtaW4gUm9sZXMgKFwiQWRtaW5cIiwgXCJNZW1iZXJcIikuXG4gKlxuICogVGhpcyBpcyB0aGUgc2luZ2xlIGRlZmluaXRpb24gb2Ygd2hhdCB0aG9zZSBidWlsdC1pbiBSb2xlcyBncmFudCDigJQgaXQgaXMgdXNlZFxuICogd2hlbiBhIFJvbGUgcmVjb3JkIGlzIGNyZWF0ZWQgKGFuZCBieSB0aGUgc3RhcnR1cCBiYWNrZmlsbCkgdG8gcG9wdWxhdGUgdGhhdFxuICogUm9sZSdzIG93biBgcGVybWlzc2lvbnNbXWAuIEl0IGlzIE5PVCBhIHJ1bnRpbWUgcGVybWlzc2lvbiBzb3VyY2U6IGEgdXNlcidzXG4gKiBlZmZlY3RpdmUgcGVybWlzc2lvbnMgY29tZSBPTkxZIGZyb20gdGhlIFJvbGVzIGFzc2lnbmVkIHRvIHRoZW0gKHNlZVxuICoge0BsaW5rIHJlc29sdmVVc2VyUGVybWlzc2lvbnN9KS4gVGhlIGNvYXJzZSBgcm9sZWAgbGFiZWwgKG93bmVyL2FkbWluL21lbWJlcilcbiAqIHN1cnZpdmVzIG9ubHkgZm9yIGBpc0FkbWluYC9vd25lcnNoaXAvZGlzcGxheSwgbmV2ZXIgdG8gZ3JhbnQgcGVybWlzc2lvbnMuXG4gKlxuICogLSBgbWVtYmVyYCAg4oCUIGRheS10by1kYXkgYnVpbGRlcjogcmVhZCArIHdyaXRlIG9uIHBpcGVsaW5lcy90ZW1wbGF0ZXMvcGx1Z2lucyxcbiAqICAgcmVhZCBlbHNld2hlcmUuIE5vIG1lbWJlci9yb2xlL2JpbGxpbmcgbWFuYWdlbWVudCwgbm8gY29tcGxpYW5jZS9hbGVydFxuICogICBhdXRob3JpbmcsIGFuZCBubyBgOnB1Ymxpc2hgIG9uIGFueSBjYXRhbG9nLlxuICogLSBgYWRtaW5gICAg4oCUIGZ1bGwgb3JnIGFkbWluaXN0cmF0aW9uOiBldmVyeSBPUkctQVNTSUdOQUJMRSBwZXJtaXNzaW9uIChpLmUuXG4gKiAgIEFMTF9QRVJNSVNTSU9OUyBtaW51cyB0aGUge0BsaW5rIFNVUEVSQURNSU5fT05MWV9QRVJNSVNTSU9OU30gYW5kIHRoZVxuICogICB7QGxpbmsgU1lTVEVNX09SR19PTkxZX1BFUk1JU1NJT05TfSwgc28gYHJlZ2lzdHJ5OipgIHN0YXlcbiAqICAgc3VwZXJhZG1pbi1pbXBsaWNpdC1vbmx5IGFuZCBlY29zeXN0ZW0gbW9kZXJhdGlvbiBzdGF5cyB3aXRoIHRoZSBzeXN0ZW1cbiAqICAgb3JnJ3MgRWNvc3lzdGVtIE1hbmFnZXJzIOKAlCBuZWl0aGVyIGlzIGdyYW50ZWQgdG8gb3JnIGFkbWlucykuXG4gKiAtIGBvd25lcmAgICDigJQgc2FtZSBhcyBhZG1pbiAob3duZXJzaGlwIGl0c2VsZiDigJQgdHJhbnNmZXIvZGVsZXRlIOKAlCBpcyBnYXRlZFxuICogICBzZXBhcmF0ZWx5LCBub3QgdmlhIGEgcGVybWlzc2lvbikuXG4gKi9cbmNvbnN0IE1FTUJFUl9QRVJNSVNTSU9OUzogcmVhZG9ubHkgUGVybWlzc2lvbltdID0gW1xuICAncGlwZWxpbmVzOnJlYWQnLCAncGlwZWxpbmVzOndyaXRlJyxcbiAgJ3RlbXBsYXRlczpyZWFkJywgJ3RlbXBsYXRlczp3cml0ZScsXG4gICdwbHVnaW5zOnJlYWQnLCAncGx1Z2luczp3cml0ZScsXG4gICdwbHVnaW5zOmluc3RhbGwnLFxuICAnY29tcGxpYW5jZTpyZWFkJyxcbiAgJ2Rhc2hib2FyZHM6cmVhZCcsXG4gICdvYnNlcnZhYmlsaXR5OnJlYWQnLFxuICAncmVwb3J0czpyZWFkJyxcbiAgJ21lc3NhZ2VzOnJlYWQnLCAnbWVzc2FnZXM6d3JpdGUnLFxuICAnYmlsbGluZzpyZWFkJyxcbiAgJ3F1b3RhczpyZWFkJyxcbl07XG5cbmNvbnN0IEFETUlOX1BFUk1JU1NJT05TOiByZWFkb25seSBQZXJtaXNzaW9uW10gPSBbLi4uT1JHX0FTU0lHTkFCTEVfUEVSTUlTU0lPTlNdO1xuXG4vKipcbiAqIFNlZWQgYnVuZGxlIGZvciBlYWNoIGJ1aWx0LWluIFJvbGUsIGtleWVkIGJ5IHRoZSBjb2Fyc2Ugcm9sZSBpdCBncmFudHMuXG4gKiBDb25zdW1lZCBieSB0aGUgUm9sZSBzZWVkZXIgKyB0aGUgc3RhcnR1cCBiYWNrZmlsbCB0byBwb3B1bGF0ZSBhIGJ1aWx0LWluXG4gKiBSb2xlJ3MgYHBlcm1pc3Npb25zW11gLiBOT1QgY29uc3VsdGVkIGF0IHJlcXVlc3QgdGltZSDigJQgc2VlXG4gKiB7QGxpbmsgcmVzb2x2ZVVzZXJQZXJtaXNzaW9uc30uXG4gKi9cbmV4cG9ydCBjb25zdCBST0xFX1BFUk1JU1NJT05TOiBSZWNvcmQ8T3JnUm9sZSwgcmVhZG9ubHkgUGVybWlzc2lvbltdPiA9IHtcbiAgbWVtYmVyOiBNRU1CRVJfUEVSTUlTU0lPTlMsXG4gIGFkbWluOiBBRE1JTl9QRVJNSVNTSU9OUyxcbiAgb3duZXI6IEFETUlOX1BFUk1JU1NJT05TLFxufTtcblxuLyoqXG4gKiBTZWVkIGJ1bmRsZSBmb3IgdGhlIGJ1aWx0LWluIFwiRWNvc3lzdGVtIE1hbmFnZXJcIiBSb2xlIOKAlCBzZWVkZWQgT05MWSBpbiB0aGVcbiAqIHN5c3RlbSBvcmcgKGRvY3MvcGx1Z2luLXB1Ymxpc2hpbmcubWQpLiBJdCBjYXJyaWVzIHRoZVxuICoge0BsaW5rIFNZU1RFTV9PUkdfT05MWV9QRVJNSVNTSU9OU30gcGx1cyB0aGUgcmVhZHMgYSBtb2RlcmF0b3IgbmVlZHMgKHRoZVxuICogaW4tYXBwIGNhdGFsb2csIGluLWFwcCBub3RpY2VzLCB0aGUgbW9kZXJhdGlvbi1TTEEgZGFzaGJvYXJkKSBhbmQgbm90aGluZ1xuICogdGVuYW50LWZhY2luZzogbm8gYHJlZ2lzdHJ5OipgLCBubyBgbWVtYmVyczptYW5hZ2VgLiBUaGUgUm9sZSBncmFudHMgdGhlXG4gKiBjb2Fyc2UgYG1lbWJlcmAgbGFiZWwgYW5kIG5ldmVyIHNldHMgYGlzU3VwZXJBZG1pbmAuXG4gKi9cbmV4cG9ydCBjb25zdCBFQ09TWVNURU1fTUFOQUdFUl9QRVJNSVNTSU9OUzogcmVhZG9ubHkgUGVybWlzc2lvbltdID0gW1xuICAncGx1Z2luczpyZWFkJyxcbiAgJ3BsdWdpbnM6bW9kZXJhdGUnLFxuICAncHVibGlzaGVyczp2ZXJpZnknLFxuICAnbWVzc2FnZXM6cmVhZCcsXG4gICdvYnNlcnZhYmlsaXR5OnJlYWQnLFxuXTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFJlc29sdXRpb25cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogUmVzb2x2ZSBhIHVzZXIncyBlZmZlY3RpdmUgb3JnIHBlcm1pc3Npb25zIGZyb20gdGhlIFJvbGVzIGFzc2lnbmVkIHRvIHRoZW0uXG4gKlxuICogU2luZ2xlLXNvdXJjZSBtb2RlbDogYSB1c2VyJ3MgYWJpbGl0aWVzIGFyZSBFWEFDVExZIHRoZSB1bmlvbiBvZiB0aGVcbiAqIHBlcm1pc3Npb25zIGNhcnJpZWQgYnkgdGhlIFJvbGVzIHRoZXkgaG9sZCAoYSBSb2xlID0gYSBuYW1lZCBwZXJtaXNzaW9uIHNldDtcbiAqIGJ1aWx0LWluIFJvbGVzIGNhcnJ5IHRoZWlyIGJ1bmRsZSBleHBsaWNpdGx5LCBzZWVkZWQgZnJvbVxuICoge0BsaW5rIFJPTEVfUEVSTUlTU0lPTlN9KS4gVGhlcmUgaXMgbm8gc2VwYXJhdGUgcm9sZS1kZXJpdmVkIGJhc2VsaW5lIOKAlCB0aGVcbiAqIGNvYXJzZSBgcm9sZWAgbGFiZWwgZ3JhbnRzIG5vdGhpbmcgb24gaXRzIG93bi5cbiAqXG4gKiAxLiBQbGF0Zm9ybSBzdXBlcmFkbWlucyAoYGlzU3VwZXJBZG1pbmApIGFsd2F5cyBnZXQgQUxMIHBlcm1pc3Npb25zLlxuICogMi4gT3RoZXJ3aXNlLCB1bmlvbiBldmVyeSBwZXJtaXNzaW9uIGdyYW50ZWQgYnkgdGhlIHVzZXIncyBhc3NpZ25lZCBSb2xlcy5cbiAqIDMuIEludmFsaWQvdW5rbm93biBwZXJtaXNzaW9uIHN0cmluZ3MgYXJlIHNpbGVudGx5IGlnbm9yZWQuXG4gKlxuICogQHBhcmFtIGFzc2lnbmVkUGVybWlzc2lvbnMgLSBGbGF0dGVuZWQgcGVybWlzc2lvbnMgZnJvbSBldmVyeSBSb2xlIHRoZSB1c2VyIGhvbGRzXG4gKiBAcGFyYW0gaXNTdXBlckFkbWluIC0gV2hldGhlciB0aGUgdXNlciBoYXMgdGhlIGdsb2JhbCBzdXBlci1hZG1pbiBmbGFnXG4gKiBAcmV0dXJucyBFZmZlY3RpdmUgcGVybWlzc2lvbnMgaW4gY2Fub25pY2FsIG9yZGVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlVXNlclBlcm1pc3Npb25zKFxuICBhc3NpZ25lZFBlcm1pc3Npb25zPzogcmVhZG9ubHkgc3RyaW5nW10gfCBudWxsLFxuICBpc1N1cGVyQWRtaW4/OiBib29sZWFuLFxuKTogUGVybWlzc2lvbltdIHtcbiAgaWYgKGlzU3VwZXJBZG1pbikgcmV0dXJuIFsuLi5BTExfUEVSTUlTU0lPTlNdO1xuXG4gIGNvbnN0IHBlcm1zID0gbmV3IFNldDxQZXJtaXNzaW9uPigpO1xuICBpZiAoYXNzaWduZWRQZXJtaXNzaW9ucykge1xuICAgIGZvciAoY29uc3QgcCBvZiBhc3NpZ25lZFBlcm1pc3Npb25zKSB7XG4gICAgICBpZiAoaXNWYWxpZFBlcm1pc3Npb24ocCkpIHBlcm1zLmFkZChwKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIEFMTF9QRVJNSVNTSU9OUy5maWx0ZXIocCA9PiBwZXJtcy5oYXMocCkpO1xufVxuXG4vKipcbiAqIENvbmZpbmUgYSByZXNvbHZlZCBwZXJtaXNzaW9uIGxpc3QgdG8gd2hhdCBtYXkgYmUgaGVsZCBpbiB0aGUgdG9rZW4ncyBBQ1RJVkVcbiAqIG9yZzogb3V0c2lkZSB0aGUgc3lzdGVtIG9yZyBldmVyeSB7QGxpbmsgU1lTVEVNX09SR19PTkxZX1BFUk1JU1NJT05TfSBlbnRyeSBpc1xuICogZHJvcHBlZCAoZG9jcy9wbHVnaW4tcHVibGlzaGluZy5tZCkuIEFwcGxpZWQgYXQgdG9rZW4gaXNzdWUgb25cbiAqIHRvcCBvZiB7QGxpbmsgcmVzb2x2ZVVzZXJQZXJtaXNzaW9uc30g4oCUIGluY2x1ZGluZyBhIHN1cGVyYWRtaW4ncyBpbXBsaWNpdC1hbGwg4oCUXG4gKiBzbyBhIHRva2VuIG1pbnRlZCBpbiBhIHRlbmFudCBvcmcgbmV2ZXIgQ0xBSU1TIGBwbHVnaW5zOm1vZGVyYXRlYCAvXG4gKiBgcHVibGlzaGVyczp2ZXJpZnlgLCBldmVuIGlmIGEgaGFuZC13cml0dGVuIFJvbGUgZG9jdW1lbnQgc29tZWhvdyBjYXJyaWVkXG4gKiB0aGVtIHRoZXJlLiAoU3VwZXJhZG1pbnMgc3RpbGwgcGFzcyBgaGFzUGVybWlzc2lvbmAgdmlhIHRoZSBmbGFnOyB0aGVcbiAqIGVjb3N5c3RlbSByb3V0ZSBnYXRlIGFkZGl0aW9uYWxseSByZXF1aXJlcyB0aGUgc3lzdGVtIG9yZywgc28gdGhhdCBieXBhc3NcbiAqIG5ldmVyIHJlYWNoZXMgYSBnb3Zlcm5hbmNlIHJvdXRlIGZyb20gYSB0ZW5hbnQgb3JnIGVpdGhlci4pXG4gKlxuICogVGFrZXMgYSBib29sZWFuIHJhdGhlciB0aGFuIGFuIG9yZyBpZCBzbyB0aGlzIG1vZHVsZSBzdGF5cyBkZXBlbmRlbmN5LWZyZWVcbiAqICh0aGUgZnJvbnRlbmQgaW1wb3J0cyBpdCk7IGNhbGxlcnMgZGVjaWRlIHdpdGggYXBpLWNvcmUgYGlzU3lzdGVtT3JnSWRgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29uZmluZVBlcm1pc3Npb25zVG9Pcmc8UCBleHRlbmRzIHN0cmluZz4oXG4gIHBlcm1pc3Npb25zOiByZWFkb25seSBQW10sXG4gIGFjdGl2ZU9yZ0lzU3lzdGVtT3JnOiBib29sZWFuLFxuKTogUFtdIHtcbiAgcmV0dXJuIGFjdGl2ZU9yZ0lzU3lzdGVtT3JnID8gWy4uLnBlcm1pc3Npb25zXSA6IHBlcm1pc3Npb25zLmZpbHRlcigocCkgPT4gIWlzU3lzdGVtT3JnT25seVBlcm1pc3Npb24ocCkpO1xufVxuXG4vKiogV2hldGhlciBhIHJlc29sdmVkIHBlcm1pc3Npb24gbGlzdCBncmFudHMgYHBlcm1pc3Npb25gIChzdXBlcmFkbWluIOKHkiBhbHdheXMpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1Blcm1pc3Npb24oXG4gIGdyYW50ZWQ6IHJlYWRvbmx5IHN0cmluZ1tdIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgcGVybWlzc2lvbjogUGVybWlzc2lvbixcbiAgaXNTdXBlckFkbWluPzogYm9vbGVhbixcbik6IGJvb2xlYW4ge1xuICBpZiAoaXNTdXBlckFkbWluKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuICEhZ3JhbnRlZCAmJiBncmFudGVkLmluY2x1ZGVzKHBlcm1pc3Npb24pO1xufVxuIl19
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Plugin catalog vocabulary: the descriptive (editable) fields of a plugin
3
+ * version, the category ids, the per-field provenance values and the size
4
+ * limits. Dependency-free so the browser imports it through the
5
+ * `@pipeline-builder/api-core/plugin-catalog` subpath; the Zod validators built
6
+ * on it live in `validation/plugin-catalog-metadata.ts`.
7
+ */
8
+ /** Card one-liner cap. */
9
+ export declare const PLUGIN_SUMMARY_MAX = 160;
10
+ /** `description` cap, characters. */
11
+ export declare const PLUGIN_DESCRIPTION_MAX = 2000;
12
+ /** `displayName` cap, characters. */
13
+ export declare const PLUGIN_DISPLAY_NAME_MAX = 100;
14
+ /** Max keywords, and max characters per keyword. */
15
+ export declare const PLUGIN_KEYWORDS_MAX = 10;
16
+ export declare const PLUGIN_KEYWORD_MAX_LENGTH = 32;
17
+ /** README.md cap, bytes (UTF-8). */
18
+ export declare const PLUGIN_README_MAX_BYTES: number;
19
+ /** `changelog` cap, bytes (UTF-8). */
20
+ export declare const PLUGIN_CHANGELOG_MAX_BYTES: number;
21
+ /** Project URL cap, characters. */
22
+ export declare const PLUGIN_URL_MAX = 2048;
23
+ /** Canonical plugin categories (the directory's category grid, `plugin-spec.yaml`, `report-schema.json`). */
24
+ export declare const PLUGIN_CATEGORIES: readonly ['language', 'security', 'quality', 'monitoring', 'artifact', 'deploy', 'infrastructure', 'testing', 'notification', 'ai'];
25
+ export type PluginCatalogCategory = typeof PLUGIN_CATEGORIES[number];
26
+ /** Every descriptive (editable) catalog field, in display order. */
27
+ export declare const PLUGIN_CATALOG_FIELDS: readonly ['displayName', 'summary', 'description', 'category', 'keywords', 'license', 'homepageUrl', 'sourceUrl', 'documentationUrl', 'icon', 'changelog', 'readme'];
28
+ export type PluginCatalogField = typeof PLUGIN_CATALOG_FIELDS[number];
29
+ /** The link fields — a user-edited link is highlighted in review. */
30
+ export declare const PLUGIN_CATALOG_LINK_FIELDS: ReadonlyArray<PluginCatalogField>;
31
+ /** Where a catalog field's value came from (stored per version in `metadata_sources`; `user` = edited by a person). */
32
+ export declare const METADATA_SOURCES: readonly ['spec', 'readme', 'dockerfile', 'derived', 'user'];
33
+ export type MetadataSource = typeof METADATA_SOURCES[number];
34
+ /** Per-field provenance of a version's catalog metadata. */
35
+ export type MetadataSources = Partial<Record<PluginCatalogField, MetadataSource>>;
@@ -0,0 +1,39 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Plugin catalog vocabulary: the descriptive (editable) fields of a plugin
5
+ * version, the category ids, the per-field provenance values and the size
6
+ * limits. Dependency-free so the browser imports it through the
7
+ * `@pipeline-builder/api-core/plugin-catalog` subpath; the Zod validators built
8
+ * on it live in `validation/plugin-catalog-metadata.ts`.
9
+ */
10
+ /** Card one-liner cap. */
11
+ export const PLUGIN_SUMMARY_MAX = 160;
12
+ /** `description` cap, characters. */
13
+ export const PLUGIN_DESCRIPTION_MAX = 2000;
14
+ /** `displayName` cap, characters. */
15
+ export const PLUGIN_DISPLAY_NAME_MAX = 100;
16
+ /** Max keywords, and max characters per keyword. */
17
+ export const PLUGIN_KEYWORDS_MAX = 10;
18
+ export const PLUGIN_KEYWORD_MAX_LENGTH = 32;
19
+ /** README.md cap, bytes (UTF-8). */
20
+ export const PLUGIN_README_MAX_BYTES = 64 * 1024;
21
+ /** `changelog` cap, bytes (UTF-8). */
22
+ export const PLUGIN_CHANGELOG_MAX_BYTES = 32 * 1024;
23
+ /** Project URL cap, characters. */
24
+ export const PLUGIN_URL_MAX = 2048;
25
+ /** Canonical plugin categories (the directory's category grid, `plugin-spec.yaml`, `report-schema.json`). */
26
+ export const PLUGIN_CATEGORIES = [
27
+ 'language', 'security', 'quality', 'monitoring', 'artifact',
28
+ 'deploy', 'infrastructure', 'testing', 'notification', 'ai',
29
+ ];
30
+ /** Every descriptive (editable) catalog field, in display order. */
31
+ export const PLUGIN_CATALOG_FIELDS = [
32
+ 'displayName', 'summary', 'description', 'category', 'keywords', 'license',
33
+ 'homepageUrl', 'sourceUrl', 'documentationUrl', 'icon', 'changelog', 'readme',
34
+ ];
35
+ /** The link fields — a user-edited link is highlighted in review. */
36
+ export const PLUGIN_CATALOG_LINK_FIELDS = ['homepageUrl', 'sourceUrl', 'documentationUrl'];
37
+ /** Where a catalog field's value came from (stored per version in `metadata_sources`; `user` = edited by a person). */
38
+ export const METADATA_SOURCES = ['spec', 'readme', 'dockerfile', 'derived', 'user'];
39
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWNhdGFsb2cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvcGx1Z2luLWNhdGFsb2cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7O0dBTUc7QUFFSCwwQkFBMEI7QUFDMUIsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsR0FBRyxDQUFDO0FBQ3RDLHFDQUFxQztBQUNyQyxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLENBQUM7QUFDM0MscUNBQXFDO0FBQ3JDLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLEdBQUcsQ0FBQztBQUMzQyxvREFBb0Q7QUFDcEQsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsRUFBRSxDQUFDO0FBQ3RDLE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLEVBQUUsQ0FBQztBQUM1QyxvQ0FBb0M7QUFDcEMsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUNqRCxzQ0FBc0M7QUFDdEMsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUNwRCxtQ0FBbUM7QUFDbkMsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQztBQUVuQyw2R0FBNkc7QUFDN0csTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUc7SUFDL0IsVUFBVSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLFVBQVU7SUFDM0QsUUFBUSxFQUFFLGdCQUFnQixFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsSUFBSTtDQUNuRCxDQUFDO0FBR1gsb0VBQW9FO0FBQ3BFLE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHO0lBQ25DLGFBQWEsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsU0FBUztJQUMxRSxhQUFhLEVBQUUsV0FBVyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsUUFBUTtDQUNyRSxDQUFDO0FBR1gscUVBQXFFO0FBQ3JFLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFzQyxDQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztBQUU5SCx1SEFBdUg7QUFDdkgsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFVLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBQbHVnaW4gY2F0YWxvZyB2b2NhYnVsYXJ5OiB0aGUgZGVzY3JpcHRpdmUgKGVkaXRhYmxlKSBmaWVsZHMgb2YgYSBwbHVnaW5cbiAqIHZlcnNpb24sIHRoZSBjYXRlZ29yeSBpZHMsIHRoZSBwZXItZmllbGQgcHJvdmVuYW5jZSB2YWx1ZXMgYW5kIHRoZSBzaXplXG4gKiBsaW1pdHMuIERlcGVuZGVuY3ktZnJlZSBzbyB0aGUgYnJvd3NlciBpbXBvcnRzIGl0IHRocm91Z2ggdGhlXG4gKiBgQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUvcGx1Z2luLWNhdGFsb2dgIHN1YnBhdGg7IHRoZSBab2QgdmFsaWRhdG9ycyBidWlsdFxuICogb24gaXQgbGl2ZSBpbiBgdmFsaWRhdGlvbi9wbHVnaW4tY2F0YWxvZy1tZXRhZGF0YS50c2AuXG4gKi9cblxuLyoqIENhcmQgb25lLWxpbmVyIGNhcC4gKi9cbmV4cG9ydCBjb25zdCBQTFVHSU5fU1VNTUFSWV9NQVggPSAxNjA7XG4vKiogYGRlc2NyaXB0aW9uYCBjYXAsIGNoYXJhY3RlcnMuICovXG5leHBvcnQgY29uc3QgUExVR0lOX0RFU0NSSVBUSU9OX01BWCA9IDIwMDA7XG4vKiogYGRpc3BsYXlOYW1lYCBjYXAsIGNoYXJhY3RlcnMuICovXG5leHBvcnQgY29uc3QgUExVR0lOX0RJU1BMQVlfTkFNRV9NQVggPSAxMDA7XG4vKiogTWF4IGtleXdvcmRzLCBhbmQgbWF4IGNoYXJhY3RlcnMgcGVyIGtleXdvcmQuICovXG5leHBvcnQgY29uc3QgUExVR0lOX0tFWVdPUkRTX01BWCA9IDEwO1xuZXhwb3J0IGNvbnN0IFBMVUdJTl9LRVlXT1JEX01BWF9MRU5HVEggPSAzMjtcbi8qKiBSRUFETUUubWQgY2FwLCBieXRlcyAoVVRGLTgpLiAqL1xuZXhwb3J0IGNvbnN0IFBMVUdJTl9SRUFETUVfTUFYX0JZVEVTID0gNjQgKiAxMDI0O1xuLyoqIGBjaGFuZ2Vsb2dgIGNhcCwgYnl0ZXMgKFVURi04KS4gKi9cbmV4cG9ydCBjb25zdCBQTFVHSU5fQ0hBTkdFTE9HX01BWF9CWVRFUyA9IDMyICogMTAyNDtcbi8qKiBQcm9qZWN0IFVSTCBjYXAsIGNoYXJhY3RlcnMuICovXG5leHBvcnQgY29uc3QgUExVR0lOX1VSTF9NQVggPSAyMDQ4O1xuXG4vKiogQ2Fub25pY2FsIHBsdWdpbiBjYXRlZ29yaWVzICh0aGUgZGlyZWN0b3J5J3MgY2F0ZWdvcnkgZ3JpZCwgYHBsdWdpbi1zcGVjLnlhbWxgLCBgcmVwb3J0LXNjaGVtYS5qc29uYCkuICovXG5leHBvcnQgY29uc3QgUExVR0lOX0NBVEVHT1JJRVMgPSBbXG4gICdsYW5ndWFnZScsICdzZWN1cml0eScsICdxdWFsaXR5JywgJ21vbml0b3JpbmcnLCAnYXJ0aWZhY3QnLFxuICAnZGVwbG95JywgJ2luZnJhc3RydWN0dXJlJywgJ3Rlc3RpbmcnLCAnbm90aWZpY2F0aW9uJywgJ2FpJyxcbl0gYXMgY29uc3Q7XG5leHBvcnQgdHlwZSBQbHVnaW5DYXRhbG9nQ2F0ZWdvcnkgPSB0eXBlb2YgUExVR0lOX0NBVEVHT1JJRVNbbnVtYmVyXTtcblxuLyoqIEV2ZXJ5IGRlc2NyaXB0aXZlIChlZGl0YWJsZSkgY2F0YWxvZyBmaWVsZCwgaW4gZGlzcGxheSBvcmRlci4gKi9cbmV4cG9ydCBjb25zdCBQTFVHSU5fQ0FUQUxPR19GSUVMRFMgPSBbXG4gICdkaXNwbGF5TmFtZScsICdzdW1tYXJ5JywgJ2Rlc2NyaXB0aW9uJywgJ2NhdGVnb3J5JywgJ2tleXdvcmRzJywgJ2xpY2Vuc2UnLFxuICAnaG9tZXBhZ2VVcmwnLCAnc291cmNlVXJsJywgJ2RvY3VtZW50YXRpb25VcmwnLCAnaWNvbicsICdjaGFuZ2Vsb2cnLCAncmVhZG1lJyxcbl0gYXMgY29uc3Q7XG5leHBvcnQgdHlwZSBQbHVnaW5DYXRhbG9nRmllbGQgPSB0eXBlb2YgUExVR0lOX0NBVEFMT0dfRklFTERTW251bWJlcl07XG5cbi8qKiBUaGUgbGluayBmaWVsZHMg4oCUIGEgdXNlci1lZGl0ZWQgbGluayBpcyBoaWdobGlnaHRlZCBpbiByZXZpZXcuICovXG5leHBvcnQgY29uc3QgUExVR0lOX0NBVEFMT0dfTElOS19GSUVMRFM6IFJlYWRvbmx5QXJyYXk8UGx1Z2luQ2F0YWxvZ0ZpZWxkPiA9IFsnaG9tZXBhZ2VVcmwnLCAnc291cmNlVXJsJywgJ2RvY3VtZW50YXRpb25VcmwnXTtcblxuLyoqIFdoZXJlIGEgY2F0YWxvZyBmaWVsZCdzIHZhbHVlIGNhbWUgZnJvbSAoc3RvcmVkIHBlciB2ZXJzaW9uIGluIGBtZXRhZGF0YV9zb3VyY2VzYDsgYHVzZXJgID0gZWRpdGVkIGJ5IGEgcGVyc29uKS4gKi9cbmV4cG9ydCBjb25zdCBNRVRBREFUQV9TT1VSQ0VTID0gWydzcGVjJywgJ3JlYWRtZScsICdkb2NrZXJmaWxlJywgJ2Rlcml2ZWQnLCAndXNlciddIGFzIGNvbnN0O1xuZXhwb3J0IHR5cGUgTWV0YWRhdGFTb3VyY2UgPSB0eXBlb2YgTUVUQURBVEFfU09VUkNFU1tudW1iZXJdO1xuLyoqIFBlci1maWVsZCBwcm92ZW5hbmNlIG9mIGEgdmVyc2lvbidzIGNhdGFsb2cgbWV0YWRhdGEuICovXG5leHBvcnQgdHlwZSBNZXRhZGF0YVNvdXJjZXMgPSBQYXJ0aWFsPFJlY29yZDxQbHVnaW5DYXRhbG9nRmllbGQsIE1ldGFkYXRhU291cmNlPj47XG4iXX0=
@@ -0,0 +1,102 @@
1
+ /**
2
+ * The plugin HEALTH SCORE (docs/plugin-publishing.md): one 0–100
3
+ * number per listing, from seven components. Pure and dependency-free so the
4
+ * plugin service (the stats sweep), the frontend (the breakdown panel's
5
+ * labels) and the tests share one definition.
6
+ *
7
+ * Each component scores 0..1 and carries a fixed weight. A component whose
8
+ * inputs are missing is DROPPED and the remaining weights are renormalized; with
9
+ * fewer than {@link HEALTH_MIN_COMPONENTS} components the score is null ("not
10
+ * enough data"), never a guess.
11
+ *
12
+ * | component | weight | score |
13
+ * |------------|--------|-----------------------------------------------------------------------|
14
+ * | runtime | 25 | 30-day success rate; only with ≥ 20 runs |
15
+ * | vulns | 20 | 1 − 0.5·critical − 0.1·high (floor 0), latest listed version; scanned only |
16
+ * | freshness | 15 | release age (≤90d 1 → 0 at 540d) averaged with base-image age (≤60d 1 → 0 at 365d) when recorded |
17
+ * | signed | 10 | image digest present and signed ⇒ 1 |
18
+ * | smokeTest | 10 | smoke test declared ⇒ 1 |
19
+ * | docs | 10 | README 0.5 + license 0.5 |
20
+ * | rating | 10 | Bayesian rating / 5; only with ≥ 3 ratings |
21
+ */
22
+ export declare const HEALTH_COMPONENTS: readonly ['runtime', 'vulns', 'freshness', 'signed', 'smokeTest', 'docs', 'rating'];
23
+ export type HealthComponent = (typeof HEALTH_COMPONENTS)[number];
24
+ /** Nominal weight of each component (they sum to 100). */
25
+ export declare const HEALTH_WEIGHTS: Readonly<Record<HealthComponent, number>>;
26
+ /** Human labels for the breakdown panel. */
27
+ export declare const HEALTH_COMPONENT_LABELS: Readonly<Record<HealthComponent, string>>;
28
+ /** Fewer available components than this ⇒ no score. */
29
+ export declare const HEALTH_MIN_COMPONENTS = 3;
30
+ /** Runs needed in the window before the success rate counts. */
31
+ export declare const HEALTH_MIN_RUNS = 20;
32
+ /** Ratings needed before the rating counts. */
33
+ export declare const HEALTH_MIN_RATINGS = 3;
34
+ /** Release age: full marks up to this many days, zero at {@link HEALTH_RELEASE_ZERO_DAYS}. */
35
+ export declare const HEALTH_RELEASE_FULL_DAYS = 90;
36
+ export declare const HEALTH_RELEASE_ZERO_DAYS = 540;
37
+ /** Base-image age: full marks up to this many days, zero at {@link HEALTH_BASE_IMAGE_ZERO_DAYS}. */
38
+ export declare const HEALTH_BASE_IMAGE_FULL_DAYS = 60;
39
+ export declare const HEALTH_BASE_IMAGE_ZERO_DAYS = 365;
40
+ /** One component's contribution: its 0..1 score (null = missing, dropped) and its nominal weight. */
41
+ export interface HealthComponentScore {
42
+ score: number | null;
43
+ weight: number;
44
+ }
45
+ export type HealthBreakdown = Record<HealthComponent, HealthComponentScore>;
46
+ export interface HealthResult {
47
+ /** 0–100 integer, or null with fewer than {@link HEALTH_MIN_COMPONENTS} components. */
48
+ score: number | null;
49
+ breakdown: HealthBreakdown;
50
+ }
51
+ /**
52
+ * What the score is computed from. Every field is optional: `undefined` / null
53
+ * means "not known", which drops the component (or, for freshness, that half).
54
+ */
55
+ export interface HealthInputs {
56
+ /** Terminal runs in the 30-day window, and the share that succeeded (0..1). */
57
+ runs30d?: number | null;
58
+ successRate30d?: number | null;
59
+ /** The latest listed version's scan; `scannedAt` null ⇒ never scanned. */
60
+ vulnCritical?: number | null;
61
+ vulnHigh?: number | null;
62
+ scannedAt?: Date | string | null;
63
+ /** When the latest listed version was published. */
64
+ lastReleaseAt?: Date | string | null;
65
+ /** The latest listed version's base image `created` time, when recorded. */
66
+ baseImageCreatedAt?: Date | string | null;
67
+ /** Latest listed version has an image digest AND a signature (its `public/*` copy). */
68
+ signed?: boolean | null;
69
+ smokeTestDeclared?: boolean | null;
70
+ hasReadme?: boolean | null;
71
+ hasLicense?: boolean | null;
72
+ ratingBayes?: number | null;
73
+ ratingCount?: number | null;
74
+ }
75
+ /** 1 up to `fullDays`, falling linearly to 0 at `zeroDays` (a future date counts as fresh). */
76
+ export declare function ageScore(ageDays: number, fullDays: number, zeroDays: number): number;
77
+ /** The vulnerability component: 1 − 0.5·critical − 0.1·high, floored at 0. */
78
+ export declare function vulnScore(critical: number, high: number): number;
79
+ /** The health score and its per-component breakdown. Pure; `now` is injectable for tests. */
80
+ export declare function computeHealthScore(inputs: HealthInputs, now?: Date): HealthResult;
81
+ /**
82
+ * A publisher's health: the install-weighted mean of its listings' scores
83
+ * (listings with no score are skipped; when no listing has installs, the plain
84
+ * mean). Null when no listing has a score.
85
+ */
86
+ export declare function publisherHealthScore(listings: ReadonlyArray<{
87
+ healthScore: number | null;
88
+ installCount: number;
89
+ }>): number | null;
90
+ /**
91
+ * A publisher's 30-day success rate across its listings, weighted by runs.
92
+ * Null when none of its listings ran in the window.
93
+ */
94
+ export declare function publisherSuccessRate(listings: ReadonlyArray<{
95
+ successRate30d: number | null;
96
+ runs30d: number;
97
+ }>): number | null;
98
+ /** Display band for a score: good ≥ 80, fair ≥ 50, poor below, unknown when null. */
99
+ export type HealthBand = 'good' | 'fair' | 'poor' | 'unknown';
100
+ export declare const HEALTH_BAND_GOOD = 80;
101
+ export declare const HEALTH_BAND_FAIR = 50;
102
+ export declare function healthBand(score: number | null | undefined): HealthBand;