solfaces 1.0.2 → 2.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 (69) hide show
  1. package/README.md +359 -87
  2. package/dist/agent/index.cjs +14 -14
  3. package/dist/agent/index.js +4 -4
  4. package/dist/agent/mcp-server.cjs +716 -277
  5. package/dist/{chunk-VMNATBH3.cjs → chunk-23XJ5VDX.cjs} +37 -27
  6. package/dist/chunk-23XJ5VDX.cjs.map +1 -0
  7. package/dist/chunk-46ZEFA6R.cjs +243 -0
  8. package/dist/chunk-46ZEFA6R.cjs.map +1 -0
  9. package/dist/{chunk-A6N3RPEA.cjs → chunk-546TBMAR.cjs} +6 -6
  10. package/dist/{chunk-A6N3RPEA.cjs.map → chunk-546TBMAR.cjs.map} +1 -1
  11. package/dist/chunk-6QRDULAO.cjs +191 -0
  12. package/dist/chunk-6QRDULAO.cjs.map +1 -0
  13. package/dist/chunk-6UWILY7E.cjs +647 -0
  14. package/dist/chunk-6UWILY7E.cjs.map +1 -0
  15. package/dist/chunk-DRUSCLEF.js +177 -0
  16. package/dist/chunk-DRUSCLEF.js.map +1 -0
  17. package/dist/chunk-HCEE4K4T.js +625 -0
  18. package/dist/chunk-HCEE4K4T.js.map +1 -0
  19. package/dist/chunk-JS527VKL.js +238 -0
  20. package/dist/chunk-JS527VKL.js.map +1 -0
  21. package/dist/{chunk-SNJABBAT.js → chunk-LRHYF5QN.js} +3 -3
  22. package/dist/{chunk-SNJABBAT.js.map → chunk-LRHYF5QN.js.map} +1 -1
  23. package/dist/{chunk-RX6D5FGH.js → chunk-TTGJZEPV.js} +30 -20
  24. package/dist/chunk-TTGJZEPV.js.map +1 -0
  25. package/dist/core/index.cjs +69 -29
  26. package/dist/core/index.d.cts +29 -47
  27. package/dist/core/index.d.ts +29 -47
  28. package/dist/core/index.js +3 -3
  29. package/dist/index.cjs +75 -35
  30. package/dist/index.d.cts +2 -2
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +5 -5
  33. package/dist/react/index.cjs +431 -397
  34. package/dist/react/index.cjs.map +1 -1
  35. package/dist/react/index.d.cts +3 -2
  36. package/dist/react/index.d.ts +3 -2
  37. package/dist/react/index.js +427 -393
  38. package/dist/react/index.js.map +1 -1
  39. package/dist/solfaces.cdn.global.js +2 -2
  40. package/dist/solfaces.cdn.global.js.map +1 -1
  41. package/dist/themes/index.cjs +29 -17
  42. package/dist/themes/index.d.cts +10 -7
  43. package/dist/themes/index.d.ts +10 -7
  44. package/dist/themes/index.js +1 -1
  45. package/dist/{traits-DAFZnXeS.d.cts → traits-QlWuxZDD.d.cts} +45 -1
  46. package/dist/{traits-DAFZnXeS.d.ts → traits-QlWuxZDD.d.ts} +45 -1
  47. package/dist/vanilla/index.cjs +20 -8
  48. package/dist/vanilla/index.cjs.map +1 -1
  49. package/dist/vanilla/index.d.cts +1 -1
  50. package/dist/vanilla/index.d.ts +1 -1
  51. package/dist/vanilla/index.js +17 -5
  52. package/dist/vanilla/index.js.map +1 -1
  53. package/package.json +1 -1
  54. package/python/solfaces.py +557 -235
  55. package/skill.md +210 -65
  56. package/dist/chunk-2DIKGLXZ.cjs +0 -126
  57. package/dist/chunk-2DIKGLXZ.cjs.map +0 -1
  58. package/dist/chunk-CVFO7YHY.cjs +0 -97
  59. package/dist/chunk-CVFO7YHY.cjs.map +0 -1
  60. package/dist/chunk-H3SK3MNX.cjs +0 -409
  61. package/dist/chunk-H3SK3MNX.cjs.map +0 -1
  62. package/dist/chunk-KSGFMW33.js +0 -401
  63. package/dist/chunk-KSGFMW33.js.map +0 -1
  64. package/dist/chunk-LQWJRHGC.js +0 -86
  65. package/dist/chunk-LQWJRHGC.js.map +0 -1
  66. package/dist/chunk-RX6D5FGH.js.map +0 -1
  67. package/dist/chunk-VMNATBH3.cjs.map +0 -1
  68. package/dist/chunk-WURY4QGH.js +0 -117
  69. package/dist/chunk-WURY4QGH.js.map +0 -1
@@ -1,37 +1,110 @@
1
- import { generateTraits, SKIN_COLORS, EYE_COLORS, HAIR_COLORS, BG_COLORS } from '../chunk-WURY4QGH.js';
1
+ import { generateTraits, SKIN_COLORS, EYE_COLORS, HAIR_COLORS, BG_COLORS, deriveSkinColors, blend, effectiveAccessory, renderSolFaceSVG, lighten, darken, buzzOpacity } from '../chunk-HCEE4K4T.js';
2
2
  import { useMemo } from 'react';
3
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
 
