prreviewbuddy 0.44.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.45.0
4
+
5
+ **Expand a pane to fill the review page.** Buddy AI, Issues, Questions, Files and the review path
6
+ each have an expand button at the right of their title (on the review path, beside the theme count).
7
+ The pane you expand takes the whole review page below the header, which still shows the pull
8
+ request, its branch and its freshness. The collapse button, Escape or your browser's Back button puts
9
+ the page back as it was, and Forward expands it again. Nothing in the pane is reloaded on the way in
10
+ or out, so a conversation, an open file and your scroll position are all still there. An expanded
11
+ pane is part of the page's address, so a reload keeps it. With the review path expanded, its themes
12
+ are listed above the current one, and moving between them keeps it expanded.
13
+
14
+ **Ask Buddy about a whole issue or question.** Every issue and question card now has a sparkle icon
15
+ next to Copy. It opens the same questions you get by selecting text: **Explain**, **Explain simply**,
16
+ **Is this actually a problem?**, **Why does this matter?**, **Suggest a better implementation** and
17
+ **Generate a question for the author**, plus your own prompts. Buddy AI answers about the entire
18
+ finding straight away, in the pane beside the review. **Ask a question** and your own prompts put the
19
+ finding in the question box for you to finish instead. Selecting text works as before: whatever you
20
+ pick goes into the question box, and nothing is sent until you send it.
21
+
22
+ **Explain and Explain simply are now two different questions.** In the review page's menus,
23
+ **Explain** gives a full explanation with the technical detail kept, and **Explain simply** asks for
24
+ the plain version that **Explain** used to give.
25
+
26
+ **Starter prompts.** If you have never saved a prompt, **Your prompts** now starts with five:
27
+ **Teach me this**, **What could go wrong?**, **Walk me through it**, **What should I verify?** and
28
+ **What does it assume?**. They are ordinary prompts that you can edit or delete, and a prompt you delete
29
+ does not come back. If you have ever saved a prompt, your list is left exactly as it is.
30
+
31
+ **Your prompts can be folded away.** Click **Your prompts** in Buddy AI to hide the prompts and show
32
+ only how many you have, and click it again to show them. **Add** stays visible either way, and every
33
+ review remembers your choice. The suggested questions Buddy AI makes for each review are not affected.
34
+
35
+ **The address always names the theme you are reading.** Opening the review path now shows its
36
+ address as the theme it opens on, and a theme tag on a card changes the address too. Back and Forward
37
+ step through the themes you actually read, instead of going back to the review path while still
38
+ showing the theme you left.
39
+
40
+ **Review summaries on the Reviews page show code as code.** Names the review wrote in backticks now
41
+ appear as inline code instead of showing the backticks.
42
+
3
43
  ## 0.44.0
4
44
 
5
45
  **`prreviewbuddy review --queue` puts the reviews it starts on your review queue.** Add `--queue`
package/dist/server.js CHANGED
@@ -785,6 +785,34 @@ function svg(paths) {
785
785
  return `<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor">${paths}</svg>`;
786
786
  }
787
787
  //#endregion
788
+ //#region ../../packages/review-harness/src/domain/ui/components/ask_buddy_menu.ts
789
+ /**
790
+ * Ask Buddy on a finding card: a sparkle beside Copy that opens the assistant's actions for the
791
+ * whole finding.
792
+ *
793
+ * The selection menu has offered these actions for a long time, but only to someone who thought to
794
+ * highlight text first, and few did. This puts the same actions on the card itself. The selection
795
+ * menu stays the precision tool for asking about an excerpt.
796
+ *
797
+ * The markup is the page's existing `[data-menu]` menu (the header's `...` uses it), so it opens,
798
+ * closes and positions exactly as that one does. The panel is empty here and filled when it opens,
799
+ * because it lists the reviewer's saved prompts and those change without the page re-rendering.
800
+ *
801
+ * Workspace only. The extension renders these cards too, and there is no Buddy pane behind a card
802
+ * there for this to open, so `ReviewTabOptions.askBuddy` gates it and the extension never sets it.
803
+ */
804
+ var ASK_BUDDY_LABEL = "Ask Buddy";
805
+ /** Four-point sparkle, the conventional mark for "ask the AI". currentColor, like Copy beside it. */
806
+ var SPARKLE = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="14" height="14" fill="currentColor" aria-hidden="true"><path d="M7.53 1.28a.5.5 0 0 1 .94 0l.9 2.6a3 3 0 0 0 1.85 1.85l2.6.9a.5.5 0 0 1 0 .94l-2.6.9a3 3 0 0 0-1.85 1.85l-.9 2.6a.5.5 0 0 1-.94 0l-.9-2.6a3 3 0 0 0-1.85-1.85l-2.6-.9a.5.5 0 0 1 0-.94l2.6-.9a3 3 0 0 0 1.85-1.85z"/><path d="M13 11.2a.3.3 0 0 1 .56 0l.3.86a1 1 0 0 0 .62.62l.86.3a.3.3 0 0 1 0 .56l-.86.3a1 1 0 0 0-.62.62l-.3.86a.3.3 0 0 1-.56 0l-.3-.86a1 1 0 0 0-.62-.62l-.86-.3a.3.3 0 0 1 0-.56l.86-.3a1 1 0 0 0 .62-.62z"/></svg>`;
807
+ /** `kind` goes into the accessible name, so a screen reader hears which finding it is about. */
808
+ function renderAskBuddyMenu(kind) {
809
+ const name = `${ASK_BUDDY_LABEL} about this ${kind}`;
810
+ return `<div class="prb-menu prb-ask-buddy" data-menu data-ask-buddy-menu>
811
+ <button type="button" class="prb-menu-trigger prb-ask-buddy-trigger" data-menu-trigger aria-haspopup="menu" aria-expanded="false" aria-label="${escapeHtml$1(name)}" data-tip="${escapeHtml$1(ASK_BUDDY_LABEL)}">${SPARKLE}</button>
812
+ <div class="prb-menu-panel prb-ask-buddy-panel" data-menu-panel role="menu" aria-label="${escapeHtml$1(name)}" hidden></div>
813
+ </div>`;
814
+ }
815
+ //#endregion
788
816
  //#region ../../packages/review-harness/src/domain/ui/components/finding_copy.ts
789
817
  /** An issue: its title in bold, the description, then the location when it has one. */
790
818
  function issueMarkdown(issue) {
@@ -2139,7 +2167,7 @@ function renderClosedFindings(summary, cards, kind, nothingOpen) {
2139
2167
  <div class="pr-helper-closed-findings-list">${cards}</div>
2140
2168
  </details>`;
2141
2169
  }
