@youtyan/code-viewer 0.1.16 → 0.1.18

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/web/app.js CHANGED
@@ -21,6 +21,21 @@
21
21
  throw Error('Dynamic require of "' + x + '" is not supported');
22
22
  });
23
23
 
24
+ // web-src/catch-up.ts
25
+ function shouldCatchUpDiff(route) {
26
+ return route.screen !== "repo" && !(route.screen === "file" && route.view === "blob");
27
+ }
28
+ function createCatchUpGate(now, minIntervalMs) {
29
+ let lastForceAt = 0;
30
+ return function shouldRun() {
31
+ const current = now();
32
+ if (current - lastForceAt < minIntervalMs)
33
+ return false;
34
+ lastForceAt = current;
35
+ return true;
36
+ };
37
+ }
38
+
24
39
  // web-src/expand-logic.ts
25
40
  function initExpandState(prevHunkEndNew, hunkNewStart) {
26
41
  return {
@@ -78,20 +93,6 @@
78
93
  applyTrailingResult
79
94
  };
80
95
 
81
- // web-src/file-navigation.ts
82
- function nextVisibleFileIndex(currentIndex, itemCount, direction) {
83
- if (itemCount <= 0)
84
- return -1;
85
- if (currentIndex < 0)
86
- return direction > 0 ? 0 : itemCount - 1;
87
- return Math.max(0, Math.min(itemCount - 1, currentIndex + direction));
88
- }
89
-
90
- // web-src/file-path-copy.ts
91
- function filePathClipboardText(path) {
92
- return path || "";
93
- }
94
-
95
96
  // web-src/file-filter.ts
96
97
  function normalizeFileFilterQuery(value) {
97
98
  return (value || "").toLowerCase().trim();
@@ -131,6 +132,20 @@
131
132
  };
132
133
  }
133
134
 
135
+ // web-src/file-navigation.ts
136
+ function nextVisibleFileIndex(currentIndex, itemCount, direction) {
137
+ if (itemCount <= 0)
138
+ return -1;
139
+ if (currentIndex < 0)
140
+ return direction > 0 ? 0 : itemCount - 1;
141
+ return Math.max(0, Math.min(itemCount - 1, currentIndex + direction));
142
+ }
143
+
144
+ // web-src/file-path-copy.ts
145
+ function filePathClipboardText(path) {
146
+ return path || "";
147
+ }
148
+
134
149
  // web-src/focus-scope.ts
135
150
  function isEditableKeyTarget(target) {
136
151
  if (!target)
@@ -433,147 +448,6 @@
433
448
  return null;
434
449
  }
435
450
 
436
- // web-src/search-palette.ts
437
- var PALETTE_RESULT_LIMIT = 50;
438
- function limitPaletteResults(items) {
439
- return items.slice(0, PALETTE_RESULT_LIMIT);
440
- }
441
- function movePaletteSelection(index, count, direction) {
442
- if (count <= 0)
443
- return -1;
444
- if (index < 0)
445
- return direction > 0 ? 0 : count - 1;
446
- return (index + direction + count) % count;
447
- }
448
-
449
- // web-src/catch-up.ts
450
- function shouldCatchUpDiff(route) {
451
- return route.screen !== "repo" && !(route.screen === "file" && route.view === "blob");
452
- }
453
- function createCatchUpGate(now, minIntervalMs) {
454
- let lastForceAt = 0;
455
- return function shouldRun() {
456
- const current = now();
457
- if (current - lastForceAt < minIntervalMs)
458
- return false;
459
- lastForceAt = current;
460
- return true;
461
- };
462
- }
463
-
464
- // web-src/routes.ts
465
- function assertNever(value) {
466
- throw new Error("unhandled route: " + JSON.stringify(value));
467
- }
468
- function parseLegacyRange(value, fallback) {
469
- const raw = value || "";
470
- const sep = raw.indexOf("..");
471
- if (sep < 0)
472
- return fallback;
473
- return {
474
- from: raw.slice(0, sep) || fallback.from,
475
- to: raw.slice(sep + 2) || fallback.to
476
- };
477
- }
478
- function parseLineTarget(value) {
479
- const raw = value || "";
480
- const range = /^(\d+)-(\d+)$/.exec(raw);
481
- if (range) {
482
- const a = Number(range[1]);
483
- const b = Number(range[2]);
484
- const start = Math.min(a, b);
485
- const end = Math.max(a, b);
486
- if (start > 0)
487
- return { start, end };
488
- return;
489
- }
490
- const line = Number(raw);
491
- return Number.isInteger(line) && line > 0 ? line : undefined;
492
- }
493
- function formatLineTarget(line) {
494
- return typeof line === "number" ? String(line) : line.start + "-" + line.end;
495
- }
496
- function parseRoute(pathname, search, fallbackRange) {
497
- const params = new URLSearchParams(search);
498
- const legacyRange = parseLegacyRange(params.get("range"), fallbackRange);
499
- const range = {
500
- from: params.get("from") || legacyRange.from,
501
- to: params.get("to") || legacyRange.to
502
- };
503
- switch (pathname) {
504
- case "/":
505
- case "/index.html":
506
- return {
507
- screen: "repo",
508
- ref: params.get("ref") || params.get("target") || "worktree",
509
- path: params.get("path") || "",
510
- range
511
- };
512
- case "/todif":
513
- case "/todiff":
514
- return {
515
- screen: "diff",
516
- range,
517
- ...params.get("path") ? { path: params.get("path") || "" } : {},
518
- ...parseLineTarget(params.get("line")) ? { line: parseLineTarget(params.get("line")) } : {}
519
- };
520
- case "/file": {
521
- const path = params.get("path") || "";
522
- const target = params.get("target") || "";
523
- const ref = target || params.get("ref") || "worktree";
524
- const line = parseLineTarget(params.get("line"));
525
- if (!path)
526
- return { screen: "unknown", reason: "missing-path", rawPathname: pathname, rawSearch: search, range };
527
- return { screen: "file", path, ref, range, view: target ? "blob" : "detail", ...line ? { line } : {} };
528
- }
529
- case "/help":
530
- return {
531
- screen: "help",
532
- range,
533
- lang: params.get("lang") || "en",
534
- section: params.get("section") || "keybindings"
535
- };
536
- default:
537
- return { screen: "unknown", reason: "unknown-pathname", rawPathname: pathname, rawSearch: search, range };
538
- }
539
- }
540
- function buildRoute(route) {
541
- switch (route.screen) {
542
- case "repo": {
543
- const params = new URLSearchParams;
544
- if (route.ref && route.ref !== "worktree")
545
- params.set("ref", route.ref);
546
- if (route.path)
547
- params.set("path", route.path);
548
- const qs = params.toString();
549
- return "/" + (qs ? "?" + qs : "");
550
- }
551
- case "file":
552
- if (route.view === "blob") {
553
- return "/file?path=" + encodeURIComponent(route.path) + "&target=" + encodeURIComponent(route.ref || "worktree") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
554
- }
555
- return "/file?path=" + encodeURIComponent(route.path) + "&ref=" + encodeURIComponent(route.ref || "worktree") + "&from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
556
- case "diff":
557
- return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.path ? "&path=" + encodeURIComponent(route.path) : "") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
558
- case "help": {
559
- const params = new URLSearchParams;
560
- if (route.lang && route.lang !== "en")
561
- params.set("lang", route.lang);
562
- if (route.section && route.section !== "keybindings")
563
- params.set("section", route.section);
564
- const qs = params.toString();
565
- return "/help" + (qs ? "?" + qs : "");
566
- }
567
- case "unknown":
568
- return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree");
569
- default:
570
- return assertNever(route);
571
- }
572
- }
573
- function buildRawFileUrl(target) {
574
- return "/_file?path=" + encodeURIComponent(target.path) + "&ref=" + encodeURIComponent(target.ref || "worktree");
575
- }
576
-
577
451
  // node_modules/markdown-it/lib/common/utils.mjs
