@shakenbake/linear 0.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.
@@ -0,0 +1,355 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const core_1 = require("@shakenbake/core");
5
+ const adapter_js_1 = require("../adapter.js");
6
+ // ---- Helpers ----
7
+ function makeConfig(overrides) {
8
+ return {
9
+ apiKey: 'lin_api_test_key',
10
+ teamId: 'team-123',
11
+ ...overrides,
12
+ };
13
+ }
14
+ /** Create a successful GraphQL JSON response. */
15
+ function graphqlResponse(data) {
16
+ return new Response(JSON.stringify({ data }), {
17
+ status: 200,
18
+ headers: { 'Content-Type': 'application/json' },
19
+ });
20
+ }
21
+ /** Create a successful PUT response. */
22
+ function putResponse() {
23
+ return new Response(null, { status: 200 });
24
+ }
25
+ /** Standard file upload response data with headers. */
26
+ function fileUploadData(index, headers = []) {
27
+ return {
28
+ fileUpload: {
29
+ success: true,
30
+ uploadFile: {
31
+ uploadUrl: `https://uploads.linear.app/upload-${String(index)}`,
32
+ assetUrl: `https://assets.linear.app/asset-${String(index)}`,
33
+ headers,
34
+ },
35
+ },
36
+ };
37
+ }
38
+ /** Extract the request init from a fetch mock call. */
39
+ function getCallInit(
40
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
+ calls, index) {
42
+ const call = calls[index];
43
+ if (!call)
44
+ throw new Error(`No fetch call at index ${String(index)}`);
45
+ return call[1];
46
+ }
47
+ /** Extract the URL from a fetch mock call. */
48
+ function getCallUrl(
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
+ calls, index) {
51
+ const call = calls[index];
52
+ if (!call)
53
+ throw new Error(`No fetch call at index ${String(index)}`);
54
+ return call[0];
55
+ }
56
+ // ---- Tests ----
57
+ (0, vitest_1.describe)('uploadImage', () => {
58
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
+ let fetchMock;
60
+ (0, vitest_1.beforeEach)(() => {
61
+ fetchMock = vitest_1.vi.spyOn(globalThis, 'fetch');
62
+ });
63
+ (0, vitest_1.afterEach)(() => {
64
+ vitest_1.vi.restoreAllMocks();
65
+ });
66
+ // == Happy path ==
67
+ (0, vitest_1.describe)('successful upload', () => {
68
+ (0, vitest_1.it)('calls requestUploadUrl then PUTs to signed URL', async () => {
69
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
70
+ fetchMock.mockResolvedValueOnce(putResponse());
71
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
72
+ await adapter.uploadImage(Buffer.from('image-data'), 'test.png');
73
+ // First call is the fileUpload GraphQL mutation
74
+ (0, vitest_1.expect)(fetchMock).toHaveBeenCalledTimes(2);
75
+ (0, vitest_1.expect)(getCallUrl(fetchMock.mock.calls, 0)).toBe('https://api.linear.app/graphql');
76
+ // Second call is the PUT to the signed URL
77
+ (0, vitest_1.expect)(getCallUrl(fetchMock.mock.calls, 1)).toBe('https://uploads.linear.app/upload-1');
78
+ const putInit = getCallInit(fetchMock.mock.calls, 1);
79
+ (0, vitest_1.expect)(putInit.method).toBe('PUT');
80
+ });
81
+ (0, vitest_1.it)('returns assetUrl on success', async () => {
82
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
83
+ fetchMock.mockResolvedValueOnce(putResponse());
84
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
85
+ const url = await adapter.uploadImage(Buffer.from('image-data'), 'screenshot.png');
86
+ (0, vitest_1.expect)(url).toBe('https://assets.linear.app/asset-1');
87
+ });
88
+ (0, vitest_1.it)('handles Buffer input correctly', async () => {
89
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
90
+ fetchMock.mockResolvedValueOnce(putResponse());
91
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
92
+ const imageBuffer = Buffer.from('test-buffer-data');
93
+ const url = await adapter.uploadImage(imageBuffer, 'test.png');
94
+ (0, vitest_1.expect)(url).toBe('https://assets.linear.app/asset-1');
95
+ // Verify the GraphQL mutation received the correct size
96
+ const graphqlInit = getCallInit(fetchMock.mock.calls, 0);
97
+ const body = JSON.parse(graphqlInit.body);
98
+ (0, vitest_1.expect)(body.variables.size).toBe(imageBuffer.byteLength);
99
+ });
100
+ (0, vitest_1.it)('handles Blob input correctly', async () => {
101
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
102
+ fetchMock.mockResolvedValueOnce(putResponse());
103
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
104
+ const imageBlob = new Blob(['test-blob-data'], { type: 'image/png' });
105
+ const url = await adapter.uploadImage(imageBlob, 'test.png');
106
+ (0, vitest_1.expect)(url).toBe('https://assets.linear.app/asset-1');
107
+ // Verify the GraphQL mutation received the correct size (Blob.size)
108
+ const graphqlInit = getCallInit(fetchMock.mock.calls, 0);
109
+ const body = JSON.parse(graphqlInit.body);
110
+ (0, vitest_1.expect)(body.variables.size).toBe(imageBlob.size);
111
+ });
112
+ (0, vitest_1.it)('applies additional headers from fileUpload response to PUT request', async () => {
113
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1, [
114
+ { key: 'x-amz-acl', value: 'public-read' },
115
+ { key: 'x-amz-meta-custom', value: 'linear-upload' },
116
+ ])));
117
+ fetchMock.mockResolvedValueOnce(putResponse());
118
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
119
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
120
+ const putInit = getCallInit(fetchMock.mock.calls, 1);
121
+ const headers = putInit.headers;
122
+ (0, vitest_1.expect)(headers['x-amz-acl']).toBe('public-read');
123
+ (0, vitest_1.expect)(headers['x-amz-meta-custom']).toBe('linear-upload');
124
+ (0, vitest_1.expect)(headers['Content-Type']).toBe('image/png');
125
+ (0, vitest_1.expect)(headers['Cache-Control']).toBe('public, max-age=31536000');
126
+ });
127
+ });
128
+ // == Content type detection ==
129
+ (0, vitest_1.describe)('content type detection', () => {
130
+ (0, vitest_1.it)('detects image/png for .png files', () => {
131
+ (0, vitest_1.expect)(adapter_js_1.LinearAdapter.detectContentType('screenshot.png')).toBe('image/png');
132
+ });
133
+ (0, vitest_1.it)('detects image/jpeg for .jpg files', () => {
134
+ (0, vitest_1.expect)(adapter_js_1.LinearAdapter.detectContentType('photo.jpg')).toBe('image/jpeg');
135
+ });
136
+ (0, vitest_1.it)('detects image/jpeg for .jpeg files', () => {
137
+ (0, vitest_1.expect)(adapter_js_1.LinearAdapter.detectContentType('photo.jpeg')).toBe('image/jpeg');
138
+ });
139
+ (0, vitest_1.it)('detects audio/webm for .webm files', () => {
140
+ (0, vitest_1.expect)(adapter_js_1.LinearAdapter.detectContentType('audio.webm')).toBe('audio/webm');
141
+ });
142
+ (0, vitest_1.it)('detects audio/m4a for .m4a files', () => {
143
+ (0, vitest_1.expect)(adapter_js_1.LinearAdapter.detectContentType('recording.m4a')).toBe('audio/m4a');
144
+ });
145
+ (0, vitest_1.it)('detects image/gif for .gif files', () => {
146
+ (0, vitest_1.expect)(adapter_js_1.LinearAdapter.detectContentType('animation.gif')).toBe('image/gif');
147
+ });
148
+ (0, vitest_1.it)('detects image/webp for .webp files', () => {
149
+ (0, vitest_1.expect)(adapter_js_1.LinearAdapter.detectContentType('photo.webp')).toBe('image/webp');
150
+ });
151
+ (0, vitest_1.it)('falls back to application/octet-stream for unknown extensions', () => {
152
+ (0, vitest_1.expect)(adapter_js_1.LinearAdapter.detectContentType('file.xyz')).toBe('application/octet-stream');
153
+ });
154
+ (0, vitest_1.it)('is case-insensitive', () => {
155
+ (0, vitest_1.expect)(adapter_js_1.LinearAdapter.detectContentType('SCREENSHOT.PNG')).toBe('image/png');
156
+ });
157
+ (0, vitest_1.it)('sends correct content type for PNG in upload mutation', async () => {
158
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
159
+ fetchMock.mockResolvedValueOnce(putResponse());
160
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
161
+ await adapter.uploadImage(Buffer.from('data'), 'screenshot.png');
162
+ const graphqlInit = getCallInit(fetchMock.mock.calls, 0);
163
+ const body = JSON.parse(graphqlInit.body);
164
+ (0, vitest_1.expect)(body.variables.contentType).toBe('image/png');
165
+ });
166
+ (0, vitest_1.it)('sends correct content type for JPEG in upload mutation', async () => {
167
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
168
+ fetchMock.mockResolvedValueOnce(putResponse());
169
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
170
+ await adapter.uploadImage(Buffer.from('data'), 'photo.jpg');
171
+ const graphqlInit = getCallInit(fetchMock.mock.calls, 0);
172
+ const body = JSON.parse(graphqlInit.body);
173
+ (0, vitest_1.expect)(body.variables.contentType).toBe('image/jpeg');
174
+ });
175
+ (0, vitest_1.it)('sends correct content type for webm in upload mutation', async () => {
176
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
177
+ fetchMock.mockResolvedValueOnce(putResponse());
178
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
179
+ await adapter.uploadImage(Buffer.from('data'), 'audio.webm');
180
+ const graphqlInit = getCallInit(fetchMock.mock.calls, 0);
181
+ const body = JSON.parse(graphqlInit.body);
182
+ (0, vitest_1.expect)(body.variables.contentType).toBe('audio/webm');
183
+ });
184
+ });
185
+ // == Error handling ==
186
+ (0, vitest_1.describe)('error handling', () => {
187
+ (0, vitest_1.it)('throws UPLOAD_FAILED on PUT failure (HTTP 500)', async () => {
188
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
189
+ fetchMock.mockResolvedValueOnce(new Response('Server Error', { status: 500 }));
190
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
191
+ try {
192
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
193
+ vitest_1.expect.unreachable('Should have thrown');
194
+ }
195
+ catch (e) {
196
+ (0, vitest_1.expect)(e).toBeInstanceOf(core_1.ShakeNbakeError);
197
+ (0, vitest_1.expect)(e.code).toBe('UPLOAD_FAILED');
198
+ (0, vitest_1.expect)(e.retryable).toBe(false);
199
+ }
200
+ });
201
+ (0, vitest_1.it)('throws UPLOAD_FAILED on PUT network error', async () => {
202
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
203
+ fetchMock.mockRejectedValueOnce(new TypeError('Network error'));
204
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
205
+ try {
206
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
207
+ vitest_1.expect.unreachable('Should have thrown');
208
+ }
209
+ catch (e) {
210
+ (0, vitest_1.expect)(e).toBeInstanceOf(core_1.ShakeNbakeError);
211
+ (0, vitest_1.expect)(e.code).toBe('UPLOAD_FAILED');
212
+ }
213
+ });
214
+ (0, vitest_1.it)('throws AUTH_FAILED on 401 during fileUpload mutation', async () => {
215
+ fetchMock.mockResolvedValueOnce(new Response('Unauthorized', { status: 401 }));
216
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
217
+ try {
218
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
219
+ vitest_1.expect.unreachable('Should have thrown');
220
+ }
221
+ catch (e) {
222
+ (0, vitest_1.expect)(e).toBeInstanceOf(core_1.ShakeNbakeError);
223
+ (0, vitest_1.expect)(e.code).toBe('AUTH_FAILED');
224
+ (0, vitest_1.expect)(e.retryable).toBe(false);
225
+ }
226
+ });
227
+ (0, vitest_1.it)('throws RATE_LIMITED on 429 during fileUpload mutation', async () => {
228
+ fetchMock.mockResolvedValueOnce(new Response('Too Many Requests', { status: 429 }));
229
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
230
+ try {
231
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
232
+ vitest_1.expect.unreachable('Should have thrown');
233
+ }
234
+ catch (e) {
235
+ (0, vitest_1.expect)(e).toBeInstanceOf(core_1.ShakeNbakeError);
236
+ (0, vitest_1.expect)(e.code).toBe('RATE_LIMITED');
237
+ (0, vitest_1.expect)(e.retryable).toBe(true);
238
+ }
239
+ });
240
+ (0, vitest_1.it)('throws NETWORK_ERROR on fetch failure during fileUpload mutation', async () => {
241
+ fetchMock.mockRejectedValueOnce(new TypeError('fetch failed'));
242
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
243
+ try {
244
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
245
+ vitest_1.expect.unreachable('Should have thrown');
246
+ }
247
+ catch (e) {
248
+ (0, vitest_1.expect)(e).toBeInstanceOf(core_1.ShakeNbakeError);
249
+ (0, vitest_1.expect)(e.code).toBe('NETWORK_ERROR');
250
+ }
251
+ });
252
+ (0, vitest_1.it)('throws RATE_LIMITED on GraphQL RATELIMITED extension code during upload', async () => {
253
+ fetchMock.mockResolvedValueOnce(new Response(JSON.stringify({
254
+ errors: [
255
+ {
256
+ message: 'Rate limit exceeded',
257
+ extensions: { code: 'RATELIMITED' },
258
+ },
259
+ ],
260
+ }), { status: 200 }));
261
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
262
+ try {
263
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
264
+ vitest_1.expect.unreachable('Should have thrown');
265
+ }
266
+ catch (e) {
267
+ (0, vitest_1.expect)(e).toBeInstanceOf(core_1.ShakeNbakeError);
268
+ (0, vitest_1.expect)(e.code).toBe('RATE_LIMITED');
269
+ (0, vitest_1.expect)(e.retryable).toBe(true);
270
+ }
271
+ });
272
+ (0, vitest_1.it)('throws UPLOAD_FAILED when fileUpload mutation returns success=false', async () => {
273
+ fetchMock.mockResolvedValueOnce(graphqlResponse({
274
+ fileUpload: {
275
+ success: false,
276
+ uploadFile: {
277
+ uploadUrl: '',
278
+ assetUrl: '',
279
+ headers: [],
280
+ },
281
+ },
282
+ }));
283
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
284
+ try {
285
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
286
+ vitest_1.expect.unreachable('Should have thrown');
287
+ }
288
+ catch (e) {
289
+ (0, vitest_1.expect)(e).toBeInstanceOf(core_1.ShakeNbakeError);
290
+ (0, vitest_1.expect)(e.code).toBe('UPLOAD_FAILED');
291
+ }
292
+ });
293
+ (0, vitest_1.it)('throws UPLOAD_FAILED on PUT 403 (expired URL)', async () => {
294
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
295
+ fetchMock.mockResolvedValueOnce(new Response('Forbidden', { status: 403 }));
296
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
297
+ try {
298
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
299
+ vitest_1.expect.unreachable('Should have thrown');
300
+ }
301
+ catch (e) {
302
+ (0, vitest_1.expect)(e).toBeInstanceOf(core_1.ShakeNbakeError);
303
+ (0, vitest_1.expect)(e.code).toBe('UPLOAD_FAILED');
304
+ }
305
+ });
306
+ });
307
+ // == PUT request structure ==
308
+ (0, vitest_1.describe)('PUT request structure', () => {
309
+ (0, vitest_1.it)('sends PUT method to upload URL', async () => {
310
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
311
+ fetchMock.mockResolvedValueOnce(putResponse());
312
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
313
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
314
+ const putInit = getCallInit(fetchMock.mock.calls, 1);
315
+ (0, vitest_1.expect)(putInit.method).toBe('PUT');
316
+ });
317
+ (0, vitest_1.it)('includes Content-Type header in PUT request', async () => {
318
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
319
+ fetchMock.mockResolvedValueOnce(putResponse());
320
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
321
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
322
+ const putInit = getCallInit(fetchMock.mock.calls, 1);
323
+ const headers = putInit.headers;
324
+ (0, vitest_1.expect)(headers['Content-Type']).toBe('image/png');
325
+ });
326
+ (0, vitest_1.it)('includes Cache-Control header in PUT request', async () => {
327
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
328
+ fetchMock.mockResolvedValueOnce(putResponse());
329
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
330
+ await adapter.uploadImage(Buffer.from('data'), 'test.png');
331
+ const putInit = getCallInit(fetchMock.mock.calls, 1);
332
+ const headers = putInit.headers;
333
+ (0, vitest_1.expect)(headers['Cache-Control']).toBe('public, max-age=31536000');
334
+ });
335
+ (0, vitest_1.it)('sends body as Blob even when input is Buffer', async () => {
336
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
337
+ fetchMock.mockResolvedValueOnce(putResponse());
338
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
339
+ await adapter.uploadImage(Buffer.from('test-data'), 'test.png');
340
+ const putInit = getCallInit(fetchMock.mock.calls, 1);
341
+ (0, vitest_1.expect)(putInit.body).toBeInstanceOf(Blob);
342
+ });
343
+ (0, vitest_1.it)('passes Blob input directly as body', async () => {
344
+ fetchMock.mockResolvedValueOnce(graphqlResponse(fileUploadData(1)));
345
+ fetchMock.mockResolvedValueOnce(putResponse());
346
+ const adapter = new adapter_js_1.LinearAdapter(makeConfig());
347
+ const inputBlob = new Blob(['test-data'], { type: 'image/png' });
348
+ await adapter.uploadImage(inputBlob, 'test.png');
349
+ const putInit = getCallInit(fetchMock.mock.calls, 1);
350
+ // The body should be a Blob (the exact same instance or a Blob)
351
+ (0, vitest_1.expect)(putInit.body).toBeInstanceOf(Blob);
352
+ });
353
+ });
354
+ });
355
+ //# sourceMappingURL=upload.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.test.js","sourceRoot":"","sources":["../../src/__tests__/upload.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { DestinationAdapter, BugReport, SubmitResult } from '@shakenbake/core';
2
+ import type { LinearConfig } from './types.js';
3
+ /**
4
+ * Linear destination adapter.
5
+ *
6
+ * Creates issues in Linear via the GraphQL API with markdown descriptions,
7
+ * embedded screenshots, and full device context.
8
+ */
9
+ export declare class LinearAdapter implements DestinationAdapter {
10
+ readonly name = "linear";
11
+ private readonly config;
12
+ private readonly apiUrl;
13
+ private readonly severityMapping;
14
+ constructor(config: LinearConfig);
15
+ /**
16
+ * Upload an image to Linear via the two-step file upload flow:
17
+ * 1. Call fileUpload mutation to get a signed upload URL and asset URL
18
+ * 2. PUT the image data to the signed URL with headers from response
19
+ * 3. Return the asset URL for embedding in the issue
20
+ *
21
+ * @throws {ShakeNbakeError} with code UPLOAD_FAILED on failure
22
+ */
23
+ uploadImage(imageData: Buffer | Blob, filename: string): Promise<string>;
24
+ /**
25
+ * Detect the content type from a filename extension.
26
+ */
27
+ static detectContentType(filename: string): string;
28
+ /**
29
+ * Create a Linear issue from a BugReport.
30
+ *
31
+ * Uploads screenshots, builds a markdown description, and creates the issue
32
+ * via the issueCreate GraphQL mutation.
33
+ *
34
+ * @throws {ShakeNbakeError} with appropriate code on failure
35
+ */
36
+ createIssue(report: BugReport): Promise<SubmitResult>;
37
+ /**
38
+ * Test the connection to Linear by querying the authenticated user.
39
+ *
40
+ * @returns true if credentials are valid, false if auth fails
41
+ * @throws {ShakeNbakeError} with NETWORK_ERROR for connectivity issues
42
+ */
43
+ testConnection(): Promise<boolean>;
44
+ /**
45
+ * Resolve the Linear priority from a severity string.
46
+ */
47
+ private resolvePriority;
48
+ /**
49
+ * Resolve label IDs from default labels + category-based labels.
50
+ */
51
+ private resolveLabelIds;
52
+ }
53
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAiB/C;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,kBAAkB;IACtD,QAAQ,CAAC,IAAI,YAAY;IAEzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyB;gBAE7C,MAAM,EAAE,YAAY;IAMhC;;;;;;;OAOG;IACG,WAAW,CACf,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IA8ElB;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAYlD;;;;;;;OAOG;IACG,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC;IAkG3D;;;;;OAKG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAuBxC;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB;;OAEG;IACH,OAAO,CAAC,eAAe;CAiBxB"}