@khanacademy/perseus-core 40.1.0 → 41.0.0

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.
@@ -166,14 +166,14 @@ export interface PerseusWidgetTypes {
166
166
  sorter: SorterWidget;
167
167
  table: TableWidget;
168
168
  video: VideoWidget;
169
- "molecule-renderer": DeprecatedStandinWidget;
170
- "passage-ref-target": DeprecatedStandinWidget;
171
- "passage-ref": DeprecatedStandinWidget;
172
- passage: DeprecatedStandinWidget;
173
- "lights-puzzle": DeprecatedStandinWidget;
174
- sequence: DeprecatedStandinWidget;
175
- simulator: DeprecatedStandinWidget;
176
- transformer: DeprecatedStandinWidget;
169
+ "molecule-renderer": DeprecatedStandinWidget<"molecule-renderer">;
170
+ "passage-ref-target": DeprecatedStandinWidget<"passage-ref-target">;
171
+ "passage-ref": DeprecatedStandinWidget<"passage-ref">;
172
+ passage: DeprecatedStandinWidget<"passage">;
173
+ "lights-puzzle": DeprecatedStandinWidget<"lights-puzzle">;
174
+ sequence: DeprecatedStandinWidget<"sequence">;
175
+ simulator: DeprecatedStandinWidget<"simulator">;
176
+ transformer: DeprecatedStandinWidget<"transformer">;
177
177
  }
178
178
  /**
179
179
  * A map of widget IDs to widget options. This is most often used as the type
@@ -394,7 +394,7 @@ export type SorterWidget = WidgetOptions<'sorter', PerseusSorterWidgetOptions>;
394
394
  export type TableWidget = WidgetOptions<'table', PerseusTableWidgetOptions>;
395
395
  export type InputNumberWidget = WidgetOptions<'input-number', PerseusInputNumberWidgetOptions>;
396
396
  export type VideoWidget = WidgetOptions<'video', PerseusVideoWidgetOptions>;
397
- export type DeprecatedStandinWidget = WidgetOptions<'deprecated-standin', object>;
397
+ export type DeprecatedStandinWidget<Type extends string> = WidgetOptions<Type, object>;
398
398
  /**
399
399
  * A background image applied to various widgets.
400
400
  */
@@ -1276,6 +1276,7 @@ type VectorGraphCorrect = {
1276
1276
  match?: "exact" | "congruent";
1277
1277
  };
1278
1278
  export type PerseusGraphCorrectType = AbsoluteValueGraphCorrect | AngleGraphCorrect | CircleGraphCorrect | LinearGraphCorrect | LinearSystemGraphCorrect | NoneGraphCorrect | PointGraphCorrect | PolygonGraphCorrect | QuadraticGraphCorrect | RayGraphCorrect | SegmentGraphCorrect | SinusoidGraphCorrect | ExponentialGraphCorrect | TangentGraphCorrect | LogarithmGraphCorrect | VectorGraphCorrect;
1279
+ export type PreferredPopoverDirection = "NONE" | "UP" | "DOWN" | "LEFT" | "RIGHT";
1279
1280
  /** Options for the label-image widget. Asks learners to label image parts. */
