sa2kit 2.0.1 → 2.0.2

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 (264) hide show
  1. package/README.md +1 -1
  2. package/dist/CollisionBalls-BpHufX3H.d.mts +41 -0
  3. package/dist/CollisionBalls-BpHufX3H.d.ts +41 -0
  4. package/dist/ConfigService-BxK06xP6.d.mts +262 -0
  5. package/dist/ConfigService-BxK06xP6.d.ts +262 -0
  6. package/dist/UniversalFileService-BpvbZitV.d.mts +139 -0
  7. package/dist/UniversalFileService-GsP6D3Rc.d.ts +139 -0
  8. package/dist/audioDetection/index.d.mts +449 -0
  9. package/dist/audioDetection/index.d.ts +449 -0
  10. package/dist/audioDetection/index.js +1244 -0
  11. package/dist/audioDetection/index.js.map +1 -0
  12. package/dist/audioDetection/index.mjs +1227 -0
  13. package/dist/audioDetection/index.mjs.map +1 -0
  14. package/dist/auth/legacy/core/index.d.mts +42 -0
  15. package/dist/auth/legacy/core/index.d.ts +42 -0
  16. package/dist/auth/legacy/core/index.js +242 -0
  17. package/dist/auth/legacy/core/index.js.map +1 -0
  18. package/dist/auth/legacy/core/index.mjs +226 -0
  19. package/dist/auth/legacy/core/index.mjs.map +1 -0
  20. package/dist/auth/legacy/db/index.d.mts +5 -0
  21. package/dist/auth/legacy/db/index.d.ts +5 -0
  22. package/dist/auth/legacy/db/index.js +261 -0
  23. package/dist/auth/legacy/db/index.js.map +1 -0
  24. package/dist/auth/legacy/db/index.mjs +250 -0
  25. package/dist/auth/legacy/db/index.mjs.map +1 -0
  26. package/dist/auth/legacy/index.d.mts +5 -0
  27. package/dist/auth/legacy/index.d.ts +5 -0
  28. package/dist/auth/legacy/index.js +1107 -0
  29. package/dist/auth/legacy/index.js.map +1 -0
  30. package/dist/auth/legacy/index.mjs +1086 -0
  31. package/dist/auth/legacy/index.mjs.map +1 -0
  32. package/dist/auth/legacy/logic/index.d.mts +9 -0
  33. package/dist/auth/legacy/logic/index.d.ts +9 -0
  34. package/dist/auth/legacy/logic/index.js +194 -0
  35. package/dist/auth/legacy/logic/index.js.map +1 -0
  36. package/dist/auth/legacy/logic/index.mjs +187 -0
  37. package/dist/auth/legacy/logic/index.mjs.map +1 -0
  38. package/dist/auth/legacy/miniapp/index.d.mts +5 -0
  39. package/dist/auth/legacy/miniapp/index.d.ts +5 -0
  40. package/dist/auth/legacy/miniapp/index.js +506 -0
  41. package/dist/auth/legacy/miniapp/index.js.map +1 -0
  42. package/dist/auth/legacy/miniapp/index.mjs +487 -0
  43. package/dist/auth/legacy/miniapp/index.mjs.map +1 -0
  44. package/dist/auth/legacy/routes/index.d.mts +53 -0
  45. package/dist/auth/legacy/routes/index.d.ts +53 -0
  46. package/dist/auth/legacy/routes/index.js +278 -0
  47. package/dist/auth/legacy/routes/index.js.map +1 -0
  48. package/dist/auth/legacy/routes/index.mjs +271 -0
  49. package/dist/auth/legacy/routes/index.mjs.map +1 -0
  50. package/dist/auth/legacy/schema/index.d.mts +401 -0
  51. package/dist/auth/legacy/schema/index.d.ts +401 -0
  52. package/dist/auth/legacy/schema/index.js +50 -0
  53. package/dist/auth/legacy/schema/index.js.map +1 -0
  54. package/dist/auth/legacy/schema/index.mjs +44 -0
  55. package/dist/auth/legacy/schema/index.mjs.map +1 -0
  56. package/dist/auth/legacy/server/index.d.mts +13 -0
  57. package/dist/auth/legacy/server/index.d.ts +13 -0
  58. package/dist/auth/legacy/server/index.js +21 -0
  59. package/dist/auth/legacy/server/index.js.map +1 -0
  60. package/dist/auth/legacy/server/index.mjs +19 -0
  61. package/dist/auth/legacy/server/index.mjs.map +1 -0
  62. package/dist/auth/legacy/services/index.d.mts +40 -0
  63. package/dist/auth/legacy/services/index.d.ts +40 -0
  64. package/dist/auth/legacy/services/index.js +258 -0
  65. package/dist/auth/legacy/services/index.js.map +1 -0
  66. package/dist/auth/legacy/services/index.mjs +252 -0
  67. package/dist/auth/legacy/services/index.mjs.map +1 -0
  68. package/dist/auth/legacy/ui/miniapp/index.d.mts +10 -0
  69. package/dist/auth/legacy/ui/miniapp/index.d.ts +10 -0
  70. package/dist/auth/legacy/ui/miniapp/index.js +298 -0
  71. package/dist/auth/legacy/ui/miniapp/index.js.map +1 -0
  72. package/dist/auth/legacy/ui/miniapp/index.mjs +290 -0
  73. package/dist/auth/legacy/ui/miniapp/index.mjs.map +1 -0
  74. package/dist/auth/legacy/ui/web/index.d.mts +22 -0
  75. package/dist/auth/legacy/ui/web/index.d.ts +22 -0
  76. package/dist/auth/legacy/ui/web/index.js +899 -0
  77. package/dist/auth/legacy/ui/web/index.js.map +1 -0
  78. package/dist/auth/legacy/ui/web/index.mjs +889 -0
  79. package/dist/auth/legacy/ui/web/index.mjs.map +1 -0
  80. package/dist/auth/legacy/web/index.d.mts +5 -0
  81. package/dist/auth/legacy/web/index.d.ts +5 -0
  82. package/dist/auth/legacy/web/index.js +1107 -0
  83. package/dist/auth/legacy/web/index.js.map +1 -0
  84. package/dist/auth/legacy/web/index.mjs +1086 -0
  85. package/dist/auth/legacy/web/index.mjs.map +1 -0
  86. package/dist/auth/rn/index.d.mts +64 -0
  87. package/dist/auth/rn/index.d.ts +64 -0
  88. package/dist/auth/rn/index.js +765 -0
  89. package/dist/auth/rn/index.js.map +1 -0
  90. package/dist/auth/rn/index.mjs +754 -0
  91. package/dist/auth/rn/index.mjs.map +1 -0
  92. package/dist/base-api-client-ACKKt13v.d.mts +277 -0
  93. package/dist/base-api-client-ACKKt13v.d.ts +277 -0
  94. package/dist/boothVaultService-Cn4WPhjg.d.mts +83 -0
  95. package/dist/boothVaultService-Cn4WPhjg.d.ts +83 -0
  96. package/dist/business/index.d.mts +6 -0
  97. package/dist/business/index.d.ts +6 -0
  98. package/dist/business/index.js +1682 -0
  99. package/dist/business/index.js.map +1 -0
  100. package/dist/business/index.mjs +1675 -0
  101. package/dist/business/index.mjs.map +1 -0
  102. package/dist/calendar/index.d.mts +1325 -0
  103. package/dist/calendar/index.d.ts +1325 -0
  104. package/dist/calendar/index.js +5964 -0
  105. package/dist/calendar/index.js.map +1 -0
  106. package/dist/calendar/index.mjs +5878 -0
  107. package/dist/calendar/index.mjs.map +1 -0
  108. package/dist/components/index.d.mts +405 -0
  109. package/dist/components/index.d.ts +405 -0
  110. package/dist/components/index.js +2516 -0
  111. package/dist/components/index.js.map +1 -0
  112. package/dist/components/index.mjs +2396 -0
  113. package/dist/components/index.mjs.map +1 -0
  114. package/dist/drizzle-schema-BNhqj2AZ.d.mts +1114 -0
  115. package/dist/drizzle-schema-BNhqj2AZ.d.ts +1114 -0
  116. package/dist/festivalCard/index.d.mts +75 -0
  117. package/dist/festivalCard/index.d.ts +75 -0
  118. package/dist/festivalCard/index.js +1492 -0
  119. package/dist/festivalCard/index.js.map +1 -0
  120. package/dist/festivalCard/index.mjs +1475 -0
  121. package/dist/festivalCard/index.mjs.map +1 -0
  122. package/dist/festivalCard/server/index.d.mts +120 -0
  123. package/dist/festivalCard/server/index.d.ts +120 -0
  124. package/dist/festivalCard/server/index.js +272 -0
  125. package/dist/festivalCard/server/index.js.map +1 -0
  126. package/dist/festivalCard/server/index.mjs +265 -0
  127. package/dist/festivalCard/server/index.mjs.map +1 -0
  128. package/dist/festivalCardService-CZomuQ4E.d.mts +80 -0
  129. package/dist/festivalCardService-CZomuQ4E.d.ts +80 -0
  130. package/dist/index-1Ag7IBXN.d.ts +144 -0
  131. package/dist/index-DNKZ7-R_.d.mts +184 -0
  132. package/dist/index-DNKZ7-R_.d.ts +184 -0
  133. package/dist/index-DSel44Ke.d.mts +93 -0
  134. package/dist/index-DSel44Ke.d.ts +93 -0
  135. package/dist/index-DdeZSeTJ.d.mts +144 -0
  136. package/dist/index-DrPcMJPc.d.mts +250 -0
  137. package/dist/index-DrPcMJPc.d.ts +250 -0
  138. package/dist/index.d.mts +5333 -0
  139. package/dist/index.d.ts +5333 -0
  140. package/dist/index.js +18809 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/index.mjs +18533 -0
  143. package/dist/index.mjs.map +1 -0
  144. package/dist/mikuContest/ui/web/index.d.mts +2 -0
  145. package/dist/mikuContest/ui/web/index.d.ts +2 -0
  146. package/dist/mikuContest/ui/web/index.js +353 -0
  147. package/dist/mikuContest/ui/web/index.js.map +1 -0
  148. package/dist/mikuContest/ui/web/index.mjs +343 -0
  149. package/dist/mikuContest/ui/web/index.mjs.map +1 -0
  150. package/dist/mikuFireworks3D/index.d.mts +268 -0
  151. package/dist/mikuFireworks3D/index.d.ts +268 -0
  152. package/dist/mikuFireworks3D/index.js +1267 -0
  153. package/dist/mikuFireworks3D/index.js.map +1 -0
  154. package/dist/mikuFireworks3D/index.mjs +1228 -0
  155. package/dist/mikuFireworks3D/index.mjs.map +1 -0
  156. package/dist/mikuFusionGame/index.d.mts +117 -0
  157. package/dist/mikuFusionGame/index.d.ts +117 -0
  158. package/dist/mikuFusionGame/index.js +1208 -0
  159. package/dist/mikuFusionGame/index.js.map +1 -0
  160. package/dist/mikuFusionGame/index.mjs +1195 -0
  161. package/dist/mikuFusionGame/index.mjs.map +1 -0
  162. package/dist/mmd/admin/index.d.mts +487 -0
  163. package/dist/mmd/admin/index.d.ts +487 -0
  164. package/dist/mmd/admin/index.js +1058 -0
  165. package/dist/mmd/admin/index.js.map +1 -0
  166. package/dist/mmd/admin/index.mjs +1027 -0
  167. package/dist/mmd/admin/index.mjs.map +1 -0
  168. package/dist/mmd/index.d.mts +2467 -0
  169. package/dist/mmd/index.d.ts +2467 -0
  170. package/dist/mmd/index.js +10119 -0
  171. package/dist/mmd/index.js.map +1 -0
  172. package/dist/mmd/index.mjs +10028 -0
  173. package/dist/mmd/index.mjs.map +1 -0
  174. package/dist/mmd/server/index.d.mts +139 -0
  175. package/dist/mmd/server/index.d.ts +139 -0
  176. package/dist/mmd/server/index.js +424 -0
  177. package/dist/mmd/server/index.js.map +1 -0
  178. package/dist/mmd/server/index.mjs +404 -0
  179. package/dist/mmd/server/index.mjs.map +1 -0
  180. package/dist/music/index.d.mts +74 -0
  181. package/dist/music/index.d.ts +74 -0
  182. package/dist/music/index.js +830 -0
  183. package/dist/music/index.js.map +1 -0
  184. package/dist/music/index.mjs +809 -0
  185. package/dist/music/index.mjs.map +1 -0
  186. package/dist/music/server/index.d.mts +1 -0
  187. package/dist/music/server/index.d.ts +1 -0
  188. package/dist/music/server/index.js +194 -0
  189. package/dist/music/server/index.js.map +1 -0
  190. package/dist/music/server/index.mjs +182 -0
  191. package/dist/music/server/index.mjs.map +1 -0
  192. package/dist/navigation/index.d.mts +93 -0
  193. package/dist/navigation/index.d.ts +93 -0
  194. package/dist/navigation/index.js +453 -0
  195. package/dist/navigation/index.js.map +1 -0
  196. package/dist/navigation/index.mjs +443 -0
  197. package/dist/navigation/index.mjs.map +1 -0
  198. package/dist/portfolio/index.d.mts +66 -0
  199. package/dist/portfolio/index.d.ts +66 -0
  200. package/dist/portfolio/index.js +736 -0
  201. package/dist/portfolio/index.js.map +1 -0
  202. package/dist/portfolio/index.mjs +724 -0
  203. package/dist/portfolio/index.mjs.map +1 -0
  204. package/dist/qqbot/server/index.d.mts +216 -0
  205. package/dist/qqbot/server/index.d.ts +216 -0
  206. package/dist/qqbot/server/index.js +394 -0
  207. package/dist/qqbot/server/index.js.map +1 -0
  208. package/dist/qqbot/server/index.mjs +385 -0
  209. package/dist/qqbot/server/index.mjs.map +1 -0
  210. package/dist/qqbot/ui/web/index.d.mts +10 -0
  211. package/dist/qqbot/ui/web/index.d.ts +10 -0
  212. package/dist/qqbot/ui/web/index.js +105 -0
  213. package/dist/qqbot/ui/web/index.js.map +1 -0
  214. package/dist/qqbot/ui/web/index.mjs +99 -0
  215. package/dist/qqbot/ui/web/index.mjs.map +1 -0
  216. package/dist/screenReceiver/index.d.mts +86 -0
  217. package/dist/screenReceiver/index.d.ts +86 -0
  218. package/dist/screenReceiver/index.js +281 -0
  219. package/dist/screenReceiver/index.js.map +1 -0
  220. package/dist/screenReceiver/index.mjs +273 -0
  221. package/dist/screenReceiver/index.mjs.map +1 -0
  222. package/dist/testYourself/admin/index.d.mts +58 -0
  223. package/dist/testYourself/admin/index.d.ts +58 -0
  224. package/dist/testYourself/admin/index.js +1009 -0
  225. package/dist/testYourself/admin/index.js.map +1 -0
  226. package/dist/testYourself/admin/index.mjs +1002 -0
  227. package/dist/testYourself/admin/index.mjs.map +1 -0
  228. package/dist/testYourself/index.d.mts +53 -0
  229. package/dist/testYourself/index.d.ts +53 -0
  230. package/dist/testYourself/index.js +2551 -0
  231. package/dist/testYourself/index.js.map +1 -0
  232. package/dist/testYourself/index.mjs +2531 -0
  233. package/dist/testYourself/index.mjs.map +1 -0
  234. package/dist/testYourself/server/index.d.mts +1029 -0
  235. package/dist/testYourself/server/index.d.ts +1029 -0
  236. package/dist/testYourself/server/index.js +825 -0
  237. package/dist/testYourself/server/index.js.map +1 -0
  238. package/dist/testYourself/server/index.mjs +816 -0
  239. package/dist/testYourself/server/index.mjs.map +1 -0
  240. package/dist/types-BTiaMsBz.d.mts +292 -0
  241. package/dist/types-DyG3ZV9V.d.mts +270 -0
  242. package/dist/types-DyG3ZV9V.d.ts +270 -0
  243. package/dist/types-ERmJyjx8.d.ts +292 -0
  244. package/dist/types-HorDyIRv.d.mts +303 -0
  245. package/dist/types-HorDyIRv.d.ts +303 -0
  246. package/dist/vocaloidBooth/index.d.mts +64 -0
  247. package/dist/vocaloidBooth/index.d.ts +64 -0
  248. package/dist/vocaloidBooth/index.js +376 -0
  249. package/dist/vocaloidBooth/index.js.map +1 -0
  250. package/dist/vocaloidBooth/index.mjs +362 -0
  251. package/dist/vocaloidBooth/index.mjs.map +1 -0
  252. package/dist/vocaloidBooth/server/index.d.mts +111 -0
  253. package/dist/vocaloidBooth/server/index.d.ts +111 -0
  254. package/dist/vocaloidBooth/server/index.js +247 -0
  255. package/dist/vocaloidBooth/server/index.js.map +1 -0
  256. package/dist/vocaloidBooth/server/index.mjs +237 -0
  257. package/dist/vocaloidBooth/server/index.mjs.map +1 -0
  258. package/dist/vocaloidBooth/web/index.d.mts +3 -0
  259. package/dist/vocaloidBooth/web/index.d.ts +3 -0
  260. package/dist/vocaloidBooth/web/index.js +376 -0
  261. package/dist/vocaloidBooth/web/index.js.map +1 -0
  262. package/dist/vocaloidBooth/web/index.mjs +362 -0
  263. package/dist/vocaloidBooth/web/index.mjs.map +1 -0
  264. package/package.json +1 -1
