@coldtea/pr-lens-cli 0.1.3 → 0.3.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 (51) hide show
  1. package/README.md +37 -7
  2. package/dist/canvas/api.d.ts +65 -0
  3. package/dist/canvas/api.d.ts.map +1 -0
  4. package/dist/canvas/api.js +175 -0
  5. package/dist/canvas/api.js.map +1 -0
  6. package/dist/canvas/registry.d.ts +45 -0
  7. package/dist/canvas/registry.d.ts.map +1 -0
  8. package/dist/canvas/registry.js +309 -0
  9. package/dist/canvas/registry.js.map +1 -0
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +17 -5
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/analyze.d.ts.map +1 -1
  14. package/dist/commands/analyze.js +3 -4
  15. package/dist/commands/analyze.js.map +1 -1
  16. package/dist/commands/canvas.d.ts +4 -0
  17. package/dist/commands/canvas.d.ts.map +1 -0
  18. package/dist/commands/canvas.js +358 -0
  19. package/dist/commands/canvas.js.map +1 -0
  20. package/dist/commands/skill.d.ts +4 -0
  21. package/dist/commands/skill.d.ts.map +1 -0
  22. package/dist/commands/skill.js +28 -0
  23. package/dist/commands/skill.js.map +1 -0
  24. package/dist/errors.d.ts +1 -1
  25. package/dist/errors.d.ts.map +1 -1
  26. package/dist/errors.js.map +1 -1
  27. package/dist/io.d.ts +7 -0
  28. package/dist/io.d.ts.map +1 -1
  29. package/dist/io.js +22 -1
  30. package/dist/io.js.map +1 -1
  31. package/dist/skill-content.generated.d.ts +6 -0
  32. package/dist/skill-content.generated.d.ts.map +1 -0
  33. package/dist/skill-content.generated.js +7 -0
  34. package/dist/skill-content.generated.js.map +1 -0
  35. package/dist/version.d.ts +1 -1
  36. package/dist/version.js +1 -1
  37. package/dist/workspace.d.ts.map +1 -1
  38. package/dist/workspace.js +8 -3
  39. package/dist/workspace.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/canvas/api.ts +312 -0
  42. package/src/canvas/registry.ts +479 -0
  43. package/src/cli.ts +18 -6
  44. package/src/commands/analyze.ts +3 -8
  45. package/src/commands/canvas.ts +549 -0
  46. package/src/commands/skill.ts +41 -0
  47. package/src/errors.ts +8 -1
  48. package/src/io.ts +23 -1
  49. package/src/skill-content.generated.ts +6 -0
  50. package/src/version.ts +1 -1
  51. package/src/workspace.ts +9 -4
package/README.md CHANGED
@@ -10,7 +10,7 @@ npx @coldtea/pr-lens-cli analyze --base origin/main
10
10
 
11
11
  ## Bring your own key
12
12
 
13
- Only `analyze` talks to a model; `render`, `comment`, `validate` and `export` never do. Its key is read from the environment, never from a flag: a flag lands in shell history and in the log of whatever CI runs it. The diff goes to the provider you name and nowhere else: there is no PR Lens service in this path.
13
+ Only `analyze` talks to a model; `render`, `comment`, `validate`, `export` and `canvas` never do. Its key is read from the environment, never from a flag: a flag lands in shell history and in the log of whatever CI runs it. The diff goes to the provider you name and nowhere else: there is no PR Lens service in this path.
14
14
 