5
- function renderFace(traits, skin) {
6
- switch (traits.faceShape) {
5
+ function djb2(str) {
6
+ let hash = 5381;
7
+ for (let i = 0; i < str.length; i++) {
8
+ hash = (hash << 5) + hash + str.charCodeAt(i) | 0;
9
+ }
10
+ return hash >>> 0;
11
+ }
12
+ function HairBack({ hi, id, flat }) {
13
+ const fill = flat ? "currentColor" : `url(#${id}hg)`;
14
+ switch (hi) {
15
+ case 5:
16
+ return /* @__PURE__ */ jsx("rect", { x: "10", y: "14", width: "44", height: "42", rx: "6", fill });
17
+ case 6:
18
+ return /* @__PURE__ */ jsx("rect", { x: "12", y: "14", width: "40", height: "32", rx: "8", fill });
19
+ case 8:
20
+ return /* @__PURE__ */ jsx("rect", { x: "11", y: "14", width: "42", height: "38", rx: "8", fill });
21
+ default:
22
+ return null;
23
+ }
24
+ }
25
+ function Ears({ earFill, earShadow }) {
26
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
27
+ /* @__PURE__ */ jsx("ellipse", { cx: "11", cy: "34", rx: "4", ry: "5", fill: earFill }),
28
+ /* @__PURE__ */ jsx("ellipse", { cx: "11", cy: "34", rx: "2.5", ry: "3.5", fill: earShadow, opacity: "0.3" }),
29
+ /* @__PURE__ */ jsx("ellipse", { cx: "53", cy: "34", rx: "4", ry: "5", fill: earFill }),
30
+ /* @__PURE__ */ jsx("ellipse", { cx: "53", cy: "34", rx: "2.5", ry: "3.5", fill: earShadow, opacity: "0.3" })
31
+ ] });
32
+ }
33
+ function FaceOverlays({ id }) {
34
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
35
+ /* @__PURE__ */ jsx("rect", { x: "14", y: "16", width: "36", height: "38", rx: "12", ry: "12", fill: `url(#${id}glow)` }),
36
+ /* @__PURE__ */ jsx("rect", { x: "14", y: "16", width: "36", height: "38", rx: "12", ry: "12", fill: `url(#${id}chin)` }),
37
+ /* @__PURE__ */ jsx("ellipse", { cx: "22", cy: "42", rx: "5", ry: "3.5", fill: `url(#${id}cL)` }),
38
+ /* @__PURE__ */ jsx("ellipse", { cx: "42", cy: "42", rx: "5", ry: "3.5", fill: `url(#${id}cR)` }),
39
+ /* @__PURE__ */ jsx("line", { x1: "20", y1: "50", x2: "44", y2: "50", stroke: "currentColor", strokeWidth: "0.3", opacity: "0.08", strokeLinecap: "round" })
40
+ ] });
41
+ }
42
+ function HairFront({ hi, id, hairCol, skin, flat }) {
43
+ const fill = flat ? hairCol : `url(#${id}hg)`;
44
+ switch (hi) {
7
45
  case 0:
8
- return /* @__PURE__ */ jsx("circle", { cx: "32", cy: "34", r: "20", fill: skin });
46
+ return null;
9
47
  case 1:
10
- return /* @__PURE__ */ jsx("rect", { x: "12", y: "14", width: "40", height: "40", rx: "8", ry: "8", fill: skin });
48
+ return /* @__PURE__ */ jsx("path", { d: "M14 28 Q14 14 32 12 Q50 14 50 28 L50 22 Q50 12 32 10 Q14 12 14 22 Z", fill });
11
49
  case 2:
12
- return /* @__PURE__ */ jsx("ellipse", { cx: "32", cy: "34", rx: "18", ry: "22", fill: skin });
50
+ return /* @__PURE__ */ jsxs("g", { fill, children: [
51
+ /* @__PURE__ */ jsx("circle", { cx: "20", cy: "14", r: "5" }),
52
+ /* @__PURE__ */ jsx("circle", { cx: "28", cy: "11", r: "5.5" }),
53
+ /* @__PURE__ */ jsx("circle", { cx: "36", cy: "11", r: "5.5" }),
54
+ /* @__PURE__ */ jsx("circle", { cx: "44", cy: "14", r: "5" }),
55
+ /* @__PURE__ */ jsx("circle", { cx: "16", cy: "20", r: "4" }),
56
+ /* @__PURE__ */ jsx("circle", { cx: "48", cy: "20", r: "4" })
57
+ ] });
13
58
  case 3:
14
- return /* @__PURE__ */ jsx(
15
- "path",
16
- {
17
- d: "M32 12 L50 24 L50 44 L32 56 L14 44 L14 24 Z",
18
- fill: skin,
19
- strokeLinejoin: "round"
20
- }
21
- );
59
+ return /* @__PURE__ */ jsxs("g", { fill, children: [
60
+ /* @__PURE__ */ jsx("path", { d: "M14 26 Q14 12 32 10 Q50 12 50 26 L50 20 Q50 10 32 8 Q14 10 14 20 Z" }),
61
+ /* @__PURE__ */ jsx("path", { d: "M14 20 Q8 16 10 8 Q14 10 20 16 Z" })
62
+ ] });
63
+ case 4:
64
+ return /* @__PURE__ */ jsx("ellipse", { cx: "32", cy: "10", rx: "14", ry: "8", fill });
65
+ case 5:
66
+ return /* @__PURE__ */ jsx("path", { d: "M14 28 Q14 12 32 10 Q50 12 50 28 L50 20 Q50 10 32 8 Q14 10 14 20 Z", fill });
67
+ case 6:
68
+ return /* @__PURE__ */ jsxs("g", { fill, children: [
69
+ /* @__PURE__ */ jsx("path", { d: "M14 28 Q14 12 32 10 Q50 12 50 28 L50 20 Q50 10 32 8 Q14 10 14 20 Z" }),
70
+ /* @__PURE__ */ jsx("rect", { x: "10", y: "28", width: "8", height: "14", rx: "4" }),
71
+ /* @__PURE__ */ jsx("rect", { x: "46", y: "28", width: "8", height: "14", rx: "4" })
72
+ ] });
73
+ case 7: {
74
+ const bOp = buzzOpacity(hairCol, skin);
75
+ return /* @__PURE__ */ jsx("rect", { x: "15", y: "13", width: "34", height: "16", rx: "10", ry: "8", fill: hairCol, opacity: bOp });
76
+ }
77
+ case 8:
78
+ return /* @__PURE__ */ jsxs("g", { children: [
79
+ /* @__PURE__ */ jsx("path", { d: "M14 28 Q14 12 32 10 Q50 12 50 28 L50 20 Q50 10 32 8 Q14 10 14 20 Z", fill }),
80
+ /* @__PURE__ */ jsx("path", { d: "M12 30 Q10 20 14 16", fill: "none", stroke: fill, strokeWidth: "4", strokeLinecap: "round" }),
81
+ /* @__PURE__ */ jsx("path", { d: "M52 30 Q54 20 50 16", fill: "none", stroke: fill, strokeWidth: "4", strokeLinecap: "round" })
82
+ ] });
83
+ case 9:
84
+ return /* @__PURE__ */ jsxs("g", { fill, children: [
85
+ /* @__PURE__ */ jsx("path", { d: "M14 28 Q14 14 32 12 Q50 14 50 28 L50 22 Q50 12 32 10 Q14 12 14 22 Z" }),
86
+ /* @__PURE__ */ jsx("ellipse", { cx: "32", cy: "6", rx: "6", ry: "5" })
87
+ ] });
22
88
  default:
23
- return /* @__PURE__ */ jsx("circle", { cx: "32", cy: "34", r: "20", fill: skin });
89
+ return null;
24
90
  }
25
91
  }
26
- function renderEyes(traits, eyeCol, eyeWhite = "white") {
27
- const lx = 24, rx = 40, y = 30;
28
- switch (traits.eyeStyle) {
92
+ function Eyes({ ei, eyeCol, eyeWhite, lidColor, full }) {
93
+ const lx = 25, rx = 39, y = 33;
94
+ const lids = full && ei !== 1 && ei !== 5 ? /* @__PURE__ */ jsxs(Fragment, { children: [
95
+ /* @__PURE__ */ jsx("path", { d: `M${lx - 4} ${y - 1.5} Q${lx} ${y - 4} ${lx + 4} ${y - 1.5}`, fill: "none", stroke: lidColor, strokeWidth: "0.5", opacity: "0.4" }),
96
+ /* @__PURE__ */ jsx("path", { d: `M${rx - 4} ${y - 1.5} Q${rx} ${y - 4} ${rx + 4} ${y - 1.5}`, fill: "none", stroke: lidColor, strokeWidth: "0.5", opacity: "0.4" })
97
+ ] }) : null;
98
+ switch (ei) {
29
99
  case 0:
30
100
  return /* @__PURE__ */ jsxs(Fragment, { children: [
31
- /* @__PURE__ */ jsx("circle", { cx: lx, cy: y, r: "3.5", fill: eyeWhite }),
32
- /* @__PURE__ */ jsx("circle", { cx: lx + 1, cy: y, r: "2", fill: eyeCol }),
33
- /* @__PURE__ */ jsx("circle", { cx: rx, cy: y, r: "3.5", fill: eyeWhite }),
34
- /* @__PURE__ */ jsx("circle", { cx: rx + 1, cy: y, r: "2", fill: eyeCol })
101
+ /* @__PURE__ */ jsx("circle", { cx: lx, cy: y, r: "4", fill: eyeWhite }),
102
+ /* @__PURE__ */ jsx("circle", { cx: lx + 0.8, cy: y, r: "2.2", fill: eyeCol }),
103
+ full && /* @__PURE__ */ jsx("circle", { cx: lx + 1.5, cy: y - 1, r: "0.7", fill: "white", opacity: "0.8" }),
104
+ /* @__PURE__ */ jsx("circle", { cx: rx, cy: y, r: "4", fill: eyeWhite }),
105
+ /* @__PURE__ */ jsx("circle", { cx: rx + 0.8, cy: y, r: "2.2", fill: eyeCol }),
106
+ full && /* @__PURE__ */ jsx("circle", { cx: rx + 1.5, cy: y - 1, r: "0.7", fill: "white", opacity: "0.8" }),
107
+ lids
35
108
  ] });
36
109
  case 1:
37
110
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -40,420 +113,328 @@ function renderEyes(traits, eyeCol, eyeWhite = "white") {
40
113
  ] });
41
114
  case 2:
42
115
  return /* @__PURE__ */ jsxs(Fragment, { children: [
43
- /* @__PURE__ */ jsx("ellipse", { cx: lx, cy: y, rx: "4", ry: "2.5", fill: eyeWhite }),
44
- /* @__PURE__ */ jsx("circle", { cx: lx + 0.5, cy: y, r: "1.5", fill: eyeCol }),
45
- /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: y, rx: "4", ry: "2.5", fill: eyeWhite }),
46
- /* @__PURE__ */ jsx("circle", { cx: rx + 0.5, cy: y, r: "1.5", fill: eyeCol })
116
+ /* @__PURE__ */ jsx("ellipse", { cx: lx, cy: y, rx: "4.5", ry: "2.8", fill: eyeWhite }),
117
+ /* @__PURE__ */ jsx("circle", { cx: lx + 0.5, cy: y, r: "1.8", fill: eyeCol }),
118
+ full && /* @__PURE__ */ jsx("circle", { cx: lx + 1.2, cy: y - 0.8, r: "0.6", fill: "white", opacity: "0.7" }),
119
+ /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: y, rx: "4.5", ry: "2.8", fill: eyeWhite }),
120
+ /* @__PURE__ */ jsx("circle", { cx: rx + 0.5, cy: y, r: "1.8", fill: eyeCol }),
121
+ full && /* @__PURE__ */ jsx("circle", { cx: rx + 1.2, cy: y - 0.8, r: "0.6", fill: "white", opacity: "0.7" }),
122
+ lids
47
123
  ] });
48
124
  case 3:
49
125
  return /* @__PURE__ */ jsxs(Fragment, { children: [
50
- /* @__PURE__ */ jsx("circle", { cx: lx, cy: y, r: "4.5", fill: eyeWhite }),
51
- /* @__PURE__ */ jsx("circle", { cx: lx, cy: y + 0.5, r: "2.5", fill: eyeCol }),
52
- /* @__PURE__ */ jsx("circle", { cx: rx, cy: y, r: "4.5", fill: eyeWhite }),
53
- /* @__PURE__ */ jsx("circle", { cx: rx, cy: y + 0.5, r: "2.5", fill: eyeCol })
126
+ /* @__PURE__ */ jsx("circle", { cx: lx, cy: y, r: "5", fill: eyeWhite }),
127
+ /* @__PURE__ */ jsx("circle", { cx: lx, cy: y + 0.5, r: "2.8", fill: eyeCol }),
128
+ full && /* @__PURE__ */ jsx("circle", { cx: lx + 1.5, cy: y - 1, r: "0.8", fill: "white", opacity: "0.8" }),
129
+ /* @__PURE__ */ jsx("circle", { cx: rx, cy: y, r: "5", fill: eyeWhite }),
130
+ /* @__PURE__ */ jsx("circle", { cx: rx, cy: y + 0.5, r: "2.8", fill: eyeCol }),
131
+ full && /* @__PURE__ */ jsx("circle", { cx: rx + 1.5, cy: y - 1, r: "0.8", fill: "white", opacity: "0.8" }),
132
+ lids
54
133
  ] });
55
134
  case 4:
56
135
  return /* @__PURE__ */ jsxs(Fragment, { children: [
57
- /* @__PURE__ */ jsx("ellipse", { cx: lx, cy: y + 1, rx: "3.5", ry: "2", fill: eyeWhite }),
136
+ /* @__PURE__ */ jsx("ellipse", { cx: lx, cy: y + 1, rx: "4", ry: "2.2", fill: eyeWhite }),
58
137
  /* @__PURE__ */ jsx("circle", { cx: lx, cy: y + 1, r: "1.5", fill: eyeCol }),
59
- /* @__PURE__ */ jsx(
60
- "line",
61
- {
62
- x1: lx - 4,
63
- y1: y - 0.5,
64
- x2: lx + 4,
65
- y2: y - 0.5,
66
- stroke: eyeCol,
67
- strokeWidth: "1",
68
- strokeLinecap: "round"
69
- }
70
- ),
71
- /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: y + 1, rx: "3.5", ry: "2", fill: eyeWhite }),
138
+ full && /* @__PURE__ */ jsx("line", { x1: lx - 4.5, y1: y - 0.5, x2: lx + 4.5, y2: y - 0.5, stroke: lidColor, strokeWidth: "0.8", strokeLinecap: "round" }),
139
+ /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: y + 1, rx: "4", ry: "2.2", fill: eyeWhite }),
72
140
  /* @__PURE__ */ jsx("circle", { cx: rx, cy: y + 1, r: "1.5", fill: eyeCol }),
73
- /* @__PURE__ */ jsx(
74
- "line",
75
- {
76
- x1: rx - 4,
77
- y1: y - 0.5,
78
- x2: rx + 4,
79
- y2: y - 0.5,
80
- stroke: eyeCol,
81
- strokeWidth: "1",
82
- strokeLinecap: "round"
83
- }
84
- )
141
+ full && /* @__PURE__ */ jsx("line", { x1: rx - 4.5, y1: y - 0.5, x2: rx + 4.5, y2: y - 0.5, stroke: lidColor, strokeWidth: "0.8", strokeLinecap: "round" }),
142
+ lids
85
143
  ] });
86
144
  case 5:
87
145
  return /* @__PURE__ */ jsxs(Fragment, { children: [
88
- /* @__PURE__ */ jsx(
89
- "path",
90
- {
91
- d: `M${lx - 3} ${y} Q${lx} ${y + 3} ${lx + 3} ${y}`,
92
- fill: "none",
93
- stroke: eyeCol,
94
- strokeWidth: "1.5",
95
- strokeLinecap: "round"
96
- }
97
- ),
98
- /* @__PURE__ */ jsx("circle", { cx: rx, cy: y, r: "3.5", fill: eyeWhite }),
99
- /* @__PURE__ */ jsx("circle", { cx: rx + 1, cy: y, r: "2", fill: eyeCol })
146
+ /* @__PURE__ */ jsx("path", { d: `M${lx - 4} ${y} Q${lx} ${y + 4} ${lx + 4} ${y}`, fill: "none", stroke: eyeCol, strokeWidth: "1.8", strokeLinecap: "round" }),
147
+ /* @__PURE__ */ jsx("path", { d: `M${rx - 4} ${y} Q${rx} ${y + 4} ${rx + 4} ${y}`, fill: "none", stroke: eyeCol, strokeWidth: "1.8", strokeLinecap: "round" })
100
148
  ] });
101
149
  case 6:
102
150
  return /* @__PURE__ */ jsxs(Fragment, { children: [
103
- /* @__PURE__ */ jsx("circle", { cx: lx, cy: y, r: "3", fill: eyeWhite }),
104
- /* @__PURE__ */ jsx("circle", { cx: lx + 0.5, cy: y, r: "1.5", fill: eyeCol }),
105
- /* @__PURE__ */ jsx(
106
- "line",
107
- {
108
- x1: lx + 2,
109
- y1: y - 3,
110
- x2: lx + 3.5,
111
- y2: y - 4.5,
112
- stroke: eyeCol,
113
- strokeWidth: "0.8",
114
- strokeLinecap: "round"
115
- }
116
- ),
117
- /* @__PURE__ */ jsx(
118
- "line",
119
- {
120
- x1: lx + 3,
121
- y1: y - 2,
122
- x2: lx + 4.5,
123
- y2: y - 3,
124
- stroke: eyeCol,
125
- strokeWidth: "0.8",
126
- strokeLinecap: "round"
127
- }
128
- ),
129
- /* @__PURE__ */ jsx("circle", { cx: rx, cy: y, r: "3", fill: eyeWhite }),
130
- /* @__PURE__ */ jsx("circle", { cx: rx + 0.5, cy: y, r: "1.5", fill: eyeCol }),
131
- /* @__PURE__ */ jsx(
132
- "line",
133
- {
134
- x1: rx + 2,
135
- y1: y - 3,
136
- x2: rx + 3.5,
137
- y2: y - 4.5,
138
- stroke: eyeCol,
139
- strokeWidth: "0.8",
140
- strokeLinecap: "round"
141
- }
142
- ),
143
- /* @__PURE__ */ jsx(
144
- "line",
145
- {
146
- x1: rx + 3,
147
- y1: y - 2,
148
- x2: rx + 4.5,
149
- y2: y - 3,
150
- stroke: eyeCol,
151
- strokeWidth: "0.8",
152
- strokeLinecap: "round"
153
- }
154
- )
151
+ /* @__PURE__ */ jsx("circle", { cx: lx, cy: y, r: "3.5", fill: eyeWhite }),
152
+ /* @__PURE__ */ jsx("circle", { cx: lx + 0.5, cy: y, r: "2", fill: eyeCol }),
153
+ /* @__PURE__ */ jsx("circle", { cx: lx + 1.5, cy: y - 1, r: "1", fill: "white", opacity: "0.9" }),
154
+ full && /* @__PURE__ */ jsxs(Fragment, { children: [
155
+ /* @__PURE__ */ jsx("line", { x1: lx + 2.5, y1: y - 3.5, x2: lx + 4, y2: y - 5, stroke: eyeCol, strokeWidth: "0.8", strokeLinecap: "round" }),
156
+ /* @__PURE__ */ jsx("line", { x1: lx + 3.5, y1: y - 2.5, x2: lx + 5, y2: y - 3.5, stroke: eyeCol, strokeWidth: "0.8", strokeLinecap: "round" })
157
+ ] }),
158
+ /* @__PURE__ */ jsx("circle", { cx: rx, cy: y, r: "3.5", fill: eyeWhite }),
159
+ /* @__PURE__ */ jsx("circle", { cx: rx + 0.5, cy: y, r: "2", fill: eyeCol }),
160
+ /* @__PURE__ */ jsx("circle", { cx: rx + 1.5, cy: y - 1, r: "1", fill: "white", opacity: "0.9" }),
161
+ full && /* @__PURE__ */ jsxs(Fragment, { children: [
162
+ /* @__PURE__ */ jsx("line", { x1: rx + 2.5, y1: y - 3.5, x2: rx + 4, y2: y - 5, stroke: eyeCol, strokeWidth: "0.8", strokeLinecap: "round" }),
163
+ /* @__PURE__ */ jsx("line", { x1: rx + 3.5, y1: y - 2.5, x2: rx + 5, y2: y - 3.5, stroke: eyeCol, strokeWidth: "0.8", strokeLinecap: "round" })
164
+ ] }),
165
+ lids
155
166
  ] });