578
452
  var exports_utils = {};
579
453
  __export(exports_utils, {
@@ -6155,6 +6029,119 @@
6155
6029
  md.core.ruler.after("inline", "footnote_tail", footnote_tail);
6156
6030
  }
6157
6031
 
6032
+ // web-src/routes.ts
6033
+ function assertNever(value) {
6034
+ throw new Error("unhandled route: " + JSON.stringify(value));
6035
+ }
6036
+ function parseLegacyRange(value, fallback) {
6037
+ const raw = value || "";
6038
+ const sep = raw.indexOf("..");
6039
+ if (sep < 0)
6040
+ return fallback;
6041
+ return {
6042
+ from: raw.slice(0, sep) || fallback.from,
6043
+ to: raw.slice(sep + 2) || fallback.to
6044
+ };
6045
+ }
6046
+ function parseLineTarget(value) {
6047
+ const raw = value || "";
6048
+ const range = /^(\d+)-(\d+)$/.exec(raw);
6049
+ if (range) {
6050
+ const a2 = Number(range[1]);
6051
+ const b2 = Number(range[2]);
6052
+ const start = Math.min(a2, b2);
6053
+ const end = Math.max(a2, b2);
6054
+ if (start > 0)
6055
+ return { start, end };
6056
+ return;
6057
+ }
6058
+ const line = Number(raw);
6059
+ return Number.isInteger(line) && line > 0 ? line : undefined;
6060
+ }
6061
+ function formatLineTarget(line) {
6062
+ return typeof line === "number" ? String(line) : line.start + "-" + line.end;
6063
+ }
6064
+ function parseRoute(pathname, search, fallbackRange) {
6065
+ const params = new URLSearchParams(search);
6066
+ const legacyRange = parseLegacyRange(params.get("range"), fallbackRange);
6067
+ const range = {
6068
+ from: params.get("from") || legacyRange.from,
6069
+ to: params.get("to") || legacyRange.to
6070
+ };
6071
+ switch (pathname) {
6072
+ case "/":
6073
+ case "/index.html":
6074
+ return {
6075
+ screen: "repo",
6076
+ ref: params.get("ref") || params.get("target") || "worktree",
6077
+ path: params.get("path") || "",
6078
+ range
6079
+ };
6080
+ case "/todif":
6081
+ case "/todiff":
6082
+ return {
6083
+ screen: "diff",
6084
+ range,
6085
+ ...params.get("path") ? { path: params.get("path") || "" } : {},
6086
+ ...parseLineTarget(params.get("line")) ? { line: parseLineTarget(params.get("line")) } : {}
6087
+ };
6088
+ case "/file": {
6089
+ const path = params.get("path") || "";
6090
+ const target = params.get("target") || "";
6091
+ const ref = target || params.get("ref") || "worktree";
6092
+ const line = parseLineTarget(params.get("line"));
6093
+ if (!path)
6094
+ return { screen: "unknown", reason: "missing-path", rawPathname: pathname, rawSearch: search, range };
6095
+ return { screen: "file", path, ref, range, view: target ? "blob" : "detail", ...line ? { line } : {} };
6096
+ }
6097
+ case "/help":
6098
+ return {
6099
+ screen: "help",
6100
+ range,
6101
+ lang: params.get("lang") || "en",
6102
+ section: params.get("section") || "keybindings"
6103
+ };
6104
+ default:
6105
+ return { screen: "unknown", reason: "unknown-pathname", rawPathname: pathname, rawSearch: search, range };
6106
+ }
6107
+ }
6108
+ function buildRoute(route) {
6109
+ switch (route.screen) {
6110
+ case "repo": {
6111
+ const params = new URLSearchParams;
6112
+ if (route.ref && route.ref !== "worktree")
6113
+ params.set("ref", route.ref);
6114
+ if (route.path)
6115
+ params.set("path", route.path);
6116
+ const qs = params.toString();
6117
+ return "/" + (qs ? "?" + qs : "");
6118
+ }
6119
+ case "file":
6120
+ if (route.view === "blob") {
6121
+ return "/file?path=" + encodeURIComponent(route.path) + "&target=" + encodeURIComponent(route.ref || "worktree") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
6122
+ }
6123
+ return "/file?path=" + encodeURIComponent(route.path) + "&ref=" + encodeURIComponent(route.ref || "worktree") + "&from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
6124
+ case "diff":
6125
+ return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.path ? "&path=" + encodeURIComponent(route.path) : "") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
6126
+ case "help": {
6127
+ const params = new URLSearchParams;
6128
+ if (route.lang && route.lang !== "en")
6129
+ params.set("lang", route.lang);
6130
+ if (route.section && route.section !== "keybindings")
6131
+ params.set("section", route.section);
6132
+ const qs = params.toString();
6133
+ return "/help" + (qs ? "?" + qs : "");
6134
+ }
6135
+ case "unknown":
6136
+ return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree");
6137
+ default:
6138
+ return assertNever(route);
6139
+ }
6140
+ }
6141
+ function buildRawFileUrl(target) {
6142
+ return "/_file?path=" + encodeURIComponent(target.path) + "&ref=" + encodeURIComponent(target.ref || "worktree");
6143
+ }
6144
+
6158
6145
  // web-src/markdown-preview.ts
