@veriko-mx/sdk 0.4.9 → 0.4.11
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/CHANGELOG.md +34 -0
- package/README.md +76 -11
- package/dist/cjs/client.d.ts +5 -3
- package/dist/cjs/client.d.ts.map +1 -1
- package/dist/cjs/client.js +5 -3
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/generated/openapi.d.ts +89 -10
- package/dist/cjs/generated/openapi.d.ts.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +6 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/resources.d.ts +10 -1
- package/dist/cjs/resources.d.ts.map +1 -1
- package/dist/cjs/resources.js +19 -4
- package/dist/cjs/resources.js.map +1 -1
- package/dist/cjs/types.d.ts +14 -4
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/webhooks.d.ts +41 -1
- package/dist/cjs/webhooks.d.ts.map +1 -1
- package/dist/cjs/webhooks.js +94 -6
- package/dist/cjs/webhooks.js.map +1 -1
- package/dist/esm/client.d.ts +5 -3
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +5 -3
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/generated/openapi.d.ts +89 -10
- package/dist/esm/generated/openapi.d.ts.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/resources.d.ts +10 -1
- package/dist/esm/resources.d.ts.map +1 -1
- package/dist/esm/resources.js +19 -4
- package/dist/esm/resources.js.map +1 -1
- package/dist/esm/types.d.ts +14 -4
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/webhooks.d.ts +41 -1
- package/dist/esm/webhooks.d.ts.map +1 -1
- package/dist/esm/webhooks.js +91 -5
- package/dist/esm/webhooks.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/webhooks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/webhooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,YAAY,CAAC;AAElE,4BAA4B;AAC5B,eAAO,MAAM,gBAAgB,wBAAwB,CAAC;AAEtD,4DAA4D;AAC5D,eAAO,MAAM,4BAA4B,oCAAoC,CAAC;AAE9E,0EAA0E;AAC1E,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,sCAAsC;AACtC,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAC7C,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AACzD,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AASrD,KAAK,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;AAMnC,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,MAAM,EAAE,MAAM,GACb,OAAO,CAWT;AAED,oDAAoD;AACpD,MAAM,WAAW,wBAAwB;IACvC,+FAA+F;IAC/F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qFAAqF;IACrF,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AA4BD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAoBT;AAED,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;AAY/D;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAE3E;AAED,sFAAsF;AACtF,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAEtF;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,MAAM,EAAE,MAAM,GACb,YAAY,CA4Bd"}
|
package/dist/esm/webhooks.js
CHANGED
|
@@ -12,12 +12,23 @@
|
|
|
12
12
|
* el escape de los caracteres no ASCII no se conservan, y la firma deja de
|
|
13
13
|
* cuadrar. En Express, eso significa `express.raw()` en la ruta del webhook.
|
|
14
14
|
*
|
|
15
|
+
* Cada entrega lleva además una segunda firma que incluye la hora del intento:
|
|
16
|
+
*
|
|
17
|
+
* X-Webhook-Signature-Timestamped: t=<segundos>,v1=<hex>
|
|
18
|
+
*
|
|
19
|
+
* `v1` es el HMAC-SHA256 de `<t>.<cuerpo>`. Con ella el receptor puede descartar
|
|
20
|
+
* una entrega vieja que alguien vuelva a enviar.
|
|
21
|
+
*
|
|
15
22
|
* @see https://docs.veriko.mx/es/concepts/webhooks-architecture
|
|
16
23
|
*/
|
|
17
24
|
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
18
25
|
import { SignatureVerificationError } from './errors.js';
|
|
19
26
|
/** Cabecera de la firma. */
|
|
20
27
|
export const SIGNATURE_HEADER = 'X-Webhook-Signature';
|
|
28
|
+
/** Cabecera de la firma que incluye la hora del intento. */
|
|
29
|
+
export const TIMESTAMPED_SIGNATURE_HEADER = 'X-Webhook-Signature-Timestamped';
|
|
30
|
+
/** Ventana recomendada entre `t` y el reloj del receptor, en segundos. */
|
|
31
|
+
export const DEFAULT_TOLERANCE_SECONDS = 300;
|
|
21
32
|
/** Otras cabeceras de una entrega. */
|
|
22
33
|
export const EVENT_HEADER = 'X-Veriko-Event';
|
|
23
34
|
export const DELIVERY_ID_HEADER = 'X-Veriko-Delivery-Id';
|
|
@@ -59,14 +70,76 @@ export function verifyWebhook(payload, signature, secret) {
|
|
|
59
70
|
return false;
|
|
60
71
|
return timingSafeEqual(receivedBuffer, expectedBuffer);
|
|
61
72
|
}
|
|
73
|
+
const UNIX_SECONDS = /^[0-9]{1,15}$/;
|
|
62
74
|
/**
|
|
63
|
-
*
|
|
75
|
+
* Separa `t=<segundos>,v1=<hex>` en la hora y las firmas `v1`.
|
|
64
76
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
77
|
+
* Admite varias `v1` y descarta las claves que no conoce. Devuelve `undefined`
|
|
78
|
+
* cuando falta `t`, cuando trae más de una, o cuando no es un entero de segundos.
|
|
67
79
|
*/
|
|
68
|
-
|
|
69
|
-
const
|
|
80
|
+
function parseTimestamped(header) {
|
|
81
|
+
const times = [];
|
|
82
|
+
const digests = [];
|
|
83
|
+
for (const part of header.split(',')) {
|
|
84
|
+
const separator = part.indexOf('=');
|
|
85
|
+
if (separator === -1)
|
|
86
|
+
continue;
|
|
87
|
+
const key = part.slice(0, separator).trim();
|
|
88
|
+
const value = part.slice(separator + 1).trim();
|
|
89
|
+
if (key === 't')
|
|
90
|
+
times.push(value);
|
|
91
|
+
else if (key === 'v1')
|
|
92
|
+
digests.push(value.toLowerCase());
|
|
93
|
+
}
|
|
94
|
+
const timestamp = times[0];
|
|
95
|
+
if (times.length !== 1 || timestamp === undefined || !UNIX_SECONDS.test(timestamp)) {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
return { timestamp, digests };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Comprueba la firma con marca de tiempo de una entrega. Devuelve `true` o
|
|
102
|
+
* `false`, sin lanzar.
|
|
103
|
+
*
|
|
104
|
+
* Acepta el valor de la cabecera `X-Webhook-Signature-Timestamped`:
|
|
105
|
+
* `t=<segundos>,v1=<hex>`. Calcula el HMAC-SHA256 de `<t>.<cuerpo>`, lo compara
|
|
106
|
+
* en tiempo constante con cada `v1` y rechaza la entrega cuando `t` se aleja del
|
|
107
|
+
* reloj del receptor más de `toleranceSeconds`.
|
|
108
|
+
*
|
|
109
|
+
* La ventana se mide contra `t`, la hora de ese intento, y no contra el campo
|
|
110
|
+
* `timestamp` del cuerpo, que es la hora del evento. Un reintento llega hasta
|
|
111
|
+
* unas 8,6 horas después del evento, pero con una `t` nueva.
|
|
112
|
+
*
|
|
113
|
+
* @param payload El cuerpo crudo de la petición, sin reserializar.
|
|
114
|
+
* @param header El valor de la cabecera `X-Webhook-Signature-Timestamped`.
|
|
115
|
+
* @param secret El secreto del endpoint, entregado al registrarlo.
|
|
116
|
+
* @param options La ventana y la hora actual.
|
|
117
|
+
*/
|
|
118
|
+
export function verifyWebhookTimestamped(payload, header, secret, options = {}) {
|
|
119
|
+
if (!header || !secret)
|
|
120
|
+
return false;
|
|
121
|
+
const parsed = parseTimestamped(header);
|
|
122
|
+
if (!parsed)
|
|
123
|
+
return false;
|
|
124
|
+
const tolerance = options.toleranceSeconds ?? DEFAULT_TOLERANCE_SECONDS;
|
|
125
|
+
const nowSeconds = (options.now ?? new Date()).getTime() / 1000;
|
|
126
|
+
if (!(Math.abs(nowSeconds - Number(parsed.timestamp)) <= tolerance))
|
|
127
|
+
return false;
|
|
128
|
+
const signed = Buffer.concat([Buffer.from(`${parsed.timestamp}.`, 'utf8'), toBuffer(payload)]);
|
|
129
|
+
const expected = Buffer.from(createHmac('sha256', secret).update(signed).digest('hex'), 'utf8');
|
|
130
|
+
// Se comparan todas, sin cortar en la primera que cuadra.
|
|
131
|
+
let matched = false;
|
|
132
|
+
for (const digest of parsed.digests) {
|
|
133
|
+
const received = Buffer.from(digest, 'utf8');
|
|
134
|
+
if (received.length === expected.length && timingSafeEqual(received, expected)) {
|
|
135
|
+
matched = true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return matched;
|
|
139
|
+
}
|
|
140
|
+
/** El valor de una cabecera, sin distinguir mayúsculas. */
|
|
141
|
+
function headerValue(headers, header) {
|
|
142
|
+
const wanted = header.toLowerCase();
|
|
70
143
|
for (const [name, value] of Object.entries(headers)) {
|
|
71
144
|
if (name.toLowerCase() !== wanted)
|
|
72
145
|
continue;
|
|
@@ -74,6 +147,19 @@ export function signatureFromHeaders(headers) {
|
|
|
74
147
|
}
|
|
75
148
|
return undefined;
|
|
76
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* Busca la cabecera de firma en cualquiera de sus grafías.
|
|
152
|
+
*
|
|
153
|
+
* Los nombres de cabecera no distinguen mayúsculas, y cada framework los
|
|
154
|
+
* entrega a su manera.
|
|
155
|
+
*/
|
|
156
|
+
export function signatureFromHeaders(headers) {
|
|
157
|
+
return headerValue(headers, SIGNATURE_HEADER);
|
|
158
|
+
}
|
|
159
|
+
/** Busca la cabecera de la firma con marca de tiempo en cualquiera de sus grafías. */
|
|
160
|
+
export function timestampedSignatureFromHeaders(headers) {
|
|
161
|
+
return headerValue(headers, TIMESTAMPED_SIGNATURE_HEADER);
|
|
162
|
+
}
|
|
77
163
|
/**
|
|
78
164
|
* Verifica la firma y devuelve el evento ya interpretado.
|
|
79
165
|
*
|
package/dist/esm/webhooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/webhooks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/webhooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAGzD,4BAA4B;AAC5B,MAAM,CAAC,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAEtD,4DAA4D;AAC5D,MAAM,CAAC,MAAM,4BAA4B,GAAG,iCAAiC,CAAC;AAE9E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAE7C,sCAAsC;AACtC,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAErD,MAAM,gBAAgB,GAAG,SAAS,CAAC;AAEnC,qEAAqE;AACrE,SAAS,oBAAoB,CAAC,IAAa;IACzC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC;AACnG,CAAC;AAID,SAAS,QAAQ,CAAC,OAAgB;IAChC,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC3F,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,OAAgB,EAAE,MAAc;IAC/D,OAAO,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAgB,EAChB,SAAoC,EACpC,MAAc;IAEd,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACxD,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;IACnE,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACrD,IAAI,cAAc,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAClE,OAAO,eAAe,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;AACzD,CAAC;AAUD,MAAM,YAAY,GAAG,eAAe,CAAC;AAErC;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,MAAc;IACtC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,SAAS,KAAK,CAAC,CAAC;YAAE,SAAS;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,GAAG,KAAK,GAAG;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;aAC9B,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACnF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAChC,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAgB,EAChB,MAAiC,EACjC,MAAc,EACd,UAAoC,EAAE;IAEtC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACrC,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE1B,MAAM,SAAS,GAAG,OAAO,CAAC,gBAAgB,IAAI,yBAAyB,CAAC;IACxE,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IAChE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IAElF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,GAAG,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/F,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;IAChG,0DAA0D;IAC1D,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC/E,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAID,2DAA2D;AAC3D,SAAS,WAAW,CAAC,OAAkB,EAAE,MAAc;IACrD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM;YAAE,SAAS;QAC5C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACjD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAkB;IACrD,OAAO,WAAW,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAChD,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,+BAA+B,CAAC,OAAkB;IAChE,OAAO,WAAW,CAAC,OAAO,EAAE,4BAA4B,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAgB,EAChB,SAAoC,EACpC,MAAc;IAEd,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,0BAA0B,CAClC,yEAAyE;YACvE,qEAAqE;YACrE,qBAAqB,CACxB,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvF,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,0BAA0B,CAAC,8CAA8C,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,QAAQ,GAAG,MAAiC,CAAC;IACnD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,UAAU,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAEjE,MAAM,KAAK,GAAiB;QAC1B,KAAK,EAAE,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;KACtE,CAAC;IACF,IAAI,OAAO,QAAQ,CAAC,WAAW,CAAC,KAAK,QAAQ;QAAE,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IACvF,IAAI,UAAU;QAAE,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC;IACxC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,QAAQ,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC7D,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAM,CAA4B,CAAC;IAC3D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|