1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-BMLbwVmD.css","assets/PricingModal-C3eThBVu.css"])))=>i.map(i=>d[i]); 2import{u as F,a as J,aT as de,aU as me,aV as fe,aW as B,P as he,K as pe,aa as ge,_ as G}from"./index-VzCPatgX.js";import{r,j as s}from"./react-vendor-Celz-2fn.js";/* empty css */import{u as X}from"./useLocalizedNavigate-BJzuaEqK.js";import{Q as xe,A as ve}from"./AnalysisView-9wQcciXx.js";import{L as we,a as be}from"./ListeningAnalysisView-Dj-kc_dX.js";import{C as Se}from"./ConfirmDialog-BCZwcEVu.js";import{c as ye,b as Ne,u as je}from"./useQuestionCharge-B3lc2hDk.js";import{c as Ae}from"./examScoring-QWhLhmyh.js";import{c as Ce}from"./achievements-B4G56tbM.js";import{g as ke}from"./streak-D85F2gnt.js";import{g as Ie}from"./i18n-CkSDoCal.js";import{i as V,H as Pe,A as Re,a5 as qe,ah as Ee}from"./libs-vendor-CzM8KNR6.js";import{F as Y,c as Qe,E as _e}from"./PageStatus-8biKI0vg.js";import{S as De}from"./SkeletonLoader-D5elwXVN.js";import{e as Le}from"./vendor-S-J9ZazT.js";import"./useR2Src-DsI_tTm1.js";import"./analysisCache-CGU_q5eT.js";import"./audioSpeed-BOKbGJpD.js";import"./postPaymentReturn-BJ-cWjWI.js";import"./ShareResultPanel-Dgdm3lO_.js";import"./freeQuotaCharge-BZno-wsy.js";import"./supabase-C_v1m5mF.js";import"./supabase-vendor-BTZ5uhR1.js";(function(){try{var n=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};n.SENTRY_RELEASE={id:"b49a520c0c446c72dc60d814870565ed522e908d"};var t=new n.Error().stack;t&&(n._sentryDebugIds=n._sentryDebugIds||{},n._sentryDebugIds[t]="274b6573-43cc-4f56-8612-c6a2db8421c5",n._sentryDebugIdIdentifier="sentry-dbid-274b6573-43cc-4f56-8612-c6a2db8421c5")}catch{}})();const K={zh:{title:"ç¡®å®éåºï¼",message:"éåºåæ¬æ¬¡å·é¢è¿åº¦ä¸ä¼ä¿åï¼éé¢å·²åå ¥é颿¬ï¼ãç¡®å®éåºåï¼",confirm:"éåº",cancel:"ç»§ç»å·é¢"},en:{title:"Quit?",message:"Your current drill progress will not be saved (wrong answers are already saved to Review). Quit now?",confirm:"Quit",cancel:"Continue"},fr:{title:"Quitter ?",message:"Votre progression actuelle ne sera pas sauvegardée (les erreurs sont déjà enregistrées dans Révision). Quitter maintenant ?",confirm:"Quitter",cancel:"Continuer"}},Te=({questions:n,currentIndex:t,answers:a,subtitleText:u,subtitleClassName:o,onPrev:i,onNext:h,hasPrev:g,hasNext:d,onQuit:m,children:e,embedded:x=!1})=>{const{language:j}=F();ye(!0);const[R,k]=r.useState(!1),A=K[j]||K.fr,p=n.length,q=t+1,l=t>0?t:null,D=t<n.length-1?t+2:null,C=p>0?(t+1)/p*100:0;return s.jsxs("div",{className:`app-container practice-mode${x?" embedded":""}`,children:[s.jsx("div",{className:`subtitle-bar${o?` ${o}`:""}`,children:u}),s.jsxs("div",{className:"mobile-timer-bar",children:[s.jsx("div",{className:"mobile-timer-progress",children:s.jsx("div",{className:"progress-bar green",style:{width:`${C}%`}})}),s.jsxs("div",{className:"mobile-timer-text",children:[t+1," / ",p]}),s.jsxs("div",{className:"mobile-answer-count",children:[a.length,"/",p]})]}),s.jsxs("div",{className:"main-content",children:[s.jsxs("aside",{className:"question-nav",children:[s.jsxs("div",{className:"nav-header-row",children:[s.jsx("span",{className:"nav-prev-num",children:l||""}),s.jsx("div",{className:`nav-arrow-btn ${g?"":"disabled"}`,onClick:()=>g&&i(),children:s.jsx("span",{className:"arrow-icon",children:"â"})}),s.jsx("span",{className:"nav-current-num",children:q}),s.jsx("div",{className:`nav-arrow-btn ${d?"":"disabled"}`,onClick:()=>d&&h(),children:s.jsx("span",{className:"arrow-icon",children:"â"})}),s.jsx("span",{className:"nav-next-num",children:D||""})]}),s.jsx("div",{className:"question-list question-list-full",children:n.map((I,P)=>{const E=a.find(Q=>Q.questionId===I.id),f=P===t,L=E?"answered":"";return s.jsxs("div",{className:`question-item ${f?"active":""} ${L}`,children:[f&&s.jsx("span",{className:"item-arrow left",children:"â"}),s.jsx("span",{className:"item-number",children:P+1}),f&&s.jsx("span",{className:"item-arrow right",children:"â"})]},I.id)})})]}),s.jsx("main",{className:"question-area",children:e})]}),s.jsxs("footer",{className:"bottom-bar",children:[s.jsx("div",{style:{flex:1}}),s.jsxs("div",{className:"bottom-info",children:[s.jsx("span",{className:"answer-count",children:a.length})," réponses données sur ",p]}),s.jsx("button",{className:"exit-button red tactile-press",onClick:()=>
2k(!0),children:"Quitter"})]}),s.jsx(Se,{isOpen:R,title:A.title,message:A.message,confirmText:A.confirm,cancelText:A.cancel,onConfirm:()=>{k(!1),m()},onCancel:()=>k(!1),variant:"danger"})]})};function Fe({module:n,difficulty:t,questions:a,answers:u,onRestart:o,onExit:i}){const h=X(),{user:g}=J(),{language:d}=F(),m=Ie(d),e=d||"en",x=(p,q,l)=>e==="zh"?p:e==="fr"?l:q,j=Ae(a,u,n);r.useEffect(()=>{ke(g?.id).then(p=>Ce({score:j.weightedPercent,streak:p})).catch(p=>console.error("[DrillResult] getStreak failed:",p))},[]);const R=n==="reading"?V:Pe,k=n==="reading"?m.readingComprehension:m.listeningComprehension,A=[{label:x("åç»ä¸ç»","Practice again","Encore une série"),variant:"primary",icon:s.jsx(qe,{className:"w-4 h-4"}),onClick:o},{label:x("æ¢ä¸ªé¾åº¦","Change level","Changer de niveau"),variant:"secondary",icon:s.jsx(Ee,{className:"w-4 h-4"}),onClick:i}];return j.incorrect>0&&A.push({label:x("å»é颿¬å¤ä¹ ","Review wrong answers","Réviser les erreurs"),variant:"ghost",icon:s.jsx(V,{className:"w-4 h-4"}),onClick:()=>h("/mistake-book")}),s.jsxs("div",{className:"min-h-screen flex flex-col font-display-sans",style:{background:"hsl(var(--background))"},children:[s.jsxs("header",{className:"px-3 sm:px-6 py-3 sm:py-4 flex items-center justify-between",style:{background:"hsl(var(--background))",borderBottom:"1px solid hsl(var(--border))"},children:[s.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[s.jsx("div",{className:"shrink-0 inline-flex items-center justify-center rounded-lg",style:{width:36,height:36,border:"1px solid hsl(var(--border))",background:"hsl(var(--card))"},children:s.jsx(R,{className:"w-4 h-4",style:{color:"hsl(var(--foreground))"}})}),s.jsxs("h1",{className:"truncate",style:{fontFamily:"'Albert Sans', 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Source Han Sans SC', 'Noto Sans CJK SC', 'WenQuanYi Micro Hei', Arial, sans-serif",fontWeight:800,fontSize:"clamp(15px, 2vw, 20px)",lineHeight:1.1,letterSpacing:"-0.018em",color:"hsl(var(--foreground))",margin:0},children:[x("ä¸é¡¹ç»ä¹ ","Drill","Entraînement")," · ",k," · ",t]})]}),s.jsxs("button",{onClick:i,type:"button",className:"tactile-press inline-flex items-center gap-2 rounded-lg",style:{fontFamily:"'Albert Sans', 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Source Han Sans SC', 'Noto Sans CJK SC', 'WenQuanYi Micro Hei', Arial, sans-serif",fontWeight:700,fontSize:13,padding:"8px 14px",background:"transparent",color:"hsl(var(--foreground))",border:"1.5px solid hsl(var(--border))",cursor:"pointer",letterSpacing:"0.02em"},children:[s.jsx("span",{className:"hidden sm:inline",children:x("éåº","Exit","Quitter")}),s.jsx(Re,{className:"w-4 h-4"})]})]}),s.jsx("div",{className:"practice-mode px-3 sm:px-6 py-6",children:s.jsx(Ne,{breakdown:j,module:n,ctas:A,drillLevel:t})})]})}const Me=60,Z=(n,t)=>`tcf_drill_seen_${n}_${t}`;function ee(n,t){try{const a=localStorage.getItem(Z(n,t));if(!a)return[];const u=JSON.parse(a);return Array.isArray(u)?u.filter(o=>typeof o=="string"):[]}catch{return[]}}function He(n,t,a){try{const o=[...ee(n,t),...a].slice(-Me);localStorage.setItem(Z(n,t),JSON.stringify(o))}catch{}}function Ue({module:n,difficulty:t,count:a,onQuestionAnswered:u}){const{user:o}=J(),i=o?.id,[h,g]=r.useState(!0),[d,m]=r.useState(null),[e,x]=r.useState([]),[j,R]=r.useState(0),[k,A]=r.useState(0),[p,q]=r.useState(!1),[l,D]=r.useState(0),[C,I]=r.useState(""),[P,E]=r.useState(!1),[f,L]=r.useState([]),[Q,M]=r.useState(!1),[se,H]=r.useState(!1),U=r.useRef(new Set),$=r.useRef(u);$.current=u;const T=r.useRef("");T.current||(T.current=typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,10)}`),r.useEffect(()=>{i&&de(i)},[i]);const O=r.useRef(!1);r.useEffect(()=>{if(O.current)return;O.current=!0;let c=!1;return g(!0),m(null),(async()=>{try{const S=ee(n,t),b=n==="reading"?await B("reading",t,a,S):await B("listening",t,a,S);if(c)return;const y=b.questions;y.length>0&&He(n,t,y.map(_=>_.id)),x(y),R(b.poolSize),A(b.effectiveCount),q(b.effectiveCount<a),g(!1)}catch(S){if(c)return;m(S),g(!1)}})(),()=>{c=!0}},[n,t,a]);
2const w=e[l]||null,ne=f[l],te=r.useCallback(async()=>{if(!w||!C||P)return;const c=C===w.correctAnswer,v={questionId:w.id,selectedAnswer:C,isCorrect:c,timestamp:Date.now()};L(N=>{const z=[...N];return z[l]=v,z});const S=w.id,b=$.current;if(b&&!U.current.has(S))try{const{exceeded:N}=await b(S);if(N){H(!0);return}U.current.add(S)}catch(N){console.error("[Quota] drill per-question charge failed (non-blocking):",N)}E(!0);const y=w.difficulty||t,_=C;me({questionId:w.id,module:n,cefr:y,isCorrect:c,userAnswer:_,sessionId:T.current,userId:i}),c||fe(w.id,C,w.correctAnswer,w.difficulty||t,i).catch(N=>console.error("addDrillMistake failed:",N))},[w,C,P,l,i,t,n]),re=r.useCallback(()=>{if(l<e.length-1){const c=l+1,v=f[c];D(c),I(v?.selectedAnswer||""),E(!!v)}else M(!0)},[l,e.length,f]),ae=r.useCallback(()=>{if(l>0){const c=l-1,v=f[c];D(c),I(v?.selectedAnswer||""),E(!!v)}},[l,f]),ie=r.useCallback(()=>{M(!0)},[]),oe=r.useCallback(()=>H(!1),[]),ce=r.useMemo(()=>{if(!Q)return null;const c=f.filter(Boolean).length,v=f.filter(y=>y?.isCorrect).length,S=c-v,b={};return f.forEach((y,_)=>{if(y&&!y.isCorrect){const N=e[_]?.difficulty||"unknown";b[N]=(b[N]||0)+1}}),{total:c,correct:v,wrong:S,percent:c>0?Math.round(v/c*100):0,byDifficultyWrong:b}},[Q,f,e]),le=l<e.length-1,ue=l>0;return{loading:h,error:d,poolSize:j,effectiveCount:k,trialLimited:p,questions:e,currentIndex:l,currentQuestion:w,selectedAnswer:C,setSelectedAnswer:I,showAnalysis:P,answers:f,currentUserAnswer:ne,hasNext:le,hasPrevious:ue,handleSubmit:te,handleNext:re,handlePrevious:ae,handleFinish:ie,dismissQuotaExceeded:oe,quotaExceeded:se,finished:Q,stats:ce}}const W=r.lazy(()=>G(()=>import("./PricingModal-C3RO_SEg.js"),__vite__mapDeps([0,1]))),$e=r.lazy(()=>G(()=>import("./index-VzCPatgX.js").then(n=>n.bw),__vite__mapDeps([0]))),Oe=["A1","A2","B1","B2","C1"],ze=[10,20,30];function Be({module:n,difficulty:t,count:a,onRestart:u,onExit:o,embedded:i=!1}){const{t:h}=F(),g=je(n),[d,m]=r.useState(!1),e=Ue({module:n,difficulty:t,count:a,onQuestionAnswered:g});if(d)return s.jsx(r.Suspense,{fallback:null,children:s.jsx($e,{isOpen:!0,onClose:()=>m(!1),onLoginSuccess:()=>m(!1),defaultTab:"register"})});if(e.quotaExceeded)return sessionStorage.setItem("postPaymentReturnUrl",window.location.pathname+window.location.search),s.jsx(r.Suspense,{fallback:null,children:s.jsx(W,{isOpen:!0,onClose:o,onLoginRequired:()=>{m(!0)},reason:"free_quota_exceeded"})});if(e.loading)return s.jsx(De,{variant:"question"});if(e.error){if(e.error instanceof he)return s.jsx(Y,{children:s.jsxs("div",{style:{textAlign:"center"},children:[s.jsx("p",{children:h("drill.session.proRequired").replace("{level}",t)}),s.jsx("button",{onClick:o,style:{marginTop:16,padding:"8px 24px",background:"hsl(var(--primary))",border:"1px solid hsl(var(--primary))",color:"hsl(var(--primary-foreground))",borderRadius:999,cursor:"pointer"},children:h("drill.session.backHome")})]})});if(e.error instanceof pe)return sessionStorage.setItem("postPaymentReturnUrl",window.location.pathname+window.location.search),s.jsx(r.Suspense,{fallback:null,children:s.jsx(W,{isOpen:!0,onClose:o,onLoginRequired:()=>{m(!0)},reason:"free_quota_exceeded"})});const j=e.error instanceof ge?{kind:"rateLimit",retryAfterSec:e.error.retryAfter,requestId:e.error.requestId}:Qe(e.error);return s.jsx(_e,{info:j,onRetry:u,moduleName:"drill"})}if(!e.currentQuestion)return s.jsx(Y,{children:s.jsxs("div",{style:{textAlign:"center"},children:[s.jsx("p",{children:h("drill.session.noQuestions")}),s.jsx("button",{onClick:o,style:{marginTop:16,padding:"8px 24px",background:"rgba(255,255,255,0.2)",border:"1px solid rgba(255,255,255,0.4)",color:"white",borderRadius:999,cursor:"pointer"},children:h("drill.session.backHome")})]})});if(e.finished)return s.jsx(Fe,{module:n,difficulty:t,questions:e.questions,answers:e.answers,onRestart:u,onExit:o});const x=h(`drill.session.subtitle.${n}`).replace("{difficulty}",t).replace("{count}",String(e.questions.length));return s.jsx(Te,{questions:e.questions,currentIndex:e.currentIndex,answers:e.answers,subtitleText:x,subtitleClassName:n==="listening"?"listening":void 0,onPrev:e.handlePrevious,onNext:e.handleNext,hasPrev:e.hasPrevious,hasNext:e.hasNext,onQuit:o,embedded:i,children:e.showAnalysis?n==="reading"?s.jsx(ve,{question:e.currentQuestion,userAnswer:e.currentUserAnswer,onNext:e.handleNext,onPrevious:e.handlePrevious,hasNext:e.hasNext,hasPrevious:e.hasPrevious,onFinish:e.hasNext?void 0:e.handleFinish,displayNumber:e.currentIndex+1}):s.jsx(be,{question:e.currentQuestion,userAnswer:e.currentUserAnswer,onNext:e.handleNext,onPrevious:e.handlePrevious,hasNext:e.hasNext,hasPrevious:e.hasPrevious,onFinish:e.hasNext?void 0:e.handleFinish,displayNumber:e.currentIndex+1}):n==="reading"?s.jsx(xe,{question:e.currentQuestion,selectedAnswer:e.selectedAnswer,onSelectAnswer:e.setSelectedAnswer,onSubmit:e.handleSubmit,displayNumber:e.currentIndex+1}):s.jsx(we,{question:e.currentQuestion,selectedAnswer:e.selectedAnswer,onSelectAnswer:e.setSelectedAnswer,onSubmit:e.handleSubmit,displayNumber:e.currentIndex+1})})}const gs=({embedded:n=!1}
2)=>{const t=X(),[a]=Le(),[u,o]=r.useState(0),i=r.useMemo(()=>{const d=a.get("module"),m=a.get("difficulty"),e=parseInt(a.get("count")||"",10);return(d==="reading"||d==="listening")&&Oe.includes(m)&&ze.includes(e)?{module:d,difficulty:m,count:e}:null},[a]);if(r.useEffect(()=>{i||t(n?"/practice/difficulty/reading":"/practice/by-difficulty",{replace:!0})},[i,t,n]),!i)return null;const h=()=>t(n?`/practice/difficulty/${i.module}`:"/practice/by-difficulty"),g=()=>o(d=>d+1);return s.jsx(Be,{module:i.module,difficulty:i.difficulty,count:i.count,onRestart:g,onExit:h,embedded:n},u)};export{gs as default};
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.