function D(e,d){e.style.cursor="pointer",e.title="Double-click to edit",e.addEventListener("dblclick",()=>{let a=!1,s=document.createElement("input");s.type="text",s.className=d.className??"nbplay-inline-edit",s.value=d.getValue(),s.style.width=Math.max(e.offsetWidth+8,48)+"px",e.replaceWith(s),s.focus(),s.select();function f(){if(a)return;a=!0;let g=d.parse(s.value.trim());g!==null&&d.apply(g),s.replaceWith(e),d.sync()}s.addEventListener("keydown",g=>{g.key==="Enter"&&(g.preventDefault(),f()),g.key==="Escape"&&(g.preventDefault(),a||(a=!0,s.replaceWith(e),d.sync()))}),s.addEventListener("blur",f)})}var H=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];function T(e){let d=Math.floor(e/12)-1;return H[e%12]+d}function V(e){return 440*Math.pow(2,(e-69)/12)}function F(){let e=null,d=null,a=!0,s=null,f=0,g=.1,C=.025,m=-1;return{start(l){let i=l.get("session_id"),u=l.get("channel_index");if(i&&u>=0){let c=globalThis.__nbplay;c&&c[i]&&c[i].channels[u]&&(e=c[i].audioCtx,d=c[i].channels[u].gain,a=!1)}e||(e=new AudioContext,d=null,a=!0),e.state==="suspended"&&e.resume(),s||(m=-1,f=e.currentTime,s=setInterval(()=>{this.scheduler(l)},C*1e3))},stop(){s&&(clearInterval(s),s=null),m=-1},destroy(){this.stop(),a&&e&&e.state!=="closed"&&e.close(),e=null,d=null,a=!0},scheduler(l){if(!e)return;let i=e.currentTime;for(;f<i+g;){this.scheduleStep(l,f);let u=l.get("bpm")||120,S=(l.get("step_duration")||.25)/(u/60);f+=S}},scheduleStep(l,i){if(!e)return;let u=l.get("steps")||[];if(u.length===0)return;let c=l.get("bpm")||120,_=(l.get("step_duration")||.25)/(c/60),v=(m+1)%u.length,h=l.get("loop_enabled");if(v===0&&m>=0&&!h){l.set("is_playing",!1),l.save_changes();return}m=v,l.set("current_step",v);let q=u[v];if(q.active){let M=V(q.note),t=(q.velocity||100)/127;this.playOscillator(M,t,i,_)}},playOscillator(l,i,u,c){if(!e)return;let S=.005,_=Math.min(.05,c*.2);try{let v=e.createOscillator(),h=e.createGain();v.type="sine",v.frequency.value=l,h.gain.setValueAtTime(0,u),h.gain.linearRampToValueAtTime(i,u+S),h.gain.linearRampToValueAtTime(0,u+c-_),v.connect(h),h.connect(d||e.destination),v.start(u),v.stop(u+c)}catch{}},isPlaying(){return s!==null}}}function I({model:e,el:d}){let a=document.createElement("div");a.className="nbplay-sequencer",a.innerHTML=`
    <div class="nbplay-seq-header">
      <h3>nbplay</h3>
      <span class="nbplay-badge">sequencer</span>
    </div>
    <div class="nbplay-seq-transport">
      <button class="nbplay-seq-btn nbplay-seq-play" title="Play/Stop">\u25B6</button>
      <button class="nbplay-seq-btn nbplay-seq-stop" title="Stop">\u25A0</button>
      <div class="nbplay-seq-bpm-section">
        <label class="nbplay-seq-label">BPM</label>
        <input type="range" class="nbplay-seq-bpm-slider" min="30" max="300" step="1" />
        <span class="nbplay-seq-bpm-val"></span>
      </div>
      <div class="nbplay-seq-dur-section">
        <label class="nbplay-seq-label">Step</label>
        <select class="nbplay-seq-dur-select">
          <option value="1">1 beat</option>
          <option value="0.5">1/2 beat</option>
          <option value="0.25">1/4 beat</option>
          <option value="0.125">1/8 beat</option>
        </select>
      </div>
      <label class="nbplay-seq-loop-label">
        <input type="checkbox" class="nbplay-seq-loop-chk" /> Loop
      </label>
    </div>
    <div class="nbplay-seq-grid-wrap">
      <div class="nbplay-seq-grid"></div>
    </div>
    <div class="nbplay-seq-footer">
      <span class="nbplay-seq-info"></span>
    </div>
  `,d.appendChild(a);let s=a.querySelector(".nbplay-seq-play"),f=a.querySelector(".nbplay-seq-stop"),g=a.querySelector(".nbplay-seq-bpm-slider"),C=a.querySelector(".nbplay-seq-bpm-val"),m=a.querySelector(".nbplay-seq-dur-select"),l=a.querySelector(".nbplay-seq-loop-chk"),i=a.querySelector(".nbplay-seq-grid"),u=a.querySelector(".nbplay-seq-info"),c=F();function S(){i.innerHTML="";let t=e.get("steps")||[],p=e.get("current_step"),L=document.createElement("div");L.className="nbplay-seq-row nbplay-seq-header-row";let w=document.createElement("div");w.className="nbplay-seq-label-cell",w.textContent="#",L.appendChild(w);for(let n=0;n<t.length;n++){let r=document.createElement("div");r.className="nbplay-seq-header-cell",r.textContent=String(n+1),n===p&&r.classList.add("active-col"),L.appendChild(r)}i.appendChild(L);let A=document.createElement("div");A.className="nbplay-seq-row";let y=document.createElement("div");y.className="nbplay-seq-label-cell",y.textContent="ON",A.appendChild(y);for(let n=0;n<t.length;n++){let r=document.createElement("div");r.className="nbplay-seq-cell",r.dataset.step=String(n),t[n].active&&r.classList.add("active"),n===p&&r.classList.add("current"),r.textContent=T(t[n].note),r.title=`Step ${n+1}: ${T(t[n].note)} vel=${t[n].velocity}`,r.addEventListener("click",()=>{let b=[...e.get("steps")||[]];n<b.length&&(b[n]={...b[n],active:!b[n].active},e.set("steps",b),e.save_changes())}),r.addEventListener("wheel",b=>{b.preventDefault();let E=[...e.get("steps")||[]];if(n<E.length){let x=b.deltaY<0?1:-1,k=Math.max(0,Math.min(127,E[n].note+x));E[n]={...E[n],note:k},e.set("steps",E),e.save_changes()}}),A.appendChild(r)}i.appendChild(A);let o=document.createElement("div");o.className="nbplay-seq-row nbplay-seq-vel-row";let N=document.createElement("div");N.className="nbplay-seq-label-cell",N.textContent="VEL",o.appendChild(N);for(let n=0;n<t.length;n++){let r=document.createElement("div");r.className="nbplay-seq-vel-cell";let b=document.createElement("div");b.className="nbplay-seq-vel-bar",b.style.height=t[n].velocity/127*100+"%",t[n].active&&b.classList.add("active"),n===p&&b.classList.add("current"),r.appendChild(b),r.addEventListener("wheel",E=>{E.preventDefault();let x=[...e.get("steps")||[]];if(n<x.length){let k=E.deltaY<0?5:-5,B=Math.max(0,Math.min(127,x[n].velocity+k));x[n]={...x[n],velocity:B},e.set("steps",x),e.save_changes()}}),r.appendChild(b),o.appendChild(r)}i.appendChild(o),v()}function _(){let t=e.get("steps")||[],p=e.get("current_step");i.querySelectorAll(".nbplay-seq-header-cell").forEach((y,o)=>{y.classList.toggle("active-col",o===p)}),i.querySelectorAll(".nbplay-seq-cell").forEach((y,o)=>{o>=t.length||(y.classList.toggle("active",!!t[o].active),y.classList.toggle("current",o===p),y.textContent=T(t[o].note),y.title=`Step ${o+1}: ${T(t[o].note)} vel=${t[o].velocity}`)}),i.querySelectorAll(".nbplay-seq-vel-bar").forEach((y,o)=>{o>=t.length||(y.style.height=t[o].velocity/127*100+"%",y.classList.toggle("active",!!t[o].active),y.classList.toggle("current",o===p))}),v()}function v(){let t=e.get("steps")||[],p=t.filter(L=>L.active).length;u.textContent=`${p}/${t.length} steps active \xB7 ${e.get("bpm")} BPM`}s.addEventListener("click",()=>{let t=e.get("is_playing");e.set("is_playing",!t),e.save_changes()}),f.addEventListener("click",()=>{e.set("is_playing",!1),e.set("current_step",-1),e.save_changes()}),g.addEventListener("input",()=>{let t=parseFloat(g.value);C.textContent=t+" BPM",e.set("bpm",t),e.save_changes()}),D(C,{className:"nbplay-seq-inline-edit",getValue:()=>String(e.get("bpm")),parse:t=>{let p=parseFloat(t);return isNaN(p)?null:Math.max(30,Math.min(300,Math.round(p)))},apply:t=>{e.set("bpm",t),e.save_changes()},sync:M}),m.addEventListener("change",()=>{e.set("step_duration",parseFloat(m.value)),e.save_changes()}),l.addEventListener("change",()=>{e.set("loop_enabled",l.checked),e.save_changes()});let h=-1;function q(){let t=e.get("steps")||[];t.length!==h?(h=t.length,S()):_();let p=e.get("is_playing");s.textContent=p?"\u23F8":"\u25B6",s.classList.toggle("playing",p),p&&!c.isPlaying()?c.start(e):!p&&c.isPlaying()&&c.stop()}function M(){g.value=String(e.get("bpm")),C.textContent=e.get("bpm")+" BPM",m.value=String(e.get("step_duration")),l.checked=e.get("loop_enabled")}return e.on("change:steps",q),e.on("change:current_step",q),e.on("change:is_playing",q),e.on("change:bpm",M),e.on("change:step_duration",M),e.on("change:loop_enabled",M),M(),S(),e.set("is_playing",!1),e.set("current_step",-1),q(),()=>{c.destroy()}}var $={render:I};export{$ as default};
//# sourceMappingURL=sequencer.js.map