6159
6146
  var mermaidPromise = null;
6160
6147
  var mermaidInitialized = false;
@@ -6728,6 +6715,19 @@
6728
6715
  return { width: rect.width || 800, height: rect.height || 600 };
6729
6716
  }
6730
6717
 
6718
+ // web-src/search-palette.ts
6719
+ var PALETTE_RESULT_LIMIT = 50;
6720
+ function limitPaletteResults(items) {
6721
+ return items.slice(0, PALETTE_RESULT_LIMIT);
6722
+ }
6723
+ function movePaletteSelection(index, count, direction) {
6724
+ if (count <= 0)
6725
+ return -1;
6726
+ if (index < 0)
6727
+ return direction > 0 ? 0 : count - 1;
6728
+ return (index + direction + count) % count;
6729
+ }
6730
+
6731
6731
  // web-src/ws-highlight.ts
6732
6732
  function isWhitespaceOnlyInlineHighlight(text2) {
6733
6733
  return !!text2 && !/\S/.test(text2);
@@ -6844,10 +6844,41 @@
6844
6844
  title: "Keyboard Shortcuts",
6845
6845
  intro: "Use these shortcuts to move between panels and navigate files without leaving the keyboard.",
6846
6846
  groups: [
6847
- { title: "Global", rows: [["Ctrl+K", "Open file palette"], ["Ctrl+G", "Open grep palette"], ["/", "Focus file filter"], ["t", "Toggle theme"]] },
6848
- { title: "Panels", rows: [["Ctrl+H", "Focus sidebar"], ["Ctrl+L", "Focus main panel"]] },
6849
- { title: "Sidebar", rows: [["j / k", "Move selection down / up"], ["Ctrl+D / Ctrl+U", "Move selection by half a page"], ["gg / Shift+G", "Move to top / bottom"], ["Enter", "Open selected item"], ["h / l", "Collapse / expand directory"]] },
6850
- { title: "Main Panel", rows: [["j / k", "Move code cursor down / up"], ["Ctrl+D / Ctrl+U", "Move code cursor by half a page"], ["gg / Shift+G", "Move code cursor to top / bottom"], ["gp / gc", "Switch to Preview / Code tab"]] }
6847
+ {
6848
+ title: "Global",
6849
+ rows: [
6850
+ ["Ctrl+K", "Open file palette"],
6851
+ ["Ctrl+G", "Open grep palette"],
6852
+ ["/", "Focus file filter"],
6853
+ ["t", "Toggle theme"]
6854
+ ]
6855
+ },
6856
+ {
6857
+ title: "Panels",
6858
+ rows: [
6859
+ ["Ctrl+H", "Focus sidebar"],
6860
+ ["Ctrl+L", "Focus main panel"]
6861
+ ]
6862
+ },
6863
+ {
6864
+ title: "Sidebar",
6865
+ rows: [
6866
+ ["j / k", "Move selection down / up"],
6867
+ ["Ctrl+D / Ctrl+U", "Move selection by half a page"],
6868
+ ["gg / Shift+G", "Move to top / bottom"],
6869
+ ["Enter", "Open selected item"],
6870
+ ["h / l", "Collapse / expand directory"]
6871
+ ]
6872
+ },
6873
+ {
6874
+ title: "Main Panel",
6875
+ rows: [
6876
+ ["j / k", "Move code cursor down / up"],
6877
+ ["Ctrl+D / Ctrl+U", "Move code cursor by half a page"],
6878
+ ["gg / Shift+G", "Move code cursor to top / bottom"],
6879
+ ["gp / gc", "Switch to Preview / Code tab"]
6880
+ ]
6881
+ }
6851
6882
  ]
6852
6883
  }
6853
6884
  }
@@ -6861,10 +6892,41 @@
6861
6892
  title: "キーバインド",
6862
6893
  intro: "キーボードだけでパネル移動、ファイル選択、スクロールを行うためのショートカットです。",
6863
6894
  groups: [
6864
- { title: "グローバル", rows: [["Ctrl+K", "ファイルパレットを開く"], ["Ctrl+G", "grep パレットを開く"], ["/", "ファイルフィルターへフォーカス"], ["t", "テーマ切り替え"]] },
6865
- { title: "パネル", rows: [["Ctrl+H", "サイドバーへフォーカス"], ["Ctrl+L", "メインパネルへフォーカス"]] },
6866
- { title: "サイドバー", rows: [["j / k", "選択を下 / 上へ移動"], ["Ctrl+D / Ctrl+U", "半ページ分選択を移動"], ["gg / Shift+G", "先頭 / 末尾へ移動"], ["Enter", "選択項目を開く"], ["h / l", "ディレクトリを閉じる / 開く"]] },
6867
- { title: "メインパネル", rows: [["j / k", "コードカーソルを下 / 上へ移動"], ["Ctrl+D / Ctrl+U", "コードカーソルを半ページ分移動"], ["gg / Shift+G", "コードカーソルを先頭 / 末尾へ移動"], ["gp / gc", "Preview / Code タブへ切り替え"]] }
6895
+ {
6896
+ title: "グローバル",
6897
+ rows: [
6898
+ ["Ctrl+K", "ファイルパレットを開く"],
6899
+ ["Ctrl+G", "grep パレットを開く"],
6900
+ ["/", "ファイルフィルターへフォーカス"],
6901
+ ["t", "テーマ切り替え"]
6902
+ ]
6903
+ },
6904
+ {
6905
+ title: "パネル",
6906
+ rows: [
6907
+ ["Ctrl+H", "サイドバーへフォーカス"],
6908
+ ["Ctrl+L", "メインパネルへフォーカス"]
6909
+ ]
6910
+ },
6911
+ {
6912
+ title: "サイドバー",
6913
+ rows: [
6914
+ ["j / k", "選択を下 / 上へ移動"],
6915
+ ["Ctrl+D / Ctrl+U", "半ページ分選択を移動"],
6916
+ ["gg / Shift+G", "先頭 / 末尾へ移動"],
6917
+ ["Enter", "選択項目を開く"],
6918
+ ["h / l", "ディレクトリを閉じる / 開く"]
6919
+ ]
6920
+ },
6921
+ {
6922
+ title: "メインパネル",
6923
+ rows: [
6924
+ ["j / k", "コードカーソルを下 / 上へ移動"],
6925
+ ["Ctrl+D / Ctrl+U", "コードカーソルを半ページ分移動"],
6926
+ ["gg / Shift+G", "コードカーソルを先頭 / 末尾へ移動"],
6927
+ ["gp / gc", "Preview / Code タブへ切り替え"]
6928
+ ]
6929
+ }
6868
6930
  ]
