@memberjunction/integration-connectors 5.51.0 → 6.1.0-edge.0

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 (155) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +109 -277
  3. package/dist/index.d.ts +0 -36
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +7 -38
  6. package/dist/index.js.map +1 -1
  7. package/package.json +14 -19
  8. package/dist/AptifyConnector.d.ts +0 -95
  9. package/dist/AptifyConnector.d.ts.map +0 -1
  10. package/dist/AptifyConnector.js +0 -760
  11. package/dist/AptifyConnector.js.map +0 -1
  12. package/dist/BlackbaudConnector.d.ts +0 -64
  13. package/dist/BlackbaudConnector.d.ts.map +0 -1
  14. package/dist/BlackbaudConnector.js +0 -916
  15. package/dist/BlackbaudConnector.js.map +0 -1
  16. package/dist/ConstantContactConnector.d.ts +0 -137
  17. package/dist/ConstantContactConnector.d.ts.map +0 -1
  18. package/dist/ConstantContactConnector.js +0 -663
  19. package/dist/ConstantContactConnector.js.map +0 -1
  20. package/dist/CventConnector.d.ts +0 -146
  21. package/dist/CventConnector.d.ts.map +0 -1
  22. package/dist/CventConnector.js +0 -540
  23. package/dist/CventConnector.js.map +0 -1
  24. package/dist/DynamicsDataverseConnector.d.ts +0 -296
  25. package/dist/DynamicsDataverseConnector.d.ts.map +0 -1
  26. package/dist/DynamicsDataverseConnector.js +0 -790
  27. package/dist/DynamicsDataverseConnector.js.map +0 -1
  28. package/dist/FileFeedConnector.d.ts +0 -64
  29. package/dist/FileFeedConnector.d.ts.map +0 -1
  30. package/dist/FileFeedConnector.js +0 -190
  31. package/dist/FileFeedConnector.js.map +0 -1
  32. package/dist/FontevaConnector.d.ts +0 -153
  33. package/dist/FontevaConnector.d.ts.map +0 -1
  34. package/dist/FontevaConnector.js +0 -421
  35. package/dist/FontevaConnector.js.map +0 -1
  36. package/dist/GrowthZoneConnector.d.ts +0 -183
  37. package/dist/GrowthZoneConnector.d.ts.map +0 -1
  38. package/dist/GrowthZoneConnector.js +0 -702
  39. package/dist/GrowthZoneConnector.js.map +0 -1
  40. package/dist/HivebriteConnector.d.ts +0 -151
  41. package/dist/HivebriteConnector.d.ts.map +0 -1
  42. package/dist/HivebriteConnector.js +0 -533
  43. package/dist/HivebriteConnector.js.map +0 -1
  44. package/dist/HubSpotConnector.d.ts +0 -523
  45. package/dist/HubSpotConnector.d.ts.map +0 -1
  46. package/dist/HubSpotConnector.js +0 -3110
  47. package/dist/HubSpotConnector.js.map +0 -1
  48. package/dist/IMISConnector.d.ts +0 -171
  49. package/dist/IMISConnector.d.ts.map +0 -1
  50. package/dist/IMISConnector.js +0 -695
  51. package/dist/IMISConnector.js.map +0 -1
  52. package/dist/MJToMJConnector.d.ts +0 -279
  53. package/dist/MJToMJConnector.d.ts.map +0 -1
  54. package/dist/MJToMJConnector.js +0 -893
  55. package/dist/MJToMJConnector.js.map +0 -1
  56. package/dist/MagnetMailConnector.d.ts +0 -163
  57. package/dist/MagnetMailConnector.d.ts.map +0 -1
  58. package/dist/MagnetMailConnector.js +0 -823
  59. package/dist/MagnetMailConnector.js.map +0 -1
  60. package/dist/MailchimpConnector.d.ts +0 -197
  61. package/dist/MailchimpConnector.d.ts.map +0 -1
  62. package/dist/MailchimpConnector.js +0 -791
  63. package/dist/MailchimpConnector.js.map +0 -1
  64. package/dist/MemberSuiteConnector.d.ts +0 -185
  65. package/dist/MemberSuiteConnector.d.ts.map +0 -1
  66. package/dist/MemberSuiteConnector.js +0 -762
  67. package/dist/MemberSuiteConnector.js.map +0 -1
  68. package/dist/NeonCRMConnector.d.ts +0 -273
  69. package/dist/NeonCRMConnector.d.ts.map +0 -1
  70. package/dist/NeonCRMConnector.js +0 -1039
  71. package/dist/NeonCRMConnector.js.map +0 -1
  72. package/dist/NetForumConnector.d.ts +0 -170
  73. package/dist/NetForumConnector.d.ts.map +0 -1
  74. package/dist/NetForumConnector.js +0 -778
  75. package/dist/NetForumConnector.js.map +0 -1
  76. package/dist/NetSuiteConnector.d.ts +0 -136
  77. package/dist/NetSuiteConnector.d.ts.map +0 -1
  78. package/dist/NetSuiteConnector.js +0 -703
  79. package/dist/NetSuiteConnector.js.map +0 -1
  80. package/dist/NimbleAMSConnector.d.ts +0 -142
  81. package/dist/NimbleAMSConnector.d.ts.map +0 -1
  82. package/dist/NimbleAMSConnector.js +0 -703
  83. package/dist/NimbleAMSConnector.js.map +0 -1
  84. package/dist/NoviConnector.d.ts +0 -178
  85. package/dist/NoviConnector.d.ts.map +0 -1
  86. package/dist/NoviConnector.js +0 -566
  87. package/dist/NoviConnector.js.map +0 -1
  88. package/dist/ORCIDConnector.d.ts +0 -207
  89. package/dist/ORCIDConnector.d.ts.map +0 -1
  90. package/dist/ORCIDConnector.js +0 -708
  91. package/dist/ORCIDConnector.js.map +0 -1
  92. package/dist/OpenWaterConnector.d.ts +0 -173
  93. package/dist/OpenWaterConnector.d.ts.map +0 -1
  94. package/dist/OpenWaterConnector.js +0 -893
  95. package/dist/OpenWaterConnector.js.map +0 -1
  96. package/dist/PathLMSConnector.d.ts +0 -395
  97. package/dist/PathLMSConnector.d.ts.map +0 -1
  98. package/dist/PathLMSConnector.js +0 -1281
  99. package/dist/PathLMSConnector.js.map +0 -1
  100. package/dist/PheedLoopConnector.d.ts +0 -119
  101. package/dist/PheedLoopConnector.d.ts.map +0 -1
  102. package/dist/PheedLoopConnector.js +0 -429
  103. package/dist/PheedLoopConnector.js.map +0 -1
  104. package/dist/PropFuelConnector.d.ts +0 -153
  105. package/dist/PropFuelConnector.d.ts.map +0 -1
  106. package/dist/PropFuelConnector.js +0 -450
  107. package/dist/PropFuelConnector.js.map +0 -1
  108. package/dist/QuickBooksConnector.d.ts +0 -92
  109. package/dist/QuickBooksConnector.d.ts.map +0 -1
  110. package/dist/QuickBooksConnector.js +0 -713
  111. package/dist/QuickBooksConnector.js.map +0 -1
  112. package/dist/RasaConnector.d.ts +0 -152
  113. package/dist/RasaConnector.d.ts.map +0 -1
  114. package/dist/RasaConnector.js +0 -929
  115. package/dist/RasaConnector.js.map +0 -1
  116. package/dist/Reach360Connector.d.ts +0 -175
  117. package/dist/Reach360Connector.d.ts.map +0 -1
  118. package/dist/Reach360Connector.js +0 -796
  119. package/dist/Reach360Connector.js.map +0 -1
  120. package/dist/RelationalDBConnector.d.ts +0 -108
  121. package/dist/RelationalDBConnector.d.ts.map +0 -1
  122. package/dist/RelationalDBConnector.js +0 -228
  123. package/dist/RelationalDBConnector.js.map +0 -1
  124. package/dist/RhythmConnector.d.ts +0 -188
  125. package/dist/RhythmConnector.d.ts.map +0 -1
  126. package/dist/RhythmConnector.js +0 -784
  127. package/dist/RhythmConnector.js.map +0 -1
  128. package/dist/SageIntacctConnector.d.ts +0 -337
  129. package/dist/SageIntacctConnector.d.ts.map +0 -1
  130. package/dist/SageIntacctConnector.js +0 -2081
  131. package/dist/SageIntacctConnector.js.map +0 -1
  132. package/dist/SalesforceConnector.d.ts +0 -461
  133. package/dist/SalesforceConnector.d.ts.map +0 -1
  134. package/dist/SalesforceConnector.js +0 -1862
  135. package/dist/SalesforceConnector.js.map +0 -1
  136. package/dist/SharePointConnector.d.ts +0 -188
  137. package/dist/SharePointConnector.d.ts.map +0 -1
  138. package/dist/SharePointConnector.js +0 -716
  139. package/dist/SharePointConnector.js.map +0 -1
  140. package/dist/WicketConnector.d.ts +0 -252
  141. package/dist/WicketConnector.d.ts.map +0 -1
  142. package/dist/WicketConnector.js +0 -938
  143. package/dist/WicketConnector.js.map +0 -1
  144. package/dist/WildApricotConnector.d.ts +0 -201
  145. package/dist/WildApricotConnector.d.ts.map +0 -1
  146. package/dist/WildApricotConnector.js +0 -1129
  147. package/dist/WildApricotConnector.js.map +0 -1
  148. package/dist/YourMembershipConnector.d.ts +0 -349
  149. package/dist/YourMembershipConnector.d.ts.map +0 -1
  150. package/dist/YourMembershipConnector.js +0 -4062
  151. package/dist/YourMembershipConnector.js.map +0 -1
  152. package/dist/generate-integration-actions.d.ts +0 -23
  153. package/dist/generate-integration-actions.d.ts.map +0 -1
  154. package/dist/generate-integration-actions.js +0 -201
  155. package/dist/generate-integration-actions.js.map +0 -1