156
167
  case 7:
157
168
  return /* @__PURE__ */ jsxs(Fragment, { children: [
158
- /* @__PURE__ */ jsx("ellipse", { cx: lx, cy: y, rx: "4", ry: "1.2", fill: eyeWhite }),
159
- /* @__PURE__ */ jsx("ellipse", { cx: lx + 0.5, cy: y, rx: "2", ry: "1", fill: eyeCol }),
160
- /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: y, rx: "4", ry: "1.2", fill: eyeWhite }),
161
- /* @__PURE__ */ jsx("ellipse", { cx: rx + 0.5, cy: y, rx: "2", ry: "1", fill: eyeCol })
169
+ /* @__PURE__ */ jsx("ellipse", { cx: lx, cy: y, rx: "4.5", ry: "1.5", fill: eyeWhite }),
170
+ /* @__PURE__ */ jsx("ellipse", { cx: lx + 0.5, cy: y, rx: "2.2", ry: "1.2", fill: eyeCol }),
171
+ /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: y, rx: "4.5", ry: "1.5", fill: eyeWhite }),
172
+ /* @__PURE__ */ jsx("ellipse", { cx: rx + 0.5, cy: y, rx: "2.2", ry: "1.2", fill: eyeCol }),
173
+ lids
162
174
  ] });
163
175
  default:
164
176
  return /* @__PURE__ */ jsxs(Fragment, { children: [
165
- /* @__PURE__ */ jsx("circle", { cx: lx, cy: y, r: "3", fill: eyeWhite }),
166
- /* @__PURE__ */ jsx("circle", { cx: lx + 1, cy: y, r: "2", fill: eyeCol }),
167
- /* @__PURE__ */ jsx("circle", { cx: rx, cy: y, r: "3", fill: eyeWhite }),
168
- /* @__PURE__ */ jsx("circle", { cx: rx + 1, cy: y, r: "2", fill: eyeCol })
177
+ /* @__PURE__ */ jsx("circle", { cx: lx, cy: y, r: "3.5", fill: eyeWhite }),
178
+ /* @__PURE__ */ jsx("circle", { cx: lx + 0.8, cy: y, r: "2", fill: eyeCol }),
179
+ /* @__PURE__ */ jsx("circle", { cx: rx, cy: y, r: "3.5", fill: eyeWhite }),
180
+ /* @__PURE__ */ jsx("circle", { cx: rx + 0.8, cy: y, r: "2", fill: eyeCol }),
181
+ lids
169
182
  ] });
170
183
  }
171
184
  }