6869
6931
  }
6870
6932
  }
@@ -6915,7 +6977,10 @@
6915
6977
  }
6916
6978
  function resetSourceCursorForTarget(target, totalLines) {
6917
6979
  const routeLine = lineTargetStart(currentSourceLineTarget(target));
6918
- SOURCE_CURSOR = { target, line: Math.max(1, Math.min(totalLines, routeLine || 1)) };
6980
+ SOURCE_CURSOR = {
6981
+ target,
6982
+ line: Math.max(1, Math.min(totalLines, routeLine || 1))
6983
+ };
6919
6984
  }
6920
6985
  function scrollSourceCursorIntoView(cursor, edge = "nearest") {
6921
6986
  const scroller = findMainScrollTarget();
@@ -7004,7 +7069,10 @@
7004
7069
  return;
7005
7070
  const target = findMainScrollTarget();
7006
7071
  if (target) {
7007
- target.scrollTo({ top: edge === "top" ? 0 : target.scrollHeight, behavior: "auto" });
7072
+ target.scrollTo({
7073
+ top: edge === "top" ? 0 : target.scrollHeight,
7074
+ behavior: "auto"
7075
+ });
7008
7076
  return;
7009
7077
  }
7010
7078
  const top = edge === "top" ? 0 : Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
@@ -7033,7 +7101,9 @@
7033
7101
  }
7034
7102
  function normalizeScopeOmitDirs(value) {
7035
7103
  const raw = Array.isArray(value) ? value : value.split(/[\n,]+/);
7036
- return [...new Set(raw.map((item) => item.trim()).filter((item) => item && item.length <= 64 && !item.includes("/") && !item.includes("\\") && item !== "." && item !== ".." && item !== ".git"))].slice(0, 100).sort((a2, b2) => a2.localeCompare(b2));
7104
+ return [
7105
+ ...new Set(raw.map((item) => item.trim()).filter((item) => item && item.length <= 64 && !item.includes("/") && !item.includes("\\") && item !== "." && item !== ".." && item !== ".git"))
7106
+ ].slice(0, 100).sort((a2, b2) => a2.localeCompare(b2));
7037
7107
  }
7038
7108
  function scopeOmitDirsStorageKey() {
7039
7109
  return SCOPE_OMIT_DIRS_STORAGE_KEY_PREFIX + (PROJECT_NAME || "default");
@@ -7494,7 +7564,14 @@
7494
7564
  refreshRepositoryTreeAfterSettings();
7495
7565
  }
7496
7566
  function buildTree(files) {
7497
- const root = { name: "", dirs: {}, files: [], path: "", minOrder: Infinity, explicit: true };
7567
+ const root = {
7568
+ name: "",
7569
+ dirs: {},
7570
+ files: [],
7571
+ path: "",
7572
+ minOrder: Infinity,
7573
+ explicit: true
7574
+ };
7498
7575
  for (const f2 of files) {
7499
7576
  const parts = f2.path.split("/");
7500
7577
  let node = root;
@@ -7504,7 +7581,13 @@
7504
7581
  const p2 = parts[i2];
7505
7582
  acc = acc ? acc + "/" + p2 : p2;
7506
7583
  if (!node.dirs[p2]) {
7507
- node.dirs[p2] = { name: p2, dirs: {}, files: [], path: acc, minOrder: Infinity };
7584
+ node.dirs[p2] = {
7585
+ name: p2,
7586
+ dirs: {},
7587
+ files: [],
7588
+ path: acc,
7589
+ minOrder: Infinity
7590
+ };
7508
7591
  }
7509
7592
  node = node.dirs[p2];
7510
7593
  if (typeof f2.order === "number" && f2.order < node.minOrder)
@@ -7544,7 +7627,11 @@
7544
7627
  items.push({ kind: "dir", sortKey: d2.minOrder, dir: d2 });
7545
7628
  }
7546
7629
  for (const f2 of node.files) {
7547
- items.push({ kind: "file", sortKey: f2.order != null ? f2.order : Infinity, file: f2 });
7630
+ items.push({
7631
+ kind: "file",
7632
+ sortKey: f2.order != null ? f2.order : Infinity,
7633
+ file: f2
7634
+ });
7548
7635
  }
7549
7636
  items.sort((a2, b2) => a2.sortKey - b2.sortKey);
7550
7637
  for (const item of items) {
@@ -7665,7 +7752,9 @@
7665
7752
  scheduleMainSurfaceFocus();
7666
7753
  });
7667
7754
  if (!onFileClick)
7668
- li.addEventListener("mouseenter", () => prefetchByPath(f2.path), { passive: true });
7755
+ li.addEventListener("mouseenter", () => prefetchByPath(f2.path), {
7756
+ passive: true
7757
+ });
7669
7758
  ul.appendChild(li);
7670
7759
  }
7671
7760
  }
@@ -7698,7 +7787,9 @@
7698
7787
  scheduleMainSurfaceFocus();
7699
7788
  });
7700
7789
  if (!onFileClick)
7701
- li.addEventListener("mouseenter", () => prefetchByPath(f2.path), { passive: true });
7790
+ li.addEventListener("mouseenter", () => prefetchByPath(f2.path), {
7791
+ passive: true
7792
+ });
7702
7793
  ul.appendChild(li);
7703
7794
  });
7704
7795
  }
@@ -7998,7 +8089,13 @@
7998
8089
  });
7999
8090
  }
