@tokenfactory/acc-runner 0.11.0 → 0.14.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.
Files changed (55) hide show
  1. package/README.md +25 -0
  2. package/dist/cli.js +5 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/doctor.d.ts +19 -0
  5. package/dist/doctor.d.ts.map +1 -1
  6. package/dist/doctor.js +155 -7
  7. package/dist/doctor.js.map +1 -1
  8. package/dist/failure-classifier.d.ts +13 -0
  9. package/dist/failure-classifier.d.ts.map +1 -1
  10. package/dist/failure-classifier.js +4 -0
  11. package/dist/failure-classifier.js.map +1 -1
  12. package/dist/git.d.ts +15 -0
  13. package/dist/git.d.ts.map +1 -1
  14. package/dist/git.js +19 -0
  15. package/dist/git.js.map +1 -1
  16. package/dist/github-client.d.ts +133 -0
  17. package/dist/github-client.d.ts.map +1 -0
  18. package/dist/github-client.js +234 -0
  19. package/dist/github-client.js.map +1 -0
  20. package/dist/login.d.ts +3 -0
  21. package/dist/login.d.ts.map +1 -1
  22. package/dist/login.js +5 -2
  23. package/dist/login.js.map +1 -1
  24. package/dist/runtime/cache-dir.d.ts +2 -0
  25. package/dist/runtime/cache-dir.d.ts.map +1 -0
  26. package/dist/runtime/cache-dir.js +15 -0
  27. package/dist/runtime/cache-dir.js.map +1 -0
  28. package/dist/runtime/quarantine.d.ts +10 -0
  29. package/dist/runtime/quarantine.d.ts.map +1 -1
  30. package/dist/runtime/quarantine.js.map +1 -1
  31. package/dist/runtime/rework.d.ts +48 -0
  32. package/dist/runtime/rework.d.ts.map +1 -0
  33. package/dist/runtime/rework.js +136 -0
  34. package/dist/runtime/rework.js.map +1 -0
  35. package/dist/runtime/singleton.d.ts +47 -0
  36. package/dist/runtime/singleton.d.ts.map +1 -0
  37. package/dist/runtime/singleton.js +200 -0
  38. package/dist/runtime/singleton.js.map +1 -0
  39. package/dist/runtime/version-drift.d.ts +31 -0
  40. package/dist/runtime/version-drift.d.ts.map +1 -0
  41. package/dist/runtime/version-drift.js +114 -0
  42. package/dist/runtime/version-drift.js.map +1 -0
  43. package/dist/task-runner.d.ts +16 -1
  44. package/dist/task-runner.d.ts.map +1 -1
  45. package/dist/task-runner.js +302 -59
  46. package/dist/task-runner.js.map +1 -1
  47. package/dist/token-provider.d.ts +50 -0
  48. package/dist/token-provider.d.ts.map +1 -0
  49. package/dist/token-provider.js +177 -0
  50. package/dist/token-provider.js.map +1 -0
  51. package/dist/watch.d.ts +25 -0
  52. package/dist/watch.d.ts.map +1 -1
  53. package/dist/watch.js +219 -10
  54. package/dist/watch.js.map +1 -1
  55. package/package.json +1 -1