172
- function renderEyebrows(traits, col) {
173
- const lx = 24, rx = 40, y = 25;
174
- switch (traits.eyebrows) {
185
+ function Eyebrows({ bi, browColor }) {
186
+ const lx = 25, rx = 39, y = 27;
187
+ switch (bi) {
175
188
  case 0:
176
- return null;
189
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
190
+ /* @__PURE__ */ jsx("line", { x1: lx - 3, y1: y, x2: lx + 3, y2: y - 0.5, stroke: browColor, strokeWidth: "0.7", strokeLinecap: "round" }),
191
+ /* @__PURE__ */ jsx("line", { x1: rx - 3, y1: y - 0.5, x2: rx + 3, y2: y, stroke: browColor, strokeWidth: "0.7", strokeLinecap: "round" })
192
+ ] });
177
193
  case 1:
178
194
  return /* @__PURE__ */ jsxs(Fragment, { children: [
179
- /* @__PURE__ */ jsx(
180
- "line",
181
- {
182
- x1: lx - 3,
183
- y1: y,
184
- x2: lx + 3,
185
- y2: y,
186
- stroke: col,
187
- strokeWidth: "0.8",
188
- strokeLinecap: "round"
189
- }
190
- ),
191
- /* @__PURE__ */ jsx(
192
- "line",
193
- {
194
- x1: rx - 3,
195
- y1: y,
196
- x2: rx + 3,
197
- y2: y,
198
- stroke: col,
199
- strokeWidth: "0.8",
200
- strokeLinecap: "round"
201
- }
202
- )
195
+ /* @__PURE__ */ jsx("line", { x1: lx - 3.5, y1: y, x2: lx + 3.5, y2: y, stroke: browColor, strokeWidth: "1.2", strokeLinecap: "round" }),
196
+ /* @__PURE__ */ jsx("line", { x1: rx - 3.5, y1: y, x2: rx + 3.5, y2: y, stroke: browColor, strokeWidth: "1.2", strokeLinecap: "round" })
203
197
  ] });
204
198
  case 2:
205
199
  return /* @__PURE__ */ jsxs(Fragment, { children: [
206
- /* @__PURE__ */ jsx(
207
- "line",
208
- {
209
- x1: lx - 3.5,
210
- y1: y,
211
- x2: lx + 3.5,
212
- y2: y,
213
- stroke: col,
214
- strokeWidth: "2",
215
- strokeLinecap: "round"
216
- }
217
- ),
218
- /* @__PURE__ */ jsx(
219
- "line",
220
- {
221
- x1: rx - 3.5,
222
- y1: y,
223
- x2: rx + 3.5,
224
- y2: y,
225
- stroke: col,
226
- strokeWidth: "2",
227
- strokeLinecap: "round"
228
- }
229
- )
200
+ /* @__PURE__ */ jsx("path", { d: `M${lx - 3.5} ${y + 0.5} Q${lx} ${y - 1.5} ${lx + 3.5} ${y + 0.5}`, fill: "none", stroke: browColor, strokeWidth: "1.2", strokeLinecap: "round" }),
201
+ /* @__PURE__ */ jsx("path", { d: `M${rx - 3.5} ${y + 0.5} Q${rx} ${y - 1.5} ${rx + 3.5} ${y + 0.5}`, fill: "none", stroke: browColor, strokeWidth: "1.2", strokeLinecap: "round" })
230
202
  ] });
231
203
  case 3:
232
204
  return /* @__PURE__ */ jsxs(Fragment, { children: [
233
- /* @__PURE__ */ jsx(
234
- "path",
235
- {
236
- d: `M${lx - 3.5} ${y + 1} Q${lx} ${y - 2} ${lx + 3.5} ${y + 1}`,
237
- fill: "none",
238
- stroke: col,
239
- strokeWidth: "1",
240
- strokeLinecap: "round"
241
- }
242
- ),
243
- /* @__PURE__ */ jsx(
244
- "path",
245
- {
246
- d: `M${rx - 3.5} ${y + 1} Q${rx} ${y - 2} ${rx + 3.5} ${y + 1}`,
247
- fill: "none",
248
- stroke: col,
249
- strokeWidth: "1",
250
- strokeLinecap: "round"
251
- }
252
- )
205
+ /* @__PURE__ */ jsx("path", { d: `M${lx - 4} ${y + 1} Q${lx} ${y - 3} ${lx + 4} ${y + 1}`, fill: "none", stroke: browColor, strokeWidth: "1", strokeLinecap: "round" }),
206
+ /* @__PURE__ */ jsx("path", { d: `M${rx - 4} ${y + 1} Q${rx} ${y - 3} ${rx + 4} ${y + 1}`, fill: "none", stroke: browColor, strokeWidth: "1", strokeLinecap: "round" })
253
207
  ] });
254
208
  case 4:
255
209
  return /* @__PURE__ */ jsxs(Fragment, { children: [
256
- /* @__PURE__ */ jsx(
257
- "line",
258
- {
259
- x1: lx - 3,
260
- y1: y - 1,
261
- x2: lx + 3,
262
- y2: y + 1,
263
- stroke: col,
264
- strokeWidth: "1.2",
265
- strokeLinecap: "round"
266
- }
267
- ),
268
- /* @__PURE__ */ jsx(
269
- "line",
270
- {
271
- x1: rx - 3,
272
- y1: y + 1,
273
- x2: rx + 3,
274
- y2: y - 1,
275
- stroke: col,
276
- strokeWidth: "1.2",
277
- strokeLinecap: "round"
278
- }
279
- )
210
+ /* @__PURE__ */ jsx("polyline", { points: `${lx - 3},${y + 1} ${lx},${y - 2} ${lx + 3},${y}`, fill: "none", stroke: browColor, strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" }),
211
+ /* @__PURE__ */ jsx("polyline", { points: `${rx - 3},${y} ${rx},${y - 2} ${rx + 3},${y + 1}`, fill: "none", stroke: browColor, strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })
280
212
  ] });
281
213
  default:
282
214
  return null;
283
215
  }
284
216
  }
285
- function renderNose(traits, skin, noseCol) {
286
- const cx = 32, y = 36;
287
- const shadow = noseCol ?? skin + "aa";
288
- switch (traits.nose) {
217
+ function Nose({ ni, noseFill }) {
218
+ const cx = 32, y = 39;
219
+ switch (ni) {
289
220
  case 0:
290
- return null;
221
+ return /* @__PURE__ */ jsx("ellipse", { cx, cy: y, rx: "2", ry: "1.2", fill: noseFill, opacity: "0.35" });
291
222
  case 1:
292
- return /* @__PURE__ */ jsx("circle", { cx, cy: y, r: "1.5", fill: shadow });
223
+ return /* @__PURE__ */ jsx("circle", { cx, cy: y, r: "1.8", fill: noseFill, opacity: "0.5" });
293
224
  case 2:
294
- return /* @__PURE__ */ jsx(
295
- "path",
296
- {
297
- d: `M${cx} ${y - 1.5} L${cx + 2.5} ${y + 2} L${cx - 2.5} ${y + 2} Z`,
298
- fill: shadow
299
- }
300
- );
225
+ return /* @__PURE__ */ jsx("path", { d: `M${cx - 2} ${y + 1} Q${cx} ${y - 2} ${cx + 2} ${y + 1}`, fill: "none", stroke: noseFill, strokeWidth: "1", strokeLinecap: "round", opacity: "0.5" });
301
226
  case 3:
302
227
  return /* @__PURE__ */ jsxs(Fragment, { children: [
303
- /* @__PURE__ */ jsx("circle", { cx: cx - 1.5, cy: y, r: "1", fill: shadow }),
304
- /* @__PURE__ */ jsx("circle", { cx: cx + 1.5, cy: y, r: "1", fill: shadow })
228
+ /* @__PURE__ */ jsx("circle", { cx: cx - 1.8, cy: y, r: "1.2", fill: noseFill, opacity: "0.4" }),
229
+ /* @__PURE__ */ jsx("circle", { cx: cx + 1.8, cy: y, r: "1.2", fill: noseFill, opacity: "0.4" })
305
230
  ] });
306
231
  default:
307
- return null;
232
+ return /* @__PURE__ */ jsx("ellipse", { cx, cy: y, rx: "2", ry: "1.2", fill: noseFill, opacity: "0.35" });
308
233
  }
309
234
  }
310
- function renderMouth(traits, col, teethCol = "white") {
311
- const cx = 32, y = 42;
312
- switch (traits.mouth) {
235
+ function Mouth({ mi, lipColor, isDark }) {
236
+ const cx = 32, y = 45;
237
+ const teethCol = isDark ? "#e8e0d8" : "#ffffff";
238
+ switch (mi) {
313
239
  case 0:
314
- return /* @__PURE__ */ jsx(
315
- "path",
316
- {
317
- d: `M${cx - 4} ${y} Q${cx} ${y + 4} ${cx + 4} ${y}`,
318
- fill: "none",
319
- stroke: col,
320
- strokeWidth: "1.2",
321
- strokeLinecap: "round"
322
- }
323
- );
240
+ return /* @__PURE__ */ jsx("path", { d: `M${cx - 4} ${y} Q${cx} ${y + 4} ${cx + 4} ${y}`, fill: "none", stroke: lipColor, strokeWidth: "1.4", strokeLinecap: "round" });
324
241
  case 1:
325
- return /* @__PURE__ */ jsx(
326
- "line",
327
- {
328
- x1: cx - 3,
329
- y1: y + 1,
330
- x2: cx + 3,
331
- y2: y + 1,
332
- stroke: col,
333
- strokeWidth: "1.2",
334
- strokeLinecap: "round"
335
- }
336
- );
242
+ return /* @__PURE__ */ jsx("line", { x1: cx - 3, y1: y + 1, x2: cx + 3, y2: y + 1, stroke: lipColor, strokeWidth: "1.2", strokeLinecap: "round" });
337
243
  case 2:
338
- return /* @__PURE__ */ jsx(
339
- "path",
340
- {
341
- d: `M${cx - 6} ${y} Q${cx} ${y + 5} ${cx + 6} ${y}`,
342
- fill: "none",
343
- stroke: col,
344
- strokeWidth: "1.5",
345
- strokeLinecap: "round"
346
- }
347
- );
244
+ return /* @__PURE__ */ jsx("path", { d: `M${cx - 5} ${y} Q${cx} ${y + 5} ${cx + 5} ${y}`, fill: "none", stroke: lipColor, strokeWidth: "1.5", strokeLinecap: "round" });
348
245
  case 3:
349
- return /* @__PURE__ */ jsx("ellipse", { cx, cy: y + 1, rx: "3", ry: "2.5", fill: col, opacity: "0.8" });
246
+ return /* @__PURE__ */ jsx("ellipse", { cx, cy: y + 1, rx: "2.5", ry: "3", fill: lipColor, opacity: "0.7" });
350
247
  case 4:
351
- return /* @__PURE__ */ jsx(
352
- "path",
353
- {
354
- d: `M${cx - 4} ${y + 1} Q${cx - 1} ${y + 1} ${cx + 4} ${y - 1}`,
355
- fill: "none",
356
- stroke: col,
357
- strokeWidth: "1.2",
358
- strokeLinecap: "round"
359
- }
360
- );
248
+ return /* @__PURE__ */ jsx("path", { d: `M${cx - 4} ${y + 1} Q${cx + 1} ${y + 1} ${cx + 4} ${y - 1.5}`, fill: "none", stroke: lipColor, strokeWidth: "1.3", strokeLinecap: "round" });
361
249
  case 5:
362
- return /* @__PURE__ */ jsx(
363
- "path",
364
- {
365
- d: `M${cx - 6} ${y} Q${cx} ${y + 6} ${cx + 6} ${y}`,
366
- fill: teethCol,
367
- stroke: col,
368
- strokeWidth: "1"
369
- }
370
- );
250
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
251
+ /* @__PURE__ */ jsx("path", { d: `M${cx - 5} ${y} Q${cx} ${y + 6} ${cx + 5} ${y}`, fill: teethCol, stroke: lipColor, strokeWidth: "1" }),
252
+ /* @__PURE__ */ jsx("line", { x1: cx - 4, y1: y + 1.5, x2: cx + 4, y2: y + 1.5, stroke: lipColor, strokeWidth: "0.3", opacity: "0.3" })
253
+ ] });
254
+ case 6:
255
+ return /* @__PURE__ */ jsx("line", { x1: cx - 4, y1: y + 1, x2: cx + 4, y2: y + 1, stroke: lipColor, strokeWidth: "1.5", strokeLinecap: "round" });
256
+ case 7:
257
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
258
+ /* @__PURE__ */ jsx("ellipse", { cx, cy: y + 1, rx: "3.5", ry: "2", fill: lipColor, opacity: "0.25" }),
259
+ /* @__PURE__ */ jsx("path", { d: `M${cx - 3} ${y} Q${cx} ${y + 2.5} ${cx + 3} ${y}`, fill: "none", stroke: lipColor, strokeWidth: "1.2", strokeLinecap: "round" })
260
+ ] });
371
261
  default:
372
- return /* @__PURE__ */ jsx(
373
- "path",
374
- {
375
- d: `M${cx - 4} ${y} Q${cx} ${y + 4} ${cx + 4} ${y}`,
376
- fill: "none",
377
- stroke: col,
378
- strokeWidth: "1.2",
379
- strokeLinecap: "round"
380
- }
381
- );
262
+ return /* @__PURE__ */ jsx("path", { d: `M${cx - 4} ${y} Q${cx} ${y + 4} ${cx + 4} ${y}`, fill: "none", stroke: lipColor, strokeWidth: "1.4", strokeLinecap: "round" });
382
263
  }
383
264
  }
