From 7498ad55fc7fa7f834560d5677be62434f7dfa22 Mon Sep 17 00:00:00 2001 From: Shawn Date: Fri, 12 Jun 2026 17:09:49 -0400 Subject: [PATCH] fix: real VU meter levels from pipeline instead of random animation - Added input_level and output_level to /api/state (scaled 0-100) - React RigScreen now reads real levels from state instead of random walk - When no audio flows, VU meters show flat (0) instead of fake animation --- frontend-react/src/App.jsx | 20 ++++++------------- src/web/server.py | 5 +++++ .../{index-3XaYhUGn.js => index-By7LnVlV.js} | 2 +- src/web/ui-dist/index.html | 2 +- 4 files changed, 13 insertions(+), 16 deletions(-) rename src/web/ui-dist/assets/{index-3XaYhUGn.js => index-By7LnVlV.js} (85%) diff --git a/frontend-react/src/App.jsx b/frontend-react/src/App.jsx index 03b05cf..2df707c 100644 --- a/frontend-react/src/App.jsx +++ b/frontend-react/src/App.jsx @@ -460,23 +460,11 @@ function SlidePanel({ children, onClose }) { // 1. RIG SCREEN ──────────────────────────────────────────────── function RigScreen({ state, connected }) { const [volume, setVolume] = useState(state?.master_volume != null ? Math.round(state.master_volume * 100) : 80); - const [vuL, setVuL] = useState(45); - const [vuR, setVuR] = useState(42); - const [saving, setSaving] = useState(false); useEffect(() => { if (state?.master_volume != null) setVolume(Math.round(state.master_volume * 100)); }, [state?.master_volume]); - // Animated VU - useEffect(() => { - const id = setInterval(() => { - setVuL(prev => Math.max(10, Math.min(95, prev + (Math.random() - 0.48) * 12))); - setVuR(prev => Math.max(10, Math.min(95, prev + (Math.random() - 0.48) * 12))); - }, 90); - return () => clearInterval(id); - }, []); - const handleVolume = async (val) => { setVolume(val); try { @@ -497,6 +485,10 @@ function RigScreen({ state, connected }) { } catch (e) { /* ignore */ } }; + // Real audio levels from the pipeline (0-100 scale, updated every poll cycle) + const inputLevel = state?.input_level ?? 0; + const outputLevel = state?.output_level ?? 0; + return (
@@ -518,8 +510,8 @@ function RigScreen({ state, connected }) {
- - + +
diff --git a/src/web/server.py b/src/web/server.py index c53c7c7..d3dae2d 100644 --- a/src/web/server.py +++ b/src/web/server.py @@ -1023,6 +1023,8 @@ class WebServer: "nam_model": None, "ir_loaded": False, "ir_name": None, + "input_level": 0, + "output_level": 0, "wifi": {}, "bluetooth": {}, } @@ -1065,6 +1067,9 @@ class WebServer: "nam_model": current_model_name, "ir_loaded": bool(ir and ir.is_loaded) if ir else False, "ir_name": current_ir_name, + # Audio levels from pipeline (RMS float32 normalized 0.0-1.0, scaled to 0-100) + "input_level": min(100, round((pl._input_level or 0.0) * 150)) if pl else 0, + "output_level": min(100, round((pl._output_level or 0.0) * 150)) if pl else 0, "wifi": self._gather_wifi_state(), "bluetooth": self._gather_bt_state(), } diff --git a/src/web/ui-dist/assets/index-3XaYhUGn.js b/src/web/ui-dist/assets/index-By7LnVlV.js similarity index 85% rename from src/web/ui-dist/assets/index-3XaYhUGn.js rename to src/web/ui-dist/assets/index-By7LnVlV.js index 5f5db71..be7ecc9 100644 --- a/src/web/ui-dist/assets/index-3XaYhUGn.js +++ b/src/web/ui-dist/assets/index-By7LnVlV.js @@ -149,4 +149,4 @@ Error generating stack: `+e.message+` border-radius: 16px 16px 0 0; overflow: hidden; display: flex; flex-direction: column; } .slide-panel-handle { width: 36px; height: 4px; border-radius: 2px; background: ${p.border}; margin: 8px auto; flex-shrink: 0; } -`;function C({label:e,value:t=50,onChange:n,size:r=52,color:i=p.amber,min:a=0,max:o=100}){let s=(0,l.useRef)(null),c=(0,l.useRef)(null),u=(t-a)/(o-a),d=-140+u*280,m=e=>{e.preventDefault(),c.current={y:e.touches?e.touches[0].clientY:e.clientY,val:t};let r=e=>{let t=e.touches?e.touches[0].clientY:e.clientY,r=(c.current.y-t)/120,i=Math.max(a,Math.min(o,c.current.val+r*(o-a)));n?.(Math.round(i))},i=()=>{window.removeEventListener(`mousemove`,r),window.removeEventListener(`mouseup`,i),window.removeEventListener(`touchmove`,r),window.removeEventListener(`touchend`,i)};window.addEventListener(`mousemove`,r),window.addEventListener(`mouseup`,i),window.addEventListener(`touchmove`,r,{passive:!1}),window.addEventListener(`touchend`,i)},h=r+12,g=h/2,_=h/2,v=r/2+3,y=(d-90)*(Math.PI/180),b=g+v*Math.cos(y),x=_+v*Math.sin(y);return(0,f.jsxs)(`div`,{className:`knob-wrap`,style:{width:r+12},children:[(0,f.jsxs)(`div`,{className:`knob`,style:{width:r,height:r},onMouseDown:m,onTouchStart:m,ref:s,children:[(0,f.jsxs)(`svg`,{style:{position:`absolute`,inset:-6,width:h,height:h,overflow:`visible`},children:[(0,f.jsx)(`circle`,{cx:g,cy:_,r:v,fill:`none`,stroke:p.border,strokeWidth:`2.5`,strokeLinecap:`round`,opacity:`.5`}),u>0&&(0,f.jsx)(`path`,{d:`M ${g} ${_-v} A ${v} ${v} 0 ${+(u>.5)} 1 ${b} ${x}`,fill:`none`,stroke:i,strokeWidth:`2.5`,strokeLinecap:`round`,style:{filter:`drop-shadow(0 0 3px ${i})`}})]}),(0,f.jsx)(`div`,{className:`knob-inner`,style:{"--amber":i},children:(0,f.jsx)(`div`,{className:`knob-dot`,style:{height:r*.38,bottom:r/2-2,transform:`translateX(-50%) rotate(${d}deg)`,transformOrigin:`50% ${r*.38}px`}})})]}),(0,f.jsx)(`div`,{className:`knob-value mono`,style:{color:i},children:t}),(0,f.jsx)(`div`,{className:`knob-label`,children:e})]})}function w({level:e=0,height:t=60,vertical:n=!0}){let r=Math.round(e/100*12),i=e=>e>=10?p.red:e>=8?`#E8C030`:p.green;return n?(0,f.jsx)(`div`,{style:{display:`flex`,flexDirection:`column-reverse`,gap:2,height:t,alignItems:`center`},children:Array.from({length:12}).map((e,n)=>(0,f.jsx)(`div`,{style:{width:6,height:(t-24)/12,borderRadius:1,background:n(0,f.jsx)(`div`,{style:{flex:1,height:`100%`,borderRadius:1,background:t{let r=a.current;if(!r)return;let o=r.getContext(`2d`);o.clearRect(0,0,e,t);let s=t/2;o.strokeStyle=n,o.lineWidth=1,o.shadowColor=n,o.shadowBlur=2,o.beginPath();for(let t=0;te.default??e.default??50));return(0,f.jsxs)(`div`,{className:`fx-block ${n?`active`:``} ${r?`bypassed`:``}`,children:[(0,f.jsxs)(`div`,{className:`fx-header`,onClick:()=>s(e=>!e),children:[(0,f.jsx)(`div`,{className:`bypass-led ${r?`led-off`:`led-on`}`,onClick:e=>{e.stopPropagation(),a?.()}}),(0,f.jsx)(`span`,{style:{flex:1,fontSize:13,fontWeight:600},children:e}),(0,f.jsx)(`span`,{className:`badge badge-blue`,style:{fontSize:10},children:t}),(0,f.jsx)(`span`,{style:{color:p.textDim,fontSize:18,marginLeft:6},children:o?`▾`:`▸`})]}),o&&(0,f.jsx)(`div`,{className:`fx-body`,children:i.map((e,t)=>(0,f.jsx)(C,{label:e.name,value:c[t],size:44,onChange:e=>u(n=>n.map((n,r)=>r===t?e:n)),min:e.min??0,max:e.max??100},e.key||e.name))})]})}function te({children:e,onClose:t}){return(0,f.jsx)(`div`,{className:`slide-panel`,onClick:t,children:(0,f.jsxs)(`div`,{className:`slide-panel-inner`,onClick:e=>e.stopPropagation(),children:[(0,f.jsx)(`div`,{className:`slide-panel-handle`}),e]})})}function E({state:e,connected:t}){let[n,r]=(0,l.useState)(e?.master_volume==null?80:Math.round(e.master_volume*100)),[i,a]=(0,l.useState)(45),[o,s]=(0,l.useState)(42),[c,u]=(0,l.useState)(!1);(0,l.useEffect)(()=>{e?.master_volume!=null&&r(Math.round(e.master_volume*100))},[e?.master_volume]),(0,l.useEffect)(()=>{let e=setInterval(()=>{a(e=>Math.max(10,Math.min(95,e+(Math.random()-.48)*12))),s(e=>Math.max(10,Math.min(95,e+(Math.random()-.48)*12)))},90);return()=>clearInterval(e)},[]);let d=async e=>{r(e);try{await v(`/api/volume`,{volume:e/100})}catch{}};return(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`screen-title`,children:`Active Rig`}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6,marginTop:4,flexWrap:`wrap`,alignItems:`center`},children:[e?.current_preset?(0,f.jsx)(`span`,{className:`nam-chip`,style:{color:p.amber,borderColor:`${p.amber}55`,background:`${p.amber}15`},children:e.current_preset.name}):(0,f.jsx)(`span`,{style:{fontSize:11,color:p.textDim},children:`No preset loaded`}),t?(0,f.jsx)(`span`,{className:`badge badge-green`,children:`Connected`}):(0,f.jsx)(`span`,{className:`badge badge-red`,children:`Offline`})]})]}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`},children:[(0,f.jsx)(w,{level:i,height:44}),(0,f.jsx)(w,{level:o,height:44})]})]}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[(0,f.jsxs)(`div`,{className:`card-sm`,style:{display:`flex`,gap:10,justifyContent:`space-around`},children:[(0,f.jsxs)(`div`,{style:{textAlign:`center`},children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:4},children:`Bypass`}),(0,f.jsx)(`div`,{className:`switch ${e?.bypass?`on`:``}`,onClick:async()=>{try{await _(`/api/bypass`)}catch{}},style:{margin:`0 auto`}})]}),(0,f.jsxs)(`div`,{style:{textAlign:`center`},children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:4},children:`Tuner`}),(0,f.jsx)(`div`,{className:`switch ${e?.tuner_enabled?`on`:``}`,onClick:async()=>{try{let t=e?.tuner_enabled;await _(`/api/tuner`,{enabled:!t})}catch{}},style:{margin:`0 auto`}})]}),(0,f.jsxs)(`div`,{style:{textAlign:`center`},children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:4},children:`Routing`}),(0,f.jsx)(`span`,{className:`mono`,style:{fontSize:12,color:p.amber},children:e?.routing_mode||`mono`})]})]}),(0,f.jsxs)(`div`,{className:`card`,style:{display:`flex`,gap:20,alignItems:`center`},children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{className:`section-label`,children:`Master Volume`}),(0,f.jsx)(`input`,{type:`range`,min:0,max:100,value:n,onChange:e=>d(+e.target.value),style:{width:`100%`,accentColor:p.amber}}),(0,f.jsxs)(`div`,{className:`mono`,style:{fontSize:11,color:p.amber,marginTop:4},children:[n,`%`]})]}),(0,f.jsxs)(`div`,{className:`mono`,style:{fontSize:11,color:p.textSec,textAlign:`right`},children:[e?.nam_loaded?`NAM: Active`:`NAM: —`,(0,f.jsx)(`br`,{}),e?.ir_loaded?`IR: Active`:`IR: —`]})]}),(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsx)(`div`,{className:`section-label`,children:`Signal Chain`}),(0,f.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,overflowX:`auto`,padding:`4px 0`},children:[`IN`,e?.bypass?`BYP`:e?.nam_loaded?`NAM`:`AMP`,e?.ir_loaded?`IR`:`CAB`,`OUT`].map((e,t,n)=>(0,f.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,flexShrink:0},children:[(0,f.jsx)(`div`,{style:{padding:`3px 8px`,borderRadius:4,fontSize:10,fontWeight:700,background:t===0||t===n.length-1?p.blueDim:p.amberDim,color:t===0||t===n.length-1?p.blue:p.amber,border:`1px solid ${t===0||t===n.length-1?p.blue:p.amber}60`},children:e}),t{if(!t||!e?.current_preset){r([{id:1,title:`Overdrive`,type:`OD`,bypassed:!1,params:[{key:`drive`,name:`Drive`,default:62},{key:`tone`,name:`Tone`,default:55}]},{id:2,title:`Compressor`,type:`COMP`,bypassed:!1,params:[{key:`thresh`,name:`Thresh`,default:40},{key:`ratio`,name:`Ratio`,default:40}]},{id:3,title:`NAM Amp`,type:`AMP`,bypassed:!1,params:[]},{id:4,title:`Delay`,type:`DELAY`,bypassed:!0,params:[{key:`time`,name:`Time`,default:45},{key:`feedback`,name:`Fdbk`,default:38}]}]),a(!1);return}g(`/api/presets`).then(e=>{let t=e.banks||[];if(t.length>0&&t[0].presets){let e=t[0].presets.find(e=>e!=null);e?.chain&&r(e.chain.map((e,t)=>({id:t+1,title:e.fx_type.replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase()),type:e.fx_type.toUpperCase(),bypassed:e.bypass||!e.enabled,params:[]})))}a(!1)}).catch(()=>{a(!1)})},[t,e]);let o=e=>r(t=>t&&t.map(t=>t.id===e?{...t,bypassed:!t.bypassed}:t));return i?(0,f.jsx)(`div`,{style:{flex:1,display:`flex`,alignItems:`center`,justifyContent:`center`},children:(0,f.jsx)(`div`,{className:`loader`})}):(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsx)(`div`,{className:`screen-title`,children:`FX Chain`}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,children:`+ Add Block`})]}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[(0,f.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,padding:`4px 2px`,overflowX:`auto`},children:[`IN`,...(n||[]).map(e=>e.type),`OUT`].map((e,t,n)=>(0,f.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,flexShrink:0},children:[(0,f.jsx)(`div`,{style:{padding:`3px 8px`,borderRadius:4,fontSize:10,fontWeight:700,background:e===`IN`||e===`OUT`?p.blueDim:p.amberDim,color:e===`IN`||e===`OUT`?p.blue:p.amber,border:`1px solid ${e===`IN`||e===`OUT`?p.blue:p.amber}60`},children:e}),t(0,f.jsx)(T,{...e,active:!e.bypassed,onToggle:()=>o(e.id)},e.id))]})]})}function re({state:e,connected:t,refresh:n}){let[r,i]=(0,l.useState)([]),[a,o]=(0,l.useState)(null),[s,c]=(0,l.useState)(!0),[u,d]=(0,l.useState)(!1),[m,h]=(0,l.useState)(``),[v,y]=(0,l.useState)([]),[x,S]=(0,l.useState)(!1),[C,w]=(0,l.useState)(!1),ee=(0,l.useRef)(null),T=(0,l.useCallback)(async()=>{if(!t){c(!1);return}try{let e=await g(`/api/models`);i(e.models||[]),o(e.current)}catch{}c(!1)},[t]);(0,l.useEffect)(()=>{T()},[T]);let te=async e=>{try{await _(`/api/models/load`,{path:e}),await T(),n()}catch{alert(`Failed to load model`)}},E=async()=>{try{await _(`/api/models/unload`),o(null),await T(),n()}catch{alert(`Failed to unload`)}},ne=async e=>{let t=e.target.files?.[0];if(t){w(!0);try{await b(`/api/models/upload`,t),await T()}catch{alert(`Upload failed`)}w(!1)}},re=(0,l.useCallback)(async()=>{if(m.trim()){d(!0);try{y((await g(`/api/models/tonedownload/search?q=${encodeURIComponent(m)}`)).results||[])}catch{alert(`Search failed`)}d(!1)}},[m]),ie=async e=>{try{await _(`/api/models/tonedownload/install`,{download_url:e.download_url,name:e.name||e.filename,id:e.id,size:e.size,pack_name:e.pack_name,display_name:e.name}),await T(),n()}catch{alert(`Install failed`)}};return s?(0,f.jsx)(`div`,{style:{flex:1,display:`flex`,alignItems:`center`,justifyContent:`center`},children:(0,f.jsx)(`div`,{className:`loader`})}):(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsxs)(`div`,{className:`screen-title`,children:[`NAM Models (`,r.length,`)`]}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6},children:[(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>S(!x),children:x?`Local`:`Search`}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,onClick:()=>ee.current?.click(),children:C?`...`:`+ Upload`}),(0,f.jsx)(`input`,{ref:ee,type:`file`,accept:`.nam`,style:{display:`none`},onChange:ne})]})]}),x&&(0,f.jsxs)(`div`,{style:{padding:`8px 12px`,borderBottom:`1px solid ${p.border}`},children:[(0,f.jsxs)(`div`,{className:`search-bar`,children:[(0,f.jsx)(`span`,{style:{color:p.textDim},children:`🔍`}),(0,f.jsx)(`input`,{type:`text`,placeholder:`Search Tone3000…`,value:m,onChange:e=>h(e.target.value),onKeyDown:e=>e.key===`Enter`&&re()}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,onClick:re,disabled:u,children:u?`...`:`Go`})]}),v.length>0&&(0,f.jsx)(`div`,{style:{marginTop:8,maxHeight:240,overflow:`auto`},children:v.map(e=>(0,f.jsxs)(`div`,{className:`preset-row`,onClick:()=>ie(e),style:{borderBottom:`1px solid ${p.border}`,borderRadius:0},children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13},children:e.name}),(0,f.jsxs)(`div`,{style:{fontSize:10,color:p.textDim},children:[e.author,` · `,e.size_display,` · `,e.architecture]})]}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,children:`Get`})]},e.id))})]}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[a&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:6},children:`Loaded Model`}),(0,f.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,f.jsx)(`div`,{className:`nam-chip`,children:a}),(0,f.jsx)(`button`,{className:`btn btn-danger btn-sm`,onClick:E,children:`Unload`})]})]}),r.length===0?(0,f.jsxs)(`div`,{style:{textAlign:`center`,padding:30,color:p.textDim,fontSize:14},children:[`No NAM models found.`,(0,f.jsx)(`br`,{}),`Upload a .nam file or search Tone3000.`]}):r.map(e=>(0,f.jsxs)(`div`,{className:`preset-row ${e.loaded?`active`:``}`,children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13,fontWeight:500},children:e.name}),(0,f.jsxs)(`div`,{style:{fontSize:10,color:p.textDim},children:[e.architecture,` · `,e.size_mb,` MB`]})]}),e.loaded?(0,f.jsx)(`span`,{className:`badge badge-green`,children:`Loaded`}):(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>te(e.path),children:`Load`})]},e.name))]})]})}function ie({state:e,connected:t,refresh:n}){let[r,i]=(0,l.useState)([]),[a,o]=(0,l.useState)(null),[s,c]=(0,l.useState)(!0),[u,d]=(0,l.useState)(!1),[m,h]=(0,l.useState)(``),[v,y]=(0,l.useState)([]),[x,S]=(0,l.useState)(!1),[C,w]=(0,l.useState)(!1),ee=(0,l.useRef)(null),T=(0,l.useCallback)(async()=>{if(!t){c(!1);return}try{let e=await g(`/api/irs`);i(e.irs||[]),o(e.current)}catch{}c(!1)},[t]);(0,l.useEffect)(()=>{T()},[T]);let te=async e=>{try{await _(`/api/irs/load`,{path:e}),await T(),n()}catch{alert(`Failed to load IR`)}},E=async()=>{try{await _(`/api/irs/unload`),o(null),await T(),n()}catch{alert(`Failed to unload`)}},ne=async e=>{let t=e.target.files?.[0];if(t){w(!0);try{await b(`/api/irs/upload`,t),await T()}catch{alert(`Upload failed`)}w(!1)}},re=(0,l.useCallback)(async()=>{if(m.trim()){d(!0);try{y((await g(`/api/irs/tonedownload/search?q=${encodeURIComponent(m)}`)).results||[])}catch{alert(`Search failed`)}d(!1)}},[m]),ie=async e=>{try{await _(`/api/irs/tonedownload/install`,{download_url:e.download_url,name:e.name||e.filename,id:e.id,size:e.size,display_name:e.name}),await T(),n()}catch{alert(`Install failed`)}};return s?(0,f.jsx)(`div`,{style:{flex:1,display:`flex`,alignItems:`center`,justifyContent:`center`},children:(0,f.jsx)(`div`,{className:`loader`})}):(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsxs)(`div`,{className:`screen-title`,children:[`IR Files (`,r.length,`)`]}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6},children:[(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>S(!x),children:x?`Local`:`Search`}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,onClick:()=>ee.current?.click(),children:C?`...`:`+ Upload`}),(0,f.jsx)(`input`,{ref:ee,type:`file`,accept:`.wav`,style:{display:`none`},onChange:ne})]})]}),x&&(0,f.jsxs)(`div`,{style:{padding:`8px 12px`,borderBottom:`1px solid ${p.border}`},children:[(0,f.jsxs)(`div`,{className:`search-bar`,children:[(0,f.jsx)(`span`,{style:{color:p.textDim},children:`🔍`}),(0,f.jsx)(`input`,{type:`text`,placeholder:`Search Tone3000 IRs…`,value:m,onChange:e=>h(e.target.value),onKeyDown:e=>e.key===`Enter`&&re()}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,onClick:re,disabled:u,children:u?`...`:`Go`})]}),v.length>0&&(0,f.jsx)(`div`,{style:{marginTop:8,maxHeight:240,overflow:`auto`},children:v.map(e=>(0,f.jsxs)(`div`,{className:`preset-row`,onClick:()=>ie(e),style:{borderBottom:`1px solid ${p.border}`,borderRadius:0},children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13},children:e.name}),(0,f.jsxs)(`div`,{style:{fontSize:10,color:p.textDim},children:[e.author,` · `,e.size_display]})]}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,children:`Get`})]},e.id))})]}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[a&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:6},children:`Loaded IR`}),(0,f.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,f.jsx)(`div`,{className:`nam-chip`,style:{color:p.green,borderColor:`${p.green}55`,background:`${p.green}15`},children:a}),(0,f.jsx)(`button`,{className:`btn btn-danger btn-sm`,onClick:E,children:`Unload`})]})]}),r.length===0?(0,f.jsxs)(`div`,{style:{textAlign:`center`,padding:30,color:p.textDim,fontSize:14},children:[`No IR files found.`,(0,f.jsx)(`br`,{}),`Upload a .wav file or search Tone3000.`]}):r.map(e=>(0,f.jsxs)(`div`,{className:`preset-row ${e.loaded?`active`:``}`,children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13,fontWeight:500},children:e.name}),(0,f.jsxs)(`div`,{style:{fontSize:10,color:p.textDim},children:[e.sample_rate,` Hz · `,e.length_ms,` ms · `,e.num_taps,` taps`]})]}),e.loaded?(0,f.jsx)(`span`,{className:`badge badge-green`,children:`Loaded`}):(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>te(e.path),children:`Load`})]},e.name))]})]})}function ae({state:e,connected:t,refresh:n}){let[r,i]=(0,l.useState)([]),[a,o]=(0,l.useState)(0),[s,c]=(0,l.useState)(!0),[u,d]=(0,l.useState)(``),[m,h]=(0,l.useState)(!1),[b,x]=(0,l.useState)(null),S=(0,l.useCallback)(async()=>{if(!t){i([{name:`Default`,number:0,presets:[{name:`Edge of Breakup`,bank:0,program:0},{name:`Modern High Gain`,bank:0,program:1},null,null]}]),c(!1);return}try{i((await g(`/api/presets`)).banks||[])}catch{}c(!1)},[t]);(0,l.useEffect)(()=>{S()},[S]);let C=async(e,t)=>{try{await _(`/api/presets/${e}/${t}/activate`),await S(),n()}catch{alert(`Failed to load preset`)}},w=async()=>{if(!u.trim())return;let t=e?.current_preset?.bank??0,n=e?.current_preset?.program??0;try{await v(`/api/presets/${t}/${n}`,{name:u}),h(!1),await S()}catch{alert(`Failed to save`)}},ee=async(e,t)=>{try{await y(`/api/presets/${e}/${t}`),x(null),await S()}catch{alert(`Failed to delete`)}};if(s)return(0,f.jsx)(`div`,{style:{flex:1,display:`flex`,alignItems:`center`,justifyContent:`center`},children:(0,f.jsx)(`div`,{className:`loader`})});let T=e?.current_preset,E=r[a]?.presets||[];return(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsx)(`div`,{className:`screen-title`,children:`Presets`}),(0,f.jsx)(`div`,{style:{display:`flex`,gap:6},children:(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>h(!0),children:`Save`})})]}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[r.length>1&&(0,f.jsx)(`div`,{className:`toggle`,children:r.map((e,t)=>(0,f.jsx)(`button`,{className:`toggle-btn ${a===t?`active`:``}`,onClick:()=>o(t),children:e.name},e.number))}),T&&(0,f.jsx)(`div`,{className:`card-sm`,style:{display:`flex`,alignItems:`center`,gap:8},children:(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:11,color:p.textDim},children:`Current`}),(0,f.jsxs)(`div`,{style:{fontSize:14,fontWeight:600,color:p.amber},children:[T.name,(0,f.jsxs)(`span`,{className:`mono`,style:{fontSize:10,color:p.textDim,marginLeft:8},children:[`Bank `,T.bank,` · Prog `,T.program]})]})]})}),E.length===0?(0,f.jsx)(`div`,{style:{textAlign:`center`,padding:30,color:p.textDim,fontSize:14},children:`No presets in this bank.`}):E.map((e,t)=>{if(!e)return null;let n=T?.bank===e.bank&&T?.program===e.program,r=b===`${e.bank}-${e.program}`;return(0,f.jsxs)(`div`,{className:`preset-row ${n?`active`:``}`,onClick:()=>!r&&C(e.bank,e.program),children:[(0,f.jsx)(`div`,{className:`mono`,style:{width:28,height:28,borderRadius:6,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:12,fontWeight:700,background:n?`${p.amber}22`:p.surface,color:n?p.amber:p.textDim,border:`1px solid ${n?p.amber+`60`:p.border}`},children:e.program+1}),(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13,fontWeight:600},children:e.name}),(0,f.jsxs)(`div`,{style:{fontSize:10,color:p.textDim},children:[`Bank `,e.bank,` · Program `,e.program]})]}),n&&(0,f.jsx)(`span`,{style:{color:p.amber,fontSize:16},children:`●`}),r?(0,f.jsxs)(`div`,{style:{display:`flex`,gap:4},children:[(0,f.jsx)(`button`,{className:`btn btn-danger btn-sm`,onClick:t=>{t.stopPropagation(),ee(e.bank,e.program)},children:`Confirm`}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:e=>{e.stopPropagation(),x(null)},children:`Cancel`})]}):(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,style:{color:p.red},onClick:t=>{t.stopPropagation(),x(`${e.bank}-${e.program}`)},children:`Delete`})]},t)})]}),m&&(0,f.jsxs)(te,{onClose:()=>h(!1),children:[(0,f.jsx)(`div`,{className:`screen-header`,children:(0,f.jsx)(`div`,{className:`screen-title`,children:`Save Preset`})}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[(0,f.jsx)(`div`,{className:`search-bar`,children:(0,f.jsx)(`input`,{type:`text`,placeholder:`Preset name…`,value:u,onChange:e=>d(e.target.value),autoFocus:!0,onKeyDown:e=>e.key===`Enter`&&w()})}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,f.jsx)(`button`,{className:`btn btn-primary`,style:{flex:1},onClick:w,children:`Save`}),(0,f.jsx)(`button`,{className:`btn btn-ghost`,onClick:()=>h(!1),children:`Cancel`})]})]})]})]})}function oe({state:e,connected:t,refresh:n}){let[r,i]=(0,l.useState)(`wifi`),[a,o]=(0,l.useState)([]),[s,c]=(0,l.useState)([]),[u,d]=(0,l.useState)([]),[m,h]=(0,l.useState)(!1),[v,y]=(0,l.useState)(!1),[b,x]=(0,l.useState)(``),[S,C]=(0,l.useState)(``),[w,ee]=(0,l.useState)(null),[T,te]=(0,l.useState)(e?.routing_mode||`mono`),[E,ne]=(0,l.useState)(e?.routing_breakpoint||7);(0,l.useEffect)(()=>{e?.routing_mode&&te(e.routing_mode),e?.routing_breakpoint!=null&&ne(e.routing_breakpoint)},[e?.routing_mode,e?.routing_breakpoint]);let re=async()=>{h(!0);try{o((await g(`/api/wifi/scan`)).networks||[])}catch{}h(!1)},ie=async(e,t)=>{try{await _(`/api/wifi/connect`,{ssid:e,password:t}),ee(null),x(``),C(``),setTimeout(n,2e3)}catch{alert(`Failed to connect`)}},ae=async()=>{try{await _(`/api/wifi/disconnect`),setTimeout(n,2e3)}catch{}},oe=async()=>{let t=e?.wifi?.hotspot_active;try{t?await _(`/api/wifi/hotspot/disable`):await _(`/api/wifi/hotspot/enable`,{ssid:`Pi-Pedal`,password:`pedal1234`}),setTimeout(n,2e3)}catch{}},se=async e=>{try{await _(`/api/bluetooth/power`,{on:e}),setTimeout(n,1e3)}catch{}},ce=async()=>{y(!0);try{c((await _(`/api/bluetooth/scan`)).devices||[])}catch{}y(!1)},D=async()=>{try{d((await g(`/api/bluetooth/paired`)).devices||[])}catch{}},O=async e=>{try{await _(`/api/bluetooth/pair`,{address:e}),await D()}catch{alert(`Pairing failed`)}},le=async(e,t)=>{try{await _(`/api/routing`,{routing_mode:e,routing_breakpoint:t})}catch{}};(0,l.useEffect)(()=>{t&&(re(),D())},[t]);let ue=e?.wifi,de=e?.bluetooth;return(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsx)(`div`,{className:`screen-header`,children:(0,f.jsx)(`div`,{className:`screen-title`,children:`Settings`})}),(0,f.jsx)(`div`,{className:`toggle`,style:{margin:`6px 10px`},children:[{id:`wifi`,label:`WiFi`},{id:`bt`,label:`Bluetooth`},{id:`routing`,label:`Routing`}].map(e=>(0,f.jsx)(`button`,{className:`toggle-btn ${r===e.id?`active`:``}`,onClick:()=>i(e.id),children:e.label},e.id))}),(0,f.jsxs)(`div`,{className:`screen-body`,style:{gap:4},children:[r===`wifi`&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsxs)(`div`,{className:`setting-row`,style:{border:`none`,paddingTop:0},children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`WiFi`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:ue?.connected?`Connected to ${ue.ssid}`:`Disconnected`})]}),(0,f.jsx)(`div`,{className:`switch ${ue?.connected?`on`:``}`,onClick:ae})]}),ue?.connected&&(0,f.jsxs)(`div`,{style:{fontSize:11,color:p.textDim},children:[`IP: `,ue.ip,` · Signal: `,ue.signal,`%`]}),(0,f.jsxs)(`div`,{className:`setting-row`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Hotspot`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:ue?.hotspot_active?`Active: ${ue.hotspot_ssid}`:`Off`})]}),(0,f.jsx)(`div`,{className:`switch ${ue?.hotspot_active?`on`:``}`,onClick:oe})]})]}),(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,marginBottom:8},children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:0},children:`Networks`}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:re,disabled:m,children:m?`...`:`Scan`})]}),a.length===0?(0,f.jsx)(`div`,{style:{fontSize:12,color:p.textDim,padding:`8px 0`},children:`Scan to see available networks.`}):a.map(e=>(0,f.jsxs)(`div`,{className:`preset-row`,style:{padding:`8px 0`,borderRadius:0,borderBottom:`1px solid ${p.border}`},onClick:()=>wpaState?.ssid!==e.ssid&&ee(e.ssid),children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13},children:e.ssid}),(0,f.jsxs)(`div`,{className:`mono`,style:{fontSize:10,color:p.textDim},children:[`Signal: `,e.signal,`% · `,e.encryption||`Open`]})]}),ue?.ssid===e.ssid&&(0,f.jsx)(`span`,{className:`badge badge-green`,children:`Connected`})]},e.ssid))]}),w&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsxs)(`div`,{className:`section-label`,children:[`Connect to `,w]}),(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:[(0,f.jsx)(`input`,{type:`password`,placeholder:`Password (leave blank for open network)`,value:S,onChange:e=>C(e.target.value),style:{background:p.surface,border:`1px solid ${p.border}`,borderRadius:6,padding:`8px 12px`,color:p.textPrimary,fontSize:13,outline:`none`},onKeyDown:e=>e.key===`Enter`&&ie(w,S)}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6},children:[(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,style:{flex:1},onClick:()=>ie(w,S),children:`Connect`}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>ee(null),children:`Cancel`})]})]})]})]}),r===`bt`&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsxs)(`div`,{className:`setting-row`,style:{border:`none`,paddingTop:0},children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Bluetooth`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:de?.powered?`Powered on`:`Off`})]}),(0,f.jsx)(`div`,{className:`switch ${de?.powered?`on`:``}`,onClick:()=>se(!de?.powered)})]}),de?.powered&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(`div`,{className:`setting-row`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Discoverable`}),(0,f.jsxs)(`div`,{className:`setting-desc`,children:[de?.name,` (`,de?.address,`)`]})]}),(0,f.jsx)(`div`,{className:`switch ${de?.discoverable?`on`:``}`,onClick:async()=>{try{await _(`/api/bluetooth/discoverable`,{on:!de?.discoverable}),setTimeout(n,500)}catch{}}})]}),(0,f.jsxs)(`div`,{className:`setting-row`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Bluetooth MIDI`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:de?.midi_enabled?`Enabled`:`Disabled`})]}),(0,f.jsx)(`div`,{className:`switch ${de?.midi_enabled?`on`:``}`,onClick:async()=>{try{await(de?.midi_enabled?_(`/api/bluetooth/midi-disable`):_(`/api/bluetooth/midi-enable`)),setTimeout(n,500)}catch{}}})]})]})]}),de?.powered&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,marginBottom:8},children:[(0,f.jsxs)(`div`,{className:`section-label`,style:{marginBottom:0},children:[`Paired Devices (`,u.length,`)`]}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:ce,disabled:v,children:v?`...`:`Scan`})]}),u.length===0?(0,f.jsx)(`div`,{style:{fontSize:12,color:p.textDim,padding:`8px 0`},children:`No paired devices.`}):u.map(e=>(0,f.jsxs)(`div`,{className:`preset-row`,style:{padding:`8px 0`,borderRadius:0,borderBottom:`1px solid ${p.border}`},children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13},children:e.name||e.address}),(0,f.jsxs)(`div`,{className:`mono`,style:{fontSize:10,color:p.textDim},children:[e.address,` · `,e.connected?`Connected`:`Paired`]})]}),!e.connected&&(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:async()=>{try{await _(`/api/bluetooth/connect`,{address:e.address})}catch{alert(`Failed`)}},children:`Connect`})]},e.address))]}),v&&s.length>0&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:6},children:`Discovered`}),s.map(e=>(0,f.jsxs)(`div`,{className:`preset-row`,style:{padding:`8px 0`,borderRadius:0,borderBottom:`1px solid ${p.border}`},children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13},children:e.name||e.address}),(0,f.jsx)(`div`,{className:`mono`,style:{fontSize:10,color:p.textDim},children:e.address})]}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>O(e.address),children:`Pair`})]},e.address))]})]}),r===`routing`&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsx)(`div`,{className:`section-label`,children:`4CM Routing`}),(0,f.jsxs)(`div`,{className:`setting-row`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Mode`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:`Mono (normal) or 4CM (4-cable method)`})]}),(0,f.jsxs)(`select`,{value:T,onChange:e=>{te(e.target.value),le(e.target.value,E)},style:{background:p.surface,border:`1px solid ${p.border}`,borderRadius:6,padding:`6px 10px`,color:p.textPrimary,fontSize:13,outline:`none`},children:[(0,f.jsx)(`option`,{value:`mono`,children:`Mono`}),(0,f.jsx)(`option`,{value:`4cm`,children:`4CM`})]})]}),T===`4cm`&&(0,f.jsxs)(`div`,{className:`setting-row`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Breakpoint`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:`Chain position for amp send/return`})]}),(0,f.jsx)(`input`,{type:`number`,min:1,max:15,value:E,onChange:e=>{let t=+e.target.value;ne(t),le(T,t)},style:{background:p.surface,border:`1px solid ${p.border}`,borderRadius:6,padding:`6px 10px`,color:p.textPrimary,fontSize:13,width:60,outline:`none`,textAlign:`center`}})]})]})]})]})}function se(){let[e,t]=(0,l.useState)(!1),[n,r]=(0,l.useState)(!1),[i,a]=(0,l.useState)(0),[o,s]=(0,l.useState)([{name:`Guitar 1`,color:p.amber,vol:80,pan:50,mute:!1,solo:!1,level:72},{name:`Guitar 2`,color:p.blue,vol:65,pan:35,mute:!1,solo:!1,level:55},{name:`Bass DI`,color:p.green,vol:75,pan:50,mute:!0,solo:!1,level:68},{name:`Drum Loop`,color:`#A060E0`,vol:70,pan:52,mute:!1,solo:!1,level:60}]);(0,l.useEffect)(()=>{let t;return e&&(t=setInterval(()=>a(e=>e>=100?0:e+.3),80)),()=>clearInterval(t)},[e]),(0,l.useEffect)(()=>{let e=setInterval(()=>{s(e=>e.map(e=>({...e,level:e.mute?0:Math.max(10,Math.min(95,e.level+(Math.random()-.48)*12))})))},90);return()=>clearInterval(e)},[]);let c=e=>s(t=>t.map((t,n)=>n===e?{...t,mute:!t.mute}:t)),u=e=>s(t=>t.map((t,n)=>n===e?{...t,solo:!t.solo}:t)),d=(e,t)=>s(n=>n.map((n,r)=>r===e?{...n,vol:t}:n));return(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`screen-title`,children:`Multitrack`}),(0,f.jsxs)(`div`,{className:`mono`,style:{fontSize:12,color:p.textSec,marginTop:2},children:[Math.floor(i/100*32).toString().padStart(2,`0`),`:`,Math.floor(i/100*32%1*60).toString().padStart(2,`0`)]})]}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`},children:[(0,f.jsx)(`div`,{className:`transport-btn`,onClick:()=>a(0),children:`⏮`}),(0,f.jsx)(`div`,{className:`transport-btn ${n?`rec`:``}`,onClick:()=>{r(e=>!e),n||t(!0)},children:(0,f.jsx)(`div`,{style:{width:14,height:14,borderRadius:n?3:`50%`,background:n?p.red:p.textSec,boxShadow:n?`0 0 12px ${p.red}`:`none`}})}),(0,f.jsx)(`div`,{className:`transport-btn ${e?`play`:``}`,onClick:()=>t(e=>!e),children:e?`⏸`:`▶`})]})]}),(0,f.jsx)(`div`,{style:{flex:1,overflow:`hidden`,display:`flex`,flexDirection:`column`},children:o.map((e,t)=>(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6,padding:`6px 10px`,borderBottom:`1px solid ${p.border}`,alignItems:`center`},children:[(0,f.jsx)(`div`,{style:{width:4,alignSelf:`stretch`,borderRadius:2,background:e.mute?p.textDim:e.color,flexShrink:0,opacity:e.mute?.4:1}}),(0,f.jsxs)(`div`,{style:{width:60,flexShrink:0},children:[(0,f.jsx)(`div`,{style:{fontSize:11,fontWeight:600,color:e.mute?p.textDim:p.textPrimary,marginBottom:2,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`},children:e.name}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:3},children:[(0,f.jsx)(`div`,{onClick:()=>c(t),style:{padding:`1px 4px`,borderRadius:3,fontSize:9,fontWeight:700,cursor:`pointer`,background:e.mute?`${p.red}33`:p.surface,color:e.mute?p.red:p.textDim,border:`1px solid ${e.mute?p.red+`60`:p.border}`},children:`M`}),(0,f.jsx)(`div`,{onClick:()=>u(t),style:{padding:`1px 4px`,borderRadius:3,fontSize:9,fontWeight:700,cursor:`pointer`,background:e.solo?`${p.amber}33`:p.surface,color:e.solo?p.amber:p.textDim,border:`1px solid ${e.solo?p.amber+`60`:p.border}`},children:`S`})]})]}),(0,f.jsx)(`div`,{style:{flex:1,overflow:`hidden`},children:(0,f.jsx)(ee,{width:120,height:36,color:e.mute?p.textDim:e.color,playPos:i,seed:t+1})}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:4,alignItems:`center`,flexShrink:0},children:[(0,f.jsx)(w,{level:e.level,height:36}),(0,f.jsx)(`input`,{type:`range`,min:0,max:100,value:e.vol,onChange:e=>d(t,+e.target.value),style:{writingMode:`vertical-lr`,direction:`rtl`,height:40,width:20,accentColor:e.color,cursor:`pointer`}})]})]},t))}),(0,f.jsxs)(`div`,{style:{padding:`8px 10px`,borderTop:`1px solid ${p.border}`,display:`flex`,gap:10,alignItems:`center`,background:p.panel},children:[(0,f.jsx)(`div`,{style:{fontSize:10,fontWeight:600,color:p.textSec,width:44},children:`MASTER`}),(0,f.jsx)(`div`,{style:{flex:1},children:(0,f.jsx)(w,{level:68,vertical:!1,height:120})}),(0,f.jsx)(`div`,{className:`mono`,style:{fontSize:10,color:p.green},children:`-4.2 dBFS`}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,children:`Export`})]})]})}var ce=[{id:`rig`,label:`Rig`,icon:`🎛`},{id:`fx`,label:`FX Chain`,icon:`⛓`},{id:`models`,label:`Models`,icon:`📁`},{id:`irs`,label:`IRs`,icon:`🎚`},{id:`presets`,label:`Presets`,icon:`⭐`},{id:`settings`,label:`Settings`,icon:`⚙`},{id:`record`,label:`Record`,icon:`🎙`}];function D(){let[e,t]=(0,l.useState)(`rig`),{state:n,connected:r,refresh:i}=x();return(0,l.useEffect)(()=>{document.title=`Pi Multi-FX Pedal`},[]),(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`style`,{children:S}),(0,f.jsxs)(`div`,{style:{width:`100%`,maxWidth:440,margin:`0 auto`,height:`100dvh`,display:`flex`,flexDirection:`column`,background:p.bg,overflow:`hidden`,fontFamily:`'Inter', sans-serif`},children:[(0,f.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,padding:`6px 12px 4px`,background:p.panel,borderBottom:`1px solid ${p.border}`,flexShrink:0},children:[(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`},children:[(0,f.jsx)(`div`,{style:{width:6,height:6,borderRadius:`50%`,background:r?p.green:p.red,boxShadow:r?`0 0 6px ${p.green}`:`none`}}),(0,f.jsx)(`span`,{className:`mono`,style:{fontSize:9,color:p.textSec},children:`PI MULTI-FX`})]}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:10,alignItems:`center`},children:[n?.bypass&&(0,f.jsx)(`span`,{className:`badge badge-red`,children:`BYP`}),n?.tuner_enabled&&(0,f.jsx)(`span`,{className:`badge badge-amber`,children:`TUNER`}),n?.nam_loaded&&(0,f.jsx)(`span`,{className:`badge badge-blue`,children:`NAM`}),n?.ir_loaded&&(0,f.jsx)(`span`,{className:`badge badge-green`,children:`IR`})]})]}),(0,f.jsxs)(`div`,{style:{flex:1,overflow:`hidden`,display:`flex`,flexDirection:`column`},children:[e===`rig`&&(0,f.jsx)(E,{state:n,connected:r}),e===`fx`&&(0,f.jsx)(ne,{state:n,connected:r}),e===`models`&&(0,f.jsx)(re,{state:n,connected:r,refresh:i}),e===`irs`&&(0,f.jsx)(ie,{state:n,connected:r,refresh:i}),e===`presets`&&(0,f.jsx)(ae,{state:n,connected:r,refresh:i}),e===`settings`&&(0,f.jsx)(oe,{state:n,connected:r,refresh:i}),e===`record`&&(0,f.jsx)(se,{})]}),(0,f.jsx)(`div`,{className:`tabbar`,children:ce.map(n=>(0,f.jsxs)(`div`,{className:`tab ${e===n.id?`active`:``}`,onClick:()=>t(n.id),children:[(0,f.jsx)(`span`,{style:{fontSize:14,display:`block`},children:n.icon}),n.label]},n.id))})]})]})}(0,u.createRoot)(document.getElementById(`root`)).render((0,f.jsx)(l.StrictMode,{children:(0,f.jsx)(D,{})})); \ No newline at end of file +`;function C({label:e,value:t=50,onChange:n,size:r=52,color:i=p.amber,min:a=0,max:o=100}){let s=(0,l.useRef)(null),c=(0,l.useRef)(null),u=(t-a)/(o-a),d=-140+u*280,m=e=>{e.preventDefault(),c.current={y:e.touches?e.touches[0].clientY:e.clientY,val:t};let r=e=>{let t=e.touches?e.touches[0].clientY:e.clientY,r=(c.current.y-t)/120,i=Math.max(a,Math.min(o,c.current.val+r*(o-a)));n?.(Math.round(i))},i=()=>{window.removeEventListener(`mousemove`,r),window.removeEventListener(`mouseup`,i),window.removeEventListener(`touchmove`,r),window.removeEventListener(`touchend`,i)};window.addEventListener(`mousemove`,r),window.addEventListener(`mouseup`,i),window.addEventListener(`touchmove`,r,{passive:!1}),window.addEventListener(`touchend`,i)},h=r+12,g=h/2,_=h/2,v=r/2+3,y=(d-90)*(Math.PI/180),b=g+v*Math.cos(y),x=_+v*Math.sin(y);return(0,f.jsxs)(`div`,{className:`knob-wrap`,style:{width:r+12},children:[(0,f.jsxs)(`div`,{className:`knob`,style:{width:r,height:r},onMouseDown:m,onTouchStart:m,ref:s,children:[(0,f.jsxs)(`svg`,{style:{position:`absolute`,inset:-6,width:h,height:h,overflow:`visible`},children:[(0,f.jsx)(`circle`,{cx:g,cy:_,r:v,fill:`none`,stroke:p.border,strokeWidth:`2.5`,strokeLinecap:`round`,opacity:`.5`}),u>0&&(0,f.jsx)(`path`,{d:`M ${g} ${_-v} A ${v} ${v} 0 ${+(u>.5)} 1 ${b} ${x}`,fill:`none`,stroke:i,strokeWidth:`2.5`,strokeLinecap:`round`,style:{filter:`drop-shadow(0 0 3px ${i})`}})]}),(0,f.jsx)(`div`,{className:`knob-inner`,style:{"--amber":i},children:(0,f.jsx)(`div`,{className:`knob-dot`,style:{height:r*.38,bottom:r/2-2,transform:`translateX(-50%) rotate(${d}deg)`,transformOrigin:`50% ${r*.38}px`}})})]}),(0,f.jsx)(`div`,{className:`knob-value mono`,style:{color:i},children:t}),(0,f.jsx)(`div`,{className:`knob-label`,children:e})]})}function w({level:e=0,height:t=60,vertical:n=!0}){let r=Math.round(e/100*12),i=e=>e>=10?p.red:e>=8?`#E8C030`:p.green;return n?(0,f.jsx)(`div`,{style:{display:`flex`,flexDirection:`column-reverse`,gap:2,height:t,alignItems:`center`},children:Array.from({length:12}).map((e,n)=>(0,f.jsx)(`div`,{style:{width:6,height:(t-24)/12,borderRadius:1,background:n(0,f.jsx)(`div`,{style:{flex:1,height:`100%`,borderRadius:1,background:t{let r=a.current;if(!r)return;let o=r.getContext(`2d`);o.clearRect(0,0,e,t);let s=t/2;o.strokeStyle=n,o.lineWidth=1,o.shadowColor=n,o.shadowBlur=2,o.beginPath();for(let t=0;te.default??e.default??50));return(0,f.jsxs)(`div`,{className:`fx-block ${n?`active`:``} ${r?`bypassed`:``}`,children:[(0,f.jsxs)(`div`,{className:`fx-header`,onClick:()=>s(e=>!e),children:[(0,f.jsx)(`div`,{className:`bypass-led ${r?`led-off`:`led-on`}`,onClick:e=>{e.stopPropagation(),a?.()}}),(0,f.jsx)(`span`,{style:{flex:1,fontSize:13,fontWeight:600},children:e}),(0,f.jsx)(`span`,{className:`badge badge-blue`,style:{fontSize:10},children:t}),(0,f.jsx)(`span`,{style:{color:p.textDim,fontSize:18,marginLeft:6},children:o?`▾`:`▸`})]}),o&&(0,f.jsx)(`div`,{className:`fx-body`,children:i.map((e,t)=>(0,f.jsx)(C,{label:e.name,value:c[t],size:44,onChange:e=>u(n=>n.map((n,r)=>r===t?e:n)),min:e.min??0,max:e.max??100},e.key||e.name))})]})}function te({children:e,onClose:t}){return(0,f.jsx)(`div`,{className:`slide-panel`,onClick:t,children:(0,f.jsxs)(`div`,{className:`slide-panel-inner`,onClick:e=>e.stopPropagation(),children:[(0,f.jsx)(`div`,{className:`slide-panel-handle`}),e]})})}function E({state:e,connected:t}){let[n,r]=(0,l.useState)(e?.master_volume==null?80:Math.round(e.master_volume*100));(0,l.useEffect)(()=>{e?.master_volume!=null&&r(Math.round(e.master_volume*100))},[e?.master_volume]);let i=async e=>{r(e);try{await v(`/api/volume`,{volume:e/100})}catch{}},a=async()=>{try{await _(`/api/bypass`)}catch{}},o=async()=>{try{let t=e?.tuner_enabled;await _(`/api/tuner`,{enabled:!t})}catch{}},s=e?.input_level??0,c=e?.output_level??0;return(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`screen-title`,children:`Active Rig`}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6,marginTop:4,flexWrap:`wrap`,alignItems:`center`},children:[e?.current_preset?(0,f.jsx)(`span`,{className:`nam-chip`,style:{color:p.amber,borderColor:`${p.amber}55`,background:`${p.amber}15`},children:e.current_preset.name}):(0,f.jsx)(`span`,{style:{fontSize:11,color:p.textDim},children:`No preset loaded`}),t?(0,f.jsx)(`span`,{className:`badge badge-green`,children:`Connected`}):(0,f.jsx)(`span`,{className:`badge badge-red`,children:`Offline`})]})]}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`},children:[(0,f.jsx)(w,{level:s,height:44}),(0,f.jsx)(w,{level:c,height:44})]})]}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[(0,f.jsxs)(`div`,{className:`card-sm`,style:{display:`flex`,gap:10,justifyContent:`space-around`},children:[(0,f.jsxs)(`div`,{style:{textAlign:`center`},children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:4},children:`Bypass`}),(0,f.jsx)(`div`,{className:`switch ${e?.bypass?`on`:``}`,onClick:a,style:{margin:`0 auto`}})]}),(0,f.jsxs)(`div`,{style:{textAlign:`center`},children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:4},children:`Tuner`}),(0,f.jsx)(`div`,{className:`switch ${e?.tuner_enabled?`on`:``}`,onClick:o,style:{margin:`0 auto`}})]}),(0,f.jsxs)(`div`,{style:{textAlign:`center`},children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:4},children:`Routing`}),(0,f.jsx)(`span`,{className:`mono`,style:{fontSize:12,color:p.amber},children:e?.routing_mode||`mono`})]})]}),(0,f.jsxs)(`div`,{className:`card`,style:{display:`flex`,gap:20,alignItems:`center`},children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{className:`section-label`,children:`Master Volume`}),(0,f.jsx)(`input`,{type:`range`,min:0,max:100,value:n,onChange:e=>i(+e.target.value),style:{width:`100%`,accentColor:p.amber}}),(0,f.jsxs)(`div`,{className:`mono`,style:{fontSize:11,color:p.amber,marginTop:4},children:[n,`%`]})]}),(0,f.jsxs)(`div`,{className:`mono`,style:{fontSize:11,color:p.textSec,textAlign:`right`},children:[e?.nam_loaded?`NAM: Active`:`NAM: —`,(0,f.jsx)(`br`,{}),e?.ir_loaded?`IR: Active`:`IR: —`]})]}),(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsx)(`div`,{className:`section-label`,children:`Signal Chain`}),(0,f.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,overflowX:`auto`,padding:`4px 0`},children:[`IN`,e?.bypass?`BYP`:e?.nam_loaded?`NAM`:`AMP`,e?.ir_loaded?`IR`:`CAB`,`OUT`].map((e,t,n)=>(0,f.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,flexShrink:0},children:[(0,f.jsx)(`div`,{style:{padding:`3px 8px`,borderRadius:4,fontSize:10,fontWeight:700,background:t===0||t===n.length-1?p.blueDim:p.amberDim,color:t===0||t===n.length-1?p.blue:p.amber,border:`1px solid ${t===0||t===n.length-1?p.blue:p.amber}60`},children:e}),t{if(!t||!e?.current_preset){r([{id:1,title:`Overdrive`,type:`OD`,bypassed:!1,params:[{key:`drive`,name:`Drive`,default:62},{key:`tone`,name:`Tone`,default:55}]},{id:2,title:`Compressor`,type:`COMP`,bypassed:!1,params:[{key:`thresh`,name:`Thresh`,default:40},{key:`ratio`,name:`Ratio`,default:40}]},{id:3,title:`NAM Amp`,type:`AMP`,bypassed:!1,params:[]},{id:4,title:`Delay`,type:`DELAY`,bypassed:!0,params:[{key:`time`,name:`Time`,default:45},{key:`feedback`,name:`Fdbk`,default:38}]}]),a(!1);return}g(`/api/presets`).then(e=>{let t=e.banks||[];if(t.length>0&&t[0].presets){let e=t[0].presets.find(e=>e!=null);e?.chain&&r(e.chain.map((e,t)=>({id:t+1,title:e.fx_type.replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase()),type:e.fx_type.toUpperCase(),bypassed:e.bypass||!e.enabled,params:[]})))}a(!1)}).catch(()=>{a(!1)})},[t,e]);let o=e=>r(t=>t&&t.map(t=>t.id===e?{...t,bypassed:!t.bypassed}:t));return i?(0,f.jsx)(`div`,{style:{flex:1,display:`flex`,alignItems:`center`,justifyContent:`center`},children:(0,f.jsx)(`div`,{className:`loader`})}):(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsx)(`div`,{className:`screen-title`,children:`FX Chain`}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,children:`+ Add Block`})]}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[(0,f.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,padding:`4px 2px`,overflowX:`auto`},children:[`IN`,...(n||[]).map(e=>e.type),`OUT`].map((e,t,n)=>(0,f.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,flexShrink:0},children:[(0,f.jsx)(`div`,{style:{padding:`3px 8px`,borderRadius:4,fontSize:10,fontWeight:700,background:e===`IN`||e===`OUT`?p.blueDim:p.amberDim,color:e===`IN`||e===`OUT`?p.blue:p.amber,border:`1px solid ${e===`IN`||e===`OUT`?p.blue:p.amber}60`},children:e}),t(0,f.jsx)(T,{...e,active:!e.bypassed,onToggle:()=>o(e.id)},e.id))]})]})}function re({state:e,connected:t,refresh:n}){let[r,i]=(0,l.useState)([]),[a,o]=(0,l.useState)(null),[s,c]=(0,l.useState)(!0),[u,d]=(0,l.useState)(!1),[m,h]=(0,l.useState)(``),[v,y]=(0,l.useState)([]),[x,S]=(0,l.useState)(!1),[C,w]=(0,l.useState)(!1),ee=(0,l.useRef)(null),T=(0,l.useCallback)(async()=>{if(!t){c(!1);return}try{let e=await g(`/api/models`);i(e.models||[]),o(e.current)}catch{}c(!1)},[t]);(0,l.useEffect)(()=>{T()},[T]);let te=async e=>{try{await _(`/api/models/load`,{path:e}),await T(),n()}catch{alert(`Failed to load model`)}},E=async()=>{try{await _(`/api/models/unload`),o(null),await T(),n()}catch{alert(`Failed to unload`)}},ne=async e=>{let t=e.target.files?.[0];if(t){w(!0);try{await b(`/api/models/upload`,t),await T()}catch{alert(`Upload failed`)}w(!1)}},re=(0,l.useCallback)(async()=>{if(m.trim()){d(!0);try{y((await g(`/api/models/tonedownload/search?q=${encodeURIComponent(m)}`)).results||[])}catch{alert(`Search failed`)}d(!1)}},[m]),ie=async e=>{try{await _(`/api/models/tonedownload/install`,{download_url:e.download_url,name:e.name||e.filename,id:e.id,size:e.size,pack_name:e.pack_name,display_name:e.name}),await T(),n()}catch{alert(`Install failed`)}};return s?(0,f.jsx)(`div`,{style:{flex:1,display:`flex`,alignItems:`center`,justifyContent:`center`},children:(0,f.jsx)(`div`,{className:`loader`})}):(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsxs)(`div`,{className:`screen-title`,children:[`NAM Models (`,r.length,`)`]}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6},children:[(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>S(!x),children:x?`Local`:`Search`}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,onClick:()=>ee.current?.click(),children:C?`...`:`+ Upload`}),(0,f.jsx)(`input`,{ref:ee,type:`file`,accept:`.nam`,style:{display:`none`},onChange:ne})]})]}),x&&(0,f.jsxs)(`div`,{style:{padding:`8px 12px`,borderBottom:`1px solid ${p.border}`},children:[(0,f.jsxs)(`div`,{className:`search-bar`,children:[(0,f.jsx)(`span`,{style:{color:p.textDim},children:`🔍`}),(0,f.jsx)(`input`,{type:`text`,placeholder:`Search Tone3000…`,value:m,onChange:e=>h(e.target.value),onKeyDown:e=>e.key===`Enter`&&re()}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,onClick:re,disabled:u,children:u?`...`:`Go`})]}),v.length>0&&(0,f.jsx)(`div`,{style:{marginTop:8,maxHeight:240,overflow:`auto`},children:v.map(e=>(0,f.jsxs)(`div`,{className:`preset-row`,onClick:()=>ie(e),style:{borderBottom:`1px solid ${p.border}`,borderRadius:0},children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13},children:e.name}),(0,f.jsxs)(`div`,{style:{fontSize:10,color:p.textDim},children:[e.author,` · `,e.size_display,` · `,e.architecture]})]}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,children:`Get`})]},e.id))})]}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[a&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:6},children:`Loaded Model`}),(0,f.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,f.jsx)(`div`,{className:`nam-chip`,children:a}),(0,f.jsx)(`button`,{className:`btn btn-danger btn-sm`,onClick:E,children:`Unload`})]})]}),r.length===0?(0,f.jsxs)(`div`,{style:{textAlign:`center`,padding:30,color:p.textDim,fontSize:14},children:[`No NAM models found.`,(0,f.jsx)(`br`,{}),`Upload a .nam file or search Tone3000.`]}):r.map(e=>(0,f.jsxs)(`div`,{className:`preset-row ${e.loaded?`active`:``}`,children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13,fontWeight:500},children:e.name}),(0,f.jsxs)(`div`,{style:{fontSize:10,color:p.textDim},children:[e.architecture,` · `,e.size_mb,` MB`]})]}),e.loaded?(0,f.jsx)(`span`,{className:`badge badge-green`,children:`Loaded`}):(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>te(e.path),children:`Load`})]},e.name))]})]})}function ie({state:e,connected:t,refresh:n}){let[r,i]=(0,l.useState)([]),[a,o]=(0,l.useState)(null),[s,c]=(0,l.useState)(!0),[u,d]=(0,l.useState)(!1),[m,h]=(0,l.useState)(``),[v,y]=(0,l.useState)([]),[x,S]=(0,l.useState)(!1),[C,w]=(0,l.useState)(!1),ee=(0,l.useRef)(null),T=(0,l.useCallback)(async()=>{if(!t){c(!1);return}try{let e=await g(`/api/irs`);i(e.irs||[]),o(e.current)}catch{}c(!1)},[t]);(0,l.useEffect)(()=>{T()},[T]);let te=async e=>{try{await _(`/api/irs/load`,{path:e}),await T(),n()}catch{alert(`Failed to load IR`)}},E=async()=>{try{await _(`/api/irs/unload`),o(null),await T(),n()}catch{alert(`Failed to unload`)}},ne=async e=>{let t=e.target.files?.[0];if(t){w(!0);try{await b(`/api/irs/upload`,t),await T()}catch{alert(`Upload failed`)}w(!1)}},re=(0,l.useCallback)(async()=>{if(m.trim()){d(!0);try{y((await g(`/api/irs/tonedownload/search?q=${encodeURIComponent(m)}`)).results||[])}catch{alert(`Search failed`)}d(!1)}},[m]),ie=async e=>{try{await _(`/api/irs/tonedownload/install`,{download_url:e.download_url,name:e.name||e.filename,id:e.id,size:e.size,display_name:e.name}),await T(),n()}catch{alert(`Install failed`)}};return s?(0,f.jsx)(`div`,{style:{flex:1,display:`flex`,alignItems:`center`,justifyContent:`center`},children:(0,f.jsx)(`div`,{className:`loader`})}):(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsxs)(`div`,{className:`screen-title`,children:[`IR Files (`,r.length,`)`]}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6},children:[(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>S(!x),children:x?`Local`:`Search`}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,onClick:()=>ee.current?.click(),children:C?`...`:`+ Upload`}),(0,f.jsx)(`input`,{ref:ee,type:`file`,accept:`.wav`,style:{display:`none`},onChange:ne})]})]}),x&&(0,f.jsxs)(`div`,{style:{padding:`8px 12px`,borderBottom:`1px solid ${p.border}`},children:[(0,f.jsxs)(`div`,{className:`search-bar`,children:[(0,f.jsx)(`span`,{style:{color:p.textDim},children:`🔍`}),(0,f.jsx)(`input`,{type:`text`,placeholder:`Search Tone3000 IRs…`,value:m,onChange:e=>h(e.target.value),onKeyDown:e=>e.key===`Enter`&&re()}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,onClick:re,disabled:u,children:u?`...`:`Go`})]}),v.length>0&&(0,f.jsx)(`div`,{style:{marginTop:8,maxHeight:240,overflow:`auto`},children:v.map(e=>(0,f.jsxs)(`div`,{className:`preset-row`,onClick:()=>ie(e),style:{borderBottom:`1px solid ${p.border}`,borderRadius:0},children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13},children:e.name}),(0,f.jsxs)(`div`,{style:{fontSize:10,color:p.textDim},children:[e.author,` · `,e.size_display]})]}),(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,children:`Get`})]},e.id))})]}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[a&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:6},children:`Loaded IR`}),(0,f.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8},children:[(0,f.jsx)(`div`,{className:`nam-chip`,style:{color:p.green,borderColor:`${p.green}55`,background:`${p.green}15`},children:a}),(0,f.jsx)(`button`,{className:`btn btn-danger btn-sm`,onClick:E,children:`Unload`})]})]}),r.length===0?(0,f.jsxs)(`div`,{style:{textAlign:`center`,padding:30,color:p.textDim,fontSize:14},children:[`No IR files found.`,(0,f.jsx)(`br`,{}),`Upload a .wav file or search Tone3000.`]}):r.map(e=>(0,f.jsxs)(`div`,{className:`preset-row ${e.loaded?`active`:``}`,children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13,fontWeight:500},children:e.name}),(0,f.jsxs)(`div`,{style:{fontSize:10,color:p.textDim},children:[e.sample_rate,` Hz · `,e.length_ms,` ms · `,e.num_taps,` taps`]})]}),e.loaded?(0,f.jsx)(`span`,{className:`badge badge-green`,children:`Loaded`}):(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>te(e.path),children:`Load`})]},e.name))]})]})}function ae({state:e,connected:t,refresh:n}){let[r,i]=(0,l.useState)([]),[a,o]=(0,l.useState)(0),[s,c]=(0,l.useState)(!0),[u,d]=(0,l.useState)(``),[m,h]=(0,l.useState)(!1),[b,x]=(0,l.useState)(null),S=(0,l.useCallback)(async()=>{if(!t){i([{name:`Default`,number:0,presets:[{name:`Edge of Breakup`,bank:0,program:0},{name:`Modern High Gain`,bank:0,program:1},null,null]}]),c(!1);return}try{i((await g(`/api/presets`)).banks||[])}catch{}c(!1)},[t]);(0,l.useEffect)(()=>{S()},[S]);let C=async(e,t)=>{try{await _(`/api/presets/${e}/${t}/activate`),await S(),n()}catch{alert(`Failed to load preset`)}},w=async()=>{if(!u.trim())return;let t=e?.current_preset?.bank??0,n=e?.current_preset?.program??0;try{await v(`/api/presets/${t}/${n}`,{name:u}),h(!1),await S()}catch{alert(`Failed to save`)}},ee=async(e,t)=>{try{await y(`/api/presets/${e}/${t}`),x(null),await S()}catch{alert(`Failed to delete`)}};if(s)return(0,f.jsx)(`div`,{style:{flex:1,display:`flex`,alignItems:`center`,justifyContent:`center`},children:(0,f.jsx)(`div`,{className:`loader`})});let T=e?.current_preset,E=r[a]?.presets||[];return(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsx)(`div`,{className:`screen-title`,children:`Presets`}),(0,f.jsx)(`div`,{style:{display:`flex`,gap:6},children:(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>h(!0),children:`Save`})})]}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[r.length>1&&(0,f.jsx)(`div`,{className:`toggle`,children:r.map((e,t)=>(0,f.jsx)(`button`,{className:`toggle-btn ${a===t?`active`:``}`,onClick:()=>o(t),children:e.name},e.number))}),T&&(0,f.jsx)(`div`,{className:`card-sm`,style:{display:`flex`,alignItems:`center`,gap:8},children:(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:11,color:p.textDim},children:`Current`}),(0,f.jsxs)(`div`,{style:{fontSize:14,fontWeight:600,color:p.amber},children:[T.name,(0,f.jsxs)(`span`,{className:`mono`,style:{fontSize:10,color:p.textDim,marginLeft:8},children:[`Bank `,T.bank,` · Prog `,T.program]})]})]})}),E.length===0?(0,f.jsx)(`div`,{style:{textAlign:`center`,padding:30,color:p.textDim,fontSize:14},children:`No presets in this bank.`}):E.map((e,t)=>{if(!e)return null;let n=T?.bank===e.bank&&T?.program===e.program,r=b===`${e.bank}-${e.program}`;return(0,f.jsxs)(`div`,{className:`preset-row ${n?`active`:``}`,onClick:()=>!r&&C(e.bank,e.program),children:[(0,f.jsx)(`div`,{className:`mono`,style:{width:28,height:28,borderRadius:6,display:`flex`,alignItems:`center`,justifyContent:`center`,fontSize:12,fontWeight:700,background:n?`${p.amber}22`:p.surface,color:n?p.amber:p.textDim,border:`1px solid ${n?p.amber+`60`:p.border}`},children:e.program+1}),(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13,fontWeight:600},children:e.name}),(0,f.jsxs)(`div`,{style:{fontSize:10,color:p.textDim},children:[`Bank `,e.bank,` · Program `,e.program]})]}),n&&(0,f.jsx)(`span`,{style:{color:p.amber,fontSize:16},children:`●`}),r?(0,f.jsxs)(`div`,{style:{display:`flex`,gap:4},children:[(0,f.jsx)(`button`,{className:`btn btn-danger btn-sm`,onClick:t=>{t.stopPropagation(),ee(e.bank,e.program)},children:`Confirm`}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:e=>{e.stopPropagation(),x(null)},children:`Cancel`})]}):(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,style:{color:p.red},onClick:t=>{t.stopPropagation(),x(`${e.bank}-${e.program}`)},children:`Delete`})]},t)})]}),m&&(0,f.jsxs)(te,{onClose:()=>h(!1),children:[(0,f.jsx)(`div`,{className:`screen-header`,children:(0,f.jsx)(`div`,{className:`screen-title`,children:`Save Preset`})}),(0,f.jsxs)(`div`,{className:`screen-body`,children:[(0,f.jsx)(`div`,{className:`search-bar`,children:(0,f.jsx)(`input`,{type:`text`,placeholder:`Preset name…`,value:u,onChange:e=>d(e.target.value),autoFocus:!0,onKeyDown:e=>e.key===`Enter`&&w()})}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,f.jsx)(`button`,{className:`btn btn-primary`,style:{flex:1},onClick:w,children:`Save`}),(0,f.jsx)(`button`,{className:`btn btn-ghost`,onClick:()=>h(!1),children:`Cancel`})]})]})]})]})}function oe({state:e,connected:t,refresh:n}){let[r,i]=(0,l.useState)(`wifi`),[a,o]=(0,l.useState)([]),[s,c]=(0,l.useState)([]),[u,d]=(0,l.useState)([]),[m,h]=(0,l.useState)(!1),[v,y]=(0,l.useState)(!1),[b,x]=(0,l.useState)(``),[S,C]=(0,l.useState)(``),[w,ee]=(0,l.useState)(null),[T,te]=(0,l.useState)(e?.routing_mode||`mono`),[E,ne]=(0,l.useState)(e?.routing_breakpoint||7);(0,l.useEffect)(()=>{e?.routing_mode&&te(e.routing_mode),e?.routing_breakpoint!=null&&ne(e.routing_breakpoint)},[e?.routing_mode,e?.routing_breakpoint]);let re=async()=>{h(!0);try{o((await g(`/api/wifi/scan`)).networks||[])}catch{}h(!1)},ie=async(e,t)=>{try{await _(`/api/wifi/connect`,{ssid:e,password:t}),ee(null),x(``),C(``),setTimeout(n,2e3)}catch{alert(`Failed to connect`)}},ae=async()=>{try{await _(`/api/wifi/disconnect`),setTimeout(n,2e3)}catch{}},oe=async()=>{let t=e?.wifi?.hotspot_active;try{t?await _(`/api/wifi/hotspot/disable`):await _(`/api/wifi/hotspot/enable`,{ssid:`Pi-Pedal`,password:`pedal1234`}),setTimeout(n,2e3)}catch{}},se=async e=>{try{await _(`/api/bluetooth/power`,{on:e}),setTimeout(n,1e3)}catch{}},ce=async()=>{y(!0);try{c((await _(`/api/bluetooth/scan`)).devices||[])}catch{}y(!1)},D=async()=>{try{d((await g(`/api/bluetooth/paired`)).devices||[])}catch{}},O=async e=>{try{await _(`/api/bluetooth/pair`,{address:e}),await D()}catch{alert(`Pairing failed`)}},le=async(e,t)=>{try{await _(`/api/routing`,{routing_mode:e,routing_breakpoint:t})}catch{}};(0,l.useEffect)(()=>{t&&(re(),D())},[t]);let ue=e?.wifi,de=e?.bluetooth;return(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsx)(`div`,{className:`screen-header`,children:(0,f.jsx)(`div`,{className:`screen-title`,children:`Settings`})}),(0,f.jsx)(`div`,{className:`toggle`,style:{margin:`6px 10px`},children:[{id:`wifi`,label:`WiFi`},{id:`bt`,label:`Bluetooth`},{id:`routing`,label:`Routing`}].map(e=>(0,f.jsx)(`button`,{className:`toggle-btn ${r===e.id?`active`:``}`,onClick:()=>i(e.id),children:e.label},e.id))}),(0,f.jsxs)(`div`,{className:`screen-body`,style:{gap:4},children:[r===`wifi`&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsxs)(`div`,{className:`setting-row`,style:{border:`none`,paddingTop:0},children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`WiFi`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:ue?.connected?`Connected to ${ue.ssid}`:`Disconnected`})]}),(0,f.jsx)(`div`,{className:`switch ${ue?.connected?`on`:``}`,onClick:ae})]}),ue?.connected&&(0,f.jsxs)(`div`,{style:{fontSize:11,color:p.textDim},children:[`IP: `,ue.ip,` · Signal: `,ue.signal,`%`]}),(0,f.jsxs)(`div`,{className:`setting-row`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Hotspot`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:ue?.hotspot_active?`Active: ${ue.hotspot_ssid}`:`Off`})]}),(0,f.jsx)(`div`,{className:`switch ${ue?.hotspot_active?`on`:``}`,onClick:oe})]})]}),(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,marginBottom:8},children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:0},children:`Networks`}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:re,disabled:m,children:m?`...`:`Scan`})]}),a.length===0?(0,f.jsx)(`div`,{style:{fontSize:12,color:p.textDim,padding:`8px 0`},children:`Scan to see available networks.`}):a.map(e=>(0,f.jsxs)(`div`,{className:`preset-row`,style:{padding:`8px 0`,borderRadius:0,borderBottom:`1px solid ${p.border}`},onClick:()=>wpaState?.ssid!==e.ssid&&ee(e.ssid),children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13},children:e.ssid}),(0,f.jsxs)(`div`,{className:`mono`,style:{fontSize:10,color:p.textDim},children:[`Signal: `,e.signal,`% · `,e.encryption||`Open`]})]}),ue?.ssid===e.ssid&&(0,f.jsx)(`span`,{className:`badge badge-green`,children:`Connected`})]},e.ssid))]}),w&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsxs)(`div`,{className:`section-label`,children:[`Connect to `,w]}),(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:[(0,f.jsx)(`input`,{type:`password`,placeholder:`Password (leave blank for open network)`,value:S,onChange:e=>C(e.target.value),style:{background:p.surface,border:`1px solid ${p.border}`,borderRadius:6,padding:`8px 12px`,color:p.textPrimary,fontSize:13,outline:`none`},onKeyDown:e=>e.key===`Enter`&&ie(w,S)}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6},children:[(0,f.jsx)(`button`,{className:`btn btn-primary btn-sm`,style:{flex:1},onClick:()=>ie(w,S),children:`Connect`}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>ee(null),children:`Cancel`})]})]})]})]}),r===`bt`&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsxs)(`div`,{className:`setting-row`,style:{border:`none`,paddingTop:0},children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Bluetooth`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:de?.powered?`Powered on`:`Off`})]}),(0,f.jsx)(`div`,{className:`switch ${de?.powered?`on`:``}`,onClick:()=>se(!de?.powered)})]}),de?.powered&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(`div`,{className:`setting-row`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Discoverable`}),(0,f.jsxs)(`div`,{className:`setting-desc`,children:[de?.name,` (`,de?.address,`)`]})]}),(0,f.jsx)(`div`,{className:`switch ${de?.discoverable?`on`:``}`,onClick:async()=>{try{await _(`/api/bluetooth/discoverable`,{on:!de?.discoverable}),setTimeout(n,500)}catch{}}})]}),(0,f.jsxs)(`div`,{className:`setting-row`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Bluetooth MIDI`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:de?.midi_enabled?`Enabled`:`Disabled`})]}),(0,f.jsx)(`div`,{className:`switch ${de?.midi_enabled?`on`:``}`,onClick:async()=>{try{await(de?.midi_enabled?_(`/api/bluetooth/midi-disable`):_(`/api/bluetooth/midi-enable`)),setTimeout(n,500)}catch{}}})]})]})]}),de?.powered&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,marginBottom:8},children:[(0,f.jsxs)(`div`,{className:`section-label`,style:{marginBottom:0},children:[`Paired Devices (`,u.length,`)`]}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:ce,disabled:v,children:v?`...`:`Scan`})]}),u.length===0?(0,f.jsx)(`div`,{style:{fontSize:12,color:p.textDim,padding:`8px 0`},children:`No paired devices.`}):u.map(e=>(0,f.jsxs)(`div`,{className:`preset-row`,style:{padding:`8px 0`,borderRadius:0,borderBottom:`1px solid ${p.border}`},children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13},children:e.name||e.address}),(0,f.jsxs)(`div`,{className:`mono`,style:{fontSize:10,color:p.textDim},children:[e.address,` · `,e.connected?`Connected`:`Paired`]})]}),!e.connected&&(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:async()=>{try{await _(`/api/bluetooth/connect`,{address:e.address})}catch{alert(`Failed`)}},children:`Connect`})]},e.address))]}),v&&s.length>0&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsx)(`div`,{className:`section-label`,style:{marginBottom:6},children:`Discovered`}),s.map(e=>(0,f.jsxs)(`div`,{className:`preset-row`,style:{padding:`8px 0`,borderRadius:0,borderBottom:`1px solid ${p.border}`},children:[(0,f.jsxs)(`div`,{style:{flex:1},children:[(0,f.jsx)(`div`,{style:{fontSize:13},children:e.name||e.address}),(0,f.jsx)(`div`,{className:`mono`,style:{fontSize:10,color:p.textDim},children:e.address})]}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,onClick:()=>O(e.address),children:`Pair`})]},e.address))]})]}),r===`routing`&&(0,f.jsxs)(`div`,{className:`card-sm`,children:[(0,f.jsx)(`div`,{className:`section-label`,children:`4CM Routing`}),(0,f.jsxs)(`div`,{className:`setting-row`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Mode`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:`Mono (normal) or 4CM (4-cable method)`})]}),(0,f.jsxs)(`select`,{value:T,onChange:e=>{te(e.target.value),le(e.target.value,E)},style:{background:p.surface,border:`1px solid ${p.border}`,borderRadius:6,padding:`6px 10px`,color:p.textPrimary,fontSize:13,outline:`none`},children:[(0,f.jsx)(`option`,{value:`mono`,children:`Mono`}),(0,f.jsx)(`option`,{value:`4cm`,children:`4CM`})]})]}),T===`4cm`&&(0,f.jsxs)(`div`,{className:`setting-row`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`setting-label`,children:`Breakpoint`}),(0,f.jsx)(`div`,{className:`setting-desc`,children:`Chain position for amp send/return`})]}),(0,f.jsx)(`input`,{type:`number`,min:1,max:15,value:E,onChange:e=>{let t=+e.target.value;ne(t),le(T,t)},style:{background:p.surface,border:`1px solid ${p.border}`,borderRadius:6,padding:`6px 10px`,color:p.textPrimary,fontSize:13,width:60,outline:`none`,textAlign:`center`}})]})]})]})]})}function se(){let[e,t]=(0,l.useState)(!1),[n,r]=(0,l.useState)(!1),[i,a]=(0,l.useState)(0),[o,s]=(0,l.useState)([{name:`Guitar 1`,color:p.amber,vol:80,pan:50,mute:!1,solo:!1,level:72},{name:`Guitar 2`,color:p.blue,vol:65,pan:35,mute:!1,solo:!1,level:55},{name:`Bass DI`,color:p.green,vol:75,pan:50,mute:!0,solo:!1,level:68},{name:`Drum Loop`,color:`#A060E0`,vol:70,pan:52,mute:!1,solo:!1,level:60}]);(0,l.useEffect)(()=>{let t;return e&&(t=setInterval(()=>a(e=>e>=100?0:e+.3),80)),()=>clearInterval(t)},[e]),(0,l.useEffect)(()=>{let e=setInterval(()=>{s(e=>e.map(e=>({...e,level:e.mute?0:Math.max(10,Math.min(95,e.level+(Math.random()-.48)*12))})))},90);return()=>clearInterval(e)},[]);let c=e=>s(t=>t.map((t,n)=>n===e?{...t,mute:!t.mute}:t)),u=e=>s(t=>t.map((t,n)=>n===e?{...t,solo:!t.solo}:t)),d=(e,t)=>s(n=>n.map((n,r)=>r===e?{...n,vol:t}:n));return(0,f.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100%`},children:[(0,f.jsxs)(`div`,{className:`screen-header`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`screen-title`,children:`Multitrack`}),(0,f.jsxs)(`div`,{className:`mono`,style:{fontSize:12,color:p.textSec,marginTop:2},children:[Math.floor(i/100*32).toString().padStart(2,`0`),`:`,Math.floor(i/100*32%1*60).toString().padStart(2,`0`)]})]}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:8,alignItems:`center`},children:[(0,f.jsx)(`div`,{className:`transport-btn`,onClick:()=>a(0),children:`⏮`}),(0,f.jsx)(`div`,{className:`transport-btn ${n?`rec`:``}`,onClick:()=>{r(e=>!e),n||t(!0)},children:(0,f.jsx)(`div`,{style:{width:14,height:14,borderRadius:n?3:`50%`,background:n?p.red:p.textSec,boxShadow:n?`0 0 12px ${p.red}`:`none`}})}),(0,f.jsx)(`div`,{className:`transport-btn ${e?`play`:``}`,onClick:()=>t(e=>!e),children:e?`⏸`:`▶`})]})]}),(0,f.jsx)(`div`,{style:{flex:1,overflow:`hidden`,display:`flex`,flexDirection:`column`},children:o.map((e,t)=>(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6,padding:`6px 10px`,borderBottom:`1px solid ${p.border}`,alignItems:`center`},children:[(0,f.jsx)(`div`,{style:{width:4,alignSelf:`stretch`,borderRadius:2,background:e.mute?p.textDim:e.color,flexShrink:0,opacity:e.mute?.4:1}}),(0,f.jsxs)(`div`,{style:{width:60,flexShrink:0},children:[(0,f.jsx)(`div`,{style:{fontSize:11,fontWeight:600,color:e.mute?p.textDim:p.textPrimary,marginBottom:2,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`},children:e.name}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:3},children:[(0,f.jsx)(`div`,{onClick:()=>c(t),style:{padding:`1px 4px`,borderRadius:3,fontSize:9,fontWeight:700,cursor:`pointer`,background:e.mute?`${p.red}33`:p.surface,color:e.mute?p.red:p.textDim,border:`1px solid ${e.mute?p.red+`60`:p.border}`},children:`M`}),(0,f.jsx)(`div`,{onClick:()=>u(t),style:{padding:`1px 4px`,borderRadius:3,fontSize:9,fontWeight:700,cursor:`pointer`,background:e.solo?`${p.amber}33`:p.surface,color:e.solo?p.amber:p.textDim,border:`1px solid ${e.solo?p.amber+`60`:p.border}`},children:`S`})]})]}),(0,f.jsx)(`div`,{style:{flex:1,overflow:`hidden`},children:(0,f.jsx)(ee,{width:120,height:36,color:e.mute?p.textDim:e.color,playPos:i,seed:t+1})}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:4,alignItems:`center`,flexShrink:0},children:[(0,f.jsx)(w,{level:e.level,height:36}),(0,f.jsx)(`input`,{type:`range`,min:0,max:100,value:e.vol,onChange:e=>d(t,+e.target.value),style:{writingMode:`vertical-lr`,direction:`rtl`,height:40,width:20,accentColor:e.color,cursor:`pointer`}})]})]},t))}),(0,f.jsxs)(`div`,{style:{padding:`8px 10px`,borderTop:`1px solid ${p.border}`,display:`flex`,gap:10,alignItems:`center`,background:p.panel},children:[(0,f.jsx)(`div`,{style:{fontSize:10,fontWeight:600,color:p.textSec,width:44},children:`MASTER`}),(0,f.jsx)(`div`,{style:{flex:1},children:(0,f.jsx)(w,{level:68,vertical:!1,height:120})}),(0,f.jsx)(`div`,{className:`mono`,style:{fontSize:10,color:p.green},children:`-4.2 dBFS`}),(0,f.jsx)(`button`,{className:`btn btn-ghost btn-sm`,children:`Export`})]})]})}var ce=[{id:`rig`,label:`Rig`,icon:`🎛`},{id:`fx`,label:`FX Chain`,icon:`⛓`},{id:`models`,label:`Models`,icon:`📁`},{id:`irs`,label:`IRs`,icon:`🎚`},{id:`presets`,label:`Presets`,icon:`⭐`},{id:`settings`,label:`Settings`,icon:`⚙`},{id:`record`,label:`Record`,icon:`🎙`}];function D(){let[e,t]=(0,l.useState)(`rig`),{state:n,connected:r,refresh:i}=x();return(0,l.useEffect)(()=>{document.title=`Pi Multi-FX Pedal`},[]),(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`style`,{children:S}),(0,f.jsxs)(`div`,{style:{width:`100%`,maxWidth:440,margin:`0 auto`,height:`100dvh`,display:`flex`,flexDirection:`column`,background:p.bg,overflow:`hidden`,fontFamily:`'Inter', sans-serif`},children:[(0,f.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,padding:`6px 12px 4px`,background:p.panel,borderBottom:`1px solid ${p.border}`,flexShrink:0},children:[(0,f.jsxs)(`div`,{style:{display:`flex`,gap:6,alignItems:`center`},children:[(0,f.jsx)(`div`,{style:{width:6,height:6,borderRadius:`50%`,background:r?p.green:p.red,boxShadow:r?`0 0 6px ${p.green}`:`none`}}),(0,f.jsx)(`span`,{className:`mono`,style:{fontSize:9,color:p.textSec},children:`PI MULTI-FX`})]}),(0,f.jsxs)(`div`,{style:{display:`flex`,gap:10,alignItems:`center`},children:[n?.bypass&&(0,f.jsx)(`span`,{className:`badge badge-red`,children:`BYP`}),n?.tuner_enabled&&(0,f.jsx)(`span`,{className:`badge badge-amber`,children:`TUNER`}),n?.nam_loaded&&(0,f.jsx)(`span`,{className:`badge badge-blue`,children:`NAM`}),n?.ir_loaded&&(0,f.jsx)(`span`,{className:`badge badge-green`,children:`IR`})]})]}),(0,f.jsxs)(`div`,{style:{flex:1,overflow:`hidden`,display:`flex`,flexDirection:`column`},children:[e===`rig`&&(0,f.jsx)(E,{state:n,connected:r}),e===`fx`&&(0,f.jsx)(ne,{state:n,connected:r}),e===`models`&&(0,f.jsx)(re,{state:n,connected:r,refresh:i}),e===`irs`&&(0,f.jsx)(ie,{state:n,connected:r,refresh:i}),e===`presets`&&(0,f.jsx)(ae,{state:n,connected:r,refresh:i}),e===`settings`&&(0,f.jsx)(oe,{state:n,connected:r,refresh:i}),e===`record`&&(0,f.jsx)(se,{})]}),(0,f.jsx)(`div`,{className:`tabbar`,children:ce.map(n=>(0,f.jsxs)(`div`,{className:`tab ${e===n.id?`active`:``}`,onClick:()=>t(n.id),children:[(0,f.jsx)(`span`,{style:{fontSize:14,display:`block`},children:n.icon}),n.label]},n.id))})]})]})}(0,u.createRoot)(document.getElementById(`root`)).render((0,f.jsx)(l.StrictMode,{children:(0,f.jsx)(D,{})})); \ No newline at end of file diff --git a/src/web/ui-dist/index.html b/src/web/ui-dist/index.html index 1fe185a..9588bbf 100644 --- a/src/web/ui-dist/index.html +++ b/src/web/ui-dist/index.html @@ -5,7 +5,7 @@ Pi Multi-FX Pedal - +