@@ -0,0 +1,50 @@
1
+ import type { StoredSession } from "./types.js";
2
+ export type TokenMode = "keychain" | "env";
3
+ export interface TokenProvider {
4
+ readonly mode: TokenMode;
5
+ /** True when the provider has a refresh token to rotate. The watch
6
+ * loop skips refresh timers / startup refresh when false. */
7
+ canRefresh(): boolean;
8
+ load(): Promise<StoredSession | null>;
9
+ save(session: StoredSession): Promise<void>;
10
+ clear(): Promise<boolean>;
11
+ }
12
+ /** Prefix marking a runner as ephemeral to the autoscale sweep. */
13
+ export declare const EPHEMERAL_RUNNER_PREFIX = "acc-eph-";
14
+ /** Mint a fresh ephemeral runner id: acc-eph-<8 hex chars>. */
15
+ export declare function mintEphemeralRunnerId(): string;
16
+ export declare function isEphemeralRunnerId(id: string): boolean;
17
+ interface JwtClaims {
18
+ sub?: string;
19
+ email?: string;
20
+ exp?: number;
21
+ }
22
+ /**
23
+ * Decode the payload segment of a JWT without verifying the signature.
24
+ * The runner is the token's *bearer*, not its verifier — PostgREST does
25
+ * the real verification server-side. Returns null on any shape problem
26
+ * so a malformed env token fails loudly at startup with a clear message
27
+ * rather than an opaque 401 on the first RPC.
28
+ */
29
+ export declare function decodeJwtClaims(jwt: string): JwtClaims | null;
30
+ export declare class EnvTokenProvider implements TokenProvider {
31
+ readonly mode: "env";
32
+ private session;
33
+ private initError;
34
+ constructor(env?: NodeJS.ProcessEnv);
35
+ canRefresh(): boolean;
36
+ load(): Promise<StoredSession | null>;
37
+ save(session: StoredSession): Promise<void>;
38
+ clear(): Promise<boolean>;
39
+ }
40
+ export declare function resolveTokenMode(env?: NodeJS.ProcessEnv): TokenMode;
41
+ /**
42
+ * Resolve the process-wide token provider. Cached so the ephemeral
43
+ * runner id minted by EnvTokenProvider is stable across watch.ts,
44
+ * doctor.ts, and any future consumer in the same process.
45
+ */
46
+ export declare function getTokenProvider(): TokenProvider;
47
+ /** Test-only seam: override or reset the cached provider. */
48
+ export declare function __setTokenProvider(provider: TokenProvider | null): void;
49
+ export {};
50
+ //# sourceMappingURL=token-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-provider.d.ts","sourceRoot":"","sources":["../src/token-provider.ts"],"names":[],"mappings":"AAqDA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB;kEAC8D;IAC9D,UAAU,IAAI,OAAO,CAAC;IACtB,IAAI,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3B;AAED,mEAAmE;AACnE,eAAO,MAAM,uBAAuB,aAAa,CAAC;AAElD,+DAA+D;AAC/D,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,UAAU,SAAS;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAiB7D;AAkBD,qBAAa,gBAAiB,YAAW,aAAa;IACpD,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,SAAS,CAAuB;gBAE5B,GAAG,GAAE,MAAM,CAAC,UAAwB;IA+BhD,UAAU,IAAI,OAAO;IAIf,IAAI,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAKrC,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;CAKhC;AAED,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,SAAS,CAOhF;AAID;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAOhD;AAED,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAEvE"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * v0.12.0 (T-52-7): token-provider abstraction for ephemeral runners.
3
+ *
4
+ * Two modes, selected by ACC_RUNNER_TOKEN_MODE:
5
+ *
6
+ * "keychain" (default, or unset) — delegates byte-for-byte to the
7
+ * existing keychain.ts functions. The OS-keychain entry schema
8
+ * (service "acc-runner", account "default", JSON StoredSession) is a
9
+ * FROZEN contract; this module never touches its shape. Desktop
10
+ * runners see identical behavior to v0.11.
11
+ *
12
+ * "env" — containerized / ephemeral runners. The session is sourced
13
+ * from env vars instead of keytar (containers have no OS keychain
14
+ * and keytar's native binding is never imported on this path):
15
+ *
16
+ * ACC_RUNNER_ACCESS_TOKEN (required) the Supabase-compatible JWT
17
+ * minted by the device-code exchange,
18
+ * /api/runner/refresh, or the autoscale
19
+ * provider. user_id / email / expiry are
20
+ * decoded from the JWT payload (sub,
21
+ * email, exp) — no extra env needed.
22
+ * ACC_RUNNER_REFRESH_TOKEN (optional) enables in-process token
23
+ * rotation via /api/runner/refresh.
24
+ * Rotated successors live in process
25
+ * memory only — they are NEVER written
26
+ * to disk. Restarting a container with a
27
+ * previously-rotated refresh token trips
28
+ * the server's reuse detection and
29
+ * revokes the chain, so provision a
30
+ * fresh pair per container (see
31
+ * docs/acc/RUNNER_AUTOSCALE.md). When
32
+ * absent the runner simply cannot
33
+ * refresh and exits when the 8h access
34
+ * token expires — fine for idle-TTL
35
+ * bounded ephemeral runners.
36
+ * ACC_RUNNER_ID (optional) pre-assigned runner id.
37
+ * Defaults to a fresh `acc-eph-<hex8>`
38
+ * minted once per process. The acc-eph-
39
+ * prefix is the autoscale sweep's
40
+ * "ephemeral fleet" discriminator — do
41
+ * not reuse it for desktop runners.
42
+ *
43
+ * save() in env mode updates the in-memory session (so refresh rotation
44
+ * works for the life of the process) and deliberately does NOT persist:
45
+ * an ephemeral runner that writes credentials to its writable layer
46
+ * would leak them into image diffs / volume snapshots.
47
+ */
48
+ import crypto from "node:crypto";
49
+ import { clearSession as keychainClear, loadSession as keychainLoad, saveSession as keychainSave, } from "./keychain.js";
50
+ /** Prefix marking a runner as ephemeral to the autoscale sweep. */
51
+ export const EPHEMERAL_RUNNER_PREFIX = "acc-eph-";
52
+ /** Mint a fresh ephemeral runner id: acc-eph-<8 hex chars>. */
53
+ export function mintEphemeralRunnerId() {
54
+ return `${EPHEMERAL_RUNNER_PREFIX}${crypto.randomBytes(4).toString("hex")}`;
55
+ }
56
+ export function isEphemeralRunnerId(id) {
57
+ return id.startsWith(EPHEMERAL_RUNNER_PREFIX);
58
+ }
59
+ /**
60
+ * Decode the payload segment of a JWT without verifying the signature.
61
+ * The runner is the token's *bearer*, not its verifier — PostgREST does
62
+ * the real verification server-side. Returns null on any shape problem
63
+ * so a malformed env token fails loudly at startup with a clear message
64
+ * rather than an opaque 401 on the first RPC.
65
+ */
66
+ export function decodeJwtClaims(jwt) {
67
+ const parts = jwt.split(".");
68
+ if (parts.length !== 3)
69
+ return null;
70
+ try {
71
+ const payload = Buffer.from(parts[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8");
72
+ const parsed = JSON.parse(payload);
73
+ return {
74
+ sub: typeof parsed.sub === "string" ? parsed.sub : undefined,
75
+ email: typeof parsed.email === "string" ? parsed.email : undefined,
76
+ exp: typeof parsed.exp === "number" ? parsed.exp : undefined,
77
+ };
78
+ }
79
+ catch {
80
+ return null;
81
+ }
82
+ }
83
+ class KeychainTokenProvider {
84
+ mode = "keychain";
85
+ canRefresh() {
86
+ return true;
87
+ }
88
+ load() {
89
+ return keychainLoad();
90
+ }
91
+ save(session) {
92
+ return keychainSave(session);
93
+ }
94
+ clear() {
95
+ return keychainClear();
96
+ }
97
+ }
98
+ export class EnvTokenProvider {
99
+ mode = "env";
100
+ session = null;
101
+ initError = null;
102
+ constructor(env = process.env) {
103
+ const accessToken = env.ACC_RUNNER_ACCESS_TOKEN?.trim() ?? "";
104
+ if (!accessToken) {
105
+ this.initError =
106
+ "ACC_RUNNER_TOKEN_MODE=env requires ACC_RUNNER_ACCESS_TOKEN to be set";
107
+ return;
108
+ }
109
+ const claims = decodeJwtClaims(accessToken);
110
+ if (!claims?.sub) {
111
+ this.initError =
112
+ "ACC_RUNNER_ACCESS_TOKEN is not a decodable JWT (expected the access token minted by the device-code exchange or the autoscale provider)";
113
+ return;
114
+ }
115
+ const refreshToken = env.ACC_RUNNER_REFRESH_TOKEN?.trim() ?? "";
116
+ const runnerId = env.ACC_RUNNER_ID?.trim() || mintEphemeralRunnerId();
117
+ this.session = {
118
+ access_token: accessToken,
119
+ // Empty string when refresh is unavailable; canRefresh() gates every
120
+ // consumer so the placeholder is never sent to /api/runner/refresh.
121
+ refresh_token: refreshToken,
122
+ access_expires_at: claims.exp
123
+ ? new Date(claims.exp * 1000).toISOString()
124
+ : // No exp claim: treat as far-future so the watch loop doesn't
125
+ // spin on refresh attempts it can't perform.
126
+ new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString(),
127
+ email: claims.email ?? null,
128
+ user_id: claims.sub,
129
+ runner_id: runnerId,
130
+ };
131
+ }
132
+ canRefresh() {
133
+ return Boolean(this.session?.refresh_token);
134
+ }
135
+ async load() {
136
+ if (this.initError)
137
+ throw new Error(this.initError);
138
+ return this.session;
139
+ }
140
+ async save(session) {
141
+ // In-memory only — see module docstring.
142
+ this.session = session;
143
+ }
144
+ async clear() {
145
+ const had = this.session !== null;
146
+ this.session = null;
147
+ return had;
148
+ }
149
+ }
150
+ export function resolveTokenMode(env = process.env) {
151
+ const raw = env.ACC_RUNNER_TOKEN_MODE?.trim().toLowerCase();
152
+ if (!raw || raw === "keychain")
153
+ return "keychain";
154
+ if (raw === "env")
155
+ return "env";
156
+ throw new Error(`ACC_RUNNER_TOKEN_MODE=${JSON.stringify(raw)} is not supported (expected "keychain" or "env")`);
157
+ }
158
+ let cachedProvider = null;
159
+ /**
160
+ * Resolve the process-wide token provider. Cached so the ephemeral
161
+ * runner id minted by EnvTokenProvider is stable across watch.ts,
162
+ * doctor.ts, and any future consumer in the same process.
163
+ */
164
+ export function getTokenProvider() {
165
+ if (cachedProvider)
166
+ return cachedProvider;
167
+ cachedProvider =
168
+ resolveTokenMode() === "env"
169
+ ? new EnvTokenProvider()
170
+ : new KeychainTokenProvider();
171
+ return cachedProvider;
172
+ }
173
+ /** Test-only seam: override or reset the cached provider. */
174
+ export function __setTokenProvider(provider) {
175
+ cachedProvider = provider;
176
+ }
177
+ //# sourceMappingURL=token-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-provider.js","sourceRoot":"","sources":["../src/token-provider.ts"],"names":[],"mappings":"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"}
package/dist/watch.d.ts CHANGED
@@ -44,7 +44,32 @@ export interface WatchOptions {
44
44
  * restore the strict serial v0.9 behaviour.
45
45
  */
46
46
  concurrencyLimit?: number;
47
+ /**
48
+ * v0.12.0 (T-52-7): idle TTL in ms. Overrides ACC_RUNNER_IDLE_TTL_MIN
49
+ * for tests. null/undefined falls back to the env var; when neither is
50
+ * set the idle-TTL machinery is never armed (desktop default — byte-
51
+ * identical v0.11 behaviour).
52
+ */
53
+ idleTtlMs?: number | null;
54
+ /** v0.12.0 (T-52-7): idle-check cadence override for tests. */
55
+ idleCheckMs?: number;
56
+ /** v0.12.0 (T-52-7): exit hook for tests. Defaults to process.exit. */
57
+ exit?: (code: number) => void;
58
+ /**
59
+ * v0.14.0 (T-54-2, GA-3): acquire the single-instance lock on the repo
60
+ * path before starting. Defaults to true for real runs and false when a
61
+ * taskRunnerFactory is injected (tests) so parallel test workers don't
62
+ * fight over a shared machine-wide lock. Set explicitly to exercise the
63
+ * guard.
64
+ */
65
+ enforceSingleton?: boolean;
47
66
  }
67
+ /**
68
+ * v0.12.0 (T-52-7): resolve ACC_RUNNER_IDLE_TTL_MIN into ms. Returns null
69
+ * (TTL disabled) when unset; warns and returns null on junk so a typo'd
70
+ * env never strands a container in "never exits" mode silently.
71
+ */
72
+ export declare function resolveIdleTtlMs(env?: NodeJS.ProcessEnv): number | null;
48
73
  export interface WatchHandle {
49
74
  stop(): Promise<void>;
50
75
  /** Test hook: forces one polling pass and resolves when it finishes. */
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAsB,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,OAAO,EAA0B,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAY/B,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,EAAE,MAAM;CAI5B;AAuBD,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN,KAAK,GACL,KAAK,GACL,OAAO,GACP,SAAS,GACT,SAAS,GACT,SAAS,CAAC;AAEd;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GACxE,kBAAkB,CA2CpB;AAED;;;6CAG6C;AAC7C,wBAAgB,oBAAoB,CAAC,mBAAmB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIxF;AAED,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,OAAO,OAAO,CAAC;IACnC,yEAAyE;IACzE,eAAe,CAAC,EAAE,CAChB,UAAU,EAAE,gBAAgB,EAC5B,IAAI,EAAE;QAAE,QAAQ,EAAE,oBAAoB,CAAA;KAAE,KACrC,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9B;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,wEAAwE;IACxE,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,2EAA2E;IAC3E,YAAY,IAAI,MAAM,CAAC;CACxB;AAiQD,wBAAsB,YAAY,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CA4PnF"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAsB,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,OAAO,EAA0B,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAqB/B,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,EAAE,MAAM;CAI5B;AA0BD,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN,KAAK,GACL,KAAK,GACL,OAAO,GACP,SAAS,GACT,SAAS,GACT,SAAS,CAAC;AAEd;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GACxE,kBAAkB,CA2CpB;AAED;;;6CAG6C;AAC7C,wBAAgB,oBAAoB,CAAC,mBAAmB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIxF;AAED,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,OAAO,OAAO,CAAC;IACnC,yEAAyE;IACzE,eAAe,CAAC,EAAE,CAChB,UAAU,EAAE,gBAAgB,EAC5B,IAAI,EAAE;QAAE,QAAQ,EAAE,oBAAoB,CAAA;KAAE,KACrC,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9B;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,GAAG,IAAI,CAWf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,wEAAwE;IACxE,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,2EAA2E;IAC3E,YAAY,IAAI,MAAM,CAAC;CACxB;AAmSD,wBAAsB,YAAY,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAiXnF"}