1import { r as reactExports, j as jsxRuntimeExports } from "./vendor-react-Bay9Y7Lb.js"; 2import { C as CreditsExhaustedModal } from "./CreditsExhaustedModal-DRhMaBTs.js"; 3import { u as useTranslation } from "./vendor-i18n-BC7ZMXWQ.js"; 4import { co as FileMusic, ec as CloudUpload, bE as Link, ed as File, bF as ChevronRight, cM as RefreshCw, a_ as CircleCheck, aY as TriangleAlert, d1 as Download, b1 as CircleAlert } from "./vendor-D0P4XgNj.js"; 5function ScoreConverterPage({ 6 currentUser, 7 onAuthRequested 8}) { 9 var _a, _b, _c, _d, _e, _f; 10 const { t } = useTranslation(); 11 const [activeTab, setActiveTab] = reactExports.useState("file"); 12 const [file, setFile] = reactExports.useState(null); 13 const [url, setUrl] = reactExports.useState(""); 14 const [status, setStatus] = reactExports.useState("idle"); 15 const [jobId, setJobId] = reactExports.useState(null); 16 const [progress, setProgress] = reactExports.useState(0); 17 const [result, setResult] = reactExports.useState(null); 18 const [errorMsg, setErrorMsg] = reactExports.useState(""); 19 const [isPublishing, setIsPublishing] = reactExports.useState(false); 20 const [showCreditWarning, setShowCreditWarning] = reactExports.useState(false); 21 const [showExhausted, setShowExhausted] = reactExports.useState(false); 22 const [isDragging, setIsDragging] = reactExports.useState(false); 23 const fileInputRef = reactExports.useRef(null); 24 const onDragOver = (e) => { 25 e.preventDefault(); 26 setIsDragging(true); 27 }; 28 const onDragLeave = (e) => { 29 e.preventDefault(); 30 setIsDragging(false); 31 }; 32 const onDrop = (e) => { 33 e.preventDefault(); 34 setIsDragging(false); 35 if (e.dataTransfer.files && e.dataTransfer.files[0]) { 36 setFile(e.dataTransfer.files[0]); 37 } 38 }; 39 reactExports.useEffect(() => { 40 let interval; 41 if (status === "processing" && jobId) { 42 interval = setInterval(async () => { 43 try { 44 const res = await fetch(`/api/score-converter/status/${jobId}`); 45 const data = await res.json(); 46 if (data.status === "completed") { 47 setStatus("completed"); 48 setResult(data.result); 49 clearInterval(interval); 50 } else if (data.status === "error" || data.status === "failed") { 51 setStatus("error"); 52 setErrorMsg(data.error || data.details || "An error occurred during conversion."); 53 clearInterval(interval); 54 } else { 55 setProgress(data.progress || 0); 56 } 57 } catch (e) { 58 setStatus("error"); 59 setErrorMsg("Failed to check status."); 60 clearInterval(interval); 61 } 62 }, 2e3); 63 } 64 return () => clearInterval(interval); 65 }, [status, jobId]); 66 const startConversion = () => { 67 if (!currentUser) { 68 onAuthRequested(); 69 return; 70 } 71 if (activeTab === "file" && !file || activeTab === "url" && !url.trim()) { 72 return; 73 } 74 setShowCreditWarning(true); 75 }; 76 const confirmConversion = async () => { 77 setShowCreditWarning(false); 78 if (((currentUser == null ? void 0 : currentUser.credits) || 0) < 3) { 79 setShowExhausted(true); 80 return; 81 } 82 setStatus("processing"); 83 setProgress(0); 84 setErrorMsg(""); 85 try { 86 let res; 87 if (activeTab === "file" && file) { 88 const formData = new FormData(); 89 formData.append("file", file); 90 res = await fetch("/api/score-converter/convert", { 91 method: "POST", 92 body: formData 93 }); 94 } else if (activeTab === "url" && url) { 95 res = await fetch("/api/score-converter/convert-url", { 96 method: "POST", 97 headers: { "Content-Type": "application/json" }, 98 body: JSON.stringify({ url }) 99 }); 100 } else { 101 return; 102 } 103 const data = await res.json(); 104 if (data.success && data.jobId) { 105 setJobId(data.jobId); 106 } else { 107 setStatus("error"); 108 setErrorMsg(data.error || "Failed to start conversion."); 109 } 110 } catch (e) { 111 setStatus("error"); 112 setErrorMsg("Network error while starting conversion."); 113 } 114 }; 115 const handlePublish = async () => { 116 if (!jobId || isPublishing) return; 117 setIsPublishing(true); 118 try { 119 const res = await fetch("/api/score-converter/upload-to-site", { 120 method: "POST", 121 headers: { "Content-Type": "application/json" }, 122 body: JSON.stringify({ jobId }) 123 }); 124 const data = await res.json(); 125 if (data.success && data.trackUrl) { 126 window.location.href = data.trackUrl; 127 } else { 128 alert(data.error || "Failed to publish."); 129 setIsPublishing(false); 130 } 131 } catch (e) { 132 alert("Error publishing to site."); 133 setIsPublishing(false); 134 } 135 }; 136 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-h-screen bg-zinc-50 dark:bg-zinc-950 py-12 px-4 sm:px-6 lg:px-8", children: [
137 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-4xl mx-auto", children: [ 138 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center mb-12", children: [ 139 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-100 dark:bg-blue-900/30 mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(FileMusic, { className: "w-8 h-8 text-blue-600 dark:text-blue-400" }) }), 140 /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-4xl font-extrabold text-zinc-900 dark:text-white tracking-tight", children: "Score Format Converter" }), 141 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-4 text-lg text-zinc-600 dark:text-zinc-400 max-w-2xl mx-auto", children: "Transform your digital sheet music files (MXL, MusicXML, MuseScore) into high-quality standard MIDI formats seamlessly." }) 142 ] }), 143 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-zinc-900 rounded-2xl shadow-xl border border-zinc-200 dark:border-zinc-800 overflow-hidden", children: [
144 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex border-b border-zinc-200 dark:border-zinc-800", children: [ 145 /* @__PURE__ */ jsxRuntimeExports.jsxs( 146 "button", 147 { 148 onClick: () => setActiveTab("file"), 149 className: `flex-1 py-4 px-6 text-sm font-medium flex items-center justify-center gap-2 transition-colors ${activeTab === "file" ? "border-b-2 border-blue-500 text-blue-600 dark:text-blue-400 bg-blue-50/50 dark:bg-blue-900/10" : "text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-300"}`, 150 children: [ 151 /* @__PURE__ */ jsxRuntimeExports.jsx(CloudUpload, { className: "w-4 h-4" }), 152 "Upload File" 153 ] 154 } 155 ), 156 /* @__PURE__ */ jsxRuntimeExports.jsxs( 157 "button", 158 { 159 onClick: () => setActiveTab("url"), 160 className: `flex-1 py-4 px-6 text-sm font-medium flex items-center justify-center gap-2 transition-colors ${activeTab === "url" ? "border-b-2 border-blue-500 text-blue-600 dark:text-blue-400 bg-blue-50/50 dark:bg-blue-900/10" : "text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-300"}`, 161 children: [
162 /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { className: "w-4 h-4" }), 163 "Enter URL" 164 ] 165 } 166 ) 167 ] }), 168 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-8", children: [ 169 status === "idle" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-8", children: [ 170 activeTab === "file" ? /* @__PURE__ */ jsxRuntimeExports.jsxs( 171 "div", 172 { 173 onDragOver, 174 onDragLeave, 175 onDrop, 176 className: `border-2 border-dashed rounded-xl p-12 text-center transition-all ${isDragging ? "border-blue-500 bg-blue-50 dark:bg-blue-900/20" : "border-zinc-300 dark:border-zinc-700 hover:border-blue-400 hover:bg-zinc-50 dark:hover:bg-zinc-800/50"}`, 177 children: [ 178 /* @__PURE__ */ jsxRuntimeExports.jsx( 179 "input", 180 { 181 type: "file", 182 ref: fileInputRef, 183 className: "hidden", 184 accept: ".mxl,.xml,.musicxml,.mscz,.mscx,.ly,.ily,.abc,.ptb,.gp,.gp3,.gp4,.gp5,.gp6,.gp7,.gpx,.krn,.ham,.cap,.capx,.ove,.scw", 185 onChange: (e) => { 186 if (e.target.files && e.target.files[0]) { 187 setFile(e.target.files[0]); 188 } 189 } 190 } 191 ),
192 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-auto w-16 h-16 mb-4 rounded-full bg-zinc-100 dark:bg-zinc-800 flex items-center justify-center", children: file ? /* @__PURE__ */ jsxRuntimeExports.jsx(File, { className: "w-8 h-8 text-blue-500" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(CloudUpload, { className: "w-8 h-8 text-zinc-400" }) }), 193 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium text-zinc-900 dark:text-zinc-100 mb-2", children: file ? file.name : "Drag & drop your score file here" }), 194 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-zinc-500 dark:text-zinc-400 mb-6", children: file ? `${(file.size / 1024 / 1024).toFixed(2)} MB` : "Supports MusicXML, MuseScore, LilyPond, ABC, Guitar Pro, PowerTab, Humdrum, and Hamie up to 50MB" }), 195 /* @__PURE__ */ jsxRuntimeExports.jsx( 196 "button", 197 { 198 onClick: () => { 199 var _a2; 200 return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click(); 201 }, 202 className: "px-6 py-2.5 rounded-lg bg-zinc-900 dark:bg-white text-white dark:text-zinc-900 font-medium hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors", 203 children: "Browse Files" 204 } 205 ) 206 ] 207 } 208 ) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
209 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-zinc-700 dark:text-zinc-300", children: "Score URL (MuseScore, IMSLP, abcnotation, etc.)" }), 210 /* @__PURE__ */ jsxRuntimeExports.jsx( 211 "input", 212 { 213 type: "url", 214 value: url, 215 onChange: (e) => setUrl(e.target.value), 216 placeholder: "https://...", 217 className: "w-full px-4 py-3 rounded-xl border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all" 218 } 219 ) 220 ] }), 221 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntimeExports.jsxs( 222 "button", 223 { 224 onClick: startConversion, 225 disabled: activeTab === "file" ? !file : !url.trim(), 226 className: "flex items-center gap-2 px-8 py-3.5 bg-blue-600 hover:bg-blue-700 disabled:opacity-50 disabled:hover:bg-blue-600 text-white rounded-xl font-semibold shadow-md shadow-blue-500/20 transition-all", 227 children: [ 228 "Convert Score",
229 /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-5 h-5" }) 230 ] 231 } 232 ) }) 233 ] }), 234 status === "processing" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-12 text-center", children: [ 235 /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "w-12 h-12 text-blue-500 mx-auto animate-spin mb-6" }), 236 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-xl font-bold text-zinc-900 dark:text-white mb-2", children: "Converting your score..." }), 237 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-500 dark:text-zinc-400 mb-8", children: "This might take a minute depending on the complexity." }), 238 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-w-md mx-auto bg-zinc-100 dark:bg-zinc-800 rounded-full h-3 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx( 239 "div", 240 { 241 className: "bg-blue-500 h-full rounded-full transition-all duration-500 ease-out", 242 style: { width: `${progress}%` } 243 } 244 ) }),
245 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-3 text-sm font-medium text-blue-600 dark:text-blue-400", children: [ 246 progress, 247 "% Complete" 248 ] }) 249 ] }), 250 status === "completed" && result && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-8 animate-in fade-in slide-in-from-bottom-4 duration-500", children: [ 251 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [ 252 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "inline-flex items-center justify-center w-16 h-16 rounded-full bg-green-100 dark:bg-green-900/30 mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "w-8 h-8 text-green-600 dark:text-green-400" }) }), 253 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-2xl font-bold text-zinc-900 dark:text-white", children: "Conversion Successful!" }) 254 ] }), 255 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-50 dark:bg-zinc-800/50 rounded-xl p-6 border border-zinc-200 dark:border-zinc-700", children: [
256 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-semibold text-zinc-900 dark:text-white uppercase tracking-wider mb-4", children: "Metadata" }), 257 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [ 258 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 259 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Title" }), 260 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium text-zinc-900 dark:text-white truncate", children: ((_a = result.metadata) == null ? void 0 : _a.title) && result.metadata.title.toLowerCase() !== "unknown" ? result.metadata.title : file ? file.name.replace(/\.[^/.]+$/, "") : "Converted Score" }) 261 ] }), 262 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 263 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Composer" }),
264 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium text-zinc-900 dark:text-white truncate", children: ((_b = result.metadata) == null ? void 0 : _b.composer) && !["unknown", "unknown artist", "unknown composer"].includes(result.metadata.composer.trim().toLowerCase()) ? result.metadata.composer : "-" }) 265 ] }), 266 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 267 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Time Signature" }), 268 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium text-zinc-900 dark:text-white", children: ((_c = result.metadata) == null ? void 0 : _c.timeSignature) || ((_d = result.metadata) == null ? void 0 : _d.time_signature) || "-" }) 269 ] }), 270 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 271 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Key" }),
272 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium text-zinc-900 dark:text-white", children: ((_e = result.metadata) == null ? void 0 : _e.key) || ((_f = result.metadata) == null ? void 0 : _f.key_signature) || "-" }) 273 ] }) 274 ] }) 275 ] }), 276 result.warnings && result.warnings.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-xl p-4 flex gap-3", children: [ 277 /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "w-5 h-5 text-amber-600 dark:text-amber-500 flex-shrink-0" }), 278 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 279 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-semibold text-amber-800 dark:text-amber-400 mb-1", children: "Warnings" }), 280 /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "text-sm text-amber-700 dark:text-amber-500 list-disc list-inside", children: result.warnings.map((w, i) => /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: w }, i)) }) 281 ] }) 282 ] }),
283 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row gap-4 pt-4 border-t border-zinc-200 dark:border-zinc-800", children: [ 284 /* @__PURE__ */ jsxRuntimeExports.jsxs( 285 "a", 286 { 287 href: `/api/score-converter/download/${jobId}`, 288 download: true, 289 className: "flex-1 flex items-center justify-center gap-2 px-6 py-3.5 bg-zinc-900 hover:bg-zinc-800 dark:bg-white dark:hover:bg-zinc-100 text-white dark:text-zinc-900 rounded-xl font-semibold transition-colors", 290 children: [ 291 /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "w-5 h-5" }), 292 "Download MIDI" 293 ] 294 } 295 ), 296 /* @__PURE__ */ jsxRuntimeExports.jsx( 297 "button", 298 { 299 onClick: handlePublish, 300 disabled: isPublishing, 301 className: "flex-1 flex items-center justify-center gap-2 px-6 py-3.5 bg-blue-600 hover:bg-blue-700 disabled:opacity-60 text-white rounded-xl font-semibold shadow-md shadow-blue-500/20 transition-all",
302 children: isPublishing ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 303 /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "w-5 h-5 animate-spin" }), 304 "Publishing to HamieNET..." 305 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 306 /* @__PURE__ */ jsxRuntimeExports.jsx(CloudUpload, { className: "w-5 h-5" }), 307 "Publish to HamieNET" 308 ] }) 309 } 310 ) 311 ] }) 312 ] }), 313 status === "error" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-12 text-center animate-in fade-in", children: [ 314 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "inline-flex items-center justify-center w-16 h-16 rounded-full bg-red-100 dark:bg-red-900/30 mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "w-8 h-8 text-red-600 dark:text-red-400" }) }),
315 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-2xl font-bold text-zinc-900 dark:text-white mb-2", children: "Conversion Failed" }), 316 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-red-600 dark:text-red-400 mb-8 max-w-md mx-auto", children: errorMsg }), 317 /* @__PURE__ */ jsxRuntimeExports.jsx( 318 "button", 319 { 320 onClick: () => { 321 setStatus("idle"); 322 setProgress(0); 323 }, 324 className: "px-8 py-3 bg-zinc-900 hover:bg-zinc-800 dark:bg-white dark:hover:bg-zinc-100 text-white dark:text-zinc-900 rounded-xl font-semibold transition-colors", 325 children: "Try Again" 326 } 327 ) 328 ] }) 329 ] }) 330 ] }) 331 ] }), 332 showCreditWarning && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-zinc-900 rounded-2xl max-w-md w-full p-6 shadow-2xl animate-in zoom-in-95 duration-200", children: [
333 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-start mb-4", children: [ 334 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-xl font-bold text-zinc-900 dark:text-white", children: "Confirm Action" }), 335 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShowCreditWarning(false), className: "text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "w-6 h-6" }) }) 336 ] }), 337 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-zinc-600 dark:text-zinc-400 mb-6", children: [ 338 "Converting a score costs ", 339 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "text-zinc-900 dark:text-white", children: "3 credits" }), 340 ". You currently have ", 341 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "text-zinc-900 dark:text-white", children: (currentUser == null ? void 0 : currentUser.credits) || 0 }), 342 " credits remaining." 343 ] }),
344 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-3 justify-end", children: [ 345 /* @__PURE__ */ jsxRuntimeExports.jsx( 346 "button", 347 { 348 onClick: () => setShowCreditWarning(false), 349 className: "px-5 py-2.5 rounded-lg text-sm font-medium text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors", 350 children: "Cancel" 351 } 352 ), 353 /* @__PURE__ */ jsxRuntimeExports.jsx( 354 "button", 355 { 356 onClick: confirmConversion, 357 className: "px-5 py-2.5 rounded-lg text-sm font-medium bg-blue-600 hover:bg-blue-700 text-white shadow-sm transition-colors", 358 children: "Confirm & Convert" 359 } 360 ) 361 ] }) 362 ] }) }), 363 /* @__PURE__ */ jsxRuntimeExports.jsx( 364 CreditsExhaustedModal, 365 { 366 isOpen: showExhausted, 367 onClose: () => setShowExhausted(false), 368 onSignUp: () => { 369 setShowExhausted(false); 370 onAuthRequested(); 371 } 372 } 373 ) 374 ] }); 375} 376export { 377 ScoreConverterPage as default 378};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.