@ignaciocabeza/bitface 1.0.0 → 1.0.1

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.
@@ -1,1099 +0,0 @@
1
- // src/renderer/palette.ts
2
- var SKIN_PRESETS = {
3
- light: "#FDDCB5",
4
- medium: "#E8B88A",
5
- tan: "#D19A6A",
6
- brown: "#A0673C",
7
- dark: "#6B4226",
8
- pale: "#FFF0E0"
9
- };
10
- var SKIN_SHADOW_MAP = {
11
- "#FDDCB5": "#E5C49D",
12
- "#E8B88A": "#CFA072",
13
- "#D19A6A": "#B98252",
14
- "#A0673C": "#885524",
15
- "#6B4226": "#533010",
16
- "#FFF0E0": "#E7D8C8"
17
- };
18
- var HAIR_PRESETS = {
19
- black: "#1A1A2E",
20
- brown: "#6B3A2A",
21
- blonde: "#E8C84A",
22
- red: "#B83A1E",
23
- gray: "#9E9E9E",
24
- white: "#E8E8E8",
25
- auburn: "#8B3A1A",
26
- strawberry: "#D4713A",
27
- platinum: "#E8E0D0",
28
- pink: "#E8559E",
29
- blue: "#3A6BD5",
30
- purple: "#6B3A8B",
31
- teal: "#2A9E8B"
32
- };
33
- var EYE_PRESETS = {
34
- brown: "#5C3A1E",
35
- blue: "#3A7BD5",
36
- green: "#3A9D5C",
37
- gray: "#7A7A7A"
38
- };
39
- var HEX_COLOR_RE = /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
40
- function sanitizeColor(value, fallback) {
41
- if (HEX_COLOR_RE.test(value)) return value;
42
- return fallback;
43
- }
44
- function resolveSkinColor(value) {
45
- if (!value) return SKIN_PRESETS.medium;
46
- return SKIN_PRESETS[value] ?? sanitizeColor(value, SKIN_PRESETS.medium);
47
- }
48
- function resolveSkinShadow(skinHex) {
49
- return SKIN_SHADOW_MAP[skinHex] ?? darken(skinHex, 30);
50
- }
51
- function resolveHairColor(value) {
52
- if (!value) return HAIR_PRESETS.black;
53
- return HAIR_PRESETS[value] ?? sanitizeColor(value, HAIR_PRESETS.black);
54
- }
55
- function resolveEyeColor(value) {
56
- if (!value) return EYE_PRESETS.brown;
57
- return EYE_PRESETS[value] ?? sanitizeColor(value, EYE_PRESETS.brown);
58
- }
59
- function darken(hex, amount) {
60
- const num = parseInt(hex.replace("#", ""), 16);
61
- const r = Math.max(0, (num >> 16) - amount);
62
- const g = Math.max(0, (num >> 8 & 255) - amount);
63
- const b = Math.max(0, (num & 255) - amount);
64
- return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0").toUpperCase()}`;
65
- }
66
-
67
- // src/renderer/parts/face-shapes.ts
68
- var faceShapes = {
69
- round: {
70
- pixels: [
71
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
72
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
73
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
74
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
75
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
76
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
77
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
78
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
79
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
80
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
81
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
82
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
83
- ],
84
- slotMap: { 1: "skin", 2: "skinShadow" },
85
- offsetX: 0,
86
- offsetY: 3
87
- },
88
- oval: {
89
- pixels: [
90
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
91
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
92
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
93
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
94
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
95
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
96
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
97
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
98
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
99
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
100
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
101
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
102
- ],
103
- slotMap: { 1: "skin", 2: "skinShadow" },
104
- offsetX: 0,
105
- offsetY: 3
106
- },
107
- square: {
108
- pixels: [
109
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
110
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
111
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
112
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
113
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
114
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
115
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
116
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
117
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
118
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
119
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
120
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
121
- ],
122
- slotMap: { 1: "skin", 2: "skinShadow" },
123
- offsetX: 0,
124
- offsetY: 3
125
- },
126
- heart: {
127
- pixels: [
128
- [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
129
- [0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0],
130
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
131
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
132
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
133
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
134
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
135
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
136
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
137
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
138
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
139
- [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]
140
- ],
141
- slotMap: { 1: "skin", 2: "skinShadow" },
142
- offsetX: 0,
143
- offsetY: 3
144
- },
145
- long: {
146
- pixels: [
147
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
148
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
149
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
150
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
151
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
152
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
153
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
154
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
155
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
156
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
157
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
158
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
159
- [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]
160
- ],
161
- slotMap: { 1: "skin", 2: "skinShadow" },
162
- offsetX: 0,
163
- offsetY: 2
164
- },
165
- diamond: {
166
- pixels: [
167
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
168
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
169
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
170
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
171
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
172
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
173
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
174
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
175
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
176
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
177
- [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]
178
- ],
179
- slotMap: { 1: "skin", 2: "skinShadow" },
180
- offsetX: 0,
181
- offsetY: 3
182
- },
183
- wide: {
184
- pixels: [
185
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
186
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
187
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
188
- [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
189
- [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
190
- [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
191
- [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
192
- [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
193
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
194
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
195
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
196
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
197
- ],
198
- slotMap: { 1: "skin", 2: "skinShadow" },
199
- offsetX: 0,
200
- offsetY: 3
201
- }
202
- };
203
- var face_shapes_default = faceShapes;
204
-
205
- // src/renderer/parts/eyes.ts
206
- var eyes = {
207
- big: {
208
- pixels: [
209
- [1, 1, 0, 0, 0, 0, 1, 1],
210
- [1, 2, 1, 0, 0, 1, 2, 1],
211
- [1, 2, 3, 0, 0, 1, 2, 3],
212
- [1, 1, 0, 0, 0, 0, 1, 1]
213
- ],
214
- slotMap: { 1: "white", 2: "eyes", 3: "pupil" },
215
- offsetX: 4,
216
- offsetY: 7
217
- },
218
- small: {
219
- pixels: [
220
- [0, 2, 0, 0, 0, 0, 2, 0],
221
- [0, 3, 0, 0, 0, 0, 3, 0]
222
- ],
223
- slotMap: { 2: "eyes", 3: "pupil" },
224
- offsetX: 4,
225
- offsetY: 8
226
- },
227
- narrow: {
228
- pixels: [
229
- [1, 2, 3, 0, 0, 1, 2, 3]
230
- ],
231
- slotMap: { 1: "white", 2: "eyes", 3: "pupil" },
232
- offsetX: 4,
233
- offsetY: 8
234
- },
235
- round: {
236
- pixels: [
237
- [0, 1, 0, 0, 0, 0, 1, 0],
238
- [1, 2, 1, 0, 0, 1, 2, 1],
239
- [1, 2, 3, 0, 0, 1, 2, 3],
240
- [0, 1, 0, 0, 0, 0, 1, 0]
241
- ],
242
- slotMap: { 1: "white", 2: "eyes", 3: "pupil" },
243
- offsetX: 4,
244
- offsetY: 7
245
- },
246
- wink: {
247
- pixels: [
248
- [1, 1, 0, 0, 0, 0, 0, 0],
249
- [1, 2, 1, 0, 0, 0, 0, 0],
250
- [1, 2, 3, 0, 0, 3, 3, 3],
251
- [1, 1, 0, 0, 0, 0, 0, 0]
252
- ],
253
- slotMap: { 1: "white", 2: "eyes", 3: "pupil" },
254
- offsetX: 4,
255
- offsetY: 7
256
- },
257
- happy: {
258
- pixels: [
259
- [0, 3, 3, 0, 0, 0, 3, 3],
260
- [3, 0, 0, 0, 0, 3, 0, 0]
261
- ],
262
- slotMap: { 3: "pupil" },
263
- offsetX: 4,
264
- offsetY: 8
265
- },
266
- angry: {
267
- pixels: [
268
- [1, 1, 0, 0, 0, 0, 1, 1],
269
- [1, 2, 3, 0, 0, 3, 2, 1],
270
- [0, 1, 1, 0, 0, 1, 1, 0]
271
- ],
272
- slotMap: { 1: "white", 2: "eyes", 3: "pupil" },
273
- offsetX: 4,
274
- offsetY: 7
275
- },
276
- dots: {
277
- pixels: [
278
- [0, 0, 3, 0, 0, 0, 0, 3]
279
- ],
280
- slotMap: { 3: "pupil" },
281
- offsetX: 4,
282
- offsetY: 9
283
- },
284
- sleepy: {
285
- pixels: [
286
- [1, 1, 0, 0, 0, 0, 1, 1],
287
- [3, 3, 0, 0, 0, 0, 3, 3]
288
- ],
289
- slotMap: { 1: "white", 3: "pupil" },
290
- offsetX: 4,
291
- offsetY: 8
292
- },
293
- cross: {
294
- pixels: [
295
- [3, 0, 3, 0, 0, 3, 0, 3],
296
- [0, 3, 0, 0, 0, 0, 3, 0],
297
- [3, 0, 3, 0, 0, 3, 0, 3]
298
- ],
299
- slotMap: { 3: "pupil" },
300
- offsetX: 4,
301
- offsetY: 7
302
- },
303
- heart: {
304
- pixels: [
305
- [2, 0, 2, 0, 0, 2, 0, 2],
306
- [2, 2, 2, 0, 0, 2, 2, 2],
307
- [0, 2, 0, 0, 0, 0, 2, 0]
308
- ],
309
- slotMap: { 2: "eyes" },
310
- offsetX: 4,
311
- offsetY: 7
312
- }
313
- };
314
- var eyes_default = eyes;
315
-
316
- // src/renderer/parts/eyebrows.ts
317
- var eyebrows = {
318
- thick: {
319
- pixels: [
320
- [1, 1, 1, 0, 0, 1, 1, 1],
321
- [1, 1, 1, 0, 0, 1, 1, 1]
322
- ],
323
- slotMap: { 1: "hair" },
324
- offsetX: 4,
325
- offsetY: 6
326
- },
327
- thin: {
328
- pixels: [
329
- [1, 1, 1, 0, 0, 1, 1, 1]
330
- ],
331
- slotMap: { 1: "hair" },
332
- offsetX: 4,
333
- offsetY: 6
334
- },
335
- arched: {
336
- pixels: [
337
- [0, 1, 1, 0, 0, 0, 1, 1],
338
- [1, 0, 0, 0, 0, 1, 0, 0]
339
- ],
340
- slotMap: { 1: "hair" },
341
- offsetX: 4,
342
- offsetY: 5
343
- },
344
- angry: {
345
- pixels: [
346
- [1, 0, 0, 0, 0, 0, 0, 1],
347
- [0, 1, 1, 0, 0, 1, 1, 0]
348
- ],
349
- slotMap: { 1: "hair" },
350
- offsetX: 4,
351
- offsetY: 5
352
- },
353
- worried: {
354
- pixels: [
355
- [0, 0, 1, 0, 0, 1, 0, 0],
356
- [0, 1, 0, 0, 0, 0, 1, 0]
357
- ],
358
- slotMap: { 1: "hair" },
359
- offsetX: 4,
360
- offsetY: 5
361
- },
362
- unibrow: {
363
- pixels: [
364
- [1, 1, 1, 1, 1, 1, 1, 1],
365
- [1, 1, 0, 0, 0, 0, 1, 1]
366
- ],
367
- slotMap: { 1: "hair" },
368
- offsetX: 4,
369
- offsetY: 5
370
- },
371
- none: {
372
- pixels: [],
373
- slotMap: {},
374
- offsetX: 0,
375
- offsetY: 0
376
- }
377
- };
378
- var eyebrows_default = eyebrows;
379
-
380
- // src/renderer/parts/mouth.ts
381
- var mouth = {
382
- smile: {
383
- pixels: [
384
- [1, 0, 0, 0, 0, 1],
385
- [0, 1, 1, 1, 1, 0]
386
- ],
387
- slotMap: { 1: "mouth" },
388
- offsetX: 5,
389
- offsetY: 12
390
- },
391
- frown: {
392
- pixels: [
393
- [0, 1, 1, 1, 1, 0],
394
- [1, 0, 0, 0, 0, 1]
395
- ],
396
- slotMap: { 1: "mouth" },
397
- offsetX: 5,
398
- offsetY: 12
399
- },
400
- open: {
401
- pixels: [
402
- [0, 1, 1, 1, 1, 0],
403
- [1, 1, 1, 1, 1, 1],
404
- [0, 1, 1, 1, 1, 0]
405
- ],
406
- slotMap: { 1: "mouth" },
407
- offsetX: 5,
408
- offsetY: 11
409
- },
410
- flat: {
411
- pixels: [
412
- [1, 1, 1, 1, 1, 1]
413
- ],
414
- slotMap: { 1: "mouth" },
415
- offsetX: 5,
416
- offsetY: 12
417
- },
418
- teeth: {
419
- pixels: [
420
- [0, 1, 1, 1, 1, 0],
421
- [0, 2, 2, 2, 2, 0],
422
- [0, 1, 1, 1, 1, 0]
423
- ],
424
- slotMap: { 1: "mouth", 2: "white" },
425
- offsetX: 5,
426
- offsetY: 11
427
- },
428
- smirk: {
429
- pixels: [
430
- [0, 0, 0, 0, 1, 0],
431
- [0, 1, 1, 1, 0, 0]
432
- ],
433
- slotMap: { 1: "mouth" },
434
- offsetX: 5,
435
- offsetY: 12
436
- },
437
- grin: {
438
- pixels: [
439
- [0, 1, 1, 1, 1, 1, 1, 0],
440
- [0, 1, 2, 2, 2, 2, 1, 0],
441
- [0, 0, 1, 1, 1, 1, 0, 0]
442
- ],
443
- slotMap: { 1: "mouth", 2: "white" },
444
- offsetX: 4,
445
- offsetY: 11
446
- },
447
- tongue: {
448
- pixels: [
449
- [0, 1, 1, 1, 1, 0],
450
- [0, 0, 1, 1, 0, 0],
451
- [0, 0, 0, 1, 0, 0]
452
- ],
453
- slotMap: { 1: "mouth" },
454
- offsetX: 5,
455
- offsetY: 12
456
- },
457
- oh: {
458
- pixels: [
459
- [0, 1, 1, 0],
460
- [1, 0, 0, 1],
461
- [0, 1, 1, 0]
462
- ],
463
- slotMap: { 1: "mouth" },
464
- offsetX: 6,
465
- offsetY: 11
466
- }
467
- };
468
- var mouth_default = mouth;
469
-
470
- // src/renderer/parts/nose.ts
471
- var nose = {
472
- small: {
473
- pixels: [
474
- [0, 1, 0],
475
- [1, 0, 1]
476
- ],
477
- slotMap: { 1: "skinShadow" },
478
- offsetX: 7,
479
- offsetY: 10
480
- },
481
- pointy: {
482
- pixels: [
483
- [0, 1, 0],
484
- [0, 1, 0],
485
- [1, 0, 1]
486
- ],
487
- slotMap: { 1: "skinShadow" },
488
- offsetX: 7,
489
- offsetY: 9
490
- },
491
- wide: {
492
- pixels: [
493
- [0, 1, 1, 0],
494
- [1, 0, 0, 1],
495
- [1, 0, 0, 1]
496
- ],
497
- slotMap: { 1: "skinShadow" },
498
- offsetX: 6,
499
- offsetY: 9
500
- },
501
- button: {
502
- pixels: [
503
- [1, 1]
504
- ],
505
- slotMap: { 1: "skinShadow" },
506
- offsetX: 7,
507
- offsetY: 10
508
- },
509
- long: {
510
- pixels: [
511
- [0, 1, 0],
512
- [0, 1, 0],
513
- [0, 1, 0],
514
- [1, 0, 1]
515
- ],
516
- slotMap: { 1: "skinShadow" },
517
- offsetX: 7,
518
- offsetY: 8
519
- },
520
- snub: {
521
- pixels: [
522
- [0, 1],
523
- [1, 1]
524
- ],
525
- slotMap: { 1: "skinShadow" },
526
- offsetX: 7,
527
- offsetY: 10
528
- }
529
- };
530
- var nose_default = nose;
531
-
532
- // src/renderer/parts/ears.ts
533
- var ears = {
534
- small: {
535
- pixels: [
536
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
537
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
538
- [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]
539
- ],
540
- slotMap: { 1: "skin", 2: "skinShadow" },
541
- offsetX: 0,
542
- offsetY: 8
543
- },
544
- big: {
545
- pixels: [
546
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
547
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
548
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
549
- [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
550
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
551
- ],
552
- slotMap: { 1: "skin", 2: "skinShadow" },
553
- offsetX: 0,
554
- offsetY: 7
555
- },
556
- pointed: {
557
- pixels: [
558
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
559
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
560
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
561
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
562
- [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]
563
- ],
564
- slotMap: { 1: "skin", 2: "skinShadow" },
565
- offsetX: 0,
566
- offsetY: 5
567
- },
568
- elf: {
569
- pixels: [
570
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
571
- [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
572
- [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
573
- [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
574
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
575
- [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]
576
- ],
577
- slotMap: { 1: "skin", 2: "skinShadow" },
578
- offsetX: 0,
579
- offsetY: 4
580
- },
581
- none: {
582
- pixels: [],
583
- slotMap: {},
584
- offsetX: 0,
585
- offsetY: 0
586
- }
587
- };
588
- var ears_default = ears;
589
-
590
- // src/renderer/parts/hair.ts
591
- var hair = {
592
- short: {
593
- pixels: [
594
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
595
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
596
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
597
- [0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 0]
598
- ],
599
- slotMap: { 1: "hair", 2: "hairShadow" },
600
- offsetX: 0,
601
- offsetY: 2
602
- },
603
- long: {
604
- pixels: [
605
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
606
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
607
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
608
- [0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 0],
609
- [0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0],
610
- [0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0],
611
- [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
612
- [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
613
- [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
614
- [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
615
- [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
616
- [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
617
- ],
618
- slotMap: { 1: "hair", 2: "hairShadow" },
619
- offsetX: 0,
620
- offsetY: 2
621
- },
622
- curly: {
623
- pixels: [
624
- [0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0],
625
- [0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0],
626
- [0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0],
627
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
628
- [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
629
- [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
630
- [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
631
- [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
632
- [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
633
- ],
634
- slotMap: { 1: "hair", 2: "hairShadow" },
635
- offsetX: 0,
636
- offsetY: 1
637
- },
638
- mohawk: {
639
- pixels: [
640
- [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
641
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
642
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
643
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
644
- [0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0]
645
- ],
646
- slotMap: { 1: "hair", 2: "hairShadow" },
647
- offsetX: 0,
648
- offsetY: 0
649
- },
650
- bald: {
651
- pixels: [],
652
- slotMap: {},
653
- offsetX: 0,
654
- offsetY: 0
655
- },
656
- ponytail: {
657
- pixels: [
658
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
659
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
660
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
661
- [0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 0],
662
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
663
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
664
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
665
- [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
666
- ],
667
- slotMap: { 1: "hair", 2: "hairShadow" },
668
- offsetX: 0,
669
- offsetY: 2
670
- },
671
- spiky: {
672
- pixels: [
673
- [0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0],
674
- [0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0],
675
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
676
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
677
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
678
- [0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 0]
679
- ],
680
- slotMap: { 1: "hair", 2: "hairShadow" },
681
- offsetX: 0,
682
- offsetY: 0
683
- },
684
- bob: {
685
- pixels: [
686
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
687
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
688
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
689
- [0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 0],
690
- [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
691
- [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
692
- [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
693
- [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0]
694
- ],
695
- slotMap: { 1: "hair", 2: "hairShadow" },
696
- offsetX: 0,
697
- offsetY: 2
698
- },
699
- afro: {
700
- pixels: [
701
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
702
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
703
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
704
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
705
- [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
706
- [1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1],
707
- [1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1],
708
- [1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1],
709
- [1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1]
710
- ],
711
- slotMap: { 1: "hair", 2: "hairShadow" },
712
- offsetX: 0,
713
- offsetY: 0
714
- },
715
- bangs: {
716
- pixels: [
717
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
718
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
719
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
720
- [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
721
- [0, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 2, 1, 1, 0]
722
- ],
723
- slotMap: { 1: "hair", 2: "hairShadow" },
724
- offsetX: 0,
725
- offsetY: 2
726
- }
727
- };
728
- var hair_default = hair;
729
-
730
- // src/renderer/parts/beard.ts
731
- var beard = {
732
- stubble: {
733
- // Sparse dots at chin/jaw edge
734
- pixels: [
735
- [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
736
- [0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0]
737
- ],
738
- slotMap: { 1: "hair" },
739
- offsetX: 0,
740
- offsetY: 13
741
- },
742
- goatee: {
743
- // Small chin patch below the mouth
744
- pixels: [
745
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
746
- [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]
747
- ],
748
- slotMap: { 1: "hair" },
749
- offsetX: 0,
750
- offsetY: 13
751
- },
752
- full: {
753
- // Jaw outline: sideburns at edges + solid chin, hollow center so mouth shows
754
- pixels: [
755
- [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
756
- [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
757
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
758
- [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
759
- ],
760
- slotMap: { 1: "hair" },
761
- offsetX: 0,
762
- offsetY: 11
763
- },
764
- mustache: {
765
- // Sits just above the mouth line
766
- pixels: [
767
- [0, 0, 1, 1, 0, 0, 1, 1, 0, 0],
768
- [0, 1, 0, 0, 1, 1, 0, 0, 1, 0]
769
- ],
770
- slotMap: { 1: "hair" },
771
- offsetX: 3,
772
- offsetY: 11
773
- },
774
- handlebar: {
775
- // Wide curling mustache
776
- pixels: [
777
- [0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0],
778
- [0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0],
779
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
780
- ],
781
- slotMap: { 1: "hair" },
782
- offsetX: 2,
783
- offsetY: 11
784
- },
785
- none: {
786
- pixels: [],
787
- slotMap: {},
788
- offsetX: 0,
789
- offsetY: 0
790
- }
791
- };
792
- var beard_default = beard;
793
-
794
- // src/renderer/parts/accessories.ts
795
- var accessories = {
796
- glasses: {
797
- pixels: [
798
- [0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0],
799
- [1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1],
800
- [0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0]
801
- ],
802
- slotMap: { 1: "accessoryPrimary", 3: "lens" },
803
- offsetX: 1,
804
- offsetY: 7
805
- },
806
- sunglasses: {
807
- pixels: [
808
- [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
809
- [1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1],
810
- [0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0]
811
- ],
812
- slotMap: { 1: "accessoryPrimary", 2: "accessorySecondary" },
813
- offsetX: 1,
814
- offsetY: 7
815
- },
816
- hat: {
817
- pixels: [
818
- [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
819
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
820
- [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
821
- [0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0]
822
- ],
823
- slotMap: { 1: "accessoryPrimary", 2: "accessorySecondary" },
824
- offsetX: 0,
825
- offsetY: 0
826
- },
827
- headband: {
828
- pixels: [
829
- [0, 0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 0, 0]
830
- ],
831
- slotMap: { 1: "accessoryPrimary", 2: "accessorySecondary" },
832
- offsetX: 0,
833
- offsetY: 5
834
- },
835
- earrings: {
836
- pixels: [
837
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
838
- [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
839
- ],
840
- slotMap: { 1: "accessoryPrimary" },
841
- offsetX: 0,
842
- offsetY: 11
843
- },
844
- none: {
845
- pixels: [],
846
- slotMap: {},
847
- offsetX: 0,
848
- offsetY: 0
849
- }
850
- };
851
- var accessories_default = accessories;
852
-
853
- // src/renderer/parts/index.ts
854
- var registry = {
855
- faceShape: face_shapes_default,
856
- eyes: eyes_default,
857
- eyebrows: eyebrows_default,
858
- mouth: mouth_default,
859
- nose: nose_default,
860
- ears: ears_default,
861
- hair: hair_default,
862
- beard: beard_default,
863
- accessories: accessories_default
864
- };
865
- function getPart(category, name) {
866
- return registry[category]?.[name];
867
- }
868
- function getVariantNames(category) {
869
- const cat = registry[category];
870
- return cat ? Object.keys(cat) : [];
871
- }
872
- function getAllCategories() {
873
- return Object.keys(registry);
874
- }
875
-
876
- // src/renderer/generator.ts
877
- var BASE_SIZE = 16;
878
- function buildColorMap(config) {
879
- const skin = resolveSkinColor(config.skinColor);
880
- const skinShadow = resolveSkinShadow(skin);
881
- const hairColor = resolveHairColor(config.hairColor);
882
- const eyeColor = resolveEyeColor(config.eyeColor);
883
- return {
884
- skin,
885
- skinShadow,
886
- hair: hairColor,
887
- hairShadow: darkenColor(hairColor, 25),
888
- eyes: eyeColor,
889
- pupil: "#111111",
890
- white: "#FFFFFF",
891
- mouth: "#C75050",
892
- accessoryPrimary: "#333333",
893
- accessorySecondary: "#1A1A1A",
894
- lens: "#87CEEB"
895
- };
896
- }
897
- function darkenColor(hex, amount) {
898
- const num = parseInt(hex.replace("#", ""), 16);
899
- const r = Math.max(0, (num >> 16) - amount);
900
- const g = Math.max(0, (num >> 8 & 255) - amount);
901
- const b = Math.max(0, (num & 255) - amount);
902
- return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0")}`;
903
- }
904
- function stampPart(grid, part, colorMap) {
905
- for (let py = 0; py < part.pixels.length; py++) {
906
- const row = part.pixels[py];
907
- for (let px = 0; px < row.length; px++) {
908
- const slot = row[px];
909
- if (slot === 0) continue;
910
- const role = part.slotMap[slot];
911
- if (!role) continue;
912
- const color = colorMap[role];
913
- if (!color) continue;
914
- const gx = part.offsetX + px;
915
- const gy = part.offsetY + py;
916
- if (gx >= 0 && gx < BASE_SIZE && gy >= 0 && gy < BASE_SIZE) {
917
- grid[gy][gx] = color;
918
- }
919
- }
920
- }
921
- }
922
- var LAYER_ORDER = [
923
- { category: "faceShape", configKey: "faceShape" },
924
- { category: "ears", configKey: "ears" },
925
- { category: "nose", configKey: "nose" },
926
- { category: "mouth", configKey: "mouth" },
927
- { category: "eyes", configKey: "eyes" },
928
- { category: "eyebrows", configKey: "eyebrows" },
929
- { category: "hair", configKey: "hair" },
930
- { category: "beard", configKey: "beard" },
931
- { category: "accessories", configKey: "accessories" }
932
- ];
933
- function generateGrid(config) {
934
- const grid = Array.from(
935
- { length: BASE_SIZE },
936
- () => Array.from({ length: BASE_SIZE }, () => null)
937
- );
938
- const colorMap = buildColorMap(config);
939
- for (const layer of LAYER_ORDER) {
940
- const name = config[layer.configKey];
941
- if (!name || name === "none") continue;
942
- const part = getPart(layer.category, name);
943
- if (!part) continue;
944
- stampPart(grid, part, colorMap);
945
- }
946
- return grid;
947
- }
948
- function generatePartThumbnail(category, name, skinColor, hairColor, eyeColor) {
949
- const grid = Array.from(
950
- { length: BASE_SIZE },
951
- () => Array.from({ length: BASE_SIZE }, () => null)
952
- );
953
- const skin = resolveSkinColor(skinColor);
954
- const colorMap = {
955
- skin,
956
- skinShadow: resolveSkinShadow(skin),
957
- hair: resolveHairColor(hairColor),
958
- hairShadow: darkenColor(resolveHairColor(hairColor), 25),
959
- eyes: resolveEyeColor(eyeColor),
960
- pupil: "#111111",
961
- white: "#FFFFFF",
962
- mouth: "#C75050",
963
- accessoryPrimary: "#333333",
964
- accessorySecondary: "#1A1A1A",
965
- lens: "#87CEEB"
966
- };
967
- const part = getPart(category, name);
968
- if (part) {
969
- stampPart(grid, part, colorMap);
970
- }
971
- return grid;
972
- }
973
-
974
- // src/renderer/svg.ts
975
- function gridToSvg(grid, backgroundColor) {
976
- const height = grid.length;
977
- const width = height > 0 ? grid[0].length : 0;
978
- const raw = backgroundColor ?? "#87CEEB";
979
- const bg = raw === "transparent" ? "transparent" : sanitizeColor(raw, "#87CEEB");
980
- const rects = [];
981
- if (bg !== "transparent") {
982
- rects.push(`<rect width="${width}" height="${height}" fill="${bg}"/>`);
983
- }
984
- for (let y = 0; y < height; y++) {
985
- let x = 0;
986
- while (x < width) {
987
- const color = grid[y][x];
988
- if (color === null) {
989
- x++;
990
- continue;
991
- }
992
- let runLen = 1;
993
- while (x + runLen < width && grid[y][x + runLen] === color) {
994
- runLen++;
995
- }
996
- rects.push(`<rect x="${x}" y="${y}" width="${runLen}" height="1" fill="${color}"/>`);
997
- x += runLen;
998
- }
999
- }
1000
- return [
1001
- `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" shape-rendering="crispEdges">`,
1002
- ...rects,
1003
- "</svg>"
1004
- ].join("");
1005
- }
1006
-
1007
- // src/renderer/index.ts
1008
- function pickRandom(arr) {
1009
- return arr[Math.floor(Math.random() * arr.length)];
1010
- }
1011
- function generateRandomConfig() {
1012
- return {
1013
- faceShape: pickRandom(getVariantNames("faceShape")),
1014
- eyes: pickRandom(getVariantNames("eyes")),
1015
- eyebrows: pickRandom(getVariantNames("eyebrows")),
1016
- mouth: pickRandom(getVariantNames("mouth")),
1017
- nose: pickRandom(getVariantNames("nose")),
1018
- ears: pickRandom(getVariantNames("ears")),
1019
- hair: pickRandom(getVariantNames("hair")),
1020
- beard: pickRandom(getVariantNames("beard")),
1021
- accessories: pickRandom(getVariantNames("accessories")),
1022
- skinColor: pickRandom(Object.keys(SKIN_PRESETS)),
1023
- hairColor: pickRandom(Object.keys(HAIR_PRESETS)),
1024
- eyeColor: pickRandom(Object.keys(EYE_PRESETS))
1025
- };
1026
- }
1027
- function generateFace(config) {
1028
- const resolved = config ?? generateRandomConfig();
1029
- const grid = generateGrid(resolved);
1030
- return gridToSvg(grid, resolved.backgroundColor);
1031
- }
1032
- function getAvailableParts() {
1033
- const result = {};
1034
- for (const category of getAllCategories()) {
1035
- result[category] = getVariantNames(category);
1036
- }
1037
- return result;
1038
- }
1039
- function getPartThumbnail(category, name, skinColor, hairColor, eyeColor) {
1040
- const grid = generatePartThumbnail(category, name, skinColor, hairColor, eyeColor);
1041
- return gridToSvg(grid);
1042
- }
1043
-
1044
- // src/renderer/animations.ts
1045
- var ANIMATIONS = {
1046
- idle: {
1047
- name: "idle",
1048
- frames: [
1049
- { duration: 3e3, overrides: {} },
1050
- { duration: 150, overrides: { eyes: "happy" } },
1051
- { duration: 150, overrides: {} }
1052
- ]
1053
- },
1054
- talk: {
1055
- name: "talk",
1056
- frames: [
1057
- { duration: 200, overrides: { mouth: "smile" } },
1058
- { duration: 200, overrides: { mouth: "open" } },
1059
- { duration: 200, overrides: { mouth: "flat" } },
1060
- { duration: 200, overrides: { mouth: "open" } },
1061
- { duration: 300, overrides: { mouth: "smile" } }
1062
- ]
1063
- },
1064
- blink: {
1065
- name: "blink",
1066
- frames: [
1067
- { duration: 2500, overrides: {} },
1068
- { duration: 100, overrides: { eyes: "narrow" } },
1069
- { duration: 100, overrides: { eyes: "happy" } },
1070
- { duration: 100, overrides: { eyes: "narrow" } },
1071
- { duration: 200, overrides: {} }
1072
- ]
1073
- },
1074
- emote: {
1075
- name: "emote",
1076
- frames: [
1077
- { duration: 500, overrides: {} },
1078
- { duration: 400, overrides: { eyebrows: "arched", mouth: "open" } },
1079
- { duration: 400, overrides: { eyebrows: "arched", mouth: "smile" } },
1080
- { duration: 300, overrides: {} }
1081
- ]
1082
- }
1083
- };
1084
- function getAnimationNames() {
1085
- return Object.keys(ANIMATIONS);
1086
- }
1087
-
1088
- export {
1089
- SKIN_PRESETS,
1090
- HAIR_PRESETS,
1091
- EYE_PRESETS,
1092
- generateRandomConfig,
1093
- generateFace,
1094
- getAvailableParts,
1095
- getPartThumbnail,
1096
- ANIMATIONS,
1097
- getAnimationNames
1098
- };
1099
- //# sourceMappingURL=chunk-SCBE5EEX.js.map