pierre-review 0.1.32 → 0.1.34

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.
@@ -10,7 +10,7 @@ const dismissSchema = {
10
10
  properties: {
11
11
  kind: {
12
12
  type: 'string',
13
- enum: ['review_request', 'thread', 'watched_repo_pr', 'claude_review'],
13
+ enum: ['review_request', 'thread', 'watched_repo_pr', 'pr_approved', 'claude_review'],
14
14
  },
15
15
  refId: { type: 'integer' },
16
16
  },
@@ -25,6 +25,7 @@ export async function meRoutes(app) {
25
25
  counts: {
26
26
  awaitingReview: myTurn.awaitingReview.length,
27
27
  yourPrsActivity: myTurn.yourPrs.length,
28
+ approvedPrs: myTurn.approvedPrs.length,
28
29
  threadsAwaiting: myTurn.threadsAwaiting.length,
29
30
  watchedRepoPrs: myTurn.watchedRepoPrs.length,
30
31
  claudeReviewsToAction: myTurn.claudeReviewsToAction.length,
@@ -1,5 +1,6 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { getAccessToken, getAccountUserId } from '../../auth/account.js';
3
+ import { ghRestGetText } from '../../github/client.js';
3
4
  import { getPrDetail, getPrFilesContext, getPrWriteContext, markAllViewed, markPrViewed, upsertLocalPrComment, upsertLocalReview, } from '../../db/queries.js';
4
5
  import { buildFileAnchors, fallbackAnchor, isFindingAnchored, } from '../../github/diff-anchor.js';
5
6
  import { addIssueComment, fetchHeadShaFor, fetchPrFilesWithPatch, postInlineComment, submitPrReview, } from '../../github/mutations.js';
@@ -33,6 +34,20 @@ const idParamSchema = {
33
34
  properties: { id: { type: 'integer' } },
34
35
  },
35
36
  };
37
+ const checkLogsSchema = {
38
+ params: {
39
+ type: 'object',
40
+ required: ['id', 'jobId'],
41
+ properties: {
42
+ id: { type: 'integer' },
43
+ jobId: { type: 'integer', minimum: 1 },
44
+ },
45
+ },
46
+ querystring: {
47
+ type: 'object',
48
+ properties: { tail: { type: 'integer', minimum: 1, maximum: 1000 } },
49
+ },
50
+ };
36
51
  const markViewedSchema = {
37
52
  ...idParamSchema,
38
53
  body: {
@@ -312,5 +327,56 @@ export async function prRoutes(app) {
312
327
  return result;
313
328
  }
314
329
  });
330
+ // Failed-check logs: the tail of a GitHub Actions job's log, fetched live (never
331
+ // stored). The jobId comes from CheckRun.jobId (parsed from the Actions detailsUrl);
332
+ // only Actions checks have one, so the frontend offers this on failed Actions rows.
333
+ // Degrades to {available:false, reason} on any GitHub error (expired logs, no
334
+ // actions:read, network) instead of 500ing.
335
+ app.get('/api/prs/:id/checks/:jobId/logs', { schema: checkLogsSchema }, async (req, reply) => {
336
+ const { id, jobId } = req.params;
337
+ const { tail } = req.query;
338
+ const accountId = accountIdOf(req);
339
+ const ctx = await getPrWriteContext(id, accountId);
340
+ if (!ctx) {
341
+ reply.status(404);
342
+ return { error: 'NotFound', message: `PR ${id} not found` };
343
+ }
344
+ const tailLines = Math.min(Math.max(tail ?? 200, 1), 1000);
345
+ const unavailable = (reason) => ({
346
+ available: false,
347
+ reason,
348
+ text: '',
349
+ totalLines: 0,
350
+ returnedLines: 0,
351
+ });
352
+ try {
353
+ const token = await getAccessToken(accountId);
354
+ const res = await ghRestGetText(token, `/repos/${ctx.owner}/${ctx.name}/actions/jobs/${jobId}/logs`);
355
+ if (!res.ok) {
356
+ const reason = res.status === 404 || res.status === 410
357
+ ? 'Logs are no longer available (expired, or the job was re-run).'
358
+ : res.status === 403
359
+ ? 'No permission to read GitHub Actions logs for this repo.'
360
+ : `Couldn't fetch logs (GitHub returned ${res.status}).`;
361
+ return unavailable(reason);
362
+ }
363
+ // A job log can be many MB — normalise line endings, drop a trailing blank,
364
+ // and tail server-side so only the last N lines reach the browser. Guard the
365
+ // empty/blank body so it reports 0 lines (not [''] → a misleading "1 of 1").
366
+ const trimmed = res.text.replace(/\r\n/g, '\n').replace(/\n+$/, '');
367
+ const lines = trimmed === '' ? [] : trimmed.split('\n');
368
+ const tailed = lines.slice(-tailLines);
369
+ const result = {
370
+ available: true,
371
+ text: tailed.join('\n'),
372
+ totalLines: lines.length,
373
+ returnedLines: tailed.length,
374
+ };
375
+ return result;
376
+ }
377
+ catch {
378
+ return unavailable("Couldn't reach GitHub to fetch the logs.");
379
+ }
380
+ });
315
381
  }
316
382
  //# sourceMappingURL=prs.js.map
@@ -16,7 +16,7 @@ const REASON_PRIORITY = [
16
16
  import { db, schema, isPg } from './client.js';
17
17
  import { runTransaction } from './client.js';
18
18
  import { config } from '../config.js';
19
- import { computeTriage } from './triage.js';
19
+ import { computeApprovalInfoByPr, computeTriage, } from './triage.js';
20
20
  import { getAccountUserId } from '../auth/account.js';
21
21
  // Bind a JS Date into a raw-`sql` epoch comparison portably: Postgres columns are
22
22
  // timestamptz (drizzle binds the Date through the codec), whereas SQLite columns
@@ -1073,8 +1073,10 @@ export async function markAllViewed(accountId, repoIds) {
1073
1073
  // doesn't own (refId is a local PR/thread id). Defense-in-depth; the read path is
1074
1074
  // already account-scoped.
1075
1075
  async function ownsDismissRef(accountId, kind, refId) {
1076
- if (kind === 'review_request' || kind === 'watched_repo_pr') {
1077
- // Both reference a PR id directly.
1076
+ if (kind === 'review_request' ||
1077
+ kind === 'watched_repo_pr' ||
1078
+ kind === 'pr_approved') {
1079
+ // All three reference a PR id directly.
1078
1080
  const rows = await db
1079
1081
  .select({ id: pullRequests.id })
1080
1082
  .from(pullRequests)
@@ -1146,6 +1148,7 @@ export async function getCompletedDismissals(accountId, daysBefore = 90) {
1146
1148
  const reviewDismissals = dismissals.filter((d) => d.kind === 'review_request');
1147
1149
  const threadDismissals = dismissals.filter((d) => d.kind === 'thread');
1148
1150
  const watchedDismissals = dismissals.filter((d) => d.kind === 'watched_repo_pr');
1151
+ const approvedDismissals = dismissals.filter((d) => d.kind === 'pr_approved');
1149
1152
  const claudeDismissals = dismissals.filter((d) => d.kind === 'claude_review');
1150
1153
  const items = [];
1151
1154
  const referencedUsers = new Set();
@@ -1223,6 +1226,42 @@ export async function getCompletedDismissals(accountId, daysBefore = 90) {
1223
1226
  });
1224
1227
  }
1225
1228
  }
1229
+ // pr_approved dismissals → their PRs (account-scoped). Same shape as a
1230
+ // review_request dismissal, a different kind tag.
1231
+ if (approvedDismissals.length > 0) {
1232
+ const prRows = await db
1233
+ .select()
1234
+ .from(pullRequests)
1235
+ .innerJoin(repos, eq(repos.id, pullRequests.repoId))
1236
+ .where(and(eq(pullRequests.accountId, accountId), inArray(pullRequests.id, approvedDismissals.map((d) => d.refId))))
1237
+ .execute();
1238
+ const byId = new Map(prRows.map((r) => [r.pull_requests.id, r]));
1239
+ for (const d of approvedDismissals) {
1240
+ const row = byId.get(d.refId);
1241
+ if (!row)
1242
+ continue;
1243
+ const { pull_requests: pr, repos: repo } = row;
1244
+ if (pr.authorId != null)
1245
+ referencedUsers.add(pr.authorId);
1246
+ const restorable = actionable.approvedPrIds.has(pr.id);
1247
+ items.push({
1248
+ kind: 'pr_approved',
1249
+ prId: pr.id,
1250
+ repoFullName: `${repo.owner}/${repo.name}`,
1251
+ number: pr.number,
1252
+ title: pr.title,
1253
+ authorId: pr.authorId,
1254
+ state: pr.state,
1255
+ openedAt: pr.openedAt.toISOString(),
1256
+ githubUrl: `https://github.com/${repo.owner}/${repo.name}/pull/${pr.number}`,
1257
+ dismissedAt: d.dismissedAt.toISOString(),
1258
+ restorable,
1259
+ ...(restorable
1260
+ ? {}
1261
+ : { reason: prClosedReason(pr.state) ?? 'No longer approved' }),
1262
+ });
1263
+ }
1264
+ }
1226
1265
  // thread dismissals → their review threads + parent PR + last reply.
1227
1266
  if (threadDismissals.length > 0) {
1228
1267
  const threadIds = threadDismissals.map((d) => d.refId);
@@ -1396,6 +1435,7 @@ async function getActionableInboxIds(accountId) {
1396
1435
  const empty = {
1397
1436
  reviewRequestPrIds: new Set(),
1398
1437
  watchedPrIds: new Set(),
1438
+ approvedPrIds: new Set(),
1399
1439
  threadIds: new Set(),
1400
1440
  claudeReviewIds: new Set(),
1401
1441
  };
@@ -1409,6 +1449,12 @@ async function getActionableInboxIds(accountId) {
1409
1449
  const open = await buildTimelinePrs(openRows, accountId);
1410
1450
  const reviewRequestPrIds = new Set(open.filter((t) => t.reviewRequestedFromMe).map((t) => t.id));
1411
1451
  const watchedPrIds = await getWatchedActionablePrIds(accountId, localUserId, open, openRows);
1452
+ // Your authored, open PRs with a standing approval (restorability source for the
1453
+ // pr_approved Done entries).
1454
+ const approvalInfo = await computeApprovalInfoByPr(open.map((t) => t.id));
1455
+ const approvedPrIds = new Set(open
1456
+ .filter((t) => t.authorId === localUserId && !t.isDraft && approvalInfo.get(t.id)?.approved)
1457
+ .map((t) => t.id));
1412
1458
  const repoNameById = new Map();
1413
1459
  for (const r of await listRepos(accountId))
1414
1460
  repoNameById.set(r.id, r.fullName);
@@ -1416,13 +1462,14 @@ async function getActionableInboxIds(accountId) {
1416
1462
  const claudeReviewIds = config.claudeReviewEnabled
1417
1463
  ? new Set((await getUnactionedClaudeReviews(accountId)).map((c) => c.reviewId))
1418
1464
  : new Set();
1419
- return { reviewRequestPrIds, watchedPrIds, threadIds, claudeReviewIds };
1465
+ return { reviewRequestPrIds, watchedPrIds, approvedPrIds, threadIds, claudeReviewIds };
1420
1466
  }
1421
1467
  export async function getMyTurn(accountId) {
1422
1468
  const localUserId = await getAccountUserId(accountId);
1423
1469
  const empty = {
1424
1470
  awaitingReview: [],
1425
1471
  yourPrs: [],
1472
+ approvedPrs: [],
1426
1473
  threadsAwaiting: [],
1427
1474
  watchedRepoPrs: [],
1428
1475
  claudeReviewsToAction: [],
@@ -1449,6 +1496,9 @@ export async function getMyTurn(accountId) {
1449
1496
  .execute();
1450
1497
  const reviewDismissedAt = new Map();
1451
1498
  const threadDismissedAt = new Map();
1499
+ // Dismissed "your PR was approved" entries. Keyed by PR id; honoured until a NEWER
1500
+ // approval lands (compared against the latest approving review's timestamp below).
1501
+ const approvedDismissedAt = new Map();
1452
1502
  // Dismissed Claude-review run ids. Keyed by run id (not PR id): a fresh run gets
1453
1503
  // a new id, so it naturally re-appears without a timestamp comparison.
1454
1504
  const claudeDismissedIds = new Set();
@@ -1460,6 +1510,8 @@ export async function getMyTurn(accountId) {
1460
1510
  reviewDismissedAt.set(d.refId, d.dismissedAt);
1461
1511
  else if (d.kind === 'thread')
1462
1512
  threadDismissedAt.set(d.refId, d.dismissedAt);
1513
+ else if (d.kind === 'pr_approved')
1514
+ approvedDismissedAt.set(d.refId, d.dismissedAt);
1463
1515
  else if (d.kind === 'claude_review')
1464
1516
  claudeDismissedIds.add(d.refId);
1465
1517
  else if (d.kind === 'watched_repo_pr')
@@ -1496,9 +1548,38 @@ export async function getMyTurn(accountId) {
1496
1548
  const others = await countOtherReviewers(t.id, localUserId);
1497
1549
  return { ...toMyTurnPr(t), alsoRequested: others };
1498
1550
  }));
1499
- // 2. Your PRs with new activity since you last looked.
1551
+ // 2. Your authored, open PRs that have a standing approval (likely ready to merge).
1552
+ // An approving review lands them here; a "Done" dismissal hides them until a
1553
+ // NEWER approval arrives (compared against the latest approving review's
1554
+ // timestamp — not the PR's updatedAt, which any commit would bump and re-nag).
1555
+ // They leave automatically once the PR is merged/closed (drops out of `open`).
1556
+ const approvalInfo = await computeApprovalInfoByPr(open.map((t) => t.id));
1557
+ const approvedPrs = open
1558
+ .filter((t) => {
1559
+ // Drafts can't merge even when approved — don't claim "ready to merge".
1560
+ if (t.authorId !== localUserId || t.isDraft)
1561
+ return false;
1562
+ const info = approvalInfo.get(t.id);
1563
+ if (!info?.approved)
1564
+ return false;
1565
+ const dismissedAt = approvedDismissedAt.get(t.id);
1566
+ if (!dismissedAt)
1567
+ return true;
1568
+ const latest = info.latestApprovalAt?.getTime() ?? 0;
1569
+ return latest > dismissedAt.getTime();
1570
+ })
1571
+ .map((t) => ({
1572
+ ...toMyTurnPr(t),
1573
+ approvals: approvalInfo.get(t.id)?.approvals ?? 0,
1574
+ mergeable: t.mergeable,
1575
+ mergeStateStatus: t.mergeStateStatus,
1576
+ }));
1577
+ const approvedShownIds = new Set(approvedPrs.map((i) => i.prId));
1578
+ // 3. Your PRs with new activity since you last looked — excluding ones already shown
1579
+ // under "approved" (the stronger, more actionable signal wins).
1500
1580
  const yourPrs = open
1501
1581
  .filter((t) => t.authorId === localUserId &&
1582
+ !approvedShownIds.has(t.id) &&
1502
1583
  t.newSinceLastViewed != null &&
1503
1584
  (t.newSinceLastViewed.comments > 0 ||
1504
1585
  t.newSinceLastViewed.reviews > 0 ||
@@ -1517,6 +1598,7 @@ export async function getMyTurn(accountId) {
1517
1598
  const inOtherSections = new Set([
1518
1599
  ...awaitingReview.map((i) => i.prId),
1519
1600
  ...yourPrs.map((i) => i.prId),
1601
+ ...approvedPrs.map((i) => i.prId),
1520
1602
  ]);
1521
1603
  const watchedRepoPrs = open
1522
1604
  .filter((t) => watchedEligible.has(t.id) &&
@@ -1549,6 +1631,7 @@ export async function getMyTurn(accountId) {
1549
1631
  return {
1550
1632
  awaitingReview,
1551
1633
  yourPrs,
1634
+ approvedPrs,
1552
1635
  threadsAwaiting,
1553
1636
  watchedRepoPrs,
1554
1637
  claudeReviewsToAction,
@@ -167,7 +167,7 @@ export const myTurnDismissals = pgTable('my_turn_dismissals', {
167
167
  .notNull()
168
168
  .references(() => accounts.id),
169
169
  kind: text('kind', {
170
- enum: ['review_request', 'thread', 'watched_repo_pr', 'claude_review'],
170
+ enum: ['review_request', 'thread', 'watched_repo_pr', 'pr_approved', 'claude_review'],
171
171
  }).notNull(),
172
172
  refId: integer('ref_id').notNull(),
173
173
  dismissedAt: timestamp('dismissed_at', {
@@ -193,7 +193,7 @@ export const myTurnDismissals = sqliteTable('my_turn_dismissals', {
193
193
  .notNull()
194
194
  .references(() => accounts.id),
195
195
  kind: text('kind', {
196
- enum: ['review_request', 'thread', 'watched_repo_pr', 'claude_review'],
196
+ enum: ['review_request', 'thread', 'watched_repo_pr', 'pr_approved', 'claude_review'],
197
197
  }).notNull(),
198
198
  refId: integer('ref_id').notNull(),
199
199
  dismissedAt: integer('dismissed_at', { mode: 'timestamp' }).notNull(),
package/dist/db/triage.js CHANGED
@@ -5,11 +5,17 @@ const { reviewRequests, prViews, events, reviews } = schema;
5
5
  function emptyNew() {
6
6
  return { commits: 0, comments: 0, reviews: 0 };
7
7
  }
8
- /** Per-author latest review state → is the PR approved with no blocking review? */
9
- async function computeApprovedByPr(prIds) {
10
- const approved = new Set();
8
+ /**
9
+ * Per-author latest review state → per-PR approval standing. A reviewer's standing
10
+ * decision is their latest non-"commented" review (approved / changes_requested);
11
+ * a PR is "approved" when at least one reviewer's standing decision is approved and
12
+ * none is changes_requested. Used both for the `approved_ready` reason tag and the
13
+ * "your PR was approved" My Turn section.
14
+ */
15
+ export async function computeApprovalInfoByPr(prIds) {
16
+ const out = new Map();
11
17
  if (prIds.length === 0)
12
- return approved;
18
+ return out;
13
19
  const rows = await db
14
20
  .select({
15
21
  prId: reviews.prId,
@@ -26,25 +32,41 @@ async function computeApprovedByPr(prIds) {
26
32
  if (r.state !== 'approved' && r.state !== 'changes_requested')
27
33
  continue;
28
34
  const key = `${r.prId}:${r.authorId}`;
29
- const at = r.submittedAt.getTime();
30
35
  const prev = latest.get(key);
31
- if (!prev || at > prev.at)
32
- latest.set(key, { state: r.state, at });
36
+ if (!prev || r.submittedAt.getTime() > prev.at.getTime()) {
37
+ latest.set(key, { prId: r.prId, state: r.state, at: r.submittedAt });
38
+ }
33
39
  }
34
40
  const byPr = new Map();
35
- for (const [key, v] of latest) {
36
- const prId = Number.parseInt(key.split(':')[0], 10);
37
- const entry = byPr.get(prId) ?? { approvals: 0, blocks: 0 };
38
- if (v.state === 'approved')
41
+ for (const v of latest.values()) {
42
+ const entry = byPr.get(v.prId) ?? { approvals: 0, blocks: 0, latestApprovalAt: null };
43
+ if (v.state === 'approved') {
39
44
  entry.approvals += 1;
40
- else
45
+ if (!entry.latestApprovalAt || v.at.getTime() > entry.latestApprovalAt.getTime()) {
46
+ entry.latestApprovalAt = v.at;
47
+ }
48
+ }
49
+ else {
41
50
  entry.blocks += 1;
42
- byPr.set(prId, entry);
51
+ }
52
+ byPr.set(v.prId, entry);
43
53
  }
44
54
  for (const [prId, e] of byPr) {
45
- if (e.approvals > 0 && e.blocks === 0)
46
- approved.add(prId);
55
+ out.set(prId, {
56
+ approved: e.approvals > 0 && e.blocks === 0,
57
+ approvals: e.approvals,
58
+ latestApprovalAt: e.latestApprovalAt,
59
+ });
47
60
  }
61
+ return out;
62
+ }
63
+ /** Per-author latest review state → is the PR approved with no blocking review? */
64
+ async function computeApprovedByPr(prIds) {
65
+ const info = await computeApprovalInfoByPr(prIds);
66
+ const approved = new Set();
67
+ for (const [prId, e] of info)
68
+ if (e.approved)
69
+ approved.add(prId);
48
70
  return approved;
49
71
  }
50
72
  /**
@@ -29,6 +29,23 @@ async function ghRest(token, method, path, body) {
29
29
  export function ghRestGetFor(token, path) {
30
30
  return ghRest(token, 'GET', path);
31
31
  }
32
+ // REST GET returning the raw response TEXT (not JSON), for endpoints with a plain-text
33
+ // body — notably the Actions job-logs endpoint, which 302-redirects to a signed
34
+ // download URL. fetch follows the redirect automatically AND strips the Authorization
35
+ // header on the cross-origin hop, so our token is never sent to the signed URL. Does
36
+ // NOT throw on a non-2xx status — returns it so the caller can degrade gracefully
37
+ // (logs expire after ~90 days / on a re-run → 404/410; missing actions:read → 403).
38
+ export async function ghRestGetText(token, path) {
39
+ const res = await fetch(`https://api.github.com${path}`, {
40
+ method: 'GET',
41
+ headers: {
42
+ authorization: `token ${token}`,
43
+ 'x-github-api-version': '2022-11-28',
44
+ },
45
+ });
46
+ const text = await res.text().catch(() => '');
47
+ return { status: res.status, ok: res.ok, text };
48
+ }
32
49
  // REST POST (submitting a PR review — inline line comments require the REST
33
50
  // reviews endpoint) for a specific account's token.
34
51
  export function ghRestPostFor(token, path, body) {
@@ -185,13 +185,30 @@ function checkContextState(c) {
185
185
  return 'unknown';
186
186
  }
187
187
  }
188
+ // A GitHub Actions check's detailsUrl is .../actions/runs/<runId>/job/<jobId> — parse
189
+ // the two ids so the frontend can fetch that job's logs on demand. Third-party CI
190
+ // (StatusContext / external CheckRuns) has a detailsUrl pointing elsewhere; no match →
191
+ // null, and the UI keeps it as a plain external link (logs aren't retrievable).
192
+ const ACTIONS_JOB_RE = /\/actions\/runs\/(\d+)\/job\/(\d+)/;
193
+ function parseActionsIds(url) {
194
+ const m = url ? ACTIONS_JOB_RE.exec(url) : null;
195
+ if (!m)
196
+ return { runId: null, jobId: null };
197
+ return { runId: Number(m[1]), jobId: Number(m[2]) };
198
+ }
188
199
  export function checkRunsFrom(head) {
189
200
  const nodes = head?.statusCheckRollup?.contexts?.nodes ?? [];
190
- return nodes.map((c) => ({
191
- name: c.__typename === 'CheckRun' ? c.name : c.context,
192
- state: checkContextState(c),
193
- url: c.__typename === 'CheckRun' ? c.detailsUrl : c.targetUrl,
194
- }));
201
+ return nodes.map((c) => {
202
+ const url = c.__typename === 'CheckRun' ? c.detailsUrl : c.targetUrl;
203
+ const { runId, jobId } = c.__typename === 'CheckRun' ? parseActionsIds(url) : { runId: null, jobId: null };
204
+ return {
205
+ name: c.__typename === 'CheckRun' ? c.name : c.context,
206
+ state: checkContextState(c),
207
+ url,
208
+ runId,
209
+ jobId,
210
+ };
211
+ });
195
212
  }
196
213
  const REVIEW_STATES = new Set([
197
214
  'approved',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pierre-review",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "description": "Dashboard for tracking your team's GitHub PR activity across repos — local (SQLite + gh) or self-hosted multi-tenant cloud (Postgres + GitHub App).",
5
5
  "type": "module",
6
6
  "author": "Alex Wakeman",
@@ -0,0 +1,10 @@
1
+ .vis-time-axis{position:relative;overflow:hidden}.vis-time-axis.vis-foreground{top:0;left:0;width:100%}.vis-time-axis.vis-background{position:absolute;top:0;left:0;width:100%;height:100%}.vis-time-axis .vis-text{position:absolute;color:#4d4d4d;padding:3px;overflow:hidden;box-sizing:border-box;white-space:nowrap}.vis-time-axis .vis-text.vis-measure{position:absolute;padding-left:0;padding-right:0;margin-left:0;margin-right:0;visibility:hidden}.vis-time-axis .vis-grid.vis-vertical{position:absolute;border-left:1px solid}.vis-time-axis .vis-grid.vis-vertical-rtl{position:absolute;border-right:1px solid}.vis-time-axis .vis-grid.vis-minor{border-color:#e5e5e5}.vis-time-axis .vis-grid.vis-major{border-color:#bfbfbf}.vis .overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10}.vis-active{box-shadow:0 0 10px #86d5f8}.vis-custom-time{background-color:#6e94ff;width:2px;cursor:move;z-index:1}.vis-custom-time>.vis-custom-time-marker{background-color:inherit;color:#fff;font-size:12px;white-space:nowrap;padding:3px 5px;top:0;cursor:initial;z-index:inherit}.vis-current-time{background-color:#ff7f6e;width:2px;z-index:1;pointer-events:none}.vis-rolling-mode-btn{height:40px;width:40px;position:absolute;top:7px;right:20px;border-radius:50%;font-size:28px;cursor:pointer;opacity:.8;color:#fff;font-weight:700;text-align:center;background:#3876c2}.vis-rolling-mode-btn:before{content:"⛶"}.vis-rolling-mode-btn:hover{opacity:1}.vis-panel{position:absolute;padding:0;margin:0;box-sizing:border-box}.vis-panel.vis-center,.vis-panel.vis-left,.vis-panel.vis-right,.vis-panel.vis-top,.vis-panel.vis-bottom{border:1px #bfbfbf}.vis-panel.vis-center,.vis-panel.vis-left,.vis-panel.vis-right{border-top-style:solid;border-bottom-style:solid;overflow:hidden}.vis-left.vis-panel.vis-vertical-scroll,.vis-right.vis-panel.vis-vertical-scroll{height:100%;overflow-x:hidden;overflow-y:scroll}.vis-left.vis-panel.vis-vertical-scroll{direction:rtl}.vis-left.vis-panel.vis-vertical-scroll .vis-content,.vis-right.vis-panel.vis-vertical-scroll{direction:ltr}.vis-right.vis-panel.vis-vertical-scroll .vis-content{direction:rtl}.vis-panel.vis-center,.vis-panel.vis-top,.vis-panel.vis-bottom{border-left-style:solid;border-right-style:solid}.vis-background{overflow:hidden}.vis-panel>.vis-content{position:relative}.vis-panel .vis-shadow{position:absolute;width:100%;height:1px;box-shadow:0 0 10px #000c}.vis-panel .vis-shadow.vis-top{top:-1px;left:0}.vis-panel .vis-shadow.vis-bottom{bottom:-1px;left:0}.vis-graph-group0{fill:#4f81bd;fill-opacity:0;stroke-width:2px;stroke:#4f81bd}.vis-graph-group1{fill:#f79646;fill-opacity:0;stroke-width:2px;stroke:#f79646}.vis-graph-group2{fill:#8c51cf;fill-opacity:0;stroke-width:2px;stroke:#8c51cf}.vis-graph-group3{fill:#75c841;fill-opacity:0;stroke-width:2px;stroke:#75c841}.vis-graph-group4{fill:#ff0100;fill-opacity:0;stroke-width:2px;stroke:#ff0100}.vis-graph-group5{fill:#37d8e6;fill-opacity:0;stroke-width:2px;stroke:#37d8e6}.vis-graph-group6{fill:#042662;fill-opacity:0;stroke-width:2px;stroke:#042662}.vis-graph-group7{fill:#00ff26;fill-opacity:0;stroke-width:2px;stroke:#00ff26}.vis-graph-group8{fill:#f0f;fill-opacity:0;stroke-width:2px;stroke:#f0f}.vis-graph-group9{fill:#8f3938;fill-opacity:0;stroke-width:2px;stroke:#8f3938}.vis-timeline .vis-fill{fill-opacity:.1;stroke:none}.vis-timeline .vis-bar{fill-opacity:.5;stroke-width:1px}.vis-timeline .vis-point{stroke-width:2px;fill-opacity:1}.vis-timeline .vis-legend-background{stroke-width:1px;fill-opacity:.9;fill:#fff;stroke:#c2c2c2}.vis-timeline .vis-outline{stroke-width:1px;fill-opacity:1;fill:#fff;stroke:#e5e5e5}.vis-timeline .vis-icon-fill{fill-opacity:.3;stroke:none}.vis-timeline{position:relative;border:1px solid #bfbfbf;overflow:hidden;padding:0;margin:0;box-sizing:border-box}.vis-loading-screen{width:100%;height:100%;position:absolute;top:0;left:0}.vis [class*=span]{min-height:0;width:auto}.vis-item{position:absolute;color:#1a1a1a;border-color:#97b0f8;border-width:1px;background-color:#d5ddf6;display:inline-block;z-index:1}.vis-item.vis-selected{border-color:#ffc200;background-color:#fff785;z-index:2}.vis-editable.vis-selected{cursor:move}.vis-item.vis-point.vis-selected{background-color:#fff785}.vis-item.vis-box{text-align:center;border-style:solid;border-radius:2px}.vis-item.vis-point{background:none}.vis-item.vis-dot{position:absolute;padding:0;border-width:4px;border-style:solid;border-radius:4px}.vis-item.vis-range{border-style:solid;border-radius:2px;box-sizing:border-box}.vis-item.vis-background{border:none;background-color:#d5ddf666;box-sizing:border-box;padding:0;margin:0}.vis-item .vis-item-overflow{position:relative;width:100%;height:100%;padding:0;margin:0;overflow:hidden}.vis-item-visible-frame{white-space:nowrap}.vis-item.vis-range .vis-item-content{position:relative;display:inline-block}.vis-item.vis-background .vis-item-content{position:absolute;display:inline-block}.vis-item.vis-line{padding:0;position:absolute;width:0;border-left-width:1px;border-left-style:solid}.vis-item .vis-item-content{white-space:nowrap;box-sizing:border-box;padding:5px}.vis-item .vis-onUpdateTime-tooltip{position:absolute;background:#4f81bd;color:#fff;width:200px;text-align:center;white-space:nowrap;padding:5px;border-radius:1px;transition:.4s;-o-transition:.4s;-moz-transition:.4s;-webkit-transition:.4s}.vis-item .vis-delete,.vis-item .vis-delete-rtl{position:absolute;top:0;width:24px;height:24px;box-sizing:border-box;padding:0 5px;cursor:pointer;transition:background .2s linear}.vis-item .vis-delete{right:-24px}.vis-item .vis-delete-rtl{left:-24px}.vis-item .vis-delete:after,.vis-item .vis-delete-rtl:after{content:"×";color:red;font-family:arial,sans-serif;font-size:22px;font-weight:700;transition:color .2s linear}.vis-item .vis-delete:hover,.vis-item .vis-delete-rtl:hover{background:red}.vis-item .vis-delete:hover:after,.vis-item .vis-delete-rtl:hover:after{color:#fff}.vis-item .vis-drag-center{position:absolute;width:100%;height:100%;top:0;left:0;cursor:move}.vis-item.vis-range .vis-drag-left{position:absolute;width:24px;max-width:20%;min-width:2px;height:100%;top:0;left:-4px;cursor:w-resize}.vis-item.vis-range .vis-drag-right{position:absolute;width:24px;max-width:20%;min-width:2px;height:100%;top:0;right:-4px;cursor:e-resize}.vis-range.vis-item.vis-readonly .vis-drag-left,.vis-range.vis-item.vis-readonly .vis-drag-right{cursor:auto}.vis-item.vis-cluster{vertical-align:center;text-align:center;border-style:solid;border-radius:2px}.vis-item.vis-cluster-line{padding:0;position:absolute;width:0;border-left-width:1px;border-left-style:solid}.vis-item.vis-cluster-dot{position:absolute;padding:0;border-width:4px;border-style:solid;border-radius:4px}div.vis-tooltip{position:absolute;visibility:hidden;padding:5px;white-space:nowrap;font-family:verdana;font-size:14px;color:#000;background-color:#f5f4ed;border-radius:3px;border:1px solid #808074;box-shadow:3px 3px 10px #0003;pointer-events:none;z-index:5}.vis-itemset{position:relative;padding:0;margin:0;box-sizing:border-box}.vis-itemset .vis-background,.vis-itemset .vis-foreground{position:absolute;width:100%;height:100%;overflow:visible}.vis-axis{position:absolute;width:100%;height:0;left:0;z-index:1}.vis-foreground .vis-group{position:relative;box-sizing:border-box;border-bottom:1px solid #bfbfbf}.vis-foreground .vis-group:last-child{border-bottom:none}.vis-nesting-group{cursor:pointer}.vis-label.vis-nested-group.vis-group-level-unknown-but-gte1{background:#f5f5f5}.vis-label.vis-nested-group.vis-group-level-0{background-color:#fff}.vis-ltr .vis-label.vis-nested-group.vis-group-level-0 .vis-inner{padding-left:0}.vis-rtl .vis-label.vis-nested-group.vis-group-level-0 .vis-inner{padding-right:0}.vis-label.vis-nested-group.vis-group-level-1{background-color:#0000000d}.vis-ltr .vis-label.vis-nested-group.vis-group-level-1 .vis-inner{padding-left:15px}.vis-rtl .vis-label.vis-nested-group.vis-group-level-1 .vis-inner{padding-right:15px}.vis-label.vis-nested-group.vis-group-level-2{background-color:#0000001a}.vis-ltr .vis-label.vis-nested-group.vis-group-level-2 .vis-inner{padding-left:30px}.vis-rtl .vis-label.vis-nested-group.vis-group-level-2 .vis-inner{padding-right:30px}.vis-label.vis-nested-group.vis-group-level-3{background-color:#00000026}.vis-ltr .vis-label.vis-nested-group.vis-group-level-3 .vis-inner{padding-left:45px}.vis-rtl .vis-label.vis-nested-group.vis-group-level-3 .vis-inner{padding-right:45px}.vis-label.vis-nested-group.vis-group-level-4{background-color:#0003}.vis-ltr .vis-label.vis-nested-group.vis-group-level-4 .vis-inner{padding-left:60px}.vis-rtl .vis-label.vis-nested-group.vis-group-level-4 .vis-inner{padding-right:60px}.vis-label.vis-nested-group.vis-group-level-5{background-color:#00000040}.vis-ltr .vis-label.vis-nested-group.vis-group-level-5 .vis-inner{padding-left:75px}.vis-rtl .vis-label.vis-nested-group.vis-group-level-5 .vis-inner{padding-right:75px}.vis-label.vis-nested-group.vis-group-level-6{background-color:#0000004d}.vis-ltr .vis-label.vis-nested-group.vis-group-level-6 .vis-inner{padding-left:90px}.vis-rtl .vis-label.vis-nested-group.vis-group-level-6 .vis-inner{padding-right:90px}.vis-label.vis-nested-group.vis-group-level-7{background-color:#00000059}.vis-ltr .vis-label.vis-nested-group.vis-group-level-7 .vis-inner{padding-left:105px}.vis-rtl .vis-label.vis-nested-group.vis-group-level-7 .vis-inner{padding-right:105px}.vis-label.vis-nested-group.vis-group-level-8{background-color:#0006}.vis-ltr .vis-label.vis-nested-group.vis-group-level-8 .vis-inner{padding-left:120px}.vis-rtl .vis-label.vis-nested-group.vis-group-level-8 .vis-inner{padding-right:120px}.vis-label.vis-nested-group.vis-group-level-9{background-color:#00000073}.vis-ltr .vis-label.vis-nested-group.vis-group-level-9 .vis-inner{padding-left:135px}.vis-rtl .vis-label.vis-nested-group.vis-group-level-9 .vis-inner{padding-right:135px}.vis-label.vis-nested-group{background-color:#00000080}.vis-ltr .vis-label.vis-nested-group .vis-inner{padding-left:150px}.vis-rtl .vis-label.vis-nested-group .vis-inner{padding-right:150px}.vis-group-level-unknown-but-gte1{border:1px solid red}.vis-label.vis-nesting-group:before{display:inline-block;width:15px}.vis-label.vis-nesting-group.expanded:before{content:"▼"}.vis-label.vis-nesting-group.collapsed:before{content:"▶"}.vis-rtl .vis-label.vis-nesting-group.collapsed:before{content:"◀"}.vis-ltr .vis-label:not(.vis-nesting-group):not(.vis-group-level-0){padding-left:15px}.vis-rtl .vis-label:not(.vis-nesting-group):not(.vis-group-level-0){padding-right:15px}.vis-overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10}.vis-labelset{position:relative;overflow:hidden;box-sizing:border-box}.vis-labelset .vis-label{position:relative;left:0;top:0;width:100%;color:#4d4d4d;box-sizing:border-box;border-bottom:1px solid #bfbfbf}.vis-labelset .vis-label.draggable{cursor:pointer}.vis-group-is-dragging{background:#0000001a}.vis-labelset .vis-label:last-child{border-bottom:none}.vis-labelset .vis-label .vis-inner{display:inline-block;padding:5px}.vis-labelset .vis-label .vis-inner.vis-hidden{padding:0}div.vis-configuration{position:relative;display:block;float:left;font-size:12px}div.vis-configuration-wrapper{display:block;width:700px}div.vis-configuration-wrapper:after{clear:both;content:"";display:block}div.vis-configuration.vis-config-option-container{display:block;width:495px;background-color:#fff;border:2px solid #f7f8fa;border-radius:4px;margin-top:20px;left:10px;padding-left:5px}div.vis-configuration.vis-config-button{display:block;width:495px;height:25px;vertical-align:middle;line-height:25px;background-color:#f7f8fa;border:2px solid #ceced0;border-radius:4px;margin-top:20px;left:10px;padding-left:5px;cursor:pointer;margin-bottom:30px}div.vis-configuration.vis-config-button.hover{background-color:#4588e6;border:2px solid #214373;color:#fff}div.vis-configuration.vis-config-item{display:block;float:left;width:495px;height:25px;vertical-align:middle;line-height:25px}div.vis-configuration.vis-config-item.vis-config-s2{left:10px;background-color:#f7f8fa;padding-left:5px;border-radius:3px}div.vis-configuration.vis-config-item.vis-config-s3{left:20px;background-color:#e4e9f0;padding-left:5px;border-radius:3px}div.vis-configuration.vis-config-item.vis-config-s4{left:30px;background-color:#cfd8e6;padding-left:5px;border-radius:3px}div.vis-configuration.vis-config-header{font-size:18px;font-weight:700}div.vis-configuration.vis-config-label{width:120px;height:25px;line-height:25px}div.vis-configuration.vis-config-label.vis-config-s3{width:110px}div.vis-configuration.vis-config-label.vis-config-s4{width:100px}div.vis-configuration.vis-config-colorBlock{top:1px;width:30px;height:19px;border:1px solid #444444;border-radius:2px;padding:0;margin:0;cursor:pointer}input.vis-configuration.vis-config-checkbox{left:-5px}input.vis-configuration.vis-config-rangeinput{position:relative;top:-5px;width:60px;padding:1px;margin:0;pointer-events:none}input.vis-configuration.vis-config-range{-webkit-appearance:none;border:0px solid white;background-color:#0000;width:300px;height:20px}input.vis-configuration.vis-config-range::-webkit-slider-runnable-track{width:300px;height:5px;background:#dedede;background:linear-gradient(to bottom,#dedede,#c8c8c8 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#dedede",endColorstr="#c8c8c8",GradientType=0);border:1px solid #999999;box-shadow:#aaa 0 0 3px;border-radius:3px}input.vis-configuration.vis-config-range::-webkit-slider-thumb{-webkit-appearance:none;border:1px solid #14334b;height:17px;width:17px;border-radius:50%;background:#3876c2;background:linear-gradient(to bottom,#3876c2,#385380);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#3876c2",endColorstr="#385380",GradientType=0);box-shadow:#111927 0 0 1px;margin-top:-7px}input.vis-configuration.vis-config-range:focus{outline:none}input.vis-configuration.vis-config-range:focus::-webkit-slider-runnable-track{background:#9d9d9d;background:linear-gradient(to bottom,#9d9d9d,#c8c8c8 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#9d9d9d",endColorstr="#c8c8c8",GradientType=0)}input.vis-configuration.vis-config-range::-moz-range-track{width:300px;height:10px;background:#dedede;background:linear-gradient(to bottom,#dedede,#c8c8c8 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#dedede",endColorstr="#c8c8c8",GradientType=0);border:1px solid #999999;box-shadow:#aaa 0 0 3px;border-radius:3px}input.vis-configuration.vis-config-range::-moz-range-thumb{border:none;height:16px;width:16px;border-radius:50%;background:#385380}input.vis-configuration.vis-config-range:-moz-focusring{outline:1px solid white;outline-offset:-1px}input.vis-configuration.vis-config-range::-ms-track{width:300px;height:5px;background:transparent;border-color:transparent;border-width:6px 0;color:transparent}input.vis-configuration.vis-config-range::-ms-fill-lower{background:#777;border-radius:10px}input.vis-configuration.vis-config-range::-ms-fill-upper{background:#ddd;border-radius:10px}input.vis-configuration.vis-config-range::-ms-thumb{border:none;height:16px;width:16px;border-radius:50%;background:#385380}input.vis-configuration.vis-config-range:focus::-ms-fill-lower{background:#888}input.vis-configuration.vis-config-range:focus::-ms-fill-upper{background:#ccc}.vis-configuration-popup{position:absolute;background:#394c59d9;border:2px solid #f2faff;line-height:30px;height:30px;width:150px;text-align:center;color:#fff;font-size:14px;border-radius:4px;transition:opacity .3s ease-in-out}.vis-configuration-popup:after,.vis-configuration-popup:before{left:100%;top:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}.vis-configuration-popup:after{border-color:#88b7d500;border-left-color:#394c59d9;border-width:8px;margin-top:-8px}.vis-configuration-popup:before{border-color:#c2e1f500;border-left-color:#f2faff;border-width:12px;margin-top:-12px}.vis-panel.vis-background.vis-horizontal .vis-grid.vis-horizontal{position:absolute;width:100%;height:0;border-bottom:1px solid}.vis-panel.vis-background.vis-horizontal .vis-grid.vis-minor{border-color:#e5e5e5}.vis-panel.vis-background.vis-horizontal .vis-grid.vis-major{border-color:#bfbfbf}.vis-data-axis .vis-y-axis.vis-major{width:100%;position:absolute;color:#4d4d4d;white-space:nowrap}.vis-data-axis .vis-y-axis.vis-major.vis-measure{padding:0;margin:0;border:0;visibility:hidden;width:auto}.vis-data-axis .vis-y-axis.vis-minor{position:absolute;width:100%;color:#bebebe;white-space:nowrap}.vis-data-axis .vis-y-axis.vis-minor.vis-measure{padding:0;margin:0;border:0;visibility:hidden;width:auto}.vis-data-axis .vis-y-axis.vis-title{position:absolute;color:#4d4d4d;white-space:nowrap;bottom:20px;text-align:center}.vis-data-axis .vis-y-axis.vis-title.vis-measure{padding:0;margin:0;visibility:hidden;width:auto}.vis-data-axis .vis-y-axis.vis-title.vis-left{bottom:0;transform-origin:left bottom;transform:rotate(-90deg)}.vis-data-axis .vis-y-axis.vis-title.vis-right{bottom:0;transform-origin:right bottom;transform:rotate(90deg)}.vis-legend{background-color:#f7fcffa6;padding:5px;border:1px solid #b3b3b3;box-shadow:2px 2px 10px #9a9a9a8c}.vis-legend-text{white-space:nowrap;display:inline-block}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
2
+ Theme: GitHub Dark
3
+ Description: Dark theme as seen on github.com
4
+ Author: github.com
5
+ Maintainer: @Hirse
6
+ Updated: 2021-05-15
7
+
8
+ Outdated base version: https://github.com/primer/github-syntax-dark
9
+ Current colors taken from GitHub's CSS
10
+ */.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#79c0ff}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-comment,.hljs-code,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.left-0{left:0}.right-0{right:0}.right-1\.5{right:.375rem}.right-2{right:.5rem}.right-4{right:1rem}.top-0{top:0}.top-1\.5{top:.375rem}.top-full{top:100%}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.z-\[60\]{z-index:60}.my-1{margin-top:.25rem;margin-bottom:.25rem}.-mb-px{margin-bottom:-1px}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.ml-1{margin-left:.25rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-7{margin-top:1.75rem}.mt-auto{margin-top:auto}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.\!hidden{display:none!important}.hidden{display:none}.h-0{height:0px}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-\[120px\]{height:120px}.h-full{height:100%}.max-h-32{max-height:8rem}.max-h-60{max-height:15rem}.max-h-64{max-height:16rem}.max-h-72{max-height:18rem}.max-h-80{max-height:20rem}.max-h-96{max-height:24rem}.max-h-\[40rem\]{max-height:40rem}.max-h-\[80vh\]{max-height:80vh}.max-h-\[82vh\]{max-height:82vh}.max-h-\[88vh\]{max-height:88vh}.min-h-0{min-height:0px}.min-h-screen{min-height:100vh}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-28{width:7rem}.w-3{width:.75rem}.w-4{width:1rem}.w-44{width:11rem}.w-5{width:1.25rem}.w-52{width:13rem}.w-56{width:14rem}.w-60{width:15rem}.w-64{width:16rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-96{width:24rem}.w-\[28rem\]{width:28rem}.w-\[34rem\]{width:34rem}.w-\[44rem\]{width:44rem}.w-\[60rem\]{width:60rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-\[12rem\]{max-width:12rem}.max-w-\[14rem\]{max-width:14rem}.max-w-\[8rem\]{max-width:8rem}.max-w-\[90vw\]{max-width:90vw}.max-w-\[92vw\]{max-width:92vw}.max-w-\[94vw\]{max-width:94vw}.max-w-\[96vw\]{max-width:96vw}.max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-none{flex:none}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.border-collapse{border-collapse:collapse}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-full{--tw-translate-y: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-row-resize{cursor:row-resize}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-rows-\[0fr\]{grid-template-rows:0fr}.grid-rows-\[1fr\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-0\.5{row-gap:.125rem}.gap-y-2{row-gap:.5rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-gray-100>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(243 244 246 / var(--tw-divide-opacity, 1))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(229 231 235 / var(--tw-divide-opacity, 1))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\[1px\]{border-radius:1px}.rounded-\[2px\]{border-radius:2px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-y{border-top-width:1px;border-bottom-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-300{--tw-border-opacity: 1;border-color:rgb(252 211 77 / var(--tw-border-opacity, 1))}.border-amber-400{--tw-border-opacity: 1;border-color:rgb(251 191 36 / var(--tw-border-opacity, 1))}.border-amber-500\/40{border-color:#f59e0b66}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-blue-400{--tw-border-opacity: 1;border-color:rgb(96 165 250 / var(--tw-border-opacity, 1))}.border-blue-500{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-gray-100{--tw-border-opacity: 1;border-color:rgb(243 244 246 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-gray-400{--tw-border-opacity: 1;border-color:rgb(156 163 175 / var(--tw-border-opacity, 1))}.border-gray-800{--tw-border-opacity: 1;border-color:rgb(31 41 55 / var(--tw-border-opacity, 1))}.border-green-300{--tw-border-opacity: 1;border-color:rgb(134 239 172 / var(--tw-border-opacity, 1))}.border-green-500{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.border-green-500\/40{border-color:#22c55e66}.border-purple-300{--tw-border-opacity: 1;border-color:rgb(216 180 254 / var(--tw-border-opacity, 1))}.border-red-300{--tw-border-opacity: 1;border-color:rgb(252 165 165 / var(--tw-border-opacity, 1))}.border-red-500{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-sky-300{--tw-border-opacity: 1;border-color:rgb(125 211 252 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-t-blue-500{--tw-border-opacity: 1;border-top-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.bg-\[\#8957e5\]\/15{background-color:#8957e526}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-400\/5{background-color:#fbbf240d}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-black\/50{background-color:#00000080}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-50\/40{background-color:#eff6ff66}.bg-blue-50\/50{background-color:#eff6ff80}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-blue-500\/10{background-color:#3b82f61a}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-300{--tw-bg-opacity: 1;background-color:rgb(209 213 219 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-500\/10{background-color:#6b72801a}.bg-gray-500\/20{background-color:#6b728033}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-gray-900\/40{background-color:#11182766}.bg-gray-950{--tw-bg-opacity: 1;background-color:rgb(3 7 18 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-500\/10{background-color:#22c55e1a}.bg-green-500\/15{background-color:#22c55e26}.bg-orange-500\/10{background-color:#f973161a}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-500\/10{background-color:#ef44441a}.bg-red-500\/15{background-color:#ef444426}.bg-sky-100{--tw-bg-opacity: 1;background-color:rgb(224 242 254 / var(--tw-bg-opacity, 1))}.bg-sky-500\/15{background-color:#0ea5e926}.bg-sky-500\/20{background-color:#0ea5e933}.bg-sky-500\/5{background-color:#0ea5e90d}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/95{background-color:#fffffff2}.bg-yellow-500\/10{background-color:#eab3081a}.fill-gray-400{fill:#9ca3af}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-0\.5{padding-bottom:.125rem}.pb-1{padding-bottom:.25rem}.pb-1\.5{padding-bottom:.375rem}.pb-3{padding-bottom:.75rem}.pl-0\.5{padding-left:.125rem}.pl-2{padding-left:.5rem}.pl-2\.5{padding-left:.625rem}.pr-1{padding-right:.25rem}.pr-2{padding-right:.5rem}.pr-2\.5{padding-right:.625rem}.pr-28{padding-right:7rem}.pr-4{padding-right:1rem}.pt-0\.5{padding-top:.125rem}.pt-1{padding-top:.25rem}.pt-1\.5{padding-top:.375rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-top{vertical-align:top}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-\[1\.45\]{line-height:1.45}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-wide{letter-spacing:.025em}.text-\[\#8957e5\]{--tw-text-opacity: 1;color:rgb(137 87 229 / var(--tw-text-opacity, 1))}.text-amber-200{--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-amber-700\/80{color:#b45309cc}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-blue-400\/50{color:#60a5fa80}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-500\/15{color:#3b82f626}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-emerald-500{--tw-text-opacity: 1;color:rgb(16 185 129 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-gray-200{--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-400\/10{color:#9ca3af1a}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-green-300{--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-green-700\/70{color:#15803db3}.text-green-700\/80{color:#15803dcc}.text-orange-500{--tw-text-opacity: 1;color:rgb(249 115 22 / var(--tw-text-opacity, 1))}.text-orange-700{--tw-text-opacity: 1;color:rgb(194 65 12 / var(--tw-text-opacity, 1))}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-sky-400\/80{color:#38bdf8cc}.text-sky-500{--tw-text-opacity: 1;color:rgb(14 165 233 / var(--tw-text-opacity, 1))}.text-sky-600{--tw-text-opacity: 1;color:rgb(2 132 199 / var(--tw-text-opacity, 1))}.text-sky-700{--tw-text-opacity: 1;color:rgb(3 105 161 / var(--tw-text-opacity, 1))}.text-violet-500{--tw-text-opacity: 1;color:rgb(139 92 246 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-700{--tw-text-opacity: 1;color:rgb(161 98 7 / var(--tw-text-opacity, 1))}.opacity-0{opacity:0}.opacity-45{opacity:.45}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-blue-500{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur{--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[grid-template-rows\]{transition-property:grid-template-rows;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-500{transition-duration:.5s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}:root{color-scheme:light dark}html,body,#root{height:100%;margin:0}body{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}body:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(3 7 18 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}body{font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif}.brand-title{font-family:Great Vibes,ui-serif,cursive;font-weight:400;font-size:1.75rem;line-height:1;letter-spacing:.3px;padding-bottom:2px;cursor:default;-webkit-user-select:none;-moz-user-select:none;user-select:none}.focus-indicator{display:inline-flex;align-items:center;gap:7px;padding:2px 10px;border-radius:9999px;letter-spacing:.5px;text-transform:uppercase;color:#0284c7;background:#38bdf81f;border:1px solid rgba(56,189,248,.4);white-space:nowrap;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;font:inherit;font-size:11px;font-weight:600;transition:box-shadow .15s ease}.focus-indicator:hover{animation:ev-select-pulse 1.8s ease-in-out infinite}.dark .focus-indicator{color:#7dd3fc}.focus-indicator-dot{width:7px;height:7px;border-radius:9999px;background:#38bdf8;box-shadow:0 0 #38bdf899;animation:focus-dot-pulse 1.8s ease-in-out infinite}.focus-indicator-close{display:inline-flex;align-items:center;justify-content:center;margin-left:1px;margin-right:-4px;width:16px;height:16px;border-radius:9999px;font-size:10px;line-height:1;color:inherit;opacity:0;transition:background .15s ease,opacity .15s ease}.focus-indicator:hover .focus-indicator-close{opacity:.95;background:#38bdf840;animation:focus-close-wobble 1s ease-out}@keyframes focus-close-wobble{0%{transform:rotate(0)}12%{transform:rotate(-14deg)}28%{transform:rotate(11deg)}44%{transform:rotate(-8deg)}60%{transform:rotate(5deg)}76%{transform:rotate(-2deg)}to{transform:rotate(0)}}@keyframes focus-dot-pulse{0%,to{box-shadow:0 0 #38bdf88c}50%{box-shadow:0 0 0 5px #38bdf800}}@media(prefers-reduced-motion:reduce){.focus-indicator-dot,.focus-indicator:hover,.focus-indicator:hover .focus-indicator-close{animation:none}}.focus-frame{position:relative}.focus-frame:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:20;pointer-events:none;border:1.5px solid rgba(56,189,248,.8);border-radius:8px;animation:focus-frame-pulse 2.4s ease-in-out infinite}@keyframes focus-frame-pulse{0%,to{box-shadow:inset 0 0 0 1px #38bdf81f,inset 0 0 10px #38bdf81a}50%{box-shadow:inset 0 0 0 1px #38bdf847,inset 0 0 18px 2px #38bdf833}}@media(prefers-reduced-motion:reduce){.focus-frame:after{animation:none}}.filters-disabled{opacity:.45;pointer-events:none}.md-body{font-size:13px;line-height:1.5;word-break:break-word}.md-body>*:first-child{margin-top:0}.md-body>*:last-child{margin-bottom:0}.md-body p{margin:.5em 0}.md-body h1,.md-body h2,.md-body h3{font-weight:600;margin:.6em 0 .3em}.md-body ul,.md-body ol{margin:.5em 0;padding-left:1.4em}.md-body ul{list-style:disc}.md-body ol{list-style:decimal}.md-body li{margin:.15em 0}.md-body a{color:#3b82f6;text-decoration:underline}.md-body code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em;background:#7f7f7f2e;padding:.1em .3em;border-radius:4px}.md-body pre{margin:.5em 0;padding:.7em;border-radius:6px;overflow-x:auto;background:#0d1117}.md-body pre code{background:transparent;padding:0}.md-body blockquote{border-left:3px solid rgba(127,127,127,.4);padding-left:.8em;margin:.5em 0;color:#9ca3af}.md-body table{border-collapse:collapse;margin:.5em 0}.md-body th,.md-body td{border:1px solid rgba(127,127,127,.3);padding:.3em .6em}.md-body img{max-width:100%;max-height:24rem;width:auto;height:auto}.pr-summary-collapsed .pr-summary-tall-img{display:none}.md-body input[type=checkbox]{margin-right:.4em}.dark .vis-timeline{border-color:#1f2937}.dark .vis-panel .vis-content,.dark .vis-panel .vis-background,.dark .vis-labelset .vis-label,.dark .vis-foreground .vis-group{border-color:#1f2937;color:#e5e7eb}.dark .vis-time-axis .vis-text{color:#9ca3af}.dark .vis-time-axis .vis-grid.vis-minor{border-color:#1f2937}.dark .vis-time-axis .vis-grid.vis-major{border-color:#374151}.dark .vis-labelset .vis-label{color:#d1d5db}.dark .vis-current-time{background-color:#ef4444}.vis-labelset .vis-label.vis-nested-group{padding-left:.625rem;font-size:11px;opacity:.85}.vis-labelset .vis-label.tl-user-row .vis-inner{width:100%;max-width:264px}.tl-user{display:flex;align-items:flex-start;gap:5px;min-width:0;width:100%}.tl-user-main{display:flex;flex-direction:column;min-width:0;flex:1 1 auto;gap:1px}.tl-user-name-line{display:flex;align-items:center;gap:5px;min-width:0}.tl-collapse-caret{flex:none;display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;margin-right:-1px;padding:0;border:0;border-radius:3px;background:transparent;color:#9ca3af;font-size:13px;line-height:1;cursor:pointer}.tl-collapse-caret:hover{background:#7878782e;color:#374151}.dark .tl-collapse-caret:hover{color:#e5e7eb}.tl-focus-active .tl-collapse-caret{display:none}.tl-stats-toggle{flex:none;display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:0;border-radius:3px;background:transparent;color:#9ca3af;line-height:1;cursor:pointer}.tl-stats-toggle:hover{background:#7878782e;color:#374151}.dark .tl-stats-toggle:hover{color:#e5e7eb}.tl-user-avatar{flex:none;width:18px;height:18px;border-radius:9999px;-o-object-fit:cover;object-fit:cover;background:#e5e7eb}.dark .tl-user-avatar{background:#374151}.tl-user-avatar-fallback{display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;color:#6b7280}.tl-user-name{font-size:12.5px;font-weight:600;flex:0 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tl-user-name-link{color:inherit;text-decoration:none;cursor:pointer}.tl-user-name-link:hover{text-decoration:underline}.tl-merger{flex:none;display:inline-flex;align-items:center}.tl-modal-header{display:flex;align-items:center;gap:6px;padding:4px 8px;cursor:move;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;border-bottom:1px solid #e5e7eb;background:#f9fafb;border-top-left-radius:.5rem;border-top-right-radius:.5rem}.dark .tl-modal-header{border-color:#374151;background:#11182799}.tl-modal-header:active{cursor:grabbing}.tl-grip{flex:none;color:#9ca3af}.tl-modal-title{font-size:11px;color:#9ca3af;margin-right:auto}.tl-modal-close{flex:none;display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:4px;font-size:12px;line-height:1;color:#9ca3af;cursor:pointer}.tl-modal-close:hover{background:#94a3b833;color:#374151}.dark .tl-modal-close:hover{color:#e5e7eb}.vis-labelset .vis-label.tl-user-row,.vis-foreground .vis-group.tl-user-row{transition:max-height .22s ease,opacity .22s ease}@media(prefers-reduced-motion:reduce){.vis-labelset .vis-label.tl-user-row,.vis-foreground .vis-group.tl-user-row{transition:none}}.tl-repo-tint-0{--tl-tint: 59 130 246}.tl-repo-tint-1{--tl-tint: 139 92 246}.tl-repo-watch{display:inline-flex;align-items:center;margin-left:5px;color:#0ea5e9;vertical-align:middle}.vis-labelset .vis-label.tl-user-row[class*=tl-repo-tint-],.vis-foreground .vis-group.tl-user-row[class*=tl-repo-tint-],.vis-labelset .vis-label.tl-repo-header[class*=tl-repo-tint-],.vis-foreground .vis-group.tl-repo-header[class*=tl-repo-tint-]{background-color:rgb(var(--tl-tint) / .1)}.dark .vis-labelset .vis-label.tl-user-row[class*=tl-repo-tint-],.dark .vis-foreground .vis-group.tl-user-row[class*=tl-repo-tint-],.dark .vis-labelset .vis-label.tl-repo-header[class*=tl-repo-tint-],.dark .vis-foreground .vis-group.tl-repo-header[class*=tl-repo-tint-]{background-color:rgb(var(--tl-tint) / .13)}.vis-labelset .vis-label.tl-user-row:nth-child(2n),.vis-foreground .vis-group.tl-user-row:nth-child(2n){background-image:linear-gradient(#0f172a0d,#0f172a0d)}.dark .vis-labelset .vis-label.tl-user-row:nth-child(2n),.dark .vis-foreground .vis-group.tl-user-row:nth-child(2n){background-image:linear-gradient(#ffffff0d,#ffffff0d)}.vis-labelset .vis-label.tl-user-row,.vis-foreground .vis-group.tl-user-row{box-shadow:inset 0 -2px #0f172a33}.dark .vis-labelset .vis-label.tl-user-row,.dark .vis-foreground .vis-group.tl-user-row{box-shadow:inset 0 -2px #ffffff29}.vis-item.vis-range.pr-bar{border-radius:6px;border-width:1px;color:#fff;font-size:11px;cursor:pointer;z-index:2;min-width:4px}.vis-item.pr-emph{font-size:11px}.vis-item.pr-muted{opacity:.85;font-size:10px}.vis-item.pr-muted .pr-title{max-width:16ch}.pr-status{display:flex;align-items:center;gap:5px;padding:1px 4px 2px;font-size:9px;line-height:1.2}.pr-ci{display:inline-block;width:7px;height:7px;border-radius:50%}.pr-warn{color:#fdba74;font-weight:700}.pr-comment-mark{display:inline-flex;align-items:center;color:#e0f2fe;opacity:.85}.pr-comment-mark svg{display:block}.vis-item.pr-muted .pr-comment-mark{margin-left:2px;opacity:.75}.vis-item.pr-bar.pr-open{background-color:#1d4ed8;border-color:#3b82f6}.vis-item.pr-bar.pr-merged{background-color:#15803d;border-color:#22c55e}.vis-item.pr-bar.pr-closed{background-color:#4b5563;border-color:#9ca3af}.vis-item.pr-draft{background-image:repeating-linear-gradient(45deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 4px,transparent 4px,transparent 8px)}.vis-item.pr-stalled{box-shadow:0 0 0 2px #ef4444}.vis-item.vis-selected.pr-bar{overflow:visible;z-index:5;animation:ev-select-pulse 1.8s ease-in-out infinite}.vis-item.pr-bar.pr-focus-hidden{display:none}@media(prefers-reduced-motion:reduce){.vis-item.vis-selected.pr-bar{animation:none;box-shadow:0 0 0 3px #38bdf8d9,0 0 12px 3px #38bdf880}}.vis-item.pr-bar.pr-cross-linked,.vis-item.ev-cross-linked .ev-marker-inner,.vis-item.ev-cross-linked .ev-cluster-inner{animation:ev-select-pulse 1.8s ease-in-out infinite}.vis-item.pr-bar.pr-cross-linked{overflow:visible;z-index:5}.vis-item.ev-cross-linked .ev-marker-inner,.vis-item.ev-cross-linked .ev-cluster-inner{position:relative;z-index:5}.vis-item.ev-cross-linked .ev-marker-inner{border-radius:9999px}@media(prefers-reduced-motion:reduce){.vis-item.pr-bar.pr-cross-linked,.vis-item.ev-cross-linked .ev-marker-inner,.vis-item.ev-cross-linked .ev-cluster-inner{animation:none;box-shadow:0 0 0 3px #38bdf8d9,0 0 12px 3px #38bdf880}}.vis-item.ev-exit-glow .ev-marker-inner,.vis-item.ev-exit-glow .ev-cluster-inner{position:relative;z-index:5;animation:ev-select-pulse 1.8s ease-in-out infinite}.vis-item.ev-exit-glow .ev-marker-inner{border-radius:9999px}@media(prefers-reduced-motion:reduce){.vis-item.ev-exit-glow .ev-marker-inner,.vis-item.ev-exit-glow .ev-cluster-inner{animation:none;box-shadow:0 0 0 3px #38bdf8cc,0 0 12px 3px #38bdf880}}@keyframes ev-select-pulse{0%,to{box-shadow:0 0 0 3px #38bdf8d9,0 0 14px 5px #38bdf88c}50%{box-shadow:0 0 0 5px #38bdf866,0 0 8px 2px #38bdf840}}.vis-item.ev-selected:not(.ev-cross-linked) .ev-marker-inner,.vis-item.ev-selected:not(.ev-cross-linked) .ev-cluster-inner{position:relative;z-index:5;animation:ev-select-pulse 1.8s ease-in-out infinite}.vis-item.ev-selected:not(.ev-cross-linked) .ev-marker-inner{border-radius:9999px}@media(prefers-reduced-motion:reduce){.vis-item.ev-selected:not(.ev-cross-linked) .ev-marker-inner,.vis-item.ev-selected:not(.ev-cross-linked) .ev-cluster-inner{animation:none;box-shadow:0 0 0 3px #38bdf8d9,0 0 12px 3px #38bdf880}}.pr-bar-inner{display:flex;align-items:center;gap:4px;padding:0 2px}.pr-num{font-weight:700;opacity:.85}.pr-avatar{border-radius:9999px;flex-shrink:0;vertical-align:middle}.pr-author{font-size:10px;opacity:.8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:12ch}.vis-item.pr-muted .pr-author{max-width:9ch}.pr-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:22ch}.pr-draft-tag{font-size:9px;text-transform:uppercase;background:#00000040;border-radius:3px;padding:0 3px}.pr-stall{color:#fca5a5}.pr-dots{display:inline-flex;align-items:center;gap:2px;margin-left:2px}.pr-dot{display:inline-block;width:7px;height:7px;border-radius:50%}.pr-dot-n{font-size:9px;font-weight:700;margin-right:3px}.vis-item.ev-marker,.vis-item.ev-cluster{background:transparent;border:none;box-shadow:none;pointer-events:none}.vis-item.ev-marker .vis-dot,.vis-item.ev-cluster .vis-dot{display:none}.vis-item.ev-marker .vis-item-content,.vis-item.ev-cluster .vis-item-content{transform:translate(-50%);padding:0}.ev-marker-inner{display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;pointer-events:auto}.ev-marker-inner svg{display:block}.ev-cluster-inner{display:flex;align-items:center;justify-content:center;gap:2px;min-width:18px;height:16px;padding:0 4px;border-radius:9px;background:#475569;color:#fff;font-size:10px;font-weight:700;line-height:1;cursor:pointer;border:1px solid rgba(255,255,255,.25);position:relative;pointer-events:auto}.vis-item.ev-cluster.vis-selected,.vis-item.ev-marker.vis-selected{background:transparent;box-shadow:none}.vis-item.vis-background.cross-sep{border-top:1px solid rgba(99,102,241,.38);background:#6366f10f;pointer-events:none}.dark .vis-item.vis-background.cross-sep{border-top-color:#818cf86b;background:#818cf817}.vis-item.ev-own .ev-marker-inner:after,.vis-item.ev-own .ev-cluster-inner:after{content:"";position:absolute;bottom:100%;left:50%;width:0;height:14px;border-left:1.5px solid rgba(203,213,225,.85);transform:translate(-50%);pointer-events:none}.vis-item.ev-own .ev-marker-inner.ev-round:after{bottom:calc(100% - 3px);height:17px}.tl-cross-connectors{position:absolute;pointer-events:none;overflow:hidden;z-index:5}.tl-cross-connectors path{stroke:#cbd5e1d9;stroke-width:1.5;fill:none}.dark .tl-cross-connectors path{stroke:#94a3b8b3}.vis-item.ev-cross .ev-marker-inner{border-radius:9999px;background:#6366f11a}.vis-item.ev-cross:not(.ev-selected):not(.ev-cross-linked):not(.ev-exit-glow) .ev-marker-inner{box-shadow:inset 0 0 0 1px #6366f16b}.vis-item.ev-cross:not(.ev-selected):not(.ev-cross-linked):not(.ev-exit-glow) .ev-cluster-inner{box-shadow:0 0 0 2px #6366f140}.dark .vis-item.ev-cross .ev-marker-inner{background:#818cf829}.dark .vis-item.ev-cross:not(.ev-selected):not(.ev-cross-linked):not(.ev-exit-glow) .ev-marker-inner{box-shadow:inset 0 0 0 1px #818cf885}.dark .vis-item.ev-cross:not(.ev-selected):not(.ev-cross-linked):not(.ev-exit-glow) .ev-cluster-inner{box-shadow:0 0 0 2px #818cf852}.vis-item.vis-point .vis-dot{border-width:5px}.ev-pr_opened .vis-dot{border-color:#3b82f6}.ev-pr_merged .vis-dot{border-color:#8957e5}.ev-pr_closed .vis-dot{border-color:#9ca3af}.ev-review_submitted .vis-dot{border-color:#22c55e}.ev-review_comment .vis-dot{border-color:#f59e0b}.ev-pr_comment .vis-dot{border-color:#a78bfa}.ev-commit_pushed .vis-dot{border-color:#6b7280;border-width:4px}.ev-diamond .vis-dot{border-radius:0;transform:rotate(45deg)}.ev-square .vis-dot{border-radius:2px}.comment-new{border-left:3px solid #38bdf8;margin-left:-2px;border-radius:1px;background:#38bdf80d}@keyframes activity-flash{0%{background:#38bdf847}to{background:#38bdf800}}.activity-flash{animation:activity-flash 1.8s ease-out forwards}@keyframes myturn-pulse{0%,to{opacity:1}50%{opacity:.35}}.my-turn-ring,.vis-item.pr-myturn{position:relative;overflow:visible}.my-turn-ring:after,.vis-item.pr-myturn:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;border-radius:inherit;box-shadow:0 0 0 2px #3b82f6e6;animation:myturn-pulse 2s ease-in-out infinite;will-change:opacity}@media(prefers-reduced-motion:reduce){.my-turn-ring:after,.vis-item.pr-myturn:after{animation:none;opacity:.85}}.first\:border-0:first-child{border-width:0px}.first\:pt-0:first-child{padding-top:0}.last\:mb-0:last-child{margin-bottom:0}.last\:pb-0:last-child{padding-bottom:0}.hover\:border-blue-500:hover{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.hover\:border-gray-400:hover{--tw-border-opacity: 1;border-color:rgb(156 163 175 / var(--tw-border-opacity, 1))}.hover\:border-red-400:hover{--tw-border-opacity: 1;border-color:rgb(248 113 113 / var(--tw-border-opacity, 1))}.hover\:border-sky-400:hover{--tw-border-opacity: 1;border-color:rgb(56 189 248 / var(--tw-border-opacity, 1))}.hover\:bg-amber-100:hover{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-400:hover{--tw-bg-opacity: 1;background-color:rgb(96 165 250 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-50:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-600:hover{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-200\/60:hover{background-color:#e5e7eb99}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-green-50:hover{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.hover\:bg-purple-50:hover{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:bg-sky-100:hover{--tw-bg-opacity: 1;background-color:rgb(224 242 254 / var(--tw-bg-opacity, 1))}.hover\:bg-sky-50:hover{--tw-bg-opacity: 1;background-color:rgb(240 249 255 / var(--tw-bg-opacity, 1))}.hover\:bg-sky-500\/25:hover{background-color:#0ea5e940}.hover\:text-amber-700:hover{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.hover\:text-blue-500:hover{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.hover\:text-gray-800:hover{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.hover\:text-red-500:hover{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.focus\:border-blue-500:focus{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.focus\:opacity-100:focus{opacity:1}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-sky-400:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(56 189 248 / var(--tw-ring-opacity, 1))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus\:ring-offset-gray-950:focus{--tw-ring-offset-color: #030712}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:no-underline:disabled{text-decoration-line:none}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}.group:hover .group-hover\:text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:opacity-100{opacity:1}@media(prefers-reduced-motion:reduce){.motion-reduce\:transition-none{transition-property:none}}.dark\:divide-gray-800:is(.dark *)>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(31 41 55 / var(--tw-divide-opacity, 1))}.dark\:border-amber-600:is(.dark *){--tw-border-opacity: 1;border-color:rgb(217 119 6 / var(--tw-border-opacity, 1))}.dark\:border-amber-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(180 83 9 / var(--tw-border-opacity, 1))}.dark\:border-amber-700\/60:is(.dark *){border-color:#b4530999}.dark\:border-amber-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(146 64 14 / var(--tw-border-opacity, 1))}.dark\:border-amber-900\/50:is(.dark *){border-color:#78350f80}.dark\:border-blue-600:is(.dark *){--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1))}.dark\:border-blue-900\/50:is(.dark *){border-color:#1e3a8a80}.dark\:border-gray-600:is(.dark *){--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1))}.dark\:border-gray-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.dark\:border-gray-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(31 41 55 / var(--tw-border-opacity, 1))}.dark\:border-green-600:is(.dark *){--tw-border-opacity: 1;border-color:rgb(22 163 74 / var(--tw-border-opacity, 1))}.dark\:border-green-700\/50:is(.dark *){border-color:#15803d80}.dark\:border-green-700\/60:is(.dark *){border-color:#15803d99}.dark\:border-purple-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(126 34 206 / var(--tw-border-opacity, 1))}.dark\:border-red-700\/60:is(.dark *){border-color:#b91c1c99}.dark\:border-red-900:is(.dark *){--tw-border-opacity: 1;border-color:rgb(127 29 29 / var(--tw-border-opacity, 1))}.dark\:border-sky-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(3 105 161 / var(--tw-border-opacity, 1))}.dark\:border-t-blue-400:is(.dark *){--tw-border-opacity: 1;border-top-color:rgb(96 165 250 / var(--tw-border-opacity, 1))}.dark\:bg-amber-900\/20:is(.dark *){background-color:#78350f33}.dark\:bg-amber-900\/40:is(.dark *){background-color:#78350f66}.dark\:bg-amber-950\/40:is(.dark *){background-color:#451a0366}.dark\:bg-blue-500\/5:is(.dark *){background-color:#3b82f60d}.dark\:bg-blue-900\/10:is(.dark *){background-color:#1e3a8a1a}.dark\:bg-blue-900\/20:is(.dark *){background-color:#1e3a8a33}.dark\:bg-gray-700:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-800\/50:is(.dark *){background-color:#1f293780}.dark\:bg-gray-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.dark\:bg-gray-900\/50:is(.dark *){background-color:#11182780}.dark\:bg-gray-900\/60:is(.dark *){background-color:#11182799}.dark\:bg-gray-900\/95:is(.dark *){background-color:#111827f2}.dark\:bg-gray-950:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(3 7 18 / var(--tw-bg-opacity, 1))}.dark\:bg-green-900\/20:is(.dark *){background-color:#14532d33}.dark\:bg-red-900\/20:is(.dark *){background-color:#7f1d1d33}.dark\:bg-sky-900\/50:is(.dark *){background-color:#0c4a6e80}.dark\:text-amber-200:is(.dark *){--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.dark\:text-amber-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.dark\:text-amber-300\/80:is(.dark *){color:#fcd34dcc}.dark\:text-amber-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.dark\:text-blue-300:is(.dark *){--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.dark\:text-blue-300\/40:is(.dark *){color:#93c5fd66}.dark\:text-blue-400:is(.dark *){--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.dark\:text-blue-400\/15:is(.dark *){color:#60a5fa26}.dark\:text-gray-100:is(.dark *){--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.dark\:text-gray-200:is(.dark *){--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.dark\:text-gray-300:is(.dark *){--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.dark\:text-gray-300\/10:is(.dark *){color:#d1d5db1a}.dark\:text-gray-400:is(.dark *){--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.dark\:text-gray-500:is(.dark *){--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.dark\:text-gray-600:is(.dark *){--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.dark\:text-gray-700:is(.dark *){--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.dark\:text-gray-800:is(.dark *){--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.dark\:text-green-300:is(.dark *){--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.dark\:text-green-400\/70:is(.dark *){color:#4ade80b3}.dark\:text-green-400\/80:is(.dark *){color:#4ade80cc}.dark\:text-green-500:is(.dark *){--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.dark\:text-orange-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 146 60 / var(--tw-text-opacity, 1))}.dark\:text-purple-300:is(.dark *){--tw-text-opacity: 1;color:rgb(216 180 254 / var(--tw-text-opacity, 1))}.dark\:text-red-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.dark\:text-red-400:is(.dark *){--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.dark\:text-sky-300:is(.dark *){--tw-text-opacity: 1;color:rgb(125 211 252 / var(--tw-text-opacity, 1))}.dark\:text-sky-400:is(.dark *){--tw-text-opacity: 1;color:rgb(56 189 248 / var(--tw-text-opacity, 1))}.dark\:text-yellow-500:is(.dark *){--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.dark\:hover\:border-gray-500:hover:is(.dark *){--tw-border-opacity: 1;border-color:rgb(107 114 128 / var(--tw-border-opacity, 1))}.dark\:hover\:bg-amber-900\/40:hover:is(.dark *){background-color:#78350f66}.dark\:hover\:bg-blue-500:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-blue-900\/30:hover:is(.dark *){background-color:#1e3a8a4d}.dark\:hover\:bg-gray-700:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-gray-700\/60:hover:is(.dark *){background-color:#37415199}.dark\:hover\:bg-gray-800:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-gray-800\/60:hover:is(.dark *){background-color:#1f293799}.dark\:hover\:bg-gray-900:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-gray-900\/40:hover:is(.dark *){background-color:#11182766}.dark\:hover\:bg-gray-900\/50:hover:is(.dark *){background-color:#11182780}.dark\:hover\:bg-green-900\/30:hover:is(.dark *){background-color:#14532d4d}.dark\:hover\:bg-purple-900\/30:hover:is(.dark *){background-color:#581c874d}.dark\:hover\:bg-red-950:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(69 10 10 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-sky-900\/30:hover:is(.dark *){background-color:#0c4a6e4d}.dark\:hover\:bg-sky-900\/40:hover:is(.dark *){background-color:#0c4a6e66}.dark\:hover\:text-amber-300:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.dark\:hover\:text-gray-100:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.dark\:hover\:text-gray-200:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.dark\:hover\:text-gray-300:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}@media(min-width:640px){.sm\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}