dsh-diff-approval 0.17.0 → 0.18.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/lib/client.js CHANGED
@@ -7838,7 +7838,7 @@ window.__ModuleLoader__.load({
7838
7838
  }
7839
7839
  return { position: value.length };
7840
7840
  }
7841
- function parseColor(sequence) {
7841
+ function parseColor$1(sequence) {
7842
7842
  const colorMode = sequence.shift();
7843
7843
  if (colorMode === "2") {
7844
7844
  const rgb = sequence.splice(0, 3).map((x) => Number.parseInt(x));
@@ -7888,7 +7888,7 @@ window.__ModuleLoader__.load({
7888
7888
  }
7889
7889
  });
7890
7890
  else if (codeInt === 38) {
7891
- const color = parseColor(sequence);
7891
+ const color = parseColor$1(sequence);
7892
7892
  if (color) commands.push({
7893
7893
  type: "setForegroundColor",
7894
7894
  value: color
@@ -7902,7 +7902,7 @@ window.__ModuleLoader__.load({
7902
7902
  }
7903
7903
  });
7904
7904
  else if (codeInt === 48) {
7905
- const color = parseColor(sequence);
7905
+ const color = parseColor$1(sequence);
7906
7906
  if (color) commands.push({
7907
7907
  type: "setBackgroundColor",
7908
7908
  value: color
@@ -12384,7 +12384,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12384
12384
  });
12385
12385
  chip.insertAdjacentElement("afterend", btn);
12386
12386
  }
12387
- for (const btn of document.querySelectorAll(`[${BUTTON_ATTR}]`)) btn.style.display = "inline-flex";
12387
+ for (const btn of document.querySelectorAll(`[${BUTTON_ATTR}]`)) {
12388
+ const chip = btn.previousElementSibling;
12389
+ const chipHidden = chip !== null && getComputedStyle(chip).display === "none";
12390
+ btn.style.display = chipHidden ? "none" : "inline-flex";
12391
+ }
12388
12392
  };
12389
12393
  inject();
12390
12394
  const observer = new MutationObserver(() => inject());
@@ -12409,6 +12413,10 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12409
12413
  const TAB_WIDTH_KEY = "diff-approval:tab-size";
12410
12414
  const SPLIT_MODE_KEY = "diff-approval:split-mode";
12411
12415
  const NAV_LEAD_KEY = "diff-approval:nav-lead-rows";
12416
+ const DIFF_FONT_SCALE_KEY = "diff-approval:diff-font-scale";
12417
+ const DIFF_LINE_HEIGHT_KEY = "diff-approval:diff-line-height";
12418
+ const DIFF_ADD_COLOR_KEY = "diff-approval:diff-add-color";
12419
+ const DIFF_DEL_COLOR_KEY = "diff-approval:diff-del-color";
12412
12420
  const WRAP_PREFIX = "diff-approval:wrap:";
12413
12421
  /**
12414
12422
  * Whether copying a reference should also paste it into the chat input and
@@ -12465,6 +12473,68 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12465
12473
  localStorage.setItem(TAB_WIDTH_KEY, String(value));
12466
12474
  }
12467
12475
  /**
12476
+ * The diff code font size as a percentage of the current (theme) size. Defaults
12477
+ * to 100 (the current look); the settings UI steps it by ±10.
12478
+ * @returns the font-size scale, as a percentage (e.g. 100, 110, 90).
12479
+ */
12480
+ function diffFontScale() {
12481
+ const raw = Number.parseInt(localStorage.getItem(DIFF_FONT_SCALE_KEY) ?? "", 10);
12482
+ if (!Number.isFinite(raw)) return 100;
12483
+ return Math.max(50, Math.min(200, raw));
12484
+ }
12485
+ /** Persist the diff's code font-size scale (a percentage). */
12486
+ function setDiffFontScale(value) {
12487
+ localStorage.setItem(DIFF_FONT_SCALE_KEY, String(Math.max(50, Math.min(200, value))));
12488
+ }
12489
+ /**
12490
+ * The diff code line height in px (the fixed row height the virtual window and
12491
+ * jump math are keyed to). Defaults to 22 (the pre-customization value).
12492
+ * @returns the line height in px.
12493
+ */
12494
+ function diffLineHeight() {
12495
+ const raw = Number.parseInt(localStorage.getItem(DIFF_LINE_HEIGHT_KEY) ?? "", 10);
12496
+ if (!Number.isFinite(raw)) return 22;
12497
+ return Math.max(10, Math.min(36, raw));
12498
+ }
12499
+ /** Persist the diff's code line height (px). */
12500
+ function setDiffLineHeight(value) {
12501
+ localStorage.setItem(DIFF_LINE_HEIGHT_KEY, String(Math.max(10, Math.min(36, value))));
12502
+ }
12503
+ /** Read a theme CSS custom property, with a fallback when it is unavailable. */
12504
+ function themeColor(name, fallback) {
12505
+ if (typeof document !== "undefined") {
12506
+ const v = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
12507
+ if (/^#[0-9a-f]{6}$/i.test(v)) return v;
12508
+ }
12509
+ return fallback;
12510
+ }
12511
+ /** The added-line base color the user chose, or `undefined` (theme color). */
12512
+ function diffAddColor() {
12513
+ const v = localStorage.getItem(DIFF_ADD_COLOR_KEY);
12514
+ return v !== null && v.length > 0 ? v : void 0;
12515
+ }
12516
+ /** Persist the added-line base color (a hex like `#22c55e`). */
12517
+ function setDiffAddColor(value) {
12518
+ localStorage.setItem(DIFF_ADD_COLOR_KEY, value);
12519
+ }
12520
+ /** The removed-line base color the user chose, or `undefined` (theme color). */
12521
+ function diffDelColor() {
12522
+ const v = localStorage.getItem(DIFF_DEL_COLOR_KEY);
12523
+ return v !== null && v.length > 0 ? v : void 0;
12524
+ }
12525
+ /** Persist the removed-line base color (a hex like `#ef4444`). */
12526
+ function setDiffDelColor(value) {
12527
+ localStorage.setItem(DIFF_DEL_COLOR_KEY, value);
12528
+ }
12529
+ /** The theme's added-line base color, for the settings swatch default. */
12530
+ function currentDiffAddColor() {
12531
+ return themeColor("--dsw-alias-state-success-primary", "#22c55e");
12532
+ }
12533
+ /** The theme's removed-line base color, for the settings swatch default. */
12534
+ function currentDiffDelColor() {
12535
+ return themeColor("--dsw-alias-state-error-primary", "#ef4444");
12536
+ }
12537
+ /**
12468
12538
  * Whether the whole-file diff view uses the two-column (side-by-side) layout.
12469
12539
  * Default off (single column): the unified diff. Only an explicit `'1'` enables
12470
12540
  * split mode.
@@ -12550,7 +12620,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12550
12620
  }
12551
12621
  //#endregion
12552
12622
  //#region \0dsh-css:/home/runner/work/dsh-diff-approval/dsh-diff-approval/src/client/PendingPanel.module.css.mjs
12553
- const css = ".F1KBNa_layer{box-sizing:border-box;flex:none;align-items:center;width:calc(100% + 4px);height:42px;margin:4px -2px;display:flex;position:relative}.F1KBNa_footerButtons{align-items:center;width:100%;display:flex}.F1KBNa_badge{box-sizing:border-box;width:100%;height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.F1KBNa_badge:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_badge[data-active]{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_badge:disabled{color:var(--dsw-alias-label-tertiary);cursor:default;background:0 0}.F1KBNa_badgeLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.F1KBNa_badgeCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto;font-size:12px;line-height:16px}.F1KBNa_layer.F1KBNa_rail{width:36px;height:36px;margin:8px 0 10px}.F1KBNa_rail .F1KBNa_badge{border-radius:50%;justify-content:center;gap:0;width:36px;height:36px;padding:0}.F1KBNa_rail .F1KBNa_badgeLabel{display:none}.F1KBNa_rail .F1KBNa_badgeCount{box-sizing:border-box;background:var(--dsw-alias-state-business-primary);min-width:18px;height:18px;color:var(--dsw-alias-label-primary-foreground);font-variant-numeric:tabular-nums;border-radius:9px;justify-content:center;align-items:center;padding:0 4px;font-size:11px;line-height:18px;display:flex;position:absolute;top:-3px;right:-7px}.F1KBNa_fullscreenBackdrop{z-index:29;background:var(--dsw-specific-sidebar-fill);position:fixed;inset:0}.F1KBNa_panel{z-index:30;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:none;box-shadow:var(--dsw-shadow-lv2);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex-direction:column;display:flex;position:fixed;inset:8px 8px 128px;overflow:hidden}.F1KBNa_header{box-sizing:border-box;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:10px 12px;display:flex}.F1KBNa_headerActions{align-items:center;gap:2px;display:flex}.F1KBNa_settingsPage{padding:8px 12px}.F1KBNa_settingsGroup{border-bottom:1px solid var(--dsw-alias-border-l2);margin-top:8px}.F1KBNa_settingsGroupHeader{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;padding:12px 0;display:flex}.F1KBNa_settingsGroupTitle{font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsGroupChevron{margin-left:auto;transition:transform .15s}.F1KBNa_settingsGroup[data-open] .F1KBNa_settingsGroupChevron{transform:rotate(180deg)}.F1KBNa_settingsGroup[data-open] .F1KBNa_settingsGroupHeader{border-bottom:1px solid var(--dsw-alias-border-l2)}.F1KBNa_settingsGroupBody{display:grid}.F1KBNa_settingsGroupBody .F1KBNa_settingsRow{padding-left:16px}.F1KBNa_settingsGroupBody .F1KBNa_settingsRow:last-child,.F1KBNa_settingsPage>.F1KBNa_settingsRow:last-child{border-bottom:none}.F1KBNa_settingsRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.F1KBNa_settingsRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.F1KBNa_settingsRowTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsRowDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.F1KBNa_settingsSelector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.F1KBNa_settingsSelector:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_settingsSelectorChevron{flex:none}.F1KBNa_toggle{border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:18px;flex:none;width:60px;height:36px;padding:0;position:relative}.F1KBNa_toggle:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_toggle:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.F1KBNa_toggleOn{border-color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-state-business-primary)}.F1KBNa_toggleOn:hover{background:var(--dsw-alias-state-business-primary)}.F1KBNa_toggleThumb{background:var(--dsw-alias-label-primary);border-radius:50%;width:28px;height:28px;transition:left .12s;position:absolute;top:3px;left:3px}.F1KBNa_toggleOn .F1KBNa_toggleThumb{background:#fff;left:27px}.F1KBNa_stepper{align-items:center;gap:6px;display:inline-flex}.F1KBNa_stepperButton{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-module-platform);width:32px;height:32px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:8px;padding:0;position:relative}.F1KBNa_stepperButton:before,.F1KBNa_stepperButton:after{content:\"\";background:currentColor;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.F1KBNa_stepperButton:before{width:10px;height:1px}.F1KBNa_stepperButton:after{width:1px;height:10px;display:none}.F1KBNa_stepperButtonUp:after{display:block}.F1KBNa_stepperButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_stepperButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_stepperValue{text-align:center;min-width:2ch;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:14px;line-height:22px}.F1KBNa_states{flex-direction:column;flex:1;min-height:0;padding:4px 12px 12px;display:flex;overflow-y:auto}.F1KBNa_split{flex:1;align-items:stretch;min-height:0;display:flex;position:relative}.F1KBNa_fileListFloat{z-index:40;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv2);border-radius:12px;flex-direction:column;padding:6px 8px 10px;display:flex;position:absolute;overflow:hidden}.F1KBNa_fileList{box-sizing:border-box;border-right:1px solid var(--dsw-alias-border-l2);flex-direction:column;flex:none;width:240px;min-height:0;padding:4px 8px 12px;display:flex}.F1KBNa_listScroll{flex:1;min-height:0;overflow-y:auto}.F1KBNa_bulkActions{flex:none;gap:6px;padding-top:8px;display:flex}.F1KBNa_bulkActions .F1KBNa_action{text-align:center;flex:1}.F1KBNa_resizeHandle{cursor:col-resize;background:0 0;flex:none;width:5px;margin:0 -2px}.F1KBNa_resizeHandle:hover{background:var(--dsw-alias-border-l2)}.F1KBNa_detail{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.F1KBNa_detailEmpty{color:var(--dsw-alias-label-tertiary);text-align:center;flex:1;justify-content:center;align-items:center;margin:0;padding:24px;font-size:12px;line-height:18px;display:flex}.F1KBNa_confirmBackdrop{z-index:5;background:color-mix(in srgb, var(--dsw-alias-bg-base) 55%, transparent);justify-content:center;align-items:center;padding:24px;display:flex;position:absolute;inset:0}.F1KBNa_confirmCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);max-width:340px;box-shadow:var(--dsw-shadow-lv3);border-radius:12px;flex-direction:column;gap:12px;padding:16px;display:flex}.F1KBNa_confirmText{font:var(--dsw-font-caption);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0;line-height:1.5}.F1KBNa_confirmActions{justify-content:flex-end;gap:8px;display:flex}.F1KBNa_title{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}.F1KBNa_note,.F1KBNa_readError,.F1KBNa_hint{color:var(--dsw-alias-label-tertiary);margin:4px 0;font-size:12px;line-height:18px}.F1KBNa_noteCentered{text-align:center;margin:auto}.F1KBNa_emptyState{flex-direction:column;align-items:center;gap:10px;margin:auto;display:flex}.F1KBNa_importButton{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:5px 14px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_importButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_importButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_importNote{color:var(--dsw-alias-label-tertiary);text-align:center;margin:0;font-size:12px;line-height:18px}.F1KBNa_readError{color:var(--dsw-alias-state-error-primary)}.F1KBNa_group{color:var(--dsw-alias-label-tertiary);margin:8px 0 4px;font-size:12px;font-weight:500;line-height:16px}.F1KBNa_rows{margin:0;padding:0;list-style:none}.F1KBNa_row{border:1px solid #0000;border-radius:10px;margin:2px 0}.F1KBNa_rowHead{width:100%;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;align-items:baseline;gap:8px;padding:6px 8px;display:flex}.F1KBNa_rowHead:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_rowHead[data-selected]{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_rowPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-markdown-code-block);overflow:hidden}.F1KBNa_kindTag{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_kindHint{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:16px}.F1KBNa_divergedHint,.F1KBNa_missingHint{border-bottom:1px solid var(--dsw-alias-border-l2);margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missing{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary));white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_rowFailed{border:1px solid var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_actionError{border-bottom:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missingHint{color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary))}.F1KBNa_rowMeta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;gap:6px;margin-left:auto;font-size:12px;line-height:16px;display:inline-flex}.F1KBNa_addCount{color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 60%, var(--dsw-alias-label-primary))}.F1KBNa_delCount{color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 60%, var(--dsw-alias-label-primary))}.F1KBNa_diff{background:var(--dsw-alias-markdown-code-block);flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_diffHeader{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffPath{white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code-block);-webkit-user-select:text;user-select:text;flex:1;font-size:12px;line-height:18px;overflow:auto hidden}.F1KBNa_diffActions{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffStats{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:16px}.F1KBNa_flexSpacer{flex:1}.F1KBNa_divider{background:var(--dsw-alias-border-l1);align-self:stretch;width:1px;margin:2px 0}.F1KBNa_action{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_action:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_actionPrimary{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_actionPrimary:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_actionPrimary:disabled{background:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:.55}.F1KBNa_actionQuietDisabled:disabled{cursor:pointer;color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l1);background:0 0}.F1KBNa_actionPrimary.F1KBNa_actionQuietDisabled:disabled{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:1}.F1KBNa_iconAction{justify-content:center;align-items:center;min-height:25px;padding:4px 6px;display:inline-flex}.F1KBNa_close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expand{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_expand:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expandExpanded svg{transform:rotate(180deg)}.F1KBNa_diffBodyWrap{flex:1;min-height:0;display:flex;position:relative}.F1KBNa_diffBody{min-width:0;font:var(--dsw-font-markdown-code-block);-webkit-text-size-adjust:100%;text-size-adjust:100%;cursor:text;outline:none;flex:1;padding:0;position:relative;overflow:auto}.F1KBNa_diffBody::-webkit-scrollbar,.F1KBNa_diffBody::-webkit-scrollbar-track,.F1KBNa_diffBody::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_blockActions{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);z-index:2;border-radius:10px;align-items:center;gap:9px;padding:5px;display:flex;position:absolute;right:8px}.F1KBNa_blockPosition{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;margin-top:1px;margin-left:7px;font-size:12px;line-height:16px}.F1KBNa_searchBar{z-index:3;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);border-radius:10px;align-items:center;gap:4px;padding:4px;display:flex;position:absolute;top:8px;right:8px}.F1KBNa_searchInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);width:150px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:3px 8px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_searchInput:focus{border-color:var(--dsw-alias-state-business-primary)}.F1KBNa_searchCount{text-align:center;min-width:34px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:16px}.F1KBNa_searchMatch{background-color:#facc1542;border-radius:2px}.F1KBNa_searchMatchCurrent{background-color:#facc1599;border-radius:2px}.F1KBNa_blockFlash{z-index:1;box-sizing:border-box;border:2px solid var(--dsw-alias-state-business-primary);pointer-events:none;border-radius:4px;animation:1s ease-out forwards F1KBNa_diffFlashFade;position:absolute;left:0;right:0}.F1KBNa_blockFlashShake{animation:.7s ease-out forwards F1KBNa_diffFlashShake}@keyframes F1KBNa_diffFlashFade{0%{opacity:1}to{opacity:0}}@keyframes F1KBNa_diffFlashShake{0%{opacity:1;transform:translateY(0)}10%{transform:translateY(1px)}20%{transform:translateY(-1px)}30%{transform:translateY(1px)}40%{transform:translateY(-1px)}50%{transform:translateY(1px)}60%{transform:translateY(-1px)}70%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(0)}}.F1KBNa_overviewRuler{pointer-events:none;opacity:.5;width:4px;position:absolute;top:0;bottom:0;right:0}.F1KBNa_overviewMarker{border-radius:2px;width:100%;min-height:2px;position:absolute;right:0}.F1KBNa_markerDel{background-color:var(--dsw-alias-state-error-primary)}.F1KBNa_markerAdd{background-color:var(--dsw-alias-state-success-primary)}.F1KBNa_lines{border-spacing:0;width:max-content;min-width:100%;display:table}.F1KBNa_line{-webkit-user-select:none;user-select:none;height:22px;line-height:22px;display:table-row}.F1KBNa_vSpacer{display:table-row}.F1KBNa_gutter{box-sizing:border-box;text-align:right;width:44px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;-webkit-user-select:none;user-select:none;cursor:default;padding-right:10px;display:table-cell}.F1KBNa_code{white-space:pre;-webkit-user-select:text;user-select:text;display:table-cell}.F1KBNa_context{color:var(--dsw-alias-label-primary)}.F1KBNa_del{background-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.F1KBNa_add{background-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent)}.F1KBNa_statusBar{box-sizing:border-box;border-top:1px solid var(--dsw-alias-border-l2);height:34px;color:var(--dsw-alias-label-tertiary);font-family:var(--dsw-font-markdown-code-block);font-variant-numeric:tabular-nums;flex:none;align-items:center;gap:8px;padding:0 8px;font-size:12px;line-height:18px;display:flex}.F1KBNa_statusAction{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_statusAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langSelect{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;flex:none;align-items:center;gap:4px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_langSelect:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langLabel{text-overflow:ellipsis;white-space:nowrap;max-width:140px;overflow:hidden}.F1KBNa_notice{z-index:60;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);max-width:360px;box-shadow:var(--dsw-shadow-lv3);border-radius:10px;align-items:flex-start;gap:12px;padding:12px 14px;display:flex;position:fixed;bottom:24px;right:24px}.F1KBNa_noticeText{font:var(--dsw-font-caption);color:var(--dsw-alias-label-primary);flex:1;margin:0;line-height:1.45}.F1KBNa_noticeButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);font:var(--dsw-font-caption);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px}.F1KBNa_noticeButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_wrap .F1KBNa_line{height:auto;min-height:22px}.F1KBNa_subline{white-space:pre;height:22px;line-height:22px;display:block;overflow:hidden}.F1KBNa_wrapActive{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_wrapActive:hover{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_splitRoot{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.F1KBNa_diffBodySplit{flex:1;min-height:0;overflow-x:hidden}.F1KBNa_splitCols{width:100%;min-width:0;display:flex}.F1KBNa_splitCol{box-sizing:border-box;flex:1 1 0;min-width:0;overflow:hidden}.F1KBNa_splitDivider{background:var(--dsw-alias-border-l2);flex:0 0 1px}.F1KBNa_splitCol .F1KBNa_gutter,.F1KBNa_splitCol .F1KBNa_code{vertical-align:top}.F1KBNa_splitHScrollRow{border-top:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;width:100%;min-width:0;display:flex}.F1KBNa_splitHScroll{flex:1 1 0;min-width:0;height:15px;overflow:auto hidden}.F1KBNa_splitHScroll::-webkit-scrollbar{height:15px}.F1KBNa_splitHScroll::-webkit-scrollbar-track{cursor:default}.F1KBNa_splitHScroll::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_splitHScrollFill{height:1px}.F1KBNa_splitLdel{background-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.F1KBNa_splitLadd{background-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent)}.F1KBNa_splitRdel{background-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.F1KBNa_splitRadd{background-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent)}.F1KBNa_intraDel{background-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 26%, transparent);text-decoration:line-through}.F1KBNa_intraAdd{background-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 24%, transparent)}";
12623
+ const css = ".F1KBNa_layer{box-sizing:border-box;flex:none;align-items:center;width:calc(100% + 4px);height:42px;margin:4px -2px;display:flex;position:relative}.F1KBNa_footerButtons{align-items:center;width:100%;display:flex}.F1KBNa_badge{box-sizing:border-box;width:100%;height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.F1KBNa_badge:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_badge[data-active]{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_badge:disabled{color:var(--dsw-alias-label-tertiary);cursor:default;background:0 0}.F1KBNa_badgeLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.F1KBNa_badgeCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto;font-size:12px;line-height:16px}.F1KBNa_layer.F1KBNa_rail{width:36px;height:36px;margin:8px 0 10px}.F1KBNa_rail .F1KBNa_badge{border-radius:50%;justify-content:center;gap:0;width:36px;height:36px;padding:0}.F1KBNa_rail .F1KBNa_badgeLabel{display:none}.F1KBNa_rail .F1KBNa_badgeCount{box-sizing:border-box;background:var(--dsw-alias-state-business-primary);min-width:18px;height:18px;color:var(--dsw-alias-label-primary-foreground);font-variant-numeric:tabular-nums;border-radius:9px;justify-content:center;align-items:center;padding:0 4px;font-size:11px;line-height:18px;display:flex;position:absolute;top:-3px;right:-7px}.F1KBNa_fullscreenBackdrop{z-index:29;background:var(--dsw-specific-sidebar-fill);position:fixed;inset:0}.F1KBNa_panel{z-index:30;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:none;box-shadow:var(--dsw-shadow-lv2);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex-direction:column;display:flex;position:fixed;inset:8px 8px 128px;overflow:hidden}.F1KBNa_header{box-sizing:border-box;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:10px 12px;display:flex}.F1KBNa_headerActions{align-items:center;gap:2px;display:flex}.F1KBNa_settingsPage{padding:8px 12px}.F1KBNa_settingsGroup{border-bottom:1px solid var(--dsw-alias-border-l2);margin-top:8px}.F1KBNa_settingsGroupHeader{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:8px;padding:12px 0;display:flex}.F1KBNa_settingsGroupText{text-align:left;flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.F1KBNa_settingsGroupTitle{font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsGroupDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.F1KBNa_settingsGroupChevron{margin-left:auto;transition:transform .15s}.F1KBNa_settingsGroup[data-open] .F1KBNa_settingsGroupChevron{transform:rotate(180deg)}.F1KBNa_settingsGroup[data-open] .F1KBNa_settingsGroupHeader{border-bottom:1px solid var(--dsw-alias-border-l2)}.F1KBNa_settingsGroupBody{flex-direction:column;display:flex}.F1KBNa_settingsGroupBody .F1KBNa_settingsRow{padding-left:16px}.F1KBNa_settingsGroupBody .F1KBNa_settingsRow:last-child,.F1KBNa_settingsPage>.F1KBNa_settingsRow:last-child{border-bottom:none}.F1KBNa_settingsRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.F1KBNa_settingsRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.F1KBNa_settingsRowTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsRowDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.F1KBNa_settingsSelector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.F1KBNa_settingsSelector:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_settingsSelectorChevron{flex:none}.F1KBNa_colorPicker{position:relative}.F1KBNa_colorPickerTrigger{background:var(--dsw-alias-bg-module-platform);width:120px;height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:8px;padding:0 8px;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_colorPickerTrigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_colorSwatch{border:1px solid var(--dsw-alias-border-l2);border-radius:50%;flex:none;width:24px;height:24px}.F1KBNa_colorValue{text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums;flex:1;min-width:0;overflow:hidden}.F1KBNa_colorPickerChevron{flex:none}.F1KBNa_colorBackdrop{z-index:40;position:fixed;inset:0}.F1KBNa_colorPickerPopover{z-index:41;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv2);border-radius:10px;padding:10px;position:absolute;top:calc(100% + 6px);right:0}.F1KBNa_colorPickerPanel{flex-direction:column;gap:8px;display:flex}.F1KBNa_colorPickerInputRow{align-items:center;gap:8px;display:flex}.F1KBNa_colorPickerPreview{border:1px solid var(--dsw-alias-border-l2);border-radius:6px;flex:none;width:22px;height:22px}.F1KBNa_colorPickerInput{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-module-platform);min-width:0;height:30px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;flex:1;padding:0 8px;font-size:12px;line-height:28px}.F1KBNa_colorPickerInput:focus{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-1px}.F1KBNa_colorSv{border:1px solid var(--dsw-alias-border-l1);cursor:crosshair;touch-action:none;border-radius:8px;height:140px;position:relative}.F1KBNa_colorSvCursor{pointer-events:none;border:2px solid #fff;border-radius:50%;width:14px;height:14px;position:absolute;transform:translate(-50%,-50%);box-shadow:0 0 0 1px #00000080}.F1KBNa_colorHue{border:1px solid var(--dsw-alias-border-l1);cursor:pointer;touch-action:none;border-radius:7px;height:14px;position:relative}.F1KBNa_colorHueCursor{pointer-events:none;border:2px solid #fff;border-radius:50%;width:16px;height:16px;position:absolute;top:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 1px #00000080}.F1KBNa_diffPreview{z-index:2;border:1px solid var(--dsw-alias-border-l1);font:var(--dsw-font-markdown-code-block);background:var(--dsw-alias-markdown-code-block);border-radius:8px;margin-bottom:8px;padding:8px;position:sticky;top:0;overflow:hidden}.F1KBNa_diffPreviewTitle{color:var(--dsw-alias-label-tertiary);margin-bottom:6px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_diffPreviewScroll{height:132px;overflow-y:auto}.F1KBNa_toggle{border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:18px;flex:none;width:60px;height:36px;padding:0;position:relative}.F1KBNa_toggle:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_toggle:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.F1KBNa_toggleOn{border-color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-state-business-primary)}.F1KBNa_toggleOn:hover{background:var(--dsw-alias-state-business-primary)}.F1KBNa_toggleThumb{background:var(--dsw-alias-label-primary);border-radius:50%;width:28px;height:28px;transition:left .12s;position:absolute;top:3px;left:3px}.F1KBNa_toggleOn .F1KBNa_toggleThumb{background:#fff;left:27px}.F1KBNa_stepper{align-items:center;gap:6px;display:inline-flex}.F1KBNa_stepperButton{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-module-platform);width:32px;height:32px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:8px;padding:0;position:relative}.F1KBNa_stepperButton:before,.F1KBNa_stepperButton:after{content:\"\";background:currentColor;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.F1KBNa_stepperButton:before{width:10px;height:1px}.F1KBNa_stepperButton:after{width:1px;height:10px;display:none}.F1KBNa_stepperButtonUp:after{display:block}.F1KBNa_stepperButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_stepperButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_stepperValue{text-align:center;min-width:2ch;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:14px;line-height:22px}.F1KBNa_states{flex-direction:column;flex:1;min-height:0;padding:4px 12px 12px;display:flex;overflow-y:auto}.F1KBNa_split{flex:1;align-items:stretch;min-height:0;display:flex;position:relative}.F1KBNa_fileListFloat{z-index:40;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv2);border-radius:12px;flex-direction:column;padding:6px 8px 10px;display:flex;position:absolute;overflow:hidden}.F1KBNa_fileList{box-sizing:border-box;border-right:1px solid var(--dsw-alias-border-l2);flex-direction:column;flex:none;width:240px;min-height:0;padding:4px 8px 12px;display:flex}.F1KBNa_listScroll{flex:1;min-height:0;overflow-y:auto}.F1KBNa_bulkActions{flex:none;gap:6px;padding-top:8px;display:flex}.F1KBNa_bulkActions .F1KBNa_action{text-align:center;flex:1}.F1KBNa_resizeHandle{cursor:col-resize;background:0 0;flex:none;width:5px;margin:0 -2px}.F1KBNa_resizeHandle:hover{background:var(--dsw-alias-border-l2)}.F1KBNa_detail{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.F1KBNa_detailEmpty{color:var(--dsw-alias-label-tertiary);text-align:center;flex:1;justify-content:center;align-items:center;margin:0;padding:24px;font-size:12px;line-height:18px;display:flex}.F1KBNa_confirmBackdrop{z-index:5;background:color-mix(in srgb, var(--dsw-alias-bg-base) 55%, transparent);justify-content:center;align-items:center;padding:24px;display:flex;position:absolute;inset:0}.F1KBNa_confirmCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);max-width:340px;box-shadow:var(--dsw-shadow-lv3);border-radius:12px;flex-direction:column;gap:12px;padding:16px;display:flex}.F1KBNa_confirmText{font:var(--dsw-font-caption);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;margin:0;line-height:1.5}.F1KBNa_confirmActions{justify-content:flex-end;gap:8px;display:flex}.F1KBNa_title{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}.F1KBNa_note,.F1KBNa_readError,.F1KBNa_hint{color:var(--dsw-alias-label-tertiary);margin:4px 0;font-size:12px;line-height:18px}.F1KBNa_noteCentered{text-align:center;margin:auto}.F1KBNa_emptyState{flex-direction:column;align-items:center;gap:10px;margin:auto;display:flex}.F1KBNa_importButton{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:5px 14px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_importButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_importButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_importNote{color:var(--dsw-alias-label-tertiary);text-align:center;margin:0;font-size:12px;line-height:18px}.F1KBNa_readError{color:var(--dsw-alias-state-error-primary)}.F1KBNa_group{color:var(--dsw-alias-label-tertiary);margin:8px 0 4px;font-size:12px;font-weight:500;line-height:16px}.F1KBNa_rows{margin:0;padding:0;list-style:none}.F1KBNa_row{border:1px solid #0000;border-radius:10px;margin:2px 0}.F1KBNa_rowHead{width:100%;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;align-items:baseline;gap:8px;padding:6px 8px;display:flex}.F1KBNa_rowHead:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_rowHead[data-selected]{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_rowPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-markdown-code-block);overflow:hidden}.F1KBNa_kindTag{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_kindHint{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:16px}.F1KBNa_divergedHint,.F1KBNa_missingHint{border-bottom:1px solid var(--dsw-alias-border-l2);margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missing{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary));white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_rowFailed{border:1px solid var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_actionError{border-bottom:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missingHint{color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary))}.F1KBNa_rowMeta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;gap:6px;margin-left:auto;font-size:12px;line-height:16px;display:inline-flex}.F1KBNa_addCount{color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 60%, var(--dsw-alias-label-primary))}.F1KBNa_delCount{color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 60%, var(--dsw-alias-label-primary))}.F1KBNa_diff{background:var(--dsw-alias-markdown-code-block);flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_diffHeader{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffPath{white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code-block);-webkit-user-select:text;user-select:text;flex:1;font-size:12px;line-height:18px;overflow:auto hidden}.F1KBNa_diffActions{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffStats{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:16px}.F1KBNa_flexSpacer{flex:1}.F1KBNa_divider{background:var(--dsw-alias-border-l1);align-self:stretch;width:1px;margin:2px 0}.F1KBNa_action{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_action:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_actionPrimary{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_actionPrimary:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_actionPrimary:disabled{background:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:.55}.F1KBNa_actionQuietDisabled:disabled{cursor:pointer;color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l1);background:0 0}.F1KBNa_actionPrimary.F1KBNa_actionQuietDisabled:disabled{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:1}.F1KBNa_iconAction{justify-content:center;align-items:center;min-height:25px;padding:4px 6px;display:inline-flex}.F1KBNa_close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expand{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_expand:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expandExpanded svg{transform:rotate(180deg)}.F1KBNa_diffBodyWrap{flex:1;min-height:0;display:flex;position:relative}.F1KBNa_diffBody{min-width:0;font:var(--dsw-font-markdown-code-block);-webkit-text-size-adjust:100%;text-size-adjust:100%;cursor:text;outline:none;flex:1;padding:0;position:relative;overflow:auto}.F1KBNa_diffBody::-webkit-scrollbar,.F1KBNa_diffBody::-webkit-scrollbar-track,.F1KBNa_diffBody::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_blockActions{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);z-index:2;border-radius:10px;align-items:center;gap:9px;padding:5px;display:flex;position:absolute;right:8px}.F1KBNa_blockPosition{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;margin-top:1px;margin-left:7px;font-size:12px;line-height:16px}.F1KBNa_searchBar{z-index:3;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);border-radius:10px;align-items:center;gap:4px;padding:4px;display:flex;position:absolute;top:8px;right:8px}.F1KBNa_searchInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);width:150px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:3px 8px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_searchInput:focus{border-color:var(--dsw-alias-state-business-primary)}.F1KBNa_searchCount{text-align:center;min-width:34px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:16px}.F1KBNa_searchMatch{background-color:#facc1542;border-radius:2px}.F1KBNa_searchMatchCurrent{background-color:#facc1599;border-radius:2px}.F1KBNa_blockFlash{z-index:1;box-sizing:border-box;border:2px solid var(--dsw-alias-state-business-primary);pointer-events:none;border-radius:4px;animation:1s ease-out forwards F1KBNa_diffFlashFade;position:absolute;left:0;right:0}.F1KBNa_blockFlashShake{animation:.7s ease-out forwards F1KBNa_diffFlashShake}@keyframes F1KBNa_diffFlashFade{0%{opacity:1}to{opacity:0}}@keyframes F1KBNa_diffFlashShake{0%{opacity:1;transform:translateY(0)}10%{transform:translateY(1px)}20%{transform:translateY(-1px)}30%{transform:translateY(1px)}40%{transform:translateY(-1px)}50%{transform:translateY(1px)}60%{transform:translateY(-1px)}70%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(0)}}.F1KBNa_overviewRuler{pointer-events:none;opacity:.5;width:4px;position:absolute;top:0;bottom:0;right:0}.F1KBNa_overviewMarker{border-radius:2px;width:100%;min-height:2px;position:absolute;right:0}.F1KBNa_markerDel{background-color:var(--dsw-alias-state-error-primary)}.F1KBNa_markerAdd{background-color:var(--dsw-alias-state-success-primary)}.F1KBNa_lines{border-spacing:0;width:max-content;min-width:100%;font-size:calc(1em * var(--dsh-diff-font-scale,1));display:table}.F1KBNa_line{height:var(--dsh-diff-line-height,22px);line-height:var(--dsh-diff-line-height,22px);-webkit-user-select:none;user-select:none;display:table-row}.F1KBNa_vSpacer{display:table-row}.F1KBNa_gutter{box-sizing:border-box;text-align:right;width:44px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;-webkit-user-select:none;user-select:none;cursor:default;padding-right:10px;display:table-cell}.F1KBNa_code{white-space:pre;-webkit-user-select:text;user-select:text;display:table-cell}.F1KBNa_context{color:var(--dsw-alias-label-primary)}.F1KBNa_del{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_add{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_statusBar{box-sizing:border-box;border-top:1px solid var(--dsw-alias-border-l2);height:34px;color:var(--dsw-alias-label-tertiary);font-family:var(--dsw-font-markdown-code-block);font-variant-numeric:tabular-nums;flex:none;align-items:center;gap:8px;padding:0 8px;font-size:12px;line-height:18px;display:flex}.F1KBNa_statusAction{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_statusAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langSelect{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;flex:none;align-items:center;gap:4px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_langSelect:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langLabel{text-overflow:ellipsis;white-space:nowrap;max-width:140px;overflow:hidden}.F1KBNa_notice{z-index:60;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);max-width:360px;box-shadow:var(--dsw-shadow-lv3);border-radius:10px;align-items:flex-start;gap:12px;padding:12px 14px;display:flex;position:fixed;bottom:24px;right:24px}.F1KBNa_noticeText{font:var(--dsw-font-caption);color:var(--dsw-alias-label-primary);flex:1;margin:0;line-height:1.45}.F1KBNa_noticeButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);font:var(--dsw-font-caption);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px}.F1KBNa_noticeButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_wrap .F1KBNa_line{height:auto;min-height:var(--dsh-diff-line-height,22px)}.F1KBNa_subline{height:var(--dsh-diff-line-height,22px);line-height:var(--dsh-diff-line-height,22px);white-space:pre;display:block;overflow:hidden}.F1KBNa_wrapActive{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_wrapActive:hover{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_splitRoot{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.F1KBNa_diffBodySplit{flex:1;min-height:0;overflow-x:hidden}.F1KBNa_splitCols{width:100%;min-width:0;display:flex}.F1KBNa_splitCol{box-sizing:border-box;flex:1 1 0;min-width:0;overflow:hidden}.F1KBNa_splitDivider{background:var(--dsw-alias-border-l2);flex:0 0 1px}.F1KBNa_splitCol .F1KBNa_gutter,.F1KBNa_splitCol .F1KBNa_code{vertical-align:top}.F1KBNa_splitHScrollRow{border-top:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;width:100%;min-width:0;display:flex}.F1KBNa_splitHScroll{flex:1 1 0;min-width:0;height:15px;overflow:auto hidden}.F1KBNa_splitHScroll::-webkit-scrollbar{height:15px}.F1KBNa_splitHScroll::-webkit-scrollbar-track{cursor:default}.F1KBNa_splitHScroll::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_splitHScrollFill{height:1px}.F1KBNa_splitLdel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_splitLadd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_splitRdel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 12%, transparent)}.F1KBNa_splitRadd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 10%, transparent)}.F1KBNa_intraDel{background-color:color-mix(in srgb, var(--dsh-diff-del-color,var(--dsw-alias-state-error-primary)) 26%, transparent);text-decoration:line-through}.F1KBNa_intraAdd{background-color:color-mix(in srgb, var(--dsh-diff-add-color,var(--dsw-alias-state-success-primary)) 24%, transparent)}";
12554
12624
  const tagId = "dsh-diff-approval/PendingPanel.module.css";
12555
12625
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
12556
12626
  const tag = document.createElement("style");
@@ -12560,134 +12630,154 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12560
12630
  document.head.appendChild(tag);
12561
12631
  }
12562
12632
  var PendingPanel_module_css_default = {
12563
- "stepperButton": "F1KBNa_stepperButton",
12564
- "divergedHint": "F1KBNa_divergedHint",
12565
- "delCount": "F1KBNa_delCount",
12566
- "expandExpanded": "F1KBNa_expandExpanded",
12567
- "noticeButton": "F1KBNa_noticeButton",
12568
- "detail": "F1KBNa_detail",
12569
- "settingsRow": "F1KBNa_settingsRow",
12570
- "diffFlashFade": "F1KBNa_diffFlashFade",
12571
- "searchMatch": "F1KBNa_searchMatch",
12572
- "rail": "F1KBNa_rail",
12573
- "title": "F1KBNa_title",
12574
- "importNote": "F1KBNa_importNote",
12575
- "diffFlashShake": "F1KBNa_diffFlashShake",
12576
- "line": "F1KBNa_line",
12577
- "split": "F1KBNa_split",
12578
- "missing": "F1KBNa_missing",
12633
+ "confirmBackdrop": "F1KBNa_confirmBackdrop",
12634
+ "statusBar": "F1KBNa_statusBar",
12635
+ "layer": "F1KBNa_layer",
12636
+ "flexSpacer": "F1KBNa_flexSpacer",
12637
+ "fileListFloat": "F1KBNa_fileListFloat",
12579
12638
  "searchBar": "F1KBNa_searchBar",
12580
- "splitHScroll": "F1KBNa_splitHScroll",
12581
- "splitRadd": "F1KBNa_splitRadd",
12639
+ "splitHScrollRow": "F1KBNa_splitHScrollRow",
12640
+ "intraAdd": "F1KBNa_intraAdd",
12641
+ "settingsRowDesc": "F1KBNa_settingsRowDesc",
12642
+ "settingsRow": "F1KBNa_settingsRow",
12643
+ "toggleOn": "F1KBNa_toggleOn",
12582
12644
  "noteCentered": "F1KBNa_noteCentered",
12583
- "overviewRuler": "F1KBNa_overviewRuler",
12584
- "actionQuietDisabled": "F1KBNa_actionQuietDisabled",
12585
- "states": "F1KBNa_states",
12645
+ "colorPickerInput": "F1KBNa_colorPickerInput",
12646
+ "divider": "F1KBNa_divider",
12647
+ "del": "F1KBNa_del",
12648
+ "emptyState": "F1KBNa_emptyState",
12649
+ "settingsGroup": "F1KBNa_settingsGroup",
12650
+ "expand": "F1KBNa_expand",
12651
+ "diffFlashFade": "F1KBNa_diffFlashFade",
12586
12652
  "vSpacer": "F1KBNa_vSpacer",
12587
- "fullscreenBackdrop": "F1KBNa_fullscreenBackdrop",
12588
- "resizeHandle": "F1KBNa_resizeHandle",
12589
- "diffBodySplit": "F1KBNa_diffBodySplit",
12590
- "splitCol": "F1KBNa_splitCol",
12591
- "badge": "F1KBNa_badge",
12592
- "settingsGroupHeader": "F1KBNa_settingsGroupHeader",
12593
- "code": "F1KBNa_code",
12594
- "settingsGroupTitle": "F1KBNa_settingsGroupTitle",
12595
- "toggleOn": "F1KBNa_toggleOn",
12596
- "diffPath": "F1KBNa_diffPath",
12597
- "confirmText": "F1KBNa_confirmText",
12598
- "searchCount": "F1KBNa_searchCount",
12599
- "blockFlashShake": "F1KBNa_blockFlashShake",
12600
- "settingsSelectorChevron": "F1KBNa_settingsSelectorChevron",
12601
- "hint": "F1KBNa_hint",
12602
- "settingsGroupBody": "F1KBNa_settingsGroupBody",
12603
- "group": "F1KBNa_group",
12604
- "wrap": "F1KBNa_wrap",
12605
- "splitHScrollRow": "F1KBNa_splitHScrollRow",
12606
- "header": "F1KBNa_header",
12653
+ "settingsPage": "F1KBNa_settingsPage",
12654
+ "kindTag": "F1KBNa_kindTag",
12655
+ "splitRoot": "F1KBNa_splitRoot",
12656
+ "searchMatch": "F1KBNa_searchMatch",
12657
+ "rowMeta": "F1KBNa_rowMeta",
12658
+ "splitDivider": "F1KBNa_splitDivider",
12659
+ "colorSv": "F1KBNa_colorSv",
12607
12660
  "iconAction": "F1KBNa_iconAction",
12661
+ "blockPosition": "F1KBNa_blockPosition",
12662
+ "stepperValue": "F1KBNa_stepperValue",
12663
+ "kindHint": "F1KBNa_kindHint",
12664
+ "colorValue": "F1KBNa_colorValue",
12665
+ "toggle": "F1KBNa_toggle",
12666
+ "diffPreviewScroll": "F1KBNa_diffPreviewScroll",
12667
+ "row": "F1KBNa_row",
12608
12668
  "gutter": "F1KBNa_gutter",
12609
- "diffActions": "F1KBNa_diffActions",
12610
- "settingsPage": "F1KBNa_settingsPage",
12611
- "badgeCount": "F1KBNa_badgeCount",
12669
+ "actionPrimary": "F1KBNa_actionPrimary",
12670
+ "noticeButton": "F1KBNa_noticeButton",
12671
+ "wrapActive": "F1KBNa_wrapActive",
12672
+ "markerAdd": "F1KBNa_markerAdd",
12673
+ "stepperButton": "F1KBNa_stepperButton",
12674
+ "colorBackdrop": "F1KBNa_colorBackdrop",
12675
+ "wrap": "F1KBNa_wrap",
12676
+ "markerDel": "F1KBNa_markerDel",
12677
+ "actionError": "F1KBNa_actionError",
12678
+ "missingHint": "F1KBNa_missingHint",
12679
+ "settingsGroupTitle": "F1KBNa_settingsGroupTitle",
12680
+ "searchMatchCurrent": "F1KBNa_searchMatchCurrent",
12681
+ "addCount": "F1KBNa_addCount",
12682
+ "searchInput": "F1KBNa_searchInput",
12612
12683
  "footerButtons": "F1KBNa_footerButtons",
12684
+ "colorPickerPanel": "F1KBNa_colorPickerPanel",
12685
+ "rail": "F1KBNa_rail",
12686
+ "close": "F1KBNa_close",
12613
12687
  "noticeText": "F1KBNa_noticeText",
12614
- "detailEmpty": "F1KBNa_detailEmpty",
12615
- "divider": "F1KBNa_divider",
12616
- "searchMatchCurrent": "F1KBNa_searchMatchCurrent",
12617
- "splitLadd": "F1KBNa_splitLadd",
12618
- "actionError": "F1KBNa_actionError",
12619
- "expand": "F1KBNa_expand",
12620
- "blockPosition": "F1KBNa_blockPosition",
12621
- "splitHScrollFill": "F1KBNa_splitHScrollFill",
12622
- "badgeLabel": "F1KBNa_badgeLabel",
12623
- "stepper": "F1KBNa_stepper",
12624
- "statusBar": "F1KBNa_statusBar",
12625
- "markerDel": "F1KBNa_markerDel",
12626
12688
  "confirmCard": "F1KBNa_confirmCard",
12689
+ "intraDel": "F1KBNa_intraDel",
12690
+ "header": "F1KBNa_header",
12691
+ "settingsSelectorChevron": "F1KBNa_settingsSelectorChevron",
12627
12692
  "blockActions": "F1KBNa_blockActions",
12628
- "toggle": "F1KBNa_toggle",
12629
- "missingHint": "F1KBNa_missingHint",
12630
- "diffHeader": "F1KBNa_diffHeader",
12631
- "splitRdel": "F1KBNa_splitRdel",
12632
- "headerActions": "F1KBNa_headerActions",
12633
- "actionPrimary": "F1KBNa_actionPrimary",
12634
- "readError": "F1KBNa_readError",
12635
- "splitCols": "F1KBNa_splitCols",
12636
- "kindHint": "F1KBNa_kindHint",
12637
- "settingsRowText": "F1KBNa_settingsRowText",
12638
- "blockFlash": "F1KBNa_blockFlash",
12639
- "langSelect": "F1KBNa_langSelect",
12640
- "settingsGroup": "F1KBNa_settingsGroup",
12641
- "wrapActive": "F1KBNa_wrapActive",
12693
+ "splitHScroll": "F1KBNa_splitHScroll",
12694
+ "splitRadd": "F1KBNa_splitRadd",
12642
12695
  "rowFailed": "F1KBNa_rowFailed",
12643
- "del": "F1KBNa_del",
12644
- "kindTag": "F1KBNa_kindTag",
12645
- "diff": "F1KBNa_diff",
12646
- "searchInput": "F1KBNa_searchInput",
12647
- "lines": "F1KBNa_lines",
12648
- "stepperButtonUp": "F1KBNa_stepperButtonUp",
12649
- "confirmActions": "F1KBNa_confirmActions",
12650
- "listScroll": "F1KBNa_listScroll",
12651
- "notice": "F1KBNa_notice",
12652
- "panel": "F1KBNa_panel",
12653
- "rowHead": "F1KBNa_rowHead",
12696
+ "badge": "F1KBNa_badge",
12654
12697
  "settingsSelector": "F1KBNa_settingsSelector",
12655
- "note": "F1KBNa_note",
12656
- "row": "F1KBNa_row",
12657
- "markerAdd": "F1KBNa_markerAdd",
12658
- "intraAdd": "F1KBNa_intraAdd",
12659
- "importButton": "F1KBNa_importButton",
12660
- "overviewMarker": "F1KBNa_overviewMarker",
12698
+ "badgeCount": "F1KBNa_badgeCount",
12699
+ "readError": "F1KBNa_readError",
12700
+ "importNote": "F1KBNa_importNote",
12701
+ "statusAction": "F1KBNa_statusAction",
12702
+ "title": "F1KBNa_title",
12703
+ "notice": "F1KBNa_notice",
12661
12704
  "bulkActions": "F1KBNa_bulkActions",
12662
- "rowPath": "F1KBNa_rowPath",
12705
+ "blockFlash": "F1KBNa_blockFlash",
12706
+ "rowHead": "F1KBNa_rowHead",
12707
+ "colorSwatch": "F1KBNa_colorSwatch",
12708
+ "split": "F1KBNa_split",
12709
+ "panel": "F1KBNa_panel",
12663
12710
  "diffStats": "F1KBNa_diffStats",
12664
- "emptyState": "F1KBNa_emptyState",
12711
+ "detail": "F1KBNa_detail",
12712
+ "code": "F1KBNa_code",
12713
+ "settingsGroupChevron": "F1KBNa_settingsGroupChevron",
12714
+ "settingsRowText": "F1KBNa_settingsRowText",
12715
+ "actionQuietDisabled": "F1KBNa_actionQuietDisabled",
12716
+ "splitHScrollFill": "F1KBNa_splitHScrollFill",
12665
12717
  "toggleThumb": "F1KBNa_toggleThumb",
12666
- "stepperValue": "F1KBNa_stepperValue",
12667
- "settingsRowTitle": "F1KBNa_settingsRowTitle",
12668
- "diffBody": "F1KBNa_diffBody",
12669
- "subline": "F1KBNa_subline",
12670
- "addCount": "F1KBNa_addCount",
12671
- "layer": "F1KBNa_layer",
12672
- "intraDel": "F1KBNa_intraDel",
12673
- "langLabel": "F1KBNa_langLabel",
12674
- "statusAction": "F1KBNa_statusAction",
12675
- "action": "F1KBNa_action",
12676
- "settingsRowDesc": "F1KBNa_settingsRowDesc",
12677
- "rows": "F1KBNa_rows",
12678
- "splitRoot": "F1KBNa_splitRoot",
12679
- "splitDivider": "F1KBNa_splitDivider",
12680
- "confirmBackdrop": "F1KBNa_confirmBackdrop",
12718
+ "line": "F1KBNa_line",
12719
+ "detailEmpty": "F1KBNa_detailEmpty",
12720
+ "colorSvCursor": "F1KBNa_colorSvCursor",
12721
+ "splitCol": "F1KBNa_splitCol",
12722
+ "colorPickerTrigger": "F1KBNa_colorPickerTrigger",
12723
+ "confirmText": "F1KBNa_confirmText",
12724
+ "colorPickerChevron": "F1KBNa_colorPickerChevron",
12725
+ "fileList": "F1KBNa_fileList",
12726
+ "listScroll": "F1KBNa_listScroll",
12727
+ "confirmActions": "F1KBNa_confirmActions",
12728
+ "headerActions": "F1KBNa_headerActions",
12729
+ "importButton": "F1KBNa_importButton",
12730
+ "settingsGroupHeader": "F1KBNa_settingsGroupHeader",
12681
12731
  "diffBodyWrap": "F1KBNa_diffBodyWrap",
12732
+ "diffPreviewTitle": "F1KBNa_diffPreviewTitle",
12733
+ "note": "F1KBNa_note",
12734
+ "rows": "F1KBNa_rows",
12735
+ "diffHeader": "F1KBNa_diffHeader",
12736
+ "hint": "F1KBNa_hint",
12737
+ "fullscreenBackdrop": "F1KBNa_fullscreenBackdrop",
12738
+ "searchCount": "F1KBNa_searchCount",
12739
+ "splitRdel": "F1KBNa_splitRdel",
12740
+ "colorHueCursor": "F1KBNa_colorHueCursor",
12741
+ "lines": "F1KBNa_lines",
12742
+ "stepperButtonUp": "F1KBNa_stepperButtonUp",
12743
+ "delCount": "F1KBNa_delCount",
12744
+ "resizeHandle": "F1KBNa_resizeHandle",
12682
12745
  "splitLdel": "F1KBNa_splitLdel",
12746
+ "missing": "F1KBNa_missing",
12683
12747
  "add": "F1KBNa_add",
12684
- "fileList": "F1KBNa_fileList",
12685
- "fileListFloat": "F1KBNa_fileListFloat",
12686
- "flexSpacer": "F1KBNa_flexSpacer",
12687
- "rowMeta": "F1KBNa_rowMeta",
12688
- "settingsGroupChevron": "F1KBNa_settingsGroupChevron",
12748
+ "states": "F1KBNa_states",
12749
+ "colorPicker": "F1KBNa_colorPicker",
12750
+ "expandExpanded": "F1KBNa_expandExpanded",
12751
+ "diffFlashShake": "F1KBNa_diffFlashShake",
12752
+ "splitLadd": "F1KBNa_splitLadd",
12753
+ "subline": "F1KBNa_subline",
12754
+ "blockFlashShake": "F1KBNa_blockFlashShake",
12755
+ "langSelect": "F1KBNa_langSelect",
12756
+ "settingsGroupBody": "F1KBNa_settingsGroupBody",
12757
+ "colorPickerPreview": "F1KBNa_colorPickerPreview",
12758
+ "diffPreview": "F1KBNa_diffPreview",
12759
+ "rowPath": "F1KBNa_rowPath",
12760
+ "overviewMarker": "F1KBNa_overviewMarker",
12761
+ "colorPickerPopover": "F1KBNa_colorPickerPopover",
12762
+ "settingsRowTitle": "F1KBNa_settingsRowTitle",
12763
+ "badgeLabel": "F1KBNa_badgeLabel",
12764
+ "colorPickerInputRow": "F1KBNa_colorPickerInputRow",
12765
+ "colorHue": "F1KBNa_colorHue",
12766
+ "action": "F1KBNa_action",
12767
+ "group": "F1KBNa_group",
12768
+ "langLabel": "F1KBNa_langLabel",
12769
+ "diffBody": "F1KBNa_diffBody",
12770
+ "diffBodySplit": "F1KBNa_diffBodySplit",
12771
+ "divergedHint": "F1KBNa_divergedHint",
12772
+ "settingsGroupText": "F1KBNa_settingsGroupText",
12773
+ "diff": "F1KBNa_diff",
12774
+ "diffPath": "F1KBNa_diffPath",
12775
+ "settingsGroupDesc": "F1KBNa_settingsGroupDesc",
12776
+ "diffActions": "F1KBNa_diffActions",
12777
+ "stepper": "F1KBNa_stepper",
12778
+ "overviewRuler": "F1KBNa_overviewRuler",
12689
12779
  "context": "F1KBNa_context",
12690
- "close": "F1KBNa_close"
12780
+ "splitCols": "F1KBNa_splitCols"
12691
12781
  };
12692
12782
  //#endregion
12693
12783
  //#region lib/types/client/PendingPanel.js
@@ -12721,12 +12811,29 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
12721
12811
  const MAX_LIST_WIDTH_PX = 560;
12722
12812
  /** Inset of the floating file-list card from the code scroll box, in px. */
12723
12813
  const FLOAT_LIST_MARGIN_PX = 12;
12724
- /** Fixed diff-row height in px; the virtual window and jump math are built on it. */
12725
- const ROW_HEIGHT_PX = 22;
12726
- /** Tolerance absorbed when comparing a block's offset to the navigation anchor,
12727
- * so a sub-pixel float error (wrapped row heights, fractional scrollTop) never
12728
- * mis-classifies the block the view is sitting on. Half a row height. */
12729
- const NAV_ANCHOR_TOLERANCE_PX = ROW_HEIGHT_PX / 4;
12814
+ /** Normalize a path for comparison: forward slashes, no trailing slash. */
12815
+ function normalizeDiffPath(p) {
12816
+ return p.replaceAll("\\", "/").replace(/\/+$/, "");
12817
+ }
12818
+ /** Whether a produced-file chip path and a pending file path refer to the same
12819
+ * file, tolerant of separator style (\\ vs /) and of a workspace-relative vs
12820
+ * absolute form. `chipPath` is typically the harness's workspace-relative
12821
+ * forward-slash path; `filePath` is the host's absolute native-separator path.
12822
+ * Matching is case-insensitive so a Windows drive/segment case difference does
12823
+ * not miss the file the user clicked. */
12824
+ function diffPathsMatch(chipPath, filePath, workspacePath) {
12825
+ const toAbsolute = (p) => {
12826
+ const norm = normalizeDiffPath(p);
12827
+ if (/^[A-Za-z]:\//.test(norm) || norm.startsWith("/")) return norm;
12828
+ if (workspacePath !== void 0 && workspacePath !== "") return `${normalizeDiffPath(workspacePath).replace(/\/+$/, "")}/${norm}`;
12829
+ return norm;
12830
+ };
12831
+ const absolute = toAbsolute(chipPath).toLowerCase();
12832
+ const file = toAbsolute(filePath).toLowerCase();
12833
+ if (absolute === file) return true;
12834
+ const rel = normalizeDiffPath(chipPath).toLowerCase();
12835
+ return file === rel || file.endsWith(`/${rel}`);
12836
+ }
12730
12837
  /** The diff view-mode toggle glyph: the whole file as one column of text lines
12731
12838
  * (unified) or two side-by-side columns of text lines (split). Hand-drawn
12732
12839
  * because the icon library has no single/double-column glyph. Rendered 1:1
@@ -13251,6 +13358,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
13251
13358
  }
13252
13359
  /** The two-column (side-by-side) whole-file diff view. */
13253
13360
  const SplitDiff = (0, react.forwardRef)(function SplitDiff({ file, model, runs, langWrap, tabWidthSpaces, busy, t, selection, leadRows, onBlockKeep, onBlockRevert, onWrapToast }, ref) {
13361
+ const ROW_HEIGHT_PX = diffLineHeight();
13362
+ const NAV_ANCHOR_TOLERANCE_PX = ROW_HEIGHT_PX / 4;
13254
13363
  const { pairs, pairOfRow } = (0, react.useMemo)(() => computeSideBySideDiff(model.diff.rows, true), [model]);
13255
13364
  const pairCount = pairs.length;
13256
13365
  const pairRowIndices = (0, react.useMemo)(() => {
@@ -14082,6 +14191,17 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
14082
14191
  const [tabWidthSpaces] = (0, react.useState)(() => tabWidth());
14083
14192
  const [splitView, setSplitView] = (0, react.useState)(() => splitMode());
14084
14193
  const leadRows = navLeadRows();
14194
+ const diffFontScaleValue = diffFontScale();
14195
+ const diffLineHeightValue = diffLineHeight();
14196
+ const diffAddColorPx = diffAddColor();
14197
+ const diffDelColorPx = diffDelColor();
14198
+ const diffViewVars = {};
14199
+ diffViewVars["--dsh-diff-font-scale"] = String(diffFontScaleValue / 100);
14200
+ diffViewVars["--dsh-diff-line-height"] = `${diffLineHeightValue}px`;
14201
+ if (diffAddColorPx !== void 0) diffViewVars["--dsh-diff-add-color"] = diffAddColorPx;
14202
+ if (diffDelColorPx !== void 0) diffViewVars["--dsh-diff-del-color"] = diffDelColorPx;
14203
+ const ROW_HEIGHT_PX = diffLineHeightValue;
14204
+ const NAV_ANCHOR_TOLERANCE_PX = ROW_HEIGHT_PX / 4;
14085
14205
  const toggleSplitView = () => {
14086
14206
  const next = !splitView;
14087
14207
  setSplitView(next);
@@ -14697,6 +14817,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
14697
14817
  return (0, react_jsx_runtime.jsxs)("div", {
14698
14818
  className: PendingPanel_module_css_default.diff,
14699
14819
  "data-diff-approval-diff": true,
14820
+ style: diffViewVars,
14700
14821
  children: [
14701
14822
  (0, react_jsx_runtime.jsxs)("div", {
14702
14823
  className: PendingPanel_module_css_default.diffHeader,
@@ -15171,7 +15292,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15171
15292
  });
15172
15293
  }
15173
15294
  /** Render the pending-edit review panel and its unified footer action. */
15174
- function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPasteReference, onUndo, onRedo, onImportVcs, onAckRedoCleared, onAckJustResolved, collapseSidebar, t }) {
15295
+ function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPasteReference, onUndo, onRedo, onImportVcs, onAckRedoCleared, collapseSidebar, t }) {
15175
15296
  const current = useSessions((state) => state.current);
15176
15297
  const currentBlank = useSessions((state) => {
15177
15298
  const id = state.current;
@@ -15209,7 +15330,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15209
15330
  };
15210
15331
  const handleOpenFileRef = (0, react.useRef)();
15211
15332
  handleOpenFileRef.current = (path) => {
15212
- const entry = snapshot.files.find((file) => file.path === path);
15333
+ const entry = snapshot.files.find((file) => diffPathsMatch(path, file.path, snapshot.workspacePath));
15213
15334
  if (entry === void 0) {
15214
15335
  showCopyToast(t("panel.fileNotPending"));
15215
15336
  return;
@@ -15230,8 +15351,9 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15230
15351
  }, []);
15231
15352
  /** Whether the redo-cleared notice is showing (bottom-right, OK to dismiss). */
15232
15353
  const [redoClearedNotice, setRedoClearedNotice] = (0, react.useState)(false);
15233
- /** A file whose last block just resolved, pending a remove-or-keep choice. */
15234
- const [confirmDismiss, setConfirmDismiss] = (0, react.useState)(null);
15354
+ /** A last-block keep/revert awaiting the user's remove-or-keep choice; the
15355
+ * choice rides the same block RPC as its `removeWhenResolved` flag. */
15356
+ const [blockPrompt, setBlockPrompt] = (0, react.useState)(null);
15235
15357
  /** Bottom offset tracking the chat composer's top edge so the input stays visible. */
15236
15358
  const [bottomPx, setBottomPx] = (0, react.useState)(FALLBACK_BOTTOM_PX);
15237
15359
  /** Fullscreen expanded: the panel bottom pins to the window edge, ignoring the composer offset. */
@@ -15370,6 +15492,32 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15370
15492
  };
15371
15493
  }, [open]);
15372
15494
  const files = snapshot.files.filter((file) => current !== void 0 && (file.sessionIds ?? [file.sessionId]).includes(current)).sort((left, right) => compareFileNames(left.path, right.path));
15495
+ const blockKeepWithPrompt = (sessionId, id, block, removeWhenResolved) => {
15496
+ const file = files.find((entry) => entry.id === id);
15497
+ if (removeWhenResolved === void 0 && file !== void 0 && changeBlocksOf(computeWholeFileDiff(file.oldText, file.newText)).length === 1) {
15498
+ setBlockPrompt({
15499
+ action: "keep",
15500
+ sessionId,
15501
+ id,
15502
+ block
15503
+ });
15504
+ return Promise.resolve();
15505
+ }
15506
+ return removeWhenResolved === void 0 ? onBlockKeep(sessionId, id, block) : onBlockKeep(sessionId, id, block, removeWhenResolved);
15507
+ };
15508
+ const blockRevertWithPrompt = (sessionId, id, block, removeWhenResolved) => {
15509
+ const file = files.find((entry) => entry.id === id);
15510
+ if (removeWhenResolved === void 0 && file !== void 0 && changeBlocksOf(computeWholeFileDiff(file.oldText, file.newText)).length === 1) {
15511
+ setBlockPrompt({
15512
+ action: "revert",
15513
+ sessionId,
15514
+ id,
15515
+ block
15516
+ });
15517
+ return Promise.resolve();
15518
+ }
15519
+ return removeWhenResolved === void 0 ? onBlockRevert(sessionId, id, block) : onBlockRevert(sessionId, id, block, removeWhenResolved);
15520
+ };
15373
15521
  /** Per-file keep/revert failures, surfaced inline on the row and detail. */
15374
15522
  const failed = snapshot.failed ?? EMPTY_FAILED_MAP;
15375
15523
  const failedInitialized = (0, react.useRef)(false);
@@ -15386,16 +15534,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15386
15534
  if (fresh.length > 0) setActionToast(fresh[0][1]);
15387
15535
  failedRef.current = current;
15388
15536
  }, [snapshot.failed]);
15389
- (0, react.useEffect)(() => {
15390
- if (snapshot.justResolved === void 0) return;
15391
- setConfirmDismiss(snapshot.justResolved);
15392
- const timer = window.setTimeout(() => {
15393
- onAckJustResolved();
15394
- }, 0);
15395
- return () => {
15396
- window.clearTimeout(timer);
15397
- };
15398
- }, [snapshot.justResolved, onAckJustResolved]);
15399
15537
  (0, react.useEffect)(() => {
15400
15538
  if (!open) return;
15401
15539
  if (selected !== "" && files.some((file) => file.id === selected)) return;
@@ -15453,8 +15591,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15453
15591
  }
15454
15592
  }, entry.id);
15455
15593
  const selectedFile = files.find((file) => file.id === selected);
15456
- /** The file whose removal is being confirmed, if any. */
15457
- const confirmFile = confirmDismiss === null ? void 0 : files.find((file) => file.id === confirmDismiss);
15594
+ /** The file whose removal is being confirmed (a last-block action), if any. */
15595
+ const promptFile = blockPrompt === null ? void 0 : files.find((file) => file.id === blockPrompt.id);
15458
15596
  const fileListBody = (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("div", {
15459
15597
  className: PendingPanel_module_css_default.listScroll,
15460
15598
  children: files.length > 0 && (0, react_jsx_runtime.jsxs)("section", { children: [(0, react_jsx_runtime.jsx)("h3", {
@@ -15761,8 +15899,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15761
15899
  t,
15762
15900
  onKeep,
15763
15901
  onRevert,
15764
- onBlockKeep,
15765
- onBlockRevert,
15902
+ onBlockKeep: blockKeepWithPrompt,
15903
+ onBlockRevert: blockRevertWithPrompt,
15766
15904
  onOpen,
15767
15905
  floatMode,
15768
15906
  floatOpen,
@@ -15782,7 +15920,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15782
15920
  })
15783
15921
  ]
15784
15922
  }),
15785
- confirmFile !== void 0 && (0, react_jsx_runtime.jsx)("div", {
15923
+ blockPrompt !== null && promptFile !== void 0 && (0, react_jsx_runtime.jsx)("div", {
15786
15924
  className: PendingPanel_module_css_default.confirmBackdrop,
15787
15925
  "data-diff-confirm": true,
15788
15926
  children: (0, react_jsx_runtime.jsxs)("div", {
@@ -15791,7 +15929,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15791
15929
  "aria-modal": "true",
15792
15930
  children: [(0, react_jsx_runtime.jsx)("p", {
15793
15931
  className: PendingPanel_module_css_default.confirmText,
15794
- children: t("panel.resolvedAsk", { file: basenameOf(confirmFile.path) })
15932
+ children: t("panel.resolvedAsk", { file: basenameOf(promptFile.path) })
15795
15933
  }), (0, react_jsx_runtime.jsxs)("div", {
15796
15934
  className: PendingPanel_module_css_default.confirmActions,
15797
15935
  children: [(0, react_jsx_runtime.jsx)("button", {
@@ -15799,8 +15937,9 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15799
15937
  className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionPrimary}`,
15800
15938
  "data-diff-confirm-remove": true,
15801
15939
  onClick: () => {
15802
- setConfirmDismiss(null);
15803
- onKeep(confirmFile.sessionId, confirmFile.id);
15940
+ setBlockPrompt(null);
15941
+ const { action, sessionId, id, block } = blockPrompt;
15942
+ action === "keep" ? onBlockKeep(sessionId, id, block, true) : onBlockRevert(sessionId, id, block, true);
15804
15943
  },
15805
15944
  children: t("row.dismiss")
15806
15945
  }), (0, react_jsx_runtime.jsx)("button", {
@@ -15808,7 +15947,9 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15808
15947
  className: PendingPanel_module_css_default.action,
15809
15948
  "data-diff-confirm-keep": true,
15810
15949
  onClick: () => {
15811
- setConfirmDismiss(null);
15950
+ setBlockPrompt(null);
15951
+ const { action, sessionId, id, block } = blockPrompt;
15952
+ action === "keep" ? onBlockKeep(sessionId, id, block, false) : onBlockRevert(sessionId, id, block, false);
15812
15953
  },
15813
15954
  children: t("panel.keepInList")
15814
15955
  })]
@@ -15862,6 +16003,215 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15862
16003
  });
15863
16004
  }
15864
16005
  //#endregion
16006
+ //#region lib/types/client/ColorPicker.js
16007
+ /** A compact HSV color picker (saturation/value square + hue bar + hex/RGB
16008
+ * input). Avoids the browser-native color dialog, which cannot be themed, so
16009
+ * it matches DSH. Pure helpers are exported for testing. */
16010
+ /** Clamp `n` to `[min, max]`. */
16011
+ function clamp(n, min, max) {
16012
+ return Math.max(min, Math.min(max, n));
16013
+ }
16014
+ /** Parse `#rrggbb` / `#rgb` / `rrggbb` / `rgb(r,g,b)` into a normalised
16015
+ * `#rrggbb`, or `undefined` when the text is not a color. */
16016
+ function parseColor(input) {
16017
+ const text = input.trim();
16018
+ let m = /^#?([0-9a-f]{6})$/i.exec(text);
16019
+ if (m !== null) return `#${m[1].toLowerCase()}`;
16020
+ m = /^#?([0-9a-f]{3})$/i.exec(text);
16021
+ if (m !== null) return `#${m[1].split("").map((c) => c + c).join("").toLowerCase()}`;
16022
+ m = /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*[\d.]+\s*)?\)$/i.exec(text);
16023
+ if (m !== null) return `#${[
16024
+ Math.min(255, Number(m[1])),
16025
+ Math.min(255, Number(m[2])),
16026
+ Math.min(255, Number(m[3]))
16027
+ ].map((n) => n.toString(16).padStart(2, "0")).join("")}`;
16028
+ }
16029
+ /** Convert a `#rrggbb` hex to HSV (h 0-360, s 0-1, v 0-1). */
16030
+ function hexToHsv(hex) {
16031
+ const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());
16032
+ const int = m === null ? 2278750 : Number.parseInt(m[1], 16);
16033
+ const r = (int >> 16 & 255) / 255;
16034
+ const g = (int >> 8 & 255) / 255;
16035
+ const b = (int & 255) / 255;
16036
+ const max = Math.max(r, g, b);
16037
+ const d = max - Math.min(r, g, b);
16038
+ let h = 0;
16039
+ if (d !== 0) {
16040
+ if (max === r) h = (g - b) / d % 6;
16041
+ else if (max === g) h = (b - r) / d + 2;
16042
+ else h = (r - g) / d + 4;
16043
+ h *= 60;
16044
+ if (h < 0) h += 360;
16045
+ }
16046
+ const s = max === 0 ? 0 : d / max;
16047
+ return {
16048
+ h,
16049
+ s,
16050
+ v: max
16051
+ };
16052
+ }
16053
+ /** Convert HSV (h 0-360, s 0-1, v 0-1) to a `#rrggbb` hex. */
16054
+ function hsvToHex(h, s, v) {
16055
+ const c = v * s;
16056
+ const x = c * (1 - Math.abs((h % 360 + 360) % 360 / 60 % 2 - 1));
16057
+ const m = v - c;
16058
+ const hp = (h % 360 + 360) % 360;
16059
+ let r = 0;
16060
+ let g = 0;
16061
+ let b = 0;
16062
+ if (hp < 60) {
16063
+ r = c;
16064
+ g = x;
16065
+ b = 0;
16066
+ } else if (hp < 120) {
16067
+ r = x;
16068
+ g = c;
16069
+ b = 0;
16070
+ } else if (hp < 180) {
16071
+ r = 0;
16072
+ g = c;
16073
+ b = x;
16074
+ } else if (hp < 240) {
16075
+ r = 0;
16076
+ g = x;
16077
+ b = c;
16078
+ } else if (hp < 300) {
16079
+ r = x;
16080
+ g = 0;
16081
+ b = c;
16082
+ } else {
16083
+ r = c;
16084
+ g = 0;
16085
+ b = x;
16086
+ }
16087
+ const to8 = (n) => Math.round((n + m) * 255).toString(16).padStart(2, "0");
16088
+ return `#${to8(r)}${to8(g)}${to8(b)}`;
16089
+ }
16090
+ /** A draggable HSV picker: saturation/value square + hue bar + a hex/RGB text
16091
+ * input. `onChange` reports a normalised `#rrggbb`; `onClose` fires after a
16092
+ * committed text value so the caller can close the popover. */
16093
+ function ColorPicker({ value, onChange, onClose, ariaLabel }) {
16094
+ const [hsv, setHsv] = (0, react.useState)(() => hexToHsv(value));
16095
+ const [text, setText] = (0, react.useState)(() => value.toUpperCase());
16096
+ const svRef = (0, react.useRef)(null);
16097
+ const hueRef = (0, react.useRef)(null);
16098
+ (0, react.useEffect)(() => {
16099
+ setHsv(hexToHsv(value));
16100
+ setText(value.toUpperCase());
16101
+ }, [value]);
16102
+ const hueColor = `hsl(${hsv.h.toFixed(1)}, 100%, 50%)`;
16103
+ const commit = (next) => {
16104
+ const normalized = parseColor(next);
16105
+ if (normalized !== void 0 && normalized.toLowerCase() !== value.toLowerCase()) {
16106
+ onChange(normalized);
16107
+ onClose?.();
16108
+ }
16109
+ };
16110
+ const updateSv = (clientX, clientY) => {
16111
+ const el = svRef.current;
16112
+ if (el === null) return;
16113
+ const rect = el.getBoundingClientRect();
16114
+ const s = clamp((clientX - rect.left) / rect.width, 0, 1);
16115
+ const v = 1 - clamp((clientY - rect.top) / rect.height, 0, 1);
16116
+ const hex = hsvToHex(hsv.h, s, v);
16117
+ setHsv((prev) => ({
16118
+ h: prev.h,
16119
+ s,
16120
+ v
16121
+ }));
16122
+ setText(hex.toUpperCase());
16123
+ onChange(hex);
16124
+ };
16125
+ const updateHue = (clientX) => {
16126
+ const el = hueRef.current;
16127
+ if (el === null) return;
16128
+ const rect = el.getBoundingClientRect();
16129
+ const h = clamp((clientX - rect.left) / rect.width, 0, 1) * 360;
16130
+ const hex = hsvToHex(h, hsv.s, hsv.v);
16131
+ setHsv((prev) => ({
16132
+ h,
16133
+ s: prev.s,
16134
+ v: prev.v
16135
+ }));
16136
+ setText(hex.toUpperCase());
16137
+ onChange(hex);
16138
+ };
16139
+ const onSvPointerDown = (e) => {
16140
+ e.currentTarget.setPointerCapture?.(e.pointerId);
16141
+ updateSv(e.clientX, e.clientY);
16142
+ };
16143
+ const onSvPointerMove = (e) => {
16144
+ if (e.buttons > 0) updateSv(e.clientX, e.clientY);
16145
+ };
16146
+ const onHuePointerDown = (e) => {
16147
+ e.currentTarget.setPointerCapture?.(e.pointerId);
16148
+ updateHue(e.clientX);
16149
+ };
16150
+ const onHuePointerMove = (e) => {
16151
+ if (e.buttons > 0) updateHue(e.clientX);
16152
+ };
16153
+ return (0, react_jsx_runtime.jsxs)("div", {
16154
+ className: PendingPanel_module_css_default.colorPickerPanel,
16155
+ children: [
16156
+ (0, react_jsx_runtime.jsxs)("div", {
16157
+ className: PendingPanel_module_css_default.colorPickerInputRow,
16158
+ children: [(0, react_jsx_runtime.jsx)("span", {
16159
+ className: PendingPanel_module_css_default.colorPickerPreview,
16160
+ style: { background: value },
16161
+ "aria-hidden": "true"
16162
+ }), (0, react_jsx_runtime.jsx)("input", {
16163
+ className: PendingPanel_module_css_default.colorPickerInput,
16164
+ value: text,
16165
+ "aria-label": ariaLabel,
16166
+ "data-diff-color-input": true,
16167
+ onChange: (e) => {
16168
+ setText(e.target.value.toUpperCase());
16169
+ },
16170
+ onBlur: () => {
16171
+ commit(text);
16172
+ },
16173
+ onKeyDown: (e) => {
16174
+ if (e.key === "Enter") e.currentTarget.blur();
16175
+ }
16176
+ })]
16177
+ }),
16178
+ (0, react_jsx_runtime.jsx)("div", {
16179
+ className: PendingPanel_module_css_default.colorSv,
16180
+ ref: svRef,
16181
+ style: { background: `linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, ${hueColor})` },
16182
+ onPointerDown: onSvPointerDown,
16183
+ onPointerMove: onSvPointerMove,
16184
+ role: "slider",
16185
+ "aria-label": `${ariaLabel} color`,
16186
+ "aria-valuetext": value,
16187
+ children: (0, react_jsx_runtime.jsx)("span", {
16188
+ className: PendingPanel_module_css_default.colorSvCursor,
16189
+ style: {
16190
+ left: `${hsv.s * 100}%`,
16191
+ top: `${(1 - hsv.v) * 100}%`,
16192
+ background: value
16193
+ },
16194
+ "aria-hidden": "true"
16195
+ })
16196
+ }),
16197
+ (0, react_jsx_runtime.jsx)("div", {
16198
+ className: PendingPanel_module_css_default.colorHue,
16199
+ ref: hueRef,
16200
+ style: { background: "linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)" },
16201
+ onPointerDown: onHuePointerDown,
16202
+ onPointerMove: onHuePointerMove,
16203
+ role: "slider",
16204
+ "aria-label": `${ariaLabel} hue`,
16205
+ children: (0, react_jsx_runtime.jsx)("span", {
16206
+ className: PendingPanel_module_css_default.colorHueCursor,
16207
+ style: { left: `${hsv.h / 360 * 100}%` },
16208
+ "aria-hidden": "true"
16209
+ })
16210
+ })
16211
+ ]
16212
+ });
16213
+ }
16214
+ //#endregion
15865
16215
  //#region lib/types/client/SettingsTab.js
15866
16216
  /** DSH Settings top-level section for this plugin's preferences. */
15867
16217
  /** A toggle switch offering the two boolean states 打开 / 关闭. */
@@ -15961,8 +16311,10 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15961
16311
  })]
15962
16312
  });
15963
16313
  }
15964
- /** A +/- number stepper for an integer preference, clamped to [min, max]. */
15965
- function StepperRow({ title, description, value, onChange, min, max, dataAttribute, t }) {
16314
+ /** A +/- number stepper for an integer preference, clamped to [min, max]. The
16315
+ * optional `step` changes the increment (default 1) and `unit` is appended to
16316
+ * the shown value (e.g. '%'). */
16317
+ function StepperRow({ title, description, value, onChange, min, max, dataAttribute, t, step = 1, unit = "" }) {
15966
16318
  return (0, react_jsx_runtime.jsxs)("div", {
15967
16319
  className: PendingPanel_module_css_default.settingsRow,
15968
16320
  children: [(0, react_jsx_runtime.jsxs)("div", {
@@ -15984,13 +16336,13 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15984
16336
  "aria-label": t("action.decrease"),
15985
16337
  disabled: value <= min,
15986
16338
  onClick: () => {
15987
- onChange(Math.max(min, value - 1));
16339
+ onChange(Math.max(min, value - step));
15988
16340
  }
15989
16341
  }),
15990
- (0, react_jsx_runtime.jsx)("span", {
16342
+ (0, react_jsx_runtime.jsxs)("span", {
15991
16343
  className: PendingPanel_module_css_default.stepperValue,
15992
16344
  [dataAttribute]: true,
15993
- children: value
16345
+ children: [value, unit]
15994
16346
  }),
15995
16347
  (0, react_jsx_runtime.jsx)("button", {
15996
16348
  type: "button",
@@ -15999,7 +16351,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
15999
16351
  "aria-label": t("action.increase"),
16000
16352
  disabled: value >= max,
16001
16353
  onClick: () => {
16002
- onChange(Math.min(max, value + 1));
16354
+ onChange(Math.min(max, value + step));
16003
16355
  }
16004
16356
  })
16005
16357
  ]
@@ -16069,6 +16421,162 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16069
16421
  })]
16070
16422
  });
16071
16423
  }
16424
+ /** One color-picker row: title + description left, a DSH pill trigger that opens
16425
+ * a small HSV dial (a real color picker, not preset swatches) with a hex/RGB
16426
+ * input. The native color dialog is browser-styled and is avoided. */
16427
+ function ColorRow({ title, description, value, onChange, dataAttribute }) {
16428
+ const [open, setOpen] = (0, react.useState)(false);
16429
+ return (0, react_jsx_runtime.jsxs)("div", {
16430
+ className: PendingPanel_module_css_default.settingsRow,
16431
+ children: [(0, react_jsx_runtime.jsxs)("div", {
16432
+ className: PendingPanel_module_css_default.settingsRowText,
16433
+ children: [(0, react_jsx_runtime.jsx)("div", {
16434
+ className: PendingPanel_module_css_default.settingsRowTitle,
16435
+ children: title
16436
+ }), (0, react_jsx_runtime.jsx)("div", {
16437
+ className: PendingPanel_module_css_default.settingsRowDesc,
16438
+ children: description
16439
+ })]
16440
+ }), (0, react_jsx_runtime.jsxs)("div", {
16441
+ className: PendingPanel_module_css_default.colorPicker,
16442
+ children: [(0, react_jsx_runtime.jsxs)("button", {
16443
+ type: "button",
16444
+ className: PendingPanel_module_css_default.colorPickerTrigger,
16445
+ [dataAttribute]: true,
16446
+ "aria-haspopup": "dialog",
16447
+ "aria-expanded": open,
16448
+ "data-diff-color-trigger": true,
16449
+ onClick: () => {
16450
+ setOpen((value) => !value);
16451
+ },
16452
+ children: [
16453
+ (0, react_jsx_runtime.jsx)("span", {
16454
+ className: PendingPanel_module_css_default.colorSwatch,
16455
+ style: { background: value },
16456
+ "aria-hidden": "true"
16457
+ }),
16458
+ (0, react_jsx_runtime.jsx)("span", {
16459
+ className: PendingPanel_module_css_default.colorValue,
16460
+ children: value.toUpperCase()
16461
+ }),
16462
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: PendingPanel_module_css_default.colorPickerChevron })
16463
+ ]
16464
+ }), open && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("div", {
16465
+ className: PendingPanel_module_css_default.colorBackdrop,
16466
+ onClick: () => {
16467
+ setOpen(false);
16468
+ }
16469
+ }), (0, react_jsx_runtime.jsx)("div", {
16470
+ className: PendingPanel_module_css_default.colorPickerPopover,
16471
+ children: (0, react_jsx_runtime.jsx)(ColorPicker, {
16472
+ value,
16473
+ onChange,
16474
+ onClose: () => {
16475
+ setOpen(false);
16476
+ },
16477
+ ariaLabel: title
16478
+ })
16479
+ })] })]
16480
+ })]
16481
+ });
16482
+ }
16483
+ /** A live single-column diff preview driven by the current diff-view settings.
16484
+ * It reuses the real diff's CSS (`.line`/`.gutter`/`.code`/`.del`/`.add`/intra)
16485
+ * and applies the same CSS variables, so it reflects the actual look. */
16486
+ function DiffViewPreview({ fontScale, lineHeight, addColor, delColor, tabSize, t }) {
16487
+ const vars = {
16488
+ "--dsh-diff-font-scale": String(fontScale / 100),
16489
+ "--dsh-diff-line-height": `${lineHeight}px`,
16490
+ "--dsh-diff-add-color": addColor,
16491
+ "--dsh-diff-del-color": delColor
16492
+ };
16493
+ const rows = [
16494
+ {
16495
+ kind: PendingPanel_module_css_default.context,
16496
+ old: "1",
16497
+ next: "1",
16498
+ code: "export function review(file) {"
16499
+ },
16500
+ {
16501
+ kind: PendingPanel_module_css_default.context,
16502
+ old: "2",
16503
+ next: "2",
16504
+ code: " // 旧实现:保留当前改动"
16505
+ },
16506
+ {
16507
+ kind: PendingPanel_module_css_default.del,
16508
+ old: "3",
16509
+ next: "",
16510
+ code: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
16511
+ " return ",
16512
+ (0, react_jsx_runtime.jsx)("span", {
16513
+ className: PendingPanel_module_css_default.intraDel,
16514
+ children: "keep"
16515
+ }),
16516
+ "(file)"
16517
+ ] })
16518
+ },
16519
+ {
16520
+ kind: PendingPanel_module_css_default.context,
16521
+ old: "3",
16522
+ next: "3",
16523
+ code: " // 新实现:回退该改动"
16524
+ },
16525
+ {
16526
+ kind: PendingPanel_module_css_default.add,
16527
+ old: "",
16528
+ next: "3",
16529
+ code: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
16530
+ " return ",
16531
+ (0, react_jsx_runtime.jsx)("span", {
16532
+ className: PendingPanel_module_css_default.intraAdd,
16533
+ children: "revert"
16534
+ }),
16535
+ "(file)"
16536
+ ] })
16537
+ },
16538
+ {
16539
+ kind: PendingPanel_module_css_default.context,
16540
+ old: "4",
16541
+ next: "4",
16542
+ code: "}"
16543
+ }
16544
+ ];
16545
+ return (0, react_jsx_runtime.jsxs)("div", {
16546
+ className: PendingPanel_module_css_default.diffPreview,
16547
+ style: {
16548
+ ...vars,
16549
+ tabSize
16550
+ },
16551
+ "data-diff-view-preview": true,
16552
+ children: [(0, react_jsx_runtime.jsx)("div", {
16553
+ className: PendingPanel_module_css_default.diffPreviewTitle,
16554
+ children: t("settings.diffPreview")
16555
+ }), (0, react_jsx_runtime.jsx)("div", {
16556
+ className: PendingPanel_module_css_default.diffPreviewScroll,
16557
+ children: (0, react_jsx_runtime.jsx)("div", {
16558
+ className: PendingPanel_module_css_default.lines,
16559
+ children: rows.map((row, index) => (0, react_jsx_runtime.jsxs)("div", {
16560
+ className: `${PendingPanel_module_css_default.line} ${row.kind}`,
16561
+ children: [
16562
+ (0, react_jsx_runtime.jsx)("span", {
16563
+ className: PendingPanel_module_css_default.gutter,
16564
+ children: row.old
16565
+ }),
16566
+ (0, react_jsx_runtime.jsx)("span", {
16567
+ className: PendingPanel_module_css_default.gutter,
16568
+ children: row.next
16569
+ }),
16570
+ (0, react_jsx_runtime.jsx)("span", {
16571
+ className: PendingPanel_module_css_default.code,
16572
+ children: row.code
16573
+ })
16574
+ ]
16575
+ }, index))
16576
+ })
16577
+ })]
16578
+ });
16579
+ }
16072
16580
  /**
16073
16581
  * The plugin's preferences: auto-paste a copied reference into the input,
16074
16582
  * whether importing workspace VCS changes includes untracked files, and the
@@ -16083,6 +16591,13 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16083
16591
  const [tabOpen, setTabOpen] = (0, react.useState)(false);
16084
16592
  const [split, setSplitState] = (0, react.useState)(splitMode);
16085
16593
  const [lead, setLeadState] = (0, react.useState)(navLeadRows);
16594
+ const [fontScale, setFontScaleState] = (0, react.useState)(diffFontScale);
16595
+ const [lineHeight, setLineHeightState] = (0, react.useState)(diffLineHeight);
16596
+ const [addColor, setAddColorState] = (0, react.useState)(() => diffAddColor() ?? currentDiffAddColor());
16597
+ const [delColor, setDelColorState] = (0, react.useState)(() => diffDelColor() ?? currentDiffDelColor());
16598
+ const addDefault = currentDiffAddColor();
16599
+ const delDefault = currentDiffDelColor();
16600
+ const [diffOpen, setDiffOpen] = (0, react.useState)(true);
16086
16601
  const [summon, setSummonState] = (0, react.useState)(quickSummonKey);
16087
16602
  const [keysOpen, setKeysOpen] = (0, react.useState)(false);
16088
16603
  const [keybindings, setKeybindingsState] = (0, react.useState)(() => {
@@ -16121,10 +16636,131 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16121
16636
  setLeadState(value);
16122
16637
  setNavLeadRows(value);
16123
16638
  };
16639
+ const setFontScale = (value) => {
16640
+ setFontScaleState(value);
16641
+ setDiffFontScale(value);
16642
+ };
16643
+ const setLineHeight = (value) => {
16644
+ setLineHeightState(value);
16645
+ setDiffLineHeight(value);
16646
+ };
16647
+ const setAddColor = (value) => {
16648
+ setAddColorState(value);
16649
+ setDiffAddColor(value);
16650
+ };
16651
+ const setDelColor = (value) => {
16652
+ setDelColorState(value);
16653
+ setDiffDelColor(value);
16654
+ };
16124
16655
  return (0, react_jsx_runtime.jsxs)("div", {
16125
16656
  className: PendingPanel_module_css_default.settingsPage,
16126
16657
  "data-diff-settings": true,
16127
16658
  children: [
16659
+ (0, react_jsx_runtime.jsxs)("div", {
16660
+ className: PendingPanel_module_css_default.settingsGroup,
16661
+ "data-open": diffOpen || void 0,
16662
+ children: [(0, react_jsx_runtime.jsxs)("button", {
16663
+ type: "button",
16664
+ className: PendingPanel_module_css_default.settingsGroupHeader,
16665
+ onClick: () => {
16666
+ setDiffOpen((open) => !open);
16667
+ },
16668
+ "data-diff-view-toggle": true,
16669
+ children: [(0, react_jsx_runtime.jsxs)("span", {
16670
+ className: PendingPanel_module_css_default.settingsGroupText,
16671
+ children: [(0, react_jsx_runtime.jsx)("span", {
16672
+ className: PendingPanel_module_css_default.settingsGroupTitle,
16673
+ children: t("settings.diffView")
16674
+ }), (0, react_jsx_runtime.jsx)("span", {
16675
+ className: PendingPanel_module_css_default.settingsGroupDesc,
16676
+ children: t("settings.diffViewDesc")
16677
+ })]
16678
+ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: PendingPanel_module_css_default.settingsGroupChevron })]
16679
+ }), diffOpen && (0, react_jsx_runtime.jsxs)("div", {
16680
+ className: PendingPanel_module_css_default.settingsGroupBody,
16681
+ children: [
16682
+ (0, react_jsx_runtime.jsx)(DiffViewPreview, {
16683
+ fontScale,
16684
+ lineHeight,
16685
+ addColor,
16686
+ delColor,
16687
+ tabSize: tab,
16688
+ t
16689
+ }),
16690
+ (0, react_jsx_runtime.jsx)(StepperRow, {
16691
+ title: t("panel.diffFontSize"),
16692
+ description: t("panel.diffFontSizeDesc"),
16693
+ value: fontScale,
16694
+ onChange: setFontScale,
16695
+ min: 50,
16696
+ max: 200,
16697
+ step: 10,
16698
+ unit: "%",
16699
+ dataAttribute: "data-diff-font-size",
16700
+ t
16701
+ }),
16702
+ (0, react_jsx_runtime.jsx)(StepperRow, {
16703
+ title: t("panel.diffLineHeight"),
16704
+ description: t("panel.diffLineHeightDesc"),
16705
+ value: lineHeight,
16706
+ onChange: setLineHeight,
16707
+ min: 10,
16708
+ max: 36,
16709
+ dataAttribute: "data-diff-line-height",
16710
+ t
16711
+ }),
16712
+ (0, react_jsx_runtime.jsx)(ColorRow, {
16713
+ title: t("panel.diffAddColor"),
16714
+ description: t("panel.diffAddColorDesc", { default: addDefault.toUpperCase() }),
16715
+ value: addColor,
16716
+ onChange: setAddColor,
16717
+ dataAttribute: "data-diff-add-color"
16718
+ }),
16719
+ (0, react_jsx_runtime.jsx)(ColorRow, {
16720
+ title: t("panel.diffDelColor"),
16721
+ description: t("panel.diffDelColorDesc", { default: delDefault.toUpperCase() }),
16722
+ value: delColor,
16723
+ onChange: setDelColor,
16724
+ dataAttribute: "data-diff-del-color"
16725
+ }),
16726
+ (0, react_jsx_runtime.jsx)(TabWidthRow, {
16727
+ title: t("panel.tabWidth"),
16728
+ description: t("panel.tabWidthDesc"),
16729
+ value: tab,
16730
+ open: tabOpen,
16731
+ onOpenChange: setTabOpen,
16732
+ onSelect: setTab,
16733
+ dataAttribute: "data-diff-tab-width-select"
16734
+ }),
16735
+ (0, react_jsx_runtime.jsx)(PreferenceRow, {
16736
+ title: t("panel.splitMode"),
16737
+ description: t("panel.splitModeDesc"),
16738
+ value: split,
16739
+ onSelect: setSplit,
16740
+ dataAttribute: "data-diff-split-mode-select",
16741
+ t
16742
+ }),
16743
+ (0, react_jsx_runtime.jsx)(StepperRow, {
16744
+ title: t("panel.navLeadRows"),
16745
+ description: t("panel.navLeadRowsDesc"),
16746
+ value: lead,
16747
+ onChange: setLead,
16748
+ min: 0,
16749
+ max: 10,
16750
+ dataAttribute: "data-diff-nav-lead-rows",
16751
+ t
16752
+ }),
16753
+ (0, react_jsx_runtime.jsx)(PreferenceRow, {
16754
+ title: t("panel.pasteOnCopy"),
16755
+ description: t("panel.pasteOnCopyDesc"),
16756
+ value: pasteOnCopy,
16757
+ onSelect: setPasteOnCopy,
16758
+ dataAttribute: "data-diff-paste-on-copy-select",
16759
+ t
16760
+ })
16761
+ ]
16762
+ })]
16763
+ }),
16128
16764
  (0, react_jsx_runtime.jsxs)("div", {
16129
16765
  className: PendingPanel_module_css_default.settingsGroup,
16130
16766
  "data-open": keysOpen || void 0,
@@ -16135,9 +16771,15 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16135
16771
  setKeysOpen((open) => !open);
16136
16772
  },
16137
16773
  "data-diff-keybindings-toggle": true,
16138
- children: [(0, react_jsx_runtime.jsx)("span", {
16139
- className: PendingPanel_module_css_default.settingsGroupTitle,
16140
- children: t("settings.keybindings")
16774
+ children: [(0, react_jsx_runtime.jsxs)("span", {
16775
+ className: PendingPanel_module_css_default.settingsGroupText,
16776
+ children: [(0, react_jsx_runtime.jsx)("span", {
16777
+ className: PendingPanel_module_css_default.settingsGroupTitle,
16778
+ children: t("settings.keybindings")
16779
+ }), (0, react_jsx_runtime.jsx)("span", {
16780
+ className: PendingPanel_module_css_default.settingsGroupDesc,
16781
+ children: t("settings.keybindingsDesc")
16782
+ })]
16141
16783
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: PendingPanel_module_css_default.settingsGroupChevron })]
16142
16784
  }), keysOpen && (0, react_jsx_runtime.jsxs)("div", {
16143
16785
  className: PendingPanel_module_css_default.settingsGroupBody,
@@ -16160,14 +16802,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16160
16802
  }, action))]
16161
16803
  })]
16162
16804
  }),
16163
- (0, react_jsx_runtime.jsx)(PreferenceRow, {
16164
- title: t("panel.pasteOnCopy"),
16165
- description: t("panel.pasteOnCopyDesc"),
16166
- value: pasteOnCopy,
16167
- onSelect: setPasteOnCopy,
16168
- dataAttribute: "data-diff-paste-on-copy-select",
16169
- t
16170
- }),
16171
16805
  (0, react_jsx_runtime.jsx)(PreferenceRow, {
16172
16806
  title: t("panel.importUntracked"),
16173
16807
  description: t("panel.importUntrackedDesc"),
@@ -16175,33 +16809,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16175
16809
  onSelect: setIncludeUntracked,
16176
16810
  dataAttribute: "data-diff-import-untracked-select",
16177
16811
  t
16178
- }),
16179
- (0, react_jsx_runtime.jsx)(TabWidthRow, {
16180
- title: t("panel.tabWidth"),
16181
- description: t("panel.tabWidthDesc"),
16182
- value: tab,
16183
- open: tabOpen,
16184
- onOpenChange: setTabOpen,
16185
- onSelect: setTab,
16186
- dataAttribute: "data-diff-tab-width-select"
16187
- }),
16188
- (0, react_jsx_runtime.jsx)(PreferenceRow, {
16189
- title: t("panel.splitMode"),
16190
- description: t("panel.splitModeDesc"),
16191
- value: split,
16192
- onSelect: setSplit,
16193
- dataAttribute: "data-diff-split-mode-select",
16194
- t
16195
- }),
16196
- (0, react_jsx_runtime.jsx)(StepperRow, {
16197
- title: t("panel.navLeadRows"),
16198
- description: t("panel.navLeadRowsDesc"),
16199
- value: lead,
16200
- onChange: setLead,
16201
- min: 0,
16202
- max: 10,
16203
- dataAttribute: "data-diff-nav-lead-rows",
16204
- t
16205
16812
  })
16206
16813
  ]
16207
16814
  });
@@ -16237,18 +16844,20 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16237
16844
  id
16238
16845
  }));
16239
16846
  },
16240
- async blockKeep(sessionId, id, block) {
16847
+ async blockKeep(sessionId, id, block, removeWhenResolved) {
16241
16848
  return actionOf(await rpc.call(DIFF_APPROVAL_CHANNEL, "block-keep", {
16242
16849
  sessionId,
16243
16850
  id,
16244
- block
16851
+ block,
16852
+ removeWhenResolved
16245
16853
  }));
16246
16854
  },
16247
- async blockRevert(sessionId, id, block) {
16855
+ async blockRevert(sessionId, id, block, removeWhenResolved) {
16248
16856
  return actionOf(await rpc.call(DIFF_APPROVAL_CHANNEL, "block-revert", {
16249
16857
  sessionId,
16250
16858
  id,
16251
- block
16859
+ block,
16860
+ removeWhenResolved
16252
16861
  }));
16253
16862
  },
16254
16863
  async undo(sessionId) {
@@ -16387,17 +16996,12 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16387
16996
  };
16388
16997
  const listeners = /* @__PURE__ */ new Set();
