emoji-banner-generator 1.0.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +160 -0
  3. package/dist/animation.d.ts +14 -0
  4. package/dist/animation.d.ts.map +1 -0
  5. package/dist/animation.js +194 -0
  6. package/dist/animation.js.map +1 -0
  7. package/dist/bitmap.d.ts +25 -0
  8. package/dist/bitmap.d.ts.map +1 -0
  9. package/dist/bitmap.js +141 -0
  10. package/dist/bitmap.js.map +1 -0
  11. package/dist/cli.d.ts +19 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +174 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/clipboard.d.ts +17 -0
  16. package/dist/clipboard.d.ts.map +1 -0
  17. package/dist/clipboard.js +47 -0
  18. package/dist/clipboard.js.map +1 -0
  19. package/dist/emoji.d.ts +25 -0
  20. package/dist/emoji.d.ts.map +1 -0
  21. package/dist/emoji.js +180 -0
  22. package/dist/emoji.js.map +1 -0
  23. package/dist/fonts.d.ts +26 -0
  24. package/dist/fonts.d.ts.map +1 -0
  25. package/dist/fonts.js +551 -0
  26. package/dist/fonts.js.map +1 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +108 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/output.d.ts +26 -0
  32. package/dist/output.d.ts.map +1 -0
  33. package/dist/output.js +113 -0
  34. package/dist/output.js.map +1 -0
  35. package/dist/renderer.d.ts +18 -0
  36. package/dist/renderer.d.ts.map +1 -0
  37. package/dist/renderer.js +247 -0
  38. package/dist/renderer.js.map +1 -0
  39. package/dist/slack.d.ts +35 -0
  40. package/dist/slack.d.ts.map +1 -0
  41. package/dist/slack.js +129 -0
  42. package/dist/slack.js.map +1 -0
  43. package/dist/themes.d.ts +31 -0
  44. package/dist/themes.d.ts.map +1 -0
  45. package/dist/themes.js +84 -0
  46. package/dist/themes.js.map +1 -0
  47. package/dist/types.d.ts +113 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +5 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +57 -0