@@ -0,0 +1,736 @@
1
+ 'use strict';
2
+
3
+ var React5 = require('react');
4
+ var clsx = require('clsx');
5
+ var tailwindMerge = require('tailwind-merge');
6
+ var Link = require('next/link');
7
+
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var React5__default = /*#__PURE__*/_interopDefault(React5);
11
+ var Link__default = /*#__PURE__*/_interopDefault(Link);
12
+
13
+ // src/portfolio/AboutWithDefaults.tsx
14
+ var About = ({
15
+ timelineConfig,
16
+ collisionBallsConfig,
17
+ Timeline: Timeline2,
18
+ CollisionBalls: CollisionBalls2
19
+ }) => {
20
+ return /* @__PURE__ */ React5__default.default.createElement("section", { id: "about", className: "py-16 bg-white" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React5__default.default.createElement("h2", { className: "text-3xl font-bold text-center mb-12" }, "\u5173\u4E8E\u6211"), /* @__PURE__ */ React5__default.default.createElement("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-12" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "bg-white rounded-lg shadow-lg p-6" }, /* @__PURE__ */ React5__default.default.createElement("h3", { className: "text-2xl font-semibold mb-6" }, "\u4E2A\u4EBA\u7ECF\u5386"), /* @__PURE__ */ React5__default.default.createElement(Timeline2, { items: timelineConfig.items })), /* @__PURE__ */ React5__default.default.createElement("div", { className: "bg-white rounded-lg shadow-lg p-6" }, /* @__PURE__ */ React5__default.default.createElement("h3", { className: "text-2xl font-semibold mb-6" }, "\u6280\u80FD\u5C55\u793A"), /* @__PURE__ */ React5__default.default.createElement("div", { style: { height: "400px", position: "relative" } }, /* @__PURE__ */ React5__default.default.createElement(CollisionBalls2, { collisionBallsConfig }))))));
21
+ };
22
+ var About_default = About;
23
+ var CollisionBalls = ({
24
+ collisionBallsConfig: {
25
+ balls,
26
+ width,
27
+ height
28
+ }
29
+ }) => {
30
+ const canvasRef = React5.useRef(null);
31
+ const containerRef = React5.useRef(null);
32
+ const ballsRef = React5.useRef([]);
33
+ const [isShaking, setIsShaking] = React5.useState(false);
34
+ const [draggedBall, setDraggedBall] = React5.useState(null);
35
+ const [mousePos, setMousePos] = React5.useState({ x: 0, y: 0 });
36
+ const animationRef = React5.useRef(null);
37
+ const updateCanvasSize = () => {
38
+ const container = containerRef.current;
39
+ const canvas = canvasRef.current;
40
+ if (!container || !canvas) {
41
+ console.error("Container or canvas not found");
42
+ return;
43
+ }
44
+ const containerWidth = container.clientWidth;
45
+ const containerHeight = container.clientHeight;
46
+ console.log("Container size:", { containerWidth, containerHeight });
47
+ canvas.width = containerWidth;
48
+ canvas.height = containerHeight;
49
+ canvas.style.width = containerWidth + "px";
50
+ canvas.style.height = containerHeight + "px";
51
+ console.log("Canvas size updated:", {
52
+ width: canvas.width,
53
+ height: canvas.height,
54
+ containerWidth,
55
+ containerHeight
56
+ });
57
+ };
58
+ const initBalls = () => {
59
+ const canvas = canvasRef.current;
60
+ if (!canvas) {
61
+ console.error("Canvas not found during ball initialization");
62
+ return [];
63
+ }
64
+ console.log("Initializing balls with canvas size:", {
65
+ width: canvas.width,
66
+ height: canvas.height
67
+ });
68
+ return balls.map((ballConfig) => ({
69
+ x: Math.random() * (canvas.width - 100) + 50,
70
+ y: Math.random() * (canvas.height - 100) + 50,
71
+ vx: (Math.random() - 0.5) * 4,
72
+ vy: (Math.random() - 0.5) * 4,
73
+ radius: ballConfig.size,
74
+ color: ballConfig.color,
75
+ text: ballConfig.label,
76
+ isDragging: false
77
+ }));
78
+ };
79
+ React5.useEffect(() => {
80
+ const handleResize = () => {
81
+ console.log("Window resized");
82
+ updateCanvasSize();
83
+ };
84
+ if (typeof window !== "undefined") {
85
+ window.addEventListener("resize", handleResize);
86
+ updateCanvasSize();
87
+ }
88
+ return () => {
89
+ if (typeof window !== "undefined") {
90
+ window.removeEventListener("resize", handleResize);
91
+ }
92
+ };
93
+ }, []);
94
+ React5.useEffect(() => {
95
+ const canvas = canvasRef.current;
96
+ if (!canvas) {
97
+ console.error("Canvas element not found");
98
+ return;
99
+ }
100
+ const ctx = canvas.getContext("2d");
101
+ if (!ctx) {
102
+ console.error("Failed to get canvas context");
103
+ return;
104
+ }
105
+ console.log("Starting animation setup...");
106
+ updateCanvasSize();
107
+ ballsRef.current = initBalls();
108
+ console.log("Balls initialized:", ballsRef.current);
109
+ let lastTime = performance.now();
110
+ let frameCount = 0;
111
+ const animate = (currentTime) => {
112
+ try {
113
+ frameCount++;
114
+ if (currentTime - lastTime >= 1e3) {
115
+ console.log("FPS: " + frameCount);
116
+ frameCount = 0;
117
+ lastTime = currentTime;
118
+ }
119
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
120
+ ballsRef.current.forEach((ball) => {
121
+ if (!ball.isDragging) {
122
+ updatePosition(ball, canvas.width, canvas.height);
123
+ }
124
+ for (let i = 0; i < ballsRef.current.length; i++) {
125
+ for (let j = i + 1; j < ballsRef.current.length; j++) {
126
+ const ball1 = ballsRef.current[i];
127
+ const ball2 = ballsRef.current[j];
128
+ if (ball1 && ball2) {
129
+ checkCollision(ball1, ball2);
130
+ }
131
+ }
132
+ }
133
+ draw(ctx, ball);
134
+ });
135
+ animationRef.current = requestAnimationFrame(animate);
136
+ } catch (error) {
137
+ console.error("Animation error:", error);
138
+ }
139
+ };
140
+ console.log("Starting animation loop...");
141
+ animationRef.current = requestAnimationFrame(animate);
142
+ return () => {
143
+ console.log("Cleaning up animation...");
144
+ if (animationRef.current) {
145
+ cancelAnimationFrame(animationRef.current);
146
+ animationRef.current = null;
147
+ }
148
+ };
149
+ }, []);
150
+ const shake = () => {
151
+ setIsShaking(true);
152
+ ballsRef.current.forEach((ball) => {
153
+ ball.vx = (Math.random() - 0.5) * 10;
154
+ ball.vy = (Math.random() - 0.5) * 10;
155
+ });
156
+ setTimeout(() => setIsShaking(false), 200);
157
+ };
158
+ const slowdown = () => {
159
+ setIsShaking(true);
160
+ ballsRef.current.forEach((ball) => {
161
+ ball.vx = ball.vx * 0.5;
162
+ ball.vy = ball.vy * 0.5;
163
+ });
164
+ setTimeout(() => setIsShaking(false), 200);
165
+ };
166
+ const checkCollision = (ball1, ball2) => {
167
+ const dx = ball2.x - ball1.x;
168
+ const dy = ball2.y - ball1.y;
169
+ const distance = Math.sqrt(dx * dx + dy * dy);
170
+ if (distance < ball1.radius + ball2.radius) {
171
+ const angle = Math.atan2(dy, dx);
172
+ const overlap = (ball1.radius + ball2.radius - distance) / 2;
173
+ if (ball1.isDragging || ball2.isDragging) {
174
+ const draggedBall2 = ball1.isDragging ? ball1 : ball2;
175
+ const otherBall = ball1.isDragging ? ball2 : ball1;
176
+ otherBall.x += (draggedBall2 === ball1 ? 1 : -1) * overlap * Math.cos(angle);
177
+ otherBall.y += (draggedBall2 === ball1 ? 1 : -1) * overlap * Math.sin(angle);
178
+ const pushForce = 2;
179
+ otherBall.vx = (draggedBall2 === ball1 ? -1 : 1) * Math.cos(angle) * pushForce;
180
+ otherBall.vy = (draggedBall2 === ball1 ? -1 : 1) * Math.sin(angle) * pushForce;
181
+ return;
182
+ }
183
+ const sin = Math.sin(angle);
184
+ const cos = Math.cos(angle);
185
+ const vx1 = ball1.vx * cos + ball1.vy * sin;
186
+ const vy1 = ball1.vy * cos - ball1.vx * sin;
187
+ const vx2 = ball2.vx * cos + ball2.vy * sin;
188
+ const vy2 = ball2.vy * cos - ball2.vx * sin;
189
+ const newVx1 = vx2;
190
+ const newVx2 = vx1;
191
+ ball1.vx = newVx1 * cos - vy1 * sin;
192
+ ball1.vy = vy1 * cos + newVx1 * sin;
193
+ ball2.vx = newVx2 * cos - vy2 * sin;
194
+ ball2.vy = vy2 * cos + newVx2 * sin;
195
+ ball1.x -= overlap * Math.cos(angle);
196
+ ball1.y -= overlap * Math.sin(angle);
197
+ ball2.x += overlap * Math.cos(angle);
198
+ ball2.y += overlap * Math.sin(angle);
199
+ }
200
+ };
201
+ const updatePosition = (ball, width2, height2) => {
202
+ const handleBoundaryCollision = (velocity, position, boundary, radius) => {
203
+ let newVelocity = velocity;
204
+ let newPosition = position;
205
+ if (position - radius < 0) {
206
+ newPosition = radius;
207
+ newVelocity = Math.abs(velocity);
208
+ } else if (position + radius > boundary) {
209
+ newPosition = boundary - radius;
210
+ newVelocity = -Math.abs(velocity);
211
+ }
212
+ return [newVelocity, newPosition];
213
+ };
214
+ const [newVx, newX] = handleBoundaryCollision(
215
+ ball.vx,
216
+ ball.x,
217
+ width2,
218
+ ball.radius
219
+ );
220
+ const [newVy, newY] = handleBoundaryCollision(
221
+ ball.vy,
222
+ ball.y,
223
+ height2,
224
+ ball.radius
225
+ );
226
+ ball.vx = newVx;
227
+ ball.vy = newVy;
228
+ ball.x = newX;
229
+ ball.y = newY;
230
+ };
231
+ const draw = (ctx, ball) => {
232
+ ctx.beginPath();
233
+ ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
234
+ ctx.fillStyle = ball.color;
235
+ ctx.fill();
236
+ ctx.closePath();
237
+ if (ball.text) {
238
+ ctx.font = "14px Arial";
239
+ ctx.fillStyle = "#fff";
240
+ ctx.textAlign = "center";
241
+ ctx.textBaseline = "middle";
242
+ ctx.fillText(ball.text, ball.x, ball.y);
243
+ }
244
+ };
245
+ const handleMouseDown = (event) => {
246
+ const mousePos2 = getMousePos(event);
247
+ const ball = ballsRef.current.find((b) => {
248
+ const dx = b.x - mousePos2.x;
249
+ const dy = b.y - mousePos2.y;
250
+ return Math.sqrt(dx * dx + dy * dy) < b.radius;
251
+ });
252
+ if (ball) {
253
+ ball.isDragging = true;
254
+ setDraggedBall(ball);
255
+ }
256
+ };
257
+ const handleMouseMove = (event) => {
258
+ const mousePos2 = getMousePos(event);
259
+ setMousePos(mousePos2);
260
+ if (draggedBall) {
261
+ draggedBall.x = mousePos2.x;
262
+ draggedBall.y = mousePos2.y;
263
+ draggedBall.vx = 0;
264
+ draggedBall.vy = 0;
265
+ }
266
+ };
267
+ const handleMouseUp = () => {
268
+ if (draggedBall) {
269
+ draggedBall.isDragging = false;
270
+ setDraggedBall(null);
271
+ }
272
+ };
273
+ const getMousePos = (event) => {
274
+ const canvas = canvasRef.current;
275
+ if (!canvas) return { x: 0, y: 0 };
276
+ const rect = canvas.getBoundingClientRect();
277
+ const scaleX = canvas.width / rect.width;
278
+ const scaleY = canvas.height / rect.height;
279
+ return {
280
+ x: (event.clientX - rect.left) * scaleX,
281
+ y: (event.clientY - rect.top) * scaleY
282
+ };
283
+ };
284
+ return /* @__PURE__ */ React5__default.default.createElement("div", { style: { width: "100%", height: "100%", position: "relative", backgroundColor: "#f9fafb", borderRadius: "0.5rem" } }, /* @__PURE__ */ React5__default.default.createElement("div", { ref: containerRef, style: { width: "100%", height: "100%", position: "absolute", top: 0, left: 0 } }, /* @__PURE__ */ React5__default.default.createElement(
285
+ "canvas",
286
+ {
287
+ ref: canvasRef,
288
+ style: {
289
+ width: "100%",
290
+ height: "100%",
291
+ display: "block"
292
+ // 确保canvas正确显示
293
+ },
294
+ onMouseDown: handleMouseDown,
295
+ onMouseMove: handleMouseMove,
296
+ onMouseUp: handleMouseUp,
297
+ onMouseLeave: handleMouseUp
298
+ }
299
+ )), /* @__PURE__ */ React5__default.default.createElement("div", { className: "absolute bottom-4 right-4 flex gap-2" }, /* @__PURE__ */ React5__default.default.createElement(
300
+ "button",
301
+ {
302
+ onClick: shake,
303
+ className: clsx.clsx("px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors", isShaking ? "animate-pulse" : "")
304
+ },
305
+ "\u6447\u4E00\u6447"
306
+ ), /* @__PURE__ */ React5__default.default.createElement(
307
+ "button",
308
+ {
309
+ onClick: slowdown,
310
+ className: clsx.clsx("px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors", isShaking ? "animate-pulse" : "")
311
+ },
312
+ "\u51CF\u901F"
313
+ )));
314
+ };
315
+ var Timeline = ({ items = [] }) => {
316
+ if (!items || items.length === 0) {
317
+ return null;
318
+ }
319
+ return /* @__PURE__ */ React5__default.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "absolute left-4 top-0 bottom-0 w-0.5 bg-gray-200" }), items.map((item, index) => /* @__PURE__ */ React5__default.default.createElement("div", { key: index, className: "relative pl-12 pb-8" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "absolute left-0 w-8 h-8 rounded-full bg-blue-500 border-4 border-white shadow-md flex items-center justify-center" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "w-2 h-2 rounded-full bg-white" })), /* @__PURE__ */ React5__default.default.createElement("div", { className: "bg-white rounded-lg p-4 shadow-md" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "text-sm text-gray-500 mb-2" }, item.date), /* @__PURE__ */ React5__default.default.createElement("h4", { className: "text-lg font-semibold mb-2" }, item.title), /* @__PURE__ */ React5__default.default.createElement("p", { className: "text-gray-600" }, item.description)))));
320
+ };
321
+
322
+ // src/portfolio/AboutWithDefaults.tsx
323
+ var AboutWithDefaults = (props) => /* @__PURE__ */ React5__default.default.createElement(About_default, { ...props, Timeline, CollisionBalls });
324
+ var AboutWithDefaults_default = AboutWithDefaults;
325
+ var Contact = () => {
326
+ const [formData, setFormData] = React5.useState({
327
+ name: "",
328
+ email: "",
329
+ message: ""
330
+ });
331
+ const [isSubmitting, setIsSubmitting] = React5.useState(false);
332
+ const [submitStatus, setSubmitStatus] = React5.useState("idle");
333
+ const handleChange = (e) => {
334
+ const { name, value } = e.target;
335
+ setFormData((prev) => ({
336
+ ...prev,
337
+ [name]: value
338
+ }));
339
+ };
340
+ const handleSubmit = async (e) => {
341
+ e.preventDefault();
342
+ setIsSubmitting(true);
343
+ setSubmitStatus("idle");
344
+ try {
345
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
346
+ setSubmitStatus("success");
347
+ setFormData({ name: "", email: "", message: "" });
348
+ } catch (error) {
349
+ setSubmitStatus("error");
350
+ } finally {
351
+ setIsSubmitting(false);
352
+ }
353
+ };
354
+ return /* @__PURE__ */ React5__default.default.createElement("section", { id: "contact", className: "py-16 bg-gray-50" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "text-center mb-12" }, /* @__PURE__ */ React5__default.default.createElement("h2", { className: "text-3xl font-bold text-gray-900 sm:text-4xl" }, "\u8054\u7CFB\u6211"), /* @__PURE__ */ React5__default.default.createElement("p", { className: "mt-4 text-lg text-gray-600" }, "\u6709\u4EFB\u4F55\u95EE\u9898\u6216\u5EFA\u8BAE\uFF1F\u8BF7\u968F\u65F6\u8054\u7CFB\u6211")), /* @__PURE__ */ React5__default.default.createElement("div", { className: "bg-white rounded-lg shadow-xl p-6 sm:p-8" }, /* @__PURE__ */ React5__default.default.createElement("form", { onSubmit: handleSubmit, className: "space-y-6" }, /* @__PURE__ */ React5__default.default.createElement("div", null, /* @__PURE__ */ React5__default.default.createElement("label", { htmlFor: "name", className: "block text-sm font-medium text-gray-700" }, "\u59D3\u540D"), /* @__PURE__ */ React5__default.default.createElement(
355
+ "input",
356
+ {
357
+ type: "text",
358
+ name: "name",
359
+ id: "name",
360
+ value: formData.name,
361
+ onChange: handleChange,
362
+ required: true,
363
+ className: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm",
364
+ placeholder: "\u8BF7\u8F93\u5165\u60A8\u7684\u59D3\u540D"
365
+ }
366
+ )), /* @__PURE__ */ React5__default.default.createElement("div", null, /* @__PURE__ */ React5__default.default.createElement("label", { htmlFor: "email", className: "block text-sm font-medium text-gray-700" }, "\u90AE\u7BB1"), /* @__PURE__ */ React5__default.default.createElement(
367
+ "input",
368
+ {
369
+ type: "email",
370
+ name: "email",
371
+ id: "email",
372
+ value: formData.email,
373
+ onChange: handleChange,
374
+ required: true,
375
+ className: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm",
376
+ placeholder: "\u8BF7\u8F93\u5165\u60A8\u7684\u90AE\u7BB1"
377
+ }
378
+ )), /* @__PURE__ */ React5__default.default.createElement("div", null, /* @__PURE__ */ React5__default.default.createElement("label", { htmlFor: "message", className: "block text-sm font-medium text-gray-700" }, "\u6D88\u606F"), /* @__PURE__ */ React5__default.default.createElement(
379
+ "textarea",
380
+ {
381
+ name: "message",
382
+ id: "message",
383
+ rows: 4,
384
+ value: formData.message,
385
+ onChange: handleChange,
386
+ required: true,
387
+ className: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm",
388
+ placeholder: "\u8BF7\u8F93\u5165\u60A8\u7684\u6D88\u606F"
389
+ }
390
+ )), /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex items-center justify-end" }, /* @__PURE__ */ React5__default.default.createElement(
391
+ "button",
392
+ {
393
+ type: "submit",
394
+ disabled: isSubmitting,
395
+ className: clsx.clsx("inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white", isSubmitting ? "bg-blue-400 cursor-not-allowed" : "bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500")
396
+ },
397
+ isSubmitting ? "\u53D1\u9001\u4E2D..." : "\u53D1\u9001\u6D88\u606F"
398
+ )), submitStatus === "success" && /* @__PURE__ */ React5__default.default.createElement("div", { className: "rounded-md bg-green-50 p-4" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex-shrink-0" }, /* @__PURE__ */ React5__default.default.createElement("svg", { className: "h-5 w-5 text-green-400", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React5__default.default.createElement("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", clipRule: "evenodd" }))), /* @__PURE__ */ React5__default.default.createElement("div", { className: "ml-3" }, /* @__PURE__ */ React5__default.default.createElement("p", { className: "text-sm font-medium text-green-800" }, "\u6D88\u606F\u5DF2\u6210\u529F\u53D1\u9001\uFF01")))), submitStatus === "error" && /* @__PURE__ */ React5__default.default.createElement("div", { className: "rounded-md bg-red-50 p-4" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex-shrink-0" }, /* @__PURE__ */ React5__default.default.createElement("svg", { className: "h-5 w-5 text-red-400", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React5__default.default.createElement("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z", clipRule: "evenodd" }))), /* @__PURE__ */ React5__default.default.createElement("div", { className: "ml-3" }, /* @__PURE__ */ React5__default.default.createElement("p", { className: "text-sm font-medium text-red-800" }, "\u53D1\u9001\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5")))))), /* @__PURE__ */ React5__default.default.createElement("div", { className: "mt-12 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "bg-white rounded-lg shadow-lg p-6 text-center" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "text-blue-600 mb-4" }, /* @__PURE__ */ React5__default.default.createElement("svg", { className: "h-8 w-8 mx-auto", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React5__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }))), /* @__PURE__ */ React5__default.default.createElement("h3", { className: "text-lg font-medium text-gray-900" }, "\u90AE\u7BB1"), /* @__PURE__ */ React5__default.default.createElement("p", { className: "mt-2 text-gray-600" }, "your.email@example.com")), /* @__PURE__ */ React5__default.default.createElement("div", { className: "bg-white rounded-lg shadow-lg p-6 text-center" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "text-blue-600 mb-4" }, /* @__PURE__ */ React5__default.default.createElement("svg", { className: "h-8 w-8 mx-auto", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React5__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" }))), /* @__PURE__ */ React5__default.default.createElement("h3", { className: "text-lg font-medium text-gray-900" }, "\u7535\u8BDD"), /* @__PURE__ */ React5__default.default.createElement("p", { className: "mt-2 text-gray-600" }, "+86 123 4567 8900")), /* @__PURE__ */ React5__default.default.createElement("div", { className: "bg-white rounded-lg shadow-lg p-6 text-center" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "text-blue-600 mb-4" }, /* @__PURE__ */ React5__default.default.createElement("svg", { className: "h-8 w-8 mx-auto", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ React5__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" }), /* @__PURE__ */ React5__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M15 11a3 3 0 11-6 0 3 3 0 016 0z" }))), /* @__PURE__ */ React5__default.default.createElement("h3", { className: "text-lg font-medium text-gray-900" }, "\u5730\u5740"), /* @__PURE__ */ React5__default.default.createElement("p", { className: "mt-2 text-gray-600" }, "\u4E2D\u56FD\uFF0C\u5317\u4EAC")))));
399
+ };
400
+ var Contact_default = Contact;
401
+
402
+ // src/logger/console-adapter.ts
403
+ var ConsoleLoggerAdapter = class {
404
+ constructor() {
405
+ this.colors = {
406
+ DEBUG: "\x1B[36m",
407
+ // Cyan
408
+ INFO: "\x1B[32m",
409
+ // Green
410
+ WARN: "\x1B[33m",
411
+ // Yellow
412
+ ERROR: "\x1B[31m",
413
+ // Red
414
+ RESET: "\x1B[0m"
415
+ };
416
+ }
417
+ log(entry) {
418
+ const { level, message, timestamp, data, context, error } = entry;
419
+ let logMessage = "";
420
+ if (timestamp) {
421
+ logMessage += "[" + this.formatTimestamp(timestamp) + "] ";
422
+ }
423
+ const levelName = this.getLevelName(level);
424
+ logMessage += levelName + ": ";
425
+ if (context) {
426
+ logMessage += "[" + context + "] ";
427
+ }
428
+ logMessage += message;
429
+ switch (level) {
430
+ case 0:
431
+ console.debug(this.colorize(logMessage, "DEBUG"), data || "");
432
+ break;
433
+ case 1:
434
+ console.info(this.colorize(logMessage, "INFO"), data || "");
435
+ break;
436
+ case 2:
437
+ console.warn(this.colorize(logMessage, "WARN"), data || "");
438
+ break;
439
+ case 3:
440
+ console.error(this.colorize(logMessage, "ERROR"), data || "");
441
+ if (error) {
442
+ console.error(error);
443
+ }
444
+ break;
445
+ }
446
+ }
447
+ formatTimestamp(date) {
448
+ return date.toISOString();
449
+ }
450
+ getLevelName(level) {
451
+ const names = ["DEBUG", "INFO", "WARN", "ERROR", "NONE"];
452
+ return names[level] || "UNKNOWN";
453
+ }
454
+ colorize(message, level) {
455
+ if (typeof process !== "undefined" && process.stdout?.isTTY) {
456
+ return this.colors[level] + message + this.colors.RESET;
457
+ }
458
+ return message;
459
+ }
460
+ };
461
+
462
+ // src/logger/Logger.ts
463
+ var Logger = class _Logger {
464
+ constructor(config, context) {
465
+ const isProduction = typeof process !== "undefined" ? process.env.NODE_ENV === "production" : false;
466
+ this.config = {
467
+ minLevel: config?.minLevel ?? (isProduction ? 1 : 0),
468
+ // INFO in prod, DEBUG in dev
469
+ enableTimestamp: config?.enableTimestamp ?? true,
470
+ enableContext: config?.enableContext ?? true,
471
+ environment: config?.environment ?? (isProduction ? "production" : "development"),
472
+ adapter: config?.adapter ?? new ConsoleLoggerAdapter()
473
+ };
474
+ this.adapter = this.config.adapter;
475
+ this.context = context;
476
+ }
477
+ /**
478
+ * 创建带上下文的子 Logger
479
+ */
480
+ createChild(context) {
481
+ return new _Logger(this.config, context);
482
+ }
483
+ /**
484
+ * 调试日志
485
+ */
486
+ debug(message, data) {
487
+ this.log(0, message, data);
488
+ }
489
+ /**
490
+ * 信息日志
491
+ */
492
+ info(message, data) {
493
+ this.log(1, message, data);
494
+ }
495
+ /**
496
+ * 警告日志
497
+ */
498
+ warn(message, data) {
499
+ this.log(2, message, data);
500
+ }
501
+ /**
502
+ * 错误日志
503
+ */
504
+ error(message, error) {
505
+ this.log(
506
+ 3,
507
+ // LogLevel.ERROR
508
+ message,
509
+ error instanceof Error ? void 0 : error,
510
+ error instanceof Error ? error : void 0
511
+ );
512
+ }
513
+ /**
514
+ * 核心日志方法
515
+ */
516
+ log(level, message, data, error) {
517
+ if (level < this.config.minLevel) {
518
+ return;
519
+ }
520
+ if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
521
+ const loggerDebug = localStorage.getItem("logger-debug");
522
+ if (loggerDebug === "false" && level < 3) {
523
+ return;
524
+ }
525
+ }
526
+ const entry = {
527
+ level,
528
+ message,
529
+ timestamp: this.config.enableTimestamp ? /* @__PURE__ */ new Date() : void 0,
530
+ data,
531
+ context: this.config.enableContext ? this.context : void 0,
532
+ error
533
+ };
534
+ this.adapter.log(entry);
535
+ }
536
+ /**
537
+ * 设置日志级别
538
+ */
539
+ setLevel(level) {
540
+ this.config.minLevel = level;
541
+ }
542
+ /**
543
+ * 获取当前日志级别
544
+ */
545
+ getLevel() {
546
+ return this.config.minLevel;
547
+ }
548
+ };
549
+ new Logger();
550
+ function cn(...inputs) {
551
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
552
+ }
553
+
554
+ // src/portfolio/Home.tsx
555
+ var Home = ({ homeConfig, className }) => {
556
+ const { title, subtitle, buttons, imageSrc } = homeConfig;
557
+ const [displayText, setDisplayText] = React5.useState("");
558
+ const [currentIndex, setCurrentIndex] = React5.useState(0);
559
+ React5.useEffect(() => {
560
+ if (currentIndex < title.length) {
561
+ const timer = setTimeout(() => {
562
+ setDisplayText((prev) => prev + title[currentIndex]);
563
+ setCurrentIndex((prev) => prev + 1);
564
+ }, 150);
565
+ return () => clearTimeout(timer);
566
+ }
567
+ return () => {
568
+ setDisplayText("");
569
+ setCurrentIndex(0);
570
+ };
571
+ }, [currentIndex, title]);
572
+ return /* @__PURE__ */ React5__default.default.createElement(
573
+ "section",
574
+ {
575
+ id: "home",
576
+ className: cn("min-h-screen flex items-center justify-center py-16 bg-gradient-to-b from-white to-gray-50", className)
577
+ },
578
+ /* @__PURE__ */ React5__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex flex-col md:flex-row items-center gap-12" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex-1 text-center md:text-left" }, /* @__PURE__ */ React5__default.default.createElement("h1", { className: "text-4xl md:text-6xl font-bold mb-6 text-gray-900" }, /* @__PURE__ */ React5__default.default.createElement("span", { className: "inline-block" }, displayText), /* @__PURE__ */ React5__default.default.createElement("span", { className: "animate-pulse ml-1 text-blue-500" }, "|")), /* @__PURE__ */ React5__default.default.createElement("p", { className: "text-xl md:text-2xl text-gray-600 mb-8" }, subtitle), /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex flex-wrap gap-4 justify-center md:justify-start" }, buttons.map((button) => /* @__PURE__ */ React5__default.default.createElement(
579
+ "a",
580
+ {
581
+ key: button.link,
582
+ href: button.link,
583
+ className: "px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-all duration-300 shadow-md hover:shadow-lg font-medium"
584
+ },
585
+ button.text
586
+ )))), /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "absolute -inset-1 bg-gradient-to-r from-blue-600 to-purple-600 rounded-lg blur opacity-25 group-hover:opacity-50 transition duration-1000 group-hover:duration-200" }), /* @__PURE__ */ React5__default.default.createElement(
587
+ "img",
588
+ {
589
+ src: imageSrc,
590
+ alt: "Profile",
591
+ className: "relative w-full max-w-md mx-auto rounded-lg shadow-xl transform hover:scale-[1.02] transition-transform duration-300 bg-white"
592
+ }
593
+ )))))
594
+ );
595
+ };
596
+ var Home_default = Home;
597
+ var ExperimentCard = ({
598
+ href,
599
+ title,
600
+ description,
601
+ tags,
602
+ category,
603
+ isCompleted,
604
+ updatedAt,
605
+ createdAt,
606
+ className
607
+ }) => {
608
+ const formatDate = (dateString) => {
609
+ if (!dateString) return "";
610
+ try {
611
+ const date = new Date(dateString);
612
+ return date.toLocaleDateString("zh-CN", {
613
+ year: "numeric",
614
+ month: "2-digit",
615
+ day: "2-digit"
616
+ });
617
+ } catch (e) {
618
+ return dateString;
619
+ }
620
+ };
621
+ return /* @__PURE__ */ React5__default.default.createElement(Link__default.default, { href, className: cn("block group", className) }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "w-full h-full bg-white rounded-2xl overflow-hidden shadow-md hover:shadow-2xl transition-all duration-300 transform group-hover:-translate-y-1 border border-gray-100 hover:border-gray-200" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "p-6" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex items-start justify-between mb-4" }, /* @__PURE__ */ React5__default.default.createElement("h3", { className: "text-xl font-semibold text-gray-900 flex-1 pr-4 leading-tight" }, title), /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex flex-col gap-2 flex-shrink-0" }, /* @__PURE__ */ React5__default.default.createElement("span", { className: cn(
622
+ "px-3 py-1.5 text-xs font-medium rounded-full shadow-sm",
623
+ category === "utility" ? "bg-gradient-to-r from-green-50 to-green-100 text-green-700 border border-green-200" : "bg-gradient-to-r from-purple-50 to-purple-100 text-purple-700 border border-purple-200"
624
+ ) }, category === "utility" ? "\u{1F527} \u5B9E\u7528\u5DE5\u5177" : "\u{1F3AE} \u4F11\u95F2\u5A31\u4E50"), /* @__PURE__ */ React5__default.default.createElement("span", { className: cn(
625
+ "px-3 py-1.5 text-xs font-medium rounded-full shadow-sm border",
626
+ isCompleted ? "bg-gradient-to-r from-emerald-50 to-emerald-100 text-emerald-700 border border-emerald-200" : "bg-gradient-to-r from-orange-50 to-orange-100 text-orange-700 border border-orange-200"
627
+ ) }, isCompleted ? "\u2705 \u5DF2\u5B8C\u6210" : "\u{1F6A7} \u8FDB\u884C\u4E2D"))), /* @__PURE__ */ React5__default.default.createElement("p", { className: "text-gray-600 mb-4" }, description), updatedAt && /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex items-center gap-1 mb-3 text-xs text-gray-500" }, /* @__PURE__ */ React5__default.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, /* @__PURE__ */ React5__default.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" })), /* @__PURE__ */ React5__default.default.createElement("span", null, "\u66F4\u65B0\u4E8E: ", formatDate(updatedAt)), createdAt && createdAt !== updatedAt && /* @__PURE__ */ React5__default.default.createElement("span", { className: "ml-2 text-gray-400" }, "\u521B\u5EFA\u4E8E: ", formatDate(createdAt))), /* @__PURE__ */ React5__default.default.createElement("div", { className: "flex flex-wrap gap-2" }, tags.map((tag) => /* @__PURE__ */ React5__default.default.createElement(
628
+ "span",
629
+ {
630
+ key: tag,
631
+ className: "px-3 py-1.5 text-xs font-medium bg-gradient-to-r from-gray-50 to-gray-100 text-gray-700 rounded-full border border-gray-200 shadow-sm hover:shadow-md transition-shadow duration-200"
632
+ },
633
+ "#",
634
+ tag
635
+ ))))));
636
+ };
637
+ var ProjectCarousel = ({ projects, className }) => {
638
+ const [currentIndex, setCurrentIndex] = React5.useState(0);
639
+ const nextSlide = () => {
640
+ setCurrentIndex(
641
+ (prevIndex) => prevIndex === projects.length - 1 ? 0 : prevIndex + 1
642
+ );
643
+ };
644
+ const prevSlide = () => {
645
+ setCurrentIndex(
646
+ (prevIndex) => prevIndex === 0 ? projects.length - 1 : prevIndex - 1
647
+ );
648
+ };
649
+ return /* @__PURE__ */ React5__default.default.createElement("section", { id: "projects", className: cn("py-16 bg-gray-50", className) }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "container mx-auto px-4" }, /* @__PURE__ */ React5__default.default.createElement("h2", { className: "text-3xl font-bold text-center mb-12 text-gray-900" }, "\u9879\u76EE\u5C55\u793A"), /* @__PURE__ */ React5__default.default.createElement("div", { className: "relative max-w-4xl mx-auto" }, /* @__PURE__ */ React5__default.default.createElement("div", { className: "relative h-[400px] overflow-hidden rounded-lg shadow-xl" }, projects.map((project, index) => /* @__PURE__ */ React5__default.default.createElement(
650
+ "div",
651
+ {
652
+ key: project.id,
653
+ className: cn(
654
+ "absolute w-full h-full transition-all duration-500 transform",
655
+ index === currentIndex ? "translate-x-0 opacity-100" : index < currentIndex ? "-translate-x-full opacity-0" : "translate-x-full opacity-0"
656
+ )
657
+ },
658
+ /* @__PURE__ */ React5__default.default.createElement(
659
+ ExperimentCard,
660
+ {
661
+ href: project.link || "#",
662
+ title: project.title,
663
+ description: project.description,
664
+ tags: project.tags,
665
+ category: "utility"
666
+ }
667
+ )
668
+ ))), /* @__PURE__ */ React5__default.default.createElement(
669
+ "button",
670
+ {
671
+ onClick: prevSlide,
672
+ className: "absolute left-4 top-1/2 -translate-y-1/2 p-2 rounded-full bg-white/80 hover:bg-white shadow-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all z-[10]"
673
+ },
674
+ /* @__PURE__ */ React5__default.default.createElement(
675
+ "svg",
676
+ {
677
+ className: "w-6 h-6 text-gray-600",
678
+ fill: "none",
679
+ stroke: "currentColor",
680
+ viewBox: "0 0 24 24"
681
+ },
682
+ /* @__PURE__ */ React5__default.default.createElement(
683
+ "path",
684
+ {
685
+ strokeLinecap: "round",
686
+ strokeLinejoin: "round",
687
+ strokeWidth: 2,
688
+ d: "M15 19l-7-7 7-7"
689
+ }
690
+ )
691
+ )
692
+ ), /* @__PURE__ */ React5__default.default.createElement(
693
+ "button",
694
+ {
695
+ onClick: nextSlide,
696
+ className: "absolute right-4 top-1/2 -translate-y-1/2 p-2 rounded-full bg-white/80 hover:bg-white shadow-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all z-[10]"
697
+ },
698
+ /* @__PURE__ */ React5__default.default.createElement(
699
+ "svg",
700
+ {
701
+ className: "w-6 h-6 text-gray-600",
702
+ fill: "none",
703
+ stroke: "currentColor",
704
+ viewBox: "0 0 24 24"
705
+ },
706
+ /* @__PURE__ */ React5__default.default.createElement(
707
+ "path",
708
+ {
709
+ strokeLinecap: "round",
710
+ strokeLinejoin: "round",
711
+ strokeWidth: 2,
712
+ d: "M9 5l7 7-7 7"
713
+ }
714
+ )
715
+ )
716
+ ), /* @__PURE__ */ React5__default.default.createElement("div", { className: "absolute bottom-4 left-1/2 transform -translate-x-1/2 flex space-x-2 z-[10]" }, projects.map((_, index) => /* @__PURE__ */ React5__default.default.createElement(
717
+ "button",
718
+ {
719
+ key: index,
720
+ onClick: () => setCurrentIndex(index),
721
+ className: cn(
722
+ "w-2 h-2 rounded-full transition-all duration-300",
723
+ index === currentIndex ? "bg-blue-500 w-4" : "bg-gray-300"
724
+ )
725
+ }
726
+ ))))));
727
+ };
728
+
729
+ exports.About = AboutWithDefaults_default;
730
+ exports.AboutBase = About_default;
731
+ exports.Contact = Contact_default;
732
+ exports.ExperimentCard = ExperimentCard;
733
+ exports.Home = Home_default;
734
+ exports.ProjectCarousel = ProjectCarousel;
735
+ //# sourceMappingURL=index.js.map
736
+ //# sourceMappingURL=index.js.map