1import { r as reactExports, j as jsxRuntimeExports } from "./vendor-react-Bay9Y7Lb.js"; 2import { cr as Network, dP as GitBranch, dQ as GitMerge, b7 as Check, dR as CodeXml, et as GitCommitHorizontal, aW as X, bU as Play, cm as ArrowRight, dN as Users } from "./vendor-dVNaLJx_.js"; 3import "./vendor-i18n-R-bMoYp_.js"; 4function AlgorithmStudio({ currentUser, onAuthRequested, onNavigate }) { 5 const [algorithms, setAlgorithms] = reactExports.useState([]); 6 const [isLoading, setIsLoading] = reactExports.useState(true); 7 const fetchAlgos = async () => { 8 try { 9 const res = await fetch("/api/algorithms"); 10 const data = await res.json(); 11 if (Array.isArray(data)) setAlgorithms(data); 12 } catch (e) { 13 console.error(e); 14 } finally { 15 setIsLoading(false); 16 } 17 }; 18 reactExports.useEffect(() => { 19 fetchAlgos(); 20 }, []); 21 const handleVote = async (id, value) => { 22 if (!currentUser) return onAuthRequested(); 23 try { 24 await fetch(`/api/algorithms/${id}/vote`, { 25 method: "POST", 26 headers: { "Content-Type": "application/json" }, 27 body: JSON.stringify({ value }) 28 }); 29 await fetchAlgos(); 30 } catch (e) { 31 console.error(e); 32 } 33 }; 34 if (isLoading) { 35 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-12 text-center text-zinc-500 font-semibold", children: "Loading Studio..." }); 36 } 37 const mainBranch = algorithms.find((a) => a.isMainBranch); 38 const phase2Algos = algorithms.filter((a) => a.status === "PHASE2"); 39 const phase1Algos = algorithms.filter((a) => a.status === "PHASE1"); 40 const drafts = algorithms.filter((a) => a.status === "DRAFT"); 41 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-6xl mx-auto p-6 animate-in fade-in", children: [ 42 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-8 flex-wrap gap-4", children: [
43 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 44 /* @__PURE__ */ jsxRuntimeExports.jsxs("h1", { className: "text-3xl font-black flex items-center gap-3 flex-wrap text-zinc-900 dark:text-zinc-100", children: [ 45 /* @__PURE__ */ jsxRuntimeExports.jsx(Network, { className: "text-indigo-500" }), 46 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Community Standard Engine" }), 47 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-flex items-center px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-wider bg-indigo-500/10 text-indigo-500 border border-indigo-500/30", children: "Hamie Lab" }) 48 ] }), 49 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-500 text-sm mt-1", children: "Crowdsourced MIDI-to-Score Quantization Engine. Branch, test, benchmark, and vote on standard engraving logic." }) 50 ] }), 51 /* @__PURE__ */ jsxRuntimeExports.jsxs( 52 "button", 53 { 54 type: "button", 55 onClick: () => { 56 if (!currentUser) onAuthRequested(); 57 else onNavigate("algorithm-editor", "new"); 58 }, 59 className: "px-6 py-2.5 bg-indigo-600 hover:bg-indigo-700 text-white rounded-xl font-bold shadow-lg shadow-indigo-600/20 flex items-center gap-2 transition-all cursor-pointer", 60 children: [
61 /* @__PURE__ */ jsxRuntimeExports.jsx(GitBranch, { size: 18 }), 62 "Branch New Logic" 63 ] 64 } 65 ) 66 ] }), 67 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-900 border border-zinc-800 rounded-2xl p-6 mb-10 relative overflow-hidden shadow-xl", children: [ 68 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-0 right-0 p-4 opacity-10 pointer-events-none text-white", children: /* @__PURE__ */ jsxRuntimeExports.jsx(GitMerge, { size: 120 }) }), 69 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative z-10 flex items-start justify-between gap-4 flex-wrap", children: [ 70 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-4", children: [ 71 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-12 h-12 rounded-full bg-green-500/20 text-green-400 flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 24 }) }), 72 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
73 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [ 74 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xl font-bold text-white", children: "Active Standard (Main Branch)" }), 75 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-wider bg-green-500/20 text-green-400 border border-green-500/30", children: "Active Standard" }) 76 ] }), 77 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-400 text-sm font-semibold mb-2", children: mainBranch ? `${mainBranch.name} (v${mainBranch.version})` : "Baseline V1.00" }), 78 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-zinc-500 max-w-2xl leading-relaxed", children: (mainBranch == null ? void 0 : mainBranch.description) || "The default community-approved engraving logic used to render sheet music for all un-quantized MIDI uploads." }) 79 ] }) 80 ] }), 81 mainBranch && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 mt-2 sm:mt-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs( 82 "button", 83 { 84 type: "button", 85 onClick: () => onNavigate("algorithm-editor", mainBranch.id), 86 className: "px-4 py-2 bg-zinc-800 hover:bg-zinc-700 text-zinc-200 rounded-xl text-xs font-bold flex items-center gap-1.5 transition-colors cursor-pointer", 87 children: [
88 /* @__PURE__ */ jsxRuntimeExports.jsx(CodeXml, { size: 14 }), 89 " View Code" 90 ] 91 } 92 ) }) 93 ] }) 94 ] }), 95 /* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "text-xl font-bold mb-6 flex items-center gap-2 text-zinc-900 dark:text-zinc-100", children: [ 96 /* @__PURE__ */ jsxRuntimeExports.jsx(GitCommitHorizontal, { className: "text-zinc-400" }), 97 " Evolution Pipeline" 98 ] }), 99 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-6", children: [ 100 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-zinc-200 dark:border-zinc-800 rounded-xl bg-white dark:bg-black p-5 flex flex-col shadow-sm", children: [ 101 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-4 border-b border-zinc-100 dark:border-zinc-800 pb-3", children: [ 102 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-orange-500 font-bold text-sm", children: [
103 /* @__PURE__ */ jsxRuntimeExports.jsx(CodeXml, { size: 18 }), 104 " Phase 1: Proposals" 105 ] }), 106 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] font-mono text-zinc-400 font-semibold uppercase", children: [ 107 phase1Algos.length, 108 " active" 109 ] }) 110 ] }), 111 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ 112 phase1Algos.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-400 text-xs italic py-8 text-center", children: "No active proposals in Phase 1." }) : null, 113 phase1Algos.map((algo) => { 114 var _a; 115 const net = (algo.phase1Upvotes || 0) - (algo.phase1Downvotes || 0); 116 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-50 dark:bg-zinc-900/50 p-4 rounded-xl mb-3 border border-zinc-200/50 dark:border-zinc-800/50", children: [ 117 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-bold text-sm mb-1 text-zinc-900 dark:text-zinc-100", children: algo.name }),
118 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-zinc-500 mb-2 line-clamp-2", children: algo.description }), 119 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-[10px] font-mono text-zinc-400 mb-3 flex items-center justify-between", children: [ 120 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 121 "Author: ", 122 ((_a = algo.author) == null ? void 0 : _a.username) || "Community" 123 ] }), 124 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-semibold text-orange-500", children: [ 125 net, 126 " / 3 votes to advance" 127 ] }) 128 ] }), 129 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs pt-2 border-t border-zinc-100 dark:border-zinc-800", children: [ 130 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1.5", children: [
131 /* @__PURE__ */ jsxRuntimeExports.jsxs( 132 "button", 133 { 134 type: "button", 135 onClick: () => handleVote(algo.id, 1), 136 className: "px-2.5 py-1 rounded-lg bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400 hover:bg-green-200 dark:hover:bg-green-900/50 flex items-center gap-1 font-bold cursor-pointer transition-colors", 137 title: "Upvote", 138 children: [ 139 /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 13 }), 140 " ", 141 algo.phase1Upvotes || 0 142 ] 143 } 144 ), 145 /* @__PURE__ */ jsxRuntimeExports.jsxs( 146 "button", 147 { 148 type: "button", 149 onClick: () => handleVote(algo.id, -1), 150 className: "px-2.5 py-1 rounded-lg bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400 hover:bg-red-200 dark:hover:bg-red-900/50 flex items-center gap-1 font-bold cursor-pointer transition-colors", 151 title: "Downvote", 152 children: [
153 /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 13 }), 154 " ", 155 algo.phase1Downvotes || 0 156 ] 157 } 158 ) 159 ] }), 160 /* @__PURE__ */ jsxRuntimeExports.jsx( 161 "button", 162 { 163 type: "button", 164 onClick: () => onNavigate("algorithm-editor", algo.id), 165 className: "text-indigo-600 dark:text-indigo-400 font-bold hover:underline cursor-pointer", 166 children: "View Code" 167 } 168 ) 169 ] }) 170 ] }, algo.id); 171 }) 172 ] }) 173 ] }), 174 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-zinc-200 dark:border-zinc-800 rounded-xl bg-white dark:bg-black p-5 flex flex-col shadow-sm", children: [ 175 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-4 border-b border-zinc-100 dark:border-zinc-800 pb-3", children: [
176 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-blue-500 font-bold text-sm", children: [ 177 /* @__PURE__ */ jsxRuntimeExports.jsx(Play, { size: 18 }), 178 " Phase 2: Testing Arena" 179 ] }), 180 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] font-mono text-zinc-400 font-semibold uppercase", children: [ 181 phase2Algos.length, 182 " testing" 183 ] }) 184 ] }), 185 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ 186 phase2Algos.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-400 text-xs italic py-8 text-center", children: "No algorithms currently in Phase 2 testing." }) : null, 187 phase2Algos.map((algo) => { 188 var _a; 189 const net = (algo.phase2Upvotes || 0) - (algo.phase2Downvotes || 0); 190 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-50 dark:bg-zinc-900/50 p-4 rounded-xl mb-3 border border-blue-500/30", children: [
191 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-bold text-sm mb-1 text-zinc-900 dark:text-zinc-100", children: algo.name }), 192 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-zinc-500 mb-2 line-clamp-2", children: algo.description }), 193 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-[10px] font-mono text-zinc-400 mb-3 flex items-center justify-between", children: [ 194 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 195 "Author: ", 196 ((_a = algo.author) == null ? void 0 : _a.username) || "Community" 197 ] }), 198 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-semibold text-blue-500", children: [ 199 net, 200 " / 3 votes for Main" 201 ] }) 202 ] }), 203 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs pt-2 border-t border-zinc-100 dark:border-zinc-800", children: [
204 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1.5", children: [ 205 /* @__PURE__ */ jsxRuntimeExports.jsxs( 206 "button", 207 { 208 type: "button", 209 onClick: () => handleVote(algo.id, 1), 210 className: "px-2.5 py-1 rounded-lg bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400 hover:bg-green-200 dark:hover:bg-green-900/50 flex items-center gap-1 font-bold cursor-pointer transition-colors", 211 children: [ 212 /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 13 }), 213 " ", 214 algo.phase2Upvotes || 0 215 ] 216 } 217 ), 218 /* @__PURE__ */ jsxRuntimeExports.jsxs( 219 "button", 220 { 221 type: "button", 222 onClick: () => handleVote(algo.id, -1), 223 className: "px-2.5 py-1 rounded-lg bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400 hover:bg-red-200 dark:hover:bg-red-900/50 flex items-center gap-1 font-bold cursor-pointer transition-colors", 224 children: [
225 /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 13 }), 226 " ", 227 algo.phase2Downvotes || 0 228 ] 229 } 230 ) 231 ] }), 232 /* @__PURE__ */ jsxRuntimeExports.jsxs( 233 "button", 234 { 235 type: "button", 236 onClick: () => onNavigate("algorithm-arena", algo.id), 237 className: "text-blue-600 dark:text-blue-400 font-bold hover:underline flex items-center gap-1 cursor-pointer", 238 children: [ 239 "Enter Arena ", 240 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { size: 13 }) 241 ] 242 } 243 ) 244 ] }) 245 ] }, algo.id); 246 }) 247 ] }) 248 ] }), 249 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-zinc-200 dark:border-zinc-800 rounded-xl bg-white dark:bg-black p-5 flex flex-col shadow-sm", children: [
250 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-4 border-b border-zinc-100 dark:border-zinc-800 pb-3", children: [ 251 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-zinc-600 dark:text-zinc-400 font-bold text-sm", children: [ 252 /* @__PURE__ */ jsxRuntimeExports.jsx(Users, { size: 18 }), 253 " Community Drafts" 254 ] }), 255 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] font-mono text-zinc-400 font-semibold uppercase", children: [ 256 drafts.length, 257 " drafts" 258 ] }) 259 ] }), 260 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ 261 drafts.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-400 text-xs italic py-8 text-center", children: "No active drafts found." }) : null, 262 drafts.map((algo) => { 263 var _a; 264 const isMine = currentUser && String(algo.authorId) === String(currentUser.id); 265 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-50 dark:bg-zinc-900/50 p-3 rounded-xl mb-2 flex justify-between items-center border border-zinc-200 dark:border-zinc-800", children: [
266 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1 pr-2", children: [ 267 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [ 268 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-bold text-xs truncate text-zinc-900 dark:text-zinc-100", children: algo.name }), 269 isMine && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-1.5 py-0.2 rounded text-[9px] font-bold bg-indigo-500/10 text-indigo-500 border border-indigo-500/30", children: "Yours" }) 270 ] }), 271 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[10px] text-zinc-500", children: [ 272 "By ", 273 ((_a = algo.author) == null ? void 0 : _a.username) || "Anonymous" 274 ] }) 275 ] }), 276 /* @__PURE__ */ jsxRuntimeExports.jsx( 277 "button", 278 { 279 type: "button", 280 onClick: () => onNavigate("algorithm-editor", algo.id), 281 className: "text-xs px-3 py-1 bg-zinc-200 dark:bg-zinc-800 hover:bg-zinc-300 dark:hover:bg-zinc-700 rounded-lg font-semibold transition-colors shrink-0 cursor-pointer", 282 children: isMine ? "Edit" : "View" 283 } 284 ) 285 ] }, algo.id); 286 }) 287 ] }) 288 ] }) 289 ] }) 290 ] }); 291} 292export { 293 AlgorithmStudio as default 294};
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.