8000
8091
  function escapeHtml2(s2) {
8001
- return String(s2 == null ? "" : s2).replace(/[&<>"']/g, (c2) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[c2]);
8092
+ return String(s2 == null ? "" : s2).replace(/[&<>"']/g, (c2) => ({
8093
+ "&": "&amp;",
8094
+ "<": "&lt;",
8095
+ ">": "&gt;",
8096
+ '"': "&quot;",
8097
+ "'": "&#39;"
8098
+ })[c2]);
8002
8099
  }
8003
8100
  function sourceTargetsEqual(a2, b2) {
8004
8101
  return !!a2 && !!b2 && a2.path === b2.path && a2.ref === b2.ref;
@@ -8030,7 +8127,10 @@
8030
8127
  return { path: file.path, ref };
8031
8128
  }
8032
8129
  function currentRange() {
8033
- return { from: STATE.from || DEFAULT_RANGE.from, to: STATE.to || DEFAULT_RANGE.to };
8130
+ return {
8131
+ from: STATE.from || DEFAULT_RANGE.from,
8132
+ to: STATE.to || DEFAULT_RANGE.to
8133
+ };
8034
8134
  }
8035
8135
  function sourceTargetFromRoute() {
8036
8136
  return STATE.route.screen === "file" ? { path: STATE.route.path, ref: STATE.route.ref } : null;
@@ -8053,7 +8153,12 @@
8053
8153
  STATE.repoRef = nextRoute.ref || "worktree";
8054
8154
  }
8055
8155
  const url = buildRoute(nextRoute);
8056
- const state = nextRoute.screen === "file" ? { screen: "file", path: nextRoute.path, ref: nextRoute.ref, view: nextRoute.view || "detail" } : { view: nextRoute.screen };
8156
+ const state = nextRoute.screen === "file" ? {
8157
+ screen: "file",
8158
+ path: nextRoute.path,
8159
+ ref: nextRoute.ref,
8160
+ view: nextRoute.view || "detail"
8161
+ } : { view: nextRoute.screen };
8057
8162
  if (replace2)
8058
8163
  history.replaceState(state, "", url);
8059
8164
  else
@@ -8074,13 +8179,23 @@
8074
8179
  link2.classList.toggle("active", active);
8075
8180
  link2.setAttribute("aria-current", active ? "page" : "false");
8076
8181
  if (link2.dataset.route === "repo") {
8077
- link2.href = buildRoute({ screen: "repo", ref: STATE.repoRef || "worktree", path: "", range: currentRange() });
8182
+ link2.href = buildRoute({
8183
+ screen: "repo",
8184
+ ref: STATE.repoRef || "worktree",
8185
+ path: "",
8186
+ range: currentRange()
8187
+ });
8078
8188
  }
8079
8189
  if (link2.dataset.route === "diff") {
8080
8190
  link2.href = buildRoute({ screen: "diff", range: currentRange() });
8081
8191
  }
8082
8192
  if (link2.dataset.route === "help") {
8083
- link2.href = buildRoute({ screen: "help", lang: helpLanguageFromRoute(), section: helpSectionFromRoute(), range: currentRange() });
8193
+ link2.href = buildRoute({
8194
+ screen: "help",
8195
+ lang: helpLanguageFromRoute(),
8196
+ section: helpSectionFromRoute(),
8197
+ range: currentRange()
8198
+ });
8084
8199
  }
8085
8200
  });
8086
8201
  }
@@ -8119,7 +8234,12 @@
8119
8234
  langSelect.appendChild(option);
8120
8235
  });
8121
8236
  langSelect.addEventListener("change", () => {
8122
- setRoute({ screen: "help", lang: langSelect.value, section, range: currentRange() });
8237
+ setRoute({
8238
+ screen: "help",
8239
+ lang: langSelect.value,
8240
+ section,
8241
+ range: currentRange()
8242
+ });
8123
8243
  setPageMode();
8124
8244
  renderHelpPage();
8125
8245
  syncHeaderMenu();
@@ -8135,7 +8255,12 @@
8135
8255
  button.className = helpSection === section ? "active" : "";
8136
8256
  button.textContent = content.sections[helpSection].nav;
8137
8257
  button.addEventListener("click", () => {
8138
- setRoute({ screen: "help", lang, section: helpSection, range: currentRange() });
8258
+ setRoute({
8259
+ screen: "help",
8260
+ lang,
8261
+ section: helpSection,
8262
+ range: currentRange()
8263
+ });
8139
8264
  renderHelpPage();
8140
8265
  syncHeaderMenu();
8141
8266
  });
@@ -8265,7 +8390,10 @@
8265
8390
  try {
8266
8391
  const res = await fetch("/_open_path", {
8267
8392
  method: "POST",
8268
- headers: { "Content-Type": "application/json", "X-Code-Viewer-Action": "1" },
8393
+ headers: {
8394
+ "Content-Type": "application/json",
8395
+ "X-Code-Viewer-Action": "1"
8396
+ },
8269
8397
  body: JSON.stringify({ path, kind })
8270
8398
  });
8271
8399
  if (!res.ok)
@@ -8370,7 +8498,12 @@
8370
8498
  return dropPanel;
8371
8499
  }
8372
8500
  function repoRoute(ref, path) {
8373
- return { screen: "repo", ref: ref || "worktree", path, range: currentRange() };
8501
+ return {
8502
+ screen: "repo",
8503
+ ref: ref || "worktree",
8504
+ path,
8505
+ range: currentRange()
8506
+ };
8374
8507
  }
8375
8508
  function wireRefSelectorInput(input, onPick) {
8376
8509
  const wrap = input.closest("[data-ref-selector]");
@@ -8516,7 +8649,13 @@
8516
8649
  setRoute(repoRoute(meta.ref, entry.path));
8517
8650
  loadRepo();
8518
8651
  } else if (entry.type === "blob") {
8519
- setRoute({ screen: "file", path: entry.path, ref: meta.ref, view: "blob", range: currentRange() });
8652
+ setRoute({
8653
+ screen: "file",
8654
+ path: entry.path,
8655
+ ref: meta.ref,
8656
+ view: "blob",
8657
+ range: currentRange()
8658
+ });
8520
8659
  renderStandaloneSource({ path: entry.path, ref: meta.ref });
8521
8660
  }
8522
8661
  });
