@vibes.diy/api-svc 12.3.2 → 13.0.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.
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/intern/dead-letter-log.d.ts +10 -0
- package/intern/dead-letter-log.js +60 -0
- package/intern/dead-letter-log.js.map +1 -0
- package/intern/ensure-chat-id.d.ts +1 -0
- package/intern/ensure-chat-id.js +4 -2
- package/intern/ensure-chat-id.js.map +1 -1
- package/intern/get-open-turn.js +19 -6
- package/intern/get-open-turn.js.map +1 -1
- package/intern/half-open-turn.d.ts +5 -2
- package/intern/half-open-turn.js +7 -3
- package/intern/half-open-turn.js.map +1 -1
- package/intern/mint-admission.d.ts +1 -0
- package/intern/mint-admission.js +10 -0
- package/intern/mint-admission.js.map +1 -1
- package/intern/mint-fire-core.d.ts +2 -1
- package/intern/mint-fire-core.js +14 -7
- package/intern/mint-fire-core.js.map +1 -1
- package/intern/mint-job-store.d.ts +17 -7
- package/intern/mint-job-store.js +47 -5
- package/intern/mint-job-store.js.map +1 -1
- package/intern/prompt-assembly.d.ts +2 -0
- package/intern/prompt-assembly.js +9 -1
- package/intern/prompt-assembly.js.map +1 -1
- package/intern/work-tools.d.ts +13 -1
- package/intern/work-tools.js +45 -2
- package/intern/work-tools.js.map +1 -1
- package/package.json +14 -12
- package/public/llm-dispatch.d.ts +1 -0
- package/public/llm-dispatch.js +1 -1
- package/public/llm-dispatch.js.map +1 -1
- package/public/open-chat.js +9 -5
- package/public/open-chat.js.map +1 -1
- package/public/prompt-chat-section.d.ts +2 -2
- package/public/prompt-chat-section.js +20 -5
- package/public/prompt-chat-section.js.map +1 -1
- package/public/serv-entry-point.js +2 -1
- package/public/serv-entry-point.js.map +1 -1
- package/public/shared-mint.d.ts +1 -0
- package/public/shared-mint.js +10 -4
- package/public/shared-mint.js.map +1 -1
- package/usage-report/backfill-published-chips-util.d.ts +43 -0
- package/usage-report/backfill-published-chips-util.js +120 -0
- package/usage-report/backfill-published-chips-util.js.map +1 -0
- package/usage-report/backfill-published-chips.d.ts +1 -0
- package/usage-report/backfill-published-chips.js +97 -0
- package/usage-report/backfill-published-chips.js.map +1 -0
- package/usage-report/new-user-alert-util.d.ts +100 -0
- package/usage-report/new-user-alert-util.js +138 -0
- package/usage-report/new-user-alert-util.js.map +1 -0
- package/usage-report/new-user-alert.d.ts +1 -0
- package/usage-report/new-user-alert.js +227 -0
- package/usage-report/new-user-alert.js.map +1 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { Pool } from "@neondatabase/serverless";
|
|
2
|
+
import { Result, exception2Result } from "@adviser/cement";
|
|
3
|
+
import { formatError, loadDevVars } from "./usage-report-util.js";
|
|
4
|
+
import { SEED_DOC_PREFIX, buildAlertEmbed, isStaffOrQa, resolveExclusions, selectActivations, splitSignupTail, summarizeAppUsage, } from "./new-user-alert-util.js";
|
|
5
|
+
const DEFAULT_SINCE_HOURS = 48;
|
|
6
|
+
const HUBSPOT_PORTAL_ID = "47913361";
|
|
7
|
+
const CREDITS_PER_DOLLAR = 200;
|
|
8
|
+
const CLERK_PAGE_SIZE = 500;
|
|
9
|
+
function arg(name) {
|
|
10
|
+
const i = process.argv.indexOf(name);
|
|
11
|
+
return i >= 0 ? process.argv[i + 1] : undefined;
|
|
12
|
+
}
|
|
13
|
+
function flag(name) {
|
|
14
|
+
return process.argv.includes(name);
|
|
15
|
+
}
|
|
16
|
+
function asString(v) {
|
|
17
|
+
return typeof v === "string" ? v : undefined;
|
|
18
|
+
}
|
|
19
|
+
function asNumber(v) {
|
|
20
|
+
return typeof v === "number" && Number.isFinite(v) ? v : undefined;
|
|
21
|
+
}
|
|
22
|
+
async function clerkGet(key, path) {
|
|
23
|
+
const res = await fetch(`https://api.clerk.com/v1${path}`, { headers: { authorization: `Bearer ${key}` } });
|
|
24
|
+
if (!res.ok)
|
|
25
|
+
throw new Error(`clerk GET ${path.split("?")[0]} failed: ${res.status}`);
|
|
26
|
+
return res.json();
|
|
27
|
+
}
|
|
28
|
+
function readClerkUser(u) {
|
|
29
|
+
const emails = (Array.isArray(u.email_addresses) ? u.email_addresses : []);
|
|
30
|
+
const primary = emails.find((e) => e.id === u.primary_email_address_id) ?? emails[0];
|
|
31
|
+
const created = asNumber(u.created_at);
|
|
32
|
+
return {
|
|
33
|
+
email: asString(primary?.email_address),
|
|
34
|
+
name: [asString(u.first_name), asString(u.last_name)].filter((p) => p !== undefined && p !== "").join(" ") || undefined,
|
|
35
|
+
signup: created === undefined ? undefined : new Date(created).toISOString(),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
async function clerkSignupsSince(key, sinceMs) {
|
|
39
|
+
const ids = [];
|
|
40
|
+
for (let offset = 0;; offset += CLERK_PAGE_SIZE) {
|
|
41
|
+
const page = await clerkGet(key, `/users?created_at_after=${sinceMs}&limit=${CLERK_PAGE_SIZE}&offset=${offset}`);
|
|
42
|
+
const rows = (Array.isArray(page) ? page : []);
|
|
43
|
+
for (const r of rows) {
|
|
44
|
+
const id = asString(r.id);
|
|
45
|
+
if (id !== undefined)
|
|
46
|
+
ids.push(id);
|
|
47
|
+
}
|
|
48
|
+
if (rows.length < CLERK_PAGE_SIZE)
|
|
49
|
+
return ids;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function hubspotContact(token, email) {
|
|
53
|
+
const path = `/crm/v3/objects/contacts/${encodeURIComponent(email)}?idProperty=email&properties=email`;
|
|
54
|
+
const rRes = await exception2Result(() => fetch(`https://api.hubapi.com${path}`, { headers: { authorization: `Bearer ${token}` } }));
|
|
55
|
+
if (rRes.isErr())
|
|
56
|
+
return { state: "failed", reason: formatError(rRes.Err()).slice(0, 80) };
|
|
57
|
+
const res = rRes.Ok();
|
|
58
|
+
if (res.status === 404)
|
|
59
|
+
return { state: "absent" };
|
|
60
|
+
if (!res.ok)
|
|
61
|
+
return { state: "failed", reason: `HTTP ${res.status}` };
|
|
62
|
+
const rJson = await exception2Result(() => res.json());
|
|
63
|
+
if (rJson.isErr())
|
|
64
|
+
return { state: "failed", reason: "unparseable response" };
|
|
65
|
+
const id = asString(rJson.Ok().id);
|
|
66
|
+
return id === undefined
|
|
67
|
+
? { state: "failed", reason: "response carried no contact id" }
|
|
68
|
+
: { state: "found", url: `https://app.hubspot.com/contacts/${HUBSPOT_PORTAL_ID}/record/0-1/${id}` };
|
|
69
|
+
}
|
|
70
|
+
async function run() {
|
|
71
|
+
loadDevVars();
|
|
72
|
+
const sinceHours = Number(arg("--since-hours") ?? DEFAULT_SINCE_HOURS);
|
|
73
|
+
if (!Number.isFinite(sinceHours) || sinceHours <= 0) {
|
|
74
|
+
return Result.Err("usage: pnpm --dir vibes.diy/api/svc run new-user-alert [--since-hours 48] [--dry-run]");
|
|
75
|
+
}
|
|
76
|
+
const connectionString = process.env["NEON_DATABASE_URL"] ?? process.env["DATABASE_URL"];
|
|
77
|
+
if (connectionString === undefined)
|
|
78
|
+
return Result.Err("NEON_DATABASE_URL is required (prod Neon)");
|
|
79
|
+
const clerkKey = process.env["CLERK_SECRET_KEY"];
|
|
80
|
+
const hubspotToken = process.env["HUBSPOT_TOKEN"];
|
|
81
|
+
const webhookUrl = process.env["DISCORD_WEBHOOK_URL"];
|
|
82
|
+
const exclusions = resolveExclusions({
|
|
83
|
+
ALERT_EXCLUDE_DOMAINS: process.env["ALERT_EXCLUDE_DOMAINS"],
|
|
84
|
+
ALERT_EXCLUDE_USER_IDS: process.env["ALERT_EXCLUDE_USER_IDS"],
|
|
85
|
+
});
|
|
86
|
+
const dryRun = flag("--dry-run") || webhookUrl === undefined || webhookUrl === "";
|
|
87
|
+
const nowMs = Date.now();
|
|
88
|
+
const sinceMs = nowMs - sinceHours * 3600_000;
|
|
89
|
+
const sinceIso = new Date(sinceMs).toISOString();
|
|
90
|
+
const nowIso = new Date(nowMs).toISOString();
|
|
91
|
+
const pool = new Pool({ connectionString });
|
|
92
|
+
const result = await exception2Result(async () => {
|
|
93
|
+
const costExpr = `(ref#>>'{usage,given,0,cost}')::numeric`;
|
|
94
|
+
const activationRes = await pool.query(`select "userId", min(created) as first_turn,
|
|
95
|
+
count(*) filter (where created >= $1) as turns,
|
|
96
|
+
coalesce(round(sum(${costExpr}) filter (where created >= $1) * ${CREDITS_PER_DOLLAR}), 0) as credits
|
|
97
|
+
from "PromptContexts"
|
|
98
|
+
where "userId" in (select "userId" from "PromptContexts" where created >= $1)
|
|
99
|
+
group by "userId"
|
|
100
|
+
having min(created) >= $1`, [sinceIso]);
|
|
101
|
+
const activations = selectActivations(activationRes.rows.map((r) => ({
|
|
102
|
+
userId: asString(r.userId) ?? "",
|
|
103
|
+
firstTurn: asString(r.first_turn) ?? "",
|
|
104
|
+
turns: Number(r.turns ?? 0),
|
|
105
|
+
credits: Number(r.credits ?? 0),
|
|
106
|
+
})), sinceIso);
|
|
107
|
+
const userIds = activations.map((a) => a.userId);
|
|
108
|
+
const handles = new Map();
|
|
109
|
+
if (userIds.length > 0) {
|
|
110
|
+
const res = await pool.query(`select "userId", "userSlug" as handle from "UserSlugBindings" where "userId" = any($1) order by created`, [userIds]);
|
|
111
|
+
for (const r of res.rows) {
|
|
112
|
+
handles.set(r.userId, [...(handles.get(r.userId) ?? []), r.handle]);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
let appRows = [];
|
|
116
|
+
if (userIds.length > 0) {
|
|
117
|
+
const res = await pool.query(`select a."userId", a."appSlug", a."userSlug" as owner_handle,
|
|
118
|
+
bool_or(a.mode = 'production') and coalesce(max(b."unpublishedAt"), '') = '' as published
|
|
119
|
+
from "Apps" a
|
|
120
|
+
left join "AppSlugBindings" b on b."userSlug" = a."userSlug" and b."appSlug" = a."appSlug"
|
|
121
|
+
where a."userId" = any($1)
|
|
122
|
+
group by 1, 2, 3 order by 2`, [userIds]);
|
|
123
|
+
appRows = res.rows.map((r) => ({
|
|
124
|
+
userId: asString(r.userId) ?? "",
|
|
125
|
+
appSlug: asString(r.appSlug) ?? "",
|
|
126
|
+
ownerHandle: asString(r.owner_handle) ?? "",
|
|
127
|
+
published: r.published === true,
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
const usage = new Map();
|
|
131
|
+
if (appRows.length > 0) {
|
|
132
|
+
const res = await pool.query(`select d."userSlug" as owner_handle, d."appSlug" as app_slug, d."userId" as writer,
|
|
133
|
+
count(*) as docs,
|
|
134
|
+
count(*) filter (where starts_with(d."docId", $3)) as seed_docs
|
|
135
|
+
from unnest($1::text[], $2::text[]) as t(owner, slug)
|
|
136
|
+
join "AppDocuments" d on d."userSlug" = t.owner and d."appSlug" = t.slug
|
|
137
|
+
group by 1, 2, 3`, [appRows.map((a) => a.ownerHandle), appRows.map((a) => a.appSlug), SEED_DOC_PREFIX]);
|
|
138
|
+
for (const r of res.rows) {
|
|
139
|
+
const key = `${asString(r.owner_handle)}/${asString(r.app_slug)}`;
|
|
140
|
+
usage.set(key, [
|
|
141
|
+
...(usage.get(key) ?? []),
|
|
142
|
+
{ writerUserId: asString(r.writer) ?? "", docs: Number(r.docs ?? 0), seedDocs: Number(r.seed_docs ?? 0) },
|
|
143
|
+
]);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const cards = [];
|
|
147
|
+
for (const a of activations) {
|
|
148
|
+
const userHandles = handles.get(a.userId) ?? [];
|
|
149
|
+
let identity = {};
|
|
150
|
+
if (clerkKey !== undefined && clerkKey !== "") {
|
|
151
|
+
const r = await exception2Result(() => clerkGet(clerkKey, `/users/${a.userId}`));
|
|
152
|
+
if (r.isOk())
|
|
153
|
+
identity = readClerkUser(r.Ok());
|
|
154
|
+
}
|
|
155
|
+
if (isStaffOrQa({ userId: a.userId, email: identity.email, handles: userHandles }, exclusions))
|
|
156
|
+
continue;
|
|
157
|
+
const apps = appRows
|
|
158
|
+
.filter((r) => r.userId === a.userId)
|
|
159
|
+
.map((r) => {
|
|
160
|
+
const u = summarizeAppUsage(usage.get(`${r.ownerHandle}/${r.appSlug}`) ?? [], a.userId);
|
|
161
|
+
return { appSlug: r.appSlug, ownerHandle: r.ownerHandle, published: r.published, ...u };
|
|
162
|
+
});
|
|
163
|
+
let hubspot;
|
|
164
|
+
if (hubspotToken !== undefined && hubspotToken !== "" && identity.email !== undefined) {
|
|
165
|
+
hubspot = await hubspotContact(hubspotToken, identity.email);
|
|
166
|
+
}
|
|
167
|
+
cards.push({ ...a, handles: userHandles, ...identity, apps, hubspot });
|
|
168
|
+
}
|
|
169
|
+
let tail = { appUsers: 0, noOps: 0, topApps: [] };
|
|
170
|
+
if (clerkKey !== undefined && clerkKey !== "") {
|
|
171
|
+
const signedUp = await clerkSignupsSince(clerkKey, sinceMs);
|
|
172
|
+
if (signedUp.length > 0) {
|
|
173
|
+
const typedRes = await pool.query(`select distinct "userId" from "PromptContexts" where "userId" = any($1)`, [signedUp]);
|
|
174
|
+
const typed = new Set(typedRes.rows.map((r) => r.userId));
|
|
175
|
+
const zeroTurn = signedUp.filter((id) => !typed.has(id));
|
|
176
|
+
const wroteTo = new Map();
|
|
177
|
+
const ownHandles = new Map();
|
|
178
|
+
if (zeroTurn.length > 0) {
|
|
179
|
+
const wroteRes = await pool.query(`select d."userId", d."userSlug" as owner_handle, d."appSlug"
|
|
180
|
+
from "AppDocuments" d
|
|
181
|
+
where d."userId" = any($1) and not starts_with(d."docId", $2)
|
|
182
|
+
group by 1, 2, 3`, [zeroTurn, SEED_DOC_PREFIX]);
|
|
183
|
+
for (const r of wroteRes.rows) {
|
|
184
|
+
const id = asString(r.userId) ?? "";
|
|
185
|
+
wroteTo.set(id, [...(wroteTo.get(id) ?? []), `${asString(r.owner_handle)}/${asString(r.appSlug)}`]);
|
|
186
|
+
}
|
|
187
|
+
const handleRes = await pool.query(`select "userId", "userSlug" as handle from "UserSlugBindings" where "userId" = any($1)`, [zeroTurn]);
|
|
188
|
+
for (const r of handleRes.rows) {
|
|
189
|
+
ownHandles.set(r.userId, [...(ownHandles.get(r.userId) ?? []), r.handle]);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const tailRows = zeroTurn.map((userId) => ({
|
|
193
|
+
userId,
|
|
194
|
+
turns: 0,
|
|
195
|
+
wroteTo: wroteTo.get(userId) ?? [],
|
|
196
|
+
ownHandles: ownHandles.get(userId) ?? [],
|
|
197
|
+
}));
|
|
198
|
+
tail = splitSignupTail(tailRows);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const body = buildAlertEmbed({ activations: cards, tail, sinceHours, now: nowIso });
|
|
202
|
+
const appCount = cards.reduce((n, c) => n + c.apps.length, 0);
|
|
203
|
+
console.log(`[new-user-alert] window=${sinceHours}h activations=${cards.length} apps=${appCount} arrived_to_use_a_vibe=${tail.appUsers} did_nothing=${tail.noOps} posted=${body !== undefined && !dryRun}`);
|
|
204
|
+
if (body === undefined)
|
|
205
|
+
return;
|
|
206
|
+
if (dryRun) {
|
|
207
|
+
console.log(JSON.stringify(body, null, 2));
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const res = await fetch(webhookUrl, {
|
|
211
|
+
method: "POST",
|
|
212
|
+
headers: { "Content-Type": "application/json" },
|
|
213
|
+
body: JSON.stringify(body),
|
|
214
|
+
});
|
|
215
|
+
if (res.status !== 204)
|
|
216
|
+
throw new Error(`discord post returned ${res.status}`);
|
|
217
|
+
});
|
|
218
|
+
await pool.end();
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
run().then((result) => {
|
|
222
|
+
if (result.isErr()) {
|
|
223
|
+
console.error(formatError(result.Err()));
|
|
224
|
+
process.exitCode = 1;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
//# sourceMappingURL=new-user-alert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new-user-alert.js","sourceRoot":"","sources":["../../jsr/usage-report/new-user-alert.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,GAOlB,MAAM,0BAA0B,CAAC;AAElC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAC/B,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAErC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B,SAAS,GAAG,CAAC,IAAY;IACvB,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AACD,SAAS,IAAI,CAAC,IAAY;IACxB,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AACD,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/C,CAAC;AACD,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACrE,CAAC;AAQD,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,IAAY;IAC/C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,2BAA2B,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5G,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC;AAED,SAAS,aAAa,CAAC,CAA0B;IAC/C,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAA8B,CAAC;IACxG,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,wBAAwB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACvC,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;QACvC,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS;QACvH,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE;KAC5E,CAAC;AACJ,CAAC;AAGD,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,OAAe;IAC3D,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,IAAI,MAAM,GAAG,CAAC,GAAI,MAAM,IAAI,eAAe,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,2BAA2B,OAAO,UAAU,eAAe,WAAW,MAAM,EAAE,CAAC,CAAC;QACjH,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAA8B,CAAC;QAC5E,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC1B,IAAI,EAAE,KAAK,SAAS;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,eAAe;YAAE,OAAO,GAAG,CAAC;IAChD,CAAC;AACH,CAAC;AAUD,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,KAAa;IACxD,MAAM,IAAI,GAAG,4BAA4B,kBAAkB,CAAC,KAAK,CAAC,oCAAoC,CAAC;IACvG,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,CACvC,KAAK,CAAC,yBAAyB,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,EAAE,CAAC,CAC1F,CAAC;IACF,IAAI,IAAI,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IAC3F,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IACtB,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACnD,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;IACtE,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAsC,CAAC,CAAC;IAC3F,IAAI,KAAK,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;IAC9E,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IACnC,OAAO,EAAE,KAAK,SAAS;QACrB,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,gCAAgC,EAAE;QAC/D,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,oCAAoC,iBAAiB,eAAe,EAAE,EAAE,EAAE,CAAC;AACxG,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,WAAW,EAAE,CAAC;IACd,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,mBAAmB,CAAC,CAAC;IACvE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACpD,OAAO,MAAM,CAAC,GAAG,CAAC,uFAAuF,CAAC,CAAC;IAC7G,CAAC;IACD,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACzF,IAAI,gBAAgB,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACnG,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACjD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAGtD,MAAM,UAAU,GAAG,iBAAiB,CAAC;QACnC,qBAAqB,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;QAC3D,sBAAsB,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;KAC9D,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,EAAE,CAAC;IAElF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,KAAK,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAE7C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,KAAK,IAAI,EAAE;QAK/C,MAAM,QAAQ,GAAG,yCAAyC,CAAC;QAC3D,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,KAAK,CACpC;;mCAE6B,QAAQ,oCAAoC,kBAAkB;;;;iCAIhE,EAC3B,CAAC,QAAQ,CAAC,CACX,CAAC;QACF,MAAM,WAAW,GAAG,iBAAiB,CAClC,aAAa,CAAC,IAAkC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5D,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE;YAChC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE;YACvC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;YAC3B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC;SAChC,CAAC,CAAC,EACH,QAAQ,CACT,CAAC;QACF,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAGjD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;QAC5C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAC1B,yGAAyG,EACzG,CAAC,OAAO,CAAC,CACV,CAAC;YACF,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,IAA4C,EAAE,CAAC;gBACjE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAkBD,IAAI,OAAO,GAAa,EAAE,CAAC;QAC3B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAC1B;;;;;sCAK8B,EAC9B,CAAC,OAAO,CAAC,CACV,CAAC;YACF,OAAO,GAAI,GAAG,CAAC,IAAkC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC5D,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE;gBAChC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE;gBAClC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE;gBAC3C,SAAS,EAAE,CAAC,CAAC,SAAS,KAAK,IAAI;aAChC,CAAC,CAAC,CAAC;QACN,CAAC;QAKD,MAAM,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;QAChD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAC1B;;;;;2BAKmB,EACnB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC,CACpF,CAAC;YACF,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,IAAiC,EAAE,CAAC;gBACtD,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAClE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;oBACb,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;oBACzB,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE;iBAC1G,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAID,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAChD,IAAI,QAAQ,GAAkB,EAAE,CAAC;YACjC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;gBAC9C,MAAM,CAAC,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBACjF,IAAI,CAAC,CAAC,IAAI,EAAE;oBAAE,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAA6B,CAAC,CAAC;YAC5E,CAAC;YACD,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,UAAU,CAAC;gBAAE,SAAS;YAEzG,MAAM,IAAI,GAAoB,OAAO;iBAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC;iBACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACT,MAAM,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;gBACxF,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC;YAC1F,CAAC,CAAC,CAAC;YAEL,IAAI,OAAkC,CAAC;YACvC,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,EAAE,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBACtF,OAAO,GAAG,MAAM,cAAc,CAAC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC/D,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACzE,CAAC;QAOD,IAAI,IAAI,GAAe,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAC9D,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC5D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,yEAAyE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACzH,MAAM,KAAK,GAAG,IAAI,GAAG,CAAE,QAAQ,CAAC,IAA6B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACpF,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAIzD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;gBAC5C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;gBAC/C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B;;;+BAGmB,EACnB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAC5B,CAAC;oBACF,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAiC,EAAE,CAAC;wBAC3D,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;wBACpC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;oBACtG,CAAC;oBACD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,CAChC,wFAAwF,EACxF,CAAC,QAAQ,CAAC,CACX,CAAC;oBACF,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,IAA4C,EAAE,CAAC;wBACvE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;oBAC5E,CAAC;gBACH,CAAC;gBACD,MAAM,QAAQ,GAAoB,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;oBAC1D,MAAM;oBACN,KAAK,EAAE,CAAC;oBACR,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;oBAClC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;iBACzC,CAAC,CAAC,CAAC;gBACJ,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QAGpF,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CACT,2BAA2B,UAAU,iBAAiB,KAAK,CAAC,MAAM,SAAS,QAAQ,0BAA0B,IAAI,CAAC,QAAQ,gBAAgB,IAAI,CAAC,KAAK,WAAW,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,EAAE,CAC/L,CAAC;QACF,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,UAAoB,EAAE;YAC5C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;IACjB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;IACpB,IAAI,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC,CAAC"}
|