@pipeline-builder/pipeline-data 3.4.130 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,7 +34,7 @@ Database layer for [Pipeline Builder](https://mwashburn160.github.io/pipeline-bu
34
34
  ### Query builders & filters
35
35
  | Export | Purpose |
36
36
  |---|---|
37
- | `AccessControlQueryBuilder` | Row-level, org-scoped condition builder enforcing tenant isolation and `accessModifier` visibility |
37
+ | `AccessControlQueryBuilder` | Row-level, org-scoped condition builder enforcing tenant isolation and the three-rung `visibility` ladder |
38
38
  | `buildPipelineConditions`, `buildPluginConditions`, `buildMessageConditions`, and the compliance condition builders | Filter-to-SQL translators used by the services |
39
39
  | `PipelineFilter`, `PluginFilter`, `MessageFilter`, the compliance filter types | Typed filter interfaces |
40
40
  | `drizzleRows`, `drizzleCount` | Drizzle result type helpers |
@@ -19,23 +19,58 @@ export declare function parseBooleanFilter(value: unknown): boolean;
19
19
  */
20
20
  export declare function normalizeStringFilter(value: unknown): string;
21
21
  /**
22
- * Schema table interface for access control queries
22
+ * Build an ID predicate with UUID prefix matching.
23
+ *
24
+ * - Full UUID → exact match
25
+ * - Partial UUID → prefix match via `LIKE` (a list-search affordance)
26
+ * - Absent → `null` (no predicate)
27
+ *
28
+ * Standalone so entities that DON'T use {@link AccessControlQueryBuilder}'s
29
+ * access control (e.g. pipeline templates, which carry their own three-rung
30
+ * visibility ladder) still share one id-matching implementation.
31
+ */
32
+ export declare function buildIdCondition(idColumn: AnyColumn, id: unknown): SQL | null;
33
+ /**
34
+ * Build the `isDefault` / `isActive` predicates shared by every catalog entity.
35
+ * `isActive` defaults to true so soft-deleted rows stay out of normal reads.
36
+ * Standalone for the same reason as {@link buildIdCondition}.
37
+ */
38
+ export declare function buildBooleanConditions(columns: {
39
+ isDefault: AnyColumn;
40
+ isActive: AnyColumn;
41
+ }, filter: {
42
+ isDefault?: unknown;
43
+ isActive?: unknown;
44
+ }): SQL[];
45
+ /**
46
+ * Schema table interface for access control queries. Every catalog entity
47
+ * carries the same five columns, which is what lets ONE predicate serve
48
+ * pipelines, plugins and templates alike.
23
49
  */
24
50
  export interface AccessControlSchema {
25
51
  id: AnyColumn;
26
52
  orgId: AnyColumn;
27
- accessModifier: AnyColumn;
53
+ /** Three-rung sharing ladder — see api-core's `Visibility`. */
54
+ visibility: AnyColumn;
55
+ /** Author. Owns the `private` rung. */
56
+ createdBy: AnyColumn;
28
57
  isDefault: AnyColumn;
29
58
  isActive: AnyColumn;
30
59
  }
31
60
  /**
32
- * Base filter interface with common access control fields
61
+ * Base filter interface with common access control fields.
62
+ *
63
+ * `viewerUserId` / `viewerIsSuperAdmin` are SERVER-SET (stamped from the request's
64
+ * tenant context by `withViewerContext`), never client-supplied — see
65
+ * `viewer-context.ts` for why the tenant context is the channel.
33
66
  */
34
67
  export interface BaseAccessFilter {
35
68
  id?: string | string[];
36
- accessModifier?: string;
69
+ visibility?: string;
37
70
  isDefault?: boolean | string;
38
71
  isActive?: boolean | string;
72
+ viewerUserId?: string;
73
+ viewerIsSuperAdmin?: boolean;
39
74
  }
40
75
  /**
41
76
  * Generic access control query builder for multi-tenant entities.
@@ -53,20 +88,28 @@ export declare class AccessControlQueryBuilder<TSchema extends AccessControlSche
53
88
  private schema;
54
89
  constructor(schema: TSchema);
55
90
  /**
56
- * Build access control conditions based on orgId and accessModifier filter.
91
+ * Build the caller's visible slice of a catalog, from the three-rung
92
+ * `visibility` ladder shared by every catalog entity.
93
+ *
94
+ * Effective read set for a caller in org `O` as user `V` whose parent org is `P`:
95
+ *
96
+ * (org_id = O AND (visibility <> 'private' OR created_by = V))
97
+ * OR (visibility = 'public' AND (org_id = 'system' OR org_id = P))
57
98
  *
58
- * Without orgId (anonymous):
59
- * orgId='system' AND accessModifier='public'
99
+ * i.e. your own org's shared rungs plus your own drafts, widened by the system
100
+ * org's public catalog (the standing "system-org content is visible from every
101
+ * org" rule) and — for a team — its parent's public rows. The `public`-only
102
+ * restriction applies solely to those OTHER orgs' rows; within your own org you
103
+ * always see everything you are entitled to, or a freshly-created private row
104
+ * would vanish from its own author's listing.
60
105
  *
61
- * With orgId:
62
- * - accessModifier='private': orgId=$org AND accessModifier='private'
63
- * - accessModifier='public': orgId=$org AND accessModifier='public'
64
- * - no accessModifier: orgId=$org (any access modifier)
65
- * OR (accessModifier='public' AND (orgId='system' OR orgId=$parent))
106
+ * An explicit `visibility` filter NARROWS within that set, never widens it —
107
+ * so `?visibility=public` still surfaces the system-org catalog.
66
108
  *
67
- * `parentOrgId` (org team hierarchy) widens the default catalog view so a
68
- * team org also sees its parent's public records. Absent for root orgs, so
69
- * the condition is unchanged for non-team callers.
109
+ * Fails CLOSED on both axes: no `orgId` (anonymous) system-org public only;
110
+ * no `viewerUserId` the private rung matches nothing rather than everything.
111
+ * `viewerIsSuperAdmin` lifts the private rung only a platform operator
112
+ * administers the whole catalog.
70
113
  *
71
114
  * @param filter - Filter criteria
72
115
  * @param orgId - User's organization ID (optional)
@@ -1,7 +1,7 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { AccessModifier, SYSTEM_ORG_ID } from '@pipeline-builder/api-core';
4
- import { and, eq, or, sql, SQL } from 'drizzle-orm';
3
+ import { SYSTEM_ORG_ID } from '@pipeline-builder/api-core';
4
+ import { and, eq, ne, or, sql, SQL } from 'drizzle-orm';
5
5
  const FULL_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
6
6
  /**
7
7
  * Escape SQL LIKE wildcard characters to prevent wildcard injection.
@@ -34,6 +34,49 @@ export function parseBooleanFilter(value) {
34
34
  export function normalizeStringFilter(value) {
35
35
  return typeof value === 'string' ? value.toLowerCase() : String(value).toLowerCase();
36
36
  }
37
+ /**
38
+ * Build an ID predicate with UUID prefix matching.
39
+ *
40
+ * - Full UUID → exact match
41
+ * - Partial UUID → prefix match via `LIKE` (a list-search affordance)
42
+ * - Absent → `null` (no predicate)
43
+ *
44
+ * Standalone so entities that DON'T use {@link AccessControlQueryBuilder}'s
45
+ * access control (e.g. pipeline templates, which carry their own three-rung
46
+ * visibility ladder) still share one id-matching implementation.
47
+ */
48
+ export function buildIdCondition(idColumn, id) {
49
+ if (id === undefined || id === null)
50
+ return null;
51
+ const idString = String(id).toLowerCase();
52
+ if (FULL_UUID.test(idString)) {
53
+ return eq(idColumn, idString);
54
+ }
55
+ // Escape SQL LIKE wildcards to prevent wildcard injection
56
+ const escaped = escapeLikeWildcards(idString);
57
+ return sql `${idColumn}::text LIKE ${escaped + '%'} ESCAPE '\\'`;
58
+ }
59
+ /**
60
+ * Build the `isDefault` / `isActive` predicates shared by every catalog entity.
61
+ * `isActive` defaults to true so soft-deleted rows stay out of normal reads.
62
+ * Standalone for the same reason as {@link buildIdCondition}.
63
+ */
64
+ export function buildBooleanConditions(columns, filter) {
65
+ const conditions = [];
66
+ if (filter.isDefault !== undefined) {
67
+ conditions.push(eq(columns.isDefault, parseBooleanFilter(filter.isDefault)));
68
+ }
69
+ if (filter.isActive !== undefined) {
70
+ conditions.push(eq(columns.isActive, parseBooleanFilter(filter.isActive)));
71
+ }
72
+ else {
73
+ // Default to active records only to exclude soft-deleted entities
74
+ conditions.push(eq(columns.isActive, true));
75
+ }
76
+ return conditions;
77
+ }
78
+ /** Fail-closed predicate: matches no rows. */
79
+ const NO_ROWS = sql `false`;
37
80
  /**
38
81
  * Generic access control query builder for multi-tenant entities.
39
82
  *
@@ -52,20 +95,28 @@ export class AccessControlQueryBuilder {
52
95
  this.schema = schema;
53
96
  }
54
97
  /**
55
- * Build access control conditions based on orgId and accessModifier filter.
98
+ * Build the caller's visible slice of a catalog, from the three-rung
99
+ * `visibility` ladder shared by every catalog entity.
56
100
  *
57
- * Without orgId (anonymous):
58
- * orgId='system' AND accessModifier='public'
101
+ * Effective read set for a caller in org `O` as user `V` whose parent org is `P`:
59
102
  *
60
- * With orgId:
61
- * - accessModifier='private': orgId=$org AND accessModifier='private'
62
- * - accessModifier='public': orgId=$org AND accessModifier='public'
63
- * - no accessModifier: orgId=$org (any access modifier)
64
- * OR (accessModifier='public' AND (orgId='system' OR orgId=$parent))
103
+ * (org_id = O AND (visibility <> 'private' OR created_by = V))
104
+ * OR (visibility = 'public' AND (org_id = 'system' OR org_id = P))
65
105
  *
66
- * `parentOrgId` (org team hierarchy) widens the default catalog view so a
67
- * team org also sees its parent's public records. Absent for root orgs, so
68
- * the condition is unchanged for non-team callers.
106
+ * i.e. your own org's shared rungs plus your own drafts, widened by the system
107
+ * org's public catalog (the standing "system-org content is visible from every
108
+ * org" rule) and for a team — its parent's public rows. The `public`-only
109
+ * restriction applies solely to those OTHER orgs' rows; within your own org you
110
+ * always see everything you are entitled to, or a freshly-created private row
111
+ * would vanish from its own author's listing.
112
+ *
113
+ * An explicit `visibility` filter NARROWS within that set, never widens it —
114
+ * so `?visibility=public` still surfaces the system-org catalog.
115
+ *
116
+ * Fails CLOSED on both axes: no `orgId` (anonymous) ⇒ system-org public only;
117
+ * no `viewerUserId` ⇒ the private rung matches nothing rather than everything.
118
+ * `viewerIsSuperAdmin` lifts the private rung only — a platform operator
119
+ * administers the whole catalog.
69
120
  *
70
121
  * @param filter - Filter criteria
71
122
  * @param orgId - User's organization ID (optional)
@@ -74,49 +125,31 @@ export class AccessControlQueryBuilder {
74
125
  */
75
126
  buildAccessControl(filter, orgId, parentOrgId) {
76
127
  const conditions = [];
128
+ const requested = filter.visibility;
77
129
  if (!orgId) {
78
- // No org context — only system org's public records
130
+ // No org context — only the system org's public catalog.
79
131
  conditions.push(eq(this.schema.orgId, SYSTEM_ORG_ID));
80
- conditions.push(eq(this.schema.accessModifier, AccessModifier.PUBLIC));
132
+ conditions.push(eq(this.schema.visibility, 'public'));
133
+ // An anonymous caller asking for a narrower rung gets nothing, rather than
134
+ // having the narrowing silently ignored.
135
+ if (requested !== undefined && requested !== 'public')
136
+ conditions.push(NO_ROWS);
81
137
  return conditions;
82
138
  }
83
139
  const normalizedOrgId = orgId.toLowerCase();
84
- const accessModifier = filter.accessModifier;
85
- if (accessModifier !== undefined) {
86
- const normalized = typeof accessModifier === 'string'
87
- ? accessModifier.toLowerCase()
88
- : String(accessModifier).toLowerCase();
89
- if (normalized === AccessModifier.PUBLIC) {
90
- // Explicit "public" filter must STILL surface the system org's (and parent
91
- // org's) public content — the standing rule that orgId='system' samples are
92
- // visible from any org. Scoping to the caller's own org alone would hide them.
93
- const ownPublic = and(eq(this.schema.orgId, normalizedOrgId), eq(this.schema.accessModifier, AccessModifier.PUBLIC));
94
- const otherOrgScopes = [eq(this.schema.orgId, SYSTEM_ORG_ID)];
95
- if (parentOrgId)
96
- otherOrgScopes.push(eq(this.schema.orgId, parentOrgId.toLowerCase()));
97
- const otherOrgsPublic = and(eq(this.schema.accessModifier, AccessModifier.PUBLIC), or(...otherOrgScopes));
98
- conditions.push(or(ownPublic, otherOrgsPublic));
99
- }
100
- else {
101
- // Explicit non-public (e.g. private): you can only ever see your own org's rows.
102
- conditions.push(eq(this.schema.orgId, normalizedOrgId));
103
- conditions.push(eq(this.schema.accessModifier, normalized));
104
- }
105
- }
106
- else {
107
- // Default catalog view: ALL of the caller's own-org records (any access
108
- // modifier — you always see what you own, including private), PLUS the
109
- // PUBLIC records of the system org and the parent org (team → parent
110
- // inheritance). The public restriction applies only to those other orgs'
111
- // rows, never to your own — otherwise a freshly uploaded private plugin
112
- // would vanish from its owner's own listing.
113
- const ownOrg = eq(this.schema.orgId, normalizedOrgId);
114
- const otherOrgScopes = [eq(this.schema.orgId, SYSTEM_ORG_ID)];
115
- if (parentOrgId)
116
- otherOrgScopes.push(eq(this.schema.orgId, parentOrgId.toLowerCase()));
117
- const otherOrgsPublic = and(eq(this.schema.accessModifier, AccessModifier.PUBLIC), or(...otherOrgScopes));
118
- conditions.push(or(ownOrg, otherOrgsPublic));
119
- }
140
+ // Own-org rows: everything EXCEPT other people's private drafts.
141
+ const ownDraftsOnly = filter.viewerUserId ? eq(this.schema.createdBy, filter.viewerUserId) : NO_ROWS;
142
+ const ownOrg = filter.viewerIsSuperAdmin
143
+ ? eq(this.schema.orgId, normalizedOrgId)
144
+ : and(eq(this.schema.orgId, normalizedOrgId), or(ne(this.schema.visibility, 'private'), ownDraftsOnly));
145
+ // Rows from OTHER orgs are only ever visible at the `public` rung.
146
+ const otherOrgScopes = [eq(this.schema.orgId, SYSTEM_ORG_ID)];
147
+ if (parentOrgId)
148
+ otherOrgScopes.push(eq(this.schema.orgId, parentOrgId.toLowerCase()));
149
+ const otherOrgsPublic = and(eq(this.schema.visibility, 'public'), or(...otherOrgScopes));
150
+ conditions.push(or(ownOrg, otherOrgsPublic));
151
+ if (requested !== undefined)
152
+ conditions.push(eq(this.schema.visibility, requested));
120
153
  return conditions;
121
154
  }
122
155
  /**
@@ -129,17 +162,7 @@ export class AccessControlQueryBuilder {
129
162
  * @returns SQL condition or null if no ID filter
130
163
  */
131
164
  buildIdFilter(id) {
132
- if (id === undefined || id === null)
133
- return null;
134
- const idString = String(id).toLowerCase();
135
- if (FULL_UUID.test(idString)) {
136
- return eq(this.schema.id, idString);
137
- }
138
- else {
139
- // Escape SQL LIKE wildcards to prevent wildcard injection
140
- const escaped = escapeLikeWildcards(idString);
141
- return sql `${this.schema.id}::text LIKE ${escaped + '%'} ESCAPE '\\'`;
142
- }
165
+ return buildIdCondition(this.schema.id, id);
143
166
  }
144
167
  /**
145
168
  * Build boolean field conditions (isDefault, isActive)
@@ -148,18 +171,7 @@ export class AccessControlQueryBuilder {
148
171
  * @returns Array of SQL conditions for boolean fields
149
172
  */
150
173
  buildBooleanFilters(filter) {
151
- const conditions = [];
152
- if (filter.isDefault !== undefined) {
153
- conditions.push(eq(this.schema.isDefault, parseBooleanFilter(filter.isDefault)));
154
- }
155
- if (filter.isActive !== undefined) {
156
- conditions.push(eq(this.schema.isActive, parseBooleanFilter(filter.isActive)));
157
- }
158
- else {
159
- // Default to active records only to exclude soft-deleted entities
160
- conditions.push(eq(this.schema.isActive, true));
161
- }
162
- return conditions;
174
+ return buildBooleanConditions(this.schema, filter);
163
175
  }
164
176
  /**
165
177
  * Build all common conditions (access control + ID + booleans)
@@ -173,7 +185,7 @@ export class AccessControlQueryBuilder {
173
185
  */
174
186
  buildCommonConditions(filter, orgId, parentOrgId) {
175
187
  const conditions = [];
176
- // Access control (multi-tenant) — handles accessModifier internally
188
+ // Access control (multi-tenant) — handles visibility internally
177
189
  conditions.push(...this.buildAccessControl(filter, orgId, parentOrgId));
178
190
  // ID filter with prefix matching
179
191
  const idCondition = this.buildIdFilter(filter.id);
@@ -184,4 +196,4 @@ export class AccessControlQueryBuilder {
184
196
  return conditions;
185
197
  }
186
198
  }
187
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWNvbnRyb2wtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvYWNjZXNzLWNvbnRyb2wtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0UsT0FBTyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHcEQsTUFBTSxTQUFTLEdBQUcsaUVBQWlFLENBQUM7QUFFcEY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLEdBQVc7SUFDN0MsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxNQUFpQixFQUFFLE9BQWU7SUFDM0UsTUFBTSxPQUFPLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDM0QsT0FBTyxHQUFHLENBQUEsbURBQW1ELE1BQU0sZ0NBQWdDLEdBQUcsR0FBRyxPQUFPLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDNUgsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEtBQWM7SUFDL0MsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLEtBQUssTUFBTSxDQUFDO0lBQ3ZELE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3hCLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxLQUFjO0lBQ2xELE9BQU8sT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQUN2RixDQUFDO0FBdUJEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxPQUFPLHlCQUF5QjtJQUsxQixNQUFNO0lBRGhCLFlBQ1UsTUFBZTtzQkFBZixNQUFNO0lBQ2IsQ0FBQztJQUVKOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQW9CRztJQUNPLGtCQUFrQixDQUFDLE1BQXdCLEVBQUUsS0FBYyxFQUFFLFdBQW9CO1FBQ3pGLE1BQU0sVUFBVSxHQUFVLEVBQUUsQ0FBQztRQUU3QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxvREFBb0Q7WUFDcEQsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUN0RCxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUN2RSxPQUFPLFVBQVUsQ0FBQztRQUNwQixDQUFDO1FBRUQsTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzVDLE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxjQUFvQyxDQUFDO1FBRW5FLElBQUksY0FBYyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sVUFBVSxHQUFHLE9BQU8sY0FBYyxLQUFLLFFBQVE7Z0JBQ25ELENBQUMsQ0FBQyxjQUFjLENBQUMsV0FBVyxFQUFFO2dCQUM5QixDQUFDLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3pDLElBQUksVUFBVSxLQUFLLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDekMsMkVBQTJFO2dCQUMzRSw0RUFBNEU7Z0JBQzVFLCtFQUErRTtnQkFDL0UsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFFLENBQUM7Z0JBQ3RILE1BQU0sY0FBYyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUM7Z0JBQzlELElBQUksV0FBVztvQkFBRSxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUN2RixNQUFNLGVBQWUsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxjQUFjLENBQUUsQ0FBRSxDQUFDO2dCQUM1RyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsZUFBZSxDQUFFLENBQUMsQ0FBQztZQUNuRCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04saUZBQWlGO2dCQUNqRixVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDO2dCQUN4RCxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQzlELENBQUM7UUFDSCxDQUFDO2FBQU0sQ0FBQztZQUNOLHdFQUF3RTtZQUN4RSx1RUFBdUU7WUFDdkUscUVBQXFFO1lBQ3JFLHlFQUF5RTtZQUN6RSx3RUFBd0U7WUFDeEUsNkNBQTZDO1lBQzdDLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsQ0FBQztZQUN0RCxNQUFNLGNBQWMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDO1lBQzlELElBQUksV0FBVztnQkFBRSxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3ZGLE1BQU0sZUFBZSxHQUFHLEdBQUcsQ0FDekIsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxNQUFNLENBQUMsRUFDckQsRUFBRSxDQUFDLEdBQUcsY0FBYyxDQUFFLENBQ3RCLENBQUM7WUFDSCxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsZUFBZSxDQUFFLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBRUQsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ08sYUFBYSxDQUFDLEVBQVc7UUFDakMsSUFBSSxFQUFFLEtBQUssU0FBUyxJQUFJLEVBQUUsS0FBSyxJQUFJO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFakQsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzFDLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzdCLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7YUFBTSxDQUFDO1lBQ04sMERBQTBEO1lBQzFELE1BQU0sT0FBTyxHQUFHLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzlDLE9BQU8sR0FBRyxDQUFBLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLGVBQWUsT0FBTyxHQUFHLEdBQUcsY0FBYyxDQUFDO1FBQ3hFLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTyxtQkFBbUIsQ0FBQyxNQUF3QjtRQUNwRCxNQUFNLFVBQVUsR0FBVSxFQUFFLENBQUM7UUFFN0IsSUFBSSxNQUFNLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ25DLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkYsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNsQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pGLENBQUM7YUFBTSxDQUFDO1lBQ04sa0VBQWtFO1lBQ2xFLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDbEQsQ0FBQztRQUVELE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSSxxQkFBcUIsQ0FBQyxNQUF3QixFQUFFLEtBQWMsRUFBRSxXQUFvQjtRQUN6RixNQUFNLFVBQVUsR0FBVSxFQUFFLENBQUM7UUFFN0Isb0VBQW9FO1FBQ3BFLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBRXhFLGlDQUFpQztRQUNqQyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNsRCxJQUFJLFdBQVc7WUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTlDLGtCQUFrQjtRQUNsQixVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFFckQsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IEFjY2Vzc01vZGlmaWVyLCBTWVNURU1fT1JHX0lEIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgYW5kLCBlcSwgb3IsIHNxbCwgU1FMIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHR5cGUgeyBBbnlDb2x1bW4gfSBmcm9tICdkcml6emxlLW9ybS9jb2x1bW4nO1xuXG5jb25zdCBGVUxMX1VVSUQgPSAvXlswLTlhLWZdezh9LVswLTlhLWZdezR9LVswLTlhLWZdezR9LVswLTlhLWZdezR9LVswLTlhLWZdezEyfSQvaTtcblxuLyoqXG4gKiBFc2NhcGUgU1FMIExJS0Ugd2lsZGNhcmQgY2hhcmFjdGVycyB0byBwcmV2ZW50IHdpbGRjYXJkIGluamVjdGlvbi5cbiAqIFJlcGxhY2VzIGAlYCDihpIgYFxcXFwlYCwgYF9gIOKGkiBgXFxcXF9gLCBhbmQgYFxcXFxgIOKGkiBgXFxcXFxcXFxgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlTGlrZVdpbGRjYXJkcyhzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvXFxcXC9nLCAnXFxcXFxcXFwnKS5yZXBsYWNlKC8lL2csICdcXFxcJScpLnJlcGxhY2UoL18vZywgJ1xcXFxfJyk7XG59XG5cbi8qKlxuICogQnVpbGQgYSBjb25kaXRpb24gdGhhdCBjaGVja3MgaWYgYSBKU09OQiB0ZXh0IGFycmF5IGNvbHVtbiBjb250YWlucyBhIGtleXdvcmQgKGNhc2UtaW5zZW5zaXRpdmUpLlxuICogVXNlZCBmb3Iga2V5d29yZHMvdGFncyBmaWx0ZXJpbmcgb24gcGlwZWxpbmVzLCBwbHVnaW5zLCBhbmQgY29tcGxpYW5jZSBydWxlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkSnNvbmJLZXl3b3JkQ29uZGl0aW9uKGNvbHVtbjogQW55Q29sdW1uLCBrZXl3b3JkOiBzdHJpbmcpOiBTUUwge1xuICBjb25zdCBlc2NhcGVkID0gZXNjYXBlTGlrZVdpbGRjYXJkcyhrZXl3b3JkLnRvTG93ZXJDYXNlKCkpO1xuICByZXR1cm4gc3FsYEVYSVNUUyAoU0VMRUNUIDEgRlJPTSBqc29uYl9hcnJheV9lbGVtZW50c190ZXh0KCR7Y29sdW1ufSkgQVMgZWwgV0hFUkUgbG93ZXIoZWwpIExJS0UgJHsnJScgKyBlc2NhcGVkICsgJyUnfSlgO1xufVxuXG4vKipcbiAqIFBhcnNlIGJvb2xlYW4gZmlsdGVyIHZhbHVlIGZyb20gc3RyaW5nIG9yIGJvb2xlYW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQm9vbGVhbkZpbHRlcih2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHJldHVybiB2YWx1ZTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHJldHVybiB2YWx1ZSA9PT0gJ3RydWUnO1xuICByZXR1cm4gQm9vbGVhbih2YWx1ZSk7XG59XG5cbi8qKlxuICogTm9ybWFsaXplIHN0cmluZyBmaWx0ZXIgdmFsdWUgdG8gbG93ZXJjYXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVTdHJpbmdGaWx0ZXIodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlLnRvTG93ZXJDYXNlKCkgOiBTdHJpbmcodmFsdWUpLnRvTG93ZXJDYXNlKCk7XG59XG5cbi8qKlxuICogU2NoZW1hIHRhYmxlIGludGVyZmFjZSBmb3IgYWNjZXNzIGNvbnRyb2wgcXVlcmllc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEFjY2Vzc0NvbnRyb2xTY2hlbWEge1xuICBpZDogQW55Q29sdW1uO1xuICBvcmdJZDogQW55Q29sdW1uO1xuICBhY2Nlc3NNb2RpZmllcjogQW55Q29sdW1uO1xuICBpc0RlZmF1bHQ6IEFueUNvbHVtbjtcbiAgaXNBY3RpdmU6IEFueUNvbHVtbjtcbn1cblxuLyoqXG4gKiBCYXNlIGZpbHRlciBpbnRlcmZhY2Ugd2l0aCBjb21tb24gYWNjZXNzIGNvbnRyb2wgZmllbGRzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZUFjY2Vzc0ZpbHRlciB7XG4gIGlkPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIGFjY2Vzc01vZGlmaWVyPzogc3RyaW5nO1xuICBpc0RlZmF1bHQ/OiBib29sZWFuIHwgc3RyaW5nO1xuICBpc0FjdGl2ZT86IGJvb2xlYW4gfCBzdHJpbmc7XG59XG5cbi8qKlxuICogR2VuZXJpYyBhY2Nlc3MgY29udHJvbCBxdWVyeSBidWlsZGVyIGZvciBtdWx0aS10ZW5hbnQgZW50aXRpZXMuXG4gKlxuICogQ29uc29saWRhdGVzIGR1cGxpY2F0ZSBhY2Nlc3MgY29udHJvbCBsb2dpYyBzaGFyZWQgYWNyb3NzIHBpcGVsaW5lIGFuZCBwbHVnaW4gcXVlcmllcy5cbiAqIEhhbmRsZXM6XG4gKiAtIE11bHRpLXRlbmFudCBhY2Nlc3MgY29udHJvbCAocHVibGljL3ByaXZhdGUvb3JnLWFuZC1wdWJsaWMpXG4gKiAtIFVVSUQgcHJlZml4IG1hdGNoaW5nIGZvciBJRCBmaWx0ZXJzXG4gKiAtIEJvb2xlYW4gZmllbGQgbm9ybWFsaXphdGlvblxuICpcbiAqIEB0eXBlUGFyYW0gVFNjaGVtYSAtIFNjaGVtYSB0YWJsZSB0eXBlIHdpdGggYWNjZXNzIGNvbnRyb2wgZmllbGRzXG4gKiBAdHlwZVBhcmFtIFRGaWx0ZXIgLSBGaWx0ZXIgdHlwZSBleHRlbmRpbmcgQmFzZUFjY2Vzc0ZpbHRlclxuICovXG5leHBvcnQgY2xhc3MgQWNjZXNzQ29udHJvbFF1ZXJ5QnVpbGRlcjxcbiAgVFNjaGVtYSBleHRlbmRzIEFjY2Vzc0NvbnRyb2xTY2hlbWEsXG4gIFRGaWx0ZXIgZXh0ZW5kcyBCYXNlQWNjZXNzRmlsdGVyLFxuPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgc2NoZW1hOiBUU2NoZW1hLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFjY2VzcyBjb250cm9sIGNvbmRpdGlvbnMgYmFzZWQgb24gb3JnSWQgYW5kIGFjY2Vzc01vZGlmaWVyIGZpbHRlci5cbiAgICpcbiAgICogV2l0aG91dCBvcmdJZCAoYW5vbnltb3VzKTpcbiAgICogICBvcmdJZD0nc3lzdGVtJyBBTkQgYWNjZXNzTW9kaWZpZXI9J3B1YmxpYydcbiAgICpcbiAgICogV2l0aCBvcmdJZDpcbiAgICogICAtIGFjY2Vzc01vZGlmaWVyPSdwcml2YXRlJzogb3JnSWQ9JG9yZyBBTkQgYWNjZXNzTW9kaWZpZXI9J3ByaXZhdGUnXG4gICAqICAgLSBhY2Nlc3NNb2RpZmllcj0ncHVibGljJzogIG9yZ0lkPSRvcmcgQU5EIGFjY2Vzc01vZGlmaWVyPSdwdWJsaWMnXG4gICAqICAgLSBubyBhY2Nlc3NNb2RpZmllcjogICAgICAgIG9yZ0lkPSRvcmcgKGFueSBhY2Nlc3MgbW9kaWZpZXIpXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9SIChhY2Nlc3NNb2RpZmllcj0ncHVibGljJyBBTkQgKG9yZ0lkPSdzeXN0ZW0nIE9SIG9yZ0lkPSRwYXJlbnQpKVxuICAgKlxuICAgKiBgcGFyZW50T3JnSWRgIChvcmcg4oaSIHRlYW0gaGllcmFyY2h5KSB3aWRlbnMgdGhlIGRlZmF1bHQgY2F0YWxvZyB2aWV3IHNvIGFcbiAgICogdGVhbSBvcmcgYWxzbyBzZWVzIGl0cyBwYXJlbnQncyBwdWJsaWMgcmVjb3Jkcy4gQWJzZW50IGZvciByb290IG9yZ3MsIHNvXG4gICAqIHRoZSBjb25kaXRpb24gaXMgdW5jaGFuZ2VkIGZvciBub24tdGVhbSBjYWxsZXJzLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsdGVyIC0gRmlsdGVyIGNyaXRlcmlhXG4gICAqIEBwYXJhbSBvcmdJZCAtIFVzZXIncyBvcmdhbml6YXRpb24gSUQgKG9wdGlvbmFsKVxuICAgKiBAcGFyYW0gcGFyZW50T3JnSWQgLSBQYXJlbnQgb3JnIElEIHdoZW4gdGhlIGNhbGxlciBpcyBhIHRlYW0gKG9wdGlvbmFsKVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9ucyBmb3IgYWNjZXNzIGNvbnRyb2xcbiAgICovXG4gIHByb3RlY3RlZCBidWlsZEFjY2Vzc0NvbnRyb2woZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBTUUxbXSB7XG4gICAgY29uc3QgY29uZGl0aW9uczogU1FMW10gPSBbXTtcblxuICAgIGlmICghb3JnSWQpIHtcbiAgICAgIC8vIE5vIG9yZyBjb250ZXh0IOKAlCBvbmx5IHN5c3RlbSBvcmcncyBwdWJsaWMgcmVjb3Jkc1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBTWVNURU1fT1JHX0lEKSk7XG4gICAgICBjb25kaXRpb25zLnB1c2goZXEodGhpcy5zY2hlbWEuYWNjZXNzTW9kaWZpZXIsIEFjY2Vzc01vZGlmaWVyLlBVQkxJQykpO1xuICAgICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZE9yZ0lkID0gb3JnSWQudG9Mb3dlckNhc2UoKTtcbiAgICBjb25zdCBhY2Nlc3NNb2RpZmllciA9IGZpbHRlci5hY2Nlc3NNb2RpZmllciBhcyBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAoYWNjZXNzTW9kaWZpZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IHR5cGVvZiBhY2Nlc3NNb2RpZmllciA9PT0gJ3N0cmluZydcbiAgICAgICAgPyBhY2Nlc3NNb2RpZmllci50b0xvd2VyQ2FzZSgpXG4gICAgICAgIDogU3RyaW5nKGFjY2Vzc01vZGlmaWVyKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKG5vcm1hbGl6ZWQgPT09IEFjY2Vzc01vZGlmaWVyLlBVQkxJQykge1xuICAgICAgICAvLyBFeHBsaWNpdCBcInB1YmxpY1wiIGZpbHRlciBtdXN0IFNUSUxMIHN1cmZhY2UgdGhlIHN5c3RlbSBvcmcncyAoYW5kIHBhcmVudFxuICAgICAgICAvLyBvcmcncykgcHVibGljIGNvbnRlbnQg4oCUIHRoZSBzdGFuZGluZyBydWxlIHRoYXQgb3JnSWQ9J3N5c3RlbScgc2FtcGxlcyBhcmVcbiAgICAgICAgLy8gdmlzaWJsZSBmcm9tIGFueSBvcmcuIFNjb3BpbmcgdG8gdGhlIGNhbGxlcidzIG93biBvcmcgYWxvbmUgd291bGQgaGlkZSB0aGVtLlxuICAgICAgICBjb25zdCBvd25QdWJsaWMgPSBhbmQoZXEodGhpcy5zY2hlbWEub3JnSWQsIG5vcm1hbGl6ZWRPcmdJZCksIGVxKHRoaXMuc2NoZW1hLmFjY2Vzc01vZGlmaWVyLCBBY2Nlc3NNb2RpZmllci5QVUJMSUMpKSE7XG4gICAgICAgIGNvbnN0IG90aGVyT3JnU2NvcGVzID0gW2VxKHRoaXMuc2NoZW1hLm9yZ0lkLCBTWVNURU1fT1JHX0lEKV07XG4gICAgICAgIGlmIChwYXJlbnRPcmdJZCkgb3RoZXJPcmdTY29wZXMucHVzaChlcSh0aGlzLnNjaGVtYS5vcmdJZCwgcGFyZW50T3JnSWQudG9Mb3dlckNhc2UoKSkpO1xuICAgICAgICBjb25zdCBvdGhlck9yZ3NQdWJsaWMgPSBhbmQoZXEodGhpcy5zY2hlbWEuYWNjZXNzTW9kaWZpZXIsIEFjY2Vzc01vZGlmaWVyLlBVQkxJQyksIG9yKC4uLm90aGVyT3JnU2NvcGVzKSEpITtcbiAgICAgICAgY29uZGl0aW9ucy5wdXNoKG9yKG93blB1YmxpYywgb3RoZXJPcmdzUHVibGljKSEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRXhwbGljaXQgbm9uLXB1YmxpYyAoZS5nLiBwcml2YXRlKTogeW91IGNhbiBvbmx5IGV2ZXIgc2VlIHlvdXIgb3duIG9yZydzIHJvd3MuXG4gICAgICAgIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS5vcmdJZCwgbm9ybWFsaXplZE9yZ0lkKSk7XG4gICAgICAgIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS5hY2Nlc3NNb2RpZmllciwgbm9ybWFsaXplZCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWZhdWx0IGNhdGFsb2cgdmlldzogQUxMIG9mIHRoZSBjYWxsZXIncyBvd24tb3JnIHJlY29yZHMgKGFueSBhY2Nlc3NcbiAgICAgIC8vIG1vZGlmaWVyIOKAlCB5b3UgYWx3YXlzIHNlZSB3aGF0IHlvdSBvd24sIGluY2x1ZGluZyBwcml2YXRlKSwgUExVUyB0aGVcbiAgICAgIC8vIFBVQkxJQyByZWNvcmRzIG9mIHRoZSBzeXN0ZW0gb3JnIGFuZCB0aGUgcGFyZW50IG9yZyAodGVhbSDihpIgcGFyZW50XG4gICAgICAvLyBpbmhlcml0YW5jZSkuIFRoZSBwdWJsaWMgcmVzdHJpY3Rpb24gYXBwbGllcyBvbmx5IHRvIHRob3NlIG90aGVyIG9yZ3MnXG4gICAgICAvLyByb3dzLCBuZXZlciB0byB5b3VyIG93biDigJQgb3RoZXJ3aXNlIGEgZnJlc2hseSB1cGxvYWRlZCBwcml2YXRlIHBsdWdpblxuICAgICAgLy8gd291bGQgdmFuaXNoIGZyb20gaXRzIG93bmVyJ3Mgb3duIGxpc3RpbmcuXG4gICAgICBjb25zdCBvd25PcmcgPSBlcSh0aGlzLnNjaGVtYS5vcmdJZCwgbm9ybWFsaXplZE9yZ0lkKTtcbiAgICAgIGNvbnN0IG90aGVyT3JnU2NvcGVzID0gW2VxKHRoaXMuc2NoZW1hLm9yZ0lkLCBTWVNURU1fT1JHX0lEKV07XG4gICAgICBpZiAocGFyZW50T3JnSWQpIG90aGVyT3JnU2NvcGVzLnB1c2goZXEodGhpcy5zY2hlbWEub3JnSWQsIHBhcmVudE9yZ0lkLnRvTG93ZXJDYXNlKCkpKTtcbiAgICAgIGNvbnN0IG90aGVyT3Jnc1B1YmxpYyA9IGFuZChcbiAgICAgICAgZXEodGhpcy5zY2hlbWEuYWNjZXNzTW9kaWZpZXIsIEFjY2Vzc01vZGlmaWVyLlBVQkxJQyksXG4gICAgICAgIG9yKC4uLm90aGVyT3JnU2NvcGVzKSEsXG4gICAgICApITtcbiAgICAgIGNvbmRpdGlvbnMucHVzaChvcihvd25PcmcsIG90aGVyT3Jnc1B1YmxpYykhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29uZGl0aW9ucztcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBJRCBmaWx0ZXIgd2l0aCBVVUlEIHByZWZpeCBtYXRjaGluZyBzdXBwb3J0XG4gICAqXG4gICAqIC0gRnVsbCBVVUlEOiBFeGFjdCBtYXRjaFxuICAgKiAtIFBhcnRpYWwgVVVJRDogUHJlZml4IG1hdGNoIHVzaW5nIFNRTCBMSUtFXG4gICAqXG4gICAqIEBwYXJhbSBpZCAtIElEIGZpbHRlciB2YWx1ZSAoZnVsbCBvciBwYXJ0aWFsIFVVSUQpXG4gICAqIEByZXR1cm5zIFNRTCBjb25kaXRpb24gb3IgbnVsbCBpZiBubyBJRCBmaWx0ZXJcbiAgICovXG4gIHByb3RlY3RlZCBidWlsZElkRmlsdGVyKGlkOiB1bmtub3duKTogU1FMIHwgbnVsbCB7XG4gICAgaWYgKGlkID09PSB1bmRlZmluZWQgfHwgaWQgPT09IG51bGwpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgaWRTdHJpbmcgPSBTdHJpbmcoaWQpLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKEZVTExfVVVJRC50ZXN0KGlkU3RyaW5nKSkge1xuICAgICAgcmV0dXJuIGVxKHRoaXMuc2NoZW1hLmlkLCBpZFN0cmluZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEVzY2FwZSBTUUwgTElLRSB3aWxkY2FyZHMgdG8gcHJldmVudCB3aWxkY2FyZCBpbmplY3Rpb25cbiAgICAgIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGlkU3RyaW5nKTtcbiAgICAgIHJldHVybiBzcWxgJHt0aGlzLnNjaGVtYS5pZH06OnRleHQgTElLRSAke2VzY2FwZWQgKyAnJSd9IEVTQ0FQRSAnXFxcXCdgO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBib29sZWFuIGZpZWxkIGNvbmRpdGlvbnMgKGlzRGVmYXVsdCwgaXNBY3RpdmUpXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHJldHVybnMgQXJyYXkgb2YgU1FMIGNvbmRpdGlvbnMgZm9yIGJvb2xlYW4gZmllbGRzXG4gICAqL1xuICBwcm90ZWN0ZWQgYnVpbGRCb29sZWFuRmlsdGVycyhmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4pOiBTUUxbXSB7XG4gICAgY29uc3QgY29uZGl0aW9uczogU1FMW10gPSBbXTtcblxuICAgIGlmIChmaWx0ZXIuaXNEZWZhdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS5pc0RlZmF1bHQsIHBhcnNlQm9vbGVhbkZpbHRlcihmaWx0ZXIuaXNEZWZhdWx0KSkpO1xuICAgIH1cblxuICAgIGlmIChmaWx0ZXIuaXNBY3RpdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLmlzQWN0aXZlLCBwYXJzZUJvb2xlYW5GaWx0ZXIoZmlsdGVyLmlzQWN0aXZlKSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWZhdWx0IHRvIGFjdGl2ZSByZWNvcmRzIG9ubHkgdG8gZXhjbHVkZSBzb2Z0LWRlbGV0ZWQgZW50aXRpZXNcbiAgICAgIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS5pc0FjdGl2ZSwgdHJ1ZSkpO1xuICAgIH1cblxuICAgIHJldHVybiBjb25kaXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFsbCBjb21tb24gY29uZGl0aW9ucyAoYWNjZXNzIGNvbnRyb2wgKyBJRCArIGJvb2xlYW5zKVxuICAgKlxuICAgKiBUaGlzIGNvbWJpbmVzIGFsbCB0aGUgZ2VuZXJpYyBmaWx0ZXJzIHRoYXQgYXBwbHkgdG8gYW55IGFjY2Vzcy1jb250cm9sbGVkIGVudGl0eS5cbiAgICogU3ViY2xhc3NlcyBzaG91bGQgY2FsbCB0aGlzIGFuZCBhZGQgZW50aXR5LXNwZWNpZmljIGNvbmRpdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIGZhbGxzIGJhY2sgdG8gc3lzdGVtLXB1YmxpYy1vbmx5KVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9uc1xuICAgKi9cbiAgcHVibGljIGJ1aWxkQ29tbW9uQ29uZGl0aW9ucyhmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuXG4gICAgLy8gQWNjZXNzIGNvbnRyb2wgKG11bHRpLXRlbmFudCkg4oCUIGhhbmRsZXMgYWNjZXNzTW9kaWZpZXIgaW50ZXJuYWxseVxuICAgIGNvbmRpdGlvbnMucHVzaCguLi50aGlzLmJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCkpO1xuXG4gICAgLy8gSUQgZmlsdGVyIHdpdGggcHJlZml4IG1hdGNoaW5nXG4gICAgY29uc3QgaWRDb25kaXRpb24gPSB0aGlzLmJ1aWxkSWRGaWx0ZXIoZmlsdGVyLmlkKTtcbiAgICBpZiAoaWRDb25kaXRpb24pIGNvbmRpdGlvbnMucHVzaChpZENvbmRpdGlvbik7XG5cbiAgICAvLyBCb29sZWFuIGZpbHRlcnNcbiAgICBjb25kaXRpb25zLnB1c2goLi4udGhpcy5idWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcikpO1xuXG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cbn1cbiJdfQ==
199
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWNvbnRyb2wtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvYWNjZXNzLWNvbnRyb2wtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHeEQsTUFBTSxTQUFTLEdBQUcsaUVBQWlFLENBQUM7QUFFcEY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLEdBQVc7SUFDN0MsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxNQUFpQixFQUFFLE9BQWU7SUFDM0UsTUFBTSxPQUFPLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDM0QsT0FBTyxHQUFHLENBQUEsbURBQW1ELE1BQU0sZ0NBQWdDLEdBQUcsR0FBRyxPQUFPLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDNUgsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEtBQWM7SUFDL0MsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLEtBQUssTUFBTSxDQUFDO0lBQ3ZELE9BQU8sT0FBTyxDQUFDLEtBQUss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QUU5QyxJQUFJLFNBQVMsS0FBSyxTQUFTO1lBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUVwRixPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDTyxhQUFhLENBQUMsRUFBVztRQUNqQyxPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNPLG1CQUFtQixDQUFDLE1BQXdCO1FBQ3BELE9BQU8sc0JBQXNCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0kscUJBQXFCLENBQUMsTUFBd0IsRUFBRSxLQUFjLEVBQUUsV0FBb0I7UUFDekYsTUFBTSxVQUFVLEdBQVUsRUFBRSxDQUFDO1FBRTdCLGdFQUFnRTtRQUNoRSxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUV4RSxpQ0FBaUM7UUFDakMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbEQsSUFBSSxXQUFXO1lBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUU5QyxrQkFBa0I7UUFDbEIsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBRXJELE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBTWVNURU1fT1JHX0lEIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgYW5kLCBlcSwgbmUsIG9yLCBzcWwsIFNRTCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB0eXBlIHsgQW55Q29sdW1uIH0gZnJvbSAnZHJpenpsZS1vcm0vY29sdW1uJztcblxuY29uc3QgRlVMTF9VVUlEID0gL15bMC05YS1mXXs4fS1bMC05YS1mXXs0fS1bMC05YS1mXXs0fS1bMC05YS1mXXs0fS1bMC05YS1mXXsxMn0kL2k7XG5cbi8qKlxuICogRXNjYXBlIFNRTCBMSUtFIHdpbGRjYXJkIGNoYXJhY3RlcnMgdG8gcHJldmVudCB3aWxkY2FyZCBpbmplY3Rpb24uXG4gKiBSZXBsYWNlcyBgJWAg4oaSIGBcXFxcJWAsIGBfYCDihpIgYFxcXFxfYCwgYW5kIGBcXFxcYCDihpIgYFxcXFxcXFxcYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZUxpa2VXaWxkY2FyZHMoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoL1xcXFwvZywgJ1xcXFxcXFxcJykucmVwbGFjZSgvJS9nLCAnXFxcXCUnKS5yZXBsYWNlKC9fL2csICdcXFxcXycpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgY29uZGl0aW9uIHRoYXQgY2hlY2tzIGlmIGEgSlNPTkIgdGV4dCBhcnJheSBjb2x1bW4gY29udGFpbnMgYSBrZXl3b3JkIChjYXNlLWluc2Vuc2l0aXZlKS5cbiAqIFVzZWQgZm9yIGtleXdvcmRzL3RhZ3MgZmlsdGVyaW5nIG9uIHBpcGVsaW5lcywgcGx1Z2lucywgYW5kIGNvbXBsaWFuY2UgcnVsZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEpzb25iS2V5d29yZENvbmRpdGlvbihjb2x1bW46IEFueUNvbHVtbiwga2V5d29yZDogc3RyaW5nKTogU1FMIHtcbiAgY29uc3QgZXNjYXBlZCA9IGVzY2FwZUxpa2VXaWxkY2FyZHMoa2V5d29yZC50b0xvd2VyQ2FzZSgpKTtcbiAgcmV0dXJuIHNxbGBFWElTVFMgKFNFTEVDVCAxIEZST00ganNvbmJfYXJyYXlfZWxlbWVudHNfdGV4dCgke2NvbHVtbn0pIEFTIGVsIFdIRVJFIGxvd2VyKGVsKSBMSUtFICR7JyUnICsgZXNjYXBlZCArICclJ30pYDtcbn1cblxuLyoqXG4gKiBQYXJzZSBib29sZWFuIGZpbHRlciB2YWx1ZSBmcm9tIHN0cmluZyBvciBib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJvb2xlYW5GaWx0ZXIodmFsdWU6IHVua25vd24pOiBib29sZWFuIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSByZXR1cm4gdmFsdWU7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSByZXR1cm4gdmFsdWUgPT09ICd0cnVlJztcbiAgcmV0dXJuIEJvb2xlYW4odmFsdWUpO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBzdHJpbmcgZmlsdGVyIHZhbHVlIHRvIGxvd2VyY2FzZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplU3RyaW5nRmlsdGVyKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgPyB2YWx1ZS50b0xvd2VyQ2FzZSgpIDogU3RyaW5nKHZhbHVlKS50b0xvd2VyQ2FzZSgpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGFuIElEIHByZWRpY2F0ZSB3aXRoIFVVSUQgcHJlZml4IG1hdGNoaW5nLlxuICpcbiAqIC0gRnVsbCBVVUlEIOKGkiBleGFjdCBtYXRjaFxuICogLSBQYXJ0aWFsIFVVSUQg4oaSIHByZWZpeCBtYXRjaCB2aWEgYExJS0VgIChhIGxpc3Qtc2VhcmNoIGFmZm9yZGFuY2UpXG4gKiAtIEFic2VudCDihpIgYG51bGxgIChubyBwcmVkaWNhdGUpXG4gKlxuICogU3RhbmRhbG9uZSBzbyBlbnRpdGllcyB0aGF0IERPTidUIHVzZSB7QGxpbmsgQWNjZXNzQ29udHJvbFF1ZXJ5QnVpbGRlcn0nc1xuICogYWNjZXNzIGNvbnRyb2wgKGUuZy4gcGlwZWxpbmUgdGVtcGxhdGVzLCB3aGljaCBjYXJyeSB0aGVpciBvd24gdGhyZWUtcnVuZ1xuICogdmlzaWJpbGl0eSBsYWRkZXIpIHN0aWxsIHNoYXJlIG9uZSBpZC1tYXRjaGluZyBpbXBsZW1lbnRhdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkSWRDb25kaXRpb24oaWRDb2x1bW46IEFueUNvbHVtbiwgaWQ6IHVua25vd24pOiBTUUwgfCBudWxsIHtcbiAgaWYgKGlkID09PSB1bmRlZmluZWQgfHwgaWQgPT09IG51bGwpIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IGlkU3RyaW5nID0gU3RyaW5nKGlkKS50b0xvd2VyQ2FzZSgpO1xuICBpZiAoRlVMTF9VVUlELnRlc3QoaWRTdHJpbmcpKSB7XG4gICAgcmV0dXJuIGVxKGlkQ29sdW1uLCBpZFN0cmluZyk7XG4gIH1cbiAgLy8gRXNjYXBlIFNRTCBMSUtFIHdpbGRjYXJkcyB0byBwcmV2ZW50IHdpbGRjYXJkIGluamVjdGlvblxuICBjb25zdCBlc2NhcGVkID0gZXNjYXBlTGlrZVdpbGRjYXJkcyhpZFN0cmluZyk7XG4gIHJldHVybiBzcWxgJHtpZENvbHVtbn06OnRleHQgTElLRSAke2VzY2FwZWQgKyAnJSd9IEVTQ0FQRSAnXFxcXCdgO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSBgaXNEZWZhdWx0YCAvIGBpc0FjdGl2ZWAgcHJlZGljYXRlcyBzaGFyZWQgYnkgZXZlcnkgY2F0YWxvZyBlbnRpdHkuXG4gKiBgaXNBY3RpdmVgIGRlZmF1bHRzIHRvIHRydWUgc28gc29mdC1kZWxldGVkIHJvd3Mgc3RheSBvdXQgb2Ygbm9ybWFsIHJlYWRzLlxuICogU3RhbmRhbG9uZSBmb3IgdGhlIHNhbWUgcmVhc29uIGFzIHtAbGluayBidWlsZElkQ29uZGl0aW9ufS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQm9vbGVhbkNvbmRpdGlvbnMoXG4gIGNvbHVtbnM6IHsgaXNEZWZhdWx0OiBBbnlDb2x1bW47IGlzQWN0aXZlOiBBbnlDb2x1bW4gfSxcbiAgZmlsdGVyOiB7IGlzRGVmYXVsdD86IHVua25vd247IGlzQWN0aXZlPzogdW5rbm93biB9LFxuKTogU1FMW10ge1xuICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuXG4gIGlmIChmaWx0ZXIuaXNEZWZhdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25kaXRpb25zLnB1c2goZXEoY29sdW1ucy5pc0RlZmF1bHQsIHBhcnNlQm9vbGVhbkZpbHRlcihmaWx0ZXIuaXNEZWZhdWx0KSkpO1xuICB9XG5cbiAgaWYgKGZpbHRlci5pc0FjdGl2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uZGl0aW9ucy5wdXNoKGVxKGNvbHVtbnMuaXNBY3RpdmUsIHBhcnNlQm9vbGVhbkZpbHRlcihmaWx0ZXIuaXNBY3RpdmUpKSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gRGVmYXVsdCB0byBhY3RpdmUgcmVjb3JkcyBvbmx5IHRvIGV4Y2x1ZGUgc29mdC1kZWxldGVkIGVudGl0aWVzXG4gICAgY29uZGl0aW9ucy5wdXNoKGVxKGNvbHVtbnMuaXNBY3RpdmUsIHRydWUpKTtcbiAgfVxuXG4gIHJldHVybiBjb25kaXRpb25zO1xufVxuXG4vKipcbiAqIFNjaGVtYSB0YWJsZSBpbnRlcmZhY2UgZm9yIGFjY2VzcyBjb250cm9sIHF1ZXJpZXMuIEV2ZXJ5IGNhdGFsb2cgZW50aXR5XG4gKiBjYXJyaWVzIHRoZSBzYW1lIGZpdmUgY29sdW1ucywgd2hpY2ggaXMgd2hhdCBsZXRzIE9ORSBwcmVkaWNhdGUgc2VydmVcbiAqIHBpcGVsaW5lcywgcGx1Z2lucyBhbmQgdGVtcGxhdGVzIGFsaWtlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFjY2Vzc0NvbnRyb2xTY2hlbWEge1xuICBpZDogQW55Q29sdW1uO1xuICBvcmdJZDogQW55Q29sdW1uO1xuICAvKiogVGhyZWUtcnVuZyBzaGFyaW5nIGxhZGRlciDigJQgc2VlIGFwaS1jb3JlJ3MgYFZpc2liaWxpdHlgLiAqL1xuICB2aXNpYmlsaXR5OiBBbnlDb2x1bW47XG4gIC8qKiBBdXRob3IuIE93bnMgdGhlIGBwcml2YXRlYCBydW5nLiAqL1xuICBjcmVhdGVkQnk6IEFueUNvbHVtbjtcbiAgaXNEZWZhdWx0OiBBbnlDb2x1bW47XG4gIGlzQWN0aXZlOiBBbnlDb2x1bW47XG59XG5cbi8qKlxuICogQmFzZSBmaWx0ZXIgaW50ZXJmYWNlIHdpdGggY29tbW9uIGFjY2VzcyBjb250cm9sIGZpZWxkcy5cbiAqXG4gKiBgdmlld2VyVXNlcklkYCAvIGB2aWV3ZXJJc1N1cGVyQWRtaW5gIGFyZSBTRVJWRVItU0VUIChzdGFtcGVkIGZyb20gdGhlIHJlcXVlc3Qnc1xuICogdGVuYW50IGNvbnRleHQgYnkgYHdpdGhWaWV3ZXJDb250ZXh0YCksIG5ldmVyIGNsaWVudC1zdXBwbGllZCDigJQgc2VlXG4gKiBgdmlld2VyLWNvbnRleHQudHNgIGZvciB3aHkgdGhlIHRlbmFudCBjb250ZXh0IGlzIHRoZSBjaGFubmVsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VBY2Nlc3NGaWx0ZXIge1xuICBpZD86IHN0cmluZyB8IHN0cmluZ1tdO1xuICB2aXNpYmlsaXR5Pzogc3RyaW5nO1xuICBpc0RlZmF1bHQ/OiBib29sZWFuIHwgc3RyaW5nO1xuICBpc0FjdGl2ZT86IGJvb2xlYW4gfCBzdHJpbmc7XG4gIHZpZXdlclVzZXJJZD86IHN0cmluZztcbiAgdmlld2VySXNTdXBlckFkbWluPzogYm9vbGVhbjtcbn1cblxuLyoqIEZhaWwtY2xvc2VkIHByZWRpY2F0ZTogbWF0Y2hlcyBubyByb3dzLiAqL1xuY29uc3QgTk9fUk9XUzogU1FMID0gc3FsYGZhbHNlYDtcblxuLyoqXG4gKiBHZW5lcmljIGFjY2VzcyBjb250cm9sIHF1ZXJ5IGJ1aWxkZXIgZm9yIG11bHRpLXRlbmFudCBlbnRpdGllcy5cbiAqXG4gKiBDb25zb2xpZGF0ZXMgZHVwbGljYXRlIGFjY2VzcyBjb250cm9sIGxvZ2ljIHNoYXJlZCBhY3Jvc3MgcGlwZWxpbmUgYW5kIHBsdWdpbiBxdWVyaWVzLlxuICogSGFuZGxlczpcbiAqIC0gTXVsdGktdGVuYW50IGFjY2VzcyBjb250cm9sIChwdWJsaWMvcHJpdmF0ZS9vcmctYW5kLXB1YmxpYylcbiAqIC0gVVVJRCBwcmVmaXggbWF0Y2hpbmcgZm9yIElEIGZpbHRlcnNcbiAqIC0gQm9vbGVhbiBmaWVsZCBub3JtYWxpemF0aW9uXG4gKlxuICogQHR5cGVQYXJhbSBUU2NoZW1hIC0gU2NoZW1hIHRhYmxlIHR5cGUgd2l0aCBhY2Nlc3MgY29udHJvbCBmaWVsZHNcbiAqIEB0eXBlUGFyYW0gVEZpbHRlciAtIEZpbHRlciB0eXBlIGV4dGVuZGluZyBCYXNlQWNjZXNzRmlsdGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBBY2Nlc3NDb250cm9sUXVlcnlCdWlsZGVyPFxuICBUU2NoZW1hIGV4dGVuZHMgQWNjZXNzQ29udHJvbFNjaGVtYSxcbiAgVEZpbHRlciBleHRlbmRzIEJhc2VBY2Nlc3NGaWx0ZXIsXG4+IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBzY2hlbWE6IFRTY2hlbWEsXG4gICkge31cblxuICAvKipcbiAgICogQnVpbGQgdGhlIGNhbGxlcidzIHZpc2libGUgc2xpY2Ugb2YgYSBjYXRhbG9nLCBmcm9tIHRoZSB0aHJlZS1ydW5nXG4gICAqIGB2aXNpYmlsaXR5YCBsYWRkZXIgc2hhcmVkIGJ5IGV2ZXJ5IGNhdGFsb2cgZW50aXR5LlxuICAgKlxuICAgKiBFZmZlY3RpdmUgcmVhZCBzZXQgZm9yIGEgY2FsbGVyIGluIG9yZyBgT2AgYXMgdXNlciBgVmAgd2hvc2UgcGFyZW50IG9yZyBpcyBgUGA6XG4gICAqXG4gICAqICAgKG9yZ19pZCA9IE8gQU5EICh2aXNpYmlsaXR5IDw+ICdwcml2YXRlJyBPUiBjcmVhdGVkX2J5ID0gVikpXG4gICAqICAgT1IgKHZpc2liaWxpdHkgPSAncHVibGljJyBBTkQgKG9yZ19pZCA9ICdzeXN0ZW0nIE9SIG9yZ19pZCA9IFApKVxuICAgKlxuICAgKiBpLmUuIHlvdXIgb3duIG9yZydzIHNoYXJlZCBydW5ncyBwbHVzIHlvdXIgb3duIGRyYWZ0cywgd2lkZW5lZCBieSB0aGUgc3lzdGVtXG4gICAqIG9yZydzIHB1YmxpYyBjYXRhbG9nICh0aGUgc3RhbmRpbmcgXCJzeXN0ZW0tb3JnIGNvbnRlbnQgaXMgdmlzaWJsZSBmcm9tIGV2ZXJ5XG4gICAqIG9yZ1wiIHJ1bGUpIGFuZCDigJQgZm9yIGEgdGVhbSDigJQgaXRzIHBhcmVudCdzIHB1YmxpYyByb3dzLiBUaGUgYHB1YmxpY2Atb25seVxuICAgKiByZXN0cmljdGlvbiBhcHBsaWVzIHNvbGVseSB0byB0aG9zZSBPVEhFUiBvcmdzJyByb3dzOyB3aXRoaW4geW91ciBvd24gb3JnIHlvdVxuICAgKiBhbHdheXMgc2VlIGV2ZXJ5dGhpbmcgeW91IGFyZSBlbnRpdGxlZCB0bywgb3IgYSBmcmVzaGx5LWNyZWF0ZWQgcHJpdmF0ZSByb3dcbiAgICogd291bGQgdmFuaXNoIGZyb20gaXRzIG93biBhdXRob3IncyBsaXN0aW5nLlxuICAgKlxuICAgKiBBbiBleHBsaWNpdCBgdmlzaWJpbGl0eWAgZmlsdGVyIE5BUlJPV1Mgd2l0aGluIHRoYXQgc2V0LCBuZXZlciB3aWRlbnMgaXQg4oCUXG4gICAqIHNvIGA/dmlzaWJpbGl0eT1wdWJsaWNgIHN0aWxsIHN1cmZhY2VzIHRoZSBzeXN0ZW0tb3JnIGNhdGFsb2cuXG4gICAqXG4gICAqIEZhaWxzIENMT1NFRCBvbiBib3RoIGF4ZXM6IG5vIGBvcmdJZGAgKGFub255bW91cykg4oeSIHN5c3RlbS1vcmcgcHVibGljIG9ubHk7XG4gICAqIG5vIGB2aWV3ZXJVc2VySWRgIOKHkiB0aGUgcHJpdmF0ZSBydW5nIG1hdGNoZXMgbm90aGluZyByYXRoZXIgdGhhbiBldmVyeXRoaW5nLlxuICAgKiBgdmlld2VySXNTdXBlckFkbWluYCBsaWZ0cyB0aGUgcHJpdmF0ZSBydW5nIG9ubHkg4oCUIGEgcGxhdGZvcm0gb3BlcmF0b3JcbiAgICogYWRtaW5pc3RlcnMgdGhlIHdob2xlIGNhdGFsb2cuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwpXG4gICAqIEBwYXJhbSBwYXJlbnRPcmdJZCAtIFBhcmVudCBvcmcgSUQgd2hlbiB0aGUgY2FsbGVyIGlzIGEgdGVhbSAob3B0aW9uYWwpXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIFNRTCBjb25kaXRpb25zIGZvciBhY2Nlc3MgY29udHJvbFxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuICAgIGNvbnN0IHJlcXVlc3RlZCA9IGZpbHRlci52aXNpYmlsaXR5O1xuXG4gICAgaWYgKCFvcmdJZCkge1xuICAgICAgLy8gTm8gb3JnIGNvbnRleHQg4oCUIG9ubHkgdGhlIHN5c3RlbSBvcmcncyBwdWJsaWMgY2F0YWxvZy5cbiAgICAgIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS5vcmdJZCwgU1lTVEVNX09SR19JRCkpO1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLnZpc2liaWxpdHksICdwdWJsaWMnKSk7XG4gICAgICAvLyBBbiBhbm9ueW1vdXMgY2FsbGVyIGFza2luZyBmb3IgYSBuYXJyb3dlciBydW5nIGdldHMgbm90aGluZywgcmF0aGVyIHRoYW5cbiAgICAgIC8vIGhhdmluZyB0aGUgbmFycm93aW5nIHNpbGVudGx5IGlnbm9yZWQuXG4gICAgICBpZiAocmVxdWVzdGVkICE9PSB1bmRlZmluZWQgJiYgcmVxdWVzdGVkICE9PSAncHVibGljJykgY29uZGl0aW9ucy5wdXNoKE5PX1JPV1MpO1xuICAgICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZE9yZ0lkID0gb3JnSWQudG9Mb3dlckNhc2UoKTtcblxuICAgIC8vIE93bi1vcmcgcm93czogZXZlcnl0aGluZyBFWENFUFQgb3RoZXIgcGVvcGxlJ3MgcHJpdmF0ZSBkcmFmdHMuXG4gICAgY29uc3Qgb3duRHJhZnRzT25seSA9IGZpbHRlci52aWV3ZXJVc2VySWQgPyBlcSh0aGlzLnNjaGVtYS5jcmVhdGVkQnksIGZpbHRlci52aWV3ZXJVc2VySWQpIDogTk9fUk9XUztcbiAgICBjb25zdCBvd25PcmcgPSBmaWx0ZXIudmlld2VySXNTdXBlckFkbWluXG4gICAgICA/IGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBub3JtYWxpemVkT3JnSWQpXG4gICAgICA6IGFuZChlcSh0aGlzLnNjaGVtYS5vcmdJZCwgbm9ybWFsaXplZE9yZ0lkKSwgb3IobmUodGhpcy5zY2hlbWEudmlzaWJpbGl0eSwgJ3ByaXZhdGUnKSwgb3duRHJhZnRzT25seSkhKSE7XG5cbiAgICAvLyBSb3dzIGZyb20gT1RIRVIgb3JncyBhcmUgb25seSBldmVyIHZpc2libGUgYXQgdGhlIGBwdWJsaWNgIHJ1bmcuXG4gICAgY29uc3Qgb3RoZXJPcmdTY29wZXMgPSBbZXEodGhpcy5zY2hlbWEub3JnSWQsIFNZU1RFTV9PUkdfSUQpXTtcbiAgICBpZiAocGFyZW50T3JnSWQpIG90aGVyT3JnU2NvcGVzLnB1c2goZXEodGhpcy5zY2hlbWEub3JnSWQsIHBhcmVudE9yZ0lkLnRvTG93ZXJDYXNlKCkpKTtcbiAgICBjb25zdCBvdGhlck9yZ3NQdWJsaWMgPSBhbmQoZXEodGhpcy5zY2hlbWEudmlzaWJpbGl0eSwgJ3B1YmxpYycpLCBvciguLi5vdGhlck9yZ1Njb3BlcykhKSE7XG5cbiAgICBjb25kaXRpb25zLnB1c2gob3Iob3duT3JnLCBvdGhlck9yZ3NQdWJsaWMpISk7XG5cbiAgICBpZiAocmVxdWVzdGVkICE9PSB1bmRlZmluZWQpIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS52aXNpYmlsaXR5LCByZXF1ZXN0ZWQpKTtcblxuICAgIHJldHVybiBjb25kaXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIElEIGZpbHRlciB3aXRoIFVVSUQgcHJlZml4IG1hdGNoaW5nIHN1cHBvcnRcbiAgICpcbiAgICogLSBGdWxsIFVVSUQ6IEV4YWN0IG1hdGNoXG4gICAqIC0gUGFydGlhbCBVVUlEOiBQcmVmaXggbWF0Y2ggdXNpbmcgU1FMIExJS0VcbiAgICpcbiAgICogQHBhcmFtIGlkIC0gSUQgZmlsdGVyIHZhbHVlIChmdWxsIG9yIHBhcnRpYWwgVVVJRClcbiAgICogQHJldHVybnMgU1FMIGNvbmRpdGlvbiBvciBudWxsIGlmIG5vIElEIGZpbHRlclxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkSWRGaWx0ZXIoaWQ6IHVua25vd24pOiBTUUwgfCBudWxsIHtcbiAgICByZXR1cm4gYnVpbGRJZENvbmRpdGlvbih0aGlzLnNjaGVtYS5pZCwgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGJvb2xlYW4gZmllbGQgY29uZGl0aW9ucyAoaXNEZWZhdWx0LCBpc0FjdGl2ZSlcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9ucyBmb3IgYm9vbGVhbiBmaWVsZHNcbiAgICovXG4gIHByb3RlY3RlZCBidWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcjogUGFydGlhbDxURmlsdGVyPik6IFNRTFtdIHtcbiAgICByZXR1cm4gYnVpbGRCb29sZWFuQ29uZGl0aW9ucyh0aGlzLnNjaGVtYSwgZmlsdGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhbGwgY29tbW9uIGNvbmRpdGlvbnMgKGFjY2VzcyBjb250cm9sICsgSUQgKyBib29sZWFucylcbiAgICpcbiAgICogVGhpcyBjb21iaW5lcyBhbGwgdGhlIGdlbmVyaWMgZmlsdGVycyB0aGF0IGFwcGx5IHRvIGFueSBhY2Nlc3MtY29udHJvbGxlZCBlbnRpdHkuXG4gICAqIFN1YmNsYXNzZXMgc2hvdWxkIGNhbGwgdGhpcyBhbmQgYWRkIGVudGl0eS1zcGVjaWZpYyBjb25kaXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsdGVyIC0gRmlsdGVyIGNyaXRlcmlhXG4gICAqIEBwYXJhbSBvcmdJZCAtIFVzZXIncyBvcmdhbml6YXRpb24gSUQgKG9wdGlvbmFsIOKAlCBmYWxscyBiYWNrIHRvIHN5c3RlbS1wdWJsaWMtb25seSlcbiAgICogQHJldHVybnMgQXJyYXkgb2YgU1FMIGNvbmRpdGlvbnNcbiAgICovXG4gIHB1YmxpYyBidWlsZENvbW1vbkNvbmRpdGlvbnMoZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBTUUxbXSB7XG4gICAgY29uc3QgY29uZGl0aW9uczogU1FMW10gPSBbXTtcblxuICAgIC8vIEFjY2VzcyBjb250cm9sIChtdWx0aS10ZW5hbnQpIOKAlCBoYW5kbGVzIHZpc2liaWxpdHkgaW50ZXJuYWxseVxuICAgIGNvbmRpdGlvbnMucHVzaCguLi50aGlzLmJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCkpO1xuXG4gICAgLy8gSUQgZmlsdGVyIHdpdGggcHJlZml4IG1hdGNoaW5nXG4gICAgY29uc3QgaWRDb25kaXRpb24gPSB0aGlzLmJ1aWxkSWRGaWx0ZXIoZmlsdGVyLmlkKTtcbiAgICBpZiAoaWRDb25kaXRpb24pIGNvbmRpdGlvbnMucHVzaChpZENvbmRpdGlvbik7XG5cbiAgICAvLyBCb29sZWFuIGZpbHRlcnNcbiAgICBjb25kaXRpb25zLnB1c2goLi4udGhpcy5idWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcikpO1xuXG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cbn1cbiJdfQ==
@@ -70,7 +70,7 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
70
70
  * Typed column view of {@link schema}. `PgTable` exposes no static columns, so
71
71
  * the base class previously reached for `(this.schema as any).id` etc. at each
72
72
  * use; centralize that single unavoidable cast here so callers get structured,
73
- * typed access instead. `accessModifier` is optional (not every entity has it)
73
+ * typed access instead. `visibility` is optional (not every entity has it)
74
74
  * and the index signature covers dynamic sparse-fieldset column lookup.
75
75
  */
76
76
  private get cols();
@@ -231,7 +231,7 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
231
231
  * is undefined) keep the supplied org, matching the RLS policy
232
232
  * `current_is_sysadmin() OR org_id = current_org_id()`.
233
233
  */
234
- protected enforceOrgId<T>(data: T): T;
234
+ protected enforceOrgId<T>(data: T, isCreate?: boolean): T;
235
235
  /**
236
236
  * Create a new entity
237
237
  */
@@ -276,7 +276,7 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
276
276
  /** When true, only PRIVATE records are deleted — mirrors the single-delete
277
277
  * `requirePublicAccess` gate so a non-sysadmin can't bulk-delete public
278
278
  * (shared/sysadmin-managed) records. No-op for entities without an
279
- * `accessModifier` column. Callers pass `!isSystemAdmin(req)`. */
279
+ * `visibility` column. Callers pass `!isSystemAdmin(req)`. */
280
280
  restrictToPrivate?: boolean): Promise<TEntity[]>;
281
281
  /**
282
282
  * Restore a soft-deleted (tombstoned) entity: clear `isActive`/`deletedAt`/