@@ -8553,7 +8692,13 @@
8553
8692
  wrapper.appendChild(await renderMarkdownPreview(meta.readme.text, { path: meta.readme.path, ref: meta.ref }, {
8554
8693
  syntaxHighlight: STATE.syntaxHighlight,
8555
8694
  onNavigateMarkdown: (path, ref) => {
8556
- setRoute({ screen: "file", path, ref, view: "blob", range: currentRange() });
8695
+ setRoute({
8696
+ screen: "file",
8697
+ path,
8698
+ ref,
8699
+ view: "blob",
8700
+ range: currentRange()
8701
+ });
8557
8702
  renderStandaloneSource({ path, ref });
8558
8703
  }
8559
8704
  }));
@@ -8608,7 +8753,13 @@
8608
8753
  loadRepo();
8609
8754
  return;
8610
8755
  }
8611
- setRoute({ screen: "file", path: file.path, ref: normalizedRef, view: "blob", range: currentRange() });
8756
+ setRoute({
8757
+ screen: "file",
8758
+ path: file.path,
8759
+ ref: normalizedRef,
8760
+ view: "blob",
8761
+ range: currentRange()
8762
+ });
8612
8763
  renderStandaloneSource({ path: file.path, ref: normalizedRef });
8613
8764
  });
8614
8765
  REPO_SIDEBAR_REF = normalizedRef;
@@ -8668,7 +8819,9 @@
8668
8819
  }, { rootMargin: "1200px 0px 1600px 0px" });
8669
8820
  document.querySelectorAll(".gdp-file-shell.pending").forEach((c2) => lazyObserver.observe(c2));
8670
8821
  }
8671
- window.addEventListener("scroll", () => enqueueInitialLoads(), { passive: true });
8822
+ window.addEventListener("scroll", () => enqueueInitialLoads(), {
8823
+ passive: true
8824
+ });
8672
8825
  window.addEventListener("resize", () => {
8673
8826
  enqueueInitialLoads();
8674
8827
  syncSidebarHeaderHeight();
@@ -8757,7 +8910,12 @@
8757
8910
  openFileBtn.title = "Open this file in the virtualized source viewer";
8758
8911
  openFileBtn.addEventListener("click", () => {
8759
8912
  const target = fileSourceTarget(file);
8760
- setRoute({ screen: "file", path: target.path, ref: target.ref, range: currentRange() });
8913
+ setRoute({
8914
+ screen: "file",
8915
+ path: target.path,
8916
+ ref: target.ref,
8917
+ range: currentRange()
8918
+ });
8761
8919
  applySourceRouteToShell();
8762
8920
  });
8763
8921
  const fullBtn = document.createElement("button");
@@ -8916,7 +9074,11 @@
8916
9074
  if (!info)
8917
9075
  return;
8918
9076
  const txt = (info.textContent || "").trim();
8919
- arr.push({ tr, info, hunk: parseHunkHeader(txt) });
9077
+ arr.push({
9078
+ tr,
9079
+ info,
9080
+ hunk: parseHunkHeader(txt)
9081
+ });
8920
9082
  });
8921
9083
  perTable.push(arr);
8922
9084
  });
@@ -9161,7 +9323,13 @@
9161
9323
  });
9162
9324
  };
9163
9325
  rows.forEach((row) => {
9164
- row.ln.appendChild(createExpandStack([{ direction: "down", title: "Show more lines", onClick: fetchAndInsert }]));
9326
+ row.ln.appendChild(createExpandStack([
9327
+ {
9328
+ direction: "down",
9329
+ title: "Show more lines",
9330
+ onClick: fetchAndInsert
9331
+ }
9332
+ ]));
9165
9333
  });
9166
9334
  syncExpandRowHeights(rows.map((row) => row.tr), rows[0].tr);
9167
9335
  }
@@ -9309,7 +9477,23 @@
9309
9477
  card.appendChild(view);
9310
9478
  }
9311
9479
  function isPreviewableSource(path) {
9312
- return /\.(md|markdown|mdown|mkdn|mdx)$/i.test(path);
9480
+ return /\.(md|markdown|mdown|mkdn|mdx|html|htm)$/i.test(path);
9481
+ }
9482
+ function sourcePreviewKind(path) {
9483
+ if (/\.(md|markdown|mdown|mkdn|mdx)$/i.test(path))
9484
+ return "markdown";
9485
+ if (/\.(html|htm)$/i.test(path))
9486
+ return "html";
9487
+ return null;
9488
+ }
9489
+ function renderHtmlPreview(target, html) {
9490
+ const preview = document.createElement("div");
9491
+ preview.className = "gdp-html-preview";
9492
+ const frame = document.createElement("iframe");
9493
+ frame.title = target.path + " preview";
9494
+ frame.srcdoc = html;
9495
+ preview.appendChild(frame);
9496
+ return preview;
9313
9497
  }
