@shipfox/api-integration-gitea 2.0.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.
- package/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +96 -0
- package/LICENSE +21 -0
- package/README.md +61 -0
- package/dist/api/client.d.ts +58 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +225 -0
- package/dist/api/client.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -0
- package/dist/core/connect.d.ts +18 -0
- package/dist/core/connect.d.ts.map +1 -0
- package/dist/core/connect.js +32 -0
- package/dist/core/connect.js.map +1 -0
- package/dist/core/connection-url.d.ts +2 -0
- package/dist/core/connection-url.d.ts.map +1 -0
- package/dist/core/connection-url.js +8 -0
- package/dist/core/connection-url.js.map +1 -0
- package/dist/core/errors.d.ts +10 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +17 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/source-control.d.ts +14 -0
- package/dist/core/source-control.d.ts.map +1 -0
- package/dist/core/source-control.js +177 -0
- package/dist/core/source-control.js.map +1 -0
- package/dist/core/webhook.d.ts +38 -0
- package/dist/core/webhook.d.ts.map +1 -0
- package/dist/core/webhook.js +162 -0
- package/dist/core/webhook.js.map +1 -0
- package/dist/db/connections.d.ts +19 -0
- package/dist/db/connections.d.ts.map +1 -0
- package/dist/db/connections.js +42 -0
- package/dist/db/connections.js.map +1 -0
- package/dist/db/db.d.ts +191 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +18 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/migrations.d.ts +2 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +5 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/schema/common.d.ts +2 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +4 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/connections.d.ts +97 -0
- package/dist/db/schema/connections.d.ts.map +1 -0
- package/dist/db/schema/connections.js +28 -0
- package/dist/db/schema/connections.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/presentation/dto/integrations.d.ts +17 -0
- package/dist/presentation/dto/integrations.d.ts.map +1 -0
- package/dist/presentation/dto/integrations.js +11 -0
- package/dist/presentation/dto/integrations.js.map +1 -0
- package/dist/presentation/routes/connections.d.ts +13 -0
- package/dist/presentation/routes/connections.d.ts.map +1 -0
- package/dist/presentation/routes/connections.js +47 -0
- package/dist/presentation/routes/connections.js.map +1 -0
- package/dist/presentation/routes/errors.d.ts +2 -0
- package/dist/presentation/routes/errors.d.ts.map +1 -0
- package/dist/presentation/routes/errors.js +36 -0
- package/dist/presentation/routes/errors.js.map +1 -0
- package/dist/presentation/routes/webhooks.d.ts +11 -0
- package/dist/presentation/routes/webhooks.d.ts.map +1 -0
- package/dist/presentation/routes/webhooks.js +109 -0
- package/dist/presentation/routes/webhooks.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_initial.sql +10 -0
- package/drizzle/meta/0000_snapshot.json +96 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +7 -0
- package/package.json +66 -0
- package/src/api/client.test.ts +367 -0
- package/src/api/client.ts +364 -0
- package/src/config.ts +42 -0
- package/src/connection-external-url.test.ts +36 -0
- package/src/core/connect.test.ts +149 -0
- package/src/core/connect.ts +52 -0
- package/src/core/connection-url.ts +8 -0
- package/src/core/errors.ts +17 -0
- package/src/core/source-control-clone-url.test.ts +83 -0
- package/src/core/source-control.test.ts +349 -0
- package/src/core/source-control.ts +231 -0
- package/src/core/webhook.test.ts +396 -0
- package/src/core/webhook.ts +203 -0
- package/src/db/connections.test.ts +69 -0
- package/src/db/connections.ts +80 -0
- package/src/db/db.ts +18 -0
- package/src/db/migrations.ts +4 -0
- package/src/db/schema/common.ts +3 -0
- package/src/db/schema/connections.ts +32 -0
- package/src/index.test.ts +23 -0
- package/src/index.ts +83 -0
- package/src/presentation/dto/integrations.ts +14 -0
- package/src/presentation/routes/connections.test.ts +200 -0
- package/src/presentation/routes/connections.ts +63 -0
- package/src/presentation/routes/errors.ts +35 -0
- package/src/presentation/routes/webhooks.test.ts +188 -0
- package/src/presentation/routes/webhooks.ts +111 -0
- package/test/env.ts +11 -0
- package/test/factories/gitea-connection.ts +19 -0
- package/test/factories/index.ts +1 -0
- package/test/fixtures/gitea-webhook.ts +237 -0
- package/test/globalSetup.ts +14 -0
- package/test/index.ts +6 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +9 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ConnectionSlugConflictError } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import { ClientError } from '@shipfox/node-fastify';
|
|
3
|
+
import { GiteaIntegrationProviderError, GiteaOrgAlreadyLinkedError, GiteaOrganizationNotFoundError } from '#core/errors.js';
|
|
4
|
+
function providerStatus(reason) {
|
|
5
|
+
if (reason === 'rate-limited') return 429;
|
|
6
|
+
if (reason === 'timeout' || reason === 'provider-unavailable') return 503;
|
|
7
|
+
return 422;
|
|
8
|
+
}
|
|
9
|
+
export function giteaRouteErrorHandler(error) {
|
|
10
|
+
if (error instanceof GiteaOrganizationNotFoundError) {
|
|
11
|
+
throw new ClientError(error.message, 'gitea-organization-not-found', {
|
|
12
|
+
status: 404
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
if (error instanceof GiteaOrgAlreadyLinkedError) {
|
|
16
|
+
throw new ClientError(error.message, 'gitea-org-already-linked', {
|
|
17
|
+
status: 409
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (error instanceof ConnectionSlugConflictError) {
|
|
21
|
+
throw new ClientError(error.message, 'slug-conflict', {
|
|
22
|
+
status: 409
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (error instanceof GiteaIntegrationProviderError) {
|
|
26
|
+
throw new ClientError(error.message, error.reason, {
|
|
27
|
+
details: {
|
|
28
|
+
retry_after_seconds: error.retryAfterSeconds
|
|
29
|
+
},
|
|
30
|
+
status: providerStatus(error.reason)
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/errors.ts"],"sourcesContent":["import {\n ConnectionSlugConflictError,\n type IntegrationProviderErrorReason,\n} from '@shipfox/api-integration-core-dto';\nimport {ClientError} from '@shipfox/node-fastify';\nimport {\n GiteaIntegrationProviderError,\n GiteaOrgAlreadyLinkedError,\n GiteaOrganizationNotFoundError,\n} from '#core/errors.js';\n\nfunction providerStatus(reason: IntegrationProviderErrorReason): number {\n if (reason === 'rate-limited') return 429;\n if (reason === 'timeout' || reason === 'provider-unavailable') return 503;\n return 422;\n}\n\nexport function giteaRouteErrorHandler(error: unknown): never {\n if (error instanceof GiteaOrganizationNotFoundError) {\n throw new ClientError(error.message, 'gitea-organization-not-found', {status: 404});\n }\n if (error instanceof GiteaOrgAlreadyLinkedError) {\n throw new ClientError(error.message, 'gitea-org-already-linked', {status: 409});\n }\n if (error instanceof ConnectionSlugConflictError) {\n throw new ClientError(error.message, 'slug-conflict', {status: 409});\n }\n if (error instanceof GiteaIntegrationProviderError) {\n throw new ClientError(error.message, error.reason, {\n details: {retry_after_seconds: error.retryAfterSeconds},\n status: providerStatus(error.reason),\n });\n }\n throw error;\n}\n"],"names":["ConnectionSlugConflictError","ClientError","GiteaIntegrationProviderError","GiteaOrgAlreadyLinkedError","GiteaOrganizationNotFoundError","providerStatus","reason","giteaRouteErrorHandler","error","message","status","details","retry_after_seconds","retryAfterSeconds"],"mappings":"AAAA,SACEA,2BAA2B,QAEtB,oCAAoC;AAC3C,SAAQC,WAAW,QAAO,wBAAwB;AAClD,SACEC,6BAA6B,EAC7BC,0BAA0B,EAC1BC,8BAA8B,QACzB,kBAAkB;AAEzB,SAASC,eAAeC,MAAsC;IAC5D,IAAIA,WAAW,gBAAgB,OAAO;IACtC,IAAIA,WAAW,aAAaA,WAAW,wBAAwB,OAAO;IACtE,OAAO;AACT;AAEA,OAAO,SAASC,uBAAuBC,KAAc;IACnD,IAAIA,iBAAiBJ,gCAAgC;QACnD,MAAM,IAAIH,YAAYO,MAAMC,OAAO,EAAE,gCAAgC;YAACC,QAAQ;QAAG;IACnF;IACA,IAAIF,iBAAiBL,4BAA4B;QAC/C,MAAM,IAAIF,YAAYO,MAAMC,OAAO,EAAE,4BAA4B;YAACC,QAAQ;QAAG;IAC/E;IACA,IAAIF,iBAAiBR,6BAA6B;QAChD,MAAM,IAAIC,YAAYO,MAAMC,OAAO,EAAE,iBAAiB;YAACC,QAAQ;QAAG;IACpE;IACA,IAAIF,iBAAiBN,+BAA+B;QAClD,MAAM,IAAID,YAAYO,MAAMC,OAAO,EAAED,MAAMF,MAAM,EAAE;YACjDK,SAAS;gBAACC,qBAAqBJ,MAAMK,iBAAiB;YAAA;YACtDH,QAAQL,eAAeG,MAAMF,MAAM;QACrC;IACF;IACA,MAAME;AACR"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { GetIntegrationConnectionByIdFn, PublishSourcePushFn, RecordDeliveryOnlyFn } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import { type RouteGroup } from '@shipfox/node-fastify';
|
|
3
|
+
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
|
4
|
+
export interface CreateGiteaWebhookRoutesOptions {
|
|
5
|
+
coreDb: () => NodePgDatabase<Record<string, unknown>>;
|
|
6
|
+
publishSourcePush: PublishSourcePushFn;
|
|
7
|
+
recordDeliveryOnly: RecordDeliveryOnlyFn;
|
|
8
|
+
getIntegrationConnectionById: GetIntegrationConnectionByIdFn;
|
|
9
|
+
}
|
|
10
|
+
export declare function createGiteaWebhookRoutes(options: CreateGiteaWebhookRoutesOptions): RouteGroup;
|
|
11
|
+
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/webhooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,8BAA8B,EAC9B,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAEL,KAAK,UAAU,EAIhB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAY9D,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,MAAM,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD,iBAAiB,EAAE,mBAAmB,CAAC;IACvC,kBAAkB,EAAE,oBAAoB,CAAC;IACzC,4BAA4B,EAAE,8BAA8B,CAAC;CAC9D;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,+BAA+B,GAAG,UAAU,CA6E7F"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { defineRoute, rawBodyPlugin, verifyHexHmacSignature, WEBHOOK_BODY_LIMIT } from '@shipfox/node-fastify';
|
|
3
|
+
import { logger } from '@shipfox/node-opentelemetry';
|
|
4
|
+
import { config } from '#config.js';
|
|
5
|
+
import { GiteaWebhookMalformedJsonError, GiteaWebhookMalformedPushPayloadError, handleGiteaWebhook } from '#core/webhook.js';
|
|
6
|
+
const SIGNATURE_HEADER = 'x-gitea-signature';
|
|
7
|
+
const EVENT_HEADER = 'x-gitea-event';
|
|
8
|
+
const DELIVERY_HEADER = 'x-gitea-delivery';
|
|
9
|
+
export function createGiteaWebhookRoutes(options) {
|
|
10
|
+
const pushRoute = defineRoute({
|
|
11
|
+
method: 'POST',
|
|
12
|
+
path: '/',
|
|
13
|
+
auth: [],
|
|
14
|
+
description: 'Gitea org webhook receiver.',
|
|
15
|
+
options: {
|
|
16
|
+
bodyLimit: WEBHOOK_BODY_LIMIT
|
|
17
|
+
},
|
|
18
|
+
handler: async (request, reply)=>{
|
|
19
|
+
const deliveryId = request.headers[DELIVERY_HEADER];
|
|
20
|
+
const signature = request.headers[SIGNATURE_HEADER];
|
|
21
|
+
const event = request.headers[EVENT_HEADER];
|
|
22
|
+
if (typeof deliveryId !== 'string' || !deliveryId) {
|
|
23
|
+
reply.code(400);
|
|
24
|
+
return {
|
|
25
|
+
error: 'missing X-Gitea-Delivery header'
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (typeof signature !== 'string' || !signature) {
|
|
29
|
+
reply.code(401);
|
|
30
|
+
return {
|
|
31
|
+
error: 'missing X-Gitea-Signature header'
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (typeof event !== 'string' || !event) {
|
|
35
|
+
reply.code(400);
|
|
36
|
+
return {
|
|
37
|
+
error: 'missing X-Gitea-Event header'
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const body = request.body;
|
|
41
|
+
if (!Buffer.isBuffer(body)) {
|
|
42
|
+
reply.code(400);
|
|
43
|
+
return {
|
|
44
|
+
error: 'expected raw JSON body'
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const rawBody = body.toString('utf8');
|
|
48
|
+
if (!verifyHexHmacSignature({
|
|
49
|
+
rawBody,
|
|
50
|
+
signature,
|
|
51
|
+
secret: config.GITEA_WEBHOOK_SECRET
|
|
52
|
+
})) {
|
|
53
|
+
reply.code(401);
|
|
54
|
+
return {
|
|
55
|
+
error: 'invalid signature'
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
await options.coreDb().transaction(async (tx)=>{
|
|
60
|
+
await handleGiteaWebhook({
|
|
61
|
+
tx,
|
|
62
|
+
deliveryId,
|
|
63
|
+
event,
|
|
64
|
+
rawBody,
|
|
65
|
+
publishSourcePush: options.publishSourcePush,
|
|
66
|
+
recordDeliveryOnly: options.recordDeliveryOnly,
|
|
67
|
+
getIntegrationConnectionById: options.getIntegrationConnectionById
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (error instanceof GiteaWebhookMalformedJsonError) {
|
|
72
|
+
logger().warn({
|
|
73
|
+
deliveryId,
|
|
74
|
+
err: error
|
|
75
|
+
}, 'gitea webhook payload JSON parse failed');
|
|
76
|
+
reply.code(400);
|
|
77
|
+
return {
|
|
78
|
+
error: 'malformed JSON'
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (error instanceof GiteaWebhookMalformedPushPayloadError) {
|
|
82
|
+
logger().warn({
|
|
83
|
+
deliveryId,
|
|
84
|
+
issues: error.issues
|
|
85
|
+
}, 'gitea webhook push payload failed schema validation');
|
|
86
|
+
reply.code(400);
|
|
87
|
+
return {
|
|
88
|
+
error: 'malformed push payload'
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
reply.code(204);
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return {
|
|
98
|
+
prefix: '/webhooks/integrations/gitea',
|
|
99
|
+
auth: [],
|
|
100
|
+
plugins: [
|
|
101
|
+
rawBodyPlugin
|
|
102
|
+
],
|
|
103
|
+
routes: [
|
|
104
|
+
pushRoute
|
|
105
|
+
]
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/webhooks.ts"],"sourcesContent":["import {Buffer} from 'node:buffer';\nimport type {\n GetIntegrationConnectionByIdFn,\n PublishSourcePushFn,\n RecordDeliveryOnlyFn,\n} from '@shipfox/api-integration-core-dto';\nimport {\n defineRoute,\n type RouteGroup,\n rawBodyPlugin,\n verifyHexHmacSignature,\n WEBHOOK_BODY_LIMIT,\n} from '@shipfox/node-fastify';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport type {NodePgDatabase} from 'drizzle-orm/node-postgres';\nimport {config} from '#config.js';\nimport {\n GiteaWebhookMalformedJsonError,\n GiteaWebhookMalformedPushPayloadError,\n handleGiteaWebhook,\n} from '#core/webhook.js';\n\nconst SIGNATURE_HEADER = 'x-gitea-signature';\nconst EVENT_HEADER = 'x-gitea-event';\nconst DELIVERY_HEADER = 'x-gitea-delivery';\n\nexport interface CreateGiteaWebhookRoutesOptions {\n coreDb: () => NodePgDatabase<Record<string, unknown>>;\n publishSourcePush: PublishSourcePushFn;\n recordDeliveryOnly: RecordDeliveryOnlyFn;\n getIntegrationConnectionById: GetIntegrationConnectionByIdFn;\n}\n\nexport function createGiteaWebhookRoutes(options: CreateGiteaWebhookRoutesOptions): RouteGroup {\n const pushRoute = defineRoute({\n method: 'POST',\n path: '/',\n auth: [],\n description: 'Gitea org webhook receiver.',\n options: {bodyLimit: WEBHOOK_BODY_LIMIT},\n handler: async (request, reply) => {\n const deliveryId = request.headers[DELIVERY_HEADER];\n const signature = request.headers[SIGNATURE_HEADER];\n const event = request.headers[EVENT_HEADER];\n\n if (typeof deliveryId !== 'string' || !deliveryId) {\n reply.code(400);\n return {error: 'missing X-Gitea-Delivery header'};\n }\n if (typeof signature !== 'string' || !signature) {\n reply.code(401);\n return {error: 'missing X-Gitea-Signature header'};\n }\n if (typeof event !== 'string' || !event) {\n reply.code(400);\n return {error: 'missing X-Gitea-Event header'};\n }\n\n const body = request.body;\n if (!Buffer.isBuffer(body)) {\n reply.code(400);\n return {error: 'expected raw JSON body'};\n }\n const rawBody = body.toString('utf8');\n\n if (!verifyHexHmacSignature({rawBody, signature, secret: config.GITEA_WEBHOOK_SECRET})) {\n reply.code(401);\n return {error: 'invalid signature'};\n }\n\n try {\n await options.coreDb().transaction(async (tx) => {\n await handleGiteaWebhook({\n tx,\n deliveryId,\n event,\n rawBody,\n publishSourcePush: options.publishSourcePush,\n recordDeliveryOnly: options.recordDeliveryOnly,\n getIntegrationConnectionById: options.getIntegrationConnectionById,\n });\n });\n } catch (error) {\n if (error instanceof GiteaWebhookMalformedJsonError) {\n logger().warn({deliveryId, err: error}, 'gitea webhook payload JSON parse failed');\n reply.code(400);\n return {error: 'malformed JSON'};\n }\n if (error instanceof GiteaWebhookMalformedPushPayloadError) {\n logger().warn(\n {deliveryId, issues: error.issues},\n 'gitea webhook push payload failed schema validation',\n );\n reply.code(400);\n return {error: 'malformed push payload'};\n }\n throw error;\n }\n\n reply.code(204);\n return null;\n },\n });\n\n return {\n prefix: '/webhooks/integrations/gitea',\n auth: [],\n plugins: [rawBodyPlugin],\n routes: [pushRoute],\n };\n}\n"],"names":["Buffer","defineRoute","rawBodyPlugin","verifyHexHmacSignature","WEBHOOK_BODY_LIMIT","logger","config","GiteaWebhookMalformedJsonError","GiteaWebhookMalformedPushPayloadError","handleGiteaWebhook","SIGNATURE_HEADER","EVENT_HEADER","DELIVERY_HEADER","createGiteaWebhookRoutes","options","pushRoute","method","path","auth","description","bodyLimit","handler","request","reply","deliveryId","headers","signature","event","code","error","body","isBuffer","rawBody","toString","secret","GITEA_WEBHOOK_SECRET","coreDb","transaction","tx","publishSourcePush","recordDeliveryOnly","getIntegrationConnectionById","warn","err","issues","prefix","plugins","routes"],"mappings":"AAAA,SAAQA,MAAM,QAAO,cAAc;AAMnC,SACEC,WAAW,EAEXC,aAAa,EACbC,sBAAsB,EACtBC,kBAAkB,QACb,wBAAwB;AAC/B,SAAQC,MAAM,QAAO,8BAA8B;AAEnD,SAAQC,MAAM,QAAO,aAAa;AAClC,SACEC,8BAA8B,EAC9BC,qCAAqC,EACrCC,kBAAkB,QACb,mBAAmB;AAE1B,MAAMC,mBAAmB;AACzB,MAAMC,eAAe;AACrB,MAAMC,kBAAkB;AASxB,OAAO,SAASC,yBAAyBC,OAAwC;IAC/E,MAAMC,YAAYd,YAAY;QAC5Be,QAAQ;QACRC,MAAM;QACNC,MAAM,EAAE;QACRC,aAAa;QACbL,SAAS;YAACM,WAAWhB;QAAkB;QACvCiB,SAAS,OAAOC,SAASC;YACvB,MAAMC,aAAaF,QAAQG,OAAO,CAACb,gBAAgB;YACnD,MAAMc,YAAYJ,QAAQG,OAAO,CAACf,iBAAiB;YACnD,MAAMiB,QAAQL,QAAQG,OAAO,CAACd,aAAa;YAE3C,IAAI,OAAOa,eAAe,YAAY,CAACA,YAAY;gBACjDD,MAAMK,IAAI,CAAC;gBACX,OAAO;oBAACC,OAAO;gBAAiC;YAClD;YACA,IAAI,OAAOH,cAAc,YAAY,CAACA,WAAW;gBAC/CH,MAAMK,IAAI,CAAC;gBACX,OAAO;oBAACC,OAAO;gBAAkC;YACnD;YACA,IAAI,OAAOF,UAAU,YAAY,CAACA,OAAO;gBACvCJ,MAAMK,IAAI,CAAC;gBACX,OAAO;oBAACC,OAAO;gBAA8B;YAC/C;YAEA,MAAMC,OAAOR,QAAQQ,IAAI;YACzB,IAAI,CAAC9B,OAAO+B,QAAQ,CAACD,OAAO;gBAC1BP,MAAMK,IAAI,CAAC;gBACX,OAAO;oBAACC,OAAO;gBAAwB;YACzC;YACA,MAAMG,UAAUF,KAAKG,QAAQ,CAAC;YAE9B,IAAI,CAAC9B,uBAAuB;gBAAC6B;gBAASN;gBAAWQ,QAAQ5B,OAAO6B,oBAAoB;YAAA,IAAI;gBACtFZ,MAAMK,IAAI,CAAC;gBACX,OAAO;oBAACC,OAAO;gBAAmB;YACpC;YAEA,IAAI;gBACF,MAAMf,QAAQsB,MAAM,GAAGC,WAAW,CAAC,OAAOC;oBACxC,MAAM7B,mBAAmB;wBACvB6B;wBACAd;wBACAG;wBACAK;wBACAO,mBAAmBzB,QAAQyB,iBAAiB;wBAC5CC,oBAAoB1B,QAAQ0B,kBAAkB;wBAC9CC,8BAA8B3B,QAAQ2B,4BAA4B;oBACpE;gBACF;YACF,EAAE,OAAOZ,OAAO;gBACd,IAAIA,iBAAiBtB,gCAAgC;oBACnDF,SAASqC,IAAI,CAAC;wBAAClB;wBAAYmB,KAAKd;oBAAK,GAAG;oBACxCN,MAAMK,IAAI,CAAC;oBACX,OAAO;wBAACC,OAAO;oBAAgB;gBACjC;gBACA,IAAIA,iBAAiBrB,uCAAuC;oBAC1DH,SAASqC,IAAI,CACX;wBAAClB;wBAAYoB,QAAQf,MAAMe,MAAM;oBAAA,GACjC;oBAEFrB,MAAMK,IAAI,CAAC;oBACX,OAAO;wBAACC,OAAO;oBAAwB;gBACzC;gBACA,MAAMA;YACR;YAEAN,MAAMK,IAAI,CAAC;YACX,OAAO;QACT;IACF;IAEA,OAAO;QACLiB,QAAQ;QACR3B,MAAM,EAAE;QACR4B,SAAS;YAAC5C;SAAc;QACxB6C,QAAQ;YAAChC;SAAU;IACrB;AACF"}
|