@polymorfa/sdk 0.1.0-dev.20260922093854
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/LICENSE +21 -0
- package/README.md +1881 -0
- package/dist/bridge.d.ts +31 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +39 -0
- package/dist/bridge.js.map +1 -0
- package/dist/calls/api.d.ts +109 -0
- package/dist/calls/api.d.ts.map +1 -0
- package/dist/calls/api.js +179 -0
- package/dist/calls/api.js.map +1 -0
- package/dist/calls/call.d.ts +286 -0
- package/dist/calls/call.d.ts.map +1 -0
- package/dist/calls/call.js +860 -0
- package/dist/calls/call.js.map +1 -0
- package/dist/calls/client.d.ts +124 -0
- package/dist/calls/client.d.ts.map +1 -0
- package/dist/calls/client.js +447 -0
- package/dist/calls/client.js.map +1 -0
- package/dist/calls/diagnostics.d.ts +74 -0
- package/dist/calls/diagnostics.d.ts.map +1 -0
- package/dist/calls/diagnostics.js +133 -0
- package/dist/calls/diagnostics.js.map +1 -0
- package/dist/calls/errors.d.ts +37 -0
- package/dist/calls/errors.d.ts.map +1 -0
- package/dist/calls/errors.js +52 -0
- package/dist/calls/errors.js.map +1 -0
- package/dist/calls/events.d.ts +15 -0
- package/dist/calls/events.d.ts.map +1 -0
- package/dist/calls/events.js +34 -0
- package/dist/calls/events.js.map +1 -0
- package/dist/calls/index.d.ts +6 -0
- package/dist/calls/index.d.ts.map +1 -0
- package/dist/calls/index.js +7 -0
- package/dist/calls/index.js.map +1 -0
- package/dist/calls/internal.d.ts +18 -0
- package/dist/calls/internal.d.ts.map +1 -0
- package/dist/calls/internal.js +18 -0
- package/dist/calls/internal.js.map +1 -0
- package/dist/calls/lifecycle.d.ts +111 -0
- package/dist/calls/lifecycle.d.ts.map +1 -0
- package/dist/calls/lifecycle.js +490 -0
- package/dist/calls/lifecycle.js.map +1 -0
- package/dist/calls/media.d.ts +102 -0
- package/dist/calls/media.d.ts.map +1 -0
- package/dist/calls/media.js +414 -0
- package/dist/calls/media.js.map +1 -0
- package/dist/calls/protocol.d.ts +216 -0
- package/dist/calls/protocol.d.ts.map +1 -0
- package/dist/calls/protocol.js +268 -0
- package/dist/calls/protocol.js.map +1 -0
- package/dist/calls/token.d.ts +43 -0
- package/dist/calls/token.d.ts.map +1 -0
- package/dist/calls/token.js +146 -0
- package/dist/calls/token.js.map +1 -0
- package/dist/client.d.ts +65 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +119 -0
- package/dist/client.js.map +1 -0
- package/dist/credentials.d.ts +50 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +73 -0
- package/dist/credentials.js.map +1 -0
- package/dist/errors.d.ts +71 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +129 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/media/whatsapp.d.ts +105 -0
- package/dist/media/whatsapp.d.ts.map +1 -0
- package/dist/media/whatsapp.js +624 -0
- package/dist/media/whatsapp.js.map +1 -0
- package/dist/messaging/bansafe.d.ts +30 -0
- package/dist/messaging/bansafe.d.ts.map +1 -0
- package/dist/messaging/bansafe.js +86 -0
- package/dist/messaging/bansafe.js.map +1 -0
- package/dist/messaging/business.d.ts +35 -0
- package/dist/messaging/business.d.ts.map +1 -0
- package/dist/messaging/business.js +145 -0
- package/dist/messaging/business.js.map +1 -0
- package/dist/messaging/calls.d.ts +9 -0
- package/dist/messaging/calls.d.ts.map +1 -0
- package/dist/messaging/calls.js +16 -0
- package/dist/messaging/calls.js.map +1 -0
- package/dist/messaging/campaigns.d.ts +19 -0
- package/dist/messaging/campaigns.d.ts.map +1 -0
- package/dist/messaging/campaigns.js +77 -0
- package/dist/messaging/campaigns.js.map +1 -0
- package/dist/messaging/channels.d.ts +23 -0
- package/dist/messaging/channels.d.ts.map +1 -0
- package/dist/messaging/channels.js +104 -0
- package/dist/messaging/channels.js.map +1 -0
- package/dist/messaging/chats.d.ts +14 -0
- package/dist/messaging/chats.d.ts.map +1 -0
- package/dist/messaging/chats.js +51 -0
- package/dist/messaging/chats.js.map +1 -0
- package/dist/messaging/client-tokens.d.ts +15 -0
- package/dist/messaging/client-tokens.d.ts.map +1 -0
- package/dist/messaging/client-tokens.js +64 -0
- package/dist/messaging/client-tokens.js.map +1 -0
- package/dist/messaging/client.d.ts +58 -0
- package/dist/messaging/client.d.ts.map +1 -0
- package/dist/messaging/client.js +100 -0
- package/dist/messaging/client.js.map +1 -0
- package/dist/messaging/contacts.d.ts +20 -0
- package/dist/messaging/contacts.d.ts.map +1 -0
- package/dist/messaging/contacts.js +75 -0
- package/dist/messaging/contacts.js.map +1 -0
- package/dist/messaging/groups.d.ts +34 -0
- package/dist/messaging/groups.d.ts.map +1 -0
- package/dist/messaging/groups.js +97 -0
- package/dist/messaging/groups.js.map +1 -0
- package/dist/messaging/identities.d.ts +9 -0
- package/dist/messaging/identities.d.ts.map +1 -0
- package/dist/messaging/identities.js +21 -0
- package/dist/messaging/identities.js.map +1 -0
- package/dist/messaging/labels.d.ts +16 -0
- package/dist/messaging/labels.d.ts.map +1 -0
- package/dist/messaging/labels.js +65 -0
- package/dist/messaging/labels.js.map +1 -0
- package/dist/messaging/media.d.ts +72 -0
- package/dist/messaging/media.d.ts.map +1 -0
- package/dist/messaging/media.js +142 -0
- package/dist/messaging/media.js.map +1 -0
- package/dist/messaging/messages.d.ts +18 -0
- package/dist/messaging/messages.d.ts.map +1 -0
- package/dist/messaging/messages.js +32 -0
- package/dist/messaging/messages.js.map +1 -0
- package/dist/messaging/observation-policies.d.ts +10 -0
- package/dist/messaging/observation-policies.d.ts.map +1 -0
- package/dist/messaging/observation-policies.js +28 -0
- package/dist/messaging/observation-policies.js.map +1 -0
- package/dist/messaging/onboarding.d.ts +53 -0
- package/dist/messaging/onboarding.d.ts.map +1 -0
- package/dist/messaging/onboarding.js +69 -0
- package/dist/messaging/onboarding.js.map +1 -0
- package/dist/messaging/presence.d.ts +12 -0
- package/dist/messaging/presence.d.ts.map +1 -0
- package/dist/messaging/presence.js +43 -0
- package/dist/messaging/presence.js.map +1 -0
- package/dist/messaging/privacy.d.ts +11 -0
- package/dist/messaging/privacy.d.ts.map +1 -0
- package/dist/messaging/privacy.js +34 -0
- package/dist/messaging/privacy.js.map +1 -0
- package/dist/messaging/profile.d.ts +13 -0
- package/dist/messaging/profile.d.ts.map +1 -0
- package/dist/messaging/profile.js +49 -0
- package/dist/messaging/profile.js.map +1 -0
- package/dist/messaging/quick-replies.d.ts +13 -0
- package/dist/messaging/quick-replies.d.ts.map +1 -0
- package/dist/messaging/quick-replies.js +45 -0
- package/dist/messaging/quick-replies.js.map +1 -0
- package/dist/messaging/quicklinks.d.ts +69 -0
- package/dist/messaging/quicklinks.d.ts.map +1 -0
- package/dist/messaging/quicklinks.js +45 -0
- package/dist/messaging/quicklinks.js.map +1 -0
- package/dist/messaging/session-configuration.d.ts +67 -0
- package/dist/messaging/session-configuration.d.ts.map +1 -0
- package/dist/messaging/session-configuration.js +2 -0
- package/dist/messaging/session-configuration.js.map +1 -0
- package/dist/messaging/sessions.d.ts +26 -0
- package/dist/messaging/sessions.d.ts.map +1 -0
- package/dist/messaging/sessions.js +108 -0
- package/dist/messaging/sessions.js.map +1 -0
- package/dist/messaging/templates.d.ts +15 -0
- package/dist/messaging/templates.d.ts.map +1 -0
- package/dist/messaging/templates.js +67 -0
- package/dist/messaging/templates.js.map +1 -0
- package/dist/messaging/testing-configuration.d.ts +89 -0
- package/dist/messaging/testing-configuration.d.ts.map +1 -0
- package/dist/messaging/testing-configuration.js +14 -0
- package/dist/messaging/testing-configuration.js.map +1 -0
- package/dist/messaging/types.d.ts +1793 -0
- package/dist/messaging/types.d.ts.map +1 -0
- package/dist/messaging/types.js +25 -0
- package/dist/messaging/types.js.map +1 -0
- package/dist/messaging/users.d.ts +9 -0
- package/dist/messaging/users.d.ts.map +1 -0
- package/dist/messaging/users.js +15 -0
- package/dist/messaging/users.js.map +1 -0
- package/dist/messaging/voip.d.ts +51 -0
- package/dist/messaging/voip.d.ts.map +1 -0
- package/dist/messaging/voip.js +293 -0
- package/dist/messaging/voip.js.map +1 -0
- package/dist/messaging/webhooks.d.ts +13 -0
- package/dist/messaging/webhooks.d.ts.map +1 -0
- package/dist/messaging/webhooks.js +48 -0
- package/dist/messaging/webhooks.js.map +1 -0
- package/dist/node.d.ts +55 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +237 -0
- package/dist/node.js.map +1 -0
- package/dist/pagination.d.ts +24 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +28 -0
- package/dist/pagination.js.map +1 -0
- package/dist/platform/api-keys.d.ts +10 -0
- package/dist/platform/api-keys.d.ts.map +1 -0
- package/dist/platform/api-keys.js +22 -0
- package/dist/platform/api-keys.js.map +1 -0
- package/dist/platform/audiences.d.ts +16 -0
- package/dist/platform/audiences.d.ts.map +1 -0
- package/dist/platform/audiences.js +46 -0
- package/dist/platform/audiences.js.map +1 -0
- package/dist/platform/audit-logs.d.ts +9 -0
- package/dist/platform/audit-logs.d.ts.map +1 -0
- package/dist/platform/audit-logs.js +20 -0
- package/dist/platform/audit-logs.js.map +1 -0
- package/dist/platform/bansafe.d.ts +24 -0
- package/dist/platform/bansafe.d.ts.map +1 -0
- package/dist/platform/bansafe.js +70 -0
- package/dist/platform/bansafe.js.map +1 -0
- package/dist/platform/billing.d.ts +13 -0
- package/dist/platform/billing.d.ts.map +1 -0
- package/dist/platform/billing.js +27 -0
- package/dist/platform/billing.js.map +1 -0
- package/dist/platform/campaigns.d.ts +28 -0
- package/dist/platform/campaigns.d.ts.map +1 -0
- package/dist/platform/campaigns.js +92 -0
- package/dist/platform/campaigns.js.map +1 -0
- package/dist/platform/customers.d.ts +23 -0
- package/dist/platform/customers.d.ts.map +1 -0
- package/dist/platform/customers.js +140 -0
- package/dist/platform/customers.js.map +1 -0
- package/dist/platform/developer-resources.d.ts +101 -0
- package/dist/platform/developer-resources.d.ts.map +1 -0
- package/dist/platform/developer-resources.js +250 -0
- package/dist/platform/developer-resources.js.map +1 -0
- package/dist/platform/developer-types.d.ts +378 -0
- package/dist/platform/developer-types.d.ts.map +1 -0
- package/dist/platform/developer-types.js +2 -0
- package/dist/platform/developer-types.js.map +1 -0
- package/dist/platform/event-stream.d.ts +114 -0
- package/dist/platform/event-stream.d.ts.map +1 -0
- package/dist/platform/event-stream.js +308 -0
- package/dist/platform/event-stream.js.map +1 -0
- package/dist/platform/media.d.ts +13 -0
- package/dist/platform/media.d.ts.map +1 -0
- package/dist/platform/media.js +33 -0
- package/dist/platform/media.js.map +1 -0
- package/dist/platform/members.d.ts +9 -0
- package/dist/platform/members.d.ts.map +1 -0
- package/dist/platform/members.js +15 -0
- package/dist/platform/members.js.map +1 -0
- package/dist/platform/opt-outs.d.ts +15 -0
- package/dist/platform/opt-outs.d.ts.map +1 -0
- package/dist/platform/opt-outs.js +36 -0
- package/dist/platform/opt-outs.js.map +1 -0
- package/dist/platform/organizations.d.ts +9 -0
- package/dist/platform/organizations.d.ts.map +1 -0
- package/dist/platform/organizations.js +15 -0
- package/dist/platform/organizations.js.map +1 -0
- package/dist/platform/project-tokens.d.ts +9 -0
- package/dist/platform/project-tokens.d.ts.map +1 -0
- package/dist/platform/project-tokens.js +16 -0
- package/dist/platform/project-tokens.js.map +1 -0
- package/dist/platform/projects.d.ts +24 -0
- package/dist/platform/projects.d.ts.map +1 -0
- package/dist/platform/projects.js +83 -0
- package/dist/platform/projects.js.map +1 -0
- package/dist/platform/quicklink-settings.d.ts +85 -0
- package/dist/platform/quicklink-settings.d.ts.map +1 -0
- package/dist/platform/quicklink-settings.js +35 -0
- package/dist/platform/quicklink-settings.js.map +1 -0
- package/dist/platform/response.d.ts +10 -0
- package/dist/platform/response.d.ts.map +1 -0
- package/dist/platform/response.js +41 -0
- package/dist/platform/response.js.map +1 -0
- package/dist/platform/security-incidents.d.ts +10 -0
- package/dist/platform/security-incidents.d.ts.map +1 -0
- package/dist/platform/security-incidents.js +22 -0
- package/dist/platform/security-incidents.js.map +1 -0
- package/dist/platform/session-bans.d.ts +13 -0
- package/dist/platform/session-bans.d.ts.map +1 -0
- package/dist/platform/session-bans.js +21 -0
- package/dist/platform/session-bans.js.map +1 -0
- package/dist/platform/session-configuration.d.ts +15 -0
- package/dist/platform/session-configuration.d.ts.map +1 -0
- package/dist/platform/session-configuration.js +36 -0
- package/dist/platform/session-configuration.js.map +1 -0
- package/dist/platform/sessions.d.ts +26 -0
- package/dist/platform/sessions.d.ts.map +1 -0
- package/dist/platform/sessions.js +121 -0
- package/dist/platform/sessions.js.map +1 -0
- package/dist/platform/sip-trunks.d.ts +141 -0
- package/dist/platform/sip-trunks.d.ts.map +1 -0
- package/dist/platform/sip-trunks.js +140 -0
- package/dist/platform/sip-trunks.js.map +1 -0
- package/dist/platform/types.d.ts +897 -0
- package/dist/platform/types.d.ts.map +1 -0
- package/dist/platform/types.js +2 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/raw.d.ts +26 -0
- package/dist/raw.d.ts.map +1 -0
- package/dist/raw.js +79 -0
- package/dist/raw.js.map +1 -0
- package/dist/system.d.ts +37 -0
- package/dist/system.d.ts.map +1 -0
- package/dist/system.js +45 -0
- package/dist/system.js.map +1 -0
- package/dist/transport/body.d.ts +6 -0
- package/dist/transport/body.d.ts.map +1 -0
- package/dist/transport/body.js +33 -0
- package/dist/transport/body.js.map +1 -0
- package/dist/transport/content-disposition.d.ts +9 -0
- package/dist/transport/content-disposition.d.ts.map +1 -0
- package/dist/transport/content-disposition.js +107 -0
- package/dist/transport/content-disposition.js.map +1 -0
- package/dist/transport/http.d.ts +35 -0
- package/dist/transport/http.d.ts.map +1 -0
- package/dist/transport/http.js +660 -0
- package/dist/transport/http.js.map +1 -0
- package/dist/transport/idempotency.d.ts +10 -0
- package/dist/transport/idempotency.d.ts.map +1 -0
- package/dist/transport/idempotency.js +13 -0
- package/dist/transport/idempotency.js.map +1 -0
- package/dist/transport/retry.d.ts +11 -0
- package/dist/transport/retry.d.ts.map +1 -0
- package/dist/transport/retry.js +45 -0
- package/dist/transport/retry.js.map +1 -0
- package/dist/transport/types.d.ts +58 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +2 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/dist/webhooks/events.d.ts +741 -0
- package/dist/webhooks/events.d.ts.map +1 -0
- package/dist/webhooks/events.js +80 -0
- package/dist/webhooks/events.js.map +1 -0
- package/dist/webhooks/index.d.ts +4 -0
- package/dist/webhooks/index.d.ts.map +1 -0
- package/dist/webhooks/index.js +4 -0
- package/dist/webhooks/index.js.map +1 -0
- package/dist/webhooks/utilities.d.ts +33 -0
- package/dist/webhooks/utilities.d.ts.map +1 -0
- package/dist/webhooks/utilities.js +67 -0
- package/dist/webhooks/utilities.js.map +1 -0
- package/dist/webhooks/verify.d.ts +9 -0
- package/dist/webhooks/verify.d.ts.map +1 -0
- package/dist/webhooks/verify.js +77 -0
- package/dist/webhooks/verify.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
import { PolymorfaCancelledError, PolymorfaConfigurationError, PolymorfaConnectionError, PolymorfaError, PolymorfaMediaIntegrityError, } from "../errors.js";
|
|
2
|
+
export const DEFAULT_WHATSAPP_MEDIA_MAX_BYTES = 256 * 1024 * 1024;
|
|
3
|
+
const MAX_DESCRIPTOR_BASE64_LENGTH = 1024 * 1024;
|
|
4
|
+
const MAX_URL_LENGTH = 8192;
|
|
5
|
+
const MAX_TEXT_LENGTH = 4096;
|
|
6
|
+
const MAC_LENGTH = 10;
|
|
7
|
+
const BLOCK = 16;
|
|
8
|
+
const FALLBACK_HOST = "mmg.whatsapp.net";
|
|
9
|
+
const WEB_ORIGIN = "https://web.whatsapp.com";
|
|
10
|
+
const HKDF_INFO = {
|
|
11
|
+
image: "WhatsApp Image Keys",
|
|
12
|
+
video: "WhatsApp Video Keys",
|
|
13
|
+
audio: "WhatsApp Audio Keys",
|
|
14
|
+
document: "WhatsApp Document Keys",
|
|
15
|
+
// Stickers use image keys (whatsmeow download.go classToMediaType).
|
|
16
|
+
sticker: "WhatsApp Image Keys",
|
|
17
|
+
};
|
|
18
|
+
const MMS_TYPE = {
|
|
19
|
+
image: "image",
|
|
20
|
+
video: "video",
|
|
21
|
+
audio: "audio",
|
|
22
|
+
document: "document",
|
|
23
|
+
sticker: "image",
|
|
24
|
+
};
|
|
25
|
+
// Field numbers from whatsmeow proto/waE2E/WAWebProtobufsE2E.proto.
|
|
26
|
+
const FIELDS = {
|
|
27
|
+
image: {
|
|
28
|
+
url: 1,
|
|
29
|
+
mimetype: 2,
|
|
30
|
+
fileSha256: 4,
|
|
31
|
+
fileLength: 5,
|
|
32
|
+
mediaKey: 8,
|
|
33
|
+
fileEncSha256: 9,
|
|
34
|
+
directPath: 11,
|
|
35
|
+
},
|
|
36
|
+
video: {
|
|
37
|
+
url: 1,
|
|
38
|
+
mimetype: 2,
|
|
39
|
+
fileSha256: 3,
|
|
40
|
+
fileLength: 4,
|
|
41
|
+
mediaKey: 6,
|
|
42
|
+
fileEncSha256: 11,
|
|
43
|
+
directPath: 13,
|
|
44
|
+
},
|
|
45
|
+
audio: {
|
|
46
|
+
url: 1,
|
|
47
|
+
mimetype: 2,
|
|
48
|
+
fileSha256: 3,
|
|
49
|
+
fileLength: 4,
|
|
50
|
+
mediaKey: 7,
|
|
51
|
+
fileEncSha256: 8,
|
|
52
|
+
directPath: 9,
|
|
53
|
+
},
|
|
54
|
+
document: {
|
|
55
|
+
url: 1,
|
|
56
|
+
mimetype: 2,
|
|
57
|
+
fileSha256: 4,
|
|
58
|
+
fileLength: 5,
|
|
59
|
+
mediaKey: 7,
|
|
60
|
+
fileName: 8,
|
|
61
|
+
fileEncSha256: 9,
|
|
62
|
+
directPath: 10,
|
|
63
|
+
},
|
|
64
|
+
sticker: {
|
|
65
|
+
url: 1,
|
|
66
|
+
fileSha256: 2,
|
|
67
|
+
fileEncSha256: 3,
|
|
68
|
+
mediaKey: 4,
|
|
69
|
+
mimetype: 5,
|
|
70
|
+
directPath: 8,
|
|
71
|
+
fileLength: 9,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
const DEFAULT_MIME = {
|
|
75
|
+
image: "image/jpeg",
|
|
76
|
+
video: "video/mp4",
|
|
77
|
+
audio: "audio/ogg",
|
|
78
|
+
document: "application/octet-stream",
|
|
79
|
+
sticker: "image/webp",
|
|
80
|
+
};
|
|
81
|
+
function invalid(message) {
|
|
82
|
+
return new PolymorfaMediaIntegrityError(message, "media_invalid_descriptor");
|
|
83
|
+
}
|
|
84
|
+
function asKind(type) {
|
|
85
|
+
if (Object.hasOwn(FIELDS, type))
|
|
86
|
+
return type;
|
|
87
|
+
throw invalid(`Message type ${JSON.stringify(type)} carries no media.`);
|
|
88
|
+
}
|
|
89
|
+
function decodeBase64(value) {
|
|
90
|
+
if (value.length > MAX_DESCRIPTOR_BASE64_LENGTH) {
|
|
91
|
+
throw invalid("The media descriptor exceeds the size limit.");
|
|
92
|
+
}
|
|
93
|
+
const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
94
|
+
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(normalized) || normalized.length === 0) {
|
|
95
|
+
throw invalid("The media descriptor is not valid base64.");
|
|
96
|
+
}
|
|
97
|
+
let binary;
|
|
98
|
+
try {
|
|
99
|
+
binary = atob(normalized);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
throw invalid("The media descriptor is not valid base64.");
|
|
103
|
+
}
|
|
104
|
+
const bytes = new Uint8Array(binary.length);
|
|
105
|
+
for (let index = 0; index < binary.length; index += 1) {
|
|
106
|
+
bytes[index] = binary.charCodeAt(index);
|
|
107
|
+
}
|
|
108
|
+
return bytes;
|
|
109
|
+
}
|
|
110
|
+
class ProtoReader {
|
|
111
|
+
bytes;
|
|
112
|
+
#offset = 0;
|
|
113
|
+
constructor(bytes) {
|
|
114
|
+
this.bytes = bytes;
|
|
115
|
+
}
|
|
116
|
+
get done() {
|
|
117
|
+
return this.#offset >= this.bytes.length;
|
|
118
|
+
}
|
|
119
|
+
varint() {
|
|
120
|
+
let result = 0;
|
|
121
|
+
let multiplier = 1;
|
|
122
|
+
for (let index = 0; index < 10; index += 1) {
|
|
123
|
+
if (this.#offset >= this.bytes.length) {
|
|
124
|
+
throw invalid("The media descriptor is truncated.");
|
|
125
|
+
}
|
|
126
|
+
const byte = this.bytes[this.#offset++];
|
|
127
|
+
result += (byte & 0x7f) * multiplier;
|
|
128
|
+
if ((byte & 0x80) === 0) {
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
multiplier *= 128;
|
|
132
|
+
}
|
|
133
|
+
throw invalid("The media descriptor contains an invalid varint.");
|
|
134
|
+
}
|
|
135
|
+
bytesField() {
|
|
136
|
+
const length = this.varint();
|
|
137
|
+
if (length > this.bytes.length - this.#offset) {
|
|
138
|
+
throw invalid("The media descriptor is truncated.");
|
|
139
|
+
}
|
|
140
|
+
const value = this.bytes.subarray(this.#offset, this.#offset + length);
|
|
141
|
+
this.#offset += length;
|
|
142
|
+
return value;
|
|
143
|
+
}
|
|
144
|
+
skip(wireType) {
|
|
145
|
+
if (wireType === 0)
|
|
146
|
+
this.varint();
|
|
147
|
+
else if (wireType === 2)
|
|
148
|
+
this.bytesField();
|
|
149
|
+
else if (wireType === 1 || wireType === 5) {
|
|
150
|
+
const size = wireType === 1 ? 8 : 4;
|
|
151
|
+
if (size > this.bytes.length - this.#offset) {
|
|
152
|
+
throw invalid("The media descriptor is truncated.");
|
|
153
|
+
}
|
|
154
|
+
this.#offset += size;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
throw invalid("The media descriptor uses an unsupported wire type.");
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function text(bytes, limit) {
|
|
162
|
+
if (bytes.length > limit)
|
|
163
|
+
throw invalid("A media descriptor field is too long.");
|
|
164
|
+
try {
|
|
165
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
throw invalid("A media descriptor field is not valid UTF-8.");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function hash(bytes, name) {
|
|
172
|
+
if (bytes.length !== 32) {
|
|
173
|
+
throw invalid(`${name} must be 32 bytes.`);
|
|
174
|
+
}
|
|
175
|
+
return bytes.slice();
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Decodes the base64 `media` field of a message webhook. The input is treated
|
|
179
|
+
* as untrusted: only varint and length-delimited fields are interpreted, and
|
|
180
|
+
* lengths, hash sizes and string sizes are bounded.
|
|
181
|
+
*/
|
|
182
|
+
export function decodeWhatsAppMedia(base64, messageType) {
|
|
183
|
+
if (typeof base64 !== "string")
|
|
184
|
+
throw invalid("media must be a string.");
|
|
185
|
+
const mediaKind = asKind(messageType);
|
|
186
|
+
const fields = FIELDS[mediaKind];
|
|
187
|
+
const reader = new ProtoReader(decodeBase64(base64));
|
|
188
|
+
const out = {};
|
|
189
|
+
while (!reader.done) {
|
|
190
|
+
const tag = reader.varint();
|
|
191
|
+
const field = Math.floor(tag / 8);
|
|
192
|
+
const wireType = tag % 8;
|
|
193
|
+
if (field === 0)
|
|
194
|
+
throw invalid("The media descriptor has field number 0.");
|
|
195
|
+
if (field === fields.fileLength && wireType === 0) {
|
|
196
|
+
const value = reader.varint();
|
|
197
|
+
if (!Number.isSafeInteger(value)) {
|
|
198
|
+
throw invalid("fileLength is out of range.");
|
|
199
|
+
}
|
|
200
|
+
out.fileLength = value;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (wireType !== 2) {
|
|
204
|
+
reader.skip(wireType);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const value = reader.bytesField();
|
|
208
|
+
switch (field) {
|
|
209
|
+
case fields.url:
|
|
210
|
+
out.url = text(value, MAX_URL_LENGTH);
|
|
211
|
+
break;
|
|
212
|
+
case fields.directPath:
|
|
213
|
+
out.directPath = text(value, MAX_URL_LENGTH);
|
|
214
|
+
break;
|
|
215
|
+
case fields.mimetype:
|
|
216
|
+
out.mimetype = text(value, 255);
|
|
217
|
+
break;
|
|
218
|
+
case fields.fileName:
|
|
219
|
+
out.fileName = text(value, MAX_TEXT_LENGTH);
|
|
220
|
+
break;
|
|
221
|
+
case fields.mediaKey:
|
|
222
|
+
if (value.length !== 32)
|
|
223
|
+
throw invalid("mediaKey must be 32 bytes.");
|
|
224
|
+
out.mediaKey = value.slice();
|
|
225
|
+
break;
|
|
226
|
+
case fields.fileSha256:
|
|
227
|
+
out.fileSha256 = hash(value, "fileSha256");
|
|
228
|
+
break;
|
|
229
|
+
case fields.fileEncSha256:
|
|
230
|
+
out.fileEncSha256 = hash(value, "fileEncSha256");
|
|
231
|
+
break;
|
|
232
|
+
default:
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (out.mediaKey === undefined) {
|
|
237
|
+
throw invalid("The media descriptor has no mediaKey.");
|
|
238
|
+
}
|
|
239
|
+
return Object.freeze({ mediaKind, ...out, mediaKey: out.mediaKey });
|
|
240
|
+
}
|
|
241
|
+
function subtle() {
|
|
242
|
+
const value = globalThis.crypto?.subtle;
|
|
243
|
+
if (value === undefined) {
|
|
244
|
+
throw new PolymorfaConfigurationError("WhatsApp media decryption requires WebCrypto (crypto.subtle).", "crypto");
|
|
245
|
+
}
|
|
246
|
+
return value;
|
|
247
|
+
}
|
|
248
|
+
function buffer(bytes) {
|
|
249
|
+
return bytes.slice().buffer;
|
|
250
|
+
}
|
|
251
|
+
/** HKDF-SHA256(mediaKey, info, 112): iv [0,16), cipherKey [16,48), macKey [48,80). */
|
|
252
|
+
export async function deriveWhatsAppMediaKeys(mediaKey, mediaKind) {
|
|
253
|
+
if (!(mediaKey instanceof Uint8Array) || mediaKey.length !== 32) {
|
|
254
|
+
throw invalid("mediaKey must be 32 bytes.");
|
|
255
|
+
}
|
|
256
|
+
const info = HKDF_INFO[asKind(mediaKind)];
|
|
257
|
+
const material = await subtle().importKey("raw", buffer(mediaKey), "HKDF", false, ["deriveBits"]);
|
|
258
|
+
const expanded = new Uint8Array(await subtle().deriveBits({
|
|
259
|
+
name: "HKDF",
|
|
260
|
+
hash: "SHA-256",
|
|
261
|
+
salt: new ArrayBuffer(0),
|
|
262
|
+
info: new TextEncoder().encode(info),
|
|
263
|
+
}, material, 112 * 8));
|
|
264
|
+
return Object.freeze({
|
|
265
|
+
iv: expanded.slice(0, 16),
|
|
266
|
+
cipherKey: expanded.slice(16, 48),
|
|
267
|
+
macKey: expanded.slice(48, 80),
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
/** Constant-time comparison of equal-length byte arrays. */
|
|
271
|
+
export function timingSafeEqualBytes(a, b) {
|
|
272
|
+
if (a.length !== b.length)
|
|
273
|
+
return false;
|
|
274
|
+
let difference = 0;
|
|
275
|
+
for (let index = 0; index < a.length; index += 1) {
|
|
276
|
+
difference |= a[index] ^ b[index];
|
|
277
|
+
}
|
|
278
|
+
return difference === 0;
|
|
279
|
+
}
|
|
280
|
+
async function readAll(stream) {
|
|
281
|
+
const chunks = [];
|
|
282
|
+
let total = 0;
|
|
283
|
+
const reader = stream.getReader();
|
|
284
|
+
while (true) {
|
|
285
|
+
const { done, value } = await reader.read();
|
|
286
|
+
if (done)
|
|
287
|
+
break;
|
|
288
|
+
chunks.push(value);
|
|
289
|
+
total += value.length;
|
|
290
|
+
}
|
|
291
|
+
const out = new Uint8Array(total);
|
|
292
|
+
let offset = 0;
|
|
293
|
+
for (const chunk of chunks) {
|
|
294
|
+
out.set(chunk, offset);
|
|
295
|
+
offset += chunk.length;
|
|
296
|
+
}
|
|
297
|
+
return out;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Verifies and decrypts a complete encrypted file (`ciphertext || mac10`)
|
|
301
|
+
* with WebCrypto, in whatsmeow's order: length, encrypted-file SHA-256, MAC,
|
|
302
|
+
* AES-256-CBC with PKCS#7, plaintext SHA-256.
|
|
303
|
+
*/
|
|
304
|
+
async function decryptBuffered(data, keys, options) {
|
|
305
|
+
const crypto = subtle();
|
|
306
|
+
if (data.length <= MAC_LENGTH) {
|
|
307
|
+
throw new PolymorfaMediaIntegrityError("The encrypted media is too short.", "media_too_short");
|
|
308
|
+
}
|
|
309
|
+
const ciphertext = data.subarray(0, data.length - MAC_LENGTH);
|
|
310
|
+
const mac = data.subarray(data.length - MAC_LENGTH);
|
|
311
|
+
if (options.fileEncSha256 !== undefined) {
|
|
312
|
+
const digest = new Uint8Array(await crypto.digest("SHA-256", buffer(data)));
|
|
313
|
+
if (!timingSafeEqualBytes(digest, options.fileEncSha256)) {
|
|
314
|
+
throw new PolymorfaMediaIntegrityError("The encrypted media hash does not match.", "media_enc_hash_mismatch");
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
const macKey = await crypto.importKey("raw", buffer(keys.macKey), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
318
|
+
const signed = new Uint8Array(ciphertext.length + BLOCK);
|
|
319
|
+
signed.set(keys.iv, 0);
|
|
320
|
+
signed.set(ciphertext, BLOCK);
|
|
321
|
+
const expected = new Uint8Array(await crypto.sign("HMAC", macKey, signed)).subarray(0, MAC_LENGTH);
|
|
322
|
+
if (!timingSafeEqualBytes(expected, mac)) {
|
|
323
|
+
throw new PolymorfaMediaIntegrityError("The media MAC does not match.", "media_mac_mismatch");
|
|
324
|
+
}
|
|
325
|
+
if (ciphertext.length === 0 || ciphertext.length % BLOCK !== 0) {
|
|
326
|
+
throw new PolymorfaMediaIntegrityError("The ciphertext is not a whole number of blocks.", "media_invalid_ciphertext");
|
|
327
|
+
}
|
|
328
|
+
const cipherKey = await crypto.importKey("raw", buffer(keys.cipherKey), "AES-CBC", false, ["decrypt"]);
|
|
329
|
+
let plaintext;
|
|
330
|
+
try {
|
|
331
|
+
plaintext = new Uint8Array(await crypto.decrypt({ name: "AES-CBC", iv: buffer(keys.iv) }, cipherKey, buffer(ciphertext)));
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
throw new PolymorfaMediaIntegrityError(`The media padding is invalid (${String(error)}).`, "media_invalid_padding");
|
|
335
|
+
}
|
|
336
|
+
if (options.fileSha256 !== undefined) {
|
|
337
|
+
const digest = new Uint8Array(await crypto.digest("SHA-256", buffer(plaintext)));
|
|
338
|
+
if (!timingSafeEqualBytes(digest, options.fileSha256)) {
|
|
339
|
+
throw new PolymorfaMediaIntegrityError("The decrypted media hash does not match.", "media_hash_mismatch");
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return plaintext;
|
|
343
|
+
}
|
|
344
|
+
/** WebCrypto backend. It buffers the whole file and verifies before release. */
|
|
345
|
+
export const webCryptoMediaCrypto = Object.freeze({
|
|
346
|
+
incremental: false,
|
|
347
|
+
decrypt(ciphertext, keys, options) {
|
|
348
|
+
let result;
|
|
349
|
+
return new ReadableStream({
|
|
350
|
+
async pull(controller) {
|
|
351
|
+
if (result !== undefined) {
|
|
352
|
+
controller.close();
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
result = readAll(ciphertext).then((data) => decryptBuffered(data, keys, options));
|
|
356
|
+
const plaintext = await result;
|
|
357
|
+
if (plaintext.length > 0)
|
|
358
|
+
controller.enqueue(plaintext);
|
|
359
|
+
},
|
|
360
|
+
async cancel(reason) {
|
|
361
|
+
await ciphertext.cancel(reason).catch(() => undefined);
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
function resolveLimit(maxBytes) {
|
|
367
|
+
const value = maxBytes ?? DEFAULT_WHATSAPP_MEDIA_MAX_BYTES;
|
|
368
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
369
|
+
throw new PolymorfaConfigurationError("maxBytes must be a positive integer.", "maxBytes");
|
|
370
|
+
}
|
|
371
|
+
return value;
|
|
372
|
+
}
|
|
373
|
+
function encryptedLimit(maxBytes, fileLength) {
|
|
374
|
+
const plain = fileLength === undefined ? maxBytes : Math.min(maxBytes, fileLength);
|
|
375
|
+
if (fileLength !== undefined && fileLength > maxBytes) {
|
|
376
|
+
throw tooLarge();
|
|
377
|
+
}
|
|
378
|
+
return (Math.floor(plain / BLOCK) + 1) * BLOCK + MAC_LENGTH;
|
|
379
|
+
}
|
|
380
|
+
function tooLarge() {
|
|
381
|
+
return new PolymorfaMediaIntegrityError("The media exceeds the permitted size.", "media_too_large");
|
|
382
|
+
}
|
|
383
|
+
function cancelled(cause) {
|
|
384
|
+
return new PolymorfaCancelledError("The request was cancelled by the caller.", { code: "request_cancelled", cause });
|
|
385
|
+
}
|
|
386
|
+
/** Enforces a byte limit and maps abort and read failures. */
|
|
387
|
+
function limitStream(source, limit, signal) {
|
|
388
|
+
const reader = source.getReader();
|
|
389
|
+
let total = 0;
|
|
390
|
+
return new ReadableStream({
|
|
391
|
+
async pull(controller) {
|
|
392
|
+
try {
|
|
393
|
+
if (signal?.aborted === true)
|
|
394
|
+
throw signal.reason;
|
|
395
|
+
const { done, value } = await reader.read();
|
|
396
|
+
if (done) {
|
|
397
|
+
controller.close();
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
total += value.length;
|
|
401
|
+
if (total > limit) {
|
|
402
|
+
await reader.cancel().catch(() => undefined);
|
|
403
|
+
controller.error(tooLarge());
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
controller.enqueue(value);
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
controller.error(error instanceof PolymorfaError
|
|
410
|
+
? error
|
|
411
|
+
: signal?.aborted === true
|
|
412
|
+
? cancelled(error)
|
|
413
|
+
: new PolymorfaConnectionError("The media body could not be read.", { code: "connection_error", cause: error }));
|
|
414
|
+
}
|
|
415
|
+
},
|
|
416
|
+
async cancel(reason) {
|
|
417
|
+
await reader.cancel(reason);
|
|
418
|
+
},
|
|
419
|
+
}, { highWaterMark: 0 });
|
|
420
|
+
}
|
|
421
|
+
function toStream(input) {
|
|
422
|
+
if (input instanceof ReadableStream)
|
|
423
|
+
return input;
|
|
424
|
+
const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
|
|
425
|
+
return new ReadableStream({
|
|
426
|
+
start(controller) {
|
|
427
|
+
controller.enqueue(bytes);
|
|
428
|
+
controller.close();
|
|
429
|
+
},
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
function resolveVerify(verify, crypto) {
|
|
433
|
+
const mode = verify ?? "before-release";
|
|
434
|
+
if (mode !== "before-release" && mode !== "streaming") {
|
|
435
|
+
throw new PolymorfaConfigurationError("verify must be before-release or streaming.", "verify");
|
|
436
|
+
}
|
|
437
|
+
if (mode === "streaming" && !crypto.incremental) {
|
|
438
|
+
throw new PolymorfaConfigurationError("Streaming verification needs an incremental backend such as nodeMediaCrypto.", "verify");
|
|
439
|
+
}
|
|
440
|
+
return mode;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Verifies and decrypts media you fetched yourself. Accepts the complete
|
|
444
|
+
* encrypted file (`ciphertext || mac10`) as bytes or a stream.
|
|
445
|
+
*/
|
|
446
|
+
export function decryptWhatsAppMedia(input, keys, options = {}) {
|
|
447
|
+
const crypto = options.crypto ?? webCryptoMediaCrypto;
|
|
448
|
+
const limit = encryptedLimit(resolveLimit(options.maxBytes), options.fileLength);
|
|
449
|
+
return crypto.decrypt(limitStream(toStream(input), limit, options.signal), keys, {
|
|
450
|
+
fileSha256: options.fileSha256,
|
|
451
|
+
fileEncSha256: options.fileEncSha256,
|
|
452
|
+
verify: resolveVerify(options.verify, crypto),
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
function isDescriptor(input) {
|
|
456
|
+
return (typeof input === "object" &&
|
|
457
|
+
input !== null &&
|
|
458
|
+
"mediaKey" in input &&
|
|
459
|
+
"mediaKind" in input);
|
|
460
|
+
}
|
|
461
|
+
function descriptorFrom(input) {
|
|
462
|
+
if (isDescriptor(input))
|
|
463
|
+
return input;
|
|
464
|
+
if (typeof input !== "object" ||
|
|
465
|
+
input === null ||
|
|
466
|
+
typeof input.media !== "string") {
|
|
467
|
+
throw invalid("The message has no encrypted media descriptor. Persisted media is available through mediaUrl or the Media API instead.");
|
|
468
|
+
}
|
|
469
|
+
return decodeWhatsAppMedia(input.media, input.type);
|
|
470
|
+
}
|
|
471
|
+
/** True for HTTPS URLs on a WhatsApp media host (`*.whatsapp.net`, default port). */
|
|
472
|
+
export function isWhatsAppMediaUrl(value) {
|
|
473
|
+
let url;
|
|
474
|
+
try {
|
|
475
|
+
url = new URL(value);
|
|
476
|
+
}
|
|
477
|
+
catch {
|
|
478
|
+
return false;
|
|
479
|
+
}
|
|
480
|
+
const host = url.hostname.toLowerCase();
|
|
481
|
+
return (url.protocol === "https:" &&
|
|
482
|
+
url.port === "" &&
|
|
483
|
+
url.username === "" &&
|
|
484
|
+
url.password === "" &&
|
|
485
|
+
(host === "whatsapp.net" || host.endsWith(".whatsapp.net")));
|
|
486
|
+
}
|
|
487
|
+
function base64Url(bytes) {
|
|
488
|
+
let binary = "";
|
|
489
|
+
for (const byte of bytes)
|
|
490
|
+
binary += String.fromCharCode(byte);
|
|
491
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_");
|
|
492
|
+
}
|
|
493
|
+
function candidateUrls(descriptor) {
|
|
494
|
+
const urls = [];
|
|
495
|
+
if (descriptor.url !== undefined && descriptor.url.length > 0) {
|
|
496
|
+
if (!isWhatsAppMediaUrl(descriptor.url)) {
|
|
497
|
+
throw invalid("The media URL is not an HTTPS WhatsApp media host.");
|
|
498
|
+
}
|
|
499
|
+
urls.push(descriptor.url);
|
|
500
|
+
}
|
|
501
|
+
const path = descriptor.directPath;
|
|
502
|
+
if (path !== undefined && path.length > 0) {
|
|
503
|
+
if (!path.startsWith("/") || path.startsWith("//")) {
|
|
504
|
+
throw invalid("directPath must start with a single slash.");
|
|
505
|
+
}
|
|
506
|
+
// Same shape as whatsmeow DownloadMediaWithPath.
|
|
507
|
+
const separator = path.includes("?") ? "&" : "?";
|
|
508
|
+
const hashParam = descriptor.fileEncSha256 === undefined
|
|
509
|
+
? ""
|
|
510
|
+
: base64Url(descriptor.fileEncSha256);
|
|
511
|
+
const fallback = `https://${FALLBACK_HOST}${path}${separator}hash=${encodeURIComponent(hashParam)}&mms-type=${MMS_TYPE[descriptor.mediaKind]}&__wa-mms=`;
|
|
512
|
+
if (!isWhatsAppMediaUrl(fallback)) {
|
|
513
|
+
throw invalid("directPath does not form a valid media URL.");
|
|
514
|
+
}
|
|
515
|
+
if (!urls.includes(fallback))
|
|
516
|
+
urls.push(fallback);
|
|
517
|
+
}
|
|
518
|
+
if (urls.length === 0) {
|
|
519
|
+
throw invalid("The media descriptor has neither url nor directPath.");
|
|
520
|
+
}
|
|
521
|
+
return urls;
|
|
522
|
+
}
|
|
523
|
+
async function fetchCdn(url, fetcher, signal) {
|
|
524
|
+
let current = url;
|
|
525
|
+
for (let hop = 0; hop <= 3; hop += 1) {
|
|
526
|
+
const response = await fetcher(current, {
|
|
527
|
+
method: "GET",
|
|
528
|
+
headers: { origin: WEB_ORIGIN, referer: `${WEB_ORIGIN}/` },
|
|
529
|
+
redirect: "manual",
|
|
530
|
+
credentials: "omit",
|
|
531
|
+
referrerPolicy: "no-referrer",
|
|
532
|
+
...(signal === undefined ? {} : { signal }),
|
|
533
|
+
});
|
|
534
|
+
if (![301, 302, 303, 307, 308].includes(response.status)) {
|
|
535
|
+
return response;
|
|
536
|
+
}
|
|
537
|
+
const location = response.headers.get("location");
|
|
538
|
+
await response.body?.cancel().catch(() => undefined);
|
|
539
|
+
const next = location === null ? undefined : new URL(location, current).toString();
|
|
540
|
+
if (next === undefined || !isWhatsAppMediaUrl(next)) {
|
|
541
|
+
throw invalid("The media host redirected outside WhatsApp media hosts.");
|
|
542
|
+
}
|
|
543
|
+
current = next;
|
|
544
|
+
}
|
|
545
|
+
throw new PolymorfaConnectionError("Too many media redirects.", {
|
|
546
|
+
code: "connection_error",
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Downloads an attachment straight from the WhatsApp CDN and decrypts it
|
|
551
|
+
* locally. No Polymorfa credential is involved or sent. The CDN URL in the
|
|
552
|
+
* descriptor expires; the `directPath` fallback also stops working once
|
|
553
|
+
* WhatsApp removes the object.
|
|
554
|
+
*/
|
|
555
|
+
export async function downloadWhatsAppMedia(input, options = {}) {
|
|
556
|
+
const descriptor = descriptorFrom(input);
|
|
557
|
+
const crypto = options.crypto ?? webCryptoMediaCrypto;
|
|
558
|
+
const verify = resolveVerify(options.verify, crypto);
|
|
559
|
+
const maxBytes = resolveLimit(options.maxBytes);
|
|
560
|
+
const limit = encryptedLimit(maxBytes, descriptor.fileLength);
|
|
561
|
+
if (descriptor.fileSha256 === undefined) {
|
|
562
|
+
// whatsmeow treats a missing plaintext hash as a verification failure.
|
|
563
|
+
throw invalid("The media descriptor has no fileSha256.");
|
|
564
|
+
}
|
|
565
|
+
const urls = candidateUrls(descriptor);
|
|
566
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
567
|
+
const keys = await deriveWhatsAppMediaKeys(descriptor.mediaKey, descriptor.mediaKind);
|
|
568
|
+
let failure;
|
|
569
|
+
let response;
|
|
570
|
+
for (const url of urls) {
|
|
571
|
+
try {
|
|
572
|
+
const candidate = await fetchCdn(url, fetcher, options.signal);
|
|
573
|
+
if (candidate.ok) {
|
|
574
|
+
response = candidate;
|
|
575
|
+
break;
|
|
576
|
+
}
|
|
577
|
+
await candidate.body?.cancel().catch(() => undefined);
|
|
578
|
+
failure = new PolymorfaError(`The WhatsApp media host returned status ${candidate.status}.`, { status: candidate.status, code: "media_download_failed" });
|
|
579
|
+
}
|
|
580
|
+
catch (error) {
|
|
581
|
+
if (options.signal?.aborted === true)
|
|
582
|
+
throw cancelled(error);
|
|
583
|
+
if (error instanceof PolymorfaError)
|
|
584
|
+
throw error;
|
|
585
|
+
failure = new PolymorfaConnectionError("The WhatsApp media host could not be reached.", { code: "connection_error", cause: error });
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (response === undefined) {
|
|
589
|
+
throw failure instanceof Error
|
|
590
|
+
? failure
|
|
591
|
+
: new PolymorfaConnectionError("Media download failed.");
|
|
592
|
+
}
|
|
593
|
+
const lengthHeader = response.headers.get("content-length");
|
|
594
|
+
if (lengthHeader !== null && Number(lengthHeader) > limit) {
|
|
595
|
+
await response.body?.cancel().catch(() => undefined);
|
|
596
|
+
throw tooLarge();
|
|
597
|
+
}
|
|
598
|
+
const source = response.body ??
|
|
599
|
+
new ReadableStream({
|
|
600
|
+
start(controller) {
|
|
601
|
+
controller.close();
|
|
602
|
+
},
|
|
603
|
+
});
|
|
604
|
+
const body = crypto.decrypt(limitStream(source, limit, options.signal), keys, {
|
|
605
|
+
fileSha256: descriptor.fileSha256,
|
|
606
|
+
fileEncSha256: descriptor.fileEncSha256,
|
|
607
|
+
verify,
|
|
608
|
+
});
|
|
609
|
+
const mimetype = descriptor.mimetype ?? DEFAULT_MIME[descriptor.mediaKind];
|
|
610
|
+
return Object.freeze({
|
|
611
|
+
body,
|
|
612
|
+
mediaKind: descriptor.mediaKind,
|
|
613
|
+
mimetype,
|
|
614
|
+
...(descriptor.fileName === undefined
|
|
615
|
+
? {}
|
|
616
|
+
: { fileName: descriptor.fileName }),
|
|
617
|
+
...(descriptor.fileLength === undefined
|
|
618
|
+
? {}
|
|
619
|
+
: { fileLength: descriptor.fileLength }),
|
|
620
|
+
arrayBuffer: async () => buffer(await readAll(body)),
|
|
621
|
+
blob: async () => new Blob([buffer(await readAll(body))], { type: mimetype }),
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
//# sourceMappingURL=whatsapp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../src/media/whatsapp.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,wBAAwB,EACxB,cAAc,EACd,4BAA4B,GAC7B,MAAM,cAAc,CAAC;AA6FtB,MAAM,CAAC,MAAM,gCAAgC,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAClE,MAAM,4BAA4B,GAAG,IAAI,GAAG,IAAI,CAAC;AACjD,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,eAAe,GAAG,IAAI,CAAC;AAC7B,MAAM,UAAU,GAAG,EAAE,CAAC;AACtB,MAAM,KAAK,GAAG,EAAE,CAAC;AACjB,MAAM,aAAa,GAAG,kBAAkB,CAAC;AACzC,MAAM,UAAU,GAAG,0BAA0B,CAAC;AAE9C,MAAM,SAAS,GAAgD;IAC7D,KAAK,EAAE,qBAAqB;IAC5B,KAAK,EAAE,qBAAqB;IAC5B,KAAK,EAAE,qBAAqB;IAC5B,QAAQ,EAAE,wBAAwB;IAClC,oEAAoE;IACpE,OAAO,EAAE,qBAAqB;CAC/B,CAAC;AAEF,MAAM,QAAQ,GAAgD;IAC5D,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,OAAO;CACjB,CAAC;AAaF,oEAAoE;AACpE,MAAM,MAAM,GAAkD;IAC5D,KAAK,EAAE;QACL,GAAG,EAAE,CAAC;QACN,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC;QACX,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,EAAE;KACf;IACD,KAAK,EAAE;QACL,GAAG,EAAE,CAAC;QACN,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC;QACX,aAAa,EAAE,EAAE;QACjB,UAAU,EAAE,EAAE;KACf;IACD,KAAK,EAAE;QACL,GAAG,EAAE,CAAC;QACN,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC;QACX,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,CAAC;KACd;IACD,QAAQ,EAAE;QACR,GAAG,EAAE,CAAC;QACN,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC;QACX,QAAQ,EAAE,CAAC;QACX,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,EAAE;KACf;IACD,OAAO,EAAE;QACP,GAAG,EAAE,CAAC;QACN,UAAU,EAAE,CAAC;QACb,aAAa,EAAE,CAAC;QAChB,QAAQ,EAAE,CAAC;QACX,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;KACd;CACF,CAAC;AAEF,MAAM,YAAY,GAAgD;IAChE,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,WAAW;IAClB,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE,0BAA0B;IACpC,OAAO,EAAE,YAAY;CACtB,CAAC;AAEF,SAAS,OAAO,CAAC,OAAe;IAC9B,OAAO,IAAI,4BAA4B,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC;AAC/E,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;QAAE,OAAO,IAAyB,CAAC;IAClE,MAAM,OAAO,CAAC,gBAAgB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,IAAI,KAAK,CAAC,MAAM,GAAG,4BAA4B,EAAE,CAAC;QAChD,MAAM,OAAO,CAAC,8CAA8C,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/D,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1E,MAAM,OAAO,CAAC,2CAA2C,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,OAAO,CAAC,2CAA2C,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,WAAW;IAEc;IAD7B,OAAO,GAAG,CAAC,CAAC;IACZ,YAA6B,KAAiB;QAAjB,UAAK,GAAL,KAAK,CAAY;IAAG,CAAC;IAElD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3C,CAAC;IAED,MAAM;QACJ,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACtC,MAAM,OAAO,CAAC,oCAAoC,CAAC,CAAC;YACtD,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAE,CAAC;YACzC,MAAM,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,UAAU,CAAC;YACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,UAAU,IAAI,GAAG,CAAC;QACpB,CAAC;QACD,MAAM,OAAO,CAAC,kDAAkD,CAAC,CAAC;IACpE,CAAC;IAED,UAAU;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC9C,MAAM,OAAO,CAAC,oCAAoC,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;QACvE,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,QAAgB;QACnB,IAAI,QAAQ,KAAK,CAAC;YAAE,IAAI,CAAC,MAAM,EAAE,CAAC;aAC7B,IAAI,QAAQ,KAAK,CAAC;YAAE,IAAI,CAAC,UAAU,EAAE,CAAC;aACtC,IAAI,QAAQ,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC5C,MAAM,OAAO,CAAC,oCAAoC,CAAC,CAAC;YACtD,CAAC;YACD,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,CAAC,qDAAqD,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;CACF;AAED,SAAS,IAAI,CAAC,KAAiB,EAAE,KAAa;IAC5C,IAAI,KAAK,CAAC,MAAM,GAAG,KAAK;QACtB,MAAM,OAAO,CAAC,uCAAuC,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,OAAO,CAAC,8CAA8C,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,SAAS,IAAI,CAAC,KAAiB,EAAE,IAAY;IAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACxB,MAAM,OAAO,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,WAAmB;IAEnB,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,MAAM,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACzE,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,MAAM,GAAG,GASL,EAAE,CAAC;IACP,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,CAAC;QACzB,IAAI,KAAK,KAAK,CAAC;YAAE,MAAM,OAAO,CAAC,0CAA0C,CAAC,CAAC;QAC3E,IAAI,KAAK,KAAK,MAAM,CAAC,UAAU,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YAClD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,MAAM,OAAO,CAAC,6BAA6B,CAAC,CAAC;YAC/C,CAAC;YACD,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC;YACvB,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtB,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAClC,QAAQ,KAAK,EAAE,CAAC;YACd,KAAK,MAAM,CAAC,GAAG;gBACb,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;gBACtC,MAAM;YACR,KAAK,MAAM,CAAC,UAAU;gBACpB,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;gBAC7C,MAAM;YACR,KAAK,MAAM,CAAC,QAAQ;gBAClB,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBAChC,MAAM;YACR,KAAK,MAAM,CAAC,QAAQ;gBAClB,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;gBAC5C,MAAM;YACR,KAAK,MAAM,CAAC,QAAQ;gBAClB,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;oBAAE,MAAM,OAAO,CAAC,4BAA4B,CAAC,CAAC;gBACrE,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC7B,MAAM;YACR,KAAK,MAAM,CAAC,UAAU;gBACpB,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;gBAC3C,MAAM;YACR,KAAK,MAAM,CAAC,aAAa;gBACvB,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;gBACjD,MAAM;YACR;gBACE,MAAM;QACV,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,OAAO,CAAC,uCAAuC,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,MAAM;IACb,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC;IACxC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,2BAA2B,CACnC,+DAA+D,EAC/D,QAAQ,CACT,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,MAAM,CAAC,KAAiB;IAC/B,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC;AAC9B,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAoB,EACpB,SAA4B;IAE5B,IAAI,CAAC,CAAC,QAAQ,YAAY,UAAU,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAChE,MAAM,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAC9C,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,MAAM,MAAM,EAAE,CAAC,SAAS,CACvC,KAAK,EACL,MAAM,CAAC,QAAQ,CAAC,EAChB,MAAM,EACN,KAAK,EACL,CAAC,YAAY,CAAC,CACf,CAAC;IACF,MAAM,QAAQ,GAAG,IAAI,UAAU,CAC7B,MAAM,MAAM,EAAE,CAAC,UAAU,CACvB;QACE,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,IAAI,WAAW,CAAC,CAAC,CAAC;QACxB,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;KACrC,EACD,QAAQ,EACR,GAAG,GAAG,CAAC,CACR,CACF,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACzB,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;QACjC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,oBAAoB,CAAC,CAAa,EAAE,CAAa;IAC/D,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACjD,UAAU,IAAI,CAAC,CAAC,KAAK,CAAE,GAAG,CAAC,CAAC,KAAK,CAAE,CAAC;IACtC,CAAC;IACD,OAAO,UAAU,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,KAAK,UAAU,OAAO,CACpB,MAAkC;IAElC,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAClC,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,IAAI;YAAE,MAAM;QAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;IACxB,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;IACzB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,eAAe,CAC5B,IAAgB,EAChB,IAAuB,EACvB,OAA+B;IAE/B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,IAAI,IAAI,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,IAAI,4BAA4B,CACpC,mCAAmC,EACnC,iBAAiB,CAClB,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IACpD,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5E,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,4BAA4B,CACpC,0CAA0C,EAC1C,yBAAyB,CAC1B,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CACnC,KAAK,EACL,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EACnB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EACjC,KAAK,EACL,CAAC,MAAM,CAAC,CACT,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;IACzD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACvB,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,IAAI,UAAU,CAC7B,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAC1C,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1B,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,4BAA4B,CACpC,+BAA+B,EAC/B,oBAAoB,CACrB,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,KAAK,KAAK,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,4BAA4B,CACpC,iDAAiD,EACjD,0BAA0B,CAC3B,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,SAAS,CACtC,KAAK,EACL,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EACtB,SAAS,EACT,KAAK,EACL,CAAC,SAAS,CAAC,CACZ,CAAC;IACF,IAAI,SAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,SAAS,GAAG,IAAI,UAAU,CACxB,MAAM,MAAM,CAAC,OAAO,CAClB,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EACxC,SAAS,EACT,MAAM,CAAC,UAAU,CAAC,CACnB,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,4BAA4B,CACpC,iCAAiC,MAAM,CAAC,KAAK,CAAC,IAAI,EAClD,uBAAuB,CACxB,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,UAAU,CAC3B,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAClD,CAAC;QACF,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACtD,MAAM,IAAI,4BAA4B,CACpC,0CAA0C,EAC1C,qBAAqB,CACtB,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,MAAM,oBAAoB,GAAwB,MAAM,CAAC,MAAM,CAAC;IACrE,WAAW,EAAE,KAAK;IAClB,OAAO,CACL,UAAsC,EACtC,IAAuB,EACvB,OAA+B;QAE/B,IAAI,MAAuC,CAAC;QAC5C,OAAO,IAAI,cAAc,CAAa;YACpC,KAAK,CAAC,IAAI,CAAC,UAAU;gBACnB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,UAAU,CAAC,KAAK,EAAE,CAAC;oBACnB,OAAO;gBACT,CAAC;gBACD,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACzC,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CACrC,CAAC;gBACF,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC;gBAC/B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;oBAAE,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC1D,CAAC;YACD,KAAK,CAAC,MAAM,CAAC,MAAM;gBACjB,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACzD,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,SAAS,YAAY,CAAC,QAA4B;IAChD,MAAM,KAAK,GAAG,QAAQ,IAAI,gCAAgC,CAAC;IAC3D,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,2BAA2B,CACnC,sCAAsC,EACtC,UAAU,CACX,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,QAAgB,EAAE,UAAmB;IAC3D,MAAM,KAAK,GACT,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACvE,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,GAAG,QAAQ,EAAE,CAAC;QACtD,MAAM,QAAQ,EAAE,CAAC;IACnB,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,UAAU,CAAC;AAC9D,CAAC;AAED,SAAS,QAAQ;IACf,OAAO,IAAI,4BAA4B,CACrC,uCAAuC,EACvC,iBAAiB,CAClB,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,IAAI,uBAAuB,CAChC,0CAA0C,EAC1C,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,CACrC,CAAC;AACJ,CAAC;AAED,8DAA8D;AAC9D,SAAS,WAAW,CAClB,MAAkC,EAClC,KAAa,EACb,MAA+B;IAE/B,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAClC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,IAAI,cAAc,CACvB;QACE,KAAK,CAAC,IAAI,CAAC,UAAU;YACnB,IAAI,CAAC;gBACH,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI;oBAAE,MAAM,MAAM,CAAC,MAAM,CAAC;gBAClD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC5C,IAAI,IAAI,EAAE,CAAC;oBACT,UAAU,CAAC,KAAK,EAAE,CAAC;oBACnB,OAAO;gBACT,CAAC;gBACD,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;gBACtB,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC;oBAClB,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;oBAC7C,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;oBAC7B,OAAO;gBACT,CAAC;gBACD,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,UAAU,CAAC,KAAK,CACd,KAAK,YAAY,cAAc;oBAC7B,CAAC,CAAC,KAAK;oBACP,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI;wBACxB,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC;wBAClB,CAAC,CAAC,IAAI,wBAAwB,CAC1B,mCAAmC,EACnC,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,CAC3C,CACR,CAAC;YACJ,CAAC;QACH,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,MAAM;YACjB,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;KACF,EACD,EAAE,aAAa,EAAE,CAAC,EAAE,CACrB,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CACf,KAA4D;IAE5D,IAAI,KAAK,YAAY,cAAc;QAAE,OAAO,KAAK,CAAC;IAClD,MAAM,KAAK,GAAG,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAC1E,OAAO,IAAI,cAAc,CAAa;QACpC,KAAK,CAAC,UAAU;YACd,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1B,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CACpB,MAA2C,EAC3C,MAA2B;IAE3B,MAAM,IAAI,GAAG,MAAM,IAAI,gBAAgB,CAAC;IACxC,IAAI,IAAI,KAAK,gBAAgB,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACtD,MAAM,IAAI,2BAA2B,CACnC,6CAA6C,EAC7C,QAAQ,CACT,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAChD,MAAM,IAAI,2BAA2B,CACnC,8EAA8E,EAC9E,QAAQ,CACT,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAA4D,EAC5D,IAAuB,EACvB,UAEI,EAAE;IAEN,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAAC;IACtD,MAAM,KAAK,GAAG,cAAc,CAC1B,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,EAC9B,OAAO,CAAC,UAAU,CACnB,CAAC;IACF,OAAO,MAAM,CAAC,OAAO,CACnB,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EACnD,IAAI,EACJ;QACE,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;KAC9C,CACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,KAAyB;IAEzB,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,UAAU,IAAI,KAAK;QACnB,WAAW,IAAI,KAAK,CACrB,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAyB;IAC/C,IAAI,YAAY,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAC/B,CAAC;QACD,MAAM,OAAO,CACX,wHAAwH,CACzH,CAAC;IACJ,CAAC;IACD,OAAO,mBAAmB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACxC,OAAO,CACL,GAAG,CAAC,QAAQ,KAAK,QAAQ;QACzB,GAAG,CAAC,IAAI,KAAK,EAAE;QACf,GAAG,CAAC,QAAQ,KAAK,EAAE;QACnB,GAAG,CAAC,QAAQ,KAAK,EAAE;QACnB,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,KAAiB;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC9D,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,aAAa,CAAC,UAAmC;IACxD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,OAAO,CAAC,oDAAoD,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC;IACnC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,OAAO,CAAC,4CAA4C,CAAC,CAAC;QAC9D,CAAC;QACD,iDAAiD;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACjD,MAAM,SAAS,GACb,UAAU,CAAC,aAAa,KAAK,SAAS;YACpC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,WAAW,aAAa,GAAG,IAAI,GAAG,SAAS,QAAQ,kBAAkB,CAAC,SAAS,CAAC,aAAa,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,YAAY,CAAC;QACzJ,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,MAAM,OAAO,CAAC,6CAA6C,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,OAAO,CAAC,sDAAsD,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,QAAQ,CACrB,GAAW,EACX,OAAgC,EAChC,MAA+B;IAE/B,IAAI,OAAO,GAAG,GAAG,CAAC;IAClB,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE;YACtC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,UAAU,GAAG,EAAE;YAC1D,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,MAAM;YACnB,cAAc,EAAE,aAAa;YAC7B,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;SAC5C,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAClD,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,IAAI,GACR,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxE,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,MAAM,OAAO,CAAC,yDAAyD,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,MAAM,IAAI,wBAAwB,CAAC,2BAA2B,EAAE;QAC9D,IAAI,EAAE,kBAAkB;KACzB,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAAyB,EACzB,UAAwC,EAAE;IAE1C,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAAC;IACtD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC9D,IAAI,UAAU,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACxC,uEAAuE;QACvE,MAAM,OAAO,CAAC,yCAAyC,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,IAAI,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IAClD,MAAM,IAAI,GAAG,MAAM,uBAAuB,CACxC,UAAU,CAAC,QAAQ,EACnB,UAAU,CAAC,SAAS,CACrB,CAAC;IAEF,IAAI,OAAgB,CAAC;IACrB,IAAI,QAA8B,CAAC;IACnC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/D,IAAI,SAAS,CAAC,EAAE,EAAE,CAAC;gBACjB,QAAQ,GAAG,SAAS,CAAC;gBACrB,MAAM;YACR,CAAC;YACD,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACtD,OAAO,GAAG,IAAI,cAAc,CAC1B,2CAA2C,SAAS,CAAC,MAAM,GAAG,EAC9D,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAC5D,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI;gBAAE,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;YAC7D,IAAI,KAAK,YAAY,cAAc;gBAAE,MAAM,KAAK,CAAC;YACjD,OAAO,GAAG,IAAI,wBAAwB,CACpC,+CAA+C,EAC/C,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,CAC3C,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,OAAO,YAAY,KAAK;YAC5B,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,IAAI,wBAAwB,CAAC,wBAAwB,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC5D,IAAI,YAAY,KAAK,IAAI,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,EAAE,CAAC;QAC1D,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,QAAQ,EAAE,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GACV,QAAQ,CAAC,IAAI;QACb,IAAI,cAAc,CAAa;YAC7B,KAAK,CAAC,UAAU;gBACd,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;SACF,CAAC,CAAC;IACL,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CACzB,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAC1C,IAAI,EACJ;QACE,UAAU,EAAE,UAAU,CAAC,UAAU;QACjC,aAAa,EAAE,UAAU,CAAC,aAAa;QACvC,MAAM;KACP,CACF,CAAC;IACF,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC3E,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI;QACJ,SAAS,EAAE,UAAU,CAAC,SAAS;QAC/B,QAAQ;QACR,GAAG,CAAC,UAAU,CAAC,QAAQ,KAAK,SAAS;YACnC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;QACtC,GAAG,CAAC,UAAU,CAAC,UAAU,KAAK,SAAS;YACrC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,EAAE,CAAC;QAC1C,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACpD,IAAI,EAAE,KAAK,IAAI,EAAE,CACf,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;KAC9D,CAAC,CAAC;AACL,CAAC"}
|