{
  "schema": "https://ansicode.eversources.app/dataset.json",
  "generatedAt": "2026-05-27",
  "count": 141,
  "sequences": [
    {
      "slug": "sgr-reset",
      "family": "SGR",
      "title": {
        "en": "SGR 0 — Reset / Normal",
        "zh": "SGR 0 — 重置 / 恢复默认"
      },
      "shortDesc": {
        "en": "Clear all text attributes and colors back to the terminal default.",
        "zh": "清除所有文本属性和颜色，恢复终端默认状态。"
      },
      "bytes": {
        "canonical": "\\x1b[0m",
        "octal": "\\033[0m",
        "eEscape": "\\e[0m",
        "literal": "ESC [ 0 m",
        "hex": "1b 5b 30 6d"
      },
      "description": {
        "en": "`SGR 0` (Select Graphic Rendition with parameter 0) resets every text attribute the terminal is currently tracking — foreground color, background color, bold, italic, underline, reverse video, blink, etc. It is equivalent to `\\x1b[m` (the parameter defaults to 0 when omitted). Always emit this at the end of styled output so the next line of text is not 'colored by leak'.",
        "zh": "`SGR 0`（带参数 0 的 Select Graphic Rendition）会重置终端当前跟踪的每一个文本属性 —— 前景色、背景色、加粗、斜体、下划线、反相、闪烁等。它等价于 `\\x1b[m`（省略参数时默认值为 0）。务必在样式输出结束时发送这一序列，避免下一行文本被「颜色泄漏」污染。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[31merror\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[31merror\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[31merror\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[31merror\\x1b[0m\\n')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[31merror\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-bold",
        "sgr-fg-basic",
        "decstr-soft-reset"
      ]
    },
    {
      "slug": "sgr-bold",
      "family": "SGR",
      "title": {
        "en": "SGR 1 — Bold / Increased intensity",
        "zh": "SGR 1 — 加粗 / 高亮"
      },
      "shortDesc": {
        "en": "Render following text in bold (or bright on some terminals).",
        "zh": "将后续文本渲染为加粗（在某些终端上为高亮色）。"
      },
      "bytes": {
        "canonical": "\\x1b[1m",
        "octal": "\\033[1m",
        "eEscape": "\\e[1m",
        "literal": "ESC [ 1 m",
        "hex": "1b 5b 31 6d"
      },
      "description": {
        "en": "Turns on bold weight on most modern terminals. On older terminals and some retro emulators (Linux console with VGA fonts) this instead brightens the foreground color (mapping color N to color N+8). To turn bold OFF without clearing other attributes, emit `\\x1b[22m` (SGR 22, normal intensity).",
        "zh": "在多数现代终端上启用加粗字重。在较老的终端和一些复古模拟器（如使用 VGA 字体的 Linux console）上，这反而会将前景色变亮（将颜色 N 映射到颜色 N+8）。如需在保留其他属性的前提下关闭加粗，发送 `\\x1b[22m`（SGR 22，普通字重）。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 1)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[1mbold\\033[22m normal\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[1mbold\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[1mbold\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[1mbold\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[1mbold\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-reset",
        "sgr-italic",
        "sgr-underline"
      ]
    },
    {
      "slug": "sgr-dim",
      "family": "SGR",
      "title": {
        "en": "SGR 2 — Dim / Faint",
        "zh": "SGR 2 — 暗淡 / 减弱"
      },
      "shortDesc": {
        "en": "Render following text at reduced intensity (faint).",
        "zh": "以降低亮度（faint/暗淡）渲染后续文本。"
      },
      "bytes": {
        "canonical": "\\x1b[2m",
        "octal": "\\033[2m",
        "eEscape": "\\e[2m",
        "literal": "ESC [ 2 m",
        "hex": "1b 5b 32 6d"
      },
      "description": {
        "en": "Decreases the apparent intensity of the foreground color. On most modern emulators this is implemented as alpha-blending the foreground toward the background (typical ~60% opacity). Disable with `\\x1b[22m` (SGR 22 — normal intensity, also clears bold). Support is broad but visually subtle on light themes; some terminals (Linux console, ConPTY) treat it as a no-op.",
        "zh": "降低前景色的视觉强度。在多数现代终端上通过将前景色向背景色 alpha 混合实现（通常约 60% 不透明度）。使用 `\\x1b[22m`（SGR 22 —— 普通字重，同时清除加粗）关闭。支持广泛但在浅色主题下视觉效果较弱；部分终端（Linux console、ConPTY）视为空操作。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 2)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[2mfaint\\033[22m back\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[2mfaint\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[2mfaint\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[2mfaint\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[2mfaint\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-bold",
        "sgr-reset",
        "sgr-italic"
      ]
    },
    {
      "slug": "sgr-blink",
      "family": "SGR",
      "title": {
        "en": "SGR 5 — Blink (slow)",
        "zh": "SGR 5 — 闪烁（慢速）"
      },
      "shortDesc": {
        "en": "Blink the following text (≤ 150 blinks/minute).",
        "zh": "使后续文本闪烁（≤ 150 次/分钟）。"
      },
      "bytes": {
        "canonical": "\\x1b[5m",
        "octal": "\\033[5m",
        "eEscape": "\\e[5m",
        "literal": "ESC [ 5 m",
        "hex": "1b 5b 35 6d"
      },
      "description": {
        "en": "Slow blink (the spec also defines SGR 6 'rapid blink', > 150/min, which xterm collapses to the same behavior). Disable with `\\x1b[25m`. Most modern terminals honor it; alacritty historically did not blink the cell but rendered the attribute, and many users globally disable blink for accessibility. Avoid for any content that conveys meaning — blink is widely flagged as a vestibular / seizure trigger and may be suppressed by the OS or terminal.",
        "zh": "慢速闪烁（规范同时定义 SGR 6「快速闪烁」，> 150 次/分钟，xterm 等价处理）。使用 `\\x1b[25m` 关闭。多数现代终端支持；历史上 alacritty 不真正闪烁单元格而仅记录属性。许多用户出于无障碍考虑全局禁用闪烁，因此切勿用闪烁承载关键信息 —— 它被广泛标记为前庭/光敏触发因素，可能被系统或终端抑制。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 5)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[5mblink\\033[25m steady\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[5mblink\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[5mblink\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[5mblink\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[5mblink\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "partial",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-reset",
        "sgr-reverse",
        "sgr-hidden"
      ]
    },
    {
      "slug": "sgr-hidden",
      "family": "SGR",
      "title": {
        "en": "SGR 8 — Conceal / Hidden",
        "zh": "SGR 8 — 隐藏 / 不可见"
      },
      "shortDesc": {
        "en": "Render following text invisibly (cursor still advances).",
        "zh": "将后续文本渲染为不可见（光标仍前进）。"
      },
      "bytes": {
        "canonical": "\\x1b[8m",
        "octal": "\\033[8m",
        "eEscape": "\\e[8m",
        "literal": "ESC [ 8 m",
        "hex": "1b 5b 38 6d"
      },
      "description": {
        "en": "Sets the foreground to be visually identical to the background — the text still occupies cells and is preserved by `select-all`/copy. Useful for spoiler tags or password-style display, but NOT a security primitive: the text is copyable. Disable with `\\x1b[28m`. Most modern terminals honor it; Linux console and ConPTY treat it as a no-op.",
        "zh": "将前景色设为与背景色视觉一致 —— 文本仍占据单元格，并可通过 `全选`/复制 保留。可用于剧透标签或类似密码风格的隐藏显示，但**不是**安全特性：文本可被复制。使用 `\\x1b[28m` 关闭。多数现代终端支持；Linux console 与 ConPTY 视为空操作。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 8)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf 'password: \\033[8mhunter2\\033[28m (select to reveal)\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[8mhidden\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[8mhidden\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[8mhidden\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[8mhidden\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-reverse",
        "sgr-reset",
        "sgr-blink"
      ]
    },
    {
      "slug": "sgr-strikethrough",
      "family": "SGR",
      "title": {
        "en": "SGR 9 — Strikethrough",
        "zh": "SGR 9 — 删除线"
      },
      "shortDesc": {
        "en": "Render following text with a horizontal line through it.",
        "zh": "在后续文本中央绘制一条水平删除线。"
      },
      "bytes": {
        "canonical": "\\x1b[9m",
        "octal": "\\033[9m",
        "eEscape": "\\e[9m",
        "literal": "ESC [ 9 m",
        "hex": "1b 5b 39 6d"
      },
      "description": {
        "en": "ECMA-48 calls this 'crossed-out'. Disable with `\\x1b[29m`. Supported by most modern emulators (xterm, iTerm2, kitty, alacritty, wezterm, Windows Terminal, gnome-terminal, konsole, Ghostty). Linux console and traditional cmd.exe ignore it. Commonly used to mark deleted lines in diff renderers and crossed-out items in TODO/CLI lists.",
        "zh": "ECMA-48 称其为「crossed-out」。使用 `\\x1b[29m` 关闭。多数现代终端支持（xterm、iTerm2、kitty、alacritty、wezterm、Windows Terminal、gnome-terminal、konsole、Ghostty）。Linux console 与传统 cmd.exe 忽略。常用于 diff 渲染器中标记删除行、TODO/CLI 列表中划掉条目。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 9)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[9mdeleted line\\033[29m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[9mdeleted\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[9mdeleted\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[9mdeleted\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[9mdeleted\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-underline",
        "sgr-italic",
        "sgr-reset"
      ]
    },
    {
      "slug": "sgr-default-fg",
      "family": "SGR",
      "title": {
        "en": "SGR 39 — Default foreground color",
        "zh": "SGR 39 — 默认前景色"
      },
      "shortDesc": {
        "en": "Reset only the foreground color (leaves attributes + bg intact).",
        "zh": "仅重置前景色（保留其他属性与背景色）。"
      },
      "bytes": {
        "canonical": "\\x1b[39m",
        "octal": "\\033[39m",
        "eEscape": "\\e[39m",
        "literal": "ESC [ 3 9 m",
        "hex": "1b 5b 33 39 6d"
      },
      "description": {
        "en": "Resets the foreground to the terminal's theme default without disturbing the background, bold/italic/underline, or other SGR state. The complement of `\\x1b[49m` (default background). Useful when you want to switch fg colors mid-line without emitting a full SGR 0 reset and re-applying every attribute.",
        "zh": "将前景色恢复为终端主题默认值，不影响背景色、加粗/斜体/下划线或其他 SGR 状态。与 `\\x1b[49m`（默认背景色）相对。需要在中途切换前景色而不想发送完整 SGR 0 再重新应用所有属性时尤其有用。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 39)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[1;31mERROR\\033[39m bold continues\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[31mred\\x1b[39m default\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[31mred\\x1b[39m default\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[31mred\\x1b[39m default\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[31mred\\x1b[39m default\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-fg-basic",
        "sgr-default-bg",
        "sgr-reset"
      ]
    },
    {
      "slug": "sgr-default-bg",
      "family": "SGR",
      "title": {
        "en": "SGR 49 — Default background color",
        "zh": "SGR 49 — 默认背景色"
      },
      "shortDesc": {
        "en": "Reset only the background color (leaves attributes + fg intact).",
        "zh": "仅重置背景色（保留其他属性与前景色）。"
      },
      "bytes": {
        "canonical": "\\x1b[49m",
        "octal": "\\033[49m",
        "eEscape": "\\e[49m",
        "literal": "ESC [ 4 9 m",
        "hex": "1b 5b 34 39 6d"
      },
      "description": {
        "en": "Restores the background to the terminal's theme default without disturbing the foreground, bold/italic/underline, or other SGR state. The complement of `\\x1b[39m` (default foreground). Commonly used to end a 'banner' line (colored background) and return to the normal terminal background without resetting text color.",
        "zh": "将背景色恢复为终端主题默认值，不影响前景色、加粗/斜体/下划线或其他 SGR 状态。与 `\\x1b[39m`（默认前景色）相对。常用于结束「条幅」行（带色背景）并返回正常终端背景，同时保留文本色。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 49)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[41;37m WARNING \\033[49m text\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[41mred bg\\x1b[49m default bg\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[41mred bg\\x1b[49m default bg\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[41mred bg\\x1b[49m default bg\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[41mred bg\\x1b[49m default bg\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-bg-basic",
        "sgr-default-fg",
        "sgr-reset"
      ]
    },
    {
      "slug": "sgr-bg-256",
      "family": "SGR",
      "title": {
        "en": "SGR 48;5;n — 256-color background",
        "zh": "SGR 48;5;n — 256 色背景"
      },
      "shortDesc": {
        "en": "Pick a background color from the 256-color xterm palette.",
        "zh": "从 xterm 256 色调色板中选择背景色。"
      },
      "bytes": {
        "canonical": "\\x1b[48;5;Nm",
        "octal": "\\033[48;5;Nm",
        "eEscape": "\\e[48;5;Nm",
        "literal": "ESC [ 4 8 ; 5 ; N m",
        "hex": "1b 5b 34 38 3b 35 3b <N> 6d"
      },
      "description": {
        "en": "Background sibling of `\\x1b[38;5;Nm`. N is 0–255 with the same palette layout: 0–7 basic, 8–15 bright, 16–231 a 6×6×6 RGB cube (`16 + 36*r + 6*g + b`), 232–255 a 24-step grayscale ramp. The colon sub-parameter form `\\x1b[48:5:Nm` is also accepted by ECMA-48-strict parsers. Reset just the background with `\\x1b[49m`.",
        "zh": "`\\x1b[38;5;Nm` 的背景版本。N 取 0–255，调色板布局相同：0–7 基础色，8–15 高亮色，16–231 为 6×6×6 RGB 立方体（公式 `16 + 36*r + 6*g + b`），232–255 为 24 级灰阶。冒号子参数形式 `\\x1b[48:5:Nm` 也被严格遵循 ECMA-48 的解析器接受。仅重置背景使用 `\\x1b[49m`。"
      },
      "spec": "xterm-ctlseqs (256-color extension)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[48;5;202m highlight \\033[49m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[48;5;202m highlight \\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[48;5;202m highlight \\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[48;5;202m highlight \\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[48;5;202m highlight \\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-fg-256",
        "sgr-bg-truecolor",
        "sgr-bg-basic"
      ]
    },
    {
      "slug": "sgr-bg-truecolor",
      "family": "SGR",
      "title": {
        "en": "SGR 48;2;R;G;B — 24-bit truecolor background",
        "zh": "SGR 48;2;R;G;B — 24 位真彩色背景"
      },
      "shortDesc": {
        "en": "Pick any of 16,777,216 background RGB colors directly.",
        "zh": "直接指定 16,777,216 种 RGB 背景色之一。"
      },
      "bytes": {
        "canonical": "\\x1b[48;2;R;G;Bm",
        "octal": "\\033[48;2;R;G;Bm",
        "eEscape": "\\e[48;2;R;G;Bm",
        "literal": "ESC [ 4 8 ; 2 ; R ; G ; B m",
        "hex": "1b 5b 34 38 3b 32 3b ... 6d"
      },
      "description": {
        "en": "Background sibling of `\\x1b[38;2;R;G;Bm`. R, G, B are each 0–255. The ECMA-48-compliant colon form `\\x1b[48:2::R:G:Bm` (empty 4th sub-parameter = colorspace ID) is accepted alongside the more common semicolon form. Check `$COLORTERM=truecolor` (or `24bit`) before emitting in cross-environment tools — terminals lacking truecolor will quantize to 256-color, which may or may not look acceptable.",
        "zh": "`\\x1b[38;2;R;G;Bm` 的背景版本。R、G、B 各取 0–255。除了常用的分号写法，也支持符合 ECMA-48 的冒号形式 `\\x1b[48:2::R:G:Bm`（第 4 个子参数为空，表示色彩空间 ID）。跨环境工具发送前应检查 `$COLORTERM=truecolor`（或 `24bit`） —— 不支持真彩色的终端会量化为 256 色，效果未必可接受。"
      },
      "spec": "ITU-T T.416 / xterm-ctlseqs (Direct color)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[48;2;30;30;30;38;2;255;200;0m on graphite \\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[48;2;30;30;30m bg \\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[48;2;30;30;30m bg \\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[48;2;30;30;30m bg \\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[48;2;30;30;30m bg \\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-fg-truecolor",
        "sgr-bg-256",
        "sgr-bg-basic"
      ]
    },
    {
      "slug": "sgr-italic",
      "family": "SGR",
      "title": {
        "en": "SGR 3 — Italic",
        "zh": "SGR 3 — 斜体"
      },
      "shortDesc": {
        "en": "Render following text in italic; not universally supported.",
        "zh": "将后续文本渲染为斜体；并非所有终端都支持。"
      },
      "bytes": {
        "canonical": "\\x1b[3m",
        "octal": "\\033[3m",
        "eEscape": "\\e[3m",
        "literal": "ESC [ 3 m",
        "hex": "1b 5b 33 6d"
      },
      "description": {
        "en": "Italic is the most fragile of the basic SGR attributes. xterm, iTerm2, kitty, alacritty, wezterm, Windows Terminal and modern gnome-terminal/konsole all honor it. The Linux console, traditional cmd.exe, and ConPTY treat it as a no-op. Some terminals reuse the bit for reverse video on monochrome displays. Disable with `\\x1b[23m`.",
        "zh": "斜体是基础 SGR 属性中支持最不稳定的一个。xterm、iTerm2、kitty、alacritty、wezterm、Windows Terminal 以及现代的 gnome-terminal/konsole 都能正确显示。Linux console、传统 cmd.exe 和 ConPTY 会将其视为空操作。部分单色终端会将此位重新用于反相。关闭斜体使用 `\\x1b[23m`。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 3)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[3mitalic\\033[23m back\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[3mitalic\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[3mitalic\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[3mitalic\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[3mitalic\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-bold",
        "sgr-underline",
        "sgr-reset"
      ]
    },
    {
      "slug": "sgr-underline",
      "family": "SGR",
      "title": {
        "en": "SGR 4 — Underline",
        "zh": "SGR 4 — 下划线"
      },
      "shortDesc": {
        "en": "Render following text with an underline.",
        "zh": "为后续文本添加下划线。"
      },
      "bytes": {
        "canonical": "\\x1b[4m",
        "octal": "\\033[4m",
        "eEscape": "\\e[4m",
        "literal": "ESC [ 4 m",
        "hex": "1b 5b 34 6d"
      },
      "description": {
        "en": "Single underline. Kitty introduced extensions for styled underlines: `\\x1b[4:1m` (single), `4:2m` (double), `4:3m` (curly), `4:4m` (dotted), `4:5m` (dashed); colored underline via `\\x1b[58;5;Nm` or `\\x1b[58;2;R;G;Bm`. Disable underline with `\\x1b[24m`. The double-underline pattern `\\x1b[21m` is recognized by xterm and most modern terminals (originally SGR 21 meant 'doubly underlined' in ECMA-48; some terminals interpret it as 'bold off').",
        "zh": "单下划线。Kitty 引入了下划线样式扩展：`\\x1b[4:1m`（单线）、`4:2m`（双线）、`4:3m`（波浪线）、`4:4m`（点线）、`4:5m`（虚线）；通过 `\\x1b[58;5;Nm` 或 `\\x1b[58;2;R;G;Bm` 设置下划线颜色。关闭下划线使用 `\\x1b[24m`。`\\x1b[21m` 双下划线在 xterm 和多数现代终端中受支持（ECMA-48 中 SGR 21 原意为「双下划线」，部分终端解释为「关闭加粗」）。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 4); kitty underline extensions",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[4munderline\\033[24m back\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[4munderline\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[4munderline\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[4munderline\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[4munderline\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-bold",
        "sgr-italic",
        "sgr-double-underline"
      ]
    },
    {
      "slug": "sgr-reverse",
      "family": "SGR",
      "title": {
        "en": "SGR 7 — Reverse video",
        "zh": "SGR 7 — 反相显示"
      },
      "shortDesc": {
        "en": "Swap foreground and background colors.",
        "zh": "交换前景色与背景色。"
      },
      "bytes": {
        "canonical": "\\x1b[7m",
        "octal": "\\033[7m",
        "eEscape": "\\e[7m",
        "literal": "ESC [ 7 m",
        "hex": "1b 5b 37 6d"
      },
      "description": {
        "en": "Swaps the current foreground and background colors. Universally supported across xterm, Linux console, cmd, every Mac/Linux terminal, and Windows Terminal. Disable with `\\x1b[27m`. Often used by status bars and selection highlighting; combine with explicit fg/bg if you want the highlighted color to be consistent across terminal themes.",
        "zh": "交换当前的前景色与背景色。在 xterm、Linux console、cmd、所有 Mac/Linux 终端以及 Windows Terminal 上都得到一致支持。关闭反相使用 `\\x1b[27m`。常用于状态栏和选区高亮；如希望高亮色在不同终端主题下保持一致，请显式设置前景/背景色。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 7)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[7m highlighted \\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[7m highlighted \\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[7m highlighted \\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[7m highlighted \\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[7m highlighted \\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-fg-basic",
        "sgr-bg-basic",
        "sgr-reset"
      ]
    },
    {
      "slug": "sgr-fg-basic",
      "family": "SGR",
      "title": {
        "en": "SGR 30–37 — Foreground color (8 basic)",
        "zh": "SGR 30–37 — 前景色（8 种基础色）"
      },
      "shortDesc": {
        "en": "Set foreground to one of black/red/green/yellow/blue/magenta/cyan/white.",
        "zh": "将前景色设置为 黑/红/绿/黄/蓝/品红/青/白 中的一种。"
      },
      "bytes": {
        "canonical": "\\x1b[31m   (red, similarly 30–37)",
        "octal": "\\033[31m",
        "eEscape": "\\e[31m",
        "literal": "ESC [ 3 1 m",
        "hex": "1b 5b 33 31 6d"
      },
      "description": {
        "en": "The 8 basic foreground colors: 30 black, 31 red, 32 green, 33 yellow, 34 blue, 35 magenta, 36 cyan, 37 white. SGR 39 resets the foreground to the terminal default without touching the background. The actual rendered RGB is theme-dependent — there is no canonical RGB for 'ANSI red'. To pick a specific RGB, use truecolor (SGR 38;2;…).",
        "zh": "8 种基础前景色：30 黑、31 红、32 绿、33 黄、34 蓝、35 品红、36 青、37 白。SGR 39 仅将前景色重置为终端默认值，而不影响背景色。实际渲染的 RGB 由主题决定 —— 不存在「ANSI 红」的标准 RGB。如需精确 RGB，请使用真彩色（SGR 38;2;…）。"
      },
      "parameters": [
        {
          "name": "30",
          "desc": {
            "en": "black",
            "zh": "黑"
          }
        },
        {
          "name": "31",
          "desc": {
            "en": "red",
            "zh": "红"
          }
        },
        {
          "name": "32",
          "desc": {
            "en": "green",
            "zh": "绿"
          }
        },
        {
          "name": "33",
          "desc": {
            "en": "yellow",
            "zh": "黄"
          }
        },
        {
          "name": "34",
          "desc": {
            "en": "blue",
            "zh": "蓝"
          }
        },
        {
          "name": "35",
          "desc": {
            "en": "magenta",
            "zh": "品红"
          }
        },
        {
          "name": "36",
          "desc": {
            "en": "cyan",
            "zh": "青"
          }
        },
        {
          "name": "37",
          "desc": {
            "en": "white",
            "zh": "白"
          }
        },
        {
          "name": "39",
          "desc": {
            "en": "default foreground",
            "zh": "默认前景色"
          }
        }
      ],
      "spec": "ECMA-48 §8.3.117 (SGR parameters 30–37, 39)",
      "examples": [
        {
          "lang": "bash",
          "code": "for c in 30 31 32 33 34 35 36 37; do printf \"\\033[${c}m■\\033[0m\"; done; echo"
        },
        {
          "lang": "python",
          "code": "for c in range(30, 38): print(f'\\x1b[{c}m{c}\\x1b[0m', end=' ')"
        },
        {
          "lang": "go",
          "code": "for c := 30; c <= 37; c++ { fmt.Printf(\"\\x1b[%dm%d\\x1b[0m \", c, c) }"
        },
        {
          "lang": "javascript",
          "code": "for (let c = 30; c <= 37; c++) process.stdout.write(`\\x1b[${c}m${c}\\x1b[0m `)"
        },
        {
          "lang": "c",
          "code": "for (int c = 30; c <= 37; c++) printf(\"\\x1b[%dm%d\\x1b[0m \", c, c);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-bg-basic",
        "sgr-fg-bright",
        "sgr-fg-256",
        "sgr-fg-truecolor"
      ]
    },
    {
      "slug": "sgr-bg-basic",
      "family": "SGR",
      "title": {
        "en": "SGR 40–47 — Background color (8 basic)",
        "zh": "SGR 40–47 — 背景色（8 种基础色）"
      },
      "shortDesc": {
        "en": "Set background to one of black/red/green/yellow/blue/magenta/cyan/white.",
        "zh": "将背景色设置为 黑/红/绿/黄/蓝/品红/青/白 中的一种。"
      },
      "bytes": {
        "canonical": "\\x1b[41m   (red bg, 40–47)",
        "octal": "\\033[41m",
        "eEscape": "\\e[41m",
        "literal": "ESC [ 4 1 m",
        "hex": "1b 5b 34 31 6d"
      },
      "description": {
        "en": "Background equivalents of 30–37. 40 black, 41 red, 42 green, 43 yellow, 44 blue, 45 magenta, 46 cyan, 47 white. SGR 49 resets the background to the terminal default. Like the foreground, the rendered RGB depends on the terminal color scheme.",
        "zh": "30–37 的背景色版本。40 黑、41 红、42 绿、43 黄、44 蓝、45 品红、46 青、47 白。SGR 49 将背景色重置为终端默认值。与前景色一样，实际 RGB 取决于终端配色方案。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameters 40–47, 49)",
      "examples": [
        {
          "lang": "bash",
          "code": "for c in 40 41 42 43 44 45 46 47; do printf \"\\033[${c}m  \\033[0m\"; done; echo"
        },
        {
          "lang": "python",
          "code": "for c in range(40, 48): print(f'\\x1b[{c}m  \\x1b[0m', end='')"
        },
        {
          "lang": "go",
          "code": "for c := 40; c <= 47; c++ { fmt.Printf(\"\\x1b[%dm  \\x1b[0m\", c) }"
        },
        {
          "lang": "javascript",
          "code": "for (let c = 40; c <= 47; c++) process.stdout.write(`\\x1b[${c}m  \\x1b[0m`)"
        },
        {
          "lang": "c",
          "code": "for (int c = 40; c <= 47; c++) printf(\"\\x1b[%dm  \\x1b[0m\", c);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-fg-basic",
        "sgr-bg-bright",
        "sgr-bg-256"
      ]
    },
    {
      "slug": "sgr-fg-bright",
      "family": "SGR",
      "title": {
        "en": "SGR 90–97 — Bright foreground color",
        "zh": "SGR 90–97 — 高亮前景色"
      },
      "shortDesc": {
        "en": "Bright variants of the 8 basic foreground colors (aixterm/xterm extension).",
        "zh": "8 种基础前景色的高亮变体（aixterm/xterm 扩展）。"
      },
      "bytes": {
        "canonical": "\\x1b[91m   (bright red, 90–97)",
        "octal": "\\033[91m",
        "eEscape": "\\e[91m",
        "literal": "ESC [ 9 1 m",
        "hex": "1b 5b 39 31 6d"
      },
      "description": {
        "en": "Non-standard but ubiquitously supported aixterm extension that exposes the upper 8 of the original 16-color palette as their own SGR parameters. 90 bright black (gray), 91 bright red, ..., 97 bright white. Equivalent to combining `\\x1b[1m` + a basic color on terminals that use bold-as-bright; on modern terminals the two paths render differently and bright codes are preferred.",
        "zh": "非标准但被广泛支持的 aixterm 扩展，将原 16 色调色板的高 8 色作为独立的 SGR 参数。90 亮黑（灰）、91 亮红、……、97 亮白。在使用「加粗即高亮」策略的终端上，这等价于 `\\x1b[1m` 加基础色；在现代终端上两者渲染不同，建议优先使用高亮码。"
      },
      "spec": "aixterm color extension (xterm-ctlseqs)",
      "examples": [
        {
          "lang": "bash",
          "code": "for c in 90 91 92 93 94 95 96 97; do printf \"\\033[${c}m■\\033[0m\"; done; echo"
        },
        {
          "lang": "python",
          "code": "for c in range(90, 98): print(f'\\x1b[{c}m■\\x1b[0m', end='')"
        },
        {
          "lang": "go",
          "code": "for c := 90; c <= 97; c++ { fmt.Printf(\"\\x1b[%dm■\\x1b[0m\", c) }"
        },
        {
          "lang": "javascript",
          "code": "for (let c = 90; c <= 97; c++) process.stdout.write(`\\x1b[${c}m■\\x1b[0m`)"
        },
        {
          "lang": "c",
          "code": "for (int c = 90; c <= 97; c++) printf(\"\\x1b[%dm■\\x1b[0m\", c);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-fg-basic",
        "sgr-bg-bright",
        "sgr-fg-256"
      ]
    },
    {
      "slug": "sgr-bg-bright",
      "family": "SGR",
      "title": {
        "en": "SGR 100–107 — Bright background color",
        "zh": "SGR 100–107 — 高亮背景色"
      },
      "shortDesc": {
        "en": "Bright variants of the 8 basic background colors.",
        "zh": "8 种基础背景色的高亮变体。"
      },
      "bytes": {
        "canonical": "\\x1b[101m   (bright red bg, 100–107)",
        "octal": "\\033[101m",
        "eEscape": "\\e[101m",
        "literal": "ESC [ 1 0 1 m",
        "hex": "1b 5b 31 30 31 6d"
      },
      "description": {
        "en": "Bright background equivalents of 40–47. 100 bright black, 101 bright red, ..., 107 bright white. Same aixterm extension as 90–97 for foreground.",
        "zh": "40–47 的高亮背景版本。100 亮黑、101 亮红、……、107 亮白。与前景 90–97 同属 aixterm 扩展。"
      },
      "spec": "aixterm color extension",
      "examples": [
        {
          "lang": "bash",
          "code": "for c in 100 101 102 103 104 105 106 107; do printf \"\\033[${c}m  \\033[0m\"; done; echo"
        },
        {
          "lang": "python",
          "code": "for c in range(100, 108): print(f'\\x1b[{c}m  \\x1b[0m', end='')"
        },
        {
          "lang": "go",
          "code": "for c := 100; c <= 107; c++ { fmt.Printf(\"\\x1b[%dm  \\x1b[0m\", c) }"
        },
        {
          "lang": "javascript",
          "code": "for (let c = 100; c <= 107; c++) process.stdout.write(`\\x1b[${c}m  \\x1b[0m`)"
        },
        {
          "lang": "c",
          "code": "for (int c = 100; c <= 107; c++) printf(\"\\x1b[%dm  \\x1b[0m\", c);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-bg-basic",
        "sgr-fg-bright",
        "sgr-bg-256"
      ]
    },
    {
      "slug": "sgr-fg-256",
      "family": "SGR",
      "title": {
        "en": "SGR 38;5;n — 256-color foreground",
        "zh": "SGR 38;5;n — 256 色前景"
      },
      "shortDesc": {
        "en": "Pick a foreground color from the 256-color xterm palette.",
        "zh": "从 xterm 256 色调色板中选择前景色。"
      },
      "bytes": {
        "canonical": "\\x1b[38;5;Nm",
        "octal": "\\033[38;5;Nm",
        "eEscape": "\\e[38;5;Nm",
        "literal": "ESC [ 3 8 ; 5 ; N m",
        "hex": "1b 5b 33 38 3b 35 3b <N> 6d"
      },
      "description": {
        "en": "N is 0–255. 0–7 map to the 8 basic colors, 8–15 to the bright variants, 16–231 form a 6×6×6 RGB cube (`16 + 36*r + 6*g + b` for r,g,b in 0–5), and 232–255 form a 24-step grayscale ramp. Background equivalent: `\\x1b[48;5;Nm`. Older subterminals also accept the colon form `\\x1b[38:5:Nm` (per ECMA-48 sub-parameter separator).",
        "zh": "N 取 0–255。0–7 对应 8 种基础色，8–15 对应高亮变体，16–231 构成 6×6×6 RGB 立方体（公式 `16 + 36*r + 6*g + b`，r/g/b 取 0–5），232–255 是 24 级灰阶。背景等价形式：`\\x1b[48;5;Nm`。部分老终端也接受冒号形式 `\\x1b[38:5:Nm`（符合 ECMA-48 子参数分隔符规范）。"
      },
      "spec": "xterm-ctlseqs (256-color extension)",
      "examples": [
        {
          "lang": "bash",
          "code": "for n in 16 51 196 226 51 21 201; do printf \"\\033[38;5;${n}m■\\033[0m\"; done; echo"
        },
        {
          "lang": "python",
          "code": "for n in [16, 196, 226, 21, 51, 201]: print(f'\\x1b[38;5;{n}m■\\x1b[0m', end='')"
        },
        {
          "lang": "go",
          "code": "for _, n := range []int{16,196,226,21,51,201} { fmt.Printf(\"\\x1b[38;5;%dm■\\x1b[0m\", n) }"
        },
        {
          "lang": "javascript",
          "code": "[16,196,226,21,51,201].forEach(n => process.stdout.write(`\\x1b[38;5;${n}m■\\x1b[0m`))"
        },
        {
          "lang": "c",
          "code": "int n[] = {16,196,226,21,51,201}; for (int i=0;i<6;i++) printf(\"\\x1b[38;5;%dm■\\x1b[0m\", n[i]);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-fg-basic",
        "sgr-fg-truecolor",
        "sgr-bg-256"
      ]
    },
    {
      "slug": "sgr-fg-truecolor",
      "family": "SGR",
      "title": {
        "en": "SGR 38;2;R;G;B — 24-bit truecolor foreground",
        "zh": "SGR 38;2;R;G;B — 24 位真彩色前景"
      },
      "shortDesc": {
        "en": "Pick any of 16,777,216 foreground RGB colors directly.",
        "zh": "直接指定 16,777,216 种 RGB 前景色之一。"
      },
      "bytes": {
        "canonical": "\\x1b[38;2;R;G;Bm",
        "octal": "\\033[38;2;R;G;Bm",
        "eEscape": "\\e[38;2;R;G;Bm",
        "literal": "ESC [ 3 8 ; 2 ; R ; G ; B m",
        "hex": "1b 5b 33 38 3b 32 3b ... 6d"
      },
      "description": {
        "en": "R, G, B are each 0–255. Background equivalent: `\\x1b[48;2;R;G;Bm`. Many parsers accept either the semicolon form (xterm/legacy) or the ECMA-48-compliant colon form `\\x1b[38:2::R:G:Bm` (note the empty 4th sub-parameter for the colorspace ID). Truecolor is the right default for modern emulators; check `$COLORTERM=truecolor` or `24bit` before emitting in cross-environment tools.",
        "zh": "R、G、B 各取 0–255。背景等价形式：`\\x1b[48;2;R;G;Bm`。许多解析器同时接受分号格式（xterm/传统形式）与符合 ECMA-48 的冒号格式 `\\x1b[38:2::R:G:Bm`（注意第 4 个子参数为空，表示色彩空间 ID）。在现代终端上真彩色是合适的默认；跨环境工具发送前应检查 `$COLORTERM=truecolor` 或 `24bit`。"
      },
      "spec": "ITU-T T.416 / xterm-ctlseqs (Direct color)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[38;2;255;128;0morange\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[38;2;255;128;0morange\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[38;2;255;128;0morange\\x1b[0m\\n\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[38;2;255;128;0morange\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[38;2;255;128;0morange\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-fg-256",
        "sgr-fg-basic",
        "sgr-bg-truecolor"
      ]
    },
    {
      "slug": "cursor-move",
      "family": "CSI",
      "title": {
        "en": "CUU / CUD / CUF / CUB — Move cursor",
        "zh": "CUU / CUD / CUF / CUB — 移动光标"
      },
      "shortDesc": {
        "en": "Move the cursor up / down / right / left by N cells.",
        "zh": "将光标向上 / 下 / 右 / 左 移动 N 格。"
      },
      "bytes": {
        "canonical": "\\x1b[NA   (up; B down, C right, D left)",
        "octal": "\\033[1A",
        "eEscape": "\\e[1A",
        "literal": "ESC [ N A",
        "hex": "1b 5b <N> 41"
      },
      "description": {
        "en": "Final byte determines direction: `A`=up (CUU), `B`=down (CUD), `C`=forward/right (CUF), `D`=back/left (CUB). N defaults to 1 if omitted (`\\x1b[A` moves up one line). The cursor stops at the edge of the visible region; it does NOT wrap.",
        "zh": "末字节决定方向：`A`=上（CUU）、`B`=下（CUD）、`C`=向前/右（CUF）、`D`=向后/左（CUB）。省略 N 时默认为 1（`\\x1b[A` 向上移动一行）。光标会在可视区域边缘停下，不会环绕。"
      },
      "parameters": [
        {
          "name": "A",
          "desc": {
            "en": "up by N",
            "zh": "向上 N 格"
          }
        },
        {
          "name": "B",
          "desc": {
            "en": "down by N",
            "zh": "向下 N 格"
          }
        },
        {
          "name": "C",
          "desc": {
            "en": "right by N",
            "zh": "向右 N 格"
          }
        },
        {
          "name": "D",
          "desc": {
            "en": "left by N",
            "zh": "向左 N 格"
          }
        }
      ],
      "spec": "ECMA-48 §8.3.22 (CUU) / §8.3.19 (CUD) / §8.3.20 (CUF) / §8.3.18 (CUB)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf 'line1\\nline2\\033[1A\\rCHANGED\\033[1B\\r\\n'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[2A')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[2A\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[2A')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[2A\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-position",
        "cursor-save-restore",
        "cursor-next-prev-line"
      ]
    },
    {
      "slug": "cursor-next-prev-line",
      "family": "CSI",
      "title": {
        "en": "CNL / CPL — Cursor next / previous line",
        "zh": "CNL / CPL — 光标下/上行"
      },
      "shortDesc": {
        "en": "Move the cursor to column 1 of the line N below (CNL) or above (CPL).",
        "zh": "将光标移动到下方（CNL）或上方（CPL）第 N 行的第 1 列。"
      },
      "bytes": {
        "canonical": "\\x1b[NE   (down N lines, col 1)   \\x1b[NF   (up)",
        "octal": "\\033[E / \\033[F",
        "eEscape": "\\e[E / \\e[F",
        "literal": "ESC [ N E / F",
        "hex": "1b 5b <N> 45 / 46"
      },
      "description": {
        "en": "Final byte `E` = CNL (Cursor Next Line), `F` = CPL (Cursor Previous Line). Both move N rows (defaulting to 1 if omitted) AND reset the column to 1 — unlike CUU/CUD which preserve the column. Equivalent to a CRLF for `E` if you don't care about scroll-region semantics, but CNL respects scrolling regions and never auto-scrolls past the bottom of the region.",
        "zh": "末字节 `E` = CNL（Cursor Next Line），`F` = CPL（Cursor Previous Line）。两者均按 N 行（省略时默认为 1）移动光标，并将列重置为 1 —— 与 CUU/CUD 保留列位不同。在不关心滚动区域语义时，`E` 类似于 CRLF；但 CNL 遵守滚动区域，永远不会自动滚动越过区域底部。"
      },
      "spec": "ECMA-48 §8.3.13 (CNL) / §8.3.27 (CPL)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf 'top\\n\\033[2Ebottom-of-3rd-line-below\\n'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[3E')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[3E\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[3E')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[3E\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-move",
        "cursor-position",
        "cursor-column"
      ]
    },
    {
      "slug": "cursor-column",
      "family": "CSI",
      "title": {
        "en": "CHA — Cursor horizontal absolute (column)",
        "zh": "CHA — 光标水平绝对位置（列）"
      },
      "shortDesc": {
        "en": "Move the cursor to column N of the current row (1-indexed).",
        "zh": "将光标移动到当前行的第 N 列（从 1 开始）。"
      },
      "bytes": {
        "canonical": "\\x1b[NG",
        "octal": "\\033[1G",
        "eEscape": "\\e[1G",
        "literal": "ESC [ N G",
        "hex": "1b 5b <N> 47"
      },
      "description": {
        "en": "Final byte `G` = CHA (Cursor Horizontal Absolute). Sets the column without changing the row; N defaults to 1. Commonly paired with EL (`\\x1b[K`) to redraw the current line: `\\x1b[1G\\x1b[K` jumps to column 1 and clears to end — equivalent to `\\r\\x1b[K` for most CRLF terminals but cleanly avoids any line-feed semantics. HPA (`\\x1b[N\\``, final-byte `` ` ``) is the ECMA-48 synonym; both are widely supported.",
        "zh": "末字节 `G` = CHA（Cursor Horizontal Absolute）。仅设置列位置，不影响行；N 省略时默认为 1。常与 EL（`\\x1b[K`）配合用于重绘当前行：`\\x1b[1G\\x1b[K` 跳到第 1 列并清到行尾 —— 对多数 CRLF 终端等价于 `\\r\\x1b[K`，但完全避免任何换行语义。HPA（`\\x1b[N\\``，末字节 `` ` ``）是 ECMA-48 同义形式；两者均被广泛支持。"
      },
      "spec": "ECMA-48 §8.3.9 (CHA)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf 'progress:\\033[20G50%%\\033[1G' "
        },
        {
          "lang": "python",
          "code": "print('\\x1b[20G50%')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[20G50%\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[20G50%')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[20G50%%\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-position",
        "cursor-next-prev-line",
        "erase-line"
      ]
    },
    {
      "slug": "cursor-position",
      "family": "CSI",
      "title": {
        "en": "CUP — Set cursor position",
        "zh": "CUP — 设置光标位置"
      },
      "shortDesc": {
        "en": "Move the cursor to absolute row/column (1-indexed).",
        "zh": "将光标移动到绝对行/列（从 1 开始）。"
      },
      "bytes": {
        "canonical": "\\x1b[row;colH",
        "octal": "\\033[1;1H",
        "eEscape": "\\e[1;1H",
        "literal": "ESC [ row ; col H",
        "hex": "1b 5b ... 48"
      },
      "description": {
        "en": "Both `H` (CUP) and `f` (HVP) are synonyms — same behavior. Row and column are 1-based; omitting both defaults to (1,1), i.e. the top-left of the screen or scrolling region. Out-of-range values are clamped to the visible region.",
        "zh": "`H`（CUP）与 `f`（HVP）行为等价。行列从 1 开始计数；同时省略两者时默认为 (1,1)，即屏幕或滚动区域的左上角。超出范围的值会被钳制到可视区域内。"
      },
      "spec": "ECMA-48 §8.3.21 (CUP)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[2;5HHello at (2,5)\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[2;5HHello at (2,5)')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[2;5HHello at (2,5)\\n\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[2;5HHello at (2,5)\\n')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[2;5HHello at (2,5)\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-move",
        "cursor-save-restore",
        "csi-hvp"
      ]
    },
    {
      "slug": "cursor-save-restore",
      "family": "DEC",
      "title": {
        "en": "DECSC / DECRC — Save and restore cursor",
        "zh": "DECSC / DECRC — 保存与恢复光标"
      },
      "shortDesc": {
        "en": "Push and pop the cursor state (position + attributes).",
        "zh": "保存并恢复光标状态（位置 + 属性）。"
      },
      "bytes": {
        "canonical": "\\x1b7   (save)   \\x1b8   (restore)",
        "octal": "\\0337 / \\0338",
        "eEscape": "\\e7 / \\e8",
        "literal": "ESC 7 / ESC 8",
        "hex": "1b 37 / 1b 38"
      },
      "description": {
        "en": "DEC private 2-byte sequences (not CSI). DECSC (`ESC 7`) saves cursor position, current SGR attributes, charset selection, origin mode flag, and wraparound flag. DECRC (`ESC 8`) restores them. CSI alternatives `\\x1b[s` (save) and `\\x1b[u` (restore) are widely supported but historically save only the position. Most modern terminals treat both pairs identically.",
        "zh": "DEC 私有 2 字节序列（非 CSI）。DECSC（`ESC 7`）保存光标位置、当前 SGR 属性、字符集选择、origin mode 标志与 wraparound 标志。DECRC（`ESC 8`）将其恢复。CSI 替代形式 `\\x1b[s`（保存）与 `\\x1b[u`（恢复）也被广泛支持，但历史上只保存位置。多数现代终端将两种形式视为等价。"
      },
      "spec": "DEC STD 070 / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\0337move\\033[5;5HHERE\\0338back\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b7\\x1b[5;5HHERE\\x1b8')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b7\\x1b[5;5HHERE\\x1b8\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b7\\x1b[5;5HHERE\\x1b8')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b7\\x1b[5;5HHERE\\x1b8\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-position",
        "cursor-move",
        "sco-save-restore"
      ]
    },
    {
      "slug": "erase-display",
      "family": "CSI",
      "title": {
        "en": "ED — Erase in display (\\x1b[2J clear screen)",
        "zh": "ED — 清屏 (`\\x1b[2J`)"
      },
      "shortDesc": {
        "en": "Erase part or all of the screen.",
        "zh": "擦除屏幕的部分或全部。"
      },
      "bytes": {
        "canonical": "\\x1b[NJ",
        "octal": "\\033[2J",
        "eEscape": "\\e[2J",
        "literal": "ESC [ N J",
        "hex": "1b 5b <N> 4a"
      },
      "description": {
        "en": "Final byte `J`. Parameter N controls scope: 0 = cursor → end of screen (default), 1 = beginning of screen → cursor, 2 = entire visible screen, 3 = entire screen + scrollback buffer (xterm extension). `\\x1b[2J` is the canonical 'clear screen' but leaves the cursor where it was — most clear-screen recipes combine it with `\\x1b[H` to also reset the cursor to (1,1). On modern terminals prefer `\\x1b[2J\\x1b[H` over the legacy `\\033c` (RIS) which performs a full terminal reset including SGR and charset.",
        "zh": "末字节为 `J`。参数 N 决定范围：0 = 光标到屏幕末（默认）；1 = 屏幕开始到光标；2 = 整个可视屏幕；3 = 屏幕加滚动缓冲区（xterm 扩展）。`\\x1b[2J` 是「清屏」的标准形式，但不会移动光标 —— 大多数清屏配方会同时发送 `\\x1b[H` 将光标重置到 (1,1)。在现代终端上优先使用 `\\x1b[2J\\x1b[H`，避免遗留的 `\\033c`（RIS），它会执行完整的终端重置，包括 SGR 与字符集。"
      },
      "spec": "ECMA-48 §8.3.39 (ED)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[2J\\033[H'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[2J\\x1b[H', end='')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[2J\\x1b[H\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[2J\\x1b[H')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[2J\\x1b[H\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "erase-line",
        "cursor-position",
        "decstr-soft-reset"
      ]
    },
    {
      "slug": "erase-line",
      "family": "CSI",
      "title": {
        "en": "EL — Erase in line (\\x1b[K)",
        "zh": "EL — 行内擦除 (`\\x1b[K`)"
      },
      "shortDesc": {
        "en": "Erase part or all of the current line.",
        "zh": "擦除当前行的部分或全部。"
      },
      "bytes": {
        "canonical": "\\x1b[NK",
        "octal": "\\033[K",
        "eEscape": "\\e[K",
        "literal": "ESC [ N K",
        "hex": "1b 5b <N> 4b"
      },
      "description": {
        "en": "Final byte `K`. N = 0 erases from the cursor to the end of the line (default), N = 1 erases from the start of the line up to and including the cursor, N = 2 erases the entire current line. The cursor itself is NOT moved by EL — combine with `\\r` if you want to overwrite the line from the start.",
        "zh": "末字节为 `K`。N = 0 从光标位置擦到行尾（默认）；N = 1 从行首擦到光标（含）；N = 2 擦除整行。EL 不会移动光标 —— 如需从行首覆盖，请与 `\\r` 配合。"
      },
      "spec": "ECMA-48 §8.3.41 (EL)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf 'progress... \\r\\033[Kdone\\n'"
        },
        {
          "lang": "python",
          "code": "import sys, time\\nfor i in range(3): sys.stdout.write(f'\\r\\x1b[K{i}'); sys.stdout.flush(); time.sleep(0.2)\\nprint()"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\r\\x1b[Kclear line\\n\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\r\\x1b[Kclear line\\n')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\r\\x1b[Kclear line\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "erase-display",
        "cursor-position",
        "cursor-move",
        "decstr-soft-reset"
      ]
    },
    {
      "slug": "alt-screen",
      "family": "DEC",
      "title": {
        "en": "DECSET 1049 — Alternate screen buffer",
        "zh": "DECSET 1049 — 备用屏幕缓冲"
      },
      "shortDesc": {
        "en": "Switch to a separate screen buffer (like vim/less do on launch).",
        "zh": "切换到独立屏幕缓冲区（vim/less 启动时使用）。"
      },
      "bytes": {
        "canonical": "\\x1b[?1049h   (enter)   \\x1b[?1049l   (leave)",
        "octal": "\\033[?1049h / \\033[?1049l",
        "eEscape": "\\e[?1049h / \\e[?1049l",
        "literal": "ESC [ ? 1 0 4 9 h / l",
        "hex": "1b 5b 3f 31 30 34 39 68 / 6c"
      },
      "description": {
        "en": "DEC private mode 1049 is the canonical 'enter full-screen app' sequence. On enter (`h`), the terminal saves the cursor, switches to a fresh screen buffer (no scrollback), and clears it. On leave (`l`), the original buffer and cursor are restored — this is what lets you `q` out of `vim`/`less` and find your shell prompt exactly where you left it. Older modes 47 and 1047 do almost the same thing but without the cursor save/restore and clear behaviors.",
        "zh": "DEC 私有模式 1049 是「进入全屏应用」的标准序列。进入（`h`）时，终端保存光标，切换到新的屏幕缓冲（无回滚），并清屏。离开（`l`）时，恢复原缓冲和光标 —— 这正是 `vim`/`less` 退出后命令行提示符回到原位置的原因。早期模式 47 和 1047 行为类似，但缺少光标保存/恢复以及清屏。"
      },
      "spec": "xterm-ctlseqs (Private modes)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?1049h'; sleep 2; printf '\\033[?1049l'"
        },
        {
          "lang": "python",
          "code": "import sys, time\\nsys.stdout.write('\\x1b[?1049h'); sys.stdout.flush(); time.sleep(2); sys.stdout.write('\\x1b[?1049l')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?1049h\"); time.Sleep(2*time.Second); fmt.Print(\"\\x1b[?1049l\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?1049h'); setTimeout(() => process.stdout.write('\\x1b[?1049l'), 2000)"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?1049h\"); sleep(2); printf(\"\\x1b[?1049l\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-visibility",
        "cursor-save-restore",
        "dec-alt-screen-1047"
      ]
    },
    {
      "slug": "cursor-visibility",
      "family": "DEC",
      "title": {
        "en": "DECTCEM ?25 — Show/hide cursor",
        "zh": "DECTCEM ?25 — 显示/隐藏光标"
      },
      "shortDesc": {
        "en": "Show or hide the text cursor.",
        "zh": "显示或隐藏文本光标。"
      },
      "bytes": {
        "canonical": "\\x1b[?25h   (show)   \\x1b[?25l   (hide)",
        "octal": "\\033[?25h / \\033[?25l",
        "eEscape": "\\e[?25h / \\e[?25l",
        "literal": "ESC [ ? 2 5 h / l",
        "hex": "1b 5b 3f 32 35 68 / 6c"
      },
      "description": {
        "en": "DEC Text Cursor Enable Mode. Useful for progress bars and TUIs to avoid the blinking caret on top of redrawn text. Always restore (`?25h`) on exit, including in panic / signal handlers — a stuck `?25l` will hide the user's prompt cursor until the next `tput cnorm` / terminal reset.",
        "zh": "DEC 文本光标启用模式。常用于进度条和 TUI，避免闪烁光标遮挡重绘文本。退出时务必恢复（`?25h`），包括 panic / 信号处理器中 —— 卡住的 `?25l` 会让用户的命令行光标一直隐藏，直到下一次 `tput cnorm` 或终端重置。"
      },
      "spec": "xterm-ctlseqs (DECTCEM)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?25l'; sleep 2; printf '\\033[?25h'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[?25l')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?25l\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?25l')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?25l\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "alt-screen",
        "cursor-move",
        "cursor-save-restore",
        "dec-cursor-shape",
        "dec-cursor-blink"
      ]
    },
    {
      "slug": "dec-bracketed-paste",
      "family": "DEC",
      "title": {
        "en": "DECSET ?2004 — Bracketed paste mode",
        "zh": "DECSET ?2004 — 括号粘贴模式"
      },
      "shortDesc": {
        "en": "Wrap pasted text in distinct escape markers so apps can tell paste from typing.",
        "zh": "将粘贴文本用独立的转义标记包裹，让应用区分粘贴与键入。"
      },
      "bytes": {
        "canonical": "\\x1b[?2004h   (enable)   \\x1b[?2004l   (disable)",
        "octal": "\\033[?2004h / \\033[?2004l",
        "eEscape": "\\e[?2004h / \\e[?2004l",
        "literal": "ESC [ ? 2 0 0 4 h / l",
        "hex": "1b 5b 3f 32 30 30 34 68 / 6c"
      },
      "description": {
        "en": "When enabled, every paste from the system clipboard is delivered to the application surrounded by `\\x1b[200~` (paste start) and `\\x1b[201~` (paste end). This lets shells / editors / TUIs disable autoindent, syntax-completion, and shortcut bindings while consuming pasted bytes. Modern bash (5.1+), zsh, fish, vim, neovim, emacs, and ipython all consume bracketed paste. Always disable (`?2004l`) on exit; pasted content showing literal `^[[200~` markers means a TUI crashed without restoring.",
        "zh": "启用后，系统剪贴板的每次粘贴会被 `\\x1b[200~`（粘贴开始）和 `\\x1b[201~`（粘贴结束）包裹后送达应用。这让 shell / 编辑器 / TUI 在消费粘贴字节时可禁用自动缩进、语法补全和快捷键绑定。现代 bash（5.1+）、zsh、fish、vim、neovim、emacs、ipython 均支持。退出时务必关闭（`?2004l`）；如果粘贴出现字面 `^[[200~` 标记，通常意味着 TUI 崩溃未恢复。"
      },
      "spec": "xterm-ctlseqs (Private mode 2004)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?2004h'  # enable\\nprintf '\\033[?2004l'  # disable"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[?2004h')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?2004h\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?2004h')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?2004h\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "alt-screen",
        "cursor-visibility",
        "dec-focus-events"
      ]
    },
    {
      "slug": "dec-mouse-tracking",
      "family": "DEC",
      "title": {
        "en": "DECSET ?1000 / ?1006 — Mouse tracking",
        "zh": "DECSET ?1000 / ?1006 — 鼠标跟踪"
      },
      "shortDesc": {
        "en": "Receive mouse click / drag / scroll events as escape sequences.",
        "zh": "以转义序列形式接收鼠标点击 / 拖拽 / 滚轮事件。"
      },
      "bytes": {
        "canonical": "\\x1b[?1000h   (click only)   \\x1b[?1002h   (cell drag)   \\x1b[?1003h   (any motion)   \\x1b[?1006h   (SGR encoding)",
        "octal": "\\033[?1000h …",
        "eEscape": "\\e[?1000h …",
        "literal": "ESC [ ? <N> h / l",
        "hex": "1b 5b 3f ... 68 / 6c"
      },
      "description": {
        "en": "Mouse reporting modes are stackable on/off DEC private modes. `?1000` reports button press+release, `?1002` adds drag events while a button is held, `?1003` reports every motion. The encoding sub-modes are `?1005` (UTF-8, deprecated), `?1015` (urxvt), and `?1006` (SGR — recommended, no 223-column limit, ASCII-safe). Enable `?1006` alongside `?1000`/`?1002` for portable handling. Disable everything with `?1000l ?1002l ?1003l ?1006l` on exit — a forgotten enable will spam your shell with `^[[<…` strings.",
        "zh": "鼠标上报通过多个可叠加的 DEC 私有模式控制。`?1000` 报告按下与释放；`?1002` 在按键保持期间额外报告拖拽；`?1003` 报告所有移动。编码子模式：`?1005`（UTF-8，已弃用）、`?1015`（urxvt）、`?1006`（SGR —— 推荐，无 223 列限制，ASCII 安全）。可移植做法是同时启用 `?1006` 和 `?1000`/`?1002`。退出时务必发送 `?1000l ?1002l ?1003l ?1006l` 关闭全部 —— 漏关会让 shell 收到大量 `^[[<…` 字符串。"
      },
      "spec": "xterm-ctlseqs (Mouse Tracking)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?1000h\\033[?1006h'  # enable click+SGR\\nprintf '\\033[?1000l\\033[?1006l'  # disable"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[?1000h\\x1b[?1006h')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?1000h\\x1b[?1006h\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?1000h\\x1b[?1006h')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?1000h\\x1b[?1006h\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "dec-bracketed-paste",
        "alt-screen",
        "dec-focus-events"
      ]
    },
    {
      "slug": "osc-title",
      "family": "OSC",
      "title": {
        "en": "OSC 0 / 2 — Set window/icon title",
        "zh": "OSC 0 / 2 — 设置窗口/图标标题"
      },
      "shortDesc": {
        "en": "Change the terminal window's title bar text.",
        "zh": "修改终端窗口的标题栏文本。"
      },
      "bytes": {
        "canonical": "\\x1b]0;TITLE\\x07",
        "octal": "\\033]0;TITLE\\007",
        "eEscape": "\\e]0;TITLE\\a",
        "literal": "ESC ] 0 ; TITLE BEL",
        "hex": "1b 5d 30 3b ... 07"
      },
      "description": {
        "en": "OSC (Operating System Command) sequences start with `ESC ]` and end with either BEL (`\\x07`, the de-facto xterm terminator) or ST (`ESC \\`, `\\x1b\\\\`, the standards-correct terminator). `OSC 0` sets both window and icon title, `OSC 1` only icon, `OSC 2` only window. Used by shells (PROMPT_COMMAND), tmux, screen, and tab-renaming tools. The terminator must always be present — a missing BEL/ST will hang the OSC parser until the next byte that happens to be one.",
        "zh": "OSC（Operating System Command）序列以 `ESC ]` 开头，以 BEL（`\\x07`，xterm 事实标准）或 ST（`ESC \\`，`\\x1b\\\\`，规范标准）结尾。`OSC 0` 同时设置窗口与图标标题；`OSC 1` 仅图标；`OSC 2` 仅窗口。常用于 shell（PROMPT_COMMAND）、tmux、screen 以及标签页重命名工具。结束符必须存在 —— 缺失的 BEL/ST 会让 OSC 解析器一直挂起，直到下一个恰好是结束符的字节。"
      },
      "spec": "xterm-ctlseqs (OSC 0/1/2)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]0;Hello window\\007'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]0;Hello window\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]0;Hello window\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]0;Hello window\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]0;Hello window\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "osc-hyperlink",
        "osc-cwd",
        "osc-clipboard",
        "osc-reset-fg-bg"
      ]
    },
    {
      "slug": "osc-hyperlink",
      "family": "OSC",
      "title": {
        "en": "OSC 8 — Inline hyperlink",
        "zh": "OSC 8 — 内联超链接"
      },
      "shortDesc": {
        "en": "Render clickable hyperlinks in terminal output (gnome-terminal 3.26+, iTerm2, Windows Terminal, kitty, ...).",
        "zh": "在终端输出中渲染可点击超链接（gnome-terminal 3.26+、iTerm2、Windows Terminal、kitty 等）。"
      },
      "bytes": {
        "canonical": "\\x1b]8;;URI\\x07TEXT\\x1b]8;;\\x07",
        "octal": "\\033]8;;URI\\007TEXT\\033]8;;\\007",
        "eEscape": "\\e]8;;URI\\aTEXT\\e]8;;\\a",
        "literal": "ESC ] 8 ; ; URI BEL TEXT ESC ] 8 ; ; BEL",
        "hex": "1b 5d 38 3b 3b ... 07 ... 1b 5d 38 3b 3b 07"
      },
      "description": {
        "en": "Specified by gnome-terminal in 2017 and now widely adopted. Two-part sequence: `OSC 8 ; params ; URI BEL` opens a link region, `OSC 8 ; ; BEL` (empty URI) closes it. The middle TEXT can include any printable + further SGR. Optional params: `id=anchor` lets the terminal de-duplicate multi-line links. Plain HTTP/HTTPS URIs work everywhere; `file://` works in iTerm2 / wezterm / kitty / vscode-terminal; `vscode://` and editor URIs are supported by some.",
        "zh": "由 gnome-terminal 在 2017 年制定，现已被广泛采纳。两段式序列：`OSC 8 ; params ; URI BEL` 开始链接区段，`OSC 8 ; ; BEL`（URI 为空）结束。中间 TEXT 可包含任意可打印字符及后续 SGR。可选参数：`id=anchor` 让终端将跨行链接去重。普通 HTTP/HTTPS 链接全平台可用；`file://` 在 iTerm2 / wezterm / kitty / vscode-terminal 可用；`vscode://` 等编辑器 URI 部分支持。"
      },
      "spec": "Hyperlinks in terminal emulators (gnome-terminal proposal, 2017)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]8;;https://example.com\\033\\\\link text\\033]8;;\\033\\\\\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b]8;;https://example.com\\x07link text\\x1b]8;;\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]8;;https://example.com\\x07link text\\x1b]8;;\\x07\\n\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b]8;;https://example.com\\x07link text\\x1b]8;;\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]8;;https://example.com\\x07link text\\x1b]8;;\\x07\\n\");"
        }
      ],
      "support": {
        "xterm": "partial",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "osc-title",
        "osc-cwd",
        "osc-clipboard",
        "osc-reset-fg-bg"
      ]
    },
    {
      "slug": "scroll-up-down",
      "family": "CSI",
      "title": {
        "en": "SU / SD — Scroll up / down",
        "zh": "SU / SD — 向上 / 向下滚动"
      },
      "shortDesc": {
        "en": "Scroll the screen contents up (SU) or down (SD) by N lines without moving the cursor.",
        "zh": "将屏幕内容向上（SU）或向下（SD）滚动 N 行，光标位置不变。"
      },
      "bytes": {
        "canonical": "\\x1b[NS   (scroll up)   \\x1b[NT   (scroll down)",
        "octal": "\\033[1S / \\033[1T",
        "eEscape": "\\e[1S / \\e[1T",
        "literal": "ESC [ N S / T",
        "hex": "1b 5b <N> 53 / 54"
      },
      "description": {
        "en": "Final byte `S` = SU (Scroll Up), `T` = SD (Scroll Down). Both shift the scrolling region's contents by N rows (defaulting to 1 if omitted) and fill the exposed rows with blanks; the cursor position is unchanged. SU `\\x1b[1S` makes the top row disappear and a blank row appear at the bottom — the inverse of how a fresh line of text scrolls the screen on its own. Scroll-region semantics apply: if DECSTBM (`\\x1b[t;b r`) has restricted the region, only those rows scroll.",
        "zh": "末字节 `S` = SU（Scroll Up）、`T` = SD（Scroll Down）。两者将滚动区域内容按 N 行（省略时默认 1）平移，并以空行填补暴露出的行；光标位置不变。SU `\\x1b[1S` 会让顶行消失，底部出现一行空白 —— 与新文本自动滚屏的方向相反。受滚动区域语义影响：若已通过 DECSTBM（`\\x1b[t;b r`）限定区域，则只滚动该区域内的行。"
      },
      "parameters": [
        {
          "name": "S",
          "desc": {
            "en": "scroll up by N rows",
            "zh": "向上滚动 N 行"
          }
        },
        {
          "name": "T",
          "desc": {
            "en": "scroll down by N rows",
            "zh": "向下滚动 N 行"
          }
        }
      ],
      "spec": "ECMA-48 §8.3.147 (SU) / §8.3.113 (SD)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf 'top\\nmid\\nbot\\033[2S'   # scroll region up 2"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[1S')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[1S\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[1S')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[1S\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-move",
        "cursor-position",
        "erase-display"
      ]
    },
    {
      "slug": "dec-line-wrap",
      "family": "DEC",
      "title": {
        "en": "DECAWM ?7 — Auto-wrap mode",
        "zh": "DECAWM ?7 — 自动换行模式"
      },
      "shortDesc": {
        "en": "Toggle whether the cursor wraps to the next line at the right margin (default: on).",
        "zh": "切换光标到达右边距时是否自动换到下一行（默认开启）。"
      },
      "bytes": {
        "canonical": "\\x1b[?7h   (enable wrap)   \\x1b[?7l   (disable)",
        "octal": "\\033[?7h / \\033[?7l",
        "eEscape": "\\e[?7h / \\e[?7l",
        "literal": "ESC [ ? 7 h / l",
        "hex": "1b 5b 3f 37 68 / 6c"
      },
      "description": {
        "en": "DEC Auto-Wrap Mode. When enabled (`?7h`, the default), characters that would print past the rightmost column wrap to column 1 of the next row. When disabled (`?7l`), the cursor stays glued to the last column and each new character overwrites the previous one — useful for status lines and TUIs that draw exactly to the edge without unintentionally scrolling. Turn wrap off before drawing a fixed-width status bar; turn it back on before yielding the terminal back to the user, otherwise long shell-prompts truncate visibly.",
        "zh": "DEC 自动换行模式。启用（`?7h`，默认）时，超出最右列的字符会自动换到下一行的第 1 列。关闭（`?7l`）后，光标停在末列，新字符会覆盖前一个 —— 这对状态栏和 TUI 在屏幕边缘精确绘制（避免意外滚屏）非常有用。绘制固定宽度状态栏前先关闭换行；交还终端给用户之前必须恢复（`?7h`），否则较长的 shell 提示符会被截断。"
      },
      "spec": "xterm-ctlseqs (DEC Private Mode 7, DECAWM)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?7l'   # disable wrap for status bar\\nprintf '\\033[?7h'   # restore"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[?7l')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?7l\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?7l')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?7l\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "alt-screen",
        "cursor-position",
        "dec-origin-mode"
      ]
    },
    {
      "slug": "dec-focus-events",
      "family": "DEC",
      "title": {
        "en": "DECSET ?1004 — Focus in/out events",
        "zh": "DECSET ?1004 — 焦点进出事件"
      },
      "shortDesc": {
        "en": "Make the terminal report when its window gains or loses keyboard focus.",
        "zh": "让终端在窗口获得或失去键盘焦点时上报事件。"
      },
      "bytes": {
        "canonical": "\\x1b[?1004h   (enable)   \\x1b[?1004l   (disable)",
        "octal": "\\033[?1004h / \\033[?1004l",
        "eEscape": "\\e[?1004h / \\e[?1004l",
        "literal": "ESC [ ? 1 0 0 4 h / l",
        "hex": "1b 5b 3f 31 30 30 34 68 / 6c"
      },
      "description": {
        "en": "When enabled, the terminal sends `\\x1b[I` to stdin whenever the window gains focus and `\\x1b[O` whenever it loses focus. TUIs use this to pause animations, redraw their status bar, or refresh data when the user returns. Vim's `FocusGained` / `FocusLost` autocommands and tmux's `focus-events on` rely on this. Always disable (`?1004l`) on exit; otherwise a crashed TUI keeps spraying `^[[I` / `^[[O` into the user's shell every time they alt-tab.",
        "zh": "启用后，窗口获得焦点时终端会向 stdin 发送 `\\x1b[I`，失去焦点时发送 `\\x1b[O`。TUI 用此事件暂停动画、重绘状态栏，或在用户回到窗口时刷新数据。Vim 的 `FocusGained` / `FocusLost` 自动命令、tmux 的 `focus-events on` 均依赖此模式。退出时务必关闭（`?1004l`），否则 TUI 崩溃后用户每次切换窗口都会看到 `^[[I` / `^[[O` 字符串。"
      },
      "spec": "xterm-ctlseqs (Private mode 1004)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?1004h'   # enable focus events\\n# (when window focus changes, terminal emits \\x1b[I or \\x1b[O)"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[?1004h')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?1004h\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?1004h')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?1004h\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "dec-mouse-tracking",
        "dec-bracketed-paste",
        "alt-screen"
      ]
    },
    {
      "slug": "dec-cursor-shape",
      "family": "CSI",
      "title": {
        "en": "DECSCUSR — Cursor shape",
        "zh": "DECSCUSR — 光标形状"
      },
      "shortDesc": {
        "en": "Change the cursor shape: block, underline, or bar (with optional blink).",
        "zh": "切换光标形状：方块、下划线或竖线（可选是否闪烁）。"
      },
      "bytes": {
        "canonical": "\\x1b[N\\x20q   (N = 0..6)",
        "octal": "\\033[1 q",
        "eEscape": "\\e[1 q",
        "literal": "ESC [ N SP q",
        "hex": "1b 5b <N> 20 71"
      },
      "description": {
        "en": "Set Cursor Style. The parameter selects shape and blink: `0` or `1` = blinking block (default), `2` = steady block, `3` = blinking underline, `4` = steady underline, `5` = blinking bar (vertical line), `6` = steady bar. The intermediate byte is a literal SPACE (0x20) before the final `q`. Vim's `t_SI`/`t_EI` and many shells use `\\x1b[6 q` (bar) for insert mode and `\\x1b[2 q` (block) for normal mode. Restore your terminal default with `\\x1b[0 q` on exit.",
        "zh": "设置光标样式。参数同时决定形状与闪烁：`0` 或 `1` = 闪烁方块（默认），`2` = 实心方块，`3` = 闪烁下划线，`4` = 实心下划线，`5` = 闪烁竖线，`6` = 实心竖线。末字节 `q` 前需要一个字面 SPACE（0x20）作为中间字节。Vim 的 `t_SI`/`t_EI` 与不少 shell 使用 `\\x1b[6 q`（竖线）表示插入模式，`\\x1b[2 q`（方块）表示普通模式。退出时使用 `\\x1b[0 q` 恢复用户默认光标。"
      },
      "parameters": [
        {
          "name": "0",
          "desc": {
            "en": "user-default cursor",
            "zh": "用户默认光标"
          }
        },
        {
          "name": "1",
          "desc": {
            "en": "blinking block",
            "zh": "闪烁方块"
          }
        },
        {
          "name": "2",
          "desc": {
            "en": "steady block",
            "zh": "实心方块"
          }
        },
        {
          "name": "3",
          "desc": {
            "en": "blinking underline",
            "zh": "闪烁下划线"
          }
        },
        {
          "name": "4",
          "desc": {
            "en": "steady underline",
            "zh": "实心下划线"
          }
        },
        {
          "name": "5",
          "desc": {
            "en": "blinking bar",
            "zh": "闪烁竖线"
          }
        },
        {
          "name": "6",
          "desc": {
            "en": "steady bar",
            "zh": "实心竖线"
          }
        }
      ],
      "spec": "xterm-ctlseqs (DECSCUSR, CSI Ps SP q)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[6 q'   # vertical bar (insert mode)\\nprintf '\\033[2 q'   # block (normal mode)\\nprintf '\\033[0 q'   # restore default"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[6 q')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[6 q\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[6 q')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[6 q\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-visibility",
        "cursor-position",
        "dec-cursor-blink"
      ]
    },
    {
      "slug": "osc-set-fg-bg",
      "family": "OSC",
      "title": {
        "en": "OSC 10 / 11 — Set default foreground / background color",
        "zh": "OSC 10 / 11 — 设置默认前景 / 背景色"
      },
      "shortDesc": {
        "en": "Set the terminal's default foreground (OSC 10) or background (OSC 11) color, or query the current value.",
        "zh": "设置终端的默认前景色（OSC 10）或背景色（OSC 11），或查询当前值。"
      },
      "bytes": {
        "canonical": "\\x1b]10;#RRGGBB\\x07   (set fg)   \\x1b]11;#RRGGBB\\x07   (set bg)",
        "octal": "\\033]10;#RRGGBB\\007 / \\033]11;#RRGGBB\\007",
        "eEscape": "\\e]10;#RRGGBB\\a / \\e]11;#RRGGBB\\a",
        "literal": "ESC ] 10 ; COLOR BEL / ESC ] 11 ; COLOR BEL",
        "hex": "1b 5d 31 30 3b ... 07 / 1b 5d 31 31 3b ... 07"
      },
      "description": {
        "en": "OSC 10 sets the terminal's default foreground color, OSC 11 the background. The color argument accepts the same forms xterm parses: `#RRGGBB`, `#RGB`, `rgb:RRRR/GGGG/BBBB`, or X11 names like `cornflowerblue`. Passing `?` as the value (`\\x1b]10;?\\x07`) makes the terminal reply with the current color in the same syntax — used by tools like vim's `'background'` autodetect to choose a light or dark colorscheme. Reset to the terminal default with OSC 110 (fg) / OSC 111 (bg).",
        "zh": "OSC 10 设置终端默认前景色，OSC 11 设置默认背景色。颜色参数接受 xterm 同样的多种写法：`#RRGGBB`、`#RGB`、`rgb:RRRR/GGGG/BBBB`、或 X11 颜色名如 `cornflowerblue`。将值替换为 `?`（`\\x1b]10;?\\x07`），终端会用同样语法回报当前颜色 —— vim 的 `'background'` 自动检测就用这种查询来选择浅色或深色配色方案。使用 OSC 110（fg）/ OSC 111（bg）恢复终端默认。"
      },
      "spec": "xterm-ctlseqs (OSC 10 / 11 / 110 / 111)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]11;#1e1e2e\\007'   # set bg to deep navy\\nprintf '\\033]11;?\\007'        # query current bg"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]10;#cdd6f4\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]10;#cdd6f4\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]10;#cdd6f4\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]10;#cdd6f4\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "osc-title",
        "osc-hyperlink",
        "sgr-fg-truecolor"
      ]
    },
    {
      "slug": "osc-clipboard",
      "family": "OSC",
      "title": {
        "en": "OSC 52 — System clipboard read/write",
        "zh": "OSC 52 — 系统剪贴板读写"
      },
      "shortDesc": {
        "en": "Set (or query) the host system clipboard via the terminal — works over SSH without X11 forwarding.",
        "zh": "通过终端设置（或查询）宿主系统剪贴板 —— 可跨 SSH 工作，无需 X11 转发。"
      },
      "bytes": {
        "canonical": "\\x1b]52;c;BASE64\\x07   (set clipboard 'c' to BASE64 decoded bytes)",
        "octal": "\\033]52;c;BASE64\\007",
        "eEscape": "\\e]52;c;BASE64\\a",
        "literal": "ESC ] 52 ; SELECTION ; PAYLOAD BEL",
        "hex": "1b 5d 35 32 3b ... 07"
      },
      "description": {
        "en": "Set the system clipboard from terminal output. The first parameter is the selection: `c` = CLIPBOARD, `p` = PRIMARY, `s` = secondary, `q` = `0..9` cut-buffers. The second parameter is base64-encoded bytes; a literal `?` instead queries the current contents (and the terminal replies with `\\x1b]52;c;BASE64\\x07`). This is how `tmux set -g set-clipboard on`, `vim` (via `clipboard=unnamedplus,osc52`), `neovim` (`vim.g.clipboard`), and `yazi --copy` make yank work across SSH. Disabled by default in most terminals (security: a malicious log line can replace the user's clipboard); enable explicitly per terminal.",
        "zh": "通过终端输出来设置系统剪贴板。第一个参数为选择区：`c` = CLIPBOARD、`p` = PRIMARY、`s` = secondary、`q` 或 `0..9` 为剪切缓冲区。第二个参数为 base64 编码的字节；若改写为字面 `?`，终端会回报当前剪贴板内容（`\\x1b]52;c;BASE64\\x07`）。`tmux set -g set-clipboard on`、`vim`（`clipboard=unnamedplus,osc52`）、`neovim`（`vim.g.clipboard`）以及 `yazi --copy` 都依靠此机制在 SSH 下完成跨主机复制。出于安全考虑（恶意日志行可改写剪贴板）大多数终端默认禁用，需要在终端设置中显式开启。"
      },
      "spec": "xterm-ctlseqs (OSC 52)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]52;c;%s\\007' \"$(printf 'hello' | base64)\""
        },
        {
          "lang": "python",
          "code": "import sys, base64\\npayload = base64.b64encode(b'hello').decode()\\nsys.stdout.write(f'\\x1b]52;c;{payload}\\x07')"
        },
        {
          "lang": "go",
          "code": "import \"encoding/base64\"\\nfmt.Printf(\"\\x1b]52;c;%s\\x07\", base64.StdEncoding.EncodeToString([]byte(\"hello\")))"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]52;c;' + Buffer.from('hello').toString('base64') + '\\x07')"
        },
        {
          "lang": "c",
          "code": "/* assumes base64_encode() helper */\\nprintf(\"\\x1b]52;c;%s\\x07\", base64_encode(\"hello\", 5));"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "osc-title",
        "osc-hyperlink",
        "osc-set-fg-bg"
      ]
    },
    {
      "slug": "decstr-soft-reset",
      "family": "CSI",
      "title": {
        "en": "DECSTR — Soft terminal reset",
        "zh": "DECSTR — 软终端重置"
      },
      "shortDesc": {
        "en": "Reset DEC private modes and SGR to defaults WITHOUT clearing the screen or scrollback.",
        "zh": "将 DEC 私有模式与 SGR 重置为默认，但不清屏，也不清回滚缓冲。"
      },
      "bytes": {
        "canonical": "\\x1b[!p",
        "octal": "\\033[!p",
        "eEscape": "\\e[!p",
        "literal": "ESC [ ! p",
        "hex": "1b 5b 21 70"
      },
      "description": {
        "en": "DEC Soft Terminal Reset. Standard CSI with an intermediate `!` (0x21) before the final `p` (0x70). Restores: SGR (colour + attributes), auto-wrap (`?7`), insert/replace mode, scrolling region (DECSTBM), keyboard mode, character sets. Does NOT clear the screen, the scrollback, or the alt-screen state — making it the safe recovery path when a TUI crashed without restoring its SGR / auto-wrap / cursor state but you still want to keep your scrollback. Compare RIS (`\\x1bc`) which is the hard reset and wipes scrollback.",
        "zh": "DEC 软终端重置。标准 CSI 序列，末字节 `p`（0x70）前有一个中间字节 `!`（0x21）。会重置：SGR（颜色与属性）、自动换行（`?7`）、插入/替换模式、滚动区域（DECSTBM）、键盘模式、字符集。不清屏、不清回滚、也不影响备用屏幕状态 —— 因此在 TUI 崩溃未恢复 SGR / 自动换行 / 光标状态、但你又想保留回滚历史时，是更安全的恢复方式。对比 RIS（`\\x1bc`）—— 硬重置且会清掉回滚。"
      },
      "spec": "xterm-ctlseqs (DECSTR, CSI ! p)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[!p'   # soft reset; scrollback preserved"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[!p')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[!p\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[!p')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[!p\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "ris-reset",
        "sgr-reset",
        "alt-screen"
      ]
    },
    {
      "slug": "ris-reset",
      "family": "ESC",
      "title": {
        "en": "RIS — Reset to Initial State (full terminal reset)",
        "zh": "RIS — 重置到初始状态（终端硬重置）"
      },
      "shortDesc": {
        "en": "Hard reset the terminal: clear screen + scrollback, reset every mode and SGR, home the cursor.",
        "zh": "终端硬重置：清屏 + 清回滚、重置所有模式与 SGR、光标回到原点。"
      },
      "bytes": {
        "canonical": "\\x1bc",
        "octal": "\\033c",
        "eEscape": "\\ec",
        "literal": "ESC c",
        "hex": "1b 63"
      },
      "description": {
        "en": "Reset to Initial State. Two bytes — ESC (0x1b) followed by `c` (0x63) — with no CSI introducer, no parameters. The terminal does the moral equivalent of a power cycle: clears the screen and (on most terminals) the scrollback, resets every SGR attribute and color, exits the alt screen, resets DEC private modes (auto-wrap on, cursor visible, mouse off, bracketed-paste off), resets character sets, and homes the cursor. This is what `reset(1)` and `tput reset` ultimately emit. Use it as a last-resort recovery when a crashed TUI has left the terminal in an unusable state — but be aware it also wipes scrollback in most modern terminals, which the gentler `\\x1b[!p` (DECSTR, soft reset) does not.",
        "zh": "Reset to Initial State。仅两个字节 —— ESC（0x1b）后接 `c`（0x63），没有 CSI 引导符也无参数。终端会执行类似断电重启的操作：清屏并（大多数终端）清空回滚、重置所有 SGR 属性和颜色、退出备用屏幕、重置 DEC 私有模式（自动换行打开、光标可见、鼠标关闭、括号粘贴关闭）、重置字符集，并将光标归位。`reset(1)` 和 `tput reset` 最终发送的就是它。当 TUI 崩溃使终端不可用时，可作为最后手段；但在多数现代终端中它也会清空回滚，而较温和的 `\\x1b[!p`（DECSTR，软重置）不会。"
      },
      "spec": "ECMA-48 §8.3.105 (RIS) / xterm-ctlseqs (ESC c)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033c'   # full reset; same as tput reset"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1bc')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1bc\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1bc')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1bc\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "decstr-soft-reset",
        "sgr-reset",
        "erase-display",
        "alt-screen"
      ]
    },
    {
      "slug": "c0-controls",
      "family": "C0",
      "title": {
        "en": "C0 controls — BS, HT, LF, CR, BEL (single-byte codes)",
        "zh": "C0 控制字符 —— BS、HT、LF、CR、BEL（单字节码）"
      },
      "shortDesc": {
        "en": "The single-byte C0 control characters that move the cursor or signal events — no ESC introducer needed.",
        "zh": "无需 ESC 引导即可移动光标或触发事件的单字节 C0 控制字符。"
      },
      "bytes": {
        "canonical": "\\x08 BS  \\x09 HT  \\x0a LF  \\x0d CR  \\x07 BEL",
        "octal": "\\010 / \\011 / \\012 / \\015 / \\007",
        "eEscape": "\\b / \\t / \\n / \\r / \\a",
        "literal": "BS / HT / LF / CR / BEL",
        "hex": "08 / 09 / 0a / 0d / 07"
      },
      "description": {
        "en": "These five single-byte controls predate ANSI/VT and are still acted on by every terminal: **BS** (0x08, `\\b`) moves the cursor one cell left (does NOT erase — pair with a space + BS again to erase, or use EL). **HT** (0x09, `\\t`) advances the cursor to the next tab stop (default every 8 columns). **LF** (0x0a, `\\n`) moves down one line (and, with `onlcr` tty mode, returns to column 1 — Unix shells rely on this, which is why a raw `\\n` looks ladder-stepped under `stty -onlcr`). **CR** (0x0d, `\\r`) returns to column 1 of the current line — used for progress bars (`\\r` + redraw). **BEL** (0x07, `\\a`) rings the audible bell or flashes the visual bell depending on the terminal's setting; it also serves as the de-facto OSC string terminator (see OSC 0/2 and OSC 8). None of these consume an `ESC` byte — they are part of the C0 control set inherited from ASCII (1963) / ECMA-6.",
        "zh": "这五个单字节控制字符早于 ANSI/VT，至今所有终端仍直接响应它们：**BS**（0x08，`\\b`）光标左移一格（不擦除 —— 配合空格再退格才能擦除，或使用 EL）。**HT**（0x09，`\\t`）光标移到下一个 tab 停位（默认每 8 列）。**LF**（0x0a，`\\n`）光标下移一行（在 `onlcr` tty 模式下还会回到第 1 列 —— Unix shell 依赖此特性，否则 `\\n` 在 `stty -onlcr` 下会显得阶梯排列）。**CR**（0x0d，`\\r`）光标回到当前行第 1 列 —— 进度条常用「`\\r` + 重绘」模式。**BEL**（0x07，`\\a`）发出可闻铃声或视觉闪烁，取决于终端设置；同时也是 OSC 字符串的事实标准终止符（见 OSC 0/2 与 OSC 8）。它们都不需要 `ESC` 字节 —— 属于继承自 ASCII（1963）/ ECMA-6 的 C0 控制集。"
      },
      "parameters": [
        {
          "name": "BS (0x08)",
          "desc": {
            "en": "backspace — cursor left 1",
            "zh": "退格 —— 光标左移 1"
          }
        },
        {
          "name": "HT (0x09)",
          "desc": {
            "en": "horizontal tab — to next tab stop",
            "zh": "水平制表 —— 到下一个 tab 停位"
          }
        },
        {
          "name": "LF (0x0a)",
          "desc": {
            "en": "line feed — down 1 line",
            "zh": "换行 —— 向下 1 行"
          }
        },
        {
          "name": "CR (0x0d)",
          "desc": {
            "en": "carriage return — to column 1",
            "zh": "回车 —— 到第 1 列"
          }
        },
        {
          "name": "BEL (0x07)",
          "desc": {
            "en": "bell — audible/visual alert; OSC terminator",
            "zh": "响铃 —— 可闻/可见提示；OSC 终止符"
          }
        }
      ],
      "spec": "ECMA-48 §8.2 (C0 set) / ASCII / ECMA-6",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\rprogress: 50%%\\r'   # CR redraws current line\\nprintf 'beep\\a\\n'           # BEL rings the bell"
        },
        {
          "lang": "python",
          "code": "import sys, time\\nfor i in range(101):\\n  sys.stdout.write(f'\\r{i}%'); sys.stdout.flush(); time.sleep(0.02)"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\rprogress: 50%\\r\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\rprogress: 50%\\r')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\rprogress: 50%%\\r\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-move",
        "cursor-column",
        "erase-line",
        "ris-reset"
      ]
    },
    {
      "slug": "csi-cbt",
      "family": "CSI",
      "title": {
        "en": "CBT — Cursor Backward Tabulation (CSI Z)",
        "zh": "CBT — 光标反向制表（CSI Z）"
      },
      "shortDesc": {
        "en": "Move the cursor back N tab stops — the reverse of pressing Tab.",
        "zh": "将光标回退 N 个 tab 停位 —— 与按 Tab 键方向相反。"
      },
      "bytes": {
        "canonical": "\\x1b[NZ",
        "octal": "\\033[1Z",
        "eEscape": "\\e[1Z",
        "literal": "ESC [ N Z",
        "hex": "1b 5b <N> 5a"
      },
      "description": {
        "en": "Cursor Backward Tabulation. Final byte `Z` (0x5a) moves the cursor backward to the previous tab stop, repeated N times (default 1 if the parameter is omitted). It is the mirror of CHT (`CSI Ps I`) and the moral opposite of pressing the Tab key (HT, 0x09). If the cursor is already at column 1 or before the first remaining tab stop, it stays put. Default tab stops live every 8 columns unless the application has cleared or shifted them with TBC (`\\x1b[Ng`) and HTS (`\\x1bH`). CBT is rarely emitted by humans, but matters for terminfo capability `cbt` and for any TUI replaying recorded keystrokes (Shift-Tab in form fields, etc.).",
        "zh": "Cursor Backward Tabulation。末字节 `Z`（0x5a），将光标按 tab 停位向后回退 N 次（参数省略时默认 1）。它是 CHT（`CSI Ps I`）的镜像，也是 Tab 键（HT，0x09）的反向操作。若光标已在第 1 列或位于最靠前的剩余 tab 停位之前，则不动。默认 tab 停位为每 8 列，除非通过 TBC（`\\x1b[Ng`）与 HTS（`\\x1bH`）修改过。CBT 极少由手工输入，但对 terminfo 能力 `cbt` 与重放按键的 TUI（如表单字段的 Shift-Tab）有意义。"
      },
      "spec": "ECMA-48 §8.3.7 (CBT)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf 'a\\tb\\tc\\033[2Z|'   # cursor jumps back 2 tab stops, then writes |"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[2Z')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[2Z\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[2Z')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[2Z\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-tbc",
        "cursor-column",
        "c0-controls"
      ]
    },
    {
      "slug": "csi-tbc",
      "family": "CSI",
      "title": {
        "en": "TBC — Tab Clear (CSI g)",
        "zh": "TBC — 清除制表位（CSI g）"
      },
      "shortDesc": {
        "en": "Clear one or all tab stops, changing where HT and CBT land.",
        "zh": "清除一个或全部 tab 停位，改变 HT 和 CBT 的落点。"
      },
      "bytes": {
        "canonical": "\\x1b[g   (clear current)   \\x1b[3g   (clear all)",
        "octal": "\\033[g / \\033[3g",
        "eEscape": "\\e[g / \\e[3g",
        "literal": "ESC [ Ps g",
        "hex": "1b 5b <Ps> 67"
      },
      "description": {
        "en": "Tabulation Clear. Final byte `g` (0x67); the parameter selects scope: `0` (default, also when omitted) = clear the tab stop AT the current column, `3` = clear ALL tab stops. Pair with HTS (`\\x1bH`, ESC H) which SETS a tab stop at the current column. Default tab stops sit every 8 columns; once you `\\x1b[3g` them all, HT (`\\t`) does nothing until you set new ones. This matters for tabular CLI output (`column`, `pr`, `expand`), forms-style TUIs, and any app emitting `\\t` for layout — clear the default 8-column grid, then place HTS stops at the actual field boundaries.",
        "zh": "Tabulation Clear。末字节 `g`（0x67）；参数控制范围：`0`（默认，省略时同）= 清除当前列上的 tab 停位，`3` = 清除全部 tab 停位。配合 HTS（`\\x1bH`，ESC H）—— 在当前列设置 tab 停位。默认每 8 列一个 tab 停位；一旦 `\\x1b[3g` 全部清除，`\\t`（HT）将无任何效果，直到你重新设置。对 `column`、`pr`、`expand` 的表格输出、表单式 TUI、以及任何用 `\\t` 排版的程序意义重大 —— 清掉默认 8 列网格，再按字段边界放置 HTS 停位。"
      },
      "parameters": [
        {
          "name": "0",
          "desc": {
            "en": "clear tab stop at current column",
            "zh": "清除当前列上的 tab 停位"
          }
        },
        {
          "name": "3",
          "desc": {
            "en": "clear ALL tab stops",
            "zh": "清除所有 tab 停位"
          }
        }
      ],
      "spec": "ECMA-48 §8.3.154 (TBC)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[3g'      # clear all tab stops\\nprintf '\\033H'        # set a tab stop here (HTS, ESC H)"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[3g')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[3g\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[3g')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[3g\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-cbt",
        "c0-controls",
        "cursor-column"
      ]
    },
    {
      "slug": "decstbm",
      "family": "CSI",
      "title": {
        "en": "DECSTBM — Set Top/Bottom Margins (CSI r)",
        "zh": "DECSTBM — 设置上下边距（CSI r）"
      },
      "shortDesc": {
        "en": "Define the vertical scrolling region — rows outside it stay pinned, rows inside scroll.",
        "zh": "定义垂直滚动区域 —— 区域外的行被固定，区域内的行参与滚动。"
      },
      "bytes": {
        "canonical": "\\x1b[T;Br",
        "octal": "\\033[1;24r",
        "eEscape": "\\e[1;24r",
        "literal": "ESC [ T ; B r",
        "hex": "1b 5b <T> 3b <B> 72"
      },
      "description": {
        "en": "Set Top and Bottom Margins. Final byte `r` (0x72); parameters are 1-based row numbers — `T` (top row, default 1) and `B` (bottom row, default = screen height). Once set, all scrolling — natural overflow at the bottom row, LF beyond row `B`, SU / SD (`\\x1b[NS` / `T`), and the alt screen — operates only on rows `T..B` inclusive; rows above `T` and below `B` stay pinned. Sending `\\x1b[r` (no parameters) resets to the full screen. After DECSTBM the cursor is moved to the home position of the active region (top-left). Every full-screen TUI uses this to keep a status bar (row 1 or N) frozen while the body scrolls. Pair with DECOM (`?6h/l`) to ALSO clip cursor addressing to the region.",
        "zh": "Set Top and Bottom Margins。末字节 `r`（0x72）；参数是基于 1 的行号 —— `T`（顶部行，默认 1）与 `B`（底部行，默认 = 屏幕高度）。一旦设置，所有滚动行为 —— 底行自然溢出、`B` 之后的 LF、SU/SD（`\\x1b[NS`/`T`）以及备用屏幕 —— 都只作用于第 `T..B` 行（含端点）；`T` 之上与 `B` 之下的行被固定。发送 `\\x1b[r`（无参数）恢复整屏滚动。DECSTBM 执行后光标会被移到活动区域的原点（左上角）。每个全屏 TUI 都用它把状态栏（第 1 行或第 N 行）冻结，仅让正文滚动。结合 DECOM（`?6h/l`）可让光标定位也被裁剪到该区域。"
      },
      "parameters": [
        {
          "name": "T",
          "desc": {
            "en": "top row, 1-based (default 1)",
            "zh": "顶部行，基于 1（默认 1）"
          }
        },
        {
          "name": "B",
          "desc": {
            "en": "bottom row, 1-based (default = screen height)",
            "zh": "底部行，基于 1（默认 = 屏幕高度）"
          }
        }
      ],
      "spec": "xterm-ctlseqs (DECSTBM, CSI Ps ; Ps r)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[2;23r'   # rows 2..23 scroll; 1 and 24 pinned\\nprintf '\\033[r'       # reset to full screen"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[2;23r')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[2;23r\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[2;23r')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[2;23r\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "scroll-up-down",
        "cursor-position",
        "alt-screen"
      ]
    },
    {
      "slug": "sco-save-restore",
      "family": "CSI",
      "title": {
        "en": "SCOSC / SCORC — Save / Restore cursor (CSI s / u)",
        "zh": "SCOSC / SCORC — 保存 / 恢复光标（CSI s / u）"
      },
      "shortDesc": {
        "en": "CSI-style save (s) and restore (u) of cursor position — distinct from ESC 7 / ESC 8 (DECSC / DECRC).",
        "zh": "CSI 风格的光标位置保存（s）与恢复（u）—— 与 ESC 7 / ESC 8（DECSC / DECRC）有别。"
      },
      "bytes": {
        "canonical": "\\x1b[s   (save)   \\x1b[u   (restore)",
        "octal": "\\033[s / \\033[u",
        "eEscape": "\\e[s / \\e[u",
        "literal": "ESC [ s / u",
        "hex": "1b 5b 73 / 75"
      },
      "description": {
        "en": "Save Cursor Position (SCOSC, final byte `s`, 0x73) and Restore Cursor Position (SCORC, final byte `u`, 0x75). Originally from the SCO ANSI terminal; xterm, VTE, ConPTY, and Windows Terminal all honour them today. They are NOT the same as the older DEC pair DECSC (`\\x1b7`) / DECRC (`\\x1b8`): SCOSC/SCORC save ONLY the position (row + column), whereas DECSC also saves SGR attributes, character-set state, and origin mode. There is exactly ONE save slot — calling SCOSC again overwrites the prior save. Caveat: `\\x1b[s` collides with DECSLRM (Set Left/Right Margins) when LRMM mode (`?69h`) is active; under standard xterm defaults LRMM is OFF and `s` is unambiguous.",
        "zh": "Save Cursor Position（SCOSC，末字节 `s`，0x73）与 Restore Cursor Position（SCORC，末字节 `u`，0x75）。源自 SCO ANSI 终端；xterm、VTE、ConPTY、Windows Terminal 现今均支持。它们与较早的 DEC 对 DECSC（`\\x1b7`）/ DECRC（`\\x1b8`）不同：SCOSC/SCORC 只保存位置（行 + 列），而 DECSC 还会保存 SGR 属性、字符集状态与起点模式。只有一个保存槽 —— 再次调用 SCOSC 会覆盖之前的保存。注意：当启用 LRMM 模式（`?69h`）时 `\\x1b[s` 会与 DECSLRM（设置左右边距）冲突；xterm 默认 LRMM 关闭，`s` 含义明确。"
      },
      "spec": "xterm-ctlseqs (SCOSC / SCORC, CSI s / u)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf 'a\\033[sBCD\\033[u_'   # save after 'a', write BCD, restore, write _ -> 'a_CD'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[s'); ...; sys.stdout.write('\\x1b[u')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[s\"); /* ... */ fmt.Print(\"\\x1b[u\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[s'); /* ... */ process.stdout.write('\\x1b[u')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[s\"); /* ... */ printf(\"\\x1b[u\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-save-restore",
        "cursor-position",
        "decstbm"
      ]
    },
    {
      "slug": "osc-set-palette",
      "family": "OSC",
      "title": {
        "en": "OSC 4 — Set palette colour (and query)",
        "zh": "OSC 4 — 设置调色板颜色（与查询）"
      },
      "shortDesc": {
        "en": "Change one of the 256 palette colours, or query its current value.",
        "zh": "设置 256 色调色板中某一项颜色，或查询其当前值。"
      },
      "bytes": {
        "canonical": "\\x1b]4;N;#RRGGBB\\x07   (set)   \\x1b]4;N;?\\x07   (query)",
        "octal": "\\033]4;N;...\\007",
        "eEscape": "\\e]4;N;...\\a",
        "literal": "ESC ] 4 ; N ; COLOR BEL",
        "hex": "1b 5d 34 3b <N> 3b ... 07"
      },
      "description": {
        "en": "Set the colour at index `N` (0..255) in the terminal's working palette. Indexes 0..7 are the basic colours (black / red / green / yellow / blue / magenta / cyan / white), 8..15 the bright variants, 16..231 the 6×6×6 colour cube, 232..255 the 24-step grayscale ramp. Colour syntax matches OSC 10/11: `#RRGGBB`, `#RGB`, `rgb:RRRR/GGGG/BBBB`, or X11 names. Replacing the colour with `?` (`\\x1b]4;N;?\\x07`) makes the terminal reply with the current value — base16-themes, pywal, and theme-detectors all use this query/set loop to harvest and rewrite the palette at startup. Reset a single index with OSC 104 (`\\x1b]104;N\\x07`); reset the whole palette with OSC 104 with no parameter.",
        "zh": "设置终端工作调色板中第 `N` 项（0..255）的颜色。0..7 为基本色（黑 / 红 / 绿 / 黄 / 蓝 / 品红 / 青 / 白），8..15 为亮色版本，16..231 为 6×6×6 颜色立方，232..255 为 24 级灰度。颜色语法与 OSC 10/11 相同：`#RRGGBB`、`#RGB`、`rgb:RRRR/GGGG/BBBB`、X11 颜色名。将颜色改为 `?`（`\\x1b]4;N;?\\x07`）会让终端回报当前值 —— base16 主题、pywal、主题检测脚本都用这个查询/设置循环在启动时读取并改写调色板。使用 OSC 104（`\\x1b]104;N\\x07`）重置单个索引；不带参数的 OSC 104 重置整个调色板。"
      },
      "spec": "xterm-ctlseqs (OSC 4)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]4;1;#ff5555\\007'   # remap colour 1 (red) to #ff5555\\nprintf '\\033]4;1;?\\007'        # query current colour 1"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]4;1;#ff5555\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]4;1;#ff5555\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]4;1;#ff5555\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]4;1;#ff5555\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "osc-set-fg-bg",
        "sgr-fg-256",
        "sgr-bg-256"
      ]
    },
    {
      "slug": "osc-notification",
      "family": "OSC",
      "title": {
        "en": "OSC 9 — Toast notification (iTerm2 / Windows Terminal)",
        "zh": "OSC 9 — 桌面通知（iTerm2 / Windows Terminal）"
      },
      "shortDesc": {
        "en": "Trigger a native OS desktop notification from the terminal — long-running job done, build finished, etc.",
        "zh": "从终端触发原生桌面通知 —— 长任务完成、构建结束等场景。"
      },
      "bytes": {
        "canonical": "\\x1b]9;MESSAGE\\x07",
        "octal": "\\033]9;MESSAGE\\007",
        "eEscape": "\\e]9;MESSAGE\\a",
        "literal": "ESC ] 9 ; MESSAGE BEL",
        "hex": "1b 5d 39 3b ... 07"
      },
      "description": {
        "en": "Raise a system-tray / Notification Center / KNotifications toast with the given message string. Originally iTerm2's `iTerm2 growl` mechanism (the OSC 9 alias dates to the Growl daemon era on macOS); Windows Terminal adopted the same control later. The terminal forwards the payload to the host OS notification API — the user sees a banner outside the terminal window, useful for long compiles, `make && say done` substitutes, CI pollers. Unsupported terminals drop the entire OSC 9 frame silently, so it is safe to emit unconditionally. Caveat: ConEmu repurposes OSC 9 as its progress-bar protocol (`\\x1b]9;4;<state>;<percent>\\x07`) — a different scheme — so check your terminal docs before sending complex OSC 9 payloads.",
        "zh": "在系统托盘 / 通知中心 / KNotifications 中弹出一个包含指定消息字符串的桌面通知。最早源自 iTerm2 的 `iTerm2 growl` 机制（OSC 9 别名沿用自 macOS Growl 守护进程时代）；Windows Terminal 后来也采用同一控制码。终端会把消息载荷转发到宿主 OS 通知 API —— 用户会在终端窗口之外看到横幅，常用于长编译、`make && say done` 的替代、CI 轮询。不支持的终端会静默丢弃整条 OSC 9，因此可安全地无条件发送。注意：ConEmu 将 OSC 9 重新定义为其进度条协议（`\\x1b]9;4;<state>;<percent>\\x07`），是另一套语义；发送复杂 OSC 9 载荷前请先查终端文档。"
      },
      "spec": "iTerm2 Proprietary Escape Codes (OSC 9) / Windows Terminal",
      "examples": [
        {
          "lang": "bash",
          "code": "make && printf '\\033]9;build finished\\007'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]9;build finished\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]9;build finished\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]9;build finished\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]9;build finished\\x07\");"
        }
      ],
      "support": {
        "xterm": "no",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "no",
        "konsole": "partial"
      },
      "related": [
        "osc-title",
        "osc-hyperlink",
        "c0-controls"
      ]
    },
    {
      "slug": "dec-sync-update",
      "family": "DEC",
      "title": {
        "en": "DECSET ?2026 — Synchronized update mode",
        "zh": "DECSET ?2026 — 同步更新模式"
      },
      "shortDesc": {
        "en": "Buffer screen updates until you signal end-of-frame — eliminates flicker on full repaints.",
        "zh": "在帧结束信号到来前缓冲屏幕更新 —— 全屏重绘时消除闪烁。"
      },
      "bytes": {
        "canonical": "\\x1b[?2026h   (begin frame)   \\x1b[?2026l   (end frame)",
        "octal": "\\033[?2026h / \\033[?2026l",
        "eEscape": "\\e[?2026h / \\e[?2026l",
        "literal": "ESC [ ? 2 0 2 6 h / l",
        "hex": "1b 5b 3f 32 30 32 36 68 / 6c"
      },
      "description": {
        "en": "Originally an iTerm2 + contour proposal, now adopted by kitty, wezterm, foot, ghostty, Windows Terminal, mintty, alacritty (1.7+), and tmux as a pass-through. Wrap a full-screen redraw between `\\x1b[?2026h` (begin synchronized update) and `\\x1b[?2026l` (end) and the terminal will hold rendering until the `l` arrives, then paint the final state once — eliminating the half-painted frames that plague neovim, helix, tui-rs, ratatui, and similar apps over slow PTYs (especially over SSH). Terminals that don't recognize `?2026` simply paint as bytes arrive, so emitting the pair is safe. Apps that want to detect support should query with the DECRQM request `\\x1b[?2026$p` and parse the reply. Recommended max in-frame time is ~100 ms — terminals abort the synchronized state on timeout to avoid a stuck screen.",
        "zh": "最早由 iTerm2 + contour 提案，如今 kitty、wezterm、foot、ghostty、Windows Terminal、mintty、alacritty（1.7+）以及 tmux（直通）均已采纳。把整屏重绘包裹在 `\\x1b[?2026h`（开始同步更新）与 `\\x1b[?2026l`（结束）之间，终端会暂停渲染直到收到 `l`，然后一次性绘制最终状态 —— 消除 neovim、helix、tui-rs、ratatui 等程序在慢速 PTY（尤其 SSH）下的半帧抖动。不识别 `?2026` 的终端按字节顺序绘制，因此可放心成对发送。需要严格检测的程序可用 DECRQM 查询 `\\x1b[?2026$p` 并解析回报。建议单帧内 ≤ 100 ms —— 超时后终端会自动中止同步状态，避免屏幕卡死。"
      },
      "spec": "Synchronized Output Mode (contour spec) / Mode 2026",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?2026h'   # begin frame\\n# … emit the full repaint here …\\nprintf '\\033[?2026l'   # end frame -> painted atomically"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[?2026h'); redraw(); sys.stdout.write('\\x1b[?2026l')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?2026h\"); redraw(); fmt.Print(\"\\x1b[?2026l\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?2026h'); redraw(); process.stdout.write('\\x1b[?2026l')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?2026h\"); redraw(); printf(\"\\x1b[?2026l\");"
        }
      ],
      "support": {
        "xterm": "no",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "alt-screen",
        "dec-mouse-tracking",
        "scroll-up-down"
      ]
    },
    {
      "slug": "dcs-sixel",
      "family": "DCS",
      "title": {
        "en": "DCS Sixel — Inline raster graphics (ESC P q … ESC \\)",
        "zh": "DCS Sixel — 内联栅格图像（ESC P q … ESC \\）"
      },
      "shortDesc": {
        "en": "Embed pixel images in the terminal stream using the Sixel device-control payload.",
        "zh": "通过 Sixel 设备控制载荷在终端流中嵌入像素图像。"
      },
      "bytes": {
        "canonical": "\\x1bPq <sixel data> \\x1b\\\\",
        "octal": "\\033Pq … \\033\\\\",
        "eEscape": "\\eP q … \\e\\\\",
        "literal": "ESC P q DATA ESC \\",
        "hex": "1b 50 71 ... 1b 5c"
      },
      "description": {
        "en": "Sixel is a DEC-era inline pixel graphics format (DEC VT240/VT340) revived by modern terminals. The frame begins with the Device Control String introducer `\\x1bP` (DCS), an optional parameter run, the `q` final byte that selects Sixel mode, then a payload of `?`..`~` printable characters where each byte encodes a 6-pixel-tall vertical slice (hence 'sixel'). The frame ends with the String Terminator — either `\\x1b\\\\` (ST, spec-correct) or `\\x07` (BEL, widely accepted). `libsixel`, `chafa`, `viu`, `timg`, `ranger`-style image previews, `kitten icat --transfer-mode=stream` (Sixel fallback for Kitty's native protocol), and `mpv --vo=sixel` all emit this sequence. Terminal support varies: xterm needs `+sb` compile and `-ti vt340`, mintty + foot + wezterm + iTerm2 + Windows Terminal Canary + ghostty work out of the box, kitty + alacritty + macOS Terminal do not (Kitty has its own better protocol).",
        "zh": "Sixel 是 DEC 时代的内联像素图形格式（DEC VT240/VT340），近年被现代终端复活。帧以设备控制字符串引导符 `\\x1bP`（DCS）开头，可选参数段后接末字节 `q` 选择 Sixel 模式，再是 `?`..`~` 的可打印字节载荷 —— 每个字节编码一个 6 像素高的竖向切片（故名 sixel）。帧以字符串终止符结尾 —— 标准形式 `\\x1b\\\\`（ST），也广泛接受 `\\x07`（BEL）。`libsixel`、`chafa`、`viu`、`timg`、`ranger` 风格的图像预览、`kitten icat --transfer-mode=stream`（Kitty 原生协议的 Sixel 回退）以及 `mpv --vo=sixel` 都使用此序列。终端支持差别明显：xterm 需 `+sb` 编译并以 `-ti vt340` 启动；mintty、foot、wezterm、iTerm2、Windows Terminal Canary、ghostty 默认可用；kitty、alacritty、macOS Terminal 不支持（Kitty 有自家更优协议）。"
      },
      "spec": "DEC VT340 Programmer Reference / xterm-ctlseqs (DCS Ps; Ps; Ps q)",
      "examples": [
        {
          "lang": "bash",
          "code": "# A 12x6 magenta block via the Sixel raw payload\\nprintf '\\033Pq#0;2;100;0;100#0~~\\033\\\\'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1bPq#0;2;100;0;100#0~~\\x1b\\\\')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1bPq#0;2;100;0;100#0~~\\x1b\\\\\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1bPq#0;2;100;0;100#0~~\\x1b\\\\')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1bPq#0;2;100;0;100#0~~\\x1b\\\\\");"
        }
      ],
      "support": {
        "xterm": "partial",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "osc-hyperlink",
        "alt-screen",
        "dec-cursor-shape"
      ]
    },
    {
      "slug": "dec-cursor-blink",
      "family": "DEC",
      "title": {
        "en": "DECSET ?12 — Cursor blink",
        "zh": "DECSET ?12 — 光标闪烁"
      },
      "shortDesc": {
        "en": "Enable or disable the blinking attribute of the cursor — independent of cursor shape.",
        "zh": "启用或关闭光标闪烁属性 —— 与光标形状无关。"
      },
      "bytes": {
        "canonical": "\\x1b[?12h   (start blinking)   \\x1b[?12l   (stop blinking)",
        "octal": "\\033[?12h / \\033[?12l",
        "eEscape": "\\e[?12h / \\e[?12l",
        "literal": "ESC [ ? 1 2 h / l",
        "hex": "1b 5b 3f 31 32 68 / 6c"
      },
      "description": {
        "en": "Toggle the cursor-blink attribute. Distinct from DECSCUSR (`\\x1b[N SP q`), which combines shape AND blink in one parameter: with `?12` you can keep the user's preferred shape (block / bar / underline) and just override whether it blinks. Used by editors that want a steady cursor in normal mode and a blinking one in insert mode WITHOUT touching the user's chosen shape. Reset to terminal default by combining with DECSCUSR `\\x1b[0 q` or DECSTR (`\\x1b[!p`).",
        "zh": "切换光标的闪烁属性。与 DECSCUSR（`\\x1b[N SP q`）不同 —— 后者把形状与闪烁合并在一个参数中。使用 `?12` 可保留用户偏好的形状（方块 / 竖线 / 下划线）只控制是否闪烁。编辑器常用：普通模式稳定光标、插入模式闪烁，但不动用户选择的形状。配合 DECSCUSR `\\x1b[0 q` 或 DECSTR（`\\x1b[!p`）恢复终端默认。"
      },
      "spec": "xterm-ctlseqs (Private mode 12)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?12h'   # start blinking\\nprintf '\\033[?12l'   # stop blinking"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[?12l')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?12l\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?12l')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?12l\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "dec-cursor-shape",
        "cursor-visibility",
        "decstr-soft-reset"
      ]
    },
    {
      "slug": "esc-hts",
      "family": "ESC",
      "title": {
        "en": "HTS — Horizontal Tab Set (ESC H)",
        "zh": "HTS — 水平制表位设置（ESC H）"
      },
      "shortDesc": {
        "en": "Set a tab stop at the current cursor column — partner to TBC.",
        "zh": "在当前光标列设置一个 tab 停位 —— 与 TBC 互为伙伴。"
      },
      "bytes": {
        "canonical": "\\x1bH",
        "octal": "\\033H",
        "eEscape": "\\eH",
        "literal": "ESC H",
        "hex": "1b 48"
      },
      "description": {
        "en": "Two-byte ESC `H` sequence (no CSI introducer, no parameters). Places a tab stop at whichever column the cursor occupies right now. Pair with TBC (`\\x1b[g` / `\\x1b[3g`) which clears tab stops. Workflow: `printf '\\033[3g'` to wipe the default 8-column grid, move the cursor to each desired column with HPA / CHA (`\\x1b[Nd` / `\\x1b[NG`) and emit `\\x1bH` once per stop. After that, every `\\t` (HT, 0x09) or `\\x1b[NI` (CHT) advances to your custom layout. The terminfo capability for HTS is `hts`.",
        "zh": "两字节序列 ESC `H`（无 CSI 引导符、无参数）。在当前光标列设置一个 tab 停位。与 TBC（`\\x1b[g` / `\\x1b[3g`，清除停位）配对。常用流程：`printf '\\033[3g'` 抹掉默认 8 列网格 → 用 HPA / CHA（`\\x1b[Nd` / `\\x1b[NG`）把光标移到目标列 → 每列发一次 `\\x1bH`。此后每个 `\\t`（HT，0x09）或 `\\x1b[NI`（CHT）都会按自定义布局推进。HTS 的 terminfo 能力名为 `hts`。"
      },
      "spec": "ECMA-48 §8.3.62 (HTS)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[3g'                # clear all\\nprintf '\\033[10G\\033H\\033[20G\\033H'   # set tab stops at cols 10 and 20"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1bH')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1bH\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1bH')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1bH\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-tbc",
        "csi-cbt",
        "csi-cht"
      ]
    },
    {
      "slug": "csi-cht",
      "family": "CSI",
      "title": {
        "en": "CHT — Cursor Forward Tabulation (CSI I)",
        "zh": "CHT — 光标正向制表（CSI I）"
      },
      "shortDesc": {
        "en": "Advance the cursor N tab stops — the parameterized form of pressing Tab.",
        "zh": "把光标按 tab 停位向前推进 N 次 —— Tab 键的可带参数版本。"
      },
      "bytes": {
        "canonical": "\\x1b[NI",
        "octal": "\\033[1I",
        "eEscape": "\\e[1I",
        "literal": "ESC [ N I",
        "hex": "1b 5b <N> 49"
      },
      "description": {
        "en": "Cursor Forward Tabulation. Final byte `I` (0x49, uppercase i) moves the cursor forward to the next tab stop, repeated N times (default 1). It is the mirror of CBT (`CSI Ps Z`) and a parameterized form of HT (`\\t`, 0x09). The terminfo cap is `cht`. Where HT moves a single tab forward, CHT lets you skip ahead by an arbitrary count without emitting N literal `\\t` bytes, which matters in raw mode where `\\t` may be consumed by line discipline.",
        "zh": "Cursor Forward Tabulation。末字节 `I`（0x49，大写 i），按 tab 停位向前推进 N 次（默认 1）。是 CBT（`CSI Ps Z`）的镜像，也是 HT（`\\t`，0x09）的可带参数形式。terminfo 能力名为 `cht`。HT 每次只能前进一个 tab，而 CHT 允许一次性跳跃任意个停位 —— 在 line discipline 可能吞掉 `\\t` 的原始模式下尤为有用。"
      },
      "spec": "ECMA-48 §8.3.10 (CHT)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf 'a\\033[3Ib'   # cursor advances 3 tab stops, then writes b"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[3I')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[3I\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[3I')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[3I\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-cbt",
        "csi-tbc",
        "esc-hts"
      ]
    },
    {
      "slug": "csi-da",
      "family": "CSI",
      "title": {
        "en": "DA — Device Attributes (CSI c / CSI > c)",
        "zh": "DA — 设备属性查询（CSI c / CSI > c）"
      },
      "shortDesc": {
        "en": "Ask the terminal what kind of VT it is — primary (CSI c) returns features, secondary (CSI > c) returns model + firmware.",
        "zh": "询问终端的 VT 类型 —— 主查询（CSI c）返回支持特性，副查询（CSI > c）返回型号与固件。"
      },
      "bytes": {
        "canonical": "\\x1b[c   (primary DA)   \\x1b[>c   (secondary DA)",
        "octal": "\\033[c / \\033[>c",
        "eEscape": "\\e[c / \\e[>c",
        "literal": "ESC [ c   /   ESC [ > c",
        "hex": "1b 5b 63   /   1b 5b 3e 63"
      },
      "description": {
        "en": "Device Attributes — a request/reply pair the application sends and the terminal answers via the input stream. **Primary DA** (`\\x1b[c`, sometimes `\\x1b[0c`) — terminal replies with `\\x1b[?64;...c` listing the VT class and supported optional features (132-column mode, sixel, ReGIS, user-defined keys, etc.). **Secondary DA** (`\\x1b[>c`, sometimes `\\x1b[>0c`) — terminal replies with `\\x1b[>Pp;Pv;Pcc` where Pp is the model (`0`=VT100, `1`=VT220, `41`=VT420, `61`=xterm-style, `65`=VT525, etc.), Pv is the firmware version, Pcc is the ROM cart serial (usually 0). Apps use DA on startup to feature-detect — neovim's `t_Co` autodetect, tmux's title-set capability probing, mintty's xterm-compat checks all rely on it.",
        "zh": "Device Attributes —— 程序发送的请求/回复对，终端通过输入流应答。**主 DA**（`\\x1b[c`，亦可写 `\\x1b[0c`）—— 终端回复 `\\x1b[?64;...c`，列出 VT 等级和可选特性（132 列模式、sixel、ReGIS、用户定义键等）。**副 DA**（`\\x1b[>c`，亦可写 `\\x1b[>0c`）—— 终端回复 `\\x1b[>Pp;Pv;Pcc`，Pp 为型号（`0`=VT100，`1`=VT220，`41`=VT420，`61`=xterm 风格，`65`=VT525 等），Pv 为固件版本，Pcc 为 ROM 序列号（通常 0）。程序常在启动时通过 DA 做特性探测 —— neovim 的 `t_Co` 自动检测、tmux 的标题能力探测、mintty 的 xterm 兼容性检查均依赖它。"
      },
      "spec": "ECMA-48 §8.3.24 (DA) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Send primary DA and read the reply (raw mode):\\nstty -echo raw min 0 time 5\\nprintf '\\033[c'; IFS= read -r -t 1 -d c REPLY; stty sane\\necho \"DA reply: $REPLY c\""
        },
        {
          "lang": "python",
          "code": "import sys, termios, tty, select\\nfd = sys.stdin.fileno(); old = termios.tcgetattr(fd); tty.setraw(fd)\\ntry:\\n    sys.stdout.write('\\x1b[c'); sys.stdout.flush()\\n    r, _, _ = select.select([fd], [], [], 1.0)\\n    print(repr(sys.stdin.read(64)) if r else 'no reply')\\nfinally:\\n    termios.tcsetattr(fd, termios.TCSADRAIN, old)"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[c\")   // request; read reply via os.Stdin in raw mode"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[c')   // reply arrives on process.stdin"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[c\"); fflush(stdout); /* read reply from stdin */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-dsr",
        "decrqm",
        "ris-reset"
      ]
    },
    {
      "slug": "csi-dsr",
      "family": "CSI",
      "title": {
        "en": "DSR — Device Status Report (CSI 5n / CSI 6n)",
        "zh": "DSR — 设备状态报告（CSI 5n / CSI 6n）"
      },
      "shortDesc": {
        "en": "Ask for terminal status (5n) or the current cursor position (6n) — the reverse channel TUIs use to size the terminal.",
        "zh": "查询终端状态（5n）或当前光标位置（6n）—— TUI 用以测量终端大小的反向通道。"
      },
      "bytes": {
        "canonical": "\\x1b[5n   (status request)   \\x1b[6n   (cursor pos request)",
        "octal": "\\033[5n / \\033[6n",
        "eEscape": "\\e[5n / \\e[6n",
        "literal": "ESC [ Ps n",
        "hex": "1b 5b <Ps> 6e"
      },
      "description": {
        "en": "Device Status Report. The application sends a request; the terminal answers on stdin. **`\\x1b[5n`** — \"are you OK?\". Reply: `\\x1b[0n` (ready) or `\\x1b[3n` (malfunction). Used as a liveness check after enabling exotic modes. **`\\x1b[6n`** (a.k.a. CPR — Cursor Position Report) — \"where is the cursor?\". Reply: `\\x1b[<row>;<col>R`. The classic trick to discover terminal size without TIOCGWINSZ is to move the cursor to the end of the screen (`\\x1b[9999;9999H`), DSR-6n, parse the reply, then restore. Modern apps prefer `ioctl(TIOCGWINSZ)` + `SIGWINCH` for resizes, but DSR-6n remains the only portable answer on systems without that ioctl (over raw serial, certain CI environments). xterm extension: `\\x1b[?6n` returns the cursor position constrained by the origin-mode flag (DECOM).",
        "zh": "Device Status Report。程序发出请求，终端在 stdin 上回复。**`\\x1b[5n`** —— 「你还好吗？」。回复：`\\x1b[0n`（就绪）或 `\\x1b[3n`（异常）。常作为启用奇特模式后的存活检查。**`\\x1b[6n`**（又名 CPR，Cursor Position Report）—— 「光标在哪？」。回复：`\\x1b[<row>;<col>R`。在没有 TIOCGWINSZ 的情况下测算终端大小的经典套路：把光标推到屏幕末端（`\\x1b[9999;9999H`），DSR-6n，解析回复，再还原。现代程序首选 `ioctl(TIOCGWINSZ)` + `SIGWINCH` 监听 resize，但缺少该 ioctl 的场景（原始串口、某些 CI 环境）下，DSR-6n 仍是唯一可移植方案。xterm 扩展：`\\x1b[?6n` 返回受 DECOM（origin mode）约束的光标位置。"
      },
      "spec": "ECMA-48 §8.3.35 (DSR) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Discover terminal size without TIOCGWINSZ:\\nstty -echo raw min 0 time 5\\nprintf '\\033[s\\033[9999;9999H\\033[6n\\033[u'\\nIFS=';' read -r -d R esc_row col; stty sane\\necho \"rows=${esc_row#*[} cols=$col\""
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[6n')   # reply arrives on stdin in raw mode"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[6n\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[6n')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[6n\"); fflush(stdout); /* parse <row>;<col>R from stdin */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-da",
        "cursor-position",
        "decrqm"
      ]
    },
    {
      "slug": "decrqm",
      "family": "CSI",
      "title": {
        "en": "DECRQM — Request Mode Status (CSI ? Ps $ p)",
        "zh": "DECRQM — 模式状态查询（CSI ? Ps $ p）"
      },
      "shortDesc": {
        "en": "Ask the terminal whether a specific DEC private mode is enabled — used for feature detection at runtime.",
        "zh": "询问终端某个 DEC 私有模式是否已启用 —— 运行时特性检测的标准方式。"
      },
      "bytes": {
        "canonical": "\\x1b[?Ps$p",
        "octal": "\\033[?Ps$p",
        "eEscape": "\\e[?Ps$p",
        "literal": "ESC [ ? Ps $ p",
        "hex": "1b 5b 3f <Ps> 24 70"
      },
      "description": {
        "en": "Request Mode (DEC variant). The intermediate `$` (0x24) and final `p` (0x70) make this a DECRQM frame for a DEC private mode `Ps`. Reply: `\\x1b[?Ps;Pm$y` where `Pm` is 0 (mode not recognised), 1 (set / enabled), 2 (reset / disabled), 3 (permanently set), or 4 (permanently reset). This is the canonical way for an application to ask, at runtime, whether a feature it wants is actually available — `\\x1b[?2026$p` for synchronized output, `\\x1b[?1004$p` for focus events, `\\x1b[?2004$p` for bracketed paste, `\\x1b[?1006$p` for SGR mouse encoding. Without DECRQM, apps degrade to optimistic emission + hope. Note: the ANSI-mode variant (no `?`) `\\x1b[Ps$p` queries non-DEC modes like KAM, IRM, SRM.",
        "zh": "Request Mode（DEC 私有变体）。中间字节 `$`（0x24）+ 末字节 `p`（0x70）使其成为针对 DEC 私有模式 `Ps` 的 DECRQM 帧。回复：`\\x1b[?Ps;Pm$y`，其中 `Pm` 取值：0（不识别该模式）、1（已置位/启用）、2（已复位/关闭）、3（永久置位）、4（永久复位）。这是程序在运行时查询某特性是否可用的标准做法 —— `\\x1b[?2026$p` 查同步输出、`\\x1b[?1004$p` 查焦点事件、`\\x1b[?2004$p` 查括号粘贴、`\\x1b[?1006$p` 查 SGR 鼠标编码。无 DECRQM 时，程序只能乐观发送然后听天由命。注意：ANSI 模式变体（不带 `?`）`\\x1b[Ps$p` 查询 KAM、IRM、SRM 等非 DEC 模式。"
      },
      "spec": "xterm-ctlseqs (DECRQM, CSI ? Ps $ p)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?2026$p'   # is synchronized-update mode available?"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[?2026$p')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?2026$p\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?2026$p')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?2026$p\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-da",
        "csi-dsr",
        "dec-sync-update"
      ]
    },
    {
      "slug": "csi-ich",
      "family": "CSI",
      "title": {
        "en": "ICH — Insert Character (CSI Pn @)",
        "zh": "ICH — 插入字符（CSI Pn @）"
      },
      "shortDesc": {
        "en": "Shift the rest of the current line right by N cells and blank-fill the gap — the primitive vim's insert mode is built on.",
        "zh": "把当前行剩余内容右移 N 格并以空白填充间隙 —— vim 插入模式的底层原语。"
      },
      "bytes": {
        "canonical": "\\x1b[Pn@",
        "octal": "\\033[Pn@",
        "eEscape": "\\e[Pn@",
        "literal": "ESC [ Pn @",
        "hex": "1b 5b <Pn> 40"
      },
      "description": {
        "en": "Insert Character. Final byte `@` (0x40) shifts the cursor position and every cell to its right within the current line rightward by `Pn` cells (default 1); cells that fall off the right edge are discarded and the `Pn`-wide gap at the cursor is filled with blanks (SP, 0x20) carrying the current SGR background. The cursor itself does not move. ICH is the primitive `vim` insert mode emits per typed character — `vim` could redraw the whole line for every keystroke, but using ICH keeps screen updates O(1) per character. Pair with DCH (`\\x1b[Pn P`) to delete the same way. ICH is bounded by the right margin (DECSTBM column-margins, if set); cells past the right margin are NOT shifted into. The terminfo capability is `ich1` (Pn=1) or `ich` (parameterised).",
        "zh": "Insert Character。末字节 `@`（0x40）—— 在当前行内，把光标位置及其右侧每个单元向右移动 `Pn` 格（默认 1）；越过右边界的单元被丢弃，光标处出现 `Pn` 宽的间隙，用空格（SP，0x20，携带当前 SGR 背景色）填充。光标位置不变。ICH 是 `vim` 插入模式每键一击发送的底层原语 —— 不使用 ICH 就得为每次击键重绘整行，使用后屏幕更新降为每字符 O(1)。与 DCH（`\\x1b[Pn P`）成对（删除）。ICH 受右边距（若设定了 DECSTBM 列边距）约束 —— 右边距外的单元不会被推入。terminfo 能力名为 `ich1`（Pn=1）或 `ich`（带参数）。"
      },
      "spec": "ECMA-48 §8.3.64 (ICH)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Move cursor to column 5, insert 3 cells, then type 'xyz' (it lands at col 5).\\nprintf 'Hello world\\033[5G\\033[3@xyz'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[3@')   # open a 3-cell gap at the cursor"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[3@\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[3@')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[3@\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-dch",
        "csi-ech",
        "erase-line"
      ]
    },
    {
      "slug": "csi-dch",
      "family": "CSI",
      "title": {
        "en": "DCH — Delete Character (CSI Pn P)",
        "zh": "DCH — 删除字符（CSI Pn P）"
      },
      "shortDesc": {
        "en": "Delete N cells at the cursor and shift the rest of the line left to fill the gap — the inverse of ICH.",
        "zh": "删除光标处 N 个单元，把剩余内容左移填补 —— ICH 的逆操作。"
      },
      "bytes": {
        "canonical": "\\x1b[PnP",
        "octal": "\\033[PnP",
        "eEscape": "\\e[PnP",
        "literal": "ESC [ Pn P",
        "hex": "1b 5b <Pn> 50"
      },
      "description": {
        "en": "Delete Character. Final byte `P` (0x50) removes `Pn` cells starting at the cursor (default 1) and shifts every cell to the right of that range left by `Pn` columns; the `Pn` cells that appear at the right edge are blank (SP, 0x20) with the current SGR background. The cursor itself does not move. DCH is what `vim`/`emacs` emit when you backspace mid-line, what `less` uses to remove the bottom-of-screen prompt, and the primitive readline edits the prompt with. Pair with ICH (`\\x1b[Pn @`). DCH stops at the right margin set by DECSTBM column-margins (if active) — cells past the margin are not pulled in. Terminfo cap: `dch1` (Pn=1) or `dch` (parameterised).",
        "zh": "Delete Character。末字节 `P`（0x50）—— 从光标处删除 `Pn` 个单元（默认 1），其右侧每个单元左移 `Pn` 列；行尾出现的 `Pn` 个单元为空格（SP，0x20，带当前 SGR 背景色）。光标位置不变。DCH 是 `vim`/`emacs` 行内退格、`less` 抹掉屏幕底端提示、readline 编辑提示符所用的底层原语。与 ICH（`\\x1b[Pn @`）成对。DCH 受 DECSTBM 列边距（若启用）约束 —— 右边距外的单元不被拉入。terminfo 能力名为 `dch1`（Pn=1）或 `dch`（带参数）。"
      },
      "spec": "ECMA-48 §8.3.26 (DCH)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Print 'Hello world', move cursor to column 6, delete 6 cells.\\nprintf 'Hello world\\033[6G\\033[6P'   # leaves 'Hello' followed by trailing blanks"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[3P')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[3P\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[3P')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[3P\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-ich",
        "csi-ech",
        "erase-line"
      ]
    },
    {
      "slug": "csi-il",
      "family": "CSI",
      "title": {
        "en": "IL — Insert Line (CSI Pn L)",
        "zh": "IL — 插入行（CSI Pn L）"
      },
      "shortDesc": {
        "en": "Open N blank lines at the cursor row and push subsequent lines down within the scrolling region — vim's 'O' command primitive.",
        "zh": "在光标所在行打开 N 行空行，把后续行向下推（在滚动区域内）—— vim 'O' 命令的底层原语。"
      },
      "bytes": {
        "canonical": "\\x1b[PnL",
        "octal": "\\033[PnL",
        "eEscape": "\\e[PnL",
        "literal": "ESC [ Pn L",
        "hex": "1b 5b <Pn> 4c"
      },
      "description": {
        "en": "Insert Line. Final byte `L` (0x4c) inserts `Pn` blank lines at the cursor row (default 1); every subsequent line inside the active scrolling region (DECSTBM, default = full screen) is pushed downward by `Pn`, and the `Pn` lines that would fall below the bottom margin are discarded. Cells in the freshly-inserted blank lines carry the current SGR background. The cursor moves to column 1 of its row (ECMA-48 says column unchanged, but most modern terminals follow the xterm convention of resetting to column 1 because that's what every TUI app expects). Used by `vim`'s `O` command (open line above), `tmux`'s pane re-layout, and any `less`-style scroll-up-by-N. Counterpart is DL (`\\x1b[Pn M`). Terminfo cap: `il1` (Pn=1) or `il` (parameterised).",
        "zh": "Insert Line。末字节 `L`（0x4c）—— 在光标所在行插入 `Pn` 行空行（默认 1）；活动滚动区域（DECSTBM，默认 = 整屏）内随后的每一行向下推 `Pn`，会超出下边距的 `Pn` 行被丢弃。新插入的空行单元携带当前 SGR 背景色。光标移至所在行的第 1 列（ECMA-48 规定列不变，但多数现代终端遵循 xterm 惯例 —— 重置到第 1 列，因为这正是所有 TUI 程序的预期）。用途：`vim` 的 `O` 命令（在上方开新行）、`tmux` 窗格重布局、`less` 风格的整组向上滚动。逆操作是 DL（`\\x1b[Pn M`）。terminfo 能力名为 `il1`（Pn=1）或 `il`（带参数）。"
      },
      "spec": "ECMA-48 §8.3.67 (IL)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Set scroll region rows 1..5, position cursor at row 3, insert 2 blank lines.\\nprintf '\\033[1;5r\\033[3;1H\\033[2L'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[2L')   # insert 2 lines at cursor row"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[2L\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[2L')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[2L\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-dl",
        "decstbm",
        "scroll-up-down"
      ]
    },
    {
      "slug": "csi-dl",
      "family": "CSI",
      "title": {
        "en": "DL — Delete Line (CSI Pn M)",
        "zh": "DL — 删除行（CSI Pn M）"
      },
      "shortDesc": {
        "en": "Remove N lines starting at the cursor row and pull subsequent lines up within the scrolling region — vim's 'dd' command primitive.",
        "zh": "删除从光标所在行起的 N 行，把后续行向上拉（在滚动区域内）—— vim 'dd' 命令的底层原语。"
      },
      "bytes": {
        "canonical": "\\x1b[PnM",
        "octal": "\\033[PnM",
        "eEscape": "\\e[PnM",
        "literal": "ESC [ Pn M",
        "hex": "1b 5b <Pn> 4d"
      },
      "description": {
        "en": "Delete Line. Final byte `M` (0x4d) removes `Pn` lines starting at the cursor row (default 1); every line below them inside the active scrolling region (DECSTBM) is pulled upward by `Pn`, and `Pn` fresh blank lines appear at the bottom of the region with the current SGR background. Cursor moves to column 1 of its row (same xterm-vs-spec column-reset behaviour as IL). DL is the primitive `vim`'s `dd` command emits, what `less` uses to scroll a line at the top off-screen, and what `tmux`'s pane resize relies on. Counterpart is IL (`\\x1b[Pn L`); used together with `\\x1b[T;Br` (DECSTBM) you get atomic small-region scrolls without redrawing the whole screen. Terminfo cap: `dl1` (Pn=1) or `dl` (parameterised).",
        "zh": "Delete Line。末字节 `M`（0x4d）—— 从光标所在行起删除 `Pn` 行（默认 1）；活动滚动区域（DECSTBM）内下方的每一行向上拉 `Pn`，区域底部出现 `Pn` 行新空行（携当前 SGR 背景色）。光标移至所在行的第 1 列（与 IL 同样的 xterm-vs-spec 列重置行为）。DL 是 `vim` 的 `dd` 命令、`less` 让顶端一行滚出可视区、`tmux` 窗格调整大小的底层原语。逆操作是 IL（`\\x1b[Pn L`）；与 `\\x1b[T;Br`（DECSTBM）配合可实现原子化的小区域滚动而无需重绘整屏。terminfo 能力名为 `dl1`（Pn=1）或 `dl`（带参数）。"
      },
      "spec": "ECMA-48 §8.3.32 (DL)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Set scroll region rows 1..5, position cursor at row 2, delete 1 line.\\nprintf '\\033[1;5r\\033[2;1H\\033[1M'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[1M')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[1M\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[1M')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[1M\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-il",
        "decstbm",
        "scroll-up-down"
      ]
    },
    {
      "slug": "csi-ech",
      "family": "CSI",
      "title": {
        "en": "ECH — Erase Character (CSI Pn X)",
        "zh": "ECH — 擦除字符（CSI Pn X）"
      },
      "shortDesc": {
        "en": "Erase N cells in place at the cursor — same shape as DCH but the rest of the line does NOT shift left.",
        "zh": "在光标处原地擦除 N 个单元 —— 形状与 DCH 相同，但行剩余内容不左移。"
      },
      "bytes": {
        "canonical": "\\x1b[PnX",
        "octal": "\\033[PnX",
        "eEscape": "\\e[PnX",
        "literal": "ESC [ Pn X",
        "hex": "1b 5b <Pn> 58"
      },
      "description": {
        "en": "Erase Character. Final byte `X` (0x58) replaces `Pn` cells starting at the cursor (default 1) with blank (SP, 0x20) cells carrying the current SGR background. The cursor does not move and the rest of the line is NOT shifted — this is the key distinction from DCH (`\\x1b[Pn P`). Used when an app wants to clear a fixed-width field (input prompt, table cell, progress bar segment) without affecting surrounding content. ECH is bounded by the right margin (DECSTBM column-margins, if active); cells past the right margin are not touched. Terminfo cap: `ech` (parameterised; no `ech1` because the no-shift semantics make the parameterised form universally needed).",
        "zh": "Erase Character。末字节 `X`（0x58）—— 从光标处起把 `Pn` 个单元（默认 1）替换为空格（SP，0x20，带当前 SGR 背景色）。光标不动，行剩余内容也不左移 —— 这是与 DCH（`\\x1b[Pn P`）的关键区别。当程序需要清空一个固定宽度的字段（输入提示、表格单元、进度条段）而不影响周围内容时使用。ECH 受 DECSTBM 列边距（若启用）约束 —— 右边距外的单元不被波及。terminfo 能力名为 `ech`（带参数；不存在 `ech1`，因为「不左移」的语义使带参数形式被普遍需要）。"
      },
      "spec": "ECMA-48 §8.3.38 (ECH)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Print a 10-char field, position at col 1, erase 5 chars in place (rest of line preserved).\\nprintf '0123456789\\033[1G\\033[5X'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[5X')   # clear 5 cells in place"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[5X\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[5X')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[5X\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-ich",
        "csi-dch",
        "erase-line"
      ]
    },
    {
      "slug": "csi-rep",
      "family": "CSI",
      "title": {
        "en": "REP — Repeat Preceding Character (CSI Pn b)",
        "zh": "REP — 重复前一个字符（CSI Pn b）"
      },
      "shortDesc": {
        "en": "Repeat the most-recently-emitted printing character N times — a bandwidth-saver for runs of identical glyphs.",
        "zh": "把上一字符重复打印 N 次 —— 节省同字符长串带宽的小窍门。"
      },
      "bytes": {
        "canonical": "\\x1b[Pnb",
        "octal": "\\033[Pnb",
        "eEscape": "\\e[Pnb",
        "literal": "ESC [ Pn b",
        "hex": "1b 5b <Pn> 62"
      },
      "description": {
        "en": "Repeat Preceding Character. Final byte `b` (0x62) prints the most-recent graphic character (the one that updated the terminal's display, NOT a control code or whitespace) `Pn` more times (default 1). If the previous emitted byte was a control or none-yet, REP is a no-op. Useful in narrow SSH links: drawing a horizontal rule of 80 `─` chars costs 80 multi-byte UTF-8 bytes (160-240 bytes) versus `─\\x1b[79b` (5 bytes + 4 control bytes = 9 bytes). Supported by xterm (since X11R5), kitty, wezterm, ghostty, alacritty, mintty, foot; Windows Terminal added support in 1.18+; iTerm2 doesn't support it. Apps that emit decorative box-drawing or progress-bar fills can preflight via XTGETTCAP for the `rep` cap before using it. Terminfo cap: `rep`.",
        "zh": "Repeat Preceding Character。末字节 `b`（0x62）—— 把最近一个图形字符（即更新过终端显示的字符，不计控制码与空白）再打印 `Pn` 次（默认 1）。若上一字节是控制码或尚无字符，REP 为空操作。在窄 SSH 链路下很有用：画一条 80 个 `─` 的横线，直接写需要 80 个多字节 UTF-8（160–240 字节）；写成 `─\\x1b[79b` 仅 5 字节字符 + 4 字节控制码 = 9 字节。xterm（自 X11R5）、kitty、wezterm、ghostty、alacritty、mintty、foot 都支持；Windows Terminal 1.18+ 添加支持；iTerm2 不支持。发送装饰性方框字符或进度条填充的程序可在使用前用 XTGETTCAP 探测 `rep` 能力。terminfo 能力名为 `rep`。"
      },
      "spec": "ECMA-48 §8.3.103 (REP)",
      "examples": [
        {
          "lang": "bash",
          "code": "# 80-char horizontal rule with minimal bytes:\\nprintf '\\xe2\\x94\\x80\\033[79b\\n'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('-\\x1b[79b\\n')   # 80 dashes"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"-\\x1b[79b\\n\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('-\\x1b[79b\\n')"
        },
        {
          "lang": "c",
          "code": "printf(\"-\\x1b[79b\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "no",
        "iterm2": "no",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "csi-ich",
        "csi-ech",
        "erase-line"
      ]
    },
    {
      "slug": "osc-cwd",
      "family": "OSC",
      "title": {
        "en": "OSC 7 — Current working directory hint",
        "zh": "OSC 7 — 当前工作目录提示"
      },
      "shortDesc": {
        "en": "Tell the terminal which directory the shell is in — used for tab labels, 'new tab here', and remote-aware split-pane workflows.",
        "zh": "把当前 shell 所在目录告知终端 —— 用于标签名、「在此目录新开标签」、远程感知的分屏工作流。"
      },
      "bytes": {
        "canonical": "\\x1b]7;file://HOST/PATH\\x07",
        "octal": "\\033]7;file://HOST/PATH\\007",
        "eEscape": "\\e]7;file://HOST/PATH\\a",
        "literal": "ESC ] 7 ; URL BEL",
        "hex": "1b 5d 37 3b ... 07"
      },
      "description": {
        "en": "Tell the terminal the shell's current working directory as a `file://HOST/PATH` URL. Adopted by iTerm2, Windows Terminal, kitty, wezterm, ghostty, Konsole, and VTE-based terminals (gnome-terminal, foot). The terminal uses this for: (a) tab / pane labels that show the basename of the directory, (b) the `Cmd-T`/`new tab here` action that spawns a new shell in the same `cwd`, (c) `tmux` resurrect / wezterm `mux` recovery that restores split panes to the right directory after a session crash. The shell emits this on every prompt — bash via `PROMPT_COMMAND`, zsh via `precmd` or `chpwd`, fish has `__fish_cwd_osc` built in. The hostname matters over SSH: the terminal can refuse to reopen a tab on the remote host since it would have to ssh again.",
        "zh": "把 shell 当前工作目录以 `file://HOST/PATH` URL 形式告知终端。iTerm2、Windows Terminal、kitty、wezterm、ghostty、Konsole 与 VTE 系（gnome-terminal、foot）均已采纳。终端用途：(a) 标签/窗格名显示目录的 basename，(b) `Cmd-T`/「在此处新开标签」在同一 cwd 启动新 shell，(c) `tmux` resurrect、wezterm `mux` 恢复会话时把分屏窗格还原到正确目录。shell 在每次提示符前发送 —— bash 通过 `PROMPT_COMMAND`、zsh 通过 `precmd` 或 `chpwd`、fish 内置 `__fish_cwd_osc`。SSH 场景下 hostname 字段决定终端是否能在远程主机重开标签（因为重新 ssh）。"
      },
      "spec": "iTerm2 Proprietary Escape Codes (OSC 7) / VTE / kitty",
      "examples": [
        {
          "lang": "bash",
          "code": "# Emit on every prompt — bash 5+\\nPROMPT_COMMAND='printf \"\\033]7;file://%s%s\\007\" \"$HOSTNAME\" \"$PWD\"'"
        },
        {
          "lang": "python",
          "code": "import os, socket, sys; sys.stdout.write(f'\\x1b]7;file://{socket.gethostname()}{os.getcwd()}\\x07')"
        },
        {
          "lang": "go",
          "code": "host, _ := os.Hostname(); wd, _ := os.Getwd(); fmt.Printf(\"\\x1b]7;file://%s%s\\x07\", host, wd)"
        },
        {
          "lang": "javascript",
          "code": "import os from 'node:os'; process.stdout.write(`\\x1b]7;file://${os.hostname()}${process.cwd()}\\x07`)"
        },
        {
          "lang": "c",
          "code": "char host[256]; gethostname(host, sizeof host); printf(\"\\x1b]7;file://%s%s\\x07\", host, getcwd(NULL, 0));"
        }
      ],
      "support": {
        "xterm": "no",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "partial",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "osc-title",
        "osc-hyperlink",
        "osc-notification"
      ]
    },
    {
      "slug": "osc-reset-fg-bg",
      "family": "OSC",
      "title": {
        "en": "OSC 110 / 111 / 112 — Reset default fg / bg / cursor colour",
        "zh": "OSC 110 / 111 / 112 — 重置默认前景 / 背景 / 光标颜色"
      },
      "shortDesc": {
        "en": "Restore the terminal's user-default foreground, background, or cursor colour after OSC 10 / 11 / 12 overrode it.",
        "zh": "在 OSC 10 / 11 / 12 修改后，把终端的默认前景、背景或光标色恢复为用户设置。"
      },
      "bytes": {
        "canonical": "\\x1b]110\\x07   (reset fg)   \\x1b]111\\x07   (reset bg)   \\x1b]112\\x07   (reset cursor)",
        "octal": "\\033]110\\007 / \\033]111\\007 / \\033]112\\007",
        "eEscape": "\\e]110\\a / \\e]111\\a / \\e]112\\a",
        "literal": "ESC ] N BEL",
        "hex": "1b 5d 31 31 30 / 31 31 31 / 31 31 32 07"
      },
      "description": {
        "en": "The reset partners of OSC 10 / 11 / 12 (set fg / bg / cursor colour). Sending one of these with no payload restores the value to whatever the user configured in their terminal preferences — much friendlier than guessing what to pass to OSC 10/11/12 to undo a temporary override. Apps that briefly remap default colours (theme-switchers, demos, terminal-recorders that need to capture a clean baseline) should always emit the corresponding `11X` on exit. OSC 112 is xterm-specific for the cursor; iTerm2 also supports it. Sending `\\x1b]110\\x07` is exactly equivalent to `\\x1b]10;?\\x07` followed by re-emitting whatever was queried — but with one round-trip-free byte.",
        "zh": "OSC 10 / 11 / 12（设置 fg / bg / 光标色）的重置伙伴。无负载发送其中一条，会把对应值恢复为用户在终端偏好中的设置 —— 比猜应该传什么给 OSC 10/11/12 才能撤销修改要友好得多。短暂改写默认色的程序（主题切换器、演示、需要捕获干净基线的录屏工具）退出时都应发送对应的 `11X`。OSC 112 是 xterm 特有（针对光标），iTerm2 亦支持。发送 `\\x1b]110\\x07` 等价于「发 `\\x1b]10;?\\x07` 查询后再重发原值」，但省掉一次往返。"
      },
      "spec": "xterm-ctlseqs (OSC 110 / 111 / 112)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]11;#000000\\007'   # override bg to pure black\\n# … later …\\nprintf '\\033]111\\007'           # restore user default bg"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]111\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]111\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]111\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]111\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "osc-set-fg-bg",
        "osc-set-palette",
        "ris-reset"
      ]
    },
    {
      "slug": "dec-origin-mode",
      "family": "DEC",
      "title": {
        "en": "DECOM ?6 — Origin mode (clip cursor addressing to scroll region)",
        "zh": "DECOM ?6 — 起点模式（把光标定位限制在滚动区域内）"
      },
      "shortDesc": {
        "en": "Make the cursor's row/column origin (1,1) be the top-left of the DECSTBM region instead of the screen.",
        "zh": "让光标的行列原点 (1,1) 变为 DECSTBM 滚动区域的左上角，而非整屏左上角。"
      },
      "bytes": {
        "canonical": "\\x1b[?6h   (origin = region)   \\x1b[?6l   (origin = screen)",
        "octal": "\\033[?6h / \\033[?6l",
        "eEscape": "\\e[?6h / \\e[?6l",
        "literal": "ESC [ ? 6 h / l",
        "hex": "1b 5b 3f 36 68 / 6c"
      },
      "description": {
        "en": "Origin Mode. With DECSTBM (`\\x1b[T;Br`) you carve out a scrolling region; DECOM controls whether subsequent cursor-position commands (`\\x1b[r;c H` CUP, `\\x1b[6n` DSR-CPR, etc.) address the region as if its top-left were (1,1) (`?6h` set) or the full screen (`?6l` reset, default). With `?6h` set: `\\x1b[1;1H` moves to the region's top-left, the cursor cannot leave the region, and DSR-CPR reports relative coordinates. Used in full-screen forms-style TUIs that want a fixed status bar at row 1 of the screen while the body — a sub-rectangle from row 2 to row N-1 — behaves as if it were the whole canvas. Note: DECOM is one of the two state bits saved/restored by DECSC (`\\x1b7`) / DECRC (`\\x1b8`).",
        "zh": "Origin Mode。通过 DECSTBM（`\\x1b[T;Br`）划出滚动区域后，DECOM 决定后续光标定位指令（`\\x1b[r;c H` CUP、`\\x1b[6n` DSR-CPR 等）是把区域左上角视作 (1,1)（`?6h` 置位）还是把整屏左上角视作 (1,1)（`?6l` 复位，默认）。`?6h` 启用后：`\\x1b[1;1H` 移到区域左上角，光标不能离开区域，DSR-CPR 报告相对坐标。常见于希望第 1 行作为屏幕固定状态栏、而主体（第 2 行至第 N-1 行的子矩形）独立运作的全屏表单式 TUI。注意：DECOM 是 DECSC（`\\x1b7`）/ DECRC（`\\x1b8`）保存与恢复的两个状态位之一。"
      },
      "spec": "xterm-ctlseqs (DECOM, Private mode 6)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[2;23r\\033[?6h\\033[1;1H'   # region = rows 2..23; origin mode on; CUP to its top-left"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[?6h')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?6h\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?6h')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?6h\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "decstbm",
        "cursor-position",
        "cursor-save-restore"
      ]
    },
    {
      "slug": "dec-alt-screen-1047",
      "family": "DEC",
      "title": {
        "en": "DECSET ?1047 — Alt screen without cursor save",
        "zh": "DECSET ?1047 — 仅切换备用屏（不保存光标）"
      },
      "shortDesc": {
        "en": "Switch to / from the alt screen WITHOUT saving the cursor — the bare-bones precursor to ?1049.",
        "zh": "切换备用屏但不保存光标 —— 比 ?1049 更原始的形式。"
      },
      "bytes": {
        "canonical": "\\x1b[?1047h   (enter alt)   \\x1b[?1047l   (leave alt)",
        "octal": "\\033[?1047h / \\033[?1047l",
        "eEscape": "\\e[?1047h / \\e[?1047l",
        "literal": "ESC [ ? 1 0 4 7 h / l",
        "hex": "1b 5b 3f 31 30 34 37 68 / 6c"
      },
      "description": {
        "en": "Three private modes exist for alt-screen handling — `?47`, `?1047`, and `?1049`. **`?1047`** switches to/from the alt screen but does NOT save or restore the cursor; **`?1048`** ONLY saves/restores the cursor (no screen switch); **`?1049`** is the modern composite: save cursor + enter alt + clear, and on exit restore alt → main + restore cursor. Apps that genuinely don't care about cursor position (animation toys, simple status-bar utilities) can save bytes with `?1047`. Apps that need both (vim, less, tmux, htop) emit `?1049` — never the lower-level pair. Note: when leaving alt-screen via `?1047l` xterm also clears the main screen before flipping, which can surprise applications expecting a non-destructive flip.",
        "zh": "alt-screen 共有三种私有模式 —— `?47`、`?1047`、`?1049`。**`?1047`** 仅切换备用屏，不保存/恢复光标；**`?1048`** 仅保存/恢复光标（不切屏）；**`?1049`** 是现代复合形式：保存光标 + 进入 alt + 清屏；退出时还原 alt → 主屏 + 恢复光标。完全不关心光标位置的程序（动画玩具、简单状态栏工具）可用 `?1047` 节省字节；既要切屏又要保留光标的程序（vim、less、tmux、htop）应直接发送 `?1049`，而非底层 pair。注意：通过 `?1047l` 离开备用屏时 xterm 还会在翻屏前清掉主屏，会令期待无损翻屏的程序意外。"
      },
      "spec": "xterm-ctlseqs (Private mode 1047)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?1047h'   # switch to alt; cursor position NOT saved\\nprintf '\\033[?1047l'   # back to main; main screen is cleared first"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[?1047h')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?1047h\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?1047h')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?1047h\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "alt-screen",
        "cursor-save-restore",
        "decstr-soft-reset"
      ]
    },
    {
      "slug": "dcs-kitty-graphics",
      "family": "DCS",
      "title": {
        "en": "Kitty graphics protocol — Inline pixel images (ESC _ G … ESC \\)",
        "zh": "Kitty 图形协议 —— 内联像素图像（ESC _ G … ESC \\）"
      },
      "shortDesc": {
        "en": "Modern alternative to Sixel: stream PNG / RGBA bytes to the terminal via the Kitty APC frame, with sane chunking and a placement protocol.",
        "zh": "Sixel 的现代替代：通过 Kitty APC 帧把 PNG / RGBA 字节流式发送给终端，配合合理的分块与放置协议。"
      },
      "bytes": {
        "canonical": "\\x1b_Ga=T,f=100,m=1;BASE64_CHUNK\\x1b\\\\",
        "octal": "\\033_Ga=...;PAYLOAD\\033\\\\",
        "eEscape": "\\e_G a=...;PAYLOAD \\e\\\\",
        "literal": "ESC _ G key=value,... ; BASE64 ESC \\",
        "hex": "1b 5f 47 ... 1b 5c"
      },
      "description": {
        "en": "The Kitty graphics protocol — designed by kitty.sh as a saner alternative to Sixel/iTerm-img — uses the APC (Application Program Command) frame: introducer `\\x1b_` (ESC _ ), the literal `G` to mark a graphics command, a comma-separated key=value control header (`a=T` transmit + display, `f=100` PNG, `f=24` RGB, `f=32` RGBA, `s` `v` width/height in pixels, `m=1` more chunks coming / `m=0` last chunk, `i=ID` image ID for re-placement), `;`, then a base64 payload of up to 4096 bytes per chunk, terminated by ST (`\\x1b\\\\`). Supported natively by kitty + ghostty + wezterm; konsole has partial support. iTerm2's own `\\x1b]1337;File=...` proprietary protocol is an alternative; both are converging on Kitty's design. Sixel (DCS `Pq`) is the legacy fallback for terminals without either.",
        "zh": "Kitty 图形协议 —— kitty.sh 设计的 Sixel/iTerm-img 现代替代 —— 使用 APC（Application Program Command）帧：引导符 `\\x1b_`（ESC _），字面 `G` 标识图形命令，逗号分隔的 key=value 控制头（`a=T` 传输并显示、`f=100` PNG、`f=24` RGB、`f=32` RGBA、`s` `v` 像素宽高、`m=1` 还有后续分块/`m=0` 最后一块、`i=ID` 图像 ID 便于重新放置），`;`，然后每块最多 4096 字节的 base64 载荷，以 ST（`\\x1b\\\\`）结尾。kitty + ghostty + wezterm 原生支持；konsole 部分支持。iTerm2 自家 `\\x1b]1337;File=...` 协议是另一选项；两者正逐步向 Kitty 的设计靠拢。Sixel（DCS `Pq`）是两者均不支持时的传统回退。"
      },
      "spec": "Kitty Graphics Protocol (sw.kovidgoyal.net/kitty/graphics-protocol/)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Display a PNG file inline (one-shot, no chunking):\\nb64=$(base64 -w0 cat.png)\\nprintf '\\033_Ga=T,f=100;%s\\033\\\\' \"$b64\""
        },
        {
          "lang": "python",
          "code": "import base64, sys\\npng = open('cat.png','rb').read()\\nsys.stdout.write('\\x1b_Ga=T,f=100;' + base64.b64encode(png).decode() + '\\x1b\\\\')"
        },
        {
          "lang": "go",
          "code": "data, _ := os.ReadFile(\"cat.png\")\\nfmt.Printf(\"\\x1b_Ga=T,f=100;%s\\x1b\\\\\\\\\", base64.StdEncoding.EncodeToString(data))"
        },
        {
          "lang": "javascript",
          "code": "import fs from 'node:fs';\\nconst b64 = fs.readFileSync('cat.png').toString('base64');\\nprocess.stdout.write('\\x1b_Ga=T,f=100;' + b64 + '\\x1b\\\\')"
        },
        {
          "lang": "c",
          "code": "/* read PNG into buf, base64-encode, then: */\\nprintf(\"\\x1b_Ga=T,f=100;%s\\x1b\\\\\\\\\", b64);"
        }
      ],
      "support": {
        "xterm": "no",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "no",
        "konsole": "partial"
      },
      "related": [
        "dcs-sixel",
        "osc-hyperlink",
        "alt-screen"
      ]
    },
    {
      "slug": "dcs-decrqss",
      "family": "DCS",
      "title": {
        "en": "DECRQSS — Request Selection or Setting (DCS $ q ... ST)",
        "zh": "DECRQSS — 请求选区或设置（DCS $ q ... ST）"
      },
      "shortDesc": {
        "en": "Ask the terminal to report the current value of any SGR / mode / margin / cursor-shape setting — the catch-all DCS query.",
        "zh": "请求终端报告任一 SGR / 模式 / 边距 / 光标形状当前值 —— DCS 通用查询。"
      },
      "bytes": {
        "canonical": "\\x1bP$q<P>\\x1b\\\\",
        "octal": "\\033P$q<P>\\033\\\\",
        "eEscape": "\\eP$q<P>\\e\\\\",
        "literal": "ESC P $ q <P> ESC \\",
        "hex": "1b 50 24 71 ... 1b 5c"
      },
      "description": {
        "en": "Request Selection or Setting. A DCS frame whose intermediate is `$` (0x24) and final is `q` (0x71); the body `<P>` names the setting whose value the application wants reported. Common probes: `\\x1bP$qm\\x1b\\\\` asks for the active SGR attributes (terminal replies `\\x1bP1$rm\\x1b\\\\` listing the current colour/style stack), `\\x1bP$q r\\x1b\\\\` (the literal sequence `$ q SP r`) reports DECSTBM scroll-region margins, `\\x1bP$q\" p\\x1b\\\\` reports the DECSCL conformance level, `\\x1bP$q\" q\\x1b\\\\` reports DECSCA character protection, and `\\x1bP$q q\\x1b\\\\` (` SP q`) reports the active DECSCUSR cursor shape. The reply uses the same DCS shape — leading byte `1` (valid + supported) or `0` (invalid request), then `$r`, the requested-setting bytes, and ST. Modern apps use DECRQSS in startup probes so they can restore the terminal's pre-existing state when they exit — `vim`'s `t_RV` autodetection, `bat`'s syntax-theme picker, and `kitty kitten themes` all rely on it.",
        "zh": "Request Selection or Setting。中间字节 `$`（0x24）、末字节 `q`（0x71）的 DCS 帧；体 `<P>` 指明要查询的设置。常见探测：`\\x1bP$qm\\x1b\\\\` 查询当前 SGR 属性（终端以 `\\x1bP1$rm\\x1b\\\\` 回报当前颜色/样式栈）；`\\x1bP$q r\\x1b\\\\`（字面 `$ q SP r`）查询 DECSTBM 滚动区域上下边距；`\\x1bP$q\" p\\x1b\\\\` 查询 DECSCL 一致性级别；`\\x1bP$q\" q\\x1b\\\\` 查询 DECSCA 字符保护；`\\x1bP$q q\\x1b\\\\`（`SP q`）查询当前 DECSCUSR 光标形状。回复同样是 DCS 帧 —— 首字节 `1`（有效且支持）或 `0`（请求无效），随后 `$r`、所请求的设置字节、ST。现代程序在启动探测时使用 DECRQSS，以便退出时恢复终端的原有状态 —— `vim` 的 `t_RV` 自动检测、`bat` 的语法主题选择、`kitty kitten themes` 都依赖它。"
      },
      "spec": "xterm-ctlseqs (DECRQSS, DCS $ q Pt ST)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Ask for the current SGR attributes; reply lands on stdin in raw mode.\\nstty -echo raw min 0 time 5\\nprintf '\\033P$qm\\033\\\\'; IFS= read -r -t 1 -d '\\\\' REPLY; stty sane\\necho \"DECRQSS m reply: $REPLY\""
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1bP$qm\\x1b\\\\\\\\')   # reply arrives on stdin"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1bP$qm\\x1b\\\\\\\\\")   // request current SGR"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1bP$qm\\x1b\\\\\\\\')   // request current SGR; read process.stdin"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1bP$qm\\x1b\\\\\\\\\"); fflush(stdout); /* read DCS reply from stdin */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "csi-da",
        "csi-dsr",
        "decrqm"
      ]
    },
    {
      "slug": "dcs-termcap-query",
      "family": "DCS",
      "title": {
        "en": "XTGETTCAP — Request terminfo capability (DCS + q ... ST)",
        "zh": "XTGETTCAP — 请求 terminfo 能力（DCS + q ... ST）"
      },
      "shortDesc": {
        "en": "Ask the terminal to report a terminfo capability value by its name — the runtime way to probe true-colour, RGB, OSC 52, etc.",
        "zh": "按名称请求终端报告 terminfo 能力值 —— 运行时探测真彩、RGB、OSC 52 等的标准方法。"
      },
      "bytes": {
        "canonical": "\\x1bP+q<HEX-NAME>;<HEX-NAME>...\\x1b\\\\",
        "octal": "\\033P+q<HEX-NAME>\\033\\\\",
        "eEscape": "\\eP+q<HEX-NAME>\\e\\\\",
        "literal": "ESC P + q HEX[;HEX...] ESC \\",
        "hex": "1b 50 2b 71 ... 1b 5c"
      },
      "description": {
        "en": "XTGETTCAP — xterm's terminfo-cap query, a DCS frame whose intermediate is `+` (0x2b) and final is `q` (0x71). The body is one or more terminfo capability names encoded as ASCII-hex (no separators inside a name, `;` between names). For example `RGB` becomes `524742`, `setrgbf` becomes `73657472676266`, `Smulx` (extended underline) becomes `536d756c78`. The terminal replies with one DCS per requested cap: `\\x1bP1+r<HEX-NAME>=<HEX-VALUE>\\x1b\\\\` on success, `\\x1bP0+r<HEX-NAME>\\x1b\\\\` if the cap is unknown. This is the canonical modern way `tmux`, `neovim`, `kitty`'s shell-integration, and `wezterm`'s `mux` discover feature support at runtime instead of trusting the `$TERM` string. xterm itself, kitty, wezterm, ghostty and tmux understand it; most other terminals return the 0+r 'unknown' reply for everything, which apps interpret as 'fall back to TERM-string heuristics'.",
        "zh": "XTGETTCAP —— xterm 的 terminfo 能力查询，中间字节 `+`（0x2b）、末字节 `q`（0x71）的 DCS 帧。体为一个或多个 terminfo 能力名，按 ASCII-hex 编码（名称内无分隔符，名称之间用 `;`）。例如 `RGB` 编码为 `524742`、`setrgbf` 编码为 `73657472676266`、`Smulx`（扩展下划线）编码为 `536d756c78`。终端按请求逐项回复 DCS：成功为 `\\x1bP1+r<HEX-NAME>=<HEX-VALUE>\\x1b\\\\`，未识别为 `\\x1bP0+r<HEX-NAME>\\x1b\\\\`。这是 `tmux`、`neovim`、`kitty` 的 shell 集成、`wezterm` 的 `mux` 在运行时探测特性支持的标准做法，而不是仅信任 `$TERM` 字符串。xterm 本身、kitty、wezterm、ghostty 与 tmux 支持；其他终端多数对所有请求返回 0+r「未识别」，程序据此回落到 TERM-string 启发式。"
      },
      "spec": "xterm-ctlseqs (XTGETTCAP, DCS + q Pt ST)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Ask if the terminal advertises the RGB cap (hex of 'RGB' is 524742):\\nstty -echo raw min 0 time 5\\nprintf '\\033P+q524742\\033\\\\'\\nIFS= read -r -t 1 -d '\\\\' REPLY; stty sane\\necho \"XTGETTCAP RGB reply: $REPLY\""
        },
        {
          "lang": "python",
          "code": "import sys\\nname_hex = 'RGB'.encode().hex()   # -> '524742'\\nsys.stdout.write(f'\\x1bP+q{name_hex}\\x1b\\\\\\\\')   # reply on stdin"
        },
        {
          "lang": "go",
          "code": "name := hex.EncodeToString([]byte(\"RGB\"))\\nfmt.Printf(\"\\x1bP+q%s\\x1b\\\\\\\\\", name)"
        },
        {
          "lang": "javascript",
          "code": "const name = Buffer.from('RGB').toString('hex')   // 524742\\nprocess.stdout.write(`\\x1bP+q${name}\\x1b\\\\\\\\`)"
        },
        {
          "lang": "c",
          "code": "/* hex-encode the cap name first, e.g. 'RGB' -> \"524742\" */\\nprintf(\"\\x1bP+q524742\\x1b\\\\\\\\\"); fflush(stdout);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "csi-da",
        "dcs-decrqss",
        "c1-controls"
      ]
    },
    {
      "slug": "dcs-decudk",
      "family": "DCS",
      "title": {
        "en": "DECUDK — Define User-Defined Keys (DCS Pc;Pl|Ky/St;... ST)",
        "zh": "DECUDK — 定义用户自定义键（DCS Pc;Pl|Ky/St;... ST）"
      },
      "shortDesc": {
        "en": "Remap the DEC user-defined function keys (F6–F20) at runtime — legacy DEC VT, still decoded by xterm and its forks.",
        "zh": "运行时重映射 DEC 用户自定义功能键（F6–F20）—— DEC VT 遗留，xterm 及其分叉仍解析。"
      },
      "bytes": {
        "canonical": "\\x1bPPc;Pl|Ky/St;Ky/St;...\\x1b\\\\",
        "octal": "\\033PPc;Pl|Ky/St;...\\033\\\\",
        "eEscape": "\\ePPc;Pl|Ky/St;...\\e\\\\",
        "literal": "ESC P Pc ; Pl | Ky / St ; ... ESC \\",
        "hex": "1b 50 ... 1b 5c"
      },
      "description": {
        "en": "DECUDK — Define User-Defined Keys. The DCS frame whose body starts with two numeric parameters separated by `;`, then a `|` literal, then one-or-more `Ky/St` pairs separated by `;`. **Pc** = clear-policy: `0` clear all keys first, `1` clear only the keys being defined. **Pl** = lock-state: `0` lock the definitions (further DECUDK ignored until DECSTR), `1` keep unlocked. **Ky** = the key code (17 = F6, 18 = F7, ..., 34 = F20; F1–F5 are reserved as terminal-local). **St** = the replacement bytes, hex-encoded (two ASCII hex chars per byte). On a DEC VT520 the user could thus map F6 to send `vim<CR>` by emitting `\\x1bP1;1|17/76696D0D\\x1b\\\\`. xterm honours DECUDK by routing the hex payload into its translation table for the named PF key. Modern emulators that draw their own UI for shortcut binding (kitty, wezterm) ignore DECUDK in favour of their config file, but xterm + mintty + some industrial terminals still implement it. Practical value today: legacy DEC software, terminal-test-suites (`vttest` includes a DECUDK page), and emulator development.",
        "zh": "DECUDK —— Define User-Defined Keys。DCS 帧的体以两个数字参数（`;` 分隔）开头，紧跟字面 `|`，再是若干 `Ky/St` 对（`;` 分隔）。**Pc** = 清除策略：`0` 先清空所有键、`1` 只清除即将定义的键。**Pl** = 锁定状态：`0` 锁定定义（后续 DECUDK 被忽略直到 DECSTR）、`1` 保持解锁。**Ky** = 键码（17 = F6、18 = F7、…、34 = F20；F1–F5 为终端保留）。**St** = 替换字节，逐字节两位 ASCII 十六进制。例如 DEC VT520 上把 F6 映射为发送 `vim<CR>` 即可发出 `\\x1bP1;1|17/76696D0D\\x1b\\\\`。xterm 接受 DECUDK，将十六进制载荷写入对应 PF 键的转译表。自带快捷键 UI 的现代终端（kitty、wezterm）通常忽略 DECUDK 而依赖配置文件；xterm、mintty 与部分工业终端仍实现。今日价值：DEC 遗留软件、终端测试套件（`vttest` 含 DECUDK 测试页）、终端模拟器开发。"
      },
      "spec": "DEC STD 070 (DECUDK) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Map F6 to literally type 'vim\\\\n' when pressed (key code 17, hex 76 69 6d 0d):\\nprintf '\\033P1;1|17/76696D0D\\033\\\\'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1bP1;1|17/76696D0D\\x1b\\\\\\\\')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1bP1;1|17/76696D0D\\x1b\\\\\\\\\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1bP1;1|17/76696D0D\\x1b\\\\\\\\')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1bP1;1|17/76696D0D\\x1b\\\\\\\\\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "c1-controls",
        "dcs-decdld",
        "dcs-decrqss"
      ]
    },
    {
      "slug": "dcs-decdld",
      "family": "DCS",
      "title": {
        "en": "DECDLD — Dynamically Redefinable Character Set (DCS ... { ... ST)",
        "zh": "DECDLD — 动态可重定义字符集（DCS ... { ... ST）"
      },
      "shortDesc": {
        "en": "Download a soft glyph bitmap into a slot the terminal can then display alongside the built-in font — pure DEC VT220+ legacy.",
        "zh": "把软字模位图下载到终端的某个槽位，便可与内置字体并列显示 —— DEC VT220+ 纯遗留特性。"
      },
      "bytes": {
        "canonical": "\\x1bPPfn;Pcn;Pe;Pcms;Pw;Pt{Dscs Sxbp1;Sxbp2;...\\x1b\\\\",
        "octal": "\\033PPfn;Pcn;Pe;Pcms;Pw;Pt{Dscs ...\\033\\\\",
        "eEscape": "\\ePPfn;Pcn;Pe;Pcms;Pw;Pt{Dscs ...\\e\\\\",
        "literal": "ESC P Pfn ; Pcn ; Pe ; Pcms ; Pw ; Pt { Dscs SIXEL-DATA ESC \\",
        "hex": "1b 50 ... 7b ... 1b 5c"
      },
      "description": {
        "en": "DECDLD — Dynamically Redefinable Character Set. A DCS frame whose body is a 6-parameter header followed by the literal `{` (0x7b), a final byte naming the Dynamic Soft Character Set, then per-glyph sixel-encoded bitmaps separated by `/` (column break) and `;` (next glyph). **Pfn** = font number, **Pcn** = starting character code in the slot, **Pe** = erase control (0 = erase all glyphs, 2 = erase only ones being redefined), **Pcms** = character matrix size, **Pw** = font width (5 = 80 columns, 6 = 132 columns), **Pt** = text/full-cell mode. The payload is the same `?`..`~` sixel alphabet as `dcs-sixel`, but each byte encodes a 6-pixel vertical strip of one glyph cell. xterm, vttest, and `tek4014` emulators decode it; modern terminals universally ignore — their fonts come from the OS font system and they have no concept of a per-session bitmap slot. Still relevant today: terminal-spec authors (vttest's font-edit page), historical-VT preservation projects, and emulator developers who need a DECDLD decode path for compatibility tests.",
        "zh": "DECDLD —— Dynamically Redefinable Character Set。DCS 帧的体是 6 个参数的头部，随后是字面 `{`（0x7b），再是命名 Dynamic Soft Character Set 的末字节，最后是逐字模的 sixel 位图（`/` 表示列断、`;` 表示下一字模）。**Pfn** = 字模编号、**Pcn** = 槽内起始字符码、**Pe** = 擦除控制（0 = 全部擦除、2 = 只擦即将重定义的）、**Pcms** = 字模点阵大小、**Pw** = 字模宽度（5 = 80 列、6 = 132 列）、**Pt** = 文本/全格模式。载荷与 `dcs-sixel` 共用 `?`..`~` 字母表，但每字节编码一字模格内的 6 像素竖向条。xterm、vttest 与 `tek4014` 模拟器解码；现代终端普遍忽略 —— 它们的字体来自操作系统字体系统，没有「按会话槽位」的位图概念。今日仍相关的场景：终端规范作者（vttest 的字模编辑页）、历史 VT 保育项目、需为兼容测试实现 DECDLD 解析的模拟器开发者。"
      },
      "spec": "DEC STD 070 (DECDLD)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Define one tiny glyph at code 41 (capital 'A') in font slot 1 — payload is a 1-cell sixel.\\nprintf '\\033P1;41;0;15;0;0{ @???A;????\\033\\\\'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1bP1;41;0;15;0;0{ @???A;????\\x1b\\\\\\\\')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1bP1;41;0;15;0;0{ @???A;????\\x1b\\\\\\\\\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1bP1;41;0;15;0;0{ @???A;????\\x1b\\\\\\\\')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1bP1;41;0;15;0;0{ @???A;????\\x1b\\\\\\\\\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "dcs-decudk",
        "dcs-sixel",
        "c1-controls"
      ]
    },
    {
      "slug": "osc-cursor-color",
      "family": "OSC",
      "title": {
        "en": "OSC 12 — Set cursor colour (and query)",
        "zh": "OSC 12 — 设置光标颜色（与查询）"
      },
      "shortDesc": {
        "en": "Override the terminal's cursor colour, or query the current value via the OSC reply.",
        "zh": "覆写终端光标颜色，或通过 OSC 回报查询当前值。"
      },
      "bytes": {
        "canonical": "\\x1b]12;#RRGGBB\\x07   (set)   \\x1b]12;?\\x07   (query)",
        "octal": "\\033]12;#RRGGBB\\007",
        "eEscape": "\\e]12;#RRGGBB\\a",
        "literal": "ESC ] 12 ; COLOR BEL",
        "hex": "1b 5d 31 32 3b ... 07"
      },
      "description": {
        "en": "OSC 12 sets the colour of the text cursor (the block / bar / underline drawn at the input position). The colour argument accepts the same syntaxes as OSC 10 / 11: `#RRGGBB`, `#RGB`, `rgb:RRRR/GGGG/BBBB`, or X11 colour names. Sending `?` instead of a colour (`\\x1b]12;?\\x07`) makes the terminal reply with the current cursor colour using the same syntax — used by themes and `:set background=...` autodetect tools to query the live palette. Reset the cursor colour back to the user's terminal default with OSC 112 (`\\x1b]112\\x07`). Distinct from cursor SHAPE (`\\x1b[? q` — DECSCUSR) and cursor VISIBILITY (`\\x1b[?25h/l`), which control glyph and on/off — OSC 12 only changes the colour.",
        "zh": "OSC 12 设置文本光标（即输入位置绘制的块状 / 竖条 / 下划线）的颜色。颜色参数与 OSC 10 / 11 接受同样的写法：`#RRGGBB`、`#RGB`、`rgb:RRRR/GGGG/BBBB`、X11 颜色名。将颜色改为 `?`（`\\x1b]12;?\\x07`），终端会用同一语法回报当前光标色 —— 主题脚本与 `:set background=...` 自动检测会以此读取实时调色板。用 OSC 112（`\\x1b]112\\x07`）恢复用户在终端偏好中设置的默认光标色。与光标形状（`\\x1b[? q` — DECSCUSR）和光标可见性（`\\x1b[?25h/l`）相互独立，OSC 12 只改变颜色。"
      },
      "spec": "xterm-ctlseqs (OSC 12 / 112)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]12;#f38ba8\\007'   # set cursor to pink\\nprintf '\\033]12;?\\007'         # query current cursor colour"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]12;#f38ba8\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]12;#f38ba8\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]12;#f38ba8\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]12;#f38ba8\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "osc-set-fg-bg",
        "osc-reset-fg-bg",
        "dec-cursor-shape",
        "dec-cursor-blink"
      ]
    },
    {
      "slug": "osc-highlight-bg",
      "family": "OSC",
      "title": {
        "en": "OSC 17 — Set highlight (selection) background colour",
        "zh": "OSC 17 — 设置高亮（选区）背景色"
      },
      "shortDesc": {
        "en": "Change the background colour the terminal paints behind selected (highlighted) text.",
        "zh": "修改终端在选中（高亮）文字后面绘制的背景色。"
      },
      "bytes": {
        "canonical": "\\x1b]17;#RRGGBB\\x07   (set)   \\x1b]17;?\\x07   (query)",
        "octal": "\\033]17;#RRGGBB\\007",
        "eEscape": "\\e]17;#RRGGBB\\a",
        "literal": "ESC ] 17 ; COLOR BEL",
        "hex": "1b 5d 31 37 3b ... 07"
      },
      "description": {
        "en": "OSC 17 sets the background colour used for selected (mouse-highlighted) text in the terminal — the band of colour you see behind a click-drag selection. Colour syntax matches OSC 10 / 11 / 12: `#RRGGBB`, `#RGB`, `rgb:RRRR/GGGG/BBBB`, X11 names. Sending `?` queries the current value (the terminal replies with `\\x1b]17;rgb:...\\x07`). Historically xterm-specific (paired with OSC 19 for highlight fg); most modern terminals expose selection colour only through their config file or theme engine and ignore the runtime OSC. Use the matching reset `\\x1b]117\\x07` to restore the user's configured highlight bg. Note: the foreground partner is OSC 19, not OSC 18 — OSC 18 is reserved for the Tek-emulator cursor colour and obsolete.",
        "zh": "OSC 17 设置终端中选中（鼠标高亮）文字所用的背景色 —— 即点击拖拽选区时看到的色带。颜色语法与 OSC 10 / 11 / 12 相同：`#RRGGBB`、`#RGB`、`rgb:RRRR/GGGG/BBBB`、X11 颜色名。发送 `?` 查询当前值（终端回报 `\\x1b]17;rgb:...\\x07`）。历史上为 xterm 专有（与 OSC 19 高亮前景色配对）；现代终端大多只通过配置文件或主题引擎暴露选区颜色，会忽略运行时 OSC。配对的复位为 `\\x1b]117\\x07`，恢复用户配置的高亮背景。注意：前景色伙伴是 OSC 19 而非 OSC 18 —— OSC 18 留给 Tek 模拟器光标色，已废弃。"
      },
      "spec": "xterm-ctlseqs (OSC 17 / 117)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]17;#45475a\\007'   # set selection bg\\nprintf '\\033]17;?\\007'         # query"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]17;#45475a\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]17;#45475a\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]17;#45475a\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]17;#45475a\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "partial",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "osc-highlight-fg",
        "osc-set-fg-bg",
        "sgr-reverse"
      ]
    },
    {
      "slug": "osc-highlight-fg",
      "family": "OSC",
      "title": {
        "en": "OSC 19 — Set highlight (selection) foreground colour",
        "zh": "OSC 19 — 设置高亮（选区）前景色"
      },
      "shortDesc": {
        "en": "Change the foreground colour the terminal uses for selected (highlighted) text.",
        "zh": "修改终端为选中（高亮）文字渲染的前景色。"
      },
      "bytes": {
        "canonical": "\\x1b]19;#RRGGBB\\x07   (set)   \\x1b]19;?\\x07   (query)",
        "octal": "\\033]19;#RRGGBB\\007",
        "eEscape": "\\e]19;#RRGGBB\\a",
        "literal": "ESC ] 19 ; COLOR BEL",
        "hex": "1b 5d 31 39 3b ... 07"
      },
      "description": {
        "en": "OSC 19 sets the foreground colour used for selected (mouse-highlighted) text — the glyph colour you see on top of the OSC 17 highlight band. Colour syntax matches OSC 10 / 11 / 12 / 17: `#RRGGBB`, `#RGB`, `rgb:RRRR/GGGG/BBBB`, X11 names. Sending `?` queries the current value (the terminal replies with `\\x1b]19;rgb:...\\x07`). Like OSC 17 this is historically xterm-specific and most modern terminals route selection colours through their theme config rather than runtime OSC; check the support matrix before relying on it. Use the matching reset `\\x1b]119\\x07` to restore the user's configured highlight fg.",
        "zh": "OSC 19 设置选中（鼠标高亮）文字的前景色 —— 即覆盖在 OSC 17 高亮色带之上的字形颜色。颜色语法与 OSC 10 / 11 / 12 / 17 相同：`#RRGGBB`、`#RGB`、`rgb:RRRR/GGGG/BBBB`、X11 颜色名。发送 `?` 查询当前值（终端回报 `\\x1b]19;rgb:...\\x07`）。与 OSC 17 类似，本控制码历史上为 xterm 专有；现代终端多通过主题配置而非运行时 OSC 提供选区颜色，发送前请先查支持矩阵。配对的复位为 `\\x1b]119\\x07`，恢复用户配置的高亮前景。"
      },
      "spec": "xterm-ctlseqs (OSC 19 / 119)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]19;#cdd6f4\\007'   # set selection fg\\nprintf '\\033]19;?\\007'         # query"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]19;#cdd6f4\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]19;#cdd6f4\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]19;#cdd6f4\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]19;#cdd6f4\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "partial",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "osc-highlight-bg",
        "osc-set-fg-bg",
        "sgr-reverse"
      ]
    },
    {
      "slug": "osc-reset-palette",
      "family": "OSC",
      "title": {
        "en": "OSC 104 — Reset palette colour (one index or all)",
        "zh": "OSC 104 — 重置调色板颜色（单项或全部）"
      },
      "shortDesc": {
        "en": "Restore one palette index — or the whole 256-colour palette — to the terminal's user-configured defaults.",
        "zh": "把调色板中某一项 —— 或整个 256 色调色板 —— 恢复为终端用户配置的默认值。"
      },
      "bytes": {
        "canonical": "\\x1b]104;N\\x07   (reset index N)   \\x1b]104\\x07   (reset all)",
        "octal": "\\033]104;N\\007 / \\033]104\\007",
        "eEscape": "\\e]104;N\\a / \\e]104\\a",
        "literal": "ESC ] 104 ; N BEL   /   ESC ] 104 BEL",
        "hex": "1b 5d 31 30 34 3b <N> 07   /   1b 5d 31 30 34 07"
      },
      "description": {
        "en": "OSC 104 is the reset partner of OSC 4 (set palette colour). With one numeric argument (`\\x1b]104;N\\x07`) it restores palette index `N` (0..255) to the user-configured default; with no argument (`\\x1b]104\\x07`) it resets every entry in the working palette at once. Multiple indices can be reset in one frame as a `;`-separated list (`\\x1b]104;0;1;7\\x07`). Used by base16-themes, pywal, and recording tools on exit to undo any OSC 4 overrides they applied during the session — without this the next shell that inherits the same terminal would see the modified palette. Pair OSC 104 with OSC 110 / 111 / 112 (reset default fg / bg / cursor — see osc-reset-fg-bg) to fully unwind a colour-management session.",
        "zh": "OSC 104 是 OSC 4（设置调色板颜色）的复位伙伴。带一个数字参数（`\\x1b]104;N\\x07`）时，把调色板第 `N` 项（0..255）恢复为用户配置默认值；不带参数（`\\x1b]104\\x07`）时，一次性重置整个工作调色板的每一项。可在同一帧内用 `;` 分隔列出多个索引一并重置（`\\x1b]104;0;1;7\\x07`）。base16 主题、pywal 与录屏工具退出时常用此控制码撤销会话中应用的 OSC 4 改写 —— 否则下一个继承同一终端的 shell 会看到改过的调色板。OSC 104 配合 OSC 110 / 111 / 112（重置默认 fg / bg / 光标 —— 见 osc-reset-fg-bg）可完整撤销一次色彩管理会话。"
      },
      "spec": "xterm-ctlseqs (OSC 104)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]104;1\\007'      # reset palette index 1 (red)\\nprintf '\\033]104\\007'        # reset entire palette\\nprintf '\\033]104;0;1;7\\007'  # reset indices 0, 1, 7 in one frame"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]104\\x07')   # reset whole palette"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]104\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]104\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]104\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "osc-set-palette",
        "osc-reset-fg-bg",
        "ris-reset"
      ]
    },
    {
      "slug": "osc-icon-name",
      "family": "OSC",
      "title": {
        "en": "OSC 1 — Set icon name (separate from window title)",
        "zh": "OSC 1 — 设置图标名（与窗口标题分离）"
      },
      "shortDesc": {
        "en": "Set the X11-style icon name independent of the visible window title — historically the label shown when the window is minimised.",
        "zh": "独立于可见窗口标题设置 X11 风格的图标名 —— 历史上为窗口最小化时显示的标签。"
      },
      "bytes": {
        "canonical": "\\x1b]1;ICON-NAME\\x07",
        "octal": "\\033]1;ICON-NAME\\007",
        "eEscape": "\\e]1;ICON-NAME\\a",
        "literal": "ESC ] 1 ; ICON-NAME BEL",
        "hex": "1b 5d 31 3b ... 07"
      },
      "description": {
        "en": "OSC 1 sets the icon name — historically the short label X11 showed for a minimised window (versus OSC 2 which set the long title visible in the title bar). OSC 0 sets both at once; OSC 1 sets only the icon name; OSC 2 sets only the title. On X11/xterm + gnome-terminal + konsole + mlterm + foot this still works as designed — the window manager picks up the icon-name attribute via XSetWMIconName. On non-X11 terminals (Windows Terminal, iTerm2, kitty, alacritty, wezterm, ghostty) there is no separate icon-name surface to render to, so most ignore OSC 1 entirely or quietly treat it as a no-op. Use OSC 0 if you want both updated together (the safe default for cross-platform tools); use OSC 1 only when you specifically need to leave the title bar untouched while updating the minimised label.",
        "zh": "OSC 1 设置图标名 —— 历史上为 X11 在最小化窗口处显示的短标签（OSC 2 设置标题栏可见的长标题）。OSC 0 一次设置两者；OSC 1 只设置图标名；OSC 2 只设置标题。在 X11/xterm + gnome-terminal + konsole + mlterm + foot 上仍按设计工作 —— 窗口管理器通过 XSetWMIconName 读取图标名属性。在非 X11 终端（Windows Terminal、iTerm2、kitty、alacritty、wezterm、ghostty）上没有独立的图标名渲染面，因此多数完全忽略 OSC 1，或当作无操作。希望同步更新两者（跨平台工具的安全默认）请用 OSC 0；只在需要保留标题栏不动而更新最小化标签时才用 OSC 1。"
      },
      "spec": "xterm-ctlseqs (OSC 1)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]1;build-watch\\007'   # icon name only; title bar untouched"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]1;build-watch\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]1;build-watch\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]1;build-watch\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]1;build-watch\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "osc-title",
        "osc-hyperlink",
        "osc-cwd"
      ]
    },
    {
      "slug": "osc-mouse-cursor",
      "family": "OSC",
      "title": {
        "en": "OSC 22 — Set X11 mouse pointer / cursor name",
        "zh": "OSC 22 — 设置 X11 鼠标指针 / 光标名"
      },
      "shortDesc": {
        "en": "Override the mouse-pointer glyph the terminal window draws — historically xterm-specific, exposed via standard X cursor names.",
        "zh": "覆写终端窗口绘制的鼠标指针图形 —— 历史上为 xterm 特有，通过标准 X 光标名暴露。"
      },
      "bytes": {
        "canonical": "\\x1b]22;CURSOR-NAME\\x07",
        "octal": "\\033]22;CURSOR-NAME\\007",
        "eEscape": "\\e]22;CURSOR-NAME\\a",
        "literal": "ESC ] 22 ; CURSOR-NAME BEL",
        "hex": "1b 5d 32 32 3b ... 07"
      },
      "description": {
        "en": "OSC 22 sets the X-server cursor name for the terminal window — the mouse pointer glyph the user sees when hovering over the terminal. The argument is one of the standard X cursor names (xcursor library): `xterm` (the I-beam — default), `crosshair`, `hand2`, `watch`, `wait`, `pirate`, `pencil`, etc. Used by full-screen TUI applications that want to signal mode changes via cursor shape (e.g. `pirate` while a long operation runs, `xterm` when input is accepted), or by terminal-based games. Strictly xterm-specific historically — the OSC body is passed straight to `XDefineCursor` so it only makes sense on X11-backed terminals. Non-X11 terminals universally ignore. Empty argument (`\\x1b]22;\\x07`) resets to the user's default pointer.",
        "zh": "OSC 22 设置终端窗口的 X-server 光标名 —— 用户悬停时看到的鼠标指针图形。参数为标准 X 光标名（xcursor 库）之一：`xterm`（I 形 —— 默认）、`crosshair`、`hand2`、`watch`、`wait`、`pirate`、`pencil` 等。全屏 TUI 程序常用其通过指针形状传达模式变化（如长操作运行时显示 `pirate`、可接受输入时显示 `xterm`），终端游戏亦然。历史上为 xterm 特有 —— OSC 体直接传给 `XDefineCursor`，故只有在 X11 支持的终端上有意义。非 X11 终端普遍忽略。空参数（`\\x1b]22;\\x07`）重置为用户默认指针。"
      },
      "spec": "xterm-ctlseqs (OSC 22)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]22;watch\\007'     # show a wait-cursor while a long job runs\\nsleep 5\\nprintf '\\033]22;xterm\\007'     # restore I-beam"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]22;watch\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]22;watch\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]22;watch\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]22;watch\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "dec-cursor-shape",
        "osc-cursor-color",
        "osc-set-fg-bg"
      ]
    },
    {
      "slug": "osc-set-font",
      "family": "OSC",
      "title": {
        "en": "OSC 50 — Set or query font (xterm font selector)",
        "zh": "OSC 50 — 设置或查询字体（xterm 字体选择器）"
      },
      "shortDesc": {
        "en": "Switch the terminal's display font at runtime, or query the current font — xterm extension, also implemented by a handful of forks.",
        "zh": "运行时切换终端显示字体，或查询当前字体 —— xterm 扩展，少数分叉亦实现。"
      },
      "bytes": {
        "canonical": "\\x1b]50;FONT-SPEC\\x07   (set)   \\x1b]50;?\\x07   (query)",
        "octal": "\\033]50;FONT-SPEC\\007",
        "eEscape": "\\e]50;FONT-SPEC\\a",
        "literal": "ESC ] 50 ; FONT-SPEC BEL",
        "hex": "1b 5d 35 30 3b ... 07"
      },
      "description": {
        "en": "OSC 50 switches the terminal's display font at runtime. The argument is a font specification understood by the terminal — historically an XLFD (`-misc-fixed-medium-r-normal--14-130-75-75-c-70-iso8859-1`), modern xterm and forks also accept Xft / fontconfig names (`monospace:size=14`, `Iberian Black:size=12:weight=bold`). A leading `+N`/`-N` instead of a name shifts the size up/down by N pixels relative to current. Sending `?` (`\\x1b]50;?\\x07`) makes the terminal reply with the current font name as `\\x1b]50;NAME\\x07` — used by `vim`'s `:set guifont` autodetect equivalent and by `xterm`'s font menu. urxvt added a parallel OSC 710 / 711 / 712 for its own font/boldFont/italicFont slots. Modern non-xterm terminals (kitty, alacritty, wezterm, ghostty, Windows Terminal, iTerm2) all manage fonts via their own config — they don't honour OSC 50 because there's no single 'default font' to override.",
        "zh": "OSC 50 在运行时切换终端的显示字体。参数是终端能识别的字体规范 —— 历史上为 XLFD（`-misc-fixed-medium-r-normal--14-130-75-75-c-70-iso8859-1`），现代 xterm 及分叉也接受 Xft / fontconfig 名（`monospace:size=14`、`Iberian Black:size=12:weight=bold`）。以 `+N`/`-N` 替代名称表示相对当前字号上下增减 N 像素。发送 `?`（`\\x1b]50;?\\x07`）让终端以 `\\x1b]50;NAME\\x07` 回报当前字体名 —— `vim` 的 `:set guifont` 自动检测等价物与 `xterm` 字体菜单都用它。urxvt 增加了并行的 OSC 710 / 711 / 712 用于其 font/boldFont/italicFont 槽位。现代非 xterm 终端（kitty、alacritty、wezterm、ghostty、Windows Terminal、iTerm2）的字体均通过自家配置管理 —— 它们不实现 OSC 50，因为没有单一「默认字体」可覆写。"
      },
      "spec": "xterm-ctlseqs (OSC 50)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033]50;monospace:size=18\\007'   # bump to 18pt monospace\\nprintf '\\033]50;?\\007'                   # query current font name"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b]50;monospace:size=18\\x07')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]50;monospace:size=18\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b]50;monospace:size=18\\x07')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]50;monospace:size=18\\x07\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "osc-cursor-color",
        "osc-set-fg-bg",
        "osc-title"
      ]
    },
    {
      "slug": "c1-controls",
      "family": "ESC",
      "title": {
        "en": "C1 controls — 8-bit single-byte equivalents of ESC sequences (0x80–0x9F)",
        "zh": "C1 控制字符 —— ESC 序列的 8 位单字节等价形式（0x80–0x9F）"
      },
      "shortDesc": {
        "en": "The 8-bit C1 control bytes (0x80..0x9F) — CSI, OSC, ST, DCS, NEL, HTS, IND, RI — and their 7-bit ESC <letter> equivalents.",
        "zh": "8 位 C1 控制字节（0x80..0x9F）—— CSI、OSC、ST、DCS、NEL、HTS、IND、RI —— 及其 7 位 ESC <letter> 等价形式。"
      },
      "bytes": {
        "canonical": "\\x9b CSI  \\x9d OSC  \\x9c ST  \\x90 DCS  \\x85 NEL  \\x88 HTS  \\x84 IND  \\x8d RI",
        "octal": "\\233 / \\235 / \\234 / \\220 / \\205 / \\210 / \\204 / \\215",
        "eEscape": "(no \\e form — these are single 8-bit bytes; use the 7-bit ESC equivalents below)",
        "literal": "ESC [ ≡ CSI / ESC ] ≡ OSC / ESC \\\\ ≡ ST / ESC P ≡ DCS / ESC E ≡ NEL / ESC H ≡ HTS / ESC D ≡ IND / ESC M ≡ RI",
        "hex": "9b / 9d / 9c / 90 / 85 / 88 / 84 / 8d"
      },
      "description": {
        "en": "The **C1 control set** occupies bytes `0x80`..`0x9F` and provides single-byte alternatives to the most common `ESC <letter>` sequences. The full set: `IND` (0x84, ESC D — line feed without CR), `NEL` (0x85, ESC E — CR+LF), `HTS` (0x88, ESC H — set tab stop at cursor column), `RI` (0x8D, ESC M — reverse line feed, scroll if at top), `SS2` (0x8E, ESC N — single-shift G2 charset for the next char), `SS3` (0x8F, ESC O — single-shift G3), `DCS` (0x90, ESC P — Device Control String introducer), `CSI` (0x9B, ESC [ — Control Sequence Introducer, the most common one), `ST` (0x9C, ESC \\\\ — String Terminator for DCS / OSC / APC / PM / SOS), `OSC` (0x9D, ESC ] — Operating System Command introducer), `PM` (0x9E, ESC ^ — Privacy Message), `APC` (0x9F, ESC _ — Application Program Command, used by Kitty's graphics protocol). **Avoid the 8-bit forms on modern terminals**: every byte in `0x80..0x9F` is a UTF-8 *continuation byte* (the first bits are `10xxxxxx`), so a stray `0x9B` in a UTF-8 stream is either consumed as part of an invalid sequence or silently dropped. Always emit the 7-bit `ESC <letter>` form (`\\x1b[`, `\\x1b]`, `\\x1b\\\\`, etc.) — it is unambiguous in UTF-8, ASCII, and Latin-1, and every terminal recognises it. The 8-bit C1 set is relevant mainly to legacy contexts (DEC VT220 in S8C1T mode, ISO 8859-1 stream archives, old VT100 firmware test vectors).",
        "zh": "**C1 控制集**占据 `0x80`..`0x9F` 字节范围，为最常用的 `ESC <letter>` 序列提供单字节替代形式。完整集合：`IND`（0x84，ESC D —— 不带 CR 的换行）、`NEL`（0x85，ESC E —— CR+LF）、`HTS`（0x88，ESC H —— 在当前列设置 tab 停位）、`RI`（0x8D，ESC M —— 反向换行，到顶时滚动）、`SS2`（0x8E，ESC N —— 对下一字符使用 G2 字符集单次切换）、`SS3`（0x8F，ESC O —— 单次切换 G3）、`DCS`（0x90，ESC P —— 设备控制串引导符）、`CSI`（0x9B，ESC [ —— 控制序列引导符，最常用）、`ST`（0x9C，ESC \\\\ —— 用于 DCS / OSC / APC / PM / SOS 的串终止符）、`OSC`（0x9D，ESC ] —— 操作系统命令引导符）、`PM`（0x9E，ESC ^ —— 隐私消息）、`APC`（0x9F，ESC _ —— 应用程序命令，Kitty 图形协议在用）。**现代终端请避免使用 8 位形式**：`0x80..0x9F` 中的每个字节都是 UTF-8 的*续字节*（前导比特模式 `10xxxxxx`），UTF-8 流中出现一个孤立的 `0x9B` 要么被当作非法序列的一部分吸收，要么被静默丢弃。请始终使用 7 位 `ESC <letter>` 形式（`\\x1b[`、`\\x1b]`、`\\x1b\\\\` 等）—— 在 UTF-8、ASCII、Latin-1 下都是无歧义的，所有终端都识别。8 位 C1 集主要出现在遗留场景中（处于 S8C1T 模式的 DEC VT220、ISO 8859-1 字节流归档、老 VT100 固件测试向量）。"
      },
      "parameters": [
        {
          "name": "IND (0x84, ESC D)",
          "desc": {
            "en": "index — cursor down 1 (LF without CR); scroll if at bottom of region",
            "zh": "索引 —— 光标下移 1（无 CR 的 LF）；位于区域底部时滚动"
          }
        },
        {
          "name": "NEL (0x85, ESC E)",
          "desc": {
            "en": "next line — CR + LF combined",
            "zh": "下一行 —— CR + LF 合一"
          }
        },
        {
          "name": "HTS (0x88, ESC H)",
          "desc": {
            "en": "horizontal tab set — set tab stop at current cursor column",
            "zh": "水平制表设置 —— 在当前光标列设 tab 停位"
          }
        },
        {
          "name": "RI (0x8D, ESC M)",
          "desc": {
            "en": "reverse index — cursor up 1; scroll if at top of region",
            "zh": "反向索引 —— 光标上移 1；位于区域顶部时滚动"
          }
        },
        {
          "name": "SS2 (0x8E, ESC N)",
          "desc": {
            "en": "single shift G2 — use G2 charset for next char only",
            "zh": "单次切换 G2 —— 仅对下一字符使用 G2 字符集"
          }
        },
        {
          "name": "SS3 (0x8F, ESC O)",
          "desc": {
            "en": "single shift G3 — use G3 charset for next char only",
            "zh": "单次切换 G3 —— 仅对下一字符使用 G3 字符集"
          }
        },
        {
          "name": "DCS (0x90, ESC P)",
          "desc": {
            "en": "device control string introducer — terminated by ST",
            "zh": "设备控制串引导符 —— 由 ST 终止"
          }
        },
        {
          "name": "CSI (0x9B, ESC [)",
          "desc": {
            "en": "control sequence introducer — the most common form",
            "zh": "控制序列引导符 —— 最常用"
          }
        },
        {
          "name": "ST  (0x9C, ESC \\\\)",
          "desc": {
            "en": "string terminator — closes DCS / OSC / APC / PM / SOS",
            "zh": "串终止符 —— 关闭 DCS / OSC / APC / PM / SOS"
          }
        },
        {
          "name": "OSC (0x9D, ESC ])",
          "desc": {
            "en": "operating system command — terminated by ST or BEL",
            "zh": "操作系统命令 —— 由 ST 或 BEL 终止"
          }
        },
        {
          "name": "PM  (0x9E, ESC ^)",
          "desc": {
            "en": "privacy message — terminated by ST",
            "zh": "隐私消息 —— 由 ST 终止"
          }
        },
        {
          "name": "APC (0x9F, ESC _)",
          "desc": {
            "en": "application program command — terminated by ST (Kitty graphics)",
            "zh": "应用程序命令 —— 由 ST 终止（Kitty 图形协议在用）"
          }
        }
      ],
      "spec": "ECMA-48 §5.2 (C1 set) / ISO 6429",
      "examples": [
        {
          "lang": "bash",
          "code": "# 7-bit (preferred — UTF-8 safe):\\nprintf '\\033[31mred\\033[0m'\\nprintf '\\033]0;new window title\\033\\\\\\\\'\\n# 8-bit C1 (legacy — breaks under UTF-8):\\nprintf '\\x9b31mred\\x9b0m'   # only works if terminal is in 8-bit mode + Latin-1"
        },
        {
          "lang": "python",
          "code": "# Prefer 7-bit ESC form:\\nimport sys; sys.stdout.write('\\x1b[31mred\\x1b[0m')\\n# 8-bit C1 — fails on UTF-8 stdouts:\\n# sys.stdout.buffer.write(b'\\x9b31mred\\x9b0m')"
        },
        {
          "lang": "go",
          "code": "// 7-bit ESC form (UTF-8 safe):\\nfmt.Print(\"\\x1b[31mred\\x1b[0m\")\\n// 8-bit C1 — emits two UTF-8 continuation bytes interpreted as garbage:\\n// os.Stdout.Write([]byte{0x9b, '3','1','m'})"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[31mred\\x1b[0m');\\n// process.stdout.write(Buffer.from([0x9b, 0x33, 0x31, 0x6d]))  // breaks UTF-8"
        },
        {
          "lang": "c",
          "code": "/* 7-bit ESC form: */\\nprintf(\"\\x1b[31mred\\x1b[0m\");\\n/* 8-bit C1 — only safe on Latin-1 / explicit 8-bit terminals: */\\n/* fputc(0x9b, stdout); fputs(\"31m\", stdout); */"
        }
      ],
      "support": {
        "xterm": "partial",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "c0-controls",
        "esc-hts",
        "decstr-soft-reset",
        "ris-reset"
      ]
    },
    {
      "slug": "sgr-double-underline",
      "family": "SGR",
      "title": {
        "en": "SGR 21 — Doubly underlined",
        "zh": "SGR 21 — 双下划线"
      },
      "shortDesc": {
        "en": "Render text with a double underline — distinct from single underline (SGR 4).",
        "zh": "为文本添加双下划线 —— 与单下划线（SGR 4）不同。"
      },
      "bytes": {
        "canonical": "\\x1b[21m",
        "octal": "\\033[21m",
        "eEscape": "\\e[21m",
        "literal": "ESC [ 21 m",
        "hex": "1b 5b 32 31 6d"
      },
      "description": {
        "en": "Double underline. ECMA-48 §8.3.117 defines SGR 21 as `DOUBLY UNDERLINED`. **Caveat**: historically some terminals (older xterm builds, certain Linux console fonts) treated SGR 21 as `BOLD OFF` instead — a vestige from when bold and double-underline were both intensity-related flags on hardware terminals. Modern xterm, kitty, wezterm, iTerm2, Windows Terminal, ghostty, alacritty all implement the ECMA-48 meaning. If you also need to support legacy terminals, use Kitty's underline-style extension `\\x1b[4:2m` instead — it unambiguously means double underline and is supported by the same modern set plus kitty. Turn off with `\\x1b[24m` (same disabler as single underline).",
        "zh": "双下划线。ECMA-48 §8.3.117 把 SGR 21 定义为 `DOUBLY UNDERLINED`。**注意**：历史上部分终端（早期 xterm 版本、某些 Linux 控制台字体）把 SGR 21 视作 `BOLD OFF` —— 这是硬件终端时代加粗与双下划线都属于「强度」标志的遗留行为。现代 xterm、kitty、wezterm、iTerm2、Windows Terminal、ghostty、alacritty 都按 ECMA-48 语义实现。若需兼容老旧终端，可改用 Kitty 的下划线样式扩展 `\\x1b[4:2m` —— 明确表示双下划线，且被同样这批现代终端 + kitty 支持。关闭方式 `\\x1b[24m`（与单下划线相同）。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 21)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[21mdouble underline\\033[24m back\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[21mdouble underline\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[21mdouble underline\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[21mdouble underline\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[21mdouble underline\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "sgr-underline",
        "sgr-bold",
        "sgr-reset"
      ]
    },
    {
      "slug": "sgr-overline",
      "family": "SGR",
      "title": {
        "en": "SGR 53 — Overlined",
        "zh": "SGR 53 — 上划线"
      },
      "shortDesc": {
        "en": "Render text with a line drawn ABOVE the glyphs — mirror of underline. Disable with SGR 55.",
        "zh": "在字形上方绘制一条线 —— 与下划线相对。使用 SGR 55 关闭。"
      },
      "bytes": {
        "canonical": "\\x1b[53m",
        "octal": "\\033[53m",
        "eEscape": "\\e[53m",
        "literal": "ESC [ 53 m",
        "hex": "1b 5b 35 33 6d"
      },
      "description": {
        "en": "Overline. ECMA-48 §8.3.117 defines SGR 53 as `OVERLINED` — a horizontal line drawn along the top of the glyph row, the mirror of underline. Disable with `\\x1b[55m`. Adoption is uneven: kitty, wezterm, contour, ghostty, foot all implement it; xterm and most legacy terminals do not. Useful for marking text as struck-through-but-different (e.g., NATO message overlining, log severity markers, accentuated keys). If you need wide portability, pair the SGR 53 emission with a fallback (e.g., a Unicode combining overline `U+0305` on the previous char) so unsupported terminals still convey emphasis.",
        "zh": "上划线。ECMA-48 §8.3.117 将 SGR 53 定义为 `OVERLINED` —— 在字形顶部沿水平方向绘制一条线，与下划线相对。关闭方式 `\\x1b[55m`。终端支持参差不齐：kitty、wezterm、contour、ghostty、foot 实现该控制；xterm 与多数遗留终端不支持。常见用途包括标记「不同于划掉」的文本（如 NATO 消息上划线、日志严重级标记、强调按键）。若需更广兼容，可在发送 SGR 53 的同时为前一字符加 Unicode 结合上划线（U+0305）作为回退 —— 不支持的终端仍能传达强调。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 53)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[53moverlined\\033[55m back\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[53moverlined\\x1b[0m')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[53moverlined\\x1b[0m\")"
        },
        {
          "lang": "javascript",
          "code": "console.log('\\x1b[53moverlined\\x1b[0m')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[53moverlined\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "no",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "no",
        "konsole": "partial"
      },
      "related": [
        "sgr-underline",
        "sgr-strikethrough",
        "sgr-reset"
      ]
    },
    {
      "slug": "sgr-proportional",
      "family": "SGR",
      "title": {
        "en": "SGR 26 — Proportional spacing (ECMA-48; ignored by every common terminal)",
        "zh": "SGR 26 — 比例间距（ECMA-48 定义；常见终端均忽略）"
      },
      "shortDesc": {
        "en": "Defined by ECMA-48 as 'proportional spacing on' — but no common terminal emulator implements it. Document the gotcha.",
        "zh": "ECMA-48 把它定义为「启用比例间距」—— 但所有常见终端都不实现。记录这一陷阱。"
      },
      "bytes": {
        "canonical": "\\x1b[26m",
        "octal": "\\033[26m",
        "eEscape": "\\e[26m",
        "literal": "ESC [ 26 m",
        "hex": "1b 5b 32 36 6d"
      },
      "description": {
        "en": "ECMA-48 §8.3.117 defines SGR 26 as `PROPORTIONAL SPACING` — a hint that the rendering device should switch from fixed-width cells to a proportional font for the following characters; `\\x1b[50m` is the matching `PROPORTIONAL SPACING OFF`. **This control is effectively dead**: it was meaningful on the ANSI X3.64 / ECMA-48 print-stream targets of the 1970s–80s (typewriters, daisy-wheel printers, mainframe terminals with optional proportional firmware) but every modern terminal emulator hard-codes a monospaced grid for column math and ignores SGR 26 entirely. It is documented here so that decoders and lint tools recognise the byte sequence rather than misclassifying it — and so writers do not accidentally believe they can mix proportional and monospace text in a terminal session. If you want proportional rendering in 2026, use a non-terminal UI (web, native).",
        "zh": "ECMA-48 §8.3.117 把 SGR 26 定义为 `PROPORTIONAL SPACING` —— 提示渲染设备对后续字符切换至比例字体而非等宽格；匹配的 `PROPORTIONAL SPACING OFF` 为 `\\x1b[50m`。**该控制实际上已死**：在 1970–80 年代 ANSI X3.64 / ECMA-48 的打印流目标（打字机、菊轮打印机、可选比例固件的主机终端）上有意义，但所有现代终端模拟器硬编码等宽网格用于列计算，完全忽略 SGR 26。在此记录它，是为了让解码器与 lint 工具识别该字节序列而非错误分类 —— 同时让作者明白不能在终端会话中混用比例文本与等宽文本。若 2026 年仍需比例渲染，请改用非终端 UI（Web、原生应用）。"
      },
      "spec": "ECMA-48 §8.3.117 (SGR parameter 26)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[26mproportional\\033[50m back\\033[0m\\n'   # silently ignored by xterm/kitty/iterm2/etc."
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[26mproportional\\x1b[50m\\n')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[26mproportional\\x1b[50m\\n\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[26mproportional\\x1b[50m\\n')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[26mproportional\\x1b[50m\\n\");"
        }
      ],
      "support": {
        "xterm": "no",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "sgr-reset",
        "sgr-italic",
        "sgr-underline"
      ]
    },
    {
      "slug": "csi-vpa",
      "family": "CSI",
      "title": {
        "en": "VPA — Vertical line position absolute (CSI d)",
        "zh": "VPA — 垂直行绝对定位（CSI d）"
      },
      "shortDesc": {
        "en": "Move the cursor to an absolute row, keeping the current column.",
        "zh": "将光标移动到绝对行，保持当前列不变。"
      },
      "bytes": {
        "canonical": "\\x1b[<row>d",
        "octal": "\\033[3d",
        "eEscape": "\\e[3d",
        "literal": "ESC [ row d",
        "hex": "1b 5b ... 64"
      },
      "description": {
        "en": "Vertical Position Absolute. Move the cursor to row `<row>` (1-based) without changing the column — the row-only counterpart of CHA (`\\x1b[<col>G`, cursor-column). Default row is 1 if omitted (`\\x1b[d`). Out-of-range values clamp to the visible region (or the DECSTBM scrolling region when DECOM is active). VPA's column-preserving behaviour makes it the right primitive when redrawing a status bar or progress line at a known row while the user types in the column above — CUP (`\\x1b[r;cH`) would reset the column to 1. Less commonly used than CUP / CUU / CUD because most TUIs prefer absolute (row, col) pairs, but it's part of every ECMA-48-conformant terminal.",
        "zh": "Vertical Position Absolute。把光标移到第 `<row>` 行（从 1 开始），不改变列 —— 是 CHA（`\\x1b[<col>G`，cursor-column）的行版对照。省略时默认 row=1（`\\x1b[d`）。超界数值被钳制到可视区域（启用 DECOM 时为 DECSTBM 滚动区域）。VPA 的「保留列」行为使其成为在已知行重绘状态栏 / 进度行的正确原语，而用户继续在上方列输入 —— CUP（`\\x1b[r;cH`）则会把列重置为 1。日常 TUI 多用绝对 (row, col) 二元组，因此使用频率不如 CUP / CUU / CUD，但每个 ECMA-48 兼容终端都支持它。"
      },
      "spec": "ECMA-48 §8.3.158 (VPA) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[24dstatus: ok'   # jump to row 24, keep column"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[24dstatus: ok')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[24dstatus: ok\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[24dstatus: ok')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[24dstatus: ok\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-position",
        "cursor-column",
        "cursor-save-restore",
        "cursor-move"
      ]
    },
    {
      "slug": "csi-hvp",
      "family": "CSI",
      "title": {
        "en": "HVP — Horizontal and vertical position (CSI f, alias of CUP)",
        "zh": "HVP — 水平与垂直定位（CSI f，CUP 的别名）"
      },
      "shortDesc": {
        "en": "Move the cursor to absolute (row, col) — semantically identical to CUP but uses final byte `f` instead of `H`.",
        "zh": "将光标移动到绝对 (row, col) —— 语义与 CUP 完全相同，仅末字节用 `f` 而非 `H`。"
      },
      "bytes": {
        "canonical": "\\x1b[<row>;<col>f",
        "octal": "\\033[1;1f",
        "eEscape": "\\e[1;1f",
        "literal": "ESC [ row ; col f",
        "hex": "1b 5b ... 66"
      },
      "description": {
        "en": "Horizontal and Vertical Position. ECMA-48 §8.3.61 defines HVP with the SAME semantics as CUP (`\\x1b[r;cH`, §8.3.21) — move the cursor to the absolute 1-based row/col, default (1,1), values clamped to the visible region. The difference is purely the final byte: `H` (0x48) for CUP, `f` (0x66) for HVP. Both are widely emitted in the wild — some applications still use the older `f` form, notably parts of curses' default capability table and certain DEC VT-clone test vectors. Treat HVP exactly like CUP when decoding; emit CUP (`H`) when writing new code unless you need to match a legacy stream. Note: in ECMA-48 HVP was historically the canonical primitive and CUP the synonym; xterm-ctlseqs reverses the relationship and treats CUP as primary, reflecting modern usage.",
        "zh": "Horizontal and Vertical Position。ECMA-48 §8.3.61 定义 HVP 的语义与 CUP（`\\x1b[r;cH`，§8.3.21）完全相同 —— 移动光标到绝对的 1 起始行/列，默认 (1,1)，超界值钳到可视区域。差别仅在末字节：CUP 是 `H`（0x48），HVP 是 `f`（0x66）。两种形式在野外都常见 —— 一些程序仍使用更老的 `f` 形式，尤其是 curses 默认能力表的部分项与某些 DEC VT 克隆的测试向量。解码时把 HVP 等同于 CUP；新代码请发送 CUP（`H`），除非需要匹配遗留流。注：ECMA-48 历史上把 HVP 视作主要原语而 CUP 是同义；xterm-ctlseqs 反过来把 CUP 作为主形式，反映现代用法。"
      },
      "spec": "ECMA-48 §8.3.61 (HVP) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[2;5fHello at (2,5)\\n'   # same as \\033[2;5H"
        },
        {
          "lang": "python",
          "code": "print('\\x1b[2;5fHello at (2,5)')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[2;5fHello at (2,5)\\n\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[2;5fHello at (2,5)\\n')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[2;5fHello at (2,5)\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "yes",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "cursor-position",
        "csi-vpa",
        "cursor-column",
        "cursor-save-restore"
      ]
    },
    {
      "slug": "xtwinops",
      "family": "CSI",
      "title": {
        "en": "XTWINOPS — Window manipulation (CSI Ps ; Ps ; Ps t)",
        "zh": "XTWINOPS — 窗口操作（CSI Ps ; Ps ; Ps t）"
      },
      "shortDesc": {
        "en": "xterm's window-manipulation family — resize, minimise, raise/lower, query size, push/pop title.",
        "zh": "xterm 的窗口操作族 —— 调整大小、最小化、置顶/置底、查询尺寸、推入/弹出标题。"
      },
      "bytes": {
        "canonical": "\\x1b[<Ps>t   or   \\x1b[<Ps>;<Pa>;<Pb>t",
        "octal": "\\033[18t",
        "eEscape": "\\e[18t",
        "literal": "ESC [ Ps ; Pa ; Pb t",
        "hex": "1b 5b ... 74"
      },
      "description": {
        "en": "Dispatches by first parameter `Ps`. Common operations: `1` de-iconify, `2` iconify, `3;x;y` move window to (x,y) pixels, `4;h;w` resize to (h,w) pixels, `5` raise window, `6` lower window, `7` refresh, `8;rows;cols` resize text area to (rows,cols), `9;0` un-maximise, `9;1` maximise, `10;0` un-fullscreen, `10;1` fullscreen, `11` report iconified state (`\\x1b[1t` / `\\x1b[2t`), `13` report window position, `14` report pixel size, `18` report text size (`\\x1b[8;rows;colst`), `19` report screen size in chars, `20` report icon title, `21` report window title, `22;0` push BOTH title types, `22;1` push icon title, `22;2` push window title, `23;0`/`23;1`/`23;2` pop. Many operators (`3`/`4`/`8`/`9`/`10`/`13`/`14`/`20`/`21`) are gated by xterm's `allowWindowOps` resource for security — most modern terminals ship that disabled, so resize/move requests silently no-op and only the queries (`14`, `18`, `21`) reliably round-trip. The push/pop title pair (`22`/`23`) is the most portable use and underpins tmux's window-name preservation across nested sessions.",
        "zh": "按首参数 `Ps` 分派。常用操作：`1` 取消最小化，`2` 最小化，`3;x;y` 移动到像素坐标 (x,y)，`4;h;w` 调整到 (h,w) 像素，`5` 置顶，`6` 置底，`7` 刷新，`8;rows;cols` 文本区调整为 (rows,cols)，`9;0` 取消最大化，`9;1` 最大化，`10;0` 退出全屏，`10;1` 进入全屏，`11` 查询是否最小化（回复 `\\x1b[1t` / `\\x1b[2t`），`13` 查询窗口位置，`14` 查询像素尺寸，`18` 查询文本尺寸（回复 `\\x1b[8;rows;colst`），`19` 查询屏幕字符尺寸，`20` 查询图标标题，`21` 查询窗口标题，`22;0` 同时推入两种标题，`22;1` 推入图标标题，`22;2` 推入窗口标题，`23;0` / `23;1` / `23;2` 弹出。许多操作（`3`/`4`/`8`/`9`/`10`/`13`/`14`/`20`/`21`）受 xterm `allowWindowOps` 资源保护以防滥用 —— 多数现代终端默认禁用，调整大小 / 移动请求会被静默忽略，只有查询（`14`、`18`、`21`）可靠地往返。推入 / 弹出标题（`22`/`23`）是最便携的用法，也是 tmux 在嵌套会话间保留窗口名的实现基础。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "Operation selector (1–23). Some operators take additional Pa / Pb parameters.",
            "zh": "操作选择（1–23）。部分操作需要额外的 Pa / Pb 参数。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (XTWINOPS) / DECSLPP partial overlap",
      "examples": [
        {
          "lang": "bash",
          "code": "# Query pixel size — reply: \\x1b[4;height;widtht\\nprintf '\\033[14t'"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[18t'); sys.stdout.flush()  # reply: \\x1b[8;rows;colst"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[22;0t\")   // push BOTH titles"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[23;0t')  // pop BOTH titles"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[8;24;80t\");  // resize text area to 24 rows × 80 cols (allowWindowOps required)"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "partial",
        "wt": "partial",
        "cmd": "no",
        "kitty": "partial",
        "alacritty": "partial",
        "wezterm": "partial",
        "ghostty": "partial",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "osc-title",
        "csi-dsr",
        "csi-da",
        "alt-screen"
      ]
    },
    {
      "slug": "decsed-decsel",
      "family": "CSI",
      "title": {
        "en": "DECSED / DECSEL — Selective erase display / line (CSI ? Ps J / CSI ? Ps K)",
        "zh": "DECSED / DECSEL — 选择性擦除屏幕 / 行（CSI ? Ps J / CSI ? Ps K）"
      },
      "shortDesc": {
        "en": "Erase only the unprotected cells in the display (DECSED) or current line (DECSEL) — the private-mode siblings of ED / EL.",
        "zh": "仅擦除未受保护的单元 —— 显示区（DECSED）或当前行（DECSEL）。即 ED / EL 的私有模式对照。"
      },
      "bytes": {
        "canonical": "\\x1b[?<Ps>J   (DECSED)   \\x1b[?<Ps>K   (DECSEL)",
        "octal": "\\033[?2J / \\033[?2K",
        "eEscape": "\\e[?2J / \\e[?2K",
        "literal": "ESC [ ? Ps J   /   ESC [ ? Ps K",
        "hex": "1b 5b 3f ... 4a   /   1b 5b 3f ... 4b"
      },
      "description": {
        "en": "Identical to ED (`\\x1b[<Ps>J`) and EL (`\\x1b[<Ps>K`) in scope (`Ps=0` cursor→end, `1` start→cursor, `2` entire region), but skips cells marked as protected by DECSCA (`\\x1b[<Ps>\"q`). DECSCA tags individual character cells as protected (`Ps=1`) or unprotected (`Ps=0` / `2`); DECSED and DECSEL are the only erase primitives that honour that tag. Useful for forms — paint immutable labels with DECSCA-protected attribute on, accept user input in unprotected cells, and `\\x1b[?2K` clears only the entry fields without disturbing labels. Outside the forms / data-entry use-case these sequences are vanishingly rare; many modern emulators (alacritty, wezterm, ghostty) treat them as plain ED / EL because they don't track DECSCA at all. Don't reach for these in greenfield code unless you're actually implementing a VT220-style data-entry form.",
        "zh": "与 ED（`\\x1b[<Ps>J`）和 EL（`\\x1b[<Ps>K`）的作用域完全相同（`Ps=0` 光标→末尾，`1` 开始→光标，`2` 整个区域），但会跳过 DECSCA（`\\x1b[<Ps>\"q`）标记为「受保护」的单元。DECSCA 把单个字符单元标记为受保护（`Ps=1`）或未受保护（`Ps=0` / `2`）；DECSED 与 DECSEL 是唯一遵循这一标记的擦除原语。常用于表单 —— 用 DECSCA 把不可变的标签设为受保护并绘制，把用户输入接收在未保护单元，`\\x1b[?2K` 只清空输入字段而不影响标签。除了表单 / 数据录入场景，这两个序列极少使用；许多现代模拟器（alacritty、wezterm、ghostty）根本不跟踪 DECSCA，遇到时按普通 ED / EL 处理。除非真要实现 VT220 风格的数据录入表单，否则新代码不要使用。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "`0` (default) erase cursor → end of region · `1` start of region → cursor · `2` entire region. Protected cells (DECSCA) are skipped.",
            "zh": "`0`（默认）擦除从光标到区域末尾 · `1` 区域起始到光标 · `2` 整个区域。DECSCA 标记为受保护的单元会被跳过。"
          }
        }
      ],
      "spec": "DEC STD 070 (DECSED / DECSEL) / DEC VT510 RM",
      "examples": [
        {
          "lang": "bash",
          "code": "# Erase only unprotected cells on the current line:\\nprintf '\\033[?2K'"
        },
        {
          "lang": "python",
          "code": "import sys\\n# Selective ED 2 — keep DECSCA-protected labels intact:\\nsys.stdout.write('\\x1b[?2J')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?0K\")   // selective EL: cursor to end of line"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?2K')   // selective EL: whole line, skip protected cells"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?1J\");  // selective ED: top of screen to cursor"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "erase-display",
        "erase-line",
        "decstr-soft-reset"
      ]
    },
    {
      "slug": "csi-sl-sr",
      "family": "CSI",
      "title": {
        "en": "SL / SR — Scroll left / right (CSI Ps SP @ / CSI Ps SP A)",
        "zh": "SL / SR — 左滚 / 右滚（CSI Ps SP @ / CSI Ps SP A）"
      },
      "shortDesc": {
        "en": "Scroll the screen content left (SL) or right (SR) by Ps columns — the horizontal counterpart of CSI S / CSI T.",
        "zh": "将屏幕内容左滚（SL）或右滚（SR）Ps 列 —— 与 CSI S / CSI T 对应的水平方向版本。"
      },
      "bytes": {
        "canonical": "\\x1b[<Ps> @   (SL)   \\x1b[<Ps> A   (SR)",
        "octal": "\\033[1 @ / \\033[1 A",
        "eEscape": "\\e[1 @ / \\e[1 A",
        "literal": "ESC [ Ps SP @   /   ESC [ Ps SP A",
        "hex": "1b 5b ... 20 40   /   1b 5b ... 20 41"
      },
      "description": {
        "en": "Shifts every cell on the screen (or within the active DECSTBM / DECSLRM region) `Ps` columns left (SL — final bytes `SP @`) or right (SR — final bytes `SP A`). Columns scrolled off the edge are discarded; the opposite edge is filled with blanks using the current SGR background. The intermediate byte is **literal space (0x20)** between the parameter and the final byte — easy to miss because the canonical ECMA-48 notation writes it as `SP`. SR shares its final byte `A` with CUU (cursor-up) but is unambiguous because of the intermediate space — parsers must distinguish on the presence of any 0x20..0x2f byte before the final. Common use-case is wide-table or code-viewer panes that scroll horizontally without redrawing the rest of the screen. Support is markedly thinner than vertical scroll (CSI S / CSI T) — Linux console, ConPTY, and several xterm clones treat SL/SR as a no-op.",
        "zh": "把屏幕（或当前 DECSTBM / DECSLRM 区域）每一格内容向左（SL —— 末字节 `SP @`）或向右（SR —— 末字节 `SP A`）移动 `Ps` 列。被推出边缘的列被丢弃；另一边以当前 SGR 背景色填充空白。中间字节是**字面空格（0x20）**，位于参数与末字节之间 —— ECMA-48 习惯写作 `SP`，初读容易忽略。SR 的末字节 `A` 与 CUU（光标上移）相同，但靠中间空格区分 —— 解析器必须根据末字节前是否存在 0x20..0x2f 字节来判断。常见用途是宽表格 / 代码查看面板的水平滚动，无需重绘其他部分。支持显著薄于纵向滚动（CSI S / CSI T）—— Linux console、ConPTY 与若干 xterm 克隆把 SL / SR 视为空操作。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "Number of columns to scroll. Default 1 if omitted; values larger than the region width clear the region.",
            "zh": "滚动的列数。省略时默认 1；大于区域宽度的值会清空区域。"
          }
        }
      ],
      "spec": "ECMA-48 §8.3.121 (SL) / §8.3.135 (SR) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[3 @'   # scroll screen 3 cols left (note literal SPACE before @)"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[1 A')   # scroll 1 col right"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[2 @\")   // scroll 2 cols left"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[1 A')   // scroll 1 col right"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[5 @\");  // scroll 5 cols left"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "partial",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "scroll-up-down",
        "decstbm",
        "erase-display"
      ]
    },
    {
      "slug": "decsca",
      "family": "CSI",
      "title": {
        "en": "DECSCA — Select character protection attribute (CSI Ps \" q)",
        "zh": "DECSCA — 选择字符保护属性（CSI Ps \" q）"
      },
      "shortDesc": {
        "en": "Mark subsequently-written cells as DECSED/DECSEL-protected (Ps=1) or unprotected (Ps=0/2).",
        "zh": "把后续写入的单元标记为受 DECSED / DECSEL 保护（Ps=1）或不受保护（Ps=0 / 2）。"
      },
      "bytes": {
        "canonical": "\\x1b[<Ps>\"q",
        "octal": "\\033[1\"q",
        "eEscape": "\\e[1\"q",
        "literal": "ESC [ Ps \" q",
        "hex": "1b 5b ... 22 71"
      },
      "description": {
        "en": "Select Character Protection Attribute — toggles the protection bit that DECSED (`\\x1b[?<Ps>J`) and DECSEL (`\\x1b[?<Ps>K`) honour. `Ps=0` (default) marks following cells unprotected; `Ps=1` marks them protected; `Ps=2` is the explicit unprotected synonym (per DEC STD 070). The intermediate byte is **literal `\"` (0x22)** — easy to typo as the parameter byte. Once a region is painted with protected cells, DECSED / DECSEL skip those cells during a selective erase, while plain ED / EL still clear them. DEC's data-entry forms model used this pair to render immutable labels and accept user input in the gaps without redrawing labels on every clear. Modern emulators that don't track DECSCA at all (alacritty, wezterm, ghostty, kitty pre-0.32) silently no-op DECSCA and treat DECSED/DECSEL as plain ED/EL — design forms expecting that fallback or detect via DECRQSS (DCS $q\"q). Most TUI authors today reach for a render diff in user-space instead of relying on DECSCA round-trips through the terminal.",
        "zh": "Select Character Protection Attribute —— 切换 DECSED（`\\x1b[?<Ps>J`）与 DECSEL（`\\x1b[?<Ps>K`）所遵循的保护位。`Ps=0`（默认）把后续单元标记为不受保护；`Ps=1` 标记为受保护；`Ps=2` 是显式的「不受保护」别名（依 DEC STD 070）。中间字节是**字面 `\"`（0x22）** —— 容易误写为参数字节。区域绘制后，DECSED / DECSEL 在选择性擦除时跳过受保护单元，而普通 ED / EL 仍会清除。DEC 的数据录入表单模型利用这对原语渲染不可变标签、在间隙接收用户输入，每次擦除无需重绘标签。完全不跟踪 DECSCA 的现代模拟器（alacritty、wezterm、ghostty、kitty 0.32 之前）会静默忽略 DECSCA 并把 DECSED / DECSEL 视为普通 ED / EL —— 设计表单时应假设这种回退，或通过 DECRQSS（DCS $q\"q）探测。如今大多 TUI 作者在用户态做渲染 diff，不再依赖通过终端往返 DECSCA。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "`0` (default) unprotected · `1` protected · `2` unprotected (synonym, per DEC STD 070).",
            "zh": "`0`（默认）未受保护 · `1` 受保护 · `2` 未受保护（依 DEC STD 070 的同义形式）。"
          }
        }
      ],
      "spec": "DEC STD 070 (DECSCA) / DEC VT510 RM",
      "examples": [
        {
          "lang": "bash",
          "code": "# Protect the next bytes, write a label, accept input in the gap:\\nprintf '\\033[1\"qLabel: \\033[0\"q'\\n# now any user input written here is in an unprotected cell\\nprintf '\\033[?2K'    # selective EL: clears input only"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[1\"qStatic\\x1b[0\"q dynamic')   # 'Static' is DECSED/DECSEL-protected"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[1\\\"qHeader\\x1b[0\\\"q body\")"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[1\"qHeader\\x1b[0\"q body')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[1\\\"qHeader\\x1b[0\\\"q body\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "decsed-decsel",
        "erase-display",
        "erase-line",
        "dcs-decrqss"
      ]
    },
    {
      "slug": "decslrm",
      "family": "CSI",
      "title": {
        "en": "DECSLRM — Set left and right margins (CSI Pl ; Pr s)",
        "zh": "DECSLRM — 设置左右边距（CSI Pl ; Pr s）"
      },
      "shortDesc": {
        "en": "Constrain horizontal cursor movement + scrolling to columns Pl…Pr — the horizontal counterpart of DECSTBM.",
        "zh": "把光标水平移动与滚动限制在列 Pl…Pr —— 与 DECSTBM 对应的水平方向版本。"
      },
      "bytes": {
        "canonical": "\\x1b[<Pl>;<Pr>s",
        "octal": "\\033[1;80s",
        "eEscape": "\\e[1;80s",
        "literal": "ESC [ Pl ; Pr s",
        "hex": "1b 5b ... 73"
      },
      "description": {
        "en": "Set Left and Right Margins. Defines a vertical strip — columns `Pl` (leftmost) through `Pr` (rightmost), 1-based, inclusive — within which cursor movement and scrolling are confined. Requires DECLRMM (left-right margin mode, `\\x1b[?69h`) to be enabled first; without DECLRMM the sequence is silently ignored, and the final byte `s` instead means SCO save-cursor (this is the parse ambiguity that bites: `\\x1b[s` with no params = save cursor, `\\x1b[<Pl>;<Pr>s` with 2 params = DECSLRM if DECLRMM=on). Once active, SL/SR scrolling stays inside the strip, CUF/CUB clamp at the boundaries, and writes that hit the right margin wrap to the next row's left margin (instead of column 1). Paired with DECSTBM (`\\x1b[<Pt>;<Pb>r`) the two margins define a rectangular scrolling region — the foundation for split-pane editors like vim's `:vsplit` rendering its left half independently of the right. Defaults if omitted: `Pl=1`, `Pr=` last column. Setting `Pl≥Pr` resets to the full screen width.",
        "zh": "Set Left and Right Margins。定义一条垂直条带 —— 从 `Pl`（最左列）到 `Pr`（最右列），从 1 开始且包含两端 —— 在该范围内约束光标移动与滚动。需要先启用 DECLRMM（左右边距模式，`\\x1b[?69h`）；未启用时序列会被静默忽略，且末字节 `s` 改解作 SCO 保存光标（这就是常见的解析二义性：`\\x1b[s` 无参 = 保存光标；`\\x1b[<Pl>;<Pr>s` 两参数且 DECLRMM=on = DECSLRM）。激活后，SL / SR 滚动仅在条带内进行，CUF / CUB 在边界处钳制，写到右边距的字符会换行到下一行的左边距（而不是第 1 列）。与 DECSTBM（`\\x1b[<Pt>;<Pb>r`）配合定义矩形滚动区域 —— 这是 vim `:vsplit` 等分屏编辑器把左半区独立于右半区渲染的基础。省略时默认 `Pl=1`、`Pr=` 末列。若 `Pl≥Pr`，则重置为整屏宽度。"
      },
      "parameters": [
        {
          "name": "Pl",
          "desc": {
            "en": "Leftmost column (1-based, inclusive). Default 1.",
            "zh": "最左列（从 1 起算，包含）。默认 1。"
          }
        },
        {
          "name": "Pr",
          "desc": {
            "en": "Rightmost column (1-based, inclusive). Default = screen width.",
            "zh": "最右列（从 1 起算，包含）。默认为屏幕宽度。"
          }
        }
      ],
      "spec": "DEC STD 070 (DECSLRM) / DEC VT510 RM",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?69h'        # enable DECLRMM first\\nprintf '\\033[10;30s'      # constrain cols 10..30\\n# now scrolling + cursor moves stay within that strip"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[?69h')          # enable DECLRMM\\nsys.stdout.write('\\x1b[1;40s')          # left margin 1, right 40"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?69h\\x1b[1;40s\")    // enable + set strip"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?69h\\x1b[1;40s')"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?69h\\x1b[1;40s\");    /* enable DECLRMM + constrain to cols 1..40 */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "partial",
        "gnometerm": "no",
        "konsole": "yes"
      },
      "related": [
        "decstbm",
        "csi-sl-sr",
        "sco-save-restore",
        "cursor-position"
      ]
    },
    {
      "slug": "xtpushcolors-popcolors",
      "family": "CSI",
      "title": {
        "en": "XTPUSHCOLORS / XTPOPCOLORS / XTREPORTCOLORS — Palette stack (CSI # P / # Q / # R)",
        "zh": "XTPUSHCOLORS / XTPOPCOLORS / XTREPORTCOLORS — 调色板栈（CSI # P / # Q / # R）"
      },
      "shortDesc": {
        "en": "Save / restore / inspect xterm's ANSI palette via a process-local stack — useful for TUIs that mutate the palette temporarily.",
        "zh": "通过进程级栈保存 / 恢复 / 查询 xterm 的 ANSI 调色板 —— 适合需要临时修改调色板的 TUI。"
      },
      "bytes": {
        "canonical": "\\x1b[#P   (push)   \\x1b[#Q   (pop)   \\x1b[#R   (report)",
        "octal": "\\033[#P / \\033[#Q / \\033[#R",
        "eEscape": "\\e[#P / \\e[#Q / \\e[#R",
        "literal": "ESC [ Pm # P   /   ESC [ Pm # Q   /   ESC [ # R",
        "hex": "1b 5b ... 23 50 / 1b 5b ... 23 51 / 1b 5b 23 52"
      },
      "description": {
        "en": "Three xterm-specific operations that share the intermediate byte `#` (0x23) and dispatch on the final byte. **XTPUSHCOLORS** (`\\x1b[#P`) pushes the current 88-/256-entry ANSI palette plus the foreground / background / cursor colors onto an internal stack — call with a parameter `\\x1b[Pm#P` to tag the saved snapshot with id `Pm` for later targeted retrieval. **XTPOPCOLORS** (`\\x1b[#Q`) pops the most recent snapshot back into effect; `\\x1b[Pm#Q` pops the snapshot tagged `Pm` (and discards any snapshots pushed after it). **XTREPORTCOLORS** (`\\x1b[#R`) returns the current stack depth and tag list as a CSI ? Pm # R reply, useful for libraries that want to detect whether the user already pushed a palette before they overwrite it via OSC 4 / OSC 10 / OSC 11. Stack capacity is xterm-specific (typically 10). Support is rare outside xterm proper — most modern emulators (kitty, alacritty, wezterm, ghostty) silently ignore the sequences, so guard with a DECRQSS / XTREPORTCOLORS round-trip before relying on them.",
        "zh": "三个共享中间字节 `#`（0x23）的 xterm 专属操作，按末字节分派。**XTPUSHCOLORS**（`\\x1b[#P`）把当前 88 / 256 项 ANSI 调色板以及前景 / 背景 / 光标颜色压入内部栈；带参数 `\\x1b[Pm#P` 可给快照打上标识 `Pm` 以便精准取回。**XTPOPCOLORS**（`\\x1b[#Q`）将最近一次快照恢复生效；`\\x1b[Pm#Q` 弹出标识为 `Pm` 的快照（其后压入的快照会被一并丢弃）。**XTREPORTCOLORS**（`\\x1b[#R`）以 CSI ? Pm # R 形式回复当前栈深与标识列表，库代码可借此判断用户是否已自行压栈再决定是否通过 OSC 4 / OSC 10 / OSC 11 改色。栈容量取决于 xterm 实现（通常为 10）。除 xterm 本体外支持稀薄 —— 大多数现代模拟器（kitty、alacritty、wezterm、ghostty）会静默忽略，使用前最好用 DECRQSS / XTREPORTCOLORS 试探。"
      },
      "parameters": [
        {
          "name": "Pm",
          "desc": {
            "en": "Optional snapshot id (push) or selector (pop). When omitted, push saves untagged and pop targets the top of the stack.",
            "zh": "可选快照标识（压栈）或选择子（弹出）。省略时压栈不打标识，弹出取栈顶。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (XTPUSHCOLORS / XTPOPCOLORS / XTREPORTCOLORS)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[#P'              # push current palette\\nprintf '\\033]4;1;#ff0000\\007'  # mutate color 1 to red\\nprintf '\\033[#Q'              # restore the saved palette"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[2#P')   # push, tagged 2\\nsys.stdout.write('\\x1b[#R')   # query stack depth"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[#P\")   // push current palette\\n// ... mutate ...\\nfmt.Print(\"\\x1b[#Q\")   // pop restore"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[#R')   // ask xterm for stack depth + tag list"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[#P\");  /* push */\\nprintf(\"\\x1b[#Q\");  /* pop  */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "osc-set-palette",
        "osc-reset-palette",
        "osc-set-fg-bg",
        "sgr-fg-256"
      ]
    },
    {
      "slug": "decdc-decic",
      "family": "CSI",
      "title": {
        "en": "DECDC / DECIC — Delete / insert column (CSI Pn ' ~ / CSI Pn ' })",
        "zh": "DECDC / DECIC — 删除 / 插入列（CSI Pn ' ~ / CSI Pn ' }）"
      },
      "shortDesc": {
        "en": "Delete (DECDC) or insert (DECIC) Pn columns at the cursor — the column-oriented counterparts of DL (CSI Pn M) and IL (CSI Pn L).",
        "zh": "在光标处删除（DECDC）或插入（DECIC）Pn 列 —— DL（CSI Pn M）与 IL（CSI Pn L）的列向版本。"
      },
      "bytes": {
        "canonical": "\\x1b[<Pn>'~   (DECDC)   \\x1b[<Pn>'}   (DECIC)",
        "octal": "\\033[1'~ / \\033[1'}",
        "eEscape": "\\e[1'~ / \\e[1'}",
        "literal": "ESC [ Pn ' ~   /   ESC [ Pn ' }",
        "hex": "1b 5b ... 27 7e   /   1b 5b ... 27 7d"
      },
      "description": {
        "en": "DEC VT520+ rectangular editing primitives. **DECDC** (`\\x1b[<Pn>'~`) deletes `Pn` columns starting at the cursor column — every cell to the right of the deletion shifts left by `Pn`, and the rightmost `Pn` columns are filled with blanks using the current SGR background. **DECIC** (`\\x1b[<Pn>'}`) is the inverse — `Pn` blank columns are inserted at the cursor column, shifting existing content rightward and discarding whatever falls off the right edge. Both honour DECSTBM (vertical scroll region) **and** DECSLRM (horizontal scroll region) when those are active, so editing happens within the active rectangle rather than the whole screen. Note the intermediate byte: literal apostrophe `'` (0x27) between parameter and final byte — easy to omit when hand-typing. Defaults to `Pn=1`. Support is thin outside xterm and wezterm — many emulators (alacritty, ghostty, kitty's main mode) ignore them. Used historically by VT520 spreadsheet / form editors; modern TUIs almost universally redraw instead.",
        "zh": "DEC VT520+ 的矩形编辑原语。**DECDC**（`\\x1b[<Pn>'~`）从光标所在列开始删除 `Pn` 列 —— 删除位置右侧的每一格向左移动 `Pn` 列，最右侧的 `Pn` 列以当前 SGR 背景色填充空白。**DECIC**（`\\x1b[<Pn>'}`）相反 —— 在光标列插入 `Pn` 个空白列，原有内容右移，从右侧溢出的部分被丢弃。两者都遵循当前激活的 DECSTBM（纵向滚动区域）**与** DECSLRM（横向滚动区域），因此编辑只作用于活动矩形而非整屏。注意中间字节：参数与末字节之间是字面单引号 `'`（0x27），手写时容易遗漏。默认 `Pn=1`。除 xterm 与 wezterm 外支持稀薄 —— alacritty、ghostty、kitty 主模式都会忽略。曾被 VT520 表格 / 表单编辑器使用；现代 TUI 几乎清一色重绘代替。"
      },
      "parameters": [
        {
          "name": "Pn",
          "desc": {
            "en": "Number of columns to delete (DECDC) or insert (DECIC). Default 1.",
            "zh": "要删除（DECDC）或插入（DECIC）的列数。默认 1。"
          }
        }
      ],
      "spec": "DEC VT520 RM (DECDC / DECIC) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[3\\x27~'   # DECDC: delete 3 cols at cursor (note literal ' before ~)"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write(\"\\x1b[2'}\")   # DECIC: insert 2 blank cols"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[1'~\")   // DECDC: delete 1 col"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write(\"\\x1b[5'}\")   // DECIC: insert 5 cols"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[1'~\");   /* DECDC: delete one column at cursor */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "partial"
      },
      "related": [
        "csi-ich",
        "csi-dch",
        "csi-il",
        "csi-dl",
        "decslrm"
      ]
    },
    {
      "slug": "xtmodkeys",
      "family": "CSI",
      "title": {
        "en": "XTMODKEYS — Modify keyboard reporting (CSI > Pp ; Pv m)",
        "zh": "XTMODKEYS — 修改键盘上报模式（CSI > Pp ; Pv m）"
      },
      "shortDesc": {
        "en": "Switch xterm's modifyKeyboard / modifyCursorKeys / modifyFunctionKeys / modifyOtherKeys resources at runtime — the foundation for Ctrl+letter, Alt+letter disambiguation.",
        "zh": "运行时切换 xterm 的 modifyKeyboard / modifyCursorKeys / modifyFunctionKeys / modifyOtherKeys 资源 —— 是 Ctrl+字母、Alt+字母 等键位精准上报的基础。"
      },
      "bytes": {
        "canonical": "\\x1b[><Pp>;<Pv>m",
        "octal": "\\033[>4;2m",
        "eEscape": "\\e[>4;2m",
        "literal": "ESC [ > Pp ; Pv m",
        "hex": "1b 5b 3e ... 6d"
      },
      "description": {
        "en": "The `>` prefix flips the `m` final byte from SGR (set-graphic-rendition) to XTMODKEYS — a runtime-mutable view of four xterm resources that control how modifier-laden keys are reported. The first parameter `Pp` selects the resource (`0` = modifyKeyboard, `1` = modifyCursorKeys, `2` = modifyFunctionKeys, `3` = modifyKeypadKeys is reserved, `4` = modifyOtherKeys), and `Pv` sets its value. The killer feature is **modifyOtherKeys** (`Pp=4`): with `Pv=0` xterm only reports Ctrl+letter as the corresponding C0 byte (Ctrl+I === Tab, Ctrl+M === Enter), with `Pv=1` it reports modified versions of unambiguous keys via CSI 27 ~, and with `Pv=2` it reports **every** modified printable key — letting editors like vim/emacs/kakoune distinguish Ctrl+I from Tab, Ctrl+H from Backspace, and bind Alt+letter without the legacy ESC-prefix hack. Reset by emitting `\\x1b[>Pp m` with no `Pv` (restores xterm default) or `\\x1b[>4;0m` to leave modifyOtherKeys mode. Kitty's CSI u keyboard protocol (separate sequence) offers a strictly richer alternative and is preferred for greenfield code; XTMODKEYS remains the de-facto compatibility path for the millions of TUIs already targeting xterm.",
        "zh": "前缀 `>` 把末字节 `m` 从 SGR（设置图形属性）切换为 XTMODKEYS —— 一个运行时可改的视图，用于查看 / 修改 xterm 控制带修饰键上报方式的四个资源。首个参数 `Pp` 选择资源（`0` = modifyKeyboard，`1` = modifyCursorKeys，`2` = modifyFunctionKeys，`3` = modifyKeypadKeys，保留；`4` = modifyOtherKeys），`Pv` 设置取值。最有用的是 **modifyOtherKeys**（`Pp=4`）：`Pv=0` 时 xterm 把 Ctrl+字母只上报为对应的 C0 字节（Ctrl+I === Tab、Ctrl+M === Enter）；`Pv=1` 时把无歧义键的修饰组合以 CSI 27 ~ 上报；`Pv=2` 时上报**每一个**带修饰的可打印键 —— 让 vim / emacs / kakoune 之类的编辑器能区分 Ctrl+I 与 Tab、Ctrl+H 与 Backspace，并直接绑定 Alt+字母而不必再依赖传统的 ESC-前缀技巧。重置用 `\\x1b[>Pp m`（省略 `Pv` 恢复默认）或 `\\x1b[>4;0m`（关闭 modifyOtherKeys）。kitty 自家的 CSI u 键盘协议（另一种序列）功能更全，新代码建议优先采用；XTMODKEYS 则是数百万既有 xterm 风格 TUI 的事实兼容路径。"
      },
      "parameters": [
        {
          "name": "Pp",
          "desc": {
            "en": "Resource selector: `0` modifyKeyboard, `1` modifyCursorKeys, `2` modifyFunctionKeys, `4` modifyOtherKeys.",
            "zh": "资源选择：`0` modifyKeyboard、`1` modifyCursorKeys、`2` modifyFunctionKeys、`4` modifyOtherKeys。"
          }
        },
        {
          "name": "Pv",
          "desc": {
            "en": "New value for the resource. For modifyOtherKeys: `0` off, `1` modified-only-when-unambiguous, `2` always modified.",
            "zh": "资源的新取值。modifyOtherKeys 时：`0` 关闭、`1` 仅无歧义时上报修饰、`2` 始终上报修饰。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (XTMODKEYS)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Enable full modifyOtherKeys — every Ctrl+letter reports distinctly:\\nprintf '\\033[>4;2m'\\n# (run from inside a TUI that handles CSI 27 ~ replies; raw shells will show garbage)"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[>4;2m')   # enable modifyOtherKeys 2\\n# remember to send '\\x1b[>4;0m' on exit to restore default"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[>4;1m\")   // modifyOtherKeys mode 1"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[>4;2m')   // enable full modify-other-keys"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[>4;2m\");   /* opt in to fully-modified key reports */\\natexit_send(\"\\x1b[>4;0m\");  /* opt out at exit */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "dec-focus-events",
        "dec-bracketed-paste",
        "c0-controls",
        "decstr-soft-reset"
      ]
    },
    {
      "slug": "xtsmtitle-xtrmtitle",
      "family": "CSI",
      "title": {
        "en": "XTSMTITLE / XTRMTITLE — Set / reset title display modes (CSI > Ps ; … t / T)",
        "zh": "XTSMTITLE / XTRMTITLE — 设置 / 重置标题显示模式（CSI > Ps ; … t / T）"
      },
      "shortDesc": {
        "en": "Switch how xterm interprets / returns window-title and icon-name strings — hex vs UTF-8 encoding, truncation, set-vs-query behaviour.",
        "zh": "切换 xterm 解读 / 返回窗口标题与图标名称字符串的方式 —— 十六进制 vs UTF-8 编码、截断、设置 vs 查询行为。"
      },
      "bytes": {
        "canonical": "\\x1b[><Ps>;<Ps>…t   (set)   \\x1b[><Ps>;<Ps>…T   (reset)",
        "octal": "\\033[>2t / \\033[>2T",
        "eEscape": "\\e[>2t / \\e[>2T",
        "literal": "ESC [ > Ps ; Ps … t   /   ESC [ > Ps ; Ps … T",
        "hex": "1b 5b 3e ... 74 / 1b 5b 3e ... 54"
      },
      "description": {
        "en": "The `>` prefix disambiguates these from XTWINOPS (`CSI Ps ; Ps ; Ps t`, window resize / move / query) and from the SD / mouse-tracking final `T`. **XTSMTITLE** (`\\x1b[><Ps>t`) toggles ON one or more title-display modes; **XTRMTITLE** (`\\x1b[><Ps>T`) toggles OFF the same set. Each `Ps` selects a mode: `0` decode incoming OSC 0/1/2 title text as hex pairs (legacy escape for non-ASCII), `1` accept the title text as UTF-8 (xterm default since 2010s), `2` accept the icon name as UTF-8, `3` query replies (OSC 20 / 21 / GR 23 + XTWINOPS 21 / 20) return the title as UTF-8 instead of the bytes xterm actually has stored. Multiple `Ps` values can be combined in one sequence: `\\x1b[>1;2t` flips both UTF-8 modes. Together with `OSC 0/1/2` (set title) and XTWINOPS 20/21 (query title) these knobs control the *encoding* round-trip. Most modern terminals default to UTF-8 already and these sequences are usually no-ops, but explicitly setting `>1;2t` is the safest portable warm-up before pushing a title containing non-ASCII characters.",
        "zh": "前缀 `>` 把这两个序列与 XTWINOPS（`CSI Ps ; Ps ; Ps t`，调整 / 移动 / 查询窗口）以及 SD / 鼠标追踪的末字节 `T` 区分开。**XTSMTITLE**（`\\x1b[><Ps>t`）打开一个或多个标题显示模式；**XTRMTITLE**（`\\x1b[><Ps>T`）关闭同一组。每个 `Ps` 选一种模式：`0` 把传入的 OSC 0/1/2 标题文本按十六进制对解码（用于非 ASCII 的传统转义）；`1` 把标题文本按 UTF-8 解读（xterm 自 2010 年代起的默认行为）；`2` 把图标名按 UTF-8 解读；`3` 查询回复（OSC 20 / 21 / XTWINOPS 20 / 21）以 UTF-8 形式返回标题，而非 xterm 内部实际存储的字节。一条序列里可组合多个 `Ps`：`\\x1b[>1;2t` 同时开启两种 UTF-8 模式。配合 `OSC 0/1/2`（设置标题）与 XTWINOPS 20/21（查询标题），这些开关控制*编码*的回环。多数现代终端默认就是 UTF-8，此类序列通常是空操作，但在推送含非 ASCII 字符的标题前显式 `>1;2t` 仍是最稳妥的可移植起手式。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "Mode selector: `0` hex-decode incoming title, `1` UTF-8 window title, `2` UTF-8 icon name, `3` query replies in UTF-8. Multiple may be combined.",
            "zh": "模式选择：`0` 标题十六进制解码、`1` 窗口标题按 UTF-8、`2` 图标名按 UTF-8、`3` 查询回复按 UTF-8。可组合多个。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (XTSMTITLE / XTRMTITLE)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Opt in to UTF-8 for both title + icon name before pushing a non-ASCII title:\\nprintf '\\033[>1;2t'\\nprintf '\\033]0;\\xe6\\x9c\\x80\\xe6\\x96\\xb0\\xe6\\x97\\xa5\\xe5\\xbf\\x97\\007'"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[>1t')        # UTF-8 window title\\nsys.stdout.write('\\x1b]0;\\u4e2d\\u6587\\x07')   # CJK title now decodes correctly"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[>1;2t\")   // UTF-8 for title + icon\\nfmt.Print(\"\\x1b[>1;2T\")   // and back to hex-only when done"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[>3t')   // make query replies return UTF-8 strings"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[>1;2t\");   /* before OSC 0;<utf8 title>;BEL */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "partial",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "partial",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "osc-title",
        "osc-icon-name",
        "xtwinops"
      ]
    },
    {
      "slug": "decswbv-decsmbv",
      "family": "CSI",
      "title": {
        "en": "DECSWBV / DECSMBV — Set warning / margin bell volume (CSI Ps SP t / CSI Ps SP u)",
        "zh": "DECSWBV / DECSMBV — 设置警告 / 边距铃音量（CSI Ps SP t / CSI Ps SP u）"
      },
      "shortDesc": {
        "en": "Adjust the audio volume of the C0 BEL (DECSWBV) and the right-margin warning bell (DECSMBV) — almost universally ignored by modern emulators.",
        "zh": "调整 C0 BEL（DECSWBV）与右边距警告铃（DECSMBV）的音量 —— 现代模拟器几乎一致忽略。"
      },
      "bytes": {
        "canonical": "\\x1b[<Ps> t   (DECSWBV)   \\x1b[<Ps> u   (DECSMBV)",
        "octal": "\\033[8 t / \\033[4 u",
        "eEscape": "\\e[8 t / \\e[4 u",
        "literal": "ESC [ Ps SP t   /   ESC [ Ps SP u",
        "hex": "1b 5b ... 20 74   /   1b 5b ... 20 75"
      },
      "description": {
        "en": "Two DEC VT520 audio controls that share the same `Ps` scale: `0` or `1` silence the bell, `2` / `3` / `4` set low volume, and `5` / `6` / `7` / `8` set high volume. **DECSWBV** (`\\x1b[<Ps> t`, intermediate is a literal space `0x20`) controls the volume of the C0 BEL byte (`\\x07`, Ctrl-G) that processes emit on shell-completion / error / Ctrl+G. **DECSMBV** (`\\x1b[<Ps> u`) controls the separate margin-bell that DEC terminals could fire when text written past column N approached the right margin (column N defaulting to 72 of 80, configurable via DECSMM). The intermediate space matters — without it `\\x1b[8t` is XTWINOPS resize and `\\x1b[8u` is undefined. Modern emulators (xterm, kitty, wezterm, ghostty, alacritty, iTerm2, Windows Terminal) all delegate bell rendering to OS audio settings or a single boolean enable / disable, so DECSWBV / DECSMBV are silently ignored. The sequences remain meaningful only on physical DEC VTxxx terminals and a handful of emulators that ship VT compatibility modes (mlterm, some BBS clients). Document them for parser completeness, but don't expect actual volume control.",
        "zh": "两个 DEC VT520 音频控制，共用同一组 `Ps` 取值：`0` 或 `1` 静音、`2` / `3` / `4` 低音量、`5` / `6` / `7` / `8` 高音量。**DECSWBV**（`\\x1b[<Ps> t`，中间字节是字面空格 `0x20`）控制 C0 BEL（`\\x07`，Ctrl-G）字节触发铃音的音量 —— shell 完成 / 错误 / Ctrl+G 都会发出该字节。**DECSMBV**（`\\x1b[<Ps> u`）控制独立的边距铃 —— DEC 终端在写入超过第 N 列且逼近右边距时会触发（N 默认 80 中的 72，可经 DECSMM 调整）。中间空格不可省 —— 没有它 `\\x1b[8t` 解作 XTWINOPS 调整大小，`\\x1b[8u` 则未定义。现代模拟器（xterm、kitty、wezterm、ghostty、alacritty、iTerm2、Windows Terminal）一律把铃声渲染交给系统音频设置或单一的开 / 关布尔值处理，DECSWBV / DECSMBV 因此被静默忽略。这两个序列只在物理 DEC VTxxx 终端以及少数自带 VT 兼容模式的模拟器（mlterm、部分 BBS 客户端）上仍有效果。出于解析器完备性记录在册，但不要指望真的能调整音量。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "Volume level. `0`/`1` off · `2`–`4` low · `5`–`8` high. Default 0.",
            "zh": "音量等级。`0` / `1` 静音 · `2`–`4` 低音 · `5`–`8` 高音。默认 0。"
          }
        }
      ],
      "spec": "DEC VT520 RM (DECSWBV / DECSMBV)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[8 t'   # DECSWBV: warning bell at max volume (note SP before t)"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[0 t')   # DECSWBV: silence the warning bell"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[4 u\")   // DECSMBV: low-volume margin bell"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[0 u')   // DECSMBV: silence the margin bell"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[6 t\");  /* DECSWBV: medium-high bell — ignored on most emulators */"
        }
      ],
      "support": {
        "xterm": "no",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "c0-controls",
        "decstr-soft-reset",
        "ris-reset"
      ]
    },
    {
      "slug": "sgr-mouse-encoding",
      "family": "CSI",
      "title": {
        "en": "SGR / urxvt mouse encoding — Mouse-report wire formats (CSI M / CSI < / CSI)",
        "zh": "SGR / urxvt 鼠标编码 — 鼠标上报的线缆格式（CSI M / CSI < / CSI）"
      },
      "shortDesc": {
        "en": "The three on-wire formats a terminal uses to report mouse events: legacy CSI M Cb Cx Cy, modern SGR ?1006, and urxvt ?1015 — what's actually in the input stream after DECSET ?100x enables tracking.",
        "zh": "终端上报鼠标事件的三种线缆格式：传统 CSI M Cb Cx Cy、现代 SGR ?1006、urxvt ?1015 —— DECSET ?100x 启用追踪后，输入流里到底出现什么。"
      },
      "bytes": {
        "canonical": "\\x1b[M<Cb><Cx><Cy>   (legacy)   \\x1b[<<Cb>;<Cx>;<Cy>M|m   (SGR ?1006)   \\x1b[<Cb>;<Cx>;<Cy>M   (urxvt ?1015)",
        "octal": "\\033[M ! ! !",
        "eEscape": "\\e[<0;5;5M",
        "literal": "ESC [ M Cb Cx Cy   /   ESC [ < Cb ; Cx ; Cy M|m   /   ESC [ Cb ; Cx ; Cy M",
        "hex": "1b 5b 4d ...   /   1b 5b 3c ... 4d|6d   /   1b 5b ... 4d"
      },
      "description": {
        "en": "Enabling mouse tracking via DECSET (`?1000`/`?1002`/`?1003` — see `dec-mouse-tracking`) is only half the story; you also need to know what format the events arrive in. **Legacy X10/X11** (`\\x1b[M<Cb><Cx><Cy>`) is the default: a fixed 6-byte sequence where each of `Cb`, `Cx`, `Cy` is a **single byte** computed as `value + 32` (offset to avoid C0 collisions). Button info is encoded in `Cb`: low 2 bits = button index (0/1/2 = left/middle/right, 3 = release), bit 5 = motion, bit 4 = control, bit 3 = alt, bit 2 = shift, bits 6+7 = wheel/extra buttons. The killer flaw: `Cx`/`Cy` saturate at 223 (255−32) — beyond column 223 they break. **SGR encoding** (`?1006`) fixes this by emitting `\\x1b[<<Cb>;<Cx>;<Cy>M` for press and `m` for release — ASCII decimal numbers, no saturation, M/m disambiguates press from release on the same button (legacy used Cb=3 for any release, losing which button was let go). **urxvt encoding** (`?1015`) is an interim variant: `\\x1b[<Cb+32>;<Cx>;<Cy>M` — decimal Cx/Cy (no 223 limit) but the legacy `+32` on Cb is preserved and there's no M/m differentiation. SGR (1006) is the only modern choice — kitty, alacritty, wezterm, ghostty, Windows Terminal, iTerm2 all emit it preferentially. Parser code should accept all three formats but write greenfield code targeting only 1006.",
        "zh": "通过 DECSET（`?1000` / `?1002` / `?1003` —— 参见 `dec-mouse-tracking`）启用鼠标追踪只是一半，还要知道事件以什么格式抵达。**传统 X10/X11**（`\\x1b[M<Cb><Cx><Cy>`）是默认值：固定 6 字节序列，每个 `Cb`、`Cx`、`Cy` 都是**单字节**，按 `值 + 32` 编码（偏移以避开 C0 字节）。按键信息在 `Cb` 里：低 2 位 = 按键索引（0 / 1 / 2 = 左 / 中 / 右，3 = 释放），第 5 位 = 移动，第 4 位 = Ctrl，第 3 位 = Alt，第 2 位 = Shift，第 6 / 7 位 = 滚轮 / 扩展键。致命缺陷：`Cx` / `Cy` 在 223（255−32）饱和 —— 223 列以外的事件无法上报。**SGR 编码**（`?1006`）用 `\\x1b[<<Cb>;<Cx>;<Cy>M` 表示按下、`m` 表示释放修复此问题 —— ASCII 十进制数字，无饱和，M / m 区分按下与释放同一按键（传统格式释放都是 Cb=3，丢失了具体哪个键被松开）。**urxvt 编码**（`?1015`）是过渡变体：`\\x1b[<Cb+32>;<Cx>;<Cy>M` —— Cx / Cy 十进制（无 223 限制），但 Cb 保留传统 `+32`，且不区分 M / m。SGR（1006）是现代唯一选择 —— kitty、alacritty、wezterm、ghostty、Windows Terminal、iTerm2 全都优先输出。解析器应同时接受三种格式，新代码只用 1006。"
      },
      "parameters": [
        {
          "name": "Cb",
          "desc": {
            "en": "Button + modifier bitmask. Legacy/urxvt: byte = value+32. SGR (1006): ASCII decimal, no offset.",
            "zh": "按键 + 修饰位掩码。传统 / urxvt：字节 = 值 + 32。SGR（1006）：ASCII 十进制，无偏移。"
          }
        },
        {
          "name": "Cx, Cy",
          "desc": {
            "en": "1-based column / row. Legacy: single byte value+32 (caps at column 223). SGR/urxvt: ASCII decimal (no limit).",
            "zh": "从 1 起算的列 / 行。传统：单字节值 + 32（列上限 223）。SGR / urxvt：ASCII 十进制（无上限）。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (Mouse Tracking)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Show what arrives on stdin after enabling SGR mouse:\\nprintf '\\033[?1000h\\033[?1006h'  # enable\\ncat | xxd               # click → \\x1b[<0;5;3M  release → \\x1b[<0;5;3m"
        },
        {
          "lang": "python",
          "code": "# Decode an SGR mouse report into (button, x, y, press/release):\\nimport re\\nm = re.match(r'\\x1b\\\\[<(\\\\d+);(\\\\d+);(\\\\d+)([Mm])', '\\x1b[<0;25;12M')\\nbtn, x, y, kind = int(m[1]), int(m[2]), int(m[3]), m[4]   # 0, 25, 12, 'M' (press)"
        },
        {
          "lang": "go",
          "code": "// Match SGR mouse report: \\\\x1b\\\\[<(\\\\d+);(\\\\d+);(\\\\d+)([Mm])\\nre := regexp.MustCompile(`\\\\x1b\\\\[<(\\\\d+);(\\\\d+);(\\\\d+)([Mm])`)\\nm := re.FindStringSubmatch(\"\\x1b[<0;5;3M\")   // m[4] == \"M\" means press"
        },
        {
          "lang": "javascript",
          "code": "// Distinguish press vs release on the same button (impossible in legacy):\\nconst m = '\\x1b[<2;10;20m'.match(/\\\\x1b\\\\[<(\\\\d+);(\\\\d+);(\\\\d+)([Mm])/);\\nconst released = m[4] === 'm';   // release of right button at (10,20)"
        },
        {
          "lang": "c",
          "code": "/* Detect column-223 saturation on legacy format: */\\nif (cb_byte >= 32 && (cx_byte == 255 || cy_byte == 255)) {\\n  /* event beyond column 223 — request SGR encoding instead */\\n  printf(\"\\x1b[?1006h\");\\n}"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "dec-mouse-tracking",
        "dec-focus-events",
        "dec-bracketed-paste"
      ]
    },
    {
      "slug": "xtversion",
      "family": "CSI",
      "title": {
        "en": "XTVERSION — Report terminal name and version (CSI > Pp q)",
        "zh": "XTVERSION — 上报终端名称与版本（CSI > Pp q）"
      },
      "shortDesc": {
        "en": "Ask the terminal for a human-readable name + version string — the modern alternative to DECDA for feature detection in tools like Helix, Zellij, Neovim.",
        "zh": "向终端询问可读的名称 + 版本字符串 —— 替代 DECDA 用于功能检测的现代方案，已被 Helix、Zellij、Neovim 等采用。"
      },
      "bytes": {
        "canonical": "\\x1b[>0q   (query)   reply: \\x1bP>|<name> <version>\\x1b\\\\",
        "octal": "\\033[>0q",
        "eEscape": "\\e[>0q",
        "literal": "ESC [ > Pp q   →   DCS > | <text> ST",
        "hex": "1b 5b 3e ... 71"
      },
      "description": {
        "en": "Sends a Tertiary Device Attribute (TDA) query in xterm's extended form. The `>` prefix flips the final byte `q` from DECSCA (character protection) to XTVERSION; `Pp` is reserved (always emit `0`) and exists only for forward compatibility. The terminal replies with a DCS-framed string identifying itself: `DCS > | <name> <space> <version> ST` — e.g. `\\x1bP>|XTerm(370)\\x1b\\\\`, `\\x1bP>|kitty 0.32.2\\x1b\\\\`, `\\x1bP>|WezTerm 20240203\\x1b\\\\`, `\\x1bP>|ghostty 1.0.0\\x1b\\\\`. The terminator is ST (`\\x1b\\\\`), occasionally BEL (`\\x07`) for legacy emitters. This sequence has effectively replaced DECDA (`\\x1b[c`) for feature detection — DECDA's terminal-ID numbers (61/62/63 = VT100/220/320) were exhausted in the 1990s and don't represent modern features at all. XTVERSION is the load-bearing query behind every TUI that branches on `kitty` vs `WezTerm` vs `iTerm2` to enable kitty graphics, OSC 1337 features, or sixel. Round-trip is fast (synchronous on Unix terminals; non-blocking polling works for ConPTY). If no reply arrives within ~200 ms, assume a primitive terminal that doesn't implement XTVERSION.",
        "zh": "以 xterm 扩展形式发送 Tertiary Device Attribute（TDA）查询。`>` 前缀把末字节 `q` 从 DECSCA（字符保护）切换为 XTVERSION；`Pp` 保留（恒发 `0`），仅供前向兼容。终端以 DCS 包裹的字符串回复，标识自身：`DCS > | <名称> <空格> <版本> ST` —— 例如 `\\x1bP>|XTerm(370)\\x1b\\\\`、`\\x1bP>|kitty 0.32.2\\x1b\\\\`、`\\x1bP>|WezTerm 20240203\\x1b\\\\`、`\\x1bP>|ghostty 1.0.0\\x1b\\\\`。终止符是 ST（`\\x1b\\\\`），偶有遗留实现用 BEL（`\\x07`）。此序列实际上已取代 DECDA（`\\x1b[c`）作为功能检测手段 —— DECDA 的终端 ID 编号（61 / 62 / 63 = VT100 / 220 / 320）早在 1990 年代就耗尽，与现代特性已脱钩。所有依据 `kitty` / `WezTerm` / `iTerm2` 分支启用 kitty graphics、OSC 1337 或 sixel 的 TUI 都把 XTVERSION 作为承重查询。往返很快（Unix 终端同步；ConPTY 上轮询非阻塞也可）。若约 200 ms 内未收到回复，可视为原始终端不支持 XTVERSION。"
      },
      "parameters": [
        {
          "name": "Pp",
          "desc": {
            "en": "Reserved. Always emit `0`. The presence of any value distinguishes XTVERSION from CSI > q (no param) which is also valid.",
            "zh": "保留。恒发 `0`。任意值的存在把 XTVERSION 与同样合法的 CSI > q（无参）区分开。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (Tertiary DA / XTVERSION)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Print whichever terminal name comes back, then disambiguate:\\nprintf '\\033[>0q'\\nread -rd '\\\\' reply\\necho \"$reply\"   # e.g. \\x1bP>|kitty 0.32.2"
        },
        {
          "lang": "python",
          "code": "import sys, termios, tty, select\\nsys.stdout.write('\\x1b[>0q'); sys.stdout.flush()\\n# Read DCS-framed reply: starts with \\x1bP and ends with \\x1b\\\\"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[>0q\")\\n// scan stdin for DCS > | ... ST framing\\n// branch: strings.HasPrefix(name, \"kitty\") → enable kitty graphics"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[>0q')\\n// process.stdin gets back a DCS-framed text like \\x1bP>|WezTerm 20240203\\x1b\\\\"
        },
        {
          "lang": "c",
          "code": "fputs(\"\\x1b[>0q\", stdout); fflush(stdout);\\n/* read DCS payload, switch on substring 'kitty' / 'xterm' / 'WezTerm' */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "csi-da",
        "dcs-decrqss",
        "dcs-termcap-query"
      ]
    },
    {
      "slug": "csi-private-dsr",
      "family": "CSI",
      "title": {
        "en": "CSI ? Ps n — Private DSR (extended status queries)",
        "zh": "CSI ? Ps n — 私有 DSR（扩展状态查询）"
      },
      "shortDesc": {
        "en": "DEC private Device Status Reports — extended cursor position (?6 DECXCPR with page), printer / UDK / locator / macro-space / memory-checksum status.",
        "zh": "DEC 私有设备状态报告 —— 扩展光标位置（?6 DECXCPR 含页号）、打印机 / UDK / 定位器 / 宏空间 / 内存校验和等状态。"
      },
      "bytes": {
        "canonical": "\\x1b[?<Ps>n",
        "octal": "\\033[?6n",
        "eEscape": "\\e[?6n",
        "literal": "ESC [ ? Ps n",
        "hex": "1b 5b 3f ... 6e"
      },
      "description": {
        "en": "The `?` prefix flips the standard DSR (`\\x1b[<Ps>n`) into DEC's private DSR namespace, where Ps values have different — extended — meanings. **`?6n` DECXCPR** (Extended Cursor Position Report) is the most useful: terminals reply `\\x1b[?<row>;<col>;<page>R` adding the active display page number — the original DSR-6 reply (`\\x1b[<row>;<col>R`) omits the page. Other useful queries: **`?15n`** printer status — reply `\\x1b[?10n` (ready) / `?11n` (not ready) / `?13n` (no printer); **`?25n`** UDK lock status — reply `\\x1b[?20n` (unlocked) / `?21n` (locked); **`?26n`** keyboard dialect — reply `\\x1b[?27;<Ps>;<Pm>;<Pp>n` where Ps = language (1 = North American, 2 = British, …); **`?53n`** / **`?55n`** locator status; **`?62n`** macro space — reply `\\x1b[<Pn>*{` (bytes of macro space free); **`?63;Ps n`** memory checksum — reply `DCS Pp ! ~ Ps ! Pchecksum ST`; **`?75n`** data integrity report; **`?85n`** multiple session status. Most modern emulators implement at most `?6n` plus a stub `?13n` (no printer) — the rest reply with the silently-ignored bytes or no reply at all. Use DECRQM (`\\x1b[<Ps>$p`) for mode state queries; reserve private DSR for the few queries above.",
        "zh": "前缀 `?` 把标准 DSR（`\\x1b[<Ps>n`）切换到 DEC 的私有 DSR 命名空间，Ps 含义随之扩展。**`?6n` DECXCPR**（扩展光标位置报告）最实用：终端回复 `\\x1b[?<行>;<列>;<页>R`，额外包含当前显示页号 —— 原始 DSR-6 的回复（`\\x1b[<行>;<列>R`）省略页号。其他有用查询：**`?15n`** 打印机状态 —— 回复 `\\x1b[?10n`（就绪）/ `?11n`（未就绪）/ `?13n`（无打印机）；**`?25n`** UDK 锁定状态 —— 回复 `\\x1b[?20n`（解锁）/ `?21n`（锁定）；**`?26n`** 键盘语言 —— 回复 `\\x1b[?27;<Ps>;<Pm>;<Pp>n`，Ps = 语言（1 = 北美、2 = 英式等）；**`?53n`** / **`?55n`** 定位器状态；**`?62n`** 宏空间 —— 回复 `\\x1b[<Pn>*{`（剩余宏空间字节数）；**`?63;Ps n`** 内存校验和 —— 回复 `DCS Pp ! ~ Ps ! P校验和 ST`；**`?75n`** 数据完整性；**`?85n`** 多会话状态。多数现代模拟器最多只实现 `?6n` 加一个 `?13n`（无打印机）桩，其余不回应或回应被静默忽略。模式状态查询请用 DECRQM（`\\x1b[<Ps>$p`），私有 DSR 仅用于上述少数几项。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "Private DSR selector. Common: `6` extended cursor pos (DECXCPR), `15` printer, `25` UDK, `26` keyboard, `53/55` locator, `62` macro space, `63;n` checksum, `75` data integrity, `85` session count.",
            "zh": "私有 DSR 选择子。常见值：`6` 扩展光标位置（DECXCPR）、`15` 打印机、`25` UDK、`26` 键盘、`53` / `55` 定位器、`62` 宏空间、`63;n` 校验和、`75` 数据完整性、`85` 会话数。"
          }
        }
      ],
      "spec": "DEC VT510 RM (private DSR) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?6n'   # DECXCPR — reply: \\x1b[?<row>;<col>;<page>R"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[?15n'); sys.stdout.flush()   # query printer status"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?26n\")   // query keyboard dialect"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?62n')   // macro-space available bytes"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?6n\");   /* DECXCPR — get cursor pos + active page */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "partial",
        "wt": "partial",
        "cmd": "no",
        "kitty": "partial",
        "alacritty": "partial",
        "wezterm": "partial",
        "ghostty": "partial",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "csi-dsr",
        "decrqm",
        "dcs-decrqss"
      ]
    },
    {
      "slug": "hpa-hpr-vpr",
      "family": "CSI",
      "title": {
        "en": "HPA / HPR / VPR — Position absolute & relative (CSI ` / CSI a / CSI e)",
        "zh": "HPA / HPR / VPR — 绝对与相对定位（CSI ` / CSI a / CSI e）"
      },
      "shortDesc": {
        "en": "ECMA-48's row/col-preserving cursor moves — HPA (absolute column), HPR (relative column), VPR (relative row) — completing the trio anchored by VPA.",
        "zh": "ECMA-48 中保留行 / 列的光标移动 —— HPA（绝对列）、HPR（相对列）、VPR（相对行）—— 与 VPA 配套的完整四元。"
      },
      "bytes": {
        "canonical": "\\x1b[<col>`   (HPA)   \\x1b[<n>a   (HPR)   \\x1b[<n>e   (VPR)",
        "octal": "\\033[10` / \\033[5a / \\033[3e",
        "eEscape": "\\e[10` / \\e[5a / \\e[3e",
        "literal": "ESC [ col `   /   ESC [ n a   /   ESC [ n e",
        "hex": "1b 5b ... 60   /   1b 5b ... 61   /   1b 5b ... 65"
      },
      "description": {
        "en": "Three ECMA-48 cursor-positioning primitives that preserve the orthogonal axis — same shape as VPA (`\\x1b[<row>d`) and CHA (`\\x1b[<col>G`, slug `cursor-column`) but covering the gaps. **HPA** (`\\x1b[<col>`` ` `) Horizontal Position Absolute — move to absolute column `<col>` (1-based), keep current row. Semantically identical to CHA (`G`); final byte differs only because ECMA-48 § 8.3.57 (HPA) predates / parallels § 8.3.9 (CHA). **HPR** (`\\x1b[<n>a`) Horizontal Position Relative — move `n` columns right, keep row. Same effect as CUF (`\\x1b[<n>C`) but the final byte `a` distinguishes the ECMA-48-canonical form. **VPR** (`\\x1b[<n>e`) Vertical Position Relative — move `n` rows down, keep column. Same as CUD (`\\x1b[<n>B`) by final byte `e`. All three default to `n=1` / `col=1` when omitted; out-of-range values clamp to the visible region (or DECSTBM/DECSLRM region when those are active). In practice most modern code emits CHA/CUF/CUD/CUB instead — but every ECMA-48-conformant terminal accepts the HPA/HPR/VPR aliases, and curses' default capability table contains them, so any parser must recognize the alternative final bytes. The HPA backtick ` ` ` final byte is also the easiest of any CSI final to mistype — note it's 0x60, **not** apostrophe 0x27 (which would be DECIC / DECDC's intermediate byte).",
        "zh": "三个 ECMA-48 光标定位原语，分别保留另一根轴 —— 形态与 VPA（`\\x1b[<row>d`）、CHA（`\\x1b[<col>G`，slug `cursor-column`）相同，填补了四元中的另一半。**HPA**（`\\x1b[<col>`` ` `）水平位置绝对 —— 移到绝对列 `<col>`（从 1 起），保留当前行。语义等同 CHA（`G`），末字节有别仅因 ECMA-48 § 8.3.57（HPA）与 § 8.3.9（CHA）并列存在。**HPR**（`\\x1b[<n>a`）水平位置相对 —— 右移 `n` 列，保留行。效果同 CUF（`\\x1b[<n>C`），末字节 `a` 用以区分 ECMA-48 正统形式。**VPR**（`\\x1b[<n>e`）垂直位置相对 —— 下移 `n` 行，保留列。同 CUD（`\\x1b[<n>B`），仅末字节为 `e`。三者省略时默认 `n=1` / `col=1`；超界数值被钳到可视区域（启用 DECSTBM / DECSLRM 时为对应区域）。实际上现代代码多用 CHA / CUF / CUD / CUB；但每个 ECMA-48 兼容终端都接受 HPA / HPR / VPR 别名，curses 默认能力表里就有它们，因此解析器必须识别这些末字节。HPA 的反引号 ` ` ` 末字节是所有 CSI 末字节中最容易打错的 —— 注意它是 0x60，**不是** 0x27 的单引号（那是 DECIC / DECDC 的中间字节）。"
      },
      "parameters": [
        {
          "name": "col / n",
          "desc": {
            "en": "HPA: absolute column (1-based). HPR: columns to move right. VPR: rows to move down. Default 1 if omitted.",
            "zh": "HPA：绝对列（从 1 起）。HPR：右移的列数。VPR：下移的行数。省略默认 1。"
          }
        }
      ],
      "spec": "ECMA-48 §8.3.57 (HPA) / §8.3.59 (HPR) / §8.3.160 (VPR)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[40`status: ok'   # HPA: jump to col 40, keep row (note backtick, not single quote)"
        },
        {
          "lang": "python",
          "code": "import sys; sys.stdout.write('\\x1b[5a')   # HPR: move 5 cols right"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[3e\")   // VPR: move 3 rows down"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[1`')   // HPA: column 1 (== CR but doesn't move row)"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[10a\");   /* HPR: 10 cols right — same effect as \\x1b[10C */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-vpa",
        "cursor-column",
        "cursor-move",
        "cursor-position"
      ]
    },
    {
      "slug": "xtsmgraphics",
      "family": "CSI",
      "title": {
        "en": "XTSMGRAPHICS — Sixel / ReGIS / color-register capacity query + set (CSI ? Pi ; Pa ; Pv S)",
        "zh": "XTSMGRAPHICS — Sixel / ReGIS / 颜色寄存器容量查询 + 设置（CSI ? Pi ; Pa ; Pv S）"
      },
      "shortDesc": {
        "en": "Read / set the terminal's graphics limits — number of sixel color registers, sixel graphics area, ReGIS area. The standard knob for image-aware TUIs to size their bitmaps.",
        "zh": "查询 / 设置终端的图形上限 —— sixel 颜色寄存器数、sixel 图形区域、ReGIS 图形区域。图像感知 TUI 决定位图大小的标准入口。"
      },
      "bytes": {
        "canonical": "\\x1b[?<Pi>;<Pa>;<Pv>S",
        "octal": "\\033[?1;1S",
        "eEscape": "\\e[?1;1S",
        "literal": "ESC [ ? Pi ; Pa ; Pv S",
        "hex": "1b 5b 3f ... 53"
      },
      "description": {
        "en": "Xterm's graphics-capability primitive. The `?` prefix flips final-byte `S` from SU (scroll up) to XTSMGRAPHICS — note the parse ambiguity with SU (`\\x1b[<Ps>S` without `?` is scroll-up). Three parameters: **`Pi` item** = `1` color registers, `2` sixel graphics area (rows×cols of pixels), `3` ReGIS graphics area. **`Pa` action** = `1` read current value, `2` reset to default, `3` set to `Pv`, `4` read maximum value. **`Pv` value** is only used when `Pa=3` (set). Reply is `\\x1b[?<Pi>;<Ps>;<Pv>S` where `Ps` is a status code (`0` success, `1` error/no-graphics, `2` reset error, `3` set error, `4` out-of-range). Critical for sixel-emitting TUIs (like neovim's image.nvim, w3m-img, timg, chafa): before drawing they query `\\x1b[?1;4S` (max color registers) and `\\x1b[?2;1S` (current sixel area) to size their dither palette and tile dimensions correctly. xterm defaults are stingy (256 color registers, 1000×1000 pixel sixel area); kitty exposes huge values; alacritty/gnome-terminal/Windows Terminal return error or nothing (no sixel support). Always check the status code in the reply — `Ps=1` means the terminal said \"no graphics for you\" and you should fall back to half-block or ASCII art.",
        "zh": "xterm 的图形能力原语。前缀 `?` 把末字节 `S` 从 SU（向上滚动）切换为 XTSMGRAPHICS —— 注意与 SU 的解析二义性（`\\x1b[<Ps>S` 无 `?` 是向上滚动）。三个参数：**`Pi` 项** = `1` 颜色寄存器、`2` sixel 图形区域（像素行 × 列）、`3` ReGIS 图形区域。**`Pa` 操作** = `1` 读取当前值、`2` 重置为默认、`3` 设为 `Pv`、`4` 读取最大值。**`Pv` 取值**仅当 `Pa=3`（设置）时使用。回复格式 `\\x1b[?<Pi>;<Ps>;<Pv>S`，`Ps` 是状态码（`0` 成功、`1` 错误 / 无图形、`2` 重置错误、`3` 设置错误、`4` 超界）。对发 sixel 的 TUI（如 neovim 的 image.nvim、w3m-img、timg、chafa）至关重要：绘图前先查询 `\\x1b[?1;4S`（最大颜色寄存器数）与 `\\x1b[?2;1S`（当前 sixel 区域），据此调整抖动调色板与瓦片尺寸。xterm 默认值偏小（256 个颜色寄存器、1000×1000 像素 sixel 区域）；kitty 暴露的值很大；alacritty / gnome-terminal / Windows Terminal 返回错误或无回应（不支持 sixel）。务必检查回复里的状态码 —— `Ps=1` 表示终端宣告「无图形支持」，应回退到半块字符或 ASCII 美术。"
      },
      "parameters": [
        {
          "name": "Pi",
          "desc": {
            "en": "Item selector: `1` color registers, `2` sixel area, `3` ReGIS area.",
            "zh": "项选择：`1` 颜色寄存器、`2` sixel 区域、`3` ReGIS 区域。"
          }
        },
        {
          "name": "Pa",
          "desc": {
            "en": "Action: `1` read, `2` reset, `3` set (with Pv), `4` read max.",
            "zh": "操作：`1` 读取、`2` 重置、`3` 设置（用 Pv）、`4` 读最大。"
          }
        },
        {
          "name": "Pv",
          "desc": {
            "en": "Value to set when Pa=3. Omitted otherwise.",
            "zh": "Pa=3 时的设置值。其他情况省略。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (XTSMGRAPHICS)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?1;4S'   # query max color registers — reply: \\x1b[?1;0;<max>S"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[?2;1S')   # current sixel pixel area\\n# reply: \\x1b[?2;0;<rows>;<cols>S"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?1;3;1024S\")   // try to RAISE color registers to 1024 (kitty allows)"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?3;1S')   // query current ReGIS area"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?2;4S\");   /* before sixel encode: ask max canvas size, scale image to fit */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "partial",
        "gnometerm": "no",
        "konsole": "partial"
      },
      "related": [
        "dcs-sixel",
        "dcs-kitty-graphics",
        "csi-da"
      ]
    },
    {
      "slug": "decsasd-decssdt",
      "family": "CSI",
      "title": {
        "en": "DECSASD / DECSSDT — Status display routing & type (CSI Ps $ } / CSI Ps $ ~)",
        "zh": "DECSASD / DECSSDT — 状态显示路由与类型（CSI Ps $ } / CSI Ps $ ~）"
      },
      "shortDesc": {
        "en": "Pick which display surface (main vs status line) receives subsequent output (DECSASD), and what the status line is for (DECSSDT) — DEC VT320's split-screen status row.",
        "zh": "选择后续输出写入哪个显示面（主屏 vs 状态行 —— DECSASD），以及状态行的用途（DECSSDT）—— DEC VT320 的分屏状态行。"
      },
      "bytes": {
        "canonical": "\\x1b[<Ps>$}   (DECSASD)   \\x1b[<Ps>$~   (DECSSDT)",
        "octal": "\\033[1$} / \\033[2$~",
        "eEscape": "\\e[1$} / \\e[2$~",
        "literal": "ESC [ Ps $ }   /   ESC [ Ps $ ~",
        "hex": "1b 5b ... 24 7d / 1b 5b ... 24 7e"
      },
      "description": {
        "en": "Two paired commands governing DEC VT320's 25th-row status line — a hardware-supported strip below the main 24-row display that holds OS status, hostname, or terminal-emulator chrome. **DECSASD** (`\\x1b[<Ps>$}`) Select Active Status Display — pick which surface subsequent writes land on. `Ps=0` selects the main display (default), `Ps=1` selects the status line. After `\\x1b[1$}`, cursor moves and writes target row 25 only; switch back with `\\x1b[0$}` to resume normal output. **DECSSDT** (`\\x1b[<Ps>$~`) Set Status Display Type — configures what the status line is for. `Ps=0` no status line (row 25 returns to main display), `Ps=1` indicator (terminal owns the row — shows online/offline, keyboard lock state), `Ps=2` host-writable (application owns the row via DECSASD — the useful mode for vim-style ruler / curses status bars). Most modern emulators don't allocate a dedicated row — they treat row 25 as just another row of the main grid, making DECSASD a near-no-op (cursor jumps to row 25 but no virtual-screen split happens) and DECSSDT essentially ignored. The functional escape sequences are still recognized for VT compatibility but provide no semantic separation. Curses captures these as `tsl` (to status line) and `fsl` (from status line) entries in modern terminfo, mapping them to `\\x1b[1$}` and `\\x1b[0$}` respectively.",
        "zh": "DEC VT320 第 25 行状态行的两个配套命令 —— 主 24 行显示下方的硬件支持窄条，用于承载 OS 状态、主机名或终端模拟器装饰。**DECSASD**（`\\x1b[<Ps>$}`）选择活动状态显示 —— 选定后续写入落在哪一面。`Ps=0` 选主显示（默认），`Ps=1` 选状态行。`\\x1b[1$}` 之后光标移动与写入仅作用于第 25 行；`\\x1b[0$}` 切回正常输出。**DECSSDT**（`\\x1b[<Ps>$~`）设置状态显示类型 —— 配置状态行的用途。`Ps=0` 无状态行（第 25 行归还主显示）、`Ps=1` 指示器（终端拥有该行 —— 显示在线 / 离线、键盘锁定）、`Ps=2` 主机可写（应用通过 DECSASD 拥有该行 —— vim 风标尺 / curses 状态栏的实用模式）。多数现代模拟器不为状态行分配单独行 —— 直接把第 25 行视为主网格的一行，使 DECSASD 几乎成为空操作（光标跳到第 25 行但不发生虚拟分屏），DECSSDT 实际被忽略。这些转义序列仍按 VT 兼容性识别但不带语义分隔。curses 在现代 terminfo 中把它们捕获为 `tsl`（to status line）与 `fsl`（from status line），分别映射到 `\\x1b[1$}` 与 `\\x1b[0$}`。"
      },
      "parameters": [
        {
          "name": "Ps (DECSASD)",
          "desc": {
            "en": "Active display: `0` main, `1` status line.",
            "zh": "活动显示：`0` 主屏、`1` 状态行。"
          }
        },
        {
          "name": "Ps (DECSSDT)",
          "desc": {
            "en": "Status display type: `0` none, `1` indicator (terminal-owned), `2` host-writable.",
            "zh": "状态显示类型：`0` 无、`1` 指示器（终端拥有）、`2` 主机可写。"
          }
        }
      ],
      "spec": "DEC VT520 RM (DECSASD / DECSSDT)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Reserve status line, write to it, return to main:\\nprintf '\\033[2$~'           # DECSSDT: host-writable status\\nprintf '\\033[1$}'           # DECSASD: target status\\nprintf 'session: alice@host'\\nprintf '\\033[0$}'           # DECSASD: back to main"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[2$~')   # enable host-writable status line"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[1$}\")   // following writes go to row 25\\nfmt.Print(\"loading...\")\\nfmt.Print(\"\\x1b[0$}\") // back to main"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[0$~')   // disable status line (return row 25 to main)"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[2$~\\x1b[1$}\");   /* enable status + select it */"
        }
      ],
      "support": {
        "xterm": "partial",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "decstbm",
        "osc-title",
        "ris-reset"
      ]
    },
    {
      "slug": "xtqmodkeys",
      "family": "CSI",
      "title": {
        "en": "XTQMODKEYS — Query modifyKeys current value (CSI ? Pp m)",
        "zh": "XTQMODKEYS — 查询 modifyKeys 当前取值（CSI ? Pp m）"
      },
      "shortDesc": {
        "en": "Ask xterm what the current modifyKeyboard / modifyCursorKeys / modifyFunctionKeys / modifyOtherKeys value is — the companion query for XTMODKEYS.",
        "zh": "向 xterm 查询当前 modifyKeyboard / modifyCursorKeys / modifyFunctionKeys / modifyOtherKeys 的取值 —— XTMODKEYS 的配套查询。"
      },
      "bytes": {
        "canonical": "\\x1b[?<Pp>m",
        "octal": "\\033[?4m",
        "eEscape": "\\e[?4m",
        "literal": "ESC [ ? Pp m",
        "hex": "1b 5b 3f ... 6d"
      },
      "description": {
        "en": "The `?` prefix on a `m` final byte flips this from SGR (private SGR sub-modes don't exist) to XTQMODKEYS, the read-side companion of XTMODKEYS (`\\x1b[><Pp>;<Pv>m`). `Pp` selects which resource to query: `0` modifyKeyboard, `1` modifyCursorKeys, `2` modifyFunctionKeys, `4` modifyOtherKeys. The reply is `\\x1b[><Pp>;<Pv>m` — the **same form** as the XTMODKEYS set command, which means the terminal effectively round-trips its setting back to the caller. This is useful for libraries that want to save the current modifyKeys state before mutating it: query → mutate → restore on exit. Most CSI u protocol consumers (kitty, ghostty) also reply correctly, but their underlying keyboard model is richer than XTMODKEYS and the reply is somewhat lossy — call `\\x1b[=u` (CSI u flags push) instead if you're already in CSI u land. The query is silent on `Pp` values the terminal doesn't understand — no reply at all, so wrap your read with a timeout (~50–100 ms is plenty on a Unix tty). XTQMODKEYS is one of the few xterm queries whose round-trip is purely a state read with no side effects, making it safe to interleave anywhere in a render loop.",
        "zh": "前缀 `?` 让末字节 `m` 从 SGR（不存在 SGR 私有子模式）切换为 XTQMODKEYS，是 XTMODKEYS（`\\x1b[><Pp>;<Pv>m`）的读取对偶。`Pp` 选择查询的资源：`0` modifyKeyboard、`1` modifyCursorKeys、`2` modifyFunctionKeys、`4` modifyOtherKeys。回复是 `\\x1b[><Pp>;<Pv>m` —— 与 XTMODKEYS 设置命令**形态相同**，相当于终端把当前设置原样回送给调用方。这对希望在变更前保存当前 modifyKeys 状态的库代码很有用：查询 → 变更 → 退出时恢复。多数 CSI u 协议消费者（kitty、ghostty）也能正确回复，但它们底层的键盘模型比 XTMODKEYS 更丰富，回复略有损 —— 已经在 CSI u 体系内的话，请改用 `\\x1b[=u`（CSI u flags push）。终端不识别的 `Pp` 取值无任何回复，所以读取需配超时（Unix tty 上 50–100 ms 足够）。XTQMODKEYS 是少数纯状态读取、无副作用的 xterm 查询之一，可安全地插入渲染循环任何位置。"
      },
      "parameters": [
        {
          "name": "Pp",
          "desc": {
            "en": "Resource selector: `0` modifyKeyboard, `1` modifyCursorKeys, `2` modifyFunctionKeys, `4` modifyOtherKeys.",
            "zh": "资源选择：`0` modifyKeyboard、`1` modifyCursorKeys、`2` modifyFunctionKeys、`4` modifyOtherKeys。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (XTQMODKEYS)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?4m'   # query modifyOtherKeys — reply: \\x1b[>4;<Pv>m\\n# read with: IFS= read -t 0.1 -rN 32 reply"
        },
        {
          "lang": "python",
          "code": "import sys, select\\nsys.stdout.write('\\x1b[?4m'); sys.stdout.flush()\\n# poll stdin: if select() ready in 100ms, parse \\x1b[>4;<Pv>m"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?2m\")   // query modifyFunctionKeys current value"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?0m')   // query modifyKeyboard\\nprocess.stdin.once('data', buf => { /* parse reply */ })"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?4m\");   /* before mutating modifyOtherKeys, snapshot the current value */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "partial",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "xtmodkeys",
        "csi-dsr",
        "decrqm"
      ]
    },
    {
      "slug": "decsdm",
      "family": "DEC",
      "title": {
        "en": "DECSDM — Sixel display mode (CSI ? 80 h / l)",
        "zh": "DECSDM — Sixel 显示模式（CSI ? 80 h / l）"
      },
      "shortDesc": {
        "en": "Choose the cursor's resting position after a sixel render — at top-left of the image (private-mode set) or below the image (reset, the modern default).",
        "zh": "选择 sixel 渲染完成后光标的停留位置 —— 图像左上角（设置）或图像下方（重置，现代默认）。"
      },
      "bytes": {
        "canonical": "\\x1b[?80h   (set)   \\x1b[?80l   (reset)",
        "octal": "\\033[?80h / \\033[?80l",
        "eEscape": "\\e[?80h / \\e[?80l",
        "literal": "ESC [ ? 80 h   /   ESC [ ? 80 l",
        "hex": "1b 5b 3f 38 30 68 / 6c"
      },
      "description": {
        "en": "Sixel Display Mode — a DEC private mode that controls cursor placement after a sixel graphics block is rendered. **Set** (`\\x1b[?80h`) selects DEC's original behaviour: the cursor returns to the top-left corner of the sixel image, overlapping the rendered pixels. **Reset** (`\\x1b[?80l`, the default in xterm and most modern emulators) moves the cursor to the cell **below** the bottom-left corner of the image — the cell where the next character would naturally land in a paragraph below the picture. The reset behaviour is what tools like `chafa`, `timg`, `image.nvim`, `imgcat` (kitty), and `viu` assume — drawing several images stacked vertically just emits them in sequence and lets the cursor advance below each. Enabling the set mode is exclusively useful when you want to overlay text on top of a sixel image (a watermark, a label) without first moving the cursor explicitly. Note: kitty's image protocol (`dcs-kitty-graphics`) uses its own cursor-advance flag (`C=0` or `C=1`), not DECSDM — DECSDM only governs DCS-P payloads (sixel). Support is uniform across sixel-capable emulators; non-sixel emulators silently ignore.",
        "zh": "Sixel Display Mode —— 控制 sixel 图形块渲染完成后光标位置的 DEC 私有模式。**设置**（`\\x1b[?80h`）选择 DEC 原始行为：光标返回 sixel 图像左上角，与渲染像素重叠。**重置**（`\\x1b[?80l`，xterm 与多数现代模拟器的默认）把光标移到图像左下角**下方**的一格 —— 即在图片下方段落里下一个字符自然落点的单元。重置行为正是 `chafa`、`timg`、`image.nvim`、`imgcat`（kitty）、`viu` 等工具假定的行为 —— 多张图像纵向堆叠只需依次输出，光标自动落到每张图的下方。仅当希望在 sixel 图像上覆盖文字（水印、标签）而不显式移动光标时，才需启用设置模式。注意：kitty 自家图像协议（`dcs-kitty-graphics`）用它自己的光标推进标志（`C=0` 或 `C=1`），与 DECSDM 无关 —— DECSDM 仅作用于 DCS-P 载荷（sixel）。支持在 sixel 兼容模拟器间一致；不支持 sixel 的模拟器静默忽略。"
      },
      "parameters": [],
      "spec": "DEC VT340 (Sixel) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Modern default — cursor lands below each image, so several stack vertically:\\nprintf '\\033[?80l'\\ncat img1.six img2.six img3.six"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[?80h')   # legacy DEC: cursor returns to image top-left\\nwith open('logo.six', 'rb') as f: sys.stdout.buffer.write(f.read())"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?80l\")   // modern: cursor advances below sixel"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?80h')   // overlay text on next render"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?80l\");   /* required before image.nvim-style stacked render */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "partial",
        "gnometerm": "no",
        "konsole": "partial"
      },
      "related": [
        "dcs-sixel",
        "dcs-kitty-graphics",
        "xtsmgraphics"
      ]
    },
    {
      "slug": "xtpushsgr-popsgr",
      "family": "CSI",
      "title": {
        "en": "XTPUSHSGR / XTPOPSGR / XTREPORTSGR — SGR stack (CSI Ps + p / + q / + r)",
        "zh": "XTPUSHSGR / XTPOPSGR / XTREPORTSGR — SGR 栈（CSI Ps + p / + q / + r）"
      },
      "shortDesc": {
        "en": "Save / restore / inspect the current SGR attributes via a stack — the SGR analogue of XTPUSHCOLORS for the palette.",
        "zh": "通过栈保存 / 恢复 / 查询当前 SGR 属性 —— XTPUSHCOLORS 在调色板栈外，对 SGR 属性的对应方案。"
      },
      "bytes": {
        "canonical": "\\x1b[#{   (XTPUSHSGR, alt: CSI Pm + p)   \\x1b[#}   (XTPOPSGR, alt: CSI + q)   \\x1b[+r   (XTREPORTSGR)",
        "octal": "\\033[#{ / \\033[#}",
        "eEscape": "\\e[#{ / \\e[#}",
        "literal": "ESC [ Pm + p   /   ESC [ + q   /   ESC [ + r",
        "hex": "1b 5b ... 2b 70 / 2b 71 / 2b 72"
      },
      "description": {
        "en": "Three xterm extensions for stacking SGR (Select Graphic Rendition) state — bold / italic / underline / fg-color / bg-color / blink / strike / reverse, the full set tracked by `sgr-reset`. **XTPUSHSGR** has two equivalent forms: short `\\x1b[#{` saves the entire current SGR snapshot, or long `\\x1b[<Pm>+p` saves only the named attribute(s) in `Pm` (`1` bold, `3` italic, `4` underline, `5` blink, `7` reverse, `9` strike, `30-37`/`40-47`/`38`/`48` colors). **XTPOPSGR** (`\\x1b[#}` short, `\\x1b[+q` long) restores the top stack entry — emitted SGR attributes are the difference between current and saved state, applied automatically. **XTREPORTSGR** (`\\x1b[+r`) returns the stack depth as a reply `\\x1b[<depth>+r`. The two-byte intermediate `#{` and `#}` short forms exist because they're shorter than the long form and parser-friendlier (no parameters to parse). Useful for libraries / TUI primitives that locally mutate SGR (e.g. dim every line except the focused one) without losing the parent context: push → mutate → render → pop. Note that xterm SGR stack and color-palette stack (`xtpushcolors-popcolors`) are SEPARATE stacks — pushing one doesn't push the other. Support is xterm-only; kitty / wezterm / ghostty silently ignore (kitty's CSI u keyboard protocol coincidentally uses `+` as an intermediate but has a different meaning).",
        "zh": "三个 xterm 扩展，用于堆叠 SGR（Select Graphic Rendition）状态 —— 加粗 / 斜体 / 下划线 / 前景色 / 背景色 / 闪烁 / 删除线 / 反相，即 `sgr-reset` 跟踪的全集。**XTPUSHSGR** 有两种等价形式：短形 `\\x1b[#{` 保存当前 SGR 全量快照；长形 `\\x1b[<Pm>+p` 仅保存 `Pm` 列出的属性（`1` 加粗、`3` 斜体、`4` 下划线、`5` 闪烁、`7` 反相、`9` 删除线、`30-37` / `40-47` / `38` / `48` 颜色）。**XTPOPSGR**（短 `\\x1b[#}`，长 `\\x1b[+q`）恢复栈顶 —— 实际发出的 SGR 属性为当前与保存状态之差，自动应用。**XTREPORTSGR**（`\\x1b[+r`）以 `\\x1b[<depth>+r` 形式回复栈深度。`#{` 与 `#}` 的双字节中间序列存在是因为它们比长形短且对解析器更友好（无参数）。适合在不丢失父上下文的前提下临时局部修改 SGR 的库 / TUI 原语（例如「焦点行外全部减淡」）：压入 → 修改 → 渲染 → 弹出。注意 xterm 的 SGR 栈与调色板栈（`xtpushcolors-popcolors`）是**分离的** —— 压入一个不压入另一个。仅 xterm 支持；kitty / wezterm / ghostty 静默忽略（kitty 的 CSI u 键盘协议碰巧也用 `+` 作中间字节但语义不同）。"
      },
      "parameters": [
        {
          "name": "Pm",
          "desc": {
            "en": "Optional list of SGR attribute codes to save (long-form push only). Omitted = save all current SGR state.",
            "zh": "可选的 SGR 属性编码列表（仅长形压入）。省略 = 保存当前全部 SGR 状态。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (XTPUSHSGR / XTPOPSGR / XTREPORTSGR)",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[1;31m'   # bold red\\nprintf '\\033[#{'      # push current SGR\\nprintf '\\033[0;34mlinkified word\\033[#}'   # mutate, render, pop → bold red restored\\necho ' continues bold red'"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[#{')   # save all SGR\\nsys.stdout.write('\\x1b[2;33mdim yellow status')\\nsys.stdout.write('\\x1b[#}')   # restore parent SGR"
        },
        {
          "lang": "go",
          "code": "// Save only foreground color (long form):\\nfmt.Print(\"\\x1b[38+p\")   // push fg\\nfmt.Print(\"\\x1b[31malert\\x1b[+q\")   // pop restores fg"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[+r')   // query stack depth — reply: \\x1b[<n>+r"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[#{\");   /* push */\\nprintf(\"\\x1b[7m local highlight \\x1b[#}\");  /* pop restores */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "sgr-reset",
        "xtpushcolors-popcolors",
        "sgr-bold",
        "sgr-fg-basic"
      ]
    },
    {
      "slug": "deckpam-deckpnm",
      "family": "ESC",
      "title": {
        "en": "DECKPAM / DECKPNM — Keypad application / numeric mode (ESC = / ESC >)",
        "zh": "DECKPAM / DECKPNM — 小键盘应用 / 数字模式（ESC = / ESC >）"
      },
      "shortDesc": {
        "en": "Switch the numeric keypad between sending application escape sequences (\\eOM / \\eOj …) and plain ASCII digits — the foundation of vim / less / readline keypad behaviour.",
        "zh": "在数字小键盘发送应用转义序列（\\eOM / \\eOj …）与发送 ASCII 数字之间切换 —— vim / less / readline 小键盘行为的基础。"
      },
      "bytes": {
        "canonical": "\\x1b=   (DECKPAM)   \\x1b>   (DECKPNM)",
        "octal": "\\033= / \\033>",
        "eEscape": "\\e= / \\e>",
        "literal": "ESC =   /   ESC >",
        "hex": "1b 3d / 1b 3e"
      },
      "description": {
        "en": "Two **C1-class** escape sequences (no CSI, no parameter — just `ESC` followed by a single final byte) that flip the numeric keypad's input encoding. **DECKPAM** (`\\x1b=`) enables Application Keypad Mode — the numeric keys 0-9 and operators `+`, `-`, `*`, `/`, `.`, Enter, etc. each send an SS3-prefixed sequence (`\\x1bOq` for 1, `\\x1bOM` for Enter, `\\x1bOk` for `+`, …) instead of the literal ASCII byte. Curses programs that want to distinguish numeric-pad `5` from main-keyboard `5` enable this on startup. **DECKPNM** (`\\x1b>`) reverses — the numeric keypad emits the plain ASCII bytes `0`-`9` and `+-*/.\\n`, indistinguishable from the main keyboard. Curses `keypad(stdscr, TRUE)` translates to `\\x1b=` on entry and `\\x1b>` on exit; vim emits the pair around its main loop; less / man pages emit them around their reader UI. **Important**: cursor-pad keys (arrows, Home, End, PgUp, PgDn) are governed by a SEPARATE mode — DECCKM (`\\x1b[?1h/l`), not DECKPAM — so enabling DECKPAM does NOT change arrow-key encoding. Confusingly named together by the manuals, but they are independent settings. Both sequences are 2-byte (ESC + final byte) which makes them parser-cheap; emit them around any TUI that needs distinct numpad input.",
        "zh": "两个 **C1 级**转义序列（无 CSI、无参数 —— 仅 `ESC` 后跟一个末字节），切换数字小键盘的输入编码。**DECKPAM**（`\\x1b=`）启用应用小键盘模式 —— 数字键 0-9 与运算符 `+`、`-`、`*`、`/`、`.`、Enter 等各发送 SS3 前缀的序列（`\\x1bOq` 表示 1、`\\x1bOM` 表示 Enter、`\\x1bOk` 表示 `+` 等），而非字面 ASCII 字节。需要区分小键盘 `5` 与主键盘 `5` 的 curses 程序在启动时启用。**DECKPNM**（`\\x1b>`）反向 —— 数字小键盘发送普通 ASCII 字节 `0`-`9` 与 `+-*/.\\n`，与主键盘无差。curses 的 `keypad(stdscr, TRUE)` 进入时映射为 `\\x1b=`，退出时为 `\\x1b>`；vim 在主循环外发这一对；less / man 阅读器界面也类似。**注意**：方向键 / 编辑键（箭头、Home、End、PgUp、PgDn）由**另一个**模式控制 —— DECCKM（`\\x1b[?1h/l`），与 DECKPAM 无关 —— 因此启用 DECKPAM **不会**改变方向键编码。两者常被一同提及，但实际是独立设置。两个序列都是 2 字节（ESC + 末字节），解析极廉价；任何需要区分小键盘输入的 TUI 都可以在进出循环时发送。"
      },
      "parameters": [],
      "spec": "DEC VT100 (DECKPAM / DECKPNM) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Enable app keypad — read what numpad-Enter sends now:\\nprintf '\\033='\\nread -rsn 3 key   # captures \\x1bOM instead of \\n\\nprintf '\\033>'   # always restore on exit"
        },
        {
          "lang": "python",
          "code": "import sys, termios, tty\\nsys.stdout.write('\\x1b=')   # app keypad on\\n# … TUI loop with raw stdin …\\nsys.stdout.write('\\x1b>')   # normal keypad on exit"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b=\")   // DECKPAM: numpad sends SS3 sequences\\ndefer fmt.Print(\"\\x1b>\")   // DECKPNM: restore"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b=')   // app keypad\\nprocess.on('exit', () => process.stdout.write('\\x1b>'))"
        },
        {
          "lang": "c",
          "code": "fputs(\"\\x1b=\", stdout);   /* enter app keypad — pair with atexit handler emitting \\x1b> */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "dec-bracketed-paste",
        "dec-focus-events",
        "alt-screen",
        "xtmodkeys"
      ]
    },
    {
      "slug": "decscnm",
      "family": "DEC",
      "title": {
        "en": "DECSCNM — Reverse video screen mode (CSI ? 5 h / l)",
        "zh": "DECSCNM — 反向视频屏幕模式（CSI ? 5 h / l）"
      },
      "shortDesc": {
        "en": "Globally swap foreground and background colours for the entire screen — the screen-wide reverse-video toggle, distinct from per-cell SGR 7.",
        "zh": "在整屏范围内全局交换前景色与背景色 —— 全屏的反向视频开关，与逐格 SGR 7 不同。"
      },
      "bytes": {
        "canonical": "\\x1b[?5h   (reverse)   \\x1b[?5l   (normal)",
        "octal": "\\033[?5h / \\033[?5l",
        "eEscape": "\\e[?5h / \\e[?5l",
        "literal": "ESC [ ? 5 h   /   ESC [ ? 5 l",
        "hex": "1b 5b 3f 35 68 / 6c"
      },
      "description": {
        "en": "Screen Mode (Reverse). When set (`\\x1b[?5h`), the terminal renders the entire screen with foreground and background colours swapped — every cell appears as `bg-on-fg` instead of `fg-on-bg`, including cells with explicit SGR colours (their fg/bg are individually swapped). Reset (`\\x1b[?5l`, the default) returns to normal. This is **distinct from SGR 7** (per-cell reverse video, slug `sgr-reverse`): SGR 7 toggles a single cell's flag, DECSCNM toggles the entire rendering buffer. Use cases: accessibility (some users with photosensitivity prefer light-on-dark and toggle this on a global keybind), demonstration / debugging (flash the whole screen to highlight a state change), retro emulators (DEC VT100s shipped with this exposed as a hardware switch). Implementation note: kitty / alacritty / wezterm / ghostty implement it; some respect it only for the default background pair (cells with explicit colours stay un-swapped, breaking the semantic). Persists until reset, or until DECSTR (soft reset, restores to default) or RIS (hard reset). Don't confuse with the dark-mode / light-mode preference exchange via OSC 11 — OSC 11 changes the default background colour itself, DECSCNM swaps everything visible.",
        "zh": "屏幕模式（反向）。设置（`\\x1b[?5h`）时，终端以前 / 后景色互换的方式渲染整屏 —— 每个单元显示为 `bg-on-fg`，包括显式带 SGR 颜色的单元（其前 / 后景分别交换）。重置（`\\x1b[?5l`，默认）恢复正常。**与 SGR 7 不同**（逐格反向视频，slug `sgr-reverse`）：SGR 7 切换单格标志，DECSCNM 切换整渲染缓冲区。用途：无障碍（部分对强光敏感用户偏好亮底暗字，并配全局快捷键切换）、演示 / 调试（整屏闪烁以突出状态变化）、复古模拟器（DEC VT100 把该开关做成硬件开关）。实现注意：kitty / alacritty / wezterm / ghostty 实现该模式；部分仅尊重默认前后景对（显式带颜色的单元不交换，破坏语义）。持续到重置，或 DECSTR（软复位回到默认）或 RIS（硬复位）。不要与 OSC 11 的亮 / 暗模式偏好交换混淆 —— OSC 11 改变默认背景色本身，DECSCNM 是把已可见的一切交换。"
      },
      "parameters": [],
      "spec": "DEC VT100 (DECSCNM) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?5h'   # global reverse video\\nsleep 1\\nprintf '\\033[?5l'   # back to normal"
        },
        {
          "lang": "python",
          "code": "import sys, time\\nsys.stdout.write('\\x1b[?5h'); sys.stdout.flush()\\ntime.sleep(0.1)            # 100ms flash for state change\\nsys.stdout.write('\\x1b[?5l')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?5h\")   // reverse on\\ndefer fmt.Print(\"\\x1b[?5l\")   // always reset on exit"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?5h')   // honour user's accessibility-flash preference"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?5h\");   /* whole screen reverse */\\nprintf(\"\\x1b[?5l\");   /* back to normal */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-reverse",
        "osc-set-fg-bg",
        "decstr-soft-reset",
        "ris-reset"
      ]
    },
    {
      "slug": "decsclm",
      "family": "DEC",
      "title": {
        "en": "DECSCLM — Smooth scrolling mode (CSI ? 4 h / l)",
        "zh": "DECSCLM — 平滑滚动模式（CSI ? 4 h / l）"
      },
      "shortDesc": {
        "en": "Toggle between smooth (one-line-per-frame animated) and jump (instant) scrolling — a DEC VT100 hardware-era setting that modern emulators almost universally ignore.",
        "zh": "在平滑（逐帧一行的动画）与跳跃（瞬时）滚动间切换 —— DEC VT100 硬件时代的设置，现代模拟器几乎全部忽略。"
      },
      "bytes": {
        "canonical": "\\x1b[?4h   (smooth)   \\x1b[?4l   (jump)",
        "octal": "\\033[?4h / \\033[?4l",
        "eEscape": "\\e[?4h / \\e[?4l",
        "literal": "ESC [ ? 4 h   /   ESC [ ? 4 l",
        "hex": "1b 5b 3f 34 68 / 6c"
      },
      "description": {
        "en": "Set Scrolling Mode. When set (`\\x1b[?4h`), the terminal animates scrolling — when content needs to scroll up by one line, the entire display pixel-shifts smoothly upward over several frames rather than jumping in a single update. Reset (`\\x1b[?4l`, the default) is jump scrolling — instant single-frame update. The DEC VT100 hardware had a physical refresh-rate constraint that made smooth scrolling visibly slower (~6 lines per second), so cooperative software either left it off for terminals or enabled it temporarily during `cat`-like display of files where readability mattered more than throughput. In modern software emulators the distinction is functionally moot — frame rates are too high for `?4h` to look meaningfully different from `?4l`, and emulators either implement smooth scrolling as a tiny animation (`gnometerm`, `iterm2`) or silently ignore the mode (`alacritty`, `kitty`, `wezterm`, `ghostty`, `Windows Terminal`). Useful primarily for historical accuracy in VT100 emulators (xterm, mlterm) and for distinguishing TUI behaviour in tests. Note: smooth scrolling reduces effective throughput when implemented — disable it before bulk-printing logs.",
        "zh": "设置滚动模式。设置（`\\x1b[?4h`）时，终端为滚动加动画 —— 内容需要向上滚动一行时，整屏像素在数帧内平滑上移，而非单次更新跳变。重置（`\\x1b[?4l`，默认）是跳跃滚动 —— 单帧瞬时更新。DEC VT100 硬件有物理刷新率限制，使得平滑滚动可见地变慢（约每秒 6 行），合作型软件因此在终端上默认关闭，仅在 `cat` 之类强调可读性的文件显示时临时启用。在现代软件模拟器中差别基本失效 —— 帧率过高使 `?4h` 与 `?4l` 视觉差异微乎其微，模拟器要么以微动画形式实现（`gnometerm`、`iterm2`），要么静默忽略（`alacritty`、`kitty`、`wezterm`、`ghostty`、`Windows Terminal`）。主要用于 VT100 模拟器（xterm、mlterm）的历史准确性以及测试中区分 TUI 行为。注意：实现了平滑滚动时会降低有效吞吐 —— 批量打印日志前请关闭。"
      },
      "parameters": [],
      "spec": "DEC VT100 (DECSCLM) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?4h'   # smooth scroll on (visible on xterm, gnome-terminal)\\nfor i in $(seq 1 80); do echo \"line $i\"; done\\nprintf '\\033[?4l'"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[?4l')   # disable smooth scrolling before bulk log dump"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?4h\")   // smooth on (will be no-op on most modern emulators)"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?4l')   // jump scrolling (default; explicit reset)"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?4l\");   /* ensure jump-scroll before printing 10k log lines */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "scroll-up-down",
        "decstbm",
        "decstr-soft-reset"
      ]
    },
    {
      "slug": "decarm",
      "family": "DEC",
      "title": {
        "en": "DECARM — Auto-repeat keys mode (CSI ? 8 h / l)",
        "zh": "DECARM — 按键自动重复模式（CSI ? 8 h / l）"
      },
      "shortDesc": {
        "en": "Toggle whether the terminal repeats key bytes while a key is held down — a TUI-relevant knob for games and editors where holding `j` should NOT spam the buffer.",
        "zh": "切换终端在按住按键时是否重复发送字节 —— 对游戏与编辑器很重要，按住 `j` 不应狂刷缓冲。"
      },
      "bytes": {
        "canonical": "\\x1b[?8h   (repeat)   \\x1b[?8l   (no repeat)",
        "octal": "\\033[?8h / \\033[?8l",
        "eEscape": "\\e[?8h / \\e[?8l",
        "literal": "ESC [ ? 8 h   /   ESC [ ? 8 l",
        "hex": "1b 5b 3f 38 68 / 6c"
      },
      "description": {
        "en": "Auto-Repeat Mode. When set (`\\x1b[?8h`, the default in nearly every terminal), holding down a key after the OS-defined repeat delay (typically 250 ms) causes the terminal to inject repeated key bytes at the OS-defined repeat rate (typically 30/sec) — the standard typewriter-style behaviour. When reset (`\\x1b[?8l`), the terminal sends exactly one byte per physical keypress regardless of how long the key is held — so a roguelike that interprets `j` as 'move down once' won't see the player skipping across the map when they hold the key. The OS-defined delay/rate isn't tunable via DECARM (use `xset r rate` on X11, `defaults write -g KeyRepeat` on macOS, accessibility panel on Windows); DECARM only flips on/off. Critical for TUI games (curses-based roguelikes like nethack, brogue), action editors that interpret modal-style single-keystroke commands, and applications that want every keystroke debounced into a discrete event. Almost-universal support — only Linux console partial (depends on framebuffer driver). Restore to `?8h` on exit, always — leaving auto-repeat off pollutes the user's shell session.",
        "zh": "Auto-Repeat 模式。设置（`\\x1b[?8h`，几乎所有终端的默认）时，按键超过 OS 定义的延迟（典型 250 ms）后保持按下会让终端按 OS 定义的速率（典型每秒 30 次）注入重复字节 —— 即标准打字机风格行为。重置（`\\x1b[?8l`）时，无论按键保持多久，每次物理按键都只发一个字节 —— 这样把 `j` 解作「下移一格」的 roguelike 在玩家按住按键时不会跨地图狂奔。OS 延迟 / 速率不能通过 DECARM 调整（X11 用 `xset r rate`、macOS 用 `defaults write -g KeyRepeat`、Windows 用辅助功能面板）；DECARM 只切开 / 关。对 TUI 游戏（基于 curses 的 roguelike 如 nethack、brogue）、解释单键命令的模式化编辑器、以及希望每次击键都防抖为离散事件的应用至关重要。支持几乎一致 —— 仅 Linux console 偏 partial（取决于 framebuffer 驱动）。退出时务必恢复 `?8h` —— 关着 auto-repeat 退出会污染用户 shell 会话。"
      },
      "parameters": [],
      "spec": "DEC VT100 (DECARM) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033[?8l'   # turn OFF auto-repeat for the duration of this TUI\\ntrap 'printf \"\\\\033[?8h\"' EXIT   # restore on any exit\\n# … game loop …"
        },
        {
          "lang": "python",
          "code": "import sys, atexit\\nsys.stdout.write('\\x1b[?8l')   # roguelike: one move per keypress\\natexit.register(lambda: sys.stdout.write('\\x1b[?8h'))"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?8l\")\\ndefer fmt.Print(\"\\x1b[?8h\")   // always restore"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?8l')\\nprocess.on('exit', () => process.stdout.write('\\x1b[?8h'))"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?8l\");\\natexit_set_restore(\"\\x1b[?8h\");   /* paired restore is non-optional */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "xtmodkeys",
        "deckpam-deckpnm",
        "dec-bracketed-paste",
        "decstr-soft-reset"
      ]
    },
    {
      "slug": "decscpp",
      "family": "CSI",
      "title": {
        "en": "DECSCPP — Select columns per page (CSI Pn $ |)",
        "zh": "DECSCPP — 选择每页列数（CSI Pn $ |）"
      },
      "shortDesc": {
        "en": "Resize the active page to 80 or 132 columns — the data-side request that DECCOLM expresses as a private mode toggle.",
        "zh": "把活动页面调整为 80 或 132 列 —— DECCOLM 用私有模式表达的同一行为，DECSCPP 是其参数化等价物。"
      },
      "bytes": {
        "canonical": "\\x1b[80$|   (80 cols)   \\x1b[132$|   (132 cols)",
        "octal": "\\033[80$| / \\033[132$|",
        "eEscape": "\\e[80$| / \\e[132$|",
        "literal": "ESC [ Pn $ |",
        "hex": "1b 5b 38 30 24 7c / 1b 5b 31 33 32 24 7c"
      },
      "description": {
        "en": "Set Columns Per Page. DEC VT400 / VT520 sequence with intermediate byte `$` (0x24) and final `|` (0x7c). `Pn=80` (or omitted) requests 80-column mode; `Pn=132` requests 132-column mode. Any other value is silently ignored. **DECSCPP is the parameterised cousin of DECCOLM** (`\\x1b[?3h/l`, slug `deccolm`): both ultimately ask the terminal to change page width, but DECCOLM is a fixed two-state toggle while DECSCPP carries an explicit column count. The two share these implementation-defined side effects:\n\n- The screen is **cleared** (filled with spaces using the current SGR background).\n- The cursor is **homed** to row 1 / column 1.\n- Scrolling region (DECSTBM) and horizontal margins (DECSLRM) are **reset** to full-page.\n\nThese side effects are the historical reason `resize`-aware programs send DECCOLM/DECSCPP only at terminal-init time and never inside a TUI render loop — flipping width nukes the visible buffer. Modern emulators almost universally honour DECSCPP only when DECCOLM is also enabled at config time (xterm's `allowC132` / `c132` resources, gnome-terminal's allowAlternateScreen). When disabled, the sequence is silent-ignored — the same conservative posture as DECCOLM. The intermediate-byte trap: `CSI Pn |` (no `$`) is **DECTABSR / DECTSR depending on context**, not DECSCPP — the `$` distinguishes the column-set sequence from the tab-stop / status-report family.",
        "zh": "Set Columns Per Page。DEC VT400 / VT520 序列，中间字节 `$`（0x24），末字节 `|`（0x7c）。`Pn=80`（或省略）请求 80 列模式；`Pn=132` 请求 132 列模式；其他值静默忽略。**DECSCPP 是 DECCOLM 的参数化版本**（`\\x1b[?3h/l`，slug `deccolm`）：两者最终都让终端改变页宽，但 DECCOLM 是固定的二态开关，DECSCPP 显式携带列数。两者共享以下实现定义的副作用：\n\n- 屏幕被**清空**（以当前 SGR 背景填充空格）。\n- 光标**归位**到第 1 行 / 第 1 列。\n- 滚动区域（DECSTBM）与水平边距（DECSLRM）**重置**为整页。\n\n这些副作用正是历史上感知 `resize` 的程序仅在终端初始化时发送 DECCOLM / DECSCPP、绝不在 TUI 渲染循环中触发的原因 —— 翻转列宽会清空可见缓冲。现代模拟器几乎一致：仅当配置时启用 DECCOLM（xterm 的 `allowC132` / `c132` 资源、gnome-terminal 的 allowAlternateScreen）时才尊重 DECSCPP；禁用时静默忽略 —— 与 DECCOLM 同样保守的姿态。中间字节陷阱：`CSI Pn |`（无 `$`）按上下文是 **DECTABSR / DECTSR**，不是 DECSCPP —— `$` 字节才把列数设置序列与制表 / 状态报告族区分开。"
      },
      "parameters": [
        {
          "name": "Pn",
          "desc": {
            "en": "Column count. `80` (or omitted) selects 80-column mode; `132` selects 132-column mode. Other values are ignored.",
            "zh": "列数。`80`（或省略）选择 80 列模式；`132` 选择 132 列模式；其他值被忽略。"
          }
        }
      ],
      "spec": "DEC VT400 (DECSCPP) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Request 132-column wide mode for a log dump:\\nprintf '\\033[132$|'   # screen clears, cursor homes\\ncat very-wide-output.log\\nprintf '\\033[80$|'    # restore 80-col on exit"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b[132$|')   # widen\\ntry:\\n    render_wide_table()\\nfinally:\\n    sys.stdout.write('\\x1b[80$|')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[132$|\")   // wide\\ndefer fmt.Print(\"\\x1b[80$|\")   // narrow back"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[132$|')\\nprocess.on('exit', () => process.stdout.write('\\x1b[80$|'))"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[132$|\");   /* 132 cols — clears screen, homes cursor */\\nprintf(\"\\x1b[80$|\");    /* back to 80 */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "deccolm",
        "decstbm",
        "decslrm",
        "decstr-soft-reset",
        "ris-reset"
      ]
    },
    {
      "slug": "deccolm",
      "family": "DEC",
      "title": {
        "en": "DECCOLM — 80 / 132 column mode (CSI ? 3 h / l)",
        "zh": "DECCOLM — 80 / 132 列模式（CSI ? 3 h / l）"
      },
      "shortDesc": {
        "en": "Toggle between 80 and 132 column page width — DEC VT100's flagship 'wide mode' switch, gated by an opt-in resource on every modern emulator.",
        "zh": "在 80 列与 132 列页宽间切换 —— DEC VT100 旗舰「宽模式」开关，现代模拟器普遍以资源开关默认禁用。"
      },
      "bytes": {
        "canonical": "\\x1b[?3h   (132 cols)   \\x1b[?3l   (80 cols)",
        "octal": "\\033[?3h / \\033[?3l",
        "eEscape": "\\e[?3h / \\e[?3l",
        "literal": "ESC [ ? 3 h   /   ESC [ ? 3 l",
        "hex": "1b 5b 3f 33 68 / 6c"
      },
      "description": {
        "en": "Column Mode (DECCOLM, private mode 3). Set (`\\x1b[?3h`) requests 132-column page width; reset (`\\x1b[?3l`, the typical default) returns to 80 columns. Originally a hardware feature of the DEC VT100 — flipping this triggered a real font / clock-rate switch that physically narrowed each character cell so 132 glyphs fit on the same CRT. Software emulators implement it by resizing the page buffer; the side effects are the same as DECSCPP and intentional:\n\n- **Screen cleared** to current SGR background.\n- **Cursor homed** to (1, 1).\n- **DECSTBM and DECSLRM reset** to full-page.\n- Any pending **DECOM** (origin mode) state preserved but margins re-anchored.\n\nWhy the resource gate? In the X11 / VT100 era, applications would emit `?3h` programmatically to gain wide-display real estate, surprising the user by clearing their buffer. Modern emulators (xterm `allowC132`, putty `disable_remote_resize`, others by default) suppress DECCOLM unless explicitly opted in. Result: a program that ships `?3h` today gets silent no-ops on alacritty / kitty / wezterm / ghostty / Windows Terminal — the safe assumption is that DECCOLM does nothing unless you've already verified it works in the target environment. Use DECCOLM (or its parameter-bearing cousin DECSCPP) only when you control the terminal config; otherwise emit a `resize`-style request through your platform's window-management protocol (e.g. ioctl `TIOCSWINSZ`). DECCOLM **persists** until reset or until DECSTR (soft reset returns it to default) or RIS (hard reset).",
        "zh": "Column Mode（DECCOLM，私有模式 3）。设置（`\\x1b[?3h`）请求 132 列页宽；重置（`\\x1b[?3l`，多数默认）回到 80 列。最初是 DEC VT100 的硬件特性 —— 切换该模式触发真实的字体 / 时钟切换，物理缩小每个字符单元以在同一 CRT 上容纳 132 个字形。软件模拟器以重设页面缓冲实现；副作用与 DECSCPP 相同且属设计意图：\n\n- 屏幕**清空**为当前 SGR 背景色。\n- 光标**归位**到（1, 1）。\n- **DECSTBM 与 DECSLRM 重置**为整页。\n- 任何挂起的 **DECOM**（原点模式）状态保留，但边距重新锚定。\n\n为何要资源门控？在 X11 / VT100 时代，应用会程序化地发 `?3h` 获得宽屏空间，意外清空用户缓冲。现代模拟器（xterm `allowC132`、putty `disable_remote_resize` 等）默认抑制 DECCOLM，除非显式启用。结果：今天的程序发送 `?3h` 在 alacritty / kitty / wezterm / ghostty / Windows Terminal 上得到的多是静默 no-op —— 安全假设是 DECCOLM 啥都不做，除非你已在目标环境验证。仅在掌控终端配置时使用 DECCOLM（或其参数化兄弟 DECSCPP）；否则通过平台窗口管理协议（如 ioctl `TIOCSWINSZ`）发送 `resize` 请求。DECCOLM **持续生效**直至重置、DECSTR（软复位回到默认）或 RIS（硬复位）。"
      },
      "parameters": [],
      "spec": "DEC VT100 (DECCOLM) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Probe and request 132-col, fall back gracefully:\\nprintf '\\033[?3h'   # request wide\\nprintf '\\033[6n'    # cursor position report\\nIFS='[;R' read -t 0.05 -rsd R _ rows cols < /dev/tty || true\\nif [ \"$cols\" -lt 100 ]; then echo \"emulator ignored DECCOLM\"; fi"
        },
        {
          "lang": "python",
          "code": "import sys, os\\nsys.stdout.write('\\x1b[?3h')   # ask for 132\\nsys.stdout.flush()\\nrows, cols = os.get_terminal_size()\\nif cols < 100:\\n    print('DECCOLM not honoured — staying narrow')"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b[?3h\")\\ndefer fmt.Print(\"\\x1b[?3l\")   // always restore — clears screen on transition"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b[?3l')   // explicit 80-col (default; harmless on emulators that ignore DECCOLM)"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b[?3h\");   /* request 132 cols */\\n/* WARNING: screen now cleared. Re-render entire UI. */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "decscpp",
        "decstbm",
        "decslrm",
        "decstr-soft-reset",
        "ris-reset"
      ]
    },
    {
      "slug": "decdhl-decdwl-decswl",
      "family": "ESC",
      "title": {
        "en": "DECDHL / DECDWL / DECSWL — Double-height / double-width lines (ESC # 3 / # 4 / # 5 / # 6)",
        "zh": "DECDHL / DECDWL / DECSWL — 双倍高 / 双倍宽行（ESC # 3 / # 4 / # 5 / # 6）"
      },
      "shortDesc": {
        "en": "Mark the current line as double-height (top or bottom half) or double-width / single-height — DEC's per-line big-banner primitives, used by VT100 splash screens.",
        "zh": "把当前行标记为双倍高（上半 / 下半）或双倍宽 / 单倍高 —— DEC 的逐行大横幅原语，VT100 启动画面常用。"
      },
      "bytes": {
        "canonical": "\\x1b#3 (DHL top)   \\x1b#4 (DHL bottom)   \\x1b#5 (DECSWL)   \\x1b#6 (DECDWL)",
        "octal": "\\033#3 / \\033#4 / \\033#5 / \\033#6",
        "eEscape": "\\e#3 / \\e#4 / \\e#5 / \\e#6",
        "literal": "ESC # 3   /   ESC # 4   /   ESC # 5   /   ESC # 6",
        "hex": "1b 23 33 / 1b 23 34 / 1b 23 35 / 1b 23 36"
      },
      "description": {
        "en": "Four **C1-class** escape sequences with intermediate byte `#` (0x23) and a digit final byte (`3`/`4`/`5`/`6`). No CSI, no parameter — just `ESC # n`. Each affects the **current line** (where the cursor sits) and **persists** until overwritten by another `ESC # n` on that line, scrolled out, or cleared.\n\n- **`ESC # 3` — DECDHL top half**: render this line at double height, displaying the top half of each glyph (so the visible row is twice as tall as a normal row, occupying its own grid row).\n- **`ESC # 4` — DECDHL bottom half**: same line content as the `# 3` line above it, but rendering the **bottom half** of the doubled glyphs. The convention is to write the same string on two consecutive lines and mark the first `# 3` and the second `# 4` — the terminal stitches them into one double-height word.\n- **`ESC # 5` — DECSWL**: Single-Width Line — the default. Use this to explicitly clear a previous `# 6` / `# 3` / `# 4` from the current line.\n- **`ESC # 6` — DECDWL**: Double-Width Line — each glyph occupies two cell-widths. The line is the same height as a normal row but half as many glyphs fit. Glyphs past the new visible width are clipped (not wrapped).\n\nWhy four sequences and not two? The double-height pair (`# 3` + `# 4`) requires the **same text** on two adjacent rows because the display engine renders the top half from the upper line and the bottom half from the lower line — each line still occupies one grid row, so cursor positioning, scroll math, and erase still work on a one-row-per-byte basis. Double-width (`# 6`) doesn't need a partner because it doubles only horizontally. Modern emulators that implement these (xterm, mlterm, urxvt, gnome-terminal partial, konsole partial) honour them visually; alacritty / kitty / wezterm / ghostty silent-ignore — they're considered a legacy aesthetic feature with no path forward in graphical-output-rich emulators. Use case today: nostalgia / retrocomputing demos, DECALN-paired alignment tests (`ESC # 8`, slug `decaln`), and faithful VT100 ROM emulators. Cursor behaviour: when entering a double-width line, the cursor's logical column 1-40 maps to visual column 1-80; a write past visual column 80 (logical 41) is clipped or wraps depending on DECAWM.",
        "zh": "四个 **C1 级**转义序列，中间字节 `#`（0x23），末字节为数字（`3`/`4`/`5`/`6`）。无 CSI、无参数 —— 仅 `ESC # n`。每个影响**当前行**（光标所在行），并**持续**直到该行被另一个 `ESC # n` 覆写、滚出屏幕或被清除。\n\n- **`ESC # 3` — DECDHL 上半**：将本行渲染为双倍高，显示每个字形的**上半部分**（可见行高度是普通行的两倍，但仍占用一个网格行）。\n- **`ESC # 4` — DECDHL 下半**：与上方 `# 3` 行写相同内容，但渲染双倍字形的**下半部分**。约定是在连续两行写相同字符串，第一行标 `# 3`、第二行标 `# 4` —— 终端把它们拼成一个双倍高的字。\n- **`ESC # 5` — DECSWL**：单倍宽行（默认）。用于显式清除当前行上之前的 `# 6` / `# 3` / `# 4`。\n- **`ESC # 6` — DECDWL**：双倍宽行 —— 每个字形占两个单元宽度。行高与普通行一致，但容纳的字形数减半。超出新可见宽度的字形被裁剪（不换行）。\n\n为何四个而非两个？双倍高对（`# 3` + `# 4`）需要**相同文本**在相邻两行，因为渲染引擎从上行取上半、下行取下半 —— 每行仍占一个网格行，光标定位、滚动计算、擦除仍按「一字节一行」基础工作。双倍宽（`# 6`）无须搭档因为仅水平翻倍。实现这些序列的现代模拟器（xterm、mlterm、urxvt，gnome-terminal 与 konsole 部分实现）视觉上尊重它们；alacritty / kitty / wezterm / ghostty 静默忽略 —— 被视为图形化模拟器中无前路的遗留美学特性。今日用途：怀旧 / 复古计算演示、与 DECALN 配对的对齐测试（`ESC # 8`，slug `decaln`）、忠实的 VT100 ROM 模拟器。光标行为：进入双倍宽行时，光标的逻辑列 1-40 映射到视觉列 1-80；写入超过视觉列 80（逻辑 41）按 DECAWM 决定裁剪或换行。"
      },
      "parameters": [],
      "spec": "DEC VT100 (DECDHL / DECDWL / DECSWL) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Banner-style double-height header:\\nclear\\nprintf '\\033#3WELCOME\\n'   # top half\\nprintf '\\033#4WELCOME\\n'   # bottom half — same text, completes the doubled glyph"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\x1b#6BIG\\n')   # double-width single-height\\nsys.stdout.write('\\x1b#5normal again\\n')   # explicit single-width"
        },
        {
          "lang": "go",
          "code": "// Construct a 2-line splash header:\\nfor _, half := range []string{\"\\x1b#3\", \"\\x1b#4\"} {\\n    fmt.Print(half + \"ANSICODE\\n\")\\n}"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b#6Wide Title\\n')   // double-width\\nprocess.stdout.write('\\x1b#5')               // reset line to normal width"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b#3SPLASH\\n\");   /* top */\\nprintf(\"\\x1b#4SPLASH\\n\");   /* bottom — terminal stitches into doubled glyphs */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "decaln",
        "decstr-soft-reset",
        "ris-reset",
        "deccolm"
      ]
    },
    {
      "slug": "decaln",
      "family": "ESC",
      "title": {
        "en": "DECALN — Screen alignment pattern (ESC # 8)",
        "zh": "DECALN — 屏幕对齐测试图案（ESC # 8）"
      },
      "shortDesc": {
        "en": "Fill the entire screen with capital `E` glyphs — DEC's CRT alignment test, the canonical 'is the page buffer wired up right' smoke test.",
        "zh": "用大写 `E` 字形填满整屏 —— DEC 的 CRT 对齐测试，验证「页面缓冲是否正确接通」的标准烟囱测试。"
      },
      "bytes": {
        "canonical": "\\x1b#8",
        "octal": "\\033#8",
        "eEscape": "\\e#8",
        "literal": "ESC # 8",
        "hex": "1b 23 38"
      },
      "description": {
        "en": "Screen Alignment Test. A **C1-class** escape sequence (no CSI, no parameter — `ESC # 8`, three bytes total) that fills every cell on the active page with the ASCII character `E` (0x45). Originally a hardware diagnostic on DEC VT100 series: the bright uniform `E` pattern made it trivial for a service technician to verify that the CRT's electron beam was deflecting linearly (every `E` should be the same size and shape regardless of position) and that the page memory was addressing all rows / columns correctly (no dropped cells, no row repeats). On software emulators today, it's mostly used by terminal-emulator test suites — vt100/vt220/xterm compatibility tests emit `ESC # 8` to verify that the emulator's grid is correctly sized and addressable.\n\nKey behavioural notes:\n\n- The fill **respects the current page size** — if you've enabled DECCOLM 132 (`\\x1b[?3h`, slug `deccolm`), DECALN paints 132 columns of `E`; in 80-col mode, 80 columns.\n- **All SGR attributes are reset** for the fill — every painted cell uses the default fg/bg with no bold/italic/underline. This makes DECALN a kind of 'visual sgr-reset+clear' in one byte.\n- The cursor is **homed** to row 1 / column 1 after the fill.\n- DECALN ignores DECOM (origin mode) and scrolling regions — it always paints the entire page, edge to edge.\n\nModern emulator support is uneven: xterm and mlterm implement it faithfully (the test suites depend on it); kitty / wezterm / ghostty / alacritty mostly implement it (it's cheap — one byte to recognise, one screen fill to execute) but a few omit it. Linux fbcon and Windows Terminal silent-ignore. Use cases: emulator test suites, retro / VT100-faithful screensavers, debugging cell-grid issues during emulator development. Don't ship to end users — it instantly destroys whatever was on screen.",
        "zh": "Screen Alignment Test。**C1 级**转义序列（无 CSI、无参数 —— `ESC # 8`，共三字节），将活动页面的每个单元填充 ASCII 字符 `E`（0x45）。最初是 DEC VT100 系列的硬件诊断：亮且均匀的 `E` 图案让维修工程师可以轻易验证 CRT 电子束的偏转线性（每个 `E` 不论位置都应大小形状一致），以及页面内存正确寻址所有行 / 列（无单元丢失、无行重复）。今天在软件模拟器上主要被终端模拟器测试套件使用 —— vt100 / vt220 / xterm 兼容性测试发 `ESC # 8` 来验证模拟器网格大小与寻址正确。\n\n关键行为：\n\n- 填充**尊重当前页面大小** —— 若启用了 DECCOLM 132（`\\x1b[?3h`，slug `deccolm`），DECALN 涂 132 列 `E`；80 列模式则涂 80 列。\n- 填充时**所有 SGR 属性被重置** —— 每个被涂单元使用默认前 / 后景，无加粗 / 斜体 / 下划线。这使 DECALN 成为一字节内的「视觉 sgr-reset + 清屏」。\n- 填充后光标**归位**到第 1 行 / 第 1 列。\n- DECALN 忽略 DECOM（原点模式）与滚动区域 —— 永远从边到边涂整个页面。\n\n现代模拟器支持参差：xterm 与 mlterm 忠实实现（测试套件依赖它）；kitty / wezterm / ghostty / alacritty 多数实现（成本低 —— 一字节识别、一屏填充）但少数省略。Linux fbcon 与 Windows Terminal 静默忽略。用途：模拟器测试套件、复古 / VT100 忠实屏保、模拟器开发中调试网格问题。不要发给终端用户 —— 它会立刻摧毁屏上一切。"
      },
      "parameters": [],
      "spec": "DEC VT100 (DECALN) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "printf '\\033#8'   # fill screen with E\\nsleep 2\\nprintf '\\033[2J\\033[H'   # clear screen + home cursor — back to normal"
        },
        {
          "lang": "python",
          "code": "import sys, time\\nsys.stdout.write('\\x1b#8')   # smoke test the grid\\nsys.stdout.flush()\\ntime.sleep(0.5)\\nsys.stdout.write('\\x1b[2J\\x1b[H')   # clear"
        },
        {
          "lang": "go",
          "code": "// Cheap emulator-correctness probe: DECALN, then DSR cursor-pos, expect (1,1):\\nfmt.Print(\"\\x1b#8\")\\nfmt.Print(\"\\x1b[6n\")   // → \\x1b[1;1R if homing worked"
        },
        {
          "lang": "javascript",
          "code": "process.stdout.write('\\x1b#8')   // alignment pattern\\nprocess.stdout.write('\\x1b[2J\\x1b[H')   // restore clean state"
        },
        {
          "lang": "c",
          "code": "fputs(\"\\x1b#8\", stdout);    /* fill */\\nfputs(\"\\x1b[2J\\x1b[H\", stdout);  /* clear + home */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "yes",
        "iterm2": "yes",
        "wt": "no",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "decdhl-decdwl-decswl",
        "ris-reset",
        "decstr-soft-reset",
        "erase-display"
      ]
    },
    {
      "slug": "sgr-colon-subparams",
      "family": "SGR",
      "title": {
        "en": "SGR colon sub-parameters — ITU-T T.416 alternative (38:2:: / 48:2:: / 38:5:)",
        "zh": "SGR 冒号子参数 — ITU-T T.416 替代写法（38:2:: / 48:2:: / 38:5:）"
      },
      "shortDesc": {
        "en": "Use `:` (0x3a) instead of `;` (0x3b) between extended-color sub-parameters — the spec-blessed form that disambiguates compound SGR codes from independent ones.",
        "zh": "在扩展颜色子参数之间使用 `:`（0x3a）代替 `;`（0x3b）—— 规范认可的写法，可消除复合 SGR 与独立 SGR 的歧义。"
      },
      "bytes": {
        "canonical": "\\x1b[38:2::255:128:64m   (T.416)   \\x1b[38;2;255;128;64m   (xterm-legacy)",
        "octal": "\\033[38:2::R:G:Bm",
        "eEscape": "\\e[38:2::R:G:Bm",
        "literal": "ESC [ 38 : 2 :: R : G : B m",
        "hex": "1b 5b 33 38 3a 32 3a 3a ... 6d"
      },
      "description": {
        "en": "**ITU-T Rec. T.416 / ISO/IEC 8613-6** (1993) — the colon-separator form for SGR sub-parameters. Where xterm's original extended-color introduction used semicolons throughout (`\\x1b[38;2;R;G;Bm`), the formal standard reserves `:` (0x3a) as the **sub-parameter separator** within a single SGR parameter, and keeps `;` (0x3b) as the **parameter separator** between independent SGR codes. The shapes are:\n\n- **24-bit truecolor**: `\\x1b[38:2::R:G:Bm` (fg) / `\\x1b[48:2::R:G:Bm` (bg). The empty slot after `2` (yielding the `::`) is the optional **colorspace ID** — empty means RGB, but T.416 allows `38:2:Pcs:R:G:B` where Pcs identifies CIE Lab / CIE u'v'L' / etc. Most emulators ignore Pcs and treat the slot as decorative.\n- **256-color**: `\\x1b[38:5:Nm` / `\\x1b[48:5:Nm`. Note: only ONE colon between `5` and `N` here — no empty `::` slot, because the 256-color form has no colorspace argument.\n- **CMY** (`38:3:Pcs:C:M:Y`) and **CMYK** (`38:4:Pcs:C:M:Y:K`) variants exist in T.416 but are essentially never implemented.\n\n**Why this matters**: the original xterm form `\\x1b[38;2;R;G;Bm` is **ambiguous** to a strictly-conforming SGR parser. Each semicolon-separated token is supposed to be an independent SGR code, so a strict parser sees `38;2;R;G;B` as five independent codes: `38` (set fg to *next item*), `2` (which it might interpret as 'faint'!), then `R G B` as more SGR codes. The colon form `38:2::R:G:B` is unambiguous because the entire compound is a **single parameter** containing sub-tokens — the colons clearly nest under the `38`. The conformance breakdown:\n\n- **Honour the colon form**: kitty (since 0.17), foot, WezTerm, alacritty (since 0.10), ghostty, iTerm2, mlterm, konsole 22.04+, xterm 273+, gnome-terminal recent.\n- **Honour only the semicolon form**: very old emulators, Windows ConPTY (older), some embedded VT clones.\n- **Honour both**: every modern emulator in the first list — they parse `;` and `:` as equivalent in the truecolor / 256-color slot to avoid breaking existing software.\n\nT.416 also defines colon sub-parameters for **SGR 4 underline styles** — `\\x1b[4:0m` (none), `\\x1b[4:1m` (single, same as `4m`), `\\x1b[4:2m` (double), `\\x1b[4:3m` (curly / wavy), `\\x1b[4:4m` (dotted), `\\x1b[4:5m` (dashed) — and the underline colour pair `\\x1b[58:2::R:G:Bm` (set underline colour to RGB) / `\\x1b[59m` (default underline colour). The wavy underline is the killer feature here — IDE-style 'misspelled word' visuals at the terminal layer.\n\nFor portable software, the safe pattern is to **emit the semicolon form** (still understood by every emulator) **but parse both forms** when consuming ANSI bytes from an arbitrary log file.",
        "zh": "**ITU-T 建议书 T.416 / ISO/IEC 8613-6**（1993）—— SGR 子参数的冒号分隔写法。xterm 最初引入扩展颜色时全程使用分号（`\\x1b[38;2;R;G;Bm`），而正式标准保留 `:`（0x3a）作为**子参数分隔符**（同一个 SGR 参数内部），`;`（0x3b）作为**参数分隔符**（独立 SGR 代码之间）。形式如下：\n\n- **24 位真彩色**：`\\x1b[38:2::R:G:Bm`（前景）/ `\\x1b[48:2::R:G:Bm`（背景）。`2` 后的空槽（构成 `::`）是可选的**色彩空间 ID** —— 空表示 RGB，但 T.416 允许 `38:2:Pcs:R:G:B`，其中 Pcs 标识 CIE Lab / CIE u'v'L' 等。多数模拟器忽略 Pcs，把该槽当装饰。\n- **256 色**：`\\x1b[38:5:Nm` / `\\x1b[48:5:Nm`。注意：`5` 与 `N` 之间只有**一个**冒号 —— 没有 `::` 空槽，因为 256 色形式没有色彩空间参数。\n- **CMY**（`38:3:Pcs:C:M:Y`）和 **CMYK**（`38:4:Pcs:C:M:Y:K`）变体在 T.416 中存在但基本无人实现。\n\n**为何重要**：xterm 原始形式 `\\x1b[38;2;R;G;Bm` 对严格遵循 SGR 的解析器**有歧义**。每个分号分隔的 token 本应是独立的 SGR 代码，严格解析器把 `38;2;R;G;B` 看成五个独立代码：`38`（把前景设为下一项）、`2`（可能解为「淡显」！）、然后 `R G B` 又作为 SGR 代码。冒号形式 `38:2::R:G:B` 无歧义，因为整个复合是一个**单参数**含子 token —— 冒号清晰地嵌套在 `38` 之下。一致性现状：\n\n- **支持冒号形式**：kitty（0.17 起）、foot、WezTerm、alacritty（0.10 起）、ghostty、iTerm2、mlterm、konsole 22.04+、xterm 273+、最新 gnome-terminal。\n- **仅支持分号形式**：极老的模拟器、较旧的 Windows ConPTY、部分嵌入式 VT 克隆。\n- **两者皆支持**：上一列表中所有现代模拟器 —— 它们在真彩色 / 256 色槽中将 `;` 与 `:` 视为等价以免破坏既有软件。\n\nT.416 还为 **SGR 4 下划线样式**定义了冒号子参数 —— `\\x1b[4:0m`（无）、`\\x1b[4:1m`（单线，同 `4m`）、`\\x1b[4:2m`（双线）、`\\x1b[4:3m`（卷曲 / 波浪）、`\\x1b[4:4m`（点状）、`\\x1b[4:5m`（虚线）—— 以及下划线颜色对 `\\x1b[58:2::R:G:Bm`（下划线颜色设为 RGB）/ `\\x1b[59m`（恢复默认下划线颜色）。波浪下划线是这里的杀手特性 —— 终端层的 IDE 风「拼写错误」视觉。\n\n面向可移植软件：安全模式是**发分号形式**（每个模拟器都还认得），但在消费任意日志文件的 ANSI 字节时**两种形式都解析**。"
      },
      "parameters": [
        {
          "name": "Pcs",
          "desc": {
            "en": "Optional colorspace ID after the `2` / `3` / `4` mode byte. Empty (yielding `::`) means RGB / CMY / CMYK in the default colorspace. Most emulators ignore.",
            "zh": "在 `2` / `3` / `4` 模式字节之后的可选色彩空间 ID。为空（构成 `::`）表示在默认色彩空间下的 RGB / CMY / CMYK。多数模拟器忽略。"
          }
        },
        {
          "name": "underline-style",
          "desc": {
            "en": "After `4:` — `0` none, `1` single, `2` double, `3` curly, `4` dotted, `5` dashed. Curly (3) is the IDE-style wavy underline.",
            "zh": "在 `4:` 之后 —— `0` 无、`1` 单线、`2` 双线、`3` 卷曲、`4` 点状、`5` 虚线。卷曲（3）即 IDE 风波浪下划线。"
          }
        }
      ],
      "spec": "ITU-T Rec. T.416 (ISO/IEC 8613-6) / xterm-ctlseqs (SGR Pm)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Strict T.416 truecolor (note the `::`):\\nprintf '\\033[38:2::255:128:64morange text\\033[0m\\n'\\n# Curly underline for spell-check overlays:\\nprintf '\\033[4:3mtypo\\033[0m\\n'"
        },
        {
          "lang": "python",
          "code": "import sys\\nRGB = (255, 128, 64)\\nsys.stdout.write(f'\\x1b[38:2::{RGB[0]}:{RGB[1]}:{RGB[2]}morange\\x1b[0m\\n')\\n# Underline colour (T.416 58 / 59):\\nsys.stdout.write('\\x1b[4m\\x1b[58:2::255:0:0merror\\x1b[59m\\x1b[24m\\n')"
        },
        {
          "lang": "go",
          "code": "// Emit semicolon form (most portable) but parse both:\\nfmt.Print(\"\\x1b[38;2;255;128;64morange\\x1b[0m\\n\")\\n// T.416 strict form:\\nfmt.Print(\"\\x1b[38:2::255:128:64morange\\x1b[0m\\n\")"
        },
        {
          "lang": "javascript",
          "code": "// Curly underline + RGB underline colour:\\nprocess.stdout.write('\\x1b[4:3m\\x1b[58:2::200:80:80mmisspelled\\x1b[59m\\x1b[24m\\n')"
        },
        {
          "lang": "c",
          "code": "/* T.416 256-color: single colon, no empty slot: */\\nprintf(\"\\x1b[38:5:208morange-216\\x1b[0m\\n\");\\n/* Truecolor with empty colorspace slot: */\\nprintf(\"\\x1b[48:2::20:20:60mdeep blue bg\\x1b[0m\\n\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "sgr-fg-truecolor",
        "sgr-bg-truecolor",
        "sgr-fg-256",
        "sgr-bg-256",
        "sgr-underline"
      ]
    },
    {
      "slug": "osc-prompt-marks",
      "family": "OSC",
      "title": {
        "en": "OSC 133 — Semantic prompt marks (FinalTerm A / B / C / D)",
        "zh": "OSC 133 — 语义化提示符标记（FinalTerm A / B / C / D）"
      },
      "shortDesc": {
        "en": "Tag shell prompt-start / command-start / output-start / command-end so the terminal can jump between prompts, fold output, and decorate exit codes.",
        "zh": "标注提示符开始 / 命令开始 / 输出开始 / 命令结束，让终端能在提示符之间跳转、折叠输出、装饰退出码。"
      },
      "bytes": {
        "canonical": "\\x1b]133;A\\x07   (prompt start)   \\x1b]133;B\\x07   (command start)   \\x1b]133;C\\x07   (output start)   \\x1b]133;D;<exit>\\x07   (command end)",
        "octal": "\\033]133;A\\007 / \\033]133;B\\007 / \\033]133;C\\007 / \\033]133;D;0\\007",
        "eEscape": "\\e]133;A\\a / \\e]133;B\\a / \\e]133;C\\a / \\e]133;D;0\\a",
        "literal": "ESC ] 133 ; A BEL  etc.",
        "hex": "1b 5d 31 33 33 3b 41 07 / ...3b 42 07 / ...3b 43 07 / ...3b 44 ... 07"
      },
      "description": {
        "en": "FinalTerm-defined **shell integration** protocol now widely adopted by Kitty, WezTerm, Ghostty, iTerm2, Warp, VS Code's terminal, and (partially) Windows Terminal. Four mark codes carve a shell session into structured blocks:\n\n- **`OSC 133 ; A ST`** — prompt start (emitted just before `PS1` renders).\n- **`OSC 133 ; B ST`** — command start (between prompt and the user's input).\n- **`OSC 133 ; C ST`** — output start (after pressing Enter; before the command's stdout/stderr begins).\n- **`OSC 133 ; D [ ; <exit-code> ] ST`** — command end (after the command exits; optional numeric exit code).\n\nThe terminal turns these into UX: **jump to previous / next prompt** (kitty `kitten select-prompt`, iTerm2 ⌘↑/⌘↓, WezTerm `ActivateCommandPalette`), **fold a single command's output** (iTerm2, WezTerm), **decorate the prompt gutter** with the exit code (red triangle / green tick — kitty, iTerm2, Ghostty), and **scroll one command at a time** instead of one screen at a time. Most modern shell-integration plugins (`atuin`, `starship`'s wrappers, the bash/zsh hooks shipped with kitty / wezterm / iTerm2) wire these automatically — `__prompt_command` emits A, the `PS1` ends with B, the `DEBUG`/`preexec` hook emits C, and `precmd` emits D with `$?`. Sub-parameters used in practice: `aid=<unique>` (used by Warp / kitty to disambiguate concurrent shells), `cl=m` on `A` (the 'multi-line prompt' hint), `k=i`/`k=r` on `B` (input vs. continuation). The protocol is opt-in — emitting these into a terminal that doesn't recognise them just dropps the bytes; emit them unconditionally.",
        "zh": "FinalTerm 定义的 **shell 集成**协议，现已被 Kitty、WezTerm、Ghostty、iTerm2、Warp、VS Code 终端、（部分）Windows Terminal 广泛采用。四个标记码把一个 shell 会话切成结构化块：\n\n- **`OSC 133 ; A ST`** —— 提示符开始（`PS1` 渲染前发送）。\n- **`OSC 133 ; B ST`** —— 命令开始（提示符与用户输入之间）。\n- **`OSC 133 ; C ST`** —— 输出开始（按 Enter 后，命令 stdout / stderr 开始之前）。\n- **`OSC 133 ; D [ ; <退出码> ] ST`** —— 命令结束（命令退出后，可选的数字退出码）。\n\n终端把它们转成 UX：**跳到上 / 下一个提示符**（kitty `kitten select-prompt`、iTerm2 ⌘↑/⌘↓、WezTerm `ActivateCommandPalette`）；**折叠某条命令的输出**（iTerm2、WezTerm）；**在提示符行内装饰退出码**（红三角 / 绿勾 —— kitty、iTerm2、Ghostty）；**按一条命令滚屏**而不是按一屏滚屏。多数现代 shell 集成插件（`atuin`、`starship` 的包装层、kitty / wezterm / iTerm2 自带的 bash/zsh 钩子）自动注入这些标记 —— `__prompt_command` 发 A，`PS1` 结尾发 B，`DEBUG` / `preexec` 钩子发 C，`precmd` 用 `$?` 发 D。常见子参数：`aid=<unique>`（Warp / kitty 用于区分并发 shell）、`A` 上的 `cl=m`（「多行提示符」提示）、`B` 上的 `k=i` / `k=r`（输入 vs 续行）。协议为加入式 —— 对不识别的终端发出后字节被丢弃；可无条件发送。"
      },
      "parameters": [
        {
          "name": "A / B / C / D",
          "desc": {
            "en": "Mark type: A prompt-start, B command-start, C output-start, D command-end. Each carves a structural boundary the terminal can navigate to.",
            "zh": "标记类型：A 提示符开始、B 命令开始、C 输出开始、D 命令结束。每个划出终端可导航的结构边界。"
          }
        },
        {
          "name": "exit-code",
          "desc": {
            "en": "Optional integer after `D;` — the just-finished command's `$?`. Used to decorate the prompt gutter with success / failure indicators.",
            "zh": "`D;` 后可选整数 —— 刚结束命令的 `$?`。用于在提示符行装饰成功 / 失败标识。"
          }
        }
      ],
      "spec": "FinalTerm Semantic Prompts / xterm-ctlseqs (OSC 133)",
      "examples": [
        {
          "lang": "bash",
          "code": "# zsh/bash shell-integration sketch (real impls handle PS1 specially):\\nPS1='\\[\\e]133;A\\a\\]\\u@\\h \\W $ \\[\\e]133;B\\a\\]'\\npreexec() { printf '\\033]133;C\\007'; }\\nprecmd()  { printf '\\033]133;D;%d\\007' \"$?\"; }"
        },
        {
          "lang": "python",
          "code": "# Manually frame a command exec inside a Python REPL:\\nimport sys, subprocess\\nsys.stdout.write('\\x1b]133;C\\x07')                  # output starts\\nrc = subprocess.run(['ls']).returncode\\nsys.stdout.write(f'\\x1b]133;D;{rc}\\x07')             # command ends with exit code"
        },
        {
          "lang": "go",
          "code": "fmt.Print(\"\\x1b]133;A\\x07\")          // before prompt\\nfmt.Print(\"$ \\x1b]133;B\\x07\")        // command waiting\\n// … run command, capture rc …\\nfmt.Printf(\"\\x1b]133;D;%d\\x07\", rc)"
        },
        {
          "lang": "javascript",
          "code": "// Node REPL wrapping a child:\\nprocess.stdout.write('\\x1b]133;C\\x07')\\nconst child = spawn('npm', ['test'])\\nchild.on('close', code => process.stdout.write(`\\x1b]133;D;${code}\\x07`))"
        },
        {
          "lang": "c",
          "code": "printf(\"\\x1b]133;A\\x07\");   /* prompt-start */\\nprintf(\"%s$ \", cwd);\\nprintf(\"\\x1b]133;B\\x07\");   /* command-start */\\n/* … fork+exec, wait … */\\nprintf(\"\\x1b]133;D;%d\\x07\", WEXITSTATUS(status));"
        }
      ],
      "support": {
        "xterm": "no",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "osc-cwd",
        "osc-title",
        "osc-hyperlink",
        "osc-notification"
      ]
    },
    {
      "slug": "osc-iterm-image",
      "family": "OSC",
      "title": {
        "en": "OSC 1337 — iTerm2 inline images & file transfer",
        "zh": "OSC 1337 — iTerm2 内联图片与文件传输"
      },
      "shortDesc": {
        "en": "Embed images, files, or proprietary iTerm2 state into the terminal stream — the predecessor protocol that Kitty / Sixel later largely supplanted.",
        "zh": "把图片、文件、或 iTerm2 私有状态嵌入终端字节流 —— Kitty / Sixel 后来主要取代的前身协议。"
      },
      "bytes": {
        "canonical": "\\x1b]1337;File=name=<base64>;size=<bytes>;inline=1:<base64-data>\\x07",
        "octal": "\\033]1337;File=...:<base64>\\007",
        "eEscape": "\\e]1337;File=...:<base64>\\a",
        "literal": "ESC ] 1337 ; <key=value;...> : <base64> BEL",
        "hex": "1b 5d 31 33 33 37 3b ... 07"
      },
      "description": {
        "en": "iTerm2's proprietary OSC 1337 multiplexes a whole family of out-of-band features onto a single OSC code, distinguished by the first body token. The most-used form is **`File=...:<base64>`** for inline images and file transfers — same vocabulary, different `inline=` flag. Keys (key=value, `;`-separated, before the `:`):\n\n- `name=<base64-of-filename>` — display name / save-target on Cmd-S.\n- `size=<bytes>` — for progress bar.\n- `inline=1` — render as an image right at the cursor (default 0 means 'download to ~/Downloads').\n- `width=<n>` / `height=<n>` — sizing in cells, pixels (`px` suffix), percent (`%` suffix), or `auto`.\n- `preserveAspectRatio=0|1` — default 1.\n- `type=<mime>` — `image/png`, `image/jpeg`, `image/gif` (animated), `application/pdf` etc.\n\nAfter the keys, a single `:` separator, then the **base64-encoded payload**. Animation frames in GIF replay naturally. iTerm2 also defines non-File OSC 1337 sub-codes for `RemoteHost=<user>@<host>`, `CurrentDir=<path>` (mostly subsumed by OSC 7 now), `SetUserVar=<name>=<base64>` (for custom status-bar variables), `SetMark` (jump points distinct from OSC 133), `ReportCellSize` (replies with pixel size of one cell — Tmux uses this for ratatui-style pixel-accurate Sixel sizing). **Modern adoption**: iTerm2 (origin); WezTerm + Konsole 22.04+ implement the `File=` subset; Kitty / Ghostty advertise their *own* protocols (kitty graphics / WezTerm imgcat-compat) but accept OSC 1337 `File=` for the `imgcat` shell-script compatibility shim distributed by iTerm2. Use case today: shipping an image into the terminal pane without depending on Sixel; the `imgcat` script is the canonical entry-point.",
        "zh": "iTerm2 私有的 OSC 1337 通过一个 OSC 代码复用一整族带外特性，靠体内首个 token 区分。最常用形式是 **`File=...:<base64>`** 用于内联图片与文件传输 —— 同一词汇，不同 `inline=` 标志。键（key=value，`;` 分隔，置于 `:` 之前）：\n\n- `name=<文件名 base64>` —— 显示名 / Cmd-S 保存目标。\n- `size=<字节>` —— 进度条用。\n- `inline=1` —— 在光标处渲染为图片（默认 0 表示「下载到 ~/Downloads」）。\n- `width=<n>` / `height=<n>` —— 尺寸，单位为单元、像素（`px` 后缀）、百分比（`%` 后缀）或 `auto`。\n- `preserveAspectRatio=0|1` —— 默认 1。\n- `type=<mime>` —— `image/png`、`image/jpeg`、`image/gif`（动画）、`application/pdf` 等。\n\n键之后跟单个 `:` 分隔符，再是 **base64 编码的载荷**。GIF 的动画帧自动播放。iTerm2 还为 OSC 1337 定义了非 File 子码：`RemoteHost=<user>@<host>`、`CurrentDir=<path>`（如今多被 OSC 7 取代）、`SetUserVar=<name>=<base64>`（自定义状态栏变量）、`SetMark`（跳转点，与 OSC 133 不同）、`ReportCellSize`（回复单元像素大小 —— tmux 用它做像素精确的 Sixel 缩放）。**现代采用**：iTerm2（始作俑者）；WezTerm + Konsole 22.04+ 实现 `File=` 子集；Kitty / Ghostty 各自宣传自家协议（kitty graphics / WezTerm imgcat-compat），但都接受 OSC 1337 `File=` 以兼容 iTerm2 发行的 `imgcat` shell 脚本。今日用途：把图片送入终端面板而不依赖 Sixel；`imgcat` 脚本是标准入口。"
      },
      "parameters": [
        {
          "name": "File=...:<base64>",
          "desc": {
            "en": "Inline image / file transfer subprotocol. Keys precede the `:`; base64 payload follows. Use `inline=1` to render at cursor, 0 to download.",
            "zh": "内联图片 / 文件传输子协议。键在 `:` 之前；base64 载荷在后。`inline=1` 在光标处渲染、0 仅下载。"
          }
        },
        {
          "name": "SetUserVar / SetMark / RemoteHost / CurrentDir / ReportCellSize",
          "desc": {
            "en": "Non-File subcodes for status-bar variables, navigation marks, shell-integration host/cwd advertising, and cell-pixel-size queries.",
            "zh": "非 File 子码 —— 用于状态栏变量、导航标记、shell 集成主机 / cwd 广告、单元像素尺寸查询。"
          }
        }
      ],
      "spec": "iTerm2 Proprietary Escape Codes (OSC 1337)",
      "examples": [
        {
          "lang": "bash",
          "code": "# imgcat-style: render PNG at cursor.\\nB64=$(base64 -w 0 ./logo.png)\\nprintf '\\033]1337;File=name=%s;inline=1:%s\\007' \"$(printf 'logo.png' | base64 -w 0)\" \"$B64\""
        },
        {
          "lang": "python",
          "code": "import base64, sys\\ndata = open('logo.png','rb').read()\\nname = base64.b64encode(b'logo.png').decode()\\npayload = base64.b64encode(data).decode()\\nsys.stdout.write(f'\\x1b]1337;File=name={name};inline=1:{payload}\\x07')"
        },
        {
          "lang": "go",
          "code": "// Advertise CWD via iTerm2's older mechanism (most apps prefer OSC 7 now):\\nfmt.Print(\"\\x1b]1337;CurrentDir=/Users/me/code\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "// Set a custom iTerm2 user var that a status-bar component can read:\\nconst b64 = Buffer.from('on-call').toString('base64')\\nprocess.stdout.write(`\\x1b]1337;SetUserVar=role=${b64}\\x07`)"
        },
        {
          "lang": "c",
          "code": "/* Probe iTerm2/wezterm cell-pixel size — used by Sixel renderers: */\\nfputs(\"\\x1b]1337;ReportCellSize\\x07\", stdout);\\n/* Reply lands on stdin as another OSC 1337. */"
        }
      ],
      "support": {
        "xterm": "no",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "no",
        "cmd": "no",
        "kitty": "partial",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "partial",
        "gnometerm": "no",
        "konsole": "yes"
      },
      "related": [
        "dcs-sixel",
        "dcs-kitty-graphics",
        "osc-cwd",
        "osc-hyperlink"
      ]
    },
    {
      "slug": "osc-progress",
      "family": "OSC",
      "title": {
        "en": "OSC 9 ; 4 — ConEmu progress indicator (Windows Terminal / Ghostty)",
        "zh": "OSC 9 ; 4 — ConEmu 进度指示器（Windows Terminal / Ghostty）"
      },
      "shortDesc": {
        "en": "Push live progress percentages / paused / error states to the taskbar or tab icon — the ConEmu protocol that Windows Terminal 1.18+ standardised.",
        "zh": "把实时进度百分比 / 暂停 / 错误状态推送到任务栏或标签图标 —— ConEmu 协议，被 Windows Terminal 1.18+ 标准化。"
      },
      "bytes": {
        "canonical": "\\x1b]9;4;<state>;<percent>\\x07",
        "octal": "\\033]9;4;<state>;<percent>\\007",
        "eEscape": "\\e]9;4;<state>;<percent>\\a",
        "literal": "ESC ] 9 ; 4 ; STATE ; N BEL",
        "hex": "1b 5d 39 3b 34 3b ... 3b ... 07"
      },
      "description": {
        "en": "ConEmu's progress-bar repurpose of OSC 9 — distinct from iTerm2's `OSC 9 ; <message>` notification (slug `osc-notification`); the `;4` second token is the disambiguator. The terminal forwards progress state to whatever ambient UI it owns: Windows Terminal updates the taskbar icon (Windows 11 unified-progress UX), Ghostty / WezTerm tint the tab indicator, ConEmu paints a horizontal bar across the title bar. Four states (passed as the first numeric after `;4;`):\n\n- **`0`** — Remove / clear progress (the explicit reset).\n- **`1`** — Normal progress, `<percent>` 0–100 — the default linear-progress bar.\n- **`2`** — Error state, `<percent>` 0–100 — turns the bar red, used for build failures with progress information.\n- **`3`** — Indeterminate — `<percent>` ignored; renders an indeterminate spinner / barber-pole.\n- **`4`** — Warning / paused, `<percent>` 0–100 — yellow.\n\nUsage pattern: long-running CLI commands (`docker pull`, `cargo build`, `ffmpeg` transcodes, `apt`-style installers) emit `OSC 9 ; 4 ; 1 ; <pct>` after each meaningful step, and `OSC 9 ; 4 ; 0` on success. On failure: `OSC 9 ; 4 ; 2 ; <last-pct>` then optionally `0` after the user acks. Unsupported terminals silently drop the bytes — emit unconditionally. Critical detail: the `\\x1b]9;` prefix collides with iTerm2's notification OSC 9; almost every emulator that implements both keys the disambiguation off `;4` being present, so emit the **full** `\\x1b]9;4;<state>;<pct>\\x07` shape — never abbreviate.",
        "zh": "ConEmu 把 OSC 9 重用为进度条 —— 与 iTerm2 的 `OSC 9 ; <消息>` 通知（slug `osc-notification`）不同；第二个 token `;4` 是消歧符。终端将进度状态转发给所在的环境 UI：Windows Terminal 更新任务栏图标（Windows 11 统一进度 UX）；Ghostty / WezTerm 给标签指示器上色；ConEmu 在标题栏画一条水平进度条。四种状态（`;4;` 后第一个数字）：\n\n- **`0`** —— 移除 / 清除进度（显式复位）。\n- **`1`** —— 正常进度，`<percent>` 0–100 —— 默认线性进度条。\n- **`2`** —— 错误状态，`<percent>` 0–100 —— 进度条转红，用于带进度的构建失败。\n- **`3`** —— 不确定 —— `<percent>` 忽略；渲染不定形旋转 / 流条。\n- **`4`** —— 警告 / 暂停，`<percent>` 0–100 —— 黄色。\n\n用法：长时间 CLI 命令（`docker pull`、`cargo build`、`ffmpeg` 转码、`apt` 类安装器）在每个有意义步骤后发 `OSC 9 ; 4 ; 1 ; <pct>`，成功时发 `OSC 9 ; 4 ; 0`。失败时：`OSC 9 ; 4 ; 2 ; <最后 pct>`，用户确认后可选再发 `0`。不支持的终端静默丢弃 —— 可无条件发送。关键细节：`\\x1b]9;` 前缀与 iTerm2 通知 OSC 9 撞名；几乎所有同时实现两者的模拟器以是否带 `;4` 作判别，所以**完整**发送 `\\x1b]9;4;<state>;<pct>\\x07`，不要缩写。"
      },
      "parameters": [
        {
          "name": "state",
          "desc": {
            "en": "0 remove, 1 normal, 2 error, 3 indeterminate, 4 warning/paused.",
            "zh": "0 移除、1 正常、2 错误、3 不确定、4 警告 / 暂停。"
          }
        },
        {
          "name": "percent",
          "desc": {
            "en": "0–100 integer (ignored when state=3 indeterminate; required for 1/2/4).",
            "zh": "0–100 整数（state=3 不确定时忽略；1/2/4 必需）。"
          }
        }
      ],
      "spec": "ConEmu OSC 9;4 / Windows Terminal 1.18+ / Ghostty",
      "examples": [
        {
          "lang": "bash",
          "code": "# Build-progress wrapper:\\nfor pct in 10 30 60 90; do\\n  make step-$pct\\n  printf '\\033]9;4;1;%d\\007' \"$pct\"\\ndone\\nprintf '\\033]9;4;0\\007'   # clear on success"
        },
        {
          "lang": "python",
          "code": "import sys, time\\nfor pct in range(0, 101, 5):\\n    sys.stdout.write(f'\\x1b]9;4;1;{pct}\\x07'); sys.stdout.flush()\\n    time.sleep(0.05)\\nsys.stdout.write('\\x1b]9;4;0\\x07')"
        },
        {
          "lang": "go",
          "code": "// Indeterminate while waiting on the network:\\nfmt.Print(\"\\x1b]9;4;3\\x07\")\\ndoSlowFetch()\\nfmt.Print(\"\\x1b]9;4;0\\x07\")"
        },
        {
          "lang": "javascript",
          "code": "// Error red-bar at 50%:\\nprocess.stdout.write('\\x1b]9;4;2;50\\x07')"
        },
        {
          "lang": "c",
          "code": "/* Warning / paused state at 75%: */\\nprintf(\"\\x1b]9;4;4;75\\x07\"); fflush(stdout);"
        }
      ],
      "support": {
        "xterm": "no",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "yes",
        "cmd": "no",
        "kitty": "partial",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "osc-notification",
        "osc-title",
        "osc-prompt-marks"
      ]
    },
    {
      "slug": "dcs-decrsps",
      "family": "DCS",
      "title": {
        "en": "DECRSPS — Restore Presentation State (DCS $ t ... ST)",
        "zh": "DECRSPS — 恢复呈现状态（DCS $ t ... ST）"
      },
      "shortDesc": {
        "en": "Inverse of DECRQSS — feed back a previously-saved cursor / SGR / margin snapshot to restore the terminal's exact state.",
        "zh": "DECRQSS 的反向操作 —— 把先前保存的光标 / SGR / 边距快照回灌，恢复终端精确状态。"
      },
      "bytes": {
        "canonical": "\\x1bP1$t<saved-state>\\x1b\\\\   (cursor)   \\x1bP2$t<saved-state>\\x1b\\\\   (tab stops)",
        "octal": "\\033P<Ps>$t<state>\\033\\\\",
        "eEscape": "\\eP<Ps>$t<state>\\e\\\\",
        "literal": "ESC P Ps $ t <state> ESC \\",
        "hex": "1b 50 ... 24 74 ... 1b 5c"
      },
      "description": {
        "en": "Restore Presentation State. A DCS frame whose intermediate is `$` (0x24) and final is `t` (0x74) — the **inverse** of DECRQPSR (the DCS-side request that DECRQSS dispatches as `\\x1bP$qm\\x1b\\\\` family). The leading `Ps` selects what category of state is being restored:\n\n- **`Ps = 1`** — cursor information: row, column, page, character protection (DECSCA), origin mode (DECOM), DECSC save-stack state, charset GL/GR selections (SCS), and SGR rendition.\n- **`Ps = 2`** — tab stops: the full HTS-set column list.\n\nThe `<saved-state>` body is the **exact reply bytes** the terminal originally returned to the matching `DECRQPSR` (`\\x1bP$w...\\x1b\\\\`) — applications cache the reply at startup, then replay it at exit via DECRSPS to undo any state changes. This is the canonical mechanism behind `tmux`'s `passthrough` of saved terminal state and `screen`'s `:source` of its `.screenrc`-driven defaults. **Modern relevance**: only xterm and a handful of VT-faithful emulators (mlterm, qodem) implement DECRSPS at this fidelity; most modern emulators (alacritty / kitty / wezterm / ghostty) reply to the matching DECRQPSR with `0$w` (rejected / unsupported), making the whole save-and-restore round-trip a no-op — these apps rely on DECSC/DECRC (`\\x1b7` / `\\x1b8`) for cursor save/restore and on the alt-screen `\\x1b[?1049h/l` pair for the high-level snapshot. DECRSPS remains useful for emulator-test-suite snapshots and for VT510-faithful host software, but a portable app should NOT depend on it being honoured.",
        "zh": "Restore Presentation State。中间字节 `$`（0x24）、末字节 `t`（0x74）的 DCS 帧 —— DECRQPSR 的**反向**（DECRQSS 派发的 `\\x1bP$qm\\x1b\\\\` 族在 DCS 侧的请求形态）。开头 `Ps` 选择要恢复的状态种类：\n\n- **`Ps = 1`** —— 光标信息：行、列、页、字符保护（DECSCA）、原点模式（DECOM）、DECSC 保存栈状态、字符集 GL / GR 选择（SCS）、SGR 渲染属性。\n- **`Ps = 2`** —— 制表位：HTS 设置的完整列列表。\n\n`<saved-state>` 体是终端先前响应对应 `DECRQPSR`（`\\x1bP$w...\\x1b\\\\`）时回复的**原始字节** —— 应用在启动时缓存这份回复，退出时通过 DECRSPS 回灌，撤销所有状态变更。这就是 `tmux` `passthrough` 已存终端状态以及 `screen` `:source` `.screenrc` 默认值的标准机制。**现代相关性**：仅 xterm 与少数忠实 VT 模拟器（mlterm、qodem）以这种精度实现 DECRSPS；多数现代模拟器（alacritty / kitty / wezterm / ghostty）对对应的 DECRQPSR 以 `0$w`（拒绝 / 不支持）回应，整套保存 - 恢复回路成为 no-op —— 这些程序用 DECSC / DECRC（`\\x1b7` / `\\x1b8`）做光标保存恢复、用 alt-screen `\\x1b[?1049h/l` 对做高层快照。DECRSPS 仍对模拟器测试套件快照与 VT510 忠实主机软件有用；可移植应用**不应**依赖它被尊重。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "Category selector: `1` = cursor / SGR / charset / origin / save-stack; `2` = tab stops.",
            "zh": "类别选择子：`1` = 光标 / SGR / 字符集 / 原点 / 保存栈；`2` = 制表位。"
          }
        },
        {
          "name": "saved-state",
          "desc": {
            "en": "Verbatim body bytes from a prior DECRQPSR reply (the terminal's own format; applications shouldn't construct this — only round-trip it).",
            "zh": "先前 DECRQPSR 回复的体内字节（终端自身格式；应用不应自行构造，只做来回拷贝）。"
          }
        }
      ],
      "spec": "DEC VT510 RM (DECRSPS) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Round-trip pattern: ask, stash, later restore.\\nstty -echo raw min 0 time 5\\nprintf '\\033P1$w\\033\\\\\\\\'   # DECRQPSR cursor info\\nIFS= read -r -t 1 -d '\\\\' REPLY; stty sane\\n# … much later, restore exactly: …\\nprintf '\\033P1$t%s\\033\\\\\\\\' \"$REPLY\""
        },
        {
          "lang": "python",
          "code": "import sys\\nsaved = read_decrqpsr()                              # opaque body bytes\\nsys.stdout.write(f'\\x1bP1$t{saved}\\x1b\\\\\\\\')"
        },
        {
          "lang": "go",
          "code": "// Pseudo: restore previously-stashed cursor + SGR state\\nfmt.Printf(\"\\x1bP1$t%s\\x1b\\\\\\\\\", savedBody)"
        },
        {
          "lang": "javascript",
          "code": "// On exit, replay the snapshot we captured at startup:\\nprocess.stdout.write(`\\x1bP2$t${savedTabStops}\\x1b\\\\\\\\`)   // restore tab stops"
        },
        {
          "lang": "c",
          "code": "/* Replay the cursor / SGR snapshot captured at program start: */\\nprintf(\"\\x1bP1$t%s\\x1b\\\\\\\\\", saved_state_buf);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "dcs-decrqss",
        "cursor-save-restore",
        "decstr-soft-reset",
        "ris-reset"
      ]
    },
    {
      "slug": "dcs-decdmac",
      "family": "DCS",
      "title": {
        "en": "DECDMAC / DECINVM — Define & invoke macro (DCS Pn ; Pn ; Pn ! z ... ST  /  CSI Pn * z)",
        "zh": "DECDMAC / DECINVM — 定义与调用宏（DCS Pn ; Pn ; Pn ! z ... ST  /  CSI Pn * z）"
      },
      "shortDesc": {
        "en": "Store a byte sequence under a numeric handle (DECDMAC), then replay it on demand (DECINVM) — DEC VT520's terminal-side macro recorder.",
        "zh": "用数字句柄存储一段字节序列（DECDMAC），按需回放（DECINVM）—— DEC VT520 的终端内置宏录制器。"
      },
      "bytes": {
        "canonical": "\\x1bP<Pid>;<Pdt>;<Penc>!z<MACRO-BODY>\\x1b\\\\   (define)   \\x1b[<Pid>*z   (invoke)",
        "octal": "\\033P<Pid>;<Pdt>;<Penc>!z<body>\\033\\\\   /   \\033[<Pid>*z",
        "eEscape": "\\eP<Pid>;<Pdt>;<Penc>!z<body>\\e\\\\   /   \\e[<Pid>*z",
        "literal": "ESC P Pid ; Pdt ; Penc ! z BODY ESC \\   /   ESC [ Pid * z",
        "hex": "1b 50 ... 21 7a ... 1b 5c   /   1b 5b ... 2a 7a"
      },
      "description": {
        "en": "DEC VT520 / VT525 macro facility — two paired sequences. **DECDMAC** (Define Macro) is a DCS frame with intermediate `!` (0x21) and final `z` (0x7a) that stores the body `<MACRO-BODY>` under integer handle `Pid` (0–63). Parameters:\n\n- `Pid` — macro number (0–63).\n- `Pdt` (delete-type) — `0` (default) overwrite this macro only; `1` delete **all** macros before storing.\n- `Penc` (encoding) — `0` (default) body is plain 7-bit / 8-bit terminal bytes; `1` body is hex-encoded (every two hex digits = one byte) — the hex form lets the macro safely contain ESC, ST, `;`, and other parser-sensitive bytes that would otherwise terminate the DCS frame early.\n\n**DECINVM** (Invoke Macro) is a CSI sequence with intermediate `*` (0x2a) and final `z` — `\\x1b[<Pid>*z` replays whatever was stored under that handle as if those bytes had arrived freshly on the wire (any embedded SGR, cursor moves, OSC, etc. all execute in normal parser state).\n\n**Use case** (historical): forms-data-entry terminals — a host application defined a stable set of cursor-position + box-drawing macros at session start, then drove the screen via short DECINVM calls instead of repeating the heavy CSI sequences thousands of times across the page. Saves wire bytes on slow serial links (the original motivation), and lets the terminal cache the cursor-positioning work.\n\n**Modern relevance**: essentially nil. Only xterm implements both at meaningful fidelity (with `disallowedColors` / `allowMacro` resources defaulting to **off** for security — a remote process defining macros that later get invoked is a small but real shell-integration / clipboard-injection attack surface). Modern emulators (alacritty / kitty / wezterm / ghostty / Windows Terminal) silently ignore both. Use for: VT520-faithful emulator test suites, forms-terminal preservation work, and exotic demos.",
        "zh": "DEC VT520 / VT525 宏机制 —— 一对组合序列。**DECDMAC**（定义宏）是中间字节 `!`（0x21）、末字节 `z`（0x7a）的 DCS 帧，把体 `<MACRO-BODY>` 存于整数句柄 `Pid`（0–63）下。参数：\n\n- `Pid` —— 宏编号（0–63）。\n- `Pdt`（delete-type）—— `0`（默认）只覆盖本宏；`1` 在写入前删除**所有**宏。\n- `Penc`（encoding）—— `0`（默认）体为普通 7 / 8 位终端字节；`1` 体为十六进制编码（每两个十六进制 = 一字节）—— 十六进制形式让宏可安全包含 ESC、ST、`;` 等会提前终止 DCS 帧的解析敏感字节。\n\n**DECINVM**（调用宏）是中间字节 `*`（0x2a）、末字节 `z` 的 CSI 序列 —— `\\x1b[<Pid>*z` 回放该句柄下存储的全部字节，仿佛它们是刚通过线路到达（任何嵌入的 SGR、光标移动、OSC 等都以正常解析器状态执行）。\n\n**用途**（历史）：表单录入终端 —— 主机程序在会话开始时定义一组稳定的光标定位 + 框线宏，随后用短小的 DECINVM 调用驱动屏幕，而非在整页里重复发送沉重的 CSI 序列上千次。在慢串口上省字节（原始动机）；同时让终端缓存光标定位工作。\n\n**现代相关性**：基本为零。仅 xterm 以有意义的精度实现两者（`disallowedColors` / `allowMacro` 资源默认**关**，因远程进程定义后被调用的宏是一个小但真实的 shell 集成 / 剪贴板注入攻击面）。现代模拟器（alacritty / kitty / wezterm / ghostty / Windows Terminal）静默忽略两者。用途：VT520 忠实模拟器测试套件、表单终端保留工作、奇异演示。"
      },
      "parameters": [
        {
          "name": "Pid",
          "desc": {
            "en": "Macro number 0–63 (define and invoke share the same numeric namespace).",
            "zh": "宏编号 0–63（定义与调用共享同一数字命名空间）。"
          }
        },
        {
          "name": "Pdt",
          "desc": {
            "en": "Delete-type for DECDMAC: 0 = overwrite this slot only, 1 = delete ALL macros first.",
            "zh": "DECDMAC 的删除类型：0 = 仅覆盖该槽，1 = 先删除所有宏。"
          }
        },
        {
          "name": "Penc",
          "desc": {
            "en": "Encoding for the DECDMAC body: 0 = raw bytes, 1 = hex-encoded (safe for ESC / ST / `;`).",
            "zh": "DECDMAC 体的编码：0 = 原始字节，1 = 十六进制编码（对 ESC / ST / `;` 安全）。"
          }
        }
      ],
      "spec": "DEC VT520 RM (DECDMAC / DECINVM) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Define macro 1 = 'cursor-home + clear screen', then invoke twice.\\nprintf '\\033P1;0;0!z\\033[H\\033[2J\\033\\\\\\\\'\\nprintf '\\033[1*z'   # invoke — clears screen\\nprintf '\\033[1*z'   # invoke again — still clears"
        },
        {
          "lang": "python",
          "code": "import sys\\n# Hex-encoded body so the macro can contain ESC safely:\\nbody_hex = '1b5b481b5b324a'           # ESC[H ESC[2J\\nsys.stdout.write(f'\\x1bP2;0;1!z{body_hex}\\x1b\\\\\\\\')\\nsys.stdout.write('\\x1b[2*z')   # invoke macro 2"
        },
        {
          "lang": "go",
          "code": "// Define a 'red bold' SGR macro then invoke at every log line:\\nfmt.Print(\"\\x1bP3;0;0!z\\x1b[1;31m\\x1b\\\\\\\\\")\\nfor _, line := range lines { fmt.Print(\"\\x1b[3*z\" + line + \"\\x1b[0m\\n\") }"
        },
        {
          "lang": "javascript",
          "code": "// Wipe all macros and store a fresh one in slot 0:\\nprocess.stdout.write('\\x1bP0;1;0!zHELLO\\x1b\\\\\\\\')\\nprocess.stdout.write('\\x1b[0*z')   // prints HELLO"
        },
        {
          "lang": "c",
          "code": "/* Define macro 7 = SGR reset; invoke at end of every styled span. */\\nprintf(\"\\x1bP7;0;0!z\\x1b[0m\\x1b\\\\\\\\\");\\nfor (int i = 0; i < n; ++i) {\\n    print_colored(items[i]);\\n    printf(\"\\x1b[7*z\");\\n}"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "dcs-decrqss",
        "dcs-decrsps",
        "decstr-soft-reset",
        "ris-reset"
      ]
    },
    {
      "slug": "osc-color-query",
      "family": "OSC",
      "title": {
        "en": "OSC 10 / 11 / 12 query — Detect default fg / bg / cursor color (dark vs light)",
        "zh": "OSC 10 / 11 / 12 查询 — 探测默认前景 / 背景 / 光标色（深色对浅色）"
      },
      "shortDesc": {
        "en": "Ask the terminal for its current default foreground (10) / background (11) / cursor (12) color — the canonical way to auto-pick a dark or light theme.",
        "zh": "向终端查询当前默认前景（10）/ 背景（11）/ 光标（12）色 —— 自动选择深色或浅色主题的标准做法。"
      },
      "bytes": {
        "canonical": "\\x1b]10;?\\x07   (fg)   \\x1b]11;?\\x07   (bg)   \\x1b]12;?\\x07   (cursor)",
        "octal": "\\033]10;?\\007 / \\033]11;?\\007 / \\033]12;?\\007",
        "eEscape": "\\e]10;?\\a / \\e]11;?\\a / \\e]12;?\\a",
        "literal": "ESC ] 10 ; ? BEL   /   ESC ] 11 ; ? BEL   /   ESC ] 12 ; ? BEL",
        "hex": "1b 5d 31 30 3b 3f 07 / 1b 5d 31 31 3b 3f 07 / 1b 5d 31 32 3b 3f 07"
      },
      "description": {
        "en": "The OSC-color *query* form — substitute `?` for the color value in OSC 10 / 11 / 12 (defined under `osc-set-fg-bg` and `osc-cursor-color` respectively) and the terminal replies on stdin with the same OSC opcode and an XParseColor-shaped color: `\\x1b]<Ps>;rgb:RRRR/GGGG/BBBB\\x07` (the 16-bit-per-channel form is the canonical reply, even when the terminal stores 8-bit — pad each component by repeating: `#1e1e2e` → `rgb:1e1e/1e1e/2e2e`). The terminator matches whatever you sent — `BEL` (0x07) in → `BEL` out, `ST` (`\\x1b\\\\`) in → `ST` out.\n\n**Dark / light auto-detection** — this is the standard handshake vim's `'background'` autodetect, neovim's `bg=` probe, [atuin](https://github.com/atuinsh/atuin)'s theme picker, and `bat --color=auto` all use to choose a colorscheme without the user setting `COLORFGBG`. Algorithm:\n\n1. Save terminal mode, switch stdin to raw (no echo, no ICANON, VMIN=0, VTIME=1).\n2. Write `\\x1b]11;?\\x07`.\n3. Read until `BEL` (or `ST`) on stdin, parse out the three 16-bit hex components.\n4. Compute perceived luminance — `Y = 0.299·R + 0.587·G + 0.114·B` (Rec. 601) — and compare against `0.5 · 0xFFFF`. Below ⇒ dark theme, above ⇒ light. Some implementations use the WCAG `(R+R+B+G+G+G) / 6` shortcut for speed.\n5. Restore terminal mode. If no reply arrives within ~100 ms, fall back to the `$COLORFGBG` / `$TERM_PROGRAM` heuristic.\n\n**Why not just check `$COLORFGBG`** — only rxvt and a handful of derivatives set it; iTerm2 / Ghostty / WezTerm / Kitty / Windows Terminal don't. The OSC 11 query is the portable answer.\n\n**Caveat — OSC 12 cursor query** is the most spottily implemented of the three: xterm / iTerm2 / Kitty / WezTerm / Ghostty reply correctly; Linux console / cmd.exe ignore; macOS Terminal silently swallows; older gnome-terminal returns the *fg* color due to a long-standing parser bug. Treat the cursor-color reply as best-effort and fall back to the fg color when absent.",
        "zh": "OSC 颜色的*查询*形式 —— 把 OSC 10 / 11 / 12（分别参见 `osc-set-fg-bg` 与 `osc-cursor-color`）的颜色值改为 `?`，终端会在标准输入回复同一 OSC opcode 与一个 XParseColor 形状的颜色：`\\x1b]<Ps>;rgb:RRRR/GGGG/BBBB\\x07`（每通道 16 位的形式是规范回复，即使终端内部存 8 位也会重复扩展：`#1e1e2e` → `rgb:1e1e/1e1e/2e2e`）。终止符与发送时一致 —— 送 `BEL`（0x07）则回 `BEL`，送 `ST`（`\\x1b\\\\`）则回 `ST`。\n\n**深色 / 浅色自动检测** —— 这是 vim 的 `'background'` 自动检测、neovim 的 `bg=` 探测、[atuin](https://github.com/atuinsh/atuin) 的主题选择、`bat --color=auto` 等工具用来在用户未设 `COLORFGBG` 时选择配色方案的标准握手。算法：\n\n1. 保存终端模式，切到 raw（无回显、无 ICANON、VMIN=0、VTIME=1）。\n2. 发送 `\\x1b]11;?\\x07`。\n3. 在标准输入读到 `BEL`（或 `ST`），解析三段 16 位十六进制。\n4. 计算感知亮度 —— `Y = 0.299·R + 0.587·G + 0.114·B`（Rec. 601）—— 与 `0.5 · 0xFFFF` 比较。低于 ⇒ 深色主题，高于 ⇒ 浅色。一些实现用 WCAG 的 `(R+R+B+G+G+G) / 6` 快捷式提速。\n5. 恢复终端模式。若约 100 ms 内无回复，回退到 `$COLORFGBG` / `$TERM_PROGRAM` 启发式。\n\n**为何不直接看 `$COLORFGBG`** —— 只有 rxvt 与少数衍生终端会设；iTerm2 / Ghostty / WezTerm / Kitty / Windows Terminal 都不设。OSC 11 查询才是可移植答案。\n\n**注意 —— OSC 12 光标查询**在三者中实现最不齐：xterm / iTerm2 / Kitty / WezTerm / Ghostty 正确回复；Linux console / cmd.exe 忽略；macOS Terminal 静默吞掉；老版 gnome-terminal 因长期存在的解析器 bug 返回的是*前景*色。把光标色回复当作尽力而为，缺失时回退到前景色。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "Color slot: 10 = default foreground, 11 = default background, 12 = text cursor color.",
            "zh": "颜色槽位：10 = 默认前景、11 = 默认背景、12 = 文本光标颜色。"
          }
        },
        {
          "name": "?",
          "desc": {
            "en": "Query sentinel — replaces the color value to request the current setting instead of changing it.",
            "zh": "查询占位符 —— 替换颜色值，请求当前设置而非修改它。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (OSC 10 / 11 / 12 query)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Probe background brightness, exit 0 = dark, 1 = light.\\nold=$(stty -g); stty -echo raw min 0 time 1\\nprintf '\\033]11;?\\007' > /dev/tty\\nIFS= read -r -d $'\\\\a' reply < /dev/tty\\nstty \"$old\"\\nhex=${reply##*rgb:}\\nr=$((16#${hex%%/*})); g=${hex#*/}; g=$((16#${g%%/*})); b=$((16#${hex##*/}))\\ny=$(( (299*r + 587*g + 114*b) / 1000 ))\\n[ \"$y\" -lt 32767 ] && echo dark || echo light"
        },
        {
          "lang": "python",
          "code": "import sys, termios, tty, select, re\\nfd = sys.stdin.fileno(); old = termios.tcgetattr(fd); tty.setraw(fd)\\ntry:\\n    sys.stdout.write('\\x1b]11;?\\x07'); sys.stdout.flush()\\n    r, _, _ = select.select([fd], [], [], 0.2)\\n    if not r:\\n        print('no reply — falling back'); sys.exit(2)\\n    buf = b''\\n    while not buf.endswith(b'\\\\x07'):\\n        buf += sys.stdin.buffer.read1(64)\\n    m = re.search(rb'rgb:([0-9a-f]+)/([0-9a-f]+)/([0-9a-f]+)', buf, re.I)\\n    R, G, B = (int(x, 16) for x in m.groups())\\n    Y = (299*R + 587*G + 114*B) // 1000\\n    print('dark' if Y < 32767 else 'light')\\nfinally:\\n    termios.tcsetattr(fd, termios.TCSADRAIN, old)"
        },
        {
          "lang": "go",
          "code": "// Detect dark/light by querying OSC 11 (background).\\nimport (\\n    \\\"bufio\\\"; \\\"fmt\\\"; \\\"os\\\"; \\\"regexp\\\"; \\\"strconv\\\"\\n    \\\"golang.org/x/term\\\"\\n)\\nfunc isDark() bool {\\n    fd := int(os.Stdin.Fd())\\n    st, _ := term.MakeRaw(fd); defer term.Restore(fd, st)\\n    fmt.Print(\\\"\\\\x1b]11;?\\\\x07\\\")\\n    rd := bufio.NewReader(os.Stdin)\\n    line, _ := rd.ReadString(0x07)\\n    m := regexp.MustCompile(`rgb:([0-9a-fA-F]+)/([0-9a-fA-F]+)/([0-9a-fA-F]+)`).FindStringSubmatch(line)\\n    r, _ := strconv.ParseInt(m[1], 16, 32)\\n    g, _ := strconv.ParseInt(m[2], 16, 32)\\n    b, _ := strconv.ParseInt(m[3], 16, 32)\\n    return (299*r + 587*g + 114*b)/1000 < 32767\\n}"
        },
        {
          "lang": "javascript",
          "code": "// Node — assumes raw stdin and a TTY.\\nprocess.stdin.setRawMode(true); process.stdin.resume();\\nprocess.stdout.write('\\\\x1b]11;?\\\\x07');\\nlet buf = '';\\nprocess.stdin.on('data', chunk => {\\n    buf += chunk.toString();\\n    if (!buf.endsWith('\\\\x07')) return;\\n    process.stdin.setRawMode(false); process.stdin.pause();\\n    const [, r, g, b] = buf.match(/rgb:([0-9a-f]+)\\\\/([0-9a-f]+)\\\\/([0-9a-f]+)/i);\\n    const Y = (299 * parseInt(r, 16) + 587 * parseInt(g, 16) + 114 * parseInt(b, 16)) / 1000;\\n    console.log(Y < 0x7fff ? 'dark' : 'light');\\n});"
        },
        {
          "lang": "c",
          "code": "/* Minimal OSC 11 query — error handling omitted. */\\n#include <stdio.h>\\n#include <termios.h>\\n#include <unistd.h>\\nint main(void) {\\n    struct termios old, raw; tcgetattr(0, &old); raw = old;\\n    raw.c_lflag &= ~(ICANON|ECHO); raw.c_cc[VMIN] = 0; raw.c_cc[VTIME] = 2;\\n    tcsetattr(0, TCSANOW, &raw);\\n    printf(\\\"\\\\x1b]11;?\\\\x07\\\"); fflush(stdout);\\n    char buf[128]; int n = read(0, buf, sizeof buf - 1);\\n    tcsetattr(0, TCSANOW, &old);\\n    if (n > 0) { buf[n] = 0; printf(\\\"reply: %s\\\\n\\\", buf); }\\n    return 0;\\n}"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "osc-set-fg-bg",
        "osc-cursor-color",
        "osc-reset-fg-bg",
        "osc-palette-query"
      ]
    },
    {
      "slug": "osc-palette-query",
      "family": "OSC",
      "title": {
        "en": "OSC 4 query — Read 256-color palette index (`\\x1b]4;<n>;?\\x07`)",
        "zh": "OSC 4 查询 — 读取 256 色调色板索引（`\\x1b]4;<n>;?\\x07`）"
      },
      "shortDesc": {
        "en": "Ask the terminal what RGB value is currently bound to palette index `n` (0–255) — used by theme inspectors, screenshot tools, and palette-migration scripts.",
        "zh": "向终端查询调色板索引 `n`（0–255）当前绑定的 RGB 值 —— 主题检查器、截屏工具与调色板迁移脚本常用。"
      },
      "bytes": {
        "canonical": "\\x1b]4;<n>;?\\x07",
        "octal": "\\033]4;<n>;?\\007",
        "eEscape": "\\e]4;<n>;?\\a",
        "literal": "ESC ] 4 ; n ; ? BEL",
        "hex": "1b 5d 34 3b ... 3b 3f 07"
      },
      "description": {
        "en": "The *query* counterpart to OSC 4 (see `osc-set-palette` for the set side). Send `\\x1b]4;<n>;?\\x07` where `<n>` is the palette index 0–255 and the terminal replies on stdin with `\\x1b]4;<n>;rgb:RRRR/GGGG/BBBB\\x07` — same XParseColor-shaped, 16-bit-per-channel form used by the OSC 10 / 11 / 12 query (see `osc-color-query`). Multiple indices can be batched in one request — `\\x1b]4;0;?;1;?;2;?\\x07` returns three replies back-to-back.\n\n**Use cases**:\n- **Theme inspectors / dotfile generators** — dump the live 16 ANSI colors plus the 6×6×6 cube to YAML / JSON so a screenshot-faithful clone can be reproduced on a fresh machine.\n- **Screenshot / asciinema-style recorders** — capture the running palette so playback under a different theme still reproduces the original visuals.\n- **Palette migration scripts** — read out the current colors before applying a new theme, so the old one can be restored verbatim (a defensive `osc-reset-palette` only restores the *built-in* defaults, not whatever the user customised).\n- **CI test runners** — assert that a custom OSC 4 set actually took effect, by querying back the index immediately afterwards.\n\n**Reply parsing** — the index in the reply matches the index in the request, so when batching multiple `;<n>;?` pairs you must demultiplex by `<n>` (replies are not guaranteed to arrive in send order on every terminal, though most do). Time-out the read at ~100 ms per index and treat missing replies as 'index not customised — defer to ANSI/256 defaults'.\n\n**Caveats** — Linux console / Windows cmd ignore the query and reply nothing (timeout-and-fall-back is the correct strategy). macOS Terminal replies only for indices 0–15. Modern emulators (xterm / iTerm2 / Kitty / Alacritty / WezTerm / Ghostty / Konsole) all reply for the full 0–255 range.",
        "zh": "OSC 4 的*查询*对偶（设置形式参见 `osc-set-palette`）。发送 `\\x1b]4;<n>;?\\x07`，其中 `<n>` 为 0–255 的调色板索引，终端在标准输入回复 `\\x1b]4;<n>;rgb:RRRR/GGGG/BBBB\\x07` —— 与 OSC 10 / 11 / 12 查询（见 `osc-color-query`）相同的 XParseColor 形状、每通道 16 位形式。一次请求可批量多个索引 —— `\\x1b]4;0;?;1;?;2;?\\x07` 会连续返回三条回复。\n\n**用途**：\n- **主题检查器 / dotfile 生成器** —— 把当前 16 个 ANSI 色加上 6×6×6 立方导出为 YAML / JSON，方便在新机上做到截屏级一致复刻。\n- **截屏 / asciinema 录制器** —— 捕获运行时调色板，使回放在不同主题下仍能重现原始视觉。\n- **调色板迁移脚本** —— 在套用新主题前读出当前颜色，以便逐字回滚（防御性的 `osc-reset-palette` 只能恢复*内置*默认，无法恢复用户自定义）。\n- **CI 测试运行器** —— 自定义 OSC 4 后立即查询同一索引，断言它确实生效。\n\n**回复解析** —— 回复中的索引与请求中的索引相同，因此批量发送多对 `;<n>;?` 时需按 `<n>` 解复用（并非所有终端都保证按发送顺序回复，多数会，但不可依赖）。每索引读超时 ~100 ms，缺失视为「未自定义 —— 退到 ANSI / 256 默认」。\n\n**注意** —— Linux console / Windows cmd 忽略查询无回复（超时回退是正确策略）。macOS Terminal 仅对索引 0–15 回复。现代模拟器（xterm / iTerm2 / Kitty / Alacritty / WezTerm / Ghostty / Konsole）覆盖整段 0–255。"
      },
      "parameters": [
        {
          "name": "n",
          "desc": {
            "en": "Palette index 0–255 (0–7 = basic ANSI, 8–15 = bright ANSI, 16–231 = 6×6×6 cube, 232–255 = grayscale ramp).",
            "zh": "调色板索引 0–255（0–7 = 基础 ANSI、8–15 = 亮 ANSI、16–231 = 6×6×6 立方、232–255 = 灰阶）。"
          }
        },
        {
          "name": "?",
          "desc": {
            "en": "Query sentinel — replaces the spec to request the current binding instead of changing it.",
            "zh": "查询占位符 —— 替换颜色规范，请求当前绑定而非修改。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (OSC 4 query)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Read palette index 1 (red) and print it.\\nold=$(stty -g); stty -echo raw min 0 time 1\\nprintf '\\033]4;1;?\\007' > /dev/tty\\nIFS= read -r -d $'\\\\a' reply < /dev/tty\\nstty \"$old\"\\necho \"palette[1] = ${reply##*rgb:}\""
        },
        {
          "lang": "python",
          "code": "# Dump first 16 ANSI colors as a Python dict.\\nimport sys, termios, tty, select, re\\nfd = sys.stdin.fileno(); old = termios.tcgetattr(fd); tty.setraw(fd)\\ntry:\\n    palette = {}\\n    for i in range(16):\\n        sys.stdout.write(f'\\x1b]4;{i};?\\x07'); sys.stdout.flush()\\n        if select.select([fd], [], [], 0.1)[0]:\\n            buf = b''\\n            while not buf.endswith(b'\\\\x07'):\\n                buf += sys.stdin.buffer.read1(64)\\n            m = re.search(rb'rgb:([0-9a-f]+)/([0-9a-f]+)/([0-9a-f]+)', buf, re.I)\\n            palette[i] = '#' + ''.join(g.decode()[:2] for g in m.groups())\\n    print(palette)\\nfinally:\\n    termios.tcsetattr(fd, termios.TCSADRAIN, old)"
        },
        {
          "lang": "go",
          "code": "// Query a single palette index. (raw stdin setup elided — see osc-color-query)\\nfor _, idx := range []int{0, 1, 2, 3, 4, 5, 6, 7} {\\n    fmt.Printf(\\\"\\\\x1b]4;%d;?\\\\x07\\\", idx)\\n    // read reply with bufio.Reader.ReadString(0x07), parse rgb:RRRR/GGGG/BBBB\\n}"
        },
        {
          "lang": "javascript",
          "code": "// Batch query indices 0..15 in one write.\\nprocess.stdin.setRawMode(true); process.stdin.resume();\\nconst req = Array.from({length: 16}, (_, i) => `4;${i};?`).join(';');\\nprocess.stdout.write(`\\\\x1b]${req}\\\\x07`);\\nlet buf = '';\\nprocess.stdin.on('data', chunk => {\\n    buf += chunk.toString();\\n    const matches = [...buf.matchAll(/\\\\]4;(\\\\d+);rgb:([0-9a-f]+)\\\\/([0-9a-f]+)\\\\/([0-9a-f]+)\\\\x07/gi)];\\n    if (matches.length === 16) {\\n        process.stdin.setRawMode(false); process.stdin.pause();\\n        console.log(matches.map(m => [+m[1], `#${m[2].slice(0,2)}${m[3].slice(0,2)}${m[4].slice(0,2)}`]));\\n    }\\n});"
        },
        {
          "lang": "c",
          "code": "/* Query a single palette index — read until BEL. */\\nprintf(\\\"\\\\x1b]4;%d;?\\\\x07\\\", index); fflush(stdout);\\nchar buf[128]; int n = read(0, buf, sizeof buf - 1);\\nif (n > 0) { buf[n] = 0; /* parse rgb:RRRR/GGGG/BBBB out of buf */ }"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "osc-set-palette",
        "osc-reset-palette",
        "osc-color-query",
        "sgr-fg-256"
      ]
    },
    {
      "slug": "decscusr-query",
      "family": "DCS",
      "title": {
        "en": "DECSCUSR query via DECRQSS — Read the current cursor shape (`\\x1bP$q q\\x1b\\\\`)",
        "zh": "通过 DECRQSS 查询 DECSCUSR — 读取当前光标形状（`\\x1bP$q q\\x1b\\\\`）"
      },
      "shortDesc": {
        "en": "Round-trip the cursor-shape parameter — query side of DECSCUSR via DECRQSS, terminal replies with the current `Ps SP q` setting.",
        "zh": "光标形状参数的查询往返 —— 通过 DECRQSS 查询 DECSCUSR，终端回复当前 `Ps SP q` 设置。"
      },
      "bytes": {
        "canonical": "\\x1bP$q q\\x1b\\\\",
        "octal": "\\033P$q q\\033\\\\",
        "eEscape": "\\eP$q q\\e\\\\",
        "literal": "ESC P $ q SP q ESC \\",
        "hex": "1b 50 24 71 20 71 1b 5c"
      },
      "description": {
        "en": "DECSCUSR (`dec-cursor-shape`) defines a *setter* — `\\x1b[<Ps> SP q` to change cursor shape. There is no symmetrical setter-query (`?`-style) opcode the way OSC 10 / 11 / 12 supports; instead, the **query side** is layered on top of DECRQSS (`dcs-decrqss`): request the *settable* function whose final byte is `SP q` and let the terminal reply with its current state.\n\n**Request** — `\\x1bP$q q\\x1b\\\\`. Parse as: DCS frame (`\\x1bP`), intermediate `$` + final `q` (DECRQSS opcode), payload `\" q\"` (the bytes that uniquely identify the DECSCUSR setter — its `SP` intermediate plus its `q` final), terminated by ST (`\\x1b\\\\`).\n\n**Reply** — `\\x1bP1$r<Ps> q\\x1b\\\\` on success, where `<Ps>` is the current parameter (`0` user-default through `6` steady bar — see `dec-cursor-shape` for the full table). The leading `1` is DECRQSS's success indicator (`0` means 'invalid request'); the `$r` is its reply-frame intermediate+final.\n\n**Why this matters** — TUIs that save-and-restore the cursor shape around modal pop-ups (fuzzy finders, picker overlays in tmux / fzf / atuin / neovim) need the *original* shape to restore. Without this query, the only options are blindly resetting to `0` (user default, but that discards a parent app's override) or hard-coding a guess. The DECRQSS round-trip lets the popup capture and faithfully replay.\n\n**Example handshake** — bash with timeout: `printf '\\x1bP$q q\\x1b\\\\' > /dev/tty; IFS= read -r -d '\\\\' -t 0.1 reply < /dev/tty; echo \"$reply\" | grep -oE 'P1\\\\$r[0-9]+'` returns `P1$r6` if the cursor is a steady bar.\n\n**Caveats** — xterm / iTerm2 / Kitty / WezTerm / Ghostty / Alacritty / Konsole reply; Linux console / cmd.exe / macOS Terminal do not. Always implement a ~100 ms timeout and fall back to `Ps = 0` (user default) when no reply arrives. Some emulators reply `\\x1bP0$r\\x1b\\\\` (DECRQSS 'invalid') if cursor shape was never explicitly set — treat that as 'use default'.",
        "zh": "DECSCUSR（`dec-cursor-shape`）定义的是*设置器* —— `\\x1b[<Ps> SP q` 用于变更光标形状。它没有像 OSC 10 / 11 / 12 那样对称的 `?` 风格查询 opcode；**查询侧**是叠加在 DECRQSS（`dcs-decrqss`）之上的：向终端请求那个末字节为 `SP q` 的可设置函数，让终端回复当前状态。\n\n**请求** —— `\\x1bP$q q\\x1b\\\\`。解析：DCS 帧（`\\x1bP`）、中间字节 `$` + 末字节 `q`（DECRQSS opcode）、负载 `\" q\"`（唯一标识 DECSCUSR 设置器的字节 —— 其 `SP` 中间字节加 `q` 末字节）、以 ST（`\\x1b\\\\`）结束。\n\n**回复** —— 成功时为 `\\x1bP1$r<Ps> q\\x1b\\\\`，`<Ps>` 即当前参数（`0` 用户默认至 `6` 实心竖线 —— 完整表见 `dec-cursor-shape`）。前导 `1` 是 DECRQSS 的成功指示（`0` 表「请求无效」）；`$r` 是其回复帧的中间字节+末字节。\n\n**为何重要** —— 在模态弹层（fzf / atuin / tmux 中 neovim 的浮窗）周围保存与还原光标形状的 TUI 必须知道*原始*形状才能还原。没有此查询，只能盲目重置为 `0`（用户默认 —— 但会丢掉父程序的覆盖）或硬编码猜测。DECRQSS 的往返让弹层得以捕获并忠实回放。\n\n**示例握手** —— bash 带超时：`printf '\\x1bP$q q\\x1b\\\\' > /dev/tty; IFS= read -r -d '\\\\' -t 0.1 reply < /dev/tty; echo \"$reply\" | grep -oE 'P1\\\\$r[0-9]+'` —— 光标为实心竖线时返回 `P1$r6`。\n\n**注意** —— xterm / iTerm2 / Kitty / WezTerm / Ghostty / Alacritty / Konsole 会回复；Linux console / cmd.exe / macOS Terminal 不会。务必加约 100 ms 超时，缺失时回退到 `Ps = 0`（用户默认）。若光标形状从未显式设置过，部分模拟器会回 `\\x1bP0$r\\x1b\\\\`（DECRQSS「无效」）—— 同样按「用默认」处理。"
      },
      "parameters": [
        {
          "name": "payload",
          "desc": {
            "en": "The bytes identifying the setter being queried — here, `\" q\"` (SP + q), the intermediate + final of DECSCUSR.",
            "zh": "被查询的设置器标识字节 —— 这里为 `\" q\"`（SP + q），即 DECSCUSR 的中间字节 + 末字节。"
          }
        },
        {
          "name": "reply Ps",
          "desc": {
            "en": "Current shape: 0 = user default, 1 = blink block, 2 = steady block, 3 = blink underline, 4 = steady underline, 5 = blink bar, 6 = steady bar.",
            "zh": "当前形状：0 = 用户默认、1 = 闪烁方块、2 = 实心方块、3 = 闪烁下划线、4 = 实心下划线、5 = 闪烁竖线、6 = 实心竖线。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (DECRQSS + DECSCUSR)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Capture current cursor shape (raw + timeout).\\nold=$(stty -g); stty -echo raw min 0 time 1\\nprintf '\\033P$q q\\033\\\\\\\\' > /dev/tty\\nIFS= read -r -d '\\\\\\\\' reply < /dev/tty\\nstty \"$old\"\\nshape=$(echo \"$reply\" | sed -nE 's/.*P1\\\\$r([0-9]+).*/\\\\1/p')\\necho \"current cursor: ${shape:-default}\""
        },
        {
          "lang": "python",
          "code": "import sys, termios, tty, re\\ndef cursor_shape():\\n    fd = sys.stdin.fileno(); old = termios.tcgetattr(fd); tty.setraw(fd)\\n    try:\\n        sys.stdout.write('\\x1bP$q q\\x1b\\\\\\\\'); sys.stdout.flush()\\n        buf = b''\\n        while b'\\\\x1b\\\\\\\\' not in buf:\\n            buf += sys.stdin.buffer.read1(64)\\n        m = re.search(rb'P1\\\\$r(\\\\d+)', buf)\\n        return int(m.group(1)) if m else 0\\n    finally:\\n        termios.tcsetattr(fd, termios.TCSADRAIN, old)"
        },
        {
          "lang": "go",
          "code": "// Save shape -> open popup with bar cursor -> restore.\\nshape := queryCursorShape()                 // via DECRQSS round-trip\\nfmt.Print(\\\"\\\\x1b[6 q\\\")                       // bar for popup\\ndefer fmt.Printf(\\\"\\\\x1b[%d q\\\", shape)        // restore on exit"
        },
        {
          "lang": "javascript",
          "code": "// Query, then echo a description.\\nprocess.stdin.setRawMode(true); process.stdin.resume();\\nprocess.stdout.write('\\\\x1bP$q q\\\\x1b\\\\\\\\');\\nlet buf = '';\\nprocess.stdin.on('data', chunk => {\\n    buf += chunk.toString();\\n    if (!buf.includes('\\\\x1b\\\\\\\\')) return;\\n    process.stdin.setRawMode(false); process.stdin.pause();\\n    const m = buf.match(/P1\\\\$r(\\\\d+)/);\\n    const names = ['default','blink block','steady block','blink underline','steady underline','blink bar','steady bar'];\\n    console.log(names[m ? +m[1] : 0]);\\n});"
        },
        {
          "lang": "c",
          "code": "/* Round-trip the cursor shape — minimal raw read. */\\nprintf(\\\"\\\\x1bP$q q\\\\x1b\\\\\\\\\\\"); fflush(stdout);\\nchar buf[64]; int n = read(0, buf, sizeof buf - 1);\\nint shape = 0;\\nif (n > 0) { buf[n] = 0; sscanf(strstr(buf, \\\"P1$r\\\"), \\\"P1$r%d\\\", &shape); }"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "dec-cursor-shape",
        "dcs-decrqss",
        "dcs-decrsps",
        "cursor-visibility"
      ]
    },
    {
      "slug": "csi-da2-decoder",
      "family": "CSI",
      "title": {
        "en": "Secondary DA reply decoder — `CSI > Pp ; Pv ; Pc c` model / firmware / cart",
        "zh": "副 DA 回复解码器 — `CSI > Pp ; Pv ; Pc c` 型号 / 固件 / 卡带"
      },
      "shortDesc": {
        "en": "Decoder reference for the secondary Device Attributes reply — what each Pp model code means and how kitty / wezterm / alacritty / iTerm2 / Ghostty encode their version in Pv.",
        "zh": "副 Device Attributes 回复的解码参考 —— 每个 Pp 型号码的含义，以及 kitty / wezterm / alacritty / iTerm2 / Ghostty 如何把自身版本编入 Pv。"
      },
      "bytes": {
        "canonical": "\\x1b[>Pp;Pv;Pcc",
        "octal": "\\033[>0;276;0c",
        "eEscape": "\\e[>0;276;0c",
        "literal": "ESC [ > Pp ; Pv ; Pc c",
        "hex": "1b 5b 3e ... 63"
      },
      "description": {
        "en": "The *reply* shape for secondary DA (request side documented under `csi-da`). The application sends `\\x1b[>c` (or `\\x1b[>0c`); the terminal answers `\\x1b[>Pp;Pv;Pc c` on stdin. TUIs branch on **Pp** to pick a feature set and on **Pv** to enable per-version workarounds — this page is the lookup table.\n\n**Pp — model code**:\n\n- `0` — DEC VT100 (or terminal claiming VT100 compatibility — common from minimal embedded emulators).\n- `1` — DEC VT220.\n- `2` — DEC VT240 / VT241.\n- `18` — DEC VT330.\n- `19` — DEC VT340.\n- `24` — DEC VT320.\n- `28` — DEC VT330 (alternative).\n- `32` — Tek 4014.\n- `41` — DEC VT420.\n- `61` — DEC VT510 (and most **xterm-class** emulators, including **xterm itself** patch ≥ 95).\n- `64` — DEC VT520.\n- `65` — DEC VT525 (and **Kitty**, **Alacritty**, **WezTerm**, **iTerm2** all use 65 as a 'modern xterm-class' marker by convention; **Ghostty** uses 65 too).\n- `82` — rxvt.\n- `83` — Eterm.\n- `84` — sun terminal.\n- `85` — rxvt-unicode (urxvt).\n\n**Pv — firmware / version**:\n\n- DEC hardware: literal ROM version (e.g. xterm patch level → Pv = 95+).\n- **xterm**: Pv is the xterm patch level — `\\x1b[>61;392;0c` means xterm patch 392.\n- **Kitty**: Pv encodes the version — Pv = `major*10000 + minor*100 + patch`, so 0.41.1 → 4101 (older versions used base-100, check current behaviour).\n- **WezTerm**: Pv is a build year-month — e.g. 4604 ≈ 2024.10 build.\n- **Alacritty**: Pv is fixed at `0` (Alacritty doesn't expose version this way; use XTVERSION instead — see `xtversion`).\n- **iTerm2**: Pv is fixed at `95` (frozen at the original xterm-95 marker for compatibility — use XTVERSION for the real version).\n- **Ghostty**: Pv is the build patch level.\n- **Windows Terminal**: Pv is the WT version major*100 + minor (e.g. 0 for 1.0, 18 for 1.18).\n\n**Pc — cartridge / serial**:\n- DEC hardware: ROM cartridge number, almost always `0` on serial-only models.\n- Software emulators: always `0`.\n- Treat any non-zero Pc as informational only — no portable meaning.\n\n**Recommended consumer pattern**:\n```\nmatch (Pp, Pv) {\n    (65, v) if v >= 1000 => 'modern xterm-class'    # Kitty / WezTerm / Alacritty / iTerm2\n    (64, _)              => 'VT520 or VT520-compat'\n    (61, _)              => 'xterm or xterm-class'\n    (41, _)              => 'VT420 or VT420-compat'\n    (1,  _)              => 'VT220 or VT220-compat'\n    (0,  _)              => 'VT100 or minimal'\n    _                    => 'unknown — feature-detect via XTVERSION or DECRQM'\n}\n```\n\n**Don't trust DA2 for fine-grained feature detection** — Pp coverage is coarse and Pv encoding is per-emulator. For 'does this terminal support feature X' use **XTVERSION** (`xtversion`) for the emulator name + version, then `DECRQM` (`decrqm`) to query the specific mode bit. Use DA2 only for the broad model bucket.",
        "zh": "副 DA 的*回复*形状（请求侧参见 `csi-da`）。程序发送 `\\x1b[>c`（或 `\\x1b[>0c`）；终端在标准输入回复 `\\x1b[>Pp;Pv;Pc c`。TUI 通常用 **Pp** 选特性集，用 **Pv** 启用版本针对性的 workaround —— 本页即是查表参考。\n\n**Pp —— 型号码**：\n\n- `0` — DEC VT100（或声称 VT100 兼容的终端 —— 常见于极简嵌入式模拟器）。\n- `1` — DEC VT220。\n- `2` — DEC VT240 / VT241。\n- `18` — DEC VT330。\n- `19` — DEC VT340。\n- `24` — DEC VT320。\n- `28` — DEC VT330（替代值）。\n- `32` — Tek 4014。\n- `41` — DEC VT420。\n- `61` — DEC VT510（以及多数 **xterm 类**模拟器，含 **xterm 自身** patch ≥ 95）。\n- `64` — DEC VT520。\n- `65` — DEC VT525（**Kitty**、**Alacritty**、**WezTerm**、**iTerm2** 按惯例都用 65 作「现代 xterm 类」标记；**Ghostty** 同样用 65）。\n- `82` — rxvt。\n- `83` — Eterm。\n- `84` — sun terminal。\n- `85` — rxvt-unicode（urxvt）。\n\n**Pv —— 固件 / 版本**：\n\n- DEC 硬件：实际 ROM 版本（如 xterm patch level → Pv = 95+）。\n- **xterm**：Pv 为 xterm patch level —— `\\x1b[>61;392;0c` 表示 xterm patch 392。\n- **Kitty**：Pv 编码版本 —— Pv = `主*10000 + 次*100 + 修订`，故 0.41.1 → 4101（旧版用 100 进制，请以当前行为为准）。\n- **WezTerm**：Pv 为年-月构建号 —— 如 4604 ≈ 2024.10。\n- **Alacritty**：Pv 固定为 `0`（Alacritty 不通过此处暴露版本；改用 XTVERSION，见 `xtversion`）。\n- **iTerm2**：Pv 固定为 `95`（兼容性冻结在最初的 xterm-95 标记上；真实版本用 XTVERSION）。\n- **Ghostty**：Pv 为构建 patch level。\n- **Windows Terminal**：Pv 为 WT 版本 主*100 + 次（如 1.0 = 0，1.18 = 18）。\n\n**Pc —— 卡带 / 序列号**：\n- DEC 硬件：ROM 卡带号，仅串口型几乎全为 `0`。\n- 软件模拟器：恒为 `0`。\n- 非零 Pc 仅作信息用 —— 无可移植语义。\n\n**推荐消费模式**：\n```\nmatch (Pp, Pv) {\n    (65, v) if v >= 1000 => 'modern xterm-class'    # Kitty / WezTerm / Alacritty / iTerm2\n    (64, _)              => 'VT520 or VT520-compat'\n    (61, _)              => 'xterm or xterm-class'\n    (41, _)              => 'VT420 or VT420-compat'\n    (1,  _)              => 'VT220 or VT220-compat'\n    (0,  _)              => 'VT100 or minimal'\n    _                    => 'unknown — feature-detect via XTVERSION or DECRQM'\n}\n```\n\n**不要用 DA2 做细粒度特性检测** —— Pp 覆盖很粗、Pv 编码因模拟器而异。「此终端是否支持特性 X」请用 **XTVERSION**（`xtversion`）拿模拟器名与版本，再以 `DECRQM`（`decrqm`）查询具体模式位。DA2 只用于粗粒度的型号分桶。"
      },
      "parameters": [
        {
          "name": "Pp",
          "desc": {
            "en": "Model code — 0 VT100, 1 VT220, 41 VT420, 61 xterm-class, 64 VT520, 65 modern xterm-class (Kitty/WezTerm/Alacritty/iTerm2/Ghostty), 82 rxvt, 85 urxvt.",
            "zh": "型号码 —— 0 VT100、1 VT220、41 VT420、61 xterm 类、64 VT520、65 现代 xterm 类（Kitty/WezTerm/Alacritty/iTerm2/Ghostty）、82 rxvt、85 urxvt。"
          }
        },
        {
          "name": "Pv",
          "desc": {
            "en": "Firmware / version — encoding is per-emulator (xterm patch, Kitty major*10000+minor*100+patch, WezTerm year-month build, Alacritty=0, iTerm2=95). Use XTVERSION for portable version detection.",
            "zh": "固件 / 版本 —— 编码因模拟器而异（xterm patch、Kitty 主*10000+次*100+修订、WezTerm 年-月构建、Alacritty=0、iTerm2=95）。可移植版本检测请用 XTVERSION。"
          }
        },
        {
          "name": "Pc",
          "desc": {
            "en": "Cartridge / serial — almost always 0 on software emulators; informational only.",
            "zh": "卡带 / 序列号 —— 软件模拟器几乎恒为 0；仅作信息用。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (Secondary DA reply) / DEC VT320+ DA2",
      "examples": [
        {
          "lang": "bash",
          "code": "# Ask + decode model bucket.\\nold=$(stty -g); stty -echo raw min 0 time 1\\nprintf '\\033[>c' > /dev/tty\\nIFS= read -r -d c reply < /dev/tty\\nstty \"$old\"\\npp=$(echo \"$reply\" | sed -nE 's/.*>([0-9]+);.*/\\\\1/p')\\ncase \"$pp\" in\\n    0)   echo 'VT100 / minimal' ;;\\n    1)   echo 'VT220-compat' ;;\\n    41)  echo 'VT420-compat' ;;\\n    61)  echo 'xterm-class' ;;\\n    65)  echo 'modern xterm-class (Kitty/WezTerm/Alacritty/iTerm2/Ghostty)' ;;\\n    82)  echo 'rxvt' ;;\\n    85)  echo 'urxvt' ;;\\n    *)   echo \"unknown model: $pp\" ;;\\nesac"
        },
        {
          "lang": "python",
          "code": "import sys, termios, tty, re\\nMODELS = {0:'VT100/minimal',1:'VT220',41:'VT420',61:'xterm-class',64:'VT520',65:'modern xterm-class',82:'rxvt',85:'urxvt'}\\nfd = sys.stdin.fileno(); old = termios.tcgetattr(fd); tty.setraw(fd)\\ntry:\\n    sys.stdout.write('\\x1b[>c'); sys.stdout.flush()\\n    buf = b''\\n    while not buf.endswith(b'c'): buf += sys.stdin.buffer.read1(64)\\n    m = re.search(rb'>(\\d+);(\\d+);(\\d+)c', buf)\\n    pp, pv, pc = (int(x) for x in m.groups())\\n    print(f'model={MODELS.get(pp, \"unknown\")} ({pp}); version={pv}; cart={pc}')\\nfinally:\\n    termios.tcsetattr(fd, termios.TCSADRAIN, old)"
        },
        {
          "lang": "go",
          "code": "// Decode the (Pp, Pv) bucket — Pc is informational.\\nvar models = map[int]string{0:\\\"VT100\\\",1:\\\"VT220\\\",41:\\\"VT420\\\",61:\\\"xterm-class\\\",64:\\\"VT520\\\",65:\\\"modern xterm-class\\\",82:\\\"rxvt\\\",85:\\\"urxvt\\\"}\\nfunc decodeDA2(reply string) (string, int) {\\n    var pp, pv, pc int\\n    fmt.Sscanf(reply, \\\"\\\\x1b[>%d;%d;%dc\\\", &pp, &pv, &pc)\\n    return models[pp], pv\\n}"
        },
        {
          "lang": "javascript",
          "code": "// Parse a DA2 reply string into a labelled bucket.\\nfunction decodeDA2(reply) {\\n    const m = reply.match(/>(\\d+);(\\d+);(\\d+)c/);\\n    if (!m) return null;\\n    const [pp, pv, pc] = m.slice(1).map(Number);\\n    const models = {0:'VT100',1:'VT220',41:'VT420',61:'xterm-class',64:'VT520',65:'modern xterm-class',82:'rxvt',85:'urxvt'};\\n    return { model: models[pp] || `unknown(${pp})`, version: pv, cartridge: pc };\\n}"
        },
        {
          "lang": "c",
          "code": "/* Decode a DA2 reply already buffered in `reply`. */\\nint pp = 0, pv = 0, pc = 0;\\nif (sscanf(reply, \\\"\\\\x1b[>%d;%d;%dc\\\", &pp, &pv, &pc) == 3) {\\n    /* branch on pp / pv */\\n}"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "partial",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-da",
        "xtversion",
        "decrqm",
        "csi-private-dsr"
      ]
    },
    {
      "slug": "xtsave-xtrestore",
      "family": "CSI",
      "title": {
        "en": "XTSAVE / XTRESTORE — Save / restore DEC private mode (`CSI ? Pm s` / `CSI ? Pm r`)",
        "zh": "XTSAVE / XTRESTORE — 保存 / 恢复 DEC 私有模式（`CSI ? Pm s` / `CSI ? Pm r`）"
      },
      "shortDesc": {
        "en": "Stash one or more DEC private mode states on a stack, then restore them later — the foundation tmux / screen / fzf use to safely toggle mouse / alt-screen / paste modes without trampling user prefs.",
        "zh": "把一个或多个 DEC 私有模式状态压栈，稍后恢复 —— tmux / screen / fzf 用以安全地切换鼠标 / 备用屏 / 粘贴模式而不破坏用户设置的基础机制。"
      },
      "bytes": {
        "canonical": "\\x1b[?<Pm>s   (save)   \\x1b[?<Pm>r   (restore)",
        "octal": "\\033[?1000s / \\033[?1000r",
        "eEscape": "\\e[?1000s / \\e[?1000r",
        "literal": "ESC [ ? Pm s   /   ESC [ ? Pm r",
        "hex": "1b 5b 3f ... 73   /   1b 5b 3f ... 72"
      },
      "description": {
        "en": "The `?` prefix puts `s` and `r` into the **DEC private mode** namespace (without the prefix, `CSI Ps ; Ps s` is DECSLRM — see `decslrm` — and `CSI Ps ; Ps r` is DECSTBM — see `decstbm`). With the prefix, `Pm` is one or more semicolon-separated DEC private mode numbers (the same numbers you'd use with `CSI ? Pm h/l` to set/reset them).\n\n- **XTSAVE** (`\\x1b[?<Pm>s`) — push the *current* state of each named mode onto a per-mode stack inside the terminal. Stack depth is per-mode and typically 1-deep (a second XTSAVE overwrites the first); xterm and a few others maintain a true stack of arbitrary depth.\n- **XTRESTORE** (`\\x1b[?<Pm>r`) — pop and apply each named mode's saved state. If the mode was never saved, XTRESTORE is a no-op for that mode.\n- Multiple modes per call: `\\x1b[?1000;1002;1006;1049s` saves the four mouse-and-altscreen modes in one round-trip; the symmetric `\\x1b[?1000;1002;1006;1049r` restores them.\n\n**Why this exists** — interactive tools like tmux, GNU screen, fzf, atuin, neovim's `:terminal`, and lazygit need to temporarily change mouse-tracking, alt-screen, bracketed-paste, focus-event, etc. without leaving the user with broken settings if they crash or the user backgrounds them. The XTSAVE / XTRESTORE pair is the *non-destructive* way to do this — capture the user's preference, swap to the tool's preference, and roll back on exit regardless of what the user originally had.\n\n**Common save / restore set** (the 'tmux mouse set'): `?1000` (X10 mouse), `?1002` (cell motion mouse), `?1003` (all-motion mouse), `?1006` (SGR mouse encoding), `?1015` (urxvt mouse encoding), `?1049` (alt-screen with cursor save). Bracketed paste adds `?2004`; focus events `?1004`.\n\n**Relationship to `?1049`** — `\\x1b[?1049h/l` is itself a *compound* sequence that effectively combines `?1047` (alt-screen) + `?1048` (cursor save) + an implicit save-on-enter / restore-on-exit of the alt-screen contents. Everywhere else, the explicit XTSAVE / XTRESTORE pair is what you should reach for. Don't double-wrap `?1049` in XTSAVE / XTRESTORE — it already handles the round-trip itself.\n\n**Caveats** — xterm / iTerm2 / Kitty / WezTerm / Ghostty / Alacritty / Konsole / Windows Terminal all implement; Linux console implements partially (only the most common modes); cmd.exe doesn't. Stack depth varies — assume 1 and don't nest saves. macOS Terminal's implementation is the spottiest; test against it specifically if you target it.",
        "zh": "前缀 `?` 把 `s` 和 `r` 置入 **DEC 私有模式**命名空间（无前缀时 `CSI Ps ; Ps s` 为 DECSLRM —— 见 `decslrm` —— 而 `CSI Ps ; Ps r` 为 DECSTBM —— 见 `decstbm`）。带前缀后，`Pm` 为一个或多个分号分隔的 DEC 私有模式号（即 `CSI ? Pm h/l` 用来开关它们的同一组数字）。\n\n- **XTSAVE**（`\\x1b[?<Pm>s`）—— 把所列各模式的*当前*状态压入终端内部的逐模式栈。栈深通常逐模式 1 层深（第二次 XTSAVE 覆盖第一次）；xterm 等少数实现维持任意深度的真栈。\n- **XTRESTORE**（`\\x1b[?<Pm>r`）—— 弹出并应用每个所列模式的已保存状态。若某模式从未保存过，对它而言 XTRESTORE 为空操作。\n- 一次多模式：`\\x1b[?1000;1002;1006;1049s` 一次保存鼠标 + 备用屏的四个模式；对称的 `\\x1b[?1000;1002;1006;1049r` 一次恢复。\n\n**为何存在** —— tmux、GNU screen、fzf、atuin、neovim 的 `:terminal`、lazygit 等交互工具需要临时改变鼠标追踪、备用屏、括号粘贴、焦点事件等，又不能在崩溃或用户切后台时给用户留下被破坏的设置。XTSAVE / XTRESTORE 是*非破坏性*的方式 —— 捕获用户偏好、切换到工具偏好、退出时无论用户原本怎样都能回滚。\n\n**常用保存 / 恢复集合**（「tmux 鼠标集」）：`?1000`（X10 鼠标）、`?1002`（cell motion 鼠标）、`?1003`（all-motion 鼠标）、`?1006`（SGR 鼠标编码）、`?1015`（urxvt 鼠标编码）、`?1049`（带光标保存的备用屏）。括号粘贴加 `?2004`；焦点事件 `?1004`。\n\n**与 `?1049` 的关系** —— `\\x1b[?1049h/l` 本身是*复合*序列，等效组合了 `?1047`（备用屏）+ `?1048`（光标保存）+ 进入时隐式保存 / 退出时恢复备用屏内容。除此之外，显式 XTSAVE / XTRESTORE 才是常规手段。不要再用 XTSAVE / XTRESTORE 包裹 `?1049` —— 它已自带往返。\n\n**注意** —— xterm / iTerm2 / Kitty / WezTerm / Ghostty / Alacritty / Konsole / Windows Terminal 均实现；Linux console 仅部分实现常见模式；cmd.exe 不实现。栈深各异 —— 按 1 估，不要嵌套保存。macOS Terminal 实现最不齐，若以它为目标需专门测试。"
      },
      "parameters": [
        {
          "name": "Pm",
          "desc": {
            "en": "One or more semicolon-separated DEC private mode numbers (e.g. `1000;1002;1006;1049`). Same numbers used with `CSI ? Pm h` (set) and `CSI ? Pm l` (reset).",
            "zh": "一个或多个分号分隔的 DEC 私有模式号（如 `1000;1002;1006;1049`）。与 `CSI ? Pm h`（开启）/ `CSI ? Pm l`（关闭）使用的数字相同。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (XTSAVE / XTRESTORE — CSI ? Pm s / r)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Wrap an interactive subshell so mouse + alt-screen prefs survive it.\\nprintf '\\033[?1000;1002;1006;1049s'   # save\\nprintf '\\033[?1000l\\033[?1049h'      # enter alt-screen, mouse off\\nbash --noprofile --norc\\nprintf '\\033[?1049l'                  # leave alt-screen\\nprintf '\\033[?1000;1002;1006;1049r'   # restore user's modes"
        },
        {
          "lang": "python",
          "code": "import sys\\nMODES = '1000;1002;1006;1049'\\nsys.stdout.write(f'\\x1b[?{MODES}s')   # save\\ntry:\\n    sys.stdout.write('\\x1b[?1000h')   # enable mouse for our app\\n    run_app()\\nfinally:\\n    sys.stdout.write(f'\\x1b[?{MODES}r')   # restore"
        },
        {
          "lang": "go",
          "code": "// Defer-based save/restore wrapper for a TUI's mouse + altscreen setup.\\nmodes := \\\"1000;1002;1006;1049\\\"\\nfmt.Printf(\\\"\\\\x1b[?%ss\\\", modes)\\ndefer fmt.Printf(\\\"\\\\x1b[?%sr\\\", modes)\\nfmt.Print(\\\"\\\\x1b[?1049h\\\\x1b[?1000;1002;1006h\\\")   // enter alt-screen + cell-motion + SGR\\nrunTUI()"
        },
        {
          "lang": "javascript",
          "code": "// Node TUI — save on SIGINT/exit so user's mouse prefs always come back.\\nconst modes = '1000;1002;1006;1049';\\nprocess.stdout.write(`\\\\x1b[?${modes}s`);\\nprocess.on('exit', () => process.stdout.write(`\\\\x1b[?${modes}r`));\\nprocess.on('SIGINT', () => process.exit(130));"
        },
        {
          "lang": "c",
          "code": "/* Save -> enter alt-screen + mouse -> restore on signal. */\\nstatic const char *MODES = \\\"1000;1002;1006;1049\\\";\\nprintf(\\\"\\\\x1b[?%ss\\\", MODES);\\nsignal(SIGINT, on_exit_restore);\\nprintf(\\\"\\\\x1b[?1049h\\\\x1b[?1000;1002;1006h\\\");\\nrun_tui();\\nprintf(\\\"\\\\x1b[?%sr\\\", MODES);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "alt-screen",
        "dec-alt-screen-1047",
        "dec-mouse-tracking",
        "dec-bracketed-paste",
        "dec-focus-events"
      ]
    },
    {
      "slug": "decscl-compat-level",
      "family": "CSI",
      "title": {
        "en": "DECSCL — Select conformance level (`CSI Pl ; Pc \" p`)",
        "zh": "DECSCL — 选择一致性级别（`CSI Pl ; Pc \" p`）"
      },
      "shortDesc": {
        "en": "Choose VT100 / VT200 / VT300 / VT400 / VT500 conformance level — controls which subset of escape sequences the terminal honours, plus 7-bit vs 8-bit C1 emission. Implicitly performs a hard reset (RIS) first.",
        "zh": "选择 VT100 / VT200 / VT300 / VT400 / VT500 兼容级别 —— 控制终端识别哪个子集的转义序列，并决定 C1 以 7 位还是 8 位发送。隐式先执行硬重置（RIS）。"
      },
      "bytes": {
        "canonical": "\\x1b[<Pl>;<Pc>\" p",
        "octal": "\\033[62;1\" p",
        "eEscape": "\\e[62;1\" p",
        "literal": "ESC [ Pl ; Pc \" p",
        "hex": "1b 5b ... 22 70"
      },
      "description": {
        "en": "DECSCL — Set Conformance Level — chooses the highest VT model whose escape-sequence vocabulary the terminal will accept, **and** picks 7-bit-only C1 emission (`Pc=1`) or 8-bit C1 emission (`Pc=0` or omitted). The intermediate byte is `\"` (0x22) and the final is `p` (0x70).\n\n**`Pl` values:** `61` = VT100, `62` = VT200 / VT220, `63` = VT300 / VT320, `64` = VT400 / VT420, `65` = VT500 / VT510 / VT520.\n\n**`Pc` values** (only meaningful when `Pl ≥ 62`): `0` or omitted = 8-bit controls allowed (terminal may emit single-byte 0x80–0x9F C1 codes — IND, NEL, HTS, RI, SS2, SS3, DCS, CSI, ST, OSC, PM, APC), `1` = 7-bit controls only (the same C1 codes are emitted as their two-byte `ESC` equivalents: `ESC D` for IND, `ESC E` for NEL, `ESC \\` for ST, etc. — see `c1-controls`), `2` = 8-bit controls allowed (alias of 0 on some emulators).\n\n**Critical side-effect**: DECSCL implicitly performs a **hard reset (RIS-equivalent)** before applying the new level. Setting `\\x1b[62;1\" p` to lock the terminal into VT220-7bit mode also clears the screen + scrollback, resets SGR, resets margins, restores wraparound, etc. — do **not** call DECSCL casually mid-session unless you want the full RIS effect.\n\n**Hardware terminals** clip requested level at their native model — a real VT220 receiving `\\x1b[65\" p` falls back to VT220 conformance. **Software emulators** (xterm, kitty, iTerm2, WezTerm, Ghostty, Alacritty, Konsole, Windows Terminal) accept `61`–`65` uniformly and effectively run at VT520 native by default. Most ignore `Pc` entirely — they keep emitting 7-bit by default and only switch to 8-bit when explicitly enabled via the separate `S8C1T` `\\x1b G` / `\\x1b F` controls.\n\n**Query side**: `DCS $ q \" p ST` (DECRQSS for DECSCL — see `dcs-decrqss`) — reply is `DCS 1 $ r Pl ; Pc \" p ST`. e.g. probing on Ghostty returns `\\x1bP1$r65;1\" p\\x1b\\\\` (VT520 + 7-bit). Round-trip pattern: probe → switch → restore on exit. Use this when a TUI legitimately needs to drop to VT220 vocabulary (e.g. to suppress the terminal's interpretation of `?2026` synchronized update bracketing) — but expect the screen contents to evaporate.\n\nIf you need to *restrict feature use* without paying the RIS cost, prefer DECRQM (`decrqm`) to probe individual modes and DECRST (`\\x1b[?...l`) to selectively disable them — that's almost always what people reach for DECSCL to do.",
        "zh": "DECSCL —— 一致性级别选择 —— 设置终端将识别的最高 VT 型号转义序列集合，**并**决定 C1 仅以 7 位（`Pc=1`）还是允许 8 位发送（`Pc=0` 或省略）。中间字节为 `\"`（0x22），末字节为 `p`（0x70）。\n\n**`Pl` 取值**：`61` = VT100、`62` = VT200 / VT220、`63` = VT300 / VT320、`64` = VT400 / VT420、`65` = VT500 / VT510 / VT520。\n\n**`Pc` 取值**（仅当 `Pl ≥ 62` 时有效）：`0` 或省略 = 允许 8 位控制（终端可发出 0x80–0x9F 单字节 C1 —— IND、NEL、HTS、RI、SS2、SS3、DCS、CSI、ST、OSC、PM、APC）；`1` = 仅 7 位控制（同样的 C1 改为两字节 `ESC` 等价形式：IND 写作 `ESC D`、NEL 写作 `ESC E`、ST 写作 `ESC \\`，详见 `c1-controls`）；`2` = 允许 8 位（部分模拟器视作 0 的别名）。\n\n**关键副作用**：DECSCL 在应用新级别前会隐式执行一次**硬重置（等同于 RIS）**。设 `\\x1b[62;1\" p` 锁定 VT220-7bit 同时会清屏 + 清回滚、重置 SGR、重置边距、恢复自动换行 —— 除非你正想要 RIS 效果，否则**别**在会话中随便调用。\n\n**硬件终端**会把请求级别截断至本机型号 —— 真 VT220 收到 `\\x1b[65\" p` 仍回到 VT220 级别。**软件模拟器**（xterm、kitty、iTerm2、WezTerm、Ghostty、Alacritty、Konsole、Windows Terminal）一律接受 `61`–`65`，默认按 VT520 工作。多数完全忽略 `Pc` —— 仍默认 7 位发送，仅在 `S8C1T` / `\\x1b G` / `\\x1b F` 等单独开关启用后才发 8 位。\n\n**查询**：`DCS $ q \" p ST`（DECRQSS 查询 DECSCL，见 `dcs-decrqss`）—— 回复 `DCS 1 $ r Pl ; Pc \" p ST`。Ghostty 上测得 `\\x1bP1$r65;1\" p\\x1b\\\\`（VT520 + 7-bit）。常用模式：探测 → 切换 → 退出时恢复。当 TUI 确需切到 VT220 词汇表（如抑制终端对 `?2026` 同步更新括号的解释）时使用 —— 但要预期屏幕内容会消失。\n\n如只想*限制使用某些特性*又不愿付出 RIS 代价，请改用 DECRQM（`decrqm`）逐模式探测，再用 DECRST（`\\x1b[?...l`）选择性关闭 —— 这才是大多数人误用 DECSCL 的真实意图。"
      },
      "parameters": [
        {
          "name": "Pl",
          "desc": {
            "en": "Conformance level: 61 = VT100, 62 = VT200/VT220, 63 = VT300/VT320, 64 = VT400/VT420, 65 = VT500/VT510/VT520. Hardware terminals clip at their native model.",
            "zh": "一致性级别：61 = VT100、62 = VT200/VT220、63 = VT300/VT320、64 = VT400/VT420、65 = VT500/VT510/VT520。硬件终端会截断到本机型号。"
          }
        },
        {
          "name": "Pc",
          "desc": {
            "en": "Control bits (Pl ≥ 62 only): 0 / 2 = 8-bit C1 allowed, 1 = 7-bit-only (C1 emitted as two-byte ESC equivalents). Most emulators ignore this.",
            "zh": "控制位（仅 Pl ≥ 62 有效）：0 / 2 = 允许 8 位 C1；1 = 仅 7 位（C1 改为两字节 ESC 等价形式）。多数模拟器忽略此参数。"
          }
        }
      ],
      "spec": "DEC VT510 RM (DECSCL) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Lock terminal to VT220 7-bit conformance.\\n# WARNING: this also performs an RIS (clears screen + scrollback).\\nprintf '\\\\033[62;1\\\" p'"
        },
        {
          "lang": "python",
          "code": "import sys\\n# VT520 with 8-bit C1 allowed (modern default).\\nsys.stdout.write('\\\\x1b[65;0\\\" p')\\nsys.stdout.flush()"
        },
        {
          "lang": "go",
          "code": "// VT320 conformance — useful when targeting Sixel-era apps.\\nfmt.Print(\\\"\\\\x1b[63;0\\\\\\\" p\\\")"
        },
        {
          "lang": "javascript",
          "code": "// Most portable target: VT220 7-bit. Survives any modern emulator.\\nprocess.stdout.write('\\\\x1b[62;1\\\" p')"
        },
        {
          "lang": "c",
          "code": "/* DECSCL — implicit RIS first, then apply new level. */\\nprintf(\\\"\\\\x1b[%d;%d\\\\\\\" p\\\", 62, 1);\\nfflush(stdout);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "partial",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "ris-reset",
        "decstr-soft-reset",
        "c1-controls",
        "dcs-decrqss",
        "decrqm"
      ]
    },
    {
      "slug": "decstr-side-effects",
      "family": "CSI",
      "title": {
        "en": "DECSTR side-effects — exactly which modes `\\x1b[!p` resets",
        "zh": "DECSTR 副作用 —— `\\x1b[!p` 究竟重置哪些模式"
      },
      "shortDesc": {
        "en": "Reference enumeration of every DEC mode / attribute that DECSTR (soft reset) restores to its default — what gets cleared, what survives, and where xterm vs kitty vs iTerm2 diverge.",
        "zh": "DECSTR（软重置）会恢复到默认的每一个 DEC 模式 / 属性枚举参照 —— 哪些会被清、哪些保留、xterm / kitty / iTerm2 在哪里发生分歧。"
      },
      "bytes": {
        "canonical": "\\x1b[!p",
        "octal": "\\033[!p",
        "eEscape": "\\e[!p",
        "literal": "ESC [ ! p",
        "hex": "1b 5b 21 70"
      },
      "description": {
        "en": "Companion reference to `decstr-soft-reset` — same byte sequence (`\\x1b[!p`), expanded into the full side-effect manifest from DEC VT510 RM §8.4.1. Use this page when the question is **'will DECSTR clobber my X?'** rather than **'how do I emit a soft reset?'**.\n\n**DECSTR does NOT touch**:\n- screen contents (main or alt — survives)\n- scrollback buffer (survives)\n- alt-screen saved snapshot (survives)\n- window title / icon name (set via OSC 0/2 — survives)\n- character set definitions in G0..G3 (definitions survive; the active GL/GR pointers reset — see below)\n- macro definitions (DECDMAC entries survive — see `dcs-decdmac`)\n- user keys (DECUDK entries survive — see `dcs-decudk`)\n- cursor position (preserved at the cell it was on)\n\n**DECSTR DOES reset, to the listed default**:\n- **IRM** (Insert / Replace mode, `\\x1b[4h/l`) → Replace\n- **DECOM** (Origin Mode, `?6h/l` — see `dec-origin-mode`) → Off (absolute)\n- **DECAWM** (Auto-Wrap Mode, `?7h/l` — see `dec-line-wrap`) → On\n- **DECNRCM** (National Replacement Char Mode, `?42h/l`) → Off\n- **DECNKM** (Numeric / Application Keypad — see `deckpam-deckpnm`) → Numeric\n- **KAM** (Keyboard Action Mode, `\\x1b[2h/l`) → Unlocked\n- **DECSCA** (Select Character Protection — see `decsca`) → All chars unprotected\n- **DECSCNM** (Screen Mode reverse video, `?5h/l` — see `decscnm`) → Normal (off)\n- **DECTCEM** (Text Cursor Enable, `?25h/l` — see `cursor-visibility`) → On (cursor visible)\n- **DECCKM** (Cursor Keys Mode, `?1h/l`) → Normal\n- **DECRLM** (Right-to-Left Mode, `?34h/l`) → Off\n- **DECSCUSR** (Cursor Shape — see `dec-cursor-shape`) → implementation default (usually blinking block, `\\x1b[0 q`)\n- **DECSTBM** (Top/Bottom Margins — see `decstbm`) → Full screen (rows 1 .. height)\n- **DECSLRM** (Left/Right Margins — see `decslrm`) → Full screen (cols 1 .. width), only when DECLRMM is on\n- **SGR** (all character attributes — colour, bold, italic, etc.) → Default (`\\x1b[0m`)\n- **DECSC saved cursor state** → Cleared (popped to empty)\n- **GL / GR mappings** → GL → G0, GR → G2 (canonical defaults)\n- **Selective erase state** → Disabled\n\n**Vendor divergence** to know about when shipping DECSTR-emitting code:\n- **xterm**, **kitty**, **alacritty**, **wezterm**, **ghostty**, **konsole**: match the spec table exactly.\n- **iTerm2**: does **not** reset DECSCUSR — the cursor shape persists across `\\x1b[!p`. If you need to also restore cursor shape, send `\\x1b[0 q` explicitly after DECSTR.\n- **Windows Terminal**: pre-1.20 builds do not reset DECSLRM. Modern builds match spec.\n- **Linux console** (kernel `vt`): treats DECSTR as RIS-lite on older kernels — clears screen and scrollback too. Don't rely on scrollback survival.\n- **macOS Terminal**: silently ignores the DECSCA reset (selective erase protection persists).\n- **cmd.exe / ConPTY**: implements partially; SGR + DECTCEM reset, most others ignored.\n\n**When to reach for DECSTR vs RIS**: DECSTR preserves user-visible screen + scrollback; RIS (see `ris-reset`) wipes them. For 'I just exited a TUI in unknown state — recover gracefully without losing context' → DECSTR. For 'user typed `reset` because their terminal is wedged' → RIS (which is what the `reset` shell command actually emits via terminfo `rs1`).\n\n**Defensive pattern** when shipping a TUI that wants to leave the terminal pristine on exit:\n```\nstartup:\n  snapshot via DECRQSS what we care about (SGR, cursor shape, margins, mouse modes)\nexit (defer / signal handler):\n  emit \\x1b[!p          # soft reset clears most state\n  emit \\x1b[0 q         # force cursor shape (iTerm2 fallback)\n  emit \\x1b[?1l\\x1b>    # cursor keys + keypad normalised (extra safety)\n  emit \\x1b[?25h        # cursor visible (paranoia — DECSTR already does this)\n```",
        "zh": "`decstr-soft-reset` 的伴生参照 —— 字节序列相同（`\\x1b[!p`），扩展为 DEC VT510 RM §8.4.1 的完整副作用清单。问题是 **「DECSTR 会不会把我的 X 弄丢？」** 而非 **「软重置怎么写？」** 时看本页。\n\n**DECSTR 不会动**：\n- 屏幕内容（主屏 / 备用屏 —— 保留）\n- 回滚缓冲（保留）\n- 备用屏快照（保留）\n- 窗口标题 / 图标名（OSC 0/2 设置的 —— 保留）\n- G0..G3 字符集定义（定义保留；活动 GL/GR 指针被重置 —— 见下）\n- 宏定义（DECDMAC 条目保留 —— 见 `dcs-decdmac`）\n- 用户键（DECUDK 条目保留 —— 见 `dcs-decudk`）\n- 光标位置（仍在原单元格）\n\n**DECSTR 会重置至以下默认值**：\n- **IRM**（插入 / 替换，`\\x1b[4h/l`）→ 替换\n- **DECOM**（原点模式，`?6h/l` —— 见 `dec-origin-mode`）→ 关（绝对）\n- **DECAWM**（自动换行，`?7h/l` —— 见 `dec-line-wrap`）→ 开\n- **DECNRCM**（国家替换字符集，`?42h/l`）→ 关\n- **DECNKM**（数字 / 应用小键盘 —— 见 `deckpam-deckpnm`）→ 数字\n- **KAM**（键盘动作，`\\x1b[2h/l`）→ 解锁\n- **DECSCA**（字符保护选择 —— 见 `decsca`）→ 全部无保护\n- **DECSCNM**（反相屏幕，`?5h/l` —— 见 `decscnm`）→ 正常（关）\n- **DECTCEM**（光标可见，`?25h/l` —— 见 `cursor-visibility`）→ 开（光标可见）\n- **DECCKM**（光标键模式，`?1h/l`）→ 正常\n- **DECRLM**（从右至左模式，`?34h/l`）→ 关\n- **DECSCUSR**（光标形状 —— 见 `dec-cursor-shape`）→ 实现默认（通常为闪烁方块，`\\x1b[0 q`）\n- **DECSTBM**（上下边距 —— 见 `decstbm`）→ 全屏（1 .. 高）\n- **DECSLRM**（左右边距 —— 见 `decslrm`）→ 全屏（1 .. 宽），仅 DECLRMM 开时\n- **SGR**（所有字符属性：颜色、加粗、斜体等）→ 默认（`\\x1b[0m`）\n- **DECSC 保存的光标栈** → 清空\n- **GL / GR 映射** → GL → G0，GR → G2（规范默认）\n- **选择性擦除状态** → 关\n\n**厂商分歧**：\n- **xterm**、**kitty**、**alacritty**、**wezterm**、**ghostty**、**konsole**：与规范完全一致。\n- **iTerm2**：**不**重置 DECSCUSR —— 光标形状跨 `\\x1b[!p` 保留。如需顺带恢复形状，DECSTR 后显式发 `\\x1b[0 q`。\n- **Windows Terminal**：1.20 之前的构建不重置 DECSLRM。现代构建与规范一致。\n- **Linux console**（内核 `vt`）：旧内核把 DECSTR 当作 RIS-lite —— 屏幕和回滚也会清。别依赖回滚保留。\n- **macOS Terminal**：静默忽略 DECSCA 重置（选择性擦除保护保留）。\n- **cmd.exe / ConPTY**：部分实现；SGR + DECTCEM 会重置，其余多数忽略。\n\n**DECSTR vs RIS 何时选择**：DECSTR 保留用户可见屏幕 + 回滚；RIS（见 `ris-reset`）一并清掉。「我刚退出一个状态不明的 TUI —— 优雅恢复又不丢上下文」用 DECSTR。「用户输 `reset` 因为终端卡死了」用 RIS（`reset` shell 命令通过 terminfo `rs1` 实际发的就是它）。\n\n**离场防御性模式**：\n```\n启动时：\n  通过 DECRQSS 快照在意的状态（SGR、光标形状、边距、鼠标模式）\n退出（defer / 信号处理）：\n  发 \\x1b[!p            # 软重置清除多数状态\n  发 \\x1b[0 q           # 强制光标形状（iTerm2 兜底）\n  发 \\x1b[?1l\\x1b>      # 光标键 + 小键盘归位（额外保险）\n  发 \\x1b[?25h          # 光标可见（偏执 —— DECSTR 本来就会做）\n```"
      },
      "spec": "DEC VT510 RM §8.4.1 (DECSTR side-effect table) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Soft reset — preserves screen + scrollback. Side-effects as listed above.\\nprintf '\\\\033[!p'"
        },
        {
          "lang": "python",
          "code": "# Probe DECSCUSR after DECSTR to verify cursor-shape reset (catches iTerm2).\\nimport sys\\nsys.stdout.write('\\\\x1b[!p\\\\x1bP$q q\\\\x1b\\\\\\\\')\\nsys.stdout.flush()"
        },
        {
          "lang": "go",
          "code": "// Defensive exit: soft reset + explicit cursor shape + visible cursor.\\nfunc restoreTerminal() {\\n    fmt.Print(\\\"\\\\x1b[!p\\\")    // DECSTR\\n    fmt.Print(\\\"\\\\x1b[0 q\\\")   // cursor shape -> default (iTerm2)\\n    fmt.Print(\\\"\\\\x1b[?25h\\\")  // cursor visible (paranoia)\\n}"
        },
        {
          "lang": "javascript",
          "code": "// On Node TUI exit, leave terminal pristine for the user's shell.\\nprocess.on('exit', () => {\\n  process.stdout.write('\\\\x1b[!p\\\\x1b[0 q\\\\x1b[?25h');\\n});"
        },
        {
          "lang": "c",
          "code": "/* DECSTR keeps screen but you may want to also clear scroll-region\\n * since DECSTBM resets to full-screen. */\\nprintf(\\\"\\\\x1b[!p\\\");\\nprintf(\\\"\\\\x1b[H\\\");  /* cursor home — DECSTR leaves it where it was */\\nfflush(stdout);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "partial",
        "wt": "partial",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "decstr-soft-reset",
        "ris-reset",
        "decsca",
        "dec-cursor-shape",
        "decstbm",
        "decslrm",
        "dec-origin-mode",
        "deckpam-deckpnm"
      ]
    },
    {
      "slug": "decrpm-decoder",
      "family": "CSI",
      "title": {
        "en": "DECRPM decoder — parsing the DECRQM reply (`CSI ? Ps ; Pm $ y`)",
        "zh": "DECRPM 解码 —— 解析 DECRQM 回复（`CSI ? Ps ; Pm $ y`）"
      },
      "shortDesc": {
        "en": "How to read the `CSI ? Ps ; Pm $ y` (and `CSI Ps ; Pm $ y`) reply that DECRQM returns — the `Pm` value tells you whether the mode is set / reset / always-set / always-reset / unrecognised.",
        "zh": "解析 DECRQM 回复 `CSI ? Ps ; Pm $ y`（以及 `CSI Ps ; Pm $ y`）—— `Pm` 数值说明该模式当前是 设置 / 重置 / 永久开 / 永久关 / 不识别 中的哪一种。"
      },
      "bytes": {
        "canonical": "\\x1b[?<Ps>;<Pm>$y     (private)     \\x1b[<Ps>;<Pm>$y     (ANSI)",
        "octal": "\\033[?2004;1$y",
        "eEscape": "\\e[?2004;1$y",
        "literal": "ESC [ ? Ps ; Pm $ y",
        "hex": "1b 5b 3f ... 24 79"
      },
      "description": {
        "en": "DECRPM — Report Private Mode (private form) or Report Mode (ANSI form) — is the reply terminals emit in response to a DECRQM query (`CSI ? Ps $ p` for private modes, `CSI Ps $ p` for ANSI modes; see `decrqm`). The reply echoes the queried `Ps` and adds a `Pm` value whose small enum tells you exactly what the terminal knows about that mode.\n\n**`Pm` values**:\n- **`0`** — *mode not recognised*. Treat the mode as unsupported. Don't keep probing this `Ps`; cache the result as 'unsupported' for the session.\n- **`1`** — *mode is currently set*. Equivalent to `\\x1b[?<Ps>h` (or `\\x1b[<Ps>h` for ANSI) having been the last operation on it.\n- **`2`** — *mode is currently reset*. Equivalent to `\\x1b[?<Ps>l` (or `\\x1b[<Ps>l` for ANSI) having been the last operation on it.\n- **`3`** — *mode is permanently set*. The terminal hardwires it on; sending `\\x1b[?<Ps>l` is a no-op.\n- **`4`** — *mode is permanently reset*. The terminal hardwires it off; sending `\\x1b[?<Ps>h` is a no-op.\n\nThe `?` in the reply mirrors the `?` in the request — querying a private mode (e.g. `?2004` bracketed paste, `?1000` mouse) yields `\\x1b[?2004;Pm$y`, while querying an ANSI mode (e.g. `4` IRM, `20` LNM) yields `\\x1b[4;Pm$y` *without* the `?`. Consumers must match the request shape literally — a stream that interleaves private and ANSI probes will mis-route replies otherwise.\n\n**Recommended consumer pattern** (Python-ish pseudocode):\n```\ndef probe_mode(ps, private=True, timeout=0.1):\n    prefix = '?' if private else ''\n    sys.stdout.write(f'\\x1b[{prefix}{ps}$p')\n    sys.stdout.flush()\n    reply = read_until_finalbyte('y', timeout)        # CSI ... $ y\n    m = re.match(rf'\\x1b\\[{re.escape(prefix)}(\\d+);(\\d+)\\$y', reply or '')\n    if not m or int(m.group(1)) != ps:\n        return 'no-reply'\n    return {0:'unknown', 1:'set', 2:'reset', 3:'permaset', 4:'permareset'}[int(m.group(2))]\n```\n\n**What 'permanently set/reset' really means**: terminals use `Pm=3` / `Pm=4` to signal 'this feature is on/off and you can't toggle it from escape codes'. Examples:\n- A terminal that ships with bracketed paste always-on (some users configure xterm this way via X resources) returns `Pm=3` for `?2004`.\n- Older Linux console returns `Pm=4` for `?1000` (mouse tracking) since the kernel `vt` driver never implemented it.\n- ConPTY returns `Pm=4` for many DEC private modes (e.g. `?9` X10 mouse, `?1015` urxvt mouse) because the conhost translation layer fixes those features off.\n\nTreat `Pm=3` / `Pm=4` the same as `Pm=1` / `Pm=2` for read purposes — the mode IS in that state — but don't bother emitting an h/l toggle that would be silently ignored.\n\n**Vendor compliance**:\n- **xterm**, **kitty**, **iTerm2**, **WezTerm**, **Ghostty**, **Konsole**: full spec — return all five `Pm` values appropriately.\n- **Alacritty**: implements `Pm ∈ {0, 1, 2}` only — never returns `3` or `4`. Tools that branch on permaset/permareset must treat 'absent' as 'unknown but probably supported'.\n- **Linux console** (`vt`): replies to a small whitelist of common modes (`?1`, `?7`, `?25`); silent on everything else (no reply at all — be sure to time out).\n- **Windows Terminal**: full compliance ≥ 1.20. Earlier builds returned `Pm=0` for some supported modes.\n- **cmd.exe / ConPTY**: limited — most probes return `Pm=0` even for modes the terminal honours.\n- **macOS Terminal**: partial; some modes return `Pm=0` instead of `Pm=1`/`Pm=2` even when state-toggling works. Don't trust DECRQM on macOS Terminal for feature detection — use behavioural probes instead.\n\n**DECRQM + DECRPM vs DECRQSS** (see `dcs-decrqss`): DECRQM is the *generic mode-state* query — yes/no/permaset/permareset/unknown. DECRQSS returns the actual *value* of a settable resource (SGR stack, DECSCUSR shape, DECSTBM rows/cols, DECSCL conformance level). Use DECRQM for 'is bracketed paste on?', DECRQSS for 'which cursor shape is currently active?'. A useful TUI startup probe usually fires both: DECRQM to discover capabilities + DECRQSS to snapshot resources for later restore.",
        "zh": "DECRPM —— Report Private Mode（私有式）或 Report Mode（ANSI 式）—— 是终端对 DECRQM 查询（私有模式 `CSI ? Ps $ p`、ANSI 模式 `CSI Ps $ p`，见 `decrqm`）的回复。回复回显被查询的 `Ps`，再加一个 `Pm` 值，其小型枚举精确表达终端对该模式的认识。\n\n**`Pm` 取值**：\n- **`0`** —— *不识别该模式*。视为不支持。别再探测同一 `Ps`；按会话缓存为「不支持」。\n- **`1`** —— *当前为「设置」*。等效于最近一次执行了 `\\x1b[?<Ps>h`（ANSI 式则 `\\x1b[<Ps>h`）。\n- **`2`** —— *当前为「重置」*。等效于最近一次执行了 `\\x1b[?<Ps>l`（ANSI 式则 `\\x1b[<Ps>l`）。\n- **`3`** —— *永久设置*。终端硬编码为开；发 `\\x1b[?<Ps>l` 是空操作。\n- **`4`** —— *永久重置*。终端硬编码为关；发 `\\x1b[?<Ps>h` 是空操作。\n\n回复中的 `?` 与请求中的 `?` 镜像 —— 查询私有模式（如 `?2004` 括号粘贴、`?1000` 鼠标）得 `\\x1b[?2004;Pm$y`；查询 ANSI 模式（如 `4` IRM、`20` LNM）得 `\\x1b[4;Pm$y`，*无* `?`。消费者必须按请求形态原样匹配 —— 交错探测私有 / ANSI 时回复会被错路由。\n\n**推荐消费者模式**（Python 风伪码）：\n```\ndef probe_mode(ps, private=True, timeout=0.1):\n    prefix = '?' if private else ''\n    sys.stdout.write(f'\\x1b[{prefix}{ps}$p')\n    sys.stdout.flush()\n    reply = read_until_finalbyte('y', timeout)        # CSI ... $ y\n    m = re.match(rf'\\x1b\\[{re.escape(prefix)}(\\d+);(\\d+)\\$y', reply or '')\n    if not m or int(m.group(1)) != ps:\n        return 'no-reply'\n    return {0:'unknown', 1:'set', 2:'reset', 3:'permaset', 4:'permareset'}[int(m.group(2))]\n```\n\n**「永久设置 / 永久重置」的真实含义**：终端用 `Pm=3` / `Pm=4` 表达「该特性开 / 关且无法用转义码切换」。例如：\n- 一直常开括号粘贴的终端（部分用户通过 xterm X 资源配置）对 `?2004` 回 `Pm=3`。\n- 旧 Linux console 对 `?1000`（鼠标追踪）回 `Pm=4`，因内核 `vt` 驱动从未实现。\n- ConPTY 对多数 DEC 私有模式（如 `?9` X10 鼠标、`?1015` urxvt 鼠标）回 `Pm=4`，因 conhost 翻译层把它们写死为关。\n\n读取目的下把 `Pm=3` / `Pm=4` 等同 `Pm=1` / `Pm=2` —— 模式确在该状态 —— 但别再发会被静默忽略的 h/l。\n\n**厂商兼容性**：\n- **xterm**、**kitty**、**iTerm2**、**WezTerm**、**Ghostty**、**Konsole**：完全合规 —— 五种 `Pm` 都能正确返回。\n- **Alacritty**：仅实现 `Pm ∈ {0, 1, 2}` —— 永不返回 `3` / `4`。依赖 permaset/permareset 分支的工具需把「缺失」视作「未知但可能支持」。\n- **Linux console**（`vt`）：只对常见模式（`?1`、`?7`、`?25`）回；其余完全静默（无回复 —— 务必加超时）。\n- **Windows Terminal**：1.20 起完全合规；早期构建会对部分实际支持的模式回 `Pm=0`。\n- **cmd.exe / ConPTY**：受限 —— 多数探测即使被支持也回 `Pm=0`。\n- **macOS Terminal**：部分实现；部分模式即便能 h/l 切换也回 `Pm=0` 而不是 `Pm=1` / `Pm=2`。在 macOS Terminal 上别信 DECRQM 做特性检测 —— 改用行为探测。\n\n**DECRQM + DECRPM vs DECRQSS**（见 `dcs-decrqss`）：DECRQM 是*通用模式状态*查询 —— 开 / 关 / 永久开 / 永久关 / 未知。DECRQSS 返回可设置资源的真实*值*（SGR 栈、DECSCUSR 形状、DECSTBM 行列、DECSCL 一致性级别）。「括号粘贴开了吗」用 DECRQM；「当前光标是什么形状」用 DECRQSS。TUI 启动探测通常两者都发：DECRQM 发现能力，DECRQSS 快照资源以便退出时恢复。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "Echoes the mode number from the originating DECRQM query. Match the reply's Ps to your request to disambiguate when multiple probes are in flight.",
            "zh": "回显发起的 DECRQM 查询的模式号。若同时发出多个探测，按回复 Ps 与请求匹配以消歧。"
          }
        },
        {
          "name": "Pm",
          "desc": {
            "en": "0 unrecognised, 1 set, 2 reset, 3 permanently set (hardwired on), 4 permanently reset (hardwired off).",
            "zh": "0 不识别、1 设置、2 重置、3 永久设置（硬编码开）、4 永久重置（硬编码关）。"
          }
        }
      ],
      "spec": "xterm-ctlseqs (DECRPM, CSI ? Ps ; Pm $ y / CSI Ps ; Pm $ y)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Probe bracketed-paste; expect ?2004;1$y if on, ?2004;2$y if off.\\nprintf '\\\\033[?2004$p'\\nIFS= read -rs -d y -t 0.1 reply </dev/tty 2>/dev/null\\necho \\\"DECRPM: ${reply#$'\\\\033'}y\\\""
        },
        {
          "lang": "python",
          "code": "import sys, re, termios, tty, select\\n\\ndef probe(ps, private=True, timeout=0.1):\\n    prefix = '?' if private else ''\\n    fd = sys.stdin.fileno(); old = termios.tcgetattr(fd)\\n    try:\\n        tty.setcbreak(fd)\\n        sys.stdout.write(f'\\\\x1b[{prefix}{ps}$p'); sys.stdout.flush()\\n        buf = ''\\n        while True:\\n            r,_,_ = select.select([fd], [], [], timeout)\\n            if not r: break\\n            buf += sys.stdin.read(1)\\n            if buf.endswith('y'): break\\n    finally:\\n        termios.tcsetattr(fd, termios.TCSADRAIN, old)\\n    m = re.match(rf'\\\\x1b\\\\[{re.escape(prefix)}(\\\\d+);(\\\\d+)\\\\$y', buf)\\n    if not m or int(m.group(1)) != ps: return 'no-reply'\\n    return ['unknown','set','reset','permaset','permareset'][int(m.group(2))]\\n\\nprint(probe(2004))"
        },
        {
          "lang": "go",
          "code": "// After DECRQM probe, switch on the Pm enum.\\nswitch pm {\\ncase 0: cap[ps] = capUnknown      // not recognised\\ncase 1: cap[ps] = capOn           // currently set\\ncase 2: cap[ps] = capOff          // currently reset\\ncase 3: cap[ps] = capHardwiredOn  // can't toggle off — skip restore\\ncase 4: cap[ps] = capHardwiredOff // can't toggle on  — skip enable\\n}"
        },
        {
          "lang": "javascript",
          "code": "// Node parser — match DECRPM reply, return {ps, state}.\\nfunction parseDECRPM(buf) {\\n  const m = /\\\\x1b\\\\[(\\\\??)(\\\\d+);(\\\\d+)\\\\$y/.exec(buf);\\n  if (!m) return null;\\n  return {\\n    private: m[1] === '?',\\n    ps: Number(m[2]),\\n    state: ['unknown','set','reset','permaset','permareset'][Number(m[3])] ?? 'invalid',\\n  };\\n}"
        },
        {
          "lang": "c",
          "code": "/* Skeleton — emit DECRQM for ?1006 (SGR mouse), parse DECRPM Pm. */\\nfprintf(stdout, \\\"\\\\x1b[?1006$p\\\"); fflush(stdout);\\n/* read until 'y'; then sscanf buf, \\\"\\\\x1b[?%d;%d$y\\\", &ps, &pm) */\\nint ps = 0, pm = 0;\\n/* ...read loop... */\\nif (ps == 1006) {\\n    static const char *st[] = {\\\"unknown\\\",\\\"set\\\",\\\"reset\\\",\\\"permaset\\\",\\\"permareset\\\"};\\n    printf(\\\"SGR mouse: %s\\\\n\\\", (pm>=0 && pm<=4) ? st[pm] : \\\"invalid\\\");\\n}"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "yes",
        "wt": "yes",
        "cmd": "partial",
        "kitty": "yes",
        "alacritty": "partial",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "decrqm",
        "dcs-decrqss",
        "csi-dsr",
        "csi-private-dsr",
        "xtversion"
      ]
    },
    {
      "slug": "dec-locator",
      "family": "CSI",
      "title": {
        "en": "DEC locator suite — DECELR / DECEFR / DECSLE / DECRQLP (mouse / locator events)",
        "zh": "DEC 定位器套件 —— DECELR / DECEFR / DECSLE / DECRQLP（鼠标 / 定位器事件）"
      },
      "shortDesc": {
        "en": "The original DEC pointing-device protocol (predates xterm SGR mouse modes by a decade). Four sequences enable, filter, select, and query locator events; modern interactive UIs use SGR mouse modes (`?1000` + `?1006`) instead.",
        "zh": "DEC 原版指点设备协议（比 xterm SGR 鼠标模式早十年）。四个序列分别 启用 / 过滤 / 选择 / 查询定位器事件；现代交互式 UI 改用 SGR 鼠标模式（`?1000` + `?1006`）。"
      },
      "bytes": {
        "canonical": "\\x1b[<Pn>;<Pu>'z   \\x1b[<Pm>'{   \\x1b[<Pt>;<Pl>;<Pb>;<Pr>'w   \\x1b[<Ps>'|",
        "octal": "\\033[1;2'z",
        "eEscape": "\\e[1;2'z",
        "literal": "ESC [ ... ' z   /   ' {   /   ' w   /   ' |",
        "hex": "1b 5b ... 27 7a / 7b / 77 / 7c"
      },
      "description": {
        "en": "The DEC locator protocol predates the xterm extended mouse modes by a decade and is how VT300+ hardware terminals (and software emulators when bumped to a high DECSCL conformance — see `decscl-compat-level`) report pointing-device events. Four sequences make up the family — all share the single-quote (`0x27`) intermediate byte:\n\n- **DECELR** — *Enable Locator Reports* — `\\x1b[<Pn>;<Pu>'z`\n  - `Pn`: `0` = disable locator reports, `1` = enable, `2` = enable for one report only (then auto-disable).\n  - `Pu`: `0` or `2` = report coordinates in character cells, `1` = report in device units (pixels).\n  - Once enabled, the terminal sends a DECLRP report on every button transition that passes the DECSLE filter, plus one when an outside-the-rectangle move happens (if DECEFR has set a rectangle).\n\n- **DECSLE** — *Select Locator Events* — `\\x1b[<Pm>'{`\n  - `Pm`: `0` = only explicit DECRQLP requests trigger a report; `1` = button-down events trigger reports; `2` = disable button-down reporting; `3` = button-up events trigger reports; `4` = disable button-up reporting.\n  - May be repeated with different `Pm` values to enable button-down AND button-up: `\\x1b[1'{\\x1b[3'{`.\n\n- **DECEFR** — *Enable Filter Rectangle* — `\\x1b[<Pt>;<Pl>;<Pb>;<Pr>'w`\n  - Defines an inclusive rectangle: top row, left col, bottom row, right col. Locator movement *outside* the rectangle triggers one DECLRP report, then the filter is auto-disabled.\n  - Used for cursor-tracking apps that only care about 'mouse exited my widget' transitions.\n\n- **DECRQLP** — *Request Locator Position* — `\\x1b[<Ps>'|`\n  - `Ps`: number of transactions (currently always `1`).\n  - Forces an immediate DECLRP report regardless of filter / event settings.\n\n**DECLRP — the reply** — `\\x1b[<Pe>;<Pb>;<Pr>;<Pc>;<Pp>&w` (note the `&` intermediate, distinct from request finals):\n- `Pe` = event type: `0` = locator unavailable (no pointer), `1` = response to DECRQLP, `2` = left button down, `3` = left button up, `4` = middle down, `5` = middle up, `6` = right down, `7` = right up, `8` = M4 (button 4) down, `9` = M4 up, `10` = locator outside filter rectangle.\n- `Pb` = button-state bitmask: `1` = left, `2` = middle, `4` = right, `8` = button 4. OR them together.\n- `Pr`, `Pc` = row, column (1-indexed) in whatever units DECELR's `Pu` selected.\n- `Pp` = page number (always `1` on modern emulators — multi-page is a hardware-terminal concept).\n\n**Why you almost certainly don't need this**: certain legacy CAD, terminal-based GIS, and radar / SCADA apps written in the 1980s expect this protocol. Some xterm extensions (the `xterm*set-locator-events` X resource) still enable it. Modern interactive UIs — tmux, htop, mc, lazygit, fzf, neovim's `:terminal` — all use SGR mouse modes (`?1000` enable + `?1006` SGR encoding; see `dec-mouse-tracking` and `sgr-mouse-encoding`) because they're easier to parse, support multi-byte coordinates trivially, and have near-universal cross-emulator coverage.\n\n**Coverage matrix**: **xterm** = full implementation (only widely-deployed emulator that does). **gnome-terminal** / **konsole** = partial (DECRQLP returns a synthetic 'no pointer' DECLRP). **iTerm2** / **kitty** / **wezterm** / **alacritty** / **ghostty** / **Windows Terminal** / **cmd** / **Linux console** / **macOS Terminal** = none — the sequences are silently consumed and produce no reply.\n\n**When you might still reach for it**: targeting xterm specifically on a legacy XFCE / CDE system; porting old SCADA terminal apps; testing terminfo entries for `locator_*` capabilities. Otherwise use SGR mouse modes.",
        "zh": "DEC 定位器协议比 xterm 扩展鼠标模式早十年，是 VT300+ 硬件终端（以及软件模拟器在调到高 DECSCL 一致性级别 —— 见 `decscl-compat-level` —— 时）上报指点设备事件的方式。四个序列共同构成该族 —— 均以单引号（`0x27`）为中间字节：\n\n- **DECELR** —— *启用定位器报告* —— `\\x1b[<Pn>;<Pu>'z`\n  - `Pn`：`0` = 关闭定位器报告；`1` = 启用；`2` = 启用一次报告后自动关闭。\n  - `Pu`：`0` 或 `2` = 坐标按字符单元；`1` = 坐标按设备单位（像素）。\n  - 启用后，每次按键过 DECSLE 过滤都会发 DECLRP 报告；若 DECEFR 设了矩形，离开矩形时也发一份。\n\n- **DECSLE** —— *选择定位器事件* —— `\\x1b[<Pm>'{`\n  - `Pm`：`0` = 仅显式 DECRQLP 才回；`1` = 按下事件回；`2` = 关闭按下事件回；`3` = 抬起事件回；`4` = 关闭抬起事件回。\n  - 可多次发不同 `Pm` 同时开按下 + 抬起：`\\x1b[1'{\\x1b[3'{`。\n\n- **DECEFR** —— *启用过滤矩形* —— `\\x1b[<Pt>;<Pl>;<Pb>;<Pr>'w`\n  - 定义闭矩形：上行、左列、下行、右列。指点*离开*该矩形时触发一次 DECLRP，过滤器随即自动关闭。\n  - 用于只关心「鼠标离开我的控件」转换的光标追踪程序。\n\n- **DECRQLP** —— *请求定位器位置* —— `\\x1b[<Ps>'|`\n  - `Ps`：事务数（目前总为 `1`）。\n  - 强制立刻发 DECLRP，与过滤 / 事件设置无关。\n\n**DECLRP —— 回复** —— `\\x1b[<Pe>;<Pb>;<Pr>;<Pc>;<Pp>&w`（注意中间字节 `&`，与请求的 final 不同）：\n- `Pe` = 事件类型：`0` = 定位器不可用、`1` = DECRQLP 的回复、`2` = 左键按下、`3` = 左键抬起、`4` = 中键按下、`5` = 中键抬起、`6` = 右键按下、`7` = 右键抬起、`8` = M4（第 4 键）按下、`9` = M4 抬起、`10` = 离开过滤矩形。\n- `Pb` = 按键状态位掩码：`1` = 左、`2` = 中、`4` = 右、`8` = 第 4 键。可 OR。\n- `Pr`、`Pc` = 行、列（1 起算），单位取自 DECELR 的 `Pu`。\n- `Pp` = 页号（现代模拟器恒为 `1` —— 多页是硬件终端概念）。\n\n**为何你几乎用不到**：1980 年代写的若干 CAD、终端 GIS、radar / SCADA 程序仰赖此协议。某些 xterm 扩展（`xterm*set-locator-events` X 资源）仍允许启用。现代交互式 UI —— tmux、htop、mc、lazygit、fzf、neovim 的 `:terminal` —— 全部改用 SGR 鼠标模式（`?1000` 启用 + `?1006` SGR 编码；见 `dec-mouse-tracking` 与 `sgr-mouse-encoding`）：解析更简单、多字节坐标天然支持、跨模拟器覆盖近乎完美。\n\n**覆盖度**：**xterm** = 完整实现（唯一广泛部署的）；**gnome-terminal** / **konsole** = 部分（DECRQLP 回合成的「无指点」DECLRP）；**iTerm2** / **kitty** / **wezterm** / **alacritty** / **ghostty** / **Windows Terminal** / **cmd** / **Linux console** / **macOS Terminal** = 无 —— 序列被静默吞掉，不回。\n\n**仍可能用到的场景**：专门面向旧 XFCE / CDE 上的 xterm；移植旧 SCADA 终端程序；测 terminfo 的 `locator_*` capabilities。否则直接用 SGR 鼠标模式。"
      },
      "spec": "DEC VT510 RM (DECELR / DECEFR / DECSLE / DECRQLP / DECLRP) / xterm-ctlseqs",
      "examples": [
        {
          "lang": "bash",
          "code": "# Enable locator reports (cell coords, one-shot), then query position.\\nprintf \\\"\\\\033[2;0'z\\\"   # DECELR Pn=2 one-shot, Pu=0 cells\\nprintf \\\"\\\\033[1'|\\\"     # DECRQLP — force immediate DECLRP reply\\n# read reply matching: \\\\x1b[1;Pb;Pr;Pc;1&w"
        },
        {
          "lang": "python",
          "code": "import sys\\n# Set filter rectangle around rows 5-20, cols 10-60 then enable button-down events.\\nsys.stdout.write(\\\"\\\\x1b[1;0'z\\\")        # DECELR enable, cells\\nsys.stdout.write(\\\"\\\\x1b[5;10;20;60'w\\\") # DECEFR filter rect\\nsys.stdout.write(\\\"\\\\x1b[1'{\\\")          # DECSLE enable button-down reports\\nsys.stdout.flush()"
        },
        {
          "lang": "go",
          "code": "// Disable locator reports (clean exit).\\nfmt.Print(\\\"\\\\x1b[0;0'z\\\")"
        },
        {
          "lang": "javascript",
          "code": "// Parse a DECLRP reply: \\\\x1b[Pe;Pb;Pr;Pc;Pp&w\\nfunction parseDECLRP(buf) {\\n  const m = /\\\\x1b\\\\[(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+)&w/.exec(buf);\\n  if (!m) return null;\\n  return { event: +m[1], buttons: +m[2], row: +m[3], col: +m[4], page: +m[5] };\\n}"
        },
        {
          "lang": "c",
          "code": "/* Force a single locator-position report (synchronous-ish probe). */\\nprintf(\\\"\\\\x1b[1;0'z\\\");   /* DECELR enable, cells */\\nprintf(\\\"\\\\x1b[1'|\\\");     /* DECRQLP */\\nfflush(stdout);\\n/* read reply: matches sscanf(\\\"\\\\x1b[%d;%d;%d;%d;%d&w\\\", &pe,&pb,&pr,&pc,&pp) */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "dec-mouse-tracking",
        "sgr-mouse-encoding",
        "csi-private-dsr",
        "decscl-compat-level"
      ]
    },
    {
      "slug": "decreqtparm",
      "family": "CSI",
      "title": {
        "en": "DECREQTPARM / DECREPTPARM — Request and report terminal parameters (`CSI Ps x`)",
        "zh": "DECREQTPARM / DECREPTPARM —— 请求并报告终端参数（`CSI Ps x`）"
      },
      "shortDesc": {
        "en": "VT100-era legacy probe — ask the terminal for its serial-line parameters (parity, bit-count, baud, clock multiplier, flags). Predates DA / DA2 / XTVERSION; almost never the right tool now, but xterm and most modern emulators still answer with synthetic defaults.",
        "zh": "VT100 时代的遗留探测 —— 让终端报告其串口参数（校验、位宽、波特率、时钟倍数、标志位）。比 DA / DA2 / XTVERSION 都早；现今几乎不该再用，但 xterm 与多数现代模拟器仍以合成默认值作答。"
      },
      "bytes": {
        "canonical": "\\x1b[<Ps>x",
        "octal": "\\033[1x",
        "eEscape": "\\e[1x",
        "literal": "ESC [ Ps x",
        "hex": "1b 5b ... 78"
      },
      "description": {
        "en": "DECREQTPARM — Request Terminal Parameters — `CSI Ps x`, with `Ps` selecting solicit-vs-unsolicit convention. Originally wired to the VT100's physical serial line: a host could ask 'what baud / parity / bit-count are you set to?' and the terminal answered with its current setup over the same line.\n\n**Request**:\n- `Ps = 0` — terminal MAY thereafter send unsolicited DECREPTPARM responses (effectively obsolete; almost no emulator honours this — it's a relic of host-managed setup over a multidrop line).\n- `Ps = 1` — request a solicited response NOW.\n\n**Reply (DECREPTPARM)** — `\\x1b[<sol>;<par>;<nbits>;<xspeed>;<rspeed>;<clkmul>;<flags>x`\n- `sol` = `2` if unsolicited, `3` if solicited (matches your request).\n- `par` = parity — `1` = none, `4` = odd, `5` = even.\n- `nbits` = data bits — `1` = 8, `2` = 7.\n- `xspeed` = transmit speed code (e.g. `16` = 9600, `24` = 38400, `88` = synthetic 'fast' on most emulators).\n- `rspeed` = receive speed code (usually equal to `xspeed`).\n- `clkmul` = clock multiplier (always `1` for real VT100; modern emulators echo `1`).\n- `flags` = STP / SET-UP / TIME bitfield (always `0` on modern emulators).\n\n**What modern emulators do**:\n- **xterm**: full reply with sensible defaults — typically `\\x1b[3;1;1;112;112;1;0x` or `\\x1b[3;1;1;88;88;1;0x` depending on build. The speed code is synthetic and not meaningful.\n- **kitty**, **wezterm**, **ghostty**, **iTerm2**, **alacritty**, **Konsole**: each implements just enough to not hang a legacy probe — typically returning `\\x1b[3;1;1;112;112;1;0x` or similar.\n- **gnome-terminal**: same synthetic shape.\n- **Windows Terminal**: replies on builds ≥ 1.18; older builds silent.\n- **macOS Terminal**: silent — does not respond. Probes hang until timeout.\n- **cmd.exe / ConPTY**: silent.\n- **Linux console** (`vt`): replies with `\\x1b[3;1;1;112;112;1;0x` on most kernels.\n\n**Should you actually use this in 2026?** Probably never. The reply gives you zero information beyond 'the terminal is alive and speaks ECMA-48', which DA1 (`\\x1b[c` — see `csi-da`) already answers more cleanly with a model ID. If you find DECREQTPARM in a legacy codebase, it's almost certainly a relic of VT100-era serial-line setup code that never got modernised. Replace with:\n- `csi-da` (DA1, `\\x1b[c`) for 'is this a VT-class terminal' / what model.\n- `csi-da2-decoder` (DA2, `\\x1b[>c`) for emulator class + firmware version.\n- `xtversion` (`\\x1b[>0q`) for specific emulator name + version (xterm-family extension).\n\n**If you must use it**: send `\\x1b[1x`, read reply on stdin matching `\\x1b\\[3;\\d+;\\d+;\\d+;\\d+;\\d+;\\d+x`. **Time out at 100 ms** — macOS Terminal users will leave you hanging otherwise. Don't treat `xspeed`/`rspeed` as a real baud rate; emulators emit constants. The only field that occasionally carries signal is `par` (parity), and only on serial-attached emulators (gtkterm, picocom — both outside our 12-emulator support row).",
        "zh": "DECREQTPARM —— 请求终端参数 —— `CSI Ps x`，`Ps` 选择「主动 vs 被动」语义。原本绑定到 VT100 物理串口：主机可问「你的波特 / 校验 / 位宽是多少」，终端在同条串线上回应当前设置。\n\n**请求**：\n- `Ps = 0` —— 终端此后*可能*主动发 DECREPTPARM 响应（实际过时；几乎无模拟器实现 —— 这是主机管理多点串线设置的遗物）。\n- `Ps = 1` —— 立刻请求一次被动响应。\n\n**回复（DECREPTPARM）** —— `\\x1b[<sol>;<par>;<nbits>;<xspeed>;<rspeed>;<clkmul>;<flags>x`\n- `sol` = `2` 主动，`3` 被动（与请求匹配）。\n- `par` = 校验 —— `1` 无、`4` 奇、`5` 偶。\n- `nbits` = 数据位 —— `1` 八位，`2` 七位。\n- `xspeed` = 发送速率编码（如 `16` = 9600、`24` = 38400、`88` = 多数模拟器合成的「快」）。\n- `rspeed` = 接收速率编码（通常与 `xspeed` 相同）。\n- `clkmul` = 时钟倍数（真 VT100 恒为 `1`；现代模拟器回 `1`）。\n- `flags` = STP / SET-UP / TIME 位字段（现代模拟器恒为 `0`）。\n\n**现代模拟器表现**：\n- **xterm**：完整回复且默认合理 —— 视构建而定多为 `\\x1b[3;1;1;112;112;1;0x` 或 `\\x1b[3;1;1;88;88;1;0x`。速率编码合成，无实际意义。\n- **kitty**、**wezterm**、**ghostty**、**iTerm2**、**alacritty**、**Konsole**：均「最小实现」以免挂死遗留探测 —— 一般回 `\\x1b[3;1;1;112;112;1;0x` 或类似。\n- **gnome-terminal**：同样合成。\n- **Windows Terminal**：1.18+ 构建回；早期构建静默。\n- **macOS Terminal**：静默 —— 不回。探测挂到超时。\n- **cmd.exe / ConPTY**：静默。\n- **Linux console**（`vt`）：多数内核上回 `\\x1b[3;1;1;112;112;1;0x`。\n\n**2026 年你真要用吗**？几乎不要。回复除了「终端活着且懂 ECMA-48」之外提供零信息，而 DA1（`\\x1b[c` —— 见 `csi-da`）已经能更干净地答出型号 ID。若你在老代码里看到 DECREQTPARM，几乎可以肯定是 VT100 时代串线设置代码的遗留。请替换为：\n- `csi-da`（DA1，`\\x1b[c`）回答「这是 VT 类终端吗 / 哪个型号」。\n- `csi-da2-decoder`（DA2，`\\x1b[>c`）回答「模拟器类 + 固件版本」。\n- `xtversion`（`\\x1b[>0q`）回答「具体模拟器名 + 版本」（xterm 家族扩展）。\n\n**若必须用**：发 `\\x1b[1x`，从 stdin 读匹配 `\\x1b\\[3;\\d+;\\d+;\\d+;\\d+;\\d+;\\d+x` 的回复。**务必加 100 ms 超时** —— 否则 macOS Terminal 用户会让你卡死。别把 `xspeed`/`rspeed` 当真波特率；模拟器只发常量。唯一偶尔携带信号的字段是 `par`（校验），且只在串口直连模拟器（gtkterm、picocom —— 均不在我们 12 终端支持表内）上有意义。"
      },
      "parameters": [
        {
          "name": "Ps",
          "desc": {
            "en": "0 = enable unsolicited DECREPTPARM (almost universally ignored). 1 = request one solicited DECREPTPARM reply now.",
            "zh": "0 = 允许主动发送 DECREPTPARM（几乎所有实现都忽略）。1 = 立即请求一次被动 DECREPTPARM 回复。"
          }
        }
      ],
      "spec": "DEC VT100 User Guide §4 (DECREQTPARM / DECREPTPARM) / xterm-ctlseqs (CSI Ps x)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Solicited probe — read reply non-blocking with 100ms timeout.\\nprintf '\\\\033[1x'\\nIFS= read -rs -d x -t 0.1 reply </dev/tty 2>/dev/null\\necho \\\"DECREPTPARM: ${reply#$'\\\\033'}x\\\"   # expect \\\\x1b[3;1;1;<spd>;<spd>;1;0x"
        },
        {
          "lang": "python",
          "code": "import sys, re\\nsys.stdout.write('\\\\x1b[1x'); sys.stdout.flush()   # DECREQTPARM solicited\\n# ... terminal-aware read of reply (cbreak + select + timeout) ...\\n# Match: \\\\x1b[(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+)x\\n# Fields: sol par nbits xspeed rspeed clkmul flags"
        },
        {
          "lang": "go",
          "code": "// DECREQTPARM — expect \\\"\\\\x1b[3;...x\\\" reply within 100ms or fall back to DA1.\\nfmt.Print(\\\"\\\\x1b[1x\\\")"
        },
        {
          "lang": "javascript",
          "code": "// Node: probe + parse + fallback.\\nprocess.stdout.write('\\\\x1b[1x');\\n// On stdin 'data', match /\\\\x1b\\\\[3;(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+)x/\\n// — fields are mostly synthetic on modern emulators; prefer DA1 + XTVERSION."
        },
        {
          "lang": "c",
          "code": "/* Fire-and-forget DECREQTPARM; most modern emulators answer with constants. */\\nprintf(\\\"\\\\x1b[1x\\\"); fflush(stdout);\\n/* Parse reply (cbreak terminal): sscanf returned buf,\\n *   \\\"\\\\x1b[%d;%d;%d;%d;%d;%d;%dx\\\",\\n *   &sol, &par, &nbits, &xspd, &rspd, &clkmul, &flags); */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "yes",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "csi-da",
        "csi-da2-decoder",
        "xtversion",
        "decrqm",
        "decrpm-decoder"
      ]
    },
    {
      "slug": "deccara-decrara",
      "family": "CSI",
      "title": {
        "en": "DECCARA / DECRARA — Change / Reverse attributes in rectangular area (`CSI Pt;Pl;Pb;Pr;Ps;… $ r` / `$ t`)",
        "zh": "DECCARA / DECRARA —— 在矩形区域中改写 / 反转字符属性（`CSI Pt;Pl;Pb;Pr;Ps;… $ r` / `$ t`）"
      },
      "shortDesc": {
        "en": "Set or XOR SGR attributes across a rectangle of cells without rewriting any character data — the rectangular-attribute siblings of the copy/fill/erase ops in `dec-rect-ops`.",
        "zh": "对一矩形区域内的字符仅改写或异或 SGR 属性，不改动字符本身 —— `dec-rect-ops` 中复制 / 填充 / 擦除三件套的「矩形属性」兄弟。"
      },
      "bytes": {
        "canonical": "\\x1b[<Pt>;<Pl>;<Pb>;<Pr>;<Ps>;…$r    (DECCARA)    \\x1b[<Pt>;<Pl>;<Pb>;<Pr>;<Ps>;…$t    (DECRARA)",
        "octal": "\\033[3;5;10;30;1;7$r",
        "eEscape": "\\e[3;5;10;30;1;7$r",
        "literal": "ESC [ Pt ; Pl ; Pb ; Pr ; Ps … $ r   /   $ t",
        "hex": "1b 5b ... 24 72   /   24 74"
      },
      "description": {
        "en": "**DECCARA** — *Change Attributes in Rectangular Area* — and **DECRARA** — *Reverse Attributes in Rectangular Area* — round out the DEC rectangular-operation family (the others — DECCRA copy, DECFRA fill, DECERA erase, DECSERA selective erase — are documented in `dec-rect-ops`).\n\n**Geometry**: `Pt;Pl;Pb;Pr` are the rectangle's top row, left column, bottom row, right column (all 1-indexed, inclusive). The same rect-ops conventions from `decsace` apply — DECSACE selects whether 'rectangle' means strictly the cell-rectangle (block) or wraps line-by-line (stream).\n\n**Attribute list**: `Ps;…` is an SGR-style list of attribute selectors. The repertoire is DEC's reduced SGR set: `0` = clear all attributes, `1` = bold, `4` = underline, `5` = blink, `7` = reverse video, `22` = bold off, `24` = underline off, `25` = blink off, `27` = reverse off. Standard 8-color fg/bg (`30–37` / `40–47`) and ECMA-48 extended-color (`38;5;n`, `48;2;r;g;b`) are honoured by xterm-class emulators; pure DEC hardware ignored them. Empty `Ps;…` (just `\\x1b[Pt;Pl;Pb;Pr$r`) is treated as `0` = clear.\n\n**Semantic difference**:\n- **DECCARA** ($ r) — *sets* the listed attributes on every cell. Unlisted attributes are LEFT UNCHANGED (it's not a full SGR overwrite — it's selective). To replace all attributes, lead with `0` then re-list (e.g. `\\x1b[1;1;24;80;0;1;7$r` clears then applies bold + reverse).\n- **DECRARA** ($ t) — *XORs* the listed attributes on every cell. A cell that was bold becomes non-bold; one that wasn't becomes bold. Used by some screen renderers to implement a 'flash this region' UX without saving + restoring cell state.\n\n**No character data is touched** — both ops only modify the attribute layer at each cell. This is the killer feature: a diff highlighter can re-attribute a line block without retyping the chars, and a focus-mode TUI can dim the non-focused panes by XORing dim across them.\n\n**DECSACE coupling**: when DECSACE has selected stream-mode (`\\x1b[2*x`), the same DECCARA / DECRARA call interprets `Pt;Pl` as a single stream-start position and `Pb;Pr` as a stream-end position — the affected cells are every cell between the two positions following normal text flow, not a block. Use `\\x1b[0*x` (or omit) to keep block semantics. See `decsace`.\n\n**Coverage**: **xterm** = full both ops including extended colour. **Kitty** = full DECCARA, DECRARA partial. **WezTerm** / **Ghostty** = full. **Konsole** = full. **iTerm2** = partial (extended colour not honoured in DECCARA). **Alacritty** = no-op (silently consumed). **Windows Terminal** = no-op pre-1.20; partial DECCARA after. **macOS Terminal** / **Linux console** / **cmd / ConPTY** = no-op.\n\n**Recommended use**: yes for xterm-class emulators with explicit feature probe (DECRQM `?92` aka DECSACE — see `decsace`, plus `xtversion` for emulator family check). For portable code, simulate via DECCRA + write-with-SGR or by stream-mode SGR over the cells.",
        "zh": "**DECCARA** —— *矩形区域内属性改写* —— 和 **DECRARA** —— *矩形区域内属性反转* —— 完整化了 DEC 矩形操作族（其余 —— DECCRA 复制、DECFRA 填充、DECERA 擦除、DECSERA 选择性擦除 —— 见 `dec-rect-ops`）。\n\n**几何**：`Pt;Pl;Pb;Pr` 为矩形上行 / 左列 / 下行 / 右列（皆 1 起算，闭区间）。与 `decsace` 相同的矩形约定 —— DECSACE 决定「矩形」是严格的单元块还是按行流式包裹。\n\n**属性列表**：`Ps;…` 是类 SGR 的属性选择子列表。DEC 缩减集：`0` = 清所有属性、`1` = 加粗、`4` = 下划线、`5` = 闪烁、`7` = 反相、`22` = 取消加粗、`24` = 取消下划线、`25` = 取消闪烁、`27` = 取消反相。xterm 家族还接受标准 8 色前后景（`30–37` / `40–47`）以及 ECMA-48 扩展色（`38;5;n`、`48;2;r;g;b`）；DEC 硬件忽略。空 `Ps;…`（即 `\\x1b[Pt;Pl;Pb;Pr$r`）等同 `0` = 清。\n\n**语义差**：\n- **DECCARA**（$ r）—— *设置*所列属性到每个单元。未列出属性保持不变（不是完全 SGR 覆写 —— 是选择性的）。要换掉所有属性，先列 `0` 再列具体（如 `\\x1b[1;1;24;80;0;1;7$r` 先清再设加粗 + 反相）。\n- **DECRARA**（$ t）—— *按位异或*每个单元上所列属性。原本加粗的变为非加粗；不加粗的变为加粗。某些屏幕渲染器用它实现「闪烁此区域」UX，省下保存 + 恢复单元状态。\n\n**不动字符数据** —— 两者只改单元的属性层。这是杀手特性：diff 高亮器可以重写一行块的属性而不重打字符；focus 模式 TUI 可对非焦点窗格 XOR 一次 dim 实现暗化。\n\n**DECSACE 耦合**：当 DECSACE 选择流模式（`\\x1b[2*x`）时，DECCARA / DECRARA 把 `Pt;Pl` 解释为流起始位置、`Pb;Pr` 为流结束位置 —— 受影响单元为两个位置间按正常文本流的每个单元，而非块。要保块语义，发 `\\x1b[0*x`（或省略）。见 `decsace`。\n\n**覆盖度**：**xterm** = 双向完整含扩展色。**Kitty** = DECCARA 完整、DECRARA 部分。**WezTerm** / **Ghostty** = 完整。**Konsole** = 完整。**iTerm2** = 部分（DECCARA 忽略扩展色）。**Alacritty** = 静默吞掉。**Windows Terminal** = 1.20 前静默；之后 DECCARA 部分。**macOS Terminal** / **Linux console** / **cmd / ConPTY** = 静默。\n\n**推荐用法**：xterm 家族 + 显式特性探测（DECRQM `?92` 即 DECSACE，见 `decsace`；外加 `xtversion` 检测模拟器家族）下放心用。要可移植代码，用 DECCRA + 带 SGR 重写、或对单元流式发 SGR 模拟。"
      },
      "parameters": [
        {
          "name": "Pt;Pl;Pb;Pr",
          "desc": {
            "en": "Top row, left col, bottom row, right col (1-indexed inclusive). Stream- vs block-semantics chosen by DECSACE.",
            "zh": "上行、左列、下行、右列（1 起算、闭区间）。流式 / 块式语义由 DECSACE 决定。"
          }
        },
        {
          "name": "Ps;…",
          "desc": {
            "en": "SGR-style attribute selectors. Common: 0 clear, 1 bold, 4 underline, 5 blink, 7 reverse, 22/24/25/27 off-variants, 30–37 / 40–47 colours, 38;5;n / 48;2;r;g;b extended. Empty list = clear.",
            "zh": "类 SGR 属性选择子。常见：0 清、1 加粗、4 下划线、5 闪烁、7 反相、22 / 24 / 25 / 27 取消、30–37 / 40–47 颜色、38;5;n / 48;2;r;g;b 扩展色。空列表 = 清。"
          }
        }
      ],
      "spec": "DEC VT510 RM (DECCARA / DECRARA) / xterm-ctlseqs (CSI ... $ r / $ t)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Set bold + reverse on rows 3-10, cols 5-30 without touching characters.\\nprintf '\\\\033[3;5;10;30;0;1;7$r'"
        },
        {
          "lang": "python",
          "code": "import sys\\n# XOR underline on a one-line ribbon (rows 1, cols 1..80) — 'flash on'.\\nsys.stdout.write('\\\\x1b[1;1;1;80;4$t')\\nsys.stdout.flush()"
        },
        {
          "lang": "go",
          "code": "// 'Dim non-focused panes' — XOR SGR 2 (dim) over the unselected region.\\nfmt.Print(\\\"\\\\x1b[1;1;24;40;2$t\\\")     // dim left half\\n// later, to undim, XOR again with same selector:\\nfmt.Print(\\\"\\\\x1b[1;1;24;40;2$t\\\")"
        },
        {
          "lang": "javascript",
          "code": "// Highlight diff hunk: reverse-video lines 12-15 across full width.\\nprocess.stdout.write('\\\\x1b[12;1;15;80;7$r');"
        },
        {
          "lang": "c",
          "code": "/* Replace all attrs in rect with red-on-default. */\\nprintf(\\\"\\\\x1b[%d;%d;%d;%d;0;31$r\\\", t, l, b, r);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "partial",
        "cmd": "no",
        "kitty": "partial",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "partial",
        "konsole": "yes"
      },
      "related": [
        "dec-rect-ops",
        "decsace",
        "decsed-decsel",
        "sgr-reset"
      ]
    },
    {
      "slug": "decncsm",
      "family": "DEC",
      "title": {
        "en": "DECNCSM — No Clear Screen on column-mode change (`CSI ? 95 h / l`)",
        "zh": "DECNCSM —— 切列宽时不清屏（`CSI ? 95 h / l`）"
      },
      "shortDesc": {
        "en": "Suppress DECCOLM's (and DECSCPP's) implicit screen-clear side-effect. With DECNCSM set, switching between 80- and 132-column modes preserves cell contents instead of wiping them.",
        "zh": "抑制 DECCOLM（及 DECSCPP）切列宽时隐含的清屏副作用。DECNCSM 开启后，在 80 / 132 列之间切换会保留单元内容，而非清空。"
      },
      "bytes": {
        "canonical": "\\x1b[?95h    (set — preserve)    \\x1b[?95l    (reset — clear)",
        "octal": "\\033[?95h",
        "eEscape": "\\e[?95h",
        "literal": "ESC [ ? 9 5 h   /   ESC [ ? 9 5 l",
        "hex": "1b 5b 3f 39 35 68 / 6c"
      },
      "description": {
        "en": "DECNCSM — *No Clear Screen on column-mode change* — is the modifier mode that controls the clear-on-resize side-effect of `deccolm` (DEC 132-Column Mode, `?3h/l`) and `decscpp` (Select Columns Per Page, `CSI Pn $|`).\n\n**Reset (default, `\\x1b[?95l`)** — DECCOLM and DECSCPP behave as historically specified: switching between 80- and 132-column modes **clears** the screen, homes the cursor, resets DECSTBM scrolling-region to full screen, and resets DECSLRM left/right margins. This is the original VT100 hardware behaviour — the CRT couldn't reflow text, so the screen was wiped.\n\n**Set (`\\x1b[?95h`)** — DECCOLM / DECSCPP **preserve** cell contents on column-mode change. Cells outside the new width are dropped (or hidden in some implementations until a return to wider columns). DECSTBM and DECSLRM still reset; cursor is repositioned to fit the new geometry. This is the modern terminal-emulator-friendly default for users who want to widen / narrow without losing context.\n\n**Why this exists** — apps that need legacy DECCOLM behaviour (xterm running in `allowC132` mode for a VT220 conformance test) must clear; modern apps that want responsive resize (browser-style 'when the user toggles width, keep my buffer') want preserve. DECNCSM gives the application code the choice. Some users wire it to `?95h` permanently in their xterm resources (`*decTerminalID: vt320` + `*setColumnRequired: false`) for friendlier resize ergonomics.\n\n**Interaction with `deccolm` / `decscpp`**:\n- `\\x1b[?95l` + `\\x1b[?3h` → switch to 132-col mode, **screen cleared** (legacy).\n- `\\x1b[?95h` + `\\x1b[?3h` → switch to 132-col mode, **contents preserved**.\n- Same pairing applies to `\\x1b[80$|` / `\\x1b[132$|` (DECSCPP).\n\n**Important non-effect**: DECNCSM only suppresses the clear *from DECCOLM / DECSCPP*. RIS (`\\x1bc`), DECSTR (`\\x1b[!p` — see `decstr-side-effects`), and explicit ED (`\\x1b[2J`) all still clear regardless of DECNCSM state. Don't reach for DECNCSM as a generic 'don't clear my screen' switch — it's specifically scoped to column-mode toggles.\n\n**Coverage**: **xterm** = full (the canonical implementation). **Kitty** / **WezTerm** / **Ghostty** = full. **iTerm2** = full. **Konsole** = full. **Windows Terminal** = partial (DECCOLM itself is gated by config, but when enabled DECNCSM is honoured ≥ 1.18). **Alacritty** = effectively no-op (DECCOLM is itself a no-op, so DECNCSM has nothing to gate). **Linux console** / **macOS Terminal** / **cmd / ConPTY** / **gnome-terminal** = no-op.\n\n**Query**: `\\x1b[?95$p` (DECRQM — see `decrqm` / `decrpm-decoder`) — reply `\\x1b[?95;1$y` if set, `\\x1b[?95;2$y` if reset.",
        "zh": "DECNCSM —— *切列宽时不清屏* —— 是控制 `deccolm`（DEC 132 列模式，`?3h/l`）与 `decscpp`（每页列数选择，`CSI Pn $|`）「切宽即清屏」副作用的修饰模式。\n\n**关闭（默认，`\\x1b[?95l`）** —— DECCOLM 与 DECSCPP 按历史规范运作：切 80 / 132 列时**清屏**、光标归位、DECSTBM 滚动区重置全屏、DECSLRM 左右边距重置。这是 VT100 硬件原始行为 —— CRT 无法重排文本，屏幕被擦掉。\n\n**开启（`\\x1b[?95h`）** —— DECCOLM / DECSCPP **保留**单元内容。新宽度外的单元被丢弃（或部分实现下隐藏到切回更宽列时再现）。DECSTBM 与 DECSLRM 仍重置；光标按新几何重定位。这是现代终端模拟器对希望「拉宽 / 缩窄不丢上下文」用户更友好的默认。\n\n**为何存在** —— 需要历史 DECCOLM 行为（如 xterm 在 `allowC132` 模式下做 VT220 一致性测试）的程序必须清；想做响应式缩放（「用户切宽时保留缓冲」浏览器式语义）的现代程序则要保留。DECNCSM 把选择权交给应用代码。部分用户在 xterm 资源里永久打开（`*decTerminalID: vt320` + `*setColumnRequired: false`），让缩放体验更顺。\n\n**与 `deccolm` / `decscpp` 的交互**：\n- `\\x1b[?95l` + `\\x1b[?3h` → 切到 132 列，**清屏**（历史）。\n- `\\x1b[?95h` + `\\x1b[?3h` → 切到 132 列，**保留内容**。\n- 同样适用于 `\\x1b[80$|` / `\\x1b[132$|`（DECSCPP）。\n\n**重要的非作用**：DECNCSM 只抑制 *DECCOLM / DECSCPP 引起的清屏*。RIS（`\\x1bc`）、DECSTR（`\\x1b[!p`，见 `decstr-side-effects`）、显式 ED（`\\x1b[2J`）仍照清不误。别把 DECNCSM 当通用「别清屏」开关 —— 它只作用于列宽切换。\n\n**覆盖度**：**xterm** = 完整（标准实现）。**Kitty** / **WezTerm** / **Ghostty** = 完整。**iTerm2** = 完整。**Konsole** = 完整。**Windows Terminal** = 部分（DECCOLM 本身受配置控制，启用后 1.18+ 起 DECNCSM 起效）。**Alacritty** = 实际无作用（DECCOLM 自身就是 no-op，DECNCSM 无东西可门控）。**Linux console** / **macOS Terminal** / **cmd / ConPTY** / **gnome-terminal** = 无作用。\n\n**查询**：`\\x1b[?95$p`（DECRQM，见 `decrqm` / `decrpm-decoder`）—— 设置时回 `\\x1b[?95;1$y`，重置时回 `\\x1b[?95;2$y`。"
      },
      "spec": "DEC VT510 RM (DECNCSM) / xterm-ctlseqs (CSI ? 95 h / l)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Enable preserve-on-resize, then switch to 132 columns without losing buffer.\\nprintf '\\\\033[?95h'   # DECNCSM set — no clear on column-mode change\\nprintf '\\\\033[?3h'    # DECCOLM 132 col (with DECNCSM, contents survive)"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\\\x1b[?95h')      # don't clear on column toggle\\nsys.stdout.write('\\\\x1b[132$|')      # DECSCPP to 132 cols, preserving buffer\\nsys.stdout.flush()"
        },
        {
          "lang": "go",
          "code": "// Persist DECNCSM at startup, restore at exit.\\nfmt.Print(\\\"\\\\x1b[?95s\\\")             // XTSAVE — push current value\\nfmt.Print(\\\"\\\\x1b[?95h\\\")             // enable preserve\\ndefer fmt.Print(\\\"\\\\x1b[?95r\\\")       // XTRESTORE on exit"
        },
        {
          "lang": "javascript",
          "code": "// Probe DECNCSM state before deciding whether to defensively redraw on resize.\\nprocess.stdout.write('\\\\x1b[?95$p');\\n// expect reply \\\\x1b[?95;1$y (set) or ?95;2$y (reset)"
        },
        {
          "lang": "c",
          "code": "/* Disable preserve (restore historical clear-on-DECCOLM). */\\nprintf(\\\"\\\\x1b[?95l\\\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "no",
        "konsole": "yes"
      },
      "related": [
        "deccolm",
        "decscpp",
        "decstbm",
        "decslrm",
        "decrqm",
        "xtsave-xtrestore"
      ]
    },
    {
      "slug": "decps-play-sound",
      "family": "CSI",
      "title": {
        "en": "DECPS — Play Sound (`CSI Pv ; Pd ; Pn1 [; …] , ~`)",
        "zh": "DECPS —— 播放声音（`CSI Pv ; Pd ; Pn1 [; …] , ~`）"
      },
      "shortDesc": {
        "en": "DEC VT520 musical-tone playback — `Pv` volume, `Pd` duration, then one or more `Pn` MIDI-style note numbers. Niche but implemented by xterm, WezTerm, Ghostty, mlterm; the only ANSI way to make the terminal beep at a specific pitch.",
        "zh": "DEC VT520 音乐音播放 —— `Pv` 音量、`Pd` 时长、随后一个或多个 `Pn` 类 MIDI 音符号。冷门但 xterm、WezTerm、Ghostty、mlterm 都实现 —— 这是用 ANSI 让终端按指定音高响铃的唯一方式。"
      },
      "bytes": {
        "canonical": "\\x1b[<Pv>;<Pd>;<Pn1>[;<Pn2>…],~",
        "octal": "\\033[5;8;33,~",
        "eEscape": "\\e[5;8;33,~",
        "literal": "ESC [ Pv ; Pd ; Pn1 [; …] , ~",
        "hex": "1b 5b ... 2c 7e"
      },
      "description": {
        "en": "DECPS — *Play Sound* — was added in the DEC VT520 to play one or more tones through the terminal's beeper. Xterm and several modern emulators (WezTerm, Ghostty, mlterm) implement it; for everyone else it's a silent no-op (which is usually the desired fallback — accessibility-conscious users disable terminal sound anyway).\n\n**Parameters**:\n- `Pv` — volume (0 = off, 1–3 = low, 4–7 = high). Most emulators map to a binary 'play / silent' since their underlying audio API has no volume control here.\n- `Pd` — duration in 1/32-of-a-second units; `8` = 0.25s. Range 0–255.\n- `Pn1; Pn2; …` — one or more MIDI-ish note numbers from 0 (silence) through 25 (`C7` in the DEC table). 0 = rest, 1 = `C5`, 2 = `C#5`, … 13 = `C6`, … 25 = `C7`. Multiple notes are played sequentially (not chord-style), each at the same `Pv`/`Pd`.\n\n**Common note codes** (DEC VT520 RM Appendix A):\n- `1`=C5  `2`=C#5  `3`=D5  `4`=D#5  `5`=E5  `6`=F5  `7`=F#5  `8`=G5  `9`=G#5  `10`=A5  `11`=A#5  `12`=B5\n- `13`=C6  `14`=C#6  …  `25`=C7\n\n**'Ode to Joy' opener** as a sanity-check tune (E E F G G F E D C C D E E D D, all at `Pv=5 Pd=4`): `\\x1b[5;4;5;5;6;8;8;6;5;3;1;1;3;5;5;3;3,~`.\n\n**Use cases**: long-build completion chime (CI tool plays a 2-note 'done' upon `make` exit), distinctive failure tone (red SGR + DECPS 3-note descending pattern), accessibility-friendly notification when OSC 9 desktop-notification would be too noisy. Don't use for every keystroke — it's blocking on most emulators (the terminal's audio thread serialises with the parser).\n\n**Coverage**: **xterm** = full (reference). **WezTerm** = full ≥ 20240127. **Ghostty** = full. **mlterm** = full. **Konsole** = partial (volume ignored, plays the system bell instead). **iTerm2** = partial (plays a single beep regardless of Pn). **Kitty** = no-op by default; opt-in via `enable_audio_bell`. **Alacritty** / **Linux console** / **macOS Terminal** / **Windows Terminal** / **cmd / ConPTY** / **gnome-terminal** = silent no-op.\n\n**Accessibility note**: respect `NO_COLOR`-style hints — many users have terminal sound permanently muted at the OS level. Don't lean on DECPS for *critical* signals; treat it as a polish nicety alongside a visible status indicator.",
        "zh": "DECPS —— *播放声音* —— DEC VT520 新增，用终端蜂鸣器播放一段或多段音。xterm 与若干现代模拟器（WezTerm、Ghostty、mlterm）已实现；其他终端为静默 no-op（多数场景这正是希望的回退 —— 注重无障碍的用户也都关掉了终端声音）。\n\n**参数**：\n- `Pv` —— 音量（0 = 静音、1–3 = 低、4–7 = 高）。多数模拟器底层音频 API 没音量控制，映射为「响 / 不响」二态。\n- `Pd` —— 时长，单位 1/32 秒；`8` = 0.25 秒。范围 0–255。\n- `Pn1; Pn2; …` —— 一个或多个类 MIDI 音符号，0（静音）至 25（DEC 表中的 `C7`）。0 = 休止、1 = `C5`、2 = `C#5`……13 = `C6`……25 = `C7`。多音顺序播放（不是和弦），每个用相同 `Pv`/`Pd`。\n\n**常用音符号**（DEC VT520 RM 附录 A）：\n- `1`=C5  `2`=C#5  `3`=D5  `4`=D#5  `5`=E5  `6`=F5  `7`=F#5  `8`=G5  `9`=G#5  `10`=A5  `11`=A#5  `12`=B5\n- `13`=C6  `14`=C#6  …  `25`=C7\n\n**「欢乐颂」前奏**（E E F G G F E D C C D E E D D，皆 `Pv=5 Pd=4`）：`\\x1b[5;4;5;5;6;8;8;6;5;3;1;1;3;5;5;3;3,~`。\n\n**使用场景**：长构建完成提示（CI 工具在 `make` 退出时播 2 音「完成」）、失败提示（红色 SGR + DECPS 3 音下行）、OSC 9 桌面通知过于嘈杂时的无障碍提示。别按每次按键播 —— 多数模拟器是阻塞的（音频线程与解析器串行）。\n\n**覆盖度**：**xterm** = 完整（参考实现）。**WezTerm** = 20240127+ 完整。**Ghostty** = 完整。**mlterm** = 完整。**Konsole** = 部分（忽略音量，改播系统铃）。**iTerm2** = 部分（无视 Pn，固定单声）。**Kitty** = 默认 no-op；通过 `enable_audio_bell` 启用。**Alacritty** / **Linux console** / **macOS Terminal** / **Windows Terminal** / **cmd / ConPTY** / **gnome-terminal** = 静默 no-op。\n\n**无障碍提示**：尊重 `NO_COLOR` 类暗示 —— 不少用户在 OS 层永久静音了终端声。别把 DECPS 当 *关键*信号；与可见状态指示一起用即可。"
      },
      "parameters": [
        {
          "name": "Pv",
          "desc": {
            "en": "Volume 0–7 (0 silent, 1–3 low, 4–7 high). Most emulators binary on/off.",
            "zh": "音量 0–7（0 静音、1–3 低、4–7 高）。多数模拟器仅二态。"
          }
        },
        {
          "name": "Pd",
          "desc": {
            "en": "Duration in 1/32-second units. 8 = 0.25s. Range 0–255.",
            "zh": "时长，单位 1/32 秒。8 = 0.25 秒。范围 0–255。"
          }
        },
        {
          "name": "Pn",
          "desc": {
            "en": "Note number 0–25 (0 = rest, 1 = C5, … 25 = C7). Multiple Pn play sequentially.",
            "zh": "音符号 0–25（0 = 休止、1 = C5、…25 = C7）。多个 Pn 顺序播放。"
          }
        }
      ],
      "spec": "DEC VT520 RM Appendix A (DECPS) / xterm-ctlseqs (CSI Pv ; Pd ; Ps ; ... , ~)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Single quarter-second A5 'ding' at medium volume.\\nprintf '\\\\033[5;8;10,~'"
        },
        {
          "lang": "python",
          "code": "import sys\\n# Build-complete two-note chime: C6 then E6, half second each.\\nsys.stdout.write('\\\\x1b[5;16;13;17,~')\\nsys.stdout.flush()"
        },
        {
          "lang": "go",
          "code": "// Failure tone: descending three notes E5 -> C5 -> A4-equivalent rest.\\nfmt.Print(\\\"\\\\x1b[6;6;5;3;1,~\\\")"
        },
        {
          "lang": "javascript",
          "code": "// 'Ode to Joy' opening line.\\nprocess.stdout.write('\\\\x1b[5;4;5;5;6;8;8;6;5;3;1;1;3;5;5;3;3,~');"
        },
        {
          "lang": "c",
          "code": "/* Three quick high-pitched warning beeps. */\\nprintf(\\\"\\\\x1b[7;2;25;25;25,~\\\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "partial",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "no",
        "konsole": "partial"
      },
      "related": [
        "c0-controls",
        "decswbv-decsmbv",
        "osc-notification"
      ]
    },
    {
      "slug": "single-locking-shift",
      "family": "ESC",
      "title": {
        "en": "Single Shift / Locking Shift family — SS2 / SS3 / LS2 / LS3 / LS1R / LS2R / LS3R",
        "zh": "单次切换 / 锁定切换族 —— SS2 / SS3 / LS2 / LS3 / LS1R / LS2R / LS3R"
      },
      "shortDesc": {
        "en": "ISO 2022 character-set switching: invoke G2 / G3 once (SS2 / SS3), or lock GL / GR to a different G-set (LS2 / LS3 / LS1R / LS2R / LS3R). Pairs with `\\x1b(` / `\\x1b)` / `\\x1b*` / `\\x1b+` G-set designators.",
        "zh": "ISO 2022 字符集切换：单次调用 G2 / G3（SS2 / SS3），或将 GL / GR 锁定到不同 G 集（LS2 / LS3 / LS1R / LS2R / LS3R）。与 `\\x1b(` / `\\x1b)` / `\\x1b*` / `\\x1b+` G 集指派配对。"
      },
      "bytes": {
        "canonical": "\\x1bN  SS2     \\x1bO  SS3     \\x1bn  LS2     \\x1bo  LS3     \\x1b~  LS1R     \\x1b}  LS2R     \\x1b|  LS3R",
        "octal": "\\033N / \\033O / \\033n / \\033o / \\033~ / \\033} / \\033|",
        "eEscape": "\\eN / \\eO / \\en / \\eo / \\e~ / \\e} / \\e|",
        "literal": "ESC N / ESC O / ESC n / ESC o / ESC ~ / ESC } / ESC |",
        "hex": "1b 4e / 1b 4f / 1b 6e / 1b 6f / 1b 7e / 1b 7d / 1b 7c"
      },
      "description": {
        "en": "The ISO 2022 / ECMA-35 character-set machinery uses four registers (G0, G1, G2, G3) each pointing at a designated character set, with two 'pointers' (GL = invoked for 0x20–0x7F, GR = invoked for 0xA0–0xFF) selecting which G-set is currently active for which byte range. The single-shift and locking-shift families switch the active mapping.\n\n**Designators** (set what each G-register points at — covered separately, listed here for context):\n- `\\x1b(<final>` — designate G0 (e.g. `\\x1b(0` = G0 → DEC Special Graphics, the line-drawing set)\n- `\\x1b)<final>` — designate G1\n- `\\x1b*<final>` — designate G2\n- `\\x1b+<final>` — designate G3\n\n**Invokers** (switch GL / GR to point at a different G-register — this entry):\n- **SS2** `\\x1bN` (`ESC N`) — *Single Shift 2* — the **next single 7-bit byte** is interpreted via G2, then GL reverts. Useful for inserting a single character from a designated set without locking.\n- **SS3** `\\x1bO` (`ESC O`) — *Single Shift 3* — same as SS2 but uses G3. Note: `ESC O` is also the SS3 prefix in many keypad / function key codes (`\\x1bOA` = up-arrow in application mode — see `keymap`), which is the same SS3 in spirit.\n- **LS2** `\\x1bn` (`ESC n`) — *Locking Shift 2* — point GL at G2 until a subsequent shift. All subsequent 7-bit bytes go through G2.\n- **LS3** `\\x1bo` (`ESC o`) — *Locking Shift 3* — point GL at G3.\n- **LS1R** `\\x1b~` (`ESC ~`) — *Locking Shift 1 Right* — point GR at G1 (8-bit byte range 0xA0–0xFF flows through G1).\n- **LS2R** `\\x1b}` (`ESC }`) — *Locking Shift 2 Right* — point GR at G2.\n- **LS3R** `\\x1b|` (`ESC |`) — *Locking Shift 3 Right* — point GR at G3.\n- (LS0 = `\\x0F` SI and LS1 = `\\x0E` SO are C0 single-byte controls — see `c0-controls`.)\n\n**Why you'd see these in the wild**:\n1. DEC line drawing — `\\x1b(0` designates G0 → DEC Special Graphics, then code 0x6C (`l`) renders as `┌`. Frequently used by `ncurses` for box-drawing on non-UTF-8 terminals.\n2. Legacy mainframe / serial-line apps that ship 7-bit binary 'paths' through GR-mapped G-sets to avoid 8-bit MSB-stripping middleware.\n3. NRCS (National Replacement Character Sets) — e.g. `\\x1b)A` designates G1 → UK NRCS (substitutes `£` for `#`).\n4. Telnet/SSH options for 7-bit data paths.\n\n**Modern UTF-8 era reality**: ISO 2022 is largely vestigial. Terminals that announce UTF-8 (`\\x1b%G` / `\\x1b%@` is the UTF-8 designate / leave-UTF-8 pair) typically interpret incoming bytes as UTF-8 and **ignore** SS2/SS3/LS2/LS3 entirely. The exception is DEC Special Graphics — kept alive because `ncurses` still emits `\\x1b(0` for line drawing on terminals that don't have full Unicode box glyphs.\n\n**Coverage**: **xterm** = full (reference). **kitty** / **WezTerm** / **iTerm2** / **Ghostty** / **Konsole**: support `\\x1b(0` line-drawing path; SS2/SS3/LS2/LS3/LS{1,2,3}R variously implemented but the practical use case is line drawing. **gnome-terminal** = full. **Alacritty** = partial (DEC Special Graphics + UTF-8 only). **Linux console** = partial (`\\x1b(0` works, more exotic invokers are no-ops). **Windows Terminal / cmd / ConPTY**: line-drawing via `\\x1b(0` partial; locking-shift right (`\\x1b~`/`\\x1b}`/`\\x1b|`) no-op. **macOS Terminal** = partial. Don't rely on anything beyond DEC Special Graphics + designators unless you've specifically probed.",
        "zh": "ISO 2022 / ECMA-35 字符集机制使用四个寄存器（G0、G1、G2、G3），每个指向一个被指派的字符集；再用两个「指针」（GL 调用 0x20–0x7F、GR 调用 0xA0–0xFF）选定当前生效的 G 集。单次切换与锁定切换族切换这个活跃映射。\n\n**指派**（设定各 G 寄存器指向哪 —— 单独成项，此处仅引：）\n- `\\x1b(<末字节>` —— 指派 G0（如 `\\x1b(0` = G0 → DEC Special Graphics 制表线集）\n- `\\x1b)<末字节>` —— 指派 G1\n- `\\x1b*<末字节>` —— 指派 G2\n- `\\x1b+<末字节>` —— 指派 G3\n\n**调用**（把 GL / GR 切到指向不同 G 寄存器 —— 本条目）：\n- **SS2** `\\x1bN`（`ESC N`）—— *Single Shift 2* —— **紧接的下一个 7 位字节**按 G2 解释，之后 GL 复原。用于无需锁定地插一个字符。\n- **SS3** `\\x1bO`（`ESC O`）—— *Single Shift 3* —— 同 SS2，但用 G3。注：许多小键盘 / 功能键码（应用模式下的 `\\x1bOA` = 上箭头 —— 见 `keymap`）也以 `ESC O` 起始，本质上同样是 SS3。\n- **LS2** `\\x1bn`（`ESC n`）—— *Locking Shift 2* —— 把 GL 指向 G2，直到下一次切换。后续 7 位字节都过 G2。\n- **LS3** `\\x1bo`（`ESC o`）—— *Locking Shift 3* —— 把 GL 指向 G3。\n- **LS1R** `\\x1b~`（`ESC ~`）—— *Locking Shift 1 Right* —— 把 GR 指向 G1（8 位 0xA0–0xFF 流经 G1）。\n- **LS2R** `\\x1b}`（`ESC }`）—— *Locking Shift 2 Right* —— GR 指向 G2。\n- **LS3R** `\\x1b|`（`ESC |`）—— *Locking Shift 3 Right* —— GR 指向 G3。\n- （LS0 = `\\x0F` SI、LS1 = `\\x0E` SO 是 C0 单字节控制 —— 见 `c0-controls`。）\n\n**实际场合**：\n1. DEC 线图 —— `\\x1b(0` 指派 G0 → DEC Special Graphics，码 0x6C（`l`）渲染为 `┌`。`ncurses` 在非 UTF-8 终端上常用。\n2. 旧主机 / 串线程序，把 7 位「二进制路径」通过 GR 绑定的 G 集穿过会剥 MSB 的中间件。\n3. NRCS（国家替换字符集）—— 如 `\\x1b)A` 指派 G1 → 英式 NRCS（用 `£` 替 `#`）。\n4. Telnet / SSH 的 7 位数据通道选项。\n\n**UTF-8 时代的现实**：ISO 2022 大体上是残留。声明 UTF-8（`\\x1b%G` / `\\x1b%@` 是 UTF-8 进 / 出对）后的终端通常把输入按 UTF-8 解释、**忽略** SS2/SS3/LS2/LS3。例外是 DEC Special Graphics —— 因 `ncurses` 仍对无完整 Unicode 制表线的终端发 `\\x1b(0` 而保活。\n\n**覆盖度**：**xterm** = 完整（标准）。**kitty** / **WezTerm** / **iTerm2** / **Ghostty** / **Konsole**：支持 `\\x1b(0` 制表线路径；SS2/SS3/LS2/LS3/LS{1,2,3}R 实现程度参差不齐，但实际用例就是制表线。**gnome-terminal** = 完整。**Alacritty** = 部分（仅 DEC Special Graphics + UTF-8）。**Linux console** = 部分（`\\x1b(0` 可用，更冷门的调用器无效）。**Windows Terminal / cmd / ConPTY**：`\\x1b(0` 制表线部分支持；右侧锁定切换（`\\x1b~`/`\\x1b}`/`\\x1b|`）无效。**macOS Terminal** = 部分。除非已专门探测，否则别依赖 DEC Special Graphics + 指派以外的任何东西。"
      },
      "spec": "ISO 2022 / ECMA-35 / xterm-ctlseqs (Single Shift + Locking Shift family)",
      "examples": [
        {
          "lang": "bash",
          "code": "# DEC line-drawing top-left corner: designate G0 -> SpecGraphics, emit 'l', restore.\\nprintf '\\\\033(0l\\\\033(B'   # 'l' renders as ┌; \\\\033(B restores G0 -> US-ASCII"
        },
        {
          "lang": "python",
          "code": "# Box from DEC special graphics: ┌──┐ / │  │ / └──┘\\nimport sys\\nsys.stdout.write('\\\\x1b(0lqqk\\\\nx  x\\\\nmqqj\\\\x1b(B\\\\n')\\nsys.stdout.flush()"
        },
        {
          "lang": "go",
          "code": "// Single-shift: print one G2 char without locking.\\n// (G2 designated to DEC special graphics first.)\\nfmt.Print(\\\"\\\\x1b*0\\\")   // designate G2 -> SpecGraphics\\nfmt.Print(\\\"\\\\x1bNl\\\")    // SS2 then 'l' -> single ┌\\nfmt.Print(\\\"X\\\")          // back to GL=G0 (US-ASCII) -> literal 'X'"
        },
        {
          "lang": "javascript",
          "code": "// Lock GR to G2 for an 8-bit data path. Reset with LS0 (SI = \\\\x0f).\\nprocess.stdout.write('\\\\x1b*A\\\\x1b}');  // G2 -> UK NRCS, LS2R\\n// ... write 8-bit bytes; £ now lives at 0xA3 via G2\\nprocess.stdout.write('\\\\x1b~');           // LS1R back to G1 default"
        },
        {
          "lang": "c",
          "code": "/* ncurses-style box-drawing entry; designate G0 to SpecGraphics. */\\nprintf(\\\"\\\\x1b(0\\\");\\nputs(\\\"lqqk\\\");  /* ┌──┐ */\\nputs(\\\"x  x\\\");  /* │  │ */\\nputs(\\\"mqqj\\\");  /* └──┘ */\\nprintf(\\\"\\\\x1b(B\\\");                /* restore G0 to US-ASCII */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "partial",
        "iterm2": "partial",
        "wt": "partial",
        "cmd": "partial",
        "kitty": "partial",
        "alacritty": "partial",
        "wezterm": "partial",
        "ghostty": "partial",
        "gnometerm": "yes",
        "konsole": "partial"
      },
      "related": [
        "c0-controls",
        "c1-controls"
      ]
    },
    {
      "slug": "dectabsr",
      "family": "CSI",
      "title": {
        "en": "DECTABSR — Tab Stop Report (`CSI 2 $ w`)",
        "zh": "DECTABSR —— 制表位报告（`CSI 2 $ w`）"
      },
      "shortDesc": {
        "en": "Ask the terminal to dump its current horizontal tab stops as a DCS report. Closes the round-trip story: set via HTS (`esc-hts`), clear via TBC (`csi-tbc`), query the current set via DECTABSR.",
        "zh": "让终端以 DCS 报告形式输出当前水平制表位。补全往返链：HTS（`esc-hts`）设置、TBC（`csi-tbc`）清除、DECTABSR 查询当前集合。"
      },
      "bytes": {
        "canonical": "\\x1b[2$w",
        "octal": "\\033[2$w",
        "eEscape": "\\e[2$w",
        "literal": "ESC [ 2 $ w",
        "hex": "1b 5b 32 24 77"
      },
      "description": {
        "en": "DECTABSR — *Tab Stop Report* — is a DECRQPSR (Request Presentation State Report) variant that asks the terminal to enumerate its current horizontal tab stops as a DCS reply. It's the third leg of the tab-stop round trip:\n\n- **Set** a tab stop at the current column: `\\x1bH` (HTS — see `esc-hts`).\n- **Clear** tabs: `\\x1b[g` (this column) / `\\x1b[3g` (all) (TBC — see `csi-tbc`).\n- **Query** current tab stops: `\\x1b[2$w` (DECTABSR — this entry).\n\n**Request shape**: `\\x1b[2$w` (the `2` is the Ps selector — `1` is DECCIR cursor-info-report, `2` is DECTABSR). The `$` intermediate + `w` final mirror the DECRQPSR convention.\n\n**Reply shape (DECRPTAB)**: `\\x1bP2$u<col1>/<col2>/…/<colN>\\x1b\\\\` — a DCS frame whose body is a slash-separated list of 1-indexed column numbers where tab stops currently live. Example reply (xterm default 8-column tabs on an 80-col screen):\n```\n\\x1bP2$u9/17/25/33/41/49/57/65/73\\x1b\\\\\n```\nNote there's no tab stop at column 1 (already cursor-home, no point) and the slashes separate but don't terminate. The DCS prefix `\\x1bP2$u` echoes the request's `2$` plus `u` for 'unsolicited' / 'response' (analogous to DECRQSS's `$r` reply).\n\n**Round-trip pattern** (save / restore terminal tab state across a TUI session):\n```\nstartup:\n  send \\x1b[2$w  -> receive \\x1bP2$u9/17/25/...\\x1b\\\\\n  parse: split body on '/' -> [9, 17, 25, ...]\n  save stops_before\nexit:\n  send \\x1b[3g           # TBC clear all\n  for col in stops_before:\n    send \\x1b[<col>G\\x1bH  # CHA to col, HTS at col\n```\n\nThis is what `tput rs2` does on terminfo entries that declare `dectabsr` — the 'reset to known tab state' sequence reads + restores rather than blindly setting `\\x1b[?5W` (DECST8C — set 8-column tabs).\n\n**Edge cases**:\n- Empty reply body (`\\x1bP2$u\\x1b\\\\`) means no tab stops are set at all — emit `\\x1b[?5W` or write an 8-column HTS sequence to restore a default.\n- Some emulators report the implicit 'end of line' stop (column == screen width + 1) — strip that out of your saved list.\n- The reply uses `\\x1b\\\\` (ST as ESC + backslash) by default; xterm in 8-bit C1 mode (see `decscl-compat-level`) uses single-byte `\\x9c`.\n\n**Coverage**: **xterm** = full (reference). **WezTerm** / **mlterm** / **Konsole** = full. **Ghostty** = partial (emits reply but always with default 8-col tabs). **Kitty** / **iTerm2** = partial (replies but may miss user-set stops on certain code paths). **Alacritty** / **Linux console** / **Windows Terminal** / **cmd / ConPTY** / **macOS Terminal** / **gnome-terminal** = no-op (no reply at all — be sure to time out probes at ~100 ms).",
        "zh": "DECTABSR —— *制表位报告* —— DECRQPSR（请求陈现状态报告）的一种，请终端以 DCS 形式列出当前水平制表位。它是制表位往返链的第三只脚：\n\n- 在当前列**设置**制表位：`\\x1bH`（HTS，见 `esc-hts`）。\n- **清除**：`\\x1b[g`（当前列）/ `\\x1b[3g`（全部）（TBC，见 `csi-tbc`）。\n- **查询**当前集合：`\\x1b[2$w`（DECTABSR —— 本条目）。\n\n**请求形态**：`\\x1b[2$w`（`2` 是 Ps 选择子 —— `1` 是 DECCIR 光标信息报告、`2` 是 DECTABSR）。`$` 中间字节 + `w` 末字节同 DECRQPSR 约定。\n\n**回复形态（DECRPTAB）**：`\\x1bP2$u<col1>/<col2>/…/<colN>\\x1b\\\\` —— DCS 帧，体为以斜杠分隔的当前制表位列号（1 起算）。示例（xterm 80 列默认 8 列制表）：\n```\n\\x1bP2$u9/17/25/33/41/49/57/65/73\\x1b\\\\\n```\n注意 1 列处无制表位（本即光标 home），斜杠仅分隔不终止。DCS 前缀 `\\x1bP2$u` 回显请求的 `2$` 加上 `u` 表示「unsolicited / response」（类比 DECRQSS 的 `$r`）。\n\n**往返模式**（TUI 会话前后保存 / 恢复终端制表状态）：\n```\n启动：\n  发 \\x1b[2$w -> 收 \\x1bP2$u9/17/25/...\\x1b\\\\\n  解析：以 '/' 分割体 -> [9, 17, 25, ...]\n  保存 stops_before\n退出：\n  发 \\x1b[3g            # TBC 清全部\n  for col in stops_before:\n    发 \\x1b[<col>G\\x1bH  # CHA 至 col，HTS 于 col\n```\n\n声明 `dectabsr` 的 terminfo 条目里，`tput rs2` 做的就是这件事 —— 「重置到已知制表状态」用读 + 还原，而不是傻发 `\\x1b[?5W`（DECST8C —— 设 8 列制表）。\n\n**边界**：\n- 空回复（`\\x1bP2$u\\x1b\\\\`）表示一个制表位都没有 —— 发 `\\x1b[?5W` 或写一串 HTS 还原默认。\n- 部分模拟器会把隐含的「行尾」位（列 == 屏宽 + 1）也报出来 —— 从保存列表里剥除。\n- 回复默认以 `\\x1b\\\\`（ST 表示为 ESC + 反斜杠）结束；xterm 在 8 位 C1 模式下（见 `decscl-compat-level`）使用单字节 `\\x9c`。\n\n**覆盖度**：**xterm** = 完整（标准）。**WezTerm** / **mlterm** / **Konsole** = 完整。**Ghostty** = 部分（回但总是默认 8 列）。**Kitty** / **iTerm2** = 部分（回但某些代码路径漏掉用户设置的位）。**Alacritty** / **Linux console** / **Windows Terminal** / **cmd / ConPTY** / **macOS Terminal** / **gnome-terminal** = 无作用（完全不回 —— 探测务必加 ~100 ms 超时）。"
      },
      "spec": "DEC VT510 RM (DECTABSR / DECRPTAB) / xterm-ctlseqs (CSI 2 $ w)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Probe tab stops; read DCS reply with timeout.\\nprintf '\\\\033[2$w'\\nIFS= read -rs -d '\\\\\\\\' -t 0.1 reply </dev/tty 2>/dev/null\\necho \\\"DECTABSR: ${reply}\\\"   # expect: \\\\x1bP2$u9/17/25/..."
        },
        {
          "lang": "python",
          "code": "import sys, re\\n# Parse the slash-separated tab list from a DECRPTAB reply.\\nreply = '\\\\x1bP2$u9/17/25/33/41/49/57/65/73\\\\x1b\\\\\\\\'\\nm = re.search(r'\\\\x1bP2\\\\$u([\\\\d/]*)\\\\x1b\\\\\\\\', reply)\\nstops = [int(c) for c in m.group(1).split('/') if c] if m else []\\nprint(stops)"
        },
        {
          "lang": "go",
          "code": "// Save-then-restore tab stops across a TUI's runtime.\\nfmt.Print(\\\"\\\\x1b[2$w\\\")              // request DECTABSR\\n// ... read DCS reply, parse to []int ...\\n// On exit: TBC all, then HTS at each saved col\\nfmt.Print(\\\"\\\\x1b[3g\\\")               // TBC 3 clears all\\nfor _, col := range saved {\\n    fmt.Printf(\\\"\\\\x1b[%dG\\\\x1bH\\\", col)\\n}"
        },
        {
          "lang": "javascript",
          "code": "// Detect 'no tab stops at all' (empty body).\\nfunction parseDECTABSR(buf) {\\n  const m = /\\\\x1bP2\\\\$u([^\\\\x1b]*)\\\\x1b\\\\\\\\/.exec(buf);\\n  if (!m) return null;\\n  return m[1].split('/').filter(s => s.length).map(Number);\\n}\\nconsole.log(parseDECTABSR('\\\\x1bP2$u\\\\x1b\\\\\\\\'));   // [] — no tabs at all"
        },
        {
          "lang": "c",
          "code": "/* Skeleton: probe + parse (cbreak stdin, timed read). */\\nprintf(\\\"\\\\x1b[2$w\\\"); fflush(stdout);\\n/* read until ST (0x1b 0x5c). then strtok on '/' between \\\"$u\\\" and ST. */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "partial",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "partial",
        "gnometerm": "no",
        "konsole": "yes"
      },
      "related": [
        "esc-hts",
        "csi-tbc",
        "dcs-decrqss",
        "dcs-decrsps"
      ]
    },
    {
      "slug": "decrqupss-decaupss",
      "family": "DCS",
      "title": {
        "en": "DECRQUPSS / DECAUPSS — Request / Assign User-Preferred Supplemental Set",
        "zh": "DECRQUPSS / DECAUPSS —— 请求 / 指派用户首选补充字符集"
      },
      "shortDesc": {
        "en": "Query (`CSI & u`) and assign (`DCS Ps ! u … ST`) the supplemental character set the terminal maps into the GR slot when no Locking Shift is active. Closes the supplemental-set plumbing left after `single-locking-shift`.",
        "zh": "查询（`CSI & u`）与指派（`DCS Ps ! u … ST`）在未触发 Locking Shift 时映射进 GR 槽位的补充字符集 —— 补完 `single-locking-shift` 留下的「谁占着 GR」一环。"
      },
      "bytes": {
        "canonical": "\\x1b[&u  request    \\x1bP<Ps>!u<D…D>\\x1b\\\\  assign",
        "octal": "\\033[&u  request    \\033P<Ps>!u<D…D>\\033\\\\  assign",
        "eEscape": "\\e[&u  request    \\eP<Ps>!u<D…D>\\e\\\\  assign",
        "literal": "ESC [ & u   /   ESC P <Ps> ! u <D…D> ESC \\\\",
        "hex": "1b 5b 26 75   /   1b 50 <Ps> 21 75 <body> 1b 5c"
      },
      "description": {
        "en": "**DECRQUPSS** (*Request User-Preferred Supplemental Set*, `\\x1b[&u`) and its setter **DECAUPSS** (*Assign User-Preferred Supplemental Set*, `\\x1bP<Ps>!u<body>\\x1b\\\\`) cover the half of ISO 2022 character-set switching that `single-locking-shift` deliberately punted on: **who is the GR (right-half, 0xA0–0xFF) charset by default**, before any Locking Shift fires.\n\n**Why this matters.** On a 7-bit channel (Telnet, serial cards, NRCS terminals) the GR half is the only place left for non-ASCII glyphs once the GL half holds ASCII. ISO 2022 calls the resident occupant of GR the *user-preferred supplemental set* — by DEC default it is **DEC Supplemental Graphic** (the historical accent / box-drawing / math set), but ECMA-43 / DEC VT510 allow assigning **ISO Latin-1** (or any registered 96-char set) into the slot instead. DECAUPSS lets the host say 'from now on, GR is Latin-1'; DECRQUPSS lets the host ask 'what does GR resolve to right now?'.\n\n**Request shape** — DECRQUPSS: `\\x1b[&u`. No parameters; the `&` intermediate + `u` final is the only form.\n\n**Reply shape** — terminal echoes its current UPSS via DECAUPSS-shaped frame: `\\x1bP<Ps>!u<DesignatorBytes>\\x1b\\\\`. `Ps` = `0` for a 94-character set (G0-style designator), `Ps` = `1` for a 96-character set (Latin-style designator). `<DesignatorBytes>` is the ISO-2022 final-byte that names the set:\n- `%5` → DEC Supplemental Graphic (the DEC default, returns `\\x1bP0!u%5\\x1b\\\\`)\n- `A` → ISO Latin-1 Supplemental (`\\x1bP1!uA\\x1b\\\\` — 96-set, so `Ps=1`)\n- `<` → DEC Technical Set\n- `=` → DEC Hebrew Supplemental, `\"4` → DEC Hebrew-7, `\"?` → DEC Greek, `%2` → Turkish, `R` → French, `K` → German (the NRCS family)\n\n**Set side** — DECAUPSS uses the identical body. To put Latin-1 into GR: `\\x1bP1!uA\\x1b\\\\`. To restore DEC default: `\\x1bP0!u%5\\x1b\\\\`. Effect is global until next DECAUPSS, DECSTR soft reset (which restores DEC default), or RIS hard reset.\n\n**Relationship to the shift family.** Designators (`\\x1b ( ` / `)` / `*` / `+`) load specific sets into the G0/G1/G2/G3 registers. Locking Shifts (LS0 / LS1 / LS1R / …) and Single Shifts (SS2 / SS3) *invoke* those registers into GL / GR. **UPSS is the fallback** — when no Locking Shift to GR is active, GR resolves to the UPSS, not to G1. This explains why `\\x1b(0` (DEC Special Graphics → G0) + a GL byte produces line-drawing characters but a *high-bit* byte (0xA0+) without LS1R still hits whatever UPSS is set to (DEC Supplemental by default, Latin-1 if reassigned).\n\n**Coverage** — niche. Real **xterm** + **mlterm** + **gnome-terminal** + **Konsole** = full (the ISO 2022 path is still alive there because terminfo's `acsc`/`smacs`/`rmacs` route through it). **WezTerm** + **iTerm2** = partial (parse + acknowledge the request but treat the body as no-op; their default is Latin-1 because UTF-8 already covers what UPSS was for). **Kitty** / **Alacritty** / **Ghostty** / **Windows Terminal** / **cmd / ConPTY** / **macOS Terminal** / **Linux console** = no-op (silently ignore both directions — UTF-8 obsoleted the use case). In 2026, send DECAUPSS only if the receiver is a known ISO-2022-aware emulator; otherwise use UTF-8 encoded text directly.",
        "zh": "**DECRQUPSS**（*请求用户首选补充字符集*，`\\x1b[&u`）与其设值对偶 **DECAUPSS**（*指派用户首选补充字符集*，`\\x1bP<Ps>!u<body>\\x1b\\\\`）补全 `single-locking-shift` 故意搁置的另一半 ISO 2022 字符集切换：**在任何 Locking Shift 触发之前，GR（右半 0xA0–0xFF）默认指向谁**。\n\n**为何重要。** 在 7 位通道（Telnet、串口卡、NRCS 终端）上，GL 半段一旦让给 ASCII，GR 就是非 ASCII 字形的唯一去处。ISO 2022 把这位常驻 GR 的字符集称为*用户首选补充字符集* —— DEC 默认是 **DEC Supplemental Graphic**（历史上的重音 / 制表 / 数学集），但 ECMA-43 / DEC VT510 允许把 **ISO Latin-1**（或任何注册过的 96 字符集）装进去。DECAUPSS 让主机说「从现在起，GR 是 Latin-1」；DECRQUPSS 让主机问「GR 现在解析到哪？」。\n\n**请求形态** —— DECRQUPSS：`\\x1b[&u`。无参数；`&` 中间字节 + `u` 末字节是唯一形态。\n\n**回复形态** —— 终端以 DECAUPSS 形帧回填当前 UPSS：`\\x1bP<Ps>!u<DesignatorBytes>\\x1b\\\\`。`Ps` = `0` 表 94 字符集（G0 风格指示符），`Ps` = `1` 表 96 字符集（Latin 风格指示符）。`<DesignatorBytes>` 是 ISO-2022 末字节，命名具体集合：\n- `%5` → DEC Supplemental Graphic（DEC 默认，回 `\\x1bP0!u%5\\x1b\\\\`）\n- `A` → ISO Latin-1 Supplemental（`\\x1bP1!uA\\x1b\\\\` —— 96 集，故 `Ps=1`）\n- `<` → DEC Technical Set\n- `=` → DEC Hebrew Supplemental、`\"4` → DEC Hebrew-7、`\"?` → DEC Greek、`%2` → Turkish、`R` → French、`K` → German（NRCS 家族）\n\n**设值侧** —— DECAUPSS 用相同主体。把 Latin-1 装进 GR：`\\x1bP1!uA\\x1b\\\\`。恢复 DEC 默认：`\\x1bP0!u%5\\x1b\\\\`。生效是全局的，直至下一次 DECAUPSS、DECSTR 软重置（回到 DEC 默认）或 RIS 硬重置。\n\n**与移位家族的关系。** 指示符（`\\x1b ( ` / `)` / `*` / `+`）把具体集合加载到 G0/G1/G2/G3 寄存器。Locking Shifts（LS0 / LS1 / LS1R / …）与 Single Shifts（SS2 / SS3）*调用*这些寄存器到 GL / GR。**UPSS 是回退路径** —— 当未激活任何对 GR 的 Locking Shift 时，GR 解析到 UPSS，而不是 G1。这就解释了为何 `\\x1b(0`（DEC 特殊图形 → G0）+ 一字节 GL 产生制表线，但一个*高位*字节（0xA0+）在没有 LS1R 时仍击中 UPSS 当前的集合（默认 DEC Supplemental，若被改派则 Latin-1）。\n\n**覆盖度** —— 小众。真 **xterm** + **mlterm** + **gnome-terminal** + **Konsole** = 完整（terminfo 的 `acsc`/`smacs`/`rmacs` 仍经此路径，故 ISO 2022 在其中仍活）。**WezTerm** + **iTerm2** = 部分（解析并确认请求但视主体为空操作 —— 默认就是 Latin-1，因为 UTF-8 已覆盖了 UPSS 的全部用途）。**Kitty** / **Alacritty** / **Ghostty** / **Windows Terminal** / **cmd / ConPTY** / **macOS Terminal** / **Linux console** = 无作用（两向均静默忽略 —— UTF-8 已废止该用例）。2026 年，仅当接收端是已知 ISO-2022-aware 模拟器时再发 DECAUPSS；其余场景直接用 UTF-8 编码文本。"
      },
      "parameters": [
        {
          "name": "Ps = 0 (94-set)",
          "desc": {
            "en": "designator is a 94-character set (most DEC sets — DEC Supplemental %5, DEC Technical <, NRCS R/K/=)",
            "zh": "指示符是 94 字符集（多数 DEC 集 —— DEC Supplemental %5、DEC Technical <、NRCS R/K/=）"
          }
        },
        {
          "name": "Ps = 1 (96-set)",
          "desc": {
            "en": "designator is a 96-character set (Latin-1 A, Latin-2 B, Latin-Cyrillic L, Latin-Greek F, Latin-Hebrew H)",
            "zh": "指示符是 96 字符集（Latin-1 A、Latin-2 B、Latin-Cyrillic L、Latin-Greek F、Latin-Hebrew H）"
          }
        },
        {
          "name": "%5",
          "desc": {
            "en": "DEC Supplemental Graphic (DEC default for UPSS)",
            "zh": "DEC 补充图形（UPSS 的 DEC 默认）"
          }
        },
        {
          "name": "A",
          "desc": {
            "en": "ISO Latin-1 Supplemental (the modern default when leaving DEC mode)",
            "zh": "ISO Latin-1 补充（脱离 DEC 模式后的现代默认）"
          }
        },
        {
          "name": "<",
          "desc": {
            "en": "DEC Technical Character Set (math / Greek glyphs for technical typesetting)",
            "zh": "DEC 技术字符集（技术排版的数学 / 希腊字形）"
          }
        }
      ],
      "spec": "DEC VT510 RM (DECRQUPSS / DECAUPSS) / ISO 2022 §6.4 (UPSS) / ECMA-35 §13.4",
      "examples": [
        {
          "lang": "bash",
          "code": "# Probe UPSS, parse the DCS reply (timeout-protected).\\nprintf '\\\\033[&u'\\nIFS= read -rs -d '\\\\\\\\' -t 0.1 reply </dev/tty 2>/dev/null\\necho \\\"UPSS reply: ${reply}\\\"   # xterm: \\\\x1bP1!uA\\\\x1b  (Latin-1 today on most builds)\\n# Re-assign UPSS to DEC Supplemental Graphic (DEC default):\\nprintf '\\\\033P0!u%%5\\\\033\\\\\\\\'"
        },
        {
          "lang": "python",
          "code": "import sys, re, tty, termios, select\\n# Switch GR to ISO Latin-1, then back to DEC Supplemental.\\nsys.stdout.write('\\\\x1bP1!uA\\\\x1b\\\\\\\\')   # GR = Latin-1\\nsys.stdout.flush()\\n# ... do work that emits 0xA0–0xFF bytes ...\\nsys.stdout.write('\\\\x1bP0!u%5\\\\x1b\\\\\\\\')  # restore DEC default\\nsys.stdout.flush()"
        },
        {
          "lang": "go",
          "code": "// Parse a DECRQUPSS reply: extract Ps + designator.\\nimport (\\n    \\\"fmt\\\"\\n    \\\"regexp\\\"\\n)\\nvar upssRe = regexp.MustCompile(\\\"\\\\x1bP([01])!u([^\\\\x1b]+)\\\\x1b\\\\\\\\\\\\\\\\\\\")\\nfunc parseUPSS(buf string) (ps int, designator string, ok bool) {\\n    m := upssRe.FindStringSubmatch(buf)\\n    if m == nil { return 0, \\\"\\\", false }\\n    fmt.Sscanf(m[1], \\\"%d\\\", &ps)\\n    return ps, m[2], true\\n}"
        },
        {
          "lang": "javascript",
          "code": "// Reassign UPSS to Latin-1 (modern default) and confirm.\\nprocess.stdout.write('\\\\x1bP1!uA\\\\x1b\\\\\\\\');\\n// Query: emit DECRQUPSS and parse the reply.\\nprocess.stdout.write('\\\\x1b[&u');\\nprocess.stdin.once('data', (buf) => {\\n  const m = /\\\\x1bP([01])!u([^\\\\x1b]+)\\\\x1b\\\\\\\\/.exec(buf.toString('binary'));\\n  console.error('UPSS Ps=' + (m?.[1] ?? '?') + ' set=' + (m?.[2] ?? '?'));\\n});"
        },
        {
          "lang": "c",
          "code": "/* Set UPSS to Latin-1, then probe. */\\nfputs(\\\"\\\\x1bP1!uA\\\\x1b\\\\\\\\\\\", stdout);\\nfputs(\\\"\\\\x1b[&u\\\", stdout); fflush(stdout);\\n/* Read until ST (0x1b 0x5c) with 100ms select timeout, then parse !u<designator>. */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "partial",
        "ghostty": "no",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "single-locking-shift",
        "decstr-side-effects",
        "dcs-decrqss",
        "c1-controls"
      ]
    },
    {
      "slug": "decrqcra-decchksr",
      "family": "CSI",
      "title": {
        "en": "DECRQCRA / DECCKSR — Request Checksum of Rectangular Area (`CSI Pi;Pg;Pt;Pl;Pb;Pr*y`)",
        "zh": "DECRQCRA / DECCKSR —— 请求矩形区域校验和（`CSI Pi;Pg;Pt;Pl;Pb;Pr*y`）"
      },
      "shortDesc": {
        "en": "Ask the terminal to compute a 16-bit checksum over a rectangle of cells (`CSI Pi;Pg;Pt;Pl;Pb;Pr*y`); reply arrives as DCS DECCKSR (`\\x1bP<Pi>!~<hex4>\\x1b\\\\`). The xterm vttest / ConPTY conformance pin.",
        "zh": "请终端对矩形区域的单元算 16 位校验和（`CSI Pi;Pg;Pt;Pl;Pb;Pr*y`），DCS DECCKSR 回（`\\x1bP<Pi>!~<hex4>\\x1b\\\\`）。xterm vttest / ConPTY 一致性测试用作金标。"
      },
      "bytes": {
        "canonical": "\\x1b[Pi;Pg;Pt;Pl;Pb;Pr*y    reply  \\x1bP<Pi>!~<hex4>\\x1b\\\\",
        "octal": "\\033[Pi;Pg;Pt;Pl;Pb;Pr*y    reply  \\033P<Pi>!~<hex4>\\033\\\\",
        "eEscape": "\\e[Pi;Pg;Pt;Pl;Pb;Pr*y    reply  \\eP<Pi>!~<hex4>\\e\\\\",
        "literal": "ESC [ <Pi> ; <Pg> ; <Pt> ; <Pl> ; <Pb> ; <Pr> * y     reply: ESC P <Pi> ! ~ <hex4> ESC \\\\",
        "hex": "1b 5b … 2a 79     reply: 1b 50 … 21 7e <hex4> 1b 5c"
      },
      "description": {
        "en": "**DECRQCRA** (*Request Checksum of Rectangular Area*, `\\x1b[<Pi>;<Pg>;<Pt>;<Pl>;<Pb>;<Pr>*y`) makes the terminal compute a 16-bit checksum over the characters + attributes of every cell inside the bounding rectangle, then return it as a four-digit uppercase hex value inside a DCS **DECCKSR** frame: `\\x1bP<Pi>!~<HHHH>\\x1b\\\\`.\n\nThis is the **xterm vttest** conformance pin — every screen-painting feature (DECCRA, DECFRA, DECERA, ED, EL, scroll, line-wrap, SGR-pen carry, alt-screen swap) gets validated by 'paint, then DECRQCRA, then assert the checksum equals the recorded golden value'. Konsole's `tests/vt-tests`, mlterm's regression suite, and PowerShell ConPTY's TerminalEcho test all lean on it.\n\n**Parameters**\n- `Pi` — request ID (0–65535). Echoed back verbatim in the reply's `!~<Pi>` slot so a host pipelining multiple checksum requests can demux replies.\n- `Pg` — page number (1-based; `0` or omitted treated as `1`). Almost always `1` since modern emulators don't expose multi-page memory.\n- `Pt;Pl;Pb;Pr` — bounding rectangle (top, left, bottom, right; 1-based, inclusive). All four required; omission → entire page.\n\n**Checksum algorithm** — xterm 's reference implementation: start at `0`, for each cell in reading order subtract `cell_char_code + sgr_attr_bits` (treating attributes as a tagged bitfield: bold = 0x80, underline = 0x40, blink = 0x20, reverse = 0x10, etc.). The result modulo 0x10000 is the reported value. **Both the algorithm AND the SGR-bit mapping vary between emulators** — never compare checksums across two different terminal implementations; only golden-value vs same-emulator-version comparisons are valid.\n\n**Reply** — `\\x1bP<Pi>!~<HHHH>\\x1b\\\\`. The `!~` intermediate-final pair distinguishes DECCKSR from other DCS replies (DECRQSS's `$r`, DECRPTAB's `$u`, DECRPSS's `!u`). `<HHHH>` is exactly 4 uppercase hex digits, zero-padded. Example for an all-blank rectangle on a fresh xterm: `\\x1bP0!~0000\\x1b\\\\`. Example after `printf '\\x1b[31mABC\\x1b[0m'` at top-left and probing the first cell: `\\x1bP0!~01A1\\x1b\\\\` (xterm 392; the value drifts across versions, hence the golden-per-version pin).\n\n**Edge cases**\n- Coordinates out of page → silently clipped (no error reply).\n- Empty rectangle (`Pt > Pb` or `Pl > Pr`) → reply with checksum `0000`.\n- Some emulators (older Konsole, certain xterm builds) negate the checksum before reporting (one-complement) — match against your golden, not against an abstract formula.\n- Reply uses `\\x1b\\\\` (ST as ESC + backslash) by default; xterm in 8-bit C1 mode (`decscl-compat-level`) uses single-byte `\\x9c`.\n\n**Coverage** — **xterm** = full (reference). **mlterm** + **Konsole** + **WezTerm** = full. **Ghostty** = partial (emits a reply but checksum value diverges from xterm's by ≥ 1 bit per attribute change — treat as 'replies present, algorithm different'). **Kitty** + **iTerm2** = partial (some builds reply, some swallow). **Alacritty** / **Linux console** / **Windows Terminal** / **cmd / ConPTY** / **macOS Terminal** / **gnome-terminal** = no-op (no reply at all — be sure to time out probes at ~100 ms).",
        "zh": "**DECRQCRA**（*请求矩形区域校验和*，`\\x1b[<Pi>;<Pg>;<Pt>;<Pl>;<Pb>;<Pr>*y`）让终端对边框矩形内每个单元的字符 + 属性算一个 16 位校验和，以 4 位大写十六进制装进 DCS **DECCKSR** 帧回送：`\\x1bP<Pi>!~<HHHH>\\x1b\\\\`。\n\n这是 **xterm vttest** 的一致性金标 —— 每个绘屏特性（DECCRA、DECFRA、DECERA、ED、EL、滚屏、行回绕、SGR 笔状态承接、alt-screen 切换）都靠「绘屏 → DECRQCRA → 断言校验和等于记录的金值」来验证。Konsole 的 `tests/vt-tests`、mlterm 的回归集、PowerShell ConPTY 的 TerminalEcho 测试都依赖它。\n\n**参数**\n- `Pi` —— 请求 ID（0–65535）。在回复的 `!~<Pi>` 槽位原样回传，便于流水线发出多请求时解复用。\n- `Pg` —— 页号（1 起算；`0` 或省略按 `1` 处理）。现代模拟器几乎不暴露多页内存，故几乎总是 `1`。\n- `Pt;Pl;Pb;Pr` —— 边框矩形（上、左、下、右；1 起算，含两端）。四项均必需；省略即整页。\n\n**校验算法** —— xterm 参考实现：从 `0` 起，按阅读顺序逐单元减去 `cell_char_code + sgr_attr_bits`（属性视为带标签的位域：bold = 0x80、underline = 0x40、blink = 0x20、reverse = 0x10 等）。结果对 0x10000 取模即为上报值。**算法与 SGR 位映射在不同模拟器间不同** —— 永远不要跨模拟器实现比对校验和；只在「同模拟器同版本对金值」的语境下使用。\n\n**回复** —— `\\x1bP<Pi>!~<HHHH>\\x1b\\\\`。`!~` 中间-末字节对把 DECCKSR 与其它 DCS 回（DECRQSS 的 `$r`、DECRPTAB 的 `$u`、DECRPSS 的 `!u`）区分开。`<HHHH>` 是 4 位前补零的大写十六进制。例：全白矩形在新启动的 xterm 上 → `\\x1bP0!~0000\\x1b\\\\`。例：在左上角发 `printf '\\x1b[31mABC\\x1b[0m'` 后探测第一格 → `\\x1bP0!~01A1\\x1b\\\\`（xterm 392；值随版本漂移，故金值与版本绑定）。\n\n**边界**\n- 坐标越页 → 静默裁剪（无错误回复）。\n- 空矩形（`Pt > Pb` 或 `Pl > Pr`）→ 校验和回 `0000`。\n- 部分模拟器（旧版 Konsole、某些 xterm 构建）对校验和取一的补码再上报 —— 只比对自家金值，别比对抽象公式。\n- 回复默认以 `\\x1b\\\\`（ST 表为 ESC + 反斜杠）结束；xterm 在 8 位 C1 模式（`decscl-compat-level`）下使用单字节 `\\x9c`。\n\n**覆盖度** —— **xterm** = 完整（标准）。**mlterm** + **Konsole** + **WezTerm** = 完整。**Ghostty** = 部分（有回但校验和值在 SGR 属性变化时与 xterm 差 ≥ 1 位 —— 视为「有回复，算法不同」）。**Kitty** + **iTerm2** = 部分（部分构建回，部分吞）。**Alacritty** / **Linux console** / **Windows Terminal** / **cmd / ConPTY** / **macOS Terminal** / **gnome-terminal** = 无作用（完全不回 —— 探测务必加 ~100 ms 超时）。"
      },
      "parameters": [
        {
          "name": "Pi",
          "desc": {
            "en": "Request ID, 0–65535. Echoed verbatim into the reply's !~<Pi> slot for demuxing pipelined probes.",
            "zh": "请求 ID，0–65535。在回复的 !~<Pi> 槽原样回传，用于流水线解复用。"
          }
        },
        {
          "name": "Pg",
          "desc": {
            "en": "Page number, 1-based. Modern emulators expose only page 1; omitted / 0 → 1.",
            "zh": "页号，1 起算。现代模拟器仅暴露第 1 页；省略 / 0 → 1。"
          }
        },
        {
          "name": "Pt;Pl;Pb;Pr",
          "desc": {
            "en": "Bounding rectangle (top, left, bottom, right; 1-based, inclusive). Out-of-page coords silently clipped.",
            "zh": "边框矩形（上、左、下、右；1 起算，含两端）。越页坐标静默裁剪。"
          }
        },
        {
          "name": "Reply <hex4>",
          "desc": {
            "en": "4-digit uppercase hex, zero-padded. Algorithm + SGR bitmap vary between emulators — pin against same-emulator golden values only.",
            "zh": "4 位前补零大写十六进制。算法与 SGR 位映射各家不同 —— 仅与同模拟器金值比对。"
          }
        }
      ],
      "spec": "DEC VT510 RM (DECRQCRA / DECCKSR) / xterm-ctlseqs (CSI Pi;Pg;Pt;Pl;Pb;Pr * y)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Probe top-left cell on the main screen, parse the DCS reply.\\nprintf '\\\\033[7;1;1;1;1;1*y'\\nIFS= read -rs -d '\\\\\\\\' -t 0.1 reply </dev/tty 2>/dev/null\\necho \\\"DECCKSR: ${reply}\\\"   # expect: \\\\x1bP7!~XXXX\\\\x1b"
        },
        {
          "lang": "python",
          "code": "import sys, re\\n# Parse a DECCKSR reply, extract Pi + hex checksum.\\nreply = '\\\\x1bP42!~01A1\\\\x1b\\\\\\\\'\\nm = re.search(r'\\\\x1bP(\\\\d+)!~([0-9A-F]{4})\\\\x1b\\\\\\\\', reply)\\nif m:\\n    pi, chk = int(m.group(1)), int(m.group(2), 16)\\n    print(f'request {pi} checksum 0x{chk:04X}')"
        },
        {
          "lang": "go",
          "code": "// Pipeline three checksum probes with distinct Pi.\\nfor i, rect := range [][4]int{{1,1,1,1},{1,1,1,80},{1,1,24,80}} {\\n    pi := i + 1\\n    fmt.Printf(\\\"\\\\x1b[%d;1;%d;%d;%d;%d*y\\\", pi, rect[0], rect[1], rect[2], rect[3])\\n}\\n// Demux replies by !~<Pi> matching to issued Pi."
        },
        {
          "lang": "javascript",
          "code": "// vttest-style: paint, checksum, assert against golden.\\nasync function checksum(rect) {\\n  process.stdout.write(`\\\\x1b[1;1;${rect.t};${rect.l};${rect.b};${rect.r}*y`);\\n  for await (const buf of process.stdin) {\\n    const m = /\\\\x1bP1!~([0-9A-F]{4})\\\\x1b\\\\\\\\/.exec(buf.toString('binary'));\\n    if (m) return parseInt(m[1], 16);\\n  }\\n}"
        },
        {
          "lang": "c",
          "code": "/* Skeleton: emit probe, read until ST, parse Pi + 4 hex digits. */\\nprintf(\\\"\\\\x1b[1;1;1;1;1;1*y\\\"); fflush(stdout);\\n/* read until 0x1b 0x5c with 100ms select timeout, then sscanf(\\\"\\\\x1bP%d!~%4x\\\\x1b\\\\\\\\\\\", ...). */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "partial",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "partial",
        "gnometerm": "no",
        "konsole": "yes"
      },
      "related": [
        "dec-rect-ops",
        "decsace",
        "dcs-decrqss",
        "dectabsr"
      ]
    },
    {
      "slug": "decrqtsr-decrsts",
      "family": "DCS",
      "title": {
        "en": "DECRQTSR / DECRSTS — Request / Restore Terminal State Report",
        "zh": "DECRQTSR / DECRSTS —— 请求 / 还原终端状态报告"
      },
      "shortDesc": {
        "en": "Save (`CSI Ps$u` → DCS reply) and restore (`DCS Ps$p…ST`) the whole DEC terminal state — the terminal-wide complement to `dcs-decrsps`' presentation-state-only scope.",
        "zh": "保存（`CSI Ps$u` → DCS 回）与还原（`DCS Ps$p…ST`）整套 DEC 终端状态 —— `dcs-decrsps` 只覆盖陈现状态时的终端全态补遗。"
      },
      "bytes": {
        "canonical": "\\x1b[Ps$u  request    \\x1bP<Ps>$p<body>\\x1b\\\\  restore",
        "octal": "\\033[Ps$u  request    \\033P<Ps>$p<body>\\033\\\\  restore",
        "eEscape": "\\e[Ps$u  request    \\eP<Ps>$p<body>\\e\\\\  restore",
        "literal": "ESC [ <Ps> $ u   /   ESC P <Ps> $ p <body> ESC \\\\",
        "hex": "1b 5b … 24 75   /   1b 50 <Ps> 24 70 <body> 1b 5c"
      },
      "description": {
        "en": "**DECRQTSR** (*Request Terminal State Report*, `\\x1b[<Ps>$u`) and its inverse **DECRSTS** (*Restore Terminal State*, `\\x1bP<Ps>$p<body>\\x1b\\\\`) bracket the DEC mechanism for snapshotting an *entire terminal*'s mutable state into an opaque blob and faithfully restoring it later. They are the **terminal-wide** counterpart to `dcs-decrsps` / `dcs-decrqss`, which only carry the *presentation* slice (cursor, SGR, charset, origin, tab stops).\n\n**Request** — `\\x1b[<Ps>$u`. `Ps=1` (the only universally-supported value) selects DEC terminal-state. Some VT-series docs reserve `Ps=2` for color-table state, but no shipping emulator implements `Ps=2` distinctly from `Ps=1` — treat `1` as the only portable selector.\n\n**Reply (DECTSR)** — `\\x1bP<Ps>$s<body>\\x1b\\\\`. The `$s` intermediate-final distinguishes the DECTSR reply from the DECRSTS *restore* shape (`$p`) and from DECRPSS (`$r`). The `<body>` is **opaque to the host** — it's a serialised DEC-private snapshot of: tab stops, character set state (G0/G1/G2/G3 designators + GL/GR + UPSS), all mode states (DECCKM / DECANM / DECCOLM / DECSCLM / DECSCNM / DECOM / DECAWM / DECARM / DECTCEM / DECNRCM / DECSCA / DECNKM / DECSCUSR / DECSDM / DECSLRM), printer state, keyboard-mode state, current SGR pen, cursor position + save stack, and protected-area state. Hosts **must not parse** the body — semantics are reserved to the originating terminal.\n\n**Restore** — `\\x1bP<Ps>$p<body>\\x1b\\\\`. Pass the same `<body>` back verbatim. The terminal validates that `<Ps>` matches the saved blob's `<Ps>` (cross-Ps restore is rejected silently with `\\x1bP0$r\\x1b\\\\` on emulators that reply, or simple no-op otherwise). Cross-terminal restore (saving on xterm, restoring on Konsole) is **not portable** — the body format is DEC-implementation-defined and each emulator has its own encoding.\n\n**Round-trip pattern** (TUI takeover + restore):\n```\nstartup:\n  write '\\x1b[1$u'        # DECRQTSR Ps=1\n  read DCS until ST       # reply '\\x1bP1$s<body>\\x1b\\\\'\n  save body\nexit:\n  write '\\x1bP1$p' + body + '\\x1b\\\\'\n```\nThe modern reality: most TUIs use **alt-screen** (`\\x1b[?1049h`/`l`) + DECSC/DECRC for cursor/SGR. DECRQTSR/DECRSTS is the **terminal-wide** option only when alt-screen is unavailable (some BBS / serial-multiplexer paths) or when you need to round-trip modes that DECSTR doesn't touch (NRCS, UPSS, DECSCA).\n\n**Edge cases**\n- Reply uses `\\x1b\\\\` (ST as ESC + backslash) by default; xterm in 8-bit C1 mode (`decscl-compat-level`) uses single-byte `\\x9c` — be prepared to terminate on either.\n- Body bytes can include `\\x1b` followed by **anything except `\\\\`** (DEC encodes embedded controls via DECDLD-style hex escapes); a naive 'split on ESC' parser will mis-frame — read until ST seen at packet boundary, not first ESC.\n- Some emulators (Linux console) reply with an empty body — restore is a silent no-op.\n- DECSTR (soft reset) does not clear an in-flight DECTSR snapshot held by the host, only the live terminal state.\n\n**Coverage** — **xterm** = full (reference; body length ~100-200 bytes typical). **mlterm** = full. **WezTerm** = partial (replies with a minimal body, restore accepts but only restores SGR + cursor + tabs — the modes DECSTR would reset get re-applied, the rest silently dropped). **Konsole** + **gnome-terminal** = partial (reply lacks UPSS / DECSCA fields, restore likewise truncated). **Kitty** + **iTerm2** + **Alacritty** + **Ghostty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** + **Linux console** = no-op (no reply at all — prefer `alt-screen` + `cursor-save-restore` + `dcs-decrqss` for round-trip on these).",
        "zh": "**DECRQTSR**（*请求终端状态报告*，`\\x1b[<Ps>$u`）与逆元 **DECRSTS**（*还原终端状态*，`\\x1bP<Ps>$p<body>\\x1b\\\\`）框出 DEC 把*整台终端*可变状态快照成不透明字节流，并稍后忠实回灌的机制。它们是 `dcs-decrsps` / `dcs-decrqss`（只覆盖*陈现*片段：光标、SGR、字符集、原点、制表位）的**终端全态**对偶。\n\n**请求** —— `\\x1b[<Ps>$u`。`Ps=1`（唯一通用值）选 DEC 终端状态。部分 VT 系列文档为 `Ps=2` 保留色表状态，但无实际模拟器把 `Ps=2` 与 `Ps=1` 区别实现 —— 视 `1` 为唯一可移植选择子。\n\n**回复（DECTSR）** —— `\\x1bP<Ps>$s<body>\\x1b\\\\`。`$s` 中间-末字节把 DECTSR 与 DECRSTS *还原*形（`$p`）以及 DECRPSS（`$r`）区分开。`<body>` **对主机不透明** —— 是 DEC 私有的状态序列化，包含：制表位、字符集状态（G0/G1/G2/G3 指示符 + GL/GR + UPSS）、所有模式状态（DECCKM / DECANM / DECCOLM / DECSCLM / DECSCNM / DECOM / DECAWM / DECARM / DECTCEM / DECNRCM / DECSCA / DECNKM / DECSCUSR / DECSDM / DECSLRM）、打印机状态、键盘模式状态、当前 SGR 笔、光标位置 + 保存栈、保护区状态。主机**不得解析**主体 —— 语义保留给原发模拟器。\n\n**还原** —— `\\x1bP<Ps>$p<body>\\x1b\\\\`。把同一 `<body>` 原样回送。终端校验 `<Ps>` 与保存时一致（不一致时回复模拟器静默回 `\\x1bP0$r\\x1b\\\\`，其他模拟器视为空操作）。**跨终端还原**（在 xterm 保存、到 Konsole 还原）**不可移植** —— 主体格式是 DEC 实现自定义，各家自有编码。\n\n**往返模式**（TUI 接管 + 还原）：\n```\n启动：\n  发 '\\x1b[1$u'            # DECRQTSR Ps=1\n  读 DCS 直至 ST          # 回 '\\x1bP1$s<body>\\x1b\\\\'\n  保存 body\n退出：\n  发 '\\x1bP1$p' + body + '\\x1b\\\\'\n```\n现代现实：多数 TUI 用 **alt-screen**（`\\x1b[?1049h`/`l`）+ DECSC/DECRC 处理光标/SGR。DECRQTSR/DECRSTS 是 **终端全态**版本，仅在 alt-screen 不可用时（部分 BBS / 串口多路场景）或需要往返 DECSTR 不触碰的模式（NRCS、UPSS、DECSCA）时用。\n\n**边界**\n- 回复默认以 `\\x1b\\\\`（ST 表为 ESC + 反斜杠）结束；xterm 在 8 位 C1 模式（`decscl-compat-level`）下使用单字节 `\\x9c` —— 解析器需对两种终止都就绪。\n- 主体字节可包含 `\\x1b` 后跟**除 `\\\\` 外任意字节**（DEC 把内嵌控制用 DECDLD 风格的十六进制转义编入）；天真的「按 ESC 分割」解析器会错框 —— 读至包边界处见 ST，而非首个 ESC。\n- 部分模拟器（Linux console）回空主体 —— 还原成空操作。\n- DECSTR（软重置）不会清掉主机持有的快照，只重置在用终端状态。\n\n**覆盖度** —— **xterm** = 完整（标准；主体长度通常 100–200 字节）。**mlterm** = 完整。**WezTerm** = 部分（回最小主体，还原接受但仅还原 SGR + 光标 + 制表位 —— DECSTR 会重置的模式会被重套，其余静默丢）。**Konsole** + **gnome-terminal** = 部分（回缺 UPSS / DECSCA 字段，还原同样截断）。**Kitty** + **iTerm2** + **Alacritty** + **Ghostty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** + **Linux console** = 无作用（完全不回 —— 这些场景请改用 `alt-screen` + `cursor-save-restore` + `dcs-decrqss` 做往返）。"
      },
      "parameters": [
        {
          "name": "Ps = 1",
          "desc": {
            "en": "DEC terminal state. The only universally-supported value.",
            "zh": "DEC 终端状态。唯一通用值。"
          }
        },
        {
          "name": "Ps = 2",
          "desc": {
            "en": "Reserved (color tables in some specs); no shipping emulator distinguishes from Ps=1.",
            "zh": "保留（部分规范用于色表）；无现役模拟器与 Ps=1 区别实现。"
          }
        },
        {
          "name": "Reply $s vs Restore $p",
          "desc": {
            "en": "DCS intermediate-final `$s` = report (terminal → host); `$p` = restore (host → terminal). Don't swap.",
            "zh": "DCS 中间-末字节 `$s` = 报告（终端 → 主机）；`$p` = 还原（主机 → 终端）。勿混。"
          }
        },
        {
          "name": "<body>",
          "desc": {
            "en": "Opaque DEC-private serialisation. Round-trip verbatim. Format varies per emulator — not cross-terminal portable.",
            "zh": "DEC 私有不透明序列化。原样往返。格式因模拟器而异 —— 不可跨终端搬运。"
          }
        }
      ],
      "spec": "DEC VT510 RM (DECRQTSR / DECTSR / DECRSTS) / xterm-ctlseqs (CSI Ps $ u)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Capture full terminal state, then restore on exit (xterm).\\nprintf '\\\\033[1$u'\\nIFS= read -rs -d '\\\\\\\\' -t 0.2 snapshot </dev/tty 2>/dev/null\\n# ... session runs, mutates modes ...\\n# Restore: re-emit the body in DECRSTS shape.\\nbody=\\\"${snapshot#*\\\\\\$s}\\\"\\nbody=\\\"${body%\\\\\\\\}\\\"\\nprintf '\\\\033P1$p%s\\\\033\\\\\\\\' \\\"$body\\\""
        },
        {
          "lang": "python",
          "code": "import sys, re\\n# Save snapshot, then later push it back.\\nsys.stdout.write('\\\\x1b[1$u'); sys.stdout.flush()\\nreply = sys.stdin.buffer.read1(4096)\\nm = re.search(rb'\\\\x1bP1\\\\$s(.*?)\\\\x1b\\\\\\\\', reply, re.DOTALL)\\nbody = m.group(1) if m else b''\\n# ... TUI session ...\\nsys.stdout.flush()\\nsys.stdout.buffer.write(b'\\\\x1bP1$p' + body + b'\\\\x1b\\\\\\\\')"
        },
        {
          "lang": "go",
          "code": "// Skeleton: probe, read until ST, persist body for the duration of the run.\\nfmt.Print(\\\"\\\\x1b[1$u\\\")\\nvar buf [4096]byte\\nn, _ := os.Stdin.Read(buf[:])\\n// Match \\\\x1bP1$s<body>\\\\x1b\\\\\\\\.\\nbody := extractDECTSR(buf[:n])\\n// ...\\nfmt.Printf(\\\"\\\\x1bP1$p%s\\\\x1b\\\\\\\\\\\", body)"
        },
        {
          "lang": "javascript",
          "code": "// Snapshot at startup, restore on exit handler.\\nprocess.stdout.write('\\\\x1b[1$u');\\nlet snapshot = '';\\nprocess.stdin.once('data', (buf) => {\\n  const m = /\\\\x1bP1\\\\$s(.*?)\\\\x1b\\\\\\\\/s.exec(buf.toString('binary'));\\n  if (m) snapshot = m[1];\\n});\\nprocess.on('exit', () => {\\n  if (snapshot) process.stdout.write('\\\\x1bP1$p' + snapshot + '\\\\x1b\\\\\\\\');\\n});"
        },
        {
          "lang": "c",
          "code": "/* Skeleton: snapshot at TUI entry, restore at exit. */\\nfputs(\\\"\\\\x1b[1$u\\\", stdout); fflush(stdout);\\n/* read until ST seen at packet boundary, store body bytes opaquely. */\\n/* on exit: fputs(\\\"\\\\x1bP1$p\\\", stdout); fwrite(body, 1, body_len, stdout); fputs(\\\"\\\\x1b\\\\\\\\\\\", stdout); */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "partial",
        "ghostty": "no",
        "gnometerm": "partial",
        "konsole": "partial"
      },
      "related": [
        "dcs-decrsps",
        "dcs-decrqss",
        "decstr-side-effects",
        "alt-screen"
      ]
    },
    {
      "slug": "decll-load-leds",
      "family": "CSI",
      "title": {
        "en": "DECLL — Load LEDs (`CSI Ps q`, no SP intermediate)",
        "zh": "DECLL —— 加载 LED 灯（`CSI Ps q`，无 SP 中间字节）"
      },
      "shortDesc": {
        "en": "Turn the keyboard's front-panel L1–L4 LEDs on / off (`CSI Ps q`). Surviving in Linux-console terminfo as `KEYBOARD_LED 1/2/3/4` — modern emulators silent no-op except xterm + Linux console.",
        "zh": "开关键盘前面板 L1–L4 LED（`CSI Ps q`）。在 Linux 控制台 terminfo 里以 `KEYBOARD_LED 1/2/3/4` 留存 —— 现代模拟器除 xterm + Linux console 外静默忽略。"
      },
      "bytes": {
        "canonical": "\\x1b[Ps q",
        "octal": "\\033[Ps q",
        "eEscape": "\\e[Ps q",
        "literal": "ESC [ <Ps> q",
        "hex": "1b 5b <Ps> 71"
      },
      "description": {
        "en": "**DECLL** (*Load LEDs*, `\\x1b[<Ps>q`) controls the four front-panel keyboard LEDs (L1, L2, L3, L4) that DEC VT100-series terminals shipped with — small lamps just below the function-key row that the host could light to surface status (caps lock, mode flags, attention indicators). The sequence survives in 2026 only because the Linux console wired its three keyboard LEDs (NumLock, CapsLock, ScrollLock) to it, and terminfo's `KEYBOARD_LED 1`/`2`/`3` caps still expand to DECLL on `linux-*` entries.\n\n**The disambiguation trap.** DECLL is `CSI Ps q` with **no intermediate byte**. `dec-cursor-shape` (DECSCUSR) is `CSI Ps SP q` — note the **space (0x20) intermediate**. A parser that flattens whitespace will fuse the two and apply cursor-shape changes whenever the host wanted to toggle a status LED. The byte sequence `\\x1b[3q` is DECLL 'L3 on'; `\\x1b[3 q` (with the literal space) is DECSCUSR 'cursor blinking underline'. Real terminfo `setab` / `setaf` strings emit DECLL without the space; if you're writing a parser, key on the intermediate-byte slot, not on the final byte.\n\n**Parameter codes** (DEC VT100):\n- `0` — **All LEDs off** (the default if `Ps` omitted; also serves as a 'reset' from any partial-on state)\n- `1` — **L1 on** (NumLock on Linux console; 'L1' lamp on a real VT100)\n- `2` — **L2 on** (CapsLock on Linux console; 'L2' lamp on VT100)\n- `3` — **L3 on** (ScrollLock on Linux console; 'L3' lamp on VT100)\n- `4` — **L4 on** (no Linux mapping; 'L4' lamp on VT100 — historically used by host apps for 'attention needed')\n- `21` — **L1 off** (turn individual LED off without touching the others)\n- `22` — **L2 off**\n- `23` — **L3 off**\n- `24` — **L4 off**\n\n**Semantics.** DECLL is *additive* — `\\x1b[1q` turns L1 on without touching L2/L3/L4 state. The 'turn off' codes (21–24) likewise act on a single LED. Only `\\x1b[0q` (or `\\x1b[q` with no parameter, which defaults `Ps` to 0) clears all four at once.\n\n**Edge cases**\n- Multiple parameters in one sequence are allowed: `\\x1b[1;3q` turns L1 + L3 on, off-codes likewise compose: `\\x1b[21;22;23q` turns L1, L2, L3 off in one trip. (Note this is one of the few cases where ECMA-48 'each Ps applies the same final-byte semantics' interpretation actually matches DEC's intent.)\n- The Linux-console kernel driver requires `CAP_SYS_TTY_CONFIG` to set LEDs from anything other than the kernel itself; ordinary user-space writes to `/dev/tty` honour DECLL only when the terminal type is `linux` and `loadkeys` hasn't remapped the LED bits.\n- On xterm, DECLL toggles tiny indicator dots in the title-bar area (configurable via the `showLed` X resource). Default is off (no visible effect) unless the user opts in.\n- **Do not confuse with**: `dec-cursor-shape` (CSI Ps SP q — adds space intermediate) or `xtversion` (CSI > q — adds `>` parameter prefix, no `Ps`).\n\n**Coverage** — **xterm** = full (with `showLed` X resource opt-in for visible feedback). **Linux console** = full (drives the three kernel-managed LEDs). **mlterm** + **Konsole** = partial (parse + acknowledge, no visible feedback unless an X resource is set). **WezTerm** + **iTerm2** + **Kitty** + **Alacritty** + **Ghostty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** + **gnome-terminal** = no-op (parse silently and discard — no hardware LEDs to control in 2026's GUI emulators). In practice DECLL is invisible across the modern stack — use `osc-set-fg-bg` / `osc-cursor-color` / status-bar text for visible status indicators instead.",
        "zh": "**DECLL**（*加载 LED*，`\\x1b[<Ps>q`）控制 DEC VT100 系列终端键盘前面板的四只 LED（L1、L2、L3、L4）—— 功能键行下方的小灯，主机可点亮以呈现状态（caps lock、模式标记、注意提示）。该序列在 2026 年仍存活，仅因 Linux 控制台把自己的三只键盘 LED（NumLock、CapsLock、ScrollLock）接到它上，且 terminfo 的 `KEYBOARD_LED 1`/`2`/`3` 在 `linux-*` 条目中仍展开为 DECLL。\n\n**消歧陷阱。** DECLL 是 `CSI Ps q`，**无中间字节**。`dec-cursor-shape`（DECSCUSR）是 `CSI Ps SP q` —— 注意 **空格（0x20）中间字节**。一个把空白扁平化的解析器会把二者合一，于是主机想切状态 LED 时却改了光标形状。字节流 `\\x1b[3q` 是 DECLL「L3 亮」；`\\x1b[3 q`（带真空格）是 DECSCUSR「下划线闪烁光标」。真正的 terminfo `setab` / `setaf` 串发 DECLL 时不带空格；写解析器时请按中间字节槽位区分，而非按末字节。\n\n**参数编码**（DEC VT100）：\n- `0` —— **全部 LED 灭**（省略 `Ps` 时默认；也作为从部分点亮状态「重置」）\n- `1` —— **L1 亮**（Linux 控制台的 NumLock；真 VT100 的「L1」灯）\n- `2` —— **L2 亮**（Linux 控制台的 CapsLock；VT100 的「L2」灯）\n- `3` —— **L3 亮**（Linux 控制台的 ScrollLock；VT100 的「L3」灯）\n- `4` —— **L4 亮**（Linux 无映射；VT100 的「L4」灯 —— 历史上主机程序用作「需注意」）\n- `21` —— **L1 灭**（单独关一只 LED，不影响其它）\n- `22` —— **L2 灭**\n- `23` —— **L3 灭**\n- `24` —— **L4 灭**\n\n**语义。** DECLL 是*累加性*的 —— `\\x1b[1q` 仅点 L1，不动 L2/L3/L4。「关」码（21–24）同样作用于单只 LED。只有 `\\x1b[0q`（或无参数的 `\\x1b[q`，默认 `Ps=0`）一次清空四只。\n\n**边界**\n- 单序列内允许多参数：`\\x1b[1;3q` 同时点 L1 + L3，关码同样可组合：`\\x1b[21;22;23q` 一次关 L1、L2、L3。（这是少数 ECMA-48「每个 Ps 应用相同末字节语义」的解读真正契合 DEC 原意的场景之一。）\n- Linux 控制台的内核驱动要求 `CAP_SYS_TTY_CONFIG` 才能从内核外部点 LED；普通用户态向 `/dev/tty` 写 DECLL 仅当终端类型为 `linux` 且 `loadkeys` 未重映射 LED 位时有效。\n- 在 xterm 上，DECLL 切换标题栏区域的小指示点（通过 `showLed` X 资源配置）。默认关（无可视反馈），需用户启用。\n- **勿与**：`dec-cursor-shape`（CSI Ps SP q —— 加空格中间字节）或 `xtversion`（CSI > q —— 加 `>` 参数前缀，无 `Ps`）混淆。\n\n**覆盖度** —— **xterm** = 完整（需 `showLed` X 资源启用可视反馈）。**Linux console** = 完整（驱动内核管理的三只 LED）。**mlterm** + **Konsole** = 部分（解析 + 确认，无可视反馈除非配 X 资源）。**WezTerm** + **iTerm2** + **Kitty** + **Alacritty** + **Ghostty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** + **gnome-terminal** = 无作用（静默解析丢弃 —— 2026 的 GUI 模拟器无硬件 LED 可控）。实际上 DECLL 在现代栈里不可见 —— 想做可视状态指示请改用 `osc-set-fg-bg` / `osc-cursor-color` / 状态栏文本。"
      },
      "parameters": [
        {
          "name": "Ps = 0 (default)",
          "desc": {
            "en": "All LEDs off. Also the default if Ps omitted (\\x1b[q).",
            "zh": "全部 LED 灭。省略 Ps（\\x1b[q）时的默认。"
          }
        },
        {
          "name": "Ps = 1..4",
          "desc": {
            "en": "Turn L1..L4 on (Linux console: L1=NumLock, L2=CapsLock, L3=ScrollLock, L4 unused).",
            "zh": "点亮 L1..L4（Linux 控制台：L1=NumLock、L2=CapsLock、L3=ScrollLock、L4 未用）。"
          }
        },
        {
          "name": "Ps = 21..24",
          "desc": {
            "en": "Turn L1..L4 off individually without disturbing the other LEDs.",
            "zh": "单独熄灭 L1..L4，不动其它 LED。"
          }
        },
        {
          "name": "Multi-param",
          "desc": {
            "en": "\\x1b[1;3q lights L1+L3; \\x1b[21;22q dims L1+L2 — semicolon-separated like SGR.",
            "zh": "\\x1b[1;3q 同点 L1+L3；\\x1b[21;22q 同熄 L1+L2 —— 与 SGR 同样以分号分隔。"
          }
        }
      ],
      "spec": "DEC VT100 User Guide §5.4 (DECLL) / ECMA-48 §8.3.69 (LL — Load LEDs)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Light L1 (NumLock on Linux console).\\nprintf '\\\\033[1q'\\n# Light L1 + L3 in one shot.\\nprintf '\\\\033[1;3q'\\n# Clear all LEDs.\\nprintf '\\\\033[0q'\\n# Mind the disambiguation: \\\\x1b[3 q is DECSCUSR (cursor blinking underline), not DECLL.\\nprintf '\\\\033[3q'   # DECLL L3 on\\nprintf '\\\\033[3 q'  # DECSCUSR — note literal space"
        },
        {
          "lang": "python",
          "code": "import sys\\n# Use DECLL as a poor-man's status indicator on a serial console.\\ndef set_leds(*on):\\n    if not on: sys.stdout.write('\\\\x1b[0q'); return\\n    sys.stdout.write('\\\\x1b[' + ';'.join(str(i) for i in on) + 'q')\\n    sys.stdout.flush()\\nset_leds(1, 3)   # L1 + L3 on\\nset_leds()       # all off"
        },
        {
          "lang": "go",
          "code": "// Toggle Linux console NumLock LED based on app state.\\nfunc setNumLock(on bool) {\\n    if on {\\n        fmt.Print(\\\"\\\\x1b[1q\\\")    // L1 on\\n    } else {\\n        fmt.Print(\\\"\\\\x1b[21q\\\")   // L1 off (don't touch L2/L3)\\n    }\\n}"
        },
        {
          "lang": "javascript",
          "code": "// Avoid the DECSCUSR collision: emit DECLL with NO space between Ps and 'q'.\\nfunction decll(...ps) {\\n  const body = ps.length === 0 ? '0' : ps.join(';');\\n  process.stdout.write('\\\\x1b[' + body + 'q');  // no space — DECLL, not DECSCUSR\\n}\\ndecll(1, 3);   // L1 + L3 on"
        },
        {
          "lang": "c",
          "code": "/* DECLL on Linux console — L1 corresponds to NumLock LED. */\\n#include <stdio.h>\\nvoid set_status_led(int led, int on) {\\n    if (on)  printf(\\\"\\\\x1b[%dq\\\", led);          /* 1..4 = on */\\n    else     printf(\\\"\\\\x1b[%dq\\\", 20 + led);     /* 21..24 = off */\\n    fflush(stdout);\\n}"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "yes",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "partial"
      },
      "related": [
        "dec-cursor-shape",
        "xtversion",
        "decstr-side-effects",
        "c1-controls"
      ]
    },
    {
      "slug": "apc-application-command",
      "family": "ESC",
      "title": {
        "en": "APC — Application Program Command (`ESC _ … ESC \\\\` / `\\x9F … \\x9C`)",
        "zh": "APC —— 应用程序命令（`ESC _ … ESC \\\\` / `\\x9F … \\x9C`）"
      },
      "shortDesc": {
        "en": "The string introducer ECMA-48 reserves for application-to-application messages. Modern use: Kitty graphics protocol, VS Code shell integration, Windows Terminal API patches. Sibling to DCS / OSC / PM / SOS.",
        "zh": "ECMA-48 为应用对应用消息保留的字符串引导符。现代用途：Kitty 图形协议、VS Code shell 集成、Windows Terminal API 补丁。与 DCS / OSC / PM / SOS 同辈。"
      },
      "bytes": {
        "canonical": "\\x1b_<body>\\x1b\\\\   (7-bit)    \\x9f<body>\\x9c   (8-bit C1)",
        "octal": "\\033_<body>\\033\\\\   (7-bit)    \\237<body>\\234   (8-bit C1)",
        "eEscape": "\\e_<body>\\e\\\\",
        "literal": "ESC _  <body>  ESC \\\\      or      0x9F  <body>  0x9C",
        "hex": "1b 5f <body> 1b 5c   /   9f <body> 9c"
      },
      "description": {
        "en": "**APC** (*Application Program Command*) is the ECMA-48 string introducer reserved for **application-to-application** messages — bytes the terminal is supposed to pass through transparently to a peer application listening on the same TTY, without interpreting the body itself. The 7-bit form is `\\x1b_<body>\\x1b\\\\` (ESC `_` + opaque bytes + ST); the 8-bit C1 form is the single byte `\\x9F` introducer + body + single-byte `\\x9C` terminator. Sibling to **DCS** (`\\x1bP`, device control), **OSC** (`\\x1b]`, OS command), **PM** (`\\x1b^`, privacy message), **SOS** (`\\x1bX`, start of string) — five 'string-shaped' sequence families framed by the same ST.\n\n**Why APC matters in 2026.** ECMA-48 originally designed APC for tunneling between an application running on a remote host and a co-resident application on the same terminal (early thin-client / mainframe-frontend setups). That use case is mostly dead, but the byte shape has been **co-opted** as a 'safe escape hatch' for vendor-specific protocols that don't want to step on OSC's user-facing semantics:\n\n- **Kitty's graphics protocol** is the headline modern user — Kitty + Konsole + WezTerm + Ghostty + Wayst accept image data via `\\x1b_G<key1>=<val1>,<key2>=<val2>,...;<base64-pixels>\\x1b\\\\`. The `G` first-byte after `_` is Kitty's family tag; subsequent emulators that adopted Kitty graphics keep it. (Despite the slug name `dcs-kitty-graphics`, the actual byte sequence is APC, not DCS — the slug predates this clarification.)\n- **VS Code shell integration** uses APC with a `633;` prefix as a private channel for shell-integration markers that VS Code's terminal doesn't want to advertise via OSC 133.\n- **Windows Terminal** is experimenting with `\\x1b_<JSON>\\x1b\\\\` for terminal-API JSON messages (preview builds, not stable).\n- **ConPTY pass-through** — Windows ConPTY filters most OSC sequences for security, but historically passed APC through more permissively, so some Windows-side tools route through APC to reach the host terminal unaltered.\n\n**Parser rules.** Treat the body as **opaque bytes** until ST is seen at packet boundary. Specifically: ECMA-48 says any 'escape sequence other than ESC \\\\' inside the body must be ignored by the terminal but preserved when passed through; a strict parser reads bytes into a buffer, scanning for `\\x1b` followed immediately by `\\\\` (the only valid 7-bit ST) or for the single byte `\\x9C`. **Naive 'split on ESC' parsers will mis-frame** any body that legitimately contains ESC bytes (Kitty graphics in particular embeds binary data that statistically hits 0x1B).\n\n**Security stance.** Because APC is meant to be passed through opaquely, terminals that *do* implement APC dispatch must whitelist the protocols they recognise (Kitty graphics tag `G`, VS Code `633;`, etc.) and silently drop unknown APC bodies — emitting a stranger's APC body to the user would let one application impersonate another. Terminals that *don't* implement any APC protocols (Alacritty, gnome-terminal, macOS Terminal, Linux console) should silently swallow + discard, which they do; treat APC as 'will reach a peer that knows the tag, or vanish completely' — never as a guaranteed-visible channel.\n\n**Distinction from DCS / OSC / PM / SOS.**\n- **DCS** (`\\x1bP`) — device control (data targeted at the *terminal* itself: DECRQSS, DECDLD, DECUDK, Sixel, terminfo cap query).\n- **OSC** (`\\x1b]`) — OS command (data targeted at the terminal-as-OS-shim: window title, palette, clipboard, hyperlink, prompt markers — user-facing semantics).\n- **APC** (`\\x1b_`) — application command (data targeted at a *peer application*, not the terminal — the terminal is just a courier).\n- **PM** (`\\x1b^`) — privacy message (similar courier semantics to APC, less adopted in practice; some legacy thin-client gear used it).\n- **SOS** (`\\x1bX`) — start of string (the most generic introducer, no semantic; almost universally unused in 2026).\n\n**Common parsing bug** — terminals that implement OSC and DCS but forget APC: they see `\\x1b_G...` , don't recognise the introducer, and **emit `_G...`** to the visible screen. Look for stray `_G` runs on broken Kitty-graphics renders to diagnose this.\n\n**Coverage** — APC dispatch (i.e. routing the body to a registered handler) is **niche**. **Kitty** + **WezTerm** + **Konsole** + **Ghostty** = partial-to-full (each routes APC `G` to its graphics handler; other APC bodies discarded). **xterm** = partial (recognises APC framing, discards body by default — `apcDispatch` X resource off). **mlterm** + **iTerm2** + **Windows Terminal** = partial (APC framing recognised, vendor-tagged bodies handled, other bodies discarded). **Alacritty** + **gnome-terminal** + **macOS Terminal** + **Linux console** + **cmd / ConPTY** = no-op-but-correct (APC framing recognised, body silently swallowed — no visible artifact). **Modern emulators all do at least the framing correctly** — buggy ones that emit the body literally are limited to very old builds.",
        "zh": "**APC**（*应用程序命令*）是 ECMA-48 为**应用对应用**消息保留的字符串引导符 —— 终端应当透明转发给同 TTY 上监听的对端应用、不自行解释主体的字节。7 位形 `\\x1b_<body>\\x1b\\\\`（ESC `_` + 不透明字节 + ST）；8 位 C1 形为单字节 `\\x9F` 引导 + 主体 + 单字节 `\\x9C` 终止。与 **DCS**（`\\x1bP`，设备控制）、**OSC**（`\\x1b]`，OS 命令）、**PM**（`\\x1b^`，隐私消息）、**SOS**（`\\x1bX`，串起始）同辈 —— 五个被同样 ST 框定的「串形」序列家族。\n\n**2026 年为何还讲 APC。** ECMA-48 原本设计 APC 用于在远程主机的应用与终端上的同位应用之间打隧道（早期瘦客户机 / 大型机前端）。该用例基本死了，但字节形状被**借用**为不愿动用 OSC 用户面语义的厂商专用协议的「安全脱逃口」：\n\n- **Kitty 图形协议**是头号现代用户 —— Kitty + Konsole + WezTerm + Ghostty + Wayst 通过 `\\x1b_G<key1>=<val1>,<key2>=<val2>,...;<base64-像素>\\x1b\\\\` 接收图像数据。`_` 后的首字节 `G` 是 Kitty 家族标签；后续采纳 Kitty 图形协议的模拟器都保留这一字节。（slug 名 `dcs-kitty-graphics` 早于此澄清而定 —— 真实字节流是 APC，不是 DCS。）\n- **VS Code shell 集成**借 APC 带 `633;` 前缀作为私有通道，承载 VS Code 不愿用 OSC 133 公开广告的 shell 集成标记。\n- **Windows Terminal** 在预览版里试验 `\\x1b_<JSON>\\x1b\\\\` 作为终端 API JSON 消息载体（未稳定）。\n- **ConPTY 直通** —— Windows ConPTY 因安全考量过滤多数 OSC，历史上对 APC 直通更宽松，故部分 Windows 侧工具改走 APC 以原样抵达主机终端。\n\n**解析规则。** 视主体为**不透明字节**，直至在包边界见到 ST。具体：ECMA-48 规定主体内任何「ESC \\\\ 之外的转义序列」终端须忽略却需透传；严格解析器把字节读入缓冲，扫描 `\\x1b` 紧接 `\\\\`（唯一合法 7 位 ST）或单字节 `\\x9C`。**天真的「按 ESC 分割」解析器**对任何合法包含 ESC 字节的主体（Kitty 图形协议尤甚 —— 其内嵌二进制统计上一定撞 0x1B）会错框。\n\n**安全态度。** 因 APC 本就要原样透传，*确实*实现 APC 分派的终端必须白名单已识别协议（Kitty 图形 `G` 标签、VS Code `633;` 等）并静默丢弃未知 APC 主体 —— 把陌生人的 APC 主体送给用户会让一个应用冒充另一个。*不*实现任何 APC 协议的终端（Alacritty、gnome-terminal、macOS Terminal、Linux console）静默吞掉即可（事实如此）；视 APC 为「要么抵达知道标签的对端，要么完全消失」—— 永远不要把它当作保证可见的通道。\n\n**与 DCS / OSC / PM / SOS 的区别。**\n- **DCS**（`\\x1bP`）—— 设备控制（数据面向*终端*本身：DECRQSS、DECDLD、DECUDK、Sixel、terminfo cap 查询）。\n- **OSC**（`\\x1b]`）—— OS 命令（数据面向「终端即 OS 垫层」：窗口标题、调色板、剪贴板、超链接、提示标记 —— 用户面语义）。\n- **APC**（`\\x1b_`）—— 应用命令（数据面向*对端应用*，不面向终端 —— 终端只是搬运工）。\n- **PM**（`\\x1b^`）—— 隐私消息（搬运语义类似 APC，实际采用更少；部分遗留瘦客户机硬件用过）。\n- **SOS**（`\\x1bX`）—— 串起始（最通用引导符，无语义；2026 年几乎无人用）。\n\n**常见解析 Bug** —— 实现了 OSC + DCS 却忘了 APC 的终端：见到 `\\x1b_G...`，识别不出引导符，于是**把 `_G...` 印到可见屏幕**。Kitty 图形渲染坏了之后看见散落的 `_G` 串就是这个症。\n\n**覆盖度** —— APC 分派（即把主体路由到注册处理器）**小众**。**Kitty** + **WezTerm** + **Konsole** + **Ghostty** = 部分到完整（各把 APC `G` 路由到图形处理器；其它 APC 主体丢弃）。**xterm** = 部分（识别 APC 框架，默认丢弃主体 —— 需 `apcDispatch` X 资源启用）。**mlterm** + **iTerm2** + **Windows Terminal** = 部分（识别 APC 框架，厂商标签主体处理，其余丢弃）。**Alacritty** + **gnome-terminal** + **macOS Terminal** + **Linux console** + **cmd / ConPTY** = 无作用但正确（识别 APC 框架，主体静默吞 —— 无可见残留）。**现代模拟器至少都把框架做对了** —— 把主体字面打印的 bug 仅在很老的构建里残存。"
      },
      "parameters": [
        {
          "name": "Introducer (7-bit)",
          "desc": {
            "en": "ESC + underscore (\\x1b 0x5f). The C0-safe form; works under UTF-8.",
            "zh": "ESC + 下划线（\\x1b 0x5f）。C0 安全形；UTF-8 下亦可用。"
          }
        },
        {
          "name": "Introducer (8-bit)",
          "desc": {
            "en": "Single byte 0x9F. UTF-8 unsafe (continuation byte). Avoid except in known-Latin-1 channels.",
            "zh": "单字节 0x9F。UTF-8 不安全（续字节）。除已知 Latin-1 通道外勿用。"
          }
        },
        {
          "name": "Terminator",
          "desc": {
            "en": "ESC + backslash (\\x1b\\\\, 7-bit ST) or single byte 0x9C (8-bit ST). Either is valid; match the introducer width.",
            "zh": "ESC + 反斜杠（\\x1b\\\\，7 位 ST）或单字节 0x9C（8 位 ST）。任一皆可；与引导符宽度匹配。"
          }
        },
        {
          "name": "Body",
          "desc": {
            "en": "Opaque bytes — terminal must not interpret. Vendor protocols use a first-byte family tag (Kitty 'G', VS Code '633;', ...).",
            "zh": "不透明字节 —— 终端不得解释。厂商协议以首字节家族标签区分（Kitty 'G'、VS Code '633;' 等）。"
          }
        }
      ],
      "spec": "ECMA-48 §8.3.2 (APC) / xterm-ctlseqs (APC) / Kitty graphics protocol",
      "examples": [
        {
          "lang": "bash",
          "code": "# Probe whether the terminal accepts a Kitty-graphics APC frame.\\n# Empty image (1x1 transparent PNG, base64-tiny) — if rendered, terminal supports Kitty graphics.\\nprintf '\\\\033_Gf=32,s=1,v=1,a=T;AAAAAA==\\\\033\\\\\\\\'\\n# Emit a custom APC tag — most terminals will silently swallow.\\nprintf '\\\\033_myapp;hello\\\\033\\\\\\\\'\\necho 'still here'   # no visible artifact on any modern terminal"
        },
        {
          "lang": "python",
          "code": "import sys\\n# Send a Kitty-graphics-style APC frame.\\ndef apc(body):\\n    sys.stdout.write('\\\\x1b_' + body + '\\\\x1b\\\\\\\\')\\n    sys.stdout.flush()\\napc('Gf=32,s=1,v=1,a=T;AAAAAA==')   # Kitty 'G' tag + base64 payload\\napc('myapp;state=ready')             # private tag — silently swallowed on non-vendor terminals"
        },
        {
          "lang": "go",
          "code": "// Robust APC parser: read until ST at packet boundary, never split on raw ESC.\\nfunc readAPC(r *bufio.Reader) ([]byte, error) {\\n    var buf bytes.Buffer\\n    for {\\n        b, err := r.ReadByte()\\n        if err != nil { return nil, err }\\n        if b == 0x9c { return buf.Bytes(), nil }      // 8-bit ST\\n        if b == 0x1b {\\n            n, _ := r.ReadByte()\\n            if n == '\\\\\\\\' { return buf.Bytes(), nil }    // 7-bit ST\\n            buf.WriteByte(b); buf.WriteByte(n); continue\\n        }\\n        buf.WriteByte(b)\\n    }\\n}"
        },
        {
          "lang": "javascript",
          "code": "// Emit APC + listen for response APC from a peer.\\nfunction sendAPC(body) {\\n  process.stdout.write('\\\\x1b_' + body + '\\\\x1b\\\\\\\\');\\n}\\n// Parse incoming APC (collect bytes until ST, never split on raw ESC).\\nlet apcBuf = '';\\nprocess.stdin.on('data', chunk => {\\n  const m = /\\\\x1b_([^\\\\x1b]*(?:\\\\x1b[^\\\\\\\\][^\\\\x1b]*)*)\\\\x1b\\\\\\\\/.exec(apcBuf + chunk.toString('binary'));\\n  if (m) console.error('APC body:', m[1]);\\n});"
        },
        {
          "lang": "c",
          "code": "/* Emit APC with custom vendor tag. */\\n#include <stdio.h>\\nvoid send_apc(const char* tag, const char* body) {\\n    printf(\\\"\\\\x1b_%s;%s\\\\x1b\\\\\\\\\\\", tag, body);\\n    fflush(stdout);\\n}\\n/* Usage: send_apc(\\\"myapp\\\", \\\"hello\\\");  // silently swallowed on non-vendor terms */"
        }
      ],
      "support": {
        "xterm": "partial",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "partial",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "no",
        "konsole": "yes"
      },
      "related": [
        "dcs-kitty-graphics",
        "c1-controls",
        "osc-iterm-image",
        "dcs-decrqss"
      ]
    },
    {
      "slug": "dec-rect-ops",
      "family": "CSI",
      "title": {
        "en": "DECCRA / DECFRA / DECERA / DECSERA — Copy / Fill / Erase / Selective-erase rectangular area",
        "zh": "DECCRA / DECFRA / DECERA / DECSERA —— 矩形区域的复制 / 填充 / 擦除 / 选择性擦除"
      },
      "shortDesc": {
        "en": "The four content-side rectangle ops missing from the DEC rect family — copy a block, fill it with a glyph, erase to space, or erase only non-protected cells. Pairs with DECCARA / DECRARA (attribute-side) and DECSACE (block-vs-stream toggle).",
        "zh": "DEC 矩形操作族里改字符内容的四件套 —— 复制一块、用某字模填、擦成空格、只擦未保护单元。与 DECCARA / DECRARA（改属性侧）以及 DECSACE（块 vs 流切换）配套。"
      },
      "bytes": {
        "canonical": "\\x1b[<Pts>;<Pls>;<Pbs>;<Prs>;<Pps>;<Ptd>;<Pld>;<Ppd>$v   DECCRA\\n\\x1b[<Pch>;<Pt>;<Pl>;<Pb>;<Pr>$x                       DECFRA\\n\\x1b[<Pt>;<Pl>;<Pb>;<Pr>$z                              DECERA\\n\\x1b[<Pt>;<Pl>;<Pb>;<Pr>${                              DECSERA",
        "octal": "\\033[1;1;10;40;1;15;5;1$v   /   \\033[42;3;5;10;40$x   /   \\033[3;5;10;40$z   /   \\033[3;5;10;40${",
        "eEscape": "\\e[1;1;10;40;1;15;5;1$v   /   \\e[42;3;5;10;40$x   /   \\e[3;5;10;40$z   /   \\e[3;5;10;40${",
        "literal": "ESC [ Pts;Pls;Pbs;Prs;Pps;Ptd;Pld;Ppd $ v   /   $ x   /   $ z   /   $ {",
        "hex": "1b 5b … 24 76   /   1b 5b … 24 78   /   1b 5b … 24 7a   /   1b 5b … 24 7b"
      },
      "description": {
        "en": "Four DEC ops sharing the `$` intermediate that *do* touch character data inside a rectangle — DECCARA / DECRARA only re-attribute. Each rectangle uses 1-indexed inclusive coordinates and obeys the current scroll region + origin mode. Block-vs-stream interpretation of the rectangle is selected by **DECSACE** (`\\x1b[Ps*x`).\n\n**DECCRA** — *Copy Rectangular Area*, `$v`. Eight parameters: source rect (`Pts;Pls;Pbs;Prs;Pps`), then destination top-left (`Ptd;Pld;Ppd`). `Pps`/`Ppd` are page numbers (1 on every modern single-page emulator — DEC VT525 had multi-page memory). The op is a *cell-for-cell* copy: characters + their per-cell attributes move together; cells outside the destination's visible area are clipped, not wrapped. Overlapping source / destination is handled correctly (terminals typically copy through an internal scratch buffer so a top-to-bottom shift is safe).\n\n**DECFRA** — *Fill Rectangular Area*, `$x`. Five parameters: the glyph code (`Pch`, a 7-bit decimal code 32–126; or a 16-bit code on UTF-8-aware emulators), then `Pt;Pl;Pb;Pr` rectangle. Every cell is overwritten with the glyph, gaining the *current* SGR pen as its attributes. Common uses: clear an inset to a single character (DECFRA with `Pch=32` is the per-rect equivalent of `clear`), draw a solid frame with `█` (U+2588) on a UTF-8 emulator, or pre-fill scratch panes.\n\n**DECERA** — *Erase Rectangular Area*, `$z`. Four parameters: the rectangle. Equivalent to DECFRA with `Pch=32` (space) *and* the cell attributes reset to default — so it leaves a *fully cleared* rect, not a 'spaces with current pen'. The reset includes the SGR layer, foreground/background colour, and the selective-erase protection bit.\n\n**DECSERA** — *Selective Erase Rectangular Area*, `${`. Four parameters: the rectangle. Like DECERA *but* respects the **DECSCA-protected** bit: cells that were marked protected via `\\x1b[1\"q` survive. The other cells clear to space + default attrs. This is the rect-form of `decsed-decsel` (selective ED / EL) and the only way to clear a form template without wiping the labels.\n\n**Stream mode (DECSACE)**. With `\\x1b[2*x` in effect, `Pt;Pl` and `Pb;Pr` are interpreted as stream-start and stream-end positions instead of rectangle corners — the affected cells are every cell between the two positions following normal text-flow (line-wrap aware). Stream-mode is **only** wired through DECCARA / DECRARA on every shipping emulator; the four content ops above keep block semantics regardless of DECSACE. This is a *DEC-vs-VT510* deviation in xterm and family — verify with DECRQM `?92` if you need to depend on it.\n\n**Coverage**: **xterm** = full all four. **Konsole** = full. **WezTerm** + **Ghostty** = full (DECFRA + DECERA), DECCRA + DECSERA partial. **gnome-terminal** + **mlterm** = full. **iTerm2** = partial (no DECSERA, others honour current SGR pen rather than reset). **Kitty** = DECERA + DECFRA full, DECCRA + DECSERA no-op. **Alacritty** + **Windows Terminal** + **cmd / ConPTY** + **Linux console** + **macOS Terminal** = no-op (silently consumed). Feature-probe with `xtversion` plus a DECRQSS round-trip on `$z` before relying.",
        "zh": "DEC 矩形族中共享 `$` 中间字节、*会*改单元内字符的四件套 —— DECCARA / DECRARA 只改属性。每个矩形用 1 起算闭区间坐标，遵循当前滚动区与原点模式。「块 vs 流」的矩形语义由 **DECSACE**（`\\x1b[Ps*x`）选择。\n\n**DECCRA** —— *矩形区域复制*，`$v`。八参：源矩形（`Pts;Pls;Pbs;Prs;Pps`）+ 目的左上角（`Ptd;Pld;Ppd`）。`Pps`/`Ppd` 是页号（在所有现代单页模拟器上为 1 —— DEC VT525 有多页内存）。是*逐单元*复制：字符与每单元属性一起搬；落到目的可见区外的部分被裁剪，不换行。源 / 目的重叠时正确处理（终端通常借内部 scratch 缓冲，故自上向下平移安全）。\n\n**DECFRA** —— *矩形区域填充*，`$x`。五参：字模码（`Pch`，7 位十进制码 32–126；UTF-8 感知模拟器上是 16 位码）+ `Pt;Pl;Pb;Pr`。每个单元被该字模覆盖，并取得*当前* SGR 笔的属性。常见用途：用单字符（DECFRA `Pch=32` 是按矩形版的 `clear`）清掉一个内置框、在 UTF-8 模拟器上用 `█`（U+2588）画实心框、为 scratch 窗格预填。\n\n**DECERA** —— *矩形区域擦除*，`$z`。四参：矩形。等价于 DECFRA `Pch=32`（空格）*且*单元属性回到默认 —— 留下*完全清空*的矩形，而非「带当前笔的空格」。重置包括 SGR 层、前后景色、选择性擦除保护位。\n\n**DECSERA** —— *选择性擦除矩形区域*，`${`。四参：矩形。同 DECERA 但*尊重* **DECSCA 保护**位：被 `\\x1b[1\"q` 标为保护的单元保留；其余清成空格 + 默认属性。是 `decsed-decsel`（选择性 ED / EL）的矩形版 —— 表单模板上清字段但留标签的唯一办法。\n\n**流模式（DECSACE）**。当 `\\x1b[2*x` 生效时，`Pt;Pl` 与 `Pb;Pr` 解释为流起止位置而非矩形角 —— 受影响单元为两位置间按正常文本流（含换行）依次每单元。流模式在**所有**实际模拟器上**仅**通过 DECCARA / DECRARA 接通；以上四个内容操作无论 DECSACE 如何都按块语义。这是 xterm 家族相对 *DEC VT510* 的偏离 —— 若你要依赖此行为，用 DECRQM `?92` 探测。\n\n**覆盖度**：**xterm** = 四个都完整。**Konsole** = 完整。**WezTerm** + **Ghostty** = DECFRA + DECERA 完整，DECCRA + DECSERA 部分。**gnome-terminal** + **mlterm** = 完整。**iTerm2** = 部分（不支持 DECSERA，其余尊重当前 SGR 笔而非重置）。**Kitty** = DECERA + DECFRA 完整，DECCRA + DECSERA 静默。**Alacritty** + **Windows Terminal** + **cmd / ConPTY** + **Linux console** + **macOS Terminal** = 静默。要依赖时用 `xtversion` + 对 `$z` 做 DECRQSS 探测先确认。"
      },
      "parameters": [
        {
          "name": "Pts;Pls;Pbs;Prs;Pps (DECCRA)",
          "desc": {
            "en": "Source rectangle top / left / bottom / right / page (1-indexed, inclusive).",
            "zh": "源矩形上 / 左 / 下 / 右 / 页（1 起算、闭区间）。"
          }
        },
        {
          "name": "Ptd;Pld;Ppd (DECCRA)",
          "desc": {
            "en": "Destination top-left row / col / page.",
            "zh": "目的左上角行 / 列 / 页。"
          }
        },
        {
          "name": "Pch (DECFRA)",
          "desc": {
            "en": "Glyph code to fill with — 32–126 (7-bit ASCII) on classic DEC; many modern emulators accept up to U+FFFF.",
            "zh": "用于填充的字模码 —— 经典 DEC 上 32–126（7 位 ASCII）；多数现代模拟器接受到 U+FFFF。"
          }
        },
        {
          "name": "Pt;Pl;Pb;Pr (DECFRA / DECERA / DECSERA)",
          "desc": {
            "en": "Rectangle top row / left col / bottom row / right col, 1-indexed inclusive.",
            "zh": "矩形上行 / 左列 / 下行 / 右列，1 起算闭区间。"
          }
        }
      ],
      "spec": "DEC VT510 RM (DECCRA / DECFRA / DECERA / DECSERA) / xterm-ctlseqs (CSI ... $ v / x / z / {)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Copy rows 1-5 cols 1-40 to rows 20-24 cols 41-80.\\nprintf '\\\\033[1;1;5;40;1;20;41;1$v'\\n# Fill a status bar with U+2588 (decimal 9608) — needs UTF-8 emulator.\\nprintf '\\\\033[9608;24;1;24;80$x'\\n# Erase rows 5-10 cols 5-75 (clear an inset region).\\nprintf '\\\\033[5;5;10;75$z'"
        },
        {
          "lang": "python",
          "code": "import sys\\n# Form-field clear: keep DECSCA-protected labels, clear data cells.\\nsys.stdout.write('\\\\x1b[3;10;20;70${')   # DECSERA\\nsys.stdout.flush()"
        },
        {
          "lang": "go",
          "code": "// Pre-fill a help pane with '·' (decimal 183) before drawing content.\\nfmt.Print(\\\"\\\\x1b[183;1;1;24;80$x\\\")"
        },
        {
          "lang": "javascript",
          "code": "// 'Reset the canvas inset' — DECERA wipes both glyph + attrs to default.\\nprocess.stdout.write('\\\\x1b[2;2;23;79$z');"
        },
        {
          "lang": "c",
          "code": "/* Duplicate a logo block from rows 1-6 cols 1-30 to a side panel. */\\nprintf(\\\"\\\\x1b[1;1;6;30;1;1;51;1$v\\\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "partial",
        "alacritty": "no",
        "wezterm": "partial",
        "ghostty": "partial",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "deccara-decrara",
        "decsace",
        "decsed-decsel",
        "decstbm"
      ]
    },
    {
      "slug": "decsace",
      "family": "CSI",
      "title": {
        "en": "DECSACE — Select Attribute Change Extent (`CSI Ps * x`)",
        "zh": "DECSACE —— 选择属性改写范围（`CSI Ps * x`）"
      },
      "shortDesc": {
        "en": "Toggle whether DECCARA / DECRARA treat their rectangle as a literal cell block (default) or as a stream from start-position to end-position. The content-side rect ops (DECCRA / DECFRA / DECERA / DECSERA) are unaffected.",
        "zh": "切换 DECCARA / DECRARA 把矩形当作字面单元块（默认）还是从起点到终点的文本流。内容侧矩形操作（DECCRA / DECFRA / DECERA / DECSERA）不受影响。"
      },
      "bytes": {
        "canonical": "\\x1b[<Ps>*x",
        "octal": "\\033[0*x   /   \\033[1*x   /   \\033[2*x",
        "eEscape": "\\e[0*x   /   \\e[1*x   /   \\e[2*x",
        "literal": "ESC [ Ps * x",
        "hex": "1b 5b 30 2a 78   /   1b 5b 31 2a 78   /   1b 5b 32 2a 78"
      },
      "description": {
        "en": "**DECSACE** is the one-byte parameter that decides what 'a rectangle' means to **DECCARA** (`$r`) and **DECRARA** (`$t`). The content-side ops — **DECCRA** (`$v`), **DECFRA** (`$x`), **DECERA** (`$z`), **DECSERA** (`${`) — always use block semantics regardless of DECSACE (see `dec-rect-ops`).\n\n**Parameters**\n- `Ps = 0` (default) or `Ps = 1` — **block / rectangle** mode. Coordinates name the corners of a strict cell rectangle. `Pt;Pl` is the top-left, `Pb;Pr` is the bottom-right; the affected cells form a literal rectangle of `(Pb−Pt+1) × (Pr−Pl+1)` cells.\n- `Ps = 2` — **stream** mode. Coordinates name two positions in text-flow order. `Pt;Pl` is the stream-start, `Pb;Pr` is the stream-end; the affected cells are every cell on or after start through the end, following normal text wrap. A 'paragraph' highlighter — e.g. bold the prose from `(3,1)` through `(7,40)` ignoring column boundaries.\n\n**Query**: DECSACE is reported via DECRQM with private mode `?92` (`\\x1b[?92$p` reply: `\\x1b[?92;<Ps>$y` where `Ps` is the active extent — `2` means stream, anything else means block). Some emulators report `1` for the default rather than `0`.\n\n**Persistence**: the value is part of terminal state — saved by DECRQTSR / DECSC and restored by DECRSTS / DECRC. DECSTR (soft reset) resets DECSACE to block (`Ps = 0`). RIS (hard reset) does the same.\n\n**Practical use**: the **block** default is what TUIs and screen renderers want — a rectangle attribute change is a rectangle. **Stream** mode is what *editors* want when re-attributing a selection that may span line wraps without preserving column structure — VS Code-style 'underline this prose span'. The mode is sticky, so toggle to stream, do the rect-attr ops, toggle back to block. Don't leave it in stream mode — later code that assumes block semantics will mis-paint.\n\n**Coverage**: **xterm** = full (definitive). **Konsole** + **gnome-terminal** + **mlterm** + **WezTerm** + **Ghostty** = full. **iTerm2** = partial (DECRQM `?92` reports correctly, but stream-mode DECRARA mis-paints when the rectangle straddles a wrapped line). **Kitty** = partial (mode is parsed and stored, but DECCARA / DECRARA themselves are partial — see their entry). **Alacritty** + **Windows Terminal** + **cmd / ConPTY** + **Linux console** + **macOS Terminal** = no-op (DECCARA / DECRARA also no-op, so DECSACE has nothing to switch).",
        "zh": "**DECSACE** 是一个字节参数，决定「矩形」在 **DECCARA**（`$r`）与 **DECRARA**（`$t`）眼中是什么。内容侧的 —— **DECCRA**（`$v`）、**DECFRA**（`$x`）、**DECERA**（`$z`）、**DECSERA**（`${`）—— 不论 DECSACE 如何始终按块语义（见 `dec-rect-ops`）。\n\n**参数**\n- `Ps = 0`（默认）或 `Ps = 1` —— **块 / 矩形**模式。坐标命名严格单元矩形的角。`Pt;Pl` 是左上，`Pb;Pr` 是右下；受影响单元构成字面 `(Pb−Pt+1) × (Pr−Pl+1)` 单元矩形。\n- `Ps = 2` —— **流**模式。坐标按文本流顺序命名两个位置。`Pt;Pl` 是流起，`Pb;Pr` 是流止；受影响单元为起点至终点之间（含两端）按正常换行流的每一个单元。是「段落」高亮器 —— 对 `(3,1)` 至 `(7,40)` 之间所有散文加粗、不顾列边界。\n\n**查询**：DECSACE 通过 DECRQM 在私有模式 `?92` 上报（`\\x1b[?92$p` 回 `\\x1b[?92;<Ps>$y`，`Ps` 是当前范围 —— `2` 流、其他块）。有些模拟器对默认情况回 `1` 而非 `0`。\n\n**持久性**：值是终端状态的一部分 —— 被 DECRQTSR / DECSC 保存、被 DECRSTS / DECRC 还原。DECSTR（软重置）把 DECSACE 复位为块（`Ps = 0`）；RIS（硬重置）同。\n\n**实际用法**：**块**默认正是 TUI 与屏幕渲染器要的 —— 矩形属性改写就是一个矩形。**流**模式是*编辑器*要的 —— 对可能跨换行、不必保留列结构的选区做属性 —— VS Code 风格的「为这段散文加下划线」。模式有粘性，所以切到流、做矩形属性操作、再切回块。别留在流模式 —— 后续假定块语义的代码会画错。\n\n**覆盖度**：**xterm** = 完整（基准）。**Konsole** + **gnome-terminal** + **mlterm** + **WezTerm** + **Ghostty** = 完整。**iTerm2** = 部分（DECRQM `?92` 正确回报，但流模式 DECRARA 在矩形跨越换行行时画错）。**Kitty** = 部分（模式被解析与保存，但 DECCARA / DECRARA 本身就部分 —— 见其条目）。**Alacritty** + **Windows Terminal** + **cmd / ConPTY** + **Linux console** + **macOS Terminal** = 静默（DECCARA / DECRARA 本身就静默，故 DECSACE 没有什么可切）。"
      },
      "parameters": [
        {
          "name": "Ps = 0 or 1",
          "desc": {
            "en": "Block (rectangle) mode — DECCARA / DECRARA treat coords as rect corners. Default.",
            "zh": "块（矩形）模式 —— DECCARA / DECRARA 把坐标当作矩形角。默认。"
          }
        },
        {
          "name": "Ps = 2",
          "desc": {
            "en": "Stream mode — DECCARA / DECRARA treat coords as start / end positions in text flow.",
            "zh": "流模式 —— DECCARA / DECRARA 把坐标当作文本流中的起 / 止位置。"
          }
        }
      ],
      "spec": "DEC VT510 RM (DECSACE) / xterm-ctlseqs (CSI Ps * x)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Enter stream mode, bold a prose span from (3,1) to (7,40), restore block.\\nprintf '\\\\033[2*x'                  # DECSACE = stream\\nprintf '\\\\033[3;1;7;40;1$r'         # DECCARA bold\\nprintf '\\\\033[0*x'                  # DECSACE = block (cleanup)"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('\\\\x1b[?92$p')   # DECRQM probe — what's the current extent?\\nsys.stdout.flush()\\n# Reply on stdin: '\\\\x1b[?92;0$y' = block, ';2$y' = stream."
        },
        {
          "lang": "go",
          "code": "// Always restore block mode before exiting a TUI subroutine.\\ndefer fmt.Print(\\\"\\\\x1b[0*x\\\")\\nfmt.Print(\\\"\\\\x1b[2*x\\\")  // stream for the duration\\n// ... rect-attr work ..."
        },
        {
          "lang": "javascript",
          "code": "// Highlight a wrap-aware selection: positions 12,5 -> 18,40 as one stream.\\nprocess.stdout.write('\\\\x1b[2*x\\\\x1b[12;5;18;40;7$r\\\\x1b[0*x');"
        },
        {
          "lang": "c",
          "code": "/* Toggle stream mode briefly; assume xterm or konsole. */\\nprintf(\\\"\\\\x1b[2*x\\\");\\nprintf(\\\"\\\\x1b[%d;%d;%d;%d;1;4$r\\\", t, l, b, r);  /* bold + underline */\\nprintf(\\\"\\\\x1b[0*x\\\");"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "partial",
        "wt": "no",
        "cmd": "no",
        "kitty": "partial",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "deccara-decrara",
        "dec-rect-ops",
        "decrqm",
        "decstr-side-effects"
      ]
    },
    {
      "slug": "csi-media-copy",
      "family": "CSI",
      "title": {
        "en": "CSI Ps i — Media Copy (MC) — printer-on / printer-off / print line",
        "zh": "CSI Ps i —— 媒体复制（MC）—— 启用打印 / 关闭打印 / 打印行"
      },
      "shortDesc": {
        "en": "ECMA-48 §8.3.82 control that historically routed terminal output to an attached printer. Survives today as the 'print screen' hook on xterm/mlterm, the IBM-3270 emulator pass-through, and as private-mode `CSI ? 4 / 5 i` auto-print toggles consumed by `expect`-style automation.",
        "zh": "ECMA-48 §8.3.82 控制，历史上把终端输出转给所连打印机。今日仍存于 xterm/mlterm 的「打印屏幕」钩子、IBM-3270 模拟器透传，以及私有模式 `CSI ? 4 / 5 i` 自动打印开关（被 `expect` 风格自动化使用）。"
      },
      "bytes": {
        "canonical": "\\x1b[0i   /   \\x1b[4i   /   \\x1b[5i   /   \\x1b[?4i   /   \\x1b[?5i",
        "octal": "\\033[5i   (printer-on)    \\033[4i   (printer-off)",
        "eEscape": "\\e[5i   /   \\e[4i",
        "literal": "ESC [ Ps i   (Ps ∈ {0,1,4,5})   /   ESC [ ? Ps i",
        "hex": "1b 5b 35 69   (printer-on)   /   1b 5b 34 69   (printer-off)"
      },
      "description": {
        "en": "**Media Copy** (MC) is the ECMA-48 mechanism for diverting terminal output to a secondary stream — historically an attached line printer or a serial-port-attached page printer. The standard parameters:\n- `\\x1b[0i` (or just `\\x1b[i`) — **print page**. Send the current screen contents to the printer as a one-shot. The terminal handles framing (form-feed, page-end). xterm honours this by writing to the program named in the `printerCommand` X resource (typically `lpr`).\n- `\\x1b[1i` — **print line**. One-line variant of `0i`.\n- `\\x1b[4i` — **printer-off** (Media Copy 'deselect'). Stop the stream-divert started by `5i`. After this, output goes only to the screen.\n- `\\x1b[5i` — **printer-on** (Media Copy 'select'). Start diverting all subsequent terminal output to the printer until a matching `4i`. Often called *transparent print mode*. The screen receives nothing in this state.\n\n**Private-prefix DEC variants** (`\\x1b[?Ps i`):\n- `\\x1b[?1i` — print cursor line (single line, no form-feed).\n- `\\x1b[?4i` — turn **auto-print** off.\n- `\\x1b[?5i` — turn **auto-print** on. Whenever the cursor advances past the right margin or a `\\n` flushes a line, that line is also sent to the printer.\n- `\\x1b[?10i` / `\\x1b[?11i` — print the composed display (VT300+); print every character including received controls.\n\n**Why it still matters in 2026**\n- **IBM 3270 / 5250 emulator stacks** (`x3270`, `wc3270`, `tn5270`) flow MC through the host application to a real or virtual `LPT` device. Older mainframe batch jobs still expect the `\\x1b[5i…\\x1b[4i` envelope to bracket print data.\n- **xterm** + **mlterm** honour `0i` and `5i`/`4i` if `printerCommand` is set in the X resources — the modern equivalent is `printerCommand: cat > /tmp/xterm.dump`. Useful for screen capture / debugging without `tmux capture-pane`.\n- **`expect`** scripts against legacy systems use `\\x1b[5i` … `\\x1b[4i` as a 'capture this block' marker because almost no modern emulator implements the divert, so the bytes are emitted to the screen and visible to expect's pattern matcher.\n\n**Coverage** is mostly **no-op** today: **xterm** + **mlterm** = full (gated on `printerCommand` resource). **Konsole** = partial (parses, no-op without explicit printer support). **Linux console** = partial (`5i` / `4i` work if `lp` daemon attached). **WezTerm** + **Kitty** + **Alacritty** + **iTerm2** + **gnome-terminal** + **Ghostty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** = silent no-op (the bytes pass through the parser without effect). Do not rely on the divert outside the xterm + mlterm + 3270 path.",
        "zh": "**Media Copy**（MC）是 ECMA-48 把终端输出分流到次级流的机制 —— 历史上是所连的行式打印机或串口纸式打印机。标准参数：\n- `\\x1b[0i`（或单写 `\\x1b[i`）—— **打印当前页**。把当前屏内容作为一次性向打印机发送，由终端处理分页（换页、页尾）。xterm 通过 X 资源 `printerCommand` 指定的程序（通常是 `lpr`）执行。\n- `\\x1b[1i` —— **打印当前行**。`0i` 的单行版。\n- `\\x1b[4i` —— **关闭打印**（Media Copy 'deselect'）。停止 `5i` 启动的流分发。其后输出仅去屏幕。\n- `\\x1b[5i` —— **开启打印**（Media Copy 'select'）。开始把后续所有终端输出分发到打印机，直至匹配的 `4i`。常称*透明打印模式*。此期间屏幕无输出。\n\n**DEC 私有前缀变体**（`\\x1b[?Ps i`）：\n- `\\x1b[?1i` —— 打印光标所在行（单行，无换页）。\n- `\\x1b[?4i` —— 关 **自动打印**。\n- `\\x1b[?5i` —— 开 **自动打印**。每当光标越过右边距或 `\\n` 触发换行时，该行也被发到打印机。\n- `\\x1b[?10i` / `\\x1b[?11i` —— 打印合成显示（VT300+）；打印所有字符包括收到的控制。\n\n**2026 年为什么仍要紧**\n- **IBM 3270 / 5250 模拟器栈**（`x3270`、`wc3270`、`tn5270`）让 MC 透过宿主应用到达真实或虚拟 `LPT` 设备。老旧主机批处理仍预期 `\\x1b[5i…\\x1b[4i` 包裹打印数据。\n- **xterm** + **mlterm** 在 X 资源设置了 `printerCommand` 时尊重 `0i` 与 `5i`/`4i` —— 现代等价为 `printerCommand: cat > /tmp/xterm.dump`。可用作屏幕捕获 / 调试而无需 `tmux capture-pane`。\n- **`expect`** 对老系统跑脚本时用 `\\x1b[5i` … `\\x1b[4i` 作「捕获此块」标记，因为几乎没现代模拟器实现分发，字节会原样送到屏幕、被 expect 的模式匹配器看到。\n\n**覆盖度**今日多为**静默**：**xterm** + **mlterm** = 完整（受 `printerCommand` 资源约束）。**Konsole** = 部分（解析，未显式接打印机时静默）。**Linux console** = 部分（连了 `lp` 守护时 `5i` / `4i` 工作）。**WezTerm** + **Kitty** + **Alacritty** + **iTerm2** + **gnome-terminal** + **Ghostty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** = 静默（字节穿过解析器不生效）。除了 xterm + mlterm + 3270 路径外，不要依赖分发。"
      },
      "parameters": [
        {
          "name": "Ps = 0",
          "desc": {
            "en": "Print page — send current screen to printer (one-shot, with form-feed).",
            "zh": "打印当前页 —— 把当前屏发到打印机（一次性，含换页）。"
          }
        },
        {
          "name": "Ps = 1",
          "desc": {
            "en": "Print line — single-line variant.",
            "zh": "打印当前行 —— 单行变体。"
          }
        },
        {
          "name": "Ps = 4",
          "desc": {
            "en": "Printer-off (deselect Media Copy stream).",
            "zh": "关闭打印（取消选择 Media Copy 流）。"
          }
        },
        {
          "name": "Ps = 5",
          "desc": {
            "en": "Printer-on (select Media Copy stream — transparent print mode).",
            "zh": "开启打印（选择 Media Copy 流 —— 透明打印模式）。"
          }
        },
        {
          "name": "? Ps = 1",
          "desc": {
            "en": "Print cursor line (DEC, single-line, no form-feed).",
            "zh": "打印光标所在行（DEC，单行，无换页）。"
          }
        },
        {
          "name": "? Ps = 4 / 5",
          "desc": {
            "en": "Auto-print off / on — each cursor line-wrap also goes to printer.",
            "zh": "自动打印 关 / 开 —— 每次光标换行也送给打印机。"
          }
        }
      ],
      "spec": "ECMA-48 §8.3.82 (MC) / xterm-ctlseqs (CSI Ps i, CSI ? Ps i)",
      "examples": [
        {
          "lang": "bash",
          "code": "# xterm with printerCommand='cat > /tmp/screen.dump' — capture current screen.\\nprintf '\\\\033[0i'\\n# Bracketed print: every byte between 5i and 4i goes to the printer.\\nprintf '\\\\033[5i'; cat report.txt; printf '\\\\033[4i'"
        },
        {
          "lang": "python",
          "code": "import sys\\n# expect-style capture marker — emits visible bytes on non-xterm.\\nsys.stdout.write('\\\\x1b[5i')\\nsys.stdout.flush()\\n# (expect script greps for the literal bytes; xterm diverts them silently)"
        },
        {
          "lang": "go",
          "code": "// Auto-print every line as it scrolls (DEC private).\\nfmt.Print(\\\"\\\\x1b[?5i\\\")     // auto-print on\\ndefer fmt.Print(\\\"\\\\x1b[?4i\\\")  // auto-print off on exit"
        },
        {
          "lang": "javascript",
          "code": "// 3270 emulator print envelope around report data.\\nprocess.stdout.write('\\\\x1b[5i' + reportData + '\\\\x1b[4i');"
        },
        {
          "lang": "c",
          "code": "/* Print cursor line, no form-feed. */\\nprintf(\\\"\\\\x1b[?1i\\\");\\nfflush(stdout);"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "partial",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "no",
        "ghostty": "no",
        "gnometerm": "no",
        "konsole": "partial"
      },
      "related": [
        "csi-da",
        "decrqm",
        "c1-controls"
      ]
    },
    {
      "slug": "sgr-superscript-subscript",
      "family": "SGR",
      "title": {
        "en": "SGR 73 / 74 / 75 — Superscript / Subscript / Neither",
        "zh": "SGR 73 / 74 / 75 —— 上标 / 下标 / 取消"
      },
      "shortDesc": {
        "en": "Mintty's superscript / subscript SGR pair, now shipped by Kitty 0.32+, WezTerm, foot, and iTerm2. The first SGR attribute that lets terminal output typeset math, footnotes, and chemical formulae without trick characters.",
        "zh": "Mintty 的上标 / 下标 SGR 对，现已被 Kitty 0.32+、WezTerm、foot 与 iTerm2 实现。是终端输出能不靠特殊字符排出数学、脚注与化学式的第一组 SGR。"
      },
      "bytes": {
        "canonical": "\\x1b[73m   superscript    \\x1b[74m   subscript    \\x1b[75m   neither",
        "octal": "\\033[73m   /   \\033[74m   /   \\033[75m",
        "eEscape": "\\e[73m   /   \\e[74m   /   \\e[75m",
        "literal": "ESC [ 73 m   /   ESC [ 74 m   /   ESC [ 75 m",
        "hex": "1b 5b 37 33 6d   /   1b 5b 37 34 6d   /   1b 5b 37 35 6d"
      },
      "description": {
        "en": "Three SGR codes outside the historical ECMA-48 vocabulary (which stops at SGR 65) that **mintty** introduced ~2017 and that **Kitty 0.32+**, **WezTerm 20240128+**, **foot 1.16+**, **iTerm2 3.5+** picked up afterwards. They are the *attribute* counterpart to the Unicode superscript / subscript blocks (U+2070–U+209F) — instead of substituting alternative glyphs, the terminal renders the **current** glyphs at smaller scale and raised / lowered baseline.\n\n**Codes**\n- `\\x1b[73m` — **superscript**. Following characters render at ~75% size, baseline raised to roughly the cap-height line.\n- `\\x1b[74m` — **subscript**. Following characters render at ~75% size, baseline lowered.\n- `\\x1b[75m` — **neither**. Cancel both. Distinct from `\\x1b[0m` (which also cancels every other attribute).\n\n**Why this matters**\n- *Math output* — write `H₂O` as `H\\x1b[74m2\\x1b[75mO` rather than `H\\u2082O` (the latter only works if your output font has the subscript codepoints, many monospaced fonts don't).\n- *Footnotes* — render `text¹` from `text\\x1b[73m1\\x1b[75m` and remain searchable / copy-pasteable as plain digits.\n- *Chemistry / units* — `m²`, `m³`, `kg·m·s⁻¹` all render in monospace without font-substitution gymnastics.\n- *Diff output* — `git --color-words` and similar tools can use sub/super to mark insertion / deletion positions without disturbing the source line.\n\n**Constraints**\n- The attributes are **mutually exclusive** in spec: emitting `\\x1b[73m` while subscript is active should toggle to superscript, not stack. Real emulators implement this correctly (last one wins).\n- **No nesting** — there is no SGR for 'super-superscript'. Terminals fall back to single-level rendering.\n- **Copy / paste preserves the codepoints** as written, not the rendered glyph — so `H\\x1b[74m2\\x1b[75mO` round-trips back to `H2O` (with the escape codes stripped by clipboard). This is *correct* for plain-text round-trips but means you can't rely on visual super/sub to communicate semantic super/sub to downstream tools that don't honour SGR — use Unicode for that.\n- **Width math** — subscript / superscript characters still occupy 1 cell width on the grid; the smaller glyphs don't change column alignment. This is important for TUI layout: a labelled axis like `10²` is still 3 cells wide.\n\n**Coverage**: **Kitty** (≥ 0.32) + **WezTerm** (≥ 20240128) + **foot** (≥ 1.16) + **iTerm2** (≥ 3.5) + **mintty** (≥ 3.4) = full. **Ghostty** = full (since 1.0). **xterm** = partial (`patch #383+`, only with `cjkWidth: true`; off otherwise). **gnome-terminal** + **Konsole** + **Alacritty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** + **Linux console** = silently consumed (the SGR is parsed but the renderer paints normal-size baseline glyphs). Reset (`\\x1b[0m`) cancels both attributes everywhere.",
        "zh": "三个超出历史 ECMA-48 词汇（止于 SGR 65）的 SGR 码，由 **mintty** 在 2017 年前后引入，**Kitty 0.32+**、**WezTerm 20240128+**、**foot 1.16+**、**iTerm2 3.5+** 后续跟进。它们是 Unicode 上标 / 下标块（U+2070–U+209F）的*属性*对偶 —— 不替换字模，而让终端把*当前*字模以更小尺寸、抬升 / 下沉的基线渲染。\n\n**编码**\n- `\\x1b[73m` —— **上标**。后续字符以约 75% 尺寸、基线大致抬至 cap-height 行渲染。\n- `\\x1b[74m` —— **下标**。后续字符以约 75% 尺寸、基线下沉渲染。\n- `\\x1b[75m` —— **取消**。同时关闭上下标。与 `\\x1b[0m`（同时清掉所有其他属性）不同。\n\n**为何要紧**\n- *数学输出* —— `H₂O` 写作 `H\\x1b[74m2\\x1b[75mO`，而不是 `H\\u2082O`（后者只在输出字体含下标码点时奏效，许多等宽字体没有）。\n- *脚注* —— `text¹` 用 `text\\x1b[73m1\\x1b[75m` 渲染，且作为普通数字仍可搜索 / 复制粘贴。\n- *化学 / 单位* —— `m²`、`m³`、`kg·m·s⁻¹` 都能在等宽下渲染而无需字形替换。\n- *Diff 输出* —— `git --color-words` 等工具可用上下标标记插入 / 删除位置，不扰动源行。\n\n**约束**\n- 属性按规范**互斥**：在下标激活时发 `\\x1b[73m` 应切换到上标而非堆叠。实际模拟器实现正确（最后一个赢）。\n- **不可嵌套** —— 没有「上上标」的 SGR。终端回落为单层渲染。\n- **复制 / 粘贴保留写入的码点**，不是渲染后的字模 —— 因此 `H\\x1b[74m2\\x1b[75mO` 往返回到 `H2O`（剪贴板会剥掉转义）。这是平文本往返的正确行为，但意味着不能依赖视觉上的上下标向不识别 SGR 的下游工具传达语义上下标 —— 用 Unicode 做那件事。\n- **宽度** —— 上下标字符仍占网格 1 列宽；更小的字模不改列对齐。这对 TUI 布局很要紧：`10²` 这种标注仍是 3 单元宽。\n\n**覆盖度**：**Kitty**（≥ 0.32）+ **WezTerm**（≥ 20240128）+ **foot**（≥ 1.16）+ **iTerm2**（≥ 3.5）+ **mintty**（≥ 3.4）= 完整。**Ghostty** = 完整（自 1.0 起）。**xterm** = 部分（`patch #383+`，仅在 `cjkWidth: true` 时；否则关闭）。**gnome-terminal** + **Konsole** + **Alacritty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** + **Linux console** = 静默吞掉（SGR 被解析，但渲染器仍以正常尺寸基线绘制）。Reset（`\\x1b[0m`）在任何地方都关闭这两个属性。"
      },
      "parameters": [
        {
          "name": "73",
          "desc": {
            "en": "Superscript on.",
            "zh": "上标开。"
          }
        },
        {
          "name": "74",
          "desc": {
            "en": "Subscript on.",
            "zh": "下标开。"
          }
        },
        {
          "name": "75",
          "desc": {
            "en": "Cancel super- and subscript (does not touch other SGR attributes).",
            "zh": "取消上下标（不动其他 SGR 属性）。"
          }
        }
      ],
      "spec": "mintty / Kitty terminal-graphics-protocol superscript-extension / xterm-ctlseqs patch #383",
      "examples": [
        {
          "lang": "bash",
          "code": "# Write 'H2O' with the 2 as subscript.\\nprintf 'H\\\\033[74m2\\\\033[75mO\\\\n'\\n# Cite 'foo^1' with footnote marker.\\nprintf 'see foo\\\\033[73m1\\\\033[75m for context.\\\\n'"
        },
        {
          "lang": "python",
          "code": "import sys\\nsys.stdout.write('Area: 10\\\\x1b[73m2\\\\x1b[75m m\\\\x1b[73m2\\\\x1b[75m\\\\n')   # 10² m²"
        },
        {
          "lang": "go",
          "code": "// Render a sequence: x¹, x², x³ in monospace via SGR rather than Unicode.\\nfor _, n := range []int{1, 2, 3} {\\n    fmt.Printf(\\\"x\\\\x1b[73m%d\\\\x1b[75m \\\", n)\\n}\\nfmt.Println()"
        },
        {
          "lang": "javascript",
          "code": "// Footnote marker that copy-pastes as plain digit.\\nprocess.stdout.write('see ref' + '\\\\x1b[73m' + idx + '\\\\x1b[75m\\\\n');"
        },
        {
          "lang": "c",
          "code": "/* Chemical formula with subscripts. */\\nprintf(\\\"C\\\\x1b[74m6\\\\x1b[75mH\\\\x1b[74m12\\\\x1b[75mO\\\\x1b[74m6\\\\x1b[75m\\\\n\\\");"
        }
      ],
      "support": {
        "xterm": "partial",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "yes",
        "wt": "no",
        "cmd": "no",
        "kitty": "yes",
        "alacritty": "no",
        "wezterm": "yes",
        "ghostty": "yes",
        "gnometerm": "no",
        "konsole": "no"
      },
      "related": [
        "sgr-italic",
        "sgr-bold",
        "sgr-reset",
        "sgr-fg-truecolor"
      ]
    },
    {
      "slug": "decrqde-decrpde",
      "family": "CSI",
      "title": {
        "en": "DECRQDE / DECRPDE — Request / Report Displayed Extent (`CSI \" v` / `\" w`)",
        "zh": "DECRQDE / DECRPDE —— 请求 / 回报显示区范围（`CSI \" v` / `\" w`）"
      },
      "shortDesc": {
        "en": "VT420+ pagination query — ask the terminal how many rows / columns are currently displayed and where the scroll window sits inside the page memory. Reply tells the host the visible viewport without relying on `tput lines / cols`.",
        "zh": "VT420+ 的分页查询 —— 询问终端当前显示多少行 / 列，以及滚动窗口在页内存中的位置。让主机不必依赖 `tput lines / cols` 就能得知可视视口。"
      },
      "bytes": {
        "canonical": "\\x1b[\"v                              DECRQDE (request)\\n\\x1b[<Ph>;<Pw>;<Pml>;<Pmt>;<Pmp>\"w   DECRPDE (reply)",
        "octal": "\\033[\"v   /   \\033[<Ph>;<Pw>;<Pml>;<Pmt>;<Pmp>\"w",
        "eEscape": "\\e[\"v   /   \\e[<Ph>;<Pw>;<Pml>;<Pmt>;<Pmp>\"w",
        "literal": "ESC [ \" v   /   ESC [ Ph ; Pw ; Pml ; Pmt ; Pmp \" w",
        "hex": "1b 5b 22 76   /   1b 5b … 22 77"
      },
      "description": {
        "en": "**DECRQDE** (*Request Displayed Extent*, `\\x1b[\"v`) asks the terminal to describe the *visible viewport into its page memory*. The reply (**DECRPDE**, `\\x1b[Ph;Pw;Pml;Pmt;Pmp\"w`) carries five numbers:\n- **Ph** — number of rows visible in the viewport (almost always the terminal height).\n- **Pw** — number of columns visible (almost always the terminal width).\n- **Pml** — left margin column within the page (1-indexed; the leftmost column of the viewport relative to the page memory).\n- **Pmt** — top row of the viewport within the page memory (1-indexed; usually `1` unless the page is taller than the screen and scrolled).\n- **Pmp** — page number of the active page (1 on every single-page emulator; only meaningful on DEC VT525 with multi-page memory).\n\n**Why a separate query exists**: on classic DEC VT420/VT525 hardware, *page memory* could be larger than the screen — the terminal owned, say, 480 rows of buffer but only displayed 24 at a time, and the host needed to know what slice was on screen without redrawing. The query is the round-trip companion to **DECSCPP** (set columns-per-page) and **DECSLPP** (set lines-per-page) — host sets the geometry, terminal acknowledges via DECRPDE.\n\n**Modern usage**: in 2026, almost every emulator has a single page == single viewport == single screen-size buffer, so the reply is degenerate — `Ph` matches `LINES`, `Pw` matches `COLUMNS`, `Pml`/`Pmt`/`Pmp` are `1`. The *useful* role today is as a **feature probe**: terminals that reply at all are advertising VT420-class compatibility, which strongly correlates with support for DECRQTSR / DECRSTS, DECCARA, and the rectangle ops family. Programs that need to gate on 'real VT420 lineage' send `\\x1b[\"v` and treat any reply as 'go'.\n\n**Reading the reply safely**\n- Emit `\\x1b[\"v` to stdout.\n- Read from stdin with a 50–150 ms timeout. On no-reply terminals (most modern emulators), the timeout fires and you assume *no VT420 support*.\n- Parse `\\x1b\\[([0-9]+);([0-9]+);([0-9]+);([0-9]+);([0-9]+)\"w` — anchored on the leading CSI and the final `\"w` to avoid mis-framing on slow connections that interleave with user input.\n- **Critical**: terminals can prepend or append other reports if multiple queries are in flight — match the `\"w` final byte, not position.\n\n**Coverage**: **xterm** = full (reference implementation). **mlterm** + **Konsole** + **gnome-terminal** = full. **WezTerm** = partial (replies, but `Pmt` always `1` regardless of actual scroll). **iTerm2** = no-op (silently consumed). **Kitty** + **Alacritty** + **Ghostty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** + **Linux console** = no-op. The query is safe to emit unconditionally — non-replying terminals ignore the bytes; replying ones produce 5 small decimal fields parseable in < 30 bytes.",
        "zh": "**DECRQDE**（*请求显示区范围*，`\\x1b[\"v`）让终端描述*它对页内存的可视视口*。回复（**DECRPDE**，`\\x1b[Ph;Pw;Pml;Pmt;Pmp\"w`）携五个数：\n- **Ph** —— 视口可见行数（几乎总等于终端高度）。\n- **Pw** —— 视口可见列数（几乎总等于终端宽度）。\n- **Pml** —— 视口在页内的左列（1 起算；视口最左列相对页内存的位置）。\n- **Pmt** —— 视口在页内存中的顶行（1 起算；通常为 `1`，除非页比屏幕高且已滚动）。\n- **Pmp** —— 当前活动页号（在所有单页模拟器上为 1；只在有多页内存的 DEC VT525 上才有意义）。\n\n**为何需要单独的查询**：在经典 DEC VT420/VT525 硬件上，*页内存*可能比屏幕大 —— 终端持有例如 480 行缓冲，仅显示其中 24 行，主机要在不重绘的情况下得知屏上是哪片。它是 **DECSCPP**（设每页列数）与 **DECSLPP**（设每页行数）的往返伙伴 —— 主机设几何，终端经 DECRPDE 回执。\n\n**现代用法**：2026 年几乎所有模拟器都是单页 == 单视口 == 单屏大小缓冲，回复退化为 —— `Ph` 等于 `LINES`、`Pw` 等于 `COLUMNS`、`Pml`/`Pmt`/`Pmp` 皆为 `1`。今日*有用*的角色是作**特性探测**：会回报的终端宣称 VT420 级兼容，强相关于支持 DECRQTSR / DECRSTS、DECCARA、矩形操作族。要门控「真 VT420 血统」的程序发 `\\x1b[\"v`，把任意回复视作「可走」。\n\n**安全读取回复**\n- 向 stdout 发 `\\x1b[\"v`。\n- 以 50–150 ms 超时从 stdin 读。对不回复的终端（多数现代模拟器），超时触发后认为*无 VT420 支持*。\n- 解析 `\\x1b\\[([0-9]+);([0-9]+);([0-9]+);([0-9]+);([0-9]+)\"w` —— 锚定开头 CSI 与末尾 `\"w`，避免在多查询并行的慢连接上错框。\n- **要点**：若多个查询并行飞行，终端可能前后串其他回报 —— 匹配 `\"w` 末字节，而非位置。\n\n**覆盖度**：**xterm** = 完整（基准实现）。**mlterm** + **Konsole** + **gnome-terminal** = 完整。**WezTerm** = 部分（会回，但不管实际滚动 `Pmt` 永远 `1`）。**iTerm2** = 静默。**Kitty** + **Alacritty** + **Ghostty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** + **Linux console** = 静默。该查询可无条件发 —— 不回的终端忽略字节；会回的产出 5 个小十进制字段，30 字节内可解析。"
      },
      "parameters": [
        {
          "name": "Ph",
          "desc": {
            "en": "Reply field: rows visible in the viewport.",
            "zh": "回复字段：视口可见行数。"
          }
        },
        {
          "name": "Pw",
          "desc": {
            "en": "Reply field: columns visible in the viewport.",
            "zh": "回复字段：视口可见列数。"
          }
        },
        {
          "name": "Pml",
          "desc": {
            "en": "Reply field: leftmost column of the viewport within page memory (1-indexed).",
            "zh": "回复字段：视口在页内存中的最左列（1 起算）。"
          }
        },
        {
          "name": "Pmt",
          "desc": {
            "en": "Reply field: top row of the viewport within page memory (1-indexed).",
            "zh": "回复字段：视口在页内存中的顶行（1 起算）。"
          }
        },
        {
          "name": "Pmp",
          "desc": {
            "en": "Reply field: active page number (1 on single-page emulators).",
            "zh": "回复字段：当前活动页号（单页模拟器上为 1）。"
          }
        }
      ],
      "spec": "DEC VT420 / VT525 RM (DECRQDE / DECRPDE) / xterm-ctlseqs (CSI \" v / \" w)",
      "examples": [
        {
          "lang": "bash",
          "code": "# Probe DECRQDE with a 100 ms read timeout.\\nprintf '\\\\033[\"v'\\nIFS= read -rs -d 'w' -t 0.1 reply </dev/tty 2>/dev/null\\necho \\\"extent reply: ${reply}w\\\"   # e.g. \\\\x1b[24;80;1;1;1\\\"w"
        },
        {
          "lang": "python",
          "code": "import sys, re, select\\nsys.stdout.write('\\\\x1b[\"v')\\nsys.stdout.flush()\\nif select.select([sys.stdin], [], [], 0.1)[0]:\\n    reply = sys.stdin.buffer.read1(64)\\n    m = re.search(rb'\\\\x1b\\\\[(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+)\\\"w', reply)\\n    if m:\\n        h, w, ml, mt, mp = (int(x) for x in m.groups())\\n        print(f'viewport: {h}x{w}, page-offset ({mt},{ml}), page {mp}')"
        },
        {
          "lang": "go",
          "code": "// Feature-probe — treat any DECRPDE reply as 'VT420-class emulator'.\\nimport (\\n    \\\"fmt\\\"\\n    \\\"os\\\"\\n)\\nfmt.Fprint(os.Stdout, \\\"\\\\x1b[\\\\\\\"v\\\")\\n// Read with timeout (omitted); a non-empty reply => assume VT420 features."
        },
        {
          "lang": "javascript",
          "code": "// Trigger DECRQDE, log any reply.\\nprocess.stdout.write('\\\\x1b[\\\"v');\\nprocess.stdin.once('readable', () => {\\n  const m = /\\\\x1b\\\\[(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+);(\\\\d+)\\\"w/.exec(process.stdin.read()?.toString('binary') ?? '');\\n  if (m) console.error('extent:', m.slice(1));\\n});"
        },
        {
          "lang": "c",
          "code": "/* Send DECRQDE; the host expects DECRPDE within ~100 ms or gives up. */\\nfputs(\\\"\\\\x1b[\\\\\\\"v\\\", stdout);\\nfflush(stdout);\\n/* Then poll stdin with select() and scanf the 5 decimal fields. */"
        }
      ],
      "support": {
        "xterm": "yes",
        "linuxconsole": "no",
        "macterm": "no",
        "iterm2": "no",
        "wt": "no",
        "cmd": "no",
        "kitty": "no",
        "alacritty": "no",
        "wezterm": "partial",
        "ghostty": "no",
        "gnometerm": "yes",
        "konsole": "yes"
      },
      "related": [
        "decscpp",
        "decstbm",
        "decslrm",
        "csi-dsr",
        "decrqtsr-decrsts"
      ]
    }
  ]
}