@run402/functions 2.9.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Structured errors thrown by the `auth.*` namespace.
3
+ *
4
+ * The platform error envelope (`R402_AUTH_*` codes) is the wire shape;
5
+ * these Error subclasses are how user code catches them in TypeScript.
6
+ *
7
+ * The docs say "do not catch auth errors" — the platform's response-shape
8
+ * decision (303 redirect for HTML, 401/403 envelope for JSON) already does
9
+ * the right thing. But framework code, middleware, and test harnesses
10
+ * occasionally need typed catches; that's what these classes are for.
11
+ */
12
+ export type Run402AuthCode = "R402_AUTH_REQUIRED" | "R402_AUTH_INSUFFICIENT_ROLE" | "R402_AUTH_INSUFFICIENT_MEMBERSHIP" | "R402_AUTH_FRESHNESS_REQUIRED" | "R402_AUTH_PRERENDERED" | "R402_AUTH_FETCH_ABSOLUTE_URL" | "R402_AUTH_UNKNOWN_EXPORT" | "R402_AUTH_SESSION_BRIDGE_UNVERIFIED" | "R402_AUTH_IDENTITY_LINK_CONFLICT" | "R402_AUTH_UNKNOWN_IDENTITY" | "R402_AUTH_TENANT_SUFFIX_REQUIRED" | "R402_AUTH_RETURN_TO_INVALID" | "R402_AUTH_REDUNDANT_USER_FILTER" | "R402_AUTH_INVALID_CREDENTIALS" | "R402_AUTH_TENANT_SUBJECT_INVALID" | "R402_AUTH_UNTRUSTED_CONTEXT";
13
+ export declare class Run402AuthError extends Error {
14
+ readonly code: Run402AuthCode;
15
+ readonly status: number;
16
+ readonly details: Record<string, unknown>;
17
+ readonly suggestedFix?: string;
18
+ readonly docs?: string;
19
+ constructor(opts: {
20
+ code: Run402AuthCode;
21
+ status: number;
22
+ message: string;
23
+ details?: Record<string, unknown>;
24
+ suggestedFix?: string;
25
+ docs?: string;
26
+ });
27
+ }
28
+ /** Subclass identifying the "anonymous on a protected route" case. The
29
+ * middleware decides whether to surface this as a 303 (HTML) or a 401
30
+ * envelope (JSON); user code never needs to make that choice. */
31
+ export declare class AuthRequiredError extends Run402AuthError {
32
+ constructor(opts?: {
33
+ returnTo?: string;
34
+ });
35
+ }
36
+ export declare class InsufficientRoleError extends Run402AuthError {
37
+ readonly requiredRole: string;
38
+ constructor(requiredRole: string);
39
+ }
40
+ export declare class InsufficientMembershipError extends Run402AuthError {
41
+ readonly requiredMembership: string;
42
+ constructor(requiredMembership: string);
43
+ }
44
+ export declare class FreshnessRequiredError extends Run402AuthError {
45
+ readonly maxAge: string;
46
+ readonly amr: string[];
47
+ constructor(opts: {
48
+ maxAge: string;
49
+ amr: string[];
50
+ returnTo?: string;
51
+ });
52
+ }
53
+ export declare class FetchAbsoluteUrlError extends Run402AuthError {
54
+ constructor(opts: {
55
+ attempted: string;
56
+ reason: string;
57
+ });
58
+ }
59
+ export declare class PrerenderedError extends Run402AuthError {
60
+ constructor(opts: {
61
+ sdkFunction: string;
62
+ });
63
+ }
64
+ export declare class UnknownExportError extends Run402AuthError {
65
+ readonly attemptedName: string;
66
+ readonly canonicalName: string;
67
+ constructor(opts: {
68
+ attemptedName: string;
69
+ canonicalName: string;
70
+ });
71
+ }
72
+ export declare class SessionBridgeUnverifiedError extends Run402AuthError {
73
+ constructor(opts: {
74
+ reason: string;
75
+ });
76
+ }
77
+ export declare class IdentityLinkConflictError extends Run402AuthError {
78
+ constructor(opts: {
79
+ provider: string;
80
+ subject: string;
81
+ });
82
+ }
83
+ export declare class UnknownIdentityError extends Run402AuthError {
84
+ constructor(opts: {
85
+ provider: string;
86
+ subject: string;
87
+ });
88
+ }
89
+ /** The canonical "your own credential check failed" error. Thrown via the
90
+ * `auth.invalidCredentials()` FUNCTION (not `new auth.InvalidCredentialsError()`)
91
+ * per D9 — agents fumble the constructor+import; `throw auth.invalidCredentials()`
92
+ * is one call and renders the canonical `R402_AUTH_INVALID_CREDENTIALS` envelope
93
+ * (distinct from `R402_AUTH_MAGIC_LINK_INVALID`). */
94
+ export declare class InvalidCredentialsError extends Run402AuthError {
95
+ constructor();
96
+ }
97
+ /** Rejects a tenant-assertion mint whose `user` lacks a stable `id` (e.g. a
98
+ * bare email). The `fix` shows the required `{ tenant, user: { id, email, ... },
99
+ * method }` shape. SDK-side fast-feedback twin of the gateway's
100
+ * `R402_AUTH_TENANT_SUBJECT_INVALID` envelope. */
101
+ export declare class TenantSubjectInvalidError extends Run402AuthError {
102
+ constructor(opts: {
103
+ reason: string;
104
+ });
105
+ }
106
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Structured errors thrown by the `auth.*` namespace.
3
+ *
4
+ * The platform error envelope (`R402_AUTH_*` codes) is the wire shape;
5
+ * these Error subclasses are how user code catches them in TypeScript.
6
+ *
7
+ * The docs say "do not catch auth errors" — the platform's response-shape
8
+ * decision (303 redirect for HTML, 401/403 envelope for JSON) already does
9
+ * the right thing. But framework code, middleware, and test harnesses
10
+ * occasionally need typed catches; that's what these classes are for.
11
+ */
12
+ export class Run402AuthError extends Error {
13
+ code;
14
+ status;
15
+ details;
16
+ suggestedFix;
17
+ docs;
18
+ constructor(opts) {
19
+ super(opts.message);
20
+ this.name = "Run402AuthError";
21
+ this.code = opts.code;
22
+ this.status = opts.status;
23
+ this.details = opts.details ?? {};
24
+ if (opts.suggestedFix)
25
+ this.suggestedFix = opts.suggestedFix;
26
+ if (opts.docs)
27
+ this.docs = opts.docs;
28
+ }
29
+ }
30
+ /** Subclass identifying the "anonymous on a protected route" case. The
31
+ * middleware decides whether to surface this as a 303 (HTML) or a 401
32
+ * envelope (JSON); user code never needs to make that choice. */
33
+ export class AuthRequiredError extends Run402AuthError {
34
+ constructor(opts = {}) {
35
+ super({
36
+ code: "R402_AUTH_REQUIRED",
37
+ status: 401,
38
+ message: "Authentication required.",
39
+ details: opts.returnTo ? { returnTo: opts.returnTo } : {},
40
+ suggestedFix: "Use: const user = await auth.requireUser()",
41
+ docs: "https://run402.com/errors/#R402_AUTH_REQUIRED",
42
+ });
43
+ this.name = "AuthRequiredError";
44
+ }
45
+ }
46
+ export class InsufficientRoleError extends Run402AuthError {
47
+ requiredRole;
48
+ constructor(requiredRole) {
49
+ super({
50
+ code: "R402_AUTH_INSUFFICIENT_ROLE",
51
+ status: 403,
52
+ message: `Authenticated user lacks required role: ${requiredRole}.`,
53
+ details: { required_role: requiredRole },
54
+ });
55
+ this.name = "InsufficientRoleError";
56
+ this.requiredRole = requiredRole;
57
+ }
58
+ }
59
+ export class InsufficientMembershipError extends Run402AuthError {
60
+ requiredMembership;
61
+ constructor(requiredMembership) {
62
+ super({
63
+ code: "R402_AUTH_INSUFFICIENT_MEMBERSHIP",
64
+ status: 403,
65
+ message: `Authenticated user lacks required membership: ${requiredMembership}.`,
66
+ details: { required_membership: requiredMembership },
67
+ });
68
+ this.name = "InsufficientMembershipError";
69
+ this.requiredMembership = requiredMembership;
70
+ }
71
+ }
72
+ export class FreshnessRequiredError extends Run402AuthError {
73
+ maxAge;
74
+ amr;
75
+ constructor(opts) {
76
+ super({
77
+ code: "R402_AUTH_FRESHNESS_REQUIRED",
78
+ status: 401,
79
+ message: `Fresh re-auth proof required within ${opts.maxAge} matching one of: ${opts.amr.join(", ")}.`,
80
+ details: { max_age: opts.maxAge, amr: opts.amr, returnTo: opts.returnTo ?? null },
81
+ });
82
+ this.name = "FreshnessRequiredError";
83
+ this.maxAge = opts.maxAge;
84
+ this.amr = opts.amr;
85
+ }
86
+ }
87
+ export class FetchAbsoluteUrlError extends Run402AuthError {
88
+ constructor(opts) {
89
+ super({
90
+ code: "R402_AUTH_FETCH_ABSOLUTE_URL",
91
+ status: 500,
92
+ message: `auth.fetch refused URL "${opts.attempted}": ${opts.reason}`,
93
+ details: { attempted_url: opts.attempted, reason: opts.reason },
94
+ suggestedFix: "auth.fetch accepts only same-origin paths. Cross-origin calls belong in your own service module.",
95
+ docs: "https://run402.com/errors/#R402_AUTH_FETCH_ABSOLUTE_URL",
96
+ });
97
+ this.name = "FetchAbsoluteUrlError";
98
+ }
99
+ }
100
+ export class PrerenderedError extends Run402AuthError {
101
+ constructor(opts) {
102
+ super({
103
+ code: "R402_AUTH_PRERENDERED",
104
+ status: 500,
105
+ message: `${opts.sdkFunction} cannot run in prerendered context.`,
106
+ details: { sdk_function: opts.sdkFunction },
107
+ suggestedFix: "Set `export const prerender = false` or use a server island.",
108
+ docs: "https://run402.com/errors/#R402_AUTH_PRERENDERED",
109
+ });
110
+ this.name = "PrerenderedError";
111
+ }
112
+ }
113
+ export class UnknownExportError extends Run402AuthError {
114
+ attemptedName;
115
+ canonicalName;
116
+ constructor(opts) {
117
+ super({
118
+ code: "R402_AUTH_UNKNOWN_EXPORT",
119
+ status: 500,
120
+ message: `Unknown SDK export: ${opts.attemptedName}. Use ${opts.canonicalName} instead.`,
121
+ details: {
122
+ attempted_name: opts.attemptedName,
123
+ canonical_name: opts.canonicalName,
124
+ import_line: 'import { auth } from "@run402/functions"',
125
+ },
126
+ suggestedFix: `Use: ${opts.canonicalName}`,
127
+ docs: "https://run402.com/errors/#R402_AUTH_UNKNOWN_EXPORT",
128
+ });
129
+ this.name = "UnknownExportError";
130
+ this.attemptedName = opts.attemptedName;
131
+ this.canonicalName = opts.canonicalName;
132
+ }
133
+ }
134
+ export class SessionBridgeUnverifiedError extends Run402AuthError {
135
+ constructor(opts) {
136
+ super({
137
+ code: "R402_AUTH_SESSION_BRIDGE_UNVERIFIED",
138
+ status: 401,
139
+ message: `Session bridge refused unverified proof: ${opts.reason}`,
140
+ details: { reason: opts.reason },
141
+ suggestedFix: "Pass a verifiable proof to auth.sessions.createResponseFromIdentity({provider, subject, proof, amr, createUser?}).",
142
+ docs: "https://run402.com/errors/#R402_AUTH_SESSION_BRIDGE_UNVERIFIED",
143
+ });
144
+ this.name = "SessionBridgeUnverifiedError";
145
+ }
146
+ }
147
+ export class IdentityLinkConflictError extends Run402AuthError {
148
+ constructor(opts) {
149
+ super({
150
+ code: "R402_AUTH_IDENTITY_LINK_CONFLICT",
151
+ status: 409,
152
+ message: `Identity (${opts.provider}, ${opts.subject}) is already linked to another user.`,
153
+ details: { provider: opts.provider, subject: opts.subject },
154
+ });
155
+ this.name = "IdentityLinkConflictError";
156
+ }
157
+ }
158
+ export class UnknownIdentityError extends Run402AuthError {
159
+ constructor(opts) {
160
+ super({
161
+ code: "R402_AUTH_UNKNOWN_IDENTITY",
162
+ status: 401,
163
+ message: `Identity (${opts.provider}, ${opts.subject}) not found.`,
164
+ details: { provider: opts.provider, subject: opts.subject },
165
+ suggestedFix: "Pass `createUser: true` to auth.sessions.createResponseFromIdentity if first-sign-in should create the user.",
166
+ });
167
+ this.name = "UnknownIdentityError";
168
+ }
169
+ }
170
+ /** The canonical "your own credential check failed" error. Thrown via the
171
+ * `auth.invalidCredentials()` FUNCTION (not `new auth.InvalidCredentialsError()`)
172
+ * per D9 — agents fumble the constructor+import; `throw auth.invalidCredentials()`
173
+ * is one call and renders the canonical `R402_AUTH_INVALID_CREDENTIALS` envelope
174
+ * (distinct from `R402_AUTH_MAGIC_LINK_INVALID`). */
175
+ export class InvalidCredentialsError extends Run402AuthError {
176
+ constructor() {
177
+ super({
178
+ code: "R402_AUTH_INVALID_CREDENTIALS",
179
+ status: 401,
180
+ message: "Invalid credentials.",
181
+ details: {},
182
+ suggestedFix: 'After your own credential check fails, use: throw auth.invalidCredentials()',
183
+ docs: "https://run402.com/errors/#R402_AUTH_INVALID_CREDENTIALS",
184
+ });
185
+ this.name = "InvalidCredentialsError";
186
+ }
187
+ }
188
+ /** Rejects a tenant-assertion mint whose `user` lacks a stable `id` (e.g. a
189
+ * bare email). The `fix` shows the required `{ tenant, user: { id, email, ... },
190
+ * method }` shape. SDK-side fast-feedback twin of the gateway's
191
+ * `R402_AUTH_TENANT_SUBJECT_INVALID` envelope. */
192
+ export class TenantSubjectInvalidError extends Run402AuthError {
193
+ constructor(opts) {
194
+ super({
195
+ code: "R402_AUTH_TENANT_SUBJECT_INVALID",
196
+ status: 400,
197
+ message: `Tenant assertion subject invalid: ${opts.reason}`,
198
+ details: { reason: opts.reason },
199
+ suggestedFix: 'Pass a stable id: auth.sessions.createResponseFromTenantAssertion({ tenant, user: { id, email, emailVerified }, method: "password" })',
200
+ docs: "https://run402.com/errors/#R402_AUTH_TENANT_SUBJECT_INVALID",
201
+ });
202
+ this.name = "TenantSubjectInvalidError";
203
+ }
204
+ }
205
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * `auth.*` — the sole server-side auth namespace.
3
+ *
4
+ * The single import line for any consumer:
5
+ *
6
+ * import { auth } from "@run402/functions";
7
+ *
8
+ * Surface (deliberately small):
9
+ *
10
+ * auth.user() → Actor | null
11
+ * auth.requireUser() → Actor (throws / 303 otherwise)
12
+ * auth.requireRole(role) → { user, role }
13
+ * auth.requireMembership(membership) → { user, membership }
14
+ * auth.requireFresh({ maxAge, amr? }) → void (throws / 303 otherwise)
15
+ * auth.identities.link({ ... }) → void
16
+ * auth.fetch(input, init?) → Response (same-origin only)
17
+ * auth.csrfToken() → string
18
+ * auth.csrfField() → "<input type=hidden ...>"
19
+ * auth.sessions.createResponseFromIdentity({ ... }) → Response
20
+ * auth.sessions.createResponseFromTenantAssertion({ tenant, user, method }) → Response
21
+ * auth.sessions.endResponse() → Response
22
+ * auth.invalidCredentials() → InvalidCredentialsError (throw it)
23
+ *
24
+ * Behaviour notes baked into the helpers:
25
+ * - Calling any helper taints the cache (the response now depends on
26
+ * per-request actor state). The taint is monotonic — once set, the
27
+ * SSR cache layer treats the response as non-cacheable until the
28
+ * request completes.
29
+ * - HTML-vs-JSON failure decisions are made by the gateway middleware
30
+ * (303 redirect for HTML, 401/403 envelope for JSON). The SDK throws
31
+ * a typed Error subclass; framework code OR the gateway translates.
32
+ * - `requireRole` / `requireMembership` always read fresh server-side
33
+ * grant data — no positive cache (matches D8 + the "instant revocation"
34
+ * contract). For now we route via `getRole` which the gateway sets
35
+ * at the routed-function envelope; once the v1.60 grants table lands,
36
+ * gate helpers will JOIN against it inside the same request.
37
+ * - `requireFresh` consults the per-method `amr_times` on the Actor —
38
+ * a recent password proof does NOT satisfy `{amr: ["passkey"]}`.
39
+ *
40
+ * @see openspec/changes/auth-aware-ssr/specs/auth-sdk-namespace/spec.md
41
+ */
42
+ import { InvalidCredentialsError } from "./errors.js";
43
+ import type { Actor, CreateResponseFromIdentityOptions, CreateResponseFromTenantAssertionOptions, IdentityLinkOptions } from "./types.js";
44
+ interface RequireFreshOptions {
45
+ /** Human-friendly window expression. Accepted forms: `"10m"`, `"1h"`,
46
+ * `"5m30s"`, integer seconds (`"600"`). Anything that fails to parse
47
+ * is treated as 0s (immediate freshness required). */
48
+ maxAge: string;
49
+ /** Names of AMR methods one of which must have been verified within
50
+ * `maxAge`. When omitted, any flat `auth_time` proof within `maxAge`
51
+ * satisfies. */
52
+ amr?: string[];
53
+ }
54
+ /** Header on the function's RETURNED Response that the gateway's routed-invoke
55
+ * post-processor materializes into a host-bound `Set-Cookie` — AFTER it
56
+ * checks the INVOKED function's declared `auth.sessionMint` capability
57
+ * (server-side; service-key presence is NOT sufficient). The gateway always
58
+ * strips this header before the client sees it. Kept in sync with the
59
+ * gateway constant of the same name. */
60
+ export declare const MINT_DIRECTIVE_HEADER = "x-run402-mint-directive";
61
+ interface AuthNamespace {
62
+ user(): Promise<Actor | null>;
63
+ requireUser(): Promise<Actor>;
64
+ requireRole<const R extends string>(role: R): Promise<{
65
+ user: Actor;
66
+ role: R;
67
+ }>;
68
+ requireMembership<const M extends string>(membership: M): Promise<{
69
+ user: Actor;
70
+ membership: M;
71
+ }>;
72
+ requireFresh(opts: RequireFreshOptions): Promise<void>;
73
+ fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
74
+ csrfToken(): string;
75
+ csrfField(): string;
76
+ /** Canonical invalid-credentials failure for the tenant-owned credential
77
+ * case. A function (not a constructor): `throw auth.invalidCredentials()`. */
78
+ invalidCredentials(): InvalidCredentialsError;
79
+ identities: {
80
+ link(opts: IdentityLinkOptions): Promise<void>;
81
+ };
82
+ sessions: {
83
+ createResponseFromIdentity(opts: CreateResponseFromIdentityOptions): Promise<Response>;
84
+ createResponseFromTenantAssertion(opts: CreateResponseFromTenantAssertionOptions): Promise<Response>;
85
+ endResponse(): Promise<Response>;
86
+ };
87
+ }
88
+ /** Hallucinated-name proxy. Property access for a name not in
89
+ * `baseAuth` throws `R402_AUTH_UNKNOWN_EXPORT` with the canonical
90
+ * replacement. Hot-path access (existing keys) returns the actual
91
+ * helper — proxy overhead is one Reflect.has + Reflect.get. */
92
+ export declare const auth: AuthNamespace;
93
+ /** Throwing-sentinel exports for the top hallucinated *bare* names.
94
+ * ESM `import { getUser } from "@run402/functions"` can be intercepted
95
+ * only by a real export — so we ship these as exported throwing
96
+ * functions. They're marked `@deprecated` in the type JSDoc; the SDK
97
+ * proxy + lint registry + `run402 doctor` scan all flag the import
98
+ * before runtime if the user is running the tooling.
99
+ *
100
+ * Excluded from public docs and AGENTS.md per the spec.
101
+ */
102
+ /** @deprecated Use `auth.user()` or `auth.requireUser()`. */
103
+ export declare function getSession(): never;
104
+ /** @deprecated Use `auth.user()`. */
105
+ export declare function currentUser(): never;
106
+ /** @deprecated Use `auth.user()`. */
107
+ export declare function getCurrentUser(): never;
108
+ /** @deprecated Use `auth.user()`. */
109
+ export declare function getServerSession(): never;
110
+ export type { Actor, IdentityProof, TenantUser, CreateResponseFromTenantAssertionOptions, } from "./types.js";
111
+ export { AuthRequiredError, InsufficientRoleError, InsufficientMembershipError, FreshnessRequiredError, FetchAbsoluteUrlError, PrerenderedError, UnknownExportError, SessionBridgeUnverifiedError, IdentityLinkConflictError, UnknownIdentityError, InvalidCredentialsError, TenantSubjectInvalidError, Run402AuthError, } from "./errors.js";
112
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAUH,OAAO,EAML,uBAAuB,EAIxB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,KAAK,EACL,iCAAiC,EACjC,wCAAwC,EACxC,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAsJpB,UAAU,mBAAmB;IAC3B;;2DAEuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf;;qBAEiB;IACjB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AA8JD;;;;;yCAKyC;AACzC,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AA2K/D,UAAU,aAAa;IACrB,IAAI,IAAI,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,WAAW,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAChF,iBAAiB,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EACtC,UAAU,EAAE,CAAC,GACZ,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,UAAU,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAC3C,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE,SAAS,IAAI,MAAM,CAAC;IACpB,SAAS,IAAI,MAAM,CAAC;IACpB;mFAC+E;IAC/E,kBAAkB,IAAI,uBAAuB,CAAC;IAC9C,UAAU,EAAE;QACV,IAAI,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAChD,CAAC;IACF,QAAQ,EAAE;QACR,0BAA0B,CAAC,IAAI,EAAE,iCAAiC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvF,iCAAiC,CAC/B,IAAI,EAAE,wCAAwC,GAC7C,OAAO,CAAC,QAAQ,CAAC,CAAC;QACrB,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;KAClC,CAAC;CACH;AAoDD;;;gEAGgE;AAChE,eAAO,MAAM,IAAI,EAAE,aAiBjB,CAAC;AAEH;;;;;;;;GAQG;AAEH,6DAA6D;AAC7D,wBAAgB,UAAU,IAAI,KAAK,CAElC;AAED,qCAAqC;AACrC,wBAAgB,WAAW,IAAI,KAAK,CAEnC;AAED,qCAAqC;AACrC,wBAAgB,cAAc,IAAI,KAAK,CAEtC;AAED,qCAAqC;AACrC,wBAAgB,gBAAgB,IAAI,KAAK,CAKxC;AA8BD,YAAY,EACV,KAAK,EACL,aAAa,EACb,UAAU,EACV,wCAAwC,GACzC,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,yBAAyB,EACzB,eAAe,GAChB,MAAM,aAAa,CAAC"}