384
- function renderHair(traits, hairCol) {
385
- switch (traits.hairStyle) {
265
+ function Accessory({ ai, accColor, glassesColor, earringColor, headbandColor }) {
266
+ switch (ai) {
386
267
  case 0:
387
268
  return null;
388
269
  case 1:
389
- return /* @__PURE__ */ jsx("rect", { x: "14", y: "12", width: "36", height: "12", rx: "6", ry: "6", fill: hairCol });
270
+ return /* @__PURE__ */ jsx("circle", { cx: "40", cy: "44", r: "0.8", fill: "#3a2a2a" });
390
271
  case 2:
391
- return /* @__PURE__ */ jsxs("g", { fill: hairCol, children: [
392
- /* @__PURE__ */ jsx("rect", { x: "14", y: "16", width: "36", height: "8", rx: "2" }),
393
- /* @__PURE__ */ jsx("polygon", { points: "18,16 22,6 26,16" }),
394
- /* @__PURE__ */ jsx("polygon", { points: "26,16 30,4 34,16" }),
395
- /* @__PURE__ */ jsx("polygon", { points: "34,16 38,6 42,16" }),
396
- /* @__PURE__ */ jsx("polygon", { points: "42,16 46,10 48,16" })
272
+ return /* @__PURE__ */ jsxs("g", { fill: "none", stroke: glassesColor, strokeWidth: "1", children: [
273
+ /* @__PURE__ */ jsx("circle", { cx: "25", cy: "33", r: "5.5" }),
274
+ /* @__PURE__ */ jsx("circle", { cx: "39", cy: "33", r: "5.5" }),
275
+ /* @__PURE__ */ jsx("line", { x1: "30.5", y1: "33", x2: "33.5", y2: "33" }),
276
+ /* @__PURE__ */ jsx("line", { x1: "19.5", y1: "33", x2: "14", y2: "31" }),
277
+ /* @__PURE__ */ jsx("line", { x1: "44.5", y1: "33", x2: "50", y2: "31" })
397
278
  ] });
398
279
  case 3:
399
- return /* @__PURE__ */ jsxs("g", { fill: hairCol, children: [
400
- /* @__PURE__ */ jsx("rect", { x: "14", y: "14", width: "36", height: "10", rx: "4" }),
401
- /* @__PURE__ */ jsx("path", { d: "M14 18 Q8 14 10 8 Q14 10 20 14 Z" })
280
+ return /* @__PURE__ */ jsxs("g", { fill: "none", stroke: glassesColor, strokeWidth: "1", children: [
281
+ /* @__PURE__ */ jsx("rect", { x: "19", y: "29", width: "12", height: "8", rx: "1.5" }),
282
+ /* @__PURE__ */ jsx("rect", { x: "33", y: "29", width: "12", height: "8", rx: "1.5" }),
283
+ /* @__PURE__ */ jsx("line", { x1: "31", y1: "33", x2: "33", y2: "33" }),
284
+ /* @__PURE__ */ jsx("line", { x1: "19", y1: "33", x2: "14", y2: "31" }),
285
+ /* @__PURE__ */ jsx("line", { x1: "45", y1: "33", x2: "50", y2: "31" })
402
286
  ] });
403
287
  case 4:
404
- return /* @__PURE__ */ jsx("rect", { x: "26", y: "4", width: "12", height: "20", rx: "4", ry: "2", fill: hairCol });
405
- case 5:
406
- return /* @__PURE__ */ jsxs("g", { fill: hairCol, children: [
407
- /* @__PURE__ */ jsx("rect", { x: "14", y: "12", width: "36", height: "10", rx: "4" }),
408
- /* @__PURE__ */ jsx("rect", { x: "10", y: "18", width: "8", height: "24", rx: "3" }),
409
- /* @__PURE__ */ jsx("rect", { x: "46", y: "18", width: "8", height: "24", rx: "3" })
288
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
289
+ /* @__PURE__ */ jsx("circle", { cx: "10", cy: "38", r: "1.5", fill: earringColor }),
290
+ /* @__PURE__ */ jsx("circle", { cx: "10", cy: "41", r: "2", fill: earringColor, opacity: "0.8" })
410
291
  ] });
292
+ case 5:
293
+ return /* @__PURE__ */ jsx("rect", { x: "13", y: "20", width: "38", height: "3.5", rx: "1.5", fill: headbandColor, opacity: "0.85" });
411
294
  case 6:
412
- return /* @__PURE__ */ jsx(
413
- "path",
414
- {
415
- d: "M12 22 Q12 10 32 10 Q52 10 52 22 L52 38 Q52 42 48 42 L48 26 Q48 16 32 16 Q16 16 16 26 L16 42 Q12 42 12 38 Z",
416
- fill: hairCol
417
- }
418
- );
295
+ return /* @__PURE__ */ jsxs("g", { fill: "#a0785a", opacity: "0.35", children: [
296
+ /* @__PURE__ */ jsx("circle", { cx: "21", cy: "40", r: "0.6" }),
297
+ /* @__PURE__ */ jsx("circle", { cx: "23", cy: "42", r: "0.5" }),
298
+ /* @__PURE__ */ jsx("circle", { cx: "19", cy: "41.5", r: "0.5" }),
299
+ /* @__PURE__ */ jsx("circle", { cx: "43", cy: "40", r: "0.6" }),
300
+ /* @__PURE__ */ jsx("circle", { cx: "41", cy: "42", r: "0.5" }),
301
+ /* @__PURE__ */ jsx("circle", { cx: "45", cy: "41.5", r: "0.5" })
302
+ ] });
419
303
  case 7:
420
- return /* @__PURE__ */ jsx("rect", { x: "15", y: "13", width: "34", height: "9", rx: "8", ry: "4", fill: hairCol, opacity: "0.7" });
421
- default:
422
- return null;
423
- }
424
- }
425
- function renderAccessory(traits, col) {
426
- switch (traits.accessory) {
427
- case 0:
428
- case 1:
429
- return null;
430
- case 2:
431
- return /* @__PURE__ */ jsxs("g", { fill: "none", stroke: col, strokeWidth: "1", children: [
432
- /* @__PURE__ */ jsx("circle", { cx: "24", cy: "30", r: "5" }),
433
- /* @__PURE__ */ jsx("circle", { cx: "40", cy: "30", r: "5" }),
434
- /* @__PURE__ */ jsx("line", { x1: "29", y1: "30", x2: "35", y2: "30" }),
435
- /* @__PURE__ */ jsx("line", { x1: "19", y1: "30", x2: "14", y2: "28" }),
436
- /* @__PURE__ */ jsx("line", { x1: "45", y1: "30", x2: "50", y2: "28" })
304
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
305
+ /* @__PURE__ */ jsx("circle", { cx: "10", cy: "37", r: "1.2", fill: earringColor }),
306
+ /* @__PURE__ */ jsx("circle", { cx: "54", cy: "37", r: "1.2", fill: earringColor })
437
307
  ] });
438
- case 3:
439
- return /* @__PURE__ */ jsxs("g", { fill: "none", stroke: col, strokeWidth: "1", children: [
440
- /* @__PURE__ */ jsx("rect", { x: "19", y: "26", width: "10", height: "8", rx: "1" }),
441
- /* @__PURE__ */ jsx("rect", { x: "35", y: "26", width: "10", height: "8", rx: "1" }),
442
- /* @__PURE__ */ jsx("line", { x1: "29", y1: "30", x2: "35", y2: "30" }),
443
- /* @__PURE__ */ jsx("line", { x1: "19", y1: "30", x2: "14", y2: "28" }),
444
- /* @__PURE__ */ jsx("line", { x1: "45", y1: "30", x2: "50", y2: "28" })
308
+ case 8:
309
+ return /* @__PURE__ */ jsxs("g", { fill: "none", stroke: glassesColor, strokeWidth: "1.2", children: [
310
+ /* @__PURE__ */ jsx("path", { d: "M19 30 Q19 28 25 28 Q31 28 31 33 Q31 38 25 38 Q19 38 19 33 Z", fill: glassesColor, fillOpacity: "0.15" }),
311
+ /* @__PURE__ */ jsx("path", { d: "M33 30 Q33 28 39 28 Q45 28 45 33 Q45 38 39 38 Q33 38 33 33 Z", fill: glassesColor, fillOpacity: "0.15" }),
312
+ /* @__PURE__ */ jsx("line", { x1: "31", y1: "32", x2: "33", y2: "32" }),
313
+ /* @__PURE__ */ jsx("line", { x1: "19", y1: "31", x2: "14", y2: "29" }),
314
+ /* @__PURE__ */ jsx("line", { x1: "45", y1: "31", x2: "50", y2: "29" })
445
315
  ] });
446
- case 4:
447
- return /* @__PURE__ */ jsx("circle", { cx: "11", cy: "36", r: "2", fill: col, stroke: col, strokeWidth: "0.5" });
448
- case 5:
316
+ case 9:
449
317
  return /* @__PURE__ */ jsxs("g", { children: [
450
- /* @__PURE__ */ jsx("rect", { x: "12", y: "20", width: "40", height: "4", rx: "1", fill: col }),
451
- /* @__PURE__ */ jsx("path", { d: "M12 22 L8 26 L12 24 Z", fill: col })
318
+ /* @__PURE__ */ jsx("rect", { x: "38", y: "38", width: "8", height: "4", rx: "1", fill: "#f0d0a0", transform: "rotate(-15 42 40)" }),
319
+ /* @__PURE__ */ jsx("line", { x1: "40", y1: "39", x2: "40", y2: "41", stroke: "#c0a080", strokeWidth: "0.4", transform: "rotate(-15 42 40)" }),
320
+ /* @__PURE__ */ jsx("line", { x1: "42", y1: "39", x2: "42", y2: "41", stroke: "#c0a080", strokeWidth: "0.4", transform: "rotate(-15 42 40)" }),
321
+ /* @__PURE__ */ jsx("line", { x1: "44", y1: "39", x2: "44", y2: "41", stroke: "#c0a080", strokeWidth: "0.4", transform: "rotate(-15 42 40)" })
452
322
  ] });
453
323
  default:
454
324
  return null;
455
325
  }
456
326
  }
327
+ function PixelWrapper({ svgString, size, theme }) {
328
+ const density = theme._pixelDensity ?? 16;
329
+ const rounded = theme._pixelRounded ?? true;
330
+ const outline = theme._pixelOutline ?? false;
331
+ const outlineColor = theme._pixelOutlineColor ?? "#000";
332
+ const outlineWidth = theme._pixelOutlineWidth ?? 1;
333
+ const scanlines = theme._pixelScanlines ?? false;
334
+ const scanlineOpacity = theme._pixelScanlineOpacity ?? 0.08;
335
+ const scanlineSpacing = theme._pixelScanlineSpacing ?? 2;
336
+ const grid = theme._pixelGrid ?? false;
337
+ const gridOpacity = theme._pixelGridOpacity ?? 0.06;
338
+ const gridColor = theme._pixelGridColor ?? "#000";
339
+ const shadow = theme._pixelShadow ?? false;
340
+ const shadowColor = theme._pixelShadowColor ?? "rgba(0,0,0,0.3)";
341
+ const shadowOffset = theme._pixelShadowOffset ?? 2;
342
+ const contrast = theme._pixelContrast;
343
+ const saturation = theme._pixelSaturation;
344
+ const brightness = theme._pixelBrightness;
345
+ const dataUri = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
346
+ const filters = [];
347
+ if (shadow) filters.push(`drop-shadow(${shadowOffset}px ${shadowOffset}px 0px ${shadowColor})`);
348
+ if (contrast !== void 0) filters.push(`contrast(${contrast})`);
349
+ if (saturation !== void 0) filters.push(`saturate(${saturation})`);
350
+ if (brightness !== void 0) filters.push(`brightness(${brightness})`);
351
+ const containerStyle = {
352
+ position: "relative",
353
+ width: size,
354
+ height: size,
355
+ display: "inline-block",
356
+ ...filters.length ? { filter: filters.join(" ") } : {}
357
+ };
358
+ const imgStyle = {
359
+ width: size,
360
+ height: size,
361
+ imageRendering: "pixelated",
362
+ borderRadius: rounded ? "12%" : 0,
363
+ display: "block",
364
+ border: outline ? `${outlineWidth}px solid ${outlineColor}` : "none"
365
+ };
366
+ return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
367
+ /* @__PURE__ */ jsx("img", { src: dataUri, width: density, height: density, style: imgStyle, alt: "" }),
368
+ scanlines && /* @__PURE__ */ jsx("div", { style: {
369
+ position: "absolute",
370
+ inset: 0,
371
+ background: `repeating-linear-gradient(0deg, transparent, transparent ${scanlineSpacing}px, rgba(0,0,0,${scanlineOpacity}) ${scanlineSpacing}px, rgba(0,0,0,${scanlineOpacity}) ${scanlineSpacing + 1}px)`,
372
+ pointerEvents: "none",
373
+ borderRadius: rounded ? "12%" : 0
374
+ } }),
375
+ grid && /* @__PURE__ */ jsx("div", { style: {
376
+ position: "absolute",
377
+ inset: 0,
378
+ backgroundSize: `${size / density}px ${size / density}px`,
379
+ backgroundImage: `linear-gradient(${gridColor} ${gridOpacity}, transparent ${gridOpacity}), linear-gradient(90deg, ${gridColor} ${gridOpacity}, transparent ${gridOpacity})`,
380
+ pointerEvents: "none",
381
+ borderRadius: rounded ? "12%" : 0
382
+ } })
383
+ ] });
384
+ }
385
+ function GlassWrapper({ children, size, theme }) {
386
+ const blurRadius = theme._blurRadius ?? 12;
387
+ const saturate = theme._saturate ?? 1.8;
388
+ const tintOpacity = theme._tintOpacity ?? 0.12;
389
+ const tintColor = theme._tintColor ?? "rgba(255,255,255,1)";
390
+ const borderOpacity = theme._borderOpacity ?? 0.25;
391
+ const borderWidth = theme._borderWidth ?? 1;
392
+ const borderColor = theme._borderColor ?? `rgba(255,255,255,${borderOpacity})`;
393
+ const specularOpacity = theme._specularOpacity ?? 0.25;
394
+ const specularColor = theme._specularColor ?? "rgba(255,255,255,1)";
395
+ const specularEnd = theme._specularEnd ?? 50;
396
+ const lightAngle = theme._lightAngle ?? 135;
397
+ const rimIntensity = theme._rimIntensity ?? 0.08;
398
+ const shadowStr = theme._shadow ?? "0 8px 32px rgba(0,0,0,0.12)";
399
+ const bgRadius = theme.bgRadius ?? 16;
400
+ const containerStyle = {
401
+ position: "relative",
402
+ width: size,
403
+ height: size,
404
+ display: "inline-block",
405
+ borderRadius: bgRadius,
406
+ overflow: "hidden",
407
+ backdropFilter: `blur(${blurRadius}px) saturate(${saturate})`,
408
+ WebkitBackdropFilter: `blur(${blurRadius}px) saturate(${saturate})`,
409
+ border: `${borderWidth}px solid ${borderColor}`,
410
+ boxShadow: shadowStr
411
+ };
412
+ return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
413
+ /* @__PURE__ */ jsx("div", { style: {
414
+ position: "absolute",
415
+ inset: 0,
416
+ backgroundColor: tintColor,
417
+ opacity: tintOpacity,
418
+ borderRadius: bgRadius,
419
+ pointerEvents: "none"
420
+ } }),
421
+ /* @__PURE__ */ jsx("div", { style: { position: "relative", zIndex: 1 }, children }),
422
+ /* @__PURE__ */ jsx("div", { style: {
423
+ position: "absolute",
424
+ inset: 0,
425
+ background: `linear-gradient(${lightAngle}deg, ${specularColor.replace("1)", `${specularOpacity})`)} 0%, transparent ${specularEnd}%)`,
426
+ borderRadius: bgRadius,
427
+ pointerEvents: "none"
428
+ } }),
429
+ /* @__PURE__ */ jsx("div", { style: {
430
+ position: "absolute",
431
+ inset: 0,
432
+ borderRadius: bgRadius,
433
+ boxShadow: `inset 0 0 0 1px rgba(255,255,255,${rimIntensity})`,
434
+ pointerEvents: "none"
435
+ } })
436
+ ] });
437
+ }
457
438
  function SolFace({
458
439
  walletAddress,
459
440
  size = 64,
@@ -461,6 +442,7 @@ function SolFace({
461
442
  theme,
462
443
  traitOverrides,
463
444
  colorOverrides,
445
+ detail: detailProp,
464
446
  className,
465
447
  style,
466
448
  ...rest
@@ -469,6 +451,9 @@ function SolFace({
469
451
  () => generateTraits(walletAddress, traitOverrides),
470
452
  [walletAddress, traitOverrides]
471
453
  );
454
+ const detailOpt = detailProp ?? "auto";
455
+ const full = detailOpt === "full" || detailOpt === "auto" && size >= 48;
456
+ const flat = theme?.flat ?? false;
472
457
  const skinColors = theme?.skinColors ?? SKIN_COLORS;
473
458
  const eyeColors = theme?.eyeColors ?? EYE_COLORS;
474
459
  const hairColors = theme?.hairColors ?? HAIR_COLORS;
@@ -477,19 +462,40 @@ function SolFace({
477
462
  const eyeCol = colorOverrides?.eyes ?? eyeColors[traits.eyeColor % eyeColors.length];
478
463
  const hairCol = colorOverrides?.hair ?? hairColors[traits.hairColor % hairColors.length];
479
464
  const bgCol = colorOverrides?.bg ?? bgColors[traits.bgColor % bgColors.length];
480
- const bgOpacity = theme?.bgOpacity ?? 0.15;
465
+ const derived = useMemo(() => deriveSkinColors(skin), [skin]);
466
+ const bgOpacity = theme?.bgOpacity ?? 1;
481
467
  const bgRadius = theme?.bgRadius ?? 4;
482
- const mouthCol = colorOverrides?.mouth ?? theme?.mouthColor ?? "#c05050";
483
- const browCol = colorOverrides?.eyebrow ?? theme?.eyebrowColor ?? "#2a2020";
484
- const accCol = colorOverrides?.accessory ?? theme?.accessoryColor ?? "#444";
485
- const eyeWhite = colorOverrides?.eyeWhite ?? theme?.eyeWhiteColor ?? "white";
486
- const noseCol = colorOverrides?.nose ?? theme?.noseColor;
487
- const uid = useMemo(() => `sf-${walletAddress.slice(0, 8)}`, [walletAddress]);
468
+ const browColor = colorOverrides?.eyebrow ?? theme?.eyebrowColor ?? derived.browColor;
469
+ const noseFill = colorOverrides?.nose ?? theme?.noseColor ?? derived.noseFill;
470
+ const lipColor = colorOverrides?.mouth ?? theme?.mouthColor ?? derived.lipColor;
471
+ const accColor = colorOverrides?.accessory ?? theme?.accessoryColor ?? derived.accessoryColor;
472
+ const eyeWhite = colorOverrides?.eyeWhite ?? theme?.eyeWhiteColor ?? derived.eyeWhiteAdapted;
473
+ const glassesColor = theme?.glassesColor ?? "#4a4a5a";
474
+ const earringColor = theme?.earringColor ?? blend(skin, "#d4a840", 0.4);
475
+ const headbandColor = theme?.headbandColor ?? blend(hairCol, "#c04040", 0.5);
476
+ const id = useMemo(() => "sf" + djb2(walletAddress).toString(36), [walletAddress]);
477
+ const cheekEnabled = theme?.cheekEnabled ?? true;
478
+ const cheekColor = theme?.cheekColor ?? derived.cheekColor;
479
+ const cheekOpacity = theme?.cheekOpacity ?? derived.cheekOpacity;
480
+ const hi = traits.hairStyle % 10;
481
+ const ai = effectiveAccessory(traits);
488
482
  const blinkEnabled = !!enableBlink;
489
483
  const blinkDuration = typeof enableBlink === "object" ? enableBlink.duration ?? 4 : 4;
490
484
  const blinkDelay = typeof enableBlink === "object" ? enableBlink.delay ?? 0 : 0;
491
485
  const delayStr = blinkDelay ? ` ${blinkDelay}s` : "";
492
- return /* @__PURE__ */ jsxs(
486
+ const bgFill = flat ? bgCol : `url(#${id}bg)`;
487
+ const skinFill = flat ? skin : `url(#${id}sg)`;
488
+ if (theme?._pixel) {
489
+ const pixelSvg = renderSolFaceSVG(walletAddress, {
490
+ size,
491
+ theme: { ...theme, _pixel: false, _glass: false },
492
+ traitOverrides,
493
+ colorOverrides,
494
+ detail: detailProp
495
+ });
496
+ return /* @__PURE__ */ jsx(PixelWrapper, { svgString: pixelSvg, size, theme });
497
+ }
498
+ const svgElement = /* @__PURE__ */ jsxs(
493
499
  "svg",
494
500
  {
495
501
  xmlns: "http://www.w3.org/2000/svg",
@@ -500,40 +506,68 @@ function SolFace({
500
506
  style: { display: "block", ...style },
501
507
  ...rest,
502
508
  children: [
509
+ !flat && /* @__PURE__ */ jsxs("defs", { children: [
510
+ /* @__PURE__ */ jsxs("linearGradient", { id: `${id}sg`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
511
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: derived.skinHi }),
512
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: derived.skinLo })
513
+ ] }),
514
+ /* @__PURE__ */ jsxs("linearGradient", { id: `${id}hg`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
515
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: lighten(hairCol, 0.15) }),
516
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: darken(hairCol, 0.15) })
517
+ ] }),
518
+ /* @__PURE__ */ jsxs("linearGradient", { id: `${id}bg`, x1: "0", y1: "0", x2: "1", y2: "1", children: [
519
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: lighten(bgCol, 0.12) }),
520
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: darken(bgCol, 0.12) })
521
+ ] }),
522
+ full && cheekEnabled && /* @__PURE__ */ jsxs(Fragment, { children: [
523
+ /* @__PURE__ */ jsxs("radialGradient", { id: `${id}glow`, cx: "0.5", cy: "0.28", r: "0.45", children: [
524
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#ffffff", stopOpacity: 0.1 }),
525
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#ffffff", stopOpacity: 0 })
526
+ ] }),
527
+ /* @__PURE__ */ jsxs("radialGradient", { id: `${id}chin`, cx: "0.5", cy: "0.85", r: "0.35", children: [
528
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: derived.skinLo, stopOpacity: 0.3 }),
529
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: derived.skinLo, stopOpacity: 0 })
530
+ ] }),
531
+ /* @__PURE__ */ jsxs("radialGradient", { id: `${id}cL`, cx: "0.5", cy: "0.5", r: "0.5", children: [
532
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: cheekColor, stopOpacity: cheekOpacity }),
533
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: cheekColor, stopOpacity: 0 })
534
+ ] }),
535
+ /* @__PURE__ */ jsxs("radialGradient", { id: `${id}cR`, cx: "0.5", cy: "0.5", r: "0.5", children: [
536
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: cheekColor, stopOpacity: cheekOpacity }),
537
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: cheekColor, stopOpacity: 0 })
538
+ ] })
539
+ ] })
540
+ ] }),
503
541
  blinkEnabled && /* @__PURE__ */ jsx("style", { children: `
504
- @keyframes ${uid}-blink {
542
+ @keyframes ${id}-blink {
505
543
  0%, 90%, 100% { transform: scaleY(1); }
506
544
  95% { transform: scaleY(0.1); }
507
545
  }
508
- .${uid}-eyes {
509
- animation: ${uid}-blink ${blinkDuration}s ease-in-out${delayStr} infinite;
510
- transform-origin: 32px 30px;
546
+ .${id}-eyes {
547
+ animation: ${id}-blink ${blinkDuration}s ease-in-out${delayStr} infinite;
548
+ transform-origin: 32px 33px;
511
549
  }
512
550
  ` }),
