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