fix(terminal): bound cached contrast color pairs

This commit is contained in:
m4air
2026-09-18 20:04:54 -07:00
committed by Neil
parent 2038376d8e
commit 7d04d02f84
9 changed files with 2461 additions and 38 deletions
File diff suppressed because one or more lines are too long
@@ -1,3 +1,50 @@
diff --git a/src/browser/ColorContrastCache.ts b/src/browser/ColorContrastCache.ts
index fdcd9d133199a6cd6ba9bea9606a02c03ad03b3d..0558a8873f680e8fb2a27cc833c49c5ba658e1dd 100644
--- a/src/browser/ColorContrastCache.ts
+++ b/src/browser/ColorContrastCache.ts
@@ -7,11 +7,17 @@ import { IColorContrastCache } from './Types';
import { IColor } from '../common/Types';
import { TwoKeyMap } from '../common/MultiKeyMap';
+const CONTRAST_CACHE_MAX_ENTRIES = 4096;
+
export class ColorContrastCache implements IColorContrastCache {
private _color: TwoKeyMap</* bg */number, /* fg */number, IColor | null> = new TwoKeyMap();
private _css: TwoKeyMap</* bg */number, /* fg */number, string | null> = new TwoKeyMap();
+ private _entryCount = 0;
public setCss(bg: number, fg: number, value: string | null): void {
+ if (this._css.get(bg, fg) === undefined) {
+ this._admitNewEntry();
+ }
this._css.set(bg, fg, value);
}
@@ -20,6 +26,9 @@ export class ColorContrastCache implements IColorContrastCache {
}
public setColor(bg: number, fg: number, value: IColor | null): void {
+ if (this._color.get(bg, fg) === undefined) {
+ this._admitNewEntry();
+ }
this._color.set(bg, fg, value);
}
@@ -30,5 +39,14 @@ export class ColorContrastCache implements IColorContrastCache {
public clear(): void {
this._color.clear();
this._css.clear();
+ this._entryCount = 0;
+ }
+
+ private _admitNewEntry(): void {
+ // Color pairs outlive atlas pages, including cached misses and DOM-rendered colors.
+ if (this._entryCount >= CONTRAST_CACHE_MAX_ENTRIES) {
+ this.clear();
+ }
+ this._entryCount++;
}
}
diff --git a/src/browser/CoreBrowserTerminal.ts b/src/browser/CoreBrowserTerminal.ts
index 67893b7966eb095db4459b8837de9766921f36c5..0abf7ecac1aa108f7caf711d0a5c610a688d34fd 100644
--- a/src/browser/CoreBrowserTerminal.ts
@@ -0,0 +1,66 @@
import { createRequire } from 'node:module'
import { dirname, join } from 'node:path'
import { build } from 'esbuild'
import { beforeAll, describe, expect, it } from 'vitest'
const require = createRequire(import.meta.url)
let ColorContrastCache
beforeAll(async () => {
const root = dirname(require.resolve('@xterm/xterm/package.json'))
const result = await build({
entryPoints: [join(root, 'src/browser/ColorContrastCache.ts')],
bundle: true,
platform: 'node',
format: 'esm',
write: false
})
;({ ColorContrastCache } = await import(
`data:text/javascript;base64,${Buffer.from(result.outputFiles[0].text).toString('base64')}`
))
})
describe('vendored xterm contrast cache', () => {
it('retains cached nulls and updates existing entries without spending capacity', () => {
const cache = new ColorContrastCache()
for (let index = 0; index < 4096; index++) {
cache.setColor(0, index, null)
}
const corrected = { css: '#ffffff', rgba: 0xffffffff }
for (let index = 0; index < 10000; index++) {
cache.setColor(0, 4095, corrected)
}
expect(cache.getColor(0, 0)).toBeNull()
expect(cache.getColor(0, 4095)).toBe(corrected)
})
it('bounds the combined color and CSS cache across distinct backgrounds', () => {
const cache = new ColorContrastCache()
for (let index = 0; index < 2048; index++) {
cache.setColor(index, 0, null)
cache.setCss(index, 1, '#ffffff')
}
expect(cache.getColor(0, 0)).toBeNull()
expect(cache.getCss(0, 1)).toBe('#ffffff')
cache.setCss(2048, 1, '#eeeeee')
expect(cache.getColor(0, 0)).toBeUndefined()
expect(cache.getCss(0, 1)).toBeUndefined()
expect(cache.getCss(2048, 1)).toBe('#eeeeee')
})
it('resets capacity after a theme clear and preserves independent terminal caches', () => {
const cache = new ColorContrastCache()
const sibling = new ColorContrastCache()
sibling.setColor(0, 0, null)
cache.setCss(0, 0, null)
cache.clear()
for (let index = 0; index < 4096; index++) {
cache.setColor(0, index, null)
}
expect(cache.getColor(0, 0)).toBeNull()
expect(cache.getCss(0, 0)).toBeUndefined()
cache.setColor(0, 4096, null)
expect(cache.getColor(0, 0)).toBeUndefined()
expect(sibling.getColor(0, 0)).toBeNull()
})
})
@@ -0,0 +1,70 @@
# Terminal contrast-color cache retention
Xterm memoizes foreground/background contrast corrections in two caches: ordinary
and dim text. Distinct true-color pairs grow these caches even when the result is
`null` (no correction needed). Texture-page eviction does not clear them. Orca
normally enables contrast correction, so this is separate from the invisible
glyph cache fixed in #20965.
Each `ColorContrastCache` now admits at most 4,096 entries across its color and
CSS maps. Inserting another distinct key clears that cache; replacing a key does
not consume capacity. The normal and dim caches remain independent. Evicted
colors are recalculated by the unchanged correction function. Theme settings,
terminal output, and transport behavior do not change.
## Reproduce
```sh
ORCA_BACKGROUND_LAUNCH=1 node docs/audits/terminal-contrast-cache-retention/reproduce.mjs
ORCA_BACKGROUND_LAUNCH=1 node docs/audits/terminal-contrast-cache-retention/reproduce-dom.mjs
```
Both scripts exercise the installed CJS and ESM bundles in headless Chromium.
`ORCA_AUDIT_XTERM_BASELINE` can point to a pre-fix CJS bundle to add before runs.
The WebGL script also accepts `ORCA_AUDIT_WEBGL_BUNDLE`. Captured results use the
older WebGL bundle without #20965, clearing its atlas every 1,000 updates to
isolate contrast storage from glyph storage. Thus this fix and reproduction do
not depend on the other open PR. SHA-256 hashes are in the results files.
The WebGL test performs 100,000 colored-space redraws with two terminals sharing
one atlas. One visible glyph uses a low-contrast color that requires correction.
Normal and dim runs preserve both terminals' first-cell pixel hashes and the
corrected glyph's pixels, including after clearing and recalculating its color.
CDP collects garbage before measuring the JavaScript heap; no heap snapshots or
Orca application windows are used.
| Bundle | Mode | Final contrast entries | Heap growth |
| ---------- | ------ | ---------------------: | --------------: |
| Before CJS | Normal | 100,002 | 5,487,228 bytes |
| Before CJS | Dim | 100,001 | 4,023,452 bytes |
| After CJS | Normal | 1,746 | 291,796 bytes |
| After CJS | Dim | 1,721 | 316,176 bytes |
| After ESM | Normal | 1,746 | 408,652 bytes |
| After ESM | Dim | 1,721 | 436,188 bytes |
All fixed samples stay within the 4,096-entry limit per cache. The DOM test adds
10,000 redraws per case for dark/light backgrounds and normal/dim text. It checks
that an evicted color, and a color recalculated after explicit cache clearing,
produce the same computed CSS color and rendered row HTML as before.
All 12 DOM cases pass across the baseline and both fixed module formats; samples
reach the exact 4,096-entry cap. Every page and browser is closed after the run.
## Validation and limits
- 122 tests pass across cache, regeneration, contrast, appearance, IME, and
renderer suites. Two cache regressions fail against the previous source.
- The authoritative source patch, generated CJS/ESM bundles and source maps, and
lockfile hashes were regenerated together. Frozen install and the pinned
regeneration `--check` pass.
- Full desktop typecheck, formatting/lint, and changed-code quality pass.
- Captured browser: Chromium 147.0.7727.15 on macOS. Heap measurements include
GC/allocator variation and other terminal state.
- This is a desktop renderer fix. Mobile resolves its own unpatched xterm package
when generating its WebView engine; that separate bundle is not fixed here.
- `v1.4.198` shipped the same xterm version and automatic 3/4.5 contrast settings.
Its appearance path also skipped unchanged theme/ratio assignments, so ordinary
reapplication did not periodically clear the cache. User contrast overrides were
added later; their current behavior is unchanged.
- Revisited evicted pairs incur the existing contrast calculation again. No
incident report establishes the distinct-color traffic used in this proof;
renderer retention does not explain #19768's separately measured main PID.
@@ -0,0 +1,223 @@
import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
import { chromium } from 'playwright'
if (process.env.ORCA_BACKGROUND_LAUNCH !== '1') {
throw new Error('Run with ORCA_BACKGROUND_LAUNCH=1')
}
const installed = resolve('node_modules/@xterm/xterm/lib/xterm.js')
const bundles = [
['after', installed],
['after', installed.replace(/\.js$/, '.mjs')]
]
if (process.env.ORCA_AUDIT_XTERM_BASELINE) {
bundles.unshift(['before', resolve(process.env.ORCA_AUDIT_XTERM_BASELINE)])
}
const browser = await chromium.launch({
executablePath: process.env.ORCA_AUDIT_CHROMIUM,
headless: true
})
const browserVersion = browser.version()
const results = []
const referenceColors = new Map()
let pagesOpened = 0
let pagesClosed = 0
try {
for (const [phase, bundle] of bundles) {
const source = await readFile(bundle, 'utf8')
const sha256 = createHash('sha256').update(source).digest('hex')
for (const theme of ['dark', 'light']) {
for (const mode of ['normal', 'dim']) {
const page = await browser.newPage()
pagesOpened++
try {
await page.setContent('<div id="terminal"></div>')
await page.addStyleTag({ path: resolve('node_modules/@xterm/xterm/css/xterm.css') })
await (bundle.endsWith('.mjs')
? page.evaluate(
async (url) => {
window.Terminal = (await import(url)).Terminal
},
`data:text/javascript;base64,${Buffer.from(source).toString('base64')}`
)
: page.addScriptTag({ path: bundle }))
const initial = await page.evaluate(
async ({ theme, mode }) => {
const terminal = new Terminal({
minimumContrastRatio: theme === 'dark' ? 3 : 4.5,
theme:
theme === 'dark'
? { background: '#000000', foreground: '#ffffff' }
: { background: '#ffffff', foreground: '#000000' },
cols: 4,
rows: 1,
scrollback: 0,
allowProposedApi: true,
logLevel: 'off'
})
terminal.open(document.getElementById('terminal'))
await new Promise(requestAnimationFrame)
const renderer = terminal._core._renderService._renderer.value
const colors = terminal._core._themeService.colors
const probe = theme === 'dark' ? [5, 50, 25] : [245, 250, 240]
const probeRgba = ((probe[0] << 24) | (probe[1] << 16) | (probe[2] << 8) | 255) >>> 0
const draw = (rgb) => {
terminal._core.writeSync(
`\x1b[?25l\x1b[H\x1b[${mode === 'dim' ? 2 : 22}m\x1b[38;2;${rgb.join(';')}mM`
)
renderer.renderRows(0, 0)
}
const count = (cache) =>
Object.values(cache._color._data).reduce(
(sum, row) => sum + Object.keys(row).length,
0
)
const activeCache = () =>
colors[mode === 'dim' ? 'halfContrastCache' : 'contrastCache']
const state = () => ({
contrast: count(colors.contrastCache),
dimContrast: count(colors.halfContrastCache),
probeCached: Object.values(activeCache()._color._data).some((row) =>
Object.hasOwn(row, probeRgba)
)
})
const visible = () => {
const row = terminal.element.querySelector('.xterm-rows > div')
const cell = [...row.querySelectorAll('span')].find(
(span) => span.textContent === 'M'
)
if (!cell) {
throw new Error('Expected rendered probe glyph')
}
return {
color: getComputedStyle(cell).color,
opacity: getComputedStyle(cell).opacity,
html: row.innerHTML,
text: terminal.buffer.active.getLine(0).getCell(0).getChars()
}
}
draw(probe)
window.domContrastAudit = {
terminal,
renderer,
colors,
probe,
draw,
state,
visible,
index: 0
}
return {
minimumContrastRatio: terminal.options.minimumContrastRatio,
rawColor: `rgb(${probe.join(', ')})`,
...visible(),
...state()
}
},
{ theme, mode }
)
assert.equal(initial.text, 'M')
assert.notEqual(
initial.color,
initial.rawColor,
'Probe must exercise contrast correction'
)
assert.equal(initial.probeCached, true)
const samples = []
for (const count of [0, 1000, 4094, 4095, 4096, 5000, 10000]) {
samples.push(
await page.evaluate(
({ count, theme }) => {
const audit = window.domContrastAudit
for (let index = audit.index; index < count; index++) {
const color = theme === 'dark' ? index + 1 : 0xffffff - index
audit.draw([color >> 16, (color >> 8) & 255, color & 255])
}
audit.index = count
return { updates: count, ...audit.state() }
},
{ count, theme }
)
)
}
if (phase === 'after') {
assert.ok(
samples.every((sample) => sample.contrast <= 4096 && sample.dimContrast <= 4096)
)
assert.equal(samples.at(-1).probeCached, false, 'Original color must be evicted')
} else {
assert.ok(samples.at(-1)[mode === 'dim' ? 'dimContrast' : 'contrast'] >= 10000)
assert.equal(samples.at(-1).probeCached, true)
}
const checks = await page.evaluate(() => {
const audit = window.domContrastAudit
audit.draw(audit.probe)
const revisited = { ...audit.visible(), ...audit.state() }
audit.colors.contrastCache.clear()
audit.colors.halfContrastCache.clear()
const cleared = audit.state()
audit.renderer.renderRows(0, 0)
return { revisited, cleared, recomputed: { ...audit.visible(), ...audit.state() } }
})
for (const snapshot of [checks.revisited, checks.recomputed]) {
assert.equal(snapshot.color, initial.color)
assert.equal(snapshot.opacity, initial.opacity)
assert.equal(snapshot.html, initial.html)
assert.equal(snapshot.text, 'M')
assert.equal(snapshot.probeCached, true)
}
assert.equal(checks.cleared.contrast, 0)
assert.equal(checks.cleared.dimContrast, 0)
assert.equal(checks.cleared.probeCached, false)
const key = `${theme}/${mode}`
const visibleColor = { color: initial.color, opacity: initial.opacity }
if (referenceColors.has(key)) {
assert.deepEqual(visibleColor, referenceColors.get(key))
} else {
referenceColors.set(key, visibleColor)
}
results.push({
phase,
format: bundle.endsWith('.mjs') ? 'esm' : 'cjs',
theme,
mode,
sha256,
initial,
samples,
checks
})
} finally {
await page
.evaluate(() => window.domContrastAudit?.terminal.dispose())
.catch(() => undefined)
await page.close()
assert.equal(page.isClosed(), true)
pagesClosed++
}
}
}
}
} finally {
await browser.close()
}
assert.equal(pagesClosed, pagesOpened)
assert.equal(browser.isConnected(), false)
console.log(
JSON.stringify(
{
node: process.version,
browser: browserVersion,
headless: true,
renderer: 'DOM',
pagesOpened,
pagesClosed,
browserClosed: !browser.isConnected(),
results
},
null,
2
)
)
@@ -0,0 +1,211 @@
import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
import { chromium } from 'playwright'
if (process.env.ORCA_BACKGROUND_LAUNCH !== '1') {
throw new Error('Run with ORCA_BACKGROUND_LAUNCH=1')
}
const installed = resolve('node_modules/@xterm/xterm/lib/xterm.js')
const webglBundle = resolve(
process.env.ORCA_AUDIT_WEBGL_BUNDLE ?? 'node_modules/@xterm/addon-webgl/lib/addon-webgl.js'
)
const current = [
['after', installed],
['after', installed.replace(/\.js$/, '.mjs')]
]
const bundles = process.env.ORCA_AUDIT_XTERM_BASELINE
? [['before', resolve(process.env.ORCA_AUDIT_XTERM_BASELINE)], ...current]
: current
const browser = await chromium.launch({
executablePath: process.env.ORCA_AUDIT_CHROMIUM,
headless: true,
args: ['--use-gl=angle', '--use-angle=swiftshader', '--enable-unsafe-swiftshader']
})
const results = []
try {
for (const [phase, bundle] of bundles) {
const sha256 = createHash('sha256')
.update(await readFile(bundle))
.digest('hex')
for (const mode of ['normal', 'dim']) {
const page = await browser.newPage()
try {
await page.setContent('<div id="first"></div><div id="second"></div>')
await page.addStyleTag({ path: resolve('node_modules/@xterm/xterm/css/xterm.css') })
await page.addScriptTag({ path: webglBundle })
if (bundle.endsWith('.mjs')) {
const source = await readFile(bundle, 'utf8')
await page.evaluate(
async (url) => {
window.Terminal = (await import(url)).Terminal
},
`data:text/javascript;base64,${Buffer.from(source).toString('base64')}`
)
} else {
await page.addScriptTag({ path: bundle })
}
await page.evaluate(async (mode) => {
const create = (id, text) => {
const terminal = new Terminal({
minimumContrastRatio: 3,
cols: 4,
rows: 1,
scrollback: 0,
allowProposedApi: true,
logLevel: 'off'
})
terminal.open(document.getElementById(id))
const addon = new WebglAddon.WebglAddon()
terminal.loadAddon(addon)
terminal._core.writeSync(text)
addon._renderer.renderRows(0, 0)
return { terminal, addon }
}
const first = create('first', `A \x1b[${mode === 'dim' ? 2 : 22}m\x1b[38;2;5;50;25mM`)
const second = create('second', 'B')
window.glyphAudit = { first, second, mode, index: 0 }
await new Promise(requestAnimationFrame)
await new Promise(requestIdleCallback)
}, mode)
const cdp = await page.context().newCDPSession(page)
const samples = []
for (const count of [0, 1000, 5000, 10000, 50000, 100000]) {
const state = await page.evaluate((count) => {
const { first, second, mode } = window.glyphAudit
for (let index = window.glyphAudit.index; index < count; index++) {
// Isolate contrast storage even when the older glyph cache has no entry cap.
if (index > 0 && index % 1000 === 0) {
first.addon.clearTextureAtlas()
}
const color = index + 1
first.terminal._core.writeSync(
`\x1b[1;2H\x1b[${mode === 'dim' ? 2 : 22}m\x1b[38;2;${color >> 16};${(color >> 8) & 255};${color & 255}m `
)
first.addon._renderer.renderRows(0, 0)
}
first.addon._renderer.renderRows(0, 0)
second.addon._renderer.renderRows(0, 0)
window.glyphAudit.index = count
const atlas = first.addon._renderer._charAtlas
const entries = (map) => {
let result = 0
for (const second of Object.values(map?._data._data ?? {})) {
for (const inner of Object.values(second)) {
for (const fourth of Object.values(inner._data)) {
result += Object.keys(fourth).length
}
}
}
return result
}
const countColors = (cache) =>
Object.values(cache._color._data).reduce(
(sum, row) => sum + Object.keys(row).length,
0
) +
Object.values(cache._css._data).reduce((sum, row) => sum + Object.keys(row).length, 0)
const pixels = ({ terminal, addon }, cellIndex = 0) => {
const gl = addon._renderer._gl
const width = Math.floor(gl.drawingBufferWidth / terminal.cols)
const height = gl.drawingBufferHeight
const bytes = new Uint8Array(width * height * 4)
gl.readPixels(cellIndex * width, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, bytes)
let hash = 2166136261
for (const byte of bytes) {
hash = Math.imul(hash ^ byte, 16777619)
}
return hash >>> 0
}
window.glyphAudit.pixelHash = pixels
return {
contrastProbePixels: pixels(first, 2),
contrast: countColors(first.terminal._core._themeService.colors.contrastCache),
dimContrast: countColors(first.terminal._core._themeService.colors.halfContrastCache),
updates: count,
firstCellPixels: pixels(first),
secondCellPixels: pixels(second),
regular: entries(atlas._cacheMap),
combined: entries(atlas._cacheMapCombined),
empty: entries(atlas._emptyCacheMap) + entries(atlas._emptyCacheMapCombined),
pages: atlas.pages.length,
glyphs: atlas.pages.reduce((n, page) => n + page.glyphs.length, 0),
layoutVersion: atlas.pageLayoutVersion,
shared: atlas === second.addon._renderer._charAtlas,
preserved:
first.terminal.buffer.active.getLine(0).getCell(0).getChars() === 'A' &&
second.terminal.buffer.active.getLine(0).getCell(0).getChars() === 'B'
}
}, count)
await cdp.send('HeapProfiler.collectGarbage')
samples.push({ ...state, heap: (await cdp.send('Runtime.getHeapUsage')).usedSize })
}
assert.ok(samples.every((sample) => sample.shared && sample.preserved))
assert.notEqual(samples[0].firstCellPixels, samples[0].secondCellPixels)
assert.ok(
samples.every(
(sample) =>
sample.firstCellPixels === samples[0].firstCellPixels &&
sample.secondCellPixels === samples[0].secondCellPixels &&
sample.contrastProbePixels === samples[0].contrastProbePixels
)
)
if (phase === 'after') {
assert.ok(
samples.every((sample) => sample.contrast <= 4096 && sample.dimContrast <= 4096)
)
} else {
assert.ok(samples.at(-1)[mode === 'dim' ? 'dimContrast' : 'contrast'] >= 100000)
}
const checks = await page.evaluate(() => {
const { first, mode } = window.glyphAudit
const cache =
first.terminal._core._themeService.colors[
mode === 'dim' ? 'halfContrastCache' : 'contrastCache'
]
const entries = () =>
Object.values(cache._color._data).reduce((sum, row) => sum + Object.keys(row).length, 0)
const beforeAtlasClear = entries()
first.addon.clearTextureAtlas()
const afterAtlasClear = entries()
cache.clear()
const afterThemeClear = entries()
first.addon._renderer.renderRows(0, 0)
const recomputedProbePixels = window.glyphAudit.pixelHash(first, 2)
return { beforeAtlasClear, afterAtlasClear, afterThemeClear, recomputedProbePixels }
})
assert.equal(checks.beforeAtlasClear, checks.afterAtlasClear)
assert.equal(checks.afterThemeClear, 0)
assert.equal(checks.recomputedProbePixels, samples[0].contrastProbePixels)
results.push({
phase,
format: bundle.endsWith('.mjs') ? 'esm' : 'cjs',
mode,
sha256,
samples,
checks
})
} finally {
await page.close()
}
}
}
console.log(
JSON.stringify(
{
node: process.version,
browser: browser.version(),
webglSha256: createHash('sha256')
.update(await readFile(webglBundle))
.digest('hex'),
atlasClearEveryUpdates: 1000,
results
},
null,
2
)
)
} finally {
await browser.close()
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,704 @@
{
"node": "v26.6.0",
"browser": "147.0.7727.15",
"webglSha256": "c4b646075065e9ed5f885880ff80e2edd54f481f982adaf193cc742de17e1a4f",
"atlasClearEveryUpdates": 1000,
"results": [
{
"phase": "before",
"format": "cjs",
"mode": "normal",
"sha256": "c9ba43e25b417929c7ab282aa267c73f53106583aba003f6f1b2415850723707",
"samples": [
{
"contrastProbePixels": 482738276,
"contrast": 2,
"dimContrast": 0,
"updates": 0,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 95,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3350504
},
{
"contrastProbePixels": 482738276,
"contrast": 1002,
"dimContrast": 0,
"updates": 1000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1095,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3911268
},
{
"contrastProbePixels": 482738276,
"contrast": 5002,
"dimContrast": 0,
"updates": 5000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 4,
"shared": true,
"preserved": true,
"heap": 4090760
},
{
"contrastProbePixels": 482738276,
"contrast": 10002,
"dimContrast": 0,
"updates": 10000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 9,
"shared": true,
"preserved": true,
"heap": 4455848
},
{
"contrastProbePixels": 482738276,
"contrast": 50002,
"dimContrast": 0,
"updates": 50000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 49,
"shared": true,
"preserved": true,
"heap": 6503096
},
{
"contrastProbePixels": 482738276,
"contrast": 100002,
"dimContrast": 0,
"updates": 100000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 99,
"shared": true,
"preserved": true,
"heap": 8837732
}
],
"checks": {
"beforeAtlasClear": 100002,
"afterAtlasClear": 100002,
"afterThemeClear": 0,
"recomputedProbePixels": 482738276
}
},
{
"phase": "before",
"format": "cjs",
"mode": "dim",
"sha256": "c9ba43e25b417929c7ab282aa267c73f53106583aba003f6f1b2415850723707",
"samples": [
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 1,
"updates": 0,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 95,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3353600
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 1001,
"updates": 1000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1095,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3918408
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 5001,
"updates": 5000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 4,
"shared": true,
"preserved": true,
"heap": 4050468
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 10001,
"updates": 10000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 9,
"shared": true,
"preserved": true,
"heap": 4323072
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 50001,
"updates": 50000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 49,
"shared": true,
"preserved": true,
"heap": 5791324
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 100001,
"updates": 100000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 99,
"shared": true,
"preserved": true,
"heap": 7377052
}
],
"checks": {
"beforeAtlasClear": 100001,
"afterAtlasClear": 100001,
"afterThemeClear": 0,
"recomputedProbePixels": 3123285829
}
},
{
"phase": "after",
"format": "cjs",
"mode": "normal",
"sha256": "5a40045331d16d5c30e558576a07f6b13c7d9aa0c9027211af78b12a10ad8f12",
"samples": [
{
"contrastProbePixels": 482738276,
"contrast": 2,
"dimContrast": 0,
"updates": 0,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 95,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3345812
},
{
"contrastProbePixels": 482738276,
"contrast": 1002,
"dimContrast": 0,
"updates": 1000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1095,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3915296
},
{
"contrastProbePixels": 482738276,
"contrast": 907,
"dimContrast": 0,
"updates": 5000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 4,
"shared": true,
"preserved": true,
"heap": 3845328
},
{
"contrastProbePixels": 482738276,
"contrast": 1814,
"dimContrast": 0,
"updates": 10000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 9,
"shared": true,
"preserved": true,
"heap": 3970072
},
{
"contrastProbePixels": 482738276,
"contrast": 873,
"dimContrast": 0,
"updates": 50000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 49,
"shared": true,
"preserved": true,
"heap": 3912056
},
{
"contrastProbePixels": 482738276,
"contrast": 1746,
"dimContrast": 0,
"updates": 100000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 99,
"shared": true,
"preserved": true,
"heap": 3637608
}
],
"checks": {
"beforeAtlasClear": 1746,
"afterAtlasClear": 1746,
"afterThemeClear": 0,
"recomputedProbePixels": 482738276
}
},
{
"phase": "after",
"format": "cjs",
"mode": "dim",
"sha256": "5a40045331d16d5c30e558576a07f6b13c7d9aa0c9027211af78b12a10ad8f12",
"samples": [
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 1,
"updates": 0,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 95,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3353972
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 1001,
"updates": 1000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1095,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3921736
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 905,
"updates": 5000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 4,
"shared": true,
"preserved": true,
"heap": 3868104
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 1811,
"updates": 10000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 9,
"shared": true,
"preserved": true,
"heap": 3957332
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 860,
"updates": 50000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 49,
"shared": true,
"preserved": true,
"heap": 3945224
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 1721,
"updates": 100000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 99,
"shared": true,
"preserved": true,
"heap": 3670148
}
],
"checks": {
"beforeAtlasClear": 1721,
"afterAtlasClear": 1721,
"afterThemeClear": 0,
"recomputedProbePixels": 3123285829
}
},
{
"phase": "after",
"format": "esm",
"mode": "normal",
"sha256": "f644ab7b834e7866be59b48fd35456b4350554f22b6cc815bcdba00d36a2d827",
"samples": [
{
"contrastProbePixels": 482738276,
"contrast": 2,
"dimContrast": 0,
"updates": 0,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 95,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3245196
},
{
"contrastProbePixels": 482738276,
"contrast": 1002,
"dimContrast": 0,
"updates": 1000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1095,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3817160
},
{
"contrastProbePixels": 482738276,
"contrast": 907,
"dimContrast": 0,
"updates": 5000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 4,
"shared": true,
"preserved": true,
"heap": 3741948
},
{
"contrastProbePixels": 482738276,
"contrast": 1814,
"dimContrast": 0,
"updates": 10000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 9,
"shared": true,
"preserved": true,
"heap": 3866684
},
{
"contrastProbePixels": 482738276,
"contrast": 873,
"dimContrast": 0,
"updates": 50000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 49,
"shared": true,
"preserved": true,
"heap": 3811616
},
{
"contrastProbePixels": 482738276,
"contrast": 1746,
"dimContrast": 0,
"updates": 100000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 99,
"shared": true,
"preserved": true,
"heap": 3653848
}
],
"checks": {
"beforeAtlasClear": 1746,
"afterAtlasClear": 1746,
"afterThemeClear": 0,
"recomputedProbePixels": 482738276
}
},
{
"phase": "after",
"format": "esm",
"mode": "dim",
"sha256": "f644ab7b834e7866be59b48fd35456b4350554f22b6cc815bcdba00d36a2d827",
"samples": [
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 1,
"updates": 0,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 95,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3248292
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 1001,
"updates": 1000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1095,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 94,
"layoutVersion": 0,
"shared": true,
"preserved": true,
"heap": 3818640
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 905,
"updates": 5000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 4,
"shared": true,
"preserved": true,
"heap": 3767340
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 1811,
"updates": 10000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 9,
"shared": true,
"preserved": true,
"heap": 3854124
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 860,
"updates": 50000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 49,
"shared": true,
"preserved": true,
"heap": 3841040
},
{
"contrastProbePixels": 3123285829,
"contrast": 1,
"dimContrast": 1721,
"updates": 100000,
"firstCellPixels": 1033360771,
"secondCellPixels": 395161943,
"regular": 1003,
"combined": 0,
"empty": 0,
"pages": 1,
"glyphs": 3,
"layoutVersion": 99,
"shared": true,
"preserved": true,
"heap": 3684480
}
],
"checks": {
"beforeAtlasClear": 1721,
"afterAtlasClear": 1721,
"afterThemeClear": 0,
"recomputedProbePixels": 3123285829
}
}
]
}
+26 -26
View File
@@ -143,7 +143,7 @@ importers:
version: 0.0.26
'@xterm/addon-serialize':
specifier: 0.15.0-beta.300
version: 0.15.0-beta.300(patch_hash=851eac3d75e6d8c013b9f4c053e61d824b23965cb19ecc28e335e05059f3a294)(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))
version: 0.15.0-beta.300(patch_hash=851eac3d75e6d8c013b9f4c053e61d824b23965cb19ecc28e335e05059f3a294)(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))
'@xterm/headless':
specifier: 6.1.0-beta.302
version: 6.1.0-beta.302
@@ -324,28 +324,28 @@ importers:
version: 5.2.0(rolldown-vite@7.3.1(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)(@types/node@25.9.5)(esbuild@0.25.12)(jiti@2.7.0)(yaml@2.8.4))
'@xterm/addon-fit':
specifier: 0.12.0-beta.300
version: 0.12.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))
version: 0.12.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))
'@xterm/addon-image':
specifier: 0.10.0-beta.300
version: 0.10.0-beta.300(patch_hash=5fc280019957573eefe8daa2969534d6090ddb29c6b5842b8f22e99dc1ce3146)(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))
version: 0.10.0-beta.300(patch_hash=5fc280019957573eefe8daa2969534d6090ddb29c6b5842b8f22e99dc1ce3146)(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))
'@xterm/addon-ligatures':
specifier: 0.11.0-beta.300
version: 0.11.0-beta.300(patch_hash=47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920)(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))
version: 0.11.0-beta.300(patch_hash=47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920)(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))
'@xterm/addon-search':
specifier: 0.17.0-beta.300
version: 0.17.0-beta.300(patch_hash=eee5338dd2621ece46e79c61ec06766cd7fadaf79ffdb24e2a8ab68e97ef31f0)(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))
version: 0.17.0-beta.300(patch_hash=eee5338dd2621ece46e79c61ec06766cd7fadaf79ffdb24e2a8ab68e97ef31f0)(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))
'@xterm/addon-unicode11':
specifier: 0.10.0-beta.300
version: 0.10.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))
version: 0.10.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))
'@xterm/addon-web-links':
specifier: 0.13.0-beta.300
version: 0.13.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))
version: 0.13.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))
'@xterm/addon-webgl':
specifier: 0.20.0-beta.299
version: 0.20.0-beta.299(patch_hash=94687e89a0115e6e6aa102837f986debdc029c091527ee5eb4a4e17ceaf9473e)(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))
version: 0.20.0-beta.299(patch_hash=94687e89a0115e6e6aa102837f986debdc029c091527ee5eb4a4e17ceaf9473e)(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))
'@xterm/xterm':
specifier: 6.1.0-beta.303
version: 6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4)
version: 6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96)
class-variance-authority:
specifier: ^0.7.1
version: 0.7.1
@@ -10483,43 +10483,43 @@ snapshots:
'@xmldom/xmldom@0.8.15': {}
'@xterm/addon-fit@0.12.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))':
'@xterm/addon-fit@0.12.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))':
dependencies:
'@xterm/xterm': 6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4)
'@xterm/xterm': 6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96)
'@xterm/addon-image@0.10.0-beta.300(patch_hash=5fc280019957573eefe8daa2969534d6090ddb29c6b5842b8f22e99dc1ce3146)(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))':
'@xterm/addon-image@0.10.0-beta.300(patch_hash=5fc280019957573eefe8daa2969534d6090ddb29c6b5842b8f22e99dc1ce3146)(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))':
dependencies:
'@xterm/xterm': 6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4)
'@xterm/xterm': 6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96)
'@xterm/addon-ligatures@0.11.0-beta.300(patch_hash=47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920)(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))':
'@xterm/addon-ligatures@0.11.0-beta.300(patch_hash=47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920)(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))':
dependencies:
'@xterm/xterm': 6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4)
'@xterm/xterm': 6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96)
lru-cache: 11.5.1
opentype.js: 2.0.0
'@xterm/addon-search@0.17.0-beta.300(patch_hash=eee5338dd2621ece46e79c61ec06766cd7fadaf79ffdb24e2a8ab68e97ef31f0)(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))':
'@xterm/addon-search@0.17.0-beta.300(patch_hash=eee5338dd2621ece46e79c61ec06766cd7fadaf79ffdb24e2a8ab68e97ef31f0)(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))':
dependencies:
'@xterm/xterm': 6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4)
'@xterm/xterm': 6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96)
'@xterm/addon-serialize@0.15.0-beta.300(patch_hash=851eac3d75e6d8c013b9f4c053e61d824b23965cb19ecc28e335e05059f3a294)(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))':
'@xterm/addon-serialize@0.15.0-beta.300(patch_hash=851eac3d75e6d8c013b9f4c053e61d824b23965cb19ecc28e335e05059f3a294)(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))':
dependencies:
'@xterm/xterm': 6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4)
'@xterm/xterm': 6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96)
'@xterm/addon-unicode11@0.10.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))':
'@xterm/addon-unicode11@0.10.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))':
dependencies:
'@xterm/xterm': 6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4)
'@xterm/xterm': 6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96)
'@xterm/addon-web-links@0.13.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))':
'@xterm/addon-web-links@0.13.0-beta.300(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))':
dependencies:
'@xterm/xterm': 6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4)
'@xterm/xterm': 6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96)
'@xterm/addon-webgl@0.20.0-beta.299(patch_hash=94687e89a0115e6e6aa102837f986debdc029c091527ee5eb4a4e17ceaf9473e)(@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4))':
'@xterm/addon-webgl@0.20.0-beta.299(patch_hash=94687e89a0115e6e6aa102837f986debdc029c091527ee5eb4a4e17ceaf9473e)(@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96))':
dependencies:
'@xterm/xterm': 6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4)
'@xterm/xterm': 6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96)
'@xterm/headless@6.1.0-beta.302': {}
'@xterm/xterm@6.1.0-beta.303(patch_hash=1f36ce689bc50c703ae09aeda0e064f107e18e4a5ecba19e746fa5edc4b02ef4)': {}
'@xterm/xterm@6.1.0-beta.303(patch_hash=6601602d8b599cdffec11997acdc7e70a8297422d70ebdbce35c653899d93a96)': {}
abbrev@4.0.0: {}