@tinyweb_dev/oe-exam-sdk 0.1.16 → 0.1.18

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.
@@ -81,6 +81,22 @@ export interface ResultReviewAnswer {
81
81
  explanation?: string;
82
82
  teacherScore?: number | null;
83
83
  teacherFeedback?: string | null;
84
+ writingAssessment?: WritingAssessment | null;
85
+ }
86
+ export interface WritingCriterion {
87
+ code: string;
88
+ label: string;
89
+ band: number;
90
+ evidence: string;
91
+ }
92
+ export interface WritingAssessment {
93
+ criteria: WritingCriterion[];
94
+ overallBand: number;
95
+ feedback: {
96
+ en: string;
97
+ vi: string;
98
+ };
99
+ taskType: string;
84
100
  }
85
101
  export interface ResultReviewDetail {
86
102
  id: string;
@@ -1,3 +1,4 @@
1
+ import type { WritingAssessment } from '../../../../../api/result-review.types';
1
2
  interface MoversWritingRendererProps {
2
3
  partNumber: number;
3
4
  partName?: string;
@@ -13,6 +14,7 @@ interface MoversWritingRendererProps {
13
14
  teacherScore?: number | null;
14
15
  maxScore?: number;
15
16
  teacherFeedback?: string | null;
17
+ writingAssessment?: WritingAssessment | null;
16
18
  }
17
- export declare function MoversWritingRenderer({ partNumber, partName, instruction, prompt, requirements, minWords, maxWords, answer, onAnswerChange, isReviewMode, guideImages, teacherScore, maxScore, teacherFeedback, }: MoversWritingRendererProps): import("react").JSX.Element;
19
+ export declare function MoversWritingRenderer({ partNumber, partName, instruction, prompt, requirements, minWords, maxWords, answer, onAnswerChange, isReviewMode, guideImages, teacherScore, maxScore, teacherFeedback, writingAssessment, }: MoversWritingRendererProps): import("react").JSX.Element;
18
20
  export {};
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as r,Fragment as t}from"react/jsx-runtime";import{useMemo as s}from"react";import{ResolvedImage as a}from"../../../../../components/common/ResolvedImage";import l from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import i from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import{HtmlOrText as d}from"../../../../../shared/lib/html-content";export function MoversWritingRenderer({partNumber:n,partName:m,instruction:o,prompt:c,requirements:x,minWords:p,maxWords:b,answer:h,onAnswerChange:g,isReviewMode:u=!1,guideImages:f,teacherScore:N,maxScore:v,teacherFeedback:w}){const y=s(()=>h&&h.trim()?h.trim().split(/\s+/).filter(Boolean).length:0,[h]);return r("div",{className:"flex flex-col h-full gap-4 sm:gap-6 overflow-y-auto custom-scrollbar relative",children:[r("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-4",children:[e(l,{partNumber:n,questionCount:1,partName:m,isReviewMode:u}),o&&e(i,{instruction:o,isReviewMode:u})]}),e("div",{className:"flex flex-col gap-4 p-3 sm:px-6 sm:pt-0 sticky top-0 z-20 bg-white/95 backdrop-blur pb-2 shadow-sm border-b border-gray-100",children:r("div",{className:"flex flex-col gap-4",children:[e("div",{className:"rounded-2xl border border-slate-200 bg-white p-5 shadow-sm",children:r("div",{className:"flex flex-col gap-4 text-base leading-relaxed text-gray-800",children:[r("div",{className:"space-y-3",children:[e("p",{className:"text-lg font-semibold text-slate-900",children:"Writing task"}),e(d,{value:c,className:"text-base leading-relaxed text-gray-800"})]}),x&&x.length>0&&r("div",{className:"rounded-xl bg-slate-50 p-4",children:[e("p",{className:"text-sm font-bold uppercase tracking-wide text-slate-700",children:"Include"}),e("ul",{className:"mt-3 space-y-2",children:x.map((t,s)=>r("li",{className:"flex items-start gap-2 text-sm text-slate-700",children:[e("span",{className:"mt-1.5 h-2 w-2 rounded-full bg-blue-500"}),e(d,{value:t,as:"span"})]},s))})]}),(p||b)&&r("div",{className:"flex flex-wrap gap-2",children:[p&&r("div",{className:"inline-flex items-center rounded-full border border-blue-200 bg-blue-50 px-3 py-1 text-sm font-medium text-blue-700",children:["Minimum: ",p," words"]}),b&&r("div",{className:"inline-flex items-center rounded-full border border-slate-200 bg-white px-3 py-1 text-sm font-medium text-slate-600",children:["Suggested max: ",b," words"]})]})]})}),f&&f.length>0&&r("div",{className:"rounded-2xl border border-slate-200 bg-white p-4 shadow-sm",children:[r("div",{className:"mb-3 flex items-center justify-between gap-3",children:[e("p",{className:"text-sm font-semibold uppercase tracking-wide text-slate-600",children:"Story pictures"}),e("p",{className:"text-xs text-slate-400",children:"Read the sequence from left to right"})]}),e("div",{className:"grid gap-4 "+(1===f.length?"grid-cols-1":"grid-cols-1 sm:grid-cols-2"),children:f.map((t,s)=>r("div",{className:"rounded-xl border border-slate-200 bg-slate-50/80 p-2 shadow-sm",children:[e(a,{src:t,alt:`Picture ${s+1}`,className:"w-full rounded-lg bg-white object-contain "+(1===f.length?"max-h-[400px]":"aspect-[4/3]")}),e("div",{className:"pt-2 text-center text-[13px] font-medium text-slate-500",children:f.length>1?`Picture ${s+1}`:"Reference Image"})]},s))})]})]})}),r("div",{className:"flex flex-col gap-3 p-3 sm:px-6 sm:pb-6",children:[r("div",{className:"rounded-2xl border border-slate-200 bg-white shadow-sm",children:[r("div",{className:"flex items-center justify-between gap-3 border-b border-slate-100 px-5 py-3 bg-slate-50/50 rounded-t-2xl",children:[r("div",{children:[e("p",{className:"text-sm font-semibold uppercase tracking-wide text-slate-500",children:"Your answer"}),e("p",{className:"text-xs text-slate-400",children:"Write clearly and organise your ideas in order."})]}),r("div",{className:"rounded-full px-3 py-1 text-sm font-semibold "+(p&&y<p?"border border-amber-200 bg-amber-50 text-amber-700":"border border-emerald-200 bg-emerald-50 text-emerald-700"),children:[y," words"]})]}),r("div",{className:"p-4",children:[e("textarea",{id:"writing-answer",name:"writing-answer",value:h,onChange:e=>{const r=e.target.value;if(b){const e=Number(b);if((r.trim()?r.trim().split(/\s+/).filter(Boolean).length:0)>e&&r.length>=(h?.length||0))return}g(r)},disabled:u,placeholder:"Write your answer here...",className:"min-h-[340px] w-full resize-y rounded-xl border border-slate-200 bg-slate-50/50 p-4 text-base leading-8 text-gray-800 outline-none transition focus:border-blue-400 focus:bg-white focus:ring-2 focus:ring-blue-100 disabled:bg-gray-50 disabled:text-gray-700"}),r("div",{className:"mt-3 flex flex-wrap items-center justify-between gap-3 text-sm",children:[e("p",{className:"text-slate-500",children:p||b?r(t,{children:[p&&r("span",{children:["Minimum required: ",r("span",{className:"font-semibold text-slate-700",children:[p," words"]})]}),p&&b&&e("span",{className:"mx-2 text-slate-300",children:"|"}),b&&r("span",{children:["Maximum allowed: ",r("span",{className:"font-semibold text-slate-700",children:[b," words"]})]})]}):"Write a complete answer."}),r("p",{className:"font-medium "+(b&&y>=b?"text-red-500":"text-slate-500"),children:["Word count: ",y," ",b&&`/ ${b}`]})]})]})]}),u&&(null!=N?r("div",{className:"mt-1 rounded-2xl border border-green-200 bg-green-50 p-4",children:[e("div",{className:"mb-2 flex items-center gap-2",children:r("span",{className:"text-lg font-semibold text-green-700",children:["Điểm: ",N,"/",v]})}),w&&r("div",{className:"text-sm text-gray-700",children:[e("span",{className:"font-medium",children:"Nhận xét:"})," ",w]})]}):e("div",{className:"mt-1 rounded-2xl border border-amber-200 bg-amber-50 p-4",children:r("div",{className:"flex items-center gap-2",children:[e("svg",{className:"h-5 w-5 shrink-0 text-amber-500",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:e("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"})}),e("span",{className:"text-sm font-medium text-amber-700",children:"Bài viết đang chờ giáo viên chấm điểm"})]})}))]})]})}
1
+ "use client";import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useMemo as s}from"react";import{ResolvedImage as r}from"../../../../../components/common/ResolvedImage";import l from"../../../../../components/themes/cambridge-yle/CambridgeYlePartBanner";import d from"../../../../../components/themes/cambridge-yle/CambridgeYleInstructionBanner";import{HtmlOrText as i}from"../../../../../shared/lib/html-content";export function MoversWritingRenderer({partNumber:n,partName:c,instruction:m,prompt:o,requirements:x,minWords:b,maxWords:p,answer:h,onAnswerChange:g,isReviewMode:u=!1,guideImages:f,teacherScore:N,maxScore:v,teacherFeedback:w,writingAssessment:y}){const F=s(()=>h&&h.trim()?h.trim().split(/\s+/).filter(Boolean).length:0,[h]);return t("div",{className:"flex flex-col h-full gap-4 sm:gap-6 overflow-y-auto custom-scrollbar relative",children:[t("div",{className:"flex flex-col gap-2 sm:gap-3 p-3 sm:px-6 sm:pt-4",children:[e(l,{partNumber:n,questionCount:1,partName:c,isReviewMode:u}),m&&e(d,{instruction:m,isReviewMode:u})]}),e("div",{className:"flex flex-col gap-4 p-3 sm:px-6 sm:pt-0 sticky top-0 z-20 bg-white/95 backdrop-blur pb-2 shadow-sm border-b border-gray-100",children:t("div",{className:"flex flex-col gap-4",children:[e("div",{className:"rounded-2xl border border-slate-200 bg-white p-5 shadow-sm",children:t("div",{className:"flex flex-col gap-4 text-base leading-relaxed text-gray-800",children:[t("div",{className:"space-y-3",children:[e("p",{className:"text-lg font-semibold text-slate-900",children:"Writing task"}),e(i,{value:o,className:"text-base leading-relaxed text-gray-800"})]}),x&&x.length>0&&t("div",{className:"rounded-xl bg-slate-50 p-4",children:[e("p",{className:"text-sm font-bold uppercase tracking-wide text-slate-700",children:"Include"}),e("ul",{className:"mt-3 space-y-2",children:x.map((a,s)=>t("li",{className:"flex items-start gap-2 text-sm text-slate-700",children:[e("span",{className:"mt-1.5 h-2 w-2 rounded-full bg-blue-500"}),e(i,{value:a,as:"span"})]},s))})]}),(b||p)&&t("div",{className:"flex flex-wrap gap-2",children:[b&&t("div",{className:"inline-flex items-center rounded-full border border-blue-200 bg-blue-50 px-3 py-1 text-sm font-medium text-blue-700",children:["Minimum: ",b," words"]}),p&&t("div",{className:"inline-flex items-center rounded-full border border-slate-200 bg-white px-3 py-1 text-sm font-medium text-slate-600",children:["Suggested max: ",p," words"]})]})]})}),f&&f.length>0&&t("div",{className:"rounded-2xl border border-slate-200 bg-white p-4 shadow-sm",children:[t("div",{className:"mb-3 flex items-center justify-between gap-3",children:[e("p",{className:"text-sm font-semibold uppercase tracking-wide text-slate-600",children:"Story pictures"}),e("p",{className:"text-xs text-slate-400",children:"Read the sequence from left to right"})]}),e("div",{className:"grid gap-4 "+(1===f.length?"grid-cols-1":"grid-cols-1 sm:grid-cols-2"),children:f.map((a,s)=>t("div",{className:"rounded-xl border border-slate-200 bg-slate-50/80 p-2 shadow-sm",children:[e(r,{src:a,alt:`Picture ${s+1}`,className:"w-full rounded-lg bg-white object-contain "+(1===f.length?"max-h-[400px]":"aspect-[4/3]")}),e("div",{className:"pt-2 text-center text-[13px] font-medium text-slate-500",children:f.length>1?`Picture ${s+1}`:"Reference Image"})]},s))})]})]})}),t("div",{className:"flex flex-col gap-3 p-3 sm:px-6 sm:pb-6",children:[t("div",{className:"rounded-2xl border border-slate-200 bg-white shadow-sm",children:[t("div",{className:"flex items-center justify-between gap-3 border-b border-slate-100 px-5 py-3 bg-slate-50/50 rounded-t-2xl",children:[t("div",{children:[e("p",{className:"text-sm font-semibold uppercase tracking-wide text-slate-500",children:"Your answer"}),e("p",{className:"text-xs text-slate-400",children:"Write clearly and organise your ideas in order."})]}),t("div",{className:"rounded-full px-3 py-1 text-sm font-semibold "+(b&&F<b?"border border-amber-200 bg-amber-50 text-amber-700":"border border-emerald-200 bg-emerald-50 text-emerald-700"),children:[F," words"]})]}),t("div",{className:"p-4",children:[e("textarea",{id:"writing-answer",name:"writing-answer",value:h,onChange:e=>{const t=e.target.value;if(p){const e=Number(p);if((t.trim()?t.trim().split(/\s+/).filter(Boolean).length:0)>e&&t.length>=(h?.length||0))return}g(t)},disabled:u,placeholder:"Write your answer here...",className:"min-h-[340px] w-full resize-y rounded-xl border border-slate-200 bg-slate-50/50 p-4 text-base leading-8 text-gray-800 outline-none transition focus:border-blue-400 focus:bg-white focus:ring-2 focus:ring-blue-100 disabled:bg-gray-50 disabled:text-gray-700"}),t("div",{className:"mt-3 flex flex-wrap items-center justify-between gap-3 text-sm",children:[e("p",{className:"text-slate-500",children:b||p?t(a,{children:[b&&t("span",{children:["Minimum required: ",t("span",{className:"font-semibold text-slate-700",children:[b," words"]})]}),b&&p&&e("span",{className:"mx-2 text-slate-300",children:"|"}),p&&t("span",{children:["Maximum allowed: ",t("span",{className:"font-semibold text-slate-700",children:[p," words"]})]})]}):"Write a complete answer."}),t("p",{className:"font-medium "+(p&&F>=p?"text-red-500":"text-slate-500"),children:["Word count: ",F," ",p&&`/ ${p}`]})]})]})]}),u&&t("div",{className:"space-y-3",children:[y&&y.criteria?.length>0&&t("div",{className:"rounded-2xl border border-[#00AEEF]/30 bg-gradient-to-b from-[#F4F9FF] to-white p-4 space-y-3 shadow-xs",children:[t("div",{className:"flex flex-wrap items-center justify-between gap-2 border-b border-[#00AEEF]/20 pb-2.5",children:[t("div",{className:"flex items-center gap-2",children:[e("span",{className:"flex h-6 w-6 items-center justify-center rounded-full bg-[#0054A6] text-xs font-bold text-white",children:"AI"}),t("span",{className:"font-bold text-[#0054A6] text-sm sm:text-base",children:["Đánh giá 4 tiêu chí IELTS Writing (","TASK_2"===y.taskType?"Task 2":"Task 1",")"]})]}),t("div",{className:"flex items-center gap-1.5 rounded-lg bg-[#EAF6FF] border border-[#00AEEF]/30 px-3 py-1",children:[e("span",{className:"text-xs font-semibold text-[#0054A6]",children:"Overall Band:"}),e("span",{className:"text-sm sm:text-base font-extrabold text-[#0054A6]",children:y.overallBand.toFixed(1)}),e("span",{className:"text-xs text-slate-400",children:"/ 9.0"})]})]}),e("div",{className:"grid gap-3 sm:grid-cols-2",children:y.criteria.map(a=>{const s=Math.max(0,Math.min(100,a.band/9*100)),r=a.band>=8?"bg-emerald-500":a.band>=6.5?"bg-[#00AEEF]":a.band>=5?"bg-amber-500":"bg-rose-500";return t("div",{className:"rounded-xl border border-slate-200 bg-white p-3 space-y-2 shadow-2xs",children:[t("div",{className:"flex items-center justify-between",children:[t("div",{className:"flex items-center gap-2",children:[e("span",{className:"font-bold text-[#0054A6] bg-[#EAF6FF] px-2 py-0.5 rounded border border-[#00AEEF]/20 text-xs",children:a.code}),e("span",{className:"font-semibold text-slate-800 text-xs sm:text-sm",children:a.label})]}),t("span",{className:"font-extrabold text-[#0054A6] bg-slate-100 px-2 py-0.5 rounded text-xs sm:text-sm",children:["Band ",a.band.toFixed(1)]})]}),e("div",{className:"h-2 w-full rounded-full bg-slate-100 overflow-hidden",children:e("div",{className:`h-full rounded-full transition-all duration-500 ${r}`,style:{width:`${s}%`}})}),a.evidence&&e("p",{className:"text-xs text-slate-600 leading-relaxed pt-0.5",children:a.evidence})]},a.code)})}),(y.feedback?.vi||y.feedback?.en)&&t("div",{className:"rounded-xl bg-[#F4F9FF] border border-[#00AEEF]/20 p-3 text-xs sm:text-sm text-slate-700 space-y-1.5",children:[e("span",{className:"font-bold text-[#0054A6] block",children:"Nhận xét từ giám khảo AI:"}),y.feedback.vi&&e("p",{className:"leading-relaxed",children:y.feedback.vi}),y.feedback.en&&e("p",{className:"text-slate-500 italic border-t border-[#00AEEF]/10 pt-1.5 mt-1.5",children:y.feedback.en})]})]}),null!=N?t("div",{className:"rounded-2xl border border-green-200 bg-green-50 p-4",children:[e("div",{className:"mb-2 flex items-center gap-2",children:t("span",{className:"text-lg font-semibold text-green-700",children:["Điểm: ",N,"/",v]})}),w&&t("div",{className:"text-sm text-gray-700",children:[e("span",{className:"font-medium",children:"Nhận xét:"})," ",w]})]}):y?null:e("div",{className:"rounded-2xl border border-amber-200 bg-amber-50 p-4",children:t("div",{className:"flex items-center gap-2",children:[e("svg",{className:"h-5 w-5 shrink-0 text-amber-500",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:e("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"})}),e("span",{className:"text-sm font-medium text-amber-700",children:"Bài viết đang chờ giáo viên chấm điểm"})]})})]})]})]})}
@@ -1 +1 @@
1
- "use client";import{jsx as e}from"react/jsx-runtime";import{MoversAnswerTheQuestionRenderer as n,MoversFillWordHintRenderer as t,MoversGridFillRenderer as r,MoversLabelThePictureRenderer as s,MoversMatchByWritingAnswerRenderer as o,MoversPictureChooseRenderer as i,MoversPictureFillBlankChooseRenderer as a,MoversReadingPassageRenderer as u,MoversTrueFalseRenderer as c,MoversWordFillParagraphRenderer as m,MoversWordFillStructuredFormRenderer as p,MoversWordOrderingRenderer as l,MoversWriteSentencesRenderer as w,MoversWritingRenderer as g}from"../../../components/exams/take/components/question-renderers";import{transformAnswerTheQuestion as d,transformFillWordHint as C,transformGridFill as R,transformLabelPicture as A,transformMatchByWritingAnswer as N,transformPictureChoose as _,transformPictureFillBlankChoose as M,transformReadingPassage as q,transformTrueFalse as T,transformWordFillParagraph as I,transformWordFillStructuredForm as U,transformWordOrdering as E,transformWriteSentences as h,transformWriteShortLetter as b}from"../../../components/exams/take/utils/question-transformers";const O=()=>{};export function renderMoversReviewBody(S){const{part:v,answers:L,isCorrectMap:x,correctAnswerTextMap:W,correctOptionIdMap:F,cellAnswersMap:D,essayGradingMap:f,rawCorrectAnswerMap:k}=S,{partNo:B,questionType:H,questions:P}=v,Q=P.length,G=P;switch(H){case"WRITE_A_SHORT_LETTER":{const n=G[0];if(!n)return null;const t=b(n),r=L[n.id]||"",s=f[n.id];return e(g,{partNumber:B,partName:v.name,prompt:t.prompt,requirements:t.requirements,minWords:t.minWords,maxWords:t.maxWords,answer:r,onAnswerChange:O,isReviewMode:!0,teacherScore:s?.score,maxScore:s?.maxScore,teacherFeedback:s?.teacherFeedback})}case"LOOK_PICTURE_CHOOSE_CORRECT_ANSWER":{const n=_(G),t=n.subQuestions.map(e=>({...e,correctOptionId:F[e.id]}));return e(i,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,subQuestions:t,answers:L,onAnswerChange:O,isReviewMode:!0})}case"LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER":{const n=M(G),t=n.subQuestions.map(e=>({...e,correctOptionId:F[e.id]}));return e(a,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,subQuestions:t,answers:L,onAnswerChange:O,isReviewMode:!0})}case"READ_PASSAGE_AND_ANSWER_QUESTIONS":{const n=q(G);return e(u,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:n.questions.length,passageTitle:n.passageTitle,passage:n.passage,passageImageUrl:n.passageImageUrl,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0,correctOptionIdMap:F})}case"LABEL_THE_PICTURE":{const n=A(G),t=n.labels.map(e=>({...e,correctAnswer:e.isPreFilled?e.correctAnswer:W[e.id]||e.correctAnswer}));return e(s,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:n.labels.length,imageUrl:n.imageUrl,wordBank:n.wordBank,labels:t,answers:L,onAnswerChange:O,isReviewMode:!0})}case"LOOK_PICTURE_FILL_WORD_HINT":{const n=C(G),r=n.subQuestions.map(e=>({...e,correctAnswer:W[e.id]}));return e(t,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,hintLetters:n.hintLetters,subQuestions:r,answers:L,onAnswerChange:O,isReviewMode:!0})}case"FILL_MISSING_WORDS_IN_GRID":{const n=R(G),t=P[0]?.id,s=t?D[t]:null,o=s?.cells||{},i=s?.caseSensitive??!1,a=t?L[t]:null,u=a&&"object"==typeof a&&null!==a&&"answers"in a?a.answers??{}:{};return e(r,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,grid:n.grid,rows:n.rows,columns:n.columns,cellAnswers:o,answers:u,onAnswerChange:O,isReviewMode:!0,caseSensitive:i,disabledCells:n.disabledCells})}case"ANSWER_THE_QUESTION":{const t=d(G);return e(n,{partNumber:B,partName:v.name,instruction:v.instructions||t.instruction,questionCount:Q,imageUrl:t.imageUrl,audioUrl:v.audioUrl,title:t.title,groupContent:t.groupContent,questions:t.questions,answers:L,onAnswerChange:O,isReviewMode:!0,correctAnswerTextMap:W})}case"TRUE_FALSE":{const n=T(G);return e(c,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,imageUrl:n.imageUrl,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0,correctAnswerTextMap:W})}case"MATCH_BY_WRITING_ANSWER":{const n=N(G);return e(o,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,audioUrl:v.audioUrl,options:n.options,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0,viewMode:n.viewMode,groupImageUrl:n.groupImageUrl,correctAnswerTextMap:W,isCorrectMap:x})}case"WORD_ORDERING":{const n=E(G);return e(l,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0,rawCorrectAnswerMap:k,isCorrectMap:x})}case"WORD_FILL_PARAGRAPH":{const n=I(G),t=n.wordBank.filter(e=>e.isExample).length,r=n.paragraph.match(/\{\d+\}/g),s=r?r.length:0,o=Math.max(1,s-t);let i=v.instructions||n.instruction;return i=i.replace(/\{FROM\}/gi,"1").replace(/\{TO\}/gi,String(o)),e(m,{partNumber:B,partName:v.name,questionCount:Q,instruction:i,questionId:n.questionId,paragraph:n.paragraph,title:n.title,imageUrl:n.imageUrl,wordBank:n.wordBank,viewMode:n.viewMode,answers:L,onAnswerChange:O,exampleAnswer:n.exampleAnswer,emailFrom:n.emailFrom,emailTo:n.emailTo,isReviewMode:!0,correctAnswerTextMap:W})}case"WRITE_SENTENCES":{const n=h(G);return e(w,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,imageUrl:n.imageUrl,title:n.title,groupContent:n.groupContent,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0})}case"WORD_FILL_STRUCTURED_FORM":{const n=U(G);return e(p,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,audioUrl:n.audioUrl||v.audioUrl,groupTitle:n.groupTitle,groupContent:n.groupContent,groupImageUrl:n.groupImageUrl,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0})}default:return null}}
1
+ "use client";import{jsx as e}from"react/jsx-runtime";import{MoversAnswerTheQuestionRenderer as n,MoversFillWordHintRenderer as t,MoversGridFillRenderer as s,MoversLabelThePictureRenderer as r,MoversMatchByWritingAnswerRenderer as o,MoversPictureChooseRenderer as i,MoversPictureFillBlankChooseRenderer as a,MoversReadingPassageRenderer as u,MoversTrueFalseRenderer as c,MoversWordFillParagraphRenderer as m,MoversWordFillStructuredFormRenderer as p,MoversWordOrderingRenderer as l,MoversWriteSentencesRenderer as w,MoversWritingRenderer as g}from"../../../components/exams/take/components/question-renderers";import{transformAnswerTheQuestion as d,transformFillWordHint as C,transformGridFill as A,transformLabelPicture as R,transformMatchByWritingAnswer as N,transformPictureChoose as _,transformPictureFillBlankChoose as M,transformReadingPassage as q,transformTrueFalse as T,transformWordFillParagraph as I,transformWordFillStructuredForm as U,transformWordOrdering as E,transformWriteSentences as h,transformWriteShortLetter as b}from"../../../components/exams/take/utils/question-transformers";const O=()=>{};export function renderMoversReviewBody(S){const{part:v,answers:L,isCorrectMap:x,correctAnswerTextMap:W,correctOptionIdMap:F,cellAnswersMap:D,essayGradingMap:f,rawCorrectAnswerMap:k}=S,{partNo:B,questionType:H,questions:P}=v,Q=P.length,G=P;switch(H){case"WRITE_A_SHORT_LETTER":{const n=G[0];if(!n)return null;const t=b(n),s=L[n.id]||"",r=f[n.id];return e(g,{partNumber:B,partName:v.name,prompt:t.prompt,requirements:t.requirements,minWords:t.minWords,maxWords:t.maxWords,answer:s,onAnswerChange:O,isReviewMode:!0,teacherScore:r?.score,maxScore:r?.maxScore,teacherFeedback:r?.teacherFeedback,writingAssessment:r?.writingAssessment})}case"LOOK_PICTURE_CHOOSE_CORRECT_ANSWER":{const n=_(G),t=n.subQuestions.map(e=>({...e,correctOptionId:F[e.id]}));return e(i,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,subQuestions:t,answers:L,onAnswerChange:O,isReviewMode:!0})}case"LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER":{const n=M(G),t=n.subQuestions.map(e=>({...e,correctOptionId:F[e.id]}));return e(a,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,subQuestions:t,answers:L,onAnswerChange:O,isReviewMode:!0})}case"READ_PASSAGE_AND_ANSWER_QUESTIONS":{const n=q(G);return e(u,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:n.questions.length,passageTitle:n.passageTitle,passage:n.passage,passageImageUrl:n.passageImageUrl,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0,correctOptionIdMap:F})}case"LABEL_THE_PICTURE":{const n=R(G),t=n.labels.map(e=>({...e,correctAnswer:e.isPreFilled?e.correctAnswer:W[e.id]||e.correctAnswer}));return e(r,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:n.labels.length,imageUrl:n.imageUrl,wordBank:n.wordBank,labels:t,answers:L,onAnswerChange:O,isReviewMode:!0})}case"LOOK_PICTURE_FILL_WORD_HINT":{const n=C(G),s=n.subQuestions.map(e=>({...e,correctAnswer:W[e.id]}));return e(t,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,hintLetters:n.hintLetters,subQuestions:s,answers:L,onAnswerChange:O,isReviewMode:!0})}case"FILL_MISSING_WORDS_IN_GRID":{const n=A(G),t=P[0]?.id,r=t?D[t]:null,o=r?.cells||{},i=r?.caseSensitive??!1,a=t?L[t]:null,u=a&&"object"==typeof a&&null!==a&&"answers"in a?a.answers??{}:{};return e(s,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,grid:n.grid,rows:n.rows,columns:n.columns,cellAnswers:o,answers:u,onAnswerChange:O,isReviewMode:!0,caseSensitive:i,disabledCells:n.disabledCells})}case"ANSWER_THE_QUESTION":{const t=d(G);return e(n,{partNumber:B,partName:v.name,instruction:v.instructions||t.instruction,questionCount:Q,imageUrl:t.imageUrl,audioUrl:v.audioUrl,title:t.title,groupContent:t.groupContent,questions:t.questions,answers:L,onAnswerChange:O,isReviewMode:!0,correctAnswerTextMap:W})}case"TRUE_FALSE":{const n=T(G);return e(c,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,imageUrl:n.imageUrl,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0,correctAnswerTextMap:W})}case"MATCH_BY_WRITING_ANSWER":{const n=N(G);return e(o,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,audioUrl:v.audioUrl,options:n.options,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0,viewMode:n.viewMode,groupImageUrl:n.groupImageUrl,correctAnswerTextMap:W,isCorrectMap:x})}case"WORD_ORDERING":{const n=E(G);return e(l,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0,rawCorrectAnswerMap:k,isCorrectMap:x})}case"WORD_FILL_PARAGRAPH":{const n=I(G),t=n.wordBank.filter(e=>e.isExample).length,s=n.paragraph.match(/\{\d+\}/g),r=s?s.length:0,o=Math.max(1,r-t);let i=v.instructions||n.instruction;return i=i.replace(/\{FROM\}/gi,"1").replace(/\{TO\}/gi,String(o)),e(m,{partNumber:B,partName:v.name,questionCount:Q,instruction:i,questionId:n.questionId,paragraph:n.paragraph,title:n.title,imageUrl:n.imageUrl,wordBank:n.wordBank,viewMode:n.viewMode,answers:L,onAnswerChange:O,exampleAnswer:n.exampleAnswer,emailFrom:n.emailFrom,emailTo:n.emailTo,isReviewMode:!0,correctAnswerTextMap:W})}case"WRITE_SENTENCES":{const n=h(G);return e(w,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,imageUrl:n.imageUrl,title:n.title,groupContent:n.groupContent,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0})}case"WORD_FILL_STRUCTURED_FORM":{const n=U(G);return e(p,{partNumber:B,partName:v.name,instruction:v.instructions||n.instruction,questionCount:Q,audioUrl:n.audioUrl||v.audioUrl,groupTitle:n.groupTitle,groupContent:n.groupContent,groupImageUrl:n.groupImageUrl,questions:n.questions,answers:L,onAnswerChange:O,isReviewMode:!0})}default:return null}}
@@ -1 +1 @@
1
- const e=new Set(["READ_PASSAGE_AND_ANSWER_QUESTIONS","LOOK_PICTURE_FILL_WORD_HINT","LABEL_THE_PICTURE","READ_AND_COLOR_OBJECTS","IMAGE_OBJECT_MATCHING"]);export function transformResultAnswersForReview(e,s=[]){const o=function(e){const r=new Map;return e.forEach(e=>{const t=[e.partId??"unknown",e.questionGroup?.id??"none",e.questionType].join(":");r.set(t,[...r.get(t)??[],e])}),r}(e),a={parts:[],studentAnswers:{},correctAnswersMap:new Map,isCorrectMap:{},correctAnswerTextMap:{},correctOptionIdMap:{},cellAnswersMap:{},essayGradingMap:{},partScoresMap:{},rawCorrectAnswerMap:{},rawStudentAnswerMap:{},questionScoreMap:{}},c=[];for(const e of o.values()){e.sort((e,r)=>e.questionNumber-r.questionNumber);const o=e[0];if(!o)continue;const u=s.find(e=>String(e.id)===String(o.partId)),p=r(u,o.questionNumber),A=i(u?.name)??o.partNo??0;a.parts.push({partId:o.partId,partNo:A,questionType:o.questionType,name:u?.name,instructions:p?.name||p?.instructions||u?.instructions,audioUrl:u?.audioUrl,questions:e.map(t)});const _=e.filter(e=>!e.isExample);c.push({score:_.reduce((e,r)=>e+(r.score??0),0),maxScore:_.reduce((e,r)=>e+r.maxScore,0),correctCount:_.filter(e=>!0===e.isCorrect).length,totalCount:_.length}),e.forEach(e=>n(a,e))}const u=a.parts.map((e,r)=>r).sort((e,r)=>{const t=a.parts[e],n=a.parts[r];return t.partNo-n.partNo||(t.questions[0]?.question_number??0)-(n.questions[0]?.question_number??0)});return a.parts=u.map(e=>a.parts[e]),u.forEach((e,r)=>{a.partScoresMap[r]=c[e]}),a}export const transformDetailedResultForReview=transformResultAnswersForReview;function r(e,r){const t=r-1;return e?.sections?.find(e=>null!=e.startIndex&&null!=e.endIndex&&t>=e.startIndex&&t<=e.endIndex)}function t(e){const r=o(e.questionContent);return{id:e.questionId,content:{...r,_correctAnswer:e.correctAnswer},correct_answer:e.correctAnswer,total_points:String(e.maxScore),question_type:e.questionType,is_example:e.isExample??!1,explanation:e.explanation??"",difficult_level:"MEDIUM",question_skill_type:"",exam_id:"",part_id:e.partId??"",part_no:e.partNo??0,question_number:e.questionNumber,questionGroup:e.questionGroup??null,score:e.score}}function n(r,t){const n=function(e,r,t){if(null==t)return;const n=o(t);if("CHOOSE_THE_CORRECT_ANSWER"===r||"CHOOSE_CORRECT_ADJECTIVE"===r){const r=s(e,n.answer);return r.length>1?r:r[0]}if("READ_PASSAGE_AND_ANSWER_QUESTIONS"===r&&a(n.subAnswers))return Object.fromEntries(Object.entries(n.subAnswers).map(([e,r])=>[e,"number"==typeof r?`${e}-opt-${r}`:r]));if("LABEL_THE_PICTURE"===r)return n.answers??t;if("LOOK_PICTURE_FILL_WORD_HINT"===r&&"string"==typeof n.answer&&n.answer.includes(","))return Object.fromEntries(n.answer.split(",").map((r,t)=>[`${e}-blank-${t}`,r.trim()]));if("WORD_FILL_PARAGRAPH"===r){if(Array.isArray(n.answers))return n.answers;if(Array.isArray(n.answer))return n.answer;if(Array.isArray(t))return t;if("string"==typeof t)return[t];return Object.keys(n).filter(e=>/^\d+$/.test(e)).sort((e,r)=>Number(e)-Number(r)).map(e=>n[e])}return"READ_AND_COLOR_OBJECTS"===r||"IMAGE_OBJECT_MATCHING"===r?n.answers??t:"WRITE_A_SHORT_LETTER"===r?"string"==typeof t?t:n.answer??"":n.answer??t}(t.questionId,t.questionType,t.studentAnswer);void 0!==n&&(e.has(t.questionType)&&a(n)?Object.assign(r.studentAnswers,n):r.studentAnswers[t.questionId]=n),r.correctAnswersMap.set(t.questionId,t.correctAnswer),r.isCorrectMap[t.questionId]=t.isCorrect,r.rawCorrectAnswerMap[t.questionId]=t.correctAnswer,r.rawStudentAnswerMap[t.questionId]=t.studentAnswer,r.questionScoreMap[t.questionId]={score:t.score,maxScore:t.maxScore},function(e,r){const t=o(r.correctAnswer),n=s(r.questionId,t.answer);n.length&&(e.correctOptionIdMap[r.questionId]=n.join(","));"READ_PASSAGE_AND_ANSWER_QUESTIONS"===r.questionType&&a(t.answers)&&Object.entries(t.answers).forEach(([r,t])=>{"number"==typeof t&&(e.correctOptionIdMap[r]=`${r}-opt-${t}`)});const i=function(e){if(Array.isArray(e.answers))return e.answers.map(String);if(a(e.answers))return Object.values(e.answers).map(String);const r=e.answer??e.correctAnswer;return null==r?[]:[String(r)]}(t);i[0]&&(e.correctAnswerTextMap[r.questionId]=i[0]);"WORD_FILL_PARAGRAPH"===r.questionType&&i.forEach((t,n)=>{e.correctAnswerTextMap[`${r.questionId}-blank-${n}`]=t});"LABEL_THE_PICTURE"===r.questionType&&a(t.labels)&&Object.entries(t.labels).forEach(([r,t])=>{e.correctAnswerTextMap[r]=String(t)});"FILL_MISSING_WORDS_IN_GRID"===r.questionType&&a(t.cells)&&(e.cellAnswersMap[r.questionId]={cells:t.cells,caseSensitive:!0===t.caseSensitive})}(r,t),"WRITE_A_SHORT_LETTER"!==t.questionType&&"WRITE_SHORT_PARAGRAPH"!==t.questionType||(r.essayGradingMap[t.questionId]={score:t.teacherScore??t.score,maxScore:t.maxScore,teacherFeedback:t.teacherFeedback??null})}function s(e,r){return(Array.isArray(r)?r:[r]).filter(e=>"number"==typeof e||"string"==typeof e).map(r=>"number"==typeof r?`${e}-opt-${r}`:r)}function o(e){return a(e)?e:{}}function a(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function i(e){const r=e?.match(/\d+/);return r?Number(r[0]):void 0}
1
+ const e=new Set(["READ_PASSAGE_AND_ANSWER_QUESTIONS","LOOK_PICTURE_FILL_WORD_HINT","LABEL_THE_PICTURE","READ_AND_COLOR_OBJECTS","IMAGE_OBJECT_MATCHING"]);export function transformResultAnswersForReview(e,s=[]){const o=function(e){const r=new Map;return e.forEach(e=>{const t=[e.partId??"unknown",e.questionGroup?.id??"none",e.questionType].join(":");r.set(t,[...r.get(t)??[],e])}),r}(e),i={parts:[],studentAnswers:{},correctAnswersMap:new Map,isCorrectMap:{},correctAnswerTextMap:{},correctOptionIdMap:{},cellAnswersMap:{},essayGradingMap:{},partScoresMap:{},rawCorrectAnswerMap:{},rawStudentAnswerMap:{},questionScoreMap:{}},u=[];for(const e of o.values()){e.sort((e,r)=>e.questionNumber-r.questionNumber);const o=e[0];if(!o)continue;const c=s.find(e=>String(e.id)===String(o.partId)),p=r(c,o.questionNumber),A=a(c?.name)??o.partNo??0;i.parts.push({partId:o.partId,partNo:A,questionType:o.questionType,name:c?.name,instructions:p?.name||p?.instructions||c?.instructions,audioUrl:c?.audioUrl,questions:e.map(t)});const _=e.filter(e=>!e.isExample);u.push({score:_.reduce((e,r)=>e+(r.score??0),0),maxScore:_.reduce((e,r)=>e+r.maxScore,0),correctCount:_.filter(e=>!0===e.isCorrect).length,totalCount:_.length}),e.forEach(e=>n(i,e))}const c=i.parts.map((e,r)=>r).sort((e,r)=>{const t=i.parts[e],n=i.parts[r];return t.partNo-n.partNo||(t.questions[0]?.question_number??0)-(n.questions[0]?.question_number??0)});return i.parts=c.map(e=>i.parts[e]),c.forEach((e,r)=>{i.partScoresMap[r]=u[e]}),i}export const transformDetailedResultForReview=transformResultAnswersForReview;function r(e,r){const t=r-1;return e?.sections?.find(e=>null!=e.startIndex&&null!=e.endIndex&&t>=e.startIndex&&t<=e.endIndex)}function t(e){const r=o(e.questionContent);return{id:e.questionId,content:{...r,_correctAnswer:e.correctAnswer},correct_answer:e.correctAnswer,total_points:String(e.maxScore),question_type:e.questionType,is_example:e.isExample??!1,explanation:e.explanation??"",difficult_level:"MEDIUM",question_skill_type:"",exam_id:"",part_id:e.partId??"",part_no:e.partNo??0,question_number:e.questionNumber,questionGroup:e.questionGroup??null,score:e.score}}function n(r,t){const n=function(e,r,t){if(null==t)return;const n=o(t);if("CHOOSE_THE_CORRECT_ANSWER"===r||"CHOOSE_CORRECT_ADJECTIVE"===r){const r=s(e,n.answer);return r.length>1?r:r[0]}if("READ_PASSAGE_AND_ANSWER_QUESTIONS"===r&&i(n.subAnswers))return Object.fromEntries(Object.entries(n.subAnswers).map(([e,r])=>[e,"number"==typeof r?`${e}-opt-${r}`:r]));if("LABEL_THE_PICTURE"===r)return n.answers??t;if("LOOK_PICTURE_FILL_WORD_HINT"===r&&"string"==typeof n.answer&&n.answer.includes(","))return Object.fromEntries(n.answer.split(",").map((r,t)=>[`${e}-blank-${t}`,r.trim()]));if("WORD_FILL_PARAGRAPH"===r){if(Array.isArray(n.answers))return n.answers;if(Array.isArray(n.answer))return n.answer;if(Array.isArray(t))return t;if("string"==typeof t)return[t];return Object.keys(n).filter(e=>/^\d+$/.test(e)).sort((e,r)=>Number(e)-Number(r)).map(e=>n[e])}return"READ_AND_COLOR_OBJECTS"===r||"IMAGE_OBJECT_MATCHING"===r?n.answers??t:"WRITE_A_SHORT_LETTER"===r?"string"==typeof t?t:n.answer??"":n.answer??t}(t.questionId,t.questionType,t.studentAnswer);void 0!==n&&(e.has(t.questionType)&&i(n)?Object.assign(r.studentAnswers,n):r.studentAnswers[t.questionId]=n),r.correctAnswersMap.set(t.questionId,t.correctAnswer),r.isCorrectMap[t.questionId]=t.isCorrect,r.rawCorrectAnswerMap[t.questionId]=t.correctAnswer,r.rawStudentAnswerMap[t.questionId]=t.studentAnswer,r.questionScoreMap[t.questionId]={score:t.score,maxScore:t.maxScore},function(e,r){const t=o(r.correctAnswer),n=s(r.questionId,t.answer);n.length&&(e.correctOptionIdMap[r.questionId]=n.join(","));"READ_PASSAGE_AND_ANSWER_QUESTIONS"===r.questionType&&i(t.answers)&&Object.entries(t.answers).forEach(([r,t])=>{"number"==typeof t&&(e.correctOptionIdMap[r]=`${r}-opt-${t}`)});const a=function(e){if(Array.isArray(e.answers))return e.answers.map(String);if(i(e.answers))return Object.values(e.answers).map(String);const r=e.answer??e.correctAnswer;return null==r?[]:[String(r)]}(t);a[0]&&(e.correctAnswerTextMap[r.questionId]=a[0]);"WORD_FILL_PARAGRAPH"===r.questionType&&a.forEach((t,n)=>{e.correctAnswerTextMap[`${r.questionId}-blank-${n}`]=t});"LABEL_THE_PICTURE"===r.questionType&&i(t.labels)&&Object.entries(t.labels).forEach(([r,t])=>{e.correctAnswerTextMap[r]=String(t)});"FILL_MISSING_WORDS_IN_GRID"===r.questionType&&i(t.cells)&&(e.cellAnswersMap[r.questionId]={cells:t.cells,caseSensitive:!0===t.caseSensitive})}(r,t),"WRITE_A_SHORT_LETTER"!==t.questionType&&"WRITE_SHORT_PARAGRAPH"!==t.questionType||(r.essayGradingMap[t.questionId]={score:t.teacherScore??t.score,maxScore:t.maxScore,teacherFeedback:t.teacherFeedback??null,writingAssessment:t.writingAssessment??null})}function s(e,r){return(Array.isArray(r)?r:[r]).filter(e=>"number"==typeof e||"string"==typeof e).map(r=>"number"==typeof r?`${e}-opt-${r}`:r)}function o(e){return i(e)?e:{}}function i(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function a(e){const r=e?.match(/\d+/);return r?Number(r[0]):void 0}
@@ -12,10 +12,12 @@ export interface ReviewQuestionPart {
12
12
  audioUrl?: string;
13
13
  questions: ExamTakingQuestion[];
14
14
  }
15
+ import type { WritingAssessment } from '../../api/result-review.types';
15
16
  export interface EssayGradingInfo {
16
17
  score: number | null;
17
18
  maxScore: number;
18
19
  teacherFeedback: string | null;
20
+ writingAssessment?: WritingAssessment | null;
19
21
  }
20
22
  export interface PartScoreInfo {
21
23
  score: number;
@@ -14,9 +14,14 @@ export declare const ENGLISH_CERT_STICKY_AUDIO_ATTR = "data-ec-sticky-audio";
14
14
  /** Nearest ancestor that actually scrolls (falls back to document scrolling element). */
15
15
  export declare function findScrollableParent(el: HTMLElement): HTMLElement;
16
16
  /**
17
- * Scroll `el` into view inside its nearest scrollable ancestor.
18
- * Prefer parent-relative scroll so nested columns (Reading split-view) work.
19
- * When a sticky Listening audio bar is present, leave room under it.
17
+ * Find all scrollable ancestors of `el` up to the root scroll container.
18
+ * Returns array ordered from innermost parent to outermost parent.
19
+ */
20
+ export declare function findAllScrollableParents(el: HTMLElement): HTMLElement[];
21
+ /**
22
+ * Scroll `el` into view across all its nested scrollable ancestors.
23
+ * Handles split-view columns (Reading Part 7 / Articles), parent document wrappers,
24
+ * main scroll area, and sticky Listening audio bar clearance.
20
25
  */
21
26
  export declare function scrollElementIntoView(el: HTMLElement, options?: {
22
27
  behavior?: ScrollBehavior;
@@ -1 +1 @@
1
- export function englishCertQuestionDomId(t){return`ec-question-${t}`}export const ENGLISH_CERT_STICKY_AUDIO_ATTR="data-ec-sticky-audio";const t=[0,50,120,250,400];function e(t){const e=window.getComputedStyle(t).overflowY;return("auto"===e||"scroll"===e||"overlay"===e)&&t.scrollHeight>t.clientHeight+1}export function findScrollableParent(t){let n=t.parentElement;for(;n;){if(e(n))return n;n=n.parentElement}return document.scrollingElement??document.documentElement}export function scrollElementIntoView(t,e){const n=e?.behavior??"smooth",o=e?.block??"start",i=findScrollableParent(t),l=function(t,e){const n=t.querySelectorAll("[data-ec-sticky-audio]");if(!n.length)return 0;let o=0;return n.forEach(n=>{if(n===e||n.contains(e))return;if(!t.contains(n))return;const i=n.getBoundingClientRect().height;i>o&&(o=i)}),o>0?o+12:0}(i,t),r=i.getBoundingClientRect(),c=t.getBoundingClientRect(),s=i.scrollTop,u=c.top-r.top+s;let a=u;if("center"===o)a=u-i.clientHeight/2+c.height/2;else if("end"===o)a=u-i.clientHeight+c.height;else if("nearest"===o){const t=s+l,e=s+i.clientHeight,n=u+c.height;if(u>=t&&n<=e)return;a=u<t?u-l:n-i.clientHeight}else a=u-l;"start"===o&&0===l&&(a=Math.max(0,a-12)),i.scrollTo({top:Math.max(0,a),behavior:n})}export function scrollToEnglishCertQuestion(e,n){if("undefined"==typeof document||!e)return;const o=englishCertQuestionDomId(e);let i=0;const l=()=>{const e=document.getElementById(o);e?scrollElementIntoView(e,n):(i+=1,i<t.length&&window.setTimeout(l,t[i]))};window.setTimeout(l,t[0])}
1
+ export function englishCertQuestionDomId(t){return`ec-question-${t}`}export const ENGLISH_CERT_STICKY_AUDIO_ATTR="data-ec-sticky-audio";const t=[0,30,80,150,300,500,800];function e(t){const e=window.getComputedStyle(t).overflowY;return("auto"===e||"scroll"===e||"overlay"===e)&&t.scrollHeight>t.clientHeight+1}export function findScrollableParent(t){let n=t.parentElement;for(;n;){if(e(n))return n;n=n.parentElement}return document.scrollingElement??document.documentElement}export function findAllScrollableParents(t){const n=[];let o=t.parentElement;for(;o;)e(o)&&n.push(o),o=o.parentElement;const l=document.scrollingElement??document.documentElement;return l&&!n.includes(l)&&l.scrollHeight>l.clientHeight+1&&n.push(l),n.length?n:[l]}export function scrollElementIntoView(t,e){const n=e?.behavior??"smooth",o=e?.block??"start",l=findAllScrollableParents(t);if(!l.length)return;l.map(e=>{const n=e.getBoundingClientRect(),l=t.getBoundingClientRect(),r=e.scrollTop,i=l.top-n.top+r,c=function(t,e){const n=t.querySelectorAll("[data-ec-sticky-audio]");if(!n.length)return 0;let o=0;return n.forEach(n=>{if(n===e||n.contains(e))return;if(!t.contains(n))return;const l=n.getBoundingClientRect().height;l>o&&(o=l)}),o>0?o+12:0}(e,t);let s=i;if("center"===o)s=i-e.clientHeight/2+l.height/2;else if("end"===o)s=i-e.clientHeight+l.height;else if("nearest"===o){const t=r+c,n=r+e.clientHeight,o=i+l.height;s=i>=t&&o<=n?r:i<t?i-c:o-e.clientHeight}else s=i-c;return"start"===o&&0===c&&(s=Math.max(0,s-12)),{parent:e,targetTop:Math.max(0,s)}}).forEach(({parent:t,targetTop:e})=>{t.scrollTo({top:e,behavior:n})})}export function scrollToEnglishCertQuestion(e,n){if("undefined"==typeof document||!e)return;const o=englishCertQuestionDomId(e),l=()=>{const t=document.getElementById(o);return!!t&&(scrollElementIntoView(t,n),!0)};if(l())return;let r=1;const i=()=>{l()||(r+=1,r<t.length&&window.setTimeout(i,t[r]))};window.setTimeout(i,t[1])}
@@ -25,6 +25,7 @@ export interface AuditUser {
25
25
  export interface Branch extends BaseEntity {
26
26
  code: string;
27
27
  name: string;
28
+ shortName?: string | null;
28
29
  address?: string | null;
29
30
  phone?: string | null;
30
31
  email?: string | null;
@@ -90,6 +91,7 @@ export interface BranchTeacher {
90
91
  export interface CreateBranchDto {
91
92
  code: string;
92
93
  name: string;
94
+ shortName?: string;
93
95
  address?: string;
94
96
  phone?: string;
95
97
  email?: string;
@@ -106,6 +108,7 @@ export interface CreateBranchDto {
106
108
  export interface UpdateBranchDto {
107
109
  code?: string;
108
110
  name?: string;
111
+ shortName?: string;
109
112
  address?: string;
110
113
  phone?: string;
111
114
  email?: string;
package/package.json CHANGED
@@ -1,163 +1,163 @@
1
- {
2
- "name": "@tinyweb_dev/oe-exam-sdk",
3
- "version": "0.1.16",
4
- "description": "Reusable OceanEdu question components.",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "bin": {
10
- "oe-exam-mcp": "./dist/mcp/index.js"
11
- },
12
- "files": [
13
- "dist",
14
- "README.md"
15
- ],
16
- "sideEffects": [
17
- "**/*.css"
18
- ],
19
- "scripts": {
20
- "clean": "rm -rf dist",
21
- "build:compile": "tsc -p tsconfig.build.json",
22
- "build:alias": "tsc-alias -p tsconfig.build.json",
23
- "build:ts": "npm run build:compile && npm run build:assets && npm run build:alias",
24
- "build:assets": "for d in cambridge-yle english-certification summer-sky; do [ -d src/components/themes/$d/assets ] && cp -R src/components/themes/$d/assets dist/components/themes/$d/ || true; done; [ -d src/components/shared/audio/assets ] && cp -R src/components/shared/audio/assets dist/components/shared/audio/ || true; [ -d src/components/results/report/assets ] && mkdir -p dist/components/results/report && cp -R src/components/results/report/assets dist/components/results/report/ || true; (cd src && find . -name '*.module.css' -exec cp --parents {} ../dist/ \\;); cp src/global.d.ts dist/global.d.ts",
25
- "minify:js": "find dist -name '*.js' -type f -exec sh -c 'for f do terser \"$f\" --compress directives=false --mangle --module --comments false --output \"$f\"; done' sh {} +",
26
- "build": "npm run clean && npm run build:ts && npm run minify:js",
27
- "pack:local": "npm pack",
28
- "release": "npm run release:patch",
29
- "release:patch": "npm version patch --no-git-tag-version && npm run release:push",
30
- "release:minor": "npm version minor --no-git-tag-version && npm run release:push",
31
- "release:major": "npm version major --no-git-tag-version && npm run release:push",
32
- "release:push": "npm run build && npm pack --dry-run && VERSION=$(node -p \"require('./package.json').version\") && git add package.json package-lock.json && git commit -m \"chore(sdk): release v$VERSION\" && git tag \"sdk-v$VERSION\" && git push origin HEAD && git push origin \"sdk-v$VERSION\"",
33
- "prepack": "npm run build"
34
- },
35
- "exports": {
36
- ".": {
37
- "types": "./dist/index.d.ts",
38
- "import": "./dist/index.js"
39
- },
40
- "./api": {
41
- "types": "./dist/api/index.d.ts",
42
- "import": "./dist/api/index.js"
43
- },
44
- "./components": {
45
- "types": "./dist/components/index.d.ts",
46
- "import": "./dist/components/index.js"
47
- },
48
- "./mcp": {
49
- "types": "./dist/mcp/index.d.ts",
50
- "import": "./dist/mcp/index.js"
51
- },
52
- "./components/exams": {
53
- "types": "./dist/components/exams/index.d.ts",
54
- "import": "./dist/components/exams/index.js"
55
- },
56
- "./components/exams/take": {
57
- "types": "./dist/components/exams/take/index.d.ts",
58
- "import": "./dist/components/exams/take/index.js"
59
- },
60
- "./components/exams/entry": {
61
- "types": "./dist/components/exams/entry/index.d.ts",
62
- "import": "./dist/components/exams/entry/index.js"
63
- },
64
- "./components/exams/rooms": {
65
- "types": "./dist/components/exams/rooms/index.d.ts",
66
- "import": "./dist/components/exams/rooms/index.js"
67
- },
68
- "./components/questions": {
69
- "types": "./dist/components/questions/index.d.ts",
70
- "import": "./dist/components/questions/index.js"
71
- },
72
- "./components/themes": {
73
- "types": "./dist/components/themes/index.d.ts",
74
- "import": "./dist/components/themes/index.js"
75
- },
76
- "./components/results": {
77
- "types": "./dist/components/results/index.d.ts",
78
- "import": "./dist/components/results/index.js"
79
- },
80
- "./components/questions/*": {
81
- "types": "./dist/components/questions/*.d.ts",
82
- "import": "./dist/components/questions/*.js"
83
- },
84
- "./shared": {
85
- "types": "./dist/shared/index.d.ts",
86
- "import": "./dist/shared/index.js"
87
- },
88
- "./*": {
89
- "types": "./dist/components/questions/*.d.ts",
90
- "import": "./dist/components/questions/*.js"
91
- },
92
- "./package.json": "./package.json"
93
- },
94
- "publishConfig": {
95
- "access": "public"
96
- },
97
- "peerDependencies": {
98
- "next": ">=15",
99
- "react": ">=19",
100
- "react-dom": ">=19"
101
- },
102
- "devDependencies": {
103
- "@types/node": "^25.9.3",
104
- "terser": "^5.48.0",
105
- "tsc-alias": "^1.8.17",
106
- "typescript": "~5.9.2"
107
- },
108
- "dependencies": {
109
- "@dnd-kit/core": "^6.3.1",
110
- "@dnd-kit/sortable": "^10.0.0",
111
- "@dnd-kit/utilities": "^3.2.2",
112
- "@fortawesome/free-solid-svg-icons": "^7.3.1",
113
- "@fortawesome/react-fontawesome": "^3.3.1",
114
- "@hookform/resolvers": "^5.2.2",
115
- "@modelcontextprotocol/sdk": "^1.29.0",
116
- "@radix-ui/react-alert-dialog": "^1.1.15",
117
- "@radix-ui/react-avatar": "^1.1.10",
118
- "@radix-ui/react-checkbox": "^1.3.3",
119
- "@radix-ui/react-collapsible": "^1.1.12",
120
- "@radix-ui/react-dialog": "^1.1.15",
121
- "@radix-ui/react-dropdown-menu": "^2.1.16",
122
- "@radix-ui/react-hover-card": "^1.1.15",
123
- "@radix-ui/react-label": "^2.1.7",
124
- "@radix-ui/react-popover": "^1.1.15",
125
- "@radix-ui/react-progress": "^1.1.7",
126
- "@radix-ui/react-radio-group": "^1.3.8",
127
- "@radix-ui/react-scroll-area": "^1.2.10",
128
- "@radix-ui/react-select": "^2.2.6",
129
- "@radix-ui/react-separator": "^1.1.7",
130
- "@radix-ui/react-slot": "^1.2.3",
131
- "@radix-ui/react-switch": "^1.2.6",
132
- "@radix-ui/react-tabs": "^1.1.13",
133
- "@radix-ui/react-tooltip": "^1.2.8",
134
- "@tanstack/react-query": "^5.90.2",
135
- "@tiptap/extension-table": "^3.22.3",
136
- "@tiptap/extension-table-cell": "^3.22.3",
137
- "@tiptap/extension-table-header": "^3.22.3",
138
- "@tiptap/extension-table-row": "^3.22.3",
139
- "@tiptap/extension-text-align": "^3.22.3",
140
- "@tiptap/pm": "^3.22.3",
141
- "@tiptap/react": "^3.22.3",
142
- "@tiptap/starter-kit": "^3.22.3",
143
- "@types/qrcode": "^1.5.6",
144
- "@xyflow/react": "^12.8.6",
145
- "axios": "^1.12.2",
146
- "class-variance-authority": "^0.7.1",
147
- "clsx": "^2.1.1",
148
- "cmdk": "^1.1.1",
149
- "date-fns": "^4.1.0",
150
- "embla-carousel-react": "^8.6.0",
151
- "howler": "^2.2.4",
152
- "lucide-react": "^0.544.0",
153
- "qrcode": "^1.5.4",
154
- "radix-ui": "^1.4.3",
155
- "react-day-picker": "^9.14.0",
156
- "react-hook-form": "^7.65.0",
157
- "sonner": "^2.0.7",
158
- "tailwind-merge": "^3.3.1",
159
- "vaul": "^1.1.2",
160
- "zod": "^4.1.11",
161
- "zustand": "^5.0.8"
162
- }
163
- }
1
+ {
2
+ "name": "@tinyweb_dev/oe-exam-sdk",
3
+ "version": "0.1.18",
4
+ "description": "Reusable OceanEdu question components.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "oe-exam-mcp": "./dist/mcp/index.js"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "README.md"
15
+ ],
16
+ "sideEffects": [
17
+ "**/*.css"
18
+ ],
19
+ "scripts": {
20
+ "clean": "rm -rf dist",
21
+ "build:compile": "tsc -p tsconfig.build.json",
22
+ "build:alias": "tsc-alias -p tsconfig.build.json",
23
+ "build:ts": "npm run build:compile && npm run build:assets && npm run build:alias",
24
+ "build:assets": "for d in cambridge-yle english-certification summer-sky; do [ -d src/components/themes/$d/assets ] && cp -R src/components/themes/$d/assets dist/components/themes/$d/ || true; done; [ -d src/components/shared/audio/assets ] && cp -R src/components/shared/audio/assets dist/components/shared/audio/ || true; [ -d src/components/results/report/assets ] && mkdir -p dist/components/results/report && cp -R src/components/results/report/assets dist/components/results/report/ || true; (cd src && find . -name '*.module.css' -exec cp --parents {} ../dist/ \\;); cp src/global.d.ts dist/global.d.ts",
25
+ "minify:js": "find dist -name '*.js' -type f -exec sh -c 'for f do terser \"$f\" --compress directives=false --mangle --module --comments false --output \"$f\"; done' sh {} +",
26
+ "build": "npm run clean && npm run build:ts && npm run minify:js",
27
+ "pack:local": "npm pack",
28
+ "release": "npm run release:patch",
29
+ "release:patch": "npm version patch --no-git-tag-version && npm run release:push",
30
+ "release:minor": "npm version minor --no-git-tag-version && npm run release:push",
31
+ "release:major": "npm version major --no-git-tag-version && npm run release:push",
32
+ "release:push": "npm run build && npm pack --dry-run && VERSION=$(node -p \"require('./package.json').version\") && git add package.json package-lock.json && git commit -m \"chore(sdk): release v$VERSION\" && git tag \"sdk-v$VERSION\" && git push origin HEAD && git push origin \"sdk-v$VERSION\"",
33
+ "prepack": "npm run build"
34
+ },
35
+ "exports": {
36
+ ".": {
37
+ "types": "./dist/index.d.ts",
38
+ "import": "./dist/index.js"
39
+ },
40
+ "./api": {
41
+ "types": "./dist/api/index.d.ts",
42
+ "import": "./dist/api/index.js"
43
+ },
44
+ "./components": {
45
+ "types": "./dist/components/index.d.ts",
46
+ "import": "./dist/components/index.js"
47
+ },
48
+ "./mcp": {
49
+ "types": "./dist/mcp/index.d.ts",
50
+ "import": "./dist/mcp/index.js"
51
+ },
52
+ "./components/exams": {
53
+ "types": "./dist/components/exams/index.d.ts",
54
+ "import": "./dist/components/exams/index.js"
55
+ },
56
+ "./components/exams/take": {
57
+ "types": "./dist/components/exams/take/index.d.ts",
58
+ "import": "./dist/components/exams/take/index.js"
59
+ },
60
+ "./components/exams/entry": {
61
+ "types": "./dist/components/exams/entry/index.d.ts",
62
+ "import": "./dist/components/exams/entry/index.js"
63
+ },
64
+ "./components/exams/rooms": {
65
+ "types": "./dist/components/exams/rooms/index.d.ts",
66
+ "import": "./dist/components/exams/rooms/index.js"
67
+ },
68
+ "./components/questions": {
69
+ "types": "./dist/components/questions/index.d.ts",
70
+ "import": "./dist/components/questions/index.js"
71
+ },
72
+ "./components/themes": {
73
+ "types": "./dist/components/themes/index.d.ts",
74
+ "import": "./dist/components/themes/index.js"
75
+ },
76
+ "./components/results": {
77
+ "types": "./dist/components/results/index.d.ts",
78
+ "import": "./dist/components/results/index.js"
79
+ },
80
+ "./components/questions/*": {
81
+ "types": "./dist/components/questions/*.d.ts",
82
+ "import": "./dist/components/questions/*.js"
83
+ },
84
+ "./shared": {
85
+ "types": "./dist/shared/index.d.ts",
86
+ "import": "./dist/shared/index.js"
87
+ },
88
+ "./*": {
89
+ "types": "./dist/components/questions/*.d.ts",
90
+ "import": "./dist/components/questions/*.js"
91
+ },
92
+ "./package.json": "./package.json"
93
+ },
94
+ "publishConfig": {
95
+ "access": "public"
96
+ },
97
+ "peerDependencies": {
98
+ "next": ">=15",
99
+ "react": ">=19",
100
+ "react-dom": ">=19"
101
+ },
102
+ "devDependencies": {
103
+ "@types/node": "^25.9.3",
104
+ "terser": "^5.48.0",
105
+ "tsc-alias": "^1.8.17",
106
+ "typescript": "~5.9.2"
107
+ },
108
+ "dependencies": {
109
+ "@dnd-kit/core": "^6.3.1",
110
+ "@dnd-kit/sortable": "^10.0.0",
111
+ "@dnd-kit/utilities": "^3.2.2",
112
+ "@fortawesome/free-solid-svg-icons": "^7.3.1",
113
+ "@fortawesome/react-fontawesome": "^3.3.1",
114
+ "@hookform/resolvers": "^5.2.2",
115
+ "@modelcontextprotocol/sdk": "^1.29.0",
116
+ "@radix-ui/react-alert-dialog": "^1.1.15",
117
+ "@radix-ui/react-avatar": "^1.1.10",
118
+ "@radix-ui/react-checkbox": "^1.3.3",
119
+ "@radix-ui/react-collapsible": "^1.1.12",
120
+ "@radix-ui/react-dialog": "^1.1.15",
121
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
122
+ "@radix-ui/react-hover-card": "^1.1.15",
123
+ "@radix-ui/react-label": "^2.1.7",
124
+ "@radix-ui/react-popover": "^1.1.15",
125
+ "@radix-ui/react-progress": "^1.1.7",
126
+ "@radix-ui/react-radio-group": "^1.3.8",
127
+ "@radix-ui/react-scroll-area": "^1.2.10",
128
+ "@radix-ui/react-select": "^2.2.6",
129
+ "@radix-ui/react-separator": "^1.1.7",
130
+ "@radix-ui/react-slot": "^1.2.3",
131
+ "@radix-ui/react-switch": "^1.2.6",
132
+ "@radix-ui/react-tabs": "^1.1.13",
133
+ "@radix-ui/react-tooltip": "^1.2.8",
134
+ "@tanstack/react-query": "^5.90.2",
135
+ "@tiptap/extension-table": "^3.22.3",
136
+ "@tiptap/extension-table-cell": "^3.22.3",
137
+ "@tiptap/extension-table-header": "^3.22.3",
138
+ "@tiptap/extension-table-row": "^3.22.3",
139
+ "@tiptap/extension-text-align": "^3.22.3",
140
+ "@tiptap/pm": "^3.22.3",
141
+ "@tiptap/react": "^3.22.3",
142
+ "@tiptap/starter-kit": "^3.22.3",
143
+ "@types/qrcode": "^1.5.6",
144
+ "@xyflow/react": "^12.8.6",
145
+ "axios": "^1.12.2",
146
+ "class-variance-authority": "^0.7.1",
147
+ "clsx": "^2.1.1",
148
+ "cmdk": "^1.1.1",
149
+ "date-fns": "^4.1.0",
150
+ "embla-carousel-react": "^8.6.0",
151
+ "howler": "^2.2.4",
152
+ "lucide-react": "^0.544.0",
153
+ "qrcode": "^1.5.4",
154
+ "radix-ui": "^1.4.3",
155
+ "react-day-picker": "^9.14.0",
156
+ "react-hook-form": "^7.65.0",
157
+ "sonner": "^2.0.7",
158
+ "tailwind-merge": "^3.3.1",
159
+ "vaul": "^1.1.2",
160
+ "zod": "^4.1.11",
161
+ "zustand": "^5.0.8"
162
+ }
163
+ }