15
15
  ```bash
16
16
  export GEMINI_API_KEY=… # Gemini is the default, not a requirement
@@ -19,10 +19,10 @@ pr-lens analyze --base origin/main --head HEAD
19
19
 
20
20
  Three request shapes are implemented rather than a list of vendors:
21
21
 
22
- | `--provider` | Endpoint | Key |
23
- | --- | --- | --- |
24
- | `gemini` (default) | Google's own API | `GEMINI_API_KEY` |
25
- | `openai` | OpenAI's own API | `OPENAI_API_KEY` |
22
+ | `--provider` | Endpoint | Key |
23
+ | ------------------- | ----------------------------------------------------------------- | ---------------- |
24
+ | `gemini` (default) | Google's own API | `GEMINI_API_KEY` |
25
+ | `openai` | OpenAI's own API | `OPENAI_API_KEY` |
26
26
  | `openai-compatible` | anything else speaking `/chat/completions`, named by `--base-url` | `OPENAI_API_KEY` |
27
27
 
28
28
  DeepSeek, Anthropic's compatibility endpoint, OpenRouter, Ollama and llama.cpp are all reached by pointing `--base-url` at them, and a new vendor needs no release here. OpenAI is listed separately from the servers that copied it because the two have drifted: it renamed the output limit to `max_completion_tokens` and its newer models reject `max_tokens`, which is the only spelling the others know. There is no field both accept, so you say which endpoint you are talking to rather than the CLI guessing from a hostname.
@@ -43,6 +43,8 @@ None of it is meant to be committed. The SVGs, the document and the manifest are
43
43
 
44
44
  `--out` overrides the location on every command that writes. Point it somewhere else and PR Lens leaves your `.gitignore` alone: that directory is yours to decide about.
45
45
 
46
+ `canvas` keeps one more file there, `.pr-lens/canvas.json`, which holds the write token for every canvas this checkout has pushed. It is the one file in the directory that cannot be rebuilt, and a bigger reason the directory is ignored.
47
+
46
48
  ## The commands
47
49
 
48
50
  ### `analyze`
@@ -69,7 +71,7 @@ pr-lens render .pr-lens/graph.json
69
71
 
70
72
  Draws the document as self-contained light and dark SVGs (one pair per drill-down section per lens, or one pair per lens when the document has no sections), and writes two files beside them: `manifest.json`, which says what was drawn and under which file name, and `drawn.graph.json`, the document those pictures actually show.
71
73
 
72
- Both matter to what comes next. The manifest is where `comment` gets its file names, so neither command re-derives the other's. And `drawn.graph.json` exists because this is where corrections are applied: excluding a node can empty out a whole drill-down section, and the renderer then draws no picture for it. A comment composed from the document that went *in* would announce a section that came out of nothing.
74
+ Both matter to what comes next. The manifest is where `comment` gets its file names, so neither command re-derives the other's. And `drawn.graph.json` exists because this is where corrections are applied: excluding a node can empty out a whole drill-down section, and the renderer then draws no picture for it. A comment composed from the document that went _in_ would announce a section that came out of nothing.
73
75
 
74
76
  The SVGs carry no script and no external reference, and the same document renders to the same bytes every time. `--theme light` or `--theme dark` draws one half of the pair.
75
77
 
@@ -100,6 +102,34 @@ Turns a pull-request document into the map of the system once that pull request
100
102
 
101
103
  The map is a snapshot, not a source of truth. Nothing reads it back into the pipeline: a committed map that overrode inference would be hand-maintained rot with merge conflicts attached. Commit it so a repository has something to read, to diff, and to hand an agent.
102
104
 
105
+ ### `canvas`
106
+
107
+ ```bash
108
+ pr-lens canvas push
109
+ ```
110
+
111
+ Puts the document on prlens.dev as a canvas: a page anyone with the link can read, and an SVG a README can embed.
112
+
113
+ `push` sends the JSON document, never an SVG; the app draws it. The default is `.pr-lens/drawn.graph.json`, the document `render` drew, so what the page shows is what the diagrams show. The first push of a file mints a canvas and every push after that updates the same one, matched by the path it came from. `--canvas <id|name>` picks a different one and `--name` says what to call a new one; the document's title is the default. It prints three links:
114
+
115
+ ```
116
+ ✓ https://prlens.dev/c/{id} — rev 1 · 4 diagrams
117
+ edit link, keep it to yourself: https://prlens.dev/c/{id}#w=…
118
+ README embed: https://prlens.dev/c/{id}.svg
119
+ ```
120
+
121
+ The view link is the one to share. The edit link is the same page with the write token in the fragment, and anyone holding it can push over your canvas, so it stays with you. The embed is the hero diagram as an SVG, for a README or a wiki.
122
+
123
+ `pull` fetches the document back, by the view link or the bare id, into `.pr-lens/graph.json` unless `-o` says otherwise, and records the revision. Pull the edit link, the one ending in `#w=…`, and its token is recorded too: that is how a fresh checkout, or one that lost `.pr-lens/canvas.json`, gets the canvas back. A push carries the revision it last saw, and one that has been overtaken is refused rather than applied: pull, then push again.
124
+
125
+ `rotate` mints a new write token and retires the old one. Use it when an edit link has leaked. The CLI saves the new token before it sends the request, so if the connection drops, the next command finishes the rotation instead of losing the token. The token lives in `.pr-lens/canvas.json`, keyed by canvas id, and git ignores it. Lose that file and the canvas is still readable by everyone; pushing to it again needs the token, which the edit link still carries.
126
+
127
+ Registry writes take a lock at `.pr-lens/canvas.json.lock`. The CLI never removes another command's lock. If a command dies and leaves one behind, the error names its process id and you remove the file yourself.
128
+
129
+ The CLI refuses to write the registry where git could commit it. If a checkout tracks `.pr-lens/canvas.json` or un-ignores `.pr-lens/`, the command fails with `CANVAS_REGISTRY_EXPOSED` and writes nothing.
130
+
131
+ `--api` points at another PR Lens app, or set `PR_LENS_API_URL`.
132
+
103
133
  ## Corrections