9314
9498
  const EXT_TO_LANG = {
9315
9499
  js: "javascript",
@@ -9753,6 +9937,7 @@
9753
9937
  if (signal?.aborted)
9754
9938
  return false;
9755
9939
  const previewable = isPreviewableSource(target.path);
9940
+ const previewKind = sourcePreviewKind(target.path);
9756
9941
  const tabsHost = card.querySelector(".gdp-file-detail-tabs");
9757
9942
  if (usesVirtualSource) {
9758
9943
  const virtualCode = renderVirtualSource(target, textValue, lines, hljsRef, lang);
@@ -9762,11 +9947,17 @@
9762
9947
  tabsHost.hidden = false;
9763
9948
  tabsHost.replaceChildren(tabs2);
9764
9949
  }
9765
- const preview = await renderMarkdownPreview(textValue, target, {
9950
+ const preview = previewKind === "html" ? renderHtmlPreview(target, textValue) : await renderMarkdownPreview(textValue, target, {
9766
9951
  syntaxHighlight: STATE.syntaxHighlight,
9767
9952
  signal,
9768
9953
  onNavigateMarkdown: (path, ref) => {
9769
- setRoute({ screen: "file", path, ref, view: "blob", range: currentRange() });
9954
+ setRoute({
9955
+ screen: "file",
9956
+ path,
9957
+ ref,
9958
+ view: "blob",
9959
+ range: currentRange()
9960
+ });
9770
9961
  renderStandaloneSource({ path, ref });
9771
9962
  }
9772
9963
  });
@@ -9848,11 +10039,17 @@
9848
10039
  tabsHost.replaceChildren(tabs);
9849
10040
  }
9850
10041
  if (previewable) {
9851
- const preview = await renderMarkdownPreview(textValue, target, {
10042
+ const preview = previewKind === "html" ? renderHtmlPreview(target, textValue) : await renderMarkdownPreview(textValue, target, {
9852
10043
  syntaxHighlight: STATE.syntaxHighlight,
9853
10044
  signal,
9854
10045
  onNavigateMarkdown: (path, ref) => {
9855
- setRoute({ screen: "file", path, ref, view: "blob", range: currentRange() });
10046
+ setRoute({
10047
+ screen: "file",
10048
+ path,
10049
+ ref,
10050
+ view: "blob",
10051
+ range: currentRange()
10052
+ });
9856
10053
  renderStandaloneSource({ path, ref });
9857
10054
  }
9858
10055
  });
@@ -10229,7 +10426,10 @@
10229
10426
  const activeRange = search?.activeRange() || null;
10230
10427
  if (appendVirtualSourceLineCode(code2, line, searchQuery, activeRange, index + 1)) {} else if (hljsRef && hljsRef.highlight && lang && line.length <= VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH && (!hljsRef.getLanguage || hljsRef.getLanguage(lang))) {
10231
10428
  try {
10232
- code2.innerHTML = hljsRef.highlight(line, { language: lang, ignoreIllegals: true }).value;
10429
+ code2.innerHTML = hljsRef.highlight(line, {
10430
+ language: lang,
10431
+ ignoreIllegals: true
10432
+ }).value;
10233
10433
  code2.classList.add("hljs");
10234
10434
  } catch {
10235
10435
  code2.textContent = line;
@@ -10391,7 +10591,10 @@
10391
10591
  code2.textContent = "";
10392
10592
  } else if (appendVirtualSourceLineCode(code2, line, search?.query() || "", search?.activeRange() || null, lineNumber)) {} else if (hljsRef && hljsRef.highlight && lang && line.length <= VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH && (!hljsRef.getLanguage || hljsRef.getLanguage(lang))) {
10393
10593
  try {
10394
- code2.innerHTML = hljsRef.highlight(line, { language: lang, ignoreIllegals: true }).value;
10594
+ code2.innerHTML = hljsRef.highlight(line, {
10595
+ language: lang,
10596
+ ignoreIllegals: true
10597
+ }).value;
10395
10598
  code2.classList.add("hljs");
10396
10599
  } catch {
10397
10600
  code2.textContent = line;
@@ -10420,7 +10623,9 @@
10420
10623
  let done = false;
10421
10624
  while (!done && matches.length < 5000) {
10422
10625
  const endLine = startLine + VIRTUAL_SOURCE_PAGE_SIZE - 1;
10423
- const data = await trackLoad(fetch(buildFileRangeUrl(target, startLine, endLine), { signal: matchSignal }).then((res) => {
10626
+ const data = await trackLoad(fetch(buildFileRangeUrl(target, startLine, endLine), {
10627
+ signal: matchSignal
10628
+ }).then((res) => {
10424
10629
  if (!res.ok)
10425
10630
  throw new Error("file range failed");
10426
10631
  return res.json();
@@ -10431,7 +10636,11 @@
10431
10636
  const lineNumber = data.start + index;
10432
10637
  lines.set(lineNumber, lineValue);
10433
10638
  for (const range of virtualSourceSearchRanges(lineValue, query)) {
10434
- matches.push({ line: lineNumber, start: range.start, end: range.end });
10639
+ matches.push({
10640
+ line: lineNumber,
10641
+ start: range.start,
10642
+ end: range.end
10643
+ });
10435
10644
  if (matches.length >= 5000)
10436
10645
  break;
10437
10646
  }
@@ -10491,7 +10700,9 @@
10491
10700
  const hljsRef = STATE.syntaxHighlight ? await loadSyntaxHighlighter() : null;
10492
10701
  if (signal?.aborted)
10493
10702
  return false;
10494
- const initial = await trackLoad(fetch(buildFileRangeUrl(target, initialStart, initialEnd), { signal }).then((res) => res.ok ? res.json() : null));
10703
+ const initial = await trackLoad(fetch(buildFileRangeUrl(target, initialStart, initialEnd), {
10704
+ signal
10705
+ }).then((res) => res.ok ? res.json() : null));
10495
10706
  if (!initial)
10496
10707
  return false;
10497
10708
  if (signal?.aborted)
@@ -10942,7 +11153,12 @@
10942
11153
  viewFile.addEventListener("click", (e2) => {
10943
11154
  e2.stopPropagation();
10944
11155
  const target = fileSourceTarget(file);
10945
- setRoute({ screen: "file", path: target.path, ref: target.ref, range: currentRange() });
11156
+ setRoute({
11157
+ screen: "file",
11158
+ path: target.path,
11159
+ ref: target.ref,
11160
+ range: currentRange()
11161
+ });
10946
11162
  applySourceRouteToShell();
10947
11163
  });
10948
11164
  header.appendChild(viewFile);
@@ -11053,7 +11269,10 @@
11053
11269
  if (text2.length === 0)
11054
11270
  return;
11055
11271
  try {
11056
- s2.innerHTML = hljsRef.highlight(text2, { language: lang, ignoreIllegals: true }).value;
11272
+ s2.innerHTML = hljsRef.highlight(text2, {
11273
+ language: lang,
11274
+ ignoreIllegals: true
11275
+ }).value;
11057
11276
  if (!s2.classList.contains("hljs"))
11058
11277
  s2.classList.add("hljs");
11059
11278
  } catch (_) {}
@@ -11084,7 +11303,10 @@
11084
11303
  if (text2.length === 0)
11085
11304
  continue;
11086
11305
  try {
11087
- s2.innerHTML = hljsRef.highlight(text2, { language: lang, ignoreIllegals: true }).value;
11306
+ s2.innerHTML = hljsRef.highlight(text2, {
11307
+ language: lang,
11308
+ ignoreIllegals: true
11309
+ }).value;
11088
11310
  if (!s2.classList.contains("hljs"))
11089
11311
  s2.classList.add("hljs");
11090
11312
  } catch (_) {}
@@ -11729,7 +11951,17 @@
11729
11951
  if (!query.trim()) {
11730
11952
  const base2 = source === "diff" ? state.diffSnapshot.map((file) => {
11731
11953
  const target = fileSourceTarget(file);
11732
- return { kind: "file", path: file.path, old_path: file.old_path, displayPath: file.path, ref: paletteRef(source), targetPath: target.path, targetRef: target.ref, source, ranges: [] };
11954
+ return {
11955
+ kind: "file",
11956
+ path: file.path,
11957
+ old_path: file.old_path,
11958
+ displayPath: file.path,
11959
+ ref: paletteRef(source),
11960
+ targetPath: target.path,
11961
+ targetRef: target.ref,
11962
+ source,
11963
+ ranges: []
11964
+ };
11733
11965
  }) : [];
11734
11966
  state.items = limitPaletteResults(base2);
11735
11967
  state.selected = state.items.length ? 0 : -1;
@@ -11795,7 +12027,9 @@
11795
12027
  }
11796
12028
  const controller = new AbortController;
11797
12029
  state.controller = controller;
11798
- trackLoad(fetch("/_grep?" + params.toString(), { signal: controller.signal }).then((r2) => {
12030
+ trackLoad(fetch("/_grep?" + params.toString(), {
12031
+ signal: controller.signal
12032
+ }).then((r2) => {
11799
12033
  if (!r2.ok)
11800
12034
  throw new Error("grep failed");
11801
12035
  return r2.json();
@@ -11839,22 +12073,45 @@
11839
12073
  if (item.kind === "file") {
11840
12074
  if (item.source === "diff") {
11841
12075
  if (STATE.route.screen === "file") {
11842
- setRoute({ screen: "file", path: item.targetPath || item.path, ref: item.targetRef || item.ref, range: currentRange() });
12076
+ setRoute({
12077
+ screen: "file",
12078
+ path: item.targetPath || item.path,
12079
+ ref: item.targetRef || item.ref,
12080
+ range: currentRange()
12081
+ });
11843
12082
  applySourceRouteToShell();
11844
12083
  } else {
11845
12084
  scrollToFile(item.path);
11846
12085
  }
11847
12086
  } else {
11848
- setRoute({ screen: "file", path: item.path, ref: item.ref, view: "blob", range: currentRange() });
12087
+ setRoute({
12088
+ screen: "file",
12089
+ path: item.path,
12090
+ ref: item.ref,
12091
+ view: "blob",
12092
+ range: currentRange()
12093
+ });
11849
12094
  renderStandaloneSource({ path: item.path, ref: item.ref });
11850
12095
  }
11851
12096
  return;
11852
12097
  }
11853
12098
  if (item.source === "diff") {
11854
- setRoute({ screen: "diff", range: currentRange(), path: item.path, line: item.line });
12099
+ setRoute({
12100
+ screen: "diff",
12101
+ range: currentRange(),
12102
+ path: item.path,
12103
+ line: item.line
12104
+ });
11855
12105
  scrollToFile(item.path, item.line);
11856
12106
  } else {
11857
- setRoute({ screen: "file", path: item.path, ref: item.ref, view: "blob", line: item.line, range: currentRange() });
12107
+ setRoute({
12108
+ screen: "file",
12109
+ path: item.path,
12110
+ ref: item.ref,
12111
+ view: "blob",
12112
+ line: item.line,
12113
+ range: currentRange()
12114
+ });
11858
12115
  renderStandaloneSource({ path: item.path, ref: item.ref });
11859
12116
  }
11860
12117
  }
@@ -11991,7 +12248,10 @@
11991
12248
  else if (scope === "sidebar")
11992
12249
  moveActiveSidebarToEdge(edge);
11993
12250
  else
11994
- window.scrollTo({ top: edge === "top" ? 0 : Math.max(document.documentElement.scrollHeight, document.body.scrollHeight), behavior: "auto" });
12251
+ window.scrollTo({
12252
+ top: edge === "top" ? 0 : Math.max(document.documentElement.scrollHeight, document.body.scrollHeight),
12253
+ behavior: "auto"
12254
+ });
11995
12255
  return true;
11996
12256
  }
11997
12257
  if (action === "layout-unified") {
@@ -12041,7 +12301,9 @@
12041
12301
  function handleVirtualSourcePagingKeydown(e2) {
12042
12302
  handleVirtualSourcePagingKey(e2, e2.target);
12043
12303
  }
12044
- document.addEventListener("keydown", handleVirtualSourcePagingKeydown, { capture: true });
12304
+ document.addEventListener("keydown", handleVirtualSourcePagingKeydown, {
12305
+ capture: true
12306
+ });
12045
12307
  document.addEventListener("keydown", (e2) => {
12046
12308
  if (e2.__gdpVirtualSourcePagingHandled)
12047
12309
  return;
@@ -12145,7 +12407,12 @@
12145
12407
  if (STATE.route.screen === "file") {
12146
12408
  setRoute({ screen: "file", path: STATE.route.path, ref: STATE.route.ref, range }, true);
12147
12409
  } else if (STATE.route.screen === "help") {
12148
- setRoute({ screen: "help", lang: helpLanguageFromRoute(), section: helpSectionFromRoute(), range }, true);
12410
+ setRoute({
12411
+ screen: "help",
12412
+ lang: helpLanguageFromRoute(),
12413
+ section: helpSectionFromRoute(),
12414
+ range
12415
+ }, true);
12149
12416
  renderHelpPage();
12150
12417
  } else {
12151
12418
  setRoute({ screen: "diff", range }, true);
@@ -12154,7 +12421,12 @@
12154
12421
  }
12155
12422
  syncRefInputs();
12156
12423
  syncHeaderMenu();
12157
- const REFS = { branches: [], tags: [], commits: [], current: "" };
12424
+ const REFS = {
12425
+ branches: [],
12426
+ tags: [],
12427
+ commits: [],
12428
+ current: ""
12429
+ };
12158
12430
  const popover = $("#ref-popover");
12159
12431
  const popBody = popover.querySelector(".rp-body");
12160
12432
  const popSearch = popover.querySelector(".rp-search");
@@ -12258,7 +12530,13 @@
12258
12530
  wireRefSelectorInput($("#repo-target"), (ref) => {
12259
12531
  if (STATE.route.screen !== "file")
12260
12532
  return;
12261
- setRoute({ screen: "file", path: STATE.route.path, ref, view: "blob", range: currentRange() });
12533
+ setRoute({
12534
+ screen: "file",
12535
+ path: STATE.route.path,
12536
+ ref,
12537
+ view: "blob",
12538
+ range: currentRange()
12539
+ });
12262
12540
  renderStandaloneSource({ path: STATE.route.path, ref });
12263
12541
  });
12264
12542
  popSearch.addEventListener("input", () => buildPopBody(popSearch.value));