1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[11893],{46482:(e,t,i)=>{i.d(t,{o:()=>n});var o=i(75556),s=i(19966);class l{static getInstance(){return l.instance||(l.instance=new l),l.instance}initialize(){if(!this.isInitialized){for(let[e,t]of(this.correctSound=new o.Howl({src:["/sounds/correct.mp3"],volume:this.uiVolume,html5:!1}),this.wrongSound=new o.Howl({src:["/sounds/wrong.mp3"],volume:this.uiVolume,html5:!1}),this.badgeSound=new o.Howl({src:["/sounds/badge.mp3"],volume:this.uiVolume,html5:!1}),this.completeSound=new o.Howl({src:["/sounds/complete.mp3"],volume:this.uiVolume,html5:!1}),[["levelUpSound","levelup"],["confettiSound","confetti"],["streakSound","streak"],["coinSound","coin"]]))this[e]=new o.Howl({src:["/sounds/".concat(t,".mp3")],volume:this.uiVolume,html5:!1});this.isInitialized=!0,this.loadVolumeSettings()}}setUIVolume(e){this.uiVolume=Math.max(0,Math.min(1,e)),this.correctSound&&this.correctSound.volume(this.uiVolume),this.wrongSound&&this.wrongSound.volume(this.uiVolume),this.badgeSound&&this.badgeSound.volume(this.uiVolume),this.completeSound&&this.completeSound.volume(this.uiVolume),this.saveVolumeSettings()}setMusicVolume(e){this.musicVolume=Math.max(0,Math.min(1,e)),this.saveVolumeSettings()}setExerciseVolume(e){this.setMusicVolume(e)}setUserVolume(e){this.setMusicVolume(e)}getUIVolume(){return this.uiVolume}getMusicVolume(){return this.musicVolume}getExerciseVolume(){return this.musicVolume}getUserVolume(){return this.musicVolume}saveVolumeSettings(){{let e={uiVolume:this.uiVolume,musicVolume:this.musicVolume};localStorage.setItem("soundVolumeSettings",JSON.stringify(e))}}loadVolumeSettings(){{let e=localStorage.getItem("soundVolumeSettings");if(e)try{let t=JSON.parse(e);void 0!==t.uiVolume&&(this.uiVolume=t.uiVolume),void 0!==t.musicVolume?this.musicVolume=t.musicVolume:void 0!==t.exerciseVolume&&(this.musicVolume=t.exerciseVolume),this.correctSound&&this.correctSound.volume(this.uiVolume),this.wrongSound&&this.wrongSound.volume(this.uiVolume),this.badgeSound&&this.badgeSound.volume(this.uiVolume),this.completeSound&&this.completeSound.volume(this.uiVolume)}catch(e){}}}playCorrect(){this.isInitialized||this.initialize(),this.correctSound&&(this.correctSound.stop(),this.correctSound.volume(this.uiVolume),this.correctSound.play()),(0,s.Ac)()}playWrong(){this.isInitialized||this.initialize(),this.wrongSound&&(this.wrongSound.stop(),this.wrongSound.volume(this.uiVolume),this.wrongSound.play()),(0,s.Rm)()}playBadge(){this.isInitialized||this.initialize(),this.badgeSound&&(this.badgeSound.stop(),this.badgeSound.volume(this.uiVolume),this.badgeSound.play())}playComplete(){this.isInitialized||this.initialize(),this.completeSound&&(this.completeSound.stop(),this.completeSound.volume(this.uiVolume),this.completeSound.play())}playCelebration(e){this.isInitialized||this.initialize();let t={levelup:this.levelUpSound,confetti:this.confettiSound,streak:this.streakSound,coin:this.coinSound}[e];t&&(t.stop(),t.volume(this.uiVolume),t.play())}cleanup(){this.correctSound&&(this.correctSound.stop(),this.correctSound.unload(),this.correctSound=null),this.wrongSound&&(this.wrongSound.stop(),this.wrongSound.unload(),this.wrongSound=null),this.badgeSound&&(this.badgeSound.stop(),this.badgeSound.unload(),this.badgeSound=null),this.completeSound&&(this.completeSound.stop(),this.completeSound.unload(),this.completeSound=null),this.isInitialized=!1}constructor(){this.correctSound=null,this.wrongSound=null,this.badgeSound=null,this.completeSound=null,this.levelUpSound=null,this.confettiSound=null,this.streakSound=null,this.coinSound=null,this.uiVolume=.5,this.musicVolume=.5,this.isInitialized=!1}}l.instance=null;let n=l.getInstance()},86877:(e,t,i)=>{i.d(t,{A:()=>u});var o=i(95155),s=i(58803),l=i.n(s),n=i(12115),a=i(25683),r=i(2178),c=i(21567);let u=e=>{let{items:t,placeholder:i,wrapperClassName:s,surfaceClassName:u}=e,d=(0,n.useMemo)(()=>t.slice(-3),[t]),m={correct:"bg-emerald-500/15 text-emerald-300 border-emerald-500/30",wrong:"bg-red-500/15 text-red-300 border-red-500/30",skip:"bg-amber-500/15 text-amber-300 border-amber-500/30"};return(0,o.jsxs)("div",{className:"jsx-c55aa17868d3279c "+((0,c.cn)("my-1 sm:my-2 w-full px-2 overflow-hidden",s)||""),children:[(0,o.jsx)("div",{className:"jsx-c55aa17868d3279c "+((0,c.cn)("history-bar mx-auto flex gap-1.5 sm:gap-2 flex-nowrap justify-center overflow-hidden py-1.5 px-2 sm:px-3 rounded-md sm:rounded-lg bg-card/40 border border-border/40 max-w-sm sm:max-w-xl min-h-[32px] sm:min-h-[40px]",u)||""),children:d.length>0?(0,o.jsx)(a.N,{initial:!1,children:d.map(e=>
1(0,o.jsxs)(r.P.div,{className:(0,c.cn)("flex flex-row items-center justify-center rounded border px-2 sm:px-3 py-1 sm:py-1.5 text-[10px] sm:text-sm leading-tight shadow-sm flex-shrink min-w-0 max-w-[120px] sm:max-w-[180px] gap-1 overflow-hidden",m[e.result]),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.25,ease:"easeOut"},children:[(0,o.jsx)("span",{className:"jsx-c55aa17868d3279c font-semibold leading-snug truncate",children:e.label}),"correct"!==e.result&&e.correctLabel&&(0,o.jsxs)("span",{className:"jsx-c55aa17868d3279c opacity-80 leading-snug text-[9px] sm:text-xs truncate",children:["â ",e.correctLabel]})]},e.id))}):i?(0,o.jsx)("div",{className:"jsx-c55aa17868d3279c flex w-full items-center justify-center text-[0.6rem] sm:text-xs tracking-[0.15em] sm:tracking-[0.2em] uppercase text-muted-foreground/70 px-1 text-center",children:i}):null}),(0,o.jsx)(l(),{id:"c55aa17868d3279c",children:".history-bar{white-space:nowrap}"})]})}},30078:(e,t,i)=>{i.r(t),i.d(t,{default:()=>y});var o=i(95155),s=i(12115),l=i(2178),n=i(25683),a=i(54294),r=i(63060),c=i(87338),u=i(43226),d=i(3115),m=i(89227),h=i(1628),p=i(32528),x=i(51569),g=i(11536),f=i(19507),b=i(19966),v=i(86877);let N=e=>{let[t,i]=e.split("/"),o=t.toUpperCase().match(/^([A-G])(##|#|BB|B|b|ââ|â|ðª|X)?$/);if(!o)return console.error("Failed to parse note:",t),e;let[,s,l]=o,n=null==l?void 0:l.toUpperCase();if("BB"===n||"ââ"===l){let e={C:"A#",D:"C",E:"D",F:"D#",G:"F",A:"G",B:"A"}[s];if("C"===s&&"A#"===e){let e=parseInt(i)-1;return"A#/".concat(e)}return"".concat(e,"/").concat(i)}if("B"===n||"â"===l){let e={DB:"C#",EB:"D#",FB:"E",GB:"F#",AB:"G#",BB:"A#",CB:"B"}["".concat(s,"B")];if("C"===s&&"B"===e){let e=parseInt(i)-1;return"B/".concat(e)}return"".concat(e||s,"/").concat(i)}if("##"===n||"\uD834\uDD2A"===l||"X"===n){let e={C:"D",D:"E",E:"F#",F:"G",G:"A",A:"B",B:"C#"}[s];if("B"===s&&"C#"===e){let e=parseInt(i)+1;return"C#/".concat(e)}return"".concat(e,"/").concat(i)}if("#"===l){if("E"===s)return"F/".concat(i);if("B"===s){let e=parseInt(i)+1;return"C/".concat(e)}}return"".concat(s).concat(l||"","/").concat(i)},S=function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=t?500:0,o=e=>{if(2!==e.split("/").length)return null;let[t,i]=N(e).split("/"),o=t.replace("#","#");return"".concat(o).concat(i)};if(t)e.forEach((e,t)=>{let s=o(e);s&&setTimeout(()=>{m.JD.playExerciseNote(s)},i*t)});else{let t=e.map(o).filter(e=>!!e);m.JD.playExerciseNotesFromSprite(t)}},y=e=>{let{settings:t,onBackToSettings:i,localVoicings:y,hideBackButton:w=!1,hideKeyboardHints:j=!1}=e,{playCorrect:V,playWrong:k}=(0,h.J)(),[C,B]=(0,s.useState)(null),[I,z]=(0,s.useState)([]),[D,E]=(0,s.useState)(""),[P,A]=(0,s.useState)("idle"),[J,M]=(0,s.use
1State)(!1),[U,T]=(0,s.useState)(""),[O,F]=(0,s.useState)(null),[_,G]=(0,s.useState)(!0),[H,R]=(0,s.useState)(!1),[$,K]=(0,s.useState)([]),L=(0,s.useRef)(!1),X=(0,s.useRef)([]),Q=(0,s.useRef)(Date.now()),W=(0,s.useRef)(!1);(0,s.useEffect)(()=>{W.current=!0},[]);let Z=(0,s.useCallback)(e=>!W.current&&e,[]),q=(0,s.useCallback)(function(e){let t=!(arguments.length>1)||void 0===arguments[1]||arguments[1];if(!t||!C||"checking"===P||"correct"===P)return;let{note:i,octave:o}=(0,p.T)(e),s="".concat(i).concat(o);m.JD.playUserNote(s);let l="".concat(i,"/").concat(o),n=[C.lowestNote,...JSON.parse(C.otherNotes)],a=N(l),r=l;for(let e of n)if(a===N(e)){r=e;break}let c=N(r),u=N(C.lowestNote);if(-1!==I.findIndex(e=>N(e)===c)){if(c===u)return;z([C.lowestNote,...I.filter(e=>N(e)!==u&&N(e)!==c)])}else z([C.lowestNote,...I.filter(e=>N(e)!==u),r]);L.current=!1,T(""),M(!1)},[C,I,P]),{midiInputs:Y,selectedInput:ee,setSelectedInput:et,error:ei}=(0,d.Z)(q);(0,s.useEffect)(()=>{if(C&&!_){R(!0);let e=setTimeout(()=>{S([C.lowestNote,...JSON.parse(C.otherNotes)]),setTimeout(()=>{R(!1)},1e3)},500);return()=>{clearTimeout(e),R(!1)}}},[C,_]),(0,s.useEffect)(()=>{if(!C||"idle"!==P||J||L.current)return;let e=JSON.parse(C.otherNotes),t=N(C.lowestNote),i=I.filter(e=>N(e)!==t);if(i.length===e.length&&i.length>0){let e=setTimeout(()=>{L.current=!0,el()},300);return()=>clearTimeout(e)}},[I,C,P,J]);let eo=(0,s.useCallback)(async()=>{try{var e;if(G(!0),y&&y.length>0){let e=C&&y.length>1?y.filter(e=>e.id!==C.id):y,t=e[Math.floor(Math.random()*e.length)];B(t),z([t.lowestNote]),A("idle"),M(!1),F(null),T(""),L.current=!1,Q.current=Date.now(),G(!1);return}let i=null!==(e=t.selectedVoicings)&&void 0!==e?e:[];if(0===X.current.length&&i.length>0){let e=await fetch("/api/jazz-voicings?voicingTypes=".concat(encodeURIComponent(i.join(","))),{headers:{Accept:"application/json"}});e.ok&&(X.current=await e.json())}let o=X.current;if(o.length>0){let e=o[Math.floor(Math.random()*o.length)];if(C&&o.length>1)for(let t=0;t<5&&e.id===C.id;t++)e=o[Math.floor(Math.random()*o.length)];B(e),z([e.lowestNote]),A("idle"),M(!1),F(null),T(""),L.current=!1,Q.current=Date.now(),G(!1)}else T("No voicings for the selected families. Pick at least one voicing family."),G(!1)}catch(e){console.error("Error fetching voicing:",e),T("Unable to load voicing. Please try again."),G(!1)}},[t.selectedVoicings,y,C]);(0,s.useEffect)(()=>{eo()},[]);let es=(0,s.useCallback)(e=>{if(!C)return;let{note:t,octave:i}=(0,p.T)(e),o="".concat(t).concat(i);m.JD.playUserNote(o);let s="".concat(t,"/").concat(i),l=[C.lowestNote,...JSON.parse(C.otherNotes)],n=N(s),a=s;for(let e of l)if(n===N(e)){a=e;break}let r=N(a),c=N(C.lowestNote);if(-1!==I.findIndex(e=>N(e)===r)){if(r===c)return;z([C.lowestNote,...I.filter(e=>N(e)!==c&&N(e)!==r)]),L.current=!1,T(""),M(!1)}else z([C.lowestNote,...I.filter(e=>N(e)!==c),a]),L.current=!1,T(""),M(!1)},[C,I]),el=(0,s.useCallback)(()=>{if("idle"!==P||(A("checking"),!C))return;let e=JSON.parse(C.otherNotes),t=N(C.lowestNote),i=I.filter(e=>N(e)!==t),o=e.map(e=>N(e)).sort(),s=i.map(e=>N(e)).sort();setTimeout(()=>{let e=s.length===o.length&&s.every((e,t)=>e===o[t]),t=C.name||"Voicing";e?((0,b.Ac)(),V(),T("".concat(t," â")),A("correct"),F(!0),M(!0),K(e=>[...e,{id:"".concat(Date.now(),"-").concat(Math.random().toString(36).slice(2,8)),label:t,result:"correct"}]),setTimeout(()=>{eo()},1500)):((0,b.Rm)(),k(),T("Try again! \uD83C\uDFB9"),A("idle"),F(!1),M(!0))},100)},[C,I,P,V,k,eo]),en=(0,s.useCallback)(e=>{if(!C)return;let[t,i]=N(e).split("/"),o="".concat(t).concat(i);m.JD.playUserNote(o);let s=[C.lowestNote,...JSON.parse(C.otherNotes)],l=N(e),n=e;for(let e of s)if(l===N(e)){n=e;break}let a=N(n),r=N(C.lowestNote);if(-1!==I.findIndex(e=>N(e)===a)){if(a===r)return;z([C.lowestNote,...I.filter(e=>N(e)!==r&&N(e)!==a)]),L.current=!1,T(""),M(!1)}else z([C.lowestNote,...I.filter(e=>N(e)!==r),n]),L.current=!1,T(""),M(!1)},[C,I]),ea=(0,s.useCallback)(()=>{C&&(z([C.lowestNote]),L.current=!1,A("idle"),M(!1),T(""))},[C]);return((0,x.B)({onSpacebar:()=>{C&&!H&&S([C.lowestNote,...JSON.parse(C.otherNotes)])},disabled:!C||H}),_&&!C)?(0,o.jsx)("div",{className:"flex items-center justify-center min-h-[600px]",children:(0,o.jsxs)(l.P.div,{initial:Z({opacity:0}
1),animate:{opacity:1},className:"flex flex-col items-center gap-4",children:[(0,o.jsx)("div",{className:"w-12 h-12 border-4 border-action border-t-transparent rounded-full animate-spin"}),(0,o.jsx)("p",{className:"text-muted-foreground",children:"Loading voicing..."})]})}):(0,o.jsxs)("div",{className:"relative w-full max-w-2xl mx-auto px-2 sm:px-4",children:[(0,o.jsxs)(l.P.div,{initial:Z({opacity:0,y:-20}),animate:{opacity:1,y:0},className:"mb-8 text-center",children:[(0,o.jsxs)("div",{className:"flex items-center justify-center gap-3 mb-2",children:[(0,o.jsx)(f.gKD,{className:"text-blue-500 text-3xl"}),(0,o.jsx)("h1",{className:"text-3xl font-bold bg-gradient-to-r from-blue-400 to-blue-500 bg-clip-text text-transparent",children:"Jazz Voicing Practice"}),(0,o.jsx)(f.gKD,{className:"text-blue-500 text-3xl"})]}),(0,o.jsx)("p",{className:"text-sm text-muted-foreground",children:"Listen carefully and identify the voicing you hear"})]}),(0,o.jsxs)(l.P.div,{initial:Z({opacity:0,scale:.95}),animate:{opacity:1,scale:1},transition:{delay:.2},className:"relative rounded-3xl bg-gradient-to-br from-blue-950/30 via-purple-950/20 to-pink-950/30 sm:backdrop-blur-xl border border-white/10 shadow-2xl overflow-hidden p-4 sm:p-8",children:[(0,o.jsx)("div",{className:"hidden sm:block absolute inset-0 bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-blue-900/20 via-transparent to-transparent pointer-events-none"}),(0,o.jsx)("div",{className:"hidden sm:block absolute inset-0 bg-[radial-gradient(ellipse_at_bottom,_var(--tw-gradient-stops))] from-purple-900/20 via-transparent to-transparent pointer-events-none"}),(0,o.jsxs)("div",{className:"relative z-10",children:[(0,o.jsx)(l.P.div,{initial:Z({opacity:0,y:10}),animate:{opacity:1,y:0},transition:{delay:.4},className:"text-center mb-8",children:(0,o.jsx)("p",{className:"text-base text-foreground/85",children:"The root note is shown below. Select the remaining notes you hear."})}),(0,o.jsxs)(l.P.div,{initial:Z({opacity:0,y:10}),animate:{opacity:1,y:0},transition:{delay:.5},className:"flex flex-wrap justify-center gap-3 mb-8",children:[(0,o.jsxs)(u.$,{onClick:()=>{C&&S([C.lowestNote,...JSON.parse(C.otherNotes)])},disabled:H,variant:"outline",className:"bg-action/20 hover:bg-action/30 border-action/30 text-action sm:backdrop-blur-sm transition-all duration-300 sm:hover:scale-105 focus-visible:scale-105",children:[(0,o.jsx)(g.gSK,{className:"mr-2"})," Play Harmonic"]}),(0,o.jsxs)(u.$,{onClick:()=>{C&&S([C.lowestNote,...JSON.parse(C.otherNotes)],!0)},disabled:H,variant:"outline",className:"bg-purple-600/20 hover:bg-purple-600/30 border-purple-500/30 text-purple-300 sm:backdrop-blur-sm transition-all duration-300 sm:hover:scale-105 focus-visible:scale-105",children:[(0,o.jsx)(g.gSK,{className:"mr-2"})," Play Melodic"]})]}),Y.length>0&&(0,o.jsxs)(l.P.div,{initial:Z({opacity:0}),animate:{opacity:1},transition:{delay:.6},className:"mb-6 flex items-center justify-center gap-3",children:[(0,o.jsx)("label",{htmlFor:"midi-input",className:"text-sm text-muted-foreground",children:"MIDI Input:"}),(0,o.jsxs)("select",{id:"midi-input",className:"px-3 py-1.5 rounded-lg bg-white/5 border border-white/10 text-sm focus:outline-none focus:border-action/50 transition-colors",value:(null==ee?void 0:ee.id)||"",onChange:e=>{et(Y.find(t=>t.id===e.target.value)||null)},children:[(0,o.jsx)("option",{value:"",children:"None"}),Y.map(e=>(0,o.jsx)("option",{value:e.id,children:e.name||e.manufacturer||e.id},e.id))]})]}),ei&&(0,o.jsx)(l.P.div,{initial:Z({opacity:0}),animate:{opacity:1},className:"text-red-400 text-sm text-center mb-4",children:ei}),(0,o.jsx)(l.P.div,{initial:Z({opacity:0,y:20}),animate:{opacity:1,y:0},transition:{delay:.3},className:"mb-6 flex justify-center",children:(0,o.jsx)("div",{className:"bg-white/5 sm:backdrop-blur-sm rounded-xl sm:rounded-2xl p-2 sm:p-6 border border-white/10 w-full flex justify-center",children:(0,o.jsxs)("div",{className:"relative inline-block",children:[(0,o.jsx)(a.Ve,{selectedNote:I,onNoteSelect:en,allowMultiple:!0,onClear:ea,overlayNotes:J&&C?[C.lowestNote,...JSON.parse(C.otherNotes)]:[],overlayColor:!0===O?"#10B981":!1===O?"#EF4444":"#3B82F6",useExternalTouchHandling:!0,onAccidentalChange:E}),(0,o.jsx)("div",{className:"absolute pointer-events-auto",style:{to
1p:"48px",left:"50%",transform:"translateX(-50%)",width:"".concat(a.U0,"px"),height:"".concat(a.mx,"px"),zIndex:100},children:(0,o.jsx)(r.D,{width:a.U0,height:a.mx,onNoteSelect:en,disabled:"checking"===P||"correct"===P,currentAccidental:D})})]})})}),(0,o.jsx)(v.A,{items:$,placeholder:"Answer history will appear here once you start guessing"}),(0,o.jsx)(l.P.div,{initial:Z({opacity:0,y:20}),animate:{opacity:1,y:0},transition:{delay:.4},className:"w-full",children:(0,o.jsx)("div",{className:"ear-glass backdrop-blur-sm rounded-xl p-4 border border-white/10",children:(0,o.jsx)(c.A,{firstNote:"C2",lastNote:"B5",onPlayNote:es,disabled:"checking"===P||"correct"===P})})}),(0,o.jsx)("div",{className:"mt-8 text-center h-[60px] flex items-center justify-center",children:(0,o.jsx)(n.N,{mode:"wait",children:U&&(0,o.jsx)(l.P.div,{initial:{opacity:0,scale:.9,y:-10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.9,y:-10},transition:{duration:.2},children:(0,o.jsx)("div",{className:"inline-block px-6 py-3 rounded-2xl font-semibold text-lg sm:backdrop-blur-sm ".concat(!0===O?"bg-green-500/20 text-green-300 border border-green-500/30":"bg-red-500/20 text-red-300 border border-red-500/30"),children:U})},U)})}),(0,o.jsxs)(l.P.div,{initial:Z({opacity:0}),animate:{opacity:1},transition:{delay:.7},className:"flex justify-center gap-4 mt-8",children:[(0,o.jsx)(u.$,{onClick:()=>eo(),variant:"outline",className:"bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 text-white border-0 transition-all duration-300 sm:hover:scale-105 focus-visible:scale-105 shadow-lg",children:"Next Voicing"}),!w&&(0,o.jsxs)(u.$,{onClick:i,variant:"outline",className:"hidden sm:flex bg-white/10 hover:bg-white/20 border-white/20 transition-all duration-300",children:[(0,o.jsx)(g.QVr,{className:"mr-2"})," Back to Settings"]})]}),!j&&(0,o.jsx)(l.P.div,{initial:Z({opacity:0}),animate:{opacity:1},transition:{delay:.8},className:"mt-6 text-center text-xs text-muted-foreground",children:(0,o.jsxs)("p",{children:["Press ",(0,o.jsx)("kbd",{className:"px-2 py-1 bg-white/10 rounded border border-white/20",children:"Space"})," to replay"]})})]})]})]})}}}]);
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.