@pipeline-builder/pipeline-data 4.1.14 → 4.1.16

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 (60) hide show
  1. package/lib/api/access-control-builder.d.ts +18 -1
  2. package/lib/api/access-control-builder.js +19 -6
  3. package/lib/api/crud-service.d.ts +94 -36
  4. package/lib/api/crud-service.js +188 -166
  5. package/lib/api/plugin-resolution.d.ts +253 -0
  6. package/lib/api/plugin-resolution.js +649 -0
  7. package/lib/api/public-directory.d.ts +281 -0
  8. package/lib/api/public-directory.js +457 -0
  9. package/lib/api/query-builders.d.ts +13 -0
  10. package/lib/api/query-builders.js +74 -9
  11. package/lib/api/reporting/caches.js +4 -4
  12. package/lib/api/reporting/dora-scoring.d.ts +3 -3
  13. package/lib/api/reporting/dora-scoring.js +4 -4
  14. package/lib/api/reporting/dora.d.ts +6 -6
  15. package/lib/api/reporting/dora.js +97 -73
  16. package/lib/api/reporting/plugin-runtime.d.ts +25 -0
  17. package/lib/api/reporting/plugin-runtime.js +106 -0
  18. package/lib/api/reporting/query-scope.d.ts +8 -2
  19. package/lib/api/reporting/query-scope.js +16 -7
  20. package/lib/api/reporting/retention.d.ts +4 -10
  21. package/lib/api/reporting/retention.js +8 -11
  22. package/lib/api/reporting/sql-helpers.d.ts +4 -7
  23. package/lib/api/reporting/sql-helpers.js +8 -9
  24. package/lib/api/reporting/types.d.ts +55 -17
  25. package/lib/api/reporting/types.js +1 -1
  26. package/lib/api/reporting-service.d.ts +35 -26
  27. package/lib/api/reporting-service.js +245 -161
  28. package/lib/api/semver-range.d.ts +73 -0
  29. package/lib/api/semver-range.js +227 -0
  30. package/lib/api/soft-delete-sweep.js +8 -20
  31. package/lib/core/query-filters.d.ts +18 -3
  32. package/lib/core/query-filters.js +1 -1
  33. package/lib/database/drizzle-schema.d.ts +7790 -2461
  34. package/lib/database/drizzle-schema.js +29 -1
  35. package/lib/database/index.d.ts +4 -2
  36. package/lib/database/index.js +5 -3
  37. package/lib/database/pg-result.d.ts +19 -0
  38. package/lib/database/pg-result.js +32 -0
  39. package/lib/database/postgres-connection.js +14 -24
  40. package/lib/database/public-reader.d.ts +14 -0
  41. package/lib/database/public-reader.js +68 -0
  42. package/lib/database/retry-strategy.d.ts +3 -5
  43. package/lib/database/retry-strategy.js +4 -6
  44. package/lib/database/schema/compliance.d.ts +16 -34
  45. package/lib/database/schema/compliance.js +4 -4
  46. package/lib/database/schema/dashboard.js +4 -2
  47. package/lib/database/schema/ecosystem.d.ts +6586 -0
  48. package/lib/database/schema/ecosystem.js +709 -0
  49. package/lib/database/schema/message.d.ts +6 -12
  50. package/lib/database/schema/message.js +3 -1
  51. package/lib/database/schema/pipeline.d.ts +79 -5
  52. package/lib/database/schema/pipeline.js +46 -25
  53. package/lib/database/schema/plugin.d.ts +587 -3
  54. package/lib/database/schema/plugin.js +86 -14
  55. package/lib/database/tenancy.d.ts +6 -7
  56. package/lib/database/tenancy.js +13 -14
  57. package/lib/index.d.ts +7 -4
  58. package/lib/index.js +7 -4
  59. package/lib/testing/exports.json +146 -0
  60. package/package.json +44 -7
@@ -72,6 +72,18 @@ export interface BaseAccessFilter {
72
72
  viewerUserId?: string;
73
73
  viewerIsSuperAdmin?: boolean;
74
74
  }
75
+ /** Per-entity tuning of {@link AccessControlQueryBuilder}. */
76
+ export interface AccessControlOptions {
77
+ /**
78
+ * Whether the SYSTEM org's `public` rung reaches callers in other orgs (and
79
+ * anonymous callers). Default true: the system org's sample pipelines,
80
+ * templates and dashboards are visible from every org. Plugins set it false:
81
+ * since the plugin ecosystem the Official catalog reaches
82
+ * other orgs only as LISTINGS resolved through installs, never through
83
+ * `visibility = 'public'` on a `plugins` row.
84
+ */
85
+ systemCatalog?: boolean;
86
+ }
75
87
  /**
76
88
  * Generic access control query builder for multi-tenant entities.
77
89
  *
@@ -86,7 +98,8 @@ export interface BaseAccessFilter {
86
98
  */
