@shunt-network/verify 1.0.1 → 1.0.2
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/dist/core.d.ts +4 -1
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +22 -4
- package/dist/core.js.map +1 -1
- package/dist/express.d.ts +1 -0
- package/dist/express.d.ts.map +1 -1
- package/dist/express.js +3 -1
- package/dist/express.js.map +1 -1
- package/dist/web.d.ts +14 -5
- package/dist/web.d.ts.map +1 -1
- package/dist/web.js +11 -5
- package/dist/web.js.map +1 -1
- package/package.json +1 -1
package/dist/core.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export type VerifyResult = {
|
|
2
2
|
ok: true;
|
|
3
3
|
requestId: string;
|
|
4
|
+
agent?: string;
|
|
4
5
|
} | {
|
|
5
6
|
ok: false;
|
|
6
|
-
reason: "missing_headers" | "stale_timestamp" | "bad_signature" | "replay";
|
|
7
|
+
reason: "missing_headers" | "stale_timestamp" | "bad_signature" | "agent_required" | "replay";
|
|
7
8
|
};
|
|
8
9
|
export interface VerifyInput {
|
|
9
10
|
secret: string | string[];
|
|
@@ -13,6 +14,8 @@ export interface VerifyInput {
|
|
|
13
14
|
getHeader: (name: string) => string | undefined | null;
|
|
14
15
|
maxSkewSec?: number;
|
|
15
16
|
replayCache?: ReplayCache;
|
|
17
|
+
/** Reject requests that carry no signed agent identity (v1 signatures). */
|
|
18
|
+
requireAgent?: boolean;
|
|
16
19
|
}
|
|
17
20
|
export declare class ReplayCache {
|
|
18
21
|
private ttlMs;
|
package/dist/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EACF,iBAAiB,GACjB,iBAAiB,GACjB,eAAe,GACf,gBAAgB,GAChB,QAAQ,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IACtC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,qBAAa,WAAW;IAEV,OAAO,CAAC,KAAK;IADzB,OAAO,CAAC,IAAI,CAA6B;IACzC,YAAoB,KAAK,SAAc,EAAI;IAC3C,8CAA8C;IAC9C,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAMzB;CACF;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,YAAY,CA6CxD"}
|
package/dist/core.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
+
const AGENT_RE = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/; // base58 Solana pubkey
|
|
2
3
|
export class ReplayCache {
|
|
3
4
|
ttlMs;
|
|
4
5
|
seen = new Map();
|
|
@@ -20,14 +21,31 @@ export class ReplayCache {
|
|
|
20
21
|
export function verifyShunt(i) {
|
|
21
22
|
const ts = i.getHeader("x-shunt-timestamp");
|
|
22
23
|
const rid = i.getHeader("x-shunt-request-id");
|
|
23
|
-
const
|
|
24
|
-
if (!ts || !rid || !
|
|
24
|
+
const m = /^(v1|v2)=([0-9a-f]+)$/.exec(i.getHeader("x-shunt-signature") ?? "");
|
|
25
|
+
if (!ts || !rid || !m)
|
|
25
26
|
return { ok: false, reason: "missing_headers" };
|
|
27
|
+
const version = m[1];
|
|
28
|
+
const sig = m[2];
|
|
29
|
+
// Only v2 signatures cover the agent, so only v2 can produce a trusted agent.
|
|
30
|
+
// A v1 request's x-shunt-agent header is never returned, even if present.
|
|
31
|
+
let agent;
|
|
32
|
+
if (version === "v2") {
|
|
33
|
+
const raw = i.getHeader("x-shunt-agent");
|
|
34
|
+
if (!raw || !AGENT_RE.test(raw))
|
|
35
|
+
return { ok: false, reason: "missing_headers" };
|
|
36
|
+
agent = raw;
|
|
37
|
+
}
|
|
38
|
+
else if (i.requireAgent) {
|
|
39
|
+
return { ok: false, reason: "agent_required" };
|
|
40
|
+
}
|
|
26
41
|
const skew = Math.abs(Date.now() / 1000 - Number(ts));
|
|
27
42
|
if (!Number.isFinite(skew) || skew > (i.maxSkewSec ?? 300))
|
|
28
43
|
return { ok: false, reason: "stale_timestamp" };
|
|
29
44
|
const bodyHash = crypto.createHash("sha256").update(i.rawBody).digest("hex");
|
|
30
|
-
const
|
|
45
|
+
const method = i.method.toUpperCase();
|
|
46
|
+
const payload = version === "v2"
|
|
47
|
+
? `v2\n${ts}\n${rid}\n${agent}\n${method}\n${i.pathAndQuery}\n${bodyHash}`
|
|
48
|
+
: `v1\n${ts}\n${rid}\n${method}\n${i.pathAndQuery}\n${bodyHash}`;
|
|
31
49
|
const secrets = Array.isArray(i.secret) ? i.secret : [i.secret];
|
|
32
50
|
const sigBuf = Buffer.from(sig, "utf8");
|
|
33
51
|
const valid = secrets.some((s) => {
|
|
@@ -39,6 +57,6 @@ export function verifyShunt(i) {
|
|
|
39
57
|
// only record the id AFTER the signature is valid, so attackers can't fill the cache
|
|
40
58
|
if (i.replayCache?.check(rid))
|
|
41
59
|
return { ok: false, reason: "replay" };
|
|
42
|
-
return { ok: true, requestId: rid };
|
|
60
|
+
return { ok: true, requestId: rid, agent };
|
|
43
61
|
}
|
|
44
62
|
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
package/dist/express.d.ts
CHANGED
|
@@ -3,5 +3,6 @@ export declare const shuntRawBody: (req: any, _res: any, buf: Buffer) => void;
|
|
|
3
3
|
export declare function shuntExpress(secret: string | string[], opts?: {
|
|
4
4
|
maxSkewSec?: number;
|
|
5
5
|
replayProtection?: boolean;
|
|
6
|
+
requireAgent?: boolean;
|
|
6
7
|
}): (req: any, res: any, next: any) => any;
|
|
7
8
|
//# sourceMappingURL=express.d.ts.map
|
package/dist/express.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,eAAO,MAAM,YAAY,QAAS,GAAG,QAAQ,GAAG,OAAO,MAAM,SAE5D,CAAC;AAEF,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAO,
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,eAAO,MAAM,YAAY,QAAS,GAAG,QAAQ,GAAG,OAAO,MAAM,SAE5D,CAAC;AAEF,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,SAGzE,GAAG,OAAO,GAAG,QAAQ,GAAG,SAkBtC"}
|
package/dist/express.js
CHANGED
|
@@ -13,12 +13,14 @@ export function shuntExpress(secret, opts = {}) {
|
|
|
13
13
|
rawBody: req.rawBody ?? Buffer.alloc(0),
|
|
14
14
|
getHeader: (n) => req.get(n),
|
|
15
15
|
maxSkewSec: opts.maxSkewSec,
|
|
16
|
+
requireAgent: opts.requireAgent,
|
|
16
17
|
replayCache,
|
|
17
18
|
});
|
|
18
19
|
if (!r.ok) {
|
|
19
20
|
return res.status(401).json({ error: "Unauthorized: requests must come via Shunt" });
|
|
20
21
|
}
|
|
21
|
-
req.shunt
|
|
22
|
+
// req.shunt.agent is the VERIFIED agent. Never read the raw x-shunt-agent header.
|
|
23
|
+
req.shunt = { requestId: r.requestId, agent: r.agent };
|
|
22
24
|
next();
|
|
23
25
|
};
|
|
24
26
|
}
|
package/dist/express.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.js","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAErD,gFAAgF;AAChF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAQ,EAAE,IAAS,EAAE,GAAW,EAAE,EAAE;IAC/D,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,UAAU,YAAY,CAC1B,MAAyB,EACzB,IAAI,
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAErD,gFAAgF;AAChF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAQ,EAAE,IAAS,EAAE,GAAW,EAAE,EAAE;IAC/D,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,UAAU,YAAY,CAC1B,MAAyB,EACzB,IAAI,GAAgF,EAAE;IAEtF,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,OAAO,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,WAAW,CAAC;YACpB,MAAM;YACN,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,YAAY,EAAE,GAAG,CAAC,WAAW;YAC7B,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACvC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5B,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,WAAW;SACZ,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACV,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,kFAAkF;QAClF,GAAG,CAAC,KAAK,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QACvD,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/web.d.ts
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { ReplayCache } from "./core.js";
|
|
2
|
-
export
|
|
2
|
+
export interface ShuntContext {
|
|
3
|
+
requestId: string;
|
|
4
|
+
/** Verified agent wallet (present for v2 signatures). */
|
|
5
|
+
agent?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ShuntWebOptions {
|
|
3
8
|
maxSkewSec?: number;
|
|
4
9
|
replayCache?: ReplayCache;
|
|
5
|
-
|
|
10
|
+
requireAgent?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function verifyShuntRequest(req: Request, secret: string | string[], opts?: ShuntWebOptions): Promise<import("./core.js").VerifyResult>;
|
|
13
|
+
/** Inside a withShunt handler: const { agent } = getShunt(req)!; */
|
|
14
|
+
export declare const getShunt: (req: Request) => ShuntContext | undefined;
|
|
6
15
|
/** Next.js App Router: export const POST = withShunt(secret, async (req) => ...) */
|
|
7
|
-
export declare function withShunt<T extends (req: Request, ...a: any[]) => Promise<Response> | Response>(secret: string | string[], handler: T): T;
|
|
8
|
-
/** Hono: app.use("/paid/*", shuntHono(secret)) */
|
|
9
|
-
export declare const shuntHono: (secret: string | string[]) => (c: any, next: any) => Promise<any>;
|
|
16
|
+
export declare function withShunt<T extends (req: Request, ...a: any[]) => Promise<Response> | Response>(secret: string | string[], handler: T, opts?: ShuntWebOptions): T;
|
|
17
|
+
/** Hono: app.use("/paid/*", shuntHono(secret)); then c.get("shunt").agent */
|
|
18
|
+
export declare const shuntHono: (secret: string | string[], opts?: ShuntWebOptions) => (c: any, next: any) => Promise<any>;
|
|
10
19
|
//# sourceMappingURL=web.d.ts.map
|
package/dist/web.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,WAAW,EAAE,MAAM,WAAW,CAAC;AAErD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,IAAI,GAAE;
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,WAAW,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,IAAI,GAAE,eAAoB,6CAY3B;AAKD,oEAAoE;AACpE,eAAO,MAAM,QAAQ,QAAS,OAAO,KAAG,YAAY,GAAG,SAA8B,CAAC;AAEtF,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,EAC7F,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,OAAO,EAAE,CAAC,EACV,IAAI,GAAE,eAAoB,GACzB,CAAC,CASH;AAED,6EAA6E;AAC7E,eAAO,MAAM,SAAS,WACX,MAAM,GAAG,MAAM,EAAE,SAAQ,eAAe,SACrC,GAAG,QAAQ,GAAG,iBAKvB,CAAC"}
|
package/dist/web.js
CHANGED
|
@@ -11,21 +11,27 @@ export async function verifyShuntRequest(req, secret, opts = {}) {
|
|
|
11
11
|
...opts,
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
|
+
// Verified context, keyed by the Request object the handler receives.
|
|
15
|
+
const contexts = new WeakMap();
|
|
16
|
+
/** Inside a withShunt handler: const { agent } = getShunt(req)!; */
|
|
17
|
+
export const getShunt = (req) => contexts.get(req);
|
|
14
18
|
/** Next.js App Router: export const POST = withShunt(secret, async (req) => ...) */
|
|
15
|
-
export function withShunt(secret, handler) {
|
|
19
|
+
export function withShunt(secret, handler, opts = {}) {
|
|
16
20
|
return (async (req, ...args) => {
|
|
17
|
-
const r = await verifyShuntRequest(req, secret);
|
|
21
|
+
const r = await verifyShuntRequest(req, secret, opts);
|
|
18
22
|
if (!r.ok) {
|
|
19
23
|
return Response.json({ error: "Unauthorized: requests must come via Shunt" }, { status: 401 });
|
|
20
24
|
}
|
|
25
|
+
contexts.set(req, { requestId: r.requestId, agent: r.agent });
|
|
21
26
|
return handler(req, ...args);
|
|
22
27
|
});
|
|
23
28
|
}
|
|
24
|
-
/** Hono: app.use("/paid/*", shuntHono(secret)) */
|
|
25
|
-
export const shuntHono = (secret) => async (c, next) => {
|
|
26
|
-
const r = await verifyShuntRequest(c.req.raw, secret);
|
|
29
|
+
/** Hono: app.use("/paid/*", shuntHono(secret)); then c.get("shunt").agent */
|
|
30
|
+
export const shuntHono = (secret, opts = {}) => async (c, next) => {
|
|
31
|
+
const r = await verifyShuntRequest(c.req.raw, secret, opts);
|
|
27
32
|
if (!r.ok)
|
|
28
33
|
return c.json({ error: "Unauthorized: requests must come via Shunt" }, 401);
|
|
34
|
+
c.set("shunt", { requestId: r.requestId, agent: r.agent });
|
|
29
35
|
await next();
|
|
30
36
|
};
|
|
31
37
|
//# sourceMappingURL=web.js.map
|
package/dist/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAe,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAe,MAAM,WAAW,CAAC;AAcrD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAY,EACZ,MAAyB,EACzB,IAAI,GAAoB,EAAE;IAE1B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IAChE,OAAO,WAAW,CAAC;QACjB,MAAM;QACN,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,YAAY,EAAE,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM;QACvC,OAAO;QACP,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QACpC,GAAG,IAAI;KACR,CAAC,CAAC;AACL,CAAC;AAED,sEAAsE;AACtE,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAyB,CAAC;AAEtD,oEAAoE;AACpE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAY,EAA4B,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEtF,oFAAoF;AACpF,MAAM,UAAU,SAAS,CACvB,MAAyB,EACzB,OAAU,EACV,IAAI,GAAoB,EAAE;IAE1B,OAAO,CAAC,KAAK,EAAE,GAAY,EAAE,GAAG,IAAW,EAAE,EAAE;QAC7C,MAAM,CAAC,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACV,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4CAA4C,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACjG,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9D,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAM,CAAC;AACV,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,MAAM,SAAS,GACpB,CAAC,MAAyB,EAAE,IAAI,GAAoB,EAAE,EAAE,EAAE,CACxD,KAAK,EAAE,CAAM,EAAE,IAAS,EAAE,EAAE;IAC1B,MAAM,CAAC,GAAG,MAAM,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4CAA4C,EAAE,EAAE,GAAG,CAAC,CAAC;IACvF,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAyB,CAAC,CAAC;IAClF,MAAM,IAAI,EAAE,CAAC;AACf,CAAC,CAAC"}
|