@khanacademy/perseus 66.4.0 → 67.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.
package/dist/index.js CHANGED
@@ -1713,7 +1713,7 @@ var widgets$1 = /*#__PURE__*/Object.freeze({
1713
1713
 
1714
1714
  class WidgetContainer extends React__namespace.Component{componentDidMount(){if(this.state.widgetProps.apiOptions.isMobile){const containerWidth=ReactDOM__namespace.default.findDOMNode(this).offsetWidth;this.setState({sizeClass:getClassFromWidth(containerWidth)});}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.type!==nextProps.type){throw new Error("WidgetContainer can't change widget type; set a different "+"key instead to recreate the container.")}}shouldComponentUpdate(nextProps,nextState){return this.props.shouldHighlight!==nextProps.shouldHighlight||this.props.type!==nextProps.type||this.state.widgetProps!==nextState.widgetProps||this.state.sizeClass!==nextState.sizeClass}render(){let className=classNames__default.default({"perseus-widget-container":true,"widget-highlight":this.props.shouldHighlight,"widget-nohighlight":!this.props.shouldHighlight,"perseus-widget__definition":this.props.type==="definition"});const type=this.props.type;const userAgent=navigator.userAgent;const WidgetType=getWidget(type);if(WidgetType==null){console.warn(`Widget type '${type}' not found!`);return jsxRuntimeExports.jsx("div",{className:className})}let subType="null";if(type==="interactive-graph"){const props=this.state.widgetProps;subType=props.graph?.type??"null";}let alignment=this.state.widgetProps.alignment;if(alignment==="default"){alignment=perseusCore.CoreWidgetRegistry.getDefaultAlignment(type);}className+=" widget-"+alignment;const apiOptions=this.state.widgetProps.apiOptions;const isStatic=this.state.widgetProps.static||apiOptions.readOnly;const staticContainerStyles={position:"relative",overflow:"visible"};const staticOverlayStyles={width:"100%",height:"100%",position:"absolute",top:0,left:0,zIndex:3};const linterContext=isLintable(type)?this.props.linterContext:{...this.props.linterContext,highlightLint:false};return jsxRuntimeExports.jsx("div",{className:className,style:isStatic?staticContainerStyles:{},children:jsxRuntimeExports.jsx(DependenciesContext.Consumer,{children:({analytics})=>jsxRuntimeExports.jsxs(ErrorBoundary,{metadata:{widget_type:type,widget_id:this.props.id},onError:error=>{analytics.onAnalyticsEvent({type:"perseus:widget-rendering-error:ti",payload:{widgetSubType:subType,widgetType:type,widgetId:this.props.id,message:error.message,userAgent:userAgent}});},children:[jsxRuntimeExports.jsx(WidgetType,{...this.state.widgetProps,linterContext:linterContext,containerSizeClass:this.state.sizeClass,ref:this.widgetRef}),isStatic&&jsxRuntimeExports.jsx("div",{style:staticOverlayStyles})]})})})}constructor(...args){super(...args),this.widgetRef=React__namespace.createRef(),this.state={sizeClass:containerSizeClass.MEDIUM,widgetProps:this.props.initialProps},this.getWidget=()=>{return this.widgetRef.current},this.replaceWidgetProps=newWidgetProps=>{this.setState({widgetProps:newWidgetProps});};}}WidgetContainer.defaultProps={linterContext:PerseusLinter.linterContextDefault};
1715
1715
 
1716
- const rContainsNonWhitespace=/\S/;const rImageURL=/(web\+graphie|https):\/\/[^\s]*/;const noopOnRender=()=>{};const makeContainerId=id=>"container:"+id;const isIdPathPrefix=function(prefixArray,wholeArray){if(prefixArray===null||wholeArray===null){return prefixArray===wholeArray}return ___default.default.every(prefixArray,(elem,i)=>{if(wholeArray!=null){return ___default.default.isEqual(elem,wholeArray[i])}})};function isDifferentQuestion(propsA,propsB){function makeItem(props){return perseusCore.splitPerseusItem({question:{content:props.content,widgets:props.widgets,images:{}},hints:[],answerArea:perseusCore.getDefaultAnswerArea()})}return propsA.problemNum!==propsB.problemNum||!___default.default.isEqual(makeItem(propsA),makeItem(propsB))}class Renderer extends React__namespace.Component{componentDidMount(){this._isMounted=true;this.handleRender({});this._currentFocus=null;this.props.initializeUserInput?.(this.props.widgets,this.props.problemNum??0);if(this.props.serializedState){this.restoreSerializedState(this.props.serializedState);}if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}}UNSAFE_componentWillReceiveProps(nextProps){if(isDifferentQuestion(this.props,nextProps)){this.props.initializeUserInput?.(nextProps.widgets,nextProps.problemNum??0);this.setState(this._getInitialWidgetState(nextProps));}}shouldComponentUpdate(nextProps,nextState){if(this.props.alwaysUpdate){return true}const stateChanged=!___default.default.isEqual(this.state,nextState);const propsChanged=!___default.default.isEqual(this.props,nextProps);return propsChanged||stateChanged}UNSAFE_componentWillUpdate(nextProps,nextState){const oldJipt=this.shouldRenderJiptPlaceholder(this.props,this.state);const newJipt=this.shouldRenderJiptPlaceholder(nextProps,nextState);const oldContent=this.getContent(this.props,this.state);const newContent=this.getContent(nextProps,nextState);const oldHighlightedWidgets=this.props.highlightedWidgets;const newHighlightedWidgets=nextProps.highlightedWidgets;this.reuseMarkdown=!oldJipt&&!newJipt&&oldContent===newContent&&___default.default.isEqual(this.state.translationLintErrors,nextState.translationLintErrors)&&(!this.props.linterContext.highlightLint||___default.default.isEqual(this.props.widgets,nextProps.widgets))&&this.props.linterContext.highlightLint===nextProps.linterContext.highlightLint&&oldHighlightedWidgets===newHighlightedWidgets;}componentDidUpdate(prevProps,prevState){this.handleRender(prevProps);this.widgetIds.forEach(id=>{const container=this._widgetContainers.get(makeContainerId(id));container?.replaceWidgetProps(this.getWidgetProps(id));});if(this.props.serializedState&&!___default.default.isEqual(this.props.serializedState,prevProps.serializedState)){this.restoreSerializedState(this.props.serializedState);}if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}}componentWillUnmount(){this.widgetIds=[];if(this.translationIndex!=null){getDependencies().rendererTranslationComponents.removeComponentAtIndex(this.translationIndex);}this._isMounted=false;}getWidgetProps(widgetId){const apiOptions=this.getApiOptions();const widgetProps=this.state.widgetProps[widgetId]||{};const widgetInfo=this.state.widgetInfo[widgetId];const reviewModeRubric=this.props.reviewMode&&widgetInfo?widgetInfo.options:null;if(!this._interactionTrackers){this._interactionTrackers={};}let interactionTracker=this._interactionTrackers[widgetId];if(!interactionTracker){interactionTracker=this._interactionTrackers[widgetId]=new InteractionTracker(apiOptions.trackInteraction,widgetInfo&&widgetInfo.type,widgetId,getTracking(widgetInfo&&widgetInfo.type));}return {...widgetProps,userInput:this.props.userInput?.[widgetId],widgetId:widgetId,alignment:widgetInfo&&widgetInfo.alignment,static:widgetInfo?.static,problemNum:this.props.problemNum,apiOptions:this.getApiOptions(),keypadElement:this.props.keypadElement,questionCompleted:this.props.questionCompleted,showSolutions:this.props.showSolutions,onFocus:___default.default.partial(this._onWidgetFocus,widgetId),onBlur:___default.default.partial(this._onWidgetBlur,widgetId),findWidgets:this.findWidgets,reviewModeRubric:reviewModeRubric,reviewMode:this.props.reviewMode,onChange:(newProps,cb,silent=false)=>{this._setWidgetProps(widgetId,newProps,cb,silent);},handleUserInput:newUserInput=>{const updatedUserInput={...this.props.userInput,[widgetId]:newUserInput};const emptyWidgetIds=perseusScore.emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,updatedUserInput,this.context.locale);const widgetsEmpty=emptyWidgetIds.length>0;this.props.handleUserInput?.(widgetId,newUserInput,widgetsEmpty);this.props.onInteractWithWidget(widgetId);},trackInteraction:interactionTracker.track,isLastUsedWidget:widgetId===this.state.lastUsedWidgetId}}emptyWidgets(){if(!this.props.userInput){throw new Error(`emptyWidgets called without providing userInput to Renderer`)}return perseusScore.emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale)}handleStateUpdate(id,cb,silent){this.setState(prevState=>{const lastUsedWidgetId=silent?prevState.lastUsedWidgetId:id;return {lastUsedWidgetId}},()=>{setTimeout(()=>{const cbResult=cb&&cb();if(!silent){this.props.onInteractWithWidget(id);}if(cbResult!==false){this._setCurrentFocus([id]);}},0);});}_setWidgetProps(id,nextWidgetProps,cb,silent){this.setState(prevState=>{const widgetProps=nextWidgetProps?{...prevState.widgetProps,[id]:{...prevState.widgetProps[id],...nextWidgetProps}}:prevState.widgetProps;return {widgetProps}},()=>{this.handleStateUpdate(id,cb,silent);});}getUserInput(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInput called without providing userInput to Renderer`)}return this.widgetIds.map(id=>{return userInput[id]})}getUserInputMap(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInputMap called without providing userInput to Renderer`)}return userInput}getPromptJSON(){const{content}=this.props;const widgetJSON={};this.widgetIds.forEach(id=>{const widget=this.getWidgetInstance(id);widgetJSON[id]=widget?.getPromptJSON?.()||{};});return {content,widgets:widgetJSON}}score(){if(!this.props.userInput){throw new Error(`score called without providing userInput to Renderer`)}const scores=perseusScore.scoreWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale);const combinedScore=perseusScore.flattenScores(scores);return combinedScore}render(){const apiOptions=this.getApiOptions();if(this.reuseMarkdown){return this.lastRenderedMarkdown}const content=this.getContent(this.props,this.state);this.widgetIds=[];if(this.shouldRenderJiptPlaceholder(this.props,this.state)){if(!this.translationIndex){this.translationIndex=getDependencies().rendererTranslationComponents.addComponent(this);}if(!apiOptions.isArticle){return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{"data-perseus-component-index":this.translationIndex,children:content})})}}this._isTwoColumn=false;const parsedMarkdown=this.props.inline?PerseusMarkdown.parseInline(content,{isJipt:this.translationIndex!=null}):PerseusMarkdown.parse(content,{isJipt:this.translationIndex!=null});if(this.props.linterContext.highlightLint){const fullLinterContext={content:this.props.content,widgets:this.props.widgets,...this.props.linterContext};PerseusLinter__namespace.runLinter(parsedMarkdown,fullLinterContext,true);this._translationLinter.applyLintErrors(parsedMarkdown,[...this.state.translationLintErrors,...this.props.legacyPerseusLint||[]]);}const markdownContents=this.outputMarkdown(parsedMarkdown,{baseElements:apiOptions.baseElements});const className=classNames__default.default({[ClassNames.RENDERER]:true,[ClassNames.RESPONSIVE_RENDERER]:true,[ClassNames.TWO_COLUMN_RENDERER]:this._isTwoColumn});this.lastRenderedMarkdown=jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{className:className,children:markdownContents})});return this.lastRenderedMarkdown}constructor(props){super(props),this._widgetContainers=new Map,this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions}},this._getInitialWidgetState=props=>{const allWidgetInfo=perseusCore.applyDefaultsToWidgets(props.widgets);return {widgetInfo:allWidgetInfo,widgetProps:this._getAllWidgetsStartProps(allWidgetInfo,props)}},this._getAllWidgetsStartProps=(allWidgetInfo,props)=>{const{apiOptions,problemNum}=props;const widgetsStartProps={};const{strings}=this.props;wonderStuffCore.entries(allWidgetInfo).forEach(([key,widgetInfo])=>{widgetsStartProps[key]=getRendererPropsForWidgetInfo(widgetInfo,strings,problemNum);});apiOptions?.onWidgetStartProps?.(widgetsStartProps);return widgetsStartProps},this._getDefaultWidgetInfo=widgetId=>{const widgetIdParts=Util.rTypeFromWidgetId.exec(widgetId);if(widgetIdParts==null){return {}}return {type:widgetIdParts[1],graded:true,options:{}}},this._getWidgetInfo=widgetId=>{return this.state.widgetInfo[widgetId]||this._getDefaultWidgetInfo(widgetId)},this.renderWidget=(impliedType,id,state)=>{const widgetInfo=this.state.widgetInfo[id];if(widgetInfo&&widgetInfo.alignment==="full-width"){state.foundFullWidth=true;}if(widgetInfo){const type=widgetInfo&&widgetInfo.type||impliedType;const shouldHighlight=___default.default.contains(this.props.highlightedWidgets,id);return jsxRuntimeExports.jsx(WidgetContainer,{id:id,ref:node=>{const containerId=makeContainerId(id);if(node!=null){this._widgetContainers.set(containerId,node);}else {this._widgetContainers.delete(containerId);}},type:type,initialProps:this.getWidgetProps(id),shouldHighlight:shouldHighlight,linterContext:PerseusLinter__namespace.pushContextStack(this.props.linterContext,"widget")},makeContainerId(id))}return null},this.getSerializedState=widgetProps=>{return perseusCore.mapObject(widgetProps||this.state.widgetProps,(props,widgetId)=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getSerializedState){return excludeDenylistKeys(widget.getSerializedState())}return props})},this.restoreSerializedState=(serializedState,callback)=>{const serializedWidgetIds=___default.default.keys(serializedState);const widgetPropIds=___default.default.keys(this.state.widgetProps);if(serializedWidgetIds.length!==widgetPropIds.length||___default.default.intersection(serializedWidgetIds,widgetPropIds).length!==serializedWidgetIds.length){Log.error("Refusing to restore bad serialized state:",perseusCore.Errors.Internal,{loggedMetadata:{serializedState:JSON.stringify(serializedState),currentProps:JSON.stringify(this.state.widgetProps)}});return}let numCallbacks=1;const fireCallback=()=>{--numCallbacks;if(callback&&numCallbacks===0){callback();}};const restoredWidgetProps={};Object.entries(serializedState).forEach(([widgetId,props])=>{const widget=this.getWidgetInstance(widgetId);if(widget?.restoreSerializedState){++numCallbacks;const restoreResult=widget.restoreSerializedState(props,fireCallback);restoredWidgetProps[widgetId]={...this.state.widgetProps[widgetId],...restoreResult};}else {restoredWidgetProps[widgetId]=props;}});this.props.restoreUserInputFromSerializedState?.(serializedState,this.props.widgets);this.setState({widgetProps:restoredWidgetProps},()=>{setTimeout(fireCallback,0);});},this.findInternalWidgets=filterCriterion=>{let filterFunc;if(typeof filterCriterion==="string"){if(filterCriterion.indexOf(" ")!==-1){const widgetId=filterCriterion;filterFunc=(id,widgetInfo,widget)=>id===widgetId;}else {const widgetType=filterCriterion;filterFunc=(id,widgetInfo,widget)=>{return widgetInfo.type===widgetType};}}else {filterFunc=filterCriterion;}const results=this.widgetIds.filter(id=>{const widgetInfo=this._getWidgetInfo(id);const widget=this.getWidgetInstance(id);return filterFunc(id,widgetInfo,widget)}).map(this.getWidgetInstance);return results},this.findWidgets=filterCriterion=>{return [...this.findInternalWidgets(filterCriterion),...this.props.findExternalWidgets(filterCriterion)]},this.getWidgetInstance=id=>{const ref=this._widgetContainers.get(makeContainerId(id));if(!ref){return null}return ref.getWidget()},this._onWidgetFocus=(id,focusPath=[])=>{if(!___default.default.isArray(focusPath)){throw new perseusCore.PerseusError("widget props.onFocus focusPath must be an Array, "+"but was"+JSON.stringify(focusPath),perseusCore.Errors.Internal)}this._setCurrentFocus([id].concat(focusPath));},this._onWidgetBlur=(id,blurPath)=>{const blurringFocusPath=this._currentFocus;const fullPath=[id].concat(blurPath);if(!___default.default.isEqual(fullPath,blurringFocusPath)){return}___default.default.defer(()=>{if(___default.default.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.getContent=(props,state)=>{return state.jiptContent||props.content},this.shouldRenderJiptPlaceholder=(props,state)=>{return getDependencies().JIPT.useJIPT&&state.jiptContent==null&&props.content.indexOf("crwdns")!==-1},this.replaceJiptContent=(content,paragraphIndex)=>{if(paragraphIndex==null){this.setState({jiptContent:content});}else {const codeFenceRegex=/^\s*(`{3,}|~{3,})\s*(\S+)?\s*\n([\s\S]+?)\s*\1\s*$/;if(codeFenceRegex.test(content));else if(/\S\n\s*\n\S/.test(content)){content="$\\large{\\red{\\text{Please translate each "+"paragraph to a single paragraph.}}}$";}else if(/^\s*$/.test(content)){content="$\\large{\\red{\\text{Translated paragraph is "+"currently empty}}}$";}const allContent=this.getContent(this.props,this.state);const paragraphs=JiptParagraphs.parseToArray(allContent);paragraphs[paragraphIndex]=content;this.setState({jiptContent:JiptParagraphs.joinFromArray(paragraphs)});}},this.outputMarkdown=(ast,state)=>{if(___default.default.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;state.paragraphIndex=i;const nodeOut=this.outputMarkdown(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}this._foundTextNodes=false;state.foundFullWidth=false;const output=this.outputNested(ast,state);let className;if(this.translationIndex!=null){className=null;}else {className=classNames__default.default({"perseus-paragraph-centered":!this._foundTextNodes,"perseus-paragraph-full-width":state.foundFullWidth&&ast.content.length===1});}return jsxRuntimeExports.jsx(QuestionParagraph,{className:className,translationIndex:this.translationIndex,paragraphIndex:state.paragraphIndex,inline:this.props.inline,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:output})},state.key)},this.outputNested=(ast,state)=>{if(___default.default.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;const nodeOut=this.outputNested(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}return this.outputNode(ast,this.outputNested,state)},this.outputNode=(node,nestedOutput,state)=>{const apiOptions=this.getApiOptions();const imagePlaceholder=apiOptions.imagePlaceholder;if(node.type==="widget"){const widgetPlaceholder=apiOptions.widgetPlaceholder;if(widgetPlaceholder){return widgetPlaceholder}this._foundTextNodes=true;if(this.widgetIds.includes(node.id)){return jsxRuntimeExports.jsx("span",{className:"renderer-widget-error",children:["Widget [[","☃"," ",node.id,"]] already exists."].join("")},state.key)}this.widgetIds.push(node.id);return this.renderWidget(node.widgetType,node.id,state)}if(node.type==="blockMath"){const content=preprocessTex(node.content);const innerStyle={overflowX:"auto",overflowY:"hidden",paddingTop:10,paddingBottom:10,marginTop:-10,marginBottom:-10};if(apiOptions.isMobile){const margin=16;const outerStyle={marginLeft:-16,marginRight:-16};const horizontalPadding={paddingLeft:margin,paddingRight:margin};const mobileInnerStyle={...innerStyle,...styles$E.mobileZoomableParentFix};return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",style:outerStyle,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:{...mobileInnerStyle,...horizontalPadding},children:jsxRuntimeExports.jsx(ZoomableTeX,{children:content})})})},state.key)}return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:innerStyle,children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{setAssetStatus:setAssetStatus,children:content})})})})},state.key)}if(node.type==="math"){const tex=node.content;return jsxRuntimeExports.jsx("span",{style:{whiteSpace:"nowrap"},children:jsxRuntimeExports.jsxs(ErrorBoundary,{children:[jsxRuntimeExports.jsx("span",{}),jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.props.onRender,setAssetStatus:setAssetStatus,children:tex})}),jsxRuntimeExports.jsx("span",{})]})},state.key)}if(node.type==="image"){if(imagePlaceholder){return imagePlaceholder}const extraAttrs=___default.default.has(this.props.images,node.target)?this.props.images[node.target]:null;const responsive=!state.inTable;return jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{setAssetStatus:setAssetStatus,src:PerseusMarkdown.sanitizeUrl(node.target),alt:node.alt,title:node.title,responsive:responsive,onUpdate:this.props.onRender,zoomToFullSizeOnMobile:apiOptions.isMobile&&apiOptions.isArticle,...extraAttrs})})},state.key)}if(node.type==="columns"){this._isTwoColumn=true;return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)}if(node.type==="text"){if(rContainsNonWhitespace.test(node.content)){this._foundTextNodes=true;}if(imagePlaceholder&&rImageURL.test(node.content)){return imagePlaceholder}return node.content}if(node.type==="table"||node.type==="titledTable"){const output=PerseusMarkdown.ruleOutput(node,nestedOutput,{...state,isMobile:apiOptions.isMobile,inTable:true});if(!apiOptions.isMobile){return output}const outerStyle={marginLeft:-16,marginRight:-16};const innerStyle={paddingLeft:0,paddingRight:0};const mobileInnerStyle={...innerStyle,...styles$E.mobileZoomableParentFix};const wrappedOutput=jsxRuntimeExports.jsx("div",{style:{...mobileInnerStyle,overflowX:"auto"},children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(Zoomable,{animateHeight:true,children:output})})});return jsxRuntimeExports.jsx("div",{style:outerStyle,children:wrappedOutput})}return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)},this.handleRender=prevProps=>{const onRender=this.props.onRender;const oldOnRender=prevProps.onRender;if(onRender!==noopOnRender||oldOnRender!==noopOnRender){const $images=$__default.default(ReactDOM__namespace.default.findDOMNode(this)).find("img");if(oldOnRender!==noopOnRender){$images.off("load",oldOnRender);}if(onRender!==noopOnRender){$images.on("load",onRender);}}onRender();},this._setCurrentFocus=path=>{const apiOptions=this.getApiOptions();if(!isIdPathPrefix(path,this._currentFocus)){const prevFocus=this._currentFocus;if(prevFocus){this.blurPath(prevFocus);}this._currentFocus=path;apiOptions.onFocusChange(this._currentFocus,prevFocus);}},this.focus=()=>{let id;let focusResult;for(let i=0;i<this.widgetIds.length;i++){const widgetId=this.widgetIds[i];const widget=this.getWidgetInstance(widgetId);const widgetFocusResult=widget?.focus?.();if(widgetFocusResult){id=widgetId;focusResult=widgetFocusResult;break}}if(id){let path;if(typeof focusResult==="object"){path=[id].concat(focusResult.path||[]);Log.error("Renderer received a focus result of type 'object' "+"instead of the expected type 'boolean'",perseusCore.Errors.Internal,{loggedMetadata:{focusResult:JSON.stringify(focusResult),currentProps:JSON.stringify(this.state.widgetProps)}});}else {path=[id];}this._setCurrentFocus(path);return true}},this.getDOMNodeForPath=path=>{const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget?.getDOMNodeForPath){return widget.getDOMNodeForPath(interWidgetPath)}if(interWidgetPath.length===0){return ReactDOM__namespace.default.findDOMNode(widget)}},this.getInputPaths=()=>{const inputPaths=[];this.widgetIds.forEach(widgetId=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getInputPaths){const widgetInputPaths=widget.getInputPaths();widgetInputPaths.forEach(inputPath=>{const relativeInputPath=[widgetId].concat(inputPath);inputPaths.push(relativeInputPath);});}});return inputPaths},this.focusPath=path=>{if(___default.default.isEqual(this._currentFocus,path)){return}if(this._currentFocus){this.blurPath(this._currentFocus);}const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const focusWidget=this.getWidgetInstance(widgetId);focusWidget?.focusInputPath?.(interWidgetPath);},this.blurPath=path=>{if(!___default.default.isEqual(this._currentFocus,path)){return}const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget){const blurWidget=this.getWidgetInstance(widgetId);blurWidget?.blurInputPath?.(interWidgetPath);}},this.blur=()=>{if(this._currentFocus){this.blurPath(this._currentFocus);}},this.serialize=()=>{const state={};___default.default.each(this.state.widgetInfo,function(info,id){const widget=this.getWidgetInstance(id);const s=widget.serialize();if(!___default.default.isEmpty(s)){state[id]=s;}},this);return state},this.getWidgetIds=()=>{return this.widgetIds},this.handletranslationLintErrors=lintErrors=>{if(!this._isMounted){return}this.setState({translationLintErrors:lintErrors});};this._translationLinter=new TranslationLinter;this.state={jiptContent:null,translationLintErrors:[],lastUsedWidgetId:null,...this._getInitialWidgetState(props)};}}Renderer.contextType=PerseusI18nContext;Renderer.defaultProps={content:"",widgets:{},images:{},highlightedWidgets:[],questionCompleted:false,showSolutions:"none",onRender:noopOnRender,onInteractWithWidget:function(){},findExternalWidgets:()=>[],alwaysUpdate:false,reviewMode:false,serializedState:null,linterContext:PerseusLinter__namespace.linterContextDefault};const styles$E={mobileZoomableParentFix:{transform:"translate3d(0,0,0)"}};
1716
+ const rContainsNonWhitespace=/\S/;const rImageURL=/(web\+graphie|https):\/\/[^\s]*/;const noopOnRender=()=>{};const makeContainerId=id=>"container:"+id;const isIdPathPrefix=function(prefixArray,wholeArray){if(prefixArray===null||wholeArray===null){return prefixArray===wholeArray}return ___default.default.every(prefixArray,(elem,i)=>{if(wholeArray!=null){return ___default.default.isEqual(elem,wholeArray[i])}})};function isDifferentQuestion(propsA,propsB){function makeItem(props){return perseusCore.splitPerseusItem({question:{content:props.content,widgets:props.widgets,images:{}},hints:[],answerArea:perseusCore.getDefaultAnswerArea()})}return propsA.problemNum!==propsB.problemNum||!___default.default.isEqual(makeItem(propsA),makeItem(propsB))}class Renderer extends React__namespace.Component{componentDidMount(){this._isMounted=true;this.handleRender({});this._currentFocus=null;this.props.initializeUserInput?.(this.props.widgets,this.props.problemNum??0);if(this.props.serializedState){this.restoreSerializedState(this.props.serializedState);}if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}}UNSAFE_componentWillReceiveProps(nextProps){if(isDifferentQuestion(this.props,nextProps)){this.props.initializeUserInput?.(nextProps.widgets,nextProps.problemNum??0);this.setState(this._getInitialWidgetState(nextProps));}}shouldComponentUpdate(nextProps,nextState){if(this.props.alwaysUpdate){return true}const stateChanged=!___default.default.isEqual(this.state,nextState);const propsChanged=!___default.default.isEqual(this.props,nextProps);return propsChanged||stateChanged}UNSAFE_componentWillUpdate(nextProps,nextState){const oldJipt=this.shouldRenderJiptPlaceholder(this.props,this.state);const newJipt=this.shouldRenderJiptPlaceholder(nextProps,nextState);const oldContent=this.getContent(this.props,this.state);const newContent=this.getContent(nextProps,nextState);const oldHighlightedWidgets=this.props.highlightedWidgets;const newHighlightedWidgets=nextProps.highlightedWidgets;this.reuseMarkdown=!oldJipt&&!newJipt&&oldContent===newContent&&___default.default.isEqual(this.state.translationLintErrors,nextState.translationLintErrors)&&(!this.props.linterContext.highlightLint||___default.default.isEqual(this.props.widgets,nextProps.widgets))&&this.props.linterContext.highlightLint===nextProps.linterContext.highlightLint&&oldHighlightedWidgets===newHighlightedWidgets;}componentDidUpdate(prevProps,prevState){this.handleRender(prevProps);this.widgetIds.forEach(id=>{const container=this._widgetContainers.get(makeContainerId(id));container?.replaceWidgetProps(this.getWidgetProps(id));});if(this.props.serializedState&&!___default.default.isEqual(this.props.serializedState,prevProps.serializedState)){this.restoreSerializedState(this.props.serializedState);}if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}}componentWillUnmount(){this.widgetIds=[];if(this.translationIndex!=null){getDependencies().rendererTranslationComponents.removeComponentAtIndex(this.translationIndex);}this._isMounted=false;}getWidgetProps(widgetId){const apiOptions=this.getApiOptions();const widgetProps=this.state.widgetProps[widgetId]||{};const widgetInfo=this.state.widgetInfo[widgetId];const reviewModeRubric=this.props.reviewMode&&widgetInfo?widgetInfo.options:null;if(!this._interactionTrackers){this._interactionTrackers={};}let interactionTracker=this._interactionTrackers[widgetId];if(!interactionTracker){interactionTracker=this._interactionTrackers[widgetId]=new InteractionTracker(apiOptions.trackInteraction,widgetInfo&&widgetInfo.type,widgetId,getTracking(widgetInfo&&widgetInfo.type));}return {...widgetProps,userInput:this.props.userInput?.[widgetId],widgetId:widgetId,alignment:widgetInfo&&widgetInfo.alignment,static:widgetInfo?.static,problemNum:this.props.problemNum,apiOptions:this.getApiOptions(),keypadElement:this.props.keypadElement,questionCompleted:this.props.questionCompleted,showSolutions:this.props.showSolutions,onFocus:___default.default.partial(this._onWidgetFocus,widgetId),onBlur:___default.default.partial(this._onWidgetBlur,widgetId),findWidgets:this.findWidgets,reviewModeRubric:reviewModeRubric,reviewMode:this.props.reviewMode,onChange:(newProps,cb,silent=false)=>{this._setWidgetProps(widgetId,newProps,cb,silent);},handleUserInput:newUserInput=>{const updatedUserInput={...this.props.userInput,[widgetId]:newUserInput};const emptyWidgetIds=perseusScore.emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,updatedUserInput,this.context.locale);const widgetsEmpty=emptyWidgetIds.length>0;this.props.handleUserInput?.(widgetId,newUserInput,widgetsEmpty);this.props.onInteractWithWidget(widgetId);},trackInteraction:interactionTracker.track,isLastUsedWidget:widgetId===this.state.lastUsedWidgetId}}emptyWidgets(){if(!this.props.userInput){throw new Error(`emptyWidgets called without providing userInput to Renderer`)}return perseusScore.emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale)}handleStateUpdate(id,cb,silent){this.setState(prevState=>{const lastUsedWidgetId=silent?prevState.lastUsedWidgetId:id;return {lastUsedWidgetId}},()=>{setTimeout(()=>{const cbResult=cb&&cb();if(!silent){this.props.onInteractWithWidget(id);}if(cbResult!==false){this._setCurrentFocus([id]);}},0);});}_setWidgetProps(id,nextWidgetProps,cb,silent){this.setState(prevState=>{const widgetProps=nextWidgetProps?{...prevState.widgetProps,[id]:{...prevState.widgetProps[id],...nextWidgetProps}}:prevState.widgetProps;return {widgetProps}},()=>{this.handleStateUpdate(id,cb,silent);});}getUserInput(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInput called without providing userInput to Renderer`)}return this.widgetIds.map(id=>{return userInput[id]})}getUserInputMap(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInputMap called without providing userInput to Renderer`)}return userInput}getPromptJSON(){const{content}=this.props;const widgetJSON={};this.widgetIds.forEach(id=>{const widget=this.getWidgetInstance(id);widgetJSON[id]=widget?.getPromptJSON?.()||{};});return {content,widgets:widgetJSON}}score(){if(!this.props.userInput){throw new Error(`score called without providing userInput to Renderer`)}const scores=perseusScore.scoreWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale);const combinedScore=perseusScore.flattenScores(scores);return combinedScore}render(){const apiOptions=this.getApiOptions();if(this.reuseMarkdown){return this.lastRenderedMarkdown}const content=this.getContent(this.props,this.state);this.widgetIds=[];if(this.shouldRenderJiptPlaceholder(this.props,this.state)){if(!this.translationIndex){this.translationIndex=getDependencies().rendererTranslationComponents.addComponent(this);}if(!apiOptions.isArticle){return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{"data-perseus-component-index":this.translationIndex,children:content})})}}this._isTwoColumn=false;const parsedMarkdown=this.props.inline?PerseusMarkdown.parseInline(content,{isJipt:this.translationIndex!=null}):PerseusMarkdown.parse(content,{isJipt:this.translationIndex!=null});if(this.props.linterContext.highlightLint){const fullLinterContext={content:this.props.content,widgets:this.props.widgets,...this.props.linterContext};PerseusLinter__namespace.runLinter(parsedMarkdown,fullLinterContext,true);this._translationLinter.applyLintErrors(parsedMarkdown,[...this.state.translationLintErrors,...this.props.legacyPerseusLint||[]]);}const markdownContents=this.outputMarkdown(parsedMarkdown,{baseElements:apiOptions.baseElements});const className=classNames__default.default({[ClassNames.RENDERER]:true,[ClassNames.RESPONSIVE_RENDERER]:true,[ClassNames.TWO_COLUMN_RENDERER]:this._isTwoColumn});this.lastRenderedMarkdown=jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{className:className,children:markdownContents})});return this.lastRenderedMarkdown}constructor(props){super(props),this._widgetContainers=new Map,this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions}},this._getInitialWidgetState=props=>{const allWidgetInfo=perseusCore.applyDefaultsToWidgets(props.widgets);return {widgetInfo:allWidgetInfo,widgetProps:this._getAllWidgetsStartProps(allWidgetInfo,props)}},this._getAllWidgetsStartProps=(allWidgetInfo,props)=>{const{problemNum}=props;const widgetsStartProps={};const{strings}=this.props;wonderStuffCore.entries(allWidgetInfo).forEach(([key,widgetInfo])=>{widgetsStartProps[key]=getRendererPropsForWidgetInfo(widgetInfo,strings,problemNum);});return widgetsStartProps},this._getDefaultWidgetInfo=widgetId=>{const widgetIdParts=Util.rTypeFromWidgetId.exec(widgetId);if(widgetIdParts==null){return {}}return {type:widgetIdParts[1],graded:true,options:{}}},this._getWidgetInfo=widgetId=>{return this.state.widgetInfo[widgetId]||this._getDefaultWidgetInfo(widgetId)},this.renderWidget=(impliedType,id,state)=>{const widgetInfo=this.state.widgetInfo[id];if(widgetInfo&&widgetInfo.alignment==="full-width"){state.foundFullWidth=true;}if(widgetInfo){const type=widgetInfo&&widgetInfo.type||impliedType;const shouldHighlight=___default.default.contains(this.props.highlightedWidgets,id);return jsxRuntimeExports.jsx(WidgetContainer,{id:id,ref:node=>{const containerId=makeContainerId(id);if(node!=null){this._widgetContainers.set(containerId,node);}else {this._widgetContainers.delete(containerId);}},type:type,initialProps:this.getWidgetProps(id),shouldHighlight:shouldHighlight,linterContext:PerseusLinter__namespace.pushContextStack(this.props.linterContext,"widget")},makeContainerId(id))}return null},this.getSerializedState=widgetProps=>{return perseusCore.mapObject(widgetProps||this.state.widgetProps,(props,widgetId)=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getSerializedState){return excludeDenylistKeys(widget.getSerializedState())}return props})},this.restoreSerializedState=(serializedState,callback)=>{const serializedWidgetIds=___default.default.keys(serializedState);const widgetPropIds=___default.default.keys(this.state.widgetProps);if(serializedWidgetIds.length!==widgetPropIds.length||___default.default.intersection(serializedWidgetIds,widgetPropIds).length!==serializedWidgetIds.length){Log.error("Refusing to restore bad serialized state:",perseusCore.Errors.Internal,{loggedMetadata:{serializedState:JSON.stringify(serializedState),currentProps:JSON.stringify(this.state.widgetProps)}});return}let numCallbacks=1;const fireCallback=()=>{--numCallbacks;if(callback&&numCallbacks===0){callback();}};const restoredWidgetProps={};Object.entries(serializedState).forEach(([widgetId,props])=>{const widget=this.getWidgetInstance(widgetId);if(widget?.restoreSerializedState){++numCallbacks;const restoreResult=widget.restoreSerializedState(props,fireCallback);restoredWidgetProps[widgetId]={...this.state.widgetProps[widgetId],...restoreResult};}else {restoredWidgetProps[widgetId]=props;}});this.props.restoreUserInputFromSerializedState?.(serializedState,this.props.widgets);this.setState({widgetProps:restoredWidgetProps},()=>{setTimeout(fireCallback,0);});},this.findInternalWidgets=filterCriterion=>{let filterFunc;if(typeof filterCriterion==="string"){if(filterCriterion.indexOf(" ")!==-1){const widgetId=filterCriterion;filterFunc=(id,widgetInfo,widget)=>id===widgetId;}else {const widgetType=filterCriterion;filterFunc=(id,widgetInfo,widget)=>{return widgetInfo.type===widgetType};}}else {filterFunc=filterCriterion;}const results=this.widgetIds.filter(id=>{const widgetInfo=this._getWidgetInfo(id);const widget=this.getWidgetInstance(id);return filterFunc(id,widgetInfo,widget)}).map(this.getWidgetInstance);return results},this.findWidgets=filterCriterion=>{return [...this.findInternalWidgets(filterCriterion),...this.props.findExternalWidgets(filterCriterion)]},this.getWidgetInstance=id=>{const ref=this._widgetContainers.get(makeContainerId(id));if(!ref){return null}return ref.getWidget()},this._onWidgetFocus=(id,focusPath=[])=>{if(!___default.default.isArray(focusPath)){throw new perseusCore.PerseusError("widget props.onFocus focusPath must be an Array, "+"but was"+JSON.stringify(focusPath),perseusCore.Errors.Internal)}this._setCurrentFocus([id].concat(focusPath));},this._onWidgetBlur=(id,blurPath)=>{const blurringFocusPath=this._currentFocus;const fullPath=[id].concat(blurPath);if(!___default.default.isEqual(fullPath,blurringFocusPath)){return}___default.default.defer(()=>{if(___default.default.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.getContent=(props,state)=>{return state.jiptContent||props.content},this.shouldRenderJiptPlaceholder=(props,state)=>{return getDependencies().JIPT.useJIPT&&state.jiptContent==null&&props.content.indexOf("crwdns")!==-1},this.replaceJiptContent=(content,paragraphIndex)=>{if(paragraphIndex==null){this.setState({jiptContent:content});}else {const codeFenceRegex=/^\s*(`{3,}|~{3,})\s*(\S+)?\s*\n([\s\S]+?)\s*\1\s*$/;if(codeFenceRegex.test(content));else if(/\S\n\s*\n\S/.test(content)){content="$\\large{\\red{\\text{Please translate each "+"paragraph to a single paragraph.}}}$";}else if(/^\s*$/.test(content)){content="$\\large{\\red{\\text{Translated paragraph is "+"currently empty}}}$";}const allContent=this.getContent(this.props,this.state);const paragraphs=JiptParagraphs.parseToArray(allContent);paragraphs[paragraphIndex]=content;this.setState({jiptContent:JiptParagraphs.joinFromArray(paragraphs)});}},this.outputMarkdown=(ast,state)=>{if(___default.default.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;state.paragraphIndex=i;const nodeOut=this.outputMarkdown(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}this._foundTextNodes=false;state.foundFullWidth=false;const output=this.outputNested(ast,state);let className;if(this.translationIndex!=null){className=null;}else {className=classNames__default.default({"perseus-paragraph-centered":!this._foundTextNodes,"perseus-paragraph-full-width":state.foundFullWidth&&ast.content.length===1});}return jsxRuntimeExports.jsx(QuestionParagraph,{className:className,translationIndex:this.translationIndex,paragraphIndex:state.paragraphIndex,inline:this.props.inline,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:output})},state.key)},this.outputNested=(ast,state)=>{if(___default.default.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;const nodeOut=this.outputNested(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}return this.outputNode(ast,this.outputNested,state)},this.outputNode=(node,nestedOutput,state)=>{const apiOptions=this.getApiOptions();const imagePlaceholder=apiOptions.imagePlaceholder;if(node.type==="widget"){const widgetPlaceholder=apiOptions.widgetPlaceholder;if(widgetPlaceholder){return widgetPlaceholder}this._foundTextNodes=true;if(this.widgetIds.includes(node.id)){return jsxRuntimeExports.jsx("span",{className:"renderer-widget-error",children:["Widget [[","☃"," ",node.id,"]] already exists."].join("")},state.key)}this.widgetIds.push(node.id);return this.renderWidget(node.widgetType,node.id,state)}if(node.type==="blockMath"){const content=preprocessTex(node.content);const innerStyle={overflowX:"auto",overflowY:"hidden",paddingTop:10,paddingBottom:10,marginTop:-10,marginBottom:-10};if(apiOptions.isMobile){const margin=16;const outerStyle={marginLeft:-16,marginRight:-16};const horizontalPadding={paddingLeft:margin,paddingRight:margin};const mobileInnerStyle={...innerStyle,...styles$E.mobileZoomableParentFix};return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",style:outerStyle,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:{...mobileInnerStyle,...horizontalPadding},children:jsxRuntimeExports.jsx(ZoomableTeX,{children:content})})})},state.key)}return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:innerStyle,children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{setAssetStatus:setAssetStatus,children:content})})})})},state.key)}if(node.type==="math"){const tex=node.content;return jsxRuntimeExports.jsx("span",{style:{whiteSpace:"nowrap"},children:jsxRuntimeExports.jsxs(ErrorBoundary,{children:[jsxRuntimeExports.jsx("span",{}),jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.props.onRender,setAssetStatus:setAssetStatus,children:tex})}),jsxRuntimeExports.jsx("span",{})]})},state.key)}if(node.type==="image"){if(imagePlaceholder){return imagePlaceholder}const extraAttrs=___default.default.has(this.props.images,node.target)?this.props.images[node.target]:null;const responsive=!state.inTable;return jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{setAssetStatus:setAssetStatus,src:PerseusMarkdown.sanitizeUrl(node.target),alt:node.alt,title:node.title,responsive:responsive,onUpdate:this.props.onRender,zoomToFullSizeOnMobile:apiOptions.isMobile&&apiOptions.isArticle,...extraAttrs})})},state.key)}if(node.type==="columns"){this._isTwoColumn=true;return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)}if(node.type==="text"){if(rContainsNonWhitespace.test(node.content)){this._foundTextNodes=true;}if(imagePlaceholder&&rImageURL.test(node.content)){return imagePlaceholder}return node.content}if(node.type==="table"||node.type==="titledTable"){const output=PerseusMarkdown.ruleOutput(node,nestedOutput,{...state,isMobile:apiOptions.isMobile,inTable:true});if(!apiOptions.isMobile){return output}const outerStyle={marginLeft:-16,marginRight:-16};const innerStyle={paddingLeft:0,paddingRight:0};const mobileInnerStyle={...innerStyle,...styles$E.mobileZoomableParentFix};const wrappedOutput=jsxRuntimeExports.jsx("div",{style:{...mobileInnerStyle,overflowX:"auto"},children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(Zoomable,{animateHeight:true,children:output})})});return jsxRuntimeExports.jsx("div",{style:outerStyle,children:wrappedOutput})}return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)},this.handleRender=prevProps=>{const onRender=this.props.onRender;const oldOnRender=prevProps.onRender;if(onRender!==noopOnRender||oldOnRender!==noopOnRender){const $images=$__default.default(ReactDOM__namespace.default.findDOMNode(this)).find("img");if(oldOnRender!==noopOnRender){$images.off("load",oldOnRender);}if(onRender!==noopOnRender){$images.on("load",onRender);}}onRender();},this._setCurrentFocus=path=>{const apiOptions=this.getApiOptions();if(!isIdPathPrefix(path,this._currentFocus)){const prevFocus=this._currentFocus;if(prevFocus){this.blurPath(prevFocus);}this._currentFocus=path;apiOptions.onFocusChange(this._currentFocus,prevFocus);}},this.focus=()=>{let id;let focusResult;for(let i=0;i<this.widgetIds.length;i++){const widgetId=this.widgetIds[i];const widget=this.getWidgetInstance(widgetId);const widgetFocusResult=widget?.focus?.();if(widgetFocusResult){id=widgetId;focusResult=widgetFocusResult;break}}if(id){let path;if(typeof focusResult==="object"){path=[id].concat(focusResult.path||[]);Log.error("Renderer received a focus result of type 'object' "+"instead of the expected type 'boolean'",perseusCore.Errors.Internal,{loggedMetadata:{focusResult:JSON.stringify(focusResult),currentProps:JSON.stringify(this.state.widgetProps)}});}else {path=[id];}this._setCurrentFocus(path);return true}},this.getDOMNodeForPath=path=>{const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget?.getDOMNodeForPath){return widget.getDOMNodeForPath(interWidgetPath)}if(interWidgetPath.length===0){return ReactDOM__namespace.default.findDOMNode(widget)}},this.getInputPaths=()=>{const inputPaths=[];this.widgetIds.forEach(widgetId=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getInputPaths){const widgetInputPaths=widget.getInputPaths();widgetInputPaths.forEach(inputPath=>{const relativeInputPath=[widgetId].concat(inputPath);inputPaths.push(relativeInputPath);});}});return inputPaths},this.focusPath=path=>{if(___default.default.isEqual(this._currentFocus,path)){return}if(this._currentFocus){this.blurPath(this._currentFocus);}const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const focusWidget=this.getWidgetInstance(widgetId);focusWidget?.focusInputPath?.(interWidgetPath);},this.blurPath=path=>{if(!___default.default.isEqual(this._currentFocus,path)){return}const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget){const blurWidget=this.getWidgetInstance(widgetId);blurWidget?.blurInputPath?.(interWidgetPath);}},this.blur=()=>{if(this._currentFocus){this.blurPath(this._currentFocus);}},this.serialize=()=>{const state={};___default.default.each(this.state.widgetInfo,function(info,id){const widget=this.getWidgetInstance(id);const s=widget.serialize();if(!___default.default.isEmpty(s)){state[id]=s;}},this);return state},this.getWidgetIds=()=>{return this.widgetIds},this.handletranslationLintErrors=lintErrors=>{if(!this._isMounted){return}this.setState({translationLintErrors:lintErrors});};this._translationLinter=new TranslationLinter;this.state={jiptContent:null,translationLintErrors:[],lastUsedWidgetId:null,...this._getInitialWidgetState(props)};}}Renderer.contextType=PerseusI18nContext;Renderer.defaultProps={content:"",widgets:{},images:{},highlightedWidgets:[],questionCompleted:false,showSolutions:"none",onRender:noopOnRender,onInteractWithWidget:function(){},findExternalWidgets:()=>[],alwaysUpdate:false,reviewMode:false,serializedState:null,linterContext:PerseusLinter__namespace.linterContextDefault};const styles$E={mobileZoomableParentFix:{transform:"translate3d(0,0,0)"}};
1717
1717
 
1718
1718
  const{captureScratchpadTouchStart: captureScratchpadTouchStart$2}=Util;const InputWithExamples=React.forwardRef(function InputWithExamples({shouldShowExamples=true,onFocus=()=>{},onBlur=()=>{},disabled=false,linterContext=PerseusLinter__namespace.linterContextDefault,className="",...props},ref){const context=React__namespace.useContext(PerseusI18nContext);const inputRef=React__namespace.useRef(null);const[inputFocused,setInputFocused]=React__namespace.useState(false);const id=React.useId();const ariaId=`aria-for-${id}`;React.useImperativeHandle(ref,()=>({current:inputRef.current,focus:()=>{if(inputRef.current){inputRef.current.focus();}},blur:()=>{if(inputRef.current){inputRef.current.blur();}}}));const getInputClassName=()=>{let inputClassName=ClassNames.INPUT;if(inputFocused){inputClassName+=" "+ClassNames.FOCUSED;}if(className){inputClassName+=" "+className;}return inputClassName};const handleFocus=()=>{onFocus();setInputFocused(true);};const handleBlur=()=>{onBlur();setInputFocused(false);};const renderInput=()=>{const examplesAria=shouldShowExamples?`${props.examples[0]}
1719
1719
  ${props.examples.slice(1).join(", or\n")}`.replaceAll("*","").replaceAll("$","").replaceAll("\\ \\text{pi}"," pi").replaceAll("\\ "," and "):"";const inputProps={id:id,"aria-describedby":shouldShowExamples?ariaId:undefined,ref:inputRef,className:getInputClassName(),labelText:props.labelText,value:props.value,onFocus:handleFocus,onBlur:handleBlur,disabled:disabled,style:props.style,onChange:props.onChange,onTouchStart:captureScratchpadTouchStart$2,autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:"false"};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(TextInput,{...inputProps}),jsxRuntimeExports.jsx("span",{id:ariaId,style:{display:"none"},children:examplesAria})]})};const renderTooltipContent=()=>{return jsxRuntimeExports.jsx(Tooltip.TooltipContent,{children:jsxRuntimeExports.jsx("div",{id:id,className:"input-with-examples-tooltip",children:jsxRuntimeExports.jsx(Renderer,{content:examplesContent,linterContext:PerseusLinter__namespace.pushContextStack(linterContext,"input-with-examples"),strings:context.strings})})})};const examplesContent=props.examples.length<=2?props.examples.join(" "):props.examples.map((example,index)=>{return index===0&&example.startsWith("**")?`${example}
@@ -1723,11 +1723,11 @@ const formExamples={integer:function(_,strings){return strings.integerExample},p
1723
1723
 
1724
1724
  const getPromptJSON$r=renderProps=>{return {type:"numeric-input",label:renderProps.labelText,userInput:{value:renderProps.userInput.currentValue}}};
1725
1725
 
1726
- const NumericExampleStrings={integer:(form,strings)=>strings.integerExample,proper:(form,strings)=>form.simplify==="optional"?strings.properExample:strings.simplifiedProperExample,improper:(form,strings)=>form.simplify==="optional"?strings.improperExample:strings.simplifiedImproperExample,mixed:(form,strings)=>strings.mixedExample,decimal:(form,strings)=>strings.decimalExample,pi:(form,strings)=>strings.piExample};const generateExamples=(answerForms,strings)=>{if(answerForms.length===0){return []}const uniqueForms=getUniqueAnswerForms(answerForms);const examples=uniqueForms.map(form=>{return NumericExampleStrings[form.name](form,strings)});return [strings.yourAnswer].concat(examples)};const shouldShowExamples=answerForms=>{if(answerForms.length===0){return false}const answerFormNames=getUniqueAnswerForms(answerForms).map(form=>form.name);const allFormsAccepted=answerFormNames.length>=Object.keys(NumericExampleStrings).length;return !allFormsAccepted};const getUniqueAnswerForms=function(list){const foundForms=new Set;return list.filter(form=>{if(foundForms.has(form.name)){return false}foundForms.add(form.name);return true})};const unionAnswerForms=function(answerFormsList){const allForms=answerFormsList.flat();const uniqueForms=getUniqueAnswerForms(allForms);const formExampleKeys=Object.keys(NumericExampleStrings);return uniqueForms.sort((a,b)=>{return formExampleKeys.indexOf(a.name)-formExampleKeys.indexOf(b.name)})};
1726
+ const NumericExampleStrings={integer:(form,strings)=>strings.integerExample,proper:(form,strings)=>form.simplify==="optional"?strings.properExample:strings.simplifiedProperExample,improper:(form,strings)=>form.simplify==="optional"?strings.improperExample:strings.simplifiedImproperExample,mixed:(form,strings)=>strings.mixedExample,decimal:(form,strings)=>strings.decimalExample,pi:(form,strings)=>strings.piExample};const generateExamples=(answerForms,strings)=>{if(answerForms.length===0){return []}const uniqueForms=getUniqueAnswerForms(answerForms);const examples=uniqueForms.map(form=>{return NumericExampleStrings[form.name](form,strings)});return [strings.yourAnswer].concat(examples)};const shouldShowExamples=answerForms=>{if(answerForms.length===0){return false}const answerFormNames=getUniqueAnswerForms(answerForms).map(form=>form.name);const allFormsAccepted=answerFormNames.length>=Object.keys(NumericExampleStrings).length;return !allFormsAccepted};const getUniqueAnswerForms=function(list){const foundForms=new Set;return list.filter(form=>{if(foundForms.has(form.name)){return false}foundForms.add(form.name);return true})};const unionAnswerForms=function(answerFormsList){const allForms=answerFormsList.flat();const uniqueForms=getUniqueAnswerForms(allForms);const formExampleKeys=Object.keys(NumericExampleStrings);return uniqueForms.sort((a,b)=>{return formExampleKeys.indexOf(a.name)-formExampleKeys.indexOf(b.name)})};function normalizeCorrectAnswerForms(answers){if(answers==null){return []}return unionAnswerForms(answers.filter(answer=>answer.status==="correct").map(answer=>{return (answer.answerForms||[]).map(form=>{return {simplify:answer.simplify,name:form}})}))}
1727
1727
 
1728
1728
  const NumericInputComponent=React.forwardRef(function NumericInputComponent(props,ref){const context=React.useContext(PerseusI18nContext);const inputRef=React.useRef(null);const[isFocused,setIsFocused]=React.useState(false);React.useImperativeHandle(ref,()=>({current:inputRef.current,focus:()=>{if(inputRef.current){inputRef.current?.focus();setIsFocused(true);}},blur:()=>{if(inputRef.current){inputRef.current?.blur();setIsFocused(false);}}}));const handleChange=newValue=>{props.handleUserInput({currentValue:newValue});props.trackInteraction();};const handleFocus=()=>{props.onFocus([]);setIsFocused(true);};const handleBlur=()=>{props.onBlur([]);setIsFocused(false);};const styles=aphrodite.StyleSheet.create({inputWithExamples:{borderRadius:"3px",borderWidth:isFocused?"2px":"1px",display:"inline-block",fontFamily:`Symbola, "Times New Roman", serif`,fontSize:"18px",height:"32px",lineHeight:"18px",padding:isFocused?"4px":"4px 5px",textAlign:props.rightAlign?"right":"left",width:props.size==="small"?40:80,direction:"ltr"}});if(props.apiOptions.customKeypad){const alignmentClass=props.rightAlign?"perseus-input-right-align":undefined;return jsxRuntimeExports.jsx("div",{className:alignmentClass,children:jsxRuntimeExports.jsx(SimpleKeypadInput,{ref:inputRef,value:props.userInput.currentValue,keypadElement:props.keypadElement,onChange:handleChange,onFocus:handleFocus,onBlur:handleBlur})})}return jsxRuntimeExports.jsx(InputWithExamples,{ref:inputRef,value:props.userInput.currentValue,onChange:handleChange,labelText:props.labelText,examples:generateExamples(props.answerForms,context.strings),shouldShowExamples:shouldShowExamples(props.answerForms),onFocus:handleFocus,onBlur:handleBlur,id:props.widgetId,disabled:props.apiOptions.readOnly,style:styles.inputWithExamples})});
1729
1729
 
1730
- class NumericInput extends React__namespace.Component{getPromptJSON(){return getPromptJSON$r(this.props)}getSerializedState(){const{userInput,...rest}=this.props;return {...rest,currentValue:userInput.currentValue}}render(){return jsxRuntimeExports.jsx(NumericInputComponent,{...this.props,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:""}};const propsTransform=function(widgetOptions){const{answers:_,...rendererProps}={...widgetOptions,answerForms:unionAnswerForms(widgetOptions.answers.filter(answer=>answer.status==="correct").map(answer=>{return (answer.answerForms||[]).map(form=>{return {simplify:answer.simplify,name:form}})}))};return rendererProps};function getStartUserInput$h(){return {currentValue:""}}function getUserInputFromSerializedState$g(serializedState){return {currentValue:serializedState.currentValue}}var NumericInput$1 = {name:"numeric-input",displayName:"Numeric input",widget:NumericInput,transform:propsTransform,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};
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
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?.choicesSelected?.slice()??[]}}};
1733
1733
 
@@ -1737,7 +1737,7 @@ const SCROLL_DISTANCE=100;function ScrollableView({overflowX,overflowY,children,
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
 
1740
- const Indicator=props=>{const{checked,showCorrectness}=props;const iconImage=checked&&showCorrectness==="correct"?checkIcon__default.default:checked&&showCorrectness==="wrong"?minusIcon__default.default:undefined;const icon=iconImage?jsxRuntimeExports.jsx(wonderBlocksIcon.PhosphorIcon,{"aria-hidden":true,className:styles$B.icon,icon:iconImage,role:"img"}):undefined;const classes=[styles$B.base,styles$B[props.shape+"-shape"]];if(showCorrectness){classes.push(styles$B["is-"+showCorrectness]);}const handleClick=showCorrectness?undefined:event=>{event.stopPropagation();props.updateChecked(!checked);};return jsxRuntimeExports.jsxs("button",{"aria-pressed":checked,className:classes.join(" "),type:"button",ref:props.buttonRef,onClick:handleClick,children:[icon,props.content]})};
1740
+ const Indicator=props=>{const{checked,content,showCorrectness}=props;const indicatorId=React.useId();const ariaLabelledby=content.labelledBy?`${indicatorId} ${content.labelledBy}`:undefined;const ariaDisabled=showCorrectness?"true":"false";const iconImage=checked&&showCorrectness==="correct"?checkIcon__default.default:checked&&showCorrectness==="wrong"?minusIcon__default.default:undefined;const icon=iconImage?jsxRuntimeExports.jsx(wonderBlocksIcon.PhosphorIcon,{"aria-hidden":true,className:styles$B.icon,icon:iconImage}):undefined;const classes=[styles$B.base,styles$B[props.shape+"-shape"]];if(showCorrectness){classes.push(styles$B["is-"+showCorrectness]);}const handleClick=showCorrectness?undefined:event=>{event.stopPropagation();props.updateChecked(!checked);};return jsxRuntimeExports.jsxs("button",{"aria-describedby":content.describedBy,"aria-disabled":ariaDisabled,"aria-pressed":checked,"aria-label":content.screenReader,"aria-labelledby":ariaLabelledby,className:classes.join(" "),id:indicatorId,type:"button",ref:props.buttonRef,onClick:handleClick,children:[icon,content.visible]})};
1741
1741
 
1742
1742
  var styles$A = {"choice":"perseus_hm3uu-sq","is-correct":"perseus_qpU2z5U7","isCorrect":"perseus_qpU2z5U7","is-wrong":"perseus_dUXUrBDI","isWrong":"perseus_dUXUrBDI"};
1743
1743
 
@@ -1749,7 +1749,7 @@ function getChoiceLetter(pos,strings){const lettersString=strings.letters;const
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 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",{className:styles$z.instructions,children:instructions}),jsxRuntimeExports.jsx(ScrollableView,{overflowX:"auto",children:jsxRuntimeExports.jsx("ul",{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 items=choices.map((choice,i)=>{const updateChecked=isChecked=>{onChoiceChange(i,isChecked);};const choiceLetter=getChoiceLetter(i,i18nStrings);const showCorrectness=reviewMode===true?choice.correct?"correct":"wrong":undefined;const content=choice.isNoneOfTheAbove?i18nStrings.noneOfTheAbove:choice.content;const rationaleClasses=[styles$z.rationale].concat(showCorrectness==="correct"?[styles$z.isCorrect]:[]).join(" ");const rationale=reviewMode&&choice.hasRationale?jsxRuntimeExports.jsx("div",{className:rationaleClasses,children:choice.rationale}):undefined;return jsxRuntimeExports.jsx(Choice$2,{checked:choice.checked,indicatorContent:choiceLetter,isMultiSelect:multipleSelect,showCorrectness:showCorrectness,updateChecked:updateChecked,children:jsxRuntimeExports.jsxs("div",{className:styles$z.content,children:[content,rationale]})},choice.id)});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:items})};
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(i,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
 
@@ -1857,7 +1857,7 @@ class FreeResponse extends React__namespace.Component{isOverLimit(){return !this
1857
1857
 
1858
1858
  function getWidgetTypeByWidgetId(widgetId,widgetMap){const widget=widgetMap[widgetId];return widget?.type??null}function getWidgetSubTypeByWidgetId(widgetId,widgetMap){const widget=widgetMap[widgetId];const widgetType=widget?.type??null;switch(widgetType){case "interactive-graph":const graph=widget.options.graph;return graph?.type??null;default:return null}}function contentHasWidgetType(type,content,widgetMap){return perseusCore.getWidgetIdsFromContentByType(type,content,widgetMap).length>0}function getWidgetsMapFromItemData(itemData){return itemData.question.widgets}function getWidgetFromWidgetMap(widgetId,widgetMap){return widgetMap[widgetId]??null}function getWidgetsFromWidgetMap(widgetIds,widgetMap){const widgets={};widgetIds.forEach(widgetId=>{const widget=getWidgetFromWidgetMap(widgetId,widgetMap);if(widget){widgets[widgetId]=widget;}});return widgets}
1859
1859
 
1860
- function sharedInitializeUserInput(widgetOptions,problemNum){const startUserInput={};if(!widgetOptions){return startUserInput}Object.entries(widgetOptions).forEach(([id,widgetInfo])=>{const widgetExports=getWidgetExport(widgetInfo.type);if(widgetInfo.static&&widgetExports?.getCorrectUserInput){startUserInput[id]=widgetExports.getCorrectUserInput(widgetInfo.options);}else if(widgetExports?.getStartUserInput){startUserInput[id]=widgetExports.getStartUserInput(widgetInfo.options,problemNum??0);}});return startUserInput}function sharedRestoreUserInputFromSerializedState(serializedState,widgetsMap){const restoredUserInput={};Object.entries(serializedState).forEach(([widgetId,props])=>{const widgetType=getWidgetTypeByWidgetId(widgetId,widgetsMap);const widgetExport=getWidgetExport(widgetType);if(widgetExport?.getUserInputFromSerializedState){const restoreResult=widgetExport.getUserInputFromSerializedState(props,widgetsMap[widgetId].options);restoredUserInput[widgetId]=restoreResult;}});return restoredUserInput}function UserInputManager(props){const[userInput,setUserInput]=React.useState(sharedInitializeUserInput(props.widgets,props.problemNum??0));function handleUserInput(id,nextUserInput,widgetsEmpty){const next={...userInput,[id]:nextUserInput};setUserInput(next);props.handleUserInput?.(next,widgetsEmpty);}function initializeUserInput(widgetOptions,problemNum){setUserInput(sharedInitializeUserInput(widgetOptions,problemNum));}function restoreUserInputFromSerializedState(serializedState,widgetOptions){setUserInput(sharedRestoreUserInputFromSerializedState(serializedState,widgetOptions));}return props.children({userInput,handleUserInput,initializeUserInput,restoreUserInputFromSerializedState})}
1860
+ function sharedInitializeUserInput(widgetOptions,problemNum){const startUserInput={};if(!widgetOptions){return startUserInput}Object.entries(widgetOptions).forEach(([id,widgetInfo])=>{const widgetExports=getWidgetExport(widgetInfo.type);if(widgetInfo.static&&widgetExports?.getCorrectUserInput){startUserInput[id]=widgetExports.getCorrectUserInput(widgetInfo.options);}else if(widgetExports?.getStartUserInput){startUserInput[id]=widgetExports.getStartUserInput(widgetInfo.options,problemNum??0);}});return startUserInput}function deriveUserInputFromSerializedState(serializedState,widgetsMap){const restoredUserInput={};Object.entries(serializedState).forEach(([widgetId,props])=>{const widgetType=getWidgetTypeByWidgetId(widgetId,widgetsMap);const widgetExport=getWidgetExport(widgetType);if(widgetExport?.getUserInputFromSerializedState){const restoreResult=widgetExport.getUserInputFromSerializedState(props,widgetsMap[widgetId].options);restoredUserInput[widgetId]=restoreResult;}});return restoredUserInput}function UserInputManager(props){const[userInput,setUserInput]=React.useState(sharedInitializeUserInput(props.widgets,props.problemNum??0));function handleUserInput(id,nextUserInput,widgetsEmpty){const next={...userInput,[id]:nextUserInput};setUserInput(next);props.handleUserInput?.(next,widgetsEmpty);}function initializeUserInput(widgetOptions,problemNum){setUserInput(sharedInitializeUserInput(widgetOptions,problemNum));}function restoreUserInputFromSerializedState(serializedState,widgetOptions){setUserInput(deriveUserInputFromSerializedState(serializedState,widgetOptions));}return props.children({userInput,handleUserInput,initializeUserInput,restoreUserInputFromSerializedState})}
1861
1861
 
1862
1862
  const getPromptJSON$i=(title,rendererJSON,hintRendererJSON)=>{if(!rendererJSON){return {type:"graded-group",title,content:"",widgets:{},hint:hintRendererJSON}}return {...rendererJSON,title,type:"graded-group",hint:hintRendererJSON}};
1863
1863
 
@@ -1867,7 +1867,7 @@ const GRADING_STATUSES={ungraded:"ungraded",correct:"correct",incorrect:"incorre
1867
1867
 
1868
1868
  const getPromptJSON$h=(renderProps,activeGroupJSON)=>{return {type:"graded-group-set",options:{groupCount:renderProps.gradedGroups.length,currentGroup:activeGroupJSON}}};
1869
1869
 
1870
- class Indicators extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("ul",{className:classNames__default.default(aphrodite.css(styles$h.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>jsxRuntimeExports.jsx("li",{className:aphrodite.css(styles$h.indicator),children:jsxRuntimeExports.jsx(Clickable__default.default,{role:"button","aria-label":this.context.strings.skipToTitle({title}),style:styles$h.indicatorButton,onClick:()=>this.props.onChangeCurrentGroup(i),onKeyDown:e=>this.handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:[styles$h.indicatorDot,(hovered||focused||pressed)&&styles$h.indicatorDotFocused],children:i===this.props.currentGroup&&jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:styles$h.indicatorDotActive,children:jsxRuntimeExports.jsx("span",{className:aphrodite.css(a11y.srOnly),children:this.context.strings.current})})})})},title))})}constructor(...args){super(...args),this.handleKeyDown=(e,i)=>{if(e.key==="Enter"||e.key===" "){this.props.onChangeCurrentGroup(i);}};}}Indicators.contextType=PerseusI18nContext;class GradedGroupSet extends React__namespace.Component{shouldComponentUpdate(nextProps,nextState){return nextProps!==this.props||nextState!==this.state}getPromptJSON(){const activeGroupPromptJSON=this._childGroup.getPromptJSON();return getPromptJSON$h(this.props,activeGroupPromptJSON)}render(){const{JIPT}=getDependencies();if(JIPT.useJIPT&&this.props.gradedGroups.length>1){return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$h.container),children:this.props.gradedGroups.map((gradedGroup,i)=>{return jsxRuntimeExports.jsx(GradedGroup,{...this.props,...gradedGroup,inGradedGroupSet:false,linterContext:this.props.linterContext},i)})})}const currentGroup=this.props.gradedGroups[this.state.currentGroup];if(!currentGroup){return jsxRuntimeExports.jsx("span",{children:"No current group..."})}const numGroups=this.props.gradedGroups.length;const handleNextQuestion=this.state.currentGroup<numGroups-1?this.handleNextQuestion:null;return jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$h.container),children:[jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$h.top),children:[jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$h.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$h.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroup:this.state.currentGroup,gradedGroups:this.props.gradedGroups,onChangeCurrentGroup:currentGroup=>this.setState({currentGroup})})]}),jsxRuntimeExports.jsx(GradedGroup,{ref:comp=>this._childGroup=comp,...this.props,...currentGroup,inGradedGroupSet:true,title:null,onNextQuestion:handleNextQuestion,linterContext:this.props.linterContext},this.state.currentGroup)]})}constructor(...args){super(...args),this.state={currentGroup:0},this.getInputPaths=()=>{return this._childGroup.getInputPaths()},this.focus=()=>{return this._childGroup.focus()},this.focusInputPath=path=>{this._childGroup.focusInputPath(path);},this.blurInputPath=path=>{this._childGroup.blurInputPath(path);},this.handleNextQuestion=()=>{const{currentGroup}=this.state;const numGroups=this.props.gradedGroups.length;if(currentGroup<numGroups-1){this.setState({currentGroup:currentGroup+1});}};}}GradedGroupSet.defaultProps={gradedGroups:[],linterContext:PerseusLinter.linterContextDefault};var GradedGroupSet$1 = {name:"graded-group-set",displayName:"Graded group set (articles only)",widget:GradedGroupSet,hidden:false,tracking:"all",isLintable:true};const styles$h=aphrodite.StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:12,color:wonderBlocksTokens.color.offBlack64,textTransform:"uppercase",marginBottom:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyle:"none",margin:"unset",paddingInlineStart:"unset",flexWrap:"wrap"},indicator:{width:24,height:24},indicatorButton:{width:"100%",height:"100%",display:"flex",flexWrap:"wrap",placeContent:"center",cursor:"pointer",":focus":{outline:"none"}},indicatorDot:{boxSizing:"content-box",width:10,height:10,borderRadius:"100%",borderWidth:2,borderColor:wonderBlocksTokens.color.blue,borderStyle:"solid"},indicatorDotFocused:{borderWidth:5,borderStyle:"double"},indicatorDotActive:{backgroundColor:wonderBlocksTokens.color.blue,width:"100%",height:"100%"},container:{borderTop:`1px solid ${gray76}`,borderBottom:`1px solid ${gray76}`,backgroundColor:tableBackgroundAccent,marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin,paddingBottom:phoneMargin,paddingLeft:phoneMargin,paddingRight:phoneMargin,paddingTop:10,width:"auto"}});
1870
+ class Indicators extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("ul",{className:classNames__default.default(aphrodite.css(styles$h.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>jsxRuntimeExports.jsx("li",{className:aphrodite.css(styles$h.indicator),children:jsxRuntimeExports.jsx(Clickable__default.default,{role:"button","aria-label":this.context.strings.skipToTitle({title}),style:styles$h.indicatorButton,onClick:()=>this.props.onChangeCurrentGroup(i),onKeyDown:e=>this.handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:[styles$h.indicatorDot,(hovered||focused||pressed)&&styles$h.indicatorDotFocused],children:i===this.props.currentGroup&&jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:styles$h.indicatorDotActive,children:jsxRuntimeExports.jsx("span",{className:aphrodite.css(a11y.srOnly),children:this.context.strings.current})})})})},title))})}constructor(...args){super(...args),this.handleKeyDown=(e,i)=>{if(e.key==="Enter"||e.key===" "){this.props.onChangeCurrentGroup(i);}};}}Indicators.contextType=PerseusI18nContext;class GradedGroupSet extends React__namespace.Component{shouldComponentUpdate(nextProps,nextState){return nextProps!==this.props||nextState!==this.state}getPromptJSON(){const activeGroupPromptJSON=this._childGroup.getPromptJSON();return getPromptJSON$h(this.props,activeGroupPromptJSON)}render(){const{JIPT}=getDependencies();if(JIPT.useJIPT&&this.props.gradedGroups.length>1){return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$h.container),children:this.props.gradedGroups.map((gradedGroup,i)=>{return jsxRuntimeExports.jsx(GradedGroup,{...this.props,...gradedGroup,inGradedGroupSet:false,linterContext:this.props.linterContext},i)})})}const currentGroup=this.props.gradedGroups[this.state.currentGroup];if(!currentGroup){return jsxRuntimeExports.jsx("span",{children:"No current group..."})}const numGroups=this.props.gradedGroups.length;const handleNextQuestion=this.state.currentGroup<numGroups-1?this.handleNextQuestion:null;return jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$h.container),children:[jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$h.top),children:[jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$h.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$h.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroup:this.state.currentGroup,gradedGroups:this.props.gradedGroups,onChangeCurrentGroup:currentGroup=>this.setState({currentGroup})})]}),jsxRuntimeExports.jsx(GradedGroup,{ref:comp=>this._childGroup=comp,...this.props,...currentGroup,inGradedGroupSet:true,title:null,onNextQuestion:handleNextQuestion,linterContext:this.props.linterContext},this.state.currentGroup)]})}constructor(...args){super(...args),this.state={currentGroup:0},this.getInputPaths=()=>{return this._childGroup.getInputPaths()},this.focus=()=>{return this._childGroup.focus()},this.focusInputPath=path=>{this._childGroup.focusInputPath(path);},this.blurInputPath=path=>{this._childGroup.blurInputPath(path);},this.handleNextQuestion=()=>{const{currentGroup}=this.state;const numGroups=this.props.gradedGroups.length;if(currentGroup<numGroups-1){this.setState({currentGroup:currentGroup+1});}};}}GradedGroupSet.defaultProps={gradedGroups:[],linterContext:PerseusLinter.linterContextDefault};var GradedGroupSet$1 = {name:"graded-group-set",displayName:"Graded group set (articles only)",widget:GradedGroupSet,hidden:false,tracking:"all",isLintable:true};const styles$h=aphrodite.StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:12,color:wonderBlocksTokens.color.offBlack64,textTransform:"uppercase",marginBottom:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyle:"none",margin:"unset",paddingInlineStart:"unset",flexWrap:"wrap"},indicator:{width:24,height:24},indicatorButton:{width:"100%",height:"100%",display:"flex",flexWrap:"wrap",placeContent:"center",cursor:"pointer",":focus":{outline:"none"}},indicatorDot:{boxSizing:"content-box",width:10,height:10,borderRadius:"100%",borderWidth:2,borderColor:wonderBlocksTokens.color.blue,borderStyle:"solid"},indicatorDotFocused:{borderWidth:5,borderStyle:"double"},indicatorDotActive:{backgroundColor:wonderBlocksTokens.color.blue,width:"100%",height:"100%"},container:{borderTop:`1px solid ${gray76}`,borderBottom:`1px solid ${gray76}`,backgroundColor:tableBackgroundAccent,"--perseus-widget-background-color":tableBackgroundAccent,marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin,paddingBottom:phoneMargin,paddingLeft:phoneMargin,paddingRight:phoneMargin,paddingTop:10,width:"auto"}});
1871
1871
 
1872
1872
  class ButtonGroup extends React__namespace.Component{componentWillUnmount(){this.container=null;}focus(){if(this.container){this.container.focus();return true}}toggleSelect(newValue){const value=this.props.value;if(this.props.allowEmpty){this.props.onChange(value!==newValue?newValue:null);}else {this.props.onChange(newValue);}}render(){const value=this.props.value;const buttons=this.props.buttons.map((button,i)=>{return jsxRuntimeExports.jsx("button",{title:button.title,type:"button",ref:"button"+i,className:aphrodite.css(styles$g.buttonStyle,button.value===value&&styles$g.selectedStyle,button.value===value&&this.props.selectedButtonStyle),onClick:()=>this.toggleSelect(button.value),children:button.content||""+button.value},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:node=>this.container=node,children:buttons})}}ButtonGroup.defaultProps={value:null,allowEmpty:true};const styles$g=aphrodite.StyleSheet.create({buttonStyle:{backgroundColor:"white",border:"1px solid #ccc",borderLeft:"0",cursor:"pointer",margin:"0",padding:"5px 10px",position:"relative",":first-child":{borderLeft:"1px solid #ccc",borderTopLeftRadius:"3px",borderBottomLeftRadius:"3px"},":last-child":{borderRight:"1px solid #ccc",borderTopRightRadius:"3px",borderBottomRightRadius:"3px"},":hover":{backgroundColor:"#ccc"},":focus":{zIndex:2}},selectedStyle:{backgroundColor:"#ddd"}});
1873
1873
 
@@ -1879,7 +1879,7 @@ const MovablePoint$3=Graphie.MovablePoint;const MovableLine$2=Graphie.MovableLin
1879
1879
 
1880
1880
  const getPromptJSON$f=rendererJSON=>{if(!rendererJSON){return {type:"group",content:"",widgets:{}}}return {...rendererJSON,type:"group"}};
1881
1881
 
1882
- class Group extends React__namespace.Component{componentDidMount(){this.forceUpdate();}getPromptJSON(){return getPromptJSON$f(this.rendererRef?.getPromptJSON())}getInputPaths(){return this.rendererRef?.getInputPaths()??[]}focus(){return this.rendererRef?.focus()??false}render(){const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,onFocusChange:(newFocus,oldFocus)=>{if(oldFocus){this.props.onBlur(oldFocus);}if(newFocus){this.props.onFocus(newFocus);}}};const groupWidgets=this.props.findWidgets("group");const number=groupWidgets.indexOf(this);const problemNumComponent=this.props.apiOptions.groupAnnotator(number,this.props.widgetId);const onInteractWithWidget=id=>{if(this.rendererRef){this.change("widgets",this.rendererRef.props.widgets);}};return jsxRuntimeExports.jsxs("div",{className:classNames__default.default({"perseus-group":true}),children:[problemNumComponent,jsxRuntimeExports.jsx(Renderer,{userInput:this.props.userInput,handleUserInput:(widgetId,userInput)=>{this.props.handleUserInput({...this.props.userInput,[widgetId]:userInput});},content:this.props.content,widgets:this.props.widgets,images:this.props.images,ref:ref=>this.rendererRef=ref,apiOptions:apiOptions,findExternalWidgets:this.props.findWidgets,reviewMode:this.props.reviewMode,showSolutions:this.props.showSolutions,onInteractWithWidget:onInteractWithWidget,linterContext:this.props.linterContext,strings:this.context.strings})]})}constructor(...args){super(...args),this.change=(...args)=>{return change.apply(this,args)},this.getSerializedState=()=>{return this.rendererRef?.getSerializedState()},this.restoreSerializedState=(state,callback)=>{this.rendererRef?.restoreSerializedState(state,callback);return null},this.focusInputPath=path=>{this.rendererRef?.focusPath(path);},this.blurInputPath=path=>{this.rendererRef?.blurPath(path);};}}Group.contextType=PerseusI18nContext;Group.defaultProps={content:"",widgets:{},images:{},linterContext:PerseusLinter.linterContextDefault};function getStartUserInput$a(options,problemNum){return sharedInitializeUserInput(options.widgets,problemNum)}function getUserInputFromSerializedState$a(serializedState,widgetOptions){return sharedRestoreUserInputFromSerializedState(serializedState,widgetOptions.widgets)}var Group$1 = {name:"group",displayName:"Group (SAT only)",widget:Group,hidden:true,isLintable:true,getStartUserInput: getStartUserInput$a,getUserInputFromSerializedState: getUserInputFromSerializedState$a};
1882
+ class Group extends React__namespace.Component{componentDidMount(){this.forceUpdate();}getPromptJSON(){return getPromptJSON$f(this.rendererRef?.getPromptJSON())}getInputPaths(){return this.rendererRef?.getInputPaths()??[]}focus(){return this.rendererRef?.focus()??false}render(){const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,onFocusChange:(newFocus,oldFocus)=>{if(oldFocus){this.props.onBlur(oldFocus);}if(newFocus){this.props.onFocus(newFocus);}}};const groupWidgets=this.props.findWidgets("group");const number=groupWidgets.indexOf(this);const problemNumComponent=this.props.apiOptions.groupAnnotator(number,this.props.widgetId);const onInteractWithWidget=id=>{if(this.rendererRef){this.change("widgets",this.rendererRef.props.widgets);}};return jsxRuntimeExports.jsxs("div",{className:classNames__default.default({"perseus-group":true}),children:[problemNumComponent,jsxRuntimeExports.jsx(Renderer,{userInput:this.props.userInput,handleUserInput:(widgetId,userInput)=>{this.props.handleUserInput({...this.props.userInput,[widgetId]:userInput});},content:this.props.content,widgets:this.props.widgets,images:this.props.images,ref:ref=>this.rendererRef=ref,apiOptions:apiOptions,findExternalWidgets:this.props.findWidgets,reviewMode:this.props.reviewMode,showSolutions:this.props.showSolutions,onInteractWithWidget:onInteractWithWidget,linterContext:this.props.linterContext,strings:this.context.strings})]})}constructor(...args){super(...args),this.change=(...args)=>{return change.apply(this,args)},this.getSerializedState=()=>{return this.rendererRef?.getSerializedState()},this.restoreSerializedState=(state,callback)=>{this.rendererRef?.restoreSerializedState(state,callback);return null},this.focusInputPath=path=>{this.rendererRef?.focusPath(path);},this.blurInputPath=path=>{this.rendererRef?.blurPath(path);};}}Group.contextType=PerseusI18nContext;Group.defaultProps={content:"",widgets:{},images:{},linterContext:PerseusLinter.linterContextDefault};function getStartUserInput$a(options,problemNum){return sharedInitializeUserInput(options.widgets,problemNum)}function getUserInputFromSerializedState$a(serializedState,widgetOptions){return deriveUserInputFromSerializedState(serializedState,widgetOptions.widgets)}var Group$1 = {name:"group",displayName:"Group (SAT only)",widget:Group,hidden:true,isLintable:true,getStartUserInput: getStartUserInput$a,getUserInputFromSerializedState: getUserInputFromSerializedState$a};
1883
1883
 
1884
1884
  const getPromptJSON$e=()=>{return getUnsupportedPromptJSON("iframe")};
1885
1885
 
@@ -1887,7 +1887,7 @@ 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 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(){let image;const alt=this.props.caption===this.props.alt?"":this.props.alt;const{apiOptions}=this.props;const backgroundImage=this.props.backgroundImage;if(backgroundImage.url){const url=backgroundImage.url;image=jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:url,alt:alt,width:backgroundImage.width,height:backgroundImage.height,preloader:apiOptions.imagePreloader,extraGraphie:{box:this.props.box,range:this.props.range,labels:this.props.labels},trackInteraction:this.props.trackInteraction,zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,setAssetStatus:setAssetStatus})});}if(apiOptions.isMobile){let titleAndCaption;if(this.props.title||this.props.caption){let title=this.props.title;if(title){if(this.props.caption&&!/[.?!"']\s*$/.test(title)){title+=".";}title=`**${title}** `;}const className=classNames__default.default({"perseus-image-caption":true,"has-title":!!title});const alignment=this.props.alignment;const isImageFullWidth=alignment==="block"||alignment==="full-width";const minWidth=isImageFullWidth?null:"0 !important";titleAndCaption=jsxRuntimeExports.jsx("figcaption",{className:className,style:{maxWidth:backgroundImage.width},children:jsxRuntimeExports.jsx("div",{style:{minWidth:minWidth},children:jsxRuntimeExports.jsx(Renderer,{content:title+this.props.caption,apiOptions:apiOptions,linterContext:this.props.linterContext,strings:this.context.strings})})});}return jsxRuntimeExports.jsxs("figure",{className:"perseus-image-widget",style:{maxWidth:backgroundImage.width},children:[image,titleAndCaption]})}let title;let caption;if(this.props.title){title=jsxRuntimeExports.jsx("div",{className:"perseus-image-title",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.title,apiOptions:apiOptions,linterContext:this.props.linterContext,strings:this.context.strings})});}if(this.props.caption){caption=jsxRuntimeExports.jsx("figcaption",{className:"perseus-image-caption",style:{maxWidth:backgroundImage.width},children:jsxRuntimeExports.jsx(Renderer,{content:this.props.caption,apiOptions:apiOptions,linterContext:this.props.linterContext,strings:this.context.strings})});}return jsxRuntimeExports.jsxs("figure",{className:"perseus-image-widget",style:{maxWidth:backgroundImage.width},children:[title,image,caption]})}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};
1890
+ 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(){let image;const alt=this.props.caption===this.props.alt?"":this.props.alt;const{apiOptions}=this.props;const backgroundImage=this.props.backgroundImage;if(backgroundImage.url){const url=backgroundImage.url;image=jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:url,alt:alt,width:backgroundImage.width,height:backgroundImage.height,preloader:apiOptions.imagePreloader,extraGraphie:{box:this.props.box,range:this.props.range,labels:this.props.labels},trackInteraction:this.props.trackInteraction,zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,setAssetStatus:setAssetStatus})});}let title;let caption;if(this.props.title){title=jsxRuntimeExports.jsx("div",{className:"perseus-image-title",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.title,apiOptions:apiOptions,linterContext:this.props.linterContext,strings:this.context.strings})});}if(this.props.caption){caption=jsxRuntimeExports.jsx("figcaption",{className:"perseus-image-caption",style:{maxWidth:backgroundImage.width},children:jsxRuntimeExports.jsx(Renderer,{content:this.props.caption,apiOptions:apiOptions,linterContext:this.props.linterContext,strings:this.context.strings})});}return jsxRuntimeExports.jsxs("figure",{className:"perseus-image-widget",style:{maxWidth:backgroundImage.width},children:[title,image,caption]})}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
1891
 
1892
1892
  const getPromptJSON$c=()=>{return getUnsupportedPromptJSON("interaction")};
1893
1893
 
@@ -2118,13 +2118,13 @@ const getPromptJSON=()=>{return getUnsupportedPromptJSON("video")};
2118
2118
 
2119
2119
  const IS_URL$1=/^https?:\/\//;const getYoutubeId=url=>{const regExp=/^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;const match=url.match(regExp);if(match&&match[7].length===11){return match[7]}return "videoNotFound"};const VideoTranscriptLink=props=>{const{location}=props;const{useVideo}=useDependencies();const[id,kind]=IS_URL$1.test(location)?[getYoutubeId(location),"YOUTUBE_ID"]:[location,"READABLE_ID"];const result=useVideo(id,kind);const{strings}=usePerseusI18n();switch(result.status){case "loading":return jsxRuntimeExports.jsx(wonderBlocksCore.View,{children:strings.loading});case "success":{const video=result.data?.video;return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{style:styles$3.transcriptLink,children:[jsxRuntimeExports.jsx(wonderBlocksCore.Text,{children:video?.title}),jsxRuntimeExports.jsx(wonderBlocksLayout.Strut,{size:10}),jsxRuntimeExports.jsx(Link__default.default,{href:"/transcript/"+(video?.contentId||"videoNotFound"),target:"_blank",className:"visited-no-recolor",children:strings.videoTranscript})]})}case "error":return jsxRuntimeExports.jsx(wonderBlocksCore.View,{children:strings.somethingWrong});case "aborted":return jsxRuntimeExports.jsx(wonderBlocksCore.View,{children:strings.somethingWrong});default:return jsxRuntimeExports.jsx(wonderBlocksCore.View,{children:strings.somethingWrong})}};const styles$3=aphrodite.StyleSheet.create({transcriptLink:{flexDirection:"row",width:"100%",justifyContent:"center"}});
2120
2120
 
2121
- const DEFAULT_WIDTH=1280;const DEFAULT_HEIGHT=720;const KA_EMBED="{host}/embed_video?slug={slug}"+"&internal_video_only=1";const IS_URL=/^https?:\/\//;const IS_KA_SITE=/(khanacademy\.org|localhost)/;const IS_VIMEO=/(vimeo\.com)/;class Video extends React__namespace.Component{getPromptJSON(){return getPromptJSON()}render(){const{InitialRequestUrl}=getDependencies();const location=this.props.location;if(!location){return jsxRuntimeExports.jsx("div",{})}let url;if(IS_URL.test(location)){url=location;if(IS_VIMEO.test(url)){if(url.indexOf("?")===-1){url+="?dnt=1";}else {url+="&dnt=1";}}}else {url=KA_EMBED.replace("{slug}",location);let embedHostname="https://www.khanacademy.org";if(IS_KA_SITE.test(InitialRequestUrl.host)){embedHostname=InitialRequestUrl.origin;}url=url.replace("{host}",embedHostname);}return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{children:[jsxRuntimeExports.jsxs(FixedToResponsive,{width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,children:[jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:a11y.srOnly,children:this.context.strings.videoWrapper}),jsxRuntimeExports.jsx("iframe",{className:"perseus-video-widget",sandbox:"allow-same-origin allow-scripts",width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,src:url,allowFullScreen:true})]},location+this.props.alignment),jsxRuntimeExports.jsx(VideoTranscriptLink,{location:location})]})}constructor(...args){super(...args),this.isWidget=true;}}Video.contextType=PerseusI18nContext;var Video$1 = {name:"video",displayName:"Video",widget:Video};
2121
+ const DEFAULT_WIDTH=1280;const DEFAULT_HEIGHT=720;const KA_EMBED="{host}/embed_video?slug={slug}"+"&internal_video_only=1";const IS_URL=/^https?:\/\//;const IS_KA_SITE=/(khanacademy\.org|localhost)/;const IS_VIMEO=/(vimeo\.com)/;class Video extends React__namespace.Component{getPromptJSON(){return getPromptJSON()}render(){const{InitialRequestUrl}=getDependencies();const location=this.props.location;if(!location){return jsxRuntimeExports.jsx("div",{})}let url;if(IS_URL.test(location)){url=location;if(IS_VIMEO.test(url)){if(url.indexOf("?")===-1){url+="?dnt=1";}else {url+="&dnt=1";}}}else {url=KA_EMBED.replace("{slug}",location);let embedHostname="https://www.khanacademy.org";if(IS_KA_SITE.test(InitialRequestUrl.host)){embedHostname=InitialRequestUrl.origin;}url=url.replace("{host}",embedHostname);}return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{children:[jsxRuntimeExports.jsxs(FixedToResponsive,{width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,children:[jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:a11y.srOnly,children:this.context.strings.videoWrapper}),jsxRuntimeExports.jsx("iframe",{className:"perseus-video-widget",sandbox:"allow-same-origin allow-scripts",width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,src:url,allowFullScreen:true,allow:"autoplay"})]},location+this.props.alignment),jsxRuntimeExports.jsx(VideoTranscriptLink,{location:location})]})}constructor(...args){super(...args),this.isWidget=true;}}Video.contextType=PerseusI18nContext;var Video$1 = {name:"video",displayName:"Video",widget:Video};
2122
2122
 
2123
2123
  var extraWidgets = [CSProgram$1,Categorizer$1,Definition$1,DeprecatedStandin$1,Dropdown$1,Explanation$1,FreeResponse$1,GradedGroup$1,GradedGroupSet$1,Grapher$1,Group$1,Iframe$1,Image$1,Interactive,InteractiveGraph$1,LabelImage$1,Matcher$1,Matrix$1,Measurer$1,Molecule$1,NumberLine$1,Orderer$1,Passage$1,PassageRef$1,PassageRefTarget$1,PhetSimulation$1,Plotter$1,PythonProgram$1,Sorter$1,Table$1,Video$1];
2124
2124
 
2125
2125
  const init=function(){registerWidgets(basicWidgets);registerWidgets(extraWidgets);replaceDeprecatedWidgets();};
2126
2126
 
2127
- const libName="@khanacademy/perseus";const libVersion="66.4.0";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
2127
+ const libName="@khanacademy/perseus";const libVersion="67.0.0";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
2128
2128
 
2129
2129
  const apiVersion={major:12,minor:0};
2130
2130
 
@@ -2227,6 +2227,7 @@ exports.components = components;
2227
2227
  exports.containerSizeClass = containerSizeClass;
2228
2228
  exports.contentHasWidgetType = contentHasWidgetType;
2229
2229
  exports.convertWidgetNameToEnum = convertWidgetNameToEnum;
2230
+ exports.deriveUserInputFromSerializedState = deriveUserInputFromSerializedState;
2230
2231
  exports.displaySigFigs = displaySigFigs;
2231
2232
  exports.excludeDenylistKeys = excludeDenylistKeys;
2232
2233
  exports.generateTestCategorizerWidget = generateTestCategorizerWidget;