2142
- function renderIssuesTab(session, investigatingId) {
2170
+ function renderIssuesTab(session, investigatingId, options) {
2143
2171
  if (!session) return emptyState("Generate an analysis to see issues.");
2144
2172
  const outcome = outcomeOf(session);
2145
2173
  if (outcome.kind === "none") return emptyState("Generate an analysis to see issues.");
@@ -2162,6 +2190,7 @@ function renderIssuesTab(session, investigatingId) {
2162
2190
  <div class="pr-helper-issue-title-row">
2163
2191
  <p class="pr-helper-issue-title">${renderInlineText(issue.title)}</p>
2164
2192
  ${renderFindingCopySource(issueMarkdown(issue), "issue")}
2193
+ ${options?.askBuddy ? renderAskBuddyMenu("issue") : ""}
2165
2194
  </div>
2166
2195
  <div class="pr-helper-issue-badges">
2167
2196
  ${renderFindingStatus(issue.reconciliationStatus)}
@@ -2253,6 +2282,7 @@ function renderQuestionCard(q, sections, answered, records, now = Date.now(), in
2253
2282
  <div class="pr-helper-issue-title-row">
2254
2283
  <p class="pr-helper-issue-title">${renderInlineText(q.question)}</p>
2255
2284
  ${renderFindingCopySource(questionMarkdown(q), "question")}
2285
+ ${options?.askBuddy ? renderAskBuddyMenu("question") : ""}
2256
2286
  </div>
2257
2287
  <div class="pr-helper-issue-badges">
2258
2288
  ${renderQuestionStatus(q.reconciliationStatus)}
@@ -2350,6 +2380,70 @@ function renderQuestionsTab(session, investigatingId, options) {
2350
2380
  `).join("")}${ungrouped.map(card).join("")}${closed}`;
2351
2381
  }
2352
2382
  //#endregion
2383
+ //#region ../../packages/review-harness/src/workspace/doc_head.ts
2384
+ /**
2385
+ * The title row a document pane opens with, and the provenance disclosure at the right of it.
2386
+ *
2387
+ * Two things sit in this row and they are not the same kind of thing. The title names the pane;
2388
+ * Analysis details answers "how was this made, and does it describe the code I am looking at" --
2389
+ * when it completed, which commit, which audience, which model, what it spent, which rubric. That
2390
+ * is a question about the whole analysis, so it belongs level with the pane's name rather than
2391
+ * below the output: a reader who meets it after the recommendations has already decided how much
2392
+ * to trust them.
2393
+ *
2394
+ * A control, not a strip. Full width would give provenance the weight of content, which it is not,
2395
+ * and it is the reason the disclosure opens into a panel anchored under the button rather than
2396
+ * pushing the report down the page. Opening it must not move the thing the reader was reading.
2397
+ *
2398
+ * This row lives inside the light document pane, never in the dark page header above it. The
2399
+ * header names the change; these details describe one run against it, and the two would be read as
2400
+ * one fact if they shared a surface. The `prb-doc-` prefix is load-bearing for that: it is what
2401
+ * `pane_palette.test.ts` looks for when it checks that nothing in the pane borrows a shell colour.
2402
+ */
2403
+ /**
2404
+ * The panel's contents are plain sentences, escaped here, because every caller is passing facts
2405
+ * rather than markup and one of them is a model's own words about a file it cited.
2406
+ */
2407
+ function renderAnalysisDetails(items) {
2408
+ if (items.length === 0) return "";
2409
+ return `<details class="prb-doc-provenance" data-analysis-details>
2410
+ <summary class="prb-doc-provenance-summary">Analysis details</summary>
2411
+ <div class="prb-doc-provenance-panel">
2412
+ <ul>${items.map((item) => `<li>${escapeHtml$1(item)}</li>`).join("")}</ul>
2413
+ </div>
2414
+ </details>`;
2415
+ }
2416
+ /**
2417
+ * `aside` is markup rather than a string of text: it is a rendered control, and the only one so
2418
+ * far is the disclosure above. Empty when a pane has no provenance to show, which is every state
2419
+ * before a run has produced something, and the row then draws as the bare title it used to be.
2420
+ */
2421
+ function renderDocHead(title, aside = "") {
2422
+ return `<div class="prb-doc-head">
2423
+ <h3 class="prb-doc-title">${escapeHtml$1(title)}</h3>
2424
+ ${aside}
2425
+ </div>`;
2426
+ }
2427
+ /**
2428
+ * Expand a surface to fill the workspace, or bring it back.
2429
+ *
2430
+ * Icon-only, like Copy on a card, because it sits in a title row and a word there would compete
2431
+ * with the title. Both icons are in the markup and the stylesheet shows the one `aria-pressed`
2432
+ * calls for, so the client only has to flip the attribute (see `paintFocus` in focus_mode.ts),
2433
+ * which also rewrites the name to say what pressing it will do.
2434
+ *
2435
+ * `name` is the surface as a person would say it, and goes into the accessible name.
2436
+ */
2437
+ var EXPAND_ICON = "<path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\"/>";
2438
+ var COLLAPSE_ICON = "<path d=\"M4 14h6v6M20 10h-6V4M14 10l7-7M3 21l7-7\"/>";
2439
+ function focusIcon(paths, className) {
2440
+ return `<svg class="${className}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
2441
+ }
2442
+ function renderFocusToggle(surface, name) {
2443
+ const label = `Expand ${name}`;
2444
+ return `<button type="button" class="prb-focus-toggle" data-focus-toggle="${surface}" data-focus-name="${escapeHtml$1(name)}" aria-pressed="false" aria-label="${escapeHtml$1(label)}" title="${escapeHtml$1(label)}">${focusIcon(EXPAND_ICON, "prb-focus-expand")}${focusIcon(COLLAPSE_ICON, "prb-focus-collapse")}</button>`;
2445
+ }
2446
+ //#endregion
2353
2447
  //#region ../../packages/review-harness/src/workspace/guide_view.ts
2354
2448
  /**
2355
2449
  * The workspace's Guide: one theme at a time.
@@ -2400,7 +2494,7 @@ function renderWorkspaceGuide(session, followUpInFlight = null) {
2400
2494
  return `<div class="prb-guide-detail" data-guide-detail="${escapeHtml$1(section.id)}"${hidden}>${card}</div>`;
2401
2495
  }).join("");
2402
2496
  return `
2403
- <div class="pr-helper-guide prb-guide">
2497
+ <div class="pr-helper-guide prb-guide" data-guide-start="${escapeHtml$1(selected.id)}">
2404
2498
  ${renderGuideProgress(sections, completed)}
2405
2499
  ${renderThemePicker(sections, selected.id)}
2406
2500
  <div class="prb-guide-details">${details}</div>
@@ -2420,7 +2514,7 @@ function renderGuideProgress(sections, completed) {
2420
2514
  const done = sections.filter((section) => completed.has(section.id)).length;
2421
2515
  const left = remainingMinutes(sections, completed);
2422
2516
  const time = left > 0 ? ` &middot; ~${left} min` : "";
2423
- return `<p class="prb-guide-progress">${done > 0 ? `${done} of ${total} theme${total === 1 ? "" : "s"} completed` : `${total} theme${total === 1 ? "" : "s"}`}${time}</p>`;
2517
+ return `<div class="prb-guide-head"><p class="prb-guide-progress">${done > 0 ? `${done} of ${total} theme${total === 1 ? "" : "s"} completed` : `${total} theme${total === 1 ? "" : "s"}`}${time}</p>${renderFocusToggle("guide", "Review path")}</div>`;
2424
2518
  }
2425
2519
  /**
2426
2520
  * The same theme list the rail draws, for the width where the rail is not drawn.
@@ -2434,51 +2528,6 @@ function renderThemePicker(sections, selectedId) {
2434
2528
  return `<div class="prb-guide-picker">${sections.map((section, index) => `<button type="button" class="prb-guide-pick" data-goto-section="${escapeHtml$1(section.id)}" data-theme-index="${index}" data-recommended-start="${section.recommendedStartingPoint}" aria-current="${section.id === selectedId}"><span class="prb-guide-pick-order">${index + 1}</span>${escapeHtml$1(section.title)}</button>`).join("")}</div>`;
2435
2529
  }
2436
2530
  //#endregion
2437
- //#region ../../packages/review-harness/src/workspace/doc_head.ts
2438
- /**
2439
- * The title row a document pane opens with, and the provenance disclosure at the right of it.
2440
- *
2441
- * Two things sit in this row and they are not the same kind of thing. The title names the pane;
2442
- * Analysis details answers "how was this made, and does it describe the code I am looking at" --
2443
- * when it completed, which commit, which audience, which model, what it spent, which rubric. That
2444
- * is a question about the whole analysis, so it belongs level with the pane's name rather than
2445
- * below the output: a reader who meets it after the recommendations has already decided how much
2446
- * to trust them.
2447
- *
2448
- * A control, not a strip. Full width would give provenance the weight of content, which it is not,
2449
- * and it is the reason the disclosure opens into a panel anchored under the button rather than
2450
- * pushing the report down the page. Opening it must not move the thing the reader was reading.
2451
- *
2452
- * This row lives inside the light document pane, never in the dark page header above it. The
2453
- * header names the change; these details describe one run against it, and the two would be read as
2454
- * one fact if they shared a surface. The `prb-doc-` prefix is load-bearing for that: it is what
2455
- * `pane_palette.test.ts` looks for when it checks that nothing in the pane borrows a shell colour.
2456
- */
2457
- /**
2458
- * The panel's contents are plain sentences, escaped here, because every caller is passing facts
2459
- * rather than markup and one of them is a model's own words about a file it cited.
2460
- */
2461
- function renderAnalysisDetails(items) {
2462
- if (items.length === 0) return "";
2463
- return `<details class="prb-doc-provenance" data-analysis-details>
2464
- <summary class="prb-doc-provenance-summary">Analysis details</summary>
2465
- <div class="prb-doc-provenance-panel">
2466
- <ul>${items.map((item) => `<li>${escapeHtml$1(item)}</li>`).join("")}</ul>
2467
- </div>
2468
- </details>`;
2469
- }
2470
- /**
2471
- * `aside` is markup rather than a string of text: it is a rendered control, and the only one so
2472
- * far is the disclosure above. Empty when a pane has no provenance to show, which is every state
2473
- * before a run has produced something, and the row then draws as the bare title it used to be.
2474
- */
2475
- function renderDocHead(title, aside = "") {
2476
- return `<div class="prb-doc-head">
2477
- <h3 class="prb-doc-title">${escapeHtml$1(title)}</h3>
2478
- ${aside}
2479
- </div>`;
2480
- }
2481
- //#endregion
2482
2531
  //#region ../../packages/review-harness/src/workspace/diagram_view.ts
2483
2532
  /**
2484
2533
  * The diagrams a review holds, drawn as cards in one scrolling pane.
@@ -4232,7 +4281,7 @@ function renderKissViews(view) {
4232
4281
  function renderFilesView(view, sections) {
4233
4282
  if (!(view.session.result !== null || (view.job ? changeIsRead(view.job) : false))) return "";
4234
4283
  return `<section class="prb-view" data-view="files" hidden>
4235
- <h3 class="prb-doc-title">Files</h3>
4284
+ ${renderDocHead("Files", renderFocusToggle("files", "Files"))}
4236
4285
  ${renderFiles(view, sections)}
4237
4286
  </section>`;
4238
4287
  }
@@ -4250,13 +4299,16 @@ function renderStandardViews(view, sections) {
4250
4299
  ${renderDiagrams(view.diagrams ?? [], sections, view.reviewedSha ?? null)}
4251
4300
  </section>
4252
4301
  <section class="prb-view" data-view="issues" hidden>
4253
- <h3 class="prb-doc-title">Issues</h3>
4302
+ ${renderDocHead("Issues", renderFocusToggle("issues", "Issues"))}
4254
4303
  ${renderAttributionAge(view)}
4255
- ${renderIssuesTab(session, null)}
4304
+ ${renderIssuesTab(session, null, { askBuddy: true })}
4256
4305
  </section>
4257
4306
  <section class="prb-view" data-view="questions" hidden>
4258
- <h3 class="prb-doc-title">Questions</h3>
4259
- ${renderQuestionsTab(session, null, { suppressFileJump: true })}
4307
+ ${renderDocHead("Questions", renderFocusToggle("questions", "Questions"))}
4308
+ ${renderQuestionsTab(session, null, {
4309
+ suppressFileJump: true,
4310
+ askBuddy: true
4311
+ })}
4260
4312
  </section>
4261
4313
  <section class="prb-view" data-view="prcontext" hidden>
4262
4314
  ${renderPrContextView(view.prContext ?? null, {
@@ -4991,8 +5043,9 @@ function renderAsk(view, sections, paused = false) {
4991
5043
  <div class="prb-ask-header">
4992
5044
  <h2>Ask Buddy AI</h2>
4993
5045
  <span class="prb-ask-scope" data-ask-scope>whole change</span>
5046
+ ${renderFocusToggle("buddy", "Buddy AI")}
4994
5047
  </div>
4995
- ${paused ? "" : renderPromptBank(view.prompts ?? [])}
5048
+ ${paused ? "" : renderPromptBank(view.prompts ?? [], view.promptsCollapsed === true)}
4996
5049
  <div class="prb-ask-log" data-ask-log>
4997
5050
  ${transcript.length > 0 || pending ? transcript.map((exchange) => `<div class="prb-msg prb-msg-user">${escapeHtml$1(exchange.question)}</div>
4998
5051
  <div class="prb-msg prb-msg-assistant prb-md">${renderMarkdown(exchange.answer)}${renderMessageCopySource(exchange.answer)}</div>`).join("") + pendingTurn : `<div class="prb-ask-empty"${paused ? " inert" : ""}>
@@ -5017,13 +5070,16 @@ function renderAsk(view, sections, paused = false) {
5017
5070
  * The list is always present, even when empty: an empty bank with an Add button explains what
5018
5071
  * the feature is, where a hidden one leaves it undiscoverable until someone reads a changelog.
5019
5072
  */
5020
- function renderPromptBank(prompts) {
5021
- return `<div class="prb-bank" data-prompt-bank data-prompts="${escapeHtml$1(JSON.stringify(prompts))}">
5073
+ function renderPromptBank(prompts, collapsed = false) {
5074
+ return `<div class="prb-bank" data-prompt-bank data-prompts="${escapeHtml$1(JSON.stringify(prompts))}"${collapsed ? " data-collapsed" : ""}>
5022
5075
  <div class="prb-bank-head">
5023
- <span>Your prompts</span>
5076
+ <button type="button" class="prb-bank-toggle" data-prompt-toggle aria-expanded="${!collapsed}" aria-controls="prb-bank-list">
5077
+ <svg class="prb-bank-chevron" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="10" height="10" fill="currentColor" aria-hidden="true"><path d="M6 4l4 4-4 4z"/></svg>
5078
+ <span>Your prompts</span><span class="prb-bank-count" data-prompt-count>${prompts.length}</span>
5079
+ </button>
5024
5080
  <button type="button" class="prb-bank-add" data-prompt-add>Add</button>
5025
5081
  </div>
5026
- <div class="prb-bank-list" data-prompt-list>${prompts.map(renderPromptChip).join("")}</div>
5082
+ <div class="prb-bank-list" id="prb-bank-list" data-prompt-list${collapsed ? " hidden" : ""}>${prompts.map(renderPromptChip).join("")}</div>
5027
5083
  </div>`;
5028
5084
  }
5029
5085
  function renderPromptChip(prompt) {
@@ -6255,7 +6311,7 @@ function renderCard(group, now, analysis, queued, moved, prState) {
6255
6311
  ${renderStatus(status)}
6256
6312
  ${renderPrState(prState)}
6257
6313
  </div>
6258
- ${review.summary ? `<p class="prb-card-summary">${escapeHtml$1(review.summary)}</p>` : ""}
6314
+ ${review.summary ? `<p class="prb-card-summary">${renderInlineText(review.summary)}</p>` : ""}
6259
6315
  <p class="prb-card-where">
6260
6316
  <span class="prb-card-repo">${escapeHtml$1(lastSegment(review.repoPath))}</span>
6261
6317
  ${review.prNumber === void 0 ? "" : `<span class="prb-card-pr">#${review.prNumber}</span>`}
@@ -7934,10 +7990,11 @@ function readPreferences() {
7934
7990
  try {
7935
7991
  const parsed = JSON.parse(readFileSync(PREFERENCES_PATH, "utf8"));
7936
7992
  if (!parsed || typeof parsed !== "object") return {};
7937
- const { askWidth, dismissedNotices } = parsed;
7993
+ const { askWidth, dismissedNotices, promptsCollapsed } = parsed;
7938
7994
  return {
7939
7995
  ...typeof askWidth === "number" && Number.isFinite(askWidth) ? { askWidth: clampAskWidth(askWidth) } : {},
7940
- ...Array.isArray(dismissedNotices) ? { dismissedNotices: dismissedNotices.filter((key) => typeof key === "string" && NOTICE_KEY.test(key)) } : {}
7996
+ ...Array.isArray(dismissedNotices) ? { dismissedNotices: dismissedNotices.filter((key) => typeof key === "string" && NOTICE_KEY.test(key)) } : {},
7997
+ ...typeof promptsCollapsed === "boolean" ? { promptsCollapsed } : {}
7941
7998
  };
7942
7999
  } catch {
7943
8000
  return {};
@@ -7954,6 +8011,16 @@ function writeAskWidth(width) {
7954
8011
  writeFileSync(PREFERENCES_PATH, `${JSON.stringify(next, null, 2)}\n`);
7955
8012
  } catch {}
7956
8013
  }
8014
+ /** Remember whether "Your prompts" is folded. Read-modify-write, like every other field here. */
8015
+ function writePromptsCollapsed(collapsed) {
8016
+ try {
8017
+ mkdirSync(STORE_ROOT, { recursive: true });
8018
+ writeFileSync(PREFERENCES_PATH, `${JSON.stringify({
8019
+ ...readPreferences(),
8020
+ promptsCollapsed: collapsed
8021
+ }, null, 2)}\n`);
8022
+ } catch {}
8023
+ }
7957
8024
  /** Remember that the reviewer has read a notice. Refuses anything not shaped like a key. */
7958
8025
  function dismissNotice(key) {
7959
8026
  if (!NOTICE_KEY.test(key)) return false;
@@ -7989,6 +8056,44 @@ function clampAskWidth(width) {
7989
8056
  /** Long enough for a paragraph of standing instructions, short enough not to crowd the question. */
7990
8057
  var MAX_PROMPT_CHARS = 2e3;
7991
8058
  /**
8059
+ * What a reviewer starts with, before they have saved anything.
8060
+ *
8061
+ * Drawn from what reviewers were typing by hand most often. Ordinary saved prompts in every
8062
+ * respect: no flag marks them as defaults, so they edit, delete and reorder exactly as a prompt the
8063
+ * reviewer wrote does. Whoever reads a bank decides when these apply. In the workspace that is
8064
+ * only when no bank has ever been written, so a deleted default stays deleted.
8065
+ *
8066
+ * The ids are fixed rather than generated, so reading an unwritten bank twice gives the same bank.
8067
+ * Nothing depends on their spelling beyond that.
8068
+ */
8069
+ var DEFAULT_PROMPTS = Object.freeze([
8070
+ {
8071
+ id: "default-assumptions",
8072
+ name: "What does it assume?",
8073
+ prompt: "What assumptions does this change make? Say which are stated, which are implied, and what happens if one turns out to be wrong."
8074
+ },
8075
+ {
8076
+ id: "default-explain-educational",
8077
+ name: "Teach me this",
8078
+ prompt: "Explain this in an educational way: the concepts it relies on, why it is built this way, and what I should take away from it."
8079
+ },
8080
+ {
8081
+ id: "default-what-could-go-wrong",
8082
+ name: "What could go wrong?",
8083
+ prompt: "What could go wrong here? Think about edge cases, failure modes and the existing callers this could break."
8084
+ },
8085
+ {
8086
+ id: "default-walkthrough",
8087
+ name: "Walk me through it",
8088
+ prompt: "Walk me through the implementation step by step, in the order the code runs."
8089
+ },
8090
+ {
8091
+ id: "default-verify-manually",
8092
+ name: "What should I verify?",
8093
+ prompt: "What should I verify manually before approving this, and how would I check each one?"
8094
+ }
8095
+ ].map((prompt) => Object.freeze(prompt)));
8096
+ /**
7992
8097
  * Everything reaching this function came from a client, so nothing here is trusted.
7993
8098
  *
7994
8099
  * Entries are repaired where the repair is unambiguous — trimming, truncating — and dropped where
@@ -8030,9 +8135,29 @@ function sanitisePromptBank(value) {
8030
8135
  * a workspace that will not open.
8031
8136
  */
8032
8137
  var PROMPTS_PATH = join(STORE_ROOT, "prompts.json");
8138
+ /**
8139
+ * The bank as stored or, when nothing has ever been stored, the defaults.
8140
+ *
8141
+ * Only a file that does not exist counts as a new bank. Once the file exists it is the reviewer's,
8142
+ * even when it is empty: an empty list is a reviewer who deleted every prompt, and handing the
8143
+ * defaults back to them would be undoing what they did. A corrupt file is not "new" either. It
8144
+ * reads as empty, as it always has, rather than being covered over with prompts the reviewer
8145
+ * never chose.
8146
+ *
8147
+ * The defaults are returned, not written. The first add, edit or delete posts the whole bank,
8148
+ * defaults included, and that write is what turns them into the reviewer's own. A reader that
8149
+ * wrote here would create the file on a page load, which the offline preview must not do.
8150
+ */
8033
8151
  function readPromptBank() {
8152
+ let raw;
8153
+ try {
8154
+ raw = readFileSync(PROMPTS_PATH, "utf8");
8155
+ } catch (error) {
8156
+ if (error.code === "ENOENT") return DEFAULT_PROMPTS.map((prompt) => ({ ...prompt }));
8157
+ return [];
8158
+ }
8034
8159
  try {
8035
- return sanitisePromptBank(JSON.parse(readFileSync(PROMPTS_PATH, "utf8")));
8160
+ return sanitisePromptBank(JSON.parse(raw));
8036
8161
  } catch {
8037
8162
  return [];
8038
8163
  }
@@ -8897,6 +9022,7 @@ async function sendWorkspacePage(res, workspace) {
8897
9022
  repoPath: workspace.repoPath,
8898
9023
  askWidth: readPreferences().askWidth,
8899
9024
  dismissedNotices: readPreferences().dismissedNotices,
9025
+ promptsCollapsed: readPreferences().promptsCollapsed === true,
8900
9026
  transcript: workspace.transcript,
8901
9027
  pendingAsk: reportRun(workspace.id, "ask"),
8902
9028
  pendingDiagram: reportRun(workspace.id, "diagram"),
@@ -9481,6 +9607,7 @@ async function handlePrefs(req, res) {
9481
9607
  const askWidth = body?.askWidth;
9482
9608
  if (typeof askWidth === "number") writeAskWidth(askWidth);
9483
9609
  else if (askWidth === null) clearAskWidth();
9610
+ if (typeof body?.promptsCollapsed === "boolean") writePromptsCollapsed(body.promptsCollapsed);
9484
9611
  if (typeof body?.dismissNotice === "string" && !dismissNotice(body.dismissNotice)) return send(res, 400, { error: "Not a notice this page can dismiss." });
9485
9612
  send(res, 200, { ok: true });
9486
9613
  }
@@ -9542,7 +9669,8 @@ var ASK_SOURCES = [
9542
9669
  "suggestion",
9543
9670
  "free_text",
9544
9671
  "explain_simply",
9545
- "selection"
9672
+ "selection",
9673
+ "finding"
9546
9674
  ];
9547
9675
  function askSource(value) {
9548
9676
  return ASK_SOURCES.includes(value) ? value : "free_text";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prreviewbuddy",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
4
4
  "description": "Review a branch or pull request in an isolated checkout, from your terminal, with the coding agent you already have installed.",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://prreviewbuddy.com",
package/static/shell.css CHANGED
@@ -3252,6 +3252,12 @@ a.prb-rail-item { text-decoration: none; }
3252
3252
  -webkit-box-orient: vertical;
3253
3253
  overflow: hidden;
3254
3254
  }
3255
+ .prb-card-summary code {
3256
+ padding: 0 4px;
3257
+ border-radius: 4px;
3258
+ background: var(--surface-2);
3259
+ font-size: var(--t-code);
3260
+ }
3255
3261
  .prb-card-where,
3256
3262
  .prb-card-meta {
3257
3263
  display: flex;
@@ -3863,8 +3869,15 @@ a.prb-rail-item { text-decoration: none; }
3863
3869
  line-height: var(--lh-tight);
3864
3870
  }
3865
3871
 
3866
- .prb-guide-progress {
3872
+ .prb-guide-head {
3873
+ display: flex;
3874
+ align-items: center;
3875
+ gap: 12px;
3867
3876
  margin: 0 0 20px;
3877
+ }
3878
+ .prb-guide-head .prb-focus-toggle { margin-left: auto; }
3879
+ .prb-guide-progress {
3880
+ margin: 0;
3868
3881
  color: var(--pane-ink-faint);
3869
3882
  font-size: var(--t-meta);
3870
3883
  }
@@ -4517,3 +4530,199 @@ a.prb-notification-open:focus-visible { outline: 2px solid var(--brand-hover); o
4517
4530
  .prb-toast-close:hover { color: var(--text-primary); background: rgba(255, 255, 255, 0.06); }
4518
4531
  .prb-toast-open:focus-visible,
4519
4532
  .prb-toast-close:focus-visible { outline: 2px solid var(--brand-hover); outline-offset: 2px; }
4533
+
4534
+ /* ── Focus mode ──
4535
+ One surface as the whole workspace, beneath the same header, which is outside `.prb-body` and so
4536
+ never changes. The client sets `data-focus` and nothing else: every pane stays in the DOM,
4537
+ hidden rather than removed, which is why a conversation, an open code panel and a scroll position
4538
+ are all still there on the way back.
4539
+
4540
+ `body` in front of every selector, deliberately. The responsive blocks above set the grid with
4541
+ (0,2,0) selectors inside media queries that come later in the cascade than anything this could
4542
+ be placed beside. One element of extra specificity wins at every width without `!important`,
4543
+ and without depending on this block staying last. */
4544
+ body .prb-body[data-focus] { grid-template-columns: minmax(0, 1fr); }
4545
+ body .prb-body[data-focus] .prb-rail { display: none; }
4546
+
4547
+ /* A document surface: the review pane takes the width, and gets more room to use it. Issues and
4548
+ Questions stay a readable measure; a diff is the one thing here that genuinely wants the width. */
4549
+ body .prb-body:is([data-focus='issues'], [data-focus='questions'], [data-focus='files'], [data-focus='guide']) .prb-ask { display: none; }
4550
+ body .prb-body:is([data-focus='issues'], [data-focus='questions'], [data-focus='guide']) .pr-helper-sidebar.prb-pane { max-width: 1080px; }
4551
+ /* The rail is where the themes are listed, and it is hidden here, so the picker it stands in for
4552
+ below 860px stands in for it now. */
4553
+ body .prb-body[data-focus='guide'] .prb-guide-picker { display: flex; }
4554
+ body .prb-body[data-focus='files'] .pr-helper-sidebar.prb-pane { max-width: 1600px; }
4555
+
4556
+ /* The assistant: the review pane goes, and the assistant is a column in the grid again at every
4557
+ width. Below 860px it is otherwise a fixed overlay, and an overlay as the whole workspace would
4558
+ sit over the header this mode promises to keep. */
4559
+ body .prb-body[data-focus='buddy'] .prb-doc { display: none; }
4560
+ body .prb-body[data-focus='buddy'] .prb-ask {
4561
+ display: flex;
4562
+ position: relative;
4563
+ inset: auto;
4564
+ width: auto;
4565
+ border-left: 0;
4566
+ }
4567
+ body .prb-body[data-focus='buddy'] .prb-ask-resize { display: none; }
4568
+
4569
+ /* Prose at a reading measure, centred, with the column itself wider so a code block or a table in
4570
+ an answer can use the room the mode exists to give it. The padding does the centring rather than
4571
+ a max-width on the log, so the log's scrollbar stays at the window's edge. */
4572
+ body .prb-body[data-focus='buddy'] :is(.prb-ask-header, .prb-bank, .prb-ask-log, .prb-ask-form, .prb-ask-paused) {
4573
+ padding-inline: max(18px, calc((100% - 1040px) / 2));
4574
+ }
4575
+ body .prb-body[data-focus='buddy'] .prb-msg-assistant :is(p, ul, ol, blockquote, h1, h2, h3, h4, h5, h6) { max-width: 78ch; }
4576
+ body .prb-body[data-focus='buddy'] .prb-msg-user { max-width: min(90%, 78ch); }
4577
+
4578
+ /* The expand control. Icon-only, like Copy on a card, so it does not compete with a title. Both
4579
+ icons are in the markup and `aria-pressed` picks one, which is the state the client sets. */
4580
+ .prb-focus-toggle {
4581
+ display: inline-flex;
4582
+ align-items: center;
4583
+ justify-content: center;
4584
+ flex-shrink: 0;
4585
+ width: 26px;
4586
+ height: 26px;
4587
+ padding: 0;
4588
+ border: 1px solid transparent;
4589
+ border-radius: 7px;
4590
+ background: transparent;
4591
+ color: var(--text-muted);
4592
+ cursor: pointer;
4593
+ }
4594
+ .prb-focus-toggle:hover { color: var(--text-primary); background: var(--surface-2); }
4595
+ .prb-focus-toggle:focus-visible { outline: 2px solid var(--brand-hover); outline-offset: -2px; }
4596
+ .prb-focus-toggle .prb-focus-collapse,
4597
+ .prb-focus-toggle[aria-pressed='true'] .prb-focus-expand { display: none; }
4598
+ .prb-focus-toggle[aria-pressed='true'] .prb-focus-collapse { display: block; }
4599
+ /* In the assistant's header it follows the scope label, which takes the free space with
4600
+ `margin-left: auto`, so the control stays at the right edge beside it. */
4601
+ .prb-ask-header .prb-focus-toggle { align-self: center; }
4602
+
4603
+ /* The same control in the light document pane, in the pane's palette. */
4604
+ .prb-doc .prb-focus-toggle { color: var(--pane-ink-faint); }
4605
+ .prb-doc .prb-focus-toggle:hover { color: var(--pane-ink); background: var(--pane-bg); border-color: var(--pane-line); }
4606
+ /* The title row is baseline-aligned for the disclosure's text; an icon has no baseline worth
4607
+ aligning, so it centres on the title instead. */
4608
+ .prb-doc .prb-doc-head .prb-focus-toggle { align-self: center; margin-left: auto; }
4609
+
4610
+ /* ── Your prompts, folded ──
4611
+ The heading is the toggle. Folded, it keeps a count, so a reviewer knows what is behind it
4612
+ without opening it, and Add stays beside it. */
4613
+ .prb-bank-toggle {
4614
+ display: inline-flex;
4615
+ align-items: center;
4616
+ gap: 6px;
4617
+ padding: 2px 4px 2px 0;
4618
+ border: 0;
4619
+ background: transparent;
4620
+ color: inherit;
4621
+ font: inherit;
4622
+ letter-spacing: inherit;
4623
+ text-transform: inherit;
4624
+ cursor: pointer;
4625
+ }
4626
+ .prb-bank-toggle:hover { color: var(--text-primary); }
4627
+ .prb-bank-toggle:focus-visible { outline: 2px solid var(--brand-hover); outline-offset: 2px; border-radius: 4px; }
4628
+ .prb-bank-chevron { transition: transform 120ms ease; transform: rotate(90deg); }
4629
+ .prb-bank-toggle[aria-expanded='false'] .prb-bank-chevron { transform: none; }
4630
+ .prb-bank-count {
4631
+ padding: 0 6px;
4632
+ border-radius: 999px;
4633
+ background: var(--surface-2);
4634
+ font-variant-numeric: tabular-nums;
4635
+ letter-spacing: normal;
4636
+ }
4637
+ .prb-bank-toggle[aria-expanded='true'] .prb-bank-count { display: none; }
4638
+ .prb-bank[data-collapsed] { padding-bottom: 8px; }
4639
+ .prb-bank[data-collapsed] .prb-bank-head { margin-bottom: 0; }
4640
+
4641
+ /* ── Ask Buddy on a finding card ──
4642
+ The page's `[data-menu]` menu, as the header's `...` is, dropped into a card's title row beside
4643
+ Copy. Positioned as the flex child it is, the way `.prb-header .prb-menu` is, so the panel hangs
4644
+ off the trigger rather than off a corner of the card. The panel is in the card's flow inside the
4645
+ scrolling pane, so near the bottom it extends the scroll rather than being cut off. */
4646
+ .prb-doc .pr-helper-issue-title-row .prb-menu {
4647
+ position: relative;
4648
+ top: auto;
4649
+ right: auto;
4650
+ display: inline-flex;
4651
+ flex-shrink: 0;
4652
+ /* Not the base rule's `z-index: 2`. That makes every card's wrapper a stacking context of its
4653
+ own at the same level, and the next card's sparkle, later in the document, then paints over
4654
+ this card's open panel. With no context here the panel's own z-index is measured against the
4655
+ whole pane. */
4656
+ z-index: auto;
4657
+ }
4658
+ .prb-doc .prb-ask-buddy-trigger {
4659
+ display: inline-flex;
4660
+ align-items: center;
4661
+ justify-content: center;
4662
+ width: 24px;
4663
+ height: 24px;
4664
+ margin-top: -3px;
4665
+ color: var(--pane-accent);
4666
+ }
4667
+ .prb-doc .prb-ask-buddy-trigger:hover,
4668
+ .prb-doc .prb-ask-buddy-trigger[aria-expanded='true'] { background: var(--pane-bg); color: var(--pane-accent-ink); }
4669
+ .prb-doc .prb-ask-buddy-trigger:focus-visible { outline: 2px solid var(--pane-accent); outline-offset: -2px; }
4670
+
4671
+ /* The tooltip Copy uses beside it, so the two icons explain themselves the same way. */
4672
+ .prb-doc .prb-ask-buddy-trigger::after {
4673
+ content: attr(data-tip);
4674
+ position: absolute;
4675
+ top: calc(100% + 6px);
4676
+ right: 0;
4677
+ z-index: 3;
4678
+ padding: 5px 8px;
4679
+ border-radius: 6px;
4680
+ background: #24292f;
4681
+ color: #ffffff;
4682
+ font-size: 11px;
4683
+ line-height: 1.4;
4684
+ white-space: nowrap;
4685
+ opacity: 0;
4686
+ pointer-events: none;
4687
+ transition: opacity 0.1s;
4688
+ }
4689
+ .prb-doc .prb-ask-buddy-trigger:hover::after,
4690
+ .prb-doc .prb-ask-buddy-trigger:focus-visible::after { opacity: 1; transition-delay: 0.35s; }
4691
+ .prb-doc .prb-ask-buddy-trigger[aria-expanded='true']::after { display: none; }
4692
+
4693
+ /* The panel in the pane's palette: the header's is dark on the dark shell, and a dark box in the
4694
+ middle of a light card is the mistake pane_palette.test.ts exists to catch. */
4695
+ .prb-doc .prb-ask-buddy-panel {
4696
+ top: 28px;
4697
+ width: 280px;
4698
+ max-width: min(280px, calc(100vw - 48px));
4699
+ border-color: var(--pane-line);
4700
+ background: var(--pane-surface);
4701
+ box-shadow: 0 10px 28px rgba(15, 23, 42, 0.16);
4702
+ color: var(--pane-ink);
4703
+ }
4704
+ .prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-item {
4705
+ display: block;
4706
+ width: 100%;
4707
+ padding: 7px 9px;
4708
+ border: 0;
4709
+ border-radius: 6px;
4710
+ background: transparent;
4711
+ color: var(--pane-ink);
4712
+ font: inherit;
4713
+ font-size: var(--t-meta);
4714
+ text-align: left;
4715
+ cursor: pointer;
4716
+ }
4717
+ .prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-item:hover,
4718
+ .prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-item:focus-visible { background: var(--pane-bg); outline: none; }
4719
+ .prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-item:focus-visible { box-shadow: inset 0 0 0 2px var(--pane-accent); }
4720
+ .prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-item:disabled { opacity: 0.5; cursor: default; }
4721
+ .prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-group { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--pane-line); }
4722
+ .prb-doc .prb-ask-buddy-panel .pr-helper-selection-menu-heading {
4723
+ padding: 4px 9px 2px;
4724
+ color: var(--pane-ink-faint);
4725
+ font-size: var(--t-micro);
4726
+ letter-spacing: 0.04em;
4727
+ text-transform: uppercase;
4728
+ }
@@ -1,13 +1,13 @@
1
1
  const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["chunk-BeqgAIrQ.js","chunk-DsF7k-Jl.js","chunk-BWjKdrB5.js","chunk-hePW80VL.js","chunk-CN9Gw02i.js","chunk-DJ4Pz6CG.js","chunk-B2kMZj3m.js","chunk-DN473Oml.js","chunk-DwZ_OKDV.js","chunk-CFLfawWY.js","chunk-Wc3Sd0cy.js","chunk-Dy-Kn_BL.js","chunk-CUxm3YXF.js","chunk-tz4nb_gp.js","chunk-BsaS8BTP.js","chunk-fybaL0A-.js","chunk-BifhSqXX.js","chunk-DS17s2tU.js","chunk-nU5620mN.js","chunk-CAnKkQXq.js","chunk-LbU1hoFO.js","chunk-BzbQS41l.js","chunk-BsjqnLg3.js","chunk-BtIQNnN0.js","chunk-D3KKoC5L.js","chunk-CP0rg-5b.js","chunk-j_1H8WHN.js","chunk-BOvsFOI6.js","chunk-CqHdAlCp.js","chunk-DijMHRDA.js","chunk-D2pwppYQ.js","chunk-Cjc271yU.js","chunk-B2PgDgse.js","chunk-D95j_xjm.js","chunk-Cv3JjNkX.js","chunk-EIJEcyW-.js","chunk-C3nvJp0N.js","chunk-D2NZorQR.js","chunk-NzFayA7r.js","chunk-AdYjtsZU.js","chunk-pNSm1SyV.js","chunk-c-cg1wCO.js","chunk-CBrdyqSx.js"])))=>i.map(i=>d[i]);
2
- import{c as e,i as t,t as n}from"./chunk-BeL0x-wt.js";import{_ as r,d as i,g as a,h as o}from"./chunk-CmPWaXhU.js";function s(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`)}var c=`pr-helper-code-block`,l=`pr-helper-code-copy`,u=`\0`,d=``,ee=/\u0000(\d+)\u0000/g,f=/^\u0000\d+\u0000$/,p=/\u0001(\d+)\u0001/g,m=/^(?:https?:\/\/|#)/i;function te(e){let{text:t,blocks:n}=ne(e.replace(/[\u0000\u0001]/g,``));return re(ie(t),n)}function ne(e){let t=[],n=e.split(`
2
+ import{c as e,i as t,t as n}from"./chunk-BeL0x-wt.js";import{_ as r,d as i,g as a,h as o}from"./chunk-CmPWaXhU.js";function s(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`)}var c=`pr-helper-code-block`,l=`pr-helper-code-copy`,u=`\0`,d=``,ee=/\u0000(\d+)\u0000/g,f=/^\u0000\d+\u0000$/,te=/\u0001(\d+)\u0001/g,ne=/^(?:https?:\/\/|#)/i;function re(e){let{text:t,blocks:n}=p(e.replace(/[\u0000\u0001]/g,``));return ie(ae(t),n)}function p(e){let t=[],n=e.split(`
3
3
  `),r=[],i=0;for(;i<n.length;){let e=n[i].match(/^\s*(`{3,}|~{3,})\s*[\w+#.-]*\s*$/);if(!e){r.push(n[i]),i+=1;continue}let a=RegExp(`^\\s*${e[1][0]}{3,}\\s*$`),o=[];for(i+=1;i<n.length&&!a.test(n[i]);)o.push(n[i]),i+=1;i+=1,r.push(`${u}${t.length}${u}`),t.push(o.join(`
4
4
  `))}return{text:r.join(`
5
- `),blocks:t}}function re(e,t){return e.replace(ee,(e,n)=>`<div class="${c}"><pre><code>${s(t[Number(n)])}</code></pre><button type="button" class="${l}" aria-label="Copy code">Copy</button></div>`)}function ie(e){let t=[],n=[],r=[],i=null,a=()=>{n.length&&t.push(`<p>${ae(n.join(` `))}</p>`),r.length&&t.push(`<blockquote>${ae(r.join(` `))}</blockquote>`),i&&t.push(`<${i.tag}>${i.items.map(e=>`<li>${ae(e)}</li>`).join(``)}</${i.tag}>`),n=[],r=[],i=null};for(let o of e.split(`
6
- `)){let e=o.trim();if(!e){a();continue}if(f.test(e)){a(),t.push(e);continue}if(/^(?:-{3,}|\*{3,}|_{3,})$/.test(e)){a(),t.push(`<hr>`);continue}let s=e.match(/^(#{1,6})\s+(.+)$/);if(s){a();let e=Math.min(s[1].length,3)+3;t.push(`<h${e}>${ae(s[2])}</h${e}>`);continue}let c=e.match(/^[-*+]\s+(.+)$/);if(c){i?.tag!==`ul`&&(a(),i={tag:`ul`,items:[]}),i.items.push(c[1]);continue}let l=e.match(/^\d{1,9}[.)]\s+(.+)$/);if(l){i?.tag!==`ol`&&(a(),i={tag:`ol`,items:[]}),i.items.push(l[1]);continue}let u=e.match(/^>\s?(.*)$/);if(u){r.length||a(),r.push(u[1]);continue}if(i&&i.items.length){i.items[i.items.length-1]+=` ${e}`;continue}if(r.length){r[r.length-1]+=` ${e}`;continue}n.push(e)}return a(),t.join(``)}function ae(e){let t=[];return s(e).replace(/`([^`\n]+)`/g,(e,n)=>(t.push(n),`${d}${t.length-1}${d}`)).replace(/(?<!!)\[([^\]\n]+)\]\(([^)\s]+)\)/g,(e,t,n)=>m.test(n)?`<a href="${n}" target="_blank" rel="noopener noreferrer">${t}</a>`:e).replace(/\*\*([^*\n]+)\*\*/g,`<strong>$1</strong>`).replace(/__([^_\n]+)__/g,`<strong>$1</strong>`).replace(/(^|[^*\w])\*([^*\n]+)\*/g,`$1<em>$2</em>`).replace(/(^|[^_\w])_([^_\n]+)_(?![\w_])/g,`$1<em>$2</em>`).replace(p,(e,n)=>`<code>${t[Number(n)]}</code>`)}var oe=`pr-helper-selection-popover`,se=`pr-helper-selection-popover-expanded`,ce=`pr-helper-selection-copy-done`,le=8,h=8,ue=1e3,de=`Copy selected text`,fe=`Copy`,pe=`Copied`,me=`pr-helper-selection-popover-flat`,g=null;function he(e){return`<button type="button" class="pr-helper-selection-menu-item" data-selection-action="${s(e.id)}">${s(e.label)}</button>`}function ge(e){let t=new Map;for(let n of e){if(!n.section)continue;let e=t.get(n.section);e?e.push(n):t.set(n.section,[n])}return`${e.filter(e=>!e.section).map(he).join(``)}${[...t].map(([e,t])=>`
5
+ `),blocks:t}}function ie(e,t){return e.replace(ee,(e,n)=>`<div class="${c}"><pre><code>${s(t[Number(n)])}</code></pre><button type="button" class="${l}" aria-label="Copy code">Copy</button></div>`)}function ae(e){let t=[],n=[],r=[],i=null,a=()=>{n.length&&t.push(`<p>${m(n.join(` `))}</p>`),r.length&&t.push(`<blockquote>${m(r.join(` `))}</blockquote>`),i&&t.push(`<${i.tag}>${i.items.map(e=>`<li>${m(e)}</li>`).join(``)}</${i.tag}>`),n=[],r=[],i=null};for(let o of e.split(`
6
+ `)){let e=o.trim();if(!e){a();continue}if(f.test(e)){a(),t.push(e);continue}if(/^(?:-{3,}|\*{3,}|_{3,})$/.test(e)){a(),t.push(`<hr>`);continue}let s=e.match(/^(#{1,6})\s+(.+)$/);if(s){a();let e=Math.min(s[1].length,3)+3;t.push(`<h${e}>${m(s[2])}</h${e}>`);continue}let c=e.match(/^[-*+]\s+(.+)$/);if(c){i?.tag!==`ul`&&(a(),i={tag:`ul`,items:[]}),i.items.push(c[1]);continue}let l=e.match(/^\d{1,9}[.)]\s+(.+)$/);if(l){i?.tag!==`ol`&&(a(),i={tag:`ol`,items:[]}),i.items.push(l[1]);continue}let u=e.match(/^>\s?(.*)$/);if(u){r.length||a(),r.push(u[1]);continue}if(i&&i.items.length){i.items[i.items.length-1]+=` ${e}`;continue}if(r.length){r[r.length-1]+=` ${e}`;continue}n.push(e)}return a(),t.join(``)}function m(e){let t=[];return s(e).replace(/`([^`\n]+)`/g,(e,n)=>(t.push(n),`${d}${t.length-1}${d}`)).replace(/(?<!!)\[([^\]\n]+)\]\(([^)\s]+)\)/g,(e,t,n)=>ne.test(n)?`<a href="${n}" target="_blank" rel="noopener noreferrer">${t}</a>`:e).replace(/\*\*([^*\n]+)\*\*/g,`<strong>$1</strong>`).replace(/__([^_\n]+)__/g,`<strong>$1</strong>`).replace(/(^|[^*\w])\*([^*\n]+)\*/g,`$1<em>$2</em>`).replace(/(^|[^_\w])_([^_\n]+)_(?![\w_])/g,`$1<em>$2</em>`).replace(te,(e,n)=>`<code>${t[Number(n)]}</code>`)}async function oe(e){try{return await navigator.clipboard.writeText(e),!0}catch(t){return console.warn(`PR Helper: clipboard write failed, falling back to execCommand`,t),se(e)}}function se(e){let t=document.createElement(`textarea`);t.value=e,t.setAttribute(`aria-hidden`,`true`),t.style.cssText=`position:fixed;top:-9999px;left:-9999px;opacity:0;`,document.body.appendChild(t);try{return t.select(),document.execCommand(`copy`)}catch(e){return console.warn(`PR Helper: clipboard fallback failed`,e),!1}finally{t.remove()}}var h=`pr-helper-msg-copy`,ce=`pr-helper-chat-actions`,le=`data-message-id`,ue=`data-copy-source`,de={idle:{icon:`<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>`,label:``,aria:`Copy message`},copied:{icon:`<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>`,label:`Copied`,aria:`Copied`},failed:{icon:`<path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>`,label:`Copy failed`,aria:`Copy failed`}};function fe(e){return ge(`${ue}="${s(e)}"`)}var pe=`pr-helper-finding-copy`,me=`data-copy-idle-label`,he=`data-copy-idle-aria`;function ge(e,t){let{icon:n}=de.idle,r=t?.label??de.idle.label,i=t?.aria??de.idle.aria,a=t?` ${me}="${s(r)}" ${he}="${s(i)}"`:``,o=`<button type="button" class="${t?`${h} ${pe}`:h}" ${e}${a}${t?` data-tip="${s(t.tip)}"`:``} aria-label="${s(i)}"><span class="${h}-icon" aria-hidden="true">${ve(n)}</span><span class="${h}-label"${r?``:` hidden`}>${s(r)}</span></button>`;return t?o:`<div class="${ce}">${o}</div>`}function _e(e,t){let n=de[t],r=t===`idle`?{...n,label:e.getAttribute(me)??n.label,aria:e.getAttribute(he)??n.aria}:n,i=e.querySelector(`.${h}-icon`),a=e.querySelector(`.${h}-label`);i&&(i.innerHTML=ve(r.icon)),a instanceof HTMLElement&&(a.textContent=r.label,a.hidden=r.label===``),e.setAttribute(`aria-label`,r.aria),e.classList.toggle(`copied`,t===`copied`),e.classList.toggle(`failed`,t===`failed`)}function ve(e){return`<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor">${e}</svg>`}var ye=1400,be=`Copy`,xe=`Copied`,Se=/Mac|iPhone|iPad/.test(navigator.userAgent)?`Press ⌘C`:`Press Ctrl C`,g=new WeakMap;function Ce(e,t={}){let n=e=>{let n=e.target;if(!(n instanceof Element))return;let r=n.closest(`.${l}`),i=r?null:n.closest(`.${h}`);!r&&!i||(e.preventDefault(),e.stopPropagation(),r?Ee(r):i&&we(i,t.messageSource))};return e.addEventListener(`click`,n,!0),()=>e.removeEventListener(`click`,n,!0)}async function we(e,t){let n=Te(e,t);Oe(e,n!==null&&await oe(n)?`copied`:`failed`)}function Te(e,t){let n=e.getAttribute(ue);if(n!==null)return n;let r=e.getAttribute(le);return r&&t?t(r):null}async function Ee(e){let t=e.parentElement?.querySelector(`pre code`),n=t?await oe(t.textContent??``):!1;!n&&t&&De(t),ke(e,n?xe:Se,n)}function De(e){let t=window.getSelection();if(!t)return;let n=document.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n)}function Oe(e,t){let n=g.get(e);n&&window.clearTimeout(n),_e(e,t),g.set(e,window.setTimeout(()=>{_e(e,`idle`),g.delete(e)},ye))}function ke(e,t,n){let r=g.get(e);r&&window.clearTimeout(r),e.textContent=t,e.classList.toggle(`copied`,n),g.set(e,window.setTimeout(()=>{e.textContent=be,e.classList.remove(`copied`),g.delete(e)},ye))}var Ae=`pr-helper-selection-popover`,je=`pr-helper-selection-popover-expanded`,Me=`pr-helper-selection-copy-done`,Ne=8,_=8,Pe=1e3,Fe=`Copy selected text`,Ie=`Copy`,Le=`Copied`,Re=`pr-helper-selection-popover-flat`,v=null;function ze(e){return`<button type="button" class="pr-helper-selection-menu-item" data-selection-action="${s(e.id)}">${s(e.label)}</button>`}function Be(e){let t=new Map;for(let n of e){if(!n.section)continue;let e=t.get(n.section);e?e.push(n):t.set(n.section,[n])}return`${e.filter(e=>!e.section).map(ze).join(``)}${[...t].map(([e,t])=>`
7
7
  <div class="pr-helper-selection-menu-group">
8
8
  <div class="pr-helper-selection-menu-heading">${s(e)}</div>
9
- <div class="pr-helper-selection-menu-group-items">${t.map(he).join(``)}</div>
10
- </div>`).join(``)}`}function _e(e){if(e.layout===`flat`)return ve(e);let t=ge(e.actions);return`
9
+ <div class="pr-helper-selection-menu-group-items">${t.map(ze).join(``)}</div>
10
+ </div>`).join(``)}`}function Ve(e){if(e.layout===`flat`)return He(e);let t=Be(e.actions);return`
11
11
  <div class="pr-helper-selection-bar">
12
12
  <button type="button" class="pr-helper-selection-trigger" data-selection-open>
13
13
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="12" height="12" fill="currentColor" aria-hidden="true">
@@ -15,7 +15,7 @@ import{c as e,i as t,t as n}from"./chunk-BeL0x-wt.js";import{_ as r,d as i,g as
15
15
  </svg>
16
16
  <span>${s(e.triggerLabel??`Ask`)}</span>
17
17
  </button>
18
- <button type="button" class="pr-helper-selection-copy" data-selection-copy aria-label="${de}" aria-describedby="pr-helper-selection-tip">
18
+ <button type="button" class="pr-helper-selection-copy" data-selection-copy aria-label="${Fe}" aria-describedby="pr-helper-selection-tip">
19
19
  <svg class="pr-helper-selection-copy-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true">
20
20
  <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"/>
21
21
  <path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"/>
@@ -24,43 +24,43 @@ import{c as e,i as t,t as n}from"./chunk-BeL0x-wt.js";import{_ as r,d as i,g as
24
24
  <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L1.22 8.28a.75.75 0 0 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"/>
25
25
  </svg>
26
26
  </button>
27
- <span class="pr-helper-selection-tip" id="pr-helper-selection-tip" role="tooltip">${de}</span>
27
+ <span class="pr-helper-selection-tip" id="pr-helper-selection-tip" role="tooltip">${Fe}</span>
28
28
  </div>
29
29
  <div class="pr-helper-selection-menu">${t}</div>
30
- `}function ve(e){return`<div class="pr-helper-selection-menu">
31
- ${ge(e.actions)}
32
- <button type="button" class="pr-helper-selection-menu-item pr-helper-selection-copy-item" data-selection-copy>${fe}</button>
33
- </div>`}function ye(e,t){let{width:n,height:r}=e.getBoundingClientRect(),i=t.top-r-le,a=i>=h?i:Math.min(t.bottom+le,window.innerHeight-r-h),o=Math.max(h,Math.min(t.left,window.innerWidth-n-h));e.style.top=`${Math.max(h,a)}px`,e.style.left=`${o}px`}function _(){v&&=(window.clearTimeout(v),0),g?.popover.remove(),g=null}var v=0;function be(e){let t=e.querySelector(`.pr-helper-selection-tip`),n=e.querySelector(`.pr-helper-selection-copy-item`);e.classList.add(ce),t&&(t.textContent=pe),n&&(n.textContent=pe),v&&window.clearTimeout(v),v=window.setTimeout(()=>xe(e),ue)}function xe(e){v&&=(window.clearTimeout(v),0),e.classList.remove(ce);let t=e.querySelector(`.pr-helper-selection-tip`);t&&(t.textContent=de);let n=e.querySelector(`.pr-helper-selection-copy-item`);n&&(n.textContent=fe)}async function Se(e,t){try{await navigator.clipboard.writeText(t)}catch(e){console.warn(`PR Helper: clipboard write failed, falling back to execCommand`,e);let t=!1;try{t=document.execCommand(`copy`)}catch(e){console.warn(`PR Helper: clipboard fallback failed`,e)}if(!t)return}be(e)}function Ce(e,t){let n=window.getSelection();if(!n||n.isCollapsed||n.rangeCount===0)return null;let r=n.toString().trim();if(!r)return null;let i=n.getRangeAt(0);if(!e.contains(i.commonAncestorContainer))return null;if(t.onlyWithin||t.ignoreWithin){let e=i.commonAncestorContainer,n=e instanceof HTMLElement?e:e.parentElement;if(t.onlyWithin&&!n?.closest(t.onlyWithin)||t.ignoreWithin&&n?.closest(t.ignoreWithin))return null}let a=i.getBoundingClientRect();return a.width===0&&a.height===0?null:{text:r,rect:a}}function we(e,t){let n={},r=()=>{let r=Ce(e,t);if(!r){(!g||g.owner===n)&&_();return}if(g&&g.owner!==n&&_(),g)g.popover.classList.remove(se),xe(g.popover),g.text=r.text;else{let i=document.createElement(`div`);i.className=t.layout===`flat`?`${oe} ${me}`:oe,i.innerHTML=_e(t),i.addEventListener(`mousedown`,e=>e.preventDefault()),i.addEventListener(`click`,n=>{let r=n.target;if(r.closest(`[data-selection-copy]`)){g?.text&&Se(i,g.text);return}if(r.closest(`[data-selection-open]`)){i.classList.add(se);let n=Ce(e,t);ye(i,n?.rect??i.getBoundingClientRect());return}let a=r.closest(`[data-selection-action]`)?.dataset.selectionAction;if(!a||!g)return;let o=g.text;_(),t.onChoose(a,o)}),document.body.appendChild(i),g={popover:i,text:r.text,owner:n}}ye(g.popover,r.rect)},i=e=>{g&&e.target instanceof Node&&g.popover.contains(e.target)||window.setTimeout(r,0)},a=e=>{(e.shiftKey||e.key===`Shift`)&&r()},o=()=>{if(!g)return;let e=window.getSelection();(!e||e.isCollapsed)&&_()},s=e=>{e.key===`Escape`&&_()},c=()=>_();return document.addEventListener(`mouseup`,i,!0),document.addEventListener(`keyup`,a,!0),e.addEventListener(`scroll`,c,!0),document.addEventListener(`selectionchange`,o),document.addEventListener(`keydown`,s),window.addEventListener(`scroll`,c,!0),()=>{document.removeEventListener(`mouseup`,i,!0),document.removeEventListener(`keyup`,a,!0),e.removeEventListener(`scroll`,c,!0),document.removeEventListener(`selectionchange`,o),document.removeEventListener(`keydown`,s),window.removeEventListener(`scroll`,c,!0),_()}}async function Te(e){try{return await navigator.clipboard.writeText(e),!0}catch(t){return console.warn(`PR Helper: clipboard write failed, falling back to execCommand`,t),Ee(e)}}function Ee(e){let t=document.createElement(`textarea`);t.value=e,t.setAttribute(`aria-hidden`,`true`),t.style.cssText=`position:fixed;top:-9999px;left:-9999px;opacity:0;`,document.body.appendChild(t);try{return t.select(),document.execCommand(`copy`)}catch(e){return console.warn(`PR Helper: clipboard fallback failed`,e),!1}finally{t.remove()}}var y=`pr-helper-msg-copy`,De=`pr-helper-chat-actions`,Oe=`data-message-id`,ke=`data-copy-source`,Ae={idle:{icon:`<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>`,label:``,aria:`Copy message`},copied:{icon:`<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>`,label:`Copied`,aria:`Copied`},failed:{icon:`<path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>`,label:`Copy failed`,aria:`Copy failed`}};function je(e){return Fe(`${ke}="${s(e)}"`)}var Me=`pr-helper-finding-copy`,Ne=`data-copy-idle-label`,Pe=`data-copy-idle-aria`;function Fe(e,t){let{icon:n}=Ae.idle,r=t?.label??Ae.idle.label,i=t?.aria??Ae.idle.aria,a=t?` ${Ne}="${s(r)}" ${Pe}="${s(i)}"`:``,o=`<button type="button" class="${t?`${y} ${Me}`:y}" ${e}${a}${t?` data-tip="${s(t.tip)}"`:``} aria-label="${s(i)}"><span class="${y}-icon" aria-hidden="true">${Le(n)}</span><span class="${y}-label"${r?``:` hidden`}>${s(r)}</span></button>`;return t?o:`<div class="${De}">${o}</div>`}function Ie(e,t){let n=Ae[t],r=t===`idle`?{...n,label:e.getAttribute(Ne)??n.label,aria:e.getAttribute(Pe)??n.aria}:n,i=e.querySelector(`.${y}-icon`),a=e.querySelector(`.${y}-label`);i&&(i.innerHTML=Le(r.icon)),a instanceof HTMLElement&&(a.textContent=r.label,a.hidden=r.label===``),e.setAttribute(`aria-label`,r.aria),e.classList.toggle(`copied`,t===`copied`),e.classList.toggle(`failed`,t===`failed`)}function Le(e){return`<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor">${e}</svg>`}var Re=1400,ze=`Copy`,Be=`Copied`,Ve=/Mac|iPhone|iPad/.test(navigator.userAgent)?`Press ⌘C`:`Press Ctrl C`,b=new WeakMap;function He(e,t={}){let n=e=>{let n=e.target;if(!(n instanceof Element))return;let r=n.closest(`.${l}`),i=r?null:n.closest(`.${y}`);!r&&!i||(e.preventDefault(),e.stopPropagation(),r?Ge(r):i&&Ue(i,t.messageSource))};return e.addEventListener(`click`,n,!0),()=>e.removeEventListener(`click`,n,!0)}async function Ue(e,t){let n=We(e,t);qe(e,n!==null&&await Te(n)?`copied`:`failed`)}function We(e,t){let n=e.getAttribute(ke);if(n!==null)return n;let r=e.getAttribute(Oe);return r&&t?t(r):null}async function Ge(e){let t=e.parentElement?.querySelector(`pre code`),n=t?await Te(t.textContent??``):!1;!n&&t&&Ke(t),Je(e,n?Be:Ve,n)}function Ke(e){let t=window.getSelection();if(!t)return;let n=document.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n)}function qe(e,t){let n=b.get(e);n&&window.clearTimeout(n),Ie(e,t),b.set(e,window.setTimeout(()=>{Ie(e,`idle`),b.delete(e)},Re))}function Je(e,t,n){let r=b.get(e);r&&window.clearTimeout(r),e.textContent=t,e.classList.toggle(`copied`,n),b.set(e,window.setTimeout(()=>{e.textContent=ze,e.classList.remove(`copied`),b.delete(e)},Re))}var Ye=[{id:`explain`,label:`Explain`,instruction:`Explain this in simpler terms.`},{id:`is-problem`,label:`Is this actually a problem?`,instruction:`Is this actually a problem? Be specific about when it would and would not matter.`},{id:`better-implementation`,label:`Suggest a better implementation`,instruction:`Suggest a better implementation for this.`},{id:`author-question`,label:`Generate a question for the author`,instruction:`Generate a question I could ask the author about this.`},{id:`custom`,label:`Ask a question`}],Xe=[{id:`add-to-chat`,label:`Add to chat`}],Ze=800;function Qe(e){let t=e.replace(/\r\n/g,`
30
+ `}function He(e){return`<div class="pr-helper-selection-menu">
31
+ ${Be(e.actions)}
32
+ <button type="button" class="pr-helper-selection-menu-item pr-helper-selection-copy-item" data-selection-copy>${Ie}</button>
33
+ </div>`}function Ue(e,t){let{width:n,height:r}=e.getBoundingClientRect(),i=t.top-r-Ne,a=i>=_?i:Math.min(t.bottom+Ne,window.innerHeight-r-_),o=Math.max(_,Math.min(t.left,window.innerWidth-n-_));e.style.top=`${Math.max(_,a)}px`,e.style.left=`${o}px`}function y(){b&&=(window.clearTimeout(b),0),v?.popover.remove(),v=null}var b=0;function We(e){let t=e.querySelector(`.pr-helper-selection-tip`),n=e.querySelector(`.pr-helper-selection-copy-item`);e.classList.add(Me),t&&(t.textContent=Le),n&&(n.textContent=Le),b&&window.clearTimeout(b),b=window.setTimeout(()=>Ge(e),Pe)}function Ge(e){b&&=(window.clearTimeout(b),0),e.classList.remove(Me);let t=e.querySelector(`.pr-helper-selection-tip`);t&&(t.textContent=Fe);let n=e.querySelector(`.pr-helper-selection-copy-item`);n&&(n.textContent=Ie)}async function Ke(e,t){try{await navigator.clipboard.writeText(t)}catch(e){console.warn(`PR Helper: clipboard write failed, falling back to execCommand`,e);let t=!1;try{t=document.execCommand(`copy`)}catch(e){console.warn(`PR Helper: clipboard fallback failed`,e)}if(!t)return}We(e)}function qe(e,t){let n=window.getSelection();if(!n||n.isCollapsed||n.rangeCount===0)return null;let r=n.toString().trim();if(!r)return null;let i=n.getRangeAt(0);if(!e.contains(i.commonAncestorContainer))return null;if(t.onlyWithin||t.ignoreWithin){let e=i.commonAncestorContainer,n=e instanceof HTMLElement?e:e.parentElement;if(t.onlyWithin&&!n?.closest(t.onlyWithin)||t.ignoreWithin&&n?.closest(t.ignoreWithin))return null}let a=i.getBoundingClientRect();return a.width===0&&a.height===0?null:{text:r,rect:a}}function Je(e,t){let n={},r=()=>{let r=qe(e,t);if(!r){(!v||v.owner===n)&&y();return}if(v&&v.owner!==n&&y(),v)v.popover.classList.remove(je),Ge(v.popover),v.text=r.text;else{let i=document.createElement(`div`);i.className=t.layout===`flat`?`${Ae} ${Re}`:Ae,i.innerHTML=Ve(t),i.addEventListener(`mousedown`,e=>e.preventDefault()),i.addEventListener(`click`,n=>{let r=n.target;if(r.closest(`[data-selection-copy]`)){v?.text&&Ke(i,v.text);return}if(r.closest(`[data-selection-open]`)){i.classList.add(je);let n=qe(e,t);Ue(i,n?.rect??i.getBoundingClientRect());return}let a=r.closest(`[data-selection-action]`)?.dataset.selectionAction;if(!a||!v)return;let o=v.text;y(),t.onChoose(a,o)}),document.body.appendChild(i),v={popover:i,text:r.text,owner:n}}Ue(v.popover,r.rect)},i=e=>{v&&e.target instanceof Node&&v.popover.contains(e.target)||window.setTimeout(r,0)},a=e=>{(e.shiftKey||e.key===`Shift`)&&r()},o=()=>{if(!v)return;let e=window.getSelection();(!e||e.isCollapsed)&&y()},s=e=>{e.key===`Escape`&&y()},c=()=>y();return document.addEventListener(`mouseup`,i,!0),document.addEventListener(`keyup`,a,!0),e.addEventListener(`scroll`,c,!0),document.addEventListener(`selectionchange`,o),document.addEventListener(`keydown`,s),window.addEventListener(`scroll`,c,!0),()=>{document.removeEventListener(`mouseup`,i,!0),document.removeEventListener(`keyup`,a,!0),e.removeEventListener(`scroll`,c,!0),document.removeEventListener(`selectionchange`,o),document.removeEventListener(`keydown`,s),window.removeEventListener(`scroll`,c,!0),y()}}var x=[{id:`explain`,label:`Explain`,instruction:`Explain this in simpler terms.`},{id:`is-problem`,label:`Is this actually a problem?`,instruction:`Is this actually a problem? Be specific about when it would and would not matter.`},{id:`better-implementation`,label:`Suggest a better implementation`,instruction:`Suggest a better implementation for this.`},{id:`author-question`,label:`Generate a question for the author`,instruction:`Generate a question I could ask the author about this.`},{id:`custom`,label:`Ask a question`}],Ye=[{id:`explain-detail`,label:`Explain`,instruction:`Explain this, keeping the technical detail.`},{id:`explain`,label:`Explain simply`,instruction:`Explain this in simpler terms.`},x.find(e=>e.id===`is-problem`),{id:`why-matters`,label:`Why does this matter?`,instruction:`Why does this matter? Say who or what it affects, and when.`},x.find(e=>e.id===`better-implementation`),x.find(e=>e.id===`author-question`),x.find(e=>e.id===`custom`)];function Xe(e){return![...x,...Ye,...Ze].find(t=>t.id===e)?.instruction}var Ze=[{id:`add-to-chat`,label:`Add to chat`}],Qe=800;function $e(e,t={}){let n=t.maxChars??Qe,r=e.replace(/\r\n/g,`
34
34
  `).split(`
35
- `).map(e=>e.replace(/\s+$/,``));for(;t.length&&!t[0].trim();)t.shift();for(;t.length&&!t[t.length-1].trim();)t.pop();let n=t.filter(e=>e.trim()).map(e=>e.match(/^[ \t]*/)[0].length),r=n.length?Math.min(...n):0,i=t.map(e=>e.slice(r)).join(`
35
+ `).map(e=>e.replace(/\s+$/,``));for(;r.length&&!r[0].trim();)r.shift();for(;r.length&&!r[r.length-1].trim();)r.pop();let i=r.filter(e=>e.trim()).map(e=>e.match(/^[ \t]*/)[0].length),a=i.length?Math.min(...i):0,o=r.map(e=>e.slice(a)).join(`
36
36
  `).replace(/\n{3,}/g,`
37
37
 
38
- `);return i.trim()?(i.length>Ze?`${i.slice(0,Ze).trimEnd()}…`:i).split(`
38
+ `);return o.trim()?(o.length>n?`${o.slice(0,n).trimEnd()}…`:o).split(`
39
39
  `).map(e=>`> ${e}`.trimEnd()).join(`
40
- `):``}function $e(e,t){let n=Qe(e);if(!n)return null;let r=[...Ye,...Xe].find(e=>e.id===t);return r?r.instruction?`${n}\n\n${r.instruction}`:`${n}\n\n`:null}var et=`saved:`,tt=`Your prompts`;function nt(e){return`${et}${e}`}function rt(e){return e.startsWith(`saved:`)?e.slice(6):null}function it(e){return e.reviewerClosed>0?`dealt with`:`resolved`}({claude:`Claude Code`,codex:`Codex`,gemini:`Gemini CLI`}).claude;var at=`Dismissed by you — you decided this finding needs no action. It stops counting towards what is left, and stays here so the decision is visible rather than lost.`;function ot(e,t,n=`resolved`){return t===0?`<span class="pr-helper-questions-progress-check" aria-hidden="true">\u2713</span><span class="pr-helper-questions-progress-count">All ${e} issues ${n}</span>`:`<span class="pr-helper-questions-progress-count">${t} of ${e} still open</span>`}function st(e){let t=e.done-e.reviewerClosed;return e.reviewerClosed===0?`Resolved by the new commits (${e.done})`:t===0?`Dismissed by you (${e.done})`:`Dealt with (${e.done})`}function ct(e,t){return t===0?`<span class="pr-helper-questions-progress-check" aria-hidden="true">✓</span><span class="pr-helper-questions-progress-count">All ${e} questions answered</span>`:`<span class="pr-helper-questions-progress-count">${t} of ${e} unanswered</span>`}function lt(e){let t=[...document.querySelectorAll(`[data-guide-detail]`)],n=t.find(t=>t.dataset.guideDetail===e);if(!n)return null;for(let e of t)e.hidden=e!==n;return n}function ut(e){return e instanceof Element&&e.closest(`[data-guide-jump]`)?.dataset.guideJump||null}function dt(e){for(let t of document.querySelectorAll(`[data-goto-section]`))t.setAttribute(`aria-current`,String(t.dataset.gotoSection===e))}function ft(){for(let e of document.querySelectorAll(`.prb-rail [data-goto-section]`))e.setAttribute(`aria-current`,`false`)}function pt(e,t){let n=e.trim();return n?`${n}\n\n${t}`:t}var mt=[`progress`,`overview`,`guide`,`issues`,`questions`,`files`,`prcontext`,`diagram`,`kiss`,`kissrecs`],ht=`#theme-`;function gt(e){return`#${e}`}function _t(e){return`${ht}${encodeURIComponent(e)}`}function vt(e){return e.kind===`view`?gt(e.view):_t(e.sectionId)}function yt(e){if(e.startsWith(ht)){let t=e.slice(7);if(!t)return null;try{return{kind:`section`,sectionId:decodeURIComponent(t)}}catch{return null}}let t=e.replace(/^#/,``);return mt.includes(t)?{kind:`view`,view:t}:null}function bt(e){if(!Number.isFinite(e))return``;let t=Math.round((Date.now()-e)/6e4);if(t<1)return`just now`;if(t<60)return`${t} minute${t===1?``:`s`} ago`;let n=Math.round(t/60);if(n<24)return`${n} hour${n===1?``:`s`} ago`;let r=Math.round(n/24);return`${r} day${r===1?``:`s`} ago`}function xt(){return`<button type="button" class="prb-update-btn" data-review-update>Update review</button>`}var St=`Updating this review checks the latest commits and refreshes the PR conversation. Your progress and Buddy AI history will be kept.`;function Ct(e){return`<details class="prb-update-alt">
40
+ `):``}function et(e,t,n={}){let r=$e(e,n);if(!r)return null;let i=[...Ye,...x,...Ze].find(e=>e.id===t);return i?i.instruction?`${r}\n\n${i.instruction}`:`${r}\n\n`:null}Object.freeze([{id:`default-assumptions`,name:`What does it assume?`,prompt:`What assumptions does this change make? Say which are stated, which are implied, and what happens if one turns out to be wrong.`},{id:`default-explain-educational`,name:`Teach me this`,prompt:`Explain this in an educational way: the concepts it relies on, why it is built this way, and what I should take away from it.`},{id:`default-what-could-go-wrong`,name:`What could go wrong?`,prompt:`What could go wrong here? Think about edge cases, failure modes and the existing callers this could break.`},{id:`default-walkthrough`,name:`Walk me through it`,prompt:`Walk me through the implementation step by step, in the order the code runs.`},{id:`default-verify-manually`,name:`What should I verify?`,prompt:`What should I verify manually before approving this, and how would I check each one?`}].map(e=>Object.freeze(e)));var tt=`saved:`,nt=`Your prompts`;function rt(e){return`${tt}${e}`}function it(e){return e.startsWith(`saved:`)?e.slice(6):null}var at=[`progress`,`overview`,`guide`,`issues`,`questions`,`files`,`prcontext`,`diagram`,`kiss`,`kissrecs`],ot=`#theme-`,st=[`buddy`,`issues`,`questions`,`files`,`guide`],ct=`&focus=`;function lt(e){return`#${e}`}function ut(e){return`${ot}${encodeURIComponent(e)}`}function S(e){let t=e.kind===`view`?lt(e.view):ut(e.sectionId);return e.focus?`${t}${ct}${e.focus}`:t}function dt(e){let{focus:t,...n}=e;return n}function ft(e,t){return e.kind!==`view`||e.view!==`guide`||!t?e:{kind:`section`,sectionId:t,...e.focus?{focus:e.focus}:{}}}function pt(e){return st.includes(e)}function mt(e){let t=e.indexOf(ct);if(t===-1)return ht(e);let n=ht(e.slice(0,t));if(!n)return null;let r=e.slice(t+7);return pt(r)?{...n,focus:r}:n}function ht(e){if(e.startsWith(ot)){let t=e.slice(7);if(!t)return null;try{return{kind:`section`,sectionId:decodeURIComponent(t)}}catch{return null}}let t=e.replace(/^#/,``);return at.includes(t)?{kind:`view`,view:t}:null}var gt=`pushedFocus`;function _t(e){let{[gt]:t,...n}=e;return n}function vt(e,t){return e.kind===`view`&&t.kind===`view`?e.view===t.view:e.kind===`section`&&t.kind===`section`&&e.sectionId===t.sectionId}function yt(e,t,n){if(e.focus===t)return;let r={...dt(_t(e)),focus:t};e.focus&&n.history.state?.[gt]?n.history.replaceState({...r,[gt]:!0},``,S(r)):n.history.pushState({...r,[gt]:!0},``,S(r)),n.apply(r)}function bt(e,t){if(!e.focus)return;if(t.history.state?.[gt]){t.history.back();return}let n=dt(_t(e));t.history.replaceState(n,``,S(n)),t.apply(n)}function xt(e,t,n){if(!n||e.key!==`Escape`||e.defaultPrevented||t.querySelector(`dialog[open], [data-menu-panel]:not([hidden]), [data-analysis-details][open], .pr-helper-selection-popover`))return!1;let r=e.target;return!(r?.closest?.(`[data-ask-resize]`)||r instanceof HTMLInputElement&&r.value!==``)}function St(e,t,n){e&&(n?e.dataset.focus=n:delete e.dataset.focus);for(let e of t.querySelectorAll(`[data-focus-toggle]`)){let t=e.dataset.focusToggle===n,r=e.dataset.focusName??`this`,i=t?`Exit focus on ${r}`:`Expand ${r}`;e.setAttribute(`aria-pressed`,String(t)),e.setAttribute(`aria-label`,i),e.setAttribute(`title`,t?`${i} (Esc)`:i)}}function Ct(e,t,n,r){let i=n===`finding`?{maxChars:1/0}:{},a=it(e);if(a===null)return et(t,e,i);let o=r(a);if(!o)return null;let s=$e(t,i);return s?`${s}\n\n${o}`:null}function wt(e,t,n){let r=Ct(e,t.text,t.context,n.savedPrompt);if(!r)return null;let i=Xe(e)||it(e)!==null;return t.context===`selection`||i?(n.stage(r),`staged`):(n.send(r),`sent`)}var Tt=`button:not([disabled])`;function Et(e){return e.querySelector(`[data-menu-panel]`)}function Dt(e){return e.querySelector(`[data-menu-trigger]`)}function Ot(e){let t=Et(e);return t?[...t.querySelectorAll(Tt)].filter(e=>!e.closest(`[hidden]`)):[]}function kt(e,t={}){let n=null,r=(e,r={})=>{let i=Et(e);if(!i||i.hidden)return;i.hidden=!0;let a=Dt(e);a?.setAttribute(`aria-expanded`,`false`),n===e&&(n=null),t.onClose?.(e),r.returnFocus&&a?.focus()},i=()=>{for(let t of e.querySelectorAll(`[data-menu]`))r(t)},a=(e,r)=>{let a=Et(e);a&&(i(),t.onOpen?.(e),a.hidden=!1,Dt(e)?.setAttribute(`aria-expanded`,`true`),n=e,r&&Ot(e)[0]?.focus())};return e.addEventListener(`click`,e=>{let t=e.target,o=t?.closest?.(`[data-menu]`)??null;if(!o){i();return}if(t?.closest(`[data-menu-trigger]`)){let t=e.detail===0;Et(o)?.hidden?a(o,t):r(o);return}n&&n!==o&&r(n)}),e.addEventListener(`keydown`,e=>{if(!n)return;let t=n;if(e.key===`Escape`){e.preventDefault(),r(t,{returnFocus:!0});return}if(!t.contains(e.target))return;if(e.key===`Tab`){r(t);return}let i=Ot(t);if(i.length===0)return;let a=i.indexOf(e.target),o=e.key===`ArrowDown`?i[(a+1)%i.length]:e.key===`ArrowUp`?i[(a-1+i.length)%i.length]:e.key===`Home`?i[0]:e.key===`End`?i[i.length-1]:null;o&&(e.preventDefault(),o.focus())}),{close:r,closeAll:i}}function At(e){return e.reviewerClosed>0?`dealt with`:`resolved`}({claude:`Claude Code`,codex:`Codex`,gemini:`Gemini CLI`}).claude;var jt=`Dismissed by you — you decided this finding needs no action. It stops counting towards what is left, and stays here so the decision is visible rather than lost.`;function Mt(e,t,n=`resolved`){return t===0?`<span class="pr-helper-questions-progress-check" aria-hidden="true">\u2713</span><span class="pr-helper-questions-progress-count">All ${e} issues ${n}</span>`:`<span class="pr-helper-questions-progress-count">${t} of ${e} still open</span>`}function Nt(e){let t=e.done-e.reviewerClosed;return e.reviewerClosed===0?`Resolved by the new commits (${e.done})`:t===0?`Dismissed by you (${e.done})`:`Dealt with (${e.done})`}function Pt(e,t){return t===0?`<span class="pr-helper-questions-progress-check" aria-hidden="true">✓</span><span class="pr-helper-questions-progress-count">All ${e} questions answered</span>`:`<span class="pr-helper-questions-progress-count">${t} of ${e} unanswered</span>`}function Ft(e){let t=[...document.querySelectorAll(`[data-guide-detail]`)],n=t.find(t=>t.dataset.guideDetail===e);if(!n)return null;for(let e of t)e.hidden=e!==n;return n}function It(e){return e instanceof Element&&e.closest(`[data-guide-jump]`)?.dataset.guideJump||null}function Lt(e){for(let t of document.querySelectorAll(`[data-goto-section]`))t.setAttribute(`aria-current`,String(t.dataset.gotoSection===e))}function Rt(){for(let e of document.querySelectorAll(`.prb-rail [data-goto-section]`))e.setAttribute(`aria-current`,`false`)}function zt(e,t){let n=e.trim();return n?`${n}\n\n${t}`:t}function Bt(e){if(!Number.isFinite(e))return``;let t=Math.round((Date.now()-e)/6e4);if(t<1)return`just now`;if(t<60)return`${t} minute${t===1?``:`s`} ago`;let n=Math.round(t/60);if(n<24)return`${n} hour${n===1?``:`s`} ago`;let r=Math.round(n/24);return`${r} day${r===1?``:`s`} ago`}function Vt(){return`<button type="button" class="prb-update-btn" data-review-update>Update review</button>`}var Ht=`Updating this review checks the latest commits and refreshes the PR conversation. Your progress and Buddy AI history will be kept.`;function Ut(e){return`<details class="prb-update-alt">
41
41
  <summary>Start a new review</summary>
42
42
  <span>A brand new review, with its own findings and its own path through the change. Run <code>${s(e)}</code> in your session.<button type="button" class="prb-fresh-quiet" data-copy-command="${s(e)}">Copy</button></span>
43
- </details>`}var wt=`prreviewbuddy review --fresh`;function Tt(e,t){return e?e.code.state===`fixed`?{label:`Freshness: Fixed`,state:`fixed`}:t?{label:`PR updated`,state:`changed`}:e.code.state===`changed`?{label:e.code.rewritten?`Code rewritten`:`Code changed`,state:`changed`}:e.code.state===`current`?{label:`Review up to date`,state:`current`}:{label:`Freshness unknown`,state:`unknown`}:t?{label:`PR updated`,state:`changed`}:{label:`Check for updates`,state:`unknown`}}function Et(e,t={}){let n=e??(t.remote?Mt(t.remote):null);if(!n)return``;let r=n.code.state===`fixed`?null:t.remote??null,i=n.code.state===`changed`||r!==null,a=n.code.reason===`missing-commit`,o=t.availability?.state===`missing`,c=r?.sha??n.code.latestSha,l=t.dismissedSha!==void 0&&t.dismissedSha===c;if(!t.open&&!o&&(!(i||a)||l))return``;let u=r?Nt(n.code,r):jt(n.code,t.availability??null),d=e?[...u.facts,`checked ${s(bt(n.checkedAt))}`]:u.facts;return`<div class="prb-fresh" data-state="${i||a?`changed`:`quiet`}" role="status">
43
+ </details>`}var Wt=`prreviewbuddy review --fresh`;function Gt(e,t){return e?e.code.state===`fixed`?{label:`Freshness: Fixed`,state:`fixed`}:t?{label:`PR updated`,state:`changed`}:e.code.state===`changed`?{label:e.code.rewritten?`Code rewritten`:`Code changed`,state:`changed`}:e.code.state===`current`?{label:`Review up to date`,state:`current`}:{label:`Freshness unknown`,state:`unknown`}:t?{label:`PR updated`,state:`changed`}:{label:`Check for updates`,state:`unknown`}}function Kt(e,t={}){let n=e??(t.remote?Qt(t.remote):null);if(!n)return``;let r=n.code.state===`fixed`?null:t.remote??null,i=n.code.state===`changed`||r!==null,a=n.code.reason===`missing-commit`,o=t.availability?.state===`missing`,c=r?.sha??n.code.latestSha,l=t.dismissedSha!==void 0&&t.dismissedSha===c;if(!t.open&&!o&&(!(i||a)||l))return``;let u=r?$t(n.code,r):Zt(n.code,t.availability??null),d=e?[...u.facts,`checked ${s(Bt(n.checkedAt))}`]:u.facts;return`<div class="prb-fresh" data-state="${i||a?`changed`:`quiet`}" role="status">
44
44
  <div class="prb-fresh-head">
45
45
  <span class="prb-fresh-dot" data-freshness="${u.state}" aria-hidden="true"></span>
46
46
  <strong class="prb-fresh-title">${s(u.title)}</strong>
47
47
  <span class="prb-fresh-facts">${d.join(` &middot; `)}</span>
48
48
  </div>
49
49
  ${u.consequence?`<p class="prb-fresh-say">${u.consequence}</p>`:``}
50
- ${Dt(n,t,i||a)}
51
- </div>`}function Dt(e,t,n){let r=t.actions&&n,i=n?``:`<button type="button" class="prb-fresh-close" data-fresh-close aria-label="Close">×</button>`;return`<div class="prb-fresh-actions">
52
- ${r?xt():``}
53
- ${r?Ct(wt):``}
50
+ ${qt(n,t,i||a)}
51
+ </div>`}function qt(e,t,n){let r=t.actions&&n,i=n?``:`<button type="button" class="prb-fresh-close" data-fresh-close aria-label="Close">×</button>`;return`<div class="prb-fresh-actions">
52
+ ${r?Vt():``}
53
+ ${r?Ut(Wt):``}
54
54
  ${i}
55
- ${Ot(e,t,n,r===!0)}
56
- </div>`}function Ot(e,t,n,r){let i=[r?s(St):``,t.remote?Pt(e.code):Ft(e.code,e.checkout.reason!==`no-pull-request`),It(e,t.actions===!0),n?`<button type="button" class="prb-fresh-quiet" data-fresh-dismiss="${s(t.remote?.sha??e.code.latestSha??``)}">Dismiss this warning</button>`:``].filter(e=>e!==``);if(i.length===0)return``;let a=`<div class="prb-fresh-notes">${i.map(e=>`<p>${e}</p>`).join(``)}</div>`;return n?`<details class="prb-fresh-more">
55
+ ${Jt(e,t,n,r===!0)}
56
+ </div>`}function Jt(e,t,n,r){let i=[r?s(Ht):``,t.remote?en(e.code):tn(e.code,e.checkout.reason!==`no-pull-request`),nn(e,t.actions===!0),n?`<button type="button" class="prb-fresh-quiet" data-fresh-dismiss="${s(t.remote?.sha??e.code.latestSha??``)}">Dismiss this warning</button>`:``].filter(e=>e!==``);if(i.length===0)return``;let a=`<div class="prb-fresh-notes">${i.map(e=>`<p>${e}</p>`).join(``)}</div>`;return n?`<details class="prb-fresh-more">
57
57
  <summary>More details</summary>
58
58
  ${a}
59
- </details>`:a}function kt(e,t){return e===null?[]:[`${e} file${e===1?``:`s`} ${t}`]}function At(e){return e?`<code title="${s(e)}">${s(e.slice(0,7))}</code>`:``}function x(e){return e?[`reviewed ${At(e)}`]:[]}function jt(e,t){if(e.state===`fixed`)return{state:`fixed`,title:`Freshness: Fixed`,facts:x(e.reviewedSha),consequence:t?.state===`missing`?`That commit is no longer in this repository. The review still reads in full, but it cannot be analysed again until the commit is back.`:`This review is of one commit, and a commit does not change, so these findings keep describing it.`};if(e.state===`current`)return{state:`current`,title:`Review up to date`,facts:x(e.reviewedSha),consequence:``};if(e.state===`changed`){if(e.rewritten)return{state:`changed`,title:`Code rewritten`,facts:[...x(e.reviewedSha),...kt(e.changedFiles,`differ`)],consequence:`The branch was rebased or amended, so this review describes older code.`};let t=e.newCommits===null?[]:[`${e.newCommits} new commit${e.newCommits===1?``:`s`}`];return{state:`changed`,title:`Code changed`,facts:[...x(e.reviewedSha),...t,...kt(e.changedFiles,`changed`)],consequence:`New commits landed, so the lines these findings cite may have moved.`}}switch(e.reason){case`uncommitted`:return{state:`unknown`,title:`Cannot be compared`,facts:x(e.reviewedSha),consequence:`This review read uncommitted work and nothing recorded what the working tree held, so whether the files still match cannot be told from here.`};case`missing-commit`:return{state:`unknown`,title:`Reviewed commit is gone`,facts:x(e.reviewedSha),consequence:`It is not in this repository any more, after a force-push or a branch rebuilt from scratch, so nothing can be measured against it.`};case`no-branch`:return{state:`unknown`,title:`Cannot be compared`,facts:x(e.reviewedSha),consequence:`This review’s branch is not in this repository, which is what a pull request from a fork or a branch deleted after merging looks like, so whether the findings still describe it cannot be told from here.`};default:return{state:`unknown`,title:`Cannot be compared`,facts:[],consequence:`Git could not be read in this checkout.`}}}function Mt(e){return{checkedAt:0,code:{state:`unknown`,reviewedSha:e.reviewedSha,latestSha:null,comparison:null,newCommits:null,changedFiles:null,rewritten:!1,reason:null},checkout:{state:`unknown`,relation:`unknown`,prHeadSha:null,presentLocally:!1,reason:null},conversation:{attached:!1}}}function Nt(e,t){let n=e.state===`changed`&&e.latestSha===t.sha?e:null,r=t.newCommits??n?.newCommits??null,i=n?.rewritten?[]:[r===null?`new commits on the pull request`:`${r} new commit${r===1?``:`s`}`];return{state:`changed`,title:`PR updated`,facts:[...x(e.reviewedSha),...i,...n?kt(n.changedFiles,n.rewritten?`differ`:`changed`):[],`seen ${s(bt(t.observedAt))}`],consequence:n?.rewritten?`The branch was rebased or amended, so this review describes older code.`:`New commits landed, so the lines these findings cite may have moved.`}}function Pt(e){return`This review is based on ${At(e.reviewedSha)}. The pull request has newer commits. <strong>Update review</strong> fetches them first.`}function Ft(e,t){if(!e.comparison)return``;let n=`<code>${s(e.comparison.ref)}</code>`;return e.state===`current`?t?`This review is based on the latest PR commit ${At(e.reviewedSha)}.`:`This review is based on ${At(e.reviewedSha)}, the latest commit on ${n}.`:e.comparison.remote?`This review is currently based on ${n}. <strong>Check for updates</strong> compares against the latest version you already have locally. <strong>Update review</strong> fetches the newest version first.`:`This review is currently based on ${n}, the branch it is of.`}function It(e,t){if(!e.conversation.attached)return``;let n=s(bt(e.conversation.importedAt));return t?`<button type="button" class="prb-fresh-quiet" data-pr-recheck>Re-check the conversation</button> to refresh comments and resolved threads without re-running the code review. Last checked ${n}.`:`The PR conversation was last checked ${n}.`}function Lt(e){return e===`done`||e===`failed`}function Rt(e,t){let n=e=>e.toLowerCase().replace(/\bthe\b/g,``).replace(/[^a-z]/g,``);return n(e)===n(t)}function zt(e,t,n={}){if(!t||t.state!==`changed`||n.dismissedSha&&n.dismissedSha===t.latestSha)return``;let r=t.rewritten?`The branch has been rewritten since, so this report describes commits that are no longer on it.`:t.newCommits===null?`The branch has moved on since.`:`There ${t.newCommits===1?`has been 1 commit`:`have been ${t.newCommits} commits`} on the branch since.`;return`<div class="prb-kiss-fresh" data-kiss-freshness="changed" role="status">
59
+ </details>`:a}function Yt(e,t){return e===null?[]:[`${e} file${e===1?``:`s`} ${t}`]}function Xt(e){return e?`<code title="${s(e)}">${s(e.slice(0,7))}</code>`:``}function C(e){return e?[`reviewed ${Xt(e)}`]:[]}function Zt(e,t){if(e.state===`fixed`)return{state:`fixed`,title:`Freshness: Fixed`,facts:C(e.reviewedSha),consequence:t?.state===`missing`?`That commit is no longer in this repository. The review still reads in full, but it cannot be analysed again until the commit is back.`:`This review is of one commit, and a commit does not change, so these findings keep describing it.`};if(e.state===`current`)return{state:`current`,title:`Review up to date`,facts:C(e.reviewedSha),consequence:``};if(e.state===`changed`){if(e.rewritten)return{state:`changed`,title:`Code rewritten`,facts:[...C(e.reviewedSha),...Yt(e.changedFiles,`differ`)],consequence:`The branch was rebased or amended, so this review describes older code.`};let t=e.newCommits===null?[]:[`${e.newCommits} new commit${e.newCommits===1?``:`s`}`];return{state:`changed`,title:`Code changed`,facts:[...C(e.reviewedSha),...t,...Yt(e.changedFiles,`changed`)],consequence:`New commits landed, so the lines these findings cite may have moved.`}}switch(e.reason){case`uncommitted`:return{state:`unknown`,title:`Cannot be compared`,facts:C(e.reviewedSha),consequence:`This review read uncommitted work and nothing recorded what the working tree held, so whether the files still match cannot be told from here.`};case`missing-commit`:return{state:`unknown`,title:`Reviewed commit is gone`,facts:C(e.reviewedSha),consequence:`It is not in this repository any more, after a force-push or a branch rebuilt from scratch, so nothing can be measured against it.`};case`no-branch`:return{state:`unknown`,title:`Cannot be compared`,facts:C(e.reviewedSha),consequence:`This review’s branch is not in this repository, which is what a pull request from a fork or a branch deleted after merging looks like, so whether the findings still describe it cannot be told from here.`};default:return{state:`unknown`,title:`Cannot be compared`,facts:[],consequence:`Git could not be read in this checkout.`}}}function Qt(e){return{checkedAt:0,code:{state:`unknown`,reviewedSha:e.reviewedSha,latestSha:null,comparison:null,newCommits:null,changedFiles:null,rewritten:!1,reason:null},checkout:{state:`unknown`,relation:`unknown`,prHeadSha:null,presentLocally:!1,reason:null},conversation:{attached:!1}}}function $t(e,t){let n=e.state===`changed`&&e.latestSha===t.sha?e:null,r=t.newCommits??n?.newCommits??null,i=n?.rewritten?[]:[r===null?`new commits on the pull request`:`${r} new commit${r===1?``:`s`}`];return{state:`changed`,title:`PR updated`,facts:[...C(e.reviewedSha),...i,...n?Yt(n.changedFiles,n.rewritten?`differ`:`changed`):[],`seen ${s(Bt(t.observedAt))}`],consequence:n?.rewritten?`The branch was rebased or amended, so this review describes older code.`:`New commits landed, so the lines these findings cite may have moved.`}}function en(e){return`This review is based on ${Xt(e.reviewedSha)}. The pull request has newer commits. <strong>Update review</strong> fetches them first.`}function tn(e,t){if(!e.comparison)return``;let n=`<code>${s(e.comparison.ref)}</code>`;return e.state===`current`?t?`This review is based on the latest PR commit ${Xt(e.reviewedSha)}.`:`This review is based on ${Xt(e.reviewedSha)}, the latest commit on ${n}.`:e.comparison.remote?`This review is currently based on ${n}. <strong>Check for updates</strong> compares against the latest version you already have locally. <strong>Update review</strong> fetches the newest version first.`:`This review is currently based on ${n}, the branch it is of.`}function nn(e,t){if(!e.conversation.attached)return``;let n=s(Bt(e.conversation.importedAt));return t?`<button type="button" class="prb-fresh-quiet" data-pr-recheck>Re-check the conversation</button> to refresh comments and resolved threads without re-running the code review. Last checked ${n}.`:`The PR conversation was last checked ${n}.`}function rn(e){return e===`done`||e===`failed`}function an(e,t){let n=e=>e.toLowerCase().replace(/\bthe\b/g,``).replace(/[^a-z]/g,``);return n(e)===n(t)}function on(e,t,n={}){if(!t||t.state!==`changed`||n.dismissedSha&&n.dismissedSha===t.latestSha)return``;let r=t.rewritten?`The branch has been rewritten since, so this report describes commits that are no longer on it.`:t.newCommits===null?`The branch has moved on since.`:`There ${t.newCommits===1?`has been 1 commit`:`have been ${t.newCommits} commits`} on the branch since.`;return`<div class="prb-kiss-fresh" data-kiss-freshness="changed" role="status">
60
60
  <p><strong>This KISS review describes commit ${s(e.slice(0,7))}.</strong> ${s(r)}</p>
61
61
  <p class="prb-kiss-fresh-note">Running KISS again analyses the branch as it is now. The report below is kept either way.</p>
62
62
  ${n.actions&&t.latestSha?`<button type="button" class="prb-kiss-fresh-dismiss" data-kiss-freshness-dismiss="${s(t.latestSha)}">Not now</button>`:``}
63
- </div>`}function Bt(e,t=!1){return e!==`merged`&&e!==`closed`?``:`<span class="prb-card-pr-state" data-pr-state="${e}">${e===`merged`?`Merged`:t?`Closed`:`PR closed`}</span>`}function Vt(e,t=Date.now()){let n=Math.max(0,Math.round((t-e)/1e3));if(n<60)return`${n} second${n===1?``:`s`}`;let r=Math.round(n/60);return`${r} minute${r===1?``:`s`}`}var Ht={job:`data-job-phase`,kiss:`data-kiss-phase`,update:`data-update-phase`};function Ut(e){let t=new Map;for(let n of Object.keys(Ht)){let r=Ht[n],i=e.querySelector(`[${r}]`);i&&!Lt(i.getAttribute(r)??void 0)&&t.set(n,i)}return t}function Wt(e,t,n){return t.failed?!0:e===`update`?t.phase===`none`||Lt(t.phase):Gt(t.phase,n)}function Gt(e,t){return Lt(e)?!0:(e===`conversation`||e===`analysing`)&&!t.querySelector(`[data-view="files"]`)}function Kt(e,t,n){let r=[...e.querySelectorAll(`.prb-progress-step`)],i=r.findIndex(e=>e.dataset.phase===t);if(i===-1)return;r.forEach((e,t)=>{let n=t<i?`complete`:t===i?`active`:`pending`;e.dataset.state=n;let r=e.querySelector(`.prb-progress-label`),a=n===`complete`?e.dataset.labelDone:e.dataset.labelDoing;r&&a&&(r.textContent=a),t!==i&&e.querySelector(`[data-step-note]`)?.remove()});let a=r[i];if(!n||Rt(n,a.querySelector(`.prb-progress-label`)?.textContent??``))return;let o=a.querySelector(`[data-step-note]`);o||(o=document.createElement(`p`),o.className=`prb-progress-note`,o.setAttribute(`data-step-note`,``),a.appendChild(o)),o.textContent=n}function qt(e){let t=e.querySelector(`[data-started-at]`),n=Number(t?.dataset.startedAt);!t||!Number.isFinite(n)||(t.textContent=`Running for ${Vt(n)}.`)}function Jt(e,t,n){let r=e.scope===`change`?`Whole change`:t.get(e.scope)??`A theme of this change`,i=e.scope===`change`?``:e.scope;return`<article class="prb-diagram" id="prb-diagram-${s(e.scope)}" data-diagram-card="${s(e.scope)}">
63
+ </div>`}function sn(e,t=!1){return e!==`merged`&&e!==`closed`?``:`<span class="prb-card-pr-state" data-pr-state="${e}">${e===`merged`?`Merged`:t?`Closed`:`PR closed`}</span>`}function cn(e,t=Date.now()){let n=Math.max(0,Math.round((t-e)/1e3));if(n<60)return`${n} second${n===1?``:`s`}`;let r=Math.round(n/60);return`${r} minute${r===1?``:`s`}`}var ln={job:`data-job-phase`,kiss:`data-kiss-phase`,update:`data-update-phase`};function un(e){let t=new Map;for(let n of Object.keys(ln)){let r=ln[n],i=e.querySelector(`[${r}]`);i&&!rn(i.getAttribute(r)??void 0)&&t.set(n,i)}return t}function dn(e,t,n){return t.failed?!0:e===`update`?t.phase===`none`||rn(t.phase):fn(t.phase,n)}function fn(e,t){return rn(e)?!0:(e===`conversation`||e===`analysing`)&&!t.querySelector(`[data-view="files"]`)}function pn(e,t,n){let r=[...e.querySelectorAll(`.prb-progress-step`)],i=r.findIndex(e=>e.dataset.phase===t);if(i===-1)return;r.forEach((e,t)=>{let n=t<i?`complete`:t===i?`active`:`pending`;e.dataset.state=n;let r=e.querySelector(`.prb-progress-label`),a=n===`complete`?e.dataset.labelDone:e.dataset.labelDoing;r&&a&&(r.textContent=a),t!==i&&e.querySelector(`[data-step-note]`)?.remove()});let a=r[i];if(!n||an(n,a.querySelector(`.prb-progress-label`)?.textContent??``))return;let o=a.querySelector(`[data-step-note]`);o||(o=document.createElement(`p`),o.className=`prb-progress-note`,o.setAttribute(`data-step-note`,``),a.appendChild(o)),o.textContent=n}function mn(e){let t=e.querySelector(`[data-started-at]`),n=Number(t?.dataset.startedAt);!t||!Number.isFinite(n)||(t.textContent=`Running for ${cn(n)}.`)}function hn(e,t,n){let r=e.scope===`change`?`Whole change`:t.get(e.scope)??`A theme of this change`,i=e.scope===`change`?``:e.scope;return`<article class="prb-diagram" id="prb-diagram-${s(e.scope)}" data-diagram-card="${s(e.scope)}">
64
64
  <header class="prb-diagram-head">
65
65
  <div class="prb-diagram-heading">
66
66
  <h4 class="prb-diagram-title">
@@ -79,32 +79,32 @@ import{c as e,i as t,t as n}from"./chunk-BeL0x-wt.js";import{_ as r,d as i,g as
79
79
  </div>
80
80
  </header>
81
81
  ${e.caption?`<p class="prb-diagram-caption">${s(e.caption)}</p>`:``}
82
- ${Yt(e,n)}
82
+ ${gn(e,n)}
83
83
  <div class="prb-diagram-canvas" data-diagram-canvas></div>
84
84
  <details class="prb-diagram-source">
85
85
  <summary>Diagram source</summary>
86
86
  <div class="${c}"><pre><code data-mermaid-source>${s(e.mermaid)}</code></pre><button type="button" class="${l}" aria-label="Copy code">Copy</button></div>
87
87
  </details>
88
- </article>`}function Yt(e,t){return!e.commitSha||!t||e.commitSha===t?``:`<p class="prb-diagram-stale">Drawn from <code>${s(e.commitSha.slice(0,7))}</code>, before this review was brought up to date. Regenerate to draw it from the commit the review now describes.</p>`}var Xt={review:`<path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2"/><rect x="9" y="3" width="6" height="4" rx="1"/><path d="m9 14 2 2 4-4"/>`,kiss:`<path d="M12 3v4M12 17v4M3 12h4M17 12h4"/><circle cx="12" cy="12" r="2"/>`,diagrams:`<rect x="3" y="3" width="7" height="6" rx="1"/><rect x="14" y="15" width="7" height="6" rx="1"/><path d="M6.5 9v3a2 2 0 0 0 2 2h7a2 2 0 0 1 2 2v-1"/>`,issues:`<circle cx="12" cy="12" r="9"/><path d="M12 8v4M12 16h.01"/>`,questions:`<circle cx="12" cy="12" r="9"/><path d="M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3M12 17h.01"/>`,files:`<path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5M9 13h6M9 17h6"/>`,prcontext:`<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>`,recommendations:`<path d="M9 18h6M10 22h4"/><path d="M12 2a7 7 0 0 0-4 12.7c.6.5 1 1.2 1 2V17h6v-.3c0-.8.4-1.5 1-2A7 7 0 0 0 12 2z"/>`,reviews:`<path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/>`,notifications:`<path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.7 21a2 2 0 0 1-3.4 0"/>`,settings:`<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/>`,feedback:`<path d="m22 2-7 20-4-9-9-4z"/><path d="M22 2 11 13"/>`,stop:`<path d="M12 2v10"/><path d="M18.4 6.6a9 9 0 1 1-12.8 0"/>`,restart:`<path d="M21 12a9 9 0 1 1-2.64-6.36"/><path d="M21 3v6h-6"/>`};function Zt(e){return`<span class="prb-rail-icon" aria-hidden="true">${Qt(e)}</span>`}function Qt(e){return`<svg viewBox="0 0 24 24" focusable="false" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">${Xt[e]}</svg>`}var $t=`modulepreload`,en=function(e){return`/`+e},tn={},S=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=en(t,n),t=s(t),t in tn)return;tn[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:$t,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},nn=.5,rn=3,an=1.25,on=null;function sn(){return on??=S(()=>import(`./chunk-BeqgAIrQ.js`).then(e=>(e.default.initialize({startOnLoad:!1,securityLevel:`strict`,htmlLabels:!1,flowchart:{htmlLabels:!1},theme:`neutral`,fontFamily:`inherit`}),e.default)),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18])),on}var cn=new WeakSet,ln=new WeakMap,un=new WeakMap,C=null;function dn(e){return document.addEventListener(`click`,t=>{let n=t.target;if(!(n instanceof Element))return;let r=n.closest(`[data-diagram-stop]`);if(r){r.setAttribute(`disabled`,``),r.textContent=`Stopping…`,fetch(e.endpoint(`/stop`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({kind:`diagram`})}).catch(()=>{}).finally(()=>{C?.abort()});return}let i=n.closest(`[data-diagram-toggle]`);if(i){yn(i.closest(`[data-diagram-card]`),i.getAttribute(`aria-expanded`)===`true`);return}let a=n.closest(`[data-diagram-zoom]`);if(a){Sn(a.closest(`[data-diagram-card]`),a.dataset.diagramZoom??`reset`);return}let o=n.closest(`[data-diagram-request]`);o&&fn(e,o.dataset.diagramRequest||null)}),pn(),{drawPane:bn}}async function fn(e,t){if(C)return;let n=t??`change`,r=document.querySelector(`[data-diagram-pane]`),i=r?.querySelector(`[data-diagram-card="${An(n)}"]`)??null??hn(r,n,t);if(!i)return;mn(),e.showDiagrams();let a=gn(i);C=new AbortController,Tn(!1);try{let n=await fetch(e.endpoint(`/diagram`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({sectionId:t}),signal:C.signal}),r=await n.json().catch(()=>null);if(n.status===409&&r?.running){window.location.reload();return}if(r?.stopped)throw new DOMException(`Stopped`,`AbortError`);if(!n.ok||!r?.diagram)return _n(i,a,r?.error??`Buddy AI did not return a diagram. Check the terminal running PR Review Buddy.`);vn(i,r.diagram,t)}catch(e){if(e instanceof DOMException&&e.name===`AbortError`){i.hasAttribute(`data-diagram-pending`)?(i.remove(),mn()):a.remove();return}_n(i,a,`Could not reach PR Review Buddy. The workspace server may have stopped.`)}finally{C=null,Tn(!0)}}function pn(){let e=document.querySelector(`[data-diagram-pane][data-diagram-running]`);if(!e)return;let t=e.dataset.diagramRunning||null,n=t??`change`,r=e.querySelector(`[data-diagram-card="${An(n)}"]`)??hn(e,n,t);r&&(mn(),gn(r,{scroll:!1}),Tn(!1))}function mn(){let e=document.querySelectorAll(`[data-diagram-pane] [data-diagram-card]`).length,t=document.querySelector(`[data-view-nav="diagram"]`);if(e===0){t?.remove();return}if(!t){let e=document.querySelector(`[data-view-nav="issues"]`);if(!e)return;t=document.createElement(`button`),t.setAttribute(`type`,`button`),t.className=`prb-rail-item prb-rail-link`,t.dataset.viewNav=`diagram`,t.innerHTML=`${Zt(`diagrams`)}<span class="prb-rail-label"><span class="prb-rail-title">Diagrams</span></span><span class="prb-rail-count"></span>`,e.before(t)}let n=t.querySelector(`.prb-rail-count`);n&&(n.textContent=String(e),n.setAttribute(`aria-label`,e===1?`1 diagram`:`${e} diagrams`))}function hn(e,t,n){if(!e)return null;let r=document.createElement(`article`);return r.className=`prb-diagram`,r.dataset.diagramCard=t,r.setAttribute(`data-diagram-pending`,``),r.innerHTML=`<header class="prb-diagram-head">
88
+ </article>`}function gn(e,t){return!e.commitSha||!t||e.commitSha===t?``:`<p class="prb-diagram-stale">Drawn from <code>${s(e.commitSha.slice(0,7))}</code>, before this review was brought up to date. Regenerate to draw it from the commit the review now describes.</p>`}var _n={review:`<path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2"/><rect x="9" y="3" width="6" height="4" rx="1"/><path d="m9 14 2 2 4-4"/>`,kiss:`<path d="M12 3v4M12 17v4M3 12h4M17 12h4"/><circle cx="12" cy="12" r="2"/>`,diagrams:`<rect x="3" y="3" width="7" height="6" rx="1"/><rect x="14" y="15" width="7" height="6" rx="1"/><path d="M6.5 9v3a2 2 0 0 0 2 2h7a2 2 0 0 1 2 2v-1"/>`,issues:`<circle cx="12" cy="12" r="9"/><path d="M12 8v4M12 16h.01"/>`,questions:`<circle cx="12" cy="12" r="9"/><path d="M9.1 9a3 3 0 0 1 5.8 1c0 2-3 3-3 3M12 17h.01"/>`,files:`<path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5M9 13h6M9 17h6"/>`,prcontext:`<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>`,recommendations:`<path d="M9 18h6M10 22h4"/><path d="M12 2a7 7 0 0 0-4 12.7c.6.5 1 1.2 1 2V17h6v-.3c0-.8.4-1.5 1-2A7 7 0 0 0 12 2z"/>`,reviews:`<path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/>`,notifications:`<path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.7 21a2 2 0 0 1-3.4 0"/>`,settings:`<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/>`,feedback:`<path d="m22 2-7 20-4-9-9-4z"/><path d="M22 2 11 13"/>`,stop:`<path d="M12 2v10"/><path d="M18.4 6.6a9 9 0 1 1-12.8 0"/>`,restart:`<path d="M21 12a9 9 0 1 1-2.64-6.36"/><path d="M21 3v6h-6"/>`};function vn(e){return`<span class="prb-rail-icon" aria-hidden="true">${yn(e)}</span>`}function yn(e){return`<svg viewBox="0 0 24 24" focusable="false" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">${_n[e]}</svg>`}var bn=`modulepreload`,xn=function(e){return`/`+e},Sn={},w=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=xn(t,n),t=s(t),t in Sn)return;Sn[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:bn,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Cn=.5,wn=3,Tn=1.25,En=null;function Dn(){return En??=w(()=>import(`./chunk-BeqgAIrQ.js`).then(e=>(e.default.initialize({startOnLoad:!1,securityLevel:`strict`,htmlLabels:!1,flowchart:{htmlLabels:!1},theme:`neutral`,fontFamily:`inherit`}),e.default)),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18])),En}var On=new WeakSet,kn=new WeakMap,An=new WeakMap,T=null;function jn(e){return document.addEventListener(`click`,t=>{let n=t.target;if(!(n instanceof Element))return;let r=n.closest(`[data-diagram-stop]`);if(r){r.setAttribute(`disabled`,``),r.textContent=`Stopping…`,fetch(e.endpoint(`/stop`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({kind:`diagram`})}).catch(()=>{}).finally(()=>{T?.abort()});return}let i=n.closest(`[data-diagram-toggle]`);if(i){zn(i.closest(`[data-diagram-card]`),i.getAttribute(`aria-expanded`)===`true`);return}let a=n.closest(`[data-diagram-zoom]`);if(a){Hn(a.closest(`[data-diagram-card]`),a.dataset.diagramZoom??`reset`);return}let o=n.closest(`[data-diagram-request]`);o&&Mn(e,o.dataset.diagramRequest||null)}),Nn(),{drawPane:Bn}}async function Mn(e,t){if(T)return;let n=t??`change`,r=document.querySelector(`[data-diagram-pane]`),i=r?.querySelector(`[data-diagram-card="${Xn(n)}"]`)??null??Fn(r,n,t);if(!i)return;Pn(),e.showDiagrams();let a=In(i);T=new AbortController,Gn(!1);try{let n=await fetch(e.endpoint(`/diagram`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({sectionId:t}),signal:T.signal}),r=await n.json().catch(()=>null);if(n.status===409&&r?.running){window.location.reload();return}if(r?.stopped)throw new DOMException(`Stopped`,`AbortError`);if(!n.ok||!r?.diagram)return Ln(i,a,r?.error??`Buddy AI did not return a diagram. Check the terminal running PR Review Buddy.`);Rn(i,r.diagram,t)}catch(e){if(e instanceof DOMException&&e.name===`AbortError`){i.hasAttribute(`data-diagram-pending`)?(i.remove(),Pn()):a.remove();return}Ln(i,a,`Could not reach PR Review Buddy. The workspace server may have stopped.`)}finally{T=null,Gn(!0)}}function Nn(){let e=document.querySelector(`[data-diagram-pane][data-diagram-running]`);if(!e)return;let t=e.dataset.diagramRunning||null,n=t??`change`,r=e.querySelector(`[data-diagram-card="${Xn(n)}"]`)??Fn(e,n,t);r&&(Pn(),In(r,{scroll:!1}),Gn(!1))}function Pn(){let e=document.querySelectorAll(`[data-diagram-pane] [data-diagram-card]`).length,t=document.querySelector(`[data-view-nav="diagram"]`);if(e===0){t?.remove();return}if(!t){let e=document.querySelector(`[data-view-nav="issues"]`);if(!e)return;t=document.createElement(`button`),t.setAttribute(`type`,`button`),t.className=`prb-rail-item prb-rail-link`,t.dataset.viewNav=`diagram`,t.innerHTML=`${vn(`diagrams`)}<span class="prb-rail-label"><span class="prb-rail-title">Diagrams</span></span><span class="prb-rail-count"></span>`,e.before(t)}let n=t.querySelector(`.prb-rail-count`);n&&(n.textContent=String(e),n.setAttribute(`aria-label`,e===1?`1 diagram`:`${e} diagrams`))}function Fn(e,t,n){if(!e)return null;let r=document.createElement(`article`);return r.className=`prb-diagram`,r.dataset.diagramCard=t,r.setAttribute(`data-diagram-pending`,``),r.innerHTML=`<header class="prb-diagram-head">
89
89
  <div class="prb-diagram-heading">
90
90
  <h4 class="prb-diagram-title">Drawing…</h4>
91
- <p class="prb-diagram-scope">${t===`change`?`Whole change`:kn(En(n))}</p>
91
+ <p class="prb-diagram-scope">${t===`change`?`Whole change`:Yn(Kn(n))}</p>
92
92
  </div>
93
- </header>`,Dn(e,r,n),r}function gn(e,{scroll:t=!0}={}){e.querySelector(`[data-diagram-status]`)?.remove();let n=document.createElement(`p`);n.className=`prb-diagram-status`,n.setAttribute(`data-diagram-status`,``),n.innerHTML=`<span class="prb-thinking"><i></i><i></i><i></i></span><span>Reading the change…</span>`;let r=document.createElement(`button`);return r.type=`button`,r.className=`prb-diagram-redraw`,r.setAttribute(`data-diagram-stop`,``),r.textContent=`Stop`,n.appendChild(r),e.querySelector(`.prb-diagram-head`)?.insertAdjacentElement(`afterend`,n),t&&e.scrollIntoView({behavior:jn()?`auto`:`smooth`,block:`start`}),n}function _n(e,t,n){if(t.className=`prb-diagram-failed`,t.textContent=n,e.hasAttribute(`data-diagram-pending`)){let n=document.createElement(`button`);n.type=`button`,n.className=`prb-diagram-redraw`,n.dataset.diagramRequest=e.dataset.diagramCard===`change`?``:e.dataset.diagramCard??``,n.textContent=`Try again`,t.appendChild(document.createTextNode(` `)),t.appendChild(n)}}function vn(e,t,n){let r=Jt(t,new Map(n?[[n,En(n)]]:[]),t.commitSha),i=document.createElement(`div`);i.innerHTML=r;let a=i.firstElementChild;a&&(e.replaceWith(a),mn(),xn(a))}function yn(e,t){e&&(e.toggleAttribute(`data-diagram-collapsed`,t),e.querySelector(`[data-diagram-toggle]`)?.setAttribute(`aria-expanded`,String(!t)),t||xn(e))}function bn(){for(let e of document.querySelectorAll(`[data-diagram-pane] [data-diagram-card]`))xn(e)}async function xn(e){let t=e.querySelector(`[data-diagram-canvas]`),n=e.querySelector(`[data-mermaid-source]`)?.textContent??``;if(!(!t||!n||cn.has(e)||e.hasAttribute(`data-diagram-collapsed`))){cn.add(e);try{let e=await sn();await e.parse(n);let{svg:r}=await e.render(`prb-mermaid-${Math.random().toString(36).slice(2)}`,n);t.innerHTML=r}catch{cn.delete(e),t.innerHTML=``;let n=document.createElement(`p`);n.className=`prb-diagram-failed`,n.textContent=`This diagram could not be drawn. Its source is below, and Regenerate will ask for another.`,t.replaceWith(n),e.querySelector(`details`)?.setAttribute(`open`,``)}}}function Sn(e,t){let n=e?.querySelector(`[data-diagram-canvas] svg`),r=e?.querySelector(`[data-diagram-canvas]`);if(!e||!n||!r)return;if(t===`reset`){un.delete(e),r.removeAttribute(`data-zoomed`),n.style.removeProperty(`width`);return}let i=Cn(e,n);if(i<=0)return;let a=wn((un.get(e)??1)*(t===`in`?an:1/an));un.set(e,a),r.setAttribute(`data-zoomed`,``),n.style.width=`${Math.round(i*a)}px`}function Cn(e,t){let n=ln.get(e);if(n)return n;let r=t.getBoundingClientRect().width;if(r>0)return ln.set(e,r),r;let i=t.getAttribute(`viewBox`)?.split(/[\s,]+/),a=Number(i?.[2]??0);return Number.isFinite(a)?a:0}function wn(e){return Math.min(rn,Math.max(nn,e))}function Tn(e){for(let t of document.querySelectorAll(`[data-diagram-request]`))t.disabled=!e}function En(e){return e?document.querySelector(`[data-goto-section="${An(e)}"]`)?.querySelector(`.prb-rail-title`)?.textContent?.trim()||`A theme of this change`:`Whole change`}function Dn(e,t,n){let r=On(n);for(let n of e.querySelectorAll(`[data-diagram-card]`)){let e=n.dataset.diagramCard??``;if(On(e===`change`?null:e)>r){n.before(t);return}}e.appendChild(t)}function On(e){if(!e)return-1;let t=document.querySelector(`[data-goto-section="${An(e)}"]`);return Number(t?.dataset.themeIndex??0)}function kn(e){let t=document.createElement(`span`);return t.textContent=e,t.innerHTML}function An(e){return CSS.escape(e)}function jn(){return window.matchMedia(`(prefers-reduced-motion: reduce)`).matches}function Mn(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}var Nn=1e3,Pn=new WeakMap;function Fn(e,t){return e.length<=1e3?Mn(e)||`&nbsp;`:`${Mn(e.slice(0,Nn))}\u2026 <button type="button" class="prb-code-long-toggle" data-full-line="${t}">Show full line</button>`}function In(e){let t=e.lines.length;return`<tr class="prb-code-deletion" data-before-line="${e.beforeLine}"><td class="prb-code-num"></td><td class="prb-code-line"><button type="button" class="prb-code-deletion-toggle" data-deletion-toggle aria-expanded="false">− ${t} deleted ${t===1?`line`:`lines`}</button></td></tr>`+e.lines.map(e=>`<tr class="prb-code-deleted" hidden><td class="prb-code-num">− ${e.oldLine}</td><td class="prb-code-line">${Fn(e.text,`old:${e.oldLine}`)}</td></tr>`).join(``)}function Ln(e,t){let n=new Set(e.addedLines),r=new Map;for(let t of e.deletions??[])r.set(t.beforeLine,t);let i=e.lines.map((i,a)=>{let o=e.from+a,s=[n.has(o)?`prb-code-added`:``,o===t?`prb-code-target`:``].filter(Boolean).join(` `),c=r.get(o);return`${c?In(c):``}<tr class="${s}" data-line="${o}"><td class="prb-code-num">${o}</td><td class="prb-code-line">${Fn(i,`new:${o}`)}</td></tr>`}),a=r.get(e.totalLines+1);return a&&e.to===e.totalLines&&i.push(In(a)),i.join(``)}function Rn(e){let t=e.getAttribute(`aria-expanded`)!==`true`;e.setAttribute(`aria-expanded`,String(t));let n=e.closest(`tr`)?.nextElementSibling;for(;n?.classList.contains(`prb-code-deleted`);)n.hidden=!t,n=n.nextElementSibling}function zn(e,t){let n=new Map;for(let e of t.deletions??[])for(let t of e.lines)n.set(t.oldLine,t.text);for(let r of e.querySelectorAll(`[data-full-line]`)){let[e,i]=(r.dataset.fullLine??``).split(`:`),a=Number(i),o=e===`old`?n.get(a):t.lines[a-t.from];o!==void 0&&Pn.set(r,o)}}function Bn(e){let t=Pn.get(e),n=e.closest(`td`);return t===void 0||!n?null:(n.textContent=t,n)}function Vn(e){return e.deletion?2*e.line-1:2*e.line}function Hn(e){return e%2==1?{line:(e+1)/2,deletion:!0}:{line:e/2,deletion:!1}}function Un(e,t){if(e.length===0)return``;let n=e.map(Vn),r=n.indexOf(t),i=n.some(e=>e<t),a=n.some(e=>e>t),o=e.length,s=r===-1?`${o} ${o===1?`change`:`changes`}`:`${r+1} of ${o}`;return`<span class="prb-code-nav" data-change-navigator data-change-keys="${n.join(`,`)}" data-change-position="${t}">
93
+ </header>`,qn(e,r,n),r}function In(e,{scroll:t=!0}={}){e.querySelector(`[data-diagram-status]`)?.remove();let n=document.createElement(`p`);n.className=`prb-diagram-status`,n.setAttribute(`data-diagram-status`,``),n.innerHTML=`<span class="prb-thinking"><i></i><i></i><i></i></span><span>Reading the change…</span>`;let r=document.createElement(`button`);return r.type=`button`,r.className=`prb-diagram-redraw`,r.setAttribute(`data-diagram-stop`,``),r.textContent=`Stop`,n.appendChild(r),e.querySelector(`.prb-diagram-head`)?.insertAdjacentElement(`afterend`,n),t&&e.scrollIntoView({behavior:Zn()?`auto`:`smooth`,block:`start`}),n}function Ln(e,t,n){if(t.className=`prb-diagram-failed`,t.textContent=n,e.hasAttribute(`data-diagram-pending`)){let n=document.createElement(`button`);n.type=`button`,n.className=`prb-diagram-redraw`,n.dataset.diagramRequest=e.dataset.diagramCard===`change`?``:e.dataset.diagramCard??``,n.textContent=`Try again`,t.appendChild(document.createTextNode(` `)),t.appendChild(n)}}function Rn(e,t,n){let r=hn(t,new Map(n?[[n,Kn(n)]]:[]),t.commitSha),i=document.createElement(`div`);i.innerHTML=r;let a=i.firstElementChild;a&&(e.replaceWith(a),Pn(),Vn(a))}function zn(e,t){e&&(e.toggleAttribute(`data-diagram-collapsed`,t),e.querySelector(`[data-diagram-toggle]`)?.setAttribute(`aria-expanded`,String(!t)),t||Vn(e))}function Bn(){for(let e of document.querySelectorAll(`[data-diagram-pane] [data-diagram-card]`))Vn(e)}async function Vn(e){let t=e.querySelector(`[data-diagram-canvas]`),n=e.querySelector(`[data-mermaid-source]`)?.textContent??``;if(!(!t||!n||On.has(e)||e.hasAttribute(`data-diagram-collapsed`))){On.add(e);try{let e=await Dn();await e.parse(n);let{svg:r}=await e.render(`prb-mermaid-${Math.random().toString(36).slice(2)}`,n);t.innerHTML=r}catch{On.delete(e),t.innerHTML=``;let n=document.createElement(`p`);n.className=`prb-diagram-failed`,n.textContent=`This diagram could not be drawn. Its source is below, and Regenerate will ask for another.`,t.replaceWith(n),e.querySelector(`details`)?.setAttribute(`open`,``)}}}function Hn(e,t){let n=e?.querySelector(`[data-diagram-canvas] svg`),r=e?.querySelector(`[data-diagram-canvas]`);if(!e||!n||!r)return;if(t===`reset`){An.delete(e),r.removeAttribute(`data-zoomed`),n.style.removeProperty(`width`);return}let i=Un(e,n);if(i<=0)return;let a=Wn((An.get(e)??1)*(t===`in`?Tn:1/Tn));An.set(e,a),r.setAttribute(`data-zoomed`,``),n.style.width=`${Math.round(i*a)}px`}function Un(e,t){let n=kn.get(e);if(n)return n;let r=t.getBoundingClientRect().width;if(r>0)return kn.set(e,r),r;let i=t.getAttribute(`viewBox`)?.split(/[\s,]+/),a=Number(i?.[2]??0);return Number.isFinite(a)?a:0}function Wn(e){return Math.min(wn,Math.max(Cn,e))}function Gn(e){for(let t of document.querySelectorAll(`[data-diagram-request]`))t.disabled=!e}function Kn(e){return e?document.querySelector(`[data-goto-section="${Xn(e)}"]`)?.querySelector(`.prb-rail-title`)?.textContent?.trim()||`A theme of this change`:`Whole change`}function qn(e,t,n){let r=Jn(n);for(let n of e.querySelectorAll(`[data-diagram-card]`)){let e=n.dataset.diagramCard??``;if(Jn(e===`change`?null:e)>r){n.before(t);return}}e.appendChild(t)}function Jn(e){if(!e)return-1;let t=document.querySelector(`[data-goto-section="${Xn(e)}"]`);return Number(t?.dataset.themeIndex??0)}function Yn(e){let t=document.createElement(`span`);return t.textContent=e,t.innerHTML}function Xn(e){return CSS.escape(e)}function Zn(){return window.matchMedia(`(prefers-reduced-motion: reduce)`).matches}function Qn(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}var $n=1e3,er=new WeakMap;function tr(e,t){return e.length<=1e3?Qn(e)||`&nbsp;`:`${Qn(e.slice(0,$n))}\u2026 <button type="button" class="prb-code-long-toggle" data-full-line="${t}">Show full line</button>`}function nr(e){let t=e.lines.length;return`<tr class="prb-code-deletion" data-before-line="${e.beforeLine}"><td class="prb-code-num"></td><td class="prb-code-line"><button type="button" class="prb-code-deletion-toggle" data-deletion-toggle aria-expanded="false">− ${t} deleted ${t===1?`line`:`lines`}</button></td></tr>`+e.lines.map(e=>`<tr class="prb-code-deleted" hidden><td class="prb-code-num">− ${e.oldLine}</td><td class="prb-code-line">${tr(e.text,`old:${e.oldLine}`)}</td></tr>`).join(``)}function rr(e,t){let n=new Set(e.addedLines),r=new Map;for(let t of e.deletions??[])r.set(t.beforeLine,t);let i=e.lines.map((i,a)=>{let o=e.from+a,s=[n.has(o)?`prb-code-added`:``,o===t?`prb-code-target`:``].filter(Boolean).join(` `),c=r.get(o);return`${c?nr(c):``}<tr class="${s}" data-line="${o}"><td class="prb-code-num">${o}</td><td class="prb-code-line">${tr(i,`new:${o}`)}</td></tr>`}),a=r.get(e.totalLines+1);return a&&e.to===e.totalLines&&i.push(nr(a)),i.join(``)}function ir(e){let t=e.getAttribute(`aria-expanded`)!==`true`;e.setAttribute(`aria-expanded`,String(t));let n=e.closest(`tr`)?.nextElementSibling;for(;n?.classList.contains(`prb-code-deleted`);)n.hidden=!t,n=n.nextElementSibling}function ar(e,t){let n=new Map;for(let e of t.deletions??[])for(let t of e.lines)n.set(t.oldLine,t.text);for(let r of e.querySelectorAll(`[data-full-line]`)){let[e,i]=(r.dataset.fullLine??``).split(`:`),a=Number(i),o=e===`old`?n.get(a):t.lines[a-t.from];o!==void 0&&er.set(r,o)}}function or(e){let t=er.get(e),n=e.closest(`td`);return t===void 0||!n?null:(n.textContent=t,n)}function sr(e){return e.deletion?2*e.line-1:2*e.line}function cr(e){return e%2==1?{line:(e+1)/2,deletion:!0}:{line:e/2,deletion:!1}}function lr(e,t){if(e.length===0)return``;let n=e.map(sr),r=n.indexOf(t),i=n.some(e=>e<t),a=n.some(e=>e>t),o=e.length,s=r===-1?`${o} ${o===1?`change`:`changes`}`:`${r+1} of ${o}`;return`<span class="prb-code-nav" data-change-navigator data-change-keys="${n.join(`,`)}" data-change-position="${t}">
94
94
  <button type="button" class="prb-code-nav-step" data-change-step="previous"${i?``:` disabled`}>\u2191 Previous</button>
95
95
  <span class="prb-code-nav-count" aria-live="polite">${s}</span>
96
96
  <button type="button" class="prb-code-nav-step" data-change-step="next"${a?``:` disabled`}>Next \u2193</button>
97
- </span>`}function Wn(e,t){let n=(e.dataset.changeKeys??``).split(`,`).filter(Boolean).map(Number),r=Number(e.dataset.changePosition)||0,i=t===`next`?n.find(e=>e>r):[...n].reverse().find(e=>e<r);return i===void 0?null:{key:i,anchor:Hn(i)}}function Gn(e,t){return e.querySelector(t.deletion?`tr[data-before-line="${t.line}"]`:`tr[data-line="${t.line}"]`)}function Kn(e){return(e.dataset.changeKeys??``).split(`,`).filter(Boolean).map(Number).map(Hn)}function qn(e){if(!e)return;let t=Number(e.dataset.changePosition)||0;return(e.dataset.changeKeys??``).split(`,`).filter(Boolean).map(Number).includes(t)?Hn(t):void 0}function Jn(e,t){return Math.max(e,+!t)+1}var Yn=8;function Xn(e){for(let t=e.parentElement;t;t=t.parentElement){let e=getComputedStyle(t).overflowY;if(e===`auto`||e===`scroll`)return t}return null}function Zn(e){let t=e.panel-e.scroller;return Math.max(340,Math.floor(e.pane-t-16))}function Qn(e){let t=e.getBoundingClientRect().top;for(let n of e.querySelectorAll(`tr`)){let e=n.getBoundingClientRect();if(e.bottom>t)return{row:n,offset:e.top-t}}return null}function $n(e,t){let n=t.row.getBoundingClientRect().top-e.getBoundingClientRect().top-t.offset;e.scrollTop+=n}function er(e){if(!e.hasAttribute(`data-expanded`))return;let t=Xn(e),n=e.querySelector(`.prb-code-scroll`);if(!t||!n)return;let r=Zn({pane:t.clientHeight,panel:e.offsetHeight,scroller:n.offsetHeight});e.style.setProperty(`--prb-code-expanded`,`${r}px`)}function tr(e){let t=e.querySelector(`[data-code-expand]`),n=e.querySelector(`.prb-code-scroll`);if(!t||!n)return;let r=e.hasAttribute(`data-expanded`);t.hidden=!r&&n.scrollHeight<=n.clientHeight,t.textContent=r?`Collapse`:`Expand`,t.setAttribute(`aria-expanded`,String(r))}var nr=!1;function rr(){nr||(nr=!0,window.addEventListener(`resize`,()=>{for(let e of document.querySelectorAll(`.prb-code[data-expanded]`))er(e)}))}function ir(e,t){let n=e.querySelector(`.prb-code-scroll`),r=n?Qn(n):null;t?(e.setAttribute(`data-expanded`,``),er(e),rr()):(e.removeAttribute(`data-expanded`),e.style.removeProperty(`--prb-code-expanded`)),tr(e),n&&r&&$n(n,r);let i=t?Xn(e):null;i&&(i.scrollTop+=e.getBoundingClientRect().top-i.getBoundingClientRect().top-Yn)}var ar={rb:`ruby`,js:`javascript`,mjs:`javascript`,cjs:`javascript`,ts:`typescript`,mts:`typescript`,cts:`typescript`,jsx:`jsx`,tsx:`tsx`,json:`json`,yml:`yaml`,yaml:`yaml`,md:`markdown`,html:`html`,css:`css`,scss:`scss`,sql:`sql`,py:`python`,java:`java`,kt:`kotlin`,kts:`kotlin`,go:`go`,rs:`rust`,sh:`shellscript`,bash:`shellscript`,zsh:`shellscript`,tf:`terraform`,tfvars:`terraform`};function or(e){let t=e.slice(e.lastIndexOf(`/`)+1);if(t===`Dockerfile`||t.startsWith(`Dockerfile.`))return`docker`;let n=t.lastIndexOf(`.`);return n<=0?null:ar[t.slice(n+1).toLowerCase()]??null}function sr(e){let t=new Set;for(let n of e){let e=or(n);e&&t.add(e)}return[...t]}var cr={ruby:()=>S(()=>import(`./chunk-CAnKkQXq.js`),__vite__mapDeps([19,20,21,22,23,24,25,26,27,28,29])),javascript:()=>S(()=>import(`./chunk-D2pwppYQ.js`),__vite__mapDeps([30,21])),typescript:()=>S(()=>import(`./chunk-Cjc271yU.js`),__vite__mapDeps([31,26])),jsx:()=>S(()=>import(`./chunk-B2PgDgse.js`),__vite__mapDeps([32,24])),tsx:()=>S(()=>import(`./chunk-D95j_xjm.js`),__vite__mapDeps([33,27])),json:()=>S(()=>import(`./chunk-qhed-kSA.js`),[]),yaml:()=>S(()=>import(`./chunk-Cv3JjNkX.js`),__vite__mapDeps([34,29])),markdown:()=>S(()=>import(`./chunk-BYOwaDjH.js`),[]),html:()=>S(()=>import(`./chunk-EIJEcyW-.js`),__vite__mapDeps([35,22,20,21])),css:()=>S(()=>import(`./chunk-C3nvJp0N.js`),__vite__mapDeps([36,20])),scss:()=>S(()=>import(`./chunk-D2NZorQR.js`),__vite__mapDeps([37,20])),sql:()=>S(()=>import(`./chunk-NzFayA7r.js`),__vite__mapDeps([38,25])),python:()=>S(()=>import(`./chunk-gzcpVVnB.js`),[]),java:()=>S(()=>import(`./chunk-AdYjtsZU.js`),__vite__mapDeps([39,23])),kotlin:()=>S(()=>import(`./chunk-DhhofPvG.js`),[]),go:()=>S(()=>import(`./chunk-rLFTqkRN.js`),[]),rust:()=>S(()=>import(`./chunk-Cfkwpbl8.js`),[]),shellscript:()=>S(()=>import(`./chunk-pNSm1SyV.js`),__vite__mapDeps([40,28])),docker:()=>S(()=>import(`./chunk-IyjqRm3v.js`),[]),terraform:()=>S(()=>import(`./chunk-DswuEJGm.js`),[])},lr=`github-light-default`,ur=null,dr=new Map;function fr(){return ur??=Promise.all([S(()=>import(`./chunk-c-cg1wCO.js`),__vite__mapDeps([41,3])),S(()=>import(`./chunk-CBrdyqSx.js`),__vite__mapDeps([42,3])),S(()=>import(`./chunk-BXViO-2h.js`),[])]).then(([{createHighlighterCore:e},{createOnigurumaEngine:t},n])=>e({themes:[n.default],langs:[],engine:t(S(()=>import(`./chunk-BnjxR4X6.js`),[]))})).catch(()=>null),ur}function pr(e){let t=dr.get(e);return t||(t=fr().then(async t=>t?(await t.loadLanguage(cr[e]),!0):!1).catch(()=>!1),dr.set(e,t)),t.then(e=>e?fr():null)}var mr={async preload(e){await pr(e)},async tokenize(e,t){let n=await pr(t);if(!n)return null;try{let{tokens:r,fg:i}=n.codeToTokens(e,{lang:t,theme:lr}),a=i?.toLowerCase();return r.map(e=>e.map(e=>({content:e.content,...e.color&&e.color.toLowerCase()!==a?{color:e.color}:{}})))}catch{return null}}};function hr(e,t=mr){return Promise.all(e.map(e=>t.preload(e))).then(()=>void 0)}var gr=/^#[0-9a-f]{3,8}$/i;function _r(e,t){return!t||t.map(e=>e.content).join(``)!==e?null:t.map(e=>e.color&&gr.test(e.color)?`<span style="color:${e.color}">${Mn(e.content)}</span>`:Mn(e.content)).join(``)}function vr(e){return e.length>1e3?e.slice(0,Nn):e}function yr(e,t,n){if(!e||t===``)return;let r=_r(vr(t),n);if(r===null)return;if(t.length<=1e3){if(e.childElementCount!==0||e.textContent!==t)return;e.innerHTML=r;return}let i=e.querySelector(`[data-full-line]`);i&&(e.innerHTML=`${r}… `,e.append(i))}async function br(e,t,n=mr){let r=or(t.path);if(!r){delete e.dataset.syntax;return}e.dataset.syntax=r;let i=e.querySelector(`tbody`);if(!i)return;let a=()=>i.isConnected&&e.querySelector(`tbody`)===i,o=await n.tokenize(t.lines.map(vr).join(`
98
- `),r);if(a()){o&&t.lines.forEach((e,n)=>{yr(i.querySelector(`tr[data-line="${t.from+n}"] .prb-code-line`),e,o[n])});for(let e of t.deletions??[]){if(!i.querySelector(`tr[data-before-line="${e.beforeLine}"]`))continue;let t=await n.tokenize(e.lines.map(e=>vr(e.text)).join(`
99
- `),r);if(!a())return;if(!t)continue;let o=i.querySelector(`tr[data-before-line="${e.beforeLine}"]`)?.nextElementSibling;for(let[n,r]of e.lines.entries()){if(!o?.classList.contains(`prb-code-deleted`))break;yr(o.querySelector(`.prb-code-line`),r.text,t[n]),o=o.nextElementSibling}}}}async function xr(e,t=mr){let n=e.closest(`.prb-code`)?.dataset.syntax,r=e.textContent??``;if(!n||!(n in cr)||r===``)return;let i=await t.tokenize(r,n);if(!e.isConnected||e.childElementCount!==0||e.textContent!==r)return;let a=_r(r,i?.[0]);a!==null&&i?.length===1&&(e.innerHTML=a)}var w=document.body,Sr=w.dataset.apiBase??``,Cr=w.dataset.token??``,wr=w.dataset.editorLabel??``,Tr=w.dataset.editorTemplate??``,Er=w.dataset.repoPath??``,Dr=w.dataset.explainPrompt??``,Or=w.dataset.sessionId??``;function T(e){return`${Sr}${e}?t=${encodeURIComponent(Cr)}`}function E(e){fetch(T(`/event`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e),keepalive:!0}).catch(()=>{})}var kr=dn({endpoint:T,showDiagrams:()=>Pr(`diagram`)}),Ar=null,jr=`whole change`;function Mr(e){let t=vt(e);window.location.hash!==t&&history.pushState(e,``,t),Nr(e)}function Nr(e){e.kind===`view`?Ir(e.view):Br(e.sectionId)}function Pr(e){Mr({kind:`view`,view:e})}function Fr(e){Mr({kind:`section`,sectionId:e})}function Ir(e){for(let t of document.querySelectorAll(`.prb-view`))t.hidden=t.dataset.view!==e;for(let t of document.querySelectorAll(`[data-view-nav]`))t.setAttribute(`aria-current`,String(t.dataset.viewNav===e));E({event:`view_opened`,view:e}),e===`diagram`&&kr.drawPane(),Lr(),document.querySelector(`.prb-doc`)?.scrollTo({top:0})}function Lr(){ft(),Ar=null,jr=`whole change`,Vr()}function Rr(e,t){let n=document.getElementById(e.getAttribute(`aria-controls`)??``);n&&(e.setAttribute(`aria-expanded`,String(t)),e.setAttribute(`aria-label`,`${t?`Collapse`:`Expand`} ${e.dataset.railToggle??`this section`}`),n.hidden=!t)}function zr(){for(let e of document.querySelectorAll(`[data-rail-toggle]`)){let t=document.getElementById(e.getAttribute(`aria-controls`)??``);(t?.contains(document.getElementById(`prb-rail-path`))||t?.id===`prb-rail-path`)&&Rr(e,!0)}}function Br(e){Ir(`guide`),zr(),dt(e);let t=lt(e);if(!t)return;let n=document.querySelector(`[data-goto-section="${CSS.escape(e)}"]`);E({event:`theme_opened`,themeIndex:Number(n?.dataset.themeIndex??-1),attention:n?.querySelector(`.prb-attention`)?.dataset.attention??`medium`,isRecommendedStart:n?.dataset.recommendedStart===`true`}),Ar=e,jr=t.querySelector(`.pr-helper-guide-section-title`)?.textContent?.trim()??`this theme`,Vr()}function Vr(){let e=document.querySelector(`[data-ask-scope]`);e&&(e.textContent=jr,e.title=Ar?`Questions are answered about "${jr}"`:`Questions cover the whole change`)}function D(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}function Hr(e){return e.tagName===`LI`?{parent:e,position:`beforeend`}:{parent:e,position:`afterend`}}async function Ur(e){let t=e.tagName===`LI`?e.querySelector(`:scope > .prb-code`):e.nextElementSibling;if(t?.classList.contains(`prb-code`)){t.remove(),e.setAttribute(`aria-expanded`,`false`);return}let n=e.dataset.file;if(!n)return;let r=Number(e.dataset.line)||0,i=e.tagName!==`LI`,a=document.createElement(`div`);a.className=`prb-code`,a.innerHTML=`<p class="prb-code-status">Reading…</p>`;let{parent:o,position:s}=Hr(e);o.insertAdjacentElement(s,a),e.setAttribute(`aria-expanded`,`true`),E({event:`file_opened`,fromFinding:i,targeted:r>0}),await Wr(a,n,{cited:r,centre:r,expand:0,position:r?2*r:0})}async function Wr(e,t,n){try{let{centre:r,expand:i}=n,a=`&path=${encodeURIComponent(t)}${r?`&line=${r}`:``}${i?`&expand=${i}`:``}`,o=await fetch(`${T(`/file`)}${a}`),s=await o.json();if(!o.ok){e.innerHTML=`<p class="prb-code-status">${D(s?.error??`Could not read that file.`)}</p>`;return}Gr(e,s,n)}catch{e.innerHTML=`<p class="prb-code-status">Could not reach PR Review Buddy. The workspace server may have stopped.</p>`}}function Gr(e,t,n){let{cited:r,centre:i,expand:a}=n,o=Ln(t,r),s=Tr&&Er?t.checkout===`absent`?`<button type="button" class="prb-code-open" disabled>Not in your working folder</button>`:`<button type="button" class="prb-code-open" data-open-editor="${D(t.path)}" data-open-line="${r||t.from}">${D(`Open in ${wr||`editor`}`)}</button>`:``,c=t.pullRequest&&t.pullRequest.precise?`<a class="prb-code-open prb-code-pr" href="${D(t.pullRequest.href)}" target="_blank" rel="noopener noreferrer">${D(t.pullRequest.label)}</a>`:``,l=t.truncated?`<button type="button" class="prb-code-more" data-expand-file="${D(t.path)}" data-expand-line="${i||0}" data-expand-cited="${r||0}" data-expand-step="${Jn(a,i)}">Show more of this file</button>`:``,u=t.checkout===`differs`?` · your editor will show a different version`:t.checkout===`absent`?` · not in your working folder`:``,d=t.changes===`unavailable`?` · change details unavailable`:``,ee=`<div class="prb-code-source"><span>${t.source===`commit`?`Viewing reviewed version${t.sourceSha?` <code>${D(t.sourceSha.slice(0,7))}</code>`:``}${u}${d}`:`Viewing your working folder${d}`}</span>${Un(t.changeAnchors??[],n.position)}</div>`,f=e.hasAttribute(`data-expanded`),p=`<button type="button" class="prb-code-open" data-code-expand aria-expanded="${f}">${f?`Collapse`:`Expand`}</button>`;e.innerHTML=`<div class="prb-code-header">
97
+ </span>`}function ur(e,t){let n=(e.dataset.changeKeys??``).split(`,`).filter(Boolean).map(Number),r=Number(e.dataset.changePosition)||0,i=t===`next`?n.find(e=>e>r):[...n].reverse().find(e=>e<r);return i===void 0?null:{key:i,anchor:cr(i)}}function dr(e,t){return e.querySelector(t.deletion?`tr[data-before-line="${t.line}"]`:`tr[data-line="${t.line}"]`)}function fr(e){return(e.dataset.changeKeys??``).split(`,`).filter(Boolean).map(Number).map(cr)}function pr(e){if(!e)return;let t=Number(e.dataset.changePosition)||0;return(e.dataset.changeKeys??``).split(`,`).filter(Boolean).map(Number).includes(t)?cr(t):void 0}function mr(e,t){return Math.max(e,+!t)+1}var hr=8;function gr(e){for(let t=e.parentElement;t;t=t.parentElement){let e=getComputedStyle(t).overflowY;if(e===`auto`||e===`scroll`)return t}return null}function _r(e){let t=e.panel-e.scroller;return Math.max(340,Math.floor(e.pane-t-16))}function vr(e){let t=e.getBoundingClientRect().top;for(let n of e.querySelectorAll(`tr`)){let e=n.getBoundingClientRect();if(e.bottom>t)return{row:n,offset:e.top-t}}return null}function yr(e,t){let n=t.row.getBoundingClientRect().top-e.getBoundingClientRect().top-t.offset;e.scrollTop+=n}function br(e){if(!e.hasAttribute(`data-expanded`))return;let t=gr(e),n=e.querySelector(`.prb-code-scroll`);if(!t||!n)return;let r=_r({pane:t.clientHeight,panel:e.offsetHeight,scroller:n.offsetHeight});e.style.setProperty(`--prb-code-expanded`,`${r}px`)}function xr(e){let t=e.querySelector(`[data-code-expand]`),n=e.querySelector(`.prb-code-scroll`);if(!t||!n)return;let r=e.hasAttribute(`data-expanded`);t.hidden=!r&&n.scrollHeight<=n.clientHeight,t.textContent=r?`Collapse`:`Expand`,t.setAttribute(`aria-expanded`,String(r))}var Sr=!1;function Cr(){Sr||(Sr=!0,window.addEventListener(`resize`,()=>{for(let e of document.querySelectorAll(`.prb-code[data-expanded]`))br(e)}))}function wr(e,t){let n=e.querySelector(`.prb-code-scroll`),r=n?vr(n):null;t?(e.setAttribute(`data-expanded`,``),br(e),Cr()):(e.removeAttribute(`data-expanded`),e.style.removeProperty(`--prb-code-expanded`)),xr(e),n&&r&&yr(n,r);let i=t?gr(e):null;i&&(i.scrollTop+=e.getBoundingClientRect().top-i.getBoundingClientRect().top-hr)}var Tr={rb:`ruby`,js:`javascript`,mjs:`javascript`,cjs:`javascript`,ts:`typescript`,mts:`typescript`,cts:`typescript`,jsx:`jsx`,tsx:`tsx`,json:`json`,yml:`yaml`,yaml:`yaml`,md:`markdown`,html:`html`,css:`css`,scss:`scss`,sql:`sql`,py:`python`,java:`java`,kt:`kotlin`,kts:`kotlin`,go:`go`,rs:`rust`,sh:`shellscript`,bash:`shellscript`,zsh:`shellscript`,tf:`terraform`,tfvars:`terraform`};function Er(e){let t=e.slice(e.lastIndexOf(`/`)+1);if(t===`Dockerfile`||t.startsWith(`Dockerfile.`))return`docker`;let n=t.lastIndexOf(`.`);return n<=0?null:Tr[t.slice(n+1).toLowerCase()]??null}function Dr(e){let t=new Set;for(let n of e){let e=Er(n);e&&t.add(e)}return[...t]}var Or={ruby:()=>w(()=>import(`./chunk-CAnKkQXq.js`),__vite__mapDeps([19,20,21,22,23,24,25,26,27,28,29])),javascript:()=>w(()=>import(`./chunk-D2pwppYQ.js`),__vite__mapDeps([30,21])),typescript:()=>w(()=>import(`./chunk-Cjc271yU.js`),__vite__mapDeps([31,26])),jsx:()=>w(()=>import(`./chunk-B2PgDgse.js`),__vite__mapDeps([32,24])),tsx:()=>w(()=>import(`./chunk-D95j_xjm.js`),__vite__mapDeps([33,27])),json:()=>w(()=>import(`./chunk-qhed-kSA.js`),[]),yaml:()=>w(()=>import(`./chunk-Cv3JjNkX.js`),__vite__mapDeps([34,29])),markdown:()=>w(()=>import(`./chunk-BYOwaDjH.js`),[]),html:()=>w(()=>import(`./chunk-EIJEcyW-.js`),__vite__mapDeps([35,22,20,21])),css:()=>w(()=>import(`./chunk-C3nvJp0N.js`),__vite__mapDeps([36,20])),scss:()=>w(()=>import(`./chunk-D2NZorQR.js`),__vite__mapDeps([37,20])),sql:()=>w(()=>import(`./chunk-NzFayA7r.js`),__vite__mapDeps([38,25])),python:()=>w(()=>import(`./chunk-gzcpVVnB.js`),[]),java:()=>w(()=>import(`./chunk-AdYjtsZU.js`),__vite__mapDeps([39,23])),kotlin:()=>w(()=>import(`./chunk-DhhofPvG.js`),[]),go:()=>w(()=>import(`./chunk-rLFTqkRN.js`),[]),rust:()=>w(()=>import(`./chunk-Cfkwpbl8.js`),[]),shellscript:()=>w(()=>import(`./chunk-pNSm1SyV.js`),__vite__mapDeps([40,28])),docker:()=>w(()=>import(`./chunk-IyjqRm3v.js`),[]),terraform:()=>w(()=>import(`./chunk-DswuEJGm.js`),[])},kr=`github-light-default`,Ar=null,jr=new Map;function Mr(){return Ar??=Promise.all([w(()=>import(`./chunk-c-cg1wCO.js`),__vite__mapDeps([41,3])),w(()=>import(`./chunk-CBrdyqSx.js`),__vite__mapDeps([42,3])),w(()=>import(`./chunk-BXViO-2h.js`),[])]).then(([{createHighlighterCore:e},{createOnigurumaEngine:t},n])=>e({themes:[n.default],langs:[],engine:t(w(()=>import(`./chunk-BnjxR4X6.js`),[]))})).catch(()=>null),Ar}function Nr(e){let t=jr.get(e);return t||(t=Mr().then(async t=>t?(await t.loadLanguage(Or[e]),!0):!1).catch(()=>!1),jr.set(e,t)),t.then(e=>e?Mr():null)}var Pr={async preload(e){await Nr(e)},async tokenize(e,t){let n=await Nr(t);if(!n)return null;try{let{tokens:r,fg:i}=n.codeToTokens(e,{lang:t,theme:kr}),a=i?.toLowerCase();return r.map(e=>e.map(e=>({content:e.content,...e.color&&e.color.toLowerCase()!==a?{color:e.color}:{}})))}catch{return null}}};function Fr(e,t=Pr){return Promise.all(e.map(e=>t.preload(e))).then(()=>void 0)}var Ir=/^#[0-9a-f]{3,8}$/i;function Lr(e,t){return!t||t.map(e=>e.content).join(``)!==e?null:t.map(e=>e.color&&Ir.test(e.color)?`<span style="color:${e.color}">${Qn(e.content)}</span>`:Qn(e.content)).join(``)}function Rr(e){return e.length>1e3?e.slice(0,$n):e}function zr(e,t,n){if(!e||t===``)return;let r=Lr(Rr(t),n);if(r===null)return;if(t.length<=1e3){if(e.childElementCount!==0||e.textContent!==t)return;e.innerHTML=r;return}let i=e.querySelector(`[data-full-line]`);i&&(e.innerHTML=`${r}… `,e.append(i))}async function Br(e,t,n=Pr){let r=Er(t.path);if(!r){delete e.dataset.syntax;return}e.dataset.syntax=r;let i=e.querySelector(`tbody`);if(!i)return;let a=()=>i.isConnected&&e.querySelector(`tbody`)===i,o=await n.tokenize(t.lines.map(Rr).join(`
98
+ `),r);if(a()){o&&t.lines.forEach((e,n)=>{zr(i.querySelector(`tr[data-line="${t.from+n}"] .prb-code-line`),e,o[n])});for(let e of t.deletions??[]){if(!i.querySelector(`tr[data-before-line="${e.beforeLine}"]`))continue;let t=await n.tokenize(e.lines.map(e=>Rr(e.text)).join(`
99
+ `),r);if(!a())return;if(!t)continue;let o=i.querySelector(`tr[data-before-line="${e.beforeLine}"]`)?.nextElementSibling;for(let[n,r]of e.lines.entries()){if(!o?.classList.contains(`prb-code-deleted`))break;zr(o.querySelector(`.prb-code-line`),r.text,t[n]),o=o.nextElementSibling}}}}async function Vr(e,t=Pr){let n=e.closest(`.prb-code`)?.dataset.syntax,r=e.textContent??``;if(!n||!(n in Or)||r===``)return;let i=await t.tokenize(r,n);if(!e.isConnected||e.childElementCount!==0||e.textContent!==r)return;let a=Lr(r,i?.[0]);a!==null&&i?.length===1&&(e.innerHTML=a)}var E=document.body,Hr=E.dataset.apiBase??``,Ur=E.dataset.token??``,Wr=E.dataset.editorLabel??``,Gr=E.dataset.editorTemplate??``,Kr=E.dataset.repoPath??``,qr=E.dataset.explainPrompt??``,Jr=E.dataset.sessionId??``;function D(e){return`${Hr}${e}?t=${encodeURIComponent(Ur)}`}function O(e){fetch(D(`/event`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e),keepalive:!0}).catch(()=>{})}var Yr=jn({endpoint:D,showDiagrams:()=>ii(`diagram`)}),Xr=null,Zr=`whole change`;function Qr(e){let t=ft(e,$r),n=S(t);window.location.hash!==n&&history.pushState(t,``,n),ei(t)}var k=null,$r=document.querySelector(`[data-guide-start]`)?.dataset.guideStart??null;function ei(e){let t=ft(e,$r);if(t!==e){let{kind:e,view:n,focus:r,...i}=history.state??{};history.replaceState({...i,...t},``,S(t))}let n=!k||!vt(k,t);k=t,n&&(t.kind===`view`?oi(t.view):ui(t.sectionId)),ni(t.focus??null)}var A={history,apply:ei},ti=kt(document,{onOpen:e=>e.hasAttribute(`data-ask-buddy-menu`)?Ca(e):wa(e),onClose:wa});function ni(e){St(document.querySelector(`.prb-body`),document,e),ti.closeAll(),e===`buddy`&&z()}function ri(e){k&&(k.focus===e?bt(k,A):yt(k,e,A))}window.addEventListener(`keydown`,e=>{!k||!xt(e,document,!!k.focus)||(e.preventDefault(),bt(k,A))},!0);function ii(e){Qr({kind:`view`,view:e})}function ai(e){Qr({kind:`section`,sectionId:e,...k?.focus===`guide`?{focus:`guide`}:{}})}function oi(e){for(let t of document.querySelectorAll(`.prb-view`))t.hidden=t.dataset.view!==e;for(let t of document.querySelectorAll(`[data-view-nav]`))t.setAttribute(`aria-current`,String(t.dataset.viewNav===e));O({event:`view_opened`,view:e}),e===`diagram`&&Yr.drawPane(),si(),document.querySelector(`.prb-doc`)?.scrollTo({top:0})}function si(){Rt(),Xr=null,Zr=`whole change`,di()}function ci(e,t){let n=document.getElementById(e.getAttribute(`aria-controls`)??``);n&&(e.setAttribute(`aria-expanded`,String(t)),e.setAttribute(`aria-label`,`${t?`Collapse`:`Expand`} ${e.dataset.railToggle??`this section`}`),n.hidden=!t)}function li(){for(let e of document.querySelectorAll(`[data-rail-toggle]`)){let t=document.getElementById(e.getAttribute(`aria-controls`)??``);(t?.contains(document.getElementById(`prb-rail-path`))||t?.id===`prb-rail-path`)&&ci(e,!0)}}function ui(e){oi(`guide`),li(),Lt(e);let t=Ft(e);if(!t)return;let n=document.querySelector(`[data-goto-section="${CSS.escape(e)}"]`);O({event:`theme_opened`,themeIndex:Number(n?.dataset.themeIndex??-1),attention:n?.querySelector(`.prb-attention`)?.dataset.attention??`medium`,isRecommendedStart:n?.dataset.recommendedStart===`true`}),Xr=e,Zr=t.querySelector(`.pr-helper-guide-section-title`)?.textContent?.trim()??`this theme`,di()}function di(){let e=document.querySelector(`[data-ask-scope]`);e&&(e.textContent=Zr,e.title=Xr?`Questions are answered about "${Zr}"`:`Questions cover the whole change`)}function j(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}function fi(e){return e.tagName===`LI`?{parent:e,position:`beforeend`}:{parent:e,position:`afterend`}}async function pi(e){let t=e.tagName===`LI`?e.querySelector(`:scope > .prb-code`):e.nextElementSibling;if(t?.classList.contains(`prb-code`)){t.remove(),e.setAttribute(`aria-expanded`,`false`);return}let n=e.dataset.file;if(!n)return;let r=Number(e.dataset.line)||0,i=e.tagName!==`LI`,a=document.createElement(`div`);a.className=`prb-code`,a.innerHTML=`<p class="prb-code-status">Reading…</p>`;let{parent:o,position:s}=fi(e);o.insertAdjacentElement(s,a),e.setAttribute(`aria-expanded`,`true`),O({event:`file_opened`,fromFinding:i,targeted:r>0}),await mi(a,n,{cited:r,centre:r,expand:0,position:r?2*r:0})}async function mi(e,t,n){try{let{centre:r,expand:i}=n,a=`&path=${encodeURIComponent(t)}${r?`&line=${r}`:``}${i?`&expand=${i}`:``}`,o=await fetch(`${D(`/file`)}${a}`),s=await o.json();if(!o.ok){e.innerHTML=`<p class="prb-code-status">${j(s?.error??`Could not read that file.`)}</p>`;return}hi(e,s,n)}catch{e.innerHTML=`<p class="prb-code-status">Could not reach PR Review Buddy. The workspace server may have stopped.</p>`}}function hi(e,t,n){let{cited:r,centre:i,expand:a}=n,o=rr(t,r),s=Gr&&Kr?t.checkout===`absent`?`<button type="button" class="prb-code-open" disabled>Not in your working folder</button>`:`<button type="button" class="prb-code-open" data-open-editor="${j(t.path)}" data-open-line="${r||t.from}">${j(`Open in ${Wr||`editor`}`)}</button>`:``,c=t.pullRequest&&t.pullRequest.precise?`<a class="prb-code-open prb-code-pr" href="${j(t.pullRequest.href)}" target="_blank" rel="noopener noreferrer">${j(t.pullRequest.label)}</a>`:``,l=t.truncated?`<button type="button" class="prb-code-more" data-expand-file="${j(t.path)}" data-expand-line="${i||0}" data-expand-cited="${r||0}" data-expand-step="${mr(a,i)}">Show more of this file</button>`:``,u=t.checkout===`differs`?` · your editor will show a different version`:t.checkout===`absent`?` · not in your working folder`:``,d=t.changes===`unavailable`?` · change details unavailable`:``,ee=`<div class="prb-code-source"><span>${t.source===`commit`?`Viewing reviewed version${t.sourceSha?` <code>${j(t.sourceSha.slice(0,7))}</code>`:``}${u}${d}`:`Viewing your working folder${d}`}</span>${lr(t.changeAnchors??[],n.position)}</div>`,f=e.hasAttribute(`data-expanded`),te=`<button type="button" class="prb-code-open" data-code-expand aria-expanded="${f}">${f?`Collapse`:`Expand`}</button>`;e.innerHTML=`<div class="prb-code-header">
100
100
  <span class="prb-code-range">lines ${t.from}\u2013${t.to} of ${t.totalLines}</span>
101
101
  ${c}
102
102
  ${s}
103
- ${p}
103
+ ${te}
104
104
  </div>
105
105
  ${ee}
106
106
  <div class="prb-code-scroll"><table class="prb-code-table"><tbody>${o}</tbody></table></div>
107
- ${l}`,zn(e,t),er(e),tr(e),(n.focus?Gn(e,n.focus):e.querySelector(`.prb-code-target`))?.scrollIntoView({block:`center`}),br(e,t)}async function Kr(e,t,n){let r=Wn(t,n);if(!r)return;let i=Gn(e,r.anchor);if(i)t.outerHTML=Un(Kn(t),r.key),i.scrollIntoView({block:`center`});else{let t=e.querySelector(`[data-expand-file]`);if(!t?.dataset.expandFile)return;await Wr(e,t.dataset.expandFile,{cited:Number(t.dataset.expandCited)||0,centre:r.anchor.line,expand:Math.max(1,(Number(t.dataset.expandStep)||1)-1),position:r.key,focus:r.anchor})}let a=e.querySelector(`[data-change-step="${n}"]`),o=e.querySelector(`[data-change-step="${n===`next`?`previous`:`next`}"]`);(a&&!a.disabled?a:o)?.focus({preventScroll:!0})}function qr(e,t,n){let r=`${Er.replace(/\/$/,``)}/${e}`,i=Tr.replace(`{path}`,r).replace(`{line}`,String(Math.max(1,t)));E({event:`editor_opened`,fromFinding:n}),window.location.href=i}var O=document.querySelector(`[data-ask-log]`);O&&O.querySelector(`.prb-msg`)&&O.scrollTo({top:O.scrollHeight});var k=document.querySelector(`[data-ask-form]`),A=k?.querySelector(`textarea`);function Jr(e,t){let n=document.createElement(`div`);return n.className=e===`user`?`prb-msg prb-msg-user`:`prb-msg prb-msg-${e===`error`?`error`:`assistant`}`,e===`assistant`?(n.classList.add(`prb-md`),n.innerHTML=te(t)+je(t)):n.textContent=t,O?.appendChild(n),O?.scrollTo({top:O.scrollHeight}),n}function Yr(){let e=document.createElement(`div`);return e.className=`prb-thinking`,e.innerHTML=`<i></i><i></i><i></i><span>Reading the change…</span>`,O?.appendChild(e),O?.scrollTo({top:O.scrollHeight}),e}var j=null,M=!!O?.querySelector(`[data-ask-pending]`);function Xr(){let e=document.createElement(`div`);e.className=`prb-stopped`,e.textContent=`Stopped.`,O?.appendChild(e),O?.scrollTo({top:O.scrollHeight})}async function Zr(e,t=`free_text`){let n=e.trim();if(!n||j||M)return;document.querySelector(`.prb-ask-empty`)?.remove(),Jr(`user`,n);let r=Yr();j=new AbortController,Qr(!0);try{let e=await fetch(T(`/ask`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({question:n,sectionId:Ar,source:t}),signal:j.signal}),i=await e.json().catch(()=>null);if(e.status===409&&(i?.running||i?.updating)){window.location.reload();return}if(r.remove(),i?.stopped){Xr();return}if(!e.ok||!i?.answer){Jr(`error`,i?.error??`Buddy AI did not answer. Check the terminal running PR Review Buddy.`);return}Jr(`assistant`,i.answer)}catch(e){r.remove(),e instanceof DOMException&&e.name===`AbortError`?(Xr(),A&&!A.value&&(A.value=n)):Jr(`error`,`Could not reach PR Review Buddy. The workspace server may have stopped.`)}finally{j=null,Qr(!1)}}function Qr(e){let t=k?.querySelector(`button`);t&&(t.textContent=e?`Stop`:`Ask`,t.toggleAttribute(`data-stop`,e),t.disabled=!1),A&&(A.disabled=e);for(let t of document.querySelectorAll($r))t.disabled=e;e||A?.focus()}var $r=`[data-suggestion], .pr-helper-explain-simply-button`;function ei(){let e=k?.querySelector(`button`);e&&(e.textContent=`Stopping…`,e.disabled=!0),fetch(T(`/stop`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({kind:`ask`})}).catch(()=>{}).finally(()=>{j?.abort()})}k?.addEventListener(`submit`,e=>{if(e.preventDefault(),j||M)return ei();let t=A?.value??``;A&&(A.value=``),Zr(t,ni(t))}),M&&Qr(!0);var ti=null;function ni(e){return ti&&e.includes(ti)?`selection`:`free_text`}A?.addEventListener(`keydown`,e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),k?.requestSubmit())}),A?.addEventListener(`input`,()=>{A&&(A.style.height=`auto`,A.style.height=`${Math.min(A.scrollHeight,140)}px`)});async function ri(e){try{await fetch(T(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({answeredQuestionIds:e})})}catch{}}function ii(){return[...document.querySelectorAll(`[data-question-answered][data-answered="true"]`)].map(e=>e.dataset.questionAnswered??``).filter(Boolean)}function ai(e,t){e.dataset.answered=String(t),e.textContent=t?`Mark as unanswered`:`Mark answered`;let n=e.closest(`[data-finding-card]`);n?.classList.toggle(`pr-helper-question-card-answered`,t),n&&di(n,t,`questions`),_i()}function oi(){return[...document.querySelectorAll(`[data-issue-dismissed][data-dismissed="true"]`)].map(e=>({id:e.dataset.issueDismissed??``,sessionId:e.dataset.dismissedIn||Or})).filter(e=>e.id)}async function si(e){try{await fetch(T(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissedIssues:e})})}catch{}}function ci(e,t){e.dataset.dismissed=String(t),e.textContent=t?`Reopen`:`Dismiss`,delete e.dataset.stale,t?e.dataset.dismissedIn=Or:delete e.dataset.dismissedIn;let n=e.closest(`[data-finding-card]`);n&&(n.classList.toggle(`pr-helper-issue-card-dismissed`,t),n.querySelector(`.pr-helper-dismissal-stale`)?.remove(),n.querySelector(`.pr-helper-finding-status-dismissed`)?.remove(),t&&n.querySelector(`.pr-helper-issue-badges`)?.prepend(li()),di(n,t||e.dataset.settled===`true`,`issues`),yi())}function li(){let e=document.createElement(`span`);return e.className=`pr-helper-finding-status pr-helper-finding-status-dismissed pr-helper-tip`,e.dataset.tip=at,e.textContent=`Dismissed by you`,e}var ui=new WeakMap;function di(e,t,n){let r=e.closest(`.pr-helper-closed-findings-list`);if(t!==!!r){if(t){let t=e.parentElement;t&&ui.set(e,{parent:t,before:e.nextElementSibling}),hi(n).append(e),t&&mi(t)}else fi(e,n),(r?.children.length===0?r.closest(`.pr-helper-closed-findings`):null)?.remove();gi(n)}}function fi(e,t){let n=ui.get(e);if(n?.parent.isConnected)n.parent.insertBefore(e,n.before);else{let n=pi(e)??document.querySelector(`[data-view="${t}"]`);n?.insertBefore(e,n.querySelector(`.pr-helper-closed-findings`))}e.closest(`.pr-helper-question-group`)?.removeAttribute(`hidden`)}function pi(e){let t=e.dataset.sectionId;return t?document.querySelector(`[data-question-group="${CSS.escape(t)}"]`):null}function mi(e){let t=e.closest(`.pr-helper-question-group`);t&&!t.querySelector(`[data-finding-card]`)&&(t.hidden=!0)}function hi(e){let t=document.querySelector(`[data-view="${e}"]`),n=t?.querySelector(`[data-closed-findings="${e}"] .pr-helper-closed-findings-list`);if(n)return n;let r=document.createElement(`details`);r.className=`pr-helper-closed-findings`,r.dataset.closedFindings=e;let i=document.createElement(`summary`);i.className=`pr-helper-closed-findings-summary`,i.setAttribute(`data-closed-findings-summary`,``);let a=document.createElement(`div`);return a.className=`pr-helper-closed-findings-list`,r.append(i,a),t?.append(r),a}function gi(e){let t=document.querySelector(`[data-closed-findings="${e}"]`),n=t?.querySelector(`[data-closed-findings-summary]`);if(!t||!n)return;let r=document.querySelectorAll(`[data-view="${e}"] [data-finding-card]`).length,i=t.querySelectorAll(`[data-finding-card]`).length;if(t.toggleAttribute(`data-nothing-open`,r===i),e===`questions`){n.textContent=`Answered (${i})`;return}n.textContent=st(vi())}function _i(){let e=[...document.querySelectorAll(`[data-question-answered]`)];if(e.length===0)return;let t=e.filter(e=>e.dataset.answered!==`true`&&e.dataset.settled!==`true`).length,n=document.querySelector(`.pr-helper-questions-progress`);n&&(n.innerHTML=ct(e.length,t)),bi(`questions`,e.length,t,`question`,`answered`)}function vi(){let e=[...document.querySelectorAll(`[data-issue-dismissed]`)],t=0,n=0;for(let r of e){let e=r.dataset.settled===`true`,i=r.dataset.dismissed===`true`&&r.dataset.stale!==`true`;!e&&!i?t+=1:!e&&i&&(n+=1)}return{total:e.length,open:t,done:e.length-t,reviewerClosed:n}}function yi(){let e=vi();if(e.total===0)return;let t=document.querySelector(`[data-view="issues"]`),n=t?.querySelector(`.pr-helper-findings-progress`);!n&&t&&e.done>0&&(n=document.createElement(`div`),n.className=`pr-helper-findings-progress`,n.setAttribute(`role`,`status`),t.querySelector(`.prb-doc-title`)?.after(n)),n&&(n.innerHTML=ot(e.total,e.open,it(e))),bi(`issues`,e.total,e.open,`issue`,it(e))}function bi(e,t,n,r,i){let a=document.querySelector(`[data-view-nav="${e}"] .prb-rail-count`);if(!a)return;let o=e=>`${e} ${r}${e===1?``:`s`}`,s=t-n;a.classList.toggle(`prb-rail-count-done`,t>0&&n===0),t===0?(a.textContent=`0`,a.setAttribute(`aria-label`,`No ${r}s`)):n===0?(a.textContent=`✓`,a.setAttribute(`aria-label`,`All ${o(t)} ${i}`)):(a.textContent=String(n),a.setAttribute(`aria-label`,s===0?o(t):`${n} of ${o(t)} left, ${s} ${i}`))}document.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`[data-rail-toggle]`);if(n){Rr(n,n.getAttribute(`aria-expanded`)!==`true`);return}let r=t.closest(`[data-view-nav]`);if(r?.dataset.viewNav){Pr(r.dataset.viewNav);return}let i=t.closest(`[data-overview-nav]`);if(i?.dataset.overviewNav){Pr(i.dataset.overviewNav===`guide`?`guide`:i.dataset.overviewNav);return}let a=t.closest(`[data-goto-section]`);if(a?.dataset.gotoSection){Fr(a.dataset.gotoSection);return}let o=t.closest(`[data-open-editor]`);if(o?.dataset.openEditor){qr(o.dataset.openEditor,Number(o.dataset.openLine)||1,!0);return}let s=t.closest(`[data-deletion-toggle]`);if(s){Rn(s);return}let c=t.closest(`[data-code-expand]`);if(c){let e=c.closest(`.prb-code`);e&&ir(e,!e.hasAttribute(`data-expanded`));return}let l=t.closest(`[data-change-step]`);if(l){let e=l.closest(`[data-change-navigator]`),t=l.closest(`.prb-code`);e&&t&&!l.disabled&&Kr(t,e,l.dataset.changeStep===`previous`?`previous`:`next`);return}let u=t.closest(`[data-full-line]`);if(u){let e=Bn(u);e&&xr(e);return}let d=t.closest(`[data-expand-file]`);if(d?.dataset.expandFile){let e=d.closest(`.prb-code`);if(e){let t=e.querySelector(`[data-change-navigator]`);Wr(e,d.dataset.expandFile,{cited:Number(d.dataset.expandCited)||0,centre:Number(d.dataset.expandLine)||0,expand:Number(d.dataset.expandStep)||1,position:Number(t?.dataset.changePosition)||0,focus:qn(t)})}return}let ee=t.closest(`[data-file]`);if(ee?.dataset.file){Ur(ee);return}let f=ut(t);if(f){Br(f);return}let p=t.closest(`[data-question-answered]`);if(p?.dataset.questionAnswered){ai(p,p.dataset.answered!==`true`);let e=ii();ri(e),E({event:`question_marked_answered`,answered:e.length,total:document.querySelectorAll(`[data-question-answered]`).length});return}let m=t.closest(`[data-issue-dismissed]`);if(m?.dataset.issueDismissed){ci(m,m.dataset.stale===`true`||m.dataset.dismissed!==`true`);let e=oi();si(e),E({event:`issue_dismissed`,dismissed:e.length,total:document.querySelectorAll(`[data-issue-dismissed]`).length});return}let te=t.closest(`[data-suggestion]`);if(te){Zr(te.textContent??``,`suggestion`);return}if(t.closest(`.pr-helper-explain-simply-button`)){Ci(),Zr(Dr,`explain_simply`);return}let ne=t.closest(`[data-prompt-use]`);if(ne?.dataset.promptUse){Ui(ne.dataset.promptUse);return}let re=t.closest(`[data-prompt-edit]`);if(re?.dataset.promptEdit){ta(re.dataset.promptEdit);return}if(t.closest(`[data-prompt-add]`)){ta(``);return}t.closest(`[data-ask-toggle]`)&&Si(!xi())});var N=document.querySelector(`.prb-body`),P=document.querySelector(`.prb-ask`);function xi(){return!!P&&getComputedStyle(P).display!==`none`}function Si(e){N&&(N.dataset.ask=e?`open`:`closed`),document.querySelector(`[data-ask-toggle]`)?.setAttribute(`aria-expanded`,String(e))}function Ci(){Si(!0)}function wi(){document.querySelector(`[data-ask-toggle]`)?.setAttribute(`aria-expanded`,String(xi()))}window.addEventListener(`resize`,wi),n(T(`/restart`));var F=document.querySelector(`[data-file-filter]`),Ti=document.querySelector(`[data-file-count]`),Ei=document.querySelector(`[data-file-none]`);function Di(){let e=(F?.value??``).trim().toLowerCase(),t=0,n=0;for(let r of document.querySelectorAll(`[data-view="files"] .prb-file`)){let i=e===``||(r.dataset.search??``).includes(e);r.hidden=!i,i&&(n+=1,r.classList.contains(`prb-file-referenced`)||(t+=1));let a=r.nextElementSibling;a?.classList.contains(`prb-code`)&&(a.hidden=!i)}for(let t of document.querySelectorAll(`[data-file-group]`)){let n=t.querySelectorAll(`.prb-file:not([hidden])`).length;t.hidden=n===0;let r=t.querySelector(`[data-group-heading]`);if(!r)continue;let i=Number(r.dataset.groupTotal)||0;r.textContent=e&&n!==i?`${r.dataset.groupHeading} · ${n} of ${i}`:`${r.dataset.groupHeading} · ${i}`}Ei&&(Ei.hidden=n>0),Ti&&(Ti.textContent=e?`${t} of ${Oi} file${Oi===1?``:`s`}`:`${Oi} file${Oi===1?``:`s`}`)}var Oi=document.querySelectorAll(`[data-view="files"] .prb-file:not(.prb-file-referenced)`).length;F?.addEventListener(`input`,Di),F?.addEventListener(`keydown`,e=>{e.key===`Escape`&&F.value!==``&&(e.preventDefault(),F.value=``,Di())}),document.addEventListener(`keydown`,e=>{if(e.key!==`Enter`&&e.key!==` `)return;let t=e.target,n=t.closest(`.prb-file[data-file][role="button"]`);!n||n!==t||(e.preventDefault(),Ur(n))});var ki=320,Ai=()=>Math.round(window.innerWidth/2),ji=e=>Math.round(Math.min(Ai(),Math.max(ki,e)));function I(e){N&&(e===null?N.style.removeProperty(`--ask-width`):N.style.setProperty(`--ask-width`,`${e}px`))}function Mi(){return P?Math.round(P.getBoundingClientRect().width):ki}function Ni(e){fetch(T(`/prefs`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({askWidth:e})}).catch(()=>{})}var L=document.querySelector(`[data-ask-resize]`);L?.addEventListener(`pointerdown`,e=>{if(e.button!==0||!N||!P)return;e.preventDefault(),L.setPointerCapture(e.pointerId),N.dataset.resizing=`true`;let t=e.clientX,n=Mi(),r=e=>{I(ji(n+(t-e.clientX)))},i=()=>{L.removeEventListener(`pointermove`,r),L.removeEventListener(`pointerup`,i),L.removeEventListener(`pointercancel`,i),delete N.dataset.resizing,Ni(Mi())};L.addEventListener(`pointermove`,r),L.addEventListener(`pointerup`,i),L.addEventListener(`pointercancel`,i)}),L?.addEventListener(`keydown`,e=>{let t=e.shiftKey?64:16;if(e.key===`ArrowLeft`||e.key===`ArrowRight`){e.preventDefault();let n=e.key===`ArrowLeft`?t:-t,r=ji(Mi()+n);I(r),Ni(r);return}(e.key===`Home`||e.key===`Escape`)&&(e.preventDefault(),I(null),Ni(null))}),L?.addEventListener(`dblclick`,()=>{I(null),Ni(null)}),window.addEventListener(`resize`,()=>{xi()&&N?.style.getPropertyValue(`--ask-width`)&&I(ji(Mi()))});var Pi=3e4,R=document.visibilityState===`visible`?Date.now():null,Fi=0;function Ii(){R!==null&&(Fi+=Date.now()-R,R=Date.now())}function Li(){Ii();let e=Math.round(Fi/1e3);return Fi-=e*1e3,e}document.addEventListener(`visibilitychange`,()=>{document.visibilityState===`visible`?R=Date.now():(Ii(),R=null)}),setInterval(()=>{let e=Li();e>0&&E({event:`workspace_heartbeat`,visibleSeconds:e})},Pi),window.addEventListener(`pagehide`,()=>{let e=T(`/event`),t=JSON.stringify({event:`review_completed`,trailingSeconds:Li()});navigator.sendBeacon?.(e,new Blob([t],{type:`application/json`}))||fetch(e,{method:`POST`,headers:{"content-type":`application/json`},body:t,keepalive:!0}).catch(()=>{})});var Ri=document.querySelector(`[data-prompt-bank]`),zi=document.querySelector(`[data-prompt-list]`),z=Bi();function Bi(){try{let e=JSON.parse(Ri?.dataset.prompts??`[]`);return Array.isArray(e)?e:[]}catch{return[]}}function Vi(){zi&&(zi.innerHTML=z.map(e=>`<span class="prb-bank-item">
108
- <button type="button" class="prb-bank-use" data-prompt-use="${D(e.id)}" title="${D(e.prompt)}">${D(e.name)}</button>
109
- <button type="button" class="prb-bank-edit" data-prompt-edit="${D(e.id)}" aria-label="Edit ${D(e.name)}">&#9998;</button>
110
- </span>`).join(``),Ji())}async function Hi(e){try{let t=await(await fetch(T(`/prompts`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({prompts:e})})).json().catch(()=>null);z=Array.isArray(t?.prompts)?t.prompts:z}catch{}Vi()}function Ui(e){let t=z.find(t=>t.id===e);!t||!A||(A.value=pt(A.value,t.prompt),Ci(),A.focus(),A.setSelectionRange(A.value.length,A.value.length),A.dispatchEvent(new Event(`input`)))}var Wi=document.querySelector(`.prb-doc`),Gi=null,Ki=null;function qi(){O&&(Ki?.(),Ki=we(O,{layout:`flat`,actions:Xe.map(e=>({id:e.id,label:e.label})),onChoose:(e,t)=>Yi(e,t)}))}function Ji(){Wi&&(Gi?.(),Gi=we(Wi,{triggerLabel:`Ask Buddy AI`,actions:[...Ye.map(e=>({id:e.id,label:e.label})),...z.map(e=>({id:nt(e.id),label:e.name,section:tt}))],onChoose:(e,t)=>Yi(e,t)}))}function Yi(e,t){let n=Xi(e,t);!n||!A||(ti=n,A.value=pt(A.value,n),Ci(),A.focus(),A.setSelectionRange(A.value.length,A.value.length),A.dispatchEvent(new Event(`input`)))}function Xi(e,t){let n=rt(e);if(n===null)return $e(t,e);let r=z.find(e=>e.id===n);if(!r)return null;let i=Qe(t);return i?`${i}\n\n${r.prompt}`:null}Ji(),qi(),He(document);var Zi=document.querySelector(`[data-prompt-dialog]`),B=document.querySelector(`[data-prompt-name]`),Qi=document.querySelector(`[data-prompt-text]`),$i=document.querySelector(`[data-prompt-delete]`),ea=document.getElementById(`prb-prompt-title`),V=``;function ta(e){let t=z.find(t=>t.id===e);V=t?.id??``,ea&&(ea.textContent=t?`Edit prompt`:`Save a prompt`),B&&(B.value=t?.name??``),Qi&&(Qi.value=t?.prompt??``),$i&&($i.hidden=!t),Zi?.showModal(),B?.focus()}async function na(){let e=B?.value.trim()??``,t=Qi?.value.trim()??``;if(!e||!t){(e?Qi:B)?.focus();return}let n=V?z.map(n=>n.id===V?{...n,name:e,prompt:t}:n):[...z,{id:crypto.randomUUID(),name:e,prompt:t}];Zi?.close(),await Hi(n)}async function ra(){if(!V)return;let e=z.filter(e=>e.id!==V);Zi?.close(),await Hi(e)}document.querySelector(`[data-prompt-cancel]`)?.addEventListener(`click`,()=>Zi?.close()),$i?.addEventListener(`click`,()=>void ra()),document.querySelector(`[data-prompt-save]`)?.addEventListener(`click`,()=>void na());var H=document.querySelector(`[data-complete]`);H?.addEventListener(`click`,()=>{let e=H.getAttribute(`aria-pressed`)!==`true`;ia(e),fetch(T(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({complete:e})}).then(async e=>{let t=await e.json().catch(()=>null);t&&ia(t.completedAt!==null)}).catch(()=>ia(!e))});function ia(e){H&&(H.setAttribute(`aria-pressed`,String(e)),H.textContent=e?`Reviewed`:`Mark reviewed`)}var U=document.querySelector(`[data-fresh-region]`),W=document.querySelector(`[data-fresh-status]`),G=document.querySelector(`[data-fresh-check]`),K=fa(U?.dataset.report),aa=`prb-fresh-reopen`,oa=ua(),q=U?.dataset.dismissedSha,sa=la(U?.dataset.availability),J=ca(U?.dataset.remote);function ca(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}function la(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}function ua(){try{return sessionStorage.getItem(aa)!==null&&(sessionStorage.removeItem(aa),!0)}catch{return!1}}oa&&Q(),G?.addEventListener(`click`,()=>void pa()),U?.addEventListener(`click`,e=>{let t=e.target;if(t.closest(`[data-fresh-close]`))return oa=!1,Q();let n=t.closest(`[data-fresh-dismiss]`);n&&(q=n.dataset.freshDismiss||void 0,oa=!1,Q(),da())});function da(){fetch(T(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissFreshnessSha:q??null})}).catch(()=>{})}function fa(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}var Y=!1;async function pa(){if(Y)return;Y=!0,va(!0);let e=ya(K,J),t=await ma(!1);t&&Sa(),Y=!1,t&&(K?.code.state===`changed`||J!==null)&&q!==void 0&&(q=void 0,da()),Q();let n=t?ya(K,J)===e?`No change`:`Updated`:`Could not check`;G&&wa(G,n,2600)}async function ma(e){try{let t=await(await fetch(`${T(`/freshness`)}${e?`&quiet=1`:``}`)).json();return K=t.report??null,sa=t.availability??null,J=t.remote??null,Z=t.kiss??null,t.kissDismissedSha!==void 0&&(ba=t.kissDismissedSha??void 0),t.prState!==void 0&&_a(t.prState),!0}catch{return!1}}async function ha(){if(Y||!U)return;Y=!0;let e=ya(K,J),t=JSON.stringify(Z),n=await ma(!0);Y=!1,ga=Date.now(),n&&(ya(K,J)!==e&&Q(),JSON.stringify(Z)!==t&&Sa())}var ga=Date.now();function _a(e){let t=document.querySelector(`[data-pr-state-slot]`);if(!t)return;let n=Bt(e,t.hasAttribute(`data-beside-number`));t.innerHTML!==n&&(t.innerHTML=n)}function va(e){G&&(G.disabled=e),W&&e&&(W.textContent=`Checking…`,W.dataset.state=`checking`)}function ya(e,t){if(!e)return JSON.stringify({report:`none`,remote:t});let{checkedAt:n,...r}=e;return JSON.stringify({...r,remote:t})}var X=document.querySelector(`[data-kiss-fresh-region]`),Z=xa(X?.dataset.freshness),ba=X?.dataset.dismissedSha;function xa(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}function Sa(){X&&(X.innerHTML=zt(X.dataset.reviewedSha??``,Z,{dismissedSha:ba,actions:Cr!==``}))}X?.addEventListener(`click`,e=>{let t=e.target.closest(`[data-kiss-freshness-dismiss]`);t&&(ba=t.dataset.kissFreshnessDismiss||void 0,Sa(),fetch(T(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissKissFreshnessSha:ba??null})}).catch(()=>{}))});function Q(){if(U&&(U.innerHTML=Et(K,{dismissedSha:q,open:oa,actions:Cr!==``,availability:sa,remote:J}),W&&(K||J))){let{label:e,state:t}=Tt(K,J);W.textContent=e,W.dataset.state=t}}document.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`[data-copy-command]`);if(n)return Ca(n);let r=t.closest(`[data-notice-dismiss]`);if(r){r.closest(`[data-notice]`)?.remove(),fetch(T(`/prefs`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissNotice:r.dataset.noticeDismiss})}).catch(()=>{});return}let i=t.closest(`[data-pr-recheck]`);if(i)return void Ta(i);let a=t.closest(`[data-review-update]`);if(a)return void Oa(a);t.closest(`[data-update-close]`)&&document.querySelector(`[data-update-result]`)?.remove()});function Ca(e){let t=e.dataset.copyCommand??``;navigator.clipboard?.writeText(t).then(()=>wa(e,`Copied`),()=>wa(e,`Select it`))}function wa(e,t,n=1400){let r=e.textContent;e.textContent=t,setTimeout(()=>{e.textContent=r},n)}async function Ta(e){let t=[...document.querySelectorAll(`[data-pr-recheck]`)];for(let e of t)e.disabled=!0;let n=Date.now(),r=()=>{let e=Math.max(1,Math.round((Date.now()-n)/1e3));for(let n of t){let t=Ea(n);t?t.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Re-checking the conversation, ${e}s. ${ka}`:n.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Checking… ${e}s`}};r();let i=window.setInterval(r,1e3),a=Ea(e)?null:Aa(e);try{await fetch(T(`/refresh`),{method:`POST`})}catch{}finally{window.clearInterval(i),a?.remove()}Ea(e)&&Da(),window.location.reload()}function Ea(e){return e.closest(`.prb-fresh-notes p`)}function Da(){try{sessionStorage.setItem(aa,`1`)}catch{}}async function Oa(e){let t=[...document.querySelectorAll(`[data-review-update]`)];for(let e of t)e.disabled=!0,e.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Updating…`;let n=!1,r=()=>{n||(n=!0,window.clearInterval(i),window.location.reload())},i=window.setInterval(async()=>{try{let e=await(await fetch(T(`/job`))).json();e.update&&e.update.phase!==`none`&&!Lt(e.update.phase)&&r()}catch{}},500);try{await fetch(T(`/update`),{method:`POST`})}catch{}r()}var ka=`Fetching the latest threads from your pull request. This usually takes under a minute.`;function Aa(e){let t=e.parentElement;if(!t)return null;let n=document.createElement(`span`);return n.className=`prb-recheck-status`,n.setAttribute(`role`,`status`),n.textContent=ka,t.appendChild(n),n}var ja=Ut(document),Ma=null,Na=Date.now();function Pa(){Ma===null&&(Ma=window.setTimeout(()=>{Ma=null,Fa()},o(Date.now()-Na)))}async function Fa(){try{let e=await(await fetch(T(`/job`))).json();if(M&&!e.ask||La&&!e.diagram){window.location.reload();return}let t={job:e,kiss:e.kiss,update:e.update};for(let[e,n]of ja){let r=t[e];if(r){if(Wt(e,r,document)){window.location.reload();return}e===`update`||n.matches(`[data-progress-pane]`)?(Kt(n,r.phase,r.progress),qt(n)):Ia(n,r.progress)}}}catch{}Pa()}function Ia(e,t){if(!t)return;let n=e.querySelector(`.prb-job-progress`);n||(n=document.createElement(`span`),n.className=`prb-job-progress`,e.querySelector(`p`)?.appendChild(n)),n.textContent=` ${t}`}var La=document.querySelector(`[data-diagram-running]`)!==null;(ja.size>0||M||La)&&(Na=Date.now(),Pa());function Ra(e){let t=e.parentElement;if(!t)return;let n=t.querySelector(`.prb-job-retry-status`);n||(n=document.createElement(`p`),n.className=`prb-job-retry-status`,n.setAttribute(`role`,`status`),t.insertBefore(n,e.nextSibling)),n.textContent=`The retry could not be started. You can try again.`}function za(e){e.parentElement?.querySelector(`.prb-job-retry-status`)?.remove()}document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-job-retry]`);t&&(t.disabled=!0,t.textContent=`Retrying…`,za(t),fetch(T(`/retry`),{method:`POST`}).then(e=>{if(!e.ok)throw Error(`refused`);Na=Date.now(),Pa()}).catch(()=>{t.disabled=!1,t.textContent=`Retry`,Ra(t)}))}),document.addEventListener(`change`,e=>{let t=e.target.closest(`[data-kiss-audience]`);if(!t)return;let n=t.closest(`[data-kiss-run-control]`)?.querySelector(`[data-kiss-run]`);n&&(n.disabled=!1)}),document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-kiss-run]`);if(!t||t.disabled)return;let n=t.closest(`[data-kiss-run-control]`),r=n?.querySelector(`[data-kiss-audience]:checked`)?.value;r&&(t.disabled=!0,t.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Starting…`,fetch(T(`/kiss`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({audience:r})}).then(e=>{if(e.ok)window.location.reload();else throw Error(`refused`)}).catch(()=>{t.disabled=!1,t.textContent=`Run KISS review`;let e=document.createElement(`p`);e.className=`prb-kiss-refused`,e.setAttribute(`role`,`status`),e.textContent=`The KISS review could not be started. You can try again.`,n?.querySelector(`.prb-kiss-refused`)?.remove(),n?.appendChild(e)}))});var Ba=document.body.dataset.defaultView||`overview`;window.addEventListener(`popstate`,e=>{Nr(e.state??yt(window.location.hash)??{kind:`view`,view:Ba})});var Va=yt(window.location.hash);Va?Nr(Va):history.replaceState({kind:`view`,view:Ba},``,window.location.pathname+window.location.search),wi(),Vr();var Ha=e=>{for(let t of document.querySelectorAll(`[data-analysis-details][open]`))(!e||!t.contains(e))&&(t.open=!1)};document.addEventListener(`click`,e=>{Ha(e.target)}),document.addEventListener(`keydown`,e=>{if(e.key!==`Escape`)return;let t=document.querySelector(`[data-analysis-details][open]`);t&&(Ha(),t.querySelector(`summary`)?.focus())});var $=document.querySelector(`.prb-header [data-menu]`);if($){let e=$.querySelector(`[data-menu-trigger]`),t=$.querySelector(`[data-menu-panel]`),n=$.querySelector(`[data-menu-items]`),r=$.querySelector(`[data-menu-confirm]`),o=$.querySelector(`[data-confirm-delete]`),s=()=>{n&&(n.hidden=!1),r&&(r.hidden=!0),$.querySelector(`[data-menu-error]`)?.remove()},c=()=>{t&&(t.hidden=!0),e?.setAttribute(`aria-expanded`,`false`),s()};e?.addEventListener(`click`,n=>{if(n.stopPropagation(),!t)return;let r=t.hidden;s(),t.hidden=!r,e.setAttribute(`aria-expanded`,String(r))}),$.addEventListener(`click`,e=>{let t=e.target,i=t?.closest(`[data-copy-id]`);if(i?.dataset.copyId){e.stopPropagation(),a(i,i.dataset.copyId);return}let o=t?.closest(`[data-save-toggle]`);if(o){e.stopPropagation(),l(o);return}if(t?.closest(`[data-delete]`)){e.stopPropagation(),n&&(n.hidden=!0),r&&(r.hidden=!1);return}if(t?.closest(`[data-cancel-delete]`)){e.stopPropagation(),s();return}t?.closest(`[data-confirm-delete]`)&&(e.stopPropagation(),u())});let l=async e=>{let t=e.getAttribute(`aria-pressed`)!==`true`;e.disabled=!0;let n=null;try{let e=await fetch(T(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({pinned:t})});e.ok&&(n=(await e.json()).pinned===!0)}catch{}if(e.disabled=!1,n===null){e.textContent=`Could not save`,window.setTimeout(()=>{e.textContent=i(e.getAttribute(`aria-pressed`)===`true`)},1600);return}e.setAttribute(`aria-pressed`,String(n)),e.textContent=i(n)},u=async()=>{o&&(o.disabled=!0,o.textContent=`Deleting`);let e;try{let t=await fetch(T(`/delete`),{method:`POST`});if(t.ok)return void window.location.replace(`/`);e=(await t.json().catch(()=>null))?.error??`That could not be deleted.`}catch{e=`The workspace server did not answer. It may have stopped.`}o&&(o.disabled=!1,o.textContent=`Delete`),s();let n=document.createElement(`p`);n.className=`prb-menu-error`,n.setAttribute(`data-menu-error`,``),n.textContent=e,t?.append(n)};document.addEventListener(`click`,e=>{$.contains(e.target)||c()}),document.addEventListener(`keydown`,n=>{n.key===`Escape`&&t&&!t.hidden&&(c(),e?.focus())})}t(),setTimeout(()=>{hr(sr([...document.querySelectorAll(`[data-view="files"] [data-file]`)].map(e=>e.dataset.file??``)))},0),e(window,()=>window.location.reload()),r(window,document.querySelector(`main.prb-doc`));var Ua=15e3,Wa=6e4;function Ga(){return Cr!==``&&document.visibilityState===`visible`&&!ja.has(`update`)}document.addEventListener(`visibilitychange`,()=>{Ga()&&Date.now()-ga>=Ua&&ha()}),window.setInterval(()=>{Ga()&&ha()},Wa);export{S as t};
107
+ ${l}`,ar(e,t),br(e),xr(e),(n.focus?dr(e,n.focus):e.querySelector(`.prb-code-target`))?.scrollIntoView({block:`center`}),Br(e,t)}async function gi(e,t,n){let r=ur(t,n);if(!r)return;let i=dr(e,r.anchor);if(i)t.outerHTML=lr(fr(t),r.key),i.scrollIntoView({block:`center`});else{let t=e.querySelector(`[data-expand-file]`);if(!t?.dataset.expandFile)return;await mi(e,t.dataset.expandFile,{cited:Number(t.dataset.expandCited)||0,centre:r.anchor.line,expand:Math.max(1,(Number(t.dataset.expandStep)||1)-1),position:r.key,focus:r.anchor})}let a=e.querySelector(`[data-change-step="${n}"]`),o=e.querySelector(`[data-change-step="${n===`next`?`previous`:`next`}"]`);(a&&!a.disabled?a:o)?.focus({preventScroll:!0})}function _i(e,t,n){let r=`${Kr.replace(/\/$/,``)}/${e}`,i=Gr.replace(`{path}`,r).replace(`{line}`,String(Math.max(1,t)));O({event:`editor_opened`,fromFinding:n}),window.location.href=i}var M=document.querySelector(`[data-ask-log]`);M&&M.querySelector(`.prb-msg`)&&M.scrollTo({top:M.scrollHeight});var N=document.querySelector(`[data-ask-form]`),P=N?.querySelector(`textarea`);function vi(e,t){let n=document.createElement(`div`);return n.className=e===`user`?`prb-msg prb-msg-user`:`prb-msg prb-msg-${e===`error`?`error`:`assistant`}`,e===`assistant`?(n.classList.add(`prb-md`),n.innerHTML=re(t)+fe(t)):n.textContent=t,M?.appendChild(n),M?.scrollTo({top:M.scrollHeight}),n}function yi(){let e=document.createElement(`div`);return e.className=`prb-thinking`,e.innerHTML=`<i></i><i></i><i></i><span>Reading the change…</span>`,M?.appendChild(e),M?.scrollTo({top:M.scrollHeight}),e}var F=null,I=!!M?.querySelector(`[data-ask-pending]`);function bi(){let e=document.createElement(`div`);e.className=`prb-stopped`,e.textContent=`Stopped.`,M?.appendChild(e),M?.scrollTo({top:M.scrollHeight})}async function xi(e,t=`free_text`){let n=e.trim();if(!n||F||I)return;document.querySelector(`.prb-ask-empty`)?.remove(),vi(`user`,n);let r=yi();F=new AbortController,Si(!0);try{let e=await fetch(D(`/ask`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({question:n,sectionId:Xr,source:t}),signal:F.signal}),i=await e.json().catch(()=>null);if(e.status===409&&(i?.running||i?.updating)){window.location.reload();return}if(r.remove(),i?.stopped){bi();return}if(!e.ok||!i?.answer){vi(`error`,i?.error??`Buddy AI did not answer. Check the terminal running PR Review Buddy.`);return}vi(`assistant`,i.answer)}catch(e){r.remove(),e instanceof DOMException&&e.name===`AbortError`?(bi(),P&&!P.value&&(P.value=n)):vi(`error`,`Could not reach PR Review Buddy. The workspace server may have stopped.`)}finally{F=null,Si(!1)}}function Si(e){let t=N?.querySelector(`button`);t&&(t.textContent=e?`Stop`:`Ask`,t.toggleAttribute(`data-stop`,e),t.disabled=!1),P&&(P.disabled=e);for(let t of document.querySelectorAll(Ci))t.disabled=e;e&&ti.closeAll(),e||P?.focus()}var Ci=`[data-suggestion], .pr-helper-explain-simply-button`;function wi(){let e=N?.querySelector(`button`);e&&(e.textContent=`Stopping…`,e.disabled=!0),fetch(D(`/stop`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({kind:`ask`})}).catch(()=>{}).finally(()=>{F?.abort()})}N?.addEventListener(`submit`,e=>{if(e.preventDefault(),F||I)return wi();let t=P?.value??``;P&&(P.value=``),xi(t,Ei(t))}),I&&Si(!0);var Ti=null;function Ei(e){return Ti&&e.includes(Ti.text)?Ti.source:`free_text`}P?.addEventListener(`keydown`,e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),N?.requestSubmit())}),P?.addEventListener(`input`,()=>{P&&(P.style.height=`auto`,P.style.height=`${Math.min(P.scrollHeight,140)}px`)});async function Di(e){try{await fetch(D(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({answeredQuestionIds:e})})}catch{}}function Oi(){return[...document.querySelectorAll(`[data-question-answered][data-answered="true"]`)].map(e=>e.dataset.questionAnswered??``).filter(Boolean)}function ki(e,t){e.dataset.answered=String(t),e.textContent=t?`Mark as unanswered`:`Mark answered`;let n=e.closest(`[data-finding-card]`);n?.classList.toggle(`pr-helper-question-card-answered`,t),n&&Fi(n,t,`questions`),Vi()}function Ai(){return[...document.querySelectorAll(`[data-issue-dismissed][data-dismissed="true"]`)].map(e=>({id:e.dataset.issueDismissed??``,sessionId:e.dataset.dismissedIn||Jr})).filter(e=>e.id)}async function ji(e){try{await fetch(D(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissedIssues:e})})}catch{}}function Mi(e,t){e.dataset.dismissed=String(t),e.textContent=t?`Reopen`:`Dismiss`,delete e.dataset.stale,t?e.dataset.dismissedIn=Jr:delete e.dataset.dismissedIn;let n=e.closest(`[data-finding-card]`);n&&(n.classList.toggle(`pr-helper-issue-card-dismissed`,t),n.querySelector(`.pr-helper-dismissal-stale`)?.remove(),n.querySelector(`.pr-helper-finding-status-dismissed`)?.remove(),t&&n.querySelector(`.pr-helper-issue-badges`)?.prepend(Ni()),Fi(n,t||e.dataset.settled===`true`,`issues`),Ui())}function Ni(){let e=document.createElement(`span`);return e.className=`pr-helper-finding-status pr-helper-finding-status-dismissed pr-helper-tip`,e.dataset.tip=jt,e.textContent=`Dismissed by you`,e}var Pi=new WeakMap;function Fi(e,t,n){let r=e.closest(`.pr-helper-closed-findings-list`);if(t!==!!r){if(t){let t=e.parentElement;t&&Pi.set(e,{parent:t,before:e.nextElementSibling}),zi(n).append(e),t&&Ri(t)}else Ii(e,n),(r?.children.length===0?r.closest(`.pr-helper-closed-findings`):null)?.remove();Bi(n)}}function Ii(e,t){let n=Pi.get(e);if(n?.parent.isConnected)n.parent.insertBefore(e,n.before);else{let n=Li(e)??document.querySelector(`[data-view="${t}"]`);n?.insertBefore(e,n.querySelector(`.pr-helper-closed-findings`))}e.closest(`.pr-helper-question-group`)?.removeAttribute(`hidden`)}function Li(e){let t=e.dataset.sectionId;return t?document.querySelector(`[data-question-group="${CSS.escape(t)}"]`):null}function Ri(e){let t=e.closest(`.pr-helper-question-group`);t&&!t.querySelector(`[data-finding-card]`)&&(t.hidden=!0)}function zi(e){let t=document.querySelector(`[data-view="${e}"]`),n=t?.querySelector(`[data-closed-findings="${e}"] .pr-helper-closed-findings-list`);if(n)return n;let r=document.createElement(`details`);r.className=`pr-helper-closed-findings`,r.dataset.closedFindings=e;let i=document.createElement(`summary`);i.className=`pr-helper-closed-findings-summary`,i.setAttribute(`data-closed-findings-summary`,``);let a=document.createElement(`div`);return a.className=`pr-helper-closed-findings-list`,r.append(i,a),t?.append(r),a}function Bi(e){let t=document.querySelector(`[data-closed-findings="${e}"]`),n=t?.querySelector(`[data-closed-findings-summary]`);if(!t||!n)return;let r=document.querySelectorAll(`[data-view="${e}"] [data-finding-card]`).length,i=t.querySelectorAll(`[data-finding-card]`).length;if(t.toggleAttribute(`data-nothing-open`,r===i),e===`questions`){n.textContent=`Answered (${i})`;return}n.textContent=Nt(Hi())}function Vi(){let e=[...document.querySelectorAll(`[data-question-answered]`)];if(e.length===0)return;let t=e.filter(e=>e.dataset.answered!==`true`&&e.dataset.settled!==`true`).length,n=document.querySelector(`.pr-helper-questions-progress`);n&&(n.innerHTML=Pt(e.length,t)),Wi(`questions`,e.length,t,`question`,`answered`)}function Hi(){let e=[...document.querySelectorAll(`[data-issue-dismissed]`)],t=0,n=0;for(let r of e){let e=r.dataset.settled===`true`,i=r.dataset.dismissed===`true`&&r.dataset.stale!==`true`;!e&&!i?t+=1:!e&&i&&(n+=1)}return{total:e.length,open:t,done:e.length-t,reviewerClosed:n}}function Ui(){let e=Hi();if(e.total===0)return;let t=document.querySelector(`[data-view="issues"]`),n=t?.querySelector(`.pr-helper-findings-progress`);!n&&t&&e.done>0&&(n=document.createElement(`div`),n.className=`pr-helper-findings-progress`,n.setAttribute(`role`,`status`),t.querySelector(`.prb-doc-title`)?.after(n)),n&&(n.innerHTML=Mt(e.total,e.open,At(e))),Wi(`issues`,e.total,e.open,`issue`,At(e))}function Wi(e,t,n,r,i){let a=document.querySelector(`[data-view-nav="${e}"] .prb-rail-count`);if(!a)return;let o=e=>`${e} ${r}${e===1?``:`s`}`,s=t-n;a.classList.toggle(`prb-rail-count-done`,t>0&&n===0),t===0?(a.textContent=`0`,a.setAttribute(`aria-label`,`No ${r}s`)):n===0?(a.textContent=`✓`,a.setAttribute(`aria-label`,`All ${o(t)} ${i}`)):(a.textContent=String(n),a.setAttribute(`aria-label`,s===0?o(t):`${n} of ${o(t)} left, ${s} ${i}`))}document.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`[data-rail-toggle]`);if(n){ci(n,n.getAttribute(`aria-expanded`)!==`true`);return}let r=t.closest(`[data-view-nav]`);if(r?.dataset.viewNav){ii(r.dataset.viewNav);return}let i=t.closest(`[data-overview-nav]`);if(i?.dataset.overviewNav){ii(i.dataset.overviewNav===`guide`?`guide`:i.dataset.overviewNav);return}let a=t.closest(`[data-goto-section]`);if(a?.dataset.gotoSection){ai(a.dataset.gotoSection);return}let o=t.closest(`[data-open-editor]`);if(o?.dataset.openEditor){_i(o.dataset.openEditor,Number(o.dataset.openLine)||1,!0);return}let s=t.closest(`[data-deletion-toggle]`);if(s){ir(s);return}let c=t.closest(`[data-code-expand]`);if(c){let e=c.closest(`.prb-code`);e&&wr(e,!e.hasAttribute(`data-expanded`));return}let l=t.closest(`[data-change-step]`);if(l){let e=l.closest(`[data-change-navigator]`),t=l.closest(`.prb-code`);e&&t&&!l.disabled&&gi(t,e,l.dataset.changeStep===`previous`?`previous`:`next`);return}let u=t.closest(`[data-full-line]`);if(u){let e=or(u);e&&Vr(e);return}let d=t.closest(`[data-expand-file]`);if(d?.dataset.expandFile){let e=d.closest(`.prb-code`);if(e){let t=e.querySelector(`[data-change-navigator]`);mi(e,d.dataset.expandFile,{cited:Number(d.dataset.expandCited)||0,centre:Number(d.dataset.expandLine)||0,expand:Number(d.dataset.expandStep)||1,position:Number(t?.dataset.changePosition)||0,focus:pr(t)})}return}let ee=t.closest(`[data-focus-toggle]`);if(ee?.dataset.focusToggle){ri(ee.dataset.focusToggle);return}let f=t.closest(`[data-prompt-toggle]`);if(f){fa(f.getAttribute(`aria-expanded`)===`true`);return}if(t.closest(`[data-ask-buddy-menu]`))return;let te=t.closest(`[data-file]`);if(te?.dataset.file){pi(te);return}let ne=It(t);if(ne){ai(ne);return}let re=t.closest(`[data-question-answered]`);if(re?.dataset.questionAnswered){ki(re,re.dataset.answered!==`true`);let e=Oi();Di(e),O({event:`question_marked_answered`,answered:e.length,total:document.querySelectorAll(`[data-question-answered]`).length});return}let p=t.closest(`[data-issue-dismissed]`);if(p?.dataset.issueDismissed){Mi(p,p.dataset.stale===`true`||p.dataset.dismissed!==`true`);let e=Ai();ji(e),O({event:`issue_dismissed`,dismissed:e.length,total:document.querySelectorAll(`[data-issue-dismissed]`).length});return}let ie=t.closest(`[data-suggestion]`);if(ie){xi(ie.textContent??``,`suggestion`);return}if(t.closest(`.pr-helper-explain-simply-button`)){z(),xi(qr,`explain_simply`);return}let ae=t.closest(`[data-prompt-use]`);if(ae?.dataset.promptUse){pa(ae.dataset.promptUse);return}let m=t.closest(`[data-prompt-edit]`);if(m?.dataset.promptEdit){ja(m.dataset.promptEdit);return}if(t.closest(`[data-prompt-add]`)){ja(``);return}if(t.closest(`[data-ask-toggle]`)){let e=k?.focus;e?(bt(k,A),Ki(e!==`buddy`)):Ki(!Gi())}});var L=document.querySelector(`.prb-body`),R=document.querySelector(`.prb-ask`);function Gi(){return!!R&&getComputedStyle(R).display!==`none`}function Ki(e){L&&(L.dataset.ask=e?`open`:`closed`),document.querySelector(`[data-ask-toggle]`)?.setAttribute(`aria-expanded`,String(e))}function z(){k?.focus&&k.focus!==`buddy`&&bt(k,A),Ki(!0)}function qi(){document.querySelector(`[data-ask-toggle]`)?.setAttribute(`aria-expanded`,String(Gi()))}window.addEventListener(`resize`,qi),n(D(`/restart`));var B=document.querySelector(`[data-file-filter]`),Ji=document.querySelector(`[data-file-count]`),Yi=document.querySelector(`[data-file-none]`);function Xi(){let e=(B?.value??``).trim().toLowerCase(),t=0,n=0;for(let r of document.querySelectorAll(`[data-view="files"] .prb-file`)){let i=e===``||(r.dataset.search??``).includes(e);r.hidden=!i,i&&(n+=1,r.classList.contains(`prb-file-referenced`)||(t+=1));let a=r.nextElementSibling;a?.classList.contains(`prb-code`)&&(a.hidden=!i)}for(let t of document.querySelectorAll(`[data-file-group]`)){let n=t.querySelectorAll(`.prb-file:not([hidden])`).length;t.hidden=n===0;let r=t.querySelector(`[data-group-heading]`);if(!r)continue;let i=Number(r.dataset.groupTotal)||0;r.textContent=e&&n!==i?`${r.dataset.groupHeading} · ${n} of ${i}`:`${r.dataset.groupHeading} · ${i}`}Yi&&(Yi.hidden=n>0),Ji&&(Ji.textContent=e?`${t} of ${Zi} file${Zi===1?``:`s`}`:`${Zi} file${Zi===1?``:`s`}`)}var Zi=document.querySelectorAll(`[data-view="files"] .prb-file:not(.prb-file-referenced)`).length;B?.addEventListener(`input`,Xi),B?.addEventListener(`keydown`,e=>{e.key===`Escape`&&B.value!==``&&(e.preventDefault(),B.value=``,Xi())}),document.addEventListener(`keydown`,e=>{if(e.key!==`Enter`&&e.key!==` `)return;let t=e.target,n=t.closest(`.prb-file[data-file][role="button"]`);!n||n!==t||(e.preventDefault(),pi(n))});var Qi=320,$i=()=>Math.round(window.innerWidth/2),ea=e=>Math.round(Math.min($i(),Math.max(Qi,e)));function V(e){L&&(e===null?L.style.removeProperty(`--ask-width`):L.style.setProperty(`--ask-width`,`${e}px`))}function ta(){return R?Math.round(R.getBoundingClientRect().width):Qi}function na(e){fetch(D(`/prefs`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({askWidth:e})}).catch(()=>{})}var H=document.querySelector(`[data-ask-resize]`);H?.addEventListener(`pointerdown`,e=>{if(e.button!==0||!L||!R)return;e.preventDefault(),H.setPointerCapture(e.pointerId),L.dataset.resizing=`true`;let t=e.clientX,n=ta(),r=e=>{V(ea(n+(t-e.clientX)))},i=()=>{H.removeEventListener(`pointermove`,r),H.removeEventListener(`pointerup`,i),H.removeEventListener(`pointercancel`,i),delete L.dataset.resizing,na(ta())};H.addEventListener(`pointermove`,r),H.addEventListener(`pointerup`,i),H.addEventListener(`pointercancel`,i)}),H?.addEventListener(`keydown`,e=>{let t=e.shiftKey?64:16;if(e.key===`ArrowLeft`||e.key===`ArrowRight`){e.preventDefault();let n=e.key===`ArrowLeft`?t:-t,r=ea(ta()+n);V(r),na(r);return}(e.key===`Home`||e.key===`Escape`)&&(e.preventDefault(),V(null),na(null))}),H?.addEventListener(`dblclick`,()=>{V(null),na(null)}),window.addEventListener(`resize`,()=>{Gi()&&L?.style.getPropertyValue(`--ask-width`)&&V(ea(ta()))});var ra=3e4,U=document.visibilityState===`visible`?Date.now():null,ia=0;function aa(){U!==null&&(ia+=Date.now()-U,U=Date.now())}function oa(){aa();let e=Math.round(ia/1e3);return ia-=e*1e3,e}document.addEventListener(`visibilitychange`,()=>{document.visibilityState===`visible`?U=Date.now():(aa(),U=null)}),setInterval(()=>{let e=oa();e>0&&O({event:`workspace_heartbeat`,visibleSeconds:e})},ra),window.addEventListener(`pagehide`,()=>{let e=D(`/event`),t=JSON.stringify({event:`review_completed`,trailingSeconds:oa()});navigator.sendBeacon?.(e,new Blob([t],{type:`application/json`}))||fetch(e,{method:`POST`,headers:{"content-type":`application/json`},body:t,keepalive:!0}).catch(()=>{})});var sa=document.querySelector(`[data-prompt-bank]`),ca=document.querySelector(`[data-prompt-list]`),W=la();function la(){try{let e=JSON.parse(sa?.dataset.prompts??`[]`);return Array.isArray(e)?e:[]}catch{return[]}}function ua(){if(!ca)return;ca.innerHTML=W.map(e=>`<span class="prb-bank-item">
108
+ <button type="button" class="prb-bank-use" data-prompt-use="${j(e.id)}" title="${j(e.prompt)}">${j(e.name)}</button>
109
+ <button type="button" class="prb-bank-edit" data-prompt-edit="${j(e.id)}" aria-label="Edit ${j(e.name)}">&#9998;</button>
110
+ </span>`).join(``);let e=document.querySelector(`[data-prompt-count]`);e&&(e.textContent=String(W.length)),ya()}async function da(e){try{let t=await(await fetch(D(`/prompts`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({prompts:e})})).json().catch(()=>null);W=Array.isArray(t?.prompts)?t.prompts:W}catch{}ua()}function fa(e){document.querySelector(`[data-prompt-toggle]`)?.setAttribute(`aria-expanded`,String(!e)),sa?.toggleAttribute(`data-collapsed`,e),ca&&(ca.hidden=e),fetch(D(`/prefs`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({promptsCollapsed:e})}).catch(()=>{})}function pa(e){let t=W.find(t=>t.id===e);!t||!P||(P.value=zt(P.value,t.prompt),z(),P.focus(),P.setSelectionRange(P.value.length,P.value.length),P.dispatchEvent(new Event(`input`)))}var ma=document.querySelector(`.prb-doc`),ha=null,ga=null;function _a(){M&&(ga?.(),ga=Je(M,{layout:`flat`,actions:Ze.map(e=>({id:e.id,label:e.label})),onChoose:(e,t)=>ba(e,`selection`,t)}))}function va(){return[...Ye.map(e=>({id:e.id,label:e.label})),...W.map(e=>({id:rt(e.id),label:e.name,section:nt}))]}function ya(){ma&&(ha?.(),ha=Je(ma,{triggerLabel:`Ask Buddy AI`,actions:va(),ignoreWithin:`[data-ask-buddy-menu]`,onChoose:(e,t)=>ba(e,`selection`,t)}))}function ba(e,t,n){wt(e,{context:t,text:n},{savedPrompt:e=>W.find(t=>t.id===e)?.prompt??null,stage:e=>xa(e,t),send:e=>{z(),xi(e,`finding`)}})}function xa(e,t){P&&(Ti={text:e,source:t},P.value=zt(P.value,e),z(),P.focus(),P.setSelectionRange(P.value.length,P.value.length),P.dispatchEvent(new Event(`input`)))}function Sa(e){return e.closest(`[data-finding-card]`)?.querySelector(`[data-copy-source]`)?.getAttribute(`data-copy-source`)??``}function Ca(e){let t=e.querySelector(`[data-menu-panel]`);if(t){t.innerHTML=Be(va());for(let e of t.querySelectorAll(`[data-selection-action]`))e.setAttribute(`role`,`menuitem`);if(F||I)for(let e of t.querySelectorAll(`button`))e.disabled=!0}}function wa(e){let t=e.querySelector(`[data-menu-items]`),n=e.querySelector(`[data-menu-confirm]`);t&&(t.hidden=!1),n&&(n.hidden=!0),e.querySelector(`[data-menu-error]`)?.remove()}document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-ask-buddy-menu] [data-selection-action]`),n=t?.closest(`[data-ask-buddy-menu]`),r=t?.dataset.selectionAction;if(!n||!r)return;let i=Sa(n);ti.close(n),i&&ba(r,`finding`,i)}),ya(),_a(),Ce(document);var Ta=document.querySelector(`[data-prompt-dialog]`),Ea=document.querySelector(`[data-prompt-name]`),Da=document.querySelector(`[data-prompt-text]`),Oa=document.querySelector(`[data-prompt-delete]`),ka=document.getElementById(`prb-prompt-title`),Aa=``;function ja(e){let t=W.find(t=>t.id===e);Aa=t?.id??``,ka&&(ka.textContent=t?`Edit prompt`:`Save a prompt`),Ea&&(Ea.value=t?.name??``),Da&&(Da.value=t?.prompt??``),Oa&&(Oa.hidden=!t),Ta?.showModal(),Ea?.focus()}async function Ma(){let e=Ea?.value.trim()??``,t=Da?.value.trim()??``;if(!e||!t){(e?Da:Ea)?.focus();return}let n=Aa?W.map(n=>n.id===Aa?{...n,name:e,prompt:t}:n):[...W,{id:crypto.randomUUID(),name:e,prompt:t}];Ta?.close(),await da(n)}async function Na(){if(!Aa)return;let e=W.filter(e=>e.id!==Aa);Ta?.close(),await da(e)}document.querySelector(`[data-prompt-cancel]`)?.addEventListener(`click`,()=>Ta?.close()),Oa?.addEventListener(`click`,()=>void Na()),document.querySelector(`[data-prompt-save]`)?.addEventListener(`click`,()=>void Ma());var Pa=document.querySelector(`[data-complete]`);Pa?.addEventListener(`click`,()=>{let e=Pa.getAttribute(`aria-pressed`)!==`true`;Fa(e),fetch(D(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({complete:e})}).then(async e=>{let t=await e.json().catch(()=>null);t&&Fa(t.completedAt!==null)}).catch(()=>Fa(!e))});function Fa(e){Pa&&(Pa.setAttribute(`aria-pressed`,String(e)),Pa.textContent=e?`Reviewed`:`Mark reviewed`)}var G=document.querySelector(`[data-fresh-region]`),K=document.querySelector(`[data-fresh-status]`),q=document.querySelector(`[data-fresh-check]`),J=Wa(G?.dataset.report),Ia=`prb-fresh-reopen`,La=Ha(),Ra=G?.dataset.dismissedSha,za=Va(G?.dataset.availability),Y=Ba(G?.dataset.remote);function Ba(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}function Va(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}function Ha(){try{return sessionStorage.getItem(Ia)!==null&&(sessionStorage.removeItem(Ia),!0)}catch{return!1}}La&&Q(),q?.addEventListener(`click`,()=>void Ga()),G?.addEventListener(`click`,e=>{let t=e.target;if(t.closest(`[data-fresh-close]`))return La=!1,Q();let n=t.closest(`[data-fresh-dismiss]`);n&&(Ra=n.dataset.freshDismiss||void 0,La=!1,Q(),Ua())});function Ua(){fetch(D(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissFreshnessSha:Ra??null})}).catch(()=>{})}function Wa(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}var X=!1;async function Ga(){if(X)return;X=!0,Xa(!0);let e=Za(J,Y),t=await Ka(!1);t&&to(),X=!1,t&&(J?.code.state===`changed`||Y!==null)&&Ra!==void 0&&(Ra=void 0,Ua()),Q();let n=t?Za(J,Y)===e?`No change`:`Updated`:`Could not check`;q&&ro(q,n,2600)}async function Ka(e){try{let t=await(await fetch(`${D(`/freshness`)}${e?`&quiet=1`:``}`)).json();return J=t.report??null,za=t.availability??null,Y=t.remote??null,Qa=t.kiss??null,t.kissDismissedSha!==void 0&&($a=t.kissDismissedSha??void 0),t.prState!==void 0&&Ya(t.prState),!0}catch{return!1}}async function qa(){if(X||!G)return;X=!0;let e=Za(J,Y),t=JSON.stringify(Qa),n=await Ka(!0);X=!1,Ja=Date.now(),n&&(Za(J,Y)!==e&&Q(),JSON.stringify(Qa)!==t&&to())}var Ja=Date.now();function Ya(e){let t=document.querySelector(`[data-pr-state-slot]`);if(!t)return;let n=sn(e,t.hasAttribute(`data-beside-number`));t.innerHTML!==n&&(t.innerHTML=n)}function Xa(e){q&&(q.disabled=e),K&&e&&(K.textContent=`Checking…`,K.dataset.state=`checking`)}function Za(e,t){if(!e)return JSON.stringify({report:`none`,remote:t});let{checkedAt:n,...r}=e;return JSON.stringify({...r,remote:t})}var Z=document.querySelector(`[data-kiss-fresh-region]`),Qa=eo(Z?.dataset.freshness),$a=Z?.dataset.dismissedSha;function eo(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}function to(){Z&&(Z.innerHTML=on(Z.dataset.reviewedSha??``,Qa,{dismissedSha:$a,actions:Ur!==``}))}Z?.addEventListener(`click`,e=>{let t=e.target.closest(`[data-kiss-freshness-dismiss]`);t&&($a=t.dataset.kissFreshnessDismiss||void 0,to(),fetch(D(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissKissFreshnessSha:$a??null})}).catch(()=>{}))});function Q(){if(G&&(G.innerHTML=Kt(J,{dismissedSha:Ra,open:La,actions:Ur!==``,availability:za,remote:Y}),K&&(J||Y))){let{label:e,state:t}=Gt(J,Y);K.textContent=e,K.dataset.state=t}}document.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`[data-copy-command]`);if(n)return no(n);let r=t.closest(`[data-notice-dismiss]`);if(r){r.closest(`[data-notice]`)?.remove(),fetch(D(`/prefs`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissNotice:r.dataset.noticeDismiss})}).catch(()=>{});return}let i=t.closest(`[data-pr-recheck]`);if(i)return void io(i);let a=t.closest(`[data-review-update]`);if(a)return void so(a);t.closest(`[data-update-close]`)&&document.querySelector(`[data-update-result]`)?.remove()});function no(e){let t=e.dataset.copyCommand??``;navigator.clipboard?.writeText(t).then(()=>ro(e,`Copied`),()=>ro(e,`Select it`))}function ro(e,t,n=1400){let r=e.textContent;e.textContent=t,setTimeout(()=>{e.textContent=r},n)}async function io(e){let t=[...document.querySelectorAll(`[data-pr-recheck]`)];for(let e of t)e.disabled=!0;let n=Date.now(),r=()=>{let e=Math.max(1,Math.round((Date.now()-n)/1e3));for(let n of t){let t=ao(n);t?t.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Re-checking the conversation, ${e}s. ${co}`:n.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Checking… ${e}s`}};r();let i=window.setInterval(r,1e3),a=ao(e)?null:lo(e);try{await fetch(D(`/refresh`),{method:`POST`})}catch{}finally{window.clearInterval(i),a?.remove()}ao(e)&&oo(),window.location.reload()}function ao(e){return e.closest(`.prb-fresh-notes p`)}function oo(){try{sessionStorage.setItem(Ia,`1`)}catch{}}async function so(e){let t=[...document.querySelectorAll(`[data-review-update]`)];for(let e of t)e.disabled=!0,e.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Updating…`;let n=!1,r=()=>{n||(n=!0,window.clearInterval(i),window.location.reload())},i=window.setInterval(async()=>{try{let e=await(await fetch(D(`/job`))).json();e.update&&e.update.phase!==`none`&&!rn(e.update.phase)&&r()}catch{}},500);try{await fetch(D(`/update`),{method:`POST`})}catch{}r()}var co=`Fetching the latest threads from your pull request. This usually takes under a minute.`;function lo(e){let t=e.parentElement;if(!t)return null;let n=document.createElement(`span`);return n.className=`prb-recheck-status`,n.setAttribute(`role`,`status`),n.textContent=co,t.appendChild(n),n}var uo=un(document),fo=null,po=Date.now();function mo(){fo===null&&(fo=window.setTimeout(()=>{fo=null,ho()},o(Date.now()-po)))}async function ho(){try{let e=await(await fetch(D(`/job`))).json();if(I&&!e.ask||_o&&!e.diagram){window.location.reload();return}let t={job:e,kiss:e.kiss,update:e.update};for(let[e,n]of uo){let r=t[e];if(r){if(dn(e,r,document)){window.location.reload();return}e===`update`||n.matches(`[data-progress-pane]`)?(pn(n,r.phase,r.progress),mn(n)):go(n,r.progress)}}}catch{}mo()}function go(e,t){if(!t)return;let n=e.querySelector(`.prb-job-progress`);n||(n=document.createElement(`span`),n.className=`prb-job-progress`,e.querySelector(`p`)?.appendChild(n)),n.textContent=` ${t}`}var _o=document.querySelector(`[data-diagram-running]`)!==null;(uo.size>0||I||_o)&&(po=Date.now(),mo());function vo(e){let t=e.parentElement;if(!t)return;let n=t.querySelector(`.prb-job-retry-status`);n||(n=document.createElement(`p`),n.className=`prb-job-retry-status`,n.setAttribute(`role`,`status`),t.insertBefore(n,e.nextSibling)),n.textContent=`The retry could not be started. You can try again.`}function yo(e){e.parentElement?.querySelector(`.prb-job-retry-status`)?.remove()}document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-job-retry]`);t&&(t.disabled=!0,t.textContent=`Retrying…`,yo(t),fetch(D(`/retry`),{method:`POST`}).then(e=>{if(!e.ok)throw Error(`refused`);po=Date.now(),mo()}).catch(()=>{t.disabled=!1,t.textContent=`Retry`,vo(t)}))}),document.addEventListener(`change`,e=>{let t=e.target.closest(`[data-kiss-audience]`);if(!t)return;let n=t.closest(`[data-kiss-run-control]`)?.querySelector(`[data-kiss-run]`);n&&(n.disabled=!1)}),document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-kiss-run]`);if(!t||t.disabled)return;let n=t.closest(`[data-kiss-run-control]`),r=n?.querySelector(`[data-kiss-audience]:checked`)?.value;r&&(t.disabled=!0,t.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Starting…`,fetch(D(`/kiss`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({audience:r})}).then(e=>{if(e.ok)window.location.reload();else throw Error(`refused`)}).catch(()=>{t.disabled=!1,t.textContent=`Run KISS review`;let e=document.createElement(`p`);e.className=`prb-kiss-refused`,e.setAttribute(`role`,`status`),e.textContent=`The KISS review could not be started. You can try again.`,n?.querySelector(`.prb-kiss-refused`)?.remove(),n?.appendChild(e)}))});var bo=document.body.dataset.defaultView||`overview`;window.addEventListener(`popstate`,e=>{ei(e.state??mt(window.location.hash)??{kind:`view`,view:bo})});var xo=mt(window.location.hash);xo?ei(xo):(k={kind:`view`,view:bo},history.replaceState(k,``,window.location.pathname+window.location.search)),qi(),di();var So=e=>{for(let t of document.querySelectorAll(`[data-analysis-details][open]`))(!e||!t.contains(e))&&(t.open=!1)};document.addEventListener(`click`,e=>{So(e.target)}),document.addEventListener(`keydown`,e=>{if(e.key!==`Escape`)return;let t=document.querySelector(`[data-analysis-details][open]`);t&&(So(),t.querySelector(`summary`)?.focus())});var $=document.querySelector(`.prb-header [data-menu]`);if($){let e=$.querySelector(`[data-menu-panel]`),t=$.querySelector(`[data-menu-items]`),n=$.querySelector(`[data-menu-confirm]`),r=$.querySelector(`[data-confirm-delete]`),o=()=>wa($);$.addEventListener(`click`,e=>{let r=e.target,i=r?.closest(`[data-copy-id]`);if(i?.dataset.copyId){e.stopPropagation(),a(i,i.dataset.copyId);return}let l=r?.closest(`[data-save-toggle]`);if(l){e.stopPropagation(),s(l);return}if(r?.closest(`[data-delete]`)){e.stopPropagation(),t&&(t.hidden=!0),n&&(n.hidden=!1);return}if(r?.closest(`[data-cancel-delete]`)){e.stopPropagation(),o();return}r?.closest(`[data-confirm-delete]`)&&(e.stopPropagation(),c())});let s=async e=>{let t=e.getAttribute(`aria-pressed`)!==`true`;e.disabled=!0;let n=null;try{let e=await fetch(D(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({pinned:t})});e.ok&&(n=(await e.json()).pinned===!0)}catch{}if(e.disabled=!1,n===null){e.textContent=`Could not save`,window.setTimeout(()=>{e.textContent=i(e.getAttribute(`aria-pressed`)===`true`)},1600);return}e.setAttribute(`aria-pressed`,String(n)),e.textContent=i(n)},c=async()=>{r&&(r.disabled=!0,r.textContent=`Deleting`);let t;try{let e=await fetch(D(`/delete`),{method:`POST`});if(e.ok)return void window.location.replace(`/`);t=(await e.json().catch(()=>null))?.error??`That could not be deleted.`}catch{t=`The workspace server did not answer. It may have stopped.`}r&&(r.disabled=!1,r.textContent=`Delete`),o();let n=document.createElement(`p`);n.className=`prb-menu-error`,n.setAttribute(`data-menu-error`,``),n.textContent=t,e?.append(n)}}t(),setTimeout(()=>{Fr(Dr([...document.querySelectorAll(`[data-view="files"] [data-file]`)].map(e=>e.dataset.file??``)))},0),e(window,()=>window.location.reload()),r(window,document.querySelector(`main.prb-doc`));var Co=15e3,wo=6e4;function To(){return Ur!==``&&document.visibilityState===`visible`&&!uo.has(`update`)}document.addEventListener(`visibilitychange`,()=>{To()&&Date.now()-Ja>=Co&&qa()}),window.setInterval(()=>{To()&&qa()},wo);export{w as t};