hacklab 0.7.4 → 0.7.5
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/README.md +16 -1
- package/dist/api-client.d.ts +18 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +40 -0
- package/dist/api-client.js.map +1 -0
- package/dist/commands/drop.d.ts +1 -1
- package/dist/commands/drop.js +1 -1
- package/dist/commands/hacker.d.ts.map +1 -1
- package/dist/commands/hacker.js +13 -28
- package/dist/commands/hacker.js.map +1 -1
- package/dist/commands/profile.d.ts +60 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +478 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/project.d.ts +5 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +387 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/project-infer.d.ts +50 -0
- package/dist/project-infer.d.ts.map +1 -0
- package/dist/project-infer.js +211 -0
- package/dist/project-infer.js.map +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +13 -6
- package/dist/registry.js.map +1 -1
- package/package.json +1 -1
- package/dist/commands/brag.d.ts +0 -5
- package/dist/commands/brag.d.ts.map +0 -1
- package/dist/commands/brag.js +0 -92
- package/dist/commands/brag.js.map +0 -1
- package/dist/project-brag.d.ts +0 -58
- package/dist/project-brag.d.ts.map +0 -1
- package/dist/project-brag.js +0 -270
- package/dist/project-brag.js.map +0 -1
package/README.md
CHANGED
|
@@ -74,12 +74,27 @@ scan local AI usage → see your rank → pick a username → sign in with GitHu
|
|
|
74
74
|
- `hacklab logout` — clear your saved session on this machine.
|
|
75
75
|
- `hacklab config <key> <value>` — set config (`cursor-api-key`, `cursor-email`).
|
|
76
76
|
Bare `hacklab config` prints the effective values and where each came from.
|
|
77
|
-
- `hacklab
|
|
77
|
+
- `hacklab project` — publish the repo you're standing in as a project. No
|
|
78
|
+
manifest: it reads the git remote, README, and package.json, shows a preview,
|
|
79
|
+
and publishes on confirm (`--yes` to skip, `--json` for agents). Re-running
|
|
80
|
+
refreshes the same project (slug derives from the repo name) without losing
|
|
81
|
+
its publish date or screenshots; if the live site (package.json `homepage` or
|
|
82
|
+
`--live <url>`) has an `og:image`, that becomes the screenshot. Override any
|
|
83
|
+
inferred field with `--title`, `--description`, `--live`, `--tags a,b,c`,
|
|
84
|
+
`--slug`. Manage the set with `hacklab project list` and
|
|
85
|
+
`hacklab project delete <slug>`.
|
|
78
86
|
- `hacklab org` — hub for company management. If you already own a company, pick
|
|
79
87
|
a field, type the new value, and it saves as you go. If you don't own one yet,
|
|
80
88
|
it offers to claim or create. Subcommands: `hacklab org claim` (take ownership
|
|
81
89
|
of a YC-seeded company you're a member of, or whose domain matches your login
|
|
82
90
|
email) and `hacklab org create` (register a brand-new company from the CLI).
|
|
91
|
+
- `hacklab profile` — view and edit your own profile. Bare `profile` (or
|
|
92
|
+
`profile view`) shows it; `profile edit` is an org-style autosave editor;
|
|
93
|
+
`profile set <field> <value>` writes one field (`--clear` unsets, handles like
|
|
94
|
+
`x mattbratos` become full links); `profile apply profile.yaml` writes many
|
|
95
|
+
fields in one shot — handy for agents setting up your profile. Fields: `name`,
|
|
96
|
+
`bio`, `website`, `blog`, `x`, `youtube`, `instagram`, `rss`, `open-to-work`.
|
|
97
|
+
Add `--json` to `view`/`set`/`apply` for machine-readable output.
|
|
83
98
|
- `hacklab --version` / `hacklab --help`.
|
|
84
99
|
|
|
85
100
|
## Cursor usage
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Session } from './session.js';
|
|
2
|
+
/** Print the versioned JSON error envelope and exit 1 (agent mode). */
|
|
3
|
+
export declare function emitJsonError(code: string, message: string): never;
|
|
4
|
+
/** Login gate: returns the session or exits with mode-appropriate copy. */
|
|
5
|
+
export declare function requireSession(json: boolean): Promise<Session>;
|
|
6
|
+
/**
|
|
7
|
+
* Human-readable message for a non-2xx envelope body. 401 gets the per-backend
|
|
8
|
+
* re-login hint (an --env mismatch names the exact login command), 429 the
|
|
9
|
+
* slow-down copy; anything else relays the server's message.
|
|
10
|
+
*/
|
|
11
|
+
export declare function apiErrorMessage(status: number, body: {
|
|
12
|
+
error?: {
|
|
13
|
+
message?: string;
|
|
14
|
+
};
|
|
15
|
+
} | null, session: Session): string;
|
|
16
|
+
/** Read a failed Response's envelope and shape it via apiErrorMessage. */
|
|
17
|
+
export declare function readApiError(res: Response, session: Session): Promise<string>;
|
|
18
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,OAAO,EAAoB,MAAM,cAAc,CAAA;AAO1E,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAGlE;AAED,2EAA2E;AAC3E,wBAAsB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CASpE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,IAAI,EAC7C,OAAO,EAAE,OAAO,GACf,MAAM,CAIR;AAED,0EAA0E;AAC1E,wBAAsB,YAAY,CAChC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,CAKjB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { loadSession, unauthorizedHint } from './session.js';
|
|
2
|
+
import { dim, error, info } from './ui.js';
|
|
3
|
+
// Shared plumbing for authenticated agent-friendly commands (profile, hacker):
|
|
4
|
+
// one login gate, one JSON error envelope, one reader for the server's
|
|
5
|
+
// {schemaVersion, error} shape — so the 401/429 copy can't drift per command.
|
|
6
|
+
/** Print the versioned JSON error envelope and exit 1 (agent mode). */
|
|
7
|
+
export function emitJsonError(code, message) {
|
|
8
|
+
console.log(JSON.stringify({ schemaVersion: 1, error: { code, message } }));
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
/** Login gate: returns the session or exits with mode-appropriate copy. */
|
|
12
|
+
export async function requireSession(json) {
|
|
13
|
+
const session = await loadSession();
|
|
14
|
+
if (!session) {
|
|
15
|
+
if (json)
|
|
16
|
+
emitJsonError('unauthorized', 'not logged in');
|
|
17
|
+
error('not logged in');
|
|
18
|
+
info(`run ${dim('hacklab login')} first`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
return session;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Human-readable message for a non-2xx envelope body. 401 gets the per-backend
|
|
25
|
+
* re-login hint (an --env mismatch names the exact login command), 429 the
|
|
26
|
+
* slow-down copy; anything else relays the server's message.
|
|
27
|
+
*/
|
|
28
|
+
export function apiErrorMessage(status, body, session) {
|
|
29
|
+
if (status === 401)
|
|
30
|
+
return unauthorizedHint(session);
|
|
31
|
+
if (status === 429)
|
|
32
|
+
return 'slow down. try again in a minute.';
|
|
33
|
+
return body?.error?.message ?? `request failed (${status})`;
|
|
34
|
+
}
|
|
35
|
+
/** Read a failed Response's envelope and shape it via apiErrorMessage. */
|
|
36
|
+
export async function readApiError(res, session) {
|
|
37
|
+
const body = (await res.json().catch(() => null));
|
|
38
|
+
return apiErrorMessage(res.status, body, session);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAgB,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC1E,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE1C,+EAA+E;AAC/E,uEAAuE;AACvE,8EAA8E;AAE9E,uEAAuE;AACvE,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,OAAe;IACzD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;IAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAa;IAChD,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,IAAI,IAAI;YAAE,aAAa,CAAC,cAAc,EAAE,eAAe,CAAC,CAAA;QACxD,KAAK,CAAC,eAAe,CAAC,CAAA;QACtB,IAAI,CAAC,OAAO,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAA;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,IAA6C,EAC7C,OAAgB;IAEhB,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACpD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,mCAAmC,CAAA;IAC9D,OAAO,IAAI,EAAE,KAAK,EAAE,OAAO,IAAI,mBAAmB,MAAM,GAAG,CAAA;AAC7D,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAa,EACb,OAAgB;IAEhB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAExC,CAAA;IACR,OAAO,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AACnD,CAAC"}
|
package/dist/commands/drop.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Parse `drop` args: free words become the message, `-u/--url <url>` attaches a
|
|
3
|
-
* link.
|
|
3
|
+
* link. Each command owns its own
|
|
4
4
|
* parsing. Exits with a usage error on an unknown flag or an empty message.
|
|
5
5
|
*/
|
|
6
6
|
export declare function parseDropArgs(args: string[]): {
|
package/dist/commands/drop.js
CHANGED
|
@@ -3,7 +3,7 @@ import { loadSession, resolveAppUrl } from '../session.js';
|
|
|
3
3
|
import { dim, error, info, success } from '../ui.js';
|
|
4
4
|
/**
|
|
5
5
|
* Parse `drop` args: free words become the message, `-u/--url <url>` attaches a
|
|
6
|
-
* link.
|
|
6
|
+
* link. Each command owns its own
|
|
7
7
|
* parsing. Exits with a usage error on an unknown flag or an empty message.
|
|
8
8
|
*/
|
|
9
9
|
export function parseDropArgs(args) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hacker.d.ts","sourceRoot":"","sources":["../../src/commands/hacker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hacker.d.ts","sourceRoot":"","sources":["../../src/commands/hacker.ts"],"names":[],"mappings":"AAyBA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAe1D"}
|
package/dist/commands/hacker.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { apiErrorMessage, emitJsonError, requireSession, } from '../api-client.js';
|
|
1
2
|
import { renderCard } from '../card.js';
|
|
2
3
|
import { resolveCommand } from '../resolve-command.js';
|
|
3
|
-
import {
|
|
4
|
-
import { fetchApi, LOGIN_EXPIRED_MESSAGE } from '../sync.js';
|
|
4
|
+
import { fetchApi } from '../sync.js';
|
|
5
5
|
import { dim, error, info } from '../ui.js';
|
|
6
|
-
// `hacklab hacker view <handle>` —
|
|
7
|
-
// agents.
|
|
8
|
-
//
|
|
9
|
-
//
|
|
6
|
+
// `hacklab hacker view <handle>` — look at another hacker's card, `--json` for
|
|
7
|
+
// agents. Managing your own profile is `hacklab profile`'s job; this command is
|
|
8
|
+
// the window, that one is the mirror. Noun-verb so an identifier never sits in
|
|
9
|
+
// a verb slot (a handle can be any word). Subcommands resolve by shortest
|
|
10
|
+
// unambiguous prefix, so `hacklab h v isomiki` works via resolveCommand.
|
|
10
11
|
const SUBCOMMANDS = ['view'];
|
|
11
12
|
function usage() {
|
|
12
13
|
error('usage: hacklab hacker view <handle>');
|
|
14
|
+
info(`looking for your own profile? run ${dim('hacklab profile')}`);
|
|
13
15
|
process.exit(1);
|
|
14
16
|
}
|
|
15
17
|
export async function hacker(args) {
|
|
@@ -33,14 +35,7 @@ async function hackerView(args) {
|
|
|
33
35
|
const handle = args.find((a) => !a.startsWith('-'));
|
|
34
36
|
if (!handle)
|
|
35
37
|
usage();
|
|
36
|
-
const session = await
|
|
37
|
-
if (!session) {
|
|
38
|
-
if (json)
|
|
39
|
-
return emitJsonError('unauthorized', LOGIN_EXPIRED_MESSAGE);
|
|
40
|
-
error('not logged in');
|
|
41
|
-
info(`run ${dim('hacklab login')} first`);
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
38
|
+
const session = await requireSession(json);
|
|
44
39
|
let res;
|
|
45
40
|
try {
|
|
46
41
|
res = await fetchApi(session, `/api/hackers/${encodeURIComponent(handle)}?src=cli`, { headers: { Authorization: `Bearer ${session.token}` } });
|
|
@@ -67,6 +62,9 @@ async function hackerView(args) {
|
|
|
67
62
|
return;
|
|
68
63
|
}
|
|
69
64
|
console.log(renderCard(body.hacker, { columns: process.stdout.columns }).join('\n'));
|
|
65
|
+
if (session.handle && session.handle.toLowerCase() === handle.toLowerCase()) {
|
|
66
|
+
info(dim(`this is you — edit with hacklab profile`));
|
|
67
|
+
}
|
|
70
68
|
}
|
|
71
69
|
/** Non-200 handling. In --json mode, relay the server's error envelope verbatim. */
|
|
72
70
|
async function handleError(res, handle, json, session) {
|
|
@@ -79,15 +77,6 @@ async function handleError(res, handle, json, session) {
|
|
|
79
77
|
}, null, 2));
|
|
80
78
|
process.exit(1);
|
|
81
79
|
}
|
|
82
|
-
if (res.status === 401) {
|
|
83
|
-
error(LOGIN_EXPIRED_MESSAGE);
|
|
84
|
-
info(`run ${dim('hacklab login')} again`);
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
if (res.status === 429) {
|
|
88
|
-
error('slow down. try again in a minute.');
|
|
89
|
-
process.exit(1);
|
|
90
|
-
}
|
|
91
80
|
if (res.status === 404) {
|
|
92
81
|
error(`no hacker named "${handle}"`);
|
|
93
82
|
const near = await nearestHandle(session, handle);
|
|
@@ -95,7 +84,7 @@ async function handleError(res, handle, json, session) {
|
|
|
95
84
|
info(`did you mean ${dim(`hacklab hacker view ${near}`)}?`);
|
|
96
85
|
process.exit(1);
|
|
97
86
|
}
|
|
98
|
-
error(
|
|
87
|
+
error(apiErrorMessage(res.status, body, session));
|
|
99
88
|
process.exit(1);
|
|
100
89
|
}
|
|
101
90
|
/** Best-effort near-match from the public search endpoint. Never throws. */
|
|
@@ -112,8 +101,4 @@ async function nearestHandle(session, handle) {
|
|
|
112
101
|
return null;
|
|
113
102
|
}
|
|
114
103
|
}
|
|
115
|
-
function emitJsonError(code, message) {
|
|
116
|
-
console.log(JSON.stringify({ schemaVersion: 1, error: { code, message } }));
|
|
117
|
-
process.exit(1);
|
|
118
|
-
}
|
|
119
104
|
//# sourceMappingURL=hacker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hacker.js","sourceRoot":"","sources":["../../src/commands/hacker.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"hacker.js","sourceRoot":"","sources":["../../src/commands/hacker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export type ProfileFieldKind = 'text' | 'url' | 'handle' | 'boolean';
|
|
2
|
+
export type ProfileField = {
|
|
3
|
+
/** API key sent to /api/hackers/me. */
|
|
4
|
+
key: string;
|
|
5
|
+
/** CLI-facing name (`hacklab profile set <name> …`). */
|
|
6
|
+
name: string;
|
|
7
|
+
kind: ProfileFieldKind;
|
|
8
|
+
/** handle kind: URL prepended to a bare handle. */
|
|
9
|
+
base?: string;
|
|
10
|
+
/** handle kind: recognized site prefixes to strip before rebuilding. */
|
|
11
|
+
strip?: RegExp;
|
|
12
|
+
hint: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const PROFILE_FIELDS: ProfileField[];
|
|
15
|
+
type Profile = {
|
|
16
|
+
handle: string;
|
|
17
|
+
displayName: string | null;
|
|
18
|
+
bio: string | null;
|
|
19
|
+
websiteUrl: string | null;
|
|
20
|
+
blogUrl: string | null;
|
|
21
|
+
xUrl: string | null;
|
|
22
|
+
youtubeUrl: string | null;
|
|
23
|
+
instagramUrl: string | null;
|
|
24
|
+
rssFeedUrl: string | null;
|
|
25
|
+
githubUsername: string | null;
|
|
26
|
+
openToWork: boolean;
|
|
27
|
+
claimed: boolean;
|
|
28
|
+
};
|
|
29
|
+
export type NormalizedValue = {
|
|
30
|
+
ok: true;
|
|
31
|
+
value: string | boolean | null;
|
|
32
|
+
} | {
|
|
33
|
+
ok: false;
|
|
34
|
+
error: string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Shape one raw CLI string into the value the API expects. Empty clears the
|
|
38
|
+
* field. URLs get https:// prepended when the scheme is missing; handle fields
|
|
39
|
+
* additionally accept a bare handle (`@mattbratos`, `mattbratos`) or a pasted
|
|
40
|
+
* profile URL and rebuild the canonical link. Real validation stays server-side.
|
|
41
|
+
*/
|
|
42
|
+
export declare function normalizeFieldValue(field: ProfileField, raw: string): NormalizedValue;
|
|
43
|
+
/**
|
|
44
|
+
* Map a parsed yaml/json document to API fields. Keys may be CLI names
|
|
45
|
+
* (`website`, `open-to-work`) or API keys (`websiteUrl`, `openToWork`);
|
|
46
|
+
* unknown keys fail loudly so a typo can't silently drop a field.
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseProfileDocument(doc: unknown): {
|
|
49
|
+
ok: true;
|
|
50
|
+
fields: Record<string, string | boolean | null>;
|
|
51
|
+
} | {
|
|
52
|
+
ok: false;
|
|
53
|
+
error: string;
|
|
54
|
+
};
|
|
55
|
+
/** Value column for human output. */
|
|
56
|
+
export declare function displayValue(field: ProfileField, value: unknown): string;
|
|
57
|
+
export declare function renderProfile(profile: Profile, appUrl: string): string[];
|
|
58
|
+
export declare function profile(args: string[]): Promise<void>;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/commands/profile.ts"],"names":[],"mappings":"AAqBA,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAA;AAEpE,MAAM,MAAM,YAAY,GAAG;IACzB,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAA;IACX,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,gBAAgB,CAAA;IACtB,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAID,eAAO,MAAM,cAAc,EAAE,YAAY,EAuCxC,CAAA;AAID,KAAK,OAAO,GAAG;IACb,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,UAAU,EAAE,OAAO,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAOD,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAahC;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,MAAM,GACV,eAAe,CA0BjB;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAC7C;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAA;CAAE,GAC7D;IACE,EAAE,EAAE,KAAK,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;CACd,CAsCJ;AAED,qCAAqC;AACrC,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAIxE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAgCxE;AAqSD,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB3D"}
|