16389
16998
  let redoCleared = false;
16390
- let justResolved;
16391
16999
  const publish = (next) => {
16392
17000
  let result = next;
16393
17001
  if (redoCleared) result = {
16394
17002
  ...result,
16395
17003
  redoCleared: true
16396
17004
  };
16397
- if (justResolved !== void 0) result = {
16398
- ...result,
16399
- justResolved
16400
- };
16401
17005
  snapshot = result;
16402
17006
  for (const listener of [...listeners]) listener();
16403
17007
  };
@@ -16501,15 +17105,15 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16501
17105
  await port.revert(sessionId, id);
16502
17106
  });
16503
17107
  },
16504
- async blockKeep(sessionId, id, block) {
17108
+ async blockKeep(sessionId, id, block, removeWhenResolved) {
16505
17109
  const { error: _cleared, ...base } = snapshot;
16506
17110
  publish({
16507
17111
  ...base,
16508
17112
  busy: /* @__PURE__ */ new Set([...snapshot.busy, id])
16509
17113
  });
16510
- let value;
16511
17114
  try {
16512
- value = await port.blockKeep(sessionId, id, block);
17115
+ if (removeWhenResolved === void 0) await port.blockKeep(sessionId, id, block);
17116
+ else await port.blockKeep(sessionId, id, block, removeWhenResolved);
16513
17117
  } catch (error) {
16514
17118
  markFailed(id, error instanceof Error ? error.message : String(error));
16515
17119
  publish({
@@ -16519,18 +17123,17 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16519
17123
  return;
16520
17124
  }
16521
17125
  clearFailed(id);
16522
- if (value.resolved === true) justResolved = id;
16523
17126
  await this.refresh(sessionId);
16524
17127
  },
16525
- async blockRevert(sessionId, id, block) {
17128
+ async blockRevert(sessionId, id, block, removeWhenResolved) {
16526
17129
  const { error: _cleared, ...base } = snapshot;
16527
17130
  publish({
16528
17131
  ...base,
16529
17132
  busy: /* @__PURE__ */ new Set([...snapshot.busy, id])
16530
17133
  });
16531
- let value;
16532
17134
  try {
16533
- value = await port.blockRevert(sessionId, id, block);
17135
+ if (removeWhenResolved === void 0) await port.blockRevert(sessionId, id, block);
17136
+ else await port.blockRevert(sessionId, id, block, removeWhenResolved);
16534
17137
  } catch (error) {
16535
17138
  markFailed(id, error instanceof Error ? error.message : String(error));
16536
17139
  publish({
@@ -16540,7 +17143,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16540
17143
  return;
16541
17144
  }
16542
17145
  clearFailed(id);
16543
- if (value.resolved === true) justResolved = id;
16544
17146
  await this.refresh(sessionId);
16545
17147
  },
16546
17148
  async undo(sessionId) {
@@ -16579,7 +17181,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16579
17181
  }
16580
17182
  },
16581
17183
  reset() {
16582
- justResolved = void 0;
16583
17184
  publish({
16584
17185
  read: false,
16585
17186
  files: [],
@@ -16590,11 +17191,6 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16590
17191
  redoCleared = false;
16591
17192
  const { redoCleared: _omit, ...rest } = snapshot;
16592
17193
  publish(rest);
16593
- },
16594
- clearJustResolved() {
16595
- justResolved = void 0;
16596
- const { justResolved: _omit, ...rest } = snapshot;
16597
- publish(rest);
16598
17194
  }
16599
17195
  };
16600
17196
  }
@@ -16766,10 +17362,22 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16766
17362
  "panel.splitModeDesc": "开启后整文件差异用左「改前」|右「当前」双栏、逐行对齐的视图展示,默认关闭使用单栏(合并)视图。",
16767
17363
  "panel.navLeadRows": "差异跳转行距",
16768
17364
  "panel.navLeadRowsDesc": "按上/下跳转差异时,目标差异上方保留的行数(默认 2)。也用于从当前滚动位置定位上/下一个差异。",
17365
+ "panel.diffFontSize": "字号",
17366
+ "panel.diffFontSizeDesc": "差异代码的文字大小,按当前字号的百分比缩放(默认为100%,每次 ±10%)。",
17367
+ "panel.diffLineHeight": "行高",
17368
+ "panel.diffLineHeightDesc": "差异代码每行的高度(像素,默认 22),滚动与跳转定位会随之调整。",
17369
+ "panel.diffAddColor": "新增颜色",
17370
+ "panel.diffAddColorDesc": "新增行的基础色;行背景与逐词差异由它派生。默认色:{default}。",
17371
+ "panel.diffDelColor": "删除颜色",
17372
+ "panel.diffDelColorDesc": "删除行的基础色;行背景与逐词差异由它派生。默认色:{default}。",
16769
17373
  "panel.quickSummon": "快速呼出",
16770
17374
  "panel.quickSummonDesc": "用键盘快捷键打开/关闭差异面板。点击右侧按钮后按下新的按键组合即可修改。",
16771
17375
  "panel.recordShortcut": "按下快捷键…",
16772
- "settings.keybindings": "按键设置",
17376
+ "settings.keybindings": "快捷键",
17377
+ "settings.keybindingsDesc": "展开后可配置各项操作的按键组合。",
17378
+ "settings.diffView": "差异视图",
17379
+ "settings.diffViewDesc": "调整差异的显示效果(字号、行高、新增/删除颜色)与布局偏好。",
17380
+ "settings.diffPreview": "预览",
16773
17381
  "panel.keyDesc": "点击右侧按钮后按下新的按键组合即可修改。",
16774
17382
  "panel.key.jumpUp": "跳转到上一个差异块",
16775
17383
  "panel.key.jumpDown": "跳转到下一个差异块",
@@ -16860,10 +17468,22 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
16860
17468
  "panel.splitModeDesc": "When on, the whole-file differences render as a side-by-side (left \"before\" | right \"current\") line-aligned view. Off (default) uses the single-column unified view.",
16861
17469
  "panel.navLeadRows": "Block jump lead rows",
16862
17470
  "panel.navLeadRowsDesc": "Rows left above the jumped-to diff block on up/down navigation (default 2). Also used to locate the previous/next diff from the current scroll position.",
17471
+ "panel.diffFontSize": "Font size",
17472
+ "panel.diffFontSizeDesc": "Diff code text size as a percentage of the current size (defaults to 100%, ±10% per step).",
17473
+ "panel.diffLineHeight": "Line height",
17474
+ "panel.diffLineHeightDesc": "The diff code line height, in pixels (default 22); scrolling and jump positioning follow it.",
17475
+ "panel.diffAddColor": "Added color",
17476
+ "panel.diffAddColorDesc": "Base color for added lines; the row background and intra-line diff are derived from it. Default: {default}.",
17477
+ "panel.diffDelColor": "Removed color",
17478
+ "panel.diffDelColorDesc": "Base color for removed lines; the row background and intra-line diff are derived from it. Default: {default}.",
16863
17479
  "panel.quickSummon": "Quick summon",
16864
17480
  "panel.quickSummonDesc": "Open or close the diff panel with a keyboard shortcut. Click the button and press a new chord to change it.",
16865
17481
  "panel.recordShortcut": "Press keys…",
16866
- "settings.keybindings": "Keybindings",
17482
+ "settings.keybindings": "Shortcuts",
17483
+ "settings.keybindingsDesc": "Expand to configure the key combo for each action.",
17484
+ "settings.diffView": "Diff view",
17485
+ "settings.diffViewDesc": "Adjust the diff appearance (font size, line height, add/delete colors) and layout preferences.",
17486
+ "settings.diffPreview": "Preview",
16867
17487
  "panel.keyDesc": "Click the button, then press a new chord to rebind it.",
16868
17488
  "panel.key.jumpUp": "Jump to the previous diff block",
16869
17489
  "panel.key.jumpDown": "Jump to the next diff block",
@@ -17045,14 +17665,13 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
17045
17665
  if (filePath !== void 0 && before !== void 0 && after !== void 0) remapFile(filePath, before, after);
17046
17666
  });
17047
17667
  },
17048
- onBlockKeep: (sessionId, id, block) => store.blockKeep(sessionId, id, block),
17049
- onBlockRevert: (sessionId, id, block) => store.blockRevert(sessionId, id, block),
17668
+ onBlockKeep: (sessionId, id, block, removeWhenResolved) => store.blockKeep(sessionId, id, block, removeWhenResolved),
17669
+ onBlockRevert: (sessionId, id, block, removeWhenResolved) => store.blockRevert(sessionId, id, block, removeWhenResolved),
17050
17670
  onOpen: (sessionId, id, action) => store.open(sessionId, id, action),
17051
17671
  onUndo: (sessionId) => store.undo(sessionId),
17052
17672
  onRedo: (sessionId) => store.redo(sessionId),
17053
17673
  onImportVcs: (sessionId, includeUntracked) => store.importVcs(sessionId, includeUntracked),
17054
17674
  onAckRedoCleared: () => store.clearRedoCleared(),
17055
- onAckJustResolved: () => store.clearJustResolved(),
17056
17675
  onPasteReference: (sessionId, reference) => {
17057
17676
  conversationAccess(ctx, () => sessionId).appendDraft(reference);
17058
17677
  document.querySelector("[data-composer-input]")?.focus();