1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[79817],{8052:(e,t,r)=>{r.d(t,{A:()=>n});let n=(0,r(74217).A)("volume-2",[["path",{d:"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",key:"uqj9uw"}],["path",{d:"M16 9a5 5 0 0 1 0 6",key:"1q6k2b"}],["path",{d:"M19.364 18.364a9 9 0 0 0 0-12.728",key:"ijwkga"}]])},10468:(e,t,r)=>{r.d(t,{A:()=>n});let n=(0,r(74217).A)("rotate-ccw",[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]])},18270:(e,t,r)=>{r.d(t,{A:()=>n});let n=(0,r(74217).A)("triangle-alert",[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]])},26483:(e,t,r)=>{r.d(t,{C:()=>s});var n=r(44976);let s=()=>{let[e,t]=(0,n.useState)(!1),[r,s]=(0,n.useState)(null),[a,i]=(0,n.useState)(null),[c,o]=(0,n.useState)(0),d=(0,n.useRef)(null),l=(0,n.useRef)([]),u=(0,n.useRef)(null),m=(0,n.useRef)(null),h=(0,n.useRef)(null),x=(0,n.useRef)(null),p=(0,n.useCallback)(()=>!!(navigator.mediaDevices&&navigator.mediaDevices.getUserMedia),[]),b=(0,n.useCallback)(()=>{o(0),m.current=setInterval(()=>{o(e=>e+1)},1e3)},[]),f=(0,n.useCallback)(()=>{m.current&&(clearInterval(m.current),m.current=null)},[]),g=(0,n.useCallback)(async()=>{if(!p())return i("Recording is not supported in this browser"),!1;try{i(null);let e=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,sampleRate:44100,channelCount:1}});u.current=e,l.current=[];let r="audio/wav";return!MediaRecorder.isTypeSupported("audio/wav")&&(MediaRecorder.isTypeSupported("audio/webm;codecs=opus")?r="audio/webm;codecs=opus":MediaRecorder.isTypeSupported("audio/webm")&&(r="audio/webm")),console.log("Recording with MIME type:",r),d.current=new MediaRecorder(e,{mimeType:r,audioBitsPerSecond:128e3}),d.current.ondataavailable=e=>{e.data.size>0&&l.current.push(e.data)},d.current.onstop=()=>{let e=new Blob(l.current,{type:r});console.log("Audio recorded successfully:",{size:e.size,type:e.type,chunks:l.current.length,duration:c}),s(e),u.current&&(u.current.getTracks().forEach(e=>e.stop()),u.current=null)},d.current.onerror=e=>{console.error("MediaRecorder error:",e),i("Recording error occurred")},h.current=Date.now(),x.current=null,d.current.start(250),t(!0),b(),!0}catch(e){return console.error("Error starting recording:",e),"NotAllowedError"===e.name?i("Microphone access denied. Please allow microphone access and try again."):"NotFoundError"===e.name?i("No microphone found. Please connect a microphone and try again."):"NotSupportedError"===e.name?i("Audio recording is not supported in this browser."):i("Failed to start recording. Please check your microphone and try again."),!1}},[p,b,c]),j=(0,n.useCallback)(()=>{d.current&&e&&(h.current&&(x.current=Date.now()),d.current.stop(),t(!1),f())},[e,f]),v=(0,n.useCallback)(()=>{s(null),o(0),i(null)},[]),y=(0,n.useCallback)(()=>{let e=Math.floor(c/60),t=c%60;return"".concat(e,":").concat(t.toString().padStart(2,"0"))},[c]),k=(0,n.useCallback)(()=>{if(r){let e=URL.createObjectURL(r),t=new Audio(e);return t.play().catch(e=>{console.error("Error playing audio:",e),i("Failed to play recording")}),t.addEventListener("ended",()=>{URL.revokeObjectURL(e)}),t}return null},[r]),w=(0,n.useCallback)(()=>{if(r){let e=(r.size/1048576).toFixed(2);return"".concat(e," MB")}return"0 MB"},[r]),N=(0,n.useCallback)(()=>{e&&j(),u.current&&u.current.getTracks().forEach(e=>e.stop()),m.current&&clearInterval(m.current)},[e,j]),S=h.current&&x.current?(x.current-h.current)/1e3:c;return{isRecording:e,recordedAudio:r,error:a,recordingTime:c,finalDuration:S,formattedTime:y(),audioSize:w(),isSupported:p(),startRecording:g,stopRecording:j,clearRecording:v,playRecording:k,cleanup:N,setError:e=>i(e)}}},33731:(e,t,r)=>{r.d(t,{A:()=>n});let n=(0,r(74217).A)("check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]])},41879:(e,t,r)=>{r.d(t,{A:()=>n});let n=(0,r(74217).A)("play",[["polygon",{points:"6 3 20 12 6 21 6 3",key:"1oa8hb"}]])},47401:(e,t,r)=>{function n(e){let t=Math.max(0,Math.round(e)),r=Math.floor(t/60);return"".concat(String(r).padStart(2,"0"),":").concat(String(t%60).padStart(2,"0"))}function s(e){if(!Number.isFinite(e))return"â";let t=Math.floor(e/60),r=Math.round(e%60);return"".concat(t,"m ").concat(String(r).padStart(2,"0"),"s")}function a(e){return Array.isArray(e)?e.length>0:null!=e&&""!==String(e).trim()}r.d(t,{a3:()=>s,ei:()=>n,lq:()=>a})},52350:(e,t,r)=>{r.d(t,{A:()=>n});let n=(0,r(74217).A)("chevron-left",[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]])},58489:(e,t,r)=>{r.d(t,{A:()=>n});let n=(0,r(74217).A)("clock",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polyline",{points:"12 6 12 12 16 14",key:"68esgv"}]])},60747:(e,t,r)=>{r.d(t,{A:()=>n});let n=(0,r(74217).A)("send",[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]])},79817:(e,t,r)=>{r.r(t),r.d(t,{default:()=>M});var n=r(23804),s=r(44976),a=r(64146),i=r(8052),c=r(22660),o=r(90494),d=r(56025),l=r(52350),u=r(58489),m=r(60747),h=r(33731),x=r(76935),p=r(18270),b=r(29037),f=r(10866),g=r(87789),j=r(43074),v=r(26483),y=r(41879),k=r(10468);
1function w(e){let{number:t,title:r,description:s,active:a,done:i,isLast:c,children:o}=e;return(0,n.jsxs)("div",{className:"flex gap-4",children:[(0,n.jsxs)("div",{className:"flex flex-col items-center flex-shrink-0",children:[(0,n.jsx)("div",{className:"w-9 h-9 rounded-full grid place-items-center border-2 transition-colors ".concat(i?"bg-module-accent border-module-accent text-white":a?"border-module-accent text-module-accent":"border-border text-muted-foreground"),children:i?(0,n.jsx)(h.A,{className:"w-4 h-4",strokeWidth:2.5}):(0,n.jsx)("span",{className:"text-sm font-bold",children:t})}),!c&&(0,n.jsx)("div",{className:"w-0.5 flex-1 min-h-[2rem] mt-1 ".concat(i?"bg-module-accent":"bg-border")})]}),(0,n.jsxs)("div",{className:"flex-1 pb-6 ".concat(a||i?"":"opacity-50"),children:[(0,n.jsx)("p",{className:"text-brand-body font-bold ".concat(i||a?"text-module-accent":"text-foreground"),children:r}),(0,n.jsx)("p",{className:"text-brand-caption text-muted-foreground mt-0.5 mb-3",children:s}),(a||i)&&o]})]})}function N(e){let{playing:t}=e;return(0,n.jsx)("div",{className:"flex items-center gap-0.5 h-8 flex-1",children:[40,70,30,90,50,65,35,80,45,60,30,75,40,55,25].map((e,r)=>(0,n.jsx)("div",{className:"w-1 rounded-full ".concat(t?"bg-module-accent":"bg-muted-foreground/30"),style:{height:"".concat(e,"%")}},r))})}function S(e){let{done:t,onConfirm:r}=e,[a,i]=(0,s.useState)(!1),[c,o]=(0,s.useState)(!1),d=(0,s.useRef)(null),l=(0,s.useCallback)(()=>{if(!a)try{var e;let t=window.AudioContext||window.webkitAudioContext,r=null!=(e=d.current)?e:new t;d.current=r;let n=r.createOscillator(),s=r.createGain();n.type="sine",n.frequency.value=440,s.gain.setValueAtTime(.15,r.currentTime),n.connect(s),s.connect(r.destination),i(!0),n.start(),n.stop(r.currentTime+1.2),n.onended=()=>{i(!1),o(!0)}}catch(e){i(!1),o(!0)}},[a]);return(0,n.jsxs)("div",{children:[(0,n.jsxs)("div",{className:"rounded-card border border-border bg-muted/30 p-3 flex items-center gap-3",children:[(0,n.jsx)("button",{type:"button",onClick:l,disabled:t,className:"w-9 h-9 rounded-full bg-module-accent text-white grid place-items-center flex-shrink-0 disabled:opacity-60",children:(0,n.jsx)(y.A,{className:"w-4 h-4 ml-0.5",strokeWidth:2,fill:"currentColor"})}),(0,n.jsx)(N,{playing:a}),(0,n.jsx)("span",{className:"text-brand-caption text-muted-foreground tabular-nums flex-shrink-0",children:"00:03"})]}),!t&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("p",{className:"text-brand-caption text-muted-foreground mt-2",children:"Click play to hear the sample tone, then confirm you can hear it."}),c&&(0,n.jsxs)(f.$,{size:"sm",onClick:r,className:"mt-3 bg-success/10 text-success border border-success/30 hover:bg-success/15",variant:"outline",children:[(0,n.jsx)(h.A,{className:"w-3.5 h-3.5 mr-1.5",strokeWidth:2.5}),"I can hear it clearly"]})]})]})}function C(e){let{done:t,onConfirm:r}=e,a=(0,v.C)(),[i,o]=(0,s.useState)(null);return(0,s.useEffect)(()=>{if(!a.recordedAudio)return void o(null);let e=URL.createObjectURL(a.recordedAudio);return o(e),()=>URL.revokeObjectURL(e)},[a.recordedAudio]),(0,n.jsxs)("div",{children:[(0,n.jsxs)("div",{className:"rounded-card border border-border bg-muted/30 p-3",children:[(0,n.jsx)("p",{className:"type-eyebrow text-muted-foreground mb-1",children:"Please read out loud:"}),(0,n.jsxs)("p",{className:"text-brand-body italic text-foreground mb-3",children:['"',"I love English. My English is great and I practice it every day!",'"']}),a.recordedAudio?(0,n.jsxs)("div",{className:"flex items-center gap-3",children:[(0,n.jsx)("audio",{src:i,controls:!0,className:"h-9 flex-1"}),!t&&(0,n.jsxs)("button",{type:"button",onClick:()=>a.clearRecording(),className:"inline-flex items-center gap-1 text-brand-caption text-muted-foreground hover:text-foreground flex-shrink-0",children:[(0,n.jsx)(k.A,{className:"w-3.5 h-3.5",strokeWidth:1.5}),"Re-record"]})]}):a.isRecording?(0,n.jsxs)(f.$,{size:"sm",variant:"outline",onClick:()=>a.stopRecording(),className:"border-destructive/40 text-destructive",children:["Stop (",a.formattedTime,")"]}):(0,n.jsxs)(f.$,{size:"sm",onClick:()=>a.startRecording(),disabled:t,className:"bg-module-accent text-white hover:bg-module-accent/90",children:[(0,n.jsx)(c.A,{className:"w-3.5 h-3.5 mr-1.5",strokeWidth:2}
1),"Start recording"]}),a.error&&(0,n.jsx)("p",{className:"text-brand-caption text-destructive mt-2",children:a.error})]}),!t&&a.recordedAudio&&(0,n.jsxs)(f.$,{size:"sm",onClick:r,className:"mt-3 bg-success/10 text-success border border-success/30 hover:bg-success/15",variant:"outline",children:[(0,n.jsx)(h.A,{className:"w-3.5 h-3.5 mr-1.5",strokeWidth:2.5}),"My microphone is working"]})]})}function A(e){let{onComplete:t,onExit:r}=e,[a,i]=(0,s.useState)(!1),[c,o]=(0,s.useState)(!1),d=a&&c;return(0,n.jsxs)("div",{className:"bg-background min-h-full",children:[(0,n.jsxs)("div",{className:"flex items-center justify-between px-4 sm:px-6 py-3 border-b border-border",children:[(0,n.jsxs)("button",{type:"button",onClick:r,className:"inline-flex items-center gap-1 text-brand-caption font-medium text-muted-foreground hover:text-foreground",children:[(0,n.jsx)(l.A,{className:"w-4 h-4",strokeWidth:1.5}),"Exit"]}),(0,n.jsx)("p",{className:"text-brand-body font-bold text-foreground",children:"Device Test"}),(0,n.jsx)("span",{className:"w-12","aria-hidden":"true"})]}),(0,n.jsxs)("div",{className:"max-w-2xl mx-auto px-4 sm:px-6 py-8 sm:py-10",children:[(0,n.jsxs)("div",{className:"text-center mb-6",children:[(0,n.jsx)("h1",{className:"text-brand-h2 font-bold text-foreground",children:"Device Test"}),(0,n.jsx)("p",{className:"text-brand-body text-muted-foreground mt-1",children:"Test if your recording device is working"})]}),(0,n.jsxs)("div",{className:"rounded-card border border-border bg-card p-5 sm:p-6",children:[(0,n.jsx)(w,{number:1,title:"Headphone check",description:"Make sure your headphone's audio is good enough before taking the test. Please click the play icon to check the sound quality.",active:!0,done:a,children:(0,n.jsx)(S,{done:a,onConfirm:()=>i(!0)})}),(0,n.jsx)(w,{number:2,title:"Microphone check",description:"Make sure your microphone works well before taking the test. Record audio and play it back to go next.",active:a,done:c,children:(0,n.jsx)(C,{done:c,onConfirm:()=>o(!0)})}),(0,n.jsx)(w,{number:3,title:"All good â ready to go!",description:"Your devices are working. Click the button below to begin your speaking exam.",active:d,done:!1,isLast:!0,children:d&&(0,n.jsxs)("div",{children:[(0,n.jsxs)("p",{className:"text-brand-caption text-success mb-3",children:[(0,n.jsx)(h.A,{className:"w-3.5 h-3.5 inline mr-1",strokeWidth:2.5}),"Headphones â \xb7 Microphone â"]}),(0,n.jsx)(f.$,{onClick:t,className:"bg-module-accent text-white hover:bg-module-accent/90 font-semibold",children:"Start Exam"})]})})]}),(0,n.jsxs)("p",{className:"text-center text-brand-caption text-muted-foreground mt-4",children:["Devices already tested?"," ",(0,n.jsx)("button",{type:"button",onClick:t,className:"text-module-accent font-semibold underline underline-offset-2",children:"Skip device test"})]})]})]})}var R=r(47401);function T(e){var t;let{item:r,saved:a,onSave:l,autoPlay:u,onAutoPlayed:m}
1=e,h=(0,v.C)(),[x,p]=(0,s.useState)(!1),[g,j]=(0,s.useState)(null!=(t=null==a?void 0:a.transcript)?t:""),[y,k]=(0,s.useState)(!1),w=(0,s.useRef)(null),N=!!(r.videoUrl||r.audioUrl);(0,s.useEffect)(()=>{var e;j(null!=(e=null==a?void 0:a.transcript)?e:""),h.clearRecording()},[r.questionId]);let S=(0,s.useCallback)(async()=>{h.stopRecording()},[h]),C=(0,s.useCallback)(()=>{let e=w.current;e&&(e.currentTime=0,e.play().catch(()=>{}))},[]);(0,s.useEffect)(()=>{if(!u||!N)return;let e=setTimeout(()=>{C(),null==m||m()},400);return()=>clearTimeout(e)},[r.questionId]),(0,s.useEffect)(()=>{var e;h.isRecording&&(null==(e=w.current)||e.pause())},[h.isRecording]);let A={onPlay:()=>k(!0),onPause:()=>k(!1),onEnded:()=>k(!1)};return(0,s.useEffect)(()=>{if(!h.recordedAudio||x)return;let e=!1;return(async()=>{p(!0);try{var t;let r=new FormData,n=h.recordedAudio.type.includes("webm")?"webm":"wav";r.append("file",h.recordedAudio,"answer.".concat(n));let s=await fetch("/api/ielts-speaking/transcribe",{method:"POST",body:r}),a=await s.json();if(e)return;(null==(t=a.text)?void 0:t.trim())?(j(a.text.trim()),l({transcript:a.text.trim(),audioDurationSeconds:h.finalDuration||h.recordingTime||30})):b.oR.error("Could not hear any speech in that recording â try again.")}catch(t){e||b.oR.error("Transcription failed. Try recording again.")}finally{e||p(!1)}})(),()=>{e=!0}},[h.recordedAudio]),(0,n.jsxs)("div",{className:"space-y-5",children:[r.videoUrl&&(0,n.jsx)("div",{className:"rounded-card border border-border bg-black overflow-hidden max-w-md mx-auto",children:(0,n.jsx)("video",{ref:w,src:r.videoUrl,playsInline:!0,preload:"auto",className:"w-full max-h-[36vh]",...A})}),!r.videoUrl&&r.audioUrl&&(0,n.jsx)("audio",{ref:w,src:r.audioUrl,preload:"auto",className:"hidden",...A}),N&&(0,n.jsx)("div",{className:"flex justify-center",children:(0,n.jsxs)("button",{type:"button",onClick:C,disabled:y||h.isRecording,className:"inline-flex items-center gap-2 h-9 px-4 rounded-full bg-muted border border-border text-brand-caption font-semibold text-foreground hover:bg-muted/70 transition-colors disabled:opacity-60",children:[(0,n.jsx)(i.A,{className:"w-4 h-4",strokeWidth:1.5}),y?"Playingâ¦":"Listen Again"]})}),(0,n.jsx)("div",{className:"rounded-card bg-module-accent/10 border border-module-accent/20 px-5 py-4 text-center",children:(0,n.jsx)("p",{className:"text-brand-body font-semibold text-foreground",children:r.prompt})}),(0,n.jsxs)("div",{className:"rounded-card border border-border bg-card p-4",children:[(0,n.jsx)("p",{className:"type-eyebrow text-muted-foreground mb-3",children:"Your answer"}),h.isRecording?(0,n.jsxs)(f.$,{onClick:S,className:"w-full h-12 bg-destructive text-white hover:bg-destructive/90 font-semibold text-brand-button",children:[(0,n.jsx)(o.A,{className:"w-4 h-4 mr-2",strokeWidth:1.5}),"Stop Recording (",h.formattedTime,")"]}):(0,n.jsxs)(f.$,{onClick:()=>h.startRecording(),disabled:x,className:"w-full h-12 bg-module-accent text-white hover:bg-module-accent/90 font-semibold text-brand-button",children:[(0,n.jsx)(c.A,{className:"w-4 h-4 mr-2",strokeWidth:1.5}),g?"Re-record":"Start Recording"]}),x&&(0,n.jsxs)("p",{className:"mt-3 inline-flex items-center gap-1.5 text-brand-caption text-muted-foreground",children:[(0,n.jsx)(d.A,{className:"w-3.5 h-3.5 animate-spin",strokeWidth:1.5}),"Transcribingâ¦"]}),h.error&&(0,n.jsx)("p",{className:"mt-3 text-brand-caption text-destructive",children:h.error}),g&&!h.isRecording&&!x&&(0,n.jsxs)("div",{className:"mt-3 rounded-btn bg-muted/40 border border-border p-3",children:[(0,n.jsx)("p",{className:"type-eyebrow text-muted-foreground mb-1",children:"Transcribed"}),(0,n.jsx)("p",{className:"text-brand-body text-foreground",children:g})]})]})]})}function M(e){var t,r,i,c,o,v,y;let{testSlug:k,embedded:w=!1,presetTestId:N=null,fullMockSessionId:S=null,onSectionComplete:C=null,onExitMock:M=null}=e,E=(0,a.useRouter)(),{showInsufficientCreditsModal:I,showExpiredCreditsModal:P,refresh:W}=(0,j.I)(),[L,q]=(0,s.useState)(!0),[O,U]=(0,s.useState)(null),[z,D]=(0,s.use
1State)(null),[$,F]=(0,s.useState)(null),[H,_]=(0,s.useState)(!1),[B,J]=(0,s.useState)({}),[Y,G]=(0,s.useState)(0),[Z,K]=(0,s.useState)(0),[Q,V]=(0,s.useState)(0),[X,ee]=(0,s.useState)("idle"),[et,er]=(0,s.useState)(!1),[en,es]=(0,s.useState)(!1),[ea,ei]=(0,s.useState)(!1),ec=(0,s.useRef)(new Set),eo=(0,s.useRef)(null),ed=(0,s.useRef)({}),el=(0,s.useRef)(!1),eu=(0,s.useRef)(!1),em=(0,s.useRef)(!1);(0,s.useEffect)(()=>{let e=!1;return(async()=>{try{var t,r,n,s;let a=await fetch("/api/ielts/speaking/attempt",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(N?{testId:N,fullMockSessionId:S}:{testSlug:k,fullMockSessionId:S})});if(401===a.status)return void E.push("/signin");if(402===a.status){let t=await a.json().catch(()=>({}));if(e)return;"expired"===t.reason?P():I(t.required),E.replace(k?"/ielts-speaking/tests/".concat(k):"/ielts-speaking");return}let i=await a.json();if(e)return;if(!i.success)throw Error(i.error||"Could not open the test");let c=null!=(r=i.attempt.answers)?r:{};D(i.test),F(i.attempt),(null==(t=i.billing)?void 0:t.charged)&&W(),J(c),ed.current=c;let o=w?Math.max(0,Math.round((Date.now()-new Date(i.attempt.startedAt).getTime())/1e3)):Math.max(0,null!=(n=i.attempt.timeTakenSeconds)?n:0);em.current=!w&&o>=(null!=(s=i.test.durationSeconds)?s:840),V(o),q(!1)}catch(t){e||(U(t.message),q(!1))}})(),()=>{e=!0}},[k,N,S,w,E]);let eh=null!=(i=null==z?void 0:z.durationSeconds)?i:840,ex=Math.max(0,eh-Q);(0,s.useEffect)(()=>{if(L||et||el.current||!H)return;let e=setInterval(()=>V(e=>e+1),1e3);return()=>clearInterval(e)},[L,et,H]);let ep=(0,s.useRef)(0),eb=(0,s.useRef)(840);(0,s.useEffect)(()=>{ep.current=Q},[Q]),(0,s.useEffect)(()=>{eb.current=eh},[eh]);let ef=null!=(c=null==$?void 0:$.id)?c:null,eg=(0,s.useCallback)(async()=>{if(ef&&!el.current){ee("saving");try{let e=await fetch("/api/ielts/speaking/attempt/".concat(ef),{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({answers:ed.current,timeTakenSeconds:Math.min(ep.current,3*eb.current)})}),t=await e.json();ee(t.success?"saved":"error")}catch(e){ee("error")}}},[ef]),ej=(0,s.useCallback)((e,t)=>{J(r=>{let n={...r,[e]:t};return ed.current=n,n}),eu.current=!0,clearTimeout(eo.current),eo.current=setTimeout(()=>{eu.current=!1,eg()},1500)},[eg]);(0,s.useEffect)(()=>{if(!ef)return;let e=()=>{el.current||(eu.current=!1,fetch("/api/ielts/speaking/attempt/".concat(ef),{method:"PATCH",headers:{"Content-Type":"application/json"},keepalive:!0,body:JSON.stringify({answers:ed.current,timeTakenSeconds:Math.min(ep.current,3*eb.current)})}).catch(()=>{}))};return window.addEventListener("pagehide",e),()=>{window.removeEventListener("pagehide",e),clearTimeout(eo.current),e()}},[ef]),(0,s.useEffect)(()=>{if(!ef)return;let e=setInterval(()=>{el.current||fetch("/api/ielts/speaking/attempt/".concat(ef),{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({answers:ed.current,timeTakenSeconds:Math.min(ep.current,3*eb.current)})}).catch(()=>{})},3e4);return()=>clearInterval(e)},[ef]);let ev=(0,s.useCallback)(async()=>{if(!el.current){el.current=!0,er(!0),es(!1);try{let e=await fetch("/api/ielts/speaking/attempt/".concat(ef,"/submit"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({answers:ed.current,timeTakenSeconds:Math.min(ep.current,3*eb.current)})}),t=await e.json();if(!t.success)throw Error(t.error||"Could not submit");if(w){null==C||C(t.attemptId);return}E.push("/ielts-speaking/result/".concat(t.attemptId))}catch(e){el.current=!1,er(!1),b.oR.error(e.message)}}},[ef,z,E,w,C]),ey=(0,s.useRef)(ev);(0,s.useEffect)(()=>{ey.current=ev},[ev]);let ek=(0,s.useRef)(!1);if((0,s.useEffect)(()=>{L||el.current||!H&&!w||ex>0||ek.current||em.current||(ek.current=!0,ey.current())},[L,ex,H,w]),!H)return(0,n.jsx)(A,{onComplete:()=>_(!0),onExit:()=>w?null==M?void 0:M():E.push("/ielts-speaking")});if(L)return(0,n.jsx)("div",{className:"min-h-[70vh] grid place-items-center",children:(0,n.jsxs)("div",{className:"text-center",children:[(0,n.jsx)(d.A,{className:"w-6 h-6 animate-spin mx-auto mb-3 text-module-accent",strokeWidth:1.5}),(0,n.jsx)("p",{className:"text-brand-body text-muted-foreground",children:"Opening your testâ¦"})]})});if(O)return(0,n.jsx)("div",{className:"min-h-[70vh] grid place-items-center px-4",children:(0,n.jsxs)("div",{className:"text-center max-w-sm",children:[(0,n.jsx)("p",{className:"text-brand-h3 font-semibold text-foreground mb-2",children:"We couldn't start this test"}),(0,n.jsx)("p",{className:"text-brand-body text-muted-foreground mb-5",children:O}),(0,n.jsx)(f.$,{variant:"outline",onClick:()=>E.push(w?"/ielts-full-mock":"/ielts-speaking"),children:"Back"})]})});let ew=null!=(o=z.parts[Y])?o:z.parts[0],eN=null!=(v=ew.items[Z])?v:ew.items[0],eS=z.parts.reduce((e,t)=>
1e+t.items.filter(e=>{var t,r;return null==(r=B[e.questionId])||null==(t=r.transcript)?void 0:t.trim()}).length,0),eC=ex<=120,eA=Y===z.parts.length-1&&Z===ew.items.length-1,eR="".concat(null!=(y=null==(t=z.book)?void 0:t.title)?y:z.title," \xb7 Speaking Test ").concat(String(z.testNumber).padStart(2,"0"));return(0,n.jsxs)("div",{className:"h-full min-h-0 flex flex-col bg-background",children:[(0,n.jsxs)("div",{className:"border-b border-border bg-card",children:[(0,n.jsxs)("div",{className:"h-14 grid grid-cols-[1fr_auto_1fr] items-center gap-3 px-3 sm:px-5",children:[(0,n.jsxs)("div",{className:"flex items-center gap-3 min-w-0 justify-self-start",children:[(0,n.jsxs)("button",{type:"button",onClick:()=>ei(!0),className:"inline-flex items-center gap-1 text-brand-caption font-medium text-muted-foreground hover:text-foreground flex-shrink-0",children:[(0,n.jsx)(l.A,{className:"w-4 h-4",strokeWidth:1.5}),"Exit"]}),(0,n.jsx)("span",{className:"hidden sm:block w-px h-5 bg-border flex-shrink-0","aria-hidden":!0}),(0,n.jsx)("p",{className:"hidden sm:block text-brand-caption font-bold text-foreground truncate",children:eR})]}),(0,n.jsxs)("span",{className:"inline-flex items-center gap-1.5 h-9 px-3 rounded-btn border tabular-nums font-bold justify-self-center ".concat(eC?"border-destructive/40 bg-destructive/10 text-destructive":"border-border bg-muted text-foreground"),role:"timer","aria-live":"off",children:[(0,n.jsx)(u.A,{className:"w-4 h-4",strokeWidth:1.5}),(0,R.ei)(ex)]}),(0,n.jsxs)("div",{className:"flex items-center gap-3 justify-self-end",children:[(0,n.jsx)("span",{className:"hidden md:inline text-brand-caption text-muted-foreground",children:"saving"===X?"Savingâ¦":"saved"===X?"Saved":"error"===X?"Save failed":""}),(0,n.jsx)(f.$,{size:"sm",onClick:()=>es(!0),disabled:et,className:"bg-module-accent text-white hover:bg-module-accent/90",children:et?(0,n.jsx)(d.A,{className:"w-4 h-4 animate-spin",strokeWidth:1.5}):(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(m.A,{className:"w-4 h-4 mr-1.5",strokeWidth:1.5}),"Submit"]})})]})]}),(0,n.jsx)("div",{className:"flex items-center justify-center px-4 py-2 border-t border-border",children:(0,n.jsx)("div",{className:"inline-flex rounded-btn border border-border bg-background p-0.5",children:z.parts.map((e,t)=>{let r=e.items.every(e=>{var t,r;return null==(r=B[e.questionId])||null==(t=r.transcript)?void 0:t.trim()});return(0,n.jsxs)("button",{onClick:()=>{G(t),K(0)},"aria-pressed":Y===t,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md text-brand-caption font-semibold transition-colors ".concat(Y===t?"bg-module-accent text-white":"text-muted-foreground hover:text-foreground"),children:["Part ",e.partNumber,r&&(0,n.jsx)(h.A,{className:"w-3.5 h-3.5",strokeWidth:2})]},e.id)})})})]}),em.current&&(0,n.jsx)("div",{className:"px-4 sm:px-6 py-2 bg-destructive/10 border-b border-destructive/20 text-brand-caption text-destructive text-center",children:"Time is up for this sitting. Answer what you can and press Submit â it will not submit itself."}),(0,n.jsx)("div",{className:"flex-1 min-h-0 overflow-y-auto px-4 sm:px-6 py-6",children:(0,n.jsxs)("div",{className:"max-w-2xl mx-auto",children:[(0,n.jsxs)("p",{className:"type-eyebrow text-muted-foreground mb-2 text-center",children:["Part ",ew.partNumber," \xb7 Question ",Z+1," of ",ew.items.length]}),(0,n.jsxs)("h2",{className:"text-brand-h2 font-bold text-foreground mb-5 text-center",children:["Part ",ew.partNumber,": ",ew.title]}),eN.cueCardPoints&&eN.cueCardPoints.length>0&&(0,n.jsxs)("div",{className:"rounded-card border border-border bg-card p-4 mb-5",children:[(0,n.jsx)("p",{className:"type-eyebrow text-muted-foreground mb-2",children:"You should say:"}),(0,n.jsx)("ul",{className:"list-disc list-inside space-y-1",children:eN.cueCardPoints.map((e,t)=>(0,n.jsx)("li",{className:"text-brand-body text-foreground",children:e},t))})]}),(0,n.jsx)(T,{item:eN,saved:B[eN.questionId],onSave:e=>ej(eN.questionId,e),autoPlay:!ec.current.has(eN.questionId)&&!(null==(r=B[eN.questionId])?void 0:r.transcript),onAutoPlayed:()=>ec.current.add(eN.questionId)},eN.questionId),(0,n.jsxs)("div",{className:"flex items-center justify-between mt-6",children:[(0,n.jsxs)(f.$,{variant:"outline",disabled:0===Y&&0===Z,onClick:()=>
1{if(Z>0)K(Z-1);else if(Y>0){let e=z.parts[Y-1];G(Y-1),K(e.items.length-1)}},children:[(0,n.jsx)(l.A,{className:"w-4 h-4 mr-1",strokeWidth:1.5}),"Previous"]}),(0,n.jsxs)(f.$,{onClick:()=>{Z<ew.items.length-1?K(Z+1):Y<z.parts.length-1?(G(Y+1),K(0)):es(!0)},className:"bg-module-accent text-white hover:bg-module-accent/90",children:[eA?"Review & submit":"Next",(0,n.jsx)(x.A,{className:"w-4 h-4 ml-1",strokeWidth:1.5})]})]})]})}),(0,n.jsx)(g.Lt,{open:en,onOpenChange:es,children:(0,n.jsxs)(g.EO,{children:[(0,n.jsxs)(g.wd,{children:[(0,n.jsx)(g.r7,{children:"Submit the speaking test?"}),(0,n.jsx)(g.$v,{asChild:!0,children:(0,n.jsxs)("div",{className:"space-y-2",children:[(0,n.jsxs)("p",{children:[eS," of ",z.parts.reduce((e,t)=>e+t.items.length,0)," items answered."]}),0===eS&&(0,n.jsx)("p",{className:"text-warning",children:"You haven't recorded any answers yet."}),(0,n.jsx)("p",{children:"Marking takes a few seconds, and you cannot re-record afterwards."})]})})]}),(0,n.jsxs)(g.ck,{children:[(0,n.jsx)(g.Zr,{children:"Keep going"}),(0,n.jsx)(g.Rx,{onClick:ev,children:"Submit"})]})]})}),(0,n.jsx)(g.Lt,{open:ea,onOpenChange:ei,children:(0,n.jsxs)(g.EO,{children:[(0,n.jsxs)(g.wd,{children:[(0,n.jsxs)(g.r7,{className:"flex items-center gap-2",children:[(0,n.jsx)(p.A,{className:"w-5 h-5 text-warning",strokeWidth:1.5}),"Leave this test?"]}),(0,n.jsx)(g.$v,{children:w?(0,n.jsx)(n.Fragment,{children:"Leaving ends your full mock. It cannot be resumed, the credits are not refunded, and it will not get an overall band. Sections you have already finished stay in your reports."}):(0,n.jsx)(n.Fragment,{children:"Your answers are saved. The clock pauses while you are away â pick this test up from the library and it continues where you left off."})})]}),(0,n.jsxs)(g.ck,{children:[(0,n.jsx)(g.Zr,{children:"Stay"}),(0,n.jsx)(g.Rx,{onClick:async()=>{if(await eg(),w){null==M||M();return}E.push("/ielts-speaking")},children:w?"End the mock":"Leave"})]})]})})]})}},90494:(e,t,r)=>{r.d(t,{A:()=>n});let n=(0,r(74217).A)("square",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]])}}]);
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.