Name fixes, more output formats, algo changes

This commit is contained in:
2024-09-10 12:50:15 -04:00
parent fdd210e13e
commit 9355fc5a12
12 changed files with 760 additions and 90 deletions

View File

@ -29,12 +29,107 @@ function generateCreativeName(colors: { [key: string]: string }): string {
const mood = getMood(allColors);
const theme = getTheme(dominantColor);
const nameComponents = [mood, theme].filter(Boolean);
if (nameComponents.length === 1) {
nameComponents.push(getRandomAdjective(dominantColor));
const nameComponents = [
generatePrefix(),
generateSuffix(),
mood,
theme,
generateCompoundWord(),
generateFancifulWord(),
generateColorName(dominantColor),
generateAdjective(),
generateNoun(),
].filter(Boolean);
// Randomly choose 2 or 3 components
const selectedComponents = shuffleArray(nameComponents).slice(0, Math.random() < 0.3 ? 2 : 3);
// Randomly decide to combine words
if (Math.random() < 0.3 && selectedComponents.length > 1) {
const indexToCombine = Math.floor(Math.random() * (selectedComponents.length - 1));
const combinedWord = combineWords(selectedComponents[indexToCombine], selectedComponents[indexToCombine + 1]);
selectedComponents.splice(indexToCombine, 2, combinedWord);
}
return nameComponents.join(' ');
return selectedComponents.join(' ');
}
function combineWords(word1: string, word2: string): string {
const shortenWord = (word: string) => {
const vowels = ['a', 'e', 'i', 'o', 'u'];
let shortened = word.toLowerCase();
// Remove ending if it's a common suffix
shortened = shortened.replace(/(tion|sion|ism|ity|ness|ment|er|or|ous|ive|al|ic|ly)$/, '');
// Remove last vowel if it's not at the start
for (let i = shortened.length - 1; i > 0; i--) {
if (vowels.includes(shortened[i])) {
shortened = shortened.slice(0, i) + shortened.slice(i + 1);
break;
}
}
return shortened;
};
const short1 = shortenWord(word1);
const short2 = shortenWord(word2);
// Randomly choose how to combine the words
const combinationStyles = [
() => short1 + short2,
() => short1 + word2,
() => word1 + short2,
() => short1[0].toUpperCase() + short1.slice(1) + short2,
() => short1 + short2[0].toUpperCase() + short2.slice(1),
];
const chosenStyle = combinationStyles[Math.floor(Math.random() * combinationStyles.length)];
return chosenStyle();
}
function generatePrefix(): string {
const prefixes = [
'Neo', 'Retro', 'Cyber', 'Quantum', 'Astro', 'Techno', 'Synth', 'Vapor', 'Pixel', 'Neon',
'Hyper', 'Micro', 'Macro', 'Ultra', 'Mega', 'Giga', 'Nano', 'Cosmic', 'Stellar', 'Lunar',
'Solar', 'Galactic', 'Atomic', 'Quantum', 'Nebula', 'Plasma', 'Fusion', 'Photon', 'Quark',
'Void', 'Flux', 'Pulse', 'Wave', 'Beam', 'Core', 'Node', 'Grid', 'Mesh', 'Nexus', 'Vortex'
];
return prefixes[Math.floor(Math.random() * prefixes.length)];
}
function generateSuffix(): string {
const suffixes = [
'wave', 'punk', 'core', 'soft', 'hard', 'tech', 'flux', 'glow', 'shine', 'spark',
'burn', 'fade', 'shift', 'drift', 'flow', 'pulse', 'beam', 'ray', 'haze', 'mist',
'dust', 'aura', 'nova', 'storm', 'breeze', 'wind', 'current', 'tide', 'surge', 'burst',
'bloom', 'flare', 'flash', 'gleam', 'glint', 'glimmer', 'glitter', 'shimmer', 'sheen', 'luster'
];
return suffixes[Math.floor(Math.random() * suffixes.length)];
}
function generateCompoundWord(): string {
const compounds = [
'Nightfall', 'Daybreak', 'Sunburst', 'Moonbeam', 'Stardust', 'Skyline', 'Seashore', 'Treeline',
'Cloudscape', 'Firefly', 'Rainbowdrop', 'Thunderbolt', 'Snowflake', 'Leafstorm', 'Sandstorm',
'Iceberg', 'Volcano', 'Earthquake', 'Tidepool', 'Windmill', 'Sunflower', 'Moonstone', 'Stargaze',
'Raindrop', 'Snowdrift', 'Firestorm', 'Icecrystal', 'Sandcastle', 'Waterfalls', 'Skyscraper'
];
return compounds[Math.floor(Math.random() * compounds.length)];
}
function generateFancifulWord(): string {
const prefixes = ['Lum', 'Chrom', 'Spec', 'Pris', 'Aur', 'Sol', 'Lun', 'Stel', 'Cos', 'Astr', 'Neb', 'Phos', 'Zeph', 'Crys', 'Aeth'];
const suffixes = ['escence', 'arium', 'opia', 'ology', 'orama', 'osyne', 'osphere', 'olith', 'onomy', 'ology', 'ium', 'eon', 'alis', 'ora', 'yx'];
const prefix = prefixes[Math.floor(Math.random() * prefixes.length)];
const suffix = suffixes[Math.floor(Math.random() * suffixes.length)];
return prefix + suffix;
}
function shuffleArray<T>(array: T[]): T[] {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
function getDominantColor(colors: string[]): Color {
@ -93,7 +188,15 @@ function getRandomAdjective(color: Color): string {
return adjectives[category][Math.floor(Math.random() * adjectives[category].length)];
}
function generateRandomScheme(): ColorScheme {
function generateRandomScheme(totalSchemes: number): ColorScheme {
if (totalSchemes < 30) {
return generateCompletelyRandomScheme();
} else {
return generateJitteredKnownScheme(totalSchemes);
}
}
function generateCompletelyRandomScheme(): ColorScheme {
const colors = {
primary: { background: generateRandomColor(), foreground: generateRandomColor() },
normal: {
@ -115,37 +218,65 @@ function generateRandomScheme(): ColorScheme {
};
}
function mutateColor(color: string): string {
function generateJitteredKnownScheme(totalSchemes: number): ColorScheme {
const baseScheme = knownSchemes[Math.floor(Math.random() * knownSchemes.length)];
const jitterAmount = Math.min(0.5, (totalSchemes - 30) / 140);
const jitteredColors = {
primary: {
background: jitterColor(baseScheme.colors.primary.background, jitterAmount),
foreground: jitterColor(baseScheme.colors.primary.foreground, jitterAmount)
},
normal: Object.fromEntries(
Object.entries(baseScheme.colors.normal).map(([key, value]) => [key, jitterColor(value, jitterAmount)])
) as ColorScheme['colors']['normal'],
bright: Object.fromEntries(
Object.entries(baseScheme.colors.bright).map(([key, value]) => [key, jitterColor(value, jitterAmount)])
) as ColorScheme['colors']['bright']
};
return {
name: generateCreativeName({ ...jitteredColors.normal, ...jitteredColors.bright }),
colors: jitteredColors
};
}
function jitterColor(color: string, amount: number): string {
const c = Color(color);
const hue = (c.hue() + Math.random() * 30 - 15 + 360) % 360;
const saturation = Math.max(0, Math.min(100, c.saturationl() + Math.random() * 20 - 10));
const lightness = Math.max(0, Math.min(100, c.lightness() + Math.random() * 20 - 10));
const hue = (c.hue() + (Math.random() * 2 - 1) * amount * 360 + 360) % 360;
const saturation = Math.max(0, Math.min(100, c.saturationl() + (Math.random() * 2 - 1) * amount * 100));
const lightness = Math.max(0, Math.min(100, c.lightness() + (Math.random() * 2 - 1) * amount * 100));
return c.hsl(hue, saturation, lightness).hex();
}
function generateSchemeFromGeneticAlgorithm(likedSchemes: ColorScheme[], dislikedSchemes: ColorScheme[]): ColorScheme {
if (likedSchemes.length === 0) {
return generateRandomScheme();
function generateSchemeFromGeneticAlgorithm(likedSchemes: ColorScheme[], dislikedSchemes: ColorScheme[], totalSchemes: number): ColorScheme {
const recentLikedSchemes = likedSchemes.slice(-15);
const recentDislikedSchemes = dislikedSchemes.slice(-15);
if (recentLikedSchemes.length === 0) {
return generateRandomScheme(totalSchemes);
}
const parentScheme = likedSchemes[Math.floor(Math.random() * likedSchemes.length)];
const parentScheme = recentLikedSchemes[Math.floor(Math.random() * recentLikedSchemes.length)];
const newScheme: ColorScheme = JSON.parse(JSON.stringify(parentScheme)); // Deep copy
const mutationRate = Math.max(0.1, 0.5 - totalSchemes / 200); // Decreases from 0.5 to 0.1 as totalSchemes increases
// Mutate colors
(Object.keys(newScheme.colors) as Array<keyof typeof newScheme.colors>).forEach((colorGroup) => {
Object.keys(newScheme.colors[colorGroup]).forEach((colorName) => {
if (Math.random() < 0.3) { // 30% chance of mutation
(newScheme.colors[colorGroup] as Record<string, string>)[colorName] = mutateColor((newScheme.colors[colorGroup] as Record<string, string>)[colorName]);
if (Math.random() < mutationRate) {
(newScheme.colors[colorGroup] as Record<string, string>)[colorName] = mutateColor((newScheme.colors[colorGroup] as Record<string, string>)[colorName], mutationRate);
}
});
});
// Avoid similarities with disliked schemes
dislikedSchemes.forEach(dislikedScheme => {
recentDislikedSchemes.forEach(dislikedScheme => {
(Object.keys(newScheme.colors) as Array<keyof typeof newScheme.colors>).forEach((colorGroup) => {
Object.keys(newScheme.colors[colorGroup]).forEach((colorName) => {
if ((newScheme.colors[colorGroup] as Record<string, string>)[colorName] === (dislikedScheme.colors[colorGroup] as Record<string, string>)[colorName]) {
(newScheme.colors[colorGroup] as Record<string, string>)[colorName] = mutateColor((newScheme.colors[colorGroup] as Record<string, string>)[colorName]);
(newScheme.colors[colorGroup] as Record<string, string>)[colorName] = mutateColor((newScheme.colors[colorGroup] as Record<string, string>)[colorName], mutationRate * 2);
}
});
});
@ -157,5 +288,68 @@ function generateSchemeFromGeneticAlgorithm(likedSchemes: ColorScheme[], dislike
return newScheme;
}
function mutateColor(color: string, mutationRate: number): string {
const c = Color(color);
const hue = (c.hue() + (Math.random() * 2 - 1) * mutationRate * 360 + 360) % 360;
const saturation = Math.max(0, Math.min(100, c.saturationl() + (Math.random() * 2 - 1) * mutationRate * 100));
const lightness = Math.max(0, Math.min(100, c.lightness() + (Math.random() * 2 - 1) * mutationRate * 100));
return c.hsl(hue, saturation, lightness).hex();
}
function generateColorName(color: Color): string {
const hue = color.hue();
const saturation = color.saturationl();
const lightness = color.lightness();
const hueNames = [
'Red', 'Crimson', 'Scarlet', 'Ruby', 'Vermilion',
'Orange', 'Amber', 'Gold', 'Marigold', 'Tangerine',
'Yellow', 'Lemon', 'Canary', 'Saffron', 'Mustard',
'Lime', 'Chartreuse', 'Olive', 'Sage', 'Emerald',
'Green', 'Jade', 'Forest', 'Mint', 'Pine',
'Cyan', 'Turquoise', 'Aqua', 'Teal', 'Azure',
'Blue', 'Cobalt', 'Sapphire', 'Navy', 'Indigo',
'Purple', 'Violet', 'Lavender', 'Plum', 'Amethyst',
'Magenta', 'Fuchsia', 'Pink', 'Rose', 'Cerise',
];
const index = Math.floor(hue / (360 / hueNames.length));
let colorName = hueNames[index];
if (saturation < 20) {
colorName = ['Gray', 'Ash', 'Slate', 'Stone', 'Pewter'][Math.floor(Math.random() * 5)];
}
if (lightness > 80) {
colorName = `Pale ${colorName}`;
} else if (lightness < 20) {
colorName = `Dark ${colorName}`;
}
return colorName;
}
function generateAdjective(): string {
const adjectives = [
'Ethereal', 'Vivid', 'Serene', 'Dynamic', 'Mellow', 'Vibrant', 'Tranquil', 'Radiant',
'Subtle', 'Bold', 'Elegant', 'Rustic', 'Sleek', 'Vintage', 'Modern', 'Classic',
'Dreamy', 'Energetic', 'Calm', 'Lively', 'Soft', 'Intense', 'Gentle', 'Fierce',
'Mystical', 'Enchanted', 'Whimsical', 'Surreal', 'Fantastical', 'Otherworldly',
'Harmonious', 'Balanced', 'Contrasting', 'Complementary', 'Unified', 'Diverse',
];
return adjectives[Math.floor(Math.random() * adjectives.length)];
}
function generateNoun(): string {
const nouns = [
'Horizon', 'Cascade', 'Prism', 'Spectrum', 'Mirage', 'Oasis', 'Zenith', 'Abyss',
'Echo', 'Whisper', 'Tempest', 'Serenity', 'Harmony', 'Rhythm', 'Melody', 'Symphony',
'Essence', 'Spirit', 'Soul', 'Aura', 'Nimbus', 'Halo', 'Veil', 'Shroud',
'Crystal', 'Gem', 'Jewel', 'Pearl', 'Diamond', 'Sapphire', 'Emerald', 'Ruby',
'Nebula', 'Galaxy', 'Cosmos', 'Universe', 'Infinity', 'Eternity', 'Dimension', 'Realm',
];
return nouns[Math.floor(Math.random() * nouns.length)];
}
export type { ColorScheme };
export { knownSchemes, generateRandomScheme, generateSchemeFromGeneticAlgorithm };

View File

@ -84,4 +84,268 @@ magenta = "${scheme.colors.bright.magenta}"
cyan = "${scheme.colors.bright.cyan}"
white = "${scheme.colors.bright.white}"
`;
}
}
export function generateITerm2(scheme: ColorScheme): string {
return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Ansi 0 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.normal.black.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.normal.black.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.normal.black.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 1 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.normal.red.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.normal.red.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.normal.red.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 2 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.normal.green.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.normal.green.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.normal.green.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 3 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.normal.yellow.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.normal.yellow.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.normal.yellow.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 4 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.normal.blue.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.normal.blue.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.normal.blue.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 5 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.normal.magenta.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.normal.magenta.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.normal.magenta.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 6 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.normal.cyan.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.normal.cyan.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.normal.cyan.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 7 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.normal.white.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.normal.white.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.normal.white.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 8 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.bright.black.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.bright.black.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.bright.black.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 9 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.bright.red.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.bright.red.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.bright.red.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 10 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.bright.green.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.bright.green.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.bright.green.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 11 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.bright.yellow.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.bright.yellow.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.bright.yellow.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 12 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.bright.blue.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.bright.blue.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.bright.blue.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 13 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.bright.magenta.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.bright.magenta.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.bright.magenta.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 14 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.bright.cyan.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.bright.cyan.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.bright.cyan.slice(1, 3), 16) / 255}</real>
</dict>
<key>Ansi 15 Color</key>
<dict>
<key>Color Space</key>
<string>sRGB</string>
<key>Blue Component</key>
<real>${parseInt(scheme.colors.bright.white.slice(5, 7), 16) / 255}</real>
<key>Green Component</key>
<real>${parseInt(scheme.colors.bright.white.slice(3, 5), 16) / 255}</real>
<key>Red Component</key>
<real>${parseInt(scheme.colors.bright.white.slice(1, 3), 16) / 255}</real>
</dict>
</dict>
</plist>`;
}
export function generateWindowsTerminal(scheme: ColorScheme): string {
return JSON.stringify({
"name": scheme.name,
"background": scheme.colors.primary.background,
"foreground": scheme.colors.primary.foreground,
"black": scheme.colors.normal.black,
"red": scheme.colors.normal.red,
"green": scheme.colors.normal.green,
"yellow": scheme.colors.normal.yellow,
"blue": scheme.colors.normal.blue,
"purple": scheme.colors.normal.magenta,
"cyan": scheme.colors.normal.cyan,
"white": scheme.colors.normal.white,
"brightBlack": scheme.colors.bright.black,
"brightRed": scheme.colors.bright.red,
"brightGreen": scheme.colors.bright.green,
"brightYellow": scheme.colors.bright.yellow,
"brightBlue": scheme.colors.bright.blue,
"brightPurple": scheme.colors.bright.magenta,
"brightCyan": scheme.colors.bright.cyan,
"brightWhite": scheme.colors.bright.white
}, null, 2);
}
export function generateTerminalApp(scheme: ColorScheme): string {
return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ANSIBlackColor</key>
<data>${colorToBase64(scheme.colors.normal.black)}</data>
<key>ANSIRedColor</key>
<data>${colorToBase64(scheme.colors.normal.red)}</data>
<key>ANSIGreenColor</key>
<data>${colorToBase64(scheme.colors.normal.green)}</data>
<key>ANSIYellowColor</key>
<data>${colorToBase64(scheme.colors.normal.yellow)}</data>
<key>ANSIBlueColor</key>
<data>${colorToBase64(scheme.colors.normal.blue)}</data>
<key>ANSIMagentaColor</key>
<data>${colorToBase64(scheme.colors.normal.magenta)}</data>
<key>ANSICyanColor</key>
<data>${colorToBase64(scheme.colors.normal.cyan)}</data>
<key>ANSIWhiteColor</key>
<data>${colorToBase64(scheme.colors.normal.white)}</data>
<key>ANSIBrightBlackColor</key>
<data>${colorToBase64(scheme.colors.bright.black)}</data>
<key>ANSIBrightRedColor</key>
<data>${colorToBase64(scheme.colors.bright.red)}</data>
<key>ANSIBrightGreenColor</key>
<data>${colorToBase64(scheme.colors.bright.green)}</data>
<key>ANSIBrightYellowColor</key>
<data>${colorToBase64(scheme.colors.bright.yellow)}</data>
<key>ANSIBrightBlueColor</key>
<data>${colorToBase64(scheme.colors.bright.blue)}</data>
<key>ANSIBrightMagentaColor</key>
<data>${colorToBase64(scheme.colors.bright.magenta)}</data>
<key>ANSIBrightCyanColor</key>
<data>${colorToBase64(scheme.colors.bright.cyan)}</data>
<key>ANSIBrightWhiteColor</key>
<data>${colorToBase64(scheme.colors.bright.white)}</data>
<key>BackgroundColor</key>
<data>${colorToBase64(scheme.colors.primary.background)}</data>
<key>TextColor</key>
<data>${colorToBase64(scheme.colors.primary.foreground)}</data>
<key>CursorColor</key>
<data>${colorToBase64(scheme.colors.primary.foreground)}</data>
</dict>
</plist>`;
}
function colorToBase64(color: string): string {
const r = parseInt(color.slice(1, 3), 16) / 255;
const g = parseInt(color.slice(3, 5), 16) / 255;
const b = parseInt(color.slice(5, 7), 16) / 255;
const binaryData = new Float32Array([r, g, b, 1]);
return Buffer.from(binaryData.buffer).toString('base64');
}

View File

@ -1 +1,8 @@
export type CodeSample = 'c' | 'python' | 'rust' | 'go' | 'javascript' | 'java' | 'bash';
export type CodeSample = 'c' | 'python' | 'rust' | 'go' | 'javascript' | 'java' | 'bash';
export interface AppSettings {
outputFormat: string;
codeSample: CodeSample;
juniorDevMode: boolean;
partyMode: boolean;
}