sa2kit 1.6.7 → 1.6.9

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 (139) hide show
  1. package/dist/calendar/index.js +334 -399
  2. package/dist/calendar/index.js.map +1 -1
  3. package/dist/calendar/index.mjs +241 -306
  4. package/dist/calendar/index.mjs.map +1 -1
  5. package/dist/calendar/routes/index.js +21 -21
  6. package/dist/calendar/routes/index.mjs +1 -1
  7. package/dist/calendar/server.js +13 -13
  8. package/dist/calendar/server.mjs +2 -2
  9. package/dist/chunk-4FOBBWXW.mjs +179 -0
  10. package/dist/chunk-4FOBBWXW.mjs.map +1 -0
  11. package/dist/chunk-CDK3DHKM.mjs +634 -0
  12. package/dist/chunk-CDK3DHKM.mjs.map +1 -0
  13. package/dist/chunk-G6WRJ2H2.js +187 -0
  14. package/dist/chunk-G6WRJ2H2.js.map +1 -0
  15. package/dist/{chunk-6WXOA4BE.mjs → chunk-GVVS4IMM.mjs} +2 -2
  16. package/dist/chunk-GVVS4IMM.mjs.map +1 -0
  17. package/dist/chunk-L5PW2YTI.js +647 -0
  18. package/dist/chunk-L5PW2YTI.js.map +1 -0
  19. package/dist/{chunk-AXP7KROR.js → chunk-WC5QFO3T.js} +2 -2
  20. package/dist/chunk-WC5QFO3T.js.map +1 -0
  21. package/dist/index.js +15 -7
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.mjs +6 -6
  24. package/dist/index.mjs.map +1 -1
  25. package/dist/mmd/index.js +2 -2
  26. package/dist/mmd/index.mjs +1 -1
  27. package/dist/music/index.js +14 -6
  28. package/dist/music/index.mjs +1 -1
  29. package/package.json +41 -7
  30. package/dist/ConfigService-BxK06xP6.d.mts +0 -262
  31. package/dist/ConfigService-BxK06xP6.d.ts +0 -262
  32. package/dist/UniversalFileService-BuHN-jrR.d.ts +0 -515
  33. package/dist/UniversalFileService-CGGzYeeF.d.mts +0 -515
  34. package/dist/analytics/index.d.mts +0 -1084
  35. package/dist/analytics/index.d.ts +0 -1084
  36. package/dist/analytics/server/index.d.mts +0 -499
  37. package/dist/analytics/server/index.d.ts +0 -499
  38. package/dist/api/index.d.mts +0 -248
  39. package/dist/api/index.d.ts +0 -248
  40. package/dist/audioDetection/index.d.mts +0 -449
  41. package/dist/audioDetection/index.d.ts +0 -449
  42. package/dist/auth/client/index.d.mts +0 -153
  43. package/dist/auth/client/index.d.ts +0 -153
  44. package/dist/auth/components/index.d.mts +0 -227
  45. package/dist/auth/components/index.d.ts +0 -227
  46. package/dist/auth/hooks/index.d.mts +0 -31
  47. package/dist/auth/hooks/index.d.ts +0 -31
  48. package/dist/auth/index.d.mts +0 -40
  49. package/dist/auth/index.d.ts +0 -40
  50. package/dist/auth/middleware/index.d.mts +0 -75
  51. package/dist/auth/middleware/index.d.ts +0 -75
  52. package/dist/auth/routes/index.d.mts +0 -261
  53. package/dist/auth/routes/index.d.ts +0 -261
  54. package/dist/auth/schema/index.d.mts +0 -789
  55. package/dist/auth/schema/index.d.ts +0 -789
  56. package/dist/auth/services/index.d.mts +0 -48
  57. package/dist/auth/services/index.d.ts +0 -48
  58. package/dist/calendar/index.d.mts +0 -1197
  59. package/dist/calendar/index.d.ts +0 -1197
  60. package/dist/calendar/routes/index.d.mts +0 -118
  61. package/dist/calendar/routes/index.d.ts +0 -118
  62. package/dist/calendar/server.d.mts +0 -1184
  63. package/dist/calendar/server.d.ts +0 -1184
  64. package/dist/chunk-6WXOA4BE.mjs.map +0 -1
  65. package/dist/chunk-AXP7KROR.js.map +0 -1
  66. package/dist/chunk-GAC4J5GX.js +0 -228
  67. package/dist/chunk-GAC4J5GX.js.map +0 -1
  68. package/dist/chunk-IEA55H3G.js +0 -106
  69. package/dist/chunk-IEA55H3G.js.map +0 -1
  70. package/dist/chunk-R2F4BXUU.mjs +0 -100
  71. package/dist/chunk-R2F4BXUU.mjs.map +0 -1
  72. package/dist/chunk-T6TE7GTY.mjs +0 -218
  73. package/dist/chunk-T6TE7GTY.mjs.map +0 -1
  74. package/dist/config/index.d.mts +0 -64
  75. package/dist/config/index.d.ts +0 -64
  76. package/dist/config/server/index.d.mts +0 -1533
  77. package/dist/config/server/index.d.ts +0 -1533
  78. package/dist/drizzle-auth-service-Bxlovhv8.d.ts +0 -145
  79. package/dist/drizzle-auth-service-DZY2F1sv.d.mts +0 -145
  80. package/dist/drizzle-schema-BNhqj2AZ.d.mts +0 -1114
  81. package/dist/drizzle-schema-BNhqj2AZ.d.ts +0 -1114
  82. package/dist/enums-Dume-V5Y.d.mts +0 -16
  83. package/dist/enums-Dume-V5Y.d.ts +0 -16
  84. package/dist/i18n/index.d.mts +0 -417
  85. package/dist/i18n/index.d.ts +0 -417
  86. package/dist/imageCrop/index.d.mts +0 -165
  87. package/dist/imageCrop/index.d.ts +0 -165
  88. package/dist/index-DSel44Ke.d.mts +0 -93
  89. package/dist/index-DSel44Ke.d.ts +0 -93
  90. package/dist/index.d.mts +0 -671
  91. package/dist/index.d.ts +0 -671
  92. package/dist/logger/index.d.mts +0 -125
  93. package/dist/logger/index.d.ts +0 -125
  94. package/dist/mmd/admin/index.d.mts +0 -487
  95. package/dist/mmd/admin/index.d.ts +0 -487
  96. package/dist/mmd/index.d.mts +0 -599
  97. package/dist/mmd/index.d.ts +0 -599
  98. package/dist/mmd/server/index.d.mts +0 -138
  99. package/dist/mmd/server/index.d.ts +0 -138
  100. package/dist/music/index.d.mts +0 -79
  101. package/dist/music/index.d.ts +0 -79
  102. package/dist/music/server/index.d.mts +0 -1
  103. package/dist/music/server/index.d.ts +0 -1
  104. package/dist/request/index.d.mts +0 -51
  105. package/dist/request/index.d.ts +0 -51
  106. package/dist/storage/index.d.mts +0 -75
  107. package/dist/storage/index.d.ts +0 -75
  108. package/dist/testYourself/admin/index.d.mts +0 -58
  109. package/dist/testYourself/admin/index.d.ts +0 -58
  110. package/dist/testYourself/index.d.mts +0 -53
  111. package/dist/testYourself/index.d.ts +0 -53
  112. package/dist/testYourself/server/index.d.mts +0 -1029
  113. package/dist/testYourself/server/index.d.ts +0 -1029
  114. package/dist/types-B60F7EZZ.d.mts +0 -248
  115. package/dist/types-B60F7EZZ.d.ts +0 -248
  116. package/dist/types-BINlP9MK.d.mts +0 -286
  117. package/dist/types-BINlP9MK.d.ts +0 -286
  118. package/dist/types-BaZccpvk.d.mts +0 -48
  119. package/dist/types-BaZccpvk.d.ts +0 -48
  120. package/dist/types-CK4We_aI.d.mts +0 -270
  121. package/dist/types-CK4We_aI.d.ts +0 -270
  122. package/dist/types-CbTsi9CZ.d.mts +0 -31
  123. package/dist/types-CbTsi9CZ.d.ts +0 -31
  124. package/dist/types-CroexXnI.d.ts +0 -99
  125. package/dist/types-DmsXCWvm.d.mts +0 -99
  126. package/dist/types-Dt0oqeFM.d.mts +0 -70
  127. package/dist/types-zK6kDzDQ.d.ts +0 -70
  128. package/dist/universalExport/index.d.mts +0 -235
  129. package/dist/universalExport/index.d.ts +0 -235
  130. package/dist/universalExport/server/index.d.mts +0 -1270
  131. package/dist/universalExport/server/index.d.ts +0 -1270
  132. package/dist/universalFile/index.d.mts +0 -480
  133. package/dist/universalFile/index.d.ts +0 -480
  134. package/dist/universalFile/server/index.d.mts +0 -4516
  135. package/dist/universalFile/server/index.d.ts +0 -4516
  136. package/dist/useElectronStorage-Dj0rcorG.d.mts +0 -65
  137. package/dist/useElectronStorage-DwnNfIhl.d.ts +0 -65
  138. package/dist/utils/index.d.mts +0 -192
  139. package/dist/utils/index.d.ts +0 -192