@@ -1,566 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- import { RegisterClass } from '@memberjunction/global';
8
- import { Metadata } from '@memberjunction/core';
9
- import { BaseIntegrationConnector, BaseRESTIntegrationConnector, } from '@memberjunction/integration-engine';
10
- // ─── Constants ────────────────────────────────────────────────────────
11
- const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
12
- const DEFAULT_MAX_RETRIES = 4;
13
- /** Novi caps at 20 req/s; a 50ms floor keeps us at/under that per single connector. */
14
- const DEFAULT_MIN_REQUEST_INTERVAL_MS = 50;
15
- const DEFAULT_PAGE_SIZE = 50;
16
- /** Novi documented limits: 20/s, 600/min, 100k/day per key. Run conservatively under the per-second cap. */
17
- const RATE_LIMIT_TOKENS_PER_SEC = 15;
18
- const RATE_LIMIT_BURST = 20;
19
- // ─── Connector implementation ─────────────────────────────────────────
20
- /**
21
- * Connector for the Novi AMS REST API.
22
- *
23
- * Authenticates via the Novi API key placed RAW (not base64) after `Basic ` in
24
- * the Authorization header. Novi has no shared host — the per-tenant base URL
25
- * (`https://www.<assoc>.org`) is resolved from CompanyIntegration.Configuration.
26
- *
27
- * Reads ride the base {@link BaseRESTIntegrationConnector} pull path; this class
28
- * overrides only the genuinely Novi-specific bits:
29
- * - {@link BuildHeaders}: `Basic <rawApiKey>` (NOT base64 user:password).
30
- * - {@link GetBaseURL}: per-tenant host from Configuration.
31
- * - {@link NormalizeResponse}: unwraps the `{TotalCount, Results}` list envelope
32
- * and the `{data}` single-record envelope.
33
- * - {@link ExtractPaginationInfo} / {@link BuildPaginatedURL}: Novi offset
34
- * pagination uses `pageSize` + `offset` (the base default emits `limit`/`offset`).
35
- * - {@link FetchChanges}: emits each IO's `IncrementalWatermarkField` as a request
36
- * param for incremental sync and advances the watermark on full-batch success only.
37
- * - {@link UpdateRecord}: Novi PUT is FULL-OBJECT REPLACEMENT (no PATCH), so update
38
- * is GET-then-merge-then-PUT to avoid nulling unspecified fields.
39
- *
40
- * Create/Delete use the generic per-operation column path (CreateAPIPath/Method/
41
- * BodyShape/IDLocation, DeleteAPIPath/Method/IDLocation) driven entirely by the IO
42
- * metadata — no per-verb override.
43
- */
44
- let NoviConnector = class NoviConnector extends BaseRESTIntegrationConnector {
45
- constructor() {
46
- super(...arguments);
47
- /** Cached auth context (raw key + resolved per-tenant host). */
48
- this.authState = null;
49
- /** Timestamp of the last outbound request, used for throttling. */
50
- this.lastRequestTime = 0;
51
- }
52
- // ── Identity + capability getters ───────────────────────────────────
53
- /** Verbatim from the metadata Integration row — part of the three-way name invariant. */
54
- get IntegrationName() { return 'Novi AMS'; }
55
- // Novi exposes a documented two-way API. The generic per-operation path enforces
56
- // null-capability honesty per IO (an IO with no CreateAPIPath throws on create), so
57
- // these getters reflect that SOME IOs are writable; the actual writable set is the
58
- // metadata's per-op columns (~12 Create, ~13 Update, ~5 Delete IOs).
59
- get SupportsCreate() { return true; }
60
- get SupportsUpdate() { return true; }
61
- get SupportsDelete() { return true; }
62
- // ── Sync-efficiency hooks ───────────────────────────────────────────
63
- /**
64
- * Novi documents 20 req/s, 600/min, 100k/day per key. Run under the per-second cap;
65
- * the engine's AIMD bucket throttles + backs off on 429.
66
- */
67
- get RateLimitPolicy() {
68
- return { TokensPerSec: RATE_LIMIT_TOKENS_PER_SEC, Burst: RATE_LIMIT_BURST, ThrottleBackoffFactor: 0.5 };
69
- }
70
- /** Parse Novi's Retry-After header (delta-seconds or HTTP-date) into milliseconds. */
71
- ExtractRetryAfterMs(error) {
72
- const headers = error?.Headers;
73
- if (!headers)
74
- return undefined;
75
- const retryAfter = headers['retry-after'] ?? headers['Retry-After'];
76
- if (typeof retryAfter !== 'string' || retryAfter.length === 0)
77
- return undefined;
78
- const asSeconds = Number(retryAfter);
79
- if (!isNaN(asSeconds) && asSeconds >= 0)
80
- return Math.round(asSeconds * 1000);
81
- const asDate = Date.parse(retryAfter);
82
- if (!isNaN(asDate)) {
83
- const delta = asDate - Date.now();
84
- if (delta > 0)
85
- return delta;
86
- }
87
- return undefined;
88
- }
89
- // ─── TestConnection ──────────────────────────────────────────────
90
- /**
91
- * Verifies connectivity by listing a single Member record. A 2xx confirms the
92
- * raw API key + per-tenant base URL are valid; a 401/403 means the key was rejected.
93
- */
94
- async TestConnection(companyIntegration, contextUser) {
95
- try {
96
- const auth = await this.Authenticate(companyIntegration, contextUser);
97
- const headers = this.BuildHeaders(auth);
98
- const probeUrl = `${auth.BaseUrl}/api/members?pageSize=1&offset=0`;
99
- const resp = await this.MakeHTTPRequest(auth, probeUrl, 'GET', headers);
100
- if (resp.Status === 401 || resp.Status === 403) {
101
- return { Success: false, Message: `Novi AMS TestConnection failed: HTTP ${resp.Status} (API key rejected)` };
102
- }
103
- if (resp.Status >= 500) {
104
- return { Success: false, Message: `Novi AMS TestConnection failed: HTTP ${resp.Status} (server error)` };
105
- }
106
- if (resp.Status < 200 || resp.Status >= 300) {
107
- return { Success: false, Message: `Novi AMS returned HTTP ${resp.Status} from ${probeUrl}` };
108
- }
109
- return {
110
- Success: true,
111
- Message: `Connected to Novi AMS at ${auth.BaseUrl}`,
112
- ServerVersion: 'Novi AMS REST API',
113
- };
114
- }
115
- catch (err) {
116
- const message = err instanceof Error ? err.message : String(err);
117
- return { Success: false, Message: `Connection failed: ${message}` };
118
- }
119
- }
120
- // ─── FetchChanges (watermark-aware) ───────────────────────────────
121
- /**
122
- * Sets the watermark context that {@link BuildPaginatedURL} emits as the IO's
123
- * `IncrementalWatermarkField`, delegates the actual fetch + pagination to the base,
124
- * then advances the watermark from the returned records on the FINAL batch only
125
- * (HasMore=false) so a partial-failure mid-pagination leaves the watermark unchanged.
126
- */
127
- async FetchChanges(ctx) {
128
- this.currentWatermark = ctx.WatermarkValue ?? undefined;
129
- const result = await super.FetchChanges(ctx);
130
- const obj = this.GetCachedObject(ctx.CompanyIntegration.IntegrationID, ctx.ObjectName);
131
- if (obj.SupportsIncrementalSync && obj.IncrementalWatermarkField && !result.HasMore) {
132
- const advanced = this.ExtractLatestWatermark(result.Records, obj.IncrementalWatermarkField);
133
- const newWatermark = advanced ?? ctx.WatermarkValue ?? undefined;
134
- if (newWatermark != null)
135
- return { ...result, NewWatermarkValue: newWatermark };
136
- }
137
- return result;
138
- }
139
- /**
140
- * Scans a batch for the latest watermark value. Novi's per-object watermark column is
141
- * a server-side date field (e.g. `lastModifiedDate`); the corresponding RECORD field
142
- * carries the comparable timestamp. We probe the common date columns a record may
143
- * surface and take the max ISO date so the next run resumes from there.
144
- */
145
- ExtractLatestWatermark(records, _watermarkField) {
146
- // Candidate record-level date columns that mirror a Novi watermark param.
147
- const candidates = [
148
- 'lastModifiedDate', 'LastModifiedDate', 'lastUpdatedDate', 'LastUpdatedDate',
149
- 'modifiedDate', 'ModifiedDate', 'publishOnDate', 'PublishOnDate',
150
- 'orderDate', 'OrderDate', 'date', 'Date',
151
- ];
152
- let latest = null;
153
- for (const rec of records) {
154
- for (const key of candidates) {
155
- const raw = rec.Fields?.[key];
156
- if (typeof raw !== 'string' || raw.length === 0)
157
- continue;
158
- const d = new Date(raw);
159
- if (!isNaN(d.getTime()) && (latest === null || d > latest))
160
- latest = d;
161
- }
162
- }
163
- return latest ? latest.toISOString() : null;
164
- }
165
- // ─── Update: GET-then-merge-then-PUT (full-object replacement) ─────
166
- /**
167
- * Novi PUT is FULL-OBJECT REPLACEMENT — there is no PATCH, so a bare PUT of only the
168
- * mapped attributes would NULL every unspecified field. We override UpdateRecord to
169
- * GET the current record, deep-merge the changed attributes over it, then PUT the
170
- * merged whole. (Create/Delete use the generic per-operation column path unchanged.)
171
- */
172
- async UpdateRecord(ctx) {
173
- const ci = ctx.CompanyIntegration;
174
- const contextUser = ctx.ContextUser;
175
- const obj = this.GetCachedObject(ci.IntegrationID, ctx.ObjectName);
176
- if (!obj.UpdateAPIPath || !obj.UpdateMethod) {
177
- throw new Error(`UpdateRecord not supported for "${ctx.ObjectName}": ` +
178
- `UpdateAPIPath / UpdateMethod not configured on IntegrationObject.`);
179
- }
180
- const auth = await this.Authenticate(ci, contextUser);
181
- const headers = this.BuildHeaders(auth);
182
- // 1) Resolve the single-record path: substitute {id} with the ExternalID, plus any
183
- // remaining {var} template segments (e.g. {CommitteeUniqueID}) from the attributes.
184
- const resolvedPath = this.ResolveUpdatePath(obj.UpdateAPIPath, ctx.ExternalID, ctx.Attributes);
185
- const url = `${auth.BaseUrl}${this.ensureLeadingSlash(resolvedPath)}`;
186
- // 2) GET the current full record so the PUT preserves unspecified fields.
187
- const current = await this.GetCurrentRecord(auth, url, headers);
188
- // 3) Merge the changed attributes over the current record (shallow — Novi resources are flat).
189
- const merged = { ...(current ?? {}), ...ctx.Attributes };
190
- // 4) PUT the full merged object.
191
- const response = await this.MakeHTTPRequest(auth, url, obj.UpdateMethod, headers, merged);
192
- if (response.Status >= 200 && response.Status < 300) {
193
- return { Success: true, StatusCode: response.Status, ExternalID: ctx.ExternalID };
194
- }
195
- return {
196
- Success: false,
197
- StatusCode: response.Status,
198
- ErrorMessage: this.ExtractErrorMessage(response) ?? `HTTP ${response.Status} on update`,
199
- };
200
- }
201
- /** GETs the current single record (for merge); returns null on 404/empty. */
202
- async GetCurrentRecord(auth, url, headers) {
203
- const resp = await this.MakeHTTPRequest(auth, url, 'GET', headers);
204
- if (resp.Status === 404)
205
- return null;
206
- if (resp.Status < 200 || resp.Status >= 300) {
207
- throw Object.assign(new Error(`Novi AMS update pre-fetch failed: HTTP ${resp.Status} for ${url}`), { Status: resp.Status, Headers: resp.Headers });
208
- }
209
- const records = this.NormalizeResponse(resp.Body, null);
210
- return records.length > 0 ? records[0] : null;
211
- }
212
- /**
213
- * Resolves an update path template: {id}/{ID}/{ExternalID} → the record's ExternalID,
214
- * and any remaining {var} (e.g. {CommitteeUniqueID}) from the matching attribute value.
215
- */
216
- ResolveUpdatePath(template, externalID, attributes) {
217
- const idEncoded = encodeURIComponent(externalID);
218
- let path = template
219
- .replace(/\{ID\}/g, idEncoded)
220
- .replace(/\{id\}/g, idEncoded)
221
- .replace(/\{ExternalID\}/g, idEncoded);
222
- // Resolve any remaining {var} from the attributes (case-insensitive key match).
223
- path = path.replace(/\{(\w+)\}/g, (_match, varName) => {
224
- const hit = Object.entries(attributes).find(([k]) => k.toLowerCase() === varName.toLowerCase());
225
- return hit && hit[1] != null ? encodeURIComponent(String(hit[1])) : _match;
226
- });
227
- return path;
228
- }
229
- ensureLeadingSlash(path) {
230
- return path.startsWith('/') ? path : `/${path}`;
231
- }
232
- /**
233
- * Extracts the new record's external ID from a create response. Novi names its keys
234
- * `UniqueID` / `<Object>UniqueId` / `<Object>UniqueID` (e.g. `EventUniqueId`,
235
- * `OrderUniqueID`, `WebhookUniqueId`) rather than a bare `id`, so for body-located IDs
236
- * we probe Novi's conventions first, then fall back to the base's common id names.
237
- * `header` IDs (Location trailing segment) reuse the base behavior.
238
- */
239
- ExtractIDFromResponse(response, idLocation) {
240
- if (!idLocation || idLocation === 'body') {
241
- const body = response.Body;
242
- // Novi may return the created record directly or wrapped in { data: {...} }.
243
- const record = this.asObject(this.NormalizeResponse(body, null)[0]) ?? this.asObject(body);
244
- if (record) {
245
- // Prefer the exact `UniqueID`, then any `*UniqueId`/`*UniqueID` key, then common id names.
246
- const direct = record['UniqueID'] ?? record['uniqueId'] ?? record['uniqueID'];
247
- if (typeof direct === 'string' || typeof direct === 'number')
248
- return String(direct);
249
- for (const [key, value] of Object.entries(record)) {
250
- if (/uniqueid$/i.test(key) && (typeof value === 'string' || typeof value === 'number')) {
251
- return String(value);
252
- }
253
- }
254
- for (const k of ['id', 'ID', 'Id', 'externalID', 'ExternalID']) {
255
- const v = record[k];
256
- if (typeof v === 'string' || typeof v === 'number')
257
- return String(v);
258
- }
259
- }
260
- return undefined;
261
- }
262
- return super.ExtractIDFromResponse(response, idLocation);
263
- }
264
- // ─── Auth + transport (abstract base requirements) ────────────────
265
- async Authenticate(companyIntegration, contextUser) {
266
- if (this.authState)
267
- return this.authState;
268
- const config = await this.parseConfig(companyIntegration, contextUser);
269
- const state = {
270
- APIKey: config.APIKey ?? '',
271
- BaseUrl: this.resolveBaseUrl(config),
272
- Config: config,
273
- };
274
- this.authState = state;
275
- return state;
276
- }
277
- /**
278
- * Builds the Novi auth header. The API key is placed VERBATIM after `Basic ` — this is
279
- * NOT standard HTTP Basic Auth (no base64 of user:password). Documented behavior.
280
- */
281
- BuildHeaders(auth) {
282
- const noviAuth = auth;
283
- return {
284
- 'Authorization': `Basic ${noviAuth.APIKey}`,
285
- 'Accept': 'application/json',
286
- 'Content-Type': 'application/json',
287
- };
288
- }
289
- /**
290
- * Unwraps Novi's response envelopes:
291
- * - List endpoints: `{ TotalCount, Results: [ ... ] }` → the Results array.
292
- * - Single-record detail: `{ data: { ... } }` → a one-element array of `data`.
293
- * - A bare array or bare object is handled as a fallback.
294
- * `responseDataKey` (from the IO metadata) takes precedence when set.
295
- */
296
- NormalizeResponse(rawBody, responseDataKey) {
297
- if (rawBody == null)
298
- return [];
299
- const asObj = this.asObject(rawBody);
300
- // Explicit metadata-declared envelope key wins.
301
- if (responseDataKey && asObj) {
302
- return this.coerceToArray(asObj[responseDataKey]);
303
- }
304
- if (asObj) {
305
- // Novi list envelope.
306
- if ('Results' in asObj)
307
- return this.coerceToArray(asObj.Results);
308
- // Novi single-record detail envelope.
309
- if ('data' in asObj)
310
- return this.coerceToArray(asObj['data']);
311
- // Bare single object.
312
- return [asObj];
313
- }
314
- // Bare array.
315
- if (Array.isArray(rawBody))
316
- return rawBody.filter(this.isRecord);
317
- return [];
318
- }
319
- coerceToArray(node) {
320
- if (Array.isArray(node))
321
- return node.filter(this.isRecord);
322
- if (node && typeof node === 'object')
323
- return [node];
324
- return [];
325
- }
326
- isRecord(node) {
327
- return node != null && typeof node === 'object' && !Array.isArray(node);
328
- }
329
- /**
330
- * Offset pagination: Novi reports `TotalCount` in the list envelope. There are more
331
- * records while `offset + page-size < TotalCount`. When TotalCount is absent, fall
332
- * back to "stop when the page returned fewer than the page size".
333
- */
334
- ExtractPaginationInfo(rawBody, paginationType, currentPage, currentOffset, pageSize) {
335
- if (paginationType !== 'Offset') {
336
- return { HasMore: false, NextPage: currentPage, NextOffset: currentOffset };
337
- }
338
- const asObj = this.asObject(rawBody);
339
- const results = asObj && 'Results' in asObj ? this.coerceToArray(asObj.Results) : [];
340
- const returned = results.length;
341
- const nextOffset = currentOffset + (returned > 0 ? returned : pageSize);
342
- const totalCount = asObj && typeof asObj.TotalCount === 'number'
343
- ? asObj.TotalCount
344
- : undefined;
345
- let hasMore;
346
- if (totalCount != null) {
347
- hasMore = nextOffset < totalCount;
348
- }
349
- else {
350
- hasMore = returned >= pageSize && returned > 0;
351
- }
352
- return {
353
- HasMore: hasMore,
354
- NextPage: currentPage + 1,
355
- NextOffset: nextOffset,
356
- TotalRecords: totalCount,
357
- };
358
- }
359
- /**
360
- * Novi offset pagination uses `pageSize` + `offset` (the base default emits `limit`/`offset`).
361
- * Also emits the IO's `IncrementalWatermarkField` as a request param when this is an
362
- * incremental object and a watermark is in context (fully metadata-driven — never keyed
363
- * off a hardcoded object name).
364
- */
365
- BuildPaginatedURL(basePath, obj, _page, offset, _cursor, effectivePageSize) {
366
- const pageSize = effectivePageSize ?? obj.DefaultPageSize ?? DEFAULT_PAGE_SIZE;
367
- const separator = basePath.includes('?') ? '&' : '?';
368
- const params = new URLSearchParams();
369
- const watermarkField = obj.IncrementalWatermarkField;
370
- if (obj.SupportsIncrementalSync && watermarkField && this.currentWatermark) {
371
- params.set(watermarkField, this.currentWatermark);
372
- }
373
- params.set('pageSize', String(pageSize));
374
- params.set('offset', String(offset));
375
- return `${basePath}${separator}${params.toString()}`;
376
- }
377
- GetBaseURL(_companyIntegration, auth) {
378
- return auth.BaseUrl;
379
- }
380
- // ─── HTTP transport with retry + throttling ───────────────────────
381
- async MakeHTTPRequest(auth, url, method, headers, body) {
382
- const noviAuth = auth;
383
- const cfg = noviAuth.Config;
384
- const maxRetries = cfg.MaxRetries ?? DEFAULT_MAX_RETRIES;
385
- const timeoutMs = cfg.RequestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
386
- const minInterval = cfg.MinRequestIntervalMs ?? DEFAULT_MIN_REQUEST_INTERVAL_MS;
387
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
388
- await this.throttle(minInterval);
389
- try {
390
- const resp = await this.doFetch(url, method, headers, body, timeoutMs);
391
- this.lastRequestTime = Date.now();
392
- if ((resp.Status === 429 || resp.Status === 503) && attempt < maxRetries) {
393
- await this.sleep(this.backoffFromResponse(resp, attempt));
394
- continue;
395
- }
396
- return resp;
397
- }
398
- catch (err) {
399
- if (attempt === maxRetries)
400
- throw err;
401
- if (!this.isRetryableError(err))
402
- throw err;
403
- await this.sleep(this.backoffMs(attempt));
404
- }
405
- }
406
- throw new Error(`Novi AMS request to ${url} exhausted ${maxRetries + 1} attempts`);
407
- }
408
- /** Single fetch() with an AbortController-backed timeout. */
409
- async doFetch(url, method, headers, body, timeoutMs) {
410
- const controller = new AbortController();
411
- const handle = setTimeout(() => controller.abort(), timeoutMs);
412
- try {
413
- const resp = await fetch(url, {
414
- method,
415
- headers,
416
- body: body !== undefined && method !== 'GET' ? JSON.stringify(body) : undefined,
417
- signal: controller.signal,
418
- });
419
- const respHeaders = {};
420
- resp.headers.forEach((value, key) => { respHeaders[key.toLowerCase()] = value; });
421
- const text = await resp.text();
422
- const parsed = text.length > 0 ? this.safeParseJSON(text) : null;
423
- return { Status: resp.status, Body: parsed, Headers: respHeaders };
424
- }
425
- finally {
426
- clearTimeout(handle);
427
- }
428
- }
429
- safeParseJSON(text) {
430
- try {
431
- return JSON.parse(text);
432
- }
433
- catch {
434
- return text;
435
- }
436
- }
437
- isRetryableError(err) {
438
- const msg = err instanceof Error ? err.message : String(err);
439
- return /abort|timeout|ECONNRESET|ENOTFOUND|ETIMEDOUT|ECONNREFUSED|fetch failed|network/i.test(msg);
440
- }
441
- backoffMs(attempt) {
442
- const base = Math.min(1000 * Math.pow(2, attempt), 20000);
443
- const jitter = Math.floor(Math.random() * 500);
444
- return base + jitter;
445
- }
446
- backoffFromResponse(resp, attempt) {
447
- const fromHeader = this.ExtractRetryAfterMs({ Headers: resp.Headers });
448
- if (fromHeader != null)
449
- return Math.min(fromHeader, 30000);
450
- return this.backoffMs(attempt);
451
- }
452
- async throttle(minIntervalMs) {
453
- const elapsed = Date.now() - this.lastRequestTime;
454
- if (elapsed < minIntervalMs)
455
- await this.sleep(minIntervalMs - elapsed);
456
- }
457
- sleep(ms) {
458
- return new Promise(resolve => setTimeout(resolve, ms));
459
- }
460
- asObject(node) {
461
- return node && typeof node === 'object' && !Array.isArray(node) ? node : undefined;
462
- }
463
- // ─── Config parsing ───────────────────────────────────────────────
464
- /**
465
- * Resolves the connection config: the raw API key from the credential store; the
466
- * per-tenant base URL + non-secret overrides from CompanyIntegration.Configuration.
467
- * Secrets are NEVER baked into code.
468
- */
469
- async parseConfig(companyIntegration, contextUser) {
470
- const fromCredential = companyIntegration.CredentialID
471
- ? await this.loadFromCredential(companyIntegration.CredentialID, contextUser)
472
- : null;
473
- const fromConfig = this.parseConfigurationJson(companyIntegration.Configuration);
474
- const merged = { ...fromConfig, ...fromCredential };
475
- // Credential's APIKey wins; tenant host + overrides come from Configuration.
476
- merged.TenantBaseURL = merged.TenantBaseURL ?? fromConfig.TenantBaseURL;
477
- merged.ApiBaseUrl = merged.ApiBaseUrl ?? fromConfig.ApiBaseUrl;
478
- merged.RequestTimeoutMs = merged.RequestTimeoutMs ?? fromConfig.RequestTimeoutMs;
479
- merged.MaxRetries = merged.MaxRetries ?? fromConfig.MaxRetries;
480
- merged.MinRequestIntervalMs = merged.MinRequestIntervalMs ?? fromConfig.MinRequestIntervalMs;
481
- if (!merged.APIKey) {
482
- throw new Error('NoviConnector: an API key (APIKey) must be provided via the credential store.');
483
- }
484
- if (!merged.ApiBaseUrl && !merged.TenantBaseURL) {
485
- throw new Error('NoviConnector: TenantBaseURL must be set on CompanyIntegration.Configuration ' +
486
- '(Novi has no shared host — e.g. "https://www.myassociation.org").');
487
- }
488
- return merged;
489
- }
490
- /** Resolves the per-tenant base host; normalizes a trailing `/api` (resource paths already include it). */
491
- resolveBaseUrl(config) {
492
- const raw = (config.ApiBaseUrl ?? config.TenantBaseURL ?? '').trim();
493
- return raw.replace(/\/+$/, '').replace(/\/api$/i, '');
494
- }
495
- /** Parses the non-secret tenant/overrides config from CompanyIntegration.Configuration JSON. */
496
- parseConfigurationJson(raw) {
497
- if (!raw || raw.trim().length === 0)
498
- return {};
499
- let parsed;
500
- try {
501
- parsed = JSON.parse(raw);
502
- }
503
- catch {
504
- throw new Error('NoviConnector: CompanyIntegration.Configuration is not valid JSON.');
505
- }
506
- const str = (...keys) => {
507
- for (const k of keys) {
508
- const hit = Object.entries(parsed).find(([key]) => key.toLowerCase() === k.toLowerCase());
509
- if (hit && typeof hit[1] === 'string' && hit[1].length > 0)
510
- return hit[1];
511
- }
512
- return undefined;
513
- };
514
- const num = (...keys) => {
515
- for (const k of keys) {
516
- const hit = Object.entries(parsed).find(([key]) => key.toLowerCase() === k.toLowerCase());
517
- if (hit && typeof hit[1] === 'number')
518
- return hit[1];
519
- }
520
- return undefined;
521
- };
522
- return {
523
- APIKey: str('apiKey', 'api_key', 'key'),
524
- TenantBaseURL: str('tenantBaseUrl', 'tenant_base_url', 'baseUrl', 'base_url'),
525
- ApiBaseUrl: str('apiBaseUrl', 'api_base_url'),
526
- RequestTimeoutMs: num('requestTimeoutMs'),
527
- MaxRetries: num('maxRetries'),
528
- MinRequestIntervalMs: num('minRequestIntervalMs'),
529
- };
530
- }
531
- /** Loads the raw API key from the MJ credential store. */
532
- async loadFromCredential(credentialID, contextUser, provider) {
533
- const md = provider ?? new Metadata();
534
- const credential = await md.GetEntityObject('MJ: Credentials', contextUser);
535
- const loaded = await credential.Load(credentialID);
536
- if (!loaded || !credential.Values)
537
- return null;
538
- let raw;
539
- try {
540
- raw = JSON.parse(credential.Values);
541
- }
542
- catch {
543
- return null;
544
- }
545
- const get = (...keys) => {
546
- for (const k of keys) {
547
- const hit = Object.entries(raw).find(([key]) => key.toLowerCase() === k.toLowerCase());
548
- if (hit && typeof hit[1] === 'string')
549
- return hit[1];
550
- }
551
- return undefined;
552
- };
553
- return {
554
- APIKey: get('APIKey', 'apiKey', 'api_key', 'key'),
555
- // A credential MAY also carry the tenant host (single source of truth for a connection).
556
- TenantBaseURL: get('TenantBaseURL', 'tenantBaseUrl', 'baseUrl', 'base_url'),
557
- };
558
- }
559
- };
560
- NoviConnector = __decorate([
561
- RegisterClass(BaseIntegrationConnector, 'NoviConnector')
562
- ], NoviConnector);
563
- export { NoviConnector };
564
- /** Tree-shaking prevention function — import and call from the package entry point. */
565
- export function LoadNoviConnector() { }
566
- //# sourceMappingURL=NoviConnector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NoviConnector.js","sourceRoot":"","sources":["../src/NoviConnector.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAyC,MAAM,sBAAsB,CAAC;AAEvF,OAAO,EACH,wBAAwB,EACxB,4BAA4B,GAW/B,MAAM,oCAAoC,CAAC;AAoD5C,yEAAyE;AAEzE,MAAM,0BAA0B,GAAG,KAAK,CAAC;AACzC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,uFAAuF;AACvF,MAAM,+BAA+B,GAAG,EAAE,CAAC;AAC3C,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,4GAA4G;AAC5G,MAAM,yBAAyB,GAAG,EAAE,CAAC;AACrC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B,yEAAyE;AAEzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEI,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,4BAA4B;IAAxD;;QAEH,gEAAgE;QACxD,cAAS,GAA2B,IAAI,CAAC;QACjD,mEAAmE;QAC3D,oBAAe,GAAG,CAAC,CAAC;IA4kBhC,CAAC;IAxkBG,uEAAuE;IAEvE,yFAAyF;IACzF,IAAoB,eAAe,KAAa,OAAO,UAAU,CAAC,CAAC,CAAC;IAEpE,iFAAiF;IACjF,oFAAoF;IACpF,mFAAmF;IACnF,qEAAqE;IACrE,IAAoB,cAAc,KAAc,OAAO,IAAI,CAAC,CAAC,CAAC;IAC9D,IAAoB,cAAc,KAAc,OAAO,IAAI,CAAC,CAAC,CAAC;IAC9D,IAAoB,cAAc,KAAc,OAAO,IAAI,CAAC,CAAC,CAAC;IAE9D,uEAAuE;IAEvE;;;OAGG;IACH,IAAoB,eAAe;QAC/B,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,GAAG,EAAE,CAAC;IAC5G,CAAC;IAED,sFAAsF;IACtE,mBAAmB,CAAC,KAAc;QAC9C,MAAM,OAAO,GAAI,KAA8C,EAAE,OAAO,CAAC;QACzE,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAC/B,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;QACpE,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAChF,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAClC,IAAI,KAAK,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;QAChC,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,oEAAoE;IAEpE;;;OAGG;IACI,KAAK,CAAC,cAAc,CACvB,kBAA8C,EAC9C,WAAqB;QAErB,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,WAAW,CAAoB,CAAC;YACzF,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,OAAO,kCAAkC,CAAC;YACnE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YACxE,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC7C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,wCAAwC,IAAI,CAAC,MAAM,qBAAqB,EAAE,CAAC;YACjH,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;gBACrB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,wCAAwC,IAAI,CAAC,MAAM,iBAAiB,EAAE,CAAC;YAC7G,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;gBAC1C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,0BAA0B,IAAI,CAAC,MAAM,SAAS,QAAQ,EAAE,EAAE,CAAC;YACjG,CAAC;YACD,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,4BAA4B,IAAI,CAAC,OAAO,EAAE;gBACnD,aAAa,EAAE,mBAAmB;aACrC,CAAC;QACN,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,OAAO,EAAE,EAAE,CAAC;QACxE,CAAC;IACL,CAAC;IAED,qEAAqE;IAErE;;;;;OAKG;IACa,KAAK,CAAC,YAAY,CAAC,GAAiB;QAChD,IAAI,CAAC,gBAAgB,GAAG,GAAG,CAAC,cAAc,IAAI,SAAS,CAAC;QAExD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAE7C,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,kBAAkB,CAAC,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;QACvF,IAAI,GAAG,CAAC,uBAAuB,IAAI,GAAG,CAAC,yBAAyB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClF,MAAM,QAAQ,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,yBAAyB,CAAC,CAAC;YAC5F,MAAM,YAAY,GAAG,QAAQ,IAAI,GAAG,CAAC,cAAc,IAAI,SAAS,CAAC;YACjE,IAAI,YAAY,IAAI,IAAI;gBAAE,OAAO,EAAE,GAAG,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,CAAC;QACpF,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;;;OAKG;IACK,sBAAsB,CAC1B,OAA8C,EAC9C,eAAuB;QAEvB,0EAA0E;QAC1E,MAAM,UAAU,GAAG;YACf,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB;YAC5E,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe;YAChE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM;SAC3C,CAAC;QACF,IAAI,MAAM,GAAgB,IAAI,CAAC;QAC/B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YACxB,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;gBAC9B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAS;gBAC1D,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;gBACxB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,GAAG,MAAM,CAAC;oBAAE,MAAM,GAAG,CAAC,CAAC;YAC3E,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAChD,CAAC;IAED,sEAAsE;IAEtE;;;;;OAKG;IACa,KAAK,CAAC,YAAY,CAAC,GAAwB;QACvD,MAAM,EAAE,GAAG,GAAG,CAAC,kBAAgD,CAAC;QAChE,MAAM,WAAW,GAAG,GAAG,CAAC,WAAuB,CAAC;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;QACnE,IAAI,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACX,mCAAmC,GAAG,CAAC,UAAU,KAAK;gBACtD,mEAAmE,CACtE,CAAC;QACN,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,WAAW,CAAoB,CAAC;QACzE,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAExC,mFAAmF;QACnF,uFAAuF;QACvF,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;QAC/F,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;QAEtE,0EAA0E;QAC1E,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QAEhE,+FAA+F;QAC/F,MAAM,MAAM,GAA4B,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QAElF,iCAAiC;QACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1F,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC;QACtF,CAAC;QACD,OAAO;YACH,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,QAAQ,CAAC,MAAM;YAC3B,YAAY,EAAE,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,QAAQ,QAAQ,CAAC,MAAM,YAAY;SAC1F,CAAC;IACN,CAAC;IAED,6EAA6E;IACrE,KAAK,CAAC,gBAAgB,CAC1B,IAAqB,EACrB,GAAW,EACX,OAA+B;QAE/B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACnE,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QACrC,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YAC1C,MAAM,MAAM,CAAC,MAAM,CACf,IAAI,KAAK,CAAC,0CAA0C,IAAI,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC,EAC7E,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CACjD,CAAC;QACN,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,CAAC;IAED;;;OAGG;IACK,iBAAiB,CACrB,QAAgB,EAChB,UAAkB,EAClB,UAAmC;QAEnC,MAAM,SAAS,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,IAAI,GAAG,QAAQ;aACd,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC;aAC7B,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC;aAC7B,OAAO,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;QAC3C,gFAAgF;QAChF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAe,EAAE,EAAE;YAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;YAChG,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/E,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,kBAAkB,CAAC,IAAY;QACnC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IACpD,CAAC;IAED;;;;;;OAMG;IACgB,qBAAqB,CAAC,QAAsB,EAAE,UAAyB;QACtF,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;YAC3B,6EAA6E;YAC7E,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3F,IAAI,MAAM,EAAE,CAAC;gBACT,2FAA2F;gBAC3F,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC9E,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ;oBAAE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;gBACpF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBAChD,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,EAAE,CAAC;wBACrF,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;oBACzB,CAAC;gBACL,CAAC;gBACD,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,CAAC;oBAC7D,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;oBACpB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ;wBAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;gBACzE,CAAC;YACL,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,OAAO,KAAK,CAAC,qBAAqB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC7D,CAAC;IAED,qEAAqE;IAE3D,KAAK,CAAC,YAAY,CACxB,kBAA8C,EAC9C,WAAqB;QAErB,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;QACvE,MAAM,KAAK,GAAoB;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;YAC3B,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;YACpC,MAAM,EAAE,MAAM;SACjB,CAAC;QACF,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;;OAGG;IACO,YAAY,CAAC,IAAqB;QACxC,MAAM,QAAQ,GAAG,IAAuB,CAAC;QACzC,OAAO;YACH,eAAe,EAAE,SAAS,QAAQ,CAAC,MAAM,EAAE;YAC3C,QAAQ,EAAE,kBAAkB;YAC5B,cAAc,EAAE,kBAAkB;SACrC,CAAC;IACN,CAAC;IAED;;;;;;OAMG;IACO,iBAAiB,CAAC,OAAgB,EAAE,eAA8B;QACxE,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAErC,gDAAgD;QAChD,IAAI,eAAe,IAAI,KAAK,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,KAAK,EAAE,CAAC;YACR,sBAAsB;YACtB,IAAI,SAAS,IAAI,KAAK;gBAAE,OAAO,IAAI,CAAC,aAAa,CAAE,KAA0B,CAAC,OAAO,CAAC,CAAC;YACvF,sCAAsC;YACtC,IAAI,MAAM,IAAI,KAAK;gBAAE,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAC9D,sBAAsB;YACtB,OAAO,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;QACD,cAAc;QACd,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAA8B,CAAC;QAC9F,OAAO,EAAE,CAAC;IACd,CAAC;IAEO,aAAa,CAAC,IAAa;QAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAA8B,CAAC;QACxF,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,CAAC,IAA+B,CAAC,CAAC;QAC/E,OAAO,EAAE,CAAC;IACd,CAAC;IAEO,QAAQ,CAAC,IAAa;QAC1B,OAAO,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,CAAC;IAED;;;;OAIG;IACO,qBAAqB,CAC3B,OAAgB,EAChB,cAA8B,EAC9B,WAAmB,EACnB,aAAqB,EACrB,QAAgB;QAEhB,IAAI,cAAc,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;QAChF,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAE,KAA0B,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3G,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;QAChC,MAAM,UAAU,GAAG,aAAa,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAExE,MAAM,UAAU,GAAG,KAAK,IAAI,OAAQ,KAA0B,CAAC,UAAU,KAAK,QAAQ;YAClF,CAAC,CAAE,KAA0B,CAAC,UAAoB;YAClD,CAAC,CAAC,SAAS,CAAC;QAEhB,IAAI,OAAgB,CAAC;QACrB,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACrB,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;QACtC,CAAC;aAAM,CAAC;YACJ,OAAO,GAAG,QAAQ,IAAI,QAAQ,IAAI,QAAQ,GAAG,CAAC,CAAC;QACnD,CAAC;QACD,OAAO;YACH,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE,WAAW,GAAG,CAAC;YACzB,UAAU,EAAE,UAAU;YACtB,YAAY,EAAE,UAAU;SAC3B,CAAC;IACN,CAAC;IAED;;;;;OAKG;IACgB,iBAAiB,CAChC,QAAgB,EAChB,GAA8B,EAC9B,KAAa,EACb,MAAc,EACd,OAAgB,EAChB,iBAA0B;QAE1B,MAAM,QAAQ,GAAG,iBAAiB,IAAI,GAAG,CAAC,eAAe,IAAI,iBAAiB,CAAC;QAC/E,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QAErC,MAAM,cAAc,GAAG,GAAG,CAAC,yBAAyB,CAAC;QACrD,IAAI,GAAG,CAAC,uBAAuB,IAAI,cAAc,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACzE,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAErC,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IACzD,CAAC;IAES,UAAU,CAChB,mBAA+C,EAC/C,IAAqB;QAErB,OAAQ,IAAwB,CAAC,OAAO,CAAC;IAC7C,CAAC;IAED,qEAAqE;IAE3D,KAAK,CAAC,eAAe,CAC3B,IAAqB,EACrB,GAAW,EACX,MAAc,EACd,OAA+B,EAC/B,IAAc;QAEd,MAAM,QAAQ,GAAG,IAAuB,CAAC;QACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC5B,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,IAAI,mBAAmB,CAAC;QACzD,MAAM,SAAS,GAAG,GAAG,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;QACrE,MAAM,WAAW,GAAG,GAAG,CAAC,oBAAoB,IAAI,+BAA+B,CAAC;QAEhF,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;YACrD,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YACjC,IAAI,CAAC;gBACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;gBACvE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAElC,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;oBACvE,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;oBAC1D,SAAS;gBACb,CAAC;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACpB,IAAI,OAAO,KAAK,UAAU;oBAAE,MAAM,GAAG,CAAC;gBACtC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;oBAAE,MAAM,GAAG,CAAC;gBAC3C,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YAC9C,CAAC;QACL,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,cAAc,UAAU,GAAG,CAAC,WAAW,CAAC,CAAC;IACvF,CAAC;IAED,6DAA6D;IACrD,KAAK,CAAC,OAAO,CACjB,GAAW,EACX,MAAc,EACd,OAA+B,EAC/B,IAAa,EACb,SAAiB;QAEjB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;QAC/D,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC1B,MAAM;gBACN,OAAO;gBACP,IAAI,EAAE,IAAI,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC/E,MAAM,EAAE,UAAU,CAAC,MAAM;aAC5B,CAAC,CAAC;YACH,MAAM,WAAW,GAA2B,EAAE,CAAC;YAC/C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAClF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QACvE,CAAC;gBAAS,CAAC;YACP,YAAY,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,IAAY;QAC9B,IAAI,CAAC;YAAC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;IACtE,CAAC;IAEO,gBAAgB,CAAC,GAAY;QACjC,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,iFAAiF,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvG,CAAC;IAEO,SAAS,CAAC,OAAe;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;QAC/C,OAAO,IAAI,GAAG,MAAM,CAAC;IACzB,CAAC;IAEO,mBAAmB,CAAC,IAAkB,EAAE,OAAe;QAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE,IAAI,UAAU,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,aAAqB;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC;QAClD,IAAI,OAAO,GAAG,aAAa;YAAE,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,OAAO,CAAC,CAAC;IAC3E,CAAC;IAEO,KAAK,CAAC,EAAU;QACpB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IAEO,QAAQ,CAAC,IAAa;QAC1B,OAAO,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAA+B,CAAC,CAAC,CAAC,SAAS,CAAC;IAClH,CAAC;IAED,qEAAqE;IAErE;;;;OAIG;IACK,KAAK,CAAC,WAAW,CACrB,kBAA8C,EAC9C,WAAqB;QAErB,MAAM,cAAc,GAAG,kBAAkB,CAAC,YAAY;YAClD,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,YAAY,EAAE,WAAW,CAAC;YAC7E,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,UAAU,GAAG,IAAI,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;QAEjF,MAAM,MAAM,GAAyB,EAAE,GAAG,UAAU,EAAE,GAAG,cAAc,EAAE,CAAC;QAC1E,6EAA6E;QAC7E,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,UAAU,CAAC,aAAa,CAAC;QACxE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC;QAC/D,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,UAAU,CAAC,gBAAgB,CAAC;QACjF,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC;QAC/D,MAAM,CAAC,oBAAoB,GAAG,MAAM,CAAC,oBAAoB,IAAI,UAAU,CAAC,oBAAoB,CAAC;QAE7F,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAC;QACrG,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACX,+EAA+E;gBAC/E,mEAAmE,CACtE,CAAC;QACN,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,2GAA2G;IACnG,cAAc,CAAC,MAA4B;QAC/C,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACrE,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,gGAAgG;IACxF,sBAAsB,CAAC,GAAkB;QAC7C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAC/C,IAAI,MAA+B,CAAC;QACpC,IAAI,CAAC;YACD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACL,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QAC1F,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,GAAG,IAAc,EAAsB,EAAE;YAClD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC1F,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;oBAAE,OAAO,GAAG,CAAC,CAAC,CAAW,CAAC;YACxF,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC,CAAC;QACF,MAAM,GAAG,GAAG,CAAC,GAAG,IAAc,EAAsB,EAAE;YAClD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC1F,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ;oBAAE,OAAO,GAAG,CAAC,CAAC,CAAW,CAAC;YACnE,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC,CAAC;QACF,OAAO;YACH,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;YACvC,aAAa,EAAE,GAAG,CAAC,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,UAAU,CAAC;YAC7E,UAAU,EAAE,GAAG,CAAC,YAAY,EAAE,cAAc,CAAC;YAC7C,gBAAgB,EAAE,GAAG,CAAC,kBAAkB,CAAC;YACzC,UAAU,EAAE,GAAG,CAAC,YAAY,CAAC;YAC7B,oBAAoB,EAAE,GAAG,CAAC,sBAAsB,CAAC;SACpD,CAAC;IACN,CAAC;IAED,0DAA0D;IAClD,KAAK,CAAC,kBAAkB,CAC5B,YAAoB,EACpB,WAAqB,EACrB,QAA4B;QAE5B,MAAM,EAAE,GAAG,QAAQ,IAAI,IAAI,QAAQ,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,eAAe,CAAqB,iBAAiB,EAAE,WAAW,CAAC,CAAC;QAChG,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAC/C,IAAI,GAA4B,CAAC;QACjC,IAAI,CAAC;YACD,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAA4B,CAAC;QACnE,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,GAAG,IAAc,EAAsB,EAAE;YAClD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;gBACvF,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ;oBAAE,OAAO,GAAG,CAAC,CAAC,CAAW,CAAC;YACnE,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC,CAAC;QACF,OAAO;YACH,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;YACjD,yFAAyF;YACzF,aAAa,EAAE,GAAG,CAAC,eAAe,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,CAAC;SAC9E,CAAC;IACN,CAAC;CACJ,CAAA;AAjlBY,aAAa;IADzB,aAAa,CAAC,wBAAwB,EAAE,eAAe,CAAC;GAC5C,aAAa,CAilBzB;;AAED,uFAAuF;AACvF,MAAM,UAAU,iBAAiB,KAAuB,CAAC"}