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