@khanacademy/perseus-core 0.0.0-PR3084-20251204004313 → 0.0.0-PR3084-20251218000921
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/error-codes.d.ts +1 -0
- package/dist/es/index.item-splitting.js.map +1 -1
- package/dist/es/index.js +42 -7
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.item-splitting.js.map +1 -1
- package/dist/index.js +89 -6
- package/dist/index.js.map +1 -1
- package/dist/utils/extract-perseus-ai-data.d.ts +39 -0
- package/dist/utils/generators/definition-widget-generator.d.ts +3 -0
- package/dist/utils/generators/dropdown-widget-generator.d.ts +3 -0
- package/dist/utils/generators/explanation-widget-generator.d.ts +3 -0
- package/dist/utils/generators/expression-widget-generator.d.ts +4 -0
- package/dist/utils/generators/free-response-widget-generator.d.ts +3 -0
- package/dist/utils/generators/graded-group-set-widget-generator.d.ts +2 -0
- package/dist/utils/generators/graded-group-widget-generator.d.ts +3 -0
- package/dist/utils/generators/group-widget-generator.d.ts +3 -0
- package/dist/utils/generators/interactive-graph-widget-generator.d.ts +21 -0
- package/dist/utils/generators/label-image-widget-generator.d.ts +3 -0
- package/dist/utils/generators/numeric-input-widget-generator.d.ts +4 -0
- package/dist/utils/generators/radio-widget-generator.d.ts +16 -0
- package/dist/utils/get-default-figure-for-type.d.ts +9 -0
- package/dist/validation.types.d.ts +2 -22
- package/dist/widgets/interactive-graph/index.d.ts +1 -1
- package/dist/widgets/label-image/label-image-util.d.ts +2 -1
- package/package.json +7 -7
- package/dist/validation.typetest.d.ts +0 -1
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ var _ = require('underscore');
|
|
|
6
6
|
require('tiny-invariant');
|
|
7
7
|
var KAS = require('@khanacademy/kas');
|
|
8
8
|
var perseusUtils = require('@khanacademy/perseus-utils');
|
|
9
|
+
var wonderStuffCore = require('@khanacademy/wonder-stuff-core');
|
|
9
10
|
var pureMarkdown = require('@khanacademy/pure-markdown');
|
|
10
11
|
|
|
11
12
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
@@ -31,7 +32,7 @@ function _interopNamespaceCompat(e) {
|
|
|
31
32
|
var ___default = /*#__PURE__*/_interopDefaultCompat(_);
|
|
32
33
|
var KAS__namespace = /*#__PURE__*/_interopNamespaceCompat(KAS);
|
|
33
34
|
|
|
34
|
-
const APPROXIMATED_PI_ERROR="APPROXIMATED_PI_ERROR";const CHOOSE_CORRECT_NUM_ERROR="CHOOSE_CORRECT_NUM_ERROR";const EXTRA_SYMBOLS_ERROR="EXTRA_SYMBOLS_ERROR";const FILL_ALL_CELLS_ERROR="FILL_ALL_CELLS_ERROR";const INVALID_CHOICE_SELECTION="INVALID_CHOICE_SELECTION";const INVALID_SELECTION_ERROR="INVALID_SELECTION_ERROR";const MISSING_PERCENT_ERROR="MISSING_PERCENT_ERROR";const MULTIPLICATION_SIGN_ERROR="MULTIPLICATION_SIGN_ERROR";const NEEDS_TO_BE_SIMPLIFIED_ERROR="NEEDS_TO_BE_SIMPLIFIED_ERROR";const NOT_NONE_ABOVE_ERROR="NOT_NONE_ABOVE_ERROR";const USER_INPUT_EMPTY="USER_INPUT_EMPTY";const USER_INPUT_TOO_LONG="USER_INPUT_TOO_LONG";const WRONG_CASE_ERROR="WRONG_CASE_ERROR";const WRONG_LETTER_ERROR="WRONG_LETTER_ERROR";const ErrorCodes={APPROXIMATED_PI_ERROR,CHOOSE_CORRECT_NUM_ERROR,EXTRA_SYMBOLS_ERROR,FILL_ALL_CELLS_ERROR,INVALID_CHOICE_SELECTION,INVALID_SELECTION_ERROR,MISSING_PERCENT_ERROR,MULTIPLICATION_SIGN_ERROR,NEEDS_TO_BE_SIMPLIFIED_ERROR,NOT_NONE_ABOVE_ERROR,USER_INPUT_EMPTY,USER_INPUT_TOO_LONG,WRONG_CASE_ERROR,WRONG_LETTER_ERROR};
|
|
35
|
+
const APPROXIMATED_PI_ERROR="APPROXIMATED_PI_ERROR";const CHOOSE_CORRECT_NUM_ERROR="CHOOSE_CORRECT_NUM_ERROR";const EMPTY_RESPONSE_ERROR="EMPTY_RESPONSE_ERROR";const EXTRA_SYMBOLS_ERROR="EXTRA_SYMBOLS_ERROR";const FILL_ALL_CELLS_ERROR="FILL_ALL_CELLS_ERROR";const INVALID_CHOICE_SELECTION="INVALID_CHOICE_SELECTION";const INVALID_SELECTION_ERROR="INVALID_SELECTION_ERROR";const MISSING_PERCENT_ERROR="MISSING_PERCENT_ERROR";const MULTIPLICATION_SIGN_ERROR="MULTIPLICATION_SIGN_ERROR";const NEEDS_TO_BE_SIMPLIFIED_ERROR="NEEDS_TO_BE_SIMPLIFIED_ERROR";const NOT_NONE_ABOVE_ERROR="NOT_NONE_ABOVE_ERROR";const USER_INPUT_EMPTY="USER_INPUT_EMPTY";const USER_INPUT_TOO_LONG="USER_INPUT_TOO_LONG";const WRONG_CASE_ERROR="WRONG_CASE_ERROR";const WRONG_LETTER_ERROR="WRONG_LETTER_ERROR";const ErrorCodes={APPROXIMATED_PI_ERROR,CHOOSE_CORRECT_NUM_ERROR,EMPTY_RESPONSE_ERROR,EXTRA_SYMBOLS_ERROR,FILL_ALL_CELLS_ERROR,INVALID_CHOICE_SELECTION,INVALID_SELECTION_ERROR,MISSING_PERCENT_ERROR,MULTIPLICATION_SIGN_ERROR,NEEDS_TO_BE_SIMPLIFIED_ERROR,NOT_NONE_ABOVE_ERROR,USER_INPUT_EMPTY,USER_INPUT_TOO_LONG,WRONG_CASE_ERROR,WRONG_LETTER_ERROR};
|
|
35
36
|
|
|
36
37
|
function getMatrixSize(matrix){const matrixSize=[1,1];matrix.forEach((matrixRow,row)=>{let rowWidth=0;matrixRow.forEach((matrixCol,col)=>{if(matrixCol!=null&&matrixCol.toString().length){rowWidth=col+1;}});matrixSize[1]=Math.max(matrixSize[1],rowWidth);if(rowWidth>0){matrixSize[0]=Math.max(matrixSize[0],row+1);}});return matrixSize}
|
|
37
38
|
|
|
@@ -258,7 +259,7 @@ const parseUserInputMap=(rawValue,ctx)=>{if(!isPlainObject(rawValue)){return ctx
|
|
|
258
259
|
|
|
259
260
|
function parsePerseusItem(json){if(isRealJSONParse(JSON.parse)){return JSON.parse(json)}throw new Error("Something went wrong.")}function parseAndMigratePerseusItem(data){throwErrorIfCheatingDetected();const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parsePerseusItem$1);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}function parseAndMigratePerseusArticle(data){throwErrorIfCheatingDetected();const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parsePerseusArticle);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}function parseAndMigrateUserInputMap(data){const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parseUserInputMap);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}function throwErrorIfCheatingDetected(){if(!isRealJSONParse(JSON.parse)){throw new Error("Something went wrong.")}}
|
|
260
261
|
|
|
261
|
-
const libName="@khanacademy/perseus-core";const libVersion="
|
|
262
|
+
const libName="@khanacademy/perseus-core";const libVersion="21.0.2";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
262
263
|
|
|
263
264
|
const Errors=Object.freeze({Unknown:"Unknown",Internal:"Internal",InvalidInput:"InvalidInput",NotAllowed:"NotAllowed",TransientService:"TransientService",Service:"Service"});
|
|
264
265
|
|
|
@@ -318,11 +319,11 @@ const svgLabelsRegex=/^web\+graphie:/;const svgLocalLabelsRegex=/^file\+graphie:
|
|
|
318
319
|
|
|
319
320
|
function getInteractiveGraphPublicWidgetOptions(options){const{correct:_,...publicOptions}=options;return publicOptions}
|
|
320
321
|
|
|
321
|
-
const defaultWidgetOptions$i={labels:["$x$","$y$"],labelLocation:"onAxis",range:[[-10,10],[-10,10]],step:[1,1],backgroundImage:{url:null},markings:"graph",showTooltips:false,showProtractor:false,graph:{type:"linear"},correct:{type:"linear",coords:null}};const interactiveGraphWidgetLogic={name:"interactive-graph",defaultWidgetOptions: defaultWidgetOptions$i,getPublicWidgetOptions:getInteractiveGraphPublicWidgetOptions,accessible:widgetOptions=>{const interactiveGraphOptions=widgetOptions;if(interactiveGraphOptions.showProtractor){return false}if(interactiveGraphOptions.backgroundImage?.url&&isLabeledSVG(interactiveGraphOptions.backgroundImage?.url)){return false}return true}};
|
|
322
|
+
const defaultWidgetOptions$i={labels:["$x$","$y$"],labelLocation:"onAxis",lockedFigures:[],range:[[-10,10],[-10,10]],step:[1,1],backgroundImage:{url:null},markings:"graph",showAxisArrows:{xMin:true,xMax:true,yMin:true,yMax:true},showTooltips:false,showProtractor:false,graph:{type:"linear"},correct:{type:"linear",coords:null}};const interactiveGraphWidgetLogic={name:"interactive-graph",defaultWidgetOptions: defaultWidgetOptions$i,getPublicWidgetOptions:getInteractiveGraphPublicWidgetOptions,accessible:widgetOptions=>{const interactiveGraphOptions=widgetOptions;if(interactiveGraphOptions.showProtractor){return false}if(interactiveGraphOptions.backgroundImage?.url&&isLabeledSVG(interactiveGraphOptions.backgroundImage?.url)){return false}return true}};
|
|
322
323
|
|
|
323
|
-
function getLabelImagePublicWidgetOptions(options){return {...options,markers:options.markers.map(getLabelImageMarkerPublicData)}}function getLabelImageMarkerPublicData(marker){const{answers:_,...publicData}=marker;return publicData}
|
|
324
|
+
function getLabelImagePublicWidgetOptions(options){return {...options,markers:options.markers.map(getLabelImageMarkerPublicData)}}function getLabelImageMarkerPublicData(marker){const{answers:_,...publicData}=marker;return publicData}function isLabelImageAccessible(options){const labelImageOptions=options;if(labelImageOptions.imageUrl!==""&&labelImageOptions.imageAlt===""){return false}for(const marker of labelImageOptions.markers){if(marker.label===""){return false}}return true}
|
|
324
325
|
|
|
325
|
-
const defaultWidgetOptions$h={choices:[],imageAlt:"",imageUrl:"",imageWidth:0,imageHeight:0,markers:[],multipleAnswers:false,hideChoicesFromInstructions:false};const labelImageWidgetLogic={name:"label-image",defaultWidgetOptions: defaultWidgetOptions$h,getPublicWidgetOptions:getLabelImagePublicWidgetOptions,accessible:
|
|
326
|
+
const defaultWidgetOptions$h={choices:[],imageAlt:"",imageUrl:"",imageWidth:0,imageHeight:0,markers:[],multipleAnswers:false,hideChoicesFromInstructions:false};const labelImageWidgetLogic={name:"label-image",defaultWidgetOptions: defaultWidgetOptions$h,getPublicWidgetOptions:getLabelImagePublicWidgetOptions,accessible:isLabelImageAccessible};
|
|
326
327
|
|
|
327
328
|
const seededRNG=function(seed){let randomSeed=seed;return function(){let seed=randomSeed;seed=seed+0x7ed55d16+(seed<<12)&0xffffffff;seed=(seed^0xc761c23c^seed>>>19)&0xffffffff;seed=seed+0x165667b1+(seed<<5)&0xffffffff;seed=(seed+0xd3a2646c^seed<<9)&0xffffffff;seed=seed+0xfd7046c5+(seed<<3)&0xffffffff;seed=(seed^0xb55a4f09^seed>>>16)&0xffffffff;return (randomSeed=seed&0xfffffff)/0x10000000}};function shuffle(array,randomSeed,ensurePermuted=false){let random;if(typeof randomSeed==="function"){random=randomSeed;}else {random=seededRNG(randomSeed);}function isValidShuffle(shuffled){return ensurePermuted?!___default.default.isEqual(array,shuffled):true}return constrainedShuffle(array,random,isValidShuffle)}function constrainedShuffle(array,random,isValidShuffle){const maxIterations=100;const shuffled=[...array];if(shuffled.every(value=>___default.default.isEqual(value,shuffled[0]))){return shuffled}for(let i=0;i<maxIterations;i++){shuffleInPlace(shuffled,random);if(isValidShuffle(shuffled)){return shuffled}}throw new Error(`constrainedShuffle: constraint not met after ${maxIterations} attempts`)}function shuffleInPlace(a,random){for(let i=a.length-1;i>0;i--){const k=randomIntInRange(0,i,random);[a[k],a[i]]=[a[i],a[k]];}}function randomIntInRange(min,max,random){return Math.floor(random()*(max-min+1))+min}const random=seededRNG(new Date().getTime()&0xffffffff);
|
|
328
329
|
|
|
@@ -405,6 +406,8 @@ const defaultWidgetOptions={content:"",widgets:{},images:{}};const traverseChild
|
|
|
405
406
|
|
|
406
407
|
function getDefaultAnswerArea(){return ItemExtras.reduce((acc,curr)=>({...acc,[curr]:false}),{})}
|
|
407
408
|
|
|
409
|
+
const DEFAULT_COLOR="grayH";function getDefaultFigureForType(type){switch(type){case "point":return {type:"point",coord:[0,0],color:DEFAULT_COLOR,filled:true,labels:[]};case "line":return {type:"line",kind:"line",points:[getDefaultFigureForType("point"),{...getDefaultFigureForType("point"),coord:[2,2]}],color:DEFAULT_COLOR,lineStyle:"solid",showPoint1:false,showPoint2:false,weight:"medium",labels:[]};case "vector":return {type:"vector",points:[[0,0],[2,2]],color:DEFAULT_COLOR,weight:"medium",labels:[]};case "ellipse":return {type:"ellipse",center:[0,0],radius:[1,1],angle:0,color:DEFAULT_COLOR,fillStyle:"none",strokeStyle:"solid",weight:"medium",labels:[]};case "polygon":return {type:"polygon",points:[[0,2],[-1,0],[1,0]],color:DEFAULT_COLOR,showVertices:false,fillStyle:"none",strokeStyle:"solid",weight:"medium",labels:[]};case "function":return {type:"function",color:DEFAULT_COLOR,strokeStyle:"solid",weight:"medium",equation:"x^2",domain:[-Infinity,Infinity],directionalAxis:"x",labels:[]};case "label":return {type:"label",coord:[0,0],text:"label",color:DEFAULT_COLOR,size:"medium"};default:throw new wonderStuffCore.UnreachableCaseError(type)}}
|
|
410
|
+
|
|
408
411
|
function splitPerseusItem(original){const item=deepClone(original);return {...item,question:splitPerseusRenderer(item.question),hints:[]}}function splitPerseusItemJSON(data){const parseResult=parseAndMigratePerseusItem(data);if(isFailure(parseResult)){throw new SyntaxError(parseResult.detail.message)}const item=parseResult.value;return JSON.stringify(splitPerseusItem(item))}
|
|
409
412
|
|
|
410
413
|
const PerseusFeatureFlags=["new-radio-widget","image-widget-upgrade"];function isFeatureOn(props,flag){return props.apiOptions?.flags?.[flag]??false}
|
|
@@ -413,10 +416,42 @@ const noop=function(){};const deepCallbackFor=function(contentCallback,widgetCal
|
|
|
413
416
|
|
|
414
417
|
function violatingWidgets(itemData){const widgetTypes=[];traverse(itemData.question,null,function(info){if(info.type&&!isAccessible(info.type,info.options)){widgetTypes.push(info.type);}});return [...new Set(widgetTypes)]}function isItemAccessible(itemData){const ast=pureMarkdown.parse(itemData.question.content);const widgetIdsInUse=new Set;let hasInaccessibleImage=false;pureMarkdown.traverseContent(ast,node=>{if(node.type==="image"&&(node.alt==null||node.alt==="")){hasInaccessibleImage=true;return}if(node.type==="widget"){widgetIdsInUse.add(node.id);}});if(hasInaccessibleImage){return false}const itemDataWithOnlyActiveWidgets={...itemData,question:{...itemData.question,widgets:Object.fromEntries(Object.entries(itemData.question.widgets).filter(([id])=>widgetIdsInUse.has(id)))}};return violatingWidgets(itemDataWithOnlyActiveWidgets).length===0}
|
|
415
418
|
|
|
416
|
-
function
|
|
419
|
+
function generateDefinitionOptions(options){return {...definitionWidgetLogic.defaultWidgetOptions,...options}}function generateDefinitionWidget(definitionWidgetProperties){return {type:"definition",graded:false,version:{major:0,minor:0},static:false,alignment:"default",options:generateDefinitionOptions(),...definitionWidgetProperties}}
|
|
420
|
+
|
|
421
|
+
function generateDropdownOptions(options){return {...dropdownWidgetLogic.defaultWidgetOptions,...options}}function generateDropdownWidget(dropdownWidgetProperties){return {type:"dropdown",graded:true,version:{major:0,minor:0},static:false,alignment:"default",options:generateDropdownOptions(),...dropdownWidgetProperties}}
|
|
422
|
+
|
|
423
|
+
function generateExplanationOptions(options){return {...explanationWidgetLogic.defaultWidgetOptions,...options}}function generateExplanationWidget(explanationWidgetProperties){return {type:"explanation",graded:false,version:{major:0,minor:0},static:false,alignment:"default",options:generateExplanationOptions(),...explanationWidgetProperties}}
|
|
424
|
+
|
|
425
|
+
function generateExpressionOptions(options){return {...expressionWidgetLogic.defaultWidgetOptions,...options}}function generateExpressionAnswerForm(answerFormOptions){return {value:"",form:false,simplify:false,considered:"wrong",...answerFormOptions}}function generateExpressionWidget(expressionWidgetProperties){return {type:"expression",graded:true,version:{major:0,minor:0},static:false,alignment:"default",options:generateExpressionOptions(),...expressionWidgetProperties}}
|
|
426
|
+
|
|
427
|
+
function generateFreeResponseOptions(options){return {...freeResponseWidgetLogic.defaultWidgetOptions,...options}}function generateFreeResponseWidget(freeResponseWidgetProperties){return {type:"free-response",graded:true,version:{major:0,minor:0},static:false,alignment:"default",options:generateFreeResponseOptions(),...freeResponseWidgetProperties}}
|
|
428
|
+
|
|
429
|
+
function generateGradedGroupOptions(options){return {...gradedGroupWidgetLogic.defaultWidgetOptions,...options}}function generateGradedGroupWidget(gradedGroupWidgetProperties){return {type:"graded-group",graded:false,version:{major:0,minor:0},static:false,alignment:"default",options:generateGradedGroupOptions(),...gradedGroupWidgetProperties}}
|
|
430
|
+
|
|
431
|
+
function generateGradedGroupSetWidget(gradedGroupSetWidgetProperties){return {type:"graded-group-set",graded:false,version:{major:0,minor:0},static:false,alignment:"default",options:{gradedGroups:[]},...gradedGroupSetWidgetProperties}}
|
|
432
|
+
|
|
433
|
+
function generateGroupOptions(options){return {...groupWidgetLogic.defaultWidgetOptions,...options}}function generateGroupWidget(groupWidgetProperties){return {type:"group",graded:true,version:{major:0,minor:0},static:false,alignment:"default",options:generateGroupOptions(),...groupWidgetProperties}}
|
|
434
|
+
|
|
435
|
+
function generateImageOptions(options){const defaultImageOptions={backgroundImage:{}};return {...defaultImageOptions,...options}}function generateImageWidget(imageWidgetProperties){return {type:"image",graded:false,version:{major:0,minor:0},static:false,alignment:"default",options:generateImageOptions({}),...imageWidgetProperties}}
|
|
436
|
+
|
|
437
|
+
function generateInteractiveGraphWidget(interactiveGraphWidgetProperties){return {type:"interactive-graph",graded:true,version:{major:0,minor:0},static:false,alignment:"default",options:generateInteractiveGraphOptions(),...interactiveGraphWidgetProperties}}function generateInteractiveGraphOptions(options){return {...interactiveGraphWidgetLogic.defaultWidgetOptions,...options}}function generateIGAngleGraph(options){return {type:"angle",...options}}function generateIGCircleGraph(options){return {type:"circle",...options}}function generateIGLinearGraph(options){return {type:"linear",...options}}function generateIGLinearSystemGraph(options){return {type:"linear-system",...options}}function generateIGNoneGraph(){return {type:"none"}}function generateIGPointGraph(options){return {type:"point",...options}}function generateIGPolygonGraph(options){return {type:"polygon",...options}}function generateIGQuadraticGraph(options){return {type:"quadratic",...options}}function generateIGRayGraph(options){return {type:"ray",...options}}function generateIGSegmentGraph(options){return {type:"segment",...options}}function generateIGSinusoidGraph(options){return {type:"sinusoid",...options}}function generateIGLockedPoint(options){return {...getDefaultFigureForType("point"),...options}}function generateIGLockedLine(options){return {...getDefaultFigureForType("line"),...options}}function generateIGLockedVector(options){return {...getDefaultFigureForType("vector"),...options}}function generateIGLockedEllipse(options){return {...getDefaultFigureForType("ellipse"),...options}}function generateIGLockedPolygon(options){return {...getDefaultFigureForType("polygon"),...options}}function generateIGLockedFunction(options){return {...getDefaultFigureForType("function"),...options}}function generateIGLockedLabel(options){return {...getDefaultFigureForType("label"),...options}}
|
|
438
|
+
|
|
439
|
+
function generateNumericInputOptions(options){return {...numericInputWidgetLogic.defaultWidgetOptions,static:false,...options}}function generateNumericInputAnswer(answerOptions){return {...numericInputWidgetLogic.defaultWidgetOptions.answers[0],...answerOptions}}function generateNumericInputWidget(numericInputWidgetProperties){return {type:"numeric-input",graded:true,version:{major:0,minor:0},static:false,alignment:"default",options:generateNumericInputOptions(),...numericInputWidgetProperties}}
|
|
440
|
+
|
|
441
|
+
function generateRadioOptions(options){return {...radioWidgetLogic.defaultWidgetOptions,...options}}function generateRadioWidget(radioWidgetProperties){return {type:"radio",graded:true,version:{major:0,minor:0},static:false,alignment:"default",options:generateRadioOptions(),...radioWidgetProperties}}function generateRadioChoice(text,options){return {content:text,id:`radio-choice-${Math.random()}`,correct:false,...options}}function generateSimpleRadioQuestion(options){return generateTestPerseusRenderer({content:"[[☃ radio 1]]",widgets:{"radio 1":generateRadioWidget({options:generateRadioOptions(options)})}})}function generateSimpleRadioItem(options){return generateTestPerseusItem({question:generateSimpleRadioQuestion(options)})}
|
|
417
442
|
|
|
418
443
|
function generateVideoWidget(videoWidgetProperties){return {type:"video",graded:true,version:{major:0,minor:0},static:false,alignment:"default",options:{location:""},...videoWidgetProperties}}
|
|
419
444
|
|
|
445
|
+
const joinOptionContents=options=>options.map(({content})=>content).join("\n");const toOptionLetter=index=>String.fromCharCode("A".charCodeAt(0)+index);function getAnswersFromWidgets(widgets){const answers=[];wonderStuffCore.keys(widgets).forEach(widgetID=>{const widget=widgets[widgetID];if(!widget.options){return}switch(widget.type){case "radio":const radio=widget;const options=radio.options;if(options?.choices?.length){for(const choice of options.choices){if(choice?.correct){answers.push(choice.content);}}}break;case "categorizer":const categorizer=widget;if(categorizer.options?.categories&&categorizer.options?.items&&categorizer.options?.values){const categories=categorizer.options?.categories;const items=categorizer.options?.items;const values=categorizer.options?.values;answers.push(...values.map((value,index)=>`${items[index]}: ${categories[value]}`));}break;case "dropdown":const dropdown=widget;if(dropdown.options?.choices){for(const choice of dropdown.options.choices){if(choice.correct){answers.push(choice.content);}}}break;case "numeric-input":const numericInput=widget;if(numericInput.options?.answers){for(const ans of numericInput.options.answers){if(ans.status==="correct"&&ans.value!=null){answers.push(ans.value.toString());}}}break;case "input-number":const inputNumber=widget;if(inputNumber.options?.value){answers.push(inputNumber.options.value.toString());}break;case "expression":const expression=widget;if(expression.options?.answerForms){answers.push(...expression.options.answerForms.map(answer=>answer.value));}break;case "group":case "graded-group":const gradedGroup=widget;if(gradedGroup.options?.widgets){answers.push(...getAnswersFromWidgets(gradedGroup.options.widgets));}break;case "plotter":const plotter=widget;if(plotter.options?.categories&&plotter.options?.correct&&plotter.options.categories.length===plotter.options.correct.length){const{categories,correct}=plotter.options;answers.push(`{${categories.map((category,index)=>`${category}: ${correct[index]}`).join(", ")}}`);}break;case "interactive-graph":case "grapher":const grapher=widget;if(grapher.options?.correct?.coords){answers.push(`There should be point(s) on [${grapher.options.correct?.coords.join("], [")}]`);}break;case "orderer":const orderer=widget;if(orderer.options?.correctOptions){answers.push(joinOptionContents(orderer.options.correctOptions));}break;case "sorter":const sorter=widget;if(sorter.options?.correct){answers.push(sorter.options.correct.join(", "));}break;case "label-image":const labelImage=widget;if(labelImage.options?.markers){answers.push(...labelImage.options.markers.map(m=>`{label: "${m.label}", position: {${m.x},${m.y}}, answer: "${m.answers.join(", ")}"}`));}break;case "number-line":const numberLine=widget;if(numberLine.options?.correctX!=null){answers.push(numberLine.options.correctX.toString());}break;case "matrix":const matrix=widget;if(matrix.options?.answers){answers.push(`[${matrix.options.answers.join("], [")}]`);}break;case "matcher":const matcher=widget;if(matcher.options?.left&&matcher.options?.right){const{left,right}=matcher.options;const[leftHeader,rightHeader]=matcher.options.labels;const tableHeader=`| ${leftHeader} | ${rightHeader} |
|
|
446
|
+
| --- | --- |`;const tableRows=left.map((leftItem,index)=>{return `| ${leftItem} | ${right[index]} |`});const table=[tableHeader,...tableRows].join("\n");answers.push(table);}break}});return answers}function injectWidgets(content,widgets,widgetProps){if(!content){return ""}if(!widgets){return content}let context=content;wonderStuffCore.keys(widgets).forEach(widgetID=>{const widget=widgets[widgetID];if(!widget.options){return}switch(widget.type){case "radio":const radio=widget;const radioProps=widgetProps?.[widgetID];if(radio.options?.choices?.length){let radioContext=joinOptionContents(radioProps?radioProps.choices.map(({content},i)=>({content:`Option ${toOptionLetter(i)}: ${content}`})):radio.options.choices);if(!radioProps&&radio.options?.randomize){radioContext+="\nThose options are displayed in a different order to the user. If the user says the letter, number, or ordinal number, always ask them clarify which option they are referring to.\n";}context=context.replace(`[[☃ ${widgetID}]]`,radioContext);}break;case "image":const image=widget;if(image.options?.alt){context=context.replace(`[[☃ ${widgetID}]]`,`<img id="${widgetID}" alt="${image.options.alt}">`);}break;case "label-image":const labelImage=widget;if(labelImage.options?.imageAlt){context=context.replace(`[[☃ ${widgetID}]]`,`[An image with dots that user needs to label. Label choices: [${labelImage.options.choices.join(", ")}]. Image alt text: ${labelImage.options?.imageAlt??""}]`);}break;case "explanation":const explanation=widget;if(explanation.options?.explanation){context=context.replace(`[[☃ ${widgetID}]]`,injectWidgets(explanation.options.explanation,explanation.options.widgets));}break;case "passage":const passage=widget;if(passage.options?.passageTitle||passage.options?.passageText){const{passageTitle,passageText}=passage.options;context=context.replace(`[[☃ ${widgetID}]]`,`# ${passageTitle}
|
|
447
|
+
|
|
448
|
+
${passageText}`);}break;case "group":case "graded-group":const group=widget;if(group.options?.widgets&&group.options.content){context=context.replace(`[[☃ ${widgetID}]]`,injectWidgets(group.options.content,group.options.widgets));}break;case "graded-group-set":const gradedGroup=widget;if(gradedGroup.options?.gradedGroups){const gradedGroups=gradedGroup.options.gradedGroups;const gradedGroupsContent=gradedGroups.reduce((acc,group)=>{if(group.widgets&&group.content){acc+=injectWidgets(group.content,group.widgets)+"\n";}return acc},"");context=context.replace(`[[☃ ${widgetID}]]`,gradedGroupsContent);}break;case "categorizer":const categorizer=widget;if(categorizer.options?.categories&&categorizer.options.items){const categories=categorizer.options.categories;const items=categorizer.options.items;context=context.replace(`[[☃ ${widgetID}]]`,`For each item, select the correct category. Categories: ${categories.join(", ")}.
|
|
449
|
+
Items:
|
|
450
|
+
${items.join("\n")}
|
|
451
|
+
`);}break;case "dropdown":const dropdown=widget;if(dropdown.options?.choices){const choices=dropdown.options.choices.map(choice=>choice.content);context=context.replace(`[[☃ ${widgetID}]]`,`[${choices.join(" | ")}]`);}break;case "definition":const definition=widget;if(definition.options?.togglePrompt){context=context.replace(`[[☃ ${widgetID}]]`,definition.options.togglePrompt);}break;case "orderer":const orderer=widget;if(orderer.options?.options){context=context.replace(`[[☃ ${widgetID}]]`,joinOptionContents(orderer.options.options));}break;case "sorter":const sorter=widget;if(sorter.options?.correct){const choices=sorter.options.correct;context=context.replace(`[[☃ ${widgetID}]]`,`[${choices.join(" | ")}]`);}break;case "interactive-graph":const interactiveGraph=widget;if(interactiveGraph.options?.range.length===2){const[x,y]=interactiveGraph.options.range;context=context.replace(`[[☃ ${widgetID}]]`,`[Graph with an x range of ${x[0]} to ${x[1]} and y range of ${y[0]} to ${y[1]}]`);}break;case "number-line":const numberLine=widget;if(numberLine.options?.range.length===2&&numberLine.options?.tickStep&&numberLine.options?.initialX){const[min,max]=numberLine.options.range;const step=numberLine.options.tickStep;const initialPosition=numberLine.options.initialX;context=context.replace(`[[☃ ${widgetID}]]`,`[Number line with a range of ${min} to ${max}, a step of ${step}, and an initial position of ${initialPosition}]`);}break;case "matrix":const matrix=widget;if(matrix.options?.matrixBoardSize.length===2){const[rows,columns]=matrix.options.matrixBoardSize;context=context.replace(`[[☃ ${widgetID}]]`,`[Matrix with ${rows} rows and ${columns} columns. The user can click on each cell to enter a value]`);}break;case "matcher":const matcher=widget;if(matcher.options?.left&&matcher.options?.right){const{left,right}=matcher.options;const[leftHeader,rightHeader]=matcher.options.labels;const tableHeader=`| ${leftHeader} | ${rightHeader} |
|
|
452
|
+
| --- | --- |`;const tableRows=left.map((leftItem,index)=>{return `| ${leftItem} | ${right[index]} |`});const table=[tableHeader,...tableRows].join("\n");const matcherWidgetExplanation="The user needs to move items in the right column to match the correct option on the left. The order of items on the right side will be different from what the user sees.";context=context.replace(`[[☃ ${widgetID}]]`,`${matcherWidgetExplanation}
|
|
453
|
+
${table}`);}break;case "numeric-input":case "input-number":case "expression":context=context.replace(`[[☃ ${widgetID}]]`,"?");break;default:context=context.replace(`[[☃ ${widgetID}]]`,`[[Unsupported ${widget.type} widget: Explain to the user that you are unable to understand the content in this widget and ask them to describe it.]]`);}});return context}function getPerseusAIData(perseusItem){const answers=getAnswersFromWidgets(perseusItem.question.widgets);const hints=perseusItem.hints.map(hint=>injectWidgets(hint.content,hint.widgets));return {answers,hints}}
|
|
454
|
+
|
|
420
455
|
registerCoreWidgets();
|
|
421
456
|
|
|
422
457
|
exports.CoreWidgetRegistry = coreWidgetRegistry;
|
|
@@ -443,17 +478,63 @@ exports.dropdownLogic = dropdownWidgetLogic;
|
|
|
443
478
|
exports.explanationLogic = explanationWidgetLogic;
|
|
444
479
|
exports.expressionLogic = expressionWidgetLogic;
|
|
445
480
|
exports.freeResponseLogic = freeResponseWidgetLogic;
|
|
481
|
+
exports.generateDefinitionOptions = generateDefinitionOptions;
|
|
482
|
+
exports.generateDefinitionWidget = generateDefinitionWidget;
|
|
483
|
+
exports.generateDropdownOptions = generateDropdownOptions;
|
|
484
|
+
exports.generateDropdownWidget = generateDropdownWidget;
|
|
485
|
+
exports.generateExplanationOptions = generateExplanationOptions;
|
|
486
|
+
exports.generateExplanationWidget = generateExplanationWidget;
|
|
487
|
+
exports.generateExpressionAnswerForm = generateExpressionAnswerForm;
|
|
488
|
+
exports.generateExpressionOptions = generateExpressionOptions;
|
|
489
|
+
exports.generateExpressionWidget = generateExpressionWidget;
|
|
490
|
+
exports.generateFreeResponseOptions = generateFreeResponseOptions;
|
|
491
|
+
exports.generateFreeResponseWidget = generateFreeResponseWidget;
|
|
492
|
+
exports.generateGradedGroupOptions = generateGradedGroupOptions;
|
|
493
|
+
exports.generateGradedGroupSetWidget = generateGradedGroupSetWidget;
|
|
494
|
+
exports.generateGradedGroupWidget = generateGradedGroupWidget;
|
|
495
|
+
exports.generateGroupOptions = generateGroupOptions;
|
|
496
|
+
exports.generateGroupWidget = generateGroupWidget;
|
|
497
|
+
exports.generateIGAngleGraph = generateIGAngleGraph;
|
|
498
|
+
exports.generateIGCircleGraph = generateIGCircleGraph;
|
|
499
|
+
exports.generateIGLinearGraph = generateIGLinearGraph;
|
|
500
|
+
exports.generateIGLinearSystemGraph = generateIGLinearSystemGraph;
|
|
501
|
+
exports.generateIGLockedEllipse = generateIGLockedEllipse;
|
|
502
|
+
exports.generateIGLockedFunction = generateIGLockedFunction;
|
|
503
|
+
exports.generateIGLockedLabel = generateIGLockedLabel;
|
|
504
|
+
exports.generateIGLockedLine = generateIGLockedLine;
|
|
505
|
+
exports.generateIGLockedPoint = generateIGLockedPoint;
|
|
506
|
+
exports.generateIGLockedPolygon = generateIGLockedPolygon;
|
|
507
|
+
exports.generateIGLockedVector = generateIGLockedVector;
|
|
508
|
+
exports.generateIGNoneGraph = generateIGNoneGraph;
|
|
509
|
+
exports.generateIGPointGraph = generateIGPointGraph;
|
|
510
|
+
exports.generateIGPolygonGraph = generateIGPolygonGraph;
|
|
511
|
+
exports.generateIGQuadraticGraph = generateIGQuadraticGraph;
|
|
512
|
+
exports.generateIGRayGraph = generateIGRayGraph;
|
|
513
|
+
exports.generateIGSegmentGraph = generateIGSegmentGraph;
|
|
514
|
+
exports.generateIGSinusoidGraph = generateIGSinusoidGraph;
|
|
446
515
|
exports.generateImageOptions = generateImageOptions;
|
|
447
516
|
exports.generateImageWidget = generateImageWidget;
|
|
517
|
+
exports.generateInteractiveGraphOptions = generateInteractiveGraphOptions;
|
|
518
|
+
exports.generateInteractiveGraphWidget = generateInteractiveGraphWidget;
|
|
519
|
+
exports.generateNumericInputAnswer = generateNumericInputAnswer;
|
|
520
|
+
exports.generateNumericInputOptions = generateNumericInputOptions;
|
|
521
|
+
exports.generateNumericInputWidget = generateNumericInputWidget;
|
|
522
|
+
exports.generateRadioChoice = generateRadioChoice;
|
|
523
|
+
exports.generateRadioOptions = generateRadioOptions;
|
|
524
|
+
exports.generateRadioWidget = generateRadioWidget;
|
|
525
|
+
exports.generateSimpleRadioItem = generateSimpleRadioItem;
|
|
526
|
+
exports.generateSimpleRadioQuestion = generateSimpleRadioQuestion;
|
|
448
527
|
exports.generateTestPerseusItem = generateTestPerseusItem;
|
|
449
528
|
exports.generateTestPerseusRenderer = generateTestPerseusRenderer;
|
|
450
529
|
exports.generateVideoWidget = generateVideoWidget;
|
|
530
|
+
exports.getAnswersFromWidgets = getAnswersFromWidgets;
|
|
451
531
|
exports.getBaseUrl = getBaseUrl;
|
|
452
532
|
exports.getCSProgramPublicWidgetOptions = getCSProgramPublicWidgetOptions;
|
|
453
533
|
exports.getCategorizerPublicWidgetOptions = getCategorizerPublicWidgetOptions;
|
|
454
534
|
exports.getDataUrl = getDataUrl;
|
|
455
535
|
exports.getDecimalSeparator = getDecimalSeparator;
|
|
456
536
|
exports.getDefaultAnswerArea = getDefaultAnswerArea;
|
|
537
|
+
exports.getDefaultFigureForType = getDefaultFigureForType;
|
|
457
538
|
exports.getDivideSymbol = getDivideSymbol;
|
|
458
539
|
exports.getDivideSymbolForTex = getDivideSymbolForTex;
|
|
459
540
|
exports.getDropdownPublicWidgetOptions = getDropdownPublicWidgetOptions;
|
|
@@ -471,6 +552,7 @@ exports.getMatrixSize = getMatrixSize;
|
|
|
471
552
|
exports.getNumberLinePublicWidgetOptions = getNumberLinePublicWidgetOptions;
|
|
472
553
|
exports.getNumericInputPublicWidgetOptions = getNumericInputPublicWidgetOptions;
|
|
473
554
|
exports.getOrdererPublicWidgetOptions = getOrdererPublicWidgetOptions;
|
|
555
|
+
exports.getPerseusAIData = getPerseusAIData;
|
|
474
556
|
exports.getPlotterPublicWidgetOptions = getPlotterPublicWidgetOptions;
|
|
475
557
|
exports.getRadioPublicWidgetOptions = getRadioPublicWidgetOptions;
|
|
476
558
|
exports.getRealImageUrl = getRealImageUrl;
|
|
@@ -485,6 +567,7 @@ exports.grapherLogic = grapherWidgetLogic;
|
|
|
485
567
|
exports.groupLogic = groupWidgetLogic;
|
|
486
568
|
exports.iframeLogic = iframeWidgetLogic;
|
|
487
569
|
exports.imageLogic = imageWidgetLogic;
|
|
570
|
+
exports.injectWidgets = injectWidgets;
|
|
488
571
|
exports.inputNumberLogic = inputNumberWidgetLogic;
|
|
489
572
|
exports.interactionLogic = interactionWidgetLogic;
|
|
490
573
|
exports.interactiveGraphLogic = interactiveGraphWidgetLogic;
|