1280
1281
  export type PerseusLabelImageWidgetOptions = {
1281
1282
  /** Translatable Text; TeX representation of choices */
@@ -1294,6 +1295,8 @@ export type PerseusLabelImageWidgetOptions = {
1294
1295
  hideChoicesFromInstructions: boolean;
1295
1296
  /** Allow multiple answers per marker */
1296
1297
  multipleAnswers: boolean;
1298
+ /** Determines the placement of the list of choices for each marker */
1299
+ preferredPopoverDirection?: PreferredPopoverDirection;
1297
1300
  };
1298
1301
  export type PerseusLabelImageMarker = {
1299
1302
  /**
@@ -1654,7 +1657,10 @@ export type PerseusInteractionWidgetOptions = {
1654
1657
  elements: PerseusInteractionElement[];
1655
1658
  };
1656
1659
  export type PerseusInteractionGraph = {
1657
- /** "canvas", "graph" */
1660
+ /**
1661
+ * "canvas", "graph"
1662
+ * @deprecated - not used
1663
+ */
1658
1664
  editableSettings?: Array<"canvas" | "graph">;
1659
1665
  /** The Grid Canvas size. e.g. [400, 140] */
1660
1666
  box: Size;
package/dist/index.js CHANGED
@@ -146,7 +146,7 @@ const pairOfNumbers$1=pair(number,number);const stringOrEmpty=defaulted(string,(
146
146
 
147
147
  const pairOfNumbers=pair(number,number);const parsePerseusGraphTypeAngle=object({type:constant("angle"),showAngles:optional(boolean),allowReflexAngles:optional(boolean),angleOffsetDeg:optional(nullable(number)),snapDegrees:optional(number),match:optional(constant("congruent")),coords:optional(trio(pairOfNumbers,pairOfNumbers,pairOfNumbers)),startCoords:optional(trio(pairOfNumbers,pairOfNumbers,pairOfNumbers)),pointLabels:optional(trio(string,string,string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeCircle=object({type:constant("circle"),center:optional(pairOfNumbers),radius:optional(number),startCoords:optional(object({center:pairOfNumbers,radius:number})),pointLabels:optional(array(string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeLinear=object({type:constant("linear"),coords:optional(nullable(pair(pairOfNumbers,pairOfNumbers))),startCoords:optional(pair(pairOfNumbers,pairOfNumbers)),pointLabels:optional(pair(string,string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeLinearSystem=object({type:constant("linear-system"),coords:optional(nullable(array(pair(pairOfNumbers,pairOfNumbers)))),startCoords:optional(array(pair(pairOfNumbers,pairOfNumbers))),pointLabels:optional(array(string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeNone=object({type:constant("none")});const parsePerseusGraphTypePoint=object({type:constant("point"),numPoints:optional(union(number).or(constant("unlimited")).parser),coords:optional(nullable(array(pairOfNumbers))),startCoords:optional(array(pairOfNumbers)),coord:optional(pairOfNumbers),pointLabels:optional(array(string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypePolygon=object({type:constant("polygon"),numSides:optional(union(number).or(constant("unlimited")).parser),showAngles:optional(boolean),showSides:optional(boolean),snapTo:optional(enumeration("grid","angles","sides")),match:optional(enumeration("similar","congruent","approx","exact")),startCoords:optional(array(pairOfNumbers)),coords:optional(nullable(array(pairOfNumbers))),pointLabels:optional(array(string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeQuadratic=object({type:constant("quadratic"),coords:optional(nullable(trio(pairOfNumbers,pairOfNumbers,pairOfNumbers))),startCoords:optional(trio(pairOfNumbers,pairOfNumbers,pairOfNumbers)),pointLabels:optional(trio(string,string,string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeRay=object({type:constant("ray"),coords:optional(nullable(pair(pairOfNumbers,pairOfNumbers))),startCoords:optional(pair(pairOfNumbers,pairOfNumbers)),pointLabels:optional(pair(string,string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeSegment=object({type:constant("segment"),numSegments:optional(number),coords:optional(nullable(array(pair(pairOfNumbers,pairOfNumbers)))),startCoords:optional(array(pair(pairOfNumbers,pairOfNumbers))),pointLabels:optional(array(string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeSinusoid=object({type:constant("sinusoid"),coords:optional(nullable(pair(pairOfNumbers,pairOfNumbers))),startCoords:optional(pair(pairOfNumbers,pairOfNumbers)),pointLabels:optional(array(string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeExponential=object({type:constant("exponential"),coords:optional(nullable(pair(pairOfNumbers,pairOfNumbers))),asymptote:optional(nullable(number)),startCoords:optional(object({coords:pair(pairOfNumbers,pairOfNumbers),asymptote:number})),pointLabels:optional(array(string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeAbsoluteValue=object({type:constant("absolute-value"),coords:optional(nullable(pair(pairOfNumbers,pairOfNumbers))),startCoords:optional(pair(pairOfNumbers,pairOfNumbers)),pointLabels:optional(pair(string,string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeTangent=object({type:constant("tangent"),coords:optional(nullable(pair(pairOfNumbers,pairOfNumbers))),startCoords:optional(pair(pairOfNumbers,pairOfNumbers)),pointLabels:optional(array(string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeLogarithm=object({type:constant("logarithm"),coords:optional(nullable(pair(pairOfNumbers,pairOfNumbers))),asymptote:optional(nullable(number)),startCoords:optional(object({coords:pair(pairOfNumbers,pairOfNumbers),asymptote:number})),pointLabels:optional(array(string)),showPointLabels:optional(boolean)});const parsePerseusGraphTypeVector=object({type:constant("vector"),coords:optional(nullable(pair(pairOfNumbers,pairOfNumbers))),startCoords:optional(pair(pairOfNumbers,pairOfNumbers)),match:optional(enumeration("exact","congruent"))});const parsePerseusGraphType=discriminatedUnionOn("type").withBranch("absolute-value",parsePerseusGraphTypeAbsoluteValue).withBranch("angle",parsePerseusGraphTypeAngle).withBranch("circle",parsePerseusGraphTypeCircle).withBranch("exponential",parsePerseusGraphTypeExponential).withBranch("linear",parsePerseusGraphTypeLinear).withBranch("linear-system",parsePerseusGraphTypeLinearSystem).withBranch("none",parsePerseusGraphTypeNone).withBranch("point",parsePerseusGraphTypePoint).withBranch("polygon",parsePerseusGraphTypePolygon).withBranch("quadratic",parsePerseusGraphTypeQuadratic).withBranch("ray",parsePerseusGraphTypeRay).withBranch("segment",parsePerseusGraphTypeSegment).withBranch("sinusoid",parsePerseusGraphTypeSinusoid).withBranch("tangent",parsePerseusGraphTypeTangent).withBranch("logarithm",parsePerseusGraphTypeLogarithm).withBranch("vector",parsePerseusGraphTypeVector).parser;const parseLockedFigureColor=pipeParsers(enumeration("blue","gold","green","grayH","purple","pink","red","orange")).then(convert(color=>color==="orange"?"gold":color)).parser;const parseLockedFigureFillType=enumeration("none","white","translucent","solid");const parseLockedLineStyle=enumeration("solid","dashed");const parseLockedFigureStrokeStyle=enumeration("solid","dashed","none");const parseStrokeWeight=defaulted(enumeration("medium","thin","thick"),()=>"medium");const parseLockedLabelType=object({type:constant("label"),coord:pairOfNumbers,text:defaulted(string,()=>""),color:defaulted(parseLockedFigureColor,()=>"grayH"),size:defaulted(enumeration("small","medium","large"),()=>"medium")});const parseLockedPointType=object({type:constant("point"),coord:pairOfNumbers,color:parseLockedFigureColor,filled:boolean,labels:defaulted(array(parseLockedLabelType),()=>[]),ariaLabel:optional(string)});const parseLockedLineType=object({type:constant("line"),kind:enumeration("line","ray","segment"),points:pair(parseLockedPointType,parseLockedPointType),color:parseLockedFigureColor,lineStyle:parseLockedLineStyle,showPoint1:defaulted(boolean,()=>false),showPoint2:defaulted(boolean,()=>false),weight:parseStrokeWeight,labels:defaulted(array(parseLockedLabelType),()=>[]),ariaLabel:optional(string)});const parseLockedVectorType=object({type:constant("vector"),points:pair(pairOfNumbers,pairOfNumbers),color:parseLockedFigureColor,weight:parseStrokeWeight,labels:defaulted(array(parseLockedLabelType),()=>[]),ariaLabel:optional(string)});const parseLockedEllipseType=object({type:constant("ellipse"),center:pairOfNumbers,radius:pairOfNumbers,angle:number,color:parseLockedFigureColor,fillStyle:parseLockedFigureFillType,strokeStyle:parseLockedFigureStrokeStyle,weight:parseStrokeWeight,labels:defaulted(array(parseLockedLabelType),()=>[]),ariaLabel:optional(string)});const parseLockedPolygonType=object({type:constant("polygon"),points:array(pairOfNumbers),color:parseLockedFigureColor,showVertices:boolean,fillStyle:parseLockedFigureFillType,strokeStyle:parseLockedFigureStrokeStyle,weight:parseStrokeWeight,labels:defaulted(array(parseLockedLabelType),()=>[]),ariaLabel:optional(string)});const numberOrNegativeInfinity=union(number).or(constant(-Infinity)).parser;const numberOrPositiveInfinity=union(number).or(constant(Infinity)).parser;const parseLockedFunctionDomain=defaulted(pair(defaulted(numberOrNegativeInfinity,()=>-Infinity),defaulted(numberOrPositiveInfinity,()=>Infinity)),()=>[-Infinity,Infinity]);const parseLockedFunctionType=object({type:constant("function"),color:parseLockedFigureColor,strokeStyle:parseLockedLineStyle,weight:parseStrokeWeight,equation:string,directionalAxis:enumeration("x","y"),domain:parseLockedFunctionDomain,labels:defaulted(array(parseLockedLabelType),()=>[]),ariaLabel:optional(string)});const parseLockedFigure=discriminatedUnionOn("type").withBranch("point",parseLockedPointType).withBranch("line",parseLockedLineType).withBranch("vector",parseLockedVectorType).withBranch("ellipse",parseLockedEllipseType).withBranch("polygon",parseLockedPolygonType).withBranch("function",parseLockedFunctionType).withBranch("label",parseLockedLabelType).parser;const parseLabelLocation=pipeParsers(enumeration("onAxis","alongEdge","",null,undefined)).then(convert(value=>value||"onAxis")).parser;const parseInteractiveGraphWidget=parseWidget(constant("interactive-graph"),object({step:pairOfNumbers,gridStep:optional(pairOfNumbers),snapStep:optional(pairOfNumbers),backgroundImage:defaulted(parsePerseusImageBackground,()=>({url:null})),markings:enumeration("graph","grid","none","axes"),labels:defaulted(array(string),()=>["$x$","$y$"]),labelLocation:parseLabelLocation,showProtractor:boolean,showRuler:optional(boolean),showTooltips:defaulted(boolean,()=>false),rulerLabel:optional(string),rulerTicks:optional(number),range:pair(pairOfNumbers,pairOfNumbers),showAxisArrows:defaulted(object({xMin:boolean,xMax:boolean,yMin:boolean,yMax:boolean}),()=>({xMin:true,xMax:true,yMin:true,yMax:true})),showAxisTicks:defaulted(object({x:boolean,y:boolean}),()=>({x:true,y:true})),graph:defaulted(parsePerseusGraphType,()=>({type:"linear"})),correct:defaulted(parsePerseusGraphType,()=>({type:"linear"})),lockedFigures:defaulted(array(parseLockedFigure),()=>[]),fullGraphAriaLabel:optional(string),fullGraphAriaDescription:optional(string)}));
148
148
 
149
- const parseLabelImageWidget=parseWidget(constant("label-image"),object({choices:array(string),imageUrl:string,imageAlt:string,imageHeight:number,imageWidth:number,markers:array(object({answers:defaulted(array(string),()=>[]),label:string,x:number,y:number})),hideChoicesFromInstructions:boolean,multipleAnswers:boolean}));
149
+ const parsePreferredPopoverDirection=enumeration("NONE","UP","DOWN","LEFT","RIGHT");const parseLabelImageWidget=parseWidget(constant("label-image"),object({choices:array(string),imageUrl:string,imageAlt:string,imageHeight:number,imageWidth:number,markers:array(object({answers:defaulted(array(string),()=>[]),label:string,x:number,y:number})),hideChoicesFromInstructions:boolean,multipleAnswers:boolean,preferredPopoverDirection:optional(parsePreferredPopoverDirection)}));
150
150
 
151
151
  const matcherOptions=object({labels:array(string),left:array(string),right:array(string),orderMatters:boolean,padding:boolean});function getDefaultOptions$1(){return {left:["$x$","$y$","$z$"],right:["$1$","$2$","$3$"],labels:["test","label"],orderMatters:false,padding:true}}const parseMatcherWidget=parseWidget(constant("matcher"),defaulted(matcherOptions,getDefaultOptions$1));
152
152
 
@@ -178,7 +178,7 @@ const parseVideoWidget=parseWidget(constant("video"),object({location:string}),{
178
178
 
179
179
  const parseStringToNonNegativeInt=(rawValue,ctx)=>{if(typeof rawValue!=="string"||!/^(0|[1-9][0-9]*)$/.test(rawValue)){return ctx.failure("a string representing a non-negative integer",rawValue)}return ctx.success(+rawValue)};const parseWidgetIdComponents=pair(string,parseStringToNonNegativeInt);
180
180
 
181
- const parseWidgetsMap=(rawValue,ctx)=>{if(!isPlainObject(rawValue)){return ctx.failure("PerseusWidgetsMap",rawValue)}const widgetsMap={};for(const key of Object.keys(rawValue)){const entryResult=parseWidgetsMapEntry([key,rawValue[key]],widgetsMap,ctx.forSubtree(key));if(isFailure(entryResult)){return entryResult}}return ctx.success(widgetsMap)};const parseWidgetsMapEntry=([id,widget],widgetMap,ctx)=>{const idComponentsResult=parseWidgetIdComponents(id.split(" "),ctx.forSubtree("(widget ID)"));if(isFailure(idComponentsResult)){return idComponentsResult}const[type,n]=idComponentsResult.value;function parseAndAssign(key,parse){const widgetResult=parse(widget,ctx);if(isFailure(widgetResult)){return widgetResult}widgetMap[key]=widgetResult.value;return ctx.success(undefined)}switch(type){case "blank":return parseAndAssign(`blank ${n}`,parseBlankWidget);case "categorizer":return parseAndAssign(`categorizer ${n}`,parseCategorizerWidget);case "cs-program":return parseAndAssign(`cs-program ${n}`,parseCSProgramWidget);case "definition":return parseAndAssign(`definition ${n}`,parseDefinitionWidget);case "dropdown":return parseAndAssign(`dropdown ${n}`,parseDropdownWidget);case "explanation":return parseAndAssign(`explanation ${n}`,parseExplanationWidget);case "expression":return parseAndAssign(`expression ${n}`,parseExpressionWidget);case "fill-in-the-blank":return parseAndAssign(`fill-in-the-blank ${n}`,parseFillInTheBlankWidget);case "free-response":return parseAndAssign(`free-response ${n}`,parseFreeResponseWidget);case "grapher":return parseAndAssign(`grapher ${n}`,parseGrapherWidget);case "group":return parseAndAssign(`group ${n}`,parseGroupWidget);case "graded-group":return parseAndAssign(`graded-group ${n}`,parseGradedGroupWidget);case "graded-group-set":return parseAndAssign(`graded-group-set ${n}`,parseGradedGroupSetWidget);case "iframe":return parseAndAssign(`iframe ${n}`,parseIframeWidget);case "image":return parseAndAssign(`image ${n}`,parseImageWidget);case "input-number":return parseAndAssign(`input-number ${n}`,parseInputNumberWidget);case "interaction":return parseAndAssign(`interaction ${n}`,parseInteractionWidget);case "interactive-graph":return parseAndAssign(`interactive-graph ${n}`,parseInteractiveGraphWidget);case "label-image":return parseAndAssign(`label-image ${n}`,parseLabelImageWidget);case "matcher":return parseAndAssign(`matcher ${n}`,parseMatcherWidget);case "matrix":return parseAndAssign(`matrix ${n}`,parseMatrixWidget);case "measurer":return parseAndAssign(`measurer ${n}`,parseMeasurerWidget);case "molecule-renderer":return parseAndAssign(`molecule-renderer ${n}`,parseDeprecatedWidget);case "number-line":return parseAndAssign(`number-line ${n}`,parseNumberLineWidget);case "numeric-input":return parseAndAssign(`numeric-input ${n}`,parseNumericInputWidget);case "orderer":return parseAndAssign(`orderer ${n}`,parseOrdererWidget);case "phet-simulation":return parseAndAssign(`phet-simulation ${n}`,parsePhetSimulationWidget);case "plotter":return parseAndAssign(`plotter ${n}`,parsePlotterWidget);case "python-program":return parseAndAssign(`python-program ${n}`,parsePythonProgramWidget);case "radio":return parseAndAssign(`radio ${n}`,parseRadioWidget);case "sorter":return parseAndAssign(`sorter ${n}`,parseSorterWidget);case "table":return parseAndAssign(`table ${n}`,parseTableWidget);case "video":return parseAndAssign(`video ${n}`,parseVideoWidget);case "sequence":return parseAndAssign(`sequence ${n}`,parseDeprecatedWidget);case "lights-puzzle":return parseAndAssign(`lights-puzzle ${n}`,parseDeprecatedWidget);case "simulator":return parseAndAssign(`simulator ${n}`,parseDeprecatedWidget);case "transformer":return parseAndAssign(`transformer ${n}`,parseDeprecatedWidget);case "passage":return parseAndAssign(`passage ${n}`,parseDeprecatedWidget);case "passage-ref":return parseAndAssign(`passage-ref ${n}`,parseDeprecatedWidget);case "passage-ref-target":return parseAndAssign(`passage-ref-target ${n}`,parseDeprecatedWidget);default:return parseAndAssign(`${type} ${n}`,parseWidget(constant(type),any))}};const parseDeprecatedWidget=parseWidget((_,ctx)=>ctx.success("deprecated-standin"),looseObject({}));
181
+ const parseWidgetsMap=(rawValue,ctx)=>{if(!isPlainObject(rawValue)){return ctx.failure("PerseusWidgetsMap",rawValue)}const widgetsMap={};for(const key of Object.keys(rawValue)){const entryResult=parseWidgetsMapEntry([key,rawValue[key]],widgetsMap,ctx.forSubtree(key));if(isFailure(entryResult)){return entryResult}}return ctx.success(widgetsMap)};const parseWidgetsMapEntry=([id,widget],widgetMap,ctx)=>{const idComponentsResult=parseWidgetIdComponents(id.split(" "),ctx.forSubtree("(widget ID)"));if(isFailure(idComponentsResult)){return idComponentsResult}const[type,n]=idComponentsResult.value;function parseAndAssign(key,parse){const widgetResult=parse(widget,ctx);if(isFailure(widgetResult)){return widgetResult}widgetMap[key]=widgetResult.value;return ctx.success(undefined)}switch(type){case "blank":return parseAndAssign(`blank ${n}`,parseBlankWidget);case "categorizer":return parseAndAssign(`categorizer ${n}`,parseCategorizerWidget);case "cs-program":return parseAndAssign(`cs-program ${n}`,parseCSProgramWidget);case "definition":return parseAndAssign(`definition ${n}`,parseDefinitionWidget);case "dropdown":return parseAndAssign(`dropdown ${n}`,parseDropdownWidget);case "explanation":return parseAndAssign(`explanation ${n}`,parseExplanationWidget);case "expression":return parseAndAssign(`expression ${n}`,parseExpressionWidget);case "fill-in-the-blank":return parseAndAssign(`fill-in-the-blank ${n}`,parseFillInTheBlankWidget);case "free-response":return parseAndAssign(`free-response ${n}`,parseFreeResponseWidget);case "grapher":return parseAndAssign(`grapher ${n}`,parseGrapherWidget);case "group":return parseAndAssign(`group ${n}`,parseGroupWidget);case "graded-group":return parseAndAssign(`graded-group ${n}`,parseGradedGroupWidget);case "graded-group-set":return parseAndAssign(`graded-group-set ${n}`,parseGradedGroupSetWidget);case "iframe":return parseAndAssign(`iframe ${n}`,parseIframeWidget);case "image":return parseAndAssign(`image ${n}`,parseImageWidget);case "input-number":return parseAndAssign(`input-number ${n}`,parseInputNumberWidget);case "interaction":return parseAndAssign(`interaction ${n}`,parseInteractionWidget);case "interactive-graph":return parseAndAssign(`interactive-graph ${n}`,parseInteractiveGraphWidget);case "label-image":return parseAndAssign(`label-image ${n}`,parseLabelImageWidget);case "matcher":return parseAndAssign(`matcher ${n}`,parseMatcherWidget);case "matrix":return parseAndAssign(`matrix ${n}`,parseMatrixWidget);case "measurer":return parseAndAssign(`measurer ${n}`,parseMeasurerWidget);case "molecule-renderer":return parseAndAssign(`molecule-renderer ${n}`,parseDeprecatedWidget("molecule-renderer"));case "number-line":return parseAndAssign(`number-line ${n}`,parseNumberLineWidget);case "numeric-input":return parseAndAssign(`numeric-input ${n}`,parseNumericInputWidget);case "orderer":return parseAndAssign(`orderer ${n}`,parseOrdererWidget);case "phet-simulation":return parseAndAssign(`phet-simulation ${n}`,parsePhetSimulationWidget);case "plotter":return parseAndAssign(`plotter ${n}`,parsePlotterWidget);case "python-program":return parseAndAssign(`python-program ${n}`,parsePythonProgramWidget);case "radio":return parseAndAssign(`radio ${n}`,parseRadioWidget);case "sorter":return parseAndAssign(`sorter ${n}`,parseSorterWidget);case "table":return parseAndAssign(`table ${n}`,parseTableWidget);case "video":return parseAndAssign(`video ${n}`,parseVideoWidget);case "sequence":return parseAndAssign(`sequence ${n}`,parseDeprecatedWidget("sequence"));case "lights-puzzle":return parseAndAssign(`lights-puzzle ${n}`,parseDeprecatedWidget("lights-puzzle"));case "simulator":return parseAndAssign(`simulator ${n}`,parseDeprecatedWidget("simulator"));case "transformer":return parseAndAssign(`transformer ${n}`,parseDeprecatedWidget("transformer"));case "passage":return parseAndAssign(`passage ${n}`,parseDeprecatedWidget("passage"));case "passage-ref":return parseAndAssign(`passage-ref ${n}`,parseDeprecatedWidget("passage-ref"));case "passage-ref-target":return parseAndAssign(`passage-ref-target ${n}`,parseDeprecatedWidget("passage-ref-target"));default:return parseAndAssign(`${type} ${n}`,parseWidget(constant(type),any))}};function parseDeprecatedWidget(type){return parseWidget(constant(type),looseObject({}))}
182
182
 
183
183
  const parsePerseusRenderer=defaulted(object({content:defaulted(string,()=>""),widgets:defaulted((rawVal,ctx)=>parseWidgetsMap(rawVal,ctx),()=>({})),images:parseImages,metadata:any}),()=>({content:"",widgets:{},images:{}}));
184
184
 
@@ -232,7 +232,7 @@ const parseUserInputMap=(rawValue,ctx)=>{if(!isPlainObject(rawValue)){return ctx
232
232
 
233
233
  function parseAndMigratePerseusItem(data){const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parsePerseusItem);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}function parseAndMigratePerseusArticle(data){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 parseAndMigratePerseusRenderer(data){const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parsePerseusRenderer);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}
234
234
 
235
- const libName="@khanacademy/perseus-core";const libVersion="40.1.0";addLibraryVersionToPerseusDebug(libName,libVersion);
235
+ const libName="@khanacademy/perseus-core";const libVersion="41.0.0";addLibraryVersionToPerseusDebug(libName,libVersion);
236
236
 
237
237
  const Errors=Object.freeze({Unknown:"Unknown",Internal:"Internal",InvalidInput:"InvalidInput",NotAllowed:"NotAllowed",TransientService:"TransientService",Service:"Service"});
238
238
 
@@ -244,7 +244,7 @@ const pluck=function(table,subKey){return _.object(_.map(table,function(value,ke
244
244
 
245
245
  function getBlankPublicWidgetOptions(options){const{correctId,...publicWidgetOptions}=options;return publicWidgetOptions}
246
246
 
247
- const blankWidgetLogic={name:"blank",version:{major:0,minor:0},defaultAlignment:"inline-block",getPublicWidgetOptions:getBlankPublicWidgetOptions,accessible:true};
247
+ const defaultWidgetOptions$v={displayType:"normal",correctId:""};const blankWidgetLogic={name:"blank",version:{major:0,minor:0},defaultWidgetOptions: defaultWidgetOptions$v,defaultAlignment:"inline-block",getPublicWidgetOptions:getBlankPublicWidgetOptions,accessible:true};
248
248
 
249
249
  function getCategorizerPublicWidgetOptions(options){return {items:options.items,categories:options.categories,randomizeItems:options.randomizeItems}}
250
250
 
@@ -268,7 +268,7 @@ const currentVersion$1={major:2,minor:0};const defaultWidgetOptions$p={answerFor
268
268
 
269
269
  class Registry{throwIfUnregistered(){if(!this.anythingRegistered){throw new Error(`${this.name} accessed before initialization!`)}}has(key){this.throwIfUnregistered();return Object.prototype.hasOwnProperty.call(this.contents,key)}get(key){this.throwIfUnregistered();return this.contents[key]}keys(){this.throwIfUnregistered();return Object.keys(this.contents)}entries(){this.throwIfUnregistered();return Object.entries(this.contents)}set(key,value){this.anythingRegistered=true;this.contents[key]=value;}constructor(name="Registry"){this.contents={};this.anythingRegistered=false;this.name=name;}}
270
270
 
271
- const deprecatedStandinWidgetLogic={name:"deprecated-standin",accessible:true};
271
+ const deprecatedStandinWidgetLogic={name:"deprecated-standin",defaultWidgetOptions:{},accessible:true};
272
272
 
273
273
  const defaultWidgetOptions$o={title:"",content:"",widgets:{},images:{},hint:null};const traverseChildWidgets$3=function(props,traverseRenderer){return {...props,...traverseRenderer(props)}};const gradedGroupWidgetLogic={name:"graded-group",defaultWidgetOptions: defaultWidgetOptions$o,accessible:true,traverseChildWidgets:traverseChildWidgets$3};
274
274
 
@@ -440,7 +440,7 @@ function generatePhetSimulationOptions(options){return {...phetSimulationWidgetL
440
440
 
441
441
  function generateNumberLineOptions(options){const defaultNumberLineOptions={range:[-4,4],labelRange:[null,null],labelStyle:"decimal",labelTicks:true,isInequality:false,isTickCtrl:false,divisionRange:[1,10],numDivisions:null,snapDivisions:2,tickStep:1,correctRel:"eq",correctX:null,initialX:null,showTooltips:false};return {...defaultNumberLineOptions,...options}}function generateNumberLineWidget(numberLineWidgetProperties){return {type:"number-line",graded:true,version:{major:0,minor:0},static:false,alignment:"default",...numberLineWidgetProperties,options:generateNumberLineOptions(numberLineWidgetProperties?.options)}}
442
442
 
443
- 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}}
443
+ function generateNumericInputOptions(options){return {...numericInputWidgetLogic.defaultWidgetOptions,...options}}function generateNumericInputAnswer(answerOptions){return {...numericInputWidgetLogic.defaultWidgetOptions.answers[0],...answerOptions}}function generateNumericInputWidget(numericInputWidgetProperties){return {type:"numeric-input",graded:true,static:false,version:{major:0,minor:0},alignment:"default",options:generateNumericInputOptions(),...numericInputWidgetProperties}}
444
444
 
445
445
  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)})}
446
446
 
@@ -460,7 +460,7 @@ ${items.join("\n")}
460
460
  | --- | --- |`;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}
461
461
  ${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}}
462
462
 
463
- const denylist=["key","ref","containerSizeClass","widgetId","onChange","problemNum","apiOptions","widgetIsOpen","findWidgets","onRemove","id","onBlur","onFocus","trackInteraction","keypadElement","linterContext","handleUserInput","analytics","showSolutions","reviewMode","isScorable","widgetIndex","graded"];function excludeDenylistKeys(obj){if(obj==null){return obj}const rv={};for(const k of Object.keys(obj)){if(!denylist.includes(k)){rv[k]=obj[k];}}return rv}
463
+ const denylist=["key","ref","containerSizeClass","widgetId","onChange","problemNum","apiOptions","widgetIsOpen","findWidgets","onRemove","id","onBlur","onFocus","trackInteraction","keypadElement","linterContext","handleUserInput","analytics","dependencies","showSolutions","reviewMode","isScorable","widgetIndex","graded"];function excludeDenylistKeys(obj){if(obj==null){return obj}const rv={};for(const k of Object.keys(obj)){if(!denylist.includes(k)){rv[k]=obj[k];}}return rv}
464
464
 
465
465
  registerCoreWidgets();
466
466