104
134
 
105
135
  A repository's `.github/pr-lens.yml` is picked up automatically by `render` and applied at draw time: renames, exclusions, lane pins, groupings. It is an overlay: inference never writes back into it, so a correction keeps holding as the code moves and the model renames things between runs, and the document on disk stays the record of what was inferred.
@@ -120,7 +150,7 @@ A lane pin may name a lane the document never declared; the band is created and
120
150
 
121
151
  ## Failures
122
152
 
123
- Every failure carries a code, so a script can branch on it: `USAGE`, `UNREADABLE_FILE`, `UNKNOWN_DOCUMENT`, `INVALID_DOCUMENT`, `GIT_FAILED`, `EMPTY_DIFF`, `REPOSITORY_UNKNOWN`, `MISSING_API_KEY`, `PROVIDER_FAILED`, `MODEL_OUTPUT_INVALID`, `RENDER_FAILED`. Misuse exits 2, everything else exits 1.
153
+ Every failure carries a code, so a script can branch on it: `USAGE`, `UNREADABLE_FILE`, `UNKNOWN_DOCUMENT`, `INVALID_DOCUMENT`, `GIT_FAILED`, `EMPTY_DIFF`, `REPOSITORY_UNKNOWN`, `MISSING_API_KEY`, `PROVIDER_FAILED`, `MODEL_OUTPUT_INVALID`, `RENDER_FAILED`, and for `canvas`: `CANVAS_UNREGISTERED`, `CANVAS_UNKNOWN`, `CANVAS_CONFLICT`, `CANVAS_REJECTED`, `CANVAS_RATE_LIMITED`, `CANVAS_UNAVAILABLE`, `CANVAS_REGISTRY_EXPOSED`. Misuse exits 2, everything else exits 1.
124
154
 
125
155
  ---
126
156
 
