@simon_he/vue-tui 1.1.4 → 1.1.6

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/dist/cli.cjs CHANGED
@@ -7355,7 +7355,7 @@ function pickBestTerminalGraphicsProtocol(protocols) {
7355
7355
  }
7356
7356
  function detectCandidates(env) {
7357
7357
  let candidates = [], term = String(envString2(env, "TERM") ?? "").toLowerCase(), termProgram = String(envString2(env, "TERM_PROGRAM") ?? "").toLowerCase(), termProgramVersion = String(envString2(env, "TERM_PROGRAM_VERSION") ?? "").toLowerCase();
7358
- return (envString2(env, "KITTY_WINDOW_ID") || envString2(env, "GHOSTTY_RESOURCES_DIR") || /(?:^|-)kitty(?:-|$)/i.test(term) || term.includes("ghostty") || termProgram.includes("ghostty")) && candidates.push("kitty"), (termProgram.includes("iterm") || termProgram.includes("wezterm") || envString2(env, "WEZTERM_PANE") || envString2(env, "WEZTERM_EXECUTABLE")) && candidates.push("iterm2"), (truthy(envString2(env, "VUE_TUI_SIXEL")) || truthy(envString2(env, "VUE_TUI_GRAPHICS_SIXEL")) || String(envString2(env, "TERMINAL_GRAPHICS") ?? "").toLowerCase().includes("sixel") || /\bsixel\b/i.test(`${term} ${termProgram} ${termProgramVersion}`)) && candidates.push("sixel"), uniqueProtocols(candidates);
7358
+ return (envString2(env, "KITTY_WINDOW_ID") || envString2(env, "GHOSTTY_RESOURCES_DIR") || /(?:^|-)kitty(?:-|$)/i.test(term) || term.includes("ghostty") || termProgram.includes("ghostty") || termProgram.includes("wezterm") || envString2(env, "WEZTERM_PANE") || envString2(env, "WEZTERM_EXECUTABLE")) && candidates.push("kitty"), termProgram.includes("iterm") && candidates.push("iterm2"), (truthy(envString2(env, "VUE_TUI_SIXEL")) || truthy(envString2(env, "VUE_TUI_GRAPHICS_SIXEL")) || String(envString2(env, "TERMINAL_GRAPHICS") ?? "").toLowerCase().includes("sixel") || /\bsixel\b/i.test(`${term} ${termProgram} ${termProgramVersion}`)) && candidates.push("sixel"), uniqueProtocols(candidates);
7359
7359
  }
7360
7360
  function capabilitiesFor(protocol, input) {
7361
7361
  let supported = protocol === "kitty" || protocol === "iterm2" || protocol === "sixel", candidates = uniqueProtocols([...input.candidates ?? (supported ? [protocol] : [])]);
@@ -8000,7 +8000,7 @@ function createStdoutRenderer(terminal, options) {
8000
8000
  return "multi-span";
8001
8001
  }
8002
8002
  }
8003
- let effectiveDirtyRowPatchMode = resolveEffectiveDirtyRowPatchMode(), shouldUseDirtySpans = () => effectiveDirtyRowPatchMode !== "row", shouldUseMultiDirtySpans = () => effectiveDirtyRowPatchMode === "multi-span", enableOsc8Links = outputAllowsOsc8Links && !isVscodeTerminal, renderedHref = (value) => enableOsc8Links ? normalizeHref(value) : null, disposed = !1, lastFrameTime = 0, pendingRender = !1, renderTimer = null, rowsOnlyResizeRepaintTimer = null, writeEmaMs = 0, lastCursorX = null, lastCursorY = null, accumulatedAllRows = !1, accumulatedDirtyBits = null, accumulatedDirtyCount = 0, accumulatedDirtyMin = Number.POSITIVE_INFINITY, accumulatedDirtyMax = -1, accumulatedDirtyRowsRequireRepaint = !1, accumulatedScrollOperations = null, allowNextGraphicsOnlyRenderWithoutBaseline = !1, preserveNextRowsOnlyResizeBaseline = !1, deferGraphicsFlushUntilResizeCommit = !1, graphicsCapabilities = resolveTerminalGraphicsCapabilities(options, env, outputIsTTY), pendingGraphics = /* @__PURE__ */ new Map(), pendingGraphicClears = /* @__PURE__ */ new Set(), activeGraphics = /* @__PURE__ */ new Map(), pendingGraphicSignatures = /* @__PURE__ */ new Map(), activeGraphicSignatures = /* @__PURE__ */ new Map(), retainedGraphics = /* @__PURE__ */ new Map(), knownKittyImageIds = /* @__PURE__ */ new Set(), terminalResizeDirtyGraphics = /* @__PURE__ */ new Set(), nextGraphicsOrder = 0, terminalGraphicsFlushTimer = null, hasPendingTerminalGraphics = () => pendingGraphics.size > 0 || pendingGraphicClears.size > 0;
8003
+ let effectiveDirtyRowPatchMode = resolveEffectiveDirtyRowPatchMode(), shouldUseDirtySpans = () => effectiveDirtyRowPatchMode !== "row", shouldUseMultiDirtySpans = () => effectiveDirtyRowPatchMode === "multi-span", enableOsc8Links = outputAllowsOsc8Links && !isVscodeTerminal, renderedHref = (value) => enableOsc8Links ? normalizeHref(value) : null, disposed = !1, lastFrameTime = 0, pendingRender = !1, renderTimer = null, rowsOnlyResizeRepaintTimer = null, writeEmaMs = 0, lastCursorX = null, lastCursorY = null, accumulatedAllRows = !1, accumulatedDirtyBits = null, accumulatedDirtyCount = 0, accumulatedDirtyMin = Number.POSITIVE_INFINITY, accumulatedDirtyMax = -1, accumulatedDirtyRowsRequireRepaint = !1, accumulatedScrollOperations = null, allowNextGraphicsOnlyRenderWithoutBaseline = !1, preserveNextRowsOnlyResizeBaseline = !1, deferGraphicsFlushUntilResizeCommit = !1, graphicsCapabilities = resolveTerminalGraphicsCapabilities(options, env, outputIsTTY), pendingGraphics = /* @__PURE__ */ new Map(), pendingGraphicClears = /* @__PURE__ */ new Set(), activeGraphics = /* @__PURE__ */ new Map(), pendingGraphicSignatures = /* @__PURE__ */ new Map(), activeGraphicSignatures = /* @__PURE__ */ new Map(), validatedGraphicFrames = /* @__PURE__ */ new Map(), graphicSequenceHashes = /* @__PURE__ */ new Map(), retainedGraphics = /* @__PURE__ */ new Map(), knownKittyImageIds = /* @__PURE__ */ new Set(), terminalResizeDirtyGraphics = /* @__PURE__ */ new Set(), nextGraphicsOrder = 0, terminalGraphicsFlushTimer = null, hasPendingTerminalGraphics = () => pendingGraphics.size > 0 || pendingGraphicClears.size > 0;
8004
8004
  function canUseTerminalGraphicsProtocol(protocol, capabilities) {
8005
8005
  return capabilities.supported && isTerminalGraphicsProtocol(protocol) && protocol === capabilities.preferredProtocol;
8006
8006
  }