@@ -0,0 +1,647 @@
1
+ 'use strict';
2
+
3
+ var chunk2ODO4HEI_js = require('./chunk-2ODO4HEI.js');
4
+ var React = require('react');
5
+ var useSWR = require('swr');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var React__default = /*#__PURE__*/_interopDefault(React);
10
+ var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
11
+
12
+ function MusicPlayer({
13
+ track,
14
+ onPlay,
15
+ onPause,
16
+ onStop,
17
+ onVolumeChange,
18
+ onSeek,
19
+ initialVolume = 0.7,
20
+ className = "",
21
+ compact = false,
22
+ ultraCompact = false,
23
+ hideVolumeControl = false,
24
+ showTrackInfo = true,
25
+ isPlaying,
26
+ currentTime,
27
+ duration,
28
+ externalVolume
29
+ }) {
30
+ const [volume, setVolume] = React.useState(externalVolume ?? initialVolume);
31
+ const [isLoading, setIsLoading] = React.useState(false);
32
+ const [error, setError] = React.useState();
33
+ const progressRef = React.useRef(null);
34
+ const volumeRef = React.useRef(null);
35
+ const [isDraggingProgress, setIsDraggingProgress] = React.useState(false);
36
+ const [isDraggingVolume, setIsDraggingVolume] = React.useState(false);
37
+ React.useEffect(() => {
38
+ if (externalVolume !== void 0) {
39
+ setVolume(externalVolume);
40
+ }
41
+ }, [externalVolume]);
42
+ const formatTime = (seconds) => {
43
+ if (!seconds || isNaN(seconds)) return "0:00";
44
+ const mins = Math.floor(seconds / 60);
45
+ const secs = Math.floor(seconds % 60);
46
+ return `${mins}:${secs.toString().padStart(2, "0")}`;
47
+ };
48
+ const handlePlay = React.useCallback(() => {
49
+ onPlay?.();
50
+ }, [onPlay]);
51
+ const handlePause = React.useCallback(() => {
52
+ onPause?.();
53
+ }, [onPause]);
54
+ const handleStop = React.useCallback(() => {
55
+ onStop?.();
56
+ }, [onStop]);
57
+ const handleVolumeChange = React.useCallback((newVolume) => {
58
+ const clampedVolume = Math.max(0, Math.min(1, newVolume));
59
+ setVolume(clampedVolume);
60
+ onVolumeChange?.(clampedVolume);
61
+ }, [onVolumeChange]);
62
+ const handleSeek = React.useCallback((time) => {
63
+ if (!duration || isNaN(duration)) return;
64
+ const seekTime = Math.max(0, Math.min(duration, time));
65
+ onSeek?.(seekTime);
66
+ }, [duration, onSeek]);
67
+ const handleProgressMouseDown = React.useCallback((e) => {
68
+ if (!progressRef.current || !duration) return;
69
+ setIsDraggingProgress(true);
70
+ const rect = progressRef.current.getBoundingClientRect();
71
+ const percent = (e.clientX - rect.left) / rect.width;
72
+ const time = percent * duration;
73
+ handleSeek(time);
74
+ }, [duration, handleSeek]);
75
+ const handleVolumeMouseDown = React.useCallback((e) => {
76
+ if (!volumeRef.current) return;
77
+ setIsDraggingVolume(true);
78
+ const rect = volumeRef.current.getBoundingClientRect();
79
+ const percent = (e.clientX - rect.left) / rect.width;
80
+ handleVolumeChange(percent);
81
+ }, [handleVolumeChange]);
82
+ React.useEffect(() => {
83
+ const handleMouseMove = (e) => {
84
+ if (isDraggingProgress && progressRef.current && duration) {
85
+ const rect = progressRef.current.getBoundingClientRect();
86
+ const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
87
+ const time = percent * duration;
88
+ handleSeek(time);
89
+ }
90
+ if (isDraggingVolume && volumeRef.current) {
91
+ const rect = volumeRef.current.getBoundingClientRect();
92
+ const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
93
+ handleVolumeChange(percent);
94
+ }
95
+ };
96
+ const handleMouseUp = () => {
97
+ setIsDraggingProgress(false);
98
+ setIsDraggingVolume(false);
99
+ };
100
+ if (isDraggingProgress || isDraggingVolume) {
101
+ document.addEventListener("mousemove", handleMouseMove);
102
+ document.addEventListener("mouseup", handleMouseUp);
103
+ }
104
+ return () => {
105
+ document.removeEventListener("mousemove", handleMouseMove);
106
+ document.removeEventListener("mouseup", handleMouseUp);
107
+ };
108
+ }, [isDraggingProgress, isDraggingVolume, duration, handleSeek, handleVolumeChange]);
109
+ const stopPropagation = React.useCallback((e) => {
110
+ e.preventDefault();
111
+ e.stopPropagation();
112
+ }, []);
113
+ if (ultraCompact) {
114
+ return /* @__PURE__ */ React__default.default.createElement(
115
+ "div",
116
+ {
117
+ className: `flex items-center gap-2 bg-white/90 backdrop-blur-sm rounded-xl p-2 shadow-lg border border-purple-200 ${className}`,
118
+ style: { width: hideVolumeControl ? "120px" : "192px" },
119
+ onClick: stopPropagation,
120
+ onMouseDown: stopPropagation,
121
+ onMouseUp: stopPropagation,
122
+ onTouchStart: stopPropagation,
123
+ onTouchEnd: stopPropagation,
124
+ onPointerDown: stopPropagation,
125
+ onPointerUp: stopPropagation
126
+ },
127
+ /* @__PURE__ */ React__default.default.createElement("div", { className: `flex items-center gap-1 ${hideVolumeControl ? "w-full justify-center" : ""}` }, /* @__PURE__ */ React__default.default.createElement(
128
+ "button",
129
+ {
130
+ onClick: (e) => {
131
+ stopPropagation(e);
132
+ handleStop();
133
+ },
134
+ onMouseDown: stopPropagation,
135
+ onMouseUp: stopPropagation,
136
+ onTouchStart: stopPropagation,
137
+ onTouchEnd: stopPropagation,
138
+ onPointerDown: stopPropagation,
139
+ onPointerUp: stopPropagation,
140
+ className: "w-7 h-7 rounded-lg bg-gray-100 hover:bg-gray-200 border border-gray-300 flex items-center justify-center transition-colors",
141
+ title: "\u505C\u6B62"
142
+ },
143
+ /* @__PURE__ */ React__default.default.createElement("div", { className: "w-2.5 h-2.5 bg-gray-600 rounded-sm" })
144
+ ), /* @__PURE__ */ React__default.default.createElement(
145
+ "button",
146
+ {
147
+ onClick: (e) => {
148
+ stopPropagation(e);
149
+ isPlaying ? handlePause() : handlePlay();
150
+ },
151
+ onMouseDown: stopPropagation,
152
+ onMouseUp: stopPropagation,
153
+ onTouchStart: stopPropagation,
154
+ onTouchEnd: stopPropagation,
155
+ onPointerDown: stopPropagation,
156
+ onPointerUp: stopPropagation,
157
+ className: `w-8 h-8 rounded-lg border flex items-center justify-center transition-colors ${isPlaying ? "bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white border-purple-400" : "bg-gradient-to-r from-green-500 to-blue-500 hover:from-green-600 hover:to-blue-600 text-white border-green-400 cursor-pointer"}`,
158
+ title: isPlaying ? "\u6682\u505C" : "\u64AD\u653E"
159
+ },
160
+ isPlaying ? /* @__PURE__ */ React__default.default.createElement("div", { className: "flex gap-0.5" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1 h-3 bg-white rounded-sm" }), /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1 h-3 bg-white rounded-sm" })) : /* @__PURE__ */ React__default.default.createElement("div", { className: "w-0 h-0 border-l-[6px] border-l-white border-t-[4px] border-t-transparent border-b-[4px] border-b-transparent ml-0.5" })
161
+ )),
162
+ !hideVolumeControl && /* @__PURE__ */ React__default.default.createElement("div", { className: "flex items-center gap-1 flex-1" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "text-gray-500 text-xs" }, "\u{1F50A}"), /* @__PURE__ */ React__default.default.createElement(
163
+ "div",
164
+ {
165
+ ref: volumeRef,
166
+ className: "flex-1 h-2 bg-gray-200 rounded-full cursor-pointer relative",
167
+ onMouseDown: handleVolumeMouseDown,
168
+ onClick: stopPropagation,
169
+ onTouchStart: stopPropagation,
170
+ onTouchEnd: stopPropagation,
171
+ onPointerDown: stopPropagation,
172
+ onPointerUp: stopPropagation
173
+ },
174
+ /* @__PURE__ */ React__default.default.createElement(
175
+ "div",
176
+ {
177
+ className: "h-full bg-gradient-to-r from-purple-400 to-pink-400 rounded-full",
178
+ style: { width: `${volume * 100}%` }
179
+ }
180
+ ),
181
+ /* @__PURE__ */ React__default.default.createElement(
182
+ "div",
183
+ {
184
+ className: "absolute top-1/2 w-3 h-3 bg-white border-2 border-purple-400 rounded-full transform -translate-y-1/2 cursor-grab",
185
+ style: { left: `${volume * 100}%`, transform: "translateX(-50%) translateY(-50%)" }
186
+ }
187
+ )
188
+ ))
189
+ );
190
+ }
191
+ return /* @__PURE__ */ React__default.default.createElement(
192
+ "div",
193
+ {
194
+ className: `bg-white/90 backdrop-blur-sm rounded-xl p-4 shadow-lg border border-purple-200 ${className}`,
195
+ style: { width: compact ? "280px" : "320px" },
196
+ onClick: stopPropagation,
197
+ onMouseDown: stopPropagation,
198
+ onMouseUp: stopPropagation,
199
+ onTouchStart: stopPropagation,
200
+ onTouchEnd: stopPropagation,
201
+ onPointerDown: stopPropagation,
202
+ onPointerUp: stopPropagation
203
+ },
204
+ !compact && showTrackInfo && track && /* @__PURE__ */ React__default.default.createElement("div", { className: "mb-3" }, /* @__PURE__ */ React__default.default.createElement("h3", { className: "text-sm font-medium text-gray-800 truncate" }, track.name), /* @__PURE__ */ React__default.default.createElement("p", { className: "text-xs text-gray-500" }, "\u80CC\u666F\u97F3\u4E50")),
205
+ !compact && /* @__PURE__ */ React__default.default.createElement("div", { className: "mb-3" }, /* @__PURE__ */ React__default.default.createElement(
206
+ "div",
207
+ {
208
+ ref: progressRef,
209
+ className: "w-full h-2 bg-gray-200 rounded-full cursor-pointer relative",
210
+ onMouseDown: handleProgressMouseDown,
211
+ onClick: stopPropagation,
212
+ onTouchStart: stopPropagation,
213
+ onTouchEnd: stopPropagation,
214
+ onPointerDown: stopPropagation,
215
+ onPointerUp: stopPropagation
216
+ },
217
+ /* @__PURE__ */ React__default.default.createElement(
218
+ "div",
219
+ {
220
+ className: "h-full bg-gradient-to-r from-purple-400 to-pink-400 rounded-full transition-all duration-100",
221
+ style: { width: duration > 0 ? `${currentTime / duration * 100}%` : "0%" }
222
+ }
223
+ ),
224
+ /* @__PURE__ */ React__default.default.createElement(
225
+ "div",
226
+ {
227
+ className: "absolute top-1/2 w-4 h-4 bg-white border-2 border-purple-400 rounded-full transform -translate-y-1/2 cursor-grab",
228
+ style: {
229
+ left: duration > 0 ? `${currentTime / duration * 100}%` : "0%",
230
+ transform: "translateX(-50%) translateY(-50%)"
231
+ }
232
+ }
233
+ )
234
+ ), /* @__PURE__ */ React__default.default.createElement("div", { className: "flex justify-between text-xs text-gray-500 mt-1" }, /* @__PURE__ */ React__default.default.createElement("span", null, formatTime(currentTime)), /* @__PURE__ */ React__default.default.createElement("span", null, formatTime(duration)))),
235
+ /* @__PURE__ */ React__default.default.createElement("div", { className: "flex items-center justify-center gap-3 mb-3" }, /* @__PURE__ */ React__default.default.createElement(
236
+ "button",
237
+ {
238
+ onClick: (e) => {
239
+ stopPropagation(e);
240
+ handleStop();
241
+ },
242
+ onMouseDown: stopPropagation,
243
+ onMouseUp: stopPropagation,
244
+ onTouchStart: stopPropagation,
245
+ onTouchEnd: stopPropagation,
246
+ onPointerDown: stopPropagation,
247
+ onPointerUp: stopPropagation,
248
+ className: "w-10 h-10 rounded-full bg-gray-100 hover:bg-gray-200 border border-gray-300 flex items-center justify-center transition-colors",
249
+ title: "\u505C\u6B62"
250
+ },
251
+ /* @__PURE__ */ React__default.default.createElement("div", { className: "w-4 h-4 bg-gray-600 rounded-sm" })
252
+ ), /* @__PURE__ */ React__default.default.createElement(
253
+ "button",
254
+ {
255
+ onClick: (e) => {
256
+ stopPropagation(e);
257
+ isPlaying ? handlePause() : handlePlay();
258
+ },
259
+ onMouseDown: stopPropagation,
260
+ onMouseUp: stopPropagation,
261
+ onTouchStart: stopPropagation,
262
+ onTouchEnd: stopPropagation,
263
+ onPointerDown: stopPropagation,
264
+ onPointerUp: stopPropagation,
265
+ className: `w-12 h-12 rounded-full border-2 flex items-center justify-center transition-colors ${isPlaying ? "bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white border-purple-400" : "bg-gradient-to-r from-green-500 to-blue-500 hover:from-green-600 hover:to-blue-600 text-white border-green-400 cursor-pointer"}`,
266
+ title: isPlaying ? "\u6682\u505C" : "\u64AD\u653E"
267
+ },
268
+ isLoading ? /* @__PURE__ */ React__default.default.createElement("div", { className: "w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin" }) : isPlaying ? /* @__PURE__ */ React__default.default.createElement("div", { className: "flex gap-1" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1.5 h-4 bg-white rounded-sm" }), /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1.5 h-4 bg-white rounded-sm" })) : /* @__PURE__ */ React__default.default.createElement("div", { className: "w-0 h-0 border-l-[10px] border-l-white border-t-[7px] border-t-transparent border-b-[7px] border-b-transparent ml-1" })
269
+ )),
270
+ !hideVolumeControl && /* @__PURE__ */ React__default.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "text-gray-500 text-sm" }, "\u{1F50A}"), /* @__PURE__ */ React__default.default.createElement(
271
+ "div",
272
+ {
273
+ ref: volumeRef,
274
+ className: "flex-1 h-2 bg-gray-200 rounded-full cursor-pointer relative",
275
+ onMouseDown: handleVolumeMouseDown,
276
+ onClick: stopPropagation,
277
+ onTouchStart: stopPropagation,
278
+ onTouchEnd: stopPropagation,
279
+ onPointerDown: stopPropagation,
280
+ onPointerUp: stopPropagation
281
+ },
282
+ /* @__PURE__ */ React__default.default.createElement(
283
+ "div",
284
+ {
285
+ className: "h-full bg-gradient-to-r from-purple-400 to-pink-400 rounded-full",
286
+ style: { width: `${volume * 100}%` }
287
+ }
288
+ ),
289
+ /* @__PURE__ */ React__default.default.createElement(
290
+ "div",
291
+ {
292
+ className: "absolute top-1/2 w-4 h-4 bg-white border-2 border-purple-400 rounded-full transform -translate-y-1/2 cursor-grab",
293
+ style: { left: `${volume * 100}%`, transform: "translateX(-50%) translateY(-50%)" }
294
+ }
295
+ )
296
+ ), /* @__PURE__ */ React__default.default.createElement("div", { className: "text-xs text-gray-500 w-8 text-right" }, Math.round(volume * 100), "%")),
297
+ error && /* @__PURE__ */ React__default.default.createElement("div", { className: "mt-2 text-xs text-red-500" }, error)
298
+ );
299
+ }
300
+ function MikutapMusicPlayer({
301
+ track,
302
+ onPlay,
303
+ onPause,
304
+ onSeek,
305
+ className = "",
306
+ isPlaying,
307
+ currentTime,
308
+ duration
309
+ }) {
310
+ const progressRef = React.useRef(null);
311
+ const [isDraggingProgress, setIsDraggingProgress] = React.useState(false);
312
+ const formatTime = (seconds) => {
313
+ if (!seconds || isNaN(seconds)) return "0:00";
314
+ const mins = Math.floor(seconds / 60);
315
+ const secs = Math.floor(seconds % 60);
316
+ return `${mins}:${secs.toString().padStart(2, "0")}`;
317
+ };
318
+ const handlePlay = React.useCallback(() => {
319
+ onPlay?.();
320
+ }, [onPlay]);
321
+ const handlePause = React.useCallback(() => {
322
+ onPause?.();
323
+ }, [onPause]);
324
+ const handleSeek = React.useCallback((time) => {
325
+ if (!duration || isNaN(duration)) return;
326
+ const seekTime = Math.max(0, Math.min(duration, time));
327
+ onSeek?.(seekTime);
328
+ }, [duration, onSeek]);
329
+ const handleProgressMouseDown = React.useCallback((e) => {
330
+ if (!progressRef.current || !duration) return;
331
+ setIsDraggingProgress(true);
332
+ const rect = progressRef.current.getBoundingClientRect();
333
+ const percent = (e.clientX - rect.left) / rect.width;
334
+ const time = percent * duration;
335
+ handleSeek(time);
336
+ }, [duration, handleSeek]);
337
+ React.useEffect(() => {
338
+ const handleMouseMove = (e) => {
339
+ if (isDraggingProgress && progressRef.current && duration) {
340
+ const rect = progressRef.current.getBoundingClientRect();
341
+ const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
342
+ const time = percent * duration;
343
+ handleSeek(time);
344
+ }
345
+ };
346
+ const handleMouseUp = () => {
347
+ setIsDraggingProgress(false);
348
+ };
349
+ if (isDraggingProgress) {
350
+ document.addEventListener("mousemove", handleMouseMove);
351
+ document.addEventListener("mouseup", handleMouseUp);
352
+ }
353
+ return () => {
354
+ document.removeEventListener("mousemove", handleMouseMove);
355
+ document.removeEventListener("mouseup", handleMouseUp);
356
+ };
357
+ }, [isDraggingProgress, duration, handleSeek]);
358
+ const stopPropagation = React.useCallback((e) => {
359
+ e.preventDefault();
360
+ e.stopPropagation();
361
+ }, []);
362
+ return /* @__PURE__ */ React__default.default.createElement(
363
+ "div",
364
+ {
365
+ className: `bg-gradient-to-r from-purple-900/95 to-pink-900/95 backdrop-blur-sm rounded-2xl p-4 shadow-2xl border border-purple-300/30 ${className}`,
366
+ style: { width: "200px" },
367
+ onClick: stopPropagation,
368
+ onMouseDown: stopPropagation,
369
+ onMouseUp: stopPropagation,
370
+ onTouchStart: stopPropagation,
371
+ onTouchEnd: stopPropagation,
372
+ onPointerDown: stopPropagation,
373
+ onPointerUp: stopPropagation
374
+ },
375
+ track && /* @__PURE__ */ React__default.default.createElement("div", { className: "mb-3 text-center" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "text-white text-sm font-medium truncate mb-1" }, track.name), /* @__PURE__ */ React__default.default.createElement("div", { className: "text-purple-200 text-xs" }, "\u80CC\u666F\u97F3\u4E50")),
376
+ /* @__PURE__ */ React__default.default.createElement("div", { className: "flex justify-center mb-3" }, /* @__PURE__ */ React__default.default.createElement(
377
+ "button",
378
+ {
379
+ onClick: (e) => {
380
+ stopPropagation(e);
381
+ isPlaying ? handlePause() : handlePlay();
382
+ },
383
+ onMouseDown: stopPropagation,
384
+ onMouseUp: stopPropagation,
385
+ onTouchStart: stopPropagation,
386
+ onTouchEnd: stopPropagation,
387
+ onPointerDown: stopPropagation,
388
+ onPointerUp: stopPropagation,
389
+ className: `w-12 h-12 rounded-full border-2 flex items-center justify-center transition-all duration-300 shadow-lg hover:scale-105 ${isPlaying ? "bg-gradient-to-r from-orange-400 to-red-500 hover:from-orange-500 hover:to-red-600 text-white border-orange-300 shadow-orange-500/50" : "bg-gradient-to-r from-green-400 to-emerald-500 hover:from-green-500 hover:to-emerald-600 text-white border-green-300 shadow-green-500/50"}`,
390
+ title: isPlaying ? "\u6682\u505C" : "\u64AD\u653E"
391
+ },
392
+ isPlaying ? /* @__PURE__ */ React__default.default.createElement("div", { className: "flex gap-1" }, /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1.5 h-4 bg-white rounded-sm" }), /* @__PURE__ */ React__default.default.createElement("div", { className: "w-1.5 h-4 bg-white rounded-sm" })) : /* @__PURE__ */ React__default.default.createElement("div", { className: "w-0 h-0 border-l-[10px] border-l-white border-t-[7px] border-t-transparent border-b-[7px] border-b-transparent ml-1" })
393
+ )),
394
+ /* @__PURE__ */ React__default.default.createElement("div", { className: "mb-2" }, /* @__PURE__ */ React__default.default.createElement(
395
+ "div",
396
+ {
397
+ ref: progressRef,
398
+ className: "w-full h-2 bg-white/20 rounded-full cursor-pointer relative overflow-hidden",
399
+ onMouseDown: handleProgressMouseDown,
400
+ onClick: stopPropagation,
401
+ onTouchStart: stopPropagation,
402
+ onTouchEnd: stopPropagation,
403
+ onPointerDown: stopPropagation,
404
+ onPointerUp: stopPropagation
405
+ },
406
+ /* @__PURE__ */ React__default.default.createElement(
407
+ "div",
408
+ {
409
+ className: "h-full bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full transition-all duration-100 shadow-sm",
410
+ style: { width: duration > 0 ? `${currentTime / duration * 100}%` : "0%" }
411
+ }
412
+ ),
413
+ /* @__PURE__ */ React__default.default.createElement(
414
+ "div",
415
+ {
416
+ className: "absolute top-1/2 w-3 h-3 bg-white border-2 border-cyan-400 rounded-full transform -translate-y-1/2 cursor-grab shadow-lg",
417
+ style: {
418
+ left: duration > 0 ? `${currentTime / duration * 100}%` : "0%",
419
+ transform: "translateX(-50%) translateY(-50%)"
420
+ }
421
+ }
422
+ )
423
+ ), /* @__PURE__ */ React__default.default.createElement("div", { className: "flex justify-between text-xs text-purple-200 mt-1" }, /* @__PURE__ */ React__default.default.createElement("span", null, formatTime(currentTime)), /* @__PURE__ */ React__default.default.createElement("span", null, formatTime(duration)))),
424
+ /* @__PURE__ */ React__default.default.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React__default.default.createElement("div", { className: `flex items-center gap-2 text-xs px-3 py-1 rounded-full transition-all duration-300 ${isPlaying ? "bg-orange-500/20 text-orange-200 border border-orange-400/30" : "bg-gray-500/20 text-gray-300 border border-gray-400/30"}` }, /* @__PURE__ */ React__default.default.createElement("div", { className: `w-2 h-2 rounded-full transition-all duration-300 ${isPlaying ? "bg-orange-400 animate-pulse" : "bg-gray-400"}` }), /* @__PURE__ */ React__default.default.createElement("span", null, isPlaying ? "\u64AD\u653E\u4E2D" : "\u5DF2\u6682\u505C")))
425
+ );
426
+ }
427
+
428
+ // src/music/adapters/kugou.ts
429
+ var kugouAdapter = {
430
+ parseSearchResult(data) {
431
+ const root = typeof data === "string" ? JSON.parse(data) : data;
432
+ const info = root.data?.data?.info || root.data?.info || root.info || [];
433
+ const total = root.data?.data?.total || root.data?.total || info.length;
434
+ return {
435
+ tracks: info.map((item) => {
436
+ let pic = item.pic || "";
437
+ if (item.trans_param?.union_cover) {
438
+ pic = item.trans_param.union_cover.replace("{size}", "400");
439
+ }
440
+ return {
441
+ id: item.hash || item.id,
442
+ name: item.songname || item.filename || "Unknown",
443
+ artist: item.singername || "Unknown Artist",
444
+ album: item.album_name || item.album || "",
445
+ pic,
446
+ url: item.url,
447
+ lrc: item.lrc,
448
+ source: "kugou",
449
+ isVip: item.privilege >= 8,
450
+ playable: item.status !== 0
451
+ };
452
+ }),
453
+ total
454
+ };
455
+ },
456
+ parseGetSongUrl(data) {
457
+ return data.url?.url || data.url?.backup_url?.[0] || null;
458
+ },
459
+ parseGetLyric(data) {
460
+ const root = typeof data === "string" ? JSON.parse(data) : data;
461
+ return root.lyric || root.lrc || root.data?.lyric || root.data || "";
462
+ }
463
+ };
464
+
465
+ // src/music/adapters/netease.ts
466
+ var neteaseAdapter = {
467
+ parseSearchResult(data) {
468
+ const root = typeof data === "string" ? JSON.parse(data) : data;
469
+ const songs = root.result?.songs || root.songs || (Array.isArray(root) ? root : []);
470
+ return {
471
+ tracks: songs.map((item) => ({
472
+ id: item.id,
473
+ name: item.name,
474
+ artist: Array.isArray(item.artist) ? item.artist.join(", ") : item.artist,
475
+ album: item.album?.name || item.album,
476
+ pic: item.pic || item.album?.picUrl,
477
+ url: item.url,
478
+ lrc: item.lrc,
479
+ source: "netease",
480
+ isVip: item.fee === 1 || item.fee === 4,
481
+ playable: item.noCopyrightRcmd === null
482
+ })),
483
+ total: root.result?.songCount || songs.length
484
+ };
485
+ },
486
+ parseGetSongUrl(data) {
487
+ const root = typeof data === "string" ? JSON.parse(data) : data;
488
+ const item = root.data?.[0] || root[0] || root;
489
+ return item.url || null;
490
+ },
491
+ parseGetLyric(data) {
492
+ const root = typeof data === "string" ? JSON.parse(data) : data;
493
+ return root.lyric || root.lrc || root.data?.lyric || "";
494
+ }
495
+ };
496
+
497
+ // src/music/adapters/tencent.ts
498
+ var tencentAdapter = {
499
+ parseSearchResult(data) {
500
+ const root = typeof data === "string" ? JSON.parse(data) : data;
501
+ const songData = root.data?.data?.song || root.data?.song || root.data || root;
502
+ const list = songData.list || root.songs || [];
503
+ const total = songData.totalnum || root.total || list.length;
504
+ return {
505
+ tracks: list.map((item) => {
506
+ const artist = Array.isArray(item.singer) ? item.singer.map((s) => s.name).join(", ") : item.singer?.[0]?.name || item.artist || "Unknown";
507
+ let pic = item.pic;
508
+ if (!pic && item.album?.mid) {
509
+ pic = `https://y.gtimg.cn/music/photo_new/T002R300x300M000${item.album.mid}.jpg`;
510
+ }
511
+ return {
512
+ id: item.mid || item.id || item.songid,
513
+ name: item.name || item.title || item.songname,
514
+ artist,
515
+ album: item.album?.name || item.albumname || item.album,
516
+ pic: pic || "",
517
+ url: item.url,
518
+ lrc: item.lrc,
519
+ source: "tencent",
520
+ isVip: item.pay?.pay_play === 1,
521
+ playable: item.action?.switch !== 0
522
+ };
523
+ }),
524
+ total
525
+ };
526
+ },
527
+ parseGetSongUrl(data) {
528
+ const root = data;
529
+ const urlData = root.url.url;
530
+ let finalUrl = Object.values(urlData)[0];
531
+ console.log("finalUrl2", finalUrl);
532
+ return finalUrl.startsWith("http") ? finalUrl : `http://${finalUrl}`;
533
+ },
534
+ parseGetLyric(data) {
535
+ const root = typeof data === "string" ? JSON.parse(data) : data;
536
+ return root.lyric || root.lrc || root.data?.lyric || "";
537
+ }
538
+ };
539
+
540
+ // src/music/adapters/xiami.ts
541
+ var xiamiAdapter = {
542
+ parseSearchResult(data) {
543
+ const root = typeof data === "string" ? JSON.parse(data) : data;
544
+ const result = root.data?.result || root.result || root;
545
+ const songs = result.songs || (Array.isArray(root) ? root : []);
546
+ return {
547
+ tracks: songs.map((item) => ({
548
+ id: item.id?.toString() || "",
549
+ name: item.name || "Unknown",
550
+ artist: Array.isArray(item.ar) ? item.ar.map((a) => a.name).join(", ") : item.artist || "Unknown Artist",
551
+ album: item.al?.name || item.album || "",
552
+ pic: item.al?.picUrl || item.pic || "",
553
+ url: item.url,
554
+ lrc: item.lrc,
555
+ source: "xiami",
556
+ // 这里的逻辑参考提供的数据结构
557
+ isVip: item.fee === 1 || item.fee === 8,
558
+ playable: item.copyright !== 0
559
+ })),
560
+ total: result.songCount || songs.length
561
+ };
562
+ },
563
+ parseGetSongUrl(data) {
564
+ const root = typeof data === "string" ? JSON.parse(data) : data;
565
+ const item = root.data?.[0] || root.data || root[0] || root;
566
+ return item.url || null;
567
+ },
568
+ parseGetLyric(data) {
569
+ const root = typeof data === "string" ? JSON.parse(data) : data;
570
+ return root.lyric || root.lrc || root.data?.lyric || root.data || "";
571
+ }
572
+ };
573
+
574
+ // src/music/hooks/useMusic.ts
575
+ var fetcher = (url) => fetch(url).then((res) => res.json());
576
+ var ADAPTERS = {
577
+ kugou: kugouAdapter,
578
+ netease: neteaseAdapter,
579
+ tencent: tencentAdapter,
580
+ xiami: xiamiAdapter
581
+ };
582
+ function useMusic() {
583
+ const [searchOptions, setSearchOptions] = React.useState(null);
584
+ const { data: rawData, error: searchError, isLoading: isSearching } = useSWR__default.default(
585
+ searchOptions ? `/api/music/search?keyword=${encodeURIComponent(searchOptions.keyword)}&source=${searchOptions.source || chunk2ODO4HEI_js.DEFAULT_MUSIC_SOURCE}&limit=${searchOptions.limit || 20}&offset=${searchOptions.offset || 0}${searchOptions.miku ? "&miku=true" : ""}` : null,
586
+ fetcher
587
+ );
588
+ const searchResult = React.useMemo(() => {
589
+ if (!rawData?.data || !searchOptions) return void 0;
590
+ const adapter = ADAPTERS[searchOptions.source || chunk2ODO4HEI_js.DEFAULT_MUSIC_SOURCE];
591
+ if (adapter) {
592
+ return adapter.parseSearchResult(rawData.data);
593
+ }
594
+ return void 0;
595
+ }, [rawData, searchOptions]);
596
+ const search = React.useCallback((options) => {
597
+ setSearchOptions(options);
598
+ }, []);
599
+ const getSongUrl = React.useCallback(async (id, source = chunk2ODO4HEI_js.DEFAULT_MUSIC_SOURCE) => {
600
+ try {
601
+ const res = await fetch(`/api/music/url?id=${id}&source=${source}`);
602
+ const json = await res.json();
603
+ const adapter = ADAPTERS[source];
604
+ console.log("json2", json.data, source, adapter);
605
+ if (adapter && json.data) {
606
+ console.log("getSongUrl2", json.data);
607
+ return adapter.parseGetSongUrl(json.data) || void 0;
608
+ }
609
+ return json.data?.url;
610
+ } catch (err) {
611
+ console.error("[Music] Failed to get song URL:", err);
612
+ return void 0;
613
+ }
614
+ }, []);
615
+ const getLyric = React.useCallback(async (id, source = chunk2ODO4HEI_js.DEFAULT_MUSIC_SOURCE) => {
616
+ try {
617
+ const res = await fetch(`/api/music/lyric?id=${id}&source=${source}`);
618
+ const json = await res.json();
619
+ const adapter = ADAPTERS[source];
620
+ if (adapter && json.data) {
621
+ return adapter.parseGetLyric(json.data);
622
+ }
623
+ return json.data?.lyric;
624
+ } catch (err) {
625
+ console.error("[Music] Failed to get lyric:", err);
626
+ return void 0;
627
+ }
628
+ }, []);
629
+ return {
630
+ search,
631
+ searchResult,
632
+ isSearching,
633
+ searchError,
634
+ getSongUrl,
635
+ getLyric
636
+ };
637
+ }
638
+
639
+ exports.MikutapMusicPlayer = MikutapMusicPlayer;
640
+ exports.MusicPlayer = MusicPlayer;
641
+ exports.kugouAdapter = kugouAdapter;
642
+ exports.neteaseAdapter = neteaseAdapter;
643
+ exports.tencentAdapter = tencentAdapter;
644
+ exports.useMusic = useMusic;
645
+ exports.xiamiAdapter = xiamiAdapter;
646
+ //# sourceMappingURL=chunk-L5PW2YTI.js.map
647
+ //# sourceMappingURL=chunk-L5PW2YTI.js.map