@@ -0,0 +1,65 @@
1
+ import { type GraphDoc } from "@coldtea/pr-lens-schema";
2
+ import { z } from "zod";
3
+ declare const Minted: z.ZodObject<{
4
+ id: z.ZodString;
5
+ writeToken: z.ZodString;
6
+ rev: z.ZodNumber;
7
+ viewUrl: z.ZodString;
8
+ editUrl: z.ZodString;
9
+ embedUrl: z.ZodString;
10
+ }, z.core.$strip>;
11
+ declare const Fetched: z.ZodObject<{
12
+ id: z.ZodString;
13
+ rev: z.ZodNumber;
14
+ viewUrl: z.ZodString;
15
+ embedUrl: z.ZodString;
16
+ document: z.ZodUnknown;
17
+ tiles: z.ZodArray<z.ZodObject<{
18
+ id: z.ZodString;
19
+ title: z.ZodString;
20
+ lens: z.ZodString;
21
+ crumbs: z.ZodArray<z.ZodString>;
22
+ hero: z.ZodBoolean;
23
+ width: z.ZodNumber;
24
+ height: z.ZodNumber;
25
+ renders: z.ZodRecord<z.ZodString, z.ZodString>;
26
+ images: z.ZodRecord<z.ZodString, z.ZodString>;
27
+ }, z.core.$strip>>;
28
+ }, z.core.$strip>;
29
+ declare const Pushed: z.ZodObject<{
30
+ id: z.ZodString;
31
+ rev: z.ZodNumber;
32
+ viewUrl: z.ZodString;
33
+ editUrl: z.ZodString;
34
+ embedUrl: z.ZodString;
35
+ tiles: z.ZodArray<z.ZodObject<{
36
+ id: z.ZodString;
37
+ title: z.ZodString;
38
+ lens: z.ZodString;
39
+ crumbs: z.ZodArray<z.ZodString>;
40
+ hero: z.ZodBoolean;
41
+ width: z.ZodNumber;
42
+ height: z.ZodNumber;
43
+ renders: z.ZodRecord<z.ZodString, z.ZodString>;
44
+ images: z.ZodRecord<z.ZodString, z.ZodString>;
45
+ }, z.core.$strip>>;
46
+ }, z.core.$strip>;
47
+ declare const Rotated: z.ZodObject<{
48
+ id: z.ZodString;
49
+ editUrl: z.ZodString;
50
+ }, z.core.$strip>;
51
+ export type Minted = z.infer<typeof Minted>;
52
+ export type Pushed = z.infer<typeof Pushed>;
53
+ export type Rotated = z.infer<typeof Rotated>;
54
+ export type Fetched = Omit<z.infer<typeof Fetched>, "document"> & {
55
+ document: GraphDoc;
56
+ };
57
+ export declare const mintCanvas: (api: string) => Promise<Minted>;
58
+ export declare const fetchCanvas: (api: string, id: string) => Promise<Fetched>;
59
+ export declare const pushCanvas: (api: string, id: string, token: string, rev: number, document: GraphDoc) => Promise<Pushed>;
60
+ /** A rotation onto itself changes nothing and is answered "rotated" only for the current token. */
61
+ export declare const verifyWriteToken: (api: string, id: string, token: string) => Promise<boolean>;
62
+ /** The caller mints the next token, so a lost answer can be asked for again. */
63
+ export declare const rotateCanvas: (api: string, id: string, token: string, nextToken: string) => Promise<Rotated>;
64
+ export {};
65
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/canvas/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,QAAQ,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkBxB,QAAA,MAAM,MAAM;;;;;;;iBAOV,CAAC;AAEH,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;iBAOX,CAAC;AAEH,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;iBAOV,CAAC;AAEH,QAAA,MAAM,OAAO;;;iBAAoD,CAAC;AAElE,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAC5C,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAC5C,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC;AAC9C,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,EAAE,UAAU,CAAC,GAAG;IAChE,QAAQ,EAAE,QAAQ,CAAC;CACpB,CAAC;AAkLF,eAAO,MAAM,UAAU,QAAS,MAAM,KAAG,OAAO,CAAC,MAAM,CACwB,CAAC;AAEhF,eAAO,MAAM,WAAW,QACjB,MAAM,MACP,MAAM,KACT,OAAO,CAAC,OAAO,CAgBjB,CAAC;AAEF,eAAO,MAAM,UAAU,QAChB,MAAM,MACP,MAAM,SACH,MAAM,OACR,MAAM,YACD,QAAQ,KACjB,OAAO,CAAC,MAAM,CAYd,CAAC;AAEJ,mGAAmG;AACnG,eAAO,MAAM,gBAAgB,QACtB,MAAM,MACP,MAAM,SACH,MAAM,KACZ,OAAO,CAAC,OAAO,CAQf,CAAC;AAEJ,gFAAgF;AAChF,eAAO,MAAM,YAAY,QAClB,MAAM,MACP,MAAM,SACH,MAAM,aACF,MAAM,KAChB,OAAO,CAAC,OAAO,CAWf,CAAC"}
@@ -0,0 +1,175 @@
1
+ import { assertNever, safeParseGraphDoc, } from "@coldtea/pr-lens-schema";
2
+ import { z } from "zod";
3
+ import { PrLensCliError } from "../errors.js";
4
+ import { CLI_VERSION } from "../version.js";
5
+ const REQUEST_TIMEOUT_MS = 60_000;
6
+ const Tile = z.object({
7
+ id: z.string(),
8
+ title: z.string(),
9
+ lens: z.string(),
10
+ crumbs: z.array(z.string()),
11
+ hero: z.boolean(),
12
+ width: z.number(),
13
+ height: z.number(),
14
+ renders: z.record(z.string(), z.string()),
15
+ images: z.record(z.string(), z.string()),
16
+ });
17
+ const Minted = z.object({
18
+ id: z.string(),
19
+ writeToken: z.string(),
20
+ rev: z.number().int(),
21
+ viewUrl: z.string(),
22
+ editUrl: z.string(),
23
+ embedUrl: z.string(),
24
+ });
25
+ const Fetched = z.object({
26
+ id: z.string(),
27
+ rev: z.number().int(),
28
+ viewUrl: z.string(),
29
+ embedUrl: z.string(),
30
+ document: z.unknown(),
31
+ tiles: z.array(Tile),
32
+ });
33
+ const Pushed = z.object({
34
+ id: z.string(),
35
+ rev: z.number().int(),
36
+ viewUrl: z.string(),
37
+ editUrl: z.string(),
38
+ embedUrl: z.string(),
39
+ tiles: z.array(Tile),
40
+ });
41
+ const Rotated = z.object({ id: z.string(), editUrl: z.string() });
42
+ /** Loose inner object: an unknown code must still reach the refusal below. */
43
+ const Envelope = z.object({
44
+ error: z.looseObject({ code: z.string(), message: z.string() }),
45
+ });
46
+ const Refusal = z.discriminatedUnion("code", [
47
+ z.object({ code: z.literal("NOT_FOUND"), message: z.string() }),
48
+ z.object({ code: z.literal("INVALID_REQUEST"), message: z.string() }),
49
+ z.object({
50
+ code: z.literal("INVALID_DOCUMENT"),
51
+ message: z.string(),
52
+ issues: z.array(z.object({ code: z.string(), path: z.string(), message: z.string() })),
53
+ }),
54
+ z.object({ code: z.literal("CANNOT_DRAW"), message: z.string() }),
55
+ z.object({
56
+ code: z.literal("REVISION_MOVED"),
57
+ message: z.string(),
58
+ rev: z.number().int(),
59
+ }),
60
+ z.object({
61
+ code: z.literal("RATE_LIMITED"),
62
+ message: z.string(),
63
+ retryAt: z.string(),
64
+ }),
65
+ z.object({ code: z.literal("TOO_LARGE"), message: z.string() }),
66
+ ]);
67
+ const hostOf = (api) => new URL(api).host;
68
+ const unavailable = (api, status, details) => new PrLensCliError("CANVAS_UNAVAILABLE", status === undefined
69
+ ? `${hostOf(api)} did not answer`
70
+ : `${hostOf(api)} answered ${status}`, details);
71
+ const parseJson = (text) => {
72
+ try {
73
+ return JSON.parse(text);
74
+ }
75
+ catch {
76
+ return undefined;
77
+ }
78
+ };
79
+ const refusal = (api, request, status, body) => {
80
+ const envelope = Envelope.safeParse(body);
81
+ if (!envelope.success)
82
+ return unavailable(api, status);
83
+ const known = Refusal.safeParse(envelope.data.error);
84
+ if (!known.success)
85
+ return unavailable(api, status, envelope.data.error.message);
86
+ const error = known.data;
87
+ switch (error.code) {
88
+ case "NOT_FOUND":
89
+ return request.canvas === undefined
90
+ ? unavailable(api, status, error.message)
91
+ : new PrLensCliError("CANVAS_UNKNOWN", `no canvas ${request.canvas} at ${hostOf(api)}, or the token is wrong`, "if the token was rotated elsewhere, pull the current edit link to record it");
92
+ case "REVISION_MOVED":
93
+ return new PrLensCliError("CANVAS_CONFLICT", `${request.canvas ?? "the canvas"} is at rev ${error.rev} on ${hostOf(api)}, not rev ${request.ifMatch ?? "?"}`, "pr-lens canvas pull, then push again");
94
+ case "INVALID_DOCUMENT":
95
+ return new PrLensCliError("CANVAS_REJECTED", error.message, error.issues
96
+ .map((issue) => issue.path === ""
97
+ ? issue.message
98
+ : `${issue.path}: ${issue.message}`)
99
+ .join("\n"));
100
+ case "CANNOT_DRAW":
101
+ // Passed the contract but nothing to draw; the app's message says why.
102
+ return new PrLensCliError("CANVAS_REJECTED", error.message);
103
+ case "RATE_LIMITED":
104
+ return new PrLensCliError("CANVAS_RATE_LIMITED", `${hostOf(api)} is rate limiting this client until ${error.retryAt}`, error.message);
105
+ case "INVALID_REQUEST":
106
+ case "TOO_LARGE":
107
+ return unavailable(api, status, error.message);
108
+ default:
109
+ return assertNever(error, "Unhandled canvas refusal");
110
+ }
111
+ };
112
+ const call = async (api, request, schema) => {
113
+ const headers = {
114
+ accept: "application/json",
115
+ "user-agent": `pr-lens-cli/${CLI_VERSION}`,
116
+ };
117
+ if (request.token !== undefined)
118
+ headers.authorization = `Bearer ${request.token}`;
119
+ if (request.ifMatch !== undefined)
120
+ headers["if-match"] = String(request.ifMatch);
121
+ if (request.body !== undefined)
122
+ headers["content-type"] = "application/json";
123
+ const response = await fetch(`${api}${request.path}`, {
124
+ method: request.method,
125
+ headers,
126
+ body: request.body === undefined ? undefined : JSON.stringify(request.body),
127
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
128
+ }).catch(() => {
129
+ // The runtime's message names addresses and internals; keep it out.
130
+ throw unavailable(api, undefined, "check the address and the connection, then try again");
131
+ });
132
+ // A body can fail after the headers arrived.
133
+ const text = await response.text().catch(() => {
134
+ throw unavailable(api, response.status, "the answer was cut off; check the connection, then try again");
135
+ });
136
+ const body = parseJson(text);
137
+ if (!response.ok)
138
+ throw refusal(api, request, response.status, body);
139
+ const parsed = schema.safeParse(body);
140
+ if (!parsed.success)
141
+ throw unavailable(api, response.status, "the answer was not in the shape the canvas API documents");
142
+ return parsed.data;
143
+ };
144
+ const canvasPath = (id) => `/api/canvas/${id}`;
145
+ export const mintCanvas = (api) => call(api, { method: "POST", path: "/api/canvas", canvas: undefined }, Minted);
146
+ export const fetchCanvas = async (api, id) => {
147
+ const fetched = await call(api, { method: "GET", path: canvasPath(id), canvas: id }, Fetched);
148
+ const document = safeParseGraphDoc(fetched.document);
149
+ if (!document.ok)
150
+ throw new PrLensCliError("CANVAS_UNAVAILABLE", `${hostOf(api)} serves a document for ${id} that this CLI cannot read [${document.error.code}]`, "a newer CLI may know the shape: npx @coldtea/pr-lens-cli@latest");
151
+ return { ...fetched, document: document.value };
152
+ };
153
+ export const pushCanvas = (api, id, token, rev, document) => call(api, {
154
+ method: "PUT",
155
+ path: canvasPath(id),
156
+ canvas: id,
157
+ token,
158
+ ifMatch: rev,
159
+ body: document,
160
+ }, Pushed);
161
+ /** A rotation onto itself changes nothing and is answered "rotated" only for the current token. */
162
+ export const verifyWriteToken = (api, id, token) => rotateCanvas(api, id, token, token).then(() => true, (error) => {
163
+ if (error instanceof PrLensCliError && error.code === "CANVAS_UNKNOWN")
164
+ return false;
165
+ throw error;
166
+ });
167
+ /** The caller mints the next token, so a lost answer can be asked for again. */
168
+ export const rotateCanvas = (api, id, token, nextToken) => call(api, {
169
+ method: "POST",
170
+ path: `${canvasPath(id)}/rotate`,
171
+ canvas: id,
172
+ token,
173
+ body: { writeToken: nextToken },
174
+ }, Rotated);
175
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/canvas/api.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,iBAAiB,GAElB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC;IACpB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;IACjB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;CACzC,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC,CAAC;AAEH,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC;IACvB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;IACrB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CACrB,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;CACrB,CAAC,CAAC;AAEH,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AASlE,8EAA8E;AAC9E,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC;IACxB,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;CAChE,CAAC,CAAC;AAEH,MAAM,OAAO,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC3C,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IAC/D,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IACrE,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC;QACnC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,MAAM,EAAE,CAAC,CAAC,KAAK,CACb,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACtE;KACF,CAAC;IACF,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IACjE,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACjC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;KACtB,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;QAC/B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;KACpB,CAAC;IACF,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;CAChE,CAAC,CAAC;AAYH,MAAM,MAAM,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AAE1D,MAAM,WAAW,GAAG,CAClB,GAAW,EACX,MAA0B,EAC1B,OAAgB,EACA,EAAE,CAClB,IAAI,cAAc,CAChB,oBAAoB,EACpB,MAAM,KAAK,SAAS;IAClB,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,iBAAiB;IACjC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,MAAM,EAAE,EACvC,OAAO,CACR,CAAC;AAEJ,MAAM,SAAS,GAAG,CAAC,IAAY,EAAW,EAAE;IAC1C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,CACd,GAAW,EACX,OAAgB,EAChB,MAAc,EACd,IAAa,EACG,EAAE;IAClB,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,QAAQ,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAEvD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,CAAC,KAAK,CAAC,OAAO;QAChB,OAAO,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAE/D,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC;IACzB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,OAAO,CAAC,MAAM,KAAK,SAAS;gBACjC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;gBACzC,CAAC,CAAC,IAAI,cAAc,CAChB,gBAAgB,EAChB,aAAa,OAAO,CAAC,MAAM,OAAO,MAAM,CAAC,GAAG,CAAC,yBAAyB,EACtE,6EAA6E,CAC9E,CAAC;QACR,KAAK,gBAAgB;YACnB,OAAO,IAAI,cAAc,CACvB,iBAAiB,EACjB,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,cAAc,KAAK,CAAC,GAAG,OAAO,MAAM,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,OAAO,IAAI,GAAG,EAAE,EAC/G,sCAAsC,CACvC,CAAC;QACJ,KAAK,kBAAkB;YACrB,OAAO,IAAI,cAAc,CACvB,iBAAiB,EACjB,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,MAAM;iBACT,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACb,KAAK,CAAC,IAAI,KAAK,EAAE;gBACf,CAAC,CAAC,KAAK,CAAC,OAAO;gBACf,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CACtC;iBACA,IAAI,CAAC,IAAI,CAAC,CACd,CAAC;QACJ,KAAK,aAAa;YAChB,uEAAuE;YACvE,OAAO,IAAI,cAAc,CAAC,iBAAiB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9D,KAAK,cAAc;YACjB,OAAO,IAAI,cAAc,CACvB,qBAAqB,EACrB,GAAG,MAAM,CAAC,GAAG,CAAC,uCAAuC,KAAK,CAAC,OAAO,EAAE,EACpE,KAAK,CAAC,OAAO,CACd,CAAC;QACJ,KAAK,iBAAiB,CAAC;QACvB,KAAK,WAAW;YACd,OAAO,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACjD;YACE,OAAO,WAAW,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,KAAK,EAChB,GAAW,EACX,OAAgB,EAChB,MAAoB,EACR,EAAE;IACd,MAAM,OAAO,GAA2B;QACtC,MAAM,EAAE,kBAAkB;QAC1B,YAAY,EAAE,eAAe,WAAW,EAAE;KAC3C,CAAC;IAEF,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;QAC7B,OAAO,CAAC,aAAa,GAAG,UAAU,OAAO,CAAC,KAAK,EAAE,CAAC;IAEpD,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAC/B,OAAO,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;IAE7E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE;QACpD,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO;QACP,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;QAC3E,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;KAChD,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QACZ,oEAAoE;QACpE,MAAM,WAAW,CACf,GAAG,EACH,SAAS,EACT,sDAAsD,CACvD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,6CAA6C;IAC7C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;QAC5C,MAAM,WAAW,CACf,GAAG,EACH,QAAQ,CAAC,MAAM,EACf,8DAA8D,CAC/D,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAErE,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,CAAC,OAAO;QACjB,MAAM,WAAW,CACf,GAAG,EACH,QAAQ,CAAC,MAAM,EACf,0DAA0D,CAC3D,CAAC;IAEJ,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,eAAe,EAAE,EAAE,CAAC;AAE/D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAmB,EAAE,CACzD,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAEhF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,GAAW,EACX,EAAU,EACQ,EAAE;IACpB,MAAM,OAAO,GAAG,MAAM,IAAI,CACxB,GAAG,EACH,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EACnD,OAAO,CACR,CAAC;IAEF,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,CAAC,QAAQ,CAAC,EAAE;QACd,MAAM,IAAI,cAAc,CACtB,oBAAoB,EACpB,GAAG,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,+BAA+B,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,EAC/F,iEAAiE,CAClE,CAAC;IAEJ,OAAO,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;AAClD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,GAAW,EACX,EAAU,EACV,KAAa,EACb,GAAW,EACX,QAAkB,EACD,EAAE,CACnB,IAAI,CACF,GAAG,EACH;IACE,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC;IACpB,MAAM,EAAE,EAAE;IACV,KAAK;IACL,OAAO,EAAE,GAAG;IACZ,IAAI,EAAE,QAAQ;CACf,EACD,MAAM,CACP,CAAC;AAEJ,mGAAmG;AACnG,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,GAAW,EACX,EAAU,EACV,KAAa,EACK,EAAE,CACpB,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CACtC,GAAG,EAAE,CAAC,IAAI,EACV,CAAC,KAAc,EAAE,EAAE;IACjB,IAAI,KAAK,YAAY,cAAc,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB;QACpE,OAAO,KAAK,CAAC;IACf,MAAM,KAAK,CAAC;AACd,CAAC,CACF,CAAC;AAEJ,gFAAgF;AAChF,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,GAAW,EACX,EAAU,EACV,KAAa,EACb,SAAiB,EACC,EAAE,CACpB,IAAI,CACF,GAAG,EACH;IACE,MAAM,EAAE,MAAM;IACd,IAAI,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC,SAAS;IAChC,MAAM,EAAE,EAAE;IACV,KAAK;IACL,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE;CAChC,EACD,OAAO,CACR,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ import type { Terminal } from "../terminal.js";
3
+ /** Holds write tokens, the one thing here nothing can rebuild. */
4
+ export declare const REGISTRY_PATH: string;
5
+ export declare const isCanvasId: (value: string) => boolean;
6
+ export declare const mintWriteToken: () => string;
7
+ declare const Entry: z.ZodObject<{
8
+ name: z.ZodString;
9
+ source: z.ZodString;
10
+ api: z.ZodString;
11
+ writeToken: z.ZodOptional<z.ZodString>;
12
+ pending: z.ZodOptional<z.ZodString>;
13
+ rev: z.ZodNumber;
14
+ }, z.core.$strip>;
15
+ declare const Registry: z.ZodObject<{
16
+ canvases: z.ZodRecord<z.ZodString, z.ZodObject<{
17
+ name: z.ZodString;
18
+ source: z.ZodString;
19
+ api: z.ZodString;
20
+ writeToken: z.ZodOptional<z.ZodString>;
21
+ pending: z.ZodOptional<z.ZodString>;
22
+ rev: z.ZodNumber;
23
+ }, z.core.$strip>>;
24
+ }, z.core.$strip>;
25
+ export type CanvasEntry = z.infer<typeof Entry>;
26
+ export type CanvasRegistry = z.infer<typeof Registry>;
27
+ export type Registered = {
28
+ id: string;
29
+ entry: CanvasEntry;
30
+ };
31
+ export declare const readRegistry: () => Promise<CanvasRegistry>;
32
+ /** Asked before a canvas is minted, so a refusal costs nothing on the app. */
33
+ export declare const ensureRegistryHome: (terminal: Terminal) => Promise<void>;
34
+ /** Compared case-blind and by inode: macOS ignores case, and a link is the same file. */
35
+ export declare const isReservedRegistryTarget: (path: string) => Promise<boolean>;
36
+ export declare const writeRegistry: (registry: CanvasRegistry, terminal: Terminal) => Promise<void>;
37
+ /** Two commands writing the whole file at once would each keep only their own change. */
38
+ export declare const withRegistryLock: <T>(work: () => Promise<T>) => Promise<T>;
39
+ export declare const updateRegistry: (change: (registry: CanvasRegistry) => void, terminal: Terminal) => Promise<CanvasRegistry>;
40
+ export declare const sourceKey: (path: string) => string;
41
+ export declare const findCanvas: (registry: CanvasRegistry, ref: string) => Registered;
42
+ export declare const findBySource: (registry: CanvasRegistry, path: string) => Registered | undefined;
43
+ export declare const onlyCanvas: (registry: CanvasRegistry) => Registered;
44
+ export {};
45
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/canvas/registry.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK/C,kEAAkE;AAClE,eAAO,MAAM,aAAa,QAAqC,CAAC;AAMhE,eAAO,MAAM,UAAU,UAAW,MAAM,KAAG,OAAgC,CAAC;AAE5E,eAAO,MAAM,cAAc,QAAO,MACK,CAAC;AAExC,QAAA,MAAM,KAAK;;;;;;;iBAUT,CAAC;AAEH,QAAA,MAAM,QAAQ;;;;;;;;;iBAEZ,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC;AAChD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AACtD,MAAM,MAAM,UAAU,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AAQ5D,eAAO,MAAM,YAAY,QAAa,OAAO,CAAC,cAAc,CAc3D,CAAC;AAkGF,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,aAAoB,QAAQ,KAAG,OAAO,CAAC,IAAI,CAGzE,CAAC;AAWF,yFAAyF;AACzF,eAAO,MAAM,wBAAwB,SAC7B,MAAM,KACX,OAAO,CAAC,OAAO,CA6BjB,CAAC;AAEF,eAAO,MAAM,aAAa,aACd,cAAc,YACd,QAAQ,KACjB,OAAO,CAAC,IAAI,CAGd,CAAC;AAyHF,yFAAyF;AACzF,eAAO,MAAM,gBAAgB,GAAU,CAAC,QAChC,MAAM,OAAO,CAAC,CAAC,CAAC,KACrB,OAAO,CAAC,CAAC,CAwCX,CAAC;AAEF,eAAO,MAAM,cAAc,WACjB,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,YAChC,QAAQ,KACjB,OAAO,CAAC,cAAc,CAMrB,CAAC;AAEL,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,MACD,CAAC;AAUzC,eAAO,MAAM,UAAU,aACX,cAAc,OACnB,MAAM,KACV,UAoBF,CAAC;AAEF,eAAO,MAAM,YAAY,aACb,cAAc,QAClB,MAAM,KACX,UAAU,GAAG,SAaf,CAAC;AAEF,eAAO,MAAM,UAAU,aAAc,cAAc,KAAG,UAiBrD,CAAC"}