@@ -8020,16 +8020,24 @@ function createStdoutRenderer(terminal, options) {
8020
8020
  }
8021
8021
  }
8022
8022
  function terminalGraphicsPayloadSignature(payload) {
8023
- return [
8023
+ let cached = graphicSequenceHashes.get(payload.id), resizeSequence = payload.resizeSequence ?? "", clearSequence = payload.clearSequence ?? "", hashes = cached && cached.sequence === payload.sequence && cached.resizeSequence === resizeSequence && cached.clearSequence === clearSequence ? cached : {
8024
+ sequence: payload.sequence,
8025
+ resizeSequence,
8026
+ clearSequence,
8027
+ sequenceHash: hashTerminalGraphicsString(payload.sequence),
8028
+ resizeSequenceHash: hashTerminalGraphicsString(resizeSequence),
8029
+ clearSequenceHash: hashTerminalGraphicsString(clearSequence)
8030
+ };
8031
+ return hashes !== cached && graphicSequenceHashes.set(payload.id, hashes), [
8024
8032
  payload.id,
8025
8033
  payload.protocol,
8026
8034
  payload.x,
8027
8035
  payload.y,
8028
8036
  payload.w ?? "",
8029
8037
  payload.h ?? "",
8030
- hashTerminalGraphicsString(payload.sequence),
8031
- hashTerminalGraphicsString(payload.resizeSequence ?? ""),
8032
- hashTerminalGraphicsString(payload.clearSequence ?? ""),
8038
+ hashes.sequenceHash,
8039
+ hashes.resizeSequenceHash,
8040
+ hashes.clearSequenceHash,
8033
8041
  payload.allowTextOverlay ? "1" : "0"
8034
8042
  ].join(":");
8035
8043
  }
@@ -8095,6 +8103,10 @@ function createStdoutRenderer(terminal, options) {
8095
8103
  }
8096
8104
  return null;
8097
8105
  }
