silvery 0.18.2 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{animation-DhINOJk8.mjs → animation-Cn64yepo.mjs} +1 -1
- package/dist/{animation-DhINOJk8.mjs.map → animation-Cn64yepo.mjs.map} +1 -1
- package/dist/{ansi-C6Qs1Wn2.mjs → ansi-CLOitHKx.mjs} +1 -1
- package/dist/ansi-CLOitHKx.mjs.map +1 -0
- package/dist/{ansi-CsjnZtAw.d.mts → ansi-Cc33mW54.d.mts} +1 -1
- package/dist/{ansi-CsjnZtAw.d.mts.map → ansi-Cc33mW54.d.mts.map} +1 -1
- package/dist/{chunk-BSw8zbkd.mjs → chunk-Vs_PY4HZ.mjs} +1 -1
- package/dist/cli-BKp0YtBD.mjs +4 -0
- package/dist/{context-BjWgrikx.mjs → context-BU5LkkIy.mjs} +8 -7
- package/dist/context-BU5LkkIy.mjs.map +1 -0
- package/dist/devtools-9QY4teqI.mjs +2 -0
- package/dist/{devtools-CeO9X_uv.mjs → devtools-DxkSLXDA.mjs} +4 -5
- package/dist/devtools-DxkSLXDA.mjs.map +1 -0
- package/dist/{eta-BnQSZcWf.mjs → eta-Bb3RH3wh.mjs} +1 -1
- package/dist/{eta-BnQSZcWf.mjs.map → eta-Bb3RH3wh.mjs.map} +1 -1
- package/dist/{flexily-zero-adapter-BOM0cl8R.mjs → flexily-zero-adapter-BlQa46nr.mjs} +21 -64
- package/dist/flexily-zero-adapter-BlQa46nr.mjs.map +1 -0
- package/dist/{flexily-zero-adapter-V8R3HQtK.mjs → flexily-zero-adapter-CMxXhdOL.mjs} +1 -1
- package/dist/{image-B0zMbVUr.mjs → image-CTII5QWI.mjs} +3 -3
- package/dist/image-CTII5QWI.mjs.map +1 -0
- package/dist/{index-Bh3U1K09.d.mts → index-BXslOebb.d.mts} +547 -137
- package/dist/index-BXslOebb.d.mts.map +1 -0
- package/dist/{index-C4vrhbud.d.mts → index-BnA7mNpo.d.mts} +1 -1
- package/dist/{index-C4vrhbud.d.mts.map → index-BnA7mNpo.d.mts.map} +1 -1
- package/dist/index-D3saHouR.d.mts +1392 -0
- package/dist/index-D3saHouR.d.mts.map +1 -0
- package/dist/index.d.mts +5 -33
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +13 -13
- package/dist/{layout-engine--drvrWjD.mjs → layout-engine-B6Cdz1yZ.mjs} +1 -1
- package/dist/{layout-engine-Dr3cY5U4.mjs → layout-engine-ClUgv6jB.mjs} +3 -3
- package/dist/{layout-engine-Dr3cY5U4.mjs.map → layout-engine-ClUgv6jB.mjs.map} +1 -1
- package/dist/{multi-progress-CcdqJFlf.mjs → multi-progress-Bq9Oi_WI.mjs} +3 -3
- package/dist/{multi-progress-CcdqJFlf.mjs.map → multi-progress-Bq9Oi_WI.mjs.map} +1 -1
- package/dist/{multi-progress-DQ-uUzLf.d.mts → multi-progress-DAQC7eap.d.mts} +2 -2
- package/dist/{multi-progress-DQ-uUzLf.d.mts.map → multi-progress-DAQC7eap.d.mts.map} +1 -1
- package/dist/{node-CP5WChgr.mjs → node-BeWlnCPY.mjs} +4 -4
- package/dist/node-BeWlnCPY.mjs.map +1 -0
- package/dist/{progress-bar-IrUjkLfU.mjs → progress-bar-CXE5Qfkd.mjs} +4 -4
- package/dist/progress-bar-CXE5Qfkd.mjs.map +1 -0
- package/dist/reconciler-Cwgm8hRR.mjs +8459 -0
- package/dist/reconciler-Cwgm8hRR.mjs.map +1 -0
- package/dist/{render-string-DVfgc8xr.mjs → render-string-Cbuf63Ya.mjs} +936 -136
- package/dist/render-string-Cbuf63Ya.mjs.map +1 -0
- package/dist/{render-string-BwLG7rIX.mjs → render-string-Tv-jqM16.mjs} +1 -1
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.mjs +3 -3
- package/dist/{spinner-BRkaJI0N.d.mts → spinner-CGo34vyR.d.mts} +2 -2
- package/dist/{spinner-BRkaJI0N.d.mts.map → spinner-CGo34vyR.d.mts.map} +1 -1
- package/dist/{spinner-BmldKx0M.mjs → spinner-CeOmcuw_.mjs} +3 -3
- package/dist/spinner-CeOmcuw_.mjs.map +1 -0
- package/dist/src-B5GjfG7g.mjs +4305 -0
- package/dist/src-B5GjfG7g.mjs.map +1 -0
- package/dist/{src-CJPXf3fC.mjs → src-C2uvC-r0.mjs} +7535 -6467
- package/dist/src-C2uvC-r0.mjs.map +1 -0
- package/dist/{src-D8kLrQBT.mjs → src-CChwjk0Z.mjs} +8 -86
- package/dist/src-CChwjk0Z.mjs.map +1 -0
- package/dist/{src-D_BS-as7.mjs → src-NCKb8kE5.mjs} +777 -776
- package/dist/src-NCKb8kE5.mjs.map +1 -0
- package/dist/theme.d.mts +2 -130
- package/dist/theme.mjs +3 -8
- package/dist/{types-B4A8Ebba.d.mts → types-BH_v3iMT.d.mts} +1 -1
- package/dist/{types-B4A8Ebba.d.mts.map → types-BH_v3iMT.d.mts.map} +1 -1
- package/dist/{types-e4dpfbSa.mjs → types-Bk2yw9Qj.mjs} +3 -3
- package/dist/types-Bk2yw9Qj.mjs.map +1 -0
- package/dist/ui/animation.d.mts +1 -1
- package/dist/ui/animation.mjs +1 -1
- package/dist/ui/ansi.d.mts +1 -1
- package/dist/ui/ansi.mjs +1 -1
- package/dist/ui/cli.d.mts +3 -3
- package/dist/ui/cli.mjs +5 -5
- package/dist/ui/display.d.mts +1 -1
- package/dist/ui/display.mjs.map +1 -1
- package/dist/ui/image.d.mts +1 -1
- package/dist/ui/image.mjs +1 -1
- package/dist/ui/input.d.mts +1 -1
- package/dist/ui/input.d.mts.map +1 -1
- package/dist/ui/input.mjs +2 -4
- package/dist/ui/input.mjs.map +1 -1
- package/dist/ui/progress.d.mts +3 -3
- package/dist/ui/progress.d.mts.map +1 -1
- package/dist/ui/progress.mjs +3 -3
- package/dist/ui/progress.mjs.map +1 -1
- package/dist/ui/react.d.mts +1 -1
- package/dist/ui/react.d.mts.map +1 -1
- package/dist/ui/react.mjs +2 -2
- package/dist/ui/react.mjs.map +1 -1
- package/dist/ui/utils.mjs +1 -1
- package/dist/ui/wrappers.d.mts +2 -2
- package/dist/ui/wrappers.mjs +1 -1
- package/dist/ui.d.mts +5 -5
- package/dist/ui.mjs +6 -6
- package/dist/{useLatest-6xqnGIU6.d.mts → useLatest-Bg2x4bfP.d.mts} +1 -1
- package/dist/{useLatest-6xqnGIU6.d.mts.map → useLatest-Bg2x4bfP.d.mts.map} +1 -1
- package/dist/{with-text-input-lUh9gYAG.d.mts → with-text-input-CRfoiFFG.d.mts} +3 -3
- package/dist/with-text-input-CRfoiFFG.d.mts.map +1 -0
- package/dist/{wrappers-JrEYTuKA.mjs → wrappers-UTADQkSY.mjs} +4 -4
- package/dist/wrappers-UTADQkSY.mjs.map +1 -0
- package/dist/{yoga-adapter-Bc8XT9cN.mjs → yoga-adapter-8oRGRw8V.mjs} +2 -2
- package/dist/{yoga-adapter-Bc8XT9cN.mjs.map → yoga-adapter-8oRGRw8V.mjs.map} +1 -1
- package/dist/yoga-adapter-D_CcxSt5.mjs +2 -0
- package/package.json +54 -45
- package/dist/UPNG-DvKjM6wE.mjs +0 -5076
- package/dist/UPNG-DvKjM6wE.mjs.map +0 -1
- package/dist/__vite-browser-external-2447137e-DPKHHqQK.mjs +0 -6
- package/dist/__vite-browser-external-2447137e-DPKHHqQK.mjs.map +0 -1
- package/dist/ansi-C6Qs1Wn2.mjs.map +0 -1
- package/dist/apng-CvSlLBtc.mjs +0 -3
- package/dist/apng-DFFVOItr.mjs +0 -70
- package/dist/apng-DFFVOItr.mjs.map +0 -1
- package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
- package/dist/backend-DU0Y938U.mjs +0 -13396
- package/dist/backend-DU0Y938U.mjs.map +0 -1
- package/dist/backends-BihMKFY_.mjs +0 -1181
- package/dist/backends-BihMKFY_.mjs.map +0 -1
- package/dist/backends-Dk_5G_gC.mjs +0 -3
- package/dist/cli-GwJ0S2In.mjs +0 -4
- package/dist/context-BjWgrikx.mjs.map +0 -1
- package/dist/derive-O_Kb1Bk_.d.mts +0 -28
- package/dist/derive-O_Kb1Bk_.d.mts.map +0 -1
- package/dist/devtools-CeO9X_uv.mjs.map +0 -1
- package/dist/devtools-nX4tj6OH.mjs +0 -2
- package/dist/flexily-zero-adapter-BOM0cl8R.mjs.map +0 -1
- package/dist/gif-B9Uq4qZA.mjs +0 -73
- package/dist/gif-B9Uq4qZA.mjs.map +0 -1
- package/dist/gif-BdrLRBmM.mjs +0 -3
- package/dist/gifenc-DfhOb4xr.mjs +0 -730
- package/dist/gifenc-DfhOb4xr.mjs.map +0 -1
- package/dist/image-B0zMbVUr.mjs.map +0 -1
- package/dist/index-Bh3U1K09.d.mts.map +0 -1
- package/dist/index-dehZ18K-.d.mts +0 -679
- package/dist/index-dehZ18K-.d.mts.map +0 -1
- package/dist/key-mapping-7k2ufK2b.mjs +0 -3
- package/dist/key-mapping-WLUmxjx1.mjs +0 -132
- package/dist/key-mapping-WLUmxjx1.mjs.map +0 -1
- package/dist/node-CP5WChgr.mjs.map +0 -1
- package/dist/progress-bar-IrUjkLfU.mjs.map +0 -1
- package/dist/reconciler-B8uxQxaU.mjs +0 -16482
- package/dist/reconciler-B8uxQxaU.mjs.map +0 -1
- package/dist/render-string-DVfgc8xr.mjs.map +0 -1
- package/dist/resvg-js-Cwipz-_J.mjs +0 -203
- package/dist/resvg-js-Cwipz-_J.mjs.map +0 -1
- package/dist/spinner-BmldKx0M.mjs.map +0 -1
- package/dist/src-C0sOQW-t.mjs +0 -3866
- package/dist/src-C0sOQW-t.mjs.map +0 -1
- package/dist/src-CJPXf3fC.mjs.map +0 -1
- package/dist/src-D8kLrQBT.mjs.map +0 -1
- package/dist/src-D_BS-as7.mjs.map +0 -1
- package/dist/theme.d.mts.map +0 -1
- package/dist/theme.mjs.map +0 -1
- package/dist/types-e4dpfbSa.mjs.map +0 -1
- package/dist/with-text-input-lUh9gYAG.d.mts.map +0 -1
- package/dist/wrapper-CE6GQ27z.mjs +0 -3527
- package/dist/wrapper-CE6GQ27z.mjs.map +0 -1
- package/dist/wrappers-JrEYTuKA.mjs.map +0 -1
- package/dist/yoga-adapter-B8LZpQcE.mjs +0 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { i as __require, n as __esmMin } from "./chunk-
|
|
1
|
+
import { i as __require, n as __esmMin } from "./chunk-Vs_PY4HZ.mjs";
|
|
2
2
|
import "string-width";
|
|
3
|
+
import { blend, brighten, checkContrast, colorDistance, complement, contrastFg, darken, deltaE, ensureContrast, hexToOklch, hexToRgb as hexToRgb$1, oklchToHex } from "@silvery/color";
|
|
3
4
|
//#region packages/ansi/src/detection.ts
|
|
4
5
|
/**
|
|
5
6
|
* Detect if terminal supports cursor control (repositioning).
|
|
@@ -289,7 +290,148 @@ function bgFromRgb(r, g, b, level) {
|
|
|
289
290
|
const idx = nearestAnsi16(r, g, b);
|
|
290
291
|
return idx < 8 ? `${40 + idx}` : `${92 + idx}`;
|
|
291
292
|
}
|
|
292
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Convert a 256-palette index back to its canonical xterm hex value.
|
|
295
|
+
*
|
|
296
|
+
* Mirrors `rgbToAnsi256`:
|
|
297
|
+
* - 16–231: 6×6×6 color cube. Index = 16 + 36·r + 6·g + b (each channel 0..5).
|
|
298
|
+
* - 232–255: 24-step grayscale ramp.
|
|
299
|
+
* - 0–15: ANSI 16 slots (reuses ANSI16_SLOT_HEX for exact parity with
|
|
300
|
+
* `nearestAnsi16`).
|
|
301
|
+
*/
|
|
302
|
+
function ansi256ToHex(idx) {
|
|
303
|
+
if (idx < 0 || idx > 255 || !Number.isInteger(idx)) return "#000000";
|
|
304
|
+
if (idx < 16) {
|
|
305
|
+
const [r, g, b] = ANSI_16_COLORS[idx];
|
|
306
|
+
return rgbToHexHash(r, g, b);
|
|
307
|
+
}
|
|
308
|
+
if (idx < 232) {
|
|
309
|
+
const levels = [
|
|
310
|
+
0,
|
|
311
|
+
95,
|
|
312
|
+
135,
|
|
313
|
+
175,
|
|
314
|
+
215,
|
|
315
|
+
255
|
|
316
|
+
];
|
|
317
|
+
const i = idx - 16;
|
|
318
|
+
const r = levels[Math.floor(i / 36)];
|
|
319
|
+
const g = levels[Math.floor(i % 36 / 6)];
|
|
320
|
+
const b = levels[i % 6];
|
|
321
|
+
return rgbToHexHash(r, g, b);
|
|
322
|
+
}
|
|
323
|
+
const gray = 8 + (idx - 232) * 10;
|
|
324
|
+
return rgbToHexHash(gray, gray, gray);
|
|
325
|
+
}
|
|
326
|
+
function rgbToHexHash(r, g, b) {
|
|
327
|
+
const h = (n) => n.toString(16).padStart(2, "0");
|
|
328
|
+
return `#${h(r)}${h(g)}${h(b)}`;
|
|
329
|
+
}
|
|
330
|
+
function parseHexLocal(hex) {
|
|
331
|
+
if (typeof hex !== "string") return null;
|
|
332
|
+
let s = hex.trim();
|
|
333
|
+
if (s.startsWith("#")) s = s.slice(1);
|
|
334
|
+
if (s.length === 3) s = s.split("").map((c) => c + c).join("");
|
|
335
|
+
if (s.length !== 6) return null;
|
|
336
|
+
const r = parseInt(s.slice(0, 2), 16);
|
|
337
|
+
const g = parseInt(s.slice(2, 4), 16);
|
|
338
|
+
const b = parseInt(s.slice(4, 6), 16);
|
|
339
|
+
if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return null;
|
|
340
|
+
return [
|
|
341
|
+
r,
|
|
342
|
+
g,
|
|
343
|
+
b
|
|
344
|
+
];
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Hex-in / hex-out quantization for previews.
|
|
348
|
+
*
|
|
349
|
+
* Takes any hex color and returns the hex a real terminal at that tier would
|
|
350
|
+
* actually emit. Used by the Sterling storybook to make the `1/2/3/4` tier
|
|
351
|
+
* toggle visibly different in-process — the output phase already does this
|
|
352
|
+
* when writing to a real TTY, but preview surfaces (theme swatches, rendered
|
|
353
|
+
* components inside a storybook app) bypass output-phase quantization. Apply
|
|
354
|
+
* `quantizeHex` at render time to mimic tier-specific terminal output.
|
|
355
|
+
*
|
|
356
|
+
* - `truecolor`: returns the input unchanged (normalized to `#rrggbb`).
|
|
357
|
+
* - `256`: snaps to the nearest xterm-256 slot, then returns that slot's hex.
|
|
358
|
+
* - `ansi16`: snaps to one of the 16 standard slots (canonical xterm RGB).
|
|
359
|
+
* - `mono`: luminance threshold (>= 0.5 → `#ffffff`, else `#000000`).
|
|
360
|
+
*
|
|
361
|
+
* Returns the input unchanged if it cannot be parsed as a hex color.
|
|
362
|
+
*/
|
|
363
|
+
function quantizeHex(hex, tier) {
|
|
364
|
+
const rgb = parseHexLocal(hex);
|
|
365
|
+
if (!rgb) return hex;
|
|
366
|
+
const [r, g, b] = rgb;
|
|
367
|
+
if (tier === "truecolor") return rgbToHexHash(r, g, b);
|
|
368
|
+
if (tier === "256") return ansi256ToHex(rgbToAnsi256(r, g, b));
|
|
369
|
+
if (tier === "ansi16") {
|
|
370
|
+
const [cr, cg, cb] = ANSI_16_COLORS[nearestAnsi16(r, g, b)];
|
|
371
|
+
return rgbToHexHash(cr, cg, cb);
|
|
372
|
+
}
|
|
373
|
+
return (.2126 * r + .7152 * g + .0722 * b) / 255 >= .5 ? "#ffffff" : "#000000";
|
|
374
|
+
}
|
|
375
|
+
function isHexLeaf$1(value) {
|
|
376
|
+
return typeof value === "string" && HEX_LEAF_RE$1.test(value);
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Pre-quantize every hex leaf in a Theme (or any object tree) to the
|
|
380
|
+
* requested color tier.
|
|
381
|
+
*
|
|
382
|
+
* Walks the input recursively — each string leaf matching `#rgb` / `#rrggbb`
|
|
383
|
+
* is passed through {@link quantizeHex}; all other values (numbers, booleans,
|
|
384
|
+
* non-hex strings like `"Nord"`, null/undefined, arrays of non-hex values)
|
|
385
|
+
* pass through unchanged. Arrays and nested objects are rebuilt with
|
|
386
|
+
* quantized leaves.
|
|
387
|
+
*
|
|
388
|
+
* Works on both the legacy ANSI Theme (flat hex tokens + `palette` array)
|
|
389
|
+
* and the Sterling Theme (nested roles + flat tokens) — the structural rule
|
|
390
|
+
* "any leaf that looks like a hex is a color value" holds for both.
|
|
391
|
+
*
|
|
392
|
+
* @example Pre-cache tier variants
|
|
393
|
+
* ```ts
|
|
394
|
+
* import { pickColorLevel } from "silvery"
|
|
395
|
+
*
|
|
396
|
+
* const themes = {
|
|
397
|
+
* truecolor: theme,
|
|
398
|
+
* ansi16: pickColorLevel(theme, "ansi16"),
|
|
399
|
+
* mono: pickColorLevel(theme, "mono"),
|
|
400
|
+
* }
|
|
401
|
+
* ```
|
|
402
|
+
*
|
|
403
|
+
* @example Storybook — show multiple tiers simultaneously
|
|
404
|
+
* ```tsx
|
|
405
|
+
* <ThemeProvider theme={pickColorLevel(theme, "ansi16")}>
|
|
406
|
+
* <AlertPreview />
|
|
407
|
+
* </ThemeProvider>
|
|
408
|
+
* ```
|
|
409
|
+
*
|
|
410
|
+
* Notes:
|
|
411
|
+
* - `truecolor` is a no-op — returns the input unchanged (identity).
|
|
412
|
+
* - The result is structurally identical to the input (same keys, same
|
|
413
|
+
* nesting); only hex leaves are remapped.
|
|
414
|
+
* - Idempotent per tier: `pickColorLevel(pickColorLevel(t, "ansi16"), "ansi16")`
|
|
415
|
+
* yields the same hex values as `pickColorLevel(t, "ansi16")`.
|
|
416
|
+
* - Does not freeze the returned object. Callers that want immutability
|
|
417
|
+
* should `Object.freeze()` (or deep-freeze) the result themselves.
|
|
418
|
+
*/
|
|
419
|
+
function pickColorLevel(theme, tier) {
|
|
420
|
+
if (tier === "truecolor") return theme;
|
|
421
|
+
return pickColorLevelWalk(theme, tier);
|
|
422
|
+
}
|
|
423
|
+
function pickColorLevelWalk(obj, tier) {
|
|
424
|
+
if (obj == null) return obj;
|
|
425
|
+
if (isHexLeaf$1(obj)) return quantizeHex(obj, tier);
|
|
426
|
+
if (Array.isArray(obj)) return obj.map((v) => pickColorLevelWalk(v, tier));
|
|
427
|
+
if (typeof obj === "object") {
|
|
428
|
+
const out = {};
|
|
429
|
+
for (const [k, v] of Object.entries(obj)) out[k] = pickColorLevelWalk(v, tier);
|
|
430
|
+
return out;
|
|
431
|
+
}
|
|
432
|
+
return obj;
|
|
433
|
+
}
|
|
434
|
+
var MODIFIERS, FG_COLORS, BG_COLORS, ANSI_16_COLORS, ANSI16_SLOT_HEX, HEX_LEAF_RE$1;
|
|
293
435
|
var init_color_maps = __esmMin((() => {
|
|
294
436
|
MODIFIERS = {
|
|
295
437
|
reset: [0, 0],
|
|
@@ -424,6 +566,95 @@ var init_color_maps = __esmMin((() => {
|
|
|
424
566
|
255
|
|
425
567
|
]
|
|
426
568
|
];
|
|
569
|
+
ANSI16_SLOT_HEX = {
|
|
570
|
+
black: "#000000",
|
|
571
|
+
red: "#800000",
|
|
572
|
+
green: "#008000",
|
|
573
|
+
yellow: "#808000",
|
|
574
|
+
blue: "#000080",
|
|
575
|
+
magenta: "#800080",
|
|
576
|
+
cyan: "#008080",
|
|
577
|
+
white: "#c0c0c0",
|
|
578
|
+
blackBright: "#808080",
|
|
579
|
+
gray: "#808080",
|
|
580
|
+
grey: "#808080",
|
|
581
|
+
redBright: "#ff0000",
|
|
582
|
+
greenBright: "#00ff00",
|
|
583
|
+
yellowBright: "#ffff00",
|
|
584
|
+
blueBright: "#0000ff",
|
|
585
|
+
magentaBright: "#ff00ff",
|
|
586
|
+
cyanBright: "#00ffff",
|
|
587
|
+
whiteBright: "#ffffff"
|
|
588
|
+
};
|
|
589
|
+
HEX_LEAF_RE$1 = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/;
|
|
590
|
+
}));
|
|
591
|
+
//#endregion
|
|
592
|
+
//#region packages/ansi/src/flatten.ts
|
|
593
|
+
function isHexLeaf(value) {
|
|
594
|
+
return typeof value === "string" && HEX_LEAF_RE.test(value);
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Populate flat hyphen-keys onto `theme` in-place by walking hex leaves and
|
|
598
|
+
* asking `rule` where each leaf should also live at the root.
|
|
599
|
+
*
|
|
600
|
+
* Both the nested and flat forms reference the SAME string (not copies) —
|
|
601
|
+
* `bakeFlat({...}).accent.bg === bakeFlat({...})["bg-accent"]`.
|
|
602
|
+
*
|
|
603
|
+
* `rule` defaults to {@link defaultFlattenRule} (channel-role-state).
|
|
604
|
+
* Rules returning `null` for a path skip that leaf — useful for suppressing
|
|
605
|
+
* metadata or implementing partial projections.
|
|
606
|
+
*
|
|
607
|
+
* The returned object is deep-frozen. The input object is mutated in place
|
|
608
|
+
* and returned; callers that want an unfrozen copy should `structuredClone`
|
|
609
|
+
* before calling.
|
|
610
|
+
*
|
|
611
|
+
* @param theme nested POJO of hex-string leaves (plus optional metadata)
|
|
612
|
+
* @param rule how to compute flat keys from nested paths
|
|
613
|
+
* @returns the same object, with flat keys added and frozen
|
|
614
|
+
*/
|
|
615
|
+
function bakeFlat(theme, rule = defaultFlattenRule) {
|
|
616
|
+
const root = theme;
|
|
617
|
+
if (Object.isFrozen(root)) return theme;
|
|
618
|
+
walk(root, [], root, rule);
|
|
619
|
+
freezeDeep(root);
|
|
620
|
+
return theme;
|
|
621
|
+
}
|
|
622
|
+
function walk(node, path, root, rule) {
|
|
623
|
+
for (const key of Object.keys(node)) {
|
|
624
|
+
if (node === root && key.includes("-")) continue;
|
|
625
|
+
const value = node[key];
|
|
626
|
+
const subpath = [...path, key];
|
|
627
|
+
if (isHexLeaf(value)) {
|
|
628
|
+
const flatKey = rule(subpath);
|
|
629
|
+
if (flatKey !== null) root[flatKey] = value;
|
|
630
|
+
continue;
|
|
631
|
+
}
|
|
632
|
+
if (value && typeof value === "object" && !Array.isArray(value)) walk(value, subpath, root, rule);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
function freezeDeep(o) {
|
|
636
|
+
if (o === null || typeof o !== "object") return;
|
|
637
|
+
if (Object.isFrozen(o)) return;
|
|
638
|
+
Object.freeze(o);
|
|
639
|
+
for (const k of Object.keys(o)) freezeDeep(o[k]);
|
|
640
|
+
}
|
|
641
|
+
var defaultFlattenRule, HEX_LEAF_RE;
|
|
642
|
+
var init_flatten = __esmMin((() => {
|
|
643
|
+
defaultFlattenRule = (path) => {
|
|
644
|
+
if (path.length < 2) return null;
|
|
645
|
+
const role = path[0];
|
|
646
|
+
const last = path[path.length - 1];
|
|
647
|
+
const mid = path.slice(1, -1);
|
|
648
|
+
if (last === "fgOn") return `fg-on-${role}`;
|
|
649
|
+
if (last === "fg" || last === "bg" || last === "border") {
|
|
650
|
+
const state = mid.length > 0 ? mid.join("-") : void 0;
|
|
651
|
+
return state ? `${last}-${role}-${state}` : `${last}-${role}`;
|
|
652
|
+
}
|
|
653
|
+
if (role === "surface") return `bg-surface-${last}`;
|
|
654
|
+
if (role === "border") return `border-${last}`;
|
|
655
|
+
return null;
|
|
656
|
+
};
|
|
657
|
+
HEX_LEAF_RE = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?([0-9a-fA-F]{2})?$/;
|
|
427
658
|
}));
|
|
428
659
|
//#endregion
|
|
429
660
|
//#region packages/ansi/src/terminal-control.ts
|
|
@@ -486,447 +717,123 @@ var init_terminal_control = __esmMin((() => {
|
|
|
486
717
|
`${ESC$3}`;
|
|
487
718
|
}));
|
|
488
719
|
//#endregion
|
|
489
|
-
//#region packages/
|
|
490
|
-
function parseHex(hex) {
|
|
491
|
-
if (hex[0] !== "#") return null;
|
|
492
|
-
const h = hex.slice(1);
|
|
493
|
-
if (h.length === 3) {
|
|
494
|
-
const r = parseInt(h[0] + h[0], 16);
|
|
495
|
-
const g = parseInt(h[1] + h[1], 16);
|
|
496
|
-
const b = parseInt(h[2] + h[2], 16);
|
|
497
|
-
if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return null;
|
|
498
|
-
return [
|
|
499
|
-
r,
|
|
500
|
-
g,
|
|
501
|
-
b
|
|
502
|
-
];
|
|
503
|
-
}
|
|
504
|
-
if (h.length === 6) {
|
|
505
|
-
const r = parseInt(h.slice(0, 2), 16);
|
|
506
|
-
const g = parseInt(h.slice(2, 4), 16);
|
|
507
|
-
const b = parseInt(h.slice(4, 6), 16);
|
|
508
|
-
if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return null;
|
|
509
|
-
return [
|
|
510
|
-
r,
|
|
511
|
-
g,
|
|
512
|
-
b
|
|
513
|
-
];
|
|
514
|
-
}
|
|
515
|
-
return null;
|
|
516
|
-
}
|
|
517
|
-
/** sRGB channel (0–255) → linear RGB (0–1). Inverse gamma. */
|
|
518
|
-
function srgbToLinear(c) {
|
|
519
|
-
const s = c / 255;
|
|
520
|
-
return s <= .04045 ? s / 12.92 : ((s + .055) / 1.055) ** 2.4;
|
|
521
|
-
}
|
|
522
|
-
/** Linear RGB (0–1) → sRGB channel (0–255). Forward gamma. */
|
|
523
|
-
function linearToSrgb(c) {
|
|
524
|
-
const clamped = Math.max(0, Math.min(1, c));
|
|
525
|
-
return clamped <= .0031308 ? 12.92 * clamped * 255 : (1.055 * clamped ** (1 / 2.4) - .055) * 255;
|
|
526
|
-
}
|
|
527
|
-
/** Linear RGB → OKLab (Ottosson 2020 matrix). */
|
|
528
|
-
function linearRgbToOklab(r, g, b) {
|
|
529
|
-
const l = .4122214708 * r + .5363325363 * g + .0514459929 * b;
|
|
530
|
-
const m = .2119034982 * r + .6806995451 * g + .1073969566 * b;
|
|
531
|
-
const s = .0883024619 * r + .2817188376 * g + .6299787005 * b;
|
|
532
|
-
const lCbrt = Math.cbrt(l);
|
|
533
|
-
const mCbrt = Math.cbrt(m);
|
|
534
|
-
const sCbrt = Math.cbrt(s);
|
|
535
|
-
return [
|
|
536
|
-
.2104542553 * lCbrt + .793617785 * mCbrt - .0040720468 * sCbrt,
|
|
537
|
-
1.9779984951 * lCbrt - 2.428592205 * mCbrt + .4505937099 * sCbrt,
|
|
538
|
-
.0259040371 * lCbrt + .7827717662 * mCbrt - .808675766 * sCbrt
|
|
539
|
-
];
|
|
540
|
-
}
|
|
541
|
-
/** OKLab → linear RGB (inverse of the above). */
|
|
542
|
-
function oklabToLinearRgb(L, a, bb) {
|
|
543
|
-
const lCbrt = L + .3963377774 * a + .2158037573 * bb;
|
|
544
|
-
const mCbrt = L - .1055613458 * a - .0638541728 * bb;
|
|
545
|
-
const sCbrt = L - .0894841775 * a - 1.291485548 * bb;
|
|
546
|
-
const l = lCbrt ** 3;
|
|
547
|
-
const m = mCbrt ** 3;
|
|
548
|
-
const s = sCbrt ** 3;
|
|
549
|
-
return [
|
|
550
|
-
4.0767416621 * l - 3.3077115913 * m + .2309699292 * s,
|
|
551
|
-
-1.2684380046 * l + 2.6097574011 * m - .3413193965 * s,
|
|
552
|
-
-.0041960863 * l - .7034186147 * m + 1.707614701 * s
|
|
553
|
-
];
|
|
554
|
-
}
|
|
555
|
-
/** Hex (`#RRGGBB`) → OKLCH. Returns `null` for invalid hex. */
|
|
556
|
-
function hexToOklch(hex) {
|
|
557
|
-
const rgb = parseHex(hex);
|
|
558
|
-
if (!rgb) return null;
|
|
559
|
-
const [r, g, b] = rgb;
|
|
560
|
-
const [lr, lg, lb] = [
|
|
561
|
-
srgbToLinear(r),
|
|
562
|
-
srgbToLinear(g),
|
|
563
|
-
srgbToLinear(b)
|
|
564
|
-
];
|
|
565
|
-
const [L, a, bb] = linearRgbToOklab(lr, lg, lb);
|
|
566
|
-
const C = Math.sqrt(a * a + bb * bb);
|
|
567
|
-
let H = Math.atan2(bb, a) * 180 / Math.PI;
|
|
568
|
-
if (H < 0) H += 360;
|
|
569
|
-
return {
|
|
570
|
-
L,
|
|
571
|
-
C,
|
|
572
|
-
H
|
|
573
|
-
};
|
|
574
|
-
}
|
|
575
|
-
/** Check whether linear RGB is inside sRGB gamut (each channel in [0, 1]). */
|
|
576
|
-
function inGamut(r, g, b) {
|
|
577
|
-
const e = 1e-5;
|
|
578
|
-
return r >= -e && r <= 1 + e && g >= -e && g <= 1 + e && b >= -e && b <= 1 + e;
|
|
579
|
-
}
|
|
720
|
+
//#region packages/ansi/src/kitty-graphics.ts
|
|
580
721
|
/**
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
* recommended approach for rendering OKLCH on sRGB displays.
|
|
722
|
+
* Derive a stable placement ID for a given (x, y) cell. Max column = 9999,
|
|
723
|
+
* which comfortably exceeds any realistic terminal width.
|
|
584
724
|
*/
|
|
585
|
-
function
|
|
586
|
-
|
|
587
|
-
const Crad = (c.H % 360 + 360) % 360 * Math.PI / 180;
|
|
588
|
-
let lo = 0;
|
|
589
|
-
let hi = Math.max(0, c.C);
|
|
590
|
-
let [rHi, gHi, bHi] = oklabToLinearRgb(L, hi * Math.cos(Crad), hi * Math.sin(Crad));
|
|
591
|
-
if (inGamut(rHi, gHi, bHi)) return rgbToHexInternal(linearToSrgb(rHi), linearToSrgb(gHi), linearToSrgb(bHi));
|
|
592
|
-
for (let i = 0; i < 20; i++) {
|
|
593
|
-
const mid = (lo + hi) / 2;
|
|
594
|
-
const [rr, gg, bbLin] = oklabToLinearRgb(L, mid * Math.cos(Crad), mid * Math.sin(Crad));
|
|
595
|
-
if (inGamut(rr, gg, bbLin)) lo = mid;
|
|
596
|
-
else hi = mid;
|
|
597
|
-
}
|
|
598
|
-
const a = lo * Math.cos(Crad);
|
|
599
|
-
const bb = lo * Math.sin(Crad);
|
|
600
|
-
[rHi, gHi, bHi] = oklabToLinearRgb(L, a, bb);
|
|
601
|
-
return rgbToHexInternal(linearToSrgb(rHi), linearToSrgb(gHi), linearToSrgb(bHi));
|
|
602
|
-
}
|
|
603
|
-
function rgbToHexInternal(r, g, b) {
|
|
604
|
-
const clamp = (n) => Math.max(0, Math.min(255, Math.round(n)));
|
|
605
|
-
return `#${clamp(r).toString(16).padStart(2, "0")}${clamp(g).toString(16).padStart(2, "0")}${clamp(b).toString(16).padStart(2, "0")}`.toUpperCase();
|
|
725
|
+
function backdropPlacementId(x, y) {
|
|
726
|
+
return x * BACKDROP_PLACEMENT_X_STRIDE + y + 1;
|
|
606
727
|
}
|
|
607
728
|
/**
|
|
608
|
-
*
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
* effectively undefined). Produces the expected "tinted surface" when blending
|
|
613
|
-
* `bg` with an accent color.
|
|
729
|
+
* Encode a Uint8Array as base64. Kitty expects standard base64 (with `+`/`/`
|
|
730
|
+
* and `=` padding). We use Buffer when available (Node/Bun), fall back to
|
|
731
|
+
* btoa for browser/canvas adapters (the canvas target may never actually
|
|
732
|
+
* need to emit Kitty escapes — this is just defensive).
|
|
614
733
|
*/
|
|
615
|
-
function
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
const
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
const aB = aOk.C * Math.sin(aRad);
|
|
623
|
-
const bA = bOk.C * Math.cos(bRad);
|
|
624
|
-
const bB = bOk.C * Math.sin(bRad);
|
|
625
|
-
const L = aOk.L + (bOk.L - aOk.L) * t;
|
|
626
|
-
const A = aA + (bA - aA) * t;
|
|
627
|
-
const B = aB + (bB - aB) * t;
|
|
628
|
-
const C = Math.sqrt(A * A + B * B);
|
|
629
|
-
let H = Math.atan2(B, A) * 180 / Math.PI;
|
|
630
|
-
if (H < 0) H += 360;
|
|
631
|
-
return oklchToHex({
|
|
632
|
-
L,
|
|
633
|
-
C,
|
|
634
|
-
H
|
|
635
|
-
});
|
|
734
|
+
function base64Encode(bytes) {
|
|
735
|
+
if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
|
|
736
|
+
let binary = "";
|
|
737
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
738
|
+
const g = globalThis;
|
|
739
|
+
if (typeof g.btoa === "function") return g.btoa(binary);
|
|
740
|
+
throw new Error("base64 encoding unavailable in this environment");
|
|
636
741
|
}
|
|
637
742
|
/**
|
|
638
|
-
*
|
|
639
|
-
* distance perceptually meaningful). Hue is weighted by chroma so near-neutral
|
|
640
|
-
* colors don't produce spurious large ΔH contributions.
|
|
641
|
-
*/
|
|
642
|
-
function deltaE(a, b) {
|
|
643
|
-
const dL = a.L - b.L;
|
|
644
|
-
const dC = a.C - b.C;
|
|
645
|
-
const dh = ((a.H - b.H + 540) % 360 - 180) * (Math.PI / 180);
|
|
646
|
-
(a.C + b.C) / 2;
|
|
647
|
-
const dH = 2 * Math.sqrt(a.C * b.C) * Math.sin(dh / 2);
|
|
648
|
-
return Math.sqrt(dL * dL + dC * dC + dH * dH);
|
|
649
|
-
}
|
|
650
|
-
var init_oklch = __esmMin((() => {}));
|
|
651
|
-
//#endregion
|
|
652
|
-
//#region packages/color/src/color.ts
|
|
653
|
-
/** Parse #rrggbb or #rgb to [r, g, b]. Returns null for invalid input. */
|
|
654
|
-
function hexToRgb(hex) {
|
|
655
|
-
if (hex[0] !== "#") return null;
|
|
656
|
-
const h = hex.slice(1);
|
|
657
|
-
if (h.length === 3) return [
|
|
658
|
-
parseInt(h[0] + h[0], 16),
|
|
659
|
-
parseInt(h[1] + h[1], 16),
|
|
660
|
-
parseInt(h[2] + h[2], 16)
|
|
661
|
-
];
|
|
662
|
-
if (h.length === 6) return [
|
|
663
|
-
parseInt(h.slice(0, 2), 16),
|
|
664
|
-
parseInt(h.slice(2, 4), 16),
|
|
665
|
-
parseInt(h.slice(4, 6), 16)
|
|
666
|
-
];
|
|
667
|
-
return null;
|
|
668
|
-
}
|
|
669
|
-
/** Convert [r, g, b] (0-255) to hex string. */
|
|
670
|
-
function rgbToHex(r, g, b) {
|
|
671
|
-
const clamp = (n) => Math.max(0, Math.min(255, Math.round(n)));
|
|
672
|
-
return `#${clamp(r).toString(16).padStart(2, "0")}${clamp(g).toString(16).padStart(2, "0")}${clamp(b).toString(16).padStart(2, "0")}`.toUpperCase();
|
|
673
|
-
}
|
|
674
|
-
/**
|
|
675
|
-
* Blend two hex colors in OKLab space. t=0 returns a, t=1 returns b.
|
|
676
|
-
* Perceptually-uniform midpoints (unlike naive RGB blending which produces
|
|
677
|
-
* muddy halfway colors).
|
|
743
|
+
* Build a tiny RGBA pixel grid for the scrim overlay.
|
|
678
744
|
*
|
|
679
|
-
*
|
|
680
|
-
*
|
|
681
|
-
*
|
|
682
|
-
*
|
|
745
|
+
* Kitty's graphics protocol paints images at native pixel resolution scaled
|
|
746
|
+
* to `c` x `r` cells. A 2x2 RGBA image scaled to a single cell (~10x20 px
|
|
747
|
+
* depending on font) gives us a smooth fill. We intentionally keep the
|
|
748
|
+
* image tiny to minimize base64 payload size on the upload frame.
|
|
683
749
|
*
|
|
684
|
-
*
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
return lerpOklabHex(a, b, t) ?? a;
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* Brighten a hex color by raising OKLCH lightness. amount=0.1 adds 0.1 to L
|
|
691
|
-
* (perceptually linear — 10% brighter looks 10% brighter regardless of hue).
|
|
750
|
+
* Pixel color: `(r, g, b, a)` where `r/g/b` is the scrim tint and `a` is the
|
|
751
|
+
* alpha (0-255). For a dark backdrop we use near-black at ~50% alpha, which
|
|
752
|
+
* darkens the emoji underneath without completely hiding it.
|
|
692
753
|
*
|
|
693
|
-
*
|
|
754
|
+
* Width/height = 2 pixels — 16 bytes total, ~24 bytes base64. Upload is ~60
|
|
755
|
+
* bytes including control chars. One-time cost per modal session.
|
|
694
756
|
*/
|
|
695
|
-
function
|
|
696
|
-
const
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
757
|
+
function buildScrimPixels(tint, alpha) {
|
|
758
|
+
const a = Math.max(0, Math.min(255, Math.round(alpha)));
|
|
759
|
+
const r = Math.max(0, Math.min(255, Math.round(tint.r)));
|
|
760
|
+
const g = Math.max(0, Math.min(255, Math.round(tint.g)));
|
|
761
|
+
const b = Math.max(0, Math.min(255, Math.round(tint.b)));
|
|
762
|
+
const bytes = new Uint8Array(16);
|
|
763
|
+
for (let i = 0; i < 4; i++) {
|
|
764
|
+
bytes[i * 4 + 0] = r;
|
|
765
|
+
bytes[i * 4 + 1] = g;
|
|
766
|
+
bytes[i * 4 + 2] = b;
|
|
767
|
+
bytes[i * 4 + 3] = a;
|
|
768
|
+
}
|
|
769
|
+
return bytes;
|
|
703
770
|
}
|
|
704
771
|
/**
|
|
705
|
-
*
|
|
772
|
+
* APC wrapper: `\x1b_G<control>[;<payload>]\x1b\\`.
|
|
706
773
|
*
|
|
707
|
-
*
|
|
774
|
+
* The protocol allows chunking large payloads via `m=1` but our scrim is
|
|
775
|
+
* tiny — always fits in one chunk.
|
|
708
776
|
*/
|
|
709
|
-
function
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
return oklchToHex({
|
|
713
|
-
L: Math.max(0, o.L - amount),
|
|
714
|
-
C: o.C,
|
|
715
|
-
H: o.H
|
|
716
|
-
});
|
|
777
|
+
function apc(control, payload) {
|
|
778
|
+
if (payload === void 0 || payload === "") return `\x1b_G${control}\x1b\\`;
|
|
779
|
+
return `\x1b_G${control};${payload}\x1b\\`;
|
|
717
780
|
}
|
|
718
781
|
/**
|
|
719
|
-
*
|
|
720
|
-
*
|
|
721
|
-
*
|
|
782
|
+
* Emit a one-shot image upload. Terminal stores the RGBA pixels under
|
|
783
|
+
* `i=<imageId>` and keeps them until explicitly freed. Subsequent placements
|
|
784
|
+
* reference the image by ID without re-sending pixel data.
|
|
722
785
|
*
|
|
723
|
-
*
|
|
786
|
+
* `q=2` suppresses the terminal's OK/error reply — otherwise we'd see stray
|
|
787
|
+
* APC sequences back on stdin.
|
|
724
788
|
*/
|
|
725
|
-
function
|
|
726
|
-
const
|
|
727
|
-
|
|
728
|
-
return oklchToHex({
|
|
729
|
-
L: o.L,
|
|
730
|
-
C: Math.max(0, o.C * (1 - amount)),
|
|
731
|
-
H: o.H
|
|
732
|
-
});
|
|
789
|
+
function kittyUploadScrimImage(pixels, width, height, imageId = BACKDROP_SCRIM_IMAGE_ID) {
|
|
790
|
+
const payload = base64Encode(pixels);
|
|
791
|
+
return apc(`a=t,f=32,s=${width},v=${height},i=${imageId},q=2`, payload);
|
|
733
792
|
}
|
|
734
793
|
/**
|
|
735
|
-
*
|
|
736
|
-
*
|
|
794
|
+
* Emit a cell placement. Places `imageId` at the current cursor position
|
|
795
|
+
* covering `c` cols and `r` rows with z-index `z`. `C=1` prevents the cursor
|
|
796
|
+
* from advancing after placement (critical — otherwise every placement
|
|
797
|
+
* shifts the cursor, breaking the caller's positioning).
|
|
737
798
|
*
|
|
738
|
-
*
|
|
739
|
-
|
|
740
|
-
function complement(color) {
|
|
741
|
-
const o = hexToOklch(color);
|
|
742
|
-
if (!o) return color;
|
|
743
|
-
return oklchToHex({
|
|
744
|
-
L: o.L,
|
|
745
|
-
C: o.C,
|
|
746
|
-
H: (o.H + 180) % 360
|
|
747
|
-
});
|
|
748
|
-
}
|
|
749
|
-
/** Perceptual color distance (ΔE) between two hex colors, in OKLCH. */
|
|
750
|
-
function colorDistance(a, b) {
|
|
751
|
-
const oa = hexToOklch(a);
|
|
752
|
-
const ob = hexToOklch(b);
|
|
753
|
-
if (!oa || !ob) return null;
|
|
754
|
-
return deltaE(oa, ob);
|
|
755
|
-
}
|
|
756
|
-
/**
|
|
757
|
-
* Linearize an sRGB channel value (0-255) for WCAG 2.1 luminance.
|
|
758
|
-
* Kept for WCAG contrast checking — OKLCH uses its own linearization.
|
|
759
|
-
*/
|
|
760
|
-
function channelLuminance(c) {
|
|
761
|
-
const s = c / 255;
|
|
762
|
-
return s <= .03928 ? s / 12.92 : Math.pow((s + .055) / 1.055, 2.4);
|
|
763
|
-
}
|
|
764
|
-
/**
|
|
765
|
-
* Compute relative luminance of a hex color per WCAG 2.1.
|
|
766
|
-
* Returns a value between 0 (darkest) and 1 (lightest), or null for invalid input.
|
|
767
|
-
*/
|
|
768
|
-
function relativeLuminance(hex) {
|
|
769
|
-
const rgb = hexToRgb(hex);
|
|
770
|
-
if (!rgb) return null;
|
|
771
|
-
return .2126 * channelLuminance(rgb[0]) + .7152 * channelLuminance(rgb[1]) + .0722 * channelLuminance(rgb[2]);
|
|
772
|
-
}
|
|
773
|
-
/**
|
|
774
|
-
* Pick black or white text for readability on the given background.
|
|
775
|
-
* Uses WCAG 2.1 relative luminance.
|
|
799
|
+
* Placement ID (`p=<pid>`) is stable per cell so incremental frames can
|
|
800
|
+
* replace placements without accumulating duplicates.
|
|
776
801
|
*/
|
|
777
|
-
function
|
|
778
|
-
const
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
r /= 255;
|
|
784
|
-
g /= 255;
|
|
785
|
-
b /= 255;
|
|
786
|
-
const max = Math.max(r, g, b), min = Math.min(r, g, b);
|
|
787
|
-
const l = (max + min) / 2;
|
|
788
|
-
if (max === min) return [
|
|
789
|
-
0,
|
|
790
|
-
0,
|
|
791
|
-
l
|
|
792
|
-
];
|
|
793
|
-
const d = max - min;
|
|
794
|
-
const s = l > .5 ? d / (2 - max - min) : d / (max + min);
|
|
795
|
-
let h = 0;
|
|
796
|
-
if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
797
|
-
else if (max === g) h = ((b - r) / d + 2) / 6;
|
|
798
|
-
else h = ((r - g) / d + 4) / 6;
|
|
799
|
-
return [
|
|
800
|
-
h * 360,
|
|
801
|
-
s,
|
|
802
|
-
l
|
|
803
|
-
];
|
|
804
|
-
}
|
|
805
|
-
function hslToHex(h, s, l) {
|
|
806
|
-
h = (h % 360 + 360) % 360;
|
|
807
|
-
const a = s * Math.min(l, 1 - l);
|
|
808
|
-
const f = (n) => {
|
|
809
|
-
const k = (n + h / 30) % 12;
|
|
810
|
-
return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
811
|
-
};
|
|
812
|
-
return rgbToHex(f(0) * 255, f(8) * 255, f(4) * 255);
|
|
813
|
-
}
|
|
814
|
-
function hexToHsl(hex) {
|
|
815
|
-
const rgb = hexToRgb(hex);
|
|
816
|
-
if (!rgb) return null;
|
|
817
|
-
return rgbToHsl(rgb[0], rgb[1], rgb[2]);
|
|
802
|
+
function kittyPlaceAt(opts) {
|
|
803
|
+
const imageId = opts.imageId ?? 48879;
|
|
804
|
+
const cols = opts.cols ?? 1;
|
|
805
|
+
const rows = opts.rows ?? 1;
|
|
806
|
+
const z = opts.z ?? 1;
|
|
807
|
+
return apc(`a=p,i=${imageId},p=${opts.placementId},c=${cols},r=${rows},z=${z},C=1,q=2`);
|
|
818
808
|
}
|
|
819
|
-
var init_color = __esmMin((() => {
|
|
820
|
-
init_oklch();
|
|
821
|
-
}));
|
|
822
|
-
//#endregion
|
|
823
|
-
//#region packages/color/src/contrast.ts
|
|
824
809
|
/**
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
* ratio and check AA (>= 4.5:1) and AAA (>= 7:1) compliance for normal text.
|
|
829
|
-
*
|
|
830
|
-
* @param fg - Foreground hex color (e.g. "#FFFFFF")
|
|
831
|
-
* @param bg - Background hex color (e.g. "#000000")
|
|
832
|
-
* @returns Contrast ratio and AA/AAA pass/fail, or null if colors are not valid hex
|
|
833
|
-
*
|
|
834
|
-
* @example
|
|
835
|
-
* ```typescript
|
|
836
|
-
* const result = checkContrast("#FFFFFF", "#000000")
|
|
837
|
-
* // { ratio: 21, aa: true, aaa: true }
|
|
838
|
-
*
|
|
839
|
-
* const poor = checkContrast("#777777", "#888888")
|
|
840
|
-
* // { ratio: ~1.3, aa: false, aaa: false }
|
|
841
|
-
* ```
|
|
810
|
+
* Delete ALL placements of our scrim image without freeing the image.
|
|
811
|
+
* Used when the modal closes — we leave the image cached in case another
|
|
812
|
+
* modal opens, but remove every overlay cell at once.
|
|
842
813
|
*/
|
|
843
|
-
function
|
|
844
|
-
|
|
845
|
-
const bgLum = relativeLuminance(bg);
|
|
846
|
-
if (fgLum === null || bgLum === null) return null;
|
|
847
|
-
const lighter = Math.max(fgLum, bgLum);
|
|
848
|
-
const darker = Math.min(fgLum, bgLum);
|
|
849
|
-
const ratio = (lighter + .05) / (darker + .05);
|
|
850
|
-
return {
|
|
851
|
-
ratio,
|
|
852
|
-
aa: ratio >= 4.5,
|
|
853
|
-
aaa: ratio >= 7
|
|
854
|
-
};
|
|
814
|
+
function kittyDeleteAllScrimPlacements(imageId = BACKDROP_SCRIM_IMAGE_ID) {
|
|
815
|
+
return apc(`a=d,d=i,i=${imageId},q=2`);
|
|
855
816
|
}
|
|
856
817
|
/**
|
|
857
|
-
*
|
|
858
|
-
* against a reference color. Preserves hue and chroma — only lightness shifts,
|
|
859
|
-
* and only as much as needed.
|
|
860
|
-
*
|
|
861
|
-
* Returns the original color unchanged if it already meets the target.
|
|
818
|
+
* Absolute cursor position (CUP). 1-based row/col per VT100.
|
|
862
819
|
*
|
|
863
|
-
*
|
|
864
|
-
*
|
|
865
|
-
*
|
|
866
|
-
*
|
|
867
|
-
* @param against - The reference background color (hex)
|
|
868
|
-
* @param minRatio - Minimum contrast ratio to achieve (e.g. 4.5 for AA)
|
|
869
|
-
* @returns Adjusted hex color meeting the target, or original if already OK
|
|
870
|
-
*
|
|
871
|
-
* @example
|
|
872
|
-
* ```typescript
|
|
873
|
-
* // Yellow on white — too low contrast, gets darkened (perceptually; same hue preserved)
|
|
874
|
-
* ensureContrast("#FFAB91", "#FFFFFF", 4.5)
|
|
875
|
-
*
|
|
876
|
-
* // Blue on dark bg — already fine, returned unchanged
|
|
877
|
-
* ensureContrast("#5C9FFF", "#1A1A2E", 4.5) // → "#5C9FFF"
|
|
878
|
-
* ```
|
|
820
|
+
* Used to position the cursor before emitting a placement so the placement
|
|
821
|
+
* lands in the right cell. Kept small and local — the rest of the pipeline
|
|
822
|
+
* uses more elaborate cursor tracking, but for out-of-band overlay emission
|
|
823
|
+
* we just want a deterministic "jump here, place, done."
|
|
879
824
|
*/
|
|
880
|
-
function
|
|
881
|
-
|
|
882
|
-
if (!current) return color;
|
|
883
|
-
if (current.ratio >= minRatio) return color;
|
|
884
|
-
const o = hexToOklch(color);
|
|
885
|
-
if (!o) return color;
|
|
886
|
-
const lightBg = contrastFg(against) === "#000000";
|
|
887
|
-
let lo, hi;
|
|
888
|
-
if (lightBg) {
|
|
889
|
-
lo = 0;
|
|
890
|
-
hi = o.L;
|
|
891
|
-
} else {
|
|
892
|
-
lo = o.L;
|
|
893
|
-
hi = 1;
|
|
894
|
-
}
|
|
895
|
-
for (let i = 0; i < 24; i++) {
|
|
896
|
-
const mid = (lo + hi) / 2;
|
|
897
|
-
const r = checkContrast(oklchToHex({
|
|
898
|
-
L: mid,
|
|
899
|
-
C: o.C,
|
|
900
|
-
H: o.H
|
|
901
|
-
}), against);
|
|
902
|
-
if (!r) break;
|
|
903
|
-
if (lightBg) if (r.ratio >= minRatio) lo = mid;
|
|
904
|
-
else hi = mid;
|
|
905
|
-
else if (r.ratio >= minRatio) hi = mid;
|
|
906
|
-
else lo = mid;
|
|
907
|
-
}
|
|
908
|
-
return oklchToHex({
|
|
909
|
-
L: lightBg ? lo : hi,
|
|
910
|
-
C: o.C,
|
|
911
|
-
H: o.H
|
|
912
|
-
});
|
|
825
|
+
function cupTo(col, row) {
|
|
826
|
+
return `\x1b[${row + 1};${col + 1}H`;
|
|
913
827
|
}
|
|
914
|
-
var
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
//#endregion
|
|
919
|
-
//#region packages/color/src/index.ts
|
|
920
|
-
var init_src$1 = __esmMin((() => {
|
|
921
|
-
init_color();
|
|
922
|
-
init_oklch();
|
|
923
|
-
init_contrast();
|
|
828
|
+
var BACKDROP_SCRIM_IMAGE_ID, BACKDROP_PLACEMENT_X_STRIDE;
|
|
829
|
+
var init_kitty_graphics = __esmMin((() => {
|
|
830
|
+
BACKDROP_SCRIM_IMAGE_ID = 48879;
|
|
831
|
+
BACKDROP_PLACEMENT_X_STRIDE = 1e4;
|
|
924
832
|
}));
|
|
925
833
|
//#endregion
|
|
926
834
|
//#region packages/ansi/src/style/colors.ts
|
|
927
835
|
var THEME_TOKEN_DEFAULTS;
|
|
928
836
|
var init_colors = __esmMin((() => {
|
|
929
|
-
init_src$1();
|
|
930
837
|
init_color_maps();
|
|
931
838
|
THEME_TOKEN_DEFAULTS = {
|
|
932
839
|
primary: 33,
|
|
@@ -959,7 +866,26 @@ function resolveThemeColor(name, theme) {
|
|
|
959
866
|
if (!theme) return void 0;
|
|
960
867
|
return resolveToken(name, theme);
|
|
961
868
|
}
|
|
962
|
-
/** Internal: resolve a token name (with or without $ prefix) against a theme.
|
|
869
|
+
/** Internal: resolve a token name (with or without $ prefix) against a theme.
|
|
870
|
+
*
|
|
871
|
+
* Resolution order:
|
|
872
|
+
* 1. Direct key lookup — finds Sterling flat keys (`bg-accent`,
|
|
873
|
+
* `fg-on-error`, `border-focus`, …) and legacy kebab keys
|
|
874
|
+
* (`primary-hover`, `fg-hover`, `bg-surface-hover`) and plain names
|
|
875
|
+
* (`bg`, `primary`, `muted`).
|
|
876
|
+
* 2. No-hyphen fallback — `$surface-bg` → `theme.surfacebg`,
|
|
877
|
+
* `$focus-border` → `theme.focusborder`.
|
|
878
|
+
*
|
|
879
|
+
* The old `LEGACY_ALIASES` table (e.g. `fgmuted` → `muted`, `bgsurface` →
|
|
880
|
+
* `surfacebg`) was removed in 0.18.1 once every shipped default Theme ships
|
|
881
|
+
* with Sterling flat tokens baked in — `theme["fg-muted"]` and
|
|
882
|
+
* `theme["bg-surface-subtle"]` are direct fields now, so no alias fallback
|
|
883
|
+
* is required for canonical Sterling tokens. Tokens that existed only as
|
|
884
|
+
* aliases (e.g. `$bg-surface`, `$fg-on-primary`, `$border-input`,
|
|
885
|
+
* `$fg-disabled`) no longer resolve — callers should use the canonical
|
|
886
|
+
* Sterling equivalents (`$bg-surface-default`, `$fg-on-accent`,
|
|
887
|
+
* `$border-default`, `$fg-muted`).
|
|
888
|
+
*/
|
|
963
889
|
function resolveToken(name, theme) {
|
|
964
890
|
if (!theme) return void 0;
|
|
965
891
|
const token = name.startsWith("$") ? name.slice(1) : name;
|
|
@@ -967,14 +893,13 @@ function resolveToken(name, theme) {
|
|
|
967
893
|
const idx = parseInt(token.slice(5), 10);
|
|
968
894
|
if (idx >= 0 && idx < 16 && theme.palette && idx < theme.palette.length) return theme.palette[idx];
|
|
969
895
|
}
|
|
970
|
-
const key = token.replace(/-/g, "");
|
|
971
896
|
const themeObj = theme;
|
|
972
|
-
const direct = themeObj[
|
|
897
|
+
const direct = themeObj[token];
|
|
973
898
|
if (typeof direct === "string") return direct;
|
|
974
|
-
const
|
|
975
|
-
if (
|
|
976
|
-
const
|
|
977
|
-
if (typeof
|
|
899
|
+
const noHyphen = token.replace(/-/g, "");
|
|
900
|
+
if (noHyphen !== token) {
|
|
901
|
+
const stripped = themeObj[noHyphen];
|
|
902
|
+
if (typeof stripped === "string") return stripped;
|
|
978
903
|
}
|
|
979
904
|
}
|
|
980
905
|
/** Convert chalk numeric level (0-3) to ColorLevel. */
|
|
@@ -1066,7 +991,7 @@ function createChainWithRef(state, ref) {
|
|
|
1066
991
|
const level = ref.level;
|
|
1067
992
|
if (prop === "hex" || prop === "bgHex") return (color) => {
|
|
1068
993
|
if (level === null) return createChainWithRef(state, ref);
|
|
1069
|
-
const rgb = hexToRgb(color);
|
|
994
|
+
const rgb = hexToRgb$1(color);
|
|
1070
995
|
if (!rgb) return createChainWithRef(state, ref);
|
|
1071
996
|
const code = prop === "hex" ? fgFromRgb(rgb[0], rgb[1], rgb[2], level) : bgFromRgb(rgb[0], rgb[1], rgb[2], level);
|
|
1072
997
|
const close = prop === "hex" ? "39" : "49";
|
|
@@ -1124,7 +1049,7 @@ function createChainWithRef(state, ref) {
|
|
|
1124
1049
|
if (level === null) return createChainWithRef(state, ref);
|
|
1125
1050
|
const hex = resolveToken(prop, ref.theme);
|
|
1126
1051
|
if (hex) {
|
|
1127
|
-
const rgb = hexToRgb(hex);
|
|
1052
|
+
const rgb = hexToRgb$1(hex);
|
|
1128
1053
|
if (rgb) {
|
|
1129
1054
|
const code = fgFromRgb(rgb[0], rgb[1], rgb[2], level);
|
|
1130
1055
|
if (prop === "link") return createChainWithRef({
|
|
@@ -1188,44 +1113,10 @@ function createChainWithRef(state, ref) {
|
|
|
1188
1113
|
proxyRef.proxy = proxy;
|
|
1189
1114
|
return proxy;
|
|
1190
1115
|
}
|
|
1191
|
-
var
|
|
1116
|
+
var ESC$2, KNOWN_METHODS, THEME_TOKENS;
|
|
1192
1117
|
var init_style = __esmMin((() => {
|
|
1193
1118
|
init_detection();
|
|
1194
1119
|
init_colors();
|
|
1195
|
-
PRIMER_ALIASES = {
|
|
1196
|
-
fgmuted: "muted",
|
|
1197
|
-
fgdisabled: "disabledfg",
|
|
1198
|
-
fgcursor: "cursor",
|
|
1199
|
-
fgselected: "selection",
|
|
1200
|
-
fginverse: "inverse",
|
|
1201
|
-
fgonsurface: "surface",
|
|
1202
|
-
fgonpopover: "popover",
|
|
1203
|
-
fgonprimary: "primaryfg",
|
|
1204
|
-
fgonsecondary: "secondaryfg",
|
|
1205
|
-
fgonaccent: "accentfg",
|
|
1206
|
-
fgonerror: "errorfg",
|
|
1207
|
-
fgonwarning: "warningfg",
|
|
1208
|
-
fgonsuccess: "successfg",
|
|
1209
|
-
fgoninfo: "infofg",
|
|
1210
|
-
bgmuted: "mutedbg",
|
|
1211
|
-
bgsurface: "surfacebg",
|
|
1212
|
-
bgpopover: "popoverbg",
|
|
1213
|
-
bginverse: "inversebg",
|
|
1214
|
-
bgselected: "selectionbg",
|
|
1215
|
-
bgcursor: "cursorbg",
|
|
1216
|
-
borderfocus: "focusborder",
|
|
1217
|
-
borderinput: "inputborder",
|
|
1218
|
-
brandhover: "brandHover",
|
|
1219
|
-
brandactive: "brandActive",
|
|
1220
|
-
brandred: "brandRed",
|
|
1221
|
-
brandorange: "brandOrange",
|
|
1222
|
-
brandyellow: "brandYellow",
|
|
1223
|
-
brandgreen: "brandGreen",
|
|
1224
|
-
brandteal: "brandTeal",
|
|
1225
|
-
brandblue: "brandBlue",
|
|
1226
|
-
brandpurple: "brandPurple",
|
|
1227
|
-
brandpink: "brandPink"
|
|
1228
|
-
};
|
|
1229
1120
|
ESC$2 = "\x1B[";
|
|
1230
1121
|
KNOWN_METHODS = new Set([
|
|
1231
1122
|
"hex",
|
|
@@ -1326,6 +1217,31 @@ var init_mixed_proxy = __esmMin((() => {
|
|
|
1326
1217
|
}));
|
|
1327
1218
|
//#endregion
|
|
1328
1219
|
//#region packages/ansi/src/theme/invariants.ts
|
|
1220
|
+
/**
|
|
1221
|
+
* Theme invariants — post-derivation visibility + optional WCAG checks.
|
|
1222
|
+
*
|
|
1223
|
+
* Two independent invariant groups:
|
|
1224
|
+
*
|
|
1225
|
+
* 1. **Visibility (always checked)** — selection and cursor must be
|
|
1226
|
+
* distinguishable from bg. These fail silently because ensureContrast
|
|
1227
|
+
* doesn't touch `bg-selected`/`bg-cursor`; you get "invisible selection"
|
|
1228
|
+
* bugs that only surface via user complaints.
|
|
1229
|
+
*
|
|
1230
|
+
* 2. **WCAG contrast (opt-in)** — `deriveTheme()` already runs `ensureContrast`
|
|
1231
|
+
* on every text/bg pair as it builds the Theme (lenient auto-adjust). A
|
|
1232
|
+
* second validation pass is redundant for normal use. Enable it explicitly
|
|
1233
|
+
* at build time to *verify* that shipped themes meet the targets, or when
|
|
1234
|
+
* loading a hand-authored Theme object that skipped `deriveTheme`.
|
|
1235
|
+
*
|
|
1236
|
+
* This is why `validateThemeInvariants` defaults to `{ wcag: false }` — the
|
|
1237
|
+
* existing derivation already handles contrast. Callers opt in via
|
|
1238
|
+
* `validateThemeInvariants(theme, { wcag: true })` for strict pre-ship audits.
|
|
1239
|
+
*
|
|
1240
|
+
* All token access is Sterling-shaped — flat hyphen keys (`bg-accent`,
|
|
1241
|
+
* `fg-on-error`, `border-focus`) exist on every Theme via the derive +
|
|
1242
|
+
* bakeFlat pipeline. No concat-kebab legacy names (`primaryfg`, `mutedbg`, …)
|
|
1243
|
+
* — those were removed in silvery 0.19.0 (Sterling interior migration).
|
|
1244
|
+
*/
|
|
1329
1245
|
function lightness(hex) {
|
|
1330
1246
|
const o = hexToOklch(hex);
|
|
1331
1247
|
return o ? o.L : null;
|
|
@@ -1357,43 +1273,51 @@ function validateThemeInvariants(theme, opts = {}) {
|
|
|
1357
1273
|
const checkWcag = opts.wcag ?? false;
|
|
1358
1274
|
const checkVisibility = opts.visibility ?? true;
|
|
1359
1275
|
const violations = [];
|
|
1360
|
-
if (checkWcag)
|
|
1361
|
-
const
|
|
1362
|
-
const
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1276
|
+
if (checkWcag) {
|
|
1277
|
+
const themeRecord = theme;
|
|
1278
|
+
for (const pair of CONTRAST_PAIRS) {
|
|
1279
|
+
const fg = themeRecord[pair.fg];
|
|
1280
|
+
const bg = themeRecord[pair.bg];
|
|
1281
|
+
if (typeof fg !== "string" || typeof bg !== "string") continue;
|
|
1282
|
+
const r = checkContrast(fg, bg);
|
|
1283
|
+
if (r === null) continue;
|
|
1284
|
+
if (r.ratio < pair.min) violations.push({
|
|
1285
|
+
rule: pair.rule,
|
|
1286
|
+
tokens: [pair.fg, pair.bg],
|
|
1287
|
+
actual: r.ratio,
|
|
1288
|
+
required: pair.min,
|
|
1289
|
+
message: `${pair.fg} (${fg}) on ${pair.bg} (${bg}) is ${r.ratio.toFixed(2)}:1, needs ${pair.min.toFixed(1)}:1`
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1373
1292
|
}
|
|
1374
1293
|
if (checkVisibility) {
|
|
1294
|
+
const themeAny = theme;
|
|
1295
|
+
const selectionBg = themeAny["bg-selected"] ?? themeAny["selectionbg"] ?? "";
|
|
1296
|
+
const cursorBg = themeAny["bg-cursor"] ?? themeAny["cursorbg"] ?? "";
|
|
1297
|
+
const selectionKey = themeAny["bg-selected"] !== void 0 ? "bg-selected" : "selectionbg";
|
|
1298
|
+
const cursorKey = themeAny["bg-cursor"] !== void 0 ? "bg-cursor" : "cursorbg";
|
|
1375
1299
|
const lBg = lightness(theme.bg);
|
|
1376
|
-
const lSelBg = lightness(
|
|
1300
|
+
const lSelBg = lightness(selectionBg);
|
|
1377
1301
|
if (lBg !== null && lSelBg !== null) {
|
|
1378
1302
|
const dL = Math.abs(lSelBg - lBg);
|
|
1379
1303
|
if (dL < .08) violations.push({
|
|
1380
1304
|
rule: "visibility:selection",
|
|
1381
|
-
tokens: [
|
|
1305
|
+
tokens: [selectionKey, "bg"],
|
|
1382
1306
|
actual: dL,
|
|
1383
1307
|
required: SELECTION_DELTA_L,
|
|
1384
|
-
message:
|
|
1308
|
+
message: `${selectionKey} (${selectionBg}) differs from bg (${theme.bg}) by ΔL=${dL.toFixed(3)}, needs ≥ ${SELECTION_DELTA_L.toFixed(2)}`
|
|
1385
1309
|
});
|
|
1386
1310
|
}
|
|
1387
1311
|
const oBg = hexToOklch(theme.bg);
|
|
1388
|
-
const oCursorBg = hexToOklch(
|
|
1312
|
+
const oCursorBg = hexToOklch(cursorBg);
|
|
1389
1313
|
if (oBg && oCursorBg) {
|
|
1390
1314
|
const de = deltaE(oBg, oCursorBg);
|
|
1391
1315
|
if (de < .15) violations.push({
|
|
1392
1316
|
rule: "visibility:cursor",
|
|
1393
|
-
tokens: [
|
|
1317
|
+
tokens: [cursorKey, "bg"],
|
|
1394
1318
|
actual: de,
|
|
1395
1319
|
required: CURSOR_DELTA_E,
|
|
1396
|
-
message:
|
|
1320
|
+
message: `${cursorKey} (${cursorBg}) differs from bg (${theme.bg}) by ΔE=${de.toFixed(3)}, needs ≥ ${CURSOR_DELTA_E.toFixed(2)}`
|
|
1397
1321
|
});
|
|
1398
1322
|
}
|
|
1399
1323
|
}
|
|
@@ -1411,7 +1335,6 @@ function formatViolations(violations) {
|
|
|
1411
1335
|
}
|
|
1412
1336
|
var AA_RATIO, FAINT_RATIO, SELECTION_DELTA_L, CURSOR_DELTA_E, CONTRAST_PAIRS, ThemeInvariantError;
|
|
1413
1337
|
var init_invariants = __esmMin((() => {
|
|
1414
|
-
init_src$1();
|
|
1415
1338
|
AA_RATIO = 4.5;
|
|
1416
1339
|
FAINT_RATIO = 1.5;
|
|
1417
1340
|
SELECTION_DELTA_L = .08;
|
|
@@ -1424,152 +1347,110 @@ var init_invariants = __esmMin((() => {
|
|
|
1424
1347
|
min: AA_RATIO
|
|
1425
1348
|
},
|
|
1426
1349
|
{
|
|
1427
|
-
rule: "contrast:fg/
|
|
1350
|
+
rule: "contrast:fg/bg-surface-subtle",
|
|
1428
1351
|
fg: "fg",
|
|
1429
|
-
bg: "
|
|
1352
|
+
bg: "bg-surface-subtle",
|
|
1430
1353
|
min: AA_RATIO
|
|
1431
1354
|
},
|
|
1432
1355
|
{
|
|
1433
|
-
rule: "contrast:fg/
|
|
1356
|
+
rule: "contrast:fg/bg-surface-overlay",
|
|
1434
1357
|
fg: "fg",
|
|
1435
|
-
bg: "
|
|
1358
|
+
bg: "bg-surface-overlay",
|
|
1436
1359
|
min: AA_RATIO
|
|
1437
1360
|
},
|
|
1438
1361
|
{
|
|
1439
|
-
rule: "contrast:muted/
|
|
1440
|
-
fg: "muted",
|
|
1441
|
-
bg: "
|
|
1362
|
+
rule: "contrast:fg-muted/bg-muted",
|
|
1363
|
+
fg: "fg-muted",
|
|
1364
|
+
bg: "bg-muted",
|
|
1442
1365
|
min: 3
|
|
1443
1366
|
},
|
|
1444
1367
|
{
|
|
1445
|
-
rule: "contrast:
|
|
1446
|
-
fg: "
|
|
1368
|
+
rule: "contrast:fg-accent/bg",
|
|
1369
|
+
fg: "fg-accent",
|
|
1447
1370
|
bg: "bg",
|
|
1448
1371
|
min: AA_RATIO
|
|
1449
1372
|
},
|
|
1450
1373
|
{
|
|
1451
|
-
rule: "contrast:
|
|
1452
|
-
fg: "
|
|
1374
|
+
rule: "contrast:fg-error/bg",
|
|
1375
|
+
fg: "fg-error",
|
|
1453
1376
|
bg: "bg",
|
|
1454
1377
|
min: AA_RATIO
|
|
1455
1378
|
},
|
|
1456
1379
|
{
|
|
1457
|
-
rule: "contrast:
|
|
1458
|
-
fg: "
|
|
1380
|
+
rule: "contrast:fg-warning/bg",
|
|
1381
|
+
fg: "fg-warning",
|
|
1459
1382
|
bg: "bg",
|
|
1460
1383
|
min: AA_RATIO
|
|
1461
1384
|
},
|
|
1462
1385
|
{
|
|
1463
|
-
rule: "contrast:
|
|
1464
|
-
fg: "
|
|
1386
|
+
rule: "contrast:fg-success/bg",
|
|
1387
|
+
fg: "fg-success",
|
|
1465
1388
|
bg: "bg",
|
|
1466
1389
|
min: AA_RATIO
|
|
1467
1390
|
},
|
|
1468
1391
|
{
|
|
1469
|
-
rule: "contrast:
|
|
1470
|
-
fg: "
|
|
1392
|
+
rule: "contrast:fg-info/bg",
|
|
1393
|
+
fg: "fg-info",
|
|
1471
1394
|
bg: "bg",
|
|
1472
1395
|
min: AA_RATIO
|
|
1473
1396
|
},
|
|
1474
1397
|
{
|
|
1475
|
-
rule: "contrast:
|
|
1476
|
-
fg: "
|
|
1477
|
-
bg: "bg",
|
|
1398
|
+
rule: "contrast:fg-on-accent/bg-accent",
|
|
1399
|
+
fg: "fg-on-accent",
|
|
1400
|
+
bg: "bg-accent",
|
|
1478
1401
|
min: AA_RATIO
|
|
1479
1402
|
},
|
|
1480
1403
|
{
|
|
1481
|
-
rule: "contrast:
|
|
1482
|
-
fg: "
|
|
1483
|
-
bg: "bg",
|
|
1404
|
+
rule: "contrast:fg-on-error/bg-error",
|
|
1405
|
+
fg: "fg-on-error",
|
|
1406
|
+
bg: "bg-error",
|
|
1484
1407
|
min: AA_RATIO
|
|
1485
1408
|
},
|
|
1486
1409
|
{
|
|
1487
|
-
rule: "contrast:
|
|
1488
|
-
fg: "
|
|
1489
|
-
bg: "bg",
|
|
1410
|
+
rule: "contrast:fg-on-warning/bg-warning",
|
|
1411
|
+
fg: "fg-on-warning",
|
|
1412
|
+
bg: "bg-warning",
|
|
1490
1413
|
min: AA_RATIO
|
|
1491
1414
|
},
|
|
1492
1415
|
{
|
|
1493
|
-
rule: "contrast:
|
|
1494
|
-
fg: "
|
|
1495
|
-
bg: "
|
|
1416
|
+
rule: "contrast:fg-on-success/bg-success",
|
|
1417
|
+
fg: "fg-on-success",
|
|
1418
|
+
bg: "bg-success",
|
|
1496
1419
|
min: AA_RATIO
|
|
1497
1420
|
},
|
|
1498
1421
|
{
|
|
1499
|
-
rule: "contrast:
|
|
1500
|
-
fg: "
|
|
1501
|
-
bg: "
|
|
1422
|
+
rule: "contrast:fg-on-info/bg-info",
|
|
1423
|
+
fg: "fg-on-info",
|
|
1424
|
+
bg: "bg-info",
|
|
1502
1425
|
min: AA_RATIO
|
|
1503
1426
|
},
|
|
1504
1427
|
{
|
|
1505
|
-
rule: "contrast:
|
|
1506
|
-
fg: "
|
|
1507
|
-
bg: "
|
|
1428
|
+
rule: "contrast:fg-on-selected/bg-selected",
|
|
1429
|
+
fg: "fg-on-selected",
|
|
1430
|
+
bg: "bg-selected",
|
|
1508
1431
|
min: AA_RATIO
|
|
1509
1432
|
},
|
|
1510
1433
|
{
|
|
1511
|
-
rule: "contrast:
|
|
1512
|
-
fg: "
|
|
1513
|
-
bg: "
|
|
1434
|
+
rule: "contrast:fg-cursor/bg-cursor",
|
|
1435
|
+
fg: "fg-cursor",
|
|
1436
|
+
bg: "bg-cursor",
|
|
1514
1437
|
min: AA_RATIO
|
|
1515
1438
|
},
|
|
1516
1439
|
{
|
|
1517
|
-
rule: "contrast:
|
|
1518
|
-
fg: "
|
|
1519
|
-
bg: "secondary",
|
|
1520
|
-
min: AA_RATIO
|
|
1521
|
-
},
|
|
1522
|
-
{
|
|
1523
|
-
rule: "contrast:accentfg/accent",
|
|
1524
|
-
fg: "accentfg",
|
|
1525
|
-
bg: "accent",
|
|
1526
|
-
min: AA_RATIO
|
|
1527
|
-
},
|
|
1528
|
-
{
|
|
1529
|
-
rule: "contrast:errorfg/error",
|
|
1530
|
-
fg: "errorfg",
|
|
1531
|
-
bg: "error",
|
|
1532
|
-
min: AA_RATIO
|
|
1533
|
-
},
|
|
1534
|
-
{
|
|
1535
|
-
rule: "contrast:warningfg/warning",
|
|
1536
|
-
fg: "warningfg",
|
|
1537
|
-
bg: "warning",
|
|
1538
|
-
min: AA_RATIO
|
|
1539
|
-
},
|
|
1540
|
-
{
|
|
1541
|
-
rule: "contrast:successfg/success",
|
|
1542
|
-
fg: "successfg",
|
|
1543
|
-
bg: "success",
|
|
1544
|
-
min: AA_RATIO
|
|
1545
|
-
},
|
|
1546
|
-
{
|
|
1547
|
-
rule: "contrast:infofg/info",
|
|
1548
|
-
fg: "infofg",
|
|
1549
|
-
bg: "info",
|
|
1550
|
-
min: AA_RATIO
|
|
1551
|
-
},
|
|
1552
|
-
{
|
|
1553
|
-
rule: "contrast:inputborder/bg",
|
|
1554
|
-
fg: "inputborder",
|
|
1555
|
-
bg: "bg",
|
|
1556
|
-
min: 3
|
|
1557
|
-
},
|
|
1558
|
-
{
|
|
1559
|
-
rule: "contrast:focusborder/bg",
|
|
1560
|
-
fg: "focusborder",
|
|
1440
|
+
rule: "contrast:border-default/bg",
|
|
1441
|
+
fg: "border-default",
|
|
1561
1442
|
bg: "bg",
|
|
1562
1443
|
min: 3
|
|
1563
1444
|
},
|
|
1564
1445
|
{
|
|
1565
|
-
rule: "contrast:
|
|
1566
|
-
fg: "
|
|
1446
|
+
rule: "contrast:border-focus/bg",
|
|
1447
|
+
fg: "border-focus",
|
|
1567
1448
|
bg: "bg",
|
|
1568
1449
|
min: 3
|
|
1569
1450
|
},
|
|
1570
1451
|
{
|
|
1571
|
-
rule: "contrast:border/bg",
|
|
1572
|
-
fg: "border",
|
|
1452
|
+
rule: "contrast:border-muted/bg",
|
|
1453
|
+
fg: "border-muted",
|
|
1573
1454
|
bg: "bg",
|
|
1574
1455
|
min: FAINT_RATIO
|
|
1575
1456
|
}
|
|
@@ -1584,7 +1465,97 @@ var init_invariants = __esmMin((() => {
|
|
|
1584
1465
|
};
|
|
1585
1466
|
}));
|
|
1586
1467
|
//#endregion
|
|
1468
|
+
//#region packages/ansi/src/theme/derived.ts
|
|
1469
|
+
/**
|
|
1470
|
+
* deriveFields — single helper that fills all derived theme sections.
|
|
1471
|
+
*
|
|
1472
|
+
* Eliminates 4-way duplication of brand, categorical ring, state-variant, and
|
|
1473
|
+
* variants population across:
|
|
1474
|
+
* - derive.ts (deriveTruecolorTheme + deriveAnsi16Theme)
|
|
1475
|
+
* - default-schemes.ts (ansi16DarkTheme + ansi16LightTheme)
|
|
1476
|
+
* - @silvery/theme/generate.ts (generateTheme)
|
|
1477
|
+
* - @silvery/theme/schemes/index.ts (ansi16DarkTheme + ansi16LightTheme)
|
|
1478
|
+
*
|
|
1479
|
+
* Canonical authority: derive.ts truecolor path. ANSI16 paths are aligned to
|
|
1480
|
+
* deriveAnsi16Theme output (which is itself the canonical ANSI16 reference).
|
|
1481
|
+
*/
|
|
1482
|
+
/**
|
|
1483
|
+
* Derive the shared "delta" fields common to every theme object:
|
|
1484
|
+
* brand tokens, categorical ring, state variants, and typography variants.
|
|
1485
|
+
*
|
|
1486
|
+
* Pass a `shift` function for truecolor hover/active derivation (OKLCH
|
|
1487
|
+
* brighten/darken). Omit `shift` for ANSI16 — hover/active fall back to the
|
|
1488
|
+
* base color (no intermediate intensities available on 16-color terminals).
|
|
1489
|
+
*
|
|
1490
|
+
* @example
|
|
1491
|
+
* // Truecolor (dark theme)
|
|
1492
|
+
* import { brighten, darken } from "@silvery/color"
|
|
1493
|
+
* deriveFields({ shift: (hex, a) => brighten(hex, a), primary, ... })
|
|
1494
|
+
*
|
|
1495
|
+
* @example
|
|
1496
|
+
* // ANSI16 — no shift function
|
|
1497
|
+
* deriveFields({ primary, accent, fg, selectionbg, surfacebg, ring })
|
|
1498
|
+
*/
|
|
1499
|
+
function deriveFields(input) {
|
|
1500
|
+
const { dark, shift, primary, accent, fg, selectionbg, surfacebg, ring } = input;
|
|
1501
|
+
const applyShift = dark !== void 0 ? (color, amount) => dark ? brighten(color, amount) : darken(color, amount) : shift ?? ((color, _amount) => color);
|
|
1502
|
+
return {
|
|
1503
|
+
brand: primary,
|
|
1504
|
+
"brand-hover": applyShift(primary, .04),
|
|
1505
|
+
"brand-active": applyShift(primary, .08),
|
|
1506
|
+
...ring,
|
|
1507
|
+
"primary-hover": applyShift(primary, .04),
|
|
1508
|
+
"primary-active": applyShift(primary, .08),
|
|
1509
|
+
"accent-hover": applyShift(accent, .04),
|
|
1510
|
+
"accent-active": applyShift(accent, .08),
|
|
1511
|
+
"fg-hover": applyShift(fg, .04),
|
|
1512
|
+
"fg-active": applyShift(fg, .08),
|
|
1513
|
+
"bg-selected-hover": applyShift(selectionbg, .04),
|
|
1514
|
+
"bg-surface-hover": applyShift(surfacebg, .04),
|
|
1515
|
+
variants: DEFAULT_VARIANTS
|
|
1516
|
+
};
|
|
1517
|
+
}
|
|
1518
|
+
var DEFAULT_VARIANTS;
|
|
1519
|
+
var init_derived = __esmMin((() => {
|
|
1520
|
+
DEFAULT_VARIANTS = {
|
|
1521
|
+
h1: {
|
|
1522
|
+
color: "$primary",
|
|
1523
|
+
bold: true
|
|
1524
|
+
},
|
|
1525
|
+
h2: {
|
|
1526
|
+
color: "$accent",
|
|
1527
|
+
bold: true
|
|
1528
|
+
},
|
|
1529
|
+
h3: { bold: true },
|
|
1530
|
+
body: {},
|
|
1531
|
+
"body-muted": { color: "$muted" },
|
|
1532
|
+
"fine-print": {
|
|
1533
|
+
color: "$muted",
|
|
1534
|
+
dim: true
|
|
1535
|
+
},
|
|
1536
|
+
strong: { bold: true },
|
|
1537
|
+
em: { italic: true },
|
|
1538
|
+
link: {
|
|
1539
|
+
color: "$link",
|
|
1540
|
+
underlineStyle: "single"
|
|
1541
|
+
},
|
|
1542
|
+
key: {
|
|
1543
|
+
color: "$accent",
|
|
1544
|
+
bold: true
|
|
1545
|
+
},
|
|
1546
|
+
code: { backgroundColor: "$mutedbg" },
|
|
1547
|
+
kbd: {
|
|
1548
|
+
backgroundColor: "$mutedbg",
|
|
1549
|
+
color: "$accent",
|
|
1550
|
+
bold: true
|
|
1551
|
+
}
|
|
1552
|
+
};
|
|
1553
|
+
}));
|
|
1554
|
+
//#endregion
|
|
1587
1555
|
//#region packages/ansi/src/theme/derive.ts
|
|
1556
|
+
/**
|
|
1557
|
+
* Theme derivation — transforms a ColorScheme into a Theme.
|
|
1558
|
+
*/
|
|
1588
1559
|
function deriveTheme(palette, mode = "truecolor", adjustments) {
|
|
1589
1560
|
if (mode === "ansi16") return deriveAnsi16Theme(palette);
|
|
1590
1561
|
return deriveTruecolorTheme(palette, adjustments);
|
|
@@ -1652,9 +1623,6 @@ function deriveTruecolorTheme(p, adjustments) {
|
|
|
1652
1623
|
const success = ensure("success", p.green, bg, AA);
|
|
1653
1624
|
const info = ensure("info", blend(fg, accent, .5), bg, AA);
|
|
1654
1625
|
const link = ensure("link", dark ? p.brightBlue : p.blue, bg, AA);
|
|
1655
|
-
const brand = primary;
|
|
1656
|
-
const brandHover = dark ? brighten(primary, .04) : darken(primary, .04);
|
|
1657
|
-
const brandActive = dark ? brighten(primary, .08) : darken(primary, .08);
|
|
1658
1626
|
const red = ensure("red", p.red, bg, AA);
|
|
1659
1627
|
const orange = ensure("orange", blend(p.red, p.yellow, .5), bg, AA);
|
|
1660
1628
|
const yellow = ensure("yellow", p.yellow, bg, AA);
|
|
@@ -1672,6 +1640,24 @@ function deriveTruecolorTheme(p, adjustments) {
|
|
|
1672
1640
|
const selection = ensure("selection", p.selectionForeground, selectionBg, AA);
|
|
1673
1641
|
const cursorBgRepaired = repairCursorBg(p.cursorColor, bg);
|
|
1674
1642
|
const cursor = ensure("cursor", p.cursorText, cursorBgRepaired, AA);
|
|
1643
|
+
const derived = deriveFields({
|
|
1644
|
+
dark,
|
|
1645
|
+
primary,
|
|
1646
|
+
accent,
|
|
1647
|
+
fg,
|
|
1648
|
+
selectionbg: selectionBg,
|
|
1649
|
+
surfacebg,
|
|
1650
|
+
ring: {
|
|
1651
|
+
red,
|
|
1652
|
+
orange,
|
|
1653
|
+
yellow,
|
|
1654
|
+
green,
|
|
1655
|
+
teal,
|
|
1656
|
+
blue,
|
|
1657
|
+
purple,
|
|
1658
|
+
pink
|
|
1659
|
+
}
|
|
1660
|
+
});
|
|
1675
1661
|
return {
|
|
1676
1662
|
name: p.name ?? (dark ? "derived-dark" : "derived-light"),
|
|
1677
1663
|
bg,
|
|
@@ -1725,30 +1711,30 @@ function deriveTruecolorTheme(p, adjustments) {
|
|
|
1725
1711
|
p.brightCyan,
|
|
1726
1712
|
p.brightWhite
|
|
1727
1713
|
],
|
|
1728
|
-
|
|
1729
|
-
brandHover,
|
|
1730
|
-
brandActive,
|
|
1731
|
-
red,
|
|
1732
|
-
orange,
|
|
1733
|
-
yellow,
|
|
1734
|
-
green,
|
|
1735
|
-
teal,
|
|
1736
|
-
blue,
|
|
1737
|
-
purple,
|
|
1738
|
-
pink,
|
|
1739
|
-
brandRed: red,
|
|
1740
|
-
brandOrange: orange,
|
|
1741
|
-
brandYellow: yellow,
|
|
1742
|
-
brandGreen: green,
|
|
1743
|
-
brandTeal: teal,
|
|
1744
|
-
brandBlue: blue,
|
|
1745
|
-
brandPurple: purple,
|
|
1746
|
-
brandPink: pink
|
|
1714
|
+
...derived
|
|
1747
1715
|
};
|
|
1748
1716
|
}
|
|
1749
1717
|
function deriveAnsi16Theme(p) {
|
|
1750
1718
|
const dark = p.dark ?? true;
|
|
1751
1719
|
const primaryColor = dark ? p.yellow : p.blue;
|
|
1720
|
+
const accentColor = p.cyan;
|
|
1721
|
+
const derived = deriveFields({
|
|
1722
|
+
primary: primaryColor,
|
|
1723
|
+
accent: accentColor,
|
|
1724
|
+
fg: p.foreground,
|
|
1725
|
+
selectionbg: p.selectionBackground,
|
|
1726
|
+
surfacebg: p.black,
|
|
1727
|
+
ring: {
|
|
1728
|
+
red: dark ? p.brightRed : p.red,
|
|
1729
|
+
orange: dark ? p.brightRed : p.red,
|
|
1730
|
+
yellow: p.yellow,
|
|
1731
|
+
green: dark ? p.brightGreen : p.green,
|
|
1732
|
+
teal: p.cyan,
|
|
1733
|
+
blue: dark ? p.brightBlue : p.blue,
|
|
1734
|
+
purple: p.magenta,
|
|
1735
|
+
pink: dark ? p.brightMagenta : p.magenta
|
|
1736
|
+
}
|
|
1737
|
+
});
|
|
1752
1738
|
return {
|
|
1753
1739
|
name: p.name ?? (dark ? "derived-ansi16-dark" : "derived-ansi16-light"),
|
|
1754
1740
|
bg: p.background,
|
|
@@ -1769,7 +1755,7 @@ function deriveAnsi16Theme(p) {
|
|
|
1769
1755
|
primaryfg: p.black,
|
|
1770
1756
|
secondary: p.magenta,
|
|
1771
1757
|
secondaryfg: p.black,
|
|
1772
|
-
accent:
|
|
1758
|
+
accent: accentColor,
|
|
1773
1759
|
accentfg: p.black,
|
|
1774
1760
|
error: dark ? p.brightRed : p.red,
|
|
1775
1761
|
errorfg: p.black,
|
|
@@ -1802,17 +1788,7 @@ function deriveAnsi16Theme(p) {
|
|
|
1802
1788
|
p.brightCyan,
|
|
1803
1789
|
p.brightWhite
|
|
1804
1790
|
],
|
|
1805
|
-
|
|
1806
|
-
brandHover: primaryColor,
|
|
1807
|
-
brandActive: primaryColor,
|
|
1808
|
-
brandRed: dark ? p.brightRed : p.red,
|
|
1809
|
-
brandOrange: dark ? p.brightRed : p.red,
|
|
1810
|
-
brandYellow: p.yellow,
|
|
1811
|
-
brandGreen: dark ? p.brightGreen : p.green,
|
|
1812
|
-
brandTeal: p.cyan,
|
|
1813
|
-
brandBlue: dark ? p.brightBlue : p.blue,
|
|
1814
|
-
brandPurple: p.magenta,
|
|
1815
|
-
brandPink: dark ? p.brightMagenta : p.magenta
|
|
1791
|
+
...derived
|
|
1816
1792
|
};
|
|
1817
1793
|
}
|
|
1818
1794
|
/**
|
|
@@ -1859,8 +1835,8 @@ function repairCursorBg(cursorBg, bg) {
|
|
|
1859
1835
|
}
|
|
1860
1836
|
var AA, DIM, FAINT, CONTROL;
|
|
1861
1837
|
var init_derive = __esmMin((() => {
|
|
1862
|
-
init_src$1();
|
|
1863
1838
|
init_invariants();
|
|
1839
|
+
init_derived();
|
|
1864
1840
|
AA = 4.5;
|
|
1865
1841
|
DIM = 3;
|
|
1866
1842
|
FAINT = 1.5;
|
|
@@ -1883,10 +1859,16 @@ function deriveMonochromeTheme(theme) {
|
|
|
1883
1859
|
* consumed by the render pipeline.
|
|
1884
1860
|
*
|
|
1885
1861
|
* Accepts strings like `"$primary"`, `"$fg-muted"`, `"$border-focus"`. Strips
|
|
1886
|
-
* the `$` prefix and
|
|
1887
|
-
*
|
|
1862
|
+
* the `$` prefix and looks the name up directly against `DEFAULT_MONO_ATTRS`,
|
|
1863
|
+
* which carries both legacy keys (`muted`, `surfacebg`, `focusborder`, …) AND
|
|
1864
|
+
* Sterling flat tokens (`fg-muted`, `bg-surface-default`, `border-focus`, …)
|
|
1865
|
+
* as first-class entries. Returns `undefined` for non-token strings (hex,
|
|
1888
1866
|
* rgb(), named ANSI colors) — callers should treat this as "no attrs".
|
|
1889
1867
|
*
|
|
1868
|
+
* A secondary no-hyphen fallback (`$surface-bg` → `surfacebg`) keeps the
|
|
1869
|
+
* legacy hyphenated-compound form working for callers that still emit that
|
|
1870
|
+
* shape.
|
|
1871
|
+
*
|
|
1890
1872
|
* @param color The color string (e.g. `"$primary"`, `"#ff0000"`, `"red"`)
|
|
1891
1873
|
* @param theme Active theme (reserved for per-theme overrides)
|
|
1892
1874
|
* @returns Array of mono-attrs for the token, or `undefined` if not a
|
|
@@ -1894,17 +1876,17 @@ function deriveMonochromeTheme(theme) {
|
|
|
1894
1876
|
*/
|
|
1895
1877
|
function monoAttrsForColorString(color, theme) {
|
|
1896
1878
|
if (!color.startsWith("$")) return void 0;
|
|
1897
|
-
const
|
|
1879
|
+
const name = color.slice(1);
|
|
1898
1880
|
const attrs = deriveMonochromeTheme(theme);
|
|
1899
|
-
const direct = attrs[
|
|
1881
|
+
const direct = attrs[name];
|
|
1900
1882
|
if (direct !== void 0) return direct;
|
|
1901
|
-
const
|
|
1902
|
-
if (
|
|
1903
|
-
const
|
|
1904
|
-
if (
|
|
1883
|
+
const noHyphen = name.replace(/-/g, "");
|
|
1884
|
+
if (noHyphen !== name) {
|
|
1885
|
+
const stripped = attrs[noHyphen];
|
|
1886
|
+
if (stripped !== void 0) return stripped;
|
|
1905
1887
|
}
|
|
1906
1888
|
}
|
|
1907
|
-
var DEFAULT_MONO_ATTRS
|
|
1889
|
+
var DEFAULT_MONO_ATTRS;
|
|
1908
1890
|
var init_monochrome = __esmMin((() => {
|
|
1909
1891
|
DEFAULT_MONO_ATTRS = {
|
|
1910
1892
|
bg: [],
|
|
@@ -1938,31 +1920,47 @@ var init_monochrome = __esmMin((() => {
|
|
|
1938
1920
|
inputborder: [],
|
|
1939
1921
|
selection: [],
|
|
1940
1922
|
selectionbg: ["inverse"],
|
|
1941
|
-
cursor: []
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1923
|
+
cursor: [],
|
|
1924
|
+
"fg-muted": ["dim"],
|
|
1925
|
+
"bg-muted": [],
|
|
1926
|
+
"fg-accent": ["italic", "bold"],
|
|
1927
|
+
"bg-accent": [],
|
|
1928
|
+
"fg-on-accent": [],
|
|
1929
|
+
"border-accent": [],
|
|
1930
|
+
"fg-accent-hover": ["italic", "bold"],
|
|
1931
|
+
"bg-accent-hover": [],
|
|
1932
|
+
"fg-accent-active": ["italic", "bold"],
|
|
1933
|
+
"bg-accent-active": [],
|
|
1934
|
+
"fg-info": ["italic"],
|
|
1935
|
+
"bg-info": [],
|
|
1936
|
+
"fg-on-info": [],
|
|
1937
|
+
"bg-info-hover": [],
|
|
1938
|
+
"bg-info-active": [],
|
|
1939
|
+
"fg-success": ["bold"],
|
|
1940
|
+
"bg-success": [],
|
|
1941
|
+
"fg-on-success": [],
|
|
1942
|
+
"bg-success-hover": [],
|
|
1943
|
+
"bg-success-active": [],
|
|
1944
|
+
"fg-warning": ["bold"],
|
|
1945
|
+
"bg-warning": [],
|
|
1946
|
+
"fg-on-warning": [],
|
|
1947
|
+
"bg-warning-hover": [],
|
|
1948
|
+
"bg-warning-active": [],
|
|
1949
|
+
"fg-error": ["bold", "inverse"],
|
|
1950
|
+
"bg-error": [],
|
|
1951
|
+
"fg-on-error": ["inverse"],
|
|
1952
|
+
"bg-error-hover": [],
|
|
1953
|
+
"bg-error-active": [],
|
|
1954
|
+
"bg-surface-default": [],
|
|
1955
|
+
"bg-surface-subtle": [],
|
|
1956
|
+
"bg-surface-raised": [],
|
|
1957
|
+
"bg-surface-overlay": [],
|
|
1958
|
+
"bg-surface-hover": [],
|
|
1959
|
+
"border-default": [],
|
|
1960
|
+
"border-focus": ["bold"],
|
|
1961
|
+
"border-muted": [],
|
|
1962
|
+
"fg-cursor": [],
|
|
1963
|
+
"bg-cursor": []
|
|
1966
1964
|
};
|
|
1967
1965
|
}));
|
|
1968
1966
|
//#endregion
|
|
@@ -2021,7 +2019,6 @@ function fingerprintMatch(probed, catalog, opts = {}) {
|
|
|
2021
2019
|
}
|
|
2022
2020
|
var FINGERPRINT_FIELDS;
|
|
2023
2021
|
var init_fingerprint = __esmMin((() => {
|
|
2024
|
-
init_src$1();
|
|
2025
2022
|
FINGERPRINT_FIELDS = [
|
|
2026
2023
|
"foreground",
|
|
2027
2024
|
"background",
|
|
@@ -2074,154 +2071,9 @@ var init_types = __esmMin((() => {
|
|
|
2074
2071
|
}));
|
|
2075
2072
|
//#endregion
|
|
2076
2073
|
//#region packages/ansi/src/theme/default-schemes.ts
|
|
2077
|
-
var
|
|
2074
|
+
var defaultDarkScheme, defaultLightScheme, ansi16DarkTheme, ansi16LightTheme;
|
|
2078
2075
|
var init_default_schemes = __esmMin((() => {
|
|
2079
|
-
|
|
2080
|
-
name: "dark-ansi16",
|
|
2081
|
-
bg: "",
|
|
2082
|
-
fg: "whiteBright",
|
|
2083
|
-
muted: "white",
|
|
2084
|
-
mutedbg: "black",
|
|
2085
|
-
surface: "whiteBright",
|
|
2086
|
-
surfacebg: "black",
|
|
2087
|
-
popover: "whiteBright",
|
|
2088
|
-
popoverbg: "black",
|
|
2089
|
-
inverse: "black",
|
|
2090
|
-
inversebg: "whiteBright",
|
|
2091
|
-
cursor: "black",
|
|
2092
|
-
cursorbg: "yellow",
|
|
2093
|
-
selection: "black",
|
|
2094
|
-
selectionbg: "yellow",
|
|
2095
|
-
primary: "yellow",
|
|
2096
|
-
primaryfg: "black",
|
|
2097
|
-
secondary: "white",
|
|
2098
|
-
secondaryfg: "black",
|
|
2099
|
-
accent: "blueBright",
|
|
2100
|
-
accentfg: "black",
|
|
2101
|
-
error: "redBright",
|
|
2102
|
-
errorfg: "black",
|
|
2103
|
-
warning: "yellow",
|
|
2104
|
-
warningfg: "black",
|
|
2105
|
-
success: "greenBright",
|
|
2106
|
-
successfg: "black",
|
|
2107
|
-
info: "cyan",
|
|
2108
|
-
infofg: "black",
|
|
2109
|
-
border: "gray",
|
|
2110
|
-
inputborder: "gray",
|
|
2111
|
-
focusborder: "blueBright",
|
|
2112
|
-
link: "blueBright",
|
|
2113
|
-
disabledfg: "gray",
|
|
2114
|
-
palette: [
|
|
2115
|
-
"black",
|
|
2116
|
-
"red",
|
|
2117
|
-
"green",
|
|
2118
|
-
"yellow",
|
|
2119
|
-
"blue",
|
|
2120
|
-
"magenta",
|
|
2121
|
-
"cyan",
|
|
2122
|
-
"white",
|
|
2123
|
-
"blackBright",
|
|
2124
|
-
"redBright",
|
|
2125
|
-
"greenBright",
|
|
2126
|
-
"yellowBright",
|
|
2127
|
-
"blueBright",
|
|
2128
|
-
"magentaBright",
|
|
2129
|
-
"cyanBright",
|
|
2130
|
-
"whiteBright"
|
|
2131
|
-
],
|
|
2132
|
-
brand: "yellow",
|
|
2133
|
-
brandHover: "yellow",
|
|
2134
|
-
brandActive: "yellow",
|
|
2135
|
-
red: "redBright",
|
|
2136
|
-
orange: "redBright",
|
|
2137
|
-
yellow: "yellow",
|
|
2138
|
-
green: "greenBright",
|
|
2139
|
-
teal: "cyan",
|
|
2140
|
-
blue: "blueBright",
|
|
2141
|
-
purple: "magenta",
|
|
2142
|
-
pink: "magentaBright",
|
|
2143
|
-
brandRed: "redBright",
|
|
2144
|
-
brandOrange: "redBright",
|
|
2145
|
-
brandYellow: "yellow",
|
|
2146
|
-
brandGreen: "greenBright",
|
|
2147
|
-
brandTeal: "cyan",
|
|
2148
|
-
brandBlue: "blueBright",
|
|
2149
|
-
brandPurple: "magenta",
|
|
2150
|
-
brandPink: "magentaBright"
|
|
2151
|
-
};
|
|
2152
|
-
ansi16LightTheme = {
|
|
2153
|
-
name: "light-ansi16",
|
|
2154
|
-
bg: "",
|
|
2155
|
-
fg: "black",
|
|
2156
|
-
muted: "blackBright",
|
|
2157
|
-
mutedbg: "white",
|
|
2158
|
-
surface: "black",
|
|
2159
|
-
surfacebg: "white",
|
|
2160
|
-
popover: "black",
|
|
2161
|
-
popoverbg: "white",
|
|
2162
|
-
inverse: "whiteBright",
|
|
2163
|
-
inversebg: "black",
|
|
2164
|
-
cursor: "black",
|
|
2165
|
-
cursorbg: "blue",
|
|
2166
|
-
selection: "black",
|
|
2167
|
-
selectionbg: "cyan",
|
|
2168
|
-
primary: "blue",
|
|
2169
|
-
primaryfg: "black",
|
|
2170
|
-
secondary: "blue",
|
|
2171
|
-
secondaryfg: "black",
|
|
2172
|
-
accent: "cyan",
|
|
2173
|
-
accentfg: "black",
|
|
2174
|
-
error: "red",
|
|
2175
|
-
errorfg: "black",
|
|
2176
|
-
warning: "yellow",
|
|
2177
|
-
warningfg: "black",
|
|
2178
|
-
success: "green",
|
|
2179
|
-
successfg: "black",
|
|
2180
|
-
info: "cyan",
|
|
2181
|
-
infofg: "black",
|
|
2182
|
-
border: "gray",
|
|
2183
|
-
inputborder: "gray",
|
|
2184
|
-
focusborder: "blue",
|
|
2185
|
-
link: "blueBright",
|
|
2186
|
-
disabledfg: "gray",
|
|
2187
|
-
palette: [
|
|
2188
|
-
"black",
|
|
2189
|
-
"red",
|
|
2190
|
-
"green",
|
|
2191
|
-
"yellow",
|
|
2192
|
-
"blue",
|
|
2193
|
-
"magenta",
|
|
2194
|
-
"cyan",
|
|
2195
|
-
"white",
|
|
2196
|
-
"blackBright",
|
|
2197
|
-
"redBright",
|
|
2198
|
-
"greenBright",
|
|
2199
|
-
"yellowBright",
|
|
2200
|
-
"blueBright",
|
|
2201
|
-
"magentaBright",
|
|
2202
|
-
"cyanBright",
|
|
2203
|
-
"whiteBright"
|
|
2204
|
-
],
|
|
2205
|
-
brand: "blue",
|
|
2206
|
-
brandHover: "blue",
|
|
2207
|
-
brandActive: "blue",
|
|
2208
|
-
red: "red",
|
|
2209
|
-
orange: "red",
|
|
2210
|
-
yellow: "yellow",
|
|
2211
|
-
green: "green",
|
|
2212
|
-
teal: "cyan",
|
|
2213
|
-
blue: "blue",
|
|
2214
|
-
purple: "magenta",
|
|
2215
|
-
pink: "magenta",
|
|
2216
|
-
brandRed: "red",
|
|
2217
|
-
brandOrange: "red",
|
|
2218
|
-
brandYellow: "yellow",
|
|
2219
|
-
brandGreen: "green",
|
|
2220
|
-
brandTeal: "cyan",
|
|
2221
|
-
brandBlue: "blue",
|
|
2222
|
-
brandPurple: "magenta",
|
|
2223
|
-
brandPink: "magenta"
|
|
2224
|
-
};
|
|
2076
|
+
init_derive();
|
|
2225
2077
|
defaultDarkScheme = {
|
|
2226
2078
|
name: "default-dark",
|
|
2227
2079
|
dark: true,
|
|
@@ -2274,6 +2126,8 @@ var init_default_schemes = __esmMin((() => {
|
|
|
2274
2126
|
selectionBackground: "#ccd0da",
|
|
2275
2127
|
selectionForeground: "#4c4f69"
|
|
2276
2128
|
};
|
|
2129
|
+
ansi16DarkTheme = deriveAnsi16Theme(defaultDarkScheme);
|
|
2130
|
+
ansi16LightTheme = deriveAnsi16Theme(defaultLightScheme);
|
|
2277
2131
|
}));
|
|
2278
2132
|
//#endregion
|
|
2279
2133
|
//#region packages/ansi/src/osc-palette.ts
|
|
@@ -2487,6 +2341,23 @@ async function detectTerminalScheme(timeoutMs = 150) {
|
|
|
2487
2341
|
if (!wasRaw) stdin.setRawMode(false);
|
|
2488
2342
|
}
|
|
2489
2343
|
}
|
|
2344
|
+
async function detectTheme(opts = {}) {
|
|
2345
|
+
const colorLevel = opts.caps?.colorLevel;
|
|
2346
|
+
if (colorLevel === "none" || colorLevel === "basic") return opts.caps?.darkBackground ?? true ? ansi16DarkTheme : ansi16LightTheme;
|
|
2347
|
+
const detected = await detectTerminalScheme(opts.timeoutMs);
|
|
2348
|
+
const isDark = detected?.dark ?? opts.caps?.darkBackground ?? true;
|
|
2349
|
+
const fallback = opts.fallback ?? (isDark ? opts.fallbackDark ?? defaultDarkScheme : opts.fallbackLight ?? defaultLightScheme);
|
|
2350
|
+
if (!detected) return deriveTheme(fallback);
|
|
2351
|
+
return deriveTheme({
|
|
2352
|
+
...fallback,
|
|
2353
|
+
...stripNulls$1(detected.palette)
|
|
2354
|
+
});
|
|
2355
|
+
}
|
|
2356
|
+
function stripNulls$1(partial) {
|
|
2357
|
+
const result = {};
|
|
2358
|
+
for (const [k, v] of Object.entries(partial)) if (v != null) result[k] = v;
|
|
2359
|
+
return result;
|
|
2360
|
+
}
|
|
2490
2361
|
function isDarkColor(hex) {
|
|
2491
2362
|
const r = parseInt(hex.slice(1, 3), 16) / 255;
|
|
2492
2363
|
const g = parseInt(hex.slice(3, 5), 16) / 255;
|
|
@@ -2494,6 +2365,8 @@ function isDarkColor(hex) {
|
|
|
2494
2365
|
return .2126 * r + .7152 * g + .0722 * b <= .5;
|
|
2495
2366
|
}
|
|
2496
2367
|
var init_detect = __esmMin((() => {
|
|
2368
|
+
init_derive();
|
|
2369
|
+
init_default_schemes();
|
|
2497
2370
|
init_osc_palette();
|
|
2498
2371
|
init_osc_colors();
|
|
2499
2372
|
}));
|
|
@@ -2629,6 +2502,25 @@ var init_orchestrator = __esmMin((() => {
|
|
|
2629
2502
|
init_detect();
|
|
2630
2503
|
init_fingerprint();
|
|
2631
2504
|
init_default_schemes();
|
|
2505
|
+
}));
|
|
2506
|
+
//#endregion
|
|
2507
|
+
//#region packages/ansi/src/theme/tokens.ts
|
|
2508
|
+
var KNOWN_VARIANTS;
|
|
2509
|
+
var init_tokens = __esmMin((() => {
|
|
2510
|
+
KNOWN_VARIANTS = [
|
|
2511
|
+
"h1",
|
|
2512
|
+
"h2",
|
|
2513
|
+
"h3",
|
|
2514
|
+
"body",
|
|
2515
|
+
"body-muted",
|
|
2516
|
+
"fine-print",
|
|
2517
|
+
"strong",
|
|
2518
|
+
"em",
|
|
2519
|
+
"link",
|
|
2520
|
+
"key",
|
|
2521
|
+
"code",
|
|
2522
|
+
"kbd"
|
|
2523
|
+
];
|
|
2632
2524
|
})), CSI;
|
|
2633
2525
|
var init_color_scheme = __esmMin((() => {
|
|
2634
2526
|
CSI = `[`;
|
|
@@ -2636,24 +2528,133 @@ var init_color_scheme = __esmMin((() => {
|
|
|
2636
2528
|
`${CSI}`;
|
|
2637
2529
|
}));
|
|
2638
2530
|
//#endregion
|
|
2531
|
+
//#region packages/ansi/src/theme/generators.ts
|
|
2532
|
+
var init_generators = __esmMin((() => {}));
|
|
2533
|
+
//#endregion
|
|
2534
|
+
//#region packages/ansi/src/theme/auto-generate.ts
|
|
2535
|
+
var init_auto_generate = __esmMin((() => {
|
|
2536
|
+
init_generators();
|
|
2537
|
+
init_derive();
|
|
2538
|
+
}));
|
|
2539
|
+
//#endregion
|
|
2540
|
+
//#region packages/ansi/src/theme/generate.ts
|
|
2541
|
+
/**
|
|
2542
|
+
* Generate a complete ANSI 16 theme from a primary color + dark/light preference.
|
|
2543
|
+
*
|
|
2544
|
+
* All token values are ANSI color names (e.g. "yellow", "blueBright").
|
|
2545
|
+
*/
|
|
2546
|
+
function generateTheme(primary, dark) {
|
|
2547
|
+
const fg = dark ? "whiteBright" : "black";
|
|
2548
|
+
const accent = primary;
|
|
2549
|
+
const selectionbg = primary;
|
|
2550
|
+
const surfacebg = dark ? "black" : "white";
|
|
2551
|
+
const derived = deriveFields({
|
|
2552
|
+
primary,
|
|
2553
|
+
accent,
|
|
2554
|
+
fg,
|
|
2555
|
+
selectionbg,
|
|
2556
|
+
surfacebg,
|
|
2557
|
+
ring: {
|
|
2558
|
+
red: dark ? "redBright" : "red",
|
|
2559
|
+
orange: dark ? "redBright" : "red",
|
|
2560
|
+
yellow: "yellow",
|
|
2561
|
+
green: dark ? "greenBright" : "green",
|
|
2562
|
+
teal: "cyan",
|
|
2563
|
+
blue: dark ? "blueBright" : "blue",
|
|
2564
|
+
purple: "magenta",
|
|
2565
|
+
pink: dark ? "magentaBright" : "magenta"
|
|
2566
|
+
}
|
|
2567
|
+
});
|
|
2568
|
+
return {
|
|
2569
|
+
name: `${dark ? "dark" : "light"}-${primary}`,
|
|
2570
|
+
bg: "",
|
|
2571
|
+
fg,
|
|
2572
|
+
muted: dark ? "white" : "blackBright",
|
|
2573
|
+
mutedbg: dark ? "black" : "white",
|
|
2574
|
+
surface: dark ? "whiteBright" : "black",
|
|
2575
|
+
surfacebg,
|
|
2576
|
+
popover: dark ? "whiteBright" : "black",
|
|
2577
|
+
popoverbg: dark ? "blackBright" : "white",
|
|
2578
|
+
inverse: dark ? "black" : "whiteBright",
|
|
2579
|
+
inversebg: dark ? "whiteBright" : "black",
|
|
2580
|
+
cursor: "black",
|
|
2581
|
+
cursorbg: primary,
|
|
2582
|
+
selection: "black",
|
|
2583
|
+
selectionbg: primary,
|
|
2584
|
+
primary,
|
|
2585
|
+
primaryfg: "black",
|
|
2586
|
+
secondary: primary,
|
|
2587
|
+
secondaryfg: "black",
|
|
2588
|
+
accent: primary,
|
|
2589
|
+
accentfg: "black",
|
|
2590
|
+
error: dark ? "redBright" : "red",
|
|
2591
|
+
errorfg: "black",
|
|
2592
|
+
warning: primary,
|
|
2593
|
+
warningfg: "black",
|
|
2594
|
+
success: dark ? "greenBright" : "green",
|
|
2595
|
+
successfg: "black",
|
|
2596
|
+
info: dark ? "cyanBright" : "cyan",
|
|
2597
|
+
infofg: "black",
|
|
2598
|
+
border: "gray",
|
|
2599
|
+
inputborder: "gray",
|
|
2600
|
+
focusborder: dark ? "blueBright" : "blue",
|
|
2601
|
+
link: "blueBright",
|
|
2602
|
+
disabledfg: "gray",
|
|
2603
|
+
palette: [
|
|
2604
|
+
"black",
|
|
2605
|
+
"red",
|
|
2606
|
+
"green",
|
|
2607
|
+
"yellow",
|
|
2608
|
+
"blue",
|
|
2609
|
+
"magenta",
|
|
2610
|
+
"cyan",
|
|
2611
|
+
"white",
|
|
2612
|
+
"blackBright",
|
|
2613
|
+
"redBright",
|
|
2614
|
+
"greenBright",
|
|
2615
|
+
"yellowBright",
|
|
2616
|
+
"blueBright",
|
|
2617
|
+
"magentaBright",
|
|
2618
|
+
"cyanBright",
|
|
2619
|
+
"whiteBright"
|
|
2620
|
+
],
|
|
2621
|
+
...derived
|
|
2622
|
+
};
|
|
2623
|
+
}
|
|
2624
|
+
var init_generate = __esmMin((() => {
|
|
2625
|
+
init_derived();
|
|
2626
|
+
}));
|
|
2627
|
+
//#endregion
|
|
2639
2628
|
//#region packages/ansi/src/index.ts
|
|
2640
2629
|
var init_src = __esmMin((() => {
|
|
2641
2630
|
init_detection();
|
|
2642
2631
|
init_sgr_codes();
|
|
2643
2632
|
init_utils();
|
|
2633
|
+
init_color_maps();
|
|
2634
|
+
init_flatten();
|
|
2644
2635
|
init_terminal_control();
|
|
2636
|
+
init_kitty_graphics();
|
|
2645
2637
|
init_style();
|
|
2646
2638
|
init_mixed_proxy();
|
|
2639
|
+
init_colors();
|
|
2647
2640
|
init_derive();
|
|
2641
|
+
init_derived();
|
|
2648
2642
|
init_monochrome();
|
|
2643
|
+
init_fingerprint();
|
|
2649
2644
|
init_orchestrator();
|
|
2645
|
+
init_invariants();
|
|
2650
2646
|
init_default_schemes();
|
|
2651
2647
|
init_types();
|
|
2648
|
+
init_tokens();
|
|
2652
2649
|
init_detect();
|
|
2653
2650
|
init_osc_palette();
|
|
2651
|
+
init_osc_colors();
|
|
2654
2652
|
init_color_scheme();
|
|
2653
|
+
init_generators();
|
|
2654
|
+
init_auto_generate();
|
|
2655
|
+
init_generate();
|
|
2655
2656
|
}));
|
|
2656
2657
|
//#endregion
|
|
2657
|
-
export {
|
|
2658
|
+
export { backdropPlacementId as A, bakeFlat as B, COLOR_SCHEME_FIELDS as C, createMixedStyle as D, deriveFields as E, kittyUploadScrimImage as F, bgColorCode as G, ANSI16_SLOT_HEX as H, disableKittyKeyboard as I, detectColor as J, fgColorCode as K, disableMouse as L, cupTo as M, kittyDeleteAllScrimPlacements as N, createStyle as O, kittyPlaceAt as P, detectUnicode as Q, enableKittyKeyboard as R, ansi16LightTheme as S, deriveTheme as T, pickColorLevel as U, defaultFlattenRule as V, quantizeHex as W, detectInput as X, detectCursor as Y, detectTerminalCaps as Z, parsePaletteResponse as _, detectTerminalScheme as a, setPaletteColor as b, queryBackgroundColor as c, resetBackgroundColor as d, resetCursorColor as f, setForegroundColor as g, setCursorColor as h, detectScheme as i, buildScrimPixels as j, resolveThemeColor as k, queryCursorColor as l, setBackgroundColor as m, generateTheme as n, detectTheme as o, resetForegroundColor as p, defaultCaps as q, KNOWN_VARIANTS as r, detectColorScheme as s, init_src as t, queryForegroundColor as u, queryMultiplePaletteColors as v, monoAttrsForColorString as w, ansi16DarkTheme as x, queryPaletteColor as y, enableMouse as z };
|
|
2658
2659
|
|
|
2659
|
-
//# sourceMappingURL=src-
|
|
2660
|
+
//# sourceMappingURL=src-NCKb8kE5.mjs.map
|