@khanacademy/perseus 67.0.0 → 67.1.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.
- package/dist/components/scrollable-view.d.ts +12 -3
- package/dist/es/index.css +6 -6
- package/dist/es/index.css.map +1 -1
- package/dist/es/index.js +14 -12
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +6 -6
- package/dist/index.css.map +1 -1
- package/dist/index.js +14 -12
- package/dist/index.js.map +1 -1
- package/dist/widget-ai-utils/image/image-ai-utils.d.ts +1 -1
- package/dist/widget-ai-utils/radio/radio-ai-utils.d.ts +1 -1
- package/dist/widgets/image/image.class.d.ts +43 -0
- package/dist/widgets/image/image.d.ts +2 -42
- package/dist/widgets/image/index.d.ts +1 -1
- package/dist/widgets/radio/base-radio.d.ts +1 -3
- package/dist/widgets/radio/multiple-choice-component.new.d.ts +1 -1
- package/dist/widgets/radio/multiple-choice-widget.new.d.ts +2 -79
- package/dist/widgets/radio/radio-component.d.ts +1 -3
- package/dist/widgets/radio/radio.d.ts +2 -2
- package/package.json +47 -47
package/dist/index.js
CHANGED
|
@@ -1729,11 +1729,11 @@ const NumericInputComponent=React.forwardRef(function NumericInputComponent(prop
|
|
|
1729
1729
|
|
|
1730
1730
|
class NumericInput extends React__namespace.Component{getPromptJSON(){return getPromptJSON$r(this.props)}getSerializedState(){const{userInput,answers:_,...rest}=this.props;return {...rest,currentValue:userInput.currentValue}}render(){return jsxRuntimeExports.jsx(NumericInputComponent,{...this.props,answerForms:normalizeCorrectAnswerForms(this.props.answers),ref:this.inputRef})}constructor(...args){super(...args),this.inputRef=React__namespace.createRef(),this.focus=()=>{this.inputRef.current?.focus();return true},this.focusInputPath=()=>{this.inputRef.current?.focus();},this.blurInputPath=()=>{this.inputRef.current?.blur();},this.getInputPaths=()=>{return [[]]};}}NumericInput.defaultProps={size:"normal",rightAlign:false,apiOptions:ApiOptions.defaults,coefficient:false,answerForms:[],labelText:"",linterContext:PerseusLinter.linterContextDefault,userInput:{currentValue:""}};function getStartUserInput$h(){return {currentValue:""}}function getUserInputFromSerializedState$g(serializedState){return {currentValue:serializedState.currentValue}}var NumericInput$1 = {name:"numeric-input",displayName:"Numeric input",widget:NumericInput,isLintable:true,getOneCorrectAnswerFromRubric(rubric){const correctAnswers=rubric.answers.filter(answer=>answer.status==="correct");const answerStrings=correctAnswers.map(answer=>{const format=answer.answerForms&&answer.answerForms[0]?answer.answerForms[0]:"decimal";let answerString=kmath.KhanMath.toNumericString(answer.value,format);if(answer.maxError){answerString+=" ± "+kmath.KhanMath.toNumericString(answer.maxError,format);}return answerString});if(answerStrings.length===0){return}return answerStrings[0]},getStartUserInput: getStartUserInput$h,getUserInputFromSerializedState: getUserInputFromSerializedState$g};
|
|
1731
1731
|
|
|
1732
|
-
const getPromptJSON$q=(renderProps,userInput)=>{const choices=renderProps.choices||[];const options=choices.map(choice=>{const option={value:choice.content};if(choice.rationale){option.rationale=choice.rationale;}return option});return {type:"radio",hasNoneOfTheAbove:!!renderProps.hasNoneOfTheAbove,options,userInput:{selectedOptions:userInput?.
|
|
1732
|
+
const getPromptJSON$q=(renderProps,userInput)=>{const choices=renderProps.choices||[];const options=choices.map(choice=>{const option={value:choice.content};if(choice.rationale){option.rationale=choice.rationale;}return option});return {type:"radio",hasNoneOfTheAbove:!!renderProps.hasNoneOfTheAbove,options,userInput:{selectedOptions:userInput?.selectedChoiceIds??[]}}};
|
|
1733
1733
|
|
|
1734
1734
|
var styles$C = {"scrollButtonsContainer":"perseus_kjDHiWdD"};
|
|
1735
1735
|
|
|
1736
|
-
const SCROLL_DISTANCE=100;function
|
|
1736
|
+
const SCROLL_DISTANCE=100;const scrollInstances=new Map;function ScrollableArea({overflowX,overflowY,children,className,scrollDescription,style,role="group",id:providedId,...additionalProps}){const{strings}=usePerseusI18n();const containerRef=React.useRef(null);const[isScrollable,setIsScrollable]=React.useState(false);const[isRtl,setIsRtl]=React.useState(false);const[isScrolling,setIsScrolling]=React.useState(false);const generatedId=React__namespace.useId();const id=providedId||generatedId;const scrollableThreshold=React__namespace.useMemo(()=>{return window.innerWidth<=767?8:5},[]);const scroll=React__namespace.useCallback(direction=>{if(!containerRef.current||isScrolling){return}setIsScrolling(true);const scrollNegative=isRtl&&direction!=="start"||!isRtl&&direction==="start";const scrollAmount=scrollNegative?-100:SCROLL_DISTANCE;containerRef.current.scrollBy({left:scrollAmount,behavior:"smooth"});setTimeout(()=>{setIsScrolling(false);},150);},[isRtl,isScrolling]);const updateScrollState=React__namespace.useCallback(()=>{if(!containerRef.current){return}const{scrollLeft,scrollWidth,clientWidth}=containerRef.current;const newIsRtl=getComputedStyle(containerRef.current).direction==="rtl";setIsRtl(newIsRtl);const newIsScrollable=scrollWidth>clientWidth+scrollableThreshold;setIsScrollable(newIsScrollable);let newCanScrollStart;let newCanScrollEnd;if(newIsRtl){newCanScrollStart=Math.abs(scrollLeft)<scrollWidth-clientWidth-scrollableThreshold;newCanScrollEnd=scrollLeft<-scrollableThreshold;}else {newCanScrollStart=scrollLeft>scrollableThreshold;newCanScrollEnd=scrollLeft+clientWidth<scrollWidth-scrollableThreshold;}const scrollState={isScrollable:newIsScrollable,canScrollStart:newCanScrollStart,canScrollEnd:newCanScrollEnd,isRTL:newIsRtl,scroll,scrollDescription:scrollDescription||strings.scrollAnswers};scrollInstances.set(id,scrollState);},[id,scrollableThreshold,scrollDescription,strings.scrollAnswers,scroll]);React.useEffect(()=>{const container=containerRef.current;if(!container){return}updateScrollState();container.addEventListener("scroll",updateScrollState);window.addEventListener("resize",updateScrollState);return ()=>{container.removeEventListener("scroll",updateScrollState);window.removeEventListener("resize",updateScrollState);scrollInstances.delete(id);}},[children,updateScrollState,id]);const mergeStyle={overflowX:isScrollable&&overflowX==="auto"?"scroll":overflowX,overflowY:isScrollable&&overflowY==="auto"?"scroll":overflowY,scrollbarWidth:"thin",...style};return jsxRuntimeExports.jsx("div",{...additionalProps,id:id,role:role,className:className,style:mergeStyle,ref:containerRef,children:children})}function ScrollControls({target,scrollDescription:overrideDescription}){const{strings}=usePerseusI18n();const[scrollState,setScrollState]=React.useState(null);React.useEffect(()=>{if(!target){return}const checkForScrollState=()=>{const state=scrollInstances.get(target);if(state){setScrollState(state);}};checkForScrollState();const interval=setInterval(checkForScrollState,100);return ()=>{clearInterval(interval);}},[target]);if(!scrollState||!scrollState.isScrollable){return null}const description=overrideDescription||scrollState.scrollDescription;return jsxRuntimeExports.jsxs("div",{className:styles$C.scrollButtonsContainer,"aria-live":"polite",role:"group","aria-label":description,children:[jsxRuntimeExports.jsx(IconButton__default.default,{icon:scrollState.isRTL?caretRightIcon__default.default:caretLeftIcon__default.default,actionType:"neutral",kind:"secondary",size:"small",onClick:()=>scrollState.isRTL?scrollState.scroll("end"):scrollState.scroll("start"),"aria-label":strings.scrollStart,disabled:scrollState.isRTL?!scrollState.canScrollEnd:!scrollState.canScrollStart}),jsxRuntimeExports.jsx(IconButton__default.default,{icon:scrollState.isRTL?caretLeftIcon__default.default:caretRightIcon__default.default,actionType:"neutral",kind:"secondary",size:"small",onClick:()=>scrollState.isRTL?scrollState.scroll("start"):scrollState.scroll("end"),"aria-label":strings.scrollEnd,disabled:scrollState.isRTL?!scrollState.canScrollStart:!scrollState.canScrollEnd}),jsxRuntimeExports.jsx(wonderBlocksTypography.LabelSmall,{children:description})]})}const ScrollableView=ScrollableArea;ScrollableView.Controls=ScrollControls;
|
|
1737
1737
|
|
|
1738
1738
|
var styles$B = {"base":"perseus_C4cWo-dY","is-correct":"perseus_vWc7XkhJ","isCorrect":"perseus_vWc7XkhJ","is-wrong":"perseus_yVmsF9sA","isWrong":"perseus_yVmsF9sA","icon":"perseus_brEUCVvd","circle-shape":"perseus_irgRpkgB","circleShape":"perseus_irgRpkgB","square-shape":"perseus_JsUZt48D","squareShape":"perseus_JsUZt48D"};
|
|
1739
1739
|
|
|
@@ -1745,11 +1745,11 @@ const Choice$2=props=>{const showCorrectness=props.showCorrectness;const buttonR
|
|
|
1745
1745
|
|
|
1746
1746
|
var styles$z = {"container":"perseus_dzsult1u","choiceList":"perseus_HSvzOAAR","content":"perseus_A5d7KcQj","instructions":"perseus_skOlpdjN","rationale":"perseus_y4m8wyRd","isCorrect":"perseus_IfCbxIVP","reviewAnswers":"perseus_QYlQJ6BF"};
|
|
1747
1747
|
|
|
1748
|
-
function getChoiceLetter(pos,strings){const lettersString=strings.letters;const letters=lettersString.split(" ");if(pos<letters.length){return letters[pos]}return " "}function getUserInputFromSerializedState$f(props,unshuffle=true){if(props.choiceStates){const choiceStates=props.choiceStates;
|
|
1748
|
+
function getChoiceLetter(pos,strings){const lettersString=strings.letters;const letters=lettersString.split(" ");if(pos<letters.length){return letters[pos]}return " "}function getUserInputFromSerializedState$f(props,unshuffle=true){const selectedChoiceIds=[];if(props.choiceStates){const choiceStates=props.choiceStates;for(let i=0;i<choiceStates.length;i++){if(choiceStates[i].selected){selectedChoiceIds.push(props.choices[i].id);}}return {selectedChoiceIds}}const{values}=props;if(values){const valuesLength=values.length;for(let i=0;i<valuesLength&&i<props.choices.length;i++){if(values[i]){selectedChoiceIds.push(props.choices[i].id);}}return {selectedChoiceIds}}return {selectedChoiceIds}}
|
|
1749
1749
|
|
|
1750
1750
|
const getInstructionsText$1=({multipleSelect,countChoices,numCorrect,strings})=>{if(multipleSelect){if(perseusCore.usesNumCorrect(multipleSelect,!!countChoices,numCorrect)){return strings.chooseNumAnswers({numCorrect:String(numCorrect)})}return strings.chooseAllAnswers}return strings.chooseOneAnswer};
|
|
1751
1751
|
|
|
1752
|
-
const MultipleChoiceComponent=({choices,countChoices,multipleSelect=false,numCorrect,onChoiceChange,reviewMode})=>{const{strings}=usePerseusI18n();const legendId=React.useId();const instructions=getInstructionsText$1({multipleSelect,countChoices,numCorrect,strings});const choiceListClasses=reviewMode?`${styles$z.choiceList} ${styles$z.reviewAnswers}`:styles$z.choiceList;return jsxRuntimeExports.jsxs("fieldset",{className:styles$z.container,"data-feature-flag":"feature flag is ON",children:[jsxRuntimeExports.jsx("legend",{id:legendId,"aria-hidden":"true",className:styles$z.instructions,children:instructions}),jsxRuntimeExports.jsx(ScrollableView,{overflowX:"auto",children:jsxRuntimeExports.jsx("ul",{"aria-labelledby":legendId,className:choiceListClasses,children:jsxRuntimeExports.jsx(ChoiceListItems,{choices:choices,i18nStrings:strings,onChoiceChange:onChoiceChange,reviewMode:reviewMode,multipleSelect:multipleSelect})})})]})};const ChoiceListItems=props=>{const{choices,i18nStrings,multipleSelect,onChoiceChange,reviewMode}=props;const listId=React.useId();const items=choices.map((choice,i)=>{const updateChecked=isChecked=>{onChoiceChange(
|
|
1752
|
+
const MultipleChoiceComponent=({choices,countChoices,multipleSelect=false,numCorrect,onChoiceChange,reviewMode})=>{const{strings}=usePerseusI18n();const legendId=React.useId();const instructions=getInstructionsText$1({multipleSelect,countChoices,numCorrect,strings});const choiceListClasses=reviewMode?`${styles$z.choiceList} ${styles$z.reviewAnswers}`:styles$z.choiceList;const scrollId=React.useId()+"-scroll";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs("fieldset",{className:styles$z.container,"data-feature-flag":"feature flag is ON",children:[jsxRuntimeExports.jsx("legend",{id:legendId,"aria-hidden":"true",className:styles$z.instructions,children:instructions}),jsxRuntimeExports.jsx(ScrollableView,{id:scrollId,overflowX:"auto",children:jsxRuntimeExports.jsx("ul",{"aria-labelledby":legendId,className:choiceListClasses,children:jsxRuntimeExports.jsx(ChoiceListItems,{choices:choices,i18nStrings:strings,onChoiceChange:onChoiceChange,reviewMode:reviewMode,multipleSelect:multipleSelect})})})]}),jsxRuntimeExports.jsx(ScrollableView.Controls,{target:scrollId})]})};const ChoiceListItems=props=>{const{choices,i18nStrings,multipleSelect,onChoiceChange,reviewMode}=props;const listId=React.useId();const items=choices.map((choice,i)=>{const updateChecked=isChecked=>{onChoiceChange(choice.id,isChecked);};const contentId=`${listId}-choice-${i+1}`;const choiceLetter=getChoiceLetter(i,i18nStrings);const srContent=reviewMode&&choice.correct?i18nStrings.choiceCorrect:i18nStrings.choice;const indicatorContent={visible:choiceLetter,screenReader:srContent({letter:choiceLetter}),labelledBy:contentId};const showCorrectness=reviewMode?choice.correct?"correct":"wrong":undefined;const content=choice.isNoneOfTheAbove?i18nStrings.noneOfTheAbove:choice.content;let rationale;if(reviewMode&&choice.hasRationale){const rationaleId=`${contentId}-rationale`;indicatorContent.describedBy=rationaleId;const rationaleClasses=showCorrectness==="correct"?`${styles$z.rationale} ${styles$z.isCorrect}`:styles$z.rationale;rationale=jsxRuntimeExports.jsx("div",{id:rationaleId,className:rationaleClasses,children:choice.rationale});}return jsxRuntimeExports.jsx(Choice$2,{checked:choice.checked,indicatorContent:indicatorContent,isMultiSelect:multipleSelect,showCorrectness:showCorrectness,updateChecked:updateChecked,children:jsxRuntimeExports.jsxs("div",{className:styles$z.content,children:[jsxRuntimeExports.jsx("div",{id:contentId,children:content}),rationale]})},choice.id)});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:items})};
|
|
1753
1753
|
|
|
1754
1754
|
const getPromptJSON$p=renderProps=>{return {type:"passage-ref",options:{passageNumber:renderProps.passageNumber,referenceNumber:renderProps.referenceNumber,summaryText:renderProps.summaryText}}};
|
|
1755
1755
|
|
|
@@ -1785,7 +1785,7 @@ const EN_DASH$1="–";class PassageRef extends React__namespace.Component{compon
|
|
|
1785
1785
|
|
|
1786
1786
|
const getChoiceStates=({choices,isStatic,showSolutions,choiceStates,values})=>{const defaultState={selected:false,readOnly:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false};if(isStatic||showSolutions==="all"){return choices.map(choice=>({...defaultState,selected:!!choice.correct,readOnly:true,rationaleShown:true,correctnessShown:true}))}if(choiceStates){return choiceStates}if(values){return values.map(val=>({...defaultState,selected:val}))}return choices.map(()=>({...defaultState}))};const parseNestedWidgets=content=>{let nextPassageRefId=1;const extractedWidgets={};const parsedContent=content.replace(/\{\{passage-ref (\d+) (\d+)(?: "([^"]*)")?\}\}/g,(_,passageNum,refNum,summaryText)=>{const widgetId="passage-ref "+nextPassageRefId;nextPassageRefId++;extractedWidgets[widgetId]={type:"passage-ref",graded:false,options:{passageNumber:parseInt(passageNum),referenceNumber:parseInt(refNum),summaryText:summaryText},version:PassageRef$1.version};return "[["+Util.snowman+" "+widgetId+"]]"});return {parsedContent,extractedWidgets}};
|
|
1787
1787
|
|
|
1788
|
-
|
|
1788
|
+
const MultipleChoiceWidget=React.forwardRef(function MultipleChoiceWidget(props,ref){const{choices=[],multipleSelect=false,countChoices=false,showSolutions="none",choiceStates,values,reviewModeRubric,questionCompleted,strings=mockStrings,static:isStatic,apiOptions,onChange,trackInteraction,findWidgets,reviewMode}=props;React.useImperativeHandle(ref,()=>({getPromptJSON:()=>{return getPromptJSON$q(props,props.userInput)}}),[props]);const renderContent=(content="")=>{const{parsedContent,extractedWidgets}=parseNestedWidgets(content);const linterContext={contentType:"radio",highlightLint:false,paths:[],stack:[]};return jsxRuntimeExports.jsx(Renderer,{content:parsedContent,widgets:extractedWidgets,findExternalWidgets:findWidgets,alwaysUpdate:true,linterContext:linterContext,strings:strings},"choiceContentRenderer")};const handleChoiceChange=(choiceId,newCheckedState)=>{const checkedChoiceIds=[];if(newCheckedState&&!multipleSelect){checkedChoiceIds.push(choiceId);}else if(newCheckedState&&multipleSelect){const currentSelectedIds=choiceStates?choiceStates.map((state,i)=>({selected:state.selected,id:choices[i].id})).filter(choice=>choice.selected).map(choice=>choice.id):[];checkedChoiceIds.push(...currentSelectedIds,choiceId);}else {const currentSelectedIds=choiceStates?choiceStates.map((state,i)=>({selected:state.selected,id:choices[i].id})).filter(choice=>choice.selected&&choice.id!==choiceId).map(choice=>choice.id):[];checkedChoiceIds.push(...currentSelectedIds);}const newChoiceStates=choiceStates?choiceStates.map(state=>({...state})):choices.map(()=>({selected:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false,readOnly:false}));newChoiceStates.forEach((choiceState,i)=>{const choiceId=choices[i].id;choiceState.selected=checkedChoiceIds.includes(choiceId);});onChange({choiceStates:newChoiceStates});trackInteraction();};const buildChoiceProps=choiceStates=>{return choices.map((choice,i)=>{const content=choice.isNoneOfTheAbove&&!choice.content?strings.noneOfTheAbove:choice.content;const{selected,rationaleShown,correctnessShown,readOnly,previouslyAnswered}=choiceStates[i];const reviewChoice=reviewModeRubric?.choices[i];return {id:choice.id,content:renderContent(content),checked:selected,correct:choice.correct===undefined?!!reviewChoice&&!!reviewChoice.correct:choice.correct,disabled:readOnly,hasRationale:!!choice.rationale,rationale:renderContent(choice.rationale),showRationale:rationaleShown,showCorrectness:correctnessShown,isNoneOfTheAbove:!!choice.isNoneOfTheAbove,revealNoneOfTheAbove:!!(questionCompleted&&selected),previouslyAnswered}})};const prepareChoicesProps=()=>{const processedChoiceStates=getChoiceStates({choices,isStatic,showSolutions,choiceStates,values});return buildChoiceProps(processedChoiceStates)};const choicesProps=prepareChoicesProps();const numCorrect=props.numCorrect;const isReviewMode=reviewMode||isStatic||showSolutions==="all";const onChoiceChange=apiOptions.readOnly||isReviewMode?()=>{}:handleChoiceChange;return jsxRuntimeExports.jsx(MultipleChoiceComponent,{reviewMode:isReviewMode,multipleSelect:multipleSelect,countChoices:countChoices,numCorrect:numCorrect,choices:choicesProps,onChoiceChange:onChoiceChange})});const Radio$3=MultipleChoiceWidget;
|
|
1789
1789
|
|
|
1790
1790
|
const{pureXsMax,pureSmMax,pureMdMin,pureMdMax,pureLgMin,pureLgMax,pureXlMin}=constants;var mediaQueries = {md:`@media screen and (min-width: ${pureMdMin}) and `+`(max-width: ${pureMdMax})`,xl:`@media screen and (min-width: ${pureXlMin})`,xsOrSmaller:`@media screen and (max-width: ${pureXsMax})`,smOrSmaller:`@media screen and (max-width: ${pureSmMax})`,mdOrSmaller:`@media screen and (max-width: ${pureMdMax})`,lgOrSmaller:`@media screen and (max-width: ${pureLgMax})`,lgOrLarger:`@media screen and (min-width: ${pureLgMin})`};
|
|
1791
1791
|
|
|
@@ -1805,13 +1805,13 @@ const intermediateCheckboxPadding=`16px 16px`;const intermediateCheckboxPaddingP
|
|
|
1805
1805
|
|
|
1806
1806
|
const ChoiceNoneAbove=function({content,forwardedRef,showContent=true,...rest}){const{strings}=usePerseusI18n();const choiceProps={...rest,content:showContent?content:jsxRuntimeExports.jsx(Renderer,{content:strings.noneOfTheAbove,strings:strings},"noneOfTheAboveRenderer")};return jsxRuntimeExports.jsx(Choice$1,{...choiceProps,ref:forwardedRef})};var ChoiceNoneAbove$1 = React__namespace.forwardRef(function ChoiceNoneAboveWithRef(props,ref){return jsxRuntimeExports.jsx(ChoiceNoneAbove,{...props,forwardedRef:ref})});
|
|
1807
1807
|
|
|
1808
|
-
const{captureScratchpadTouchStart: captureScratchpadTouchStart$1}=Util;function getInstructionsText(multipleSelect,countChoices,numCorrect,strings){if(multipleSelect){if(perseusCore.usesNumCorrect(multipleSelect,!!countChoices,numCorrect)){return strings.chooseNumAnswers({numCorrect:String(numCorrect)})}return strings.chooseAllAnswers}return strings.chooseOneAnswer}const BaseRadio=function({apiOptions,reviewModeRubric,reviewMode,choices,editMode=false,multipleSelect=false,labelWrap,countChoices,numCorrect,isLastUsedWidget,onChange,registerFocusFunction}){const{strings}=usePerseusI18n();const prevReviewModeRubric=React.useRef();const choiceRefs=React.useRef([]);React.useEffect(()=>{if(apiOptions.canScrollPage&&isLastUsedWidget&&reviewModeRubric&&!prevReviewModeRubric.current){const checkedIndex=choices.findIndex(c=>c.checked);if(checkedIndex>=0){const ref=choiceRefs.current[checkedIndex];const anyNode=ReactDOM__namespace.default.findDOMNode(ref.current);const buttonNode=anyNode;if(buttonNode){scrollElementIntoView(buttonNode);}}}prevReviewModeRubric.current=reviewModeRubric;},[apiOptions,choices,isLastUsedWidget,reviewModeRubric]);function updateChoice(
|
|
1808
|
+
const{captureScratchpadTouchStart: captureScratchpadTouchStart$1}=Util;function getInstructionsText(multipleSelect,countChoices,numCorrect,strings){if(multipleSelect){if(perseusCore.usesNumCorrect(multipleSelect,!!countChoices,numCorrect)){return strings.chooseNumAnswers({numCorrect:String(numCorrect)})}return strings.chooseAllAnswers}return strings.chooseOneAnswer}const BaseRadio=function({apiOptions,reviewModeRubric,reviewMode,choices,editMode=false,multipleSelect=false,labelWrap,countChoices,numCorrect,isLastUsedWidget,onChange,registerFocusFunction}){const{strings}=usePerseusI18n();const prevReviewModeRubric=React.useRef();const choiceRefs=React.useRef([]);React.useEffect(()=>{if(apiOptions.canScrollPage&&isLastUsedWidget&&reviewModeRubric&&!prevReviewModeRubric.current){const checkedIndex=choices.findIndex(c=>c.checked);if(checkedIndex>=0){const ref=choiceRefs.current[checkedIndex];const anyNode=ReactDOM__namespace.default.findDOMNode(ref.current);const buttonNode=anyNode;if(buttonNode){scrollElementIntoView(buttonNode);}}}prevReviewModeRubric.current=reviewModeRubric;},[apiOptions,choices,isLastUsedWidget,reviewModeRubric]);function updateChoice(choiceId,checked){const checkedChoiceIds=[];if(checked&&!multipleSelect){checkedChoiceIds.push(choiceId);}else if(checked&&multipleSelect){const currentCheckedIds=choices.filter(choice=>choice.checked).map(choice=>choice.id);checkedChoiceIds.push(...currentCheckedIds,choiceId);}else {const currentCheckedIds=choices.filter(choice=>choice.checked&&choice.id!==choiceId).map(choice=>choice.id);checkedChoiceIds.push(...currentCheckedIds);}onChange(checkedChoiceIds);}registerFocusFunction?.(choiceIndex=>{const ref=choiceRefs.current[choiceIndex||0];const anyNode=ReactDOM__namespace.default.findDOMNode(ref.current);const buttonNode=anyNode;if(buttonNode){buttonNode.focus();}else {return false}return true});const isMobile=apiOptions.isMobile;const firstChoiceHighlighted=choices[0].highlighted;const lastChoiceHighlighted=choices[choices.length-1].highlighted;const className=classNames__default.default("perseus-widget-radio",!editMode&&"perseus-rendered-radio",aphrodite.css(styles$p.radio,styles$p.responsiveRadioContainer,firstChoiceHighlighted&&isMobile&&styles$p.radioContainerFirstHighlighted,lastChoiceHighlighted&&isMobile&&styles$p.radioContainerLastHighlighted));const instructionsClassName=classNames__default.default("instructions",aphrodite.css(styles$p.instructions,isMobile&&styles$p.instructionsMobile));const instructions=getInstructionsText(multipleSelect,countChoices,numCorrect,strings);const responsiveClassName=aphrodite.css(styles$p.responsiveFieldset);const fieldset=jsxRuntimeExports.jsxs("fieldset",{className:`perseus-widget-radio-fieldset ${responsiveClassName}`,children:[jsxRuntimeExports.jsx("legend",{className:"perseus-sr-only",children:instructions}),jsxRuntimeExports.jsx("div",{className:instructionsClassName,"aria-hidden":"true",children:instructions}),jsxRuntimeExports.jsx("ul",{className:className,style:{listStyle:"none"},children:choices.map((choice,i)=>{let Element=Choice$1;const ref=React__namespace.createRef();choiceRefs.current[i]=ref;const elementProps={id:choice.id,apiOptions:apiOptions,multipleSelect:multipleSelect,checked:choice.checked,previouslyAnswered:choice.previouslyAnswered,reviewMode,correct:choice.correct,rationale:choice.rationale,content:choice.content,disabled:apiOptions.readOnly||choice.disabled,showCorrectness:reviewMode||!!choice.showCorrectness,showRationale:choice.hasRationale&&(reviewMode||choice.showRationale),pos:i,onChange:newValues=>{if(editMode){return}updateChoice(choice.id,newValues.checked);}};if(choice.isNoneOfTheAbove){Element=ChoiceNoneAbove$1;___default.default.extend(elementProps,{showContent:choice.revealNoneOfTheAbove});}const nextChoice=choices[i+1];const nextChoiceHighlighted=!!nextChoice&&nextChoice.highlighted;const aphroditeClassName=checked=>{return aphrodite.css(styles$p.item,styles$p.responsiveItem,checked&&styles$p.selectedItem,checked&&choice.highlighted&&styles$p.aboveBackdrop,checked&&choice.highlighted&&apiOptions.isMobile&&styles$p.aboveBackdropMobile,nextChoiceHighlighted&&apiOptions.isMobile&&styles$p.nextHighlighted)};aphroditeClassName(true);let correctnessClass;if(reviewMode&&reviewModeRubric){correctnessClass=reviewModeRubric.choices[i].correct?ClassNames.CORRECT:ClassNames.INCORRECT;}const className=classNames__default.default(aphroditeClassName(choice.checked),ClassNames.RADIO.OPTION,choice.checked&&ClassNames.RADIO.SELECTED,correctnessClass);let listElem=null;let clickHandler;if(editMode){clickHandler=e=>{let elem=e.target;while(elem&&elem!==listElem){if(elem.getAttribute("data-is-radio-icon")){updateChoice(choice.id,!choice.checked);return}elem=elem.parentNode;}};}return jsxRuntimeExports.jsx("li",{ref:e=>listElem=e,className:className,onClick:clickHandler,onTouchStart:labelWrap?undefined:captureScratchpadTouchStart$1,children:jsxRuntimeExports.jsx(Element,{...elementProps,ref:ref})},choice.id)})})]});return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$p.responsiveContainer),children:fieldset})};const styles$p=aphrodite.StyleSheet.create({instructions:{display:"block",color:gray17,fontSize:14,lineHeight:1.25,fontFamily:"inherit",fontStyle:"normal",fontWeight:"bold",marginBottom:16},instructionsMobile:{fontSize:18,[mediaQueries.smOrSmaller]:{fontSize:16},[mediaQueries.xl]:{fontSize:20}},radio:{padding:0},responsiveRadioContainer:{borderBottom:`1px solid ${radioBorderColor$1}`,borderTop:`1px solid ${radioBorderColor$1}`,width:"auto",[mediaQueries.smOrSmaller]:{marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin}},radioContainerFirstHighlighted:{borderTop:`1px solid rgba(0, 0, 0, 0)`},radioContainerLastHighlighted:{borderBottom:`1px solid rgba(0, 0, 0, 0)`},item:{marginLeft:20},responsiveItem:{marginLeft:0,padding:0,":not(:last-child)":{borderBottom:`1px solid ${radioBorderColor$1}`}},selectedItem:{background:"white"},aboveBackdrop:{position:"relative",zIndex:1062},aboveBackdropMobile:{boxShadow:"0 0 4px 0 rgba(0, 0, 0, 0.2),"+"0 0 2px 0 rgba(0, 0, 0, 0.1)",":not(:last-child)":{borderBottom:`1px solid rgba(0, 0, 0, 0)`}},nextHighlighted:{":not(:last-child)":{borderBottom:`1px solid rgba(0, 0, 0, 0)`}},responsiveContainer:{overflow:"auto",marginLeft:negativePhoneMargin,paddingLeft:phoneMargin},responsiveFieldset:{paddingRight:phoneMargin,minWidth:"auto"}});
|
|
1809
1809
|
|
|
1810
|
-
let Radio$2 = class Radio extends React__namespace.Component{focus(choiceIndex){if(this.focusFunction){return this.focusFunction(choiceIndex)}return false}registerFocusFunction(fun){this.focusFunction=fun;}getPromptJSON(){return getPromptJSON$q(this.props,this.props.userInput)}render(){const{choices}=this.props;const{strings}=this.context;let choiceStates;if(this.props.static){choiceStates=choices.map(choice=>({selected:!!choice.correct,crossedOut:false,readOnly:true,highlighted:false,rationaleShown:true,correctnessShown:true,previouslyAnswered:false}));}else if(this.props.showSolutions==="all"){choiceStates=choices.map(({correct})=>({selected:!!correct,crossedOut:false,readOnly:true,highlighted:false,rationaleShown:true,correctnessShown:true,previouslyAnswered:false}));}else if(this.props.choiceStates){choiceStates=this.props.choiceStates;}else if(this.props.values){choiceStates=this.props.values.map(val=>({selected:val,crossedOut:false,readOnly:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}));}else {choiceStates=choices.map(()=>({selected:false,crossedOut:false,readOnly:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}));}const choicesProp=choices.map((choice,i)=>{const content=choice.isNoneOfTheAbove&&!choice.content?strings.noneOfTheAbove:choice.content;const{selected,rationaleShown,correctnessShown,readOnly,highlighted,previouslyAnswered}=choiceStates[i];const reviewChoice=this.props.reviewModeRubric?.choices[i];return {id:choice.id,content:this._renderRenderer(content),checked:selected,correct:choice.correct===undefined?!!reviewChoice&&!!reviewChoice.correct:choice.correct,disabled:readOnly,hasRationale:!!choice.rationale,rationale:this._renderRenderer(choice.rationale),showRationale:rationaleShown,showCorrectness:correctnessShown,isNoneOfTheAbove:!!choice.isNoneOfTheAbove,revealNoneOfTheAbove:!!(this.props.questionCompleted&&selected),highlighted,previouslyAnswered:previouslyAnswered}});return jsxRuntimeExports.jsx(BaseRadio,{labelWrap:true,multipleSelect:this.props.multipleSelect,countChoices:this.props.countChoices,numCorrect:this.props.numCorrect,choices:choicesProp,onChange:this.updateChoices,reviewModeRubric:this.props.reviewModeRubric,reviewMode:this.props.reviewMode,deselectEnabled:this.props.deselectEnabled,apiOptions:this.props.apiOptions,isLastUsedWidget:this.props.isLastUsedWidget,registerFocusFunction:i=>this.registerFocusFunction(i)})}constructor(...args){super(...args),this._renderRenderer=(content="")=>{let nextPassageRefId=1;const widgets={};const modContent=content.replace(/\{\{passage-ref (\d+) (\d+)(?: "([^"]*)")?\}\}/g,(match,passageNum,refNum,summaryText)=>{const widgetId="passage-ref "+nextPassageRefId;nextPassageRefId++;widgets[widgetId]={type:"passage-ref",graded:false,options:{passageNumber:parseInt(passageNum),referenceNumber:parseInt(refNum),summaryText:summaryText},version:PassageRef$1.version};return "[["+Util.snowman+" "+widgetId+"]]"});return jsxRuntimeExports.jsx(Renderer,{content:modContent,widgets:widgets,findExternalWidgets:this.props.findWidgets,alwaysUpdate:true,linterContext:{...this.props.linterContext,blockHighlight:true},strings:this.context.strings},"choiceContentRenderer")},this.updateChoices=
|
|
1810
|
+
let Radio$2 = class Radio extends React__namespace.Component{focus(choiceIndex){if(this.focusFunction){return this.focusFunction(choiceIndex)}return false}registerFocusFunction(fun){this.focusFunction=fun;}getPromptJSON(){return getPromptJSON$q(this.props,this.props.userInput)}render(){const{choices}=this.props;const{strings}=this.context;let choiceStates;if(this.props.static){choiceStates=choices.map(choice=>({selected:!!choice.correct,crossedOut:false,readOnly:true,highlighted:false,rationaleShown:true,correctnessShown:true,previouslyAnswered:false}));}else if(this.props.showSolutions==="all"){choiceStates=choices.map(({correct})=>({selected:!!correct,crossedOut:false,readOnly:true,highlighted:false,rationaleShown:true,correctnessShown:true,previouslyAnswered:false}));}else if(this.props.choiceStates){choiceStates=this.props.choiceStates;}else if(this.props.values){choiceStates=this.props.values.map(val=>({selected:val,crossedOut:false,readOnly:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}));}else {choiceStates=choices.map(()=>({selected:false,crossedOut:false,readOnly:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}));}const choicesProp=choices.map((choice,i)=>{const content=choice.isNoneOfTheAbove&&!choice.content?strings.noneOfTheAbove:choice.content;const{selected,rationaleShown,correctnessShown,readOnly,highlighted,previouslyAnswered}=choiceStates[i];const reviewChoice=this.props.reviewModeRubric?.choices[i];return {id:choice.id,content:this._renderRenderer(content),checked:selected,correct:choice.correct===undefined?!!reviewChoice&&!!reviewChoice.correct:choice.correct,disabled:readOnly,hasRationale:!!choice.rationale,rationale:this._renderRenderer(choice.rationale),showRationale:rationaleShown,showCorrectness:correctnessShown,isNoneOfTheAbove:!!choice.isNoneOfTheAbove,revealNoneOfTheAbove:!!(this.props.questionCompleted&&selected),highlighted,previouslyAnswered:previouslyAnswered}});return jsxRuntimeExports.jsx(BaseRadio,{labelWrap:true,multipleSelect:this.props.multipleSelect,countChoices:this.props.countChoices,numCorrect:this.props.numCorrect,choices:choicesProp,onChange:this.updateChoices,reviewModeRubric:this.props.reviewModeRubric,reviewMode:this.props.reviewMode,deselectEnabled:this.props.deselectEnabled,apiOptions:this.props.apiOptions,isLastUsedWidget:this.props.isLastUsedWidget,registerFocusFunction:i=>this.registerFocusFunction(i)})}constructor(...args){super(...args),this._renderRenderer=(content="")=>{let nextPassageRefId=1;const widgets={};const modContent=content.replace(/\{\{passage-ref (\d+) (\d+)(?: "([^"]*)")?\}\}/g,(match,passageNum,refNum,summaryText)=>{const widgetId="passage-ref "+nextPassageRefId;nextPassageRefId++;widgets[widgetId]={type:"passage-ref",graded:false,options:{passageNumber:parseInt(passageNum),referenceNumber:parseInt(refNum),summaryText:summaryText},version:PassageRef$1.version};return "[["+Util.snowman+" "+widgetId+"]]"});return jsxRuntimeExports.jsx(Renderer,{content:modContent,widgets:widgets,findExternalWidgets:this.props.findWidgets,alwaysUpdate:true,linterContext:{...this.props.linterContext,blockHighlight:true},strings:this.context.strings},"choiceContentRenderer")},this.updateChoices=checkedChoiceIds=>{const{choiceStates,choices}=this.props;const newChoiceStates=choiceStates?choiceStates.map(state=>({...state})):choices.map(()=>({selected:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false,readOnly:false}));newChoiceStates.forEach((choiceState,i)=>{const choiceId=choices[i].id;choiceState.selected=checkedChoiceIds.includes(choiceId);});this.props.onChange({choiceStates:newChoiceStates});this.props.trackInteraction();};}};Radio$2.contextType=PerseusI18nContext;Radio$2.defaultProps={choices:[],multipleSelect:false,countChoices:false,deselectEnabled:false,linterContext:PerseusLinter.linterContextDefault,showSolutions:"none"};
|
|
1811
1811
|
|
|
1812
|
-
function initChoiceStates(choices){return choices.map(()=>({highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false,readOnly:false}))}let Radio$1 = class Radio extends Radio$2{UNSAFE_componentWillUpdate(nextProps){if(!___default.default.isEqual(nextProps.choices,this.props.choices)){this.setState({choiceStates:initChoiceStates(nextProps.choices)});}}getSerializedState(){const{userInput:_,...rest}=this._mergePropsAndState();return {...rest}}_handleChange(arg){const newChoiceStates=arg.choiceStates;if(newChoiceStates){this.setState({choiceStates:newChoiceStates.map(choiceState=>{const{selected:_,...rest}=choiceState;return {...rest}})},()=>{const props=this._mergePropsAndState();const mergedProps={...props,choiceStates:perseusCore.deepClone(props.choiceStates||[]).map((choiceState,index)=>{return {...choiceState,selected:newChoiceStates[index].selected}})};const unshuffledUserInput=getUserInputFromSerializedState$f(mergedProps);this.props.handleUserInput(unshuffledUserInput);});}else {throw new Error("unhandled onChange call in Radio!")}}_mergePropsAndState(){return {...this.props,choiceStates:this.state.choiceStates?.map((choiceState,index)=>{const choice=this.props.choices[index];const selected=this.props.userInput?.
|
|
1812
|
+
function initChoiceStates(choices){return choices.map(()=>({highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false,readOnly:false}))}let Radio$1 = class Radio extends Radio$2{UNSAFE_componentWillUpdate(nextProps){if(!___default.default.isEqual(nextProps.choices,this.props.choices)){this.setState({choiceStates:initChoiceStates(nextProps.choices)});}}getSerializedState(){const{userInput:_,...rest}=this._mergePropsAndState();return {...rest}}_handleChange(arg){const newChoiceStates=arg.choiceStates;if(newChoiceStates){this.setState({choiceStates:newChoiceStates.map(choiceState=>{const{selected:_,...rest}=choiceState;return {...rest}})},()=>{const props=this._mergePropsAndState();const mergedProps={...props,choiceStates:perseusCore.deepClone(props.choiceStates||[]).map((choiceState,index)=>{return {...choiceState,selected:newChoiceStates[index].selected}})};const unshuffledUserInput=getUserInputFromSerializedState$f(mergedProps);this.props.handleUserInput(unshuffledUserInput);});}else {throw new Error("unhandled onChange call in Radio!")}}_mergePropsAndState(){return {...this.props,choiceStates:this.state.choiceStates?.map((choiceState,index)=>{const choice=this.props.choices[index];const selected=this.props.userInput?.selectedChoiceIds.includes(choice.id)??false;return {...choiceState,selected}}),onChange:arg=>this._handleChange(arg)}}focus(choiceIndex){if(this.radioRef.current?.focus){return this.radioRef.current.focus(choiceIndex)}return false}render(){const props=this._mergePropsAndState();return this.ffIsOn?jsxRuntimeExports.jsx(Radio$3,{...props}):jsxRuntimeExports.jsx(Radio$2,{ref:this.radioRef,...props})}constructor(props){super(props),this.ffIsOn=false,this.radioRef=React__namespace.createRef(),this.state={choiceStates:[]};this.ffIsOn=props.apiOptions.flags?.["new-radio-widget"]??false;this.state={choiceStates:initChoiceStates(props.choices)};}};
|
|
1813
1813
|
|
|
1814
|
-
const _choiceTransform=(widgetOptions,strings)=>{const _maybeRandomize=function(array){return widgetOptions.randomize?perseusCore.randomizeArrayElements(array):array};const _addNoneOfAbove=function(choices){let noneOfTheAbove=null;const newChoices=choices.filter((choice,index)=>{if(choice.isNoneOfTheAbove){noneOfTheAbove=choice;return false}return true});if(noneOfTheAbove){newChoices.push(noneOfTheAbove);}return newChoices};const enforceOrdering=choices=>{const ReversedChoices=[[strings.false,strings.true],[strings.no,strings.yes]];const content=choices.map(c=>c.content);if(ReversedChoices.some(reversed=>___default.default.isEqual(content,reversed))){return [choices[1],choices[0]]}return choices};const choices=widgetOptions.choices.map((choice,i)=>{return {...choice,originalIndex:i,correct:Boolean(choice.correct)}});return _addNoneOfAbove(enforceOrdering(_maybeRandomize(choices)))};const transform$1=(widgetOptions,strings)=>{const choices=_choiceTransform(widgetOptions,strings);const{hasNoneOfTheAbove,multipleSelect,countChoices,deselectEnabled,numCorrect}=widgetOptions;return {numCorrect:numCorrect,hasNoneOfTheAbove,multipleSelect,countChoices,deselectEnabled,choices,selectedChoices:___default.default.pluck(choices,"correct")}};function getStartUserInput$g(
|
|
1814
|
+
const _choiceTransform=(widgetOptions,strings)=>{const _maybeRandomize=function(array){return widgetOptions.randomize?perseusCore.randomizeArrayElements(array):array};const _addNoneOfAbove=function(choices){let noneOfTheAbove=null;const newChoices=choices.filter((choice,index)=>{if(choice.isNoneOfTheAbove){noneOfTheAbove=choice;return false}return true});if(noneOfTheAbove){newChoices.push(noneOfTheAbove);}return newChoices};const enforceOrdering=choices=>{const ReversedChoices=[[strings.false,strings.true],[strings.no,strings.yes]];const content=choices.map(c=>c.content);if(ReversedChoices.some(reversed=>___default.default.isEqual(content,reversed))){return [choices[1],choices[0]]}return choices};const choices=widgetOptions.choices.map((choice,i)=>{return {...choice,originalIndex:i,correct:Boolean(choice.correct)}});return _addNoneOfAbove(enforceOrdering(_maybeRandomize(choices)))};const transform$1=(widgetOptions,strings)=>{const choices=_choiceTransform(widgetOptions,strings);const{hasNoneOfTheAbove,multipleSelect,countChoices,deselectEnabled,numCorrect}=widgetOptions;return {numCorrect:numCorrect,hasNoneOfTheAbove,multipleSelect,countChoices,deselectEnabled,choices,selectedChoices:___default.default.pluck(choices,"correct")}};function getStartUserInput$g(){return {selectedChoiceIds:[]}}function getCorrectUserInput$6(options){return {selectedChoiceIds:options.choices.filter(option=>option.correct).map(option=>option.id)}}var Radio = {name:"radio",displayName:"Radio / Multiple choice",widget:Radio$1,transform: transform$1,staticTransform:transform$1,getStartUserInput: getStartUserInput$g,getCorrectUserInput: getCorrectUserInput$6,version:perseusCore.radioLogic.version,isLintable:true,getUserInputFromSerializedState:serializedState=>{return getUserInputFromSerializedState$f(serializedState,true)}};
|
|
1815
1815
|
|
|
1816
1816
|
var basicWidgets = [Radio,InputNumber$1,NumericInput$1,Expression$1];
|
|
1817
1817
|
|
|
@@ -1887,7 +1887,9 @@ const{updateQueryString}=Util;class Iframe extends React__namespace.Component{co
|
|
|
1887
1887
|
|
|
1888
1888
|
const getPromptJSON$d=renderProps=>{return {type:"image",options:{altText:renderProps.alt,title:renderProps.title,caption:renderProps.caption,imageUrl:renderProps.backgroundImage.url}}};
|
|
1889
1889
|
|
|
1890
|
-
const
|
|
1890
|
+
const ImageComponent=({apiOptions,alt,backgroundImage,box,caption,linterContext,labels,range,title,trackInteraction})=>{const context=React__namespace.useContext(PerseusI18nContext);return jsxRuntimeExports.jsxs("figure",{className:"perseus-image-widget",style:{maxWidth:backgroundImage.width},children:[title&&jsxRuntimeExports.jsx("div",{className:"perseus-image-title",children:jsxRuntimeExports.jsx(Renderer,{content:title,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})}),backgroundImage.url&&jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,alt:caption===alt?"":alt,width:backgroundImage.width,height:backgroundImage.height,preloader:apiOptions.imagePreloader,extraGraphie:{box:box,range:range,labels:labels},trackInteraction:trackInteraction,zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,setAssetStatus:setAssetStatus})}),caption&&jsxRuntimeExports.jsx("figcaption",{className:"perseus-image-caption",style:{maxWidth:backgroundImage.width},children:jsxRuntimeExports.jsx(Renderer,{content:caption,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})})]})};
|
|
1891
|
+
|
|
1892
|
+
const defaultBoxSize=400;const defaultRange=[0,10];const defaultBackgroundImage$1={url:null,width:0,height:0};class ImageWidget extends React__namespace.Component{getPromptJSON(){return getPromptJSON$d(this.props)}render(){return jsxRuntimeExports.jsx(ImageComponent,{...this.props})}constructor(...args){super(...args),this.isWidget=true;}}ImageWidget.contextType=PerseusI18nContext;ImageWidget.defaultProps={alignment:"block",title:"",range:[defaultRange,defaultRange],box:[defaultBoxSize,defaultBoxSize],backgroundImage:defaultBackgroundImage$1,labels:[],alt:"",caption:"",linterContext:PerseusLinter.linterContextDefault};var Image$1 = {name:"image",displayName:"Image",widget:ImageWidget,isLintable:true};
|
|
1891
1893
|
|
|
1892
1894
|
const getPromptJSON$c=()=>{return getUnsupportedPromptJSON("interaction")};
|
|
1893
1895
|
|
|
@@ -2124,7 +2126,7 @@ var extraWidgets = [CSProgram$1,Categorizer$1,Definition$1,DeprecatedStandin$1,D
|
|
|
2124
2126
|
|
|
2125
2127
|
const init=function(){registerWidgets(basicWidgets);registerWidgets(extraWidgets);replaceDeprecatedWidgets();};
|
|
2126
2128
|
|
|
2127
|
-
const libName="@khanacademy/perseus";const libVersion="67.
|
|
2129
|
+
const libName="@khanacademy/perseus";const libVersion="67.1.0";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
2128
2130
|
|
|
2129
2131
|
const apiVersion={major:12,minor:0};
|
|
2130
2132
|
|
|
@@ -2158,7 +2160,7 @@ Items:
|
|
|
2158
2160
|
${items.join("\n")}
|
|
2159
2161
|
`);}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} |
|
|
2160
2162
|
| --- | --- |`;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}
|
|
2161
|
-
${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 getImagesWithoutAltData(perseusRenderer){if(!perseusRenderer.widgets){return ""}const imgsWithoutAltData=[];Object.entries(perseusRenderer.widgets).forEach(([widgetId,widget])=>{if(!widget.options){return}if(widget.type==="image"&&!widget.options.alt&&widget.options.backgroundImage?.url){imgsWithoutAltData.push({widgetId,imgUrl:widget.options.backgroundImage.url});}});return JSON.stringify(imgsWithoutAltData)}const INDIVIDUAL_ANSWER_WIDGETS=["interactive-graph","categorizer","grapher"];const SUPPORTED_WIDGETS=["radio","numeric-input","input-number","expression",...INDIVIDUAL_ANSWER_WIDGETS];const isWrongAnswerSupported=(widgetIds,widgetMap)=>{return widgetIds.length!==0&&widgetIds.every(widgetId=>SUPPORTED_WIDGETS.includes(getWidgetTypeByWidgetId(widgetId,widgetMap)))};const shouldHaveIndividualAnswer=(widgetId,widgetMap)=>{return INDIVIDUAL_ANSWER_WIDGETS.includes(getWidgetTypeByWidgetId(widgetId,widgetMap))};const getAnswerFromUserInput=(widgetType,userInput)=>{switch(widgetType){case "categorizer":return userInput.values;case "input-number":return userInput.currentValue;case "numeric-input":return userInput.currentValue;case "radio":return userInput.
|
|
2163
|
+
${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 getImagesWithoutAltData(perseusRenderer){if(!perseusRenderer.widgets){return ""}const imgsWithoutAltData=[];Object.entries(perseusRenderer.widgets).forEach(([widgetId,widget])=>{if(!widget.options){return}if(widget.type==="image"&&!widget.options.alt&&widget.options.backgroundImage?.url){imgsWithoutAltData.push({widgetId,imgUrl:widget.options.backgroundImage.url});}});return JSON.stringify(imgsWithoutAltData)}const INDIVIDUAL_ANSWER_WIDGETS=["interactive-graph","categorizer","grapher"];const SUPPORTED_WIDGETS=["radio","numeric-input","input-number","expression",...INDIVIDUAL_ANSWER_WIDGETS];const isWrongAnswerSupported=(widgetIds,widgetMap)=>{return widgetIds.length!==0&&widgetIds.every(widgetId=>SUPPORTED_WIDGETS.includes(getWidgetTypeByWidgetId(widgetId,widgetMap)))};const shouldHaveIndividualAnswer=(widgetId,widgetMap)=>{return INDIVIDUAL_ANSWER_WIDGETS.includes(getWidgetTypeByWidgetId(widgetId,widgetMap))};const getAnswerFromUserInput=(widgetType,userInput)=>{switch(widgetType){case "categorizer":return userInput.values;case "input-number":return userInput.currentValue;case "numeric-input":return userInput.currentValue;case "radio":return userInput.selectedChoiceIds}return userInput};const getCorrectAnswerForWidgetId=(widgetId,itemData)=>{const rubric=itemData.question.widgets[widgetId].options;const widgetMap=getWidgetsMapFromItemData(itemData);const widgetType=getWidgetTypeByWidgetId(widgetId,widgetMap);const widget=getWidgetExport(widgetType);return widget?.getOneCorrectAnswerFromRubric?.(rubric)};const isWidgetIdInContent=(perseusItem,widgetId)=>{return perseusItem.question.content.indexOf(widgetId)!==-1};const getValidWidgetIds=perseusItem=>{const{widgets}=perseusItem.question;return wonderStuffCore.keys(widgets).filter(id=>isWidgetIdInContent(perseusItem,id))};
|
|
2162
2164
|
|
|
2163
2165
|
function generateTestRadioWidget(){return {type:"radio",options:{choices:[]}}}function generateTestInteractiveGraphWidget(){return {type:"interactive-graph",options:{step:[1,1],gridStep:[1,1],snapStep:[1,1],markings:"graph",labels:["x","y"],lockedFigures:[],showProtractor:false,range:[[-10,10],[-10,10]],graph:{type:"angle"},correct:{type:"angle"},showAxisArrows:{xMin:true,xMax:true,yMin:true,yMax:true}}}}function generateTestCategorizerWidget(){return {type:"categorizer",options:{items:[],categories:[],randomizeItems:false,static:false,values:[]}}}function generateTestExpressionWidget(){return {type:"expression",options:{answerForms:[],buttonSets:["basic"],functions:[],times:false}}}function generateTestNumericInputWidget(){return {type:"numeric-input",options:{answers:[],labelText:"",size:"normal",coefficient:false,static:false}}}
|
|
2164
2166
|
|