87
99
  export declare class AccessControlQueryBuilder<TSchema extends AccessControlSchema, TFilter extends BaseAccessFilter> {
88
100
  private schema;
89
- constructor(schema: TSchema);
101
+ private options;
102
+ constructor(schema: TSchema, options?: AccessControlOptions);
90
103
  /**
91
104
  * Build the caller's visible slice of a catalog, from the three-rung
92
105
  * `visibility` ladder shared by every catalog entity.
@@ -103,6 +116,10 @@ export declare class AccessControlQueryBuilder<TSchema extends AccessControlSche
103
116
  * always see everything you are entitled to, or a freshly-created private row
104
117
  * would vanish from its own author's listing.
105
118
  *
119
+ * An entity can drop the system-org branch with `systemCatalog: false`
120
+ * ({@link AccessControlOptions}): plugins do, so a system-org plugin reaches
121
+ * other orgs only as an Official listing.
122
+ *
106
123
  * An explicit `visibility` filter NARROWS within that set, never widens it —
107
124
  * so `?visibility=public` still surfaces the system-org catalog.
108
125
  *
@@ -103,8 +103,10 @@ const NO_ROWS = sql `false`;
103
103
  */
104
104
  export class AccessControlQueryBuilder {
105
105
  schema;
106
- constructor(schema) {
106
+ options;
107
+ constructor(schema, options = {}) {
107
108
  this.schema = schema;
109
+ this.options = options;
108
110
  }
109
111
  /**
110
112
  * Build the caller's visible slice of a catalog, from the three-rung
@@ -122,6 +124,10 @@ export class AccessControlQueryBuilder {
122
124
  * always see everything you are entitled to, or a freshly-created private row
123
125
  * would vanish from its own author's listing.
124
126
  *
127
+ * An entity can drop the system-org branch with `systemCatalog: false`
128
+ * ({@link AccessControlOptions}): plugins do, so a system-org plugin reaches
129
+ * other orgs only as an Official listing.
130
+ *
125
131
  * An explicit `visibility` filter NARROWS within that set, never widens it —
126
132
  * so `?visibility=public` still surfaces the system-org catalog.
127
133
  *
@@ -138,8 +144,12 @@ export class AccessControlQueryBuilder {
138
144
  buildAccessControl(filter, orgId, parentOrgId) {
139
145
  const conditions = [];
140
146
  const requested = filter.visibility;
147
+ const systemCatalog = this.options.systemCatalog !== false;
141
148
  if (!orgId) {
142
- // No org context — only the system org's public catalog.
149
+ // No org context — only the system org's public catalog (nothing at all
150
+ // for an entity without one).
151
+ if (!systemCatalog)
152
+ return [NO_ROWS];
143
153
  conditions.push(eq(this.schema.orgId, SYSTEM_ORG_ID));
144
154
  conditions.push(eq(this.schema.visibility, 'public'));
145
155
  // An anonymous caller asking for a narrower rung gets nothing, rather than
@@ -155,11 +165,14 @@ export class AccessControlQueryBuilder {
155
165
  ? eq(this.schema.orgId, normalizedOrgId)
156
166
  : and(eq(this.schema.orgId, normalizedOrgId), or(ne(this.schema.visibility, 'private'), ownDraftsOnly));
157
167
  // Rows from OTHER orgs are only ever visible at the `public` rung.
158
- const otherOrgScopes = [eq(this.schema.orgId, SYSTEM_ORG_ID)];
168
+ const otherOrgScopes = [];
169
+ if (systemCatalog)
170
+ otherOrgScopes.push(eq(this.schema.orgId, SYSTEM_ORG_ID));
159
171
  if (parentOrgId)
160
172
  otherOrgScopes.push(eq(this.schema.orgId, parentOrgId.toLowerCase()));
161
- const otherOrgsPublic = and(eq(this.schema.visibility, 'public'), or(...otherOrgScopes));
162
- conditions.push(or(ownOrg, otherOrgsPublic));
173
+ conditions.push(otherOrgScopes.length > 0
174
+ ? or(ownOrg, and(eq(this.schema.visibility, 'public'), or(...otherOrgScopes)))
175
+ : ownOrg);
163
176
  if (requested !== undefined)
164
177
  conditions.push(eq(this.schema.visibility, requested));
165
178
  return conditions;
@@ -208,4 +221,4 @@ export class AccessControlQueryBuilder {
208
221
  return conditions;
209
222
  }
210
223
  }
211
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWNvbnRyb2wtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvYWNjZXNzLWNvbnRyb2wtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHeEQsTUFBTSxTQUFTLEdBQUcsaUVBQWlFLENBQUM7QUFFcEY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLEdBQVc7SUFDN0MsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxNQUFpQixFQUFFLE9BQWU7SUFDM0UsTUFBTSxPQUFPLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDM0QsT0FBTyxHQUFHLENBQUEsbURBQW1ELE1BQU0sZ0NBQWdDLEdBQUcsR0FBRyxPQUFPLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDNUgsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEtBQWM7SUFDL0MsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLEtBQUssTUFBTSxDQUFDO0lBQ3ZELE9BQU8sT0FBTyxDQUFDLEtBQUss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LEVBQUUsQ0FBQztRQUU3QixnRUFBZ0U7UUFDaEUsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFFeEUsaUNBQWlDO1FBQ2pDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xELElBQUksV0FBVztZQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFOUMsa0JBQWtCO1FBQ2xCLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUVyRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgU1lTVEVNX09SR19JRCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGFuZCwgZXEsIG5lLCBvciwgc3FsLCBTUUwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgdHlwZSB7IEFueUNvbHVtbiB9IGZyb20gJ2RyaXp6bGUtb3JtL2NvbHVtbic7XG5cbmNvbnN0IEZVTExfVVVJRCA9IC9eWzAtOWEtZl17OH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17MTJ9JC9pO1xuXG4vKipcbiAqIEVzY2FwZSBTUUwgTElLRSB3aWxkY2FyZCBjaGFyYWN0ZXJzIHRvIHByZXZlbnQgd2lsZGNhcmQgaW5qZWN0aW9uLlxuICogUmVwbGFjZXMgYCVgIOKGkiBgXFxcXCVgLCBgX2Ag4oaSIGBcXFxcX2AsIGFuZCBgXFxcXGAg4oaSIGBcXFxcXFxcXGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVMaWtlV2lsZGNhcmRzKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cXFxcL2csICdcXFxcXFxcXCcpLnJlcGxhY2UoLyUvZywgJ1xcXFwlJykucmVwbGFjZSgvXy9nLCAnXFxcXF8nKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIGNvbmRpdGlvbiB0aGF0IGNoZWNrcyBpZiBhIEpTT05CIHRleHQgYXJyYXkgY29sdW1uIGNvbnRhaW5zIGEga2V5d29yZCAoY2FzZS1pbnNlbnNpdGl2ZSkuXG4gKiBVc2VkIGZvciBrZXl3b3Jkcy90YWdzIGZpbHRlcmluZyBvbiBwaXBlbGluZXMsIHBsdWdpbnMsIGFuZCBjb21wbGlhbmNlIHJ1bGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRKc29uYktleXdvcmRDb25kaXRpb24oY29sdW1uOiBBbnlDb2x1bW4sIGtleXdvcmQ6IHN0cmluZyk6IFNRTCB7XG4gIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGtleXdvcmQudG9Mb3dlckNhc2UoKSk7XG4gIHJldHVybiBzcWxgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIGpzb25iX2FycmF5X2VsZW1lbnRzX3RleHQoJHtjb2x1bW59KSBBUyBlbCBXSEVSRSBsb3dlcihlbCkgTElLRSAkeyclJyArIGVzY2FwZWQgKyAnJSd9KWA7XG59XG5cbi8qKlxuICogUGFyc2UgYm9vbGVhbiBmaWx0ZXIgdmFsdWUgZnJvbSBzdHJpbmcgb3IgYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCb29sZWFuRmlsdGVyKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykgcmV0dXJuIHZhbHVlO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuIHZhbHVlID09PSAndHJ1ZSc7XG4gIHJldHVybiBCb29sZWFuKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgc3RyaW5nIGZpbHRlciB2YWx1ZSB0byBsb3dlcmNhc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZ0ZpbHRlcih2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUudG9Mb3dlckNhc2UoKSA6IFN0cmluZyh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhbiBJRCBwcmVkaWNhdGUgd2l0aCBVVUlEIHByZWZpeCBtYXRjaGluZy5cbiAqXG4gKiAtIEZ1bGwgVVVJRCDihpIgZXhhY3QgbWF0Y2hcbiAqIC0gUGFydGlhbCBVVUlEIOKGkiBwcmVmaXggbWF0Y2ggdmlhIGBMSUtFYCAoYSBsaXN0LXNlYXJjaCBhZmZvcmRhbmNlKVxuICogLSBBYnNlbnQg4oaSIGBudWxsYCAobm8gcHJlZGljYXRlKVxuICpcbiAqIFN0YW5kYWxvbmUgc28gZW50aXRpZXMgdGhhdCBET04nVCB1c2Uge0BsaW5rIEFjY2Vzc0NvbnRyb2xRdWVyeUJ1aWxkZXJ9J3NcbiAqIGFjY2VzcyBjb250cm9sIChlLmcuIHBpcGVsaW5lIHRlbXBsYXRlcywgd2hpY2ggY2FycnkgdGhlaXIgb3duIHRocmVlLXJ1bmdcbiAqIHZpc2liaWxpdHkgbGFkZGVyKSBzdGlsbCBzaGFyZSBvbmUgaWQtbWF0Y2hpbmcgaW1wbGVtZW50YXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZElkQ29uZGl0aW9uKGlkQ29sdW1uOiBBbnlDb2x1bW4sIGlkOiB1bmtub3duKTogU1FMIHwgbnVsbCB7XG4gIGlmIChpZCA9PT0gdW5kZWZpbmVkIHx8IGlkID09PSBudWxsKSByZXR1cm4gbnVsbDtcblxuICAvLyBgQmFzZUFjY2Vzc0ZpbHRlci5pZGAgaXMgZGVjbGFyZWQgYHN0cmluZyB8IHN0cmluZ1tdYCwgc28gaG9ub3VyIHRoZSBhcnJheVxuICAvLyBmb3JtOiBtYXRjaCBBTlkgb2YgdGhlIGlkcywgZWFjaCB3aXRoIHRoZSBzYW1lIGV4YWN0LXZzLXByZWZpeCBzZW1hbnRpY3MgYXNcbiAgLy8gYSBzaW5nbGUgdmFsdWUuIGBTdHJpbmcoWydhJywnYiddKWAgd291bGQgb3RoZXJ3aXNlIHByb2R1Y2UgYExJS0UgJ2EsYiUnYFxuICAvLyBhbmQgc2lsZW50bHkgcmV0dXJuIHplcm8gcm93cyDigJQgYSB0cmFwIGZvciB0aGUgZmlyc3QgY2FsbGVyIHRvIHBhc3Mgb25lLlxuICBpZiAoQXJyYXkuaXNBcnJheShpZCkpIHtcbiAgICBjb25zdCBwYXJ0cyA9IGlkXG4gICAgICAubWFwKChvbmUpID0+IGJ1aWxkSWRDb25kaXRpb24oaWRDb2x1bW4sIG9uZSkpXG4gICAgICAuZmlsdGVyKChjKTogYyBpcyBTUUwgPT4gYyAhPT0gbnVsbCk7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHBhcnRzLmxlbmd0aCA9PT0gMSA/IHBhcnRzWzBdIDogKG9yKC4uLnBhcnRzKSBhcyBTUUwpO1xuICB9XG5cbiAgY29uc3QgaWRTdHJpbmcgPSBTdHJpbmcoaWQpLnRvTG93ZXJDYXNlKCk7XG4gIGlmIChGVUxMX1VVSUQudGVzdChpZFN0cmluZykpIHtcbiAgICByZXR1cm4gZXEoaWRDb2x1bW4sIGlkU3RyaW5nKTtcbiAgfVxuICAvLyBFc2NhcGUgU1FMIExJS0Ugd2lsZGNhcmRzIHRvIHByZXZlbnQgd2lsZGNhcmQgaW5qZWN0aW9uXG4gIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGlkU3RyaW5nKTtcbiAgcmV0dXJuIHNxbGAke2lkQ29sdW1ufTo6dGV4dCBMSUtFICR7ZXNjYXBlZCArICclJ30gRVNDQVBFICdcXFxcJ2A7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIGBpc0RlZmF1bHRgIC8gYGlzQWN0aXZlYCBwcmVkaWNhdGVzIHNoYXJlZCBieSBldmVyeSBjYXRhbG9nIGVudGl0eS5cbiAqIGBpc0FjdGl2ZWAgZGVmYXVsdHMgdG8gdHJ1ZSBzbyBzb2Z0LWRlbGV0ZWQgcm93cyBzdGF5IG91dCBvZiBub3JtYWwgcmVhZHMuXG4gKiBTdGFuZGFsb25lIGZvciB0aGUgc2FtZSByZWFzb24gYXMge0BsaW5rIGJ1aWxkSWRDb25kaXRpb259LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRCb29sZWFuQ29uZGl0aW9ucyhcbiAgY29sdW1uczogeyBpc0RlZmF1bHQ6IEFueUNvbHVtbjsgaXNBY3RpdmU6IEFueUNvbHVtbiB9LFxuICBmaWx0ZXI6IHsgaXNEZWZhdWx0PzogdW5rbm93bjsgaXNBY3RpdmU/OiB1bmtub3duIH0sXG4pOiBTUUxbXSB7XG4gIGNvbnN0IGNvbmRpdGlvbnM6IFNRTFtdID0gW107XG5cbiAgaWYgKGZpbHRlci5pc0RlZmF1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbmRpdGlvbnMucHVzaChlcShjb2x1bW5zLmlzRGVmYXVsdCwgcGFyc2VCb29sZWFuRmlsdGVyKGZpbHRlci5pc0RlZmF1bHQpKSk7XG4gIH1cblxuICBpZiAoZmlsdGVyLmlzQWN0aXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25kaXRpb25zLnB1c2goZXEoY29sdW1ucy5pc0FjdGl2ZSwgcGFyc2VCb29sZWFuRmlsdGVyKGZpbHRlci5pc0FjdGl2ZSkpKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBEZWZhdWx0IHRvIGFjdGl2ZSByZWNvcmRzIG9ubHkgdG8gZXhjbHVkZSBzb2Z0LWRlbGV0ZWQgZW50aXRpZXNcbiAgICBjb25kaXRpb25zLnB1c2goZXEoY29sdW1ucy5pc0FjdGl2ZSwgdHJ1ZSkpO1xuICB9XG5cbiAgcmV0dXJuIGNvbmRpdGlvbnM7XG59XG5cbi8qKlxuICogU2NoZW1hIHRhYmxlIGludGVyZmFjZSBmb3IgYWNjZXNzIGNvbnRyb2wgcXVlcmllcy4gRXZlcnkgY2F0YWxvZyBlbnRpdHlcbiAqIGNhcnJpZXMgdGhlIHNhbWUgZml2ZSBjb2x1bW5zLCB3aGljaCBpcyB3aGF0IGxldHMgT05FIHByZWRpY2F0ZSBzZXJ2ZVxuICogcGlwZWxpbmVzLCBwbHVnaW5zIGFuZCB0ZW1wbGF0ZXMgYWxpa2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNjZXNzQ29udHJvbFNjaGVtYSB7XG4gIGlkOiBBbnlDb2x1bW47XG4gIG9yZ0lkOiBBbnlDb2x1bW47XG4gIC8qKiBUaHJlZS1ydW5nIHNoYXJpbmcgbGFkZGVyIOKAlCBzZWUgYXBpLWNvcmUncyBgVmlzaWJpbGl0eWAuICovXG4gIHZpc2liaWxpdHk6IEFueUNvbHVtbjtcbiAgLyoqIEF1dGhvci4gT3ducyB0aGUgYHByaXZhdGVgIHJ1bmcuICovXG4gIGNyZWF0ZWRCeTogQW55Q29sdW1uO1xuICBpc0RlZmF1bHQ6IEFueUNvbHVtbjtcbiAgaXNBY3RpdmU6IEFueUNvbHVtbjtcbn1cblxuLyoqXG4gKiBCYXNlIGZpbHRlciBpbnRlcmZhY2Ugd2l0aCBjb21tb24gYWNjZXNzIGNvbnRyb2wgZmllbGRzLlxuICpcbiAqIGB2aWV3ZXJVc2VySWRgIC8gYHZpZXdlcklzU3VwZXJBZG1pbmAgYXJlIFNFUlZFUi1TRVQgKHN0YW1wZWQgZnJvbSB0aGUgcmVxdWVzdCdzXG4gKiB0ZW5hbnQgY29udGV4dCBieSBgd2l0aFZpZXdlckNvbnRleHRgKSwgbmV2ZXIgY2xpZW50LXN1cHBsaWVkIOKAlCBzZWVcbiAqIGB2aWV3ZXItY29udGV4dC50c2AgZm9yIHdoeSB0aGUgdGVuYW50IGNvbnRleHQgaXMgdGhlIGNoYW5uZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZUFjY2Vzc0ZpbHRlciB7XG4gIGlkPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIHZpc2liaWxpdHk/OiBzdHJpbmc7XG4gIGlzRGVmYXVsdD86IGJvb2xlYW4gfCBzdHJpbmc7XG4gIGlzQWN0aXZlPzogYm9vbGVhbiB8IHN0cmluZztcbiAgdmlld2VyVXNlcklkPzogc3RyaW5nO1xuICB2aWV3ZXJJc1N1cGVyQWRtaW4/OiBib29sZWFuO1xufVxuXG4vKiogRmFpbC1jbG9zZWQgcHJlZGljYXRlOiBtYXRjaGVzIG5vIHJvd3MuICovXG5jb25zdCBOT19ST1dTOiBTUUwgPSBzcWxgZmFsc2VgO1xuXG4vKipcbiAqIEdlbmVyaWMgYWNjZXNzIGNvbnRyb2wgcXVlcnkgYnVpbGRlciBmb3IgbXVsdGktdGVuYW50IGVudGl0aWVzLlxuICpcbiAqIENvbnNvbGlkYXRlcyBkdXBsaWNhdGUgYWNjZXNzIGNvbnRyb2wgbG9naWMgc2hhcmVkIGFjcm9zcyBwaXBlbGluZSBhbmQgcGx1Z2luIHF1ZXJpZXMuXG4gKiBIYW5kbGVzOlxuICogLSBNdWx0aS10ZW5hbnQgYWNjZXNzIGNvbnRyb2wgKHB1YmxpYy9wcml2YXRlL29yZy1hbmQtcHVibGljKVxuICogLSBVVUlEIHByZWZpeCBtYXRjaGluZyBmb3IgSUQgZmlsdGVyc1xuICogLSBCb29sZWFuIGZpZWxkIG5vcm1hbGl6YXRpb25cbiAqXG4gKiBAdHlwZVBhcmFtIFRTY2hlbWEgLSBTY2hlbWEgdGFibGUgdHlwZSB3aXRoIGFjY2VzcyBjb250cm9sIGZpZWxkc1xuICogQHR5cGVQYXJhbSBURmlsdGVyIC0gRmlsdGVyIHR5cGUgZXh0ZW5kaW5nIEJhc2VBY2Nlc3NGaWx0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIEFjY2Vzc0NvbnRyb2xRdWVyeUJ1aWxkZXI8XG4gIFRTY2hlbWEgZXh0ZW5kcyBBY2Nlc3NDb250cm9sU2NoZW1hLFxuICBURmlsdGVyIGV4dGVuZHMgQmFzZUFjY2Vzc0ZpbHRlcixcbj4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHNjaGVtYTogVFNjaGVtYSxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgY2FsbGVyJ3MgdmlzaWJsZSBzbGljZSBvZiBhIGNhdGFsb2csIGZyb20gdGhlIHRocmVlLXJ1bmdcbiAgICogYHZpc2liaWxpdHlgIGxhZGRlciBzaGFyZWQgYnkgZXZlcnkgY2F0YWxvZyBlbnRpdHkuXG4gICAqXG4gICAqIEVmZmVjdGl2ZSByZWFkIHNldCBmb3IgYSBjYWxsZXIgaW4gb3JnIGBPYCBhcyB1c2VyIGBWYCB3aG9zZSBwYXJlbnQgb3JnIGlzIGBQYDpcbiAgICpcbiAgICogICAob3JnX2lkID0gTyBBTkQgKHZpc2liaWxpdHkgPD4gJ3ByaXZhdGUnIE9SIGNyZWF0ZWRfYnkgPSBWKSlcbiAgICogICBPUiAodmlzaWJpbGl0eSA9ICdwdWJsaWMnIEFORCAob3JnX2lkID0gJ3N5c3RlbScgT1Igb3JnX2lkID0gUCkpXG4gICAqXG4gICAqIGkuZS4geW91ciBvd24gb3JnJ3Mgc2hhcmVkIHJ1bmdzIHBsdXMgeW91ciBvd24gZHJhZnRzLCB3aWRlbmVkIGJ5IHRoZSBzeXN0ZW1cbiAgICogb3JnJ3MgcHVibGljIGNhdGFsb2cgKHRoZSBzdGFuZGluZyBcInN5c3RlbS1vcmcgY29udGVudCBpcyB2aXNpYmxlIGZyb20gZXZlcnlcbiAgICogb3JnXCIgcnVsZSkgYW5kIOKAlCBmb3IgYSB0ZWFtIOKAlCBpdHMgcGFyZW50J3MgcHVibGljIHJvd3MuIFRoZSBgcHVibGljYC1vbmx5XG4gICAqIHJlc3RyaWN0aW9uIGFwcGxpZXMgc29sZWx5IHRvIHRob3NlIE9USEVSIG9yZ3MnIHJvd3M7IHdpdGhpbiB5b3VyIG93biBvcmcgeW91XG4gICAqIGFsd2F5cyBzZWUgZXZlcnl0aGluZyB5b3UgYXJlIGVudGl0bGVkIHRvLCBvciBhIGZyZXNobHktY3JlYXRlZCBwcml2YXRlIHJvd1xuICAgKiB3b3VsZCB2YW5pc2ggZnJvbSBpdHMgb3duIGF1dGhvcidzIGxpc3RpbmcuXG4gICAqXG4gICAqIEFuIGV4cGxpY2l0IGB2aXNpYmlsaXR5YCBmaWx0ZXIgTkFSUk9XUyB3aXRoaW4gdGhhdCBzZXQsIG5ldmVyIHdpZGVucyBpdCDigJRcbiAgICogc28gYD92aXNpYmlsaXR5PXB1YmxpY2Agc3RpbGwgc3VyZmFjZXMgdGhlIHN5c3RlbS1vcmcgY2F0YWxvZy5cbiAgICpcbiAgICogRmFpbHMgQ0xPU0VEIG9uIGJvdGggYXhlczogbm8gYG9yZ0lkYCAoYW5vbnltb3VzKSDih5Igc3lzdGVtLW9yZyBwdWJsaWMgb25seTtcbiAgICogbm8gYHZpZXdlclVzZXJJZGAg4oeSIHRoZSBwcml2YXRlIHJ1bmcgbWF0Y2hlcyBub3RoaW5nIHJhdGhlciB0aGFuIGV2ZXJ5dGhpbmcuXG4gICAqIGB2aWV3ZXJJc1N1cGVyQWRtaW5gIGxpZnRzIHRoZSBwcml2YXRlIHJ1bmcgb25seSDigJQgYSBwbGF0Zm9ybSBvcGVyYXRvclxuICAgKiBhZG1pbmlzdGVycyB0aGUgd2hvbGUgY2F0YWxvZy5cbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcGFyYW0gb3JnSWQgLSBVc2VyJ3Mgb3JnYW5pemF0aW9uIElEIChvcHRpb25hbClcbiAgICogQHBhcmFtIHBhcmVudE9yZ0lkIC0gUGFyZW50IG9yZyBJRCB3aGVuIHRoZSBjYWxsZXIgaXMgYSB0ZWFtIChvcHRpb25hbClcbiAgICogQHJldHVybnMgQXJyYXkgb2YgU1FMIGNvbmRpdGlvbnMgZm9yIGFjY2VzcyBjb250cm9sXG4gICAqL1xuICBwcm90ZWN0ZWQgYnVpbGRBY2Nlc3NDb250cm9sKGZpbHRlcjogUGFydGlhbDxURmlsdGVyPiwgb3JnSWQ/OiBzdHJpbmcsIHBhcmVudE9yZ0lkPzogc3RyaW5nKTogU1FMW10ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnM6IFNRTFtdID0gW107XG4gICAgY29uc3QgcmVxdWVzdGVkID0gZmlsdGVyLnZpc2liaWxpdHk7XG5cbiAgICBpZiAoIW9yZ0lkKSB7XG4gICAgICAvLyBObyBvcmcgY29udGV4dCDigJQgb25seSB0aGUgc3lzdGVtIG9yZydzIHB1YmxpYyBjYXRhbG9nLlxuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBTWVNURU1fT1JHX0lEKSk7XG4gICAgICBjb25kaXRpb25zLnB1c2goZXEodGhpcy5zY2hlbWEudmlzaWJpbGl0eSwgJ3B1YmxpYycpKTtcbiAgICAgIC8vIEFuIGFub255bW91cyBjYWxsZXIgYXNraW5nIGZvciBhIG5hcnJvd2VyIHJ1bmcgZ2V0cyBub3RoaW5nLCByYXRoZXIgdGhhblxuICAgICAgLy8gaGF2aW5nIHRoZSBuYXJyb3dpbmcgc2lsZW50bHkgaWdub3JlZC5cbiAgICAgIGlmIChyZXF1ZXN0ZWQgIT09IHVuZGVmaW5lZCAmJiByZXF1ZXN0ZWQgIT09ICdwdWJsaWMnKSBjb25kaXRpb25zLnB1c2goTk9fUk9XUyk7XG4gICAgICByZXR1cm4gY29uZGl0aW9ucztcbiAgICB9XG5cbiAgICBjb25zdCBub3JtYWxpemVkT3JnSWQgPSBvcmdJZC50b0xvd2VyQ2FzZSgpO1xuXG4gICAgLy8gT3duLW9yZyByb3dzOiBldmVyeXRoaW5nIEVYQ0VQVCBvdGhlciBwZW9wbGUncyBwcml2YXRlIGRyYWZ0cy5cbiAgICBjb25zdCBvd25EcmFmdHNPbmx5ID0gZmlsdGVyLnZpZXdlclVzZXJJZCA/IGVxKHRoaXMuc2NoZW1hLmNyZWF0ZWRCeSwgZmlsdGVyLnZpZXdlclVzZXJJZCkgOiBOT19ST1dTO1xuICAgIGNvbnN0IG93bk9yZyA9IGZpbHRlci52aWV3ZXJJc1N1cGVyQWRtaW5cbiAgICAgID8gZXEodGhpcy5zY2hlbWEub3JnSWQsIG5vcm1hbGl6ZWRPcmdJZClcbiAgICAgIDogYW5kKGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBub3JtYWxpemVkT3JnSWQpLCBvcihuZSh0aGlzLnNjaGVtYS52aXNpYmlsaXR5LCAncHJpdmF0ZScpLCBvd25EcmFmdHNPbmx5KSEpITtcblxuICAgIC8vIFJvd3MgZnJvbSBPVEhFUiBvcmdzIGFyZSBvbmx5IGV2ZXIgdmlzaWJsZSBhdCB0aGUgYHB1YmxpY2AgcnVuZy5cbiAgICBjb25zdCBvdGhlck9yZ1Njb3BlcyA9IFtlcSh0aGlzLnNjaGVtYS5vcmdJZCwgU1lTVEVNX09SR19JRCldO1xuICAgIGlmIChwYXJlbnRPcmdJZCkgb3RoZXJPcmdTY29wZXMucHVzaChlcSh0aGlzLnNjaGVtYS5vcmdJZCwgcGFyZW50T3JnSWQudG9Mb3dlckNhc2UoKSkpO1xuICAgIGNvbnN0IG90aGVyT3Jnc1B1YmxpYyA9IGFuZChlcSh0aGlzLnNjaGVtYS52aXNpYmlsaXR5LCAncHVibGljJyksIG9yKC4uLm90aGVyT3JnU2NvcGVzKSEpITtcblxuICAgIGNvbmRpdGlvbnMucHVzaChvcihvd25PcmcsIG90aGVyT3Jnc1B1YmxpYykhKTtcblxuICAgIGlmIChyZXF1ZXN0ZWQgIT09IHVuZGVmaW5lZCkgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLnZpc2liaWxpdHksIHJlcXVlc3RlZCkpO1xuXG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgSUQgZmlsdGVyIHdpdGggVVVJRCBwcmVmaXggbWF0Y2hpbmcgc3VwcG9ydFxuICAgKlxuICAgKiAtIEZ1bGwgVVVJRDogRXhhY3QgbWF0Y2hcbiAgICogLSBQYXJ0aWFsIFVVSUQ6IFByZWZpeCBtYXRjaCB1c2luZyBTUUwgTElLRVxuICAgKlxuICAgKiBAcGFyYW0gaWQgLSBJRCBmaWx0ZXIgdmFsdWUgKGZ1bGwgb3IgcGFydGlhbCBVVUlEKVxuICAgKiBAcmV0dXJucyBTUUwgY29uZGl0aW9uIG9yIG51bGwgaWYgbm8gSUQgZmlsdGVyXG4gICAqL1xuICBwcm90ZWN0ZWQgYnVpbGRJZEZpbHRlcihpZDogdW5rbm93bik6IFNRTCB8IG51bGwge1xuICAgIHJldHVybiBidWlsZElkQ29uZGl0aW9uKHRoaXMuc2NoZW1hLmlkLCBpZCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYm9vbGVhbiBmaWVsZCBjb25kaXRpb25zIChpc0RlZmF1bHQsIGlzQWN0aXZlKVxuICAgKlxuICAgKiBAcGFyYW0gZmlsdGVyIC0gRmlsdGVyIGNyaXRlcmlhXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIFNRTCBjb25kaXRpb25zIGZvciBib29sZWFuIGZpZWxkc1xuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkQm9vbGVhbkZpbHRlcnMoZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+KTogU1FMW10ge1xuICAgIHJldHVybiBidWlsZEJvb2xlYW5Db25kaXRpb25zKHRoaXMuc2NoZW1hLCBmaWx0ZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFsbCBjb21tb24gY29uZGl0aW9ucyAoYWNjZXNzIGNvbnRyb2wgKyBJRCArIGJvb2xlYW5zKVxuICAgKlxuICAgKiBUaGlzIGNvbWJpbmVzIGFsbCB0aGUgZ2VuZXJpYyBmaWx0ZXJzIHRoYXQgYXBwbHkgdG8gYW55IGFjY2Vzcy1jb250cm9sbGVkIGVudGl0eS5cbiAgICogU3ViY2xhc3NlcyBzaG91bGQgY2FsbCB0aGlzIGFuZCBhZGQgZW50aXR5LXNwZWNpZmljIGNvbmRpdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIGZhbGxzIGJhY2sgdG8gc3lzdGVtLXB1YmxpYy1vbmx5KVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9uc1xuICAgKi9cbiAgcHVibGljIGJ1aWxkQ29tbW9uQ29uZGl0aW9ucyhmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuXG4gICAgLy8gQWNjZXNzIGNvbnRyb2wgKG11bHRpLXRlbmFudCkg4oCUIGhhbmRsZXMgdmlzaWJpbGl0eSBpbnRlcm5hbGx5XG4gICAgY29uZGl0aW9ucy5wdXNoKC4uLnRoaXMuYnVpbGRBY2Nlc3NDb250cm9sKGZpbHRlciwgb3JnSWQsIHBhcmVudE9yZ0lkKSk7XG5cbiAgICAvLyBJRCBmaWx0ZXIgd2l0aCBwcmVmaXggbWF0Y2hpbmdcbiAgICBjb25zdCBpZENvbmRpdGlvbiA9IHRoaXMuYnVpbGRJZEZpbHRlcihmaWx0ZXIuaWQpO1xuICAgIGlmIChpZENvbmRpdGlvbikgY29uZGl0aW9ucy5wdXNoKGlkQ29uZGl0aW9uKTtcblxuICAgIC8vIEJvb2xlYW4gZmlsdGVyc1xuICAgIGNvbmRpdGlvbnMucHVzaCguLi50aGlzLmJ1aWxkQm9vbGVhbkZpbHRlcnMoZmlsdGVyKSk7XG5cbiAgICByZXR1cm4gY29uZGl0aW9ucztcbiAgfVxufVxuIl19
224
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWNvbnRyb2wtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvYWNjZXNzLWNvbnRyb2wtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHeEQsTUFBTSxTQUFTLEdBQUcsaUVBQWlFLENBQUM7QUFFcEY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLEdBQVc7SUFDN0MsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxNQUFpQixFQUFFLE9BQWU7SUFDM0UsTUFBTSxPQUFPLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDM0QsT0FBTyxHQUFHLENBQUEsbURBQW1ELE1BQU0sZ0NBQWdDLEdBQUcsR0FBRyxPQUFPLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDNUgsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEtBQWM7SUFDL0MsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLEtBQUssTUFBTSxDQUFDO0lBQ3ZELE9BQU8sT0FBTyxDQUFDLEtBQUss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Q0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTyxtQkFBbUIsQ0FBQyxNQUF3QjtRQUNwRCxPQUFPLHNCQUFzQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLHFCQUFxQixDQUFDLE1BQXdCLEVBQUUsS0FBYyxFQUFFLFdBQW9CO1FBQ3pGLE1BQU0sVUFBVSxHQUFVLEVBQUUsQ0FBQztRQUU3QixnRUFBZ0U7UUFDaEUsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFFeEUsaUNBQWlDO1FBQ2pDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xELElBQUksV0FBVztZQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFOUMsa0JBQWtCO1FBQ2xCLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUVyRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgU1lTVEVNX09SR19JRCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGFuZCwgZXEsIG5lLCBvciwgc3FsLCBTUUwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgdHlwZSB7IEFueUNvbHVtbiB9IGZyb20gJ2RyaXp6bGUtb3JtL2NvbHVtbic7XG5cbmNvbnN0IEZVTExfVVVJRCA9IC9eWzAtOWEtZl17OH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17MTJ9JC9pO1xuXG4vKipcbiAqIEVzY2FwZSBTUUwgTElLRSB3aWxkY2FyZCBjaGFyYWN0ZXJzIHRvIHByZXZlbnQgd2lsZGNhcmQgaW5qZWN0aW9uLlxuICogUmVwbGFjZXMgYCVgIOKGkiBgXFxcXCVgLCBgX2Ag4oaSIGBcXFxcX2AsIGFuZCBgXFxcXGAg4oaSIGBcXFxcXFxcXGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVMaWtlV2lsZGNhcmRzKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cXFxcL2csICdcXFxcXFxcXCcpLnJlcGxhY2UoLyUvZywgJ1xcXFwlJykucmVwbGFjZSgvXy9nLCAnXFxcXF8nKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIGNvbmRpdGlvbiB0aGF0IGNoZWNrcyBpZiBhIEpTT05CIHRleHQgYXJyYXkgY29sdW1uIGNvbnRhaW5zIGEga2V5d29yZCAoY2FzZS1pbnNlbnNpdGl2ZSkuXG4gKiBVc2VkIGZvciBrZXl3b3Jkcy90YWdzIGZpbHRlcmluZyBvbiBwaXBlbGluZXMsIHBsdWdpbnMsIGFuZCBjb21wbGlhbmNlIHJ1bGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRKc29uYktleXdvcmRDb25kaXRpb24oY29sdW1uOiBBbnlDb2x1bW4sIGtleXdvcmQ6IHN0cmluZyk6IFNRTCB7XG4gIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGtleXdvcmQudG9Mb3dlckNhc2UoKSk7XG4gIHJldHVybiBzcWxgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIGpzb25iX2FycmF5X2VsZW1lbnRzX3RleHQoJHtjb2x1bW59KSBBUyBlbCBXSEVSRSBsb3dlcihlbCkgTElLRSAkeyclJyArIGVzY2FwZWQgKyAnJSd9KWA7XG59XG5cbi8qKlxuICogUGFyc2UgYm9vbGVhbiBmaWx0ZXIgdmFsdWUgZnJvbSBzdHJpbmcgb3IgYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCb29sZWFuRmlsdGVyKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykgcmV0dXJuIHZhbHVlO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuIHZhbHVlID09PSAndHJ1ZSc7XG4gIHJldHVybiBCb29sZWFuKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgc3RyaW5nIGZpbHRlciB2YWx1ZSB0byBsb3dlcmNhc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZ0ZpbHRlcih2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUudG9Mb3dlckNhc2UoKSA6IFN0cmluZyh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhbiBJRCBwcmVkaWNhdGUgd2l0aCBVVUlEIHByZWZpeCBtYXRjaGluZy5cbiAqXG4gKiAtIEZ1bGwgVVVJRCDihpIgZXhhY3QgbWF0Y2hcbiAqIC0gUGFydGlhbCBVVUlEIOKGkiBwcmVmaXggbWF0Y2ggdmlhIGBMSUtFYCAoYSBsaXN0LXNlYXJjaCBhZmZvcmRhbmNlKVxuICogLSBBYnNlbnQg4oaSIGBudWxsYCAobm8gcHJlZGljYXRlKVxuICpcbiAqIFN0YW5kYWxvbmUgc28gZW50aXRpZXMgdGhhdCBET04nVCB1c2Uge0BsaW5rIEFjY2Vzc0NvbnRyb2xRdWVyeUJ1aWxkZXJ9J3NcbiAqIGFjY2VzcyBjb250cm9sIChlLmcuIHBpcGVsaW5lIHRlbXBsYXRlcywgd2hpY2ggY2FycnkgdGhlaXIgb3duIHRocmVlLXJ1bmdcbiAqIHZpc2liaWxpdHkgbGFkZGVyKSBzdGlsbCBzaGFyZSBvbmUgaWQtbWF0Y2hpbmcgaW1wbGVtZW50YXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZElkQ29uZGl0aW9uKGlkQ29sdW1uOiBBbnlDb2x1bW4sIGlkOiB1bmtub3duKTogU1FMIHwgbnVsbCB7XG4gIGlmIChpZCA9PT0gdW5kZWZpbmVkIHx8IGlkID09PSBudWxsKSByZXR1cm4gbnVsbDtcblxuICAvLyBgQmFzZUFjY2Vzc0ZpbHRlci5pZGAgaXMgZGVjbGFyZWQgYHN0cmluZyB8IHN0cmluZ1tdYCwgc28gaG9ub3VyIHRoZSBhcnJheVxuICAvLyBmb3JtOiBtYXRjaCBBTlkgb2YgdGhlIGlkcywgZWFjaCB3aXRoIHRoZSBzYW1lIGV4YWN0LXZzLXByZWZpeCBzZW1hbnRpY3MgYXNcbiAgLy8gYSBzaW5nbGUgdmFsdWUuIGBTdHJpbmcoWydhJywnYiddKWAgd291bGQgb3RoZXJ3aXNlIHByb2R1Y2UgYExJS0UgJ2EsYiUnYFxuICAvLyBhbmQgc2lsZW50bHkgcmV0dXJuIHplcm8gcm93cyDigJQgYSB0cmFwIGZvciB0aGUgZmlyc3QgY2FsbGVyIHRvIHBhc3Mgb25lLlxuICBpZiAoQXJyYXkuaXNBcnJheShpZCkpIHtcbiAgICBjb25zdCBwYXJ0cyA9IGlkXG4gICAgICAubWFwKChvbmUpID0+IGJ1aWxkSWRDb25kaXRpb24oaWRDb2x1bW4sIG9uZSkpXG4gICAgICAuZmlsdGVyKChjKTogYyBpcyBTUUwgPT4gYyAhPT0gbnVsbCk7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHBhcnRzLmxlbmd0aCA9PT0gMSA/IHBhcnRzWzBdIDogKG9yKC4uLnBhcnRzKSBhcyBTUUwpO1xuICB9XG5cbiAgY29uc3QgaWRTdHJpbmcgPSBTdHJpbmcoaWQpLnRvTG93ZXJDYXNlKCk7XG4gIGlmIChGVUxMX1VVSUQudGVzdChpZFN0cmluZykpIHtcbiAgICByZXR1cm4gZXEoaWRDb2x1bW4sIGlkU3RyaW5nKTtcbiAgfVxuICAvLyBFc2NhcGUgU1FMIExJS0Ugd2lsZGNhcmRzIHRvIHByZXZlbnQgd2lsZGNhcmQgaW5qZWN0aW9uXG4gIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGlkU3RyaW5nKTtcbiAgcmV0dXJuIHNxbGAke2lkQ29sdW1ufTo6dGV4dCBMSUtFICR7ZXNjYXBlZCArICclJ30gRVNDQVBFICdcXFxcJ2A7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIGBpc0RlZmF1bHRgIC8gYGlzQWN0aXZlYCBwcmVkaWNhdGVzIHNoYXJlZCBieSBldmVyeSBjYXRhbG9nIGVudGl0eS5cbiAqIGBpc0FjdGl2ZWAgZGVmYXVsdHMgdG8gdHJ1ZSBzbyBzb2Z0LWRlbGV0ZWQgcm93cyBzdGF5IG91dCBvZiBub3JtYWwgcmVhZHMuXG4gKiBTdGFuZGFsb25lIGZvciB0aGUgc2FtZSByZWFzb24gYXMge0BsaW5rIGJ1aWxkSWRDb25kaXRpb259LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRCb29sZWFuQ29uZGl0aW9ucyhcbiAgY29sdW1uczogeyBpc0RlZmF1bHQ6IEFueUNvbHVtbjsgaXNBY3RpdmU6IEFueUNvbHVtbiB9LFxuICBmaWx0ZXI6IHsgaXNEZWZhdWx0PzogdW5rbm93bjsgaXNBY3RpdmU/OiB1bmtub3duIH0sXG4pOiBTUUxbXSB7XG4gIGNvbnN0IGNvbmRpdGlvbnM6IFNRTFtdID0gW107XG5cbiAgaWYgKGZpbHRlci5pc0RlZmF1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbmRpdGlvbnMucHVzaChlcShjb2x1bW5zLmlzRGVmYXVsdCwgcGFyc2VCb29sZWFuRmlsdGVyKGZpbHRlci5pc0RlZmF1bHQpKSk7XG4gIH1cblxuICBpZiAoZmlsdGVyLmlzQWN0aXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25kaXRpb25zLnB1c2goZXEoY29sdW1ucy5pc0FjdGl2ZSwgcGFyc2VCb29sZWFuRmlsdGVyKGZpbHRlci5pc0FjdGl2ZSkpKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBEZWZhdWx0IHRvIGFjdGl2ZSByZWNvcmRzIG9ubHkgdG8gZXhjbHVkZSBzb2Z0LWRlbGV0ZWQgZW50aXRpZXNcbiAgICBjb25kaXRpb25zLnB1c2goZXEoY29sdW1ucy5pc0FjdGl2ZSwgdHJ1ZSkpO1xuICB9XG5cbiAgcmV0dXJuIGNvbmRpdGlvbnM7XG59XG5cbi8qKlxuICogU2NoZW1hIHRhYmxlIGludGVyZmFjZSBmb3IgYWNjZXNzIGNvbnRyb2wgcXVlcmllcy4gRXZlcnkgY2F0YWxvZyBlbnRpdHlcbiAqIGNhcnJpZXMgdGhlIHNhbWUgZml2ZSBjb2x1bW5zLCB3aGljaCBpcyB3aGF0IGxldHMgT05FIHByZWRpY2F0ZSBzZXJ2ZVxuICogcGlwZWxpbmVzLCBwbHVnaW5zIGFuZCB0ZW1wbGF0ZXMgYWxpa2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNjZXNzQ29udHJvbFNjaGVtYSB7XG4gIGlkOiBBbnlDb2x1bW47XG4gIG9yZ0lkOiBBbnlDb2x1bW47XG4gIC8qKiBUaHJlZS1ydW5nIHNoYXJpbmcgbGFkZGVyIOKAlCBzZWUgYXBpLWNvcmUncyBgVmlzaWJpbGl0eWAuICovXG4gIHZpc2liaWxpdHk6IEFueUNvbHVtbjtcbiAgLyoqIEF1dGhvci4gT3ducyB0aGUgYHByaXZhdGVgIHJ1bmcuICovXG4gIGNyZWF0ZWRCeTogQW55Q29sdW1uO1xuICBpc0RlZmF1bHQ6IEFueUNvbHVtbjtcbiAgaXNBY3RpdmU6IEFueUNvbHVtbjtcbn1cblxuLyoqXG4gKiBCYXNlIGZpbHRlciBpbnRlcmZhY2Ugd2l0aCBjb21tb24gYWNjZXNzIGNvbnRyb2wgZmllbGRzLlxuICpcbiAqIGB2aWV3ZXJVc2VySWRgIC8gYHZpZXdlcklzU3VwZXJBZG1pbmAgYXJlIFNFUlZFUi1TRVQgKHN0YW1wZWQgZnJvbSB0aGUgcmVxdWVzdCdzXG4gKiB0ZW5hbnQgY29udGV4dCBieSBgd2l0aFZpZXdlckNvbnRleHRgKSwgbmV2ZXIgY2xpZW50LXN1cHBsaWVkIOKAlCBzZWVcbiAqIGB2aWV3ZXItY29udGV4dC50c2AgZm9yIHdoeSB0aGUgdGVuYW50IGNvbnRleHQgaXMgdGhlIGNoYW5uZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZUFjY2Vzc0ZpbHRlciB7XG4gIGlkPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIHZpc2liaWxpdHk/OiBzdHJpbmc7XG4gIGlzRGVmYXVsdD86IGJvb2xlYW4gfCBzdHJpbmc7XG4gIGlzQWN0aXZlPzogYm9vbGVhbiB8IHN0cmluZztcbiAgdmlld2VyVXNlcklkPzogc3RyaW5nO1xuICB2aWV3ZXJJc1N1cGVyQWRtaW4/OiBib29sZWFuO1xufVxuXG4vKiogRmFpbC1jbG9zZWQgcHJlZGljYXRlOiBtYXRjaGVzIG5vIHJvd3MuICovXG5jb25zdCBOT19ST1dTOiBTUUwgPSBzcWxgZmFsc2VgO1xuXG4vKiogUGVyLWVudGl0eSB0dW5pbmcgb2Yge0BsaW5rIEFjY2Vzc0NvbnRyb2xRdWVyeUJ1aWxkZXJ9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBBY2Nlc3NDb250cm9sT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBTWVNURU0gb3JnJ3MgYHB1YmxpY2AgcnVuZyByZWFjaGVzIGNhbGxlcnMgaW4gb3RoZXIgb3JncyAoYW5kXG4gICAqIGFub255bW91cyBjYWxsZXJzKS4gRGVmYXVsdCB0cnVlOiB0aGUgc3lzdGVtIG9yZydzIHNhbXBsZSBwaXBlbGluZXMsXG4gICAqIHRlbXBsYXRlcyBhbmQgZGFzaGJvYXJkcyBhcmUgdmlzaWJsZSBmcm9tIGV2ZXJ5IG9yZy4gUGx1Z2lucyBzZXQgaXQgZmFsc2U6XG4gICAqIHNpbmNlIHRoZSBwbHVnaW4gZWNvc3lzdGVtIHRoZSBPZmZpY2lhbCBjYXRhbG9nIHJlYWNoZXNcbiAgICogb3RoZXIgb3JncyBvbmx5IGFzIExJU1RJTkdTIHJlc29sdmVkIHRocm91Z2ggaW5zdGFsbHMsIG5ldmVyIHRocm91Z2hcbiAgICogYHZpc2liaWxpdHkgPSAncHVibGljJ2Agb24gYSBgcGx1Z2luc2Agcm93LlxuICAgKi9cbiAgc3lzdGVtQ2F0YWxvZz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogR2VuZXJpYyBhY2Nlc3MgY29udHJvbCBxdWVyeSBidWlsZGVyIGZvciBtdWx0aS10ZW5hbnQgZW50aXRpZXMuXG4gKlxuICogQ29uc29saWRhdGVzIGR1cGxpY2F0ZSBhY2Nlc3MgY29udHJvbCBsb2dpYyBzaGFyZWQgYWNyb3NzIHBpcGVsaW5lIGFuZCBwbHVnaW4gcXVlcmllcy5cbiAqIEhhbmRsZXM6XG4gKiAtIE11bHRpLXRlbmFudCBhY2Nlc3MgY29udHJvbCAocHVibGljL3ByaXZhdGUvb3JnLWFuZC1wdWJsaWMpXG4gKiAtIFVVSUQgcHJlZml4IG1hdGNoaW5nIGZvciBJRCBmaWx0ZXJzXG4gKiAtIEJvb2xlYW4gZmllbGQgbm9ybWFsaXphdGlvblxuICpcbiAqIEB0eXBlUGFyYW0gVFNjaGVtYSAtIFNjaGVtYSB0YWJsZSB0eXBlIHdpdGggYWNjZXNzIGNvbnRyb2wgZmllbGRzXG4gKiBAdHlwZVBhcmFtIFRGaWx0ZXIgLSBGaWx0ZXIgdHlwZSBleHRlbmRpbmcgQmFzZUFjY2Vzc0ZpbHRlclxuICovXG5leHBvcnQgY2xhc3MgQWNjZXNzQ29udHJvbFF1ZXJ5QnVpbGRlcjxcbiAgVFNjaGVtYSBleHRlbmRzIEFjY2Vzc0NvbnRyb2xTY2hlbWEsXG4gIFRGaWx0ZXIgZXh0ZW5kcyBCYXNlQWNjZXNzRmlsdGVyLFxuPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgc2NoZW1hOiBUU2NoZW1hLFxuICAgIHByaXZhdGUgb3B0aW9uczogQWNjZXNzQ29udHJvbE9wdGlvbnMgPSB7fSxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgY2FsbGVyJ3MgdmlzaWJsZSBzbGljZSBvZiBhIGNhdGFsb2csIGZyb20gdGhlIHRocmVlLXJ1bmdcbiAgICogYHZpc2liaWxpdHlgIGxhZGRlciBzaGFyZWQgYnkgZXZlcnkgY2F0YWxvZyBlbnRpdHkuXG4gICAqXG4gICAqIEVmZmVjdGl2ZSByZWFkIHNldCBmb3IgYSBjYWxsZXIgaW4gb3JnIGBPYCBhcyB1c2VyIGBWYCB3aG9zZSBwYXJlbnQgb3JnIGlzIGBQYDpcbiAgICpcbiAgICogICAob3JnX2lkID0gTyBBTkQgKHZpc2liaWxpdHkgPD4gJ3ByaXZhdGUnIE9SIGNyZWF0ZWRfYnkgPSBWKSlcbiAgICogICBPUiAodmlzaWJpbGl0eSA9ICdwdWJsaWMnIEFORCAob3JnX2lkID0gJ3N5c3RlbScgT1Igb3JnX2lkID0gUCkpXG4gICAqXG4gICAqIGkuZS4geW91ciBvd24gb3JnJ3Mgc2hhcmVkIHJ1bmdzIHBsdXMgeW91ciBvd24gZHJhZnRzLCB3aWRlbmVkIGJ5IHRoZSBzeXN0ZW1cbiAgICogb3JnJ3MgcHVibGljIGNhdGFsb2cgKHRoZSBzdGFuZGluZyBcInN5c3RlbS1vcmcgY29udGVudCBpcyB2aXNpYmxlIGZyb20gZXZlcnlcbiAgICogb3JnXCIgcnVsZSkgYW5kIOKAlCBmb3IgYSB0ZWFtIOKAlCBpdHMgcGFyZW50J3MgcHVibGljIHJvd3MuIFRoZSBgcHVibGljYC1vbmx5XG4gICAqIHJlc3RyaWN0aW9uIGFwcGxpZXMgc29sZWx5IHRvIHRob3NlIE9USEVSIG9yZ3MnIHJvd3M7IHdpdGhpbiB5b3VyIG93biBvcmcgeW91XG4gICAqIGFsd2F5cyBzZWUgZXZlcnl0aGluZyB5b3UgYXJlIGVudGl0bGVkIHRvLCBvciBhIGZyZXNobHktY3JlYXRlZCBwcml2YXRlIHJvd1xuICAgKiB3b3VsZCB2YW5pc2ggZnJvbSBpdHMgb3duIGF1dGhvcidzIGxpc3RpbmcuXG4gICAqXG4gICAqIEFuIGVudGl0eSBjYW4gZHJvcCB0aGUgc3lzdGVtLW9yZyBicmFuY2ggd2l0aCBgc3lzdGVtQ2F0YWxvZzogZmFsc2VgXG4gICAqICh7QGxpbmsgQWNjZXNzQ29udHJvbE9wdGlvbnN9KTogcGx1Z2lucyBkbywgc28gYSBzeXN0ZW0tb3JnIHBsdWdpbiByZWFjaGVzXG4gICAqIG90aGVyIG9yZ3Mgb25seSBhcyBhbiBPZmZpY2lhbCBsaXN0aW5nLlxuICAgKlxuICAgKiBBbiBleHBsaWNpdCBgdmlzaWJpbGl0eWAgZmlsdGVyIE5BUlJPV1Mgd2l0aGluIHRoYXQgc2V0LCBuZXZlciB3aWRlbnMgaXQg4oCUXG4gICAqIHNvIGA/dmlzaWJpbGl0eT1wdWJsaWNgIHN0aWxsIHN1cmZhY2VzIHRoZSBzeXN0ZW0tb3JnIGNhdGFsb2cuXG4gICAqXG4gICAqIEZhaWxzIENMT1NFRCBvbiBib3RoIGF4ZXM6IG5vIGBvcmdJZGAgKGFub255bW91cykg4oeSIHN5c3RlbS1vcmcgcHVibGljIG9ubHk7XG4gICAqIG5vIGB2aWV3ZXJVc2VySWRgIOKHkiB0aGUgcHJpdmF0ZSBydW5nIG1hdGNoZXMgbm90aGluZyByYXRoZXIgdGhhbiBldmVyeXRoaW5nLlxuICAgKiBgdmlld2VySXNTdXBlckFkbWluYCBsaWZ0cyB0aGUgcHJpdmF0ZSBydW5nIG9ubHkg4oCUIGEgcGxhdGZvcm0gb3BlcmF0b3JcbiAgICogYWRtaW5pc3RlcnMgdGhlIHdob2xlIGNhdGFsb2cuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwpXG4gICAqIEBwYXJhbSBwYXJlbnRPcmdJZCAtIFBhcmVudCBvcmcgSUQgd2hlbiB0aGUgY2FsbGVyIGlzIGEgdGVhbSAob3B0aW9uYWwpXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIFNRTCBjb25kaXRpb25zIGZvciBhY2Nlc3MgY29udHJvbFxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuICAgIGNvbnN0IHJlcXVlc3RlZCA9IGZpbHRlci52aXNpYmlsaXR5O1xuXG4gICAgY29uc3Qgc3lzdGVtQ2F0YWxvZyA9IHRoaXMub3B0aW9ucy5zeXN0ZW1DYXRhbG9nICE9PSBmYWxzZTtcblxuICAgIGlmICghb3JnSWQpIHtcbiAgICAgIC8vIE5vIG9yZyBjb250ZXh0IOKAlCBvbmx5IHRoZSBzeXN0ZW0gb3JnJ3MgcHVibGljIGNhdGFsb2cgKG5vdGhpbmcgYXQgYWxsXG4gICAgICAvLyBmb3IgYW4gZW50aXR5IHdpdGhvdXQgb25lKS5cbiAgICAgIGlmICghc3lzdGVtQ2F0YWxvZykgcmV0dXJuIFtOT19ST1dTXTtcbiAgICAgIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS5vcmdJZCwgU1lTVEVNX09SR19JRCkpO1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLnZpc2liaWxpdHksICdwdWJsaWMnKSk7XG4gICAgICAvLyBBbiBhbm9ueW1vdXMgY2FsbGVyIGFza2luZyBmb3IgYSBuYXJyb3dlciBydW5nIGdldHMgbm90aGluZywgcmF0aGVyIHRoYW5cbiAgICAgIC8vIGhhdmluZyB0aGUgbmFycm93aW5nIHNpbGVudGx5IGlnbm9yZWQuXG4gICAgICBpZiAocmVxdWVzdGVkICE9PSB1bmRlZmluZWQgJiYgcmVxdWVzdGVkICE9PSAncHVibGljJykgY29uZGl0aW9ucy5wdXNoKE5PX1JPV1MpO1xuICAgICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZE9yZ0lkID0gb3JnSWQudG9Mb3dlckNhc2UoKTtcblxuICAgIC8vIE93bi1vcmcgcm93czogZXZlcnl0aGluZyBFWENFUFQgb3RoZXIgcGVvcGxlJ3MgcHJpdmF0ZSBkcmFmdHMuXG4gICAgY29uc3Qgb3duRHJhZnRzT25seSA9IGZpbHRlci52aWV3ZXJVc2VySWQgPyBlcSh0aGlzLnNjaGVtYS5jcmVhdGVkQnksIGZpbHRlci52aWV3ZXJVc2VySWQpIDogTk9fUk9XUztcbiAgICBjb25zdCBvd25PcmcgPSBmaWx0ZXIudmlld2VySXNTdXBlckFkbWluXG4gICAgICA/IGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBub3JtYWxpemVkT3JnSWQpXG4gICAgICA6IGFuZChlcSh0aGlzLnNjaGVtYS5vcmdJZCwgbm9ybWFsaXplZE9yZ0lkKSwgb3IobmUodGhpcy5zY2hlbWEudmlzaWJpbGl0eSwgJ3ByaXZhdGUnKSwgb3duRHJhZnRzT25seSkhKSE7XG5cbiAgICAvLyBSb3dzIGZyb20gT1RIRVIgb3JncyBhcmUgb25seSBldmVyIHZpc2libGUgYXQgdGhlIGBwdWJsaWNgIHJ1bmcuXG4gICAgY29uc3Qgb3RoZXJPcmdTY29wZXM6IFNRTFtdID0gW107XG4gICAgaWYgKHN5c3RlbUNhdGFsb2cpIG90aGVyT3JnU2NvcGVzLnB1c2goZXEodGhpcy5zY2hlbWEub3JnSWQsIFNZU1RFTV9PUkdfSUQpKTtcbiAgICBpZiAocGFyZW50T3JnSWQpIG90aGVyT3JnU2NvcGVzLnB1c2goZXEodGhpcy5zY2hlbWEub3JnSWQsIHBhcmVudE9yZ0lkLnRvTG93ZXJDYXNlKCkpKTtcbiAgICBjb25kaXRpb25zLnB1c2gob3RoZXJPcmdTY29wZXMubGVuZ3RoID4gMFxuICAgICAgPyBvcihvd25PcmcsIGFuZChlcSh0aGlzLnNjaGVtYS52aXNpYmlsaXR5LCAncHVibGljJyksIG9yKC4uLm90aGVyT3JnU2NvcGVzKSEpISkhXG4gICAgICA6IG93bk9yZyk7XG5cbiAgICBpZiAocmVxdWVzdGVkICE9PSB1bmRlZmluZWQpIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS52aXNpYmlsaXR5LCByZXF1ZXN0ZWQpKTtcblxuICAgIHJldHVybiBjb25kaXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIElEIGZpbHRlciB3aXRoIFVVSUQgcHJlZml4IG1hdGNoaW5nIHN1cHBvcnRcbiAgICpcbiAgICogLSBGdWxsIFVVSUQ6IEV4YWN0IG1hdGNoXG4gICAqIC0gUGFydGlhbCBVVUlEOiBQcmVmaXggbWF0Y2ggdXNpbmcgU1FMIExJS0VcbiAgICpcbiAgICogQHBhcmFtIGlkIC0gSUQgZmlsdGVyIHZhbHVlIChmdWxsIG9yIHBhcnRpYWwgVVVJRClcbiAgICogQHJldHVybnMgU1FMIGNvbmRpdGlvbiBvciBudWxsIGlmIG5vIElEIGZpbHRlclxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkSWRGaWx0ZXIoaWQ6IHVua25vd24pOiBTUUwgfCBudWxsIHtcbiAgICByZXR1cm4gYnVpbGRJZENvbmRpdGlvbih0aGlzLnNjaGVtYS5pZCwgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGJvb2xlYW4gZmllbGQgY29uZGl0aW9ucyAoaXNEZWZhdWx0LCBpc0FjdGl2ZSlcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9ucyBmb3IgYm9vbGVhbiBmaWVsZHNcbiAgICovXG4gIHByb3RlY3RlZCBidWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcjogUGFydGlhbDxURmlsdGVyPik6IFNRTFtdIHtcbiAgICByZXR1cm4gYnVpbGRCb29sZWFuQ29uZGl0aW9ucyh0aGlzLnNjaGVtYSwgZmlsdGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhbGwgY29tbW9uIGNvbmRpdGlvbnMgKGFjY2VzcyBjb250cm9sICsgSUQgKyBib29sZWFucylcbiAgICpcbiAgICogVGhpcyBjb21iaW5lcyBhbGwgdGhlIGdlbmVyaWMgZmlsdGVycyB0aGF0IGFwcGx5IHRvIGFueSBhY2Nlc3MtY29udHJvbGxlZCBlbnRpdHkuXG4gICAqIFN1YmNsYXNzZXMgc2hvdWxkIGNhbGwgdGhpcyBhbmQgYWRkIGVudGl0eS1zcGVjaWZpYyBjb25kaXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsdGVyIC0gRmlsdGVyIGNyaXRlcmlhXG4gICAqIEBwYXJhbSBvcmdJZCAtIFVzZXIncyBvcmdhbml6YXRpb24gSUQgKG9wdGlvbmFsIOKAlCBmYWxscyBiYWNrIHRvIHN5c3RlbS1wdWJsaWMtb25seSlcbiAgICogQHJldHVybnMgQXJyYXkgb2YgU1FMIGNvbmRpdGlvbnNcbiAgICovXG4gIHB1YmxpYyBidWlsZENvbW1vbkNvbmRpdGlvbnMoZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBTUUxbXSB7XG4gICAgY29uc3QgY29uZGl0aW9uczogU1FMW10gPSBbXTtcblxuICAgIC8vIEFjY2VzcyBjb250cm9sIChtdWx0aS10ZW5hbnQpIOKAlCBoYW5kbGVzIHZpc2liaWxpdHkgaW50ZXJuYWxseVxuICAgIGNvbmRpdGlvbnMucHVzaCguLi50aGlzLmJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCkpO1xuXG4gICAgLy8gSUQgZmlsdGVyIHdpdGggcHJlZml4IG1hdGNoaW5nXG4gICAgY29uc3QgaWRDb25kaXRpb24gPSB0aGlzLmJ1aWxkSWRGaWx0ZXIoZmlsdGVyLmlkKTtcbiAgICBpZiAoaWRDb25kaXRpb24pIGNvbmRpdGlvbnMucHVzaChpZENvbmRpdGlvbik7XG5cbiAgICAvLyBCb29sZWFuIGZpbHRlcnNcbiAgICBjb25kaXRpb25zLnB1c2goLi4udGhpcy5idWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcikpO1xuXG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cbn1cbiJdfQ==
@@ -66,15 +66,47 @@ export interface PaginatedResult<T> {
66
66
  * soft-delete paths (e.g. platform's hand-rolled dashboard/alert services)
67
67
  * stamp `purge_after` with the SAME window the CrudService entities use. */
68
68
  export declare function softDeleteRetentionMs(): number;
69
+ /**
70
+ * Abstract CRUD service with multi-tenant access control and pagination.
71
+ *
72
+ * Subclasses bind to a specific Drizzle table by implementing `schema`,
73
+ * `buildConditions`, `getSortColumn`, and the org/project-column accessors.
74
+ *
75
+ * @typeParam TEntity - Entity type extending BaseEntity
76
+ * @typeParam TFilter - Filter type for query parameters
77
+ * @typeParam TInsert - Insert DTO type
78
+ * @typeParam TUpdate - Update DTO type
79
+ *
80
+ * **A note on the type casts.** Drizzle's row types are inferred from
81
+ * `pgTable(...)` and don't generically narrow through the abstract `schema`
82
+ * getter, so the base class casts query results to `TEntity` and back. The
83
+ * cast is *not* a runtime safety guarantee — it relies on each subclass
84
+ * passing the matching entity type. Org-scoping is enforced by every
85
+ * subclass's `buildConditions` injecting `WHERE org_id = $1`; this class
86
+ * does not add that filter itself.
87
+ *
88
+ * **Error policy.** Errors propagate up to the route-level handler
89
+ * (`withRoute`); no catch-and-swallow here.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * class PipelineService extends CrudService<Pipeline, PipelineFilter, PipelineInsert, PipelineUpdate> {
94
+ * protected get schema() { return schema.pipeline; }
95
+ * protected buildConditions(filter, orgId) { return buildPipelineConditions(filter, orgId); }
96
+ * protected getSortColumn(sortBy) { return Object.hasOwn(sortColumnMap, sortBy) ? sortColumnMap[sortBy] : null; }
97
+ * protected getProjectColumn() { return schema.pipeline.project; }
98
+ * protected getOrgColumn() { return schema.pipeline.orgId; }
99
+ * }
100
+ * ```
101
+ */
69
102
  export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, TInsert, TUpdate> {
70
103
  /** Drizzle schema table for this entity */
71
104
  protected abstract get schema(): PgTable;
72
105
  /**
73
106
  * Typed column view of {@link schema}. `PgTable` exposes no static columns, so
74
- * the base class previously reached for `(this.schema as any).id` etc. at each
75
- * use; centralize that single unavoidable cast here so callers get structured,
76
- * typed access instead. `visibility` is optional (not every entity has it)
77
- * and the index signature covers dynamic sparse-fieldset column lookup.
107
+ * this is the single unavoidable cast for column access. `visibility` is
108
+ * optional (not every entity has it) and the index signature covers dynamic
109
+ * sparse-fieldset column lookup.
78
110
  */
79
111
  private get cols();
80
112
  /**
@@ -102,6 +134,16 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
102
134
  * hierarchy) — same opt-in semantics as `find`/`findPaginated`. Omitted by the
103
135
  * write path (`writeConditions`), which must stay own-org scoped. */
104
136
  private idConditions;
137
+ /**
138
+ * Excludes soft-deleted tombstones on entities with a `deletedAt` column. The
139
+ * by-id filter deliberately skips the `isActive` default (a deactivated row is
140
+ * still readable by id), so without this a tombstone would be readable and —
141
+ * through `update` — half-revivable (`isActive` flipped back while
142
+ * `deletedAt`/`purgeAfter` stay set, so the sweep later purges a row the UI
143
+ * shows as live). Tombstones are reached only via the dedicated
144
+ * restore/purge/findDeleted paths.
145
+ */
146
+ private notTombstoned;
105
147
  /**
106
148
  * Conditions for a MUTATION (update/delete) of a single entity.
107
149
  *
@@ -117,6 +159,25 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
117
159
  * `schema` is typed `PgTable` (no static `.id`), so cast — same pattern the
118
160
  * sort/default helpers use for column access. */
119
161
  private exactIdCondition;
162
+ /** The actor stamped on a write: the caller, or the system actor for background work. */
163
+ private actor;
164
+ /**
165
+ * The one cast point for `.set()` / `.values()` / `.select()` shapes. The base class writes
166
+ * the shared columns (`updatedBy`, `deletedAt`, …) through the abstract
167
+ * `PgTable`, whose insert/update types can't prove those columns exist.
168
+ */
169
+ private row;
170
+ /** Run a lifecycle hook best-effort: a failure is logged, never thrown. */
171
+ private runHook;
172
+ /** The columns a soft-delete stamps, including the purge deadline. */
173
+ private tombstoneSet;
174
+ /**
175
+ * Hard-delete up to `limit` rows matching `conditions` in one transaction:
176
+ * dependents are torn down first by `onBeforePurge` in the SAME tx (a
177
+ * FK-blocking child can't strand the parent; a throw aborts the batch), then
178
+ * `onAfterPurge` handles external side-effects best-effort. Returns the ids.
179
+ */
180
+ private purgeWhere;
120
181
  /** Called after a new entity is created */
121
182
  protected onAfterCreate(_entity: TEntity, _userId: string): Promise<void>;
122
183
  /** Called after an entity is updated */
@@ -171,10 +232,18 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
171
232
  * @param orgId - User's organization ID (optional — omit for anonymous/system-public-only access)
172
233
  */
173
234
  find(filter: Partial<TFilter>, orgId?: string, parentOrgId?: string): Promise<TEntity[]>;
235
+ /**
236
+ * ORDER BY for {@link findFirst}, so "take one" is deterministic rather than
237
+ * whatever row the planner meets first: the default row, then the newest,
238
+ * then id as the final tiebreak. Services override it to rank by their own
239
+ * notion of "best match" (plugins: own org first, then semver).
240
+ */
241
+ protected findFirstOrderBy(_filter: Partial<TFilter>, _orgId?: string, _parentOrgId?: string): SQL[];
174
242
  /**
175
243
  * Find the FIRST entity matching `filter` — a bounded (`LIMIT 1`) variant of
176
244
  * `find` for the "match by filter, take one" read paths (e.g. `GET /find`), so
177
- * they don't `SELECT` every matching org row just to return `[0]`.
245
+ * they don't `SELECT` every matching org row just to return `[0]`. Ranked by
246
+ * {@link findFirstOrderBy}.
178
247
  */
179
248
  findFirst(filter: Partial<TFilter>, orgId?: string, parentOrgId?: string): Promise<TEntity | null>;
180
249
  /**
@@ -218,9 +287,8 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
218
287
  */
219
288
  findById(id: string, orgId?: string, parentOrgId?: string): Promise<TEntity | null>;
220
289
  /**
221
- * Defense-in-depth tenant stamp. RLS is in owner-bypass mode, so the app layer
222
- * is the only tenant gate on writes. A NON-sysadmin caller may only write into
223
- * its OWN org, so pin the row to the trusted tenant-context org.
290
+ * Defense-in-depth tenant stamp alongside RLS: a NON-sysadmin caller may only
291
+ * write into its OWN org, so pin the row to the trusted tenant-context org.
224
292
  *
225
293
  * The stamp fires whenever the payload's `orgId` differs from the context org —
226
294
  * which covers BOTH a forged/mismatched `data.orgId` AND an ABSENT one. The
@@ -271,15 +339,8 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
271
339
  bulkDelete(ids: string[], orgId: string, userId: string,
272
340
  /**
273
341
  * The caller's authority on the three-rung `visibility` ladder. Omit (or
274
- * pass `isSystemAdmin: true`) for an unrestricted delete.
275
- *
276
- * This used to be a `restrictToPrivate` boolean that narrowed to
277
- * `visibility = 'private'`. That encoded the OLD two-state model: since
278
- * `resolveVisibility` defaults pipelines and plugins to `org`, and
279
- * single-row delete allows an `org` row with plain `:write`, bulk delete
280
- * 403'd the normal case — an org admin could delete a pipeline one at a
281
- * time but not in bulk. The rungs enforced here mirror
282
- * `requireVisibilityWriteAccess` exactly:
342
+ * pass `isSystemAdmin: true`) for an unrestricted delete. The rungs mirror
343
+ * `requireVisibilityWriteAccess` exactly, so bulk and single-row delete agree:
283
344
  * - `private` → author only (`createdBy === userId`)
284
345
  * - `org` → any member of the org (plain `:write`)
285
346
  * - `public` → requires the entity's publish permission
@@ -288,19 +349,6 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
288
349
  isSystemAdmin: boolean;
289
350
  canPublish: boolean;
290
351
  }): Promise<TEntity[]>;
291
- /**
292
- * Restore a soft-deleted (tombstoned) entity: clear `isActive`/`deletedAt`/
293
- * `deletedBy`/`purgeAfter` so it reappears in normal reads.
294
- *
295
- * Matches ONLY a genuine tombstone — `isActive = false` AND `deletedAt IS NOT
296
- * NULL` — so a merely *deactivated* row (isActive=false, no deletedAt) is never
297
- * silently "restored". Pinned to the caller's own org (orgId-less sysadmin
298
- * context spans orgs, matching delete/update). Returns null when there is no
299
- * such tombstone (already active, purged, or unknown) so the route can 404.
300
- * A unique-key collision (a live row already holds the key) surfaces as the
301
- * driver's unique-violation for the route to map to 409 — in practice the
302
- * tombstone IS the key holder, so this is defensive.
303
- */
304
352
  /** Conditions matching a GENUINE tombstone (`isActive=false` AND `deletedAt IS
305
353
  * NOT NULL`), optionally pinned to `id` and/or `orgId`. Single source of truth
306
354
  * for restore/findDeletedById/findDeleted so the "what is a tombstone" rule
@@ -309,12 +357,9 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
309
357
  /**
310
358
  * The `private` rung, for TOMBSTONE reads and restore.
311
359
  *
312
- * Deleting a row does not declassify it. These conditions carried only
313
- * `isActive=false + deletedAt IS NOT NULL + org_id = O`, so the "recently
314
- * deleted" list handed every member of an org the tombstones of everyone
315
- * else's PRIVATE pipelines, plugins and templates — rows the very same member
316
- * could not read one second before they were deleted. `restore` shared the
317
- * clause, so they could also bring one back.
360
+ * Deleting a row does not declassify it: without this, the "recently
361
+ * deleted" list (and restore) would expose other members' PRIVATE rows that
362
+ * the same viewer could not read before they were deleted.
318
363
  *
319
364
  * Mirrors the live read ladder (`visibility <> 'private' OR created_by = V`)
320
365
  * rather than the delete ladder: this gates who may SEE a tombstone, and a
@@ -327,6 +372,19 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
327
372
  * it runs org-wide under a sysadmin scope and must reach every tombstone.
328
373
  */
329
374
  private tombstoneVisibilityConditions;
375
+ /**
376
+ * Restore a soft-deleted (tombstoned) entity: clear `isActive`/`deletedAt`/
377
+ * `deletedBy`/`purgeAfter` so it reappears in normal reads.
378
+ *
379
+ * Matches ONLY a genuine tombstone — `isActive = false` AND `deletedAt IS NOT
380
+ * NULL` — so a merely *deactivated* row (isActive=false, no deletedAt) is never
381
+ * silently "restored". Pinned to the caller's own org (orgId-less sysadmin
382
+ * context spans orgs, matching delete/update). Returns null when there is no
383
+ * such tombstone (already active, purged, or unknown) so the route can 404.
384
+ * A unique-key collision (a live row already holds the key) surfaces as the
385
+ * driver's unique-violation for the route to map to 409 — in practice the
386
+ * tombstone IS the key holder, so this is defensive.
387
+ */
330
388
  restore(id: string, orgId: string, userId: string): Promise<TEntity | null>;
331
389
  /**
332
390
  * Read a soft-deleted entity by id (the inverse of the default `isActive=true`