@khanacademy/perseus-score 7.1.8 → 7.1.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.
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,6 @@ export { default as scoreMatcher } from "./widgets/matcher/score-matcher";
|
|
|
16
16
|
export { default as scoreMatrix } from "./widgets/matrix/score-matrix";
|
|
17
17
|
export { default as validateMatrix } from "./widgets/matrix/validate-matrix";
|
|
18
18
|
export { default as scoreNumberLine } from "./widgets/number-line/score-number-line";
|
|
19
|
-
export { default as validateNumberLine } from "./widgets/number-line/validate-number-line";
|
|
20
19
|
export { default as scoreNumericInput } from "./widgets/numeric-input/score-numeric-input";
|
|
21
20
|
export { default as scoreOrderer } from "./widgets/orderer/score-orderer";
|
|
22
21
|
export { default as validateOrderer } from "./widgets/orderer/validate-orderer";
|
package/dist/index.js
CHANGED
|
@@ -62,9 +62,7 @@ function scoreMatrix(userInput,rubric){const solution=rubric.answers;const suppl
|
|
|
62
62
|
|
|
63
63
|
function validateMatrix(userInput){const supplied=userInput.answers;const suppliedSize=perseusCore.getMatrixSize(supplied);for(let row=0;row<suppliedSize[0];row++){for(let col=0;col<suppliedSize[1];col++){if(supplied[row][col]==null||supplied[row][col].toString().length===0){return {type:"invalid",message:ErrorCodes.FILL_ALL_CELLS_ERROR}}}}return null}
|
|
64
64
|
|
|
65
|
-
function scoreNumberLine(userInput,rubric){const range=rubric.range;const start=rubric.initialX!=null?rubric.initialX:range[0];const startRel=rubric.isInequality?"ge":"eq";const correctRel=rubric.correctRel||"eq";const correctPos=kmath.number.equal(userInput.numLinePosition,rubric.correctX||0);if(correctPos&&correctRel===userInput.rel){return {type:"points",earned:1,total:1,message:null}}if(userInput.numLinePosition===start&&userInput.rel===startRel){return {type:"invalid",message:null}}return {type:"points",earned:0,total:1,message:null}}
|
|
66
|
-
|
|
67
|
-
function validateNumberLine(userInput){const divisionRange=userInput.divisionRange;const outsideAllowedRange=userInput.numDivisions>divisionRange[1]||userInput.numDivisions<divisionRange[0];if(userInput.isTickCrtl&&outsideAllowedRange){return {type:"invalid",message:"Number of divisions is outside the allowed range."}}return null}
|
|
65
|
+
function scoreNumberLine(userInput,rubric){const divisionRange=rubric.divisionRange;const outsideAllowedRange=userInput.numDivisions>divisionRange[1]||userInput.numDivisions<divisionRange[0];if(rubric.isTickCtrl&&outsideAllowedRange){return {type:"invalid",message:"Number of divisions is outside the allowed range."}}const range=rubric.range;const start=rubric.initialX!=null?rubric.initialX:range[0];const startRel=rubric.isInequality?"ge":"eq";const correctRel=rubric.correctRel||"eq";const correctPos=kmath.number.equal(userInput.numLinePosition,rubric.correctX||0);if(correctPos&&correctRel===userInput.rel){return {type:"points",earned:1,total:1,message:null}}if(userInput.numLinePosition===start&&userInput.rel===startRel){return {type:"invalid",message:null}}return {type:"points",earned:0,total:1,message:null}}
|
|
68
66
|
|
|
69
67
|
function findEndpoint(tex,currentIndex){let bracketDepth=0;for(let i=currentIndex,len=tex.length;i<len;i++){const c=tex[i];if(c==="{"){bracketDepth++;}else if(c==="}"){bracketDepth--;}if(bracketDepth<0){return i}}return tex.length}function parseNextExpression(tex,currentIndex,handler){const openBracketIndex=tex.indexOf("{",currentIndex);if(openBracketIndex===-1){return {endpoint:tex.length,expression:""}}const nextExpIndex=openBracketIndex+1;const endpoint=findEndpoint(tex,nextExpIndex);const expressionTeX=tex.substring(nextExpIndex,endpoint);const parsedExp=walkTex(expressionTeX,handler);return {endpoint:endpoint,expression:parsedExp}}function getNextFracIndex(tex,currentIndex){const dfrac="\\dfrac";const frac="\\frac";const nextFrac=tex.indexOf(frac,currentIndex);const nextDFrac=tex.indexOf(dfrac,currentIndex);if(nextFrac>-1&&nextDFrac>-1){return Math.min(nextFrac,nextDFrac)}if(nextFrac>-1){return nextFrac}if(nextDFrac>-1){return nextDFrac}return -1}function walkTex(tex,handler){if(!tex){return ""}let parsedString="";let currentIndex=0;let nextFrac=getNextFracIndex(tex,currentIndex);while(nextFrac>-1){parsedString+=tex.substring(currentIndex,nextFrac);currentIndex=nextFrac;const firstParsedExpression=parseNextExpression(tex,currentIndex,handler);currentIndex=firstParsedExpression.endpoint+1;const secondParsedExpression=parseNextExpression(tex,currentIndex,handler);currentIndex=secondParsedExpression.endpoint+1;if(parsedString.length){parsedString+=" ";}parsedString+=handler(firstParsedExpression.expression,secondParsedExpression.expression);nextFrac=getNextFracIndex(tex,currentIndex);}parsedString+=tex.slice(currentIndex);return parsedString}function parseTex(tex){const handler=function(exp1,exp2){return exp1+"/"+exp2};const texWithoutFracs=walkTex(tex,handler);return texWithoutFracs.replace("\\%","%")}
|
|
70
68
|
|
|
@@ -84,7 +82,7 @@ function validateRadio(userInput){if(!userInput.choicesSelected.includes(true)){
|
|
|
84
82
|
|
|
85
83
|
function scoreSorter(userInput,rubric){const correct=perseusCore.approximateDeepEqual(userInput.options,rubric.correct);return {type:"points",earned:correct?1:0,total:1,message:null}}
|
|
86
84
|
|
|
87
|
-
function validateSorter(userInput){if(!userInput
|
|
85
|
+
function validateSorter(userInput){if(!userInput?.changed){return {type:"invalid",message:null}}return null}
|
|
88
86
|
|
|
89
87
|
const filterNonEmpty=function(table){return table.filter(function(row){return row.some(cell=>cell)})};
|
|
90
88
|
|
|
@@ -112,7 +110,7 @@ function validateMockWidget(userInput){if(userInput.currentValue==null||userInpu
|
|
|
112
110
|
|
|
113
111
|
function scoreMockWidget(userInput,rubric){const validationResult=validateMockWidget(userInput);if(validationResult!=null){return validationResult}return {type:"points",earned:userInput.currentValue===rubric.value?1:0,total:1,message:""}}
|
|
114
112
|
|
|
115
|
-
const widgets=new perseusCore.Registry("Score widget registry");function registerWidget(type,scorer,validator){const logic={scorer,validator};widgets.set(type,logic);}const getWidgetValidator=type=>{return widgets.get(type)?.validator??null};const getWidgetScorer=type=>{return widgets.get(type)?.scorer??null};registerWidget("categorizer",scoreCategorizer,validateCategorizer);registerWidget("cs-program",scoreCSProgram);registerWidget("dropdown",scoreDropdown,validateDropdown);registerWidget("expression",scoreExpression,validateExpression);registerWidget("free-response",scoreFreeResponse,validateFreeResponse);registerWidget("grapher",scoreGrapher);registerWidget("group",scoreGroup,validateGroup);registerWidget("iframe",scoreIframe);registerWidget("input-number",scoreInputNumber);registerWidget("interactive-graph",scoreInteractiveGraph);registerWidget("label-image",scoreLabelImage,validateLabelImage);registerWidget("matcher",scoreMatcher);registerWidget("matrix",scoreMatrix,validateMatrix);registerWidget("mock-widget",scoreMockWidget,scoreMockWidget);registerWidget("number-line",scoreNumberLine
|
|
113
|
+
const widgets=new perseusCore.Registry("Score widget registry");function registerWidget(type,scorer,validator){const logic={scorer,validator};widgets.set(type,logic);}const getWidgetValidator=type=>{return widgets.get(type)?.validator??null};const getWidgetScorer=type=>{return widgets.get(type)?.scorer??null};registerWidget("categorizer",scoreCategorizer,validateCategorizer);registerWidget("cs-program",scoreCSProgram);registerWidget("dropdown",scoreDropdown,validateDropdown);registerWidget("expression",scoreExpression,validateExpression);registerWidget("free-response",scoreFreeResponse,validateFreeResponse);registerWidget("grapher",scoreGrapher);registerWidget("group",scoreGroup,validateGroup);registerWidget("iframe",scoreIframe);registerWidget("input-number",scoreInputNumber);registerWidget("interactive-graph",scoreInteractiveGraph);registerWidget("label-image",scoreLabelImage,validateLabelImage);registerWidget("matcher",scoreMatcher);registerWidget("matrix",scoreMatrix,validateMatrix);registerWidget("mock-widget",scoreMockWidget,scoreMockWidget);registerWidget("number-line",scoreNumberLine);registerWidget("numeric-input",scoreNumericInput);registerWidget("orderer",scoreOrderer,validateOrderer);registerWidget("plotter",scorePlotter,validatePlotter);registerWidget("radio",scoreRadio,validateRadio);registerWidget("sorter",scoreSorter,validateSorter);registerWidget("table",scoreTable,validateTable);registerWidget("deprecated-standin",()=>scoreNoop(1));registerWidget("measurer",()=>scoreNoop(1));registerWidget("definition",scoreNoop);registerWidget("explanation",scoreNoop);registerWidget("image",scoreNoop);registerWidget("interaction",scoreNoop);registerWidget("molecule",scoreNoop);registerWidget("passage",scoreNoop);registerWidget("passage-ref",scoreNoop);registerWidget("passage-ref-target",scoreNoop);registerWidget("video",scoreNoop);
|
|
116
114
|
|
|
117
115
|
const noScore={type:"points",earned:0,total:0,message:null};function scoreIsEmpty(score){return score.type==="invalid"&&(!score.message||score.message.length===0)}function combineScores(scoreA,scoreB){let message;if(scoreA.type==="points"&&scoreB.type==="points"){if(scoreA.message&&scoreB.message&&scoreA.message!==scoreB.message){message=null;}else {message=scoreA.message||scoreB.message;}return {type:"points",earned:scoreA.earned+scoreB.earned,total:scoreA.total+scoreB.total,message:message}}if(scoreA.type==="points"&&scoreB.type==="invalid"){return scoreB}if(scoreA.type==="invalid"&&scoreB.type==="points"){return scoreA}if(scoreA.type==="invalid"&&scoreB.type==="invalid"){if(scoreA.message&&scoreB.message&&scoreA.message!==scoreB.message){message=null;}else {message=scoreA.message||scoreB.message;}return {type:"invalid",message:message}}throw new perseusCore.PerseusError("PerseusScore with unknown type encountered",perseusCore.Errors.InvalidInput,{metadata:{scoreA:JSON.stringify(scoreA),scoreB:JSON.stringify(scoreB)}})}function flattenScores(widgetScoreMap){return Object.values(widgetScoreMap).reduce(combineScores,noScore)}function scorePerseusItem(perseusRenderData,userInputMap,locale){const usedWidgetIds=perseusCore.getWidgetIdsFromContent(perseusRenderData.content);const scores=scoreWidgetsFunctional(perseusRenderData.widgets,usedWidgetIds,userInputMap,locale);return flattenScores(scores)}function scoreWidgetsFunctional(widgets,widgetIds,userInputMap,locale){const upgradedWidgets=perseusCore.applyDefaultsToWidgets(widgets);const gradedWidgetIds=widgetIds.filter(id=>{const props=upgradedWidgets[id];const widgetIsGraded=props?.graded==null||props.graded;const widgetIsStatic=!!props?.static;return widgetIsGraded&&!widgetIsStatic});const widgetScores={};gradedWidgetIds.forEach(id=>{const widget=upgradedWidgets[id];if(!widget){return}const userInput=userInputMap[id];const validator=getWidgetValidator(widget.type);const scorer=getWidgetScorer(widget.type);const score=validator?.(userInput,widget.options,locale)??scorer?.(userInput,widget.options,locale);if(score!=null){widgetScores[id]=score;}});return widgetScores}
|
|
118
116
|
|
|
@@ -152,7 +150,6 @@ exports.validateCategorizer = validateCategorizer;
|
|
|
152
150
|
exports.validateDropdown = validateDropdown;
|
|
153
151
|
exports.validateExpression = validateExpression;
|
|
154
152
|
exports.validateMatrix = validateMatrix;
|
|
155
|
-
exports.validateNumberLine = validateNumberLine;
|
|
156
153
|
exports.validateOrderer = validateOrderer;
|
|
157
154
|
exports.validatePlotter = validatePlotter;
|
|
158
155
|
exports.validateRadio = validateRadio;
|