@mathwiz/ui-components 0.1.27 → 0.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -250,6 +250,6 @@ ${new Error().stack?.split(`
250
250
  }
251
251
  `;const Iu="/api/v1/content",Fu="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJ1c2VyLTAwMSIsIm5hbWUiOiLlsI_mmI4iLCJsZXZlbCI6NSwiYXZhdGFyIjoiaHR0cHM6Ly9pLnByYXZhdGFyLmNjLzQwP3U9c3R1ZGVudDEiLCJiYWRnZXMiOlsi8J-SoiIsIvCfjZUiLCLwn5KbIl0sImlhdCI6MTY5MTYwMDAwMCwiZXhwIjoxNzIzMTM2MDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",Pu=10,He="question",ne=Ft.create()(pi.devtools((r,e)=>({sessionId:null,problems:[],totalProblems:0,currentProblemIndex:0,currentScene:"question",userAnswers:{},submissionResults:{},geometryShapes:{},selectedShapeId:null,geometryMode:"view",loading:!1,error:null,timeSpent:0,startTime:null,sessionComplete:!1,loadQuestions:async(t,n)=>{r({loading:!0,sessionId:t});try{const{gradeLevel:s,unitId:o,lessonId:i,count:a=Pu}=n,c=`${Iu}/grades/${s}/units/${o}/lessons/${i}/sessions/${t}/questions`,l=await fetch(c,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Fu}`},body:JSON.stringify({count:a})});if(!l.ok)throw new Error(`Failed to load questions: ${l.status} ${l.statusText}`);const u=(await l.json()).questions||[],y={};u.forEach(m=>{m.geometryShapes&&Array.isArray(m.geometryShapes)&&(y[m.problemId]=m.geometryShapes)}),r({problems:u,totalProblems:u.length,currentProblemIndex:0,currentScene:He,geometryShapes:y,loading:!1,error:null,startTime:Date.now()})}catch(s){const o=s instanceof Error?s.message:"Unknown error occurred";throw r({error:o,loading:!1}),s}},goToNextProblem:()=>{const{currentProblemIndex:t,problems:n,currentScene:s}=e();if(s!==He){console.warn("Cannot navigate during review/solve scene");return}t<n.length-1?r({currentProblemIndex:t+1,currentScene:He}):r({sessionComplete:!0})},goToPreviousProblem:()=>{const{currentProblemIndex:t,currentScene:n}=e();n===He&&t>0&&r({currentProblemIndex:t-1,currentScene:He})},goToProblem:t=>{const{problems:n,currentScene:s}=e();s===He&&(t<0||t>=n.length||r({currentProblemIndex:t,currentScene:He}))},switchScene:t=>{r({currentScene:t})},submitAnswer:async(t,n)=>{const{problems:s,currentProblemIndex:o}=e(),i=s[o];r({loading:!0});try{const a=i?.answer.correctAnswer||[],c=n.length>0&&n[0]===a[0],l={userAnswer:n,isCorrect:c,feedback:c?"🎉 Great job! Your answer is correct!":"❌ Sorry, that's not correct."};r(d=>({userAnswers:{...d.userAnswers,[t]:n},submissionResults:{...d.submissionResults,[t]:l},loading:!1,currentScene:c?"review":"solve"}))}catch(a){r({error:a instanceof Error?a.message:"Submission error",loading:!1})}},updateUserAnswer:(t,n)=>{r(s=>({userAnswers:{...s.userAnswers,[t]:n}}))},updateShape:(t,n,s)=>{r(o=>{const a=(o.geometryShapes[t]||[]).map(c=>c.id===n&&c.type==="point"?{...c,position:s}:c);return{geometryShapes:{...o.geometryShapes,[t]:a}}})},selectShape:(t,n)=>{r({selectedShapeId:n})},setGeometryMode:(t,n)=>{r({geometryMode:n})},startTimer:()=>{r({startTime:Date.now()})},stopTimer:()=>{const{startTime:t}=e();if(t){const n=Math.floor((Date.now()-t)/1e3);r(s=>({timeSpent:s.timeSpent+n,startTime:null}))}},reset:()=>{r({sessionId:null,problems:[],totalProblems:0,currentProblemIndex:0,currentScene:He,userAnswers:{},submissionResults:{},geometryShapes:{},selectedShapeId:null,geometryMode:"view",loading:!1,error:null,timeSpent:0,startTime:null,sessionComplete:!1})},getCurrentProblem:()=>{const{problems:t,currentProblemIndex:n}=e();return t[n]||null},getProgress:()=>{const{currentProblemIndex:t,totalProblems:n}=e();return{current:t+1,total:n,percentage:n>0?(t+1)/n*100:0}},getSessionResults:()=>{const{sessionId:t,problems:n,submissionResults:s,timeSpent:o}=e(),i=n.map(c=>({problemId:c.problemId,userAnswer:s[c.problemId]?.userAnswer||[],isCorrect:s[c.problemId]?.isCorrect||!1,timeSpent:0})),a=i.filter(c=>c.isCorrect).length;return{sessionId:t||"",totalProblems:n.length,correctAnswers:a,accuracy:n.length>0?a/n.length:0,timeSpent:o,averageTime:n.length>0?o/n.length:0,answers:i}}}),{name:"MathSessionStore"})),ni=(r,e,t,n,s,o,i)=>{const a=b.useMemo(()=>t==="question",[t]),c=b.useMemo(()=>r<e.length-1,[r,e.length]),l=b.useMemo(()=>r>0,[r]),d=b.useMemo(()=>!n||!s?!1:n.problemType?.includes("geometry")||o&&o[s]&&o[s].length>0?!0:i?.enableMathGraph!==void 0?i.enableMathGraph:!1,[n,s,o,i?.enableMathGraph]);return{canNavigate:a,canGoNext:c,canGoPrevious:l,shouldRenderMathGraph:d}},si=(r,e,t,n,s)=>{const o=ne(d=>d.selectShape),i=ne(d=>d.setGeometryMode),a=b.useMemo(()=>!e||!n?[]:n[e]||[],[n,e]);b.useEffect(()=>{if(!e||!t)return;let d="view";switch(r){case"question":d="edit";break;case"solve":case"review":d="view";break;default:d="view"}s!==d&&i(e,d)},[r,e,s,i,t]);const c=b.useCallback(d=>{e&&ne.setState(u=>({geometryShapes:{...u.geometryShapes,[e]:d}}))},[e]),l=b.useCallback(d=>{if(e){const u=d.length>0?d[0]:null;o(e,u)}},[e,o]);return{currentGeometryShapes:a,geometryMode:s,handleShapeChange:c,handleSelectionChange:l}},oi=(r,e,t)=>{const n=ne(m=>m.updateUserAnswer),s=ne(m=>m.submitAnswer),o=ne(m=>m.goToNextProblem),i=ne(m=>m.goToPreviousProblem),a=ne(m=>m.goToProblem),c=b.useCallback(m=>{r&&n(r,m)},[r,n]),l=b.useCallback(()=>{r&&t[r]&&s(r,t[r])},[r,t,s]),d=b.useCallback(m=>{o(),m?.(r,e+1)},[o,r,e]),u=b.useCallback(m=>{i(),m?.(r,e-1)},[i,r,e]),y=b.useCallback((m,h)=>{a(m-1),h?.(r,m-1)},[a,r]);return{handleAnswerChange:c,handleSubmit:l,handleNext:d,handlePrevious:u,handlePagination:y}},ii=({config:r={},onSessionComplete:e,onSessionExit:t,onProblemChange:n,className:s="",style:o})=>{const i=ne(j=>j.problems),a=ne(j=>j.currentProblemIndex),c=ne(j=>j.currentScene),l=ne(j=>j.loading),d=ne(j=>j.error),u=ne(j=>j.sessionComplete),y=ne(j=>j.submissionResults),m=ne(j=>j.userAnswers),h=ne(j=>j.geometryShapes),g=ne(j=>j.geometryMode),p=ne(j=>j.getSessionResults),x=b.useMemo(()=>i[a]??null,[i,a]),S=b.useMemo(()=>x?.problemId??"",[x]),{canNavigate:R,canGoNext:C,canGoPrevious:_,shouldRenderMathGraph:O}=ni(a,i,c,x,S,h,r),{currentGeometryShapes:w,handleShapeChange:F,handleSelectionChange:$}=si(c,S,O,h,g),{handleAnswerChange:k,handleSubmit:B,handleNext:W,handlePrevious:M,handlePagination:L}=oi(S,a,m);b.useEffect(()=>{if(u&&typeof p=="function"){const j=p();e?.(j)}},[u,p,e]);const J=j=>typeof j=="string"?j:j instanceof Error?j.message:String(j);return l&&i.length===0?f.jsx("div",{className:"flex items-center justify-center p-12","data-testid":"math-session-loading",children:f.jsxs("div",{className:"text-center",children:[f.jsx("div",{className:"animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"}),f.jsx("p",{className:"text-gray-600",children:"Loading questions..."})]})}):d&&d!==null?f.jsx("div",{className:"flex items-center justify-center p-12","data-testid":"math-session-error",children:f.jsxs("div",{className:"text-center text-red-600",children:[f.jsx("p",{className:"text-lg font-semibold mb-2",children:"Error"}),f.jsx("p",{children:J(d)})]})}):x?f.jsxs("div",{className:`flex flex-col max-w-4xl mx-auto p-6 ${s}`,style:o,"data-testid":"math-session-container",role:"region","aria-label":"数学练习会话",children:[f.jsx("div",{className:"mb-6",children:f.jsx(Ne.Pagination,{total:i.length,page:a+1,onChange:j=>L(j,n),isDisabled:!R,showControls:!1,color:"primary",size:"lg",className:"justify-center"})}),f.jsx(Ve,{problemData:x,scene:c,submissionResult:y[S],loading:l,error:d?J(d):void 0,value:m[S],onAnswerChange:k,onSubmit:B,onNext:()=>W(n),config:{theme:r.theme??"light",submitButtonText:"提交答案",nextButtonText:c==="solve"?"Got it!":"下一题",showHints:r.enableHints}}),O&&f.jsx("div",{className:"mt-4 w-full max-w-4xl mx-auto","data-testid":"mathgraph-container",children:f.jsx(Ar,{shapes:w,mode:g,onShapeChange:F,onSelectionChange:$,showGrid:!0,showAxis:!0,width:800,height:500,boundingBoxOptions:{padding:.5,margin:2,minSize:8}})}),r.showProgress&&f.jsxs("div",{className:"mt-6 flex justify-between items-center",children:[f.jsx("button",{onClick:()=>M(n),disabled:!_,className:"px-4 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",children:"上一题"}),f.jsxs("div",{className:"text-sm text-gray-600",children:[a+1," / ",i.length]}),f.jsx("button",{onClick:()=>W(n),disabled:!C||!R,className:"px-4 py-2 text-sm bg-blue-600 text-white rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",children:"下一题"})]}),t&&f.jsx("div",{className:"mt-4 flex justify-center",children:f.jsx("button",{onClick:t,className:"px-4 py-2 text-sm text-gray-600 hover:text-gray-900 transition-colors",children:"退出练习"})})]}):f.jsx("div",{className:"flex items-center justify-center p-12","data-testid":"math-session-empty",children:f.jsx("p",{className:"text-gray-600",children:"No problems available"})})},Du=({sessionId:r,gradeId:e,unitId:t,lessonId:n,userId:s,config:o={},className:i="",onSessionComplete:a,onSessionExit:c})=>{const[l,d]=b.useState({loading:!1,error:null,initialized:!1}),[u,y]=b.useState(0),[m,h]=b.useState(""),g=b.useRef(null),p=b.useRef(null),x=b.useRef(null),S=ne(F=>F.loadQuestions),R=ne(F=>F.reset);b.useEffect(()=>{const F=async()=>{try{d($=>({...$,loading:!0,error:null})),console.log("🎯 MathSessionPage: 开始初始化会话",{sessionId:r,gradeId:e,unitId:t,lessonId:n,userId:s}),await S(r,{gradeLevel:parseInt(e.replace("g",""))||5,unitId:t,lessonId:n,count:o.questionCount||10}),d($=>({...$,loading:!1,initialized:!0})),console.log("✅ MathSessionPage: 会话初始化完成")}catch($){const k=$ instanceof Error?$.message:"Failed to initialize session";d(B=>({...B,loading:!1,error:k,initialized:!1})),console.error("❌ MathSessionPage: 会话初始化失败",$)}};r&&e&&t&&n&&!l.initialized&&F()},[r,e,t,n,S,o.questionCount,l.initialized,u]),b.useEffect(()=>{l.loading&&!l.initialized?h("正在加载数学练习内容,请稍候..."):l.error?h(`加载失败:${l.error},请点击重试按钮重新加载`):l.initialized&&h("数学练习内容已加载完成,可以开始练习")},[l.loading,l.error,l.initialized]),b.useEffect(()=>{l.initialized&&g.current&&g.current.focus()},[l.initialized]),b.useEffect(()=>{l.error&&x.current&&x.current.focus()},[l.error]),b.useEffect(()=>{l.loading&&p.current&&p.current.focus()},[l.loading]),b.useEffect(()=>()=>{console.log("🧹 MathSessionPage: 清理会话状态"),R()},[R]);const C=b.useCallback(F=>{console.log("🎉 MathSessionPage: 会话完成",F),a?.(F)},[a]),_=b.useCallback(()=>{console.log("🚪 MathSessionPage: 退出会话"),c?.()},[c]),O=b.useCallback((F,$)=>{console.log(`📝 MathSessionPage: 切换到题目 ${$+1}`,F)},[]),w=b.useCallback(F=>{F.key==="Escape"&&(F.preventDefault(),_()),F.key==="Enter"&&l.error&&F.target===x.current&&(F.preventDefault(),d({loading:!1,error:null,initialized:!1}),y($=>$+1))},[_,l.error]);return l.loading&&!l.initialized?f.jsxs("div",{className:`math-session-page loading ${i}`,"data-testid":"math-session-page",role:"main","aria-label":"数学练习页面",onKeyDown:w,tabIndex:-1,ref:p,children:[f.jsx("div",{"aria-live":"assertive","aria-atomic":"true",className:"sr-only",children:m}),f.jsx("div",{className:"page-loading-container",children:f.jsxs("div",{className:"loading-spinner","data-testid":"page-loading-spinner",role:"status","aria-label":"正在加载练习内容",children:[f.jsx("div",{className:"spinner","aria-hidden":"true"}),f.jsx("p",{className:"loading-text",children:"正在加载练习内容..."})]})})]}):l.error?f.jsxs("div",{className:`math-session-page error ${i}`,"data-testid":"math-session-page",role:"main","aria-label":"数学练习页面 - 错误状态",onKeyDown:w,tabIndex:-1,ref:x,children:[f.jsx("div",{"aria-live":"assertive","aria-atomic":"true",className:"sr-only",children:m}),f.jsxs("div",{className:"error-container",children:[f.jsx("div",{className:"error-icon",role:"img","aria-label":"警告图标",children:"⚠️"}),f.jsx("h3",{className:"error-title",children:"加载失败"}),f.jsx("p",{className:"error-message",children:l.error}),f.jsx("button",{onClick:()=>{d({loading:!1,error:null,initialized:!1}),y(F=>F+1)},className:"retry-button","data-testid":"retry-button","aria-label":"重新加载练习内容",children:"重试"})]})]}):f.jsxs("div",{className:`math-session-page ${i}`,"data-testid":"math-session-page",role:"main","aria-label":"数学练习页面",onKeyDown:w,children:[f.jsx("div",{"aria-live":"polite","aria-atomic":"true",className:"sr-only",children:m}),o.layout?.showHeader&&f.jsx("header",{className:"page-header",role:"banner",children:f.jsxs("div",{className:"header-content",children:[f.jsx("h1",{className:"page-title",children:"数学练习"}),f.jsxs("div",{className:"session-info","aria-label":"会话信息",children:[f.jsxs("span",{className:"session-id",children:["会话: ",r]}),f.jsxs("span",{className:"grade-info",children:["年级: ",e]})]})]})}),f.jsx("main",{className:"page-main",ref:g,tabIndex:-1,"aria-label":"数学练习主要内容区域",children:f.jsx(ii,{config:{showProgress:o.showProgress??!0,enableHints:o.enableHints??!1,autoAdvance:o.autoAdvance??!1,theme:o.theme??"light"},onSessionComplete:C,onSessionExit:_,onProblemChange:O})}),o.layout?.showFooter&&f.jsx("footer",{className:"page-footer",role:"contentinfo",children:f.jsx("div",{className:"footer-content",children:f.jsx("p",{className:"footer-text",children:"© 2024 MathWiz - 小学数学益智教育平台"})})})]})},Lu=b.memo(Du),Uu=({problemData:r,userAnswer:e,onNextQuestion:t})=>f.jsxs("div",{children:[f.jsxs("div",{className:"decimal-error-banner",children:[f.jsxs("div",{children:[f.jsx("h3",{className:"decimal-error-title",children:"抱歉,答案不正确..."}),f.jsxs("p",{className:"decimal-error-description",children:["正确答案是: ",f.jsx("strong",{children:r.answer.value})]})]}),f.jsx("button",{onClick:t,className:"decimal-understand-button",children:"明白了"})]}),f.jsxs("div",{className:"decimal-content-area",children:[f.jsx(vn,{problemData:r,userAnswer:e}),f.jsx(_n,{problemData:r})]}),f.jsx("div",{className:"decimal-bottom-area",children:f.jsx("button",{onClick:t,className:"decimal-bottom-button",children:"明白了"})})]}),Gu="rectangle-area-003",zu="矩形面积计算问题",Bu=5,Vu="几何与测量",qu="计算矩形的面积,理解面积公式 A = l × w 的应用",Wu={shape:"rectangle",length:7,width:5,lengthUnit:"码",widthUnit:"码",areaUnit:"平方码",question:"这个矩形的面积是多少?"},Hu=[{type:"text",content:"What is the area of this rectangle?"}],Yu={question:{content:[{type:"text",content:"What is the area of this rectangle?",style:{fontSize:"1.5rem",color:"#1e293b"}},{type:"graph",content:"矩形图形",shapes:[{id:"pointA",type:"point",position:{x:1,y:1},name:"A",size:4,strokeColor:"#3B82F6"},{id:"pointB",type:"point",position:{x:8,y:1},name:"B",size:4,strokeColor:"#3B82F6"},{id:"pointC",type:"point",position:{x:8,y:6},name:"C",size:4,strokeColor:"#3B82F6"},{id:"pointD",type:"point",position:{x:1,y:6},name:"D",size:4,strokeColor:"#3B82F6"},{id:"rectangle",type:"polygon",vertices:[{$ref:"pointA"},{$ref:"pointB"},{$ref:"pointC"},{$ref:"pointD"}],strokeColor:"#0ea5e9",fillColor:"#7dd3fc",fillOpacity:.3,strokeWidth:2,name:"矩形"},{id:"lengthLabel",type:"text",position:{x:4.5,y:0},content:"7 yd",color:"#475569",fontSize:16},{id:"widthLabel",type:"text",position:{x:9,y:3.5},content:"5 yd",color:"#475569",fontSize:16}],width:400,height:300,boundingBox:[0,8,10,0],showGrid:!1,showAxis:!1}]},solve:{content:[{type:"text",content:"解题步骤:",style:{fontSize:"1.25rem",fontWeight:"bold",color:"#1e293b"}},{type:"text",content:"1. 观察矩形:长度是 7 码,宽度是 5 码",style:{marginTop:"8px"}},{type:"formula",content:"A = l × w",parts:["A = l \\times w"]},{type:"formula",content:"= 7 × 5",parts:["= 7 \\times 5"]},{type:"formula",content:"= 35",parts:["= 35"]},{type:"text",content:"长度和宽度以码为单位,所以面积以平方码为单位",style:{marginTop:"8px"}},{type:"text",content:"最终答案:矩形的面积是 35 平方码",style:{marginTop:"8px",fontWeight:"bold"}}]},review:{content:[{type:"text",content:"核心概念回顾:",style:{fontSize:"1.25rem",fontWeight:"bold",color:"#1e293b"}},{type:"text",content:"矩形面积公式:A = l × w",style:{marginTop:"8px"}},{type:"text",content:"其中 l 是长度,w 是宽度",style:{color:"#64748b"}}]}},Ku=[{id:"exp-step-1",type:"instructionalStep",content:{title:"步骤1:识别矩形的尺寸",description:"观察图形,确定矩形的长度和宽度,并理解尺寸的单位。",chartConfig:{type:"graph",shapes:[{id:"pointA",type:"point",position:{x:1,y:1},name:"A",size:4,strokeColor:"#3B82F6"},{id:"pointB",type:"point",position:{x:8,y:1},name:"B",size:4,strokeColor:"#3B82F6"},{id:"pointC",type:"point",position:{x:8,y:6},name:"C",size:4,strokeColor:"#3B82F6"},{id:"pointD",type:"point",position:{x:1,y:6},name:"D",size:4,strokeColor:"#3B82F6"},{id:"rectangle",type:"polygon",vertices:[{$ref:"pointA"},{$ref:"pointB"},{$ref:"pointC"},{$ref:"pointD"}],strokeColor:"#0ea5e9",fillColor:"#7dd3fc",fillOpacity:.3,strokeWidth:2},{id:"lengthLabel",type:"text",position:{x:4.5,y:0},content:"长度:7 码",color:"#475569",fontSize:14},{id:"widthLabel",type:"text",position:{x:9,y:3.5},content:"宽度:5 码",color:"#475569",fontSize:14}],boundingBox:[0,8,10,0],showGrid:!1,showAxis:!1}}},{id:"exp-step-2",type:"instructionalStep",content:{title:"步骤2:回忆矩形面积公式",description:"复习矩形面积的基本公式:面积 = 长度 × 宽度。",chartConfig:{type:"graph",shapes:[{id:"pointA",type:"point",position:{x:1,y:1},name:"A",size:4,strokeColor:"#3B82F6"},{id:"pointB",type:"point",position:{x:8,y:1},name:"B",size:4,strokeColor:"#3B82F6"},{id:"pointC",type:"point",position:{x:8,y:6},name:"C",size:4,strokeColor:"#3B82F6"},{id:"pointD",type:"point",position:{x:1,y:6},name:"D",size:4,strokeColor:"#3B82F6"},{id:"rectangle",type:"polygon",vertices:[{$ref:"pointA"},{$ref:"pointB"},{$ref:"pointC"},{$ref:"pointD"}],strokeColor:"#0ea5e9",fillColor:"#7dd3fc",fillOpacity:.3,strokeWidth:2},{id:"formulaLabel",type:"text",position:{x:5,y:7},content:"面积公式:A = l × w",color:"#10B981",fontSize:16,fontWeight:"bold"}],boundingBox:[0,8,10,0],showGrid:!1,showAxis:!1}}},{id:"exp-step-3",type:"instructionalStep",content:{title:"步骤3:代入数值计算",description:"将已知的长度和宽度代入公式进行计算。",chartConfig:{type:"graph",shapes:[{id:"pointA",type:"point",position:{x:1,y:1},name:"A",size:4,strokeColor:"#3B82F6"},{id:"pointB",type:"point",position:{x:8,y:1},name:"B",size:4,strokeColor:"#3B82F6"},{id:"pointC",type:"point",position:{x:8,y:6},name:"C",size:4,strokeColor:"#3B82F6"},{id:"pointD",type:"point",position:{x:1,y:6},name:"D",size:4,strokeColor:"#3B82F6"},{id:"rectangle",type:"polygon",vertices:[{$ref:"pointA"},{$ref:"pointB"},{$ref:"pointC"},{$ref:"pointD"}],strokeColor:"#0ea5e9",fillColor:"#7dd3fc",fillOpacity:.3,strokeWidth:2},{id:"calculationLabel",type:"text",position:{x:5,y:7},content:"A = 7 × 5 = 35",color:"#F59E0B",fontSize:16,fontWeight:"bold"}],boundingBox:[0,8,10,0],showGrid:!1,showAxis:!1}}},{id:"exp-step-4",type:"instructionalStep",content:{title:"步骤4:确定面积单位",description:"根据长度和宽度的单位确定面积的单位。",chartConfig:{type:"graph",shapes:[{id:"pointA",type:"point",position:{x:1,y:1},name:"A",size:4,strokeColor:"#3B82F6"},{id:"pointB",type:"point",position:{x:8,y:1},name:"B",size:4,strokeColor:"#3B82F6"},{id:"pointC",type:"point",position:{x:8,y:6},name:"C",size:4,strokeColor:"#3B82F6"},{id:"pointD",type:"point",position:{x:1,y:6},name:"D",size:4,strokeColor:"#3B82F6"},{id:"rectangle",type:"polygon",vertices:[{$ref:"pointA"},{$ref:"pointB"},{$ref:"pointC"},{$ref:"pointD"}],strokeColor:"#0ea5e9",fillColor:"#7dd3fc",fillOpacity:.3,strokeWidth:2},{id:"unitLabel",type:"text",position:{x:5,y:7},content:"长度:码,宽度:码 → 面积:平方码",color:"#8B5CF6",fontSize:14},{id:"finalAnswer",type:"text",position:{x:5,y:7.5},content:"最终答案:35 平方码",color:"#10B981",fontSize:16,fontWeight:"bold"}],boundingBox:[0,8,10,0],showGrid:!1,showAxis:!1}}}],Xu={value:35,unit:"平方码",explanation:"矩形的面积是 35 平方码。计算方法:长度 7 码 × 宽度 5 码 = 35 平方码。"},Ju={type:"card",padding:"20px"},Zu={id:Gu,title:zu,grade:Bu,unit:Vu,description:qu,basicInfo:Wu,content:Hu,scenes:Yu,explanation:Ku,answer:Xu,layout:Ju},Qu=({className:r=""})=>{const e=fn(),t=un(),n=mn(),{updateUserAnswer:s,submitAnswer:o,nextQuestion:i}=hn(),a=l=>{if(!l)return l;const d=JSON.parse(JSON.stringify(l));return d.lesson||(d.lesson="面积计算"),d.skill||(d.skill="面积公式应用"),d.objective||(d.objective="掌握面积计算方法"),(!d.knowledgePoints||!Array.isArray(d.knowledgePoints))&&(d.knowledgePoints=["面积公式","几何变换"]),d.difficulty||(d.difficulty=2),d.metadata||(d.metadata={topic:"几何",skill:"面积计算",tags:["面积","公式"]}),["question","solve","review","remember"].forEach(y=>{if(d.scenes?.[y]){const m=d.scenes[y];!m.items&&m.content&&(m.items=m.content),Array.isArray(m.items)||(m.items=[])}}),d},c=b.useMemo(()=>a(Zu),[]);return f.jsxs("div",{className:`max-w-4xl mx-auto p-4 md:p-8 bg-slate-50 min-h-screen ${r}`,children:[f.jsxs("header",{className:"mb-8",children:[f.jsx("h1",{className:"text-2xl font-bold text-slate-800",children:"数学练习"}),f.jsxs("p",{className:"text-slate-600 mt-2",children:[c.grade,"年级 - ",c.unit]})]}),f.jsxs("main",{className:"bg-white border border-slate-200 rounded-lg shadow-sm",children:[e==="question"&&f.jsx(wt,{problemData:c,userAnswer:t,showAnswerForm:n,onAnswerSubmit:o,onAnswerChange:s}),e==="explanation"&&f.jsx(qt,{problemData:c,userAnswer:t,onNextQuestion:i}),e==="success"&&f.jsx(At,{problemData:c,onNextQuestion:i})]})]})},St=Ft.create(r=>({currentScene:"question",userAnswer:"",isCorrect:null,showAnswerForm:!0,problemData:null,validationError:null,setProblemData:e=>{r({problemData:e,currentScene:"question",userAnswer:"",isCorrect:null,showAnswerForm:!0,validationError:null})},updateUserAnswer:e=>{r({userAnswer:e,validationError:null})},submitAnswer:e=>{const t=St.getState();if(!t.problemData){r({validationError:"问题数据未加载,请刷新页面重试"});return}const n=t.problemData.answer.value.toString(),s=e.trim(),o=n.trim();let i=!1;(s===o||s===".12"&&o==="0.12"||s==="0,12"&&o==="0.12")&&(i=!0),r({userAnswer:e,isCorrect:i,showAnswerForm:!1,validationError:null,currentScene:i?"success":"explanation"})},nextQuestion:()=>{r({currentScene:"question",userAnswer:"",isCorrect:null,showAnswerForm:!0,validationError:null})},resetSession:()=>{r({currentScene:"question",userAnswer:"",isCorrect:null,showAnswerForm:!0,validationError:null})}})),ai=()=>St(r=>r.currentScene),li=()=>St(r=>r.userAnswer),ci=()=>St(r=>r.showAnswerForm),em=()=>St(r=>r.validationError),di=()=>St(en.useShallow(r=>({updateUserAnswer:r.updateUserAnswer,submitAnswer:r.submitAnswer,nextQuestion:r.nextQuestion,resetSession:r.resetSession,setProblemData:r.setProblemData}))),tm={id:"decimal-grid-problem-001",title:"百格图识别小数",grade:4,unit:"小数的认识",lesson:"小数认识",skill:"百格图识别小数",objective:"理解百分位和小数的关系",knowledgePoints:["小数表示","百分位概念","百格图模型"],difficulty:1,metadata:{topic:"小数",skill:"小数识别",tags:["百格图","百分位","小数表示"]},description:"通过百格图模型理解百分位和小数的关系。",basicInfo:{question:"What decimal number does the model represent?",answerUnit:""},scenes:{question:{content:[{type:"text",content:"What decimal number does the model represent?",style:{fontSize:"1.5rem",color:"#1e293b",fontWeight:"bold"}},{type:"text",content:"The large square represents 1 whole.",style:{fontSize:"1rem",color:"#475569",marginTop:"4px"}},{type:"hundredGrid",content:"",props:{value:.12,mode:"readonly",rows:10,cols:10,cellSize:12,fillColor:"#a5b4fc",baseColor:"#e2e8f0",strokeColor:"#d1d5db",shadingDirection:"ltr",hasShadow:!0}}],items:[{type:"text",content:"What decimal number does the model represent?",style:{fontSize:"1.5rem",color:"#1e293b",fontWeight:"bold"}},{type:"text",content:"The large square represents 1 whole.",style:{fontSize:"1rem",color:"#475569",marginTop:"4px"}},{type:"hundredGrid",content:"",props:{value:.12,mode:"readonly",rows:10,cols:10,cellSize:12,fillColor:"#a5b4fc",baseColor:"#e2e8f0",strokeColor:"#d1d5db",shadingDirection:"ltr",hasShadow:!0}}]},solve:{content:[{type:"text",content:"解题步骤:",style:{fontSize:"1.25rem",fontWeight:"bold",color:"#1e293b"}},{type:"text",content:'1. 在模型中, 100个小方格中有12个被涂色。这代表 12/100 或者"一百分之十二"。'},{type:"text",content:'2. 你可以使用数位表将"一百分之十二"写作小数。'},{type:"placeValueChart",content:"",props:{headers:["ones (个位)","tenths (十分位)","hundredths (百分位)"],values:["0","1","2"],colors:{headerBg:"#f1f5f9",valueBg:"#ffffff",borderColor:"#e2e8f0"}}},{type:"text",content:"所以, 这个模型代表的小数是 <strong>0.12</strong>。",style:{marginTop:"1rem"}}],items:[{type:"text",content:"解题步骤:",style:{fontSize:"1.25rem",fontWeight:"bold",color:"#1e293b"}},{type:"text",content:'1. 在模型中, 100个小方格中有12个被涂色。这代表 12/100 或者"一百分之十二"。'},{type:"text",content:'2. 你可以使用数位表将"一百分之十二"写作小数。'},{type:"placeValueChart",content:"",props:{headers:["ones (个位)","tenths (十分位)","hundredths (百分位)"],values:["0","1","2"],colors:{headerBg:"#f1f5f9",valueBg:"#ffffff",borderColor:"#e2e8f0"}}},{type:"text",content:"所以, 这个模型代表的小数是 <strong>0.12</strong>。",style:{marginTop:"1rem"}}]},review:{content:[{type:"text",content:"回顾问题:",style:{fontSize:"1.25rem",fontWeight:"bold",color:"#1e293b"}},{type:"text",content:`What decimal number does the model represent?
252
252
  The large square represents 1 whole.`},{type:"hundredGrid",content:"",props:{value:.12,mode:"readonly",rows:10,cols:10,cellSize:12,fillColor:"#a5b4fc",baseColor:"#e2e8f0",strokeColor:"#d1d5db",shadingDirection:"ltr",hasShadow:!0}}],items:[{type:"text",content:"回顾问题:",style:{fontSize:"1.25rem",fontWeight:"bold",color:"#1e293b"}},{type:"text",content:`What decimal number does the model represent?
253
- The large square represents 1 whole.`},{type:"hundredGrid",content:"",props:{value:.12,mode:"readonly",rows:10,cols:10,cellSize:12,fillColor:"#a5b4fc",baseColor:"#e2e8f0",strokeColor:"#d1d5db",shadingDirection:"ltr",hasShadow:!0}}]}},explanation:[],answer:{value:.12,unit:"",explanation:"模型中100个方格有12个被涂色,代表12/100,即0.12。"}},rm=({className:r="",problemData:e})=>{const t=ai(),n=li(),s=ci(),o=em(),{updateUserAnswer:i,submitAnswer:a,nextQuestion:c,setProblemData:l}=di(),d=b.useMemo(()=>e||tm,[e]);return b.useEffect(()=>{l(d)},[d,l]),f.jsxs("div",{className:`max-w-4xl mx-auto p-4 md:p-8 bg-slate-50 min-h-screen ${r}`,children:[f.jsxs("header",{className:"mb-8",children:[f.jsx("h1",{className:"text-2xl font-bold text-slate-800",children:"小数认识练习"}),f.jsxs("p",{className:"text-slate-600 mt-2",children:[d.grade,"年级 - ",d.unit]}),f.jsx("p",{className:"text-slate-500 text-sm mt-1",children:"通过百格图模型理解百分位和小数的关系"})]}),f.jsxs("main",{className:"bg-white border border-slate-200 rounded-lg shadow-sm",children:[t==="question"&&f.jsx(wt,{problemData:d,userAnswer:n,showAnswerForm:s,onAnswerSubmit:a,onAnswerChange:i,validationError:o}),t==="explanation"&&f.jsx(Uu,{problemData:d,userAnswer:n,onNextQuestion:c}),t==="success"&&f.jsx(At,{problemData:d,onNextQuestion:c})]}),f.jsxs("div",{className:"mt-4 text-center text-sm text-slate-500",children:[t==="question"&&"请识别百格图代表的小数",t==="explanation"&&"查看详细解释",t==="success"&&"恭喜!答案正确"]})]})},Oe=(r,e,t)=>({x:r.x+(e.x-r.x)*t,y:r.y+(e.y-r.y)*t}),nm=()=>{const r={x:.5,y:.1,name:"A"},e={x:.1,y:.75,name:"B"},t={x:.9,y:.75,name:"C"},n={...Oe(r,e,1/3),name:"D"},s={...Oe(r,t,1/3),name:"E"},o={...Oe(r,e,2/3),name:"M"},i={...Oe(r,t,2/3),name:"N"},a={...Oe(e,t,1/3),name:"P"},c={...Oe(e,t,2/3),name:"Q"},l={...Oe(n,s,1/3),name:"U"},d={...Oe(n,s,2/3),name:"S"},u={...Oe(o,i,1/3),name:"K"},y={...Oe(o,i,2/3),name:"L"};return{A:r,B:e,C:t,D:n,E:s,M:o,N:i,P:a,Q:c,U:l,S:d,K:u,L:y}},sm=(r,e,t)=>{const n={};for(const[s,o]of Object.entries(r))n[s]={...o,x:o.x*e,y:o.y*t};return n},om=(r,e)=>{const[t,n,s]=e,{x:o,y:i}=r,a=(n.y-s.y)*(t.x-s.x)+(s.x-n.x)*(t.y-s.y);if(Math.abs(a)<1e-4)return!1;const c=((n.y-s.y)*(o-s.x)+(s.x-n.x)*(i-s.y))/a,l=((s.y-t.y)*(o-s.x)+(t.x-s.x)*(i-s.y))/a,d=1-c-l;return c>=-.001&&l>=-.001&&d>=-.001},im=(r,e)=>{if(!r||!e||r.length!==3||e.length!==3)return!1;const t=r.map(s=>s.name).sort(),n=e.map(s=>s.name).sort();return t.every((s,o)=>s===n[o])},am=(r,e)=>{if(!r||!e||r.length!==e.length)return!1;const t=r.map(s=>s.name).sort(),n=e.map(s=>s.name).sort();return t.join("")===n.join("")},lm=()=>[{from:"A",to:"B"},{from:"A",to:"C"},{from:"B",to:"C"},{from:"D",to:"E"},{from:"M",to:"N"},{from:"P",to:"Q"},{from:"A",to:"D"},{from:"A",to:"E"},{from:"A",to:"M"},{from:"A",to:"N"},{from:"A",to:"P"},{from:"A",to:"Q"},{from:"D",to:"U"},{from:"U",to:"S"},{from:"S",to:"E"},{from:"M",to:"K"},{from:"K",to:"L"},{from:"L",to:"N"},{from:"B",to:"P"},{from:"P",to:"Q"},{from:"Q",to:"C"}],cm=()=>[{id:"gem_1",vertices:["A","B","P"],points:10,category:"basic"},{id:"gem_2",vertices:["A","P","Q"],points:10,category:"basic"},{id:"gem_3",vertices:["A","Q","C"],points:10,category:"basic"},{id:"gem_4",vertices:["A","B","Q"],points:15,category:"medium"},{id:"gem_5",vertices:["A","P","C"],points:15,category:"medium"},{id:"gem_6",vertices:["A","B","C"],points:20,category:"large"},{id:"gem_7",vertices:["A","D","U"],points:12,category:"ade_small"},{id:"gem_8",vertices:["A","U","S"],points:12,category:"ade_small"},{id:"gem_9",vertices:["A","S","E"],points:12,category:"ade_small"},{id:"gem_10",vertices:["A","D","S"],points:18,category:"ade_medium"},{id:"gem_11",vertices:["A","U","E"],points:18,category:"ade_medium"},{id:"gem_12",vertices:["A","D","E"],points:25,category:"ade_large"},{id:"gem_13",vertices:["A","M","K"],points:14,category:"amn_small"},{id:"gem_14",vertices:["A","K","L"],points:14,category:"amn_small"},{id:"gem_15",vertices:["A","L","N"],points:14,category:"amn_small"},{id:"gem_16",vertices:["A","M","L"],points:20,category:"amn_medium"},{id:"gem_17",vertices:["A","K","N"],points:20,category:"amn_medium"},{id:"gem_18",vertices:["A","M","N"],points:30,category:"amn_large"}],dm={TOTAL_GEMS:18,CANVAS_RATIO:4/3,DEFAULT_VIEWBOX:{width:700,height:600},POINT_RADIUS:{default:6,selected:9},TOLERANCE:.001,MIN_TRIANGLE_AREA:.001,COORDINATE_PRECISION:1e-4,BARYCENTRIC_TOLERANCE:-.001},fi=(r=Bt.id)=>{const e=se.units.map((s,o)=>{const i=Math.min(100,Math.max(0,o*15+Math.random()*20)),a=Math.floor(s.lessons.length*i/100),c=s.lessons.map((l,d)=>{const u=Math.min(100,Math.max(0,i-d*10+Math.random()*30));return{lessonId:l.id,status:u>=100?"completed":u>0?"in-progress":"not-started",progressPercentage:Math.round(u),lastAccessed:u>0?new Date(Date.now()-Math.random()*7*24*60*60*1e3).toISOString():void 0,timeSpent:u>0?Math.floor(Math.random()*120+10):void 0,score:u>=100?Math.floor(Math.random()*21+80):void 0,attempts:u>0?Math.floor(Math.random()*3+1):void 0}});return{unitId:s.id,userId:r,totalLessons:s.lessons.length,completedLessons:a,progressPercentage:Math.round(i),status:i>=100?"completed":i>0?"in-progress":"not-started",lastAccessed:i>0?new Date(Date.now()-Math.random()*14*24*60*60*1e3).toISOString():void 0,lessons:c}}),t=e.reduce((s,o)=>s+o.progressPercentage,0)/e.length,n=e.filter(s=>s.status==="completed").length;return{courseId:se.id,userId:r,totalUnits:e.length,completedUnits:n,progressPercentage:Math.round(t),status:t>=100?"completed":t>0?"in-progress":"not-started",lastAccessed:new Date(Date.now()-Math.random()*3*24*60*60*1e3).toISOString(),units:e}},ui=fi(),Tn=(r,e)=>r===Bt.id&&e===se.id?ui:null,mi=(r,e,t)=>{const n=Tn(r,e);return n&&n.units.find(s=>s.unitId===t)||null},fm=(r,e,t,n)=>{const s=mi(r,e,t);return s&&s.lessons.find(o=>o.lessonId===n)||null},um=(r,e,t,n,s)=>(console.log("Updating lesson progress:",{userId:r,courseId:e,unitId:t,lessonId:n,progress:s}),!0),Nn=(r,e)=>{const t=Tn(r,e);if(!t)return null;const n=se.units.map((s,o)=>{const i=t.units.find(a=>a.unitId===s.id);return{unitId:s.id,title:s.title,description:s.description,moduleCategory:s.moduleCategory,estimatedDuration:s.estimatedDuration,totalLessons:s.lessons.length,completedLessons:i?.completedLessons||0,progressPercentage:i?.progressPercentage||0,status:i?.status||"not-started",lastAccessed:i?.lastAccessed,isActive:o===0,route:`/math/grade-${se.level}/unit/${s.id}`}});return{userId:r,courseId:se.id,courseTitle:se.title,courseLevel:se.level,totalUnits:n.length,completedUnits:n.filter(s=>s.status==="completed").length,overallProgress:t.progressPercentage,status:t.status,lastAccessed:t.lastAccessed,units:n}},mm=(r,e,t)=>{const n=Nn(r,e);return n&&n.units.find(s=>s.unitId===t)||null},hm=(r,e,t,n)=>(console.log("Updating unit active status:",{userId:r,courseId:e,unitId:t,isActive:n}),!0),gm=Nn(Bt.id,se.id),pm={userId:Bt.id,courseId:se.id,courseTitle:se.title,courseLevel:se.level,totalUnits:se.units.length,completedUnits:3,overallProgress:45,status:"in-progress",lastAccessed:"2024-01-15T10:30:00Z",units:[{unitId:"unit_1",title:"小数乘法",description:"学习小数乘法的计算方法及应用",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"3周",totalLessons:10,completedLessons:8,progressPercentage:80,status:"completed",lastAccessed:"2024-01-10T14:20:00Z",isActive:!1,route:"/math/grade-5/unit/unit_1",icon:"🔢"},{unitId:"unit_2",title:"小数除法",description:"学习小数除法的计算方法及应用",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"3周",totalLessons:12,completedLessons:6,progressPercentage:50,status:"in-progress",lastAccessed:"2024-01-15T10:30:00Z",isActive:!0,route:"/math/grade-5/unit/unit_2",icon:"➗"},{unitId:"unit_3",title:"简易方程",description:"学习用字母表示数和解简易方程",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"4周",totalLessons:14,completedLessons:2,progressPercentage:14,status:"in-progress",lastAccessed:"2024-01-12T16:45:00Z",isActive:!1,route:"/math/grade-5/unit/unit_3",icon:"📝"},{unitId:"unit_4",title:"多边形的面积",description:"学习平行四边形、三角形、梯形和组合图形的面积计算",moduleCategory:"Graphics and Geometry",estimatedDuration:"3周",totalLessons:12,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_4",icon:"📐"},{unitId:"unit_5",title:"因数与倍数",description:"学习因数、倍数、质数、合数等概念",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"3周",totalLessons:10,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_5",icon:"🔢"},{unitId:"unit_6",title:"长方体和正方体",description:"学习长方体和正方体的特征、表面积和体积计算",moduleCategory:"Graphics and Geometry",estimatedDuration:"4周",totalLessons:14,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_6",icon:"📦"},{unitId:"unit_7",title:"分数的意义和性质",description:"学习分数的意义、性质和约分、通分等方法",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"4周",totalLessons:16,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_7",icon:"½"},{unitId:"unit_8",title:"分数的加法和减法",description:"学习同分母分数、异分母分数的加法和减法",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"3周",totalLessons:12,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_8",icon:"➕"},{unitId:"unit_9",title:"折线统计图",description:"学习单式折线统计图和复式折线统计图的认识和制作",moduleCategory:"Probability and Statistics",estimatedDuration:"2周",totalLessons:6,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_9",icon:"📊"}]},ym=({className:r="",problemData:e,children:t})=>{const n=gn(),s=pn(),o=yn(),i=bn(),{updateUserAnswer:a,submitAnswer:c,nextQuestion:l,setProblemData:d}=xn();b.useEffect(()=>{e&&d(e)},[e,d]);const y=(()=>{switch(e?.basicInfo?.shape){case"triangle":return{titleColor:"text-cyan-600",label:"三角形面积"};case"parallelogram":return{titleColor:"text-blue-600",label:"平行四边形面积"};case"trapezoid":return{titleColor:"text-green-600",label:"梯形面积"};default:return e?.title?.includes("年龄")||e?.basicInfo?.question?.includes("年龄")?{titleColor:"text-purple-600",label:"年龄问题"}:{titleColor:"text-slate-600",label:"数学问题"}}})();return f.jsxs("div",{className:"min-h-screen bg-gradient-to-br from-slate-50 to-cyan-50 flex flex-col items-center justify-center p-4 font-sans",children:[f.jsxs("header",{className:"w-full max-w-4xl mb-8",children:[f.jsxs("div",{className:"flex flex-col md:flex-row md:items-center md:justify-between",children:[f.jsxs("div",{children:[f.jsx("h1",{className:`text-2xl md:text-3xl font-bold ${y.titleColor}`,children:e?.title||"数学问题练习"}),f.jsxs("p",{className:"text-slate-600 mt-2",children:[e?.grade||5,"年级 · ",e?.unit||"数学",e?.lesson&&` · ${e.lesson}`]})]}),f.jsx("div",{className:"mt-4 md:mt-0",children:f.jsx("span",{className:"inline-block px-3 py-1 text-sm font-medium rounded-full bg-white border border-slate-200 text-slate-700",children:y.label})})]}),e?.description&&f.jsx("p",{className:"mt-4 text-slate-700 bg-white/50 p-3 rounded-lg border border-slate-200",children:e.description})]}),f.jsx("main",{className:"w-full max-w-4xl bg-white border border-slate-200 rounded-xl shadow-sm overflow-hidden",children:e?f.jsxs(f.Fragment,{children:[n==="question"&&f.jsx(wt,{problemData:e,userAnswer:s,showAnswerForm:o,onAnswerSubmit:c,onAnswerChange:a,validationError:i}),n==="explanation"&&f.jsx(qt,{problemData:e,userAnswer:s,onNextQuestion:l}),n==="success"&&f.jsx(At,{problemData:e,onNextQuestion:l})]}):f.jsxs("div",{className:"p-8 text-center",children:[f.jsx("div",{className:"text-red-500 text-4xl mb-4",children:"⚠️"}),f.jsx("h3",{className:"text-xl font-semibold text-slate-800 mb-2",children:"缺少问题数据"}),f.jsx("p",{className:"text-slate-600",children:"请提供有效的problemData prop"})]})}),f.jsx("footer",{className:"w-full max-w-4xl mt-8 text-center text-slate-500 text-sm",children:f.jsxs("div",{className:"flex flex-col md:flex-row md:justify-between items-center",children:[f.jsx("div",{className:"mb-4 md:mb-0",children:f.jsx("p",{children:"使用MathCardV2组件系统 · 三场景交互设计"})}),f.jsx("div",{children:f.jsxs("p",{children:["数据源: ",e?.id||"未知"]})})]})}),t&&f.jsx("div",{className:"w-full max-w-4xl mt-8",children:t})]})},bm=new Proxy({},{get(){throw new Error(`⚠️ MathCard 已废弃!请使用 MathCardV2 代替。
253
+ The large square represents 1 whole.`},{type:"hundredGrid",content:"",props:{value:.12,mode:"readonly",rows:10,cols:10,cellSize:12,fillColor:"#a5b4fc",baseColor:"#e2e8f0",strokeColor:"#d1d5db",shadingDirection:"ltr",hasShadow:!0}}]}},explanation:[],answer:{value:.12,unit:"",explanation:"模型中100个方格有12个被涂色,代表12/100,即0.12。"}},rm=({className:r="",problemData:e})=>{const t=ai(),n=li(),s=ci(),o=em(),{updateUserAnswer:i,submitAnswer:a,nextQuestion:c,setProblemData:l}=di(),d=b.useMemo(()=>e||tm,[e]);return b.useEffect(()=>{l(d)},[d,l]),f.jsxs("div",{className:`max-w-4xl mx-auto p-4 md:p-8 bg-slate-50 min-h-screen ${r}`,children:[f.jsxs("header",{className:"mb-8",children:[f.jsx("h1",{className:"text-2xl font-bold text-slate-800",children:"小数认识练习"}),f.jsxs("p",{className:"text-slate-600 mt-2",children:[d.grade,"年级 - ",d.unit]}),f.jsx("p",{className:"text-slate-500 text-sm mt-1",children:"通过百格图模型理解百分位和小数的关系"})]}),f.jsxs("main",{className:"bg-white border border-slate-200 rounded-lg shadow-sm",children:[t==="question"&&f.jsx(wt,{problemData:d,userAnswer:n,showAnswerForm:s,onAnswerSubmit:a,onAnswerChange:i,validationError:o}),t==="explanation"&&f.jsx(Uu,{problemData:d,userAnswer:n,onNextQuestion:c}),t==="success"&&f.jsx(At,{problemData:d,onNextQuestion:c})]}),f.jsxs("div",{className:"mt-4 text-center text-sm text-slate-500",children:[t==="question"&&"请识别百格图代表的小数",t==="explanation"&&"查看详细解释",t==="success"&&"恭喜!答案正确"]})]})},Oe=(r,e,t)=>({x:r.x+(e.x-r.x)*t,y:r.y+(e.y-r.y)*t}),nm=()=>{const r={x:.5,y:.1,name:"A"},e={x:.1,y:.75,name:"B"},t={x:.9,y:.75,name:"C"},n={...Oe(r,e,1/3),name:"D"},s={...Oe(r,t,1/3),name:"E"},o={...Oe(r,e,2/3),name:"M"},i={...Oe(r,t,2/3),name:"N"},a={...Oe(e,t,1/3),name:"P"},c={...Oe(e,t,2/3),name:"Q"},l={...Oe(n,s,1/3),name:"U"},d={...Oe(n,s,2/3),name:"S"},u={...Oe(o,i,1/3),name:"K"},y={...Oe(o,i,2/3),name:"L"};return{A:r,B:e,C:t,D:n,E:s,M:o,N:i,P:a,Q:c,U:l,S:d,K:u,L:y}},sm=(r,e,t)=>{const n={};for(const[s,o]of Object.entries(r))n[s]={...o,x:o.x*e,y:o.y*t};return n},om=(r,e)=>{const[t,n,s]=e,{x:o,y:i}=r,a=(n.y-s.y)*(t.x-s.x)+(s.x-n.x)*(t.y-s.y);if(Math.abs(a)<1e-4)return!1;const c=((n.y-s.y)*(o-s.x)+(s.x-n.x)*(i-s.y))/a,l=((s.y-t.y)*(o-s.x)+(t.x-s.x)*(i-s.y))/a,d=1-c-l;return c>=-.001&&l>=-.001&&d>=-.001},im=(r,e)=>{if(!r||!e||r.length!==3||e.length!==3)return!1;const t=r.map(s=>s.name).sort(),n=e.map(s=>s.name).sort();return t.every((s,o)=>s===n[o])},am=(r,e)=>{if(!r||!e||r.length!==e.length)return!1;const t=r.map(s=>s.name).sort(),n=e.map(s=>s.name).sort();return t.join("")===n.join("")},lm=()=>[{from:"A",to:"B"},{from:"A",to:"C"},{from:"B",to:"C"},{from:"D",to:"E"},{from:"M",to:"N"},{from:"P",to:"Q"},{from:"A",to:"D"},{from:"A",to:"E"},{from:"A",to:"M"},{from:"A",to:"N"},{from:"A",to:"P"},{from:"A",to:"Q"},{from:"D",to:"U"},{from:"U",to:"S"},{from:"S",to:"E"},{from:"M",to:"K"},{from:"K",to:"L"},{from:"L",to:"N"},{from:"B",to:"P"},{from:"P",to:"Q"},{from:"Q",to:"C"}],cm=()=>[{id:"gem_1",vertices:["A","B","P"],points:10,category:"basic"},{id:"gem_2",vertices:["A","P","Q"],points:10,category:"basic"},{id:"gem_3",vertices:["A","Q","C"],points:10,category:"basic"},{id:"gem_4",vertices:["A","B","Q"],points:15,category:"medium"},{id:"gem_5",vertices:["A","P","C"],points:15,category:"medium"},{id:"gem_6",vertices:["A","B","C"],points:20,category:"large"},{id:"gem_7",vertices:["A","D","U"],points:12,category:"ade_small"},{id:"gem_8",vertices:["A","U","S"],points:12,category:"ade_small"},{id:"gem_9",vertices:["A","S","E"],points:12,category:"ade_small"},{id:"gem_10",vertices:["A","D","S"],points:18,category:"ade_medium"},{id:"gem_11",vertices:["A","U","E"],points:18,category:"ade_medium"},{id:"gem_12",vertices:["A","D","E"],points:25,category:"ade_large"},{id:"gem_13",vertices:["A","M","K"],points:14,category:"amn_small"},{id:"gem_14",vertices:["A","K","L"],points:14,category:"amn_small"},{id:"gem_15",vertices:["A","L","N"],points:14,category:"amn_small"},{id:"gem_16",vertices:["A","M","L"],points:20,category:"amn_medium"},{id:"gem_17",vertices:["A","K","N"],points:20,category:"amn_medium"},{id:"gem_18",vertices:["A","M","N"],points:30,category:"amn_large"}],dm={TOTAL_GEMS:18,CANVAS_RATIO:4/3,DEFAULT_VIEWBOX:{width:700,height:600},POINT_RADIUS:{default:6,selected:9},TOLERANCE:.001,MIN_TRIANGLE_AREA:.001,COORDINATE_PRECISION:1e-4,BARYCENTRIC_TOLERANCE:-.001},fi=(r=Bt.id)=>{const e=se.units.map((s,o)=>{const i=Math.min(100,Math.max(0,o*15+Math.random()*20)),a=Math.floor(s.lessons.length*i/100),c=s.lessons.map((l,d)=>{const u=Math.min(100,Math.max(0,i-d*10+Math.random()*30));return{lessonId:l.id,status:u>=100?"completed":u>0?"in-progress":"not-started",progressPercentage:Math.round(u),lastAccessed:u>0?new Date(Date.now()-Math.random()*7*24*60*60*1e3).toISOString():void 0,timeSpent:u>0?Math.floor(Math.random()*120+10):void 0,score:u>=100?Math.floor(Math.random()*21+80):void 0,attempts:u>0?Math.floor(Math.random()*3+1):void 0}});return{unitId:s.id,userId:r,totalLessons:s.lessons.length,completedLessons:a,progressPercentage:Math.round(i),status:i>=100?"completed":i>0?"in-progress":"not-started",lastAccessed:i>0?new Date(Date.now()-Math.random()*14*24*60*60*1e3).toISOString():void 0,lessons:c}}),t=e.reduce((s,o)=>s+o.progressPercentage,0)/e.length,n=e.filter(s=>s.status==="completed").length;return{courseId:se.id,userId:r,totalUnits:e.length,completedUnits:n,progressPercentage:Math.round(t),status:t>=100?"completed":t>0?"in-progress":"not-started",lastAccessed:new Date(Date.now()-Math.random()*3*24*60*60*1e3).toISOString(),units:e}},ui=fi(),Tn=(r,e)=>r===Bt.id&&e===se.id?ui:null,mi=(r,e,t)=>{const n=Tn(r,e);return n&&n.units.find(s=>s.unitId===t)||null},fm=(r,e,t,n)=>{const s=mi(r,e,t);return s&&s.lessons.find(o=>o.lessonId===n)||null},um=(r,e,t,n,s)=>(console.log("Updating lesson progress:",{userId:r,courseId:e,unitId:t,lessonId:n,progress:s}),!0),Nn=(r,e)=>{const t=Tn(r,e);if(!t)return null;const n=se.units.map((s,o)=>{const i=t.units.find(a=>a.unitId===s.id);return{unitId:s.id,title:s.title,description:s.description,moduleCategory:s.moduleCategory,estimatedDuration:s.estimatedDuration,totalLessons:s.lessons.length,completedLessons:i?.completedLessons||0,progressPercentage:i?.progressPercentage||0,status:i?.status||"not-started",lastAccessed:i?.lastAccessed,isActive:o===0,route:`/math/grade-${se.level}/unit/${s.id}`}});return{userId:r,courseId:se.id,courseTitle:se.title,courseLevel:se.level,totalUnits:n.length,completedUnits:n.filter(s=>s.status==="completed").length,overallProgress:t.progressPercentage,status:t.status,lastAccessed:t.lastAccessed,units:n}},mm=(r,e,t)=>{const n=Nn(r,e);return n&&n.units.find(s=>s.unitId===t)||null},hm=(r,e,t,n)=>(console.log("Updating unit active status:",{userId:r,courseId:e,unitId:t,isActive:n}),!0),gm=Nn(Bt.id,se.id),pm={userId:Bt.id,courseId:se.id,courseTitle:se.title,courseLevel:se.level,totalUnits:se.units.length,completedUnits:3,overallProgress:45,status:"in-progress",lastAccessed:"2024-01-15T10:30:00Z",units:[{unitId:"unit_1",title:"小数乘法",description:"学习小数乘法的计算方法及应用",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"3周",totalLessons:10,completedLessons:8,progressPercentage:80,status:"completed",lastAccessed:"2024-01-10T14:20:00Z",isActive:!1,route:"/math/grade-5/unit/unit_1",icon:"🔢"},{unitId:"unit_2",title:"小数除法",description:"学习小数除法的计算方法及应用",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"3周",totalLessons:12,completedLessons:6,progressPercentage:50,status:"in-progress",lastAccessed:"2024-01-15T10:30:00Z",isActive:!0,route:"/math/grade-5/unit/unit_2",icon:"➗"},{unitId:"unit_3",title:"简易方程",description:"学习用字母表示数和解简易方程",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"4周",totalLessons:14,completedLessons:2,progressPercentage:14,status:"in-progress",lastAccessed:"2024-01-12T16:45:00Z",isActive:!1,route:"/math/grade-5/unit/unit_3",icon:"📝"},{unitId:"unit_4",title:"多边形的面积",description:"学习平行四边形、三角形、梯形和组合图形的面积计算",moduleCategory:"Graphics and Geometry",estimatedDuration:"3周",totalLessons:12,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_4",icon:"📐"},{unitId:"unit_5",title:"因数与倍数",description:"学习因数、倍数、质数、合数等概念",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"3周",totalLessons:10,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_5",icon:"🔢"},{unitId:"unit_6",title:"长方体和正方体",description:"学习长方体和正方体的特征、表面积和体积计算",moduleCategory:"Graphics and Geometry",estimatedDuration:"4周",totalLessons:14,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_6",icon:"📦"},{unitId:"unit_7",title:"分数的意义和性质",description:"学习分数的意义、性质和约分、通分等方法",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"4周",totalLessons:16,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_7",icon:"½"},{unitId:"unit_8",title:"分数的加法和减法",description:"学习同分母分数、异分母分数的加法和减法",moduleCategory:"Arithmetic and Algebra",estimatedDuration:"3周",totalLessons:12,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_8",icon:"➕"},{unitId:"unit_9",title:"折线统计图",description:"学习单式折线统计图和复式折线统计图的认识和制作",moduleCategory:"Probability and Statistics",estimatedDuration:"2周",totalLessons:6,completedLessons:0,progressPercentage:0,status:"not-started",isActive:!1,route:"/math/grade-5/unit/unit_9",icon:"📊"}]},ym=({className:r="",problemData:e,children:t})=>{const n=gn(),s=pn(),o=yn(),i=bn(),{updateUserAnswer:a,submitAnswer:c,nextQuestion:l,setProblemData:d}=xn();b.useEffect(()=>{e&&d(e)},[e,d]);const y=(()=>{switch(e?.basicInfo?.shape){case"triangle":return{titleColor:"text-cyan-600",label:"三角形面积"};case"parallelogram":return{titleColor:"text-blue-600",label:"平行四边形面积"};case"trapezoid":return{titleColor:"text-green-600",label:"梯形面积"};default:return e?.title?.includes("年龄")||e?.basicInfo?.question?.includes("年龄")?{titleColor:"text-purple-600",label:"年龄问题"}:{titleColor:"text-slate-600",label:"数学问题"}}})();return f.jsxs("div",{className:`bg-gradient-to-br from-slate-50 to-cyan-50 flex flex-col items-center p-4 font-sans ${r}`,children:[f.jsxs("header",{className:"w-full max-w-4xl mb-8",children:[f.jsxs("div",{className:"flex flex-col md:flex-row md:items-center md:justify-between",children:[f.jsxs("div",{children:[f.jsx("h1",{className:`text-2xl md:text-3xl font-bold ${y.titleColor}`,children:e?.title||"数学问题练习"}),f.jsxs("p",{className:"text-slate-600 mt-2",children:[e?.grade||5,"年级 · ",e?.unit||"数学",e?.lesson&&` · ${e.lesson}`]})]}),f.jsx("div",{className:"mt-4 md:mt-0",children:f.jsx("span",{className:"inline-block px-3 py-1 text-sm font-medium rounded-full bg-white border border-slate-200 text-slate-700",children:y.label})})]}),e?.description&&f.jsx("p",{className:"mt-4 text-slate-700 bg-white/50 p-3 rounded-lg border border-slate-200",children:e.description})]}),f.jsx("main",{className:"w-full max-w-4xl bg-white border border-slate-200 rounded-xl shadow-sm",children:e?f.jsxs(f.Fragment,{children:[n==="question"&&f.jsx(wt,{problemData:e,userAnswer:s,showAnswerForm:o,onAnswerSubmit:c,onAnswerChange:a,validationError:i}),n==="explanation"&&f.jsx(qt,{problemData:e,userAnswer:s,onNextQuestion:l}),n==="success"&&f.jsx(At,{problemData:e,onNextQuestion:l})]}):f.jsxs("div",{className:"p-8 text-center",children:[f.jsx("div",{className:"text-red-500 text-4xl mb-4",children:"⚠️"}),f.jsx("h3",{className:"text-xl font-semibold text-slate-800 mb-2",children:"缺少问题数据"}),f.jsx("p",{className:"text-slate-600",children:"请提供有效的problemData prop"})]})}),f.jsx("footer",{className:"w-full max-w-4xl mt-8 text-center text-slate-500 text-sm",children:f.jsxs("div",{className:"flex flex-col md:flex-row md:justify-between items-center",children:[f.jsx("div",{className:"mb-4 md:mb-0",children:f.jsx("p",{children:"使用MathCardV2组件系统 · 三场景交互设计"})}),f.jsx("div",{children:f.jsxs("p",{children:["数据源: ",e?.id||"未知"]})})]})}),t&&f.jsx("div",{className:"w-full max-w-4xl mt-8",children:t})]})},bm=new Proxy({},{get(){throw new Error(`⚠️ MathCard 已废弃!请使用 MathCardV2 代替。
254
254
  更改: import { MathCard } from '@mathwiz/ui-components' → import { MathCardV2 as MathCard } from '@mathwiz/ui-components'`)}});exports.AbilityAssessmentDashboard=Jl;exports.AbilityProgressBar=co;exports.AreaGeometrySessionPage=ym;exports.Button=pt;exports.ContentAccordion=gs;exports.DEFAULT_IXL_CONFIG=Gl;exports.DecimalNumberRecognitionSessionPage=rm;exports.EquationRender=zt;exports.ExplanationScene=qt;exports.GEOMETRY_CONFIG=dm;exports.GeometryProblemAdapterV4=Yc;exports.GeometryTransform=Bs;exports.GradeNavigation=Vl;exports.GradeUnitBrowserPage=uc;exports.GradeUnitBrowserProvider=go;exports.GraphContainer=no;exports.HundredChart=Xs;exports.IXLStyleCard=xt;exports.IXL_COLORS=zl;exports.IXL_LABELS=Bl;exports.InputValidator=Yr;exports.MOCK_USER_COURSE_PROGRESS=ui;exports.MOCK_USER_GRADE_UNITS_NAV=gm;exports.MOCK_USER_GRADE_UNITS_PROGRESS=pm;exports.MathCard=bm;exports.MathCardV2=_e;exports.MathGraph=Ar;exports.MathPracticeSessionPage=Qu;exports.MathSessionContainer=ii;exports.MathSessionPage=Lu;exports.MathWizHeader=Us;exports.OutputValidator=Kr;exports.ParallelogramAreaCalculationSessionPage=Cf;exports.PersonalizedAdvicePanel=fo;exports.QuestionScene=wt;exports.RadarChart=lo;exports.RecommendationCard=uo;exports.RememberModule=yo;exports.ReviewModule=vn;exports.SCHEMA_VERSION=jo;exports.Sidebar=ps;exports.SolveModule=_n;exports.Submenu=tn;exports.SuccessScene=At;exports.TriangleAreaCalculationSessionPage=Ef;exports.UserProfile=Ls;exports.VERSION=Kc;exports.ValidationManager=lt;exports.adaptGeometryData=wn;exports.adaptGeometryDataAsync=wn;exports.adaptGeometryDataSync=ct;exports.adaptGeometryDataV4=ct;exports.benchmarkAdapter=Hc;exports.calculateBoundingBox=cn;exports.calculateDragRange=Ys;exports.calculateFilledCells=Ws;exports.calculateGamePoints=nm;exports.calculateValueFromDrag=Ks;exports.categoryIcons=Ot;exports.checkCompatibility=Xc;exports.comparePointArrays=am;exports.courseData=se;exports.createAsyncAdapter=Oo;exports.createGeometryDataAdapter=Oo;exports.createSyncAdapter=ko;exports.exploreItems=rc;exports.formatPercentage=Tl;exports.generateCellData=Hs;exports.generateMockUserCourseProgress=fi;exports.getBasicGemDefinitions=cm;exports.getBasicLineDefinitions=lm;exports.getUnitNavItem=mm;exports.getUserCourseProgress=Tn;exports.getUserGradeUnitsNav=Nn;exports.getUserLessonProgress=fm;exports.getUserUnitProgress=mi;exports.isGeometryProblem=Jc;exports.isPointInTriangle=om;exports.isV4Format=Mo;exports.loadGeometryProblemData=$o;exports.loadGeometryProblemDataAsync=$o;exports.loadGeometryProblemDataSync=No;exports.loadGeometryProblemDataV4=No;exports.pointOnLine=Oe;exports.statusColors=Ql;exports.statusMapping=Zl;exports.toPixelCoordinates=sm;exports.trianglesMatch=im;exports.updateUnitActiveStatus=hm;exports.updateUserLessonProgress=um;exports.useAnswerCorrectness=gc;exports.useAnswerFormVisibility=mn;exports.useCurrentScene=fn;exports.useDataAdapter=Js;exports.useDecimalAnswerFormVisibility=ci;exports.useDecimalCurrentScene=ai;exports.useDecimalSessionActions=di;exports.useDecimalUserAnswer=li;exports.useGeometryManagement=si;exports.useGradeUnitBrowser=ho;exports.useHundredChartDrag=qs;exports.useHundredChartStore=ln;exports.useHundredChartValue=Vs;exports.useIXLStyle=io;exports.useMathPracticeSessionStore=Xe;exports.useProblemData=pc;exports.useResponsive=ao;exports.useSessionActions=hn;exports.useSessionCalculations=ni;exports.useSessionEventHandlers=oi;exports.useSessionStore=ne;exports.useUserAnswer=un;exports.useValidationError=po;exports.userData=nc;exports.validateGeometryData=Wc;exports.validateValue=or;
255
255
  //# sourceMappingURL=index.cjs.map