513
- /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: "64", height: "64", fill: bgCol, opacity: bgOpacity, rx: bgRadius }),
514
- renderHair(traits, hairCol),
515
- renderFace(traits, skin),
516
- /* @__PURE__ */ jsx("g", { className: blinkEnabled ? `${uid}-eyes` : void 0, children: renderEyes(traits, eyeCol, eyeWhite) }),
517
- renderEyebrows(traits, browCol),
518
- renderNose(traits, skin, noseCol),
519
- renderMouth(traits, mouthCol, eyeWhite),
520
- renderAccessory(traits, accCol),
521
- theme?.border && /* @__PURE__ */ jsx(
522
- "rect",
523
- {
524
- x: "0",
525
- y: "0",
526
- width: "64",
527
- height: "64",
528
- fill: "none",
529
- stroke: theme.border.color,
530
- strokeWidth: theme.border.width,
531
- rx: bgRadius
532
- }
533
- )
551
+ /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: "64", height: "64", fill: bgFill, opacity: bgOpacity, rx: bgRadius }),
552
+ /* @__PURE__ */ jsx(HairBack, { hi, id, flat }),
553
+ /* @__PURE__ */ jsx(Ears, { earFill: derived.earFill, earShadow: derived.earShadow }),
554
+ /* @__PURE__ */ jsx("rect", { x: "14", y: "16", width: "36", height: "38", rx: "12", ry: "12", fill: skinFill }),
555
+ full && cheekEnabled && !flat && /* @__PURE__ */ jsx(FaceOverlays, { id }),
556
+ ai === 5 && /* @__PURE__ */ jsx(Accessory, { ai: 5, accColor, glassesColor, earringColor, headbandColor }),
557
+ /* @__PURE__ */ jsx(HairFront, { hi, id, hairCol, skin, flat }),
558
+ /* @__PURE__ */ jsx("g", { className: blinkEnabled ? `${id}-eyes` : void 0, children: /* @__PURE__ */ jsx(Eyes, { ei: traits.eyeStyle % 8, eyeCol, eyeWhite, lidColor: derived.lidColor, full }) }),
559
+ /* @__PURE__ */ jsx(Eyebrows, { bi: traits.eyebrows % 5, browColor }),
560
+ /* @__PURE__ */ jsx(Nose, { ni: traits.nose % 4, noseFill }),
561
+ /* @__PURE__ */ jsx(Mouth, { mi: traits.mouth % 8, lipColor, isDark: derived.isDark }),
562
+ ai !== 0 && ai !== 5 && /* @__PURE__ */ jsx(Accessory, { ai, accColor, glassesColor, earringColor, headbandColor }),
563
+ theme?.border && /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: "64", height: "64", fill: "none", stroke: theme.border.color, strokeWidth: theme.border.width, rx: bgRadius })
534
564
  ]
535
565
  }
536
566
  );
567
+ if (theme?._glass) {
568
+ return /* @__PURE__ */ jsx(GlassWrapper, { size, theme, children: svgElement });
569
+ }
570
+ return svgElement;
537
571
  }
538
572
 
539
573
  export { SolFace };