8106
+ function sameKittyImage(a, b) {
8107
+ let aId = kittyImageId(a);
8108
+ return aId != null && aId === kittyImageId(b);
8109
+ }
8098
8110
  function canReplaceKittyPlacementWithoutClear(previous, payload) {
8099
8111
  if (payload.terminalResizeRedraw || !payload.resizeRedraw || previous.protocol !== "kitty" || payload.protocol !== "kitty")
8100
8112
  return !1;
@@ -8113,7 +8125,7 @@ function createStdoutRenderer(terminal, options) {
8113
8125
  pendingGraphicSignatures.delete(id), terminalResizeDirtyGraphics.delete(id);
8114
8126
  let active = activeGraphics.get(id);
8115
8127
  if (!active)
8116
- return options2.retainOnClear || retainedGraphics.delete(id), removedPendingDraw;
8128
+ return options2.retainOnClear || (retainedGraphics.delete(id), validatedGraphicFrames.delete(id), graphicSequenceHashes.delete(id)), removedPendingDraw;
8117
8129
  if (active.clearSequence) {
8118
8130
  let payload = {
8119
8131
  id,
@@ -8155,7 +8167,7 @@ function createStdoutRenderer(terminal, options) {
8155
8167
  );
8156
8168
  for (let payload of pendingGraphics.values())
8157
8169
  rememberImageId(payload.sequence, payload.resizeSequence, payload.clearSequence);
8158
- pendingGraphics.clear(), pendingGraphicClears.clear(), activeGraphics.clear(), pendingGraphicSignatures.clear(), activeGraphicSignatures.clear(), retainedGraphics.clear(), knownKittyImageIds.clear(), terminalResizeDirtyGraphics.clear();
8170
+ pendingGraphics.clear(), pendingGraphicClears.clear(), activeGraphics.clear(), pendingGraphicSignatures.clear(), activeGraphicSignatures.clear(), retainedGraphics.clear(), validatedGraphicFrames.clear(), graphicSequenceHashes.clear(), knownKittyImageIds.clear(), terminalResizeDirtyGraphics.clear();
8159
8171
  for (let imageId of imageIds) {
8160
8172
  let payload = {
8161
8173
  id: `__terminal_graphics_clear_image_${imageId}__`,
@@ -8263,16 +8275,17 @@ function createStdoutRenderer(terminal, options) {
8263
8275
  if (!normalized.id.trim() || !Number.isFinite(normalized.x) || !Number.isFinite(normalized.y) || !canUseTerminalGraphicsProtocol(normalized.protocol, graphicsCapabilities))
8264
8276
  return !1;
8265
8277
  if (op === "draw") {
8266
- let frame = validateTerminalGraphicFrame({
8278
+ let cachedFrame = validatedGraphicFrames.get(normalized.id), width = normalized.w ?? 1, height = normalized.h ?? 1, frame = cachedFrame && cachedFrame.protocol === normalized.protocol && cachedFrame.sequence === normalized.sequence && cachedFrame.width === width && cachedFrame.height === height && cachedFrame.fallbackText === (normalized.fallbackText ?? "") ? cachedFrame : validateTerminalGraphicFrame({
8267
8279
  id: normalized.id,
8268
8280
  protocol: normalized.protocol,
8269
8281
  sequence: normalized.sequence,
8270
8282
  fallbackText: normalized.fallbackText,
8271
- width: normalized.w ?? 1,
8272
- height: normalized.h ?? 1
8283
+ width,
8284
+ height
8273
8285
  });
8274
8286
  if (!frame)
8275
8287
  return !1;
8288
+ frame !== cachedFrame && validatedGraphicFrames.set(frame.id, frame);
8276
8289
  let imageId = kittyImageId(frame.sequence) ?? kittyImageId(normalized.resizeSequence);
8277
8290
  if (imageId != null && knownKittyImageIds.add(imageId), isDebugEnabled()) {
8278
8291
  let size = terminal.size();
@@ -8317,7 +8330,7 @@ function createStdoutRenderer(terminal, options) {
8317
8330
  }), isDebugEnabled() && getDebugLog().render(
8318
8331
  `terminal graphic queue draw canceled clear: id=${frame.id}, x=${normalized.x}, y=${normalized.y}, w=${frame.width}, h=${frame.height}`
8319
8332
  ), !0;
8320
- let active = activeGraphics.get(frame.id), activeCanReplacePlacement = active && active.sequence === frame.sequence && resizeSequence && canReplaceKittyPlacementWithoutClear(active, {
8333
+ let active = activeGraphics.get(frame.id), activeCanReplacePlacement = active && (active.sequence === frame.sequence || normalized.placementMoveWithoutClear && sameKittyImage(active.sequence, frame.sequence)) && resizeSequence && canReplaceKittyPlacementWithoutClear(active, {
8321
8334
  ...normalized,
8322
8335
  id: frame.id,
8323
8336
  w: frame.width,
@@ -8340,14 +8353,18 @@ function createStdoutRenderer(terminal, options) {
8340
8353
  clearSequence,
8341
8354
  fallbackText: frame.fallbackText,
8342
8355
  resizeRedraw: !0,
8343
- placementMoveWithoutClear: !1
8356
+ // Preserve the caller's opt-in: when the placement moves (e.g.
8357
+ // interactive wheel zoom) the render pass can replace the kitty
8358
+ // placement in place and keep the original transmission sequence,
8359
+ // so subsequent resizes stay on the cheap path.
8360
+ placementMoveWithoutClear: !!normalized.placementMoveWithoutClear
8344
8361
  }), pendingGraphicSignatures.set(frame.id, signature), recordTerminalGraphicTrace({
8345
8362
  type: "queue",
8346
8363
  id: frame.id,
8347
8364
  protocol: normalized.protocol,
8348
8365
  bytes: resizeSequence.length
8349
8366
  }), requestTerminalGraphicsFlush(!!normalized.deferFlush), !0;
8350
- let retained = retainedGraphics.get(frame.id), retainedCanReplacePlacement = retained && retained.active.sequence === frame.sequence && resizeSequence && canReplaceKittyPlacementWithoutClear(retained.active, {
8367
+ let retained = retainedGraphics.get(frame.id), retainedCanReplacePlacement = retained && (retained.active.sequence === frame.sequence || normalized.placementMoveWithoutClear && sameKittyImage(retained.active.sequence, frame.sequence)) && resizeSequence && canReplaceKittyPlacementWithoutClear(retained.active, {
8351
8368
  ...normalized,
8352
8369
  id: frame.id,
8353
8370
  w: frame.width,
@@ -8369,7 +8386,7 @@ function createStdoutRenderer(terminal, options) {
8369
8386
  clearSequence,
8370
8387
  fallbackText: frame.fallbackText,
8371
8388
  resizeRedraw: !0,
8372
- placementMoveWithoutClear: !1,
8389
+ placementMoveWithoutClear: !!normalized.placementMoveWithoutClear,
8373
8390
  terminalResizeRedraw: forceTerminalResizeRedraw
8374
8391
  }), pendingGraphicSignatures.set(frame.id, signature), isDebugEnabled() && getDebugLog().render(
8375
8392
  `terminal graphic retained resize redraw: id=${frame.id}, x=${retained.active.x}, y=${retained.active.y}, w=${retained.active.w}, h=${retained.active.h}, bytes=${resizeSequence.length}`
@@ -9739,7 +9756,7 @@ function createStdoutRenderer(terminal, options) {
9739
9756
  return opA - opB || a.order - b.order;
9740
9757
  }), graphicsToRender = graphicsEntriesToRender.map(([, payload]) => payload));
9741
9758
  })(), graphicsClearsToRender.length > 0 || graphicsToRender.length > 0) {
9742
- let nextActiveGraphics = new Map(activeGraphics), nextActiveGraphicSignatures = new Map(activeGraphicSignatures), nextPendingGraphicSignatures = new Map(pendingGraphicSignatures), terminalGraphicsDraws = 0, terminalGraphicsClears = 0, terminalGraphicsBytes = 0, countGraphicsBytes = (value) => (terminalGraphicsBytes += import_node_buffer3.Buffer.byteLength(value, "utf8"), value), appendTerminalGraphicSequenceAt = (sequence, rect, fallbackCell, skipWithoutRect = !1) => {
9759
+ let nextActiveGraphics = new Map(activeGraphics), nextActiveGraphicSignatures = new Map(activeGraphicSignatures), nextPendingGraphicSignatures = new Map(pendingGraphicSignatures), clearedGraphicCacheIds = /* @__PURE__ */ new Set(), terminalGraphicsDraws = 0, terminalGraphicsClears = 0, terminalGraphicsBytes = 0, countGraphicsBytes = (value) => (terminalGraphicsBytes += import_node_buffer3.Buffer.byteLength(value, "utf8"), value), appendTerminalGraphicSequenceAt = (sequence, rect, fallbackCell, skipWithoutRect = !1) => {
9743
9760
  if (!rect && skipWithoutRect)
9744
9761
  return !1;
9745
9762
  let cell = rect ? { x: rect.x, y: rect.y } : clampCellToViewport(fallbackCell, size);
@@ -9780,7 +9797,7 @@ function createStdoutRenderer(terminal, options) {
9780
9797
  let clearRect2 = clearGraphicRectForRowsNotPainted(visibleRect);
9781
9798
  clearRect2 && (frameParts.push(countGraphicsBytes(clearRect2)), wroteClear = !0);
9782
9799
  }
9783
- wroteClear = appendActiveGraphicProtocolClear(active, visibleRect) || wroteClear, wroteClear && terminalGraphicsClears++, retainedGraphics.delete(id), terminalResizeDirtyGraphics.delete(id), nextActiveGraphics.delete(id), nextActiveGraphicSignatures.delete(id), nextPendingGraphicSignatures.delete(id);
9800
+ wroteClear = appendActiveGraphicProtocolClear(active, visibleRect) || wroteClear, wroteClear && terminalGraphicsClears++, retainedGraphics.delete(id), clearedGraphicCacheIds.add(id), terminalResizeDirtyGraphics.delete(id), nextActiveGraphics.delete(id), nextActiveGraphicSignatures.delete(id), nextPendingGraphicSignatures.delete(id);
9784
9801
  }
9785
9802
  for (let payload of graphicsToRender) {
9786
9803
  if (payload.op === "clear") {
@@ -9805,7 +9822,7 @@ function createStdoutRenderer(terminal, options) {
9805
9822
  cellY: (active == null ? void 0 : active.y) ?? payload.y
9806
9823
  },
9807
9824
  clearSequenceNeedsVisibleCell(payload.sequence, payload.protocol)
9808
- ) || wroteClear, wroteClear && terminalGraphicsClears++, active && payload.retainOnClear ? retainTerminalGraphic(payload.id, active, nextActiveGraphicSignatures.get(payload.id)) : retainedGraphics.delete(payload.id), terminalResizeDirtyGraphics.delete(payload.id), nextActiveGraphics.delete(payload.id), nextActiveGraphicSignatures.delete(payload.id), nextPendingGraphicSignatures.delete(payload.id);
9825
+ ) || wroteClear, wroteClear && terminalGraphicsClears++, active && payload.retainOnClear ? retainTerminalGraphic(payload.id, active, nextActiveGraphicSignatures.get(payload.id)) : (retainedGraphics.delete(payload.id), clearedGraphicCacheIds.add(payload.id)), terminalResizeDirtyGraphics.delete(payload.id), nextActiveGraphics.delete(payload.id), nextActiveGraphicSignatures.delete(payload.id), nextPendingGraphicSignatures.delete(payload.id);
9809
9826
  continue;
9810
9827
  }
9811
9828
  let previous = nextActiveGraphics.get(payload.id), rect = anchoredGraphicRectInViewport(
@@ -9876,6 +9893,8 @@ function createStdoutRenderer(terminal, options) {
9876
9893
  pendingGraphicSignatures.clear();
9877
9894
  for (let [id, signature] of nextPendingGraphicSignatures)
9878
9895
  pendingGraphicSignatures.set(id, signature);
9896
+ for (let id of clearedGraphicCacheIds)
9897
+ nextActiveGraphics.has(id) || retainedGraphics.has(id) || (validatedGraphicFrames.delete(id), graphicSequenceHashes.delete(id));
9879
9898
  }, terminalGraphicsMetrics = {
9880
9899
  draws: terminalGraphicsDraws,
9881
9900
  clears: terminalGraphicsClears,
@@ -10271,7 +10290,7 @@ function createStdoutRenderer(terminal, options) {
10271
10290
  return;
10272
10291
  disposed = !0;
10273
10292
  let disposeError = null;
10274
- renderTimer && (clearTimeout(renderTimer), renderTimer = null), terminalGraphicsFlushTimer && (clearTimeout(terminalGraphicsFlushTimer), terminalGraphicsFlushTimer = null), clearRowsOnlyResizeRepaintTimer(), accumulatedAllRows = !1, accumulatedDirtyBits = null, accumulatedDirtyCount = 0, accumulatedDirtyMin = Number.POSITIVE_INFINITY, accumulatedDirtyMax = -1, accumulatedDirtyRowsRequireRepaint = !1, pendingGraphics.clear(), pendingGraphicClears.clear(), pendingGraphicSignatures.clear(), retainedGraphics.clear(), knownKittyImageIds.clear(), terminalResizeDirtyGraphics.clear();
10293
+ renderTimer && (clearTimeout(renderTimer), renderTimer = null), terminalGraphicsFlushTimer && (clearTimeout(terminalGraphicsFlushTimer), terminalGraphicsFlushTimer = null), clearRowsOnlyResizeRepaintTimer(), accumulatedAllRows = !1, accumulatedDirtyBits = null, accumulatedDirtyCount = 0, accumulatedDirtyMin = Number.POSITIVE_INFINITY, accumulatedDirtyMax = -1, accumulatedDirtyRowsRequireRepaint = !1, pendingGraphics.clear(), pendingGraphicClears.clear(), pendingGraphicSignatures.clear(), retainedGraphics.clear(), validatedGraphicFrames.clear(), graphicSequenceHashes.clear(), knownKittyImageIds.clear(), terminalResizeDirtyGraphics.clear();
10275
10294
  try {
10276
10295
  if (activeGraphics.size > 0) {
10277
10296
  let size = terminal.size(), clearParts = [], terminalGraphicsClears = 0;
package/dist/cli.js CHANGED
@@ -9335,8 +9335,8 @@ function detectCandidates(env) {
9335
9335
  const term = String(envString(env, "TERM") ?? "").toLowerCase();
9336
9336
  const termProgram = String(envString(env, "TERM_PROGRAM") ?? "").toLowerCase();
9337
9337
  const termProgramVersion = String(envString(env, "TERM_PROGRAM_VERSION") ?? "").toLowerCase();
9338
- if (envString(env, "KITTY_WINDOW_ID") || envString(env, "GHOSTTY_RESOURCES_DIR") || /(?:^|-)kitty(?:-|$)/i.test(term) || term.includes("ghostty") || termProgram.includes("ghostty")) candidates.push("kitty");
9339
- if (termProgram.includes("iterm") || termProgram.includes("wezterm") || envString(env, "WEZTERM_PANE") || envString(env, "WEZTERM_EXECUTABLE")) candidates.push("iterm2");
9338
+ if (envString(env, "KITTY_WINDOW_ID") || envString(env, "GHOSTTY_RESOURCES_DIR") || /(?:^|-)kitty(?:-|$)/i.test(term) || term.includes("ghostty") || termProgram.includes("ghostty") || termProgram.includes("wezterm") || envString(env, "WEZTERM_PANE") || envString(env, "WEZTERM_EXECUTABLE")) candidates.push("kitty");
9339
+ if (termProgram.includes("iterm")) candidates.push("iterm2");
9340
9340
  if (truthy(envString(env, "VUE_TUI_SIXEL")) || truthy(envString(env, "VUE_TUI_GRAPHICS_SIXEL")) || String(envString(env, "TERMINAL_GRAPHICS") ?? "").toLowerCase().includes("sixel") || /\bsixel\b/i.test(`${term} ${termProgram} ${termProgramVersion}`)) candidates.push("sixel");
9341
9341
  return uniqueProtocols(candidates);
9342
9342
  }
@@ -10096,6 +10096,8 @@ function createStdoutRenderer(terminal, options) {
10096
10096
  const activeGraphics = new Map();
10097
10097
  const pendingGraphicSignatures = new Map();
10098
10098
  const activeGraphicSignatures = new Map();
10099
+ const validatedGraphicFrames = new Map();
10100
+ const graphicSequenceHashes = new Map();
10099
10101
  const retainedGraphics = new Map();
10100
10102
  const knownKittyImageIds = new Set();
10101
10103
  const terminalResizeDirtyGraphics = new Set();
@@ -10122,6 +10124,18 @@ function createStdoutRenderer(terminal, options) {
10122
10124
  }, 0);
10123
10125
  }
10124
10126
  function terminalGraphicsPayloadSignature(payload) {
10127
+ const cached = graphicSequenceHashes.get(payload.id);
10128
+ const resizeSequence = payload.resizeSequence ?? "";
10129
+ const clearSequence = payload.clearSequence ?? "";
10130
+ const hashes = cached && cached.sequence === payload.sequence && cached.resizeSequence === resizeSequence && cached.clearSequence === clearSequence ? cached : {
10131
+ sequence: payload.sequence,
10132
+ resizeSequence,
10133
+ clearSequence,
10134
+ sequenceHash: hashTerminalGraphicsString(payload.sequence),
10135
+ resizeSequenceHash: hashTerminalGraphicsString(resizeSequence),
10136
+ clearSequenceHash: hashTerminalGraphicsString(clearSequence)
10137
+ };
10138
+ if (hashes !== cached) graphicSequenceHashes.set(payload.id, hashes);
10125
10139
  return [
10126
10140
  payload.id,
10127
10141
  payload.protocol,
@@ -10129,9 +10143,9 @@ function createStdoutRenderer(terminal, options) {
10129
10143
  payload.y,
10130
10144
  payload.w ?? "",
10131
10145
  payload.h ?? "",
10132
- hashTerminalGraphicsString(payload.sequence),
10133
- hashTerminalGraphicsString(payload.resizeSequence ?? ""),
10134
- hashTerminalGraphicsString(payload.clearSequence ?? ""),
10146
+ hashes.sequenceHash,
10147
+ hashes.resizeSequenceHash,
10148
+ hashes.clearSequenceHash,
10135
10149
  payload.allowTextOverlay ? "1" : "0"
10136
10150
  ].join(":");
10137
10151
  }
@@ -10196,6 +10210,10 @@ function createStdoutRenderer(terminal, options) {
10196
10210
  }
10197
10211
  return null;
10198
10212
  }
10213
+ function sameKittyImage(a, b) {
10214
+ const aId = kittyImageId(a);
10215
+ return aId != null && aId === kittyImageId(b);
10216
+ }
10199
10217
  function canReplaceKittyPlacementWithoutClear(previous, payload) {
10200
10218
  if (payload.terminalResizeRedraw) return false;
10201
10219
  if (!payload.resizeRedraw || previous.protocol !== "kitty" || payload.protocol !== "kitty") return false;
@@ -10215,7 +10233,11 @@ function createStdoutRenderer(terminal, options) {
10215
10233
  terminalResizeDirtyGraphics.delete(id);
10216
10234
  const active = activeGraphics.get(id);
10217
10235
  if (!active) {
10218
- if (!options$1.retainOnClear) retainedGraphics.delete(id);
10236
+ if (!options$1.retainOnClear) {
10237
+ retainedGraphics.delete(id);
10238
+ validatedGraphicFrames.delete(id);
10239
+ graphicSequenceHashes.delete(id);
10240
+ }
10219
10241
  return removedPendingDraw;
10220
10242
  }
10221
10243
  if (active.clearSequence) {
@@ -10273,6 +10295,8 @@ function createStdoutRenderer(terminal, options) {
10273
10295
  pendingGraphicSignatures.clear();
10274
10296
  activeGraphicSignatures.clear();
10275
10297
  retainedGraphics.clear();
10298
+ validatedGraphicFrames.clear();
10299
+ graphicSequenceHashes.clear();
10276
10300
  knownKittyImageIds.clear();
10277
10301
  terminalResizeDirtyGraphics.clear();
10278
10302
  for (const imageId of imageIds) {
@@ -10397,15 +10421,19 @@ function createStdoutRenderer(terminal, options) {
10397
10421
  if (!Number.isFinite(normalized.x) || !Number.isFinite(normalized.y)) return false;
10398
10422
  if (!canUseTerminalGraphicsProtocol(normalized.protocol, graphicsCapabilities)) return false;
10399
10423
  if (op === "draw") {
10400
- const frame = validateTerminalGraphicFrame({
10424
+ const cachedFrame = validatedGraphicFrames.get(normalized.id);
10425
+ const width = normalized.w ?? 1;
10426
+ const height = normalized.h ?? 1;
10427
+ const frame = cachedFrame && cachedFrame.protocol === normalized.protocol && cachedFrame.sequence === normalized.sequence && cachedFrame.width === width && cachedFrame.height === height && cachedFrame.fallbackText === (normalized.fallbackText ?? "") ? cachedFrame : validateTerminalGraphicFrame({
10401
10428
  id: normalized.id,
10402
10429
  protocol: normalized.protocol,
10403
10430
  sequence: normalized.sequence,
10404
10431
  fallbackText: normalized.fallbackText,
10405
- width: normalized.w ?? 1,
10406
- height: normalized.h ?? 1
10432
+ width,
10433
+ height
10407
10434
  });
10408
10435
  if (!frame) return false;
10436
+ if (frame !== cachedFrame) validatedGraphicFrames.set(frame.id, frame);
10409
10437
  const imageId = kittyImageId(frame.sequence) ?? kittyImageId(normalized.resizeSequence);
10410
10438
  if (imageId != null) knownKittyImageIds.add(imageId);
10411
10439
  if (isDebugEnabled()) {
@@ -10459,7 +10487,7 @@ function createStdoutRenderer(terminal, options) {
10459
10487
  return true;
10460
10488
  }
10461
10489
  const active = activeGraphics.get(frame.id);
10462
- const activeCanReplacePlacement = active && active.sequence === frame.sequence && resizeSequence && canReplaceKittyPlacementWithoutClear(active, {
10490
+ const activeCanReplacePlacement = active && (active.sequence === frame.sequence || normalized.placementMoveWithoutClear && sameKittyImage(active.sequence, frame.sequence)) && resizeSequence && canReplaceKittyPlacementWithoutClear(active, {
10463
10491
  ...normalized,
10464
10492
  id: frame.id,
10465
10493
  w: frame.width,
@@ -10482,7 +10510,7 @@ function createStdoutRenderer(terminal, options) {
10482
10510
  clearSequence,
10483
10511
  fallbackText: frame.fallbackText,
10484
10512
  resizeRedraw: true,
10485
- placementMoveWithoutClear: false
10513
+ placementMoveWithoutClear: Boolean(normalized.placementMoveWithoutClear)
10486
10514
  });
10487
10515
  pendingGraphicSignatures.set(frame.id, signature);
10488
10516
  recordTerminalGraphicTrace({
@@ -10495,7 +10523,7 @@ function createStdoutRenderer(terminal, options) {
10495
10523
  return true;
10496
10524
  }
10497
10525
  const retained = retainedGraphics.get(frame.id);
10498
- const retainedCanReplacePlacement = retained && retained.active.sequence === frame.sequence && resizeSequence && canReplaceKittyPlacementWithoutClear(retained.active, {
10526
+ const retainedCanReplacePlacement = retained && (retained.active.sequence === frame.sequence || normalized.placementMoveWithoutClear && sameKittyImage(retained.active.sequence, frame.sequence)) && resizeSequence && canReplaceKittyPlacementWithoutClear(retained.active, {
10499
10527
  ...normalized,
10500
10528
  id: frame.id,
10501
10529
  w: frame.width,
@@ -10521,7 +10549,7 @@ function createStdoutRenderer(terminal, options) {
10521
10549
  clearSequence,
10522
10550
  fallbackText: frame.fallbackText,
10523
10551
  resizeRedraw: true,
10524
- placementMoveWithoutClear: false,
10552
+ placementMoveWithoutClear: Boolean(normalized.placementMoveWithoutClear),
10525
10553
  terminalResizeRedraw: forceTerminalResizeRedraw
10526
10554
  });
10527
10555
  pendingGraphicSignatures.set(frame.id, signature);
@@ -12450,6 +12478,7 @@ function createStdoutRenderer(terminal, options) {
12450
12478
  const nextActiveGraphics = new Map(activeGraphics);
12451
12479
  const nextActiveGraphicSignatures = new Map(activeGraphicSignatures);
12452
12480
  const nextPendingGraphicSignatures = new Map(pendingGraphicSignatures);
12481
+ const clearedGraphicCacheIds = new Set();
12453
12482
  let terminalGraphicsDraws = 0;
12454
12483
  let terminalGraphicsClears = 0;
12455
12484
  let terminalGraphicsBytes = 0;
@@ -12504,6 +12533,7 @@ function createStdoutRenderer(terminal, options) {
12504
12533
  wroteClear = appendActiveGraphicProtocolClear(active, visibleRect) || wroteClear;
12505
12534
  if (wroteClear) terminalGraphicsClears++;
12506
12535
  retainedGraphics.delete(id);
12536
+ clearedGraphicCacheIds.add(id);
12507
12537
  terminalResizeDirtyGraphics.delete(id);
12508
12538
  nextActiveGraphics.delete(id);
12509
12539
  nextActiveGraphicSignatures.delete(id);
@@ -12531,7 +12561,10 @@ function createStdoutRenderer(terminal, options) {
12531
12561
  }, clearSequenceNeedsVisibleCell(payload.sequence, payload.protocol)) || wroteClear;
12532
12562
  if (wroteClear) terminalGraphicsClears++;
12533
12563
  if (active && payload.retainOnClear) retainTerminalGraphic(payload.id, active, nextActiveGraphicSignatures.get(payload.id));
12534
- else retainedGraphics.delete(payload.id);
12564
+ else {
12565
+ retainedGraphics.delete(payload.id);
12566
+ clearedGraphicCacheIds.add(payload.id);
12567
+ }
12535
12568
  terminalResizeDirtyGraphics.delete(payload.id);
12536
12569
  nextActiveGraphics.delete(payload.id);
12537
12570
  nextActiveGraphicSignatures.delete(payload.id);
@@ -12618,6 +12651,11 @@ function createStdoutRenderer(terminal, options) {
12618
12651
  for (const [id, signature] of nextActiveGraphicSignatures) activeGraphicSignatures.set(id, signature);
12619
12652
  pendingGraphicSignatures.clear();
12620
12653
  for (const [id, signature] of nextPendingGraphicSignatures) pendingGraphicSignatures.set(id, signature);
12654
+ for (const id of clearedGraphicCacheIds) {
12655
+ if (nextActiveGraphics.has(id) || retainedGraphics.has(id)) continue;
12656
+ validatedGraphicFrames.delete(id);
12657
+ graphicSequenceHashes.delete(id);
12658
+ }
12621
12659
  };
12622
12660
  terminalGraphicsMetrics = {
12623
12661
  draws: terminalGraphicsDraws,
@@ -13206,6 +13244,8 @@ function createStdoutRenderer(terminal, options) {
13206
13244
  pendingGraphicClears.clear();
13207
13245
  pendingGraphicSignatures.clear();
13208
13246
  retainedGraphics.clear();
13247
+ validatedGraphicFrames.clear();
13248
+ graphicSequenceHashes.clear();
13209
13249
  knownKittyImageIds.clear();
13210
13250
  terminalResizeDirtyGraphics.clear();
13211
13251
  try {
@@ -2619,6 +2619,10 @@ function createTerminalGraphicPngSequence(options) {
2619
2619
  );
2620
2620
  crop && (placement = { ...placement, ...crop });
2621
2621
  }
2622
+ let transmissionPlacement = options.cropTransmission !== !1 ? placement : {
2623
+ columns: options.transmissionColumns ?? options.placementColumns,
2624
+ rows: options.transmissionRows ?? options.placementRows
2625
+ };
2622
2626
  return {
2623
2627
  type: "sequence",
2624
2628
  protocol: "kitty",
@@ -2626,7 +2630,7 @@ function createTerminalGraphicPngSequence(options) {
2626
2630
  imageId: options.imageId,
2627
2631
  placementId: options.placementId,
2628
2632
  zIndex: options.zIndex,
2629
- ...placement
2633
+ ...transmissionPlacement
2630
2634
  }),
2631
2635
  resizeSequence: createKittyPlacementSequence({
2632
2636
  imageId: options.imageId,
@@ -2800,6 +2804,7 @@ var tAgentTerminalGraphicProps = {
2800
2804
  suspendRenderWhileScrolling: { type: Boolean, default: !0 },
2801
2805
  scrolling: { type: Boolean, default: !1 },
2802
2806
  scrollVersion: { type: Number, default: 0 },
2807
+ /** Advanced Kitty-only opt-in for moving an unchanged image via a reusable placement sequence. */
2803
2808
  placementMoveWithoutClear: { type: Boolean, default: !1 },
2804
2809
  preserveRawWhileRendering: { type: Boolean, default: !1 },
2805
2810
  suspended: { type: Boolean, default: !1 },
@@ -5,8 +5,8 @@ import { TText, TView, createFrameMailbox, mergeStyle } from "./linkify-CL9wwnZN
5
5
  import "./frame-perf-CHpWhbC4.js";
6
6
  import "./terminal-selection-4W1SJj4c.js";
7
7
  import "./wheel-scroll-DASkEZr-.js";
8
- import { createTerminalGraphicPngSequence, getTerminalGraphicsOutput, getTerminalGraphicsOutputVersion, subscribeTerminalGraphicsOutput } from "./terminal-graphics-DWZrl3oh.js";
9
- import { TAgentTerminalGraphic, TLogLinksPanel, TLogMinimap, TLogScrollbar, TLogSearchBar, TLogSearchPager, TLogSearchResults, TLogView, TLogVirtualLinksPanel, TLogVirtualSearchResults, TTranscriptView, TVirtualList, createAppendOnlyLogStore, createTLogDensityBucketsFromMarkers, createTLogLevelPlugin, createTLogLineMatcherPlugin, createTLogLinkActionPlugin, createTLogOsc8LinkPlugin, createTLogUrlPlugin, detectTLogUrls, dispatchTLogPluginLinkAction, getTLogPluginMetadata, handleTLogKeymapEvent, matchesTLogKeyBinding, parseTLogAnnotatedText, resolveTLogLinksPanelTheme, resolveTLogMinimapTheme, resolveTLogScrollbarTheme, resolveTLogSearchBarTheme, resolveTLogSearchPagerTheme, resolveTLogSearchResultsTheme, resolveTLogViewTheme, stripTLogAnsiText, tlogDarkPreset, tlogDarkTheme, tlogDefaultKeymap, tlogDefaultPreset, tlogDefaultTheme, tlogHighContrastKeymap, tlogHighContrastPreset, tlogHighContrastTheme, toTLogExternalLinkFromVisibleLink, useTLogLinkController, useTLogRetainedIndex, useTLogSearchController, useTLogSearchResultsPage, useTLogVirtualSearchResults } from "./tlog-theme-DqnF_zNe.js";
8
+ import { createTerminalGraphicPngSequence, getTerminalGraphicsOutput, getTerminalGraphicsOutputVersion, subscribeTerminalGraphicsOutput } from "./terminal-graphics-D6KErRBY.js";
9
+ import { TAgentTerminalGraphic, TLogLinksPanel, TLogMinimap, TLogScrollbar, TLogSearchBar, TLogSearchPager, TLogSearchResults, TLogView, TLogVirtualLinksPanel, TLogVirtualSearchResults, TTranscriptView, TVirtualList, createAppendOnlyLogStore, createTLogDensityBucketsFromMarkers, createTLogLevelPlugin, createTLogLineMatcherPlugin, createTLogLinkActionPlugin, createTLogOsc8LinkPlugin, createTLogUrlPlugin, detectTLogUrls, dispatchTLogPluginLinkAction, getTLogPluginMetadata, handleTLogKeymapEvent, matchesTLogKeyBinding, parseTLogAnnotatedText, resolveTLogLinksPanelTheme, resolveTLogMinimapTheme, resolveTLogScrollbarTheme, resolveTLogSearchBarTheme, resolveTLogSearchPagerTheme, resolveTLogSearchResultsTheme, resolveTLogViewTheme, stripTLogAnsiText, tlogDarkPreset, tlogDarkTheme, tlogDefaultKeymap, tlogDefaultPreset, tlogDefaultTheme, tlogHighContrastKeymap, tlogHighContrastPreset, tlogHighContrastTheme, toTLogExternalLinkFromVisibleLink, useTLogLinkController, useTLogRetainedIndex, useTLogSearchController, useTLogSearchResultsPage, useTLogVirtualSearchResults } from "./tlog-theme-DIrlCw6m.js";
10
10
  import { computed, defineComponent, getCurrentInstance, h, inject, markRaw, onBeforeUnmount, onUnmounted, ref, shallowRef, watch } from "vue";
11
11
 
12
12
  //#region src/vue/components/TVideo.ts