@shadowob/shared 0.4.0 → 1.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.
- package/dist/chunk-6H4LIJZC.js +0 -0
- package/dist/chunk-EMLX23LF.js +59 -0
- package/dist/chunk-PXKHJSTK.js +328 -0
- package/dist/constants/index.cjs +87 -0
- package/dist/constants/index.d.cts +55 -0
- package/dist/constants/index.d.ts +55 -0
- package/dist/constants/index.js +10 -0
- package/dist/index.cjs +424 -0
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +35 -0
- package/dist/types/index.cjs +18 -0
- package/dist/types/index.d.cts +278 -0
- package/dist/types/index.d.ts +278 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/index.cjs +362 -0
- package/dist/utils/index.d.cts +41 -0
- package/dist/utils/index.d.ts +41 -0
- package/dist/utils/index.js +26 -0
- package/package.json +22 -5
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/utils/index.ts
|
|
21
|
+
var utils_exports = {};
|
|
22
|
+
__export(utils_exports, {
|
|
23
|
+
CAT_AVATAR_COUNT: () => CAT_AVATAR_COUNT,
|
|
24
|
+
formatDate: () => formatDate,
|
|
25
|
+
generateInviteCode: () => generateInviteCode,
|
|
26
|
+
generateRandomCatConfig: () => generateRandomCatConfig,
|
|
27
|
+
getAllCatAvatars: () => getAllCatAvatars,
|
|
28
|
+
getCatAvatar: () => getCatAvatar,
|
|
29
|
+
getCatAvatarByUserId: () => getCatAvatarByUserId,
|
|
30
|
+
getCatSvgString: () => getCatSvgString,
|
|
31
|
+
isValidEmail: () => isValidEmail,
|
|
32
|
+
renderCatSvg: () => renderCatSvg,
|
|
33
|
+
slugify: () => slugify
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(utils_exports);
|
|
36
|
+
var import_nanoid = require("nanoid");
|
|
37
|
+
|
|
38
|
+
// src/utils/avatar-generator.ts
|
|
39
|
+
var COLORS = {
|
|
40
|
+
bg: [
|
|
41
|
+
"transparent",
|
|
42
|
+
"#1e1f22",
|
|
43
|
+
"#313338",
|
|
44
|
+
"#5865F2",
|
|
45
|
+
"#23a559",
|
|
46
|
+
"#da373c",
|
|
47
|
+
"#f472b6",
|
|
48
|
+
"#3b82f6",
|
|
49
|
+
"#fbbf24",
|
|
50
|
+
"#a855f7",
|
|
51
|
+
"#1abc9c",
|
|
52
|
+
"#f39c12",
|
|
53
|
+
"#e74c3c"
|
|
54
|
+
],
|
|
55
|
+
body: [
|
|
56
|
+
"#2d2d30",
|
|
57
|
+
"#e8842c",
|
|
58
|
+
"#e8e8e8",
|
|
59
|
+
"#7a7a80",
|
|
60
|
+
"#d4a574",
|
|
61
|
+
"#6b8094",
|
|
62
|
+
"#f472b6",
|
|
63
|
+
"#c8d6e5",
|
|
64
|
+
"#3e2723",
|
|
65
|
+
"#bdc3c7",
|
|
66
|
+
"#ffb8b8"
|
|
67
|
+
],
|
|
68
|
+
eyes: [
|
|
69
|
+
"#f8e71c",
|
|
70
|
+
"#00f3ff",
|
|
71
|
+
"#4ade80",
|
|
72
|
+
"#60a5fa",
|
|
73
|
+
"#a855f7",
|
|
74
|
+
"#fbbf24",
|
|
75
|
+
"#f87171",
|
|
76
|
+
"#ffc0cb",
|
|
77
|
+
"#1dd1a1",
|
|
78
|
+
"#e056fd"
|
|
79
|
+
],
|
|
80
|
+
pattern: ["#1a1a1c", "#ffffff", "#5a4a46", "#3d3d40", "#9a9aa0", "#d1ccc0", "#2d3436"]
|
|
81
|
+
};
|
|
82
|
+
function getRandomElement(arr) {
|
|
83
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
84
|
+
}
|
|
85
|
+
function generateRandomCatConfig() {
|
|
86
|
+
return {
|
|
87
|
+
bg: getRandomElement(COLORS.bg),
|
|
88
|
+
bgPattern: getRandomElement(["none", "dots", "stripes", "grid", "stars"]),
|
|
89
|
+
body: getRandomElement(COLORS.body),
|
|
90
|
+
pattern: getRandomElement([
|
|
91
|
+
"none",
|
|
92
|
+
"tabby",
|
|
93
|
+
"tuxedo",
|
|
94
|
+
"siamese",
|
|
95
|
+
"calico",
|
|
96
|
+
"bicolor"
|
|
97
|
+
]),
|
|
98
|
+
patternColor: getRandomElement(COLORS.pattern),
|
|
99
|
+
eyeColor: getRandomElement(COLORS.eyes),
|
|
100
|
+
expression: getRandomElement([
|
|
101
|
+
"smile",
|
|
102
|
+
"open",
|
|
103
|
+
"flat",
|
|
104
|
+
"sad",
|
|
105
|
+
"surprised",
|
|
106
|
+
"kawaii",
|
|
107
|
+
"winking",
|
|
108
|
+
"smirk"
|
|
109
|
+
]),
|
|
110
|
+
decoration: getRandomElement([
|
|
111
|
+
"none",
|
|
112
|
+
"glasses",
|
|
113
|
+
"blush",
|
|
114
|
+
"scar",
|
|
115
|
+
"flower",
|
|
116
|
+
"fish",
|
|
117
|
+
"headband"
|
|
118
|
+
])
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function renderCatSvg(config) {
|
|
122
|
+
const { bg, bgPattern, body, pattern, patternColor, eyeColor, expression, decoration } = config;
|
|
123
|
+
const stroke = "#1a1a1c";
|
|
124
|
+
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">`;
|
|
125
|
+
if (bg && bg !== "transparent") {
|
|
126
|
+
svg += `<rect width="100" height="100" fill="${bg}" rx="20" />`;
|
|
127
|
+
const pColor = `rgba(255,255,255,0.15)`;
|
|
128
|
+
const cleanBg = bg.replace("#", "");
|
|
129
|
+
if (bgPattern === "dots") {
|
|
130
|
+
svg += `<pattern id="p-${cleanBg}-dots" x="0" y="0" width="10" height="10" patternUnits="userSpaceOnUse"><circle cx="2" cy="2" r="2" fill="${pColor}"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-dots)" rx="20" />`;
|
|
131
|
+
} else if (bgPattern === "stripes") {
|
|
132
|
+
svg += `<pattern id="p-${cleanBg}-str" x="0" y="0" width="12" height="12" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="12" stroke="${pColor}" stroke-width="4"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-str)" rx="20" />`;
|
|
133
|
+
} else if (bgPattern === "grid") {
|
|
134
|
+
svg += `<pattern id="p-${cleanBg}-grid" width="16" height="16" patternUnits="userSpaceOnUse"><path d="M 16 0 L 0 0 0 16" fill="none" stroke="${pColor}" stroke-width="1"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-grid)" rx="20" />`;
|
|
135
|
+
} else if (bgPattern === "stars") {
|
|
136
|
+
svg += `<pattern id="p-${cleanBg}-star" width="20" height="20" patternUnits="userSpaceOnUse"><path d="M10,2 L12,8 L18,8 L13,12 L15,18 L10,14 L5,18 L7,12 L2,8 L8,8 Z" fill="${pColor}" transform="scale(0.5) translate(5,5)"/></pattern><rect width="100" height="100" fill="url(#p-${cleanBg}-star)" rx="20" />`;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
svg += `<ellipse cx="50" cy="85" rx="30" ry="6" fill="rgba(0,0,0,0.2)"/>`;
|
|
140
|
+
svg += `<path d="M22,45 C15,22 28,18 34,22 C38,25 40,38 40,38" fill="${body}" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>`;
|
|
141
|
+
svg += `<path d="M78,45 C85,22 72,18 66,22 C62,25 60,38 60,38" fill="${body}" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>`;
|
|
142
|
+
svg += `<path d="M26,38 C22,26 29,24 33,26 C35,28 36,34 36,34" fill="#ffb8b8" opacity="0.8"/>`;
|
|
143
|
+
svg += `<path d="M74,38 C78,26 71,24 67,26 C65,28 64,34 64,34" fill="#ffb8b8" opacity="0.8"/>`;
|
|
144
|
+
svg += `<ellipse cx="50" cy="58" rx="38" ry="30" fill="${body}" stroke="${stroke}" stroke-width="2.5"/>`;
|
|
145
|
+
if (pattern === "tabby") {
|
|
146
|
+
svg += `<path d="M50,30 L50,40 M42,32 L46,39 M58,32 L54,39" stroke="${patternColor}" stroke-width="3" stroke-linecap="round" opacity="0.7"/>`;
|
|
147
|
+
svg += `<path d="M18,55 L26,57 M20,62 L27,62" stroke="${patternColor}" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/>`;
|
|
148
|
+
svg += `<path d="M82,55 L74,57 M80,62 L73,62" stroke="${patternColor}" stroke-width="2.5" stroke-linecap="round" opacity="0.7"/>`;
|
|
149
|
+
} else if (pattern === "tuxedo") {
|
|
150
|
+
svg += `<path d="M50,56 C30,68 28,88 50,88 C72,88 70,68 50,56" fill="${patternColor}" opacity="0.95"/>`;
|
|
151
|
+
svg += `<ellipse cx="50" cy="65" rx="16" ry="12" fill="${patternColor}" opacity="0.95"/>`;
|
|
152
|
+
} else if (pattern === "siamese") {
|
|
153
|
+
svg += `<ellipse cx="50" cy="62" rx="20" ry="16" fill="${patternColor}" opacity="0.6"/>`;
|
|
154
|
+
} else if (pattern === "calico") {
|
|
155
|
+
svg += `<path d="M25,40 Q35,30 45,45 Q35,55 25,40" fill="${patternColor}" opacity="0.8"/>`;
|
|
156
|
+
svg += `<path d="M75,45 Q65,60 55,50 Q65,35 75,45" fill="#e8842c" opacity="0.8"/>`;
|
|
157
|
+
} else if (pattern === "bicolor") {
|
|
158
|
+
svg += `<path d="M12,58 Q30,30 50,40 Q60,70 50,88 Q12,88 12,58 Z" fill="${patternColor}" opacity="0.8"/>`;
|
|
159
|
+
}
|
|
160
|
+
if (decoration === "blush") {
|
|
161
|
+
svg += `<ellipse cx="28" cy="62" rx="5" ry="3" fill="#ff7675" opacity="0.7"/>`;
|
|
162
|
+
svg += `<ellipse cx="72" cy="62" rx="5" ry="3" fill="#ff7675" opacity="0.7"/>`;
|
|
163
|
+
}
|
|
164
|
+
if (decoration === "scar") {
|
|
165
|
+
svg += `<path d="M28,42 L40,52 M30,48 L35,43 M34,51 L39,46 M32,53 L37,48" stroke="#d63031" stroke-width="1.5" stroke-linecap="round"/>`;
|
|
166
|
+
}
|
|
167
|
+
const drawEye = (cx, cy, lookDir = 0) => {
|
|
168
|
+
if (expression === "kawaii") {
|
|
169
|
+
return `<path d="M${cx - 8},${cy} Q${cx},${cy - 8} ${cx + 8},${cy} Q${cx},${cy - 3} ${cx - 8},${cy}" fill="${eyeColor}" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx + lookDir}" cy="${cy - 2}" r="3" fill="white"/><circle cx="${cx - 3 + lookDir}" cy="${cy}" r="1" fill="white"/>`;
|
|
170
|
+
} else if (expression === "winking" && cx > 50) {
|
|
171
|
+
return `<path d="M${cx - 7},${cy + 2} Q${cx},${cy - 4} ${cx + 7},${cy + 2}" fill="none" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round"/>`;
|
|
172
|
+
} else if (expression === "surprised") {
|
|
173
|
+
return `<circle cx="${cx}" cy="${cy}" r="8" fill="white" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx}" cy="${cy}" r="3" fill="${eyeColor}"/>`;
|
|
174
|
+
} else {
|
|
175
|
+
return `<circle cx="${cx}" cy="${cy}" r="7.5" fill="${eyeColor}" stroke="${stroke}" stroke-width="1.5"/><circle cx="${cx - 2 + lookDir}" cy="${cy - 2}" r="2.5" fill="white"/><circle cx="${cx + 2 + lookDir}" cy="${cy + 1}" r="1" fill="white"/>`;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
if (expression === "smirk") {
|
|
179
|
+
svg += `<path d="M26,50 L42,50" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round"/>`;
|
|
180
|
+
svg += drawEye(66, 52, 2);
|
|
181
|
+
} else {
|
|
182
|
+
svg += drawEye(34, 52, 0);
|
|
183
|
+
svg += drawEye(66, 52, 0);
|
|
184
|
+
}
|
|
185
|
+
if (decoration === "glasses") {
|
|
186
|
+
svg += `<circle cx="34" cy="52" r="11" fill="rgba(255,255,255,0.2)" stroke="#2d3436" stroke-width="2.5"/>`;
|
|
187
|
+
svg += `<circle cx="66" cy="52" r="11" fill="rgba(255,255,255,0.2)" stroke="#2d3436" stroke-width="2.5"/>`;
|
|
188
|
+
svg += `<path d="M45,50 Q50,48 55,50" fill="none" stroke="#2d3436" stroke-width="2.5" stroke-linecap="round"/>`;
|
|
189
|
+
}
|
|
190
|
+
svg += `<path d="M47,62 L53,62 L50,65 Z" fill="#ff9ff3" stroke="${stroke}" stroke-width="1" stroke-linejoin="round"/>`;
|
|
191
|
+
if (expression === "smile" || expression === "kawaii" || expression === "winking") {
|
|
192
|
+
svg += `<path d="M42,67 Q46,72 50,67 M50,67 Q54,72 58,67" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`;
|
|
193
|
+
} else if (expression === "open") {
|
|
194
|
+
svg += `<path d="M46,67 Q50,75 54,67 Z" fill="#ff7675" stroke="${stroke}" stroke-width="1.5" stroke-linejoin="round"/>`;
|
|
195
|
+
} else if (expression === "flat") {
|
|
196
|
+
svg += `<path d="M47,68 L53,68" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`;
|
|
197
|
+
} else if (expression === "sad") {
|
|
198
|
+
svg += `<path d="M43,70 Q50,64 57,70" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`;
|
|
199
|
+
} else if (expression === "surprised") {
|
|
200
|
+
svg += `<circle cx="50" cy="70" r="3" fill="#1a1a1c"/>`;
|
|
201
|
+
} else if (expression === "smirk") {
|
|
202
|
+
svg += `<path d="M46,67 Q52,69 56,64" fill="none" stroke="${stroke}" stroke-width="2" stroke-linecap="round"/>`;
|
|
203
|
+
}
|
|
204
|
+
svg += `<path d="M28,62 L15,60 M28,65 L14,66" stroke="${stroke}" stroke-width="1.5" stroke-linecap="round" opacity="0.6"/>`;
|
|
205
|
+
svg += `<path d="M72,62 L85,60 M72,65 L86,66" stroke="${stroke}" stroke-width="1.5" stroke-linecap="round" opacity="0.6"/>`;
|
|
206
|
+
if (decoration === "headband") {
|
|
207
|
+
svg += `<path d="M16,35 Q50,20 84,35" fill="none" stroke="#e17055" stroke-width="6" stroke-linecap="round"/>`;
|
|
208
|
+
svg += `<path d="M50,15 L60,25 L50,28 L40,25 Z" fill="#fab1a0" stroke="#e17055" stroke-width="2"/>`;
|
|
209
|
+
} else if (decoration === "flower") {
|
|
210
|
+
svg += `<path d="M75,30 Q80,20 85,30 Q95,25 85,35 Q90,45 80,40 Q70,45 75,35 Q65,25 75,30 Z" fill="#ffeaa7" stroke="#fdcb6e" stroke-width="1.5"/>`;
|
|
211
|
+
svg += `<circle cx="80" cy="33" r="3" fill="#d63031"/>`;
|
|
212
|
+
} else if (decoration === "fish") {
|
|
213
|
+
svg += `<path d="M40,82 Q50,75 60,82 L65,78 L65,86 L60,82 Q50,89 40,82 Z" fill="#81ecec" stroke="${stroke}" stroke-width="1.5"/>`;
|
|
214
|
+
svg += `<circle cx="45" cy="81" r="1" fill="${stroke}"/>`;
|
|
215
|
+
}
|
|
216
|
+
svg += `</svg>`;
|
|
217
|
+
return `data:image/svg+xml,${encodeURIComponent(svg.replace(/\n\s*/g, ""))}`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/utils/pixel-cats.ts
|
|
221
|
+
var variants = [
|
|
222
|
+
// 0: Shadow — Black cat (logo style)
|
|
223
|
+
{
|
|
224
|
+
body: "#2d2d30",
|
|
225
|
+
stroke: "#1a1a1c",
|
|
226
|
+
earInner: "#3d3d40",
|
|
227
|
+
eyeL: "#f8e71c",
|
|
228
|
+
eyeR: "#00f3ff",
|
|
229
|
+
nose: "#3a2a26"
|
|
230
|
+
},
|
|
231
|
+
// 1: Mikan — Orange tabby
|
|
232
|
+
{
|
|
233
|
+
body: "#e8842c",
|
|
234
|
+
stroke: "#1a1a1c",
|
|
235
|
+
earInner: "#f5a623",
|
|
236
|
+
eyeL: "#4ade80",
|
|
237
|
+
eyeR: "#4ade80",
|
|
238
|
+
nose: "#d46b1a"
|
|
239
|
+
},
|
|
240
|
+
// 2: Yuki — White cat
|
|
241
|
+
{
|
|
242
|
+
body: "#e8e8e8",
|
|
243
|
+
stroke: "#a0a0a0",
|
|
244
|
+
earInner: "#ffc0cb",
|
|
245
|
+
eyeL: "#60a5fa",
|
|
246
|
+
eyeR: "#60a5fa",
|
|
247
|
+
nose: "#f5a0b0"
|
|
248
|
+
},
|
|
249
|
+
// 3: Haiiro — Gray cat
|
|
250
|
+
{
|
|
251
|
+
body: "#7a7a80",
|
|
252
|
+
stroke: "#4a4a50",
|
|
253
|
+
earInner: "#9a9aa0",
|
|
254
|
+
eyeL: "#fbbf24",
|
|
255
|
+
eyeR: "#fbbf24",
|
|
256
|
+
nose: "#5a4a46"
|
|
257
|
+
},
|
|
258
|
+
// 4: Tuxedo — Black & white accents
|
|
259
|
+
{
|
|
260
|
+
body: "#2d2d30",
|
|
261
|
+
stroke: "#1a1a1c",
|
|
262
|
+
earInner: "#e0e0e0",
|
|
263
|
+
eyeL: "#22c55e",
|
|
264
|
+
eyeR: "#22c55e",
|
|
265
|
+
nose: "#3a2a26"
|
|
266
|
+
},
|
|
267
|
+
// 5: Mocha — Cream/beige
|
|
268
|
+
{
|
|
269
|
+
body: "#d4a574",
|
|
270
|
+
stroke: "#8b6914",
|
|
271
|
+
earInner: "#e8c9a0",
|
|
272
|
+
eyeL: "#d97706",
|
|
273
|
+
eyeR: "#d97706",
|
|
274
|
+
nose: "#a0705a"
|
|
275
|
+
},
|
|
276
|
+
// 6: Blue — Russian blue
|
|
277
|
+
{
|
|
278
|
+
body: "#6b8094",
|
|
279
|
+
stroke: "#3d5060",
|
|
280
|
+
earInner: "#8ba0b4",
|
|
281
|
+
eyeL: "#22c55e",
|
|
282
|
+
eyeR: "#22c55e",
|
|
283
|
+
nose: "#5a6a76"
|
|
284
|
+
},
|
|
285
|
+
// 7: Sakura — Fantasy pink
|
|
286
|
+
{
|
|
287
|
+
body: "#f472b6",
|
|
288
|
+
stroke: "#be185d",
|
|
289
|
+
earInner: "#f9a8d4",
|
|
290
|
+
eyeL: "#a855f7",
|
|
291
|
+
eyeR: "#c084fc",
|
|
292
|
+
nose: "#d44a8c"
|
|
293
|
+
}
|
|
294
|
+
];
|
|
295
|
+
function makeCatSvg(c) {
|
|
296
|
+
return [
|
|
297
|
+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">',
|
|
298
|
+
`<path d="M22,45 Q15,22 28,22 Q34,22 40,38" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5" stroke-linecap="round"/>`,
|
|
299
|
+
`<path d="M78,45 Q85,22 72,22 Q66,22 60,38" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5" stroke-linecap="round"/>`,
|
|
300
|
+
`<path d="M26,38 Q22,26 29,26 Q33,26 36,34" fill="${c.earInner}" opacity="0.5"/>`,
|
|
301
|
+
`<path d="M74,38 Q78,26 71,26 Q67,26 64,34" fill="${c.earInner}" opacity="0.5"/>`,
|
|
302
|
+
`<ellipse cx="50" cy="58" rx="36" ry="28" fill="${c.body}" stroke="${c.stroke}" stroke-width="2.5"/>`,
|
|
303
|
+
`<circle cx="35" cy="52" r="7" fill="${c.eyeL}" stroke="${c.stroke}" stroke-width="1.5"/>`,
|
|
304
|
+
`<circle cx="33" cy="49" r="2.5" fill="white"/>`,
|
|
305
|
+
`<circle cx="65" cy="52" r="7" fill="${c.eyeR}" stroke="${c.stroke}" stroke-width="1.5"/>`,
|
|
306
|
+
`<circle cx="63" cy="49" r="2.5" fill="white"/>`,
|
|
307
|
+
`<ellipse cx="50" cy="62" rx="3.5" ry="2.2" fill="${c.nose}"/>`,
|
|
308
|
+
`<path d="M42,67 Q46,72 50,67" fill="none" stroke="${c.stroke}" stroke-width="2" stroke-linecap="round"/>`,
|
|
309
|
+
`<path d="M50,67 Q54,72 58,67" fill="none" stroke="${c.stroke}" stroke-width="2" stroke-linecap="round"/>`,
|
|
310
|
+
"</svg>"
|
|
311
|
+
].join("");
|
|
312
|
+
}
|
|
313
|
+
var catDataUris = variants.map((v) => {
|
|
314
|
+
const svg = makeCatSvg(v);
|
|
315
|
+
return `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
316
|
+
});
|
|
317
|
+
function getCatAvatar(index) {
|
|
318
|
+
return catDataUris[index % catDataUris.length];
|
|
319
|
+
}
|
|
320
|
+
function getCatAvatarByUserId(userId) {
|
|
321
|
+
let hash = 0;
|
|
322
|
+
for (let i = 0; i < userId.length; i++) {
|
|
323
|
+
hash = (hash << 5) - hash + userId.charCodeAt(i) | 0;
|
|
324
|
+
}
|
|
325
|
+
return getCatAvatar(Math.abs(hash) % catDataUris.length);
|
|
326
|
+
}
|
|
327
|
+
function getAllCatAvatars() {
|
|
328
|
+
const names = ["\u5F71\u5B50", "\u871C\u67D1", "\u5C0F\u96EA", "\u7070\u7070", "\u71D5\u5C3E\u670D", "\u6469\u5361", "\u84DD\u84DD", "\u5C0F\u6A31"];
|
|
329
|
+
return catDataUris.map((uri, i) => ({ index: i, name: names[i], dataUri: uri }));
|
|
330
|
+
}
|
|
331
|
+
function getCatSvgString(index) {
|
|
332
|
+
return makeCatSvg(variants[index % variants.length]);
|
|
333
|
+
}
|
|
334
|
+
var CAT_AVATAR_COUNT = variants.length;
|
|
335
|
+
|
|
336
|
+
// src/utils/index.ts
|
|
337
|
+
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
338
|
+
var generateInviteCode = (0, import_nanoid.customAlphabet)(alphabet, 8);
|
|
339
|
+
function formatDate(date) {
|
|
340
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
341
|
+
return d.toISOString();
|
|
342
|
+
}
|
|
343
|
+
function isValidEmail(email) {
|
|
344
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
345
|
+
}
|
|
346
|
+
function slugify(text) {
|
|
347
|
+
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
348
|
+
}
|
|
349
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
350
|
+
0 && (module.exports = {
|
|
351
|
+
CAT_AVATAR_COUNT,
|
|
352
|
+
formatDate,
|
|
353
|
+
generateInviteCode,
|
|
354
|
+
generateRandomCatConfig,
|
|
355
|
+
getAllCatAvatars,
|
|
356
|
+
getCatAvatar,
|
|
357
|
+
getCatAvatarByUserId,
|
|
358
|
+
getCatSvgString,
|
|
359
|
+
isValidEmail,
|
|
360
|
+
renderCatSvg,
|
|
361
|
+
slugify
|
|
362
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
type CatPattern = 'none' | 'tabby' | 'tuxedo' | 'siamese' | 'calico' | 'bicolor';
|
|
2
|
+
type CatExpression = 'smile' | 'open' | 'flat' | 'sad' | 'surprised' | 'kawaii' | 'winking' | 'smirk';
|
|
3
|
+
type CatDecoration = 'none' | 'glasses' | 'blush' | 'scar' | 'flower' | 'fish' | 'headband';
|
|
4
|
+
type BgPattern = 'none' | 'dots' | 'stripes' | 'grid' | 'stars';
|
|
5
|
+
interface CatConfig {
|
|
6
|
+
bg: string;
|
|
7
|
+
bgPattern: BgPattern;
|
|
8
|
+
body: string;
|
|
9
|
+
pattern: CatPattern;
|
|
10
|
+
patternColor: string;
|
|
11
|
+
eyeColor: string;
|
|
12
|
+
expression: CatExpression;
|
|
13
|
+
decoration: CatDecoration;
|
|
14
|
+
}
|
|
15
|
+
declare function generateRandomCatConfig(): CatConfig;
|
|
16
|
+
declare function renderCatSvg(config: CatConfig): string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Pixel Art Cat Avatar System
|
|
20
|
+
* 8 unique cat variants with distinct color schemes inspired by the Shadow logo
|
|
21
|
+
*/
|
|
22
|
+
/** Get avatar data URI by index (0-7) */
|
|
23
|
+
declare function getCatAvatar(index: number): string;
|
|
24
|
+
/** Get deterministic avatar by user ID string */
|
|
25
|
+
declare function getCatAvatarByUserId(userId: string): string;
|
|
26
|
+
/** Get all cat avatars for selection UI */
|
|
27
|
+
declare function getAllCatAvatars(): {
|
|
28
|
+
index: number;
|
|
29
|
+
name: string;
|
|
30
|
+
dataUri: string;
|
|
31
|
+
}[];
|
|
32
|
+
/** Get the raw SVG string for a cat variant (useful for generating PNG files) */
|
|
33
|
+
declare function getCatSvgString(index: number): string;
|
|
34
|
+
declare const CAT_AVATAR_COUNT: number;
|
|
35
|
+
|
|
36
|
+
declare const generateInviteCode: (size?: number) => string;
|
|
37
|
+
declare function formatDate(date: string | Date): string;
|
|
38
|
+
declare function isValidEmail(email: string): boolean;
|
|
39
|
+
declare function slugify(text: string): string;
|
|
40
|
+
|
|
41
|
+
export { type BgPattern, CAT_AVATAR_COUNT, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isValidEmail, renderCatSvg, slugify };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
type CatPattern = 'none' | 'tabby' | 'tuxedo' | 'siamese' | 'calico' | 'bicolor';
|
|
2
|
+
type CatExpression = 'smile' | 'open' | 'flat' | 'sad' | 'surprised' | 'kawaii' | 'winking' | 'smirk';
|
|
3
|
+
type CatDecoration = 'none' | 'glasses' | 'blush' | 'scar' | 'flower' | 'fish' | 'headband';
|
|
4
|
+
type BgPattern = 'none' | 'dots' | 'stripes' | 'grid' | 'stars';
|
|
5
|
+
interface CatConfig {
|
|
6
|
+
bg: string;
|
|
7
|
+
bgPattern: BgPattern;
|
|
8
|
+
body: string;
|
|
9
|
+
pattern: CatPattern;
|
|
10
|
+
patternColor: string;
|
|
11
|
+
eyeColor: string;
|
|
12
|
+
expression: CatExpression;
|
|
13
|
+
decoration: CatDecoration;
|
|
14
|
+
}
|
|
15
|
+
declare function generateRandomCatConfig(): CatConfig;
|
|
16
|
+
declare function renderCatSvg(config: CatConfig): string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Pixel Art Cat Avatar System
|
|
20
|
+
* 8 unique cat variants with distinct color schemes inspired by the Shadow logo
|
|
21
|
+
*/
|
|
22
|
+
/** Get avatar data URI by index (0-7) */
|
|
23
|
+
declare function getCatAvatar(index: number): string;
|
|
24
|
+
/** Get deterministic avatar by user ID string */
|
|
25
|
+
declare function getCatAvatarByUserId(userId: string): string;
|
|
26
|
+
/** Get all cat avatars for selection UI */
|
|
27
|
+
declare function getAllCatAvatars(): {
|
|
28
|
+
index: number;
|
|
29
|
+
name: string;
|
|
30
|
+
dataUri: string;
|
|
31
|
+
}[];
|
|
32
|
+
/** Get the raw SVG string for a cat variant (useful for generating PNG files) */
|
|
33
|
+
declare function getCatSvgString(index: number): string;
|
|
34
|
+
declare const CAT_AVATAR_COUNT: number;
|
|
35
|
+
|
|
36
|
+
declare const generateInviteCode: (size?: number) => string;
|
|
37
|
+
declare function formatDate(date: string | Date): string;
|
|
38
|
+
declare function isValidEmail(email: string): boolean;
|
|
39
|
+
declare function slugify(text: string): string;
|
|
40
|
+
|
|
41
|
+
export { type BgPattern, CAT_AVATAR_COUNT, type CatConfig, type CatDecoration, type CatExpression, type CatPattern, formatDate, generateInviteCode, generateRandomCatConfig, getAllCatAvatars, getCatAvatar, getCatAvatarByUserId, getCatSvgString, isValidEmail, renderCatSvg, slugify };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CAT_AVATAR_COUNT,
|
|
3
|
+
formatDate,
|
|
4
|
+
generateInviteCode,
|
|
5
|
+
generateRandomCatConfig,
|
|
6
|
+
getAllCatAvatars,
|
|
7
|
+
getCatAvatar,
|
|
8
|
+
getCatAvatarByUserId,
|
|
9
|
+
getCatSvgString,
|
|
10
|
+
isValidEmail,
|
|
11
|
+
renderCatSvg,
|
|
12
|
+
slugify
|
|
13
|
+
} from "../chunk-PXKHJSTK.js";
|
|
14
|
+
export {
|
|
15
|
+
CAT_AVATAR_COUNT,
|
|
16
|
+
formatDate,
|
|
17
|
+
generateInviteCode,
|
|
18
|
+
generateRandomCatConfig,
|
|
19
|
+
getAllCatAvatars,
|
|
20
|
+
getCatAvatar,
|
|
21
|
+
getCatAvatarByUserId,
|
|
22
|
+
getCatSvgString,
|
|
23
|
+
isValidEmail,
|
|
24
|
+
renderCatSvg,
|
|
25
|
+
slugify
|
|
26
|
+
};
|
package/package.json
CHANGED
|
@@ -1,25 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shadowob/shared",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"require": "./dist/index.cjs",
|
|
6
8
|
"types": "./dist/index.d.ts",
|
|
7
9
|
"exports": {
|
|
8
10
|
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"development": "./src/index.ts",
|
|
9
13
|
"import": "./dist/index.js",
|
|
10
|
-
"
|
|
14
|
+
"require": "./dist/index.cjs",
|
|
15
|
+
"default": "./dist/index.js"
|
|
11
16
|
},
|
|
12
17
|
"./types": {
|
|
18
|
+
"types": "./dist/types/index.d.ts",
|
|
19
|
+
"development": "./src/types/index.ts",
|
|
13
20
|
"import": "./dist/types/index.js",
|
|
14
|
-
"
|
|
21
|
+
"require": "./dist/types/index.cjs",
|
|
22
|
+
"default": "./dist/types/index.js"
|
|
15
23
|
},
|
|
16
24
|
"./constants": {
|
|
25
|
+
"types": "./dist/constants/index.d.ts",
|
|
26
|
+
"development": "./src/constants/index.ts",
|
|
17
27
|
"import": "./dist/constants/index.js",
|
|
18
|
-
"
|
|
28
|
+
"require": "./dist/constants/index.cjs",
|
|
29
|
+
"default": "./dist/constants/index.js"
|
|
19
30
|
},
|
|
20
31
|
"./utils": {
|
|
32
|
+
"types": "./dist/utils/index.d.ts",
|
|
33
|
+
"development": "./src/utils/index.ts",
|
|
21
34
|
"import": "./dist/utils/index.js",
|
|
22
|
-
"
|
|
35
|
+
"require": "./dist/utils/index.cjs",
|
|
36
|
+
"default": "./dist/utils/index.js"
|
|
23
37
|
}
|
|
24
38
|
},
|
|
25
39
|
"files": [
|
|
@@ -32,6 +46,9 @@
|
|
|
32
46
|
"tsup": "^8.5.0",
|
|
33
47
|
"typescript": "^5.9.3"
|
|
34
48
|
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
35
52
|
"scripts": {
|
|
36
53
|
"build": "tsup",
|
|
37
54
|
"dev": "tsup --watch",
|