openlearn-next 0.7.9 → 0.7.10

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.
Files changed (41) hide show
  1. package/README.md +4 -2
  2. package/cli-data.mjs +1 -1
  3. package/dist/assets/{ActivityWorkspaceWidget-DbspLRxB.js → ActivityWorkspaceWidget-BU88GGUG.js} +1 -1
  4. package/dist/assets/{AdminDirectoryView-C2ZFIwHx.js → AdminDirectoryView-Cdsk9Mdr.js} +1 -1
  5. package/dist/assets/{AssessmentCenter-DbJAcTvr.js → AssessmentCenter-BoSWbJMt.js} +1 -1
  6. package/dist/assets/{AssignmentFilePreview-DEVTb4YJ.js → AssignmentFilePreview-D_POvLmv.js} +1 -1
  7. package/dist/assets/{BatchPickerModal-czw6eA6e.js → BatchPickerModal-DiHd_6Tg.js} +1 -1
  8. package/dist/assets/{ClassesView-B1F0tTtB.js → ClassesView-CWKqzWH0.js} +1 -1
  9. package/dist/assets/{ClassroomCountdownWidget-C9pv3GLy.js → ClassroomCountdownWidget-B5-KUVU8.js} +1 -1
  10. package/dist/assets/{CloudDriveModal-goDB6dlC.js → CloudDriveModal-CjcvdDiw.js} +1 -1
  11. package/dist/assets/{ComputerLabView-Csqiqvw2.js → ComputerLabView-CNTcmWAh.js} +1 -1
  12. package/dist/assets/{CourseManagement-BD-4z2OZ.js → CourseManagement-ha_iSnLU.js} +1 -1
  13. package/dist/assets/{CourseWizardModal-NXwhuph_.js → CourseWizardModal-oVT9mYSG.js} +1 -1
  14. package/dist/assets/{Dashboard-CFDWNYSw.js → Dashboard-Vb9coh9_.js} +1 -1
  15. package/dist/assets/{ExportWeightModal-dBxYVUP4.js → ExportWeightModal-BEesz6rd.js} +1 -1
  16. package/dist/assets/{HelpView-DSZC-1F0.js → HelpView--Um9DFYx.js} +1 -1
  17. package/dist/assets/{ImportLessonsModal-m_s44eus.js → ImportLessonsModal-DXGopj4j.js} +1 -1
  18. package/dist/assets/{InteractiveCoursewareViewer-C7faFOFD.js → InteractiveCoursewareViewer-DzgF9_LU.js} +1 -1
  19. package/dist/assets/{InteractiveWhiteboard-10fno-bJ.js → InteractiveWhiteboard-DJqgP_tU.js} +7 -7
  20. package/dist/assets/{LazyCourseware-DNn0O8lA.js → LazyCourseware-6yb_QiYS.js} +2 -2
  21. package/dist/assets/{LazyWhiteboard-BxpydfnE.js → LazyWhiteboard-CsF9GB6J.js} +2 -2
  22. package/dist/assets/{LessonEditorView-CMCgnrJD.js → LessonEditorView-CZTZ7Q0B.js} +1 -1
  23. package/dist/assets/{LiveClassroomView-BA0us3bY.js → LiveClassroomView-D2ugupT9.js} +1 -1
  24. package/dist/assets/{NotificationDetailModal-BMrt09PY.js → NotificationDetailModal-mUeIQP4R.js} +1 -1
  25. package/dist/assets/{PluginView-B6gCF1ZB.js → PluginView-CT3-zS2n.js} +1 -1
  26. package/dist/assets/{QuizGeneratorModal-BNW6tZ78.js → QuizGeneratorModal-ViKxNX5Q.js} +1 -1
  27. package/dist/assets/{StudentAssignmentEvalPanel-DMwBSOXf.js → StudentAssignmentEvalPanel-BRxHMABY.js} +1 -1
  28. package/dist/assets/{StudentAssignmentView-cQpPme4_.js → StudentAssignmentView-g-ewJIS3.js} +1 -1
  29. package/dist/assets/{StudentLessonView-CpGgYV-b.js → StudentLessonView-Dbvr3Xlo.js} +1 -1
  30. package/dist/assets/{StudentView-BfXi6-NQ.js → StudentView-20vfEk4v.js} +2 -2
  31. package/dist/assets/{SystemResourceLibraryModal-d4vfqM_9.js → SystemResourceLibraryModal-CDKeaKf8.js} +1 -1
  32. package/dist/assets/{TeacherView-DSJCvFE-.js → TeacherView-KIKuhXGF.js} +2 -2
  33. package/dist/assets/{TimetableView-D9Rhnvfj.js → TimetableView-7V2AwWml.js} +1 -1
  34. package/dist/assets/{index-DCnGJbif.css → index-C4cHQZyx.css} +1 -1
  35. package/dist/assets/{index-DuxQtTr9.js → index-XduPa2-x.js} +31 -31
  36. package/dist/assets/{pluginParsers-HRw6CVog.js → pluginParsers-BO6U1E-h.js} +1 -1
  37. package/dist/assets/{student-workspace-DO1mSl_I.js → student-workspace-DstiW0pM.js} +1 -1
  38. package/dist/env-validation.cjs +14 -6
  39. package/dist/index.html +2 -2
  40. package/dist/server.cjs +681 -346
  41. package/package.json +2 -2
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/InteractiveCoursewareViewer-C7faFOFD.js","assets/vendor-react-DHoBZpn2.js","assets/vendor-utils-BxOuk3id.js","assets/index-DuxQtTr9.js","assets/vendor-icons-DLOPlM4i.js","assets/vendor-motion-BFAPOs-b.js","assets/index-DCnGJbif.css"])))=>i.map(i=>d[i]);
2
- import{_ as a}from"./vendor-pdf-DVWGghIL.js";import{j as e,r}from"./vendor-react-DHoBZpn2.js";const i=r.lazy(()=>a(()=>import("./InteractiveCoursewareViewer-C7faFOFD.js"),__vite__mapDeps([0,1,2,3,4,5,6])));function n(s){return e.jsx(r.Suspense,{fallback:e.jsx("div",{className:"flex items-center justify-center h-full bg-gray-50",children:e.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-500"})}),children:e.jsx(i,{...s})})}export{n as L};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/InteractiveCoursewareViewer-DzgF9_LU.js","assets/vendor-react-DHoBZpn2.js","assets/vendor-utils-BxOuk3id.js","assets/index-XduPa2-x.js","assets/vendor-icons-DLOPlM4i.js","assets/vendor-motion-BFAPOs-b.js","assets/index-C4cHQZyx.css"])))=>i.map(i=>d[i]);
2
+ import{_ as a}from"./vendor-pdf-DVWGghIL.js";import{j as e,r}from"./vendor-react-DHoBZpn2.js";const i=r.lazy(()=>a(()=>import("./InteractiveCoursewareViewer-DzgF9_LU.js"),__vite__mapDeps([0,1,2,3,4,5,6])));function n(s){return e.jsx(r.Suspense,{fallback:e.jsx("div",{className:"flex items-center justify-center h-full bg-gray-50",children:e.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-500"})}),children:e.jsx(i,{...s})})}export{n as L};
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/InteractiveWhiteboard-10fno-bJ.js","assets/vendor-react-DHoBZpn2.js","assets/vendor-utils-BxOuk3id.js","assets/index-DuxQtTr9.js","assets/vendor-icons-DLOPlM4i.js","assets/vendor-motion-BFAPOs-b.js","assets/AssignmentFilePreview-DEVTb4YJ.js","assets/index-DCnGJbif.css","assets/vendor-pptx-DIWdXF1L.css","assets/vendor-reveal-DcQQzuI9.css"])))=>i.map(i=>d[i]);
2
- import{_ as s}from"./vendor-pdf-DVWGghIL.js";import{r as t,j as e}from"./vendor-react-DHoBZpn2.js";const i=t.lazy(()=>s(()=>import("./InteractiveWhiteboard-10fno-bJ.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9])).then(r=>({default:r.InteractiveWhiteboard}))),n=t.forwardRef((r,a)=>e.jsx(t.Suspense,{fallback:e.jsx("div",{className:"flex items-center justify-center h-full bg-gray-50",children:e.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-500"})}),children:e.jsx(i,{ref:a,...r})}));export{n as L};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/InteractiveWhiteboard-DJqgP_tU.js","assets/vendor-react-DHoBZpn2.js","assets/vendor-utils-BxOuk3id.js","assets/index-XduPa2-x.js","assets/vendor-icons-DLOPlM4i.js","assets/vendor-motion-BFAPOs-b.js","assets/AssignmentFilePreview-D_POvLmv.js","assets/index-C4cHQZyx.css","assets/vendor-pptx-DIWdXF1L.css","assets/vendor-reveal-DcQQzuI9.css"])))=>i.map(i=>d[i]);
2
+ import{_ as s}from"./vendor-pdf-DVWGghIL.js";import{r as t,j as e}from"./vendor-react-DHoBZpn2.js";const i=t.lazy(()=>s(()=>import("./InteractiveWhiteboard-DJqgP_tU.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9])).then(r=>({default:r.InteractiveWhiteboard}))),n=t.forwardRef((r,a)=>e.jsx(t.Suspense,{fallback:e.jsx("div",{className:"flex items-center justify-center h-full bg-gray-50",children:e.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-500"})}),children:e.jsx(i,{ref:a,...r})}));export{n as L};
@@ -1 +1 @@
1
- import{j as e,r as p,R as oe}from"./vendor-react-DHoBZpn2.js";import{n as re,d as Pe,p as $e,q as Ae,v as me,w as Re,x as Le,y as _e,z as Me,B as Se,F as Fe,G as Qe,E as H,H as ye,I as Oe,J as qe,e as Ce,K as Ze,S as Be,j as le,L as ce,O as Ge,b as We,Q as He,R as ve}from"./index-DuxQtTr9.js";import{L as Ue}from"./LazyWhiteboard-BxpydfnE.js";import{P as Je,t as Ee,b9 as Ke,aU as je,ba as we,bb as Ve,aa as Ne,an as fe,x as Ye,af as be,a$ as Xe,X as Ie,a4 as ge,V as Te,k as et,bc as tt,aR as st,h as De,aZ as rt,L as at,ae as nt,D as ke,i as it,ab as ot,au as lt,c as pe,as as ct,bd as dt,T as ut,ai as ht,aQ as mt}from"./vendor-icons-DLOPlM4i.js";import{r as pt}from"./timeline-duration-BgdJCSrW.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-skggaP9D.js";function ze({config:s,lang:t,onActivate:a,disabled:u=!1,isFavorite:m=!1,onToggleFavorite:r}){const n=s.icon||Je,k=re[s.color]||re.indigo;return e.jsxs("div",{draggable:!u,onDragStart:f=>{if(u){f.preventDefault();return}const v={type:s.type,...s.defaultData},h=JSON.stringify(v);f.dataTransfer.effectAllowed="copy",f.dataTransfer.setData("application/json",h),f.dataTransfer.setData("text/plain",h)},onClick:()=>!u&&a(s.type),title:u?t==="zh"?"当前为只读模式":"Read-only mode":t==="zh"?"点击编辑并添加到画板,或拖拽到画板":"Click to edit & add, or drag onto the board","aria-disabled":u,className:`group relative bg-surface border border-theme rounded-xl p-2.5 shadow-sm transition-all duration-200 ${u?"opacity-60 cursor-not-allowed":"cursor-grab active:cursor-grabbing hover:shadow-md hover:-translate-y-0.5"} ${k.cardHoverBorder} ${k.cardHoverRing} ${k.cardHoverShadow} flex flex-col justify-between min-h-[92px]`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-1",children:[e.jsx("div",{className:`p-2 rounded-lg ${k.iconBg} ${k.iconText} transition-transform group-hover:scale-105 shrink-0`,children:e.jsx(n,{size:16})}),r&&e.jsx("button",{type:"button",onClick:f=>{f.stopPropagation(),r(s.type,f)},className:`p-1 rounded-md transition-colors ${m?"text-amber-400 opacity-100":"text-slate-300 opacity-0 group-hover:opacity-100 hover:text-amber-400 hover:bg-surface-secondary"}`,title:m?t==="zh"?"取消收藏":"Remove favorite":t==="zh"?"收藏组件":"Add favorite",children:e.jsx(Ee,{size:13,className:m?"fill-amber-400":""})})]}),e.jsxs("div",{className:"flex flex-col min-w-0 mt-1.5",children:[e.jsx("span",{className:"font-semibold text-xs text-main truncate group-hover:text-primary-theme transition-colors",children:t==="zh"?s.labelZh:s.labelEn}),e.jsx("span",{className:"text-xs text-muted leading-tight mt-0.5 truncate",children:t==="zh"?s.descriptionZh:s.descriptionEn})]}),e.jsx("div",{className:"absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none",children:e.jsx("span",{className:"text-xs font-bold text-indigo-500 bg-indigo-50 px-1 py-0.5 rounded border border-indigo-100",children:"+ Drag"})})]})}class xt{constructor(){this.items=new Map,this.providers=new Map,this.recents=[],this.favorites=new Set}registerItem(t){if(!t||!t.id)throw new Error("QuickInsertRegistry Error: QuickInsertItemDescriptor must have a valid ID.");this.items.set(t.id,t)}registerProvider(t){if(!t||!t.id)throw new Error("QuickInsertRegistry Error: QuickInsertProvider must have a valid ID.");this.providers.set(t.id,t);const a=t.getItems();for(const u of a)this.registerItem(u)}unregisterItem(t){return this.recents=this.recents.filter(a=>a!==t),this.favorites.delete(t),this.items.delete(t)}getItem(t){return this.items.get(t)}search(t="",a){const m=(t.startsWith("/")?t.slice(1):t).trim().toLowerCase(),r=Array.from(this.items.values());return Object.freeze(r.filter(n=>{if(a&&n.category!==a)return!1;if(!m)return!0;const k=n.title.toLowerCase().includes(m),f=n.description?.toLowerCase().includes(m)??!1,v=n.keywords?.some(h=>h.toLowerCase().includes(m))??!1;return k||f||v}))}async executeItem(t,a){const u=this.items.get(t);if(!u)throw new Error(`QuickInsertRegistry Error: Item '${t}' not found.`);this.recents=[t,...this.recents.filter(m=>m!==t)].slice(0,10),await u.execute(a)}getRecents(){const t=this.recents.map(a=>this.items.get(a)).filter(a=>a!==void 0);return Object.freeze(t)}getFavorites(){const t=Array.from(this.favorites).map(a=>this.items.get(a)).filter(a=>a!==void 0);return Object.freeze(t)}toggleFavorite(t){this.favorites.has(t)?this.favorites.delete(t):this.items.has(t)&&this.favorites.add(t)}listAll(){return Object.freeze(Array.from(this.items.values()))}clear(){this.items.clear(),this.providers.clear(),this.recents=[],this.favorites.clear()}}const ft=["Media","Shape","Tool","AI","Widget","Plugin"],xe=new xt,bt=({isOpen:s,onClose:t,registry:a=xe,initialQuery:u="/"})=>{const[m,r]=p.useState(u),[n,k]=p.useState("All"),[f,v]=p.useState(0),h=Pe(o=>o.extensionPoints),b=p.useMemo(()=>{const o=n==="All"?void 0:n,N=a.search(m,o),y=(h.get("quick_insert.item")??[]).map(x=>{const C=$e(x.slotProps),P=Ae(C.category,ft,"Plugin"),Q=me(C,"title"),O=me(C,"commandType"),g=Re(C.payload);return{id:x.id,title:x.label||Q||x.id,description:me(C,"description"),icon:typeof x.icon=="string"?x.icon:void 0,category:P,keywords:Me(C.keywords),execute:async w=>{if(O){const E=await Le.post("/api/plugins/execute-command",{type:O,payload:g??w});E.success||_e.getState().addToast({id:`plugin-cmd-error-${Date.now()}`,type:"error",title:"插件命令执行失败",message:E.error||`命令 ${O} 未能执行`})}}}}).filter(x=>{if(o&&x.category!==o)return!1;const P=(m.startsWith("/")?m.slice(1):m).trim().toLowerCase();if(!P)return!0;const Q=x.title.toLowerCase().includes(P),O=x.description?.toLowerCase().includes(P)??!1,g=x.keywords?.some(w=>w.toLowerCase().includes(P))??!1;return Q||O||g});return[...N,...y]},[a,m,n,h]),z=p.useCallback(o=>{if(o.key==="ArrowDown")o.preventDefault(),v(N=>N+1<b.length?N+1:0);else if(o.key==="ArrowUp")o.preventDefault(),v(N=>N-1>=0?N-1:b.length-1);else if(o.key==="Enter"){o.preventDefault();const N=b[f];N&&(a.getItem?.(N.id)?a.executeItem(N.id):N.execute(),t())}else o.key==="Escape"&&(o.preventDefault(),t())},[b,f,a,t]);return p.useEffect(()=>{v(0)},[m,n]),s?e.jsx("div",{className:"quick-insert-backdrop fixed inset-0 bg-slate-950/40 backdrop-blur-xs z-50 flex items-center justify-center",onClick:t,"data-testid":"quick-insert-backdrop",children:e.jsxs("div",{className:"quick-insert-container w-full max-w-lg bg-slate-900 border border-slate-800 rounded-xl shadow-2xl overflow-hidden flex flex-col",onClick:o=>o.stopPropagation(),"data-testid":"quick-insert-modal",children:[e.jsxs("div",{className:"flex items-center px-4 py-3 border-b border-slate-800 bg-slate-900/90",children:[e.jsx("span",{className:"text-indigo-400 font-mono font-bold text-lg mr-2",children:"/"}),e.jsx("input",{type:"text",className:"w-full bg-transparent text-slate-100 placeholder-slate-400 outline-none text-sm font-medium",placeholder:"Type a command or filter...",value:m.startsWith("/")?m.slice(1):m,onChange:o=>r("/"+o.target.value),onKeyDown:z,autoFocus:!0,"data-testid":"quick-insert-search-input"}),e.jsx("kbd",{className:"text-xs bg-slate-800 text-slate-400 px-2 py-0.5 rounded border border-slate-700 font-mono",children:"ESC"})]}),e.jsx("div",{className:"flex items-center space-x-1 px-3 py-1.5 border-b border-slate-800 bg-slate-900/50 overflow-x-auto",children:["All","Media","Shape","Tool","AI","Widget","Plugin"].map(o=>e.jsx("button",{className:`px-2 py-0.5 text-xs rounded-md transition-colors font-medium ${n===o?"bg-indigo-600 text-white":"text-slate-400 hover:bg-slate-800 hover:text-slate-200"}`,onClick:()=>k(o),children:o},o))}),e.jsx("div",{className:"max-h-80 overflow-y-auto p-2 divide-y divide-slate-800/40",children:b.length===0?e.jsx("div",{className:"py-6 text-center text-slate-500 text-sm",children:"No insertable items match slash command."}):b.map((o,N)=>e.jsxs("div",{className:`flex items-center justify-between px-3 py-2 rounded-lg cursor-pointer transition-colors ${N===f?"bg-indigo-600/20 text-white":"text-slate-300 hover:bg-slate-800/60"}`,onClick:()=>{a.getItem?.(o.id)?a.executeItem(o.id):o.execute(),t()},"data-testid":`quick-insert-item-${o.id}`,children:[e.jsxs("div",{className:"flex items-center space-x-2.5",children:[e.jsx("span",{className:"text-xs font-semibold px-2 py-0.5 rounded bg-slate-800 text-indigo-400 border border-slate-700",children:o.category}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-slate-100",children:o.title}),o.description&&e.jsx("div",{className:"text-xs text-slate-400",children:o.description})]})]}),o.shortcut&&e.jsx("kbd",{className:"text-xs font-mono text-slate-400 bg-slate-800 px-1.5 py-0.5 rounded border border-slate-700",children:o.shortcut})]},o.id))})]})}):null},gt={present:"Media",media:"Media",interact:"Tool",tool:"Tool",ai:"AI",widget:"Widget"};function yt(s){return Se.map(t=>{const a=s.lang==="zh"?t.labelZh:t.labelEn,u=s.lang==="zh"?t.descriptionZh:t.descriptionEn;return{id:`builtin.quickInsert.${t.type}`,title:a,description:u,category:gt[t.group]??"Widget",keywords:[t.type,...s.lang==="zh"?[t.labelZh]:[t.labelEn]],execute:()=>{s.readOnly||s.onActivate(t.type)}}})}function vt(s,t){for(const a of yt(t))s.registerItem(a)}function jt({lang:s,onActivate:t,readOnly:a=!1,collapsed:u,onToggleCollapse:m,pages:r,currentPage:n=0,onSwitchPage:k,onAddPage:f,onDeletePage:v,onRenamePage:h,dragState:b,onHoverDropTarget:z}){const[o,N]=p.useState(!1),c=u!==void 0?u:o,y=()=>{const l=!c;N(l),m&&m(l)},[x,C]=p.useState(""),[P,Q]=p.useState(!1),[O,g]=p.useState(""),[w,E]=p.useState(!1),[q,Z]=p.useState(null),[A,G]=p.useState(""),[_,F]=p.useState("all"),[I,U]=p.useState(()=>{try{const l=localStorage.getItem("openlearn_palette_favs");return l?JSON.parse(l):[]}catch{return[]}}),[de,X]=p.useState(()=>{try{const l=localStorage.getItem("openlearn_palette_recent");return l?JSON.parse(l):[]}catch{return[]}}),[R,ue]=p.useState({}),J=l=>{a||(X(d=>{const j=[l,...d.filter(T=>T!==l)].slice(0,6);try{localStorage.setItem("openlearn_palette_recent",JSON.stringify(j))}catch{}return j}),t(l))},ee=(l,d)=>{d.stopPropagation(),U(j=>{const D=j.includes(l)?j.filter(i=>i!==l):[...j,l];try{localStorage.setItem("openlearn_palette_favs",JSON.stringify(D))}catch{}return D})},ae=l=>{ue(d=>({...d,[l]:!d[l]}))},ne=p.useRef(J);ne.current=J,p.useEffect(()=>{vt(xe,{lang:s,onActivate:l=>ne.current(l),readOnly:a})},[s,a]);const he=Fe(),ie=[...Se,...he],V=ie.filter(l=>{if(x.trim()){const d=x.toLowerCase(),j=l.labelZh.toLowerCase().includes(d)||l.descriptionZh.toLowerCase().includes(d),T=l.labelEn.toLowerCase().includes(d)||l.descriptionEn.toLowerCase().includes(d);if(!j&&!T)return!1}return _==="favorites"?I.includes(l.type):_==="recent"?de.includes(l.type):!0}),te=oe.useRef(null),W=oe.useRef(null),B=oe.useRef(null),M=oe.useRef(null),[Y,se]=p.useState(null);return p.useEffect(()=>{if(!b){M.current&&(clearTimeout(M.current),M.current=null),B.current&&(clearTimeout(B.current),B.current=null),se(null),z?.(null);return}const{clientX:l,clientY:d}=b;if(te.current){const j=te.current.getBoundingClientRect(),T=l>=j.left&&l<=j.right&&d>=j.top&&d<=j.bottom;T&&c?B.current||(B.current=setTimeout(()=>{N(!1),m?.(!1),B.current=null},250)):!T&&B.current&&(clearTimeout(B.current),B.current=null)}if(W.current){const j=W.current.getBoundingClientRect(),T=l>=j.left&&l<=j.right&&d>=j.top&&d<=j.bottom;if(T&&w?M.current||(M.current=setTimeout(()=>{E(!1),M.current=null},250)):!T&&M.current&&(clearTimeout(M.current),M.current=null),!w&&r&&r.length>0){let D=null;W.current.querySelectorAll("[data-page-index]").forEach(S=>{const $=S.getBoundingClientRect();if(l>=$.left&&l<=$.right&&d>=$.top&&d<=$.bottom){const K=S.getAttribute("data-page-index");K!==null&&(D=parseInt(K,10))}}),D!==null&&D!==b.initialPage?(se(D),z?.({type:"page",pageIndex:D})):(se(null),z?.(null))}}},[b,c,w,r,m,z]),c?e.jsxs("div",{ref:te,className:`w-14 shrink-0 border-r border-theme bg-surface-secondary/40 backdrop-blur-md p-2 flex flex-col items-center gap-3 select-none transition-all duration-300 ${b?"ring-2 ring-primary-theme/50 bg-primary-theme/10":""}`,children:[e.jsx("button",{type:"button",onClick:y,className:"w-10 h-10 rounded-xl bg-surface hover:bg-surface-secondary border border-theme text-muted hover:text-main flex items-center justify-center transition-all cursor-pointer shadow-2xs hover:scale-105",title:s==="zh"?"展开备课组件库 (Ctrl+B)":"Expand Component Palette",children:e.jsx(Ke,{size:16})}),e.jsx("div",{className:"w-8 h-px bg-border/60 my-0.5"}),r&&r.length>0&&e.jsxs("button",{type:"button",onClick:y,className:"w-10 h-10 rounded-xl bg-surface hover:bg-primary-theme/10 border border-theme text-primary-theme flex items-center justify-center transition-all cursor-pointer shadow-2xs group relative",title:`${s==="zh"?"页面大纲":"Outline"} (P${n+1}/${r.length}) - ${s==="zh"?"点击展开":"Click to expand"}`,children:[e.jsx(je,{size:16}),e.jsx("span",{className:"absolute -top-1 -right-1 text-[9px] bg-primary-theme text-white rounded-full w-4 h-4 flex items-center justify-center font-bold",children:n+1})]}),e.jsx("div",{className:"flex flex-col gap-2 overflow-y-auto max-h-[calc(100vh-220px)] p-0.5",children:ie.slice(0,8).map(l=>{const d=l.icon||we;return e.jsx("button",{type:"button",onClick:()=>J(l.type),disabled:a,"aria-disabled":a,className:`w-10 h-10 rounded-xl bg-surface border border-theme text-main flex items-center justify-center transition-all shadow-2xs group relative ${a?"opacity-50 cursor-not-allowed":"hover:bg-primary-theme/10 hover:border-primary-theme cursor-pointer"}`,title:`${s==="zh"?l.labelZh:l.labelEn} - ${s==="zh"?"点击配置":"Configure"}`,children:e.jsx(d,{size:16,className:"text-primary-theme transition-transform group-hover:scale-110"})},l.type)})})]}):e.jsxs("div",{ref:te,className:`w-[260px] shrink-0 border-r border-theme bg-surface-secondary/40 backdrop-blur-md p-3.5 overflow-y-auto flex flex-col gap-3.5 font-sans select-none text-main transition-all duration-300 ${b&&Y!==null?"ring-1 ring-primary-theme/30":""}`,children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-theme/60 pb-2.5",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-7 h-7 rounded-lg bg-primary-theme/10 text-primary-theme flex items-center justify-center",children:e.jsx(we,{size:15})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xs font-black text-main uppercase tracking-wider",children:s==="zh"?"备课组件画板":"Palette"}),e.jsxs("span",{className:"text-[10px] text-muted",children:[V.length," ",s==="zh"?"个可用组件":"components"]})]})]}),e.jsx("button",{type:"button",onClick:y,className:"p-1.5 rounded-lg text-muted hover:text-main hover:bg-surface border border-theme/50 transition-colors cursor-pointer",title:s==="zh"?"收起组件面板以扩大画布":"Collapse Palette",children:e.jsx(Ve,{size:14})})]}),r&&r.length>0&&e.jsxs("div",{ref:W,className:`bg-surface rounded-xl border border-theme p-2.5 flex flex-col gap-2 shadow-2xs transition-all duration-200 ${Y!==null?"border-primary-theme shadow-md ring-1 ring-primary-theme/30":""}`,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("button",{type:"button",onClick:()=>E(l=>!l),className:"flex items-center gap-1.5 text-xs font-bold text-main hover:text-primary-theme transition-colors cursor-pointer",children:[e.jsx(je,{size:14,className:"text-primary-theme"}),e.jsxs("span",{children:[s==="zh"?"页面大纲":"Outline"," (",r.length,")"]}),e.jsx(Ne,{size:13,className:`text-muted transition-transform duration-200 ${w?"-rotate-90":""}`})]}),!a&&f&&e.jsx("button",{type:"button",onClick:()=>f(),className:"p-1 rounded-md text-muted hover:text-primary-theme hover:bg-primary-theme/10 transition-colors cursor-pointer",title:s==="zh"?"新建白板页面":"Add page",children:e.jsx(fe,{size:13})})]}),w?e.jsxs("div",{onClick:()=>E(!1),className:`flex items-center justify-between text-2xs px-2 py-1 bg-surface-secondary/70 rounded-lg text-muted hover:text-main cursor-pointer transition-colors ${b?"border border-dashed border-primary-theme/60 bg-primary-theme/10 text-primary-theme font-medium animate-pulse":""}`,children:[e.jsx("span",{className:"truncate max-w-[170px]",children:b?s==="zh"?"🎯 悬停自动展开页面大纲":"🎯 Hover to expand outline":`${s==="zh"?"当前":"Current"}: ${r[n]?.title||`P${n+1}`}`}),e.jsx("span",{className:"text-[10px] text-primary-theme font-medium",children:s==="zh"?"展开":"Expand"})]}):e.jsx("div",{className:"flex flex-col gap-1 max-h-48 overflow-y-auto pr-0.5 no-scrollbar",children:r.map((l,d)=>{const j=d===n,T=q===d,D=Y===d;return e.jsxs("div",{"data-page-index":d,onClick:()=>{T||k?.(d)},className:`group flex items-center justify-between px-2.5 py-1.5 rounded-lg text-xs transition-all cursor-pointer ${D?"ring-2 ring-primary-theme ring-offset-1 border-dashed border-2 border-primary-theme bg-primary-theme/15 animate-pulse":j?"bg-primary-theme text-white font-semibold shadow-xs":"bg-surface hover:bg-surface-secondary text-main border border-theme/40"}`,children:[e.jsxs("div",{className:"flex items-center gap-1.5 truncate min-w-0 flex-1",children:[e.jsxs("span",{className:`text-[10px] px-1 py-0.2 rounded font-mono shrink-0 ${D?"bg-primary-theme text-white font-bold":j?"bg-white/20 text-white":"bg-surface-secondary text-muted"}`,children:["P",d+1]}),T?e.jsx("input",{type:"text",autoFocus:!0,value:A,onChange:i=>G(i.target.value),onKeyDown:i=>{i.key==="Enter"&&(A.trim()&&h?.(d,A.trim()),Z(null)),i.key==="Escape"&&Z(null)},onBlur:()=>{A.trim()&&h?.(d,A.trim()),Z(null)},className:"px-1.5 py-0.5 text-xs bg-surface border border-primary-theme rounded text-main outline-none w-full",onClick:i=>i.stopPropagation()}):e.jsx("span",{className:"truncate",children:l.title})]}),D&&e.jsxs("span",{className:"text-[10px] font-bold text-primary-theme animate-bounce shrink-0 flex items-center gap-1 pl-1",children:[e.jsx("span",{children:"📥"}),e.jsx("span",{children:s==="zh"?"松开移入":"Drop"})]}),!a&&!T&&e.jsxs("div",{className:"flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity ml-1 shrink-0",onClick:i=>i.stopPropagation(),children:[h&&e.jsx("button",{type:"button",onClick:()=>{Z(d),G(l.title)},className:`p-0.5 rounded hover:bg-black/10 cursor-pointer ${j?"text-white":"text-muted hover:text-main"}`,title:"重命名",children:e.jsx(Ye,{size:11})}),r.length>1&&v&&e.jsx("button",{type:"button",onClick:()=>{window.confirm(`确定删除页面"${l.title}"吗?页面内的组件也将被清理。`)&&v(d)},className:`p-0.5 rounded hover:bg-rose-500/20 text-rose-500 cursor-pointer ${j?"text-white hover:bg-white/20":""}`,title:"删除此页",children:e.jsx(be,{size:11})})]})]},l.id||d)})})]}),e.jsxs("div",{className:"relative",children:[e.jsx(Xe,{size:13,className:"absolute left-2.5 top-1/2 -translate-y-1/2 text-muted"}),e.jsx("input",{type:"text",value:x,onChange:l=>{const d=l.target.value;if(d.startsWith("/")){g(d),Q(!0),C("");return}C(d)},placeholder:s==="zh"?"搜索画板组件...(输入 / 快速插入)":"Search components... (type / to quick insert)",className:"w-full pl-8 pr-7 py-1.5 bg-surface border border-theme rounded-xl text-xs text-main placeholder-muted outline-none focus:border-primary-theme focus:ring-1 focus:ring-primary-theme transition-all shadow-2xs"}),x&&e.jsx("button",{onClick:()=>C(""),className:"absolute right-2.5 top-1/2 -translate-y-1/2 text-muted hover:text-main cursor-pointer",children:e.jsx(Ie,{size:12})})]}),e.jsxs("div",{className:"flex items-center gap-1 bg-surface border border-theme p-1 rounded-xl shadow-2xs",children:[e.jsx("button",{type:"button",onClick:()=>F("all"),className:`flex-1 py-1 text-xs rounded-lg transition-all cursor-pointer ${_==="all"?"bg-surface-secondary text-main font-bold shadow-2xs":"text-muted hover:text-main font-medium"}`,children:s==="zh"?"全部":"All"}),e.jsxs("button",{type:"button",onClick:()=>F("favorites"),className:`flex-1 py-1 text-xs rounded-lg transition-all flex items-center justify-center gap-1 cursor-pointer ${_==="favorites"?"bg-amber-500/10 text-amber-600 font-bold border border-amber-500/20 shadow-2xs":"text-muted hover:text-amber-500 font-medium"}`,children:[e.jsx(Ee,{size:11,className:_==="favorites"?"fill-amber-500":""}),e.jsx("span",{children:s==="zh"?"常用":"Favs"})]}),e.jsxs("button",{type:"button",onClick:()=>F("recent"),className:`flex-1 py-1 text-xs rounded-lg transition-all flex items-center justify-center gap-1 cursor-pointer ${_==="recent"?"bg-primary-theme/10 text-primary-theme font-bold border border-primary-theme/20 shadow-2xs":"text-muted hover:text-primary-theme font-medium"}`,children:[e.jsx(ge,{size:11}),e.jsx("span",{children:s==="zh"?"最近":"Recent"})]})]}),e.jsxs("div",{className:"flex-1 flex flex-col gap-3 overflow-y-auto pr-0.5",children:[V.length===0?e.jsxs("div",{className:"text-center py-8 text-muted text-xs",children:[e.jsx(Te,{size:24,className:"mx-auto mb-2 opacity-30 text-primary-theme"}),e.jsx("p",{className:"font-bold text-main",children:s==="zh"?"未找到相关组件":"No components found"}),e.jsx("p",{className:"text-[11px] mt-1 text-muted",children:_!=="all"?s==="zh"?"尝试切换回「全部」标签":"Try switching to All tab":s==="zh"?"请更换关键词重新搜索":"Try a different keyword"})]}):_!=="all"||x.trim()?e.jsx("div",{className:"grid grid-cols-2 gap-2",children:V.map(l=>e.jsx(ze,{config:l,lang:s,onActivate:J,disabled:a,isFavorite:I.includes(l.type),onToggleFavorite:ee},l.type))}):(()=>{const l=[...Qe];return V.forEach(d=>{l.some(j=>j.id===d.group)||l.push({id:d.group,labelZh:d.group,labelEn:d.group})}),l.map(d=>{const j=V.filter(i=>i.group===d.id);if(j.length===0)return null;const T=re[j[0].color]||re.indigo,D=R[d.id];return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs("button",{type:"button",onClick:()=>ae(d.id),className:"flex items-center justify-between px-1.5 py-1 text-left rounded-lg transition-colors cursor-pointer hover:bg-surface-secondary/60",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full ${T.groupAccent}`}),e.jsx("span",{className:`text-[11px] font-black uppercase tracking-wider ${T.groupText}`,children:s==="zh"?d.labelZh:d.labelEn})]}),e.jsxs("div",{className:"flex items-center gap-1 text-muted",children:[e.jsxs("span",{className:"text-[10px] font-mono opacity-80",children:["(",j.length,")"]}),D?e.jsx(et,{size:12}):e.jsx(Ne,{size:12})]})]}),!D&&e.jsx("div",{className:"grid grid-cols-2 gap-2",children:j.map(i=>e.jsx(ze,{config:i,lang:s,onActivate:J,disabled:a,isFavorite:I.includes(i.type),onToggleFavorite:ee},i.type))})]},d.id)})})(),e.jsx(H,{slot:"editor.palette_item",slotProps:{lang:s,onActivate:J,readOnly:a}})]}),e.jsx(bt,{isOpen:P,onClose:()=>{Q(!1),g("")},registry:xe,initialQuery:O})]})}function wt({lang:s,segments:t,activeSegmentId:a,setActiveSegmentId:u,draggedSegmentIdx:m,setDraggedSegmentIdx:r,selectedLesson:n,saveTimeline:k,readOnly:f=!1,editorPanelsExpanded:v,setEditorPanelsExpanded:h,dragState:b,onHoverDropTarget:z}){const o=t.findIndex(g=>g.id===a),N=t.length>1&&o>=0?o/(t.length-1):0,c=o>=0?ye(t[o].color):null,y=p.useRef(null),[x,C]=p.useState(null);p.useEffect(()=>{if(!b){C(null),z?.(null);return}const{clientX:g,clientY:w}=b;if(y.current&&t&&t.length>0){let E=null;y.current.querySelectorAll("[data-segment-id]").forEach(Z=>{const A=Z.getBoundingClientRect();if(g>=A.left&&g<=A.right&&w>=A.top&&w<=A.bottom){const G=Z.getAttribute("data-segment-id");G&&(E=G)}}),E!==null&&E!==b.initialSegmentId?(C(E),z?.({type:"segment",segmentId:E})):(C(null),z?.(null))}},[b,t,z]);const P=t.reduce((g,w)=>{const{seconds:E}=pt(w,{fallbackSeconds:600});return E==null||!Number.isFinite(E)?g:g+Math.round(E/60)},0),Q=g=>{if(f)return;if(m===null||m===g){r(null);return}const w=[...t],[E]=w.splice(m,1);w.splice(g,0,E),r(null),n&&k(n,w)},O=()=>{if(f||!n)return;const g="seg-"+Math.random().toString(36).slice(2,9),w={id:g,title:s==="zh"?`新环节 ${t.length+1}`:`Segment ${t.length+1}`,notes:"",type:"lecture",duration:"10m",color:qe};k(n,[...t,w]),u(g),h(!0)};return e.jsxs("div",{ref:y,className:`sticky top-0 z-30 flex items-center justify-between gap-3 px-3.5 py-2 border-b border-theme bg-surface/95 backdrop-blur-md shrink-0 select-none overflow-x-auto text-main shadow-2xs transition-all ${b?"ring-1 ring-primary-theme/30":""}`,children:[e.jsxs("div",{className:"flex items-center gap-2 shrink-0 border-r border-theme pr-3",children:[e.jsx("div",{className:"w-6 h-6 rounded-lg bg-primary-theme/10 text-primary-theme flex items-center justify-center",children:e.jsx(tt,{size:14})}),e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{className:"text-xs font-black uppercase tracking-wider text-main whitespace-nowrap",children:s==="zh"?"教学流程":"Lesson Flow"}),e.jsxs("span",{className:"text-[10px] font-mono text-muted flex items-center gap-0.5",children:[e.jsx(ge,{size:9}),e.jsxs("span",{children:[P," min"]})]})]})]}),e.jsxs("div",{className:"relative flex items-center gap-2 py-0.5 min-w-0 flex-1",children:[e.jsx("div",{className:"absolute left-3 right-3 top-1/2 h-0.5 -translate-y-1/2 bg-border/80 rounded-full"}),o>=0&&e.jsx("div",{className:`absolute left-3 top-1/2 h-0.5 -translate-y-1/2 rounded-full transition-all duration-300 ${c?.rail||"bg-primary-theme"}`,style:{width:`calc(${N*100}% - 0.5rem)`}}),t.map((g,w)=>{const E=g.id===a,q=o>=0&&w<o,Z=m===w,A=x===g.id,G=Oe(g.type),_=ye(g.color),F=G.icon,I=A?"ring-2 ring-primary-theme ring-offset-2 border-dashed border-2 border-primary-theme bg-primary-theme/20 shadow-md scale-108 animate-pulse text-primary-theme font-bold":E?_.solid+" shadow-md ring-2 ring-primary-theme/30 scale-105":q?"bg-surface-secondary/90 text-main/80 border-primary-theme/30":_.color;return e.jsxs("div",{"data-segment-id":g.id,draggable:!f,onDragStart:U=>{if(f){U.preventDefault();return}r(w),U.dataTransfer.effectAllowed="move"},onDragOver:U=>!f&&U.preventDefault(),onDrop:()=>Q(w),onClick:()=>u(g.id),"aria-disabled":f,className:`relative z-10 flex items-center gap-1.5 px-2.5 py-1 rounded-xl text-xs font-semibold ${f?"cursor-pointer":"cursor-grab"} transition-all duration-200 border border-theme/60 shadow-2xs group ${I} ${Z?"opacity-40 scale-95":"hover:scale-102"}`,children:[e.jsx(st,{size:11,className:"opacity-0 group-hover:opacity-60 -ml-0.5 text-muted cursor-grab"}),e.jsx("span",{className:"text-[10px] font-mono font-bold opacity-75",children:w+1}),e.jsx(F,{size:12,className:"shrink-0"}),e.jsx("span",{className:"truncate max-w-[90px]",children:g.title}),e.jsxs("span",{className:"text-[10px] font-mono opacity-60",children:["(",g.duration||"10m",")"]}),q&&e.jsx(De,{size:11,className:"text-emerald-500 shrink-0 ml-0.5"}),e.jsx(H,{slot:"editor.timeline.node_badge",slotProps:{segment:g,idx:w,isActive:E,isCompleted:q,lang:s}}),A&&e.jsxs("span",{className:"text-[10px] font-bold text-primary-theme animate-bounce flex items-center gap-0.5 ml-1",children:[e.jsx("span",{children:"📥"}),e.jsx("span",{children:s==="zh"?"移入此环节":"Move here"})]})]},g.id)}),n&&!f&&e.jsxs("button",{type:"button",onClick:O,className:"relative z-10 flex items-center gap-1 px-2 py-1 rounded-xl text-xs font-medium text-muted hover:text-primary-theme bg-surface hover:bg-surface-secondary border border-dashed border-theme hover:border-primary-theme transition-all cursor-pointer shadow-2xs",title:s==="zh"?"追加新环节":"Add new segment",children:[e.jsx(fe,{size:12}),e.jsx("span",{className:"hidden sm:inline",children:s==="zh"?"加环节":"Add"})]})]}),e.jsxs("button",{type:"button",onClick:()=>h(g=>!g),"aria-expanded":v,className:`px-3 py-1 text-xs font-bold rounded-xl border transition-all flex items-center gap-1.5 cursor-pointer shrink-0 ${v?"bg-primary-theme text-white border-primary-theme shadow-md shadow-primary-theme/30 ring-2 ring-primary-theme/30 scale-102":"bg-surface hover:bg-surface-secondary text-muted hover:text-main border-theme shadow-2xs"}`,title:s==="zh"?"展开/收起环节设置面板":"Toggle Segment Settings",children:[e.jsx(rt,{size:13,className:v?"rotate-90 transition-transform text-white":""}),e.jsx("span",{children:s==="zh"?"环节参数":"Settings"}),v&&e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-white animate-ping ml-0.5"})]})]})}const Nt=[{type:"quiz_completed",labelZh:"完成练习",labelEn:"Quiz completed"},{type:"quiz_accuracy",labelZh:"练习正确率",labelEn:"Quiz accuracy"},{type:"assignment_submitted",labelZh:"已提交作业",labelEn:"Assignment submitted"},{type:"dwell_seconds",labelZh:"停留时长",labelEn:"Dwell time"},{type:"checked_in",labelZh:"已签到",labelEn:"Checked in"}];function kt(s){const t=[];for(const a of s){if(a.status!=="active")continue;let u={};try{u=JSON.parse(a.manifest)}catch{continue}const m=u.contributes?.["segment.gate_type"];if(Array.isArray(m))for(const r of m){if(!r||typeof r!="object")continue;const n=r.id,k=r.commandType;typeof n!="string"||typeof k!="string"||t.push(r)}}return t}function zt(s){return Array.isArray(s)?s.filter(t=>t&&typeof t=="object"&&typeof t.type=="string"):[]}function St({lang:s,segment:t,readOnly:a=!1,onPatch:u}){const m=Ce(h=>h.plugins),r=kt(m),n=zt(t.gates),k=[...Nt.map(h=>({type:h.type,label:s==="zh"?h.labelZh:h.labelEn})),...r.map(h=>({type:h.id,label:(s==="zh"?h.labelZh:h.labelEn)||h.id}))],f=h=>u({gates:h}),v=(h,b)=>{const z=n.map((o,N)=>N===h?{...o,...b,params:{...o.params||{},...b.params||{}}}:o);f(z)};return e.jsxs("div",{className:"flex flex-col gap-2 rounded-xl p-2.5 bg-indigo-500/5 border border-indigo-500/20",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("span",{className:"text-[11px] font-bold text-indigo-700 dark:text-indigo-300 flex items-center gap-1.5",children:[e.jsx(at,{size:12}),e.jsx("span",{children:s==="zh"?"进入条件":"Entry conditions"})]}),!a&&e.jsxs("button",{type:"button",onClick:()=>f([...n,{type:"quiz_completed",params:{}}]),className:"text-[11px] font-bold text-indigo-700 flex items-center gap-1 cursor-pointer",children:[e.jsx(fe,{size:12}),s==="zh"?"添加条件":"Add condition"]})]}),e.jsx("p",{className:"text-[10px] text-muted leading-snug",children:s==="zh"?"课级 progress_mode 已废弃。条件写在本环节上,全部满足后学生才能看到这一环节。全班仍跟随教师的当前环节。":"Lesson-level progress_mode is deprecated. Students see this segment only after every condition below is met. The class still shares one current segment."}),n.length===0&&e.jsx("p",{className:"text-[11px] text-muted",children:s==="zh"?"未设置条件,跟随课堂即可进入。":"No conditions. Following the class is enough."}),n.map((h,b)=>e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-4 gap-2 items-end",children:[e.jsxs("label",{className:"flex flex-col gap-1 sm:col-span-2",children:[e.jsx("span",{className:"text-[10px] font-bold text-muted",children:s==="zh"?"条件类型":"Type"}),e.jsxs("select",{"aria-label":s==="zh"?"条件类型":"Condition type",value:h.type,disabled:a,onChange:z=>{const o=n.map((N,c)=>c===b?{type:z.target.value,params:{}}:N);f(o)},className:"border border-theme/80 px-2 py-1.5 rounded-xl bg-surface text-xs",children:[k.map(z=>e.jsx("option",{value:z.type,children:z.label},z.type)),!k.some(z=>z.type===h.type)&&e.jsx("option",{value:h.type,children:h.type})]})]}),e.jsx(Et,{lang:s,gate:h,readOnly:a,onChange:z=>v(b,{params:z})}),!a&&e.jsxs("button",{type:"button",onClick:()=>f(n.filter((z,o)=>o!==b)),className:"px-2 py-1.5 text-xs text-rose-600 border border-rose-200 rounded-xl cursor-pointer flex items-center justify-center gap-1",children:[e.jsx(be,{size:12}),s==="zh"?"移除":"Remove"]})]},`${h.type}-${b}`))]})}function Ct(s,t){const a=s?.[t];return typeof a=="string"||typeof a=="number"?String(a):""}function Et({lang:s,gate:t,readOnly:a,onChange:u}){const m=t.params||{},r=(n,k,f,v=!1)=>e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-[10px] font-bold text-muted",children:k}),e.jsx("input",{value:Ct(m,n),disabled:a,placeholder:f,onChange:h=>{if(!v){u({[n]:h.target.value});return}const b=Number(h.target.value);u({[n]:h.target.value.trim()===""||!Number.isFinite(b)?h.target.value:b})},className:"border border-theme/80 px-2 py-1.5 rounded-xl bg-surface text-xs"})]});return t.type==="checked_in"?e.jsx("div",{}):t.type==="quiz_accuracy"?e.jsxs(e.Fragment,{children:[r("minScore",s==="zh"?"最低分":"Min score","60",!0),r("elementId",s==="zh"?"题目 ID":"Element ID","")]}):t.type==="dwell_seconds"?r("seconds",s==="zh"?"秒":"Seconds","60",!0):t.type==="assignment_submitted"?r("assignmentId",s==="zh"?"作业 ID":"Assignment ID",""):t.type==="quiz_completed"?r("elementId",s==="zh"?"题目 ID":"Element ID",""):r("segmentId",s==="zh"?"环节 ID":"Segment ID","")}function It({lang:s,segment:t,readOnly:a=!1,onPatch:u,onDelete:m}){const r=Ze();return e.jsxs("div",{className:"relative mx-3 sm:mx-4 my-3 rounded-2xl bg-surface/98 backdrop-blur-xl border-2 border-primary-theme/50 dark:border-primary-theme/60 shadow-2xl shadow-primary-theme/20 ring-4 ring-primary-theme/15 overflow-hidden shrink-0 text-main animate-in fade-in-0 zoom-in-[0.98] slide-in-from-top-3 duration-300 ease-out transition-all",children:[e.jsx("div",{className:"pointer-events-none absolute -top-12 -left-12 w-64 h-32 bg-primary-theme/15 rounded-full blur-2xl opacity-60"}),e.jsx("div",{className:"pointer-events-none absolute -bottom-12 -right-12 w-64 h-32 bg-indigo-500/10 rounded-full blur-2xl opacity-60"}),e.jsx("div",{className:"relative h-1.5 w-full bg-gradient-to-r from-primary-theme via-indigo-500 to-sky-400 shadow-sm shadow-primary-theme/30",children:e.jsx("div",{className:"absolute inset-0 bg-gradient-to-r from-transparent via-white/40 to-transparent animate-pulse"})}),e.jsxs("div",{className:"p-3.5 sm:p-4 flex flex-col gap-3.5 relative z-1",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 pb-2.5 border-b border-primary-theme/15",children:[e.jsxs("div",{className:"flex items-center gap-2.5 min-w-0",children:[e.jsxs("div",{className:"relative w-8 h-8 rounded-xl bg-gradient-to-br from-primary-theme/25 to-primary-theme/10 text-primary-theme flex items-center justify-center shrink-0 border border-primary-theme/40 shadow-xs",children:[e.jsx(nt,{size:15}),e.jsxs("span",{className:"absolute -top-1 -right-1 flex h-3 w-3",children:[e.jsx("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-primary-theme opacity-80"}),e.jsx("span",{className:"relative inline-flex rounded-full h-3 w-3 bg-primary-theme ring-2 ring-surface shadow-xs"})]})]}),e.jsxs("div",{className:"flex items-center gap-2 truncate",children:[e.jsxs("span",{className:"text-xs sm:text-sm font-black text-main tracking-tight truncate flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-2 h-2 rounded-full bg-primary-theme animate-pulse"}),s==="zh"?`环节参数配置:${t.title}`:`Segment Config: ${t.title}`]}),e.jsxs("span",{className:"hidden sm:inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-[10px] font-black uppercase tracking-wider bg-primary-theme text-white shadow-xs shadow-primary-theme/30 animate-pulse",children:[e.jsx(Te,{size:10}),s==="zh"?"正在聚焦编辑":"Active Editing"]}),e.jsxs("span",{className:"text-[10px] text-muted font-mono opacity-80 bg-surface-secondary/80 px-1.5 py-0.5 rounded-md border border-theme/50",children:["ID: ",t.id]})]})]}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx(H,{slot:"editor.timeline.node_badge",slotProps:{segment:t,lang:s,isActive:!0,isCompleted:!1}}),e.jsx(H,{slot:"editor.segment.action",slotProps:{segmentId:t.id,segment:t,lang:s,readOnly:a,onPatch:u}}),a?e.jsx("span",{className:"text-2xs font-semibold text-muted px-2 py-1 rounded-lg border border-theme",children:s==="zh"?"只读":"Read-only"}):e.jsxs("button",{type:"button",onClick:m,className:"px-2.5 py-1 text-xs text-rose-600 hover:text-white bg-rose-500/10 hover:bg-rose-600 border border-rose-500/25 rounded-xl flex items-center gap-1.5 transition-all hover:scale-102 cursor-pointer shadow-2xs shrink-0",title:s==="zh"?"删除当前环节":"Delete Segment",children:[e.jsx(be,{size:12}),e.jsx("span",{children:s==="zh"?"删除环节":"Delete"})]})]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-4 gap-2.5",children:[e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsxs("span",{className:"text-[11px] font-bold text-muted flex items-center gap-1",children:[e.jsx(ke,{size:11,className:"text-primary-theme"}),e.jsx("span",{children:s==="zh"?"环节名称":"Title"})]}),e.jsx("input",{type:"text",value:t.title||"",onChange:n=>u({title:n.target.value}),disabled:a,className:"border border-theme/80 px-2.5 py-1.5 rounded-xl bg-surface-secondary/80 focus:bg-surface text-xs text-main font-medium outline-none focus:border-primary-theme focus:ring-2 focus:ring-primary-theme/25 transition-all shadow-2xs"})]}),e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsxs("span",{className:"text-[11px] font-bold text-muted flex items-center gap-1",children:[e.jsx(ge,{size:11,className:"text-primary-theme"}),e.jsx("span",{children:s==="zh"?"预计用时":"Duration"})]}),e.jsx("input",{type:"text",value:t.duration||"10m",onChange:n=>u({duration:n.target.value}),disabled:a,placeholder:"例如: 10m",className:"border border-theme/80 px-2.5 py-1.5 rounded-xl bg-surface-secondary/80 focus:bg-surface text-xs text-main font-mono outline-none focus:border-primary-theme focus:ring-2 focus:ring-primary-theme/25 transition-all shadow-2xs"})]}),e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsxs("span",{className:"text-[11px] font-bold text-muted flex items-center gap-1",children:[e.jsx(it,{size:11,className:"text-primary-theme"}),e.jsx("span",{children:s==="zh"?"教学形态":"Instructional Type"})]}),e.jsx("select",{value:t.type||"lecture",onChange:n=>u({type:n.target.value}),disabled:a,className:"border border-theme/80 px-2.5 py-1.5 rounded-xl bg-surface-secondary/80 focus:bg-surface text-xs text-main font-medium outline-none focus:border-primary-theme focus:ring-2 focus:ring-primary-theme/25 transition-all shadow-2xs cursor-pointer",children:r.map(n=>e.jsx("option",{value:n.id,className:"bg-surface text-main",children:s==="zh"?n.labelZh:n.labelEn},n.id))})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("span",{className:"text-[11px] font-bold text-muted flex items-center gap-1",children:[e.jsx(ot,{size:11,className:"text-primary-theme"}),e.jsx("span",{children:s==="zh"?"环节标识色":"Accent Color"})]}),e.jsx("div",{className:"flex items-center gap-1.5 pt-1",children:Be.map(n=>e.jsx("button",{type:"button",onClick:()=>u({color:n.color}),disabled:a,"aria-label":s==="zh"?`选择颜色 ${n.name}`:`Choose color ${n.name}`,className:`w-5 h-5 rounded-full border border-theme/60 transition-all hover:scale-115 cursor-pointer ${n.color.split(" ")[0]} ${t.color===n.color?"ring-2 ring-primary-theme ring-offset-2 scale-110 shadow-xs":""}`,title:n.name},n.name))})]})]}),e.jsxs("div",{className:"flex flex-col gap-1 rounded-xl p-2.5 bg-amber-500/5 dark:bg-amber-500/10 border border-amber-500/20",children:[e.jsxs("span",{className:"text-[11px] font-bold text-amber-700 dark:text-amber-400 flex items-center gap-1.5",children:[e.jsx(ke,{size:12,className:"text-amber-500"}),e.jsx("span",{children:s==="zh"?"教师备课备忘 & 教学设计要点":"Instructional Notes"})]}),e.jsx("textarea",{rows:2,value:t.notes||"",onChange:n=>u({notes:n.target.value}),disabled:a,placeholder:s==="zh"?"写给自己的教学小抄:本环节核心提问、白板板书重点、容易卡壳的步骤…":"Teaching points, blackboard highlights, key student friction points…",className:"w-full border border-theme/70 px-3 py-1.5 rounded-xl bg-surface/90 focus:bg-surface text-xs text-main placeholder-muted outline-none focus:border-primary-theme focus:ring-2 focus:ring-primary-theme/20 transition-all resize-y shadow-2xs leading-relaxed"})]}),e.jsx(St,{lang:s,segment:t,readOnly:a,onPatch:u}),e.jsx(H,{slot:"editor.segment.type_config",slotProps:{segmentType:t.type||"lecture",segment:t,lang:s,readOnly:a,onPatch:u}}),e.jsx(H,{slot:"editor.timeline_segment",slotProps:{segment:t,lang:s,readOnly:a,onPatch:u}})]})]})}function Tt({config:s,lang:t,initialData:a,onConfirm:u,onCancel:m}){const[r,n]=p.useState(()=>({...a})),[k,f]=p.useState({}),v=s.icon,h=re[s.color]||re.indigo,b=Array.isArray(s.editFields)?s.editFields:[];p.useEffect(()=>{let c=!1;const y=b.filter(x=>x.kind==="select"&&x.loadOptions);if(y.length!==0)return Promise.all(y.map(async x=>{try{const C=await x.loadOptions();return[x.key,C]}catch{return[x.key,[]]}})).then(x=>{c||f(Object.fromEntries(x))}),()=>{c=!0}},[s]);const z=(c,y)=>{n(x=>({...x,[c]:y}))},o=Array.isArray(r.options)?r.options:[],N=(c,y)=>{n(x=>({...x,options:o.map((C,P)=>P===c?y:C)}))};return e.jsx("div",{className:"fixed inset-0 bg-gray-900/40 backdrop-blur-sm flex items-center justify-center p-6 z-50",children:e.jsxs("div",{className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-md flex flex-col overflow-hidden",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 flex items-center justify-between bg-gray-50/80",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-xl ${h.iconBg} ${h.iconText}`,children:v?e.jsx(v,{size:18}):null}),e.jsx("h2",{className:"font-bold text-gray-800 text-base",children:t==="zh"?`编辑:${s.labelZh}`:`Edit: ${s.labelEn}`})]}),e.jsx("button",{onClick:m,className:"text-gray-400 hover:text-gray-600 font-bold p-1 hover:bg-gray-200 rounded transition-colors text-lg",children:"×"})]}),e.jsx("div",{className:"p-5 space-y-4",children:b.length===0?e.jsx("p",{className:"text-sm text-gray-500 leading-relaxed",children:t==="zh"?"该组件无需预编辑内容,确认后即可添加到画板。":"No content to edit for this component. Confirm to add it to the board."}):b.map(c=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-600",children:t==="zh"?c.labelZh:c.labelEn}),c.kind==="options"?e.jsx("div",{className:"grid grid-cols-2 gap-2",children:o.map((y,x)=>e.jsx("input",{value:y,onChange:C=>N(x,C.target.value),placeholder:`${String.fromCharCode(65+x)}`,className:"border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"},x))}):c.kind==="textarea"?e.jsx("textarea",{value:r[c.key]??"",onChange:y=>z(c.key,y.target.value),placeholder:t==="zh"?c.placeholderZh:c.placeholderEn,rows:5,className:`w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 resize-y ${c.key==="code"||c.key==="markdown"?"font-mono text-[12px]":""}`}):c.kind==="select"?e.jsxs("select",{value:r[c.key]??"",onChange:y=>z(c.key,y.target.value),className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 bg-white",children:[e.jsx("option",{value:"",children:t==="zh"?"— 不选择 —":"— None —"}),(k[c.key]??c.options??[]).map(y=>e.jsx("option",{value:y.value,children:y.label},y.value))]}):e.jsx("input",{type:"text",value:r[c.key]??"",onChange:y=>z(c.key,y.target.value),placeholder:t==="zh"?c.placeholderZh:c.placeholderEn,className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"})]},c.key))}),e.jsxs("div",{className:"p-4 border-t border-gray-100 flex justify-end gap-2",children:[e.jsx("button",{onClick:m,className:"px-4 py-2 text-sm rounded-lg border border-gray-200 text-gray-600 hover:bg-gray-100 cursor-pointer",children:t==="zh"?"取消":"Cancel"}),e.jsx("button",{onClick:()=>u(r),className:"px-4 py-2 text-sm rounded-lg bg-indigo-600 text-white hover:bg-indigo-700 cursor-pointer",children:t==="zh"?"添加到画板":"Add to Board"})]})]})})}class Dt{constructor(t){this.lessonId=null,this.debounceDelay=800,this.status="none",this.lastSavedTime=null,this.pendingMap=new Map,this.timer=null,this.isFlushing=!1,this.lastError=null,this.saveHandler=null,this.interceptors=new Set,this.listeners=new Set,t?.debounceDelay!==void 0&&(this.debounceDelay=t.debounceDelay),t?.saveHandler&&(this.saveHandler=t.saveHandler)}setLessonId(t){this.lessonId!==t&&(this.pendingMap.size>0&&this.lessonId&&this.flush(),this.lessonId=t,this.status=t?"saved":"none",this.notifyListeners())}getLessonId(){return this.lessonId}setSaveHandler(t){this.saveHandler=t}setDebounceDelay(t){this.debounceDelay=Math.max(100,t)}getDebounceDelay(){return this.debounceDelay}getStatus(){return this.status}getLastSavedTime(){return this.lastSavedTime}getPendingCount(){return this.pendingMap.size}getLastError(){return this.lastError}registerInterceptor(t){return this.interceptors.add(t),()=>{this.interceptors.delete(t)}}registerListener(t){return this.listeners.add(t),t(this.status,{lessonId:this.lessonId||void 0,lastSavedTime:this.lastSavedTime,count:this.pendingMap.size}),()=>{this.listeners.delete(t)}}notifyListeners(){this.listeners.forEach(t=>{try{t(this.status,{lessonId:this.lessonId||void 0,lastSavedTime:this.lastSavedTime,error:this.lastError,count:this.pendingMap.size})}catch(a){console.error("[WhiteboardAutoSaveManager] Listener error:",a)}})}queueUpdate(t,a){if(!this.lessonId)return;const u=this.pendingMap.get(t)||{};this.pendingMap.set(t,{...u,...a}),this.status="pending",this.notifyListeners(),le.publish({id:ce(),type:"whiteboard.autosave.pending",source:"whiteboard.autosave",payload:{lessonId:this.lessonId,elementId:t,pendingCount:this.pendingMap.size},timestamp:Date.now(),correlationId:this.lessonId}),this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.flush()},this.debounceDelay)}async flush(){if(this.timer&&(clearTimeout(this.timer),this.timer=null),this.pendingMap.size===0||!this.lessonId||!this.saveHandler)return this.status==="pending"&&(this.status="saved",this.notifyListeners()),!0;if(this.isFlushing)return!1;let t=!1;const a={lessonId:this.lessonId,pendingElements:new Map(this.pendingMap),cancel:()=>{t=!0}};for(const n of this.interceptors)try{if(await n(a)===!1||t){t=!0;break}}catch(k){console.error("[WhiteboardAutoSaveManager] Interceptor error:",k)}if(t)return!1;this.isFlushing=!0,this.status="saving",this.notifyListeners(),le.publish({id:ce(),type:"whiteboard.autosave.saving",source:"whiteboard.autosave",payload:{lessonId:this.lessonId,pendingCount:this.pendingMap.size},timestamp:Date.now(),correlationId:this.lessonId});const u=Array.from(this.pendingMap.entries()),m=[];let r=!1;try{for(const[n,k]of u)await this.saveHandler(this.lessonId,n,k)?(m.push(n),this.pendingMap.get(n)===k&&this.pendingMap.delete(n)):r=!0;if(r)throw new Error("One or more element updates failed to save");return this.lastSavedTime=new Date,this.lastError=null,this.status=this.pendingMap.size>0?"pending":"saved",this.notifyListeners(),le.publish({id:ce(),type:"whiteboard.autosave.saved",source:"whiteboard.autosave",payload:{lessonId:this.lessonId,savedElementIds:m,lastSavedTime:this.lastSavedTime.toISOString()},timestamp:Date.now(),correlationId:this.lessonId}),!0}catch(n){return this.lastError=n,this.status="error",this.notifyListeners(),le.publish({id:ce(),type:"whiteboard.autosave.error",source:"whiteboard.autosave",payload:{lessonId:this.lessonId,error:n?.message||String(n)},timestamp:Date.now(),correlationId:this.lessonId}),!1}finally{this.isFlushing=!1,this.pendingMap.size>0&&!this.timer&&(this.timer=setTimeout(()=>{this.flush()},this.debounceDelay))}}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.pendingMap.clear(),this.status=this.lessonId?"saved":"none",this.lastError=null,this.notifyListeners()}}const L=new Dt;function Pt({lessonId:s,onSaveToServer:t,debounceDelay:a=800,onStatusChange:u}){const[m,r]=p.useState(()=>L.getStatus()),[n,k]=p.useState(()=>L.getLastSavedTime()),[f,v]=p.useState(()=>L.getPendingCount()),h=p.useRef(t);h.current=t;const b=p.useRef(u);b.current=u,p.useEffect(()=>{L.setLessonId(s),L.setDebounceDelay(a),L.setSaveHandler(async(c,y,x)=>h.current(c,y,x))},[s,a]),p.useEffect(()=>{const c=L.registerListener((y,x)=>{r(y),x?.lastSavedTime!==void 0&&k(x.lastSavedTime),x?.count!==void 0&&v(x.count),b.current?.(y,x?.lastSavedTime??null)});return()=>{c()}},[]),p.useEffect(()=>{const c=()=>{L.getPendingCount()>0&&L.flush()};return window.addEventListener("beforeunload",c),()=>{window.removeEventListener("beforeunload",c),L.flush()}},[]);const z=p.useCallback((c,y)=>{L.queueUpdate(c,y)},[]),o=p.useCallback(async()=>L.flush(),[]),N=p.useCallback(()=>{L.cancel()},[]);return{status:m,lastSavedTime:n,pendingCount:f,queueUpdate:z,flush:o,cancel:N,registry:L}}function qt(){const s=Ge(),{lang:t,session:a,onCopyCourse:u,lessons:m,selectedLesson:r,activeRole:n,setActiveRole:k,editorSaveStatus:f,setEditorSaveStatus:v,editorLastSavedTime:h,setEditorLastSavedTime:b,setTeacherTab:z,handlePaletteActivate:o,timelineSegments:N,activeSegmentId:c,setActiveSegmentId:y,draggedSegmentIdx:x,setDraggedSegmentIdx:C,saveTimeline:P,editorPanelsExpanded:Q,setEditorPanelsExpanded:O,fetchElements:g,whiteboardRef:w,elements:E,paletteEdit:q,handlePaletteConfirm:Z,setPaletteEdit:A,exportCoursePackage:G}=We(),_=Ce(i=>i.session),F=a||_,I=m.find(i=>i.id===r),U=F?.username==="admin"||F?.userId==="usr_admin"||F?.role==="administrator"||F?.subRole==="administrator",de=!I?.creator_id||I.creator_id===F?.userId||I.creator_id===F?.username,X=U||de,R=!X||n!=="teacher",[ue,J]=p.useState(!1),[ee,ae]=p.useState(!1),ne=async()=>{if(!(!r||ee)){ae(!0);try{await G(r)}finally{ae(!1)}}},[he,ie]=p.useState([]),[V,te]=p.useState(0),[W,B]=p.useState(null),M=p.useRef(null),Y=p.useRef(null);p.useEffect(()=>{W||(M.current=null,Y.current=null)},[W]),p.useEffect(()=>{if(!s)return;const i=s.getDispatcher?.();if(!i)return;const S=i.registerHandler("host:refresh",async $=>{const K=$.action.payload.target;if(K==="lessons"||K==="all")return r&&g&&await g(r),{success:!0,refreshed:["lessons"]}});return()=>{S.dispose()}},[s,r,g]);const se=async(i,S,$)=>{try{return(await fetch(`/api/lessons/${i}/whiteboard/${S}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:$})})).ok}catch(K){return console.error("[LessonEditorView] autosave element failed:",K),!1}},{queueUpdate:l,flush:d,pendingCount:j}=Pt({lessonId:r,onSaveToServer:se,debounceDelay:800,onStatusChange:(i,S)=>{i!=="pending"&&v(i),S&&b(S)}}),T=p.useCallback((i,S)=>{const $=M.current||Y.current;return $?$.type==="page"?((async()=>(await w.current?.moveElementToPage?.(S,$.pageIndex),r&&(await d(),await g(r))))(),!0):$.type==="segment"?((async()=>(await w.current?.moveElementToSegment?.(S,$.segmentId),r&&(await d(),await g(r))))(),!0):!1:!1},[w,r,d,g]);p.useEffect(()=>{if(!r)return;const i=new He;return i.broadcastChangeLesson(r),c&&i.broadcastChangeSegment(c),()=>{i.destroy()}},[r,c]);const D=i=>{if(R){alert(X?t==="zh"?"学生视角预览为只读模式。":"Student preview is read-only.":t==="zh"?"【只读模式】您无法直接修改其他教师创建的课程。请点击上方的「一键克隆为我的备课」生成您的专属教案副本。":"[Read-Only Mode] You cannot modify lessons created by other teachers. Please clone it to your own lessons.");return}o(i)};return e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 min-w-0 bg-surface rounded-2xl border border-theme overflow-hidden shadow-sm text-main transition-colors",children:[e.jsxs("div",{className:"px-4 py-2.5 border-b border-theme flex flex-wrap items-center justify-between gap-3 shrink-0 bg-surface/85 backdrop-blur-md",children:[e.jsxs("div",{className:"flex items-center gap-3 min-w-0 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx("div",{className:"w-8 h-8 rounded-xl bg-primary-theme/10 text-primary-theme border border-primary-theme/20 flex items-center justify-center shrink-0",children:e.jsx(lt,{size:16})}),e.jsxs("div",{className:"flex flex-col min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[10px] font-black uppercase tracking-wider text-primary-theme",children:t==="zh"?"教案与白板编排":"Lesson Orchestrator"}),R&&e.jsx("span",{className:"text-[9px] px-1.5 py-0.2 rounded-full font-bold bg-amber-500/15 text-amber-600 border border-amber-500/30",children:t==="zh"?"只读预览":"Read-Only Preview"})]}),e.jsx("h2",{className:"text-xs sm:text-sm font-black text-main truncate tracking-tight",children:t==="zh"?`课程编辑器: ${I?.title||"未选择课程"}`:`Lesson Editor: ${I?.title||"No Lesson Selected"}`})]})]}),r&&e.jsxs("div",{className:"hidden sm:flex items-center gap-1.5 shrink-0",children:[j>0&&f!=="saving"&&e.jsxs("button",{type:"button",onClick:()=>void d(),title:t==="zh"?"有未保存改动,点击立即写入服务器":"Pending changes, click to sync now",className:"flex items-center gap-1.5 text-xs font-bold text-amber-700 dark:text-amber-300 bg-amber-500/10 hover:bg-amber-500/20 border border-amber-500/30 px-2.5 py-1 rounded-full transition-all cursor-pointer shadow-2xs hover:scale-102",children:[e.jsx(pe,{size:11,className:"animate-spin text-amber-600"}),e.jsx("span",{children:t==="zh"?`${j} 项待写入 (点击立即保存)`:`${j} pending (sync now)`})]}),f==="saving"&&e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-bold text-amber-700 dark:text-amber-300 bg-amber-500/10 border border-amber-500/30 px-2.5 py-1 rounded-full animate-pulse shadow-2xs",children:[e.jsx(pe,{size:11,className:"animate-spin text-amber-600"}),e.jsx("span",{children:t==="zh"?"同步 SQLite...":"Saving SQLite..."})]}),f==="saved"&&j===0&&e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-bold text-emerald-700 dark:text-emerald-300 bg-emerald-500/10 border border-emerald-500/30 px-2.5 py-1 rounded-full shadow-2xs",children:[e.jsx(De,{size:11,className:"text-emerald-500"}),e.jsx("span",{children:t==="zh"?"已自动保存":"Auto-Saved"}),h&&e.jsx("span",{className:"text-[11px] font-mono opacity-70",children:h.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})})]}),f==="error"&&e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-bold text-rose-600 bg-rose-500/10 border border-rose-500/30 px-2.5 py-1 rounded-full shadow-2xs",children:[e.jsx(Ie,{size:11,className:"text-rose-600"}),e.jsx("span",{children:t==="zh"?"写入失败":"Failed to save"})]}),f==="none"&&j===0&&e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-bold text-muted bg-surface-secondary border border-theme px-2.5 py-1 rounded-full shadow-2xs",children:[e.jsx(ct,{size:11,className:"text-muted"}),e.jsx("span",{children:t==="zh"?"同步就绪":"Ready"})]}),e.jsx(H,{slot:"whiteboard.autosave.status",slotProps:{lessonId:r,status:f,pendingCount:j,lastSavedTime:h}}),e.jsx(H,{slot:"whiteboard.autosave.action",slotProps:{lessonId:r,flush:d,pendingCount:j}})]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsxs("div",{className:"bg-surface-secondary border border-theme p-1 rounded-xl flex items-center gap-1 shadow-2xs",children:[e.jsxs("button",{type:"button",onClick:()=>k("teacher"),className:`px-3 py-1 text-xs font-bold rounded-lg transition-all cursor-pointer flex items-center gap-1.5 ${n==="teacher"?"bg-surface text-primary-theme font-black shadow-xs border border-theme/60 scale-102":"text-muted hover:text-main"}`,title:t==="zh"?"在当前窗口切回教师编辑视角":"Switch back to the teacher editor view",children:[e.jsx("span",{children:"👨‍🏫"}),e.jsx("span",{children:t==="zh"?"教师视角":"Teacher"})]}),e.jsxs("button",{type:"button",onClick:()=>{const i=`${window.location.origin}${window.location.pathname}?mode=student_preview&lessonId=${encodeURIComponent(r||"")}#/student_preview`;window.open(i,"_blank")||alert(t==="zh"?"新标签页被浏览器拦截,请允许本站打开弹出窗口后重试。":"The new tab was blocked. Please allow pop-ups for this site and retry.")},className:`px-3 py-1 text-xs font-bold rounded-lg transition-all cursor-pointer flex items-center gap-1.5 ${n==="student"?"bg-primary-theme text-white font-black shadow-xs scale-102":"text-muted hover:text-main"}`,title:t==="zh"?"在新标签页中以学生身份预览本课节(不影响当前备课窗口)":"Open a student-perspective preview of this lesson in a new tab",children:[e.jsx("span",{children:"🎓"}),e.jsx("span",{children:t==="zh"?"学生视角":"Student"})]})]}),e.jsx(H,{slot:"editor.header.action",slotProps:{lessonId:r,currentLesson:I,lang:t,isReadOnly:R,activeRole:n,onSave:se}}),X&&I&&e.jsxs("button",{type:"button",onClick:()=>void ne(),disabled:ee,className:"px-3 py-1.5 bg-sky-50 hover:bg-sky-100 border border-sky-200 text-sky-700 text-xs font-bold rounded-xl transition-all cursor-pointer shadow-2xs hover:scale-102 flex items-center gap-1.5 disabled:opacity-60 disabled:cursor-wait",title:t==="zh"?"导出为课程包(教学环节 + 白板元素 + 内联附件,可拖回导入框复用)":"Export as course package (segments + whiteboard elements + embedded assets)","data-testid":"editor-export-package-btn",children:[ee?e.jsx(pe,{size:13,className:"animate-spin"}):e.jsx(dt,{size:13}),e.jsx("span",{children:t==="zh"?"导出课程包":"Export Package"})]}),e.jsx("button",{type:"button",onClick:()=>z("courses"),className:"px-3 py-1.5 bg-surface hover:bg-surface-secondary border border-theme text-muted hover:text-main text-xs font-bold rounded-xl transition-all cursor-pointer shadow-2xs hover:scale-102",children:t==="zh"?"返回课程库":"Back to Courses"})]})]}),!X&&I&&e.jsxs("div",{className:"bg-amber-500/10 border-b border-amber-500/20 px-4 py-2.5 flex items-center justify-between text-xs text-amber-800 dark:text-amber-300 backdrop-blur-xs shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ut,{size:15,className:"text-amber-500 shrink-0"}),e.jsx("span",{children:t==="zh"?`【他人课程只读模式】当前课程由教师「${I.creator_name||I.creator_id}」创建。您拥有完整查看与备课参考权限。如需编辑调整,请克隆为您的专属教案。`:`[Read-Only Mode] This lesson was created by teacher "${I.creator_name||I.creator_id}". To customize, please clone it.`})]}),u&&e.jsxs("button",{onClick:()=>u(I.id),className:"flex items-center gap-1.5 bg-amber-600 hover:bg-amber-500 text-white font-semibold px-3 py-1.5 rounded-xl shadow-xs transition-all hover:scale-102 cursor-pointer shrink-0",children:[e.jsx(ht,{size:13}),e.jsx("span",{children:t==="zh"?"一键克隆为我的备课":"Clone as My Lesson"})]})]}),e.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[e.jsx(jt,{lang:t,onActivate:D,readOnly:R,collapsed:ue,onToggleCollapse:J,pages:he,currentPage:V,onSwitchPage:i=>w.current?.switchPage?.(i),onAddPage:i=>w.current?.addPage?.(i),onDeletePage:i=>w.current?.deletePage?.(i),onRenamePage:(i,S)=>w.current?.renamePage?.(i,S),dragState:W,onHoverDropTarget:i=>{M.current=i}}),e.jsxs("div",{className:"flex-1 relative bg-surface flex flex-col min-w-0",children:[e.jsx(wt,{lang:t,segments:N,activeSegmentId:c,setActiveSegmentId:y,draggedSegmentIdx:x,setDraggedSegmentIdx:C,selectedLesson:r,saveTimeline:P,readOnly:R,editorPanelsExpanded:Q,setEditorPanelsExpanded:O,dragState:W,onHoverDropTarget:i=>{Y.current=i}}),e.jsxs("div",{className:"flex-1 relative flex flex-col min-w-0 overflow-y-auto",children:[r&&c&&Q&&N.some(i=>i.id===c)&&e.jsx(It,{lang:t,segment:N.find(i=>i.id===c),readOnly:R,onPatch:i=>P(r,N.map(S=>S.id===c?{...S,...i}:S)),onDelete:()=>{if(N.length<=1){alert("无法删除!课程必须包含至少一个环节。");return}if(window.confirm(`确定要删除环节"${N.find(i=>i.id===c)?.title}"吗?`)){const i=N.filter(S=>S.id!==c);P(r,i),y(i[0]?.id||null)}}},c),e.jsx("div",{className:"flex-1 min-h-[380px] relative flex flex-col min-w-0",children:r?e.jsxs(e.Fragment,{children:[e.jsx(Ue,{ref:w,lessonId:r,userRole:n,readOnly:R,elements:E,activeSegmentId:c,hidePageBar:!0,onPagesStateChange:({pages:i,currentPage:S})=>{ie(i),te(S)},onSegmentSync:i=>y(i),onElementDragChange:B,onElementDropCheck:T,onElementAdd:async(i,S)=>{if(!R){await d(),v("saving");try{(await fetch(`/api/lessons/${r}/whiteboard`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:i,data:S})})).ok?(v("saved"),b(new Date),g(r)):v("error")}catch{v("error")}}},onElementUpdate:(i,S)=>{R||l(i,S)},onElementDelete:async i=>{if(!R){await d(),v("saving");try{(await fetch(`/api/lessons/${r}/whiteboard/${i}`,{method:"DELETE"})).ok?(v("saved"),b(new Date),g(r)):v("error")}catch{v("error")}}},onClearBoard:async()=>{if(!R){await d(),v("saving");try{(await fetch(`/api/lessons/${r}/whiteboard`,{method:"DELETE"})).ok?(v("saved"),b(new Date),g(r)):v("error")}catch{v("error")}}},onRefresh:()=>g(r)}),q&&!R&&ve(q.type)&&e.jsx(Tt,{config:ve(q.type),lang:t,initialData:q.data,onConfirm:Z,onCancel:()=>A(null)})]}):e.jsx("div",{className:"absolute inset-0 flex items-center justify-center text-muted p-8 text-center bg-surface-secondary/50",children:e.jsxs("div",{children:[e.jsx(mt,{size:48,className:"mx-auto mb-4 opacity-30"}),e.jsx("p",{className:"font-medium text-lg text-main mb-2",children:"No active lesson selected"}),e.jsx("p",{className:"text-sm",children:"Please select a lesson from the Dashboard to orchestrate."})]})})})]})]})]})]})}export{qt as LessonEditorView};
1
+ import{j as e,r as p,R as oe}from"./vendor-react-DHoBZpn2.js";import{n as re,d as Pe,p as $e,q as Ae,v as me,w as Re,x as Le,y as _e,z as Me,B as Se,F as Fe,G as Qe,E as H,H as ye,I as Oe,J as qe,e as Ce,K as Ze,S as Be,j as le,L as ce,O as Ge,b as We,Q as He,R as ve}from"./index-XduPa2-x.js";import{L as Ue}from"./LazyWhiteboard-CsF9GB6J.js";import{P as Je,t as Ee,b9 as Ke,aU as je,ba as we,bb as Ve,aa as Ne,an as fe,x as Ye,af as be,a$ as Xe,X as Ie,a4 as ge,V as Te,k as et,bc as tt,aR as st,h as De,aZ as rt,L as at,ae as nt,D as ke,i as it,ab as ot,au as lt,c as pe,as as ct,bd as dt,T as ut,ai as ht,aQ as mt}from"./vendor-icons-DLOPlM4i.js";import{r as pt}from"./timeline-duration-BgdJCSrW.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-skggaP9D.js";function ze({config:s,lang:t,onActivate:a,disabled:u=!1,isFavorite:m=!1,onToggleFavorite:r}){const n=s.icon||Je,k=re[s.color]||re.indigo;return e.jsxs("div",{draggable:!u,onDragStart:f=>{if(u){f.preventDefault();return}const v={type:s.type,...s.defaultData},h=JSON.stringify(v);f.dataTransfer.effectAllowed="copy",f.dataTransfer.setData("application/json",h),f.dataTransfer.setData("text/plain",h)},onClick:()=>!u&&a(s.type),title:u?t==="zh"?"当前为只读模式":"Read-only mode":t==="zh"?"点击编辑并添加到画板,或拖拽到画板":"Click to edit & add, or drag onto the board","aria-disabled":u,className:`group relative bg-surface border border-theme rounded-xl p-2.5 shadow-sm transition-all duration-200 ${u?"opacity-60 cursor-not-allowed":"cursor-grab active:cursor-grabbing hover:shadow-md hover:-translate-y-0.5"} ${k.cardHoverBorder} ${k.cardHoverRing} ${k.cardHoverShadow} flex flex-col justify-between min-h-[92px]`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-1",children:[e.jsx("div",{className:`p-2 rounded-lg ${k.iconBg} ${k.iconText} transition-transform group-hover:scale-105 shrink-0`,children:e.jsx(n,{size:16})}),r&&e.jsx("button",{type:"button",onClick:f=>{f.stopPropagation(),r(s.type,f)},className:`p-1 rounded-md transition-colors ${m?"text-amber-400 opacity-100":"text-slate-300 opacity-0 group-hover:opacity-100 hover:text-amber-400 hover:bg-surface-secondary"}`,title:m?t==="zh"?"取消收藏":"Remove favorite":t==="zh"?"收藏组件":"Add favorite",children:e.jsx(Ee,{size:13,className:m?"fill-amber-400":""})})]}),e.jsxs("div",{className:"flex flex-col min-w-0 mt-1.5",children:[e.jsx("span",{className:"font-semibold text-xs text-main truncate group-hover:text-primary-theme transition-colors",children:t==="zh"?s.labelZh:s.labelEn}),e.jsx("span",{className:"text-xs text-muted leading-tight mt-0.5 truncate",children:t==="zh"?s.descriptionZh:s.descriptionEn})]}),e.jsx("div",{className:"absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none",children:e.jsx("span",{className:"text-xs font-bold text-indigo-500 bg-indigo-50 px-1 py-0.5 rounded border border-indigo-100",children:"+ Drag"})})]})}class xt{constructor(){this.items=new Map,this.providers=new Map,this.recents=[],this.favorites=new Set}registerItem(t){if(!t||!t.id)throw new Error("QuickInsertRegistry Error: QuickInsertItemDescriptor must have a valid ID.");this.items.set(t.id,t)}registerProvider(t){if(!t||!t.id)throw new Error("QuickInsertRegistry Error: QuickInsertProvider must have a valid ID.");this.providers.set(t.id,t);const a=t.getItems();for(const u of a)this.registerItem(u)}unregisterItem(t){return this.recents=this.recents.filter(a=>a!==t),this.favorites.delete(t),this.items.delete(t)}getItem(t){return this.items.get(t)}search(t="",a){const m=(t.startsWith("/")?t.slice(1):t).trim().toLowerCase(),r=Array.from(this.items.values());return Object.freeze(r.filter(n=>{if(a&&n.category!==a)return!1;if(!m)return!0;const k=n.title.toLowerCase().includes(m),f=n.description?.toLowerCase().includes(m)??!1,v=n.keywords?.some(h=>h.toLowerCase().includes(m))??!1;return k||f||v}))}async executeItem(t,a){const u=this.items.get(t);if(!u)throw new Error(`QuickInsertRegistry Error: Item '${t}' not found.`);this.recents=[t,...this.recents.filter(m=>m!==t)].slice(0,10),await u.execute(a)}getRecents(){const t=this.recents.map(a=>this.items.get(a)).filter(a=>a!==void 0);return Object.freeze(t)}getFavorites(){const t=Array.from(this.favorites).map(a=>this.items.get(a)).filter(a=>a!==void 0);return Object.freeze(t)}toggleFavorite(t){this.favorites.has(t)?this.favorites.delete(t):this.items.has(t)&&this.favorites.add(t)}listAll(){return Object.freeze(Array.from(this.items.values()))}clear(){this.items.clear(),this.providers.clear(),this.recents=[],this.favorites.clear()}}const ft=["Media","Shape","Tool","AI","Widget","Plugin"],xe=new xt,bt=({isOpen:s,onClose:t,registry:a=xe,initialQuery:u="/"})=>{const[m,r]=p.useState(u),[n,k]=p.useState("All"),[f,v]=p.useState(0),h=Pe(o=>o.extensionPoints),b=p.useMemo(()=>{const o=n==="All"?void 0:n,N=a.search(m,o),y=(h.get("quick_insert.item")??[]).map(x=>{const C=$e(x.slotProps),P=Ae(C.category,ft,"Plugin"),Q=me(C,"title"),O=me(C,"commandType"),g=Re(C.payload);return{id:x.id,title:x.label||Q||x.id,description:me(C,"description"),icon:typeof x.icon=="string"?x.icon:void 0,category:P,keywords:Me(C.keywords),execute:async w=>{if(O){const E=await Le.post("/api/plugins/execute-command",{type:O,payload:g??w});E.success||_e.getState().addToast({id:`plugin-cmd-error-${Date.now()}`,type:"error",title:"插件命令执行失败",message:E.error||`命令 ${O} 未能执行`})}}}}).filter(x=>{if(o&&x.category!==o)return!1;const P=(m.startsWith("/")?m.slice(1):m).trim().toLowerCase();if(!P)return!0;const Q=x.title.toLowerCase().includes(P),O=x.description?.toLowerCase().includes(P)??!1,g=x.keywords?.some(w=>w.toLowerCase().includes(P))??!1;return Q||O||g});return[...N,...y]},[a,m,n,h]),z=p.useCallback(o=>{if(o.key==="ArrowDown")o.preventDefault(),v(N=>N+1<b.length?N+1:0);else if(o.key==="ArrowUp")o.preventDefault(),v(N=>N-1>=0?N-1:b.length-1);else if(o.key==="Enter"){o.preventDefault();const N=b[f];N&&(a.getItem?.(N.id)?a.executeItem(N.id):N.execute(),t())}else o.key==="Escape"&&(o.preventDefault(),t())},[b,f,a,t]);return p.useEffect(()=>{v(0)},[m,n]),s?e.jsx("div",{className:"quick-insert-backdrop fixed inset-0 bg-slate-950/40 backdrop-blur-xs z-50 flex items-center justify-center",onClick:t,"data-testid":"quick-insert-backdrop",children:e.jsxs("div",{className:"quick-insert-container w-full max-w-lg bg-slate-900 border border-slate-800 rounded-xl shadow-2xl overflow-hidden flex flex-col",onClick:o=>o.stopPropagation(),"data-testid":"quick-insert-modal",children:[e.jsxs("div",{className:"flex items-center px-4 py-3 border-b border-slate-800 bg-slate-900/90",children:[e.jsx("span",{className:"text-indigo-400 font-mono font-bold text-lg mr-2",children:"/"}),e.jsx("input",{type:"text",className:"w-full bg-transparent text-slate-100 placeholder-slate-400 outline-none text-sm font-medium",placeholder:"Type a command or filter...",value:m.startsWith("/")?m.slice(1):m,onChange:o=>r("/"+o.target.value),onKeyDown:z,autoFocus:!0,"data-testid":"quick-insert-search-input"}),e.jsx("kbd",{className:"text-xs bg-slate-800 text-slate-400 px-2 py-0.5 rounded border border-slate-700 font-mono",children:"ESC"})]}),e.jsx("div",{className:"flex items-center space-x-1 px-3 py-1.5 border-b border-slate-800 bg-slate-900/50 overflow-x-auto",children:["All","Media","Shape","Tool","AI","Widget","Plugin"].map(o=>e.jsx("button",{className:`px-2 py-0.5 text-xs rounded-md transition-colors font-medium ${n===o?"bg-indigo-600 text-white":"text-slate-400 hover:bg-slate-800 hover:text-slate-200"}`,onClick:()=>k(o),children:o},o))}),e.jsx("div",{className:"max-h-80 overflow-y-auto p-2 divide-y divide-slate-800/40",children:b.length===0?e.jsx("div",{className:"py-6 text-center text-slate-500 text-sm",children:"No insertable items match slash command."}):b.map((o,N)=>e.jsxs("div",{className:`flex items-center justify-between px-3 py-2 rounded-lg cursor-pointer transition-colors ${N===f?"bg-indigo-600/20 text-white":"text-slate-300 hover:bg-slate-800/60"}`,onClick:()=>{a.getItem?.(o.id)?a.executeItem(o.id):o.execute(),t()},"data-testid":`quick-insert-item-${o.id}`,children:[e.jsxs("div",{className:"flex items-center space-x-2.5",children:[e.jsx("span",{className:"text-xs font-semibold px-2 py-0.5 rounded bg-slate-800 text-indigo-400 border border-slate-700",children:o.category}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-slate-100",children:o.title}),o.description&&e.jsx("div",{className:"text-xs text-slate-400",children:o.description})]})]}),o.shortcut&&e.jsx("kbd",{className:"text-xs font-mono text-slate-400 bg-slate-800 px-1.5 py-0.5 rounded border border-slate-700",children:o.shortcut})]},o.id))})]})}):null},gt={present:"Media",media:"Media",interact:"Tool",tool:"Tool",ai:"AI",widget:"Widget"};function yt(s){return Se.map(t=>{const a=s.lang==="zh"?t.labelZh:t.labelEn,u=s.lang==="zh"?t.descriptionZh:t.descriptionEn;return{id:`builtin.quickInsert.${t.type}`,title:a,description:u,category:gt[t.group]??"Widget",keywords:[t.type,...s.lang==="zh"?[t.labelZh]:[t.labelEn]],execute:()=>{s.readOnly||s.onActivate(t.type)}}})}function vt(s,t){for(const a of yt(t))s.registerItem(a)}function jt({lang:s,onActivate:t,readOnly:a=!1,collapsed:u,onToggleCollapse:m,pages:r,currentPage:n=0,onSwitchPage:k,onAddPage:f,onDeletePage:v,onRenamePage:h,dragState:b,onHoverDropTarget:z}){const[o,N]=p.useState(!1),c=u!==void 0?u:o,y=()=>{const l=!c;N(l),m&&m(l)},[x,C]=p.useState(""),[P,Q]=p.useState(!1),[O,g]=p.useState(""),[w,E]=p.useState(!1),[q,Z]=p.useState(null),[A,G]=p.useState(""),[_,F]=p.useState("all"),[I,U]=p.useState(()=>{try{const l=localStorage.getItem("openlearn_palette_favs");return l?JSON.parse(l):[]}catch{return[]}}),[de,X]=p.useState(()=>{try{const l=localStorage.getItem("openlearn_palette_recent");return l?JSON.parse(l):[]}catch{return[]}}),[R,ue]=p.useState({}),J=l=>{a||(X(d=>{const j=[l,...d.filter(T=>T!==l)].slice(0,6);try{localStorage.setItem("openlearn_palette_recent",JSON.stringify(j))}catch{}return j}),t(l))},ee=(l,d)=>{d.stopPropagation(),U(j=>{const D=j.includes(l)?j.filter(i=>i!==l):[...j,l];try{localStorage.setItem("openlearn_palette_favs",JSON.stringify(D))}catch{}return D})},ae=l=>{ue(d=>({...d,[l]:!d[l]}))},ne=p.useRef(J);ne.current=J,p.useEffect(()=>{vt(xe,{lang:s,onActivate:l=>ne.current(l),readOnly:a})},[s,a]);const he=Fe(),ie=[...Se,...he],V=ie.filter(l=>{if(x.trim()){const d=x.toLowerCase(),j=l.labelZh.toLowerCase().includes(d)||l.descriptionZh.toLowerCase().includes(d),T=l.labelEn.toLowerCase().includes(d)||l.descriptionEn.toLowerCase().includes(d);if(!j&&!T)return!1}return _==="favorites"?I.includes(l.type):_==="recent"?de.includes(l.type):!0}),te=oe.useRef(null),W=oe.useRef(null),B=oe.useRef(null),M=oe.useRef(null),[Y,se]=p.useState(null);return p.useEffect(()=>{if(!b){M.current&&(clearTimeout(M.current),M.current=null),B.current&&(clearTimeout(B.current),B.current=null),se(null),z?.(null);return}const{clientX:l,clientY:d}=b;if(te.current){const j=te.current.getBoundingClientRect(),T=l>=j.left&&l<=j.right&&d>=j.top&&d<=j.bottom;T&&c?B.current||(B.current=setTimeout(()=>{N(!1),m?.(!1),B.current=null},250)):!T&&B.current&&(clearTimeout(B.current),B.current=null)}if(W.current){const j=W.current.getBoundingClientRect(),T=l>=j.left&&l<=j.right&&d>=j.top&&d<=j.bottom;if(T&&w?M.current||(M.current=setTimeout(()=>{E(!1),M.current=null},250)):!T&&M.current&&(clearTimeout(M.current),M.current=null),!w&&r&&r.length>0){let D=null;W.current.querySelectorAll("[data-page-index]").forEach(S=>{const $=S.getBoundingClientRect();if(l>=$.left&&l<=$.right&&d>=$.top&&d<=$.bottom){const K=S.getAttribute("data-page-index");K!==null&&(D=parseInt(K,10))}}),D!==null&&D!==b.initialPage?(se(D),z?.({type:"page",pageIndex:D})):(se(null),z?.(null))}}},[b,c,w,r,m,z]),c?e.jsxs("div",{ref:te,className:`w-14 shrink-0 border-r border-theme bg-surface-secondary/40 backdrop-blur-md p-2 flex flex-col items-center gap-3 select-none transition-all duration-300 ${b?"ring-2 ring-primary-theme/50 bg-primary-theme/10":""}`,children:[e.jsx("button",{type:"button",onClick:y,className:"w-10 h-10 rounded-xl bg-surface hover:bg-surface-secondary border border-theme text-muted hover:text-main flex items-center justify-center transition-all cursor-pointer shadow-2xs hover:scale-105",title:s==="zh"?"展开备课组件库 (Ctrl+B)":"Expand Component Palette",children:e.jsx(Ke,{size:16})}),e.jsx("div",{className:"w-8 h-px bg-border/60 my-0.5"}),r&&r.length>0&&e.jsxs("button",{type:"button",onClick:y,className:"w-10 h-10 rounded-xl bg-surface hover:bg-primary-theme/10 border border-theme text-primary-theme flex items-center justify-center transition-all cursor-pointer shadow-2xs group relative",title:`${s==="zh"?"页面大纲":"Outline"} (P${n+1}/${r.length}) - ${s==="zh"?"点击展开":"Click to expand"}`,children:[e.jsx(je,{size:16}),e.jsx("span",{className:"absolute -top-1 -right-1 text-[9px] bg-primary-theme text-white rounded-full w-4 h-4 flex items-center justify-center font-bold",children:n+1})]}),e.jsx("div",{className:"flex flex-col gap-2 overflow-y-auto max-h-[calc(100vh-220px)] p-0.5",children:ie.slice(0,8).map(l=>{const d=l.icon||we;return e.jsx("button",{type:"button",onClick:()=>J(l.type),disabled:a,"aria-disabled":a,className:`w-10 h-10 rounded-xl bg-surface border border-theme text-main flex items-center justify-center transition-all shadow-2xs group relative ${a?"opacity-50 cursor-not-allowed":"hover:bg-primary-theme/10 hover:border-primary-theme cursor-pointer"}`,title:`${s==="zh"?l.labelZh:l.labelEn} - ${s==="zh"?"点击配置":"Configure"}`,children:e.jsx(d,{size:16,className:"text-primary-theme transition-transform group-hover:scale-110"})},l.type)})})]}):e.jsxs("div",{ref:te,className:`w-[260px] shrink-0 border-r border-theme bg-surface-secondary/40 backdrop-blur-md p-3.5 overflow-y-auto flex flex-col gap-3.5 font-sans select-none text-main transition-all duration-300 ${b&&Y!==null?"ring-1 ring-primary-theme/30":""}`,children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-theme/60 pb-2.5",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-7 h-7 rounded-lg bg-primary-theme/10 text-primary-theme flex items-center justify-center",children:e.jsx(we,{size:15})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xs font-black text-main uppercase tracking-wider",children:s==="zh"?"备课组件画板":"Palette"}),e.jsxs("span",{className:"text-[10px] text-muted",children:[V.length," ",s==="zh"?"个可用组件":"components"]})]})]}),e.jsx("button",{type:"button",onClick:y,className:"p-1.5 rounded-lg text-muted hover:text-main hover:bg-surface border border-theme/50 transition-colors cursor-pointer",title:s==="zh"?"收起组件面板以扩大画布":"Collapse Palette",children:e.jsx(Ve,{size:14})})]}),r&&r.length>0&&e.jsxs("div",{ref:W,className:`bg-surface rounded-xl border border-theme p-2.5 flex flex-col gap-2 shadow-2xs transition-all duration-200 ${Y!==null?"border-primary-theme shadow-md ring-1 ring-primary-theme/30":""}`,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("button",{type:"button",onClick:()=>E(l=>!l),className:"flex items-center gap-1.5 text-xs font-bold text-main hover:text-primary-theme transition-colors cursor-pointer",children:[e.jsx(je,{size:14,className:"text-primary-theme"}),e.jsxs("span",{children:[s==="zh"?"页面大纲":"Outline"," (",r.length,")"]}),e.jsx(Ne,{size:13,className:`text-muted transition-transform duration-200 ${w?"-rotate-90":""}`})]}),!a&&f&&e.jsx("button",{type:"button",onClick:()=>f(),className:"p-1 rounded-md text-muted hover:text-primary-theme hover:bg-primary-theme/10 transition-colors cursor-pointer",title:s==="zh"?"新建白板页面":"Add page",children:e.jsx(fe,{size:13})})]}),w?e.jsxs("div",{onClick:()=>E(!1),className:`flex items-center justify-between text-2xs px-2 py-1 bg-surface-secondary/70 rounded-lg text-muted hover:text-main cursor-pointer transition-colors ${b?"border border-dashed border-primary-theme/60 bg-primary-theme/10 text-primary-theme font-medium animate-pulse":""}`,children:[e.jsx("span",{className:"truncate max-w-[170px]",children:b?s==="zh"?"🎯 悬停自动展开页面大纲":"🎯 Hover to expand outline":`${s==="zh"?"当前":"Current"}: ${r[n]?.title||`P${n+1}`}`}),e.jsx("span",{className:"text-[10px] text-primary-theme font-medium",children:s==="zh"?"展开":"Expand"})]}):e.jsx("div",{className:"flex flex-col gap-1 max-h-48 overflow-y-auto pr-0.5 no-scrollbar",children:r.map((l,d)=>{const j=d===n,T=q===d,D=Y===d;return e.jsxs("div",{"data-page-index":d,onClick:()=>{T||k?.(d)},className:`group flex items-center justify-between px-2.5 py-1.5 rounded-lg text-xs transition-all cursor-pointer ${D?"ring-2 ring-primary-theme ring-offset-1 border-dashed border-2 border-primary-theme bg-primary-theme/15 animate-pulse":j?"bg-primary-theme text-white font-semibold shadow-xs":"bg-surface hover:bg-surface-secondary text-main border border-theme/40"}`,children:[e.jsxs("div",{className:"flex items-center gap-1.5 truncate min-w-0 flex-1",children:[e.jsxs("span",{className:`text-[10px] px-1 py-0.2 rounded font-mono shrink-0 ${D?"bg-primary-theme text-white font-bold":j?"bg-white/20 text-white":"bg-surface-secondary text-muted"}`,children:["P",d+1]}),T?e.jsx("input",{type:"text",autoFocus:!0,value:A,onChange:i=>G(i.target.value),onKeyDown:i=>{i.key==="Enter"&&(A.trim()&&h?.(d,A.trim()),Z(null)),i.key==="Escape"&&Z(null)},onBlur:()=>{A.trim()&&h?.(d,A.trim()),Z(null)},className:"px-1.5 py-0.5 text-xs bg-surface border border-primary-theme rounded text-main outline-none w-full",onClick:i=>i.stopPropagation()}):e.jsx("span",{className:"truncate",children:l.title})]}),D&&e.jsxs("span",{className:"text-[10px] font-bold text-primary-theme animate-bounce shrink-0 flex items-center gap-1 pl-1",children:[e.jsx("span",{children:"📥"}),e.jsx("span",{children:s==="zh"?"松开移入":"Drop"})]}),!a&&!T&&e.jsxs("div",{className:"flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity ml-1 shrink-0",onClick:i=>i.stopPropagation(),children:[h&&e.jsx("button",{type:"button",onClick:()=>{Z(d),G(l.title)},className:`p-0.5 rounded hover:bg-black/10 cursor-pointer ${j?"text-white":"text-muted hover:text-main"}`,title:"重命名",children:e.jsx(Ye,{size:11})}),r.length>1&&v&&e.jsx("button",{type:"button",onClick:()=>{window.confirm(`确定删除页面"${l.title}"吗?页面内的组件也将被清理。`)&&v(d)},className:`p-0.5 rounded hover:bg-rose-500/20 text-rose-500 cursor-pointer ${j?"text-white hover:bg-white/20":""}`,title:"删除此页",children:e.jsx(be,{size:11})})]})]},l.id||d)})})]}),e.jsxs("div",{className:"relative",children:[e.jsx(Xe,{size:13,className:"absolute left-2.5 top-1/2 -translate-y-1/2 text-muted"}),e.jsx("input",{type:"text",value:x,onChange:l=>{const d=l.target.value;if(d.startsWith("/")){g(d),Q(!0),C("");return}C(d)},placeholder:s==="zh"?"搜索画板组件...(输入 / 快速插入)":"Search components... (type / to quick insert)",className:"w-full pl-8 pr-7 py-1.5 bg-surface border border-theme rounded-xl text-xs text-main placeholder-muted outline-none focus:border-primary-theme focus:ring-1 focus:ring-primary-theme transition-all shadow-2xs"}),x&&e.jsx("button",{onClick:()=>C(""),className:"absolute right-2.5 top-1/2 -translate-y-1/2 text-muted hover:text-main cursor-pointer",children:e.jsx(Ie,{size:12})})]}),e.jsxs("div",{className:"flex items-center gap-1 bg-surface border border-theme p-1 rounded-xl shadow-2xs",children:[e.jsx("button",{type:"button",onClick:()=>F("all"),className:`flex-1 py-1 text-xs rounded-lg transition-all cursor-pointer ${_==="all"?"bg-surface-secondary text-main font-bold shadow-2xs":"text-muted hover:text-main font-medium"}`,children:s==="zh"?"全部":"All"}),e.jsxs("button",{type:"button",onClick:()=>F("favorites"),className:`flex-1 py-1 text-xs rounded-lg transition-all flex items-center justify-center gap-1 cursor-pointer ${_==="favorites"?"bg-amber-500/10 text-amber-600 font-bold border border-amber-500/20 shadow-2xs":"text-muted hover:text-amber-500 font-medium"}`,children:[e.jsx(Ee,{size:11,className:_==="favorites"?"fill-amber-500":""}),e.jsx("span",{children:s==="zh"?"常用":"Favs"})]}),e.jsxs("button",{type:"button",onClick:()=>F("recent"),className:`flex-1 py-1 text-xs rounded-lg transition-all flex items-center justify-center gap-1 cursor-pointer ${_==="recent"?"bg-primary-theme/10 text-primary-theme font-bold border border-primary-theme/20 shadow-2xs":"text-muted hover:text-primary-theme font-medium"}`,children:[e.jsx(ge,{size:11}),e.jsx("span",{children:s==="zh"?"最近":"Recent"})]})]}),e.jsxs("div",{className:"flex-1 flex flex-col gap-3 overflow-y-auto pr-0.5",children:[V.length===0?e.jsxs("div",{className:"text-center py-8 text-muted text-xs",children:[e.jsx(Te,{size:24,className:"mx-auto mb-2 opacity-30 text-primary-theme"}),e.jsx("p",{className:"font-bold text-main",children:s==="zh"?"未找到相关组件":"No components found"}),e.jsx("p",{className:"text-[11px] mt-1 text-muted",children:_!=="all"?s==="zh"?"尝试切换回「全部」标签":"Try switching to All tab":s==="zh"?"请更换关键词重新搜索":"Try a different keyword"})]}):_!=="all"||x.trim()?e.jsx("div",{className:"grid grid-cols-2 gap-2",children:V.map(l=>e.jsx(ze,{config:l,lang:s,onActivate:J,disabled:a,isFavorite:I.includes(l.type),onToggleFavorite:ee},l.type))}):(()=>{const l=[...Qe];return V.forEach(d=>{l.some(j=>j.id===d.group)||l.push({id:d.group,labelZh:d.group,labelEn:d.group})}),l.map(d=>{const j=V.filter(i=>i.group===d.id);if(j.length===0)return null;const T=re[j[0].color]||re.indigo,D=R[d.id];return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs("button",{type:"button",onClick:()=>ae(d.id),className:"flex items-center justify-between px-1.5 py-1 text-left rounded-lg transition-colors cursor-pointer hover:bg-surface-secondary/60",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full ${T.groupAccent}`}),e.jsx("span",{className:`text-[11px] font-black uppercase tracking-wider ${T.groupText}`,children:s==="zh"?d.labelZh:d.labelEn})]}),e.jsxs("div",{className:"flex items-center gap-1 text-muted",children:[e.jsxs("span",{className:"text-[10px] font-mono opacity-80",children:["(",j.length,")"]}),D?e.jsx(et,{size:12}):e.jsx(Ne,{size:12})]})]}),!D&&e.jsx("div",{className:"grid grid-cols-2 gap-2",children:j.map(i=>e.jsx(ze,{config:i,lang:s,onActivate:J,disabled:a,isFavorite:I.includes(i.type),onToggleFavorite:ee},i.type))})]},d.id)})})(),e.jsx(H,{slot:"editor.palette_item",slotProps:{lang:s,onActivate:J,readOnly:a}})]}),e.jsx(bt,{isOpen:P,onClose:()=>{Q(!1),g("")},registry:xe,initialQuery:O})]})}function wt({lang:s,segments:t,activeSegmentId:a,setActiveSegmentId:u,draggedSegmentIdx:m,setDraggedSegmentIdx:r,selectedLesson:n,saveTimeline:k,readOnly:f=!1,editorPanelsExpanded:v,setEditorPanelsExpanded:h,dragState:b,onHoverDropTarget:z}){const o=t.findIndex(g=>g.id===a),N=t.length>1&&o>=0?o/(t.length-1):0,c=o>=0?ye(t[o].color):null,y=p.useRef(null),[x,C]=p.useState(null);p.useEffect(()=>{if(!b){C(null),z?.(null);return}const{clientX:g,clientY:w}=b;if(y.current&&t&&t.length>0){let E=null;y.current.querySelectorAll("[data-segment-id]").forEach(Z=>{const A=Z.getBoundingClientRect();if(g>=A.left&&g<=A.right&&w>=A.top&&w<=A.bottom){const G=Z.getAttribute("data-segment-id");G&&(E=G)}}),E!==null&&E!==b.initialSegmentId?(C(E),z?.({type:"segment",segmentId:E})):(C(null),z?.(null))}},[b,t,z]);const P=t.reduce((g,w)=>{const{seconds:E}=pt(w,{fallbackSeconds:600});return E==null||!Number.isFinite(E)?g:g+Math.round(E/60)},0),Q=g=>{if(f)return;if(m===null||m===g){r(null);return}const w=[...t],[E]=w.splice(m,1);w.splice(g,0,E),r(null),n&&k(n,w)},O=()=>{if(f||!n)return;const g="seg-"+Math.random().toString(36).slice(2,9),w={id:g,title:s==="zh"?`新环节 ${t.length+1}`:`Segment ${t.length+1}`,notes:"",type:"lecture",duration:"10m",color:qe};k(n,[...t,w]),u(g),h(!0)};return e.jsxs("div",{ref:y,className:`sticky top-0 z-30 flex items-center justify-between gap-3 px-3.5 py-2 border-b border-theme bg-surface/95 backdrop-blur-md shrink-0 select-none overflow-x-auto text-main shadow-2xs transition-all ${b?"ring-1 ring-primary-theme/30":""}`,children:[e.jsxs("div",{className:"flex items-center gap-2 shrink-0 border-r border-theme pr-3",children:[e.jsx("div",{className:"w-6 h-6 rounded-lg bg-primary-theme/10 text-primary-theme flex items-center justify-center",children:e.jsx(tt,{size:14})}),e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{className:"text-xs font-black uppercase tracking-wider text-main whitespace-nowrap",children:s==="zh"?"教学流程":"Lesson Flow"}),e.jsxs("span",{className:"text-[10px] font-mono text-muted flex items-center gap-0.5",children:[e.jsx(ge,{size:9}),e.jsxs("span",{children:[P," min"]})]})]})]}),e.jsxs("div",{className:"relative flex items-center gap-2 py-0.5 min-w-0 flex-1",children:[e.jsx("div",{className:"absolute left-3 right-3 top-1/2 h-0.5 -translate-y-1/2 bg-border/80 rounded-full"}),o>=0&&e.jsx("div",{className:`absolute left-3 top-1/2 h-0.5 -translate-y-1/2 rounded-full transition-all duration-300 ${c?.rail||"bg-primary-theme"}`,style:{width:`calc(${N*100}% - 0.5rem)`}}),t.map((g,w)=>{const E=g.id===a,q=o>=0&&w<o,Z=m===w,A=x===g.id,G=Oe(g.type),_=ye(g.color),F=G.icon,I=A?"ring-2 ring-primary-theme ring-offset-2 border-dashed border-2 border-primary-theme bg-primary-theme/20 shadow-md scale-108 animate-pulse text-primary-theme font-bold":E?_.solid+" shadow-md ring-2 ring-primary-theme/30 scale-105":q?"bg-surface-secondary/90 text-main/80 border-primary-theme/30":_.color;return e.jsxs("div",{"data-segment-id":g.id,draggable:!f,onDragStart:U=>{if(f){U.preventDefault();return}r(w),U.dataTransfer.effectAllowed="move"},onDragOver:U=>!f&&U.preventDefault(),onDrop:()=>Q(w),onClick:()=>u(g.id),"aria-disabled":f,className:`relative z-10 flex items-center gap-1.5 px-2.5 py-1 rounded-xl text-xs font-semibold ${f?"cursor-pointer":"cursor-grab"} transition-all duration-200 border border-theme/60 shadow-2xs group ${I} ${Z?"opacity-40 scale-95":"hover:scale-102"}`,children:[e.jsx(st,{size:11,className:"opacity-0 group-hover:opacity-60 -ml-0.5 text-muted cursor-grab"}),e.jsx("span",{className:"text-[10px] font-mono font-bold opacity-75",children:w+1}),e.jsx(F,{size:12,className:"shrink-0"}),e.jsx("span",{className:"truncate max-w-[90px]",children:g.title}),e.jsxs("span",{className:"text-[10px] font-mono opacity-60",children:["(",g.duration||"10m",")"]}),q&&e.jsx(De,{size:11,className:"text-emerald-500 shrink-0 ml-0.5"}),e.jsx(H,{slot:"editor.timeline.node_badge",slotProps:{segment:g,idx:w,isActive:E,isCompleted:q,lang:s}}),A&&e.jsxs("span",{className:"text-[10px] font-bold text-primary-theme animate-bounce flex items-center gap-0.5 ml-1",children:[e.jsx("span",{children:"📥"}),e.jsx("span",{children:s==="zh"?"移入此环节":"Move here"})]})]},g.id)}),n&&!f&&e.jsxs("button",{type:"button",onClick:O,className:"relative z-10 flex items-center gap-1 px-2 py-1 rounded-xl text-xs font-medium text-muted hover:text-primary-theme bg-surface hover:bg-surface-secondary border border-dashed border-theme hover:border-primary-theme transition-all cursor-pointer shadow-2xs",title:s==="zh"?"追加新环节":"Add new segment",children:[e.jsx(fe,{size:12}),e.jsx("span",{className:"hidden sm:inline",children:s==="zh"?"加环节":"Add"})]})]}),e.jsxs("button",{type:"button",onClick:()=>h(g=>!g),"aria-expanded":v,className:`px-3 py-1 text-xs font-bold rounded-xl border transition-all flex items-center gap-1.5 cursor-pointer shrink-0 ${v?"bg-primary-theme text-white border-primary-theme shadow-md shadow-primary-theme/30 ring-2 ring-primary-theme/30 scale-102":"bg-surface hover:bg-surface-secondary text-muted hover:text-main border-theme shadow-2xs"}`,title:s==="zh"?"展开/收起环节设置面板":"Toggle Segment Settings",children:[e.jsx(rt,{size:13,className:v?"rotate-90 transition-transform text-white":""}),e.jsx("span",{children:s==="zh"?"环节参数":"Settings"}),v&&e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-white animate-ping ml-0.5"})]})]})}const Nt=[{type:"quiz_completed",labelZh:"完成练习",labelEn:"Quiz completed"},{type:"quiz_accuracy",labelZh:"练习正确率",labelEn:"Quiz accuracy"},{type:"assignment_submitted",labelZh:"已提交作业",labelEn:"Assignment submitted"},{type:"dwell_seconds",labelZh:"停留时长",labelEn:"Dwell time"},{type:"checked_in",labelZh:"已签到",labelEn:"Checked in"}];function kt(s){const t=[];for(const a of s){if(a.status!=="active")continue;let u={};try{u=JSON.parse(a.manifest)}catch{continue}const m=u.contributes?.["segment.gate_type"];if(Array.isArray(m))for(const r of m){if(!r||typeof r!="object")continue;const n=r.id,k=r.commandType;typeof n!="string"||typeof k!="string"||t.push(r)}}return t}function zt(s){return Array.isArray(s)?s.filter(t=>t&&typeof t=="object"&&typeof t.type=="string"):[]}function St({lang:s,segment:t,readOnly:a=!1,onPatch:u}){const m=Ce(h=>h.plugins),r=kt(m),n=zt(t.gates),k=[...Nt.map(h=>({type:h.type,label:s==="zh"?h.labelZh:h.labelEn})),...r.map(h=>({type:h.id,label:(s==="zh"?h.labelZh:h.labelEn)||h.id}))],f=h=>u({gates:h}),v=(h,b)=>{const z=n.map((o,N)=>N===h?{...o,...b,params:{...o.params||{},...b.params||{}}}:o);f(z)};return e.jsxs("div",{className:"flex flex-col gap-2 rounded-xl p-2.5 bg-indigo-500/5 border border-indigo-500/20",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("span",{className:"text-[11px] font-bold text-indigo-700 dark:text-indigo-300 flex items-center gap-1.5",children:[e.jsx(at,{size:12}),e.jsx("span",{children:s==="zh"?"进入条件":"Entry conditions"})]}),!a&&e.jsxs("button",{type:"button",onClick:()=>f([...n,{type:"quiz_completed",params:{}}]),className:"text-[11px] font-bold text-indigo-700 flex items-center gap-1 cursor-pointer",children:[e.jsx(fe,{size:12}),s==="zh"?"添加条件":"Add condition"]})]}),e.jsx("p",{className:"text-[10px] text-muted leading-snug",children:s==="zh"?"课级 progress_mode 已废弃。条件写在本环节上,全部满足后学生才能看到这一环节。全班仍跟随教师的当前环节。":"Lesson-level progress_mode is deprecated. Students see this segment only after every condition below is met. The class still shares one current segment."}),n.length===0&&e.jsx("p",{className:"text-[11px] text-muted",children:s==="zh"?"未设置条件,跟随课堂即可进入。":"No conditions. Following the class is enough."}),n.map((h,b)=>e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-4 gap-2 items-end",children:[e.jsxs("label",{className:"flex flex-col gap-1 sm:col-span-2",children:[e.jsx("span",{className:"text-[10px] font-bold text-muted",children:s==="zh"?"条件类型":"Type"}),e.jsxs("select",{"aria-label":s==="zh"?"条件类型":"Condition type",value:h.type,disabled:a,onChange:z=>{const o=n.map((N,c)=>c===b?{type:z.target.value,params:{}}:N);f(o)},className:"border border-theme/80 px-2 py-1.5 rounded-xl bg-surface text-xs",children:[k.map(z=>e.jsx("option",{value:z.type,children:z.label},z.type)),!k.some(z=>z.type===h.type)&&e.jsx("option",{value:h.type,children:h.type})]})]}),e.jsx(Et,{lang:s,gate:h,readOnly:a,onChange:z=>v(b,{params:z})}),!a&&e.jsxs("button",{type:"button",onClick:()=>f(n.filter((z,o)=>o!==b)),className:"px-2 py-1.5 text-xs text-rose-600 border border-rose-200 rounded-xl cursor-pointer flex items-center justify-center gap-1",children:[e.jsx(be,{size:12}),s==="zh"?"移除":"Remove"]})]},`${h.type}-${b}`))]})}function Ct(s,t){const a=s?.[t];return typeof a=="string"||typeof a=="number"?String(a):""}function Et({lang:s,gate:t,readOnly:a,onChange:u}){const m=t.params||{},r=(n,k,f,v=!1)=>e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-[10px] font-bold text-muted",children:k}),e.jsx("input",{value:Ct(m,n),disabled:a,placeholder:f,onChange:h=>{if(!v){u({[n]:h.target.value});return}const b=Number(h.target.value);u({[n]:h.target.value.trim()===""||!Number.isFinite(b)?h.target.value:b})},className:"border border-theme/80 px-2 py-1.5 rounded-xl bg-surface text-xs"})]});return t.type==="checked_in"?e.jsx("div",{}):t.type==="quiz_accuracy"?e.jsxs(e.Fragment,{children:[r("minScore",s==="zh"?"最低分":"Min score","60",!0),r("elementId",s==="zh"?"题目 ID":"Element ID","")]}):t.type==="dwell_seconds"?r("seconds",s==="zh"?"秒":"Seconds","60",!0):t.type==="assignment_submitted"?r("assignmentId",s==="zh"?"作业 ID":"Assignment ID",""):t.type==="quiz_completed"?r("elementId",s==="zh"?"题目 ID":"Element ID",""):r("segmentId",s==="zh"?"环节 ID":"Segment ID","")}function It({lang:s,segment:t,readOnly:a=!1,onPatch:u,onDelete:m}){const r=Ze();return e.jsxs("div",{className:"relative mx-3 sm:mx-4 my-3 rounded-2xl bg-surface/98 backdrop-blur-xl border-2 border-primary-theme/50 dark:border-primary-theme/60 shadow-2xl shadow-primary-theme/20 ring-4 ring-primary-theme/15 overflow-hidden shrink-0 text-main animate-in fade-in-0 zoom-in-[0.98] slide-in-from-top-3 duration-300 ease-out transition-all",children:[e.jsx("div",{className:"pointer-events-none absolute -top-12 -left-12 w-64 h-32 bg-primary-theme/15 rounded-full blur-2xl opacity-60"}),e.jsx("div",{className:"pointer-events-none absolute -bottom-12 -right-12 w-64 h-32 bg-indigo-500/10 rounded-full blur-2xl opacity-60"}),e.jsx("div",{className:"relative h-1.5 w-full bg-gradient-to-r from-primary-theme via-indigo-500 to-sky-400 shadow-sm shadow-primary-theme/30",children:e.jsx("div",{className:"absolute inset-0 bg-gradient-to-r from-transparent via-white/40 to-transparent animate-pulse"})}),e.jsxs("div",{className:"p-3.5 sm:p-4 flex flex-col gap-3.5 relative z-1",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 pb-2.5 border-b border-primary-theme/15",children:[e.jsxs("div",{className:"flex items-center gap-2.5 min-w-0",children:[e.jsxs("div",{className:"relative w-8 h-8 rounded-xl bg-gradient-to-br from-primary-theme/25 to-primary-theme/10 text-primary-theme flex items-center justify-center shrink-0 border border-primary-theme/40 shadow-xs",children:[e.jsx(nt,{size:15}),e.jsxs("span",{className:"absolute -top-1 -right-1 flex h-3 w-3",children:[e.jsx("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-primary-theme opacity-80"}),e.jsx("span",{className:"relative inline-flex rounded-full h-3 w-3 bg-primary-theme ring-2 ring-surface shadow-xs"})]})]}),e.jsxs("div",{className:"flex items-center gap-2 truncate",children:[e.jsxs("span",{className:"text-xs sm:text-sm font-black text-main tracking-tight truncate flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-2 h-2 rounded-full bg-primary-theme animate-pulse"}),s==="zh"?`环节参数配置:${t.title}`:`Segment Config: ${t.title}`]}),e.jsxs("span",{className:"hidden sm:inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-[10px] font-black uppercase tracking-wider bg-primary-theme text-white shadow-xs shadow-primary-theme/30 animate-pulse",children:[e.jsx(Te,{size:10}),s==="zh"?"正在聚焦编辑":"Active Editing"]}),e.jsxs("span",{className:"text-[10px] text-muted font-mono opacity-80 bg-surface-secondary/80 px-1.5 py-0.5 rounded-md border border-theme/50",children:["ID: ",t.id]})]})]}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx(H,{slot:"editor.timeline.node_badge",slotProps:{segment:t,lang:s,isActive:!0,isCompleted:!1}}),e.jsx(H,{slot:"editor.segment.action",slotProps:{segmentId:t.id,segment:t,lang:s,readOnly:a,onPatch:u}}),a?e.jsx("span",{className:"text-2xs font-semibold text-muted px-2 py-1 rounded-lg border border-theme",children:s==="zh"?"只读":"Read-only"}):e.jsxs("button",{type:"button",onClick:m,className:"px-2.5 py-1 text-xs text-rose-600 hover:text-white bg-rose-500/10 hover:bg-rose-600 border border-rose-500/25 rounded-xl flex items-center gap-1.5 transition-all hover:scale-102 cursor-pointer shadow-2xs shrink-0",title:s==="zh"?"删除当前环节":"Delete Segment",children:[e.jsx(be,{size:12}),e.jsx("span",{children:s==="zh"?"删除环节":"Delete"})]})]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-4 gap-2.5",children:[e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsxs("span",{className:"text-[11px] font-bold text-muted flex items-center gap-1",children:[e.jsx(ke,{size:11,className:"text-primary-theme"}),e.jsx("span",{children:s==="zh"?"环节名称":"Title"})]}),e.jsx("input",{type:"text",value:t.title||"",onChange:n=>u({title:n.target.value}),disabled:a,className:"border border-theme/80 px-2.5 py-1.5 rounded-xl bg-surface-secondary/80 focus:bg-surface text-xs text-main font-medium outline-none focus:border-primary-theme focus:ring-2 focus:ring-primary-theme/25 transition-all shadow-2xs"})]}),e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsxs("span",{className:"text-[11px] font-bold text-muted flex items-center gap-1",children:[e.jsx(ge,{size:11,className:"text-primary-theme"}),e.jsx("span",{children:s==="zh"?"预计用时":"Duration"})]}),e.jsx("input",{type:"text",value:t.duration||"10m",onChange:n=>u({duration:n.target.value}),disabled:a,placeholder:"例如: 10m",className:"border border-theme/80 px-2.5 py-1.5 rounded-xl bg-surface-secondary/80 focus:bg-surface text-xs text-main font-mono outline-none focus:border-primary-theme focus:ring-2 focus:ring-primary-theme/25 transition-all shadow-2xs"})]}),e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsxs("span",{className:"text-[11px] font-bold text-muted flex items-center gap-1",children:[e.jsx(it,{size:11,className:"text-primary-theme"}),e.jsx("span",{children:s==="zh"?"教学形态":"Instructional Type"})]}),e.jsx("select",{value:t.type||"lecture",onChange:n=>u({type:n.target.value}),disabled:a,className:"border border-theme/80 px-2.5 py-1.5 rounded-xl bg-surface-secondary/80 focus:bg-surface text-xs text-main font-medium outline-none focus:border-primary-theme focus:ring-2 focus:ring-primary-theme/25 transition-all shadow-2xs cursor-pointer",children:r.map(n=>e.jsx("option",{value:n.id,className:"bg-surface text-main",children:s==="zh"?n.labelZh:n.labelEn},n.id))})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("span",{className:"text-[11px] font-bold text-muted flex items-center gap-1",children:[e.jsx(ot,{size:11,className:"text-primary-theme"}),e.jsx("span",{children:s==="zh"?"环节标识色":"Accent Color"})]}),e.jsx("div",{className:"flex items-center gap-1.5 pt-1",children:Be.map(n=>e.jsx("button",{type:"button",onClick:()=>u({color:n.color}),disabled:a,"aria-label":s==="zh"?`选择颜色 ${n.name}`:`Choose color ${n.name}`,className:`w-5 h-5 rounded-full border border-theme/60 transition-all hover:scale-115 cursor-pointer ${n.color.split(" ")[0]} ${t.color===n.color?"ring-2 ring-primary-theme ring-offset-2 scale-110 shadow-xs":""}`,title:n.name},n.name))})]})]}),e.jsxs("div",{className:"flex flex-col gap-1 rounded-xl p-2.5 bg-amber-500/5 dark:bg-amber-500/10 border border-amber-500/20",children:[e.jsxs("span",{className:"text-[11px] font-bold text-amber-700 dark:text-amber-400 flex items-center gap-1.5",children:[e.jsx(ke,{size:12,className:"text-amber-500"}),e.jsx("span",{children:s==="zh"?"教师备课备忘 & 教学设计要点":"Instructional Notes"})]}),e.jsx("textarea",{rows:2,value:t.notes||"",onChange:n=>u({notes:n.target.value}),disabled:a,placeholder:s==="zh"?"写给自己的教学小抄:本环节核心提问、白板板书重点、容易卡壳的步骤…":"Teaching points, blackboard highlights, key student friction points…",className:"w-full border border-theme/70 px-3 py-1.5 rounded-xl bg-surface/90 focus:bg-surface text-xs text-main placeholder-muted outline-none focus:border-primary-theme focus:ring-2 focus:ring-primary-theme/20 transition-all resize-y shadow-2xs leading-relaxed"})]}),e.jsx(St,{lang:s,segment:t,readOnly:a,onPatch:u}),e.jsx(H,{slot:"editor.segment.type_config",slotProps:{segmentType:t.type||"lecture",segment:t,lang:s,readOnly:a,onPatch:u}}),e.jsx(H,{slot:"editor.timeline_segment",slotProps:{segment:t,lang:s,readOnly:a,onPatch:u}})]})]})}function Tt({config:s,lang:t,initialData:a,onConfirm:u,onCancel:m}){const[r,n]=p.useState(()=>({...a})),[k,f]=p.useState({}),v=s.icon,h=re[s.color]||re.indigo,b=Array.isArray(s.editFields)?s.editFields:[];p.useEffect(()=>{let c=!1;const y=b.filter(x=>x.kind==="select"&&x.loadOptions);if(y.length!==0)return Promise.all(y.map(async x=>{try{const C=await x.loadOptions();return[x.key,C]}catch{return[x.key,[]]}})).then(x=>{c||f(Object.fromEntries(x))}),()=>{c=!0}},[s]);const z=(c,y)=>{n(x=>({...x,[c]:y}))},o=Array.isArray(r.options)?r.options:[],N=(c,y)=>{n(x=>({...x,options:o.map((C,P)=>P===c?y:C)}))};return e.jsx("div",{className:"fixed inset-0 bg-gray-900/40 backdrop-blur-sm flex items-center justify-center p-6 z-50",children:e.jsxs("div",{className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-md flex flex-col overflow-hidden",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 flex items-center justify-between bg-gray-50/80",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-xl ${h.iconBg} ${h.iconText}`,children:v?e.jsx(v,{size:18}):null}),e.jsx("h2",{className:"font-bold text-gray-800 text-base",children:t==="zh"?`编辑:${s.labelZh}`:`Edit: ${s.labelEn}`})]}),e.jsx("button",{onClick:m,className:"text-gray-400 hover:text-gray-600 font-bold p-1 hover:bg-gray-200 rounded transition-colors text-lg",children:"×"})]}),e.jsx("div",{className:"p-5 space-y-4",children:b.length===0?e.jsx("p",{className:"text-sm text-gray-500 leading-relaxed",children:t==="zh"?"该组件无需预编辑内容,确认后即可添加到画板。":"No content to edit for this component. Confirm to add it to the board."}):b.map(c=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-600",children:t==="zh"?c.labelZh:c.labelEn}),c.kind==="options"?e.jsx("div",{className:"grid grid-cols-2 gap-2",children:o.map((y,x)=>e.jsx("input",{value:y,onChange:C=>N(x,C.target.value),placeholder:`${String.fromCharCode(65+x)}`,className:"border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"},x))}):c.kind==="textarea"?e.jsx("textarea",{value:r[c.key]??"",onChange:y=>z(c.key,y.target.value),placeholder:t==="zh"?c.placeholderZh:c.placeholderEn,rows:5,className:`w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 resize-y ${c.key==="code"||c.key==="markdown"?"font-mono text-[12px]":""}`}):c.kind==="select"?e.jsxs("select",{value:r[c.key]??"",onChange:y=>z(c.key,y.target.value),className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 bg-white",children:[e.jsx("option",{value:"",children:t==="zh"?"— 不选择 —":"— None —"}),(k[c.key]??c.options??[]).map(y=>e.jsx("option",{value:y.value,children:y.label},y.value))]}):e.jsx("input",{type:"text",value:r[c.key]??"",onChange:y=>z(c.key,y.target.value),placeholder:t==="zh"?c.placeholderZh:c.placeholderEn,className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"})]},c.key))}),e.jsxs("div",{className:"p-4 border-t border-gray-100 flex justify-end gap-2",children:[e.jsx("button",{onClick:m,className:"px-4 py-2 text-sm rounded-lg border border-gray-200 text-gray-600 hover:bg-gray-100 cursor-pointer",children:t==="zh"?"取消":"Cancel"}),e.jsx("button",{onClick:()=>u(r),className:"px-4 py-2 text-sm rounded-lg bg-indigo-600 text-white hover:bg-indigo-700 cursor-pointer",children:t==="zh"?"添加到画板":"Add to Board"})]})]})})}class Dt{constructor(t){this.lessonId=null,this.debounceDelay=800,this.status="none",this.lastSavedTime=null,this.pendingMap=new Map,this.timer=null,this.isFlushing=!1,this.lastError=null,this.saveHandler=null,this.interceptors=new Set,this.listeners=new Set,t?.debounceDelay!==void 0&&(this.debounceDelay=t.debounceDelay),t?.saveHandler&&(this.saveHandler=t.saveHandler)}setLessonId(t){this.lessonId!==t&&(this.pendingMap.size>0&&this.lessonId&&this.flush(),this.lessonId=t,this.status=t?"saved":"none",this.notifyListeners())}getLessonId(){return this.lessonId}setSaveHandler(t){this.saveHandler=t}setDebounceDelay(t){this.debounceDelay=Math.max(100,t)}getDebounceDelay(){return this.debounceDelay}getStatus(){return this.status}getLastSavedTime(){return this.lastSavedTime}getPendingCount(){return this.pendingMap.size}getLastError(){return this.lastError}registerInterceptor(t){return this.interceptors.add(t),()=>{this.interceptors.delete(t)}}registerListener(t){return this.listeners.add(t),t(this.status,{lessonId:this.lessonId||void 0,lastSavedTime:this.lastSavedTime,count:this.pendingMap.size}),()=>{this.listeners.delete(t)}}notifyListeners(){this.listeners.forEach(t=>{try{t(this.status,{lessonId:this.lessonId||void 0,lastSavedTime:this.lastSavedTime,error:this.lastError,count:this.pendingMap.size})}catch(a){console.error("[WhiteboardAutoSaveManager] Listener error:",a)}})}queueUpdate(t,a){if(!this.lessonId)return;const u=this.pendingMap.get(t)||{};this.pendingMap.set(t,{...u,...a}),this.status="pending",this.notifyListeners(),le.publish({id:ce(),type:"whiteboard.autosave.pending",source:"whiteboard.autosave",payload:{lessonId:this.lessonId,elementId:t,pendingCount:this.pendingMap.size},timestamp:Date.now(),correlationId:this.lessonId}),this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.flush()},this.debounceDelay)}async flush(){if(this.timer&&(clearTimeout(this.timer),this.timer=null),this.pendingMap.size===0||!this.lessonId||!this.saveHandler)return this.status==="pending"&&(this.status="saved",this.notifyListeners()),!0;if(this.isFlushing)return!1;let t=!1;const a={lessonId:this.lessonId,pendingElements:new Map(this.pendingMap),cancel:()=>{t=!0}};for(const n of this.interceptors)try{if(await n(a)===!1||t){t=!0;break}}catch(k){console.error("[WhiteboardAutoSaveManager] Interceptor error:",k)}if(t)return!1;this.isFlushing=!0,this.status="saving",this.notifyListeners(),le.publish({id:ce(),type:"whiteboard.autosave.saving",source:"whiteboard.autosave",payload:{lessonId:this.lessonId,pendingCount:this.pendingMap.size},timestamp:Date.now(),correlationId:this.lessonId});const u=Array.from(this.pendingMap.entries()),m=[];let r=!1;try{for(const[n,k]of u)await this.saveHandler(this.lessonId,n,k)?(m.push(n),this.pendingMap.get(n)===k&&this.pendingMap.delete(n)):r=!0;if(r)throw new Error("One or more element updates failed to save");return this.lastSavedTime=new Date,this.lastError=null,this.status=this.pendingMap.size>0?"pending":"saved",this.notifyListeners(),le.publish({id:ce(),type:"whiteboard.autosave.saved",source:"whiteboard.autosave",payload:{lessonId:this.lessonId,savedElementIds:m,lastSavedTime:this.lastSavedTime.toISOString()},timestamp:Date.now(),correlationId:this.lessonId}),!0}catch(n){return this.lastError=n,this.status="error",this.notifyListeners(),le.publish({id:ce(),type:"whiteboard.autosave.error",source:"whiteboard.autosave",payload:{lessonId:this.lessonId,error:n?.message||String(n)},timestamp:Date.now(),correlationId:this.lessonId}),!1}finally{this.isFlushing=!1,this.pendingMap.size>0&&!this.timer&&(this.timer=setTimeout(()=>{this.flush()},this.debounceDelay))}}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.pendingMap.clear(),this.status=this.lessonId?"saved":"none",this.lastError=null,this.notifyListeners()}}const L=new Dt;function Pt({lessonId:s,onSaveToServer:t,debounceDelay:a=800,onStatusChange:u}){const[m,r]=p.useState(()=>L.getStatus()),[n,k]=p.useState(()=>L.getLastSavedTime()),[f,v]=p.useState(()=>L.getPendingCount()),h=p.useRef(t);h.current=t;const b=p.useRef(u);b.current=u,p.useEffect(()=>{L.setLessonId(s),L.setDebounceDelay(a),L.setSaveHandler(async(c,y,x)=>h.current(c,y,x))},[s,a]),p.useEffect(()=>{const c=L.registerListener((y,x)=>{r(y),x?.lastSavedTime!==void 0&&k(x.lastSavedTime),x?.count!==void 0&&v(x.count),b.current?.(y,x?.lastSavedTime??null)});return()=>{c()}},[]),p.useEffect(()=>{const c=()=>{L.getPendingCount()>0&&L.flush()};return window.addEventListener("beforeunload",c),()=>{window.removeEventListener("beforeunload",c),L.flush()}},[]);const z=p.useCallback((c,y)=>{L.queueUpdate(c,y)},[]),o=p.useCallback(async()=>L.flush(),[]),N=p.useCallback(()=>{L.cancel()},[]);return{status:m,lastSavedTime:n,pendingCount:f,queueUpdate:z,flush:o,cancel:N,registry:L}}function qt(){const s=Ge(),{lang:t,session:a,onCopyCourse:u,lessons:m,selectedLesson:r,activeRole:n,setActiveRole:k,editorSaveStatus:f,setEditorSaveStatus:v,editorLastSavedTime:h,setEditorLastSavedTime:b,setTeacherTab:z,handlePaletteActivate:o,timelineSegments:N,activeSegmentId:c,setActiveSegmentId:y,draggedSegmentIdx:x,setDraggedSegmentIdx:C,saveTimeline:P,editorPanelsExpanded:Q,setEditorPanelsExpanded:O,fetchElements:g,whiteboardRef:w,elements:E,paletteEdit:q,handlePaletteConfirm:Z,setPaletteEdit:A,exportCoursePackage:G}=We(),_=Ce(i=>i.session),F=a||_,I=m.find(i=>i.id===r),U=F?.username==="admin"||F?.userId==="usr_admin"||F?.role==="administrator"||F?.subRole==="administrator",de=!I?.creator_id||I.creator_id===F?.userId||I.creator_id===F?.username,X=U||de,R=!X||n!=="teacher",[ue,J]=p.useState(!1),[ee,ae]=p.useState(!1),ne=async()=>{if(!(!r||ee)){ae(!0);try{await G(r)}finally{ae(!1)}}},[he,ie]=p.useState([]),[V,te]=p.useState(0),[W,B]=p.useState(null),M=p.useRef(null),Y=p.useRef(null);p.useEffect(()=>{W||(M.current=null,Y.current=null)},[W]),p.useEffect(()=>{if(!s)return;const i=s.getDispatcher?.();if(!i)return;const S=i.registerHandler("host:refresh",async $=>{const K=$.action.payload.target;if(K==="lessons"||K==="all")return r&&g&&await g(r),{success:!0,refreshed:["lessons"]}});return()=>{S.dispose()}},[s,r,g]);const se=async(i,S,$)=>{try{return(await fetch(`/api/lessons/${i}/whiteboard/${S}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:$})})).ok}catch(K){return console.error("[LessonEditorView] autosave element failed:",K),!1}},{queueUpdate:l,flush:d,pendingCount:j}=Pt({lessonId:r,onSaveToServer:se,debounceDelay:800,onStatusChange:(i,S)=>{i!=="pending"&&v(i),S&&b(S)}}),T=p.useCallback((i,S)=>{const $=M.current||Y.current;return $?$.type==="page"?((async()=>(await w.current?.moveElementToPage?.(S,$.pageIndex),r&&(await d(),await g(r))))(),!0):$.type==="segment"?((async()=>(await w.current?.moveElementToSegment?.(S,$.segmentId),r&&(await d(),await g(r))))(),!0):!1:!1},[w,r,d,g]);p.useEffect(()=>{if(!r)return;const i=new He;return i.broadcastChangeLesson(r),c&&i.broadcastChangeSegment(c),()=>{i.destroy()}},[r,c]);const D=i=>{if(R){alert(X?t==="zh"?"学生视角预览为只读模式。":"Student preview is read-only.":t==="zh"?"【只读模式】您无法直接修改其他教师创建的课程。请点击上方的「一键克隆为我的备课」生成您的专属教案副本。":"[Read-Only Mode] You cannot modify lessons created by other teachers. Please clone it to your own lessons.");return}o(i)};return e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 min-w-0 bg-surface rounded-2xl border border-theme overflow-hidden shadow-sm text-main transition-colors",children:[e.jsxs("div",{className:"px-4 py-2.5 border-b border-theme flex flex-wrap items-center justify-between gap-3 shrink-0 bg-surface/85 backdrop-blur-md",children:[e.jsxs("div",{className:"flex items-center gap-3 min-w-0 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx("div",{className:"w-8 h-8 rounded-xl bg-primary-theme/10 text-primary-theme border border-primary-theme/20 flex items-center justify-center shrink-0",children:e.jsx(lt,{size:16})}),e.jsxs("div",{className:"flex flex-col min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[10px] font-black uppercase tracking-wider text-primary-theme",children:t==="zh"?"教案与白板编排":"Lesson Orchestrator"}),R&&e.jsx("span",{className:"text-[9px] px-1.5 py-0.2 rounded-full font-bold bg-amber-500/15 text-amber-600 border border-amber-500/30",children:t==="zh"?"只读预览":"Read-Only Preview"})]}),e.jsx("h2",{className:"text-xs sm:text-sm font-black text-main truncate tracking-tight",children:t==="zh"?`课程编辑器: ${I?.title||"未选择课程"}`:`Lesson Editor: ${I?.title||"No Lesson Selected"}`})]})]}),r&&e.jsxs("div",{className:"hidden sm:flex items-center gap-1.5 shrink-0",children:[j>0&&f!=="saving"&&e.jsxs("button",{type:"button",onClick:()=>void d(),title:t==="zh"?"有未保存改动,点击立即写入服务器":"Pending changes, click to sync now",className:"flex items-center gap-1.5 text-xs font-bold text-amber-700 dark:text-amber-300 bg-amber-500/10 hover:bg-amber-500/20 border border-amber-500/30 px-2.5 py-1 rounded-full transition-all cursor-pointer shadow-2xs hover:scale-102",children:[e.jsx(pe,{size:11,className:"animate-spin text-amber-600"}),e.jsx("span",{children:t==="zh"?`${j} 项待写入 (点击立即保存)`:`${j} pending (sync now)`})]}),f==="saving"&&e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-bold text-amber-700 dark:text-amber-300 bg-amber-500/10 border border-amber-500/30 px-2.5 py-1 rounded-full animate-pulse shadow-2xs",children:[e.jsx(pe,{size:11,className:"animate-spin text-amber-600"}),e.jsx("span",{children:t==="zh"?"同步 SQLite...":"Saving SQLite..."})]}),f==="saved"&&j===0&&e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-bold text-emerald-700 dark:text-emerald-300 bg-emerald-500/10 border border-emerald-500/30 px-2.5 py-1 rounded-full shadow-2xs",children:[e.jsx(De,{size:11,className:"text-emerald-500"}),e.jsx("span",{children:t==="zh"?"已自动保存":"Auto-Saved"}),h&&e.jsx("span",{className:"text-[11px] font-mono opacity-70",children:h.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})})]}),f==="error"&&e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-bold text-rose-600 bg-rose-500/10 border border-rose-500/30 px-2.5 py-1 rounded-full shadow-2xs",children:[e.jsx(Ie,{size:11,className:"text-rose-600"}),e.jsx("span",{children:t==="zh"?"写入失败":"Failed to save"})]}),f==="none"&&j===0&&e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-bold text-muted bg-surface-secondary border border-theme px-2.5 py-1 rounded-full shadow-2xs",children:[e.jsx(ct,{size:11,className:"text-muted"}),e.jsx("span",{children:t==="zh"?"同步就绪":"Ready"})]}),e.jsx(H,{slot:"whiteboard.autosave.status",slotProps:{lessonId:r,status:f,pendingCount:j,lastSavedTime:h}}),e.jsx(H,{slot:"whiteboard.autosave.action",slotProps:{lessonId:r,flush:d,pendingCount:j}})]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsxs("div",{className:"bg-surface-secondary border border-theme p-1 rounded-xl flex items-center gap-1 shadow-2xs",children:[e.jsxs("button",{type:"button",onClick:()=>k("teacher"),className:`px-3 py-1 text-xs font-bold rounded-lg transition-all cursor-pointer flex items-center gap-1.5 ${n==="teacher"?"bg-surface text-primary-theme font-black shadow-xs border border-theme/60 scale-102":"text-muted hover:text-main"}`,title:t==="zh"?"在当前窗口切回教师编辑视角":"Switch back to the teacher editor view",children:[e.jsx("span",{children:"👨‍🏫"}),e.jsx("span",{children:t==="zh"?"教师视角":"Teacher"})]}),e.jsxs("button",{type:"button",onClick:()=>{const i=`${window.location.origin}${window.location.pathname}?mode=student_preview&lessonId=${encodeURIComponent(r||"")}#/student_preview`;window.open(i,"_blank")||alert(t==="zh"?"新标签页被浏览器拦截,请允许本站打开弹出窗口后重试。":"The new tab was blocked. Please allow pop-ups for this site and retry.")},className:`px-3 py-1 text-xs font-bold rounded-lg transition-all cursor-pointer flex items-center gap-1.5 ${n==="student"?"bg-primary-theme text-white font-black shadow-xs scale-102":"text-muted hover:text-main"}`,title:t==="zh"?"在新标签页中以学生身份预览本课节(不影响当前备课窗口)":"Open a student-perspective preview of this lesson in a new tab",children:[e.jsx("span",{children:"🎓"}),e.jsx("span",{children:t==="zh"?"学生视角":"Student"})]})]}),e.jsx(H,{slot:"editor.header.action",slotProps:{lessonId:r,currentLesson:I,lang:t,isReadOnly:R,activeRole:n,onSave:se}}),X&&I&&e.jsxs("button",{type:"button",onClick:()=>void ne(),disabled:ee,className:"px-3 py-1.5 bg-sky-50 hover:bg-sky-100 border border-sky-200 text-sky-700 text-xs font-bold rounded-xl transition-all cursor-pointer shadow-2xs hover:scale-102 flex items-center gap-1.5 disabled:opacity-60 disabled:cursor-wait",title:t==="zh"?"导出为课程包(教学环节 + 白板元素 + 内联附件,可拖回导入框复用)":"Export as course package (segments + whiteboard elements + embedded assets)","data-testid":"editor-export-package-btn",children:[ee?e.jsx(pe,{size:13,className:"animate-spin"}):e.jsx(dt,{size:13}),e.jsx("span",{children:t==="zh"?"导出课程包":"Export Package"})]}),e.jsx("button",{type:"button",onClick:()=>z("courses"),className:"px-3 py-1.5 bg-surface hover:bg-surface-secondary border border-theme text-muted hover:text-main text-xs font-bold rounded-xl transition-all cursor-pointer shadow-2xs hover:scale-102",children:t==="zh"?"返回课程库":"Back to Courses"})]})]}),!X&&I&&e.jsxs("div",{className:"bg-amber-500/10 border-b border-amber-500/20 px-4 py-2.5 flex items-center justify-between text-xs text-amber-800 dark:text-amber-300 backdrop-blur-xs shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ut,{size:15,className:"text-amber-500 shrink-0"}),e.jsx("span",{children:t==="zh"?`【他人课程只读模式】当前课程由教师「${I.creator_name||I.creator_id}」创建。您拥有完整查看与备课参考权限。如需编辑调整,请克隆为您的专属教案。`:`[Read-Only Mode] This lesson was created by teacher "${I.creator_name||I.creator_id}". To customize, please clone it.`})]}),u&&e.jsxs("button",{onClick:()=>u(I.id),className:"flex items-center gap-1.5 bg-amber-600 hover:bg-amber-500 text-white font-semibold px-3 py-1.5 rounded-xl shadow-xs transition-all hover:scale-102 cursor-pointer shrink-0",children:[e.jsx(ht,{size:13}),e.jsx("span",{children:t==="zh"?"一键克隆为我的备课":"Clone as My Lesson"})]})]}),e.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[e.jsx(jt,{lang:t,onActivate:D,readOnly:R,collapsed:ue,onToggleCollapse:J,pages:he,currentPage:V,onSwitchPage:i=>w.current?.switchPage?.(i),onAddPage:i=>w.current?.addPage?.(i),onDeletePage:i=>w.current?.deletePage?.(i),onRenamePage:(i,S)=>w.current?.renamePage?.(i,S),dragState:W,onHoverDropTarget:i=>{M.current=i}}),e.jsxs("div",{className:"flex-1 relative bg-surface flex flex-col min-w-0",children:[e.jsx(wt,{lang:t,segments:N,activeSegmentId:c,setActiveSegmentId:y,draggedSegmentIdx:x,setDraggedSegmentIdx:C,selectedLesson:r,saveTimeline:P,readOnly:R,editorPanelsExpanded:Q,setEditorPanelsExpanded:O,dragState:W,onHoverDropTarget:i=>{Y.current=i}}),e.jsxs("div",{className:"flex-1 relative flex flex-col min-w-0 overflow-y-auto",children:[r&&c&&Q&&N.some(i=>i.id===c)&&e.jsx(It,{lang:t,segment:N.find(i=>i.id===c),readOnly:R,onPatch:i=>P(r,N.map(S=>S.id===c?{...S,...i}:S)),onDelete:()=>{if(N.length<=1){alert("无法删除!课程必须包含至少一个环节。");return}if(window.confirm(`确定要删除环节"${N.find(i=>i.id===c)?.title}"吗?`)){const i=N.filter(S=>S.id!==c);P(r,i),y(i[0]?.id||null)}}},c),e.jsx("div",{className:"flex-1 min-h-[380px] relative flex flex-col min-w-0",children:r?e.jsxs(e.Fragment,{children:[e.jsx(Ue,{ref:w,lessonId:r,userRole:n,readOnly:R,elements:E,activeSegmentId:c,hidePageBar:!0,onPagesStateChange:({pages:i,currentPage:S})=>{ie(i),te(S)},onSegmentSync:i=>y(i),onElementDragChange:B,onElementDropCheck:T,onElementAdd:async(i,S)=>{if(!R){await d(),v("saving");try{(await fetch(`/api/lessons/${r}/whiteboard`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:i,data:S})})).ok?(v("saved"),b(new Date),g(r)):v("error")}catch{v("error")}}},onElementUpdate:(i,S)=>{R||l(i,S)},onElementDelete:async i=>{if(!R){await d(),v("saving");try{(await fetch(`/api/lessons/${r}/whiteboard/${i}`,{method:"DELETE"})).ok?(v("saved"),b(new Date),g(r)):v("error")}catch{v("error")}}},onClearBoard:async()=>{if(!R){await d(),v("saving");try{(await fetch(`/api/lessons/${r}/whiteboard`,{method:"DELETE"})).ok?(v("saved"),b(new Date),g(r)):v("error")}catch{v("error")}}},onRefresh:()=>g(r)}),q&&!R&&ve(q.type)&&e.jsx(Tt,{config:ve(q.type),lang:t,initialData:q.data,onConfirm:Z,onCancel:()=>A(null)})]}):e.jsx("div",{className:"absolute inset-0 flex items-center justify-center text-muted p-8 text-center bg-surface-secondary/50",children:e.jsxs("div",{children:[e.jsx(mt,{size:48,className:"mx-auto mb-4 opacity-30"}),e.jsx("p",{className:"font-medium text-lg text-main mb-2",children:"No active lesson selected"}),e.jsx("p",{className:"text-sm",children:"Please select a lesson from the Dashboard to orchestrate."})]})})})]})]})]})]})}export{qt as LessonEditorView};
@@ -1,4 +1,4 @@
1
- import{r as i,j as e,R as Tt}from"./vendor-react-DHoBZpn2.js";import{T as Ks,E as me,s as va,U as ps,V as wa,W as ka,X as za,l as Ut,Y as at,Z as xt,_ as Sa,b as Ca,e as $a,y as Br,$ as Aa,O as Ea,a0 as Ta,Q as Pa,a1 as _a,a2 as Ct,a3 as Ra}from"./index-DuxQtTr9.js";import{L as Ia}from"./LazyWhiteboard-BxpydfnE.js";import{R as _e,q as ft,aZ as La,C as fs,a8 as Ma,D as yt,E as tn,U as Ee,j as Xs,aa as qt,as as Vt,ah as er,Z as ut,be as Oa,a9 as Me,X as ke,B as It,h as Ae,aA as sn,Q as bt,bf as rn,bg as Kt,bh as bs,bi as Da,a4 as Oe,bj as nn,J as gs,b7 as tr,s as an,k as ms,V as ve,bk as on,t as Js,ag as Yt,a7 as ln,bl as Fa,bm as Ba,bn as us,af as tt,an as Pt,bo as cn,bp as Ga,T as Ie,u as Ve,aC as dn,bq as Ha,br as js,bs as Wa,n as ys,bt as Ua,i as Lt,K as qa,ad as gt,ai as Qt,bu as Va,m as Ka,aU as Jt,e as xn,bv as mn,O as sr,$ as rr,g as Wt,bw as Ja,G as nr,bx as Ya,A as Ns,by as un,bz as ar,a$ as Mt,x as or,c as jt,a3 as vs,bA as hn,bB as Qa,bC as _t,aD as Gr,b2 as Za,bD as ds,L as Xa,y as Zt,_ as ir,w as pn,bE as eo,am as fn,aM as to,aG as lr,a0 as bn,bF as gn,bG as cr,bH as so,bI as jn,bJ as yn,v as ro,bK as no,bL as ao,b as Ys,av as oo,bM as io,bN as Hr,bO as Bs,S as Wr,aT as lo,bP as Ur,bQ as co,aB as xo,bR as mo,bS as uo,bT as ho,bU as po}from"./vendor-icons-DLOPlM4i.js";import{C as fo,T as bo}from"./ClassroomCountdownWidget-C9pv3GLy.js";import{a as Nn,P as go,h as jo,g as yo,A as No,C as vo,X as wo,Y as ko,b as zo,T as So,e as Co}from"./vendor-charts-skggaP9D.js";import{r as dr,f as vn,D as wn,s as kn}from"./timeline-duration-BgdJCSrW.js";import{f as $o,t as Ao}from"./teaching-modes-client-BeVaDdJ-.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";const qr=Ks;function zn({lessonId:t,lang:r,addToast:a}){const[o,d]=i.useState(!1),[n,l]=i.useState(!1),[s,h]=i.useState([]),[c,u]=i.useState(60),[m,p]=i.useState(40),[w,f]=i.useState({}),[N,b]=i.useState({}),[$,P]=i.useState({}),[y,k]=i.useState({}),[g,A]=i.useState({}),[U,W]=i.useState({}),T=r==="zh",Y=async(j=!1)=>{j?l(!0):d(!0);try{const ee=await(await fetch(`/api/lessons/${t}/eval-grades`)).json();if(Array.isArray(ee)){h(ee);const R={},O={},L={},X={};ee.forEach(K=>{K.grade?(R[K.id]=K.grade.teacher_score,O[K.id]=K.grade.teacher_comment,L[K.id]=Math.round(K.grade.teacher_weight*100),X[K.id]=Math.round(K.grade.peer_weight*100)):(R[K.id]=w[K.id]!==void 0?w[K.id]:80,O[K.id]=N[K.id]!==void 0?N[K.id]:"",L[K.id]=$[K.id]!==void 0?$[K.id]:c,X[K.id]=y[K.id]!==void 0?y[K.id]:m)}),f(K=>({...R,...K})),b(K=>({...O,...K})),P(K=>({...L,...K})),k(K=>({...X,...K}))}else throw new Error("Invalid submissions data format")}catch(q){console.error("Error fetching submissions grades:",q),a(T?"数据加载失败":"Failed to Load Data",T?"请检查网络连接或刷新页面。":"Please check your connection and try again.","warning")}finally{d(!1),l(!1)}};i.useEffect(()=>{t&&Y()},[t]),i.useEffect(()=>{const j=ps();if(!j||!t)return;const q=ee=>{(!ee?.lessonId||ee.lessonId===t)&&Y()};return j.on("assignment-submitted-toast",q),()=>{typeof j.off=="function"&&j.off("assignment-submitted-toast",q)}},[t]);const V=j=>{u(j),p(100-j),P(q=>{const ee={...q};return s.forEach(R=>{(!R.grade||R.grade.status!=="confirmed")&&(ee[R.id]=j)}),ee}),k(q=>{const ee={...q};return s.forEach(R=>{(!R.grade||R.grade.status!=="confirmed")&&(ee[R.id]=100-j)}),ee})},le=(j,q)=>{P(ee=>({...ee,[j]:q})),k(ee=>({...ee,[j]:100-q}))},F=async(j,q)=>{const ee=w[j],R=N[j]||"",O=($[j]??c)/100,L=(y[j]??m)/100;if(ee===void 0||isNaN(ee)||ee<0||ee>100){a(T?"评分无效":"Invalid Score",T?"教师评分必须在 0 到 100 之间!":"Teacher score must be between 0 and 100!","warning");return}if(q==="confirmed"){const X=T?"确认同步后,最终得分将直接同步写入宿主学期成绩库,此后该学生的作业成绩将锁定不可修改。是否确认?":"Once confirmed, the final score will be synced to the host semester reports and locked. Proceed?";if(!window.confirm(X))return}W(X=>({...X,[j]:q}));try{const K=await(await fetch("/api/commands",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({commandType:"assignment.grade",payload:{submissionId:j,teacherScore:Number(ee),teacherComment:R,teacherWeight:O,peerWeight:L,status:q}})})).json();if(K.success)a(q==="confirmed"?T?"平时成绩同步成功":"Semester Grade Synced":T?"平时成绩草稿已保存":"Grade Draft Saved",q==="confirmed"?T?`已将平时成绩 ${K.result.calculatedFinalScore} 分同步至学期报告!`:`Successfully synced grade ${K.result.calculatedFinalScore}!`:T?"成功保存了教师打分与评语草稿。":"Successfully saved score and comment draft.","success"),Y(!0);else throw new Error(K.error||"Failed to submit grade")}catch(X){a(T?"操作失败":"Operation Failed",X.message,"warning")}finally{W(X=>({...X,[j]:null}))}},D=j=>{A(q=>({...q,[j]:!q[j]}))};return o?e.jsxs("div",{className:"flex-grow flex flex-col items-center justify-center py-12 text-gray-500",children:[e.jsx(_e,{className:"animate-spin text-indigo-500 mb-2",size:32}),e.jsx("p",{className:"text-xs",children:T?"正在读取学生作业与成绩状态...":"Loading student submissions and grades..."})]}):e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 w-full relative rounded-xl overflow-hidden border border-slate-200 shadow-md bg-white p-5 text-left",children:[e.jsxs("div",{className:"flex justify-between items-center pb-4 border-b border-slate-100 mb-4 gap-3 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("h3",{className:"text-sm font-bold text-slate-800 flex items-center gap-1.5 select-none",children:[e.jsx(ft,{size:16,className:"text-indigo-655"}),T?"学生作业成绩评定与折算系统":"Student Assignment Grading & Sync"]}),e.jsxs("span",{className:"text-xs bg-indigo-50 text-indigo-750 px-2 py-0.5 rounded-full border border-indigo-100 font-bold",children:[s.length," ",T?"个提交":"submissions"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(me,{slot:"assignment.grade.toolbar.action",slotProps:{lessonId:t,submissions:s,refresh:()=>Y(!0),lang:r}}),e.jsx("button",{onClick:()=>Y(!0),disabled:n,className:"p-1.5 bg-white hover:bg-slate-55 border border-slate-200 rounded-lg text-slate-600 transition-colors flex items-center justify-center cursor-pointer shadow-4xs",title:T?"刷新数据":"Refresh",children:e.jsx(_e,{size:12,className:n?"animate-spin":""})})]})]}),e.jsxs("div",{className:"bg-slate-50 border border-slate-200 rounded-xl p-4 mb-5 shrink-0 flex flex-col md:flex-row md:items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-2.5",children:[e.jsx(La,{className:"text-indigo-500 shrink-0 mt-0.5",size:16}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs font-bold text-slate-700",children:T?"全局默认折算权重设置":"Default Grading Weights Configuration"}),e.jsx("p",{className:"text-xs text-subtle mt-0.5 font-medium",children:T?"调整权重分配,所有尚未锁定成绩的学生将自动应用此默认权重比例。":"Setting global default weights. Changes will automatically apply to non-confirmed grades."})]})]}),e.jsxs("div",{className:"flex items-center gap-4 shrink-0 bg-white px-3.5 py-2 rounded-lg border border-slate-200 shadow-3xs",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs font-bold text-slate-500",children:T?"教师评分:":"Teacher:"}),e.jsx("input",{type:"range","aria-label":T?"教师评分权重":"Teacher weight",min:"0",max:"100",step:"5",value:c,onChange:j=>V(Number(j.target.value)),className:"w-20 accent-indigo-650 cursor-pointer"}),e.jsxs("span",{className:"text-xs font-bold text-indigo-700 w-8 text-right",children:[c,"%"]})]}),e.jsx("div",{className:"h-4 w-[1px] bg-slate-200"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs font-bold text-slate-500",children:T?"学生互评:":"Peer Review:"}),e.jsxs("span",{className:"text-xs font-bold text-slate-700 w-8",children:[m,"%"]})]})]}),e.jsx(me,{slot:"assignment.grade.rubric.addon",slotProps:{lessonId:t,defaultTeacherWeight:c,defaultPeerWeight:m,onTeacherWeightChange:V,lang:r}})]}),e.jsx("div",{className:"flex-grow flex-1 overflow-y-auto space-y-4 pr-1 scrollbar-thin",children:s.length===0?e.jsxs("div",{className:"h-full flex flex-col items-center justify-center py-12 text-slate-400 gap-2",children:[e.jsx(fs,{size:32,className:"text-slate-350"}),e.jsx("p",{className:"text-xs",children:T?"本节课目前没有任何学生提交作业。":"No students have submitted assignments yet for this lesson."})]}):s.map(j=>{const q=w[j.id]!==void 0?w[j.id]:80,ee=N[j.id]||"",R=$[j.id]??c,O=y[j.id]??m,L=j.grade?.status==="confirmed",X=Math.round(q*(R/100)+j.peerAverageScore*(O/100));return e.jsxs("div",{className:`bg-white border rounded-xl shadow-3xs overflow-hidden transition-all ${L?"border-emerald-200 bg-emerald-50/5":"border-slate-200"}`,children:[e.jsxs("div",{className:"px-4 py-3 bg-slate-50/50 border-b border-slate-100 flex flex-col md:flex-row md:items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("div",{className:"w-8 h-8 rounded-full bg-indigo-50 border border-indigo-100 flex items-center justify-center text-indigo-700 font-bold text-xs select-none",children:j.studentName?.charAt(0)||"S"}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-bold text-slate-800",children:j.studentName}),e.jsxs("div",{className:"text-xs text-slate-400 font-mono mt-0.5 flex items-center gap-1.5",children:[e.jsxs("span",{children:["V",j.version]}),e.jsx("span",{children:"•"}),e.jsx("span",{children:new Date(j.updatedAt).toLocaleString()})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[L?e.jsxs("span",{className:"bg-emerald-55 text-emerald-700 text-xs font-black px-2.5 py-1 rounded-full border border-emerald-150 flex items-center gap-1 shadow-3xs select-none",children:[e.jsx(Ma,{size:12}),T?"成绩已同步":"Synced to Reports"]}):e.jsx("span",{className:"bg-amber-50 text-amber-805 text-xs font-bold px-2 py-0.5 rounded-full border border-amber-200/60 select-none",children:j.grade?T?"草稿状态":"Draft":T?"未评定":"Ungraded"}),(()=>{const K=va(j.filePath);return K?e.jsxs("a",{href:K,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-indigo-600 hover:text-indigo-850 font-medium hover:underline flex items-center gap-1 bg-white border border-slate-200 px-2 py-1 rounded-lg shadow-4xs",title:j.filePath,children:[e.jsx(yt,{size:11}),T?"查看作业":"View File",e.jsx(tn,{size:8})]}):null})()]})]}),e.jsxs("div",{className:"p-4 grid grid-cols-1 lg:grid-cols-12 gap-5",children:[e.jsxs("div",{className:"lg:col-span-5 flex flex-col gap-2.5 border-r border-slate-100 pr-0 lg:pr-5 text-left",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("span",{className:"text-xs font-bold text-slate-650 flex items-center gap-1 select-none",children:[e.jsx(Ee,{size:13,className:"text-slate-400"}),T?"学生互评详情":"Peer Review Details"]}),e.jsxs("span",{className:"text-xs font-bold text-slate-500 bg-slate-100 px-2 py-0.5 rounded-md",children:[T?"互评人数:":"Reviews:"," ",j.peerReviews.length]})]}),e.jsxs("div",{className:"bg-slate-50 border border-slate-100 rounded-xl p-3 flex items-center gap-3",children:[e.jsxs("div",{className:"bg-white border border-slate-200 w-12 h-12 rounded-lg flex flex-col items-center justify-center shrink-0 shadow-3xs",children:[e.jsx("span",{className:"text-xs text-slate-405 select-none font-bold",children:T?"均分":"Avg"}),e.jsx("span",{className:"text-sm font-extrabold text-slate-700 leading-none mt-0.5",children:j.peerAverageScore})]}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-xs text-slate-450 leading-normal font-medium",children:j.peerReviews.length>0?T?"根据同学互评分数得出的平均值。":"Average score computed from classmate evaluations.":T?"暂无同学对此作业给出评分。":"No classmate peer reviews received yet."}),j.peerReviews.length>0&&e.jsx("button",{onClick:()=>D(j.id),className:"text-xs text-indigo-650 hover:text-indigo-800 font-bold mt-1.5 flex items-center gap-0.5 cursor-pointer outline-none",children:g[j.id]?e.jsxs(e.Fragment,{children:[T?"收起互评详情":"Hide Details"," ",e.jsx(Xs,{size:12})]}):e.jsxs(e.Fragment,{children:[T?"展开互评详情":"Show Details"," ",e.jsx(qt,{size:12})]})})]})]}),g[j.id]&&j.peerReviews.length>0&&e.jsx("div",{className:"mt-2 space-y-2 border-t border-slate-100 pt-2.5 max-h-40 overflow-y-auto scrollbar-thin",children:j.peerReviews.map(K=>e.jsxs("div",{className:"bg-white border border-slate-200 rounded-lg p-2.5 text-xs text-left shadow-4xs",children:[e.jsxs("div",{className:"flex justify-between items-center font-bold text-slate-700",children:[e.jsxs("span",{className:"flex items-center gap-1 font-semibold text-slate-655",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-slate-300"}),K.reviewer_name]}),e.jsxs("span",{className:"text-indigo-650 bg-indigo-50 border border-indigo-100 rounded px-1.5 py-0.5 text-xs",children:[K.score," ",T?"分":"pts"]})]}),K.comment&&e.jsxs("p",{className:"text-xs text-slate-550 mt-1 italic pl-2.5 border-l-2 border-slate-100 font-medium",children:['"',K.comment,'"']})]},K.id))})]}),e.jsxs("div",{className:"lg:col-span-7 flex flex-col gap-3 justify-between",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-slate-650 mb-1 select-none",children:T?"教师平时分评分 (0-100)":"Teacher Score (0-100)"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{id:`teacher_score_input_${j.id}`,type:"number",min:"0",max:"100",disabled:L,value:q,onChange:K=>f(H=>({...H,[j.id]:Math.min(100,Math.max(0,Number(K.target.value)))})),className:"bg-white border border-slate-250 rounded-lg text-xs font-bold text-slate-700 px-3 py-1.5 focus:ring-1 focus:ring-indigo-500 outline-none w-20 shadow-4xs disabled:opacity-50 disabled:bg-slate-50"}),e.jsx("input",{type:"range","aria-label":T?`${j.studentName||"学生"} 的得分`:`Score for ${j.studentName||"student"}`,min:"0",max:"100",disabled:L,value:q,onChange:K=>f(H=>({...H,[j.id]:Number(K.target.value)})),className:"flex-1 accent-indigo-650 disabled:opacity-40 cursor-pointer"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center mb-1",children:[e.jsx("label",{className:"block text-xs font-bold text-slate-600 select-none",children:T?"打分占比 (教师权重)":"Teacher Score Weight"}),e.jsx("span",{className:"text-xs font-bold text-slate-400",children:T?`学生互评: ${O}%`:`Peer: ${O}%`})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{id:`teacher_weight_input_${j.id}`,type:"range",min:"0",max:"100",step:"5",disabled:L,value:R,onChange:K=>le(j.id,Number(K.target.value)),className:"flex-1 accent-indigo-650 disabled:opacity-40 cursor-pointer"}),e.jsxs("span",{className:"text-xs font-extrabold text-indigo-750 w-9 text-right",children:[R,"%"]})]})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-slate-655 mb-1 select-none",children:T?"教师评价评语":"Teacher Comments & Feedback"}),e.jsx("textarea",{id:`teacher_comment_input_${j.id}`,disabled:L,value:ee,placeholder:T?"在此输入对学生作业作品的改进指导意见及评语。":"Enter guiding feedback for this student.",onChange:K=>b(H=>({...H,[j.id]:K.target.value})),rows:2,className:"w-full bg-white border border-slate-250 rounded-lg text-xs p-2 focus:ring-1 focus:ring-indigo-500 outline-none shadow-4xs disabled:opacity-50 disabled:bg-slate-50 resize-none font-medium text-slate-700"})]}),e.jsx(me,{slot:"assignment.grade.item.addon",slotProps:{submission:j,studentId:j.student_id,lessonId:t,score:q,comment:ee,isConfirmed:L,onScoreChange:K=>f(H=>({...H,[j.id]:K})),onCommentChange:K=>b(H=>({...H,[j.id]:K})),lang:r}}),e.jsxs("div",{className:"flex flex-col md:flex-row md:items-center justify-between gap-4 pt-2 border-t border-slate-100 mt-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:`p-1.5 rounded-lg border flex items-center justify-center shrink-0 ${L?"bg-emerald-50 text-emerald-600 border-emerald-100":"bg-indigo-50 text-indigo-700 border-indigo-100"}`,children:e.jsx(Vt,{size:14})}),e.jsxs("div",{className:"text-xs text-slate-500 font-medium",children:[e.jsxs("div",{children:[T?"平时总分计算公式":"Calculated Final Grade",":"]}),e.jsxs("div",{className:"font-bold text-slate-700 mt-0.5 animate-formula",children:[R,"% × ",e.jsx("span",{className:"text-indigo-650 font-bold",children:q}),j.peerReviews.length>0&&` + ${O}% × ${j.peerAverageScore}`," = ",e.jsx("span",{className:L?"text-emerald-700 font-black text-xs":"text-indigo-700 font-black text-xs",children:L&&j.grade?.calculated_final_score||X}),T?"分":" pts"]})]})]}),!L&&e.jsxs("div",{className:"flex gap-2 justify-end shrink-0",children:[e.jsxs("button",{id:`teacher_draft_btn_${j.id}`,type:"button",disabled:!!U[j.id],onClick:()=>F(j.id,"draft"),className:"px-3 py-1.5 bg-white border border-slate-350 rounded-lg text-xs font-bold text-slate-700 hover:bg-slate-55 flex items-center gap-1.5 shadow-4xs cursor-pointer select-none disabled:opacity-50",children:[e.jsx(er,{size:12}),U[j.id]==="draft"?T?"保存中...":"Saving...":T?"暂存草稿":"Save Draft"]}),e.jsxs("button",{id:`teacher_confirm_btn_${j.id}`,type:"button",disabled:!!U[j.id],onClick:()=>F(j.id,"confirmed"),className:"px-3.5 py-1.5 bg-indigo-600 border border-indigo-700 rounded-lg text-xs font-bold text-white hover:bg-indigo-700 flex items-center gap-1.5 shadow-3xs cursor-pointer select-none disabled:opacity-50",children:[e.jsx(ut,{size:12}),U[j.id]==="confirmed"?T?"同步中...":"Syncing...":T?"确认并同步":"Confirm & Sync"]})]})]})]})]})]},j.id)})})]})}function Eo({isOpen:t,onClose:r,lessonId:a,lessonTitle:o,lang:d="zh"}){const{data:n,health:l,lastSyncedAt:s}=wa(a,{enabled:t});return t?e.jsx(ka,{lessonId:a,lessonTitle:o,data:n,lang:d,health:l,lastSyncedAt:s,onClose:r}):null}function To({lessonId:t,lessonTitle:r,lang:a}){const o=new URLSearchParams({mode:"stage_display",lessonId:t});r&&o.set("title",r),a&&o.set("lang",a);const{pathname:d,origin:n}=window.location;return`${n}${d}?${o.toString()}#/stage_display`}function Po(){const t=i.useRef(null),[r,a]=i.useState(!1),[o,d]=i.useState(!1);i.useEffect(()=>()=>{t.current=null},[]),i.useEffect(()=>{const h=setInterval(()=>{const c=t.current;c&&c.closed&&(t.current=null)},3e3);return()=>clearInterval(h)},[]);const n=i.useCallback(h=>{const c=t.current;if(c&&!c.closed){c.focus();return}let u;try{u=window.open(To(h),"openlearn-stage-display","width=1280,height=720,menubar=no,toolbar=no,location=no")}catch(m){console.warn("[StageDisplay] window.open threw:",m),u=null}if(!u){d(!0),a(!0);return}t.current=u,d(!1),a(!1),u.focus?.()},[]),l=i.useCallback(()=>a(!1),[]),s=i.useCallback(()=>d(!1),[]);return{fallbackOpen:r,blocked:o,openStageWindow:n,closeFallback:l,clearBlockedHint:s}}const Gs={CLEAR:{emoji:"💡",zh:"理解",en:"Clear",color:"#10b981"},CONFUSED:{emoji:"❓",zh:"困惑",en:"Confused",color:"#f59e0b"},TOO_FAST:{emoji:"🐇",zh:"慢一点",en:"Slow down",color:"#f43f5e"},SLOW:{emoji:"🐢",zh:"快一点",en:"Speed up",color:"#6366f1"}},_o=["CLEAR","CONFUSED","TOO_FAST","SLOW"];function Ro({lessonId:t,lang:r,signals:a,onlineCount:o=0,onClose:d,activeSegmentTitle:n}){const l=r==="zh",[s,h]=i.useState(a);i.useEffect(()=>{const f=ps();if(!f)return;const N=b=>{b?.lessonId===t&&b?.summary&&h(b.summary)};return f.on("classroom:pacing_updated",N),()=>{typeof f.off=="function"&&f.off("classroom:pacing_updated",N)}},[t]);const c=_o.map(f=>({key:f,count:Number(s[f]??0)})),u=c.reduce((f,N)=>f+N.count,0);Number(s.CONFUSED??0)+Number(s.TOO_FAST??0)+Number(s.SLOW??0);const m=u>0?Math.round(Number(s.CLEAR??0)/u*100):null,p=i.useCallback(()=>u===0?{text:l?"暂无学生反馈,等待中…":"No feedback yet",tone:"text-muted"}:Number(s.CONFUSED??0)>=Math.max(2,u*.3)?{text:l?"⚠ 较多学生困惑,建议放慢并重新讲解当前环节":"⚠ Many students are confused — slow down and re-explain",tone:"text-amber-600"}:Number(s.TOO_FAST??0)>=Math.max(2,u*.3)?{text:l?"🐇 较多学生希望放慢节奏":"🐇 Many students want you to slow down",tone:"text-rose-600"}:Number(s.SLOW??0)>=Math.max(2,u*.3)?{text:l?"🐢 较多学生希望加快节奏":"🐢 Many students want you to speed up",tone:"text-indigo-600"}:{text:l?"✓ 节奏反馈健康,可按当前节奏继续":"✓ Pace is healthy — carry on",tone:"text-emerald-700 dark:text-emerald-400"},[s,u,l]),w=c.filter(f=>f.count>0).map(f=>({name:Gs[f.key][l?"zh":"en"],value:f.count,color:Gs[f.key].color}));return e.jsx("div",{className:"fixed inset-0 z-[90] flex items-center justify-center bg-slate-900/60 backdrop-blur-2xs",onPointerDown:d,children:e.jsxs("div",{className:"bg-surface border border-theme rounded-2xl shadow-2xl w-[560px] max-w-[92vw] max-h-[86vh] overflow-y-auto p-5 font-sans text-main",onPointerDown:f=>f.stopPropagation(),children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"p-2 bg-primary-theme/10 text-primary-theme rounded-xl",children:e.jsx(Oa,{size:18})}),e.jsxs("div",{children:[e.jsxs("h2",{className:"text-sm font-black text-main flex items-center gap-1.5",children:[l?"课堂反馈情绪仪表盘":"Classroom Feedback Dashboard",e.jsxs("span",{className:"flex items-center gap-1 text-2xs font-bold text-emerald-700 dark:text-emerald-400 bg-emerald-500/10 px-1.5 py-0.5 rounded-full",children:[e.jsx(Me,{size:10})," ",l?"实时":"LIVE"]})]}),e.jsx("p",{className:"text-2xs text-muted mt-0.5",children:n?l?`当前教学环节: ${n} · 去重实时聚合`:`Active Segment: ${n} · Real-time`:l?"按环节去重 · 实时节奏反馈聚合":"Deduplicated real-time pacing feedback"})]})]}),e.jsx("button",{onClick:d,className:"p-1.5 rounded-lg hover:bg-surface-secondary text-muted cursor-pointer",title:l?"关闭":"Close",children:e.jsx(ke,{size:16})})]}),e.jsxs("div",{className:"flex flex-col md:flex-row gap-4 items-center",children:[e.jsxs("div",{className:"w-[200px] h-[200px] relative shrink-0",children:[u>0?e.jsx(Nn,{width:"100%",height:"100%",children:e.jsx(go,{children:e.jsx(jo,{data:w,dataKey:"value",nameKey:"name",innerRadius:52,outerRadius:85,paddingAngle:3,strokeWidth:0,isAnimationActive:!1,children:w.map((f,N)=>e.jsx(yo,{fill:f.color},N))})})}):e.jsx("div",{className:"w-full h-full flex items-center justify-center text-3xl opacity-30",children:"📊"}),e.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center pointer-events-none",children:[e.jsxs("span",{className:"text-2xs text-muted flex items-center gap-1",children:[e.jsx(Ee,{size:10})," ",o," ",l?"在线":"online"]}),e.jsx("span",{className:`text-xl font-black ${m===null?"text-muted":m>=60?"text-emerald-700 dark:text-emerald-400":m>=30?"text-amber-700 dark:text-amber-400":"text-rose-700 dark:text-rose-400"}`,children:m===null?"—":`${m}%`}),e.jsx("span",{className:"text-2xs text-muted",children:l?"理解占比":"clear ratio"})]})]}),e.jsxs("div",{className:"flex-1 w-full flex flex-col gap-2.5",children:[c.map(({key:f,count:N})=>{const b=Gs[f],$=u>0?Math.round(N/u*100):0;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between text-xs mb-0.5",children:[e.jsxs("span",{className:"font-bold text-main",children:[b.emoji," ",l?b.zh:b.en]}),e.jsxs("span",{className:"text-muted font-mono",children:[N," · ",$,"%"]})]}),e.jsx("div",{className:"h-2.5 bg-surface-secondary rounded-full overflow-hidden border border-theme/50",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${$}%`,background:b.color}})})]},f)}),e.jsx("div",{className:`mt-1 text-xs font-bold ${p().tone}`,children:p().text}),e.jsx(me,{slot:"classroom.barometer.metric",slotProps:{lessonId:t,signals:s,total:u,health:m,lang:r}})]})]})]})})}function Io({progressHistory:t,lang:r="zh",compact:a=!1}){const o=i.useMemo(()=>({title:r==="zh"?"课程学习进度趋势":"Learning Progress Trend",badge:r==="zh"?"历史趋势":"History",subtitle:r==="zh"?"按课程追踪学习完成度与进度变化曲线":"Track lesson completion progress over time",emptyTitle:r==="zh"?"暂无学习进度记录":"No Progress Records Yet",emptyDesc:r==="zh"?"当学生被分配课程并开始学习后,进度趋势将在此展示。":"Progress trends will appear here once lessons are assigned and started.",tooltipLesson:r==="zh"?"课程":"Lesson",tooltipProgress:r==="zh"?"完成进度":"Progress",tooltipDate:r==="zh"?"分配时间":"Assigned",tooltipStatus:r==="zh"?"状态":"Status",completed:r==="zh"?"已完成":"Completed",inProgress:r==="zh"?"进行中":"In Progress",statAvg:r==="zh"?"平均进度":"Avg Progress",statCompleted:r==="zh"?"已完成":"Completed",statTotal:r==="zh"?"总课程数":"Total Lessons"}),[r]),{chartData:d,stats:n}=i.useMemo(()=>{if(!t||t.length===0)return{chartData:[],stats:{avg:0,completed:0,total:0}};const s=new Map;for(const p of t){const w=s.get(p.lesson_id);(!w||p.assigned_at>w.assigned_at)&&s.set(p.lesson_id,p)}const c=Array.from(s.values()).sort((p,w)=>p.assigned_at-w.assigned_at).map(p=>{const w=new Date(p.assigned_at),f=r==="zh"?`${w.getMonth()+1}月${w.getDate()}日`:w.toLocaleDateString("en-US",{month:"short",day:"numeric"});return{label:p.lesson_title.length>8?p.lesson_title.slice(0,8)+"…":p.lesson_title,lessonTitle:p.lesson_title,progressPercent:Math.max(0,Math.min(100,Math.round(p.progress_percent))),completed:p.completed===1,dateLabel:f,timestamp:p.assigned_at}}),u=c.reduce((p,w)=>p+w.progressPercent,0),m=c.filter(p=>p.completed).length;return{chartData:c,stats:{avg:c.length>0?Math.round(u/c.length):0,completed:m,total:c.length}}},[t,r]);if(d.length===0)return e.jsxs("div",{className:"bg-surface rounded-xl border border-border/80 p-3.5 shadow-3xs","data-testid":"learning-progress-trend-empty",children:[e.jsxs("div",{className:"flex items-center gap-1.5 mb-2",children:[e.jsx(Me,{size:15,className:"text-primary-theme"}),e.jsx("h4",{className:"text-xs font-bold text-foreground",children:o.title})]}),e.jsxs("div",{className:"rounded-xl border border-dashed border-border/60 p-4 text-center",children:[e.jsx(fs,{size:24,className:"mx-auto text-muted mb-1.5"}),e.jsx("p",{className:"text-[11px] font-semibold text-muted",children:o.emptyTitle}),e.jsx("p",{className:"text-[10px] text-muted mt-0.5",children:o.emptyDesc})]})]});const l=a?180:220;return e.jsxs("div",{className:"bg-surface rounded-xl border border-border/80 p-3.5 shadow-3xs","data-testid":"learning-progress-trend-chart",children:[e.jsx("div",{className:"flex items-center justify-between mb-2",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(Me,{size:15,className:"text-primary-theme"}),e.jsx("h4",{className:"text-xs font-bold text-foreground",children:o.title}),e.jsx("span",{className:"text-[10px] font-mono font-bold px-1.5 py-0.5 rounded-md bg-primary-theme/10 text-primary-theme border border-primary-theme/20",children:o.badge})]})}),e.jsxs("div",{className:"grid grid-cols-3 gap-2 mb-2.5",children:[e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statAvg}),e.jsxs("div",{className:"text-sm font-extrabold text-foreground font-mono",children:[n.avg,"%"]})]}),e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statCompleted}),e.jsxs("div",{className:"text-sm font-extrabold text-emerald-600 dark:text-emerald-400 font-mono",children:[n.completed,"/",n.total]})]}),e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statTotal}),e.jsx("div",{className:"text-sm font-extrabold text-foreground font-mono",children:n.total})]})]}),e.jsx("div",{style:{width:"100%",height:l},children:e.jsx(Nn,{width:"100%",height:"100%",children:e.jsxs(No,{data:d,margin:{top:10,right:10,left:-25,bottom:5},children:[e.jsxs("defs",{children:[e.jsxs("linearGradient",{id:"progressGradientFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"5%",stopColor:"#6366f1",stopOpacity:.3}),e.jsx("stop",{offset:"95%",stopColor:"#6366f1",stopOpacity:.02})]}),e.jsxs("linearGradient",{id:"progressStrokeGrad",x1:"0",y1:"0",x2:"1",y2:"0",children:[e.jsx("stop",{offset:"0%",stopColor:"#6366f1"}),e.jsx("stop",{offset:"50%",stopColor:"#818cf8"}),e.jsx("stop",{offset:"100%",stopColor:"#a78bfa"})]})]}),e.jsx(vo,{strokeDasharray:"3 3",vertical:!1,stroke:"#e2e8f0",opacity:.5}),e.jsx(wo,{dataKey:"label",tick:{fontSize:12,fill:"#64748b",fontWeight:600},axisLine:{stroke:"#e2e8f0"},tickLine:!1,interval:d.length>8?Math.floor(d.length/6):0}),e.jsx(ko,{domain:[0,100],ticks:[0,25,50,75,100],tick:{fontSize:12,fill:"#64748b",fontWeight:600},axisLine:{stroke:"#e2e8f0"},tickLine:!1,tickFormatter:s=>`${s}%`}),e.jsx(zo,{y:100,stroke:"#10b981",strokeDasharray:"4 4",strokeWidth:1,label:{value:r==="zh"?"完成 100%":"100% Complete",fill:"#059669",fontSize:12,fontWeight:700,position:"insideTopRight"}}),e.jsx(So,{content:({active:s,payload:h})=>{if(!s||!h||!h.length)return null;const c=h[0].payload;return e.jsxs("div",{className:"bg-slate-900 text-white rounded-xl p-2.5 shadow-xl border border-slate-700/80 text-xs min-w-[180px] z-50",children:[e.jsxs("div",{className:"flex items-center gap-1.5 pb-1.5 border-b border-slate-800",children:[e.jsx(It,{size:12,className:"text-indigo-300"}),e.jsx("span",{className:"font-bold text-indigo-300 truncate max-w-[150px]",children:c.lessonTitle})]}),e.jsxs("div",{className:"pt-1.5 space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipProgress,":"]}),e.jsxs("span",{className:"font-extrabold text-emerald-400 font-mono",children:[c.progressPercent,"%"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipDate,":"]}),e.jsx("span",{className:"text-slate-200 font-mono text-[11px]",children:c.dateLabel})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipStatus,":"]}),e.jsxs("span",{className:`flex items-center gap-1 font-semibold ${c.completed?"text-emerald-400":"text-amber-400"}`,children:[e.jsx(Ae,{size:11}),c.completed?o.completed:o.inProgress]})]})]})]})}}),e.jsx(Co,{type:"monotone",dataKey:"progressPercent",name:r==="zh"?"完成进度":"Progress",stroke:"url(#progressStrokeGrad)",strokeWidth:2.5,fill:"url(#progressGradientFill)",dot:{r:3.5,fill:"#6366f1",stroke:"#ffffff",strokeWidth:2},activeDot:{r:6,stroke:"#a78bfa",strokeWidth:2,fill:"#ffffff"},animationDuration:600})]})})})]})}function xr({isOpen:t,onClose:r,student:a,lessonId:o,classId:d,lang:n="zh",addToast:l,onInspectSandbox:s,onCastStudentScreen:h,onAwardPoints:c,progressHistory:u}){const[m,p]=i.useState(!1),[w,f]=i.useState([]),[N,b]=i.useState("overview"),$=za(H=>H.version);i.useEffect(()=>{t&&b("overview")},[t,a?.id]),i.useEffect(()=>{if(u!==void 0)return;if(!t||!a?.id){f([]);return}let H=!0;return(async()=>{try{const te=await fetch(`/api/students/${a.id}/progress`);if(te.ok){const de=await te.json();H&&Array.isArray(de)&&f(de)}}catch{}})(),()=>{H=!1}},[t,a?.id,u,$]);const P=u!==void 0?u:w,y=a?.competencyScores,k=i.useMemo(()=>[{key:"logic",label:n==="zh"?"算法逻辑":"Logic"},{key:"engineering",label:n==="zh"?"代码工程":"Engineering"},{key:"creativity",label:n==="zh"?"创新思维":"Creativity"},{key:"collaboration",label:n==="zh"?"团队协作":"Collaboration"},{key:"focus",label:n==="zh"?"课堂专注":"Focus"}],[n]),g=i.useMemo(()=>k.map(H=>{const re=y?.[H.key],te=typeof re=="number"&&Number.isFinite(re);return{key:H.key,label:H.label,score:te?Math.max(0,Math.min(100,Math.round(re))):0,available:te}}),[y,k]),A=g.some(H=>H.available),U=g.filter(H=>!H.available).map(H=>H.label),W=i.useMemo(()=>{const H=n==="zh",re=a?.name??(n==="zh"?"该学生":"This student"),te=g.filter(B=>B.available);if(te.length===0)return H?`${re}本节暂无可用的维度数据(未参与随堂测/课件互动),无法生成掌握度评语。建议下节课关注其参与情况。`:`${re} has no competency data for this session (no quiz/courseware interaction).`;const de=Math.round(te.reduce((B,se)=>B+se.score,0)/te.length),G=te.reduce((B,se)=>se.score>B.score?se:B),C=te.reduce((B,se)=>se.score<B.score?se:B),M=g.filter(B=>!B.available).map(B=>B.label);return(H?[`本节已采集维度:${te.map(B=>`${B.label} ${B.score}`).join("、")},平均 ${de}。`,`相对优势为${G.label}(${G.score}),相对薄弱为${C.label}(${C.score})。`,M.length>0?`未采集维度:${M.join("、")}。`:""]:[`Collected: ${te.map(B=>`${B.label} ${B.score}`).join(", ")}; average ${de}.`,`Strongest ${G.label} (${G.score}), weakest ${C.label} (${C.score}).`,M.length>0?`Missing: ${M.join(", ")}.`:""]).filter(Boolean).join(" ")},[g,n,a]),T=i.useMemo(()=>{const H=n==="zh",re=g.filter(de=>de.available);if(re.length===0)return H?"数据不足,暂不生成建议":"Insufficient data";const te=re.reduce((de,G)=>de+G.score,0)/re.length;return te>=85?H?"建议进入算法创新挑战营":"Recommended for Advanced Camp":te>=70?H?"建议保持当前节奏并补强薄弱维度":"Keep pace, strengthen weak areas":H?"建议课后补充基础微练习":"Suggest remedial practice"},[g,n]),Y=i.useMemo(()=>{const H=g.filter(te=>te.available);if(H.length===0)return"—";const re=H.reduce((te,de)=>te+de.score,0)/H.length;return re>=90?"A+":re>=80?"A":re>=70?"B+":re>=60?"B":"C"},[g]),V=i.useMemo(()=>{const de=(B,se)=>{const v=-Math.PI/2+2*Math.PI/5*se;return{x:100+B*Math.cos(v),y:100+B*Math.sin(v)}},G=[1,.66,.33].map(B=>{const se=75*B;return Array.from({length:5},(_,Z)=>{const{x:ie,y:xe}=de(se,Z);return`${ie.toFixed(1)},${xe.toFixed(1)}`}).join(" ")}),C=Array.from({length:5},(B,se)=>{const{x:v,y:_}=de(75,se);return{x1:100,y1:100,x2:v,y2:_}}),M=g.map((B,se)=>{const v=75*Math.min(Math.max(B.score/100,.1),1);return de(v,se)}),I=M.map(B=>`${B.x.toFixed(1)},${B.y.toFixed(1)}`).join(" ");return{gridLevels:G,axes:C,dataPoints:M,dataPolygonString:I}},[g]);if(!t||!a)return null;const le=a.points??0,F=a.deltaPoints??4,D=a.focusPercentage,j=a.accuracyPercentage,q=a.helpCount??3,ee=a.role||a.student_number||"",R=a.group_name||"",O=a.student_number||a.id.slice(-6),L=a.timeline??[],X=async(H,re)=>{p(!0);try{c?c(a.id,H,re):await fetch(`/api/students/${a.id}/points`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({delta:H,dimension:"attribution",reason:re,classId:d,lessonId:o})}),l?.(n==="zh"?"成长积分已发放":"Points Awarded",n==="zh"?`已为学生 [${a.name}] ${H>=0?"+":""}${H} 分(${re})`:`Awarded ${H} pts to [${a.name}]`,"success")}catch(te){const de=te instanceof Error?te.message:String(te);l?.("Error",de,"error")}finally{p(!1)}},K=()=>{const H=`# 学生个人全景学情与成长档案 (${a.name})
1
+ import{r as i,j as e,R as Tt}from"./vendor-react-DHoBZpn2.js";import{T as Ks,E as me,s as va,U as ps,V as wa,W as ka,X as za,l as Ut,Y as at,Z as xt,_ as Sa,b as Ca,e as $a,y as Br,$ as Aa,O as Ea,a0 as Ta,Q as Pa,a1 as _a,a2 as Ct,a3 as Ra}from"./index-XduPa2-x.js";import{L as Ia}from"./LazyWhiteboard-CsF9GB6J.js";import{R as _e,q as ft,aZ as La,C as fs,a8 as Ma,D as yt,E as tn,U as Ee,j as Xs,aa as qt,as as Vt,ah as er,Z as ut,be as Oa,a9 as Me,X as ke,B as It,h as Ae,aA as sn,Q as bt,bf as rn,bg as Kt,bh as bs,bi as Da,a4 as Oe,bj as nn,J as gs,b7 as tr,s as an,k as ms,V as ve,bk as on,t as Js,ag as Yt,a7 as ln,bl as Fa,bm as Ba,bn as us,af as tt,an as Pt,bo as cn,bp as Ga,T as Ie,u as Ve,aC as dn,bq as Ha,br as js,bs as Wa,n as ys,bt as Ua,i as Lt,K as qa,ad as gt,ai as Qt,bu as Va,m as Ka,aU as Jt,e as xn,bv as mn,O as sr,$ as rr,g as Wt,bw as Ja,G as nr,bx as Ya,A as Ns,by as un,bz as ar,a$ as Mt,x as or,c as jt,a3 as vs,bA as hn,bB as Qa,bC as _t,aD as Gr,b2 as Za,bD as ds,L as Xa,y as Zt,_ as ir,w as pn,bE as eo,am as fn,aM as to,aG as lr,a0 as bn,bF as gn,bG as cr,bH as so,bI as jn,bJ as yn,v as ro,bK as no,bL as ao,b as Ys,av as oo,bM as io,bN as Hr,bO as Bs,S as Wr,aT as lo,bP as Ur,bQ as co,aB as xo,bR as mo,bS as uo,bT as ho,bU as po}from"./vendor-icons-DLOPlM4i.js";import{C as fo,T as bo}from"./ClassroomCountdownWidget-B5-KUVU8.js";import{a as Nn,P as go,h as jo,g as yo,A as No,C as vo,X as wo,Y as ko,b as zo,T as So,e as Co}from"./vendor-charts-skggaP9D.js";import{r as dr,f as vn,D as wn,s as kn}from"./timeline-duration-BgdJCSrW.js";import{f as $o,t as Ao}from"./teaching-modes-client-BeVaDdJ-.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";const qr=Ks;function zn({lessonId:t,lang:r,addToast:a}){const[o,d]=i.useState(!1),[n,l]=i.useState(!1),[s,h]=i.useState([]),[c,u]=i.useState(60),[m,p]=i.useState(40),[w,f]=i.useState({}),[N,b]=i.useState({}),[$,P]=i.useState({}),[y,k]=i.useState({}),[g,A]=i.useState({}),[U,W]=i.useState({}),T=r==="zh",Y=async(j=!1)=>{j?l(!0):d(!0);try{const ee=await(await fetch(`/api/lessons/${t}/eval-grades`)).json();if(Array.isArray(ee)){h(ee);const R={},O={},L={},X={};ee.forEach(K=>{K.grade?(R[K.id]=K.grade.teacher_score,O[K.id]=K.grade.teacher_comment,L[K.id]=Math.round(K.grade.teacher_weight*100),X[K.id]=Math.round(K.grade.peer_weight*100)):(R[K.id]=w[K.id]!==void 0?w[K.id]:80,O[K.id]=N[K.id]!==void 0?N[K.id]:"",L[K.id]=$[K.id]!==void 0?$[K.id]:c,X[K.id]=y[K.id]!==void 0?y[K.id]:m)}),f(K=>({...R,...K})),b(K=>({...O,...K})),P(K=>({...L,...K})),k(K=>({...X,...K}))}else throw new Error("Invalid submissions data format")}catch(q){console.error("Error fetching submissions grades:",q),a(T?"数据加载失败":"Failed to Load Data",T?"请检查网络连接或刷新页面。":"Please check your connection and try again.","warning")}finally{d(!1),l(!1)}};i.useEffect(()=>{t&&Y()},[t]),i.useEffect(()=>{const j=ps();if(!j||!t)return;const q=ee=>{(!ee?.lessonId||ee.lessonId===t)&&Y()};return j.on("assignment-submitted-toast",q),()=>{typeof j.off=="function"&&j.off("assignment-submitted-toast",q)}},[t]);const V=j=>{u(j),p(100-j),P(q=>{const ee={...q};return s.forEach(R=>{(!R.grade||R.grade.status!=="confirmed")&&(ee[R.id]=j)}),ee}),k(q=>{const ee={...q};return s.forEach(R=>{(!R.grade||R.grade.status!=="confirmed")&&(ee[R.id]=100-j)}),ee})},le=(j,q)=>{P(ee=>({...ee,[j]:q})),k(ee=>({...ee,[j]:100-q}))},F=async(j,q)=>{const ee=w[j],R=N[j]||"",O=($[j]??c)/100,L=(y[j]??m)/100;if(ee===void 0||isNaN(ee)||ee<0||ee>100){a(T?"评分无效":"Invalid Score",T?"教师评分必须在 0 到 100 之间!":"Teacher score must be between 0 and 100!","warning");return}if(q==="confirmed"){const X=T?"确认同步后,最终得分将直接同步写入宿主学期成绩库,此后该学生的作业成绩将锁定不可修改。是否确认?":"Once confirmed, the final score will be synced to the host semester reports and locked. Proceed?";if(!window.confirm(X))return}W(X=>({...X,[j]:q}));try{const K=await(await fetch("/api/commands",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({commandType:"assignment.grade",payload:{submissionId:j,teacherScore:Number(ee),teacherComment:R,teacherWeight:O,peerWeight:L,status:q}})})).json();if(K.success)a(q==="confirmed"?T?"平时成绩同步成功":"Semester Grade Synced":T?"平时成绩草稿已保存":"Grade Draft Saved",q==="confirmed"?T?`已将平时成绩 ${K.result.calculatedFinalScore} 分同步至学期报告!`:`Successfully synced grade ${K.result.calculatedFinalScore}!`:T?"成功保存了教师打分与评语草稿。":"Successfully saved score and comment draft.","success"),Y(!0);else throw new Error(K.error||"Failed to submit grade")}catch(X){a(T?"操作失败":"Operation Failed",X.message,"warning")}finally{W(X=>({...X,[j]:null}))}},D=j=>{A(q=>({...q,[j]:!q[j]}))};return o?e.jsxs("div",{className:"flex-grow flex flex-col items-center justify-center py-12 text-gray-500",children:[e.jsx(_e,{className:"animate-spin text-indigo-500 mb-2",size:32}),e.jsx("p",{className:"text-xs",children:T?"正在读取学生作业与成绩状态...":"Loading student submissions and grades..."})]}):e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 w-full relative rounded-xl overflow-hidden border border-slate-200 shadow-md bg-white p-5 text-left",children:[e.jsxs("div",{className:"flex justify-between items-center pb-4 border-b border-slate-100 mb-4 gap-3 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("h3",{className:"text-sm font-bold text-slate-800 flex items-center gap-1.5 select-none",children:[e.jsx(ft,{size:16,className:"text-indigo-655"}),T?"学生作业成绩评定与折算系统":"Student Assignment Grading & Sync"]}),e.jsxs("span",{className:"text-xs bg-indigo-50 text-indigo-750 px-2 py-0.5 rounded-full border border-indigo-100 font-bold",children:[s.length," ",T?"个提交":"submissions"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(me,{slot:"assignment.grade.toolbar.action",slotProps:{lessonId:t,submissions:s,refresh:()=>Y(!0),lang:r}}),e.jsx("button",{onClick:()=>Y(!0),disabled:n,className:"p-1.5 bg-white hover:bg-slate-55 border border-slate-200 rounded-lg text-slate-600 transition-colors flex items-center justify-center cursor-pointer shadow-4xs",title:T?"刷新数据":"Refresh",children:e.jsx(_e,{size:12,className:n?"animate-spin":""})})]})]}),e.jsxs("div",{className:"bg-slate-50 border border-slate-200 rounded-xl p-4 mb-5 shrink-0 flex flex-col md:flex-row md:items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-2.5",children:[e.jsx(La,{className:"text-indigo-500 shrink-0 mt-0.5",size:16}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs font-bold text-slate-700",children:T?"全局默认折算权重设置":"Default Grading Weights Configuration"}),e.jsx("p",{className:"text-xs text-subtle mt-0.5 font-medium",children:T?"调整权重分配,所有尚未锁定成绩的学生将自动应用此默认权重比例。":"Setting global default weights. Changes will automatically apply to non-confirmed grades."})]})]}),e.jsxs("div",{className:"flex items-center gap-4 shrink-0 bg-white px-3.5 py-2 rounded-lg border border-slate-200 shadow-3xs",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs font-bold text-slate-500",children:T?"教师评分:":"Teacher:"}),e.jsx("input",{type:"range","aria-label":T?"教师评分权重":"Teacher weight",min:"0",max:"100",step:"5",value:c,onChange:j=>V(Number(j.target.value)),className:"w-20 accent-indigo-650 cursor-pointer"}),e.jsxs("span",{className:"text-xs font-bold text-indigo-700 w-8 text-right",children:[c,"%"]})]}),e.jsx("div",{className:"h-4 w-[1px] bg-slate-200"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs font-bold text-slate-500",children:T?"学生互评:":"Peer Review:"}),e.jsxs("span",{className:"text-xs font-bold text-slate-700 w-8",children:[m,"%"]})]})]}),e.jsx(me,{slot:"assignment.grade.rubric.addon",slotProps:{lessonId:t,defaultTeacherWeight:c,defaultPeerWeight:m,onTeacherWeightChange:V,lang:r}})]}),e.jsx("div",{className:"flex-grow flex-1 overflow-y-auto space-y-4 pr-1 scrollbar-thin",children:s.length===0?e.jsxs("div",{className:"h-full flex flex-col items-center justify-center py-12 text-slate-400 gap-2",children:[e.jsx(fs,{size:32,className:"text-slate-350"}),e.jsx("p",{className:"text-xs",children:T?"本节课目前没有任何学生提交作业。":"No students have submitted assignments yet for this lesson."})]}):s.map(j=>{const q=w[j.id]!==void 0?w[j.id]:80,ee=N[j.id]||"",R=$[j.id]??c,O=y[j.id]??m,L=j.grade?.status==="confirmed",X=Math.round(q*(R/100)+j.peerAverageScore*(O/100));return e.jsxs("div",{className:`bg-white border rounded-xl shadow-3xs overflow-hidden transition-all ${L?"border-emerald-200 bg-emerald-50/5":"border-slate-200"}`,children:[e.jsxs("div",{className:"px-4 py-3 bg-slate-50/50 border-b border-slate-100 flex flex-col md:flex-row md:items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("div",{className:"w-8 h-8 rounded-full bg-indigo-50 border border-indigo-100 flex items-center justify-center text-indigo-700 font-bold text-xs select-none",children:j.studentName?.charAt(0)||"S"}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-bold text-slate-800",children:j.studentName}),e.jsxs("div",{className:"text-xs text-slate-400 font-mono mt-0.5 flex items-center gap-1.5",children:[e.jsxs("span",{children:["V",j.version]}),e.jsx("span",{children:"•"}),e.jsx("span",{children:new Date(j.updatedAt).toLocaleString()})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[L?e.jsxs("span",{className:"bg-emerald-55 text-emerald-700 text-xs font-black px-2.5 py-1 rounded-full border border-emerald-150 flex items-center gap-1 shadow-3xs select-none",children:[e.jsx(Ma,{size:12}),T?"成绩已同步":"Synced to Reports"]}):e.jsx("span",{className:"bg-amber-50 text-amber-805 text-xs font-bold px-2 py-0.5 rounded-full border border-amber-200/60 select-none",children:j.grade?T?"草稿状态":"Draft":T?"未评定":"Ungraded"}),(()=>{const K=va(j.filePath);return K?e.jsxs("a",{href:K,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-indigo-600 hover:text-indigo-850 font-medium hover:underline flex items-center gap-1 bg-white border border-slate-200 px-2 py-1 rounded-lg shadow-4xs",title:j.filePath,children:[e.jsx(yt,{size:11}),T?"查看作业":"View File",e.jsx(tn,{size:8})]}):null})()]})]}),e.jsxs("div",{className:"p-4 grid grid-cols-1 lg:grid-cols-12 gap-5",children:[e.jsxs("div",{className:"lg:col-span-5 flex flex-col gap-2.5 border-r border-slate-100 pr-0 lg:pr-5 text-left",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("span",{className:"text-xs font-bold text-slate-650 flex items-center gap-1 select-none",children:[e.jsx(Ee,{size:13,className:"text-slate-400"}),T?"学生互评详情":"Peer Review Details"]}),e.jsxs("span",{className:"text-xs font-bold text-slate-500 bg-slate-100 px-2 py-0.5 rounded-md",children:[T?"互评人数:":"Reviews:"," ",j.peerReviews.length]})]}),e.jsxs("div",{className:"bg-slate-50 border border-slate-100 rounded-xl p-3 flex items-center gap-3",children:[e.jsxs("div",{className:"bg-white border border-slate-200 w-12 h-12 rounded-lg flex flex-col items-center justify-center shrink-0 shadow-3xs",children:[e.jsx("span",{className:"text-xs text-slate-405 select-none font-bold",children:T?"均分":"Avg"}),e.jsx("span",{className:"text-sm font-extrabold text-slate-700 leading-none mt-0.5",children:j.peerAverageScore})]}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-xs text-slate-450 leading-normal font-medium",children:j.peerReviews.length>0?T?"根据同学互评分数得出的平均值。":"Average score computed from classmate evaluations.":T?"暂无同学对此作业给出评分。":"No classmate peer reviews received yet."}),j.peerReviews.length>0&&e.jsx("button",{onClick:()=>D(j.id),className:"text-xs text-indigo-650 hover:text-indigo-800 font-bold mt-1.5 flex items-center gap-0.5 cursor-pointer outline-none",children:g[j.id]?e.jsxs(e.Fragment,{children:[T?"收起互评详情":"Hide Details"," ",e.jsx(Xs,{size:12})]}):e.jsxs(e.Fragment,{children:[T?"展开互评详情":"Show Details"," ",e.jsx(qt,{size:12})]})})]})]}),g[j.id]&&j.peerReviews.length>0&&e.jsx("div",{className:"mt-2 space-y-2 border-t border-slate-100 pt-2.5 max-h-40 overflow-y-auto scrollbar-thin",children:j.peerReviews.map(K=>e.jsxs("div",{className:"bg-white border border-slate-200 rounded-lg p-2.5 text-xs text-left shadow-4xs",children:[e.jsxs("div",{className:"flex justify-between items-center font-bold text-slate-700",children:[e.jsxs("span",{className:"flex items-center gap-1 font-semibold text-slate-655",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-slate-300"}),K.reviewer_name]}),e.jsxs("span",{className:"text-indigo-650 bg-indigo-50 border border-indigo-100 rounded px-1.5 py-0.5 text-xs",children:[K.score," ",T?"分":"pts"]})]}),K.comment&&e.jsxs("p",{className:"text-xs text-slate-550 mt-1 italic pl-2.5 border-l-2 border-slate-100 font-medium",children:['"',K.comment,'"']})]},K.id))})]}),e.jsxs("div",{className:"lg:col-span-7 flex flex-col gap-3 justify-between",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-slate-650 mb-1 select-none",children:T?"教师平时分评分 (0-100)":"Teacher Score (0-100)"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{id:`teacher_score_input_${j.id}`,type:"number",min:"0",max:"100",disabled:L,value:q,onChange:K=>f(H=>({...H,[j.id]:Math.min(100,Math.max(0,Number(K.target.value)))})),className:"bg-white border border-slate-250 rounded-lg text-xs font-bold text-slate-700 px-3 py-1.5 focus:ring-1 focus:ring-indigo-500 outline-none w-20 shadow-4xs disabled:opacity-50 disabled:bg-slate-50"}),e.jsx("input",{type:"range","aria-label":T?`${j.studentName||"学生"} 的得分`:`Score for ${j.studentName||"student"}`,min:"0",max:"100",disabled:L,value:q,onChange:K=>f(H=>({...H,[j.id]:Number(K.target.value)})),className:"flex-1 accent-indigo-650 disabled:opacity-40 cursor-pointer"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center mb-1",children:[e.jsx("label",{className:"block text-xs font-bold text-slate-600 select-none",children:T?"打分占比 (教师权重)":"Teacher Score Weight"}),e.jsx("span",{className:"text-xs font-bold text-slate-400",children:T?`学生互评: ${O}%`:`Peer: ${O}%`})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{id:`teacher_weight_input_${j.id}`,type:"range",min:"0",max:"100",step:"5",disabled:L,value:R,onChange:K=>le(j.id,Number(K.target.value)),className:"flex-1 accent-indigo-650 disabled:opacity-40 cursor-pointer"}),e.jsxs("span",{className:"text-xs font-extrabold text-indigo-750 w-9 text-right",children:[R,"%"]})]})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-slate-655 mb-1 select-none",children:T?"教师评价评语":"Teacher Comments & Feedback"}),e.jsx("textarea",{id:`teacher_comment_input_${j.id}`,disabled:L,value:ee,placeholder:T?"在此输入对学生作业作品的改进指导意见及评语。":"Enter guiding feedback for this student.",onChange:K=>b(H=>({...H,[j.id]:K.target.value})),rows:2,className:"w-full bg-white border border-slate-250 rounded-lg text-xs p-2 focus:ring-1 focus:ring-indigo-500 outline-none shadow-4xs disabled:opacity-50 disabled:bg-slate-50 resize-none font-medium text-slate-700"})]}),e.jsx(me,{slot:"assignment.grade.item.addon",slotProps:{submission:j,studentId:j.student_id,lessonId:t,score:q,comment:ee,isConfirmed:L,onScoreChange:K=>f(H=>({...H,[j.id]:K})),onCommentChange:K=>b(H=>({...H,[j.id]:K})),lang:r}}),e.jsxs("div",{className:"flex flex-col md:flex-row md:items-center justify-between gap-4 pt-2 border-t border-slate-100 mt-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:`p-1.5 rounded-lg border flex items-center justify-center shrink-0 ${L?"bg-emerald-50 text-emerald-600 border-emerald-100":"bg-indigo-50 text-indigo-700 border-indigo-100"}`,children:e.jsx(Vt,{size:14})}),e.jsxs("div",{className:"text-xs text-slate-500 font-medium",children:[e.jsxs("div",{children:[T?"平时总分计算公式":"Calculated Final Grade",":"]}),e.jsxs("div",{className:"font-bold text-slate-700 mt-0.5 animate-formula",children:[R,"% × ",e.jsx("span",{className:"text-indigo-650 font-bold",children:q}),j.peerReviews.length>0&&` + ${O}% × ${j.peerAverageScore}`," = ",e.jsx("span",{className:L?"text-emerald-700 font-black text-xs":"text-indigo-700 font-black text-xs",children:L&&j.grade?.calculated_final_score||X}),T?"分":" pts"]})]})]}),!L&&e.jsxs("div",{className:"flex gap-2 justify-end shrink-0",children:[e.jsxs("button",{id:`teacher_draft_btn_${j.id}`,type:"button",disabled:!!U[j.id],onClick:()=>F(j.id,"draft"),className:"px-3 py-1.5 bg-white border border-slate-350 rounded-lg text-xs font-bold text-slate-700 hover:bg-slate-55 flex items-center gap-1.5 shadow-4xs cursor-pointer select-none disabled:opacity-50",children:[e.jsx(er,{size:12}),U[j.id]==="draft"?T?"保存中...":"Saving...":T?"暂存草稿":"Save Draft"]}),e.jsxs("button",{id:`teacher_confirm_btn_${j.id}`,type:"button",disabled:!!U[j.id],onClick:()=>F(j.id,"confirmed"),className:"px-3.5 py-1.5 bg-indigo-600 border border-indigo-700 rounded-lg text-xs font-bold text-white hover:bg-indigo-700 flex items-center gap-1.5 shadow-3xs cursor-pointer select-none disabled:opacity-50",children:[e.jsx(ut,{size:12}),U[j.id]==="confirmed"?T?"同步中...":"Syncing...":T?"确认并同步":"Confirm & Sync"]})]})]})]})]})]},j.id)})})]})}function Eo({isOpen:t,onClose:r,lessonId:a,lessonTitle:o,lang:d="zh"}){const{data:n,health:l,lastSyncedAt:s}=wa(a,{enabled:t});return t?e.jsx(ka,{lessonId:a,lessonTitle:o,data:n,lang:d,health:l,lastSyncedAt:s,onClose:r}):null}function To({lessonId:t,lessonTitle:r,lang:a}){const o=new URLSearchParams({mode:"stage_display",lessonId:t});r&&o.set("title",r),a&&o.set("lang",a);const{pathname:d,origin:n}=window.location;return`${n}${d}?${o.toString()}#/stage_display`}function Po(){const t=i.useRef(null),[r,a]=i.useState(!1),[o,d]=i.useState(!1);i.useEffect(()=>()=>{t.current=null},[]),i.useEffect(()=>{const h=setInterval(()=>{const c=t.current;c&&c.closed&&(t.current=null)},3e3);return()=>clearInterval(h)},[]);const n=i.useCallback(h=>{const c=t.current;if(c&&!c.closed){c.focus();return}let u;try{u=window.open(To(h),"openlearn-stage-display","width=1280,height=720,menubar=no,toolbar=no,location=no")}catch(m){console.warn("[StageDisplay] window.open threw:",m),u=null}if(!u){d(!0),a(!0);return}t.current=u,d(!1),a(!1),u.focus?.()},[]),l=i.useCallback(()=>a(!1),[]),s=i.useCallback(()=>d(!1),[]);return{fallbackOpen:r,blocked:o,openStageWindow:n,closeFallback:l,clearBlockedHint:s}}const Gs={CLEAR:{emoji:"💡",zh:"理解",en:"Clear",color:"#10b981"},CONFUSED:{emoji:"❓",zh:"困惑",en:"Confused",color:"#f59e0b"},TOO_FAST:{emoji:"🐇",zh:"慢一点",en:"Slow down",color:"#f43f5e"},SLOW:{emoji:"🐢",zh:"快一点",en:"Speed up",color:"#6366f1"}},_o=["CLEAR","CONFUSED","TOO_FAST","SLOW"];function Ro({lessonId:t,lang:r,signals:a,onlineCount:o=0,onClose:d,activeSegmentTitle:n}){const l=r==="zh",[s,h]=i.useState(a);i.useEffect(()=>{const f=ps();if(!f)return;const N=b=>{b?.lessonId===t&&b?.summary&&h(b.summary)};return f.on("classroom:pacing_updated",N),()=>{typeof f.off=="function"&&f.off("classroom:pacing_updated",N)}},[t]);const c=_o.map(f=>({key:f,count:Number(s[f]??0)})),u=c.reduce((f,N)=>f+N.count,0);Number(s.CONFUSED??0)+Number(s.TOO_FAST??0)+Number(s.SLOW??0);const m=u>0?Math.round(Number(s.CLEAR??0)/u*100):null,p=i.useCallback(()=>u===0?{text:l?"暂无学生反馈,等待中…":"No feedback yet",tone:"text-muted"}:Number(s.CONFUSED??0)>=Math.max(2,u*.3)?{text:l?"⚠ 较多学生困惑,建议放慢并重新讲解当前环节":"⚠ Many students are confused — slow down and re-explain",tone:"text-amber-600"}:Number(s.TOO_FAST??0)>=Math.max(2,u*.3)?{text:l?"🐇 较多学生希望放慢节奏":"🐇 Many students want you to slow down",tone:"text-rose-600"}:Number(s.SLOW??0)>=Math.max(2,u*.3)?{text:l?"🐢 较多学生希望加快节奏":"🐢 Many students want you to speed up",tone:"text-indigo-600"}:{text:l?"✓ 节奏反馈健康,可按当前节奏继续":"✓ Pace is healthy — carry on",tone:"text-emerald-700 dark:text-emerald-400"},[s,u,l]),w=c.filter(f=>f.count>0).map(f=>({name:Gs[f.key][l?"zh":"en"],value:f.count,color:Gs[f.key].color}));return e.jsx("div",{className:"fixed inset-0 z-[90] flex items-center justify-center bg-slate-900/60 backdrop-blur-2xs",onPointerDown:d,children:e.jsxs("div",{className:"bg-surface border border-theme rounded-2xl shadow-2xl w-[560px] max-w-[92vw] max-h-[86vh] overflow-y-auto p-5 font-sans text-main",onPointerDown:f=>f.stopPropagation(),children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"p-2 bg-primary-theme/10 text-primary-theme rounded-xl",children:e.jsx(Oa,{size:18})}),e.jsxs("div",{children:[e.jsxs("h2",{className:"text-sm font-black text-main flex items-center gap-1.5",children:[l?"课堂反馈情绪仪表盘":"Classroom Feedback Dashboard",e.jsxs("span",{className:"flex items-center gap-1 text-2xs font-bold text-emerald-700 dark:text-emerald-400 bg-emerald-500/10 px-1.5 py-0.5 rounded-full",children:[e.jsx(Me,{size:10})," ",l?"实时":"LIVE"]})]}),e.jsx("p",{className:"text-2xs text-muted mt-0.5",children:n?l?`当前教学环节: ${n} · 去重实时聚合`:`Active Segment: ${n} · Real-time`:l?"按环节去重 · 实时节奏反馈聚合":"Deduplicated real-time pacing feedback"})]})]}),e.jsx("button",{onClick:d,className:"p-1.5 rounded-lg hover:bg-surface-secondary text-muted cursor-pointer",title:l?"关闭":"Close",children:e.jsx(ke,{size:16})})]}),e.jsxs("div",{className:"flex flex-col md:flex-row gap-4 items-center",children:[e.jsxs("div",{className:"w-[200px] h-[200px] relative shrink-0",children:[u>0?e.jsx(Nn,{width:"100%",height:"100%",children:e.jsx(go,{children:e.jsx(jo,{data:w,dataKey:"value",nameKey:"name",innerRadius:52,outerRadius:85,paddingAngle:3,strokeWidth:0,isAnimationActive:!1,children:w.map((f,N)=>e.jsx(yo,{fill:f.color},N))})})}):e.jsx("div",{className:"w-full h-full flex items-center justify-center text-3xl opacity-30",children:"📊"}),e.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center pointer-events-none",children:[e.jsxs("span",{className:"text-2xs text-muted flex items-center gap-1",children:[e.jsx(Ee,{size:10})," ",o," ",l?"在线":"online"]}),e.jsx("span",{className:`text-xl font-black ${m===null?"text-muted":m>=60?"text-emerald-700 dark:text-emerald-400":m>=30?"text-amber-700 dark:text-amber-400":"text-rose-700 dark:text-rose-400"}`,children:m===null?"—":`${m}%`}),e.jsx("span",{className:"text-2xs text-muted",children:l?"理解占比":"clear ratio"})]})]}),e.jsxs("div",{className:"flex-1 w-full flex flex-col gap-2.5",children:[c.map(({key:f,count:N})=>{const b=Gs[f],$=u>0?Math.round(N/u*100):0;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between text-xs mb-0.5",children:[e.jsxs("span",{className:"font-bold text-main",children:[b.emoji," ",l?b.zh:b.en]}),e.jsxs("span",{className:"text-muted font-mono",children:[N," · ",$,"%"]})]}),e.jsx("div",{className:"h-2.5 bg-surface-secondary rounded-full overflow-hidden border border-theme/50",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${$}%`,background:b.color}})})]},f)}),e.jsx("div",{className:`mt-1 text-xs font-bold ${p().tone}`,children:p().text}),e.jsx(me,{slot:"classroom.barometer.metric",slotProps:{lessonId:t,signals:s,total:u,health:m,lang:r}})]})]})]})})}function Io({progressHistory:t,lang:r="zh",compact:a=!1}){const o=i.useMemo(()=>({title:r==="zh"?"课程学习进度趋势":"Learning Progress Trend",badge:r==="zh"?"历史趋势":"History",subtitle:r==="zh"?"按课程追踪学习完成度与进度变化曲线":"Track lesson completion progress over time",emptyTitle:r==="zh"?"暂无学习进度记录":"No Progress Records Yet",emptyDesc:r==="zh"?"当学生被分配课程并开始学习后,进度趋势将在此展示。":"Progress trends will appear here once lessons are assigned and started.",tooltipLesson:r==="zh"?"课程":"Lesson",tooltipProgress:r==="zh"?"完成进度":"Progress",tooltipDate:r==="zh"?"分配时间":"Assigned",tooltipStatus:r==="zh"?"状态":"Status",completed:r==="zh"?"已完成":"Completed",inProgress:r==="zh"?"进行中":"In Progress",statAvg:r==="zh"?"平均进度":"Avg Progress",statCompleted:r==="zh"?"已完成":"Completed",statTotal:r==="zh"?"总课程数":"Total Lessons"}),[r]),{chartData:d,stats:n}=i.useMemo(()=>{if(!t||t.length===0)return{chartData:[],stats:{avg:0,completed:0,total:0}};const s=new Map;for(const p of t){const w=s.get(p.lesson_id);(!w||p.assigned_at>w.assigned_at)&&s.set(p.lesson_id,p)}const c=Array.from(s.values()).sort((p,w)=>p.assigned_at-w.assigned_at).map(p=>{const w=new Date(p.assigned_at),f=r==="zh"?`${w.getMonth()+1}月${w.getDate()}日`:w.toLocaleDateString("en-US",{month:"short",day:"numeric"});return{label:p.lesson_title.length>8?p.lesson_title.slice(0,8)+"…":p.lesson_title,lessonTitle:p.lesson_title,progressPercent:Math.max(0,Math.min(100,Math.round(p.progress_percent))),completed:p.completed===1,dateLabel:f,timestamp:p.assigned_at}}),u=c.reduce((p,w)=>p+w.progressPercent,0),m=c.filter(p=>p.completed).length;return{chartData:c,stats:{avg:c.length>0?Math.round(u/c.length):0,completed:m,total:c.length}}},[t,r]);if(d.length===0)return e.jsxs("div",{className:"bg-surface rounded-xl border border-border/80 p-3.5 shadow-3xs","data-testid":"learning-progress-trend-empty",children:[e.jsxs("div",{className:"flex items-center gap-1.5 mb-2",children:[e.jsx(Me,{size:15,className:"text-primary-theme"}),e.jsx("h4",{className:"text-xs font-bold text-foreground",children:o.title})]}),e.jsxs("div",{className:"rounded-xl border border-dashed border-border/60 p-4 text-center",children:[e.jsx(fs,{size:24,className:"mx-auto text-muted mb-1.5"}),e.jsx("p",{className:"text-[11px] font-semibold text-muted",children:o.emptyTitle}),e.jsx("p",{className:"text-[10px] text-muted mt-0.5",children:o.emptyDesc})]})]});const l=a?180:220;return e.jsxs("div",{className:"bg-surface rounded-xl border border-border/80 p-3.5 shadow-3xs","data-testid":"learning-progress-trend-chart",children:[e.jsx("div",{className:"flex items-center justify-between mb-2",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(Me,{size:15,className:"text-primary-theme"}),e.jsx("h4",{className:"text-xs font-bold text-foreground",children:o.title}),e.jsx("span",{className:"text-[10px] font-mono font-bold px-1.5 py-0.5 rounded-md bg-primary-theme/10 text-primary-theme border border-primary-theme/20",children:o.badge})]})}),e.jsxs("div",{className:"grid grid-cols-3 gap-2 mb-2.5",children:[e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statAvg}),e.jsxs("div",{className:"text-sm font-extrabold text-foreground font-mono",children:[n.avg,"%"]})]}),e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statCompleted}),e.jsxs("div",{className:"text-sm font-extrabold text-emerald-600 dark:text-emerald-400 font-mono",children:[n.completed,"/",n.total]})]}),e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statTotal}),e.jsx("div",{className:"text-sm font-extrabold text-foreground font-mono",children:n.total})]})]}),e.jsx("div",{style:{width:"100%",height:l},children:e.jsx(Nn,{width:"100%",height:"100%",children:e.jsxs(No,{data:d,margin:{top:10,right:10,left:-25,bottom:5},children:[e.jsxs("defs",{children:[e.jsxs("linearGradient",{id:"progressGradientFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"5%",stopColor:"#6366f1",stopOpacity:.3}),e.jsx("stop",{offset:"95%",stopColor:"#6366f1",stopOpacity:.02})]}),e.jsxs("linearGradient",{id:"progressStrokeGrad",x1:"0",y1:"0",x2:"1",y2:"0",children:[e.jsx("stop",{offset:"0%",stopColor:"#6366f1"}),e.jsx("stop",{offset:"50%",stopColor:"#818cf8"}),e.jsx("stop",{offset:"100%",stopColor:"#a78bfa"})]})]}),e.jsx(vo,{strokeDasharray:"3 3",vertical:!1,stroke:"#e2e8f0",opacity:.5}),e.jsx(wo,{dataKey:"label",tick:{fontSize:12,fill:"#64748b",fontWeight:600},axisLine:{stroke:"#e2e8f0"},tickLine:!1,interval:d.length>8?Math.floor(d.length/6):0}),e.jsx(ko,{domain:[0,100],ticks:[0,25,50,75,100],tick:{fontSize:12,fill:"#64748b",fontWeight:600},axisLine:{stroke:"#e2e8f0"},tickLine:!1,tickFormatter:s=>`${s}%`}),e.jsx(zo,{y:100,stroke:"#10b981",strokeDasharray:"4 4",strokeWidth:1,label:{value:r==="zh"?"完成 100%":"100% Complete",fill:"#059669",fontSize:12,fontWeight:700,position:"insideTopRight"}}),e.jsx(So,{content:({active:s,payload:h})=>{if(!s||!h||!h.length)return null;const c=h[0].payload;return e.jsxs("div",{className:"bg-slate-900 text-white rounded-xl p-2.5 shadow-xl border border-slate-700/80 text-xs min-w-[180px] z-50",children:[e.jsxs("div",{className:"flex items-center gap-1.5 pb-1.5 border-b border-slate-800",children:[e.jsx(It,{size:12,className:"text-indigo-300"}),e.jsx("span",{className:"font-bold text-indigo-300 truncate max-w-[150px]",children:c.lessonTitle})]}),e.jsxs("div",{className:"pt-1.5 space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipProgress,":"]}),e.jsxs("span",{className:"font-extrabold text-emerald-400 font-mono",children:[c.progressPercent,"%"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipDate,":"]}),e.jsx("span",{className:"text-slate-200 font-mono text-[11px]",children:c.dateLabel})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipStatus,":"]}),e.jsxs("span",{className:`flex items-center gap-1 font-semibold ${c.completed?"text-emerald-400":"text-amber-400"}`,children:[e.jsx(Ae,{size:11}),c.completed?o.completed:o.inProgress]})]})]})]})}}),e.jsx(Co,{type:"monotone",dataKey:"progressPercent",name:r==="zh"?"完成进度":"Progress",stroke:"url(#progressStrokeGrad)",strokeWidth:2.5,fill:"url(#progressGradientFill)",dot:{r:3.5,fill:"#6366f1",stroke:"#ffffff",strokeWidth:2},activeDot:{r:6,stroke:"#a78bfa",strokeWidth:2,fill:"#ffffff"},animationDuration:600})]})})})]})}function xr({isOpen:t,onClose:r,student:a,lessonId:o,classId:d,lang:n="zh",addToast:l,onInspectSandbox:s,onCastStudentScreen:h,onAwardPoints:c,progressHistory:u}){const[m,p]=i.useState(!1),[w,f]=i.useState([]),[N,b]=i.useState("overview"),$=za(H=>H.version);i.useEffect(()=>{t&&b("overview")},[t,a?.id]),i.useEffect(()=>{if(u!==void 0)return;if(!t||!a?.id){f([]);return}let H=!0;return(async()=>{try{const te=await fetch(`/api/students/${a.id}/progress`);if(te.ok){const de=await te.json();H&&Array.isArray(de)&&f(de)}}catch{}})(),()=>{H=!1}},[t,a?.id,u,$]);const P=u!==void 0?u:w,y=a?.competencyScores,k=i.useMemo(()=>[{key:"logic",label:n==="zh"?"算法逻辑":"Logic"},{key:"engineering",label:n==="zh"?"代码工程":"Engineering"},{key:"creativity",label:n==="zh"?"创新思维":"Creativity"},{key:"collaboration",label:n==="zh"?"团队协作":"Collaboration"},{key:"focus",label:n==="zh"?"课堂专注":"Focus"}],[n]),g=i.useMemo(()=>k.map(H=>{const re=y?.[H.key],te=typeof re=="number"&&Number.isFinite(re);return{key:H.key,label:H.label,score:te?Math.max(0,Math.min(100,Math.round(re))):0,available:te}}),[y,k]),A=g.some(H=>H.available),U=g.filter(H=>!H.available).map(H=>H.label),W=i.useMemo(()=>{const H=n==="zh",re=a?.name??(n==="zh"?"该学生":"This student"),te=g.filter(B=>B.available);if(te.length===0)return H?`${re}本节暂无可用的维度数据(未参与随堂测/课件互动),无法生成掌握度评语。建议下节课关注其参与情况。`:`${re} has no competency data for this session (no quiz/courseware interaction).`;const de=Math.round(te.reduce((B,se)=>B+se.score,0)/te.length),G=te.reduce((B,se)=>se.score>B.score?se:B),C=te.reduce((B,se)=>se.score<B.score?se:B),M=g.filter(B=>!B.available).map(B=>B.label);return(H?[`本节已采集维度:${te.map(B=>`${B.label} ${B.score}`).join("、")},平均 ${de}。`,`相对优势为${G.label}(${G.score}),相对薄弱为${C.label}(${C.score})。`,M.length>0?`未采集维度:${M.join("、")}。`:""]:[`Collected: ${te.map(B=>`${B.label} ${B.score}`).join(", ")}; average ${de}.`,`Strongest ${G.label} (${G.score}), weakest ${C.label} (${C.score}).`,M.length>0?`Missing: ${M.join(", ")}.`:""]).filter(Boolean).join(" ")},[g,n,a]),T=i.useMemo(()=>{const H=n==="zh",re=g.filter(de=>de.available);if(re.length===0)return H?"数据不足,暂不生成建议":"Insufficient data";const te=re.reduce((de,G)=>de+G.score,0)/re.length;return te>=85?H?"建议进入算法创新挑战营":"Recommended for Advanced Camp":te>=70?H?"建议保持当前节奏并补强薄弱维度":"Keep pace, strengthen weak areas":H?"建议课后补充基础微练习":"Suggest remedial practice"},[g,n]),Y=i.useMemo(()=>{const H=g.filter(te=>te.available);if(H.length===0)return"—";const re=H.reduce((te,de)=>te+de.score,0)/H.length;return re>=90?"A+":re>=80?"A":re>=70?"B+":re>=60?"B":"C"},[g]),V=i.useMemo(()=>{const de=(B,se)=>{const v=-Math.PI/2+2*Math.PI/5*se;return{x:100+B*Math.cos(v),y:100+B*Math.sin(v)}},G=[1,.66,.33].map(B=>{const se=75*B;return Array.from({length:5},(_,Z)=>{const{x:ie,y:xe}=de(se,Z);return`${ie.toFixed(1)},${xe.toFixed(1)}`}).join(" ")}),C=Array.from({length:5},(B,se)=>{const{x:v,y:_}=de(75,se);return{x1:100,y1:100,x2:v,y2:_}}),M=g.map((B,se)=>{const v=75*Math.min(Math.max(B.score/100,.1),1);return de(v,se)}),I=M.map(B=>`${B.x.toFixed(1)},${B.y.toFixed(1)}`).join(" ");return{gridLevels:G,axes:C,dataPoints:M,dataPolygonString:I}},[g]);if(!t||!a)return null;const le=a.points??0,F=a.deltaPoints??4,D=a.focusPercentage,j=a.accuracyPercentage,q=a.helpCount??3,ee=a.role||a.student_number||"",R=a.group_name||"",O=a.student_number||a.id.slice(-6),L=a.timeline??[],X=async(H,re)=>{p(!0);try{c?c(a.id,H,re):await fetch(`/api/students/${a.id}/points`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({delta:H,dimension:"attribution",reason:re,classId:d,lessonId:o})}),l?.(n==="zh"?"成长积分已发放":"Points Awarded",n==="zh"?`已为学生 [${a.name}] ${H>=0?"+":""}${H} 分(${re})`:`Awarded ${H} pts to [${a.name}]`,"success")}catch(te){const de=te instanceof Error?te.message:String(te);l?.("Error",de,"error")}finally{p(!1)}},K=()=>{const H=`# 学生个人全景学情与成长档案 (${a.name})
2
2
  - **学生姓名**: ${a.name}
3
3
  - **学号**: ${O}
4
4
  - **所属班级**: ${a.className||d||"默认班级"}