package/dist/cli.js ADDED
@@ -0,0 +1,174 @@
1
+ /**
2
+ * CLI module
3
+ * Handles command line argument parsing
4
+ */
5
+ import { Command } from 'commander';
6
+ import fs from 'fs/promises';
7
+ import { DEFAULT_FONT_NAME } from './fonts.js';
8
+ /**
9
+ * Valid emoji modes
10
+ */
11
+ const VALID_MODES = [
12
+ 'random',
13
+ 'row',
14
+ 'column',
15
+ 'row-gradient',
16
+ 'column-gradient',
17
+ ];
18
+ /**
19
+ * Valid output formats
20
+ */
21
+ const VALID_FORMATS = ['text', 'slack'];
22
+ /**
23
+ * Valid themes
24
+ */
25
+ const VALID_THEMES = ['default', 'github'];
26
+ /**
27
+ * Create and configure the CLI program
28
+ */
29
+ export function createCLI() {
30
+ const program = new Command();
31
+ program
32
+ .name('emoji-banner')
33
+ .description('Convert text to emoji banner art for CLI display\n\n' +
34
+ 'Examples:\n' +
35
+ ' $ emoji-banner "Hello" -e 🔥\n' +
36
+ ' $ emoji-banner "World" -e fire\n' +
37
+ ' $ emoji-banner "Test" -e "🔥,⭐,💎" -m row-gradient\n' +
38
+ ' $ emoji-banner "GitHub" --theme github\n' +
39
+ ' $ emoji-banner "Slack" -e 🎉 --format slack')
40
+ .version('1.0.0')
41
+ .argument('[text]', 'Text to convert to emoji banner')
42
+ .option('-e, --emoji <emoji>', 'Emoji to use (can be emoji or alias, comma-separated for multiple)', '🔥')
43
+ .option('-b, --background <emoji>', 'Background emoji (default: space)')
44
+ .option('-f, --file <path>', 'Read text from file instead of argument')
45
+ .option('-c, --copy', 'Copy result to clipboard')
46
+ .option('--format <format>', 'Output format (text, slack)', 'text')
47
+ .option('--theme <theme>', 'Theme to use (default, github)', 'default')
48
+ .option('-m, --mode <mode>', 'Emoji selection mode when multiple emojis provided (random, row, column, row-gradient, column-gradient)', 'random')
49
+ .option('--font <font>', 'Pixel font to use', DEFAULT_FONT_NAME)
50
+ .option('--border [emoji]', 'Add an outer border. Emoji optional; defaults to the background emoji when omitted.')
51
+ .addHelpText('after', `
52
+ Emoji Input:
53
+ You can specify emojis in several ways:
54
+ - Direct emoji: 🔥, ⭐, 💎
55
+ - Alias with colons: :fire:, :star:
56
+ - Alias without colons: fire, star
57
+ - Multiple emojis (comma-separated): 🔥,⭐,💎 or fire,star,gem
58
+
59
+ Emoji Modes (when multiple emojis provided):
60
+ - random: Random emoji for each dot
61
+ - row: Different emoji per row
62
+ - column: Different emoji per column
63
+ - row-gradient: Gradient across rows
64
+ - column-gradient: Gradient across columns
65
+
66
+ Themes:
67
+ - default: Uses the specified emoji(s)
68
+ - github: GitHub contribution graph style with green squares
69
+
70
+ Output Formats:
71
+ - text: Plain text (default)
72
+ - slack: Slack Block Kit JSON format
73
+ `);
74
+ return program;
75
+ }
76
+ /**
77
+ * Parse and validate CLI options
78
+ */
79
+ export async function parseCLIOptions(program) {
80
+ const opts = program.opts();
81
+ const args = program.args;
82
+ // Get text from argument or file
83
+ let text = args[0];
84
+ if (opts.file) {
85
+ // Read from file
86
+ text = await readTextFromFile(opts.file);
87
+ }
88
+ // Validate mode
89
+ const mode = opts.mode;
90
+ if (!VALID_MODES.includes(mode)) {
91
+ throw new Error(`Invalid mode: ${mode}. Valid modes are: ${VALID_MODES.join(', ')}`);
92
+ }
93
+ // Validate format
94
+ const format = opts.format;
95
+ if (!VALID_FORMATS.includes(format)) {
96
+ throw new Error(`Invalid format: ${format}. Valid formats are: ${VALID_FORMATS.join(', ')}`);
97
+ }
98
+ // Validate theme
99
+ const theme = opts.theme;
100
+ if (!VALID_THEMES.includes(theme)) {
101
+ throw new Error(`Invalid theme: ${theme}. Valid themes are: ${VALID_THEMES.join(', ')}`);
102
+ }
103
+ return {
104
+ text,
105
+ file: opts.file,
106
+ emoji: opts.emoji,
107
+ background: opts.background,
108
+ copy: opts.copy || false,
109
+ format,
110
+ theme,
111
+ mode,
112
+ font: opts.font,
113
+ border: opts.border,
114
+ };
115
+ }
116
+ /**
117
+ * Read text from file with validation
118
+ */
119
+ async function readTextFromFile(filePath) {
120
+ // Validate file path
121
+ if (!filePath || typeof filePath !== 'string') {
122
+ throw new Error('Invalid file path');
123
+ }
124
+ // Check for path traversal attempts
125
+ if (filePath.includes('..')) {
126
+ throw new Error('Path traversal not allowed');
127
+ }
128
+ try {
129
+ // Check file exists and is readable
130
+ await fs.access(filePath, fs.constants.R_OK);
131
+ // Get file stats
132
+ const stats = await fs.stat(filePath);
133
+ // Limit file size (1MB max)
134
+ const maxSize = 1024 * 1024;
135
+ if (stats.size > maxSize) {
136
+ throw new Error(`File too large. Maximum size is ${maxSize} bytes`);
137
+ }
138
+ // Read file content
139
+ const content = await fs.readFile(filePath, 'utf-8');
140
+ // Return trimmed content
141
+ return content.trim();
142
+ }
143
+ catch (error) {
144
+ if (error instanceof Error) {
145
+ if (error.message.includes('ENOENT')) {
146
+ throw new Error(`File not found: ${filePath}`);
147
+ }
148
+ if (error.message.includes('EACCES')) {
149
+ throw new Error(`Permission denied: ${filePath}`);
150
+ }
151
+ throw error;
152
+ }
153
+ throw new Error(`Failed to read file: ${filePath}`);
154
+ }
155
+ }
156
+ /**
157
+ * Validate that required options are provided
158
+ */
159
+ export function validateOptions(options) {
160
+ if (!options.text && !options.file) {
161
+ throw new Error('Text is required. Provide text as an argument or use --file option.\n' +
162
+ 'Run with --help for usage information.');
163
+ }
164
+ if (!options.emoji) {
165
+ throw new Error('Emoji is required. Use --emoji option.');
166
+ }
167
+ if (options.border) {
168
+ const backgroundProvided = Boolean(options.background) || options.theme === 'github';
169
+ if (!backgroundProvided) {
170
+ throw new Error('Border requires a background emoji. Specify --background <emoji>.');
171
+ }
172
+ }
173
+ }
174
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Clipboard module
3
+ * Handles copying text to system clipboard
4
+ */
5
+ /**
6
+ * Copy text to clipboard
7
+ */
8
+ export declare function copyToClipboard(text: string): Promise<void>;
9
+ /**
10
+ * Read from clipboard (for testing purposes)
11
+ */
12
+ export declare function readFromClipboard(): Promise<string>;
13
+ /**
14
+ * Check if clipboard is available
15
+ */
16
+ export declare function isClipboardAvailable(): Promise<boolean>;
17
+ //# sourceMappingURL=clipboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clipboard.d.ts","sourceRoot":"","sources":["../src/clipboard.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYjE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAOzD;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAQ7D"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Clipboard module
3
+ * Handles copying text to system clipboard
4
+ */
5
+ import clipboardy from 'clipboardy';
6
+ /**
7
+ * Copy text to clipboard
8
+ */
9
+ export async function copyToClipboard(text) {
10
+ if (!text || typeof text !== 'string') {
11
+ throw new Error('Invalid text for clipboard');
12
+ }
13
+ try {
14
+ await clipboardy.write(text);
15
+ }
16
+ catch (error) {
17
+ // Handle clipboard access errors gracefully
18
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
19
+ throw new Error(`Failed to copy to clipboard: ${errorMessage}`);
20
+ }
21
+ }
22
+ /**
23
+ * Read from clipboard (for testing purposes)
24
+ */
25
+ export async function readFromClipboard() {
26
+ try {
27
+ return await clipboardy.read();
28
+ }
29
+ catch (error) {
30
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
31
+ throw new Error(`Failed to read from clipboard: ${errorMessage}`);
32
+ }
33
+ }
34
+ /**
35
+ * Check if clipboard is available
36
+ */
37
+ export async function isClipboardAvailable() {
38
+ try {
39
+ // Try to read clipboard - this will fail if not available
40
+ await clipboardy.read();
41
+ return true;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ //# sourceMappingURL=clipboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../src/clipboard.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,4CAA4C;QAC5C,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,gCAAgC,YAAY,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC;QACH,OAAO,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,kCAAkC,YAAY,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC;QACH,0DAA0D;QAC1D,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Emoji handling module
3
+ * Resolves emoji aliases and handles direct emoji input
4
+ */
5
+ /**
6
+ * Resolve an emoji input to an actual emoji character
7
+ * Supports:
8
+ * - Direct emoji: 🔥
9
+ * - Alias with colons: :fire:
10
+ * - Alias without colons: fire
11
+ */
12
+ export declare function resolveEmoji(input: string): string;
13
+ /**
14
+ * Parse comma-separated emoji input into array of resolved emojis
15
+ */
16
+ export declare function parseEmojis(input: string): string[];
17
+ /**
18
+ * Get a default background emoji (empty space with proper width)
19
+ */
20
+ export declare function getBackgroundEmoji(): string;
21
+ /**
22
+ * Validate that the resolved emoji is valid
23
+ */
24
+ export declare function validateEmoji(emoji: string): boolean;
25
+ //# sourceMappingURL=emoji.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emoji.d.ts","sourceRoot":"","sources":["../src/emoji.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA6GH;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CA6ClD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAYnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAG3C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD"}
package/dist/emoji.js ADDED
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Emoji handling module
3
+ * Resolves emoji aliases and handles direct emoji input
4
+ */
5
+ import * as nodeEmoji from 'node-emoji';
6
+ // Common emoji aliases mapping (subset for fallback)
7
+ const CUSTOM_ALIASES = {
8
+ // Colored squares for themes
9
+ 'green_square': '🟩',
10
+ 'white_square': '⬜',
11
+ 'black_square': '⬛',
12
+ 'red_square': '🟥',
13
+ 'blue_square': '🟦',
14
+ 'yellow_square': '🟨',
15
+ 'orange_square': '🟧',
16
+ 'purple_square': '🟪',
17
+ 'brown_square': '🟫',
18
+ // Common emojis
19
+ 'star': '⭐',
20
+ 'fire': '🔥',
21
+ 'heart': '❤️',
22
+ 'smile': '😊',
23
+ 'rocket': '🚀',
24
+ 'check': '✅',
25
+ 'x': '❌',
26
+ 'warning': '⚠️',
27
+ 'sparkles': '✨',
28
+ 'thumbsup': '👍',
29
+ 'thumbs_up': '👍',
30
+ 'clap': '👏',
31
+ 'wave': '👋',
32
+ 'eyes': '👀',
33
+ 'thinking': '🤔',
34
+ 'party': '🎉',
35
+ 'tada': '🎉',
36
+ 'sun': '☀️',
37
+ 'moon': '🌙',
38
+ 'cloud': '☁️',
39
+ 'rain': '🌧️',
40
+ 'snow': '❄️',
41
+ 'tree': '🌳',
42
+ 'flower': '🌸',
43
+ 'muscle': '💪',
44
+ 'coffee': '☕',
45
+ 'beer': '🍺',
46
+ 'pizza': '🍕',
47
+ 'apple': '🍎',
48
+ 'banana': '🍌',
49
+ 'cat': '🐱',
50
+ 'dog': '🐶',
51
+ 'bird': '🐦',
52
+ 'fish': '🐟',
53
+ 'bug': '🐛',
54
+ 'ghost': '👻',
55
+ 'alien': '👽',
56
+ 'robot': '🤖',
57
+ 'skull': '💀',
58
+ 'poop': '💩',
59
+ '100': '💯',
60
+ 'money': '💰',
61
+ 'gem': '💎',
62
+ 'crown': '👑',
63
+ 'trophy': '🏆',
64
+ 'medal': '🏅',
65
+ 'flag': '🚩',
66
+ 'pin': '📌',
67
+ 'bell': '🔔',
68
+ 'key': '🔑',
69
+ 'lock': '🔒',
70
+ 'bulb': '💡',
71
+ 'book': '📚',
72
+ 'pencil': '✏️',
73
+ 'scissors': '✂️',
74
+ 'hammer': '🔨',
75
+ 'wrench': '🔧',
76
+ 'gear': '⚙️',
77
+ 'link': '🔗',
78
+ 'bomb': '💣',
79
+ 'zap': '⚡',
80
+ 'dizzy': '💫',
81
+ 'boom': '💥',
82
+ 'droplet': '💧',
83
+ 'leaves': '🍃',
84
+ 'cactus': '🌵',
85
+ 'palm': '🌴',
86
+ 'maple': '🍁',
87
+ 'cherry_blossom': '🌸',
88
+ 'rose': '🌹',
89
+ 'tulip': '🌷',
90
+ 'sunflower': '🌻',
91
+ };
92
+ /**
93
+ * Check if a string is an emoji (contains emoji characters)
94
+ */
95
+ function isEmoji(str) {
96
+ // Emoji regex pattern - covers most common emoji ranges
97
+ const emojiRegex = /[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]|[\u{1F600}-\u{1F64F}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]|[\u{2300}-\u{23FF}]|[\u{2B50}]|[\u{2934}-\u{2935}]|[\u{25AA}-\u{25AB}]|[\u{25B6}]|[\u{25C0}]|[\u{25FB}-\u{25FE}]|[\u{2614}-\u{2615}]|[\u{2648}-\u{2653}]|[\u{267F}]|[\u{2693}]|[\u{26A1}]|[\u{26AA}-\u{26AB}]|[\u{26BD}-\u{26BE}]|[\u{26C4}-\u{26C5}]|[\u{26CE}]|[\u{26D4}]|[\u{26EA}]|[\u{26F2}-\u{26F3}]|[\u{26F5}]|[\u{26FA}]|[\u{26FD}]|[\u{2702}]|[\u{2705}]|[\u{2708}-\u{270D}]|[\u{270F}]|[\u{2712}]|[\u{2714}]|[\u{2716}]|[\u{271D}]|[\u{2721}]|[\u{2728}]|[\u{2733}-\u{2734}]|[\u{2744}]|[\u{2747}]|[\u{274C}]|[\u{274E}]|[\u{2753}-\u{2755}]|[\u{2757}]|[\u{2763}-\u{2764}]|[\u{2795}-\u{2797}]|[\u{27A1}]|[\u{27B0}]|[\u{27BF}]|[\u{2B05}-\u{2B07}]|[\u{2B1B}-\u{2B1C}]|[\u{2B55}]|[\u{3030}]|[\u{303D}]|[\u{3297}]|[\u{3299}]|[\u{FE00}-\u{FE0F}]|[\u{200D}]/u;
98
+ return emojiRegex.test(str);
99
+ }
100
+ /**
101
+ * Remove colons from alias if present
102
+ * :fire: -> fire
103
+ * fire -> fire
104
+ */
105
+ function normalizeAlias(alias) {
106
+ return alias.replace(/^:/, '').replace(/:$/, '').trim();
107
+ }
108
+ /**
109
+ * Resolve an emoji input to an actual emoji character
110
+ * Supports:
111
+ * - Direct emoji: 🔥
112
+ * - Alias with colons: :fire:
113
+ * - Alias without colons: fire
114
+ */
115
+ export function resolveEmoji(input) {
116
+ const trimmed = input.trim();
117
+ // If it's already an emoji, return as is
118
+ if (isEmoji(trimmed)) {
119
+ return trimmed;
120
+ }
121
+ // Normalize the alias (remove colons if present)
122
+ const alias = normalizeAlias(trimmed);
123
+ // Try node-emoji first
124
+ const resolved = nodeEmoji.get(alias);
125
+ if (resolved && resolved !== `:${alias}:`) {
126
+ return resolved;
127
+ }
128
+ // Try custom aliases
129
+ if (CUSTOM_ALIASES[alias]) {
130
+ return CUSTOM_ALIASES[alias];
131
+ }
132
+ // Try with underscores replaced by different variations
133
+ const variations = [
134
+ alias,
135
+ alias.replace(/-/g, '_'),
136
+ alias.replace(/_/g, '-'),
137
+ alias.toLowerCase(),
138
+ alias.toUpperCase(),
139
+ ];
140
+ for (const variant of variations) {
141
+ const result = nodeEmoji.get(variant);
142
+ if (result && result !== `:${variant}:`) {
143
+ return result;
144
+ }
145
+ if (CUSTOM_ALIASES[variant]) {
146
+ return CUSTOM_ALIASES[variant];
147
+ }
148
+ }
149
+ // If nothing found, return the input (it might be a custom character)
150
+ // But warn the user
151
+ console.warn(`Warning: Could not resolve emoji "${input}", using as-is`);
152
+ return trimmed;
153
+ }
154
+ /**
155
+ * Parse comma-separated emoji input into array of resolved emojis
156
+ */
157
+ export function parseEmojis(input) {
158
+ if (!input || typeof input !== 'string') {
159
+ throw new Error('Emoji input is required');
160
+ }
161
+ const parts = input.split(',').map((s) => s.trim()).filter(Boolean);
162
+ if (parts.length === 0) {
163
+ throw new Error('At least one emoji is required');
164
+ }
165
+ return parts.map(resolveEmoji);
166
+ }
167
+ /**
168
+ * Get a default background emoji (empty space with proper width)
169
+ */
170
+ export function getBackgroundEmoji() {
171
+ // Use a full-width space to keep alignment when no background is provided
172
+ return ' ';
173
+ }
174
+ /**
175
+ * Validate that the resolved emoji is valid
176
+ */
177
+ export function validateEmoji(emoji) {
178
+ return emoji.length > 0;
179
+ }
180
+ //# sourceMappingURL=emoji.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emoji.js","sourceRoot":"","sources":["../src/emoji.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Pixel font definitions for rendering text into bitmaps.
3
+ * Each character is represented by a 2D pattern using # for filled pixels.
4
+ */
5
+ export interface PixelFont {
6
+ /** Font name */
7
+ name: string;
8
+ /** Number of rows in each character */
9
+ height: number;
10
+ /** Spaces between characters */
11
+ letterSpacing: number;
12
+ /** Spaces between lines */
13
+ lineSpacing: number;
14
+ /** Character bitmap patterns */
15
+ map: Record<string, string[]>;
16
+ }
17
+ export declare const DEFAULT_FONT_NAME = "block";
18
+ /**
19
+ * Retrieve a font by name. Falls back to default if not found.
20
+ */
21
+ export declare function getFont(name?: string): PixelFont;
22
+ /**
23
+ * List available font names.
24
+ */
25
+ export declare function getAvailableFonts(): string[];
26
+ //# sourceMappingURL=fonts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,SAAS;IACxB,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC/B;AAED,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAyhBzC;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,GAAE,MAA0B,GAAG,SAAS,CAEnE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAE5C"}