local-serverless-stack 0.0.8 → 0.0.10

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.
@@ -0,0 +1,239 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { DynamoDBClient, ListTablesCommand, DescribeTableCommand, BatchWriteItemCommand, ScanCommand, } from '@aws-sdk/client-dynamodb';
4
+ import { marshall } from '@aws-sdk/util-dynamodb';
5
+ import { LocalStackManager } from './localstack-manager.js';
6
+ import { ConfigManager } from './config-manager.js';
7
+ const BATCH_LIMIT = 25;
8
+ export class SeedManager {
9
+ static instance;
10
+ dynamoClient;
11
+ currentRegion = 'us-east-1';
12
+ constructor() {
13
+ this.initializeClient(this.currentRegion);
14
+ }
15
+ static getInstance() {
16
+ if (!SeedManager.instance) {
17
+ SeedManager.instance = new SeedManager();
18
+ }
19
+ return SeedManager.instance;
20
+ }
21
+ initializeClient(region) {
22
+ const baseConfig = LocalStackManager.getInstance().getConfig();
23
+ this.dynamoClient = new DynamoDBClient({ ...baseConfig, region });
24
+ this.currentRegion = region;
25
+ }
26
+ setRegion(region) {
27
+ if (region && region !== this.currentRegion) {
28
+ this.initializeClient(region);
29
+ }
30
+ }
31
+ getSeedsDir() {
32
+ return ConfigManager.getInstance().getSeedsDir();
33
+ }
34
+ seedFilePath(tableName) {
35
+ return path.join(this.getSeedsDir(), `${tableName}.json`);
36
+ }
37
+ readSeedFile(tableName) {
38
+ const file = this.seedFilePath(tableName);
39
+ if (!fs.existsSync(file))
40
+ return null;
41
+ try {
42
+ const raw = fs.readFileSync(file, 'utf-8');
43
+ const parsed = JSON.parse(raw);
44
+ if (!Array.isArray(parsed)) {
45
+ throw new Error('seed file must contain a JSON array of items');
46
+ }
47
+ return parsed;
48
+ }
49
+ catch (error) {
50
+ const msg = error instanceof Error ? error.message : 'unknown error';
51
+ throw new Error(`Failed to read seed file ${file}: ${msg}`);
52
+ }
53
+ }
54
+ hasSeedFile(tableName) {
55
+ return fs.existsSync(this.seedFilePath(tableName));
56
+ }
57
+ async list() {
58
+ const dir = this.getSeedsDir();
59
+ if (!fs.existsSync(dir))
60
+ return [];
61
+ const liveTables = new Set(await this.listTables());
62
+ const files = fs.readdirSync(dir).filter(f => f.endsWith('.json'));
63
+ return files.map(file => {
64
+ const tableName = file.slice(0, -5);
65
+ let itemCount = 0;
66
+ try {
67
+ const items = this.readSeedFile(tableName);
68
+ itemCount = items?.length ?? 0;
69
+ }
70
+ catch {
71
+ itemCount = -1;
72
+ }
73
+ return {
74
+ tableName,
75
+ file: path.join(dir, file),
76
+ itemCount,
77
+ tableExists: liveTables.has(tableName),
78
+ };
79
+ });
80
+ }
81
+ async seedTable(tableName) {
82
+ const items = this.readSeedFile(tableName);
83
+ if (items === null) {
84
+ return { tableName, inserted: 0, skipped: true, reason: 'no seed file' };
85
+ }
86
+ if (items.length === 0) {
87
+ return { tableName, inserted: 0, skipped: true, reason: 'empty seed file' };
88
+ }
89
+ const requests = items.map((item, idx) => {
90
+ if (item === null || typeof item !== 'object' || Array.isArray(item)) {
91
+ throw new Error(`Item at index ${idx} in ${tableName}.json is not a plain object`);
92
+ }
93
+ return {
94
+ PutRequest: {
95
+ Item: marshall(item, {
96
+ removeUndefinedValues: true,
97
+ convertClassInstanceToMap: true,
98
+ }),
99
+ },
100
+ };
101
+ });
102
+ let inserted = 0;
103
+ for (let i = 0; i < requests.length; i += BATCH_LIMIT) {
104
+ const chunk = requests.slice(i, i + BATCH_LIMIT);
105
+ await this.writeBatchWithRetry(tableName, chunk);
106
+ inserted += chunk.length;
107
+ }
108
+ console.log(` ✓ Seeded ${inserted} item(s) into ${tableName}`);
109
+ return { tableName, inserted };
110
+ }
111
+ async seedAll() {
112
+ const entries = await this.list();
113
+ const results = await Promise.all(entries.map(async (entry) => {
114
+ if (!entry.tableExists) {
115
+ return {
116
+ tableName: entry.tableName,
117
+ inserted: 0,
118
+ skipped: true,
119
+ reason: 'table does not exist in LocalStack',
120
+ };
121
+ }
122
+ try {
123
+ return await this.seedTable(entry.tableName);
124
+ }
125
+ catch (error) {
126
+ const msg = error instanceof Error ? error.message : 'unknown error';
127
+ console.warn(`[seed] ${entry.tableName}: ${msg}`);
128
+ return { tableName: entry.tableName, inserted: 0, skipped: true, reason: msg };
129
+ }
130
+ }));
131
+ return results;
132
+ }
133
+ async clearTable(tableName) {
134
+ const keyAttrs = await this.getTableKeyAttributes(tableName);
135
+ if (!keyAttrs) {
136
+ return { tableName, deleted: 0, skipped: true, reason: 'table not found' };
137
+ }
138
+ let deleted = 0;
139
+ let exclusiveStartKey;
140
+ do {
141
+ const scan = await this.dynamoClient.send(new ScanCommand({
142
+ TableName: tableName,
143
+ ProjectionExpression: keyAttrs.map((_, i) => `#k${i}`).join(', '),
144
+ ExpressionAttributeNames: Object.fromEntries(keyAttrs.map((attr, i) => [`#k${i}`, attr])),
145
+ ExclusiveStartKey: exclusiveStartKey,
146
+ }));
147
+ const items = scan.Items ?? [];
148
+ for (let i = 0; i < items.length; i += BATCH_LIMIT) {
149
+ const chunk = items.slice(i, i + BATCH_LIMIT).map(item => {
150
+ const key = {};
151
+ for (const attr of keyAttrs) {
152
+ if (item[attr] !== undefined)
153
+ key[attr] = item[attr];
154
+ }
155
+ return { DeleteRequest: { Key: key } };
156
+ });
157
+ await this.writeBatchWithRetry(tableName, chunk);
158
+ deleted += chunk.length;
159
+ }
160
+ exclusiveStartKey = scan.LastEvaluatedKey;
161
+ } while (exclusiveStartKey);
162
+ console.log(` ✓ Cleared ${deleted} item(s) from ${tableName}`);
163
+ return { tableName, deleted };
164
+ }
165
+ async clearAllSeeded() {
166
+ const entries = await this.list();
167
+ const results = [];
168
+ for (const entry of entries) {
169
+ if (!entry.tableExists) {
170
+ results.push({
171
+ tableName: entry.tableName,
172
+ deleted: 0,
173
+ skipped: true,
174
+ reason: 'table does not exist in LocalStack',
175
+ });
176
+ continue;
177
+ }
178
+ try {
179
+ results.push(await this.clearTable(entry.tableName));
180
+ }
181
+ catch (error) {
182
+ const msg = error instanceof Error ? error.message : 'unknown error';
183
+ console.warn(`[seed:clear] ${entry.tableName}: ${msg}`);
184
+ results.push({ tableName: entry.tableName, deleted: 0, skipped: true, reason: msg });
185
+ }
186
+ }
187
+ return results;
188
+ }
189
+ /**
190
+ * Background fire-and-forget seeding triggered when a table is provisioned.
191
+ * Never throws — logs warnings instead so it cannot break the provisioner.
192
+ */
193
+ seedOnTableCreated(tableName) {
194
+ if (!this.hasSeedFile(tableName))
195
+ return;
196
+ this.seedTable(tableName).catch(error => {
197
+ const msg = error instanceof Error ? error.message : 'unknown error';
198
+ console.warn(`[seed] auto-seed for ${tableName} failed: ${msg}`);
199
+ });
200
+ }
201
+ async listTables() {
202
+ try {
203
+ const res = await this.dynamoClient.send(new ListTablesCommand({}));
204
+ return res.TableNames ?? [];
205
+ }
206
+ catch {
207
+ return [];
208
+ }
209
+ }
210
+ async getTableKeyAttributes(tableName) {
211
+ try {
212
+ const res = await this.dynamoClient.send(new DescribeTableCommand({ TableName: tableName }));
213
+ const keys = res.Table?.KeySchema?.map(k => k.AttributeName).filter(Boolean) ?? [];
214
+ return keys.length > 0 ? keys : null;
215
+ }
216
+ catch {
217
+ return null;
218
+ }
219
+ }
220
+ // BatchWriteItem returns UnprocessedItems on throttling/partial failures.
221
+ // Retry them with exponential backoff so we don't silently drop writes.
222
+ async writeBatchWithRetry(tableName, requests) {
223
+ let pending = requests;
224
+ let attempt = 0;
225
+ while (pending.length > 0) {
226
+ const res = await this.dynamoClient.send(new BatchWriteItemCommand({ RequestItems: { [tableName]: pending } }));
227
+ const unprocessed = res.UnprocessedItems?.[tableName] ?? [];
228
+ if (unprocessed.length === 0)
229
+ return;
230
+ attempt++;
231
+ if (attempt > 5) {
232
+ throw new Error(`BatchWriteItem left ${unprocessed.length} unprocessed item(s) after 5 retries`);
233
+ }
234
+ await new Promise(r => setTimeout(r, 100 * Math.pow(2, attempt)));
235
+ pending = unprocessed;
236
+ }
237
+ }
238
+ }
239
+ //# sourceMappingURL=seed-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-manager.js","sourceRoot":"","sources":["../../../src/server/services/seed-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,WAAW,GAGZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,WAAW,GAAG,EAAE,CAAC;AAuBvB,MAAM,OAAO,WAAW;IACd,MAAM,CAAC,QAAQ,CAAc;IAC7B,YAAY,CAAkB;IAC9B,aAAa,GAAW,WAAW,CAAC;IAE5C;QACE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC1B,WAAW,CAAC,QAAQ,GAAG,IAAI,WAAW,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO,WAAW,CAAC,QAAQ,CAAC;IAC9B,CAAC;IAEO,gBAAgB,CAAC,MAAc;QACrC,MAAM,UAAU,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,CAAC;QAC/D,IAAI,CAAC,YAAY,GAAG,IAAI,cAAc,CAAC,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;IAC9B,CAAC;IAED,SAAS,CAAC,MAAc;QACtB,IAAI,MAAM,IAAI,MAAM,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;YAC5C,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAEO,WAAW;QACjB,OAAO,aAAa,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,CAAC;IAEO,YAAY,CAAC,SAAiB;QACpC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;IAC5D,CAAC;IAEO,YAAY,CAAC,SAAiB;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAClE,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACrE,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,WAAW,CAAC,SAAiB;QAC3B,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QAEnC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QAEnE,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YACtB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACpC,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;gBAC3C,SAAS,GAAG,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC;YACjC,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS,GAAG,CAAC,CAAC,CAAC;YACjB,CAAC;YACD,OAAO;gBACL,SAAS;gBACT,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC;gBAC1B,SAAS;gBACT,WAAW,EAAE,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;aACvC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,SAAiB;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QAC3E,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;QAC9E,CAAC;QAED,MAAM,QAAQ,GAAmB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACvD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrE,MAAM,IAAI,KAAK,CAAC,iBAAiB,GAAG,OAAO,SAAS,6BAA6B,CAAC,CAAC;YACrF,CAAC;YACD,OAAO;gBACL,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ,CAAC,IAA+B,EAAE;wBAC9C,qBAAqB,EAAE,IAAI;wBAC3B,yBAAyB,EAAE,IAAI;qBAChC,CAAmC;iBACrC;aACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC;YACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC;YACjD,MAAM,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACjD,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC;QAC3B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,cAAc,QAAQ,iBAAiB,SAAS,EAAE,CAAC,CAAC;QAChE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;YACxB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBACvB,OAAO;oBACL,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,QAAQ,EAAE,CAAC;oBACX,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,oCAAoC;iBAC/B,CAAC;YAClB,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAC/C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;gBACrE,OAAO,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,SAAS,KAAK,GAAG,EAAE,CAAC,CAAC;gBAClD,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;YACjF,CAAC;QACH,CAAC,CAAC,CACH,CAAC;QACF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;QAC7E,CAAC;QAED,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,iBAA6D,CAAC;QAElE,GAAG,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CACvC,IAAI,WAAW,CAAC;gBACd,SAAS,EAAE,SAAS;gBACpB,oBAAoB,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;gBACjE,wBAAwB,EAAE,MAAM,CAAC,WAAW,CAC1C,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAC5C;gBACD,iBAAiB,EAAE,iBAAiB;aACrC,CAAC,CACH,CAAC;YAEF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC;gBACnD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;oBACvD,MAAM,GAAG,GAAmC,EAAE,CAAC;oBAC/C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;wBAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,SAAS;4BAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;oBACvD,CAAC;oBACD,OAAO,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAkB,CAAC;gBACzD,CAAC,CAAC,CAAC;gBACH,MAAM,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;gBACjD,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC;YAC1B,CAAC;YAED,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC5C,CAAC,QAAQ,iBAAiB,EAAE;QAE5B,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,iBAAiB,SAAS,EAAE,CAAC,CAAC;QAChE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClC,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC;oBACX,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,OAAO,EAAE,CAAC;oBACV,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,oCAAoC;iBAC7C,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YACvD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;gBACrE,OAAO,CAAC,IAAI,CAAC,gBAAgB,KAAK,CAAC,SAAS,KAAK,GAAG,EAAE,CAAC,CAAC;gBACxD,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACvF,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAAC,SAAiB;QAClC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;YAAE,OAAO;QACzC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;YACtC,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,wBAAwB,SAAS,YAAY,GAAG,EAAE,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;YACpE,OAAO,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,SAAiB;QACnD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CACtC,IAAI,oBAAoB,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CACnD,CAAC;YACF,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAc,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpF,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,wEAAwE;IAChE,KAAK,CAAC,mBAAmB,CAAC,SAAiB,EAAE,QAAwB;QAC3E,IAAI,OAAO,GAAG,QAAQ,CAAC;QACvB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CACtC,IAAI,qBAAqB,CAAC,EAAE,YAAY,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CACtE,CAAC;YACF,MAAM,WAAW,GAAG,GAAG,CAAC,gBAAgB,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YAC5D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YACrC,OAAO,EAAE,CAAC;YACV,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CACb,uBAAuB,WAAW,CAAC,MAAM,sCAAsC,CAChF,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YAClE,OAAO,GAAG,WAAW,CAAC;QACxB,CAAC;IACH,CAAC;CACF"}